1 | //
|
---|
2 | // stors.cc
|
---|
3 | //
|
---|
4 | // Copyright (C) 1996 Limit Point Systems, Inc.
|
---|
5 | //
|
---|
6 | // Author: Curtis Janssen <cljanss@limitpt.com>
|
---|
7 | // Maintainer: LPS
|
---|
8 | //
|
---|
9 | // This file is part of the SC Toolkit.
|
---|
10 | //
|
---|
11 | // The SC Toolkit is free software; you can redistribute it and/or modify
|
---|
12 | // it under the terms of the GNU Library General Public License as published by
|
---|
13 | // the Free Software Foundation; either version 2, or (at your option)
|
---|
14 | // any later version.
|
---|
15 | //
|
---|
16 | // The SC Toolkit is distributed in the hope that it will be useful,
|
---|
17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
19 | // GNU Library General Public License for more details.
|
---|
20 | //
|
---|
21 | // You should have received a copy of the GNU Library General Public License
|
---|
22 | // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
|
---|
23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
24 | //
|
---|
25 | // The U.S. Government is granted a limited license as per AL 91-7.
|
---|
26 | //
|
---|
27 |
|
---|
28 | #include <string.h>
|
---|
29 | #include <util/misc/math.h>
|
---|
30 |
|
---|
31 | #include <util/misc/formio.h>
|
---|
32 | #include <util/state/stateio.h>
|
---|
33 | #include <chemistry/molecule/simple.h>
|
---|
34 | #include <chemistry/molecule/localdef.h>
|
---|
35 |
|
---|
36 | using namespace sc;
|
---|
37 |
|
---|
38 | static ClassDesc ScaledTorsSimpleCo_cd(
|
---|
39 | typeid(ScaledTorsSimpleCo),"ScaledTorsSimpleCo",1,"public SimpleCo",
|
---|
40 | create<ScaledTorsSimpleCo>, create<ScaledTorsSimpleCo>, create<ScaledTorsSimpleCo>);
|
---|
41 | SimpleCo_IMPL_eq(ScaledTorsSimpleCo)
|
---|
42 |
|
---|
43 | ScaledTorsSimpleCo::ScaledTorsSimpleCo(StateIn&s):
|
---|
44 | SimpleCo(s)
|
---|
45 | {
|
---|
46 | s.get(old_torsion_);
|
---|
47 | }
|
---|
48 |
|
---|
49 | void
|
---|
50 | ScaledTorsSimpleCo::save_data_state(StateOut&s)
|
---|
51 | {
|
---|
52 | SimpleCo::save_data_state(s);
|
---|
53 | s.put(old_torsion_);
|
---|
54 | }
|
---|
55 |
|
---|
56 | ScaledTorsSimpleCo::ScaledTorsSimpleCo() : SimpleCo(4)
|
---|
57 | {
|
---|
58 | old_torsion_ = 0.0;
|
---|
59 | }
|
---|
60 |
|
---|
61 | ScaledTorsSimpleCo::ScaledTorsSimpleCo(const ScaledTorsSimpleCo& s)
|
---|
62 | : SimpleCo(4)
|
---|
63 | {
|
---|
64 | *this=s;
|
---|
65 | old_torsion_ = 0.0;
|
---|
66 | }
|
---|
67 |
|
---|
68 | ScaledTorsSimpleCo::ScaledTorsSimpleCo(const char *refr,
|
---|
69 | int a1, int a2, int a3, int a4)
|
---|
70 | : SimpleCo(4,refr)
|
---|
71 | {
|
---|
72 | atoms[0]=a1; atoms[1]=a2; atoms[2]=a3; atoms[3]=a4;
|
---|
73 | old_torsion_ = 0.0;
|
---|
74 | }
|
---|
75 |
|
---|
76 | ScaledTorsSimpleCo::~ScaledTorsSimpleCo()
|
---|
77 | {
|
---|
78 | }
|
---|
79 |
|
---|
80 | ScaledTorsSimpleCo::ScaledTorsSimpleCo(const Ref<KeyVal> &kv):
|
---|
81 | SimpleCo(kv,4)
|
---|
82 | {
|
---|
83 | old_torsion_ = 0.0;
|
---|
84 | }
|
---|
85 |
|
---|
86 | ScaledTorsSimpleCo&
|
---|
87 | ScaledTorsSimpleCo::operator=(const ScaledTorsSimpleCo& s)
|
---|
88 | {
|
---|
89 | if(label_) delete[] label_;
|
---|
90 | label_=new char[strlen(s.label_)+1];
|
---|
91 | strcpy(label_,s.label_);
|
---|
92 | atoms[0]=s.atoms[0]; atoms[1]=s.atoms[1]; atoms[2]=s.atoms[2];
|
---|
93 | atoms[3]=s.atoms[3];
|
---|
94 | return *this;
|
---|
95 | }
|
---|
96 |
|
---|
97 | double
|
---|
98 | ScaledTorsSimpleCo::calc_intco(Molecule& m, double *bmat, double coeff)
|
---|
99 | {
|
---|
100 | int a=atoms[0]-1; int b=atoms[1]-1; int c=atoms[2]-1; int d=atoms[3]-1;
|
---|
101 | SCVector3 u1,u2,u3,z1,z2;
|
---|
102 |
|
---|
103 | SCVector3 ra(m.r(a)), rb(m.r(b)), rc(m.r(c)), rd(m.r(d));
|
---|
104 |
|
---|
105 | double rab, rbc, rcd;
|
---|
106 | u1 = ra - rb; rab = u1.norm(); u1 *= 1.0/rab;
|
---|
107 | u2 = rc - rb; rbc = u2.norm(); u2 *= 1.0/rbc;
|
---|
108 | u3 = rc - rd; rcd = u3.norm(); u3 *= 1.0/rcd;
|
---|
109 |
|
---|
110 | z1 = u1.perp_unit(u2);
|
---|
111 | z2 = u3.perp_unit(u2);
|
---|
112 |
|
---|
113 | double co=z1.dot(z2);
|
---|
114 | SCVector3 z1xz2 = z1.cross(z2);
|
---|
115 | double co2=z1xz2.dot(u2);
|
---|
116 |
|
---|
117 | if (co < -1.0) co= -1.0;
|
---|
118 | if (co > 1.0) co = 1.0;
|
---|
119 |
|
---|
120 | double tors_value = (co2<0) ? acos(-co) : -acos(-co);
|
---|
121 |
|
---|
122 | // ok, we want omega between 3*pi/2 and -pi/2, so if omega is > pi/2
|
---|
123 | // (omega is eventually -omega), then knock 2pi off of it
|
---|
124 | if(tors_value > pih) tors_value -= tpi;
|
---|
125 |
|
---|
126 | // the following tests to see if the new coordinate has crossed the
|
---|
127 | // 3pi/2 <--> -pi/2 boundary...if so, then we add or subtract 2pi as
|
---|
128 | // needed to prevent the transformation from internals to cartesians
|
---|
129 | // from blowing up
|
---|
130 | while(old_torsion_ - tors_value > pi + 1.0e-6) tors_value += tpi;
|
---|
131 | while(old_torsion_ - tors_value < -(pi + 1.0e-6)) tors_value -= tpi;
|
---|
132 |
|
---|
133 | // This differs from a normal torsion by the factor
|
---|
134 | // scalar(u1,u2)*scalar(u2,u3). This prevents the
|
---|
135 | // value from being ill defined at nearly linear geometries.
|
---|
136 | double cos_abc = u1.dot(u2);
|
---|
137 | double cos_bcd = u2.dot(u3);
|
---|
138 | double sin_abc=s2(cos_abc);
|
---|
139 | double sin_bcd=s2(cos_bcd);
|
---|
140 | double colin = sin_abc * sin_bcd;
|
---|
141 | value_ = tors_value * colin;
|
---|
142 |
|
---|
143 | if (bmat) {
|
---|
144 | double uu,vv,ww,zz;
|
---|
145 | double r1 = rab;
|
---|
146 | double r2 = rbc;
|
---|
147 | double r3 = rcd;
|
---|
148 | #if OLD_BMAT
|
---|
149 | r1 *= bohr;
|
---|
150 | r2 *= bohr;
|
---|
151 | r3 *= bohr;
|
---|
152 | #endif
|
---|
153 | for (int j=0; j < 3; j++) {
|
---|
154 | // compute the derivatives for a normal torsion
|
---|
155 | if (sin_abc > 1.0e-5) uu = z1[j]/(r1*sin_abc);
|
---|
156 | else uu = 0.0;
|
---|
157 | if (sin_bcd > 1.0e-5) zz = z2[j]/(r3*sin_bcd);
|
---|
158 | else zz = 0.0;
|
---|
159 | vv = (r1*cos_abc/r2-1.0)*uu-zz*r3*cos_bcd/r2;
|
---|
160 | // use the chain rule to get the values for the scaled torsion
|
---|
161 | static int first = 0;
|
---|
162 | if (first) {
|
---|
163 | ExEnv::out0() << indent
|
---|
164 | << scprintf("uu = %12.8f colin = %12.8f sin_abc = %12.8f\n",
|
---|
165 | uu, colin, sin_abc)
|
---|
166 | << indent
|
---|
167 | << scprintf("tors_value = %12.8f (%12.8f deg)\n", tors_value,
|
---|
168 | tors_value * 180.0/M_PI)
|
---|
169 | << indent
|
---|
170 | << scprintf("cos_abc = %12.8f cos_bcd = %12.8f\n",
|
---|
171 | cos_abc, cos_bcd);
|
---|
172 | }
|
---|
173 | uu = uu*colin;
|
---|
174 | if (sin_abc > 1.0e-5) uu += tors_value
|
---|
175 | * (-cos_abc/sin_abc)
|
---|
176 | * sin_bcd
|
---|
177 | * (u2[j] - cos_abc * u1[j])/rab;
|
---|
178 | vv = vv*colin;
|
---|
179 | if (sin_abc > 1.0e-5) vv += tors_value
|
---|
180 | * (-cos_abc/sin_abc)
|
---|
181 | * sin_bcd
|
---|
182 | * ((-u2[j] + cos_abc*u1[j])/rab
|
---|
183 | +(-u1[j] + cos_abc*u2[j])/rbc);
|
---|
184 | if (sin_bcd > 1.0e-5) vv += tors_value
|
---|
185 | * (-cos_bcd/sin_bcd)
|
---|
186 | * sin_abc
|
---|
187 | * (-u3[j] + cos_bcd * u2[j])/rbc;
|
---|
188 | zz = zz*colin;
|
---|
189 | if (sin_bcd > 1.0e-5) zz += tors_value
|
---|
190 | * (-cos_bcd/sin_bcd)
|
---|
191 | * sin_abc
|
---|
192 | * (-u2[j] + cos_bcd * u3[j])/rcd;
|
---|
193 | ww = -uu-vv-zz;
|
---|
194 | bmat[a*3+j] += coeff*uu;
|
---|
195 | bmat[b*3+j] += coeff*vv;
|
---|
196 | bmat[c*3+j] += coeff*ww;
|
---|
197 | bmat[d*3+j] += coeff*zz;
|
---|
198 | if (first) first = 0;
|
---|
199 | }
|
---|
200 | }
|
---|
201 |
|
---|
202 | // save the old value of the torsion so we can make sure the discontinuity
|
---|
203 | // at -pi/2 doesn't bite us
|
---|
204 | old_torsion_ = tors_value;
|
---|
205 | return value_;
|
---|
206 | }
|
---|
207 |
|
---|
208 | double
|
---|
209 | ScaledTorsSimpleCo::calc_force_con(Molecule& m)
|
---|
210 | {
|
---|
211 | int a=atoms[1]-1; int b=atoms[2]-1;
|
---|
212 |
|
---|
213 | SCVector3 ra(m.r(a));
|
---|
214 | SCVector3 rb(m.r(b));
|
---|
215 |
|
---|
216 | double rad_ab = m.atominfo()->atomic_radius(m.Z(a))
|
---|
217 | + m.atominfo()->atomic_radius(m.Z(b));
|
---|
218 |
|
---|
219 | double r_ab = ra.dist(rb);
|
---|
220 |
|
---|
221 | double k = 0.0015 + 14.0*pow(1.0,0.57)/pow((rad_ab*r_ab),4.0) *
|
---|
222 | exp(-2.85*(r_ab-rad_ab));
|
---|
223 |
|
---|
224 | #if OLD_BMAT
|
---|
225 | // return force constant in mdyn*ang/rad^2
|
---|
226 | return k*4.359813653;
|
---|
227 | #else
|
---|
228 | return k;
|
---|
229 | #endif
|
---|
230 | }
|
---|
231 |
|
---|
232 | const char *
|
---|
233 | ScaledTorsSimpleCo::ctype() const
|
---|
234 | {
|
---|
235 | return "STOR";
|
---|
236 | }
|
---|
237 |
|
---|
238 | double
|
---|
239 | ScaledTorsSimpleCo::radians() const
|
---|
240 | {
|
---|
241 | return value_;
|
---|
242 | }
|
---|
243 |
|
---|
244 | double
|
---|
245 | ScaledTorsSimpleCo::degrees() const
|
---|
246 | {
|
---|
247 | return value_*rtd;
|
---|
248 | }
|
---|
249 |
|
---|
250 | double
|
---|
251 | ScaledTorsSimpleCo::preferred_value() const
|
---|
252 | {
|
---|
253 | return value_*rtd;
|
---|
254 | }
|
---|
255 |
|
---|
256 | /////////////////////////////////////////////////////////////////////////////
|
---|
257 |
|
---|
258 | // Local Variables:
|
---|
259 | // mode: c++
|
---|
260 | // c-file-style: "CLJ"
|
---|
261 | // End:
|
---|