diff --git a/src/dump.cpp b/src/dump.cpp index 8723627ec5..92ecb262d7 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -245,12 +245,21 @@ void Dump::modify_params(int narg, char **arg) iarg += 2; } else if (strcmp(arg[iarg],"every") == 0) { if (iarg+2 > narg) error->all("Illegal dump_modify command"); - int n = atoi(arg[iarg+1]); - if (n <= 0) error->all("Illegal dump_modify command"); int idump; for (idump = 0; idump < output->ndump; idump++) if (strcmp(id,output->dump[idump]->id) == 0) break; - output->dump_every[idump] = n; + int n; + if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { + delete [] output->var_dump[idump]; + n = strlen(&arg[iarg+1][2]) + 1; + output->var_dump[idump] = new char[n]; + strcpy(output->var_dump[idump],&arg[iarg+1][2]); + n = 0; + } else { + n = atoi(arg[iarg+1]); + if (n <= 0) error->all("Illegal dump_modify command"); + } + output->every_dump[idump] = n; iarg += 2; } else if (strcmp(arg[iarg],"first") == 0) { if (iarg+2 > narg) error->all("Illegal dump_modify command"); diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp index c8c477869a..77bf91c4dc 100644 --- a/src/dump_dcd.cpp +++ b/src/dump_dcd.cpp @@ -90,20 +90,17 @@ DumpDCD::~DumpDCD() void DumpDCD::init() { - // check that dump frequency has not changed + // check that dump frequency has not changed and is not a variable - if (nevery_save == 0) { - int idump; - for (idump = 0; idump < output->ndump; idump++) - if (strcmp(id,output->dump[idump]->id) == 0) break; - nevery_save = output->dump_every[idump]; - } else { - int idump; - for (idump = 0; idump < output->ndump; idump++) - if (strcmp(id,output->dump[idump]->id) == 0) break; - if (nevery_save != output->dump_every[idump]) - error->all("Cannot change dump_modify every for dump dcd"); - } + int idump; + for (idump = 0; idump < output->ndump; idump++) + if (strcmp(id,output->dump[idump]->id) == 0) break; + if (output->every_dump[idump] == 0) + error->all("Cannot use variable every setting for dump dcd"); + + if (nevery_save == 0) nevery_save = output->every_dump[idump]; + else if (nevery_save != output->every_dump[idump]) + error->all("Cannot change dump_modify every for dump dcd"); } /* ---------------------------------------------------------------------- */ diff --git a/src/output.cpp b/src/output.cpp index b4f6b9764a..c132ab564b 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -18,6 +18,8 @@ #include "style_dump.h" #include "atom.h" #include "neighbor.h" +#include "input.h" +#include "variable.h" #include "comm.h" #include "update.h" #include "group.h" @@ -76,9 +78,11 @@ Output::Output(LAMMPS *lmp) : Pointers(lmp) ndump = 0; max_dump = 0; + every_dump = NULL; next_dump = NULL; last_dump = NULL; - dump_every = NULL; + var_dump = NULL; + ivar_dump = NULL; dump = NULL; restart = NULL; @@ -95,9 +99,12 @@ Output::~Output() { if (thermo) delete thermo; + memory->sfree(every_dump); memory->sfree(next_dump); memory->sfree(last_dump); - memory->sfree(dump_every); + for (int i = 0; i < ndump; i++) delete [] var_dump[i]; + memory->sfree(var_dump); + memory->sfree(ivar_dump); for (int i = 0; i < ndump; i++) delete dump[i]; memory->sfree(dump); @@ -112,6 +119,14 @@ void Output::init() { thermo->init(); for (int i = 0; i < ndump; i++) dump[i]->init(); + for (int i = 0; i < ndump; i++) + if (every_dump[i] == 0) { + ivar_dump[i] = input->variable->find(var_dump[i]); + if (ivar_dump[i] < 0) + error->all("Variable name for dump every does not exist"); + if (!input->variable->equalstyle(ivar_dump[i])) + error->all("Variable for dump every is invalid style"); + } } /* ---------------------------------------------------------------------- @@ -139,15 +154,23 @@ void Output::setup(int flag) for (int idump = 0; idump < ndump; idump++) { if (dump[idump]->clearstep) modify->clearstep_compute(); writeflag = 0; - if (ntimestep % dump_every[idump] == 0 && last_dump[idump] != ntimestep) - writeflag = 1; + if (every_dump[idump] && ntimestep % every_dump[idump] == 0 && + last_dump[idump] != ntimestep) writeflag = 1; if (last_dump[idump] < 0 && dump[idump]->first_flag == 1) writeflag = 1; if (writeflag) { dump[idump]->write(); last_dump[idump] = ntimestep; } - next_dump[idump] = - (ntimestep/dump_every[idump])*dump_every[idump] + dump_every[idump]; + if (every_dump[idump]) + next_dump[idump] = + (ntimestep/every_dump[idump])*every_dump[idump] + every_dump[idump]; + else { + int nextdump = static_cast + (input->variable->compute_equal(ivar_dump[idump])); + if (nextdump <= ntimestep) + error->all("Dump every variable returned a bad timestep"); + next_dump[idump] = nextdump; + } if (dump[idump]->clearstep) { if (writeflag) modify->addstep_compute(next_dump[idump]); else modify->addstep_compute_all(next_dump[idump]); @@ -211,7 +234,14 @@ void Output::write(int ntimestep) if (dump[idump]->clearstep) modify->clearstep_compute(); dump[idump]->write(); last_dump[idump] = ntimestep; - next_dump[idump] += dump_every[idump]; + if (every_dump[idump]) next_dump[idump] += every_dump[idump]; + else { + int nextdump = static_cast + (input->variable->compute_equal(ivar_dump[idump])); + if (nextdump <= ntimestep) + error->all("Dump every variable returned a bad timestep"); + next_dump[idump] = nextdump; + } if (dump[idump]->clearstep) modify->addstep_compute(next_dump[idump]); } if (idump) next_dump_any = MYMIN(next_dump_any,next_dump[idump]); @@ -319,12 +349,16 @@ void Output::add_dump(int narg, char **arg) max_dump += DELTA; dump = (Dump **) memory->srealloc(dump,max_dump*sizeof(Dump *),"output:dump"); - dump_every = (int *) - memory->srealloc(dump_every,max_dump*sizeof(int *),"output:dump_every"); + every_dump = (int *) + memory->srealloc(every_dump,max_dump*sizeof(int),"output:every_dump"); next_dump = (int *) - memory->srealloc(next_dump,max_dump*sizeof(int *),"output:next_dump"); + memory->srealloc(next_dump,max_dump*sizeof(int),"output:next_dump"); last_dump = (int *) - memory->srealloc(last_dump,max_dump*sizeof(int *),"output:last_dump"); + memory->srealloc(last_dump,max_dump*sizeof(int),"output:last_dump"); + var_dump = (char **) + memory->srealloc(var_dump,max_dump*sizeof(char *),"output:var_dump"); + ivar_dump = (int *) + memory->srealloc(ivar_dump,max_dump*sizeof(int),"output:ivar_dump"); } // create the Dump @@ -339,9 +373,10 @@ void Output::add_dump(int narg, char **arg) else error->all("Invalid dump style"); - dump_every[ndump] = atoi(arg[3]); - if (dump_every[ndump] <= 0) error->all("Illegal dump command"); + every_dump[ndump] = atoi(arg[3]); + if (every_dump[ndump] <= 0) error->all("Illegal dump command"); last_dump[ndump] = -1; + var_dump[ndump] = NULL; ndump++; } @@ -377,14 +412,17 @@ void Output::delete_dump(char *id) if (idump == ndump) error->all("Could not find undump ID"); delete dump[idump]; + delete [] var_dump[idump]; // move other dumps down in list one slot for (int i = idump+1; i < ndump; i++) { dump[i-1] = dump[i]; - dump_every[i-1] = dump_every[i]; + every_dump[i-1] = every_dump[i]; next_dump[i-1] = next_dump[i]; last_dump[i-1] = last_dump[i]; + var_dump[i-1] = var_dump[i]; + ivar_dump[i-1] = ivar_dump[i]; } ndump--; } diff --git a/src/output.h b/src/output.h index 18db730db9..651966e812 100644 --- a/src/output.h +++ b/src/output.h @@ -31,8 +31,10 @@ class Output : protected Pointers { int max_dump; // max size of Dump list int next_dump_any; // next timestep for any Dump int *next_dump; // next timestep to do each Dump - int *dump_every; // output of each Dump every this many steps + int *every_dump; // output of each Dump every this many steps int *last_dump; // last timestep each a snapshot was output + char **var_dump; // variable name for dump frequency + int *ivar_dump; // variable index for dump frequency class Dump **dump; // list of defined Dumps int next_restart; // next timestep to write a restart file diff --git a/src/variable.cpp b/src/variable.cpp index 9fb256e259..9bd7db45cd 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -42,7 +42,8 @@ enum{ARG,OP}; enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,UNARY, EQ,NE,LT,LE,GT,GE,AND,OR, SQRT,EXP,LN,LOG,SIN,COS,TAN,ASIN,ACOS,ATAN, - CEIL,FLOOR,ROUND,RAMP,VALUE,ATOMARRAY,TYPEARRAY,INTARRAY}; + CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ, + VALUE,ATOMARRAY,TYPEARRAY,INTARRAY}; #define INVOKED_SCALAR 1 #define INVOKED_VECTOR 2 @@ -641,7 +642,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = atof(number); - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = atof(number); @@ -723,7 +724,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; @@ -748,7 +749,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; @@ -776,7 +777,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; @@ -838,7 +839,7 @@ double Variable::evaluate(char *str, Tree **tree) newtree->type = ATOMARRAY; newtree->array = compute->vector_atom; newtree->nstride = 1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; // c_ID[i] = vector from per-atom array @@ -864,7 +865,7 @@ double Variable::evaluate(char *str, Tree **tree) newtree->type = ATOMARRAY; newtree->array = &compute->array_atom[0][index1-1]; newtree->nstride = compute->size_peratom_cols; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else error->all("Mismatched compute in variable formula"); @@ -918,7 +919,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; @@ -936,7 +937,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; @@ -956,7 +957,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; @@ -1002,7 +1003,7 @@ double Variable::evaluate(char *str, Tree **tree) newtree->type = ATOMARRAY; newtree->array = fix->vector_atom; newtree->nstride = 1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; // f_ID[i] = vector from per-atom array @@ -1022,7 +1023,7 @@ double Variable::evaluate(char *str, Tree **tree) newtree->type = ATOMARRAY; newtree->array = &fix->array_atom[0][index1-1]; newtree->nstride = fix->size_peratom_cols; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; @@ -1065,7 +1066,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = atof(var); - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = atof(var); @@ -1157,7 +1158,7 @@ double Variable::evaluate(char *str, Tree **tree) Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value1; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value1; } @@ -1226,9 +1227,10 @@ double Variable::evaluate(char *str, Tree **tree) newtree->type = opprevious; if (opprevious == UNARY) { newtree->left = treestack[--ntreestack]; - newtree->right = NULL; + newtree->middle = newtree->right = NULL; } else { newtree->right = treestack[--ntreestack]; + newtree->middle = NULL; newtree->left = treestack[--ntreestack]; } treestack[ntreestack++] = newtree; @@ -1309,7 +1311,7 @@ double Variable::evaluate(char *str, Tree **tree) process an evaulation tree customize by adding a math function: sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan() - ceil(),floor(),round(),ramp() + ceil(),floor(),round(),ramp(),stagger(),logfreq() ---------------------------------------------------------------------- */ double Variable::eval_tree(Tree *tree, int i) @@ -1375,19 +1377,21 @@ double Variable::eval_tree(Tree *tree, int i) if (tree->type == SQRT) { double arg = eval_tree(tree->left,i); - if (arg < 0.0) error->all("Sqrt of negative in variable formula"); + if (arg < 0.0) error->all("Sqrt of negative value in variable formula"); return sqrt(arg); } if (tree->type == EXP) return exp(eval_tree(tree->left,i)); if (tree->type == LN) { double arg = eval_tree(tree->left,i); - if (arg <= 0.0) error->all("Log of zero/negative in variable formula"); + if (arg <= 0.0) + error->all("Log of zero/negative value in variable formula"); return log(arg); } if (tree->type == LOG) { double arg = eval_tree(tree->left,i); - if (arg <= 0.0) error->all("Log of zero/negative in variable formula"); + if (arg <= 0.0) + error->all("Log of zero/negative value in variable formula"); return log10(arg); } @@ -1430,6 +1434,33 @@ double Variable::eval_tree(Tree *tree, int i) return arg1 + delta*(arg2-arg1); } + if (tree->type == STAGGER) { + int arg1 = static_cast (eval_tree(tree->left,i)); + int arg2 = static_cast (eval_tree(tree->right,i)); + if (arg1 <= 0 || arg2 <= 0 || arg1 <= arg2) + error->all("Invalid math function in variable formula"); + int lower = update->ntimestep/arg1 * arg1; + int delta = update->ntimestep - lower; + if (delta < arg2) return 1.0*(lower+arg2); + else return 1.0*(lower+arg1); + } + + if (tree->type == LOGFREQ) { + int arg1 = static_cast (eval_tree(tree->left,i)); + int arg2 = static_cast (eval_tree(tree->middle,i)); + int arg3 = static_cast (eval_tree(tree->right,i)); + if (arg1 <= 0 || arg2 <= 0 || arg3 <= 0 || arg2 >= arg3) + error->all("Invalid math function in variable formula"); + if (update->ntimestep < arg1) return 1.0*arg1; + else { + int lower = arg1; + while (update->ntimestep >= arg3*lower) lower *= arg3; + int multiple = update->ntimestep/lower; + if (multiple < arg2) return 1.0*(multiple+1)*lower; + else return 1.0*(lower*arg3); + } + } + return 0.0; } @@ -1438,6 +1469,7 @@ double Variable::eval_tree(Tree *tree, int i) void Variable::free_tree(Tree *tree) { if (tree->left) free_tree(tree->left); + if (tree->middle) free_tree(tree->middle); if (tree->right) free_tree(tree->right); delete tree; } @@ -1510,7 +1542,7 @@ int Variable::int_between_brackets(char *&ptr) return 0 if not a match, 1 if successfully processed customize by adding a math function in 2 places: sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan() - ceil(),floor(),round(),ramp() + ceil(),floor(),round(),ramp(),stagger(),logfreq() ------------------------------------------------------------------------- */ int Variable::math_function(char *word, char *contents, Tree **tree, @@ -1525,7 +1557,8 @@ int Variable::math_function(char *word, char *contents, Tree **tree, strcmp(word,"tan") && strcmp(word,"asin") && strcmp(word,"acos") && strcmp(word,"atan") && strcmp(word,"ceil") && strcmp(word,"floor") && - strcmp(word,"round") && strcmp(word,"ramp")) + strcmp(word,"round") && strcmp(word,"ramp") && + strcmp(word,"stagger") && strcmp(word,"logfreq")) return 0; // parse contents for arg1,arg2,arg3 separated by commas @@ -1561,7 +1594,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, // evaluate args Tree *newtree; - double tmp,value1,value2; + double tmp,value1,value2,value3; if (tree) { newtree = new Tree(); @@ -1569,24 +1602,37 @@ int Variable::math_function(char *word, char *contents, Tree **tree, if (narg == 1) { tmp = evaluate(arg1,&argtree); newtree->left = argtree; - newtree->right = NULL; + newtree->middle = newtree->right = NULL; } else if (narg == 2) { tmp = evaluate(arg1,&argtree); newtree->left = argtree; + newtree->middle = NULL; tmp = evaluate(arg2,&argtree); newtree->right = argtree; + } else if (narg == 3) { + tmp = evaluate(arg1,&argtree); + newtree->left = argtree; + tmp = evaluate(arg2,&argtree); + newtree->middle = argtree; + tmp = evaluate(arg3,&argtree); + newtree->right = argtree; } treestack[ntreestack++] = newtree; } else { - if (narg == 1) + if (narg == 1) { value1 = evaluate(arg1,NULL); - else if (narg == 2) { + } else if (narg == 2) { value1 = evaluate(arg1,NULL); value2 = evaluate(arg2,NULL); + } else if (narg == 3) { + value1 = evaluate(arg1,NULL); + value2 = evaluate(arg2,NULL); + value3 = evaluate(arg3,NULL); } } if (strcmp(word,"sqrt") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = SQRT; else { if (value1 < 0.0) @@ -1595,9 +1641,11 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"exp") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = EXP; else argstack[nargstack++] = exp(value1); } else if (strcmp(word,"ln") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = LN; else { if (value1 <= 0.0) @@ -1605,6 +1653,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, argstack[nargstack++] = log(value1); } } else if (strcmp(word,"log") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = LOG; else { if (value1 <= 0.0) @@ -1613,16 +1662,20 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } } else if (strcmp(word,"sin") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = SIN; else argstack[nargstack++] = sin(value1); } else if (strcmp(word,"cos") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = COS; else argstack[nargstack++] = cos(value1); } else if (strcmp(word,"tan") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = TAN; else argstack[nargstack++] = tan(value1); } else if (strcmp(word,"asin") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = ASIN; else { if (value1 < -1.0 || value1 > 1.0) @@ -1630,6 +1683,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, argstack[nargstack++] = asin(value1); } } else if (strcmp(word,"acos") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = ACOS; else { if (value1 < -1.0 || value1 > 1.0) @@ -1637,22 +1691,27 @@ int Variable::math_function(char *word, char *contents, Tree **tree, argstack[nargstack++] = acos(value1); } } else if (strcmp(word,"atan") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = ATAN; else argstack[nargstack++] = atan(value1); } else if (strcmp(word,"ceil") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = CEIL; else argstack[nargstack++] = ceil(value1); } else if (strcmp(word,"floor") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = FLOOR; else argstack[nargstack++] = floor(value1); } else if (strcmp(word,"round") == 0) { + if (narg != 1) error->all("Invalid math function in variable formula"); if (tree) newtree->type = ROUND; else argstack[nargstack++] = MYROUND(value1); } else if (strcmp(word,"ramp") == 0) { + if (narg != 2) error->all("Invalid math function in variable formula"); if (update->whichflag == 0) error->all("Cannot use ramp in variable formula between runs"); if (tree) newtree->type = RAMP; @@ -1661,6 +1720,39 @@ int Variable::math_function(char *word, char *contents, Tree **tree, delta /= update->endstep - update->beginstep; argstack[nargstack++] = value1 + delta*(value2-value1); } + + } else if (strcmp(word,"stagger") == 0) { + if (narg != 2) error->all("Invalid math function in variable formula"); + if (tree) newtree->type = STAGGER; + else { + int ivalue1 = static_cast (value1); + int ivalue2 = static_cast (value2); + if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2) + error->all("Invalid math function in variable formula"); + int lower = update->ntimestep/ivalue1 * ivalue1; + int delta = update->ntimestep - lower; + if (delta < value2) argstack[nargstack++] = lower+ivalue2; + else argstack[nargstack++] = lower+ivalue1; + } + + } else if (strcmp(word,"logfreq") == 0) { + if (narg != 3) error->all("Invalid math function in variable formula"); + if (tree) newtree->type = LOGFREQ; + else { + int ivalue1 = static_cast (value1); + int ivalue2 = static_cast (value2); + int ivalue3 = static_cast (value3); + if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3) + error->all("Invalid math function in variable formula"); + if (update->ntimestep < ivalue1) argstack[nargstack++] = ivalue1; + else { + int lower = ivalue1; + while (update->ntimestep >= ivalue3*lower) lower *= ivalue3; + int multiple = update->ntimestep/lower; + if (multiple < ivalue2) argstack[nargstack++] = (multiple+1)*lower; + else argstack[nargstack++] = lower*ivalue3; + } + } } delete [] arg1; @@ -1898,7 +1990,7 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value; @@ -1966,7 +2058,7 @@ void Variable::peratom2global(int flag, char *word, Tree *newtree = new Tree(); newtree->type = VALUE; newtree->value = value; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value; } @@ -2009,7 +2101,7 @@ void Variable::atom_vector(char *word, Tree **tree, Tree *newtree = new Tree(); newtree->type = ATOMARRAY; newtree->nstride = 3; - newtree->left = newtree->right = NULL; + newtree->left = newtree->middle = newtree->right = NULL; treestack[ntreestack++] = newtree; if (strcmp(word,"mass") == 0) { diff --git a/src/variable.h b/src/variable.h index 5b344b708a..75279348c1 100644 --- a/src/variable.h +++ b/src/variable.h @@ -50,7 +50,7 @@ class Variable : protected Pointers { int *iarray; int nstride; int type; - Tree *left,*right; + Tree *left,*middle,*right; }; void remove(int);