Beispiel #1
0
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;
}
Beispiel #2
0
/* Get the dimensions of the molecule stored in thee->alist */
VPRIVATE void Vclist_getMolDims(
        Vclist *thee, 
        double lower_corner[VAPBS_DIM], /* Set to lower corner of molecule */
        double upper_corner[VAPBS_DIM], /* Set to lower corner of molecule */
        double *r_max /* Set to max atom radius */
        ) {

    int i, j;
    double pos;
    Valist *alist;
    Vatom *atom;

    alist = thee->alist;

    /* Initialize */
    for (i=0; i<VAPBS_DIM; i++) {
        lower_corner[i] = VLARGE;
        upper_corner[i] = -VLARGE;
    }
    *r_max = -1.0;

    /* Check each atom */
    for (i=0; i<Valist_getNumberAtoms(alist); i++) {
        atom = Valist_getAtom(alist, i);
		for (j=0; j<VAPBS_DIM; j++) {
            pos = (Vatom_getPosition(atom))[j];
            if ( pos < lower_corner[j] ) lower_corner[j] = pos;
            if ( pos > upper_corner[j] ) upper_corner[j] = pos;
        }
        if (Vatom_getRadius(atom) > *r_max) *r_max = Vatom_getRadius(atom);
    }

}
Beispiel #3
0
/* Calculate the gridpoints an atom spans */
VPRIVATE void Vclist_gridSpan(Vclist *thee, 
        Vatom *atom, /* Atom */
        int imin[VAPBS_DIM], /* Set to min grid indices */
        int imax[VAPBS_DIM]  /* Set to max grid indices */
        ) {

    int i;
    double *coord, dc, idc, rtot;

    /* Get the position in the grid's frame of reference */
    coord = Vatom_getPosition(atom);

    /* Get the range the atom radius + probe radius spans */
    rtot = Vatom_getRadius(atom) + thee->max_radius;
    
    /* Calculate the range of grid points the inflated atom spans in the x 
     * direction. */
    for (i=0; i<VAPBS_DIM; i++) {
        dc = coord[i] - (thee->lower_corner)[i];
        idc = (dc + rtot)/(thee->spacs[i]);
        imax[i] = (int)(ceil(idc));
        imax[i] = VMIN2(imax[i], thee->npts[i]-1);
        idc = (dc - rtot)/(thee->spacs[i]);
        imin[i] = (int)(floor(idc));
        imin[i] = VMAX2(imin[i], 0);
    }

}
Beispiel #4
0
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;
}
Beispiel #5
0
VPUBLIC int Vcsm_update(Vcsm *thee, SS **simps, int num) {

    /* Counters */
    int isimp, jsimp, iatom, jatom, atomID, simpID;
    int nsimps, gotMem;
    /* Object info */
    Vatom *atom;
    SS *simplex;
    double *position;
    /* Lists */
    int *qParent, nqParent;
    int **sqmNew, *nsqmNew;
    int *affAtoms, nAffAtoms;
    int *dnqsm, *nqsmNew, **qsmNew;

    VASSERT(thee != VNULL);
    VASSERT(thee->initFlag);

    /* If we don't have enough memory to accommodate the new entries, 
     * add more by doubling the existing amount */
    isimp = thee->nsimp + num - 1;
    gotMem = 0;
    while (!gotMem) {
        if (isimp > thee->msimp) {
            isimp = 2 * isimp;
            thee->nsqm = Vmem_realloc(thee->vmem, thee->msimp, sizeof(int), 
              (void **)&(thee->nsqm), isimp);
            VASSERT(thee->nsqm != VNULL);
            thee->sqm = Vmem_realloc(thee->vmem, thee->msimp, sizeof(int *), 
              (void **)&(thee->sqm), isimp);
            VASSERT(thee->sqm != VNULL);
            thee->msimp = isimp;
        } else gotMem = 1;
    }
    /* Initialize the nsqm entires we just allocated */
    for (isimp = thee->nsimp; isimp<thee->nsimp+num-1 ; isimp++) {
       thee->nsqm[isimp] = 0;
    }
    
    thee->nsimp = thee->nsimp + num - 1;

    /* There's a simple case to deal with:  if simps[0] didn't have a
     * charge in the first place */
    isimp = SS_id(simps[0]);
    if (thee->nsqm[isimp] == 0) {
        for (isimp=1; isimp<num; isimp++) {
            thee->nsqm[SS_id(simps[isimp])] = 0;
        }
        return 1;
    }

    /* The more complicated case has occured; the parent simplex had one or
     * more charges.  First, generate the list of affected charges. */
    isimp = SS_id(simps[0]);
    nqParent = thee->nsqm[isimp];
    qParent = thee->sqm[isimp];

    sqmNew = Vmem_malloc(thee->vmem, num, sizeof(int *));
    VASSERT(sqmNew != VNULL);
    nsqmNew = Vmem_malloc(thee->vmem, num, sizeof(int));
    VASSERT(nsqmNew != VNULL);
    for (isimp=0; isimp<num; isimp++) nsqmNew[isimp] = 0;

    /* Loop throught the affected atoms to determine how many atoms each
     * simplex will get. */
    for (iatom=0; iatom<nqParent; iatom++) {

        atomID = qParent[iatom];
        atom = Valist_getAtom(thee->alist, atomID);
        position = Vatom_getPosition(atom);
        nsimps = 0;

        jsimp = 0;

        for (isimp=0; isimp<num; isimp++) {
            simplex = simps[isimp];
            if (Gem_pointInSimplex(thee->gm, simplex, position)) {
                nsqmNew[isimp]++;
                jsimp = 1;
            }
        }
 
        VASSERT(jsimp != 0);
    }

    /* Sanity check that we didn't lose any atoms... */
    iatom = 0;
    for (isimp=0; isimp<num; isimp++) iatom += nsqmNew[isimp];
    if (iatom < nqParent) {
        Vnm_print(2,"Vcsm_update: Lost %d (of %d) atoms!\n", 
            nqParent - iatom, nqParent);
        VASSERT(0);
    }

    /* Allocate the storage */
    for (isimp=0; isimp<num; isimp++) {
        if (nsqmNew[isimp] > 0) {
            sqmNew[isimp] = Vmem_malloc(thee->vmem, nsqmNew[isimp], 
              sizeof(int));
            VASSERT(sqmNew[isimp] != VNULL);
        }
    }

    /* Assign charges to simplices */
    for (isimp=0; isimp<num; isimp++) {

        jsimp = 0;
        simplex = simps[isimp];

        /* Loop over the atoms associated with the parent simplex */
        for (iatom=0; iatom<nqParent; iatom++) {

            atomID = qParent[iatom];
            atom = Valist_getAtom(thee->alist, atomID);
            position = Vatom_getPosition(atom);
            if (Gem_pointInSimplex(thee->gm, simplex, position)) {
                sqmNew[isimp][jsimp] = atomID;
                jsimp++;
            }
        }
    }

    /* Update the QSM map using the old and new SQM lists */
    /* The affected atoms are those contained in the parent simplex; i.e.
     * thee->sqm[SS_id(simps[0])] */
    affAtoms = thee->sqm[SS_id(simps[0])];
    nAffAtoms = thee->nsqm[SS_id(simps[0])];
    /* Each of these atoms will go somewhere else; i.e., the entries in
     * thee->qsm are never destroyed and thee->nqsm never decreases.
     * However, it is possible that a subdivision could cause an atom to be
     * shared by two child simplices.  Here we record the change, if any,
     * in the number of simplices associated with each atom. */
    dnqsm = Vmem_malloc(thee->vmem, nAffAtoms, sizeof(int));
    VASSERT(dnqsm != VNULL);
    nqsmNew = Vmem_malloc(thee->vmem, nAffAtoms, sizeof(int));
    VASSERT(nqsmNew != VNULL);
    qsmNew = Vmem_malloc(thee->vmem, nAffAtoms, sizeof(int*));
    VASSERT(qsmNew != VNULL);
    for (iatom=0; iatom<nAffAtoms; iatom++) {
        dnqsm[iatom] = -1;
        atomID = affAtoms[iatom];
        for (isimp=0; isimp<num; isimp++) {
            for (jatom=0; jatom<nsqmNew[isimp]; jatom++) {
                if (sqmNew[isimp][jatom] == atomID) dnqsm[iatom]++;
            }
        }
        VASSERT(dnqsm[iatom] > -1);
    }
    /* Setup the new entries in the array */
    for (iatom=0;iatom<nAffAtoms; iatom++) {
        atomID = affAtoms[iatom];
        qsmNew[iatom] = Vmem_malloc(thee->vmem, 
                (dnqsm[iatom] + thee->nqsm[atomID]), 
                sizeof(int));
        nqsmNew[iatom] = 0;
        VASSERT(qsmNew[iatom] != VNULL);
    }
    /* Fill the new entries in the array */
    /* First, do the modified entries */
    for (isimp=0; isimp<num; isimp++) {
        simpID = SS_id(simps[isimp]);
        for (iatom=0; iatom<nsqmNew[isimp]; iatom++) {
            atomID = sqmNew[isimp][iatom];
            for (jatom=0; jatom<nAffAtoms; jatom++) {
                if (atomID == affAtoms[jatom]) break;
            }
            if (jatom < nAffAtoms) {
                qsmNew[jatom][nqsmNew[jatom]] = simpID;
                nqsmNew[jatom]++;
            } 
        }
    }
    /* Now do the unmodified entries */
    for (iatom=0; iatom<nAffAtoms; iatom++) {
        atomID = affAtoms[iatom];
        for (isimp=0; isimp<thee->nqsm[atomID]; isimp++) {
            for (jsimp=0; jsimp<num; jsimp++) {
                simpID = SS_id(simps[jsimp]);
                if (thee->qsm[atomID][isimp] == simpID) break;
            }
            if (jsimp == num) {
                qsmNew[iatom][nqsmNew[iatom]] = thee->qsm[atomID][isimp];
                nqsmNew[iatom]++;
            }
        }
    }

    /* Replace the existing entries in the table.  Do the QSM entires
     * first, since they require affAtoms = thee->sqm[simps[0]] */
    for (iatom=0; iatom<nAffAtoms; iatom++) {
        atomID = affAtoms[iatom]; 
        Vmem_free(thee->vmem, thee->nqsm[atomID], sizeof(int), 
          (void **)&(thee->qsm[atomID]));
        thee->qsm[atomID] = qsmNew[iatom];
        thee->nqsm[atomID] = nqsmNew[iatom];
    }
    for (isimp=0; isimp<num; isimp++) {
        simpID = SS_id(simps[isimp]);
        if (thee->nsqm[simpID] > 0) Vmem_free(thee->vmem, thee->nsqm[simpID], 
          sizeof(int), (void **)&(thee->sqm[simpID]));
        thee->sqm[simpID] = sqmNew[isimp];
        thee->nsqm[simpID] = nsqmNew[isimp];
    }

    Vmem_free(thee->vmem, num, sizeof(int *), (void **)&sqmNew);
    Vmem_free(thee->vmem, num, sizeof(int), (void **)&nsqmNew);
    Vmem_free(thee->vmem, nAffAtoms, sizeof(int *), (void **)&qsmNew);
    Vmem_free(thee->vmem, nAffAtoms, sizeof(int), (void **)&nqsmNew);
    Vmem_free(thee->vmem, nAffAtoms, sizeof(int), (void **)&dnqsm);


    return 1;


}
Beispiel #6
0
VPUBLIC void Vcsm_init(Vcsm *thee) {
 
    /* Counters */
    int iatom, jatom, isimp, jsimp, gotSimp;
    /* Atomic information */
    Vatom *atom;
    double *position;
    /* Simplex/Vertex information */
    SS *simplex;
    /* Basis function values */

    if (thee == VNULL) {
        Vnm_print(2, "Vcsm_init:  Error!  Got NULL thee!\n");
        VASSERT(0);
    }
    if (thee->gm == VNULL) {
    VASSERT(thee->gm != VNULL);
        Vnm_print(2, "Vcsm_init:  Error!  Got NULL thee->gm!\n");
        VASSERT(0);
    }
    thee->nsimp = Gem_numSS(thee->gm);
    if (thee->nsimp <= 0) {
        Vnm_print(2, "Vcsm_init:  Error!  Got %d simplices!\n", thee->nsimp);
        VASSERT(0);
    }
    thee->natom = Valist_getNumberAtoms(thee->alist);

    /* Allocate and initialize space for the first dimensions of the 
     * simplex-charge map, the simplex array, and the counters */
    thee->sqm = Vmem_malloc(thee->vmem, thee->nsimp, sizeof(int *));
    VASSERT(thee->sqm != VNULL);
    thee->nsqm = Vmem_malloc(thee->vmem, thee->nsimp, sizeof(int));
    VASSERT(thee->nsqm != VNULL);
    for (isimp=0; isimp<thee->nsimp; isimp++) (thee->nsqm)[isimp] = 0;

    /* Count the number of charges per simplex. */
    for (iatom=0; iatom<thee->natom; iatom++) {
        atom = Valist_getAtom(thee->alist, iatom);
        position = Vatom_getPosition(atom);
        gotSimp = 0;
        for (isimp=0; isimp<thee->nsimp; isimp++) {
            simplex = Gem_SS(thee->gm, isimp);
            if (Gem_pointInSimplex(thee->gm, simplex, position)) {
                (thee->nsqm)[isimp]++;
                gotSimp = 1;
             }
        }
    }

    /* Allocate the space for the simplex-charge map */
    for (isimp=0; isimp<thee->nsimp; isimp++) {
        if ((thee->nsqm)[isimp] > 0) {
            thee->sqm[isimp] = Vmem_malloc(thee->vmem, (thee->nsqm)[isimp], 
              sizeof(int));
            VASSERT(thee->sqm[isimp] != VNULL);
        }
    }

    /* Finally, set up the map */
    for (isimp=0; isimp<thee->nsimp; isimp++) {
        jsimp = 0;
        simplex = Gem_SS(thee->gm, isimp);
        for (iatom=0; iatom<thee->natom; iatom++) {
            atom = Valist_getAtom(thee->alist, iatom);
            position = Vatom_getPosition(atom);
            /* Check to see if the atom's in this simplex */
            if (Gem_pointInSimplex(thee->gm, simplex, position)) {
                /* Assign the entries in the next vacant spot */
                (thee->sqm)[isimp][jsimp] = iatom;
                jsimp++;
            }
        }
    }

    thee->msimp = thee->nsimp;

    /* Allocate space for the charge-simplex map */
    thee->qsm = Vmem_malloc(thee->vmem, thee->natom, sizeof(int *));
    VASSERT(thee->qsm != VNULL);
    thee->nqsm = Vmem_malloc(thee->vmem, thee->natom, sizeof(int));
    VASSERT(thee->nqsm != VNULL);
    for (iatom=0; iatom<thee->natom; iatom++) (thee->nqsm)[iatom] = 0;
    /* Loop through the list of simplices and count the number of times
     * each atom appears */
    for (isimp=0; isimp<thee->nsimp; isimp++) {
        for (iatom=0; iatom<thee->nsqm[isimp]; iatom++) {
            jatom = thee->sqm[isimp][iatom];
            thee->nqsm[jatom]++;
        }
    }
    /* Do a TIME-CONSUMING SANITY CHECK to make sure that each atom was
     * placed in at simplex */
    for (iatom=0; iatom<thee->natom; iatom++) {
        if (thee->nqsm[iatom] == 0) {
            Vnm_print(2, "Vcsm_init: Atom %d not placed in simplex!\n", iatom);
            VASSERT(0);
        }
    }
    /* Allocate the appropriate amount of space for each entry in the
     * charge-simplex map and clear the counter for re-use in assignment */
    for (iatom=0; iatom<thee->natom; iatom++) {
        thee->qsm[iatom] = Vmem_malloc(thee->vmem, (thee->nqsm)[iatom],
          sizeof(int));
        VASSERT(thee->qsm[iatom] != VNULL);
        thee->nqsm[iatom] = 0;
    }
    /* Assign the simplices to atoms */
    for (isimp=0; isimp<thee->nsimp; isimp++) {
        for (iatom=0; iatom<thee->nsqm[isimp]; iatom++) {
            jatom = thee->sqm[isimp][iatom];
            thee->qsm[jatom][thee->nqsm[jatom]] = isimp;
            thee->nqsm[jatom]++;
        }
    }

    thee->initFlag = 1;
}
Beispiel #7
0
/* ///////////////////////////////////////////////////////////////////////////
// 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;

}
Beispiel #8
0
/* ///////////////////////////////////////////////////////////////////////////
// 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;

}
Beispiel #9
0
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;

}
Beispiel #10
0
VPRIVATE int treesetup(Vgreen *thee) {

#ifdef HAVE_TREE

    double dist_tol = FMM_DIST_TOL;
    int iflag = FMM_IFLAG;
    double order = FMM_ORDER;
    int theta = FMM_THETA;
    int shrink = FMM_SHRINK;
    int maxparnode = FMM_MAXPARNODE;
    int minlevel = FMM_MINLEVEL;
    int maxlevel = FMM_MAXLEVEL;
    int level = 0;
    int one = 1;
    Vatom *atom;
    double xyzminmax[6], *pos;
    int i;

    /* Set up particle arrays with atomic coordinates and charges */
    Vnm_print(0, "treesetup:  Initializing FMM particle arrays...\n");
    thee->np = Valist_getNumberAtoms(thee->alist);
    thee->xp = VNULL;
    thee->xp = (double *)Vmem_malloc(thee->vmem, thee->np, sizeof(double));
    if (thee->xp == VNULL) {
        Vnm_print(2, "Vgreen_ctor2:  Failed to allocate %d*sizeof(double)!\n",
          thee->np);
        return 0;
    }
    thee->yp = VNULL;
    thee->yp = (double *)Vmem_malloc(thee->vmem, thee->np, sizeof(double));
    if (thee->yp == VNULL) {
        Vnm_print(2, "Vgreen_ctor2:  Failed to allocate %d*sizeof(double)!\n",
          thee->np);
        return 0;
    }
    thee->zp = VNULL;
    thee->zp = (double *)Vmem_malloc(thee->vmem, thee->np, sizeof(double));
    if (thee->zp == VNULL) {
        Vnm_print(2, "Vgreen_ctor2:  Failed to allocate %d*sizeof(double)!\n",
          thee->np);
        return 0;
    }
    thee->qp = VNULL;
    thee->qp = (double *)Vmem_malloc(thee->vmem, thee->np, sizeof(double));
    if (thee->qp == VNULL) {
        Vnm_print(2, "Vgreen_ctor2:  Failed to allocate %d*sizeof(double)!\n",
          thee->np);
        return 0;
    }
    for (i=0; i<thee->np; i++) {
        atom = Valist_getAtom(thee->alist, i);
        pos = Vatom_getPosition(atom);
        thee->xp[i] = pos[0];
        thee->yp[i] = pos[1];
        thee->zp[i] = pos[2];
        thee->qp[i] = Vatom_getCharge(atom);
    }

    Vnm_print(0, "treesetup:  Setting things up...\n");
    F77SETUP(thee->xp, thee->yp, thee->zp, &(thee->np), &order, &theta, &iflag,
            &dist_tol, xyzminmax, &(thee->np));


    Vnm_print(0, "treesetup:  Initializing levels...\n");
    F77INITLEVELS(&minlevel, &maxlevel);

    Vnm_print(0, "treesetup:  Creating tree...\n");
    F77CREATE_TREE(&one, &(thee->np), thee->xp, thee->yp, thee->zp, thee->qp, 
      &shrink, &maxparnode, xyzminmax, &level, &(thee->np));

    return 1;

#else /* ifdef HAVE_TREE */

    Vnm_print(2, "treesetup:  Error!  APBS not linked with treecode!\n");
    return 0;

#endif /* ifdef HAVE_TREE */
}