Simpatico  v1.10
LinkPotentialImpl.h
1 #ifndef MCMD_LINK_POTENTIAL_IMPL_H
2 #define MCMD_LINK_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/bond/BondPotential.h> // base class
12 #include <mcMd/simulation/SystemInterface.h> // base class
13 #include <mcMd/links/LinkMaster.h> // member
14 #include <util/global.h>
15 
16 namespace Util
17 {
18  class Vector;
19  class Tensor;
20 }
21 
22 namespace McMd
23 {
24 
25  using namespace Util;
26 
27  class System;
28 
38  template <class Interaction>
40  {
41 
42  public:
43 
47  LinkPotentialImpl(System& system);
48 
53 
57  virtual ~LinkPotentialImpl();
58 
66  virtual void readParameters(std::istream& in);
67 
69 
70 
74  virtual double energy(double rsq, int bondTypeId) const;
75 
79  virtual double forceOverR(double rsq, int bondTypeId) const;
80 
84  virtual
85  double randomBondLength(Random* random, double beta, int bondTypeId)
86  const;
87 
95  void set(std::string name, int type, double value)
96  { interactionPtr_->set(name, type, value); }
97 
104  double get(std::string name, int type) const
105  { return interactionPtr_->get(name, type); }
106 
110  virtual std::string interactionClassName() const;
111 
113 
115 
122  virtual double atomEnergy(const Atom& atom) const;
123 
127  virtual void addForces();
128 
132  virtual void computeEnergy();
133 
137  virtual void computeStress();
138 
140 
144  Interaction& interaction();
145 
149  const Interaction& interaction() const;
150 
151  private:
152 
153  // Pointer to a link/bond interaction.
154  Interaction* interactionPtr_;
155 
156  // Pointer to LinkMaster of parent System.
157  LinkMaster* linkMasterPtr_;
158 
159  // What this created with a copy constructor?
160  bool isCopy_;
161 
162  // Generic implementation of stress calculation
163  template <typename T>
164  void computeStressImpl(T& stress) const;
165 
166  };
167 
168 }
169 
170 #include <mcMd/simulation/System.h>
171 #include <mcMd/simulation/Simulation.h>
172 #include <mcMd/simulation/stress.h>
173 #include <mcMd/links/Link.h>
174 
175 #include <simp/species/Species.h>
176 #include <simp/boundary/Boundary.h>
177 
178 #include <util/space/Dimension.h>
179 #include <util/space/Vector.h>
180 #include <util/space/Tensor.h>
181 #include <util/accumulators/setToZero.h>
182 
183 #include <fstream>
184 
185 namespace McMd
186 {
187 
188  using namespace Util;
189  using namespace Simp;
190 
191  /*
192  * Default constructor.
193  */
194  template <class Interaction>
196  : BondPotential(),
197  SystemInterface(system),
198  interactionPtr_(0),
199  linkMasterPtr_(&system.linkMaster()),
200  isCopy_(false)
201  {
202  setClassName("LinkPotential");
203  interactionPtr_ = new Interaction();
204  }
205 
206  /*
207  * Constructor, copy from LinkPotentialImpl<Interaction>.
208  */
209  template <class Interaction>
212  : BondPotential(),
213  SystemInterface(other.system()),
214  interactionPtr_(&other.interaction()),
215  linkMasterPtr_(&other.system().linkMaster()),
216  isCopy_(true)
217  { setClassName("LinkPotential"); }
218 
219  /*
220  * Destructor.
221  */
222  template <class Interaction>
224  {}
225 
226  /*
227  * Read parameters from file.
228  */
229  template <class Interaction>
231  {
232  // Read only if not a copy. Do not indent interaction block.
233  if (!isCopy_) {
234  interaction().setNBondType(simulation().nLinkType());
235  bool nextIndent = false;
236  addParamComposite(interaction(), nextIndent);
237  interaction().readParameters(in);
238  }
239  }
240 
241  /*
242  * Return bond energy for a single pair.
243  */
244  template <class Interaction>
245  double LinkPotentialImpl<Interaction>::energy(double rsq, int iBondType)
246  const
247  { return interaction().energy(rsq, iBondType); }
248 
249  /*
250  * Return force / separation for a single bonded pair.
251  */
252  template <class Interaction>
253  double LinkPotentialImpl<Interaction>::forceOverR(double rsq, int iBondType)
254  const
255  { return interaction().forceOverR(rsq, iBondType); }
256 
257  /*
258  * Return force / separation for a single bonded pair.
259  */
260  template <class Interaction> double
262  randomBondLength(Random* random, double beta, int bondTypeId) const
263  { return interaction().randomBondLength(random, beta, bondTypeId); }
264 
265  /*
266  * Return link energy for one Atom.
267  */
268  template <class Interaction>
270  const
271  {
272  double rsq;
273  double energy = 0.0;
274  LinkMaster::AtomLinkSet* linkSetPtr;
275  Link* linkPtr;
276  int iLink, nLink;
277 
278  linkSetPtr = &linkMasterPtr_->atomLinkSet(atom);
279  nLink = linkSetPtr->size();
280  for (iLink = 0; iLink < nLink; ++iLink) {
281  linkPtr = &((*linkSetPtr)[iLink]);
282  rsq = boundary().distanceSq(linkPtr->atom0().position(),
283  linkPtr->atom1().position());
284  energy += interaction().energy(rsq, linkPtr->typeId());
285  }
286 
287  return energy;
288  }
289 
290  /*
291  * Add link forces to all atomic forces.
292  */
293  template <class Interaction>
295  {
296  Vector force;
297  double rsq;
298  Link* linkPtr;
299  Atom* atom0Ptr;
300  Atom* atom1Ptr;
301  int iLink, nLink;
302  nLink = linkMasterPtr_->nLink();
303  for (iLink = 0; iLink < nLink; ++iLink) {
304  linkPtr = &linkMasterPtr_->link(iLink);
305  atom0Ptr = &(linkPtr->atom0());
306  atom1Ptr = &(linkPtr->atom1());
307  rsq = boundary().
308  distanceSq(atom0Ptr->position(), atom1Ptr->position(), force);
309  force *= interaction().forceOverR(rsq, linkPtr->typeId());
310  atom0Ptr->force() += force;
311  atom1Ptr->force() -= force;
312  }
313  }
314 
315  /*
316  * Return total link energy.
317  */
318  template <class Interaction>
320  {
321  double rsq;
322  double energy = 0.0;
323  Link* linkPtr;
324  int iLink, nLink;
325  nLink = linkMasterPtr_->nLink();
326  for (iLink = 0; iLink < nLink; ++iLink) {
327  linkPtr = &(linkMasterPtr_->link(iLink));
328  rsq = boundary().distanceSq(linkPtr->atom0().position(),
329  linkPtr->atom1().position());
330  energy += interaction().energy(rsq, linkPtr->typeId());
331  }
332  energy_.set(energy);
333  }
334 
335  /*
336  * Compute the link pressure or stress
337  */
338  template <class Interaction>
339  template <typename T>
341  {
342  Vector dr;
343  Vector force;
344  double rsq;
345  Link* linkPtr;
346  int iLink, nLink;
347 
348  setToZero(stress);
349 
350  // Loop over links
351  nLink = linkMasterPtr_->nLink();
352  for (iLink = 0; iLink < nLink; ++iLink) {
353  linkPtr = &linkMasterPtr_->link(iLink);
354  rsq = boundary().distanceSq(linkPtr->atom0().position(),
355  linkPtr->atom1().position(), dr);
356  force = dr;
357  force *= interaction().forceOverR(rsq, linkPtr->typeId());
358  incrementPairStress(force, dr, stress);
359  }
360 
361  // Normalize by volume
362  stress /= boundary().volume();
363  normalizeStress(stress);
364  }
365 
366  /*
367  * Compute all short-range pair contributions to stress.
368  */
369  template <class Interaction>
371  {
372  Tensor stress;
373  computeStressImpl(stress);
374 
375  // Set value of Setable<double> energy_
376  stress_.set(stress);
377  }
378 
379  template <class Interaction>
381  { return *interactionPtr_; }
382 
383  template <class Interaction>
384  inline const Interaction& LinkPotentialImpl<Interaction>::interaction() const
385  { return *interactionPtr_; }
386 
387  /*
388  * Return bond interaction class name.
389  */
390  template <class Interaction>
392  { return interaction().className(); }
393 
394 }
395 #endif
int nLink() const
Get the total number of active Links.
Definition: LinkMaster.h:261
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual void addForces()
Compute and increment link forces for all atoms.
virtual void computeEnergy()
Calculate and store pair energy for this System.
An interface to a System.
virtual ~LinkPotentialImpl()
Destructor.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
virtual void readParameters(std::istream &in)
Read potential energy.
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
Interaction & interaction()
Return bond interaction by reference.
int size() const
Return logical size of this array.
Definition: SSet.h:254
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.
A Tensor represents a Cartesian tensor.
Definition: Tensor.h:32
virtual void computeStress()
Compute and store the total nonbonded pressure.
virtual std::string interactionClassName() const
Return pair interaction class name (e.g., "HarmonicBond").
virtual double forceOverR(double rsq, int bondTypeId) const
Return force / separation for a single pair.
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
Manages all Link objects in a System.
Definition: LinkMaster.h:39
virtual double randomBondLength(Random *random, double beta, int bondTypeId) const
Return force / separation for a single pair.
virtual double atomEnergy(const Atom &atom) const
Calculate the link potential energy for one Atom.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
void addParamComposite(ParamComposite &child, bool next=true)
Add a child ParamComposite object to the format array.
void setClassName(const char *className)
Set class name string.
Boundary & boundary() const
Get the Boundary by reference.
Abstract Bond Potential class.
Link & link(int id) const
Return an active link by an internal set index.
Definition: LinkMaster.h:255
Statically allocated array of pointers to an unordered set.
Definition: SSet.h:43
Random number generator.
Definition: Random.h:46
const Vector & position() const
Get the position Vector by const reference.
const AtomLinkSet & atomLinkSet(const Atom &atom) const
Return a set of links associated with an Atom by const reference.
Definition: LinkMaster.h:226
System & system() const
Get the parent System by reference.
Template implementation of an BondPotential for links.
LinkPotentialImpl(System &system)
Constructor.
double energy()
Return the energy contribution, compute if necessary.