ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/integrators/NPTi.cpp
Revision: 1907
Committed: Thu Jan 6 22:31:07 2005 UTC (21 years, 5 months ago) by tim
File size: 4082 byte(s)
Log Message:
constraint is almost working

File Contents

# User Rev Content
1 tim 1822 #include "NPTi.hpp"
2 tim 1492 #include "brains/SimInfo.hpp"
3     #include "brains/Thermo.hpp"
4 tim 1837 #include "integrators/IntegratorCreator.hpp"
5 tim 1822 #include "integrators/NPT.hpp"
6     #include "primitives/Molecule.hpp"
7     #include "utils/OOPSEConstant.hpp"
8 tim 1492 #include "utils/simError.h"
9 gezelter 1490
10 tim 1822 namespace oopse {
11 gezelter 1490
12     // Basic isotropic thermostating and barostating via the Melchionna
13     // modification of the Hoover algorithm:
14     //
15     // Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
16     // Molec. Phys., 78, 533.
17     //
18     // and
19     //
20     // Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
21    
22 tim 1822 NPTi::NPTi ( SimInfo *info) : NPT(info){
23 gezelter 1490
24     }
25    
26 tim 1774 void NPTi::evolveEtaA() {
27 tim 1822 eta += dt2 * ( instaVol * (instaPress - targetPressure) /
28     (OOPSEConstant::pressureConvert*NkBT*tb2));
29     oldEta = eta;
30 gezelter 1490 }
31    
32 tim 1774 void NPTi::evolveEtaB() {
33 gezelter 1490
34 tim 1822 prevEta = eta;
35     eta = oldEta + dt2 * ( instaVol * (instaPress - targetPressure) /
36     (OOPSEConstant::pressureConvert*NkBT*tb2));
37 gezelter 1490 }
38    
39 tim 1774 void NPTi::calcVelScale() {
40 tim 1822 vScale = chi + eta;
41 gezelter 1490 }
42    
43 tim 1774 void NPTi::getVelScaleA(Vector3d& sc, const Vector3d& vel) {
44     sc = vel * vScale;
45 gezelter 1490 }
46    
47 tim 1774 void NPTi::getVelScaleB(Vector3d& sc, int index ){
48     sc = oldVel[index] * vScale;
49 gezelter 1490 }
50    
51    
52 tim 1774 void NPTi::getPosScale(const Vector3d& pos, const Vector3d& COM,
53 tim 1822 int index, Vector3d& sc){
54 tim 1774 /**@todo*/
55 tim 1897 sc = (oldPos[index] + pos)/2.0 -COM;
56 tim 1774 sc *= eta;
57 gezelter 1490 }
58    
59 tim 1774 void NPTi::scaleSimBox(){
60 gezelter 1490
61 tim 1822 double scaleFactor;
62 gezelter 1490
63 tim 1822 scaleFactor = exp(dt*eta);
64 gezelter 1490
65 tim 1822 if ((scaleFactor > 1.1) || (scaleFactor < 0.9)) {
66     sprintf( painCave.errMsg,
67 gezelter 1490 "NPTi error: Attempting a Box scaling of more than 10 percent"
68     " check your tauBarostat, as it is probably too small!\n"
69     " eta = %lf, scaleFactor = %lf\n", eta, scaleFactor
70     );
71 tim 1822 painCave.isFatal = 1;
72     simError();
73     } else {
74     Mat3x3d hmat = currentSnapshot_->getHmat();
75     hmat *= scaleFactor;
76     currentSnapshot_->setHmat(hmat);
77     }
78 gezelter 1490
79     }
80    
81 tim 1774 bool NPTi::etaConverged() {
82 gezelter 1490
83 tim 1822 return ( fabs(prevEta - eta) <= etaTolerance );
84 gezelter 1490 }
85    
86 tim 1774 double NPTi::calcConservedQuantity(){
87 gezelter 1490
88 tim 1867 chi= currentSnapshot_->getChi();
89     integralOfChidt = currentSnapshot_->getIntegralOfChiDt();
90     loadEta();
91     // We need NkBT a lot, so just set it here: This is the RAW number
92     // of integrableObjects, so no subtraction or addition of constraints or
93     // orientational degrees of freedom:
94     NkBT = info_->getNGlobalIntegrableObjects()*OOPSEConstant::kB *targetTemp;
95    
96     // fkBT is used because the thermostat operates on more degrees of freedom
97     // than the barostat (when there are particles with orientational degrees
98     // of freedom).
99     fkBT = info_->getNdf()*OOPSEConstant::kB *targetTemp;
100    
101 tim 1822 double conservedQuantity;
102     double Energy;
103     double thermostat_kinetic;
104     double thermostat_potential;
105     double barostat_kinetic;
106     double barostat_potential;
107 gezelter 1490
108 tim 1822 Energy =thermo.getTotalE();
109 gezelter 1490
110 tim 1822 thermostat_kinetic = fkBT* tt2 * chi * chi / (2.0 * OOPSEConstant::energyConvert);
111 gezelter 1490
112 tim 1822 thermostat_potential = fkBT* integralOfChidt / OOPSEConstant::energyConvert;
113 gezelter 1490
114    
115 tim 1822 barostat_kinetic = 3.0 * NkBT * tb2 * eta * eta /(2.0 * OOPSEConstant::energyConvert);
116 gezelter 1490
117 tim 1822 barostat_potential = (targetPressure * thermo.getVolume() / OOPSEConstant::pressureConvert) /
118     OOPSEConstant::energyConvert;
119 gezelter 1490
120 tim 1822 conservedQuantity = Energy + thermostat_kinetic + thermostat_potential +
121     barostat_kinetic + barostat_potential;
122 tim 1907
123 tim 1822 return conservedQuantity;
124 gezelter 1490 }
125    
126 tim 1822 void NPTi::loadEta() {
127     Mat3x3d etaMat = currentSnapshot_->getEta();
128     eta = etaMat(0,0);
129 tim 1883 //if (fabs(etaMat(1,1) - eta) >= oopse::epsilon || fabs(etaMat(1,1) - eta) >= oopse::epsilon || !etaMat.isDiagonal()) {
130     // sprintf( painCave.errMsg,
131     // "NPTi error: the diagonal elements of eta matrix are not the same or etaMat is not a diagonal matrix");
132     // painCave.isFatal = 1;
133     // simError();
134     //}
135 tim 1822 }
136    
137     void NPTi::saveEta() {
138     Mat3x3d etaMat(0.0);
139     etaMat(0, 0) = eta;
140     etaMat(1, 1) = eta;
141     etaMat(2, 2) = eta;
142     currentSnapshot_->setEta(etaMat);
143     }
144    
145     }