27 #define INDEX(ncols,i,j) ((i)*ncols + (j)) 40 #ifdef MEM_OPT_VERSION 41 NAMD_die(
"Should not be called in CrosstermElem::getMoleculePointers in memory optimized version!");
44 *byatom = mol->crosstermsByAtom;
45 *structarray = mol->crossterms;
50 *v =
p->crossterm_array;
69 for (
int ituple=0; ituple<ntuple; ++ituple ) {
87 double cos_phi,cos_psi;
88 double sin_phi,sin_psi;
95 Force f1(0,0,0),f2(0,0,0),f3(0,0,0);
96 Force f4(0,0,0),f5(0,0,0),f6(0,0,0);
133 cos_phi = A*B/(rA*rB);
134 sin_phi = C*B/(rC*rB);
135 cos_psi = D*E/(rD*rE);
136 sin_psi = F*E/(rF*rE);
144 phi= -atan2(sin_phi,cos_phi);
145 psi= -atan2(sin_psi,cos_psi);
147 if (fabs(sin_phi) > 0.1) {
151 dcosdA = rA*(cos_phi*A-B);
152 dcosdB = rB*(cos_phi*B-A);
157 dsindC = rC*(sin_phi*C-B);
158 dsindB = rB*(sin_phi*B-C);
161 if (fabs(sin_psi) > 0.1) {
165 dcosdD = rD*(cos_psi*D-E);
166 dcosdE = rE*(cos_psi*E-D);
171 dsindF = rF*(sin_psi*F-E);
172 dsindE = rE*(sin_psi*E-F);
178 const double h_1 = 1.0 / h;
180 const double six_h = 6.0 * h_1;
186 double xa[2], xb[2], dxa[2], dxb[2];
187 double ya[2], yb[2], dya[2], dyb[2];
188 double t, dx_h, dy_h;
190 double s1, s2, s3, s4, s5;
192 double f = 0, fx = 0, fy = 0;
194 int i, j, ilo, jlo, ij;
197 dx_h = (phi - phi_0) * h_1;
198 dy_h = (psi - psi_0) * h_1;
201 ilo = (int) floor(dx_h);
202 if ( ilo < 0 ) ilo = 0;
204 jlo = (int) floor(dy_h);
205 if ( jlo < 0 ) jlo = 0;
211 t = dx_h - (double) ilo;
212 xa[0] = (1 - t) * (1 - t) * (1 + 2*t);
213 xb[0] = h * t * (1 - t) * (1 - t);
214 dxa[0] = -6 * t * (1 - t) * h_1;
215 dxb[0] = (1 - t) * (1 - 3*t);
217 xa[1] = (1 + t) * (1 + t) * (1 - 2*t);
218 xb[1] = h * t * (1 + t) * (1 + t);
219 dxa[1] = -6 * t * (1 + t) * h_1;
220 dxb[1] = (1 + t) * (1 + 3*t);
223 t = dy_h - (double) jlo;
224 ya[0] = (1 - t) * (1 - t) * (1 + 2*t);
225 yb[0] = h * t * (1 - t) * (1 - t);
226 dya[0] = -6 * t * (1 - t) * h_1;
227 dyb[0] = (1 - t) * (1 - 3*t);
229 ya[1] = (1 + t) * (1 + t) * (1 - 2*t);
230 yb[1] = h * t * (1 + t) * (1 + t);
231 dya[1] = -6 * t * (1 + t) * h_1;
232 dyb[1] = (1 + t) * (1 + 3*t);
237 t = dx_h - (double) ilo;
243 xa[0] = s1*s1*(1+s2);
253 t = dy_h - (double) jlo;
259 ya[0] = s1*s1*(1+s2);
270 for (i = 0; i < 2; i++) {
271 for (j = 0; j < 2; j++) {
272 ij =
INDEX(D,i+ilo,j+jlo);
276 f += xa[i] * ya[j] * table[ij].
d00 277 + xb[i] * ya[j] * table[ij].
d10 278 + xa[i] * yb[j] * table[ij].
d01 279 + xb[i] * yb[j] * table[ij].
d11;
281 fx += dxa[i] * ya[j] * table[ij].
d00 282 + dxb[i] * ya[j] * table[ij].
d10 283 + dxa[i] * yb[j] * table[ij].
d01 284 + dxb[i] * yb[j] * table[ij].
d11;
286 fy += xa[i] * dya[j] * table[ij].
d00 287 + xb[i] * dya[j] * table[ij].
d10 288 + xa[i] * dyb[j] * table[ij].
d01 289 + xb[i] * dyb[j] * table[ij].
d11;
293 s1=ya[j]*table[ij].
d00;
294 s2=yb[j]*table[ij].
d01;
295 s3=ya[j]*table[ij].
d10;
296 s4=yb[j]*table[ij].
d11;
298 f+=xa[i]*(s1+s2)+xb[i]*(s3+s4);
299 fx+=dxa[i]*(s1+s2)+dxb[i]*(s3+s4);
300 fy+=xa[i]*(dya[j]*table[ij].
d00+dyb[j]*table[ij].
d01)
301 +xb[i]*(dya[j]*table[ij].d10+dyb[j]*table[ij].d11);
331 if (fabs(sin_phi) > 0.1)
334 U_phi = U_phi/sin_phi;
336 f1.x += U_phi*(r23.
y*dcosdA.
z - r23.
z*dcosdA.
y);
337 f1.y += U_phi*(r23.
z*dcosdA.
x - r23.
x*dcosdA.
z);
338 f1.z += U_phi*(r23.
x*dcosdA.
y - r23.
y*dcosdA.
x);
340 f3.
x += U_phi*(r23.
z*dcosdB.
y - r23.
y*dcosdB.
z);
341 f3.
y += U_phi*(r23.
x*dcosdB.
z - r23.
z*dcosdB.
x);
342 f3.
z += U_phi*(r23.
y*dcosdB.
x - r23.
x*dcosdB.
y);
344 f2.x += U_phi*(r12.
z*dcosdA.
y - r12.
y*dcosdA.
z 345 + r34.
y*dcosdB.
z - r34.
z*dcosdB.
y);
346 f2.y += U_phi*(r12.
x*dcosdA.
z - r12.
z*dcosdA.
x 347 + r34.
z*dcosdB.
x - r34.
x*dcosdB.
z);
348 f2.z += U_phi*(r12.
y*dcosdA.
x - r12.
x*dcosdA.
y 349 + r34.
x*dcosdB.
y - r34.
y*dcosdB.
x);
355 U_phi = -U_phi/cos_phi;
357 f1.x += U_phi*((r23.
y*r23.
y + r23.
z*r23.
z)*dsindC.
x 358 - r23.
x*r23.
y*dsindC.
y 359 - r23.
x*r23.
z*dsindC.
z);
360 f1.y += U_phi*((r23.
z*r23.
z + r23.
x*r23.
x)*dsindC.
y 361 - r23.
y*r23.
z*dsindC.
z 362 - r23.
y*r23.
x*dsindC.
x);
363 f1.z += U_phi*((r23.
x*r23.
x + r23.
y*r23.
y)*dsindC.
z 364 - r23.
z*r23.
x*dsindC.
x 365 - r23.
z*r23.
y*dsindC.
y);
367 f3 += cross(U_phi,dsindB,r23);
369 f2.x += U_phi*(-(r23.
y*r12.
y + r23.
z*r12.
z)*dsindC.
x 370 +(2.0*r23.
x*r12.
y - r12.
x*r23.
y)*dsindC.
y 371 +(2.0*r23.
x*r12.
z - r12.
x*r23.
z)*dsindC.
z 372 +dsindB.
z*r34.
y - dsindB.
y*r34.
z);
373 f2.y += U_phi*(-(r23.
z*r12.
z + r23.
x*r12.
x)*dsindC.
y 374 +(2.0*r23.
y*r12.
z - r12.
y*r23.
z)*dsindC.
z 375 +(2.0*r23.
y*r12.
x - r12.
y*r23.
x)*dsindC.
x 376 +dsindB.
x*r34.
z - dsindB.
z*r34.
x);
377 f2.z += U_phi*(-(r23.
x*r12.
x + r23.
y*r12.
y)*dsindC.
z 378 +(2.0*r23.
z*r12.
x - r12.
z*r23.
x)*dsindC.
x 379 +(2.0*r23.
z*r12.
y - r12.
z*r23.
y)*dsindC.
y 380 +dsindB.
y*r34.
x - dsindB.
x*r34.
y);
383 if (fabs(sin_psi) > 0.1)
386 U_psi = U_psi/sin_psi;
388 f4.x += U_psi*(r67.
y*dcosdD.
z - r67.
z*dcosdD.
y);
389 f4.y += U_psi*(r67.
z*dcosdD.
x - r67.
x*dcosdD.
z);
390 f4.z += U_psi*(r67.
x*dcosdD.
y - r67.
y*dcosdD.
x);
392 f6.
x += U_psi*(r67.
z*dcosdE.
y - r67.
y*dcosdE.
z);
393 f6.
y += U_psi*(r67.
x*dcosdE.
z - r67.
z*dcosdE.
x);
394 f6.
z += U_psi*(r67.
y*dcosdE.
x - r67.
x*dcosdE.
y);
396 f5.x += U_psi*(r56.
z*dcosdD.
y - r56.
y*dcosdD.
z 397 + r78.
y*dcosdE.
z - r78.
z*dcosdE.
y);
398 f5.y += U_psi*(r56.
x*dcosdD.
z - r56.
z*dcosdD.
x 399 + r78.
z*dcosdE.
x - r78.
x*dcosdE.
z);
400 f5.z += U_psi*(r56.
y*dcosdD.
x - r56.
x*dcosdD.
y 401 + r78.
x*dcosdE.
y - r78.
y*dcosdE.
x);
407 U_psi = -U_psi/cos_psi;
409 f4.x += U_psi*((r67.
y*r67.
y + r67.
z*r67.
z)*dsindF.
x 410 - r67.
x*r67.
y*dsindF.
y 411 - r67.
x*r67.
z*dsindF.
z);
412 f4.y += U_psi*((r67.
z*r67.
z + r67.
x*r67.
x)*dsindF.
y 413 - r67.
y*r67.
z*dsindF.
z 414 - r67.
y*r67.
x*dsindF.
x);
415 f4.z += U_psi*((r67.
x*r67.
x + r67.
y*r67.
y)*dsindF.
z 416 - r67.
z*r67.
x*dsindF.
x 417 - r67.
z*r67.
y*dsindF.
y);
419 f6 += cross(U_psi,dsindE,r67);
421 f5.x += U_psi*(-(r67.
y*r56.
y + r67.
z*r56.
z)*dsindF.
x 422 +(2.0*r67.
x*r56.
y - r56.
x*r67.
y)*dsindF.
y 423 +(2.0*r67.
x*r56.
z - r56.
x*r67.
z)*dsindF.
z 424 +dsindE.
z*r78.
y - dsindE.
y*r78.
z);
425 f5.y += U_psi*(-(r67.
z*r56.
z + r67.
x*r56.
x)*dsindF.
y 426 +(2.0*r67.
y*r56.
z - r56.
y*r67.
z)*dsindF.
z 427 +(2.0*r67.
y*r56.
x - r56.
y*r67.
x)*dsindF.
x 428 +dsindE.
x*r78.
z - dsindE.
z*r78.
x);
429 f5.z += U_psi*(-(r67.
x*r56.
x + r67.
y*r56.
y)*dsindF.
z 430 +(2.0*r67.
z*r56.
x - r56.
z*r67.
x)*dsindF.
x 431 +(2.0*r67.
z*r56.
y - r56.
z*r67.
y)*dsindF.
y 432 +dsindE.
y*r78.
x - dsindE.
x*r78.
y);
438 int typeSum1, typeSum2;
439 typeSum1 = typeSum2 = 0;
440 for (
int i=0; i < 4; ++i ) {
442 mol->get_fep_type(
atomID[i]));
444 mol->get_fep_type(
atomID[i+4]));
447 if ( (0 < typeSum1 && typeSum1 <
order) ||
448 (0 < typeSum2 && typeSum2 <
order) ) {
451 energy *= bond_lambda_1;
458 }
else if ( (0 > typeSum1 && typeSum1 > -
order) ||
459 (0 > typeSum2 && typeSum2 > -
order) ) {
462 energy *= bond_lambda_2;
494 DebugM(3,
"::computeForce() -- ending with delta energy " << energy << std::endl);
496 reduction[virialIndex_XX] += ( f1.x * r12.
x + f2.x * r23.
x + f3.
x * r34.
x );
497 reduction[virialIndex_XY] += ( f1.x * r12.
y + f2.x * r23.
y + f3.
x * r34.
y );
498 reduction[virialIndex_XZ] += ( f1.x * r12.
z + f2.x * r23.
z + f3.
x * r34.
z );
499 reduction[virialIndex_YX] += ( f1.y * r12.
x + f2.y * r23.
x + f3.
y * r34.
x );
500 reduction[virialIndex_YY] += ( f1.y * r12.
y + f2.y * r23.
y + f3.
y * r34.
y );
501 reduction[virialIndex_YZ] += ( f1.y * r12.
z + f2.y * r23.
z + f3.
y * r34.
z );
502 reduction[virialIndex_ZX] += ( f1.z * r12.
x + f2.z * r23.
x + f3.
z * r34.
x );
503 reduction[virialIndex_ZY] += ( f1.z * r12.
y + f2.z * r23.
y + f3.
z * r34.
y );
504 reduction[virialIndex_ZZ] += ( f1.z * r12.
z + f2.z * r23.
z + f3.
z * r34.
z );
506 reduction[virialIndex_XX] += ( f4.x * r56.
x + f5.x * r67.
x + f6.
x * r78.
x );
507 reduction[virialIndex_XY] += ( f4.x * r56.
y + f5.x * r67.
y + f6.
x * r78.
y );
508 reduction[virialIndex_XZ] += ( f4.x * r56.
z + f5.x * r67.
z + f6.
x * r78.
z );
509 reduction[virialIndex_YX] += ( f4.y * r56.
x + f5.y * r67.
x + f6.
y * r78.
x );
510 reduction[virialIndex_YY] += ( f4.y * r56.
y + f5.y * r67.
y + f6.
y * r78.
y );
511 reduction[virialIndex_YZ] += ( f4.y * r56.
z + f5.y * r67.
z + f6.
y * r78.
z );
512 reduction[virialIndex_ZX] += ( f4.z * r56.
x + f5.z * r67.
x + f6.
z * r78.
x );
513 reduction[virialIndex_ZY] += ( f4.z * r56.
y + f5.z * r67.
y + f6.
z * r78.
y );
514 reduction[virialIndex_ZZ] += ( f4.z * r56.
z + f5.z * r67.
z + f6.
z * r78.
z );
516 if (pressureProfileData) {
551 f1.x * r12.
x, f1.y * r12.
y, f1.z * r12.
z,
552 pressureProfileData);
554 f2.x * r23.
x, f2.y * r23.
y, f2.z * r23.
z,
555 pressureProfileData);
557 f3.
x * r34.
x, f3.
y * r34.
y, f3.
z * r34.
z,
558 pressureProfileData);
560 f4.x * r56.
x, f4.y * r56.
y, f4.z * r56.
z,
561 pressureProfileData);
563 f5.x * r67.
x, f5.y * r67.
y, f5.z * r67.
z,
564 pressureProfileData);
566 f6.
x * r78.
x, f6.
y * r78.
y, f6.
z * r78.
z,
567 pressureProfileData);
579 ADD_TENSOR(reduction,REDUCTION_VIRIAL_NORMAL,data,virialIndex);
580 ADD_TENSOR(reduction,REDUCTION_VIRIAL_AMD_DIHE,data,virialIndex);
594 const double h_2 = h_1 * h_1;
595 const double tr_h = 3.0 * h_1;
598 int ijp1p1, ijm1m1, ijp1m1, ijm1p1;
599 int ijp2p2, ijm2m2, ijp2m2, ijm2p2;
602 double*
const m =
new double[N*N];
603 memset(m,0,N*N*
sizeof(
double));
607 for (i = 1; i < N; i++) {
608 m[
INDEX(N,i-1,i)] = 1;
609 m[
INDEX(N,i,i-1)] = 1;
613 m[
INDEX(N,0,N-1)] = 1;
614 m[
INDEX(N,N-1,0)] = 1;
620 double*
const v =
new double[N];
621 memset(v,0,N*
sizeof(
double));
624 for (i = 0; i < N; i++) {
628 for (j = 1; j < N; j++) {
636 for (j = 0; j < N; j++) {
641 for (j = 0; j <= N; j++) {
646 for (j = 0; j < N; j++) {
650 for (i = 1; i < N; i++) {
658 for (i = 0; i < N; i++) {
663 for (i = 0; i <= N; i++) {
676 for (i = 0; i < N; i++) {
680 for (j = 1; j < N; j++) {
688 for (j = 0; j < N; j++) {
693 for (j = 0; j <= N; j++) {
709 for (k = 0; k < n-1; k++) {
710 for (i = k+1; i < n; i++) {
712 for (j = k; j < n; j++) {
715 m[
INDEX(n,i,k)] = l_ik;
726 for (j = 0; j < n-1; j++) {
727 for (i = j+1; i < n; i++) {
728 b[i] -= m[
INDEX(n,i,j)] * b[j];
732 for (j = n-1; j >= 0; j--) {
733 b[j] /= m[
INDEX(n,j,j)];
734 for (i = j-1; i >= 0; i--) {
735 b[i] -= m[
INDEX(n,i,j)] * b[j];
const CrosstermValue * value
CrosstermData c[dim][dim]
#define ADD_TENSOR(R, RL, D, DL)
void pp_reduction(int nslabs, int n1, int n2, int atype1, int atype2, int numtypes, BigReal vxx, BigReal vyy, BigReal vzz, BigReal *reduction)
static void forward_back_sub(double *b, double *m, int n)
SimParameters * simParameters
#define INDEX(ncols, i, j)
static int pressureProfileSlabs
static void submitReductionData(BigReal *, SubmitReduction *)
static void lu_decomp_nopivot(double *m, int n)
Molecule stores the structural information for the system.
static int pressureProfileAtomTypes
static void getParameterPointers(Parameters *, const CrosstermValue **)
void pp_clamp(int &n, int nslabs)
NAMD_HOST_DEVICE BigReal length(void) const
static BigReal pressureProfileMin
void NAMD_die(const char *err_msg)
static void getMoleculePointers(Molecule *, int *, int32 ***, Crossterm **)
unsigned char get_fep_type(int anum) const
static void computeForce(CrosstermElem *, int, BigReal *, BigReal *)
void crossterm_setup(CrosstermData *table)
static BigReal pressureProfileThickness
NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const