Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/srefine.c
3206 views
1
/*
2
* Copyright 1997, Regents of the University of Minnesota
3
*
4
* srefine.c
5
*
6
* This file contains code for the separator refinement algortihms
7
*
8
* Started 8/1/97
9
* George
10
*
11
* $Id: srefine.c 10515 2011-07-08 15:46:18Z karypis $
12
*
13
*/
14
15
#include "metislib.h"
16
17
18
/*************************************************************************/
19
/*! This function is the entry point of the separator refinement.
20
It does not perform any refinement on graph, but it starts by first
21
projecting it to the next level finer graph and proceeds from there. */
22
/*************************************************************************/
23
void Refine2WayNode(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph)
24
{
25
26
IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));
27
28
if (graph == orggraph) {
29
Compute2WayNodePartitionParams(ctrl, graph);
30
}
31
else {
32
do {
33
graph = graph->finer;
34
35
IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));
36
Project2WayNodePartition(ctrl, graph);
37
IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));
38
39
IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));
40
FM_2WayNodeBalance(ctrl, graph);
41
42
ASSERT(CheckNodePartitionParams(graph));
43
44
switch (ctrl->rtype) {
45
case METIS_RTYPE_SEP2SIDED:
46
FM_2WayNodeRefine2Sided(ctrl, graph, ctrl->niter);
47
break;
48
case METIS_RTYPE_SEP1SIDED:
49
FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter);
50
break;
51
default:
52
gk_errexit(SIGERR, "Unknown rtype of %d\n", ctrl->rtype);
53
}
54
IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));
55
56
} while (graph != orggraph);
57
}
58
59
IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
60
}
61
62
63
/*************************************************************************/
64
/*! This function allocates memory for 2-way node-based refinement */
65
/**************************************************************************/
66
void Allocate2WayNodePartitionMemory(ctrl_t *ctrl, graph_t *graph)
67
{
68
idx_t nvtxs;
69
70
nvtxs = graph->nvtxs;
71
72
graph->pwgts = imalloc(3, "Allocate2WayNodePartitionMemory: pwgts");
73
graph->where = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: where");
74
graph->bndptr = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: bndptr");
75
graph->bndind = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: bndind");
76
graph->nrinfo = (nrinfo_t *)gk_malloc(nvtxs*sizeof(nrinfo_t), "Allocate2WayNodePartitionMemory: nrinfo");
77
}
78
79
80
/*************************************************************************/
81
/*! This function computes the edegrees[] to the left & right sides */
82
/*************************************************************************/
83
void Compute2WayNodePartitionParams(ctrl_t *ctrl, graph_t *graph)
84
{
85
idx_t i, j, nvtxs, nbnd;
86
idx_t *xadj, *adjncy, *vwgt;
87
idx_t *where, *pwgts, *bndind, *bndptr, *edegrees;
88
nrinfo_t *rinfo;
89
idx_t me, other;
90
91
nvtxs = graph->nvtxs;
92
xadj = graph->xadj;
93
vwgt = graph->vwgt;
94
adjncy = graph->adjncy;
95
96
where = graph->where;
97
rinfo = graph->nrinfo;
98
pwgts = iset(3, 0, graph->pwgts);
99
bndind = graph->bndind;
100
bndptr = iset(nvtxs, -1, graph->bndptr);
101
102
103
/*------------------------------------------------------------
104
/ Compute now the separator external degrees
105
/------------------------------------------------------------*/
106
nbnd = 0;
107
for (i=0; i<nvtxs; i++) {
108
me = where[i];
109
pwgts[me] += vwgt[i];
110
111
ASSERT(me >=0 && me <= 2);
112
113
if (me == 2) { /* If it is on the separator do some computations */
114
BNDInsert(nbnd, bndind, bndptr, i);
115
116
edegrees = rinfo[i].edegrees;
117
edegrees[0] = edegrees[1] = 0;
118
119
for (j=xadj[i]; j<xadj[i+1]; j++) {
120
other = where[adjncy[j]];
121
if (other != 2)
122
edegrees[other] += vwgt[adjncy[j]];
123
}
124
}
125
}
126
127
ASSERT(CheckNodeBnd(graph, nbnd));
128
129
graph->mincut = pwgts[2];
130
graph->nbnd = nbnd;
131
}
132
133
134
/*************************************************************************/
135
/*! This function projects the node-based bisection */
136
/*************************************************************************/
137
void Project2WayNodePartition(ctrl_t *ctrl, graph_t *graph)
138
{
139
idx_t i, j, nvtxs;
140
idx_t *cmap, *where, *cwhere;
141
graph_t *cgraph;
142
143
cgraph = graph->coarser;
144
cwhere = cgraph->where;
145
146
nvtxs = graph->nvtxs;
147
cmap = graph->cmap;
148
149
Allocate2WayNodePartitionMemory(ctrl, graph);
150
where = graph->where;
151
152
/* Project the partition */
153
for (i=0; i<nvtxs; i++) {
154
where[i] = cwhere[cmap[i]];
155
ASSERTP(where[i] >= 0 && where[i] <= 2, ("%"PRIDX" %"PRIDX" %"PRIDX" %"PRIDX"\n",
156
i, cmap[i], where[i], cwhere[cmap[i]]));
157
}
158
159
FreeGraph(&graph->coarser);
160
graph->coarser = NULL;
161
162
Compute2WayNodePartitionParams(ctrl, graph);
163
}
164
165