ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/primitives/Torsion.cpp
Revision: 1742
Committed: Tue Nov 16 20:36:18 2004 UTC (19 years, 9 months ago) by tim
File size: 11614 byte(s)
Log Message:
BondType, BendType and TorsionType

File Contents

# User Rev Content
1 tim 1742 #include "primitives/Torsion.hpp"
2 tim 1692
3 tim 1742 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 tim 1692 }
9    
10 tim 1742 void Torsion::calcForce() {
11 tim 1692
12 tim 1742 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 tim 1692 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 tim 1701 Vector3d aR, bR, cR, dR;
173 tim 1742 Vector3d aF, bF, cF, dF;
174 tim 1692
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 tim 1742 //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 tim 1692 /**********************************************************************
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 tim 1742 //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 tim 1692
256 tim 1742
257    
258 tim 1692 /********************************************************************
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 tim 1742 //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 tim 1692 /***********************************************************************
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 tim 1742 - 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 tim 1692 bF[1] = force * ( d_cos_dx_cr1 * (r_cb.z - r_ab.z)
306 tim 1742 + 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 tim 1692 bF[2] = force * ( d_cos_dx_cr1 * (r_ab.y - r_cb.y)
310 tim 1742 - 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 tim 1692
314     cF[0] = force * (- d_cos_dy_cr1 * r_ab.z
315 tim 1742 - 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 tim 1692 cF[1] = force * ( d_cos_dx_cr1 * r_ab.z
319 tim 1742 - 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 tim 1692 cF[2] = force * (- d_cos_dx_cr1 * r_ab.y
323 tim 1742 - 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 tim 1692
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 tim 1742
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 tim 1692 }
350 tim 1742
351     }