Simpatico  v1.10
mcMd/potentials/external/ExternalPotentialImpl.h
1 #ifndef MCMD_EXTERNAL_POTENTIAL_IMPL_H
2 #define MCMD_EXTERNAL_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/external/ExternalPotential.h> // base class
12 #include <mcMd/simulation/SystemInterface.h> // base class
13 #include <util/global.h>
14 
15 namespace Util
16 {
17  class Vector;
18  class Tensor;
19 }
20 
21 namespace McMd
22 {
23 
24  class System;
25 
26  using namespace Util;
27  using namespace Simp;
28 
34  template <class Interaction>
36  private SystemInterface
37  {
38 
39  public:
40 
45 
50 
54  virtual ~ExternalPotentialImpl();
55 
63  virtual void readParameters(std::istream& in);
64 
70  virtual void loadParameters(Serializable::IArchive &ar);
71 
77  virtual void save(Serializable::OArchive &ar);
78 
80 
81 
89  virtual double energy(const Vector& position, int typeId) const;
90 
98  virtual void getForce(const Vector& position, int typeId, Vector& force) const;
99 
103  virtual std::string interactionClassName() const;
104 
106 
108 
112  void addForces();
113 
117  void computeEnergy();
118 
124  double atomEnergy(const Atom& atom) const;
125 
127 
131  Interaction& interaction();
132 
136  const Interaction& interaction() const;
137 
138  private:
139 
140  Interaction* interactionPtr_;
141 
142  bool isCopy_;
143 
144  template <typename T>
145  void computeStressImpl(T& stress) const;
146 
147  };
148 
149 }
150 
151 #include <mcMd/simulation/System.h>
152 #include <mcMd/simulation/Simulation.h>
153 
154 #include <simp/species/Species.h>
155 #include <simp/boundary/Boundary.h>
156 
157 #include <util/space/Dimension.h>
158 #include <util/space/Vector.h>
159 
160 #include <fstream>
161 
162 namespace McMd
163 {
164 
165  using namespace Util;
166  using namespace Simp;
167 
168  /*
169  * Default constructor.
170  */
171  template <class Interaction>
173  : ExternalPotential(),
174  SystemInterface(system),
175  interactionPtr_(0),
176  isCopy_(false)
177  { interactionPtr_ = new Interaction(); }
178 
179  /*
180  * Constructor, copy from ExternalPotentialImpl<Interaction>.
181  */
182  template <class Interaction>
185  : ExternalPotential(),
186  SystemInterface(other.system()),
187  interactionPtr_(&other.interaction()),
188  isCopy_(true)
189  {}
190 
191  /*
192  * Destructor.
193  */
194  template <class Interaction>
196  {}
197 
198  /*
199  * Read parameters from file.
200  */
201  template <class Interaction>
203  {
204  // Read only if not a copy. Do not indent interaction block.
205  if (!isCopy_) {
206  interaction().setNAtomType(simulation().nAtomType());
207  interaction().setBoundary(system().boundary());
208  bool nextIndent = false;
209  addParamComposite(interaction(), nextIndent);
210  interaction().readParameters(in);
211  }
212  }
213 
214  /*
215  * Load internal state from an archive.
216  */
217  template <class Interaction>
218  void
220  {
221  ar >> isCopy_;
222  if (!isCopy_) {
223  interaction().setNAtomType(simulation().nAtomType());
224  bool nextIndent = false;
225  addParamComposite(interaction(), nextIndent);
226  interaction().loadParameters(ar);
227  }
228  }
229 
230  /*
231  * Save internal state to an archive.
232  */
233  template <class Interaction>
235  {
236  ar << isCopy_;
237  if (!isCopy_) {
238  interaction().save(ar);
239  }
240  }
241 
242  /*
243  * Return external energy of an atom.
244  */
245  template <class Interaction>
246  double
248  const
249  { return interaction().energy(position, typeId); }
250 
251  /*
252  * Return external force on an atom.
253  */
254  template <class Interaction>
256  int typeId, Vector& force) const
257  { interaction().getForce(position, typeId, force); }
258 
259  /*
260  * Add external forces to total forces on each atom.
261  */
262  template <class Interaction>
264  {
265  Vector force;
266  System::MoleculeIterator molIter;
267  Molecule::AtomIterator atomIter;
268  for (int iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
269  for (begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
270  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
271  interaction().getForce(atomIter->position(),
272  atomIter->typeId(), force);
273  atomIter->force() += force;
274  }
275  }
276  }
277  }
278 
279  /*
280  * Return total external potential energy.
281  */
282  template <class Interaction>
284  {
287  double energy = 0.0;
288  for (int iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
289  for (begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
290  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
291  energy += interaction().energy(atomIter->position(),
292  atomIter->typeId());
293  }
294  }
295  }
296  energy_.set(energy);
297  //return energy;
298  }
299 
300  /*
301  * Compute and return external potential for one atom.
302  */
303  template <class Interaction>
305  {
306  return interaction().energy(atom.position(), atom.typeId());
307  }
308 
309  template <class Interaction>
311  { return *interactionPtr_; }
312 
313  template <class Interaction>
314  inline const Interaction& ExternalPotentialImpl<Interaction>::interaction() const
315  { return *interactionPtr_; }
316 
317  /*
318  * Return external interaction class name.
319  */
320  template <class Interaction>
322  { return interaction().className(); }
323 
324 }
325 #endif
A Vector is a Cartesian vector.
Definition: Vector.h:75
An interface to a System.
bool notEnd() const
Is the current pointer not at the end of the array?
Definition: ArrayIterator.h:83
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
void set(const T &value)
Set the value and mark as set.
Definition: Setable.h:107
A set of interacting Molecules enclosed by a Boundary.
Definition: System.h:115
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Forward iterator for a PArray.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
virtual void getForce(const Vector &position, int typeId, Vector &force) const
Returns force caused by the external potential.
Forward const iterator for an Array or a C array.
virtual std::string interactionClassName() const
Return external interaction class name (e.g., "LamellarOrderingExternal").
Saving / output archive for binary ostream.
double atomEnergy(const Atom &atom) const
Calculate the external energy for one Atom.
Abstract External Potential class.
int typeId() const
Get type index for this Atom.
Interaction & interaction()
Return external interaction by reference.
Simulation & simulation() const
Get the parent Simulation by reference.
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 void readParameters(std::istream &in)
Read param for external potential.
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
Forward iterator for a PArray.
Definition: ArraySet.h:19
void addForces()
Add external force of an Atom to the total force acting on it.
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.
Saving archive for binary istream.
Template implementation of ExternalPotential.
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.
Boundary & boundary() const
Get the Boundary by reference.
const Vector & position() const
Get the position Vector by const reference.
bool notEnd() const
Is this not the end of the array?
System & system() const
Get the parent System by reference.
void computeEnergy()
Compute and store total external energy of this System.
double energy()
Return the energy contribution, compute if necessary.