12 #include <Eigen/Dense> 19 #if defined(__SSE2__) && ! defined(NAMD_DISABLE_SSE) 20 #include <emmintrin.h> 21 #if defined(__INTEL_COMPILER) 22 #define __align(X) __declspec(align(X) ) 24 #define __align(X) __attribute__((aligned(X) )) 25 #define MISSING_mm_cvtsd_f64 26 #elif defined(__GNUC__) 27 #define __align(X) __attribute__((aligned(X) )) 29 #define MISSING_mm_cvtsd_f64 32 #define __align(X) __declspec(align(X) ) 50 BigReal rmT = 1.0 / (pmO+pmH+pmH);
57 ra = sqrt(ohdist*ohdist-rc*rc)/(1.0+t1);
66 #if defined(__SSE2__) && ! defined(NAMD_DISABLE_SSE) 80 __m128d REF0xy = _mm_loadu_pd((
double *) &ref[0].x);
81 __m128d REF1xy = _mm_loadu_pd((
double *) &ref[1].x);
83 __m128d B0xy = _mm_sub_pd(REF1xy, REF0xy);
84 _mm_storeu_pd((
double *) &b0.
x, B0xy);
85 b0.
z = ref[1].
z - ref[0].
z;
87 __m128d REF2xy = _mm_loadu_pd((
double *) &ref[2].x);
89 __m128d C0xy = _mm_sub_pd(REF2xy, REF0xy);
90 _mm_storeu_pd((
double *) &c0.
x, C0xy);
91 c0.
z = ref[2].
z - ref[0].
z;
100 __m128d POS1xy = _mm_loadu_pd((
double *) &pos[1].x);
101 __m128d POS2xy = _mm_loadu_pd((
double *) &pos[2].x);
102 __m128d PMHrmTxy = _mm_mul_pd(_mm_add_pd(POS1xy, POS2xy), _mm_set1_pd(mHrmT));
104 __m128d POS0xy = _mm_loadu_pd((
double *) &pos[0].x);
105 __m128d PMOrmTxy = _mm_mul_pd(POS0xy, _mm_set1_pd(mOrmT));
106 __m128d D0xy = _mm_add_pd(PMOrmTxy, PMHrmTxy);
108 d0.
z = pos[0].
z * mOrmT + ((pos[1].
z + pos[2].
z) * mHrmT);
109 a1.
z = pos[0].
z - d0.
z;
110 b1.
z = pos[1].
z - d0.
z;
111 c1.
z = pos[2].
z - d0.
z;
113 __m128d A1xy = _mm_sub_pd(POS0xy, D0xy);
114 _mm_store_pd((
double *) &a1.
x, A1xy);
116 __m128d B1xy = _mm_sub_pd(POS1xy, D0xy);
117 _mm_store_pd((
double *) &b1.
x, B1xy);
119 __m128d C1xy = _mm_sub_pd(POS2xy, D0xy);
120 _mm_store_pd((
double *) &c1.
x, C1xy);
122 _mm_store_pd((
double *) &d0.
x, D0xy);
126 Vector n0 = cross(b0, c0);
127 Vector n1 = cross(a1, n0);
128 Vector n2 = cross(n0, n1);
131 Vector b0 = ref[1]-ref[0];
132 Vector c0 = ref[2]-ref[0];
135 Vector d0 = pos[0]*mOrmT + ((pos[1] + pos[2])*mHrmT);
143 Vector n0 = cross(b0, c0);
144 Vector n1 = cross(a1, n0);
145 Vector n2 = cross(n0, n1);
148 #if defined(__SSE2__) && ! defined(NAMD_DISABLE_SSE) && ! defined(MISSING_mm_cvtsd_f64) 149 __m128d l1 = _mm_set_pd(n0.
x, n0.
y);
150 l1 = _mm_mul_pd(l1, l1);
152 double l1xy0 = _mm_cvtsd_f64(_mm_add_sd(l1, _mm_shuffle_pd(l1, l1, 1)));
154 __m128d l3 = _mm_set_pd(n1.
y, n1.
z);
155 l3 = _mm_mul_pd(l3, l3);
157 double l3yz1 = _mm_cvtsd_f64(_mm_add_sd(l3, _mm_shuffle_pd(l3, l3, 1)));
159 __m128d l2 = _mm_set_pd(n1.
x, n0.
z);
161 __m128d ts01 = _mm_add_pd(_mm_set_pd(l3yz1, l1xy0), _mm_mul_pd(l2, l2));
163 __m128d l4 = _mm_set_pd(n2.
x, n2.
y);
164 l4 = _mm_mul_pd(l4, l4);
166 double l4xy2 = _mm_cvtsd_f64(_mm_add_sd(l4, _mm_shuffle_pd(l4, l4, 1)));
167 double ts2 = l4xy2 + (n2.
z * n2.
z);
172 static const __m128d fvecd1p0 = _mm_set1_pd(1.0);
175 __m128d invlen12 = _mm_div_pd(fvecd1p0, _mm_sqrt_pd(ts01));
178 _mm_storeu_pd(invlens, invlen12);
180 n0 = n0 * invlens[0];
187 BigReal tmp = 1.0-sinphi*sinphi;
189 __m128d n2cosphi = _mm_sqrt_pd(_mm_set_pd(tmp, ts2));
191 _mm_storeu_pd(invlens+2, n2cosphi);
193 n1 = n1 * invlens[1];
194 n2 = n2 * (1.0 / invlens[2]);
197 b0 =
Vector(n1*b0, n2*b0, n0*b0);
198 c0 =
Vector(n1*c0, n2*c0, n0*c0);
200 b1 =
Vector(n1*b1, n2*b1, n0*b1);
201 c1 =
Vector(n1*c1, n2*c1, n0*c1);
204 BigReal sinpsi = (b1.z - c1.z)/(2.0*rc*cosphi);
205 tmp = 1.0-sinpsi*sinpsi;
212 b0 =
Vector(n1*b0, n2*b0, n0*b0);
213 c0 =
Vector(n1*c0, n2*c0, n0*c0);
216 b1 =
Vector(n1*b1, n2*b1, n0*b1);
217 c1 =
Vector(n1*c1, n2*c1, n0*c1);
221 BigReal tmp = 1.0-sinphi*sinphi;
223 BigReal sinpsi = (b1.z - c1.z)/(2.0*rc*cosphi);
224 tmp = 1.0-sinpsi*sinpsi;
229 BigReal tmp1 = rc*sinpsi*sinphi;
230 BigReal tmp2 = rc*sinpsi*cosphi;
232 Vector a2(0, ra*cosphi, ra*sinphi);
233 Vector b2(-rc*cospsi, rbphi - tmp1, -rb*sinphi + tmp2);
234 Vector c2( rc*cosphi, rbphi + tmp1, -rb*sinphi - tmp2);
238 BigReal alpha = b2.
x*(b0.x - c0.x) + b0.y*b2.
y + c0.y*c2.
y;
239 BigReal beta = b2.
x*(c0.y - b0.y) + b0.x*b2.
y + c0.x*c2.
y;
240 BigReal gama = b0.x*b1.y - b1.x*b0.y + c0.x*c1.y - c1.x*c0.y;
242 BigReal a2b2 = alpha*alpha + beta*beta;
243 BigReal sintheta = (alpha*gama - beta*sqrt(a2b2 - gama*gama))/a2b2;
244 BigReal costheta = sqrt(1.0 - sintheta*sintheta);
250 Vector b3(b2.
x*costheta - b2.
y*sintheta,
251 b2.
x*sintheta + b2.
y*costheta,
253 Vector c3(c2.
x*costheta - c2.
y*sintheta,
254 c2.
x*sintheta + c2.
y*costheta,
261 Vector b3(b2.
x*costheta - b2.
y*sintheta,
262 b2.
x*sintheta + b2.
y*costheta,
264 Vector c3(-b2.
x*costheta - c2.
y*sintheta,
265 -b2.
x*sintheta + c2.
y*costheta,
275 pos[0] =
Vector(a3*m1, a3*m2, a3*m0) + d0;
276 pos[1] =
Vector(b3*m1, b3*m2, b3*m0) + d0;
277 pos[2] =
Vector(c3*m1, c3*m2, c3*m0) + d0;
281 vel[0] = (pos[0]-ref[0])*invdt;
282 vel[1] = (pos[1]-ref[1])*invdt;
283 vel[2] = (pos[2]-ref[2])*invdt;
292 template <
int veclen>
317 for (
int i=0;i < veclen;i++) {
318 ref0xt[i] = ref[i*3+0].
x;
319 ref0yt[i] = ref[i*3+0].
y;
320 ref0zt[i] = ref[i*3+0].
z;
321 ref1xt[i] = ref[i*3+1].
x;
322 ref1yt[i] = ref[i*3+1].
y;
323 ref1zt[i] = ref[i*3+1].
z;
324 ref2xt[i] = ref[i*3+2].
x;
325 ref2yt[i] = ref[i*3+2].
y;
326 ref2zt[i] = ref[i*3+2].
z;
328 pos0xt[i] = pos[i*3+0].
x;
329 pos0yt[i] = pos[i*3+0].
y;
330 pos0zt[i] = pos[i*3+0].
z;
331 pos1xt[i] = pos[i*3+1].
x;
332 pos1yt[i] = pos[i*3+1].
y;
333 pos1zt[i] = pos[i*3+1].
z;
334 pos2xt[i] = pos[i*3+2].
x;
335 pos2yt[i] = pos[i*3+2].
y;
336 pos2zt[i] = pos[i*3+2].
z;
340 for (
int i=0;i < veclen;i++) {
372 BigReal d0x = pos0x*mOrmT + ((pos1x + pos2x)*mHrmT);
373 BigReal d0y = pos0y*mOrmT + ((pos1y + pos2y)*mHrmT);
374 BigReal d0z = pos0z*mOrmT + ((pos1z + pos2z)*mHrmT);
406 BigReal n0inv = 1.0/sqrt(n0x*n0x + n0y*n0y + n0z*n0z);
411 BigReal n1inv = 1.0/sqrt(n1x*n1x + n1y*n1y + n1z*n1z);
416 BigReal n2inv = 1.0/sqrt(n2x*n2x + n2y*n2y + n2z*n2z);
422 BigReal n1b0 = n1x*b0x + n1y*b0y + n1z*b0z;
423 BigReal n2b0 = n2x*b0x + n2y*b0y + n2z*b0z;
426 BigReal n1c0 = n1x*c0x + n1y*c0y + n1z*c0z;
427 BigReal n2c0 = n2x*c0x + n2y*c0y + n2z*c0z;
429 BigReal A1Z = n0x*a1x + n0y*a1y + n0z*a1z;
432 BigReal n1b1 = n1x*b1x + n1y*b1y + n1z*b1z;
433 BigReal n2b1 = n2x*b1x + n2y*b1y + n2z*b1z;
434 BigReal n0b1 = n0x*b1x + n0y*b1y + n0z*b1z;
437 BigReal n1c1 = n1x*c1x + n1y*c1y + n1z*c1z;
438 BigReal n2c1 = n2x*c1x + n2y*c1y + n2z*c1z;
439 BigReal n0c1 = n0x*c1x + n0y*c1y + n0z*c1z;
443 BigReal tmp = 1.0-sinphi*sinphi;
445 BigReal sinpsi = (n0b1 - n0c1)/(2.0*rc*cosphi);
446 tmp = 1.0-sinpsi*sinpsi;
450 BigReal tmp1 = rc*sinpsi*sinphi;
451 BigReal tmp2 = rc*sinpsi*cosphi;
465 BigReal alpha = b2x*(n1b0 - n1c0) + n2b0*b2y + n2c0*c2y;
466 BigReal beta = b2x*(n2c0 - n2b0) + n1b0*b2y + n1c0*c2y;
467 BigReal gama = n1b0*n2b1 - n1b1*n2b0 + n1c0*n2c1 - n1c1*n2c0;
469 BigReal a2b2 = alpha*alpha + beta*beta;
470 BigReal sintheta = (alpha*gama - beta*sqrt(a2b2 - gama*gama))/a2b2;
471 BigReal costheta = sqrt(1.0 - sintheta*sintheta);
483 BigReal b3x = b2x*costheta - b2y*sintheta;
484 BigReal b3y = b2x*sintheta + b2y*costheta;
490 BigReal c3x = -b2x*costheta - c2y*sintheta;
491 BigReal c3y = -b2x*sintheta + c2y*costheta;
511 pos0x = a3x*m1x + a3y*m1y + a3z*m1z + d0x;
512 pos0y = a3x*m2x + a3y*m2y + a3z*m2z + d0y;
513 pos0z = a3x*m0x + a3y*m0y + a3z*m0z + d0z;
516 pos1x = b3x*m1x + b3y*m1y + b3z*m1z + d0x;
517 pos1y = b3x*m2x + b3y*m2y + b3z*m2z + d0y;
518 pos1z = b3x*m0x + b3y*m0y + b3z*m0z + d0z;
521 pos2x = c3x*m1x + c3y*m1y + c3z*m1z + d0x;
522 pos2y = c3x*m2x + c3y*m2y + c3z*m2z + d0y;
523 pos2z = c3x*m0x + c3y*m0y + c3z*m0z + d0z;
536 for (
int i=0;i < veclen;i++) {
537 pos[i*3+0].
x = pos0xt[i];
538 pos[i*3+0].
y = pos0yt[i];
539 pos[i*3+0].
z = pos0zt[i];
540 pos[i*3+1].
x = pos1xt[i];
541 pos[i*3+1].
y = pos1yt[i];
542 pos[i*3+1].
z = pos1zt[i];
543 pos[i*3+2].
x = pos2xt[i];
544 pos[i*3+2].
y = pos2yt[i];
545 pos[i*3+2].
z = pos2zt[i];
553 template <
int veclen>
558 int a = rattleParam[0].
ia;
559 int b = rattleParam[0].
ib;
560 BigReal pabx = posx[a] - posx[b];
561 BigReal paby = posy[a] - posy[b];
562 BigReal pabz = posz[a] - posz[b];
563 BigReal pabsq = pabx*pabx + paby*paby + pabz*pabz;
565 BigReal diffsq = rabsq - pabsq;
566 BigReal rabx = refx[a] - refx[b];
567 BigReal raby = refy[a] - refy[b];
568 BigReal rabz = refz[a] - refz[b];
570 BigReal refsq = rabx*rabx + raby*raby + rabz*rabz;
572 BigReal rpab = rabx*pabx + raby*paby + rabz*pabz;
578 BigReal sqrtarg = rpab*rpab + refsq*diffsq;
579 if ( sqrtarg < 0. ) {
584 gab = (-rpab + sqrt(sqrtarg))/(refsq*(rma + rmb));
590 posx[a] += rma * dpx;
591 posy[a] += rma * dpy;
592 posz[a] += rma * dpz;
593 posx[b] -= rmb * dpx;
594 posy[b] -= rmb * dpy;
595 posz[b] -= rmb * dpz;
599 void iterate(
const int icnt,
const RattleParam* rattleParam,
602 const BigReal tol2,
const int maxiter,
603 bool& done,
bool& consFailure)
606 using namespace Eigen;
608 typedef VectorXf VectorXr;
609 typedef MatrixXf MatrixXr;
611 typedef VectorXd VectorXr;
612 typedef MatrixXd MatrixXr;
614 VectorXr sigma(icnt), lambda(icnt), ptmp(3*icnt), rtmp(3*icnt);
615 MatrixXr A(icnt, icnt);
618 PartialPivLU<MatrixXr> lu;
619 bool constructMatrix =
true;
620 for(loop = 0; loop < maxiter; ++loop)
623 for(
int i = 0; i < icnt; ++i)
625 int a = rattleParam[i].
ia;
626 int b = rattleParam[i].
ib;
627 BigReal pabx = posx[a] - posx[b];
628 BigReal paby = posy[a] - posy[b];
629 BigReal pabz = posz[a] - posz[b];
633 BigReal pabsq = pabx*pabx + paby*paby + pabz*pabz;
635 BigReal diffsq = pabsq - rabsq;
637 if ( fabs(diffsq) > (rabsq * tol2) )
644 for(
int i = 0; i < icnt; ++i)
646 int a = rattleParam[i].
ia;
647 int b = rattleParam[i].
ib;
648 rtmp[3*i] = refx[a] - refx[b];
649 rtmp[3*i+1] = refy[a] - refy[b];
650 rtmp[3*i+2] = refz[a] - refz[b];
652 for(
int i = 0; i < icnt; ++i)
662 for(
int j = 0; j < icnt; ++j)
670 A(i,i) = 2.*(pabx*rabx+paby*raby+pabz*rabz)*(rma+rmb);
672 A(i,j) = 2.*(pabx*rabx+paby*raby+pabz*rabz)*rma;
679 constructMatrix =
false;
683 lambda = lu.solve(sigma);
685 for(
int i = 0; i < icnt; ++i)
687 int a = rattleParam[i].
ia;
688 int b = rattleParam[i].
ib;
695 posx[a] -= rma * rabx;
696 posy[a] -= rma * raby;
697 posz[a] -= rma * rabz;
698 posx[b] += rmb * rabx;
699 posy[b] += rmb * raby;
700 posz[b] += rmb * rabz;
710 #if !(defined(__CUDACC__) || defined(__HIPCC__)) 714 A[0][0]*(A[1][1]*A[2][2]-A[1][2]*A[2][1])-
715 A[0][1]*(A[1][0]*A[2][2]-A[1][2]*A[2][0])+
716 A[0][2]*(A[1][0]*A[2][1]-A[1][1]*A[2][0]);
722 for (
int i = 0; i < 4; i++)
740 for (
int k = 0; k < 4; ++k)
746 for (
int row = k + 1; row < 4; ++row)
748 if ((tmp = fabs(A(row, k))) > Max)
757 for (
int row = k + 1; row < 4; ++row)
759 BigReal tmp = A[row][k]/ A[k][k];
760 for (
int col = k+1; col < 4; col++)
761 A[row][col] -= tmp * A[k][col];
763 sigma[row]-= tmp * sigma[k];
766 for (
int row = 3; row >= 0; --row)
769 for (
int j = 3; j > row; --j)
770 tmp -= lambda[j] * A[row][j];
771 lambda[row] = tmp / A[row][row];
781 lambda[0] = sigma[0]/A[0][0];
787 BigReal det=1./(A[0][0]*A[1][1]-A[0][1]*A[1][0]);
788 lambda[0] = ( A[1][1]*sigma[0]-A[0][1]*sigma[1])*det;
789 lambda[1] = (-A[1][0]*sigma[0]+A[0][0]*sigma[1])*det;
795 lambda[0] = det*((A[1][1]*A[2][2]-A[1][2]*A[2][1])*sigma[0]-
796 (A[0][1]*A[2][2]-A[0][2]*A[2][1])*sigma[1]+
797 (A[0][1]*A[1][2]-A[0][2]*A[1][1])*sigma[2]);
799 lambda[1] = det*((A[1][2]*A[2][0]-A[1][0]*A[2][2])*sigma[0]+
800 (A[0][0]*A[2][2]-A[0][2]*A[2][0])*sigma[1]-
801 (A[0][0]*A[1][2]-A[0][2]*A[1][0])*sigma[2]);
803 lambda[2] = det*((A[1][0]*A[2][1]-A[1][1]*A[2][0])*sigma[0]-
804 (A[0][0]*A[2][1]-A[0][1]*A[2][0])*sigma[1]+
805 (A[0][0]*A[1][1]-A[0][1]*A[1][0])*sigma[2]);
819 for(
int i = 0; i < icnt; ++i)
825 for(
int j = 0; j < 4; ++j)
833 const BigReal tol2,
const int maxiter,
834 bool& done,
bool& consFailure)
849 for(
int i = 0; i < 4; ++i)
851 int a = rattleParam[i].
ia;
852 int b = rattleParam[i].
ib;
853 pabx[i] = posx[a] - posx[b];
854 paby[i] = posy[a] - posy[b];
855 pabz[i] = posz[a] - posz[b];
856 rabx[i] = refx[a] - refx[b];
857 raby[i] = refy[a] - refy[b];
858 rabz[i] = refz[a] - refz[b];
861 for(
int i = 0; i < 4; ++i)
863 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
865 BigReal diffsq = pabsq - rabsq;
867 if ( fabs(diffsq) > (rabsq * tol2) && i < icnt)
870 for(loop = 0; loop < maxiter; ++loop)
876 for(
int j = 0; j < 4; ++j)
880 for(
int i = 0; i < 4; ++i)
882 A[j][i] = 2.*(pabx[j]*rabx[i]+paby[j]*raby[i]+pabz[j]*rabz[i])*rma;
885 A[j][j] += 2.*(pabx[j]*rabx[j]+paby[j]*raby[j]+pabz[j]*rabz[j])*rmb;
894 for(
int i = 0; i < 4; ++i)
896 int a = rattleParam[i].
ia;
897 int b = rattleParam[i].
ib;
901 posx[a] -= rma * rabx[i];
902 posy[a] -= rma * raby[i];
903 posz[a] -= rma * rabz[i];
904 posx[b] += rmb * rabx[i];
905 posy[b] += rmb * raby[i];
906 posz[b] += rmb * rabz[i];
914 for(
int i = 0; i < 4; ++i)
916 int a = rattleParam[i].
ia;
917 int b = rattleParam[i].
ib;
918 pabx[i] = posx[a] - posx[b];
919 paby[i] = posy[a] - posy[b];
920 pabz[i] = posz[a] - posz[b];
921 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
923 BigReal diffsq = pabsq - rabsq;
925 if ( fabs(diffsq) > (rabsq * tol2) && i < icnt)
939 const BigReal tol2,
const int maxiter,
940 bool& done,
bool& consFailure)
955 for(
int i = 0; i < 4; ++i)
957 int a = rattleParam[i].
ia;
958 int b = rattleParam[i].
ib;
959 pabx[i] = posx[a] - posx[b];
960 paby[i] = posy[a] - posy[b];
961 pabz[i] = posz[a] - posz[b];
962 rabx[i] = refx[a] - refx[b];
963 raby[i] = refy[a] - refy[b];
964 rabz[i] = refz[a] - refz[b];
965 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
968 drab[i] = 1./sqrt(rabx[i]*rabx[i]+raby[i]*raby[i]+rabz[i]*rabz[i]);
971 BigReal diffsq = pabsq - rabsq;
972 if ( fabs(diffsq) > (rabsq * tol2) && i < icnt)
981 for(
int i = 0; i < 16; ++i)
984 int idx = i - (idy << 2);
985 S[idy][idx] = (rabx[idx]*rabx[idy]+raby[idx]*raby[idy]+rabz[idx]*rabz[idy])*rattleParam[idx].rma
986 *drab[idx]*drab[idy];
990 for(
int i = 0; i < 4; ++i)
993 S[i][i] += rattleParam[i].
rmb/rattleParam[i].
rma*S[i][i];
994 r_unc[i] = (pabx[i]*rabx[i]+paby[i]*raby[i]+pabz[i]*rabz[i])*drab[i] -sqrt(rattleParam[i].dsq);
998 for(
int i = 0; i < 4; ++i)
1000 for(
int j = 0; j < 4; ++j)
1004 for(
int i = 0; i < 4; ++i)
1006 for(
int j = 0; j < 4; ++j)
1007 lambda[i] += A[i][j] * r_unc[j];
1009 for(
int i = 0; i < 4; ++i)
1011 int a = rattleParam[i].
ia;
1012 int b = rattleParam[i].
ib;
1016 posx[a] = posx[a] - rabx[i]*rma;
1017 posy[a] = posy[a] - raby[i]*rma;
1018 posz[a] = posz[a] - rabz[i]*rma;
1019 posx[b] = posx[b] + rabx[i]*rmb;
1020 posy[b] = posy[b] + raby[i]*rmb;
1021 posz[b] = posz[b] + rabz[i]*rmb;
1023 for(iter = 1; iter < maxiter; ++iter)
1027 for(
int i = 0; i < 4; ++i)
1029 int a = rattleParam[i].
ia;
1030 int b = rattleParam[i].
ib;
1031 pabx[i] = posx[a] - posx[b];
1032 paby[i] = posy[a] - posy[b];
1033 pabz[i] = posz[a] - posz[b];
1034 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
1036 BigReal diffsq = pabsq - rabsq;
1037 if ( fabs(diffsq) > (rabsq * tol2) && i < icnt)
1039 r_unc[i] = (pabx[i]*rabx[i]+paby[i]*raby[i]+pabz[i]*rabz[i])*drab[i] -sqrt(2.*rabsq-pabsq);
1050 for(
int i = 0; i < 4; ++i)
1052 for(
int j = 0; j < 4; ++j)
1053 lambda[i] += A[i][j] * r_unc[j];
1056 for(
int i = 0; i < 4; ++i)
1058 int a = rattleParam[i].
ia;
1059 int b = rattleParam[i].
ib;
1063 posx[a] = posx[a] - rabx[i]*rma;
1064 posy[a] = posy[a] - raby[i]*rma;
1065 posz[a] = posz[a] - rabz[i]*rma;
1066 posx[b] = posx[b] + rabx[i]*rmb;
1067 posy[b] = posy[b] + raby[i]*rmb;
1068 posz[b] = posz[b] + rabz[i]*rmb;
1082 const BigReal tol2,
const int maxiter,
1083 bool& done,
bool& consFailure)
1085 using namespace Eigen;
1087 typedef VectorXf VectorXr;
1088 typedef MatrixXf MatrixXr;
1090 typedef VectorXd VectorXr;
1091 typedef MatrixXd MatrixXr;
1093 VectorXr sigma(icnt), lambda(icnt);
1094 MatrixXr A(icnt, icnt);
1108 consFailure =
false;
1110 for(
int i = 0; i < icnt; ++i)
1112 int a = rattleParam[i].
ia;
1113 int b = rattleParam[i].
ib;
1114 pabx[i] = posx[a] - posx[b];
1115 paby[i] = posy[a] - posy[b];
1116 pabz[i] = posz[a] - posz[b];
1117 rabx[i] = refx[a] - refx[b];
1118 raby[i] = refy[a] - refy[b];
1119 rabz[i] = refz[a] - refz[b];
1121 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
1123 BigReal diffsq = pabsq - rabsq;
1125 if ( fabs(diffsq) > (rabsq * tol2) )
1128 for(loop = 0; loop < maxiter; ++loop)
1133 for(
int i = 0; i < icnt*icnt; ++i)
1135 int idx2 = i / icnt;
1136 int idx1 = i - icnt * idx2;
1138 A(idx1,idx2) = 2.*(pabx[idx1]*rabx[idx2]+paby[idx1]*raby[idx2]+pabz[idx1]*rabz[idx2])*rma;
1140 for(
int i = 0; i < icnt; ++i)
1144 A(i,i) += A(i,i)*rattleParam[i].
rmb/rattleParam[i].
rma;
1150 lambda = A.partialPivLu().solve(sigma);
1151 for(
int i = 0; i < icnt; ++i)
1153 int a = rattleParam[i].
ia;
1154 int b = rattleParam[i].
ib;
1155 BigReal rma = rattleParam[i].
rma * lambda(i);
1156 BigReal rmb = rattleParam[i].
rmb * lambda(i);
1158 posx[a] -= rma * rabx[i];
1159 posy[a] -= rma * raby[i];
1160 posz[a] -= rma * rabz[i];
1161 posx[b] += rmb * rabx[i];
1162 posy[b] += rmb * raby[i];
1163 posz[b] += rmb * rabz[i];
1169 for(
int i = 0; i < icnt; ++i)
1171 int a = rattleParam[i].
ia;
1172 int b = rattleParam[i].
ib;
1173 pabx[i] = posx[a] - posx[b];
1174 paby[i] = posy[a] - posy[b];
1175 pabz[i] = posz[a] - posz[b];
1176 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
1178 BigReal diffsq = pabsq - rabsq;
1180 if ( fabs(diffsq) > (rabsq * tol2) )
1204 const BigReal tol2,
const int maxiter,
1205 bool& done,
bool& consFailure)
1207 using namespace Eigen;
1209 typedef VectorXf VectorXr;
1210 typedef MatrixXf MatrixXr;
1212 typedef VectorXd VectorXr;
1213 typedef MatrixXd MatrixXr;
1224 consFailure =
false;
1227 for(
int i = 0; i < icnt; ++i)
1229 int a = rattleParam[i].
ia;
1230 int b = rattleParam[i].
ib;
1231 pabx[i] = posx[a] - posx[b];
1232 paby[i] = posy[a] - posy[b];
1233 pabz[i] = posz[a] - posz[b];
1234 rabx[i] = refx[a] - refx[b];
1235 raby[i] = refy[a] - refy[b];
1236 rabz[i] = refz[a] - refz[b];
1238 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
1242 drab[i] = 1./sqrt(rabx[i]*rabx[i]+raby[i]*raby[i]+rabz[i]*rabz[i]);
1243 BigReal diffsq = pabsq - rabsq;
1244 if ( fabs(diffsq) > (rabsq * tol2) )
1249 MatrixXr S(icnt, icnt);
1251 for(
int i = 0; i < icnt*icnt; ++i)
1253 int idy = (int)(i / icnt);
1254 int idx = i - idy * icnt;
1255 S(idy,idx) = (rabx[idx]*rabx[idy]+raby[idx]*raby[idy]+rabz[idx]*rabz[idy])*rattleParam[idx].rma
1256 *drab[idx]*drab[idy];
1258 VectorXr r_unc(icnt);
1259 for(
int i = 0; i < icnt; ++i)
1261 S(i,i) += rattleParam[i].
rmb/rattleParam[i].
rma*S(i,i);
1262 r_unc(i) = (pabx[i]*rabx[i]+paby[i]*raby[i]+pabz[i]*rabz[i])*drab[i] -sqrt(rattleParam[i].dsq);
1264 LLT<MatrixXr> lltOfS(S);
1265 VectorXr lambda = lltOfS.solve(r_unc);
1267 for(
int i = 0; i < icnt; ++i)
1269 int a = rattleParam[i].
ia;
1270 int b = rattleParam[i].
ib;
1274 posx[a] = posx[a] - rabx[i]*rma;
1275 posy[a] = posy[a] - raby[i]*rma;
1276 posz[a] = posz[a] - rabz[i]*rma;
1277 posx[b] = posx[b] + rabx[i]*rmb;
1278 posy[b] = posy[b] + raby[i]*rmb;
1279 posz[b] = posz[b] + rabz[i]*rmb;
1281 for(iter = 1; iter < maxiter; ++iter)
1284 for(
int i = 0; i < icnt; ++i)
1286 int a = rattleParam[i].
ia;
1287 int b = rattleParam[i].
ib;
1288 pabx[i] = posx[a] - posx[b];
1289 paby[i] = posy[a] - posy[b];
1290 pabz[i] = posz[a] - posz[b];
1291 BigReal pabsq = pabx[i]*pabx[i] + paby[i]*paby[i] + pabz[i]*pabz[i];
1293 BigReal diffsq = pabsq - rabsq;
1295 if ( fabs(diffsq) > (rabsq * tol2) )
1297 r_unc(i) = (pabx[i]*rabx[i]+paby[i]*raby[i]+pabz[i]*rabz[i])*drab[i] -sqrt(2.*rabsq-pabsq);
1302 lambda = lltOfS.solve(r_unc);
1303 for(
int i = 0; i < icnt; ++i)
1305 int a = rattleParam[i].
ia;
1306 int b = rattleParam[i].
ib;
1310 posx[a] = posx[a] - rabx[i]*rma;
1311 posy[a] = posy[a] - raby[i]*rma;
1312 posz[a] = posz[a] - rabz[i]*rma;
1313 posx[b] = posx[b] + rabx[i]*rmb;
1314 posy[b] = posy[b] + raby[i]*rmb;
1315 posz[b] = posz[b] + rabz[i]*rmb;
1362 const BigReal tol2,
const int maxiter,
1363 bool& done,
bool& consFailure) {
1365 for (
int iter = 0; iter < maxiter; ++iter ) {
1367 consFailure =
false;
1368 for (
int i = 0; i < icnt; ++i ) {
1369 int a = rattleParam[i].
ia;
1370 int b = rattleParam[i].
ib;
1371 BigReal pabx = posx[a] - posx[b];
1372 BigReal paby = posy[a] - posy[b];
1373 BigReal pabz = posz[a] - posz[b];
1374 BigReal pabsq = pabx*pabx + paby*paby + pabz*pabz;
1376 BigReal diffsq = rabsq - pabsq;
1377 if ( fabs(diffsq) > (rabsq * tol2) ) {
1378 BigReal rabx = refx[a] - refx[b];
1379 BigReal raby = refy[a] - refy[b];
1380 BigReal rabz = refz[a] - refz[b];
1381 BigReal rpab = rabx*pabx + raby*paby + rabz*pabz;
1382 if ( rpab < ( rabsq * 1.0e-6 ) ) {
1389 BigReal gab = diffsq / ( 2.0 * ( rma + rmb ) * rpab );
1393 posx[a] += rma * dpx;
1394 posy[a] += rma * dpy;
1395 posz[a] += rma * dpz;
1396 posx[b] -= rmb * dpx;
1397 posy[b] -= rmb * dpy;
1398 posz[b] -= rmb * dpz;
1423 Vector rAB = pos[1]-pos[0];
1424 Vector rBC = pos[2]-pos[1];
1425 Vector rCA = pos[0]-pos[2];
1435 BigReal vab = (vel[1]-vel[0])*AB;
1436 BigReal vbc = (vel[2]-vel[1])*BC;
1437 BigReal vca = (vel[0]-vel[2])*CA;
1441 BigReal d = (2*mab*mab + 2*ma*mb*cosA*cosB*cosC - 2*mb*mb*cosA*cosA
1442 - ma*mab*(cosB*cosB + cosC*cosC))*0.5/mb;
1444 BigReal tab = (vab*(2*mab - ma*cosC*cosC) +
1445 vbc*(mb*cosC*cosA - mab*cosB) +
1446 vca*(ma*cosB*cosC - 2*mb*cosA))*ma/d;
1448 BigReal tbc = (vbc*(mab*mab - mb*mb*cosA*cosA) +
1449 vca*ma*(mb*cosA*cosB - mab*cosC) +
1450 vab*ma*(mb*cosC*cosA - mab*cosB))/d;
1452 BigReal tca = (vca*(2*mab - ma*cosB*cosB) +
1453 vab*(ma*cosB*cosC - 2*mb*cosA) +
1454 vbc*(mb*cosA*cosB - mab*cosC))*ma/d;
1456 Vector ga = tab*AB - tca*CA;
1457 Vector gb = tbc*BC - tab*AB;
1458 Vector gc = tca*CA - tbc*BC;
1461 *virial += 0.5*
outer(tab, rAB)/dt;
1462 *virial += 0.5*
outer(tbc, rBC)/dt;
1463 *virial += 0.5*
outer(tca, rCA)/dt;
1466 vel[0] += (0.5/ma)*ga;
1467 vel[1] += (0.5/mb)*gb;
1468 vel[2] += (0.5/mb)*gc;
1476 settlev(pos, mO, mH, vel, dt, virial);
1488 const double * __restrict ref_x,
1489 const double * __restrict ref_y,
1490 const double * __restrict ref_z,
1491 double * __restrict pos_x,
1492 double * __restrict pos_y,
1493 double * __restrict pos_z,
1502 for (
int i=0; i < numWaters; i++) {
1533 BigReal d0x = pos0x*mOrmT + ((pos1x + pos2x)*mHrmT);
1534 BigReal d0y = pos0y*mOrmT + ((pos1y + pos2y)*mHrmT);
1535 BigReal d0z = pos0z*mOrmT + ((pos1z + pos2z)*mHrmT);
1552 BigReal n0x = b0y*c0z-c0y*b0z;
1553 BigReal n0y = c0x*b0z-b0x*c0z;
1554 BigReal n0z = b0x*c0y-c0x*b0y;
1557 BigReal n1x = a1y*n0z-n0y*a1z;
1558 BigReal n1y = n0x*a1z-a1x*n0z;
1559 BigReal n1z = a1x*n0y-n0x*a1y;
1562 BigReal n2x = n0y*n1z-n1y*n0z;
1563 BigReal n2y = n1x*n0z-n0x*n1z;
1564 BigReal n2z = n0x*n1y-n1x*n0y;
1567 BigReal n0inv = 1.0/sqrt(n0x*n0x + n0y*n0y + n0z*n0z);
1572 BigReal n1inv = 1.0/sqrt(n1x*n1x + n1y*n1y + n1z*n1z);
1577 BigReal n2inv = 1.0/sqrt(n2x*n2x + n2y*n2y + n2z*n2z);
1583 BigReal n1b0 = n1x*b0x + n1y*b0y + n1z*b0z;
1584 BigReal n2b0 = n2x*b0x + n2y*b0y + n2z*b0z;
1587 BigReal n1c0 = n1x*c0x + n1y*c0y + n1z*c0z;
1588 BigReal n2c0 = n2x*c0x + n2y*c0y + n2z*c0z;
1590 BigReal A1Z = n0x*a1x + n0y*a1y + n0z*a1z;
1593 BigReal n1b1 = n1x*b1x + n1y*b1y + n1z*b1z;
1594 BigReal n2b1 = n2x*b1x + n2y*b1y + n2z*b1z;
1595 BigReal n0b1 = n0x*b1x + n0y*b1y + n0z*b1z;
1598 BigReal n1c1 = n1x*c1x + n1y*c1y + n1z*c1z;
1599 BigReal n2c1 = n2x*c1x + n2y*c1y + n2z*c1z;
1600 BigReal n0c1 = n0x*c1x + n0y*c1y + n0z*c1z;
1604 BigReal tmp = 1.0-sinphi*sinphi;
1606 BigReal sinpsi = (n0b1 - n0c1)/(2.0*rc*cosphi);
1607 tmp = 1.0-sinpsi*sinpsi;
1611 BigReal tmp1 = rc*sinpsi*sinphi;
1612 BigReal tmp2 = rc*sinpsi*cosphi;
1626 BigReal alpha = b2x*(n1b0 - n1c0) + n2b0*b2y + n2c0*c2y;
1627 BigReal beta = b2x*(n2c0 - n2b0) + n1b0*b2y + n1c0*c2y;
1628 BigReal gama = n1b0*n2b1 - n1b1*n2b0 + n1c0*n2c1 - n1c1*n2c0;
1630 BigReal a2b2 = alpha*alpha + beta*beta;
1631 BigReal sintheta = (alpha*gama - beta*sqrt(a2b2 - gama*gama))/a2b2;
1632 BigReal costheta = sqrt(1.0 - sintheta*sintheta);
1644 BigReal b3x = b2x*costheta - b2y*sintheta;
1645 BigReal b3y = b2x*sintheta + b2y*costheta;
1651 BigReal c3x = -b2x*costheta - c2y*sintheta;
1652 BigReal c3y = -b2x*sintheta + c2y*costheta;
1672 pos0x = a3x*m1x + a3y*m1y + a3z*m1z + d0x;
1673 pos0y = a3x*m2x + a3y*m2y + a3z*m2z + d0y;
1674 pos0z = a3x*m0x + a3y*m0y + a3z*m0z + d0z;
1677 pos1x = b3x*m1x + b3y*m1y + b3z*m1z + d0x;
1678 pos1y = b3x*m2x + b3y*m2y + b3z*m2z + d0y;
1679 pos1z = b3x*m0x + b3y*m0y + b3z*m0z + d0z;
1682 pos2x = c3x*m1x + c3y*m1y + c3z*m1z + d0x;
1683 pos2y = c3x*m2x + c3y*m2y + c3z*m2z + d0y;
1684 pos2z = c3x*m0x + c3y*m0y + c3z*m0z + d0z;
1689 pos_x[3*i+1] = pos1x;
1690 pos_y[3*i+1] = pos1y;
1691 pos_z[3*i+1] = pos1z;
1692 pos_x[3*i+2] = pos2x;
1693 pos_y[3*i+2] = pos2y;
1694 pos_z[3*i+2] = pos2z;
template void settle1_SIMD< 1 >(const Vector *ref, Vector *pos, BigReal mOrmT, BigReal mHrmT, BigReal ra, BigReal rb, BigReal rc, BigReal rra)
static int settlev(const Vector *pos, BigReal ma, BigReal mb, Vector *vel, BigReal dt, Tensor *virial)
void rattlePair(const RattleParam *rattleParam, const BigReal *refx, const BigReal *refy, const BigReal *refz, BigReal *posx, BigReal *posy, BigReal *posz, bool &consFailure)
void settle1_SOA(const double *__restrict ref_x, const double *__restrict ref_y, const double *__restrict ref_z, double *__restrict pos_x, double *__restrict pos_y, double *__restrict pos_z, int numWaters, BigReal mOrmT, BigReal mHrmT, BigReal ra, BigReal rb, BigReal rc, BigReal rra)
NAMD_HOST_DEVICE Tensor outer(const Vector &v1, const Vector &v2)
void MSHAKEIterate(const int icnt, const RattleParam *rattleParam, const BigReal *refx, const BigReal *refy, const BigReal *refz, BigReal *posx, BigReal *posy, BigReal *posz, const BigReal tol2, const int maxiter, bool &done, bool &consFailure)
template void settle1_SIMD< 2 >(const Vector *ref, Vector *pos, BigReal mOrmT, BigReal mHrmT, BigReal ra, BigReal rb, BigReal rc, BigReal rra)
int settle2(BigReal mO, BigReal mH, const Vector *pos, Vector *vel, BigReal dt, Tensor *virial)
static void swap_row(BigReal A[4][4], BigReal b[4], int r1, int r2)
void settle1init(BigReal pmO, BigReal pmH, BigReal hhdist, BigReal ohdist, BigReal &mO, BigReal &mH, BigReal &mOrmT, BigReal &mHrmT, BigReal &ra, BigReal &rb, BigReal &rc, BigReal &rra)
initialize cached water properties
static void solve_4by4(BigReal lambda [4], BigReal A[4][4], BigReal sigma[4])
void LINCS(const int icnt, const RattleParam *rattleParam, const BigReal *refx, const BigReal *refy, const BigReal *refz, BigReal *posx, BigReal *posy, BigReal *posz, const BigReal tol2, const int maxiter, bool &done, bool &consFailure)
template void rattlePair< 1 >(const RattleParam *rattleParam, const BigReal *refx, const BigReal *refy, const BigReal *refz, BigReal *posx, BigReal *posy, BigReal *posz, bool &consFailure)
static BigReal det_3by3(BigReal A[4][4])
int settle1(const Vector *ref, Vector *pos, Vector *vel, BigReal invdt, BigReal mOrmT, BigReal mHrmT, BigReal ra, BigReal rb, BigReal rc, BigReal rra)
optimized settle1 algorithm, reuses water properties as much as possible
void settle1_SIMD(const Vector *ref, Vector *pos, BigReal mOrmT, BigReal mHrmT, BigReal ra, BigReal rb, BigReal rc, BigReal rra)
static void solveMatrix(BigReal lambda [4], BigReal A[4][4], BigReal sigma[4], int icnt)
void rattleN(const int icnt, const RattleParam *rattleParam, const BigReal *refx, const BigReal *refy, const BigReal *refz, BigReal *posx, BigReal *posy, BigReal *posz, const BigReal tol2, const int maxiter, bool &done, bool &consFailure)
NAMD_HOST_DEVICE Vector unit(void) const
static void solveFullInverse(BigReal A[4][4], BigReal S[4][4], int icnt)