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

Comparing trunk/OOPSE-2.0/src/integrators/NPTf.cpp (file contents):
Revision 1625 by tim, Thu Oct 21 16:22:01 2004 UTC vs.
Revision 1930 by gezelter, Wed Jan 12 22:41:40 2005 UTC

# Line 1 | Line 1
1 < #include <math.h>
2 <
3 < #include "math/MatVec3.h"
4 < #include "primitives/Atom.hpp"
5 < #include "primitives/SRI.hpp"
6 < #include "primitives/AbstractClasses.hpp"
1 > /*
2 > * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 > *
4 > * The University of Notre Dame grants you ("Licensee") a
5 > * non-exclusive, royalty free, license to use, modify and
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
19 > *    notice, this list of conditions and the following disclaimer.
20 > *
21 > * 3. Redistributions in binary form must reproduce the above copyright
22 > *    notice, this list of conditions and the following disclaimer in the
23 > *    documentation and/or other materials provided with the
24 > *    distribution.
25 > *
26 > * This software is provided "AS IS," without a warranty of any
27 > * kind. All express or implied conditions, representations and
28 > * warranties, including any implied warranty of merchantability,
29 > * fitness for a particular purpose or non-infringement, are hereby
30 > * excluded.  The University of Notre Dame and its licensors shall not
31 > * be liable for any damages suffered by licensee as a result of
32 > * using, modifying or distributing the software or its
33 > * derivatives. In no event will the University of Notre Dame or its
34 > * licensors be liable for any lost revenue, profit or data, or for
35 > * direct, indirect, special, consequential, incidental or punitive
36 > * damages, however caused and regardless of the theory of liability,
37 > * arising out of the use of or inability to use software, even if the
38 > * University of Notre Dame has been advised of the possibility of
39 > * such damages.
40 > */
41 >
42   #include "brains/SimInfo.hpp"
8 #include "UseTheForce/ForceFields.hpp"
43   #include "brains/Thermo.hpp"
44 < #include "io/ReadWrite.hpp"
45 < #include "integrators/Integrator.hpp"
44 > #include "integrators/IntegratorCreator.hpp"
45 > #include "integrators/NPTf.hpp"
46 > #include "primitives/Molecule.hpp"
47 > #include "utils/OOPSEConstant.hpp"
48   #include "utils/simError.h"
49  
50 < #ifdef IS_MPI
15 < #include "brains/mpiSimulation.hpp"
16 < #endif
50 > namespace oopse {
51  
52   // Basic non-isotropic thermostating and barostating via the Melchionna
53   // modification of the Hoover algorithm:
# Line 25 | Line 59 | template<typename T> NPTf<T>::NPTf ( SimInfo *theInfo,
59   //
60   //    Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
61  
62 < template<typename T> NPTf<T>::NPTf ( SimInfo *theInfo, ForceFields* the_ff):
29 <  T( theInfo, the_ff )
30 < {
31 <  GenericData* data;
32 <  DoubleVectorGenericData * etaValue;
33 <  int i,j;
62 > void NPTf::evolveEtaA() {
63  
64 <  for(i = 0; i < 3; i++){
36 <    for (j = 0; j < 3; j++){
64 >  int i, j;
65  
66 <      eta[i][j] = 0.0;
67 <      oldEta[i][j] = 0.0;
66 >    for(i = 0; i < 3; i ++){
67 >        for(j = 0; j < 3; j++){
68 >            if( i == j) {
69 >                eta(i, j) += dt2 *  instaVol * (press(i, j) - targetPressure/OOPSEConstant::pressureConvert) / (NkBT*tb2);
70 >            } else {
71 >                eta(i, j) += dt2 * instaVol * press(i, j) / (NkBT*tb2);
72 >            }
73 >        }
74      }
75 <  }
76 <
77 <
78 <  if( theInfo->useInitXSstate ){
79 <    // retrieve eta array from simInfo if it exists
46 <    data = info->getProperty(ETAVALUE_ID);
47 <    if(data){
48 <      etaValue = dynamic_cast<DoubleVectorGenericData*>(data);
49 <      
50 <      if(etaValue){
51 <        
52 <        for(i = 0; i < 3; i++){
53 <          for (j = 0; j < 3; j++){
54 <            eta[i][j] = (*etaValue)[3*i+j];
55 <            oldEta[i][j] = eta[i][j];
56 <          }
57 <        }
58 <      }
75 >  
76 >    for(i = 0; i < 3; i++) {
77 >        for (j = 0; j < 3; j++) {
78 >        oldEta(i, j) = eta(i, j);
79 >        }
80      }
81 <  }
61 <
81 >  
82   }
83  
84 < template<typename T> NPTf<T>::~NPTf() {
84 > void NPTf::evolveEtaB() {
85  
86 <  // empty for now
87 < }
86 >    int i;
87 >    int j;
88  
89 < template<typename T> void NPTf<T>::resetIntegrator() {
89 >    for(i = 0; i < 3; i++) {
90 >        for (j = 0; j < 3; j++) {
91 >            prevEta(i, j) = eta(i, j);
92 >        }
93 >    }
94  
95 <  int i, j;
96 <
97 <  for(i = 0; i < 3; i++)
98 <    for (j = 0; j < 3; j++)
99 <      eta[i][j] = 0.0;
100 <
101 <  T::resetIntegrator();
102 < }
103 <
80 < template<typename T> void NPTf<T>::evolveEtaA() {
81 <
82 <  int i, j;
83 <
84 <  for(i = 0; i < 3; i ++){
85 <    for(j = 0; j < 3; j++){
86 <      if( i == j)
87 <        eta[i][j] += dt2 *  instaVol *
88 <          (press[i][j] - targetPressure/p_convert) / (NkBT*tb2);
89 <      else
90 <        eta[i][j] += dt2 * instaVol * press[i][j] / (NkBT*tb2);
95 >    for(i = 0; i < 3; i ++){
96 >        for(j = 0; j < 3; j++){
97 >            if( i == j) {
98 >                eta(i, j) = oldEta(i, j) + dt2 *  instaVol *
99 >                (press(i, j) - targetPressure/OOPSEConstant::pressureConvert) / (NkBT*tb2);
100 >            } else {
101 >                eta(i, j) = oldEta(i, j) + dt2 * instaVol * press(i, j) / (NkBT*tb2);
102 >            }
103 >        }
104      }
105 <  }
105 >
106    
94  for(i = 0; i < 3; i++)
95    for (j = 0; j < 3; j++)
96      oldEta[i][j] = eta[i][j];
107   }
108  
109 < template<typename T> void NPTf<T>::evolveEtaB() {
109 > void NPTf::calcVelScale(){
110  
111 <  int i,j;
111 >  for (int i = 0; i < 3; i++ ) {
112 >    for (int j = 0; j < 3; j++ ) {
113 >      vScale(i, j) = eta(i, j);
114  
115 <  for(i = 0; i < 3; i++)
116 <    for (j = 0; j < 3; j++)
105 <      prevEta[i][j] = eta[i][j];
106 <
107 <  for(i = 0; i < 3; i ++){
108 <    for(j = 0; j < 3; j++){
109 <      if( i == j) {
110 <        eta[i][j] = oldEta[i][j] + dt2 *  instaVol *
111 <          (press[i][j] - targetPressure/p_convert) / (NkBT*tb2);
112 <      } else {
113 <        eta[i][j] = oldEta[i][j] + dt2 * instaVol * press[i][j] / (NkBT*tb2);
115 >      if (i == j) {
116 >        vScale(i, j) += chi;
117        }
118      }
119    }
120   }
121  
122 < template<typename T> void NPTf<T>::calcVelScale(void){
123 <  int i,j;
121 <
122 <  for (i = 0; i < 3; i++ ) {
123 <    for (j = 0; j < 3; j++ ) {
124 <      vScale[i][j] = eta[i][j];
125 <
126 <      if (i == j) {
127 <        vScale[i][j] += chi;
128 <      }
129 <    }
130 <  }
122 > void NPTf::getVelScaleA(Vector3d& sc, const Vector3d& vel){
123 >    sc = vScale * vel;
124   }
125  
126 < template<typename T> void NPTf<T>::getVelScaleA(double sc[3], double vel[3]) {
127 <
135 <  matVecMul3( vScale, vel, sc );
126 > void NPTf::getVelScaleB(Vector3d& sc, int index ) {
127 >  sc = vScale * oldVel[index];
128   }
129  
130 < template<typename T> void NPTf<T>::getVelScaleB(double sc[3], int index ){
139 <  int j;
140 <  double myVel[3];
130 > void NPTf::getPosScale(const Vector3d& pos, const Vector3d& COM, int index, Vector3d& sc) {
131  
132 <  for (j = 0; j < 3; j++)
133 <    myVel[j] = oldVel[3*index + j];
134 <  
145 <  matVecMul3( vScale, myVel, sc );
132 >    /**@todo */
133 >    Vector3d rj = (oldPos[index] + pos)/2.0 -COM;
134 >    sc = eta * rj;
135   }
136  
137 < template<typename T> void NPTf<T>::getPosScale(double pos[3], double COM[3],
149 <                                               int index, double sc[3]){
150 <  int j;
151 <  double rj[3];
137 > void NPTf::scaleSimBox(){
138  
139 <  for(j=0; j<3; j++)
140 <    rj[j] = ( oldPos[index*3+j] + pos[j]) / 2.0 - COM[j];
141 <
142 <  matVecMul3( eta, rj, sc );
157 < }
158 <
159 < template<typename T> void NPTf<T>::scaleSimBox( void ){
160 <
161 <  int i,j,k;
162 <  double scaleMat[3][3];
139 >  int i;
140 >  int j;
141 >  int k;
142 >  Mat3x3d scaleMat;
143    double eta2ij;
144    double bigScale, smallScale, offDiagMax;
145 <  double hm[3][3], hmnew[3][3];
145 >  Mat3x3d hm;
146 >  Mat3x3d hmnew;
147  
148  
149  
# Line 183 | Line 164 | template<typename T> void NPTf<T>::scaleSimBox( void )
164  
165        eta2ij = 0.0;
166        for(k=0; k<3; k++){
167 <        eta2ij += eta[i][k] * eta[k][j];
167 >        eta2ij += eta(i, k) * eta(k, j);
168        }
169  
170 <      scaleMat[i][j] = 0.0;
170 >      scaleMat(i, j) = 0.0;
171        // identity matrix (see above):
172 <      if (i == j) scaleMat[i][j] = 1.0;
172 >      if (i == j) scaleMat(i, j) = 1.0;
173        // Taylor expansion for the exponential truncated at second order:
174 <      scaleMat[i][j] += dt*eta[i][j]  + 0.5*dt*dt*eta2ij;
174 >      scaleMat(i, j) += dt*eta(i, j)  + 0.5*dt*dt*eta2ij;
175        
176  
177        if (i != j)
178 <        if (fabs(scaleMat[i][j]) > offDiagMax)
179 <          offDiagMax = fabs(scaleMat[i][j]);
178 >        if (fabs(scaleMat(i, j)) > offDiagMax)
179 >          offDiagMax = fabs(scaleMat(i, j));
180      }
181  
182 <    if (scaleMat[i][i] > bigScale) bigScale = scaleMat[i][i];
183 <    if (scaleMat[i][i] < smallScale) smallScale = scaleMat[i][i];
182 >    if (scaleMat(i, i) > bigScale) bigScale = scaleMat(i, i);
183 >    if (scaleMat(i, i) < smallScale) smallScale = scaleMat(i, i);
184    }
185  
186    if ((bigScale > 1.01) || (smallScale < 0.99)) {
# Line 212 | Line 193 | template<typename T> void NPTf<T>::scaleSimBox( void )
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]);
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) {
# Line 230 | Line 211 | template<typename T> void NPTf<T>::scaleSimBox( void )
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]);
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 <    info->getBoxM(hm);
224 <    matMul3(hm, scaleMat, hmnew);
225 <    info->setBoxM(hmnew);
223 >
224 >        Mat3x3d hmat = currentSnapshot_->getHmat();
225 >        hmat = hmat *scaleMat;
226 >        currentSnapshot_->setHmat(hmat);
227 >        
228    }
229   }
230  
231 < template<typename T> bool NPTf<T>::etaConverged() {
232 <  int i;
233 <  double diffEta, sumEta;
231 > bool NPTf::etaConverged() {
232 >    int i;
233 >    double diffEta, sumEta;
234  
235 <  sumEta = 0;
236 <  for(i = 0; i < 3; i++)
237 <    sumEta += pow(prevEta[i][i] - eta[i][i], 2);
235 >    sumEta = 0;
236 >    for(i = 0; i < 3; i++) {
237 >        sumEta += pow(prevEta(i, i) - eta(i, i), 2);
238 >    }
239 >    
240 >    diffEta = sqrt( sumEta / 3.0 );
241  
242 <  diffEta = sqrt( sumEta / 3.0 );
257 <
258 <  return ( diffEta <= etaTolerance );
242 >    return ( diffEta <= etaTolerance );
243   }
244  
245 < template<typename T> double NPTf<T>::getConservedQuantity(void){
245 > double NPTf::calcConservedQuantity(){
246  
247 <  double conservedQuantity;
248 <  double totalEnergy;
249 <  double thermostat_kinetic;
250 <  double thermostat_potential;
251 <  double barostat_kinetic;
252 <  double barostat_potential;
253 <  double trEta;
254 <  double a[3][3], b[3][3];
247 >    chi= currentSnapshot_->getChi();
248 >    integralOfChidt = currentSnapshot_->getIntegralOfChiDt();
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;
255  
256 <  totalEnergy = tStats->getTotalE();
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;    
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;
268  
269 <  thermostat_kinetic = fkBT * tt2 * chi * chi /
275 <    (2.0 * eConvert);
269 >    totalEnergy = thermo.getTotalE();
270  
271 <  thermostat_potential = fkBT* integralOfChidt / eConvert;
271 >    thermostat_kinetic = fkBT * tt2 * chi * chi /(2.0 * OOPSEConstant::energyConvert);
272  
273 <  transposeMat3(eta, a);
280 <  matMul3(a, eta, b);
281 <  trEta = matTrace3(b);
273 >    thermostat_potential = fkBT* integralOfChidt / OOPSEConstant::energyConvert;
274  
275 <  barostat_kinetic = NkBT * tb2 * trEta /
276 <    (2.0 * eConvert);
275 >    SquareMatrix<double, 3> tmp = eta.transpose() * eta;
276 >    trEta = tmp.trace();
277 >    
278 >    barostat_kinetic = NkBT * tb2 * trEta /(2.0 * OOPSEConstant::energyConvert);
279  
280 <  barostat_potential = (targetPressure * tStats->getVolume() / p_convert) /
287 <    eConvert;
280 >    barostat_potential = (targetPressure * thermo.getVolume() / OOPSEConstant::pressureConvert) /OOPSEConstant::energyConvert;
281  
282 <  conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
283 <    barostat_kinetic + barostat_potential;
282 >    conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
283 >        barostat_kinetic + barostat_potential;
284  
285 <  return conservedQuantity;
285 >    return conservedQuantity;
286  
287   }
288  
289 < template<typename T> string NPTf<T>::getAdditionalParameters(void){
290 <  string parameters;
298 <  const int BUFFERSIZE = 2000; // size of the read buffer
299 <  char buffer[BUFFERSIZE];
289 > void NPTf::loadEta() {
290 >    eta= currentSnapshot_->getEta();
291  
292 <  sprintf(buffer,"\t%G\t%G;", chi, integralOfChidt);
293 <  parameters += buffer;
292 >    //if (!eta.isDiagonal()) {
293 >    //    sprintf( painCave.errMsg,
294 >    //             "NPTf error: the diagonal elements of eta matrix are not the same or etaMat is not a diagonal matrix");
295 >    //    painCave.isFatal = 1;
296 >    //    simError();
297 >    //}
298 > }
299  
300 <  for(int i = 0; i < 3; i++){
301 <    sprintf(buffer,"\t%G\t%G\t%G;", eta[i][0], eta[i][1], eta[i][2]);
302 <    parameters += buffer;
307 <  }
300 > void NPTf::saveEta() {
301 >    currentSnapshot_->setEta(eta);
302 > }
303  
309  return parameters;
310
304   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines