ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new-templateless/OOPSE/libmdtools/NPTf.cpp
Revision: 850
Committed: Mon Nov 3 22:07:17 2003 UTC (21 years, 8 months ago) by mmeineke
File size: 7406 byte(s)
Log Message:
begun work on removing templates and most of standard template library from OOPSE.

File Contents

# User Rev Content
1 mmeineke 850 #include <stdlib.h>
2 gezelter 829 #include <math.h>
3 mmeineke 850
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 mmeineke 849 NPTf::NPTf ( SimInfo *theInfo, ForceFields* the_ff):
29 mmeineke 850 NPT( theInfo, the_ff )
30 gezelter 576 {
31 tim 837 GenericData* data;
32 mmeineke 850 double *etaArray;
33 mmeineke 780 int i,j;
34 tim 837
35 mmeineke 780 for(i = 0; i < 3; i++){
36     for (j = 0; j < 3; j++){
37 tim 837
38 gezelter 588 eta[i][j] = 0.0;
39 mmeineke 780 oldEta[i][j] = 0.0;
40     }
41     }
42 tim 837
43 mmeineke 850 // retrieve eta array from simInfo if it exists
44     data = info->getProperty(ETAVALUE_ID);
45     if(data != NULL){
46    
47     int test = data->getDarray(etaArray);
48    
49     if( test == 9 ){
50    
51     for(i = 0; i < 3; i++){
52     for (j = 0; j < 3; j++){
53     eta[i][j] = etaArray[3*i+j];
54     oldEta[i][j] = eta[i][j];
55     }
56     }
57     delete[] etaArray;
58 tim 837 }
59 mmeineke 850 else
60     std::cerr << "NPTf error: etaArray is not length 9 (actual = " << test
61     << ").\n"
62     << " Simulation wil proceed with eta = 0;\n";
63     }
64 mmeineke 780 }
65 gezelter 588
66 mmeineke 849 NPTf::~NPTf() {
67 tim 767
68 mmeineke 780 // empty for now
69     }
70 tim 767
71 mmeineke 849 void NPTf::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 850 NPT::resetIntegrator();
80 gezelter 576 }
81    
82 mmeineke 849 void NPTf::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 849 void NPTf::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 849 void NPTf::getVelScaleA(double sc[3], double vel[3]) {
122 mmeineke 780 int i,j;
123     double vScale[3][3];
124 gezelter 576
125 gezelter 588 for (i = 0; i < 3; i++ ) {
126     for (j = 0; j < 3; j++ ) {
127 tim 767 vScale[i][j] = eta[i][j];
128 tim 837
129 gezelter 588 if (i == j) {
130 tim 837 vScale[i][j] += chi;
131     }
132 gezelter 588 }
133     }
134 tim 837
135 mmeineke 780 info->matVecMul3( vScale, vel, sc );
136     }
137 gezelter 600
138 mmeineke 849 void NPTf::getVelScaleB(double sc[3], int index ){
139 mmeineke 780 int i,j;
140     double myVel[3];
141     double vScale[3][3];
142 gezelter 600
143 mmeineke 780 for (i = 0; i < 3; i++ ) {
144     for (j = 0; j < 3; j++ ) {
145     vScale[i][j] = eta[i][j];
146 tim 837
147 mmeineke 780 if (i == j) {
148 tim 837 vScale[i][j] += chi;
149     }
150 tim 767 }
151     }
152 tim 837
153 mmeineke 780 for (j = 0; j < 3; j++)
154     myVel[j] = oldVel[3*index + j];
155 tim 767
156 mmeineke 780 info->matVecMul3( vScale, myVel, sc );
157     }
158 tim 767
159 mmeineke 849 void NPTf::getPosScale(double pos[3], double COM[3],
160 mmeineke 780 int index, double sc[3]){
161     int j;
162     double rj[3];
163 tim 767
164 mmeineke 780 for(j=0; j<3; j++)
165     rj[j] = ( oldPos[index*3+j] + pos[j]) / 2.0 - COM[j];
166 tim 767
167 mmeineke 780 info->matVecMul3( eta, rj, sc );
168     }
169 tim 767
170 mmeineke 849 void NPTf::scaleSimBox( void ){
171 tim 767
172 mmeineke 780 int i,j,k;
173     double scaleMat[3][3];
174     double eta2ij;
175     double bigScale, smallScale, offDiagMax;
176     double hm[3][3], hmnew[3][3];
177 tim 767
178 mmeineke 780
179 tim 837
180 gezelter 577 // Scale the box after all the positions have been moved:
181 tim 837
182 gezelter 578 // Use a taylor expansion for eta products: Hmat = Hmat . exp(dt * etaMat)
183     // Hmat = Hmat . ( Ident + dt * etaMat + dt^2 * etaMat*etaMat / 2)
184 tim 837
185 gezelter 617 bigScale = 1.0;
186     smallScale = 1.0;
187     offDiagMax = 0.0;
188 tim 837
189 gezelter 578 for(i=0; i<3; i++){
190     for(j=0; j<3; j++){
191 tim 837
192 gezelter 588 // Calculate the matrix Product of the eta array (we only need
193     // the ij element right now):
194 tim 837
195 gezelter 588 eta2ij = 0.0;
196 gezelter 578 for(k=0; k<3; k++){
197 gezelter 588 eta2ij += eta[i][k] * eta[k][j];
198 gezelter 578 }
199 tim 837
200 gezelter 588 scaleMat[i][j] = 0.0;
201     // identity matrix (see above):
202     if (i == j) scaleMat[i][j] = 1.0;
203     // Taylor expansion for the exponential truncated at second order:
204     scaleMat[i][j] += dt*eta[i][j] + 0.5*dt*dt*eta2ij;
205 gezelter 617
206     if (i != j)
207 tim 837 if (fabs(scaleMat[i][j]) > offDiagMax)
208 gezelter 617 offDiagMax = fabs(scaleMat[i][j]);
209 gezelter 578 }
210 gezelter 617
211     if (scaleMat[i][i] > bigScale) bigScale = scaleMat[i][i];
212     if (scaleMat[i][i] < smallScale) smallScale = scaleMat[i][i];
213 gezelter 578 }
214 tim 837
215 gezelter 617 if ((bigScale > 1.1) || (smallScale < 0.9)) {
216     sprintf( painCave.errMsg,
217     "NPTf error: Attempting a Box scaling of more than 10 percent.\n"
218     " Check your tauBarostat, as it is probably too small!\n\n"
219     " scaleMat = [%lf\t%lf\t%lf]\n"
220     " [%lf\t%lf\t%lf]\n"
221     " [%lf\t%lf\t%lf]\n",
222     scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
223     scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
224     scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
225     painCave.isFatal = 1;
226     simError();
227     } else if (offDiagMax > 0.1) {
228     sprintf( painCave.errMsg,
229     "NPTf error: Attempting an off-diagonal Box scaling of more than 10 percent.\n"
230     " Check your tauBarostat, as it is probably too small!\n\n"
231     " scaleMat = [%lf\t%lf\t%lf]\n"
232     " [%lf\t%lf\t%lf]\n"
233     " [%lf\t%lf\t%lf]\n",
234     scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
235     scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
236     scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
237     painCave.isFatal = 1;
238     simError();
239     } else {
240     info->getBoxM(hm);
241     info->matMul3(hm, scaleMat, hmnew);
242     info->setBoxM(hmnew);
243     }
244 gezelter 576 }
245    
246 mmeineke 849 bool NPTf::etaConverged() {
247 mmeineke 780 int i;
248     double diffEta, sumEta;
249 gezelter 600
250 mmeineke 780 sumEta = 0;
251 tim 767 for(i = 0; i < 3; i++)
252 tim 837 sumEta += pow(prevEta[i][i] - eta[i][i], 2);
253    
254 mmeineke 780 diffEta = sqrt( sumEta / 3.0 );
255 tim 837
256 mmeineke 780 return ( diffEta <= etaTolerance );
257 gezelter 576 }
258    
259 mmeineke 849 double NPTf::getConservedQuantity(void){
260 tim 837
261 tim 763 double conservedQuantity;
262 mmeineke 782 double totalEnergy;
263 gezelter 772 double thermostat_kinetic;
264     double thermostat_potential;
265     double barostat_kinetic;
266     double barostat_potential;
267     double trEta;
268     double a[3][3], b[3][3];
269 tim 763
270 mmeineke 782 totalEnergy = tStats->getTotalE();
271 tim 763
272 tim 837 thermostat_kinetic = fkBT * tt2 * chi * chi /
273 gezelter 772 (2.0 * eConvert);
274 tim 763
275 gezelter 772 thermostat_potential = fkBT* integralOfChidt / eConvert;
276 tim 763
277 gezelter 772 info->transposeMat3(eta, a);
278     info->matMul3(a, eta, b);
279     trEta = info->matTrace3(b);
280 tim 767
281 tim 837 barostat_kinetic = NkBT * tb2 * trEta /
282 gezelter 772 (2.0 * eConvert);
283 tim 837
284     barostat_potential = (targetPressure * tStats->getVolume() / p_convert) /
285 gezelter 772 eConvert;
286 tim 767
287 mmeineke 782 conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
288 gezelter 772 barostat_kinetic + barostat_potential;
289 tim 837
290 mmeineke 780 // cout.width(8);
291     // cout.precision(8);
292 tim 767
293 tim 837 // cerr << info->getTime() << "\t" << Energy << "\t" << thermostat_kinetic <<
294     // "\t" << thermostat_potential << "\t" << barostat_kinetic <<
295 mmeineke 780 // "\t" << barostat_potential << "\t" << conservedQuantity << endl;
296 gezelter 772
297 tim 837 return conservedQuantity;
298    
299 tim 763 }
300 tim 837
301 mmeineke 849 string NPTf::getAdditionalParameters(void){
302 tim 837 string parameters;
303     const int BUFFERSIZE = 2000; // size of the read buffer
304     char buffer[BUFFERSIZE];
305    
306 mmeineke 847 sprintf(buffer,"\t%lf\t%lf;", chi, integralOfChidt);
307 tim 837 parameters += buffer;
308    
309     for(int i = 0; i < 3; i++){
310 mmeineke 847 sprintf(buffer,"\t%lf\t%lf\t%lf;", eta[3*i], eta[3*i+1], eta[3*i+2]);
311 tim 837 parameters += buffer;
312     }
313    
314     return parameters;
315    
316     }