VPUBLIC int Vgreen_coulomb_direct(Vgreen *thee, int npos, double *x, double *y, double *z, double *val) { Vatom *atom; double *apos, charge, dist, dx, dy, dz, scale; double *q, qtemp, fx, fy, fz; int iatom, ipos; if (thee == VNULL) { Vnm_print(2, "Vgreen_coulomb: Got NULL thee!\n"); return 0; } for (ipos=0; ipos<npos; ipos++) val[ipos] = 0.0; for (iatom=0; iatom<Valist_getNumberAtoms(thee->alist); iatom++) { atom = Valist_getAtom(thee->alist, iatom); apos = Vatom_getPosition(atom); charge = Vatom_getCharge(atom); for (ipos=0; ipos<npos; ipos++) { dx = apos[0] - x[ipos]; dy = apos[1] - y[ipos]; dz = apos[2] - z[ipos]; dist = VSQRT(VSQR(dx) + VSQR(dy) + VSQR(dz)); if (dist > VSMALL) val[ipos] += (charge/dist); } } scale = Vunit_ec/(4*Vunit_pi*Vunit_eps0*1.0e-10); for (ipos=0; ipos<npos; ipos++) val[ipos] = val[ipos]*scale; return 1; }
VPUBLIC int Vgreen_coulombD_direct(Vgreen *thee, int npos, double *x, double *y, double *z, double *pot, double *gradx, double *grady, double *gradz) { Vatom *atom; double *apos, charge, dist, dist2, idist3, dy, dz, dx, scale; double *q, qtemp; int iatom, ipos; if (thee == VNULL) { Vnm_print(2, "Vgreen_coulombD: Got VNULL thee!\n"); return 0; } for (ipos=0; ipos<npos; ipos++) { pot[ipos] = 0.0; gradx[ipos] = 0.0; grady[ipos] = 0.0; gradz[ipos] = 0.0; } for (iatom=0; iatom<Valist_getNumberAtoms(thee->alist); iatom++) { atom = Valist_getAtom(thee->alist, iatom); apos = Vatom_getPosition(atom); charge = Vatom_getCharge(atom); for (ipos=0; ipos<npos; ipos++) { dx = apos[0] - x[ipos]; dy = apos[1] - y[ipos]; dz = apos[2] - z[ipos]; dist2 = VSQR(dx) + VSQR(dy) + VSQR(dz); dist = VSQRT(dist2); if (dist > VSMALL) { idist3 = 1.0/(dist*dist2); gradx[ipos] -= (charge*dx*idist3); grady[ipos] -= (charge*dy*idist3); gradz[ipos] -= (charge*dz*idist3); pot[ipos] += (charge/dist); } } } scale = Vunit_ec/(4*VPI*Vunit_eps0*(1.0e-10)); for (ipos=0; ipos<npos; ipos++) { gradx[ipos] = gradx[ipos]*scale; grady[ipos] = grady[ipos]*scale; gradz[ipos] = gradz[ipos]*scale; pot[ipos] = pot[ipos]*scale; } return 1; }
/* * *************************************************************************** * Routine: markSimplex_default * * Purpose: DEFAULT: Simplex marking routine for refinement. * * Author: Michael Holst * *************************************************************************** */ VPRIVATE int markSimplex_default(int dim, int dimII, int simplexType, int faceType[4], int vertexType[4], int chart[], double vx[][3], void *data) { int j, k, less, more; double radius, d[4]; /* radius = radius of a refinement sphere for testing */ radius = 0.1; /* must be > 0 */ less = 0; more = 0; for (j=0; j<dim+1; j++) { d[j] = 0.0; for (k=0; k<3; k++) d[j] += VSQR( vx[j][k] ); d[j] = VSQRT( d[j] ); if (d[j] <= radius+VSMALL) less = 1; else more = 1; } /* return true if simplex touches or stradles surface of sphere */ return ( less && more ); }
/* /////////////////////////////////////////////////////////////////////////// // Routine: Vopot_gradient // // Authors: Nathan Baker /////////////////////////////////////////////////////////////////////////// */ VPUBLIC int Vopot_gradient(Vopot *thee, double pt[3], double grad[3]) { Vatom *atom; int iatom; double T, charge, eps_w, xkappa, size, val, *position; double dx, dy, dz, dist; Valist *alist; VASSERT(thee != VNULL); eps_w = Vpbe_getSolventDiel(thee->pbe); xkappa = (1.0e10)*Vpbe_getXkappa(thee->pbe); T = Vpbe_getTemperature(thee->pbe); alist = Vpbe_getValist(thee->pbe); if (!Vmgrid_gradient(thee->mgrid, pt, grad)) { switch (thee->bcfl) { case BCFL_ZERO: grad[0] = 0.0; grad[1] = 0.0; grad[2] = 0.0; break; case BCFL_SDH: grad[0] = 0.0; grad[1] = 0.0; grad[2] = 0.0; size = (1.0e-10)*Vpbe_getSoluteRadius(thee->pbe); position = Vpbe_getSoluteCenter(thee->pbe); charge = Vunit_ec*Vpbe_getSoluteCharge(thee->pbe); dx = position[0] - pt[0]; dy = position[1] - pt[1]; dz = position[2] - pt[2]; dist = VSQR(dx) + VSQR(dy) + VSQR(dz); dist = (1.0e-10)*VSQRT(dist); val = (charge)/(4*VPI*Vunit_eps0*eps_w); if (xkappa != 0.0) val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size)); val = val*Vunit_ec/(Vunit_kb*T); grad[0] = val*dx/dist*(-1.0/dist/dist + xkappa/dist); grad[1] = val*dy/dist*(-1.0/dist/dist + xkappa/dist); grad[2] = val*dz/dist*(-1.0/dist/dist + xkappa/dist); break; case BCFL_MDH: grad[0] = 0.0; grad[1] = 0.0; grad[2] = 0.0; for (iatom=0; iatom<Valist_getNumberAtoms(alist); iatom++) { atom = Valist_getAtom(alist, iatom); position = Vatom_getPosition(atom); charge = Vunit_ec*Vatom_getCharge(atom); size = (1e-10)*Vatom_getRadius(atom); dx = position[0] - pt[0]; dy = position[1] - pt[1]; dz = position[2] - pt[2]; dist = VSQR(dx) + VSQR(dy) + VSQR(dz); dist = (1.0e-10)*VSQRT(dist); val = (charge)/(4*VPI*Vunit_eps0*eps_w); if (xkappa != 0.0) val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size)); val = val*Vunit_ec/(Vunit_kb*T); grad[0] += (val*dx/dist*(-1.0/dist/dist + xkappa/dist)); grad[1] += (val*dy/dist*(-1.0/dist/dist + xkappa/dist)); grad[2] += (val*dz/dist*(-1.0/dist/dist + xkappa/dist)); } break; case BCFL_UNUSED: Vnm_print(2, "Vopot: Invalid bcfl (%d)!\n", thee->bcfl); return 0; case BCFL_FOCUS: Vnm_print(2, "Vopot: Invalid bcfl (%d)!\n", thee->bcfl); return 0; default: Vnm_print(2, "Vopot_pot: Bogus thee->bcfl flag (%d)!\n", thee->bcfl); return 0; break; } return 1; } return 1; }
/* /////////////////////////////////////////////////////////////////////////// // Routine: Vopot_curvature // // Notes: cflag=0 ==> Reduced Maximal Curvature // cflag=1 ==> Mean Curvature (Laplace) // cflag=2 ==> Gauss Curvature // cflag=3 ==> True Maximal Curvature // If we are off the grid, we can still evaluate the Laplacian; assuming, we // are away from the molecular surface, it is simply equal to the DH factor. // // Authors: Nathan Baker /////////////////////////////////////////////////////////////////////////// */ VPUBLIC int Vopot_curvature(Vopot *thee, double pt[3], int cflag, double *value) { Vatom *atom; int i, iatom; double u, T, charge, eps_w, xkappa, dist, size, val, *position, zkappa2; Valist *alist; VASSERT(thee != VNULL); eps_w = Vpbe_getSolventDiel(thee->pbe); xkappa = (1.0e10)*Vpbe_getXkappa(thee->pbe); zkappa2 = Vpbe_getZkappa2(thee->pbe); T = Vpbe_getTemperature(thee->pbe); alist = Vpbe_getValist(thee->pbe); u = 0; if (Vmgrid_curvature(thee->mgrid, pt, cflag, value)) return 1; else if (cflag != 1) { Vnm_print(2, "Vopot_curvature: Off mesh!\n"); return 1; } else { switch (thee->bcfl) { case BCFL_ZERO: u = 0; break; case BCFL_SDH: size = (1.0e-10)*Vpbe_getSoluteRadius(thee->pbe); position = Vpbe_getSoluteCenter(thee->pbe); charge = Vunit_ec*Vpbe_getSoluteCharge(thee->pbe); dist = 0; for (i=0; i<3; i++) dist += VSQR(position[i] - pt[i]); dist = (1.0e-10)*VSQRT(dist); if (xkappa != 0.0) u = zkappa2*(exp(-xkappa*(dist-size))/(1+xkappa*size)); break; case BCFL_MDH: u = 0; for (iatom=0; iatom<Valist_getNumberAtoms(alist); iatom++) { atom = Valist_getAtom(alist, iatom); position = Vatom_getPosition(atom); charge = Vunit_ec*Vatom_getCharge(atom); size = (1e-10)*Vatom_getRadius(atom); dist = 0; for (i=0; i<3; i++) dist += VSQR(position[i] - pt[i]); dist = (1.0e-10)*VSQRT(dist); if (xkappa != 0.0) val = zkappa2*(exp(-xkappa*(dist-size))/(1+xkappa*size)); u = u + val; } break; case BCFL_UNUSED: Vnm_print(2, "Vopot_pot: Invlid bcfl (%d)!\n", thee->bcfl); return 0; case BCFL_FOCUS: Vnm_print(2, "Vopot_pot: Invlid bcfl (%d)!\n", thee->bcfl); return 0; default: Vnm_print(2, "Vopot_pot: Bogus thee->bcfl flag (%d)!\n", thee->bcfl); return 0; break; } *value = u; } return 1; }
VPUBLIC int Vopot_pot(Vopot *thee, double pt[3], double *value) { Vatom *atom; int i, iatom; double u, T, charge, eps_w, xkappa, dist, size, val, *position; Valist *alist; VASSERT(thee != VNULL); eps_w = Vpbe_getSolventDiel(thee->pbe); xkappa = (1.0e10)*Vpbe_getXkappa(thee->pbe); T = Vpbe_getTemperature(thee->pbe); alist = Vpbe_getValist(thee->pbe); u = 0; /* See if we're on the mesh */ if (Vmgrid_value(thee->mgrid, pt, &u)) { *value = u; } else { switch (thee->bcfl) { case BCFL_ZERO: u = 0; break; case BCFL_SDH: size = (1.0e-10)*Vpbe_getSoluteRadius(thee->pbe); position = Vpbe_getSoluteCenter(thee->pbe); charge = Vunit_ec*Vpbe_getSoluteCharge(thee->pbe); dist = 0; for (i=0; i<3; i++) dist += VSQR(position[i] - pt[i]); dist = (1.0e-10)*VSQRT(dist); val = (charge)/(4*VPI*Vunit_eps0*eps_w*dist); if (xkappa != 0.0) val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size)); val = val*Vunit_ec/(Vunit_kb*T); u = val; break; case BCFL_MDH: u = 0; for (iatom=0; iatom<Valist_getNumberAtoms(alist); iatom++) { atom = Valist_getAtom(alist, iatom); position = Vatom_getPosition(atom); charge = Vunit_ec*Vatom_getCharge(atom); size = (1e-10)*Vatom_getRadius(atom); dist = 0; for (i=0; i<3; i++) dist += VSQR(position[i] - pt[i]); dist = (1.0e-10)*VSQRT(dist); val = (charge)/(4*VPI*Vunit_eps0*eps_w*dist); if (xkappa != 0.0) val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size)); val = val*Vunit_ec/(Vunit_kb*T); u = u + val; } break; case BCFL_UNUSED: Vnm_print(2, "Vopot_pot: Invalid bcfl flag (%d)!\n", thee->bcfl); return 0; case BCFL_FOCUS: Vnm_print(2, "Vopot_pot: Invalid bcfl flag (%d)!\n", thee->bcfl); return 0; default: Vnm_print(2, "Vopot_pot: Bogus thee->bcfl flag (%d)!\n", thee->bcfl); return 0; break; } *value = u; } return 1; }
/* * *************************************************************************** * Routine: Gem_formFix * * Purpose: Make some specified hacked fix to a given mesh. * * Notes: key==0 --> ? * * Author: Michael Holst * *************************************************************************** */ VPUBLIC void Gem_formFix(Gem *thee, int key) { int i, j, k, l, m, nabors, btype; double radk, radl, radm, myTol; VV *v[4]; SS *sm, *sm0, *sm1, *sm2; /* input check and some i/o */ btype = key; VASSERT( (0 <= btype) && (btype <= 2) ); /* go through all simplices and zero all boundary faces */ Vnm_print(0,"Gem_makeBnd: zeroing boundary faces/vertices.."); Gem_setNumBF(thee, 0); Gem_setNumBV(thee, 0); for (i=0; i<Gem_numSS(thee); i++) { sm = Gem_SS(thee,i); if ( (i>0) && (i % VPRTKEY) == 0 ) Vnm_print(0,"[BS:%d]",i); /* get local vertices */ for (j=0; j<Gem_dimVV(thee); j++) v[j] = SS_vertex(sm,j); /* reset all vertices and faces to interior type */ for (j=0; j<Gem_dimVV(thee); j++) { /* the other three local vertex/face numbers besides "j" */ k=(j+1) % Gem_dimVV(thee); l=(k+1) % Gem_dimVV(thee); m=(l+1) % Gem_dimVV(thee); SS_setFaceType(sm, j, 0); VV_setType(v[k], 0); VV_setType(v[l], 0); if (Gem_dim(thee) == 3) VV_setType(v[m], 0); } } Vnm_print(0,"..done.\n"); /* are we done */ /* if (btype == 0) return; */ /* okay now make a boundary */ Vnm_print(0,"Gem_makeBnd: rebuilding boundary faces/vertices.."); for (i=0; i<Gem_numSS(thee); i++) { sm = Gem_SS(thee,i); if ( (i>0) && (i % VPRTKEY) == 0 ) Vnm_print(0,"[BS:%d]",i); /* get local vertices */ for (j=0; j<Gem_dimVV(thee); j++) v[j] = SS_vertex(sm,j); /* rebuild everything */ for (j=0; j<Gem_dimVV(thee); j++) { /* the other three local vertex/face numbers besides "j" */ k=(j+1) % Gem_dimVV(thee); l=(k+1) % Gem_dimVV(thee); m=(l+1) % Gem_dimVV(thee); /* look for a face nabor sharing face "j" (opposite vertex "j") */ nabors = 0; for (sm0=VV_firstSS(v[k]); sm0!=VNULL;sm0=SS_link(sm0,v[k])) { for (sm1=VV_firstSS(v[l]); sm1!=VNULL; sm1=SS_link(sm1,v[l])) { if (Gem_dim(thee) == 2) { if ((sm0!=sm) && (sm0==sm1)) nabors++; } else { for (sm2=VV_firstSS(v[m]); sm2!=VNULL; sm2=SS_link(sm2,v[m])) { if ((sm0!=sm) && (sm0==sm1) && (sm0==sm2)) { nabors++; } } } } } /* if no one there, then face "j" is actually a boundary face */ if (nabors == 0) { myTol = 1.0e-2; if ( ( VABS(VV_coord(v[k],2) - 0.0) < myTol) && ( VABS(VV_coord(v[l],2) - 0.0) < myTol) && ( VABS(VV_coord(v[m],2) - 0.0) < myTol) ) { btype = 1; } else if ( ( VABS(VV_coord(v[k],2) - 68.03512) < myTol) && ( VABS(VV_coord(v[l],2) - 68.03512) < myTol) && ( VABS(VV_coord(v[m],2) - 68.03512) < myTol) ) { btype = 3; } else { radk = VSQRT( VSQR( VV_coord(v[k],0) ) + VSQR( VV_coord(v[k],1) ) ); radl = VSQRT( VSQR( VV_coord(v[l],0) ) + VSQR( VV_coord(v[l],1) ) ); radm = VSQRT( VSQR( VV_coord(v[m],0) ) + VSQR( VV_coord(v[m],1) ) ); if ( ( VABS(radk - 1.5) < myTol) && ( VABS(radl - 1.5) < myTol) && ( VABS(radm - 1.5) < myTol) ) { btype = 2; } else if ( ( VABS(radk - 2.0) < myTol) && ( VABS(radl - 2.0) < myTol) && ( VABS(radm - 2.0) < myTol) ){ btype = 4; } else { btype = 0; } } SS_setFaceType(sm, j, btype); Gem_numBFpp(thee); if (VINTERIOR( VV_type(v[k])) ) { VV_setType(v[k], btype); Gem_numBVpp(thee); } if (VINTERIOR( VV_type(v[l])) ) { VV_setType(v[l], btype); Gem_numBVpp(thee); } if (Gem_dim(thee) == 3) { if (VINTERIOR( VV_type(v[m])) ) { VV_setType(v[m], btype); Gem_numBVpp(thee); } } } } } Vnm_print(0,"..done.\n"); }