Simpatico  v1.10
NucleationExternal.h
1 #ifndef SIMP_NUCLEATION_EXTERNAL_H
2 #define SIMP_NUCLEATION_EXTERNAL_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 <simp/boundary/Boundary.h>
12 #include <util/space/Dimension.h>
13 #include <util/space/Vector.h>
14 #include <util/param/ParamComposite.h>
15 #include <util/global.h>
16 #include <cmath>
17 
18 namespace Simp
19 {
20 
21  using namespace Util;
22 
38  {
39 
40  public:
41 
46 
51 
56 
62  void setNAtomType(int nAtomType);
63 
70 
76  void setBoundary(Boundary &boundary);
77 
86  void readParameters(std::istream &in);
87 
93  virtual void loadParameters(Serializable::IArchive &ar);
94 
100  virtual void save(Serializable::OArchive &ar);
101 
102  /*
103  * Set a potential energy parameter, identified by a string.
104  */
105  void set(std::string name, double value);
106 
107  /*
108  * Get a parameter value, identified by a string.
109  */
110  double get(std::string name) const;
111 
117  double externalParameter() const;
118 
126  double energy(const Vector& position, int i) const;
127 
135  void getForce(const Vector& position, int type, Vector& force) const;
136 
140  std::string className() const;
141 
142  private:
143 
145  static const int MaxAtomType = 3;
146 
148  DArray<double> prefactor_;
149 
151  double externalParameter_;
152 
154  int nWaveVectors_;
155 
157  DArray<Vector> waveVectors_;
158 
160  DArray<double> phases_;
161 
163  Vector shift_;
164 
166  double C_;
167 
169  int periodicity_;
170 
172  double interfaceWidth_;
173 
175  double nucleationClip_;
176 
178  double bias_;
179 
181  Boundary *boundaryPtr_;
182 
184  int nAtomType_;
185 
187  bool isInitialized_;
188 
189  };
190 
191  // inline methods
192 
193  /*
194  * Calculate external potential energy for a single atom.
195  */
196  inline double NucleationExternal::energy(const Vector& position, int type) const
197  {
198  const Vector cellLengths = boundaryPtr_->lengths();
199  double clipParameter = 1.0/(2.0*M_PI*periodicity_*interfaceWidth_);
200  double e;
201 
202  Vector r = position;
203  r -= shift_;
204  double cosine = 0.0;
205  for (int i = 0; i < nWaveVectors_; ++i) {
206  Vector q;
207  q[0] = 2.0*M_PI*periodicity_*waveVectors_[i][0]/cellLengths[0];
208  q[1] = 2.0*M_PI*periodicity_*waveVectors_[i][1]/cellLengths[1];
209  q[2] = 2.0*M_PI*periodicity_*waveVectors_[i][2]/cellLengths[2];
210  double arg = q.dot(r)+phases_[i];
211  cosine += cos(arg);
212  }
213 
214  cosine *= clipParameter;
215  e = prefactor_[type]*externalParameter_*tanh(C_+cosine) *
216  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_))))+1)/2 *
217  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_))))+1)/2 *
218  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_))))+1)/2 ;
219 
220  return e;
221  }
222 
223  /*
224  * Calculate external force for a single atom.
225  */
226  inline
227  void NucleationExternal::getForce(const Vector& position, int type,
228  Vector& force) const
229  {
230  const Vector cellLengths = boundaryPtr_->lengths();
231  double clipParameter = 1.0/(2.0*M_PI*periodicity_*interfaceWidth_);
232  double ne;
233 
234  ne =
235  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_))))+1)/2 *
236  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_))))+1)/2 *
237  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_))))+1)/2 ;
238 
239  Vector r = position;
240  r -= shift_;
241  double cosine = 0.0;
242  Vector deriv;
243  deriv.zero();
244  for (int i = 0; i < nWaveVectors_; ++i) {
245  Vector q;
246  q[0] = 2.0*M_PI*periodicity_*waveVectors_[i][0]/cellLengths[0];
247  q[1] = 2.0*M_PI*periodicity_*waveVectors_[i][1]/cellLengths[1];
248  q[2] = 2.0*M_PI*periodicity_*waveVectors_[i][2]/cellLengths[2];
249  double arg = q.dot(r)+phases_[i];
250  cosine += cos(arg);
251  double sine = -1.0*sin(arg);
252  q *= sine;
253  deriv += q;
254  }
255  cosine *= clipParameter;
256 
257  deriv *= clipParameter;
258  double tanH = tanh(C_+cosine);
259  double sechSq = (1.0 - tanH*tanH);
260  double f = prefactor_[type]*externalParameter_*sechSq;
261  deriv *= -1.0*f;
262  deriv *= ne;
263  deriv[0] = deriv[0] + nucleationClip_*(M_PI/cellLengths[0]*sin(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_)))/
264  cosh(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_))/
265  cosh(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_))*
266  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_))))+1)/2*
267  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_))))+1)/2;
268 
269  deriv[1] = deriv[1] + nucleationClip_*(M_PI/cellLengths[1]*sin(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_)))/
270  cosh(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_))/
271  cosh(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_))*
272  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_))))+1)/2*
273  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_))))+1)/2;
274 
275  deriv[2] = deriv[2] + nucleationClip_*(M_PI/cellLengths[2]*sin(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_)))/
276  cosh(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_))/
277  cosh(2.0*M_PI*position[2]/cellLengths[2]+acos(bias_))*
278  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[0]/cellLengths[0]+acos(bias_))))+1)/2*
279  (tanh(nucleationClip_*(-bias_+cos(2.0*M_PI*position[1]/cellLengths[1]+acos(bias_))))+1)/2;
280  force = deriv;
281  }
282 
283 }
284 #endif
Vector & zero()
Set all elements of a 3D vector to zero.
Definition: Vector.h:514
A Vector is a Cartesian vector.
Definition: Vector.h:75
double dot(const Vector &v) const
Return dot product of this vector and vector v.
Definition: Vector.h:632
void setNAtomType(int nAtomType)
Set nAtomType value.
An orthorhombic periodic unit cell.
NucleationExternal & operator=(const NucleationExternal &other)
Assignment.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
Saving / output archive for binary ostream.
void getForce(const Vector &position, int type, Vector &force) const
Returns force caused by the external potential.
std::string className() const
Return name string "NucleationExternal".
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
void setExternalParameter(double externalParameter)
Sets external parameter.
double energy(const Vector &position, int i) const
Returns external potential energy of a single particle.
Utility classes for scientific computation.
Definition: accumulators.mod:1
double externalParameter() const
Returns external parameter.
NucleationExternal()
Default constructor.
void readParameters(std::istream &in)
Read potential parameters, and initialize other variables.
Saving archive for binary istream.
An object that can read multiple parameters from file.
void setBoundary(Boundary &boundary)
Set pointer to Boundary.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
A clipped cosine potential that induces ordering along directions specified by waveIntVectors, w_i.