From ce5f174281847098dbc36f0eb7d285a6668bd722 Mon Sep 17 00:00:00 2001 From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa> Date: Mon, 1 Aug 2016 20:35:57 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15414 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/dump_cfg.cpp | 75 +++++++++++------------- src/dump_custom.cpp | 49 ++++++++++++---- src/dump_custom.h | 3 + src/fix_ave_atom.cpp | 130 +++++++++++++++++++++++------------------ src/fix_ave_time.cpp | 134 +++++++++++++++--------------------------- src/fix_ave_time.h | 2 +- src/input.cpp | 136 +++++++++++++++++++++++++++++++++++++++++++ src/input.h | 1 + src/thermo.cpp | 35 +++++++---- 9 files changed, 356 insertions(+), 209 deletions(-) diff --git a/src/dump_cfg.cpp b/src/dump_cfg.cpp index 9005c3924a..477cdf3b71 100755 --- a/src/dump_cfg.cpp +++ b/src/dump_cfg.cpp @@ -46,59 +46,52 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) : { multifile_override = 0; - if (narg < 10 || - strcmp(arg[5],"mass") != 0 || strcmp(arg[6],"type") != 0 || - (strcmp(arg[7],"xs") != 0 && strcmp(arg[7],"xsu") != 0) || - (strcmp(arg[8],"ys") != 0 && strcmp(arg[8],"ysu") != 0) || - (strcmp(arg[9],"zs") != 0 && strcmp(arg[9],"zsu") != 0)) + // use earg instead of original arg since it includes expanded wildcards + // earg was created by parent DumpCustom + + if (nfield < 5 || + strcmp(earg[0],"mass") != 0 || strcmp(earg[1],"type") != 0 || + (strcmp(earg[2],"xs") != 0 && strcmp(earg[2],"xsu") != 0) || + (strcmp(earg[3],"ys") != 0 && strcmp(earg[3],"ysu") != 0) || + (strcmp(earg[4],"zs") != 0 && strcmp(earg[4],"zsu") != 0)) error->all(FLERR,"Dump cfg arguments must start with " "'mass type xs ys zs' or 'mass type xsu ysu zsu'"); - if (strcmp(arg[7],"xs") == 0) - if (strcmp(arg[8],"ysu") == 0 || strcmp(arg[9],"zsu") == 0) + if (strcmp(earg[2],"xs") == 0) { + if (strcmp(earg[3],"ysu") == 0 || strcmp(earg[4],"zsu") == 0) error->all(FLERR, "Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); - else unwrapflag = 0; - else if (strcmp(arg[8],"ys") == 0 || strcmp(arg[9],"zs") == 0) - error->all(FLERR, - "Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); - else unwrapflag = 1; + unwrapflag = 0; + } else { + if (strcmp(earg[3],"ys") == 0 || strcmp(earg[4],"zs") == 0) + error->all(FLERR, + "Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu"); + unwrapflag = 1; + } // setup auxiliary property name strings - // convert 'X_ID[m]' (X=c,f,v) to 'ID_m' + // convert 'X_ID[m]' (X=c,f,v) to 'X_ID_m' - if (narg > 10) auxname = new char*[narg-10]; + if (nfield > 5) auxname = new char*[nfield]; else auxname = NULL; int i = 0; - for (int iarg = 10; iarg < narg; iarg++, i++) { - if (strncmp(arg[iarg],"c_",2) == 0 || - strncmp(arg[iarg],"f_",2) == 0 || - strncmp(arg[iarg],"v_",2) == 0) { - int n = strlen(arg[iarg]); - char *suffix = new char[n]; - strcpy(suffix,&arg[iarg][2]); - - char *ptr = strchr(suffix,'['); - if (ptr) { - if (suffix[strlen(suffix)-1] != ']') - error->all(FLERR,"Invalid keyword in dump cfg command"); - *ptr = '\0'; - *(ptr+2) = '\0'; - auxname[i] = new char[strlen(suffix) + 3]; - strcpy(auxname[i],suffix); - strcat(auxname[i],"_"); - strcat(auxname[i],ptr+1); - } else { - auxname[i] = new char[strlen(suffix) + 1]; - strcpy(auxname[i],suffix); - } - - delete [] suffix; + for (int iarg = 5; iarg < nfield; iarg++, i++) { + if ((strncmp(earg[iarg],"c_",2) == 0 || + strncmp(earg[iarg],"f_",2) == 0 || + strncmp(earg[iarg],"v_",2) == 0) && strchr(earg[iarg],'[')) { + char *ptr = strchr(earg[iarg],'['); + char *ptr2 = strchr(ptr,']'); + auxname[i] = new char[strlen(earg[iarg])]; + *ptr = '\0'; + *ptr2 = '\0'; + strcpy(auxname[i],earg[iarg]); + strcat(auxname[i],"_"); + strcat(auxname[i],ptr+1); } else { - auxname[i] = new char[strlen(arg[iarg]) + 1]; - strcpy(auxname[i],arg[iarg]); + auxname[i] = new char[strlen(earg[iarg]) + 1]; + strcpy(auxname[i],earg[iarg]); } } } @@ -108,7 +101,7 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) : DumpCFG::~DumpCFG() { if (auxname) { - for (int i = 0; i < nfield-5; i++) delete [] auxname[i]; + for (int i = 0; i < nfield; i++) delete [] auxname[i]; delete [] auxname; } } diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 1e7356d0a1..d48e6270e4 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -62,9 +62,17 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : nevery = force->inumeric(FLERR,arg[3]); if (nevery <= 0) error->all(FLERR,"Illegal dump custom command"); - // size_one may be shrunk below if additional optional args exist + // expand args if any have wildcard character "*" + // ok to include trailing optional args, + // so long as they do not have "*" between square brackets + // nfield may be shrunk below if extra optional args exist + + expand = 0; + nfield = input->expand_args(narg-5,&arg[5],1,earg); + if (earg != &arg[5]) expand = 1; + + // allocate field vectors - size_one = nfield = narg - 5; pack_choice = new FnPtrPack[nfield]; vtype = new int[nfield]; @@ -100,15 +108,24 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : flag_custom = NULL; // process attributes - // ioptional = start of additional optional args - // only dump image and dump movie styles process optional args + // ioptional = start of additional optional args in expanded args - ioptional = parse_fields(narg,arg); + ioptional = parse_fields(nfield,earg); - if (ioptional < narg && + if (ioptional < nfield && strcmp(style,"image") != 0 && strcmp(style,"movie") != 0) error->all(FLERR,"Invalid attribute in dump custom command"); - size_one = nfield = ioptional - 5; + + // noptional = # of optional args + // reset nfield to subtract off optional args + // reset ioptional to what it would be in original arg list + // only dump image and dump movie styles process optional args, + // they do not use expanded earg list + + int noptional = nfield - ioptional; + nfield -= noptional; + size_one = nfield; + ioptional = narg - noptional; // atom selection arrays @@ -140,11 +157,11 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : // setup column string int n = 0; - for (int iarg = 5; iarg < narg; iarg++) n += strlen(arg[iarg]) + 2; + for (int iarg = 0; iarg < nfield; iarg++) n += strlen(earg[iarg]) + 2; columns = new char[n]; columns[0] = '\0'; - for (int iarg = 5; iarg < narg; iarg++) { - strcat(columns,arg[iarg]); + for (int iarg = 0; iarg < nfield; iarg++) { + strcat(columns,earg[iarg]); strcat(columns," "); } } @@ -153,6 +170,14 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : DumpCustom::~DumpCustom() { + // if wildcard expansion occurred, free earg memory from expand_args() + // could not do in constructor, b/c some derived classes process earg + + if (expand) { + for (int i = 0; i < nfield; i++) delete [] earg[i]; + memory->sfree(earg); + } + delete [] pack_choice; delete [] vtype; memory->destroy(field2index); @@ -1018,8 +1043,8 @@ int DumpCustom::parse_fields(int narg, char **arg) // customize by adding to if statement int i; - for (int iarg = 5; iarg < narg; iarg++) { - i = iarg-5; + for (int iarg = 0; iarg < narg; iarg++) { + i = iarg; if (strcmp(arg[iarg],"id") == 0) { pack_choice[i] = &DumpCustom::pack_id; diff --git a/src/dump_custom.h b/src/dump_custom.h index 79e90c1d85..3239a3283f 100644 --- a/src/dump_custom.h +++ b/src/dump_custom.h @@ -38,6 +38,9 @@ class DumpCustom : public Dump { int *thresh_op; // threshhold operation for each nthresh double *thresh_value; // threshhold value for each nthresh + int expand; // flag for whether field args were expanded + char **earg; // field names with wildcard expansion + int *vtype; // type of each vector (INT, DOUBLE) char **vformat; // format string for each vector element diff --git a/src/fix_ave_atom.cpp b/src/fix_ave_atom.cpp index 96169b7083..9b0375baec 100644 --- a/src/fix_ave_atom.cpp +++ b/src/fix_ave_atom.cpp @@ -43,76 +43,92 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : nrepeat = force->inumeric(FLERR,arg[4]); peratom_freq = force->inumeric(FLERR,arg[5]); - // parse remaining values - - which = new int[narg-6]; - argindex = new int[narg-6]; - ids = new char*[narg-6]; - value2index = new int[narg-6]; - nvalues = 0; - - int iarg = 6; - while (iarg < narg) { - ids[nvalues] = NULL; - - if (strcmp(arg[iarg],"x") == 0) { - which[nvalues] = X; - argindex[nvalues++] = 0; - } else if (strcmp(arg[iarg],"y") == 0) { - which[nvalues] = X; - argindex[nvalues++] = 1; - } else if (strcmp(arg[iarg],"z") == 0) { - which[nvalues] = X; - argindex[nvalues++] = 2; - - } else if (strcmp(arg[iarg],"vx") == 0) { - which[nvalues] = V; - argindex[nvalues++] = 0; - } else if (strcmp(arg[iarg],"vy") == 0) { - which[nvalues] = V; - argindex[nvalues++] = 1; - } else if (strcmp(arg[iarg],"vz") == 0) { - which[nvalues] = V; - argindex[nvalues++] = 2; - - } else if (strcmp(arg[iarg],"fx") == 0) { - which[nvalues] = F; - argindex[nvalues++] = 0; - } else if (strcmp(arg[iarg],"fy") == 0) { - which[nvalues] = F; - argindex[nvalues++] = 1; - } else if (strcmp(arg[iarg],"fz") == 0) { - which[nvalues] = F; - argindex[nvalues++] = 2; - - } else if (strncmp(arg[iarg],"c_",2) == 0 || - strncmp(arg[iarg],"f_",2) == 0 || - strncmp(arg[iarg],"v_",2) == 0) { - if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE; - else if (arg[iarg][0] == 'f') which[nvalues] = FIX; - else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE; - - int n = strlen(arg[iarg]); + nvalues = narg - 6; + + // expand args if any have wildcard character "*" + // this can reset nvalues + + int expand = 0; + char **earg,**arghold; + nvalues = input->expand_args(nvalues,&arg[6],1,earg); + + if (earg != &arg[6]) expand = 1; + arghold = arg; + arg = earg; + + // parse values + + which = new int[nvalues]; + argindex = new int[nvalues]; + ids = new char*[nvalues]; + value2index = new int[nvalues]; + + for (int i = 0; i < nvalues; i++) { + ids[i] = NULL; + + if (strcmp(arg[i],"x") == 0) { + which[i] = X; + argindex[i++] = 0; + } else if (strcmp(arg[i],"y") == 0) { + which[i] = X; + argindex[i++] = 1; + } else if (strcmp(arg[i],"z") == 0) { + which[i] = X; + argindex[i++] = 2; + + } else if (strcmp(arg[i],"vx") == 0) { + which[i] = V; + argindex[i++] = 0; + } else if (strcmp(arg[i],"vy") == 0) { + which[i] = V; + argindex[i++] = 1; + } else if (strcmp(arg[i],"vz") == 0) { + which[i] = V; + argindex[i++] = 2; + + } else if (strcmp(arg[i],"fx") == 0) { + which[i] = F; + argindex[i++] = 0; + } else if (strcmp(arg[i],"fy") == 0) { + which[i] = F; + argindex[i++] = 1; + } else if (strcmp(arg[i],"fz") == 0) { + which[i] = F; + argindex[i++] = 2; + + } else if (strncmp(arg[i],"c_",2) == 0 || + strncmp(arg[i],"f_",2) == 0 || + strncmp(arg[i],"v_",2) == 0) { + if (arg[i][0] == 'c') which[i] = COMPUTE; + else if (arg[i][0] == 'f') which[i] = FIX; + else if (arg[i][0] == 'v') which[i] = VARIABLE; + + int n = strlen(arg[i]); char *suffix = new char[n]; - strcpy(suffix,&arg[iarg][2]); + strcpy(suffix,&arg[i][2]); char *ptr = strchr(suffix,'['); if (ptr) { if (suffix[strlen(suffix)-1] != ']') error->all(FLERR,"Illegal fix ave/atom command"); - argindex[nvalues] = atoi(ptr+1); + argindex[i] = atoi(ptr+1); *ptr = '\0'; - } else argindex[nvalues] = 0; + } else argindex[i] = 0; n = strlen(suffix) + 1; - ids[nvalues] = new char[n]; - strcpy(ids[nvalues],suffix); - nvalues++; + ids[i] = new char[n]; + strcpy(ids[i],suffix); delete [] suffix; } else error->all(FLERR,"Illegal fix ave/atom command"); + } + + // if wildcard expansion occurred, free earg memory from exapnd_args() - iarg++; + if (expand) { + for (int i = 0; i < nvalues; i++) delete [] earg[i]; + memory->sfree(earg); + arg = arghold; } // setup and error check diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp index 588aca4738..56a3900f0e 100644 --- a/src/fix_ave_time.cpp +++ b/src/fix_ave_time.cpp @@ -73,89 +73,46 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : if (nvalues == 0) error->all(FLERR,"No values in fix ave/time command"); - options(narg,arg); + options(iarg,narg,arg); - // parse values until one isn't recognized - // if mode = VECTOR and value is a global array: - // expand it as if columns listed one by one - // adjust nvalues accordingly via maxvalues + // expand args if any have wildcard character "*" + // this can reset nvalues - which = argindex = value2index = offcol = varlen = NULL; - ids = NULL; - int maxvalues = nvalues; - allocate_values(maxvalues); - nvalues = 0; + int expand = 0; + char **earg,**arghold; + nvalues = input->expand_args(nvalues,&arg[6],mode,earg); - iarg = 6; - while (iarg < narg) { - if (strncmp(arg[iarg],"c_",2) == 0 || - strncmp(arg[iarg],"f_",2) == 0 || - strncmp(arg[iarg],"v_",2) == 0) { - if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE; - else if (arg[iarg][0] == 'f') which[nvalues] = FIX; - else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE; - - int n = strlen(arg[iarg]); - char *suffix = new char[n]; - strcpy(suffix,&arg[iarg][2]); - - char *ptr = strchr(suffix,'['); - if (ptr) { - if (suffix[strlen(suffix)-1] != ']') - error->all(FLERR,"Illegal fix ave/time command"); - argindex[nvalues] = atoi(ptr+1); - *ptr = '\0'; - } else argindex[nvalues] = 0; - - n = strlen(suffix) + 1; - ids[nvalues] = new char[n]; - strcpy(ids[nvalues],suffix); - delete [] suffix; - - if (mode == VECTOR && which[nvalues] == COMPUTE && - argindex[nvalues] == 0) { - int icompute = modify->find_compute(ids[nvalues]); - if (icompute < 0) - error->all(FLERR,"Compute ID for fix ave/time does not exist"); - if (modify->compute[icompute]->array_flag) { - int ncols = modify->compute[icompute]->size_array_cols; - maxvalues += ncols-1; - allocate_values(maxvalues); - argindex[nvalues] = 1; - for (int icol = 1; icol < ncols; icol++) { - which[nvalues+icol] = which[nvalues]; - argindex[nvalues+icol] = icol+1; - n = strlen(ids[nvalues]) + 1; - ids[nvalues+icol] = new char[n]; - strcpy(ids[nvalues+icol],ids[nvalues]); - } - nvalues += ncols-1; - } + if (earg != &arg[6]) expand = 1; + arghold = arg; + arg = earg; - } else if (mode == VECTOR && which[nvalues] == FIX && - argindex[nvalues] == 0) { - int ifix = modify->find_fix(ids[nvalues]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/time does not exist"); - if (modify->fix[ifix]->array_flag) { - int ncols = modify->fix[ifix]->size_array_cols; - maxvalues += ncols-1; - allocate_values(maxvalues); - argindex[nvalues] = 1; - for (int icol = 1; icol < ncols; icol++) { - which[nvalues+icol] = which[nvalues]; - argindex[nvalues+icol] = icol+1; - n = strlen(ids[nvalues]) + 1; - ids[nvalues+icol] = new char[n]; - strcpy(ids[nvalues+icol],ids[nvalues]); - } - nvalues += ncols-1; - } - } + // parse values - nvalues++; - iarg++; - } else break; + which = argindex = value2index = offcol = varlen = NULL; + ids = NULL; + allocate_values(nvalues); + + for (int i = 0; i < nvalues; i++) { + if (arg[i][0] == 'c') which[i] = COMPUTE; + else if (arg[i][0] == 'f') which[i] = FIX; + else if (arg[i][0] == 'v') which[i] = VARIABLE; + + int n = strlen(arg[i]); + char *suffix = new char[n]; + strcpy(suffix,&arg[i][2]); + + char *ptr = strchr(suffix,'['); + if (ptr) { + if (suffix[strlen(suffix)-1] != ']') + error->all(FLERR,"Illegal fix ave/time command"); + argindex[i] = atoi(ptr+1); + *ptr = '\0'; + } else argindex[i] = 0; + + n = strlen(suffix) + 1; + ids[i] = new char[n]; + strcpy(ids[i],suffix); + delete [] suffix; } // set off columns now that nvalues is finalized @@ -311,18 +268,13 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : if (title2) fprintf(fp,"%s\n",title2); else if (mode == SCALAR) { fprintf(fp,"# TimeStep"); - for (int i = 0; i < nvalues; i++) fprintf(fp," %s",arg[6+i]); + for (int i = 0; i < nvalues; i++) fprintf(fp," %s",earg[i]); fprintf(fp,"\n"); } else fprintf(fp,"# TimeStep Number-of-rows\n"); if (title3 && mode == VECTOR) fprintf(fp,"%s\n",title3); else if (mode == VECTOR) { fprintf(fp,"# Row"); - for (int i = 0; i < nvalues; i++) { - if (which[i] == COMPUTE) fprintf(fp," c_%s",ids[i]); - else if (which[i] == FIX) fprintf(fp," f_%s",ids[i]); - else if (which[i] == VARIABLE) fprintf(fp," v_%s",ids[i]); - if (argindex[i]) fprintf(fp,"[%d]",argindex[i]); - } + for (int i = 0; i < nvalues; i++) fprintf(fp," %s",earg[i]); fprintf(fp,"\n"); } if (ferror(fp)) @@ -335,6 +287,15 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : delete [] title2; delete [] title3; + // if wildcard expansion occurred, free earg memory from expand_args() + // wait to do this after file comment lines are printed + + if (expand) { + for (int i = 0; i < nvalues; i++) delete [] earg[i]; + memory->sfree(earg); + arg = arghold; + } + // allocate memory for averaging vector = vector_total = NULL; @@ -1049,7 +1010,7 @@ double FixAveTime::compute_array(int i, int j) parse optional args ------------------------------------------------------------------------- */ -void FixAveTime::options(int narg, char **arg) +void FixAveTime::options(int iarg, int narg, char **arg) { // option defaults @@ -1068,7 +1029,6 @@ void FixAveTime::options(int narg, char **arg) // optional args - int iarg = 6 + nvalues; while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/time command"); diff --git a/src/fix_ave_time.h b/src/fix_ave_time.h index 98b665140c..f2f79f1276 100644 --- a/src/fix_ave_time.h +++ b/src/fix_ave_time.h @@ -69,7 +69,7 @@ class FixAveTime : public Fix { int column_length(int); void invoke_scalar(bigint); void invoke_vector(bigint); - void options(int, char **); + void options(int, int, char **); void allocate_values(int); void allocate_arrays(); bigint nextvalid(); diff --git a/src/input.cpp b/src/input.cpp index 7983f81532..dda64856dc 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -36,6 +36,7 @@ #include "min.h" #include "modify.h" #include "compute.h" +#include "fix.h" #include "bond.h" #include "angle.h" #include "dihedral.h" @@ -583,6 +584,141 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag) strcpy(str,str2); } +/* ---------------------------------------------------------------------- + expand arg to earg, for arguments with syntax c_ID[*] or f_ID[*] + fields to consider in input arg range from iarg to narg + return new expanded # of values, and copy them w/out "*" into earg + if any expansion occurs, earg is new allocation, must be freed by caller + if no expansion occurs, earg just points to arg, caller need not free +------------------------------------------------------------------------- */ + +int Input::expand_args(int narg, char **arg, int mode, char **&earg) +{ + int n,iarg,index,nlo,nhi,nmax,which,expandflag,icompute,ifix; + char *ptr1,*ptr2,*str; + + ptr1 = NULL; + for (iarg = 0; iarg < narg; iarg++) { + ptr1 = strchr(arg[iarg],'*'); + if (ptr1) break; + } + + if (!ptr1) { + earg = arg; + return narg; + } + + // maxarg should always end up equal to newarg, so caller can free earg + + int maxarg = narg-iarg; + earg = (char **) memory->smalloc(maxarg*sizeof(char *),"input:earg"); + + int newarg = 0; + for (iarg = 0; iarg < narg; iarg++) { + expandflag = 0; + + if (strncmp(arg[iarg],"c_",2) == 0 || + strncmp(arg[iarg],"f_",2) == 0) { + + ptr1 = strchr(&arg[iarg][2],'['); + if (ptr1) { + ptr2 = strchr(ptr1,']'); + if (ptr2) { + *ptr2 = '\0'; + if (strchr(ptr1,'*')) { + if (arg[iarg][0] == 'c') { + *ptr1 = '\0'; + icompute = modify->find_compute(&arg[iarg][2]); + *ptr1 = '['; + + // check for global vector/array, peratom array, local array + + if (icompute >= 0) { + if (mode == 0 && modify->compute[icompute]->vector_flag) { + nmax = modify->compute[icompute]->size_vector; + expandflag = 1; + } else if (mode == 1 && modify->compute[icompute]->array_flag) { + nmax = modify->compute[icompute]->size_array_cols; + expandflag = 1; + } else if (modify->compute[icompute]->peratom_flag && + modify->compute[icompute]->size_peratom_cols) { + nmax = modify->compute[icompute]->size_peratom_cols; + expandflag = 1; + } else if (modify->compute[icompute]->local_flag && + modify->compute[icompute]->size_local_cols) { + nmax = modify->compute[icompute]->size_local_cols; + expandflag = 1; + } + } + } else if (arg[iarg][0] == 'f') { + *ptr1 = '\0'; + ifix = modify->find_fix(&arg[iarg][2]); + *ptr1 = '['; + + // check for global vector/array, peratom array, local array + + if (ifix >= 0) { + if (mode == 0 && modify->fix[ifix]->vector_flag) { + nmax = modify->fix[ifix]->size_vector; + expandflag = 1; + } else if (mode == 1 && modify->fix[ifix]->array_flag) { + nmax = modify->fix[ifix]->size_array_cols; + expandflag = 1; + } else if (modify->fix[ifix]->peratom_flag && + modify->fix[ifix]->size_peratom_cols) { + nmax = modify->fix[ifix]->size_peratom_cols; + expandflag = 1; + } else if (modify->fix[ifix]->local_flag && + modify->fix[ifix]->size_local_cols) { + nmax = modify->fix[ifix]->size_local_cols; + expandflag = 1; + } + } + } + } + *ptr2 = ']'; + } + } + } + + if (expandflag) { + *ptr2 = '\0'; + force->bounds(ptr1+1,nmax,nlo,nhi); + *ptr2 = ']'; + if (newarg+nhi-nlo+1 > maxarg) { + maxarg += nhi-nlo+1; + earg = (char **) + memory->srealloc(earg,maxarg*sizeof(char *),"input:earg"); + } + for (index = nlo; index <= nhi; index++) { + n = strlen(arg[iarg]) + 16; // 16 = space for large inserted integer + str = earg[newarg] = new char[n]; + strncpy(str,arg[iarg],ptr1+1-arg[iarg]); + sprintf(&str[ptr1+1-arg[iarg]],"%d",index); + strcat(str,ptr2); + newarg++; + } + + } else { + if (newarg == maxarg) { + maxarg++; + earg = (char **) + memory->srealloc(earg,maxarg*sizeof(char *),"input:earg"); + } + n = strlen(arg[iarg]) + 1; + earg[newarg] = new char[n]; + strcpy(earg[newarg],arg[iarg]); + newarg++; + } + } + + //printf("NEWARG %d\n",newarg); + //for (int i = 0; i < newarg; i++) + // printf(" arg %d: %s\n",i,earg[i]); + + return newarg; +} + /* ---------------------------------------------------------------------- return number of triple quotes in line ------------------------------------------------------------------------- */ diff --git a/src/input.h b/src/input.h index ccda3f49b1..c1947fee03 100644 --- a/src/input.h +++ b/src/input.h @@ -35,6 +35,7 @@ class Input : protected Pointers { char *one(const char *); // process a single command void substitute(char *&, char *&, int &, int &, int); // substitute for variables in a string + int expand_args(int, char **, int, char **&); // expand args due to wildcard private: int me; // proc ID diff --git a/src/thermo.cpp b/src/thermo.cpp index 5ecc161c8f..1b0fc3c68a 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -102,7 +102,7 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) flushflag = 0; // set style and corresponding lineflag - // custom style builds its own line of keywords + // custom style builds its own line of keywords, including wildcard expansion // customize a new thermo style by adding to if statement // allocate line string used for 3 tasks // concat of custom style args @@ -121,14 +121,29 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) } else if (strcmp(style,"custom") == 0) { if (narg == 1) error->all(FLERR,"Illegal thermo style custom command"); + + // expand args if any have wildcard character "*" + + int expand = 0; + char **earg; + int nvalues = input->expand_args(narg-1,&arg[1],0,earg); + if (earg != &arg[1]) expand = 1; + line = new char[256+narg*64]; line[0] = '\0'; - for (int iarg = 1; iarg < narg; iarg++) { - strcat(line,arg[iarg]); + for (int iarg = 0; iarg < nvalues; iarg++) { + strcat(line,earg[iarg]); strcat(line," "); } line[strlen(line)-1] = '\0'; + // if wildcard expansion occurred, free earg memory from exapnd_args() + + if (expand) { + for (int i = 0; i < nvalues; i++) delete [] earg[i]; + memory->sfree(earg); + } + } else error->all(FLERR,"Illegal thermo style command"); // ptrs, flags, IDs for compute objects thermo may use or create @@ -573,7 +588,7 @@ void Thermo::allocate() int n = nfield_initial + 1; keyword = new char*[n]; - for (int i = 0; i < n; i++) keyword[i] = new char[32]; + for (int i = 0; i < n; i++) keyword[i] = NULL; vfunc = new FnPtr[n]; vtype = new int[n]; @@ -821,7 +836,6 @@ void Thermo::parse_fields(char *str) // compute value = c_ID, fix value = f_ID, variable value = v_ID // count trailing [] and store int arguments - // copy = at most 8 chars of ID to pass to addfield } else if ((strncmp(word,"c_",2) == 0) || (strncmp(word,"f_",2) == 0) || (strncmp(word,"v_",2) == 0)) { @@ -829,9 +843,6 @@ void Thermo::parse_fields(char *str) int n = strlen(word); char *id = new char[n]; strcpy(id,&word[2]); - char copy[9]; - strncpy(copy,id,8); - copy[8] = '\0'; // parse zero or one or two trailing brackets from ID // argindex1,argindex2 = int inside each bracket pair, 0 if no bracket @@ -878,7 +889,7 @@ void Thermo::parse_fields(char *str) field2index[nfield] = add_compute(id,VECTOR); else field2index[nfield] = add_compute(id,ARRAY); - addfield(copy,&Thermo::compute_compute,FLOAT); + addfield(word,&Thermo::compute_compute,FLOAT); } else if (word[0] == 'f') { n = modify->find_fix(id); @@ -903,7 +914,7 @@ void Thermo::parse_fields(char *str) } field2index[nfield] = add_fix(id); - addfield(copy,&Thermo::compute_fix,FLOAT); + addfield(word,&Thermo::compute_fix,FLOAT); } else if (word[0] == 'v') { n = input->variable->find(id); @@ -919,7 +930,7 @@ void Thermo::parse_fields(char *str) error->all(FLERR,"Thermo custom variable cannot have two indices"); field2index[nfield] = add_variable(id); - addfield(copy,&Thermo::compute_variable,FLOAT); + addfield(word,&Thermo::compute_variable,FLOAT); } delete [] id; @@ -936,6 +947,8 @@ void Thermo::parse_fields(char *str) void Thermo::addfield(const char *key, FnPtr func, int typeflag) { + int n = strlen(key) + 1; + keyword[nfield] = new char[n]; strcpy(keyword[nfield],key); vfunc[nfield] = func; vtype[nfield] = typeflag; -- GitLab