Simpatico  v1.10
CosineSqAngle.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "CosineSqAngle.h"
9 #include <util/math/Constants.h>
10 #include <util/random/Random.h>
11 #ifdef UTIL_MPI
12 #include <util/mpi/MpiLoader.h>
13 #endif
14 
15 namespace Simp
16 {
17 
18  using namespace Util;
19 
20  /*
21  * Constructor.
22  */
24  : nAngleType_(0)
25  {
26  setClassName("CosineSqAngle");
27  for (int i = 0; i < MaxNAngleType; ++i) {
28  kappa_[i] = 0.0;
29  theta0_[i] = 0.0;
30  cosTheta0_[i] = 1.0;
31  }
32  }
33 
34  /*
35  * Copy constructor.
36  */
38  : nAngleType_(other.nAngleType_)
39  {
40  for (int i = 0; i < MaxNAngleType; ++i) {
41  kappa_[i] = other.kappa_[i];
42  theta0_[i] = other.theta0_[i];
43  cosTheta0_[i] = other.cosTheta0_[i];
44  }
45  }
46 
47  /*
48  * Assignment.
49  */
51  {
52  nAngleType_ = other.nAngleType_;
53  for (int i = 0; i < MaxNAngleType; ++i) {
54  kappa_[i] = other.kappa_[i];
55  theta0_[i] = other.theta0_[i];
56  cosTheta0_[i] = other.cosTheta0_[i];
57  }
58  return *this;
59  }
60 
61  /*
62  * Set the nAngleType_ member.
63  */
64  void CosineSqAngle::setNAngleType(int nAngleType)
65  {
66  if (nAngleType > MaxNAngleType) {
67  UTIL_THROW("nAngleType > CosineSqAngle::MaxNAngleType");
68  }
69  nAngleType_ = nAngleType;
70  }
71 
72  /*
73  * Read bend interaction parameters kappa from file.
74  */
75  void CosineSqAngle::readParameters(std::istream &in)
76  {
77  // Precondition
78  UTIL_CHECK(nAngleType_ > 0);
79 
80  // Read parameters
81  readCArray<double>(in, "kappa", kappa_, nAngleType_);
82  readCArray<double>(in, "theta0", theta0_, nAngleType_);
83 
84  // Compute cosine.
85  for (int i = 0; i < nAngleType_; ++i) {
86  cosTheta0_[i] = cos(theta0_[i] / 180.0 * Constants::Pi);
87  }
88  }
89 
90  /*
91  * Load internal state from an archive.
92  */
94  {
95  UTIL_CHECK(nAngleType_ > 0);
96  loadCArray<double> (ar, "kappa", kappa_, nAngleType_);
97  loadCArray<double>(ar, "theta0", theta0_, nAngleType_);
98  #ifdef UTIL_MPI
99  MpiLoader<Serializable::IArchive> loader(*this, ar);
100  loader.load(cosTheta0_, nAngleType_);
101  #else
102  ar.unpack(cosTheta0_, nAngleType_);
103  #endif
104  }
105 
106  /*
107  * Save internal state to an archive.
108  */
110  {
111  UTIL_CHECK(nAngleType_ > 0);
112  ar.pack(kappa_, nAngleType_);
113  ar.pack(theta0_, nAngleType_);
114  ar.pack(cosTheta0_, nAngleType_);
115  }
116 
117  /*
118  * Generate a random bond angle chosen from an equilibrium distribution for
119  * randomly oriented bonds.
120  *
121  * Algorithm: Generate random bond vector and take the angle.
122  */
124  Random *random, double beta, int type) const
125  {
126  double Theta, Theta_min;
127  double U, U_min;
128  bool chosen = false;
129 
130  Theta_min = acos(cosTheta0_[type]);
131  U_min = energy(cos(Theta_min), type);
132 
133  while (chosen == false) {
134  Theta = random->uniform(0, Constants::Pi);
135  U = energy(cos(Theta), type);
136  if (random->uniform() < exp(-beta*(U-U_min))*cos(Theta)/cos(Theta_min))
137  chosen = true;
138  }
139 
140  return Theta;
141  }
142 
143  /*
144  * Generate a random bond angle cosine chosen from an equilibrium distribution
145  * for randomly oriented bonds.
146  *
147  * Algorithm: Generate random bond vector and take the angle.
148  */
150  Random *random, double beta, int type) const
151  {
152  double CosineTheta, CosineTheta_min;
153  double U, U_min;
154  bool chosen = false;
155 
156  CosineTheta_min = cosTheta0_[type];
157  U_min = energy(CosineTheta_min, type);
158 
159  while (chosen == false) {
160  CosineTheta = random->uniform(-1, 1);
161  U = energy(CosineTheta, type);
162  if (random->uniform() < exp(-beta*(U-U_min)))
163  chosen = true;
164  }
165 
166  return CosineTheta;
167  }
168 
169  /*
170  * Modify a parameter, identified by a string.
171  */
172  void CosineSqAngle::set(std::string name, int type, double value)
173  {
174  if (name == "kappa") {
175  kappa_[type] = value;
176  } else
177  if (name == "theta0") {
178  theta0_[type] = value;
179  } else {
180  UTIL_THROW("Unrecognized parameter name");
181  }
182  }
183 
184  /*
185  * Get a parameter value, identified by a string.
186  */
187  double CosineSqAngle::get(std::string name, int type) const
188  {
189  double value = 0.0;
190  if (name == "kappa") {
191  value = kappa_[type];
192  } else
193  if (name == "theta0") {
194  value = theta0_[type];
195  } else {
196  UTIL_THROW("Unrecognized parameter name");
197  }
198  return value;
199  }
200 
201  /*
202  * Return name string "CosineSqAngle" for this evaluator class.
203  */
204  std::string CosineSqAngle::className() const
205  { return std::string("CosineSqAngle"); }
206 
207 
208 }
double energy(double cosTheta, int type) const
Returns potential energy for one angle.
std::string className() const
Return name string "CosineSqAngle" for this evaluator class.
CosineSqAngle()
Default constructor.
Classes used by all simpatico molecular simulations.
double uniform()
Return a random floating point number x, uniformly distributed in the range 0 <= x < 1...
Definition: Random.h:203
void set(std::string name, int type, double value)
Modify a parameter, identified by a string.
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
void pack(const T &data)
Pack one object of type T.
A three body angle potential, as a function of angle cosine.
Definition: CosineSqAngle.h:34
Utility classes for scientific computation.
Definition: accumulators.mod:1
double randomCosineAngle(Random *random, double beta, int type) const
Return bond angle cosine chosen from equilibrium distribution.
void setNAngleType(int nAngleType)
Set the number of angle types.
void readParameters(std::istream &in)
Read angle interaction parameters from input stream.
CosineSqAngle & operator=(const CosineSqAngle &other)
Assignment.
Saving archive for binary istream.
Provides methods for MPI-aware loading of data from input archive.
Definition: MpiLoader.h:43
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
static const double Pi
Trigonometric constant Pi.
Definition: Constants.h:35
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
void setClassName(const char *className)
Set class name string.
Random number generator.
Definition: Random.h:46
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
double get(std::string name, int type) const
Get a parameter value, identified by a string.
double randomAngle(Random *random, double beta, int type) const
Return bond angle chosen from equilibrium distribution.