Simpatico  v1.10
SliplinkMove.cpp
1 #ifndef SLIPLINKMOVE_CPP
2 #define SLIPLINKMOVE_CPP
3 
4 /*
5 * MolMcD - Monte Carlo and Molecular Dynamics Simulator for Molecular Liquids
6 *
7 * Copyright 2010 - 2014, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include "SliplinkMove.h"
12 #include <util/misc/FileMaster.h>
13 #include <mcMd/simulation/Simulation.h>
14 #include <mcMd/links/LinkMaster.h>
15 #include <mcMd/mcSimulation/McSystem.h>
16 #include <mcMd/potentials/pair/McPairPotential.h>
17 #include <mcMd/potentials/bond/BondPotential.h>
18 #include <mcMd/chemistry/Molecule.h>
19 #include <mcMd/chemistry/Atom.h>
20 #include <simp/boundary/Boundary.h>
21 #include <util/space/Vector.h>
22 #include <util/global.h>
23 #include <cmath>
24 
25 #define MCMD_LINK_TRANSFER
26 
27 namespace McMd
28 {
29 
30  using namespace Util;
31  using namespace Simp;
32 
33  // Constructor
35  SystemMove(system),
36  cutoff_(0),
37  speciesId_(0)
38  { setClassName("SliplinkMove"); }
39 
40  void SliplinkMove::readParameters(std::istream& in)
41  {
42  readProbability(in);
43  read<double>(in, "cutoff", cutoff_);
44  read<int>(in, "speciesId", speciesId_);
45  }
46 
47 
48  // Create or destroy the slip-springs.
50  {
52  Atom *atom0Ptr, *atom1Ptr;
53  Molecule *mol0Ptr, *mol1Ptr;
54  int j, iMolecule0, iMolecule1, n0, nLinks0, endId;
55  int idLink, iAtom0,iAtom1, iAtom, nNeighbor,id0, id1;
56  double rsq, oldEnergy, newEnergy;
57  double dRSq, mindRSq=cutoff_*cutoff_, rnd, norm;
58  Link* linkPtr;
59  static const int maxNeighbor = CellList::MaxNeighbor;
60  double cdf[maxNeighbor], energy, sum;
61  int idneighbors[maxNeighbor];
62 
63 
64  // Go through all links.
65  nLinks0 = system().linkMaster().nLink();
66  for (idLink = nLinks0-1; idLink >= 0 ; idLink--) {
68  linkPtr = &(system().linkMaster().link(idLink));
69 
70  // Choose an end to be moved: atom0.
71  endId = 0;
72  atom0Ptr = &(linkPtr->atom0());
73  atom1Ptr = &(linkPtr->atom1());
74  if (random().uniform(0.0, 1.0) > 0.5) {
75  endId=1;
76  atom0Ptr = &(linkPtr->atom1());
77  atom1Ptr = &(linkPtr->atom0());
78  }
79  mol0Ptr = &atom0Ptr->molecule();
80  iAtom0 = atom0Ptr->indexInMolecule();
81  iMolecule0 = system().moleculeId(*mol0Ptr);
82  mol1Ptr = &atom1Ptr->molecule();
83  iMolecule1 = system().moleculeId(*mol1Ptr);
84  iAtom1 = atom1Ptr->indexInMolecule();
85 
86  // If the atom is not a chain end
87  if (iAtom0 != 0 && iAtom0 != mol0Ptr->nAtom() - 1) {
88 
89  // Calculate energy of old configuration.
90  rsq = boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
91  oldEnergy = system().linkPotential().energy(rsq, linkPtr->typeId());
92 
93  // Move the atom
94  iAtom = iAtom0;
95  iAtom0 = iAtom - 1;
96  if(random().uniform(0.0, 1.0) > 0.5) iAtom0 = iAtom + 1;
97  // If the atoms belong to the same chain
98  if(iMolecule0==iMolecule1){
99  if(std::fabs(iAtom0-iAtom1)<2) iAtom0 = iAtom;
100  }
101  atom0Ptr = &mol0Ptr->atom(iAtom0);
102 
103  // Calculate energy of new configuration
104  rsq = boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
105  newEnergy = system().linkPotential().energy(rsq, linkPtr->typeId());
106  // Accept new configuration with Metropolis
107  if (random().metropolis(boltzmann(newEnergy - oldEnergy))) {
108  system().linkMaster().reSetAtom(*linkPtr, *atom0Ptr, endId);
109  //system().linkMaster().reSetAtoms(*linkPtr, *atom0Ptr, *atom1Ptr);
110  //system().linkMaster().addLink(*atom0Ptr, *atom1Ptr, 0);
111  //system().linkMaster().removeLink(idLink);
113  }
114 
115  } else { // If the atom is a chain end
116 
117  rsq = boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
118 
119  // try to move in the chain
120  if (random().uniform(0.0, 1.0) > 0.5) {
121 
122  // Calculate energy of old configuration.
123  oldEnergy = system().linkPotential().energy(rsq, linkPtr->typeId());
124 
125  // Move the atom
126  iAtom = iAtom0;
127  iAtom0 = iAtom - 1;
128  if (iAtom == 0) iAtom0 = 1;
129  // If the atoms belong to the same chain
130  if(iMolecule0==iMolecule1){
131  if(std::fabs(iAtom0-iAtom1)<2) iAtom0 = iAtom;
132  }
133  atom0Ptr = &mol0Ptr->atom(iAtom0);
134 
135  // Calculate energy of new configuration
136  rsq = boundary().distanceSq(atom0Ptr->position(),
137  atom1Ptr->position());
138  newEnergy = system().linkPotential().energy(rsq, linkPtr->typeId());
139 
140  // Accept or reject new configuration.
141  if (random().metropolis(boltzmann(newEnergy - oldEnergy))) {
142  system().linkMaster().reSetAtom(*linkPtr, *atom0Ptr, endId);
143  //system().linkMaster().reSetAtoms(*linkPtr, *atom0Ptr, *atom1Ptr);
145  }
146 
147  } else { // try to renew the slip-link
148 
149  #ifdef MCMD_LINK_TRANSFER
150  // Try to renew the link if the bond is smaller than the cutoff
151  if (rsq <= mindRSq) {
152 
153  // Get array of neighbors
154  system().pairPotential().cellList().getNeighbors(atom0Ptr->position(), neighbors_);
155  nNeighbor = neighbors_.size();
156 
157  iMolecule0 = system().moleculeId(*mol0Ptr);
158  id0 = atom0Ptr->id();
159  n0 = 0;
160  sum = 0;
161 
162  // Loop over neighboring atoms
163  for (j = 0; j < nNeighbor; ++j) {
164  atom1Ptr = neighbors_[j];
165  mol1Ptr = &atom1Ptr->molecule();
166  iMolecule1 = system().moleculeId(*mol1Ptr);
167  id1 = atom1Ptr->id();
168 
169  // Check if atoms are the same
170  if (id0 != id1){
171 
172  // Exclude masked pairs
173  if (!atom0Ptr->mask().isMasked(*atom1Ptr)) {
174 
175  // Identify possible partners and compute weights.
176  dRSq = system().boundary().distanceSq(atom0Ptr->position(),
177  atom1Ptr->position());
178  if (dRSq <= mindRSq) {
179  energy = system().linkPotential().energy(dRSq, 0);
180  sum = sum + boltzmann(energy);
181  cdf[n0] = sum;
182  idneighbors[n0] = j;
183  n0++;
184  }
185  }
186  }
187  }
188 
189  // If at least 1 candidate has been found.
190  if (n0 > 0) {
191  // Choose a partner with probability cdf[j]/cdf[n0-1]
192  j = 0;
193  rnd = random().uniform(0.0, 1.0);
194  norm = 1.0/cdf[n0-1];
195  while (rnd > cdf[j]*norm ){
196  j = j + 1;
197  }
198  atom1Ptr = neighbors_[idneighbors[j]];
199  // renew the slip-link with the selected partner.
200  system().linkMaster().addLink(*atom0Ptr, *atom1Ptr, 0);
201  system().linkMaster().removeLink(idLink);
203  }
204 
205  } // else if dRsq < mindRSq
206  #endif
207 
208  } // if (shuffle) else (transfer)
209 
210  } // if (not at end) else (at end)
211 
212  } // foreach link
213  return true;
214  }
215 
216 }
217 #endif
int nLink() const
Get the total number of active Links.
Definition: LinkMaster.h:261
Molecule & molecule() const
Get the parent Molecule by reference.
A System for use in a Markov chain Monte Carlo simulation.
Definition: McSystem.h:52
virtual void readParameters(std::istream &in)
Read cutoff and speciesId.
void removeLink(int id)
Remove a Link.
Definition: LinkMaster.cpp:77
void incrementNAttempt()
Increment the number of attempted moves.
Definition: McMove.h:191
static const int MaxNeighbor
Maximum possible number of neighboring atoms.
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.
virtual bool move()
Move slip-springs.
Mask & mask()
Get the associated Mask by reference.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
double uniform()
Return a random floating point number x, uniformly distributed in the range 0 <= x < 1...
Definition: Random.h:203
SliplinkMove(McSystem &system)
Constructor.
double boltzmann(double energy)
Boltzmann weight associated with an energy difference.
Definition: SystemMove.h:100
bool isMasked(const Atom &atom) const
True if the atom is in the masked set for the target Atom.
McSystem & system()
Get parent McSystem.
Definition: SystemMove.h:82
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
An McMove that acts on one McSystem.
Definition: SystemMove.h:28
int id() const
Get global index for this Atom within the Simulation.
void reSetAtom(Link &link, Atom &atom, int endId)
Modify one atom attached to a link.
Definition: LinkMaster.cpp:160
Forward iterator for a PArray.
Definition: ArraySet.h:19
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 double energy(double rSq, int type) const =0
Returns potential energy for one bond.
Boundary & boundary() const
Get the Boundary by reference.
Definition: System.h:1064
BondPotential & linkPotential() const
Return the McLinkPotential by reference.
Definition: McSystem.h:493
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;.
Link & link(int id) const
Return an active link by an internal set index.
Definition: LinkMaster.h:255
bool metropolis(double ratio)
Metropolis algorithm for whether to accept a MC move.
Definition: Random.h:260
A physical molecule (a set of covalently bonded Atoms).
const Vector & position() const
Get the position Vector by const reference.
void addLink(Atom &atom0, Atom &atom1, int typeId)
Add a link betwen two specific Atoms.
Definition: LinkMaster.cpp:39
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
int nAtom() const
Get the number of Atoms in this Molecule.
int moleculeId(const Molecule &molecule) const
Get the index of a Molecule within its Species in this System.
Definition: System.cpp:1189
Boundary & boundary()
Get Boundary object of parent McSystem.
Definition: SystemMove.h:88
LinkMaster & linkMaster() const
Get the LinkMaster by reference.
Definition: System.h:1074