ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Restraints.cpp
Revision: 1221
Committed: Wed Jun 2 14:56:18 2004 UTC (20 years, 1 month ago) by chrisfen
File size: 11204 byte(s)
Log Message:
Formatting Changes, removed writeRaw

File Contents

# Content
1 #include <iostream>
2 #include <stdlib.h>
3 #include <cstdio>
4 #include <fstream>
5 #include <iomanip>
6 #include <string>
7 #include <cstring>
8 #include <math.h>
9
10 using namespace std;
11
12 #include "Restraints.hpp"
13 #include "SimInfo.hpp"
14 #include "simError.h"
15
16 #define PI 3.14159265359
17 #define TWO_PI 6.28318530718
18
19 Restraints::Restraints(int nMolInfo, double lambdaVal, double lambdaExp){
20 nMol = nMolInfo;
21 lambdaValue = lambdaVal;
22 lambdaK = lambdaExp;
23
24 const char *jolt = " \t\n;,";
25
26 #ifdef IS_MPI
27 if(worldRank == 0 ){
28 #endif // is_mpi
29
30 strcpy(springName, "HarmSpringConsts.txt");
31
32 ifstream springs(springName);
33
34 if (!springs) {
35 sprintf(painCave.errMsg,
36 "In Restraints: Unable to open HarmSpringConsts.txt for reading.\n"
37 "\tDefault spring constants will be loaded. If you want to specify\n"
38 "\tspring constants, include a three line HarmSpringConsts.txt file\n"
39 "\tin the current directory.\n");
40 painCave.severity = OOPSE_WARNING;
41 painCave.isFatal = 0;
42 simError();
43
44 // load default spring constants
45 kDist = 6; // spring constant in units of kcal/(mol*ang^2)
46 kTheta = 7.5; // in units of kcal/mol
47 kOmega = 13.5; // in units of kcal/mol
48 } else {
49
50 springs.getline(inLine,999,'\n');
51 springs.getline(inLine,999,'\n');
52 token = strtok(inLine,jolt);
53 token = strtok(NULL,jolt);
54 strcpy(inValue,token);
55 kDist = (atof(inValue));
56 springs.getline(inLine,999,'\n');
57 token = strtok(inLine,jolt);
58 token = strtok(NULL,jolt);
59 strcpy(inValue,token);
60 kTheta = (atof(inValue));
61 springs.getline(inLine,999,'\n');
62 token = strtok(inLine,jolt);
63 token = strtok(NULL,jolt);
64 strcpy(inValue,token);
65 kOmega = (atof(inValue));
66 springs.close();
67 }
68 #ifdef IS_MPI
69 }
70
71 MPI_Bcast(&kDist, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
72 MPI_Bcast(&kTheta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
73 MPI_Bcast(&kOmega, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
74
75 sprintf( checkPointMsg,
76 "Sucessfully opened and read spring file.\n");
77 MPIcheckPoint();
78
79 #endif // is_mpi
80
81 sprintf(painCave.errMsg,
82 "The spring constants for thermodynamic integration are:\n"
83 "\tkDist = %lf\n"
84 "\tkTheta = %lf\n"
85 "\tkOmega = %lf\n", kDist, kTheta, kOmega);
86 painCave.severity = OOPSE_INFO;
87 painCave.isFatal = 0;
88 simError();
89 }
90
91 Restraints::~Restraints(){
92 }
93
94 void Restraints::Calc_rVal(double position[3], int currentMol){
95 delRx = position[0] - cofmPosX[currentMol];
96 delRy = position[1] - cofmPosY[currentMol];
97 delRz = position[2] - cofmPosZ[currentMol];
98
99 return;
100 }
101
102 void Restraints::Calc_body_thetaVal(double matrix[3][3], int currentMol){
103 ub0x = matrix[0][0]*uX0[currentMol] + matrix[0][1]*uY0[currentMol]
104 + matrix[0][2]*uZ0[currentMol];
105 ub0y = matrix[1][0]*uX0[currentMol] + matrix[1][1]*uY0[currentMol]
106 + matrix[1][2]*uZ0[currentMol];
107 ub0z = matrix[2][0]*uX0[currentMol] + matrix[2][1]*uY0[currentMol]
108 + matrix[2][2]*uZ0[currentMol];
109
110 normalize = sqrt(ub0x*ub0x + ub0y*ub0y + ub0z*ub0z);
111 ub0x = ub0x/normalize;
112 ub0y = ub0y/normalize;
113 ub0z = ub0z/normalize;
114
115 // Theta is the dot product of the reference and new z-axes
116 theta = acos(ub0z);
117
118 return;
119 }
120
121 void Restraints::Calc_body_omegaVal(double matrix[3][3], double zAngle){
122 double zRotator[3][3];
123 double tempOmega;
124 double wholeTwoPis;
125 // Use the omega accumulated from the rotation propagation
126 omega = zAngle;
127
128 // translate the omega into a range between -PI and PI
129 if (omega < -PI){
130 tempOmega = omega / -TWO_PI;
131 wholeTwoPis = floor(tempOmega);
132 tempOmega = omega + TWO_PI*wholeTwoPis;
133 if (tempOmega < -PI)
134 omega = tempOmega + TWO_PI;
135 else
136 omega = tempOmega;
137 }
138 if (omega > PI){
139 tempOmega = omega / TWO_PI;
140 wholeTwoPis = floor(tempOmega);
141 tempOmega = omega - TWO_PI*wholeTwoPis;
142 if (tempOmega > PI)
143 omega = tempOmega - TWO_PI;
144 else
145 omega = tempOmega;
146 }
147
148 vb0x = sin(omega);
149 vb0y = cos(omega);
150 vb0z = 0.0;
151
152 normalize = sqrt(vb0x*vb0x + vb0y*vb0y + vb0z*vb0z);
153 vb0x = vb0x/normalize;
154 vb0y = vb0y/normalize;
155 vb0z = vb0z/normalize;
156
157 return;
158 }
159
160 double Restraints::Calc_Restraint_Forces(vector<StuntDouble*> vecParticles){
161 double pos[3];
162 double A[3][3];
163 double tolerance;
164 double tempPotent;
165 double factor;
166 double spaceTrq[3];
167 double omegaPass;
168
169 tolerance = 5.72957795131e-7;
170
171 harmPotent = 0.0; // zero out the global harmonic potential variable
172
173 factor = 1 - pow(lambdaValue, lambdaK);
174
175 for (i=0; i<nMol; i++){
176 if (vecParticles[i]->isDirectional()){
177 vecParticles[i]->getPos(pos);
178 vecParticles[i]->getA(A);
179 Calc_rVal( pos, i );
180 Calc_body_thetaVal( A, i );
181 omegaPass = vecParticles[i]->getZangle();
182 Calc_body_omegaVal( A, omegaPass );
183
184 if (omega > PI || omega < -PI)
185 cout << "oops... " << omega << "\n";
186
187 // first we calculate the derivatives
188 dVdrx = -kDist*delRx;
189 dVdry = -kDist*delRy;
190 dVdrz = -kDist*delRz;
191
192 // uTx... and vTx... are the body-fixed z and y unit vectors
193 uTx = 0.0;
194 uTy = 0.0;
195 uTz = 1.0;
196 vTx = 0.0;
197 vTy = 1.0;
198 vTz = 0.0;
199
200 dVdux = 0;
201 dVduy = 0;
202 dVduz = 0;
203 dVdvx = 0;
204 dVdvy = 0;
205 dVdvz = 0;
206
207 if (fabs(theta) > tolerance) {
208 dVdux = -(kTheta*theta/sin(theta))*ub0x;
209 dVduy = -(kTheta*theta/sin(theta))*ub0y;
210 dVduz = -(kTheta*theta/sin(theta))*ub0z;
211 }
212
213 if (fabs(omega) > tolerance) {
214 dVdvx = -(kOmega*omega/sin(omega))*vb0x;
215 dVdvy = -(kOmega*omega/sin(omega))*vb0y;
216 dVdvz = -(kOmega*omega/sin(omega))*vb0z;
217 }
218
219 // next we calculate the restraint forces and torques
220 restraintFrc[0] = dVdrx;
221 restraintFrc[1] = dVdry;
222 restraintFrc[2] = dVdrz;
223 tempPotent = 0.5*kDist*(delRx*delRx + delRy*delRy + delRz*delRz);
224
225 restraintTrq[0] = 0.0;
226 restraintTrq[1] = 0.0;
227 restraintTrq[2] = 0.0;
228
229 if (fabs(omega) > tolerance) {
230 restraintTrq[0] += 0.0;
231 restraintTrq[1] += 0.0;
232 restraintTrq[2] += vTy*dVdvx;
233 tempPotent += 0.5*(kOmega*omega*omega);
234 }
235 if (fabs(theta) > tolerance) {
236 restraintTrq[0] += (uTz*dVduy);
237 restraintTrq[1] += -(uTz*dVdux);
238 restraintTrq[2] += 0.0;
239 tempPotent += 0.5*(kTheta*theta*theta);
240 }
241
242 for (j = 0; j < 3; j++) {
243 restraintFrc[j] *= factor;
244 restraintTrq[j] *= factor;
245 }
246
247 harmPotent += tempPotent;
248
249 // now we need to convert from body-fixed torques to space-fixed torques
250 spaceTrq[0] = A[0][0]*restraintTrq[0] + A[1][0]*restraintTrq[1]
251 + A[2][0]*restraintTrq[2];
252 spaceTrq[1] = A[0][1]*restraintTrq[0] + A[1][1]*restraintTrq[1]
253 + A[2][1]*restraintTrq[2];
254 spaceTrq[2] = A[0][2]*restraintTrq[0] + A[1][2]*restraintTrq[1]
255 + A[2][2]*restraintTrq[2];
256
257 // now it's time to pass these temporary forces and torques
258 // to the total forces and torques
259 vecParticles[i]->addFrc(restraintFrc);
260 vecParticles[i]->addTrq(spaceTrq);
261 }
262 }
263
264 // and we can return the appropriately scaled potential energy
265 tempPotent = harmPotent * factor;
266 return tempPotent;
267 }
268
269 void Restraints::Store_Init_Info(vector<StuntDouble*> vecParticles){
270 double pos[3];
271 double A[3][3];
272 double RfromQ[3][3];
273 double quat0, quat1, quat2, quat3;
274 double dot;
275 // char *token;
276 // char fileName[200];
277 // char angleName[200];
278 // char inLine[1000];
279 // char inValue[200];
280 const char *delimit = " \t\n;,";
281
282 //open the idealCrystal.in file and zAngle.ang file
283 strcpy(fileName, "idealCrystal.in");
284 strcpy(angleName, "zAngle.ang");
285
286 ifstream crystalIn(fileName);
287 ifstream angleIn(angleName);
288
289 if (!crystalIn) {
290 sprintf(painCave.errMsg,
291 "Restraints Error: Unable to open idealCrystal.in for reading.\n"
292 "\tMake sure a reference crystal file is in the current directory.\n");
293 painCave.isFatal = 1;
294 simError();
295
296 return;
297 }
298
299 if (!angleIn) {
300 sprintf(painCave.errMsg,
301 "Restraints Warning: The lack of a zAngle.ang file is mildly\n"
302 "\tunsettling... This means the simulation is starting from the\n"
303 "\tidealCrystal.in reference configuration, so the omega values\n"
304 "\twill all be set to zero. If this is not the case, you should\n"
305 "\tquestion your results.\n");
306 painCave.isFatal = 0;
307 simError();
308 }
309
310 // A rather specific reader for OOPSE .eor files...
311 // Let's read in the perfect crystal file
312 crystalIn.getline(inLine,999,'\n');
313 crystalIn.getline(inLine,999,'\n');
314
315 for (i=0; i<nMol; i++) {
316 crystalIn.getline(inLine,999,'\n');
317 token = strtok(inLine,delimit);
318 token = strtok(NULL,delimit);
319 strcpy(inValue,token);
320 cofmPosX.push_back(atof(inValue));
321 token = strtok(NULL,delimit);
322 strcpy(inValue,token);
323 cofmPosY.push_back(atof(inValue));
324 token = strtok(NULL,delimit);
325 strcpy(inValue,token);
326 cofmPosZ.push_back(atof(inValue));
327 token = strtok(NULL,delimit);
328 token = strtok(NULL,delimit);
329 token = strtok(NULL,delimit);
330 token = strtok(NULL,delimit);
331 strcpy(inValue,token);
332 quat0 = atof(inValue);
333 token = strtok(NULL,delimit);
334 strcpy(inValue,token);
335 quat1 = atof(inValue);
336 token = strtok(NULL,delimit);
337 strcpy(inValue,token);
338 quat2 = atof(inValue);
339 token = strtok(NULL,delimit);
340 strcpy(inValue,token);
341 quat3 = atof(inValue);
342
343 // now build the rotation matrix and find the unit vectors
344 RfromQ[0][0] = quat0*quat0 + quat1*quat1 - quat2*quat2 - quat3*quat3;
345 RfromQ[0][1] = 2*(quat1*quat2 + quat0*quat3);
346 RfromQ[0][2] = 2*(quat1*quat3 - quat0*quat2);
347 RfromQ[1][0] = 2*(quat1*quat2 - quat0*quat3);
348 RfromQ[1][1] = quat0*quat0 - quat1*quat1 + quat2*quat2 - quat3*quat3;
349 RfromQ[1][2] = 2*(quat2*quat3 + quat0*quat1);
350 RfromQ[2][0] = 2*(quat1*quat3 + quat0*quat2);
351 RfromQ[2][1] = 2*(quat2*quat3 - quat0*quat1);
352 RfromQ[2][2] = quat0*quat0 - quat1*quat1 - quat2*quat2 + quat3*quat3;
353
354 normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
355 + RfromQ[2][2]*RfromQ[2][2]);
356 uX0.push_back(RfromQ[2][0]/normalize);
357 uY0.push_back(RfromQ[2][1]/normalize);
358 uZ0.push_back(RfromQ[2][2]/normalize);
359
360 normalize = sqrt(RfromQ[1][0]*RfromQ[1][0] + RfromQ[1][1]*RfromQ[1][1]
361 + RfromQ[1][2]*RfromQ[1][2]);
362 vX0.push_back(RfromQ[1][0]/normalize);
363 vY0.push_back(RfromQ[1][1]/normalize);
364 vZ0.push_back(RfromQ[1][2]/normalize);
365 }
366
367 // now we can read in the zAngle.ang file
368 if (angleIn){
369 angleIn.getline(inLine,999,'\n');
370 for (i=0; i<nMol; i++) {
371 angleIn.getline(inLine,999,'\n');
372 token = strtok(inLine,delimit);
373 strcpy(inValue,token);
374 vecParticles[i]->setZangle(atof(inValue));
375 }
376 }
377
378 return;
379 }
380
381 void Restraints::Write_zAngle_File(vector<StuntDouble*> vecParticles){
382
383 char zOutName[200];
384
385 strcpy(zOutName,"zAngle.ang");
386
387 ofstream angleOut(zOutName);
388 angleOut << "This file contains the omega values for the .eor file\n";
389 for (i=0; i<nMol; i++) {
390 angleOut << vecParticles[i]->getZangle() << "\n";
391 }
392 return;
393 }
394
395 double Restraints::getVharm(){
396 return harmPotent;
397 }
398