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

File Contents

# User Rev Content
1 gezelter 829 #include <math.h>
2 gezelter 576 #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 tim 837 #include "simError.h"
11 gezelter 576
12 gezelter 772 #ifdef IS_MPI
13     #include "mpiSimulation.hpp"
14     #endif
15 gezelter 576
16 gezelter 578 // Basic non-isotropic thermostating and barostating via the Melchionna
17 gezelter 576 // modification of the Hoover algorithm:
18     //
19     // Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
20 tim 837 // Molec. Phys., 78, 533.
21 gezelter 576 //
22     // and
23 tim 837 //
24 gezelter 576 // Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
25    
26 tim 645 template<typename T> NPTf<T>::NPTf ( SimInfo *theInfo, ForceFields* the_ff):
27     T( theInfo, the_ff )
28 gezelter 576 {
29 tim 837 GenericData* data;
30     DoubleArrayData * etaValue;
31     vector<double> etaArray;
32 mmeineke 780 int i,j;
33 tim 837
34 mmeineke 780 for(i = 0; i < 3; i++){
35     for (j = 0; j < 3; j++){
36 tim 837
37 gezelter 588 eta[i][j] = 0.0;
38 mmeineke 780 oldEta[i][j] = 0.0;
39     }
40     }
41 tim 837
42 mmeineke 855
43     if( theInfo->useInitXSstate ){
44 tim 837 // retrieve eta array from simInfo if it exists
45     data = info->getProperty(ETAVALUE_ID);
46     if(data){
47     etaValue = dynamic_cast<DoubleArrayData*>(data);
48 mmeineke 855
49 tim 837 if(etaValue){
50 mmeineke 855 etaArray = etaValue->getData();
51    
52     for(i = 0; i < 3; i++){
53     for (j = 0; j < 3; j++){
54     eta[i][j] = etaArray[3*i+j];
55     oldEta[i][j] = eta[i][j];
56     }
57     }
58 tim 837 }
59     }
60 mmeineke 855 }
61 tim 837
62 mmeineke 780 }
63 gezelter 588
64 mmeineke 780 template<typename T> NPTf<T>::~NPTf() {
65 tim 767
66 mmeineke 780 // empty for now
67     }
68 tim 767
69 mmeineke 780 template<typename T> void NPTf<T>::resetIntegrator() {
70 tim 837
71 mmeineke 780 int i, j;
72 tim 837
73 mmeineke 780 for(i = 0; i < 3; i++)
74     for (j = 0; j < 3; j++)
75     eta[i][j] = 0.0;
76 tim 837
77 mmeineke 780 T::resetIntegrator();
78 gezelter 576 }
79    
80 mmeineke 780 template<typename T> void NPTf<T>::evolveEtaA() {
81 tim 837
82 mmeineke 780 int i, j;
83 tim 837
84 mmeineke 780 for(i = 0; i < 3; i ++){
85     for(j = 0; j < 3; j++){
86     if( i == j)
87 tim 837 eta[i][j] += dt2 * instaVol *
88 mmeineke 780 (press[i][j] - targetPressure/p_convert) / (NkBT*tb2);
89     else
90     eta[i][j] += dt2 * instaVol * press[i][j] / (NkBT*tb2);
91     }
92     }
93 tim 837
94 mmeineke 780 for(i = 0; i < 3; i++)
95     for (j = 0; j < 3; j++)
96     oldEta[i][j] = eta[i][j];
97 tim 767 }
98    
99 mmeineke 780 template<typename T> void NPTf<T>::evolveEtaB() {
100 tim 837
101 mmeineke 780 int i,j;
102 gezelter 772
103 mmeineke 780 for(i = 0; i < 3; i++)
104     for (j = 0; j < 3; j++)
105     prevEta[i][j] = eta[i][j];
106 mmeineke 778
107 mmeineke 780 for(i = 0; i < 3; i ++){
108     for(j = 0; j < 3; j++){
109     if( i == j) {
110 tim 837 eta[i][j] = oldEta[i][j] + dt2 * instaVol *
111 mmeineke 780 (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 gezelter 600
119 mmeineke 780 template<typename T> void NPTf<T>::getVelScaleA(double sc[3], double vel[3]) {
120     int i,j;
121     double vScale[3][3];
122 gezelter 576
123 gezelter 588 for (i = 0; i < 3; i++ ) {
124     for (j = 0; j < 3; j++ ) {
125 tim 767 vScale[i][j] = eta[i][j];
126 tim 837
127 gezelter 588 if (i == j) {
128 tim 837 vScale[i][j] += chi;
129     }
130 gezelter 588 }
131     }
132 tim 837
133 mmeineke 780 info->matVecMul3( vScale, vel, sc );
134     }
135 gezelter 600
136 mmeineke 780 template<typename T> void NPTf<T>::getVelScaleB(double sc[3], int index ){
137     int i,j;
138     double myVel[3];
139     double vScale[3][3];
140 gezelter 600
141 mmeineke 780 for (i = 0; i < 3; i++ ) {
142     for (j = 0; j < 3; j++ ) {
143     vScale[i][j] = eta[i][j];
144 tim 837
145 mmeineke 780 if (i == j) {
146 tim 837 vScale[i][j] += chi;
147     }
148 tim 767 }
149     }
150 tim 837
151 mmeineke 780 for (j = 0; j < 3; j++)
152     myVel[j] = oldVel[3*index + j];
153 tim 767
154 mmeineke 780 info->matVecMul3( vScale, myVel, sc );
155     }
156 tim 767
157 tim 837 template<typename T> void NPTf<T>::getPosScale(double pos[3], double COM[3],
158 mmeineke 780 int index, double sc[3]){
159     int j;
160     double rj[3];
161 tim 767
162 mmeineke 780 for(j=0; j<3; j++)
163     rj[j] = ( oldPos[index*3+j] + pos[j]) / 2.0 - COM[j];
164 tim 767
165 mmeineke 780 info->matVecMul3( eta, rj, sc );
166     }
167 tim 767
168 mmeineke 780 template<typename T> void NPTf<T>::scaleSimBox( void ){
169 tim 767
170 mmeineke 780 int i,j,k;
171     double scaleMat[3][3];
172     double eta2ij;
173     double bigScale, smallScale, offDiagMax;
174     double hm[3][3], hmnew[3][3];
175 tim 767
176 mmeineke 780
177 tim 837
178 gezelter 577 // Scale the box after all the positions have been moved:
179 tim 837
180 gezelter 578 // Use a taylor expansion for eta products: Hmat = Hmat . exp(dt * etaMat)
181     // Hmat = Hmat . ( Ident + dt * etaMat + dt^2 * etaMat*etaMat / 2)
182 tim 837
183 gezelter 617 bigScale = 1.0;
184     smallScale = 1.0;
185     offDiagMax = 0.0;
186 tim 837
187 gezelter 578 for(i=0; i<3; i++){
188     for(j=0; j<3; j++){
189 tim 837
190 gezelter 588 // Calculate the matrix Product of the eta array (we only need
191     // the ij element right now):
192 tim 837
193 gezelter 588 eta2ij = 0.0;
194 gezelter 578 for(k=0; k<3; k++){
195 gezelter 588 eta2ij += eta[i][k] * eta[k][j];
196 gezelter 578 }
197 tim 837
198 gezelter 588 scaleMat[i][j] = 0.0;
199     // identity matrix (see above):
200     if (i == j) scaleMat[i][j] = 1.0;
201     // Taylor expansion for the exponential truncated at second order:
202     scaleMat[i][j] += dt*eta[i][j] + 0.5*dt*dt*eta2ij;
203 gezelter 617
204     if (i != j)
205 tim 837 if (fabs(scaleMat[i][j]) > offDiagMax)
206 gezelter 617 offDiagMax = fabs(scaleMat[i][j]);
207 gezelter 578 }
208 gezelter 617
209     if (scaleMat[i][i] > bigScale) bigScale = scaleMat[i][i];
210     if (scaleMat[i][i] < smallScale) smallScale = scaleMat[i][i];
211 gezelter 578 }
212 tim 837
213 mmeineke 853 if ((bigScale > 1.01) || (smallScale < 0.99)) {
214 gezelter 617 sprintf( painCave.errMsg,
215 mmeineke 853 "NPTf error: Attempting a Box scaling of more than 1 percent.\n"
216 gezelter 617 " Check your tauBarostat, as it is probably too small!\n\n"
217     " scaleMat = [%lf\t%lf\t%lf]\n"
218     " [%lf\t%lf\t%lf]\n"
219     " [%lf\t%lf\t%lf]\n",
220     scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
221     scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
222     scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
223     painCave.isFatal = 1;
224     simError();
225 mmeineke 853 } else if (offDiagMax > 0.01) {
226 gezelter 617 sprintf( painCave.errMsg,
227 mmeineke 853 "NPTf error: Attempting an off-diagonal Box scaling of more than 1 percent.\n"
228 gezelter 617 " Check your tauBarostat, as it is probably too small!\n\n"
229     " scaleMat = [%lf\t%lf\t%lf]\n"
230     " [%lf\t%lf\t%lf]\n"
231     " [%lf\t%lf\t%lf]\n",
232     scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
233     scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
234     scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
235     painCave.isFatal = 1;
236     simError();
237     } else {
238     info->getBoxM(hm);
239     info->matMul3(hm, scaleMat, hmnew);
240     info->setBoxM(hmnew);
241     }
242 gezelter 576 }
243    
244 mmeineke 780 template<typename T> bool NPTf<T>::etaConverged() {
245     int i;
246     double diffEta, sumEta;
247 gezelter 600
248 mmeineke 780 sumEta = 0;
249 tim 767 for(i = 0; i < 3; i++)
250 tim 837 sumEta += pow(prevEta[i][i] - eta[i][i], 2);
251    
252 mmeineke 780 diffEta = sqrt( sumEta / 3.0 );
253 tim 837
254 mmeineke 780 return ( diffEta <= etaTolerance );
255 gezelter 576 }
256    
257 mmeineke 780 template<typename T> double NPTf<T>::getConservedQuantity(void){
258 tim 837
259 tim 763 double conservedQuantity;
260 mmeineke 782 double totalEnergy;
261 gezelter 772 double thermostat_kinetic;
262     double thermostat_potential;
263     double barostat_kinetic;
264     double barostat_potential;
265     double trEta;
266     double a[3][3], b[3][3];
267 tim 763
268 mmeineke 782 totalEnergy = tStats->getTotalE();
269 tim 763
270 tim 837 thermostat_kinetic = fkBT * tt2 * chi * chi /
271 gezelter 772 (2.0 * eConvert);
272 tim 763
273 gezelter 772 thermostat_potential = fkBT* integralOfChidt / eConvert;
274 tim 763
275 gezelter 772 info->transposeMat3(eta, a);
276     info->matMul3(a, eta, b);
277     trEta = info->matTrace3(b);
278 tim 767
279 tim 837 barostat_kinetic = NkBT * tb2 * trEta /
280 gezelter 772 (2.0 * eConvert);
281 tim 837
282     barostat_potential = (targetPressure * tStats->getVolume() / p_convert) /
283 gezelter 772 eConvert;
284 tim 767
285 mmeineke 782 conservedQuantity = totalEnergy + thermostat_kinetic + thermostat_potential +
286 gezelter 772 barostat_kinetic + barostat_potential;
287 tim 837
288     return conservedQuantity;
289    
290 tim 763 }
291 tim 837
292     template<typename T> string NPTf<T>::getAdditionalParameters(void){
293     string parameters;
294     const int BUFFERSIZE = 2000; // size of the read buffer
295     char buffer[BUFFERSIZE];
296    
297 mmeineke 853 sprintf(buffer,"\t%G\t%G;", chi, integralOfChidt);
298 tim 837 parameters += buffer;
299    
300     for(int i = 0; i < 3; i++){
301 mmeineke 853 sprintf(buffer,"\t%G\t%G\t%G;", eta[i][0], eta[i][1], eta[i][2]);
302 tim 837 parameters += buffer;
303     }
304    
305     return parameters;
306    
307     }