Merge pull request #1449 from akohlmey/fix-print-w-variable-step

Support using a variable instead of a constant interval for fix print
This commit is contained in:
Axel Kohlmeyer 2019-05-06 12:10:42 -04:00 committed by GitHub
commit a87d8e124f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 12 deletions

View File

@ -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}

View File

@ -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<bigint>
(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<bigint>
(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);

View File

@ -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;
};
}