ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPTxyz.cpp
Revision: 857
Committed: Fri Nov 7 17:09:48 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 7251 byte(s)
Log Message:
moved the velocity scale matrix calculation outside of the atom loop in the NPT family of integrators.

File Contents

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