Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/macros.h
3206 views
1
/*
2
* Copyright 1997, Regents of the University of Minnesota
3
*
4
* macros.h
5
*
6
* This file contains macros used in multilevel
7
*
8
* Started 9/25/94
9
* George
10
*
11
* $Id: macros.h 10060 2011-06-02 18:56:30Z karypis $
12
*
13
*/
14
15
#ifndef _LIBMETIS_MACROS_H_
16
#define _LIBMETIS_MACROS_H_
17
18
/*************************************************************************
19
* The following macro returns a random number in the specified range
20
**************************************************************************/
21
#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b)))
22
#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b)))
23
#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b)))
24
25
//#define icopy(n, a, b) (idx_t *)memcpy((void *)(b), (void *)(a), sizeof(idx_t)*(n))
26
27
#define HASHFCT(key, size) ((key)%(size))
28
#define SWAP gk_SWAP
29
30
/* gets the appropriate option value */
31
#define GETOPTION(options, idx, defval) \
32
((options) == NULL || (options)[idx] == -1 ? defval : (options)[idx])
33
34
/* converts a user provided ufactor into a real ubfactor */
35
#define I2RUBFACTOR(ufactor) (1.0+0.001*(ufactor))
36
37
/* set/reset the current workspace core */
38
#define WCOREPUSH wspacepush(ctrl)
39
#define WCOREPOP wspacepop(ctrl)
40
41
42
43
/*************************************************************************
44
* These macros insert and remove nodes from a Direct Access list
45
**************************************************************************/
46
#define ListInsert(n, lind, lptr, i) \
47
do { \
48
ASSERT(lptr[i] == -1); \
49
lind[n] = i; \
50
lptr[i] = (n)++;\
51
} while(0)
52
53
#define ListDelete(n, lind, lptr, i) \
54
do { \
55
ASSERT(lptr[i] != -1); \
56
lind[lptr[i]] = lind[--(n)]; \
57
lptr[lind[n]] = lptr[i]; \
58
lptr[i] = -1; \
59
} while(0)
60
61
62
/*************************************************************************
63
* These macros insert and remove nodes from the boundary list
64
**************************************************************************/
65
#define BNDInsert(nbnd, bndind, bndptr, vtx) \
66
ListInsert(nbnd, bndind, bndptr, vtx)
67
68
#define BNDDelete(nbnd, bndind, bndptr, vtx) \
69
ListDelete(nbnd, bndind, bndptr, vtx)
70
71
72
/*************************************************************************
73
* These macros deal with id/ed updating during k-way refinement
74
**************************************************************************/
75
#define UpdateMovedVertexInfoAndBND(i, from, k, to, myrinfo, mynbrs, where, \
76
nbnd, bndptr, bndind, bndtype) \
77
do { \
78
where[i] = to; \
79
myrinfo->ed += myrinfo->id-mynbrs[k].ed; \
80
SWAP(myrinfo->id, mynbrs[k].ed, j); \
81
if (mynbrs[k].ed == 0) \
82
mynbrs[k] = mynbrs[--myrinfo->nnbrs]; \
83
else \
84
mynbrs[k].pid = from; \
85
\
86
/* Update the boundary information. Both deletion and addition is \
87
allowed as this routine can be used for moving arbitrary nodes. */ \
88
if (bndtype == BNDTYPE_REFINE) { \
89
if (bndptr[i] != -1 && myrinfo->ed - myrinfo->id < 0) \
90
BNDDelete(nbnd, bndind, bndptr, i); \
91
if (bndptr[i] == -1 && myrinfo->ed - myrinfo->id >= 0) \
92
BNDInsert(nbnd, bndind, bndptr, i); \
93
} \
94
else { \
95
if (bndptr[i] != -1 && myrinfo->ed <= 0) \
96
BNDDelete(nbnd, bndind, bndptr, i); \
97
if (bndptr[i] == -1 && myrinfo->ed > 0) \
98
BNDInsert(nbnd, bndind, bndptr, i); \
99
} \
100
} while(0)
101
102
103
#define UpdateAdjacentVertexInfoAndBND(ctrl, vid, adjlen, me, from, to, \
104
myrinfo, ewgt, nbnd, bndptr, bndind, bndtype) \
105
do { \
106
idx_t k; \
107
cnbr_t *mynbrs; \
108
\
109
if (myrinfo->inbr == -1) { \
110
myrinfo->inbr = cnbrpoolGetNext(ctrl, adjlen+1); \
111
myrinfo->nnbrs = 0; \
112
} \
113
ASSERT(CheckRInfo(ctrl, myrinfo)); \
114
\
115
mynbrs = ctrl->cnbrpool + myrinfo->inbr; \
116
\
117
/* Update global ID/ED and boundary */ \
118
if (me == from) { \
119
INC_DEC(myrinfo->ed, myrinfo->id, (ewgt)); \
120
if (bndtype == BNDTYPE_REFINE) { \
121
if (myrinfo->ed-myrinfo->id >= 0 && bndptr[(vid)] == -1) \
122
BNDInsert(nbnd, bndind, bndptr, (vid)); \
123
} \
124
else { \
125
if (myrinfo->ed > 0 && bndptr[(vid)] == -1) \
126
BNDInsert(nbnd, bndind, bndptr, (vid)); \
127
} \
128
} \
129
else if (me == to) { \
130
INC_DEC(myrinfo->id, myrinfo->ed, (ewgt)); \
131
if (bndtype == BNDTYPE_REFINE) { \
132
if (myrinfo->ed-myrinfo->id < 0 && bndptr[(vid)] != -1) \
133
BNDDelete(nbnd, bndind, bndptr, (vid)); \
134
} \
135
else { \
136
if (myrinfo->ed <= 0 && bndptr[(vid)] != -1) \
137
BNDDelete(nbnd, bndind, bndptr, (vid)); \
138
} \
139
} \
140
\
141
/* Remove contribution from the .ed of 'from' */ \
142
if (me != from) { \
143
for (k=0; k<myrinfo->nnbrs; k++) { \
144
if (mynbrs[k].pid == from) { \
145
if (mynbrs[k].ed == (ewgt)) \
146
mynbrs[k] = mynbrs[--myrinfo->nnbrs]; \
147
else \
148
mynbrs[k].ed -= (ewgt); \
149
break; \
150
} \
151
} \
152
} \
153
\
154
/* Add contribution to the .ed of 'to' */ \
155
if (me != to) { \
156
for (k=0; k<myrinfo->nnbrs; k++) { \
157
if (mynbrs[k].pid == to) { \
158
mynbrs[k].ed += (ewgt); \
159
break; \
160
} \
161
} \
162
if (k == myrinfo->nnbrs) { \
163
mynbrs[k].pid = to; \
164
mynbrs[k].ed = (ewgt); \
165
myrinfo->nnbrs++; \
166
} \
167
} \
168
\
169
ASSERT(CheckRInfo(ctrl, myrinfo));\
170
} while(0)
171
172
173
#define UpdateQueueInfo(queue, vstatus, vid, me, from, to, myrinfo, oldnnbrs, \
174
nupd, updptr, updind, bndtype) \
175
do { \
176
real_t rgain; \
177
\
178
if (me == to || me == from || oldnnbrs != myrinfo->nnbrs) { \
179
rgain = (myrinfo->nnbrs > 0 ? \
180
1.0*myrinfo->ed/sqrt(myrinfo->nnbrs) : 0.0) - myrinfo->id; \
181
\
182
if (bndtype == BNDTYPE_REFINE) { \
183
if (vstatus[(vid)] == VPQSTATUS_PRESENT) { \
184
if (myrinfo->ed-myrinfo->id >= 0) \
185
rpqUpdate(queue, (vid), rgain); \
186
else { \
187
rpqDelete(queue, (vid)); \
188
vstatus[(vid)] = VPQSTATUS_NOTPRESENT; \
189
ListDelete(nupd, updind, updptr, (vid)); \
190
} \
191
} \
192
else if (vstatus[(vid)] == VPQSTATUS_NOTPRESENT && myrinfo->ed-myrinfo->id >= 0) { \
193
rpqInsert(queue, (vid), rgain); \
194
vstatus[(vid)] = VPQSTATUS_PRESENT; \
195
ListInsert(nupd, updind, updptr, (vid)); \
196
} \
197
} \
198
else { \
199
if (vstatus[(vid)] == VPQSTATUS_PRESENT) { \
200
if (myrinfo->ed > 0) \
201
rpqUpdate(queue, (vid), rgain); \
202
else { \
203
rpqDelete(queue, (vid)); \
204
vstatus[(vid)] = VPQSTATUS_NOTPRESENT; \
205
ListDelete(nupd, updind, updptr, (vid)); \
206
} \
207
} \
208
else if (vstatus[(vid)] == VPQSTATUS_NOTPRESENT && myrinfo->ed > 0) { \
209
rpqInsert(queue, (vid), rgain); \
210
vstatus[(vid)] = VPQSTATUS_PRESENT; \
211
ListInsert(nupd, updind, updptr, (vid)); \
212
} \
213
} \
214
} \
215
} while(0)
216
217
218
219
/*************************************************************************/
220
/*! This macro determines the set of subdomains that a vertex can move to
221
without increasins the maxndoms. */
222
/*************************************************************************/
223
#define SelectSafeTargetSubdomains(myrinfo, mynbrs, nads, adids, maxndoms, safetos, vtmp) \
224
do { \
225
idx_t j, k, l, nadd, to; \
226
for (j=0; j<myrinfo->nnbrs; j++) { \
227
safetos[to = mynbrs[j].pid] = 0; \
228
\
229
/* uncompress the connectivity info for the 'to' subdomain */ \
230
for (k=0; k<nads[to]; k++) \
231
vtmp[adids[to][k]] = 1; \
232
\
233
for (nadd=0, k=0; k<myrinfo->nnbrs; k++) { \
234
if (k == j) \
235
continue; \
236
\
237
l = mynbrs[k].pid; \
238
if (vtmp[l] == 0) { \
239
if (nads[l] > maxndoms-1) { \
240
nadd = maxndoms; \
241
break; \
242
} \
243
nadd++; \
244
} \
245
} \
246
if (nads[to]+nadd <= maxndoms) \
247
safetos[to] = 1; \
248
if (nadd == 0) \
249
safetos[to] = 2; \
250
\
251
/* cleanup the connectivity info due to the 'to' subdomain */ \
252
for (k=0; k<nads[to]; k++) \
253
vtmp[adids[to][k]] = 0; \
254
} \
255
} while (0)
256
257
258
#endif
259
260