Simpatico  v1.10
HarmonicBond.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 "HarmonicBond.h"
9 #include <util/random/Random.h>
10 
11 namespace Simp
12 {
13 
14  using namespace Util;
15 
16  /*
17  * Constructor.
18  */
20  : nBondType_(0)
21  {
22  setClassName("HarmonicBond");
23  for (int i = 0; i < MaxNBondType; ++i) {
24  kappa_[i] = 0.0;
25  length_[i] = 0.0;
26  }
27  }
28 
29  /*
30  * Copy constructor.
31  */
33  : nBondType_(other.nBondType_)
34  {
35  for (int i = 0; i < nBondType_; ++i) {
36  kappa_[i] = other.kappa_[i];
37  length_[i] = other.length_[i];
38  }
39  }
40 
41  /*
42  * Assignment.
43  */
45  {
46  nBondType_ = other.nBondType_;
47  for (int i = 0; i < nBondType_; ++i) {
48  kappa_[i] = other.kappa_[i];
49  length_[i] = other.length_[i];
50  }
51  return *this;
52  }
53 
54  /*
55  * Set the nBondType_ member
56  */
57  void HarmonicBond::setNBondType(int nBondType)
58  {
59  if (nBondType > MaxNBondType) {
60  UTIL_THROW("nBondType > HarmonicBond::MaxNBondType");
61  }
62  nBondType_ = nBondType;
63  }
64 
65  /*
66  * Read bond interaction parameters kappa and length from file
67  */
68  void HarmonicBond::readParameters(std::istream &in)
69  {
70  UTIL_CHECK(nBondType_ > 0);
71  readCArray<double>(in, "kappa", kappa_, nBondType_);
72  readCArray<double>(in, "length", length_, nBondType_);
73  }
74 
75  /*
76  * Load internal state from an archive.
77  */
79  {
80  UTIL_CHECK(nBondType_ > 0);
81  loadCArray<double>(ar, "kappa", kappa_, nBondType_);
82  loadCArray<double>(ar, "length", length_, nBondType_);
83  }
84 
85  /*
86  * Save internal state to an archive.
87  */
89  {
90  UTIL_CHECK(nBondType_ > 0);
91  ar.pack(kappa_, nBondType_);
92  ar.pack(length_, nBondType_);
93  }
94 
95  /*
96  * Generate a random bond length chosen from an equilibrium distribution for
97  * randomly oriented bonds.
98  *
99  * The desired probability distribution is proportional to x*x*G(x) for x > 0,
100  * where G(x) is a Gaussian distribution with a mean x0=length_[type] and a
101  * standard deviation sd = sqrt(temperature/kappa_[type]).
102  *
103  * Algorithm:
104  * - Generate trial bond length x from the Gaussian distribution G(x).
105  * - If x < 0, generate another trial bond length.
106  * - Let y = x*x/xm*xm, where xm = x0 + 7.0*sd is a maximum length.
107  * The algorithm is correct only for y < 1, or x < xm. The distribution
108  * G(y) for generated values of y is proportional to G(x)/x.
109  * - Accept y if it is greater than a uniform random number in [0,1].
110  * For y < 1, or x < xm, the probability of accepting y is equal to y.
111  * The distribution A(y) of accepted values of y for y < 1 is thus
112  * proportional to y*G(y), or to x*G(x).
113  * - If y is accepted, return x. The distribution A(x) for accepted
114  * values of x is proportional to x*x*G(x) for x < xm.
115  *
116  * Limitations:
117  * The distribution is correct only for x < xm. The probability of
118  * generating a value x >= xm is, however, less than exp(-49/2).
119  */
121  Random *random, double beta, int type) const
122  {
123 
124  double sd = 1.0/sqrt( beta*kappa_[type] );
125  double x0 = length_[type];
126  double xm2 = length_[type] + 7.0*sd;
127  xm2 = xm2*xm2;
128  double x;
129 
130  // Generate trials until one is accepted
131  for (;;) {
132  x = x0 + sd*random->gaussian();
133  if (x < 0) continue;
134  if ( x*x/xm2 >= random->uniform(0.0,1.0) ) {
135  return x;
136  };
137  }
138  }
139 
140  /*
141  * Modify a parameter, identified by a string.
142  */
143  void HarmonicBond::set(std::string name, int type, double value)
144  {
145  if (name == "kappa") {
146  kappa_[type] = value;
147  } else
148  if (name == "length") {
149  length_[type] = value;
150  } else {
151  UTIL_THROW("Unrecognized parameter name");
152  }
153  }
154 
155  /*
156  * Get a parameter value, identified by a string.
157  */
158  double HarmonicBond::get(std::string name, int type) const
159  {
160  double value = 0.0;
161  if (name == "kappa") {
162  value = kappa_[type];
163  } else
164  if (name == "length") {
165  value = length_[type];
166  } else {
167  UTIL_THROW("Unrecognized parameter name");
168  }
169  return value;
170  }
171 
172 }
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
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.
void setNBondType(int nBondType)
Set the number of bond types.
Utility classes for scientific computation.
Definition: accumulators.mod:1
HarmonicBond()
Default constructor.
double gaussian(void)
Return a Gaussian random number with zero average and unit variance.
Definition: Random.cpp:92
HarmonicBond & operator=(const HarmonicBond &other)
Assignment.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Saving archive for binary istream.
double randomBondLength(Random *random, double beta, int type) const
Return bond length chosen from equilibrium distribution.
A harmonic covalent bond potential.
Definition: HarmonicBond.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
void set(std::string name, int type, double value)
Modify a parameter, identified by a string.
double get(std::string name, int type) const
Get a parameter value, identified by a string.
void readParameters(std::istream &in)
Read bond interaction parameters from input stream.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.