Simpatico  v1.10
EndSwapMove.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 "EndSwapMove.h"
9 #include <mcMd/simulation/Simulation.h>
10 #include <mcMd/mcSimulation/McSystem.h>
12 #include <mcMd/chemistry/Molecule.h>
13 #include <mcMd/chemistry/Atom.h>
14 
15 #include <simp/boundary/Boundary.h>
16 #include <simp/species/Species.h>
17 #include <simp/species/Linear.h>
18 
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  SystemMove(system),
32  speciesId_(-1)
33  {
34  /*
35  * Preconditions:
36  * For now, Usage with angles and dihedrals is prohibited. This
37  * move would work fine with homogeneous angles and dihedrals,
38  * and could be modified to work with heterogeneous potentials,
39  * but the required checks or modifications are not implemented.
40  */
41 
42  #ifdef SIMP_ANGLE
43  if (system.hasAnglePotential()) {
44  UTIL_THROW("CfbEndBase unusable with heterogeneous dihedrals");
45  }
46  #endif
47  #ifdef SIMP_DIHEDRAL
48  if (system.hasDihedralPotential()) {
49  UTIL_THROW("CfbEndBase unusable with heterogeneous dihedrals");
50  }
51  #endif
52 
53  setClassName("EndSwapMove");
54  }
55 
56  /*
57  * Read parameter speciesId.
58  */
59  void EndSwapMove::readParameters(std::istream& in)
60  {
61  readProbability(in);
62  read<int>(in, "speciesId", speciesId_);
63 
64  Species* speciesPtr = &(simulation().species(speciesId_));
65  int nAtom = speciesPtr->nAtom();
66 
67  // Preconditions
68  if (speciesPtr->isMutable()) {
69  UTIL_THROW("EndSwapMove on mutable Species");
70  }
71  Linear* linearPtr = dynamic_cast<Linear*>(speciesPtr);
72  if (linearPtr == 0) {
73  UTIL_THROW("EndSwapMove on Species that is not a Linear");
74  }
75 
76  // Allocate memory
77  atomTypeIds_.allocate(nAtom);
78  positions_.allocate(nAtom);
79 
80  // Set array of atom type ids
81  for (int i = 0; i < nAtom; ++i) {
82  atomTypeIds_[i] = speciesPtr->atomTypeId(i);
83  }
84  }
85 
86  /*
87  * Load from archive.
88  */
90  {
92  loadParameter<int>(ar, "speciesId", speciesId_);
93  ar & atomTypeIds_;
94 
95  // Validate
96  Species* speciesPtr = &(simulation().species(speciesId_));
97  int nAtom = speciesPtr->nAtom();
98  if (speciesPtr->isMutable()) {
99  UTIL_THROW("EndSwapMove applied to mutable species");
100  }
101  Linear* linearPtr = dynamic_cast<Linear*>(speciesPtr);
102  if (linearPtr == 0) {
103  UTIL_THROW("EndSwapMove applied to species that is not Linear");
104  }
105  if (nAtom != atomTypeIds_.capacity()) {
106  UTIL_THROW("Inconsistent capacity for atomTypeIds array");
107  }
108 
109  positions_.allocate(nAtom);
110  }
111 
112  /*
113  * Save to archive.
114  */
116  {
117  McMove::save(ar);
118  ar & speciesId_;
119  ar & atomTypeIds_;
120  }
121 
122  /*
123  * Generate, attempt and accept or reject a Monte Carlo move.
124  */
126  {
127  double newEnergy, oldEnergy;
128  Molecule* molPtr;
129  Atom* atomPtr;
130  int i, nAtom;
131 
133 
134  molPtr = &(system().randomMolecule(speciesId_));
135  nAtom = molPtr->nAtom();
136 
137  // Calculate old molecule energy = pair + external
138  oldEnergy = 0.0;
139  #ifndef SIMP_NOPAIR
140  oldEnergy += system().pairPotential().moleculeEnergy(*molPtr);
141  #endif
142  #ifdef SIMP_EXTERNAL
143  if (system().hasExternalPotential()) {
144  for (i = 0; i < nAtom; ++i) {
145  atomPtr = &molPtr->atom(i);
146  oldEnergy += system().externalPotential().atomEnergy(*atomPtr);
147  }
148  }
149  #endif
150 
151  // Reverse sequence of atom types
152  for (i = 0; i < nAtom; ++i) {
153  assert(molPtr->atom(i).typeId() == atomTypeIds_[i]);
154  molPtr->atom(i).setTypeId(atomTypeIds_[nAtom - 1 - i]);
155  }
156 
157  // Calculate new energy (with reversed sequence of atom types).
158  newEnergy = 0.0;
159  #ifndef SIMP_NOPAIR
160  newEnergy += system().pairPotential().moleculeEnergy(*molPtr);
161  #endif
162  #ifdef SIMP_EXTERNAL
163  if (system().hasExternalPotential()) {
164  for (i = 0; i < nAtom; ++i) {
165  molPtr->atom(i).setTypeId(atomTypeIds_[nAtom - 1 - i]);
166  atomPtr = &molPtr->atom(i);
167  newEnergy += system().externalPotential().atomEnergy(*atomPtr);
168  }
169  }
170  #endif
171 
172  // Restore original sequence of atom type Ids
173  for (i = 0; i < nAtom; ++i) {
174  molPtr->atom(i).setTypeId(atomTypeIds_[i]);
175  }
176 
177  // Decide whether to accept or reject
178  bool accept = random().metropolis(boltzmann(newEnergy-oldEnergy));
179 
180  if (accept) {
181 
182  // Store all atomic positions
183  for (i = 0; i < nAtom; ++i) {
184  positions_[i] = molPtr->atom(i).position();
185  }
186 
187  // Reverse sequence of atomic positions
188  for (i = 0; i < nAtom; ++i) {
189  atomPtr = &molPtr->atom(i);
190  atomPtr->position() = positions_[nAtom - 1 - i];
191  #ifndef SIMP_NOPAIR
192  system().pairPotential().updateAtomCell(*atomPtr);
193  #endif
194  }
195 
197 
198  }
199 
200  return accept;
201  }
202 
203 }
A System for use in a Markov chain Monte Carlo simulation.
Definition: McSystem.h:52
virtual double atomEnergy(const Atom &atom) const =0
Calculate the external energy for one Atom.
void incrementNAttempt()
Increment the number of attempted moves.
Definition: McMove.h:191
int nAtom() const
Get number of atoms per molecule for this Species.
Include this file to include all MC potential energy classes at once.
bool hasDihedralPotential() const
Does a dihedral potential exist?.
Definition: McSystem.h:433
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: McMove.cpp:58
bool hasAnglePotential() const
Does angle potential exist?.
Definition: McSystem.h:416
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.
Saving / output archive for binary ostream.
double boltzmann(double energy)
Boltzmann weight associated with an energy difference.
Definition: SystemMove.h:100
#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
int typeId() const
Get type index for this Atom.
ExternalPotential & externalPotential() const
Return ExternalPotential by reference.
Definition: McSystem.h:473
A point particle within a Molecule.
virtual double moleculeEnergy(const Molecule &molecule) const =0
Calculate the nonbonded pair energy for an entire Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
An McMove that acts on one McSystem.
Definition: SystemMove.h:28
int speciesId_
Integer index for molecular species.
Definition: EndSwapMove.h:73
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Definition: EndSwapMove.cpp:89
virtual void readParameters(std::istream &in)
Read species to which displacement is applied.
Definition: EndSwapMove.cpp:59
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 setTypeId(int typeId)
Set the atomic type index.
Saving archive for binary istream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
virtual bool move()
Generate and accept or reject a move.
bool isMutable() const
Is this a mutable Species?
void readProbability(std::istream &in)
Read the probability from file.
Definition: McMove.cpp:42
DArray< int > atomTypeIds_
Array of atom type indices.
Definition: EndSwapMove.h:76
void setClassName(const char *className)
Set class name string.
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
bool metropolis(double ratio)
Metropolis algorithm for whether to accept a MC move.
Definition: Random.h:260
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
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.
EndSwapMove(McSystem &system)
Constructor.
Definition: EndSwapMove.cpp:30
A Species represents a set of chemically similar molecules.
Species & species(int i)
Get a specific Species by reference.
void updateAtomCell(Atom &atom)
Update the cell list to reflect a new position.
A Species of linear polymers (abstract).
Definition: Linear.h:36
DArray< Vector > positions_
Array of atomic positions (temporary).
Definition: EndSwapMove.h:79
int nAtom() const
Get the number of Atoms in this Molecule.