diff --git a/doc/src/fix_halt.rst b/doc/src/fix_halt.rst index 296be3aa10..8daa831ea8 100644 --- a/doc/src/fix_halt.rst +++ b/doc/src/fix_halt.rst @@ -14,23 +14,25 @@ Syntax * ID, group-ID are documented in :doc:`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 ` * 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 ` or :doc:`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 +` or :doc:`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 ` 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 +` 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 ` 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 ` 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 = ".". diff --git a/src/fix_halt.cpp b/src/fix_halt.cpp index 8ebb39f0e9..e201c44a46 100644 --- a/src/fix_halt.cpp +++ b/src/fix_halt.cpp @@ -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,8 +225,9 @@ 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", - id,update->ntimestep,attvalue); + sprintf(str,"Fix halt condition for fix-id %s met on step " + BIGINT_FORMAT " with value %g", + id, update->ntimestep, attvalue); if (eflag == HARD) { error->all(FLERR,str); @@ -270,3 +302,31 @@ double FixHalt::tlimit() return cpu; } + +/* ---------------------------------------------------------------------- + determine available disk space, if supported. Return -1 if not. +------------------------------------------------------------------------- */ +#if defined(__linux) +#include +#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 +} diff --git a/src/fix_halt.h b/src/fix_halt.h index 93c5e95078..ae1b8aeda7 100644 --- a/src/fix_halt.h +++ b/src/fix_halt.h @@ -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. */