Unverified Commit 69a206f7 authored by Axel Kohlmeyer's avatar Axel Kohlmeyer
Browse files

add diskfree check to fix halt

parent 072ce894
Loading
Loading
Loading
Loading
+29 −18
Original line number Diff line number Diff line
@@ -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 = ".".
+80 −20
Original line number Diff line number Diff line
@@ -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;

  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) {
  int iarg = 4;

  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
}
+10 −8
Original line number Diff line number Diff line
@@ -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.

*/