Merge pull request #3958 from jrgissing/fix_deposit-var-keyword
Fix deposit var keyword
This commit is contained in:
@ -17,12 +17,16 @@ Syntax
|
||||
* M = insert a single atom or molecule every M steps
|
||||
* seed = random # seed (positive integer)
|
||||
* one or more keyword/value pairs may be appended to args
|
||||
* keyword = *region* or *id* or *global* or *local* or *near* or *gaussian* or *attempt* or *rate* or *vx* or *vy* or *vz* or *target* or *mol* or *molfrac* or *rigid* or *shake* or *orient* or *units*
|
||||
* keyword = *region* or *var* or *set* or *id* or *global* or *local* or *near* or *gaussian* or *attempt* or *rate* or *vx* or *vy* or *vz* or *target* or *mol* or *molfrac* or *rigid* or *shake* or *orient* or *units*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*region* value = region-ID
|
||||
region-ID = ID of region to use as insertion volume
|
||||
*var* value = name = variable name to evaluate for test of atom creation
|
||||
*set* values = dim name
|
||||
dim = *x* or *y* or *z*
|
||||
name = name of variable to set with x, y, or z atom position
|
||||
*id* value = *max* or *next*
|
||||
max = atom ID for new atom(s) is max ID of all current atoms plus one
|
||||
next = atom ID for new atom(s) increments by one for every deposition
|
||||
@ -193,17 +197,19 @@ simulation that is "nearby" the chosen x,y position. In this context,
|
||||
particles is less than the *delta* setting.
|
||||
|
||||
Once a trial x,y,z position has been selected, the insertion is only
|
||||
performed if no current atom in the simulation is within a distance R
|
||||
of any atom in the new particle, including the effect of periodic
|
||||
boundary conditions if applicable. R is defined by the *near*
|
||||
keyword. Note that the default value for R is 0.0, which will allow
|
||||
atoms to strongly overlap if you are inserting where other atoms are
|
||||
present. This distance test is performed independently for each atom
|
||||
in an inserted molecule, based on the randomly rotated configuration
|
||||
of the molecule. If this test fails, a new random position within the
|
||||
insertion volume is chosen and another trial is made. Up to Q
|
||||
attempts are made. If the particle is not successfully inserted,
|
||||
LAMMPS prints a warning message.
|
||||
performed if both the *near* and *var* keywords are satisfied (see below).
|
||||
If either the *near* or the *var* keyword is not satisfied, a new random
|
||||
position within the insertion volume is chosen and another trial is made.
|
||||
Up to Q attempts are made. If one or more particle insertions are not
|
||||
successful, LAMMPS prints a warning message.
|
||||
|
||||
The *near* keyword ensures that no current atom in the simulation is within
|
||||
a distance R of any atom in the new particle, including the effect of
|
||||
periodic boundary conditions if applicable. Note that the default value
|
||||
for R is 0.0, which will allow atoms to strongly overlap if you are
|
||||
inserting where other atoms are present. This distance test is performed
|
||||
independently for each atom in an inserted molecule, based on the randomly
|
||||
rotated configuration of the molecule.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -214,6 +220,24 @@ LAMMPS prints a warning message.
|
||||
existing particle. LAMMPS will issue a warning if R is smaller than
|
||||
this value, based on the radii of existing and inserted particles.
|
||||
|
||||
The *var* and *set* keywords can be used together to provide a criterion
|
||||
for accepting or rejecting the addition of an individual atom, based on its
|
||||
coordinates. The *name* specified for the *var* keyword is the name of an
|
||||
:doc:`equal-style variable <variable>` that should evaluate to a zero or
|
||||
non-zero value based on one or two or three variables that will store the
|
||||
*x*, *y*, or *z* coordinates of an atom (one variable per coordinate). If
|
||||
used, these other variables must be :doc:`internal-style variables
|
||||
<variable>` defined in the input script; their initial numeric value can be
|
||||
anything. They must be internal-style variables, because this command
|
||||
resets their values directly. The *set* keyword is used to identify the
|
||||
names of these other variables, one variable for the *x*-coordinate of a
|
||||
created atom, one for *y*, and one for *z*. When an atom is created, its
|
||||
:math:`(x,y,z)` coordinates become the values for any *set* variable that
|
||||
is defined. The *var* variable is then evaluated. If the returned value
|
||||
is 0.0, the atom is not created. If it is non-zero, the atom is created.
|
||||
For an example of how to use these keywords, see the
|
||||
:doc:`create_atoms <create_atoms>`command.
|
||||
|
||||
The *rate* option moves the insertion volume in the z direction (3d)
|
||||
or y direction (2d). This enables particles to be inserted from a
|
||||
successively higher height over time. Note that this parameter is
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "fix.h"
|
||||
#include "input.h"
|
||||
#include "lattice.h"
|
||||
#include "math_const.h"
|
||||
#include "math_extra.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "random_park.h"
|
||||
#include "region.h"
|
||||
#include "update.h"
|
||||
#include "variable.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
@ -209,6 +211,10 @@ FixDeposit::~FixDeposit()
|
||||
delete [] idrigid;
|
||||
delete [] idshake;
|
||||
delete [] idregion;
|
||||
delete [] vstr;
|
||||
delete [] xstr;
|
||||
delete [] ystr;
|
||||
delete [] zstr;
|
||||
memory->destroy(coords);
|
||||
memory->destroy(imageflags);
|
||||
}
|
||||
@ -226,6 +232,8 @@ int FixDeposit::setmask()
|
||||
|
||||
void FixDeposit::init()
|
||||
{
|
||||
warnflag = 1;
|
||||
|
||||
// set index and check validity of region
|
||||
|
||||
iregion = domain->get_region_by_id(idregion);
|
||||
@ -361,6 +369,8 @@ void FixDeposit::pre_exchange()
|
||||
} while (iregion->match(coord[0],coord[1],coord[2]) == 0);
|
||||
} else error->all(FLERR,"Unknown particle distribution in fix deposit");
|
||||
|
||||
if (varflag && vartest(coord[0],coord[1],coord[2]) == 0) continue;
|
||||
|
||||
// adjust vertical coord by offset
|
||||
|
||||
if (dimension == 2) coord[1] += offset;
|
||||
@ -583,8 +593,10 @@ void FixDeposit::pre_exchange()
|
||||
|
||||
// warn if not successful b/c too many attempts
|
||||
|
||||
if (!success && comm->me == 0)
|
||||
error->warning(FLERR,"Particle deposition was unsuccessful");
|
||||
if (warnflag && !success && comm->me == 0) {
|
||||
error->warning(FLERR,"One or more particle depositions were unsuccessful");
|
||||
warnflag = 0;
|
||||
}
|
||||
|
||||
// reset global natoms,nbonds,etc
|
||||
// increment maxtag_all and maxmol_all if necessary
|
||||
@ -661,6 +673,8 @@ void FixDeposit::options(int narg, char **arg)
|
||||
|
||||
iregion = nullptr;
|
||||
idregion = nullptr;
|
||||
varflag = 0;
|
||||
vstr = xstr = ystr = zstr = nullptr;
|
||||
mode = ATOM;
|
||||
molfrac = nullptr;
|
||||
rigidflag = 0;
|
||||
@ -680,6 +694,7 @@ void FixDeposit::options(int narg, char **arg)
|
||||
scaleflag = 1;
|
||||
targetflag = 0;
|
||||
orientflag = 0;
|
||||
warnflag = 1;
|
||||
rx = 0.0;
|
||||
ry = 0.0;
|
||||
rz = 0.0;
|
||||
@ -693,6 +708,27 @@ void FixDeposit::options(int narg, char **arg)
|
||||
idregion = utils::strdup(arg[iarg+1]);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg], "var") == 0) {
|
||||
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix deposit var", error);
|
||||
delete[] vstr;
|
||||
vstr = utils::strdup(arg[iarg + 1]);
|
||||
varflag = 1;
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg], "set") == 0) {
|
||||
if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix deposit set", error);
|
||||
if (strcmp(arg[iarg + 1], "x") == 0) {
|
||||
delete[] xstr;
|
||||
xstr = utils::strdup(arg[iarg + 2]);
|
||||
} else if (strcmp(arg[iarg + 1], "y") == 0) {
|
||||
delete[] ystr;
|
||||
ystr = utils::strdup(arg[iarg + 2]);
|
||||
} else if (strcmp(arg[iarg + 1], "z") == 0) {
|
||||
delete[] zstr;
|
||||
zstr = utils::strdup(arg[iarg + 2]);
|
||||
} else
|
||||
error->all(FLERR, "Unknown fix deposit set option {}", arg[iarg + 2]);
|
||||
iarg += 3;
|
||||
|
||||
} else if (strcmp(arg[iarg],"mol") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command");
|
||||
int imol = atom->find_molecule(arg[iarg+1]);
|
||||
@ -815,6 +851,39 @@ void FixDeposit::options(int narg, char **arg)
|
||||
iarg += 4;
|
||||
} else error->all(FLERR,"Illegal fix deposit command");
|
||||
}
|
||||
|
||||
// error check and further setup for variable test
|
||||
|
||||
if (!vstr && (xstr || ystr || zstr))
|
||||
error->all(FLERR, "Incomplete use of variables in fix deposit command");
|
||||
if (vstr && (!xstr && !ystr && !zstr))
|
||||
error->all(FLERR, "Incomplete use of variables in fix deposit command");
|
||||
|
||||
if (varflag) {
|
||||
vvar = input->variable->find(vstr);
|
||||
if (vvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", vstr);
|
||||
if (!input->variable->equalstyle(vvar))
|
||||
error->all(FLERR, "Variable for fix deposit is invalid style");
|
||||
|
||||
if (xstr) {
|
||||
xvar = input->variable->find(xstr);
|
||||
if (xvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", xstr);
|
||||
if (!input->variable->internalstyle(xvar))
|
||||
error->all(FLERR, "Variable for fix deposit is invalid style");
|
||||
}
|
||||
if (ystr) {
|
||||
yvar = input->variable->find(ystr);
|
||||
if (yvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", ystr);
|
||||
if (!input->variable->internalstyle(yvar))
|
||||
error->all(FLERR, "Variable for fix deposit is invalid style");
|
||||
}
|
||||
if (zstr) {
|
||||
zvar = input->variable->find(zstr);
|
||||
if (zvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", zstr);
|
||||
if (!input->variable->internalstyle(zvar))
|
||||
error->all(FLERR, "Variable for fix deposit is invalid style");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -908,3 +977,20 @@ void *FixDeposit::extract(const char *str, int &itype)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
test a generated atom position against variable evaluation
|
||||
first set x,y,z values in internal variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int FixDeposit::vartest(double x, double y, double z)
|
||||
{
|
||||
if (xstr) input->variable->internal_set(xvar, x);
|
||||
if (ystr) input->variable->internal_set(yvar, y);
|
||||
if (zstr) input->variable->internal_set(zvar, z);
|
||||
|
||||
double value = input->variable->compute_equal(vvar);
|
||||
|
||||
if (value == 0.0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -40,7 +40,8 @@ class FixDeposit : public Fix {
|
||||
private:
|
||||
int ninsert, ntype, nfreq, seed;
|
||||
int globalflag, localflag, maxattempt, rateflag, scaleflag, targetflag;
|
||||
int mode, rigidflag, shakeflag, idnext, distflag, orientflag;
|
||||
int mode, rigidflag, shakeflag, idnext, distflag, orientflag, warnflag;
|
||||
int varflag, vvar, xvar, yvar, zvar;
|
||||
double lo, hi, deltasq, nearsq, rate, sigma;
|
||||
double vxlo, vxhi, vylo, vyhi, vzlo, vzhi;
|
||||
double xlo, xhi, ylo, yhi, zlo, zhi, xmid, ymid, zmid;
|
||||
@ -48,6 +49,8 @@ class FixDeposit : public Fix {
|
||||
class Region *iregion;
|
||||
char *idregion;
|
||||
char *idrigid, *idshake;
|
||||
char *vstr, *xstr, *ystr, *zstr;
|
||||
char *xstr_copy, *ystr_copy, *zstr_copy;
|
||||
|
||||
class Molecule **onemols;
|
||||
int nmol, natom_max;
|
||||
@ -64,6 +67,7 @@ class FixDeposit : public Fix {
|
||||
|
||||
void find_maxid();
|
||||
void options(int, char **);
|
||||
int vartest(double, double, double); // evaluate a variable with new atom position
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
Reference in New Issue
Block a user