ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/integrators/NPTf.cpp
(Generate patch)

Comparing trunk/src/integrators/NPTf.cpp (file contents):
Revision 246 by gezelter, Wed Jan 12 22:41:40 2005 UTC vs.
Revision 1879 by gezelter, Sun Jun 16 15:15:42 2013 UTC

# Line 1 | Line 1
1 < /*
1 > /*
2   * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3   *
4   * The University of Notre Dame grants you ("Licensee") a
# Line 6 | Line 6
6   * redistribute this software in source and binary code form, provided
7   * that the following conditions are met:
8   *
9 < * 1. Acknowledgement of the program authors must be made in any
10 < *    publication of scientific results based in part on use of the
11 < *    program.  An acceptable form of acknowledgement is citation of
12 < *    the article in which the program was described (Matthew
13 < *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 < *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 < *    Parallel Simulation Engine for Molecular Dynamics,"
16 < *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 < *
18 < * 2. Redistributions of source code must retain the above copyright
9 > * 1. Redistributions of source code must retain the above copyright
10   *    notice, this list of conditions and the following disclaimer.
11   *
12 < * 3. Redistributions in binary form must reproduce the above copyright
12 > * 2. Redistributions in binary form must reproduce the above copyright
13   *    notice, this list of conditions and the following disclaimer in the
14   *    documentation and/or other materials provided with the
15   *    distribution.
# Line 37 | Line 28
28   * arising out of the use of or inability to use software, even if the
29   * University of Notre Dame has been advised of the possibility of
30   * such damages.
31 + *
32 + * SUPPORT OPEN SCIENCE!  If you use OpenMD or its source code in your
33 + * research, please cite the appropriate papers when you publish your
34 + * work.  Good starting points are:
35 + *                                                                      
36 + * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
37 + * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
38 + * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).          
39 + * [4]  Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
40 + * [5]  Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41   */
42  
43   #include "brains/SimInfo.hpp"
# Line 44 | Line 45
45   #include "integrators/IntegratorCreator.hpp"
46   #include "integrators/NPTf.hpp"
47   #include "primitives/Molecule.hpp"
48 < #include "utils/OOPSEConstant.hpp"
48 > #include "utils/PhysicalConstants.hpp"
49   #include "utils/simError.h"
50  
51 < namespace oopse {
51 > namespace OpenMD {
52  
53 < // Basic non-isotropic thermostating and barostating via the Melchionna
54 < // modification of the Hoover algorithm:
55 < //
56 < //    Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
57 < //       Molec. Phys., 78, 533.
58 < //
59 < //           and
60 < //
61 < //    Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
53 >  // Basic non-isotropic thermostating and barostating via the Melchionna
54 >  // modification of the Hoover algorithm:
55 >  //
56 >  //    Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
57 >  //       Molec. Phys., 78, 533.
58 >  //
59 >  //           and
60 >  //
61 >  //    Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
62  
63 < void NPTf::evolveEtaA() {
63 >  void NPTf::evolveEtaA() {
64  
65 <  int i, j;
65 >    int i, j;
66  
67      for(i = 0; i < 3; i ++){
68 <        for(j = 0; j < 3; j++){
69 <            if( i == j) {
70 <                eta(i, j) += dt2 *  instaVol * (press(i, j) - targetPressure/OOPSEConstant::pressureConvert) / (NkBT*tb2);
71 <            } else {
72 <                eta(i, j) += dt2 * instaVol * press(i, j) / (NkBT*tb2);
73 <            }
74 <        }
68 >      for(j = 0; j < 3; j++){
69 >        if( i == j) {
70 >          eta(i, j) += dt2 *  instaVol * (press(i, j) - targetPressure/PhysicalConstants::pressureConvert) / (NkBT*tb2);
71 >        } else {
72 >          eta(i, j) += dt2 * instaVol * press(i, j) / (NkBT*tb2);
73 >        }
74 >      }
75      }
76    
77      for(i = 0; i < 3; i++) {
78 <        for (j = 0; j < 3; j++) {
78 >      for (j = 0; j < 3; j++) {
79          oldEta(i, j) = eta(i, j);
80 <        }
80 >      }
81      }
82    
83 < }
83 >  }
84  
85 < void NPTf::evolveEtaB() {
85 >  void NPTf::evolveEtaB() {
86  
87      int i;
88      int j;
89  
90      for(i = 0; i < 3; i++) {
91 <        for (j = 0; j < 3; j++) {
92 <            prevEta(i, j) = eta(i, j);
93 <        }
91 >      for (j = 0; j < 3; j++) {
92 >        prevEta(i, j) = eta(i, j);
93 >      }
94      }
95  
96      for(i = 0; i < 3; i ++){
97 <        for(j = 0; j < 3; j++){
98 <            if( i == j) {
99 <                eta(i, j) = oldEta(i, j) + dt2 *  instaVol *
100 <                (press(i, j) - targetPressure/OOPSEConstant::pressureConvert) / (NkBT*tb2);
101 <            } else {
102 <                eta(i, j) = oldEta(i, j) + dt2 * instaVol * press(i, j) / (NkBT*tb2);
103 <            }
104 <        }
97 >      for(j = 0; j < 3; j++){
98 >        if( i == j) {
99 >          eta(i, j) = oldEta(i, j) + dt2 *  instaVol *
100 >            (press(i, j) - targetPressure/PhysicalConstants::pressureConvert) / (NkBT*tb2);
101 >        } else {
102 >          eta(i, j) = oldEta(i, j) + dt2 * instaVol * press(i, j) / (NkBT*tb2);
103 >        }
104 >      }
105      }
106  
107    
108 < }
108 >  }
109  
110 < void NPTf::calcVelScale(){
110 >  void NPTf::calcVelScale(){
111  
112 <  for (int i = 0; i < 3; i++ ) {
113 <    for (int j = 0; j < 3; j++ ) {
114 <      vScale(i, j) = eta(i, j);
112 >    for (int i = 0; i < 3; i++ ) {
113 >      for (int j = 0; j < 3; j++ ) {
114 >        vScale(i, j) = eta(i, j);
115  
116 <      if (i == j) {
117 <        vScale(i, j) += chi;
116 >        if (i == j) {
117 >          vScale(i, j) += thermostat.first;
118 >        }
119        }
120      }
121    }
120 }
122  
123 < void NPTf::getVelScaleA(Vector3d& sc, const Vector3d& vel){
123 >  void NPTf::getVelScaleA(Vector3d& sc, const Vector3d& vel){
124      sc = vScale * vel;
125 < }
125 >  }
126  
127 < void NPTf::getVelScaleB(Vector3d& sc, int index ) {
128 <  sc = vScale * oldVel[index];
129 < }
127 >  void NPTf::getVelScaleB(Vector3d& sc, int index ) {
128 >    sc = vScale * oldVel[index];
129 >  }
130  
131 < void NPTf::getPosScale(const Vector3d& pos, const Vector3d& COM, int index, Vector3d& sc) {
131 >  void NPTf::getPosScale(const Vector3d& pos, const Vector3d& COM, int index, Vector3d& sc) {
132  
133      /**@todo */
134 <    Vector3d rj = (oldPos[index] + pos)/2.0 -COM;
134 >    Vector3d rj = (oldPos[index] + pos)/(RealType)2.0 -COM;
135      sc = eta * rj;
136 < }
136 >  }
137  
138 < void NPTf::scaleSimBox(){
138 >  void NPTf::scaleSimBox(){
139  
140 <  int i;
141 <  int j;
142 <  int k;
143 <  Mat3x3d scaleMat;
144 <  double eta2ij;
145 <  double bigScale, smallScale, offDiagMax;
146 <  Mat3x3d hm;
147 <  Mat3x3d hmnew;
140 >    int i;
141 >    int j;
142 >    int k;
143 >    Mat3x3d scaleMat;
144 >    RealType eta2ij;
145 >    RealType bigScale, smallScale, offDiagMax;
146 >    Mat3x3d hm;
147 >    Mat3x3d hmnew;
148  
149  
150  
151 <  // Scale the box after all the positions have been moved:
151 >    // Scale the box after all the positions have been moved:
152  
153 <  // Use a taylor expansion for eta products:  Hmat = Hmat . exp(dt * etaMat)
154 <  //  Hmat = Hmat . ( Ident + dt * etaMat  + dt^2 * etaMat*etaMat / 2)
153 >    // Use a taylor expansion for eta products:  Hmat = Hmat . exp(dt * etaMat)
154 >    //  Hmat = Hmat . ( Ident + dt * etaMat  + dt^2 * etaMat*etaMat / 2)
155  
156 <  bigScale = 1.0;
157 <  smallScale = 1.0;
158 <  offDiagMax = 0.0;
156 >    bigScale = 1.0;
157 >    smallScale = 1.0;
158 >    offDiagMax = 0.0;
159  
160 <  for(i=0; i<3; i++){
161 <    for(j=0; j<3; j++){
160 >    for(i=0; i<3; i++){
161 >      for(j=0; j<3; j++){
162  
163 <      // Calculate the matrix Product of the eta array (we only need
164 <      // the ij element right now):
163 >        // Calculate the matrix Product of the eta array (we only need
164 >        // the ij element right now):
165  
166 <      eta2ij = 0.0;
167 <      for(k=0; k<3; k++){
168 <        eta2ij += eta(i, k) * eta(k, j);
169 <      }
166 >        eta2ij = 0.0;
167 >        for(k=0; k<3; k++){
168 >          eta2ij += eta(i, k) * eta(k, j);
169 >        }
170  
171 <      scaleMat(i, j) = 0.0;
172 <      // identity matrix (see above):
173 <      if (i == j) scaleMat(i, j) = 1.0;
174 <      // Taylor expansion for the exponential truncated at second order:
175 <      scaleMat(i, j) += dt*eta(i, j)  + 0.5*dt*dt*eta2ij;
171 >        scaleMat(i, j) = 0.0;
172 >        // identity matrix (see above):
173 >        if (i == j) scaleMat(i, j) = 1.0;
174 >        // Taylor expansion for the exponential truncated at second order:
175 >        scaleMat(i, j) += dt*eta(i, j)  + 0.5*dt*dt*eta2ij;
176        
177  
178 <      if (i != j)
179 <        if (fabs(scaleMat(i, j)) > offDiagMax)
180 <          offDiagMax = fabs(scaleMat(i, j));
178 >        if (i != j)
179 >          if (fabs(scaleMat(i, j)) > offDiagMax)
180 >            offDiagMax = fabs(scaleMat(i, j));
181 >      }
182 >
183 >      if (scaleMat(i, i) > bigScale) bigScale = scaleMat(i, i);
184 >      if (scaleMat(i, i) < smallScale) smallScale = scaleMat(i, i);
185      }
186  
187 <    if (scaleMat(i, i) > bigScale) bigScale = scaleMat(i, i);
188 <    if (scaleMat(i, i) < smallScale) smallScale = scaleMat(i, i);
189 <  }
187 >    if ((bigScale > 1.01) || (smallScale < 0.99)) {
188 >      sprintf( painCave.errMsg,
189 >               "NPTf error: Attempting a Box scaling of more than 1 percent.\n"
190 >               " Check your tauBarostat, as it is probably too small!\n\n"
191 >               " scaleMat = [%lf\t%lf\t%lf]\n"
192 >               "            [%lf\t%lf\t%lf]\n"
193 >               "            [%lf\t%lf\t%lf]\n"
194 >               "      eta = [%lf\t%lf\t%lf]\n"
195 >               "            [%lf\t%lf\t%lf]\n"
196 >               "            [%lf\t%lf\t%lf]\n",
197 >               scaleMat(0, 0),scaleMat(0, 1),scaleMat(0, 2),
198 >               scaleMat(1, 0),scaleMat(1, 1),scaleMat(1, 2),
199 >               scaleMat(2, 0),scaleMat(2, 1),scaleMat(2, 2),
200 >               eta(0, 0),eta(0, 1),eta(0, 2),
201 >               eta(1, 0),eta(1, 1),eta(1, 2),
202 >               eta(2, 0),eta(2, 1),eta(2, 2));
203 >      painCave.isFatal = 1;
204 >      simError();
205 >    } else if (offDiagMax > 0.01) {
206 >      sprintf( painCave.errMsg,
207 >               "NPTf error: Attempting an off-diagonal Box scaling of more than 1 percent.\n"
208 >               " Check your tauBarostat, as it is probably too small!\n\n"
209 >               " scaleMat = [%lf\t%lf\t%lf]\n"
210 >               "            [%lf\t%lf\t%lf]\n"
211 >               "            [%lf\t%lf\t%lf]\n"
212 >               "      eta = [%lf\t%lf\t%lf]\n"
213 >               "            [%lf\t%lf\t%lf]\n"
214 >               "            [%lf\t%lf\t%lf]\n",
215 >               scaleMat(0, 0),scaleMat(0, 1),scaleMat(0, 2),
216 >               scaleMat(1, 0),scaleMat(1, 1),scaleMat(1, 2),
217 >               scaleMat(2, 0),scaleMat(2, 1),scaleMat(2, 2),
218 >               eta(0, 0),eta(0, 1),eta(0, 2),
219 >               eta(1, 0),eta(1, 1),eta(1, 2),
220 >               eta(2, 0),eta(2, 1),eta(2, 2));
221 >      painCave.isFatal = 1;
222 >      simError();
223 >    } else {
224  
225 <  if ((bigScale > 1.01) || (smallScale < 0.99)) {
226 <    sprintf( painCave.errMsg,
227 <             "NPTf error: Attempting a Box scaling of more than 1 percent.\n"
189 <             " Check your tauBarostat, as it is probably too small!\n\n"
190 <             " scaleMat = [%lf\t%lf\t%lf]\n"
191 <             "            [%lf\t%lf\t%lf]\n"
192 <             "            [%lf\t%lf\t%lf]\n"
193 <             "      eta = [%lf\t%lf\t%lf]\n"
194 <             "            [%lf\t%lf\t%lf]\n"
195 <             "            [%lf\t%lf\t%lf]\n",
196 <             scaleMat(0, 0),scaleMat(0, 1),scaleMat(0, 2),
197 <             scaleMat(1, 0),scaleMat(1, 1),scaleMat(1, 2),
198 <             scaleMat(2, 0),scaleMat(2, 1),scaleMat(2, 2),
199 <             eta(0, 0),eta(0, 1),eta(0, 2),
200 <             eta(1, 0),eta(1, 1),eta(1, 2),
201 <             eta(2, 0),eta(2, 1),eta(2, 2));
202 <    painCave.isFatal = 1;
203 <    simError();
204 <  } else if (offDiagMax > 0.01) {
205 <    sprintf( painCave.errMsg,
206 <             "NPTf error: Attempting an off-diagonal Box scaling of more than 1 percent.\n"
207 <             " Check your tauBarostat, as it is probably too small!\n\n"
208 <             " scaleMat = [%lf\t%lf\t%lf]\n"
209 <             "            [%lf\t%lf\t%lf]\n"
210 <             "            [%lf\t%lf\t%lf]\n"
211 <             "      eta = [%lf\t%lf\t%lf]\n"
212 <             "            [%lf\t%lf\t%lf]\n"
213 <             "            [%lf\t%lf\t%lf]\n",
214 <             scaleMat(0, 0),scaleMat(0, 1),scaleMat(0, 2),
215 <             scaleMat(1, 0),scaleMat(1, 1),scaleMat(1, 2),
216 <             scaleMat(2, 0),scaleMat(2, 1),scaleMat(2, 2),
217 <             eta(0, 0),eta(0, 1),eta(0, 2),
218 <             eta(1, 0),eta(1, 1),eta(1, 2),
219 <             eta(2, 0),eta(2, 1),eta(2, 2));
220 <    painCave.isFatal = 1;
221 <    simError();
222 <  } else {
223 <
224 <        Mat3x3d hmat = currentSnapshot_->getHmat();
225 <        hmat = hmat *scaleMat;
226 <        currentSnapshot_->setHmat(hmat);
225 >      Mat3x3d hmat = snap->getHmat();
226 >      hmat = hmat *scaleMat;
227 >      snap->setHmat(hmat);
228          
229 +    }
230    }
229 }
231  
232 < bool NPTf::etaConverged() {
232 >  bool NPTf::etaConverged() {
233      int i;
234 <    double diffEta, sumEta;
234 >    RealType diffEta, sumEta;
235  
236      sumEta = 0;
237      for(i = 0; i < 3; i++) {
238 <        sumEta += pow(prevEta(i, i) - eta(i, i), 2);
238 >      sumEta += pow(prevEta(i, i) - eta(i, i), 2);
239      }
240      
241      diffEta = sqrt( sumEta / 3.0 );
242  
243      return ( diffEta <= etaTolerance );
244 < }
244 >  }
245  
246 < double NPTf::calcConservedQuantity(){
247 <
248 <    chi= currentSnapshot_->getChi();
248 <    integralOfChidt = currentSnapshot_->getIntegralOfChiDt();
246 >  RealType NPTf::calcConservedQuantity(){
247 >    
248 >    thermostat = snap->getThermostat();
249      loadEta();
250      
251      // We need NkBT a lot, so just set it here: This is the RAW number
252      // of integrableObjects, so no subtraction or addition of constraints or
253      // orientational degrees of freedom:
254 <    NkBT = info_->getNGlobalIntegrableObjects()*OOPSEConstant::kB *targetTemp;
254 >    NkBT = info_->getNGlobalIntegrableObjects()*PhysicalConstants::kB *targetTemp;
255  
256      // fkBT is used because the thermostat operates on more degrees of freedom
257      // than the barostat (when there are particles with orientational degrees
258      // of freedom).  
259 <    fkBT = info_->getNdf()*OOPSEConstant::kB *targetTemp;    
259 >    fkBT = info_->getNdf()*PhysicalConstants::kB *targetTemp;    
260      
261 <    double conservedQuantity;
262 <    double totalEnergy;
263 <    double thermostat_kinetic;
264 <    double thermostat_potential;
265 <    double barostat_kinetic;
266 <    double barostat_potential;
267 <    double trEta;
261 >    RealType conservedQuantity;
262 >    RealType totalEnergy;
263 >    RealType thermostat_kinetic;
264 >    RealType thermostat_potential;
265 >    RealType barostat_kinetic;
266 >    RealType barostat_potential;
267 >    RealType trEta;
268  
269 <    totalEnergy = thermo.getTotalE();
269 >    totalEnergy = thermo.getTotalEnergy();
270 >    
271 >    thermostat_kinetic = fkBT * tt2 * thermostat.first *
272 >      thermostat.first /(2.0 * PhysicalConstants::energyConvert);
273  
274 <    thermostat_kinetic = fkBT * tt2 * chi * chi /(2.0 * OOPSEConstant::energyConvert);
274 >    thermostat_potential = fkBT* thermostat.second / PhysicalConstants::energyConvert;
275  
276 <    thermostat_potential = fkBT* integralOfChidt / OOPSEConstant::energyConvert;
274 <
275 <    SquareMatrix<double, 3> tmp = eta.transpose() * eta;
276 >    SquareMatrix<RealType, 3> tmp = eta.transpose() * eta;
277      trEta = tmp.trace();
278      
279 <    barostat_kinetic = NkBT * tb2 * trEta /(2.0 * OOPSEConstant::energyConvert);
279 >    barostat_kinetic = NkBT * tb2 * trEta /(2.0 * PhysicalConstants::energyConvert);
280  
281 <    barostat_potential = (targetPressure * thermo.getVolume() / OOPSEConstant::pressureConvert) /OOPSEConstant::energyConvert;
281 >    barostat_potential = (targetPressure * thermo.getVolume() / PhysicalConstants::pressureConvert) /PhysicalConstants::energyConvert;
282  
283      conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
284 <        barostat_kinetic + barostat_potential;
284 >      barostat_kinetic + barostat_potential;
285  
286      return conservedQuantity;
287  
288 < }
288 >  }
289  
290 < void NPTf::loadEta() {
291 <    eta= currentSnapshot_->getEta();
290 >  void NPTf::loadEta() {
291 >    eta= snap->getBarostat();
292  
293      //if (!eta.isDiagonal()) {
294      //    sprintf( painCave.errMsg,
# Line 295 | Line 296 | void NPTf::loadEta() {
296      //    painCave.isFatal = 1;
297      //    simError();
298      //}
299 < }
299 >  }
300  
301 < void NPTf::saveEta() {
302 <    currentSnapshot_->setEta(eta);
303 < }
301 >  void NPTf::saveEta() {
302 >    snap->setBarostat(eta);
303 >  }
304  
305   }

Comparing trunk/src/integrators/NPTf.cpp (property svn:keywords):
Revision 246 by gezelter, Wed Jan 12 22:41:40 2005 UTC vs.
Revision 1879 by gezelter, Sun Jun 16 15:15:42 2013 UTC

# Line 0 | Line 1
1 + Author Id Revision Date

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines