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 1731 by chrisfen, Thu Nov 11 21:47:25 2004 UTC vs.
Revision 2364 by tim, Thu Oct 13 22:26:47 2005 UTC

# Line 1 | Line 1
1 < // Thermodynamic integration is not multiprocessor friendly right now
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  
3 #include <iostream>
42   #include <stdlib.h>
5 #include <cstdio>
6 #include <fstream>
7 #include <iomanip>
8 #include <string>
9 #include <cstring>
43   #include <math.h>
44  
45   using namespace std;
46  
47   #include "restraints/Restraints.hpp"
48 < #include "brains/SimInfo.hpp"
48 > #include "primitives/Molecule.hpp"
49   #include "utils/simError.h"
17 #include "io/basic_ifstrstream.hpp"
50  
51   #define PI 3.14159265359
52   #define TWO_PI 6.28318530718
53  
54 < Restraints::Restraints(double lambdaVal, double lambdaExp){
55 <  lambdaValue = lambdaVal;
56 <  lambdaK = lambdaExp;
57 <  vector<double> resConsts;
58 <  const char *jolt = " \t\n;,";
54 > namespace oopse {
55 >  
56 >  Restraints::Restraints(SimInfo* info, double lambdaVal, double lambdaExp){
57 >    info_ = info;
58 >    Globals* simParam = info_->getSimParams();
59  
60 < #ifdef IS_MPI
61 <  if(worldRank == 0 ){
30 < #endif // is_mpi
31 <
32 <    strcpy(springName, "HarmSpringConsts.txt");
60 >    lambdaValue = lambdaVal;
61 >    lambdaK = lambdaExp;
62      
63 <    ifstream springs(springName);
64 <    
65 <    if (!springs) {
37 <      sprintf(painCave.errMsg,
38 <              "Unable to open HarmSpringConsts.txt for reading, so the\n"
39 <              "\tdefault spring constants will be loaded. If you want\n"
40 <              "\tto specify spring constants, include a three line\n"
41 <              "\tHarmSpringConsts.txt file in the execution directory.\n");
42 <      painCave.severity = OOPSE_WARNING;
43 <      painCave.isFatal = 0;
44 <      simError();  
45 <      
46 <      // load default spring constants
47 <      kDist  = 6;  // spring constant in units of kcal/(mol*ang^2)
48 <      kTheta = 7.5;   // in units of kcal/mol
49 <      kOmega = 13.5;   // in units of kcal/mol
50 <    } else  {
51 <      
52 <      springs.getline(inLine,999,'\n');
53 <      // the file is blank!
54 <      if (springs.eof()){
55 <      sprintf(painCave.errMsg,
56 <              "HarmSpringConsts.txt file is not valid.\n"
57 <              "\tThe file should contain four rows, the last three containing\n"
58 <              "\ta label and the spring constant value. They should be listed\n"
59 <              "\tin the following order: kDist (positional restrant), kTheta\n"
60 <              "\t(rot. restraint: deflection of z-axis), and kOmega (rot.\n"
61 <              "\trestraint: rotation about the z-axis).\n");
62 <      painCave.severity = OOPSE_ERROR;
63 <      painCave.isFatal = 1;
64 <      simError();  
63 >    if (simParam->getUseSolidThermInt()) {
64 >      if (simParam->haveThermIntDistSpringConst()) {
65 >        kDist = simParam->getThermIntDistSpringConst();
66        }
67 <      // read in spring constants and check to make sure it is a valid file
68 <      springs.getline(inLine,999,'\n');
69 <      while (!springs.eof()){
70 <        if (NULL != inLine){
71 <          token = strtok(inLine,jolt);
72 <          token = strtok(NULL,jolt);
73 <          if (NULL != token){
74 <            strcpy(inValue,token);
75 <            resConsts.push_back(atof(inValue));
76 <          }
76 <        }
77 <        springs.getline(inLine,999,'\n');
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 <      if (resConsts.size() == 3){
79 <        kDist = resConsts[0];
81 <        kTheta = resConsts[1];
82 <        kOmega = resConsts[2];
78 >      if (simParam->haveThermIntThetaSpringConst()) {
79 >        kTheta = simParam->getThermIntThetaSpringConst();
80        }
81 <      else {
82 <        sprintf(painCave.errMsg,
83 <                "HarmSpringConsts.txt file is not valid.\n"
84 <                "\tThe file should contain four rows, the last three containing\n"
85 <                "\ta label and the spring constant value. They should be listed\n"
86 <                "\tin the following order: kDist (positional restrant), kTheta\n"
87 <                "\t(rot. restraint: deflection of z-axis), and kOmega (rot.\n"
88 <                "\trestraint: rotation about the z-axis).\n");
89 <        painCave.severity = OOPSE_ERROR;
90 <        painCave.isFatal = 1;
94 <        simError();  
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 +      if (simParam->haveThermIntOmegaSpringConst()) {
93 +        kOmega = simParam->getThermIntOmegaSpringConst();
94 +      }
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 < #ifdef IS_MPI
107 >    
108 >    // build a RestReader and read in important information
109 >    
110 >    restRead_ = new RestReader(info_);
111 >    restRead_->readIdealCrystal();
112 >    restRead_->readZangle();
113 >    
114 >    delete restRead_;
115 >    restRead_ = NULL;
116 >    
117    }
118    
119 <  MPI_Bcast(&kDist, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
120 <  MPI_Bcast(&kTheta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
102 <  MPI_Bcast(&kOmega, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
119 >  Restraints::~Restraints(){
120 >  }
121    
122 <  sprintf( checkPointMsg,
123 <           "Sucessfully opened and read spring file.\n");
124 <  MPIcheckPoint();
125 <
126 < #endif // is_mpi
122 >  void Restraints::Calc_rVal(Vector3d &position, double refPosition[3]){
123 >    delRx = position.x() - refPosition[0];
124 >    delRy = position.y() - refPosition[1];
125 >    delRz = position.z() - refPosition[2];
126 >    
127 >    return;
128 >  }
129    
130 <  sprintf(painCave.errMsg,
131 <          "The spring constants for thermodynamic integration are:\n"
132 <          "\tkDist = %lf\n"
133 <          "\tkTheta = %lf\n"
134 <          "\tkOmega = %lf\n", kDist, kTheta, kOmega);
135 <  painCave.severity = OOPSE_INFO;
136 <  painCave.isFatal = 0;
137 <  simError();  
138 < }
139 <
140 < Restraints::~Restraints(){
141 < }
142 <
143 < void Restraints::Calc_rVal(double position[3], int currentMol){
144 <  delRx = position[0] - cofmPosX[currentMol];
145 <  delRy = position[1] - cofmPosY[currentMol];
146 <  delRz = position[2] - cofmPosZ[currentMol];
127 <
128 <  return;
129 < }
130 <
131 < void Restraints::Calc_body_thetaVal(double matrix[3][3], int currentMol){
132 <  ub0x = matrix[0][0]*uX0[currentMol] + matrix[0][1]*uY0[currentMol]
133 <    + matrix[0][2]*uZ0[currentMol];
134 <  ub0y = matrix[1][0]*uX0[currentMol] + matrix[1][1]*uY0[currentMol]
135 <    + matrix[1][2]*uZ0[currentMol];
136 <  ub0z = matrix[2][0]*uX0[currentMol] + matrix[2][1]*uY0[currentMol]
137 <    + matrix[2][2]*uZ0[currentMol];
138 <
139 <  normalize = sqrt(ub0x*ub0x + ub0y*ub0y + ub0z*ub0z);
140 <  ub0x = ub0x/normalize;
141 <  ub0y = ub0y/normalize;
142 <  ub0z = ub0z/normalize;
143 <
144 <  // Theta is the dot product of the reference and new z-axes
145 <  theta = acos(ub0z);
146 <
147 <  return;
148 < }
149 <
150 < void Restraints::Calc_body_omegaVal(double matrix[3][3], double zAngle){
151 <  double zRotator[3][3];
152 <  double tempOmega;
153 <  double wholeTwoPis;
154 <  // Use the omega accumulated from the rotation propagation
155 <  omega = zAngle;
156 <
157 <  // translate the omega into a range between -PI and PI
158 <  if (omega < -PI){
159 <    tempOmega = omega / -TWO_PI;
160 <    wholeTwoPis = floor(tempOmega);
161 <    tempOmega = omega + TWO_PI*wholeTwoPis;
162 <    if (tempOmega < -PI)
163 <      omega = tempOmega + TWO_PI;
164 <    else
165 <      omega = tempOmega;
130 >  void Restraints::Calc_body_thetaVal(RotMat3x3d &matrix, double refUnit[3]){
131 >    ub0x = matrix(0,0)*refUnit[0] + matrix(0,1)*refUnit[1]
132 >      + matrix(0,2)*refUnit[2];
133 >    ub0y = matrix(1,0)*refUnit[0] + matrix(1,1)*refUnit[1]
134 >      + matrix(1,2)*refUnit[2];
135 >    ub0z = matrix(2,0)*refUnit[0] + matrix(2,1)*refUnit[1]
136 >      + matrix(2,2)*refUnit[2];
137 >    
138 >    normalize = sqrt(ub0x*ub0x + ub0y*ub0y + ub0z*ub0z);
139 >    ub0x = ub0x/normalize;
140 >    ub0y = ub0y/normalize;
141 >    ub0z = ub0z/normalize;
142 >    
143 >    // Theta is the dot product of the reference and new z-axes
144 >    theta = acos(ub0z);
145 >    
146 >    return;
147    }
148 <  if (omega > PI){
149 <    tempOmega = omega / TWO_PI;
150 <    wholeTwoPis = floor(tempOmega);
151 <    tempOmega = omega - TWO_PI*wholeTwoPis;
152 <    if (tempOmega > PI)
153 <      omega = tempOmega - TWO_PI;  
154 <    else
155 <      omega = tempOmega;
148 >  
149 >  void Restraints::Calc_body_omegaVal(double zAngle){
150 >    double zRotator[3][3];
151 >    double tempOmega;
152 >    double wholeTwoPis;
153 >    // Use the omega accumulated from the rotation propagation
154 >    omega = zAngle;
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 <  vb0x = sin(omega);
189 <  vb0y = cos(omega);
190 <  vb0z = 0.0;
191 <
192 <  normalize = sqrt(vb0x*vb0x + vb0y*vb0y + vb0z*vb0z);
193 <  vb0x = vb0x/normalize;
194 <  vb0y = vb0y/normalize;
195 <  vb0z = vb0z/normalize;
196 <
197 <  return;
198 < }
199 <
200 < double Restraints::Calc_Restraint_Forces(vector<StuntDouble*> vecParticles){
201 <  double pos[3];
202 <  double A[3][3];
203 <  double tolerance;
204 <  double tempPotent;
205 <  double factor;
206 <  double spaceTrq[3];
207 <  double omegaPass;
208 <
209 <  tolerance = 5.72957795131e-7;
210 <
211 <  harmPotent = 0.0;  // zero out the global harmonic potential variable
212 <
213 <  factor = 1 - pow(lambdaValue, lambdaK);
214 <
215 <  for (i=0; i<vecParticles.size(); i++){
216 <    if (vecParticles[i]->isDirectional()){
217 <      vecParticles[i]->getPos(pos);
218 <      vecParticles[i]->getA(A);
219 <      Calc_rVal( pos, i );
220 <      Calc_body_thetaVal( A, i );
221 <      omegaPass = vecParticles[i]->getZangle();
222 <      Calc_body_omegaVal( A, omegaPass );
223 <
224 <      // first we calculate the derivatives
225 <      dVdrx = -kDist*delRx;
226 <      dVdry = -kDist*delRy;
227 <      dVdrz = -kDist*delRz;
228 <
229 <      // uTx... and vTx... are the body-fixed z and y unit vectors
230 <      uTx = 0.0;
231 <      uTy = 0.0;
232 <      uTz = 1.0;
233 <      vTx = 0.0;
234 <      vTy = 1.0;
235 <      vTz = 0.0;
236 <
237 <      dVdux = 0;
238 <      dVduy = 0;
239 <      dVduz = 0;
240 <      dVdvx = 0;
241 <      dVdvy = 0;
242 <      dVdvz = 0;
243 <
244 <      if (fabs(theta) > tolerance) {
245 <        dVdux = -(kTheta*theta/sin(theta))*ub0x;
246 <        dVduy = -(kTheta*theta/sin(theta))*ub0y;
247 <        dVduz = -(kTheta*theta/sin(theta))*ub0z;
248 <      }
249 <
250 <      if (fabs(omega) > tolerance) {
251 <        dVdvx = -(kOmega*omega/sin(omega))*vb0x;
252 <        dVdvy = -(kOmega*omega/sin(omega))*vb0y;
253 <        dVdvz = -(kOmega*omega/sin(omega))*vb0z;
187 >  
188 >  double Restraints::Calc_Restraint_Forces(){
189 >    SimInfo::MoleculeIterator mi;
190 >    Molecule* mol;
191 >    Molecule::IntegrableObjectIterator ii;
192 >    StuntDouble* integrableObject;
193 >    Vector3d pos;
194 >    RotMat3x3d A;
195 >    double refPos[3];
196 >    double refVec[3];
197 >    double tolerance;
198 >    double tempPotent;
199 >    double factor;
200 >    double spaceTrq[3];
201 >    double omegaPass;
202 >    GenericData* data;
203 >    DoubleGenericData* doubleData;
204 >    
205 >    tolerance = 5.72957795131e-7;
206 >    
207 >    harmPotent = 0.0;  // zero out the global harmonic potential variable
208 >    
209 >    factor = 1 - pow(lambdaValue, lambdaK);
210 >    
211 >    for (mol = info_->beginMolecule(mi); mol != NULL;
212 >         mol = info_->nextMolecule(mi)) {
213 >      for (integrableObject = mol->beginIntegrableObject(ii);
214 >           integrableObject != NULL;
215 >           integrableObject = mol->nextIntegrableObject(ii)) {
216 >        
217 >        // obtain the current and reference positions
218 >        pos = integrableObject->getPos();
219 >        
220 >        data = integrableObject->getPropertyByName("refPosX");
221 >        if (data){
222 >          doubleData = dynamic_cast<DoubleGenericData*>(data);
223 >          if (!doubleData){
224 >            cerr << "Can't obtain refPosX from StuntDouble\n";
225 >            return 0.0;
226 >          }
227 >          else refPos[0] = doubleData->getData();
228 >        }
229 >        data = integrableObject->getPropertyByName("refPosY");
230 >        if (data){
231 >          doubleData = dynamic_cast<DoubleGenericData*>(data);
232 >          if (!doubleData){
233 >            cerr << "Can't obtain refPosY from StuntDouble\n";
234 >            return 0.0;
235 >          }
236 >          else refPos[1] = doubleData->getData();
237 >        }
238 >        data = integrableObject->getPropertyByName("refPosZ");
239 >        if (data){
240 >          doubleData = dynamic_cast<DoubleGenericData*>(data);
241 >          if (!doubleData){
242 >            cerr << "Can't obtain refPosZ from StuntDouble\n";
243 >            return 0.0;
244 >          }
245 >          else refPos[2] = doubleData->getData();
246 >        }
247 >        
248 >        // calculate the displacement
249 >        Calc_rVal( pos, refPos );
250 >        
251 >        // calculate the derivatives
252 >        dVdrx = -kDist*delRx;
253 >        dVdry = -kDist*delRy;
254 >        dVdrz = -kDist*delRz;
255 >        
256 >        // next we calculate the restraint forces
257 >        restraintFrc[0] = dVdrx;
258 >        restraintFrc[1] = dVdry;
259 >        restraintFrc[2] = dVdrz;
260 >        tempPotent = 0.5*kDist*(delRx*delRx + delRy*delRy + delRz*delRz);
261 >        
262 >        // apply the lambda scaling factor to the forces
263 >        for (j = 0; j < 3; j++) restraintFrc[j] *= factor;
264 >        
265 >        // and add the temporary force to the total force
266 >        integrableObject->addFrc(restraintFrc);
267 >        
268 >        // if the particle is directional, we accumulate the rot. restraints
269 >        if (integrableObject->isDirectional()){
270 >          
271 >          // get the current rotation matrix and reference vector
272 >          A = integrableObject->getA();
273 >          
274 >          data = integrableObject->getPropertyByName("refVectorX");
275 >          if (data){
276 >            doubleData = dynamic_cast<DoubleGenericData*>(data);
277 >            if (!doubleData){
278 >              cerr << "Can't obtain refVectorX from StuntDouble\n";
279 >              return 0.0;
280 >            }
281 >            else refVec[0] = doubleData->getData();
282 >          }
283 >          data = integrableObject->getPropertyByName("refVectorY");
284 >          if (data){
285 >            doubleData = dynamic_cast<DoubleGenericData*>(data);
286 >            if (!doubleData){
287 >              cerr << "Can't obtain refVectorY from StuntDouble\n";
288 >              return 0.0;
289 >            }
290 >            else refVec[1] = doubleData->getData();
291 >          }
292 >          data = integrableObject->getPropertyByName("refVectorZ");
293 >          if (data){
294 >            doubleData = dynamic_cast<DoubleGenericData*>(data);
295 >            if (!doubleData){
296 >              cerr << "Can't obtain refVectorZ from StuntDouble\n";
297 >              return 0.0;
298 >            }
299 >            else refVec[2] = doubleData->getData();
300 >          }
301 >          
302 >          // calculate the theta and omega displacements
303 >          Calc_body_thetaVal( A, refVec );
304 >          omegaPass = integrableObject->getZangle();
305 >          Calc_body_omegaVal( omegaPass );
306 >          
307 >          // uTx... and vTx... are the body-fixed z and y unit vectors
308 >          uTx = 0.0;
309 >          uTy = 0.0;
310 >          uTz = 1.0;
311 >          vTx = 0.0;
312 >          vTy = 1.0;
313 >          vTz = 0.0;
314 >          
315 >          dVdux = 0.0;
316 >          dVduy = 0.0;
317 >          dVduz = 0.0;
318 >          dVdvx = 0.0;
319 >          dVdvy = 0.0;
320 >          dVdvz = 0.0;
321 >          
322 >          if (fabs(theta) > tolerance) {
323 >            dVdux = -(kTheta*theta/sin(theta))*ub0x;
324 >            dVduy = -(kTheta*theta/sin(theta))*ub0y;
325 >            dVduz = -(kTheta*theta/sin(theta))*ub0z;
326 >          }
327 >          
328 >          if (fabs(omega) > tolerance) {
329 >            dVdvx = -(kOmega*omega/sin(omega))*vb0x;
330 >            dVdvy = -(kOmega*omega/sin(omega))*vb0y;
331 >            dVdvz = -(kOmega*omega/sin(omega))*vb0z;
332 >          }
333 >          
334 >          // next we calculate the restraint torques
335 >          restraintTrq[0] = 0.0;
336 >          restraintTrq[1] = 0.0;
337 >          restraintTrq[2] = 0.0;
338 >          
339 >          if (fabs(omega) > tolerance) {
340 >            restraintTrq[0] += 0.0;
341 >            restraintTrq[1] += 0.0;
342 >            restraintTrq[2] += vTy*dVdvx;
343 >            tempPotent += 0.5*(kOmega*omega*omega);
344 >          }
345 >          if (fabs(theta) > tolerance) {
346 >            restraintTrq[0] += (uTz*dVduy);
347 >            restraintTrq[1] += -(uTz*dVdux);
348 >            restraintTrq[2] += 0.0;
349 >            tempPotent += 0.5*(kTheta*theta*theta);
350 >          }
351 >          
352 >          // apply the lambda scaling factor to these torques
353 >          for (j = 0; j < 3; j++) restraintTrq[j] *= factor;
354 >          
355 >          // now we need to convert from body-fixed to space-fixed torques
356 >          spaceTrq[0] = A(0,0)*restraintTrq[0] + A(1,0)*restraintTrq[1]
357 >            + A(2,0)*restraintTrq[2];
358 >          spaceTrq[1] = A(0,1)*restraintTrq[0] + A(1,1)*restraintTrq[1]
359 >            + A(2,1)*restraintTrq[2];
360 >          spaceTrq[2] = A(0,2)*restraintTrq[0] + A(1,2)*restraintTrq[1]
361 >            + A(2,2)*restraintTrq[2];
362 >          
363 >          // now pass this temporary torque vector to the total torque
364 >          integrableObject->addTrq(spaceTrq);
365 >        }
366 >        
367 >        // update the total harmonic potential with this object's contribution
368 >        harmPotent += tempPotent;
369        }
370 <
245 <      // next we calculate the restraint forces and torques
246 <      restraintFrc[0] = dVdrx;
247 <      restraintFrc[1] = dVdry;
248 <      restraintFrc[2] = dVdrz;
249 <      tempPotent = 0.5*kDist*(delRx*delRx + delRy*delRy + delRz*delRz);
250 <
251 <      restraintTrq[0] = 0.0;
252 <      restraintTrq[1] = 0.0;
253 <      restraintTrq[2] = 0.0;
254 <
255 <      if (fabs(omega) > tolerance) {
256 <        restraintTrq[0] += 0.0;
257 <        restraintTrq[1] += 0.0;
258 <        restraintTrq[2] += vTy*dVdvx;
259 <        tempPotent += 0.5*(kOmega*omega*omega);
260 <      }
261 <      if (fabs(theta) > tolerance) {
262 <        restraintTrq[0] += (uTz*dVduy);
263 <        restraintTrq[1] += -(uTz*dVdux);
264 <        restraintTrq[2] += 0.0;
265 <        tempPotent += 0.5*(kTheta*theta*theta);
266 <      }
267 <
268 <      for (j = 0; j < 3; j++) {
269 <        restraintFrc[j] *= factor;
270 <        restraintTrq[j] *= factor;
271 <      }
272 <
273 <      harmPotent += tempPotent;
274 <
275 <      // now we need to convert from body-fixed torques to space-fixed torques
276 <      spaceTrq[0] = A[0][0]*restraintTrq[0] + A[1][0]*restraintTrq[1]
277 <        + A[2][0]*restraintTrq[2];
278 <      spaceTrq[1] = A[0][1]*restraintTrq[0] + A[1][1]*restraintTrq[1]
279 <        + A[2][1]*restraintTrq[2];
280 <      spaceTrq[2] = A[0][2]*restraintTrq[0] + A[1][2]*restraintTrq[1]
281 <        + A[2][2]*restraintTrq[2];
282 <
283 <      // now it's time to pass these temporary forces and torques
284 <      // to the total forces and torques
285 <      vecParticles[i]->addFrc(restraintFrc);
286 <      vecParticles[i]->addTrq(spaceTrq);
370 >      
371      }
288  }
289
290  // and we can return the appropriately scaled potential energy
291  tempPotent = harmPotent * factor;
292  return tempPotent;
293 }
294
295 void Restraints::Store_Init_Info(vector<StuntDouble*> vecParticles){
296  int idealSize;
297  double pos[3];
298  double A[3][3];
299  double RfromQ[3][3];
300  double quat0, quat1, quat2, quat3;
301  double dot;
302  vector<double> tempZangs;
303  const char *delimit = " \t\n;,";
304
305  //open the idealCrystal.in file and zAngle.ang file
306  strcpy(fileName, "idealCrystal.in");
307  strcpy(angleName, "zAngle.ang");
308  
309  ifstrstream crystalIn(fileName);
310  ifstrstream angleIn(angleName);
311
312  // check to see if these files are present in the execution directory
313  if (!crystalIn) {
314    sprintf(painCave.errMsg,
315            "Restraints Error: Unable to open idealCrystal.in for reading.\n"
316            "\tMake sure a ref. crystal file is in the working directory.\n");
317    painCave.severity = OOPSE_ERROR;
318    painCave.isFatal = 1;
319    simError();  
320  }
321
322  // it's not fatal to lack a zAngle.ang file, it just means you're starting
323  // from the ideal crystal state
324  if (!angleIn) {
325    sprintf(painCave.errMsg,
326            "Restraints Warning: The lack of a zAngle.ang file is mildly\n"
327            "\tunsettling... This means the simulation is starting from the\n"
328            "\tidealCrystal.in reference configuration, so the omega values\n"
329            "\twill all be set to zero. If this is not the case, the energy\n"
330            "\tcalculations will be wrong.\n");
331    painCave.severity = OOPSE_WARNING;
332    painCave.isFatal = 0;
333    simError();  
334  }
335
336  // A rather specific reader for OOPSE .eor files...
337  // Let's read in the perfect crystal file
338  crystalIn.getline(inLine,999,'\n');
339  // check to see if the crystal file is the same length as starting config.
340  token = strtok(inLine,delimit);
341  strcpy(inValue,token);
342  idealSize = atoi(inValue);
343  if (idealSize != vecParticles.size()) {
344    sprintf(painCave.errMsg,
345            "Restraints Error: Reference crystal file is not valid.\n"
346            "\tMake sure the idealCrystal.in file is the same size as the\n"
347            "\tstarting configuration. Using an incompatable crystal will\n"
348            "\tlead to energy calculation failures.\n");
349    painCave.severity = OOPSE_ERROR;
350    painCave.isFatal = 1;
351    simError();  
352  }
353  // else, the file is okay... let's continue
354  crystalIn.getline(inLine,999,'\n');
355  
356  for (i=0; i<vecParticles.size(); i++) {
357    crystalIn.getline(inLine,999,'\n');
358    token = strtok(inLine,delimit);
359    token = strtok(NULL,delimit);
360    strcpy(inValue,token);
361    cofmPosX.push_back(atof(inValue));
362    token = strtok(NULL,delimit);
363    strcpy(inValue,token);
364    cofmPosY.push_back(atof(inValue));
365    token = strtok(NULL,delimit);
366    strcpy(inValue,token);
367    cofmPosZ.push_back(atof(inValue));
368    token = strtok(NULL,delimit);
369    token = strtok(NULL,delimit);
370    token = strtok(NULL,delimit);
371    token = strtok(NULL,delimit);
372    strcpy(inValue,token);
373    quat0 = atof(inValue);
374    token = strtok(NULL,delimit);
375    strcpy(inValue,token);
376    quat1 = atof(inValue);
377    token = strtok(NULL,delimit);
378    strcpy(inValue,token);
379    quat2 = atof(inValue);
380    token = strtok(NULL,delimit);
381    strcpy(inValue,token);
382    quat3 = atof(inValue);
383
384    // now build the rotation matrix and find the unit vectors
385    RfromQ[0][0] = quat0*quat0 + quat1*quat1 - quat2*quat2 - quat3*quat3;
386    RfromQ[0][1] = 2*(quat1*quat2 + quat0*quat3);
387    RfromQ[0][2] = 2*(quat1*quat3 - quat0*quat2);
388    RfromQ[1][0] = 2*(quat1*quat2 - quat0*quat3);
389    RfromQ[1][1] = quat0*quat0 - quat1*quat1 + quat2*quat2 - quat3*quat3;
390    RfromQ[1][2] = 2*(quat2*quat3 + quat0*quat1);
391    RfromQ[2][0] = 2*(quat1*quat3 + quat0*quat2);
392    RfromQ[2][1] = 2*(quat2*quat3 - quat0*quat1);
393    RfromQ[2][2] = quat0*quat0 - quat1*quat1 - quat2*quat2 + quat3*quat3;
372      
373 <    normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
374 <                     + RfromQ[2][2]*RfromQ[2][2]);
375 <    uX0.push_back(RfromQ[2][0]/normalize);
376 <    uY0.push_back(RfromQ[2][1]/normalize);
377 <    uZ0.push_back(RfromQ[2][2]/normalize);
400 <
401 <    normalize = sqrt(RfromQ[1][0]*RfromQ[1][0] + RfromQ[1][1]*RfromQ[1][1]
402 <                     + RfromQ[1][2]*RfromQ[1][2]);
403 <    vX0.push_back(RfromQ[1][0]/normalize);
404 <    vY0.push_back(RfromQ[1][1]/normalize);
405 <    vZ0.push_back(RfromQ[1][2]/normalize);
373 >    // we can finish by returning the appropriately scaled potential energy
374 >    tempPotent = harmPotent * factor;
375 >    
376 >    return tempPotent;
377 >    
378    }
379 <  crystalIn.close();
380 <
409 <  // now we read in the zAngle.ang file
410 <  if (angleIn){
411 <    angleIn.getline(inLine,999,'\n');
412 <    angleIn.getline(inLine,999,'\n');
413 <    while (!angleIn.eof()) {
414 <      token = strtok(inLine,delimit);
415 <      strcpy(inValue,token);
416 <      tempZangs.push_back(atof(inValue));
417 <      angleIn.getline(inLine,999,'\n');
418 <    }
419 <
420 <    // test to make sure the zAngle.ang file is the proper length
421 <    if (tempZangs.size() == vecParticles.size())
422 <      for (i=0; i<vecParticles.size(); i++)
423 <        vecParticles[i]->setZangle(tempZangs[i]);
424 <    else {
425 <      sprintf(painCave.errMsg,
426 <              "Restraints Error: the supplied zAngle file is not valid.\n"
427 <              "\tMake sure the zAngle.ang file matches with the initial\n"
428 <              "\tconfiguration (i.e. they're the same length). Using the wrong\n"
429 <              "\tzAngle file will lead to errors in the energy calculations.\n");
430 <      painCave.severity = OOPSE_ERROR;
431 <      painCave.isFatal = 1;
432 <      simError();  
433 <    }
434 <  }
435 <  angleIn.close();
436 <
437 <  return;
438 < }
439 <
440 < void Restraints::Write_zAngle_File(vector<StuntDouble*> vecParticles){
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<vecParticles.size(); i++) {
449 <    angleOut << vecParticles[i]->getZangle() << "\n";
450 <  }
451 <  return;
452 < }
453 <
454 < double Restraints::getVharm(){
455 <  return harmPotent;
456 < }
457 <
379 >  
380 > }// end namespace oopse

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines