ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/SHAPES/GridBuilder.cpp
Revision: 1281
Committed: Mon Jun 21 13:38:55 2004 UTC (20 years ago) by chrisfen
File size: 7193 byte(s)
Log Message:
Now calculates energies and builds the grid files.  There are still bugs, but
it compiles and runs...

File Contents

# Content
1 #include "GridBuilder.hpp"
2 #include "MatVec3.h"
3 #define PI 3.14159265359
4
5
6 GridBuilder::GridBuilder(RigidBody* rb, int bandWidth) {
7 rbMol = rb;
8 bandwidth = bandWidth;
9 thetaStep = PI / bandwidth;
10 thetaMin = thetaStep / 2.0;
11 phiStep = thetaStep * 2.0;
12
13 //zero out the rot mats
14 for (i=0; i<3; i++) {
15 for (j=0; j<3; j++) {
16 rotX[i][j] = 0.0;
17 rotZ[i][j] = 0.0;
18 rbMatrix[i][j] = 0.0;
19 }
20 }
21 }
22
23 GridBuilder::~GridBuilder() {
24 }
25
26 void GridBuilder::launchProbe(int forceField, vector<double> sigmaGrid, vector<double> sGrid,
27 vector<double> epsGrid){
28 ofstream sigmaOut("sigma.grid");
29 ofstream sOut("s.grid");
30 ofstream epsOut("eps.grid");
31 double startDist;
32 double minDist = 10.0; //minimum start distance
33
34 sList = sGrid;
35 sigList = sigmaGrid;
36 epsList = epsGrid;
37 forcefield = forceField;
38
39 //first determine the start distance - we always start at least minDist away
40 startDist = rbMol->findMaxExtent() + minDist;
41 if (startDist < minDist)
42 startDist = minDist;
43
44 initBody();
45 for (k=0; k<bandwidth; k++){
46 printf("step theta...\n");
47 for (j=0; j<bandwidth; j++){
48 releaseProbe(startDist);
49
50 sigList.push_back(sigDist);
51 sList.push_back(sDist);
52 epsList.push_back(epsVal);
53
54 stepPhi(phiStep);
55 }
56 stepTheta(thetaStep);
57 }
58 /*
59 //write out the grid files
60 printf("the grid size is %d\n",sigmaGrid.size());
61 for (k=0; k<sigmaGrid.size(); k++){
62 sigmaOut << sigmaGrid[k] << "\n0\n";
63 sOut << sGrid[k] << "\n0\n";
64 epsOut << epsGrid[k] << "\n0\n";
65 }
66 */
67 }
68
69 void GridBuilder::initBody(){
70 //set up the rigid body in the starting configuration
71 stepTheta(thetaMin);
72 }
73
74 void GridBuilder::releaseProbe(double farPos){
75 int tooClose;
76 double tempPotEnergy;
77 double interpRange;
78 double interpFrac;
79
80 probeCoor = farPos;
81 potProgress.clear();
82 distProgress.clear();
83 tooClose = 0;
84 epsVal = 0;
85 rhoStep = 0.1; //the distance the probe atom moves between steps
86
87
88 while (!tooClose){
89 calcEnergy();
90 potProgress.push_back(potEnergy);
91 distProgress.push_back(probeCoor);
92
93 //if we've reached a new minimum, save the value and position
94 if (potEnergy < epsVal){
95 epsVal = potEnergy;
96 sDist = probeCoor;
97 }
98
99 //test if the probe reached the origin - if so, stop stepping closer
100 if (probeCoor < 0){
101 sigDist = 0.0;
102 tooClose = 1;
103 }
104
105 //test if the probe beyond the contact point - if not, take a step closer
106 if (potEnergy < 0){
107 sigDist = probeCoor;
108 tempPotEnergy = potEnergy;
109 probeCoor -= rhoStep;
110 }
111 else {
112 //do a linear interpolation to obtain the sigDist
113 interpRange = potEnergy - tempPotEnergy;
114 interpFrac = potEnergy / interpRange;
115 interpFrac = interpFrac * rhoStep;
116 sigDist = probeCoor + interpFrac;
117
118 //end the loop
119 tooClose = 1;
120 }
121 }
122 }
123
124 void GridBuilder::calcEnergy(){
125 double rXij, rYij, rZij;
126 double rijSquared;
127 double rValSquared, rValPowerSix;
128 double rparHe, epsHe;
129 double atomRpar, atomEps;
130 double rbAtomPos[3];
131
132 //first get the probe atom parameters
133 switch(forcefield){
134 case 1:{
135 rparHe = 1.4800;
136 epsHe = -0.021270;
137 }; break;
138 case 2:{
139 rparHe = 1.14;
140 epsHe = 0.0203;
141 }; break;
142 case 3:{
143 rparHe = 2.28;
144 epsHe = 0.020269601874;
145 }; break;
146 case 4:{
147 rparHe = 2.5560;
148 epsHe = 0.0200;
149 }; break;
150 case 5:{
151 rparHe = 1.14;
152 epsHe = 0.0203;
153 }; break;
154 }
155
156 potEnergy = 0.0;
157
158 for(i=0; i<rbMol->getNumAtoms(); i++){
159 rbMol->getAtomPos(rbAtomPos, i);
160
161 rXij = rbAtomPos[0];
162 rYij = rbAtomPos[1];
163 rZij = rbAtomPos[2] - probeCoor;
164
165 rijSquared = rXij * rXij + rYij * rYij + rZij * rZij;
166
167 //in the interest of keeping the code more compact, we are being less efficient by placing
168 //a switch statement in the calculation loop
169 switch(forcefield){
170 case 1:{
171 //we are using the CHARMm force field
172 atomRpar = rbMol->getAtomRpar(i);
173 atomEps = rbMol->getAtomEps(i);
174
175 rValSquared = ((rparHe+atomRpar)*(rparHe+atomRpar)) / (rijSquared);
176 rValPowerSix = rValSquared * rValSquared * rValSquared;
177 potEnergy += sqrt(epsHe*atomEps)*(rValPowerSix * (rValPowerSix - 2.0));
178 }; break;
179
180 case 2:{
181 //we are using the AMBER force field
182 atomRpar = rbMol->getAtomRpar(i);
183 atomEps = rbMol->getAtomEps(i);
184
185 rValSquared = ((rparHe+atomRpar)*(rparHe+atomRpar)) / (rijSquared);
186 rValPowerSix = rValSquared * rValSquared * rValSquared;
187 potEnergy += sqrt(epsHe*atomEps)*(rValPowerSix * (rValPowerSix - 2.0));
188 }; break;
189
190 case 3:{
191 //we are using Allen-Tildesley LJ parameters
192 atomRpar = rbMol->getAtomRpar(i);
193 atomEps = rbMol->getAtomEps(i);
194
195 rValSquared = ((rparHe+atomRpar)*(rparHe+atomRpar)) / (4*rijSquared);
196 rValPowerSix = rValSquared * rValSquared * rValSquared;
197 potEnergy += 4*sqrt(epsHe*atomEps)*(rValPowerSix * (rValPowerSix - 1.0));
198
199 }; break;
200
201
202 case 4:{
203 //we are using the OPLS force field
204 atomRpar = rbMol->getAtomRpar(i);
205 atomEps = rbMol->getAtomEps(i);
206
207 rValSquared = (pow(sqrt(rparHe+atomRpar),2)) / (rijSquared);
208 rValPowerSix = rValSquared * rValSquared * rValSquared;
209 potEnergy += 4*sqrt(epsHe*atomEps)*(rValPowerSix * (rValPowerSix - 1.0));
210 }; break;
211
212 case 5:{
213 //we are using the GAFF force field
214 atomRpar = rbMol->getAtomRpar(i);
215 atomEps = rbMol->getAtomEps(i);
216
217 rValSquared = ((rparHe+atomRpar)*(rparHe+atomRpar)) / (rijSquared);
218 rValPowerSix = rValSquared * rValSquared * rValSquared;
219 potEnergy += sqrt(epsHe*atomEps)*(rValPowerSix * (rValPowerSix - 2.0));
220 }; break;
221 }
222 }
223 }
224
225 void GridBuilder::stepTheta(double increment){
226 //zero out the euler angles
227 for (l=0; l<3; l++)
228 angles[i] = 0.0;
229
230 //the second euler angle is for rotation about the x-axis (we use the zxz convention)
231 angles[1] = increment;
232
233 //obtain the rotation matrix through the rigid body class
234 rbMol->doEulerToRotMat(angles, rotX);
235
236 //rotate the rigid body
237 rbMol->getA(rbMatrix);
238 matMul3(rotX, rbMatrix, rotatedMat);
239 rbMol->setA(rotatedMat);
240 }
241
242 void GridBuilder::stepPhi(double increment){
243 //zero out the euler angles
244 for (l=0; l<3; l++)
245 angles[i] = 0.0;
246
247 //the phi euler angle is for rotation about the z-axis (we use the zxz convention)
248 angles[0] = increment;
249
250 //obtain the rotation matrix through the rigid body class
251 rbMol->doEulerToRotMat(angles, rotZ);
252
253 //rotate the rigid body
254 rbMol->getA(rbMatrix);
255 matMul3(rotZ, rbMatrix, rotatedMat);
256 rbMol->setA(rotatedMat);
257 }
258
259 void GridBuilder::printGridFiles(){
260 ofstream sigmaOut("sigma.grid");
261 ofstream sOut("s.grid");
262 ofstream epsOut("eps.grid");
263
264 for (k=0; k<sigList.size(); k++){
265 sigmaOut << sigList[k] << "\n0\n";
266 sOut << sList[k] << "\n0\n";
267 epsOut << epsList[k] << "\n0\n";
268 }
269 }