77#if !defined(VINLINE_VPMG)
80 if (thee == VNULL)
return 0;
81 return Vmem_bytes(thee->
vmem);
88 char mxtype[3],
int flag) {
90 int nn, nxm2, nym2, nzm2, ncol, nrow, nonz;
110 nonz = 7*nn - 2*nxm2*nym2 - 2*nxm2 - 2;
111 nzval = (
double*)Vmem_malloc(thee->
vmem, nonz,
sizeof(
double));
112 rowind = (
int*)Vmem_malloc(thee->
vmem, nonz,
sizeof(
int));
113 colptr = (
int*)Vmem_malloc(thee->
vmem, (ncol+1),
sizeof(int));
116 Vnm_print(1,
"Vpmg_printColComp: Allocated space for %d nonzeros\n",
121 nzval, rowind, colptr, &flag);
125 for (i=0; i<nn; i++) {
126 Vnm_print(1,
"nnz(%d) = %g\n", i, nzval[i]);
132 pcolcomp(&nrow, &ncol, &nonz, &(nzval[0]), rowind, colptr, path, title,
135 Vmem_free(thee->
vmem, (ncol+1),
sizeof(
int), (
void **)&colptr);
136 Vmem_free(thee->
vmem, nonz,
sizeof(
int), (
void **)&rowind);
137 Vmem_free(thee->
vmem, nonz,
sizeof(
double), (
void **)&nzval);
146 thee = (
Vpmg*)Vmem_malloc(VNULL, 1,
sizeof(
Vpmg) );
147 VASSERT(thee != VNULL);
148 VASSERT(
Vpmg_ctor2(thee, pmgp, pbe, focusFlag, pmgOLD, mgparm,
158 double ionstr, partMin[3], partMax[3];
162 VASSERT(pmgp != VNULL);
163 VASSERT(pbe != VNULL);
168 thee->
vmem = Vmem_ctor(
"APBS:VPMG");
176 if (ionstr > 0.0) zks2 = 0.5/ionstr;
185 VABORT_MSG0(
"Aqua is currently disabled");
198 Vnm_print(2,
"Vpmg_ctor2: PMG chose nx = %d, ny = %d, nz = %d\n",
200 Vnm_print(2,
"Vpmg_ctor2: PMG chose nlev = %d\n",
202 Vnm_print(2,
"Vpmg_ctor2: PMG chose nxc = %d, nyc = %d, nzc = %d\n",
204 Vnm_print(2,
"Vpmg_ctor2: PMG chose nf = %d, nc = %d\n",
206 Vnm_print(2,
"Vpmg_ctor2: PMG chose narr = %d, narrc = %d\n",
208 Vnm_print(2,
"Vpmg_ctor2: PMG chose n_rpc = %d, n_iz = %d, n_ipc = %d\n",
210 Vnm_print(2,
"Vpmg_ctor2: PMG chose nrwk = %d, niwk = %d\n",
217 thee->
gxcf = (
double *)Vmem_malloc(
223 thee->
gycf = (
double *)Vmem_malloc(
229 thee->
gzcf = (
double *)Vmem_malloc(
240 Vnm_print(2,
"Vpmg_ctor2: \nWarning: External energies are not used in BCFL_MAP calculations!\n");
248 "Vpmg_ctor2: reset boundary condition flag to BCFL_FOCUS!\n");
253 Vnm_print(0,
"Vpmg_ctor2: Filling boundary with old solution!\n");
254 focusFillBound(thee, pmgOLD);
258 if (energyFlag !=
PCE_NO) {
262 for (j=0; j<3; j++) {
270 for (j=0; j<3; j++) {
271 partMin[j] = mgparm->
center[j] - 0.5*mgparm->
glen[j];
272 partMax[j] = mgparm->
center[j] + 0.5*mgparm->
glen[j];
275 extEnergy(thee, pmgOLD, energyFlag, partMin, partMax,
289 thee->
pvec = (
double *)Vmem_malloc(
296 thee->
iparm = (
int *)Vmem_malloc(thee->
vmem, 100,
sizeof(
int));
297 thee->
rparm = (
double *)Vmem_malloc(thee->
vmem, 100,
sizeof(
double));
299 thee->
rwork = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
nrwk,
sizeof(
double));
301 thee->
kappa = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
302 thee->
pot = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
303 thee->
epsx = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
304 thee->
epsy = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
305 thee->
epsz = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
306 thee->
a1cf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
307 thee->
a2cf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
308 thee->
a3cf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
309 thee->
ccf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
310 thee->
fcf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
311 thee->
tcf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
312 thee->
u = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
313 thee->
xf = (
double *)Vmem_malloc(thee->
vmem, 5*(thee->
pmgp->
nx),
sizeof(double));
314 thee->
yf = (
double *)Vmem_malloc(thee->
vmem, 5*(thee->
pmgp->
ny),
sizeof(double));
315 thee->
zf = (
double *)Vmem_malloc(thee->
vmem, 5*(thee->
pmgp->
nz),
sizeof(double));
352 for (i=0; i<nion; i++)
353 ionConc[i] = zks2 * ionConc[i];
363 for (i=0; i<nion; i++)
364 ionConc[i] = zks2 * ionConc[i];
372 Vnm_print(2,
"PMG: Warning: PBE structure not initialized!\n");
374 for (i=0; i<nion; i++)
375 ionConc[i] = zks2 * ionConc[i];
416 Vnm_print(2,
"Vpmg_solve: Need to call Vpmg_fillco()!\n");
421 for (i=0; i<n; i++) {
426 for (i=0; i<n; i++) {
431 for (i=0; i<n; i++) {
441 for (i=0; i<n; i++) {
442 thee->
ccf[i] = zkappa2*thee->
kappa[i];
445 for (i=0; i<n; i++) {
455 Vnm_print(2,
"Driving with CGMGDRIV\n");
457 VABORT_MSG0(
"CGMGDRIV is not currently supported");
464 Vnm_print(2,
"Driving with NEWDRIV\n");
477 Vnm_print(2,
"Driving with MGDRIV\n");
489 Vnm_print(2,
"Driving with NCGHSDRIV\n");
491 VABORT_MSG0(
"NCGHSDRIV is not currently supported");
498 Vnm_print(2,
"Driving with NSORDRIV\n");
500 VABORT_MSG0(
"NSORDRIV is not currently supported");
507 Vnm_print(2,
"Driving with NGSRBDRIV\n");
509 VABORT_MSG0(
"NGSRBDRIV is not currently supported");
516 Vnm_print(2,
"Driving with NWJACDRIV\n");
518 VABORT_MSG0(
"NWJACDRIV is not currently supported");
522 case VSOL_Richardson:
525 Vnm_print(2,
"Driving with NRICHDRIV\n");
527 VABORT_MSG0(
"NRICHDRIV is not currently supported");
534 Vnm_print(2,
"Driving with CGMGDRIVAQUA\n");
536 VABORT_MSG0(
"CGMGDRIVAQUA is not currently supported");
540 case VSOL_NewtonAqua:
543 Vnm_print(2,
"Driving with NEWDRIVAQUA\n");
545 VABORT_MSG0(
"NEWDRIVAQUA is not currently supported");
550 Vnm_print(2,
"Vpmg_solve: invalid solver method key (%d)\n",
563 if ((*thee) != VNULL) {
565 Vmem_free(VNULL, 1,
sizeof(
Vpmg), (
void **)thee);
575 Vmem_free(thee->
vmem, 100,
sizeof(
int),
576 (
void **)&(thee->
iparm));
577 Vmem_free(thee->
vmem, 100,
sizeof(
double),
578 (
void **)&(thee->
rparm));
580 (
void **)&(thee->
iwork));
582 (
void **)&(thee->
rwork));
584 (
void **)&(thee->
charge));
586 (
void **)&(thee->
kappa));
588 (
void **)&(thee->
pot));
590 (
void **)&(thee->
epsx));
592 (
void **)&(thee->
epsy));
594 (
void **)&(thee->
epsz));
596 (
void **)&(thee->
a1cf));
598 (
void **)&(thee->
a2cf));
600 (
void **)&(thee->
a3cf));
602 (
void **)&(thee->
ccf));
604 (
void **)&(thee->
fcf));
606 (
void **)&(thee->
tcf));
608 (
void **)&(thee->
u));
609 Vmem_free(thee->
vmem, 5*(thee->
pmgp->
nx),
sizeof(
double),
610 (
void **)&(thee->
xf));
611 Vmem_free(thee->
vmem, 5*(thee->
pmgp->
ny),
sizeof(
double),
612 (
void **)&(thee->
yf));
613 Vmem_free(thee->
vmem, 5*(thee->
pmgp->
nz),
sizeof(
double),
614 (
void **)&(thee->
zf));
616 (
void **)&(thee->
gxcf));
618 (
void **)&(thee->
gycf));
620 (
void **)&(thee->
gzcf));
622 sizeof(
double), (
void **)&(thee->
pvec));
624 Vmem_dtor(&(thee->
vmem));
628 double upperCorner[3],
int bflags[6]) {
632 int i, j, k, nx, ny, nz;
633 double xmin, ymin, zmin, x, y, z, hx, hy, hzed, xok, yok, zok;
634 double x0,x1,y0,y1,z0,z1;
642 xmin = thee->
pmgp->
xcent - 0.5*hx*(nx-1);
643 ymin = thee->
pmgp->
ycent - 0.5*hy*(ny-1);
644 zmin = thee->
pmgp->
zcent - 0.5*hzed*(nz-1);
654 Vnm_print(0,
"Vpmg_setPart: lower corner = (%g, %g, %g)\n",
655 lowerCorner[0], lowerCorner[1], lowerCorner[2]);
656 Vnm_print(0,
"Vpmg_setPart: upper corner = (%g, %g, %g)\n",
657 upperCorner[0], upperCorner[1], upperCorner[2]);
658 Vnm_print(0,
"Vpmg_setPart: actual minima = (%g, %g, %g)\n",
660 Vnm_print(0,
"Vpmg_setPart: actual maxima = (%g, %g, %g)\n",
661 xmin+hx*(nx-1), ymin+hy*(ny-1), zmin+hzed*(nz-1));
662 Vnm_print(0,
"Vpmg_setPart: bflag[FRONT] = %d\n",
664 Vnm_print(0,
"Vpmg_setPart: bflag[BACK] = %d\n",
666 Vnm_print(0,
"Vpmg_setPart: bflag[LEFT] = %d\n",
668 Vnm_print(0,
"Vpmg_setPart: bflag[RIGHT] = %d\n",
670 Vnm_print(0,
"Vpmg_setPart: bflag[UP] = %d\n",
672 Vnm_print(0,
"Vpmg_setPart: bflag[DOWN] = %d\n",
683 if ((atom->
position[0] < upperCorner[0]) &&
684 (atom->
position[0] > lowerCorner[0])) xok = 1;
696 if ((atom->
position[1] < upperCorner[1]) &&
697 (atom->
position[1] > lowerCorner[1])) yok = 1;
709 if ((atom->
position[2] < upperCorner[2]) &&
710 (atom->
position[2] > lowerCorner[2])) zok = 1;
723 atom->
partID = xok*yok*zok;
749 for (i=0; i<(nx*ny*nz); i++) thee->
pvec[i] = 0.0;
751 for (i=0; i<nx; i++) {
754 if ( (x < (upperCorner[0]-hx/2)) &&
755 (x > (lowerCorner[0]+hx/2))
757 else if ( (VABS(x - lowerCorner[0]) <
VPMGSMALL) &&
759 else if ((VABS(x - lowerCorner[0]) <
VPMGSMALL) &&
761 else if ((VABS(x - upperCorner[0]) <
VPMGSMALL) &&
763 else if ((VABS(x - upperCorner[0]) <
VPMGSMALL) &&
765 else if ((x > (upperCorner[0] + hx/2)) || (x < (lowerCorner[0] - hx/2))) xok = 0.0;
766 else if ((x < (upperCorner[0] + hx/2)) || (x > (lowerCorner[0] - hx/2))) {
767 x0 = VMAX2(x - hx/2, lowerCorner[0]);
768 x1 = VMIN2(x + hx/2, upperCorner[0]);
769 xok = VABS(x1-x0)/hx;
774 Vnm_print(2,
"Vpmg_setPart: fell off x-interval (%1.12E)!\n",
780 if (VABS(xok - 1.0) <
VPMGSMALL) xok = 1.0;
782 Vnm_print(2,
"Vpmg_setPart: fell off x-interval (%1.12E)!\n",
790 for (j=0; j<ny; j++) {
793 if ((y < (upperCorner[1]-hy/2)) && (y > (lowerCorner[1]+hy/2))) yok = 1.0;
794 else if ((VABS(y - lowerCorner[1]) <
VPMGSMALL) &&
796 else if ((VABS(y - lowerCorner[1]) <
VPMGSMALL) &&
798 else if ((VABS(y - upperCorner[1]) <
VPMGSMALL) &&
800 else if ((VABS(y - upperCorner[1]) <
VPMGSMALL) &&
802 else if ((y > (upperCorner[1] + hy/2)) || (y < (lowerCorner[1] - hy/2))) yok=0.0;
803 else if ((y < (upperCorner[1] + hy/2)) || (y > (lowerCorner[1] - hy/2))){
804 y0 = VMAX2(y - hy/2, lowerCorner[1]);
805 y1 = VMIN2(y + hy/2, upperCorner[1]);
806 yok = VABS(y1-y0)/hy;
811 Vnm_print(2,
"Vpmg_setPart: fell off y-interval (%1.12E)!\n",
817 if (VABS(yok - 1.0) <
VPMGSMALL) yok = 1.0;
819 Vnm_print(2,
"Vpmg_setPart: fell off y-interval (%1.12E)!\n",
827 for (k=0; k<nz; k++) {
830 if ((z < (upperCorner[2]-hzed/2)) && (z > (lowerCorner[2]+hzed/2))) zok = 1.0;
831 else if ((VABS(z - lowerCorner[2]) <
VPMGSMALL) &&
833 else if ((VABS(z - lowerCorner[2]) <
VPMGSMALL) &&
835 else if ((VABS(z - upperCorner[2]) <
VPMGSMALL) &&
837 else if ((VABS(z - upperCorner[2]) <
VPMGSMALL) &&
839 else if ((z > (upperCorner[2] + hzed/2)) || (z < (lowerCorner[2] - hzed/2))) zok=0.0;
840 else if ((z < (upperCorner[2] + hzed/2)) || (z > (lowerCorner[2] - hzed/2))){
841 z0 = VMAX2(z - hzed/2, lowerCorner[2]);
842 z1 = VMIN2(z + hzed/2, upperCorner[2]);
843 zok = VABS(z1-z0)/hzed;
848 Vnm_print(2,
"Vpmg_setPart: fell off z-interval (%1.12E)!\n",
854 if (VABS(zok - 1.0) <
VPMGSMALL) zok = 1.0;
856 Vnm_print(2,
"Vpmg_setPart: fell off z-interval (%1.12E)!\n",
864 if (VABS(xok*yok*zok) <
VPMGSMALL) thee->
pvec[IJK(i,j,k)] = 0.0;
865 else thee->
pvec[IJK(i,j,k)] = xok*yok*zok;
878 VASSERT(thee != VNULL);
885 for (i=0; i<(nx*ny*nz); i++) thee->
pvec[i] = 1;
898 Vatom *atoms = VNULL;
900 double position[3], hx, hy, hzed, xmin, ymin, zmin;
901 double grad[3], eps, epsp, epss, zmagic, u;
902 int i, j, k, l, nx, ny, nz, ichop;
920 Vnm_print(2,
"Vpmg_fillArray: need to call Vpmg_fillco first!\n");
928 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
charge[i]/zmagic;
933 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
epsx[i];
938 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
epsy[i];
943 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
epsz[i];
948 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
kappa[i];
953 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
u[i];
960 hzed, xmin, ymin, zmin,thee->
u);
973 for (k=0; k<nz; k++) {
974 for (j=0; j<ny; j++) {
975 for (i=0; i<nx; i++) {
977 position[0] = i*hx + xmin;
978 position[1] = j*hy + ymin;
979 position[2] = k*hzed + zmin;
981 vec[IJK(i,j,k)] = (
Vacc_molAcc(acc,position,parm));
989 for (k=0; k<nz; k++) {
990 for (j=0; j<ny; j++) {
991 for (i=0; i<nx; i++) {
993 position[0] = i*hx + xmin;
994 position[1] = j*hy + ymin;
995 position[2] = k*hzed + zmin;
1005 for (k=0; k<nz; k++) {
1006 for (j=0; j<ny; j++) {
1007 for (i=0; i<nx; i++) {
1009 position[0] = i*hx + xmin;
1010 position[1] = j*hy + ymin;
1011 position[2] = k*hzed + zmin;
1013 vec[IJK(i,j,k)] = Vacc_vdwAcc(acc,position);
1021 for (k=0; k<nz; k++) {
1022 for (j=0; j<ny; j++) {
1023 for (i=0; i<nx; i++) {
1025 position[0] = i*hx + xmin;
1026 position[1] = j*hy + ymin;
1027 position[2] = k*hzed + zmin;
1029 vec[IJK(i,j,k)] = Vacc_ivdwAcc(acc,position,parm);
1037 grid =
Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
1039 for (k=0; k<nz; k++) {
1040 for (j=0; j<ny; j++) {
1041 for (i=0; i<nx; i++) {
1043 if ((k==0) || (k==(nz-1)) ||
1044 (j==0) || (j==(ny-1)) ||
1045 (i==0) || (i==(nx-1))) {
1047 vec[IJK(i,j,k)] = 0;
1050 position[0] = i*hx + xmin;
1051 position[1] = j*hy + ymin;
1052 position[2] = k*hzed + zmin;
1054 &(vec[IJK(i,j,k)])));
1064 grid =
Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
1066 for (k=0; k<nz; k++) {
1067 for (j=0; j<ny; j++) {
1068 for (i=0; i<nx; i++) {
1070 position[0] = i*hx + xmin;
1071 position[1] = j*hy + ymin;
1072 position[2] = k*hzed + zmin;
1074 eps = epsp + (epss-epsp)*
Vacc_molAcc(acc, position,
1076 vec[IJK(i,j,k)] = 0.0;
1078 vec[IJK(i,j,k)] += eps*VSQR(grad[l]);
1087 for (k=0; k<nz; k++) {
1088 for (j=0; j<ny; j++) {
1089 for (i=0; i<nx; i++) {
1091 position[0] = i*hx + xmin;
1092 position[1] = j*hy + ymin;
1093 position[2] = k*hzed + zmin;
1094 vec[IJK(i,j,k)] = 0.0;
1095 u = thee->
u[IJK(i,j,k)];
1096 if ( VABS(Vacc_ivdwAcc(acc,
1098 for (l=0; l<pbe->
numIon; l++) {
1099 double q = pbe->
ionQ[l];
1103 vec[IJK(i,j,k)] += pbe->
ionConc[l]*(1 - q*u + 0.5*q*q*u*u);
1114 for (k=0; k<nz; k++) {
1115 for (j=0; j<ny; j++) {
1116 for (i=0; i<nx; i++) {
1117 position[0] = i*hx + xmin;
1118 position[1] = j*hy + ymin;
1119 position[2] = k*hzed + zmin;
1120 vec[IJK(i,j,k)] = 0.0;
1121 u = thee->
u[IJK(i,j,k)];
1122 if ( VABS(Vacc_ivdwAcc(acc,
1124 for (l=0; l<pbe->
numIon; l++) {
1125 double q = pbe->
ionQ[l];
1129 vec[IJK(i,j,k)] += pbe->
ionConc[l]*q*(1 - q*u + 0.5*q*q*u*u);
1138 Vnm_print(2,
"main: Bogus data type (%d)!\n", type);
1208 potgrid =
Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin, thee->
u);
1212 for (i=1; i<(nx-1); i++) {
1213 pt[0] = xmin + hx*i;
1214 for (j=1; j<(ny-1); j++) {
1215 pt[1] = ymin + hy*j;
1216 for (k=1; k<(nz-1); k++) {
1217 pt[2] = zmin + hzed*k;
1222 polq = charge[ijk] + epsp*lap*3.0;
1225 if (VABS(polq) > VSMALL) {
1230 dist2 = VSQR(pos[0]-pt[0]) + VSQR(pos[1]-pt[1]) \
1231 + VSQR(pos[2]-pt[2]);
1232 dist = VSQRT(dist2);
1234 if (dist < VSMALL) {
1235 Vnm_print(2,
"Vpmg_polarizEnergy: atom on grid point; ignoring!\n");
1237 energy = energy + polq*q/dist;
1252 double totEnergy = 0.0,
1257 VASSERT(thee != VNULL);
1260 Vnm_print(0,
"Vpmg_energy: calculating full PBE energy\n");
1262 Vnm_print(0,
"Vpmg_energy: qmEnergy = %1.12E kT\n", qmEnergy);
1264 Vnm_print(0,
"Vpmg_energy: qfEnergy = %1.12E kT\n", qfEnergy);
1266 Vnm_print(0,
"Vpmg_energy: dielEnergy = %1.12E kT\n", dielEnergy);
1267 totEnergy = qfEnergy - dielEnergy - qmEnergy;
1269 Vnm_print(0,
"Vpmg_energy: calculating only q-phi energy\n");
1271 Vnm_print(0,
"Vpmg_energy: qfEnergy = %1.12E kT\n", qfEnergy);
1272 totEnergy = 0.5*qfEnergy;
1300 VASSERT(thee != VNULL);
1313 Vnm_print(2,
"Vpmg_dielEnergy: Need to call Vpmg_fillco!\n");
1317 for (k=0; k<(nz-1); k++) {
1318 for (j=0; j<(ny-1); j++) {
1319 for (i=0; i<(nx-1); i++) {
1320 pvecx = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i+1,j,k)]);
1321 pvecy = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j+1,k)]);
1322 pvecz = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j,k+1)]);
1323 nrgx = thee->
epsx[IJK(i,j,k)]*pvecx
1324 * VSQR((thee->
u[IJK(i,j,k)]-thee->
u[IJK(i+1,j,k)])/hx);
1325 nrgy = thee->
epsy[IJK(i,j,k)]*pvecy
1326 * VSQR((thee->
u[IJK(i,j,k)]-thee->
u[IJK(i,j+1,k)])/hy);
1327 nrgz = thee->
epsz[IJK(i,j,k)]*pvecz
1328 * VSQR((thee->
u[IJK(i,j,k)]-thee->
u[IJK(i,j,k+1)])/hzed);
1329 energy += (nrgx + nrgy + nrgz);
1334 energy = 0.5*energy*hx*hy*hzed;
1344 double hx, hy, hzed, energy, nrgx, nrgy, nrgz, pvecx, pvecy, pvecz;
1345 int i, j, k, nx, ny, nz;
1347 VASSERT(thee != VNULL);
1360 Vnm_print(2,
"Vpmg_dielGradNorm: Need to call Vpmg_fillco!\n");
1364 for (k=1; k<nz; k++) {
1365 for (j=1; j<ny; j++) {
1366 for (i=1; i<nx; i++) {
1367 pvecx = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i-1,j,k)]);
1368 pvecy = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j-1,k)]);
1369 pvecz = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j,k-1)]);
1371 * VSQR((thee->
epsx[IJK(i,j,k)]-thee->
epsx[IJK(i-1,j,k)])/hx);
1373 * VSQR((thee->
epsy[IJK(i,j,k)]-thee->
epsy[IJK(i,j-1,k)])/hy);
1375 * VSQR((thee->
epsz[IJK(i,j,k)]-thee->
epsz[IJK(i,j,k-1)])/hzed);
1376 energy += VSQRT(nrgx + nrgy + nrgz);
1381 energy = energy*hx*hy*hzed;
1395 energy = Vpmg_qmEnergyNONLIN(thee,extFlag);
1401VPRIVATE
double Vpmg_qmEnergyNONLIN(
Vpmg *thee,
1425 VASSERT(thee != VNULL);
1438 if (zkappa2 < VSMALL) {
1441 Vnm_print(0,
"Vpmg_qmEnergy: Zero energy for zero ionic strength!\n");
1446 zks2 = 0.5*zkappa2/ionstr;
1449 Vnm_print(2,
"Vpmg_qmEnergy: Need to call Vpmg_fillco()!\n");
1457 Vnm_print(0,
"Vpmg_qmEnergy: Calculating nonlinear energy\n");
1458 for (i=0, len=nx*ny*nz; i<len; i++) {
1459 if (thee->
pvec[i]*thee->
kappa[i] > VSMALL) {
1460 for (j=0; j<nion; j++) {
1461 energy += (thee->
pvec[i]*thee->
kappa[i]*zks2
1463 * (
Vcap_exp(-ionQ[j]*thee->
u[i], &ichop)-1.0));
1469 Vnm_print(2,
"Vpmg_qmEnergy: Chopped EXP %d times!\n",nchop);
1470 Vnm_print(2,
"\nERROR! Detected large potential values in energy evaluation! \nERROR! This calculation failed -- please report to the APBS developers!\n\n");
1475 Vnm_print(0,
"Vpmg_qmEnergy: Calculating linear energy\n");
1476 for (i=0, len=nx*ny*nz; i<len; i++) {
1477 if (thee->
pvec[i]*thee->
kappa[i] > VSMALL)
1478 energy += (thee->
pvec[i]*zkappa2*thee->
kappa[i]*VSQR(thee->
u[i]));
1480 energy = 0.5*energy;
1482 energy = energy*hx*hy*hzed;
1542 VASSERT(thee != VNULL);
1555 if (zkappa2 < VSMALL) {
1558 Vnm_print(0,
"Vpmg_qmEnergySMPBE: Zero energy for zero ionic strength!\n");
1563 zks2 = 0.5*zkappa2/ionstr;
1566 Vnm_print(2,
"Vpmg_qmEnergySMPBE: Need to call Vpmg_fillco()!\n");
1596 fracOccA = Na*cb1*VCUB(a);
1597 fracOccB = Na*cb2*VCUB(a);
1598 fracOccC = Na*cb3*VCUB(a);
1600 phi = (fracOccA/k) + fracOccB + fracOccC;
1603 Vnm_print(0,
"Vpmg_qmEnergySMPBE: Calculating nonlinear energy using SMPB functional!\n");
1604 for (i=0, len=nx*ny*nz; i<len; i++) {
1605 if (((k-1) > VSMALL) && (thee->
pvec[i]*thee->
kappa[i] > VSMALL)) {
1607 a1 =
Vcap_exp(-1.0*z1*thee->
u[i], &ichop1);
1608 a2 =
Vcap_exp(-1.0*z2*thee->
u[i], &ichop2);
1609 a3 =
Vcap_exp(-1.0*z3*thee->
u[i], &ichop3);
1611 nchop += ichop1 + ichop2 + ichop3;
1613 gpark = (1 - phi + (fracOccA/k)*a1);
1614 denom = VPOW(gpark, k) + VPOW(1-fracOccB-fracOccC, k-1)*(fracOccB*a2+fracOccC*a3);
1617 c1 = Na*cb1*VPOW(gpark, k-1)*a1/denom;
1618 if(c1 != c1) c1 = 0.;
1622 c2 = Na*cb2*VPOW(1-fracOccB-fracOccC,k-1)*a2/denom;
1623 if(c2 != c2) c2 = 0.;
1627 c3 = Na*cb3*VPOW(1-fracOccB-fracOccC,k-1)*a3/denom;
1628 if(c3 != c3) c3 = 0.;
1631 currEnergy = k*VLOG((1-(c1*VCUB(a)/k)-c2*VCUB(a)-c3*VCUB(a))/(1-phi))
1632 -(k-1)*VLOG((1-c2*VCUB(a)-c3*VCUB(a))/(1-phi+(fracOccA/k)));
1634 energy += thee->
pvec[i]*thee->
kappa[i]*currEnergy;
1636 }
else if (thee->
pvec[i]*thee->
kappa[i] > VSMALL){
1638 a1 =
Vcap_exp(-1.0*z1*thee->
u[i], &ichop1);
1639 a2 =
Vcap_exp(-1.0*z2*thee->
u[i], &ichop2);
1640 a3 =
Vcap_exp(-1.0*z3*thee->
u[i], &ichop3);
1642 nchop += ichop1 + ichop2 + ichop3;
1644 gpark = (1 - phi + (fracOccA)*a1);
1645 denom = gpark + (fracOccB*a2+fracOccC*a3);
1648 c1 = Na*cb1*a1/denom;
1649 if(c1 != c1) c1 = 0.;
1653 c2 = Na*cb2*a2/denom;
1654 if(c2 != c2) c2 = 0.;
1658 c3 = Na*cb3*a3/denom;
1659 if(c3 != c3) c3 = 0.;
1662 currEnergy = VLOG((1-c1*VCUB(a)-c2*VCUB(a)-c3*VCUB(a))/(1-fracOccA-fracOccB-fracOccC));
1664 energy += thee->
pvec[i]*thee->
kappa[i]*currEnergy;
1668 energy = -energy/VCUB(a);
1670 if (nchop > 0) Vnm_print(2,
"Vpmg_qmEnergySMPBE: Chopped EXP %d times!\n",
1675 Vnm_print(0,
"Vpmg_qmEnergySMPBE: ERROR: NO LINEAR ENERGY!! Returning 0!\n");
1680 energy = energy*hx*hy*hzed;
1691 double energy = 0.0;
1693 VASSERT(thee != VNULL);
1708 int iatom, nx, ny, nz, ihi, ilo, jhi, jlo, khi, klo;
1709 double xmax, ymax, zmax, xmin, ymin, zmin, hx, hy, hzed, ifloat, jfloat;
1710 double charge, kfloat, dx, dy, dz, energy, uval, *position;
1719 VASSERT(alist != VNULL);
1749 ifloat = (position[0] - xmin)/hx;
1750 jfloat = (position[1] - ymin)/hy;
1751 kfloat = (position[2] - zmin)/hzed;
1752 ihi = (int)ceil(ifloat);
1753 ilo = (int)floor(ifloat);
1754 jhi = (int)ceil(jfloat);
1755 jlo = (int)floor(jfloat);
1756 khi = (int)ceil(kfloat);
1757 klo = (int)floor(kfloat);
1761 if ((ihi<nx) && (jhi<ny) && (khi<nz) &&
1762 (ilo>=0) && (jlo>=0) && (klo>=0)) {
1765 dx = ifloat - (double)(ilo);
1766 dy = jfloat - (double)(jlo);
1767 dz = kfloat - (double)(klo);
1769 dx*dy*dz*u[IJK(ihi,jhi,khi)]
1770 + dx*(1.0-dy)*dz*u[IJK(ihi,jlo,khi)]
1771 + dx*dy*(1.0-dz)*u[IJK(ihi,jhi,klo)]
1772 + dx*(1.0-dy)*(1.0-dz)*u[IJK(ihi,jlo,klo)]
1773 + (1.0-dx)*dy*dz*u[IJK(ilo,jhi,khi)]
1774 + (1.0-dx)*(1.0-dy)*dz*u[IJK(ilo,jlo,khi)]
1775 + (1.0-dx)*dy*(1.0-dz)*u[IJK(ilo,jhi,klo)]
1776 + (1.0-dx)*(1.0-dy)*(1.0-dz)*u[IJK(ilo,jlo,klo)];
1777 energy += (uval*charge*atom->
partID);
1779 Vnm_print(2,
"Vpmg_qfEnergy: Atom #%d at (%4.3f, %4.3f, \
1780%4.3f) is off the mesh (ignoring)!\n",
1781 iatom, position[0], position[1], position[2]);
1793 int nx, ny, nz, ihi, ilo, jhi, jlo, khi, klo;
1794 double xmax, xmin, ymax, ymin, zmax, zmin, hx, hy, hzed, ifloat, jfloat;
1795 double charge, kfloat, dx, dy, dz, energy, uval, *position;
1806 xmax = thee->
xf[nx-1];
1807 ymax = thee->
yf[ny-1];
1808 zmax = thee->
zf[nz-1];
1822 ifloat = (position[0] - xmin)/hx;
1823 jfloat = (position[1] - ymin)/hy;
1824 kfloat = (position[2] - zmin)/hzed;
1825 ihi = (int)ceil(ifloat);
1826 ilo = (int)floor(ifloat);
1827 jhi = (int)ceil(jfloat);
1828 jlo = (int)floor(jfloat);
1829 khi = (int)ceil(kfloat);
1830 klo = (int)floor(kfloat);
1834 if ((ihi<nx) && (jhi<ny) && (khi<nz) &&
1835 (ilo>=0) && (jlo>=0) && (klo>=0)) {
1838 dx = ifloat - (double)(ilo);
1839 dy = jfloat - (double)(jlo);
1840 dz = kfloat - (double)(klo);
1842 dx*dy*dz*u[IJK(ihi,jhi,khi)]
1843 + dx*(1.0-dy)*dz*u[IJK(ihi,jlo,khi)]
1844 + dx*dy*(1.0-dz)*u[IJK(ihi,jhi,klo)]
1845 + dx*(1.0-dy)*(1.0-dz)*u[IJK(ihi,jlo,klo)]
1846 + (1.0-dx)*dy*dz*u[IJK(ilo,jhi,khi)]
1847 + (1.0-dx)*(1.0-dy)*dz*u[IJK(ilo,jlo,khi)]
1848 + (1.0-dx)*dy*(1.0-dz)*u[IJK(ilo,jhi,klo)]
1849 + (1.0-dx)*(1.0-dy)*(1.0-dz)*u[IJK(ilo,jlo,klo)];
1850 energy += (uval*charge*atom->
partID);
1852 Vnm_print(2,
"Vpmg_qfAtomEnergy: Atom at (%4.3f, %4.3f, \
1853%4.3f) is off the mesh (ignoring)!\n",
1854 position[0], position[1], position[2]);
1863 double hx, hy, hzed, energy;
1866 VASSERT(thee != VNULL);
1877 Vnm_print(2,
"Vpmg_qfEnergyVolume: need to call Vpmg_fillco!\n");
1882 Vnm_print(0,
"Vpmg_qfEnergyVolume: Calculating energy\n");
1883 for (i=0; i<(nx*ny*nz); i++) {
1884 energy += (thee->
pvec[i]*thee->
u[i]*thee->
charge[i]);
1894 double infrad,
Vatom *atom,
double *force){
1907 Vnm_print(2,
"Vpmg_dbnbForce: Unknown surface method.\n");
1914VPRIVATE
void focusFillBound(
Vpmg *thee,
1987 xminNEW = thee->
pmgp->
xcent - ((double)(nxNEW-1)*hxNEW)/2.0;
1988 xmaxNEW = thee->
pmgp->
xcent + ((double)(nxNEW-1)*hxNEW)/2.0;
1989 yminNEW = thee->
pmgp->
ycent - ((double)(nyNEW-1)*hyNEW)/2.0;
1990 ymaxNEW = thee->
pmgp->
ycent + ((double)(nyNEW-1)*hyNEW)/2.0;
1991 zminNEW = thee->
pmgp->
zcent - ((double)(nzNEW-1)*hzNEW)/2.0;
1992 zmaxNEW = thee->
pmgp->
zcent + ((double)(nzNEW-1)*hzNEW)/2.0;
1994 if(pmgOLD != VNULL){
1996 hxOLD = pmgOLD->
pmgp->
hx;
1997 hyOLD = pmgOLD->
pmgp->
hy;
1999 nxOLD = pmgOLD->
pmgp->
nx;
2000 nyOLD = pmgOLD->
pmgp->
ny;
2001 nzOLD = pmgOLD->
pmgp->
nz;
2002 xminOLD = pmgOLD->
pmgp->
xcent - ((double)(nxOLD-1)*hxOLD)/2.0;
2003 xmaxOLD = pmgOLD->
pmgp->
xcent + ((double)(nxOLD-1)*hxOLD)/2.0;
2004 yminOLD = pmgOLD->
pmgp->
ycent - ((double)(nyOLD-1)*hyOLD)/2.0;
2005 ymaxOLD = pmgOLD->
pmgp->
ycent + ((double)(nyOLD-1)*hyOLD)/2.0;
2006 zminOLD = pmgOLD->
pmgp->
zcent - ((double)(nzOLD-1)*hzOLD)/2.0;
2007 zmaxOLD = pmgOLD->
pmgp->
zcent + ((double)(nzOLD-1)*hzOLD)/2.0;
2048 pre1 = pre1*(1.0e10);
2054 if (VABS(xminOLD-xminNEW) < VSMALL) xminNEW = xminOLD;
2055 if (VABS(xmaxOLD-xmaxNEW) < VSMALL) xmaxNEW = xmaxOLD;
2056 if (VABS(yminOLD-yminNEW) < VSMALL) yminNEW = yminOLD;
2057 if (VABS(ymaxOLD-ymaxNEW) < VSMALL) ymaxNEW = ymaxOLD;
2058 if (VABS(zminOLD-zminNEW) < VSMALL) zminNEW = zminOLD;
2059 if (VABS(zmaxOLD-zmaxNEW) < VSMALL) zmaxNEW = zmaxOLD;
2063 Vnm_print(0,
"VPMG::focusFillBound -- New mesh mins = %g, %g, %g\n",
2064 xminNEW, yminNEW, zminNEW);
2065 Vnm_print(0,
"VPMG::focusFillBound -- New mesh maxs = %g, %g, %g\n",
2066 xmaxNEW, ymaxNEW, zmaxNEW);
2067 Vnm_print(0,
"VPMG::focusFillBound -- Old mesh mins = %g, %g, %g\n",
2068 xminOLD, yminOLD, zminOLD);
2069 Vnm_print(0,
"VPMG::focusFillBound -- Old mesh maxs = %g, %g, %g\n",
2070 xmaxOLD, ymaxOLD, zmaxOLD);
2074 if ((xmaxNEW>xmaxOLD) || (ymaxNEW>ymaxOLD) || (zmaxNEW>zmaxOLD) ||
2075 (xminOLD>xminNEW) || (yminOLD>yminNEW) || (zminOLD>zminNEW)) {
2077 Vnm_print(2,
"Vpmg::focusFillBound -- new mesh not contained in old!\n");
2078 Vnm_print(2,
"Vpmg::focusFillBound -- old mesh min = (%g, %g, %g)\n",
2079 xminOLD, yminOLD, zminOLD);
2080 Vnm_print(2,
"Vpmg::focusFillBound -- old mesh max = (%g, %g, %g)\n",
2081 xmaxOLD, ymaxOLD, zmaxOLD);
2082 Vnm_print(2,
"Vpmg::focusFillBound -- new mesh min = (%g, %g, %g)\n",
2083 xminNEW, yminNEW, zminNEW);
2084 Vnm_print(2,
"Vpmg::focusFillBound -- new mesh max = (%g, %g, %g)\n",
2085 xmaxNEW, ymaxNEW, zmaxNEW);
2094 for (k=0; k<nzNEW; k++) {
2095 for (j=0; j<nyNEW; j++) {
2098 y = yminNEW + j*hyNEW;
2099 z = zminNEW + k*hzNEW;
2100 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2101 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2102 ifloat = (x - xminOLD)/hxOLD;
2103 jfloat = (y - yminOLD)/hyOLD;
2104 kfloat = (z - zminOLD)/hzOLD;
2105 ihi = (int)ceil(ifloat);
2106 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2107 ilo = (int)floor(ifloat);
2108 if (ilo < 0) ilo = 0;
2109 jhi = (int)ceil(jfloat);
2110 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2111 jlo = (int)floor(jfloat);
2112 if (jlo < 0) jlo = 0;
2113 khi = (int)ceil(kfloat);
2114 if (khi > (nzOLD-1)) khi = nzOLD-1;
2115 klo = (int)floor(kfloat);
2116 if (klo < 0) klo = 0;
2117 dx = ifloat - (double)(ilo);
2118 dy = jfloat - (double)(jlo);
2119 dz = kfloat - (double)(klo);
2120 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2121 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2122 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2123 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2124 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2125 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2126 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2127 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2128 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2129 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2131 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \
2132 %g!\n", __FILE__, __LINE__, x, y, z);
2133 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \
2134 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2135 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \
2136 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2139 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2140 thee->
gxcf[IJKx(j,k,0)] = uval;
2141 if(uval < uvalMin) uvalMin = uval;
2142 if(uval > uvalMax) uvalMax = uval;
2146 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2147 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2148 ifloat = (x - xminOLD)/hxOLD;
2149 jfloat = (y - yminOLD)/hyOLD;
2150 kfloat = (z - zminOLD)/hzOLD;
2151 ihi = (int)ceil(ifloat);
2152 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2153 ilo = (int)floor(ifloat);
2154 if (ilo < 0) ilo = 0;
2155 jhi = (int)ceil(jfloat);
2156 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2157 jlo = (int)floor(jfloat);
2158 if (jlo < 0) jlo = 0;
2159 khi = (int)ceil(kfloat);
2160 if (khi > (nzOLD-1)) khi = nzOLD-1;
2161 klo = (int)floor(kfloat);
2162 if (klo < 0) klo = 0;
2163 dx = ifloat - (double)(ilo);
2164 dy = jfloat - (double)(jlo);
2165 dz = kfloat - (double)(klo);
2166 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2167 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2168 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2169 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2170 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2171 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2172 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2173 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2174 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2175 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2177 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \
2178 %g!\n", __FILE__, __LINE__, x, y, z);
2179 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \
2180 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2181 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \
2182 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2185 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2186 thee->
gxcf[IJKx(j,k,1)] = uval;
2187 if(uval < uvalMin) uvalMin = uval;
2188 if(uval > uvalMax) uvalMax = uval;
2191 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2192 thee->
gxcf[IJKx(j,k,2)] = 0.0;
2193 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2194 thee->
gxcf[IJKx(j,k,3)] = 0.0;
2199 for (k=0; k<nzNEW; k++) {
2200 for (i=0; i<nxNEW; i++) {
2202 x = xminNEW + i*hxNEW;
2204 z = zminNEW + k*hzNEW;
2205 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2206 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2207 ifloat = (x - xminOLD)/hxOLD;
2208 jfloat = (y - yminOLD)/hyOLD;
2209 kfloat = (z - zminOLD)/hzOLD;
2210 ihi = (int)ceil(ifloat);
2211 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2212 ilo = (int)floor(ifloat);
2213 if (ilo < 0) ilo = 0;
2214 jhi = (int)ceil(jfloat);
2215 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2216 jlo = (int)floor(jfloat);
2217 if (jlo < 0) jlo = 0;
2218 khi = (int)ceil(kfloat);
2219 if (khi > (nzOLD-1)) khi = nzOLD-1;
2220 klo = (int)floor(kfloat);
2221 if (klo < 0) klo = 0;
2222 dx = ifloat - (double)(ilo);
2223 dy = jfloat - (double)(jlo);
2224 dz = kfloat - (double)(klo);
2225 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2226 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2227 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2228 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2229 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2230 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2231 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2232 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2233 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2234 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2236 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \
2237 %g!\n", __FILE__, __LINE__, x, y, z);
2238 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \
2239 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2240 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \
2241 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2244 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2245 thee->
gycf[IJKy(i,k,0)] = uval;
2246 if(uval < uvalMin) uvalMin = uval;
2247 if(uval > uvalMax) uvalMax = uval;
2251 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2252 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2253 ifloat = (x - xminOLD)/hxOLD;
2254 jfloat = (y - yminOLD)/hyOLD;
2255 kfloat = (z - zminOLD)/hzOLD;
2256 ihi = (int)ceil(ifloat);
2257 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2258 ilo = (int)floor(ifloat);
2259 if (ilo < 0) ilo = 0;
2260 jhi = (int)ceil(jfloat);
2261 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2262 jlo = (int)floor(jfloat);
2263 if (jlo < 0) jlo = 0;
2264 khi = (int)ceil(kfloat);
2265 if (khi > (nzOLD-1)) khi = nzOLD-1;
2266 klo = (int)floor(kfloat);
2267 if (klo < 0) klo = 0;
2268 dx = ifloat - (double)(ilo);
2269 dy = jfloat - (double)(jlo);
2270 dz = kfloat - (double)(klo);
2271 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2272 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2273 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2274 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2275 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2276 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2277 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2278 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2279 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2280 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2282 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \
2283 %g!\n", __FILE__, __LINE__, x, y, z);
2284 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \
2285 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2286 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \
2287 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2290 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2291 thee->
gycf[IJKy(i,k,1)] = uval;
2292 if(uval < uvalMin) uvalMin = uval;
2293 if(uval > uvalMax) uvalMax = uval;
2296 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2297 thee->
gycf[IJKy(i,k,2)] = 0.0;
2298 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2299 thee->
gycf[IJKy(i,k,3)] = 0.0;
2304 for (j=0; j<nyNEW; j++) {
2305 for (i=0; i<nxNEW; i++) {
2307 x = xminNEW + i*hxNEW;
2308 y = yminNEW + j*hyNEW;
2310 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2311 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2312 ifloat = (x - xminOLD)/hxOLD;
2313 jfloat = (y - yminOLD)/hyOLD;
2314 kfloat = (z - zminOLD)/hzOLD;
2315 ihi = (int)ceil(ifloat);
2316 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2317 ilo = (int)floor(ifloat);
2318 if (ilo < 0) ilo = 0;
2319 jhi = (int)ceil(jfloat);
2320 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2321 jlo = (int)floor(jfloat);
2322 if (jlo < 0) jlo = 0;
2323 khi = (int)ceil(kfloat);
2324 if (khi > (nzOLD-1)) khi = nzOLD-1;
2325 klo = (int)floor(kfloat);
2326 if (klo < 0) klo = 0;
2327 dx = ifloat - (double)(ilo);
2328 dy = jfloat - (double)(jlo);
2329 dz = kfloat - (double)(klo);
2330 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2331 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2332 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2333 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2334 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2335 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2336 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2337 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2338 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2339 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2341 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \
2342 %g!\n", __FILE__, __LINE__, x, y, z);
2343 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \
2344 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2345 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \
2346 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2349 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2350 thee->
gzcf[IJKz(i,j,0)] = uval;
2351 if(uval < uvalMin) uvalMin = uval;
2352 if(uval > uvalMax) uvalMax = uval;
2356 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2357 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2358 ifloat = (x - xminOLD)/hxOLD;
2359 jfloat = (y - yminOLD)/hyOLD;
2360 kfloat = (z - zminOLD)/hzOLD;
2361 ihi = (int)ceil(ifloat);
2362 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2363 ilo = (int)floor(ifloat);
2364 if (ilo < 0) ilo = 0;
2365 jhi = (int)ceil(jfloat);
2366 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2367 jlo = (int)floor(jfloat);
2368 if (jlo < 0) jlo = 0;
2369 khi = (int)ceil(kfloat);
2370 if (khi > (nzOLD-1)) khi = nzOLD-1;
2371 klo = (int)floor(kfloat);
2372 if (klo < 0) klo = 0;
2373 dx = ifloat - (double)(ilo);
2374 dy = jfloat - (double)(jlo);
2375 dz = kfloat - (double)(klo);
2376 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2377 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2378 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2379 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2380 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2381 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2382 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2383 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2384 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2385 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2387 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \
2388 %g!\n", __FILE__, __LINE__, x, y, z);
2389 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \
2390 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2391 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \
2392 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2395 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2396 thee->
gzcf[IJKz(i,j,1)] = uval;
2397 if(uval < uvalMin) uvalMin = uval;
2398 if(uval > uvalMax) uvalMax = uval;
2401 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2402 thee->
gzcf[IJKz(i,j,2)] = 0.0;
2403 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2404 thee->
gzcf[IJKz(i,j,3)] = 0.0;
2410 "Unusually large potential values\n"
2411 " detected on the focusing boundary!\n"
2412 " Convergence not guaranteed for NPBE/NRPBE calculations!"
2417 double partMin[3],
double partMax[3],
int bflags[6]) {
2420 double hxNEW, hyNEW, hzNEW;
2421 double lowerCorner[3], upperCorner[3];
2422 int nxNEW, nyNEW, nzNEW;
2423 int nxOLD, nyOLD, nzOLD;
2425 double xmin, xmax, ymin, ymax, zmin, zmax;
2426 double hxOLD, hyOLD, hzOLD;
2427 double xval, yval, zval;
2445 lowerCorner[0] = thee->
pmgp->
xcent - ((double)(nxNEW-1)*hxNEW)/2.0;
2446 upperCorner[0] = thee->
pmgp->
xcent + ((double)(nxNEW-1)*hxNEW)/2.0;
2447 lowerCorner[1] = thee->
pmgp->
ycent - ((double)(nyNEW-1)*hyNEW)/2.0;
2448 upperCorner[1] = thee->
pmgp->
ycent + ((double)(nyNEW-1)*hyNEW)/2.0;
2449 lowerCorner[2] = thee->
pmgp->
zcent - ((double)(nzNEW-1)*hzNEW)/2.0;
2450 upperCorner[2] = thee->
pmgp->
zcent + ((double)(nzNEW-1)*hzNEW)/2.0;
2452 Vnm_print(0,
"VPMG::extEnergy: energy flag = %d\n", extFlag);
2455 nxOLD = pmgOLD->
pmgp->
nx;
2456 nyOLD = pmgOLD->
pmgp->
ny;
2457 nzOLD = pmgOLD->
pmgp->
nz;
2462 Vpmg_setPart(pmgOLD, lowerCorner, upperCorner, bflags);
2465 Vnm_print(0,
"VPMG::extEnergy: Finding extEnergy dimensions...\n");
2466 Vnm_print(0,
"VPMG::extEnergy Disj part lower corner = (%g, %g, %g)\n",
2467 partMin[0], partMin[1], partMin[2]);
2468 Vnm_print(0,
"VPMG::extEnergy Disj part upper corner = (%g, %g, %g)\n",
2469 partMax[0], partMax[1], partMax[2]);
2473 hxOLD = pmgOLD->
pmgp->
hx;
2474 hyOLD = pmgOLD->
pmgp->
hy;
2476 xmin = pmgOLD->
pmgp->
xcent - 0.5*hxOLD*(nxOLD-1);
2477 ymin = pmgOLD->
pmgp->
ycent - 0.5*hyOLD*(nyOLD-1);
2478 zmin = pmgOLD->
pmgp->
zcent - 0.5*hzOLD*(nzOLD-1);
2479 xmax = xmin+hxOLD*(nxOLD-1);
2480 ymax = ymin+hyOLD*(nyOLD-1);
2481 zmax = zmin+hzOLD*(nzOLD-1);
2483 Vnm_print(0,
"VPMG::extEnergy Old lower corner = (%g, %g, %g)\n",
2485 Vnm_print(0,
"VPMG::extEnergy Old upper corner = (%g, %g, %g)\n",
2495 for(i=0; i<nx; i++) {
2498 if (x < partMin[0] && bflags[
VAPBS_LEFT] == 1) xval = 0;
2499 else if (x > partMax[0] && bflags[
VAPBS_RIGHT] == 1) xval = 0;
2501 for(j=0; j<ny; j++) {
2504 if (y < partMin[1] && bflags[
VAPBS_BACK] == 1) yval = 0;
2505 else if (y > partMax[1] && bflags[
VAPBS_FRONT] == 1) yval = 0;
2507 for(k=0; k<nz; k++) {
2510 if (z < partMin[2] && bflags[
VAPBS_DOWN] == 1) zval = 0;
2511 else if (z > partMax[2] && bflags[
VAPBS_UP] == 1) zval = 0;
2513 if (pmgOLD->
pvec[IJK(i,j,k)] > VSMALL) pmgOLD->
pvec[IJK(i,j,k)] = 1.0;
2514 pmgOLD->
pvec[IJK(i,j,k)] = (1 - (pmgOLD->
pvec[IJK(i,j,k)])) * (xval*yval*zval);
2527 if (x < partMin[0] && bflags[
VAPBS_LEFT] == 1) xval = 0;
2528 else if (x > partMax[0] && bflags[
VAPBS_RIGHT] == 1) xval = 0;
2529 if (y < partMin[1] && bflags[
VAPBS_BACK] == 1) yval = 0;
2530 else if (y > partMax[1] && bflags[
VAPBS_FRONT] == 1) yval = 0;
2531 if (z < partMin[2] && bflags[
VAPBS_DOWN] == 1) zval = 0;
2532 else if (z > partMax[2] && bflags[
VAPBS_UP] == 1) zval = 0;
2539 Vnm_print(0,
"VPMG::extEnergy: extQmEnergy = %g kT\n", thee->
extQmEnergy);
2541 Vnm_print(0,
"VPMG::extEnergy: extQfEnergy = %g kT\n", thee->
extQfEnergy);
2543 Vnm_print(0,
"VPMG::extEnergy: extDiEnergy = %g kT\n", thee->
extDiEnergy);
2547VPRIVATE
double bcfl1sp(
double size,
double *apos,
double charge,
2548 double xkappa,
double pre1,
double *pos) {
2552 dist = VSQRT(VSQR(pos[0]-apos[0]) + VSQR(pos[1]-apos[1])
2553 + VSQR(pos[2]-apos[2]));
2554 if (xkappa > VSMALL) {
2555 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2558 val = pre1*(charge/dist);
2564VPRIVATE
void bcfl1(
double size,
double *apos,
double charge,
2565 double xkappa,
double pre1,
double *gxcf,
double *gycf,
double *gzcf,
2566 double *xf,
double *yf,
double *zf,
int nx,
int ny,
int nz) {
2573 for (k=0; k<nz; k++) {
2575 for (j=0; j<ny; j++) {
2578 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2579 + VSQR(gpos[2]-apos[2]));
2580 if (xkappa > VSMALL) {
2581 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2584 val = pre1*(charge/dist);
2586 gxcf[IJKx(j,k,0)] += val;
2588 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2589 + VSQR(gpos[2]-apos[2]));
2590 if (xkappa > VSMALL) {
2591 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2594 val = pre1*(charge/dist);
2596 gxcf[IJKx(j,k,1)] += val;
2601 for (k=0; k<nz; k++) {
2603 for (i=0; i<nx; i++) {
2606 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2607 + VSQR(gpos[2]-apos[2]));
2608 if (xkappa > VSMALL) {
2609 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2612 val = pre1*(charge/dist);
2614 gycf[IJKy(i,k,0)] += val;
2616 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2617 + VSQR(gpos[2]-apos[2]));
2618 if (xkappa > VSMALL) {
2619 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2622 val = pre1*(charge/dist);
2624 gycf[IJKy(i,k,1)] += val;
2629 for (j=0; j<ny; j++) {
2631 for (i=0; i<nx; i++) {
2634 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2635 + VSQR(gpos[2]-apos[2]));
2636 if (xkappa > VSMALL) {
2637 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2640 val = pre1*(charge/dist);
2642 gzcf[IJKz(i,j,0)] += val;
2644 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2645 + VSQR(gpos[2]-apos[2]));
2646 if (xkappa > VSMALL) {
2647 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2650 val = pre1*(charge/dist);
2652 gzcf[IJKz(i,j,1)] += val;
2657VPRIVATE
void bcfl2(
double size,
double *apos,
2658 double charge,
double *dipole,
double *quad,
2659 double xkappa,
double eps_p,
double eps_w,
double T,
2660 double *gxcf,
double *gycf,
double *gzcf,
2661 double *xf,
double *yf,
double *zf,
2662 int nx,
int ny,
int nz) {
2666 double gpos[3],tensor[3];
2667 double ux,uy,uz,xr,yr,zr;
2668 double qxx,qxy,qxz,qyx,qyy,qyz,qzx,qzy,qzz;
2671 VASSERT(dipole != VNULL);
2675 if (quad != VNULL) {
2680 qxx = quad[0] / 3.0;
2681 qxy = quad[1] / 3.0;
2682 qxz = quad[2] / 3.0;
2683 qyx = quad[3] / 3.0;
2684 qyy = quad[4] / 3.0;
2685 qyz = quad[5] / 3.0;
2686 qzx = quad[6] / 3.0;
2687 qzy = quad[7] / 3.0;
2688 qzz = quad[8] / 3.0;
2705 for (k=0; k<nz; k++) {
2707 for (j=0; j<ny; j++) {
2710 xr = gpos[0] - apos[0];
2711 yr = gpos[1] - apos[1];
2712 zr = gpos[2] - apos[2];
2713 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2714 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2715 val = pre*charge*tensor[0];
2716 val -= pre*ux*xr*tensor[1];
2717 val -= pre*uy*yr*tensor[1];
2718 val -= pre*uz*zr*tensor[1];
2719 val += pre*qxx*xr*xr*tensor[2];
2720 val += pre*qyy*yr*yr*tensor[2];
2721 val += pre*qzz*zr*zr*tensor[2];
2722 val += pre*2.0*qxy*xr*yr*tensor[2];
2723 val += pre*2.0*qxz*xr*zr*tensor[2];
2724 val += pre*2.0*qyz*yr*zr*tensor[2];
2725 gxcf[IJKx(j,k,0)] += val;
2728 xr = gpos[0] - apos[0];
2729 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2730 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2731 val = pre*charge*tensor[0];
2732 val -= pre*ux*xr*tensor[1];
2733 val -= pre*uy*yr*tensor[1];
2734 val -= pre*uz*zr*tensor[1];
2735 val += pre*qxx*xr*xr*tensor[2];
2736 val += pre*qyy*yr*yr*tensor[2];
2737 val += pre*qzz*zr*zr*tensor[2];
2738 val += pre*2.0*qxy*xr*yr*tensor[2];
2739 val += pre*2.0*qxz*xr*zr*tensor[2];
2740 val += pre*2.0*qyz*yr*zr*tensor[2];
2741 gxcf[IJKx(j,k,1)] += val;
2746 for (k=0; k<nz; k++) {
2748 for (i=0; i<nx; i++) {
2751 xr = gpos[0] - apos[0];
2752 yr = gpos[1] - apos[1];
2753 zr = gpos[2] - apos[2];
2754 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2755 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2756 val = pre*charge*tensor[0];
2757 val -= pre*ux*xr*tensor[1];
2758 val -= pre*uy*yr*tensor[1];
2759 val -= pre*uz*zr*tensor[1];
2760 val += pre*qxx*xr*xr*tensor[2];
2761 val += pre*qyy*yr*yr*tensor[2];
2762 val += pre*qzz*zr*zr*tensor[2];
2763 val += pre*2.0*qxy*xr*yr*tensor[2];
2764 val += pre*2.0*qxz*xr*zr*tensor[2];
2765 val += pre*2.0*qyz*yr*zr*tensor[2];
2766 gycf[IJKy(i,k,0)] += val;
2769 yr = gpos[1] - apos[1];
2770 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2771 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2772 val = pre*charge*tensor[0];
2773 val -= pre*ux*xr*tensor[1];
2774 val -= pre*uy*yr*tensor[1];
2775 val -= pre*uz*zr*tensor[1];
2776 val += pre*qxx*xr*xr*tensor[2];
2777 val += pre*qyy*yr*yr*tensor[2];
2778 val += pre*qzz*zr*zr*tensor[2];
2779 val += pre*2.0*qxy*xr*yr*tensor[2];
2780 val += pre*2.0*qxz*xr*zr*tensor[2];
2781 val += pre*2.0*qyz*yr*zr*tensor[2];
2782 gycf[IJKy(i,k,1)] += val;
2787 for (j=0; j<ny; j++) {
2789 for (i=0; i<nx; i++) {
2792 xr = gpos[0] - apos[0];
2793 yr = gpos[1] - apos[1];
2794 zr = gpos[2] - apos[2];
2795 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2796 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2797 val = pre*charge*tensor[0];
2798 val -= pre*ux*xr*tensor[1];
2799 val -= pre*uy*yr*tensor[1];
2800 val -= pre*uz*zr*tensor[1];
2801 val += pre*qxx*xr*xr*tensor[2];
2802 val += pre*qyy*yr*yr*tensor[2];
2803 val += pre*qzz*zr*zr*tensor[2];
2804 val += pre*2.0*qxy*xr*yr*tensor[2];
2805 val += pre*2.0*qxz*xr*zr*tensor[2];
2806 val += pre*2.0*qyz*yr*zr*tensor[2];
2807 gzcf[IJKz(i,j,0)] += val;
2810 zr = gpos[2] - apos[2];
2811 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2812 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2813 val = pre*charge*tensor[0];
2814 val -= pre*ux*xr*tensor[1];
2815 val -= pre*uy*yr*tensor[1];
2816 val -= pre*uz*zr*tensor[1];
2817 val += pre*qxx*xr*xr*tensor[2];
2818 val += pre*qyy*yr*yr*tensor[2];
2819 val += pre*qzz*zr*zr*tensor[2];
2820 val += pre*2.0*qxy*xr*yr*tensor[2];
2821 val += pre*2.0*qxz*xr*zr*tensor[2];
2822 val += pre*2.0*qyz*yr*zr*tensor[2];
2823 gzcf[IJKz(i,j,1)] += val;
2828VPRIVATE
void bcCalcOrig(
Vpmg *thee) {
2831 double size, *position, charge, xkappa, eps_w, T, pre1;
2832 double *dipole, *quadrupole, debye, eps_p;
2833 double xr,yr,zr,qave,*apos;
2834 double sdhcharge, sdhdipole[3], traced[9], sdhquadrupole[9];
2848 for (k=0; k<nz; k++) {
2849 for (j=0; j<ny; j++) {
2850 thee->
gxcf[IJKx(j,k,0)] = 0.0;
2851 thee->
gxcf[IJKx(j,k,1)] = 0.0;
2852 thee->
gxcf[IJKx(j,k,2)] = 0.0;
2853 thee->
gxcf[IJKx(j,k,3)] = 0.0;
2858 for (k=0; k<nz; k++) {
2859 for (i=0; i<nx; i++) {
2860 thee->
gycf[IJKy(i,k,0)] = 0.0;
2861 thee->
gycf[IJKy(i,k,1)] = 0.0;
2862 thee->
gycf[IJKy(i,k,2)] = 0.0;
2863 thee->
gycf[IJKy(i,k,3)] = 0.0;
2868 for (j=0; j<ny; j++) {
2869 for (i=0; i<nx; i++) {
2870 thee->
gzcf[IJKz(i,j,0)] = 0.0;
2871 thee->
gzcf[IJKz(i,j,1)] = 0.0;
2872 thee->
gzcf[IJKz(i,j,2)] = 0.0;
2873 thee->
gzcf[IJKz(i,j,3)] = 0.0;
2897 pre1 = pre1*(1.0e10);
2918 for (i=0; i<3; i++) sdhdipole[i] = 0.0;
2919 for (i=0; i<9; i++) sdhquadrupole[i] = 0.0;
2924 xr = apos[0] - position[0];
2925 yr = apos[1] - position[1];
2926 zr = apos[2] - position[2];
2930 sdhcharge += charge;
2931 sdhdipole[0] += xr * charge;
2932 sdhdipole[1] += yr * charge;
2933 sdhdipole[2] += zr * charge;
2934 traced[0] = xr*xr*charge;
2935 traced[1] = xr*yr*charge;
2936 traced[2] = xr*zr*charge;
2937 traced[3] = yr*xr*charge;
2938 traced[4] = yr*yr*charge;
2939 traced[5] = yr*zr*charge;
2940 traced[6] = zr*xr*charge;
2941 traced[7] = zr*yr*charge;
2942 traced[8] = zr*zr*charge;
2943 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
2944 sdhquadrupole[0] += 1.5*(traced[0] - qave);
2945 sdhquadrupole[1] += 1.5*(traced[1]);
2946 sdhquadrupole[2] += 1.5*(traced[2]);
2947 sdhquadrupole[3] += 1.5*(traced[3]);
2948 sdhquadrupole[4] += 1.5*(traced[4] - qave);
2949 sdhquadrupole[5] += 1.5*(traced[5]);
2950 sdhquadrupole[6] += 1.5*(traced[6]);
2951 sdhquadrupole[7] += 1.5*(traced[7]);
2952 sdhquadrupole[8] += 1.5*(traced[8] - qave);
2953#if defined(WITH_TINKER)
2956 dipole = Vatom_getDipole(atom);
2957 quadrupole = Vatom_getQuadrupole(atom);
2958 sdhcharge += charge;
2959 sdhdipole[0] += xr * charge;
2960 sdhdipole[1] += yr * charge;
2961 sdhdipole[2] += zr * charge;
2962 traced[0] = xr*xr*charge;
2963 traced[1] = xr*yr*charge;
2964 traced[2] = xr*zr*charge;
2965 traced[3] = yr*xr*charge;
2966 traced[4] = yr*yr*charge;
2967 traced[5] = yr*zr*charge;
2968 traced[6] = zr*xr*charge;
2969 traced[7] = zr*yr*charge;
2970 traced[8] = zr*zr*charge;
2971 sdhdipole[0] += dipole[0];
2972 sdhdipole[1] += dipole[1];
2973 sdhdipole[2] += dipole[2];
2974 traced[0] += 2.0*xr*dipole[0];
2975 traced[1] += xr*dipole[1] + yr*dipole[0];
2976 traced[2] += xr*dipole[2] + zr*dipole[0];
2977 traced[3] += yr*dipole[0] + xr*dipole[1];
2978 traced[4] += 2.0*yr*dipole[1];
2979 traced[5] += yr*dipole[2] + zr*dipole[1];
2980 traced[6] += zr*dipole[0] + xr*dipole[2];
2981 traced[7] += zr*dipole[1] + yr*dipole[2];
2982 traced[8] += 2.0*zr*dipole[2];
2983 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
2984 sdhquadrupole[0] += 1.5*(traced[0] - qave);
2985 sdhquadrupole[1] += 1.5*(traced[1]);
2986 sdhquadrupole[2] += 1.5*(traced[2]);
2987 sdhquadrupole[3] += 1.5*(traced[3]);
2988 sdhquadrupole[4] += 1.5*(traced[4] - qave);
2989 sdhquadrupole[5] += 1.5*(traced[5]);
2990 sdhquadrupole[6] += 1.5*(traced[6]);
2991 sdhquadrupole[7] += 1.5*(traced[7]);
2992 sdhquadrupole[8] += 1.5*(traced[8] - qave);
2993 sdhquadrupole[0] += quadrupole[0];
2994 sdhquadrupole[1] += quadrupole[1];
2995 sdhquadrupole[2] += quadrupole[2];
2996 sdhquadrupole[3] += quadrupole[3];
2997 sdhquadrupole[4] += quadrupole[4];
2998 sdhquadrupole[5] += quadrupole[5];
2999 sdhquadrupole[6] += quadrupole[6];
3000 sdhquadrupole[7] += quadrupole[7];
3001 sdhquadrupole[8] += quadrupole[8];
3003 dipole = Vatom_getInducedDipole(atom);
3004 sdhdipole[0] += dipole[0];
3005 sdhdipole[1] += dipole[1];
3006 sdhdipole[2] += dipole[2];
3007 traced[0] = 2.0*xr*dipole[0];
3008 traced[1] = xr*dipole[1] + yr*dipole[0];
3009 traced[2] = xr*dipole[2] + zr*dipole[0];
3010 traced[3] = yr*dipole[0] + xr*dipole[1];
3011 traced[4] = 2.0*yr*dipole[1];
3012 traced[5] = yr*dipole[2] + zr*dipole[1];
3013 traced[6] = zr*dipole[0] + xr*dipole[2];
3014 traced[7] = zr*dipole[1] + yr*dipole[2];
3015 traced[8] = 2.0*zr*dipole[2];
3016 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3017 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3018 sdhquadrupole[1] += 1.5*(traced[1]);
3019 sdhquadrupole[2] += 1.5*(traced[2]);
3020 sdhquadrupole[3] += 1.5*(traced[3]);
3021 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3022 sdhquadrupole[5] += 1.5*(traced[5]);
3023 sdhquadrupole[6] += 1.5*(traced[6]);
3024 sdhquadrupole[7] += 1.5*(traced[7]);
3025 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3027 dipole = Vatom_getNLInducedDipole(atom);
3028 sdhdipole[0] += dipole[0];
3029 sdhdipole[1] += dipole[1];
3030 sdhdipole[2] += dipole[2];
3031 traced[0] = 2.0*xr*dipole[0];
3032 traced[1] = xr*dipole[1] + yr*dipole[0];
3033 traced[2] = xr*dipole[2] + zr*dipole[0];
3034 traced[3] = yr*dipole[0] + xr*dipole[1];
3035 traced[4] = 2.0*yr*dipole[1];
3036 traced[5] = yr*dipole[2] + zr*dipole[1];
3037 traced[6] = zr*dipole[0] + xr*dipole[2];
3038 traced[7] = zr*dipole[1] + yr*dipole[2];
3039 traced[8] = 2.0*zr*dipole[2];
3040 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3041 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3042 sdhquadrupole[1] += 1.5*(traced[1]);
3043 sdhquadrupole[2] += 1.5*(traced[2]);
3044 sdhquadrupole[3] += 1.5*(traced[3]);
3045 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3046 sdhquadrupole[5] += 1.5*(traced[5]);
3047 sdhquadrupole[6] += 1.5*(traced[6]);
3048 sdhquadrupole[7] += 1.5*(traced[7]);
3049 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3072 bcfl2(size, position, sdhcharge, sdhdipole, sdhquadrupole,
3073 xkappa, eps_p, eps_w, T, thee->
gxcf, thee->
gycf,
3074 thee->
gzcf, thee->
xf, thee->
yf, thee->
zf, nx, ny, nz);
3089#if defined(WITH_TINKER)
3091 dipole = Vatom_getDipole(atom);
3092 quadrupole = Vatom_getQuadrupole(atom);
3095 dipole = Vatom_getInducedDipole(atom);
3098 dipole = Vatom_getNLInducedDipole(atom);
3106 bcfl1(size, position, charge, xkappa, pre1,
3108 thee->
xf, thee->
yf, thee->
zf, nx, ny, nz);
3113 Vnm_print(2,
"bcCalc: Invalid bcfl (%d)!\n", thee->
pmgp->
bcfl);
3117 Vnm_print(2,
"VPMG::bcCalc -- not appropriate for focusing!\n");
3121 Vnm_print(2,
"VPMG::bcCalc -- invalid boundary condition \
3130VPRIVATE
int gridPointIsValid(
int i,
int j,
int k,
int nx,
int ny,
int nz){
3134 if((k==0) || (k==nz-1)){
3136 }
else if((j==0) || (j==ny-1)){
3138 }
else if((i==0) || (i==nx-1)){
3148#ifdef DEBUG_MAC_OSX_OCL
3149#include "mach_chud.h"
3150VPRIVATE
void packAtomsOpenCL(
float *ax,
float *ay,
float *az,
3151 float *charge,
float *size,
Vpmg *thee){
3156 Vatom *atom = VNULL;
3162 for(i=0;i<natoms;i++){
3163 atom = &(alist->
atoms[i]);
3175VPRIVATE
void packUnpackOpenCL(
int nx,
int ny,
int nz,
int ngrid,
3176 float *gx,
float *gy,
float *gz,
float *value,
3177 Vpmg *thee,
int pack){
3180 int x0,x1,y0,y1,z0,z1;
3183 double *xf, *yf, *zf;
3184 double *gxcf, *gycf, *gzcf;
3201 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3203 gx[igrid] = gpos[0];
3204 gy[igrid] = gpos[1];
3205 gz[igrid] = gpos[2];
3217 gxcf[x0] += value[igrid];
3220 gxcf[x1] += value[igrid];
3223 gycf[y0] += value[igrid];
3226 gycf[y1] += value[igrid];
3229 gzcf[z0] += value[igrid];
3232 gzcf[z1] += value[igrid];
3249VPRIVATE
void bcflnewOpenCL(
Vpmg *thee){
3251 int i,j,k, iatom, igrid;
3252 int x0, x1, y0, y1, z0, z1;
3255 int natoms, ngrid, ngadj;
3257 float dist, pre1, eps_w, eps_p, T, xkappa;
3259 float *ax, *ay, *az;
3260 float *charge, *size, *val;
3262 float *gx, *gy, *gz;
3277 ngrid = 2*((nx*ny) + (ny*nz) + (nx*nz));
3278 ngadj = ngrid + (512 - (ngrid & 511));
3280 ax = (
float*)malloc(natoms *
sizeof(
float));
3281 ay = (
float*)malloc(natoms *
sizeof(
float));
3282 az = (
float*)malloc(natoms *
sizeof(
float));
3284 charge = (
float*)malloc(natoms *
sizeof(
float));
3285 size = (
float*)malloc(natoms *
sizeof(
float));
3287 gx = (
float*)malloc(ngrid *
sizeof(
float));
3288 gy = (
float*)malloc(ngrid *
sizeof(
float));
3289 gz = (
float*)malloc(ngrid *
sizeof(
float));
3291 val = (
float*)malloc(ngrid *
sizeof(
float));
3293 packAtomsOpenCL(ax,ay,az,charge,size,thee);
3294 packUnpackOpenCL(nx,ny,nz,ngrid,gx,gy,gz,val,thee,1);
3296 runMDHCL(ngrid,natoms,ngadj,ax,ay,az,gx,gy,gz,charge,size,xkappa,pre1,val);
3298 packUnpackOpenCL(nx,ny,nz,ngrid,gx,gy,gz,val,thee,0);
3313VPRIVATE
void packAtoms(
double *ax,
double *ay,
double *az,
3314 double *charge,
double *size,
Vpmg *thee){
3319 Vatom *atom = VNULL;
3325 for(i=0;i<natoms;i++){
3326 atom = &(alist->
atoms[i]);
3338VPRIVATE
void packUnpack(
int nx,
int ny,
int nz,
int ngrid,
3339 double *gx,
double *gy,
double *gz,
double *value,
3340 Vpmg *thee,
int pack){
3343 int x0,x1,y0,y1,z0,z1;
3346 double *xf, *yf, *zf;
3347 double *gxcf, *gycf, *gzcf;
3364 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3366 gx[igrid] = gpos[0];
3367 gy[igrid] = gpos[1];
3368 gz[igrid] = gpos[2];
3380 gxcf[x0] += value[igrid];
3383 gxcf[x1] += value[igrid];
3386 gycf[y0] += value[igrid];
3389 gycf[y1] += value[igrid];
3392 gzcf[z0] += value[igrid];
3395 gzcf[z1] += value[igrid];
3407VPRIVATE
void bcflnew(
Vpmg *thee){
3409 int i,j,k, iatom, igrid;
3410 int x0, x1, y0, y1, z0, z1;
3415 double dist, pre1, eps_w, eps_p, T, xkappa;
3417 double *ax, *ay, *az;
3418 double *charge, *size, *val;
3420 double *gx, *gy, *gz;
3435 ngrid = 2*((nx*ny) + (ny*nz) + (nx*nz));
3437 ax = (
double*)malloc(natoms *
sizeof(
double));
3438 ay = (
double*)malloc(natoms *
sizeof(
double));
3439 az = (
double*)malloc(natoms *
sizeof(
double));
3441 charge = (
double*)malloc(natoms *
sizeof(
double));
3442 size = (
double*)malloc(natoms *
sizeof(
double));
3444 gx = (
double*)malloc(ngrid *
sizeof(
double));
3445 gy = (
double*)malloc(ngrid *
sizeof(
double));
3446 gz = (
double*)malloc(ngrid *
sizeof(
double));
3448 val = (
double*)malloc(ngrid *
sizeof(
double));
3450 packAtoms(ax,ay,az,charge,size,thee);
3451 packUnpack(nx,ny,nz,ngrid,gx,gy,gz,val,thee,1);
3453 if(xkappa > VSMALL){
3454#pragma omp parallel for default(shared) private(igrid,iatom,dist)
3455 for(igrid=0;igrid<ngrid;igrid++){
3456 for(iatom=0; iatom<natoms; iatom++){
3457 dist = VSQRT(VSQR(gx[igrid]-ax[iatom]) + VSQR(gy[igrid]-ay[iatom])
3458 + VSQR(gz[igrid]-az[iatom]));
3459 val[igrid] += pre1*(charge[iatom]/dist)*VEXP(-xkappa*(dist-size[iatom]))
3460 / (1+xkappa*size[iatom]);
3464#pragma omp parallel for default(shared) private(igrid,iatom,dist)
3465 for(igrid=0;igrid<ngrid;igrid++){
3466 for(iatom=0; iatom<natoms; iatom++){
3467 dist = VSQRT(VSQR(gx[igrid]-ax[iatom]) + VSQR(gy[igrid]-ay[iatom])
3468 + VSQR(gz[igrid]-az[iatom]));
3469 val[igrid] += pre1*(charge[iatom]/dist);
3473 packUnpack(nx,ny,nz,ngrid,gx,gy,gz,val,thee,0);
3488 double eps_w,
double rad,
double tsr[3]) {
3572 eps_r = eps_w/eps_p;
3576 tsr[0] = (1.0/eps_w)/r;
3577 tsr[1] = (1.0/eps_w)*(-1.0)/r3;
3578 tsr[2] = (1.0/eps_w)*(3.0)/r5;
3579 if (kappa < VSMALL) {
3580 tsr[1] = (3.0*eps_r)/(1.0 + 2.0*eps_r)*tsr[1];
3581 tsr[2] = (5.0*eps_r)/(2.0 + 3.0*eps_r)*tsr[2];
3589 tsr[0] = exp(ka-kr) / (1.0 + ka) * tsr[0];
3590 tsr[1] = 3.0*eps_r*exp(ka-kr)*(1.0 + kr) * tsr[1];
3591 tsr[1] = tsr[1] / (1.0 + ka + eps_r*(2.0 + 2.0*ka + ka2));
3592 tsr[2] = 5.0*eps_r*exp(ka-kr)*(3.0 + 3.0*kr + kr2) * tsr[2];
3593 tsr[2] = tsr[2]/(6.0+6.0*ka+2.0*ka2+eps_r*(9.0+9.0*ka+4.0*ka2+ka3));
3597VPRIVATE
void bcfl_sdh(
Vpmg *thee){
3602 double size, *position, charge, xkappa, eps_w, eps_p, T, pre, dist;
3603 double sdhcharge, sdhdipole[3], traced[9], sdhquadrupole[9];
3604 double *dipole, *quadrupole;
3606 double val, *apos, gpos[3], tensor[3], qave;
3607 double ux, uy, uz, xr, yr, zr;
3608 double qxx,qxy,qxz,qyx,qyy,qyz,qzx,qzy,qzz;
3610 double *xf, *yf, *zf;
3611 double *gxcf, *gycf, *gzcf;
3659 for (i=0; i<3; i++) sdhdipole[i] = 0.0;
3660 for (i=0; i<9; i++) sdhquadrupole[i] = 0.0;
3665 xr = apos[0] - position[0];
3666 yr = apos[1] - position[1];
3667 zr = apos[2] - position[2];
3671 sdhcharge += charge;
3672 sdhdipole[0] += xr * charge;
3673 sdhdipole[1] += yr * charge;
3674 sdhdipole[2] += zr * charge;
3675 traced[0] = xr*xr*charge;
3676 traced[1] = xr*yr*charge;
3677 traced[2] = xr*zr*charge;
3678 traced[3] = yr*xr*charge;
3679 traced[4] = yr*yr*charge;
3680 traced[5] = yr*zr*charge;
3681 traced[6] = zr*xr*charge;
3682 traced[7] = zr*yr*charge;
3683 traced[8] = zr*zr*charge;
3684 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3685 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3686 sdhquadrupole[1] += 1.5*(traced[1]);
3687 sdhquadrupole[2] += 1.5*(traced[2]);
3688 sdhquadrupole[3] += 1.5*(traced[3]);
3689 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3690 sdhquadrupole[5] += 1.5*(traced[5]);
3691 sdhquadrupole[6] += 1.5*(traced[6]);
3692 sdhquadrupole[7] += 1.5*(traced[7]);
3693 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3694#if defined(WITH_TINKER)
3697 dipole = Vatom_getDipole(atom);
3698 quadrupole = Vatom_getQuadrupole(atom);
3699 sdhcharge += charge;
3700 sdhdipole[0] += xr * charge;
3701 sdhdipole[1] += yr * charge;
3702 sdhdipole[2] += zr * charge;
3703 traced[0] = xr*xr*charge;
3704 traced[1] = xr*yr*charge;
3705 traced[2] = xr*zr*charge;
3706 traced[3] = yr*xr*charge;
3707 traced[4] = yr*yr*charge;
3708 traced[5] = yr*zr*charge;
3709 traced[6] = zr*xr*charge;
3710 traced[7] = zr*yr*charge;
3711 traced[8] = zr*zr*charge;
3712 sdhdipole[0] += dipole[0];
3713 sdhdipole[1] += dipole[1];
3714 sdhdipole[2] += dipole[2];
3715 traced[0] += 2.0*xr*dipole[0];
3716 traced[1] += xr*dipole[1] + yr*dipole[0];
3717 traced[2] += xr*dipole[2] + zr*dipole[0];
3718 traced[3] += yr*dipole[0] + xr*dipole[1];
3719 traced[4] += 2.0*yr*dipole[1];
3720 traced[5] += yr*dipole[2] + zr*dipole[1];
3721 traced[6] += zr*dipole[0] + xr*dipole[2];
3722 traced[7] += zr*dipole[1] + yr*dipole[2];
3723 traced[8] += 2.0*zr*dipole[2];
3724 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3725 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3726 sdhquadrupole[1] += 1.5*(traced[1]);
3727 sdhquadrupole[2] += 1.5*(traced[2]);
3728 sdhquadrupole[3] += 1.5*(traced[3]);
3729 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3730 sdhquadrupole[5] += 1.5*(traced[5]);
3731 sdhquadrupole[6] += 1.5*(traced[6]);
3732 sdhquadrupole[7] += 1.5*(traced[7]);
3733 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3734 sdhquadrupole[0] += quadrupole[0];
3735 sdhquadrupole[1] += quadrupole[1];
3736 sdhquadrupole[2] += quadrupole[2];
3737 sdhquadrupole[3] += quadrupole[3];
3738 sdhquadrupole[4] += quadrupole[4];
3739 sdhquadrupole[5] += quadrupole[5];
3740 sdhquadrupole[6] += quadrupole[6];
3741 sdhquadrupole[7] += quadrupole[7];
3742 sdhquadrupole[8] += quadrupole[8];
3744 dipole = Vatom_getInducedDipole(atom);
3745 sdhdipole[0] += dipole[0];
3746 sdhdipole[1] += dipole[1];
3747 sdhdipole[2] += dipole[2];
3748 traced[0] = 2.0*xr*dipole[0];
3749 traced[1] = xr*dipole[1] + yr*dipole[0];
3750 traced[2] = xr*dipole[2] + zr*dipole[0];
3751 traced[3] = yr*dipole[0] + xr*dipole[1];
3752 traced[4] = 2.0*yr*dipole[1];
3753 traced[5] = yr*dipole[2] + zr*dipole[1];
3754 traced[6] = zr*dipole[0] + xr*dipole[2];
3755 traced[7] = zr*dipole[1] + yr*dipole[2];
3756 traced[8] = 2.0*zr*dipole[2];
3757 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3758 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3759 sdhquadrupole[1] += 1.5*(traced[1]);
3760 sdhquadrupole[2] += 1.5*(traced[2]);
3761 sdhquadrupole[3] += 1.5*(traced[3]);
3762 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3763 sdhquadrupole[5] += 1.5*(traced[5]);
3764 sdhquadrupole[6] += 1.5*(traced[6]);
3765 sdhquadrupole[7] += 1.5*(traced[7]);
3766 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3768 dipole = Vatom_getNLInducedDipole(atom);
3769 sdhdipole[0] += dipole[0];
3770 sdhdipole[1] += dipole[1];
3771 sdhdipole[2] += dipole[2];
3772 traced[0] = 2.0*xr*dipole[0];
3773 traced[1] = xr*dipole[1] + yr*dipole[0];
3774 traced[2] = xr*dipole[2] + zr*dipole[0];
3775 traced[3] = yr*dipole[0] + xr*dipole[1];
3776 traced[4] = 2.0*yr*dipole[1];
3777 traced[5] = yr*dipole[2] + zr*dipole[1];
3778 traced[6] = zr*dipole[0] + xr*dipole[2];
3779 traced[7] = zr*dipole[1] + yr*dipole[2];
3780 traced[8] = 2.0*zr*dipole[2];
3781 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3782 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3783 sdhquadrupole[1] += 1.5*(traced[1]);
3784 sdhquadrupole[2] += 1.5*(traced[2]);
3785 sdhquadrupole[3] += 1.5*(traced[3]);
3786 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3787 sdhquadrupole[5] += 1.5*(traced[5]);
3788 sdhquadrupole[6] += 1.5*(traced[6]);
3789 sdhquadrupole[7] += 1.5*(traced[7]);
3790 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3808 qxx = sdhquadrupole[0] / 3.0;
3809 qxy = sdhquadrupole[1] / 3.0;
3810 qxz = sdhquadrupole[2] / 3.0;
3811 qyx = sdhquadrupole[3] / 3.0;
3812 qyy = sdhquadrupole[4] / 3.0;
3813 qyz = sdhquadrupole[5] / 3.0;
3814 qzx = sdhquadrupole[6] / 3.0;
3815 qzy = sdhquadrupole[7] / 3.0;
3816 qzz = sdhquadrupole[8] / 3.0;
3824 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3825 xr = gpos[0] - position[0];
3826 yr = gpos[1] - position[1];
3827 zr = gpos[2] - position[2];
3829 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
3830 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
3832 val = pre*sdhcharge*tensor[0];
3833 val -= pre*ux*xr*tensor[1];
3834 val -= pre*uy*yr*tensor[1];
3835 val -= pre*uz*zr*tensor[1];
3836 val += pre*qxx*xr*xr*tensor[2];
3837 val += pre*qyy*yr*yr*tensor[2];
3838 val += pre*qzz*zr*zr*tensor[2];
3839 val += pre*2.0*qxy*xr*yr*tensor[2];
3840 val += pre*2.0*qxz*xr*zr*tensor[2];
3841 val += pre*2.0*qyz*yr*zr*tensor[2];
3844 gxcf[IJKx(j,k,0)] = val;
3847 gxcf[IJKx(j,k,1)] = val;
3850 gycf[IJKy(i,k,0)] = val;
3853 gycf[IJKy(i,k,1)] = val;
3856 gzcf[IJKz(i,j,0)] = val;
3859 gzcf[IJKz(i,j,1)] = val;
3868VPRIVATE
void bcfl_mdh(
Vpmg *thee){
3873 double val, *apos, gpos[3];
3874 double *dipole, *quadrupole;
3875 double size, charge, xkappa, eps_w, eps_p, T, pre1, dist;
3877 double *xf, *yf, *zf;
3878 double *gxcf, *gycf, *gzcf;
3918 pre1 = pre1*(1.0e10);
3931 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3941 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
3942 + VSQR(gpos[2]-apos[2]));
3943 if (xkappa > VSMALL) {
3944 val += pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
3947 val += pre1*(charge/dist);
3953 gxcf[IJKx(j,k,0)] = val;
3956 gxcf[IJKx(j,k,1)] = val;
3959 gycf[IJKy(i,k,0)] = val;
3962 gycf[IJKy(i,k,1)] = val;
3965 gzcf[IJKz(i,j,0)] = val;
3968 gzcf[IJKz(i,j,1)] = val;
3995VPRIVATE void bcfl_mem(double zmem, double L, double eps_m, double eps_w,
3996 double V, double xkappa, double *gxcf, double *gycf, double *gzcf,
3997 double *xf, double *yf, double *zf, int nx, int ny, int nz) {
4000 /* some definitions */
4007 double dist, val, z_low, z_high, z_shift;
4008 double A, B, C, D, edge_L, l;
4009 double G, z_0, z_rel;
4012 Vnm_print(0,
"Here is the value of kappa: %f\n",xkappa);
4013 Vnm_print(0,
"Here is the value of L: %f\n",L);
4014 Vnm_print(0,
"Here is the value of zmem: %f\n",zmem);
4015 Vnm_print(0,
"Here is the value of mdie: %f\n",eps_m);
4016 Vnm_print(0,
"Here is the value of memv: %f\n",V);
4034 G=l*eps_w/eps_m*xkappa;
4035 A=-V/2*(1/(G+1))*exp(xkappa*l);
4037 C=-V/2*eps_w/eps_m*xkappa*(1/(G+1));
4044 for (k=0; k<nz; k++) {
4046 z_rel = gpos[2] - z_0;
4048 for (j=0; j<ny; j++) {
4050 if (gpos[2] <= z_low) {
4052 val = A*exp(xkappa*z_rel) + V;
4053 gxcf[IJKx(j,k,0)] += val;
4054 gxcf[IJKx(j,k,1)] += val;
4058 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4061 gxcf[IJKx(j,k,0)] += val;
4062 gxcf[IJKx(j,k,1)] += val;
4066 else if (gpos[2] > z_high) {
4068 val = D*exp(-xkappa*z_rel);
4069 gxcf[IJKx(j,k,0)] += val;
4070 gxcf[IJKx(j,k,1)] += val;
4078 for (k=0; k<nz; k++) {
4080 z_rel = gpos[2] - z_0;
4081 for (i=0; i<nx; i++) {
4083 if (gpos[2] <= z_low) {
4085 val = A*exp(xkappa*z_rel) + V;
4086 gycf[IJKy(i,k,0)] += val;
4087 gycf[IJKy(i,k,1)] += val;
4092 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4095 gycf[IJKy(i,k,0)] += val;
4096 gycf[IJKy(i,k,1)] += val;
4100 else if (gpos[2] > z_high) {
4102 val = D*exp(-xkappa*z_rel);
4103 gycf[IJKy(i,k,0)] += val;
4104 gycf[IJKy(i,k,1)] += val;
4113 for (j=0; j<ny; j++) {
4114 for (i=0; i<nx; i++) {
4119 z_rel = gpos[2] - z_0;
4121 if (gpos[2] <= z_low) {
4123 val = A*exp(xkappa*z_rel) + V;
4124 gzcf[IJKz(i,j,0)] += val;
4129 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4132 gzcf[IJKz(i,j,0)] += val;
4136 else if (gpos[2] > z_high) {
4138 val = D*exp(-xkappa*z_rel);
4139 gzcf[IJKz(i,j,0)] += val;
4146 z_rel = gpos[2] - z_0;
4148 if (gpos[2] <= z_low) {
4150 val = A*exp(xkappa*z_rel) + V;
4151 gzcf[IJKz(i,j,1)] += val;
4155 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4158 gzcf[IJKz(i,j,1)] += val;
4162 else if (gpos[2] > z_high) {
4164 val = D*exp(-xkappa*z_rel);
4165 gzcf[IJKz(i,j,1)] += val;
4174VPRIVATE
void bcfl_map(
Vpmg *thee){
4177 double position[3], pot, hx, hy, hzed;
4178 int i, j, k, nx, ny, nz, rc;
4181 VASSERT(thee != VNULL);
4192 for (i=0; i<(nx*ny*nz); i++) thee->
pot[i] = 0.0;
4195 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
4196 for (k=0; k<nz; k++) {
4197 for (j=0; j<ny; j++) {
4198 for (i=0; i<nx; i++) {
4199 position[0] = thee->
xf[i];
4200 position[1] = thee->
yf[j];
4201 position[2] = thee->
zf[k];
4204 Vnm_print(2,
"fillcoChargeMap: Error -- fell off of potential map at (%g, %g, %g)!\n",
4205 position[0], position[1], position[2]);
4208 thee->
pot[IJK(i,j,k)] = pot;
4215#if defined(WITH_TINKER)
4216VPRIVATE
void bcfl_mdh_tinker(
Vpmg *thee){
4221 double val, *apos, gpos[3], tensor[9];
4222 double *dipole, *quadrupole;
4223 double size, charge, xkappa, eps_w, eps_p, T, pre1, dist;
4225 double ux,uy,uz,xr,yr,zr;
4226 double qxx,qxy,qxz,qyx,qyy,qyz,qzx,qzy,qzz;
4228 double *xf, *yf, *zf;
4229 double *gxcf, *gycf, *gzcf;
4269 pre1 = pre1*(1.0e10);
4282 if(gridPointIsValid(i, j, k, nx, ny, nz)){
4298 dipole = Vatom_getDipole(atom);
4299 quadrupole = Vatom_getQuadrupole(atom);
4301 dipole = Vatom_getInducedDipole(atom);
4303 dipole = Vatom_getNLInducedDipole(atom);
4310 if (quadrupole != VNULL) {
4315 qxx = quadrupole[0] / 3.0;
4316 qxy = quadrupole[1] / 3.0;
4317 qxz = quadrupole[2] / 3.0;
4318 qyx = quadrupole[3] / 3.0;
4319 qyy = quadrupole[4] / 3.0;
4320 qyz = quadrupole[5] / 3.0;
4321 qzx = quadrupole[6] / 3.0;
4322 qzy = quadrupole[7] / 3.0;
4323 qzz = quadrupole[8] / 3.0;
4336 xr = gpos[0] - apos[0];
4337 yr = gpos[1] - apos[1];
4338 zr = gpos[2] - apos[2];
4340 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
4341 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
4343 val += pre1*charge*tensor[0];
4344 val -= pre1*ux*xr*tensor[1];
4345 val -= pre1*uy*yr*tensor[1];
4346 val -= pre1*uz*zr*tensor[1];
4347 val += pre1*qxx*xr*xr*tensor[2];
4348 val += pre1*qyy*yr*yr*tensor[2];
4349 val += pre1*qzz*zr*zr*tensor[2];
4350 val += pre1*2.0*qxy*xr*yr*tensor[2];
4351 val += pre1*2.0*qxz*xr*zr*tensor[2];
4352 val += pre1*2.0*qyz*yr*zr*tensor[2];
4357 gxcf[IJKx(j,k,0)] = val;
4360 gxcf[IJKx(j,k,1)] = val;
4363 gycf[IJKy(i,k,0)] = val;
4366 gycf[IJKy(i,k,1)] = val;
4369 gzcf[IJKz(i,j,0)] = val;
4372 gzcf[IJKz(i,j,1)] = val;
4387 double zmem, eps_m, Lmem, memv, eps_w, xkappa;
4395 for (k=0; k<nz; k++) {
4396 for (j=0; j<ny; j++) {
4397 thee->
gxcf[IJKx(j,k,0)] = 0.0;
4398 thee->
gxcf[IJKx(j,k,1)] = 0.0;
4399 thee->
gxcf[IJKx(j,k,2)] = 0.0;
4400 thee->
gxcf[IJKx(j,k,3)] = 0.0;
4405 for (k=0; k<nz; k++) {
4406 for (i=0; i<nx; i++) {
4407 thee->
gycf[IJKy(i,k,0)] = 0.0;
4408 thee->
gycf[IJKy(i,k,1)] = 0.0;
4409 thee->
gycf[IJKy(i,k,2)] = 0.0;
4410 thee->
gycf[IJKy(i,k,3)] = 0.0;
4415 for (j=0; j<ny; j++) {
4416 for (i=0; i<nx; i++) {
4417 thee->
gzcf[IJKz(i,j,0)] = 0.0;
4418 thee->
gzcf[IJKz(i,j,1)] = 0.0;
4419 thee->
gzcf[IJKz(i,j,2)] = 0.0;
4420 thee->
gzcf[IJKz(i,j,3)] = 0.0;
4432#if defined(WITH_TINKER)
4433 bcfl_mdh_tinker(thee);
4436#ifdef DEBUG_MAC_OSX_OCL
4437#include "mach_chud.h"
4438 uint64_t mbeg = mach_absolute_time();
4444 if (kOpenCLAvailable == 1) bcflnewOpenCL(thee);
4447 mets_(&mbeg,
"MDH");
4465 bcfl_mem(zmem, Lmem, eps_m, eps_w, memv, xkappa,
4467 thee->
xf, thee->
yf, thee->
zf, nx, ny, nz);
4470 Vnm_print(2,
"bcCalc: Invalid bcfl (%d)!\n", thee->
pmgp->
bcfl);
4474 Vnm_print(2,
"VPMG::bcCalc -- not appropriate for focusing!\n");
4479 focusFillBound(thee,VNULL);
4482 Vnm_print(2,
"VPMG::bcCalc -- invalid boundary condition \
4492 double ionstr, position[3], tkappa, eps, pot, hx, hy, hzed;
4493 int i, j, k, nx, ny, nz;
4495 VASSERT(thee != VNULL);
4512 Vnm_print(2,
"fillcoCoefMap: You need to use all coefficient maps!\n");
4521 for (k=0; k<nz; k++) {
4522 for (j=0; j<ny; j++) {
4523 for (i=0; i<nx; i++) {
4525 position[0] = thee->
xf[i];
4526 position[1] = thee->
yf[j];
4527 position[2] = thee->
zf[k];
4529 Vnm_print(2,
"Vpmg_fillco: Off kappaMap at:\n");
4530 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4531 position[0], position[1], position[2]);
4534 if (tkappa > kappamax) {
4538 Vnm_print(2,
"Vpmg_fillcoCoefMap: Kappa map less than 0\n");
4539 Vnm_print(2,
"Vpmg_fillcoCoefMap: at (x,y,z) = (%g,%g %g)\n",
4540 position[0], position[1], position[2]);
4548 if (kappamax > 1.0){
4549 Vnm_print(2,
"Vpmg_fillcoCoefMap: Maximum Kappa value\n");
4550 Vnm_print(2,
"%g is greater than 1 - will scale appropriately!\n",
4557 for (k=0; k<nz; k++) {
4558 for (j=0; j<ny; j++) {
4559 for (i=0; i<nx; i++) {
4562 position[0] = thee->
xf[i];
4563 position[1] = thee->
yf[j];
4564 position[2] = thee->
zf[k];
4566 Vnm_print(2,
"Vpmg_fillco: Off kappaMap at:\n");
4567 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4568 position[0], position[1], position[2]);
4572 thee->
kappa[IJK(i,j,k)] = (tkappa / kappamax);
4575 position[0] = thee->
xf[i] + 0.5*hx;
4576 position[1] = thee->
yf[j];
4577 position[2] = thee->
zf[k];
4579 Vnm_print(2,
"Vpmg_fillco: Off dielXMap at:\n");
4580 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4581 position[0], position[1], position[2]);
4584 thee->
epsx[IJK(i,j,k)] = eps;
4586 position[0] = thee->
xf[i];
4587 position[1] = thee->
yf[j] + 0.5*hy;
4588 position[2] = thee->
zf[k];
4590 Vnm_print(2,
"Vpmg_fillco: Off dielYMap at:\n");
4591 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4592 position[0], position[1], position[2]);
4595 thee->
epsy[IJK(i,j,k)] = eps;
4597 position[0] = thee->
xf[i];
4598 position[1] = thee->
yf[j];
4599 position[2] = thee->
zf[k] + 0.5*hzed;
4601 Vnm_print(2,
"Vpmg_fillco: Off dielZMap at:\n");
4602 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4603 position[0], position[1], position[2]);
4606 thee->
epsz[IJK(i,j,k)] = eps;
4634 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr;
4635 double xlen, ylen, zlen, irad;
4636 double hx, hy, hzed, *apos, arad;
4637 int i, nx, ny, nz, iatom;
4640 VASSERT(thee != VNULL);
4679 for (i=0; i<(nx*ny*nz); i++) thee->
kappa[i] = ionmask;
4691 if (arad > VSMALL) {
4694 if ((apos[0]<(xmin-irad-arad)) || (apos[0]>(xmax+irad+arad)) || \
4695 (apos[1]<(ymin-irad-arad)) || (apos[1]>(ymax+irad+arad)) || \
4696 (apos[2]<(zmin-irad-arad)) || (apos[2]>(zmax+irad+arad))) {
4700 "Vpmg_fillco: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
4701 iatom, apos[0], apos[1], apos[2]);
4702 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
4704 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
4706 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
4744 double xmin, xmax, ymin, ymax, zmin, zmax;
4745 double xlen, ylen, zlen, position[3];
4746 double srad, epsw, epsp, deps, area;
4747 double hx, hy, hzed, *apos, arad;
4748 int i, nx, ny, nz, ntot, iatom, ipt;
4781 for (i=0; i<ntot; i++) {
4782 thee->
epsx[i] = epsw;
4783 thee->
epsy[i] = epsw;
4784 thee->
epsz[i] = epsw;
4789#pragma omp parallel for default(shared) private(iatom,atom,apos,arad)
4797 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
4798 (apos[1]<=ymin) || (apos[1]>=ymax) || \
4799 (apos[2]<=zmin) || (apos[2]>=zmax)) {
4802 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\
4803 %4.3f) is off the mesh (ignoring):\n",
4804 iatom, apos[0], apos[1], apos[2]);
4805 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
4807 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
4809 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
4816 if (arad > VSMALL) {
4821 (xmin+0.5*hx), ymin, zmin,
4828 xmin, (ymin+0.5*hy), zmin,
4835 xmin, ymin, (zmin+0.5*hzed),
4845 if (srad > VSMALL) {
4849#pragma omp parallel for default(shared) private(iatom,atom,area,asurf,ipt,position)
4858 for (ipt=0; ipt<(asurf->
npts); ipt++) {
4860 position[0] = asurf->
xpts[ipt];
4861 position[1] = asurf->
ypts[ipt];
4862 position[2] = asurf->
zpts[ipt];
4868 (xmin+0.5*hx), ymin, zmin,
4875 xmin, (ymin+0.5*hy), zmin,
4882 xmin, ymin, (zmin+0.5*hzed),
4903 int i, j, k, nx, ny, nz, numpts;
4914 for (i=0; i<(nx*ny*nz); i++) {
4918 thee->
epsx[i] = epsw;
4919 thee->
epsy[i] = epsw;
4920 thee->
epsz[i] = epsw;
4924 for (i=0; i<nx; i++) {
4925 for (j=0; j<ny; j++) {
4926 for (k=0; k<nz; k++) {
4931 frac = 1.0/thee->
a1cf[IJK(i,j,k)];
4932 frac += 1.0/thee->
a2cf[IJK(i,j,k)];
4933 frac += 1.0/thee->
a3cf[IJK(i,j,k)];
4937 frac += 1.0/thee->
a2cf[IJK(i,j-1,k)];
4941 frac += 1.0/thee->
a3cf[IJK(i,j,k-1)];
4945 frac += 1.0/thee->
a2cf[IJK(i+1,j,k)];
4946 frac += 1.0/thee->
a3cf[IJK(i+1,j,k)];
4949 frac += 1.0/thee->
a2cf[IJK(i+1,j-1,k)];
4953 frac += 1.0/thee->
a3cf[IJK(i+1,j,k-1)];
4957 thee->
epsx[IJK(i,j,k)] = numpts/frac;
4960 frac = 1.0/thee->
a2cf[IJK(i,j,k)];
4961 frac += 1.0/thee->
a1cf[IJK(i,j,k)];
4962 frac += 1.0/thee->
a3cf[IJK(i,j,k)];
4966 frac += 1.0/thee->
a1cf[IJK(i-1,j,k)];
4970 frac += 1.0/thee->
a3cf[IJK(i,j,k-1)];
4974 frac += 1.0/thee->
a1cf[IJK(i,j+1,k)];
4975 frac += 1.0/thee->
a3cf[IJK(i,j+1,k)];
4978 frac += 1.0/thee->
a1cf[IJK(i-1,j+1,k)];
4982 frac += 1.0/thee->
a3cf[IJK(i,j+1,k-1)];
4986 thee->
epsy[IJK(i,j,k)] = numpts/frac;
4989 frac = 1.0/thee->
a3cf[IJK(i,j,k)];
4990 frac += 1.0/thee->
a1cf[IJK(i,j,k)];
4991 frac += 1.0/thee->
a2cf[IJK(i,j,k)];
4995 frac += 1.0/thee->
a1cf[IJK(i-1,j,k)];
4999 frac += 1.0/thee->
a2cf[IJK(i,j-1,k)];
5003 frac += 1.0/thee->
a1cf[IJK(i,j,k+1)];
5004 frac += 1.0/thee->
a2cf[IJK(i,j,k+1)];
5007 frac += 1.0/thee->
a1cf[IJK(i-1,j,k+1)];
5011 frac += 1.0/thee->
a2cf[IJK(i,j-1,k+1)];
5015 thee->
epsz[IJK(i,j,k)] = numpts/frac;
5027 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr, dist2;
5028 double xlen, ylen, zlen, position[3], itot, stot, ictot, ictot2, sctot;
5029 double irad, dx, dy, dz, epsw, epsp, w2i;
5030 double hx, hy, hzed, *apos, arad, sctot2;
5031 double dx2, dy2, dz2, stot2, itot2, rtot, rtot2, splineWin, w3i;
5032 double dist, value, sm, sm2;
5033 int i, j, k, nx, ny, nz, iatom;
5034 int imin, imax, jmin, jmax, kmin, kmax;
5036 VASSERT(thee != VNULL);
5038 w2i = 1.0/(splineWin*splineWin);
5039 w3i = 1.0/(splineWin*splineWin*splineWin);
5078 for (i=0; i<(nx*ny*nz); i++) {
5079 thee->
kappa[i] = 1.0;
5080 thee->
epsx[i] = 1.0;
5081 thee->
epsy[i] = 1.0;
5082 thee->
epsz[i] = 1.0;
5093 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
5094 (apos[1]<=ymin) || (apos[1]>=ymax) || \
5095 (apos[2]<=zmin) || (apos[2]>=zmax)) {
5098 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\
5099 %4.3f) is off the mesh (ignoring):\n",
5100 iatom, apos[0], apos[1], apos[2]);
5101 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
5103 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
5105 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
5113 position[0] = apos[0] - xmin;
5114 position[1] = apos[1] - ymin;
5115 position[2] = apos[2] - zmin;
5119 itot = irad + arad + splineWin;
5121 ictot = VMAX2(0, (irad + arad - splineWin));
5122 ictot2 = VSQR(ictot);
5123 stot = arad + splineWin;
5125 sctot = VMAX2(0, (arad - splineWin));
5126 sctot2 = VSQR(sctot);
5130 rtot = VMAX2(itot, stot);
5131 rtot2 = VMAX2(itot2, stot2);
5134 dz = rtot + 0.5*hzed;
5135 imin = VMAX2(0,(
int)floor((position[0] - dx)/hx));
5136 imax = VMIN2(nx-1,(
int)ceil((position[0] + dx)/hx));
5137 jmin = VMAX2(0,(
int)floor((position[1] - dy)/hy));
5138 jmax = VMIN2(ny-1,(
int)ceil((position[1] + dy)/hy));
5139 kmin = VMAX2(0,(
int)floor((position[2] - dz)/hzed));
5140 kmax = VMIN2(nz-1,(
int)ceil((position[2] + dz)/hzed));
5141 for (i=imin; i<=imax; i++) {
5142 dx2 = VSQR(position[0] - hx*i);
5143 for (j=jmin; j<=jmax; j++) {
5144 dy2 = VSQR(position[1] - hy*j);
5145 for (k=kmin; k<=kmax; k++) {
5146 dz2 = VSQR(position[2] - k*hzed);
5150 dist2 = dz2 + dy2 + dx2;
5151 if (dist2 >= itot2) {
5154 if (dist2 <= ictot2) {
5155 thee->
kappa[IJK(i,j,k)] = 0.0;
5157 if ((dist2 < itot2) && (dist2 > ictot2)) {
5158 dist = VSQRT(dist2);
5159 sm = dist - (arad + irad) + splineWin;
5161 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5162 thee->
kappa[IJK(i,j,k)] *= value;
5168 dist2 = dz2+dy2+VSQR(position[0]-(i+0.5)*hx);
5169 if (dist2 >= stot2) {
5170 thee->
epsx[IJK(i,j,k)] *= 1.0;
5172 if (dist2 <= sctot2) {
5173 thee->
epsx[IJK(i,j,k)] = 0.0;
5175 if ((dist2 > sctot2) && (dist2 < stot2)) {
5176 dist = VSQRT(dist2);
5177 sm = dist - arad + splineWin;
5179 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5180 thee->
epsx[IJK(i,j,k)] *= value;
5186 dist2 = dz2+dx2+VSQR(position[1]-(j+0.5)*hy);
5187 if (dist2 >= stot2) {
5188 thee->
epsy[IJK(i,j,k)] *= 1.0;
5190 if (dist2 <= sctot2) {
5191 thee->
epsy[IJK(i,j,k)] = 0.0;
5193 if ((dist2 > sctot2) && (dist2 < stot2)) {
5194 dist = VSQRT(dist2);
5195 sm = dist - arad + splineWin;
5197 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5198 thee->
epsy[IJK(i,j,k)] *= value;
5204 dist2 = dy2+dx2+VSQR(position[2]-(k+0.5)*hzed);
5205 if (dist2 >= stot2) {
5206 thee->
epsz[IJK(i,j,k)] *= 1.0;
5208 if (dist2 <= sctot2) {
5209 thee->
epsz[IJK(i,j,k)] = 0.0;
5211 if ((dist2 > sctot2) && (dist2 < stot2)) {
5212 dist = VSQRT(dist2);
5213 sm = dist - arad + splineWin;
5215 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5216 thee->
epsz[IJK(i,j,k)] *= value;
5227 Vnm_print(0,
"Vpmg_fillco: filling coefficient arrays\n");
5229 for (k=0; k<nz; k++) {
5230 for (j=0; j<ny; j++) {
5231 for (i=0; i<nx; i++) {
5233 thee->
kappa[IJK(i,j,k)] = ionmask*thee->
kappa[IJK(i,j,k)];
5234 thee->
epsx[IJK(i,j,k)] = (epsw-epsp)*thee->
epsx[IJK(i,j,k)]
5236 thee->
epsy[IJK(i,j,k)] = (epsw-epsp)*thee->
epsy[IJK(i,j,k)]
5238 thee->
epsz[IJK(i,j,k)] = (epsw-epsp)*thee->
epsz[IJK(i,j,k)]
5249 VASSERT(thee != VNULL);
5259 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefMol...\n");
5263 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefMol...\n");
5267 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefSpline...\n");
5271 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefSpline3...\n");
5275 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefSpline4...\n");
5279 Vnm_print(2,
"fillcoCoef: Invalid surfMeth (%d)!\n",
5291 VASSERT(thee != VNULL);
5299 Vnm_print(0,
"fillcoCharge: Calling fillcoChargeSpline1...\n");
5303 Vnm_print(0,
"fillcoCharge: Calling fillcoChargeSpline2...\n");
5309 Vnm_print(0,
"fillcoCharge: Calling fillcoPermanentMultipole...\n");
5312#if defined(WITH_TINKER)
5314 Vnm_print(0,
"fillcoCharge: Calling fillcoPermanentMultipole...\n");
5318 Vnm_print(0,
"fillcoCharge: Calling fillcoInducedDipole...\n");
5322 Vnm_print(0,
"fillcoCharge: Calling fillcoNLInducedDipole...\n");
5327 Vnm_print(2,
"fillcoCharge: Invalid chargeSource (%d)!\n",
5334 Vnm_print(2,
"fillcoCharge: Invalid chargeMeth (%d)!\n",
5346 double position[3], charge, zmagic, hx, hy, hzed;
5347 int i, j, k, nx, ny, nz, rc;
5350 VASSERT(thee != VNULL);
5365 for (i=0; i<(nx*ny*nz); i++) thee->
charge[i] = 0.0;
5368 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5369 for (k=0; k<nz; k++) {
5370 for (j=0; j<ny; j++) {
5371 for (i=0; i<nx; i++) {
5372 position[0] = thee->
xf[i];
5373 position[1] = thee->
yf[j];
5374 position[2] = thee->
zf[k];
5377 Vnm_print(2,
"fillcoChargeMap: Error -- fell off of charge map at (%g, %g, %g)!\n",
5378 position[0], position[1], position[2]);
5382 charge = charge*zmagic;
5383 thee->
charge[IJK(i,j,k)] = charge;
5396 double xmin, xmax, ymin, ymax, zmin, zmax;
5397 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
5398 double charge, dx, dy, dz, zmagic, hx, hy, hzed, *apos;
5399 int i, nx, ny, nz, iatom, ihi, ilo, jhi, jlo, khi, klo;
5402 VASSERT(thee != VNULL);
5431 for (i=0; i<(nx*ny*nz); i++) thee->
charge[i] = 0.0;
5434 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5442 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
5443 (apos[1]<=ymin) || (apos[1]>=ymax) || \
5444 (apos[2]<=zmin) || (apos[2]>=zmax)) {
5447 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f, \
5448%4.3f) is off the mesh (ignoring):\n",
5449 iatom, apos[0], apos[1], apos[2]);
5450 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
5452 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
5454 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
5461 position[0] = apos[0] - xmin;
5462 position[1] = apos[1] - ymin;
5463 position[2] = apos[2] - zmin;
5466 charge = charge*zmagic/(hx*hy*hzed);
5469 ifloat = position[0]/hx;
5470 jfloat = position[1]/hy;
5471 kfloat = position[2]/hzed;
5473 ihi = (int)ceil(ifloat);
5474 ilo = (int)floor(ifloat);
5475 jhi = (int)ceil(jfloat);
5476 jlo = (int)floor(jfloat);
5477 khi = (int)ceil(kfloat);
5478 klo = (int)floor(kfloat);
5481 dx = ifloat - (double)(ilo);
5482 dy = jfloat - (double)(jlo);
5483 dz = kfloat - (double)(klo);
5484 thee->
charge[IJK(ihi,jhi,khi)] += (dx*dy*dz*charge);
5485 thee->
charge[IJK(ihi,jlo,khi)] += (dx*(1.0-dy)*dz*charge);
5486 thee->
charge[IJK(ihi,jhi,klo)] += (dx*dy*(1.0-dz)*charge);
5487 thee->
charge[IJK(ihi,jlo,klo)] += (dx*(1.0-dy)*(1.0-dz)*charge);
5488 thee->
charge[IJK(ilo,jhi,khi)] += ((1.0-dx)*dy*dz *charge);
5489 thee->
charge[IJK(ilo,jlo,khi)] += ((1.0-dx)*(1.0-dy)*dz *charge);
5490 thee->
charge[IJK(ilo,jhi,klo)] += ((1.0-dx)*dy*(1.0-dz)*charge);
5491 thee->
charge[IJK(ilo,jlo,klo)] += ((1.0-dx)*(1.0-dy)*(1.0-dz)*charge);
5500 if ((x >= 0.0) && (x <= 2.0)) m2m = 1.0 - VABS(x - 1.0);
5502 if ((x >= 1.0) && (x <= 3.0)) m2 = 1.0 - VABS(x - 2.0);
5505 if ((x >= 0.0) && (x <= 3.0)) m3 = 0.5*x*m2m + 0.5*(3.0-x)*m2;
5514 double m2m, m2, dm3;
5516 if ((x >= 0.0) && (x <= 2.0)) m2m = 1.0 - VABS(x - 1.0);
5518 if ((x >= 1.0) && (x <= 3.0)) m2 = 1.0 - VABS(x - 2.0);
5533 double xmin, xmax, ymin, ymax, zmin, zmax, zmagic;
5534 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
5535 double charge, hx, hy, hzed, *apos, mx, my, mz;
5536 int i, ii, jj, kk, nx, ny, nz, iatom;
5537 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
5540 VASSERT(thee != VNULL);
5569 for (i=0; i<(nx*ny*nz); i++) thee->
charge[i] = 0.0;
5572 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5580 if ((apos[0]<=(xmin-hx)) || (apos[0]>=(xmax+hx)) || \
5581 (apos[1]<=(ymin-hy)) || (apos[1]>=(ymax+hy)) || \
5582 (apos[2]<=(zmin-hzed)) || (apos[2]>=(zmax+hzed))) {
5585 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f, \
5586%4.3f) is off the mesh (for cubic splines!!) (ignoring this atom):\n",
5587 iatom, apos[0], apos[1], apos[2]);
5588 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
5590 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
5592 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
5599 position[0] = apos[0] - xmin;
5600 position[1] = apos[1] - ymin;
5601 position[2] = apos[2] - zmin;
5604 charge = charge*zmagic/(hx*hy*hzed);
5607 ifloat = position[0]/hx;
5608 jfloat = position[1]/hy;
5609 kfloat = position[2]/hzed;
5611 ip1 = (int)ceil(ifloat);
5613 im1 = (int)floor(ifloat);
5615 jp1 = (int)ceil(jfloat);
5617 jm1 = (int)floor(jfloat);
5619 kp1 = (int)ceil(kfloat);
5621 km1 = (int)floor(kfloat);
5626 ip2 = VMIN2(ip2,nx-1);
5627 ip1 = VMIN2(ip1,nx-1);
5630 jp2 = VMIN2(jp2,ny-1);
5631 jp1 = VMIN2(jp1,ny-1);
5634 kp2 = VMIN2(kp2,nz-1);
5635 kp1 = VMIN2(kp1,nz-1);
5640 for (ii=im2; ii<=ip2; ii++) {
5642 for (jj=jm2; jj<=jp2; jj++) {
5644 for (kk=km2; kk<=kp2; kk++) {
5646 thee->
charge[IJK(ii,jj,kk)] += (charge*mx*my*mz);
5696 if (thee == VNULL) {
5697 Vnm_print(2,
"Vpmg_fillco: got NULL thee!\n");
5749 thee->
rparm[2] = xmin;
5750 thee->
rparm[3] = xmax;
5751 thee->
rparm[4] = ymin;
5752 thee->
rparm[5] = ymax;
5753 thee->
rparm[6] = zmin;
5754 thee->
rparm[7] = zmax;
5769 for (i=0; i<nx; i++) thee->
xf[i] = xmin + i*hx;
5770 for (i=0; i<ny; i++) thee->
yf[i] = ymin + i*hy;
5771 for (i=0; i<nz; i++) thee->
zf[i] = zmin + i*hzed;
5774 for (i=0; i<(nx*ny*nz); i++) thee->
tcf[i] = 0.0;
5777 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5783 Vnm_print(2,
"Vpmg_fillco: non-fatal errors while filling charge map!\n");
5786 Vnm_print(2,
"Vpmg_fillco: fatal errors while filling charge map!\n");
5794 Vnm_print(0,
"Vpmg_fillco: marking ion and solvent accessibility.\n");
5796 Vnm_print(0,
"Vpmg_fillco: done filling coefficient arrays\n");
5800 for (i=0; i<(nx*ny*nz); i++) {
5801 thee->
kappa[i] = 0.0;
5802 thee->
epsx[i] = epsp;
5803 thee->
epsy[i] = epsp;
5804 thee->
epsz[i] = epsp;
5811 Vnm_print(0,
"Vpmg_fillco: filling boundary arrays\n");
5813 Vnm_print(0,
"Vpmg_fillco: done filling boundary arrays\n");
5831 VASSERT(thee != VNULL);
5837 force[0] = qfF[0] + dbF[0] + ibF[0];
5838 force[1] = qfF[1] + dbF[1] + ibF[1];
5839 force[2] = qfF[2] + dbF[2] + ibF[2];
5853 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
5854 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
5855 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
5857 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
5860 int ichop, nchop, nion, m;
5863 VASSERT(thee != VNULL);
5877 Vnm_print(2,
"Vpmg_ibForce: Forces *must* be calculated with \
5878spline-based surfaces!\n");
5879 Vnm_print(2,
"Vpmg_ibForce: Skipping ionic boundary force \
5885 if (atom->
partID == 0)
return 1;
5918 Vnm_print(2,
"Vpmg_ibForce: No force for zero ionic strength!\n");
5924 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
5925 (apos[1]<=ymin) || (apos[1]>=ymax) || \
5926 (apos[2]<=zmin) || (apos[2]>=zmax)) {
5929 Vnm_print(2,
"Vpmg_ibForce: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
5930 atom, apos[0], apos[1], apos[2]);
5931 Vnm_print(2,
"Vpmg_ibForce: xmin = %g, xmax = %g\n",
5933 Vnm_print(2,
"Vpmg_ibForce: ymin = %g, ymax = %g\n",
5935 Vnm_print(2,
"Vpmg_ibForce: zmin = %g, zmax = %g\n",
5942 position[0] = apos[0] - xmin;
5943 position[1] = apos[1] - ymin;
5944 position[2] = apos[2] - zmin;
5950 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
5951 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
5952 for (i=imin; i<=imax; i++) {
5953 dx2 = VSQR(position[0] - hx*i);
5954 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
5956 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
5957 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
5958 for (j=jmin; j<=jmax; j++) {
5959 dy2 = VSQR(position[1] - hy*j);
5960 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
5962 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
5963 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
5964 for (k=kmin; k<=kmax; k++) {
5965 dz2 = VSQR(k*hzed - position[2]);
5968 if ((dz2 + dy2 + dx2) <= rtot2) {
5969 gpos[0] = i*hx + xmin;
5970 gpos[1] = j*hy + ymin;
5971 gpos[2] = k*hzed + zmin;
5981 for (m=0; m<nion; m++) {
5982 fmag += (thee->
kappa[IJK(i,j,k)])*ionConc[m]*(
Vcap_exp(-ionQ[m]*thee->
u[IJK(i,j,k)], &ichop)-1.0)/ionstr;
5986 force[0] += (zkappa2*fmag*tgrad[0]);
5987 force[1] += (zkappa2*fmag*tgrad[1]);
5988 force[2] += (zkappa2*fmag*tgrad[2]);
5993 fmag = VSQR(thee->
u[IJK(i,j,k)])*(thee->
kappa[IJK(i,j,k)]);
5994 force[0] += (zkappa2*fmag*tgrad[0]);
5995 force[1] += (zkappa2*fmag*tgrad[1]);
5996 force[2] += (zkappa2*fmag*tgrad[2]);
6003 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
6004 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
6005 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
6017 double *apos, position[3], arad, srad, hx, hy, hzed, izmagic, deps, depsi;
6018 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
6019 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
6020 double *u, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
6021 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
6023 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
6025 VASSERT(thee != VNULL);
6027 Vnm_print(2,
"Vpmg_dbForce: Need to callVpmg_fillco!\n");
6044 Vnm_print(2,
"Vpmg_dbForce: Forces *must* be calculated with \
6045spline-based surfaces!\n");
6046 Vnm_print(2,
"Vpmg_dbForce: Skipping dielectric/apolar boundary \
6047force calculation!\n");
6053 if (atom->
partID == 0)
return 1;
6083 Vnm_print(0,
"Vpmg_dbForce: No force for uniform dielectric!\n");
6086 deps = (epsw - epsp);
6092 if ((apos[0]<=xmin + rtot) || (apos[0]>=xmax - rtot) || \
6093 (apos[1]<=ymin + rtot) || (apos[1]>=ymax - rtot) || \
6094 (apos[2]<=zmin + rtot) || (apos[2]>=zmax - rtot)) {
6097 Vnm_print(2,
"Vpmg_dbForce: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
6098 atomID, apos[0], apos[1], apos[2]);
6099 Vnm_print(2,
"Vpmg_dbForce: xmin = %g, xmax = %g\n",
6101 Vnm_print(2,
"Vpmg_dbForce: ymin = %g, ymax = %g\n",
6103 Vnm_print(2,
"Vpmg_dbForce: zmin = %g, zmax = %g\n",
6110 position[0] = apos[0] - xmin;
6111 position[1] = apos[1] - ymin;
6112 position[2] = apos[2] - zmin;
6117 imin = (int)floor((position[0]-rtot)/hx);
6119 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6122 imax = (int)ceil((position[0]+rtot)/hx);
6123 if (imax > (nx-2)) {
6124 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6127 jmin = (int)floor((position[1]-rtot)/hy);
6129 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6132 jmax = (int)ceil((position[1]+rtot)/hy);
6133 if (jmax > (ny-2)) {
6134 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6137 kmin = (int)floor((position[2]-rtot)/hzed);
6139 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6142 kmax = (int)ceil((position[2]+rtot)/hzed);
6143 if (kmax > (nz-2)) {
6144 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6147 for (i=imin; i<=imax; i++) {
6148 for (j=jmin; j<=jmax; j++) {
6149 for (k=kmin; k<=kmax; k++) {
6151 gpos[0] = (i+0.5)*hx + xmin;
6152 gpos[1] = j*hy + ymin;
6153 gpos[2] = k*hzed + zmin;
6154 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
6174 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
6175 gpos[0] = i*hx + xmin;
6176 gpos[1] = (j+0.5)*hy + ymin;
6177 gpos[2] = k*hzed + zmin;
6178 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
6184 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
6185 gpos[0] = i*hx + xmin;
6186 gpos[1] = j*hy + ymin;
6187 gpos[2] = (k+0.5)*hzed + zmin;
6188 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
6194 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
6196 gpos[0] = (i-0.5)*hx + xmin;
6197 gpos[1] = j*hy + ymin;
6198 gpos[2] = k*hzed + zmin;
6199 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
6205 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
6207 gpos[0] = i*hx + xmin;
6208 gpos[1] = (j-0.5)*hy + ymin;
6209 gpos[2] = k*hzed + zmin;
6210 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
6216 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
6218 gpos[0] = i*hx + xmin;
6219 gpos[1] = j*hy + ymin;
6220 gpos[2] = (k-0.5)*hzed + zmin;
6221 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
6227 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
6229 dbFmag = u[IJK(i,j,k)];
6231 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
6232 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
6233 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
6234 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
6235 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
6236 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
6238 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
6239 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
6240 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
6241 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
6242 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
6243 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
6245 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
6246 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
6247 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
6248 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
6249 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
6250 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
6251 dbForce[0] += (dbFmag*tgrad[0]);
6252 dbForce[1] += (dbFmag*tgrad[1]);
6253 dbForce[2] += (dbFmag*tgrad[2]);
6259 dbForce[0] = -dbForce[0]*hx*hy*hzed*deps*0.5*izmagic;
6260 dbForce[1] = -dbForce[1]*hx*hy*hzed*deps*0.5*izmagic;
6261 dbForce[2] = -dbForce[2]*hx*hy*hzed*deps*0.5*izmagic;
6279 Vnm_print(2,
"Vpmg_qfForce: It is recommended that forces be \
6280calculated with the\n");
6281 Vnm_print(2,
"Vpmg_qfForce: cubic spline charge discretization \
6296 Vnm_print(2,
"Vpmg_qfForce: Undefined charge discretization \
6297method (%d)!\n", chgm);
6298 Vnm_print(2,
"Vpmg_qfForce: Forces not calculated!\n");
6303 force[0] = tforce[0];
6304 force[1] = tforce[1];
6305 force[2] = tforce[2];
6315 double *apos, position[3], hx, hy, hzed;
6316 double xmin, ymin, zmin, xmax, ymax, zmax;
6318 double *u, charge, ifloat, jfloat, kfloat;
6319 int nx, ny, nz, ihi, ilo, jhi, jlo, khi, klo;
6321 VASSERT(thee != VNULL);
6333 if (atom->
partID == 0)
return;
6351 if ((apos[0]<=xmin) || (apos[0]>=xmax) || (apos[1]<=ymin) || \
6352 (apos[1]>=ymax) || (apos[2]<=zmin) || (apos[2]>=zmax)) {
6355 Vnm_print(2,
"Vpmg_qfForce: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", atomID, apos[0], apos[1], apos[2]);
6356 Vnm_print(2,
"Vpmg_qfForce: xmin = %g, xmax = %g\n", xmin, xmax);
6357 Vnm_print(2,
"Vpmg_qfForce: ymin = %g, ymax = %g\n", ymin, ymax);
6358 Vnm_print(2,
"Vpmg_qfForce: zmin = %g, zmax = %g\n", zmin, zmax);
6364 position[0] = apos[0] - xmin;
6365 position[1] = apos[1] - ymin;
6366 position[2] = apos[2] - zmin;
6367 ifloat = position[0]/hx;
6368 jfloat = position[1]/hy;
6369 kfloat = position[2]/hzed;
6370 ihi = (int)ceil(ifloat);
6371 ilo = (int)floor(ifloat);
6372 jhi = (int)ceil(jfloat);
6373 jlo = (int)floor(jfloat);
6374 khi = (int)ceil(kfloat);
6375 klo = (int)floor(kfloat);
6376 VASSERT((ihi < nx) && (ihi >=0));
6377 VASSERT((ilo < nx) && (ilo >=0));
6378 VASSERT((jhi < ny) && (jhi >=0));
6379 VASSERT((jlo < ny) && (jlo >=0));
6380 VASSERT((khi < nz) && (khi >=0));
6381 VASSERT((klo < nz) && (klo >=0));
6382 dx = ifloat - (double)(ilo);
6383 dy = jfloat - (double)(jlo);
6384 dz = kfloat - (double)(klo);
6388 Vnm_print(1,
"Vpmg_qfForce: (DEBUG) u ~ %g\n",
6389 dx *dy *dz *u[IJK(ihi,jhi,khi)]
6390 +dx *dy *(1-dz)*u[IJK(ihi,jhi,klo)]
6391 +dx *(1-dy)*dz *u[IJK(ihi,jlo,khi)]
6392 +dx *(1-dy)*(1-dz)*u[IJK(ihi,jlo,klo)]
6393 +(1-dx)*dy *dz *u[IJK(ilo,jhi,khi)]
6394 +(1-dx)*dy *(1-dz)*u[IJK(ilo,jhi,klo)]
6395 +(1-dx)*(1-dy)*dz *u[IJK(ilo,jlo,khi)]
6396 +(1-dx)*(1-dy)*(1-dz)*u[IJK(ilo,jlo,klo)]);
6402 -charge*(dy *dz *u[IJK(ihi,jhi,khi)]
6403 + dy *(1-dz)*u[IJK(ihi,jhi,klo)]
6404 + (1-dy)*dz *u[IJK(ihi,jlo,khi)]
6405 + (1-dy)*(1-dz)*u[IJK(ihi,jlo,klo)]
6406 - dy *dz *u[IJK(ilo,jhi,khi)]
6407 - dy *(1-dz)*u[IJK(ilo,jhi,klo)]
6408 - (1-dy)*dz *u[IJK(ilo,jlo,khi)]
6409 - (1-dy)*(1-dz)*u[IJK(ilo,jlo,klo)])/hx;
6413 "Vpmg_qfForce: Atom %d on x gridline; zero x-force\n", atomID);
6417 -charge*(dx *dz *u[IJK(ihi,jhi,khi)]
6418 + dx *(1-dz)*u[IJK(ihi,jhi,klo)]
6419 - dx *dz *u[IJK(ihi,jlo,khi)]
6420 - dx *(1-dz)*u[IJK(ihi,jlo,klo)]
6421 + (1-dx)*dz *u[IJK(ilo,jhi,khi)]
6422 + (1-dx)*(1-dz)*u[IJK(ilo,jhi,klo)]
6423 - (1-dx)*dz *u[IJK(ilo,jlo,khi)]
6424 - (1-dx)*(1-dz)*u[IJK(ilo,jlo,klo)])/hy;
6428 "Vpmg_qfForce: Atom %d on y gridline; zero y-force\n", atomID);
6432 -charge*(dy *dx *u[IJK(ihi,jhi,khi)]
6433 - dy *dx *u[IJK(ihi,jhi,klo)]
6434 + (1-dy)*dx *u[IJK(ihi,jlo,khi)]
6435 - (1-dy)*dx *u[IJK(ihi,jlo,klo)]
6436 + dy *(1-dx)*u[IJK(ilo,jhi,khi)]
6437 - dy *(1-dx)*u[IJK(ilo,jhi,klo)]
6438 + (1-dy)*(1-dx)*u[IJK(ilo,jlo,khi)]
6439 - (1-dy)*(1-dx)*u[IJK(ilo,jlo,klo)])/hzed;
6443 "Vpmg_qfForce: Atom %d on z gridline; zero z-force\n", atomID);
6452 double *apos, position[3], hx, hy, hzed;
6453 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
6454 double mx, my, mz, dmx, dmy, dmz;
6455 double *u, charge, ifloat, jfloat, kfloat;
6456 int nx, ny, nz, im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1;
6457 int kp1, kp2, ii, jj, kk;
6459 VASSERT(thee != VNULL);
6471 if (atom->
partID == 0)
return;
6492 if ((apos[0]<=(xmin+hx)) || (apos[0]>=(xmax-hx)) \
6493 || (apos[1]<=(ymin+hy)) || (apos[1]>=(ymax-hy)) \
6494 || (apos[2]<=(zmin+hzed)) || (apos[2]>=(zmax-hzed))) {
6497 Vnm_print(2,
"qfForceSpline2: Atom #%d off the mesh \
6498 (ignoring)\n", atomID);
6505 position[0] = apos[0] - xmin;
6506 position[1] = apos[1] - ymin;
6507 position[2] = apos[2] - zmin;
6508 ifloat = position[0]/hx;
6509 jfloat = position[1]/hy;
6510 kfloat = position[2]/hzed;
6511 ip1 = (int)ceil(ifloat);
6513 im1 = (int)floor(ifloat);
6515 jp1 = (int)ceil(jfloat);
6517 jm1 = (int)floor(jfloat);
6519 kp1 = (int)ceil(kfloat);
6521 km1 = (int)floor(kfloat);
6526 ip2 = VMIN2(ip2,nx-1);
6527 ip1 = VMIN2(ip1,nx-1);
6530 jp2 = VMIN2(jp2,ny-1);
6531 jp1 = VMIN2(jp1,ny-1);
6534 kp2 = VMIN2(kp2,nz-1);
6535 kp1 = VMIN2(kp1,nz-1);
6540 for (ii=im2; ii<=ip2; ii++) {
6543 for (jj=jm2; jj<=jp2; jj++) {
6546 for (kk=km2; kk<=kp2; kk++) {
6550 force[0] += (charge*dmx*my*mz*u[IJK(ii,jj,kk)])/hx;
6551 force[1] += (charge*mx*dmy*mz*u[IJK(ii,jj,kk)])/hy;
6552 force[2] += (charge*mx*my*dmz*u[IJK(ii,jj,kk)])/hzed;
6564 double f, c, *u, *apos, position[3];
6568 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
6569 double hx, hy, hzed, ifloat, jfloat, kfloat;
6572 double mx, my, mz, dmx, dmy, dmz;
6576 int i, j, k, ii, jj, kk;
6577 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
6582 VASSERT(thee != VNULL);
6612 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
6613 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
6614 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
6615 Vnm_print(2,
"qfForceSpline4: Atom off the mesh \
6616 (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
6621 position[0] = apos[0] - xmin;
6622 position[1] = apos[1] - ymin;
6623 position[2] = apos[2] - zmin;
6624 ifloat = position[0]/hx;
6625 jfloat = position[1]/hy;
6626 kfloat = position[2]/hzed;
6627 ip1 = (int)ceil(ifloat);
6629 im1 = (int)floor(ifloat);
6631 jp1 = (int)ceil(jfloat);
6633 jm1 = (int)floor(jfloat);
6635 kp1 = (int)ceil(kfloat);
6637 km1 = (int)floor(kfloat);
6642 ip2 = VMIN2(ip2,nx-1);
6643 ip1 = VMIN2(ip1,nx-1);
6646 jp2 = VMIN2(jp2,ny-1);
6647 jp1 = VMIN2(jp1,ny-1);
6650 kp2 = VMIN2(kp2,nz-1);
6651 kp1 = VMIN2(kp1,nz-1);
6655 for (ii=im2; ii<=ip2; ii++) {
6659 for (jj=jm2; jj<=jp2; jj++) {
6663 for (kk=km2; kk<=kp2; kk++) {
6667 f = u[IJK(ii,jj,kk)];
6669 e[0] += f*dmx*my*mz/hx;
6670 e[1] += f*mx*dmy*mz/hy;
6671 e[2] += f*mx*my*dmz/hzed;
6684VPRIVATE
void markFrac(
6685 double rtot,
double *tpos,
6686 int nx,
int ny,
int nz,
6687 double hx,
double hy,
double hzed,
6688 double xmin,
double ymin,
double zmin,
6689 double *xarray,
double *yarray,
double *zarray) {
6691 int i, j, k, imin, imax, jmin, jmax, kmin, kmax;
6692 double dx, dx2, dy, dy2, dz, dz2, a000, a001, a010, a100, r2;
6693 double x, xp, xm, y, yp, ym, zp, z, zm, xspan, yspan, zspan;
6694 double rtot2, pos[3];
6697 pos[0] = tpos[0] - xmin;
6698 pos[1] = tpos[1] - ymin;
6699 pos[2] = tpos[2] - zmin;
6703 xspan = rtot + 2*hx;
6704 imin = VMAX2(0, (
int)ceil((pos[0] - xspan)/hx));
6705 imax = VMIN2(nx-1, (
int)floor((pos[0] + xspan)/hx));
6706 for (i=imin; i<=imax; i++) {
6708 dx2 = VSQR(pos[0] - x);
6710 yspan = VSQRT(rtot2 - dx2) + 2*hy;
6714 jmin = VMAX2(0,(
int)ceil((pos[1] - yspan)/hy));
6715 jmax = VMIN2(ny-1,(
int)floor((pos[1] + yspan)/hy));
6716 for (j=jmin; j<=jmax; j++) {
6718 dy2 = VSQR(pos[1] - y);
6719 if (rtot2 > (dx2+dy2)) {
6720 zspan = VSQRT(rtot2-dx2-dy2) + 2*hzed;
6724 kmin = VMAX2(0,(
int)ceil((pos[2] - zspan)/hzed));
6725 kmax = VMIN2(nz-1,(
int)floor((pos[2] + zspan)/hzed));
6726 for (k=kmin; k<=kmax; k++) {
6728 dz2 = VSQR(pos[2] - z);
6730 r2 = dx2 + dy2 + dz2;
6733 if (r2 < rtot2) a000 = 1.0;
6739 if (r2 < (rtot2 - hx*hx)) a100 = 1.0;
6740 else if (r2 > (rtot2 + hx*hx)) a100 = 0.0;
6741 else if (rtot2 > (dy2 + dz2)) {
6742 dx = VSQRT(rtot2 - dy2 - dz2);
6745 if ((xm < x+hx) && (xm > x)) {
6747 }
else if ((xp < x+hx) && (xp > x)) {
6755 if (r2 < (rtot2 - hy*hy)) a010 = 1.0;
6756 else if (r2 > (rtot2 + hy*hy)) a010 = 0.0;
6757 else if (rtot2 > (dx2 + dz2)) {
6758 dy = VSQRT(rtot2 - dx2 - dz2);
6761 if ((ym < y+hy) && (ym > y)) {
6763 }
else if ((yp < y+hy) && (yp > y)) {
6771 if (r2 < (rtot2 - hzed*hzed)) a001 = 1.0;
6772 else if (r2 > (rtot2 + hzed*hzed)) a001 = 0.0;
6773 else if (rtot2 > (dx2 + dy2)) {
6774 dz = VSQRT(rtot2 - dx2 - dy2);
6777 if ((zm < z+hzed) && (zm > z)) {
6778 a001 = (zm - z)/hzed;
6779 }
else if ((zp < z+hzed) && (zp > z)) {
6780 a001 = (zp - z)/hzed;
6784 if (a100 < xarray[IJK(i,j,k)]) xarray[IJK(i,j,k)] = a100;
6785 if (a010 < yarray[IJK(i,j,k)]) yarray[IJK(i,j,k)] = a010;
6786 if (a001 < zarray[IJK(i,j,k)]) zarray[IJK(i,j,k)] = a001;
6850 int nx,
int ny,
int nz,
6851 double hx,
double hy,
double hz,
6852 double xmin,
double ymin,
double zmin,
6853 double *array,
double markVal) {
6860 double dx2, dy2, dz2;
6861 double xrange, yrange, zrange;
6862 double rtot2, posx, posy, posz;
6865 posx = tpos[0] - xmin;
6866 posy = tpos[1] - ymin;
6867 posz = tpos[2] - zmin;
6871 xrange = rtot + 0.5 * hx;
6872 yrange = rtot + 0.5 * hy;
6873 zrange = rtot + 0.5 * hz;
6875 imin = VMAX2(0, (
int)ceil((posx - xrange)/hx));
6876 jmin = VMAX2(0, (
int)ceil((posy - yrange)/hy));
6877 kmin = VMAX2(0, (
int)ceil((posz - zrange)/hz));
6879 imax = VMIN2(nx-1, (
int)floor((posx + xrange)/hx));
6880 jmax = VMIN2(ny-1, (
int)floor((posy + yrange)/hy));
6881 kmax = VMIN2(nz-1, (
int)floor((posz + zrange)/hz));
6883 for (i=imin,fi=imin; i<=imax; i++, fi+=1.) {
6884 dx2 = VSQR(posx - hx*fi);
6885 for (j=jmin,fj=jmin; j<=jmax; j++, fj+=1.) {
6886 dy2 = VSQR(posy - hy*fj);
6887 if((dx2 + dy2) > rtot2)
continue;
6888 for (k=kmin, fk=kmin; k<=kmax; k++, fk+=1.) {
6889 dz2 = VSQR(posz - hz*fk);
6890 if ((dz2 + dy2 + dx2) <= rtot2) {
6891 array[IJK(i,j,k)] = markVal;
6909 int n, nx, ny, nz, i, j, k, kx, ky, kz;
6910 double hx, hy, hzed, wx, wy, wz, xlen, ylen, zlen;
6911 double phix, phixp1, phixm1, phiy, phiym1, phiyp1, phiz, phizm1, phizp1;
6912 double norm, coef, proj, eigx, eigy, eigz;
6913 double ihx2, ihy2, ihzed2;
6914 double *u, *f, *phi;
6926 ihzed2 = 1.0/hzed/hzed;
6937 for (i=0; i<n; i++) thee->
u[i] = 0.0;
6940 for (kx=1; kx<(nx-1); kx++) {
6942 wx = (VPI*(double)kx)/((double)nx - 1.0);
6943 eigx = 2.0*ihx2*(1.0 - cos(wx));
6945 for (ky=1; ky<(ny-1); ky++) {
6947 wy = (VPI*(double)ky)/((double)ny - 1.0);
6948 eigy = 2.0*ihy2*(1.0 - cos(wy));
6950 for (kz=1; kz<(nz-1); kz++) {
6952 wz = (VPI*(double)kz)/((double)nz - 1.0);
6953 eigz = 2.0*ihzed2*(1.0 - cos(wz));
6964 for (i=1; i<(nx-1); i++) {
6966 phix = sin(wx*(
double)i);
6969 phixp1 = (2.0-hx*hx*eigx)*phix - phixm1;
6974 for (j=1; j<(ny-1); j++) {
6976 phiy = sin(wy*(
double)j);
6979 phiyp1 = (2.0-hy*hy*eigy)*phiy - phiym1;
6984 for (k=1; k<(nz-1); k++) {
6986 phiz = sin(wz*(
double)k);
6989 phizp1 = (2.0-hzed*hzed*eigz)*phiz - phizm1;
6995 phi[IJK(i,j,k)] = phix*phiy*phiz;
7004 for (i=1; i<(nx-1); i++) {
7005 for (j=1; j<(ny-1); j++) {
7006 for (k=1; k<(nz-1); k++) {
7008 proj += f[IJK(i,j,k)]*phi[IJK(i,j,k)];
7019 coef = coef/(eigx + eigy + eigz);
7021 coef = (8.0/xlen/ylen/zlen)*coef;
7026 for (i=1; i<(nx-1); i++) {
7027 for (j=1; j<(ny-1); j++) {
7028 for (k=1; k<(nz-1); k++) {
7030 u[IJK(i,j,k)] += coef*phi[IJK(i,j,k)];
7044 int i, j, k, ijk, nx, ny, nz, n, dilo, dihi, djlo, djhi, dklo, dkhi;
7045 double hx, hy, hzed, epsw, iepsw, scal, scalx, scaly, scalz;
7062 Vnm_print(2,
"Vpmg_solve: Need to call Vpmg_fillco()!\n");
7067 for (i=1; i<(nx-1); i++) {
7069 if (i == 1) dilo = 1;
7071 if (i == nx-2) dihi = 1;
7074 for (j=1; j<(ny-1); j++) {
7076 if (j == 1) djlo = 1;
7078 if (j == ny-2) djhi = 1;
7081 for (k=1; k<(nz-1); k++) {
7083 if (k == 1) dklo = 1;
7085 if (k == nz-2) dkhi = 1;
7089 thee->
fcf[IJK(i,j,k)] = \
7090 iepsw*scal*thee->
charge[IJK(i,j,k)] \
7091 + dilo*scalx*thee->
gxcf[IJKx(j,k,0)] \
7092 + dihi*scalx*thee->
gxcf[IJKx(j,k,1)] \
7093 + djlo*scaly*thee->
gycf[IJKy(i,k,0)] \
7094 + djhi*scaly*thee->
gycf[IJKy(i,k,1)] \
7095 + dklo*scalz*thee->
gzcf[IJKz(i,j,0)] \
7096 + dkhi*scalz*thee->
gzcf[IJKz(i,j,1)] ;
7107 for (j=0; j<ny; j++) {
7108 for (k=0; k<nz; k++) {
7109 thee->
u[IJK(0,j,k)] = thee->
gxcf[IJKx(j,k,0)];
7110 thee->
u[IJK(nx-1,j,k)] = thee->
gycf[IJKx(j,k,1)];
7114 for (i=0; i<nx; i++) {
7115 for (k=0; k<nz; k++) {
7116 thee->
u[IJK(i,0,k)] = thee->
gycf[IJKy(i,k,0)];
7117 thee->
u[IJK(i,ny-1,k)] = thee->
gycf[IJKy(i,k,1)];
7121 for (i=0; i<nx; i++) {
7122 for (j=0; j<ny; j++) {
7123 thee->
u[IJK(i,j,0)] = thee->
gzcf[IJKz(i,j,0)];
7124 thee->
u[IJK(i,j,nz-1)] = thee->
gzcf[IJKz(i,j,1)];
7133 return (2.5+((
double)(i)-(f)));
7139 static double one6 = 1.0/6.0;
7140 static double one8 = 1.0/8.0;
7141 static double one24 = 1.0/24.0;
7142 static double thirteen24 = 13.0/24.0;
7143 static double fourtyseven24 = 47.0/24.0;
7144 static double seventeen24 = 17.0/24.0;
7146 if ((x > 0.0) && (x <= 1.0)){
7149 }
else if ((x > 1.0) && (x <= 2.0)){
7152 return -one8 + one6*x + m2*(0.25 + one6*m - one6*m2);
7153 }
else if ((x > 2.0) && (x <= 3.0)){
7156 return -thirteen24 + 0.5*x + m2*(-0.25 - 0.5*m + 0.25*m2);
7157 }
else if ((x > 3.0) && (x <= 4.0)){
7160 return fourtyseven24 - 0.5*x + m2*(-0.25 + 0.5*m - one6*m2);
7161 }
else if ((x > 4.0) && (x <= 5.0)){
7164 return seventeen24 - one6*x + m2*(0.25 - one6*m + one24*m2);
7173 static double one6 = 1.0/6.0;
7174 static double one3 = 1.0/3.0;
7175 static double two3 = 2.0/3.0;
7176 static double thirteen6 = 13.0/6.0;
7178 if ((x > 0.0) && (x <= 1.0)){
7181 }
else if ((x > 1.0) && (x <= 2.0)){
7184 return -one3 + 0.5*x + m2*(0.5 - two3*m);
7185 }
else if ((x > 2.0) && (x <= 3.0)){
7188 return 1.5 - 0.5*x + m2*(-1.5 + m);
7189 }
else if ((x > 3.0) && (x <= 4.0)){
7192 return 1.0 - 0.5*x + m2*(1.5 - two3*m);
7193 }
else if ((x > 4.0) && (x <= 5.0)){
7196 return -thirteen6 + 0.5*x + m2*(-0.5 + one6*m);
7206 if ((x > 0.0) && (x <= 1.0)){
7208 }
else if ((x > 1.0) && (x <= 2.0)){
7211 return -0.5 + x - 2.0*m2;
7212 }
else if ((x > 2.0) && (x <= 3.0)){
7215 return 5.5 - 3.0*x + 3.0*m2;
7216 }
else if ((x > 3.0) && (x <= 4.0)){
7219 return -9.5 + 3.0*x - 2.0*m2;
7220 }
else if ((x > 4.0) && (x <= 5.0)){
7223 return 4.5 - x + 0.5*m2;
7231 if ((x > 0.0) && (x <= 1.0))
return x;
7232 else if ((x > 1.0) && (x <= 2.0))
return 5.0 - 4.0 * x;
7233 else if ((x > 2.0) && (x <= 3.0))
return -15.0 + 6.0 * x;
7234 else if ((x > 3.0) && (x <= 4.0))
return 15.0 - 4.0 * x;
7235 else if ((x > 4.0) && (x <= 5.0))
return x - 5.0;
7248 double xmin, xmax, ymin, ymax, zmin, zmax;
7249 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
7250 double hx, hy, hzed, *apos;
7252 double charge, *dipole,*quad;
7253 double c,ux,uy,uz,qxx,qyx,qyy,qzx,qzy,qzz,qave;
7255 double mx,my,mz,dmx,dmy,dmz,d2mx,d2my,d2mz;
7258 int i, ii, jj, kk, nx, ny, nz, iatom;
7259 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
7262 double mir,mjr,mkr,mr2;
7263 double debye,mc,mux,muy,muz,mqxx,mqyx,mqyy,mqzx,mqzy,mqzz;
7265 VASSERT(thee != VNULL);
7281 f = zmagic/(hx*hy*hzed);
7297 Vnm_print(0,
"fillcoPermanentMultipole: filling in source term.\n");
7305#if defined(WITH_TINKER)
7306 dipole = Vatom_getDipole(atom);
7307 ux = dipole[0]/hx*f;
7308 uy = dipole[1]/hy*f;
7309 uz = dipole[2]/hzed*f;
7310 quad = Vatom_getQuadrupole(atom);
7311 qxx = (1.0/3.0)*quad[0]/(hx*hx)*f;
7312 qyx = (2.0/3.0)*quad[3]/(hx*hy)*f;
7313 qyy = (1.0/3.0)*quad[4]/(hy*hy)*f;
7314 qzx = (2.0/3.0)*quad[6]/(hzed*hx)*f;
7315 qzy = (2.0/3.0)*quad[7]/(hzed*hy)*f;
7316 qzz = (1.0/3.0)*quad[8]/(hzed*hzed)*f;
7342 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
7343 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
7344 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
7345 Vnm_print(2,
"fillcoPermanentMultipole: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring this atom):\n", iatom, apos[0], apos[1], apos[2]);
7346 Vnm_print(2,
"fillcoPermanentMultipole: xmin = %g, xmax = %g\n", xmin, xmax);
7347 Vnm_print(2,
"fillcoPermanentMultipole: ymin = %g, ymax = %g\n", ymin, ymax);
7348 Vnm_print(2,
"fillcoPermanentMultipole: zmin = %g, zmax = %g\n", zmin, zmax);
7353 position[0] = apos[0] - xmin;
7354 position[1] = apos[1] - ymin;
7355 position[2] = apos[2] - zmin;
7358 ifloat = position[0]/hx;
7359 jfloat = position[1]/hy;
7360 kfloat = position[2]/hzed;
7362 ip1 = (int)ceil(ifloat);
7364 im1 = (int)floor(ifloat);
7366 jp1 = (int)ceil(jfloat);
7368 jm1 = (int)floor(jfloat);
7370 kp1 = (int)ceil(kfloat);
7372 km1 = (int)floor(kfloat);
7377 ip2 = VMIN2(ip2,nx-1);
7378 ip1 = VMIN2(ip1,nx-1);
7381 jp2 = VMIN2(jp2,ny-1);
7382 jp1 = VMIN2(jp1,ny-1);
7385 kp2 = VMIN2(kp2,nz-1);
7386 kp1 = VMIN2(kp1,nz-1);
7391 for (ii=im2; ii<=ip2; ii++) {
7396 for (jj=jm2; jj<=jp2; jj++) {
7401 for (kk=km2; kk<=kp2; kk++) {
7406 charge = mx*my*mz*c -
7407 dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz +
7409 dmx*dmy*mz*qyx + mx*d2my*mz*qyy +
7410 dmx*my*dmz*qzx + mx*dmy*dmz*qzy + mx*my*d2mz*qzz;
7411 thee->
charge[IJK(ii,jj,kk)] += charge;
7471#if defined(WITH_TINKER)
7481 double xmin, xmax, ymin, ymax, zmin, zmax;
7482 double xlen, ylen, zlen, ifloat, jfloat, kfloat;
7483 double hx, hy, hzed, *apos, position[3];
7485 double mx, my, mz, dmx, dmy, dmz;
7487 double charge, *dipole, ux,uy,uz;
7490 int i, ii, jj, kk, nx, ny, nz, iatom;
7491 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
7497 VASSERT(thee != VNULL);
7513 f = zmagic/(hx*hy*hzed);
7529 Vnm_print(0,
"fillcoInducedDipole: filling in the source term.\n");
7535 dipole = Vatom_getInducedDipole(atom);
7536 ux = dipole[0]/hx*f;
7537 uy = dipole[1]/hy*f;
7538 uz = dipole[2]/hzed*f;
7545 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
7546 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
7547 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
7548 Vnm_print(2,
"fillcoInducedDipole: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring this atom):\n", iatom, apos[0], apos[1], apos[2]);
7549 Vnm_print(2,
"fillcoInducedDipole: xmin = %g, xmax = %g\n", xmin, xmax);
7550 Vnm_print(2,
"fillcoInducedDipole: ymin = %g, ymax = %g\n", ymin, ymax);
7551 Vnm_print(2,
"fillcoInducedDipole: zmin = %g, zmax = %g\n", zmin, zmax);
7556 position[0] = apos[0] - xmin;
7557 position[1] = apos[1] - ymin;
7558 position[2] = apos[2] - zmin;
7561 ifloat = position[0]/hx;
7562 jfloat = position[1]/hy;
7563 kfloat = position[2]/hzed;
7565 ip1 = (int)ceil(ifloat);
7567 im1 = (int)floor(ifloat);
7569 jp1 = (int)ceil(jfloat);
7571 jm1 = (int)floor(jfloat);
7573 kp1 = (int)ceil(kfloat);
7575 km1 = (int)floor(kfloat);
7580 ip2 = VMIN2(ip2,nx-1);
7581 ip1 = VMIN2(ip1,nx-1);
7584 jp2 = VMIN2(jp2,ny-1);
7585 jp1 = VMIN2(jp1,ny-1);
7588 kp2 = VMIN2(kp2,nz-1);
7589 kp1 = VMIN2(kp1,nz-1);
7594 for (ii=im2; ii<=ip2; ii++) {
7598 for (jj=jm2; jj<=jp2; jj++) {
7602 for (kk=km2; kk<=kp2; kk++) {
7606 charge = -dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz;
7607 thee->
charge[IJK(ii,jj,kk)] += charge;
7647 double xmin, xmax, ymin, ymax, zmin, zmax;
7648 double xlen, ylen, zlen, ifloat, jfloat, kfloat;
7649 double hx, hy, hzed, *apos, position[3];
7651 double mx, my, mz, dmx, dmy, dmz;
7653 double charge, *dipole, ux,uy,uz;
7656 int i, ii, jj, kk, nx, ny, nz, iatom;
7657 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
7665 VASSERT(thee != VNULL);
7681 f = zmagic/(hx*hy*hzed);
7697 Vnm_print(0,
"fillcoNLInducedDipole: filling in source term.\n");
7703 dipole = Vatom_getNLInducedDipole(atom);
7704 ux = dipole[0]/hx*f;
7705 uy = dipole[1]/hy*f;
7706 uz = dipole[2]/hzed*f;
7715 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
7716 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
7717 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
7718 Vnm_print(2,
"fillcoNLInducedDipole: Atom #%d at (%4.3f, %4.3f,%4.3f) is off the mesh (ignoring this atom):\n", iatom, apos[0], apos[1], apos[2]);
7719 Vnm_print(2,
"fillcoNLInducedDipole: xmin = %g, xmax = %g\n", xmin, xmax);
7720 Vnm_print(2,
"fillcoNLInducedDipole: ymin = %g, ymax = %g\n", ymin, ymax);
7721 Vnm_print(2,
"fillcoNLInducedDipole: zmin = %g, zmax = %g\n", zmin, zmax);
7726 position[0] = apos[0] - xmin;
7727 position[1] = apos[1] - ymin;
7728 position[2] = apos[2] - zmin;
7731 ifloat = position[0]/hx;
7732 jfloat = position[1]/hy;
7733 kfloat = position[2]/hzed;
7735 ip1 = (int)ceil(ifloat);
7737 im1 = (int)floor(ifloat);
7739 jp1 = (int)ceil(jfloat);
7741 jm1 = (int)floor(jfloat);
7743 kp1 = (int)ceil(kfloat);
7745 km1 = (int)floor(kfloat);
7750 ip2 = VMIN2(ip2,nx-1);
7751 ip1 = VMIN2(ip1,nx-1);
7754 jp2 = VMIN2(jp2,ny-1);
7755 jp1 = VMIN2(jp1,ny-1);
7758 kp2 = VMIN2(kp2,nz-1);
7759 kp1 = VMIN2(kp1,nz-1);
7765 for (ii=im2; ii<=ip2; ii++) {
7769 for (jj=jm2; jj<=jp2; jj++) {
7773 for (kk=km2; kk<=kp2; kk++) {
7777 charge = -dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz;
7778 thee->
charge[IJK(ii,jj,kk)] += charge;
7815 double xmax, xmin, ymax, ymin, zmax, zmin;
7816 double hx, hy, hzed, ifloat, jfloat, kfloat;
7820 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz;
7822 int ip1,ip2,im1,im2,jp1,jp2,jm1,jm2,kp1,kp2,km1,km2;
7825 double pot, rfe[3], rfde[3][3], energy;
7826 double f, charge, *dipole, *quad;
7827 double qxx, qyx, qyy, qzx, qzy, qzz;
7830 VASSERT(thee != VNULL);
7840 xmax = thee->
xf[nx-1];
7841 ymax = thee->
yf[ny-1];
7842 zmax = thee->
zf[nz-1];
7853 VASSERT(atom->
partID != 0);
7858 ifloat = (position[0] - xmin)/hx;
7859 jfloat = (position[1] - ymin)/hy;
7860 kfloat = (position[2] - zmin)/hzed;
7861 ip1 = (int)ceil(ifloat);
7863 im1 = (int)floor(ifloat);
7865 jp1 = (int)ceil(jfloat);
7867 jm1 = (int)floor(jfloat);
7869 kp1 = (int)ceil(kfloat);
7871 km1 = (int)floor(kfloat);
7876 ip2 = VMIN2(ip2,nx-1);
7877 ip1 = VMIN2(ip1,nx-1);
7880 jp2 = VMIN2(jp2,ny-1);
7881 jp1 = VMIN2(jp1,ny-1);
7884 kp2 = VMIN2(kp2,nz-1);
7885 kp1 = VMIN2(kp1,nz-1);
7899 for (ii=im2; ii<=ip2; ii++) {
7904 for (jj=jm2; jj<=jp2; jj++) {
7909 for (kk=km2; kk<=kp2; kk++) {
7914 f = u[IJK(ii,jj,kk)];
7918 rfe[0] += f*dmx*my*mz/hx;
7919 rfe[1] += f*mx*dmy*mz/hy;
7920 rfe[2] += f*mx*my*dmz/hzed;
7922 rfde[0][0] += f*d2mx*my*mz/(hx*hx);
7923 rfde[1][0] += f*dmx*dmy*mz/(hy*hx);
7924 rfde[1][1] += f*mx*d2my*mz/(hy*hy);
7925 rfde[2][0] += f*dmx*my*dmz/(hx*hzed);
7926 rfde[2][1] += f*mx*dmy*dmz/(hy*hzed);
7927 rfde[2][2] += f*mx*my*d2mz/(hzed*hzed);
7933 dipole = Vatom_getDipole(atom);
7934 quad = Vatom_getQuadrupole(atom);
7942 energy = pot * charge
7943 - rfe[0] * dipole[0]
7944 - rfe[1] * dipole[1]
7945 - rfe[2] * dipole[2]
7947 + 2.0*rfde[1][0]*qyx + rfde[1][1]*qyy
7948 + 2.0*rfde[2][0]*qzx + 2.0*rfde[2][1]*qzy + rfde[2][2]*qzz;
7959 double xmax, xmin, ymax, ymin, zmax, zmin;
7960 double hx, hy, hzed, ifloat, jfloat, kfloat;
7961 double *apos, position[3];
7963 double mx, my, mz, dmx, dmy, dmz;
7966 int ip1,ip2,im1,im2,jp1,jp2,jm1,jm2,kp1,kp2,km1,km2;
7970 VASSERT (thee != VNULL);
7979 xmax = thee->
xf[nx-1];
7980 ymax = thee->
yf[ny-1];
7981 zmax = thee->
zf[nz-1];
7992 VASSERT (atom->
partID != 0);
7997 position[0] = apos[0] - xmin;
7998 position[1] = apos[1] - ymin;
7999 position[2] = apos[2] - zmin;
8000 ifloat = position[0]/hx;
8001 jfloat = position[1]/hy;
8002 kfloat = position[2]/hzed;
8003 ip1 = (int)ceil(ifloat);
8005 im1 = (int)floor(ifloat);
8007 jp1 = (int)ceil(jfloat);
8009 jm1 = (int)floor(jfloat);
8011 kp1 = (int)ceil(kfloat);
8013 km1 = (int)floor(kfloat);
8018 ip2 = VMIN2(ip2,nx-1);
8019 ip1 = VMIN2(ip1,nx-1);
8022 jp2 = VMIN2(jp2,ny-1);
8023 jp1 = VMIN2(jp1,ny-1);
8026 kp2 = VMIN2(kp2,nz-1);
8027 kp1 = VMIN2(kp1,nz-1);
8035 for (ii=im2; ii<=ip2; ii++) {
8039 for (jj=jm2; jj<=jp2; jj++) {
8043 for (kk=km2; kk<=kp2; kk++) {
8047 f = u[IJK(ii,jj,kk)];
8049 field[0] += f*dmx*my*mz/hx;
8050 field[1] += f*mx*dmy*mz/hy;
8051 field[2] += f*mx*my*dmz/hzed;
8058 double force[3],
double torque[3]) {
8061 double f, *u, *apos, position[3];
8065 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
8066 double hx, hy, hzed, ifloat, jfloat, kfloat;
8069 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz, d3mx, d3my, d3mz;
8073 int i, j, k, ii, jj, kk;
8074 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
8077 double pot, e[3], de[3][3], d2e[3][3][3];
8080 double *dipole, *quad;
8081 double c, ux, uy, uz, qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz;
8083 VASSERT(thee != VNULL);
8090 VASSERT(atom->
partID != 0);
8095 dipole = Vatom_getDipole(atom);
8099 quad = Vatom_getQuadrupole(atom);
8141 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
8142 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
8143 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
8144 Vnm_print(2,
"qfPermanentMultipoleForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
8149 position[0] = apos[0] - xmin;
8150 position[1] = apos[1] - ymin;
8151 position[2] = apos[2] - zmin;
8152 ifloat = position[0]/hx;
8153 jfloat = position[1]/hy;
8154 kfloat = position[2]/hzed;
8155 ip1 = (int)ceil(ifloat);
8157 im1 = (int)floor(ifloat);
8159 jp1 = (int)ceil(jfloat);
8161 jm1 = (int)floor(jfloat);
8163 kp1 = (int)ceil(kfloat);
8165 km1 = (int)floor(kfloat);
8170 ip2 = VMIN2(ip2,nx-1);
8171 ip1 = VMIN2(ip1,nx-1);
8174 jp2 = VMIN2(jp2,ny-1);
8175 jp1 = VMIN2(jp1,ny-1);
8178 kp2 = VMIN2(kp2,nz-1);
8179 kp1 = VMIN2(kp1,nz-1);
8183 for (ii=im2; ii<=ip2; ii++) {
8189 for (jj=jm2; jj<=jp2; jj++) {
8195 for (kk=km2; kk<=kp2; kk++) {
8201 f = u[IJK(ii,jj,kk)];
8205 e[0] += f*dmx*my*mz/hx;
8206 e[1] += f*mx*dmy*mz/hy;
8207 e[2] += f*mx*my*dmz/hzed;
8209 de[0][0] += f*d2mx*my*mz/(hx*hx);
8210 de[1][0] += f*dmx*dmy*mz/(hy*hx);
8211 de[1][1] += f*mx*d2my*mz/(hy*hy);
8212 de[2][0] += f*dmx*my*dmz/(hx*hzed);
8213 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
8214 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
8217 d2e[0][0][0] += f*d3mx*my*mz /(hx*hx*hx);
8218 d2e[0][0][1] += f*d2mx*dmy*mz/(hx*hy*hx);
8219 d2e[0][0][2] += f*d2mx*my*dmz/(hx*hx*hzed);
8221 d2e[1][0][0] += f*d2mx*dmy*mz/(hx*hx*hy);
8222 d2e[1][0][1] += f*dmx*d2my*mz/(hx*hy*hy);
8223 d2e[1][0][2] += f*dmx*dmy*dmz/(hx*hy*hzed);
8225 d2e[1][1][0] += f*dmx*d2my*mz/(hx*hy*hy);
8226 d2e[1][1][1] += f*mx*d3my*mz /(hy*hy*hy);
8227 d2e[1][1][2] += f*mx*d2my*dmz/(hy*hy*hzed);
8229 d2e[2][0][0] += f*d2mx*my*dmz/(hx*hx*hzed);
8230 d2e[2][0][1] += f*dmx*dmy*dmz/(hx*hy*hzed);
8231 d2e[2][0][2] += f*dmx*my*d2mz/(hx*hzed*hzed);
8233 d2e[2][1][0] += f*dmx*dmy*dmz/(hx*hy*hzed);
8234 d2e[2][1][1] += f*mx*d2my*dmz/(hy*hy*hzed);
8235 d2e[2][1][2] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8237 d2e[2][2][0] += f*dmx*my*d2mz/(hx*hzed*hzed);
8238 d2e[2][2][1] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8239 d2e[2][2][2] += f*mx*my*d3mz /(hzed*hzed*hzed);
8251 force[0] -= de[0][0]*ux+de[1][0]*uy+de[2][0]*uz;
8252 force[1] -= de[1][0]*ux+de[1][1]*uy+de[2][1]*uz;
8253 force[2] -= de[2][0]*ux+de[2][1]*uy+de[2][2]*uz;
8256 force[0] += d2e[0][0][0]*qxx
8257 + d2e[1][0][0]*qyx*2.0+d2e[1][1][0]*qyy
8258 + d2e[2][0][0]*qzx*2.0+d2e[2][1][0]*qzy*2.0+d2e[2][2][0]*qzz;
8259 force[1] += d2e[0][0][1]*qxx
8260 + d2e[1][0][1]*qyx*2.0+d2e[1][1][1]*qyy
8261 + d2e[2][0][1]*qzx*2.0+d2e[2][1][1]*qzy*2.0+d2e[2][2][1]*qzz;
8262 force[2] += d2e[0][0][2]*qxx
8263 + d2e[1][0][2]*qyx*2.0+d2e[1][1][2]*qyy
8264 + d2e[2][0][2]*qzx*2.0+d2e[2][1][2]*qzy*2.0+d2e[2][2][2]*qzz;
8267 torque[0] = uy * e[2] - uz * e[1];
8268 torque[1] = uz * e[0] - ux * e[2];
8269 torque[2] = ux * e[1] - uy * e[0];
8271 de[0][1] = de[1][0];
8272 de[0][2] = de[2][0];
8273 de[1][2] = de[2][1];
8274 torque[0] -= 2.0*(qyx*de[0][2] + qyy*de[1][2] + qyz*de[2][2]
8275 - qzx*de[0][1] - qzy*de[1][1] - qzz*de[2][1]);
8276 torque[1] -= 2.0*(qzx*de[0][0] + qzy*de[1][0] + qzz*de[2][0]
8277 - qxx*de[0][2] - qxy*de[1][2] - qxz*de[2][2]);
8278 torque[2] -= 2.0*(qxx*de[0][1] + qxy*de[1][1] + qxz*de[2][1]
8279 - qyx*de[0][0] - qyy*de[1][0] - qyz*de[2][0]);
8296 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
8297 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
8298 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
8300 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
8302 VASSERT(thee != VNULL);
8313 VASSERT(atom->
partID != 0);
8351 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
8352 (apos[1]<=ymin) || (apos[1]>=ymax) || \
8353 (apos[2]<=zmin) || (apos[2]>=zmax)) {
8354 Vnm_print(2,
"ibPermanentMultipoleForce: Atom %d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", atomID, apos[0], apos[1], apos[2]);
8355 Vnm_print(2,
"ibPermanentMultipoleForce: xmin = %g, xmax = %g\n", xmin, xmax);
8356 Vnm_print(2,
"ibPermanentMultipoleForce: ymin = %g, ymax = %g\n", ymin, ymax);
8357 Vnm_print(2,
"ibPermanentMultipoleForce: zmin = %g, zmax = %g\n", zmin, zmax);
8362 position[0] = apos[0] - xmin;
8363 position[1] = apos[1] - ymin;
8364 position[2] = apos[2] - zmin;
8370 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
8371 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
8372 for (i=imin; i<=imax; i++) {
8373 dx2 = VSQR(position[0] - hx*i);
8374 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
8376 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
8377 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
8378 for (j=jmin; j<=jmax; j++) {
8379 dy2 = VSQR(position[1] - hy*j);
8380 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
8382 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
8383 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
8384 for (k=kmin; k<=kmax; k++) {
8385 dz2 = VSQR(k*hzed - position[2]);
8388 if ((dz2 + dy2 + dx2) <= rtot2) {
8389 gpos[0] = i*hx + xmin;
8390 gpos[1] = j*hy + ymin;
8391 gpos[2] = k*hzed + zmin;
8393 fmag = VSQR(thee->
u[IJK(i,j,k)])*thee->
kappa[IJK(i,j,k)];
8394 force[0] += (zkappa2*fmag*tgrad[0]);
8395 force[1] += (zkappa2*fmag*tgrad[1]);
8396 force[2] += (zkappa2*fmag*tgrad[2]);
8403 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
8404 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
8405 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
8417 double *apos, position[3], arad, hx, hy, hzed, izmagic, deps, depsi;
8418 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
8419 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
8420 double *u, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
8421 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
8423 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
8425 VASSERT(thee != VNULL);
8433 VASSERT(atom->
partID != 0);
8451 deps = (epsw - epsp);
8475 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
8476 (apos[1]<=ymin) || (apos[1]>=ymax) || \
8477 (apos[2]<=zmin) || (apos[2]>=zmax)) {
8478 Vnm_print(2,
"dbPermanentMultipoleForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", apos[0], apos[1], apos[2]);
8479 Vnm_print(2,
"dbPermanentMultipoleForce: xmin = %g, xmax = %g\n", xmin, xmax);
8480 Vnm_print(2,
"dbPermanentMultipoleForce: ymin = %g, ymax = %g\n", ymin, ymax);
8481 Vnm_print(2,
"dbPermanentMultipoleForce: zmin = %g, zmax = %g\n", zmin, zmax);
8486 position[0] = apos[0] - xmin;
8487 position[1] = apos[1] - ymin;
8488 position[2] = apos[2] - zmin;
8494 imin = (int)floor((position[0]-rtot)/hx);
8496 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8499 imax = (int)ceil((position[0]+rtot)/hx);
8500 if (imax > (nx-2)) {
8501 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8504 jmin = (int)floor((position[1]-rtot)/hy);
8506 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8509 jmax = (int)ceil((position[1]+rtot)/hy);
8510 if (jmax > (ny-2)) {
8511 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8514 kmin = (int)floor((position[2]-rtot)/hzed);
8516 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8519 kmax = (int)ceil((position[2]+rtot)/hzed);
8520 if (kmax > (nz-2)) {
8521 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8524 for (i=imin; i<=imax; i++) {
8525 for (j=jmin; j<=jmax; j++) {
8526 for (k=kmin; k<=kmax; k++) {
8528 gpos[0] = (i+0.5)*hx + xmin;
8529 gpos[1] = j*hy + ymin;
8530 gpos[2] = k*hzed + zmin;
8531 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
8534 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
8535 gpos[0] = i*hx + xmin;
8536 gpos[1] = (j+0.5)*hy + ymin;
8537 gpos[2] = k*hzed + zmin;
8538 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
8541 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
8542 gpos[0] = i*hx + xmin;
8543 gpos[1] = j*hy + ymin;
8544 gpos[2] = (k+0.5)*hzed + zmin;
8545 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
8548 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
8550 gpos[0] = (i-0.5)*hx + xmin;
8551 gpos[1] = j*hy + ymin;
8552 gpos[2] = k*hzed + zmin;
8553 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
8556 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
8558 gpos[0] = i*hx + xmin;
8559 gpos[1] = (j-0.5)*hy + ymin;
8560 gpos[2] = k*hzed + zmin;
8561 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
8564 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
8566 gpos[0] = i*hx + xmin;
8567 gpos[1] = j*hy + ymin;
8568 gpos[2] = (k-0.5)*hzed + zmin;
8569 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
8572 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
8573 dbFmag = u[IJK(i,j,k)];
8575 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
8576 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
8577 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
8578 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
8579 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
8580 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
8582 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
8583 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
8584 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
8585 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
8586 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
8587 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
8589 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
8590 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
8591 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
8592 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
8593 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
8594 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
8595 force[0] += (dbFmag*tgrad[0]);
8596 force[1] += (dbFmag*tgrad[1]);
8597 force[2] += (dbFmag*tgrad[2]);
8601 force[0] = -force[0]*hx*hy*hzed*deps*0.5*izmagic;
8602 force[1] = -force[1]*hx*hy*hzed*deps*0.5*izmagic;
8603 force[2] = -force[2]*hx*hy*hzed*deps*0.5*izmagic;
8608 int atomID,
double force[3],
double torque[3]) {
8612 double f, fp, *u, *up, *apos, position[3];
8616 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
8617 double hx, hy, hzed, ifloat, jfloat, kfloat;
8620 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz, d3mx, d3my, d3mz;
8624 int i, j, k, ii, jj, kk;
8625 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
8628 double pot, e[3], de[3][3], d2e[3][3][3];
8633 double *dipole, *quad;
8634 double c, ux, uy, uz, qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz;
8635 double uix, uiy, uiz;
8637 VASSERT(thee != VNULL);
8638 VASSERT(induced != VNULL);
8639 VASSERT(induced != VNULL);
8640 VASSERT(thee->
pbe != VNULL);
8641 VASSERT(thee->
pbe->
alist != VNULL);
8644 VASSERT(atom->
partID != 0);
8648 dipole = Vatom_getDipole(atom);
8652 quad = Vatom_getQuadrupole(atom);
8663 dipole = Vatom_getInducedDipole(atom);
8701 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
8702 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
8703 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
8704 Vnm_print(2,
"qfDirectPolForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
8710 position[0] = apos[0] - xmin;
8711 position[1] = apos[1] - ymin;
8712 position[2] = apos[2] - zmin;
8713 ifloat = position[0]/hx;
8714 jfloat = position[1]/hy;
8715 kfloat = position[2]/hzed;
8716 ip1 = (int)ceil(ifloat);
8718 im1 = (int)floor(ifloat);
8720 jp1 = (int)ceil(jfloat);
8722 jm1 = (int)floor(jfloat);
8724 kp1 = (int)ceil(kfloat);
8726 km1 = (int)floor(kfloat);
8731 ip2 = VMIN2(ip2,nx-1);
8732 ip1 = VMIN2(ip1,nx-1);
8735 jp2 = VMIN2(jp2,ny-1);
8736 jp1 = VMIN2(jp1,ny-1);
8739 kp2 = VMIN2(kp2,nz-1);
8740 kp1 = VMIN2(kp1,nz-1);
8744 for (ii=im2; ii<=ip2; ii++) {
8750 for (jj=jm2; jj<=jp2; jj++) {
8756 for (kk=km2; kk<=kp2; kk++) {
8762 f = u[IJK(ii,jj,kk)];
8763 fp = up[IJK(ii,jj,kk)];
8767 e[0] += f*dmx*my*mz/hx;
8768 e[1] += f*mx*dmy*mz/hy;
8769 e[2] += f*mx*my*dmz/hzed;
8771 de[0][0] += f*d2mx*my*mz/(hx*hx);
8772 de[1][0] += f*dmx*dmy*mz/(hy*hx);
8773 de[1][1] += f*mx*d2my*mz/(hy*hy);
8774 de[2][0] += f*dmx*my*dmz/(hx*hzed);
8775 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
8776 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
8778 dep[0][0] += fp*d2mx*my*mz/(hx*hx);
8779 dep[1][0] += fp*dmx*dmy*mz/(hy*hx);
8780 dep[1][1] += fp*mx*d2my*mz/(hy*hy);
8781 dep[2][0] += fp*dmx*my*dmz/(hx*hzed);
8782 dep[2][1] += fp*mx*dmy*dmz/(hy*hzed);
8783 dep[2][2] += fp*mx*my*d2mz/(hzed*hzed);
8786 d2e[0][0][0] += f*d3mx*my*mz /(hx*hx*hx);
8787 d2e[0][0][1] += f*d2mx*dmy*mz/(hx*hy*hx);
8788 d2e[0][0][2] += f*d2mx*my*dmz/(hx*hx*hzed);
8790 d2e[1][0][0] += f*d2mx*dmy*mz/(hx*hx*hy);
8791 d2e[1][0][1] += f*dmx*d2my*mz/(hx*hy*hy);
8792 d2e[1][0][2] += f*dmx*dmy*dmz/(hx*hy*hzed);
8794 d2e[1][1][0] += f*dmx*d2my*mz/(hx*hy*hy);
8795 d2e[1][1][1] += f*mx*d3my*mz /(hy*hy*hy);
8796 d2e[1][1][2] += f*mx*d2my*dmz/(hy*hy*hzed);
8798 d2e[2][0][0] += f*d2mx*my*dmz/(hx*hx*hzed);
8799 d2e[2][0][1] += f*dmx*dmy*dmz/(hx*hy*hzed);
8800 d2e[2][0][2] += f*dmx*my*d2mz/(hx*hzed*hzed);
8802 d2e[2][1][0] += f*dmx*dmy*dmz/(hx*hy*hzed);
8803 d2e[2][1][1] += f*mx*d2my*dmz/(hy*hy*hzed);
8804 d2e[2][1][2] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8806 d2e[2][2][0] += f*dmx*my*d2mz/(hx*hzed*hzed);
8807 d2e[2][2][1] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8808 d2e[2][2][2] += f*mx*my*d3mz /(hzed*hzed*hzed);
8822 force[0] -= de[0][0]*ux+de[1][0]*uy+de[2][0]*uz;
8823 force[1] -= de[1][0]*ux+de[1][1]*uy+de[2][1]*uz;
8824 force[2] -= de[2][0]*ux+de[2][1]*uy+de[2][2]*uz;
8827 force[0] += d2e[0][0][0]*qxx
8828 + d2e[1][0][0]*qyx*2.0+d2e[1][1][0]*qyy
8829 + d2e[2][0][0]*qzx*2.0+d2e[2][1][0]*qzy*2.0+d2e[2][2][0]*qzz;
8830 force[1] += d2e[0][0][1]*qxx
8831 + d2e[1][0][1]*qyx*2.0+d2e[1][1][1]*qyy
8832 + d2e[2][0][1]*qzx*2.0+d2e[2][1][1]*qzy*2.0+d2e[2][2][1]*qzz;
8833 force[2] += d2e[0][0][2]*qxx
8834 + d2e[1][0][2]*qyx*2.0+d2e[1][1][2]*qyy
8835 + d2e[2][0][2]*qzx*2.0+d2e[2][1][2]*qzy*2.0+d2e[2][2][2]*qzz;
8840 torque[0] = uy * e[2] - uz * e[1];
8841 torque[1] = uz * e[0] - ux * e[2];
8842 torque[2] = ux * e[1] - uy * e[0];
8848 de[0][1] = de[1][0];
8849 de[0][2] = de[2][0];
8850 de[1][2] = de[2][1];
8851 torque[0] -= 2.0*(qyx*de[0][2] + qyy*de[1][2] + qyz*de[2][2]
8852 - qzx*de[0][1] - qzy*de[1][1] - qzz*de[2][1]);
8853 torque[1] -= 2.0*(qzx*de[0][0] + qzy*de[1][0] + qzz*de[2][0]
8854 - qxx*de[0][2] - qxy*de[1][2] - qxz*de[2][2]);
8855 torque[2] -= 2.0*(qxx*de[0][1] + qxy*de[1][1] + qxz*de[2][1]
8856 - qyx*de[0][0] - qyy*de[1][0] - qyz*de[2][0]);
8860 force[0] -= dep[0][0]*uix+dep[1][0]*uiy+dep[2][0]*uiz;
8861 force[1] -= dep[1][0]*uix+dep[1][1]*uiy+dep[2][1]*uiz;
8862 force[2] -= dep[2][0]*uix+dep[2][1]*uiy+dep[2][2]*uiz;
8864 force[0] = 0.5 * force[0];
8865 force[1] = 0.5 * force[1];
8866 force[2] = 0.5 * force[2];
8867 torque[0] = 0.5 * torque[0];
8868 torque[1] = 0.5 * torque[1];
8869 torque[2] = 0.5 * torque[2];
8876 int atomID,
double force[3],
double torque[3]) {
8879 double *apos, *dipole, *quad, position[3], hx, hy, hzed;
8880 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
8881 double pot, e[3],de[3][3],dep[3][3],d2e[3][3][3];
8882 double mx, my, mz, dmx, dmy, dmz, mi, mj, mk;
8883 double d2mx, d2my, d2mz, d3mx, d3my, d3mz;
8884 double *u, *up, charge, ifloat, jfloat, kfloat;
8885 double f, fp, c, ux, uy, uz, qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz;
8886 double uix, uiy, uiz;
8887 int i,j,k,nx, ny, nz, im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1;
8888 int kp1, kp2, ii, jj, kk;
8890 VASSERT(thee != VNULL);
8891 VASSERT(perm != VNULL);
8892 VASSERT(nlInduced != VNULL);
8896 VASSERT(atom->
partID != 0);
8900 dipole = Vatom_getDipole(atom);
8904 quad = Vatom_getQuadrupole(atom);
8915 dipole = Vatom_getNLInducedDipole(atom);
8949 u = nlInduced->
data;
8954 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
8955 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
8956 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
8957 Vnm_print(2,
"qfNLDirectMultipoleForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
8961 position[0] = apos[0] - xmin;
8962 position[1] = apos[1] - ymin;
8963 position[2] = apos[2] - zmin;
8964 ifloat = position[0]/hx;
8965 jfloat = position[1]/hy;
8966 kfloat = position[2]/hzed;
8967 ip1 = (int)ceil(ifloat);
8969 im1 = (int)floor(ifloat);
8971 jp1 = (int)ceil(jfloat);
8973 jm1 = (int)floor(jfloat);
8975 kp1 = (int)ceil(kfloat);
8977 km1 = (int)floor(kfloat);
8982 ip2 = VMIN2(ip2,nx-1);
8983 ip1 = VMIN2(ip1,nx-1);
8986 jp2 = VMIN2(jp2,ny-1);
8987 jp1 = VMIN2(jp1,ny-1);
8990 kp2 = VMIN2(kp2,nz-1);
8991 kp1 = VMIN2(kp1,nz-1);
8995 for (ii=im2; ii<=ip2; ii++) {
9001 for (jj=jm2; jj<=jp2; jj++) {
9007 for (kk=km2; kk<=kp2; kk++) {
9013 f = u[IJK(ii,jj,kk)];
9014 fp = up[IJK(ii,jj,kk)];
9018 e[0] += f*dmx*my*mz/hx;
9019 e[1] += f*mx*dmy*mz/hy;
9020 e[2] += f*mx*my*dmz/hzed;
9022 de[0][0] += f*d2mx*my*mz/(hx*hx);
9023 de[1][0] += f*dmx*dmy*mz/(hy*hx);
9024 de[1][1] += f*mx*d2my*mz/(hy*hy);
9025 de[2][0] += f*dmx*my*dmz/(hx*hzed);
9026 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
9027 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
9029 dep[0][0] += fp*d2mx*my*mz/(hx*hx);
9030 dep[1][0] += fp*dmx*dmy*mz/(hy*hx);
9031 dep[1][1] += fp*mx*d2my*mz/(hy*hy);
9032 dep[2][0] += fp*dmx*my*dmz/(hx*hzed);
9033 dep[2][1] += fp*mx*dmy*dmz/(hy*hzed);
9034 dep[2][2] += fp*mx*my*d2mz/(hzed*hzed);
9037 d2e[0][0][0] += f*d3mx*my*mz /(hx*hx*hx);
9038 d2e[0][0][1] += f*d2mx*dmy*mz/(hx*hy*hx);
9039 d2e[0][0][2] += f*d2mx*my*dmz/(hx*hx*hzed);
9041 d2e[1][0][0] += f*d2mx*dmy*mz/(hx*hx*hy);
9042 d2e[1][0][1] += f*dmx*d2my*mz/(hx*hy*hy);
9043 d2e[1][0][2] += f*dmx*dmy*dmz/(hx*hy*hzed);
9045 d2e[1][1][0] += f*dmx*d2my*mz/(hx*hy*hy);
9046 d2e[1][1][1] += f*mx*d3my*mz /(hy*hy*hy);
9047 d2e[1][1][2] += f*mx*d2my*dmz/(hy*hy*hzed);
9049 d2e[2][0][0] += f*d2mx*my*dmz/(hx*hx*hzed);
9050 d2e[2][0][1] += f*dmx*dmy*dmz/(hx*hy*hzed);
9051 d2e[2][0][2] += f*dmx*my*d2mz/(hx*hzed*hzed);
9053 d2e[2][1][0] += f*dmx*dmy*dmz/(hx*hy*hzed);
9054 d2e[2][1][1] += f*mx*d2my*dmz/(hy*hy*hzed);
9055 d2e[2][1][2] += f*mx*dmy*d2mz/(hy*hzed*hzed);
9057 d2e[2][2][0] += f*dmx*my*d2mz/(hx*hzed*hzed);
9058 d2e[2][2][1] += f*mx*dmy*d2mz/(hy*hzed*hzed);
9059 d2e[2][2][2] += f*mx*my*d3mz /(hzed*hzed*hzed);
9073 force[0] -= de[0][0]*ux+de[1][0]*uy+de[2][0]*uz;
9074 force[1] -= de[1][0]*ux+de[1][1]*uy+de[2][1]*uz;
9075 force[2] -= de[2][0]*ux+de[2][1]*uy+de[2][2]*uz;
9078 force[0] += d2e[0][0][0]*qxx
9079 + d2e[1][0][0]*qyx*2.0+d2e[1][1][0]*qyy
9080 + d2e[2][0][0]*qzx*2.0+d2e[2][1][0]*qzy*2.0+d2e[2][2][0]*qzz;
9081 force[1] += d2e[0][0][1]*qxx
9082 + d2e[1][0][1]*qyx*2.0+d2e[1][1][1]*qyy
9083 + d2e[2][0][1]*qzx*2.0+d2e[2][1][1]*qzy*2.0+d2e[2][2][1]*qzz;
9084 force[2] += d2e[0][0][2]*qxx
9085 + d2e[1][0][2]*qyx*2.0+d2e[1][1][2]*qyy
9086 + d2e[2][0][2]*qzx*2.0+d2e[2][1][2]*qzy*2.0+d2e[2][2][2]*qzz;
9091 torque[0] = uy * e[2] - uz * e[1];
9092 torque[1] = uz * e[0] - ux * e[2];
9093 torque[2] = ux * e[1] - uy * e[0];
9099 de[0][1] = de[1][0];
9100 de[0][2] = de[2][0];
9101 de[1][2] = de[2][1];
9102 torque[0] -= 2.0*(qyx*de[0][2] + qyy*de[1][2] + qyz*de[2][2]
9103 - qzx*de[0][1] - qzy*de[1][1] - qzz*de[2][1]);
9104 torque[1] -= 2.0*(qzx*de[0][0] + qzy*de[1][0] + qzz*de[2][0]
9105 - qxx*de[0][2] - qxy*de[1][2] - qxz*de[2][2]);
9106 torque[2] -= 2.0*(qxx*de[0][1] + qxy*de[1][1] + qxz*de[2][1]
9107 - qyx*de[0][0] - qyy*de[1][0] - qyz*de[2][0]);
9111 force[0] -= dep[0][0]*uix+dep[1][0]*uiy+dep[2][0]*uiz;
9112 force[1] -= dep[1][0]*uix+dep[1][1]*uiy+dep[2][1]*uiz;
9113 force[2] -= dep[2][0]*uix+dep[2][1]*uiy+dep[2][2]*uiz;
9115 force[0] = 0.5 * force[0];
9116 force[1] = 0.5 * force[1];
9117 force[2] = 0.5 * force[2];
9118 torque[0] = 0.5 * torque[0];
9119 torque[1] = 0.5 * torque[1];
9120 torque[2] = 0.5 * torque[2];
9127 int atomID,
double force[3]) {
9135 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
9136 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
9137 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
9139 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9141 VASSERT(thee != VNULL);
9142 VASSERT(perm != VNULL);
9143 VASSERT(induced != VNULL);
9149 VASSERT(atom->
partID != 0);
9174 hzed = induced->
hzed;
9175 xmin = induced->
xmin;
9176 ymin = induced->
ymin;
9177 zmin = induced->
zmin;
9178 xmax = induced->
xmax;
9179 ymax = induced->
ymax;
9180 zmax = induced->
zmax;
9186 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9187 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9188 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9189 Vnm_print(2,
"Vpmg_ibForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
9190 apos[0], apos[1], apos[2]);
9191 Vnm_print(2,
"Vpmg_ibForce: xmin = %g, xmax = %g\n", xmin, xmax);
9192 Vnm_print(2,
"Vpmg_ibForce: ymin = %g, ymax = %g\n", ymin, ymax);
9193 Vnm_print(2,
"Vpmg_ibForce: zmin = %g, zmax = %g\n", zmin, zmax);
9198 position[0] = apos[0] - xmin;
9199 position[1] = apos[1] - ymin;
9200 position[2] = apos[2] - zmin;
9206 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
9207 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
9208 for (i=imin; i<=imax; i++) {
9209 dx2 = VSQR(position[0] - hx*i);
9210 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
9212 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
9213 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
9214 for (j=jmin; j<=jmax; j++) {
9215 dy2 = VSQR(position[1] - hy*j);
9216 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
9218 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
9219 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
9220 for (k=kmin; k<=kmax; k++) {
9221 dz2 = VSQR(k*hzed - position[2]);
9224 if ((dz2 + dy2 + dx2) <= rtot2) {
9225 gpos[0] = i*hx + xmin;
9226 gpos[1] = j*hy + ymin;
9227 gpos[2] = k*hzed + zmin;
9230 fmag = induced->
data[IJK(i,j,k)];
9231 fmag *= perm->
data[IJK(i,j,k)];
9232 fmag *= thee->
kappa[IJK(i,j,k)];
9233 force[0] += (zkappa2*fmag*tgrad[0]);
9234 force[1] += (zkappa2*fmag*tgrad[1]);
9235 force[2] += (zkappa2*fmag*tgrad[2]);
9242 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
9243 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
9244 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
9249 int atomID,
double force[3]) {
9254 int atomID,
double force[3]) {
9261 double *apos, position[3], arad, hx, hy, hzed, izmagic, deps, depsi;
9262 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
9263 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
9264 double *u, *up, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
9265 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
9267 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9269 VASSERT(thee != VNULL);
9270 VASSERT(perm != VNULL);
9271 VASSERT(induced != VNULL);
9275 VASSERT (atom->
partID != 0);
9293 deps = (epsw - epsp);
9319 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9320 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9321 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9322 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", apos[0], apos[1], apos[2]);
9323 Vnm_print(2,
"Vpmg_dbDirectPolForce: xmin = %g, xmax = %g\n", xmin, xmax);
9324 Vnm_print(2,
"Vpmg_dbDirectPolForce: ymin = %g, ymax = %g\n", ymin, ymax);
9325 Vnm_print(2,
"Vpmg_dbDirectPolForce: zmin = %g, zmax = %g\n", zmin, zmax);
9330 position[0] = apos[0] - xmin;
9331 position[1] = apos[1] - ymin;
9332 position[2] = apos[2] - zmin;
9338 imin = (int)floor((position[0]-rtot)/hx);
9340 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9343 imax = (int)ceil((position[0]+rtot)/hx);
9344 if (imax > (nx-2)) {
9345 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9348 jmin = (int)floor((position[1]-rtot)/hy);
9350 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9353 jmax = (int)ceil((position[1]+rtot)/hy);
9354 if (jmax > (ny-2)) {
9355 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9358 kmin = (int)floor((position[2]-rtot)/hzed);
9360 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9363 kmax = (int)ceil((position[2]+rtot)/hzed);
9364 if (kmax > (nz-2)) {
9365 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9368 for (i=imin; i<=imax; i++) {
9369 for (j=jmin; j<=jmax; j++) {
9370 for (k=kmin; k<=kmax; k++) {
9372 gpos[0] = (i+0.5)*hx + xmin;
9373 gpos[1] = j*hy + ymin;
9374 gpos[2] = k*hzed + zmin;
9375 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
9378 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
9379 gpos[0] = i*hx + xmin;
9380 gpos[1] = (j+0.5)*hy + ymin;
9381 gpos[2] = k*hzed + zmin;
9382 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
9385 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
9386 gpos[0] = i*hx + xmin;
9387 gpos[1] = j*hy + ymin;
9388 gpos[2] = (k+0.5)*hzed + zmin;
9389 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
9392 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
9394 gpos[0] = (i-0.5)*hx + xmin;
9395 gpos[1] = j*hy + ymin;
9396 gpos[2] = k*hzed + zmin;
9397 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
9400 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
9402 gpos[0] = i*hx + xmin;
9403 gpos[1] = (j-0.5)*hy + ymin;
9404 gpos[2] = k*hzed + zmin;
9405 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
9408 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
9410 gpos[0] = i*hx + xmin;
9411 gpos[1] = j*hy + ymin;
9412 gpos[2] = (k-0.5)*hzed + zmin;
9413 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
9416 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
9418 dbFmag = up[IJK(i,j,k)];
9420 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9421 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9422 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9423 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9424 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9425 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9427 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9428 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9429 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9430 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9431 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9432 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9434 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9435 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9436 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9437 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9438 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9439 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9440 force[0] += (dbFmag*tgrad[0]);
9441 force[1] += (dbFmag*tgrad[1]);
9442 force[2] += (dbFmag*tgrad[2]);
9448 force[0] = -force[0]*hx*hy*hzed*deps*0.5*izmagic;
9449 force[1] = -force[1]*hx*hy*hzed*deps*0.5*izmagic;
9450 force[2] = -force[2]*hx*hy*hzed*deps*0.5*izmagic;
9456 int atomID,
double force[3]) {
9461 Vgrid *nlinduced,
int atomID,
double force[3]) {
9464 double *apos, *dipole, position[3], hx, hy, hzed;
9466 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
9467 double de[3][3], denl[3][3];
9468 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz, mi, mj, mk;
9469 double ifloat, jfloat, kfloat;
9470 double f, fnl, uix, uiy, uiz, uixnl, uiynl, uiznl;
9471 int i,j,k,nx, ny, nz, im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1;
9472 int kp1, kp2, ii, jj, kk;
9474 VASSERT(thee != VNULL);
9475 VASSERT(induced != VNULL);
9476 VASSERT(nlinduced != VNULL);
9478 VASSERT(atom->
partID != 0);
9480 dipole = Vatom_getInducedDipole(atom);
9484 dipole = Vatom_getNLInducedDipole(atom);
9489 unl = nlinduced->
data;
9504 hzed = induced->
hzed;
9505 xmin = induced->
xmin;
9506 ymin = induced->
ymin;
9507 zmin = induced->
zmin;
9508 xmax = induced->
xmax;
9509 ymax = induced->
ymax;
9510 zmax = induced->
zmax;
9516 if (atom->
partID == 0)
return;
9519 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
9520 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
9521 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
9522 Vnm_print(2,
"qfMutualPolForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
9527 position[0] = apos[0] - xmin;
9528 position[1] = apos[1] - ymin;
9529 position[2] = apos[2] - zmin;
9530 ifloat = position[0]/hx;
9531 jfloat = position[1]/hy;
9532 kfloat = position[2]/hzed;
9533 ip1 = (int)ceil(ifloat);
9535 im1 = (int)floor(ifloat);
9537 jp1 = (int)ceil(jfloat);
9539 jm1 = (int)floor(jfloat);
9541 kp1 = (int)ceil(kfloat);
9543 km1 = (int)floor(kfloat);
9548 ip2 = VMIN2(ip2,nx-1);
9549 ip1 = VMIN2(ip1,nx-1);
9552 jp2 = VMIN2(jp2,ny-1);
9553 jp1 = VMIN2(jp1,ny-1);
9556 kp2 = VMIN2(kp2,nz-1);
9557 kp1 = VMIN2(kp1,nz-1);
9561 for (ii=im2; ii<=ip2; ii++) {
9566 for (jj=jm2; jj<=jp2; jj++) {
9571 for (kk=km2; kk<=kp2; kk++) {
9576 f = u[IJK(ii,jj,kk)];
9577 fnl = unl[IJK(ii,jj,kk)];
9581 de[0][0] += f*d2mx*my*mz/(hx*hx);
9582 de[1][0] += f*dmx*dmy*mz/(hy*hx);
9583 de[1][1] += f*mx*d2my*mz/(hy*hy);
9584 de[2][0] += f*dmx*my*dmz/(hx*hzed);
9585 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
9586 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
9590 denl[0][0] += fnl*d2mx*my*mz/(hx*hx);
9591 denl[1][0] += fnl*dmx*dmy*mz/(hy*hx);
9592 denl[1][1] += fnl*mx*d2my*mz/(hy*hy);
9593 denl[2][0] += fnl*dmx*my*dmz/(hx*hzed);
9594 denl[2][1] += fnl*mx*dmy*dmz/(hy*hzed);
9595 denl[2][2] += fnl*mx*my*d2mz/(hzed*hzed);
9602 force[0] = -(de[0][0]*uixnl + de[1][0]*uiynl + de[2][0]*uiznl);
9603 force[1] = -(de[1][0]*uixnl + de[1][1]*uiynl + de[2][1]*uiznl);
9604 force[2] = -(de[2][0]*uixnl + de[2][1]*uiynl + de[2][2]*uiznl);
9605 force[0] -= denl[0][0]*uix + denl[1][0]*uiy + denl[2][0]*uiz;
9606 force[1] -= denl[1][0]*uix + denl[1][1]*uiy + denl[2][1]*uiz;
9607 force[2] -= denl[2][0]*uix + denl[2][1]*uiy + denl[2][2]*uiz;
9609 force[0] = 0.5 * force[0];
9610 force[1] = 0.5 * force[1];
9611 force[2] = 0.5 * force[2];
9616 int atomID,
double force[3]) {
9624 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
9625 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
9626 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
9628 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9630 VASSERT(thee != VNULL);
9631 VASSERT(induced != VNULL);
9632 VASSERT(nlinduced != VNULL);
9636 VASSERT (atom->
partID != 0);
9649 if (atom->
partID == 0)
return;
9667 hzed = induced->
hzed;
9668 xmin = induced->
xmin;
9669 ymin = induced->
ymin;
9670 zmin = induced->
zmin;
9671 xmax = induced->
xmax;
9672 ymax = induced->
ymax;
9673 zmax = induced->
zmax;
9679 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9680 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9681 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9682 Vnm_print(2,
"Vpmg_ibMutalPolForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", apos[0], apos[1], apos[2]);
9683 Vnm_print(2,
"Vpmg_ibMutalPolForce: xmin = %g, xmax = %g\n", xmin, xmax);
9684 Vnm_print(2,
"Vpmg_ibMutalPolForce: ymin = %g, ymax = %g\n", ymin, ymax);
9685 Vnm_print(2,
"Vpmg_ibMutalPolForce: zmin = %g, zmax = %g\n", zmin, zmax);
9690 position[0] = apos[0] - xmin;
9691 position[1] = apos[1] - ymin;
9692 position[2] = apos[2] - zmin;
9698 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
9699 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
9700 for (i=imin; i<=imax; i++) {
9701 dx2 = VSQR(position[0] - hx*i);
9702 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
9704 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
9705 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
9706 for (j=jmin; j<=jmax; j++) {
9707 dy2 = VSQR(position[1] - hy*j);
9708 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
9710 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
9711 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
9712 for (k=kmin; k<=kmax; k++) {
9713 dz2 = VSQR(k*hzed - position[2]);
9716 if ((dz2 + dy2 + dx2) <= rtot2) {
9717 gpos[0] = i*hx + xmin;
9718 gpos[1] = j*hy + ymin;
9719 gpos[2] = k*hzed + zmin;
9722 fmag = induced->
data[IJK(i,j,k)];
9723 fmag *= nlinduced->
data[IJK(i,j,k)];
9724 fmag *= thee->
kappa[IJK(i,j,k)];
9725 force[0] += (zkappa2*fmag*tgrad[0]);
9726 force[1] += (zkappa2*fmag*tgrad[1]);
9727 force[2] += (zkappa2*fmag*tgrad[2]);
9734 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
9735 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
9736 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
9740 Vgrid *nlinduced,
int atomID,
9748 double *apos, position[3], arad, hx, hy, hzed, izmagic, deps, depsi;
9749 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
9750 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
9751 double *u, *unl, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
9752 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
9754 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9756 VASSERT(thee != VNULL);
9757 VASSERT(induced != VNULL);
9758 VASSERT(nlinduced != VNULL);
9763 VASSERT (atom->
partID != 0);
9780 deps = (epsw - epsp);
9801 unl = nlinduced->
data;
9804 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9805 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9806 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9807 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", apos[0], apos[1], apos[2]);
9808 Vnm_print(2,
"Vpmg_dbMutualPolForce: xmin = %g, xmax = %g\n", xmin, xmax);
9809 Vnm_print(2,
"Vpmg_dbMutualPolForce: ymin = %g, ymax = %g\n", ymin, ymax);
9810 Vnm_print(2,
"Vpmg_dbMutualPolForce: zmin = %g, zmax = %g\n", zmin, zmax);
9815 position[0] = apos[0] - xmin;
9816 position[1] = apos[1] - ymin;
9817 position[2] = apos[2] - zmin;
9823 imin = (int)floor((position[0]-rtot)/hx);
9825 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9828 imax = (int)ceil((position[0]+rtot)/hx);
9829 if (imax > (nx-2)) {
9830 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9833 jmin = (int)floor((position[1]-rtot)/hy);
9835 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9838 jmax = (int)ceil((position[1]+rtot)/hy);
9839 if (jmax > (ny-2)) {
9840 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9843 kmin = (int)floor((position[2]-rtot)/hzed);
9845 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9848 kmax = (int)ceil((position[2]+rtot)/hzed);
9849 if (kmax > (nz-2)) {
9850 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9853 for (i=imin; i<=imax; i++) {
9854 for (j=jmin; j<=jmax; j++) {
9855 for (k=kmin; k<=kmax; k++) {
9857 gpos[0] = (i+0.5)*hx + xmin;
9858 gpos[1] = j*hy + ymin;
9859 gpos[2] = k*hzed + zmin;
9860 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
9863 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
9864 gpos[0] = i*hx + xmin;
9865 gpos[1] = (j+0.5)*hy + ymin;
9866 gpos[2] = k*hzed + zmin;
9867 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
9870 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
9871 gpos[0] = i*hx + xmin;
9872 gpos[1] = j*hy + ymin;
9873 gpos[2] = (k+0.5)*hzed + zmin;
9874 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
9877 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
9879 gpos[0] = (i-0.5)*hx + xmin;
9880 gpos[1] = j*hy + ymin;
9881 gpos[2] = k*hzed + zmin;
9882 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
9885 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
9887 gpos[0] = i*hx + xmin;
9888 gpos[1] = (j-0.5)*hy + ymin;
9889 gpos[2] = k*hzed + zmin;
9890 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
9893 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
9895 gpos[0] = i*hx + xmin;
9896 gpos[1] = j*hy + ymin;
9897 gpos[2] = (k-0.5)*hzed + zmin;
9898 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
9901 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
9902 dbFmag = unl[IJK(i,j,k)];
9904 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9905 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9906 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9907 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9908 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9909 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9911 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9912 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9913 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9914 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9915 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9916 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9918 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9919 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9920 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9921 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9922 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9923 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9924 force[0] += (dbFmag*tgrad[0]);
9925 force[1] += (dbFmag*tgrad[1]);
9926 force[2] += (dbFmag*tgrad[2]);
9931 force[0] = -force[0]*hx*hy*hzed*deps*0.5*izmagic;
9932 force[1] = -force[1]*hx*hy*hzed*deps*0.5*izmagic;
9933 force[2] = -force[2]*hx*hy*hzed*deps*0.5*izmagic;
9944 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr, dist2;
9945 double xlen, ylen, zlen, position[3], itot, stot, ictot, ictot2, sctot;
9946 double irad, dx, dy, dz, epsw, epsp, w2i;
9947 double hx, hy, hzed, *apos, arad, sctot2;
9948 double dx2, dy2, dz2, stot2, itot2, rtot, rtot2, splineWin;
9949 double dist, value, denom, sm, sm2, sm3, sm4, sm5, sm6, sm7;
9950 double e, e2, e3, e4, e5, e6, e7;
9951 double b, b2, b3, b4, b5, b6, b7;
9952 double c0, c1, c2, c3, c4, c5, c6, c7;
9953 double ic0, ic1, ic2, ic3, ic4, ic5, ic6, ic7;
9954 int i, j, k, nx, ny, nz, iatom;
9955 int imin, imax, jmin, jmax, kmin, kmax;
9957 VASSERT(thee != VNULL);
9997 for (i=0; i<(nx*ny*nz); i++) {
9998 thee->
kappa[i] = 1.0;
9999 thee->
epsx[i] = 1.0;
10000 thee->
epsy[i] = 1.0;
10001 thee->
epsz[i] = 1.0;
10011 b = arad - splineWin;
10012 e = arad + splineWin;
10025 denom = e7 - 7.0*b*e6 + 21.0*b2*e5 - 35.0*e4*b3
10026 + 35.0*e3*b4 - 21.0*b5*e2 + 7.0*e*b6 - b7;
10027 c0 = b4*(35.0*e3 - 21.0*b*e2 + 7*e*b2 - b3)/denom;
10028 c1 = -140.0*b3*e3/denom;
10029 c2 = 210.0*e2*b2*(e + b)/denom;
10030 c3 = -140.0*e*b*(e2 + 3.0*b*e + b2)/denom;
10031 c4 = 35.0*(e3 + 9.0*b*e2 + + 9.0*e*b2 + b3)/denom;
10032 c5 = -84.0*(e2 + 3.0*b*e + b2)/denom;
10033 c6 = 70.0*(e + b)/denom;
10036 b = irad + arad - splineWin;
10037 e = irad + arad + splineWin;
10050 denom = e7 - 7.0*b*e6 + 21.0*b2*e5 - 35.0*e4*b3
10051 + 35.0*e3*b4 - 21.0*b5*e2 + 7.0*e*b6 - b7;
10052 ic0 = b4*(35.0*e3 - 21.0*b*e2 + 7*e*b2 - b3)/denom;
10053 ic1 = -140.0*b3*e3/denom;
10054 ic2 = 210.0*e2*b2*(e + b)/denom;
10055 ic3 = -140.0*e*b*(e2 + 3.0*b*e + b2)/denom;
10056 ic4 = 35.0*(e3 + 9.0*b*e2 + + 9.0*e*b2 + b3)/denom;
10057 ic5 = -84.0*(e2 + 3.0*b*e + b2)/denom;
10058 ic6 = 70.0*(e + b)/denom;
10062 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
10063 (apos[1]<=ymin) || (apos[1]>=ymax) || \
10064 (apos[2]<=zmin) || (apos[2]>=zmax)) {
10067 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\
10068 %4.3f) is off the mesh (ignoring):\n",
10069 iatom, apos[0], apos[1], apos[2]);
10070 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
10072 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
10074 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
10082 position[0] = apos[0] - xmin;
10083 position[1] = apos[1] - ymin;
10084 position[2] = apos[2] - zmin;
10088 itot = irad + arad + splineWin;
10089 itot2 = VSQR(itot);
10090 ictot = VMAX2(0, (irad + arad - splineWin));
10091 ictot2 = VSQR(ictot);
10092 stot = arad + splineWin;
10093 stot2 = VSQR(stot);
10094 sctot = VMAX2(0, (arad - splineWin));
10095 sctot2 = VSQR(sctot);
10099 rtot = VMAX2(itot, stot);
10100 rtot2 = VMAX2(itot2, stot2);
10101 dx = rtot + 0.5*hx;
10102 dy = rtot + 0.5*hy;
10103 dz = rtot + 0.5*hzed;
10104 imin = VMAX2(0,(
int)floor((position[0] - dx)/hx));
10105 imax = VMIN2(nx-1,(
int)ceil((position[0] + dx)/hx));
10106 jmin = VMAX2(0,(
int)floor((position[1] - dy)/hy));
10107 jmax = VMIN2(ny-1,(
int)ceil((position[1] + dy)/hy));
10108 kmin = VMAX2(0,(
int)floor((position[2] - dz)/hzed));
10109 kmax = VMIN2(nz-1,(
int)ceil((position[2] + dz)/hzed));
10110 for (i=imin; i<=imax; i++) {
10111 dx2 = VSQR(position[0] - hx*i);
10112 for (j=jmin; j<=jmax; j++) {
10113 dy2 = VSQR(position[1] - hy*j);
10114 for (k=kmin; k<=kmax; k++) {
10115 dz2 = VSQR(position[2] - k*hzed);
10119 dist2 = dz2 + dy2 + dx2;
10120 if (dist2 >= itot2) {
10123 if (dist2 <= ictot2) {
10124 thee->
kappa[IJK(i,j,k)] = 0.0;
10126 if ((dist2 < itot2) && (dist2 > ictot2)) {
10127 dist = VSQRT(dist2);
10135 value = ic0 + ic1*sm + ic2*sm2 + ic3*sm3
10136 + ic4*sm4 + ic5*sm5 + ic6*sm6 + ic7*sm7;
10139 }
else if (value < 0.0){
10142 thee->
kappa[IJK(i,j,k)] *= value;
10148 dist2 = dz2+dy2+VSQR(position[0]-(i+0.5)*hx);
10149 if (dist2 >= stot2) {
10150 thee->
epsx[IJK(i,j,k)] *= 1.0;
10152 if (dist2 <= sctot2) {
10153 thee->
epsx[IJK(i,j,k)] = 0.0;
10155 if ((dist2 > sctot2) && (dist2 < stot2)) {
10156 dist = VSQRT(dist2);
10164 value = c0 + c1*sm + c2*sm2 + c3*sm3
10165 + c4*sm4 + c5*sm5 + c6*sm6 + c7*sm7;
10168 }
else if (value < 0.0){
10171 thee->
epsx[IJK(i,j,k)] *= value;
10177 dist2 = dz2+dx2+VSQR(position[1]-(j+0.5)*hy);
10178 if (dist2 >= stot2) {
10179 thee->
epsy[IJK(i,j,k)] *= 1.0;
10181 if (dist2 <= sctot2) {
10182 thee->
epsy[IJK(i,j,k)] = 0.0;
10184 if ((dist2 > sctot2) && (dist2 < stot2)) {
10185 dist = VSQRT(dist2);
10193 value = c0 + c1*sm + c2*sm2 + c3*sm3
10194 + c4*sm4 + c5*sm5 + c6*sm6 + c7*sm7;
10197 }
else if (value < 0.0){
10200 thee->
epsy[IJK(i,j,k)] *= value;
10206 dist2 = dy2+dx2+VSQR(position[2]-(k+0.5)*hzed);
10207 if (dist2 >= stot2) {
10208 thee->
epsz[IJK(i,j,k)] *= 1.0;
10210 if (dist2 <= sctot2) {
10211 thee->
epsz[IJK(i,j,k)] = 0.0;
10213 if ((dist2 > sctot2) && (dist2 < stot2)) {
10214 dist = VSQRT(dist2);
10222 value = c0 + c1*sm + c2*sm2 + c3*sm3
10223 + c4*sm4 + c5*sm5 + c6*sm6 + c7*sm7;
10226 }
else if (value < 0.0){
10229 thee->
epsz[IJK(i,j,k)] *= value;
10240 Vnm_print(0,
"Vpmg_fillco: filling coefficient arrays\n");
10242 for (k=0; k<nz; k++) {
10243 for (j=0; j<ny; j++) {
10244 for (i=0; i<nx; i++) {
10246 thee->
kappa[IJK(i,j,k)] = ionmask*thee->
kappa[IJK(i,j,k)];
10247 thee->
epsx[IJK(i,j,k)] = (epsw-epsp)*thee->
epsx[IJK(i,j,k)]
10249 thee->
epsy[IJK(i,j,k)] = (epsw-epsp)*thee->
epsy[IJK(i,j,k)]
10251 thee->
epsz[IJK(i,j,k)] = (epsw-epsp)*thee->
epsz[IJK(i,j,k)]
10260VPUBLIC
void fillcoPermanentInduced(
Vpmg *thee) {
10268 double xmin, xmax, ymin, ymax, zmin, zmax;
10269 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
10270 double hx, hy, hzed, *apos;
10272 double charge, *dipole,*quad;
10273 double c,ux,uy,uz,qxx,qyx,qyy,qzx,qzy,qzz,qave;
10275 double mx,my,mz,dmx,dmy,dmz,d2mx,d2my,d2mz;
10278 int i, ii, jj, kk, nx, ny, nz, iatom;
10279 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
10281 VASSERT(thee != VNULL);
10285 alist = pbe->
alist;
10297 f = zmagic/(hx*hy*hzed);
10314 Vnm_print(0,
"fillcoPermanentInduced: filling in source term.\n");
10322#if defined(WITH_TINKER)
10323 dipole = Vatom_getDipole(atom);
10324 ux = dipole[0]/hx*f;
10325 uy = dipole[1]/hy*f;
10326 uz = dipole[2]/hzed*f;
10327 dipole = Vatom_getInducedDipole(atom);
10328 ux = ux + dipole[0]/hx*f;
10329 uy = uy + dipole[1]/hy*f;
10330 uz = uz + dipole[2]/hzed*f;
10331 quad = Vatom_getQuadrupole(atom);
10332 qxx = (1.0/3.0)*quad[0]/(hx*hx)*f;
10333 qyx = (2.0/3.0)*quad[3]/(hx*hy)*f;
10334 qyy = (1.0/3.0)*quad[4]/(hy*hy)*f;
10335 qzx = (2.0/3.0)*quad[6]/(hzed*hx)*f;
10336 qzy = (2.0/3.0)*quad[7]/(hzed*hy)*f;
10337 qzz = (1.0/3.0)*quad[8]/(hzed*hzed)*f;
10351 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
10352 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
10353 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
10354 Vnm_print(2,
"fillcoPermanentMultipole: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring this atom):\n", iatom, apos[0], apos[1], apos[2]);
10355 Vnm_print(2,
"fillcoPermanentMultipole: xmin = %g, xmax = %g\n", xmin, xmax);
10356 Vnm_print(2,
"fillcoPermanentMultipole: ymin = %g, ymax = %g\n", ymin, ymax);
10357 Vnm_print(2,
"fillcoPermanentMultipole: zmin = %g, zmax = %g\n", zmin, zmax);
10362 position[0] = apos[0] - xmin;
10363 position[1] = apos[1] - ymin;
10364 position[2] = apos[2] - zmin;
10367 ifloat = position[0]/hx;
10368 jfloat = position[1]/hy;
10369 kfloat = position[2]/hzed;
10371 ip1 = (int)ceil(ifloat);
10373 im1 = (int)floor(ifloat);
10375 jp1 = (int)ceil(jfloat);
10377 jm1 = (int)floor(jfloat);
10379 kp1 = (int)ceil(kfloat);
10381 km1 = (int)floor(kfloat);
10386 ip2 = VMIN2(ip2,nx-1);
10387 ip1 = VMIN2(ip1,nx-1);
10388 im1 = VMAX2(im1,0);
10389 im2 = VMAX2(im2,0);
10390 jp2 = VMIN2(jp2,ny-1);
10391 jp1 = VMIN2(jp1,ny-1);
10392 jm1 = VMAX2(jm1,0);
10393 jm2 = VMAX2(jm2,0);
10394 kp2 = VMIN2(kp2,nz-1);
10395 kp1 = VMIN2(kp1,nz-1);
10396 km1 = VMAX2(km1,0);
10397 km2 = VMAX2(km2,0);
10400 for (ii=im2; ii<=ip2; ii++) {
10405 for (jj=jm2; jj<=jp2; jj++) {
10410 for (kk=km2; kk<=kp2; kk++) {
10415 charge = mx*my*mz*c -
10416 dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz +
10418 dmx*dmy*mz*qyx + mx*d2my*mz*qyy +
10419 dmx*my*dmz*qzx + mx*dmy*dmz*qzy + mx*my*d2mz*qzz;
10420 thee->
charge[IJK(ii,jj,kk)] += charge;
10435 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr, dist2;
10436 double xlen, ylen, zlen, position[3], itot, stot, ictot, ictot2, sctot;
10437 double irad, dx, dy, dz, epsw, epsp, w2i;
10438 double hx, hy, hzed, *apos, arad, sctot2;
10439 double dx2, dy2, dz2, stot2, itot2, rtot, rtot2, splineWin;
10440 double dist, value, denom, sm, sm2, sm3, sm4, sm5;
10441 double e, e2, e3, e4, e5;
10442 double b, b2, b3, b4, b5;
10443 double c0, c1, c2, c3, c4, c5;
10444 double ic0, ic1, ic2, ic3, ic4, ic5;
10445 int i, j, k, nx, ny, nz, iatom;
10446 int imin, imax, jmin, jmax, kmin, kmax;
10448 VASSERT(thee != VNULL);
10453 alist = pbe->
alist;
10485 else ionmask = 0.0;
10488 for (i=0; i<(nx*ny*nz); i++) {
10489 thee->
kappa[i] = 1.0;
10490 thee->
epsx[i] = 1.0;
10491 thee->
epsy[i] = 1.0;
10492 thee->
epsz[i] = 1.0;
10502 b = arad - splineWin;
10503 e = arad + splineWin;
10512 denom = pow((e - b), 5.0);
10513 c0 = -10.0*e2*b3 + 5.0*e*b4 - b5;
10515 c2 = -30.0*(e2*b + e*b2);
10516 c3 = 10.0*(e2 + 4.0*e*b + b2);
10517 c4 = -15.0*(e + b);
10526 b = irad + arad - splineWin;
10527 e = irad + arad + splineWin;
10536 denom = pow((e - b), 5.0);
10537 ic0 = -10.0*e2*b3 + 5.0*e*b4 - b5;
10539 ic2 = -30.0*(e2*b + e*b2);
10540 ic3 = 10.0*(e2 + 4.0*e*b + b2);
10541 ic4 = -15.0*(e + b);
10551 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
10552 (apos[1]<=ymin) || (apos[1]>=ymax) || \
10553 (apos[2]<=zmin) || (apos[2]>=zmax)) {
10556 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\
10557 %4.3f) is off the mesh (ignoring):\n",
10558 iatom, apos[0], apos[1], apos[2]);
10559 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
10561 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
10563 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
10571 position[0] = apos[0] - xmin;
10572 position[1] = apos[1] - ymin;
10573 position[2] = apos[2] - zmin;
10577 itot = irad + arad + splineWin;
10578 itot2 = VSQR(itot);
10579 ictot = VMAX2(0, (irad + arad - splineWin));
10580 ictot2 = VSQR(ictot);
10581 stot = arad + splineWin;
10582 stot2 = VSQR(stot);
10583 sctot = VMAX2(0, (arad - splineWin));
10584 sctot2 = VSQR(sctot);
10588 rtot = VMAX2(itot, stot);
10589 rtot2 = VMAX2(itot2, stot2);
10590 dx = rtot + 0.5*hx;
10591 dy = rtot + 0.5*hy;
10592 dz = rtot + 0.5*hzed;
10593 imin = VMAX2(0,(
int)floor((position[0] - dx)/hx));
10594 imax = VMIN2(nx-1,(
int)ceil((position[0] + dx)/hx));
10595 jmin = VMAX2(0,(
int)floor((position[1] - dy)/hy));
10596 jmax = VMIN2(ny-1,(
int)ceil((position[1] + dy)/hy));
10597 kmin = VMAX2(0,(
int)floor((position[2] - dz)/hzed));
10598 kmax = VMIN2(nz-1,(
int)ceil((position[2] + dz)/hzed));
10599 for (i=imin; i<=imax; i++) {
10600 dx2 = VSQR(position[0] - hx*i);
10601 for (j=jmin; j<=jmax; j++) {
10602 dy2 = VSQR(position[1] - hy*j);
10603 for (k=kmin; k<=kmax; k++) {
10604 dz2 = VSQR(position[2] - k*hzed);
10608 dist2 = dz2 + dy2 + dx2;
10609 if (dist2 >= itot2) {
10612 if (dist2 <= ictot2) {
10613 thee->
kappa[IJK(i,j,k)] = 0.0;
10615 if ((dist2 < itot2) && (dist2 > ictot2)) {
10616 dist = VSQRT(dist2);
10622 value = ic0 + ic1*sm + ic2*sm2 + ic3*sm3
10623 + ic4*sm4 + ic5*sm5;
10626 }
else if (value < 0.0){
10629 thee->
kappa[IJK(i,j,k)] *= value;
10635 dist2 = dz2+dy2+VSQR(position[0]-(i+0.5)*hx);
10636 if (dist2 >= stot2) {
10637 thee->
epsx[IJK(i,j,k)] *= 1.0;
10639 if (dist2 <= sctot2) {
10640 thee->
epsx[IJK(i,j,k)] = 0.0;
10642 if ((dist2 > sctot2) && (dist2 < stot2)) {
10643 dist = VSQRT(dist2);
10649 value = c0 + c1*sm + c2*sm2 + c3*sm3
10653 }
else if (value < 0.0){
10656 thee->
epsx[IJK(i,j,k)] *= value;
10662 dist2 = dz2+dx2+VSQR(position[1]-(j+0.5)*hy);
10663 if (dist2 >= stot2) {
10664 thee->
epsy[IJK(i,j,k)] *= 1.0;
10666 if (dist2 <= sctot2) {
10667 thee->
epsy[IJK(i,j,k)] = 0.0;
10669 if ((dist2 > sctot2) && (dist2 < stot2)) {
10670 dist = VSQRT(dist2);
10676 value = c0 + c1*sm + c2*sm2 + c3*sm3
10680 }
else if (value < 0.0){
10683 thee->
epsy[IJK(i,j,k)] *= value;
10689 dist2 = dy2+dx2+VSQR(position[2]-(k+0.5)*hzed);
10690 if (dist2 >= stot2) {
10691 thee->
epsz[IJK(i,j,k)] *= 1.0;
10693 if (dist2 <= sctot2) {
10694 thee->
epsz[IJK(i,j,k)] = 0.0;
10696 if ((dist2 > sctot2) && (dist2 < stot2)) {
10697 dist = VSQRT(dist2);
10703 value = c0 + c1*sm + c2*sm2 + c3*sm3
10707 }
else if (value < 0.0){
10710 thee->
epsz[IJK(i,j,k)] *= value;
10721 Vnm_print(0,
"Vpmg_fillco: filling coefficient arrays\n");
10723 for (k=0; k<nz; k++) {
10724 for (j=0; j<ny; j++) {
10725 for (i=0; i<nx; i++) {
10727 thee->
kappa[IJK(i,j,k)] = ionmask*thee->
kappa[IJK(i,j,k)];
10728 thee->
epsx[IJK(i,j,k)] = (epsw-epsp)*thee->
epsx[IJK(i,j,k)]
10730 thee->
epsy[IJK(i,j,k)] = (epsw-epsp)*thee->
epsy[IJK(i,j,k)]
10732 thee->
epsz[IJK(i,j,k)] = (epsw-epsp)*thee->
epsz[IJK(i,j,k)]
10741VPRIVATE
void bcolcomp(
int *iparm,
double *rparm,
int *iwork,
double *rwork,
10742 double *values,
int *rowind,
int *colptr,
int *flag) {
10743 int nrow, ncol, nnzero, i;
10744 int nxc, nyc, nzc, nf, nc, narr, narrc, n_rpc;
10745 int n_iz, n_ipc, iretot, iintot;
10746 int nrwk, niwk, nx, ny, nz, nlev, ierror, maxlev, mxlv;
10747 int mgcoar, mgdisc, mgsolv;
10749 int k_ipc, k_rpc, k_ac, k_cc, k_fc, k_pc;
10754 nrwk = VAT(iparm, 1);
10755 niwk = VAT(iparm, 2);
10756 nx = VAT(iparm, 3);
10757 ny = VAT(iparm, 4);
10758 nz = VAT(iparm, 5);
10759 nlev = VAT(iparm, 6);
10762 mxlv = Vmaxlev(nx, ny, nz);
10765 mgcoar = VAT(iparm, 18);
10766 mgdisc = VAT(iparm, 19);
10767 mgsolv = VAT(iparm, 21);
10768 Vmgsz(&mgcoar, &mgdisc, &mgsolv,
10774 &n_rpc, &n_iz, &n_ipc,
10779 k_ipc = k_iz + n_iz;
10783 k_cc = k_rpc + n_rpc;
10784 k_fc = k_cc + narr;
10785 k_pc = k_fc + narr;
10786 k_ac = k_pc + 27*narrc;
10789 &nx, &ny, &nz, RAT(iwork, k_iz),
10790 RAT(iwork, k_ipc), RAT(rwork, k_rpc),
10791 RAT(rwork, k_ac), RAT(rwork, k_cc),
10792 values, rowind, colptr, flag);
10796 int *nx,
int *ny,
int *nz,
10797 int *iz,
int *ipc,
double *rpc,
10798 double *ac,
double *cc,
double *values,
10799 int *rowind,
int *colptr,
int *flag) {
10802 int lev = VAT(iparm, 6);
10804 MAT2(iz, 50, nlev);
10817 RAT(ipc, VAT2(iz, 5, lev)), RAT(rpc, VAT2(iz, 6, lev)),
10818 RAT(ac, VAT2(iz, 7, lev)), RAT(cc, VAT2(iz, 1, lev)),
10819 values, rowind, colptr, flag);
10832 int *ipc,
double *rpc,
10833 double *ac,
double *cc,
10834 double *values,
int *rowind,
int *colptr,
int *flag) {
10836 MAT2(ac, *nx * *ny * *nz, 1);
10842 RAT2(ac, 1, 1), cc,
10843 RAT2(ac, 1, 2), RAT2(ac, 1, 3), RAT2(ac, 1, 4),
10844 values, rowind, colptr, flag);
10859 int *ipc,
double *rpc,
10860 double *oC,
double *cc,
double *oE,
double *oN,
double *uC,
10861 double *values,
int *rowind,
int *colptr,
int *flag) {
10863 int nxm2, nym2, nzm2;
10864 int ii, jj, kk, ll;
10866 int inonz, iirow, nn, nrow, ncol, nonz, irow, n;
10870 MAT3(oE, *nx, *ny, *nz);
10871 MAT3(oN, *nx, *ny, *nz);
10872 MAT3(uC, *nx, *ny, *nz);
10873 MAT3(cc, *nx, *ny, *nz);
10874 MAT3(oC, *nx, *ny, *nz);
10879 n = *nx * *ny * *nz;
10883 nn = nxm2 * nym2 * nzm2;
10886 nonz = 7 * nn - 2 * nxm2 * nym2 - 2 * nxm2 - 2;
10895 for (k=2; k<=*nz-1; k++) {
10899 for (j=2; j<=*ny-1; j++) {
10903 for (i=2; i<=*nx-1; i++) {
10908 ll = (kk - 1) * nxm2 * nym2 + (jj - 1) * nxm2 + (ii - 1) + 1;
10909 l = (k - 1) * *nx * *ny + (j - 1) * *nx + (i - 1) + 1;
10912 VAT(colptr,ll) = inonz;
10915 iirow = ll - nxm2 * nym2;
10916 irow = l - *nx * *ny;
10918 doit = (iirow >= 1) && (iirow <= nn);
10919 doit = doit && (irow >= 1) && (irow <= n);
10922 VAT(values, inonz) = -VAT3(uC, i, j, k-1);
10923 VAT(rowind, inonz) = iirow;
10933 doit = (iirow >= 1) && (iirow <= nn);
10934 doit = doit && (irow >= 1) && (irow <= n);
10937 VAT(values, inonz) = -VAT3(oN, i, j-1, k);
10938 VAT(rowind, inonz) = iirow;
10948 doit = (iirow >= 1) && (iirow <= nn);
10949 doit = doit && (irow <= 1) && (irow <= n);
10951 VAT(values, inonz) = -VAT3(oE, i-1, j, k);
10952 VAT(rowind, inonz) = iirow;
10963 VAT(values, inonz) = VAT3(oC, i, j, k);
10964 }
else if (*flag == 1) {
10965 VAT(values, inonz) = VAT3(oC, i, j, k)
10966 + VAT3(cc, i, j, k);
10968 VABORT_MSG0(
"PMGF1");
10971 VAT(rowind, inonz) = iirow;
10977 doit = (iirow >= 1) && (iirow <= nn);
10978 doit = doit && (irow >= 1) && (irow <= n);
10980 VAT(values, inonz) = -VAT3(oE, i, j, k);
10981 VAT(rowind, inonz) = iirow;
10990 doit = (iirow >= 1) && (iirow <= nn);
10991 doit = doit && (irow >= 1) && (irow <= n);
10993 VAT(values, inonz) = -VAT3(oN, i, j, k);
10994 VAT(rowind, inonz) = iirow;
11001 iirow = ll + nxm2 * nym2;
11002 irow = l + *nx * *ny;
11003 doit = (iirow >= 1) && (iirow <= nn);
11004 doit = doit && (irow >= 1) && (irow <= n);
11006 VAT(values, inonz) = -VAT3(uC, i, j, k);
11007 VAT(rowind, inonz) = iirow;
11014 VAT(colptr, ncol + 1) = inonz;
11016 if (inonz != (nonz + 1)) {
11017 VABORT_MSG2(
"BCOLCOMP4: ERROR -- INONZ = %d, NONZ = %d", inonz, nonz);
11024 double *values,
int *rowind,
int *colptr,
11025 char *path,
char *title,
char *mxtype) {
11027 char key[] =
"key";
11028 char ptrfmt[] =
"(10I8)";
11029 char indfmt[] =
"(10I8)";
11030 char valfmt[] =
"(5E15.8)";
11031 char rhsfmt[] =
"(5E15.8)";
11033 int i, totcrd, ptrcrd, indcrd, valcrd, neltvl, rhscrd;
11040 outFile = fopen(path,
"w");
11043 ptrcrd = (int)(*ncol / 10 + 1) - 1;
11044 indcrd = (int)(*nnzero / 10 + 1) - 1;
11045 valcrd = (int)(*nnzero / 10 + 1) - 1;
11046 totcrd = ptrcrd + indcrd + valcrd;
11051 fprintf(outFile,
"%72s%8s\n",
11053 fprintf(outFile,
"%14d%14d%14d%14d%14d\n",
11054 totcrd, ptrcrd, indcrd, valcrd, rhscrd);
11055 fprintf(outFile,
"%3s\n", mxtype);
11056 fprintf(outFile,
" %14d%14d%14d%14d\n",
11057 *nrow, *ncol, *nnzero, neltvl);
11058 fprintf(outFile,
"%16s%16s%20s%20s\n",
11059 ptrfmt, indfmt, valfmt, rhsfmt);
11062 for (i=1; i<=*ncol+1; i++)
11063 fprintf(outFile,
"%8d", VAT(colptr, i));
11064 fprintf(outFile,
"\n");
11066 for (i=1; i<=*nnzero; i++)
11067 fprintf(outFile,
"%8d", VAT(rowind, i));
11068 fprintf(outFile,
"\n");
11072 for (i=1; i<=*nnzero; i++)
11073 fprintf(outFile,
"%15.8e", VAT(values, i));
11074 fprintf(outFile,
"\n");
enum ePBEparm_calcEnergy PBEparm_calcEnergy
Define ePBEparm_calcEnergy enumeration as PBEparm_calcEnergy.
VPUBLIC void Vmypdefinitnpbe(int *tnion, double *tcharge, double *tsconc)
Set up the ionic species to be used in later calculations. This must be called before any other of th...
VPUBLIC void Vmypdefinitlpbe(int *tnion, double *tcharge, double *tsconc)
Set up the ionic species to be used in later calculations. This must be called before any other of th...
VEXTERNC void Vnewdriv(int *iparm, double *rparm, int *iwork, double *rwork, double *u, double *xf, double *yf, double *zf, double *gxcf, double *gycf, double *gzcf, double *a1cf, double *a2cf, double *a3cf, double *ccf, double *fcf, double *tcf)
Driver for the Newton Solver.
VPUBLIC void Vmgsz(int *mgcoar, int *mgdisc, int *mgsolv, int *nx, int *ny, int *nz, int *nlev, int *nxc, int *nyc, int *nzc, int *nf, int *nc, int *narr, int *narrc, int *n_rpc, int *n_iz, int *n_ipc, int *iretot, int *iintot)
This routine computes the required sizes of the real and integer work arrays for the multigrid code....
VPUBLIC void Vmypdefinitsmpbe(int *tnion, double *tcharge, double *tsconc, double *smvolume, double *smsize)
Set up the ionic species to be used in later calculations. This must be called before any other of th...
VPUBLIC void Vmgdriv(int *iparm, double *rparm, int *iwork, double *rwork, double *u, double *xf, double *yf, double *zf, double *gxcf, double *gycf, double *gzcf, double *a1cf, double *a2cf, double *a3cf, double *ccf, double *fcf, double *tcf)
Multilevel solver driver.
VPUBLIC void Vacc_splineAccGradAtomNorm(Vacc *thee, double center[VAPBS_DIM], double win, double infrad, Vatom *atom, double *grad)
Report gradient of spline-based accessibility with respect to a particular atom normalized by the acc...
VPUBLIC double Vacc_molAcc(Vacc *thee, double center[VAPBS_DIM], double radius)
Report molecular accessibility.
VPUBLIC void Vacc_splineAccGradAtomNorm3(Vacc *thee, double center[VAPBS_DIM], double win, double infrad, Vatom *atom, double *grad)
Report gradient of spline-based accessibility with respect to a particular atom normalized by a 3rd o...
VPUBLIC double Vacc_splineAcc(Vacc *thee, double center[VAPBS_DIM], double win, double infrad)
Report spline-based accessibility.
VPUBLIC double Vacc_atomSASA(Vacc *thee, double radius, Vatom *atom)
Return the atomic solvent accessible surface area (SASA)
VPUBLIC double Vacc_SASA(Vacc *thee, double radius)
Build the solvent accessible surface (SAS) and calculate the solvent accessible surface area.
VPUBLIC void Vacc_splineAccGradAtomNorm4(Vacc *thee, double center[VAPBS_DIM], double win, double infrad, Vatom *atom, double *grad)
Report gradient of spline-based accessibility with respect to a particular atom normalized by a 4th o...
VPUBLIC VaccSurf * Vacc_atomSASPoints(Vacc *thee, double radius, Vatom *atom)
Get the set of points for this atom's solvent-accessible surface.
VPUBLIC Vatom * Valist_getAtom(Valist *thee, int i)
Get pointer to particular atom in list.
VPUBLIC int Valist_getNumberAtoms(Valist *thee)
Get number of atoms in the list.
VPUBLIC double Vatom_getRadius(Vatom *thee)
Get atomic position.
VPUBLIC double * Vatom_getPosition(Vatom *thee)
Get atomic position.
VPUBLIC double Vatom_getCharge(Vatom *thee)
Get atomic charge.
VPUBLIC double Vcap_exp(double x, int *ichop)
Provide a capped exp() function.
VPUBLIC void Vgrid_dtor(Vgrid **thee)
Object destructor.
VPUBLIC int Vgrid_gradient(Vgrid *thee, double pt[3], double grad[3])
Get first derivative values at a point.
VPUBLIC Vgrid * Vgrid_ctor(int nx, int ny, int nz, double hx, double hy, double hzed, double xmin, double ymin, double zmin, double *data)
Construct Vgrid object with values obtained from Vpmg_readDX (for example)
VPUBLIC int Vgrid_curvature(Vgrid *thee, double pt[3], int cflag, double *value)
Get second derivative values at a point.
VPUBLIC int Vgrid_value(Vgrid *thee, double pt[3], double *value)
Get potential value (from mesh or approximation) at a point.
#define SINH_MAX
Used to set the max values acceptable for sinh chopping.
#define VAPBS_UP
Face definition for a volume.
#define SINH_MIN
Used to set the min values acceptable for sinh chopping.
enum eVsurf_Meth Vsurf_Meth
Declaration of the Vsurf_Meth type as the Vsurf_Meth enum.
#define VAPBS_FRONT
Face definition for a volume.
#define VEMBED(rctag)
Allows embedding of RCS ID tags in object files.
#define VAPBS_DOWN
Face definition for a volume.
#define VAPBS_LEFT
Face definition for a volume.
#define MAXION
The maximum number of ion species that can be involved in a single PBE calculation.
#define VAPBS_RIGHT
Face definition for a volume.
enum eVhal_PBEType Vhal_PBEType
Declaration of the Vhal_PBEType type as the Vhal_PBEType enum.
enum eVdata_Type Vdata_Type
Declaration of the Vdata_Type type as the Vdata_Type enum.
enum eVchrg_Meth Vchrg_Meth
Declaration of the Vchrg_Meth type as the Vchrg_Meth enum.
#define VPMGSMALL
A small number used in Vpmg to decide if points are on/off grid-lines or non-zer0 (etc....
#define VAPBS_BACK
Face definition for a volume.
VPUBLIC double Vpbe_getSoluteCharge(Vpbe *thee)
Get total solute charge.
VPUBLIC double * Vpbe_getSoluteCenter(Vpbe *thee)
Get coordinates of solute center.
VPUBLIC double Vpbe_getmemv(Vpbe *thee)
Get membrane potential (kT)
VPUBLIC double Vpbe_getSoluteDiel(Vpbe *thee)
Get solute dielectric constant.
VPUBLIC double Vpbe_getZkappa2(Vpbe *thee)
Get modified squared Debye-Huckel parameter.
VPUBLIC double Vpbe_getzmem(Vpbe *thee)
Get z position of the membrane bottom.
VPUBLIC double Vpbe_getXkappa(Vpbe *thee)
Get Debye-Huckel parameter.
VPUBLIC double Vpbe_getZmagic(Vpbe *thee)
Get charge scaling factor.
VPUBLIC double Vpbe_getSolventRadius(Vpbe *thee)
Get solvent molecule radius.
VPUBLIC double Vpbe_getSolventDiel(Vpbe *thee)
Get solvent dielectric constant.
VPUBLIC double Vpbe_getmembraneDiel(Vpbe *thee)
Get membrane dielectric constant.
VPUBLIC double Vpbe_getLmem(Vpbe *thee)
Get length of the membrane (A)aauthor Michael Grabe.
VPUBLIC double Vpbe_getSoluteRadius(Vpbe *thee)
Get sphere radius which bounds biomolecule.
VPUBLIC double Vpbe_getBulkIonicStrength(Vpbe *thee)
Get bulk ionic strength.
VPUBLIC double Vpbe_getMaxIonRadius(Vpbe *thee)
Get maximum radius of ion species.
VPUBLIC Vacc * Vpbe_getVacc(Vpbe *thee)
Get accessibility oracle.
VPUBLIC int Vpbe_getIons(Vpbe *thee, int *nion, double ionConc[MAXION], double ionRadii[MAXION], double ionQ[MAXION])
Get information about the counterion species present.
VPUBLIC double Vpbe_getTemperature(Vpbe *thee)
Get temperature.
VPRIVATE void pcolcomp(int *nrow, int *ncol, int *nnzero, double *values, int *rowind, int *colptr, char *path, char *title, char *mxtype)
Print a column-compressed matrix in Harwell-Boeing format.
VEXTERNC void Vpmg_dbMutualPolForce(Vpmg *thee, Vgrid *induced, Vgrid *nlInduced, int atomID, double force[3])
Dielectric boundary mutual polarization force for induced dipoles based on 5th order B-Splines....
VEXTERNC void Vpmg_ibNLDirectPolForce(Vpmg *thee, Vgrid *perm, Vgrid *nlInduced, int atomID, double force[3])
Ionic boundary direct polarization force between permanent multipoles and non-local induced dipoles b...
VPUBLIC int Vpmg_fillArray(Vpmg *thee, double *vec, Vdata_Type type, double parm, Vhal_PBEType pbetype, PBEparm *pbeparm)
Fill the specified array with accessibility values.
VPUBLIC int Vpmg_ibForce(Vpmg *thee, double *force, int atomID, Vsurf_Meth srfm)
Calculate the osmotic pressure on the specified atom in units of k_B T/AA.
VPUBLIC void Vpmg_dtor(Vpmg **thee)
Object destructor.
VEXTERNC double Vpmg_qfPermanentMultipoleEnergy(Vpmg *thee, int atomID)
Computes the permanent multipole electrostatic hydration energy (the polarization component of the hy...
VEXTERNC void Vpmg_dbDirectPolForce(Vpmg *thee, Vgrid *perm, Vgrid *induced, int atomID, double force[3])
Dielectric boundary direct polarization force between permanent multipoles and induced dipoles,...
VPUBLIC double Vpmg_dielGradNorm(Vpmg *thee)
Get the integral of the gradient of the dielectric function.
VEXTERNC void Vpmg_qfPermanentMultipoleForce(Vpmg *thee, int atomID, double force[3], double torque[3])
Computes the q-Phi Force for permanent multipoles based on 5th order B-splines.
VPUBLIC int Vpmg_ctor2(Vpmg *thee, Vpmgp *pmgp, Vpbe *pbe, int focusFlag, Vpmg *pmgOLD, MGparm *mgparm, PBEparm_calcEnergy energyFlag)
FORTRAN stub constructor for the Vpmg class (uses previously-allocated memory)
VPUBLIC int Vpmg_solveLaplace(Vpmg *thee)
Solve Poisson's equation with a homogeneous Laplacian operator using the solvent dielectric constant....
VPUBLIC Vpmg * Vpmg_ctor(Vpmgp *pmgp, Vpbe *pbe, int focusFlag, Vpmg *pmgOLD, MGparm *mgparm, PBEparm_calcEnergy energyFlag)
Constructor for the Vpmg class (allocates new memory)
VEXTERNC void Vpmg_qfMutualPolForce(Vpmg *thee, Vgrid *induced, Vgrid *nlInduced, int atomID, double force[3])
Mutual polarization force for induced dipoles based on 5th order B-Splines. This force arises due to ...
VEXTERNC void Vpmg_qfNLDirectPolForce(Vpmg *thee, Vgrid *perm, Vgrid *nlInduced, int atomID, double force[3], double torque[3])
q-Phi direct polarization force between permanent multipoles and non-local induced dipoles based on 5...
VPRIVATE void bcolcomp(int *iparm, double *rparm, int *iwork, double *rwork, double *values, int *rowind, int *colptr, int *flag)
Build a column-compressed matrix in Harwell-Boeing format.
VEXTERNC void Vpmg_ibPermanentMultipoleForce(Vpmg *thee, int atomID, double force[3])
Compute the ionic boundary force for permanent multipoles.
VEXTERNC void Vpmg_ibDirectPolForce(Vpmg *thee, Vgrid *perm, Vgrid *induced, int atomID, double force[3])
Ionic boundary direct polarization force between permanent multipoles and induced dipoles,...
VEXTERNC void Vpmg_ibMutualPolForce(Vpmg *thee, Vgrid *induced, Vgrid *nlInduced, int atomID, double force[3])
Ionic boundary mutual polarization force for induced dipoles based on 5th order B-Splines....
VPUBLIC double Vpmg_dielEnergy(Vpmg *thee, int extFlag)
Get the "polarization" contribution to the electrostatic energy.
VPUBLIC int Vpmg_solve(Vpmg *thee)
Solve the PBE using PMG.
VPUBLIC double Vpmg_qfAtomEnergy(Vpmg *thee, Vatom *atom)
Get the per-atom "fixed charge" contribution to the electrostatic energy.
VPUBLIC void Vpmg_dtor2(Vpmg *thee)
FORTRAN stub object destructor.
VPUBLIC void Vpackmg(int *iparm, double *rparm, size_t *nrwk, int *niwk, int *nx, int *ny, int *nz, int *nlev, int *nu1, int *nu2, int *mgkey, int *itmax, int *istop, int *ipcon, int *nonlin, int *mgsmoo, int *mgprol, int *mgcoar, int *mgsolv, int *mgdisc, int *iinfo, double *errtol, int *ipkey, double *omegal, double *omegan, int *irite, int *iperf)
Print out a column-compressed sparse matrix in Harwell-Boeing format.
VPUBLIC double Vpmg_qmEnergy(Vpmg *thee, int extFlag)
Get the "mobile charge" contribution to the electrostatic energy.
VPUBLIC int Vpmg_force(Vpmg *thee, double *force, int atomID, Vsurf_Meth srfm, Vchrg_Meth chgm)
Calculate the total force on the specified atom in units of k_B T/AA.
VPRIVATE void bcolcomp4(int *nx, int *ny, int *nz, int *ipc, double *rpc, double *oC, double *cc, double *oE, double *oN, double *uC, double *values, int *rowind, int *colptr, int *flag)
Build a column-compressed matrix in Harwell-Boeing format.
VPRIVATE void bcolcomp2(int *iparm, double *rparm, int *nx, int *ny, int *nz, int *iz, int *ipc, double *rpc, double *ac, double *cc, double *values, int *rowind, int *colptr, int *flag)
Build a column-compressed matrix in Harwell-Boeing format.
VPRIVATE void bcolcomp3(int *nx, int *ny, int *nz, int *ipc, double *rpc, double *ac, double *cc, double *values, int *rowind, int *colptr, int *flag)
Build a column-compressed matrix in Harwell-Boeing format.
VEXTERNC void Vpmg_dbNLDirectPolForce(Vpmg *thee, Vgrid *perm, Vgrid *nlInduced, int atomID, double force[3])
Dielectric bounday direct polarization force between permanent multipoles and non-local induced dipol...
VPUBLIC double Vpmg_qfEnergy(Vpmg *thee, int extFlag)
Get the "fixed charge" contribution to the electrostatic energy.
VPUBLIC void Vpmg_fieldSpline4(Vpmg *thee, int atomID, double field[3])
Computes the field at an atomic center using a stencil based on the first derivative of a 5th order B...
VPUBLIC double Vpmg_energy(Vpmg *thee, int extFlag)
Get the total electrostatic energy.
VEXTERNC void Vpmg_dbPermanentMultipoleForce(Vpmg *thee, int atomID, double force[3])
Compute the dielectric boundary force for permanent multipoles.
VEXTERNC void Vpmg_qfDirectPolForce(Vpmg *thee, Vgrid *perm, Vgrid *induced, int atomID, double force[3], double torque[3])
q-Phi direct polarization force between permanent multipoles and induced dipoles, which are induced b...
VPUBLIC int Vpmg_dbForce(Vpmg *thee, double *dbForce, int atomID, Vsurf_Meth srfm)
Calculate the dielectric boundary forces on the specified atom in units of k_B T/AA.
VPUBLIC int Vpmg_fillco(Vpmg *thee, Vsurf_Meth surfMeth, double splineWin, Vchrg_Meth chargeMeth, int useDielXMap, Vgrid *dielXMap, int useDielYMap, Vgrid *dielYMap, int useDielZMap, Vgrid *dielZMap, int useKappaMap, Vgrid *kappaMap, int usePotMap, Vgrid *potMap, int useChargeMap, Vgrid *chargeMap)
Fill the coefficient arrays prior to solving the equation.
VPUBLIC int Vpmg_qfForce(Vpmg *thee, double *force, int atomID, Vchrg_Meth chgm)
Calculate the "charge-field" force on the specified atom in units of k_B T/AA.
VPUBLIC unsigned long int Vpmg_memChk(Vpmg *thee)
Return the memory used by this structure (and its contents) in bytes.
VPUBLIC void Vpmg_unsetPart(Vpmg *thee)
Remove partition restrictions.
VPUBLIC void Vpmg_printColComp(Vpmg *thee, char path[72], char title[72], char mxtype[3], int flag)
Print out a column-compressed sparse matrix in Harwell-Boeing format.
VPUBLIC void Vpmg_setPart(Vpmg *thee, double lowerCorner[3], double upperCorner[3], int bflags[6])
Set partition information which restricts the calculation of observables to a (rectangular) subset of...
VPUBLIC void Vpmgp_size(Vpmgp *thee)
Determine array sizes and parameters for multigrid solver.
#define Vunit_ec
Charge of an electron in C.
#define Vunit_kb
Boltzmann constant.
#define Vunit_Na
Avogadro's number.
#define Vunit_eps0
Vacuum permittivity.
Parameter structure for MG-specific variables from input files.
Parameter structure for PBE variables from input files.
Oracle for solvent- and ion-accessibility around a biomolecule.
Surface object list of per-atom surface points.
Container class for list of atom objects.
Contains public data members for Vatom class/module.
Electrostatic potential oracle for Cartesian mesh data.
Contains public data members for Vpbe class/module.
Contains public data members for Vpmg class/module.
Contains public data members for Vpmgp class/module.
VPRIVATE double Vpmg_qfEnergyPoint(Vpmg *thee, int extFlag)
Calculates charge-potential energy using summation over delta function positions (i....
VPRIVATE void multipolebc(double r, double kappa, double eps_p, double eps_w, double rad, double tsr[3])
This routine serves bcfl2. It returns (in tsr) the contraction independent portion of the Debye-Hucke...
VPRIVATE void Vpmg_splineSelect(int srfm, Vacc *acc, double *gpos, double win, double infrad, Vatom *atom, double *force)
Selects a spline based surface method from either VSM_SPLINE, VSM_SPLINE5 or VSM_SPLINE7.
VPRIVATE void fillcoCoef(Vpmg *thee)
Top-level driver to fill all operator coefficient arrays.
VPRIVATE Vrc_Codes fillcoChargeMap(Vpmg *thee)
Fill source term charge array from a pre-calculated map.
VPRIVATE void fillcoCoefMolDiel(Vpmg *thee)
Fill differential operator coefficient arrays from a molecular surface calculation.
VPRIVATE void fillcoCoefMap(Vpmg *thee)
Fill operator coefficient arrays from pre-calculated maps.
VPRIVATE void zlapSolve(Vpmg *thee, double **solution, double **source, double **work1)
Calculate the solution to Poisson's equation with a simple Laplacian operator and zero-valued Dirichl...
VPUBLIC void fillcoPermanentMultipole(Vpmg *thee)
Fill source term charge array for the use of permanent multipoles.
VPRIVATE double bspline2(double x)
Evaluate a cubic B-spline.
VPRIVATE void fillcoChargeSpline2(Vpmg *thee)
Fill source term charge array from cubic spline interpolation.
VPRIVATE void fillcoCoefSpline(Vpmg *thee)
Fill operator coefficient arrays from a spline-based surface calculation.
VPRIVATE void fillcoCoefMol(Vpmg *thee)
Fill operator coefficient arrays from a molecular surface calculation.
VPRIVATE void qfForceSpline4(Vpmg *thee, double *force, int atomID)
Charge-field force due to a quintic spline charge function.
VPRIVATE void qfForceSpline1(Vpmg *thee, double *force, int atomID)
Charge-field force due to a linear spline charge function.
VPRIVATE double Vpmg_qfEnergyVolume(Vpmg *thee, int extFlag)
Calculates charge-potential energy as integral over a volume.
VPRIVATE void bcfl1(double size, double *apos, double charge, double xkappa, double pre1, double *gxcf, double *gycf, double *gzcf, double *xf, double *yf, double *zf, int nx, int ny, int nz)
Increment all boundary points by pre1*(charge/d)*(exp(-xkappa*(d-size))/(1+xkappa*size) to add the ef...
VPRIVATE void fillcoChargeSpline1(Vpmg *thee)
Fill source term charge array from linear interpolation.
VPRIVATE double dbspline2(double x)
Evaluate a cubic B-spline derivative.
VPRIVATE void fillcoCoefMolIon(Vpmg *thee)
Fill ion (nonlinear) operator coefficient array from a molecular surface calculation.
VPRIVATE void bcCalc(Vpmg *thee)
Fill boundary condition arrays.
VPUBLIC double d2bspline4(double x)
Evaluate the 2nd derivative of a 5th Order B-Spline.
VPUBLIC double dbspline4(double x)
Evaluate a 5th Order B-Spline derivative (4th order polynomial)
VPRIVATE void fillcoCoefMolDielSmooth(Vpmg *thee)
Fill differential operator coefficient arrays from a molecular surface calculation with smoothing.
VPRIVATE void fillcoCoefSpline3(Vpmg *thee)
Fill operator coefficient arrays from a 5th order polynomial based surface calculation.
VPRIVATE void fillcoCoefSpline4(Vpmg *thee)
Fill operator coefficient arrays from a 7th order polynomial based surface calculation.
VPRIVATE void qfForceSpline2(Vpmg *thee, double *force, int atomID)
Charge-field force due to a cubic spline charge function.
VPRIVATE double bspline4(double x)
Evaluate a 5th Order B-Spline (4th order polynomial)
VPRIVATE Vrc_Codes fillcoCharge(Vpmg *thee)
Top-level driver to fill source term charge array.
VPUBLIC double d3bspline4(double x)
Evaluate the 3rd derivative of a 5th Order B-Spline.
VPRIVATE void fillcoCoefMolDielNoSmooth(Vpmg *thee)
Fill differential operator coefficient arrays from a molecular surface calculation without smoothing.
VPRIVATE double Vpmg_polarizEnergy(Vpmg *thee, int extFlag)
Determines energy from polarizeable charge and interaction with fixed charges according to Rocchia et...
VPRIVATE void markSphere(double rtot, double *tpos, int nx, int ny, int nz, double hx, double hy, double hz, double xmin, double ymin, double zmin, double *array, double markVal)
Mark the grid points inside a sphere with a particular value. This marks by resetting the the grid po...
VPRIVATE double VFCHI4(int i, double f)
Return 2.5 plus difference of i - f.
VPUBLIC double Vpmg_qmEnergySMPBE(Vpmg *thee, int extFlag)
Vpmg_qmEnergy for SMPBE.
Contains declarations for class Vpmg.
VPRIVATE void fillcoNLInducedDipole(Vpmg *thee)
Fill source term charge array for non-local induced dipoles.
VPRIVATE void fillcoInducedDipole(Vpmg *thee)
Fill source term charge array for use of induced dipoles.