diff --git a/doc/src/fix_print.txt b/doc/src/fix_print.txt index d23c1103d3..cafc180718 100644 --- a/doc/src/fix_print.txt +++ b/doc/src/fix_print.txt @@ -14,7 +14,7 @@ fix ID group-ID print N string keyword value ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l print = style name of this fix command :l -N = print every N steps :l +N = print every N steps; N can be a variable (see below) :l string = text string to print with optional variable names :l zero or more keyword/value pairs may be appended :l keyword = {file} or {append} or {screen} or {title} :l @@ -40,6 +40,21 @@ If it contains variables it must be enclosed in double quotes to insure they are not evaluated when the input script line is read, but will instead be evaluated each time the string is printed. +Instead of a numeric value, N can be specified as an "equal-style +variable"_variable.html, which should be specified as v_name, where +name is the variable name. In this case, the variable is evaluated at +the beginning of a run to determine the [next] timestep at which the +string will be written out. On that timestep, the variable will be +evaluated again to determine the next timestep, etc. +Thus the variable should return timestep values. See the stagger() +and logfreq() and stride() math functions for "equal-style +variables"_variable.html, as examples of useful functions to use in +this context. For example, the following commands will print output at +timesteps 10,20,30,100,200,300,1000,2000,etc: + +variable s equal logfreq(10,3,10) +fix extra all print v_s "Coords of marker atom = $x $y $z" :pre + The specified group-ID is ignored by this fix. See the "variable"_variable.html command for a description of {equal} diff --git a/src/fix_print.cpp b/src/fix_print.cpp index 969fcf8140..f6db88114a 100644 --- a/src/fix_print.cpp +++ b/src/fix_print.cpp @@ -29,11 +29,18 @@ using namespace FixConst; FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), - fp(NULL), string(NULL), copy(NULL), work(NULL) + fp(NULL), string(NULL), copy(NULL), work(NULL), var_print(NULL) { if (narg < 5) error->all(FLERR,"Illegal fix print command"); - nevery = force->inumeric(FLERR,arg[3]); - if (nevery <= 0) error->all(FLERR,"Illegal fix print command"); + if (strstr(arg[3],"v_") == arg[3]) { + int n = strlen(&arg[3][2]) + 1; + var_print = new char[n]; + strcpy(var_print,&arg[3][2]); + nevery = 1; + } else { + nevery = force->inumeric(FLERR,arg[3]); + if (nevery <= 0) error->all(FLERR,"Illegal fix print command"); + } MPI_Comm_rank(world,&me); @@ -89,13 +96,6 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : } delete [] title; - - // add nfirst to all computes that store invocation times - // since don't know a priori which are invoked via variables by this fix - // once in end_of_step() can set timestep for ones actually invoked - - const bigint nfirst = (update->ntimestep/nevery)*nevery + nevery; - modify->addstep_compute_all(nfirst); } /* ---------------------------------------------------------------------- */ @@ -103,6 +103,7 @@ FixPrint::FixPrint(LAMMPS *lmp, int narg, char **arg) : FixPrint::~FixPrint() { delete [] string; + delete [] var_print; memory->sfree(copy); memory->sfree(work); @@ -120,8 +121,35 @@ int FixPrint::setmask() /* ---------------------------------------------------------------------- */ +void FixPrint::init() +{ + if (var_print) { + ivar_print = input->variable->find(var_print); + if (ivar_print < 0) + error->all(FLERR,"Variable name for fix print timestep does not exist"); + if (!input->variable->equalstyle(ivar_print)) + error->all(FLERR,"Variable for fix print timestep is invalid style"); + next_print = static_cast + (input->variable->compute_equal(ivar_print)); + if (next_print <= update->ntimestep) + error->all(FLERR,"Fix print timestep variable returned a bad timestep"); + } else { + next_print = (update->ntimestep/nevery)*nevery + nevery; + } + + // add next_print to all computes that store invocation times + // since don't know a priori which are invoked via variables by this fix + // once in end_of_step() can set timestep for ones actually invoked + + modify->addstep_compute_all(next_print); +} + +/* ---------------------------------------------------------------------- */ + void FixPrint::end_of_step() { + if (update->ntimestep != next_print) return; + // make a copy of string to work on // substitute for $ variables (no printing) // append a newline and print final copy @@ -132,7 +160,15 @@ void FixPrint::end_of_step() strcpy(copy,string); input->substitute(copy,work,maxcopy,maxwork,0); - modify->addstep_compute(update->ntimestep + nevery); + if (var_print) { + next_print = static_cast + (input->variable->compute_equal(ivar_print)); + if (next_print <= update->ntimestep) + error->all(FLERR,"Fix print timestep variable returned a bad timestep"); + } else { + next_print = (update->ntimestep/nevery)*nevery + nevery; + } + modify->addstep_compute(next_print); if (me == 0) { if (screenflag && screen) fprintf(screen,"%s\n",copy); diff --git a/src/fix_print.h b/src/fix_print.h index 1f6efdf108..37b6680aee 100644 --- a/src/fix_print.h +++ b/src/fix_print.h @@ -29,6 +29,7 @@ class FixPrint : public Fix { public: FixPrint(class LAMMPS *, int, char **); ~FixPrint(); + void init(); int setmask(); void end_of_step(); @@ -37,6 +38,9 @@ class FixPrint : public Fix { FILE *fp; char *string,*copy,*work; int maxcopy,maxwork; + char *var_print; + int ivar_print; + bigint next_print; }; }