add diskfree check to fix halt

This commit is contained in:
Axel Kohlmeyer 2020-03-09 16:23:20 -04:00
parent 072ce8947b
commit 69a206f720
No known key found for this signature in database
GPG Key ID: D9B44E93BF0C375A
3 changed files with 118 additions and 45 deletions

View File

@ -14,23 +14,25 @@ Syntax
* ID, group-ID are documented in :doc:`fix <fix>` command
* halt = style name of this fix command
* N = check halt condition every N steps
* attribute = *bondmax* or *tlimit* or v\_name
* attribute = *bondmax* or *tlimit* or *diskfree* or *v\_name*
.. parsed-literal::
bondmax = length of longest bond in the system
tlimit = elapsed CPU time
bondmax = length of longest bond in the system (in length units)
tlimit = elapsed CPU time (in seconds)
diskfree = free disk space (in megabytes)
v_name = name of :doc:`equal-style variable <variable>`
* operator = "<" or "<=" or ">" or ">=" or "==" or "!=" or "\|\^"
* avalue = numeric value to compare attribute to
* zero or more keyword/value pairs may be appended
* keyword = *error* or *message*
* keyword = *error* or *message* or *path*
.. parsed-literal::
*error* value = *hard* or *soft* or *continue*
*message* value = *yes* or *no*
*path* value = path to check for free space (may be in quotes)
@ -38,25 +40,26 @@ Examples
""""""""
.. parsed-literal::
.. code-block:: LAMMPS
fix 10 all halt 1 bondmax > 1.5
fix 10 all print 10 v_myCheck != 0 error soft
fix 10 all halt 10 v_myCheck != 0 error soft
fix 10 all halt 100 diskfree < 100000.0 path "dump storage/."
Description
"""""""""""
Check a condition every N steps during a simulation run. N must be >=
1. If the condition is met, exit the run immediately. In this
context a "run" can be dynamics or minimization iterations, as
specified by the :doc:`run <run>` or :doc:`minimize <minimize>` command.
Check a condition every N steps during a simulation run. N must be >=1.
If the condition is met, exit the run. In this context a "run" can be
dynamics or minimization iterations, as specified by the :doc:`run
<run>` or :doc:`minimize <minimize>` command.
The specified group-ID is ignored by this fix.
The specified *attribute* can be one of the options listed above,
namely *bondmax* or *tlimit*\ , or an :doc:`equal-style variable <variable>` referenced as *v\_name*, where "name" is the
name of a variable that has been defined previously in the input
script.
The specified *attribute* can be one of the options listed above, namely
*bondmax*, *tlimit*\ , *diskfree*\ , or an :doc:`equal-style variable
<variable>` referenced as *v\_name*, where "name" is the name of a
variable that has been defined previously in the input script.
The *bondmax* attribute will loop over all bonds in the system,
compute their current lengths, and set *attribute* to the longest bond
@ -80,6 +83,14 @@ a run is performing 1000s of timesteps/sec, the overhead for syncing
the timer frequently across a large number of processors may be
non-negligible.
The *diskfree* attribute will check for available disk space (in
megabytes) on supported operating systems. By default it will
check the file system of the current working directory. This
can be changed with the optional *path* keyword, which will take
the path to a file or folder on the file system to be checked
as argument. This path must be given with single or double quotes,
if it contains blanks or other special characters (like \$).
Equal-style variables evaluate to a numeric value. See the
:doc:`variable <variable>` command for a description. They calculate
formulas which can involve mathematical operations, atom properties,
@ -91,7 +102,7 @@ following "bondmax" variable will calculate the same quantity as the
hstyle = bondmax option.
.. parsed-literal::
.. code-block:: LAMMPS
compute bdist all bond/local dist
compute bmax all reduce max c_bdist
@ -100,7 +111,7 @@ hstyle = bondmax option.
Thus these two versions of a fix halt command will do the same thing:
.. parsed-literal::
.. code-block:: LAMMPS
fix 10 all halt 1 bondmax > 1.5
fix 10 all halt 1 v_bondmax > 1.5
@ -156,7 +167,7 @@ the :doc:`run <run>` command.
Restrictions
""""""""""""
none
The *diskfree* attribute is currently only supported on Linux.
Related commands
""""""""""""""""
@ -166,4 +177,4 @@ Related commands
Default
"""""""
The option defaults are error = hard and message = yes.
The option defaults are error = hard, message = yes, and path = ".".

View File

@ -29,7 +29,7 @@
using namespace LAMMPS_NS;
using namespace FixConst;
enum{BONDMAX,TLIMIT,VARIABLE};
enum{BONDMAX,TLIMIT,DISKFREE,VARIABLE};
enum{LT,LE,GT,GE,EQ,NEQ,XOR};
enum{HARD,SOFT,CONTINUE};
enum{NOMSG,YESMSG};
@ -37,7 +37,7 @@ enum{NOMSG,YESMSG};
/* ---------------------------------------------------------------------- */
FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), idvar(NULL)
Fix(lmp, narg, arg), idvar(NULL), dlimit_path(NULL)
{
if (narg < 7) error->all(FLERR,"Illegal fix halt command");
nevery = force->inumeric(FLERR,arg[3]);
@ -46,37 +46,45 @@ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) :
// comparison args
idvar = NULL;
int iarg = 4;
if (strcmp(arg[4],"tlimit") == 0) attribute = TLIMIT;
else if (strcmp(arg[4],"bondmax") == 0) attribute = BONDMAX;
else if (strncmp(arg[4],"v_",2) == 0) {
if (strcmp(arg[iarg],"tlimit") == 0) {
attribute = TLIMIT;
} else if (strcmp(arg[iarg],"diskfree") == 0) {
attribute = DISKFREE;
dlimit_path = new char[2];
strcpy(dlimit_path,".");
} else if (strcmp(arg[iarg],"bondmax") == 0) {
attribute = BONDMAX;
} else if (strncmp(arg[iarg],"v_",2) == 0) {
attribute = VARIABLE;
int n = strlen(arg[4]);
int n = strlen(arg[iarg]);
idvar = new char[n];
strcpy(idvar,&arg[4][2]);
strcpy(idvar,&arg[iarg][2]);
ivar = input->variable->find(idvar);
if (ivar < 0) error->all(FLERR,"Could not find fix halt variable name");
if (input->variable->equalstyle(ivar) == 0)
error->all(FLERR,"Fix halt variable is not equal-style variable");
} else error->all(FLERR,"Invalid fix halt attribute");
if (strcmp(arg[5],"<") == 0) operation = LT;
else if (strcmp(arg[5],"<=") == 0) operation = LE;
else if (strcmp(arg[5],">") == 0) operation = GT;
else if (strcmp(arg[5],">=") == 0) operation = GE;
else if (strcmp(arg[5],"==") == 0) operation = EQ;
else if (strcmp(arg[5],"!=") == 0) operation = NEQ;
else if (strcmp(arg[5],"|^") == 0) operation = XOR;
++iarg;
if (strcmp(arg[iarg],"<") == 0) operation = LT;
else if (strcmp(arg[iarg],"<=") == 0) operation = LE;
else if (strcmp(arg[iarg],">") == 0) operation = GT;
else if (strcmp(arg[iarg],">=") == 0) operation = GE;
else if (strcmp(arg[iarg],"==") == 0) operation = EQ;
else if (strcmp(arg[iarg],"!=") == 0) operation = NEQ;
else if (strcmp(arg[iarg],"|^") == 0) operation = XOR;
else error->all(FLERR,"Invalid fix halt operator");
value = force->numeric(FLERR,arg[6]);
++iarg;
value = force->numeric(FLERR,arg[iarg]);
// parse optional args
eflag = SOFT;
msgflag = YESMSG;
int iarg = 7;
++iarg;
while (iarg < narg) {
if (strcmp(arg[iarg],"error") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix halt command");
@ -91,6 +99,19 @@ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) :
else if (strcmp(arg[iarg+1],"yes") == 0) msgflag = YESMSG;
else error->all(FLERR,"Illegal fix halt command");
iarg += 2;
} else if (strcmp(arg[iarg],"path") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix halt command");
++iarg;
int len = strlen(arg[iarg])+1;
delete[] dlimit_path;
dlimit_path = new char[len];
// strip off quotes, if present
if ( ((arg[iarg][0] == '"') || (arg[iarg][0] == '\''))
&& (arg[iarg][0] == arg[iarg][len-2]) ) {
strcpy(dlimit_path,&arg[iarg][1]);
dlimit_path[len-3] = '\0';
} else strcpy(dlimit_path,arg[iarg]);
++iarg;
} else error->all(FLERR,"Illegal fix halt command");
}
@ -109,6 +130,7 @@ FixHalt::FixHalt(LAMMPS *lmp, int narg, char **arg) :
FixHalt::~FixHalt()
{
delete [] idvar;
delete [] dlimit_path;
}
/* ---------------------------------------------------------------------- */
@ -140,6 +162,13 @@ void FixHalt::init()
nextstep = (update->ntimestep/nevery)*nevery + nevery;
thisstep = -1;
tratio = 0.5;
// check if disk limit is supported
if (attribute == DISKFREE) {
if (diskfree() < 0.0)
error->all(FLERR,"Disk limit not supported by OS or illegal path");
}
}
/* ---------------------------------------------------------------------- */
@ -162,6 +191,8 @@ void FixHalt::end_of_step()
if (attribute == TLIMIT) {
if (update->ntimestep != nextstep) return;
attvalue = tlimit();
} else if (attribute == DISKFREE) {
attvalue = diskfree();
} else if (attribute == BONDMAX) {
attvalue = bondmax();
} else {
@ -194,7 +225,8 @@ void FixHalt::end_of_step()
// print message with ID of fix halt in case multiple instances
char str[128];
sprintf(str,"Fix halt %s condition met on step " BIGINT_FORMAT " with value %g",
sprintf(str,"Fix halt condition for fix-id %s met on step "
BIGINT_FORMAT " with value %g",
id, update->ntimestep, attvalue);
if (eflag == HARD) {
@ -270,3 +302,31 @@ double FixHalt::tlimit()
return cpu;
}
/* ----------------------------------------------------------------------
determine available disk space, if supported. Return -1 if not.
------------------------------------------------------------------------- */
#if defined(__linux)
#include <sys/statvfs.h>
#endif
double FixHalt::diskfree()
{
#if defined(__linux)
struct statvfs fs;
double disk_free = -1.0;
if (dlimit_path) {
disk_free = 1.0e100;
int rv = statvfs(dlimit_path,&fs);
if (rv == 0)
disk_free = fs.f_bavail*fs.f_bsize/1048576.0;
else
disk_free = -1.0;
MPI_Bcast(&disk_free,1,MPI_DOUBLE,0,world);
}
return disk_free;
#else
return -1.0;
#endif
}

View File

@ -39,9 +39,11 @@ class FixHalt : public Fix {
bigint nextstep,thisstep;
double value,tratio;
char *idvar;
char *dlimit_path;
double bondmax();
double tlimit();
double diskfree();
};
}
@ -59,26 +61,26 @@ command-line option when running LAMMPS to see the offending line.
E: Could not find fix halt variable name
UNDOCUMENTED
Self-explanatory.
E: Fix halt variable is not equal-style variable
UNDOCUMENTED
Self-explanatory.
E: Invalid fix halt attribute
UNDOCUMENTED
Self-explanatory.
E: Invalid fix halt operator
UNDOCUMENTED
Self-explanatory.
E: Fix halt %s condition met on step %ld with value %g
E: Disk limit not supported by OS or illegal path
UNDOCUMENTED
Self-explanatory.
U: Cannot open fix print file %s
W: Fix halt condition for fix-id %s met on step %ld with value %g
The output file generated by the fix print command cannot be opened
Self explanatory.
*/