Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bond/react delete atoms #1239

Merged
merged 5 commits into from Dec 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 23 additions & 10 deletions doc/src/fix_bond_react.txt
Expand Up @@ -69,8 +69,9 @@ Initiate complex covalent bonding (topology) changes. These topology
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.
angles, dihedrals, impropers, bond types, angle types, dihedral types,
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
Expand Down Expand Up @@ -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
jrgissing marked this conversation as resolved.
Show resolved Hide resolved
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
Expand All @@ -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:
Expand Down Expand Up @@ -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 atom that is not deleted. 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
Expand Down
1 change: 1 addition & 0 deletions doc/utils/sphinx-config/false_positives.txt
Expand Up @@ -507,6 +507,7 @@ deepskyblue
defgrad
deformable
del
deleteIDs
Dellago
delocalization
delocalized
Expand Down
100 changes: 100 additions & 0 deletions src/USER-MISC/fix_bond_react.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1650,6 +1653,18 @@ void FixBondReact::find_landlocked_atoms(int myrxn)
}
}

// additionally, if a deleted atom is bonded to an atom that is not deleted, bad
for (int i = 0; i < onemol->natoms; i++) {
if (delete_atoms[i][myrxn] == 1) {
int ii = reverse_equiv[i][1][myrxn] - 1;
for (int j = 0; j < twomol_nxspecial[ii][0]; j++) {
if (delete_atoms[equivalences[twomol_xspecial[ii][j]-1][1][myrxn]-1][myrxn] == 0) {
error->one(FLERR,"A deleted atom cannot remain bonded to an atom that is not deleted");
}
}
}
}

// also, if atoms change number of bonds, but aren't landlocked, that could be bad
if (me == 0)
for (int i = 0; i < twomol->natoms; i++) {
Expand Down Expand Up @@ -2053,6 +2068,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;
Expand Down Expand Up @@ -2086,6 +2108,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];
Expand Down Expand Up @@ -2486,6 +2520,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

Expand Down Expand Up @@ -2536,6 +2623,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;
}

Expand Down Expand Up @@ -2565,6 +2653,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);
Expand Down Expand Up @@ -2630,6 +2720,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");
Expand Down
4 changes: 3 additions & 1 deletion src/USER-MISC/fix_bond_react.h
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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();
Expand Down