Improvements & bug fixes to fix def/press
This commit is contained in:
@ -29,10 +29,12 @@ Syntax
|
|||||||
NOTE: All other styles are documented by the :doc:`fix deform <fix_deform>` command
|
NOTE: All other styles are documented by the :doc:`fix deform <fix_deform>` command
|
||||||
|
|
||||||
*xy*, *xz*, *yz* args = style value
|
*xy*, *xz*, *yz* args = style value
|
||||||
style = *final* or *delta* or *vel* or *erate* or *trate* or *wiggle* or *variable* or *pressure*
|
style = *final* or *delta* or *vel* or *erate* or *trate* or *wiggle* or *variable* or *pressure* or *erate/rescale*
|
||||||
*pressure* values = target gain
|
*pressure* values = target gain
|
||||||
target = target pressure (pressure units)
|
target = target pressure (pressure units)
|
||||||
gain = proportional gain constant (1/(time * pressure) or 1/time units)
|
gain = proportional gain constant (1/(time * pressure) or 1/time units)
|
||||||
|
*erate/rescale* value = R
|
||||||
|
R = engineering shear strain rate (1/time units)
|
||||||
NOTE: All other styles are documented by the :doc:`fix deform <fix_deform>` command
|
NOTE: All other styles are documented by the :doc:`fix deform <fix_deform>` command
|
||||||
|
|
||||||
*box* = style value
|
*box* = style value
|
||||||
@ -159,6 +161,21 @@ details of a simulation and testing different values is
|
|||||||
recommended. One can also apply a maximum limit to the magnitude of
|
recommended. One can also apply a maximum limit to the magnitude of
|
||||||
the applied strain using the :ref:`max/rate <deform_max_rate>` option.
|
the applied strain using the :ref:`max/rate <deform_max_rate>` option.
|
||||||
|
|
||||||
|
The *erate/rescale* style operates similarly to the *erate* style with
|
||||||
|
a specified strain rate in units of 1/time. The difference is that
|
||||||
|
the change in the tilt factor will depend on the current length of
|
||||||
|
the box perpendicular to the shear direction, L, instead of the
|
||||||
|
original length, L0. The tilt factor T as a function of time will
|
||||||
|
change as
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
T(t) = T(t-1) + L\*erate\* \Delta t
|
||||||
|
|
||||||
|
where T(t-1) is the tilt factor on the previous timestep and :math:`\Delta t`
|
||||||
|
is the timestep size. This option may be useful in scenarios where
|
||||||
|
L changes in time.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The *box* parameter provides an additional control over the *x*, *y*,
|
The *box* parameter provides an additional control over the *x*, *y*,
|
||||||
|
|||||||
@ -110,6 +110,12 @@ FixDeformPressure::FixDeformPressure(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
}
|
}
|
||||||
set_extra[index].pgain = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
|
set_extra[index].pgain = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
|
||||||
i += 4;
|
i += 4;
|
||||||
|
} else if (strcmp(arg[iarg + 1], "erate/rescale") == 0) {
|
||||||
|
if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix deform/pressure erate/rescale", error);
|
||||||
|
set[index].style = ERATERS;
|
||||||
|
set[index].rate = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
|
||||||
|
iarg += 3;
|
||||||
|
i += 3;
|
||||||
} else error->all(FLERR, "Illegal fix deform/pressure command: {}", arg[iarg + 1]);
|
} else error->all(FLERR, "Illegal fix deform/pressure command: {}", arg[iarg + 1]);
|
||||||
|
|
||||||
} else if (strcmp(arg[iarg], "box") == 0) {
|
} else if (strcmp(arg[iarg], "box") == 0) {
|
||||||
@ -424,16 +430,31 @@ void FixDeformPressure::init()
|
|||||||
if (!pressure)
|
if (!pressure)
|
||||||
error->all(FLERR, "Pressure ID {} for fix deform/pressure does not exist", id_press);
|
error->all(FLERR, "Pressure ID {} for fix deform/pressure does not exist", id_press);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if yz [3] changes and will cause box flip, then xy [5] cannot be changing
|
||||||
|
// this is b/c the flips would induce continuous changes in xz
|
||||||
|
// in order to keep the edge vectors of the flipped shape matrix
|
||||||
|
// an integer combination of the edge vectors of the unflipped shape matrix
|
||||||
|
// error if style PRESSURE/ERATEER for yz, can't calculate if box flip occurs
|
||||||
|
|
||||||
|
if (set[3].style && set[5].style) {
|
||||||
|
int flag = 0;
|
||||||
|
double lo,hi;
|
||||||
|
if (flipflag && set[3].style == PRESSURE)
|
||||||
|
error->all(FLERR, "Fix {} cannot use yz pressure with xy", style);
|
||||||
|
if (flipflag && set[3].style == ERATERS)
|
||||||
|
error->all(FLERR, "Fix {} cannot use yz erate/rescale with xy", style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute T,P if needed before integrator starts
|
compute T,P before integrator starts
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixDeformPressure::setup(int /*vflag*/)
|
void FixDeformPressure::setup(int /*vflag*/)
|
||||||
{
|
{
|
||||||
// trigger virial computation on next timestep
|
// trigger virial computation, if needed, on next timestep
|
||||||
if (pressure_flag) pressure->addstep(update->ntimestep+1);
|
if (pressure_flag) pressure->addstep(update->ntimestep + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -446,7 +467,20 @@ void FixDeformPressure::end_of_step()
|
|||||||
|
|
||||||
// set new box size for strain-based dims
|
// set new box size for strain-based dims
|
||||||
|
|
||||||
if (strain_flag) FixDeform::apply_strain();
|
if (strain_flag) {
|
||||||
|
FixDeform::apply_strain();
|
||||||
|
|
||||||
|
for (int i = 3; i < 6; i++) {
|
||||||
|
if (set[i].style == ERATERS) {
|
||||||
|
double L = domain->zprd;
|
||||||
|
if (i == 5) L = domain->yprd;
|
||||||
|
|
||||||
|
h_rate[i] = set[i].rate * L;
|
||||||
|
set_extra[i].cumulative_shift += update->dt * h_rate[i];
|
||||||
|
set[i].tilt_target = set[i].tilt_start + set_extra[i].cumulative_shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set new box size for pressure-based dims
|
// set new box size for pressure-based dims
|
||||||
|
|
||||||
@ -479,12 +513,33 @@ void FixDeformPressure::end_of_step()
|
|||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
set_extra[i].prior_pressure = pressure->vector[i];
|
set_extra[i].prior_pressure = pressure->vector[i];
|
||||||
set_extra[i].prior_rate = ((set[i].hi_target - set[i].lo_target) /
|
set_extra[i].prior_rate = ((set[i].hi_target - set[i].lo_target) /
|
||||||
(domain->boxhi[i] - domain->boxlo[i]) - 1.0) / update->dt;
|
domain->prd[i] - 1.0) / update->dt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varflag) modify->addstep_compute(update->ntimestep + nevery);
|
if (varflag) modify->addstep_compute(update->ntimestep + nevery);
|
||||||
|
|
||||||
|
// If tilting while evolving linear dimension, sum remapping effects
|
||||||
|
// otherwise, update_domain() will inaccurately use the current
|
||||||
|
// linear dimension to apply prior remappings
|
||||||
|
|
||||||
|
for (int i = 3; i < 6; i++) {
|
||||||
|
int idenom = 0;
|
||||||
|
if (i == 3) idenom = 1;
|
||||||
|
if (set[i].style && (set_box.style || set[idenom].style)) {
|
||||||
|
// Add prior remappings. If the box remaps this timestep, don't
|
||||||
|
// add it yet so update_domain() will first detect the remapping
|
||||||
|
set[i].tilt_target += set_extra[i].cumulative_remap;
|
||||||
|
|
||||||
|
// Update remapping for next timestep
|
||||||
|
double prd = set[idenom].hi_target - set[idenom].lo_target;
|
||||||
|
double prdinv = 1.0 / prd;
|
||||||
|
if (set[i].tilt_target * prdinv < -0.5)
|
||||||
|
set_extra[i].cumulative_remap += prd;
|
||||||
|
if (set[i].tilt_target * prdinv > 0.5)
|
||||||
|
set_extra[i].cumulative_remap -= prd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FixDeform::update_domain();
|
FixDeform::update_domain();
|
||||||
|
|
||||||
@ -556,26 +611,24 @@ void FixDeformPressure::apply_pressure()
|
|||||||
|
|
||||||
h_ratelo[i] = -0.5 * h_rate[i];
|
h_ratelo[i] = -0.5 * h_rate[i];
|
||||||
|
|
||||||
double offset = 0.5 * (domain->boxhi[i] - domain->boxlo[i]) * (1.0 + update->dt * h_rate[i]);
|
double shift = domain->prd[i] * update->dt * h_rate[i];
|
||||||
set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - offset;
|
set_extra[i].cumulative_shift += shift;
|
||||||
set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + offset;
|
set[i].lo_target = set[i].lo_start - 0.5 * set_extra[i].cumulative_shift;
|
||||||
|
set[i].hi_target = set[i].hi_start + 0.5 * set_extra[i].cumulative_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 3; i < 6; i++) {
|
for (int i = 3; i < 6; i++) {
|
||||||
if (set[i].style != PRESSURE) continue;
|
if (set[i].style != PRESSURE) continue;
|
||||||
|
|
||||||
double L, tilt, pcurrent;
|
double L, pcurrent;
|
||||||
if (i == 3) {
|
if (i == 3) {
|
||||||
L = domain->zprd;
|
L = domain->zprd;
|
||||||
tilt = domain->yz;
|
|
||||||
pcurrent = tensor[5];
|
pcurrent = tensor[5];
|
||||||
} else if (i == 4) {
|
} else if (i == 4) {
|
||||||
L = domain->zprd;
|
L = domain->zprd;
|
||||||
tilt = domain->xz + update->dt;
|
|
||||||
pcurrent = tensor[4];
|
pcurrent = tensor[4];
|
||||||
} else {
|
} else {
|
||||||
L = domain->yprd;
|
L = domain->yprd;
|
||||||
tilt = domain->xy;
|
|
||||||
pcurrent = tensor[3];
|
pcurrent = tensor[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +645,8 @@ void FixDeformPressure::apply_pressure()
|
|||||||
if (fabs(h_rate[i]) > max_h_rate)
|
if (fabs(h_rate[i]) > max_h_rate)
|
||||||
h_rate[i] = max_h_rate * h_rate[i] / fabs(h_rate[i]);
|
h_rate[i] = max_h_rate * h_rate[i] / fabs(h_rate[i]);
|
||||||
|
|
||||||
set[i].tilt_target = tilt + update->dt * h_rate[i];
|
set_extra[i].cumulative_shift += update->dt * h_rate[i];
|
||||||
|
set[i].tilt_target = set[i].tilt_start + set_extra[i].cumulative_shift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,9 +683,9 @@ void FixDeformPressure::apply_volume()
|
|||||||
double dt = update->dt;
|
double dt = update->dt;
|
||||||
double e1i = set_extra[i].prior_rate;
|
double e1i = set_extra[i].prior_rate;
|
||||||
double e2i = set_extra[fixed].prior_rate;
|
double e2i = set_extra[fixed].prior_rate;
|
||||||
double L1i = domain->boxhi[i] - domain->boxlo[i];
|
double L1i = domain->prd[i];
|
||||||
double L2i = domain->boxhi[fixed] - domain->boxlo[fixed];
|
double L2i = domain->prd[fixed];
|
||||||
double L3i = domain->boxhi[dynamic1] - domain->boxlo[dynamic1];
|
double L3i = domain->prd[dynamic1];
|
||||||
double L3 = (set[dynamic1].hi_target - set[dynamic1].lo_target);
|
double L3 = (set[dynamic1].hi_target - set[dynamic1].lo_target);
|
||||||
double Vi = L1i * L2i * L3i;
|
double Vi = L1i * L2i * L3i;
|
||||||
double V = L3 * L1i * L2i;
|
double V = L3 * L1i * L2i;
|
||||||
@ -680,7 +734,7 @@ void FixDeformPressure::apply_volume()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h_rate[i] = (2.0 * shift / (domain->boxhi[i] - domain->boxlo[i]) - 1.0) / update->dt;
|
h_rate[i] = (2.0 * shift / domain->prd[i] - 1.0) / update->dt;
|
||||||
h_ratelo[i] = -0.5 * h_rate[i];
|
h_ratelo[i] = -0.5 * h_rate[i];
|
||||||
|
|
||||||
set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - shift;
|
set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - shift;
|
||||||
@ -742,7 +796,7 @@ void FixDeformPressure::apply_box()
|
|||||||
set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + shift;
|
set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + shift;
|
||||||
|
|
||||||
// Recalculate h_rate
|
// Recalculate h_rate
|
||||||
h_rate[i] = (set[i].hi_target - set[i].lo_target) / (domain->boxhi[i] - domain->boxlo[i]) - 1.0;
|
h_rate[i] = (set[i].hi_target - set[i].lo_target) / domain->prd[i] - 1.0;
|
||||||
h_rate[i] /= update->dt;
|
h_rate[i] /= update->dt;
|
||||||
h_ratelo[i] = -0.5 * h_rate[i];
|
h_ratelo[i] = -0.5 * h_rate[i];
|
||||||
}
|
}
|
||||||
@ -767,14 +821,14 @@ void FixDeformPressure::apply_box()
|
|||||||
if (fabs(v_rate) > max_h_rate)
|
if (fabs(v_rate) > max_h_rate)
|
||||||
v_rate = max_h_rate * v_rate / fabs(v_rate);
|
v_rate = max_h_rate * v_rate / fabs(v_rate);
|
||||||
|
|
||||||
scale = (1.0 + update->dt * v_rate);
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
shift = 0.5 * (set[i].hi_target - set[i].lo_target) * scale;
|
shift = (set[i].hi_target - set[i].lo_target) * update->dt * v_rate;
|
||||||
set[i].lo_target = 0.5 * (set[i].lo_start + set[i].hi_start) - shift;
|
set_extra[6].cumulative_vshift[i] += shift;
|
||||||
set[i].hi_target = 0.5 * (set[i].lo_start + set[i].hi_start) + shift;
|
set[i].lo_target -= 0.5 * set_extra[6].cumulative_vshift[i];
|
||||||
|
set[i].hi_target += 0.5 * set_extra[6].cumulative_vshift[i];
|
||||||
|
|
||||||
// Recalculate h_rate
|
// Recalculate h_rate
|
||||||
h_rate[i] = (set[i].hi_target - set[i].lo_target) / (domain->boxhi[i] - domain->boxlo[i]) - 1.0;
|
h_rate[i] = (set[i].hi_target - set[i].lo_target) / domain->prd[i] - 1.0;
|
||||||
h_rate[i] /= update->dt;
|
h_rate[i] /= update->dt;
|
||||||
h_ratelo[i] = -0.5 * h_rate[i];
|
h_ratelo[i] = -0.5 * h_rate[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,9 @@ class FixDeformPressure : public FixDeform {
|
|||||||
struct SetExtra {
|
struct SetExtra {
|
||||||
double ptarget, pgain;
|
double ptarget, pgain;
|
||||||
double prior_pressure, prior_rate;
|
double prior_pressure, prior_rate;
|
||||||
|
double cumulative_shift;
|
||||||
|
double cumulative_vshift[3];
|
||||||
|
double cumulative_remap;
|
||||||
int saved;
|
int saved;
|
||||||
char *pstr;
|
char *pstr;
|
||||||
int pvar, pvar_flag;
|
int pvar, pvar_flag;
|
||||||
|
|||||||
@ -63,7 +63,7 @@ irregular(nullptr), set(nullptr)
|
|||||||
int nskip;
|
int nskip;
|
||||||
if (utils::strmatch(style, "^deform/pressure")) {
|
if (utils::strmatch(style, "^deform/pressure")) {
|
||||||
child_parameters.insert("box");
|
child_parameters.insert("box");
|
||||||
child_styles.insert({{"pressure", 4}, {"pressure/mean", 4}, {"volume", 2}});
|
child_styles.insert({{"pressure", 4}, {"pressure/mean", 4}, {"erate/rescale", 3}, {"volume", 2}});
|
||||||
}
|
}
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class FixDeform : public Fix {
|
|||||||
int remapflag; // whether x,v are remapped across PBC
|
int remapflag; // whether x,v are remapped across PBC
|
||||||
int dimflag[6]; // which dims are deformed
|
int dimflag[6]; // which dims are deformed
|
||||||
|
|
||||||
enum { NONE, FINAL, DELTA, SCALE, VEL, ERATE, TRATE, VOLUME, WIGGLE, VARIABLE, PRESSURE, PMEAN };
|
enum { NONE, FINAL, DELTA, SCALE, VEL, ERATE, TRATE, VOLUME, WIGGLE, VARIABLE, PRESSURE, PMEAN, ERATERS };
|
||||||
enum { ONE_FROM_ONE, ONE_FROM_TWO, TWO_FROM_ONE };
|
enum { ONE_FROM_ONE, ONE_FROM_TWO, TWO_FROM_ONE };
|
||||||
|
|
||||||
FixDeform(class LAMMPS *, int, char **);
|
FixDeform(class LAMMPS *, int, char **);
|
||||||
|
|||||||
Reference in New Issue
Block a user