# SCM Repository

[matrix] View of /pkg/src/Metis/mesh.c
 [matrix] / pkg / src / Metis / mesh.c

# View of /pkg/src/Metis/mesh.c

Revision 10 - (download) (as text) (annotate)
Mon Mar 22 20:20:05 2004 UTC (15 years, 11 months ago) by bates
File size: 10640 byte(s)
Initial import
/*
* Copyright 1997, Regents of the University of Minnesota
*
* mesh.c
*
* This file contains routines for converting 3D and 4D finite element
* meshes into dual or nodal graphs
*
* Started 8/18/97
* George
*
* \$Id: mesh.c,v 1.1 2003/12/31 21:32:30 bates Exp \$
*
*/

#include <metis.h>

/*****************************************************************************
* This function creates a graph corresponding to the dual of a finite element
* mesh. At this point the supported elements are triangles, tetrahedrons, and
* bricks.
******************************************************************************/
void METIS_MeshToDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag,
{
int esizes[] = {-1, 3, 4, 8, 4};

if (*numflag == 1)
ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts);

if (*numflag == 1)
}

/*****************************************************************************
* This function creates a graph corresponding to the finite element mesh.
* At this point the supported elements are triangles, tetrahedrons.
******************************************************************************/
void METIS_MeshToNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag,
{
int esizes[] = {-1, 3, 4, 8, 4};

if (*numflag == 1)
ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts);

switch (*etype) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
}

if (*numflag == 1)
}

/*****************************************************************************
* This function creates the dual of a finite element mesh
******************************************************************************/
void GENDUALMETIS(int nelmnts, int nvtxs, int etype, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
{
int i, j, jj, k, kk, kkk, l, m, n, nedges, mask;
idxtype *nptr, *nind;
idxtype *mark, ind[200], wgt[200];
int esize, esizes[] = {-1, 3, 4, 8, 4},
mgcnum, mgcnums[] = {-1, 2, 3, 4, 2};

mark = idxsmalloc(mask+1, -1, "GENDUALMETIS: mark");

/* Get the element size and magic number for the particular element */
esize = esizes[etype];
mgcnum = mgcnums[etype];

/* Construct the node-element list first */
nptr = idxsmalloc(nvtxs+1, 0, "GENDUALMETIS: nptr");
for (j=esize*nelmnts, i=0; i<j; i++)
nptr[elmnts[i]]++;
MAKECSR(i, nvtxs, nptr);

nind = idxmalloc(nptr[nvtxs], "GENDUALMETIS: nind");
for (k=i=0; i<nelmnts; i++) {
for (j=0; j<esize; j++, k++)
nind[nptr[elmnts[k]]++] = i;
}
for (i=nvtxs; i>0; i--)
nptr[i] = nptr[i-1];
nptr[0] = 0;

for (i=0; i<nelmnts; i++)

for (i=0; i<nelmnts; i++) {
for (m=j=0; j<esize; j++) {
n = elmnts[esize*i+j];
for (k=nptr[n+1]-1; k>=nptr[n]; k--) {
if ((kk = nind[k]) <= i)
break;

if ((l = mark[kkk]) == -1) {
ind[m] = kk;
wgt[m] = 1;
mark[kkk] = m++;
}
else if (ind[l] == kk) {
wgt[l]++;
}
else {
for (jj=0; jj<m; jj++) {
if (ind[jj] == kk) {
wgt[jj]++;
break;
}
}
if (jj == m) {
ind[m] = kk;
wgt[m++] = 1;
}
}
}
}
for (j=0; j<m; j++) {
if (wgt[j] == mgcnum) {
k = ind[j];
}
}
}

/* Go and consolidate the dxadj and dadjncy */
for (j=i=0; i<nelmnts; i++) {
for (k=esize*i; k<dxadj[i]; k++, j++)
}
for (i=nelmnts; i>0; i--)

free(mark);
free(nptr);
free(nind);

}

/*****************************************************************************
* This function creates the nodal graph of a finite element mesh
******************************************************************************/
void TRINODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
{
int i, j, jj, k, kk, kkk, l, m, n, nedges;
idxtype *nptr, *nind;
idxtype *mark;

/* Construct the node-element list first */
nptr = idxsmalloc(nvtxs+1, 0, "TRINODALMETIS: nptr");
for (j=3*nelmnts, i=0; i<j; i++)
nptr[elmnts[i]]++;
MAKECSR(i, nvtxs, nptr);

nind = idxmalloc(nptr[nvtxs], "TRINODALMETIS: nind");
for (k=i=0; i<nelmnts; i++) {
for (j=0; j<3; j++, k++)
nind[nptr[elmnts[k]]++] = i;
}
for (i=nvtxs; i>0; i--)
nptr[i] = nptr[i-1];
nptr[0] = 0;

mark = idxsmalloc(nvtxs, -1, "TRINODALMETIS: mark");

nedges = dxadj[0] = 0;
for (i=0; i<nvtxs; i++) {
mark[i] = i;
for (j=nptr[i]; j<nptr[i+1]; j++) {
for (jj=3*nind[j], k=0; k<3; k++, jj++) {
kk = elmnts[jj];
if (mark[kk] != i) {
mark[kk] = i;
}
}
}
}

free(mark);
free(nptr);
free(nind);

}

/*****************************************************************************
* This function creates the nodal graph of a finite element mesh
******************************************************************************/
void TETNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
{
int i, j, jj, k, kk, kkk, l, m, n, nedges;
idxtype *nptr, *nind;
idxtype *mark;

/* Construct the node-element list first */
nptr = idxsmalloc(nvtxs+1, 0, "TETNODALMETIS: nptr");
for (j=4*nelmnts, i=0; i<j; i++)
nptr[elmnts[i]]++;
MAKECSR(i, nvtxs, nptr);

nind = idxmalloc(nptr[nvtxs], "TETNODALMETIS: nind");
for (k=i=0; i<nelmnts; i++) {
for (j=0; j<4; j++, k++)
nind[nptr[elmnts[k]]++] = i;
}
for (i=nvtxs; i>0; i--)
nptr[i] = nptr[i-1];
nptr[0] = 0;

mark = idxsmalloc(nvtxs, -1, "TETNODALMETIS: mark");

nedges = dxadj[0] = 0;
for (i=0; i<nvtxs; i++) {
mark[i] = i;
for (j=nptr[i]; j<nptr[i+1]; j++) {
for (jj=4*nind[j], k=0; k<4; k++, jj++) {
kk = elmnts[jj];
if (mark[kk] != i) {
mark[kk] = i;
}
}
}
}

free(mark);
free(nptr);
free(nind);

}

/*****************************************************************************
* This function creates the nodal graph of a finite element mesh
******************************************************************************/
void HEXNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
{
int i, j, jj, k, kk, kkk, l, m, n, nedges;
idxtype *nptr, *nind;
idxtype *mark;
int table[8][3] = {1, 3, 4,
0, 2, 5,
1, 3, 6,
0, 2, 7,
0, 5, 7,
1, 4, 6,
2, 5, 7,
3, 4, 6};

/* Construct the node-element list first */
nptr = idxsmalloc(nvtxs+1, 0, "HEXNODALMETIS: nptr");
for (j=8*nelmnts, i=0; i<j; i++)
nptr[elmnts[i]]++;
MAKECSR(i, nvtxs, nptr);

nind = idxmalloc(nptr[nvtxs], "HEXNODALMETIS: nind");
for (k=i=0; i<nelmnts; i++) {
for (j=0; j<8; j++, k++)
nind[nptr[elmnts[k]]++] = i;
}
for (i=nvtxs; i>0; i--)
nptr[i] = nptr[i-1];
nptr[0] = 0;

mark = idxsmalloc(nvtxs, -1, "HEXNODALMETIS: mark");

nedges = dxadj[0] = 0;
for (i=0; i<nvtxs; i++) {
mark[i] = i;
for (j=nptr[i]; j<nptr[i+1]; j++) {
jj=8*nind[j];
for (k=0; k<8; k++) {
if (elmnts[jj+k] == i)
break;
}
ASSERT(k != 8);

/* You found the index, now go and put the 3 neighbors */
kk = elmnts[jj+table[k][0]];
if (mark[kk] != i) {
mark[kk] = i;
}
kk = elmnts[jj+table[k][1]];
if (mark[kk] != i) {
mark[kk] = i;
}
kk = elmnts[jj+table[k][2]];
if (mark[kk] != i) {
mark[kk] = i;
}
}
}

free(mark);
free(nptr);
free(nind);

}

/*****************************************************************************
* This function creates the nodal graph of a finite element mesh
******************************************************************************/
void QUADNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
{
int i, j, jj, k, kk, kkk, l, m, n, nedges;
idxtype *nptr, *nind;
idxtype *mark;
int table[4][2] = {1, 3,
0, 2,
1, 3,
0, 2};

/* Construct the node-element list first */
nptr = idxsmalloc(nvtxs+1, 0, "QUADNODALMETIS: nptr");
for (j=4*nelmnts, i=0; i<j; i++)
nptr[elmnts[i]]++;
MAKECSR(i, nvtxs, nptr);

nind = idxmalloc(nptr[nvtxs], "QUADNODALMETIS: nind");
for (k=i=0; i<nelmnts; i++) {
for (j=0; j<4; j++, k++)
nind[nptr[elmnts[k]]++] = i;
}
for (i=nvtxs; i>0; i--)
nptr[i] = nptr[i-1];
nptr[0] = 0;

mark = idxsmalloc(nvtxs, -1, "QUADNODALMETIS: mark");

nedges = dxadj[0] = 0;
for (i=0; i<nvtxs; i++) {
mark[i] = i;
for (j=nptr[i]; j<nptr[i+1]; j++) {
jj=4*nind[j];
for (k=0; k<4; k++) {
if (elmnts[jj+k] == i)
break;
}
ASSERT(k != 4);

/* You found the index, now go and put the 2 neighbors */
kk = elmnts[jj+table[k][0]];
if (mark[kk] != i) {
mark[kk] = i;
}
kk = elmnts[jj+table[k][1]];
if (mark[kk] != i) {
mark[kk] = i;