ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/primitives/Torsion.cpp
(Generate patch)

Comparing branches/new_design/OOPSE-3.0/src/primitives/Torsion.cpp (file contents):
Revision 1745 by tim, Tue Nov 16 20:36:18 2004 UTC vs.
Revision 1746 by tim, Wed Nov 17 06:37:56 2004 UTC

# Line 1 | Line 1
1 < #include "primitives/Torsion.hpp"
2 <
3 < namespace oopse {
4 <
5 < Torsion::Torsion(Atom* atom1, Atom* atom2, Atom* atom3, Atom* atom4, TorsionType* tt)
6 <            : atom1_(atom1), atom2_(atom2), atom3_(atom3), atom4_(atom4) {
7 <
8 < }
9 <
10 < void Torsion::calcForce() {
11 <
12 <    Vector3d pos1 = atom1_->getPos();
13 <    Vector3d pos2 = atom2_->getPos();
14 <    Vector3d pos3 = atom3_->getPos();
15 <    Vector3d pos4 = atom4_->getPos();
16 <
17 <    Vector3d r12 = pos1 - pos2;
18 <    Vector3d r23 = pos2 - pos3;
19 <    Vector3d r34 = pos3 - pos4;
20 <
21 <    //  Calculate the cross products and distances
22 <    Vector3d A = cross(r12,r23);
23 <    double rA = A.length();
24 <    Vector3d B = cross(r23,r34);
25 <    double rB = B.length();
26 <    Vector3d C = cross(r23,A);
27 <    double rC = C.length();
28 <
29 <    //  Calculate the sin and cos
30 <    double cos_phi = (A*B)/(rA*rB);
31 <    double sin_phi = (C*B)/(rC*rB);
32 <
33 <    double phi= -atan2(sin_phi,cos_phi);
34 <
35 <    double firstDerivative;
36 <    torsionType_->calcForce(phi, firstDerivative, potential_);
37 <
38 <
39 <    Vector3d f1,f2,f3;
40 <    
41 <    //  Normalize B
42 <    rB = 1.0/rB;
43 <    B *= rB;
44 <
45 <    //  Next, we want to calculate the forces.  In order
46 <    //  to do that, we first need to figure out whether the
47 <    //  sin or cos form will be more stable.  For this,
48 <    //  just look at the value of phi
49 <    if (fabs(sin_phi) > 0.1) {
50 <        //  use the sin version to avoid 1/cos terms
51 <
52 <        rA = 1.0/rA;
53 <        A *= rA;
54 <        Vector3d dcosdA = rA*(cos_phi*A-B);
55 <        Vector3d dcosdB = rB*(cos_phi*B-A);
56 <
57 <        K1 = K1/sin_phi;
58 <
59 <        //simple form
60 <        //f1 = K1 * cross(r23, dcosdA);
61 <        //f3 = K1 * cross(r23, dcosdB);
62 <        //f2 = K1 * ( cross(r34, dcosdB) - cross(r12, dcosdA));
63 <
64 <        f1.x = K1*(r23.y*dcosdA.z - r23.z*dcosdA.y);
65 <        f1.y = K1*(r23.z*dcosdA.x - r23.x*dcosdA.z);
66 <        f1.z = K1*(r23.x*dcosdA.y - r23.y*dcosdA.x);
67 <
68 <        f3.x = K1*(r23.z*dcosdB.y - r23.y*dcosdB.z);
69 <        f3.y = K1*(r23.x*dcosdB.z - r23.z*dcosdB.x);
70 <        f3.z = K1*(r23.y*dcosdB.x - r23.x*dcosdB.y);
71 <
72 <        f2.x = K1*(r12.z*dcosdA.y - r12.y*dcosdA.z + r34.y*dcosdB.z - r34.z*dcosdB.y);
73 <        f2.y = K1*(r12.x*dcosdA.z - r12.z*dcosdA.x + r34.z*dcosdB.x - r34.x*dcosdB.z);
74 <        f2.z = K1*(r12.y*dcosdA.x - r12.x*dcosdA.y + r34.x*dcosdB.y - r34.y*dcosdB.x);
75 <    } else {
76 <        //  This angle is closer to 0 or 180 than it is to
77 <        //  90, so use the cos version to avoid 1/sin terms
78 <
79 <        //  Normalize C
80 <        rC = 1.0/rC;
81 <        C *= rC;
82 <        Vector3d dsindC = rC*(sin_phi*C-B);
83 <        Vector3d dsindB = rB*(sin_phi*B-C);
84 <
85 <        K1 = -K1/cos_phi;
86 <
87 <        f1.x = K1*((r23.y*r23.y + r23.z*r23.z)*dsindC.x - r23.x*r23.y*dsindC.y - r23.x*r23.z*dsindC.z);
88 <        f1.y = K1*((r23.z*r23.z + r23.x*r23.x)*dsindC.y - r23.y*r23.z*dsindC.z - r23.y*r23.x*dsindC.x);
89 <        f1.z = K1*((r23.x*r23.x + r23.y*r23.y)*dsindC.z - r23.z*r23.x*dsindC.x - r23.z*r23.y*dsindC.y);
90 <
91 <        f3 = K1 *cross(dsindB,r23);
92 <
93 <        f2.x = K1*(-(r23.y*r12.y + r23.z*r12.z)*dsindC.x + (2.0*r23.x*r12.y - r12.x*r23.y)*dsindC.y
94 <                 + (2.0*r23.x*r12.z - r12.x*r23.z)*dsindC.z + dsindB.z*r34.y - dsindB.y*r34.z);
95 <        f2.y = K1*(-(r23.z*r12.z + r23.x*r12.x)*dsindC.y + (2.0*r23.y*r12.z - r12.y*r23.z)*dsindC.z
96 <                 + (2.0*r23.y*r12.x - r12.y*r23.x)*dsindC.x + dsindB.x*r34.z - dsindB.z*r34.x);
97 <        f2.z = K1*(-(r23.x*r12.x + r23.y*r12.y)*dsindC.z + (2.0*r23.z*r12.x - r12.z*r23.x)*dsindC.x
98 <                  +(2.0*r23.z*r12.y - r12.z*r23.y)*dsindC.y + dsindB.y*r34.x - dsindB.x*r34.y);
99 <    }
100 <
101 <    atom1_->addFrc(f1);
102 <    atom2_->addFrc(f2 - f1);
103 <    atom3_->addFrc(f3 - f2);
104 <    atom4_->addFrc(-f3);
105 <    
106 < }
107 <
108 <
109 <      double K=0;       // energy
110 <      double K1=0;      // force
111 <
112 <  // get the dihedral information
113 <  int multiplicity = value->multiplicity;
114 <
115 <  //  Loop through the multiple parameter sets for this
116 <  //  bond.  We will only loop more than once if this
117 <  //  has multiple parameter sets from Charmm22
118 <  for (int mult_num=0; mult_num<multiplicity; mult_num++)
119 <  {
120 <    /* get angle information */
121 <    double k = value->values[mult_num].k * scale;
122 <    double delta = value->values[mult_num].delta;
123 <    int n = value->values[mult_num].n;
124 <
125 <    //  Calculate the energy
126 <    if (n)
127 <    {
128 <      //  Periodicity is greater than 0, so use cos form
129 <      K += k*(1+cos(n*phi + delta));
130 <      K1 += -n*k*sin(n*phi + delta);
131 <    }
132 <    else
133 <    {
134 <      //  Periodicity is 0, so just use the harmonic form
135 <      double diff = phi-delta;
136 <      if (diff < -PI)           diff += TWOPI;
137 <      else if (diff > PI)       diff -= TWOPI;
138 <
139 <      K += k*diff*diff;
140 <      K1 += 2.0*k*diff;
141 <    }
142 <  } /* for multiplicity */
143 <
144 <
145 < void Torsion::calc_forces(){
146 <  
147 <  /**********************************************************************
148 <   *
149 <   * initialize vectors
150 <   *
151 <   ***********************************************************************/
152 <  
153 <  vect r_ab; /* the vector whose origin is a and end is b */
154 <  vect r_cb; /* the vector whose origin is c and end is b */
155 <  vect r_cd; /* the vector whose origin is c and end is b */
156 <  vect r_cr1; /* the cross product of r_ab and r_cb */
157 <  vect r_cr2; /* the cross product of r_cb and r_cd */
158 <
159 <  double r_cr1_x2; /* the components of r_cr1 squared */
160 <  double r_cr1_y2;
161 <  double r_cr1_z2;
162 <  
163 <  double r_cr2_x2; /* the components of r_cr2 squared */
164 <  double r_cr2_y2;
165 <  double r_cr2_z2;
166 <
167 <  double r_cr1_sqr; /* the length of r_cr1 squared */
168 <  double r_cr2_sqr; /* the length of r_cr2 squared */
169 <  
170 <  double r_cr1_r_cr2; /* the length of r_cr1 * length of r_cr2 */
171 <  
172 <  Vector3d aR, bR, cR, dR;
173 <  Vector3d  aF, bF, cF, dF;
174 <
175 <  aR = c_p_a->getPos();
176 <  bR = c_p_b->getPos();
177 <  cR = c_p_c->getPos();
178 <  dR = c_p_d->getPos();
179 <
180 <  r_ab.x = bR[0] - aR[0];
181 <  r_ab.y = bR[1] - aR[1];
182 <  r_ab.z = bR[2] - aR[2];
183 <  r_ab.length  = sqrt((r_ab.x * r_ab.x + r_ab.y * r_ab.y + r_ab.z * r_ab.z));
184 <
185 <  r_cb.x = bR[0] - cR[0];
186 <  r_cb.y = bR[1] - cR[1];
187 <  r_cb.z = bR[2] - cR[2];
188 <  r_cb.length = sqrt((r_cb.x * r_cb.x + r_cb.y * r_cb.y + r_cb.z * r_cb.z));
189 <
190 <  r_cd.x = dR[0] - cR[0];
191 <  r_cd.y = dR[1] - cR[1];
192 <  r_cd.z = dR[2] - cR[2];
193 <  r_cd.length = sqrt((r_cd.x * r_cd.x + r_cd.y * r_cd.y + r_cd.z * r_cd.z));
194 <
195 <  r_cr1.x = r_ab.y * r_cb.z - r_cb.y * r_ab.z;
196 <  r_cr1.y = r_ab.z * r_cb.x - r_cb.z * r_ab.x;
197 <  r_cr1.z = r_ab.x * r_cb.y - r_cb.x * r_ab.y;
198 <  r_cr1_x2 = r_cr1.x * r_cr1.x;
199 <  r_cr1_y2 = r_cr1.y * r_cr1.y;
200 <  r_cr1_z2 = r_cr1.z * r_cr1.z;
201 <  r_cr1_sqr = r_cr1_x2 + r_cr1_y2 + r_cr1_z2;
202 <  r_cr1.length = sqrt(r_cr1_sqr);
203 <
204 <  r_cr2.x = r_cb.y * r_cd.z - r_cd.y * r_cb.z;
205 <  r_cr2.y = r_cb.z * r_cd.x - r_cd.z * r_cb.x;
206 <  r_cr2.z = r_cb.x * r_cd.y - r_cd.x * r_cb.y;
207 <  r_cr2_x2 = r_cr2.x * r_cr2.x;
208 <  r_cr2_y2 = r_cr2.y * r_cr2.y;
209 <  r_cr2_z2 = r_cr2.z * r_cr2.z;
210 <  r_cr2_sqr = r_cr2_x2 + r_cr2_y2 + r_cr2_z2;
211 <  r_cr2.length = sqrt(r_cr2_sqr);
212 <
213 <  r_cr1_r_cr2 = r_cr1.length * r_cr2.length;
214 <
215 <    //Vector3d pos1 = atom1_->getPos();
216 <    //Vector3d pos2 = atom2_->getPos();
217 <    //Vector3d pos3 = atom3_->getPos();
218 <    //Vector3d pos4 = atom4_->getPos();
219 <  
220 <    //Vector3d r12 = pos2 - pos1;
221 <    //Vector3d r32 = pos2 - pos3;
222 <    //Vector3d r34 = pos4 - pos3;
223 <
224 <    //A = cross(r12, r32);
225 <    //B = cross(r32, r34);
226 <    
227 <    //rA = A.length();  
228 <    //rB = B.length();
229 <  
230 <  /**********************************************************************
231 <   *
232 <   * dot product and angle calculations
233 <   *
234 <   ***********************************************************************/
235 <  
236 <  double cr1_dot_cr2; /* the dot product of the cr1 and cr2 vectors */
237 <  double cos_phi; /* the cosine of the torsion angle */
238 <
239 <  cr1_dot_cr2 = r_cr1.x * r_cr2.x + r_cr1.y * r_cr2.y + r_cr1.z * r_cr2.z;
240 <  
241 <  cos_phi = cr1_dot_cr2 / r_cr1_r_cr2;
242 <  
243 <   /* adjust for the granularity of the numbers for angles near 0 or pi */
244 <
245 <  if(cos_phi > 1.0) cos_phi = 1.0;
246 <  if(cos_phi < -1.0) cos_phi = -1.0;
247 <
248 <    //cos_phi = dot (A, B) / (rA * rB);
249 <    //if (cos_phi > 1.0) {
250 <    //  cos_phi = 1.0;
251 <    //}
252 <    //if (cos_phi < -1.0) {
253 <    //  cos_phi = -1.0;
254 <    //}
255 <
256 <
257 <
258 <  /********************************************************************
259 <   *
260 <   * This next section calculates derivatives needed for the force
261 <   * calculation
262 <   *
263 <   ********************************************************************/
264 <
265 <
266 <  /* the derivatives of cos phi with respect to the x, y,
267 <     and z components of vectors cr1 and cr2. */
268 <  double d_cos_dx_cr1;
269 <  double d_cos_dy_cr1;
270 <  double d_cos_dz_cr1;
271 <  double d_cos_dx_cr2;
272 <  double d_cos_dy_cr2;
273 <  double d_cos_dz_cr2;
274 <
275 <  d_cos_dx_cr1 = r_cr2.x / r_cr1_r_cr2 - (cos_phi * r_cr1.x) / r_cr1_sqr;
276 <  d_cos_dy_cr1 = r_cr2.y / r_cr1_r_cr2 - (cos_phi * r_cr1.y) / r_cr1_sqr;
277 <  d_cos_dz_cr1 = r_cr2.z / r_cr1_r_cr2 - (cos_phi * r_cr1.z) / r_cr1_sqr;
278 <
279 <  d_cos_dx_cr2 = r_cr1.x / r_cr1_r_cr2 - (cos_phi * r_cr2.x) / r_cr2_sqr;
280 <  d_cos_dy_cr2 = r_cr1.y / r_cr1_r_cr2 - (cos_phi * r_cr2.y) / r_cr2_sqr;
281 <  d_cos_dz_cr2 = r_cr1.z / r_cr1_r_cr2 - (cos_phi * r_cr2.z) / r_cr2_sqr;
282 <
283 <  //Vector3d dcosdA = B /(rA * rB) - cos_phi  /(rA * rA) * A;
284 <  //Vector3d dcosdA = 1.0 /rA * (B.normalize() - cos_phi * A.normalize());
285 <  //Vector3d dcosdB = 1.0 /rB * (A.normalize() - cos_phi * B.normalize());
286 <
287 <  /***********************************************************************
288 <   *
289 <   * Calculate the actual forces and place them in the atoms.
290 <   *
291 <   ***********************************************************************/
292 <
293 <  double force; /*the force scaling factor */
294 <
295 <  force = torsion_force(cos_phi);
296 <
297 <  aF[0] = force * (d_cos_dy_cr1 * r_cb.z - d_cos_dz_cr1 * r_cb.y);
298 <  aF[1] = force * (d_cos_dz_cr1 * r_cb.x - d_cos_dx_cr1 * r_cb.z);
299 <  aF[2] = force * (d_cos_dx_cr1 * r_cb.y - d_cos_dy_cr1 * r_cb.x);
300 <
301 <  bF[0] = force * (  d_cos_dy_cr1 * (r_ab.z - r_cb.z)
302 <           - d_cos_dy_cr2 *  r_cd.z  
303 <           + d_cos_dz_cr1 * (r_cb.y - r_ab.y)
304 <           + d_cos_dz_cr2 *  r_cd.y);
305 <  bF[1] = force * (  d_cos_dx_cr1 * (r_cb.z - r_ab.z)
306 <           + d_cos_dx_cr2 *  r_cd.z  
307 <           + d_cos_dz_cr1 * (r_ab.x - r_cb.x)
308 <           - d_cos_dz_cr2 *  r_cd.x);
309 <  bF[2] = force * (  d_cos_dx_cr1 * (r_ab.y - r_cb.y)
310 <           - d_cos_dx_cr2 *  r_cd.y  
311 <           + d_cos_dy_cr1 * (r_cb.x - r_ab.x)
312 <           + d_cos_dy_cr2 *  r_cd.x);
313 <
314 <  cF[0] = force * (- d_cos_dy_cr1 *  r_ab.z
315 <           - d_cos_dy_cr2 * (r_cb.z - r_cd.z)
316 <           + d_cos_dz_cr1 *  r_ab.y
317 <           - d_cos_dz_cr2 * (r_cd.y - r_cb.y));
318 <  cF[1] = force * (  d_cos_dx_cr1 *  r_ab.z
319 <           - d_cos_dx_cr2 * (r_cd.z - r_cb.z)
320 <           - d_cos_dz_cr1 *  r_ab.x
321 <           - d_cos_dz_cr2 * (r_cb.x - r_cd.x));
322 <  cF[2] = force * (- d_cos_dx_cr1 *  r_ab.y
323 <           - d_cos_dx_cr2 * (r_cb.y - r_cd.y)
324 <           + d_cos_dy_cr1 *  r_ab.x
325 <           - d_cos_dy_cr2 * (r_cd.x - r_cb.x));
326 <
327 <  dF[0] = force * (d_cos_dy_cr2 * r_cb.z - d_cos_dz_cr2 * r_cb.y);
328 <  dF[1] = force * (d_cos_dz_cr2 * r_cb.x - d_cos_dx_cr2 * r_cb.z);
329 <  dF[2] = force * (d_cos_dx_cr2 * r_cb.y - d_cos_dy_cr2 * r_cb.x);
330 <
331 <
332 <  c_p_a->addFrc(aF);
333 <  c_p_b->addFrc(bF);
334 <  c_p_c->addFrc(cF);
335 <  c_p_d->addFrc(dF);
336 <
337 <    //double firstDerivative;
338 <    //bondType_->calcForce(cos_phi, firstDerivative, potential_);
339 <    //f1 = force * cross (dcosdA, r32);
340 <    //f2 =
341 <    //f3 =
342 <    //f4 = force * cross(dcosdB, r32);
343 <    //atom1_->addFrc(f1);
344 <    //atom2_->addFrc(f2);
345 <    //atom3_->addFrc(f3);
346 <    //atom4_->addFrc(f4);
347 <
348 <  
349 < }
350 <
351 < }
1 > #include "primitives/Torsion.hpp"
2 >
3 > namespace oopse {
4 >
5 > Torsion::Torsion(Atom *atom1, Atom *atom2, Atom *atom3, Atom *atom4,
6 >                 TorsionType *tt) :
7 >    atom1_(atom1),
8 >    atom2_(atom2),
9 >    atom3_(atom3),
10 >    atom4_(atom4) { }
11 >
12 > void Torsion::calcForce() {
13 >    Vector3d pos1 = atom1_->getPos();
14 >    Vector3d pos2 = atom2_->getPos();
15 >    Vector3d pos3 = atom3_->getPos();
16 >    Vector3d pos4 = atom4_->getPos();
17 >
18 >    Vector3d r12 = pos1 - pos2;
19 >    Vector3d r23 = pos2 - pos3;
20 >    Vector3d r34 = pos3 - pos4;
21 >
22 >    //  Calculate the cross products and distances
23 >    Vector3d A = cross(r12, r23);
24 >    double rA = A.length();
25 >    Vector3d B = cross(r23, r34);
26 >    double rB = B.length();
27 >    Vector3d C = cross(r23, A);
28 >    double rC = C.length();
29 >
30 >    A.normalize();
31 >    B.normalize();
32 >    C.normalize();
33 >    
34 >    //  Calculate the sin and cos
35 >    double cos_phi = dot(A, B) ;
36 >    double sin_phi = dot(C, B);
37 >
38 >    double phi = -atan2(sin_phi, cos_phi);
39 >
40 >    double dVdPhi;
41 >    torsionType_->calcForce(phi, potential_, dVdPhi);
42 >
43 >    Vector3d f1;
44 >    Vector3d f2;
45 >    Vector3d f3;
46 >
47 >    //  Next, we want to calculate the forces.  In order
48 >    //  to do that, we first need to figure out whether the
49 >    //  sin or cos form will be more stable.  For this,
50 >    //  just look at the value of phi
51 >    if (fabs(sin_phi) > 0.1) {
52 >        //  use the sin version to avoid 1/cos terms
53 >
54 >        Vector3d dcosdA = (cos_phi * A - B) /rA;
55 >        Vector3d dcosdB = (cos_phi * B - A) /rB;
56 >
57 >        double dVdcosPhi = dVdPhi / sin_phi;
58 >
59 >        f1 = dVdcosPhi * cross(r23, dcosdA);
60 >        f2 = dVdcosPhi * ( cross(r34, dcosdB) - cross(r12, dcosdA));
61 >        f3 = dVdcosPhi * cross(r23, dcosdB);
62 >
63 >    } else {
64 >        //  This angle is closer to 0 or 180 than it is to
65 >        //  90, so use the cos version to avoid 1/sin terms
66 >
67 >        double dVdsinPhi = -dVdPhi /cos_phi;
68 >        Vector3d dsindB = (sin_phi * B - C) /rB;
69 >        Vector3d dsindC = (sin_phi * C - B) /rC;
70 >
71 >        f1.x = dVdsinPhi*((r23.y*r23.y + r23.z*r23.z)*dsindC.x - r23.x*r23.y*dsindC.y - r23.x*r23.z*dsindC.z);
72 >
73 >        f1.y = dVdsinPhi*((r23.z*r23.z + r23.x*r23.x)*dsindC.y - r23.y*r23.z*dsindC.z - r23.y*r23.x*dsindC.x);
74 >
75 >        f1.z = dVdsinPhi*((r23.x*r23.x + r23.y*r23.y)*dsindC.z - r23.z*r23.x*dsindC.x - r23.z*r23.y*dsindC.y);
76 >
77 >        f2.x = dVdsinPhi*(-(r23.y*r12.y + r23.z*r12.z)*dsindC.x + (2.0*r23.x*r12.y - r12.x*r23.y)*dsindC.y
78 >        + (2.0*r23.x*r12.z - r12.x*r23.z)*dsindC.z + dsindB.z*r34.y - dsindB.y*r34.z);
79 >
80 >        f2.y = dVdsinPhi*(-(r23.z*r12.z + r23.x*r12.x)*dsindC.y + (2.0*r23.y*r12.z - r12.y*r23.z)*dsindC.z
81 >        + (2.0*r23.y*r12.x - r12.y*r23.x)*dsindC.x + dsindB.x*r34.z - dsindB.z*r34.x);
82 >
83 >        f2.z = dVdsinPhi*(-(r23.x*r12.x + r23.y*r12.y)*dsindC.z + (2.0*r23.z*r12.x - r12.z*r23.x)*dsindC.x
84 >        +(2.0*r23.z*r12.y - r12.z*r23.y)*dsindC.y + dsindB.y*r34.x - dsindB.x*r34.y);
85 >
86 >        f3 = dVdsinPhi * cross(dsindB, r23);
87 >
88 >    }
89 >
90 >    atom1_->addFrc(f1);
91 >    atom2_->addFrc(f2 - f1);
92 >    atom3_->addFrc(f3 - f2);
93 >    atom4_->addFrc(-f3);
94 > }
95 >
96 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines