35 namespace kinematic_closure {
46 Real d11, d12, d13, d22, d23, d33;
47 d11 = vbond[1]*vbond[1];
48 d22 = vbond[2]*vbond[2];
49 d33 = vbond[3]*vbond[3];
50 d12 = 2*vbond[1]*vbond[2];
51 d13 = 2*vbond[1]*vbond[3];
52 d23 = 2*vbond[2]*vbond[3];
53 calpha[1]=(d22-d33-d11)/d13;
54 salpha[1]=std::sqrt(1-calpha[1]*calpha[1]);
55 calpha[2]=(d33-d11-d22)/d12;
56 salpha[2]=std::sqrt(1-calpha[2]*calpha[2]);
57 calpha[3]=(d11-d22-d33)/d23;
58 salpha[3]=std::sqrt(1-calpha[3]*calpha[3]);
69 for (
int i=1; i<=3; i++ ) {
70 cosine[i]=std::cos(theta[i]);
71 sine[i]=std::sin(theta[i]);
77 for (
int i=1; i<=3; i++ ) {
78 a[i]=std::tan(theta[i]/2);
82 cosine[i]=(1-aa[i])/a1[i];
107 bool& feasible_triangle) {
109 utility::vector1<Real> ctheta (4), calpha (4), salpha (4), cxi (3), sxi (3), ceta (4), seta (4), cdelta (3), sdelta (3), caceta (4), caseta (4), saceta (4), saseta (4), capeta (4), sapeta (4), cameta (4), sameta (4);
110 Real am, ap, cdsx, sdsx,
b, bm, bp, d, dp, dm;
115 for (
int i=1; i<=4; i++ ) {
117 for (
int j=1; j<=3; j++ ) {
127 for (
int i=1; i<=3; i++ ) {
128 for (
int j=1; j<=3; j++ ) {
137 if ( (
std::abs(vb[1] - vb[2]) <= vb[3]) && (vb[1] + vb[2] >= vb[3]) ) {
138 feasible_triangle =
true;
140 for (
int i=1; i<=3; i++ ) {
141 ctheta[i]=std::cos(theta[i]);
146 for (
int i=1; i<=3; i++ ) {
151 sincos(eta, 2, ceta, seta);
152 sincos(delta, 2, cdelta, sdelta);
153 calpha[4] = calpha[1];
154 salpha[4] = salpha[1];
157 ctheta[4] = ctheta[1];
158 for (
int i=1; i<=4; i++ ) {
159 caceta[i] = calpha[i] * ceta[i];
160 caseta[i] = calpha[i] * seta[i];
161 saceta[i] = salpha[i] * ceta[i];
162 saseta[i] = salpha[i] * seta[i];
163 capeta[i] = caceta[i] - saseta[i];
164 sapeta[i] = saceta[i] + caseta[i];
165 cameta[i] = caceta[i] + saseta[i];
166 sameta[i] = saceta[i] - caseta[i];
168 for (
int i=2; i<=4; i++ ) {
169 am = cxi[i-1]*cameta[i] + ctheta[i];
170 ap = cxi[i-1]*capeta[i] + ctheta[i];
171 cdsx = cdelta[i-1]*sxi[i-1];
172 sdsx = 2*sdelta[i-1]*sxi[i-1];
189 for (
int i=1; i<=3; i++ ) {
190 for (
int j=1; j<=3; j++ ) {
191 p[1][i][j]=p[4][i][j];
198 for (
int i=1; i<=3; i++ ) {
203 for (
int k=1; k<=3; k++ ) {
204 for (
int i=1; i<=3; i++ ) {
205 L[k][i] = p[order[1]][i][k];
206 M[k][i] = p[order[2]][k][i];
207 N[k][i] = p[order[3]][k][i];
211 for (
int i=1; i<=3; i++ ) {
212 for (
int j=1; j<=3; j++ ) {
214 A[i][j] = M[i][2]*N[1][j] - M[i][1]*N[2][j];
215 B[i][j] = M[i][3]*N[1][j] - M[i][1]*N[3][j];
216 C[i][j] = M[i][3]*N[2][j] - M[i][2]*N[3][j];
221 feasible_triangle =
false;
222 for (
int i=1; i<=3; i++ ) {
223 for (
int j=1; j<=3; j++ ) {
241 r[1]=L[2]*r0[3]-L[3]*r0[2];
242 r[2]=L[3]*r0[1]-L[1]*r0[3];
243 r[3]=L[1]*r0[2]-L[2]*r0[1];
260 for (
int i=1; i<=3; i++ ) {
263 for (
int i=1; i<=3; i++ ) {
264 U[1][i]=R[2][i]-R[1][i];
266 norm1=std::sqrt(U[1][1]*U[1][1] + U[1][2]*U[1][2] + U[1][3]*U[1][3]);
267 for (
int i=1; i<=3; i++ ) {
269 dR3R2[i]=R[3][i]-R[2][i];
271 cross(U[1], dR3R2, U[3]);
272 norm3=std::sqrt(U[3][1]*U[3][1] + U[3][2]*U[3][2] + U[3][3]*U[3][3]);
273 for (
int i=1; i<=3; i++ ) {
276 cross(U[3], U[1], U[2]);
292 for (
int i=1; i<=3; i++ ) {
293 d += (a[i]-b[i]) * (c[i]-b[i]);
306 Real ang = std::atan2(sqrt(1-r*r), (
Real) r);
321 for (
int i=1; i<=3; i++ ) {
329 for (
int i=1; i<=3; i++ ) {
331 s[i][1] = c[i] - b[i];
332 s[i][2] = a[i] - b[i];
336 cross(sc1, sc2, cs12);
337 for (
int i=1; i<=3; i++ ) {
341 cross(sc3, sc1, cs31);
342 for (
int i=1; i<=3; i++ ) {
345 for (
int i=2; i<=3; i++ ) {
346 f = std::sqrt(
pow(s[1][i],2) +
pow(s[2][i],2) +
pow(s[3][i],2));
352 y = r[1]*s[1][2] + r[2]*s[2][2] + r[3]*s[3][2];
353 z = r[1]*s[1][3] + r[2]*s[2][3] + r[3]*s[3][3];
389 xi=
bondangle(atoms[n-1], atoms[n], atoms[1]);
390 eta=
bondangle(atoms[n], atoms[1], atoms[2]);
391 delta=
torsion(atoms[n-1], atoms[n], atoms[1], atoms[2]);
425 for (
int i=1; i<=n; i++ ) {
426 t_ang[i] = t_ang1[i];
427 b_ang[i] = b_ang1[i];
431 for (
int i=1; i<=n; i++ ) {
432 for (
int j=1; j<=3; j++ ) {
437 atoms[2][1] = b_len[1];
439 ca = std::cos(b_ang[2]);
440 sa = std::sin(b_ang[2]);
441 atoms[3][1] = b_len[1] - b_len[2] * ca;
442 atoms[3][2] = b_len[2] * sa;
445 for (
int i=1; i<=3; i++ ) {
452 for (
int i=1; i<=2; i++ ) {
463 for (
int j=4; j<=n1; j++ ) {
464 ca = std::cos(b_ang[j1]);
465 sa = std::sin(b_ang[j1]);
466 ct = std::cos(t_ang[j2]);
467 st = std::sin(t_ang[j2]);
468 for (
int i=1; i<=3; i++ ) {
471 for (
int i=1; i<=3; i++ ) {
472 U[2][i] = s[i]*ct + U[3][i]*st;
474 for (
int i=1; i<=3; i++ ) {
475 U[3][i] = -s[i]*st + U[3][i]*ct;
477 for (
int i=1; i<=3; i++ ) {
480 for (
int i=1; i<=3; i++ ) {
481 U[2][i] = -s[i]*ca - U[1][i]*sa;
483 for (
int i=1; i<=3; i++ ) {
484 U[1][i] = s[i]*sa - U[1][i]*ca;
486 for (
int i=1; i<=3; i++ ) {
487 atoms[j][i] = atoms[j1][i] + b_len[j1] * U[1][i];
492 ca = std::cos(b_ang[n1]);
493 sa = std::sin(b_ang[n1]);
494 ct = std::cos(t_ang[n2]);
495 st = std::sin(t_ang[n2]);
496 v[1] = -b_len[n1] * ca;
501 for (
int i=1; i<=3; i++ ) {
502 s[i] = (U[1][i] *
v[1]) + (U[2][i] *
v[2]) + (U[3][i] * v[3]);
504 for (
int i=1; i<=3; i++ ) {
505 atoms[n][i] = atoms[n1][i] + s[i];
508 if ( space ==
true ) {
514 for (
int ind=1; ind<=n; ind++ ) {
515 for (
int i=1; i<=3; i++ ) {
517 for (
int j=1; j<=3; j++ ) {
518 inner_sum += (Q[i][j] * atoms[ind][j]);
520 spaceatoms[i]=R0[i]+inner_sum;
522 for (
int k=1; k<=3; k++ ) {
523 atoms[ind][k]=spaceatoms[k];
575 chainXYZ(n, b_len, b_ang, t_ang,
false, dummy_R0, dummy_Q, atoms);
606 for (
int i=1; i<=3; i++ ) {
611 for (
int j=1; j <= n-1; j++ ) {
615 for (
int j=2; j <= n-1; j++ ) {
616 b_ang[j] =
bondangle( atoms[j-1], atoms[j], atoms[j+1] );
622 for (
int j=2; j <= n-2; j++ ) {
623 t_ang[j] =
torsion( atoms[j-1], atoms[j], atoms[j+1], atoms[j+2] );
629 for (
int j=1; j<=n; j++ ) {
643 for (
int i=1; i<=dim1; i++ ) {
644 Rx[i].resize(R[i].
size());
646 Rx[i][2] = c*R[i][2] - s*R[i][3];
647 Rx[i][3] = s*R[i][2] + c*R[i][3];
659 for (
int i=1; i<=dim1; i++ ) {
660 Ry[i].resize(R[i].
size());
661 Ry[i][1] = c*R[i][1] + s*R[i][3];
663 Ry[i][3] = -s*R[i][1] + c*R[i][3];
675 for (
int i=1; i<=dim1; i++ ) {
676 Rz[i].resize(R[i].
size());
677 Rz[i][1] = c*R[i][1] - s*R[i][2];
678 Rz[i][2] = s*R[i][1] + c*R[i][2];
687 for (
Size i = 1; i < degrees.size(); i++ ) {
696 for (
Size i = 1; i < radians.size(); i++ ) {
763 int k1, k2, k3,
l1, l2, l3, l3a, l3b;
766 bool feasible_triangle;
789 for (
int i=pivots[1]; i<=pivots[2]; i++ ) {
793 for (
int i=pivots[2]; i<=pivots[3]; i++ ) {
797 for (
int i=pivots[1]; i<=pivots[2]; i++ ) {
801 for (
int i=pivots[2]; i<=pivots[3]; i++ ) {
805 for (
int i=pivots[1]; i<=pivots[2]; i++ ) {
806 b_len1[ind++] = db[i];
809 for (
int i=pivots[2]; i<=pivots[3]; i++ ) {
810 b_len2[ind++] = db[i];
813 chainXYZ( l1, b_len1, b_ang1, t_ang1,
false, R0, Q0, chain1 );
814 chainXYZ( l2, b_len2, b_ang2, t_ang2,
false, R0, Q0, chain2 );
818 for (
int i=k3; i<=N; i++ ) {
819 chain3[ind++] = atoms[i];
821 for (
int i=1; i<=k1; i++ ) {
822 chain3[ind++] = atoms[i];
826 chainParams( l1, chain1, vbond[1], xi[1], eta[1], delta[1], R1, frame1 );
827 for (
int i=1; i<=
l1; i++ ) {
828 for (
int j=1; j<=3; j++ ) {
829 chain1[i][j] -= R1[j];
833 chainParams( l2, chain2, vbond[2], xi[2], eta[2], delta[2], R2, frame2 );
834 for (
int i=1; i<=l2; i++ ) {
835 for (
int j=1; j<=3; j++ ) {
836 chain2[i][j] -= R2[j];
840 chainParams( l3, chain3, vbond[3], xi[3], eta[3], delta[3], R3, frame3 );
841 for (
int i=1; i<=3; i++ ) {
842 theta[i] = da[pivots[i]];
847 triaxialCoefficients( vbond, xi, eta, delta, theta, order, A, B, C, D, cal, sal, feasible_triangle);
849 if ( feasible_triangle ==
false ) {
855 dixon_eig(A, B, C, D, order, cosines, sines, taus, nsol);
862 for (
int j=1; j<=nsol; j++ ) {
863 rotateX(fchain1, cosines[j][1], sines[j][1], chain1a);
864 rotateZ(chain1a, cal[1], sal[1], chain1b);
865 for (
unsigned k=1; k<=chain1b.size(); k++ ) {
866 chain1b[k][1] += vbond[3];
868 rotateX(fchain2, cosines[j][2], sines[j][2], chain2a);
869 rotateZ(chain2a, cal[3], -sal[3], chain2b);
870 for (
unsigned k=1; k<=chain2b.size(); k++ ) {
871 chain2b[k][1] -= chain2b[l2][1];
872 chain2b[k][2] -= chain2b[l2][2];
875 int chain12len = (l1-1) + (l2-2);
876 chain12.resize(chain12len);
878 for (
int k=2; k<=
l1; k++ ) {
879 chain12[ind].resize(3);
880 for (
int n=1; n<=3; n++ ) {
881 chain12[ind][n] = chain1b[k][n];
885 for (
int k=2; k<=l2-1; k++ ) {
886 chain12[ind].resize(3);
887 for (
int n=1; n<=3; n++ ) {
888 chain12[ind][n] = chain2b[k][n];
892 rotateX(chain12, cosines[j][3], -sines[j][3], chain12rX);
894 for (
int k=1; k<=chain12len; k++ ) {
895 for (
int n=1; n<=3; n++ ) {
896 chain12[k][n] += R3[n];
902 for (
int k=1; k<=l3b; k++ ) {
903 loop[j][k].resize(3);
904 for (
int kk=1; kk<=3; kk++ ) {
905 loop[j][k][kk] = chain3[l3a+k][kk];
908 for (
int k=1; k<= l1 + l2 - 3; k++ ) {
909 loop[j][l3b+k].resize(3);
910 for (
int kk=1; kk<=3; kk++ ) {
911 loop[j][l3b+k][kk] = chain12[k][kk];
914 for (
int k=1; k<=l3a; k++ ) {
915 loop[j][l3b+l1+l2-3+k].resize(3);
916 for (
int kk=1; kk<=3; kk++ ) {
917 loop[j][l3b+l1+l2-3+k][kk] = chain3[k][kk];
924 int pivots2m1 = pivots[2]-1, pivots2p1 = pivots[2]+1,
925 pivots3m1 = pivots[3]-1, pivots3p1 = pivots[3]+1;
930 t_ang[j][4] =
static_cast<Real> (
torsion(loop[j][3],loop[j][4],loop[j][5],loop[j][6]));
931 t_ang[j][5] =
static_cast<Real> (
torsion(loop[j][4],loop[j][5],loop[j][6],loop[j][7]));
932 t_ang[j][pivots2m1] =
static_cast<Real> (
torsion(loop[j][pivots[2]-2],loop[j][pivots2m1],
933 loop[j][pivots[2]],loop[j][pivots2p1]));
934 t_ang[j][pivots[2]] =
static_cast<Real> (
torsion(loop[j][pivots2m1],loop[j][pivots[2]],
935 loop[j][pivots2p1],loop[j][pivots[2]+2]));
936 t_ang[j][pivots3m1] =
static_cast<Real> (
torsion(loop[j][pivots[3]-2],loop[j][pivots3m1],
937 loop[j][pivots[3]],loop[j][pivots3p1]));
938 t_ang[j][pivots[3]] =
static_cast<Real> (
torsion(loop[j][pivots3m1],loop[j][pivots[3]],
939 loop[j][pivots3p1],loop[j][pivots[3]+2]));
void multTransMatrix(const utility::vector1< utility::vector1< Real > > &A, const utility::vector1< utility::vector1< Real > > &B, utility::vector1< utility::vector1< Real > > &C)
void triaxialCoefficients(const utility::vector1< Real > &vb, const utility::vector1< Real > &xi, const utility::vector1< Real > &eta, const utility::vector1< Real > &delta, const utility::vector1< Real > &theta, const utility::vector1< int > &order, utility::vector1< utility::vector1< Real > > &A, utility::vector1< utility::vector1< Real > > &B, utility::vector1< utility::vector1< Real > > &C, utility::vector1< utility::vector1< Real > > &D, utility::vector1< Real > &cal, utility::vector1< Real > &sal, bool &feasible_triangle)
char space()
Space Character.
Conversions between degrees and radians.
void to_degrees(utility::vector1< Real > &radians)
void frame(const utility::vector1< utility::vector1< Real > > &R, utility::vector1< utility::vector1< Real > > &U)
Real eucDistance(const utility::vector1< Real > &a, const utility::vector1< Real > &b)
Real scpn(const utility::vector1< Real > &a, const utility::vector1< Real > &b, const utility::vector1< Real > &c)
void triangle(const utility::vector1< Real > &vbond, utility::vector1< Real > &calpha, utility::vector1< Real > &salpha)
void cross(const utility::vector1< Real > &L, const utility::vector1< Real > &r0, utility::vector1< Real > &r)
T & to_degrees(T &radians)
Degrees from radians.
void chainParams(const int &n, const utility::vector1< utility::vector1< Real > > &atoms, Real &vbond, Real &xi, Real &eta, Real &delta, utility::vector1< Real > &R0, utility::vector1< utility::vector1< Real > > &Q)
Functions to wrap angles in different ranges. author Kale Kundert (kale.kundert@ucsf.edu)
T abs(T const &x)
std::abs( x ) == | x |
void sincos(const utility::vector1< Real > &theta, const int flag, utility::vector1< Real > &cosine, utility::vector1< Real > &sine)
Header file for dixon code for ALC.
Real bondangle(const utility::vector1< Real > &a, const utility::vector1< Real > &b, const utility::vector1< Real > &c)
T wrap_2pi(T const &angle)
Wrap the given angle in the range [0, 2 * pi).
T degrees(T const &radians)
Degrees of radians.
rosetta project type declarations. Should be kept updated with core/types.hh. This exists because num...
void rotateX(const utility::vector1< utility::vector1< Real > > &R, const Real &c, const Real &s, utility::vector1< utility::vector1< Real > > &Rx)
void chainTORS(const int &n, const utility::vector1< utility::vector1< Real > > &atoms, utility::vector1< Real > &t_ang, utility::vector1< Real > &b_ang, utility::vector1< Real > &b_len, utility::vector1< Real > &R0, utility::vector1< utility::vector1< Real > > &Q)
void chainXYZ(const int &n, const utility::vector1< Real > &b_len1, const utility::vector1< Real > &b_ang1, const utility::vector1< Real > &t_ang1, const bool space, const utility::vector1< Real > &R0, const utility::vector1< utility::vector1< Real > > &Q, utility::vector1< utility::vector1< Real > > &atoms)
void dixon_eig(PseudoMatrix const &A, PseudoMatrix const &B, PseudoMatrix const &C, PseudoMatrix const &D, vector1< int > const &, PseudoMatrix &cos, PseudoMatrix &sin, PseudoMatrix &u, int &num_solutions)
void multMatrix(const utility::vector1< utility::vector1< Real > > &A, const utility::vector1< utility::vector1< Real > > &B, utility::vector1< utility::vector1< Real > > &C)
DimensionExpressionPow pow(Dimension const &dim1, Dimension const &dim2)
pow( Dimension, Dimension )
void bridge_objects(const utility::vector1< utility::vector1< Real > > &atoms, const utility::vector1< Real > &dt, const utility::vector1< Real > &da, const utility::vector1< Real > &db, const utility::vector1< int > &pivots, const utility::vector1< int > &order, utility::vector1< utility::vector1< Real > > &t_ang, utility::vector1< utility::vector1< Real > > &b_ang, utility::vector1< utility::vector1< Real > > &b_len, int &nsol)
Solve the triaxial loop closure problem for a system of atoms.
vector1: std::vector with 1-based indexing
void rotateZ(const utility::vector1< utility::vector1< Real > > &R, const Real &c, const Real &s, utility::vector1< utility::vector1< Real > > &Rz)
void rotateY(const utility::vector1< utility::vector1< Real > > &R, const Real &c, const Real &s, utility::vector1< utility::vector1< Real > > &Ry)
void to_radians(utility::vector1< Real > °rees)
Real torsion(const utility::vector1< Real > &a, const utility::vector1< Real > &b, const utility::vector1< Real > &c, const utility::vector1< Real > &d)
Common numeric constants in varying precisions.
T radians(T const °rees)
Radians of degrees.
Header file for kinematic_closure_helpers.cc.
T & to_radians(T °rees)
Radians from degrees.