Simpatico  v1.10
GroupRebridgeBase.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include <util/global.h>
9 
10 #include "GroupRebridgeBase.h"
12 //#include <mcMd/potentials/pair/McPairPotential.h>
13 //#include <mcMd/potentials/bond/McBondPotential.h>
14 #include <mcMd/chemistry/getAtomGroups.h>
15 
16 namespace McMd
17 {
18 
19  using namespace Util;
20 
21  /*
22  * Constructor.
23  */
25  SystemMove(system)
26  {
27  // Precondition
28  #ifdef SIMP_DIHEDRAL
29  if (system.hasDihedralPotential()) {
30  UTIL_THROW("GroupEndBase is unusable with dihedrals");
31  }
32  #endif
33  }
34 
35  /*
36  * Destructor.
37  */
39  {}
40 
41  /*
42  * Calculate the energy change of rebridging a tetrahedron formed from
43  * 4 atoms.
44  *
45  * a - b a b
46  * -> X
47  * d - c d c
48  *
49  * Erase ab & cd bonds, and add ac & bd bonds. Energy change includes the
50  * bonding potential changes and the pairing potential changes.
51  */
53  tetraEnergy(Atom* aPtr, Atom* bPtr, Atom* cPtr, Atom* dPtr,
54  int bondType, double &energy)
55  {
56  Vector aPos = aPtr->position();
57  Vector bPos = bPtr->position();
58  Vector cPos = cPtr->position();
59  Vector dPos = dPtr->position();
60  double lab, lcd, lac, lbd;
61 
62  energy = 0.0;
63 
64  // Calculate bond lengthSq.
65  lab = boundary().distanceSq(aPos, bPos);
66  lcd = boundary().distanceSq(cPos, dPos);
67  lac = boundary().distanceSq(aPos, cPos);
68  lbd = boundary().distanceSq(bPos, dPos);
69 
70  // Subtract old bonding energies.
71  energy -= system().bondPotential().energy(lab, bondType);
72  energy -= system().bondPotential().energy(lcd, bondType);
73 
74  // Add new bonding energies.
75  energy += system().bondPotential().energy(lac, bondType);
76  energy += system().bondPotential().energy(lbd, bondType);
77 
78  #ifndef SIMP_NOPAIR
79  int aId = aPtr->typeId();
80  int bId = bPtr->typeId();
81  int cId = cPtr->typeId();
82  int dId = dPtr->typeId();
83 
84  // Subtract old pairing potentials.
85  energy -= system().pairPotential().energy(lac, aId, cId);
86  energy -= system().pairPotential().energy(lbd, bId, dId);
87 
88  // Add new pairing potentials.
89  energy += system().pairPotential().energy(lab, aId, bId);
90  energy += system().pairPotential().energy(lcd, cId, dId);
91  #endif
92 
93  #ifdef SIMP_ANGLE
94  if (system().hasAnglePotential()) {
95 
96  // Implementation assumed linear or ring molecular topology
97  const Atom *amPtr(NULL), *bpPtr(NULL), *cmPtr(NULL), *dpPtr(NULL);
98  AtomBondArray bonds;
99  AtomAngleArray angles;
100  const Bond *bondPtr;
101  int iBond, angleType;
102 
103  // find the neighboring atom pointers and angle type
104 
105  // angle type
106  getAtomAngles(*aPtr, angles);
107  angleType = angles[0]->typeId();
108 
109  // amPtr
110  getAtomBonds(*aPtr, bonds);
111  for (iBond = 0; iBond < bonds.size(); ++iBond) {
112  bondPtr = bonds[iBond];
113  if (&bondPtr->atom(0) != aPtr && &bondPtr->atom(0) != bPtr) {
114  amPtr = &bondPtr->atom(0);
115  } else if (&bondPtr->atom(1) != aPtr && &bondPtr->atom(1) != bPtr){
116  amPtr = &bondPtr->atom(1);
117  }
118  }
119 
120  // bpPtr
121  getAtomBonds(*bPtr, bonds);
122  for (iBond = 0; iBond < bonds.size(); ++iBond) {
123  bondPtr = bonds[iBond];
124  if (&bondPtr->atom(0) != bPtr && &bondPtr->atom(0) != aPtr) {
125  bpPtr = &bondPtr->atom(0);
126  } else if (&bondPtr->atom(1) != bPtr && &bondPtr->atom(1) != aPtr){
127  bpPtr = &bondPtr->atom(1);
128  }
129  }
130 
131  // cmPtr
132  getAtomBonds(*cPtr, bonds);
133  for (iBond = 0; iBond < bonds.size(); ++iBond) {
134  bondPtr = bonds[iBond];
135  if (&bondPtr->atom(0) != cPtr && &bondPtr->atom(0) != dPtr) {
136  cmPtr = &bondPtr->atom(0);
137  } else if (&bondPtr->atom(1) != cPtr && &bondPtr->atom(1) != dPtr){
138  cmPtr = &bondPtr->atom(1);
139  }
140  }
141 
142  // dpPtr
143  getAtomBonds(*dPtr, bonds);
144  for (iBond = 0; iBond < bonds.size(); ++iBond) {
145  bondPtr = bonds[iBond];
146  if (&bondPtr->atom(0) != dPtr && &bondPtr->atom(0) != cPtr) {
147  dpPtr = &bondPtr->atom(0);
148  } else if (&bondPtr->atom(1) != cPtr && &bondPtr->atom(1) != dPtr){
149  dpPtr = &bondPtr->atom(1);
150  }
151  }
152 
153  // subtract energies of angles involving bond a-b
154  energy -= angleEnergy(*amPtr, *aPtr, *bPtr, angleType);
155  energy -= angleEnergy(*aPtr, *bPtr, *bpPtr, angleType);
156 
157  // subtract energies of angles involving bond c-d
158  energy -= angleEnergy(*cmPtr, *cPtr, *dPtr, angleType);
159  energy -= angleEnergy(*cPtr, *dPtr, *dpPtr, angleType);
160 
161  // add energies of angles involving bond a-c
162  energy += angleEnergy(*amPtr, *aPtr, *cPtr, angleType);
163  energy += angleEnergy(*aPtr, *cPtr, *cmPtr, angleType);
164 
165  // add energies of angles involving bond b-d
166  energy += angleEnergy(*bpPtr, *bPtr, *dPtr, angleType);
167  energy += angleEnergy(*bPtr, *dPtr, *dpPtr, angleType);
168 
169  }
170  #endif
171  }
172 
173  /*
174  * Calculate the energy change of rebridging an octahedron formed
175  * from 6 atoms.
176  *
177  * a - m - b a m b
178  * -> X X
179  * c - n - d c n d
180  *
181  * Erase 4 bonds: am, mb, cn, nd
182  * Add 4 bonds: an, nb, cm, md
183  * The erased bonds contribute to the pairing interactions, but
184  * the pair of atoms involved in the newly added bonds lost their pairing
185  * interaction.
186  */
188  octaEnergy(Atom* aPtr, Atom* bPtr, Atom* cPtr, Atom* dPtr,
189  Atom* mPtr, Atom* nPtr, int bondType, double &energy)
190  {
191  Vector aPos = aPtr->position();
192  Vector bPos = bPtr->position();
193  Vector cPos = cPtr->position();
194  Vector dPos = dPtr->position();
195  Vector mPos = mPtr->position();
196  Vector nPos = nPtr->position();
197  double lam, lmb, lcn, lnd;
198  double lan, lnb, lcm, lmd;
199 
200  energy = 0.0;
201 
202  // Calculate atom pair distances squared.
203  lam = boundary().distanceSq(aPos, mPos);
204  lmb = boundary().distanceSq(mPos, bPos);
205  lcn = boundary().distanceSq(cPos, nPos);
206  lnd = boundary().distanceSq(nPos, dPos);
207 
208  lan = boundary().distanceSq(aPos, nPos);
209  lnb = boundary().distanceSq(nPos, bPos);
210  lcm = boundary().distanceSq(cPos, mPos);
211  lmd = boundary().distanceSq(mPos, dPos);
212 
213  // Subtract old bonding energies.
214  energy -= system().bondPotential().energy(lam, bondType);
215  energy -= system().bondPotential().energy(lmb, bondType);
216  energy -= system().bondPotential().energy(lcn, bondType);
217  energy -= system().bondPotential().energy(lnd, bondType);
218 
219  // Add new bonding energies.
220  energy += system().bondPotential().energy(lan, bondType);
221  energy += system().bondPotential().energy(lnb, bondType);
222  energy += system().bondPotential().energy(lcm, bondType);
223  energy += system().bondPotential().energy(lmd, bondType);
224 
225  #ifndef SIMP_NOPAIR
226  int aId = aPtr->typeId();
227  int bId = bPtr->typeId();
228  int cId = cPtr->typeId();
229  int dId = dPtr->typeId();
230  int mId = mPtr->typeId();
231  int nId = nPtr->typeId();
232 
233  // Subtract old pairing potentials.
234  energy -= system().pairPotential().energy(lan, aId, nId);
235  energy -= system().pairPotential().energy(lnb, nId, bId);
236  energy -= system().pairPotential().energy(lcm, cId, mId);
237  energy -= system().pairPotential().energy(lmd, mId, dId);
238 
239  // Add new pairing potentials.
240  energy += system().pairPotential().energy(lam, aId, mId);
241  energy += system().pairPotential().energy(lmb, mId, bId);
242  energy += system().pairPotential().energy(lcn, cId, nId);
243  energy += system().pairPotential().energy(lnd, nId, dId);
244  #endif
245  }
246 }
A System for use in a Markov chain Monte Carlo simulation.
Definition: McSystem.h:52
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual double energy(double rsq, int iAtomType, int jAtomType) const =0
Return pair energy for a single pair.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
Include this file to include all MC potential energy classes at once.
BondPotential & bondPotential() const
Return the BondPotential by reference.
Definition: McSystem.h:405
bool hasDihedralPotential() const
Does a dihedral potential exist?.
Definition: McSystem.h:433
void tetraEnergy(Atom *aPtr, Atom *bPtr, Atom *cPtr, Atom *dPtr, int bondType, double &energy)
Calculate the energy cost for rebriding a tetra group.
File containing preprocessor macros for error handling.
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:37
void getAtomAngles(const Atom &atom, AtomAngleArray &groups)
Fill an array of pointers to Angles that contain an Atom.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
virtual ~GroupRebridgeBase()
Destructor.
McSystem & system()
Get parent McSystem.
Definition: SystemMove.h:82
int typeId() const
Get type index for this Atom.
A point particle within a Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
GroupRebridgeBase(McSystem &system)
Constructor.
An McMove that acts on one McSystem.
Definition: SystemMove.h:28
void octaEnergy(Atom *aPtr, Atom *bPtr, Atom *cPtr, Atom *dPtr, Atom *mPtr, Atom *nPtr, int bondType, double &energy)
Calculate the energy cost for rebriding an octa group.
Atom & atom(int i)
Get a specific Atom in the Group by reference.
McPairPotential & pairPotential() const
Return the McPairPotential by reference.
Definition: McSystem.h:388
virtual double energy(double rSq, int type) const =0
Returns potential energy for one bond.
double angleEnergy(const Atom &a, const Atom &b, const Atom &c, int type)
Calculate the angle energy for a bead triple.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
A sequence of NAtom covalently interacting atoms.
const Vector & position() const
Get the position Vector by const reference.
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
void getAtomBonds(const Atom &atom, AtomBondArray &groups)
Fill an array of pointers to Bonds that contain an Atom.
Boundary & boundary()
Get Boundary object of parent McSystem.
Definition: SystemMove.h:88