ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/restraints/Restraints.cpp
(Generate patch)

Comparing trunk/OOPSE-4/src/restraints/Restraints.cpp (file contents):
Revision 1490 by gezelter, Fri Sep 24 04:16:43 2004 UTC vs.
Revision 2101 by chrisfen, Thu Mar 10 15:10:24 2005 UTC

# Line 1 | Line 1
1 < #include <iostream>
1 > /*
2 > * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 > *
4 > * The University of Notre Dame grants you ("Licensee") a
5 > * non-exclusive, royalty free, license to use, modify and
6 > * redistribute this software in source and binary code form, provided
7 > * that the following conditions are met:
8 > *
9 > * 1. Acknowledgement of the program authors must be made in any
10 > *    publication of scientific results based in part on use of the
11 > *    program.  An acceptable form of acknowledgement is citation of
12 > *    the article in which the program was described (Matthew
13 > *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 > *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 > *    Parallel Simulation Engine for Molecular Dynamics,"
16 > *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 > *
18 > * 2. Redistributions of source code must retain the above copyright
19 > *    notice, this list of conditions and the following disclaimer.
20 > *
21 > * 3. Redistributions in binary form must reproduce the above copyright
22 > *    notice, this list of conditions and the following disclaimer in the
23 > *    documentation and/or other materials provided with the
24 > *    distribution.
25 > *
26 > * This software is provided "AS IS," without a warranty of any
27 > * kind. All express or implied conditions, representations and
28 > * warranties, including any implied warranty of merchantability,
29 > * fitness for a particular purpose or non-infringement, are hereby
30 > * excluded.  The University of Notre Dame and its licensors shall not
31 > * be liable for any damages suffered by licensee as a result of
32 > * using, modifying or distributing the software or its
33 > * derivatives. In no event will the University of Notre Dame or its
34 > * licensors be liable for any lost revenue, profit or data, or for
35 > * direct, indirect, special, consequential, incidental or punitive
36 > * damages, however caused and regardless of the theory of liability,
37 > * arising out of the use of or inability to use software, even if the
38 > * University of Notre Dame has been advised of the possibility of
39 > * such damages.
40 > */
41 >
42   #include <stdlib.h>
3 #include <cstdio>
4 #include <fstream>
5 #include <iomanip>
6 #include <string>
7 #include <cstring>
43   #include <math.h>
44  
45   using namespace std;
46  
47 < #include "Restraints.hpp"
48 < #include "SimInfo.hpp"
49 < #include "simError.h"
47 > #include "restraints/Restraints.hpp"
48 > #include "primitives/Molecule.hpp"
49 > #include "utils/simError.h"
50  
51   #define PI 3.14159265359
52   #define TWO_PI 6.28318530718
53  
54 < Restraints::Restraints(double lambdaVal, double lambdaExp){
20 <  lambdaValue = lambdaVal;
21 <  lambdaK = lambdaExp;
22 <
23 <  const char *jolt = " \t\n;,";
24 <
25 < #ifdef IS_MPI
26 <  if(worldRank == 0 ){
27 < #endif // is_mpi
28 <
29 <    strcpy(springName, "HarmSpringConsts.txt");
30 <    
31 <    ifstream springs(springName);
32 <    
33 <    if (!springs) {
34 <      sprintf(painCave.errMsg,
35 <              "In Restraints: Unable to open HarmSpringConsts.txt for reading.\n"
36 <              "\tDefault spring constants will be loaded. If you want to specify\n"
37 <              "\tspring constants, include a three line HarmSpringConsts.txt file\n"
38 <              "\tin the current directory.\n");
39 <      painCave.severity = OOPSE_WARNING;
40 <      painCave.isFatal = 0;
41 <      simError();  
42 <      
43 <      // load default spring constants
44 <      kDist  = 6;  // spring constant in units of kcal/(mol*ang^2)
45 <      kTheta = 7.5;   // in units of kcal/mol
46 <      kOmega = 13.5;   // in units of kcal/mol
47 <    } else  {
48 <      
49 <      springs.getline(inLine,999,'\n');
50 <      springs.getline(inLine,999,'\n');
51 <      token = strtok(inLine,jolt);
52 <      token = strtok(NULL,jolt);
53 <      strcpy(inValue,token);
54 <      kDist = (atof(inValue));
55 <      springs.getline(inLine,999,'\n');
56 <      token = strtok(inLine,jolt);
57 <      token = strtok(NULL,jolt);
58 <      strcpy(inValue,token);
59 <      kTheta = (atof(inValue));
60 <      springs.getline(inLine,999,'\n');
61 <      token = strtok(inLine,jolt);
62 <      token = strtok(NULL,jolt);
63 <      strcpy(inValue,token);
64 <      kOmega = (atof(inValue));
65 <      springs.close();
66 <    }
67 < #ifdef IS_MPI
68 <  }
54 > namespace oopse {
55    
56 <  MPI_Bcast(&kDist, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
57 <  MPI_Bcast(&kTheta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
58 <  MPI_Bcast(&kOmega, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
73 <  
74 <  sprintf( checkPointMsg,
75 <           "Sucessfully opened and read spring file.\n");
76 <  MPIcheckPoint();
56 >  Restraints::Restraints(SimInfo* info, double lambdaVal, double lambdaExp){
57 >    info_ = info;
58 >    Globals* simParam = info_->getSimParams();
59  
60 < #endif // is_mpi
61 <  
62 <  sprintf(painCave.errMsg,
63 <          "The spring constants for thermodynamic integration are:\n"
64 <          "\tkDist = %lf\n"
65 <          "\tkTheta = %lf\n"
84 <          "\tkOmega = %lf\n", kDist, kTheta, kOmega);
85 <  painCave.severity = OOPSE_INFO;
86 <  painCave.isFatal = 0;
87 <  simError();  
88 < }
89 <
90 < Restraints::~Restraints(){
91 < }
92 <
93 < void Restraints::Calc_rVal(double position[3], int currentMol){
94 <  delRx = position[0] - cofmPosX[currentMol];
95 <  delRy = position[1] - cofmPosY[currentMol];
96 <  delRz = position[2] - cofmPosZ[currentMol];
97 <
98 <  return;
99 < }
100 <
101 < void Restraints::Calc_body_thetaVal(double matrix[3][3], int currentMol){
102 <  ub0x = matrix[0][0]*uX0[currentMol] + matrix[0][1]*uY0[currentMol]
103 <    + matrix[0][2]*uZ0[currentMol];
104 <  ub0y = matrix[1][0]*uX0[currentMol] + matrix[1][1]*uY0[currentMol]
105 <    + matrix[1][2]*uZ0[currentMol];
106 <  ub0z = matrix[2][0]*uX0[currentMol] + matrix[2][1]*uY0[currentMol]
107 <    + matrix[2][2]*uZ0[currentMol];
108 <
109 <  normalize = sqrt(ub0x*ub0x + ub0y*ub0y + ub0z*ub0z);
110 <  ub0x = ub0x/normalize;
111 <  ub0y = ub0y/normalize;
112 <  ub0z = ub0z/normalize;
113 <
114 <  // Theta is the dot product of the reference and new z-axes
115 <  theta = acos(ub0z);
116 <
117 <  return;
118 < }
119 <
120 < void Restraints::Calc_body_omegaVal(double matrix[3][3], double zAngle){
121 <  double zRotator[3][3];
122 <  double tempOmega;
123 <  double wholeTwoPis;
124 <  // Use the omega accumulated from the rotation propagation
125 <  omega = zAngle;
126 <
127 <  // translate the omega into a range between -PI and PI
128 <  if (omega < -PI){
129 <    tempOmega = omega / -TWO_PI;
130 <    wholeTwoPis = floor(tempOmega);
131 <    tempOmega = omega + TWO_PI*wholeTwoPis;
132 <    if (tempOmega < -PI)
133 <      omega = tempOmega + TWO_PI;
134 <    else
135 <      omega = tempOmega;
136 <  }
137 <  if (omega > PI){
138 <    tempOmega = omega / TWO_PI;
139 <    wholeTwoPis = floor(tempOmega);
140 <    tempOmega = omega - TWO_PI*wholeTwoPis;
141 <    if (tempOmega > PI)
142 <      omega = tempOmega - TWO_PI;  
143 <    else
144 <      omega = tempOmega;
145 <  }
146 <
147 <  vb0x = sin(omega);
148 <  vb0y = cos(omega);
149 <  vb0z = 0.0;
150 <
151 <  normalize = sqrt(vb0x*vb0x + vb0y*vb0y + vb0z*vb0z);
152 <  vb0x = vb0x/normalize;
153 <  vb0y = vb0y/normalize;
154 <  vb0z = vb0z/normalize;
155 <
156 <  return;
157 < }
158 <
159 < double Restraints::Calc_Restraint_Forces(vector<StuntDouble*> vecParticles){
160 <  double pos[3];
161 <  double A[3][3];
162 <  double tolerance;
163 <  double tempPotent;
164 <  double factor;
165 <  double spaceTrq[3];
166 <  double omegaPass;
167 <
168 <  tolerance = 5.72957795131e-7;
169 <
170 <  harmPotent = 0.0;  // zero out the global harmonic potential variable
171 <
172 <  factor = 1 - pow(lambdaValue, lambdaK);
173 <
174 <  for (i=0; i<vecParticles.size(); i++){
175 <    if (vecParticles[i]->isDirectional()){
176 <      vecParticles[i]->getPos(pos);
177 <      vecParticles[i]->getA(A);
178 <      Calc_rVal( pos, i );
179 <      Calc_body_thetaVal( A, i );
180 <      omegaPass = vecParticles[i]->getZangle();
181 <      Calc_body_omegaVal( A, omegaPass );
182 <
183 <      if (omega > PI || omega < -PI)
184 <        cout << "oops... " << omega << "\n";
185 <
186 <      // first we calculate the derivatives
187 <      dVdrx = -kDist*delRx;
188 <      dVdry = -kDist*delRy;
189 <      dVdrz = -kDist*delRz;
190 <
191 <      // uTx... and vTx... are the body-fixed z and y unit vectors
192 <      uTx = 0.0;
193 <      uTy = 0.0;
194 <      uTz = 1.0;
195 <      vTx = 0.0;
196 <      vTy = 1.0;
197 <      vTz = 0.0;
198 <
199 <      dVdux = 0;
200 <      dVduy = 0;
201 <      dVduz = 0;
202 <      dVdvx = 0;
203 <      dVdvy = 0;
204 <      dVdvz = 0;
205 <
206 <      if (fabs(theta) > tolerance) {
207 <        dVdux = -(kTheta*theta/sin(theta))*ub0x;
208 <        dVduy = -(kTheta*theta/sin(theta))*ub0y;
209 <        dVduz = -(kTheta*theta/sin(theta))*ub0z;
60 >    lambdaValue = lambdaVal;
61 >    lambdaK = lambdaExp;
62 >    
63 >    if (simParam->getUseSolidThermInt()) {
64 >      if (simParam->haveDistSpringConst()) {
65 >        kDist = simParam->getDistSpringConst();
66        }
67 <
68 <      if (fabs(omega) > tolerance) {
69 <        dVdvx = -(kOmega*omega/sin(omega))*vb0x;
70 <        dVdvy = -(kOmega*omega/sin(omega))*vb0y;
71 <        dVdvz = -(kOmega*omega/sin(omega))*vb0z;
67 >      else{
68 >        kDist = 6.0;
69 >        sprintf(painCave.errMsg,
70 >                "ThermoIntegration Warning: the spring constant for the\n"
71 >                "\ttranslational restraint was not specified. OOPSE will use\n"
72 >                "\ta default value of %f. To set it to something else, use\n"
73 >                "\tthe thermIntDistSpringConst variable.\n",
74 >                kDist);
75 >        painCave.isFatal = 0;
76 >        simError();
77        }
78 <
79 <      // next we calculate the restraint forces and torques
219 <      restraintFrc[0] = dVdrx;
220 <      restraintFrc[1] = dVdry;
221 <      restraintFrc[2] = dVdrz;
222 <      tempPotent = 0.5*kDist*(delRx*delRx + delRy*delRy + delRz*delRz);
223 <
224 <      restraintTrq[0] = 0.0;
225 <      restraintTrq[1] = 0.0;
226 <      restraintTrq[2] = 0.0;
227 <
228 <      if (fabs(omega) > tolerance) {
229 <        restraintTrq[0] += 0.0;
230 <        restraintTrq[1] += 0.0;
231 <        restraintTrq[2] += vTy*dVdvx;
232 <        tempPotent += 0.5*(kOmega*omega*omega);
78 >      if (simParam->haveThetaSpringConst()) {
79 >        kTheta = simParam->getThetaSpringConst();
80        }
81 <      if (fabs(theta) > tolerance) {
82 <        restraintTrq[0] += (uTz*dVduy);
83 <        restraintTrq[1] += -(uTz*dVdux);
84 <        restraintTrq[2] += 0.0;
85 <        tempPotent += 0.5*(kTheta*theta*theta);
81 >      else{
82 >        kTheta = 7.5;
83 >        sprintf(painCave.errMsg,
84 >                "ThermoIntegration Warning: the spring constant for the\n"
85 >                "\tdeflection orientational restraint was not specified.\n"
86 >                "\tOOPSE will use a default value of %f. To set it to\n"
87 >                "\tsomething else, use the thermIntThetaSpringConst variable.\n",
88 >                kTheta);
89 >        painCave.isFatal = 0;
90 >        simError();
91        }
92 <
93 <      for (j = 0; j < 3; j++) {
242 <        restraintFrc[j] *= factor;
243 <        restraintTrq[j] *= factor;
92 >      if (simParam->haveOmegaSpringConst()) {
93 >        kOmega = simParam->getOmegaSpringConst();
94        }
95 <
96 <      harmPotent += tempPotent;
97 <
98 <      // now we need to convert from body-fixed torques to space-fixed torques
99 <      spaceTrq[0] = A[0][0]*restraintTrq[0] + A[1][0]*restraintTrq[1]
100 <        + A[2][0]*restraintTrq[2];
101 <      spaceTrq[1] = A[0][1]*restraintTrq[0] + A[1][1]*restraintTrq[1]
102 <        + A[2][1]*restraintTrq[2];
103 <      spaceTrq[2] = A[0][2]*restraintTrq[0] + A[1][2]*restraintTrq[1]
104 <        + A[2][2]*restraintTrq[2];
105 <
256 <      // now it's time to pass these temporary forces and torques
257 <      // to the total forces and torques
258 <      vecParticles[i]->addFrc(restraintFrc);
259 <      vecParticles[i]->addTrq(spaceTrq);
95 >      else{
96 >        kOmega = 13.5;
97 >        sprintf(painCave.errMsg,
98 >                "ThermoIntegration Warning: the spring constant for the\n"
99 >                "\tspin orientational restraint was not specified. OOPSE\n"
100 >                "\twill use a default value of %f. To set it to something\n"
101 >                "\telse, use the thermIntOmegaSpringConst variable.\n",
102 >                kOmega);
103 >        painCave.isFatal = 0;
104 >        simError();
105 >      }
106      }
107 +    
108 +    // build a RestReader and read in important information
109 +    restRead_ = new RestReader(info_);
110 +    restRead_->readIdealCrystal();
111 +    restRead_->readZangle();
112 +    
113 +    delete restRead_;
114 +    restRead_ = NULL;
115 +    
116    }
262
263  // and we can return the appropriately scaled potential energy
264  tempPotent = harmPotent * factor;
265  return tempPotent;
266 }
267
268 void Restraints::Store_Init_Info(vector<StuntDouble*> vecParticles){
269  double pos[3];
270  double A[3][3];
271  double RfromQ[3][3];
272  double quat0, quat1, quat2, quat3;
273  double dot;
274 //   char *token;
275 //   char fileName[200];
276 //   char angleName[200];
277 //   char inLine[1000];
278 //   char inValue[200];
279  const char *delimit = " \t\n;,";
280
281  //open the idealCrystal.in file and zAngle.ang file
282  strcpy(fileName, "idealCrystal.in");
283  strcpy(angleName, "zAngle.ang");
117    
118 <  ifstream crystalIn(fileName);
119 <  ifstream angleIn(angleName);
120 <
121 <  if (!crystalIn) {
122 <    sprintf(painCave.errMsg,
123 <            "Restraints Error: Unable to open idealCrystal.in for reading.\n"
124 <            "\tMake sure a reference crystal file is in the current directory.\n");
292 <    painCave.isFatal = 1;
293 <    simError();  
118 >  Restraints::~Restraints(){
119 >  }
120 >  
121 >  void Restraints::Calc_rVal(Vector3d &position, double refPosition[3]){
122 >    delRx = position.x() - refPosition[0];
123 >    delRy = position.y() - refPosition[1];
124 >    delRz = position.z() - refPosition[2];
125      
126      return;
127    }
128 <
129 <  if (!angleIn) {
130 <    sprintf(painCave.errMsg,
131 <            "Restraints Warning: The lack of a zAngle.ang file is mildly\n"
132 <            "\tunsettling... This means the simulation is starting from the\n"
133 <            "\tidealCrystal.in reference configuration, so the omega values\n"
134 <            "\twill all be set to zero. If this is not the case, you should\n"
135 <            "\tquestion your results.\n");
136 <    painCave.isFatal = 0;
137 <    simError();  
128 >  
129 >  void Restraints::Calc_body_thetaVal(RotMat3x3d &matrix, double refUnit[3]){
130 >    ub0x = matrix(0,0)*refUnit[0] + matrix(0,1)*refUnit[1]
131 >    + matrix(0,2)*refUnit[2];
132 >    ub0y = matrix(1,0)*refUnit[0] + matrix(1,1)*refUnit[1]
133 >      + matrix(1,2)*refUnit[2];
134 >    ub0z = matrix(2,0)*refUnit[0] + matrix(2,1)*refUnit[1]
135 >      + matrix(2,2)*refUnit[2];
136 >    
137 >    normalize = sqrt(ub0x*ub0x + ub0y*ub0y + ub0z*ub0z);
138 >    ub0x = ub0x/normalize;
139 >    ub0y = ub0y/normalize;
140 >    ub0z = ub0z/normalize;
141 >    
142 >    // Theta is the dot product of the reference and new z-axes
143 >    theta = acos(ub0z);
144 >    
145 >    return;
146    }
308
309  // A rather specific reader for OOPSE .eor files...
310  // Let's read in the perfect crystal file
311  crystalIn.getline(inLine,999,'\n');
312  crystalIn.getline(inLine,999,'\n');
147    
148 <  for (i=0; i<vecParticles.size(); i++) {
149 <    crystalIn.getline(inLine,999,'\n');
150 <    token = strtok(inLine,delimit);
151 <    token = strtok(NULL,delimit);
152 <    strcpy(inValue,token);
153 <    cofmPosX.push_back(atof(inValue));
320 <    token = strtok(NULL,delimit);
321 <    strcpy(inValue,token);
322 <    cofmPosY.push_back(atof(inValue));
323 <    token = strtok(NULL,delimit);
324 <    strcpy(inValue,token);
325 <    cofmPosZ.push_back(atof(inValue));
326 <    token = strtok(NULL,delimit);
327 <    token = strtok(NULL,delimit);
328 <    token = strtok(NULL,delimit);
329 <    token = strtok(NULL,delimit);
330 <    strcpy(inValue,token);
331 <    quat0 = atof(inValue);
332 <    token = strtok(NULL,delimit);
333 <    strcpy(inValue,token);
334 <    quat1 = atof(inValue);
335 <    token = strtok(NULL,delimit);
336 <    strcpy(inValue,token);
337 <    quat2 = atof(inValue);
338 <    token = strtok(NULL,delimit);
339 <    strcpy(inValue,token);
340 <    quat3 = atof(inValue);
341 <
342 <    // now build the rotation matrix and find the unit vectors
343 <    RfromQ[0][0] = quat0*quat0 + quat1*quat1 - quat2*quat2 - quat3*quat3;
344 <    RfromQ[0][1] = 2*(quat1*quat2 + quat0*quat3);
345 <    RfromQ[0][2] = 2*(quat1*quat3 - quat0*quat2);
346 <    RfromQ[1][0] = 2*(quat1*quat2 - quat0*quat3);
347 <    RfromQ[1][1] = quat0*quat0 - quat1*quat1 + quat2*quat2 - quat3*quat3;
348 <    RfromQ[1][2] = 2*(quat2*quat3 + quat0*quat1);
349 <    RfromQ[2][0] = 2*(quat1*quat3 + quat0*quat2);
350 <    RfromQ[2][1] = 2*(quat2*quat3 - quat0*quat1);
351 <    RfromQ[2][2] = quat0*quat0 - quat1*quat1 - quat2*quat2 + quat3*quat3;
148 >  void Restraints::Calc_body_omegaVal(double zAngle){
149 >    double zRotator[3][3];
150 >    double tempOmega;
151 >    double wholeTwoPis;
152 >    // Use the omega accumulated from the rotation propagation
153 >    omega = zAngle;
154      
155 <    normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
156 <                     + RfromQ[2][2]*RfromQ[2][2]);
157 <    uX0.push_back(RfromQ[2][0]/normalize);
158 <    uY0.push_back(RfromQ[2][1]/normalize);
159 <    uZ0.push_back(RfromQ[2][2]/normalize);
160 <
161 <    normalize = sqrt(RfromQ[1][0]*RfromQ[1][0] + RfromQ[1][1]*RfromQ[1][1]
162 <                     + RfromQ[1][2]*RfromQ[1][2]);
163 <    vX0.push_back(RfromQ[1][0]/normalize);
164 <    vY0.push_back(RfromQ[1][1]/normalize);
165 <    vZ0.push_back(RfromQ[1][2]/normalize);
155 >    // translate the omega into a range between -PI and PI
156 >    if (omega < -PI){
157 >      tempOmega = omega / -TWO_PI;
158 >      wholeTwoPis = floor(tempOmega);
159 >      tempOmega = omega + TWO_PI*wholeTwoPis;
160 >      if (tempOmega < -PI)
161 >        omega = tempOmega + TWO_PI;
162 >      else
163 >        omega = tempOmega;
164 >    }
165 >    if (omega > PI){
166 >      tempOmega = omega / TWO_PI;
167 >      wholeTwoPis = floor(tempOmega);
168 >      tempOmega = omega - TWO_PI*wholeTwoPis;
169 >      if (tempOmega > PI)
170 >        omega = tempOmega - TWO_PI;  
171 >      else
172 >        omega = tempOmega;
173 >    }
174 >    
175 >    vb0x = sin(omega);
176 >    vb0y = cos(omega);
177 >    vb0z = 0.0;
178 >    
179 >    normalize = sqrt(vb0x*vb0x + vb0y*vb0y + vb0z*vb0z);
180 >    vb0x = vb0x/normalize;
181 >    vb0y = vb0y/normalize;
182 >    vb0z = vb0z/normalize;
183 >    
184 >    return;
185    }
186 <
187 <  // now we can read in the zAngle.ang file
188 <  if (angleIn){
189 <    angleIn.getline(inLine,999,'\n');
190 <    for (i=0; i<vecParticles.size(); i++) {
191 <      angleIn.getline(inLine,999,'\n');
192 <      token = strtok(inLine,delimit);
193 <      strcpy(inValue,token);
194 <      vecParticles[i]->setZangle(atof(inValue));
186 >  
187 >  double Restraints::Calc_Restraint_Forces(){
188 >    SimInfo::MoleculeIterator mi;
189 >    Molecule* mol;
190 >    Molecule::IntegrableObjectIterator ii;
191 >    StuntDouble* integrableObject;
192 >    Vector3d pos;
193 >    RotMat3x3d A;
194 >    double refPos[3];
195 >    double refVec[3];
196 >    double tolerance;
197 >    double tempPotent;
198 >    double factor;
199 >    double spaceTrq[3];
200 >    double omegaPass;
201 >    GenericData* data;
202 >    DoubleGenericData* doubleData;
203 >    
204 >    tolerance = 5.72957795131e-7;
205 >    
206 >    harmPotent = 0.0;  // zero out the global harmonic potential variable
207 >    
208 >    factor = 1 - pow(lambdaValue, lambdaK);
209 >    
210 >    for (mol = info_->beginMolecule(mi); mol != NULL;
211 >         mol = info_->nextMolecule(mi)) {
212 >      for (integrableObject = mol->beginIntegrableObject(ii);
213 >           integrableObject != NULL;
214 >           integrableObject = mol->nextIntegrableObject(ii)) {
215 >        
216 >        // obtain the current and reference positions
217 >        pos = integrableObject->getPos();
218 >        
219 >        data = integrableObject->getPropertyByName("refPosX");
220 >        if (data){
221 >          doubleData = dynamic_cast<DoubleGenericData*>(data);
222 >          if (!doubleData){
223 >            cerr << "Can't obtain refPosX from StuntDouble\n";
224 >            return 0.0;
225 >          }
226 >          else refPos[0] = doubleData->getData();
227 >        }
228 >        data = integrableObject->getPropertyByName("refPosY");
229 >        if (data){
230 >          doubleData = dynamic_cast<DoubleGenericData*>(data);
231 >          if (!doubleData){
232 >            cerr << "Can't obtain refPosY from StuntDouble\n";
233 >            return 0.0;
234 >          }
235 >          else refPos[1] = doubleData->getData();
236 >        }
237 >        data = integrableObject->getPropertyByName("refPosZ");
238 >        if (data){
239 >          doubleData = dynamic_cast<DoubleGenericData*>(data);
240 >          if (!doubleData){
241 >            cerr << "Can't obtain refPosZ from StuntDouble\n";
242 >            return 0.0;
243 >          }
244 >          else refPos[2] = doubleData->getData();
245 >        }
246 >        
247 >        // calculate the displacement
248 >        Calc_rVal( pos, refPos );
249 >        
250 >        // calculate the derivatives
251 >        dVdrx = -kDist*delRx;
252 >        dVdry = -kDist*delRy;
253 >        dVdrz = -kDist*delRz;
254 >        
255 >        // next we calculate the restraint forces
256 >        restraintFrc[0] = dVdrx;
257 >        restraintFrc[1] = dVdry;
258 >        restraintFrc[2] = dVdrz;
259 >        tempPotent = 0.5*kDist*(delRx*delRx + delRy*delRy + delRz*delRz);
260 >        
261 >        // apply the lambda scaling factor to the forces
262 >        for (j = 0; j < 3; j++) restraintFrc[j] *= factor;
263 >        
264 >        // and add the temporary force to the total force
265 >        integrableObject->addFrc(restraintFrc);
266 >        
267 >        // if the particle is directional, we accumulate the rot. restraints
268 >        if (integrableObject->isDirectional()){
269 >          
270 >          // get the current rotation matrix and reference vector
271 >          A = integrableObject->getA();
272 >          
273 >          data = integrableObject->getPropertyByName("refVectorX");
274 >          if (data){
275 >            doubleData = dynamic_cast<DoubleGenericData*>(data);
276 >            if (!doubleData){
277 >              cerr << "Can't obtain refVectorX from StuntDouble\n";
278 >              return 0.0;
279 >            }
280 >            else refVec[0] = doubleData->getData();
281 >          }
282 >          data = integrableObject->getPropertyByName("refVectorY");
283 >          if (data){
284 >            doubleData = dynamic_cast<DoubleGenericData*>(data);
285 >            if (!doubleData){
286 >              cerr << "Can't obtain refVectorY from StuntDouble\n";
287 >              return 0.0;
288 >            }
289 >            else refVec[1] = doubleData->getData();
290 >          }
291 >          data = integrableObject->getPropertyByName("refVectorZ");
292 >          if (data){
293 >            doubleData = dynamic_cast<DoubleGenericData*>(data);
294 >            if (!doubleData){
295 >              cerr << "Can't obtain refVectorZ from StuntDouble\n";
296 >              return 0.0;
297 >            }
298 >            else refVec[2] = doubleData->getData();
299 >          }
300 >          
301 >          // calculate the theta and omega displacements
302 >          Calc_body_thetaVal( A, refVec );
303 >          omegaPass = integrableObject->getZangle();
304 >          Calc_body_omegaVal( omegaPass );
305 >          
306 >          // uTx... and vTx... are the body-fixed z and y unit vectors
307 >          uTx = 0.0;
308 >          uTy = 0.0;
309 >          uTz = 1.0;
310 >          vTx = 0.0;
311 >          vTy = 1.0;
312 >          vTz = 0.0;
313 >          
314 >          dVdux = 0.0;
315 >          dVduy = 0.0;
316 >          dVduz = 0.0;
317 >          dVdvx = 0.0;
318 >          dVdvy = 0.0;
319 >          dVdvz = 0.0;
320 >          
321 >          if (fabs(theta) > tolerance) {
322 >            dVdux = -(kTheta*theta/sin(theta))*ub0x;
323 >            dVduy = -(kTheta*theta/sin(theta))*ub0y;
324 >            dVduz = -(kTheta*theta/sin(theta))*ub0z;
325 >          }
326 >          
327 >          if (fabs(omega) > tolerance) {
328 >            dVdvx = -(kOmega*omega/sin(omega))*vb0x;
329 >            dVdvy = -(kOmega*omega/sin(omega))*vb0y;
330 >            dVdvz = -(kOmega*omega/sin(omega))*vb0z;
331 >          }
332 >          
333 >          // next we calculate the restraint torques
334 >          restraintTrq[0] = 0.0;
335 >          restraintTrq[1] = 0.0;
336 >          restraintTrq[2] = 0.0;
337 >          
338 >          if (fabs(omega) > tolerance) {
339 >            restraintTrq[0] += 0.0;
340 >            restraintTrq[1] += 0.0;
341 >            restraintTrq[2] += vTy*dVdvx;
342 >            tempPotent += 0.5*(kOmega*omega*omega);
343 >          }
344 >          if (fabs(theta) > tolerance) {
345 >            restraintTrq[0] += (uTz*dVduy);
346 >            restraintTrq[1] += -(uTz*dVdux);
347 >            restraintTrq[2] += 0.0;
348 >            tempPotent += 0.5*(kTheta*theta*theta);
349 >          }
350 >          
351 >          // apply the lambda scaling factor to these torques
352 >          for (j = 0; j < 3; j++) restraintTrq[j] *= factor;
353 >          
354 >          // now we need to convert from body-fixed to space-fixed torques
355 >          spaceTrq[0] = A(0,0)*restraintTrq[0] + A(1,0)*restraintTrq[1]
356 >            + A(2,0)*restraintTrq[2];
357 >          spaceTrq[1] = A(0,1)*restraintTrq[0] + A(1,1)*restraintTrq[1]
358 >            + A(2,1)*restraintTrq[2];
359 >          spaceTrq[2] = A(0,2)*restraintTrq[0] + A(1,2)*restraintTrq[1]
360 >            + A(2,2)*restraintTrq[2];
361 >          
362 >          // now pass this temporary torque vector to the total torque
363 >          integrableObject->addTrq(spaceTrq);
364 >        }
365 >        
366 >        // update the total harmonic potential with this object's contribution
367 >        harmPotent += tempPotent;
368 >      }
369 >      
370      }
371 +    
372 +    // we can finish by returning the appropriately scaled potential energy
373 +    tempPotent = harmPotent * factor;
374 +    
375 +    return tempPotent;
376 +    
377    }
378 <
379 <  return;
378 < }
379 <
380 < void Restraints::Write_zAngle_File(vector<StuntDouble*> vecParticles){
381 <
382 <  char zOutName[200];
383 <
384 <  strcpy(zOutName,"zAngle.ang");
385 <
386 <  ofstream angleOut(zOutName);
387 <  angleOut << "This file contains the omega values for the .eor file\n";
388 <  for (i=0; i<vecParticles.size(); i++) {
389 <    angleOut << vecParticles[i]->getZangle() << "\n";
390 <  }
391 <  return;
392 < }
393 <
394 < double Restraints::getVharm(){
395 <  return harmPotent;
396 < }
397 <
378 >  
379 > }// end namespace oopse

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines