Simpatico  v1.10
LocalLamellarOrderingExternal.h
1 #ifndef SIMP_LOCAL_LAMELLAR_ORDERING_EXTERNAL_H
2 #define SIMP_LOCAL_LAMELLAR_ORDERING_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/param/ParamComposite.h>
14 #include <util/global.h>
15 #include <cmath>
16 
17 namespace Simp
18 {
19 
20  using namespace Util;
21 
49  {
50 
51  public:
52 
57 
62 
67 
73  void setNAtomType(int nAtomType);
74 
81 
87  void setBoundary(Boundary &boundary);
88 
97  void readParameters(std::istream &in);
98 
104  virtual void loadParameters(Serializable::IArchive &ar);
105 
111  virtual void save(Serializable::OArchive &ar);
112 
113  /*
114  * Set a potential energy parameter, identified by a string.
115  */
116  void set(std::string name, double value);
117 
118  /*
119  * Get a parameter value, identified by a string.
120  */
121  double get(std::string name) const;
122 
128  double externalParameter() const;
129 
137  double energy(const Vector& position, int i) const;
138 
146  void getForce(const Vector& position, int type, Vector& force) const;
147 
151  std::string className() const;
152 
153  private:
154 
156  static const int MaxAtomType = 2;
157 
159  int perpDirection_;
160 
162  int parallelDirection_;
163 
165  double fraction_;
166 
168  double width_;
169 
171  DArray<double> prefactor_;
172 
174  double externalParameter_;
175 
177  int periodicity_;
178 
180  Boundary *boundaryPtr_;
181 
183  int nAtomType_;
184 
186  bool isInitialized_;
187 
188  };
189 
190  // inline methods
191 
192  /*
193  inline double LocalLamellarOrderingExternal::energy(double dPerp, double dParallel, int type) const
194  {
195  double perpLength, parallelLength, q, clipParameter, arg, clipcos, parallelFactor;
196  Vector lengths;
197  lengths = boundaryPtr_->lengths();
198  perpLength = lengths[perpDirection_];
199  q = (2.0*M_PI*periodicity_)/perpLength;
200  clipParameter = 1.0/(q*width_*perpLength);
201  arg = q*dPerp;
202  clipcos = clipParameter*cos(arg);
203  parallelLength = lengths[parallelDirection_];
204  parallelFactor = tanh( 2.0*M_PI*((dParallel - (((1.0-fraction_)/2.0)*parallelLength))/(fraction_*parallelLength)) );
205  parallelFactor *= tanh( 2.0*M_PI*(((((1.0+fraction_)/2.0)*parallelLength) - dParallel)/(fraction_*parallelLength)) );
206  parallelFactor += 1.0;
207  parallelFactor /= 2.0;
208  if (parallelFactor < 0.0)
209  UTIL_THROW("Negative base factor");
210  return prefactor_[type]*externalParameter_*tanh(clipcos)*parallelFactor;
211  }
212  */
213 
214  /*
215  * Calculate external potential energy for a single atom.
216  */
217  inline
218  double LocalLamellarOrderingExternal::energy(const Vector& position, int type) const
219  {
220  double dPerp, dParallel, perpLength, parallelLength, q, clipParameter, arg, clipcos;
221  double parallelFactor1, parallelFactor2, parallelFactor;
222  dPerp = position[perpDirection_];
223  dParallel = position[parallelDirection_];
224 
225  Vector lengths;
226  lengths = boundaryPtr_->lengths();
227  perpLength = lengths[perpDirection_];
228  parallelLength = lengths[parallelDirection_];
229 
230  q = (2.0*M_PI*periodicity_)/perpLength;
231  clipParameter = 1.0/(q*width_*perpLength);
232  arg = q*dPerp;
233  clipcos = clipParameter*cos(arg);
234  parallelFactor1 = tanh( 2.0*M_PI*((dParallel - (((1.0-fraction_)/2.0)*parallelLength))/(fraction_*parallelLength)) );
235  parallelFactor2 = tanh( 2.0*M_PI*(((((1+fraction_)/2.0)*parallelLength) - dParallel)/(fraction_*parallelLength)) );
236  parallelFactor = 1.0 + (parallelFactor1*parallelFactor2);
237  parallelFactor /= 2.0;
238 
239  if (parallelFactor < 0.0)
240  UTIL_THROW("Negative base factor");
241 
242  return prefactor_[type]*externalParameter_*tanh(clipcos)*parallelFactor;
243  }
244 
245  /*
246  * Calculate external force for a single atom.
247  */
248  inline
249  void LocalLamellarOrderingExternal::getForce(const Vector& position, int type,
250  Vector& force) const
251  {
252  double dPerp, dParallel, perpLength, parallelLength, q, clipParameter, arg, clipcos, tanH, sechSq;
253  double parallelFactor1, parallelFactor2, parallelFactor, forceParallelSech1, forceParallelSech2;
254  dPerp = position[perpDirection_];
255  dParallel = position[parallelDirection_];
256  force.zero();
257 
258  Vector lengths;
259  lengths = boundaryPtr_->lengths();
260  perpLength = lengths[perpDirection_];
261  parallelLength = lengths[parallelDirection_];
262 
263  q = (2.0*M_PI*periodicity_)/perpLength;
264  clipParameter = 1.0/(q*width_*perpLength);
265  arg = q*dPerp;
266  clipcos = clipParameter*cos(arg);
267  tanH = tanh(clipcos);
268  sechSq = (1.0 - tanH*tanH);
269  parallelFactor1 = tanh( 2.0*M_PI*((dParallel - (((1.0-fraction_)/2.0)*parallelLength))/(fraction_*parallelLength)) );
270  parallelFactor2 = tanh( 2.0*M_PI*(((((1+fraction_)/2.0)*parallelLength) - dParallel)/(fraction_*parallelLength)) );
271  parallelFactor = 1.0 + (parallelFactor1*parallelFactor2);
272  parallelFactor /= 2.0;
273 
274  if (parallelFactor < 0.0) {
275  UTIL_THROW("Negative base factor");
276  } else {
277  forceParallelSech1 = (1.0 - (parallelFactor1*parallelFactor1));
278  forceParallelSech1 *= 1.0*M_PI*(1/(fraction_*parallelLength))*parallelFactor2;
279  forceParallelSech2 = (1.0 - (parallelFactor2*parallelFactor2));
280  forceParallelSech2 *= -1.0*M_PI*(1/(fraction_*parallelLength))*parallelFactor1;
281  force[parallelDirection_] = -1.0*prefactor_[type]*externalParameter_*tanh(clipcos);
282  force[parallelDirection_] *= (forceParallelSech1 + forceParallelSech2);
283  force[perpDirection_] = prefactor_[type]*externalParameter_*sechSq*clipParameter*sin(arg)*q*parallelFactor;
284  }
285 
286  }
287 
288 }
289 #endif
void readParameters(std::istream &in)
Read potential parameters, and initialize other variables.
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
std::string className() const
Return name string "LocalLamellarOrderingExternal".
void setBoundary(Boundary &boundary)
Set pointer to Boundary.
An orthorhombic periodic unit cell.
double energy(const Vector &position, int i) const
Returns external potential energy of a single particle.
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
void setExternalParameter(double externalParameter)
Sets external parameter.
A clipped cosine potential that induces lamellar ordering along the direction specified by perpDirect...
Saving / output archive for binary ostream.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Utility classes for scientific computation.
Definition: accumulators.mod:1
void getForce(const Vector &position, int type, Vector &force) const
Returns force caused by the external potential.
Saving archive for binary istream.
double externalParameter() const
Returns external parameter.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
void setNAtomType(int nAtomType)
Set nAtomType value.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
LocalLamellarOrderingExternal & operator=(const LocalLamellarOrderingExternal &other)
Assignment.
An object that can read multiple parameters from file.