From 8cc9aa5698fd8cd735a9d9bd07c1fb000ffe0515 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Sat, 10 Nov 2012 01:18:09 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9050 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/neigh_request.cpp | 1 - src/variable.cpp | 182 ++++++++++++++++++++++++++++++++++++------ src/variable.h | 14 ++++ 3 files changed, 172 insertions(+), 25 deletions(-) diff --git a/src/neigh_request.cpp b/src/neigh_request.cpp index da334da65e..9b82b5531a 100644 --- a/src/neigh_request.cpp +++ b/src/neigh_request.cpp @@ -37,7 +37,6 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) gran = granhistory = 0; respainner = respamiddle = respaouter = 0; half_from_full = 0; - ghost = 0; // default is every reneighboring // default is use newton_pair setting in force diff --git a/src/variable.cpp b/src/variable.cpp index 6458e2e090..2bc7dbb7b1 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -39,10 +39,11 @@ using namespace MathConst; #define VARDELTA 4 #define MAXLEVEL 4 +#define MAXLINE 256 #define MYROUND(a) (( a-floor(a) ) >= .5) ? ceil(a) : floor(a) -enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,EQUAL,ATOM}; +enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,FILEVAR,EQUAL,ATOM}; enum{ARG,OP}; // customize by adding a function @@ -56,7 +57,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,UNARY, // customize by adding a special function -enum{SUM,XMIN,XMAX,AVE,TRAP}; +enum{SUM,XMIN,XMAX,AVE,TRAP,NEXT}; #define INVOKED_SCALAR 1 #define INVOKED_VECTOR 2 @@ -77,6 +78,7 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp) num = NULL; which = NULL; pad = NULL; + reader = NULL; data = NULL; eval_in_progress = NULL; @@ -101,6 +103,7 @@ Variable::~Variable() { for (int i = 0; i < nvar; i++) { delete [] names[i]; + delete reader[i]; if (style[i] == LOOP || style[i] == ULOOP) delete [] data[i][0]; else for (int j = 0; j < num[i]; j++) delete [] data[i][j]; delete [] data[i]; @@ -110,6 +113,7 @@ Variable::~Variable() memory->destroy(num); memory->destroy(which); memory->destroy(pad); + memory->sfree(reader); memory->sfree(data); memory->destroy(eval_in_progress); @@ -245,7 +249,8 @@ void Variable::set(int narg, char **arg) for (int jvar = 0; jvar < nvar; jvar++) if (num[jvar] && (style[jvar] == UNIVERSE || style[jvar] == ULOOP) && num[nvar] != num[jvar]) - error->all(FLERR,"All universe/uloop variables must have same # of values"); + error->all(FLERR, + "All universe/uloop variables must have same # of values"); // STRING // remove pre-existing var if also style STRING (allows it to be reset) @@ -267,6 +272,23 @@ void Variable::set(int narg, char **arg) data[nvar] = new char*[num[nvar]]; copy(1,&arg[2],data[nvar]); + // FILEVAR for strings or numbers + // which = 1st value + + } else if (strcmp(arg[1],"file") == 0) { + if (narg != 3) error->all(FLERR,"Illegal variable command"); + if (find(arg[0]) >= 0) return; + if (nvar == maxvar) grow(); + style[nvar] = FILEVAR; + num[nvar] = 1; + which[nvar] = 0; + pad[nvar] = 0; + data[nvar] = new char*[num[nvar]]; + data[nvar][0] = new char[MAXLINE]; + reader[nvar] = new VarReader(lmp,arg[2]); + int flag = reader[nvar]->read(data[nvar][0]); + if (flag) error->all(FLERR,"File variable could not read value"); + // EQUAL // remove pre-existing var if also style EQUAL (allows it to be reset) // num = 2, which = 1st value @@ -385,6 +407,17 @@ int Variable::next(int narg, char **arg) } } + } else if (istyle == FILEVAR) { + + for (int iarg = 0; iarg < narg; iarg++) { + ivar = find(arg[iarg]); + int done = reader[ivar]->read(data[ivar][0]); + if (done) { + flag = 1; + remove(ivar); + } + } + } else if (istyle == UNIVERSE || istyle == ULOOP) { // wait until lock file can be created and owned by proc 0 of this world @@ -445,7 +478,8 @@ char *Variable::retrieve(char *name) char *str; if (style[ivar] == INDEX || style[ivar] == WORLD || - style[ivar] == UNIVERSE || style[ivar] == STRING) { + style[ivar] == UNIVERSE || style[ivar] == STRING || + style[ivar] == FILEVAR) { str = data[ivar][which[ivar]]; } else if (style[ivar] == LOOP || style[ivar] == ULOOP) { char result[16]; @@ -575,6 +609,7 @@ void Variable::remove(int n) num[i-1] = num[i]; which[i-1] = which[i]; pad[i-1] = pad[i]; + reader[i-1] = reader[i]; data[i-1] = data[i]; } nvar--; @@ -586,14 +621,20 @@ void Variable::remove(int n) void Variable::grow() { + int old = maxvar; maxvar += VARDELTA; - names = (char **) - memory->srealloc(names,maxvar*sizeof(char *),"var:names"); + names = (char **) memory->srealloc(names,maxvar*sizeof(char *),"var:names"); memory->grow(style,maxvar,"var:style"); memory->grow(num,maxvar,"var:num"); memory->grow(which,maxvar,"var:which"); memory->grow(pad,maxvar,"var:pad"); + + reader = (VarReader **) + memory->srealloc(reader,maxvar*sizeof(VarReader *),"var:reader"); + for (int i = old; i < maxvar; i++) reader[i] = NULL; + data = (char ***) memory->srealloc(data,maxvar*sizeof(char **),"var:data"); + memory->grow(eval_in_progress,maxvar,"var:eval_in_progress"); for (int i = 0; i < maxvar; i++) eval_in_progress[i] = 0; } @@ -743,14 +784,16 @@ double Variable::evaluate(char *str, Tree **tree) if (strncmp(word,"c_",2) == 0) { if (domain->box_exist == 0) - error->all(FLERR,"Variable evaluation before simulation box is defined"); + error->all(FLERR, + "Variable evaluation before simulation box is defined"); n = strlen(word) - 2 + 1; char *id = new char[n]; strcpy(id,&word[2]); int icompute = modify->find_compute(id); - if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula"); + if (icompute < 0) + error->all(FLERR,"Invalid compute ID in variable formula"); Compute *compute = modify->compute[icompute]; delete [] id; @@ -2826,7 +2869,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, if (strcmp(word,"sum") && strcmp(word,"min") && strcmp(word,"max") && strcmp(word,"ave") && strcmp(word,"trap") && strcmp(word,"gmask") && - strcmp(word,"rmask") && strcmp(word,"grmask")) + strcmp(word,"rmask") && strcmp(word,"grmask") && strcmp(word,"next")) return 0; // parse contents for arg1,arg2,arg3 separated by commas @@ -2872,7 +2915,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree, else if (strcmp(word,"ave") == 0) method = AVE; else if (strcmp(word,"trap") == 0) method = TRAP; - if (narg != 1) error->all(FLERR,"Invalid special function in variable formula"); + if (narg != 1) + error->all(FLERR,"Invalid special function in variable formula"); Compute *compute = NULL; Fix *fix = NULL; @@ -2887,12 +2931,14 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else index = 0; int icompute = modify->find_compute(&arg1[2]); - if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula"); + if (icompute < 0) + error->all(FLERR,"Invalid compute ID in variable formula"); compute = modify->compute[icompute]; if (index == 0 && compute->vector_flag) { if (update->whichflag == 0) { if (compute->invoked_vector != update->ntimestep) - error->all(FLERR,"Compute used in variable between runs is not current"); + error->all(FLERR, + "Compute used in variable between runs is not current"); } else if (!(compute->invoked_flag & INVOKED_VECTOR)) { compute->compute_vector(); compute->invoked_flag |= INVOKED_VECTOR; @@ -2986,10 +3032,6 @@ int Variable::special_function(char *word, char *contents, Tree **tree, if (method == AVE) value /= nvec; - delete [] arg1; - delete [] arg2; - delete [] arg3; - // save value in tree or on argstack if (tree) { @@ -3005,7 +3047,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"gmask") == 0) { if (tree == NULL) error->all(FLERR,"Gmask function in equal-style variable formula"); - if (narg != 1) error->all(FLERR,"Invalid special function in variable formula"); + if (narg != 1) + error->all(FLERR,"Invalid special function in variable formula"); int igroup = group->find(arg1); if (igroup == -1) @@ -3020,7 +3063,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"rmask") == 0) { if (tree == NULL) error->all(FLERR,"Rmask function in equal-style variable formula"); - if (narg != 1) error->all(FLERR,"Invalid special function in variable formula"); + if (narg != 1) + error->all(FLERR,"Invalid special function in variable formula"); int iregion = region_function(arg1); @@ -3033,7 +3077,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"grmask") == 0) { if (tree == NULL) error->all(FLERR,"Grmask function in equal-style variable formula"); - if (narg != 2) error->all(FLERR,"Invalid special function in variable formula"); + if (narg != 2) + error->all(FLERR,"Invalid special function in variable formula"); int igroup = group->find(arg1); if (igroup == -1) @@ -3046,8 +3091,37 @@ int Variable::special_function(char *word, char *contents, Tree **tree, newtree->ivalue2 = iregion; newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; + + // file variable special function + + } else if (strcmp(word,"next") == 0) { + if (narg != 1) + error->all(FLERR,"Invalid special function in variable formula"); + + int ivar = find(arg1); + if (ivar == -1) + error->all(FLERR,"Variable ID in variable formula does not exist"); + if (style[ivar] != FILEVAR) + error->all(FLERR,"Invalid variable in special function next"); + + double value = atof(data[ivar][0]); + reader[ivar]->read(data[ivar][0]); + + // save value in tree or on argstack + + if (tree) { + Tree *newtree = new Tree(); + newtree->type = VALUE; + newtree->value = value; + newtree->left = newtree->middle = newtree->right = NULL; + treestack[ntreestack++] = newtree; + } else argstack[nargstack++] = value; } + delete [] arg1; + delete [] arg2; + delete [] arg3; + return 1; } @@ -3067,7 +3141,8 @@ void Variable::peratom2global(int flag, char *word, double *argstack, int &nargstack) { if (atom->map_style == 0) - error->all(FLERR,"Indexed per-atom vector in variable formula without atom map"); + error->all(FLERR, + "Indexed per-atom vector in variable formula without atom map"); int index = atom->map(id); @@ -3210,7 +3285,8 @@ double Variable::numeric(char *str) if (isdigit(str[i])) continue; if (str[i] == '-' || str[i] == '+' || str[i] == '.') continue; if (str[i] == 'e' || str[i] == 'E') continue; - error->all(FLERR,"Expected floating point parameter in variable definition"); + error->all(FLERR, + "Expected floating point parameter in variable definition"); } return atof(str); @@ -3296,7 +3372,8 @@ double Variable::evaluate_boolean(char *str) // ---------------- else if (onechar == '(') { - if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command"); + if (expect == OP) + error->all(FLERR,"Invalid Boolean syntax in if command"); expect = OP; char *contents; @@ -3314,7 +3391,8 @@ double Variable::evaluate_boolean(char *str) // ---------------- } else if (isdigit(onechar) || onechar == '.' || onechar == '-') { - if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command"); + if (expect == OP) + error->all(FLERR,"Invalid Boolean syntax in if command"); expect = OP; // istop = end of number, including scientific notation @@ -3383,7 +3461,8 @@ double Variable::evaluate_boolean(char *str) continue; } - if (expect == ARG) error->all(FLERR,"Invalid Boolean syntax in if command"); + if (expect == ARG) + error->all(FLERR,"Invalid Boolean syntax in if command"); expect = ARG; // evaluate stack as deep as possible while respecting precedence @@ -3516,3 +3595,58 @@ unsigned int Variable::data_mask(char *str) return datamask; } + +/* ---------------------------------------------------------------------- + class to read variable values from a file, line by line +------------------------------------------------------------------------- */ + +VarReader::VarReader(LAMMPS *lmp, char *file) : Pointers(lmp) +{ + MPI_Comm_rank(world,&me); + + if (me == 0) { + fp = fopen(file,"r"); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open file variable file %s",file); + error->one(FLERR,str); + } + } +} + +/* ---------------------------------------------------------------------- */ + +VarReader::~VarReader() +{ + if (me == 0) fclose(fp); +} + +/* ---------------------------------------------------------------------- + read next value from file into str + strip comments, skip blank lines + return 0 if successful, 1 if end-of-file +------------------------------------------------------------------------- */ + +int VarReader::read(char *str) +{ + int n; + char *ptr; + + if (me == 0) { + while (1) { + if (fgets(str,MAXLINE,fp) == NULL) n = 0; + else n = strlen(str); + if (n == 0) break; // end of file + str[n-1] = '\0'; // strip newline + if (ptr = strchr(str,'#')) *ptr = '\0'; // strip comment + if (strtok(str," \t\n\r\f") == NULL) continue; // skip if blank + n = strlen(str) + 1; + break; + } + } + + MPI_Bcast(&n,1,MPI_INT,0,world); + if (n == 0) return 1; + MPI_Bcast(str,n,MPI_CHAR,0,world); + return 0; +} diff --git a/src/variable.h b/src/variable.h index 121dd98196..3eab71ff6a 100644 --- a/src/variable.h +++ b/src/variable.h @@ -14,6 +14,7 @@ #ifndef LMP_VARIABLE_H #define LMP_VARIABLE_H +#include "stdlib.h" #include "pointers.h" namespace LAMMPS_NS { @@ -45,7 +46,9 @@ class Variable : protected Pointers { int *num; // # of values for each variable int *which; // next available value for each variable int *pad; // 1 = pad loop/uloop variables with 0s, 0 = no pad + class VarReader **reader; // variable that reads lines from file char ***data; // str value of each variable's values + int *eval_in_progress; // flag if evaluation of variable is in progress class RanMars *randomequal; // random number generator for equal-style vars @@ -90,6 +93,17 @@ class Variable : protected Pointers { void print_tree(Tree *, int); }; +class VarReader : protected Pointers { + public: + VarReader(class LAMMPS *, char *); + ~VarReader(); + int read(char *); + + private: + int me; + FILE *fp; +}; + } #endif