forked from lijiext/lammps
bond/react: delete atoms
allows deleting of a user-specified set of atoms, based on topology
This commit is contained in:
parent
482e120af4
commit
53e66dcd15
|
@ -70,7 +70,8 @@ changes will be referred to as 'reactions' throughout this
|
|||
documentation. Topology changes are defined in pre- and post-reaction
|
||||
molecule templates and can include creation and deletion of bonds,
|
||||
angles, dihedrals, impropers, bond-types, angle-types, dihedral-types,
|
||||
atom-types, or atomic charges.
|
||||
atom-types, or atomic charges. In addition, reaction by-products or
|
||||
other molecules can be identified and deleted.
|
||||
|
||||
Fix bond/react does not use quantum mechanical (eg. fix qmmm) or
|
||||
pairwise bond-order potential (eg. Tersoff or AIREBO) methods to
|
||||
|
@ -79,7 +80,7 @@ probabilistic criteria to effect predetermined topology changes in
|
|||
simulations using standard force fields.
|
||||
|
||||
This fix was created to facilitate the dynamic creation of polymeric,
|
||||
amorphous or highly cross-linked systems. A suggested workflow for
|
||||
amorphous or highly-crosslinked systems. A suggested workflow for
|
||||
using this fix is: 1) identify a reaction to be simulated 2) build a
|
||||
molecule template of the reaction site before the reaction has
|
||||
occurred 3) build a molecule template of the reaction site after the
|
||||
|
@ -203,15 +204,16 @@ A discussion of correctly handling this is also provided on the
|
|||
The map file is a text document with the following format:
|
||||
|
||||
A map file has a header and a body. The header of map file the
|
||||
contains one mandatory keyword and two optional keywords. The
|
||||
contains one mandatory keyword and three optional keywords. The
|
||||
mandatory keyword is 'equivalences' and the optional keywords are
|
||||
'edgeIDs' and 'customIDs':
|
||||
'edgeIDs' and 'deleteIDs' and 'customIDs':
|
||||
|
||||
N {equivalences} = # of atoms N in the reaction molecule templates
|
||||
N {edgeIDs} = # of edge atoms N in the pre-reacted molecule template
|
||||
N {deleteIDs} = # of atoms N that are specified for deletion
|
||||
N {customIDs} = # of atoms N that are specified for a custom update :pre
|
||||
|
||||
The body of the map file contains two mandatory sections and two
|
||||
The body of the map file contains two mandatory sections and three
|
||||
optional sections. The first mandatory section begins with the keyword
|
||||
'BondingIDs' and lists the atom IDs of the bonding atom pair in the
|
||||
pre-reacted molecule template. The second mandatory section begins
|
||||
|
@ -222,10 +224,12 @@ second column is the corresponding atom ID of the post-reacted
|
|||
molecule template. The first optional section begins with the keyword
|
||||
'EdgeIDs' and lists the atom IDs of edge atoms in the pre-reacted
|
||||
molecule template. The second optional section begins with the keyword
|
||||
'Custom Edges' and allows for forcing the update of a specific atom's
|
||||
atomic charge. The first column is the ID of an atom near the edge of
|
||||
the pre-reacted molecule template, and the value of the second column
|
||||
is either 'none' or 'charges.' Further details are provided in the
|
||||
'DeleteIDs' and lists the atom IDs of pre-reaction template atoms to
|
||||
delete. The third optional section begins with the keyword 'Custom
|
||||
Edges' and allows for forcing the update of a specific atom's atomic
|
||||
charge. The first column is the ID of an atom near the edge of the
|
||||
pre-reacted molecule template, and the value of the second column is
|
||||
either 'none' or 'charges.' Further details are provided in the
|
||||
discussion of the 'update_edges' keyword.
|
||||
|
||||
A sample map file is given below:
|
||||
|
@ -309,7 +313,16 @@ edge are unaffected by this setting.
|
|||
|
||||
A few other considerations:
|
||||
|
||||
It may be beneficial to ensure reacting atoms are at a certain
|
||||
Many reactions result in one or more atoms that are considered
|
||||
unwanted by-products. Therefore, bond/react provides the option to
|
||||
delete a user-specified set of atoms. These pre-reaction atoms are
|
||||
identified in the map file. A deleted atom must still be included in
|
||||
the post-reaction molecule template, in which it cannot be bonded to
|
||||
an undeleted atom. In addition to deleting unwanted reaction
|
||||
by-products, this feature can be used to remove specific topologies,
|
||||
such as small rings, that may be otherwise indistinguishable.
|
||||
|
||||
Also, it may be beneficial to ensure reacting atoms are at a certain
|
||||
temperature before being released to the overall thermostat. For this,
|
||||
you can use the internally-created dynamic group named
|
||||
"bond_react_MASTER_group." For example, adding the following command
|
||||
|
|
|
@ -275,12 +275,14 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) :
|
|||
memory->create(edge,max_natoms,nreacts,"bond/react:edge");
|
||||
memory->create(landlocked_atoms,max_natoms,nreacts,"bond/react:landlocked_atoms");
|
||||
memory->create(custom_edges,max_natoms,nreacts,"bond/react:custom_edges");
|
||||
memory->create(delete_atoms,max_natoms,nreacts,"bond/react:delete_atoms");
|
||||
|
||||
for (int j = 0; j < nreacts; j++)
|
||||
for (int i = 0; i < max_natoms; i++) {
|
||||
edge[i][j] = 0;
|
||||
if (update_edges_flag[j] == 1) custom_edges[i][j] = 1;
|
||||
else custom_edges[i][j] = 0;
|
||||
delete_atoms[i][j] = 0;
|
||||
}
|
||||
|
||||
// read all map files afterward
|
||||
|
@ -393,6 +395,7 @@ FixBondReact::~FixBondReact()
|
|||
memory->destroy(equivalences);
|
||||
memory->destroy(reverse_equiv);
|
||||
memory->destroy(custom_edges);
|
||||
memory->destroy(delete_atoms);
|
||||
|
||||
memory->destroy(nevery);
|
||||
memory->destroy(cutsq);
|
||||
|
@ -2053,6 +2056,13 @@ void FixBondReact::update_everything()
|
|||
tagint **bond_atom = atom->bond_atom;
|
||||
int *num_bond = atom->num_bond;
|
||||
|
||||
// used when deleting atoms
|
||||
int ndel,ndelone;
|
||||
int *mark = new int[nlocal];
|
||||
for (int i = 0; i < nlocal; i++) mark[i] = 0;
|
||||
tagint *tag = atom->tag;
|
||||
AtomVec *avec = atom->avec;
|
||||
|
||||
// update atom->nbonds, etc.
|
||||
// TODO: correctly tally with 'newton off'
|
||||
int delta_bonds = 0;
|
||||
|
@ -2086,6 +2096,18 @@ void FixBondReact::update_everything()
|
|||
}
|
||||
}
|
||||
|
||||
// mark to-delete atoms
|
||||
for (int i = 0; i < update_num_mega; i++) {
|
||||
rxnID = update_mega_glove[0][i];
|
||||
onemol = atom->molecules[unreacted_mol[rxnID]];
|
||||
for (int j = 0; j < onemol->natoms; j++) {
|
||||
int iatom = atom->map(update_mega_glove[j+1][i]);
|
||||
if (delete_atoms[j][rxnID] == 1 && iatom >= 0 && iatom < nlocal) {
|
||||
mark[iatom] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update charges and types of landlocked atoms
|
||||
for (int i = 0; i < update_num_mega; i++) {
|
||||
rxnID = update_mega_glove[0][i];
|
||||
|
@ -2486,6 +2508,59 @@ void FixBondReact::update_everything()
|
|||
|
||||
memory->destroy(update_mega_glove);
|
||||
|
||||
// delete atoms. taken from fix_evaporate. but don't think it needs to be in pre_exchange
|
||||
// loop in reverse order to avoid copying marked atoms
|
||||
ndel = ndelone = 0;
|
||||
for (int i = atom->nlocal-1; i >= 0; i--) {
|
||||
if (mark[i] == 1) {
|
||||
avec->copy(atom->nlocal-1,i,1);
|
||||
atom->nlocal--;
|
||||
ndelone++;
|
||||
|
||||
if (atom->avec->bonds_allow) {
|
||||
if (force->newton_bond) delta_bonds += atom->num_bond[i];
|
||||
else {
|
||||
for (int j = 0; j < atom->num_bond[i]; j++) {
|
||||
if (tag[i] < atom->bond_atom[i][j]) delta_bonds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atom->avec->angles_allow) {
|
||||
if (force->newton_bond) delta_angle += atom->num_angle[i];
|
||||
else {
|
||||
for (int j = 0; j < atom->num_angle[i]; j++) {
|
||||
int m = atom->map(atom->angle_atom2[i][j]);
|
||||
if (m >= 0 && m < nlocal) delta_angle++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atom->avec->dihedrals_allow) {
|
||||
if (force->newton_bond) delta_dihed += atom->num_dihedral[i];
|
||||
else {
|
||||
for (int j = 0; j < atom->num_dihedral[i]; j++) {
|
||||
int m = atom->map(atom->dihedral_atom2[i][j]);
|
||||
if (m >= 0 && m < nlocal) delta_dihed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atom->avec->impropers_allow) {
|
||||
if (force->newton_bond) delta_imprp += atom->num_improper[i];
|
||||
else {
|
||||
for (int j = 0; j < atom->num_improper[i]; j++) {
|
||||
int m = atom->map(atom->improper_atom2[i][j]);
|
||||
if (m >= 0 && m < nlocal) delta_imprp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] mark;
|
||||
|
||||
MPI_Allreduce(&ndelone,&ndel,1,MPI_INT,MPI_SUM,world);
|
||||
|
||||
atom->natoms -= ndel;
|
||||
// done deleting atoms
|
||||
|
||||
// something to think about: this could done much more concisely if
|
||||
// all atom-level info (bond,angles, etc...) were kinda inherited from a common data struct --JG
|
||||
|
||||
|
@ -2536,6 +2611,7 @@ void FixBondReact::read(int myrxn)
|
|||
if (strstr(line,"edgeIDs")) sscanf(line,"%d",&nedge);
|
||||
else if (strstr(line,"equivalences")) sscanf(line,"%d",&nequivalent);
|
||||
else if (strstr(line,"customIDs")) sscanf(line,"%d",&ncustom);
|
||||
else if (strstr(line,"deleteIDs")) sscanf(line,"%d",&ndelete);
|
||||
else break;
|
||||
}
|
||||
|
||||
|
@ -2565,6 +2641,8 @@ void FixBondReact::read(int myrxn)
|
|||
} else if (strcmp(keyword,"Custom Edges") == 0) {
|
||||
customedgesflag = 1;
|
||||
CustomEdges(line, myrxn);
|
||||
} else if (strcmp(keyword,"DeleteIDs") == 0) {
|
||||
DeleteAtoms(line, myrxn);
|
||||
} else error->one(FLERR,"Unknown section in superimpose file");
|
||||
|
||||
parse_keyword(1,line,keyword);
|
||||
|
@ -2630,6 +2708,16 @@ void FixBondReact::CustomEdges(char *line, int myrxn)
|
|||
delete [] edgemode;
|
||||
}
|
||||
|
||||
void FixBondReact::DeleteAtoms(char *line, int myrxn)
|
||||
{
|
||||
int tmp;
|
||||
for (int i = 0; i < ndelete; i++) {
|
||||
readline(line);
|
||||
sscanf(line,"%d",&tmp);
|
||||
delete_atoms[tmp-1][myrxn] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void FixBondReact::open(char *file)
|
||||
{
|
||||
fp = fopen(file,"r");
|
||||
|
|
|
@ -101,7 +101,7 @@ class FixBondReact : public Fix {
|
|||
|
||||
int *ibonding,*jbonding;
|
||||
int *closeneigh; // indicates if bonding atoms of a rxn are 1-2, 1-3, or 1-4 neighbors
|
||||
int nedge,nequivalent,ncustom; // number of edge, equivalent, custom atoms in mapping file
|
||||
int nedge,nequivalent,ncustom,ndelete; // number of edge, equivalent, custom atoms in mapping file
|
||||
int attempted_rxn; // there was an attempt!
|
||||
int *local_rxn_count;
|
||||
int *ghostly_rxn_count;
|
||||
|
@ -116,6 +116,7 @@ class FixBondReact : public Fix {
|
|||
int ***reverse_equiv; // re-ordered equivalences
|
||||
int **landlocked_atoms; // all atoms at least three bonds away from edge atoms
|
||||
int **custom_edges; // atoms in molecule templates with incorrect valences
|
||||
int **delete_atoms; // atoms in pre-reacted templates to delete
|
||||
|
||||
int **nxspecial,**onemol_nxspecial,**twomol_nxspecial; // full number of 1-4 neighbors
|
||||
tagint **xspecial,**onemol_xspecial,**twomol_xspecial; // full 1-4 neighbor list
|
||||
|
@ -138,6 +139,7 @@ class FixBondReact : public Fix {
|
|||
void EdgeIDs(char *,int);
|
||||
void Equivalences(char *,int);
|
||||
void CustomEdges(char *,int);
|
||||
void DeleteAtoms(char *,int);
|
||||
|
||||
void make_a_guess ();
|
||||
void neighbor_loop();
|
||||
|
|
Loading…
Reference in New Issue