mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
218 lines
5.9 KiB
C
218 lines
5.9 KiB
C
/*
|
|
* Copyright 1997, Regents of the University of Minnesota
|
|
*
|
|
* refine.c
|
|
*
|
|
* This file contains the driving routines for multilevel refinement
|
|
*
|
|
* Started 7/24/97
|
|
* George
|
|
*
|
|
* $Id: mrefine.c,v 1.2 2002/08/10 06:29:33 karypis Exp $
|
|
*/
|
|
|
|
#include <metislib.h>
|
|
|
|
|
|
/*************************************************************************
|
|
* This function is the entry point of refinement
|
|
**************************************************************************/
|
|
void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor)
|
|
{
|
|
idxtype i;
|
|
float tubvec[MAXNCON];
|
|
|
|
for (i=0; i<graph->ncon; i++)
|
|
tubvec[i] = 1.0;
|
|
|
|
IFSET(ctrl->dbglvl, DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));
|
|
|
|
/* Compute the parameters of the coarsest graph */
|
|
MocCompute2WayPartitionParams(ctrl, graph);
|
|
|
|
for (;;) {
|
|
ASSERT(CheckBnd(graph));
|
|
|
|
IFSET(ctrl->dbglvl, DBG_TIME, gk_startcputimer(ctrl->RefTmr));
|
|
switch (ctrl->RType) {
|
|
case RTYPE_FM:
|
|
MocBalance2Way(ctrl, graph, tpwgts, 1.03);
|
|
MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8);
|
|
break;
|
|
case 2:
|
|
MocBalance2Way(ctrl, graph, tpwgts, 1.03);
|
|
MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8);
|
|
break;
|
|
default:
|
|
errexit("Unknown refinement type: %d\n", ctrl->RType);
|
|
}
|
|
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));
|
|
MocProject2WayPartition(ctrl, graph);
|
|
IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));
|
|
}
|
|
|
|
MocBalance2Way(ctrl, graph, tpwgts, 1.01);
|
|
MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8);
|
|
|
|
IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* This function allocates memory for 2-way edge refinement
|
|
**************************************************************************/
|
|
void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
|
|
{
|
|
idxtype nvtxs, ncon;
|
|
|
|
nvtxs = graph->nvtxs;
|
|
ncon = graph->ncon;
|
|
|
|
graph->npwgts = gk_fmalloc(2*ncon, "MocAllocate2WayPartitionMemory: npwgts");
|
|
graph->where = idxmalloc(nvtxs, "MocAllocate2WayPartitionMemory: where");
|
|
graph->id = idxmalloc(nvtxs, "MocAllocate2WayPartitionMemory: id");
|
|
graph->ed = idxmalloc(nvtxs, "MocAllocate2WayPartitionMemory: ed");
|
|
graph->bndptr = idxmalloc(nvtxs, "MocAllocate2WayPartitionMemory: bndptr");
|
|
graph->bndind = idxmalloc(nvtxs, "MocAllocate2WayPartitionMemory: bndind");
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* This function computes the initial id/ed
|
|
**************************************************************************/
|
|
void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
|
|
{
|
|
idxtype i, j, k, l, nvtxs, ncon, nbnd, mincut;
|
|
idxtype *xadj, *adjncy, *adjwgt;
|
|
float *nvwgt, *npwgts;
|
|
idxtype *id, *ed, *where;
|
|
idxtype *bndptr, *bndind;
|
|
idxtype me, other;
|
|
|
|
nvtxs = graph->nvtxs;
|
|
ncon = graph->ncon;
|
|
xadj = graph->xadj;
|
|
nvwgt = graph->nvwgt;
|
|
adjncy = graph->adjncy;
|
|
adjwgt = graph->adjwgt;
|
|
|
|
where = graph->where;
|
|
npwgts = gk_fset(2*ncon, 0.0, graph->npwgts);
|
|
id = idxset(nvtxs, 0, graph->id);
|
|
ed = idxset(nvtxs, 0, graph->ed);
|
|
bndptr = idxset(nvtxs, -1, graph->bndptr);
|
|
bndind = graph->bndind;
|
|
|
|
|
|
/*------------------------------------------------------------
|
|
/ Compute now the id/ed degrees
|
|
/------------------------------------------------------------*/
|
|
nbnd = mincut = 0;
|
|
for (i=0; i<nvtxs; i++) {
|
|
ASSERT(where[i] >= 0 && where[i] <= 1);
|
|
me = where[i];
|
|
gk_faxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
|
|
|
|
for (j=xadj[i]; j<xadj[i+1]; j++) {
|
|
if (me == where[adjncy[j]])
|
|
id[i] += adjwgt[j];
|
|
else
|
|
ed[i] += adjwgt[j];
|
|
}
|
|
|
|
if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
|
|
mincut += ed[i];
|
|
bndptr[i] = nbnd;
|
|
bndind[nbnd++] = i;
|
|
}
|
|
}
|
|
|
|
graph->mincut = mincut/2;
|
|
graph->nbnd = nbnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
* This function projects a partition, and at the same time computes the
|
|
* parameters for refinement.
|
|
**************************************************************************/
|
|
void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph)
|
|
{
|
|
idxtype i, j, k, nvtxs, nbnd, me;
|
|
idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
|
|
idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
|
|
idxtype *cwhere, *cid, *ced, *cbndptr;
|
|
GraphType *cgraph;
|
|
|
|
cgraph = graph->coarser;
|
|
cwhere = cgraph->where;
|
|
cid = cgraph->id;
|
|
ced = cgraph->ed;
|
|
cbndptr = cgraph->bndptr;
|
|
|
|
nvtxs = graph->nvtxs;
|
|
cmap = graph->cmap;
|
|
xadj = graph->xadj;
|
|
adjncy = graph->adjncy;
|
|
adjwgt = graph->adjwgt;
|
|
adjwgtsum = graph->adjwgtsum;
|
|
|
|
MocAllocate2WayPartitionMemory(ctrl, graph);
|
|
|
|
where = graph->where;
|
|
id = idxset(nvtxs, 0, graph->id);
|
|
ed = idxset(nvtxs, 0, graph->ed);
|
|
bndptr = idxset(nvtxs, -1, graph->bndptr);
|
|
bndind = graph->bndind;
|
|
|
|
|
|
/* 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] = cbndptr[k];
|
|
}
|
|
|
|
for (nbnd=0, i=0; i<nvtxs; i++) {
|
|
me = where[i];
|
|
|
|
id[i] = adjwgtsum[i];
|
|
|
|
if (xadj[i] == xadj[i+1]) {
|
|
bndptr[i] = nbnd;
|
|
bndind[nbnd++] = i;
|
|
}
|
|
else {
|
|
if (cmap[i] != -1) { /* If it is an interface node. Note that cmap[i] = cbndptr[cmap[i]] */
|
|
for (j=xadj[i]; j<xadj[i+1]; j++) {
|
|
if (me != where[adjncy[j]])
|
|
ed[i] += adjwgt[j];
|
|
}
|
|
id[i] -= ed[i];
|
|
|
|
if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
|
|
bndptr[i] = nbnd;
|
|
bndind[nbnd++] = i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
graph->mincut = cgraph->mincut;
|
|
graph->nbnd = nbnd;
|
|
gk_fcopy(2*graph->ncon, cgraph->npwgts, graph->npwgts);
|
|
|
|
FreeGraph(graph->coarser, 1);
|
|
graph->coarser = NULL;
|
|
|
|
}
|
|
|