From 378ab5cce1edecccaee964c78d0fcdd780db48ab Mon Sep 17 00:00:00 2001 From: sjplimp Date: Thu, 21 Nov 2013 20:47:55 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@11036 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/dump.cpp | 113 +++++++++++++++++++++++++++++++++++--------- src/dump.h | 7 +++ src/dump_atom.cpp | 84 ++++++++++++++++++++++++++++++-- src/dump_atom.h | 15 ++++-- src/dump_custom.cpp | 64 ++++++++++++++++++++++--- src/dump_custom.h | 13 +++-- src/dump_local.cpp | 52 ++++++++++++++++++++ src/dump_local.h | 6 +++ src/dump_xyz.cpp | 51 ++++++++++++++++++++ src/dump_xyz.h | 10 +++- 10 files changed, 373 insertions(+), 42 deletions(-) diff --git a/src/dump.cpp b/src/dump.cpp index 9b1b10fe98..1e48589383 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -71,6 +71,8 @@ Dump::Dump(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) clearstep = 0; sort_flag = 0; append_flag = 0; + buffer_allow = 0; + buffer_flag = 0; padflag = 0; maxbuf = maxids = maxsort = maxproc = 0; @@ -78,6 +80,9 @@ Dump::Dump(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) ids = idsort = index = proclist = NULL; irregular = NULL; + maxsbuf = 0; + sbuf = NULL; + // parse filename for special syntax // if contains '%', write one file per proc and replace % with proc-ID // if contains '*', write one file per timestep and replace * with timestep @@ -141,6 +146,8 @@ Dump::~Dump() memory->destroy(proclist); delete irregular; + memory->destroy(sbuf); + if (multiproc) MPI_Comm_free(&clustercomm); // XTC style sets fp to NULL since it closes file in its destructor @@ -301,11 +308,9 @@ void Dump::write() if (filewriter) write_header(nheader); - // insure filewriter proc can receive everyone's info - // limit nmax*size_one to int since used as arg in MPI_Rsend() below - // pack my data into buf - // if sorting on IDs also request ID list from pack() - // sort buf as needed + // insure buf is sized for packing and communicating + // use nmax to insure filewriter proc can receive info from others + // limit nmax*size_one to int since used as arg in MPI calls if (nmax > maxbuf) { if ((bigint) nmax * size_one > MAXSMALLINT) @@ -314,41 +319,90 @@ void Dump::write() memory->destroy(buf); memory->create(buf,maxbuf*size_one,"dump:buf"); } + + // insure ids buffer is sized for sorting + if (sort_flag && sortcol == 0 && nmax > maxids) { maxids = nmax; memory->destroy(ids); memory->create(ids,maxids,"dump:ids"); } + // pack my data into buf + // if sorting on IDs also request ID list from pack() + // sort buf as needed + if (sort_flag && sortcol == 0) pack(ids); else pack(NULL); if (sort_flag) sort(); + + // if buffering, convert doubles into strings + // insure sbuf is sized for communicating + + if (buffer_flag) { + nsme = convert_string(nme,buf); + int nsmin,nsmax; + MPI_Allreduce(&nsme,&nsmin,1,MPI_INT,MPI_MIN,world); + if (nsmin < 0) error->all(FLERR,"Too much buffered per-proc info for dump"); + if (multiproc != nprocs) + MPI_Allreduce(&nsme,&nsmax,1,MPI_INT,MPI_MAX,world); + else nsmax = nsme; + if (nsmax > maxsbuf) { + maxsbuf = nsmax; + memory->grow(sbuf,maxsbuf,"dump:sbuf"); + } + } // filewriter = 1 = this proc writes to file - // ping each proc in my cluster, receive its data, write data to file + // ping each proc in my cluster, receive its data, write data to file // else wait for ping from fileproc, send my data to fileproc - int tmp,nlines; + int tmp,nlines,nchars; MPI_Status status; MPI_Request request; - if (filewriter) { - for (int iproc = 0; iproc < nclusterprocs; iproc++) { - if (iproc) { - MPI_Irecv(buf,maxbuf*size_one,MPI_DOUBLE,me+iproc,0,world,&request); - MPI_Send(&tmp,0,MPI_INT,me+iproc,0,world); - MPI_Wait(&request,&status); - MPI_Get_count(&status,MPI_DOUBLE,&nlines); - nlines /= size_one; - } else nlines = nme; - - write_data(nlines,buf); - } - if (flush_flag) fflush(fp); + // comm and output buf of doubles + + if (buffer_flag == 0) { + if (filewriter) { + for (int iproc = 0; iproc < nclusterprocs; iproc++) { + if (iproc) { + MPI_Irecv(buf,maxbuf*size_one,MPI_DOUBLE,me+iproc,0,world,&request); + MPI_Send(&tmp,0,MPI_INT,me+iproc,0,world); + MPI_Wait(&request,&status); + MPI_Get_count(&status,MPI_DOUBLE,&nlines); + nlines /= size_one; + } else nlines = nme; + + write_data(nlines,buf); + } + if (flush_flag) fflush(fp); + } else { + MPI_Recv(&tmp,0,MPI_INT,fileproc,0,world,&status); + MPI_Rsend(buf,nme*size_one,MPI_DOUBLE,fileproc,0,world); + } + + // comm and output sbuf = one big string of formatted values per proc + } else { - MPI_Recv(&tmp,0,MPI_INT,fileproc,0,world,&status); - MPI_Rsend(buf,nme*size_one,MPI_DOUBLE,fileproc,0,world); + if (filewriter) { + for (int iproc = 0; iproc < nclusterprocs; iproc++) { + if (iproc) { + MPI_Irecv(sbuf,maxsbuf,MPI_CHAR,me+iproc,0,world,&request); + MPI_Send(&tmp,0,MPI_INT,me+iproc,0,world); + MPI_Wait(&request,&status); + MPI_Get_count(&status,MPI_CHAR,&nchars); + } else nchars = nsme; + + write_data(nchars,(double *) sbuf); + } + if (flush_flag) fflush(fp); + + } else { + MPI_Recv(&tmp,0,MPI_INT,fileproc,0,world,&status); + MPI_Rsend(sbuf,nsme,MPI_CHAR,fileproc,0,world); + } } // if file per timestep, close file if I am filewriter @@ -659,6 +713,16 @@ void Dump::modify_params(int narg, char **arg) else if (strcmp(arg[iarg+1],"no") == 0) append_flag = 0; else error->all(FLERR,"Illegal dump_modify command"); iarg += 2; + + } else if (strcmp(arg[iarg],"buffer") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); + if (strcmp(arg[iarg+1],"yes") == 0) buffer_flag = 1; + else if (strcmp(arg[iarg+1],"no") == 0) buffer_flag = 0; + else error->all(FLERR,"Illegal dump_modify command"); + if (buffer_flag && buffer_allow == 0) + error->all(FLERR,"Dump_modify buffer yes not allowed for this style"); + iarg += 2; + } else if (strcmp(arg[iarg],"every") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); int idump; @@ -677,6 +741,7 @@ void Dump::modify_params(int narg, char **arg) } output->every_dump[idump] = n; iarg += 2; + } else if (strcmp(arg[iarg],"first") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[iarg+1],"yes") == 0) first_flag = 1; @@ -719,6 +784,7 @@ void Dump::modify_params(int narg, char **arg) else if (strcmp(arg[iarg+1],"no") == 0) flush_flag = 0; else error->all(FLERR,"Illegal dump_modify command"); iarg += 2; + } else if (strcmp(arg[iarg],"format") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); delete [] format_user; @@ -768,6 +834,7 @@ void Dump::modify_params(int narg, char **arg) padflag = force->inumeric(FLERR,arg[iarg+1]); if (padflag < 0) error->all(FLERR,"Illegal dump_modify command"); iarg += 2; + } else if (strcmp(arg[iarg],"sort") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command"); if (strcmp(arg[iarg+1],"off") == 0) sort_flag = 0; @@ -787,6 +854,7 @@ void Dump::modify_params(int narg, char **arg) sortcolm1 = sortcol - 1; } iarg += 2; + } else { int n = modify_param(narg-iarg,&arg[iarg]); if (n == 0) error->all(FLERR,"Illegal dump_modify command"); @@ -802,6 +870,7 @@ void Dump::modify_params(int narg, char **arg) bigint Dump::memory_usage() { bigint bytes = memory->usage(buf,size_one*maxbuf); + bytes += memory->usage(sbuf,maxsbuf); if (sort_flag) { if (sortcol == 0) bytes += memory->usage(ids,maxids); bytes += memory->usage(bufsort,size_one*maxsort); diff --git a/src/dump.h b/src/dump.h index 3f581767e2..17d4554cc3 100644 --- a/src/dump.h +++ b/src/dump.h @@ -69,6 +69,8 @@ class Dump : protected Pointers { int flush_flag; // 0 if no flush, 1 if flush every dump int sort_flag; // 1 if sorted output int append_flag; // 1 if open file in append mode, 0 if not + int buffer_allow; // 1 if style allows for buffer_flag, 0 if not + int buffer_flag; // 1 if buffer output as one big string, 0 if not int padflag; // timestep padding in filename int singlefile_opened; // 1 = one big file, already opened, else 0 int sortcol; // 0 to sort on ID, 1-N on columns @@ -82,6 +84,7 @@ class Dump : protected Pointers { FILE *fp; // file to write dump to int size_one; // # of quantities for one atom int nme; // # of atoms in this dump from me + int nsme; // # of chars in string output from me double boxxlo,boxxhi; // local copies of domain values double boxylo,boxyhi; // lo/hi are bounding box for triclinic @@ -97,6 +100,9 @@ class Dump : protected Pointers { int maxbuf; // size of buf double *buf; // memory for atom quantities + int maxsbuf; // size of sbuf + char *sbuf; // memory for atom quantities in string format + int maxids; // size of ids int maxsort; // size of bufsort, idsort, index int maxproc; // size of proclist @@ -112,6 +118,7 @@ class Dump : protected Pointers { virtual void write_header(bigint) = 0; virtual int count(); virtual void pack(int *) = 0; + virtual int convert_string(int, double *) {return 0;} virtual void write_data(int, double *) = 0; void sort(); diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp index 2287c10c68..c87729e2cb 100644 --- a/src/dump_atom.cpp +++ b/src/dump_atom.cpp @@ -17,10 +17,14 @@ #include "atom.h" #include "update.h" #include "group.h" +#include "memory.h" #include "error.h" using namespace LAMMPS_NS; +#define ONELINE 256 +#define DELTA 1048576 + /* ---------------------------------------------------------------------- */ DumpAtom::DumpAtom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) @@ -29,6 +33,8 @@ DumpAtom::DumpAtom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) scale_flag = 1; image_flag = 0; + buffer_allow = 1; + buffer_flag = 1; format_default = NULL; } @@ -96,9 +102,13 @@ void DumpAtom::init_style() else if (scale_flag == 0 && image_flag == 1) pack_choice = &DumpAtom::pack_noscale_image; + if (image_flag == 0) convert_choice = &DumpAtom::convert_noimage; + else convert_choice = &DumpAtom::convert_image; + if (binary) write_choice = &DumpAtom::write_binary; - else if (image_flag == 0) write_choice = &DumpAtom::write_noimage; - else if (image_flag == 1) write_choice = &DumpAtom::write_image; + else if (buffer_flag == 1) write_choice = &DumpAtom::write_string; + else if (image_flag == 0) write_choice = &DumpAtom::write_lines_noimage; + else if (image_flag == 1) write_choice = &DumpAtom::write_lines_image; // open single file, one time only @@ -142,6 +152,13 @@ void DumpAtom::pack(int *ids) /* ---------------------------------------------------------------------- */ +int DumpAtom::convert_string(int n, double *mybuf) +{ + return (this->*convert_choice)(n,mybuf); +} + +/* ---------------------------------------------------------------------- */ + void DumpAtom::write_data(int n, double *mybuf) { (this->*write_choice)(n,mybuf); @@ -388,6 +405,58 @@ void DumpAtom::pack_noscale_noimage(int *ids) } } +/* ---------------------------------------------------------------------- + convert mybuf of doubles to one big formatted string in sbuf + return -1 if strlen exceeds an int, since used as arg in MPI calls in Dump +------------------------------------------------------------------------- */ + +int DumpAtom::convert_image(int n, double *mybuf) +{ + int offset = 0; + int m = 0; + for (int i = 0; i < n; i++) { + if (offset + ONELINE > maxsbuf) { + if ((bigint) maxsbuf + DELTA > MAXSMALLINT) return -1; + maxsbuf += DELTA; + memory->grow(sbuf,maxsbuf,"dump:sbuf"); + } + + offset += sprintf(&sbuf[offset],format, + static_cast (mybuf[m]), + static_cast (mybuf[m+1]), + mybuf[m+2],mybuf[m+3],mybuf[m+4], + static_cast (mybuf[m+5]), + static_cast (mybuf[m+6]), + static_cast (mybuf[m+7])); + m += size_one; + } + + return offset; +} + +/* ---------------------------------------------------------------------- */ + +int DumpAtom::convert_noimage(int n, double *mybuf) +{ + int offset = 0; + int m = 0; + for (int i = 0; i < n; i++) { + if (offset + ONELINE > maxsbuf) { + if ((bigint) maxsbuf + DELTA > MAXSMALLINT) return -1; + maxsbuf += DELTA; + memory->grow(sbuf,maxsbuf,"dump:sbuf"); + } + + offset += sprintf(&sbuf[offset],format, + static_cast (mybuf[m]), + static_cast (mybuf[m+1]), + mybuf[m+2],mybuf[m+3],mybuf[m+4]); + m += size_one; + } + + return offset; +} + /* ---------------------------------------------------------------------- */ void DumpAtom::write_binary(int n, double *mybuf) @@ -399,7 +468,14 @@ void DumpAtom::write_binary(int n, double *mybuf) /* ---------------------------------------------------------------------- */ -void DumpAtom::write_image(int n, double *mybuf) +void DumpAtom::write_string(int n, double *mybuf) +{ + fwrite(mybuf,sizeof(char),n,fp); +} + +/* ---------------------------------------------------------------------- */ + +void DumpAtom::write_lines_image(int n, double *mybuf) { int m = 0; for (int i = 0; i < n; i++) { @@ -413,7 +489,7 @@ void DumpAtom::write_image(int n, double *mybuf) /* ---------------------------------------------------------------------- */ -void DumpAtom::write_noimage(int n, double *mybuf) +void DumpAtom::write_lines_noimage(int n, double *mybuf) { int m = 0; for (int i = 0; i < n; i++) { diff --git a/src/dump_atom.h b/src/dump_atom.h index c792f8c0ab..cd52e8d243 100644 --- a/src/dump_atom.h +++ b/src/dump_atom.h @@ -38,6 +38,7 @@ class DumpAtom : public Dump { int modify_param(int, char **); void write_header(bigint); void pack(int *); + int convert_string(int, double *); void write_data(int, double *); typedef void (DumpAtom::*FnPtrHeader)(bigint); @@ -56,11 +57,17 @@ class DumpAtom : public Dump { void pack_scale_image_triclinic(int *); void pack_scale_noimage_triclinic(int *); - typedef void (DumpAtom::*FnPtrData)(int, double *); - FnPtrData write_choice; // ptr to write data functions + typedef int (DumpAtom::*FnPtrConvert)(int, double *); + FnPtrConvert convert_choice; // ptr to convert data functions + int convert_image(int, double *); + int convert_noimage(int, double *); + + typedef void (DumpAtom::*FnPtrWrite)(int, double *); + FnPtrWrite write_choice; // ptr to write data functions void write_binary(int, double *); - void write_image(int, double *); - void write_noimage(int, double *); + void write_string(int, double *); + void write_lines_image(int, double *); + void write_lines_noimage(int, double *); }; } diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index e3682bbaca..a87721e3bd 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -47,6 +47,8 @@ enum{LT,LE,GT,GE,EQ,NEQ}; enum{INT,DOUBLE,STRING}; // same as in DumpCFG #define INVOKED_PERATOM 8 +#define ONEFIELD 32 +#define DELTA 1048576 /* ---------------------------------------------------------------------- */ @@ -65,6 +67,8 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : pack_choice = new FnPtrPack[nfield]; vtype = new int[nfield]; + buffer_allow = 1; + buffer_flag = 1; iregion = -1; idregion = NULL; nthresh = 0; @@ -233,7 +237,8 @@ void DumpCustom::init_style() header_choice = &DumpCustom::header_item_triclinic; if (binary) write_choice = &DumpCustom::write_binary; - else write_choice = &DumpCustom::write_text; + else if (buffer_flag == 1) write_choice = &DumpCustom::write_string; + else write_choice = &DumpCustom::write_lines; // find current ptr for each compute,fix,variable // check that fix frequency is acceptable @@ -596,7 +601,8 @@ int DumpCustom::count() double boxxlo = domain->boxlo[0]; double invxprd = 1.0/domain->xprd; for (i = 0; i < nlocal; i++) - dchoose[i] = (x[i][0] - boxxlo) * invxprd + (image[i] & IMGMASK) - IMGMAX; + dchoose[i] = (x[i][0] - boxxlo) * invxprd + + (image[i] & IMGMASK) - IMGMAX; ptr = dchoose; nstride = 1; @@ -607,7 +613,8 @@ int DumpCustom::count() double invyprd = 1.0/domain->yprd; for (i = 0; i < nlocal; i++) dchoose[i] = - (x[i][1] - boxylo) * invyprd + (image[i] >> IMGBITS & IMGMASK) - IMGMAX; + (x[i][1] - boxylo) * invyprd + + (image[i] >> IMGBITS & IMGMASK) - IMGMAX; ptr = dchoose; nstride = 1; @@ -617,7 +624,8 @@ int DumpCustom::count() double boxzlo = domain->boxlo[2]; double invzprd = 1.0/domain->zprd; for (i = 0; i < nlocal; i++) - dchoose[i] = (x[i][2] - boxzlo) * invzprd + (image[i] >> IMG2BITS) - IMGMAX; + dchoose[i] = (x[i][2] - boxzlo) * invzprd + + (image[i] >> IMG2BITS) - IMGMAX; ptr = dchoose; nstride = 1; @@ -895,6 +903,39 @@ void DumpCustom::pack(int *ids) } } +/* ---------------------------------------------------------------------- + convert mybuf of doubles to one big formatted string in sbuf + return -1 if strlen exceeds an int, since used as arg in MPI calls in Dump +------------------------------------------------------------------------- */ + +int DumpCustom::convert_string(int n, double *mybuf) +{ + int i,j; + + int offset = 0; + int m = 0; + for (i = 0; i < n; i++) { + if (offset + size_one*ONEFIELD > maxsbuf) { + if ((bigint) maxsbuf + DELTA > MAXSMALLINT) return -1; + maxsbuf += DELTA; + memory->grow(sbuf,maxsbuf,"dump:sbuf"); + } + + for (j = 0; j < size_one; j++) { + if (vtype[j] == INT) + offset += sprintf(&sbuf[offset],vformat[j],static_cast (mybuf[m])); + else if (vtype[j] == DOUBLE) + offset += sprintf(&sbuf[offset],vformat[j],mybuf[m]); + else if (vtype[j] == STRING) + offset += sprintf(&sbuf[offset],vformat[j],typenames[(int) mybuf[m]]); + m++; + } + offset += sprintf(&sbuf[offset],"\n"); + } + + return offset; +} + /* ---------------------------------------------------------------------- */ void DumpCustom::write_data(int n, double *mybuf) @@ -913,7 +954,14 @@ void DumpCustom::write_binary(int n, double *mybuf) /* ---------------------------------------------------------------------- */ -void DumpCustom::write_text(int n, double *mybuf) +void DumpCustom::write_string(int n, double *mybuf) +{ + fwrite(mybuf,sizeof(char),n,fp); +} + +/* ---------------------------------------------------------------------- */ + +void DumpCustom::write_lines(int n, double *mybuf) { int i,j; @@ -1159,9 +1207,11 @@ int DumpCustom::parse_fields(int narg, char **arg) if (modify->compute[n]->peratom_flag == 0) error->all(FLERR,"Dump custom compute does not compute per-atom info"); if (argindex[i] == 0 && modify->compute[n]->size_peratom_cols > 0) - error->all(FLERR,"Dump custom compute does not calculate per-atom vector"); + error->all(FLERR, + "Dump custom compute does not calculate per-atom vector"); if (argindex[i] > 0 && modify->compute[n]->size_peratom_cols == 0) - error->all(FLERR,"Dump custom compute does not calculate per-atom array"); + error->all(FLERR,\ + "Dump custom compute does not calculate per-atom array"); if (argindex[i] > 0 && argindex[i] > modify->compute[n]->size_peratom_cols) error->all(FLERR,"Dump custom compute vector is accessed out-of-range"); diff --git a/src/dump_custom.h b/src/dump_custom.h index b5c1672948..b9c26c9e00 100644 --- a/src/dump_custom.h +++ b/src/dump_custom.h @@ -78,6 +78,7 @@ class DumpCustom : public Dump { virtual void write_header(bigint); int count(); void pack(int *); + int convert_string(int, double *); virtual void write_data(int, double *); bigint memory_usage(); @@ -94,10 +95,16 @@ class DumpCustom : public Dump { void header_item(bigint); void header_item_triclinic(bigint); - typedef void (DumpCustom::*FnPtrData)(int, double *); - FnPtrData write_choice; // ptr to write data functions + typedef int (DumpCustom::*FnPtrConvert)(int, double *); + FnPtrConvert convert_choice; // ptr to convert data functions + int convert_image(int, double *); + int convert_noimage(int, double *); + + typedef void (DumpCustom::*FnPtrWrite)(int, double *); + FnPtrWrite write_choice; // ptr to write data functions void write_binary(int, double *); - void write_text(int, double *); + void write_string(int, double *); + void write_lines(int, double *); // customize by adding a method prototype diff --git a/src/dump_local.cpp b/src/dump_local.cpp index 93bf4982d1..2f4694b548 100644 --- a/src/dump_local.cpp +++ b/src/dump_local.cpp @@ -30,6 +30,8 @@ using namespace LAMMPS_NS; enum{INT,DOUBLE}; #define INVOKED_LOCAL 16 +#define ONEFIELD 32 +#define DELTA 1048576 /* ---------------------------------------------------------------------- */ @@ -151,6 +153,11 @@ void DumpLocal::init_style() domain->boundary_string(boundstr); + // setup function ptrs + + if (buffer_flag == 1) write_choice = &DumpLocal::write_string; + else write_choice = &DumpLocal::write_lines; + // find current ptr for each compute,fix,variable // check that fix frequency is acceptable @@ -260,9 +267,54 @@ void DumpLocal::pack(int *dummy) for (int n = 0; n < size_one; n++) (this->*pack_choice[n])(n); } +/* ---------------------------------------------------------------------- + convert mybuf of doubles to one big formatted string in sbuf + return -1 if strlen exceeds an int, since used as arg in MPI calls in Dump +------------------------------------------------------------------------- */ + +int DumpLocal::convert_string(int n, double *mybuf) +{ + int i,j; + + int offset = 0; + int m = 0; + for (i = 0; i < n; i++) { + if (offset + size_one*ONEFIELD > maxsbuf) { + if ((bigint) maxsbuf + DELTA > MAXSMALLINT) return -1; + maxsbuf += DELTA; + memory->grow(sbuf,maxsbuf,"dump:sbuf"); + } + + for (j = 0; j < size_one; j++) { + if (vtype[j] == INT) + offset += sprintf(&sbuf[offset],vformat[j],static_cast (mybuf[m])); + else + offset += sprintf(&sbuf[offset],vformat[j],mybuf[m]); + m++; + } + offset += sprintf(&sbuf[offset],"\n"); + } + + return offset; +} + /* ---------------------------------------------------------------------- */ void DumpLocal::write_data(int n, double *mybuf) +{ + (this->*write_choice)(n,mybuf); +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocal::write_string(int n, double *mybuf) +{ + fwrite(mybuf,sizeof(char),n,fp); +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocal::write_lines(int n, double *mybuf) { int i,j; diff --git a/src/dump_local.h b/src/dump_local.h index 75ea54c8e3..4861141f2d 100644 --- a/src/dump_local.h +++ b/src/dump_local.h @@ -58,12 +58,18 @@ class DumpLocal : public Dump { void write_header(bigint); int count(); void pack(int *); + int convert_string(int, double *); void write_data(int, double *); void parse_fields(int, char **); int add_compute(char *); int add_fix(char *); + typedef void (DumpLocal::*FnPtrWrite)(int, double *); + FnPtrWrite write_choice; // ptr to write data functions + void write_string(int, double *); + void write_lines(int, double *); + // customize by adding a method prototype typedef void (DumpLocal::*FnPtrPack)(int); diff --git a/src/dump_xyz.cpp b/src/dump_xyz.cpp index 65504b6798..f3ef0178ce 100644 --- a/src/dump_xyz.cpp +++ b/src/dump_xyz.cpp @@ -21,6 +21,9 @@ using namespace LAMMPS_NS; +#define ONELINE 128 +#define DELTA 1048576 + /* ---------------------------------------------------------------------- */ DumpXYZ::DumpXYZ(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) @@ -29,6 +32,9 @@ DumpXYZ::DumpXYZ(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) if (binary || multiproc) error->all(FLERR,"Invalid dump xyz filename"); size_one = 5; + + buffer_allow = 1; + buffer_flag = 1; sort_flag = 1; sortcol = 0; @@ -83,6 +89,11 @@ void DumpXYZ::init_style() } } + // setup function ptr + + if (buffer_flag == 1) write_choice = &DumpXYZ::write_string; + else write_choice = &DumpXYZ::write_lines; + // open single file, one time only if (multifile == 0) openfile(); @@ -151,9 +162,49 @@ void DumpXYZ::pack(int *ids) } } + +/* ---------------------------------------------------------------------- + convert mybuf of doubles to one big formatted string in sbuf + return -1 if strlen exceeds an int, since used as arg in MPI calls in Dump +------------------------------------------------------------------------- */ + +int DumpXYZ::convert_string(int n, double *mybuf) +{ + int offset = 0; + int m = 0; + for (int i = 0; i < n; i++) { + if (offset + ONELINE > maxsbuf) { + if ((bigint) maxsbuf + DELTA > MAXSMALLINT) return -1; + maxsbuf += DELTA; + memory->grow(sbuf,maxsbuf,"dump:sbuf"); + } + + offset += sprintf(&sbuf[offset],format, + typenames[static_cast (mybuf[m+1])], + mybuf[m+2],mybuf[m+3],mybuf[m+4]); + m += size_one; + } + + return offset; +} + /* ---------------------------------------------------------------------- */ void DumpXYZ::write_data(int n, double *mybuf) +{ + (this->*write_choice)(n,mybuf); +} + +/* ---------------------------------------------------------------------- */ + +void DumpXYZ::write_string(int n, double *mybuf) +{ + fwrite(mybuf,sizeof(char),n,fp); +} + +/* ---------------------------------------------------------------------- */ + +void DumpXYZ::write_lines(int n, double *mybuf) { int m = 0; for (int i = 0; i < n; i++) { diff --git a/src/dump_xyz.h b/src/dump_xyz.h index eab50b8215..c66a6103b7 100644 --- a/src/dump_xyz.h +++ b/src/dump_xyz.h @@ -30,14 +30,20 @@ class DumpXYZ : public Dump { ~DumpXYZ(); private: + int ntypes; + char **typenames; + void init_style(); void write_header(bigint); void pack(int *); + int convert_string(int, double *); void write_data(int, double *); int modify_param(int, char **); - int ntypes; - char **typenames; + typedef void (DumpXYZ::*FnPtrWrite)(int, double *); + FnPtrWrite write_choice; // ptr to write data functions + void write_string(int, double *); + void write_lines(int, double *); }; }