hp2FEM
0.1
|
00001 /* 00002 * Copyright 1997, Regents of the University of Minnesota 00003 * 00004 * macros.h 00005 * 00006 * This file contains macros used in multilevel 00007 * 00008 * Started 9/25/94 00009 * George 00010 * 00011 * $Id: macros.h 10060 2011-06-02 18:56:30Z karypis $ 00012 * 00013 */ 00014 00015 #ifndef _LIBMETIS_MACROS_H_ 00016 #define _LIBMETIS_MACROS_H_ 00017 00018 /************************************************************************* 00019 * The following macro returns a random number in the specified range 00020 **************************************************************************/ 00021 #define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b))) 00022 #define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b))) 00023 #define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b))) 00024 00025 //#define icopy(n, a, b) (idx_t *)memcpy((void *)(b), (void *)(a), sizeof(idx_t)*(n)) 00026 00027 #define HASHFCT(key, size) ((key)%(size)) 00028 #define SWAP gk_SWAP 00029 00030 /* gets the appropriate option value */ 00031 #define GETOPTION(options, idx, defval) \ 00032 ((options) == NULL || (options)[idx] == -1 ? defval : (options)[idx]) 00033 00034 /* converts a user provided ufactor into a real ubfactor */ 00035 #define I2RUBFACTOR(ufactor) (1.0+0.001*(ufactor)) 00036 00037 /* set/reset the current workspace core */ 00038 #define WCOREPUSH wspacepush(ctrl) 00039 #define WCOREPOP wspacepop(ctrl) 00040 00041 00042 00043 /************************************************************************* 00044 * These macros insert and remove nodes from a Direct Access list 00045 **************************************************************************/ 00046 #define ListInsert(n, lind, lptr, i) \ 00047 do { \ 00048 ASSERT(lptr[i] == -1); \ 00049 lind[n] = i; \ 00050 lptr[i] = (n)++;\ 00051 } while(0) 00052 00053 #define ListDelete(n, lind, lptr, i) \ 00054 do { \ 00055 ASSERT(lptr[i] != -1); \ 00056 lind[lptr[i]] = lind[--(n)]; \ 00057 lptr[lind[n]] = lptr[i]; \ 00058 lptr[i] = -1; \ 00059 } while(0) 00060 00061 00062 /************************************************************************* 00063 * These macros insert and remove nodes from the boundary list 00064 **************************************************************************/ 00065 #define BNDInsert(nbnd, bndind, bndptr, vtx) \ 00066 ListInsert(nbnd, bndind, bndptr, vtx) 00067 00068 #define BNDDelete(nbnd, bndind, bndptr, vtx) \ 00069 ListDelete(nbnd, bndind, bndptr, vtx) 00070 00071 00072 /************************************************************************* 00073 * These macros deal with id/ed updating during k-way refinement 00074 **************************************************************************/ 00075 #define UpdateMovedVertexInfoAndBND(i, from, k, to, myrinfo, mynbrs, where, \ 00076 nbnd, bndptr, bndind, bndtype) \ 00077 do { \ 00078 where[i] = to; \ 00079 myrinfo->ed += myrinfo->id-mynbrs[k].ed; \ 00080 SWAP(myrinfo->id, mynbrs[k].ed, j); \ 00081 if (mynbrs[k].ed == 0) \ 00082 mynbrs[k] = mynbrs[--myrinfo->nnbrs]; \ 00083 else \ 00084 mynbrs[k].pid = from; \ 00085 \ 00086 /* Update the boundary information. Both deletion and addition is \ 00087 allowed as this routine can be used for moving arbitrary nodes. */ \ 00088 if (bndtype == BNDTYPE_REFINE) { \ 00089 if (bndptr[i] != -1 && myrinfo->ed - myrinfo->id < 0) \ 00090 BNDDelete(nbnd, bndind, bndptr, i); \ 00091 if (bndptr[i] == -1 && myrinfo->ed - myrinfo->id >= 0) \ 00092 BNDInsert(nbnd, bndind, bndptr, i); \ 00093 } \ 00094 else { \ 00095 if (bndptr[i] != -1 && myrinfo->ed <= 0) \ 00096 BNDDelete(nbnd, bndind, bndptr, i); \ 00097 if (bndptr[i] == -1 && myrinfo->ed > 0) \ 00098 BNDInsert(nbnd, bndind, bndptr, i); \ 00099 } \ 00100 } while(0) 00101 00102 00103 #define UpdateAdjacentVertexInfoAndBND(ctrl, vid, adjlen, me, from, to, \ 00104 myrinfo, ewgt, nbnd, bndptr, bndind, bndtype) \ 00105 do { \ 00106 idx_t k; \ 00107 cnbr_t *mynbrs; \ 00108 \ 00109 if (myrinfo->inbr == -1) { \ 00110 myrinfo->inbr = cnbrpoolGetNext(ctrl, adjlen+1); \ 00111 myrinfo->nnbrs = 0; \ 00112 } \ 00113 ASSERT(CheckRInfo(ctrl, myrinfo)); \ 00114 \ 00115 mynbrs = ctrl->cnbrpool + myrinfo->inbr; \ 00116 \ 00117 /* Update global ID/ED and boundary */ \ 00118 if (me == from) { \ 00119 INC_DEC(myrinfo->ed, myrinfo->id, (ewgt)); \ 00120 if (bndtype == BNDTYPE_REFINE) { \ 00121 if (myrinfo->ed-myrinfo->id >= 0 && bndptr[(vid)] == -1) \ 00122 BNDInsert(nbnd, bndind, bndptr, (vid)); \ 00123 } \ 00124 else { \ 00125 if (myrinfo->ed > 0 && bndptr[(vid)] == -1) \ 00126 BNDInsert(nbnd, bndind, bndptr, (vid)); \ 00127 } \ 00128 } \ 00129 else if (me == to) { \ 00130 INC_DEC(myrinfo->id, myrinfo->ed, (ewgt)); \ 00131 if (bndtype == BNDTYPE_REFINE) { \ 00132 if (myrinfo->ed-myrinfo->id < 0 && bndptr[(vid)] != -1) \ 00133 BNDDelete(nbnd, bndind, bndptr, (vid)); \ 00134 } \ 00135 else { \ 00136 if (myrinfo->ed <= 0 && bndptr[(vid)] != -1) \ 00137 BNDDelete(nbnd, bndind, bndptr, (vid)); \ 00138 } \ 00139 } \ 00140 \ 00141 /* Remove contribution from the .ed of 'from' */ \ 00142 if (me != from) { \ 00143 for (k=0; k<myrinfo->nnbrs; k++) { \ 00144 if (mynbrs[k].pid == from) { \ 00145 if (mynbrs[k].ed == (ewgt)) \ 00146 mynbrs[k] = mynbrs[--myrinfo->nnbrs]; \ 00147 else \ 00148 mynbrs[k].ed -= (ewgt); \ 00149 break; \ 00150 } \ 00151 } \ 00152 } \ 00153 \ 00154 /* Add contribution to the .ed of 'to' */ \ 00155 if (me != to) { \ 00156 for (k=0; k<myrinfo->nnbrs; k++) { \ 00157 if (mynbrs[k].pid == to) { \ 00158 mynbrs[k].ed += (ewgt); \ 00159 break; \ 00160 } \ 00161 } \ 00162 if (k == myrinfo->nnbrs) { \ 00163 mynbrs[k].pid = to; \ 00164 mynbrs[k].ed = (ewgt); \ 00165 myrinfo->nnbrs++; \ 00166 } \ 00167 } \ 00168 \ 00169 ASSERT(CheckRInfo(ctrl, myrinfo));\ 00170 } while(0) 00171 00172 00173 #define UpdateQueueInfo(queue, vstatus, vid, me, from, to, myrinfo, oldnnbrs, \ 00174 nupd, updptr, updind, bndtype) \ 00175 do { \ 00176 real_t rgain; \ 00177 \ 00178 if (me == to || me == from || oldnnbrs != myrinfo->nnbrs) { \ 00179 rgain = (myrinfo->nnbrs > 0 ? \ 00180 1.0*myrinfo->ed/sqrt(myrinfo->nnbrs) : 0.0) - myrinfo->id; \ 00181 \ 00182 if (bndtype == BNDTYPE_REFINE) { \ 00183 if (vstatus[(vid)] == VPQSTATUS_PRESENT) { \ 00184 if (myrinfo->ed-myrinfo->id >= 0) \ 00185 rpqUpdate(queue, (vid), rgain); \ 00186 else { \ 00187 rpqDelete(queue, (vid)); \ 00188 vstatus[(vid)] = VPQSTATUS_NOTPRESENT; \ 00189 ListDelete(nupd, updind, updptr, (vid)); \ 00190 } \ 00191 } \ 00192 else if (vstatus[(vid)] == VPQSTATUS_NOTPRESENT && myrinfo->ed-myrinfo->id >= 0) { \ 00193 rpqInsert(queue, (vid), rgain); \ 00194 vstatus[(vid)] = VPQSTATUS_PRESENT; \ 00195 ListInsert(nupd, updind, updptr, (vid)); \ 00196 } \ 00197 } \ 00198 else { \ 00199 if (vstatus[(vid)] == VPQSTATUS_PRESENT) { \ 00200 if (myrinfo->ed > 0) \ 00201 rpqUpdate(queue, (vid), rgain); \ 00202 else { \ 00203 rpqDelete(queue, (vid)); \ 00204 vstatus[(vid)] = VPQSTATUS_NOTPRESENT; \ 00205 ListDelete(nupd, updind, updptr, (vid)); \ 00206 } \ 00207 } \ 00208 else if (vstatus[(vid)] == VPQSTATUS_NOTPRESENT && myrinfo->ed > 0) { \ 00209 rpqInsert(queue, (vid), rgain); \ 00210 vstatus[(vid)] = VPQSTATUS_PRESENT; \ 00211 ListInsert(nupd, updind, updptr, (vid)); \ 00212 } \ 00213 } \ 00214 } \ 00215 } while(0) 00216 00217 00218 00219 /*************************************************************************/ 00222 /*************************************************************************/ 00223 #define SelectSafeTargetSubdomains(myrinfo, mynbrs, nads, adids, maxndoms, safetos, vtmp) \ 00224 do { \ 00225 idx_t j, k, l, nadd, to; \ 00226 for (j=0; j<myrinfo->nnbrs; j++) { \ 00227 safetos[to = mynbrs[j].pid] = 0; \ 00228 \ 00229 /* uncompress the connectivity info for the 'to' subdomain */ \ 00230 for (k=0; k<nads[to]; k++) \ 00231 vtmp[adids[to][k]] = 1; \ 00232 \ 00233 for (nadd=0, k=0; k<myrinfo->nnbrs; k++) { \ 00234 if (k == j) \ 00235 continue; \ 00236 \ 00237 l = mynbrs[k].pid; \ 00238 if (vtmp[l] == 0) { \ 00239 if (nads[l] > maxndoms-1) { \ 00240 nadd = maxndoms; \ 00241 break; \ 00242 } \ 00243 nadd++; \ 00244 } \ 00245 } \ 00246 if (nads[to]+nadd <= maxndoms) \ 00247 safetos[to] = 1; \ 00248 if (nadd == 0) \ 00249 safetos[to] = 2; \ 00250 \ 00251 /* cleanup the connectivity info due to the 'to' subdomain */ \ 00252 for (k=0; k<nads[to]; k++) \ 00253 vtmp[adids[to][k]] = 0; \ 00254 } \ 00255 } while (0) 00256 00257 00258 #endif