ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPTf.cpp
Revision: 782
Committed: Tue Sep 23 20:34:31 2003 UTC (20 years, 9 months ago) by mmeineke
File size: 6843 byte(s)
Log Message:
Removed NPTfm from Integrator.hpp.

Some small syntax cleaning in NPTfm and SimSetup

File Contents

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