Simpatico  v1.10
MdPairPotentialImpl.h
1 #ifndef MCMD_MD_PAIR_POTENTIAL_IMPL_H
2 #define MCMD_MD_PAIR_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 <mcMd/potentials/pair/MdPairPotential.h>
12 #include <mcMd/potentials/pair/McPairPotentialImpl.h>
13 #include <mcMd/simulation/stress.h>
14 #include <util/space/Tensor.h>
15 #include <util/misc/Setable.h>
16 #include <util/global.h>
17 
18 namespace Util
19 {
20  class Vector;
21 }
22 
23 namespace McMd
24 {
25 
26  using namespace Util;
27 
28  class System;
29 
35  template <class Interaction>
37  {
38 
39  public:
40 
46  MdPairPotentialImpl(System& system);
47 
61 
65  virtual ~MdPairPotentialImpl();
66 
77  virtual void readParameters(std::istream& in);
78 
84  virtual void loadParameters(Serializable::IArchive &ar);
85 
91  virtual void save(Serializable::OArchive &ar);
92 
94 
95 
104  virtual
105  double energy(double rsq, int iAtomType, int jAtomType) const;
106 
115  virtual
116  double forceOverR(double rsq, int iAtomType, int jAtomType) const;
117 
121  virtual double maxPairCutoff() const;
122 
131  void set(std::string name, int i, int j, double value)
132  { interactionPtr_->set(name, i, j, value); }
133 
142  double get(std::string name, int i, int j) const
143  { return interactionPtr_->get(name, i, j); }
144 
148  virtual std::string interactionClassName() const;
149 
151 
153 
162  virtual void addForces();
163 
169  virtual void computeEnergy();
170 
174  virtual void computeStress();
175 
177 
178  protected:
179 
180  Interaction& interaction() const
181  { return *interactionPtr_; }
182 
183  /*
184  * Generalized stress computation.
185  */
186  template <typename T>
187  void computeStressImpl(T& stress);
188 
189  private:
190 
191  Interaction* interactionPtr_;
192 
193  bool isCopy_;
194 
195  };
196 
197 }
198 
199 #include <mcMd/simulation/System.h>
200 #include <mcMd/simulation/Simulation.h>
201 #include <mcMd/simulation/stress.h>
202 #include <mcMd/neighbor/PairIterator.h>
203 #include <simp/boundary/Boundary.h>
204 #include <util/space/Dimension.h>
205 #include <util/space/Vector.h>
206 #include <util/accumulators/setToZero.h>
207 
208 #include <fstream>
209 
210 namespace McMd
211 {
212 
213  using namespace Util;
214  using namespace Simp;
215 
216  /*
217  * Default constructor.
218  */
219  template <class Interaction>
221  : MdPairPotential(system),
222  interactionPtr_(0),
223  isCopy_(false)
224  { interactionPtr_ = new Interaction; }
225 
226  /*
227  * Constructor, copy from McPairPotentialImpl<Interaction>.
228  */
229  template <class Interaction>
232  : MdPairPotential(other.system()),
233  interactionPtr_(&other.interaction()),
234  isCopy_(true)
235  {}
236 
237  /*
238  * Destructor.
239  */
240  template <class Interaction>
242  {
243  if (interactionPtr_ && !isCopy_) {
244  delete interactionPtr_;
245  interactionPtr_ = 0;
246  }
247  }
248 
249  template <class Interaction>
251  {
252  // Read pair potential parameters only if not a copy.
253  if (!isCopy_) {
254  interaction().setNAtomType(simulation().nAtomType());
255  bool nextIndent = false;
256  addParamComposite(interaction(), nextIndent);
257  interaction().readParameters(in);
258  }
259 
260  // Initialize the PairList
262  double cutoff = interaction().maxPairCutoff();
263  pairList_.initialize(simulation().atomCapacity(), cutoff);
264  }
265 
266  /*
267  * Load internal state from an archive.
268  */
269  template <class Interaction>
270  void
272  {
273  ar >> isCopy_;
274  if (!isCopy_) {
275  interaction().setNAtomType(simulation().nAtomType());
276  bool nextIndent = false;
277  addParamComposite(interaction(), nextIndent);
278  interaction().loadParameters(ar);
279  }
281  }
282 
283  /*
284  * Save internal state to an archive.
285  */
286  template <class Interaction>
288  {
289  ar << isCopy_;
290  if (!isCopy_) {
291  interaction().save(ar);
292  }
293  pairList_.save(ar);
294  }
295 
296  /*
297  * Return pair energy for a single pair.
298  */
299  template <class Interaction> double
301  int iAtomType, int jAtomType) const
302  { return interaction().energy(rsq, iAtomType, jAtomType); }
303 
304  /*
305  * Return force / separation for a single pair.
306  */
307  template <class Interaction> double
309  int iAtomType, int jAtomType) const
310  {
311  if (rsq < interaction().cutoffSq(iAtomType, jAtomType)) {
312  return interaction().forceOverR(rsq, iAtomType, jAtomType);
313  } else {
314  return 0.0;
315  }
316  }
317 
318  /*
319  * Return maximum cutoff.
320  */
321  template <class Interaction>
323  { return interaction().maxPairCutoff(); }
324 
325  /*
326  * Return pair interaction class name.
327  */
328  template <class Interaction>
330  { return interaction().className(); }
331 
332  /*
333  * Add nonBonded pair forces to atomic forces.
334  */
335  template <class Interaction>
337  {
338  // Update PairList if necessary
339  if (!isPairListCurrent()) {
340  buildPairList();
341  }
342 
343  PairIterator iter;
344  Vector force;
345  double rsq;
346  Atom *atom0Ptr;
347  Atom *atom1Ptr;
348  int type0, type1;
349 
350  // Loop over nonbonded neighbor pairs
351  for (pairList_.begin(iter); iter.notEnd(); ++iter) {
352  iter.getPair(atom0Ptr, atom1Ptr);
353  rsq = boundary().
354  distanceSq(atom0Ptr->position(), atom1Ptr->position(),
355  force);
356  type0 = atom0Ptr->typeId();
357  type1 = atom1Ptr->typeId();
358  if (rsq < interaction().cutoffSq(type0, type1)) {
359  force *= interaction().forceOverR(rsq, type0, type1);
360  atom0Ptr->force() += force;
361  atom1Ptr->force() -= force;
362  }
363  }
364 
365  }
366 
367  /*
368  * Compute and store all short-range pair energy components.
369  */
370  template <class Interaction>
372  {
373  // Update PairList if necessary
374  if (!isPairListCurrent()) {
375  buildPairList();
376  }
377 
378  // Loop over pairs
379  PairIterator iter;
380  Atom *atom0Ptr;
381  Atom *atom1Ptr;
382  double rsq;
383  double energy = 0.0;
384  for (pairList_.begin(iter); iter.notEnd(); ++iter) {
385  iter.getPair(atom0Ptr, atom1Ptr);
386  rsq = boundary().
387  distanceSq(atom0Ptr->position(), atom1Ptr->position());
388  energy += interaction().
389  energy(rsq, atom0Ptr->typeId(), atom1Ptr->typeId());
390  }
391 
392  // Set value of Setable<double> energy_
393  energy_.set(energy);
394  }
395 
396  /*
397  * Compute all short-range pair contributions to stress.
398  */
399  template <class Interaction>
400  template <typename T>
402  {
403  // Update PairList if necessary
404  if (!isPairListCurrent()) {
405  buildPairList();
406  }
407 
408  Vector dr;
409  Vector force;
410  double rsq;
411  PairIterator iter;
412  Atom* atom1Ptr;
413  Atom* atom0Ptr;
414  int type0, type1;
415 
416  // Set all elements of stress tensor to zero.
417  setToZero(stress);
418 
419  // Loop over nonbonded neighbor pairs
420  for (pairList_.begin(iter); iter.notEnd(); ++iter) {
421  iter.getPair(atom0Ptr, atom1Ptr);
422  rsq = boundary().
423  distanceSq(atom0Ptr->position(), atom1Ptr->position(), dr);
424  type0 = atom0Ptr->typeId();
425  type1 = atom1Ptr->typeId();
426  if (rsq < interaction().cutoffSq(type0, type1)) {
427  force = dr;
428  force *= interaction().forceOverR(rsq, type0, type1);
429  incrementPairStress(force, dr, stress);
430  }
431  }
432 
433  // Normalize by volume
434  stress /= boundary().volume();
435  normalizeStress(stress);
436  }
437 
438  /*
439  * Compute all short-range pair contributions to stress.
440  */
441  template <class Interaction>
443  {
444  Tensor stress;
445  computeStressImpl(stress);
446 
447  // Set value of Setable<double> stress_
448  stress_.set(stress);
449  }
450 
451 }
452 #endif
void initialize(int atomIdEnd, double potentialCutoff)
Allocate memory and initialize.
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual double forceOverR(double rsq, int iAtomType, int jAtomType) const
Return force / separation for a single pair.
virtual void addForces()
Calculate non-bonded pair forces for all atoms in this System.
virtual double maxPairCutoff() const
Return maximum cutoff.
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
virtual void computeEnergy()
Calculate and store pair energy for this System.
Implementation template for an MdPairPotential.
void loadParamComposite(Serializable::IArchive &ar, ParamComposite &child, bool next=true)
Add and load a required child ParamComposite.
A set of interacting Molecules enclosed by a Boundary.
Definition: System.h:115
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
MdPairPotentialImpl(System &system)
Constructor.
A Tensor represents a Cartesian tensor.
Definition: Tensor.h:32
void getPair(Atom *&atom1Ptr, Atom *&atom2Ptr) const
Get pointers for current pair of Atoms.
Saving / output archive for binary ostream.
virtual ~MdPairPotentialImpl()
Destructor.
Implementation template for an McPairPotential.
int typeId() const
Get type index for this Atom.
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.
Utility classes for scientific computation.
Definition: accumulators.mod:1
virtual std::string interactionClassName() const
Return pair interaction class name (e.g., "LJPair").
Iterator for pairs in a PairList.
virtual void readParameters(std::istream &in)
Read pair potential interaction and pair list blocks.
void begin(PairIterator &iterator) const
Initialize a PairIterator.
PairList pairList_
Verlet neighbor pair list for nonbonded interactions.
An PairPotential for MD simulation.
bool isPairListCurrent()
Return true if PairList is current, false if obsolete.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Saving archive for binary istream.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
void buildPairList()
Build the internal PairList.
void addParamComposite(ParamComposite &child, bool next=true)
Add a child ParamComposite object to the format array.
virtual void computeStress()
Compute and store the total nonbonded pressure.
Boundary & boundary() const
Get the Boundary by reference.
bool notEnd() const
Return true if not at end of PairList.
void readParamComposite(std::istream &in, ParamComposite &child, bool next=true)
Add and read a required child ParamComposite.
const Vector & position() const
Get the position Vector by const reference.
System & system() const
Get the parent System by reference.
double energy()
Return the energy contribution, compute if necessary.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.