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 1683, Thu Oct 28 22:34:02 2004 UTC vs.
Revision 1782 by tim, Wed Nov 24 20:55:03 2004 UTC

# Line 1 | Line 1
1 < #include "primitives/SRI.hpp"
2 < #include "primitives/Atom.hpp"
3 < #include <math.h>
4 < #include <iostream>
5 < #include <stdlib.h>
1 > #include "primitives/Torsion.hpp"
2  
3 < void Torsion::set_atoms( Atom &a, Atom &b, Atom &c, Atom &d){
8 <  c_p_a = &a;
9 <  c_p_b = &b;
10 <  c_p_c = &c;
11 <  c_p_d = &d;
12 < }
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::calc_forces(){
13 <  
14 <  /**********************************************************************
15 <   *
16 <   * initialize vectors
20 <   *
21 <   ***********************************************************************/
22 <  
23 <  vect r_ab; /* the vector whose origin is a and end is b */
24 <  vect r_cb; /* the vector whose origin is c and end is b */
25 <  vect r_cd; /* the vector whose origin is c and end is b */
26 <  vect r_cr1; /* the cross product of r_ab and r_cb */
27 <  vect r_cr2; /* the cross product of r_cb and r_cd */
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 <  double r_cr1_x2; /* the components of r_cr1 squared */
19 <  double r_cr1_y2;
20 <  double r_cr1_z2;
32 <  
33 <  double r_cr2_x2; /* the components of r_cr2 squared */
34 <  double r_cr2_y2;
35 <  double r_cr2_z2;
18 >    Vector3d r12 = pos1 - pos2;
19 >    Vector3d r23 = pos2 - pos3;
20 >    Vector3d r34 = pos3 - pos4;
21  
22 <  double r_cr1_sqr; /* the length of r_cr1 squared */
23 <  double r_cr2_sqr; /* the length of r_cr2 squared */
24 <  
25 <  double r_cr1_r_cr2; /* the length of r_cr1 * length of r_cr2 */
26 <  
27 <  double aR[3], bR[3], cR[3], dR[3];
28 <  double aF[3], bF[3], cF[3], dF[3];
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 <  c_p_a->getPos( aR );
31 <  c_p_b->getPos( bR );
32 <  c_p_c->getPos( cR );
33 <  c_p_d->getPos( dR );
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 <  r_ab.x = bR[0] - aR[0];
39 <  r_ab.y = bR[1] - aR[1];
52 <  r_ab.z = bR[2] - aR[2];
53 <  r_ab.length  = sqrt((r_ab.x * r_ab.x + r_ab.y * r_ab.y + r_ab.z * r_ab.z));
38 >    double dVdPhi;
39 >    torsionType_->calcForce(cos_phi, sin_phi, potential_, dVdPhi);
40  
41 <  r_cb.x = bR[0] - cR[0];
42 <  r_cb.y = bR[1] - cR[1];
43 <  r_cb.z = bR[2] - cR[2];
58 <  r_cb.length = sqrt((r_cb.x * r_cb.x + r_cb.y * r_cb.y + r_cb.z * r_cb.z));
41 >    Vector3d f1;
42 >    Vector3d f2;
43 >    Vector3d f3;
44  
45 <  r_cd.x = dR[0] - cR[0];
46 <  r_cd.y = dR[1] - cR[1];
47 <  r_cd.z = dR[2] - cR[2];
48 <  r_cd.length = sqrt((r_cd.x * r_cd.x + r_cd.y * r_cd.y + r_cd.z * r_cd.z));
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 <  r_cr1.x = r_ab.y * r_cb.z - r_cb.y * r_ab.z;
53 <  r_cr1.y = r_ab.z * r_cb.x - r_cb.z * r_ab.x;
67 <  r_cr1.z = r_ab.x * r_cb.y - r_cb.x * r_ab.y;
68 <  r_cr1_x2 = r_cr1.x * r_cr1.x;
69 <  r_cr1_y2 = r_cr1.y * r_cr1.y;
70 <  r_cr1_z2 = r_cr1.z * r_cr1.z;
71 <  r_cr1_sqr = r_cr1_x2 + r_cr1_y2 + r_cr1_z2;
72 <  r_cr1.length = sqrt(r_cr1_sqr);
52 >        Vector3d dcosdA = (cos_phi * A - B) /rA;
53 >        Vector3d dcosdB = (cos_phi * B - A) /rB;
54  
55 <  r_cr2.x = r_cb.y * r_cd.z - r_cd.y * r_cb.z;
75 <  r_cr2.y = r_cb.z * r_cd.x - r_cd.z * r_cb.x;
76 <  r_cr2.z = r_cb.x * r_cd.y - r_cd.x * r_cb.y;
77 <  r_cr2_x2 = r_cr2.x * r_cr2.x;
78 <  r_cr2_y2 = r_cr2.y * r_cr2.y;
79 <  r_cr2_z2 = r_cr2.z * r_cr2.z;
80 <  r_cr2_sqr = r_cr2_x2 + r_cr2_y2 + r_cr2_z2;
81 <  r_cr2.length = sqrt(r_cr2_sqr);
55 >        double dVdcosPhi = dVdPhi / sin_phi;
56  
57 <  r_cr1_r_cr2 = r_cr1.length * r_cr2.length;
57 >        f1 = dVdcosPhi * cross(r23, dcosdA);
58 >        f2 = dVdcosPhi * ( cross(r34, dcosdB) - cross(r12, dcosdA));
59 >        f3 = dVdcosPhi * cross(r23, dcosdB);
60  
61 <  /**********************************************************************
62 <   *
63 <   * dot product and angle calculations
88 <   *
89 <   ***********************************************************************/
90 <  
91 <  double cr1_dot_cr2; /* the dot product of the cr1 and cr2 vectors */
92 <  double cos_phi; /* the cosine of the torsion angle */
61 >    } else {
62 >        //  This angle is closer to 0 or 180 than it is to
63 >        //  90, so use the cos version to avoid 1/sin terms
64  
65 <  cr1_dot_cr2 = r_cr1.x * r_cr2.x + r_cr1.y * r_cr2.y + r_cr1.z * r_cr2.z;
66 <  
67 <  cos_phi = cr1_dot_cr2 / r_cr1_r_cr2;
97 <  
98 <   /* adjust for the granularity of the numbers for angles near 0 or pi */
65 >        double dVdsinPhi = -dVdPhi /cos_phi;
66 >        Vector3d dsindB = (sin_phi * B - C) /rB;
67 >        Vector3d dsindC = (sin_phi * C - B) /rC;
68  
69 <  if(cos_phi > 1.0) cos_phi = 1.0;
101 <  if(cos_phi < -1.0) cos_phi = -1.0;
69 >        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());
70  
71 +        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());
72  
73 <  /********************************************************************
105 <   *
106 <   * This next section calculates derivatives needed for the force
107 <   * calculation
108 <   *
109 <   ********************************************************************/
73 >        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());
74  
75 +        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()
76 +        + (2.0*r23.x()*r12.z() - r12.x()*r23.z())*dsindC.z() + dsindB.z()*r34.y() - dsindB.y()*r34.z());
77  
78 <  /* the derivatives of cos phi with respect to the x, y,
79 <     and z components of vectors cr1 and cr2. */
114 <  double d_cos_dx_cr1;
115 <  double d_cos_dy_cr1;
116 <  double d_cos_dz_cr1;
117 <  double d_cos_dx_cr2;
118 <  double d_cos_dy_cr2;
119 <  double d_cos_dz_cr2;
78 >        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()
79 >        + (2.0*r23.y()*r12.x() - r12.y()*r23.x())*dsindC.x() + dsindB.x()*r34.z() - dsindB.z()*r34.x());
80  
81 <  d_cos_dx_cr1 = r_cr2.x / r_cr1_r_cr2 - (cos_phi * r_cr1.x) / r_cr1_sqr;
82 <  d_cos_dy_cr1 = r_cr2.y / r_cr1_r_cr2 - (cos_phi * r_cr1.y) / r_cr1_sqr;
123 <  d_cos_dz_cr1 = r_cr2.z / r_cr1_r_cr2 - (cos_phi * r_cr1.z) / r_cr1_sqr;
81 >        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()
82 >        +(2.0*r23.z()*r12.y() - r12.z()*r23.y())*dsindC.y() + dsindB.y()*r34.x() - dsindB.x()*r34.y());
83  
84 <  d_cos_dx_cr2 = r_cr1.x / r_cr1_r_cr2 - (cos_phi * r_cr2.x) / r_cr2_sqr;
126 <  d_cos_dy_cr2 = r_cr1.y / r_cr1_r_cr2 - (cos_phi * r_cr2.y) / r_cr2_sqr;
127 <  d_cos_dz_cr2 = r_cr1.z / r_cr1_r_cr2 - (cos_phi * r_cr2.z) / r_cr2_sqr;
84 >        f3 = dVdsinPhi * cross(dsindB, r23);
85  
86 <  /***********************************************************************
130 <   *
131 <   * Calculate the actual forces and place them in the atoms.
132 <   *
133 <   ***********************************************************************/
86 >    }
87  
88 <  double force; /*the force scaling factor */
88 >    atom1_->addFrc(f1);
89 >    atom2_->addFrc(f2 - f1);
90 >    atom3_->addFrc(f3 - f2);
91 >    atom4_->addFrc(-f3);
92 > }
93  
137  force = torsion_force(cos_phi);
138
139  aF[0] = force * (d_cos_dy_cr1 * r_cb.z - d_cos_dz_cr1 * r_cb.y);
140  aF[1] = force * (d_cos_dz_cr1 * r_cb.x - d_cos_dx_cr1 * r_cb.z);
141  aF[2] = force * (d_cos_dx_cr1 * r_cb.y - d_cos_dy_cr1 * r_cb.x);
142
143  bF[0] = force * (  d_cos_dy_cr1 * (r_ab.z - r_cb.z)
144                   - d_cos_dy_cr2 *  r_cd.z      
145                   + d_cos_dz_cr1 * (r_cb.y - r_ab.y)
146                   + d_cos_dz_cr2 *  r_cd.y);
147  bF[1] = force * (  d_cos_dx_cr1 * (r_cb.z - r_ab.z)
148                   + d_cos_dx_cr2 *  r_cd.z      
149                   + d_cos_dz_cr1 * (r_ab.x - r_cb.x)
150                   - d_cos_dz_cr2 *  r_cd.x);
151  bF[2] = force * (  d_cos_dx_cr1 * (r_ab.y - r_cb.y)
152                   - d_cos_dx_cr2 *  r_cd.y      
153                   + d_cos_dy_cr1 * (r_cb.x - r_ab.x)
154                   + d_cos_dy_cr2 *  r_cd.x);
155
156  cF[0] = force * (- d_cos_dy_cr1 *  r_ab.z
157                   - d_cos_dy_cr2 * (r_cb.z - r_cd.z)
158                   + d_cos_dz_cr1 *  r_ab.y
159                   - d_cos_dz_cr2 * (r_cd.y - r_cb.y));
160  cF[1] = force * (  d_cos_dx_cr1 *  r_ab.z
161                   - d_cos_dx_cr2 * (r_cd.z - r_cb.z)
162                   - d_cos_dz_cr1 *  r_ab.x
163                   - d_cos_dz_cr2 * (r_cb.x - r_cd.x));
164  cF[2] = force * (- d_cos_dx_cr1 *  r_ab.y
165                   - d_cos_dx_cr2 * (r_cb.y - r_cd.y)
166                   + d_cos_dy_cr1 *  r_ab.x
167                   - d_cos_dy_cr2 * (r_cd.x - r_cb.x));
168
169  dF[0] = force * (d_cos_dy_cr2 * r_cb.z - d_cos_dz_cr2 * r_cb.y);
170  dF[1] = force * (d_cos_dz_cr2 * r_cb.x - d_cos_dx_cr2 * r_cb.z);
171  dF[2] = force * (d_cos_dx_cr2 * r_cb.y - d_cos_dy_cr2 * r_cb.x);
172
173
174  c_p_a->addFrc(aF);
175  c_p_b->addFrc(bF);
176  c_p_c->addFrc(cF);
177  c_p_d->addFrc(dF);
94   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines