Simpatico  v1.10
Sliplinker.cpp
1 #ifndef SLIPLINKER_CPP
2 #define SLIPLINKER_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 "Sliplinker.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/chemistry/Molecule.h>
17 #include <mcMd/chemistry/Atom.h>
18 #include <simp/boundary/Boundary.h>
19 #include <util/space/Vector.h>
20 #include <util/space/Dimension.h>
21 #include <util/global.h>
22 
23 
24 namespace McMd
25 {
26 
27  using namespace Util;
28  using namespace Simp;
29 
30  // Constructor
32  SystemMove(system),
33  cutoff_(0),
34  mu_(0),
35  speciesId_(0)
36  { setClassName("Sliplinker"); }
37 
38  void Sliplinker::readParameters(std::istream& in)
39  {
40  read<double>(in, "cutoff", cutoff_);
41  read<double>(in, "mu", mu_);
42  read<int>(in, "speciesId", speciesId_);
43  }
44 
45 
46  // Create or destroy the slip-springs.
48  {
50  Molecule::AtomIterator atomIter;
51  Atom *atom0Ptr, *atom1Ptr;
52  Atom* atomPtr;
53  Molecule *mol0Ptr, *mol1Ptr;
54  Molecule* molIPtr;
55  double prob, dRSq, mindRSq=cutoff_*cutoff_, rnd, norm;
56  int i, ntrials, j, nNeighbor, idLink, iAtom, id1, id0;
57  int iAtom0, iAtom1, iMolecule0, iMolecule1, n0;
58  Link* linkPtr;
59  static const int maxNeighbor = CellList::MaxNeighbor;
60  double cdf[maxNeighbor], energy, sum;
61  int idneighbors[maxNeighbor];
62 
63 
64  ntrials = 2 * system().simulation().atomCapacity();
65  for (i=0; i < ntrials; ++i){
66 
67  //Choose to create or destroy a link with prob 0.5
68  if (random().uniform(0.0, 1.0) > 0.5){
69  // Try to create a link.
71  // Choose a molecule and atom at random
72  molIPtr = &(system().randomMolecule(speciesId_));
73  iMolecule0 = system().moleculeId(*molIPtr);
74  iAtom = random().uniformInt(0, molIPtr->nAtom());
75  atomPtr = &molIPtr->atom(iAtom);
76  id0 = atomPtr->id();
77 
78  // Get array of neighbors
79  system().cellList().getNeighbors(atomPtr->position(), neighbors_);
80  nNeighbor = neighbors_.size();
81 
82  n0 = 0;
83  sum = 0;
84  // Loop over neighboring atoms
85  for (j = 0; j < nNeighbor; ++j) {
86  atom1Ptr = neighbors_[j];
87  mol1Ptr = &atom1Ptr->molecule();
88  iMolecule1 = system().moleculeId(*mol1Ptr);
89  id1 = atom1Ptr->id();
90 
91  // Check if atoms are the same
92  if (id0 != id1){
93  // Exclude masked pairs
94  if (!atomPtr->mask().isMasked(*atom1Ptr)) {
95  // Identify possible partners and calculate the cumulative distribution function
96  dRSq = system().boundary().distanceSq(atomPtr->position(), atom1Ptr->position());
97  if (dRSq <= mindRSq) {
98  energy = system().linkPotential().energy(dRSq, 0);
99  //energy = 0.5*dRSq;
100  sum = sum + boltzmann(energy);
101  cdf[n0] = sum;
102  idneighbors[n0] = j;
103  n0++;
104  }
105  }
106  }
107  }
108 
109  // If at least 1 candidate has been found.
110  if (n0 > 0) {
111  // Choose a partner with probability cdf[j]/cdf[n0-1]
112  j = 0;
113  rnd = random().uniform(0.0, 1.0);
114  norm = 1.0/cdf[n0-1];
115  while (rnd > cdf[j]*norm ){
116  j = j + 1;
117  }
118  atom1Ptr = neighbors_[idneighbors[j]];
119  // Create a slip-link between the selected atoms with probability = prob
120  prob = 2.0 * (system().linkMaster().nLink() + 1.0);
121  prob = system().simulation().atomCapacity() * boltzmann(-mu_) * cdf[n0-1]/ prob ;
122  //prob = 2.0 * system().nMolecule(speciesId_) * boltzmann(-mu_) * cdf[n0-1]/ prob ;
123  if (system().simulation().random().uniform(0.0, 1.0) < prob) {
124  system().linkMaster().addLink(*atomPtr, *atom1Ptr, 0);
125  incrementNAccept();
126  }
127  }
128  }
129  else {
130  // Try to destroy a link
132  // Choose a link at random
133  if (system().linkMaster().nLink() > 0){
134  idLink = random().uniformInt(0, system().linkMaster().nLink());
135  // Indentify the atoms for this link.
136  linkPtr = &(system().linkMaster().link(idLink));
137  atom0Ptr = &(linkPtr->atom0());
138  mol0Ptr = &atom0Ptr->molecule();
139  iMolecule0 = system().moleculeId(*mol0Ptr);
140  iAtom0 = atom0Ptr->indexInMolecule();
141  atom1Ptr = &(linkPtr->atom1());
142  mol1Ptr = &atom1Ptr->molecule();
143  iMolecule1 = system().moleculeId(*mol1Ptr);
144  iAtom1 = atom1Ptr->indexInMolecule();
145  // try to delete the slip-spring
146  dRSq = system().boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
147  // try to delete the link if the bond is smaller than the cutoff
148  if (dRSq <= mindRSq) {
149  // Get array of neighbors
150  system().cellList().getNeighbors(atom0Ptr->position(), neighbors_);
151  nNeighbor = neighbors_.size();
152  id0 = atom0Ptr->id();
153  n0 = 0;
154  sum = 0;
155  // Loop over neighboring atoms
156  for (j = 0; j < nNeighbor; ++j) {
157  atom1Ptr = neighbors_[j];
158  mol1Ptr = &atom1Ptr->molecule();
159  iMolecule1 = system().moleculeId(*mol1Ptr);
160  id1 = atom1Ptr->id();
161 
162  // Check if atoms are the same
163  if (id0 != id1){
164  // Exclude masked pairs
165  if (!atom0Ptr->mask().isMasked(*atom1Ptr)) {
166  // Identify possible partners and calculate the cumulative distribution function
167  dRSq = system().boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
168  if (dRSq <= mindRSq) {
169  energy = system().linkPotential().energy(dRSq, 0);
170  //energy = 0.5*dRSq;
171  sum = sum + boltzmann(energy);
172  cdf[n0] = sum;
173  idneighbors[n0] = j;
174  n0++;
175  }
176  }
177  }
178  }
179  // Destroy the slip-link between the selected atoms with probability = prob
180  //prob = 2.0 * system().nMolecule(speciesId_) * boltzmann(-mu_) * cdf[n0-1];
181  prob = system().simulation().atomCapacity() * boltzmann(-mu_) * cdf[n0-1];
182  prob = 2.0 * system().linkMaster().nLink() / prob;
183  if (system().simulation().random().uniform(0.0, 1.0) < prob) {
184  system().linkMaster().removeLink(idLink);
185  incrementNAccept();
186  }
187  }
188  }
189  }
190  }
191  return true;
192  }
193 
194 }
195 #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
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.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
int atomCapacity() const
Get the total number of Atoms allocated.
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
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.
virtual void readParameters(std::istream &in)
Read cutoff and probability.
Definition: Sliplinker.cpp:38
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
Sliplinker(McSystem &system)
Constructor.
Definition: Sliplinker.cpp:31
An McMove that acts on one McSystem.
Definition: SystemMove.h:28
int id() const
Get global index for this Atom within the Simulation.
long uniformInt(long range1, long range2)
Return random long int x uniformly distributed in range1 <= x < range2.
Definition: Random.h:224
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
Forward iterator for a PArray.
Definition: ArraySet.h:19
Random & random()
Get Random number generator of parent Simulation.
Definition: McMove.h:209
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 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
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.
void addLink(Atom &atom0, Atom &atom1, int typeId)
Add a link betwen two specific Atoms.
Definition: LinkMaster.cpp:39
virtual bool move()
Create or destroy slip-springs.
Definition: Sliplinker.cpp:47
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
LinkMaster & linkMaster() const
Get the LinkMaster by reference.
Definition: System.h:1074