Simpatico  v1.10
RingOctaRebridgeMove.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 "RingOctaRebridgeMove.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  upperBridge_(0),
34  lowerBridge_(0)
35  { setClassName("RingOctaRebridgeMove"); }
36 
37  /*
38  * Read parameters speciesId, and nTrial
39  */
40  void RingOctaRebridgeMove::readParameters(std::istream& in)
41  {
42  // Read parameters
43  readProbability(in);
44  read<int>(in, "speciesId", speciesId_);
45  read<double>(in, "upperBridge", upperBridge_);
46  read<double>(in, "lowerBridge", lowerBridge_);
47 
48  // Use dynamic_cast to check that the Species is actually a Linear species
49  Ring* ringPtr;
50  ringPtr = dynamic_cast<Ring*>(&(simulation().species(speciesId_)));
51  if (!ringPtr) {
52  UTIL_THROW("Not a Ring species");
53  }
54  }
55 
56  /*
57  * Load state from an archive.
58  */
60  {
62  loadParameter<int>(ar, "speciesId", speciesId_);
63  loadParameter<double>(ar, "upperBridge", upperBridge_);
64  loadParameter<double>(ar, "lowerBridge", lowerBridge_);
65 
66  // Validate
67  Ring* ringPtr;
68  ringPtr = dynamic_cast<Ring*>(&(simulation().species(speciesId_)));
69  if (!ringPtr) {
70  UTIL_THROW("Species is not a Ring species");
71  }
72  }
73 
74  /*
75  * Save state to an archive.
76  */
78  {
79  McMove::save(ar);
80  ar & speciesId_;
81  ar & upperBridge_;
82  ar & lowerBridge_;
83  }
84 
85  /*
86  * Generate, attempt and accept or reject a Monte Carlo move.
87  *
88  * A complete move involve the following stepts:
89  *
90  * 1) choose a molecule-i randomly;
91  * 2) find molecule-j of the same type as i, and monomer pairs satisfying
92  * the distance criterion exist;
93  *
94  */
96  {
97  Molecule *molPtr1; // pointer to the rebridging molecule
98  Molecule *molPtr2; // pointer to the rebridging molecule
99  Atom *mPtr, *nPtr; // atom pointers
100  Vector swapV;
101  int nAtom, im, in, molId2;
102  double energy;
103  bool found, accept;
104 
106 
107  // Randomly pick up a molecule.
108  molPtr1 = &(system().randomMolecule(speciesId_));
109  nAtom = molPtr1->nAtom();
110 
111  // Randomly choose the a atom in the tetra-group.
112  im = random().uniformInt(0, nAtom);
113 
114  // Search the rebriding sites.
115  found = scanBridge(molPtr1, im, molId2, in);
116  if (!found) return false;
117 
118  // Calcuate the energy change.
119  mPtr = &(molPtr1->atom(im));
120  molPtr2 = &(system().molecule(speciesId_, molId2));
121  nPtr = &(molPtr2->atom(in));
122 
123  energy = 0.0;
124  energy -= system().atomPotentialEnergy(*mPtr);
125  energy -= system().atomPotentialEnergy(*nPtr);
126 
127  // Swap positions of atoms m and n.
128  swapV = mPtr->position();
129 
130  //system().moveAtom(*mPtr, nPtr->position());
131  mPtr->position() = nPtr->position();
132  #ifndef SIMP_NOPAIR
134  #endif
135 
136  //system().moveAtom(*nPtr, swapV);
137  nPtr->position() = swapV;
138  #ifndef SIMP_NOPAIR
140  #endif
141 
142  energy += system().atomPotentialEnergy(*mPtr);
143  energy += system().atomPotentialEnergy(*nPtr);
144 
145  // Decide whether to accept or reject.
146  accept = random().metropolis(boltzmann(energy));
147 
148  if (accept) {
149  // Increment counter for accepted moves of this class.
151  } else {
152  // Swap back bead positions.
153  swapV = mPtr->position();
154 
155  //system().moveAtom(*mPtr, nPtr->position());
156  mPtr->position() = nPtr->position();
157  #ifndef SIMP_NOPAIR
159  #endif
160 
161  //system().moveAtom(*nPtr, swapV);
162  nPtr->position() = swapV;
163  #ifndef SIMP_NOPAIR
165  #endif
166  }
167 
168  return accept;
169  }
170 
171  /*
172  * Return true if the octahedron formed by the 6 closely approaching atoms
173  * satisfy the 8 distance criterion.
174  */
176  scanBridge(Molecule* molPtr1, int im, int& molId2, int &in)
177  {
178  Molecule *molPtr2;
179  Atom *pn;
180  Vector aPos, bPos, cPos, dPos, mPos, nPos;
181  int nAtom, ia, ib, ic, id, dmn, dnm;
182  int nNeighbor, j, *idList, *molIdList;
183  int molId1, choice, nGroup;
184  double lenSq, minSq, maxSq;
185  bool validIndex, found;
186 
187  // Number of atoms per molecule.
188  nAtom = molPtr1->nAtom();
189 
190  // The a and b Atom id.
191  ia = modId(im-1, nAtom);
192  ib = modId(im+1, nAtom);
193 
194  aPos = molPtr1->atom(ia).position();
195  bPos = molPtr1->atom(ib).position();
196  mPos = molPtr1->atom(im).position();
197 
198  // Prepare for the scan.
199  found = false;
200  maxSq = upperBridge_ * upperBridge_;
201  minSq = lowerBridge_ * lowerBridge_;
202 
203  // Check the am bond.
204  lenSq = boundary().distanceSq(aPos, mPos);
205  if (lenSq >= maxSq || lenSq <= minSq) {
206  in = -1; // invalid value
207  molId2 = -1; // invalid value
208  return found;
209  }
210 
211  // Check the mb bond.
212  lenSq = boundary().distanceSq(mPos, bPos);
213  if (lenSq >= maxSq || lenSq <= minSq) {
214  in = -1; // invalid value
215  molId2 = -1; // invalid value
216  return found;
217  }
218 
219  // Get the neighbor list.
220  #ifndef SIMP_NOPAIR
222  nNeighbor = neighbors_.size();
223  idList = new int[nNeighbor];
224  molIdList = new int[nNeighbor];
225 
226  // Loop over neighboring monomers and identify the octa-group.
227  nGroup = 0;
228  molId1 = molPtr1->id();
229  for (j = 0; j < nNeighbor; ++j) {
230  pn = neighbors_[j];
231  in = pn->indexInMolecule();
232  molId2 = pn->molecule().id();
233 
234  validIndex = true;
235 
236  if (molId2 == molId1) {
237  // Check if im and in are separated by at least two atoms.
238  dmn = in - im;
239  if (dmn < 0) dmn += nAtom;
240 
241  dnm = im - in;
242  if (dnm < 0) dnm += nAtom;
243 
244  if (dmn <= 2 && dnm <= 2) validIndex = false;
245  }
246 
247  if (pn->molecule().species().id() != speciesId_)
248  validIndex = false;
249 
250  if (validIndex) {
251 
252  molPtr2 = &(system().molecule(speciesId_, molId2));
253 
254  ic = modId(in-1, nAtom);
255  id = modId(in+1, nAtom);
256 
257  cPos = molPtr2->atom(ic).position();
258  dPos = molPtr2->atom(id).position();
259  nPos = molPtr2->atom(in).position();
260 
261  // Distance test.
262  lenSq = boundary().distanceSq(cPos, mPos);
263  if (lenSq > minSq && lenSq < maxSq) {
264 
265  lenSq = boundary().distanceSq(mPos, dPos);
266  if (lenSq > minSq && lenSq < maxSq) {
267 
268  lenSq = boundary().distanceSq(aPos, nPos);
269  if (lenSq > minSq && lenSq < maxSq) {
270 
271  lenSq = boundary().distanceSq(nPos, bPos);
272  if (lenSq > minSq && lenSq < maxSq) {
273 
274  lenSq = boundary().distanceSq(cPos, nPos);
275  if (lenSq > minSq && lenSq < maxSq) {
276 
277  lenSq = boundary().distanceSq(nPos, dPos);
278  if (lenSq > minSq && lenSq < maxSq) {
279 
280  idList[nGroup] = in;
281  molIdList[nGroup] = molId2;
282  ++nGroup;
283 
284  } } } } } } // 6 additional distance test
285 
286  } // if the atom id "in" is valid
287 
288  } // loop over neighbors
289  #endif
290 
291  if (nGroup > 0) {
292  found = true;
293  choice = random().uniformInt(0,nGroup);
294  in = idList[choice];
295  molId2 = molIdList[choice];
296  } else {
297  found = false;
298  in = -1; // Invalid value.
299  molId2 = -1; // Invalid value.
300  }
301 
302  delete [] molIdList;
303  delete [] idList;
304  return found;
305 
306  }
307 
308 }
int speciesId_
Integer index for molecular species.
Molecule & molecule() const
Get the parent Molecule by 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
void getNeighbors(const Vector &pos, NeighborArray &neighbors) const
Fill a NeighborArray with pointers to atoms near a specified position.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
const CellList & cellList() const
Get the cellList by const reference.
double lowerBridge_
Lower bounds for trial length of a bridge.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: McMove.cpp:58
double atomPotentialEnergy(const Atom &atom) const
Calculate the total potential energy for one Atom.
Definition: McSystem.cpp:459
Species & species() const
Get the molecular Species by reference.
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.
int id() const
Get the index for this Molecule (unique in species).
double upperBridge_
Upper bounds for trial length of a bridge.
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.
Molecule & molecule(int speciesId, int moleculeId)
Get a specific Molecule in this System, by integer index.
Definition: System.h:1137
double boltzmann(double energy)
Boltzmann weight associated with an energy difference.
Definition: SystemMove.h:100
bool scanBridge(Molecule *molPtr, int mId, int &molId2, int &nId)
Scan potential rebridging sites.
#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
A point particle within a Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
int modId(int id, int n)
Shift Atom index along a Ring.
long uniformInt(long range1, long range2)
Return random long int x uniformly distributed in range1 <= x < range2.
Definition: Random.h:224
CellList::NeighborArray neighbors_
Neighbor list around test atom.
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
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
int id() const
Get integer id of this Species.
Saving archive for binary istream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
void readProbability(std::istream &in)
Read the probability from file.
Definition: McMove.cpp:42
void setClassName(const char *className)
Set class name string.
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
int indexInMolecule() const
Get local index for this Atom within the parent molecule;.
bool metropolis(double ratio)
Metropolis algorithm for whether to accept a MC move.
Definition: Random.h:260
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 bool move()
Generate and accept or reject configuration bias move.
Species & species(int i)
Get a specific Species by reference.
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
void updateAtomCell(Atom &atom)
Update the cell list to reflect a new position.
int nAtom() const
Get the number of Atoms in this Molecule.
Boundary & boundary()
Get Boundary object of parent McSystem.
Definition: SystemMove.h:88
RingOctaRebridgeMove(McSystem &system)
Constructor.
virtual void readParameters(std::istream &in)
Read species to which displacement is applied.
Base class for rebridging a group of atoms forming a tetrahedron.