• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

src/mg/vopot.c

Go to the documentation of this file.
00001 
00049 #include "apbscfg.h"
00050 #include "apbs/vopot.h"
00051 #include "apbs/pbeparm.h"
00052 
00053 VEMBED(rcsid="$Id: vopot.c 1552 2010-02-10 17:46:27Z yhuang01 $")
00054 
00055 /* ///////////////////////////////////////////////////////////////////////////
00056 // Routine:  Vopot_ctor
00057 // Author:   Nathan Baker
00059 VPUBLIC Vopot* Vopot_ctor(Vmgrid *mgrid, Vpbe *pbe, Vbcfl bcfl) {
00060 
00061     Vopot *thee = VNULL;
00062 
00063     thee = Vmem_malloc(VNULL, 1, sizeof(Vopot));
00064     VASSERT(thee != VNULL);
00065     VASSERT(Vopot_ctor2(thee, mgrid, pbe, bcfl));
00066 
00067     return thee;
00068 }
00069 
00070 /* ///////////////////////////////////////////////////////////////////////////
00071 // Routine:  Vopot_ctor2
00072 // Author:   Nathan Baker
00074 VPUBLIC int Vopot_ctor2(Vopot *thee, Vmgrid *mgrid, Vpbe *pbe, Vbcfl bcfl) {
00075 
00076     if (thee == VNULL) return 0;
00077     thee->bcfl = bcfl;
00078     thee->mgrid = mgrid;
00079     thee->pbe = pbe;
00080 
00081     return 1;
00082 }
00083 
00084 /* ///////////////////////////////////////////////////////////////////////////
00085 // Routine:  Vopot_dtor
00086 // Author:   Nathan Baker
00088 VPUBLIC void Vopot_dtor(Vopot **thee) {
00089 
00090     if ((*thee) != VNULL) {
00091         Vopot_dtor2(*thee);
00092         Vmem_free(VNULL, 1, sizeof(Vopot), (void **)thee);
00093         (*thee) = VNULL;
00094     }
00095 }
00096 
00097 /* ///////////////////////////////////////////////////////////////////////////
00098 // Routine:  Vopot_dtor2
00099 // Author:   Nathan Baker
00101 VPUBLIC void Vopot_dtor2(Vopot *thee) { return; }
00102 
00103 /* ///////////////////////////////////////////////////////////////////////////
00104 // Routine:  Vopot_pot
00105 // Author:   Nathan Baker
00107 #define IJK(i,j,k)  (((k)*(nx)*(ny))+((j)*(nx))+(i))
00108 VPUBLIC int Vopot_pot(Vopot *thee, double pt[3], double *value) {
00109 
00110     Vatom *atom;
00111     int i, iatom;
00112     double u, T, charge, eps_w, xkappa, dist, size, val, *position;
00113     Valist *alist;
00114 
00115     VASSERT(thee != VNULL);
00116 
00117     eps_w = Vpbe_getSolventDiel(thee->pbe);
00118     xkappa = (1.0e10)*Vpbe_getXkappa(thee->pbe);
00119     T = Vpbe_getTemperature(thee->pbe);
00120     alist = Vpbe_getValist(thee->pbe);
00121 
00122     u = 0;
00123 
00124     /* See if we're on the mesh */
00125     if (Vmgrid_value(thee->mgrid, pt, &u)) {
00126 
00127         *value = u;
00128 
00129     } else {
00130 
00131         switch (thee->bcfl) {
00132 
00133             case BCFL_ZERO:
00134                 u = 0;
00135                 break;
00136 
00137             case BCFL_SDH:
00138                 size = (1.0e-10)*Vpbe_getSoluteRadius(thee->pbe);
00139                 position = Vpbe_getSoluteCenter(thee->pbe);
00140                 charge = Vunit_ec*Vpbe_getSoluteCharge(thee->pbe);
00141                 dist = 0;
00142                 for (i=0; i<3; i++)
00143                   dist += VSQR(position[i] - pt[i]);
00144                 dist = (1.0e-10)*VSQRT(dist);
00145                 val = (charge)/(4*VPI*Vunit_eps0*eps_w*dist);
00146                 if (xkappa != 0.0) 
00147                   val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size));
00148                 val = val*Vunit_ec/(Vunit_kb*T);
00149                 u = val;
00150                 break;
00151 
00152             case BCFL_MDH:
00153                 u = 0;
00154                 for (iatom=0; iatom<Valist_getNumberAtoms(alist); iatom++) {
00155                     atom = Valist_getAtom(alist, iatom);
00156                     position = Vatom_getPosition(atom);
00157                     charge = Vunit_ec*Vatom_getCharge(atom);
00158                     size = (1e-10)*Vatom_getRadius(atom);
00159                     dist = 0;
00160                     for (i=0; i<3; i++)
00161                       dist += VSQR(position[i] - pt[i]);
00162                     dist = (1.0e-10)*VSQRT(dist);
00163                     val = (charge)/(4*VPI*Vunit_eps0*eps_w*dist);
00164                     if (xkappa != 0.0)
00165                       val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size));
00166                     val = val*Vunit_ec/(Vunit_kb*T);
00167                     u = u + val;
00168                 }
00169                 break;
00170 
00171             case BCFL_UNUSED:
00172                 Vnm_print(2, "Vopot_pot:  Invalid bcfl flag (%d)!\n", 
00173                   thee->bcfl);
00174                 return 0;
00175 
00176             case BCFL_FOCUS:
00177                 Vnm_print(2, "Vopot_pot:  Invalid bcfl flag (%d)!\n", 
00178                   thee->bcfl);
00179                 return 0;
00180 
00181             default:
00182                 Vnm_print(2, "Vopot_pot:  Bogus thee->bcfl flag (%d)!\n", 
00183                   thee->bcfl);
00184                 return 0;        
00185                 break;
00186         }
00187 
00188         *value = u;
00189 
00190     }
00191 
00192     return 1;
00193 
00194 }
00195 
00196 /* ///////////////////////////////////////////////////////////////////////////
00197 // Routine:  Vopot_curvature
00198 //
00199 //   Notes:  cflag=0 ==> Reduced Maximal Curvature
00200 //           cflag=1 ==> Mean Curvature (Laplace)
00201 //           cflag=2 ==> Gauss Curvature
00202 //           cflag=3 ==> True Maximal Curvature
00203 //   If we are off the grid, we can still evaluate the Laplacian; assuming, we
00204 //   are away from the molecular surface, it is simply equal to the DH factor.
00205 //
00206 // Authors:  Nathan Baker
00208 VPUBLIC int Vopot_curvature(Vopot *thee, double pt[3], int cflag, 
00209   double *value) {
00210 
00211     Vatom *atom;
00212     int i, iatom;
00213     double u, T, charge, eps_w, xkappa, dist, size, val, *position, zkappa2;
00214     Valist *alist;
00215 
00216     VASSERT(thee != VNULL);
00217 
00218     eps_w = Vpbe_getSolventDiel(thee->pbe);
00219     xkappa = (1.0e10)*Vpbe_getXkappa(thee->pbe);
00220     zkappa2 = Vpbe_getZkappa2(thee->pbe);
00221     T = Vpbe_getTemperature(thee->pbe);
00222     alist = Vpbe_getValist(thee->pbe);
00223 
00224     u = 0;
00225 
00226     if (Vmgrid_curvature(thee->mgrid, pt, cflag, value)) return 1;
00227     else if (cflag != 1) {
00228         Vnm_print(2, "Vopot_curvature:  Off mesh!\n");
00229         return 1;
00230     } else {
00231 
00232         switch (thee->bcfl) {
00233 
00234             case BCFL_ZERO:
00235                 u = 0;
00236                 break;
00237 
00238             case BCFL_SDH:
00239                 size = (1.0e-10)*Vpbe_getSoluteRadius(thee->pbe);
00240                 position = Vpbe_getSoluteCenter(thee->pbe);
00241                 charge = Vunit_ec*Vpbe_getSoluteCharge(thee->pbe);
00242                 dist = 0;
00243                 for (i=0; i<3; i++)
00244                   dist += VSQR(position[i] - pt[i]);
00245                 dist = (1.0e-10)*VSQRT(dist);
00246                 if (xkappa != 0.0) 
00247                   u = zkappa2*(exp(-xkappa*(dist-size))/(1+xkappa*size));
00248                 break;
00249 
00250             case BCFL_MDH:
00251                 u = 0;
00252                 for (iatom=0; iatom<Valist_getNumberAtoms(alist); iatom++) {
00253                     atom = Valist_getAtom(alist, iatom);
00254                     position = Vatom_getPosition(atom);
00255                     charge = Vunit_ec*Vatom_getCharge(atom);
00256                     size = (1e-10)*Vatom_getRadius(atom);
00257                     dist = 0;
00258                     for (i=0; i<3; i++)
00259                       dist += VSQR(position[i] - pt[i]);
00260                     dist = (1.0e-10)*VSQRT(dist);
00261                     if (xkappa != 0.0)
00262                       val = zkappa2*(exp(-xkappa*(dist-size))/(1+xkappa*size));
00263                     u = u + val;
00264                 }
00265                 break;
00266 
00267             case BCFL_UNUSED:
00268                 Vnm_print(2, "Vopot_pot:  Invlid bcfl (%d)!\n", thee->bcfl);
00269                 return 0;
00270 
00271             case BCFL_FOCUS:
00272                 Vnm_print(2, "Vopot_pot:  Invlid bcfl (%d)!\n", thee->bcfl);
00273                 return 0;
00274 
00275             default:
00276                 Vnm_print(2, "Vopot_pot:  Bogus thee->bcfl flag (%d)!\n", 
00277                   thee->bcfl);
00278                 return 0;        
00279                 break;
00280         }
00281 
00282         *value = u;
00283     }
00284 
00285     return 1;
00286 
00287 }
00288 
00289 /* ///////////////////////////////////////////////////////////////////////////
00290 // Routine:  Vopot_gradient
00291 //
00292 // Authors:  Nathan Baker
00294 VPUBLIC int Vopot_gradient(Vopot *thee, double pt[3], double grad[3]) {
00295 
00296     Vatom *atom;
00297     int iatom;
00298     double T, charge, eps_w, xkappa, size, val, *position;
00299     double dx, dy, dz, dist;
00300     Valist *alist;
00301 
00302     VASSERT(thee != VNULL);
00303 
00304     eps_w = Vpbe_getSolventDiel(thee->pbe);
00305     xkappa = (1.0e10)*Vpbe_getXkappa(thee->pbe);
00306     T = Vpbe_getTemperature(thee->pbe);
00307     alist = Vpbe_getValist(thee->pbe);
00308 
00309 
00310     if (!Vmgrid_gradient(thee->mgrid, pt, grad)) {
00311 
00312         switch (thee->bcfl) {
00313 
00314             case BCFL_ZERO:
00315                 grad[0] = 0.0;
00316                 grad[1] = 0.0;
00317                 grad[2] = 0.0;
00318                 break;
00319 
00320             case BCFL_SDH:
00321                 grad[0] = 0.0;
00322                 grad[1] = 0.0;
00323                 grad[2] = 0.0;
00324                 size = (1.0e-10)*Vpbe_getSoluteRadius(thee->pbe);
00325                 position = Vpbe_getSoluteCenter(thee->pbe);
00326                 charge = Vunit_ec*Vpbe_getSoluteCharge(thee->pbe);
00327                 dx = position[0] - pt[0];
00328                 dy = position[1] - pt[1];
00329                 dz = position[2] - pt[2];
00330                 dist = VSQR(dx) + VSQR(dy) + VSQR(dz);
00331                 dist = (1.0e-10)*VSQRT(dist);
00332                 val = (charge)/(4*VPI*Vunit_eps0*eps_w);
00333                 if (xkappa != 0.0) 
00334                   val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size));
00335                 val = val*Vunit_ec/(Vunit_kb*T);
00336                 grad[0] = val*dx/dist*(-1.0/dist/dist + xkappa/dist);
00337                 grad[1] = val*dy/dist*(-1.0/dist/dist + xkappa/dist);
00338                 grad[2] = val*dz/dist*(-1.0/dist/dist + xkappa/dist);
00339                 break;
00340 
00341             case BCFL_MDH:
00342                 grad[0] = 0.0;
00343                 grad[1] = 0.0;
00344                 grad[2] = 0.0;
00345                 for (iatom=0; iatom<Valist_getNumberAtoms(alist); iatom++) {
00346                     atom = Valist_getAtom(alist, iatom);
00347                     position = Vatom_getPosition(atom);
00348                     charge = Vunit_ec*Vatom_getCharge(atom);
00349                     size = (1e-10)*Vatom_getRadius(atom);
00350                     dx = position[0] - pt[0];
00351                     dy = position[1] - pt[1];
00352                     dz = position[2] - pt[2];
00353                     dist = VSQR(dx) + VSQR(dy) + VSQR(dz);
00354                     dist = (1.0e-10)*VSQRT(dist);
00355                     val = (charge)/(4*VPI*Vunit_eps0*eps_w);
00356                     if (xkappa != 0.0)
00357                       val = val*(exp(-xkappa*(dist-size))/(1+xkappa*size));
00358                     val = val*Vunit_ec/(Vunit_kb*T);
00359                     grad[0] += (val*dx/dist*(-1.0/dist/dist + xkappa/dist));
00360                     grad[1] += (val*dy/dist*(-1.0/dist/dist + xkappa/dist));
00361                     grad[2] += (val*dz/dist*(-1.0/dist/dist + xkappa/dist));
00362                 }
00363                 break;
00364 
00365             case BCFL_UNUSED:
00366                 Vnm_print(2, "Vopot:  Invalid bcfl (%d)!\n", thee->bcfl);
00367                 return 0;
00368 
00369             case BCFL_FOCUS:
00370                 Vnm_print(2, "Vopot:  Invalid bcfl (%d)!\n", thee->bcfl);
00371                 return 0;
00372 
00373             default:
00374                 Vnm_print(2, "Vopot_pot:  Bogus thee->bcfl flag (%d)!\n", 
00375                   thee->bcfl);
00376                 return 0;        
00377                 break;
00378         }
00379 
00380         return 1;
00381     } 
00382 
00383     return 1;
00384 
00385 }
00386 

Generated on Wed Oct 20 2010 12:01:34 for APBS by  doxygen 1.7.2