ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPTxyz.cpp
Revision: 855
Committed: Thu Nov 6 22:01:37 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 7400 byte(s)
Log Message:
added the following parameters to BASS:
   * useInitialExtendedSystemState
   * orthoBoxTolerance
   * useIntiTime => useInitialTime

File Contents

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