Simpatico  v1.10
McPairExternalPerturbation.h
1 #ifdef MCMD_PERTURB
2 #ifdef SIMP_EXTERNAL
3 #ifndef SIMP_NOPAIR
4 #ifndef MCMD_MC_PAIR_EXTERNAL_PERTURBATION_H
5 #define MCMD_MC_PAIR_EXTERNAL_PERTURBATION_H
6 
7 
8 /*
9 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
10 *
11 * Copyright 2010 - 2017, The Regents of the University of Minnesota
12 * Distributed under the terms of the GNU General Public License.
13 */
14 
15 #include <mcMd/perturb/LinearPerturbation.h> // base class
16 #include <mcMd/neighbor/CellList.h> // member
17 #include <mcMd/simulation/Simulation.h>
18 #include <mcMd/mcSimulation/McSystem.h>
19 #include <mcMd/potentials/pair/McPairPotentialImpl.h>
20 #include <mcMd/potentials/external/ExternalPotentialImpl.h>
21 #include <mcMd/chemistry/Atom.h>
22 #include <simp/ensembles/EnergyEnsemble.h>
23 #include <util/containers/DMatrix.h> // member template
24 #include <util/containers/DArray.h> // member template
25 #include <util/containers/Pair.h> // template parameter
26 #include <util/global.h>
27 
28 namespace McMd
29 {
30 
31  class McSystem;
32 
33  using namespace Util;
34  using namespace Simp;
35 
48  template < class PairInteraction, class ExternalInteraction >
50  {
51 
52  public:
53 
61  McPairExternalPerturbation(McSystem& system, int size, int rank);
62 
66  virtual ~McPairExternalPerturbation();
67 
73  virtual void readParameters(std::istream& in);
74 
79  virtual void setParameter();
80 
87  virtual double parameter(int i) const;
88 
93  virtual double derivative(int i) const;
94 
95  PairInteraction& pairInteraction() const;
96 
97  ExternalInteraction& externalInteraction() const;
98 
99  private:
100 
102  mutable CellList::NeighborArray neighbors_;
103 
105  mutable PairInteraction* pairInteractionPtr_;
106 
108  mutable ExternalInteraction* externalInteractionPtr_;
109 
110  /*
111  Number of perturbation parameters associated with a System.
112  nParameters = 2 for McPairExternalPerturbation.
113  */
114  int nParameters_;
115 
116  };
117 
119 
120  /*
121  * Constructor.
122  */
123  template < class PairInteraction, class ExternalInteraction >
125  : LinearPerturbation<McSystem>(system, size, rank),
126  pairInteractionPtr_(0),
127  externalInteractionPtr_(0)
128  { setClassName("McPairExternalPerturbation"); }
129 
130  /*
131  * Destructor.
132  */
133  template < class PairInteraction, class ExternalInteraction >
134  McPairExternalPerturbation<PairInteraction, ExternalInteraction>::~McPairExternalPerturbation<PairInteraction, ExternalInteraction>()
135  {}
136 
137  /*
138  * Read epsilon(0,1) and external parameter from file
139  */
140  template < class PairInteraction, class ExternalInteraction >
142  {
144  nParameters_ = Perturbation::getNParameters();
145  }
146 
147  /*
148  */
149  template < class PairInteraction, class ExternalInteraction >
151  {
152  if (pairInteractionPtr_ == 0) {
153  McPairPotential* pairPtr = &(system().pairPotential());
155  implPtr = dynamic_cast< McPairPotentialImpl< PairInteraction >* >(pairPtr);
156  if (implPtr == 0) {
157  UTIL_THROW("Failed dynamic cast of McPairPotential");
158  }
159  pairInteractionPtr_ = &implPtr->interaction();
160  }
161  return *pairInteractionPtr_;
162  }
163 
164  /*
165  */
166  template < class PairInteraction, class ExternalInteraction >
168  {
169  if (externalInteractionPtr_ == 0) {
170  ExternalPotential* externalPtr = &(system().externalPotential());
172  implPtr = dynamic_cast< ExternalPotentialImpl< ExternalInteraction >* >(externalPtr);
173  if (implPtr == 0) {
174  UTIL_THROW("Failed dynamic cast of ExternalPotential");
175  }
176  externalInteractionPtr_ = &implPtr->interaction();
177  }
178  return *externalInteractionPtr_;
179  }
180 
181 
182  /*
183  * Set the parameter epsilon(0,1) and external parameter for this McSystem.
184  */
185  template < class PairInteraction, class ExternalInteraction >
187  {
188  pairInteraction().setEpsilon(0, 1, parameter_[0]);
189  externalInteraction().setExternalParameter(parameter_[1]);
190  }
191 
192  /*
193  * i = 0: Get the epsilon(0,1) from the parent System.
194  * i = 1: Get the externalParameter from the parent System.
195  */
196  template < class PairInteraction, class ExternalInteraction >
198  {
199  if (i >= nParameters_) {
200  UTIL_THROW("perturbation parameter index is out of bounds");
201  }
202  double param = 0.0;
203  if (i == 0) {
204  param = pairInteraction().epsilon(0, 1);
205  } else if (i == 1) {
206  param = externalInteraction().externalParameter();
207  }
208  return param;
209  }
210 
211  /*
212  * i = 0: Returns pair energy for unlike pairs / (kT*epsilon(0,1))
213  * i = 1: Returns external potential energy / ( kT *external parameter )
214  */
215  template < class PairInteraction, class ExternalInteraction >
217  {
218  // Preconditions
219  if (i >= nParameters_) {
220  UTIL_THROW("perturbation parameter index is out of bounds");
221  }
222  double deriv = 0.0;
223  if ( i == 0 ) {
224  if (fabs(parameter_[i] - parameter(i)) > 1.0E-8) {
225  UTIL_THROW("Pair perturbation parameter is not set correctly");
226  }
227  double pairEnergy, rsq;
228  Atom *jAtomPtr, *kAtomPtr;
229  int nNeighbor, nInCell;
230  int ic, nc, j, k, jId, kId, jType, kType;
231  // Loop over cells
232  pairEnergy = 0.0;
233  nc = system().pairPotential().cellList().totCells();
234  for (ic = 0; ic < nc; ++ic) {
235 
236  // Get array of neighbors_
237  system().pairPotential().cellList().getCellNeighbors(ic, neighbors_, nInCell);
238  nNeighbor = neighbors_.size();
239 
240  // Loop over primary atoms in this cell
241  for (j = 0; j < nInCell; ++j) {
242  jAtomPtr = neighbors_[j];
243  jId = jAtomPtr->id();
244  jType = jAtomPtr->typeId();
245 
246  // Loop over secondary atoms in this and neighboring cells
247  for (k = 0; k < nNeighbor; ++k) {
248  kAtomPtr = neighbors_[k];
249  kId = kAtomPtr->id();
250  kType = kAtomPtr->typeId();
251 
252  // Count each pair only once
253  if (kId > jId && jType != kType) {
254 
255  // Exclude masked pairs
256  if (!jAtomPtr->mask().isMasked(*kAtomPtr)) {
257 
258  rsq = system().boundary().
259  distanceSq(jAtomPtr->position(), kAtomPtr->position());
260  pairEnergy += pairInteraction().
261  energy(rsq, jAtomPtr->typeId(), kAtomPtr->typeId());
262 
263  }
264 
265  }
266 
267  } // secondary atoms
268 
269  } // primary atoms
270 
271  } // cells
272 
273  // Multiply by the temperature factor.
274  if (system().energyEnsemble().isIsothermal()) {
275  pairEnergy *= system().energyEnsemble().beta();
276  } else {
277  UTIL_THROW("Non isothermal ensemble for McPairPerturbation.");
278  }
279 
280  deriv = pairEnergy/parameter_[i];
281  } else if ( i == 1 ) {
282  if (fabs(parameter_[i] - parameter(i)) > 1.0E-8) {
283  UTIL_THROW("External perturbation parameter is not set correctly");
284  }
285  double externalEnergy;
286  System::MoleculeIterator molIter;
287  Molecule::AtomIterator atomIter;
288 
289  externalEnergy = 0.0;
290 
291  for (int iSpec=0; iSpec < system().simulation().nSpecies(); ++iSpec){
292  for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter){
293  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
294  externalEnergy += system().externalPotential().energy(atomIter->position(), atomIter->typeId());
295  }
296  }
297  }
298 
299  // Multiply by the temperature factor.
300  if (system().energyEnsemble().isIsothermal()) {
301  externalEnergy *= system().energyEnsemble().beta();
302  } else {
303  UTIL_THROW("Non isothermal ensemble");
304  }
305 
306  deriv = -1.0*(externalEnergy/parameter_[i]);
307 
308  }
309  return deriv;
310 
311  }
312 
313 }
314 
315 #endif
316 #endif // #ifndef SIMP_NOPAIR
317 #endif // #ifdef SIMP_EXTERNAL
318 #endif // ifdef MCMD_PERTURB
DArray< double > parameter_
Value of the perturbation parameter for the associated System.
Definition: Perturbation.h:172
A System for use in a Markov chain Monte Carlo simulation.
Definition: McSystem.h:52
void begin(int speciesId, MoleculeIterator &iterator)
Initialize an iterator for molecules of one species in this System.
Definition: System.h:1147
bool notEnd() const
Is the current pointer not at the end of the array?
Definition: ArrayIterator.h:83
const CellList & cellList() const
Get the cellList by const reference.
A Perturbation that is a linear function of a parameter.
A PairPotential for MC simulations (abstract).
EnergyEnsemble & energyEnsemble() const
Get the EnergyEnsemble by reference.
Definition: System.h:1095
Mask & mask()
Get the associated Mask by reference.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
virtual double energy(const Vector &position, int i) const =0
Returns external potential energy of a single particle.
bool isMasked(const Atom &atom) const
True if the atom is in the masked set for the target Atom.
double beta() const
Return the inverse temperature.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Simulation & simulation() const
Get the parent Simulation by reference.
Definition: System.h:1055
Implementation template for an McPairPotential.
Abstract External Potential class.
int typeId() const
Get type index for this Atom.
void getCellNeighbors(int ic, NeighborArray &neighbors, int &nInCell) const
Fill an array with pointers to atoms in a cell and neighboring cells.
ExternalPotential & externalPotential() const
Return ExternalPotential by reference.
Definition: McSystem.h:473
bool isIsothermal() const
Is this an Isothermal ensemble?
Interaction & interaction()
Return external interaction 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
int getNParameters() const
Gets the number of parameters per system.
int id() const
Get global index for this Atom within the Simulation.
Interaction & interaction()
Return reference to underlying pair interaction.
A Perturbation in the pair interaction epsilon(0,1) for any pair potential supporting setEpsilon() an...
int totCells() const
Get total number of cells in this CellList.
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
McSystem & system() const
Get the associated System by reference.
Forward iterator for a PArray.
Definition: ArraySet.h:19
virtual double parameter(int i) const
Return the perturbation parameter for this System.
virtual double derivative(int i) const
Return (0-1 pair energy) / ( kT *epsilon(0,1) ) if i is 0 or (external potential energy)/ ( kT *exter...
McPairPotential & pairPotential() const
Return the McPairPotential by reference.
Definition: McSystem.h:388
Boundary & boundary() const
Get the Boundary by reference.
Definition: System.h:1064
Template implementation of ExternalPotential.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
virtual void setParameter()
Set pair interaction parameter epsilon(0,1) and external parameter for this System.
int nSpecies() const
Get the number of Species in this Simulation.
void setClassName(const char *className)
Set class name string.
const Vector & position() const
Get the position Vector by const reference.
virtual void readParameters(std::istream &in)
Read parameter epsilon(0, 1) and external parameter from file.
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
McPairExternalPerturbation(McSystem &system, int size, int rank)
Constructor.
void readParameters(std::istream &in)
Read perturbation parameter(s) from file.