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");
struct sMGparm MGparm
Declaration of the MGparm class as the MGparm structure.
enum ePBEparm_calcEnergy PBEparm_calcEnergy
Define ePBEparm_calcEnergy enumeration as PBEparm_calcEnergy.
struct sPBEparm PBEparm
Declaration of the PBEparm class as the PBEparm structure.
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...
struct sVaccSurf VaccSurf
Declaration of the VaccSurf class as the VaccSurf structure.
struct sVacc Vacc
Declaration of the Vacc class as the Vacc structure.
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.
struct sValist Valist
Declaration of the Valist class as the Valist structure.
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.
struct sVatom Vatom
Declaration of the Vatom class as the Vatom structure.
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.
struct sVgrid Vgrid
Declaration of the Vgrid class as the sVgrid structure.
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.
struct sVpbe Vpbe
Declaration of the Vpbe class as the Vpbe structure.
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.
struct sVpmg Vpmg
Declaration of the Vpmg class as the Vpmg structure.
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...
struct sVpmgp Vpmgp
Declaration of the Vpmgp class as the sVpmgp structure.
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.
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.