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

# User Rev Content
1 gezelter 1490 #include <math.h>
2    
3 tim 1492 #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 gezelter 1490
14     #ifdef IS_MPI
15 tim 1492 #include "brains/mpiSimulation.hpp"
16 gezelter 1490 #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 tim 1625 DoubleVectorGenericData * etaValue;
33 gezelter 1490 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 tim 1701 data = info->getPropertyByName(ETAVALUE_ID);
47 gezelter 1490 if(data){
48 tim 1625 etaValue = dynamic_cast<DoubleVectorGenericData*>(data);
49 gezelter 1490
50     if(etaValue){
51    
52     for(i = 0; i < 3; i++){
53     for (j = 0; j < 3; j++){
54 tim 1625 eta[i][j] = (*etaValue)[3*i+j];
55 gezelter 1490 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     }