Simpatico  v1.10
ddMd/potentials/external/ExternalPotentialImpl.h
1 #ifndef DDMD_EXTERNAL_POTENTIAL_IMPL_H
2 #define DDMD_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 <ddMd/potentials/external/ExternalPotential.h>
12 #include <util/global.h>
13 
14 namespace Util {
15  class Vector;
16  class Tensor;
17 }
18 
19 namespace DdMd
20 {
21 
22  using namespace Util;
23 
24  class Simulation;
25  class AtomStorage;
26 
32  template <class Interaction>
34  {
35 
36  public:
37 
41  ExternalPotentialImpl(Simulation& simulation);
42 
47 
51  virtual ~ExternalPotentialImpl();
52 
61  virtual void associate(Boundary& boundary, AtomStorage& storage);
62 
70  virtual void setNAtomType(int nAtomType);
71 
77  virtual void readParameters(std::istream& in);
78 
84  virtual void loadParameters(Serializable::IArchive &ar);
85 
93  virtual void save(Serializable::OArchive &ar);
94 
96 
97 
105  virtual double externalEnergy(const Vector& position, int typeId) const;
106 
114  virtual void getExternalForce(const Vector& position, int typeId,
115  Vector& force) const;
116 
123  void set(std::string name, double value)
124  { interactionPtr_->set(name, value); }
125 
131  double get(std::string name) const
132  { return interactionPtr_->get(name); }
133 
137  virtual std::string interactionClassName() const;
138 
142  Interaction& interaction();
143 
147  const Interaction& interaction() const;
148 
150 
152 
156  virtual void computeForces();
157 
163  #ifdef UTIL_MPI
164  virtual void computeEnergy(MPI::Intracomm& communicator);
165  #else
166  virtual void computeEnergy();
167  #endif
168 
170 
171  private:
172 
176  Interaction* interactionPtr_;
177 
181  bool isInitialized_;
182 
186  double computeForces(bool needForce, bool needEnergy);
187 
188  };
189 
190 }
191 
192 #include <ddMd/simulation/Simulation.h>
193 #include <ddMd/storage/AtomStorage.h>
194 #include <ddMd/storage/AtomIterator.h>
195 
196 #include <util/space/Dimension.h>
197 #include <util/space/Vector.h>
198 #include <util/global.h>
199 
200 #include <fstream>
201 
202 namespace DdMd
203 {
204 
205  using namespace Util;
206 
207  /*
208  * Constructor.
209  */
210  template <class Interaction>
212  : ExternalPotential(simulation),
213  interactionPtr_(0),
214  isInitialized_(false)
215  {
216  interactionPtr_ = new Interaction;
217  interaction().setBoundary(simulation.boundary());
218  setNAtomType(simulation.nAtomType());
219  }
220 
221  /*
222  * Default constructor.
223  */
224  template <class Interaction>
226  : ExternalPotential(),
227  interactionPtr_(0),
228  isInitialized_(false)
229  { interactionPtr_ = new Interaction; }
230 
231  /*
232  * Destructor.
233  */
234  template <class Interaction>
236  {
237  if (interactionPtr_) {
238  delete interactionPtr_;
239  }
240  }
241 
242  /*
243  * Associate with related objects. (for unit testing).
244  *
245  * Required iff instantiated with default constructor.
246  */
247  template <class Interaction>
250  {
251  ExternalPotential::associate(boundary, storage);
252  interaction().setBoundary(boundary);
253  }
254 
258  template <class Interaction>
260  { interaction().setNAtomType(nAtomType); }
261 
262  /*
263  * Read parameters from file.
264  */
265  template <class Interaction>
267  {
268  UTIL_CHECK(!isInitialized_);
269  bool nextIndent = false; // Do not indent interaction block
270  addParamComposite(interaction(), nextIndent);
271  interaction().readParameters(in);
272  isInitialized_ = true;
273  }
274 
275  /*
276  * Load internal state from an archive.
277  */
278  template <class Interaction>
280  {
281  UTIL_CHECK(!isInitialized_);
282  bool nextIndent = false; // Do not indent interaction block
283  addParamComposite(interaction(), nextIndent);
284  interaction().loadParameters(ar);
285  isInitialized_ = true;
286  }
287 
288  /*
289  * Save internal state to an archive (call only on master processor).
290  */
291  template <class Interaction>
293  { interaction().save(ar); }
294 
295  /*
296  * Return external energy of an atom.
297  */
298  template <class Interaction>
299  double
301  int typeId) const
302  { return interaction().energy(position, typeId); }
303 
304  /*
305  * Return external force on an atom.
306  */
307  template <class Interaction>
308  void
310  int typeId, Vector& force) const
311  { interaction().getForce(position, typeId, force); }
312 
313  /*
314  * Return external interaction class name.
315  */
316  template <class Interaction>
318  { return interaction().className(); }
319 
323  template <class Interaction>
325  {
326  assert(interactionPtr_);
327  return *interactionPtr_;
328  }
329 
333  template <class Interaction>
335  {
336  assert(interactionPtr_);
337  return *interactionPtr_;
338  }
339 
340  /*
341  * Increment atomic forces, without calculating energy.
342  */
343  template <class Interaction>
345  { computeForces(true, false); }
346 
347  /*
348  * Compute total external energy on all processors.
349  */
350  template <class Interaction>
351  #ifdef UTIL_MPI
352  void
354  #else
356  #endif
357  {
358  double localEnergy = 0;
359  localEnergy = computeForces(false, true);
360  #ifdef UTIL_MPI
361  reduceEnergy(localEnergy, communicator);
362  #else
363  setEnergy(localEnergy);
364  #endif
365  }
366 
367  /*
368  * Increment atomic forces and/or external energy (private).
369  */
370  template <class Interaction>
371  double
372  ExternalPotentialImpl<Interaction>::computeForces(bool needForce, bool needEnergy)
373  {
374  Vector f;
375  double energy = 0.0;
376  AtomIterator iter;
377  int type;
378 
379  storage().begin(iter);
380  for ( ; iter.notEnd(); ++iter) {
381  type = iter->typeId();
382  if (needEnergy) {
383  energy +=
384  interactionPtr_->energy(iter->position(), type);
385  }
386  if (needForce) {
387  interactionPtr_->getForce(iter->position(), type, f);
388  iter->force() += f;
389  }
390  }
391  return energy;
392  }
393 
394 }
395 #endif
A Vector is a Cartesian vector.
Definition: Vector.h:75
Boundary & boundary()
Get the Boundary by reference.
Implementation template for a ExternalPotential.
Interaction & interaction()
Return external interaction by reference.
An orthorhombic periodic unit cell.
Calculates external forces and energies for a parent Simulation.
virtual void getExternalForce(const Vector &position, int typeId, Vector &force) const
Computes external force on one atom.
File containing preprocessor macros for error handling.
virtual double externalEnergy(const Vector &position, int typeId) const
Returns external potential energy of a single atom.
Parallel domain decomposition (DD) MD simulation.
Main object for a domain-decomposition MD simulation.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from archive and initialize, for restart.
Saving / output archive for binary ostream.
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 save(Serializable::OArchive &ar)
Save internal state to an archive, for restart.
A container for all the atoms and ghost atoms on this processor.
double energy() const
Return the total potential, from all processors.
Definition: Potential.cpp:39
Saving archive for binary istream.
virtual void setNAtomType(int nAtomType)
Set the maximum number of atom types.
void addParamComposite(ParamComposite &child, bool next=true)
Add a child ParamComposite object to the format array.
AtomStorage & storage()
Get the AtomStorage by reference.
void reduceEnergy(double localEnergy, MPI::Intracomm &communicator)
Add local energies from all processors, set energy on master.
Definition: Potential.cpp:120
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
int nAtomType()
Get maximum number of atom types.
virtual void associate(Boundary &boundary, AtomStorage &storage)
Associate with related objects.
ExternalPotentialImpl()
Default constructor (for unit testing).
Boundary & boundary()
Get the Boundary by reference.
virtual void computeForces()
Calculate external forces for all atoms in this Simulation.
Iterator for all atoms owned by an AtomStorage.
Definition: AtomIterator.h:24
void setEnergy(double energy)
Set a value for the total energy.
Definition: Potential.cpp:45
virtual std::string interactionClassName() const
Return external interaction class name (e.g., "LamellarOrderingExternal").
void begin(AtomIterator &iterator)
Set iterator to beginning of the set of atoms.
virtual void readParameters(std::istream &in)
Read external potential interaction.
virtual void computeEnergy(MPI::Intracomm &communicator)
Compute the total external energy for all processors.