00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "metislib.h"
00017
00018
00019
00043
00044 int METIS_MeshToDual(idx_t *ne, idx_t *nn, idx_t *eptr, idx_t *eind,
00045 idx_t *ncommon, idx_t *numflag, idx_t **r_xadj, idx_t **r_adjncy)
00046 {
00047 int sigrval=0, renumber=0;
00048
00049
00050 if (!gk_malloc_init())
00051 return METIS_ERROR_MEMORY;
00052
00053 gk_sigtrap();
00054
00055 if ((sigrval = gk_sigcatch()) != 0)
00056 goto SIGTHROW;
00057
00058
00059
00060 if (*numflag == 1) {
00061 ChangeMesh2CNumbering(*ne, eptr, eind);
00062 renumber = 1;
00063 }
00064
00065
00066 *r_xadj = *r_adjncy = NULL;
00067 CreateGraphDual(*ne, *nn, eptr, eind, *ncommon, r_xadj, r_adjncy);
00068
00069
00070 SIGTHROW:
00071 if (renumber)
00072 ChangeMesh2FNumbering(*ne, eptr, eind, *ne, *r_xadj, *r_adjncy);
00073
00074 gk_siguntrap();
00075 gk_malloc_cleanup(0);
00076
00077 if (sigrval != 0) {
00078 if (*r_xadj != NULL)
00079 free(*r_xadj);
00080 if (*r_adjncy != NULL)
00081 free(*r_adjncy);
00082 *r_xadj = *r_adjncy = NULL;
00083 }
00084
00085 return metis_rcode(sigrval);
00086 }
00087
00088
00089
00113
00114 int METIS_MeshToNodal(idx_t *ne, idx_t *nn, idx_t *eptr, idx_t *eind,
00115 idx_t *numflag, idx_t **r_xadj, idx_t **r_adjncy)
00116 {
00117 int sigrval=0, renumber=0;
00118
00119
00120 if (!gk_malloc_init())
00121 return METIS_ERROR_MEMORY;
00122
00123 gk_sigtrap();
00124
00125 if ((sigrval = gk_sigcatch()) != 0)
00126 goto SIGTHROW;
00127
00128
00129
00130 if (*numflag == 1) {
00131 ChangeMesh2CNumbering(*ne, eptr, eind);
00132 renumber = 1;
00133 }
00134
00135
00136 *r_xadj = *r_adjncy = NULL;
00137 CreateGraphNodal(*ne, *nn, eptr, eind, r_xadj, r_adjncy);
00138
00139
00140 SIGTHROW:
00141 if (renumber)
00142 ChangeMesh2FNumbering(*ne, eptr, eind, *nn, *r_xadj, *r_adjncy);
00143
00144 gk_siguntrap();
00145 gk_malloc_cleanup(0);
00146
00147 if (sigrval != 0) {
00148 if (*r_xadj != NULL)
00149 free(*r_xadj);
00150 if (*r_adjncy != NULL)
00151 free(*r_adjncy);
00152 *r_xadj = *r_adjncy = NULL;
00153 }
00154
00155 return metis_rcode(sigrval);
00156 }
00157
00158
00159
00161
00162 void CreateGraphDual(idx_t ne, idx_t nn, idx_t *eptr, idx_t *eind, idx_t ncommon,
00163 idx_t **r_xadj, idx_t **r_adjncy)
00164 {
00165 idx_t i, j, nnbrs;
00166 idx_t *nptr, *nind;
00167 idx_t *xadj, *adjncy;
00168 idx_t *marker, *nbrs;
00169
00170 if (ncommon < 1) {
00171 printf(" Increased ncommon to 1, as it was initially %"PRIDX"\n", ncommon);
00172 ncommon = 1;
00173 }
00174
00175
00176 nptr = ismalloc(nn+1, 0, "CreateGraphDual: nptr");
00177 nind = imalloc(eptr[ne], "CreateGraphDual: nind");
00178
00179 for (i=0; i<ne; i++) {
00180 for (j=eptr[i]; j<eptr[i+1]; j++)
00181 nptr[eind[j]]++;
00182 }
00183 MAKECSR(i, nn, nptr);
00184
00185 for (i=0; i<ne; i++) {
00186 for (j=eptr[i]; j<eptr[i+1]; j++)
00187 nind[nptr[eind[j]]++] = i;
00188 }
00189 SHIFTCSR(i, nn, nptr);
00190
00191
00192
00193
00194
00195 if ((xadj = (idx_t *)malloc((ne+1)*sizeof(idx_t))) == NULL)
00196 gk_errexit(SIGMEM, "***Failed to allocate memory for xadj.\n");
00197 *r_xadj = xadj;
00198 iset(ne+1, 0, xadj);
00199
00200
00201 marker = ismalloc(ne, 0, "CreateGraphDual: marker");
00202 nbrs = imalloc(ne, "CreateGraphDual: nbrs");
00203
00204 for (i=0; i<ne; i++) {
00205 xadj[i] = FindCommonElements(i, eptr[i+1]-eptr[i], eind+eptr[i], nptr,
00206 nind, eptr, ncommon, marker, nbrs);
00207 }
00208 MAKECSR(i, ne, xadj);
00209
00210
00211
00212
00213 if ((adjncy = (idx_t *)malloc(xadj[ne]*sizeof(idx_t))) == NULL) {
00214 free(xadj);
00215 *r_xadj = NULL;
00216 gk_errexit(SIGMEM, "***Failed to allocate memory for adjncy.\n");
00217 }
00218 *r_adjncy = adjncy;
00219
00220 for (i=0; i<ne; i++) {
00221 nnbrs = FindCommonElements(i, eptr[i+1]-eptr[i], eind+eptr[i], nptr,
00222 nind, eptr, ncommon, marker, nbrs);
00223 for (j=0; j<nnbrs; j++)
00224 adjncy[xadj[i]++] = nbrs[j];
00225 }
00226 SHIFTCSR(i, ne, xadj);
00227
00228 gk_free((void **)&nptr, &nind, &marker, &nbrs, LTERM);
00229 }
00230
00231
00232
00236
00237 idx_t FindCommonElements(idx_t qid, idx_t elen, idx_t *eind, idx_t *nptr,
00238 idx_t *nind, idx_t *eptr, idx_t ncommon, idx_t *marker, idx_t *nbrs)
00239 {
00240 idx_t i, ii, j, jj, k, l, overlap;
00241
00242
00243 for (k=0, i=0; i<elen; i++) {
00244 j = eind[i];
00245 for (ii=nptr[j]; ii<nptr[j+1]; ii++) {
00246 jj = nind[ii];
00247
00248 if (marker[jj] == 0)
00249 nbrs[k++] = jj;
00250 marker[jj]++;
00251 }
00252 }
00253
00254
00255
00256 if (marker[qid] == 0)
00257 nbrs[k++] = qid;
00258 marker[qid] = 0;
00259
00260
00261 for (j=0, i=0; i<k; i++) {
00262 overlap = marker[l = nbrs[i]];
00263 if (overlap >= ncommon ||
00264 overlap >= elen-1 ||
00265 overlap >= eptr[l+1]-eptr[l]-1)
00266 nbrs[j++] = l;
00267 marker[l] = 0;
00268 }
00269
00270 return j;
00271 }
00272
00273
00274
00276
00277 void CreateGraphNodal(idx_t ne, idx_t nn, idx_t *eptr, idx_t *eind,
00278 idx_t **r_xadj, idx_t **r_adjncy)
00279 {
00280 idx_t i, j, nnbrs;
00281 idx_t *nptr, *nind;
00282 idx_t *xadj, *adjncy;
00283 idx_t *marker, *nbrs;
00284
00285
00286
00287 nptr = ismalloc(nn+1, 0, "CreateGraphNodal: nptr");
00288 nind = imalloc(eptr[ne], "CreateGraphNodal: nind");
00289
00290 for (i=0; i<ne; i++) {
00291 for (j=eptr[i]; j<eptr[i+1]; j++)
00292 nptr[eind[j]]++;
00293 }
00294 MAKECSR(i, nn, nptr);
00295
00296 for (i=0; i<ne; i++) {
00297 for (j=eptr[i]; j<eptr[i+1]; j++)
00298 nind[nptr[eind[j]]++] = i;
00299 }
00300 SHIFTCSR(i, nn, nptr);
00301
00302
00303
00304
00305
00306 if ((xadj = (idx_t *)malloc((nn+1)*sizeof(idx_t))) == NULL)
00307 gk_errexit(SIGMEM, "***Failed to allocate memory for xadj.\n");
00308 *r_xadj = xadj;
00309 iset(nn+1, 0, xadj);
00310
00311
00312 marker = ismalloc(nn, 0, "CreateGraphNodal: marker");
00313 nbrs = imalloc(nn, "CreateGraphNodal: nbrs");
00314
00315 for (i=0; i<nn; i++) {
00316 xadj[i] = FindCommonNodes(i, nptr[i+1]-nptr[i], nind+nptr[i], eptr,
00317 eind, marker, nbrs);
00318 }
00319 MAKECSR(i, nn, xadj);
00320
00321
00322
00323
00324 if ((adjncy = (idx_t *)malloc(xadj[nn]*sizeof(idx_t))) == NULL) {
00325 free(xadj);
00326 *r_xadj = NULL;
00327 gk_errexit(SIGMEM, "***Failed to allocate memory for adjncy.\n");
00328 }
00329 *r_adjncy = adjncy;
00330
00331 for (i=0; i<nn; i++) {
00332 nnbrs = FindCommonNodes(i, nptr[i+1]-nptr[i], nind+nptr[i], eptr,
00333 eind, marker, nbrs);
00334 for (j=0; j<nnbrs; j++)
00335 adjncy[xadj[i]++] = nbrs[j];
00336 }
00337 SHIFTCSR(i, nn, xadj);
00338
00339 gk_free((void **)&nptr, &nind, &marker, &nbrs, LTERM);
00340 }
00341
00342
00343
00347
00348 idx_t FindCommonNodes(idx_t qid, idx_t nelmnts, idx_t *elmntids, idx_t *eptr,
00349 idx_t *eind, idx_t *marker, idx_t *nbrs)
00350 {
00351 idx_t i, ii, j, jj, k;
00352
00353
00354 marker[qid] = 1;
00355 for (k=0, i=0; i<nelmnts; i++) {
00356 j = elmntids[i];
00357 for (ii=eptr[j]; ii<eptr[j+1]; ii++) {
00358 jj = eind[ii];
00359 if (marker[jj] == 0) {
00360 nbrs[k++] = jj;
00361 marker[jj] = 1;
00362 }
00363 }
00364 }
00365
00366
00367 marker[qid] = 0;
00368 for (i=0; i<k; i++) {
00369 marker[nbrs[i]] = 0;
00370 }
00371
00372 return k;
00373 }
00374
00375
00376
00377
00379
00380 mesh_t *CreateMesh(void)
00381 {
00382 mesh_t *mesh;
00383
00384 mesh = (mesh_t *)gk_malloc(sizeof(mesh_t), "CreateMesh: mesh");
00385
00386 InitMesh(mesh);
00387
00388 return mesh;
00389 }
00390
00391
00392
00394
00395 void InitMesh(mesh_t *mesh)
00396 {
00397 memset((void *)mesh, 0, sizeof(mesh_t));
00398 }
00399
00400
00401
00403
00404 void FreeMesh(mesh_t **r_mesh)
00405 {
00406 mesh_t *mesh = *r_mesh;
00407
00408 gk_free((void **)&mesh->eptr, &mesh->eind, &mesh->ewgt, &mesh, LTERM);
00409
00410 *r_mesh = NULL;
00411 }
00412