Limit atom energy change in fix dt/reset

Allow limiting of the maximum energy change of an atom in
fix dt/reset in addition to the existing distance limit.
Useful especially for high-energy irradiation.
This commit is contained in:
Risto Toijala 2018-05-23 15:24:04 +03:00
parent 0368202d12
commit b9a8f91753
3 changed files with 26 additions and 11 deletions

View File

@ -19,7 +19,9 @@ Tmin = minimum dt allowed which can be NULL (time units)
Tmax = maximum dt allowed which can be NULL (time units)
Xmax = maximum distance for an atom to move in one timestep (distance units)
zero or more keyword/value pairs may be appended
keyword = {units} :ul
keyword = {emax} or {units} :ul
{emax} value = Emax
Emax = maximum energy change for an atom in one timestep (energy units)
{units} value = {lattice} or {box}
lattice = Xmax is defined in lattice units
box = Xmax is defined in simulation box units :pre
@ -27,12 +29,14 @@ keyword = {units} :ul
[Examples:]
fix 5 all dt/reset 10 1.0e-5 0.01 0.1
fix 5 all dt/reset 10 0.01 2.0 0.2 units box :pre
fix 5 all dt/reset 10 0.01 2.0 0.2 units box
fix 5 all dt/reset 5 NULL 0.001 0.5 emax 30 units box :pre
[Description:]
Reset the timestep size every N steps during a run, so that no atom
moves further than Xmax, based on current atom velocities and forces.
moves further than Xmax, based on current atom velocities and forces,
and (optionally) no atom's energy changes more than Emax.
This can be useful when starting from a configuration with overlapping
atoms, where forces will be large. Or it can be useful when running
an impact simulation where one or more high-energy atoms collide with
@ -48,7 +52,9 @@ current velocity and force. Since performing this calculation exactly
would require the solution to a quartic equation, a cheaper estimate
is generated. The estimate is conservative in that the atom's
displacement is guaranteed not to exceed {Xmax}, though it may be
smaller.
smaller. Also, if the {Emax} value is given, for each atom, the
timestep is limited to a value that allows the atom's energy to change
by at most {Emax}.
Given this putative timestep for each atom, the minimum timestep value
across all atoms is computed. Then the {Tmin} and {Tmax} bounds are
@ -87,4 +93,4 @@ minimization"_minimize.html.
[Default:]
The option defaults is units = lattice.
The option defaults is units = lattice, and no energy change limit.

View File

@ -69,6 +69,7 @@ FixDtReset::FixDtReset(LAMMPS *lmp, int narg, char **arg) :
int scaleflag = 1;
emax = -1.0;
int iarg = 7;
while (iarg < narg) {
if (strcmp(arg[iarg],"units") == 0) {
@ -77,6 +78,11 @@ FixDtReset::FixDtReset(LAMMPS *lmp, int narg, char **arg) :
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal fix dt/reset command");
iarg += 2;
} else if (strcmp(arg[iarg],"emax") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix dt/reset command");
emax = force->numeric(FLERR,arg[iarg+1]);
if (emax <= 0.0) error->all(FLERR,"Illegal fix dt/reset command");
iarg += 2;
} else error->all(FLERR,"Illegal fix dt/reset command");
}
@ -117,6 +123,7 @@ void FixDtReset::init()
"Dump dcd/xtc timestamp may be wrong with fix dt/reset");
ftm2v = force->ftm2v;
mvv2e = force->mvv2e;
dt = update->dt;
}
@ -131,12 +138,10 @@ void FixDtReset::setup(int vflag)
void FixDtReset::end_of_step()
{
double dtv,dtf,dtsq;
double dtv,dtf,dte,dtsq;
double vsq,fsq,massinv;
double delx,dely,delz,delr;
// compute vmax and amax of any atom in group
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
@ -153,10 +158,14 @@ void FixDtReset::end_of_step()
else massinv = 1.0/mass[type[i]];
vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
fsq = f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
dtv = dtf = BIG;
dtv = dtf = dte = BIG;
if (vsq > 0.0) dtv = xmax/sqrt(vsq);
if (fsq > 0.0) dtf = sqrt(2.0*xmax/(ftm2v*sqrt(fsq)*massinv));
dt = MIN(dtv,dtf);
if (emax > 0.0 && vsq > 0.0 && fsq > 0.0) {
dte = emax/sqrt(fsq*vsq)/sqrt(ftm2v*mvv2e);
dt = MIN(dt, dte);
}
dtsq = dt*dt;
delx = dt*v[i][0] + 0.5*dtsq*massinv*f[i][0] * ftm2v;
dely = dt*v[i][1] + 0.5*dtsq*massinv*f[i][1] * ftm2v;

View File

@ -37,8 +37,8 @@ class FixDtReset : public Fix {
private:
bigint laststep;
int minbound,maxbound;
double tmin,tmax,xmax;
double ftm2v;
double tmin,tmax,xmax,emax;
double ftm2v,mvv2e;
double dt,t_laststep;
int respaflag;
};