Path Integral Quantum Monte Carlo
cmc.cpp
Go to the documentation of this file.
1 
8 #include "common.h"
9 #include "constants.h"
10 #include "container.h"
11 #include "potential.h"
12 #include "cmc.h"
13 #include "communicator.h"
14 
15 // ---------------------------------------------------------------------------
16 // ---------------------------------------------------------------------------
17 // CLASSICAL MONTE CARLO CLASS -----------------------------------------------
18 // ---------------------------------------------------------------------------
19 // ---------------------------------------------------------------------------
20 
21 /**************************************************************************/
25  PotentialBase *_interactionPtr, MTRand &_random, const Container *_boxPtr,
26  Array <dVec,1> &initialPos) :
27  externalPtr(_externalPtr),
28  interactionPtr(_interactionPtr),
29  random(_random),
30  boxPtr(_boxPtr),
31  config(initialPos)
32 {
33  /* The number of particles */
34  numParticles = config.extent(firstDim);
35 
36  /* Set the fugacity z*/
37  z = exp(constants()->mu()/constants()->T())/pow(constants()->dBWavelength(),NDIM);
38 
39  /* Compute the initial total potential energy */
40  energy = getTotalEnergy();
41 
42  /* Initialize acceptance tracking */
43  numMoveTotal = 0;
44  numMoveAccept = 0;
45 
46  numDeleteTotal = 0;
47  numDeleteAccept = 0;
48 
49  numInsertTotal = 0;
50  numInsertAccept = 0;
51 
52  /* Initialize measurements */
53  aveEnergy = 0.0;
54  aveNumParticles = 0.0;
55  aveEoN = 0.0;
56 }
57 
58 /**************************************************************************/
62 {
63  // empty destructor
64 }
65 
66 /**************************************************************************/
69 double ClassicalMonteCarlo::getTotalEnergy()
70 {
71  double locEnergy = 0.0;
72  sep = 0.0;
73  for (int part1 = 0; part1 < numParticles; part1++) {
74  locEnergy += externalPtr->V(config(part1));
75 
76  for (int part2 = part1+1; part2 < numParticles; part2++) {
77  sep = config(part1)-config(part2);
78  boxPtr->putInside(sep);
79  locEnergy += interactionPtr->V(sep);
80  }
81  }
82  return locEnergy;
83 }
84 
85 /**************************************************************************/
88 void ClassicalMonteCarlo::run(uint32 numMCSteps, bool gce) {
89 
90  int numMeasure = 0;
91  double x;
92  for(uint32 n = 1; n < numMCSteps; n++) {
93  int m = 0;
94  do {
95  if (gce)
96  x = random.rand();
97  else
98  x = 0.0;
99 
100  /* Perform updates */
101  if (x < 1.0/3.0)
102  moveParticle();
103  else if (x < 2.0/3.0)
104  deleteParticle();
105  else
106  insertParticle();
107 
108  /* Update observables */
109  aveEnergy += energy;
110  aveNumParticles += numParticles;
111  aveEoN += energy/(1.0*numParticles);
112  numMeasure++;
113 
114  m++;
115  } while (m < numParticles);
116 
117  // if ((n % 50) == 0)
118  // measure(numMeasure);
119  }
120 
121  /* Update the config array */
122  config.resizeAndPreserve(numParticles);
123 }
124 
125 /**************************************************************************/
129 void ClassicalMonteCarlo::moveParticle() {
130 
131  dVec oldPos;
132  oldPos = 0.0;
133  double oldV,newV;
134 
135  numMoveTotal++;
136 
137  int p = random.randInt(numParticles-1);
138 
139  /* Compute the old energy of particle p*/
140  oldV = externalPtr->V(config(p));
141  for (int p2 = 0; p2 < numParticles; p2++) {
142  if (p != p2) {
143  sep = config(p)-config(p2);
144  boxPtr->putInside(sep);
145  oldV += interactionPtr->V(sep);
146  }
147  }
148 
149  oldPos = config(p);
150 
151  /* The new random position */
152  config(p) = boxPtr->randUpdate(random,oldPos);
153 
154  /* Compute the new energy of particle p*/
155  newV = externalPtr->V(config(p));
156  for (int p2 = 0; p2 < numParticles; p2++) {
157  if (p != p2) {
158  sep = config(p)-config(p2);
159  boxPtr->putInside(sep);
160  newV += interactionPtr->V(sep);
161  }
162  }
163 
164  deltaV = newV - oldV;
165 
166  /* Now the metropolis step */
167  if (random.rand() < exp(-deltaV/constants()->T())) {
168  energy += deltaV;
169  numMoveAccept++;
170  }
171  else {
172  config(p) = oldPos;
173  }
174 }
175 
176 /**************************************************************************/
180 void ClassicalMonteCarlo::insertParticle() {
181 
182  dVec newPos;
183  newPos = 0.0;
184 
185  numInsertTotal++;
186 
187  newPos = boxPtr->randPosition(random);
188 
189  /* Compute the old energy of particle p*/
190  deltaV = externalPtr->V(newPos);
191  for (int p2 = 0; p2 < numParticles; p2++) {
192  sep = newPos-config(p2);
193  boxPtr->putInside(sep);
194  deltaV += interactionPtr->V(sep);
195  }
196 
197  double factor = z*boxPtr->volume/(numParticles+1);
198 
199  /* Now the metropolis step */
200  if (random.rand() < factor*exp(-deltaV/constants()->T())) {
201  energy += deltaV;
202  if (config.extent(firstDim) < (numParticles+1))
203  config.resizeAndPreserve(numParticles+1);
204  config(numParticles) = newPos;
205  numParticles++;
206  numInsertAccept++;
207  }
208 }
209 
210 /**************************************************************************/
214 void ClassicalMonteCarlo::deleteParticle() {
215 
216  numDeleteTotal++;
217 
218  int p = random.randInt(numParticles-1);
219 
220  /* Compute the old energy of particle p*/
221  deltaV = -externalPtr->V(config(p));
222  for (int p2 = 0; p2 < numParticles; p2++) {
223  if (p != p2) {
224  sep = config(p)-config(p2);
225  boxPtr->putInside(sep);
226  deltaV -= interactionPtr->V(sep);
227  }
228  }
229 
230  double factor = numParticles/(z*boxPtr->volume);
231 
232  /* Now the metropolis step */
233  if (random.rand() < factor*exp(-deltaV/constants()->T())) {
234  energy += deltaV;
235  config(p) = config(numParticles-1);
236  numParticles--;
237  numDeleteAccept++;
238  }
239 }
240 
241 /**************************************************************************/
245 void ClassicalMonteCarlo::measure(int &numMeasure) {
246  cout << aveEnergy/(numMeasure) << "\t" << aveNumParticles/(numMeasure)
247  << "\t" << (3.0/2.0)*constants()->T() + aveEoN/(numMeasure)
248  << "\t" << aveNumParticles/(numMeasure*boxPtr->volume)
249  << "\t" << 1.0*numMoveAccept/(1.0*numMoveTotal)
250  << "\t" << 1.0*numInsertAccept/(1.0*numInsertTotal)
251  << "\t" << 1.0*numDeleteAccept/(1.0*numDeleteTotal) << endl;
252  aveEnergy = 0.0;
253  aveEoN = 0.0;
254  aveNumParticles = 0.0;
255  numMeasure = 0;
256 }
~ClassicalMonteCarlo()
Destructor.
Definition: cmc.cpp:61
ClassicalMonteCarlo(PotentialBase *, PotentialBase *, MTRand &, const Container *, Array< dVec, 1 > &)
Constructor.
Definition: cmc.cpp:24
void run(uint32, bool)
Perform the Monte Carlo equilibration.
Definition: cmc.cpp:88
double T() const
Get temperature.
Definition: constants.h:41
The base class which holds details on the generalized box that our system will be simulated inside of...
Definition: container.h:24
virtual dVec randPosition(MTRand &) const =0
Random position inside a box.
double volume
The volume of the container in A^3.
Definition: container.h:35
virtual dVec randUpdate(MTRand &, const dVec &) const =0
Random updated position inside a box.
virtual void putInside(dVec &) const =0
Place a vector inside the simulation cell.
The base class from which all specific potentials are derived from.
Definition: potential.h:32
virtual double V(const dVec &)
The potential.
Definition: potential.h:39
ClassicalMonteCarlo class definition.
Global common header with shared dependencies and methods.
#define NDIM
Number of spatial dimnsions.
Definition: common.h:71
unsigned long uint32
Unsigned integer type, at least 32 bits.
Definition: common.h:105
TinyVector< double, NDIM > dVec
A NDIM-vector of type double.
Definition: common.h:111
Class definitions for all file input/output.
ConstantParameters class definition.
ConstantParameters * constants()
Global public access to the constants.
Definition: constants.h:201
The simulation cell.
All possible potential classes.