00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <metis.h>
00016
00017
00018
00019
00020
00021
00022 void METIS_PartMeshNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag,
00023 int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
00024 {
00025 int i, j, k, me;
00026 idxtype *xadj, *adjncy, *pwgts;
00027 int options[10], pnumflag=0, wgtflag=0;
00028 int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
00029 int esize, esizes[] = {-1, 3, 4, 8, 4};
00030
00031 esize = esizes[*etype];
00032
00033 if (*numflag == 1)
00034 ChangeMesh2CNumbering((*ne)*esize, elmnts);
00035
00036 xadj = idxmalloc(*nn+1, "METIS_MESHPARTNODAL: xadj");
00037 adjncy = idxmalloc(20*(*nn), "METIS_MESHPARTNODAL: adjncy");
00038
00039 METIS_MeshToNodal(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy);
00040
00041 adjncy = realloc(adjncy, xadj[*nn]*sizeof(idxtype));
00042
00043 options[0] = 0;
00044 METIS_PartGraphKway(nn, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, npart);
00045
00046
00047 idxset(*ne, -1, epart);
00048 pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTNODAL: pwgts");
00049 for (i=0; i<*ne; i++) {
00050 me = npart[elmnts[i*esize]];
00051 for (j=1; j<esize; j++) {
00052 if (npart[elmnts[i*esize+j]] != me)
00053 break;
00054 }
00055 if (j == esize) {
00056 epart[i] = me;
00057 pwgts[me]++;
00058 }
00059 }
00060
00061 maxpwgt = 1.03*(*ne)/(*nparts);
00062 for (i=0; i<*ne; i++) {
00063 if (epart[i] == -1) {
00064 nnbrs = 0;
00065 for (j=0; j<esize; j++) {
00066 me = npart[elmnts[i*esize+j]];
00067 for (k=0; k<nnbrs; k++) {
00068 if (nbrind[k] == me) {
00069 nbrwgt[k]++;
00070 break;
00071 }
00072 }
00073 if (k == nnbrs) {
00074 nbrind[nnbrs] = me;
00075 nbrwgt[nnbrs++] = 1;
00076 }
00077 }
00078
00079 j = iamax(nnbrs, nbrwgt);
00080 if (pwgts[nbrind[j]] < maxpwgt) {
00081 epart[i] = nbrind[j];
00082 }
00083 else {
00084
00085 for (j=0; j<nnbrs; j++) {
00086 if (pwgts[nbrind[j]] < maxpwgt) {
00087 epart[i] = nbrind[j];
00088 break;
00089 }
00090 }
00091 if (j == nnbrs)
00092 epart[i] = nbrind[iamax(nnbrs, nbrwgt)];
00093 }
00094 pwgts[epart[i]]++;
00095 }
00096 }
00097
00098 if (*numflag == 1)
00099 ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart);
00100
00101 GKfree(&xadj, &adjncy, &pwgts, LTERM);
00102
00103 }
00104
00105
00106
00107
00108
00109
00110 void METIS_PartMeshDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag,
00111 int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
00112 {
00113 int i, j, k, me;
00114 idxtype *xadj, *adjncy, *pwgts, *nptr, *nind;
00115 int options[10], pnumflag=0, wgtflag=0;
00116 int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
00117 int esize, esizes[] = {-1, 3, 4, 8, 4};
00118
00119 esize = esizes[*etype];
00120
00121 if (*numflag == 1)
00122 ChangeMesh2CNumbering((*ne)*esize, elmnts);
00123
00124 xadj = idxmalloc(*ne+1, "METIS_MESHPARTNODAL: xadj");
00125 adjncy = idxmalloc(esize*(*ne), "METIS_MESHPARTNODAL: adjncy");
00126
00127 METIS_MeshToDual(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy);
00128
00129 options[0] = 0;
00130 METIS_PartGraphKway(ne, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, epart);
00131
00132
00133 nptr = idxsmalloc(*nn+1, 0, "METIS_MESHPARTDUAL: nptr");
00134 for (j=esize*(*ne), i=0; i<j; i++)
00135 nptr[elmnts[i]]++;
00136 MAKECSR(i, *nn, nptr);
00137
00138 nind = idxmalloc(nptr[*nn], "METIS_MESHPARTDUAL: nind");
00139 for (k=i=0; i<(*ne); i++) {
00140 for (j=0; j<esize; j++, k++)
00141 nind[nptr[elmnts[k]]++] = i;
00142 }
00143 for (i=(*nn); i>0; i--)
00144 nptr[i] = nptr[i-1];
00145 nptr[0] = 0;
00146
00147
00148
00149 idxset(*nn, -1, npart);
00150 pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTDUAL: pwgts");
00151 for (i=0; i<*nn; i++) {
00152 me = epart[nind[nptr[i]]];
00153 for (j=nptr[i]+1; j<nptr[i+1]; j++) {
00154 if (epart[nind[j]] != me)
00155 break;
00156 }
00157 if (j == nptr[i+1]) {
00158 npart[i] = me;
00159 pwgts[me]++;
00160 }
00161 }
00162
00163 maxpwgt = 1.03*(*nn)/(*nparts);
00164 for (i=0; i<*nn; i++) {
00165 if (npart[i] == -1) {
00166 nnbrs = 0;
00167 for (j=nptr[i]; j<nptr[i+1]; j++) {
00168 me = epart[nind[j]];
00169 for (k=0; k<nnbrs; k++) {
00170 if (nbrind[k] == me) {
00171 nbrwgt[k]++;
00172 break;
00173 }
00174 }
00175 if (k == nnbrs) {
00176 nbrind[nnbrs] = me;
00177 nbrwgt[nnbrs++] = 1;
00178 }
00179 }
00180
00181 j = iamax(nnbrs, nbrwgt);
00182 if (pwgts[nbrind[j]] < maxpwgt) {
00183 npart[i] = nbrind[j];
00184 }
00185 else {
00186
00187 npart[i] = nbrind[0];
00188 for (j=0; j<nnbrs; j++) {
00189 if (pwgts[nbrind[j]] < maxpwgt) {
00190 npart[i] = nbrind[j];
00191 break;
00192 }
00193 }
00194 }
00195 pwgts[npart[i]]++;
00196 }
00197 }
00198
00199 if (*numflag == 1)
00200 ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart);
00201
00202 GKfree(&xadj, &adjncy, &pwgts, &nptr, &nind, LTERM);
00203
00204 }