mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Creation of OpenFOAM-dev repository 15/04/2008
This commit is contained in:
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright 1997, Regents of the University of Minnesota
|
||||
*
|
||||
* mkwayrefine.c
|
||||
*
|
||||
* This file contains the driving routines for multilevel k-way refinement
|
||||
*
|
||||
* Started 7/28/97
|
||||
* George
|
||||
*
|
||||
* $Id: mkwayrefine.c,v 1.2 2002/08/10 06:29:33 karypis Exp $
|
||||
*/
|
||||
|
||||
#include <metislib.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* This function is the entry point of refinement
|
||||
**************************************************************************/
|
||||
void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, idxtype nparts,
|
||||
float *ubvec)
|
||||
{
|
||||
|
||||
IFSET(ctrl->dbglvl, DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));
|
||||
|
||||
/* Compute the parameters of the coarsest graph */
|
||||
MocComputeKWayPartitionParams(ctrl, graph, nparts);
|
||||
|
||||
for (;;) {
|
||||
IFSET(ctrl->dbglvl, DBG_TIME, gk_startcputimer(ctrl->RefTmr));
|
||||
|
||||
if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
|
||||
MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
|
||||
MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4);
|
||||
ComputeKWayBoundary(ctrl, graph, nparts);
|
||||
}
|
||||
|
||||
MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10);
|
||||
|
||||
IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->RefTmr));
|
||||
|
||||
if (graph == orggraph)
|
||||
break;
|
||||
|
||||
graph = graph->finer;
|
||||
IFSET(ctrl->dbglvl, DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));
|
||||
MocProjectKWayPartition(ctrl, graph, nparts);
|
||||
IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));
|
||||
}
|
||||
|
||||
if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
|
||||
MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
|
||||
MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4);
|
||||
ComputeKWayBoundary(ctrl, graph, nparts);
|
||||
MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10);
|
||||
}
|
||||
|
||||
IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* This function allocates memory for k-way edge refinement
|
||||
**************************************************************************/
|
||||
void MocAllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, idxtype nparts)
|
||||
{
|
||||
idxtype nvtxs, ncon;
|
||||
|
||||
nvtxs = graph->nvtxs;
|
||||
ncon = graph->ncon;
|
||||
|
||||
graph->where = idxmalloc(nvtxs, "MocAllocateKWayPartitionMemory: where");
|
||||
graph->bndptr = idxmalloc(nvtxs, "MocAllocateKWayPartitionMemory: bndptr");
|
||||
graph->bndind = idxmalloc(nvtxs, "MocAllocateKWayPartitionMemory: bndind");
|
||||
|
||||
graph->npwgts = gk_fmalloc(ncon*nparts, "MocAllocateKWayPartitionMemory: npwgts");
|
||||
|
||||
graph->rinfo = (RInfoType *)gk_malloc(nvtxs*sizeof(RInfoType), "MocAllocateKWayPartitionMemory: rinfo");
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* This function computes the initial id/ed
|
||||
**************************************************************************/
|
||||
void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, idxtype nparts)
|
||||
{
|
||||
idxtype i, j, k, l, nvtxs, ncon, nbnd, mincut, me, other;
|
||||
idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr;
|
||||
RInfoType *rinfo, *myrinfo;
|
||||
EDegreeType *myedegrees;
|
||||
float *nvwgt, *npwgts;
|
||||
|
||||
nvtxs = graph->nvtxs;
|
||||
ncon = graph->ncon;
|
||||
xadj = graph->xadj;
|
||||
nvwgt = graph->nvwgt;
|
||||
adjncy = graph->adjncy;
|
||||
adjwgt = graph->adjwgt;
|
||||
|
||||
where = graph->where;
|
||||
npwgts = gk_fset(ncon*nparts, 0.0, graph->npwgts);
|
||||
bndind = graph->bndind;
|
||||
bndptr = idxset(nvtxs, -1, graph->bndptr);
|
||||
rinfo = graph->rinfo;
|
||||
|
||||
|
||||
/*------------------------------------------------------------
|
||||
/ Compute now the id/ed degrees
|
||||
/------------------------------------------------------------*/
|
||||
ctrl->wspace.cdegree = 0;
|
||||
nbnd = mincut = 0;
|
||||
for (i=0; i<nvtxs; i++) {
|
||||
me = where[i];
|
||||
gk_faxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
|
||||
|
||||
myrinfo = rinfo+i;
|
||||
myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
|
||||
myrinfo->edegrees = NULL;
|
||||
|
||||
for (j=xadj[i]; j<xadj[i+1]; j++) {
|
||||
if (me != where[adjncy[j]])
|
||||
myrinfo->ed += adjwgt[j];
|
||||
}
|
||||
myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed;
|
||||
|
||||
if (myrinfo->ed > 0)
|
||||
mincut += myrinfo->ed;
|
||||
|
||||
if (myrinfo->ed-myrinfo->id >= 0)
|
||||
BNDInsert(nbnd, bndind, bndptr, i);
|
||||
|
||||
/* Time to compute the particular external degrees */
|
||||
if (myrinfo->ed > 0) {
|
||||
myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
|
||||
ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
|
||||
|
||||
for (j=xadj[i]; j<xadj[i+1]; j++) {
|
||||
other = where[adjncy[j]];
|
||||
if (me != other) {
|
||||
for (k=0; k<myrinfo->ndegrees; k++) {
|
||||
if (myedegrees[k].pid == other) {
|
||||
myedegrees[k].ed += adjwgt[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == myrinfo->ndegrees) {
|
||||
myedegrees[myrinfo->ndegrees].pid = other;
|
||||
myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
graph->mincut = mincut/2;
|
||||
graph->nbnd = nbnd;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* This function projects a partition, and at the same time computes the
|
||||
* parameters for refinement.
|
||||
**************************************************************************/
|
||||
void MocProjectKWayPartition(CtrlType *ctrl, GraphType *graph, idxtype nparts)
|
||||
{
|
||||
idxtype i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees;
|
||||
idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
|
||||
idxtype *cmap, *where, *bndptr, *bndind;
|
||||
idxtype *cwhere;
|
||||
GraphType *cgraph;
|
||||
RInfoType *crinfo, *rinfo, *myrinfo;
|
||||
EDegreeType *myedegrees;
|
||||
idxtype *htable;
|
||||
|
||||
cgraph = graph->coarser;
|
||||
cwhere = cgraph->where;
|
||||
crinfo = cgraph->rinfo;
|
||||
|
||||
nvtxs = graph->nvtxs;
|
||||
cmap = graph->cmap;
|
||||
xadj = graph->xadj;
|
||||
adjncy = graph->adjncy;
|
||||
adjwgt = graph->adjwgt;
|
||||
adjwgtsum = graph->adjwgtsum;
|
||||
|
||||
MocAllocateKWayPartitionMemory(ctrl, graph, nparts);
|
||||
where = graph->where;
|
||||
rinfo = graph->rinfo;
|
||||
bndind = graph->bndind;
|
||||
bndptr = idxset(nvtxs, -1, graph->bndptr);
|
||||
|
||||
/* Go through and project partition and compute id/ed for the nodes */
|
||||
for (i=0; i<nvtxs; i++) {
|
||||
k = cmap[i];
|
||||
where[i] = cwhere[k];
|
||||
cmap[i] = crinfo[k].ed; /* For optimization */
|
||||
}
|
||||
|
||||
htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts));
|
||||
|
||||
ctrl->wspace.cdegree = 0;
|
||||
for (nbnd=0, i=0; i<nvtxs; i++) {
|
||||
me = where[i];
|
||||
|
||||
myrinfo = rinfo+i;
|
||||
myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
|
||||
myrinfo->edegrees = NULL;
|
||||
|
||||
myrinfo->id = adjwgtsum[i];
|
||||
|
||||
if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */
|
||||
istart = xadj[i];
|
||||
iend = xadj[i+1];
|
||||
|
||||
myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
|
||||
ctrl->wspace.cdegree += iend-istart;
|
||||
|
||||
ndegrees = 0;
|
||||
for (j=istart; j<iend; j++) {
|
||||
other = where[adjncy[j]];
|
||||
if (me != other) {
|
||||
myrinfo->ed += adjwgt[j];
|
||||
if ((k = htable[other]) == -1) {
|
||||
htable[other] = ndegrees;
|
||||
myedegrees[ndegrees].pid = other;
|
||||
myedegrees[ndegrees++].ed = adjwgt[j];
|
||||
}
|
||||
else {
|
||||
myedegrees[k].ed += adjwgt[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
myrinfo->id -= myrinfo->ed;
|
||||
|
||||
/* Remove space for edegrees if it was interior */
|
||||
if (myrinfo->ed == 0) {
|
||||
myrinfo->edegrees = NULL;
|
||||
ctrl->wspace.cdegree -= iend-istart;
|
||||
}
|
||||
else {
|
||||
if (myrinfo->ed-myrinfo->id >= 0)
|
||||
BNDInsert(nbnd, bndind, bndptr, i);
|
||||
|
||||
myrinfo->ndegrees = ndegrees;
|
||||
|
||||
for (j=0; j<ndegrees; j++)
|
||||
htable[myedegrees[j].pid] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gk_fcopy(graph->ncon*nparts, cgraph->npwgts, graph->npwgts);
|
||||
graph->mincut = cgraph->mincut;
|
||||
graph->nbnd = nbnd;
|
||||
|
||||
FreeGraph(graph->coarser, 1);
|
||||
graph->coarser = NULL;
|
||||
|
||||
idxwspacefree(ctrl, nparts);
|
||||
|
||||
ASSERT(CheckBnd2(graph));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* This function computes the boundary definition for balancing
|
||||
**************************************************************************/
|
||||
void MocComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, idxtype nparts)
|
||||
{
|
||||
idxtype i, nvtxs, nbnd;
|
||||
idxtype *bndind, *bndptr;
|
||||
|
||||
nvtxs = graph->nvtxs;
|
||||
bndind = graph->bndind;
|
||||
bndptr = idxset(nvtxs, -1, graph->bndptr);
|
||||
|
||||
|
||||
/* Compute the new boundary */
|
||||
nbnd = 0;
|
||||
for (i=0; i<nvtxs; i++) {
|
||||
if (graph->rinfo[i].ed > 0)
|
||||
BNDInsert(nbnd, bndind, bndptr, i);
|
||||
}
|
||||
|
||||
graph->nbnd = nbnd;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user