ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPTf.cpp
Revision: 1097
Committed: Mon Apr 12 20:32:20 2004 UTC (20 years, 2 months ago) by gezelter
File size: 7175 byte(s)
Log Message:
Changes for RigidBody dynamics (Somewhat extensive)

File Contents

# User Rev Content
1 gezelter 829 #include <math.h>
2 mmeineke 857
3 gezelter 1097 #include "MatVec3.h"
4 gezelter 576 #include "Atom.hpp"
5     #include "SRI.hpp"
6     #include "AbstractClasses.hpp"
7     #include "SimInfo.hpp"
8     #include "ForceFields.hpp"
9     #include "Thermo.hpp"
10     #include "ReadWrite.hpp"
11     #include "Integrator.hpp"
12 tim 837 #include "simError.h"
13 gezelter 576
14 gezelter 772 #ifdef IS_MPI
15     #include "mpiSimulation.hpp"
16     #endif
17 gezelter 576
18 gezelter 578 // Basic non-isotropic thermostating and barostating via the Melchionna
19 gezelter 576 // modification of the Hoover algorithm:
20     //
21     // Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
22 tim 837 // Molec. Phys., 78, 533.
23 gezelter 576 //
24     // and
25 tim 837 //
26 gezelter 576 // Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
27    
28 tim 645 template<typename T> NPTf<T>::NPTf ( SimInfo *theInfo, ForceFields* the_ff):
29     T( theInfo, the_ff )
30 gezelter 576 {
31 tim 837 GenericData* data;
32     DoubleArrayData * etaValue;
33     vector<double> etaArray;
34 mmeineke 780 int i,j;
35 tim 837
36 mmeineke 780 for(i = 0; i < 3; i++){
37     for (j = 0; j < 3; j++){
38 tim 837
39 gezelter 588 eta[i][j] = 0.0;
40 mmeineke 780 oldEta[i][j] = 0.0;
41     }
42     }
43 tim 837
44 mmeineke 855
45     if( theInfo->useInitXSstate ){
46 tim 837 // retrieve eta array from simInfo if it exists
47     data = info->getProperty(ETAVALUE_ID);
48     if(data){
49     etaValue = dynamic_cast<DoubleArrayData*>(data);
50 mmeineke 855
51 tim 837 if(etaValue){
52 mmeineke 855 etaArray = etaValue->getData();
53    
54     for(i = 0; i < 3; i++){
55     for (j = 0; j < 3; j++){
56     eta[i][j] = etaArray[3*i+j];
57     oldEta[i][j] = eta[i][j];
58     }
59     }
60 tim 837 }
61     }
62 mmeineke 855 }
63 tim 837
64 mmeineke 780 }
65 gezelter 588
66 mmeineke 780 template<typename T> NPTf<T>::~NPTf() {
67 tim 767
68 mmeineke 780 // empty for now
69     }
70 tim 767
71 mmeineke 780 template<typename T> void NPTf<T>::resetIntegrator() {
72 tim 837
73 mmeineke 780 int i, j;
74 tim 837
75 mmeineke 780 for(i = 0; i < 3; i++)
76     for (j = 0; j < 3; j++)
77     eta[i][j] = 0.0;
78 tim 837
79 mmeineke 780 T::resetIntegrator();
80 gezelter 576 }
81    
82 mmeineke 780 template<typename T> void NPTf<T>::evolveEtaA() {
83 tim 837
84 mmeineke 780 int i, j;
85 tim 837
86 mmeineke 780 for(i = 0; i < 3; i ++){
87     for(j = 0; j < 3; j++){
88     if( i == j)
89 tim 837 eta[i][j] += dt2 * instaVol *
90 mmeineke 780 (press[i][j] - targetPressure/p_convert) / (NkBT*tb2);
91     else
92     eta[i][j] += dt2 * instaVol * press[i][j] / (NkBT*tb2);
93     }
94     }
95 tim 837
96 mmeineke 780 for(i = 0; i < 3; i++)
97     for (j = 0; j < 3; j++)
98     oldEta[i][j] = eta[i][j];
99 tim 767 }
100    
101 mmeineke 780 template<typename T> void NPTf<T>::evolveEtaB() {
102 tim 837
103 mmeineke 780 int i,j;
104 gezelter 772
105 mmeineke 780 for(i = 0; i < 3; i++)
106     for (j = 0; j < 3; j++)
107     prevEta[i][j] = eta[i][j];
108 mmeineke 778
109 mmeineke 780 for(i = 0; i < 3; i ++){
110     for(j = 0; j < 3; j++){
111     if( i == j) {
112 tim 837 eta[i][j] = oldEta[i][j] + dt2 * instaVol *
113 mmeineke 780 (press[i][j] - targetPressure/p_convert) / (NkBT*tb2);
114     } else {
115     eta[i][j] = oldEta[i][j] + dt2 * instaVol * press[i][j] / (NkBT*tb2);
116     }
117     }
118     }
119     }
120 gezelter 600
121 mmeineke 857 template<typename T> void NPTf<T>::calcVelScale(void){
122 mmeineke 780 int i,j;
123 gezelter 576
124 gezelter 588 for (i = 0; i < 3; i++ ) {
125     for (j = 0; j < 3; j++ ) {
126 tim 767 vScale[i][j] = eta[i][j];
127 tim 837
128 gezelter 588 if (i == j) {
129 tim 837 vScale[i][j] += chi;
130     }
131 gezelter 588 }
132     }
133 mmeineke 857 }
134 tim 837
135 mmeineke 857 template<typename T> void NPTf<T>::getVelScaleA(double sc[3], double vel[3]) {
136    
137 gezelter 1097 matVecMul3( vScale, vel, sc );
138 mmeineke 780 }
139 gezelter 600
140 mmeineke 780 template<typename T> void NPTf<T>::getVelScaleB(double sc[3], int index ){
141 mmeineke 857 int j;
142 mmeineke 780 double myVel[3];
143     double vScale[3][3];
144 gezelter 600
145 mmeineke 780 for (j = 0; j < 3; j++)
146     myVel[j] = oldVel[3*index + j];
147 tim 767
148 gezelter 1097 matVecMul3( vScale, myVel, sc );
149 mmeineke 780 }
150 tim 767
151 tim 837 template<typename T> void NPTf<T>::getPosScale(double pos[3], double COM[3],
152 mmeineke 780 int index, double sc[3]){
153     int j;
154     double rj[3];
155 tim 767
156 mmeineke 780 for(j=0; j<3; j++)
157     rj[j] = ( oldPos[index*3+j] + pos[j]) / 2.0 - COM[j];
158 tim 767
159 gezelter 1097 matVecMul3( eta, rj, sc );
160 mmeineke 780 }
161 tim 767
162 mmeineke 780 template<typename T> void NPTf<T>::scaleSimBox( void ){
163 tim 767
164 mmeineke 780 int i,j,k;
165     double scaleMat[3][3];
166     double eta2ij;
167     double bigScale, smallScale, offDiagMax;
168     double hm[3][3], hmnew[3][3];
169 tim 767
170 mmeineke 780
171 tim 837
172 gezelter 577 // Scale the box after all the positions have been moved:
173 tim 837
174 gezelter 578 // Use a taylor expansion for eta products: Hmat = Hmat . exp(dt * etaMat)
175     // Hmat = Hmat . ( Ident + dt * etaMat + dt^2 * etaMat*etaMat / 2)
176 tim 837
177 gezelter 617 bigScale = 1.0;
178     smallScale = 1.0;
179     offDiagMax = 0.0;
180 tim 837
181 gezelter 578 for(i=0; i<3; i++){
182     for(j=0; j<3; j++){
183 tim 837
184 gezelter 588 // Calculate the matrix Product of the eta array (we only need
185     // the ij element right now):
186 tim 837
187 gezelter 588 eta2ij = 0.0;
188 gezelter 578 for(k=0; k<3; k++){
189 gezelter 588 eta2ij += eta[i][k] * eta[k][j];
190 gezelter 578 }
191 tim 837
192 gezelter 588 scaleMat[i][j] = 0.0;
193     // identity matrix (see above):
194     if (i == j) scaleMat[i][j] = 1.0;
195     // Taylor expansion for the exponential truncated at second order:
196     scaleMat[i][j] += dt*eta[i][j] + 0.5*dt*dt*eta2ij;
197 gezelter 617
198     if (i != j)
199 tim 837 if (fabs(scaleMat[i][j]) > offDiagMax)
200 gezelter 617 offDiagMax = fabs(scaleMat[i][j]);
201 gezelter 578 }
202 gezelter 617
203     if (scaleMat[i][i] > bigScale) bigScale = scaleMat[i][i];
204     if (scaleMat[i][i] < smallScale) smallScale = scaleMat[i][i];
205 gezelter 578 }
206 tim 837
207 mmeineke 853 if ((bigScale > 1.01) || (smallScale < 0.99)) {
208 gezelter 617 sprintf( painCave.errMsg,
209 mmeineke 853 "NPTf error: Attempting a Box scaling of more than 1 percent.\n"
210 gezelter 617 " Check your tauBarostat, as it is probably too small!\n\n"
211     " scaleMat = [%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     painCave.isFatal = 1;
218     simError();
219 mmeineke 853 } else if (offDiagMax > 0.01) {
220 gezelter 617 sprintf( painCave.errMsg,
221 mmeineke 853 "NPTf error: Attempting an off-diagonal Box scaling of more than 1 percent.\n"
222 gezelter 617 " Check your tauBarostat, as it is probably too small!\n\n"
223     " scaleMat = [%lf\t%lf\t%lf]\n"
224     " [%lf\t%lf\t%lf]\n"
225     " [%lf\t%lf\t%lf]\n",
226     scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
227     scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
228     scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
229     painCave.isFatal = 1;
230     simError();
231     } else {
232     info->getBoxM(hm);
233 gezelter 1097 matMul3(hm, scaleMat, hmnew);
234 gezelter 617 info->setBoxM(hmnew);
235     }
236 gezelter 576 }
237    
238 mmeineke 780 template<typename T> bool NPTf<T>::etaConverged() {
239     int i;
240     double diffEta, sumEta;
241 gezelter 600
242 mmeineke 780 sumEta = 0;
243 tim 767 for(i = 0; i < 3; i++)
244 tim 837 sumEta += pow(prevEta[i][i] - eta[i][i], 2);
245    
246 mmeineke 780 diffEta = sqrt( sumEta / 3.0 );
247 tim 837
248 mmeineke 780 return ( diffEta <= etaTolerance );
249 gezelter 576 }
250    
251 mmeineke 780 template<typename T> double NPTf<T>::getConservedQuantity(void){
252 tim 837
253 tim 763 double conservedQuantity;
254 mmeineke 782 double totalEnergy;
255 gezelter 772 double thermostat_kinetic;
256     double thermostat_potential;
257     double barostat_kinetic;
258     double barostat_potential;
259     double trEta;
260     double a[3][3], b[3][3];
261 tim 763
262 mmeineke 782 totalEnergy = tStats->getTotalE();
263 tim 763
264 tim 837 thermostat_kinetic = fkBT * tt2 * chi * chi /
265 gezelter 772 (2.0 * eConvert);
266 tim 763
267 gezelter 772 thermostat_potential = fkBT* integralOfChidt / eConvert;
268 tim 763
269 gezelter 1097 transposeMat3(eta, a);
270     matMul3(a, eta, b);
271     trEta = matTrace3(b);
272 tim 767
273 tim 837 barostat_kinetic = NkBT * tb2 * trEta /
274 gezelter 772 (2.0 * eConvert);
275 tim 837
276     barostat_potential = (targetPressure * tStats->getVolume() / p_convert) /
277 gezelter 772 eConvert;
278 tim 767
279 mmeineke 782 conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
280 gezelter 772 barostat_kinetic + barostat_potential;
281 tim 837
282     return conservedQuantity;
283    
284 tim 763 }
285 tim 837
286     template<typename T> string NPTf<T>::getAdditionalParameters(void){
287     string parameters;
288     const int BUFFERSIZE = 2000; // size of the read buffer
289     char buffer[BUFFERSIZE];
290    
291 mmeineke 853 sprintf(buffer,"\t%G\t%G;", chi, integralOfChidt);
292 tim 837 parameters += buffer;
293    
294     for(int i = 0; i < 3; i++){
295 mmeineke 853 sprintf(buffer,"\t%G\t%G\t%G;", eta[i][0], eta[i][1], eta[i][2]);
296 tim 837 parameters += buffer;
297     }
298    
299     return parameters;
300    
301     }