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];
161 VASSERT(pmgp != VNULL);
162 VASSERT(pbe != VNULL);
167 thee->
vmem = Vmem_ctor(
"APBS:VPMG");
175 if (ionstr > 0.0) zks2 = 0.5/ionstr;
184 VABORT_MSG0(
"Aqua is currently disabled");
197 Vnm_print(2,
"Vpmg_ctor2: PMG chose nx = %d, ny = %d, nz = %d\n",
199 Vnm_print(2,
"Vpmg_ctor2: PMG chose nlev = %d\n",
201 Vnm_print(2,
"Vpmg_ctor2: PMG chose nxc = %d, nyc = %d, nzc = %d\n",
203 Vnm_print(2,
"Vpmg_ctor2: PMG chose nf = %d, nc = %d\n",
205 Vnm_print(2,
"Vpmg_ctor2: PMG chose narr = %d, narrc = %d\n",
207 Vnm_print(2,
"Vpmg_ctor2: PMG chose n_rpc = %d, n_iz = %d, n_ipc = %d\n",
209 Vnm_print(2,
"Vpmg_ctor2: PMG chose nrwk = %d, niwk = %d\n",
216 thee->
gxcf = (
double *)Vmem_malloc(
222 thee->
gycf = (
double *)Vmem_malloc(
228 thee->
gzcf = (
double *)Vmem_malloc(
239 Vnm_print(2,
"Vpmg_ctor2: \nWarning: External energies are not used in BCFL_MAP calculations!\n");
247 "Vpmg_ctor2: reset boundary condition flag to BCFL_FOCUS!\n");
252 Vnm_print(0,
"Vpmg_ctor2: Filling boundary with old solution!\n");
253 focusFillBound(thee, pmgOLD);
257 if (energyFlag !=
PCE_NO) {
261 for (j=0; j<3; j++) {
269 for (j=0; j<3; j++) {
270 partMin[j] = mgparm->
center[j] - 0.5*mgparm->
glen[j];
271 partMax[j] = mgparm->
center[j] + 0.5*mgparm->
glen[j];
274 extEnergy(thee, pmgOLD, energyFlag, partMin, partMax,
287 thee->
pvec = (
double *)Vmem_malloc(
294 thee->
iparm = (
int *)Vmem_malloc(thee->
vmem, 100,
sizeof(
int));
295 thee->
rparm = (
double *)Vmem_malloc(thee->
vmem, 100,
sizeof(
double));
297 thee->
rwork = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
nrwk,
sizeof(
double));
299 thee->
kappa = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
300 thee->
pot = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
301 thee->
epsx = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
302 thee->
epsy = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
303 thee->
epsz = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
304 thee->
a1cf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
305 thee->
a2cf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
306 thee->
a3cf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
307 thee->
ccf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
308 thee->
fcf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
309 thee->
tcf = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
310 thee->
u = (
double *)Vmem_malloc(thee->
vmem, thee->
pmgp->
narr,
sizeof(
double));
311 thee->
xf = (
double *)Vmem_malloc(thee->
vmem, 5*(thee->
pmgp->
nx),
sizeof(double));
312 thee->
yf = (
double *)Vmem_malloc(thee->
vmem, 5*(thee->
pmgp->
ny),
sizeof(double));
313 thee->
zf = (
double *)Vmem_malloc(thee->
vmem, 5*(thee->
pmgp->
nz),
sizeof(double));
350 for (i=0; i<nion; i++)
351 ionConc[i] = zks2 * ionConc[i];
361 for (i=0; i<nion; i++)
362 ionConc[i] = zks2 * ionConc[i];
370 Vnm_print(2,
"PMG: Warning: PBE structure not initialized!\n");
372 for (i=0; i<nion; i++)
373 ionConc[i] = zks2 * ionConc[i];
414 Vnm_print(2,
"Vpmg_solve: Need to call Vpmg_fillco()!\n");
419 for (i=0; i<n; i++) {
424 for (i=0; i<n; i++) {
429 for (i=0; i<n; i++) {
439 for (i=0; i<n; i++) {
440 thee->
ccf[i] = zkappa2*thee->
kappa[i];
443 for (i=0; i<n; i++) {
453 Vnm_print(2,
"Driving with CGMGDRIV\n");
455 VABORT_MSG0(
"CGMGDRIV is not currently supported");
462 Vnm_print(2,
"Driving with NEWDRIV\n");
475 Vnm_print(2,
"Driving with MGDRIV\n");
487 Vnm_print(2,
"Driving with NCGHSDRIV\n");
489 VABORT_MSG0(
"NCGHSDRIV is not currently supported");
496 Vnm_print(2,
"Driving with NSORDRIV\n");
498 VABORT_MSG0(
"NSORDRIV is not currently supported");
505 Vnm_print(2,
"Driving with NGSRBDRIV\n");
507 VABORT_MSG0(
"NGSRBDRIV is not currently supported");
514 Vnm_print(2,
"Driving with NWJACDRIV\n");
516 VABORT_MSG0(
"NWJACDRIV is not currently supported");
520 case VSOL_Richardson:
523 Vnm_print(2,
"Driving with NRICHDRIV\n");
525 VABORT_MSG0(
"NRICHDRIV is not currently supported");
532 Vnm_print(2,
"Driving with CGMGDRIVAQUA\n");
534 VABORT_MSG0(
"CGMGDRIVAQUA is not currently supported");
538 case VSOL_NewtonAqua:
541 Vnm_print(2,
"Driving with NEWDRIVAQUA\n");
543 VABORT_MSG0(
"NEWDRIVAQUA is not currently supported");
548 Vnm_print(2,
"Vpmg_solve: invalid solver method key (%d)\n",
561 if ((*thee) != VNULL) {
563 Vmem_free(VNULL, 1,
sizeof(
Vpmg), (
void **)thee);
573 Vmem_free(thee->
vmem, 100,
sizeof(
int),
574 (
void **)&(thee->
iparm));
575 Vmem_free(thee->
vmem, 100,
sizeof(
double),
576 (
void **)&(thee->
rparm));
578 (
void **)&(thee->
iwork));
580 (
void **)&(thee->
rwork));
582 (
void **)&(thee->
charge));
584 (
void **)&(thee->
kappa));
586 (
void **)&(thee->
pot));
588 (
void **)&(thee->
epsx));
590 (
void **)&(thee->
epsy));
592 (
void **)&(thee->
epsz));
594 (
void **)&(thee->
a1cf));
596 (
void **)&(thee->
a2cf));
598 (
void **)&(thee->
a3cf));
600 (
void **)&(thee->
ccf));
602 (
void **)&(thee->
fcf));
604 (
void **)&(thee->
tcf));
606 (
void **)&(thee->
u));
607 Vmem_free(thee->
vmem, 5*(thee->
pmgp->
nx),
sizeof(
double),
608 (
void **)&(thee->
xf));
609 Vmem_free(thee->
vmem, 5*(thee->
pmgp->
ny),
sizeof(
double),
610 (
void **)&(thee->
yf));
611 Vmem_free(thee->
vmem, 5*(thee->
pmgp->
nz),
sizeof(
double),
612 (
void **)&(thee->
zf));
614 (
void **)&(thee->
gxcf));
616 (
void **)&(thee->
gycf));
618 (
void **)&(thee->
gzcf));
620 sizeof(
double), (
void **)&(thee->
pvec));
622 Vmem_dtor(&(thee->
vmem));
626 double upperCorner[3],
int bflags[6]) {
630 int i, j, k, nx, ny, nz;
631 double xmin, ymin, zmin, x, y, z, hx, hy, hzed, xok, yok, zok;
632 double x0,x1,y0,y1,z0,z1;
640 xmin = thee->
pmgp->
xcent - 0.5*hx*(nx-1);
641 ymin = thee->
pmgp->
ycent - 0.5*hy*(ny-1);
642 zmin = thee->
pmgp->
zcent - 0.5*hzed*(nz-1);
652 Vnm_print(0,
"Vpmg_setPart: lower corner = (%g, %g, %g)\n",
653 lowerCorner[0], lowerCorner[1], lowerCorner[2]);
654 Vnm_print(0,
"Vpmg_setPart: upper corner = (%g, %g, %g)\n",
655 upperCorner[0], upperCorner[1], upperCorner[2]);
656 Vnm_print(0,
"Vpmg_setPart: actual minima = (%g, %g, %g)\n",
658 Vnm_print(0,
"Vpmg_setPart: actual maxima = (%g, %g, %g)\n",
659 xmin+hx*(nx-1), ymin+hy*(ny-1), zmin+hzed*(nz-1));
660 Vnm_print(0,
"Vpmg_setPart: bflag[FRONT] = %d\n",
662 Vnm_print(0,
"Vpmg_setPart: bflag[BACK] = %d\n",
664 Vnm_print(0,
"Vpmg_setPart: bflag[LEFT] = %d\n",
666 Vnm_print(0,
"Vpmg_setPart: bflag[RIGHT] = %d\n",
668 Vnm_print(0,
"Vpmg_setPart: bflag[UP] = %d\n",
670 Vnm_print(0,
"Vpmg_setPart: bflag[DOWN] = %d\n",
681 if ((atom->
position[0] < upperCorner[0]) &&
682 (atom->
position[0] > lowerCorner[0])) xok = 1;
685 (bflags[VAPBS_LEFT] == 0)) xok = 1;
687 (bflags[VAPBS_LEFT] == 1)) xok = 0.5;
689 (bflags[VAPBS_RIGHT] == 0)) xok = 1;
691 (bflags[VAPBS_RIGHT] == 1)) xok = 0.5;
694 if ((atom->
position[1] < upperCorner[1]) &&
695 (atom->
position[1] > lowerCorner[1])) yok = 1;
698 (bflags[VAPBS_BACK] == 0)) yok = 1;
700 (bflags[VAPBS_BACK] == 1)) yok = 0.5;
702 (bflags[VAPBS_FRONT] == 0)) yok = 1;
704 (bflags[VAPBS_FRONT] == 1)) yok = 0.5;
707 if ((atom->
position[2] < upperCorner[2]) &&
708 (atom->
position[2] > lowerCorner[2])) zok = 1;
711 (bflags[VAPBS_DOWN] == 0)) zok = 1;
713 (bflags[VAPBS_DOWN] == 1)) zok = 0.5;
715 (bflags[VAPBS_UP] == 0)) zok = 1;
717 (bflags[VAPBS_UP] == 1)) zok = 0.5;
721 atom->
partID = xok*yok*zok;
747 for (i=0; i<(nx*ny*nz); i++) thee->
pvec[i] = 0.0;
749 for (i=0; i<nx; i++) {
752 if ( (x < (upperCorner[0]-hx/2)) &&
753 (x > (lowerCorner[0]+hx/2))
755 else if ( (VABS(x - lowerCorner[0]) <
VPMGSMALL) &&
756 (bflags[VAPBS_LEFT] == 0)) xok = 1.0;
757 else if ((VABS(x - lowerCorner[0]) <
VPMGSMALL) &&
758 (bflags[VAPBS_LEFT] == 1)) xok = 0.5;
759 else if ((VABS(x - upperCorner[0]) <
VPMGSMALL) &&
760 (bflags[VAPBS_RIGHT] == 0)) xok = 1.0;
761 else if ((VABS(x - upperCorner[0]) <
VPMGSMALL) &&
762 (bflags[VAPBS_RIGHT] == 1)) xok = 0.5;
763 else if ((x > (upperCorner[0] + hx/2)) || (x < (lowerCorner[0] - hx/2))) xok = 0.0;
764 else if ((x < (upperCorner[0] + hx/2)) || (x > (lowerCorner[0] - hx/2))) {
765 x0 = VMAX2(x - hx/2, lowerCorner[0]);
766 x1 = VMIN2(x + hx/2, upperCorner[0]);
767 xok = VABS(x1-x0)/hx;
772 Vnm_print(2,
"Vpmg_setPart: fell off x-interval (%1.12E)!\n",
778 if (VABS(xok - 1.0) <
VPMGSMALL) xok = 1.0;
780 Vnm_print(2,
"Vpmg_setPart: fell off x-interval (%1.12E)!\n",
788 for (j=0; j<ny; j++) {
791 if ((y < (upperCorner[1]-hy/2)) && (y > (lowerCorner[1]+hy/2))) yok = 1.0;
792 else if ((VABS(y - lowerCorner[1]) <
VPMGSMALL) &&
793 (bflags[VAPBS_BACK] == 0)) yok = 1.0;
794 else if ((VABS(y - lowerCorner[1]) <
VPMGSMALL) &&
795 (bflags[VAPBS_BACK] == 1)) yok = 0.5;
796 else if ((VABS(y - upperCorner[1]) <
VPMGSMALL) &&
797 (bflags[VAPBS_FRONT] == 0)) yok = 1.0;
798 else if ((VABS(y - upperCorner[1]) <
VPMGSMALL) &&
799 (bflags[VAPBS_FRONT] == 1)) yok = 0.5;
800 else if ((y > (upperCorner[1] + hy/2)) || (y < (lowerCorner[1] - hy/2))) yok=0.0;
801 else if ((y < (upperCorner[1] + hy/2)) || (y > (lowerCorner[1] - hy/2))){
802 y0 = VMAX2(y - hy/2, lowerCorner[1]);
803 y1 = VMIN2(y + hy/2, upperCorner[1]);
804 yok = VABS(y1-y0)/hy;
809 Vnm_print(2,
"Vpmg_setPart: fell off y-interval (%1.12E)!\n",
815 if (VABS(yok - 1.0) <
VPMGSMALL) yok = 1.0;
817 Vnm_print(2,
"Vpmg_setPart: fell off y-interval (%1.12E)!\n",
825 for (k=0; k<nz; k++) {
828 if ((z < (upperCorner[2]-hzed/2)) && (z > (lowerCorner[2]+hzed/2))) zok = 1.0;
829 else if ((VABS(z - lowerCorner[2]) <
VPMGSMALL) &&
830 (bflags[VAPBS_DOWN] == 0)) zok = 1.0;
831 else if ((VABS(z - lowerCorner[2]) <
VPMGSMALL) &&
832 (bflags[VAPBS_DOWN] == 1)) zok = 0.5;
833 else if ((VABS(z - upperCorner[2]) <
VPMGSMALL) &&
834 (bflags[VAPBS_UP] == 0)) zok = 1.0;
835 else if ((VABS(z - upperCorner[2]) <
VPMGSMALL) &&
836 (bflags[VAPBS_UP] == 1)) zok = 0.5;
837 else if ((z > (upperCorner[2] + hzed/2)) || (z < (lowerCorner[2] - hzed/2))) zok=0.0;
838 else if ((z < (upperCorner[2] + hzed/2)) || (z > (lowerCorner[2] - hzed/2))){
839 z0 = VMAX2(z - hzed/2, lowerCorner[2]);
840 z1 = VMIN2(z + hzed/2, upperCorner[2]);
841 zok = VABS(z1-z0)/hzed;
846 Vnm_print(2,
"Vpmg_setPart: fell off z-interval (%1.12E)!\n",
852 if (VABS(zok - 1.0) <
VPMGSMALL) zok = 1.0;
854 Vnm_print(2,
"Vpmg_setPart: fell off z-interval (%1.12E)!\n",
862 if (VABS(xok*yok*zok) <
VPMGSMALL) thee->
pvec[IJK(i,j,k)] = 0.0;
863 else thee->
pvec[IJK(i,j,k)] = xok*yok*zok;
876 VASSERT(thee != VNULL);
883 for (i=0; i<(nx*ny*nz); i++) thee->
pvec[i] = 1;
896 Vatom *atoms = VNULL;
898 double position[3], hx, hy, hzed, xmin, ymin, zmin;
899 double grad[3], eps, epsp, epss, zmagic;
900 int i, j, k, l, nx, ny, nz, ichop;
918 Vnm_print(2,
"Vpmg_fillArray: need to call Vpmg_fillco first!\n");
926 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
charge[i]/zmagic;
931 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
epsx[i];
936 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
epsy[i];
941 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
epsz[i];
946 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
kappa[i];
951 for (i=0; i<nx*ny*nz; i++) vec[i] = thee->
u[i];
958 hzed, xmin, ymin, zmin,thee->
u);
971 for (k=0; k<nz; k++) {
972 for (j=0; j<ny; j++) {
973 for (i=0; i<nx; i++) {
975 position[0] = i*hx + xmin;
976 position[1] = j*hy + ymin;
977 position[2] = k*hzed + zmin;
979 vec[IJK(i,j,k)] = (
Vacc_molAcc(acc,position,parm));
987 for (k=0; k<nz; k++) {
988 for (j=0; j<ny; j++) {
989 for (i=0; i<nx; i++) {
991 position[0] = i*hx + xmin;
992 position[1] = j*hy + ymin;
993 position[2] = k*hzed + zmin;
1003 for (k=0; k<nz; k++) {
1004 for (j=0; j<ny; j++) {
1005 for (i=0; i<nx; i++) {
1007 position[0] = i*hx + xmin;
1008 position[1] = j*hy + ymin;
1009 position[2] = k*hzed + zmin;
1019 for (k=0; k<nz; k++) {
1020 for (j=0; j<ny; j++) {
1021 for (i=0; i<nx; i++) {
1023 position[0] = i*hx + xmin;
1024 position[1] = j*hy + ymin;
1025 position[2] = k*hzed + zmin;
1035 grid =
Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
1037 for (k=0; k<nz; k++) {
1038 for (j=0; j<ny; j++) {
1039 for (i=0; i<nx; i++) {
1041 if ((k==0) || (k==(nz-1)) ||
1042 (j==0) || (j==(ny-1)) ||
1043 (i==0) || (i==(nx-1))) {
1045 vec[IJK(i,j,k)] = 0;
1048 position[0] = i*hx + xmin;
1049 position[1] = j*hy + ymin;
1050 position[2] = k*hzed + zmin;
1052 &(vec[IJK(i,j,k)])));
1062 grid =
Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
1064 for (k=0; k<nz; k++) {
1065 for (j=0; j<ny; j++) {
1066 for (i=0; i<nx; i++) {
1068 position[0] = i*hx + xmin;
1069 position[1] = j*hy + ymin;
1070 position[2] = k*hzed + zmin;
1072 eps = epsp + (epss-epsp)*
Vacc_molAcc(acc, position,
1074 vec[IJK(i,j,k)] = 0.0;
1076 vec[IJK(i,j,k)] += eps*VSQR(grad[l]);
1085 for (k=0; k<nz; k++) {
1086 for (j=0; j<ny; j++) {
1087 for (i=0; i<nx; i++) {
1089 position[0] = i*hx + xmin;
1090 position[1] = j*hy + ymin;
1091 position[2] = k*hzed + zmin;
1092 vec[IJK(i,j,k)] = 0.0;
1095 for (l=0; l<pbe->
numIon; l++) {
1097 vec[IJK(i,j,k)] += (pbe->
ionConc[l]
1101 vec[IJK(i,j,k)] += (pbe->
ionConc[l]
1102 * (1 - pbe->
ionQ[l]*thee->
u[IJK(i,j,k)]));
1113 for (k=0; k<nz; k++) {
1114 for (j=0; j<ny; j++) {
1115 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;
1123 for (l=0; l<pbe->
numIon; l++) {
1125 vec[IJK(i,j,k)] += (pbe->
ionConc[l]
1130 vec[IJK(i,j,k)] += (pbe->
ionConc[l]
1132 * (1 - pbe->
ionQ[l]*thee->
u[IJK(i,j,k)]));
1143 Vnm_print(2,
"main: Bogus data type (%d)!\n", type);
1213 potgrid =
Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin, thee->
u);
1217 for (i=1; i<(nx-1); i++) {
1218 pt[0] = xmin + hx*i;
1219 for (j=1; j<(ny-1); j++) {
1220 pt[1] = ymin + hy*j;
1221 for (k=1; k<(nz-1); k++) {
1222 pt[2] = zmin + hzed*k;
1227 polq = charge[ijk] + epsp*lap*3.0;
1230 if (VABS(polq) > VSMALL) {
1235 dist2 = VSQR(pos[0]-pt[0]) + VSQR(pos[1]-pt[1]) \
1236 + VSQR(pos[2]-pt[2]);
1237 dist = VSQRT(dist2);
1239 if (dist < VSMALL) {
1240 Vnm_print(2,
"Vpmg_polarizEnergy: atom on grid point; ignoring!\n");
1242 energy = energy + polq*q/dist;
1257 double totEnergy = 0.0,
1262 VASSERT(thee != VNULL);
1265 Vnm_print(0,
"Vpmg_energy: calculating full PBE energy\n");
1267 Vnm_print(0,
"Vpmg_energy: qmEnergy = %1.12E kT\n", qmEnergy);
1269 Vnm_print(0,
"Vpmg_energy: qfEnergy = %1.12E kT\n", qfEnergy);
1271 Vnm_print(0,
"Vpmg_energy: dielEnergy = %1.12E kT\n", dielEnergy);
1272 totEnergy = qfEnergy - dielEnergy - qmEnergy;
1274 Vnm_print(0,
"Vpmg_energy: calculating only q-phi energy\n");
1276 Vnm_print(0,
"Vpmg_energy: qfEnergy = %1.12E kT\n", qfEnergy);
1277 totEnergy = 0.5*qfEnergy;
1305 VASSERT(thee != VNULL);
1318 Vnm_print(2,
"Vpmg_dielEnergy: Need to call Vpmg_fillco!\n");
1322 for (k=0; k<(nz-1); k++) {
1323 for (j=0; j<(ny-1); j++) {
1324 for (i=0; i<(nx-1); i++) {
1325 pvecx = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i+1,j,k)]);
1326 pvecy = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j+1,k)]);
1327 pvecz = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j,k+1)]);
1328 nrgx = thee->
epsx[IJK(i,j,k)]*pvecx
1329 * VSQR((thee->
u[IJK(i,j,k)]-thee->
u[IJK(i+1,j,k)])/hx);
1330 nrgy = thee->
epsy[IJK(i,j,k)]*pvecy
1331 * VSQR((thee->
u[IJK(i,j,k)]-thee->
u[IJK(i,j+1,k)])/hy);
1332 nrgz = thee->
epsz[IJK(i,j,k)]*pvecz
1333 * VSQR((thee->
u[IJK(i,j,k)]-thee->
u[IJK(i,j,k+1)])/hzed);
1334 energy += (nrgx + nrgy + nrgz);
1339 energy = 0.5*energy*hx*hy*hzed;
1349 double hx, hy, hzed, energy, nrgx, nrgy, nrgz, pvecx, pvecy, pvecz;
1350 int i, j, k, nx, ny, nz;
1352 VASSERT(thee != VNULL);
1365 Vnm_print(2,
"Vpmg_dielGradNorm: Need to call Vpmg_fillco!\n");
1369 for (k=1; k<nz; k++) {
1370 for (j=1; j<ny; j++) {
1371 for (i=1; i<nx; i++) {
1372 pvecx = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i-1,j,k)]);
1373 pvecy = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j-1,k)]);
1374 pvecz = 0.5*(thee->
pvec[IJK(i,j,k)]+thee->
pvec[IJK(i,j,k-1)]);
1376 * VSQR((thee->
epsx[IJK(i,j,k)]-thee->
epsx[IJK(i-1,j,k)])/hx);
1378 * VSQR((thee->
epsy[IJK(i,j,k)]-thee->
epsy[IJK(i,j-1,k)])/hy);
1380 * VSQR((thee->
epsz[IJK(i,j,k)]-thee->
epsz[IJK(i,j,k-1)])/hzed);
1381 energy += VSQRT(nrgx + nrgy + nrgz);
1386 energy = energy*hx*hy*hzed;
1400 energy = Vpmg_qmEnergyNONLIN(thee,extFlag);
1406 VPRIVATE
double Vpmg_qmEnergyNONLIN(
Vpmg *thee,
1430 VASSERT(thee != VNULL);
1443 if (zkappa2 < VSMALL) {
1446 Vnm_print(0,
"Vpmg_qmEnergy: Zero energy for zero ionic strength!\n");
1451 zks2 = 0.5*zkappa2/ionstr;
1454 Vnm_print(2,
"Vpmg_qmEnergy: Need to call Vpmg_fillco()!\n");
1462 Vnm_print(0,
"Vpmg_qmEnergy: Calculating nonlinear energy\n");
1463 for (i=0, len=nx*ny*nz; i<len; i++) {
1464 if (thee->
pvec[i]*thee->
kappa[i] > VSMALL) {
1465 for (j=0; j<nion; j++) {
1466 energy += (thee->
pvec[i]*thee->
kappa[i]*zks2
1468 * (
Vcap_exp(-ionQ[j]*thee->
u[i], &ichop)-1.0));
1474 Vnm_print(2,
"Vpmg_qmEnergy: Chopped EXP %d times!\n",nchop);
1475 Vnm_print(2,
"\nERROR! Detected large potential values in energy evaluation! \nERROR! This calculation failed -- please report to the APBS developers!\n\n");
1480 Vnm_print(0,
"Vpmg_qmEnergy: Calculating linear energy\n");
1481 for (i=0, len=nx*ny*nz; i<len; i++) {
1482 if (thee->
pvec[i]*thee->
kappa[i] > VSMALL)
1483 energy += (thee->
pvec[i]*zkappa2*thee->
kappa[i]*VSQR(thee->
u[i]));
1485 energy = 0.5*energy;
1487 energy = energy*hx*hy*hzed;
1547 VASSERT(thee != VNULL);
1560 if (zkappa2 < VSMALL) {
1563 Vnm_print(0,
"Vpmg_qmEnergySMPBE: Zero energy for zero ionic strength!\n");
1568 zks2 = 0.5*zkappa2/ionstr;
1571 Vnm_print(2,
"Vpmg_qmEnergySMPBE: Need to call Vpmg_fillco()!\n");
1601 fracOccA = Na*cb1*VCUB(a);
1602 fracOccB = Na*cb2*VCUB(a);
1603 fracOccC = Na*cb3*VCUB(a);
1605 phi = (fracOccA/k) + fracOccB + fracOccC;
1608 Vnm_print(0,
"Vpmg_qmEnergySMPBE: Calculating nonlinear energy using SMPB functional!\n");
1609 for (i=0, len=nx*ny*nz; i<len; i++) {
1610 if (((k-1) > VSMALL) && (thee->
pvec[i]*thee->
kappa[i] > VSMALL)) {
1612 a1 =
Vcap_exp(-1.0*z1*thee->
u[i], &ichop1);
1613 a2 =
Vcap_exp(-1.0*z2*thee->
u[i], &ichop2);
1614 a3 =
Vcap_exp(-1.0*z3*thee->
u[i], &ichop3);
1616 nchop += ichop1 + ichop2 + ichop3;
1618 gpark = (1 - phi + (fracOccA/k)*a1);
1619 denom = VPOW(gpark, k) + VPOW(1-fracOccB-fracOccC, k-1)*(fracOccB*a2+fracOccC*a3);
1622 c1 = Na*cb1*VPOW(gpark, k-1)*a1/denom;
1623 if(c1 != c1) c1 = 0.;
1627 c2 = Na*cb2*VPOW(1-fracOccB-fracOccC,k-1)*a2/denom;
1628 if(c2 != c2) c2 = 0.;
1632 c3 = Na*cb3*VPOW(1-fracOccB-fracOccC,k-1)*a3/denom;
1633 if(c3 != c3) c3 = 0.;
1636 currEnergy = k*VLOG((1-(c1*VCUB(a)/k)-c2*VCUB(a)-c3*VCUB(a))/(1-phi))
1637 -(k-1)*VLOG((1-c2*VCUB(a)-c3*VCUB(a))/(1-phi+(fracOccA/k)));
1639 energy += thee->
pvec[i]*thee->
kappa[i]*currEnergy;
1641 }
else if (thee->
pvec[i]*thee->
kappa[i] > VSMALL){
1643 a1 =
Vcap_exp(-1.0*z1*thee->
u[i], &ichop1);
1644 a2 =
Vcap_exp(-1.0*z2*thee->
u[i], &ichop2);
1645 a3 =
Vcap_exp(-1.0*z3*thee->
u[i], &ichop3);
1647 nchop += ichop1 + ichop2 + ichop3;
1649 gpark = (1 - phi + (fracOccA)*a1);
1650 denom = gpark + (fracOccB*a2+fracOccC*a3);
1653 c1 = Na*cb1*a1/denom;
1654 if(c1 != c1) c1 = 0.;
1658 c2 = Na*cb2*a2/denom;
1659 if(c2 != c2) c2 = 0.;
1663 c3 = Na*cb3*a3/denom;
1664 if(c3 != c3) c3 = 0.;
1667 currEnergy = VLOG((1-c1*VCUB(a)-c2*VCUB(a)-c3*VCUB(a))/(1-fracOccA-fracOccB-fracOccC));
1669 energy += thee->
pvec[i]*thee->
kappa[i]*currEnergy;
1673 energy = -energy/VCUB(a);
1675 if (nchop > 0) Vnm_print(2,
"Vpmg_qmEnergySMPBE: Chopped EXP %d times!\n",
1680 Vnm_print(0,
"Vpmg_qmEnergySMPBE: ERROR: NO LINEAR ENERGY!! Returning 0!\n");
1685 energy = energy*hx*hy*hzed;
1696 double energy = 0.0;
1698 VASSERT(thee != VNULL);
1713 int iatom, nx, ny, nz, ihi, ilo, jhi, jlo, khi, klo;
1714 double xmax, ymax, zmax, xmin, ymin, zmin, hx, hy, hzed, ifloat, jfloat;
1715 double charge, kfloat, dx, dy, dz, energy, uval, *position;
1724 VASSERT(alist != VNULL);
1754 ifloat = (position[0] - xmin)/hx;
1755 jfloat = (position[1] - ymin)/hy;
1756 kfloat = (position[2] - zmin)/hzed;
1757 ihi = (int)ceil(ifloat);
1758 ilo = (int)floor(ifloat);
1759 jhi = (int)ceil(jfloat);
1760 jlo = (int)floor(jfloat);
1761 khi = (int)ceil(kfloat);
1762 klo = (int)floor(kfloat);
1766 if ((ihi<nx) && (jhi<ny) && (khi<nz) &&
1767 (ilo>=0) && (jlo>=0) && (klo>=0)) {
1770 dx = ifloat - (double)(ilo);
1771 dy = jfloat - (double)(jlo);
1772 dz = kfloat - (double)(klo);
1774 dx*dy*dz*u[IJK(ihi,jhi,khi)]
1775 + dx*(1.0-dy)*dz*u[IJK(ihi,jlo,khi)]
1776 + dx*dy*(1.0-dz)*u[IJK(ihi,jhi,klo)]
1777 + dx*(1.0-dy)*(1.0-dz)*u[IJK(ihi,jlo,klo)]
1778 + (1.0-dx)*dy*dz*u[IJK(ilo,jhi,khi)]
1779 + (1.0-dx)*(1.0-dy)*dz*u[IJK(ilo,jlo,khi)]
1780 + (1.0-dx)*dy*(1.0-dz)*u[IJK(ilo,jhi,klo)]
1781 + (1.0-dx)*(1.0-dy)*(1.0-dz)*u[IJK(ilo,jlo,klo)];
1782 energy += (uval*charge*atom->
partID);
1784 Vnm_print(2,
"Vpmg_qfEnergy: Atom #%d at (%4.3f, %4.3f, \ 1785 %4.3f) is off the mesh (ignoring)!\n",
1786 iatom, position[0], position[1], position[2]);
1798 int nx, ny, nz, ihi, ilo, jhi, jlo, khi, klo;
1799 double xmax, xmin, ymax, ymin, zmax, zmin, hx, hy, hzed, ifloat, jfloat;
1800 double charge, kfloat, dx, dy, dz, energy, uval, *position;
1811 xmax = thee->
xf[nx-1];
1812 ymax = thee->
yf[ny-1];
1813 zmax = thee->
zf[nz-1];
1827 ifloat = (position[0] - xmin)/hx;
1828 jfloat = (position[1] - ymin)/hy;
1829 kfloat = (position[2] - zmin)/hzed;
1830 ihi = (int)ceil(ifloat);
1831 ilo = (int)floor(ifloat);
1832 jhi = (int)ceil(jfloat);
1833 jlo = (int)floor(jfloat);
1834 khi = (int)ceil(kfloat);
1835 klo = (int)floor(kfloat);
1839 if ((ihi<nx) && (jhi<ny) && (khi<nz) &&
1840 (ilo>=0) && (jlo>=0) && (klo>=0)) {
1843 dx = ifloat - (double)(ilo);
1844 dy = jfloat - (double)(jlo);
1845 dz = kfloat - (double)(klo);
1847 dx*dy*dz*u[IJK(ihi,jhi,khi)]
1848 + dx*(1.0-dy)*dz*u[IJK(ihi,jlo,khi)]
1849 + dx*dy*(1.0-dz)*u[IJK(ihi,jhi,klo)]
1850 + dx*(1.0-dy)*(1.0-dz)*u[IJK(ihi,jlo,klo)]
1851 + (1.0-dx)*dy*dz*u[IJK(ilo,jhi,khi)]
1852 + (1.0-dx)*(1.0-dy)*dz*u[IJK(ilo,jlo,khi)]
1853 + (1.0-dx)*dy*(1.0-dz)*u[IJK(ilo,jhi,klo)]
1854 + (1.0-dx)*(1.0-dy)*(1.0-dz)*u[IJK(ilo,jlo,klo)];
1855 energy += (uval*charge*atom->
partID);
1857 Vnm_print(2,
"Vpmg_qfAtomEnergy: Atom at (%4.3f, %4.3f, \ 1858 %4.3f) is off the mesh (ignoring)!\n",
1859 position[0], position[1], position[2]);
1868 double hx, hy, hzed, energy;
1871 VASSERT(thee != VNULL);
1882 Vnm_print(2,
"Vpmg_qfEnergyVolume: need to call Vpmg_fillco!\n");
1887 Vnm_print(0,
"Vpmg_qfEnergyVolume: Calculating energy\n");
1888 for (i=0; i<(nx*ny*nz); i++) {
1889 energy += (thee->
pvec[i]*thee->
u[i]*thee->
charge[i]);
1899 double infrad,
Vatom *atom,
double *force){
1912 Vnm_print(2,
"Vpmg_dbnbForce: Unknown surface method.\n");
1919 VPRIVATE
void focusFillBound(
Vpmg *thee,
1992 xminNEW = thee->
pmgp->
xcent - ((double)(nxNEW-1)*hxNEW)/2.0;
1993 xmaxNEW = thee->
pmgp->
xcent + ((double)(nxNEW-1)*hxNEW)/2.0;
1994 yminNEW = thee->
pmgp->
ycent - ((double)(nyNEW-1)*hyNEW)/2.0;
1995 ymaxNEW = thee->
pmgp->
ycent + ((double)(nyNEW-1)*hyNEW)/2.0;
1996 zminNEW = thee->
pmgp->
zcent - ((double)(nzNEW-1)*hzNEW)/2.0;
1997 zmaxNEW = thee->
pmgp->
zcent + ((double)(nzNEW-1)*hzNEW)/2.0;
1999 if(pmgOLD != VNULL){
2001 hxOLD = pmgOLD->
pmgp->
hx;
2002 hyOLD = pmgOLD->
pmgp->
hy;
2004 nxOLD = pmgOLD->
pmgp->
nx;
2005 nyOLD = pmgOLD->
pmgp->
ny;
2006 nzOLD = pmgOLD->
pmgp->
nz;
2007 xminOLD = pmgOLD->
pmgp->
xcent - ((double)(nxOLD-1)*hxOLD)/2.0;
2008 xmaxOLD = pmgOLD->
pmgp->
xcent + ((double)(nxOLD-1)*hxOLD)/2.0;
2009 yminOLD = pmgOLD->
pmgp->
ycent - ((double)(nyOLD-1)*hyOLD)/2.0;
2010 ymaxOLD = pmgOLD->
pmgp->
ycent + ((double)(nyOLD-1)*hyOLD)/2.0;
2011 zminOLD = pmgOLD->
pmgp->
zcent - ((double)(nzOLD-1)*hzOLD)/2.0;
2012 zmaxOLD = pmgOLD->
pmgp->
zcent + ((double)(nzOLD-1)*hzOLD)/2.0;
2053 pre1 = pre1*(1.0e10);
2059 if (VABS(xminOLD-xminNEW) < VSMALL) xminNEW = xminOLD;
2060 if (VABS(xmaxOLD-xmaxNEW) < VSMALL) xmaxNEW = xmaxOLD;
2061 if (VABS(yminOLD-yminNEW) < VSMALL) yminNEW = yminOLD;
2062 if (VABS(ymaxOLD-ymaxNEW) < VSMALL) ymaxNEW = ymaxOLD;
2063 if (VABS(zminOLD-zminNEW) < VSMALL) zminNEW = zminOLD;
2064 if (VABS(zmaxOLD-zmaxNEW) < VSMALL) zmaxNEW = zmaxOLD;
2068 Vnm_print(0,
"VPMG::focusFillBound -- New mesh mins = %g, %g, %g\n",
2069 xminNEW, yminNEW, zminNEW);
2070 Vnm_print(0,
"VPMG::focusFillBound -- New mesh maxs = %g, %g, %g\n",
2071 xmaxNEW, ymaxNEW, zmaxNEW);
2072 Vnm_print(0,
"VPMG::focusFillBound -- Old mesh mins = %g, %g, %g\n",
2073 xminOLD, yminOLD, zminOLD);
2074 Vnm_print(0,
"VPMG::focusFillBound -- Old mesh maxs = %g, %g, %g\n",
2075 xmaxOLD, ymaxOLD, zmaxOLD);
2079 if ((xmaxNEW>xmaxOLD) || (ymaxNEW>ymaxOLD) || (zmaxNEW>zmaxOLD) ||
2080 (xminOLD>xminNEW) || (yminOLD>yminNEW) || (zminOLD>zminNEW)) {
2082 Vnm_print(2,
"Vpmg::focusFillBound -- new mesh not contained in old!\n");
2083 Vnm_print(2,
"Vpmg::focusFillBound -- old mesh min = (%g, %g, %g)\n",
2084 xminOLD, yminOLD, zminOLD);
2085 Vnm_print(2,
"Vpmg::focusFillBound -- old mesh max = (%g, %g, %g)\n",
2086 xmaxOLD, ymaxOLD, zmaxOLD);
2087 Vnm_print(2,
"Vpmg::focusFillBound -- new mesh min = (%g, %g, %g)\n",
2088 xminNEW, yminNEW, zminNEW);
2089 Vnm_print(2,
"Vpmg::focusFillBound -- new mesh max = (%g, %g, %g)\n",
2090 xmaxNEW, ymaxNEW, zmaxNEW);
2099 for (k=0; k<nzNEW; k++) {
2100 for (j=0; j<nyNEW; j++) {
2103 y = yminNEW + j*hyNEW;
2104 z = zminNEW + k*hzNEW;
2105 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2106 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2107 ifloat = (x - xminOLD)/hxOLD;
2108 jfloat = (y - yminOLD)/hyOLD;
2109 kfloat = (z - zminOLD)/hzOLD;
2110 ihi = (int)ceil(ifloat);
2111 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2112 ilo = (int)floor(ifloat);
2113 if (ilo < 0) ilo = 0;
2114 jhi = (int)ceil(jfloat);
2115 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2116 jlo = (int)floor(jfloat);
2117 if (jlo < 0) jlo = 0;
2118 khi = (int)ceil(kfloat);
2119 if (khi > (nzOLD-1)) khi = nzOLD-1;
2120 klo = (int)floor(kfloat);
2121 if (klo < 0) klo = 0;
2122 dx = ifloat - (double)(ilo);
2123 dy = jfloat - (double)(jlo);
2124 dz = kfloat - (double)(klo);
2125 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2126 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2127 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2128 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2129 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2130 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2131 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2132 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2133 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2134 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2136 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \ 2137 %g!\n", __FILE__, __LINE__, x, y, z);
2138 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \ 2139 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2140 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \ 2141 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2144 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2145 thee->
gxcf[IJKx(j,k,0)] = uval;
2146 if(uval < uvalMin) uvalMin = uval;
2147 if(uval > uvalMax) uvalMax = uval;
2151 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2152 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2153 ifloat = (x - xminOLD)/hxOLD;
2154 jfloat = (y - yminOLD)/hyOLD;
2155 kfloat = (z - zminOLD)/hzOLD;
2156 ihi = (int)ceil(ifloat);
2157 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2158 ilo = (int)floor(ifloat);
2159 if (ilo < 0) ilo = 0;
2160 jhi = (int)ceil(jfloat);
2161 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2162 jlo = (int)floor(jfloat);
2163 if (jlo < 0) jlo = 0;
2164 khi = (int)ceil(kfloat);
2165 if (khi > (nzOLD-1)) khi = nzOLD-1;
2166 klo = (int)floor(kfloat);
2167 if (klo < 0) klo = 0;
2168 dx = ifloat - (double)(ilo);
2169 dy = jfloat - (double)(jlo);
2170 dz = kfloat - (double)(klo);
2171 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2172 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2173 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2174 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2175 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2176 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2177 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2178 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2179 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2180 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2182 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \ 2183 %g!\n", __FILE__, __LINE__, x, y, z);
2184 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \ 2185 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2186 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \ 2187 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2190 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2191 thee->
gxcf[IJKx(j,k,1)] = uval;
2192 if(uval < uvalMin) uvalMin = uval;
2193 if(uval > uvalMax) uvalMax = uval;
2196 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2197 thee->
gxcf[IJKx(j,k,2)] = 0.0;
2198 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2199 thee->
gxcf[IJKx(j,k,3)] = 0.0;
2204 for (k=0; k<nzNEW; k++) {
2205 for (i=0; i<nxNEW; i++) {
2207 x = xminNEW + i*hxNEW;
2209 z = zminNEW + k*hzNEW;
2210 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2211 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2212 ifloat = (x - xminOLD)/hxOLD;
2213 jfloat = (y - yminOLD)/hyOLD;
2214 kfloat = (z - zminOLD)/hzOLD;
2215 ihi = (int)ceil(ifloat);
2216 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2217 ilo = (int)floor(ifloat);
2218 if (ilo < 0) ilo = 0;
2219 jhi = (int)ceil(jfloat);
2220 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2221 jlo = (int)floor(jfloat);
2222 if (jlo < 0) jlo = 0;
2223 khi = (int)ceil(kfloat);
2224 if (khi > (nzOLD-1)) khi = nzOLD-1;
2225 klo = (int)floor(kfloat);
2226 if (klo < 0) klo = 0;
2227 dx = ifloat - (double)(ilo);
2228 dy = jfloat - (double)(jlo);
2229 dz = kfloat - (double)(klo);
2230 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2231 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2232 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2233 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2234 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2235 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2236 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2237 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2238 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2239 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2241 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \ 2242 %g!\n", __FILE__, __LINE__, x, y, z);
2243 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \ 2244 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2245 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \ 2246 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2249 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2250 thee->
gycf[IJKy(i,k,0)] = uval;
2251 if(uval < uvalMin) uvalMin = uval;
2252 if(uval > uvalMax) uvalMax = uval;
2256 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2257 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2258 ifloat = (x - xminOLD)/hxOLD;
2259 jfloat = (y - yminOLD)/hyOLD;
2260 kfloat = (z - zminOLD)/hzOLD;
2261 ihi = (int)ceil(ifloat);
2262 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2263 ilo = (int)floor(ifloat);
2264 if (ilo < 0) ilo = 0;
2265 jhi = (int)ceil(jfloat);
2266 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2267 jlo = (int)floor(jfloat);
2268 if (jlo < 0) jlo = 0;
2269 khi = (int)ceil(kfloat);
2270 if (khi > (nzOLD-1)) khi = nzOLD-1;
2271 klo = (int)floor(kfloat);
2272 if (klo < 0) klo = 0;
2273 dx = ifloat - (double)(ilo);
2274 dy = jfloat - (double)(jlo);
2275 dz = kfloat - (double)(klo);
2276 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2277 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2278 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2279 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2280 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2281 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2282 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2283 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2284 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2285 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2287 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \ 2288 %g!\n", __FILE__, __LINE__, x, y, z);
2289 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \ 2290 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2291 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \ 2292 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2295 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2296 thee->
gycf[IJKy(i,k,1)] = uval;
2297 if(uval < uvalMin) uvalMin = uval;
2298 if(uval > uvalMax) uvalMax = uval;
2301 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2302 thee->
gycf[IJKy(i,k,2)] = 0.0;
2303 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2304 thee->
gycf[IJKy(i,k,3)] = 0.0;
2309 for (j=0; j<nyNEW; j++) {
2310 for (i=0; i<nxNEW; i++) {
2312 x = xminNEW + i*hxNEW;
2313 y = yminNEW + j*hyNEW;
2315 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2316 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2317 ifloat = (x - xminOLD)/hxOLD;
2318 jfloat = (y - yminOLD)/hyOLD;
2319 kfloat = (z - zminOLD)/hzOLD;
2320 ihi = (int)ceil(ifloat);
2321 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2322 ilo = (int)floor(ifloat);
2323 if (ilo < 0) ilo = 0;
2324 jhi = (int)ceil(jfloat);
2325 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2326 jlo = (int)floor(jfloat);
2327 if (jlo < 0) jlo = 0;
2328 khi = (int)ceil(kfloat);
2329 if (khi > (nzOLD-1)) khi = nzOLD-1;
2330 klo = (int)floor(kfloat);
2331 if (klo < 0) klo = 0;
2332 dx = ifloat - (double)(ilo);
2333 dy = jfloat - (double)(jlo);
2334 dz = kfloat - (double)(klo);
2335 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2336 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2337 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2338 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2339 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2340 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2341 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2342 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2343 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2344 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2346 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \ 2347 %g!\n", __FILE__, __LINE__, x, y, z);
2348 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \ 2349 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2350 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \ 2351 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2354 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2355 thee->
gzcf[IJKz(i,j,0)] = uval;
2356 if(uval < uvalMin) uvalMin = uval;
2357 if(uval > uvalMax) uvalMax = uval;
2361 if ((x >= (xminOLD-VSMALL)) && (y >= (yminOLD-VSMALL)) && (z >= (zminOLD-VSMALL)) &&
2362 (x <= (xmaxOLD+VSMALL)) && (y <= (ymaxOLD+VSMALL)) && (z <= (zmaxOLD+VSMALL))) {
2363 ifloat = (x - xminOLD)/hxOLD;
2364 jfloat = (y - yminOLD)/hyOLD;
2365 kfloat = (z - zminOLD)/hzOLD;
2366 ihi = (int)ceil(ifloat);
2367 if (ihi > (nxOLD-1)) ihi = nxOLD-1;
2368 ilo = (int)floor(ifloat);
2369 if (ilo < 0) ilo = 0;
2370 jhi = (int)ceil(jfloat);
2371 if (jhi > (nyOLD-1)) jhi = nyOLD-1;
2372 jlo = (int)floor(jfloat);
2373 if (jlo < 0) jlo = 0;
2374 khi = (int)ceil(kfloat);
2375 if (khi > (nzOLD-1)) khi = nzOLD-1;
2376 klo = (int)floor(kfloat);
2377 if (klo < 0) klo = 0;
2378 dx = ifloat - (double)(ilo);
2379 dy = jfloat - (double)(jlo);
2380 dz = kfloat - (double)(klo);
2381 nx = nxOLD; ny = nyOLD; nz = nzOLD;
2382 uval = dx*dy*dz*(data[IJK(ihi,jhi,khi)])
2383 + dx*(1.0-dy)*dz*(data[IJK(ihi,jlo,khi)])
2384 + dx*dy*(1.0-dz)*(data[IJK(ihi,jhi,klo)])
2385 + dx*(1.0-dy)*(1.0-dz)*(data[IJK(ihi,jlo,klo)])
2386 + (1.0-dx)*dy*dz*(data[IJK(ilo,jhi,khi)])
2387 + (1.0-dx)*(1.0-dy)*dz*(data[IJK(ilo,jlo,khi)])
2388 + (1.0-dx)*dy*(1.0-dz)*(data[IJK(ilo,jhi,klo)])
2389 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(data[IJK(ilo,jlo,klo)]);
2390 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2392 Vnm_print(2,
"focusFillBound (%s, %d): Off old mesh at %g, %g \ 2393 %g!\n", __FILE__, __LINE__, x, y, z);
2394 Vnm_print(2,
"focusFillBound (%s, %d): old mesh lower corner at \ 2395 %g %g %g.\n", __FILE__, __LINE__, xminOLD, yminOLD, zminOLD);
2396 Vnm_print(2,
"focusFillBound (%s, %d): old mesh upper corner at \ 2397 %g %g %g.\n", __FILE__, __LINE__, xmaxOLD, ymaxOLD, zmaxOLD);
2400 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2401 thee->
gzcf[IJKz(i,j,1)] = uval;
2402 if(uval < uvalMin) uvalMin = uval;
2403 if(uval > uvalMax) uvalMax = uval;
2406 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2407 thee->
gzcf[IJKz(i,j,2)] = 0.0;
2408 nx = nxNEW; ny = nyNEW; nz = nzNEW;
2409 thee->
gzcf[IJKz(i,j,3)] = 0.0;
2415 "Unusually large potential values\n" 2416 " detected on the focusing boundary!\n" 2417 " Convergence not guaranteed for NPBE/NRPBE calculations!" 2422 double partMin[3],
double partMax[3],
int bflags[6]) {
2425 double hxNEW, hyNEW, hzNEW;
2426 double lowerCorner[3], upperCorner[3];
2427 int nxNEW, nyNEW, nzNEW;
2428 int nxOLD, nyOLD, nzOLD;
2430 double xmin, xmax, ymin, ymax, zmin, zmax;
2431 double hxOLD, hyOLD, hzOLD;
2432 double xval, yval, zval;
2450 lowerCorner[0] = thee->
pmgp->
xcent - ((double)(nxNEW-1)*hxNEW)/2.0;
2451 upperCorner[0] = thee->
pmgp->
xcent + ((double)(nxNEW-1)*hxNEW)/2.0;
2452 lowerCorner[1] = thee->
pmgp->
ycent - ((double)(nyNEW-1)*hyNEW)/2.0;
2453 upperCorner[1] = thee->
pmgp->
ycent + ((double)(nyNEW-1)*hyNEW)/2.0;
2454 lowerCorner[2] = thee->
pmgp->
zcent - ((double)(nzNEW-1)*hzNEW)/2.0;
2455 upperCorner[2] = thee->
pmgp->
zcent + ((double)(nzNEW-1)*hzNEW)/2.0;
2457 Vnm_print(0,
"VPMG::extEnergy: energy flag = %d\n", extFlag);
2460 nxOLD = pmgOLD->
pmgp->
nx;
2461 nyOLD = pmgOLD->
pmgp->
ny;
2462 nzOLD = pmgOLD->
pmgp->
nz;
2467 Vpmg_setPart(pmgOLD, lowerCorner, upperCorner, bflags);
2470 Vnm_print(0,
"VPMG::extEnergy: Finding extEnergy dimensions...\n");
2471 Vnm_print(0,
"VPMG::extEnergy Disj part lower corner = (%g, %g, %g)\n",
2472 partMin[0], partMin[1], partMin[2]);
2473 Vnm_print(0,
"VPMG::extEnergy Disj part upper corner = (%g, %g, %g)\n",
2474 partMax[0], partMax[1], partMax[2]);
2478 hxOLD = pmgOLD->
pmgp->
hx;
2479 hyOLD = pmgOLD->
pmgp->
hy;
2481 xmin = pmgOLD->
pmgp->
xcent - 0.5*hxOLD*(nxOLD-1);
2482 ymin = pmgOLD->
pmgp->
ycent - 0.5*hyOLD*(nyOLD-1);
2483 zmin = pmgOLD->
pmgp->
zcent - 0.5*hzOLD*(nzOLD-1);
2484 xmax = xmin+hxOLD*(nxOLD-1);
2485 ymax = ymin+hyOLD*(nyOLD-1);
2486 zmax = zmin+hzOLD*(nzOLD-1);
2488 Vnm_print(0,
"VPMG::extEnergy Old lower corner = (%g, %g, %g)\n",
2490 Vnm_print(0,
"VPMG::extEnergy Old upper corner = (%g, %g, %g)\n",
2500 for(i=0; i<nx; i++) {
2503 if (x < partMin[0] && bflags[
VAPBS_LEFT] == 1) xval = 0;
2504 else if (x > partMax[0] && bflags[
VAPBS_RIGHT] == 1) xval = 0;
2506 for(j=0; j<ny; j++) {
2509 if (y < partMin[1] && bflags[
VAPBS_BACK] == 1) yval = 0;
2510 else if (y > partMax[1] && bflags[
VAPBS_FRONT] == 1) yval = 0;
2512 for(k=0; k<nz; k++) {
2515 if (z < partMin[2] && bflags[
VAPBS_DOWN] == 1) zval = 0;
2516 else if (z > partMax[2] && bflags[
VAPBS_UP] == 1) zval = 0;
2518 if (pmgOLD->
pvec[IJK(i,j,k)] > VSMALL) pmgOLD->
pvec[IJK(i,j,k)] = 1.0;
2519 pmgOLD->
pvec[IJK(i,j,k)] = (1 - (pmgOLD->
pvec[IJK(i,j,k)])) * (xval*yval*zval);
2532 if (x < partMin[0] && bflags[
VAPBS_LEFT] == 1) xval = 0;
2533 else if (x > partMax[0] && bflags[
VAPBS_RIGHT] == 1) xval = 0;
2534 if (y < partMin[1] && bflags[
VAPBS_BACK] == 1) yval = 0;
2535 else if (y > partMax[1] && bflags[
VAPBS_FRONT] == 1) yval = 0;
2536 if (z < partMin[2] && bflags[
VAPBS_DOWN] == 1) zval = 0;
2537 else if (z > partMax[2] && bflags[
VAPBS_UP] == 1) zval = 0;
2544 Vnm_print(0,
"VPMG::extEnergy: extQmEnergy = %g kT\n", thee->
extQmEnergy);
2546 Vnm_print(0,
"VPMG::extEnergy: extQfEnergy = %g kT\n", thee->
extQfEnergy);
2548 Vnm_print(0,
"VPMG::extEnergy: extDiEnergy = %g kT\n", thee->
extDiEnergy);
2552 VPRIVATE
double bcfl1sp(
double size,
double *apos,
double charge,
2553 double xkappa,
double pre1,
double *pos) {
2557 dist = VSQRT(VSQR(pos[0]-apos[0]) + VSQR(pos[1]-apos[1])
2558 + VSQR(pos[2]-apos[2]));
2559 if (xkappa > VSMALL) {
2560 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2563 val = pre1*(charge/dist);
2569 VPRIVATE
void bcfl1(
double size,
double *apos,
double charge,
2570 double xkappa,
double pre1,
double *gxcf,
double *gycf,
double *gzcf,
2571 double *xf,
double *yf,
double *zf,
int nx,
int ny,
int nz) {
2578 for (k=0; k<nz; k++) {
2580 for (j=0; j<ny; j++) {
2583 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2584 + VSQR(gpos[2]-apos[2]));
2585 if (xkappa > VSMALL) {
2586 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2589 val = pre1*(charge/dist);
2591 gxcf[IJKx(j,k,0)] += val;
2593 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2594 + VSQR(gpos[2]-apos[2]));
2595 if (xkappa > VSMALL) {
2596 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2599 val = pre1*(charge/dist);
2601 gxcf[IJKx(j,k,1)] += val;
2606 for (k=0; k<nz; k++) {
2608 for (i=0; i<nx; i++) {
2611 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2612 + VSQR(gpos[2]-apos[2]));
2613 if (xkappa > VSMALL) {
2614 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2617 val = pre1*(charge/dist);
2619 gycf[IJKy(i,k,0)] += val;
2621 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2622 + VSQR(gpos[2]-apos[2]));
2623 if (xkappa > VSMALL) {
2624 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2627 val = pre1*(charge/dist);
2629 gycf[IJKy(i,k,1)] += val;
2634 for (j=0; j<ny; j++) {
2636 for (i=0; i<nx; i++) {
2639 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2640 + VSQR(gpos[2]-apos[2]));
2641 if (xkappa > VSMALL) {
2642 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2645 val = pre1*(charge/dist);
2647 gzcf[IJKz(i,j,0)] += val;
2649 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
2650 + VSQR(gpos[2]-apos[2]));
2651 if (xkappa > VSMALL) {
2652 val = pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
2655 val = pre1*(charge/dist);
2657 gzcf[IJKz(i,j,1)] += val;
2662 VPRIVATE
void bcfl2(
double size,
double *apos,
2663 double charge,
double *dipole,
double *quad,
2664 double xkappa,
double eps_p,
double eps_w,
double T,
2665 double *gxcf,
double *gycf,
double *gzcf,
2666 double *xf,
double *yf,
double *zf,
2667 int nx,
int ny,
int nz) {
2671 double gpos[3],tensor[3];
2672 double ux,uy,uz,xr,yr,zr;
2673 double qxx,qxy,qxz,qyx,qyy,qyz,qzx,qzy,qzz;
2676 VASSERT(dipole != VNULL);
2680 if (quad != VNULL) {
2685 qxx = quad[0] / 3.0;
2686 qxy = quad[1] / 3.0;
2687 qxz = quad[2] / 3.0;
2688 qyx = quad[3] / 3.0;
2689 qyy = quad[4] / 3.0;
2690 qyz = quad[5] / 3.0;
2691 qzx = quad[6] / 3.0;
2692 qzy = quad[7] / 3.0;
2693 qzz = quad[8] / 3.0;
2710 for (k=0; k<nz; k++) {
2712 for (j=0; j<ny; j++) {
2715 xr = gpos[0] - apos[0];
2716 yr = gpos[1] - apos[1];
2717 zr = gpos[2] - apos[2];
2718 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2719 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2720 val = pre*charge*tensor[0];
2721 val -= pre*ux*xr*tensor[1];
2722 val -= pre*uy*yr*tensor[1];
2723 val -= pre*uz*zr*tensor[1];
2724 val += pre*qxx*xr*xr*tensor[2];
2725 val += pre*qyy*yr*yr*tensor[2];
2726 val += pre*qzz*zr*zr*tensor[2];
2727 val += pre*2.0*qxy*xr*yr*tensor[2];
2728 val += pre*2.0*qxz*xr*zr*tensor[2];
2729 val += pre*2.0*qyz*yr*zr*tensor[2];
2730 gxcf[IJKx(j,k,0)] += val;
2733 xr = gpos[0] - apos[0];
2734 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2735 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2736 val = pre*charge*tensor[0];
2737 val -= pre*ux*xr*tensor[1];
2738 val -= pre*uy*yr*tensor[1];
2739 val -= pre*uz*zr*tensor[1];
2740 val += pre*qxx*xr*xr*tensor[2];
2741 val += pre*qyy*yr*yr*tensor[2];
2742 val += pre*qzz*zr*zr*tensor[2];
2743 val += pre*2.0*qxy*xr*yr*tensor[2];
2744 val += pre*2.0*qxz*xr*zr*tensor[2];
2745 val += pre*2.0*qyz*yr*zr*tensor[2];
2746 gxcf[IJKx(j,k,1)] += val;
2751 for (k=0; k<nz; k++) {
2753 for (i=0; i<nx; i++) {
2756 xr = gpos[0] - apos[0];
2757 yr = gpos[1] - apos[1];
2758 zr = gpos[2] - apos[2];
2759 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2760 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2761 val = pre*charge*tensor[0];
2762 val -= pre*ux*xr*tensor[1];
2763 val -= pre*uy*yr*tensor[1];
2764 val -= pre*uz*zr*tensor[1];
2765 val += pre*qxx*xr*xr*tensor[2];
2766 val += pre*qyy*yr*yr*tensor[2];
2767 val += pre*qzz*zr*zr*tensor[2];
2768 val += pre*2.0*qxy*xr*yr*tensor[2];
2769 val += pre*2.0*qxz*xr*zr*tensor[2];
2770 val += pre*2.0*qyz*yr*zr*tensor[2];
2771 gycf[IJKy(i,k,0)] += val;
2774 yr = gpos[1] - apos[1];
2775 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2776 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2777 val = pre*charge*tensor[0];
2778 val -= pre*ux*xr*tensor[1];
2779 val -= pre*uy*yr*tensor[1];
2780 val -= pre*uz*zr*tensor[1];
2781 val += pre*qxx*xr*xr*tensor[2];
2782 val += pre*qyy*yr*yr*tensor[2];
2783 val += pre*qzz*zr*zr*tensor[2];
2784 val += pre*2.0*qxy*xr*yr*tensor[2];
2785 val += pre*2.0*qxz*xr*zr*tensor[2];
2786 val += pre*2.0*qyz*yr*zr*tensor[2];
2787 gycf[IJKy(i,k,1)] += val;
2792 for (j=0; j<ny; j++) {
2794 for (i=0; i<nx; i++) {
2797 xr = gpos[0] - apos[0];
2798 yr = gpos[1] - apos[1];
2799 zr = gpos[2] - apos[2];
2800 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2801 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2802 val = pre*charge*tensor[0];
2803 val -= pre*ux*xr*tensor[1];
2804 val -= pre*uy*yr*tensor[1];
2805 val -= pre*uz*zr*tensor[1];
2806 val += pre*qxx*xr*xr*tensor[2];
2807 val += pre*qyy*yr*yr*tensor[2];
2808 val += pre*qzz*zr*zr*tensor[2];
2809 val += pre*2.0*qxy*xr*yr*tensor[2];
2810 val += pre*2.0*qxz*xr*zr*tensor[2];
2811 val += pre*2.0*qyz*yr*zr*tensor[2];
2812 gzcf[IJKz(i,j,0)] += val;
2815 zr = gpos[2] - apos[2];
2816 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
2817 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
2818 val = pre*charge*tensor[0];
2819 val -= pre*ux*xr*tensor[1];
2820 val -= pre*uy*yr*tensor[1];
2821 val -= pre*uz*zr*tensor[1];
2822 val += pre*qxx*xr*xr*tensor[2];
2823 val += pre*qyy*yr*yr*tensor[2];
2824 val += pre*qzz*zr*zr*tensor[2];
2825 val += pre*2.0*qxy*xr*yr*tensor[2];
2826 val += pre*2.0*qxz*xr*zr*tensor[2];
2827 val += pre*2.0*qyz*yr*zr*tensor[2];
2828 gzcf[IJKz(i,j,1)] += val;
2833 VPRIVATE
void bcCalcOrig(
Vpmg *thee) {
2836 double size, *position, charge, xkappa, eps_w, T, pre1;
2837 double *dipole, *quadrupole, debye, eps_p;
2838 double xr,yr,zr,qave,*apos;
2839 double sdhcharge, sdhdipole[3], traced[9], sdhquadrupole[9];
2853 for (k=0; k<nz; k++) {
2854 for (j=0; j<ny; j++) {
2855 thee->
gxcf[IJKx(j,k,0)] = 0.0;
2856 thee->
gxcf[IJKx(j,k,1)] = 0.0;
2857 thee->
gxcf[IJKx(j,k,2)] = 0.0;
2858 thee->
gxcf[IJKx(j,k,3)] = 0.0;
2863 for (k=0; k<nz; k++) {
2864 for (i=0; i<nx; i++) {
2865 thee->
gycf[IJKy(i,k,0)] = 0.0;
2866 thee->
gycf[IJKy(i,k,1)] = 0.0;
2867 thee->
gycf[IJKy(i,k,2)] = 0.0;
2868 thee->
gycf[IJKy(i,k,3)] = 0.0;
2873 for (j=0; j<ny; j++) {
2874 for (i=0; i<nx; i++) {
2875 thee->
gzcf[IJKz(i,j,0)] = 0.0;
2876 thee->
gzcf[IJKz(i,j,1)] = 0.0;
2877 thee->
gzcf[IJKz(i,j,2)] = 0.0;
2878 thee->
gzcf[IJKz(i,j,3)] = 0.0;
2902 pre1 = pre1*(1.0e10);
2923 for (i=0; i<3; i++) sdhdipole[i] = 0.0;
2924 for (i=0; i<9; i++) sdhquadrupole[i] = 0.0;
2929 xr = apos[0] - position[0];
2930 yr = apos[1] - position[1];
2931 zr = apos[2] - position[2];
2935 sdhcharge += charge;
2936 sdhdipole[0] += xr * charge;
2937 sdhdipole[1] += yr * charge;
2938 sdhdipole[2] += zr * charge;
2939 traced[0] = xr*xr*charge;
2940 traced[1] = xr*yr*charge;
2941 traced[2] = xr*zr*charge;
2942 traced[3] = yr*xr*charge;
2943 traced[4] = yr*yr*charge;
2944 traced[5] = yr*zr*charge;
2945 traced[6] = zr*xr*charge;
2946 traced[7] = zr*yr*charge;
2947 traced[8] = zr*zr*charge;
2948 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
2949 sdhquadrupole[0] += 1.5*(traced[0] - qave);
2950 sdhquadrupole[1] += 1.5*(traced[1]);
2951 sdhquadrupole[2] += 1.5*(traced[2]);
2952 sdhquadrupole[3] += 1.5*(traced[3]);
2953 sdhquadrupole[4] += 1.5*(traced[4] - qave);
2954 sdhquadrupole[5] += 1.5*(traced[5]);
2955 sdhquadrupole[6] += 1.5*(traced[6]);
2956 sdhquadrupole[7] += 1.5*(traced[7]);
2957 sdhquadrupole[8] += 1.5*(traced[8] - qave);
2958 #if defined(WITH_TINKER) 2961 dipole = Vatom_getDipole(atom);
2962 quadrupole = Vatom_getQuadrupole(atom);
2963 sdhcharge += charge;
2964 sdhdipole[0] += xr * charge;
2965 sdhdipole[1] += yr * charge;
2966 sdhdipole[2] += zr * charge;
2967 traced[0] = xr*xr*charge;
2968 traced[1] = xr*yr*charge;
2969 traced[2] = xr*zr*charge;
2970 traced[3] = yr*xr*charge;
2971 traced[4] = yr*yr*charge;
2972 traced[5] = yr*zr*charge;
2973 traced[6] = zr*xr*charge;
2974 traced[7] = zr*yr*charge;
2975 traced[8] = zr*zr*charge;
2976 sdhdipole[0] += dipole[0];
2977 sdhdipole[1] += dipole[1];
2978 sdhdipole[2] += dipole[2];
2979 traced[0] += 2.0*xr*dipole[0];
2980 traced[1] += xr*dipole[1] + yr*dipole[0];
2981 traced[2] += xr*dipole[2] + zr*dipole[0];
2982 traced[3] += yr*dipole[0] + xr*dipole[1];
2983 traced[4] += 2.0*yr*dipole[1];
2984 traced[5] += yr*dipole[2] + zr*dipole[1];
2985 traced[6] += zr*dipole[0] + xr*dipole[2];
2986 traced[7] += zr*dipole[1] + yr*dipole[2];
2987 traced[8] += 2.0*zr*dipole[2];
2988 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
2989 sdhquadrupole[0] += 1.5*(traced[0] - qave);
2990 sdhquadrupole[1] += 1.5*(traced[1]);
2991 sdhquadrupole[2] += 1.5*(traced[2]);
2992 sdhquadrupole[3] += 1.5*(traced[3]);
2993 sdhquadrupole[4] += 1.5*(traced[4] - qave);
2994 sdhquadrupole[5] += 1.5*(traced[5]);
2995 sdhquadrupole[6] += 1.5*(traced[6]);
2996 sdhquadrupole[7] += 1.5*(traced[7]);
2997 sdhquadrupole[8] += 1.5*(traced[8] - qave);
2998 sdhquadrupole[0] += quadrupole[0];
2999 sdhquadrupole[1] += quadrupole[1];
3000 sdhquadrupole[2] += quadrupole[2];
3001 sdhquadrupole[3] += quadrupole[3];
3002 sdhquadrupole[4] += quadrupole[4];
3003 sdhquadrupole[5] += quadrupole[5];
3004 sdhquadrupole[6] += quadrupole[6];
3005 sdhquadrupole[7] += quadrupole[7];
3006 sdhquadrupole[8] += quadrupole[8];
3008 dipole = Vatom_getInducedDipole(atom);
3009 sdhdipole[0] += dipole[0];
3010 sdhdipole[1] += dipole[1];
3011 sdhdipole[2] += dipole[2];
3012 traced[0] = 2.0*xr*dipole[0];
3013 traced[1] = xr*dipole[1] + yr*dipole[0];
3014 traced[2] = xr*dipole[2] + zr*dipole[0];
3015 traced[3] = yr*dipole[0] + xr*dipole[1];
3016 traced[4] = 2.0*yr*dipole[1];
3017 traced[5] = yr*dipole[2] + zr*dipole[1];
3018 traced[6] = zr*dipole[0] + xr*dipole[2];
3019 traced[7] = zr*dipole[1] + yr*dipole[2];
3020 traced[8] = 2.0*zr*dipole[2];
3021 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3022 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3023 sdhquadrupole[1] += 1.5*(traced[1]);
3024 sdhquadrupole[2] += 1.5*(traced[2]);
3025 sdhquadrupole[3] += 1.5*(traced[3]);
3026 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3027 sdhquadrupole[5] += 1.5*(traced[5]);
3028 sdhquadrupole[6] += 1.5*(traced[6]);
3029 sdhquadrupole[7] += 1.5*(traced[7]);
3030 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3032 dipole = Vatom_getNLInducedDipole(atom);
3033 sdhdipole[0] += dipole[0];
3034 sdhdipole[1] += dipole[1];
3035 sdhdipole[2] += dipole[2];
3036 traced[0] = 2.0*xr*dipole[0];
3037 traced[1] = xr*dipole[1] + yr*dipole[0];
3038 traced[2] = xr*dipole[2] + zr*dipole[0];
3039 traced[3] = yr*dipole[0] + xr*dipole[1];
3040 traced[4] = 2.0*yr*dipole[1];
3041 traced[5] = yr*dipole[2] + zr*dipole[1];
3042 traced[6] = zr*dipole[0] + xr*dipole[2];
3043 traced[7] = zr*dipole[1] + yr*dipole[2];
3044 traced[8] = 2.0*zr*dipole[2];
3045 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3046 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3047 sdhquadrupole[1] += 1.5*(traced[1]);
3048 sdhquadrupole[2] += 1.5*(traced[2]);
3049 sdhquadrupole[3] += 1.5*(traced[3]);
3050 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3051 sdhquadrupole[5] += 1.5*(traced[5]);
3052 sdhquadrupole[6] += 1.5*(traced[6]);
3053 sdhquadrupole[7] += 1.5*(traced[7]);
3054 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);
3101 bcfl1(size, position, charge, xkappa, pre1,
3103 thee->
xf, thee->
yf, thee->
zf, nx, ny, nz);
3108 Vnm_print(2,
"bcCalc: Invalid bcfl (%d)!\n", thee->
pmgp->
bcfl);
3112 Vnm_print(2,
"VPMG::bcCalc -- not appropriate for focusing!\n");
3116 Vnm_print(2,
"VPMG::bcCalc -- invalid boundary condition \ 3125 VPRIVATE
int gridPointIsValid(
int i,
int j,
int k,
int nx,
int ny,
int nz){
3129 if((k==0) || (k==nz-1)){
3131 }
else if((j==0) || (j==ny-1)){
3133 }
else if((i==0) || (i==nx-1)){
3143 #ifdef DEBUG_MAC_OSX_OCL 3144 #include "mach_chud.h" 3145 VPRIVATE
void packAtomsOpenCL(
float *ax,
float *ay,
float *az,
3146 float *charge,
float *size,
Vpmg *thee){
3151 Vatom *atom = VNULL;
3157 for(i=0;i<natoms;i++){
3158 atom = &(alist->
atoms[i]);
3170 VPRIVATE
void packUnpackOpenCL(
int nx,
int ny,
int nz,
int ngrid,
3171 float *gx,
float *gy,
float *gz,
float *value,
3172 Vpmg *thee,
int pack){
3175 int x0,x1,y0,y1,z0,z1;
3178 double *xf, *yf, *zf;
3179 double *gxcf, *gycf, *gzcf;
3196 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3198 gx[igrid] = gpos[0];
3199 gy[igrid] = gpos[1];
3200 gz[igrid] = gpos[2];
3212 gxcf[x0] += value[igrid];
3215 gxcf[x1] += value[igrid];
3218 gycf[y0] += value[igrid];
3221 gycf[y1] += value[igrid];
3224 gzcf[z0] += value[igrid];
3227 gzcf[z1] += value[igrid];
3244 VPRIVATE
void bcflnewOpenCL(
Vpmg *thee){
3246 int i,j,k, iatom, igrid;
3247 int x0, x1, y0, y1, z0, z1;
3250 int natoms, ngrid, ngadj;
3252 float dist, pre1, eps_w, eps_p, T, xkappa;
3254 float *ax, *ay, *az;
3255 float *charge, *size, *val;
3257 float *gx, *gy, *gz;
3272 ngrid = 2*((nx*ny) + (ny*nz) + (nx*nz));
3273 ngadj = ngrid + (512 - (ngrid & 511));
3275 ax = (
float*)malloc(natoms *
sizeof(
float));
3276 ay = (
float*)malloc(natoms *
sizeof(
float));
3277 az = (
float*)malloc(natoms *
sizeof(
float));
3279 charge = (
float*)malloc(natoms *
sizeof(
float));
3280 size = (
float*)malloc(natoms *
sizeof(
float));
3282 gx = (
float*)malloc(ngrid *
sizeof(
float));
3283 gy = (
float*)malloc(ngrid *
sizeof(
float));
3284 gz = (
float*)malloc(ngrid *
sizeof(
float));
3286 val = (
float*)malloc(ngrid *
sizeof(
float));
3288 packAtomsOpenCL(ax,ay,az,charge,size,thee);
3289 packUnpackOpenCL(nx,ny,nz,ngrid,gx,gy,gz,val,thee,1);
3291 runMDHCL(ngrid,natoms,ngadj,ax,ay,az,gx,gy,gz,charge,size,xkappa,pre1,val);
3293 packUnpackOpenCL(nx,ny,nz,ngrid,gx,gy,gz,val,thee,0);
3308 VPRIVATE
void packAtoms(
double *ax,
double *ay,
double *az,
3309 double *charge,
double *size,
Vpmg *thee){
3314 Vatom *atom = VNULL;
3320 for(i=0;i<natoms;i++){
3321 atom = &(alist->
atoms[i]);
3333 VPRIVATE
void packUnpack(
int nx,
int ny,
int nz,
int ngrid,
3334 double *gx,
double *gy,
double *gz,
double *value,
3335 Vpmg *thee,
int pack){
3338 int x0,x1,y0,y1,z0,z1;
3341 double *xf, *yf, *zf;
3342 double *gxcf, *gycf, *gzcf;
3359 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3361 gx[igrid] = gpos[0];
3362 gy[igrid] = gpos[1];
3363 gz[igrid] = gpos[2];
3375 gxcf[x0] += value[igrid];
3378 gxcf[x1] += value[igrid];
3381 gycf[y0] += value[igrid];
3384 gycf[y1] += value[igrid];
3387 gzcf[z0] += value[igrid];
3390 gzcf[z1] += value[igrid];
3402 VPRIVATE
void bcflnew(
Vpmg *thee){
3404 int i,j,k, iatom, igrid;
3405 int x0, x1, y0, y1, z0, z1;
3410 double dist, pre1, eps_w, eps_p, T, xkappa;
3412 double *ax, *ay, *az;
3413 double *charge, *size, *val;
3415 double *gx, *gy, *gz;
3430 ngrid = 2*((nx*ny) + (ny*nz) + (nx*nz));
3432 ax = (
double*)malloc(natoms *
sizeof(
double));
3433 ay = (
double*)malloc(natoms *
sizeof(
double));
3434 az = (
double*)malloc(natoms *
sizeof(
double));
3436 charge = (
double*)malloc(natoms *
sizeof(
double));
3437 size = (
double*)malloc(natoms *
sizeof(
double));
3439 gx = (
double*)malloc(ngrid *
sizeof(
double));
3440 gy = (
double*)malloc(ngrid *
sizeof(
double));
3441 gz = (
double*)malloc(ngrid *
sizeof(
double));
3443 val = (
double*)malloc(ngrid *
sizeof(
double));
3445 packAtoms(ax,ay,az,charge,size,thee);
3446 packUnpack(nx,ny,nz,ngrid,gx,gy,gz,val,thee,1);
3448 if(xkappa > VSMALL){
3449 #pragma omp parallel for default(shared) private(igrid,iatom,dist) 3450 for(igrid=0;igrid<ngrid;igrid++){
3451 for(iatom=0; iatom<natoms; iatom++){
3452 dist = VSQRT(VSQR(gx[igrid]-ax[iatom]) + VSQR(gy[igrid]-ay[iatom])
3453 + VSQR(gz[igrid]-az[iatom]));
3454 val[igrid] += pre1*(charge[iatom]/dist)*VEXP(-xkappa*(dist-size[iatom]))
3455 / (1+xkappa*size[iatom]);
3459 #pragma omp parallel for default(shared) private(igrid,iatom,dist) 3460 for(igrid=0;igrid<ngrid;igrid++){
3461 for(iatom=0; iatom<natoms; iatom++){
3462 dist = VSQRT(VSQR(gx[igrid]-ax[iatom]) + VSQR(gy[igrid]-ay[iatom])
3463 + VSQR(gz[igrid]-az[iatom]));
3464 val[igrid] += pre1*(charge[iatom]/dist);
3468 packUnpack(nx,ny,nz,ngrid,gx,gy,gz,val,thee,0);
3483 double eps_w,
double rad,
double tsr[3]) {
3567 eps_r = eps_w/eps_p;
3571 tsr[0] = (1.0/eps_w)/r;
3572 tsr[1] = (1.0/eps_w)*(-1.0)/r3;
3573 tsr[2] = (1.0/eps_w)*(3.0)/r5;
3574 if (kappa < VSMALL) {
3575 tsr[1] = (3.0*eps_r)/(1.0 + 2.0*eps_r)*tsr[1];
3576 tsr[2] = (5.0*eps_r)/(2.0 + 3.0*eps_r)*tsr[2];
3584 tsr[0] = exp(ka-kr) / (1.0 + ka) * tsr[0];
3585 tsr[1] = 3.0*eps_r*exp(ka-kr)*(1.0 + kr) * tsr[1];
3586 tsr[1] = tsr[1] / (1.0 + ka + eps_r*(2.0 + 2.0*ka + ka2));
3587 tsr[2] = 5.0*eps_r*exp(ka-kr)*(3.0 + 3.0*kr + kr2) * tsr[2];
3588 tsr[2] = tsr[2]/(6.0+6.0*ka+2.0*ka2+eps_r*(9.0+9.0*ka+4.0*ka2+ka3));
3592 VPRIVATE
void bcfl_sdh(
Vpmg *thee){
3597 double size, *position, charge, xkappa, eps_w, eps_p, T, pre, dist;
3598 double sdhcharge, sdhdipole[3], traced[9], sdhquadrupole[9];
3599 double *dipole, *quadrupole;
3601 double val, *apos, gpos[3], tensor[3], qave;
3602 double ux, uy, uz, xr, yr, zr;
3603 double qxx,qxy,qxz,qyx,qyy,qyz,qzx,qzy,qzz;
3605 double *xf, *yf, *zf;
3606 double *gxcf, *gycf, *gzcf;
3654 for (i=0; i<3; i++) sdhdipole[i] = 0.0;
3655 for (i=0; i<9; i++) sdhquadrupole[i] = 0.0;
3660 xr = apos[0] - position[0];
3661 yr = apos[1] - position[1];
3662 zr = apos[2] - position[2];
3666 sdhcharge += charge;
3667 sdhdipole[0] += xr * charge;
3668 sdhdipole[1] += yr * charge;
3669 sdhdipole[2] += zr * charge;
3670 traced[0] = xr*xr*charge;
3671 traced[1] = xr*yr*charge;
3672 traced[2] = xr*zr*charge;
3673 traced[3] = yr*xr*charge;
3674 traced[4] = yr*yr*charge;
3675 traced[5] = yr*zr*charge;
3676 traced[6] = zr*xr*charge;
3677 traced[7] = zr*yr*charge;
3678 traced[8] = zr*zr*charge;
3679 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3680 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3681 sdhquadrupole[1] += 1.5*(traced[1]);
3682 sdhquadrupole[2] += 1.5*(traced[2]);
3683 sdhquadrupole[3] += 1.5*(traced[3]);
3684 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3685 sdhquadrupole[5] += 1.5*(traced[5]);
3686 sdhquadrupole[6] += 1.5*(traced[6]);
3687 sdhquadrupole[7] += 1.5*(traced[7]);
3688 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3689 #if defined(WITH_TINKER) 3692 dipole = Vatom_getDipole(atom);
3693 quadrupole = Vatom_getQuadrupole(atom);
3694 sdhcharge += charge;
3695 sdhdipole[0] += xr * charge;
3696 sdhdipole[1] += yr * charge;
3697 sdhdipole[2] += zr * charge;
3698 traced[0] = xr*xr*charge;
3699 traced[1] = xr*yr*charge;
3700 traced[2] = xr*zr*charge;
3701 traced[3] = yr*xr*charge;
3702 traced[4] = yr*yr*charge;
3703 traced[5] = yr*zr*charge;
3704 traced[6] = zr*xr*charge;
3705 traced[7] = zr*yr*charge;
3706 traced[8] = zr*zr*charge;
3707 sdhdipole[0] += dipole[0];
3708 sdhdipole[1] += dipole[1];
3709 sdhdipole[2] += dipole[2];
3710 traced[0] += 2.0*xr*dipole[0];
3711 traced[1] += xr*dipole[1] + yr*dipole[0];
3712 traced[2] += xr*dipole[2] + zr*dipole[0];
3713 traced[3] += yr*dipole[0] + xr*dipole[1];
3714 traced[4] += 2.0*yr*dipole[1];
3715 traced[5] += yr*dipole[2] + zr*dipole[1];
3716 traced[6] += zr*dipole[0] + xr*dipole[2];
3717 traced[7] += zr*dipole[1] + yr*dipole[2];
3718 traced[8] += 2.0*zr*dipole[2];
3719 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3720 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3721 sdhquadrupole[1] += 1.5*(traced[1]);
3722 sdhquadrupole[2] += 1.5*(traced[2]);
3723 sdhquadrupole[3] += 1.5*(traced[3]);
3724 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3725 sdhquadrupole[5] += 1.5*(traced[5]);
3726 sdhquadrupole[6] += 1.5*(traced[6]);
3727 sdhquadrupole[7] += 1.5*(traced[7]);
3728 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3729 sdhquadrupole[0] += quadrupole[0];
3730 sdhquadrupole[1] += quadrupole[1];
3731 sdhquadrupole[2] += quadrupole[2];
3732 sdhquadrupole[3] += quadrupole[3];
3733 sdhquadrupole[4] += quadrupole[4];
3734 sdhquadrupole[5] += quadrupole[5];
3735 sdhquadrupole[6] += quadrupole[6];
3736 sdhquadrupole[7] += quadrupole[7];
3737 sdhquadrupole[8] += quadrupole[8];
3739 dipole = Vatom_getInducedDipole(atom);
3740 sdhdipole[0] += dipole[0];
3741 sdhdipole[1] += dipole[1];
3742 sdhdipole[2] += dipole[2];
3743 traced[0] = 2.0*xr*dipole[0];
3744 traced[1] = xr*dipole[1] + yr*dipole[0];
3745 traced[2] = xr*dipole[2] + zr*dipole[0];
3746 traced[3] = yr*dipole[0] + xr*dipole[1];
3747 traced[4] = 2.0*yr*dipole[1];
3748 traced[5] = yr*dipole[2] + zr*dipole[1];
3749 traced[6] = zr*dipole[0] + xr*dipole[2];
3750 traced[7] = zr*dipole[1] + yr*dipole[2];
3751 traced[8] = 2.0*zr*dipole[2];
3752 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3753 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3754 sdhquadrupole[1] += 1.5*(traced[1]);
3755 sdhquadrupole[2] += 1.5*(traced[2]);
3756 sdhquadrupole[3] += 1.5*(traced[3]);
3757 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3758 sdhquadrupole[5] += 1.5*(traced[5]);
3759 sdhquadrupole[6] += 1.5*(traced[6]);
3760 sdhquadrupole[7] += 1.5*(traced[7]);
3761 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3763 dipole = Vatom_getNLInducedDipole(atom);
3764 sdhdipole[0] += dipole[0];
3765 sdhdipole[1] += dipole[1];
3766 sdhdipole[2] += dipole[2];
3767 traced[0] = 2.0*xr*dipole[0];
3768 traced[1] = xr*dipole[1] + yr*dipole[0];
3769 traced[2] = xr*dipole[2] + zr*dipole[0];
3770 traced[3] = yr*dipole[0] + xr*dipole[1];
3771 traced[4] = 2.0*yr*dipole[1];
3772 traced[5] = yr*dipole[2] + zr*dipole[1];
3773 traced[6] = zr*dipole[0] + xr*dipole[2];
3774 traced[7] = zr*dipole[1] + yr*dipole[2];
3775 traced[8] = 2.0*zr*dipole[2];
3776 qave = (traced[0] + traced[4] + traced[8]) / 3.0;
3777 sdhquadrupole[0] += 1.5*(traced[0] - qave);
3778 sdhquadrupole[1] += 1.5*(traced[1]);
3779 sdhquadrupole[2] += 1.5*(traced[2]);
3780 sdhquadrupole[3] += 1.5*(traced[3]);
3781 sdhquadrupole[4] += 1.5*(traced[4] - qave);
3782 sdhquadrupole[5] += 1.5*(traced[5]);
3783 sdhquadrupole[6] += 1.5*(traced[6]);
3784 sdhquadrupole[7] += 1.5*(traced[7]);
3785 sdhquadrupole[8] += 1.5*(traced[8] - qave);
3798 qxx = sdhquadrupole[0] / 3.0;
3799 qxy = sdhquadrupole[1] / 3.0;
3800 qxz = sdhquadrupole[2] / 3.0;
3801 qyx = sdhquadrupole[3] / 3.0;
3802 qyy = sdhquadrupole[4] / 3.0;
3803 qyz = sdhquadrupole[5] / 3.0;
3804 qzx = sdhquadrupole[6] / 3.0;
3805 qzy = sdhquadrupole[7] / 3.0;
3806 qzz = sdhquadrupole[8] / 3.0;
3814 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3815 xr = gpos[0] - position[0];
3816 yr = gpos[1] - position[1];
3817 zr = gpos[2] - position[2];
3819 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
3820 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
3822 val = pre*sdhcharge*tensor[0];
3823 val -= pre*ux*xr*tensor[1];
3824 val -= pre*uy*yr*tensor[1];
3825 val -= pre*uz*zr*tensor[1];
3826 val += pre*qxx*xr*xr*tensor[2];
3827 val += pre*qyy*yr*yr*tensor[2];
3828 val += pre*qzz*zr*zr*tensor[2];
3829 val += pre*2.0*qxy*xr*yr*tensor[2];
3830 val += pre*2.0*qxz*xr*zr*tensor[2];
3831 val += pre*2.0*qyz*yr*zr*tensor[2];
3834 gxcf[IJKx(j,k,0)] = val;
3837 gxcf[IJKx(j,k,1)] = val;
3840 gycf[IJKy(i,k,0)] = val;
3843 gycf[IJKy(i,k,1)] = val;
3846 gzcf[IJKz(i,j,0)] = val;
3849 gzcf[IJKz(i,j,1)] = val;
3858 VPRIVATE
void bcfl_mdh(
Vpmg *thee){
3863 double val, *apos, gpos[3];
3864 double *dipole, *quadrupole;
3865 double size, charge, xkappa, eps_w, eps_p, T, pre1, dist;
3867 double *xf, *yf, *zf;
3868 double *gxcf, *gycf, *gzcf;
3908 pre1 = pre1*(1.0e10);
3921 if(gridPointIsValid(i, j, k, nx, ny, nz)){
3931 dist = VSQRT(VSQR(gpos[0]-apos[0]) + VSQR(gpos[1]-apos[1])
3932 + VSQR(gpos[2]-apos[2]));
3933 if (xkappa > VSMALL) {
3934 val += pre1*(charge/dist)*VEXP(-xkappa*(dist-size))
3937 val += pre1*(charge/dist);
3943 gxcf[IJKx(j,k,0)] = val;
3946 gxcf[IJKx(j,k,1)] = val;
3949 gycf[IJKy(i,k,0)] = val;
3952 gycf[IJKy(i,k,1)] = val;
3955 gzcf[IJKz(i,j,0)] = val;
3958 gzcf[IJKz(i,j,1)] = val;
3997 double dist, val, z_low, z_high, z_shift;
3998 double A, B, C, D, edge_L, l;
3999 double G, z_0, z_rel;
4002 Vnm_print(0,
"Here is the value of kappa: %f\n",xkappa);
4003 Vnm_print(0,
"Here is the value of L: %f\n",L);
4004 Vnm_print(0,
"Here is the value of zmem: %f\n",zmem);
4005 Vnm_print(0,
"Here is the value of mdie: %f\n",eps_m);
4006 Vnm_print(0,
"Here is the value of memv: %f\n",V);
4024 G=l*eps_w/eps_m*xkappa;
4025 A=-V/2*(1/(G+1))*exp(xkappa*l);
4027 C=-V/2*eps_w/eps_m*xkappa*(1/(G+1));
4034 for (k=0; k<nz; k++) {
4036 z_rel = gpos[2] - z_0;
4038 for (j=0; j<ny; j++) {
4040 if (gpos[2] <= z_low) {
4042 val = A*exp(xkappa*z_rel) + V;
4043 gxcf[IJKx(j,k,0)] += val;
4044 gxcf[IJKx(j,k,1)] += val;
4048 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4051 gxcf[IJKx(j,k,0)] += val;
4052 gxcf[IJKx(j,k,1)] += val;
4056 else if (gpos[2] > z_high) {
4058 val = D*exp(-xkappa*z_rel);
4059 gxcf[IJKx(j,k,0)] += val;
4060 gxcf[IJKx(j,k,1)] += val;
4068 for (k=0; k<nz; k++) {
4070 z_rel = gpos[2] - z_0;
4071 for (i=0; i<nx; i++) {
4073 if (gpos[2] <= z_low) {
4075 val = A*exp(xkappa*z_rel) + V;
4076 gycf[IJKy(i,k,0)] += val;
4077 gycf[IJKy(i,k,1)] += val;
4082 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4085 gycf[IJKy(i,k,0)] += val;
4086 gycf[IJKy(i,k,1)] += val;
4090 else if (gpos[2] > z_high) {
4092 val = D*exp(-xkappa*z_rel);
4093 gycf[IJKy(i,k,0)] += val;
4094 gycf[IJKy(i,k,1)] += val;
4103 for (j=0; j<ny; j++) {
4104 for (i=0; i<nx; i++) {
4109 z_rel = gpos[2] - z_0;
4111 if (gpos[2] <= z_low) {
4113 val = A*exp(xkappa*z_rel) + V;
4114 gzcf[IJKz(i,j,0)] += val;
4119 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4122 gzcf[IJKz(i,j,0)] += val;
4126 else if (gpos[2] > z_high) {
4128 val = D*exp(-xkappa*z_rel);
4129 gzcf[IJKz(i,j,0)] += val;
4136 z_rel = gpos[2] - z_0;
4138 if (gpos[2] <= z_low) {
4140 val = A*exp(xkappa*z_rel) + V;
4141 gzcf[IJKz(i,j,1)] += val;
4145 else if (gpos[2] > z_low && gpos[2] <= z_high) {
4148 gzcf[IJKz(i,j,1)] += val;
4152 else if (gpos[2] > z_high) {
4154 val = D*exp(-xkappa*z_rel);
4155 gzcf[IJKz(i,j,1)] += val;
4164 VPRIVATE
void bcfl_map(
Vpmg *thee){
4167 double position[3], pot, hx, hy, hzed;
4168 int i, j, k, nx, ny, nz, rc;
4171 VASSERT(thee != VNULL);
4182 for (i=0; i<(nx*ny*nz); i++) thee->
pot[i] = 0.0;
4185 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
4186 for (k=0; k<nz; k++) {
4187 for (j=0; j<ny; j++) {
4188 for (i=0; i<nx; i++) {
4189 position[0] = thee->
xf[i];
4190 position[1] = thee->
yf[j];
4191 position[2] = thee->
zf[k];
4194 Vnm_print(2,
"fillcoChargeMap: Error -- fell off of potential map at (%g, %g, %g)!\n",
4195 position[0], position[1], position[2]);
4198 thee->
pot[IJK(i,j,k)] = pot;
4205 #if defined(WITH_TINKER) 4206 VPRIVATE
void bcfl_mdh_tinker(
Vpmg *thee){
4211 double val, *apos, gpos[3], tensor[9];
4212 double *dipole, *quadrupole;
4213 double size, charge, xkappa, eps_w, eps_p, T, pre1, dist;
4215 double ux,uy,uz,xr,yr,zr;
4216 double qxx,qxy,qxz,qyx,qyy,qyz,qzx,qzy,qzz;
4218 double *xf, *yf, *zf;
4219 double *gxcf, *gycf, *gzcf;
4259 pre1 = pre1*(1.0e10);
4272 if(gridPointIsValid(i, j, k, nx, ny, nz)){
4288 dipole = Vatom_getDipole(atom);
4289 quadrupole = Vatom_getQuadrupole(atom);
4291 dipole = Vatom_getInducedDipole(atom);
4293 dipole = Vatom_getNLInducedDipole(atom);
4300 if (quadrupole != VNULL) {
4305 qxx = quadrupole[0] / 3.0;
4306 qxy = quadrupole[1] / 3.0;
4307 qxz = quadrupole[2] / 3.0;
4308 qyx = quadrupole[3] / 3.0;
4309 qyy = quadrupole[4] / 3.0;
4310 qyz = quadrupole[5] / 3.0;
4311 qzx = quadrupole[6] / 3.0;
4312 qzy = quadrupole[7] / 3.0;
4313 qzz = quadrupole[8] / 3.0;
4326 xr = gpos[0] - apos[0];
4327 yr = gpos[1] - apos[1];
4328 zr = gpos[2] - apos[2];
4330 dist = VSQRT(VSQR(xr) + VSQR(yr) + VSQR(zr));
4331 multipolebc(dist, xkappa, eps_p, eps_w, size, tensor);
4333 val += pre1*charge*tensor[0];
4334 val -= pre1*ux*xr*tensor[1];
4335 val -= pre1*uy*yr*tensor[1];
4336 val -= pre1*uz*zr*tensor[1];
4337 val += pre1*qxx*xr*xr*tensor[2];
4338 val += pre1*qyy*yr*yr*tensor[2];
4339 val += pre1*qzz*zr*zr*tensor[2];
4340 val += pre1*2.0*qxy*xr*yr*tensor[2];
4341 val += pre1*2.0*qxz*xr*zr*tensor[2];
4342 val += pre1*2.0*qyz*yr*zr*tensor[2];
4347 gxcf[IJKx(j,k,0)] = val;
4350 gxcf[IJKx(j,k,1)] = val;
4353 gycf[IJKy(i,k,0)] = val;
4356 gycf[IJKy(i,k,1)] = val;
4359 gzcf[IJKz(i,j,0)] = val;
4362 gzcf[IJKz(i,j,1)] = val;
4377 double zmem, eps_m, Lmem, memv, eps_w, xkappa;
4385 for (k=0; k<nz; k++) {
4386 for (j=0; j<ny; j++) {
4387 thee->
gxcf[IJKx(j,k,0)] = 0.0;
4388 thee->
gxcf[IJKx(j,k,1)] = 0.0;
4389 thee->
gxcf[IJKx(j,k,2)] = 0.0;
4390 thee->
gxcf[IJKx(j,k,3)] = 0.0;
4395 for (k=0; k<nz; k++) {
4396 for (i=0; i<nx; i++) {
4397 thee->
gycf[IJKy(i,k,0)] = 0.0;
4398 thee->
gycf[IJKy(i,k,1)] = 0.0;
4399 thee->
gycf[IJKy(i,k,2)] = 0.0;
4400 thee->
gycf[IJKy(i,k,3)] = 0.0;
4405 for (j=0; j<ny; j++) {
4406 for (i=0; i<nx; i++) {
4407 thee->
gzcf[IJKz(i,j,0)] = 0.0;
4408 thee->
gzcf[IJKz(i,j,1)] = 0.0;
4409 thee->
gzcf[IJKz(i,j,2)] = 0.0;
4410 thee->
gzcf[IJKz(i,j,3)] = 0.0;
4422 #if defined(WITH_TINKER) 4423 bcfl_mdh_tinker(thee);
4426 #ifdef DEBUG_MAC_OSX_OCL 4427 #include "mach_chud.h" 4428 uint64_t mbeg = mach_absolute_time();
4434 if (kOpenCLAvailable == 1) bcflnewOpenCL(thee);
4437 mets_(&mbeg,
"MDH");
4455 bcfl_mem(zmem, Lmem, eps_m, eps_w, memv, xkappa,
4457 thee->
xf, thee->
yf, thee->
zf, nx, ny, nz);
4460 Vnm_print(2,
"bcCalc: Invalid bcfl (%d)!\n", thee->
pmgp->
bcfl);
4464 Vnm_print(2,
"VPMG::bcCalc -- not appropriate for focusing!\n");
4469 focusFillBound(thee,VNULL);
4472 Vnm_print(2,
"VPMG::bcCalc -- invalid boundary condition \ 4482 double ionstr, position[3], tkappa, eps, pot, hx, hy, hzed;
4483 int i, j, k, nx, ny, nz;
4485 VASSERT(thee != VNULL);
4502 Vnm_print(2,
"fillcoCoefMap: You need to use all coefficient maps!\n");
4511 for (k=0; k<nz; k++) {
4512 for (j=0; j<ny; j++) {
4513 for (i=0; i<nx; i++) {
4515 position[0] = thee->
xf[i];
4516 position[1] = thee->
yf[j];
4517 position[2] = thee->
zf[k];
4519 Vnm_print(2,
"Vpmg_fillco: Off kappaMap at:\n");
4520 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4521 position[0], position[1], position[2]);
4524 if (tkappa > kappamax) {
4528 Vnm_print(2,
"Vpmg_fillcoCoefMap: Kappa map less than 0\n");
4529 Vnm_print(2,
"Vpmg_fillcoCoefMap: at (x,y,z) = (%g,%g %g)\n",
4530 position[0], position[1], position[2]);
4538 if (kappamax > 1.0){
4539 Vnm_print(2,
"Vpmg_fillcoCoefMap: Maximum Kappa value\n");
4540 Vnm_print(2,
"%g is greater than 1 - will scale appropriately!\n",
4547 for (k=0; k<nz; k++) {
4548 for (j=0; j<ny; j++) {
4549 for (i=0; i<nx; i++) {
4552 position[0] = thee->
xf[i];
4553 position[1] = thee->
yf[j];
4554 position[2] = thee->
zf[k];
4556 Vnm_print(2,
"Vpmg_fillco: Off kappaMap at:\n");
4557 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4558 position[0], position[1], position[2]);
4562 thee->
kappa[IJK(i,j,k)] = (tkappa / kappamax);
4565 position[0] = thee->
xf[i] + 0.5*hx;
4566 position[1] = thee->
yf[j];
4567 position[2] = thee->
zf[k];
4569 Vnm_print(2,
"Vpmg_fillco: Off dielXMap at:\n");
4570 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4571 position[0], position[1], position[2]);
4574 thee->
epsx[IJK(i,j,k)] = eps;
4576 position[0] = thee->
xf[i];
4577 position[1] = thee->
yf[j] + 0.5*hy;
4578 position[2] = thee->
zf[k];
4580 Vnm_print(2,
"Vpmg_fillco: Off dielYMap at:\n");
4581 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4582 position[0], position[1], position[2]);
4585 thee->
epsy[IJK(i,j,k)] = eps;
4587 position[0] = thee->
xf[i];
4588 position[1] = thee->
yf[j];
4589 position[2] = thee->
zf[k] + 0.5*hzed;
4591 Vnm_print(2,
"Vpmg_fillco: Off dielZMap at:\n");
4592 Vnm_print(2,
"Vpmg_fillco: (x,y,z) = (%g,%g %g)\n",
4593 position[0], position[1], position[2]);
4596 thee->
epsz[IJK(i,j,k)] = eps;
4624 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr;
4625 double xlen, ylen, zlen, irad;
4626 double hx, hy, hzed, *apos, arad;
4627 int i, nx, ny, nz, iatom;
4630 VASSERT(thee != VNULL);
4669 for (i=0; i<(nx*ny*nz); i++) thee->
kappa[i] = ionmask;
4681 if (arad > VSMALL) {
4684 if ((apos[0]<(xmin-irad-arad)) || (apos[0]>(xmax+irad+arad)) || \
4685 (apos[1]<(ymin-irad-arad)) || (apos[1]>(ymax+irad+arad)) || \
4686 (apos[2]<(zmin-irad-arad)) || (apos[2]>(zmax+irad+arad))) {
4690 "Vpmg_fillco: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
4691 iatom, apos[0], apos[1], apos[2]);
4692 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
4694 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
4696 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
4734 double xmin, xmax, ymin, ymax, zmin, zmax;
4735 double xlen, ylen, zlen, position[3];
4736 double srad, epsw, epsp, deps, area;
4737 double hx, hy, hzed, *apos, arad;
4738 int i, nx, ny, nz, ntot, iatom, ipt;
4771 for (i=0; i<ntot; i++) {
4772 thee->
epsx[i] = epsw;
4773 thee->
epsy[i] = epsw;
4774 thee->
epsz[i] = epsw;
4779 #pragma omp parallel for default(shared) private(iatom,atom,apos,arad) 4787 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
4788 (apos[1]<=ymin) || (apos[1]>=ymax) || \
4789 (apos[2]<=zmin) || (apos[2]>=zmax)) {
4792 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\ 4793 %4.3f) is off the mesh (ignoring):\n",
4794 iatom, apos[0], apos[1], apos[2]);
4795 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
4797 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
4799 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
4806 if (arad > VSMALL) {
4811 (xmin+0.5*hx), ymin, zmin,
4818 xmin, (ymin+0.5*hy), zmin,
4825 xmin, ymin, (zmin+0.5*hzed),
4835 if (srad > VSMALL) {
4839 #pragma omp parallel for default(shared) private(iatom,atom,area,asurf,ipt,position) 4848 for (ipt=0; ipt<(asurf->
npts); ipt++) {
4850 position[0] = asurf->
xpts[ipt];
4851 position[1] = asurf->
ypts[ipt];
4852 position[2] = asurf->
zpts[ipt];
4858 (xmin+0.5*hx), ymin, zmin,
4865 xmin, (ymin+0.5*hy), zmin,
4872 xmin, ymin, (zmin+0.5*hzed),
4893 int i, j, k, nx, ny, nz, numpts;
4904 for (i=0; i<(nx*ny*nz); i++) {
4908 thee->
epsx[i] = epsw;
4909 thee->
epsy[i] = epsw;
4910 thee->
epsz[i] = epsw;
4914 for (i=0; i<nx; i++) {
4915 for (j=0; j<ny; j++) {
4916 for (k=0; k<nz; k++) {
4921 frac = 1.0/thee->
a1cf[IJK(i,j,k)];
4922 frac += 1.0/thee->
a2cf[IJK(i,j,k)];
4923 frac += 1.0/thee->
a3cf[IJK(i,j,k)];
4927 frac += 1.0/thee->
a2cf[IJK(i,j-1,k)];
4931 frac += 1.0/thee->
a3cf[IJK(i,j,k-1)];
4935 frac += 1.0/thee->
a2cf[IJK(i+1,j,k)];
4936 frac += 1.0/thee->
a3cf[IJK(i+1,j,k)];
4939 frac += 1.0/thee->
a2cf[IJK(i+1,j-1,k)];
4943 frac += 1.0/thee->
a3cf[IJK(i+1,j,k-1)];
4947 thee->
epsx[IJK(i,j,k)] = numpts/frac;
4950 frac = 1.0/thee->
a2cf[IJK(i,j,k)];
4951 frac += 1.0/thee->
a1cf[IJK(i,j,k)];
4952 frac += 1.0/thee->
a3cf[IJK(i,j,k)];
4956 frac += 1.0/thee->
a1cf[IJK(i-1,j,k)];
4960 frac += 1.0/thee->
a3cf[IJK(i,j,k-1)];
4964 frac += 1.0/thee->
a1cf[IJK(i,j+1,k)];
4965 frac += 1.0/thee->
a3cf[IJK(i,j+1,k)];
4968 frac += 1.0/thee->
a1cf[IJK(i-1,j+1,k)];
4972 frac += 1.0/thee->
a3cf[IJK(i,j+1,k-1)];
4976 thee->
epsy[IJK(i,j,k)] = numpts/frac;
4979 frac = 1.0/thee->
a3cf[IJK(i,j,k)];
4980 frac += 1.0/thee->
a1cf[IJK(i,j,k)];
4981 frac += 1.0/thee->
a2cf[IJK(i,j,k)];
4985 frac += 1.0/thee->
a1cf[IJK(i-1,j,k)];
4989 frac += 1.0/thee->
a2cf[IJK(i,j-1,k)];
4993 frac += 1.0/thee->
a1cf[IJK(i,j,k+1)];
4994 frac += 1.0/thee->
a2cf[IJK(i,j,k+1)];
4997 frac += 1.0/thee->
a1cf[IJK(i-1,j,k+1)];
5001 frac += 1.0/thee->
a2cf[IJK(i,j-1,k+1)];
5005 thee->
epsz[IJK(i,j,k)] = numpts/frac;
5017 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr, dist2;
5018 double xlen, ylen, zlen, position[3], itot, stot, ictot, ictot2, sctot;
5019 double irad, dx, dy, dz, epsw, epsp, w2i;
5020 double hx, hy, hzed, *apos, arad, sctot2;
5021 double dx2, dy2, dz2, stot2, itot2, rtot, rtot2, splineWin, w3i;
5022 double dist, value, sm, sm2;
5023 int i, j, k, nx, ny, nz, iatom;
5024 int imin, imax, jmin, jmax, kmin, kmax;
5026 VASSERT(thee != VNULL);
5028 w2i = 1.0/(splineWin*splineWin);
5029 w3i = 1.0/(splineWin*splineWin*splineWin);
5068 for (i=0; i<(nx*ny*nz); i++) {
5069 thee->
kappa[i] = 1.0;
5070 thee->
epsx[i] = 1.0;
5071 thee->
epsy[i] = 1.0;
5072 thee->
epsz[i] = 1.0;
5083 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
5084 (apos[1]<=ymin) || (apos[1]>=ymax) || \
5085 (apos[2]<=zmin) || (apos[2]>=zmax)) {
5088 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\ 5089 %4.3f) is off the mesh (ignoring):\n",
5090 iatom, apos[0], apos[1], apos[2]);
5091 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
5093 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
5095 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
5103 position[0] = apos[0] - xmin;
5104 position[1] = apos[1] - ymin;
5105 position[2] = apos[2] - zmin;
5109 itot = irad + arad + splineWin;
5111 ictot = VMAX2(0, (irad + arad - splineWin));
5112 ictot2 = VSQR(ictot);
5113 stot = arad + splineWin;
5115 sctot = VMAX2(0, (arad - splineWin));
5116 sctot2 = VSQR(sctot);
5120 rtot = VMAX2(itot, stot);
5121 rtot2 = VMAX2(itot2, stot2);
5124 dz = rtot + 0.5*hzed;
5125 imin = VMAX2(0,(
int)floor((position[0] - dx)/hx));
5126 imax = VMIN2(nx-1,(
int)ceil((position[0] + dx)/hx));
5127 jmin = VMAX2(0,(
int)floor((position[1] - dy)/hy));
5128 jmax = VMIN2(ny-1,(
int)ceil((position[1] + dy)/hy));
5129 kmin = VMAX2(0,(
int)floor((position[2] - dz)/hzed));
5130 kmax = VMIN2(nz-1,(
int)ceil((position[2] + dz)/hzed));
5131 for (i=imin; i<=imax; i++) {
5132 dx2 = VSQR(position[0] - hx*i);
5133 for (j=jmin; j<=jmax; j++) {
5134 dy2 = VSQR(position[1] - hy*j);
5135 for (k=kmin; k<=kmax; k++) {
5136 dz2 = VSQR(position[2] - k*hzed);
5140 dist2 = dz2 + dy2 + dx2;
5141 if (dist2 >= itot2) {
5144 if (dist2 <= ictot2) {
5145 thee->
kappa[IJK(i,j,k)] = 0.0;
5147 if ((dist2 < itot2) && (dist2 > ictot2)) {
5148 dist = VSQRT(dist2);
5149 sm = dist - (arad + irad) + splineWin;
5151 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5152 thee->
kappa[IJK(i,j,k)] *= value;
5158 dist2 = dz2+dy2+VSQR(position[0]-(i+0.5)*hx);
5159 if (dist2 >= stot2) {
5160 thee->
epsx[IJK(i,j,k)] *= 1.0;
5162 if (dist2 <= sctot2) {
5163 thee->
epsx[IJK(i,j,k)] = 0.0;
5165 if ((dist2 > sctot2) && (dist2 < stot2)) {
5166 dist = VSQRT(dist2);
5167 sm = dist - arad + splineWin;
5169 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5170 thee->
epsx[IJK(i,j,k)] *= value;
5176 dist2 = dz2+dx2+VSQR(position[1]-(j+0.5)*hy);
5177 if (dist2 >= stot2) {
5178 thee->
epsy[IJK(i,j,k)] *= 1.0;
5180 if (dist2 <= sctot2) {
5181 thee->
epsy[IJK(i,j,k)] = 0.0;
5183 if ((dist2 > sctot2) && (dist2 < stot2)) {
5184 dist = VSQRT(dist2);
5185 sm = dist - arad + splineWin;
5187 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5188 thee->
epsy[IJK(i,j,k)] *= value;
5194 dist2 = dy2+dx2+VSQR(position[2]-(k+0.5)*hzed);
5195 if (dist2 >= stot2) {
5196 thee->
epsz[IJK(i,j,k)] *= 1.0;
5198 if (dist2 <= sctot2) {
5199 thee->
epsz[IJK(i,j,k)] = 0.0;
5201 if ((dist2 > sctot2) && (dist2 < stot2)) {
5202 dist = VSQRT(dist2);
5203 sm = dist - arad + splineWin;
5205 value = 0.75*sm2*w2i - 0.25*sm*sm2*w3i;
5206 thee->
epsz[IJK(i,j,k)] *= value;
5217 Vnm_print(0,
"Vpmg_fillco: filling coefficient arrays\n");
5219 for (k=0; k<nz; k++) {
5220 for (j=0; j<ny; j++) {
5221 for (i=0; i<nx; i++) {
5223 thee->
kappa[IJK(i,j,k)] = ionmask*thee->
kappa[IJK(i,j,k)];
5224 thee->
epsx[IJK(i,j,k)] = (epsw-epsp)*thee->
epsx[IJK(i,j,k)]
5226 thee->
epsy[IJK(i,j,k)] = (epsw-epsp)*thee->
epsy[IJK(i,j,k)]
5228 thee->
epsz[IJK(i,j,k)] = (epsw-epsp)*thee->
epsz[IJK(i,j,k)]
5239 VASSERT(thee != VNULL);
5249 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefMol...\n");
5253 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefMol...\n");
5257 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefSpline...\n");
5261 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefSpline3...\n");
5265 Vnm_print(0,
"fillcoCoef: Calling fillcoCoefSpline4...\n");
5269 Vnm_print(2,
"fillcoCoef: Invalid surfMeth (%d)!\n",
5281 VASSERT(thee != VNULL);
5289 Vnm_print(0,
"fillcoCharge: Calling fillcoChargeSpline1...\n");
5293 Vnm_print(0,
"fillcoCharge: Calling fillcoChargeSpline2...\n");
5299 Vnm_print(0,
"fillcoCharge: Calling fillcoPermanentMultipole...\n");
5302 #if defined(WITH_TINKER) 5304 Vnm_print(0,
"fillcoCharge: Calling fillcoPermanentMultipole...\n");
5308 Vnm_print(0,
"fillcoCharge: Calling fillcoInducedDipole...\n");
5312 Vnm_print(0,
"fillcoCharge: Calling fillcoNLInducedDipole...\n");
5317 Vnm_print(2,
"fillcoCharge: Invalid chargeSource (%d)!\n",
5324 Vnm_print(2,
"fillcoCharge: Invalid chargeMeth (%d)!\n",
5336 double position[3], charge, zmagic, hx, hy, hzed;
5337 int i, j, k, nx, ny, nz, rc;
5340 VASSERT(thee != VNULL);
5355 for (i=0; i<(nx*ny*nz); i++) thee->
charge[i] = 0.0;
5358 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5359 for (k=0; k<nz; k++) {
5360 for (j=0; j<ny; j++) {
5361 for (i=0; i<nx; i++) {
5362 position[0] = thee->
xf[i];
5363 position[1] = thee->
yf[j];
5364 position[2] = thee->
zf[k];
5367 Vnm_print(2,
"fillcoChargeMap: Error -- fell off of charge map at (%g, %g, %g)!\n",
5368 position[0], position[1], position[2]);
5372 charge = charge*zmagic;
5373 thee->
charge[IJK(i,j,k)] = charge;
5386 double xmin, xmax, ymin, ymax, zmin, zmax;
5387 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
5388 double charge, dx, dy, dz, zmagic, hx, hy, hzed, *apos;
5389 int i, nx, ny, nz, iatom, ihi, ilo, jhi, jlo, khi, klo;
5392 VASSERT(thee != VNULL);
5421 for (i=0; i<(nx*ny*nz); i++) thee->
charge[i] = 0.0;
5424 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5432 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
5433 (apos[1]<=ymin) || (apos[1]>=ymax) || \
5434 (apos[2]<=zmin) || (apos[2]>=zmax)) {
5437 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f, \ 5438 %4.3f) is off the mesh (ignoring):\n",
5439 iatom, apos[0], apos[1], apos[2]);
5440 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
5442 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
5444 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
5451 position[0] = apos[0] - xmin;
5452 position[1] = apos[1] - ymin;
5453 position[2] = apos[2] - zmin;
5456 charge = charge*zmagic/(hx*hy*hzed);
5459 ifloat = position[0]/hx;
5460 jfloat = position[1]/hy;
5461 kfloat = position[2]/hzed;
5463 ihi = (int)ceil(ifloat);
5464 ilo = (int)floor(ifloat);
5465 jhi = (int)ceil(jfloat);
5466 jlo = (int)floor(jfloat);
5467 khi = (int)ceil(kfloat);
5468 klo = (int)floor(kfloat);
5471 dx = ifloat - (double)(ilo);
5472 dy = jfloat - (double)(jlo);
5473 dz = kfloat - (double)(klo);
5474 thee->
charge[IJK(ihi,jhi,khi)] += (dx*dy*dz*charge);
5475 thee->
charge[IJK(ihi,jlo,khi)] += (dx*(1.0-dy)*dz*charge);
5476 thee->
charge[IJK(ihi,jhi,klo)] += (dx*dy*(1.0-dz)*charge);
5477 thee->
charge[IJK(ihi,jlo,klo)] += (dx*(1.0-dy)*(1.0-dz)*charge);
5478 thee->
charge[IJK(ilo,jhi,khi)] += ((1.0-dx)*dy*dz *charge);
5479 thee->
charge[IJK(ilo,jlo,khi)] += ((1.0-dx)*(1.0-dy)*dz *charge);
5480 thee->
charge[IJK(ilo,jhi,klo)] += ((1.0-dx)*dy*(1.0-dz)*charge);
5481 thee->
charge[IJK(ilo,jlo,klo)] += ((1.0-dx)*(1.0-dy)*(1.0-dz)*charge);
5490 if ((x >= 0.0) && (x <= 2.0)) m2m = 1.0 - VABS(x - 1.0);
5492 if ((x >= 1.0) && (x <= 3.0)) m2 = 1.0 - VABS(x - 2.0);
5495 if ((x >= 0.0) && (x <= 3.0)) m3 = 0.5*x*m2m + 0.5*(3.0-x)*m2;
5504 double m2m, m2, dm3;
5506 if ((x >= 0.0) && (x <= 2.0)) m2m = 1.0 - VABS(x - 1.0);
5508 if ((x >= 1.0) && (x <= 3.0)) m2 = 1.0 - VABS(x - 2.0);
5523 double xmin, xmax, ymin, ymax, zmin, zmax, zmagic;
5524 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
5525 double charge, hx, hy, hzed, *apos, mx, my, mz;
5526 int i, ii, jj, kk, nx, ny, nz, iatom;
5527 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
5530 VASSERT(thee != VNULL);
5559 for (i=0; i<(nx*ny*nz); i++) thee->
charge[i] = 0.0;
5562 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5570 if ((apos[0]<=(xmin-hx)) || (apos[0]>=(xmax+hx)) || \
5571 (apos[1]<=(ymin-hy)) || (apos[1]>=(ymax+hy)) || \
5572 (apos[2]<=(zmin-hzed)) || (apos[2]>=(zmax+hzed))) {
5575 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f, \ 5576 %4.3f) is off the mesh (for cubic splines!!) (ignoring this atom):\n",
5577 iatom, apos[0], apos[1], apos[2]);
5578 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
5580 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
5582 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
5589 position[0] = apos[0] - xmin;
5590 position[1] = apos[1] - ymin;
5591 position[2] = apos[2] - zmin;
5594 charge = charge*zmagic/(hx*hy*hzed);
5597 ifloat = position[0]/hx;
5598 jfloat = position[1]/hy;
5599 kfloat = position[2]/hzed;
5601 ip1 = (int)ceil(ifloat);
5603 im1 = (int)floor(ifloat);
5605 jp1 = (int)ceil(jfloat);
5607 jm1 = (int)floor(jfloat);
5609 kp1 = (int)ceil(kfloat);
5611 km1 = (int)floor(kfloat);
5616 ip2 = VMIN2(ip2,nx-1);
5617 ip1 = VMIN2(ip1,nx-1);
5620 jp2 = VMIN2(jp2,ny-1);
5621 jp1 = VMIN2(jp1,ny-1);
5624 kp2 = VMIN2(kp2,nz-1);
5625 kp1 = VMIN2(kp1,nz-1);
5630 for (ii=im2; ii<=ip2; ii++) {
5632 for (jj=jm2; jj<=jp2; jj++) {
5634 for (kk=km2; kk<=kp2; kk++) {
5636 thee->
charge[IJK(ii,jj,kk)] += (charge*mx*my*mz);
5686 if (thee == VNULL) {
5687 Vnm_print(2,
"Vpmg_fillco: got NULL thee!\n");
5739 thee->
rparm[2] = xmin;
5740 thee->
rparm[3] = xmax;
5741 thee->
rparm[4] = ymin;
5742 thee->
rparm[5] = ymax;
5743 thee->
rparm[6] = zmin;
5744 thee->
rparm[7] = zmax;
5759 for (i=0; i<nx; i++) thee->
xf[i] = xmin + i*hx;
5760 for (i=0; i<ny; i++) thee->
yf[i] = ymin + i*hy;
5761 for (i=0; i<nz; i++) thee->
zf[i] = zmin + i*hzed;
5764 for (i=0; i<(nx*ny*nz); i++) thee->
tcf[i] = 0.0;
5767 Vnm_print(0,
"Vpmg_fillco: filling in source term.\n");
5773 Vnm_print(2,
"Vpmg_fillco: non-fatal errors while filling charge map!\n");
5776 Vnm_print(2,
"Vpmg_fillco: fatal errors while filling charge map!\n");
5784 Vnm_print(0,
"Vpmg_fillco: marking ion and solvent accessibility.\n");
5786 Vnm_print(0,
"Vpmg_fillco: done filling coefficient arrays\n");
5790 for (i=0; i<(nx*ny*nz); i++) {
5791 thee->
kappa[i] = 0.0;
5792 thee->
epsx[i] = epsp;
5793 thee->
epsy[i] = epsp;
5794 thee->
epsz[i] = epsp;
5801 Vnm_print(0,
"Vpmg_fillco: filling boundary arrays\n");
5803 Vnm_print(0,
"Vpmg_fillco: done filling boundary arrays\n");
5821 VASSERT(thee != VNULL);
5827 force[0] = qfF[0] + dbF[0] + ibF[0];
5828 force[1] = qfF[1] + dbF[1] + ibF[1];
5829 force[2] = qfF[2] + dbF[2] + ibF[2];
5843 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
5844 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
5845 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
5847 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
5850 int ichop, nchop, nion, m;
5853 VASSERT(thee != VNULL);
5867 Vnm_print(2,
"Vpmg_ibForce: Forces *must* be calculated with \ 5868 spline-based surfaces!\n");
5869 Vnm_print(2,
"Vpmg_ibForce: Skipping ionic boundary force \ 5875 if (atom->
partID == 0)
return 1;
5908 Vnm_print(2,
"Vpmg_ibForce: No force for zero ionic strength!\n");
5914 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
5915 (apos[1]<=ymin) || (apos[1]>=ymax) || \
5916 (apos[2]<=zmin) || (apos[2]>=zmax)) {
5919 Vnm_print(2,
"Vpmg_ibForce: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
5920 atom, apos[0], apos[1], apos[2]);
5921 Vnm_print(2,
"Vpmg_ibForce: xmin = %g, xmax = %g\n",
5923 Vnm_print(2,
"Vpmg_ibForce: ymin = %g, ymax = %g\n",
5925 Vnm_print(2,
"Vpmg_ibForce: zmin = %g, zmax = %g\n",
5932 position[0] = apos[0] - xmin;
5933 position[1] = apos[1] - ymin;
5934 position[2] = apos[2] - zmin;
5940 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
5941 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
5942 for (i=imin; i<=imax; i++) {
5943 dx2 = VSQR(position[0] - hx*i);
5944 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
5946 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
5947 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
5948 for (j=jmin; j<=jmax; j++) {
5949 dy2 = VSQR(position[1] - hy*j);
5950 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
5952 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
5953 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
5954 for (k=kmin; k<=kmax; k++) {
5955 dz2 = VSQR(k*hzed - position[2]);
5958 if ((dz2 + dy2 + dx2) <= rtot2) {
5959 gpos[0] = i*hx + xmin;
5960 gpos[1] = j*hy + ymin;
5961 gpos[2] = k*hzed + zmin;
5971 for (m=0; m<nion; m++) {
5972 fmag += (thee->
kappa[IJK(i,j,k)])*ionConc[m]*(
Vcap_exp(-ionQ[m]*thee->
u[IJK(i,j,k)], &ichop)-1.0)/ionstr;
5976 force[0] += (zkappa2*fmag*tgrad[0]);
5977 force[1] += (zkappa2*fmag*tgrad[1]);
5978 force[2] += (zkappa2*fmag*tgrad[2]);
5983 fmag = VSQR(thee->
u[IJK(i,j,k)])*(thee->
kappa[IJK(i,j,k)]);
5984 force[0] += (zkappa2*fmag*tgrad[0]);
5985 force[1] += (zkappa2*fmag*tgrad[1]);
5986 force[2] += (zkappa2*fmag*tgrad[2]);
5993 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
5994 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
5995 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
6007 double *apos, position[3], arad, srad, hx, hy, hzed, izmagic, deps, depsi;
6008 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
6009 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
6010 double *u, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
6011 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
6013 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
6015 VASSERT(thee != VNULL);
6017 Vnm_print(2,
"Vpmg_dbForce: Need to callVpmg_fillco!\n");
6034 Vnm_print(2,
"Vpmg_dbForce: Forces *must* be calculated with \ 6035 spline-based surfaces!\n");
6036 Vnm_print(2,
"Vpmg_dbForce: Skipping dielectric/apolar boundary \ 6037 force calculation!\n");
6043 if (atom->
partID == 0)
return 1;
6073 Vnm_print(0,
"Vpmg_dbForce: No force for uniform dielectric!\n");
6076 deps = (epsw - epsp);
6082 if ((apos[0]<=xmin + rtot) || (apos[0]>=xmax - rtot) || \
6083 (apos[1]<=ymin + rtot) || (apos[1]>=ymax - rtot) || \
6084 (apos[2]<=zmin + rtot) || (apos[2]>=zmax - rtot)) {
6087 Vnm_print(2,
"Vpmg_dbForce: Atom #%d at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
6088 atomID, apos[0], apos[1], apos[2]);
6089 Vnm_print(2,
"Vpmg_dbForce: xmin = %g, xmax = %g\n",
6091 Vnm_print(2,
"Vpmg_dbForce: ymin = %g, ymax = %g\n",
6093 Vnm_print(2,
"Vpmg_dbForce: zmin = %g, zmax = %g\n",
6100 position[0] = apos[0] - xmin;
6101 position[1] = apos[1] - ymin;
6102 position[2] = apos[2] - zmin;
6107 imin = (int)floor((position[0]-rtot)/hx);
6109 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6112 imax = (int)ceil((position[0]+rtot)/hx);
6113 if (imax > (nx-2)) {
6114 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6117 jmin = (int)floor((position[1]-rtot)/hy);
6119 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6122 jmax = (int)ceil((position[1]+rtot)/hy);
6123 if (jmax > (ny-2)) {
6124 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6127 kmin = (int)floor((position[2]-rtot)/hzed);
6129 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6132 kmax = (int)ceil((position[2]+rtot)/hzed);
6133 if (kmax > (nz-2)) {
6134 Vnm_print(2,
"Vpmg_dbForce: Atom %d off grid!\n", atomID);
6137 for (i=imin; i<=imax; i++) {
6138 for (j=jmin; j<=jmax; j++) {
6139 for (k=kmin; k<=kmax; k++) {
6141 gpos[0] = (i+0.5)*hx + xmin;
6142 gpos[1] = j*hy + ymin;
6143 gpos[2] = k*hzed + zmin;
6144 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
6164 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
6165 gpos[0] = i*hx + xmin;
6166 gpos[1] = (j+0.5)*hy + ymin;
6167 gpos[2] = k*hzed + zmin;
6168 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
6174 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
6175 gpos[0] = i*hx + xmin;
6176 gpos[1] = j*hy + ymin;
6177 gpos[2] = (k+0.5)*hzed + zmin;
6178 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
6184 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
6186 gpos[0] = (i-0.5)*hx + xmin;
6187 gpos[1] = j*hy + ymin;
6188 gpos[2] = k*hzed + zmin;
6189 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
6195 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
6197 gpos[0] = i*hx + xmin;
6198 gpos[1] = (j-0.5)*hy + ymin;
6199 gpos[2] = k*hzed + zmin;
6200 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
6206 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
6208 gpos[0] = i*hx + xmin;
6209 gpos[1] = j*hy + ymin;
6210 gpos[2] = (k-0.5)*hzed + zmin;
6211 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
6217 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
6219 dbFmag = u[IJK(i,j,k)];
6221 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
6222 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
6223 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
6224 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
6225 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
6226 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
6228 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
6229 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
6230 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
6231 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
6232 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
6233 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
6235 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
6236 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
6237 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
6238 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
6239 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
6240 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
6241 dbForce[0] += (dbFmag*tgrad[0]);
6242 dbForce[1] += (dbFmag*tgrad[1]);
6243 dbForce[2] += (dbFmag*tgrad[2]);
6249 dbForce[0] = -dbForce[0]*hx*hy*hzed*deps*0.5*izmagic;
6250 dbForce[1] = -dbForce[1]*hx*hy*hzed*deps*0.5*izmagic;
6251 dbForce[2] = -dbForce[2]*hx*hy*hzed*deps*0.5*izmagic;
6269 Vnm_print(2,
"Vpmg_qfForce: It is recommended that forces be \ 6270 calculated with the\n");
6271 Vnm_print(2,
"Vpmg_qfForce: cubic spline charge discretization \ 6286 Vnm_print(2,
"Vpmg_qfForce: Undefined charge discretization \ 6287 method (%d)!\n", chgm);
6288 Vnm_print(2,
"Vpmg_qfForce: Forces not calculated!\n");
6293 force[0] = tforce[0];
6294 force[1] = tforce[1];
6295 force[2] = tforce[2];
6305 double *apos, position[3], hx, hy, hzed;
6306 double xmin, ymin, zmin, xmax, ymax, zmax;
6308 double *u, charge, ifloat, jfloat, kfloat;
6309 int nx, ny, nz, ihi, ilo, jhi, jlo, khi, klo;
6311 VASSERT(thee != VNULL);
6323 if (atom->
partID == 0)
return;
6341 if ((apos[0]<=xmin) || (apos[0]>=xmax) || (apos[1]<=ymin) || \
6342 (apos[1]>=ymax) || (apos[2]<=zmin) || (apos[2]>=zmax)) {
6345 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]);
6346 Vnm_print(2,
"Vpmg_qfForce: xmin = %g, xmax = %g\n", xmin, xmax);
6347 Vnm_print(2,
"Vpmg_qfForce: ymin = %g, ymax = %g\n", ymin, ymax);
6348 Vnm_print(2,
"Vpmg_qfForce: zmin = %g, zmax = %g\n", zmin, zmax);
6354 position[0] = apos[0] - xmin;
6355 position[1] = apos[1] - ymin;
6356 position[2] = apos[2] - zmin;
6357 ifloat = position[0]/hx;
6358 jfloat = position[1]/hy;
6359 kfloat = position[2]/hzed;
6360 ihi = (int)ceil(ifloat);
6361 ilo = (int)floor(ifloat);
6362 jhi = (int)ceil(jfloat);
6363 jlo = (int)floor(jfloat);
6364 khi = (int)ceil(kfloat);
6365 klo = (int)floor(kfloat);
6366 VASSERT((ihi < nx) && (ihi >=0));
6367 VASSERT((ilo < nx) && (ilo >=0));
6368 VASSERT((jhi < ny) && (jhi >=0));
6369 VASSERT((jlo < ny) && (jlo >=0));
6370 VASSERT((khi < nz) && (khi >=0));
6371 VASSERT((klo < nz) && (klo >=0));
6372 dx = ifloat - (double)(ilo);
6373 dy = jfloat - (double)(jlo);
6374 dz = kfloat - (double)(klo);
6378 Vnm_print(1,
"Vpmg_qfForce: (DEBUG) u ~ %g\n",
6379 dx *dy *dz *u[IJK(ihi,jhi,khi)]
6380 +dx *dy *(1-dz)*u[IJK(ihi,jhi,klo)]
6381 +dx *(1-dy)*dz *u[IJK(ihi,jlo,khi)]
6382 +dx *(1-dy)*(1-dz)*u[IJK(ihi,jlo,klo)]
6383 +(1-dx)*dy *dz *u[IJK(ilo,jhi,khi)]
6384 +(1-dx)*dy *(1-dz)*u[IJK(ilo,jhi,klo)]
6385 +(1-dx)*(1-dy)*dz *u[IJK(ilo,jlo,khi)]
6386 +(1-dx)*(1-dy)*(1-dz)*u[IJK(ilo,jlo,klo)]);
6392 -charge*(dy *dz *u[IJK(ihi,jhi,khi)]
6393 + dy *(1-dz)*u[IJK(ihi,jhi,klo)]
6394 + (1-dy)*dz *u[IJK(ihi,jlo,khi)]
6395 + (1-dy)*(1-dz)*u[IJK(ihi,jlo,klo)]
6396 - dy *dz *u[IJK(ilo,jhi,khi)]
6397 - dy *(1-dz)*u[IJK(ilo,jhi,klo)]
6398 - (1-dy)*dz *u[IJK(ilo,jlo,khi)]
6399 - (1-dy)*(1-dz)*u[IJK(ilo,jlo,klo)])/hx;
6403 "Vpmg_qfForce: Atom %d on x gridline; zero x-force\n", atomID);
6407 -charge*(dx *dz *u[IJK(ihi,jhi,khi)]
6408 + dx *(1-dz)*u[IJK(ihi,jhi,klo)]
6409 - dx *dz *u[IJK(ihi,jlo,khi)]
6410 - dx *(1-dz)*u[IJK(ihi,jlo,klo)]
6411 + (1-dx)*dz *u[IJK(ilo,jhi,khi)]
6412 + (1-dx)*(1-dz)*u[IJK(ilo,jhi,klo)]
6413 - (1-dx)*dz *u[IJK(ilo,jlo,khi)]
6414 - (1-dx)*(1-dz)*u[IJK(ilo,jlo,klo)])/hy;
6418 "Vpmg_qfForce: Atom %d on y gridline; zero y-force\n", atomID);
6422 -charge*(dy *dx *u[IJK(ihi,jhi,khi)]
6423 - dy *dx *u[IJK(ihi,jhi,klo)]
6424 + (1-dy)*dx *u[IJK(ihi,jlo,khi)]
6425 - (1-dy)*dx *u[IJK(ihi,jlo,klo)]
6426 + dy *(1-dx)*u[IJK(ilo,jhi,khi)]
6427 - dy *(1-dx)*u[IJK(ilo,jhi,klo)]
6428 + (1-dy)*(1-dx)*u[IJK(ilo,jlo,khi)]
6429 - (1-dy)*(1-dx)*u[IJK(ilo,jlo,klo)])/hzed;
6433 "Vpmg_qfForce: Atom %d on z gridline; zero z-force\n", atomID);
6442 double *apos, position[3], hx, hy, hzed;
6443 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
6444 double mx, my, mz, dmx, dmy, dmz;
6445 double *u, charge, ifloat, jfloat, kfloat;
6446 int nx, ny, nz, im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1;
6447 int kp1, kp2, ii, jj, kk;
6449 VASSERT(thee != VNULL);
6461 if (atom->
partID == 0)
return;
6482 if ((apos[0]<=(xmin+hx)) || (apos[0]>=(xmax-hx)) \
6483 || (apos[1]<=(ymin+hy)) || (apos[1]>=(ymax-hy)) \
6484 || (apos[2]<=(zmin+hzed)) || (apos[2]>=(zmax-hzed))) {
6487 Vnm_print(2,
"qfForceSpline2: Atom #%d off the mesh \ 6488 (ignoring)\n", atomID);
6495 position[0] = apos[0] - xmin;
6496 position[1] = apos[1] - ymin;
6497 position[2] = apos[2] - zmin;
6498 ifloat = position[0]/hx;
6499 jfloat = position[1]/hy;
6500 kfloat = position[2]/hzed;
6501 ip1 = (int)ceil(ifloat);
6503 im1 = (int)floor(ifloat);
6505 jp1 = (int)ceil(jfloat);
6507 jm1 = (int)floor(jfloat);
6509 kp1 = (int)ceil(kfloat);
6511 km1 = (int)floor(kfloat);
6516 ip2 = VMIN2(ip2,nx-1);
6517 ip1 = VMIN2(ip1,nx-1);
6520 jp2 = VMIN2(jp2,ny-1);
6521 jp1 = VMIN2(jp1,ny-1);
6524 kp2 = VMIN2(kp2,nz-1);
6525 kp1 = VMIN2(kp1,nz-1);
6530 for (ii=im2; ii<=ip2; ii++) {
6533 for (jj=jm2; jj<=jp2; jj++) {
6536 for (kk=km2; kk<=kp2; kk++) {
6540 force[0] += (charge*dmx*my*mz*u[IJK(ii,jj,kk)])/hx;
6541 force[1] += (charge*mx*dmy*mz*u[IJK(ii,jj,kk)])/hy;
6542 force[2] += (charge*mx*my*dmz*u[IJK(ii,jj,kk)])/hzed;
6554 double f, c, *u, *apos, position[3];
6558 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
6559 double hx, hy, hzed, ifloat, jfloat, kfloat;
6562 double mx, my, mz, dmx, dmy, dmz;
6566 int i, j, k, ii, jj, kk;
6567 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
6572 VASSERT(thee != VNULL);
6602 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
6603 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
6604 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
6605 Vnm_print(2,
"qfForceSpline4: Atom off the mesh \ 6606 (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
6611 position[0] = apos[0] - xmin;
6612 position[1] = apos[1] - ymin;
6613 position[2] = apos[2] - zmin;
6614 ifloat = position[0]/hx;
6615 jfloat = position[1]/hy;
6616 kfloat = position[2]/hzed;
6617 ip1 = (int)ceil(ifloat);
6619 im1 = (int)floor(ifloat);
6621 jp1 = (int)ceil(jfloat);
6623 jm1 = (int)floor(jfloat);
6625 kp1 = (int)ceil(kfloat);
6627 km1 = (int)floor(kfloat);
6632 ip2 = VMIN2(ip2,nx-1);
6633 ip1 = VMIN2(ip1,nx-1);
6636 jp2 = VMIN2(jp2,ny-1);
6637 jp1 = VMIN2(jp1,ny-1);
6640 kp2 = VMIN2(kp2,nz-1);
6641 kp1 = VMIN2(kp1,nz-1);
6645 for (ii=im2; ii<=ip2; ii++) {
6649 for (jj=jm2; jj<=jp2; jj++) {
6653 for (kk=km2; kk<=kp2; kk++) {
6657 f = u[IJK(ii,jj,kk)];
6659 e[0] += f*dmx*my*mz/hx;
6660 e[1] += f*mx*dmy*mz/hy;
6661 e[2] += f*mx*my*dmz/hzed;
6674 VPRIVATE
void markFrac(
6675 double rtot,
double *tpos,
6676 int nx,
int ny,
int nz,
6677 double hx,
double hy,
double hzed,
6678 double xmin,
double ymin,
double zmin,
6679 double *xarray,
double *yarray,
double *zarray) {
6681 int i, j, k, imin, imax, jmin, jmax, kmin, kmax;
6682 double dx, dx2, dy, dy2, dz, dz2, a000, a001, a010, a100, r2;
6683 double x, xp, xm, y, yp, ym, zp, z, zm, xspan, yspan, zspan;
6684 double rtot2, pos[3];
6687 pos[0] = tpos[0] - xmin;
6688 pos[1] = tpos[1] - ymin;
6689 pos[2] = tpos[2] - zmin;
6693 xspan = rtot + 2*hx;
6694 imin = VMAX2(0, (
int)ceil((pos[0] - xspan)/hx));
6695 imax = VMIN2(nx-1, (
int)floor((pos[0] + xspan)/hx));
6696 for (i=imin; i<=imax; i++) {
6698 dx2 = VSQR(pos[0] - x);
6700 yspan = VSQRT(rtot2 - dx2) + 2*hy;
6704 jmin = VMAX2(0,(
int)ceil((pos[1] - yspan)/hy));
6705 jmax = VMIN2(ny-1,(
int)floor((pos[1] + yspan)/hy));
6706 for (j=jmin; j<=jmax; j++) {
6708 dy2 = VSQR(pos[1] - y);
6709 if (rtot2 > (dx2+dy2)) {
6710 zspan = VSQRT(rtot2-dx2-dy2) + 2*hzed;
6714 kmin = VMAX2(0,(
int)ceil((pos[2] - zspan)/hzed));
6715 kmax = VMIN2(nz-1,(
int)floor((pos[2] + zspan)/hzed));
6716 for (k=kmin; k<=kmax; k++) {
6718 dz2 = VSQR(pos[2] - z);
6720 r2 = dx2 + dy2 + dz2;
6723 if (r2 < rtot2) a000 = 1.0;
6729 if (r2 < (rtot2 - hx*hx)) a100 = 1.0;
6730 else if (r2 > (rtot2 + hx*hx)) a100 = 0.0;
6731 else if (rtot2 > (dy2 + dz2)) {
6732 dx = VSQRT(rtot2 - dy2 - dz2);
6735 if ((xm < x+hx) && (xm > x)) {
6737 }
else if ((xp < x+hx) && (xp > x)) {
6745 if (r2 < (rtot2 - hy*hy)) a010 = 1.0;
6746 else if (r2 > (rtot2 + hy*hy)) a010 = 0.0;
6747 else if (rtot2 > (dx2 + dz2)) {
6748 dy = VSQRT(rtot2 - dx2 - dz2);
6751 if ((ym < y+hy) && (ym > y)) {
6753 }
else if ((yp < y+hy) && (yp > y)) {
6761 if (r2 < (rtot2 - hzed*hzed)) a001 = 1.0;
6762 else if (r2 > (rtot2 + hzed*hzed)) a001 = 0.0;
6763 else if (rtot2 > (dx2 + dy2)) {
6764 dz = VSQRT(rtot2 - dx2 - dy2);
6767 if ((zm < z+hzed) && (zm > z)) {
6768 a001 = (zm - z)/hzed;
6769 }
else if ((zp < z+hzed) && (zp > z)) {
6770 a001 = (zp - z)/hzed;
6774 if (a100 < xarray[IJK(i,j,k)]) xarray[IJK(i,j,k)] = a100;
6775 if (a010 < yarray[IJK(i,j,k)]) yarray[IJK(i,j,k)] = a010;
6776 if (a001 < zarray[IJK(i,j,k)]) zarray[IJK(i,j,k)] = a001;
6840 int nx,
int ny,
int nz,
6841 double hx,
double hy,
double hz,
6842 double xmin,
double ymin,
double zmin,
6843 double *array,
double markVal) {
6850 double dx2, dy2, dz2;
6851 double xrange, yrange, zrange;
6852 double rtot2, posx, posy, posz;
6855 posx = tpos[0] - xmin;
6856 posy = tpos[1] - ymin;
6857 posz = tpos[2] - zmin;
6861 xrange = rtot + 0.5 * hx;
6862 yrange = rtot + 0.5 * hy;
6863 zrange = rtot + 0.5 * hz;
6865 imin = VMAX2(0, (
int)ceil((posx - xrange)/hx));
6866 jmin = VMAX2(0, (
int)ceil((posy - yrange)/hy));
6867 kmin = VMAX2(0, (
int)ceil((posz - zrange)/hz));
6869 imax = VMIN2(nx-1, (
int)floor((posx + xrange)/hx));
6870 jmax = VMIN2(ny-1, (
int)floor((posy + yrange)/hy));
6871 kmax = VMIN2(nz-1, (
int)floor((posz + zrange)/hz));
6873 for (i=imin,fi=imin; i<=imax; i++, fi+=1.) {
6874 dx2 = VSQR(posx - hx*fi);
6875 for (j=jmin,fj=jmin; j<=jmax; j++, fj+=1.) {
6876 dy2 = VSQR(posy - hy*fj);
6877 if((dx2 + dy2) > rtot2)
continue;
6878 for (k=kmin, fk=kmin; k<=kmax; k++, fk+=1.) {
6879 dz2 = VSQR(posz - hz*fk);
6880 if ((dz2 + dy2 + dx2) <= rtot2) {
6881 array[IJK(i,j,k)] = markVal;
6899 int n, nx, ny, nz, i, j, k, kx, ky, kz;
6900 double hx, hy, hzed, wx, wy, wz, xlen, ylen, zlen;
6901 double phix, phixp1, phixm1, phiy, phiym1, phiyp1, phiz, phizm1, phizp1;
6902 double norm, coef, proj, eigx, eigy, eigz;
6903 double ihx2, ihy2, ihzed2;
6904 double *u, *f, *phi;
6916 ihzed2 = 1.0/hzed/hzed;
6927 for (i=0; i<n; i++) thee->
u[i] = 0.0;
6930 for (kx=1; kx<(nx-1); kx++) {
6932 wx = (VPI*(double)kx)/((double)nx - 1.0);
6933 eigx = 2.0*ihx2*(1.0 - cos(wx));
6935 for (ky=1; ky<(ny-1); ky++) {
6937 wy = (VPI*(double)ky)/((double)ny - 1.0);
6938 eigy = 2.0*ihy2*(1.0 - cos(wy));
6940 for (kz=1; kz<(nz-1); kz++) {
6942 wz = (VPI*(double)kz)/((double)nz - 1.0);
6943 eigz = 2.0*ihzed2*(1.0 - cos(wz));
6954 for (i=1; i<(nx-1); i++) {
6956 phix = sin(wx*(
double)i);
6959 phixp1 = (2.0-hx*hx*eigx)*phix - phixm1;
6964 for (j=1; j<(ny-1); j++) {
6966 phiy = sin(wy*(
double)j);
6969 phiyp1 = (2.0-hy*hy*eigy)*phiy - phiym1;
6974 for (k=1; k<(nz-1); k++) {
6976 phiz = sin(wz*(
double)k);
6979 phizp1 = (2.0-hzed*hzed*eigz)*phiz - phizm1;
6985 phi[IJK(i,j,k)] = phix*phiy*phiz;
6994 for (i=1; i<(nx-1); i++) {
6995 for (j=1; j<(ny-1); j++) {
6996 for (k=1; k<(nz-1); k++) {
6998 proj += f[IJK(i,j,k)]*phi[IJK(i,j,k)];
7009 coef = coef/(eigx + eigy + eigz);
7011 coef = (8.0/xlen/ylen/zlen)*coef;
7016 for (i=1; i<(nx-1); i++) {
7017 for (j=1; j<(ny-1); j++) {
7018 for (k=1; k<(nz-1); k++) {
7020 u[IJK(i,j,k)] += coef*phi[IJK(i,j,k)];
7034 int i, j, k, ijk, nx, ny, nz, n, dilo, dihi, djlo, djhi, dklo, dkhi;
7035 double hx, hy, hzed, epsw, iepsw, scal, scalx, scaly, scalz;
7052 Vnm_print(2,
"Vpmg_solve: Need to call Vpmg_fillco()!\n");
7057 for (i=1; i<(nx-1); i++) {
7059 if (i == 1) dilo = 1;
7061 if (i == nx-2) dihi = 1;
7064 for (j=1; j<(ny-1); j++) {
7066 if (j == 1) djlo = 1;
7068 if (j == ny-2) djhi = 1;
7071 for (k=1; k<(nz-1); k++) {
7073 if (k == 1) dklo = 1;
7075 if (k == nz-2) dkhi = 1;
7079 thee->
fcf[IJK(i,j,k)] = \
7080 iepsw*scal*thee->
charge[IJK(i,j,k)] \
7081 + dilo*scalx*thee->
gxcf[IJKx(j,k,0)] \
7082 + dihi*scalx*thee->
gxcf[IJKx(j,k,1)] \
7083 + djlo*scaly*thee->
gycf[IJKy(i,k,0)] \
7084 + djhi*scaly*thee->
gycf[IJKy(i,k,1)] \
7085 + dklo*scalz*thee->
gzcf[IJKz(i,j,0)] \
7086 + dkhi*scalz*thee->
gzcf[IJKz(i,j,1)] ;
7097 for (j=0; j<ny; j++) {
7098 for (k=0; k<nz; k++) {
7099 thee->
u[IJK(0,j,k)] = thee->
gxcf[IJKx(j,k,0)];
7100 thee->
u[IJK(nx-1,j,k)] = thee->
gycf[IJKx(j,k,1)];
7104 for (i=0; i<nx; i++) {
7105 for (k=0; k<nz; k++) {
7106 thee->
u[IJK(i,0,k)] = thee->
gycf[IJKy(i,k,0)];
7107 thee->
u[IJK(i,ny-1,k)] = thee->
gycf[IJKy(i,k,1)];
7111 for (i=0; i<nx; i++) {
7112 for (j=0; j<ny; j++) {
7113 thee->
u[IJK(i,j,0)] = thee->
gzcf[IJKz(i,j,0)];
7114 thee->
u[IJK(i,j,nz-1)] = thee->
gzcf[IJKz(i,j,1)];
7123 return (2.5+((
double)(i)-(f)));
7129 static double one6 = 1.0/6.0;
7130 static double one8 = 1.0/8.0;
7131 static double one24 = 1.0/24.0;
7132 static double thirteen24 = 13.0/24.0;
7133 static double fourtyseven24 = 47.0/24.0;
7134 static double seventeen24 = 17.0/24.0;
7136 if ((x > 0.0) && (x <= 1.0)){
7139 }
else if ((x > 1.0) && (x <= 2.0)){
7142 return -one8 + one6*x + m2*(0.25 + one6*m - one6*m2);
7143 }
else if ((x > 2.0) && (x <= 3.0)){
7146 return -thirteen24 + 0.5*x + m2*(-0.25 - 0.5*m + 0.25*m2);
7147 }
else if ((x > 3.0) && (x <= 4.0)){
7150 return fourtyseven24 - 0.5*x + m2*(-0.25 + 0.5*m - one6*m2);
7151 }
else if ((x > 4.0) && (x <= 5.0)){
7154 return seventeen24 - one6*x + m2*(0.25 - one6*m + one24*m2);
7163 static double one6 = 1.0/6.0;
7164 static double one3 = 1.0/3.0;
7165 static double two3 = 2.0/3.0;
7166 static double thirteen6 = 13.0/6.0;
7168 if ((x > 0.0) && (x <= 1.0)){
7171 }
else if ((x > 1.0) && (x <= 2.0)){
7174 return -one3 + 0.5*x + m2*(0.5 - two3*m);
7175 }
else if ((x > 2.0) && (x <= 3.0)){
7178 return 1.5 - 0.5*x + m2*(-1.5 + m);
7179 }
else if ((x > 3.0) && (x <= 4.0)){
7182 return 1.0 - 0.5*x + m2*(1.5 - two3*m);
7183 }
else if ((x > 4.0) && (x <= 5.0)){
7186 return -thirteen6 + 0.5*x + m2*(-0.5 + one6*m);
7196 if ((x > 0.0) && (x <= 1.0)){
7198 }
else if ((x > 1.0) && (x <= 2.0)){
7201 return -0.5 + x - 2.0*m2;
7202 }
else if ((x > 2.0) && (x <= 3.0)){
7205 return 5.5 - 3.0*x + 3.0*m2;
7206 }
else if ((x > 3.0) && (x <= 4.0)){
7209 return -9.5 + 3.0*x - 2.0*m2;
7210 }
else if ((x > 4.0) && (x <= 5.0)){
7213 return 4.5 - x + 0.5*m2;
7221 if ((x > 0.0) && (x <= 1.0))
return x;
7222 else if ((x > 1.0) && (x <= 2.0))
return 5.0 - 4.0 * x;
7223 else if ((x > 2.0) && (x <= 3.0))
return -15.0 + 6.0 * x;
7224 else if ((x > 3.0) && (x <= 4.0))
return 15.0 - 4.0 * x;
7225 else if ((x > 4.0) && (x <= 5.0))
return x - 5.0;
7238 double xmin, xmax, ymin, ymax, zmin, zmax;
7239 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
7240 double hx, hy, hzed, *apos;
7242 double charge, *dipole,*quad;
7243 double c,ux,uy,uz,qxx,qyx,qyy,qzx,qzy,qzz,qave;
7245 double mx,my,mz,dmx,dmy,dmz,d2mx,d2my,d2mz;
7248 int i, ii, jj, kk, nx, ny, nz, iatom;
7249 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
7252 double mir,mjr,mkr,mr2;
7253 double debye,mc,mux,muy,muz,mqxx,mqyx,mqyy,mqzx,mqzy,mqzz;
7255 VASSERT(thee != VNULL);
7271 f = zmagic/(hx*hy*hzed);
7287 Vnm_print(0,
"fillcoPermanentMultipole: filling in source term.\n");
7295 #if defined(WITH_TINKER) 7296 dipole = Vatom_getDipole(atom);
7297 ux = dipole[0]/hx*f;
7298 uy = dipole[1]/hy*f;
7299 uz = dipole[2]/hzed*f;
7300 quad = Vatom_getQuadrupole(atom);
7301 qxx = (1.0/3.0)*quad[0]/(hx*hx)*f;
7302 qyx = (2.0/3.0)*quad[3]/(hx*hy)*f;
7303 qyy = (1.0/3.0)*quad[4]/(hy*hy)*f;
7304 qzx = (2.0/3.0)*quad[6]/(hzed*hx)*f;
7305 qzy = (2.0/3.0)*quad[7]/(hzed*hy)*f;
7306 qzz = (1.0/3.0)*quad[8]/(hzed*hzed)*f;
7332 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
7333 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
7334 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
7335 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]);
7336 Vnm_print(2,
"fillcoPermanentMultipole: xmin = %g, xmax = %g\n", xmin, xmax);
7337 Vnm_print(2,
"fillcoPermanentMultipole: ymin = %g, ymax = %g\n", ymin, ymax);
7338 Vnm_print(2,
"fillcoPermanentMultipole: zmin = %g, zmax = %g\n", zmin, zmax);
7343 position[0] = apos[0] - xmin;
7344 position[1] = apos[1] - ymin;
7345 position[2] = apos[2] - zmin;
7348 ifloat = position[0]/hx;
7349 jfloat = position[1]/hy;
7350 kfloat = position[2]/hzed;
7352 ip1 = (int)ceil(ifloat);
7354 im1 = (int)floor(ifloat);
7356 jp1 = (int)ceil(jfloat);
7358 jm1 = (int)floor(jfloat);
7360 kp1 = (int)ceil(kfloat);
7362 km1 = (int)floor(kfloat);
7367 ip2 = VMIN2(ip2,nx-1);
7368 ip1 = VMIN2(ip1,nx-1);
7371 jp2 = VMIN2(jp2,ny-1);
7372 jp1 = VMIN2(jp1,ny-1);
7375 kp2 = VMIN2(kp2,nz-1);
7376 kp1 = VMIN2(kp1,nz-1);
7381 for (ii=im2; ii<=ip2; ii++) {
7386 for (jj=jm2; jj<=jp2; jj++) {
7391 for (kk=km2; kk<=kp2; kk++) {
7396 charge = mx*my*mz*c -
7397 dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz +
7399 dmx*dmy*mz*qyx + mx*d2my*mz*qyy +
7400 dmx*my*dmz*qzx + mx*dmy*dmz*qzy + mx*my*d2mz*qzz;
7401 thee->
charge[IJK(ii,jj,kk)] += charge;
7461 #if defined(WITH_TINKER) 7471 double xmin, xmax, ymin, ymax, zmin, zmax;
7472 double xlen, ylen, zlen, ifloat, jfloat, kfloat;
7473 double hx, hy, hzed, *apos, position[3];
7475 double mx, my, mz, dmx, dmy, dmz;
7477 double charge, *dipole, ux,uy,uz;
7480 int i, ii, jj, kk, nx, ny, nz, iatom;
7481 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
7487 VASSERT(thee != VNULL);
7503 f = zmagic/(hx*hy*hzed);
7519 Vnm_print(0,
"fillcoInducedDipole: filling in the source term.\n");
7525 dipole = Vatom_getInducedDipole(atom);
7526 ux = dipole[0]/hx*f;
7527 uy = dipole[1]/hy*f;
7528 uz = dipole[2]/hzed*f;
7535 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
7536 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
7537 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
7538 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]);
7539 Vnm_print(2,
"fillcoInducedDipole: xmin = %g, xmax = %g\n", xmin, xmax);
7540 Vnm_print(2,
"fillcoInducedDipole: ymin = %g, ymax = %g\n", ymin, ymax);
7541 Vnm_print(2,
"fillcoInducedDipole: zmin = %g, zmax = %g\n", zmin, zmax);
7546 position[0] = apos[0] - xmin;
7547 position[1] = apos[1] - ymin;
7548 position[2] = apos[2] - zmin;
7551 ifloat = position[0]/hx;
7552 jfloat = position[1]/hy;
7553 kfloat = position[2]/hzed;
7555 ip1 = (int)ceil(ifloat);
7557 im1 = (int)floor(ifloat);
7559 jp1 = (int)ceil(jfloat);
7561 jm1 = (int)floor(jfloat);
7563 kp1 = (int)ceil(kfloat);
7565 km1 = (int)floor(kfloat);
7570 ip2 = VMIN2(ip2,nx-1);
7571 ip1 = VMIN2(ip1,nx-1);
7574 jp2 = VMIN2(jp2,ny-1);
7575 jp1 = VMIN2(jp1,ny-1);
7578 kp2 = VMIN2(kp2,nz-1);
7579 kp1 = VMIN2(kp1,nz-1);
7584 for (ii=im2; ii<=ip2; ii++) {
7588 for (jj=jm2; jj<=jp2; jj++) {
7592 for (kk=km2; kk<=kp2; kk++) {
7596 charge = -dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz;
7597 thee->
charge[IJK(ii,jj,kk)] += charge;
7637 double xmin, xmax, ymin, ymax, zmin, zmax;
7638 double xlen, ylen, zlen, ifloat, jfloat, kfloat;
7639 double hx, hy, hzed, *apos, position[3];
7641 double mx, my, mz, dmx, dmy, dmz;
7643 double charge, *dipole, ux,uy,uz;
7646 int i, ii, jj, kk, nx, ny, nz, iatom;
7647 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
7655 VASSERT(thee != VNULL);
7671 f = zmagic/(hx*hy*hzed);
7687 Vnm_print(0,
"fillcoNLInducedDipole: filling in source term.\n");
7693 dipole = Vatom_getNLInducedDipole(atom);
7694 ux = dipole[0]/hx*f;
7695 uy = dipole[1]/hy*f;
7696 uz = dipole[2]/hzed*f;
7705 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
7706 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
7707 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
7708 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]);
7709 Vnm_print(2,
"fillcoNLInducedDipole: xmin = %g, xmax = %g\n", xmin, xmax);
7710 Vnm_print(2,
"fillcoNLInducedDipole: ymin = %g, ymax = %g\n", ymin, ymax);
7711 Vnm_print(2,
"fillcoNLInducedDipole: zmin = %g, zmax = %g\n", zmin, zmax);
7716 position[0] = apos[0] - xmin;
7717 position[1] = apos[1] - ymin;
7718 position[2] = apos[2] - zmin;
7721 ifloat = position[0]/hx;
7722 jfloat = position[1]/hy;
7723 kfloat = position[2]/hzed;
7725 ip1 = (int)ceil(ifloat);
7727 im1 = (int)floor(ifloat);
7729 jp1 = (int)ceil(jfloat);
7731 jm1 = (int)floor(jfloat);
7733 kp1 = (int)ceil(kfloat);
7735 km1 = (int)floor(kfloat);
7740 ip2 = VMIN2(ip2,nx-1);
7741 ip1 = VMIN2(ip1,nx-1);
7744 jp2 = VMIN2(jp2,ny-1);
7745 jp1 = VMIN2(jp1,ny-1);
7748 kp2 = VMIN2(kp2,nz-1);
7749 kp1 = VMIN2(kp1,nz-1);
7755 for (ii=im2; ii<=ip2; ii++) {
7759 for (jj=jm2; jj<=jp2; jj++) {
7763 for (kk=km2; kk<=kp2; kk++) {
7767 charge = -dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz;
7768 thee->
charge[IJK(ii,jj,kk)] += charge;
7805 double xmax, xmin, ymax, ymin, zmax, zmin;
7806 double hx, hy, hzed, ifloat, jfloat, kfloat;
7810 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz;
7812 int ip1,ip2,im1,im2,jp1,jp2,jm1,jm2,kp1,kp2,km1,km2;
7815 double pot, rfe[3], rfde[3][3], energy;
7816 double f, charge, *dipole, *quad;
7817 double qxx, qyx, qyy, qzx, qzy, qzz;
7820 VASSERT(thee != VNULL);
7830 xmax = thee->
xf[nx-1];
7831 ymax = thee->
yf[ny-1];
7832 zmax = thee->
zf[nz-1];
7843 VASSERT(atom->
partID != 0);
7848 ifloat = (position[0] - xmin)/hx;
7849 jfloat = (position[1] - ymin)/hy;
7850 kfloat = (position[2] - zmin)/hzed;
7851 ip1 = (int)ceil(ifloat);
7853 im1 = (int)floor(ifloat);
7855 jp1 = (int)ceil(jfloat);
7857 jm1 = (int)floor(jfloat);
7859 kp1 = (int)ceil(kfloat);
7861 km1 = (int)floor(kfloat);
7866 ip2 = VMIN2(ip2,nx-1);
7867 ip1 = VMIN2(ip1,nx-1);
7870 jp2 = VMIN2(jp2,ny-1);
7871 jp1 = VMIN2(jp1,ny-1);
7874 kp2 = VMIN2(kp2,nz-1);
7875 kp1 = VMIN2(kp1,nz-1);
7889 for (ii=im2; ii<=ip2; ii++) {
7894 for (jj=jm2; jj<=jp2; jj++) {
7899 for (kk=km2; kk<=kp2; kk++) {
7904 f = u[IJK(ii,jj,kk)];
7908 rfe[0] += f*dmx*my*mz/hx;
7909 rfe[1] += f*mx*dmy*mz/hy;
7910 rfe[2] += f*mx*my*dmz/hzed;
7912 rfde[0][0] += f*d2mx*my*mz/(hx*hx);
7913 rfde[1][0] += f*dmx*dmy*mz/(hy*hx);
7914 rfde[1][1] += f*mx*d2my*mz/(hy*hy);
7915 rfde[2][0] += f*dmx*my*dmz/(hx*hzed);
7916 rfde[2][1] += f*mx*dmy*dmz/(hy*hzed);
7917 rfde[2][2] += f*mx*my*d2mz/(hzed*hzed);
7923 dipole = Vatom_getDipole(atom);
7924 quad = Vatom_getQuadrupole(atom);
7932 energy = pot * charge
7933 - rfe[0] * dipole[0]
7934 - rfe[1] * dipole[1]
7935 - rfe[2] * dipole[2]
7937 + 2.0*rfde[1][0]*qyx + rfde[1][1]*qyy
7938 + 2.0*rfde[2][0]*qzx + 2.0*rfde[2][1]*qzy + rfde[2][2]*qzz;
7949 double xmax, xmin, ymax, ymin, zmax, zmin;
7950 double hx, hy, hzed, ifloat, jfloat, kfloat;
7951 double *apos, position[3];
7953 double mx, my, mz, dmx, dmy, dmz;
7956 int ip1,ip2,im1,im2,jp1,jp2,jm1,jm2,kp1,kp2,km1,km2;
7960 VASSERT (thee != VNULL);
7969 xmax = thee->
xf[nx-1];
7970 ymax = thee->
yf[ny-1];
7971 zmax = thee->
zf[nz-1];
7982 VASSERT (atom->
partID != 0);
7987 position[0] = apos[0] - xmin;
7988 position[1] = apos[1] - ymin;
7989 position[2] = apos[2] - zmin;
7990 ifloat = position[0]/hx;
7991 jfloat = position[1]/hy;
7992 kfloat = position[2]/hzed;
7993 ip1 = (int)ceil(ifloat);
7995 im1 = (int)floor(ifloat);
7997 jp1 = (int)ceil(jfloat);
7999 jm1 = (int)floor(jfloat);
8001 kp1 = (int)ceil(kfloat);
8003 km1 = (int)floor(kfloat);
8008 ip2 = VMIN2(ip2,nx-1);
8009 ip1 = VMIN2(ip1,nx-1);
8012 jp2 = VMIN2(jp2,ny-1);
8013 jp1 = VMIN2(jp1,ny-1);
8016 kp2 = VMIN2(kp2,nz-1);
8017 kp1 = VMIN2(kp1,nz-1);
8025 for (ii=im2; ii<=ip2; ii++) {
8029 for (jj=jm2; jj<=jp2; jj++) {
8033 for (kk=km2; kk<=kp2; kk++) {
8037 f = u[IJK(ii,jj,kk)];
8039 field[0] += f*dmx*my*mz/hx;
8040 field[1] += f*mx*dmy*mz/hy;
8041 field[2] += f*mx*my*dmz/hzed;
8048 double force[3],
double torque[3]) {
8051 double f, *u, *apos, position[3];
8055 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
8056 double hx, hy, hzed, ifloat, jfloat, kfloat;
8059 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz, d3mx, d3my, d3mz;
8063 int i, j, k, ii, jj, kk;
8064 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
8067 double pot, e[3], de[3][3], d2e[3][3][3];
8070 double *dipole, *quad;
8071 double c, ux, uy, uz, qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz;
8073 VASSERT(thee != VNULL);
8080 VASSERT(atom->
partID != 0);
8085 dipole = Vatom_getDipole(atom);
8089 quad = Vatom_getQuadrupole(atom);
8131 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
8132 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
8133 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
8134 Vnm_print(2,
"qfPermanentMultipoleForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
8139 position[0] = apos[0] - xmin;
8140 position[1] = apos[1] - ymin;
8141 position[2] = apos[2] - zmin;
8142 ifloat = position[0]/hx;
8143 jfloat = position[1]/hy;
8144 kfloat = position[2]/hzed;
8145 ip1 = (int)ceil(ifloat);
8147 im1 = (int)floor(ifloat);
8149 jp1 = (int)ceil(jfloat);
8151 jm1 = (int)floor(jfloat);
8153 kp1 = (int)ceil(kfloat);
8155 km1 = (int)floor(kfloat);
8160 ip2 = VMIN2(ip2,nx-1);
8161 ip1 = VMIN2(ip1,nx-1);
8164 jp2 = VMIN2(jp2,ny-1);
8165 jp1 = VMIN2(jp1,ny-1);
8168 kp2 = VMIN2(kp2,nz-1);
8169 kp1 = VMIN2(kp1,nz-1);
8173 for (ii=im2; ii<=ip2; ii++) {
8179 for (jj=jm2; jj<=jp2; jj++) {
8185 for (kk=km2; kk<=kp2; kk++) {
8191 f = u[IJK(ii,jj,kk)];
8195 e[0] += f*dmx*my*mz/hx;
8196 e[1] += f*mx*dmy*mz/hy;
8197 e[2] += f*mx*my*dmz/hzed;
8199 de[0][0] += f*d2mx*my*mz/(hx*hx);
8200 de[1][0] += f*dmx*dmy*mz/(hy*hx);
8201 de[1][1] += f*mx*d2my*mz/(hy*hy);
8202 de[2][0] += f*dmx*my*dmz/(hx*hzed);
8203 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
8204 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
8207 d2e[0][0][0] += f*d3mx*my*mz /(hx*hx*hx);
8208 d2e[0][0][1] += f*d2mx*dmy*mz/(hx*hy*hx);
8209 d2e[0][0][2] += f*d2mx*my*dmz/(hx*hx*hzed);
8211 d2e[1][0][0] += f*d2mx*dmy*mz/(hx*hx*hy);
8212 d2e[1][0][1] += f*dmx*d2my*mz/(hx*hy*hy);
8213 d2e[1][0][2] += f*dmx*dmy*dmz/(hx*hy*hzed);
8215 d2e[1][1][0] += f*dmx*d2my*mz/(hx*hy*hy);
8216 d2e[1][1][1] += f*mx*d3my*mz /(hy*hy*hy);
8217 d2e[1][1][2] += f*mx*d2my*dmz/(hy*hy*hzed);
8219 d2e[2][0][0] += f*d2mx*my*dmz/(hx*hx*hzed);
8220 d2e[2][0][1] += f*dmx*dmy*dmz/(hx*hy*hzed);
8221 d2e[2][0][2] += f*dmx*my*d2mz/(hx*hzed*hzed);
8223 d2e[2][1][0] += f*dmx*dmy*dmz/(hx*hy*hzed);
8224 d2e[2][1][1] += f*mx*d2my*dmz/(hy*hy*hzed);
8225 d2e[2][1][2] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8227 d2e[2][2][0] += f*dmx*my*d2mz/(hx*hzed*hzed);
8228 d2e[2][2][1] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8229 d2e[2][2][2] += f*mx*my*d3mz /(hzed*hzed*hzed);
8241 force[0] -= de[0][0]*ux+de[1][0]*uy+de[2][0]*uz;
8242 force[1] -= de[1][0]*ux+de[1][1]*uy+de[2][1]*uz;
8243 force[2] -= de[2][0]*ux+de[2][1]*uy+de[2][2]*uz;
8246 force[0] += d2e[0][0][0]*qxx
8247 + d2e[1][0][0]*qyx*2.0+d2e[1][1][0]*qyy
8248 + d2e[2][0][0]*qzx*2.0+d2e[2][1][0]*qzy*2.0+d2e[2][2][0]*qzz;
8249 force[1] += d2e[0][0][1]*qxx
8250 + d2e[1][0][1]*qyx*2.0+d2e[1][1][1]*qyy
8251 + d2e[2][0][1]*qzx*2.0+d2e[2][1][1]*qzy*2.0+d2e[2][2][1]*qzz;
8252 force[2] += d2e[0][0][2]*qxx
8253 + d2e[1][0][2]*qyx*2.0+d2e[1][1][2]*qyy
8254 + d2e[2][0][2]*qzx*2.0+d2e[2][1][2]*qzy*2.0+d2e[2][2][2]*qzz;
8257 torque[0] = uy * e[2] - uz * e[1];
8258 torque[1] = uz * e[0] - ux * e[2];
8259 torque[2] = ux * e[1] - uy * e[0];
8261 de[0][1] = de[1][0];
8262 de[0][2] = de[2][0];
8263 de[1][2] = de[2][1];
8264 torque[0] -= 2.0*(qyx*de[0][2] + qyy*de[1][2] + qyz*de[2][2]
8265 - qzx*de[0][1] - qzy*de[1][1] - qzz*de[2][1]);
8266 torque[1] -= 2.0*(qzx*de[0][0] + qzy*de[1][0] + qzz*de[2][0]
8267 - qxx*de[0][2] - qxy*de[1][2] - qxz*de[2][2]);
8268 torque[2] -= 2.0*(qxx*de[0][1] + qxy*de[1][1] + qxz*de[2][1]
8269 - qyx*de[0][0] - qyy*de[1][0] - qyz*de[2][0]);
8286 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
8287 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
8288 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
8290 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
8292 VASSERT(thee != VNULL);
8303 VASSERT(atom->
partID != 0);
8341 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
8342 (apos[1]<=ymin) || (apos[1]>=ymax) || \
8343 (apos[2]<=zmin) || (apos[2]>=zmax)) {
8344 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]);
8345 Vnm_print(2,
"ibPermanentMultipoleForce: xmin = %g, xmax = %g\n", xmin, xmax);
8346 Vnm_print(2,
"ibPermanentMultipoleForce: ymin = %g, ymax = %g\n", ymin, ymax);
8347 Vnm_print(2,
"ibPermanentMultipoleForce: zmin = %g, zmax = %g\n", zmin, zmax);
8352 position[0] = apos[0] - xmin;
8353 position[1] = apos[1] - ymin;
8354 position[2] = apos[2] - zmin;
8360 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
8361 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
8362 for (i=imin; i<=imax; i++) {
8363 dx2 = VSQR(position[0] - hx*i);
8364 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
8366 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
8367 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
8368 for (j=jmin; j<=jmax; j++) {
8369 dy2 = VSQR(position[1] - hy*j);
8370 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
8372 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
8373 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
8374 for (k=kmin; k<=kmax; k++) {
8375 dz2 = VSQR(k*hzed - position[2]);
8378 if ((dz2 + dy2 + dx2) <= rtot2) {
8379 gpos[0] = i*hx + xmin;
8380 gpos[1] = j*hy + ymin;
8381 gpos[2] = k*hzed + zmin;
8383 fmag = VSQR(thee->
u[IJK(i,j,k)])*thee->
kappa[IJK(i,j,k)];
8384 force[0] += (zkappa2*fmag*tgrad[0]);
8385 force[1] += (zkappa2*fmag*tgrad[1]);
8386 force[2] += (zkappa2*fmag*tgrad[2]);
8393 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
8394 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
8395 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
8407 double *apos, position[3], arad, hx, hy, hzed, izmagic, deps, depsi;
8408 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
8409 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
8410 double *u, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
8411 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
8413 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
8415 VASSERT(thee != VNULL);
8423 VASSERT(atom->
partID != 0);
8441 deps = (epsw - epsp);
8465 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
8466 (apos[1]<=ymin) || (apos[1]>=ymax) || \
8467 (apos[2]<=zmin) || (apos[2]>=zmax)) {
8468 Vnm_print(2,
"dbPermanentMultipoleForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n", apos[0], apos[1], apos[2]);
8469 Vnm_print(2,
"dbPermanentMultipoleForce: xmin = %g, xmax = %g\n", xmin, xmax);
8470 Vnm_print(2,
"dbPermanentMultipoleForce: ymin = %g, ymax = %g\n", ymin, ymax);
8471 Vnm_print(2,
"dbPermanentMultipoleForce: zmin = %g, zmax = %g\n", zmin, zmax);
8476 position[0] = apos[0] - xmin;
8477 position[1] = apos[1] - ymin;
8478 position[2] = apos[2] - zmin;
8484 imin = (int)floor((position[0]-rtot)/hx);
8486 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8489 imax = (int)ceil((position[0]+rtot)/hx);
8490 if (imax > (nx-2)) {
8491 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8494 jmin = (int)floor((position[1]-rtot)/hy);
8496 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8499 jmax = (int)ceil((position[1]+rtot)/hy);
8500 if (jmax > (ny-2)) {
8501 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8504 kmin = (int)floor((position[2]-rtot)/hzed);
8506 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8509 kmax = (int)ceil((position[2]+rtot)/hzed);
8510 if (kmax > (nz-2)) {
8511 Vnm_print(2,
"dbPermanentMultipoleForce: Atom off grid!\n");
8514 for (i=imin; i<=imax; i++) {
8515 for (j=jmin; j<=jmax; j++) {
8516 for (k=kmin; k<=kmax; k++) {
8518 gpos[0] = (i+0.5)*hx + xmin;
8519 gpos[1] = j*hy + ymin;
8520 gpos[2] = k*hzed + zmin;
8521 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
8524 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
8525 gpos[0] = i*hx + xmin;
8526 gpos[1] = (j+0.5)*hy + ymin;
8527 gpos[2] = k*hzed + zmin;
8528 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
8531 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
8532 gpos[0] = i*hx + xmin;
8533 gpos[1] = j*hy + ymin;
8534 gpos[2] = (k+0.5)*hzed + zmin;
8535 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
8538 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
8540 gpos[0] = (i-0.5)*hx + xmin;
8541 gpos[1] = j*hy + ymin;
8542 gpos[2] = k*hzed + zmin;
8543 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
8546 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
8548 gpos[0] = i*hx + xmin;
8549 gpos[1] = (j-0.5)*hy + ymin;
8550 gpos[2] = k*hzed + zmin;
8551 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
8554 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
8556 gpos[0] = i*hx + xmin;
8557 gpos[1] = j*hy + ymin;
8558 gpos[2] = (k-0.5)*hzed + zmin;
8559 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
8562 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
8563 dbFmag = u[IJK(i,j,k)];
8565 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
8566 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
8567 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
8568 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
8569 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
8570 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
8572 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
8573 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
8574 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
8575 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
8576 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
8577 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
8579 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
8580 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
8581 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
8582 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
8583 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
8584 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
8585 force[0] += (dbFmag*tgrad[0]);
8586 force[1] += (dbFmag*tgrad[1]);
8587 force[2] += (dbFmag*tgrad[2]);
8591 force[0] = -force[0]*hx*hy*hzed*deps*0.5*izmagic;
8592 force[1] = -force[1]*hx*hy*hzed*deps*0.5*izmagic;
8593 force[2] = -force[2]*hx*hy*hzed*deps*0.5*izmagic;
8598 int atomID,
double force[3],
double torque[3]) {
8602 double f, fp, *u, *up, *apos, position[3];
8606 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
8607 double hx, hy, hzed, ifloat, jfloat, kfloat;
8610 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz, d3mx, d3my, d3mz;
8614 int i, j, k, ii, jj, kk;
8615 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
8618 double pot, e[3], de[3][3], d2e[3][3][3];
8623 double *dipole, *quad;
8624 double c, ux, uy, uz, qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz;
8625 double uix, uiy, uiz;
8627 VASSERT(thee != VNULL);
8628 VASSERT(induced != VNULL);
8629 VASSERT(induced != VNULL);
8630 VASSERT(thee->
pbe != VNULL);
8631 VASSERT(thee->
pbe->
alist != VNULL);
8634 VASSERT(atom->
partID != 0);
8638 dipole = Vatom_getDipole(atom);
8642 quad = Vatom_getQuadrupole(atom);
8653 dipole = Vatom_getInducedDipole(atom);
8691 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
8692 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
8693 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
8694 Vnm_print(2,
"qfDirectPolForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
8700 position[0] = apos[0] - xmin;
8701 position[1] = apos[1] - ymin;
8702 position[2] = apos[2] - zmin;
8703 ifloat = position[0]/hx;
8704 jfloat = position[1]/hy;
8705 kfloat = position[2]/hzed;
8706 ip1 = (int)ceil(ifloat);
8708 im1 = (int)floor(ifloat);
8710 jp1 = (int)ceil(jfloat);
8712 jm1 = (int)floor(jfloat);
8714 kp1 = (int)ceil(kfloat);
8716 km1 = (int)floor(kfloat);
8721 ip2 = VMIN2(ip2,nx-1);
8722 ip1 = VMIN2(ip1,nx-1);
8725 jp2 = VMIN2(jp2,ny-1);
8726 jp1 = VMIN2(jp1,ny-1);
8729 kp2 = VMIN2(kp2,nz-1);
8730 kp1 = VMIN2(kp1,nz-1);
8734 for (ii=im2; ii<=ip2; ii++) {
8740 for (jj=jm2; jj<=jp2; jj++) {
8746 for (kk=km2; kk<=kp2; kk++) {
8752 f = u[IJK(ii,jj,kk)];
8753 fp = up[IJK(ii,jj,kk)];
8757 e[0] += f*dmx*my*mz/hx;
8758 e[1] += f*mx*dmy*mz/hy;
8759 e[2] += f*mx*my*dmz/hzed;
8761 de[0][0] += f*d2mx*my*mz/(hx*hx);
8762 de[1][0] += f*dmx*dmy*mz/(hy*hx);
8763 de[1][1] += f*mx*d2my*mz/(hy*hy);
8764 de[2][0] += f*dmx*my*dmz/(hx*hzed);
8765 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
8766 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
8768 dep[0][0] += fp*d2mx*my*mz/(hx*hx);
8769 dep[1][0] += fp*dmx*dmy*mz/(hy*hx);
8770 dep[1][1] += fp*mx*d2my*mz/(hy*hy);
8771 dep[2][0] += fp*dmx*my*dmz/(hx*hzed);
8772 dep[2][1] += fp*mx*dmy*dmz/(hy*hzed);
8773 dep[2][2] += fp*mx*my*d2mz/(hzed*hzed);
8776 d2e[0][0][0] += f*d3mx*my*mz /(hx*hx*hx);
8777 d2e[0][0][1] += f*d2mx*dmy*mz/(hx*hy*hx);
8778 d2e[0][0][2] += f*d2mx*my*dmz/(hx*hx*hzed);
8780 d2e[1][0][0] += f*d2mx*dmy*mz/(hx*hx*hy);
8781 d2e[1][0][1] += f*dmx*d2my*mz/(hx*hy*hy);
8782 d2e[1][0][2] += f*dmx*dmy*dmz/(hx*hy*hzed);
8784 d2e[1][1][0] += f*dmx*d2my*mz/(hx*hy*hy);
8785 d2e[1][1][1] += f*mx*d3my*mz /(hy*hy*hy);
8786 d2e[1][1][2] += f*mx*d2my*dmz/(hy*hy*hzed);
8788 d2e[2][0][0] += f*d2mx*my*dmz/(hx*hx*hzed);
8789 d2e[2][0][1] += f*dmx*dmy*dmz/(hx*hy*hzed);
8790 d2e[2][0][2] += f*dmx*my*d2mz/(hx*hzed*hzed);
8792 d2e[2][1][0] += f*dmx*dmy*dmz/(hx*hy*hzed);
8793 d2e[2][1][1] += f*mx*d2my*dmz/(hy*hy*hzed);
8794 d2e[2][1][2] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8796 d2e[2][2][0] += f*dmx*my*d2mz/(hx*hzed*hzed);
8797 d2e[2][2][1] += f*mx*dmy*d2mz/(hy*hzed*hzed);
8798 d2e[2][2][2] += f*mx*my*d3mz /(hzed*hzed*hzed);
8812 force[0] -= de[0][0]*ux+de[1][0]*uy+de[2][0]*uz;
8813 force[1] -= de[1][0]*ux+de[1][1]*uy+de[2][1]*uz;
8814 force[2] -= de[2][0]*ux+de[2][1]*uy+de[2][2]*uz;
8817 force[0] += d2e[0][0][0]*qxx
8818 + d2e[1][0][0]*qyx*2.0+d2e[1][1][0]*qyy
8819 + d2e[2][0][0]*qzx*2.0+d2e[2][1][0]*qzy*2.0+d2e[2][2][0]*qzz;
8820 force[1] += d2e[0][0][1]*qxx
8821 + d2e[1][0][1]*qyx*2.0+d2e[1][1][1]*qyy
8822 + d2e[2][0][1]*qzx*2.0+d2e[2][1][1]*qzy*2.0+d2e[2][2][1]*qzz;
8823 force[2] += d2e[0][0][2]*qxx
8824 + d2e[1][0][2]*qyx*2.0+d2e[1][1][2]*qyy
8825 + d2e[2][0][2]*qzx*2.0+d2e[2][1][2]*qzy*2.0+d2e[2][2][2]*qzz;
8830 torque[0] = uy * e[2] - uz * e[1];
8831 torque[1] = uz * e[0] - ux * e[2];
8832 torque[2] = ux * e[1] - uy * e[0];
8838 de[0][1] = de[1][0];
8839 de[0][2] = de[2][0];
8840 de[1][2] = de[2][1];
8841 torque[0] -= 2.0*(qyx*de[0][2] + qyy*de[1][2] + qyz*de[2][2]
8842 - qzx*de[0][1] - qzy*de[1][1] - qzz*de[2][1]);
8843 torque[1] -= 2.0*(qzx*de[0][0] + qzy*de[1][0] + qzz*de[2][0]
8844 - qxx*de[0][2] - qxy*de[1][2] - qxz*de[2][2]);
8845 torque[2] -= 2.0*(qxx*de[0][1] + qxy*de[1][1] + qxz*de[2][1]
8846 - qyx*de[0][0] - qyy*de[1][0] - qyz*de[2][0]);
8850 force[0] -= dep[0][0]*uix+dep[1][0]*uiy+dep[2][0]*uiz;
8851 force[1] -= dep[1][0]*uix+dep[1][1]*uiy+dep[2][1]*uiz;
8852 force[2] -= dep[2][0]*uix+dep[2][1]*uiy+dep[2][2]*uiz;
8854 force[0] = 0.5 * force[0];
8855 force[1] = 0.5 * force[1];
8856 force[2] = 0.5 * force[2];
8857 torque[0] = 0.5 * torque[0];
8858 torque[1] = 0.5 * torque[1];
8859 torque[2] = 0.5 * torque[2];
8866 int atomID,
double force[3],
double torque[3]) {
8869 double *apos, *dipole, *quad, position[3], hx, hy, hzed;
8870 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
8871 double pot, e[3],de[3][3],dep[3][3],d2e[3][3][3];
8872 double mx, my, mz, dmx, dmy, dmz, mi, mj, mk;
8873 double d2mx, d2my, d2mz, d3mx, d3my, d3mz;
8874 double *u, *up, charge, ifloat, jfloat, kfloat;
8875 double f, fp, c, ux, uy, uz, qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz;
8876 double uix, uiy, uiz;
8877 int i,j,k,nx, ny, nz, im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1;
8878 int kp1, kp2, ii, jj, kk;
8880 VASSERT(thee != VNULL);
8881 VASSERT(perm != VNULL);
8882 VASSERT(nlInduced != VNULL);
8886 VASSERT(atom->
partID != 0);
8890 dipole = Vatom_getDipole(atom);
8894 quad = Vatom_getQuadrupole(atom);
8905 dipole = Vatom_getNLInducedDipole(atom);
8939 u = nlInduced->
data;
8944 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
8945 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
8946 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
8947 Vnm_print(2,
"qfNLDirectMultipoleForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
8951 position[0] = apos[0] - xmin;
8952 position[1] = apos[1] - ymin;
8953 position[2] = apos[2] - zmin;
8954 ifloat = position[0]/hx;
8955 jfloat = position[1]/hy;
8956 kfloat = position[2]/hzed;
8957 ip1 = (int)ceil(ifloat);
8959 im1 = (int)floor(ifloat);
8961 jp1 = (int)ceil(jfloat);
8963 jm1 = (int)floor(jfloat);
8965 kp1 = (int)ceil(kfloat);
8967 km1 = (int)floor(kfloat);
8972 ip2 = VMIN2(ip2,nx-1);
8973 ip1 = VMIN2(ip1,nx-1);
8976 jp2 = VMIN2(jp2,ny-1);
8977 jp1 = VMIN2(jp1,ny-1);
8980 kp2 = VMIN2(kp2,nz-1);
8981 kp1 = VMIN2(kp1,nz-1);
8985 for (ii=im2; ii<=ip2; ii++) {
8991 for (jj=jm2; jj<=jp2; jj++) {
8997 for (kk=km2; kk<=kp2; kk++) {
9003 f = u[IJK(ii,jj,kk)];
9004 fp = up[IJK(ii,jj,kk)];
9008 e[0] += f*dmx*my*mz/hx;
9009 e[1] += f*mx*dmy*mz/hy;
9010 e[2] += f*mx*my*dmz/hzed;
9012 de[0][0] += f*d2mx*my*mz/(hx*hx);
9013 de[1][0] += f*dmx*dmy*mz/(hy*hx);
9014 de[1][1] += f*mx*d2my*mz/(hy*hy);
9015 de[2][0] += f*dmx*my*dmz/(hx*hzed);
9016 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
9017 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
9019 dep[0][0] += fp*d2mx*my*mz/(hx*hx);
9020 dep[1][0] += fp*dmx*dmy*mz/(hy*hx);
9021 dep[1][1] += fp*mx*d2my*mz/(hy*hy);
9022 dep[2][0] += fp*dmx*my*dmz/(hx*hzed);
9023 dep[2][1] += fp*mx*dmy*dmz/(hy*hzed);
9024 dep[2][2] += fp*mx*my*d2mz/(hzed*hzed);
9027 d2e[0][0][0] += f*d3mx*my*mz /(hx*hx*hx);
9028 d2e[0][0][1] += f*d2mx*dmy*mz/(hx*hy*hx);
9029 d2e[0][0][2] += f*d2mx*my*dmz/(hx*hx*hzed);
9031 d2e[1][0][0] += f*d2mx*dmy*mz/(hx*hx*hy);
9032 d2e[1][0][1] += f*dmx*d2my*mz/(hx*hy*hy);
9033 d2e[1][0][2] += f*dmx*dmy*dmz/(hx*hy*hzed);
9035 d2e[1][1][0] += f*dmx*d2my*mz/(hx*hy*hy);
9036 d2e[1][1][1] += f*mx*d3my*mz /(hy*hy*hy);
9037 d2e[1][1][2] += f*mx*d2my*dmz/(hy*hy*hzed);
9039 d2e[2][0][0] += f*d2mx*my*dmz/(hx*hx*hzed);
9040 d2e[2][0][1] += f*dmx*dmy*dmz/(hx*hy*hzed);
9041 d2e[2][0][2] += f*dmx*my*d2mz/(hx*hzed*hzed);
9043 d2e[2][1][0] += f*dmx*dmy*dmz/(hx*hy*hzed);
9044 d2e[2][1][1] += f*mx*d2my*dmz/(hy*hy*hzed);
9045 d2e[2][1][2] += f*mx*dmy*d2mz/(hy*hzed*hzed);
9047 d2e[2][2][0] += f*dmx*my*d2mz/(hx*hzed*hzed);
9048 d2e[2][2][1] += f*mx*dmy*d2mz/(hy*hzed*hzed);
9049 d2e[2][2][2] += f*mx*my*d3mz /(hzed*hzed*hzed);
9063 force[0] -= de[0][0]*ux+de[1][0]*uy+de[2][0]*uz;
9064 force[1] -= de[1][0]*ux+de[1][1]*uy+de[2][1]*uz;
9065 force[2] -= de[2][0]*ux+de[2][1]*uy+de[2][2]*uz;
9068 force[0] += d2e[0][0][0]*qxx
9069 + d2e[1][0][0]*qyx*2.0+d2e[1][1][0]*qyy
9070 + d2e[2][0][0]*qzx*2.0+d2e[2][1][0]*qzy*2.0+d2e[2][2][0]*qzz;
9071 force[1] += d2e[0][0][1]*qxx
9072 + d2e[1][0][1]*qyx*2.0+d2e[1][1][1]*qyy
9073 + d2e[2][0][1]*qzx*2.0+d2e[2][1][1]*qzy*2.0+d2e[2][2][1]*qzz;
9074 force[2] += d2e[0][0][2]*qxx
9075 + d2e[1][0][2]*qyx*2.0+d2e[1][1][2]*qyy
9076 + d2e[2][0][2]*qzx*2.0+d2e[2][1][2]*qzy*2.0+d2e[2][2][2]*qzz;
9081 torque[0] = uy * e[2] - uz * e[1];
9082 torque[1] = uz * e[0] - ux * e[2];
9083 torque[2] = ux * e[1] - uy * e[0];
9089 de[0][1] = de[1][0];
9090 de[0][2] = de[2][0];
9091 de[1][2] = de[2][1];
9092 torque[0] -= 2.0*(qyx*de[0][2] + qyy*de[1][2] + qyz*de[2][2]
9093 - qzx*de[0][1] - qzy*de[1][1] - qzz*de[2][1]);
9094 torque[1] -= 2.0*(qzx*de[0][0] + qzy*de[1][0] + qzz*de[2][0]
9095 - qxx*de[0][2] - qxy*de[1][2] - qxz*de[2][2]);
9096 torque[2] -= 2.0*(qxx*de[0][1] + qxy*de[1][1] + qxz*de[2][1]
9097 - qyx*de[0][0] - qyy*de[1][0] - qyz*de[2][0]);
9101 force[0] -= dep[0][0]*uix+dep[1][0]*uiy+dep[2][0]*uiz;
9102 force[1] -= dep[1][0]*uix+dep[1][1]*uiy+dep[2][1]*uiz;
9103 force[2] -= dep[2][0]*uix+dep[2][1]*uiy+dep[2][2]*uiz;
9105 force[0] = 0.5 * force[0];
9106 force[1] = 0.5 * force[1];
9107 force[2] = 0.5 * force[2];
9108 torque[0] = 0.5 * torque[0];
9109 torque[1] = 0.5 * torque[1];
9110 torque[2] = 0.5 * torque[2];
9117 int atomID,
double force[3]) {
9125 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
9126 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
9127 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
9129 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9131 VASSERT(thee != VNULL);
9132 VASSERT(perm != VNULL);
9133 VASSERT(induced != VNULL);
9139 VASSERT(atom->
partID != 0);
9164 hzed = induced->
hzed;
9165 xmin = induced->
xmin;
9166 ymin = induced->
ymin;
9167 zmin = induced->
zmin;
9168 xmax = induced->
xmax;
9169 ymax = induced->
ymax;
9170 zmax = induced->
zmax;
9176 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9177 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9178 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9179 Vnm_print(2,
"Vpmg_ibForce: Atom at (%4.3f, %4.3f, %4.3f) is off the mesh (ignoring):\n",
9180 apos[0], apos[1], apos[2]);
9181 Vnm_print(2,
"Vpmg_ibForce: xmin = %g, xmax = %g\n", xmin, xmax);
9182 Vnm_print(2,
"Vpmg_ibForce: ymin = %g, ymax = %g\n", ymin, ymax);
9183 Vnm_print(2,
"Vpmg_ibForce: zmin = %g, zmax = %g\n", zmin, zmax);
9188 position[0] = apos[0] - xmin;
9189 position[1] = apos[1] - ymin;
9190 position[2] = apos[2] - zmin;
9196 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
9197 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
9198 for (i=imin; i<=imax; i++) {
9199 dx2 = VSQR(position[0] - hx*i);
9200 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
9202 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
9203 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
9204 for (j=jmin; j<=jmax; j++) {
9205 dy2 = VSQR(position[1] - hy*j);
9206 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
9208 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
9209 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
9210 for (k=kmin; k<=kmax; k++) {
9211 dz2 = VSQR(k*hzed - position[2]);
9214 if ((dz2 + dy2 + dx2) <= rtot2) {
9215 gpos[0] = i*hx + xmin;
9216 gpos[1] = j*hy + ymin;
9217 gpos[2] = k*hzed + zmin;
9220 fmag = induced->
data[IJK(i,j,k)];
9221 fmag *= perm->
data[IJK(i,j,k)];
9222 fmag *= thee->
kappa[IJK(i,j,k)];
9223 force[0] += (zkappa2*fmag*tgrad[0]);
9224 force[1] += (zkappa2*fmag*tgrad[1]);
9225 force[2] += (zkappa2*fmag*tgrad[2]);
9232 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
9233 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
9234 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
9239 int atomID,
double force[3]) {
9244 int atomID,
double force[3]) {
9251 double *apos, position[3], arad, hx, hy, hzed, izmagic, deps, depsi;
9252 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
9253 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
9254 double *u, *up, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
9255 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
9257 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9259 VASSERT(thee != VNULL);
9260 VASSERT(perm != VNULL);
9261 VASSERT(induced != VNULL);
9265 VASSERT (atom->
partID != 0);
9283 deps = (epsw - epsp);
9309 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9310 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9311 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9312 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]);
9313 Vnm_print(2,
"Vpmg_dbDirectPolForce: xmin = %g, xmax = %g\n", xmin, xmax);
9314 Vnm_print(2,
"Vpmg_dbDirectPolForce: ymin = %g, ymax = %g\n", ymin, ymax);
9315 Vnm_print(2,
"Vpmg_dbDirectPolForce: zmin = %g, zmax = %g\n", zmin, zmax);
9320 position[0] = apos[0] - xmin;
9321 position[1] = apos[1] - ymin;
9322 position[2] = apos[2] - zmin;
9328 imin = (int)floor((position[0]-rtot)/hx);
9330 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9333 imax = (int)ceil((position[0]+rtot)/hx);
9334 if (imax > (nx-2)) {
9335 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9338 jmin = (int)floor((position[1]-rtot)/hy);
9340 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9343 jmax = (int)ceil((position[1]+rtot)/hy);
9344 if (jmax > (ny-2)) {
9345 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9348 kmin = (int)floor((position[2]-rtot)/hzed);
9350 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9353 kmax = (int)ceil((position[2]+rtot)/hzed);
9354 if (kmax > (nz-2)) {
9355 Vnm_print(2,
"Vpmg_dbDirectPolForce: Atom %d off grid!\n", atomID);
9358 for (i=imin; i<=imax; i++) {
9359 for (j=jmin; j<=jmax; j++) {
9360 for (k=kmin; k<=kmax; k++) {
9362 gpos[0] = (i+0.5)*hx + xmin;
9363 gpos[1] = j*hy + ymin;
9364 gpos[2] = k*hzed + zmin;
9365 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
9368 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
9369 gpos[0] = i*hx + xmin;
9370 gpos[1] = (j+0.5)*hy + ymin;
9371 gpos[2] = k*hzed + zmin;
9372 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
9375 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
9376 gpos[0] = i*hx + xmin;
9377 gpos[1] = j*hy + ymin;
9378 gpos[2] = (k+0.5)*hzed + zmin;
9379 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
9382 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
9384 gpos[0] = (i-0.5)*hx + xmin;
9385 gpos[1] = j*hy + ymin;
9386 gpos[2] = k*hzed + zmin;
9387 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
9390 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
9392 gpos[0] = i*hx + xmin;
9393 gpos[1] = (j-0.5)*hy + ymin;
9394 gpos[2] = k*hzed + zmin;
9395 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
9398 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
9400 gpos[0] = i*hx + xmin;
9401 gpos[1] = j*hy + ymin;
9402 gpos[2] = (k-0.5)*hzed + zmin;
9403 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
9406 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
9408 dbFmag = up[IJK(i,j,k)];
9410 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9411 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9412 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9413 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9414 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9415 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9417 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9418 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9419 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9420 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9421 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9422 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9424 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9425 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9426 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9427 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9428 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9429 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9430 force[0] += (dbFmag*tgrad[0]);
9431 force[1] += (dbFmag*tgrad[1]);
9432 force[2] += (dbFmag*tgrad[2]);
9438 force[0] = -force[0]*hx*hy*hzed*deps*0.5*izmagic;
9439 force[1] = -force[1]*hx*hy*hzed*deps*0.5*izmagic;
9440 force[2] = -force[2]*hx*hy*hzed*deps*0.5*izmagic;
9446 int atomID,
double force[3]) {
9451 Vgrid *nlinduced,
int atomID,
double force[3]) {
9454 double *apos, *dipole, position[3], hx, hy, hzed;
9456 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax;
9457 double de[3][3], denl[3][3];
9458 double mx, my, mz, dmx, dmy, dmz, d2mx, d2my, d2mz, mi, mj, mk;
9459 double ifloat, jfloat, kfloat;
9460 double f, fnl, uix, uiy, uiz, uixnl, uiynl, uiznl;
9461 int i,j,k,nx, ny, nz, im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1;
9462 int kp1, kp2, ii, jj, kk;
9464 VASSERT(thee != VNULL);
9465 VASSERT(induced != VNULL);
9466 VASSERT(nlinduced != VNULL);
9468 VASSERT(atom->
partID != 0);
9470 dipole = Vatom_getInducedDipole(atom);
9474 dipole = Vatom_getNLInducedDipole(atom);
9479 unl = nlinduced->
data;
9494 hzed = induced->
hzed;
9495 xmin = induced->
xmin;
9496 ymin = induced->
ymin;
9497 zmin = induced->
zmin;
9498 xmax = induced->
xmax;
9499 ymax = induced->
ymax;
9500 zmax = induced->
zmax;
9506 if (atom->
partID == 0)
return;
9509 if ((apos[0]<=(xmin+2*hx)) || (apos[0]>=(xmax-2*hx)) \
9510 || (apos[1]<=(ymin+2*hy)) || (apos[1]>=(ymax-2*hy)) \
9511 || (apos[2]<=(zmin+2*hzed)) || (apos[2]>=(zmax-2*hzed))) {
9512 Vnm_print(2,
"qfMutualPolForce: Atom off the mesh (ignoring) %6.3f %6.3f %6.3f\n", apos[0], apos[1], apos[2]);
9517 position[0] = apos[0] - xmin;
9518 position[1] = apos[1] - ymin;
9519 position[2] = apos[2] - zmin;
9520 ifloat = position[0]/hx;
9521 jfloat = position[1]/hy;
9522 kfloat = position[2]/hzed;
9523 ip1 = (int)ceil(ifloat);
9525 im1 = (int)floor(ifloat);
9527 jp1 = (int)ceil(jfloat);
9529 jm1 = (int)floor(jfloat);
9531 kp1 = (int)ceil(kfloat);
9533 km1 = (int)floor(kfloat);
9538 ip2 = VMIN2(ip2,nx-1);
9539 ip1 = VMIN2(ip1,nx-1);
9542 jp2 = VMIN2(jp2,ny-1);
9543 jp1 = VMIN2(jp1,ny-1);
9546 kp2 = VMIN2(kp2,nz-1);
9547 kp1 = VMIN2(kp1,nz-1);
9551 for (ii=im2; ii<=ip2; ii++) {
9556 for (jj=jm2; jj<=jp2; jj++) {
9561 for (kk=km2; kk<=kp2; kk++) {
9566 f = u[IJK(ii,jj,kk)];
9567 fnl = unl[IJK(ii,jj,kk)];
9571 de[0][0] += f*d2mx*my*mz/(hx*hx);
9572 de[1][0] += f*dmx*dmy*mz/(hy*hx);
9573 de[1][1] += f*mx*d2my*mz/(hy*hy);
9574 de[2][0] += f*dmx*my*dmz/(hx*hzed);
9575 de[2][1] += f*mx*dmy*dmz/(hy*hzed);
9576 de[2][2] += f*mx*my*d2mz/(hzed*hzed);
9580 denl[0][0] += fnl*d2mx*my*mz/(hx*hx);
9581 denl[1][0] += fnl*dmx*dmy*mz/(hy*hx);
9582 denl[1][1] += fnl*mx*d2my*mz/(hy*hy);
9583 denl[2][0] += fnl*dmx*my*dmz/(hx*hzed);
9584 denl[2][1] += fnl*mx*dmy*dmz/(hy*hzed);
9585 denl[2][2] += fnl*mx*my*d2mz/(hzed*hzed);
9592 force[0] = -(de[0][0]*uixnl + de[1][0]*uiynl + de[2][0]*uiznl);
9593 force[1] = -(de[1][0]*uixnl + de[1][1]*uiynl + de[2][1]*uiznl);
9594 force[2] = -(de[2][0]*uixnl + de[2][1]*uiynl + de[2][2]*uiznl);
9595 force[0] -= denl[0][0]*uix + denl[1][0]*uiy + denl[2][0]*uiz;
9596 force[1] -= denl[1][0]*uix + denl[1][1]*uiy + denl[2][1]*uiz;
9597 force[2] -= denl[2][0]*uix + denl[2][1]*uiy + denl[2][2]*uiz;
9599 force[0] = 0.5 * force[0];
9600 force[1] = 0.5 * force[1];
9601 force[2] = 0.5 * force[2];
9606 int atomID,
double force[3]) {
9614 double *apos, position[3], arad, irad, zkappa2, hx, hy, hzed;
9615 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2;
9616 double rtot, dx, dx2, dy, dy2, dz, dz2, gpos[3], tgrad[3], fmag;
9618 int i, j, k, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9620 VASSERT(thee != VNULL);
9621 VASSERT(induced != VNULL);
9622 VASSERT(nlinduced != VNULL);
9626 VASSERT (atom->
partID != 0);
9639 if (atom->
partID == 0)
return;
9657 hzed = induced->
hzed;
9658 xmin = induced->
xmin;
9659 ymin = induced->
ymin;
9660 zmin = induced->
zmin;
9661 xmax = induced->
xmax;
9662 ymax = induced->
ymax;
9663 zmax = induced->
zmax;
9669 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9670 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9671 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9672 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]);
9673 Vnm_print(2,
"Vpmg_ibMutalPolForce: xmin = %g, xmax = %g\n", xmin, xmax);
9674 Vnm_print(2,
"Vpmg_ibMutalPolForce: ymin = %g, ymax = %g\n", ymin, ymax);
9675 Vnm_print(2,
"Vpmg_ibMutalPolForce: zmin = %g, zmax = %g\n", zmin, zmax);
9680 position[0] = apos[0] - xmin;
9681 position[1] = apos[1] - ymin;
9682 position[2] = apos[2] - zmin;
9688 imin = VMAX2(0,(
int)ceil((position[0] - dx)/hx));
9689 imax = VMIN2(nx-1,(
int)floor((position[0] + dx)/hx));
9690 for (i=imin; i<=imax; i++) {
9691 dx2 = VSQR(position[0] - hx*i);
9692 if (rtot2 > dx2) dy = VSQRT(rtot2 - dx2) + 0.5*hy;
9694 jmin = VMAX2(0,(
int)ceil((position[1] - dy)/hy));
9695 jmax = VMIN2(ny-1,(
int)floor((position[1] + dy)/hy));
9696 for (j=jmin; j<=jmax; j++) {
9697 dy2 = VSQR(position[1] - hy*j);
9698 if (rtot2 > (dx2+dy2)) dz = VSQRT(rtot2-dx2-dy2)+0.5*hzed;
9700 kmin = VMAX2(0,(
int)ceil((position[2] - dz)/hzed));
9701 kmax = VMIN2(nz-1,(
int)floor((position[2] + dz)/hzed));
9702 for (k=kmin; k<=kmax; k++) {
9703 dz2 = VSQR(k*hzed - position[2]);
9706 if ((dz2 + dy2 + dx2) <= rtot2) {
9707 gpos[0] = i*hx + xmin;
9708 gpos[1] = j*hy + ymin;
9709 gpos[2] = k*hzed + zmin;
9712 fmag = induced->
data[IJK(i,j,k)];
9713 fmag *= nlinduced->
data[IJK(i,j,k)];
9714 fmag *= thee->
kappa[IJK(i,j,k)];
9715 force[0] += (zkappa2*fmag*tgrad[0]);
9716 force[1] += (zkappa2*fmag*tgrad[1]);
9717 force[2] += (zkappa2*fmag*tgrad[2]);
9724 force[0] = force[0] * 0.5 * hx * hy * hzed * izmagic;
9725 force[1] = force[1] * 0.5 * hx * hy * hzed * izmagic;
9726 force[2] = force[2] * 0.5 * hx * hy * hzed * izmagic;
9730 Vgrid *nlinduced,
int atomID,
9738 double *apos, position[3], arad, hx, hy, hzed, izmagic, deps, depsi;
9739 double xlen, ylen, zlen, xmin, ymin, zmin, xmax, ymax, zmax, rtot2, epsp;
9740 double rtot, dx, gpos[3], tgrad[3], dbFmag, epsw, kT;
9741 double *u, *unl, Hxijk, Hyijk, Hzijk, Hxim1jk, Hyijm1k, Hzijkm1;
9742 double dHxijk[3], dHyijk[3], dHzijk[3], dHxim1jk[3], dHyijm1k[3];
9744 int i, j, k, l, nx, ny, nz, imin, imax, jmin, jmax, kmin, kmax;
9746 VASSERT(thee != VNULL);
9747 VASSERT(induced != VNULL);
9748 VASSERT(nlinduced != VNULL);
9753 VASSERT (atom->
partID != 0);
9770 deps = (epsw - epsp);
9791 unl = nlinduced->
data;
9794 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
9795 (apos[1]<=ymin) || (apos[1]>=ymax) || \
9796 (apos[2]<=zmin) || (apos[2]>=zmax)) {
9797 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]);
9798 Vnm_print(2,
"Vpmg_dbMutualPolForce: xmin = %g, xmax = %g\n", xmin, xmax);
9799 Vnm_print(2,
"Vpmg_dbMutualPolForce: ymin = %g, ymax = %g\n", ymin, ymax);
9800 Vnm_print(2,
"Vpmg_dbMutualPolForce: zmin = %g, zmax = %g\n", zmin, zmax);
9805 position[0] = apos[0] - xmin;
9806 position[1] = apos[1] - ymin;
9807 position[2] = apos[2] - zmin;
9813 imin = (int)floor((position[0]-rtot)/hx);
9815 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9818 imax = (int)ceil((position[0]+rtot)/hx);
9819 if (imax > (nx-2)) {
9820 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9823 jmin = (int)floor((position[1]-rtot)/hy);
9825 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9828 jmax = (int)ceil((position[1]+rtot)/hy);
9829 if (jmax > (ny-2)) {
9830 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9833 kmin = (int)floor((position[2]-rtot)/hzed);
9835 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9838 kmax = (int)ceil((position[2]+rtot)/hzed);
9839 if (kmax > (nz-2)) {
9840 Vnm_print(2,
"Vpmg_dbMutualPolForce: Atom %d off grid!\n", atomID);
9843 for (i=imin; i<=imax; i++) {
9844 for (j=jmin; j<=jmax; j++) {
9845 for (k=kmin; k<=kmax; k++) {
9847 gpos[0] = (i+0.5)*hx + xmin;
9848 gpos[1] = j*hy + ymin;
9849 gpos[2] = k*hzed + zmin;
9850 Hxijk = (thee->
epsx[IJK(i,j,k)] - epsp)*depsi;
9853 for (l=0; l<3; l++) dHxijk[l] *= Hxijk;
9854 gpos[0] = i*hx + xmin;
9855 gpos[1] = (j+0.5)*hy + ymin;
9856 gpos[2] = k*hzed + zmin;
9857 Hyijk = (thee->
epsy[IJK(i,j,k)] - epsp)*depsi;
9860 for (l=0; l<3; l++) dHyijk[l] *= Hyijk;
9861 gpos[0] = i*hx + xmin;
9862 gpos[1] = j*hy + ymin;
9863 gpos[2] = (k+0.5)*hzed + zmin;
9864 Hzijk = (thee->
epsz[IJK(i,j,k)] - epsp)*depsi;
9867 for (l=0; l<3; l++) dHzijk[l] *= Hzijk;
9869 gpos[0] = (i-0.5)*hx + xmin;
9870 gpos[1] = j*hy + ymin;
9871 gpos[2] = k*hzed + zmin;
9872 Hxim1jk = (thee->
epsx[IJK(i-1,j,k)] - epsp)*depsi;
9875 for (l=0; l<3; l++) dHxim1jk[l] *= Hxim1jk;
9877 gpos[0] = i*hx + xmin;
9878 gpos[1] = (j-0.5)*hy + ymin;
9879 gpos[2] = k*hzed + zmin;
9880 Hyijm1k = (thee->
epsy[IJK(i,j-1,k)] - epsp)*depsi;
9883 for (l=0; l<3; l++) dHyijm1k[l] *= Hyijm1k;
9885 gpos[0] = i*hx + xmin;
9886 gpos[1] = j*hy + ymin;
9887 gpos[2] = (k-0.5)*hzed + zmin;
9888 Hzijkm1 = (thee->
epsz[IJK(i,j,k-1)] - epsp)*depsi;
9891 for (l=0; l<3; l++) dHzijkm1[l] *= Hzijkm1;
9892 dbFmag = unl[IJK(i,j,k)];
9894 (dHxijk[0] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9895 + dHxim1jk[0]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9896 + (dHyijk[0] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9897 + dHyijm1k[0]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9898 + (dHzijk[0] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9899 + dHzijkm1[0]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9901 (dHxijk[1] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9902 + dHxim1jk[1]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9903 + (dHyijk[1] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9904 + dHyijm1k[1]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9905 + (dHzijk[1] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9906 + dHzijkm1[1]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9908 (dHxijk[2] *(u[IJK(i+1,j,k)]-u[IJK(i,j,k)])
9909 + dHxim1jk[2]*(u[IJK(i-1,j,k)]-u[IJK(i,j,k)]))/VSQR(hx)
9910 + (dHyijk[2] *(u[IJK(i,j+1,k)]-u[IJK(i,j,k)])
9911 + dHyijm1k[2]*(u[IJK(i,j-1,k)]-u[IJK(i,j,k)]))/VSQR(hy)
9912 + (dHzijk[2] *(u[IJK(i,j,k+1)]-u[IJK(i,j,k)])
9913 + dHzijkm1[2]*(u[IJK(i,j,k-1)]-u[IJK(i,j,k)]))/VSQR(hzed);
9914 force[0] += (dbFmag*tgrad[0]);
9915 force[1] += (dbFmag*tgrad[1]);
9916 force[2] += (dbFmag*tgrad[2]);
9921 force[0] = -force[0]*hx*hy*hzed*deps*0.5*izmagic;
9922 force[1] = -force[1]*hx*hy*hzed*deps*0.5*izmagic;
9923 force[2] = -force[2]*hx*hy*hzed*deps*0.5*izmagic;
9934 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr, dist2;
9935 double xlen, ylen, zlen, position[3], itot, stot, ictot, ictot2, sctot;
9936 double irad, dx, dy, dz, epsw, epsp, w2i;
9937 double hx, hy, hzed, *apos, arad, sctot2;
9938 double dx2, dy2, dz2, stot2, itot2, rtot, rtot2, splineWin;
9939 double dist, value, denom, sm, sm2, sm3, sm4, sm5, sm6, sm7;
9940 double e, e2, e3, e4, e5, e6, e7;
9941 double b, b2, b3, b4, b5, b6, b7;
9942 double c0, c1, c2, c3, c4, c5, c6, c7;
9943 double ic0, ic1, ic2, ic3, ic4, ic5, ic6, ic7;
9944 int i, j, k, nx, ny, nz, iatom;
9945 int imin, imax, jmin, jmax, kmin, kmax;
9947 VASSERT(thee != VNULL);
9987 for (i=0; i<(nx*ny*nz); i++) {
9988 thee->
kappa[i] = 1.0;
9989 thee->
epsx[i] = 1.0;
9990 thee->
epsy[i] = 1.0;
9991 thee->
epsz[i] = 1.0;
10001 b = arad - splineWin;
10002 e = arad + splineWin;
10015 denom = e7 - 7.0*b*e6 + 21.0*b2*e5 - 35.0*e4*b3
10016 + 35.0*e3*b4 - 21.0*b5*e2 + 7.0*e*b6 - b7;
10017 c0 = b4*(35.0*e3 - 21.0*b*e2 + 7*e*b2 - b3)/denom;
10018 c1 = -140.0*b3*e3/denom;
10019 c2 = 210.0*e2*b2*(e + b)/denom;
10020 c3 = -140.0*e*b*(e2 + 3.0*b*e + b2)/denom;
10021 c4 = 35.0*(e3 + 9.0*b*e2 + + 9.0*e*b2 + b3)/denom;
10022 c5 = -84.0*(e2 + 3.0*b*e + b2)/denom;
10023 c6 = 70.0*(e + b)/denom;
10026 b = irad + arad - splineWin;
10027 e = irad + arad + splineWin;
10040 denom = e7 - 7.0*b*e6 + 21.0*b2*e5 - 35.0*e4*b3
10041 + 35.0*e3*b4 - 21.0*b5*e2 + 7.0*e*b6 - b7;
10042 ic0 = b4*(35.0*e3 - 21.0*b*e2 + 7*e*b2 - b3)/denom;
10043 ic1 = -140.0*b3*e3/denom;
10044 ic2 = 210.0*e2*b2*(e + b)/denom;
10045 ic3 = -140.0*e*b*(e2 + 3.0*b*e + b2)/denom;
10046 ic4 = 35.0*(e3 + 9.0*b*e2 + + 9.0*e*b2 + b3)/denom;
10047 ic5 = -84.0*(e2 + 3.0*b*e + b2)/denom;
10048 ic6 = 70.0*(e + b)/denom;
10052 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
10053 (apos[1]<=ymin) || (apos[1]>=ymax) || \
10054 (apos[2]<=zmin) || (apos[2]>=zmax)) {
10057 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\ 10058 %4.3f) is off the mesh (ignoring):\n",
10059 iatom, apos[0], apos[1], apos[2]);
10060 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
10062 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
10064 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
10072 position[0] = apos[0] - xmin;
10073 position[1] = apos[1] - ymin;
10074 position[2] = apos[2] - zmin;
10078 itot = irad + arad + splineWin;
10079 itot2 = VSQR(itot);
10080 ictot = VMAX2(0, (irad + arad - splineWin));
10081 ictot2 = VSQR(ictot);
10082 stot = arad + splineWin;
10083 stot2 = VSQR(stot);
10084 sctot = VMAX2(0, (arad - splineWin));
10085 sctot2 = VSQR(sctot);
10089 rtot = VMAX2(itot, stot);
10090 rtot2 = VMAX2(itot2, stot2);
10091 dx = rtot + 0.5*hx;
10092 dy = rtot + 0.5*hy;
10093 dz = rtot + 0.5*hzed;
10094 imin = VMAX2(0,(
int)floor((position[0] - dx)/hx));
10095 imax = VMIN2(nx-1,(
int)ceil((position[0] + dx)/hx));
10096 jmin = VMAX2(0,(
int)floor((position[1] - dy)/hy));
10097 jmax = VMIN2(ny-1,(
int)ceil((position[1] + dy)/hy));
10098 kmin = VMAX2(0,(
int)floor((position[2] - dz)/hzed));
10099 kmax = VMIN2(nz-1,(
int)ceil((position[2] + dz)/hzed));
10100 for (i=imin; i<=imax; i++) {
10101 dx2 = VSQR(position[0] - hx*i);
10102 for (j=jmin; j<=jmax; j++) {
10103 dy2 = VSQR(position[1] - hy*j);
10104 for (k=kmin; k<=kmax; k++) {
10105 dz2 = VSQR(position[2] - k*hzed);
10109 dist2 = dz2 + dy2 + dx2;
10110 if (dist2 >= itot2) {
10113 if (dist2 <= ictot2) {
10114 thee->
kappa[IJK(i,j,k)] = 0.0;
10116 if ((dist2 < itot2) && (dist2 > ictot2)) {
10117 dist = VSQRT(dist2);
10125 value = ic0 + ic1*sm + ic2*sm2 + ic3*sm3
10126 + ic4*sm4 + ic5*sm5 + ic6*sm6 + ic7*sm7;
10129 }
else if (value < 0.0){
10132 thee->
kappa[IJK(i,j,k)] *= value;
10138 dist2 = dz2+dy2+VSQR(position[0]-(i+0.5)*hx);
10139 if (dist2 >= stot2) {
10140 thee->
epsx[IJK(i,j,k)] *= 1.0;
10142 if (dist2 <= sctot2) {
10143 thee->
epsx[IJK(i,j,k)] = 0.0;
10145 if ((dist2 > sctot2) && (dist2 < stot2)) {
10146 dist = VSQRT(dist2);
10154 value = c0 + c1*sm + c2*sm2 + c3*sm3
10155 + c4*sm4 + c5*sm5 + c6*sm6 + c7*sm7;
10158 }
else if (value < 0.0){
10161 thee->
epsx[IJK(i,j,k)] *= value;
10167 dist2 = dz2+dx2+VSQR(position[1]-(j+0.5)*hy);
10168 if (dist2 >= stot2) {
10169 thee->
epsy[IJK(i,j,k)] *= 1.0;
10171 if (dist2 <= sctot2) {
10172 thee->
epsy[IJK(i,j,k)] = 0.0;
10174 if ((dist2 > sctot2) && (dist2 < stot2)) {
10175 dist = VSQRT(dist2);
10183 value = c0 + c1*sm + c2*sm2 + c3*sm3
10184 + c4*sm4 + c5*sm5 + c6*sm6 + c7*sm7;
10187 }
else if (value < 0.0){
10190 thee->
epsy[IJK(i,j,k)] *= value;
10196 dist2 = dy2+dx2+VSQR(position[2]-(k+0.5)*hzed);
10197 if (dist2 >= stot2) {
10198 thee->
epsz[IJK(i,j,k)] *= 1.0;
10200 if (dist2 <= sctot2) {
10201 thee->
epsz[IJK(i,j,k)] = 0.0;
10203 if ((dist2 > sctot2) && (dist2 < stot2)) {
10204 dist = VSQRT(dist2);
10212 value = c0 + c1*sm + c2*sm2 + c3*sm3
10213 + c4*sm4 + c5*sm5 + c6*sm6 + c7*sm7;
10216 }
else if (value < 0.0){
10219 thee->
epsz[IJK(i,j,k)] *= value;
10230 Vnm_print(0,
"Vpmg_fillco: filling coefficient arrays\n");
10232 for (k=0; k<nz; k++) {
10233 for (j=0; j<ny; j++) {
10234 for (i=0; i<nx; i++) {
10236 thee->
kappa[IJK(i,j,k)] = ionmask*thee->
kappa[IJK(i,j,k)];
10237 thee->
epsx[IJK(i,j,k)] = (epsw-epsp)*thee->
epsx[IJK(i,j,k)]
10239 thee->
epsy[IJK(i,j,k)] = (epsw-epsp)*thee->
epsy[IJK(i,j,k)]
10241 thee->
epsz[IJK(i,j,k)] = (epsw-epsp)*thee->
epsz[IJK(i,j,k)]
10250 VPUBLIC
void fillcoPermanentInduced(
Vpmg *thee) {
10258 double xmin, xmax, ymin, ymax, zmin, zmax;
10259 double xlen, ylen, zlen, position[3], ifloat, jfloat, kfloat;
10260 double hx, hy, hzed, *apos;
10262 double charge, *dipole,*quad;
10263 double c,ux,uy,uz,qxx,qyx,qyy,qzx,qzy,qzz,qave;
10265 double mx,my,mz,dmx,dmy,dmz,d2mx,d2my,d2mz;
10268 int i, ii, jj, kk, nx, ny, nz, iatom;
10269 int im2, im1, ip1, ip2, jm2, jm1, jp1, jp2, km2, km1, kp1, kp2;
10271 VASSERT(thee != VNULL);
10275 alist = pbe->
alist;
10287 f = zmagic/(hx*hy*hzed);
10304 Vnm_print(0,
"fillcoPermanentInduced: filling in source term.\n");
10312 #if defined(WITH_TINKER) 10313 dipole = Vatom_getDipole(atom);
10314 ux = dipole[0]/hx*f;
10315 uy = dipole[1]/hy*f;
10316 uz = dipole[2]/hzed*f;
10317 dipole = Vatom_getInducedDipole(atom);
10318 ux = ux + dipole[0]/hx*f;
10319 uy = uy + dipole[1]/hy*f;
10320 uz = uz + dipole[2]/hzed*f;
10321 quad = Vatom_getQuadrupole(atom);
10322 qxx = (1.0/3.0)*quad[0]/(hx*hx)*f;
10323 qyx = (2.0/3.0)*quad[3]/(hx*hy)*f;
10324 qyy = (1.0/3.0)*quad[4]/(hy*hy)*f;
10325 qzx = (2.0/3.0)*quad[6]/(hzed*hx)*f;
10326 qzy = (2.0/3.0)*quad[7]/(hzed*hy)*f;
10327 qzz = (1.0/3.0)*quad[8]/(hzed*hzed)*f;
10341 if ((apos[0]<=(xmin-2*hx)) || (apos[0]>=(xmax+2*hx)) || \
10342 (apos[1]<=(ymin-2*hy)) || (apos[1]>=(ymax+2*hy)) || \
10343 (apos[2]<=(zmin-2*hzed)) || (apos[2]>=(zmax+2*hzed))) {
10344 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]);
10345 Vnm_print(2,
"fillcoPermanentMultipole: xmin = %g, xmax = %g\n", xmin, xmax);
10346 Vnm_print(2,
"fillcoPermanentMultipole: ymin = %g, ymax = %g\n", ymin, ymax);
10347 Vnm_print(2,
"fillcoPermanentMultipole: zmin = %g, zmax = %g\n", zmin, zmax);
10352 position[0] = apos[0] - xmin;
10353 position[1] = apos[1] - ymin;
10354 position[2] = apos[2] - zmin;
10357 ifloat = position[0]/hx;
10358 jfloat = position[1]/hy;
10359 kfloat = position[2]/hzed;
10361 ip1 = (int)ceil(ifloat);
10363 im1 = (int)floor(ifloat);
10365 jp1 = (int)ceil(jfloat);
10367 jm1 = (int)floor(jfloat);
10369 kp1 = (int)ceil(kfloat);
10371 km1 = (int)floor(kfloat);
10376 ip2 = VMIN2(ip2,nx-1);
10377 ip1 = VMIN2(ip1,nx-1);
10378 im1 = VMAX2(im1,0);
10379 im2 = VMAX2(im2,0);
10380 jp2 = VMIN2(jp2,ny-1);
10381 jp1 = VMIN2(jp1,ny-1);
10382 jm1 = VMAX2(jm1,0);
10383 jm2 = VMAX2(jm2,0);
10384 kp2 = VMIN2(kp2,nz-1);
10385 kp1 = VMIN2(kp1,nz-1);
10386 km1 = VMAX2(km1,0);
10387 km2 = VMAX2(km2,0);
10390 for (ii=im2; ii<=ip2; ii++) {
10395 for (jj=jm2; jj<=jp2; jj++) {
10400 for (kk=km2; kk<=kp2; kk++) {
10405 charge = mx*my*mz*c -
10406 dmx*my*mz*ux - mx*dmy*mz*uy - mx*my*dmz*uz +
10408 dmx*dmy*mz*qyx + mx*d2my*mz*qyy +
10409 dmx*my*dmz*qzx + mx*dmy*dmz*qzy + mx*my*d2mz*qzz;
10410 thee->
charge[IJK(ii,jj,kk)] += charge;
10425 double xmin, xmax, ymin, ymax, zmin, zmax, ionmask, ionstr, dist2;
10426 double xlen, ylen, zlen, position[3], itot, stot, ictot, ictot2, sctot;
10427 double irad, dx, dy, dz, epsw, epsp, w2i;
10428 double hx, hy, hzed, *apos, arad, sctot2;
10429 double dx2, dy2, dz2, stot2, itot2, rtot, rtot2, splineWin;
10430 double dist, value, denom, sm, sm2, sm3, sm4, sm5;
10431 double e, e2, e3, e4, e5;
10432 double b, b2, b3, b4, b5;
10433 double c0, c1, c2, c3, c4, c5;
10434 double ic0, ic1, ic2, ic3, ic4, ic5;
10435 int i, j, k, nx, ny, nz, iatom;
10436 int imin, imax, jmin, jmax, kmin, kmax;
10438 VASSERT(thee != VNULL);
10443 alist = pbe->
alist;
10475 else ionmask = 0.0;
10478 for (i=0; i<(nx*ny*nz); i++) {
10479 thee->
kappa[i] = 1.0;
10480 thee->
epsx[i] = 1.0;
10481 thee->
epsy[i] = 1.0;
10482 thee->
epsz[i] = 1.0;
10492 b = arad - splineWin;
10493 e = arad + splineWin;
10502 denom = pow((e - b), 5.0);
10503 c0 = -10.0*e2*b3 + 5.0*e*b4 - b5;
10505 c2 = -30.0*(e2*b + e*b2);
10506 c3 = 10.0*(e2 + 4.0*e*b + b2);
10507 c4 = -15.0*(e + b);
10516 b = irad + arad - splineWin;
10517 e = irad + arad + splineWin;
10526 denom = pow((e - b), 5.0);
10527 ic0 = -10.0*e2*b3 + 5.0*e*b4 - b5;
10529 ic2 = -30.0*(e2*b + e*b2);
10530 ic3 = 10.0*(e2 + 4.0*e*b + b2);
10531 ic4 = -15.0*(e + b);
10541 if ((apos[0]<=xmin) || (apos[0]>=xmax) || \
10542 (apos[1]<=ymin) || (apos[1]>=ymax) || \
10543 (apos[2]<=zmin) || (apos[2]>=zmax)) {
10546 Vnm_print(2,
"Vpmg_fillco: Atom #%d at (%4.3f, %4.3f,\ 10547 %4.3f) is off the mesh (ignoring):\n",
10548 iatom, apos[0], apos[1], apos[2]);
10549 Vnm_print(2,
"Vpmg_fillco: xmin = %g, xmax = %g\n",
10551 Vnm_print(2,
"Vpmg_fillco: ymin = %g, ymax = %g\n",
10553 Vnm_print(2,
"Vpmg_fillco: zmin = %g, zmax = %g\n",
10561 position[0] = apos[0] - xmin;
10562 position[1] = apos[1] - ymin;
10563 position[2] = apos[2] - zmin;
10567 itot = irad + arad + splineWin;
10568 itot2 = VSQR(itot);
10569 ictot = VMAX2(0, (irad + arad - splineWin));
10570 ictot2 = VSQR(ictot);
10571 stot = arad + splineWin;
10572 stot2 = VSQR(stot);
10573 sctot = VMAX2(0, (arad - splineWin));
10574 sctot2 = VSQR(sctot);
10578 rtot = VMAX2(itot, stot);
10579 rtot2 = VMAX2(itot2, stot2);
10580 dx = rtot + 0.5*hx;
10581 dy = rtot + 0.5*hy;
10582 dz = rtot + 0.5*hzed;
10583 imin = VMAX2(0,(
int)floor((position[0] - dx)/hx));
10584 imax = VMIN2(nx-1,(
int)ceil((position[0] + dx)/hx));
10585 jmin = VMAX2(0,(
int)floor((position[1] - dy)/hy));
10586 jmax = VMIN2(ny-1,(
int)ceil((position[1] + dy)/hy));
10587 kmin = VMAX2(0,(
int)floor((position[2] - dz)/hzed));
10588 kmax = VMIN2(nz-1,(
int)ceil((position[2] + dz)/hzed));
10589 for (i=imin; i<=imax; i++) {
10590 dx2 = VSQR(position[0] - hx*i);
10591 for (j=jmin; j<=jmax; j++) {
10592 dy2 = VSQR(position[1] - hy*j);
10593 for (k=kmin; k<=kmax; k++) {
10594 dz2 = VSQR(position[2] - k*hzed);
10598 dist2 = dz2 + dy2 + dx2;
10599 if (dist2 >= itot2) {
10602 if (dist2 <= ictot2) {
10603 thee->
kappa[IJK(i,j,k)] = 0.0;
10605 if ((dist2 < itot2) && (dist2 > ictot2)) {
10606 dist = VSQRT(dist2);
10612 value = ic0 + ic1*sm + ic2*sm2 + ic3*sm3
10613 + ic4*sm4 + ic5*sm5;
10616 }
else if (value < 0.0){
10619 thee->
kappa[IJK(i,j,k)] *= value;
10625 dist2 = dz2+dy2+VSQR(position[0]-(i+0.5)*hx);
10626 if (dist2 >= stot2) {
10627 thee->
epsx[IJK(i,j,k)] *= 1.0;
10629 if (dist2 <= sctot2) {
10630 thee->
epsx[IJK(i,j,k)] = 0.0;
10632 if ((dist2 > sctot2) && (dist2 < stot2)) {
10633 dist = VSQRT(dist2);
10639 value = c0 + c1*sm + c2*sm2 + c3*sm3
10643 }
else if (value < 0.0){
10646 thee->
epsx[IJK(i,j,k)] *= value;
10652 dist2 = dz2+dx2+VSQR(position[1]-(j+0.5)*hy);
10653 if (dist2 >= stot2) {
10654 thee->
epsy[IJK(i,j,k)] *= 1.0;
10656 if (dist2 <= sctot2) {
10657 thee->
epsy[IJK(i,j,k)] = 0.0;
10659 if ((dist2 > sctot2) && (dist2 < stot2)) {
10660 dist = VSQRT(dist2);
10666 value = c0 + c1*sm + c2*sm2 + c3*sm3
10670 }
else if (value < 0.0){
10673 thee->
epsy[IJK(i,j,k)] *= value;
10679 dist2 = dy2+dx2+VSQR(position[2]-(k+0.5)*hzed);
10680 if (dist2 >= stot2) {
10681 thee->
epsz[IJK(i,j,k)] *= 1.0;
10683 if (dist2 <= sctot2) {
10684 thee->
epsz[IJK(i,j,k)] = 0.0;
10686 if ((dist2 > sctot2) && (dist2 < stot2)) {
10687 dist = VSQRT(dist2);
10693 value = c0 + c1*sm + c2*sm2 + c3*sm3
10697 }
else if (value < 0.0){
10700 thee->
epsz[IJK(i,j,k)] *= value;
10711 Vnm_print(0,
"Vpmg_fillco: filling coefficient arrays\n");
10713 for (k=0; k<nz; k++) {
10714 for (j=0; j<ny; j++) {
10715 for (i=0; i<nx; i++) {
10717 thee->
kappa[IJK(i,j,k)] = ionmask*thee->
kappa[IJK(i,j,k)];
10718 thee->
epsx[IJK(i,j,k)] = (epsw-epsp)*thee->
epsx[IJK(i,j,k)]
10720 thee->
epsy[IJK(i,j,k)] = (epsw-epsp)*thee->
epsy[IJK(i,j,k)]
10722 thee->
epsz[IJK(i,j,k)] = (epsw-epsp)*thee->
epsz[IJK(i,j,k)]
10731 VPRIVATE
void bcolcomp(
int *iparm,
double *rparm,
int *iwork,
double *rwork,
10732 double *values,
int *rowind,
int *colptr,
int *flag) {
10733 int nrow, ncol, nnzero, i;
10734 int nxc, nyc, nzc, nf, nc, narr, narrc, n_rpc;
10735 int n_iz, n_ipc, iretot, iintot;
10736 int nrwk, niwk, nx, ny, nz, nlev, ierror, maxlev, mxlv;
10737 int mgcoar, mgdisc, mgsolv;
10739 int k_ipc, k_rpc, k_ac, k_cc, k_fc, k_pc;
10744 nrwk = VAT(iparm, 1);
10745 niwk = VAT(iparm, 2);
10746 nx = VAT(iparm, 3);
10747 ny = VAT(iparm, 4);
10748 nz = VAT(iparm, 5);
10749 nlev = VAT(iparm, 6);
10752 mxlv = Vmaxlev(nx, ny, nz);
10755 mgcoar = VAT(iparm, 18);
10756 mgdisc = VAT(iparm, 19);
10757 mgsolv = VAT(iparm, 21);
10758 Vmgsz(&mgcoar, &mgdisc, &mgsolv,
10764 &n_rpc, &n_iz, &n_ipc,
10769 k_ipc = k_iz + n_iz;
10773 k_cc = k_rpc + n_rpc;
10774 k_fc = k_cc + narr;
10775 k_pc = k_fc + narr;
10776 k_ac = k_pc + 27*narrc;
10779 &nx, &ny, &nz, RAT(iwork, k_iz),
10780 RAT(iwork, k_ipc), RAT(rwork, k_rpc),
10781 RAT(rwork, k_ac), RAT(rwork, k_cc),
10782 values, rowind, colptr, flag);
10786 int *nx,
int *ny,
int *nz,
10787 int *iz,
int *ipc,
double *rpc,
10788 double *ac,
double *cc,
double *values,
10789 int *rowind,
int *colptr,
int *flag) {
10792 int lev = VAT(iparm, 6);
10794 MAT2(iz, 50, nlev);
10807 RAT(ipc, VAT2(iz, 5, lev)), RAT(rpc, VAT2(iz, 6, lev)),
10808 RAT(ac, VAT2(iz, 7, lev)), RAT(cc, VAT2(iz, 1, lev)),
10809 values, rowind, colptr, flag);
10822 int *ipc,
double *rpc,
10823 double *ac,
double *cc,
10824 double *values,
int *rowind,
int *colptr,
int *flag) {
10826 MAT2(ac, *nx * *ny * *nz, 1);
10832 RAT2(ac, 1, 1), cc,
10833 RAT2(ac, 1, 2), RAT2(ac, 1, 3), RAT2(ac, 1, 4),
10834 values, rowind, colptr, flag);
10849 int *ipc,
double *rpc,
10850 double *oC,
double *cc,
double *oE,
double *oN,
double *uC,
10851 double *values,
int *rowind,
int *colptr,
int *flag) {
10853 int nxm2, nym2, nzm2;
10854 int ii, jj, kk, ll;
10856 int inonz, iirow, nn, nrow, ncol, nonz, irow, n;
10860 MAT3(oE, *nx, *ny, *nz);
10861 MAT3(oN, *nx, *ny, *nz);
10862 MAT3(uC, *nx, *ny, *nz);
10863 MAT3(cc, *nx, *ny, *nz);
10864 MAT3(oC, *nx, *ny, *nz);
10869 n = *nx * *ny * *nz;
10873 nn = nxm2 * nym2 * nzm2;
10876 nonz = 7 * nn - 2 * nxm2 * nym2 - 2 * nxm2 - 2;
10885 for (k=2; k<=*nz-1; k++) {
10889 for (j=2; j<=*ny-1; j++) {
10893 for (i=2; i<=*nx-1; i++) {
10898 ll = (kk - 1) * nxm2 * nym2 + (jj - 1) * nxm2 + (ii - 1) + 1;
10899 l = (k - 1) * *nx * *ny + (j - 1) * *nx + (i - 1) + 1;
10902 VAT(colptr,ll) = inonz;
10905 iirow = ll - nxm2 * nym2;
10906 irow = l - *nx * *ny;
10908 doit = (iirow >= 1) && (iirow <= nn);
10909 doit = doit && (irow >= 1) && (irow <= n);
10912 VAT(values, inonz) = -VAT3(uC, i, j, k-1);
10913 VAT(rowind, inonz) = iirow;
10923 doit = (iirow >= 1) && (iirow <= nn);
10924 doit = doit && (irow >= 1) && (irow <= n);
10927 VAT(values, inonz) = -VAT3(oN, i, j-1, k);
10928 VAT(rowind, inonz) = iirow;
10938 doit = (iirow >= 1) && (iirow <= nn);
10939 doit = doit && (irow <= 1) && (irow <= n);
10941 VAT(values, inonz) = -VAT3(oE, i-1, j, k);
10942 VAT(rowind, inonz) = iirow;
10953 VAT(values, inonz) = VAT3(oC, i, j, k);
10954 }
else if (*flag == 1) {
10955 VAT(values, inonz) = VAT3(oC, i, j, k)
10956 + VAT3(cc, i, j, k);
10958 VABORT_MSG0(
"PMGF1");
10961 VAT(rowind, inonz) = iirow;
10967 doit = (iirow >= 1) && (iirow <= nn);
10968 doit = doit && (irow >= 1) && (irow <= n);
10970 VAT(values, inonz) = -VAT3(oE, i, j, k);
10971 VAT(rowind, inonz) = iirow;
10980 doit = (iirow >= 1) && (iirow <= nn);
10981 doit = doit && (irow >= 1) && (irow <= n);
10983 VAT(values, inonz) = -VAT3(oN, i, j, k);
10984 VAT(rowind, inonz) = iirow;
10991 iirow = ll + nxm2 * nym2;
10992 irow = l + *nx * *ny;
10993 doit = (iirow >= 1) && (iirow <= nn);
10994 doit = doit && (irow >= 1) && (irow <= n);
10996 VAT(values, inonz) = -VAT3(uC, i, j, k);
10997 VAT(rowind, inonz) = iirow;
11004 VAT(colptr, ncol + 1) = inonz;
11006 if (inonz != (nonz + 1)) {
11007 VABORT_MSG2(
"BCOLCOMP4: ERROR -- INONZ = %d, NONZ = %d", inonz, nonz);
11014 double *values,
int *rowind,
int *colptr,
11015 char *path,
char *title,
char *mxtype) {
11017 char key[] =
"key";
11018 char ptrfmt[] =
"(10I8)";
11019 char indfmt[] =
"(10I8)";
11020 char valfmt[] =
"(5E15.8)";
11021 char rhsfmt[] =
"(5E15.8)";
11023 int i, totcrd, ptrcrd, indcrd, valcrd, neltvl, rhscrd;
11030 outFile = fopen(path,
"w");
11033 ptrcrd = (int)(*ncol / 10 + 1) - 1;
11034 indcrd = (int)(*nnzero / 10 + 1) - 1;
11035 valcrd = (int)(*nnzero / 10 + 1) - 1;
11036 totcrd = ptrcrd + indcrd + valcrd;
11041 fprintf(outFile,
"%72s%8s\n",
11043 fprintf(outFile,
"%14d%14d%14d%14d%14d\n",
11044 totcrd, ptrcrd, indcrd, valcrd, rhscrd);
11045 fprintf(outFile,
"%3s\n", mxtype);
11046 fprintf(outFile,
" %14d%14d%14d%14d\n",
11047 *nrow, *ncol, *nnzero, neltvl);
11048 fprintf(outFile,
"%16s%16s%20s%20s\n",
11049 ptrfmt, indfmt, valfmt, rhsfmt);
11052 for (i=1; i<=*ncol+1; i++)
11053 fprintf(outFile,
"%8d", VAT(colptr, i));
11054 fprintf(outFile,
"\n");
11056 for (i=1; i<=*nnzero; i++)
11057 fprintf(outFile,
"%8d", VAT(rowind, i));
11058 fprintf(outFile,
"\n");
11062 for (i=1; i<=*nnzero; i++)
11063 fprintf(outFile,
"%15.8e", VAT(values, i));
11064 fprintf(outFile,
"\n");
VPRIVATE void fillcoCoefMolDielSmooth(Vpmg *thee)
Fill differential operator coefficient arrays from a molecular surface calculation with smoothing...
VPRIVATE void fillcoCoefMol(Vpmg *thee)
Fill operator coefficient arrays from a molecular surface calculation.
VPUBLIC double Vpmg_qmEnergy(Vpmg *thee, int extFlag)
Get the "mobile charge" contribution to the electrostatic energy.
#define SINH_MAX
Used to set the max values acceptable for sinh chopping.
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 Vpmg_unsetPart(Vpmg *thee)
Remove partition restrictions.
VPUBLIC double Vpmg_qfEnergy(Vpmg *thee, int extFlag)
Get the "fixed charge" contribution to the electrostatic energy.
VPUBLIC Vacc * Vpbe_getVacc(Vpbe *thee)
Get accessibility oracle.
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.
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.
VPRIVATE void fillcoCoefSpline(Vpmg *thee)
Fill operator coefficient arrays from a spline-based surface calculation.
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...
enum eVsurf_Meth Vsurf_Meth
Declaration of the Vsurf_Meth type as the Vsurf_Meth enum.
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.
VPUBLIC double Vacc_atomSASA(Vacc *thee, double radius, Vatom *atom)
Return the atomic solvent accessible surface area (SASA)
VPUBLIC double d3bspline4(double x)
Evaluate the 3rd derivative of a 5th Order B-Spline.
VPRIVATE void bcCalc(Vpmg *thee)
Fill boundary condition arrays.
Contains public data members for Vpbe class/module.
Oracle for solvent- and ion-accessibility around a biomolecule.
VPUBLIC double Vpbe_getSoluteDiel(Vpbe *thee)
Get solute dielectric constant.
#define VAPBS_DOWN
Face definition for a volume.
VPUBLIC void Vgrid_dtor(Vgrid **thee)
Object destructor.
VPUBLIC double Vpbe_getZkappa2(Vpbe *thee)
Get modified squared Debye-Huckel parameter.
VPRIVATE Vrc_Codes fillcoChargeMap(Vpmg *thee)
Fill source term charge array from a pre-calculated map.
VPUBLIC double dbspline4(double x)
Evaluate a 5th Order B-Spline derivative (4th order polynomial)
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. This force arises due to self-consistent convergence of the solute induced dipoles and reaction field.
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...
Electrostatic potential oracle for Cartesian mesh data.
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...
VPRIVATE void fillcoCoefSpline3(Vpmg *thee)
Fill operator coefficient arrays from a 5th order polynomial based surface calculation.
VEXTERNC double Vacc_ivdwAcc(Vacc *thee, double center[VAPBS_DIM], double radius)
Report inflated van der Waals accessibility.
VPUBLIC double Vpbe_getzmem(Vpbe *thee)
Get z position of the membrane bottom.
VPRIVATE double VFCHI4(int i, double f)
Return 2.5 plus difference of i - f.
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...
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...
Contains public data members for Vpmg class/module.
VPUBLIC int Valist_getNumberAtoms(Valist *thee)
Get number of atoms in the list.
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...
VPRIVATE void fillcoCoefMolIon(Vpmg *thee)
Fill ion (nonlinear) operator coefficient array from a molecular surface calculation.
VPUBLIC double Vpbe_getSoluteRadius(Vpbe *thee)
Get sphere radius which bounds biomolecule.
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...
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.
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 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 double Vpbe_getTemperature(Vpbe *thee)
Get temperature.
#define VAPBS_UP
Face definition for a volume.
VPUBLIC double Vpbe_getBulkIonicStrength(Vpbe *thee)
Get bulk ionic strength.
VPRIVATE void qfForceSpline1(Vpmg *thee, double *force, int atomID)
Charge-field force due to a linear spline charge function.
VPRIVATE Vrc_Codes fillcoCharge(Vpmg *thee)
Top-level driver to fill source term charge array.
VPRIVATE void fillcoCoef(Vpmg *thee)
Top-level driver to fill all operator coefficient arrays.
#define VPMGSMALL
A small number used in Vpmg to decide if points are on/off grid-lines or non-zer0 (etc...
VPUBLIC double Vpbe_getSoluteCharge(Vpbe *thee)
Get total solute charge.
VPUBLIC int Vgrid_curvature(Vgrid *thee, double pt[3], int cflag, double *value)
Get second derivative values at a point.
VPUBLIC int Vpbe_getIons(Vpbe *thee, int *nion, double ionConc[MAXION], double ionRadii[MAXION], double ionQ[MAXION])
Get information about the counterion species present.
VEXTERNC void Vpmg_ibPermanentMultipoleForce(Vpmg *thee, int atomID, double force[3])
Compute the ionic boundary force for permanent multipoles.
VPUBLIC void Vpackmg(int *iparm, double *rparm, int *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 Vcap_exp(double x, int *ichop)
Provide a capped exp() function.
VPUBLIC void fillcoPermanentMultipole(Vpmg *thee)
Fill source term charge array for the use of permanent multipoles.
VPUBLIC double * Vpbe_getSoluteCenter(Vpbe *thee)
Get coordinates of solute center.
VPUBLIC double Vpmg_dielGradNorm(Vpmg *thee)
Get the integral of the gradient of the dielectric function.
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 double Vpbe_getLmem(Vpbe *thee)
Get length of the membrane (A)aauthor Michael Grabe.
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...
VPRIVATE void fillcoCoefMolDiel(Vpmg *thee)
Fill differential operator coefficient arrays from a molecular surface calculation.
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.
VEXTERNC double Vacc_vdwAcc(Vacc *thee, double center[VAPBS_DIM])
Report van der Waals accessibility.
VPUBLIC void Vpmg_dtor(Vpmg **thee)
Object destructor.
VPRIVATE double bspline2(double x)
Evaluate a cubic B-spline.
VPRIVATE double Vpmg_qfEnergyPoint(Vpmg *thee, int extFlag)
Calculates charge-potential energy using summation over delta function positions (i.e. something like an Linf norm)
VPUBLIC double Vpbe_getXkappa(Vpbe *thee)
Get Debye-Huckel parameter.
VPUBLIC void Vpmgp_size(Vpmgp *thee)
Determine array sizes and parameters for multigrid solver.
enum eVhal_PBEType Vhal_PBEType
Declaration of the Vhal_PBEType type as the Vhal_PBEType enum.
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.
VPUBLIC double Vpbe_getSolventRadius(Vpbe *thee)
Get solvent molecule radius.
VPRIVATE double dbspline2(double x)
Evaluate a cubic B-spline derivative.
VPUBLIC double Vpmg_qmEnergySMPBE(Vpmg *thee, int extFlag)
Vpmg_qmEnergy for SMPBE.
VPUBLIC double Vpbe_getmemv(Vpbe *thee)
Get membrane potential (kT)
#define VEMBED(rctag)
Allows embedding of RCS ID tags in object files.
VPRIVATE double Vpmg_qfEnergyVolume(Vpmg *thee, int extFlag)
Calculates charge-potential energy as integral over a volume.
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.
VEXTERNC void Vpmg_dbPermanentMultipoleForce(Vpmg *thee, int atomID, double force[3])
Compute the dielectric boundary force for permanent multipoles.
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 Vatom * Valist_getAtom(Valist *thee, int i)
Get pointer to particular atom in list.
VPUBLIC double d2bspline4(double x)
Evaluate the 2nd derivative of a 5th Order B-Spline.
#define Vunit_Na
Avogadro's number.
VPRIVATE void qfForceSpline4(Vpmg *thee, double *force, int atomID)
Charge-field force due to a quintic spline charge function.
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 fillcoChargeSpline2(Vpmg *thee)
Fill source term charge array from cubic spline interpolation.
VPUBLIC int Vgrid_gradient(Vgrid *thee, double pt[3], double grad[3])
Get first derivative values at a point.
VPUBLIC int Vpmg_solveLaplace(Vpmg *thee)
Solve Poisson's equation with a homogeneous Laplacian operator using the solvent dielectric constant...
VPUBLIC double Vacc_SASA(Vacc *thee, double radius)
Build the solvent accessible surface (SAS) and calculate the solvent accessible surface area...
VPRIVATE void qfForceSpline2(Vpmg *thee, double *force, int atomID)
Charge-field force due to a cubic spline charge function.
VPUBLIC double Vpmg_dielEnergy(Vpmg *thee, int extFlag)
Get the "polarization" contribution to the electrostatic energy.
enum ePBEparm_calcEnergy PBEparm_calcEnergy
Define ePBEparm_calcEnergy enumeration as PBEparm_calcEnergy.
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)
Contains public data members for Vpmgp class/module.
#define Vunit_kb
Boltzmann constant.
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...
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...
VPRIVATE void fillcoCoefSpline4(Vpmg *thee)
Fill operator coefficient arrays from a 7th order polynomial based surface calculation.
VPRIVATE void fillcoCoefMap(Vpmg *thee)
Fill operator coefficient arrays from pre-calculated maps.
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 ...
VPUBLIC VaccSurf * Vacc_atomSASPoints(Vacc *thee, double radius, Vatom *atom)
Get the set of points for this atom's solvent-accessible surface.
#define VAPBS_BACK
Face definition for a volume.
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.
Parameter structure for PBE variables from input files.
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.
#define VAPBS_FRONT
Face definition for a volume.
VPRIVATE void fillcoNLInducedDipole(Vpmg *thee)
Fill source term charge array for non-local induced dipoles.
Surface object list of per-atom surface points.
VPRIVATE double bspline4(double x)
Evaluate a 5th Order B-Spline (4th order polynomial)
Parameter structure for MG-specific variables from input files.
VPUBLIC double Vacc_molAcc(Vacc *thee, double center[VAPBS_DIM], double radius)
Report molecular accessibility.
VPUBLIC double Vpbe_getMaxIonRadius(Vpbe *thee)
Get maximum radius of ion species.
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...
VPUBLIC double * Vatom_getPosition(Vatom *thee)
Get atomic position.
VEXTERNC double Vpmg_qfPermanentMultipoleEnergy(Vpmg *thee, int atomID)
Computes the permanent multipole electrostatic hydration energy (the polarization component of the hy...
VPUBLIC double Vpbe_getZmagic(Vpbe *thee)
Get charge scaling factor.
enum eVdata_Type Vdata_Type
Declaration of the Vdata_Type type as the Vdata_Type enum.
Contains public data members for Vatom class/module.
Container class for list of atom objects.
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...
#define Vunit_eps0
Vacuum permittivity.
#define SINH_MIN
Used to set the min values acceptable for sinh chopping.
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 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 int Vgrid_value(Vgrid *thee, double pt[3], double *value)
Get potential value (from mesh or approximation) at a point.
VPRIVATE void fillcoChargeSpline1(Vpmg *thee)
Fill source term charge array from linear interpolation.
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.
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.
#define MAXION
The maximum number of ion species that can be involved in a single PBE calculation.
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 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...
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 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 double Vpbe_getmembraneDiel(Vpbe *thee)
Get membrane dielectric constant.
VPUBLIC int Vpmg_solve(Vpmg *thee)
Solve the PBE using PMG.
VPUBLIC double Vpmg_energy(Vpmg *thee, int extFlag)
Get the total electrostatic energy.
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.
VPUBLIC double Vatom_getRadius(Vatom *thee)
Get atomic position.
VPRIVATE double Vpmg_polarizEnergy(Vpmg *thee, int extFlag)
Determines energy from polarizeable charge and interaction with fixed charges according to Rocchia et...
Contains declarations for class Vpmg.
VPUBLIC unsigned long int Vpmg_memChk(Vpmg *thee)
Return the memory used by this structure (and its contents) in bytes.
VPRIVATE void fillcoCoefMolDielNoSmooth(Vpmg *thee)
Fill differential operator coefficient arrays from a molecular surface calculation without smoothing...
VPUBLIC double Vatom_getCharge(Vatom *thee)
Get atomic charge.
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...
VPUBLIC double Vacc_splineAcc(Vacc *thee, double center[VAPBS_DIM], double win, double infrad)
Report spline-based accessibility.
enum eVchrg_Meth Vchrg_Meth
Declaration of the Vchrg_Meth type as the Vchrg_Meth enum.
#define Vunit_ec
Charge of an electron in C.
VPRIVATE void fillcoInducedDipole(Vpmg *thee)
Fill source term charge array for use of induced dipoles.
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...
#define VAPBS_LEFT
Face definition for a volume.
#define VAPBS_RIGHT
Face definition for a volume.
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 double Vpbe_getSolventDiel(Vpbe *thee)
Get solvent dielectric constant.