Пример #1
0
/*
 * ***************************************************************************
 * Routine:  Vcom_dtor
 *
 * Purpose:  Destroy the communications object
 *
 * Author:   Nathan Baker and Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Vcom_dtor(Vcom **thee)
{
    if ((*thee) != VNULL) {
        Vcom_dtor2(*thee);
        Vmem_free( VNULL, 1, sizeof(Vcom_core), (void**)&((*thee)->core) );
        Vmem_free( VNULL, 1, sizeof(Vcom), (void**)thee );
    }
}
Пример #2
0
/*
 * ***************************************************************************
 * Routine:  Mat_killStructureLN
 *
 * Purpose:  Kill the nonzero structure and structure information.
 *
 * Notes:    This routine does the reverse of Mat_initStructureLN
 *           (or Mat_copyStructureLN).  It leaves only the information
 *           about the number of blocks, number of rows, and number of
 *           columns per block.  I.e., what is left is only what was
 *           present after the initial call to Mat_ctor.
 *
 * Author:   Stephen Bond and Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Mat_killStructureLN(Mat *thee)
{
    if (thee != VNULL) {
        if (thee->state != NULL_STATE) {

            /* Format-dependent destruction */
            switch (thee->format) {

              case RLN_FORMAT:
                if (thee->lnkU != VNULL) {
                    Vset_dtor( &(thee->lnkU) );
                }
                break;

              case CLN_FORMAT:
                if (thee->lnkL != VNULL) {
                    Vset_dtor( &(thee->lnkL) );
                }
                break;

              case XLN_FORMAT:
                if (thee->lnkU != VNULL)
                    Vset_dtor( &(thee->lnkU) );

                if (thee->xln != VNULL) {
                    if ( Mat_sym(thee) == ISNOT_SYM ) {
                        Vmem_free( thee->vmem, thee->numA, sizeof(LinkRC*),
                                   (void**)&(thee->xln));
                    } else {
                        Vmem_free( thee->vmem, thee->numA, sizeof(LinkRCS),
                                   (void**)&(thee->xln));
                    }
                }

                thee->numA = 0;
                break;

              default:
                VASSERT(0);
                break;
            }

            /* initialize the state */
            thee->state = NULL_STATE;

        }
    }
}
Пример #3
0
VPUBLIC void Vgreen_dtor(Vgreen **thee) {
    if ((*thee) != VNULL) {
        Vgreen_dtor2(*thee);
        Vmem_free(VNULL, 1, sizeof(Vgreen), (void **)thee);
        (*thee) = VNULL;
    }
}
Пример #4
0
/*
 * ***************************************************************************
 * Routine:  Bmat_dtor
 *
 * Purpose:  The block sparse matrix destructor.
 *
 * Notes:    This destructor does the reverse of Bmat_ctor, and if 
 *           necessary first reverses Bmat_initStructure
 *           (or Bmat_copyStructure).  I.e., if necessary,
 *           it first frees the large integer and real arrays created by
 *           Bmat_initStructure or Bmat_copyStructure, and then frees the
 *           Bmat object itself at the last moment.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Bmat_dtor(Bmat **thee)
{
    int p, q;

    /* VASSERT( (*thee) != VNULL ); */
    if ((*thee) != VNULL) {

        /* first free any coarse guy */
        if ( (*thee)->coarse != VNULL ) {
            Bmat_dtor( &((*thee)->coarse) );
        }

        /* next free the large integer and real nonzero structure */
        Bmat_killStructure(*thee);

        /* kill the submatrices themselves */
        Mat_dtor( &((*thee)->AG) );
        for (p=0; p<(*thee)->numB; p++) {
            for (q=0; q<(*thee)->numB; q++) {
                if ( !(*thee)->mirror[p][q] ) {
                    Mat_dtor( &((*thee)->AD[p][q]) );
                }
            }
        }

        /* now kill the object itself */
        VDEBUGIO("Bmat_dtor: DESTROYING object..");
        if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
        Vmem_free( VNULL, 1, sizeof(Bmat), (void**)thee );
        VDEBUGIO("..done.\n");

        (*thee) = VNULL;
    }
}
Пример #5
0
VPUBLIC void BEMparm_dtor(BEMparm **thee) {
    if ((*thee) != VNULL) {
        BEMparm_dtor2(*thee);
        Vmem_free(VNULL, 1, sizeof(BEMparm), (void **)thee);
        (*thee) = VNULL;
    }
}
Пример #6
0
VPUBLIC void Vcsm_dtor(Vcsm **thee) {
    if ((*thee) != VNULL) {
        Vcsm_dtor2(*thee);
        Vmem_free(VNULL, 1, sizeof(Vcsm), (void **)thee);
        (*thee) = VNULL;
    }
}
Пример #7
0
/*
 * ***************************************************************************
 * Routine:  Gem_dtor
 *
 * Purpose:  Geometry manager destructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Gem_dtor(Gem **thee)
{
    int i;

    VASSERT( (*thee) != VNULL );
    if ((*thee) != VNULL) {

        if ((*thee)->iMadePDE) {
            PDE_dtor_default( &((*thee)->pde) );
        }

        Vset_dtor( &((*thee)->vertices) );
        Vset_dtor( &((*thee)->edges) );
        Vset_dtor( &((*thee)->simplices) );
        for (i=0; i<VMAXSQ; i++) {
            Vset_dtor( &((*thee)->sQueM[i]) );
        }

        VDEBUGIO("Gem_dtor: DESTROYING object..");
        if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
        Vmem_free( VNULL, 1, sizeof(Gem), (void**)thee );
        VDEBUGIO("..done.\n");

        (*thee) = VNULL;
    }
}
Пример #8
0
/* Main (stub) destructor */
VPUBLIC void VclistCell_dtor2(VclistCell *thee) {

    if (thee->natoms > 0) {
        Vmem_free(VNULL, thee->natoms, sizeof(Vatom *), 
                (void **)&(thee->atoms));
    }

}
Пример #9
0
/*
 * ***************************************************************************
 * Routine:  Vmem_realloc
 *
 * Purpose:  A logged version of realloc (using this is usually a bad idea).
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void *Vmem_realloc(Vmem *thee, size_t num, size_t size, void **ram,
    size_t newNum)
{
    void *tee = Vmem_malloc(thee, newNum, size);
    memcpy(tee, (*ram), size*VMIN2(num,newNum));
    Vmem_free(thee, num, size, ram);
    return tee;
}
Пример #10
0
/* ///////////////////////////////////////////////////////////////////////////
// Routine:  Vopot_dtor
// Author:   Nathan Baker
/////////////////////////////////////////////////////////////////////////// */
VPUBLIC void Vopot_dtor(Vopot **thee) {

    if ((*thee) != VNULL) {
        Vopot_dtor2(*thee);
        Vmem_free(VNULL, 1, sizeof(Vopot), (void **)thee);
        (*thee) = VNULL;
    }
}
Пример #11
0
VPUBLIC void VclistCell_dtor(VclistCell **thee) {
    
    if ((*thee) != VNULL) {
        VclistCell_dtor2(*thee);
        Vmem_free(VNULL, 1, sizeof(VclistCell), (void **)thee);
        (*thee) = VNULL;
    }

}
Пример #12
0
/* ///////////////////////////////////////////////////////////////////////////
// Routine:  Vpee_dtor
//
// Author:   Nathan Baker
/////////////////////////////////////////////////////////////////////////// */
VPUBLIC void Vpee_dtor(Vpee **thee) {

    if ((*thee) != VNULL) {
        Vpee_dtor2(*thee);
        Vmem_free(VNULL, 1, sizeof(Vpee), (void **)thee);
        (*thee) = VNULL;
    }

}
Пример #13
0
/*
 * ***************************************************************************
 * Routine:  PDE_dtor_default
 *
 * Purpose:  Destroy a fake differential equation object.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void PDE_dtor_default(PDE **thee)
{
    VASSERT( (*thee) != VNULL );
    if ((*thee) != VNULL) {

        Vmem_free( VNULL, 1, sizeof(PDE), (void**)thee );

        (*thee) = VNULL;
    }
}
Пример #14
0
VPRIVATE int treecleanup(Vgreen *thee) {

#ifdef HAVE_TREE

    Vmem_free(thee->vmem, thee->np, sizeof(double), (void **)&(thee->xp));
    Vmem_free(thee->vmem, thee->np, sizeof(double), (void **)&(thee->yp));
    Vmem_free(thee->vmem, thee->np, sizeof(double), (void **)&(thee->zp));
    Vmem_free(thee->vmem, thee->np, sizeof(double), (void **)&(thee->qp));
    F77CLEANUP();

    return 1;

#else /* ifdef HAVE_TREE */

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

#endif /* ifdef HAVE_TREE */
}
Пример #15
0
/*
 * ***************************************************************************
 * Routine:  Vmpi_dtor
 *
 * Purpose:  The Vmpi destructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Vmpi_dtor(Vmpi **thee)
{
    VDEBUGIO("Vmpi_dtor: DESTROYING object..");
    Vmem_free( VNULL, 1, sizeof(Vmpi), (void**)thee );
#if defined(HAVE_MPI_H)
#if 0
    VASSERT( MPI_SUCCESS == MPI_Finalize() );
#endif
#endif
    VDEBUGIO("..done.\n");
}
Пример #16
0
/*
 * ***************************************************************************
 * Routine:  Vcom_ctor
 *
 * Purpose:  Construct the communications object
 *
 * Notes:    This routine sets up data members of class and initializes MPI.  
 *
 * Author:   Nathan Baker and Michael Holst
 * ***************************************************************************
 */
VPUBLIC Vcom* Vcom_ctor(int commtype)
{
    int rc;
    Vcom *thee = VNULL;

    /* Set up the structure */
    thee       = Vmem_malloc( VNULL, 1, sizeof(Vcom) );
    thee->core = Vmem_malloc( VNULL, 1, sizeof(Vcom_core) );
    
    /* Call the real constructor */
    rc = Vcom_ctor2(thee, commtype);

    /* Destroy the guy if something went wrong */
    if (rc == 0) {
        Vmem_free( VNULL, 1, sizeof(Vcom_core), (void**)&(thee->core) );
        Vmem_free( VNULL, 1, sizeof(Vcom), (void**)&thee );
    }
 
    return thee;
}
Пример #17
0
/* ///////////////////////////////////////////////////////////////////////////
// Routine:  PDE_dtor
//
// Purpose:  Destroy the differential equation object.
//
// Speed:    This function is called by MC one time during shutdown,
//           and does not have to be particularly fast.
//
// Author:   Michael Holst
/////////////////////////////////////////////////////////////////////////// */
VPUBLIC void myPDE_dtor(PDE **thee)
{
    VASSERT( (*thee) != VNULL );
    if ((*thee) != VNULL) {

        PDE_killDyn( *thee );

        Vmem_free( VNULL, 1, sizeof(PDE), (void**)thee );

        (*thee) = VNULL;
    }
}
Пример #18
0
VPUBLIC void Vcsm_dtor2(Vcsm *thee) { 
    int i;

    if ((thee != VNULL) && thee->initFlag) {

        for (i=0; i<thee->msimp; i++) {
            if (thee->nsqm[i] > 0) Vmem_free(thee->vmem, thee->nsqm[i], 
              sizeof(int), (void **)&(thee->sqm[i]));
        }
        for (i=0; i<thee->natom; i++) {
            if (thee->nqsm[i] > 0) Vmem_free(thee->vmem, thee->nqsm[i], 
              sizeof(int), (void **)&(thee->qsm[i]));
        }
        Vmem_free(thee->vmem, thee->msimp, sizeof(int *), 
          (void **)&(thee->sqm));
        Vmem_free(thee->vmem, thee->msimp, sizeof(int),
          (void **)&(thee->nsqm));
        Vmem_free(thee->vmem, thee->natom, sizeof(int *), 
          (void **)&(thee->qsm));
        Vmem_free(thee->vmem, thee->natom, sizeof(int),
          (void **)&(thee->nqsm));

    }
    Vmem_dtor(&(thee->vmem));
}
Пример #19
0
VPUBLIC int Vgreen_coulomb(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;

#ifdef HAVE_TREE  

    /* Allocate charge array (if necessary) */
    if (Valist_getNumberAtoms(thee->alist) > 1) {
        if (npos > 1) {
            q = VNULL;
            q = Vmem_malloc(thee->vmem, npos, sizeof(double));
            if (q == VNULL) {
                Vnm_print(2, "Vgreen_coulomb:  Error allocating charge array!\n");
                return 0;
            }
        } else {
            q = &(qtemp);
        }
        for (ipos=0; ipos<npos; ipos++) q[ipos] = 1.0;
    
        /* Calculate */
        treecalc(thee, x, y, z, q, npos, val, thee->xp, thee->yp, thee->zp,
          thee->qp, thee->np, &fx, &fy, &fz, 1, 1, thee->np);
    } else return Vgreen_coulomb_direct(thee, npos, x, y, z, val);

    /* De-allocate charge array (if necessary) */
    if (npos > 1) Vmem_free(thee->vmem, npos, sizeof(double), (void **)&q);
    
    scale = Vunit_ec/(4*Vunit_pi*Vunit_eps0*1.0e-10);
    for (ipos=0; ipos<npos; ipos++) val[ipos] = val[ipos]*scale;

    return 1;

#else /* ifdef HAVE_TREE */

    return Vgreen_coulomb_direct(thee, npos, x, y, z, val);

#endif

}
Пример #20
0
/* Main (stub) destructor */
VPUBLIC void Vclist_dtor2(Vclist *thee) {

    VclistCell *cell;
    int i;

    for (i=0; i<thee->n; i++) {
        cell = &(thee->cells[i]);
        VclistCell_dtor2(cell);
    }
    Vmem_free(thee->vmem, thee->n, sizeof(VclistCell), 
            (void **)&(thee->cells));
    Vmem_dtor(&(thee->vmem));

}
Пример #21
0
/*
 * ***************************************************************************
 * Routine:  MCsh_dtor
 *
 * Purpose:  The MCsh destructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void MCsh_dtor(MCsh **thee)
{
    VASSERT( (*thee) != VNULL );
    if ((*thee) != VNULL) {

        AM_dtor(   &((*thee)->am) );
        Aprx_dtor( &((*thee)->aprx) );
        Gem_dtor(  &((*thee)->gm) );
        Vsh_dtor(  &((*thee)->vsh) );

        VDEBUGIO("MCsh_dtor: DESTROYING object..");
        Vmem_dtor( &((*thee)->vmem) );
        Vmem_free( VNULL, 1, sizeof(MCsh), (void**)thee );
        VDEBUGIO("..done.\n");

        (*thee) = VNULL;
    }
}
Пример #22
0
/*
 * ***************************************************************************
 * Routine:  Bnode_dtor
 *
 * Purpose:  The Block node destructor.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Bnode_dtor(Bnode **thee)
{
    int i;

    /* VASSERT( (*thee) != VNULL ); */
    if ((*thee) != VNULL) {

        for (i=0; i<(*thee)->numB; i++) {
            Node_dtor( (&(*thee)->ND[i]) );
        }

        VDEBUGIO("Bnode_dtor: DESTROYING object..");
        if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
        Vmem_free( VNULL, 1, sizeof(Bnode), (void**)thee );
        VDEBUGIO("..done.\n"); 

        (*thee) = VNULL;
    }
}
Пример #23
0
/*
 * ***************************************************************************
 * Routine:  Slu_dtor
 *
 * Purpose:  The Slu destructor.
 *
 * Author:   Michael Holst and Stephen Bond
 * ***************************************************************************
 */
VPUBLIC void Slu_dtor(Slu **thee)
{
    VASSERT( (*thee) != VNULL );
    if ((*thee) != VNULL) {

        /* destroy the factorization */
        if( (*thee)->statLU == 1 ) {
            umfpack_di_free_numeric( &((*thee)->work) );
            (*thee)->statLU = 0;
        }

        /* finally destroy this container */
        VDEBUGIO("Slu_dtor: DESTROYING object..");
        if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
        Vmem_free( VNULL, 1, sizeof(Slu), (void**)thee );
        VDEBUGIO("..done.\n");

        (*thee) = VNULL;

    }
}
Пример #24
0
VPUBLIC int Vgreen_coulombD(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;
    }

#ifdef HAVE_TREE

    if (Valist_getNumberAtoms(thee->alist) > 1) {
        if (npos > 1) {
            q = VNULL;
            q = Vmem_malloc(thee->vmem, npos, sizeof(double));
            if (q == VNULL) {
                Vnm_print(2, "Vgreen_coulomb:  Error allocating charge array!\n");
                return 0;
            }
        } else {
            q = &(qtemp);
        }
        for (ipos=0; ipos<npos; ipos++) q[ipos] = 1.0;
    
        /* Calculate */
        treecalc(thee, x, y, z, q, npos, pot, thee->xp, thee->yp, thee->zp,
                thee->qp, thee->np, gradx, grady, gradz, 2, npos, thee->np);
    
        /* De-allocate charge array (if necessary) */
        if (npos > 1) Vmem_free(thee->vmem, npos, sizeof(double), (void **)&q);
    } else return Vgreen_coulombD_direct(thee, npos, x, y, z, pot, 
            gradx, grady, gradz);

    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;

#else /* ifdef HAVE_TREE */

    return Vgreen_coulombD_direct(thee, npos, x, y, z, pot, 
            gradx, grady, gradz);

#endif
  
}
Пример #25
0
/*
 * ***************************************************************************
 * Routine:  Vmem_dtor
 *
 * Purpose:  Destruct the dynamic memory allocation logging object.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Vmem_dtor(Vmem **thee)
{
    Vmem_free( VNULL, 1, sizeof(Vmem), (void**)thee );
}
Пример #26
0
/*
 * ***************************************************************************
 * Routine:  Aprx_partOne
 *
 * Purpose:  Do a single bisection step.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC int Aprx_partOne(Aprx *thee, int pkey, int pwht, int pcolor, int poff)
{
    int i, j, k, ii, dim, rc, numC, numS, sCount1, sCount2, cutOff;
    int *pord, *ford, *rord;
    double tm, cm[3], *evec, eCount1, eCount2, ecutOff, ePart;
    simHelper *simH;
    SS *sm;

    Vnm_print(0,"Aprx_partOne: [pcolor=%d] partitioning:\n", pcolor);

    /* dimensions */
    dim  = Gem_dim(thee->gm);
    numS = Gem_numSS(thee->gm);

    /* how many guys of this color */
    numC = 0;
    for (i=0; i<numS; i++) {
        sm = Gem_SS(thee->gm,i);
        if ((int)SS_chart(sm) == pcolor) numC++;
    }

    /* grab some temporary storage */
    pord = Vmem_malloc( thee->vmem, numC, sizeof(int) );
    ford = Vmem_malloc( thee->vmem, numC, sizeof(int) );
    rord = Vmem_malloc( thee->vmem, numS, sizeof(int) );
    evec = Vmem_malloc( thee->vmem, numC, sizeof(double) );
    simH = Vmem_malloc( thee->vmem, numC, sizeof(simHelper) );

    /* build the simplex helper vector and forward/reverse ordering arrays */
    ePart = 0.;
    tm = 0.;
    for (i=0; i<3; i++) cm[i] = 0.;
    i = 0;
    for (ii=0; ii<Gem_numSS(thee->gm); ii++) {
        sm = Gem_SS(thee->gm,ii);
        if ((int)SS_chart(sm) == pcolor) {

            /* initialization */
            pord[i] = i;
            ford[i] = ii;
            rord[ii] = i;
            evec[i] = 0.;
            simH[i].color = SS_chart(sm);
            simH[i].diag  = 0;
            simH[i].mass  = 1.;
            simH[i].error = Bvec_valB( thee->wev, 0, ii );
            for (j=0; j<4; j++) {
                simH[i].faceId[j] = -1;
            }

            /* accumulate error into total for this partition */
            ePart += simH[i].error;

            /* baricenter of this simplex and center of mass of all */
            tm += simH[i].mass;
            for (j=0; j<3; j++) {
                simH[i].bc[j] = 0.;
                for (k=0; k<dim+1; k++) {
                    simH[i].bc[j] += VV_coord(SS_vertex(sm,k),j);
                }
                simH[i].bc[j] /= (dim+1.);
                cm[j] += (simH[i].mass * simH[i].bc[j]);
            }

            i++;
        } else {
            rord[ii] = -1;
        }
    }
    VASSERT( i == numC );
    for (i=0; i<3; i++) cm[i] /= tm;

    /* translate coordinate systems so center of mass is at origin */
    for (i=0; i<numC; i++) {
        for (j=0; j<3; j++) {
            simH[i].bc[j] -= cm[j];
        }
    }

    /* okay partition it */
    if (pkey == 0) {
        rc = Aprx_partInert(thee, pcolor, numC, evec, simH);
    } else if (pkey == 1) {
        rc = Aprx_partSpect(thee, pcolor, numC, evec, simH, ford, rord, 0);
    } else if (pkey == 2) {
        rc = Aprx_partSpect(thee, pcolor, numC, evec, simH, ford, rord, 1);
    } else if (pkey == 3) {
        rc = Aprx_partInert(thee, pcolor, numC, evec, simH);
        rc = Aprx_partSpect(thee, pcolor, numC, evec, simH, ford, rord, 0);
    } else {
        Vnm_print(2,"Aprx_partOne: illegal pkey value of <%d>\n", pkey);
        rc = -1;
    }

    /* sort the values small-to-big; allows us to have equi-size submeshes */
    Vnm_dqsortOrd(evec, pord, numC);

    /* color the mesh using the ordering given by the eigenvector */
    sCount1 = 0;
    sCount2 = 0;
    eCount1 = 0.;
    eCount2 = 0.;
    if (rc >= 0) {

        /* weighted partitioning; divides into two sets of equal error */
        if (pwht == 1) {
            ecutOff = ( ePart / 2. );
            for (i=0; i<numC; i++) {
                sm = Gem_SS(thee->gm,ford[pord[i]]);
                if (eCount1 < ecutOff) {
                    SS_setChart( sm, pcolor );
                    sCount1++;
                    eCount1 += Bvec_valB( thee->wev, 0, ford[pord[i]] );
                } else {
                    SS_setChart( sm, pcolor+poff );
                    sCount2++;
                    eCount2 += Bvec_valB( thee->wev, 0, ford[pord[i]] );
                }
            }

        /* unweighted partitioning; divides into two sets of equal number */
        } else {
            cutOff = numC / 2;
            for (i=0; i<numC; i++) {
                sm = Gem_SS(thee->gm,ford[pord[i]]);
                if (sCount1 < cutOff) {
                    SS_setChart( sm, pcolor );
                    sCount1++;
                    eCount1 += Bvec_valB( thee->wev, 0, ford[pord[i]] );
                } else {
                    SS_setChart( sm, pcolor+poff );
                    sCount2++;
                    eCount2 += Bvec_valB( thee->wev, 0, ford[pord[i]] );
                }
            }
        }
    }

    /* free the temporary storage */
    Vmem_free( thee->vmem, numC, sizeof(int), (void**)&pord );
    Vmem_free( thee->vmem, numC, sizeof(int), (void**)&ford );
    Vmem_free( thee->vmem, numS, sizeof(int), (void**)&rord );
    Vmem_free( thee->vmem, numC, sizeof(double), (void**)&evec );
    Vmem_free( thee->vmem, numC, sizeof(simHelper), (void**)&simH );

    Vnm_print(0,"Aprx_partOne: done.");
    Vnm_print(0,"  [c1=%d,c2=%d,e1=%8.2e,e2=%8.2e,eT=%8.2e]\n",
        sCount1, sCount2, eCount1, eCount2, (eCount1+eCount2));

    if (sCount1 == 0) {
      Vnm_print(2,"Aprx_partOne: ERROR: first partition has NO SIMPLICES!\n");
    }
    if (sCount2 == 0) {
      Vnm_print(2,"Aprx_partOne: ERROR: second partition has NO SIMPLICES!\n");
    }

    return rc;
}
Пример #27
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;


}
Пример #28
0
/*
 * ***************************************************************************
 * Routine:  Gem_speedChk
 *
 * Purpose:  Calculate the cost to traverse the various structures.
 *
 * Author:   Michael Holst
 * ***************************************************************************
 */
VPUBLIC void Gem_speedChk(Gem *thee)
{
    const int N = 100000;
    const int loop = 1000;
    int i, j, itotal;
    double rtotal;
    double *d0;
    int *i0;
    VV *v0, *vx;

    Vnm_print(0,"Gem_speedChk: Creating normal double vec...\n");
    Vnm_tstart(90, "double vec creation");
    d0 = Vmem_malloc( thee->vmem, N, sizeof(double) );
    Vnm_tstop(90, "double vec creation");

    Vnm_print(0,"Gem_speedChk: Creating normal int vec...\n");
    Vnm_tstart(90, "int vec creation");
    i0 = Vmem_malloc( thee->vmem, N, sizeof(int) );
    Vnm_tstop(90, "int vec creation");

    Vnm_print(0,"Gem_speedChk: Creating normal VV vec...\n");
    Vnm_tstart(90, "VV vec creation");
    v0 = Vmem_malloc( thee->vmem, N, sizeof(VV) );
    Vnm_tstop(90, "VV vec creation");

    Vnm_print(0,"Gem_speedChk: Creating Vset VV vec...\n");
    Vnm_tstart(90, "VV Vset creation");
    for (i=0; i<N; i++)
        vx = Gem_createAndInitVV(thee);
    Vnm_tstop(90, "VV Vset creation");

    Vnm_print(0,"Gem_speedChk: Looping over double vec...\n");
    Vnm_print(0,"Gem_speedChk: N, loop = %d, %d\n", N, loop);
    Vnm_tstart(90, "double vec loop");
    rtotal = 0.0;
    for (j=0; j<loop; j++)
        for (i=0; i<N; i++)
            rtotal += ( j * d0[i] * (j+d0[i]) );
    Vnm_tstop(90, "double vec loop");

    Vnm_print(0,"Gem_speedChk: Looping over int vec...\n");
    Vnm_print(0,"Gem_speedChk: N, loop = %d, %d\n", N, loop);
    Vnm_tstart(90, "int vec loop");
    itotal = 0;
    for (j=0; j<loop; j++)
        for (i=0; i<N; i++)
            itotal += ( j * i0[i] * (j+i0[i]) );
    Vnm_tstop(90, "int vec loop");

    Vnm_print(0,"Gem_speedChk: Looping over VV vec...\n");
    Vnm_print(0,"Gem_speedChk: N, loop = %d, %d\n", N, loop);
    Vnm_tstart(90, "VV vec loop");
    itotal = 0;
    for (j=0; j<loop; j++)
        for (i=0; i<N; i++)
            itotal += ( j * VV_id(&v0[i]) * (j+VV_id(&v0[i])) );
    Vnm_tstop(90, "VV vec loop");

    Vnm_print(0,"Gem_speedChk: Looping (index) over Vset VV vec...\n");
    Vnm_print(0,"Gem_speedChk: N, loop = %d, %d\n", N, loop);
    Vnm_tstart(90, "VV Vset loop");
    itotal = 0;
    for (j=0; j<loop; j++)
        for (i=0; i<N; i++)
            itotal += ( j * VV_id(Gem_VV(thee,i)) 
                     * (j + VV_id(Gem_VV(thee,i)) ) );
    Vnm_tstop(90, "VV Vset loop");

    Vnm_print(0,"Gem_speedChk: Looping (iterator) over Vset VV vec...\n");
    Vnm_print(0,"Gem_speedChk: N, loop = %d, %d\n", N, loop);
    Vnm_tstart(90, "VV Vset loop");
    itotal = 0;
    for (j=0; j<loop; j++)
        for (vx=Gem_firstVV(thee);vx!=VNULL;vx=Gem_nextVV(thee))
            itotal += ( j * VV_id(vx) * (j + VV_id(vx)) );
    Vnm_tstop(90, "VV Vset loop");

    Vnm_print(0,"Gem_speedChk: Freeing normal double vec...\n");
    Vnm_tstart(90, "Free double vec");
    Vmem_free( thee->vmem, N, sizeof(double), (void**)&d0 );
    Vnm_tstop(90, "Free double vec");

    Vnm_print(0,"Gem_speedChk: Freeing normal int vec...\n");
    Vnm_tstart(90, "Free int vec");
    Vmem_free( thee->vmem, N, sizeof(int), (void**)&i0 );
    Vnm_tstop(90, "Free int vec");

    Vnm_print(0,"Gem_speedChk: Freeing normal VV vec...\n");
    Vnm_tstart(90, "Free VV vec");
    Vmem_free( thee->vmem, N, sizeof(VV), (void**)&v0 );
    Vnm_tstop(90, "Free VV vec");

    Vnm_print(0,"Gem_speedChk: Freeing Vset VV vec...\n");
    Vnm_tstart(90, "Free VV Vset");
    for (i=0; i<N; i++)
        Gem_destroyVV(thee);
    Vnm_tstop(90, "Free VV Vset");
}