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

File Contents

# Content
1 #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 double vScale[3][3];
144
145 for (j = 0; j < 3; j++)
146 myVel[j] = oldVel[3*index + j];
147
148 matVecMul3( vScale, myVel, sc );
149 }
150
151 template<typename T> void NPTf<T>::getPosScale(double pos[3], double COM[3],
152 int index, double sc[3]){
153 int j;
154 double rj[3];
155
156 for(j=0; j<3; j++)
157 rj[j] = ( oldPos[index*3+j] + pos[j]) / 2.0 - COM[j];
158
159 matVecMul3( eta, rj, sc );
160 }
161
162 template<typename T> void NPTf<T>::scaleSimBox( void ){
163
164 int i,j,k;
165 double scaleMat[3][3];
166 double eta2ij;
167 double bigScale, smallScale, offDiagMax;
168 double hm[3][3], hmnew[3][3];
169
170
171
172 // Scale the box after all the positions have been moved:
173
174 // Use a taylor expansion for eta products: Hmat = Hmat . exp(dt * etaMat)
175 // Hmat = Hmat . ( Ident + dt * etaMat + dt^2 * etaMat*etaMat / 2)
176
177 bigScale = 1.0;
178 smallScale = 1.0;
179 offDiagMax = 0.0;
180
181 for(i=0; i<3; i++){
182 for(j=0; j<3; j++){
183
184 // Calculate the matrix Product of the eta array (we only need
185 // the ij element right now):
186
187 eta2ij = 0.0;
188 for(k=0; k<3; k++){
189 eta2ij += eta[i][k] * eta[k][j];
190 }
191
192 scaleMat[i][j] = 0.0;
193 // identity matrix (see above):
194 if (i == j) scaleMat[i][j] = 1.0;
195 // Taylor expansion for the exponential truncated at second order:
196 scaleMat[i][j] += dt*eta[i][j] + 0.5*dt*dt*eta2ij;
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 scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
215 scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
216 scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
217 painCave.isFatal = 1;
218 simError();
219 } else if (offDiagMax > 0.01) {
220 sprintf( painCave.errMsg,
221 "NPTf error: Attempting an off-diagonal Box scaling of more than 1 percent.\n"
222 " Check your tauBarostat, as it is probably too small!\n\n"
223 " scaleMat = [%lf\t%lf\t%lf]\n"
224 " [%lf\t%lf\t%lf]\n"
225 " [%lf\t%lf\t%lf]\n",
226 scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
227 scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
228 scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
229 painCave.isFatal = 1;
230 simError();
231 } else {
232 info->getBoxM(hm);
233 matMul3(hm, scaleMat, hmnew);
234 info->setBoxM(hmnew);
235 }
236 }
237
238 template<typename T> bool NPTf<T>::etaConverged() {
239 int i;
240 double diffEta, sumEta;
241
242 sumEta = 0;
243 for(i = 0; i < 3; i++)
244 sumEta += pow(prevEta[i][i] - eta[i][i], 2);
245
246 diffEta = sqrt( sumEta / 3.0 );
247
248 return ( diffEta <= etaTolerance );
249 }
250
251 template<typename T> double NPTf<T>::getConservedQuantity(void){
252
253 double conservedQuantity;
254 double totalEnergy;
255 double thermostat_kinetic;
256 double thermostat_potential;
257 double barostat_kinetic;
258 double barostat_potential;
259 double trEta;
260 double a[3][3], b[3][3];
261
262 totalEnergy = tStats->getTotalE();
263
264 thermostat_kinetic = fkBT * tt2 * chi * chi /
265 (2.0 * eConvert);
266
267 thermostat_potential = fkBT* integralOfChidt / eConvert;
268
269 transposeMat3(eta, a);
270 matMul3(a, eta, b);
271 trEta = matTrace3(b);
272
273 barostat_kinetic = NkBT * tb2 * trEta /
274 (2.0 * eConvert);
275
276 barostat_potential = (targetPressure * tStats->getVolume() / p_convert) /
277 eConvert;
278
279 conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
280 barostat_kinetic + barostat_potential;
281
282 return conservedQuantity;
283
284 }
285
286 template<typename T> string NPTf<T>::getAdditionalParameters(void){
287 string parameters;
288 const int BUFFERSIZE = 2000; // size of the read buffer
289 char buffer[BUFFERSIZE];
290
291 sprintf(buffer,"\t%G\t%G;", chi, integralOfChidt);
292 parameters += buffer;
293
294 for(int i = 0; i < 3; i++){
295 sprintf(buffer,"\t%G\t%G\t%G;", eta[i][0], eta[i][1], eta[i][2]);
296 parameters += buffer;
297 }
298
299 return parameters;
300
301 }