Simpatico  v1.10
RingTetraRebridgeMove.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 "RingTetraRebridgeMove.h"
9 #include <mcMd/mcSimulation/McSystem.h>
10 #include <mcMd/simulation/Simulation.h>
11 #ifndef SIMP_NOPAIR
12 #include <mcMd/potentials/pair/McPairPotential.h>
13 #endif
14 #include <mcMd/chemistry/Molecule.h>
15 #include <mcMd/chemistry/Bond.h>
16 #include <mcMd/chemistry/Atom.h>
17 #include <simp/species/Ring.h>
18 #include <simp/boundary/Boundary.h>
19 #include <util/global.h>
20 
21 namespace McMd
22 {
23 
24  using namespace Util;
25  using namespace Simp;
26 
27  /*
28  * Constructor
29  */
31  GroupRebridgeBase(system),
32  speciesId_(-1),
33  nAtom_(0),
34  upperBridge_(0),
35  lowerBridge_(0)
36  { setClassName("RingTetraRebridgeMove"); }
37 
38  /*
39  * Read parameters speciesId, and bridgeLength_
40  */
41  void RingTetraRebridgeMove::readParameters(std::istream& in)
42  {
43  // Read parameters
44  readProbability(in);
45  read<int>(in, "speciesId", speciesId_);
46  read<double>(in, "upperBridge", upperBridge_);
47  read<double>(in, "lowerBridge", lowerBridge_);
48 
49  // Use dynamic_cast to check that the Species is actually a Linear species
50  Ring* ringPtr;
51  ringPtr = dynamic_cast<Ring*>(&(simulation().species(speciesId_)));
52  if (!ringPtr) {
53  UTIL_THROW("Not a Ring species");
54  }
55 
56  // Allocate array for atom position vectors.
58  if (nAtom_ < 4) UTIL_THROW("nAtom < 4 for tetra rebridge move.");
59  R_.allocate(nAtom_);
60 
61  }
62 
63  /*
64  * Load state from an archive.
65  */
67  {
69  loadParameter<int>(ar, "speciesId", speciesId_);
70  loadParameter<double>(ar, "upperBridge", upperBridge_);
71  loadParameter<double>(ar, "lowerBridge", lowerBridge_);
72  ar & nAtom_;
73 
74  // Validate
75  if (nAtom_ != system().simulation().species(speciesId_).nAtom()) {
76  UTIL_THROW("Inconsistent values of nAtom");
77  }
78  Ring* ringPtr;
79  ringPtr = dynamic_cast<Ring*>(&(simulation().species(speciesId_)));
80  if (!ringPtr) {
81  UTIL_THROW("Species is not a Ring species");
82  }
83  if (nAtom_ < 4) {
84  UTIL_THROW("nAtom < 4 for tetra rebridge move.");
85  }
86 
87  // Allocate array for atom position vectors.
88  R_.allocate(nAtom_);
89  }
90 
91  /*
92  * Save state to an archive.
93  */
95  {
96  McMove::save(ar);
97  ar & speciesId_;
98  ar & upperBridge_;
99  ar & lowerBridge_;
100  ar & nAtom_;
101  }
102 
103 
104  /*
105  * Generate, attempt and accept or reject a Monte Carlo move.
106  *
107  * A complete move involve the following stepts:
108  *
109  * 1) choose a molecule-i randomly;
110  * 2) find molecule-j of the same type as i, and monomer pairs satisfying
111  * the distance criterion exist;
112  *
113  */
115  {
116  Molecule *molPtr; // pointer to the rebridging molecule
117  Atom *aPtr, *bPtr, *cPtr, *dPtr; // atom pointers
118  Atom *lPtr, *hPtr, *lTmp, *hTmp;
119  Vector swapV;
120  int ia, ic, ib, id;
121  int ibc, ida, iLow, iHigh, nSwap;
122  int bondType;
123  double energy;
124  bool found, accept;
125 
127 
128  // Randomly pick up a molecule.
129  molPtr = &(system().randomMolecule(speciesId_));
130 
131  // Randomly choose the a atom in the tetra-group.
132  ia = random().uniformInt(0, nAtom_);
133 
134  // Search the rebriding sites.
135  found = scanBridge(molPtr, ia, ic);
136  if (!found) return false;
137 
138  ib = modId(ia+1, nAtom_);
139  id = modId(ic+1, nAtom_);
140 
141  // Calcuate the energy change.
142  aPtr = &(molPtr->atom(ia));
143  bPtr = &(molPtr->atom(ib));
144  cPtr = &(molPtr->atom(ic));
145  dPtr = &(molPtr->atom(id));
146 
147  bondType = molPtr->bond(ia).typeId();
148  tetraEnergy(aPtr, bPtr, cPtr, dPtr, bondType, energy);
149 
150  // Decide whether to accept or reject.
151  accept = random().metropolis(boltzmann(energy));
152 
153  if (accept) {
154 
155  // Find the shorter half loop.
156  ibc = ic - ib;
157  if (ibc < 0) ibc += nAtom_;
158 
159  ida = ia - id;
160  if (ida < 0) ida += nAtom_;
161 
162  if (ibc <= ida) {
163  lPtr = bPtr;
164  hPtr = cPtr;
165  iLow = ib;
166  iHigh = ic;
167  if (ibc%2 == 0)
168  nSwap = ibc / 2;
169  else
170  nSwap = (ibc + 1) / 2;
171  } else {
172  lPtr = dPtr;
173  hPtr = aPtr;
174  iLow = id;
175  iHigh = ia;
176  if (ida%2 == 0)
177  nSwap = ida / 2;
178  else
179  nSwap = (ida + 1) / 2;
180  }
181 
182  // Swap positions.
183  for (int j = 0; j < nSwap; ++j) {
184  // moving pointer close to the atom with higher index
185  hTmp = hPtr + modId(iHigh - j, nAtom_) - iHigh;
186 
187  // moving pointer close to the atom with lower index
188  lTmp = lPtr + modId(iLow + j, nAtom_) - iLow;
189 
190  swapV = lTmp->position();
191 
192  //system().moveAtom(*lTmp, hTmp->position());
193  lTmp->position() = hTmp->position();
194  #ifndef SIMP_NOPAIR
196  #endif
197 
198  //system().moveAtom(*hTmp, swapV);
199  hTmp->position() = swapV;
200  #ifndef SIMP_NOPAIR
202  #endif
203 
204  }
205 
206  // Increment counter for accepted moves of this class.
208 
209  }
210 
211  return accept;
212  }
213 
214  /*
215  * Scan the valid rebridging sits.
216  */
218  scanBridge(Molecule* molPtr, int ia, int &ic)
219  {
220  Vector r1, r2, dR;
221  int ib, id, i;
222  int *idList, nGroup;
223  double lenSq, minSq, maxSq;
224  bool found;
225 
226  // Preparation.
227  found = false;
228  maxSq = upperBridge_ * upperBridge_;
229  minSq = lowerBridge_ * lowerBridge_;
230 
231  // b Atom id.
232  ib = modId(ia+1, nAtom_);
233  r1 = molPtr->atom(ia).position();
234  r2 = molPtr->atom(ib).position();
235 
236  // Check the ab bond.
237  lenSq = boundary().distanceSq(r1, r2);
238  if (lenSq >= maxSq || lenSq <= minSq) {
239  ic = -1; // invalid value
240  return found;
241  }
242 
243  // Retrace the non-periodic molecule shape.
244  R_[0] = molPtr->atom(0).position();
245  for (i = 1; i < nAtom_; ++i) {
246  r1 = molPtr->atom(i-1).position();
247  r2 = molPtr->atom(i).position();
248  system().boundary().distanceSq(r2, r1, dR);
249  R_[i].add(R_[i-1], dR);
250  }
251 
252  // Loop over all monomers to find the proper rebridging sites.
253  nGroup = 0;
254  idList = new int[nAtom_ - 3];
255  for (i = 1; i < nAtom_ - 2; ++i) {
256  ic = modId(ib+i,nAtom_);
257  id = modId(ic+1,nAtom_);
258 
259  // Distance test.
260  dR.subtract(R_[ia],R_[ic]);
261  lenSq = dR.square();
262  if (lenSq > minSq && lenSq < maxSq) {
263 
264  dR.subtract(R_[id],R_[ic]);
265  lenSq = dR.square();
266  if (lenSq > minSq && lenSq < maxSq) {
267 
268  dR.subtract(R_[id],R_[ib]);
269  lenSq = dR.square();
270  if (lenSq > minSq && lenSq < maxSq) {
271 
272  idList[nGroup] = ic;
273  ++nGroup;
274 
275  }
276  }
277  }
278 
279  } // Loop over all possible c atoms.
280 
281  if (nGroup > 0) {
282  found = true;
283  ic = idList[random().uniformInt(0,nGroup)];
284  } else {
285  found = false;
286  ic = -1; // Invalid value.
287  }
288 
289  delete [] idList;
290  return found;
291 
292  }
293 
294 }
Bond & bond(int localId)
Get a specific Bond in this Molecule by non-const reference.
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
void incrementNAttempt()
Increment the number of attempted moves.
Definition: McMove.h:191
int nAtom() const
Get number of atoms per molecule for this Species.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
int modId(int id, int n)
Shift Atom index along a Ring.
bool scanBridge(Molecule *molPtr, int aId, int &cId)
Scan potential rebridging sites.
double upperBridge_
Upper bounds for trial length of a bridge.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: McMove.cpp:58
void tetraEnergy(Atom *aPtr, Atom *bPtr, Atom *cPtr, Atom *dPtr, int bondType, double &energy)
Calculate the energy cost for rebriding a tetra group.
int typeId() const
Get the typeId for this covalent group.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Definition: McMove.cpp:48
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
virtual void save(Serializable::OArchive &ar)
Save state to an archive.
A Species of ring polymers (abstract).
Definition: Ring.h:33
Saving / output archive for binary ostream.
double boltzmann(double energy)
Boltzmann weight associated with an energy difference.
Definition: SystemMove.h:100
virtual void readParameters(std::istream &in)
Read species to which displacement is applied.
virtual bool move()
Generate and accept or reject configuration bias move.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
McSystem & system()
Get parent McSystem.
Definition: SystemMove.h:82
Molecule & randomMolecule(int speciesId)
Get a random Molecule of a specified species in this System.
Definition: System.cpp:1200
void incrementNAccept()
Increment the number of accepted moves.
Definition: McMove.h:197
Simulation & simulation() const
Get the parent Simulation by reference.
Definition: System.h:1055
A point particle within a Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
int speciesId_
Integer index for molecular species.
long uniformInt(long range1, long range2)
Return random long int x uniformly distributed in range1 <= x < range2.
Definition: Random.h:224
Random & random()
Get Random number generator of parent Simulation.
Definition: McMove.h:209
McPairPotential & pairPotential() const
Return the McPairPotential by reference.
Definition: McSystem.h:388
double lowerBridge_
Lower bounds for trial length of a bridge.
Boundary & boundary() const
Get the Boundary by reference.
Definition: System.h:1064
DArray< Vector > R_
Arrays of atom positions of the correct molecule shape.
Saving archive for binary istream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
Vector & subtract(const Vector &v1, const Vector &v2)
Subtract vector v2 from v1.
Definition: Vector.h:672
void readProbability(std::istream &in)
Read the probability from file.
Definition: McMove.cpp:42
void setClassName(const char *className)
Set class name string.
RingTetraRebridgeMove(McSystem &system)
Constructor.
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
bool metropolis(double ratio)
Metropolis algorithm for whether to accept a MC move.
Definition: Random.h:260
int nAtom_
Number of atoms per molecule.
Simulation & simulation()
Get parent Simulation object.
Definition: McMove.h:203
A physical molecule (a set of covalently bonded Atoms).
const Vector & position() const
Get the position Vector by const reference.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
Species & species(int i)
Get a specific Species by reference.
double square() const
Return square magnitude of this vector.
Definition: Vector.h:616
void updateAtomCell(Atom &atom)
Update the cell list to reflect a new position.
Boundary & boundary()
Get Boundary object of parent McSystem.
Definition: SystemMove.h:88
Base class for rebridging a group of atoms forming a tetrahedron.