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

File Contents

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