Simpatico  v1.10
CfbRingRebridgeMove.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 "CfbRingRebridgeMove.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  CfbRebridgeBase(system),
32  speciesId_(-1),
33  nRegrow_(-1)
34  { setClassName("CfbRingRebridgeMove"); }
35 
36  /*
37  * Read parameters speciesId, nRegrow, and nTrial
38  */
39  void CfbRingRebridgeMove::readParameters(std::istream& in)
40  {
41  // Read parameters
42  readProbability(in);
43  read<int>(in, "speciesId", speciesId_);
44  read<int>(in, "nRegrow", nRegrow_);
45 
46  // Read parameters hold by RebridgeBase
48 
49  // Initialize tables for spring constants and normalizations.
50  setup();
51 
52  // Use dynamic_cast to check that the Species is actually a Linear species
53  Ring* ringPtr;
54  ringPtr = dynamic_cast<Ring*>(&(simulation().species(speciesId_)));
55  if (!ringPtr) {
56  UTIL_THROW("Not a Ring species");
57  }
58 
59  // Allocate array to store old positions
60  oldPos_.allocate(nRegrow_);
61  }
62 
63  /*
64  * Load state from an archive.
65  */
67  {
69  loadParameter<int>(ar, "speciesId", speciesId_);
70  loadParameter<int>(ar, "nRegrow", nRegrow_);
72 
73  // Validate
74  Ring* ringPtr;
75  ringPtr = dynamic_cast<Ring*>(&(simulation().species(speciesId_)));
76  if (!ringPtr) {
77  UTIL_THROW("Species is not a Ring species");
78  }
79 
80  // Initialize tables for spring constants and normalizations.
81  setup();
82  oldPos_.allocate(nRegrow_);
83  }
84 
85  /*
86  * Save state to an archive.
87  */
89  {
90  McMove::save(ar);
91  ar & speciesId_;
92  ar & nRegrow_;
94  }
95 
96  /*
97  * Generate, attempt and accept or reject a Monte Carlo move.
98  *
99  * Convention for index
100  * nAtom
101  * _____________________________________
102  * | |
103  * 0 1 2 3 ... nAtom-1
104  * o---o---o---o---o---o---o---o---o---o
105  * bonds: 0 1 2 3 nAtom-1
106  *
107  * The algorithm is slightly different from that for linear molecules since a
108  * ring molecule does not have ends. The operation of moving the atom pointers
109  * have to account for the periodic boundary conditions, which is achived with
110  * the help of modId(int s, int n) method.
111  *
112  */
114  {
115  Molecule *molPtr; // pointer to randomly chosen molecule
116  Atom *thisPtr; // pointer to the current end atom
117  Atom *tempPtr; // pointer to the current end atom
118  int *bonds, iBond;
119  int nAtom, sign, beginId, endId, i;
120  double rosen_r, rosen_f;
121  double energy_r, energy_f;
122  bool accept;
123 
125 
126  // Choose a molecule at random
127  molPtr = &(system().randomMolecule(speciesId_));
128  nAtom = molPtr->nAtom();
129 
130  // Require that chain length - 2 >= nRegrow_
131  if (nRegrow_ > nAtom - 2) {
132  UTIL_THROW("nRegrow_ >= chain length");
133  }
134 
135  // Allocate bonds array
136  bonds = new int[nRegrow_ + 1];
137 
138  // Choose the beginId of the growing interior bridge
139  beginId = random().uniformInt(0, nAtom);
140 
141  // Choose direction and fill bonds array: sign = +1 if beginId < endId
142  if (random().uniform(0.0, 1.0) > 0.5) {
143  sign = +1;
144  endId = (beginId + (nRegrow_ - 1)) % nAtom;
145 
146  // Save bond types
147  iBond = endId;
148  for (i = 0; i < nRegrow_ + 1; ++i) {
149  bonds[i] = molPtr->bond(iBond).typeId();
150  iBond--;
151  if (iBond < 0) iBond += nAtom;
152  }
153  } else {
154  sign = -1;
155  endId = beginId;
156  beginId = (endId + (nRegrow_ - 1)) % nAtom;
157 
158  // Save bond types
159  iBond = endId - 1;
160  if (iBond < 0) iBond += nAtom;
161  for (i = 0; i < nRegrow_ + 1; ++i) {
162  bonds[i] = molPtr->bond(iBond).typeId();
163  iBond++;
164  if (iBond >= nAtom) iBond -= nAtom;
165  }
166  }
167 
168  // Store current atomic positions from segment to be regrown
169  tempPtr = &(molPtr->atom(beginId));
170  for (i = 0; i < nRegrow_; ++i) {
171  thisPtr = tempPtr + modId(beginId + i*sign, nAtom) - beginId;
172  oldPos_[i] = thisPtr->position();
173  }
174 
175  // Delete atoms: endId -> beginId
176  deleteSequence(sign, molPtr, endId, bonds, rosen_r, energy_r);
177 
178  // Regrow atoms: endId -> beginId
179  addSequence(sign, molPtr, beginId, bonds, rosen_f, energy_f);
180 
181  // Release bonds array
182  delete [] bonds;
183 
184  // Decide whether to accept or reject
185  accept = random().metropolis(rosen_f/rosen_r);
186  if (accept) {
187 
188  // Increment counter for accepted moves of this class.
190 
191  // If the move is accepted, keep current positions.
192 
193  } else {
194 
195  // If the move is rejected, restore old positions
196  tempPtr = &(molPtr->atom(beginId));
197  for (i = 0; i < nRegrow_; ++i) {
198  thisPtr = tempPtr + modId(beginId + i*sign, nAtom) - beginId;
199  //system().moveAtom(*thisPtr, oldPos_[i]);
200  thisPtr->position() = oldPos_[i];
201  #ifndef SIMP_NOPAIR
202  system().pairPotential().updateAtomCell(*thisPtr);
203  #endif
204  }
205 
206  }
207 
208  return accept;
209  }
210 
211  /*
212  * Delete a consecutive sequence of atoms in a Ring.
213  */
214  void CfbRingRebridgeMove::deleteSequence(int sign, Molecule *molPtr,
215  int endId, int *bonds, double &rosenbluth, double &energy)
216  {
217  Atom *endPtr;
218  Atom *thisPtr;
219  Atom *prevPtr;
220  Atom *nextPtr;
221  int prevBType, nextBType, nAtom;
222  double rosen_r, energy_r;
223 
224  // Initialize weight
225  rosenbluth = 1.0;
226  energy = 0.0;
227 
228  nAtom = molPtr->nAtom();
229  endPtr = &(molPtr->atom(endId));
230 
231  // Step 1: delete the last atom
232  if (nRegrow_ >= 1) {
233  thisPtr = endPtr;
234  prevPtr = endPtr + modId(endId - sign,nAtom) - endId;
235  nextPtr = endPtr + modId(endId + sign,nAtom) - endId;
236 
237  nextBType = bonds[0];
238  prevBType = bonds[1];
239 
240  // Orientation biased trimer rebridge move
241  deleteMiddleAtom(thisPtr, prevPtr, nextPtr,
242  prevBType, nextBType, rosen_r, energy_r);
243  #ifndef SIMP_NOPAIR
244  system().pairPotential().deleteAtom(*thisPtr);
245  #endif
246  rosenbluth *= rosen_r;
247  energy += energy_r;
248  }
249 
250  // step 2: delete the remaining atoms
251  for (int i = 0; i < nRegrow_ - 1; ++i) {
252  thisPtr = endPtr + modId(endId - (i+1)*sign, nAtom) - endId;
253  prevPtr = endPtr + modId(endId - (i+2)*sign, nAtom) - endId;
254 
255  prevBType = bonds[i+2];
256  deleteEndAtom(thisPtr, prevPtr, prevBType, rosen_r, energy_r);
257  #ifndef SIMP_NOPAIR
258  system().pairPotential().deleteAtom(*thisPtr);
259  #endif
260 
261  rosenbluth *= rosen_r;
262  energy += energy_r;
263  }
264  }
265 
266  /*
267  * Add a consecutive sequence of atoms in a Ring.
268  */
269  void CfbRingRebridgeMove::addSequence(int sign, Molecule *molPtr,
270  int beginId, int *bonds, double &rosenbluth, double &energy)
271  {
272  Atom *beginPtr;
273  Atom *thisPtr;
274  Atom *prevPtr;
275  Atom *nextPtr;
276  int prevBType, nextBType, nAtom;
277  double rosen_f, energy_f;
278 
279  // Initialize weight
280  rosenbluth = 1.0;
281  energy = 0.0;
282 
283  // Step 1: grow the first nRegrow_ - 1 atoms
284  nAtom = molPtr->nAtom();
285  beginPtr = &(molPtr->atom(beginId));
286 
287  for (int i = 0; i < nRegrow_ - 1; ++i) {
288  thisPtr = beginPtr + modId(beginId+i*sign,nAtom) - beginId;
289  prevPtr = beginPtr + modId(beginId+(i-1)*sign,nAtom) - beginId;
290 
291  prevBType = bonds[nRegrow_ - i];
292  addEndAtom(thisPtr, prevPtr, prevBType, rosen_f, energy_f);
293  #ifndef SIMP_NOPAIR
294  system().pairPotential().addAtom(*thisPtr);
295  #endif
296 
297  rosenbluth *= rosen_f;
298  energy += energy_f;
299  }
300 
301  // Step 2: grow the last atoms
302  if (nRegrow_ >= 1) {
303  prevPtr = beginPtr + modId(beginId+(nRegrow_-2)*sign,nAtom) - beginId;
304  thisPtr = beginPtr + modId(beginId+(nRegrow_-1)*sign,nAtom) - beginId;
305  nextPtr = beginPtr + modId(beginId+nRegrow_*sign,nAtom) - beginId;
306 
307  prevBType = bonds[1];
308  nextBType = bonds[0];
309 
310  // Invoke the orientation biased trimer re-bridging move
311  addMiddleAtom(thisPtr, prevPtr, nextPtr,
312  prevBType, nextBType, rosen_f, energy_f);
313  #ifndef SIMP_NOPAIR
314  system().pairPotential().addAtom(*thisPtr);
315  #endif
316 
317  rosenbluth *= rosen_f;
318  energy += energy_f;
319  }
320  }
321 
322 }
virtual void setup()
Initialize the arrays for preferential angle, effective spring constant and normalization factor...
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
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
virtual bool move()
Generate and accept or reject configuration bias move.
void addEndAtom(Atom *endPtr, Atom *pvtPtr, int bondType, double &rosenbluth, double &energy)
Configuration bias algorithm for adding an atom to a chain end.
Definition: CfbEndBase.cpp:189
void incrementNAttempt()
Increment the number of attempted moves.
Definition: McMove.h:191
void deleteMiddleAtom(Atom *partPtr, Atom *prevPtr, Atom *nextPtr, int prevBType, int nextBType, double &rosenbluth, double &energy)
Configuration bias algorithm for deleting a particle between two monomers and compute the correspondi...
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: McMove.cpp:58
void addAtom(Atom &atom)
Add an Atom to the CellList.
virtual void readParameters(std::istream &in)
Read species type, nTrial, and parameters needed to evaluate the orientation bias.
virtual void readParameters(std::istream &in)
Read species to which displacement is applied.
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.
Base class configuration bias moves internal segment regrowth moves.
A Species of ring polymers (abstract).
Definition: Ring.h:33
Saving / output archive for binary ostream.
void addMiddleAtom(Atom *partPtr, Atom *prevPtr, Atom *nextPtr, int prevBType, int nextBType, double &rosenbluth, double &energy)
Configuration bias algorithm for adding the last particle with special bias in favor of closing the b...
#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 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
DArray< Vector > oldPos_
Array of old positions of temporarily deleted atoms.
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 save(Serializable::OArchive &ar)
Save internal state to an archive.
void deleteEndAtom(Atom *endPtr, Atom *pvtPtr, int bondType, double &rosenbluth, double &energy)
CFB algorithm for deleting an end atom from a flexible chain.
Definition: CfbEndBase.cpp:62
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 nRegrow_
Number of particles at end to attempt to regrow.
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 void save(Serializable::OArchive &ar)
Save state to an archive.
Species & species(int i)
Get a specific Species by reference.
void deleteAtom(Atom &atom)
Remove an Atom from the CellList.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
void updateAtomCell(Atom &atom)
Update the cell list to reflect a new position.
CfbRingRebridgeMove(McSystem &system)
Constructor.
int nAtom() const
Get the number of Atoms in this Molecule.