# | Line 1 | Line 1 | |
---|---|---|
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 "primitives/GhostBend.hpp" |
43 | + | #include "primitives/DirectionalAtom.hpp" |
44 | + | namespace oopse { |
45 | ||
46 | < | #include <math.h> |
47 | < | #include <iostream> |
48 | < | #include <stdlib.h> |
5 | < | |
6 | < | #include "utils/simError.h" |
7 | < | #include "primitives/SRI.hpp" |
8 | < | #include "primitives/Atom.hpp" |
9 | < | |
10 | < | |
11 | < | |
12 | < | GhostBend::GhostBend( Atom &a, Atom &b ){ |
13 | < | |
14 | < | c_p_a = &a; |
15 | < | |
16 | < | if( !b.isDirectional() ){ |
46 | > | /**@todo still a lot left to improve*/ |
47 | > | void GhostBend::calcForce(RealType& angle) { |
48 | > | DirectionalAtom* ghostAtom = static_cast<DirectionalAtom*>(atom2_); |
49 | ||
50 | < | // if atom b is not directional, then bad things will happen |
51 | < | |
20 | < | sprintf( painCave.errMsg, |
21 | < | " Ghost Bend error: Atom # %d of type \"%s\" is not " |
22 | < | "directional.\n", |
23 | < | b.getIndex(), |
24 | < | b.getType() ); |
25 | < | painCave.isFatal = 1; |
26 | < | simError(); |
27 | < | } |
50 | > | Vector3d pos1 = atom1_->getPos(); |
51 | > | Vector3d pos2 = ghostAtom->getPos(); |
52 | ||
53 | < | atomB = ( DirectionalAtom* ) &b; |
54 | < | |
31 | < | c_potential_E = 0.0; |
53 | > | Vector3d r12 = pos1 - pos2; |
54 | > | RealType d12 = r12.length(); |
55 | ||
56 | < | } |
56 | > | RealType d12inv = 1.0 / d12; |
57 | ||
58 | + | Vector3d r32 = ghostAtom->getElectroFrame().getColumn(2); |
59 | + | RealType d32 = r32.length(); |
60 | ||
61 | < | void GhostBend::calc_forces(){ |
37 | < | |
38 | < | double dx,dy,dz,gx,gy,gz,dx2,dy2,dz2,gx2,gy2,gz2; |
39 | < | double rij2, rkj2, riji2, rkji2, dot, denom, cosang, angl; |
40 | < | |
41 | < | double sina2, sinai; |
61 | > | RealType d32inv = 1.0 / d32; |
62 | ||
63 | < | double comf2, comf3, comf4; |
44 | < | double dcsidx, dcsidy, dcsidz, dcskdx, dcskdy, dcskdz; |
45 | < | // double dcsjdx, dcsjdy, dcsjdz; |
46 | < | double dadxi, dadyi, dadzi; |
47 | < | double dadxk, dadyk, dadzk;//, dadxj, dadyj, dadzj; |
48 | < | double daxi, dayi, dazi, daxk, dayk, dazk, daxj, dayj, dazj; |
49 | < | double u[3]; |
50 | < | |
51 | < | double aR[3], bR[3]; |
52 | < | double aF[3], bF[3], bTrq[3]; |
63 | > | RealType cosTheta = dot(r12, r32) / (d12 * d32); |
64 | ||
65 | < | c_p_a->getPos( aR ); |
66 | < | atomB->getPos( bR ); |
67 | < | |
65 | > | //check roundoff |
66 | > | if (cosTheta > 1.0) { |
67 | > | cosTheta = 1.0; |
68 | > | } else if (cosTheta < -1.0) { |
69 | > | cosTheta = -1.0; |
70 | > | } |
71 | ||
72 | < | dx = aR[0] - bR[0]; |
59 | < | dy = aR[1] - bR[1]; |
60 | < | dz = aR[2] - bR[2]; |
72 | > | RealType theta = acos(cosTheta); |
73 | ||
74 | < | atomB->getU(u); |
74 | > | RealType firstDerivative; |
75 | ||
76 | < | gx = u[0]; |
65 | < | gy = u[1]; |
66 | < | gz = u[2]; |
67 | < | |
68 | < | dx2 = dx * dx; |
69 | < | dy2 = dy * dy; |
70 | < | dz2 = dz * dz; |
76 | > | bendType_->calcForce(theta, firstDerivative, potential_); |
77 | ||
78 | < | gx2 = gx * gx; |
73 | < | gy2 = gy * gy; |
74 | < | gz2 = gz * gz; |
75 | < | |
76 | < | rij2 = dx2 + dy2 + dz2; |
77 | < | rkj2 = gx2 + gy2 + gz2; |
78 | < | |
79 | < | riji2 = 1.0 / rij2; |
80 | < | rkji2 = 1.0 / rkj2; |
78 | > | RealType sinTheta = sqrt(1.0 - cosTheta * cosTheta); |
79 | ||
80 | < | dot = dx * gx + dy * gy + dz * gz; |
81 | < | denom = sqrt((riji2 * rkji2)); |
82 | < | cosang = dot * denom; |
80 | > | if (fabs(sinTheta) < 1.0E-12) { |
81 | > | sinTheta = 1.0E-12; |
82 | > | } |
83 | ||
84 | < | if(cosang > 1.0)cosang = 1.0; |
85 | < | if(cosang < -1.0) cosang = -1.0; |
84 | > | RealType commonFactor1 = -firstDerivative / sinTheta * d12inv; |
85 | > | RealType commonFactor2 = -firstDerivative / sinTheta * d32inv; |
86 | ||
87 | < | angl = acos(cosang); |
88 | < | angl = angl * 180.0 / M_PI; |
87 | > | Vector3d force1 = commonFactor1*(r12*(d12inv*cosTheta) - r32*d32inv); |
88 | > | Vector3d force3 = commonFactor2*(r32*(d32inv*cosTheta) - r12*d12inv); |
89 | > | atom1_->addFrc(force1); |
90 | > | ghostAtom->addFrc(-force1); |
91 | > | /**@todo test correctness */ |
92 | > | ghostAtom->addTrq(cross(r32, force3) ); |
93 | ||
94 | < | sina2 = 1.0 - cosang*cosang; |
93 | < | if(fabs(sina2) < 1.0E-12 ) sina2 = 1.0E-12; |
94 | < | sinai = 1.0 / sqrt(sina2); |
94 | > | angle = theta /M_PI * 180.0; |
95 | ||
96 | < | comf2 = cosang * riji2; |
97 | < | comf3 = cosang * rkji2; |
98 | < | comf4 = bend_force(angl); |
96 | > | } |
97 | ||
98 | < | dcsidx = gx*denom - comf2*dx; |
101 | < | dcsidy = gy*denom - comf2*dy; |
102 | < | dcsidz = gz*denom - comf2*dz; |
103 | < | |
104 | < | dcskdx = dx*denom - comf3*gx; |
105 | < | dcskdy = dy*denom - comf3*gy; |
106 | < | dcskdz = dz*denom - comf3*gz; |
107 | < | |
108 | < | // dcsjdx = -dcsidx - dcskdx; |
109 | < | // dcsjdy = -dcsidy - dcskdy; |
110 | < | // dcsjdz = -dcsidz - dcskdz; |
98 | > | } //end namespace oopse |
99 | ||
112 | – | dadxi = -sinai*dcsidx; |
113 | – | dadyi = -sinai*dcsidy; |
114 | – | dadzi = -sinai*dcsidz; |
115 | – | |
116 | – | dadxk = -sinai*dcskdx; |
117 | – | dadyk = -sinai*dcskdy; |
118 | – | dadzk = -sinai*dcskdz; |
119 | – | |
120 | – | // dadxj = -dadxi - dadxk; |
121 | – | // dadyj = -dadyi - dadyk; |
122 | – | // dadzj = -dadzi - dadzk; |
123 | – | |
124 | – | daxi = comf4*dadxi; |
125 | – | dayi = comf4*dadyi; |
126 | – | dazi = comf4*dadzi; |
127 | – | |
128 | – | daxk = comf4*dadxk; |
129 | – | dayk = comf4*dadyk; |
130 | – | dazk = comf4*dadzk; |
131 | – | |
132 | – | daxj = -daxi - daxk; |
133 | – | dayj = -dayi - dayk; |
134 | – | dazj = -dazi - dazk; |
135 | – | |
136 | – | aF[0] = daxi; |
137 | – | aF[1] = dayi; |
138 | – | aF[2] = dazi; |
139 | – | |
140 | – | bF[0] = daxj + daxk; |
141 | – | bF[1] = dayj + dayk; |
142 | – | bF[2] = dazj + dazk; |
143 | – | |
144 | – | bTrq[0] = gy*dazk - gz*dayk; |
145 | – | bTrq[1] = gz*daxk - gx*dazk; |
146 | – | bTrq[2] = gx*dayk - gy*daxk; |
147 | – | |
148 | – | |
149 | – | c_p_a->addFrc( aF ); |
150 | – | atomB->addFrc( bF ); |
151 | – | atomB->addTrq( bTrq ); |
152 | – | |
153 | – | return; |
154 | – | } |
155 | – | |
156 | – | void GhostBend::setConstants( double the_c1, double the_c2, double the_c3, |
157 | – | double the_Th0 ){ |
158 | – | c1 = the_c1; |
159 | – | c2 = the_c2; |
160 | – | c3 = the_c3; |
161 | – | theta0 = the_Th0; |
162 | – | } |
163 | – | |
164 | – | |
165 | – | double GhostBend::bend_force( double theta ){ |
166 | – | |
167 | – | double dt, dt2; |
168 | – | double force; |
169 | – | |
170 | – | dt = ( theta - theta0 ) * M_PI / 180.0; |
171 | – | dt2 = dt * dt; |
172 | – | |
173 | – | c_potential_E = ( c1 * dt2 ) + ( c2 * dt ) + c3; |
174 | – | force = -( ( 2.0 * c1 * dt ) + c2 ); |
175 | – | return force; |
176 | – | } |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |