ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-1.0/libmdtools/NPTf.cpp
Revision: 1334
Committed: Fri Jul 16 18:58:03 2004 UTC (19 years, 11 months ago) by gezelter
File size: 7697 byte(s)
Log Message:
Initial import of OOPSE-1.0 source tree

File Contents

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