Simpatico  v1.10
mcMd/potentials/bond/BondPotentialImpl.h
1 #ifndef MCMD_BOND_POTENTIAL_IMPL_H
2 #define MCMD_BOND_POTENTIAL_IMPL_H
3 
4 /*
5 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
6 *
7 * Copyright 2010 - 2017, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include <util/global.h>
12 #include <mcMd/potentials/bond/BondPotential.h>
13 #include <mcMd/simulation/SystemInterface.h>
14 
15 namespace Util
16 {
17  class Vector;
18  class Tensor;
19 }
20 
21 namespace McMd
22 {
23 
24  using namespace Util;
25 
26  class System;
27 
33  template <class Interaction>
35  {
36 
37  public:
38 
42  BondPotentialImpl(System& system);
43 
48 
52  virtual ~BondPotentialImpl();
53 
61  virtual void readParameters(std::istream& in);
62 
68  virtual void loadParameters(Serializable::IArchive &ar);
69 
75  virtual void save(Serializable::OArchive &ar);
76 
78 
79 
83  virtual double energy(double rsq, int bondTypeId) const;
84 
88  virtual double forceOverR(double rsq, int bondTypeId) const;
89 
93  virtual
94  double randomBondLength(Random* random, double beta, int bondTypeId)
95  const;
96 
104  void set(std::string name, int type, double value)
105  { interactionPtr_->set(name, type, value); }
106 
113  double get(std::string name, int type) const
114  { return interactionPtr_->get(name, type); }
115 
119  virtual std::string interactionClassName() const;
120 
122 
124 
131  double atomEnergy(const Atom& atom) const;
132 
136  void addForces();
137 
141  virtual void computeEnergy();
142 
146  virtual void computeStress();
147 
149 
153  Interaction& interaction();
154 
158  const Interaction& interaction() const;
159 
160  private:
161 
162  Interaction* interactionPtr_;
163 
164  bool isCopy_;
165 
169  template <typename T>
170  void computeStressImpl(T& stress) const;
171 
172  };
173 
174 }
175 
176 #include <mcMd/simulation/System.h>
177 #include <mcMd/simulation/Simulation.h>
178 #include <mcMd/simulation/stress.h>
179 #include <mcMd/chemistry/getAtomGroups.h>
180 #include <simp/boundary/Boundary.h>
181 #include <util/space/Dimension.h>
182 #include <util/space/Vector.h>
183 #include <util/space/Tensor.h>
184 #include <util/accumulators/setToZero.h>
185 
186 #include <fstream>
187 
188 namespace McMd
189 {
190 
191  using namespace Util;
192  using namespace Simp;
193 
194  /*
195  * Default constructor.
196  */
197  template <class Interaction>
199  : BondPotential(),
200  SystemInterface(system),
201  interactionPtr_(0),
202  isCopy_(false)
203  { interactionPtr_ = new Interaction(); }
204 
205  /*
206  * Constructor.
207  */
208  template <class Interaction>
211  : BondPotential(),
212  SystemInterface(other.system()),
213  interactionPtr_(&other.interaction()),
214  isCopy_(true)
215  {}
216 
217  /*
218  * Destructor.
219  */
220  template <class Interaction>
222  {
223  if (!isCopy_) {
224  delete interactionPtr_;
225  interactionPtr_ = 0;
226  }
227  }
228 
229  /*
230  * Read parameters from file.
231  */
232  template <class Interaction>
234  {
235  // Read only if not a copy. Do not indent interaction block.
236  if (!isCopy_) {
237  interaction().setNBondType(simulation().nBondType());
238  bool nextIndent = false;
239  addParamComposite(interaction(), nextIndent);
240  interaction().readParameters(in);
241  }
242  }
243 
244  /*
245  * Load internal state from an archive.
246  */
247  template <class Interaction>
248  void
250  {
251  ar >> isCopy_;
252  if (!isCopy_) {
253  interaction().setNBondType(simulation().nBondType());
254  bool nextIndent = false;
255  addParamComposite(interaction(), nextIndent);
256  interaction().loadParameters(ar);
257  }
258  }
259 
260  /*
261  * Save internal state to an archive.
262  */
263  template <class Interaction>
265  {
266  ar << isCopy_;
267  if (!isCopy_) {
268  interaction().save(ar);
269  }
270  }
271 
272  /*
273  * Return bond energy for a single pair.
274  */
275  template <class Interaction>
276  double BondPotentialImpl<Interaction>::energy(double rsq, int iBondType)
277  const
278  { return interaction().energy(rsq, iBondType); }
279 
280  /*
281  * Return force / separation for a single bonded pair.
282  */
283  template <class Interaction>
284  double BondPotentialImpl<Interaction>::forceOverR(double rsq, int iBondType)
285  const
286  { return interaction().forceOverR(rsq, iBondType); }
287 
288  /*
289  * Return force / separation for a single bonded pair.
290  */
291  template <class Interaction> double
293  randomBondLength(Random* random, double beta, int bondTypeId) const
294  { return interaction().randomBondLength(random, beta, bondTypeId); }
295 
296  /*
297  * Return bond energy for one Atom.
298  */
299  template <class Interaction>
301  {
302 
303  AtomBondArray bonds;
304  const Bond* bondPtr;
305  double rsq;
306  double energy = 0.0;
307  int iBond, nBond;
308 
309  getAtomBonds(atom, bonds);
310  nBond = bonds.size();
311  for (iBond = 0; iBond < nBond; ++iBond) {
312  bondPtr = bonds[iBond];
313  rsq = boundary().distanceSq(bondPtr->atom(0).position(),
314  bondPtr->atom(1).position());
315  energy += interaction().energy(rsq, bondPtr->typeId());
316  }
317 
318  return energy;
319  }
320 
321  /*
322  * Calculate covalent bond energy.
323  */
324  template <class Interaction>
326  {
327  double energy = 0.0;
328  double rsq = 0.0;
331 
332  for (int iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
333  if (simulation().species(iSpec).nBond() > 0) {
334  for (begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
335  for (molIter->begin(bondIter); bondIter.notEnd(); ++bondIter) {
336  rsq = boundary().
337  distanceSq( bondIter->atom(0).position(),
338  bondIter->atom(1).position());
339  energy += interaction().energy(rsq, bondIter->typeId());
340  }
341  }
342  }
343  }
344 
345  energy_.set(energy);
346  //return energy;
347  }
348 
349  /*
350  * Add bonded pair forces to forces array.
351  */
352  template <class Interaction>
354  {
355  Vector force;
356  double rsq;
357  System::MoleculeIterator molIter;
358  Molecule::BondIterator bondIter;
359  Atom *atom0Ptr, *atom1Ptr;
360  int iSpec;
361 
362  // Loop over all bonds in system
363  for (iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
364  if (simulation().species(iSpec).nBond() > 0) {
365  for (begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
366  for (molIter->begin(bondIter); bondIter.notEnd(); ++bondIter) {
367  atom0Ptr = &(bondIter->atom(0));
368  atom1Ptr = &(bondIter->atom(1));
369  rsq = boundary().distanceSq(atom0Ptr->position(),
370  atom1Ptr->position(), force);
371  force *= interaction().forceOverR(rsq, bondIter->typeId());
372  atom0Ptr->force() += force;
373  atom1Ptr->force() -= force;
374  }
375  }
376  }
377  }
378  }
379 
380  /*
381  * Generic stress / pressure computation.
382  *
383  * Allowed types:
384  * T == Tensor -> compute stress tensor
385  * T == Vector -> compute xx, yy, zz diagonal components
386  * T == double -> compute pressure (P_xx + P_yy + P_zz)/3
387  */
388  template <class Interaction>
389  template <typename T>
391  const
392  {
393  Vector dr, force;
394  double rsq;
395  const Atom* atom0Ptr;
396  const Atom* atom1Ptr;
397 
398  setToZero(stress);
399 
400  // Iterate over all bonds in System
403  for (int iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
404  if (simulation().species(iSpec).nBond() > 0) {
405  for (begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
406  molIter->begin(bondIter);
407  for ( ; bondIter.notEnd(); ++bondIter) {
408  atom0Ptr = &(bondIter->atom(0));
409  atom1Ptr = &(bondIter->atom(1));
410  rsq = boundary().distanceSq(atom0Ptr->position(),
411  atom1Ptr->position(), dr);
412  force = dr;
413  force *= interaction().forceOverR(rsq,
414  bondIter->typeId());
415  incrementPairStress(force, dr, stress);
416  }
417  }
418  }
419  }
420 
421  stress /= boundary().volume();
422  normalizeStress(stress);
423  }
424 
425  /*
426  * Compute all short-range pair contributions to stress.
427  */
428  template <class Interaction>
430  {
431  Tensor stress;
432  computeStressImpl(stress);
433 
434  // Set value of Setable<double> energy_
435  stress_.set(stress);
436  }
437 
438  template <class Interaction>
440  { return *interactionPtr_; }
441 
442  template <class Interaction>
443  inline
445  { return *interactionPtr_; }
446 
447  /*
448  * Return bond potential interaction class name.
449  */
450  template <class Interaction>
452  { return interaction().className(); }
453 
454 }
455 #endif
virtual double randomBondLength(Random *random, double beta, int bondTypeId) const
Return force / separation for a single pair.
A Vector is a Cartesian vector.
Definition: Vector.h:75
An interface to a System.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
bool notEnd() const
Is the current pointer not at the end of the array?
Definition: ArrayIterator.h:83
Vector & force()
Get atomic force Vector by reference.
double volume() const
Return unit cell volume.
void set(const T &value)
Set the value and mark as set.
Definition: Setable.h:107
double atomEnergy(const Atom &atom) const
Calculate the bond energy for one Atom.
void addForces()
Add the bond forces for all atoms.
Implementation template for a BondPotential.
A set of interacting Molecules enclosed by a Boundary.
Definition: System.h:115
int typeId() const
Get the typeId for this covalent group.
virtual void computeEnergy()
Calculate and store pair energy for this System.
Forward iterator for a PArray.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
A Tensor represents a Cartesian tensor.
Definition: Tensor.h:32
Forward const iterator for an Array or a C array.
Saving / output archive for binary ostream.
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:37
virtual std::string interactionClassName() const
Return pair interaction class name (e.g., "HarmonicBond").
BondPotentialImpl(System &system)
Constructor.
Simulation & simulation() const
Get the parent Simulation by reference.
void setToZero(int &value)
Set an int variable to zero.
Definition: setToZero.h:25
A point particle within a Molecule.
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
Definition: accumulators.mod:1
virtual double forceOverR(double rsq, int bondTypeId) const
Return force / separation for a single pair.
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Forward iterator for a PArray.
Definition: ArraySet.h:19
Atom & atom(int i)
Get a specific Atom in the Group by reference.
virtual void readParameters(std::istream &in)
Read potential energy.
bool notEnd() const
Is the current pointer not at the end of the array?
void begin(int speciesId, System::MoleculeIterator &iterator)
Initialize an iterator for molecules of one species in this SystemInterface.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Saving archive for binary istream.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSpecies() const
Get the number of Species in this Simulation.
void addParamComposite(ParamComposite &child, bool next=true)
Add a child ParamComposite object to the format array.
A sequence of NAtom covalently interacting atoms.
Boundary & boundary() const
Get the Boundary by reference.
Abstract Bond Potential class.
Interaction & interaction()
Return bond interaction by reference.
Random number generator.
Definition: Random.h:46
const Vector & position() const
Get the position Vector by const reference.
bool notEnd() const
Is this not the end of the array?
int nBond() const
Get number of bonds per molecule for this Species.
Species & species(int i)
Get a specific Species by reference.
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
System & system() const
Get the parent System by reference.
void getAtomBonds(const Atom &atom, AtomBondArray &groups)
Fill an array of pointers to Bonds that contain an Atom.
double energy()
Return the energy contribution, compute if necessary.
virtual void computeStress()
Compute and store the total nonbonded pressure.