ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPTxyz.cpp
Revision: 847
Committed: Fri Oct 31 18:28:52 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 7382 byte(s)
Log Message:
added template stuff to the Maikefile template

little changes to some printf format statements

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