ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Restraints.cpp
Revision: 1180
Committed: Thu May 20 20:24:07 2004 UTC (20 years, 3 months ago) by chrisfen
File size: 12621 byte(s)
Log Message:
Several additions... Restraints.cpp and .hpp were included for restraining particles in thermodynamic integration.  By including these, changes were made in Integrator, SimInfo, ForceFeilds, SimSetup, StatWriter, and possibly some other files.  Two bass keywords were also added for performing thermodynamic integration: a lambda value one and a k power one.

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 strcpy(springName, "HarmSpringConsts.txt");
27
28 ifstream springs(springName);
29
30 if (!springs) {
31 cout << "Unable to open HarmSpringConsts.txt for reading.\n";
32
33 // load place holder spring constants
34 kDist = 6; // spring constant in units of kcal/(mol*ang^2)
35 kTheta = 7.5; // in units of kcal/mol
36 kOmega = 13.5; // in units of kcal/mol
37 return;
38 }
39
40 springs.getline(inLine,999,'\n');
41 springs.getline(inLine,999,'\n');
42 token = strtok(inLine,jolt);
43 token = strtok(NULL,jolt);
44 strcpy(inValue,token);
45 kDist = (atof(inValue));
46 springs.getline(inLine,999,'\n');
47 token = strtok(inLine,jolt);
48 token = strtok(NULL,jolt);
49 strcpy(inValue,token);
50 kTheta = (atof(inValue));
51 springs.getline(inLine,999,'\n');
52 token = strtok(inLine,jolt);
53 token = strtok(NULL,jolt);
54 strcpy(inValue,token);
55 kOmega = (atof(inValue));
56 springs.close();
57
58 cout << "Spring Constants: " << kDist << "\t" << kTheta << "\t" << kOmega << "\n";
59 }
60
61 Restraints::~Restraints(){
62 }
63
64 void Restraints::Calc_rVal(double position[3], int currentMol){
65 delRx = position[0] - cofmPosX[currentMol];
66 delRy = position[1] - cofmPosY[currentMol];
67 delRz = position[2] - cofmPosZ[currentMol];
68
69 return;
70 }
71
72 void Restraints::Calc_thetaVal(double matrix[3][3], int currentMol){
73 uTx = matrix[2][0];
74 uTy = matrix[2][1];
75 uTz = matrix[2][2];
76
77 normalize = sqrt(uTx*uTx + uTy*uTy + uTz*uTz);
78 uTx = uTx/normalize;
79 uTy = uTy/normalize;
80 uTz = uTz/normalize;
81
82 // Theta is the dot product of the reference and new z-axes
83 theta = acos(uTx*uX0[currentMol]+uTy*uY0[currentMol]+uTz*uZ0[currentMol]);
84
85 return;
86 }
87
88 void Restraints::Calc_body_thetaVal(double matrix[3][3], int currentMol){
89 ub0x = matrix[0][0]*uX0[currentMol] + matrix[0][1]*uY0[currentMol]
90 + matrix[0][2]*uZ0[currentMol];
91 ub0y = matrix[1][0]*uX0[currentMol] + matrix[1][1]*uY0[currentMol]
92 + matrix[1][2]*uZ0[currentMol];
93 ub0z = matrix[2][0]*uX0[currentMol] + matrix[2][1]*uY0[currentMol]
94 + matrix[2][2]*uZ0[currentMol];
95
96 normalize = sqrt(ub0x*ub0x + ub0y*ub0y + ub0z*ub0z);
97 ub0x = ub0x/normalize;
98 ub0y = ub0y/normalize;
99 ub0z = ub0z/normalize;
100
101 // Theta is the dot product of the reference and new z-axes
102 theta = acos(ub0z);
103
104 return;
105 }
106
107 void Restraints::Calc_omegaVal(double matrix[3][3], int currentMol){
108 double dot;
109
110 uTx = matrix[2][0];
111 uTy = matrix[2][1];
112 uTz = matrix[2][2];
113 vTx = matrix[1][0];
114 vTy = matrix[1][1];
115 vTz = matrix[1][2];
116
117 normalize = sqrt(uTx*uTx + uTy*uTy + uTz*uTz);
118 uTx = uTx/normalize;
119 uTy = uTy/normalize;
120 uTz = uTz/normalize;
121
122 normalize = sqrt(vTx*vTx + vTy*vTy + vTz*vTz);
123 vTx = vTx/normalize;
124 vTy = vTy/normalize;
125 vTz = vTz/normalize;
126
127 dot = uTx * vX0[currentMol] + uTy * vY0[currentMol] + uTz * vZ0[currentMol];
128
129 // Find the original y-axis vector projection on the current
130 // space-fixed xy-plane
131 vProj0[0] = vX0[currentMol] - dot * uTx;
132 vProj0[1] = vY0[currentMol] - dot * uTy;
133 vProj0[2] = vZ0[currentMol] - dot * uTz;
134
135 // Convert the projection to a unit vector
136 vProjDist = sqrt(vProj0[0]*vProj0[0] + vProj0[1]*vProj0[1]
137 + vProj0[2]*vProj0[2]);
138 vProj0[0] = vProj0[0]/vProjDist;
139 vProj0[1] = vProj0[1]/vProjDist;
140 vProj0[2] = vProj0[2]/vProjDist;
141
142 // Omega is the dot product of the new y-axis and the projection
143 // of the reference y-axis on the current xy-plane
144 omega = acos(vTx*vProj0[0] + vTy*vProj0[1] + vTz*vProj0[2]);
145
146 return;
147 }
148
149 void Restraints::Calc_body_omegaVal(double matrix[3][3], int currentMol){
150 double zRotator[3][3];
151 double tempOmega;
152 double wholeTwoPis;
153 // Use the omega accumulated from the rotation propagation
154 omega = zAngle[currentMol];
155
156 // translate the omega into a range between -PI and PI
157 if (omega < -PI){
158 tempOmega = omega / -TWO_PI;
159 wholeTwoPis = floor(tempOmega);
160 tempOmega = omega + TWO_PI*wholeTwoPis;
161 if (tempOmega < -PI)
162 omega = tempOmega + TWO_PI;
163 else
164 omega = tempOmega;
165 }
166 if (omega > PI){
167 tempOmega = omega / TWO_PI;
168 wholeTwoPis = floor(tempOmega);
169 tempOmega = omega - TWO_PI*wholeTwoPis;
170 if (tempOmega > PI)
171 omega = tempOmega - TWO_PI;
172 else
173 omega = tempOmega;
174 }
175
176 vb0x = sin(omega);
177 vb0y = cos(omega);
178 vb0z = 0.0;
179
180 normalize = sqrt(vb0x*vb0x + vb0y*vb0y + vb0z*vb0z);
181 vb0x = vb0x/normalize;
182 vb0y = vb0y/normalize;
183 vb0z = vb0z/normalize;
184
185 return;
186 }
187
188 double Restraints::Calc_Restraint_Forces(vector<StuntDouble*> vecParticles){
189 double pos[3];
190 double A[3][3];
191 double tolerance;
192 double tempPotent;
193 double factor;
194 double spaceTrq[3];
195
196 // atoms = atomPoint;
197
198 // kDist = 6; // spring constant in units of kcal/(mol*ang^2)
199 // kTheta = 7.5; // in units of kcal/mol
200 // kOmega = 13.5; // in units of kcal/mol
201
202 tolerance = 5.72957795131e-7;
203
204 harmPotent = 0.0; // zero out the global harmonic potential variable
205
206 factor = 1 - pow(lambdaValue, lambdaK);
207
208 for (i=0; i<vecParticles.size(); i++){
209 if (vecParticles[i]->isDirectional()){
210 vecParticles[i]->getPos(pos);
211 vecParticles[i]->getA(A);
212 Calc_rVal( pos, i );
213 Calc_body_thetaVal( A, i );
214 Calc_body_omegaVal( A, i );
215
216 if (omega > PI || omega < -PI)
217 cout << "oops... " << omega << "\n";
218
219 // first we calculate the derivatives
220 dVdrx = -kDist*delRx;
221 dVdry = -kDist*delRy;
222 dVdrz = -kDist*delRz;
223
224 // uTx... and vTx... are the body-fixed z and y unit vectors
225 uTx = 0.0;
226 uTy = 0.0;
227 uTz = 1.0;
228 vTx = 0.0;
229 vTy = 1.0;
230 vTz = 0.0;
231
232 dVdux = 0;
233 dVduy = 0;
234 dVduz = 0;
235 dVdvx = 0;
236 dVdvy = 0;
237 dVdvz = 0;
238
239 if (fabs(theta) > tolerance) {
240 dVdux = -(kTheta*theta/sin(theta))*ub0x;
241 dVduy = -(kTheta*theta/sin(theta))*ub0y;
242 dVduz = -(kTheta*theta/sin(theta))*ub0z;
243 }
244
245 if (fabs(omega) > tolerance) {
246 dVdvx = -(kOmega*omega/sin(omega))*vb0x;
247 dVdvy = -(kOmega*omega/sin(omega))*vb0y;
248 dVdvz = -(kOmega*omega/sin(omega))*vb0z;
249 }
250
251 // next we calculate the restraint forces and torques
252 restraintFrc[0] = dVdrx;
253 restraintFrc[1] = dVdry;
254 restraintFrc[2] = dVdrz;
255 tempPotent = 0.5*kDist*(delRx*delRx + delRy*delRy + delRz*delRz);
256
257 restraintTrq[0] = 0.0;
258 restraintTrq[1] = 0.0;
259 restraintTrq[2] = 0.0;
260
261 if (fabs(omega) > tolerance) {
262 restraintTrq[0] += 0.0;
263 restraintTrq[1] += 0.0;
264 restraintTrq[2] += vTy*dVdvx;
265 tempPotent += 0.5*(kOmega*omega*omega);
266 }
267 if (fabs(theta) > tolerance) {
268 restraintTrq[0] += (uTz*dVduy);
269 restraintTrq[1] += -(uTz*dVdux);
270 restraintTrq[2] += 0.0;
271 tempPotent += 0.5*(kTheta*theta*theta);
272 }
273
274 for (j = 0; j < 3; j++) {
275 restraintFrc[j] *= factor;
276 restraintTrq[j] *= factor;
277 }
278
279 harmPotent += tempPotent;
280
281 // now we need to convert from body-fixed torques to space-fixed torques
282 spaceTrq[0] = A[0][0]*restraintTrq[0] + A[1][0]*restraintTrq[1]
283 + A[2][0]*restraintTrq[2];
284 spaceTrq[1] = A[0][1]*restraintTrq[0] + A[1][1]*restraintTrq[1]
285 + A[2][1]*restraintTrq[2];
286 spaceTrq[2] = A[0][2]*restraintTrq[0] + A[1][2]*restraintTrq[1]
287 + A[2][2]*restraintTrq[2];
288
289 // now it's time to pass these temporary forces and torques
290 // to the total forces and torques
291 vecParticles[i]->addFrc(restraintFrc);
292 vecParticles[i]->addTrq(spaceTrq);
293 }
294 }
295
296 // and we can return the appropriately scaled potential energy
297 tempPotent = harmPotent * factor;
298 return tempPotent;
299 }
300
301 void Restraints::Store_Init_Info(){
302 double pos[3];
303 double A[3][3];
304 double RfromQ[3][3];
305 double quat0, quat1, quat2, quat3;
306 double dot;
307 // char *token;
308 // char fileName[200];
309 // char angleName[200];
310 // char inLine[1000];
311 // char inValue[200];
312 const char *delimit = " \t\n;,";
313
314 //open the idealCrystal.in file and zAngle.ang file
315 strcpy(fileName, "idealCrystal.in");
316 strcpy(angleName, "zAngle.ang");
317
318 ifstream crystalIn(fileName);
319 ifstream angleIn(angleName);
320
321 if (!crystalIn) {
322 cout << "Unable to open idealCrystal.in for reading.\n";
323 return;
324 }
325
326 if (!angleIn) {
327 cout << "Unable to open zAngle.ang for reading.\n";
328 cout << "The omega values are all assumed to be zero.\n";
329 }
330
331 // A rather specific reader for OOPSE .eor files...
332 // Let's read in the perfect crystal file
333 crystalIn.getline(inLine,999,'\n');
334 crystalIn.getline(inLine,999,'\n');
335
336 for (i=0; i<nMol; i++) {
337 crystalIn.getline(inLine,999,'\n');
338 token = strtok(inLine,delimit);
339 token = strtok(NULL,delimit);
340 strcpy(inValue,token);
341 cofmPosX.push_back(atof(inValue));
342 token = strtok(NULL,delimit);
343 strcpy(inValue,token);
344 cofmPosY.push_back(atof(inValue));
345 token = strtok(NULL,delimit);
346 strcpy(inValue,token);
347 cofmPosZ.push_back(atof(inValue));
348 token = strtok(NULL,delimit);
349 token = strtok(NULL,delimit);
350 token = strtok(NULL,delimit);
351 token = strtok(NULL,delimit);
352 strcpy(inValue,token);
353 quat0 = atof(inValue);
354 token = strtok(NULL,delimit);
355 strcpy(inValue,token);
356 quat1 = atof(inValue);
357 token = strtok(NULL,delimit);
358 strcpy(inValue,token);
359 quat2 = atof(inValue);
360 token = strtok(NULL,delimit);
361 strcpy(inValue,token);
362 quat3 = atof(inValue);
363
364 // now build the rotation matrix and find the unit vectors
365 RfromQ[0][0] = quat0*quat0 + quat1*quat1 - quat2*quat2 - quat3*quat3;
366 RfromQ[0][1] = 2*(quat1*quat2 + quat0*quat3);
367 RfromQ[0][2] = 2*(quat1*quat3 - quat0*quat2);
368 RfromQ[1][0] = 2*(quat1*quat2 - quat0*quat3);
369 RfromQ[1][1] = quat0*quat0 - quat1*quat1 + quat2*quat2 - quat3*quat3;
370 RfromQ[1][2] = 2*(quat2*quat3 + quat0*quat1);
371 RfromQ[2][0] = 2*(quat1*quat3 + quat0*quat2);
372 RfromQ[2][1] = 2*(quat2*quat3 - quat0*quat1);
373 RfromQ[2][2] = quat0*quat0 - quat1*quat1 - quat2*quat2 + quat3*quat3;
374
375 normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
376 + RfromQ[2][2]*RfromQ[2][2]);
377 uX0.push_back(RfromQ[2][0]/normalize);
378 uY0.push_back(RfromQ[2][1]/normalize);
379 uZ0.push_back(RfromQ[2][2]/normalize);
380
381 normalize = sqrt(RfromQ[1][0]*RfromQ[1][0] + RfromQ[1][1]*RfromQ[1][1]
382 + RfromQ[1][2]*RfromQ[1][2]);
383 vX0.push_back(RfromQ[1][0]/normalize);
384 vY0.push_back(RfromQ[1][1]/normalize);
385 vZ0.push_back(RfromQ[1][2]/normalize);
386 }
387
388 // now we can read in the zAngle.ang file
389 if (angleIn){
390 angleIn.getline(inLine,999,'\n');
391 for (i=0; i<nMol; i++) {
392 angleIn.getline(inLine,999,'\n');
393 token = strtok(inLine,delimit);
394 strcpy(inValue,token);
395 zAngle[i] = (atof(inValue));
396 }
397 }
398
399 return;
400 }
401
402 void Restraints::Determine_Lambda(){
403 // double tempEps;
404
405 // atoms = entry_plug->atoms;
406
407 // if (!strcmp(atoms[0]->getType(),"SSD") ||
408 // !strcmp(atoms[0]->getType(),"SSD_E") ||
409 // !strcmp(atoms[0]->getType(),"SSD_RF") ||
410 // !strcmp(atoms[0]->getType(),"SSD1")){
411
412 // tempEps = atoms[0]->getEpsilon();
413 // scaleLam = 1.0 - (tempEps/0.152);
414 // }
415 // else if (!strcmp(atoms[0]->getType(),"O_TIP3P")){
416 // tempEps = atoms[0]->getEpsilon();
417 // scaleLam = 1.0 - (tempEps/0.1521);
418 // }
419 // else if (!strcmp(atoms[0]->getType(),"O_TIP4P")){
420 // tempEps = atoms[0]->getEpsilon();
421 // scaleLam = 1.0 - (tempEps/0.1550);
422 // }
423 // else if (!strcmp(atoms[0]->getType(),"O_TIP5P")){
424 // tempEps = atoms[0]->getEpsilon();
425 // scaleLam = 1.0 - (tempEps/0.16);
426 // }
427 // else if (!strcmp(atoms[0]->getType(),"O_SPCE")){
428 // tempEps = atoms[0]->getEpsilon();
429 // scaleLam = 1.0 - (tempEps/0.15532);
430 // }
431 // else
432 // sprintf( painCave.errMsg,
433 // "Error in setting the lambda scale: Restraints\n" );
434
435 // if (fabs(scaleLam < 1e-9))
436 // scaleLam = 0.0;
437 // cout << "The scaleLam is " << scaleLam << "\n";
438 }
439
440 void Restraints::Write_zAngle_File(){
441
442 char zOutName[200];
443
444 strcpy(zOutName,"zAngle.ang");
445
446 ofstream angleOut(zOutName);
447 angleOut << "This file contains the omega values for the .eor file\n";
448 for (i=0; i<nMol; i++)
449 angleOut << zAngle[i] << "\n";
450
451 return;
452 }
453
454 double Restraints::getVharm(){
455 return harmPotent;
456 }
457