Simpatico  v1.10
SliplinkerEnd.cpp
1 #ifndef SLIPLINKER_END_CPP
2 #define SLIPLINKER_END_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 "SliplinkerEnd.h"
12 #include <mcMd/simulation/Simulation.h>
13 #include <mcMd/mcSimulation/McSystem.h>
14 #include <mcMd/links/LinkMaster.h>
15 #include <mcMd/potentials/pair/McPairPotential.h>
16 #include <mcMd/potentials/bond/BondPotential.h>
17 #include <mcMd/chemistry/Molecule.h>
18 #include <mcMd/chemistry/Atom.h>
19 #include <simp/boundary/Boundary.h>
20 #include <util/misc/FileMaster.h>
21 #include <util/space/Vector.h>
22 #include <util/space/Dimension.h>
23 #include <util/global.h>
24 
25 
26 namespace McMd
27 {
28 
29  using namespace Util;
30  using namespace Simp;
31 
32  // Constructor
34  SystemMove(system),
35  cutoff_(0),
36  mu_(0),
37  speciesId_(0)
38  { setClassName("SliplinkerEnd"); }
39 
40  void SliplinkerEnd::readParameters(std::istream& in)
41  {
42  readProbability(in);
43  read<double>(in, "cutoff", cutoff_);
44  read<double>(in, "mu", mu_);
45  read<int>(in, "speciesId", speciesId_);
46  }
47 
48 
49  // Create or destroy the slip-springs.
51  {
53  Atom *atom0Ptr, *atom1Ptr;
54  Molecule* mol0Ptr;
55  //Molecule* mol1Ptr;
56  Molecule* molIPtr;
57  double prob, dRSq, mindRSq=cutoff_*cutoff_, rnd, norm;
58  int i, ntrials, j, nNeighbor, idLink, id0, id1;
59  int iAtom0, n0;
60  // int iAtom1;
61  Link* linkPtr;
62  static const int maxNeighbor = CellList::MaxNeighbor;
63  double cdf[maxNeighbor], energy, sum;
64  int idneighbors[maxNeighbor];
65 
66  ntrials = 4 * system().nMolecule(speciesId_);
67  for (i=0; i < ntrials; ++i){
68 
69  //Choose to create or destroy a link with prob 0.5
70  if (random().uniform(0.0, 1.0) > 0.5){
71 
72  // Try to create a link.
74 
75  // Choose a molecule at random
76  molIPtr = &(system().randomMolecule(speciesId_));
77 
78  // Choose a molecule end at random
79  iAtom0 = 0;
80  if (random().uniform(0.0, 1.0) > 0.5) iAtom0 = molIPtr->nAtom() - 1;
81  atom0Ptr = &molIPtr->atom(iAtom0);
82 
83  // Get array of neighbors
84  system().pairPotential().cellList().getNeighbors(atom0Ptr->position(), neighbors_);
85  nNeighbor = neighbors_.size();
86  id0 = atom0Ptr->id();
87 
88  n0 = 0;
89  sum = 0;
90  // Loop over neighboring atoms
91  for (j = 0; j < nNeighbor; ++j) {
92  atom1Ptr = neighbors_[j];
93  // mol1Ptr = &atom1Ptr->molecule();
94  id1 = atom1Ptr->id();
95 
96  // Check if atoms are the same
97  if (id0 != id1){
98  // Exclude masked pairs
99  if (!atom0Ptr->mask().isMasked(*atom1Ptr)) {
100  // Identify possible partners and calculate the cumulative distribution function
101  dRSq = system().boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
102  if (dRSq <= mindRSq) {
103  energy = system().linkPotential().energy(dRSq, 0);
104  //energy = 0.5*dRSq;
105  sum = sum + boltzmann(energy);
106  cdf[n0] = sum;
107  idneighbors[n0] = j;
108  n0++;
109  }
110  }
111  }
112  }
113 
114  // If at least 1 candidate has been found.
115  if (n0 > 0) {
116 
117  // Choose a partner with probability cdf[j]/cdf[n0-1]
118  j = 0;
119  rnd = random().uniform(0.0, 1.0);
120  norm = 1.0/cdf[n0-1];
121  while (rnd > cdf[j]*norm ){
122  j = j + 1;
123  }
124  atom1Ptr = neighbors_[idneighbors[j]];
125 
126  // Create a slip-link between the selected atoms with probability = prob
127  prob = 2.0*(system().linkMaster().nLink() + 1.0);
128  prob = 2.0 * system().nMolecule(speciesId_) * boltzmann(-mu_) * cdf[n0-1]/ prob ;
129  if (system().simulation().random().uniform(0.0, 1.0) < prob) {
130  if (random().uniform(0.0, 1.0) > 0.5){
131  system().linkMaster().addLink(*atom0Ptr, *atom1Ptr, 0);
132  } else {
133  system().linkMaster().addLink(*atom1Ptr, *atom0Ptr, 0);
134  }
135  incrementNAccept();
136  }
137 
138  }
139 
140  } else {
141 
142  // Try to destroy a link
144 
145  if (system().linkMaster().nLink() > 0){
146 
147  // Choose a link at random
148  idLink = random().uniformInt(0, system().linkMaster().nLink());
149  linkPtr = &(system().linkMaster().link(idLink));
150 
151  // Choose atom0 and atom1 from link ends at random
152  if (random().uniform(0.0, 1.0) > 0.5){
153  atom0Ptr = &(linkPtr->atom0());
154  atom1Ptr = &(linkPtr->atom1());
155  } else {
156  atom0Ptr = &(linkPtr->atom1());
157  atom1Ptr = &(linkPtr->atom0());
158  }
159 
160  mol0Ptr = &atom0Ptr->molecule();
161  iAtom0 = atom0Ptr->indexInMolecule();
162 
163  // mol1Ptr = &atom1Ptr->molecule();
164  // iAtom1 = atom1Ptr->indexInMolecule();
165 
166  // If atom 0 is at the end of a chain, try to delete the slip-spring
167  if (iAtom0 == 0 || iAtom0 == mol0Ptr->nAtom() - 1){
168 
169  dRSq = system().boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
170 
171  // try to delete the link if the bond is smaller than the cutoff
172  if (dRSq <= mindRSq) {
173  // Get array of neighbors
175  .getNeighbors(atom0Ptr->position(), neighbors_);
176  nNeighbor = neighbors_.size();
177  id0 = atom0Ptr->id();
178  n0 = 0;
179  sum = 0;
180  // Loop over neighboring atoms
181  for (j = 0; j < nNeighbor; ++j) {
182  atom1Ptr = neighbors_[j];
183  // mol1Ptr = &atom1Ptr->molecule();
184  id1 = atom1Ptr->id();
185 
186  // Check if atoms are the same
187  if (id0 != id1){
188  // Exclude masked pairs
189  if (!atom0Ptr->mask().isMasked(*atom1Ptr)) {
190  // Identify possible partners and calculate the cumulative distribution function
191  dRSq = system().boundary().distanceSq(atom0Ptr->position(), atom1Ptr->position());
192  if (dRSq <= mindRSq) {
193  energy = system().linkPotential().energy(dRSq, 0);
194  //energy = 0.5*dRSq;
195  sum = sum + boltzmann(energy);
196  cdf[n0] = sum;
197  idneighbors[n0] = j;
198  n0++;
199  }
200  }
201  }
202  }
203 
204  // Destroy the slip-link between the selected atoms with probability = prob
205  prob = 2.0 * system().nMolecule(speciesId_) * boltzmann(-mu_) * cdf[n0-1];
206  prob = 2.0*system().linkMaster().nLink() / prob;
207  if (system().simulation().random().uniform(0.0, 1.0) < prob) {
208  system().linkMaster().removeLink(idLink);
210  }
211  }
212  }
213  }
214  }
215  }
216  return true;
217  }
218 
219 }
220 #endif
SliplinkerEnd(McSystem &system)
Constructor.
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.
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.
virtual bool move()
Create or destroy slip-springs.
const CellList & cellList() const
Get the cellList by const reference.
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.
int nMolecule(int speciesId) const
Get the number of molecules of one Species in this System.
Definition: System.h:1128
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
An McMove that acts on one McSystem.
Definition: SystemMove.h:28
virtual void readParameters(std::istream &in)
Read cutoff and probability.
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 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
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
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.
LinkMaster & linkMaster() const
Get the LinkMaster by reference.
Definition: System.h:1074