ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/integrators/NPTf.cpp
Revision: 1701
Committed: Wed Nov 3 16:08:43 2004 UTC (19 years, 8 months ago) by tim
File size: 7754 byte(s)
Log Message:
mess up ......

File Contents

# Content
1 #include <math.h>
2
3 #include "math/MatVec3.h"
4 #include "primitives/Atom.hpp"
5 #include "primitives/SRI.hpp"
6 #include "primitives/AbstractClasses.hpp"
7 #include "brains/SimInfo.hpp"
8 #include "UseTheForce/ForceFields.hpp"
9 #include "brains/Thermo.hpp"
10 #include "io/ReadWrite.hpp"
11 #include "integrators/Integrator.hpp"
12 #include "utils/simError.h"
13
14 #ifdef IS_MPI
15 #include "brains/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 DoubleVectorGenericData * etaValue;
33 int i,j;
34
35 for(i = 0; i < 3; i++){
36 for (j = 0; j < 3; j++){
37
38 eta[i][j] = 0.0;
39 oldEta[i][j] = 0.0;
40 }
41 }
42
43
44 if( theInfo->useInitXSstate ){
45 // retrieve eta array from simInfo if it exists
46 data = info->getPropertyByName(ETAVALUE_ID);
47 if(data){
48 etaValue = dynamic_cast<DoubleVectorGenericData*>(data);
49
50 if(etaValue){
51
52 for(i = 0; i < 3; i++){
53 for (j = 0; j < 3; j++){
54 eta[i][j] = (*etaValue)[3*i+j];
55 oldEta[i][j] = eta[i][j];
56 }
57 }
58 }
59 }
60 }
61
62 }
63
64 template<typename T> NPTf<T>::~NPTf() {
65
66 // empty for now
67 }
68
69 template<typename T> void NPTf<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 NPTf<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] += dt2 * instaVol * press[i][j] / (NkBT*tb2);
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 NPTf<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] = oldEta[i][j] + dt2 * instaVol * press[i][j] / (NkBT*tb2);
114 }
115 }
116 }
117 }
118
119 template<typename T> void NPTf<T>::calcVelScale(void){
120 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
126 if (i == j) {
127 vScale[i][j] += chi;
128 }
129 }
130 }
131 }
132
133 template<typename T> void NPTf<T>::getVelScaleA(double sc[3], double vel[3]) {
134
135 matVecMul3( vScale, vel, sc );
136 }
137
138 template<typename T> void NPTf<T>::getVelScaleB(double sc[3], int index ){
139 int j;
140 double myVel[3];
141
142 for (j = 0; j < 3; j++)
143 myVel[j] = oldVel[3*index + j];
144
145 matVecMul3( vScale, myVel, sc );
146 }
147
148 template<typename T> void NPTf<T>::getPosScale(double pos[3], double COM[3],
149 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 matVecMul3( eta, rj, sc );
157 }
158
159 template<typename T> void NPTf<T>::scaleSimBox( void ){
160
161 int i,j,k;
162 double scaleMat[3][3];
163 double eta2ij;
164 double bigScale, smallScale, offDiagMax;
165 double hm[3][3], hmnew[3][3];
166
167
168
169 // Scale the box after all the positions have been moved:
170
171 // Use a taylor expansion for eta products: Hmat = Hmat . exp(dt * etaMat)
172 // Hmat = Hmat . ( Ident + dt * etaMat + dt^2 * etaMat*etaMat / 2)
173
174 bigScale = 1.0;
175 smallScale = 1.0;
176 offDiagMax = 0.0;
177
178 for(i=0; i<3; i++){
179 for(j=0; j<3; j++){
180
181 // Calculate the matrix Product of the eta array (we only need
182 // the ij element right now):
183
184 eta2ij = 0.0;
185 for(k=0; k<3; k++){
186 eta2ij += eta[i][k] * eta[k][j];
187 }
188
189 scaleMat[i][j] = 0.0;
190 // identity matrix (see above):
191 if (i == j) scaleMat[i][j] = 1.0;
192 // Taylor expansion for the exponential truncated at second order:
193 scaleMat[i][j] += dt*eta[i][j] + 0.5*dt*dt*eta2ij;
194
195
196 if (i != j)
197 if (fabs(scaleMat[i][j]) > offDiagMax)
198 offDiagMax = fabs(scaleMat[i][j]);
199 }
200
201 if (scaleMat[i][i] > bigScale) bigScale = scaleMat[i][i];
202 if (scaleMat[i][i] < smallScale) smallScale = scaleMat[i][i];
203 }
204
205 if ((bigScale > 1.01) || (smallScale < 0.99)) {
206 sprintf( painCave.errMsg,
207 "NPTf error: Attempting a Box scaling of more than 1 percent.\n"
208 " Check your tauBarostat, as it is probably too small!\n\n"
209 " scaleMat = [%lf\t%lf\t%lf]\n"
210 " [%lf\t%lf\t%lf]\n"
211 " [%lf\t%lf\t%lf]\n"
212 " eta = [%lf\t%lf\t%lf]\n"
213 " [%lf\t%lf\t%lf]\n"
214 " [%lf\t%lf\t%lf]\n",
215 scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
216 scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
217 scaleMat[2][0],scaleMat[2][1],scaleMat[2][2],
218 eta[0][0],eta[0][1],eta[0][2],
219 eta[1][0],eta[1][1],eta[1][2],
220 eta[2][0],eta[2][1],eta[2][2]);
221 painCave.isFatal = 1;
222 simError();
223 } else if (offDiagMax > 0.01) {
224 sprintf( painCave.errMsg,
225 "NPTf error: Attempting an off-diagonal Box scaling of more than 1 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 " eta = [%lf\t%lf\t%lf]\n"
231 " [%lf\t%lf\t%lf]\n"
232 " [%lf\t%lf\t%lf]\n",
233 scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
234 scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
235 scaleMat[2][0],scaleMat[2][1],scaleMat[2][2],
236 eta[0][0],eta[0][1],eta[0][2],
237 eta[1][0],eta[1][1],eta[1][2],
238 eta[2][0],eta[2][1],eta[2][2]);
239 painCave.isFatal = 1;
240 simError();
241 } else {
242 info->getBoxM(hm);
243 matMul3(hm, scaleMat, hmnew);
244 info->setBoxM(hmnew);
245 }
246 }
247
248 template<typename T> bool NPTf<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 NPTf<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 transposeMat3(eta, a);
280 matMul3(a, eta, b);
281 trEta = 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 return conservedQuantity;
293
294 }
295
296 template<typename T> string NPTf<T>::getAdditionalParameters(void){
297 string parameters;
298 const int BUFFERSIZE = 2000; // size of the read buffer
299 char buffer[BUFFERSIZE];
300
301 sprintf(buffer,"\t%G\t%G;", chi, integralOfChidt);
302 parameters += buffer;
303
304 for(int i = 0; i < 3; i++){
305 sprintf(buffer,"\t%G\t%G\t%G;", eta[i][0], eta[i][1], eta[i][2]);
306 parameters += buffer;
307 }
308
309 return parameters;
310
311 }