mirror of https://github.com/lammps/lammps.git
Merge pull request #3514 from jrgissing/per-bond_custom_constraint
bond/react feature updates
This commit is contained in:
commit
4655039774
|
@ -42,13 +42,16 @@ Syntax
|
|||
* template-ID(post-reacted) = ID of a molecule template containing post-reaction topology
|
||||
* map_file = name of file specifying corresponding atom-IDs in the pre- and post-reacted templates
|
||||
* zero or more individual keyword/value pairs may be appended to each react argument
|
||||
* individual_keyword = *prob* or *max_rxn* or *stabilize_steps* or *custom_charges* or *molecule* or *modify_create*
|
||||
* individual_keyword = *prob* or *rate_limit* or *max_rxn* or *stabilize_steps* or *custom_charges* or *rescale_charges* or *molecule* or *modify_create*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*prob* values = fraction seed
|
||||
fraction = initiate reaction with this probability if otherwise eligible
|
||||
seed = random number seed (positive integer)
|
||||
*rate_limit* = Nlimit Nsteps
|
||||
Nlimit = maximum number of reactions allowed to occur within interval
|
||||
Nsteps = the interval (number of timesteps) over which to count reactions
|
||||
*max_rxn* value = N
|
||||
N = maximum number of reactions allowed to occur
|
||||
*stabilize_steps* value = timesteps
|
||||
|
@ -56,6 +59,9 @@ Syntax
|
|||
*custom_charges* value = *no* or fragment-ID
|
||||
*no* = update all atomic charges (default)
|
||||
fragment-ID = ID of molecule fragment whose charges are updated
|
||||
*rescale_charges* value = *no* or *yes*
|
||||
*no* = do not rescale atomic charges (default)
|
||||
*yes* = rescale charges such that total charge does not change during reaction
|
||||
*molecule* value = *off* or *inter* or *intra*
|
||||
*off* = allow both inter- and intramolecular reactions (default)
|
||||
*inter* = search for reactions between molecules with different IDs
|
||||
|
@ -514,28 +520,40 @@ example, the molecule fragment could consist of only the backbone
|
|||
atoms of a polymer chain. This constraint can be used to enforce a
|
||||
specific relative position and orientation between reacting molecules.
|
||||
|
||||
.. versionchanged:: TBD
|
||||
|
||||
The constraint of type "custom" has the following syntax:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
custom *varstring*
|
||||
|
||||
where "custom" is the required keyword, and *varstring* is a
|
||||
variable expression. The expression must be a valid equal-style
|
||||
variable formula that can be read by the :doc:`variable <variable>` command,
|
||||
where 'custom' is the required keyword, and *varstring* is a variable
|
||||
expression. The expression must be a valid equal-style variable
|
||||
formula that can be read by the :doc:`variable <variable>` command,
|
||||
after any special reaction functions are evaluated. If the resulting
|
||||
expression is zero, the reaction is prevented from occurring;
|
||||
otherwise, it is permitted to occur. There are two special reaction
|
||||
functions available, "rxnsum" and "rxnave". These functions operate
|
||||
over the atoms in a given reaction site, and have one mandatory
|
||||
argument and one optional argument. The mandatory argument is the
|
||||
identifier for an atom-style variable. The second, optional argument
|
||||
is the name of a molecule fragment in the pre-reaction template, and
|
||||
can be used to operate over a subset of atoms in the reaction site.
|
||||
The "rxnsum" function sums the atom-style variable over the reaction
|
||||
site, while the "rxnave" returns the average value. For example, a
|
||||
constraint on the total potential energy of atoms involved in the
|
||||
reaction can be imposed as follows:
|
||||
otherwise, it is permitted to occur. There are three special reaction
|
||||
functions available, 'rxnbond', 'rxnsum', and 'rxnave'. The 'rxnbond'
|
||||
function allows per-bond values to be included in the variable strings
|
||||
of the custom constraint. The 'rxnbond' function has two mandatory
|
||||
arguments. The first argument is the ID of a previously defined
|
||||
'compute bond/local' command. This 'compute bond/local' must compute
|
||||
only one value, e.g. bond force. This value is returned by the
|
||||
'rxnbond' function. The second argument is the name of a molecule
|
||||
fragment in the pre-reaction template. The fragment must contain
|
||||
exactly two atoms, corresponding to the atoms involved in the bond
|
||||
whose value should be calculated. An example of a constraint that uses
|
||||
the force experienced by a bond is provided below. The 'rxnsum' and
|
||||
'rxnave' functions operate over the atoms in a given reaction site,
|
||||
and have one mandatory argument and one optional argument. The
|
||||
mandatory argument is the identifier for an atom-style variable. The
|
||||
second, optional argument is the name of a molecule fragment in the
|
||||
pre-reaction template, and can be used to operate over a subset of
|
||||
atoms in the reaction site. The 'rxnsum' function sums the atom-style
|
||||
variable over the reaction site, while the 'rxnave' returns the
|
||||
average value. For example, a constraint on the total potential energy
|
||||
of atoms involved in the reaction can be imposed as follows:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
|
@ -547,11 +565,32 @@ reaction can be imposed as follows:
|
|||
custom "rxnsum(v_my_pe) > 100" # in Constraints section of map file
|
||||
|
||||
The above example prevents the reaction from occurring unless the
|
||||
total potential energy of the reaction site is above 100. The variable
|
||||
expression can be interpreted as the probability of the reaction
|
||||
occurring by using an inequality and the :doc:`random(x,y,z) <variable>`
|
||||
function available for equal-style variables, similar to the 'arrhenius'
|
||||
constraint above.
|
||||
total potential energy of the reaction site is above 100. As a second
|
||||
example, this time using the 'rxnbond' function, consider a modified
|
||||
Arrhenius constraint that depends on the bond force of a specific bond:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
# in LAMMPS input script
|
||||
|
||||
compute bondforce all bond/local force
|
||||
|
||||
compute ke_atom all ke/atom
|
||||
variable ke atom c_ke_atom
|
||||
|
||||
variable E_a equal 100.0 # activation energy
|
||||
variable l0 equal 1.0 # characteristic length
|
||||
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
# in Constraints section of map file
|
||||
|
||||
custom "exp(-(v_E_a-rxnbond(c_bondforce,bond1frag)*v_l0)/(2/3*rxnave(v_ke))) < random(0,1,12345)"
|
||||
|
||||
By using an inequality and the 'random(x,y,z)' function, the left-hand
|
||||
side can be interpreted as the probability of the reaction occurring,
|
||||
similar to the 'arrhenius' constraint above.
|
||||
|
||||
By default, all constraints must be satisfied for the reaction to
|
||||
occur. In other words, constraints are evaluated as a series of
|
||||
|
@ -598,6 +637,15 @@ eligible reaction only occurs if the random number is less than the
|
|||
fraction. Up to :math:`N` reactions are permitted to occur, as optionally
|
||||
specified by the *max_rxn* keyword.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
The *rate_limit* keyword can enforce an upper limit on the overall
|
||||
rate of the reaction. The number of reaction occurences is limited to
|
||||
Nlimit within an interval of Nsteps timesteps. No reactions are
|
||||
permitted to occur within the first Nsteps timesteps of the first run
|
||||
after reading a data file. Nlimit can be specified with an equal-style
|
||||
:doc:`variable <variable>`.
|
||||
|
||||
The *stabilize_steps* keyword allows for the specification of how many
|
||||
time steps a reaction site is stabilized before being returned to the
|
||||
overall system thermostat. In order to produce the most physical
|
||||
|
@ -616,6 +664,19 @@ charges are updated to those specified by the post-reaction template
|
|||
fragment defined in the pre-reaction molecule template. In this case,
|
||||
only the atomic charges of atoms in the molecule fragment are updated.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
The *rescale_charges* keyword can be used to ensure the total charge
|
||||
of the system does not change as reactions occur. When the argument is
|
||||
set to *yes*\ , a fixed value is added to the charges of post-reaction
|
||||
atoms such that their total charge equals that of the pre-reaction
|
||||
site. If only a subset of atomic charges are updated via the
|
||||
*custom_charges* keyword, this rescaling is applied to the subset.
|
||||
This keyword could be useful for systems that contain different
|
||||
molecules with the same reactive site, if the partial charges on the
|
||||
reaction site vary from molecule to molecule, or when removing
|
||||
reaction by-products.
|
||||
|
||||
The *molecule* keyword can be used to force the reaction to be
|
||||
intermolecular, intramolecular or either. When the value is set to
|
||||
*off*\ , molecule IDs are not considered when searching for reactions
|
||||
|
|
|
@ -80,7 +80,7 @@ static const char cite_fix_bond_react[] =
|
|||
#define DELTA 16
|
||||
#define MAXGUESS 20 // max # of guesses allowed by superimpose algorithm
|
||||
#define MAXCONARGS 14 // max # of arguments for any type of constraint + rxnID
|
||||
#define NUMVARVALS 4 // max # of keyword values that have variables as input
|
||||
#define NUMVARVALS 5 // max # of keyword values that have variables as input
|
||||
|
||||
// various statuses of superimpose algorithm:
|
||||
// ACCEPT: site successfully matched to pre-reacted template
|
||||
|
@ -98,7 +98,7 @@ enum{DISTANCE,ANGLE,DIHEDRAL,ARRHENIUS,RMSD,CUSTOM};
|
|||
enum{ATOM,FRAG};
|
||||
|
||||
// keyword values that accept variables as input
|
||||
enum{NEVERY,RMIN,RMAX,PROB};
|
||||
enum{NEVERY,RMIN,RMAX,PROB,NRATE};
|
||||
|
||||
// flag for one-proc vs shared reaction sites
|
||||
enum{LOCAL,GLOBAL};
|
||||
|
@ -138,10 +138,15 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
status = PROCEED;
|
||||
|
||||
// reaction functions used by 'custom' constraint
|
||||
nrxnfunction = 2;
|
||||
nrxnfunction = 3;
|
||||
rxnfunclist.resize(nrxnfunction);
|
||||
peratomflag.resize(nrxnfunction);
|
||||
rxnfunclist[0] = "rxnsum";
|
||||
peratomflag[0] = 1;
|
||||
rxnfunclist[1] = "rxnave";
|
||||
peratomflag[1] = 1;
|
||||
rxnfunclist[2] = "rxnbond";
|
||||
peratomflag[2] = 0;
|
||||
nvvec = 0;
|
||||
ncustomvars = 0;
|
||||
vvec = nullptr;
|
||||
|
@ -224,8 +229,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
memory->create(nghostlyskips,nreacts,"bond/react:nghostlyskips");
|
||||
memory->create(seed,nreacts,"bond/react:seed");
|
||||
memory->create(limit_duration,nreacts,"bond/react:limit_duration");
|
||||
memory->create(rate_limit,3,nreacts,"bond/react:rate_limit");
|
||||
memory->create(stabilize_steps_flag,nreacts,"bond/react:stabilize_steps_flag");
|
||||
memory->create(custom_charges_fragid,nreacts,"bond/react:custom_charges_fragid");
|
||||
memory->create(rescale_charges_flag,nreacts,"bond/react:rescale_charges_flag");
|
||||
memory->create(create_atoms_flag,nreacts,"bond/react:create_atoms_flag");
|
||||
memory->create(modify_create_fragid,nreacts,"bond/react:modify_create_fragid");
|
||||
memory->create(overlapsq,nreacts,"bond/react:overlapsq");
|
||||
|
@ -249,8 +256,11 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
fraction[i] = 1;
|
||||
seed[i] = 12345;
|
||||
max_rxn[i] = INT_MAX;
|
||||
for (int j = 0; j < 3; j++)
|
||||
rate_limit[j][i] = 0;
|
||||
stabilize_steps_flag[i] = 0;
|
||||
custom_charges_fragid[i] = -1;
|
||||
rescale_charges_flag[i] = 0;
|
||||
create_atoms_flag[i] = 0;
|
||||
modify_create_fragid[i] = -1;
|
||||
overlapsq[i] = 0;
|
||||
|
@ -286,55 +296,31 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
if (groupid == -1) error->all(FLERR,"Could not find fix group ID");
|
||||
groupbits[rxn] = group->bitmask[groupid];
|
||||
|
||||
if (strncmp(arg[iarg],"v_",2) == 0) {
|
||||
const char *str = &arg[iarg][2];
|
||||
var_id[NEVERY][rxn] = input->variable->find(str);
|
||||
if (var_id[NEVERY][rxn] < 0)
|
||||
error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str);
|
||||
if (!input->variable->equalstyle(var_id[NEVERY][rxn]))
|
||||
error->all(FLERR,"Fix bond/react: Variable {} is not equal-style", str);
|
||||
var_flag[NEVERY][rxn] = 1;
|
||||
} else {
|
||||
if (strncmp(arg[iarg],"v_",2) == 0) read_variable_keyword(&arg[iarg][2],NEVERY,rxn);
|
||||
else {
|
||||
nevery[rxn] = utils::inumeric(FLERR,arg[iarg],false,lmp);
|
||||
if (nevery[rxn] <= 0) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'Nevery' must be a positive integer");
|
||||
}
|
||||
iarg++;
|
||||
|
||||
double cutoff;
|
||||
if (strncmp(arg[iarg],"v_",2) == 0) {
|
||||
const char *str = &arg[iarg][2];
|
||||
var_id[RMIN][rxn] = input->variable->find(str);
|
||||
if (var_id[RMIN][rxn] < 0)
|
||||
error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str);
|
||||
if (!input->variable->equalstyle(var_id[RMIN][rxn]))
|
||||
error->all(FLERR,"Fix bond/react: Variable {} is not equal-style", str);
|
||||
double cutoff = input->variable->compute_equal(var_id[RMIN][rxn]);
|
||||
cutsq[rxn][0] = cutoff*cutoff;
|
||||
var_flag[RMIN][rxn] = 1;
|
||||
} else {
|
||||
double cutoff = utils::numeric(FLERR,arg[iarg],false,lmp);
|
||||
read_variable_keyword(&arg[iarg][2],RMIN,rxn);
|
||||
cutoff = input->variable->compute_equal(var_id[RMIN][rxn]);
|
||||
} else cutoff = utils::numeric(FLERR,arg[iarg],false,lmp);
|
||||
if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'Rmin' cannot be negative");
|
||||
cutsq[rxn][0] = cutoff*cutoff;
|
||||
}
|
||||
iarg++;
|
||||
|
||||
if (strncmp(arg[iarg],"v_",2) == 0) {
|
||||
const char *str = &arg[iarg][2];
|
||||
var_id[RMAX][rxn] = input->variable->find(str);
|
||||
if (var_id[RMAX][rxn] < 0)
|
||||
error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str);
|
||||
if (!input->variable->equalstyle(var_id[RMAX][rxn]))
|
||||
error->all(FLERR,"Fix bond/react: Variable is {} not equal-style", str);
|
||||
double cutoff = input->variable->compute_equal(var_id[RMAX][rxn]);
|
||||
cutsq[rxn][1] = cutoff*cutoff;
|
||||
var_flag[RMAX][rxn] = 1;
|
||||
} else {
|
||||
double cutoff = utils::numeric(FLERR,arg[iarg],false,lmp);
|
||||
read_variable_keyword(&arg[iarg][2],RMAX,rxn);
|
||||
cutoff = input->variable->compute_equal(var_id[RMAX][rxn]);
|
||||
} else cutoff = utils::numeric(FLERR,arg[iarg],false,lmp);
|
||||
if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/react command:"
|
||||
"'Rmax' cannot be negative");
|
||||
cutsq[rxn][1] = cutoff*cutoff;
|
||||
}
|
||||
iarg++;
|
||||
|
||||
unreacted_mol[rxn] = atom->find_molecule(arg[iarg++]);
|
||||
|
@ -344,7 +330,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
if (reacted_mol[rxn] == -1) error->all(FLERR,"Reacted molecule template ID for "
|
||||
"fix bond/react does not exist");
|
||||
|
||||
// read superimpose file
|
||||
//read map file
|
||||
files[rxn] = utils::strdup(arg[iarg]);
|
||||
iarg++;
|
||||
|
||||
|
@ -354,14 +340,8 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
"'prob' keyword has too few arguments");
|
||||
// check if probability is a variable
|
||||
if (strncmp(arg[iarg+1],"v_",2) == 0) {
|
||||
const char *str = &arg[iarg+1][2];
|
||||
var_id[PROB][rxn] = input->variable->find(str);
|
||||
if (var_id[PROB][rxn] < 0)
|
||||
error->all(FLERR,"Fix bond/react: Variable name {} does not exist", str);
|
||||
if (!input->variable->equalstyle(var_id[PROB][rxn]))
|
||||
error->all(FLERR,"Fix bond/react: Variable {} is not equal-style", str);
|
||||
read_variable_keyword(&arg[iarg+1][2],PROB,rxn);
|
||||
fraction[rxn] = input->variable->compute_equal(var_id[PROB][rxn]);
|
||||
var_flag[PROB][rxn] = 1;
|
||||
} else {
|
||||
// otherwise probability should be a number
|
||||
fraction[rxn] = utils::numeric(FLERR,arg[iarg+1],false,lmp);
|
||||
|
@ -380,6 +360,14 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
if (max_rxn[rxn] < 0) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'max_rxn' cannot be negative");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"rate_limit") == 0) {
|
||||
if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'rate_limit' has too few arguments");
|
||||
rate_limit[0][rxn] = 1; // serves as flag for rate_limit keyword
|
||||
if (strncmp(arg[iarg+1],"v_",2) == 0) read_variable_keyword(&arg[iarg+1][2],NRATE,rxn);
|
||||
else rate_limit[1][rxn] = utils::numeric(FLERR,arg[iarg+1],false,lmp);
|
||||
rate_limit[2][rxn] = utils::numeric(FLERR,arg[iarg+2],false,lmp);
|
||||
iarg += 3;
|
||||
} else if (strcmp(arg[iarg],"stabilize_steps") == 0) {
|
||||
if (stabilization_flag == 0) error->all(FLERR,"Stabilize_steps keyword "
|
||||
"used without stabilization keyword");
|
||||
|
@ -398,6 +386,13 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
"'custom_charges' keyword does not exist");
|
||||
}
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"rescale_charges") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'rescale_charges' has too few arguments");
|
||||
if (strcmp(arg[iarg+1],"no") == 0) rescale_charges_flag[rxn] = 0; //default
|
||||
else if (strcmp(arg[iarg+1],"yes") == 0) rescale_charges_flag[rxn] = 1;
|
||||
else error->one(FLERR,"Bond/react: Illegal option for 'rescale_charges' keyword");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"molecule") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: "
|
||||
"'molecule' has too few arguments");
|
||||
|
@ -433,21 +428,24 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
}
|
||||
|
||||
max_natoms = 0; // the number of atoms in largest molecule template
|
||||
max_rate_limit_steps = 0;
|
||||
for (int myrxn = 0; myrxn < nreacts; myrxn++) {
|
||||
twomol = atom->molecules[reacted_mol[myrxn]];
|
||||
max_natoms = MAX(max_natoms,twomol->natoms);
|
||||
max_rate_limit_steps = MAX(max_rate_limit_steps,rate_limit[2][myrxn]);
|
||||
}
|
||||
|
||||
memory->create(equivalences,max_natoms,2,nreacts,"bond/react:equivalences");
|
||||
memory->create(reverse_equiv,max_natoms,2,nreacts,"bond/react:reverse_equiv");
|
||||
memory->create(edge,max_natoms,nreacts,"bond/react:edge");
|
||||
memory->create(landlocked_atoms,max_natoms,nreacts,"bond/react:landlocked_atoms");
|
||||
memory->create(store_rxn_count,max_rate_limit_steps,nreacts,"bond/react:store_rxn_count");
|
||||
memory->create(custom_charges,max_natoms,nreacts,"bond/react:custom_charges");
|
||||
memory->create(delete_atoms,max_natoms,nreacts,"bond/react:delete_atoms");
|
||||
memory->create(create_atoms,max_natoms,nreacts,"bond/react:create_atoms");
|
||||
memory->create(chiral_atoms,max_natoms,6,nreacts,"bond/react:chiral_atoms");
|
||||
|
||||
for (int j = 0; j < nreacts; j++)
|
||||
for (int j = 0; j < nreacts; j++) {
|
||||
for (int i = 0; i < max_natoms; i++) {
|
||||
edge[i][j] = 0;
|
||||
custom_charges[i][j] = 1; // update all partial charges by default
|
||||
|
@ -462,6 +460,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
equivalences[i][m][j] = i+1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < max_rate_limit_steps; i++) {
|
||||
store_rxn_count[i][j] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// read all map files afterward
|
||||
for (int i = 0; i < nreacts; i++) {
|
||||
|
@ -471,7 +473,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
onemol->check_attributes();
|
||||
twomol->check_attributes();
|
||||
get_molxspecials();
|
||||
read(i);
|
||||
read_map_file(i);
|
||||
fclose(fp);
|
||||
if (ncreate == 0 && onemol->natoms != twomol->natoms)
|
||||
error->all(FLERR,"Fix bond/react: Reaction templates must contain the same number of atoms");
|
||||
|
@ -598,6 +600,7 @@ FixBondReact::~FixBondReact()
|
|||
memory->destroy(equivalences);
|
||||
memory->destroy(reverse_equiv);
|
||||
memory->destroy(landlocked_atoms);
|
||||
memory->destroy(store_rxn_count);
|
||||
memory->destroy(custom_charges);
|
||||
memory->destroy(delete_atoms);
|
||||
memory->destroy(create_atoms);
|
||||
|
@ -617,8 +620,10 @@ FixBondReact::~FixBondReact()
|
|||
memory->destroy(limit_duration);
|
||||
memory->destroy(var_flag);
|
||||
memory->destroy(var_id);
|
||||
memory->destroy(rate_limit);
|
||||
memory->destroy(stabilize_steps_flag);
|
||||
memory->destroy(custom_charges_fragid);
|
||||
memory->destroy(rescale_charges_flag);
|
||||
memory->destroy(molecule_keyword);
|
||||
memory->destroy(nconstraints);
|
||||
memory->destroy(constraintstr);
|
||||
|
@ -819,6 +824,16 @@ void FixBondReact::init_list(int /*id*/, NeighList *ptr)
|
|||
|
||||
void FixBondReact::post_integrate()
|
||||
{
|
||||
// update store_rxn_count on every step
|
||||
for (int myrxn = 0; myrxn < nreacts; myrxn++) {
|
||||
if (rate_limit[0][myrxn] == 1) {
|
||||
for (int i = rate_limit[2][myrxn]-1; i > 0; i--) {
|
||||
store_rxn_count[i][myrxn] = store_rxn_count[i-1][myrxn];
|
||||
}
|
||||
store_rxn_count[0][myrxn] = reaction_count_total[myrxn];
|
||||
}
|
||||
}
|
||||
|
||||
// check if any reactions could occur on this timestep
|
||||
int nevery_check = 1;
|
||||
for (int i = 0; i < nreacts; i++) {
|
||||
|
@ -873,6 +888,8 @@ void FixBondReact::post_integrate()
|
|||
for (int i = 0; i < nreacts; i++) {
|
||||
nattempt[i] = 0;
|
||||
}
|
||||
// reset per-bond compute map flag
|
||||
atoms2bondflag = 0;
|
||||
|
||||
int nlocal = atom->nlocal;
|
||||
int nall = atom->nlocal + atom->nghost;
|
||||
|
@ -911,8 +928,22 @@ void FixBondReact::post_integrate()
|
|||
|
||||
int j;
|
||||
for (rxnID = 0; rxnID < nreacts; rxnID++) {
|
||||
int rate_limit_flag = 1;
|
||||
if (rate_limit[0][rxnID] == 1) {
|
||||
int myrxn_count = store_rxn_count[rate_limit[2][rxnID]-1][rxnID];
|
||||
if (myrxn_count == -1) rate_limit_flag = 0;
|
||||
else {
|
||||
int nrxns_delta = reaction_count_total[rxnID] - myrxn_count;
|
||||
int my_nrate;
|
||||
if (var_flag[NRATE][rxnID] == 1) {
|
||||
my_nrate = input->variable->compute_equal(var_id[NRATE][rxnID]);
|
||||
} else my_nrate = rate_limit[1][rxnID];
|
||||
if (nrxns_delta > my_nrate) rate_limit_flag = 0;
|
||||
}
|
||||
}
|
||||
if ((update->ntimestep % nevery[rxnID]) ||
|
||||
(max_rxn[rxnID] <= reaction_count_total[rxnID])) continue;
|
||||
(max_rxn[rxnID] <= reaction_count_total[rxnID]) ||
|
||||
(rate_limit_flag == 0)) continue;
|
||||
for (int ii = 0; ii < nall; ii++) {
|
||||
partner[ii] = 0;
|
||||
finalpartner[ii] = 0;
|
||||
|
@ -1385,9 +1416,25 @@ void FixBondReact::superimpose_algorithm()
|
|||
std::random_device rnd;
|
||||
std::minstd_rand park_rng(rnd());
|
||||
|
||||
// check if we overstepped our reaction limit
|
||||
// check if we overstepped our reaction limit, via either max_rxn or rate_limit
|
||||
for (int i = 0; i < nreacts; i++) {
|
||||
if (reaction_count_total[i] > max_rxn[i]) {
|
||||
int overstep = 0;
|
||||
int max_rxn_overstep = reaction_count_total[i] - max_rxn[i];
|
||||
overstep = MAX(overstep,max_rxn_overstep);
|
||||
if (rate_limit[0][i] == 1) {
|
||||
int myrxn_count = store_rxn_count[rate_limit[2][i]-1][i];
|
||||
if (myrxn_count != -1) {
|
||||
int nrxn_delta = reaction_count_total[i] - myrxn_count;
|
||||
int my_nrate;
|
||||
if (var_flag[NRATE][i] == 1) {
|
||||
my_nrate = input->variable->compute_equal(var_id[NRATE][i]);
|
||||
} else my_nrate = rate_limit[1][i];
|
||||
int rate_limit_overstep = nrxn_delta - my_nrate;
|
||||
overstep = MAX(overstep,rate_limit_overstep);
|
||||
}
|
||||
}
|
||||
|
||||
if (overstep > 0) {
|
||||
// let's randomly choose rxns to skip, unbiasedly from local and ghostly
|
||||
int *local_rxncounts;
|
||||
int *all_localskips;
|
||||
|
@ -1395,8 +1442,11 @@ void FixBondReact::superimpose_algorithm()
|
|||
memory->create(all_localskips,nprocs,"bond/react:all_localskips");
|
||||
MPI_Gather(&local_rxn_count[i],1,MPI_INT,local_rxncounts,1,MPI_INT,0,world);
|
||||
if (me == 0) {
|
||||
int overstep = reaction_count_total[i] - max_rxn[i];
|
||||
int delta_rxn = reaction_count[i] + ghostly_rxn_count[i];
|
||||
// when using variable input for rate_limit, rate_limit_overstep could be > delta_rxn (below)
|
||||
// we need to limit overstep to the number of reactions on this timestep
|
||||
// essentially skipping all reactions, would be more efficient to use a skip_all flag
|
||||
if (overstep > delta_rxn) overstep = delta_rxn;
|
||||
int *rxn_by_proc;
|
||||
memory->create(rxn_by_proc,delta_rxn,"bond/react:rxn_by_proc");
|
||||
for (int j = 0; j < delta_rxn; j++)
|
||||
|
@ -1414,14 +1464,15 @@ void FixBondReact::superimpose_algorithm()
|
|||
else all_localskips[rxn_by_proc[j]]++;
|
||||
}
|
||||
memory->destroy(rxn_by_proc);
|
||||
reaction_count_total[i] -= overstep;
|
||||
}
|
||||
reaction_count_total[i] = max_rxn[i];
|
||||
MPI_Scatter(&all_localskips[0],1,MPI_INT,&nlocalskips[i],1,MPI_INT,0,world);
|
||||
MPI_Bcast(&nghostlyskips[i],1,MPI_INT,0,world);
|
||||
memory->destroy(local_rxncounts);
|
||||
memory->destroy(all_localskips);
|
||||
}
|
||||
}
|
||||
MPI_Bcast(&reaction_count_total[0], nreacts, MPI_INT, 0, world);
|
||||
|
||||
// this updates topology next step
|
||||
next_reneighbor = update->ntimestep;
|
||||
|
@ -2118,7 +2169,7 @@ double FixBondReact::get_temperature(tagint **myglove, int row_offset, int col)
|
|||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
get per-atom variable names used by custom constraint
|
||||
get per-atom variable names used by custom constraint
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondReact::customvarnames()
|
||||
|
@ -2140,6 +2191,7 @@ void FixBondReact::customvarnames()
|
|||
// find next reaction special function occurrence
|
||||
pos1 = std::string::npos;
|
||||
for (int i = 0; i < nrxnfunction; i++) {
|
||||
if (peratomflag[i] == 0) continue;
|
||||
pos = varstr.find(rxnfunclist[i],prev3+1);
|
||||
if (pos == std::string::npos) continue;
|
||||
if (pos < pos1) pos1 = pos;
|
||||
|
@ -2261,12 +2313,67 @@ double FixBondReact::custom_constraint(const std::string& varstr)
|
|||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
currently two 'rxn' functions: rxnsum and rxnave
|
||||
currently three 'rxn' functions: rxnsum, rxnave, and rxnbond
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixBondReact::rxnfunction(const std::string& rxnfunc, const std::string& varid,
|
||||
const std::string& fragid)
|
||||
{
|
||||
int ifrag = -1;
|
||||
if (fragid != "all") {
|
||||
ifrag = onemol->findfragment(fragid.c_str());
|
||||
if (ifrag < 0) error->one(FLERR,"Bond/react: Molecule fragment "
|
||||
"in reaction special function does not exist");
|
||||
}
|
||||
|
||||
// start with 'rxnbond' per-bond function
|
||||
// for 'rxnbond', varid corresponds to 'compute bond/local' name,
|
||||
// and fragid is a pre-reaction fragment containing the two atoms in the bond
|
||||
if (rxnfunc == "rxnbond") {
|
||||
int icompute,ibond,nsum;
|
||||
double perbondval;
|
||||
std::set<tagint> aset;
|
||||
std::string computeid = varid;
|
||||
std::map<std::set<tagint>,int>::iterator it;
|
||||
|
||||
if (computeid.substr(0,2) != "c_") error->one(FLERR,"Bond/react: Reaction special function compute "
|
||||
"name should begin with 'c_'");
|
||||
computeid = computeid.substr(2);
|
||||
icompute = modify->find_compute(computeid);
|
||||
if (icompute < 0) error->one(FLERR,"Bond/react: Reaction special function compute name does not exist");
|
||||
cperbond = modify->compute[icompute];
|
||||
std::string compute_style = cperbond->style;
|
||||
if (compute_style != "bond/local") error->one(FLERR,"Bond/react: Compute used by reaction "
|
||||
"special function 'rxnbond' must be of style 'bond/local'");
|
||||
if (cperbond->size_local_cols > 0) error->one(FLERR,"Bond/react: 'Compute bond/local' used by reaction "
|
||||
"special function 'rxnbond' must compute one value");
|
||||
|
||||
if (atoms2bondflag == 0) {
|
||||
atoms2bondflag = 1;
|
||||
get_atoms2bond(cperbond->groupbit);
|
||||
}
|
||||
|
||||
nsum = 0;
|
||||
for (int i = 0; i < onemol->natoms; i++) {
|
||||
if (onemol->fragmentmask[ifrag][i]) {
|
||||
aset.insert(glove[i][1]);
|
||||
nsum++;
|
||||
}
|
||||
}
|
||||
if (nsum != 2) error->one(FLERR,"Bond/react: Molecule fragment of reaction special function 'rxnbond' "
|
||||
"must contain exactly two atoms");
|
||||
|
||||
if (cperbond->invoked_local != lmp->update->ntimestep)
|
||||
cperbond->compute_local();
|
||||
|
||||
it = atoms2bond.find(aset);
|
||||
if (it == atoms2bond.end()) error->one(FLERR,"Bond/react: Unable to locate bond referenced by "
|
||||
"reaction special function 'rxnbond'");
|
||||
ibond = it->second;
|
||||
perbondval = cperbond->vector_local[ibond];
|
||||
return perbondval;
|
||||
}
|
||||
|
||||
int ivar = -1;
|
||||
for (int i = 0; i < ncustomvars; i++) {
|
||||
if (varid == customvarstrs[i]) {
|
||||
|
@ -2280,13 +2387,6 @@ double FixBondReact::rxnfunction(const std::string& rxnfunc, const std::string&
|
|||
error->one(FLERR,"Fix bond/react: Reaction special function variable "
|
||||
"name does not exist");
|
||||
|
||||
int ifrag = -1;
|
||||
if (fragid != "all") {
|
||||
ifrag = onemol->findfragment(fragid.c_str());
|
||||
if (ifrag < 0) error->one(FLERR,"Fix bond/react: Molecule fragment "
|
||||
"in reaction special function does not exist");
|
||||
}
|
||||
|
||||
int iatom;
|
||||
int nsum = 0;
|
||||
double sumvvec = 0;
|
||||
|
@ -2313,6 +2413,39 @@ double FixBondReact::rxnfunction(const std::string& rxnfunc, const std::string&
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
populate map to get bond index from atom IDs
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondReact::get_atoms2bond(int cgroupbit)
|
||||
{
|
||||
int i,m,atom1,atom2,btype,nb;
|
||||
std::set<tagint> aset;
|
||||
|
||||
int nlocal = atom->nlocal;
|
||||
tagint *tag = atom->tag;
|
||||
int *num_bond = atom->num_bond;
|
||||
tagint **bond_atom = atom->bond_atom;
|
||||
int **bond_type = atom->bond_type;
|
||||
int *mask = atom->mask;
|
||||
|
||||
m = 0;
|
||||
atoms2bond.clear();
|
||||
for (atom1 = 0; atom1 < nlocal; atom1++) {
|
||||
if (!(mask[atom1] & cgroupbit)) continue;
|
||||
nb = num_bond[atom1];
|
||||
for (i = 0; i < nb; i++) {
|
||||
btype = bond_type[atom1][i];
|
||||
atom2 = atom->map(bond_atom[atom1][i]);
|
||||
if (atom2 < 0 || !(mask[atom2] & cgroupbit)) continue;
|
||||
if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue;
|
||||
if (btype == 0) continue;
|
||||
aset = {tag[atom1], tag[atom2]};
|
||||
atoms2bond.insert(std::make_pair(aset,m++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return handedness (1 or -1) of a chiral center, given ordered set of coordinates
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -2985,6 +3118,8 @@ void FixBondReact::update_everything()
|
|||
}
|
||||
delete [] iskip;
|
||||
|
||||
if (update_num_mega == 0) continue;
|
||||
|
||||
// if inserted atoms and global map exists, reset map now instead
|
||||
// of waiting for comm since other pre-exchange fixes may use it
|
||||
// invoke map_init() b/c atom count has grown
|
||||
|
@ -3012,6 +3147,33 @@ void FixBondReact::update_everything()
|
|||
}
|
||||
}
|
||||
|
||||
// get charge rescale delta
|
||||
double charge_rescale_addend = 0;
|
||||
if (rescale_charges_flag[rxnID] == 1) {
|
||||
double sim_total_charge = 0;
|
||||
double mol_total_charge = 0;
|
||||
int n_custom_charge = 0;
|
||||
for (int i = 0; i < update_num_mega; i++) {
|
||||
rxnID = update_mega_glove[0][i];
|
||||
twomol = atom->molecules[reacted_mol[rxnID]];
|
||||
for (int j = 0; j < twomol->natoms; j++) {
|
||||
int jj = equivalences[j][1][rxnID]-1;
|
||||
if (atom->map(update_mega_glove[jj+1][i]) >= 0 &&
|
||||
atom->map(update_mega_glove[jj+1][i]) < nlocal) {
|
||||
if (landlocked_atoms[j][rxnID] == 1)
|
||||
type[atom->map(update_mega_glove[jj+1][i])] = twomol->type[j];
|
||||
if (twomol->qflag && atom->q_flag && custom_charges[jj][rxnID] == 1) {
|
||||
double *q = atom->q;
|
||||
sim_total_charge += q[atom->map(update_mega_glove[jj+1][i])];
|
||||
mol_total_charge += twomol->q[j];
|
||||
n_custom_charge++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
charge_rescale_addend = (sim_total_charge-mol_total_charge)/n_custom_charge;
|
||||
}
|
||||
|
||||
// update charges and types of landlocked atoms
|
||||
for (int i = 0; i < update_num_mega; i++) {
|
||||
rxnID = update_mega_glove[0][i];
|
||||
|
@ -3024,7 +3186,7 @@ void FixBondReact::update_everything()
|
|||
type[atom->map(update_mega_glove[jj+1][i])] = twomol->type[j];
|
||||
if (twomol->qflag && atom->q_flag && custom_charges[jj][rxnID] == 1) {
|
||||
double *q = atom->q;
|
||||
q[atom->map(update_mega_glove[jj+1][i])] = twomol->q[j];
|
||||
q[atom->map(update_mega_glove[jj+1][i])] = twomol->q[j]+charge_rescale_addend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3795,10 +3957,24 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate)
|
|||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read superimpose file
|
||||
add equal-style variable to keyword argument list
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondReact::read(int myrxn)
|
||||
void FixBondReact::read_variable_keyword(const char *myarg, int keyword, int myrxn)
|
||||
{
|
||||
var_id[keyword][myrxn] = input->variable->find(myarg);
|
||||
if (var_id[keyword][myrxn] < 0)
|
||||
error->all(FLERR,"Fix bond/react: Variable name {} does not exist",myarg);
|
||||
if (!input->variable->equalstyle(var_id[keyword][myrxn]))
|
||||
error->all(FLERR,"Fix bond/react: Variable {} is not equal-style",myarg);
|
||||
var_flag[keyword][myrxn] = 1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read map file
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondReact::read_map_file(int myrxn)
|
||||
{
|
||||
char line[MAXLINE],keyword[MAXLINE];
|
||||
char *eof,*ptr;
|
||||
|
@ -4299,34 +4475,71 @@ void FixBondReact::unpack_reverse_comm(int n, int *list, double *buf)
|
|||
|
||||
void FixBondReact::write_restart(FILE *fp)
|
||||
{
|
||||
int revision = 1;
|
||||
set[0].nreacts = nreacts;
|
||||
set[0].max_rate_limit_steps = max_rate_limit_steps;
|
||||
|
||||
for (int i = 0; i < nreacts; i++) {
|
||||
set[i].reaction_count_total = reaction_count_total[i];
|
||||
|
||||
strncpy(set[i].rxn_name,rxn_name[i],MAXLINE-1);
|
||||
set[i].rxn_name[MAXLINE-1] = '\0';
|
||||
}
|
||||
|
||||
if (me == 0) {
|
||||
int size = nreacts*sizeof(Set);
|
||||
fwrite(&size,sizeof(int),1,fp);
|
||||
fwrite(set,sizeof(Set),nreacts,fp);
|
||||
int rbufcount = max_rate_limit_steps*nreacts;
|
||||
int *rbuf;
|
||||
if (rbufcount) {
|
||||
memory->create(rbuf,rbufcount,"bond/react:rbuf");
|
||||
memcpy(rbuf,&store_rxn_count[0][0],sizeof(int)*rbufcount);
|
||||
}
|
||||
|
||||
if (me == 0) {
|
||||
int size = nreacts*sizeof(Set)+(rbufcount+1)*sizeof(int);
|
||||
fwrite(&size,sizeof(int),1,fp);
|
||||
fwrite(&revision,sizeof(int),1,fp);
|
||||
fwrite(set,sizeof(Set),nreacts,fp);
|
||||
if (rbufcount) fwrite(rbuf,sizeof(int),rbufcount,fp);
|
||||
}
|
||||
if (rbufcount) memory->destroy(rbuf);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
use selected state info from restart file to restart the Fix
|
||||
bond/react restart revisions numbers added after LAMMPS version 3 Nov 2022
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixBondReact::restart(char *buf)
|
||||
{
|
||||
Set *set_restart = (Set *) buf;
|
||||
for (int i = 0; i < set_restart[0].nreacts; i++) {
|
||||
int n,revision,r_nreacts,r_max_rate_limit_steps,ibufcount,n2cpy;
|
||||
int **ibuf;
|
||||
|
||||
n = 0;
|
||||
if (lmp->restart_ver > utils::date2num("3 Nov 2022")) revision = buf[n++];
|
||||
else revision = 0;
|
||||
|
||||
Set *set_restart = (Set *) &buf[n*sizeof(int)];
|
||||
r_nreacts = set_restart[0].nreacts;
|
||||
|
||||
if (revision > 0) {
|
||||
r_max_rate_limit_steps = set_restart[0].max_rate_limit_steps;
|
||||
ibufcount = r_max_rate_limit_steps*r_nreacts;
|
||||
memory->create(ibuf,r_max_rate_limit_steps,r_nreacts,"bond/react:ibuf");
|
||||
memcpy(&ibuf[0][0],&buf[sizeof(int)+r_nreacts*sizeof(Set)],sizeof(int)*ibufcount);
|
||||
n2cpy = r_max_rate_limit_steps;
|
||||
} else n2cpy = 0;
|
||||
|
||||
if (max_rate_limit_steps < n2cpy) n2cpy = max_rate_limit_steps;
|
||||
for (int i = 0; i < r_nreacts; i++) {
|
||||
for (int j = 0; j < nreacts; j++) {
|
||||
if (strcmp(set_restart[i].rxn_name,rxn_name[j]) == 0) {
|
||||
reaction_count_total[j] = set_restart[i].reaction_count_total;
|
||||
// read rate_limit restart information
|
||||
for (int k = 0; k < n2cpy; k++)
|
||||
store_rxn_count[k][j] = ibuf[k][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (revision > 0) memory->destroy(ibuf);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
|
@ -25,6 +25,10 @@ FixStyle(bond/react,FixBondReact);
|
|||
#define LMP_FIX_BOND_REACT_H
|
||||
|
||||
#include "fix.h"
|
||||
#include "compute.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
|
@ -64,8 +68,11 @@ class FixBondReact : public Fix {
|
|||
int stabilization_flag;
|
||||
int reset_mol_ids_flag;
|
||||
int custom_exclude_flag;
|
||||
int **rate_limit;
|
||||
int **store_rxn_count;
|
||||
int *stabilize_steps_flag;
|
||||
int *custom_charges_fragid;
|
||||
int *rescale_charges_flag;
|
||||
int *create_atoms_flag;
|
||||
int *modify_create_fragid;
|
||||
double *overlapsq;
|
||||
|
@ -74,9 +81,11 @@ class FixBondReact : public Fix {
|
|||
int *nconstraints;
|
||||
char **constraintstr;
|
||||
int nrxnfunction;
|
||||
std::vector<std::string> rxnfunclist;
|
||||
std::vector<std::string> rxnfunclist; // lists current special rxn function
|
||||
std::vector<int> peratomflag; // 1 if special rxn function uses per-atom variable (vs. per-bond)
|
||||
int atoms2bondflag; // 1 if atoms2bond map has been populated on this timestep
|
||||
int narrhenius;
|
||||
int **var_flag, **var_id; // for keyword values with variable inputs
|
||||
int **var_flag, **var_id; // for keyword values with variable inputs
|
||||
int status;
|
||||
int *groupbits;
|
||||
|
||||
|
@ -86,6 +95,7 @@ class FixBondReact : public Fix {
|
|||
int *reaction_count_total;
|
||||
int nmax; // max num local atoms
|
||||
int max_natoms; // max natoms in a molecule template
|
||||
int max_rate_limit_steps; // max rate limit interval
|
||||
tagint *partner, *finalpartner;
|
||||
double **distsq;
|
||||
int *nattempt;
|
||||
|
@ -160,7 +170,8 @@ class FixBondReact : public Fix {
|
|||
// but whose first neighbors haven't
|
||||
int glove_counter; // used to determine when to terminate Superimpose Algorithm
|
||||
|
||||
void read(int);
|
||||
void read_variable_keyword(const char *, int, int);
|
||||
void read_map_file(int);
|
||||
void EdgeIDs(char *, int);
|
||||
void Equivalences(char *, int);
|
||||
void DeleteAtoms(char *, int);
|
||||
|
@ -184,6 +195,7 @@ class FixBondReact : public Fix {
|
|||
double custom_constraint(const std::string &); // evaulate expression for custom constraint
|
||||
double rxnfunction(const std::string &, const std::string &,
|
||||
const std::string &); // eval rxn_sum and rxn_ave
|
||||
void get_atoms2bond(int);
|
||||
int get_chirality(double[12]); // get handedness given an ordered set of coordinates
|
||||
|
||||
void open(char *);
|
||||
|
@ -198,16 +210,18 @@ class FixBondReact : public Fix {
|
|||
void ghost_glovecast();
|
||||
void update_everything();
|
||||
int insert_atoms(tagint **, int);
|
||||
void unlimit_bond();
|
||||
void unlimit_bond(); // removes atoms from stabilization, and other post-reaction every-step operations
|
||||
void limit_bond(int);
|
||||
void dedup_mega_gloves(int); //dedup global mega_glove
|
||||
void write_restart(FILE *) override;
|
||||
void restart(char *buf) override;
|
||||
|
||||
// store restart data
|
||||
struct Set {
|
||||
int nreacts;
|
||||
char rxn_name[MAXLINE];
|
||||
int reaction_count_total;
|
||||
int max_rate_limit_steps;
|
||||
};
|
||||
Set *set;
|
||||
|
||||
|
@ -221,7 +235,9 @@ class FixBondReact : public Fix {
|
|||
int ncustomvars;
|
||||
std::vector<std::string> customvarstrs;
|
||||
int nvvec;
|
||||
double **vvec; // per-atom vector to store variable constraint atom-style variable values
|
||||
double **vvec; // per-atom vector to store custom constraint atom-style variable values
|
||||
Compute *cperbond; // pointer to 'compute bond/local' used by custom constraint ('rxnbond' function)
|
||||
std::map<std::set<tagint>, int> atoms2bond; // maps atom pair to index of local bond array
|
||||
std::vector<std::vector<Constraint>> constraints;
|
||||
|
||||
// DEBUG
|
||||
|
|
Loading…
Reference in New Issue