ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/integrators/NPTi.cpp
Revision: 1913
Committed: Mon Jan 10 22:04:20 2005 UTC (21 years, 5 months ago) by tim
File size: 4037 byte(s)
Log Message:
create a register module to register force fields, integrators and minimizers

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