Simpatico  v1.10
LJPair.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 "LJPair.h"
9 #ifdef UTIL_MPI
10 #include <util/mpi/MpiLoader.h>
11 #endif
12 
13 #include <iostream>
14 #include <cstring>
15 
16 namespace Simp
17 {
18 
19  using namespace Util;
20 
21  /*
22  * Constructor.
23  */
25  : maxPairCutoff_(0.0),
26  nAtomType_(0),
27  isInitialized_(false)
28  { setClassName("LJPair"); }
29 
30  /*
31  * Copy constructor.
32  */
33  LJPair::LJPair(const LJPair& other)
35  nAtomType_(other.nAtomType_),
37  {
38  int i,j;
39  for (i = 0; i < nAtomType_; ++i) {
40  for (j = 0; j < nAtomType_; ++j) {
41  cutoffSq_[i][j]= other.cutoffSq_[i][j];
42  sigma_[i][j] = other.sigma_[i][j];
43  eps48_[i][j] = other.eps48_[i][j];
44  ljShift_[i][j] = other.ljShift_[i][j];
45  epsilon_[i][j] = other.epsilon_[i][j];
46  cutoff_[i][j] = other.cutoff_[i][j];
47  sigmaSq_[i][j] = other.sigmaSq_[i][j];
48  }
49  }
50  }
51 
52  /*
53  * Assignment operator.
54  */
56  {
58  nAtomType_ = other.nAtomType_;
60  int i,j;
61  for (i = 0; i < nAtomType_; ++i) {
62  for (j = 0; j < nAtomType_; ++j) {
63  cutoffSq_[i][j]= other.cutoffSq_[i][j];
64  sigmaSq_[i][j] = other.sigmaSq_[i][j];
65  eps48_[i][j] = other.eps48_[i][j];
66  ljShift_[i][j] = other.ljShift_[i][j];
67  epsilon_[i][j] = other.epsilon_[i][j];
68  sigma_[i][j] = other.sigma_[i][j];
69  cutoff_[i][j] = other.cutoff_[i][j];
70  }
71  }
72  return *this;
73  }
74 
75  /*
76  * Set nAtomType
77  */
78  void LJPair::setNAtomType(int nAtomType)
79  {
80  if (nAtomType <= 0) {
81  UTIL_THROW("nAtomType <= 0");
82  }
83  if (nAtomType > MaxAtomType) {
84  UTIL_THROW("nAtomType > LJPair::MaxAtomType");
85  }
86  nAtomType_ = nAtomType;
87  }
88 
89  /*
90  * Reset epsilon_[i][j] after initialization
91  */
92  void LJPair::setEpsilon(int i, int j, double epsilon)
93  {
94 
95  // Preconditions
96  if (!isInitialized_) {
97  UTIL_THROW("Cannot modify epsilon before LJPair is initialized");
98  }
99  if (i < 0 || i >= nAtomType_) {
100  UTIL_THROW("Invalid atom type index i");
101  }
102  if (j < 0 || j >= nAtomType_) {
103  UTIL_THROW("Invalid atom type index j");
104  }
105 
106  epsilon_[i][j] = epsilon;
107  eps48_[i][j] = 48.0*epsilon;
108 
109  // Calculate shift
110  double r6i = sigmaSq_[i][j]/cutoffSq_[i][j];
111  r6i = r6i*r6i*r6i;
112  ljShift_[i][j] = -4.0*epsilon_[i][j]*(r6i*r6i - r6i);
113 
114  // Symmetrize
115  if (j != i) {
116  epsilon_[j][i] = epsilon_[i][j];
117  eps48_[j][i] = eps48_[i][j];
118  ljShift_[j][i] = ljShift_[i][j];
119  }
120  }
121 
122  /*
123  * Reset sigma_[i][j] after initialization
124  */
125  void LJPair::setSigma(int i, int j, double sigma)
126  {
127 
128  // Preconditions
129  if (!isInitialized_) {
130  UTIL_THROW("Cannot modify sigma before LJPair is initialized");
131  }
132  if (i < 0 || i >= nAtomType_) {
133  UTIL_THROW("Invalid atom type index i");
134  }
135  if (j < 0 || j >= nAtomType_) {
136  UTIL_THROW("Invalid atom type index j");
137  }
138 
139  sigma_[i][j] = sigma;
140  sigmaSq_[i][j] = sigma*sigma;
141 
142  // Recalculate shift
143  double r6i = sigmaSq_[i][j]/cutoffSq_[i][j];
144  r6i = r6i*r6i*r6i;
145  ljShift_[i][j] = -4.0*epsilon_[i][j]*(r6i*r6i - r6i);
146 
147  // Symmetrize
148  if (j != i) {
149  sigma_[j][i] = sigma_[i][j];
150  sigmaSq_[j][i] = sigmaSq_[i][j];
151  ljShift_[j][i] = ljShift_[j][i];
152  }
153 
154  }
155 
156  /*
157  * Read potential parameters from file.
158  */
159  void LJPair::readParameters(std::istream &in)
160  {
161  if (nAtomType_ <= 0) {
162  UTIL_THROW( "nAtomType must be set before readParam");
163  }
164 
165  // Read parameters
166  readCArray2D<double> (in, "epsilon", epsilon_[0],
168  readCArray2D<double>(in, "sigma", sigma_[0],
170  readCArray2D<double>(in, "cutoff", cutoff_[0],
172 
173  // Initialize sigmaSq, cutoffSq, and ljShift, and maxPairCutoff_
174  double r6i;
175  int i, j;
176  maxPairCutoff_ = 0.0;
177  for (i = 0; i < nAtomType_; ++i) {
178  for (j = 0; j < nAtomType_; ++j) {
179  eps48_[i][j] = 48.0*epsilon_[i][j];
180  sigmaSq_[i][j] = sigma_[i][j]*sigma_[i][j];
181  cutoffSq_[i][j] = cutoff_[i][j]*cutoff_[i][j];
182  r6i = sigmaSq_[i][j]/cutoffSq_[i][j];
183  r6i = r6i*r6i*r6i;
184  ljShift_[i][j] = -4.0*epsilon_[i][j]*(r6i*r6i - r6i);
185  if (cutoff_[i][j] > maxPairCutoff_ ) {
186  maxPairCutoff_ = cutoff_[i][j];
187  }
188  }
189  }
190  isInitialized_ = true;
191  }
192 
193  /*
194  * Load internal state from an archive.
195  */
197  {
198  if (nAtomType_ <= 0) {
199  UTIL_THROW( "nAtomType must be set before readParam");
200  }
201 
202  // Read parameters
203  loadCArray2D<double>(ar, "epsilon", epsilon_[0],
205  loadCArray2D<double>(ar, "sigma", sigma_[0],
207  loadCArray2D<double>(ar, "cutoff", cutoff_[0],
209  #ifdef UTIL_MPI
210  MpiLoader<Serializable::IArchive> loader(*this, ar);
211  loader.load(sigmaSq_[0], nAtomType_, nAtomType_, MaxAtomType);
212  loader.load(cutoffSq_[0], nAtomType_, nAtomType_, MaxAtomType);
213  loader.load(ljShift_[0], nAtomType_, nAtomType_, MaxAtomType);
214  loader.load(eps48_[0], nAtomType_, nAtomType_, MaxAtomType);
215  loader.load(maxPairCutoff_);
216  #else
217  ar.unpack(sigmaSq_[0], nAtomType_, nAtomType_, MaxAtomType);
218  ar.unpack(cutoffSq_[0], nAtomType_, nAtomType_, MaxAtomType);
219  ar.unpack(ljShift_[0], nAtomType_, nAtomType_, MaxAtomType);
220  ar.unpack(eps48_[0], nAtomType_, nAtomType_, MaxAtomType);
221  ar >> maxPairCutoff_;
222  #endif
223  isInitialized_ = true;
224  }
225 
226  /*
227  * Save internal state to an archive.
228  */
230  {
238  ar << maxPairCutoff_;
239  }
240 
241  /*
242  * Get maximum of pair cutoff distance, for all atom type pairs.
243  */
244  double LJPair::maxPairCutoff() const
245  { return maxPairCutoff_; }
246 
247  /*
248  * Get pair interaction strength.
249  */
250  double LJPair::epsilon(int i, int j) const
251  {
252  assert(i >= 0 && i < nAtomType_);
253  assert(j >= 0 && j < nAtomType_);
254  return epsilon_[i][j];
255  }
256 
257  /*
258  * Get pair interaction strength.
259  */
260  double LJPair::sigma(int i, int j) const
261  {
262  assert(i >= 0 && i < nAtomType_);
263  assert(j >= 0 && j < nAtomType_);
264  return sigma_[i][j];
265  }
266 
267  /*
268  * Modify a parameter, identified by a string.
269  */
270  void LJPair::set(std::string name, int i, int j, double value)
271  {
272  if (name == "epsilon") {
273  epsilon_[i][j] = value;
274  eps48_[i][j] = 48.0*value;
275  if (j != i) {
276  epsilon_[j][i] = value;
277  eps48_[j][i] = eps48_[i][j];
278  }
279  } else
280  if (name == "sigma") {
281  sigma_[i][j] = value;
282  sigmaSq_[i][j] = value*value;
283  if (j != i) {
284  sigma_[j][i] = sigma_[i][j];
285  sigmaSq_[j][i] = sigmaSq_[i][j];
286  }
287  } else {
288  UTIL_THROW("Unrecognized parameter name");
289  }
290 
291  // Recalculate shift
292  double r6i = sigmaSq_[i][j]/cutoffSq_[i][j];
293  r6i = r6i*r6i*r6i;
294  ljShift_[i][j] = -4.0*epsilon_[i][j]*(r6i*r6i - r6i);
295  if (j != i) {
296  ljShift_[j][i] = ljShift_[j][i];
297  }
298 
299  }
300 
301  /*
302  * Get a parameter value, identified by a string.
303  */
304  double LJPair::get(std::string name, int i, int j) const
305  {
306  double value = 0.0;
307  if (name == "epsilon") {
308  value = epsilon_[i][j];
309  } else
310  if (name == "sigma") {
311  value = sigma_[i][j];
312  } else
313  if (name == "cutoff") {
314  value = cutoff_[i][j];
315  } else {
316  UTIL_THROW("Unrecognized parameter name");
317  }
318  return value;
319  }
320 
321 }
double sigmaSq_[MaxAtomType][MaxAtomType]
square of sigma[][].
Definition: LJPair.h:207
LJPair()
Default constructor.
Definition: LJPair.cpp:24
double epsilon_[MaxAtomType][MaxAtomType]
LJ interaction energies.
Definition: LJPair.h:205
double ljShift_[MaxAtomType][MaxAtomType]
shift in LJ potential.
Definition: LJPair.h:210
void setEpsilon(int i, int j, double epsilon)
Set LJ interaction energy for a specific pair of Atom types.
Definition: LJPair.cpp:92
double eps48_[MaxAtomType][MaxAtomType]
48*epsilon
Definition: LJPair.h:211
int nAtomType_
Total number of atom types.
Definition: LJPair.h:223
Classes used by all simpatico molecular simulations.
double get(std::string name, int i, int j) const
Get a parameter value, identified by a string.
Definition: LJPair.cpp:304
double sigma(int i, int j) const
Get LJ range for a specific pair of Atom types.
Definition: LJPair.cpp:260
void set(std::string name, int i, int j, double value)
Modify a parameter, identified by a string.
Definition: LJPair.cpp:270
Saving / output archive for binary ostream.
double epsilon(int i, int j) const
Get LJ interaction energy for a specific pair of Atom types.
Definition: LJPair.cpp:250
#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.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: LJPair.cpp:229
Utility classes for scientific computation.
Definition: accumulators.mod:1
double sigma_[MaxAtomType][MaxAtomType]
LJ range parameters.
Definition: LJPair.h:206
double cutoff_[MaxAtomType][MaxAtomType]
LJ cutoff distance.
Definition: LJPair.h:208
double maxPairCutoff() const
Get maximum of pair cutoff distance, for all atom type pairs.
Definition: LJPair.cpp:244
double cutoffSq_[MaxAtomType][MaxAtomType]
square of cutoff[][].
Definition: LJPair.h:209
void setSigma(int i, int j, double sigma)
Get LJ range for a specific pair of Atom types.
Definition: LJPair.cpp:125
Saving archive for binary istream.
bool isInitialized_
Was this object initialized by calling (read|load)Parameters ?
Definition: LJPair.h:228
Provides methods for MPI-aware loading of data from input archive.
Definition: MpiLoader.h:43
A cutoff, shifted Lennard-Jones nonbonded pair interaction.
Definition: LJPair.h:33
void setClassName(const char *className)
Set class name string.
static const int MaxAtomType
Maximum allowed value for nAtomType (# of atom types)
Definition: LJPair.h:202
double maxPairCutoff_
Maximum pair potential cutoff radius, for all monomer type pairs.
Definition: LJPair.h:218
LJPair & operator=(const LJPair &other)
Assignment.
Definition: LJPair.cpp:55
void setNAtomType(int nAtomType)
Set nAtomType value.
Definition: LJPair.cpp:78
void readParameters(std::istream &in)
Read epsilon, sigma, and cutoff, and initialize other variables.
Definition: LJPair.cpp:159
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Definition: LJPair.cpp:196