/* create bucket structure and store initial vertices */ pBucket MMG_newBucket(pMesh mesh,int nmax) { pPoint ppt; pBucket bucket; double dd; int k,ic,ii,jj,kk; /* memory alloc */ bucket = (Bucket*)M_malloc(sizeof(Bucket),"newBucket"); assert(bucket); bucket->size = nmax; bucket->head = (int*)M_calloc(nmax*nmax*nmax+1,sizeof(int),"newBucket.head"); assert(bucket->head); bucket->link = (int*)M_calloc(mesh->npmax+1,sizeof(int),"newBucket.link"); assert(bucket->link); /* insert vertices */ dd = nmax / (double)PRECI; for (k=1; k<=mesh->np; k++) { ppt = &mesh->point[k]; if ( ppt->tag & M_UNUSED ) continue; ii = M_MAX(0,(int)(dd * ppt->c[0])-1); jj = M_MAX(0,(int)(dd * ppt->c[1])-1); kk = M_MAX(0,(int)(dd * ppt->c[2])-1); ic = (kk*nmax + jj)*nmax + ii; if ( !bucket->head[ic] ) bucket->head[ic] = k; else { bucket->link[k] = bucket->head[ic]; bucket->head[ic] = k; } } return(bucket); }
pCube createCube(pScene sc,pMesh mesh) { pCube cube; cube = (pCube)M_calloc(1,sizeof(struct cube),"cube"); assert(cube); cube->cubetr = (pTransform)M_calloc(1,sizeof(struct transform),"cube"); if ( !cube->cubetr ) return(0); resetCube(sc,cube,mesh); return(cube); }
pPersp initPersp(pPersp p,float dmax) { pPersp pp; if ( p ) { p->fovy = 35.0f; p->rubber = 0; p->rubix = p->rubfx = 0; p->rubiy = p->rubfy = 0; p->alpha = p->gamma = 0.0f; p->depth = -2.0*dmax; p->pmode = PERSPECTIVE; memcpy(p->matrix,ident,16*sizeof(float)); return(p); } else { pp = (pPersp)M_calloc(1,sizeof(struct sperspective),"persp"); assert(pp); pp->fovy = 35.0f; pp->rubber = 0; pp->rubix = pp->rubfx = 0; pp->rubiy = pp->rubfy = 0; pp->alpha = pp->gamma = 0.0f; pp->depth = -2.0*dmax; pp->pmode = PERSPECTIVE; memcpy(pp->matrix,ident,16*sizeof(float)); return(pp); } }
int zaldy1(pMesh mesh) { /* default */ if ( ddebug ) printf("allocate %d points\n",mesh->np); mesh->point = (pPoint)M_calloc(mesh->np+1,sizeof(Point),"zaldy1.point"); assert(mesh->point); if ( ddebug ) printf("allocate %d tria\n",mesh->nt); mesh->tria = (pTriangle)M_calloc(mesh->nt+1,sizeof(Triangle),"zaldy1.tria"); assert(mesh->tria); if ( ddebug ) printf("allocate %d quad\n",mesh->nq); if ( mesh->nq ) { mesh->quad = (pQuad)M_calloc(mesh->nq+1,sizeof(Quad),"zaldy1.quad"); assert(mesh->quad); } if ( mesh->ntet ) { if ( ddebug ) printf("allocate %d tetra\n",mesh->ntet); mesh->tetra = (pTetra)M_calloc(mesh->ntet+1,sizeof(Tetra),"zaldy1.tetra"); assert(mesh->tetra); } if ( mesh->nhex ) { if ( ddebug ) printf("allocate %d hexa\n",mesh->nhex); mesh->hexa = (pHexa)M_calloc(mesh->nhex+1,sizeof(Hexa),"zaldy1.hexa"); assert(mesh->hexa); } if ( mesh->na ) { if ( ddebug ) printf("allocate %d edges\n",mesh->na); mesh->edge = (pEdge)M_calloc(mesh->na+1,sizeof(Edge),"zaldy1.edge"); assert(mesh->edge); } if ( mesh->nvn || mesh->ntg ) { mesh->extra = (pExtra)M_calloc(1,sizeof(Extra),"zaldy1.extra"); assert(mesh->extra); if ( mesh->nvn ) { mesh->extra->n = (float*)M_calloc(3*mesh->nvn+1,sizeof(float),"inmesh"); assert(mesh->extra->n); } if ( mesh->ntg ) { mesh->extra->t = (float*)M_calloc(3*mesh->ntg+1,sizeof(float),"inmesh"); assert(mesh->extra->n); } } return(1); }
int medit1() { pScene scene; pMesh mesh; int k; clock_t ct; /* create grafix */ fprintf(stdout,"\n medit1() \n"); fprintf(stdout,"\n Building scene(s)\n"); ct = clock(); for (k=0; k<cv.nbs; k++) { if ( !cv.scene[k] ) { cv.scene[k] = (pScene)M_calloc(1,sizeof(Scene),"medit1.scene"); if ( !cv.scene[k] ) return(0); } scene = cv.scene[k]; if ( !cv.mesh[k] ) { cv.mesh[k] = (pMesh)M_calloc(1,sizeof(Mesh),"medit1.mesh"); if ( !cv.mesh[k] ) return(0); } mesh = cv.mesh[k]; fprintf(stdout," Creating scene %d\n",k+1); parsop(scene,mesh); meshRef(scene,mesh); matSort(scene); if ( option == ISOSURF ) { if ( !mesh->nbb ) return(0); setupPalette(scene,mesh); tetraIsoPOVray(scene,mesh); } else if ( !createScene(scene,k) ) { fprintf(stderr," ## Unable to create scene\n"); return(0); } } ct = difftime(clock(),ct); fprintf(stdout," Scene seconds: %.2f\n",(double)ct/(double)CLOCKS_PER_SEC); return(1); }
int zaldy2(pMesh mesh) { pSolution ps; int k,nbf; /* memory alloc. */ mesh->sol = (pSolution)M_calloc(mesh->nbb+1,sizeof(struct solu),"zaldy2"); assert(mesh->sol); if ( mesh->nfield == 1 ) return(1); if ( mesh->nfield == mesh->dim ) nbf = mesh->dim; /* vector field */ else nbf = mesh->dim*(mesh->dim+1)/2; /* d*d matrix */ for (k=1; k<=mesh->nbb; k++) { ps = &mesh->sol[k]; ps->m = (float*)malloc(nbf*sizeof(float)); } return(1); }
/* very sioux! (09/2002) */ int hashTria(pMesh mesh) { pTriangle pt,pt1; int k,kk,l,ll,mins,maxs,mins1,maxs1,hsize; int *hcode,*link,inival,iadr,pp; char *hvoy; ubyte i,i1,i2,ii; unsigned int key; /* avoid building again! */ if ( mesh->adja ) return(1); if ( 4*sizeof(char) != sizeof(int) ) exit(1); /* default */ if ( ddebug) { fprintf(stdout," Setting topology."); fflush(stdout); } /* memory alloc */ hcode = (int*)M_calloc(MEDIT_MAX(1,3*mesh->nt/4)+1,sizeof(int),"hash.tria"); link = (int*)M_calloc(3*mesh->nt+1,sizeof(int),"hash.tria"); hsize = MEDIT_MAX(2,3*mesh->nt/4-1); assert(hcode); assert(link); hvoy = (char*)hcode; /* init */ inival = 2 << 30; for (k=0; k<=3*mesh->nt/4; k++) hcode[k] = -inival; /* build hash table */ for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; if ( !pt->v[0] ) continue; for (i=0; i<3; i++) { i1 = idir[i+1]; i2 = idir[i+2]; mins = MEDIT_MIN(pt->v[i1],pt->v[i2]); maxs = MEDIT_MAX(pt->v[i1],pt->v[i2]); /* compute key */ key = KA*mins + KB*maxs; key = key % hsize + 1; /* insert */ iadr = 3*(k-1) + i+1; link[iadr] = hcode[key]; hcode[key] = -iadr; } } if ( ddebug ) { fprintf(stdout,"."); fflush(stdout); } /* set adjacency */ for (l=3*mesh->nt; l>0; l--) { if ( link[l] >= 0 ) continue; k = (l-1) / 3 + 1; i = (l-1) % 3; i1 = idir[i+1]; i2 = idir[i+2]; pt = &mesh->tria[k]; mins = MEDIT_MIN(pt->v[i1],pt->v[i2]); maxs = MEDIT_MAX(pt->v[i1],pt->v[i2]); /* accross link */ ll = -link[l]; pp = 0; link[l] = 0; hvoy[l] = 0; while ( ll != inival ) { kk = (ll-1) / 3 + 1; ii = (ll-1) % 3; i1 = idir[ii+1]; i2 = idir[ii+2]; pt1 = &mesh->tria[kk]; mins1 = MEDIT_MIN(pt1->v[i1],pt1->v[i2]); maxs1 = MEDIT_MAX(pt1->v[i1],pt1->v[i2]); /* adjacent found */ if ( mins1 == mins && maxs1 == maxs ) { if ( pp != 0 ) link[pp] = link[ll]; link[l] = kk; hvoy[l] = ii; link[ll]= k; hvoy[ll]= i; break; } pp = ll; ll = -link[ll]; } } mesh->adja = (int*)link; mesh->voy = (ubyte*)hcode; if ( ddebug ) fprintf(stdout,".\n"); return(1); }
/* very sioux! (09/2002) */ int hashTetra(pMesh mesh) { pTetra pt,pt1; int k,kk,pp,l,ll,mins,mins1,maxs,maxs1,sum,sum1,iadr; int *hcode,*link,inival,hsize; char *hvoy; ubyte i,ii,i1,i2,i3; unsigned int key; /* avoid building */ if ( mesh->adja ) return(1); if ( 4*sizeof(char) != sizeof(int) ) exit(1); /* default */ if ( ddebug) { fprintf(stdout," Setting topology."); fflush(stdout); } /* memory alloc */ hcode = (int*)M_calloc( MEDIT_MAX(100,mesh->ntet+1),sizeof(int),"hash.tetra"); link = (int*)M_calloc(4*MEDIT_MAX(100,mesh->ntet+1),sizeof(int),"hash.tetra"); hsize = MEDIT_MAX(100,mesh->ntet); assert(hcode); assert(link); hvoy = (char*)hcode; /* init */ inival = 2<<30; for (k=0; k<=mesh->ntet; k++) hcode[k] = -inival; /* build hash table */ for (k=1; k<=mesh->ntet; k++) { pt = &mesh->tetra[k]; if ( !pt->v[0] ) continue; for (i=0; i<4; i++) { i1 = idirt[i+1]; i2 = idirt[i+2]; i3 = idirt[i+3]; mins = MEDIT_MIN(pt->v[i1],pt->v[i2]); mins = MEDIT_MIN(mins,pt->v[i3]); maxs = MEDIT_MAX(pt->v[i1],pt->v[i2]); maxs = MEDIT_MAX(maxs,pt->v[i3]); /* compute key */ sum = pt->v[i1] + pt->v[i2] + pt->v[i3]; key = KA*mins + KB*maxs + KC*sum; key = key % hsize + 1; /* insert */ iadr = 4*(k-1) + i+1; link[iadr] = hcode[key]; hcode[key] = -iadr; } } if ( ddebug ) { fprintf(stdout,"."); fflush(stdout); } /* set adjacency */ for (l=4*mesh->ntet; l>0; l--) { if ( link[l] >= 0 ) continue; k = (l-1) / 4 + 1; i = (l-1) % 4; i1 = idirt[i+1]; i2 = idirt[i+2]; i3 = idirt[i+3]; pt = &mesh->tetra[k]; sum = pt->v[i1] + pt->v[i2] + pt->v[i3]; mins = MEDIT_MIN(pt->v[i1],pt->v[i2]); mins = MEDIT_MIN(mins,pt->v[i3]); maxs = MEDIT_MAX(pt->v[i1],pt->v[i2]); maxs = MEDIT_MAX(maxs,pt->v[i3]); /* accross link */ ll = -link[l]; pp = 0; link[l] = 0; hvoy[l] = 0; while ( ll != inival ) { kk = (ll-1) / 4 + 1; ii = (ll-1) % 4; i1 = idirt[ii+1]; i2 = idirt[ii+2]; i3 = idirt[ii+3]; pt1 = &mesh->tetra[kk]; sum1 = pt1->v[i1] + pt1->v[i2] + pt1->v[i3]; if ( sum1 == sum ) { mins1 = MEDIT_MIN(pt1->v[i1],pt1->v[i2]); mins1 = MEDIT_MIN(mins1,pt1->v[i3]); if ( mins1 == mins ) { maxs1 = MEDIT_MAX(pt1->v[i1],pt1->v[i2]); maxs1 = MEDIT_MAX(maxs1,pt1->v[i3]); if ( maxs1 == maxs ) { /* adjacent found */ if ( pp != 0 ) link[pp] = link[ll]; link[l] = kk; hvoy[l] = ii; link[ll]= k; hvoy[ll]= i; break; } } } pp = ll; ll = -link[ll]; } } mesh->adja = (int*)link; mesh->voy = (ubyte*)hcode; if ( ddebug ) fprintf(stdout,"..\n"); return(1); }
/* very sioux! (09/2002) */ int hashHexa(pMesh mesh) { pHexa ph,ph1; int k,kk,iadr,pp,l,ll,v; int imin,mins,mins1,opps,opps1; int *hcode,*link,inival,hsize; char *hvoy; ubyte i,i1,ii; unsigned int key; /* avoid building again! */ if ( mesh->adja ) return(1); if ( 4*sizeof(char) != sizeof(int) ) exit(1); /* default */ if ( ddebug ) { fprintf(stdout," Setting topology."); fflush(stdout); } /* memory alloc */ /* bug fixe: 17/04/2007 hcode = (int*)M_calloc(max(11,mesh->nhex+1),sizeof(int),"hash.hexa"); link = (int*)M_calloc(6*max(11,mesh->nhex+1),sizeof(int),"hash.hexa"); hsize = MEDIT_MAX(10,mesh->nhex); if ( !hcode || !link ) { myerror.coderr = 1000; return(0); } hvoy = (char*)hcode; */ hcode = (int*)M_calloc(MEDIT_MAX(10,6*mesh->nhex/4+1),sizeof(int),"hash.hexa"); assert(hcode); link = (int*)M_calloc(MEDIT_MAX(10,6*mesh->nhex+1),sizeof(int),"hash.hexa"); assert(link); hsize = MEDIT_MAX(2,mesh->nhex); hvoy = (char*)hcode; /* init */ inival = 2 << 30; for (k=0; k<=6*mesh->nhex/4; k++) hcode[k] = -inival; /* build hash table */ for (k=1; k<=mesh->nhex; k++) { ph = &mesh->hexa[k]; if ( !ph->v[0] ) continue; for (i=0; i<6; i++) { mins = ph->v[ch[i][0]]; imin = 0; for (v=1; v<4; v++) if ( ph->v[ch[i][v]] < mins ) { mins = ph->v[ch[i][v]]; imin = v; } i1 = (imin+2) % 4; opps = ph->v[ch[i][i1]]; /* compute key */ key = KA*mins + KB*opps; key = key % hsize + 1; /* insert */ iadr = 6*(k-1) + i+1; link[iadr] = hcode[key]; hcode[key] = -iadr; } } if ( ddebug ) { fprintf(stdout,"."); fflush(stdout); } /* set adjacency */ for (l=6*mesh->nhex; l>0; l--) { if ( link[l] >= 0 ) continue; k = (l-1) / 6 + 1; i = (l-1) % 6; ph = &mesh->hexa[k]; mins = ph->v[ch[i][0]]; imin = 0; for (v=1; v<4; v++) if ( ph->v[ch[i][v]] < mins ) { mins = ph->v[ch[i][v]]; imin = v; } i1 = (imin+2) % 4; opps = ph->v[ch[i][i1]]; /* accross link */ ll = -link[l]; pp = 0; link[l] = 0; hvoy[l] = 0; while ( ll != inival ) { kk = (ll-1) / 6 +1; ii = (ll-1) % 6; ph1 = &mesh->hexa[kk]; mins1 = ph1->v[ch[ii][0]]; imin = 0; for (v=1; v<4; v++) if ( ph1->v[ch[ii][v]] < mins1 ) { mins1 = ph1->v[ch[ii][v]]; imin = v; } i1 = (imin+2) % 4; opps1 = ph1->v[ch[ii][i1]]; /* adjacent found */ if ( mins1 == mins && opps1 == opps ) { if ( pp != 0 ) link[pp] = link[ll]; link[l] = kk; hvoy[l] = ii; link[ll]= k; hvoy[ll]= i; break; } pp = ll; ll = -link[ll]; } } mesh->adja = (int*)link; mesh->voy = (ubyte*)hcode; if ( ddebug ) fprintf(stdout,"..\n"); return(1); }
int medit0() { pMesh mesh; char data[128],*name; int k,l,ret; clock_t ct; /* default */ // fprintf(stdout," \n medit0() \n"); fprintf(stdout," Loading data file(s)\n"); ct = clock(); /* enter name */ if ( !cv.nbm ) { fprintf(stdout," File name(s) missing. Please enter : "); fflush(stdout); fflush(stdin); fgets(data,120,stdin); if ( !strlen(data) ) { fprintf(stdout," ## No data\n"); return(0); } /* parse file name(s) */ name = strtok(data," \n"); while( name ) { if ( !cv.mesh[cv.nbm] ) { cv.mesh[cv.nbm] = (pMesh)M_calloc(1,sizeof(Mesh),"medit0.mesh"); if ( !cv.mesh[cv.nbm] ) return(0); } /*(cv.mesh[cv.nbm])->name = calloc(strlen(name)+1,sizeof(char));*/ strcpy(cv.mesh[cv.nbm]->name,name); name = strtok(NULL," \n\0"); if ( ++cv.nbm == MAX_MESH ) break; } if ( !cv.nbm ) return(0); } if ( !cv.nbm ) { fprintf(stdout," Number of mesh missing:. Please enter : "); fflush(stdout); fflush(stdin); fgets(data,120,stdin); cv.nbm = atoi(data); } /* read mesh(es) */ k = 0; do { if ( !cv.mesh[k] ) { cv.mesh[k] = M_calloc(1,sizeof(Mesh),"medit0.mesh"); if ( !cv.mesh[k] ) return(0); } mesh = cv.mesh[k]; mesh->typ = 0; ret = loadMesh(mesh); if ( ret < 0 ) { mesh->typ = 1; ret = inmsh2(mesh); if ( !ret ) { mesh->typ = 2; ret = loadGIS(mesh); } } if ( ret <= 0 ) { for (l=k+1; l<cv.nbm; l++) cv.mesh[l-1] = cv.mesh[l]; cv.nbm--; k--; continue; } /* compute mesh box */ if ( (mesh->ntet && !mesh->nt) || (mesh->nhex && !mesh->nq) ) meshSurf(mesh); meshBox(mesh,1); if ( !quiet ) meshInfo(mesh); /* read metric */ if ( !loadSol(mesh,mesh->name,1) ) bbfile(mesh); if ( !quiet && mesh->nbb ) fprintf(stdout," Solutions %8d\n",mesh->nbb); } while ( ++k < cv.nbm ); cv.nbs = cv.nbm; ct = difftime(clock(),ct); fprintf(stdout," Input seconds: %.2f\n", (double)ct/(double)CLOCKS_PER_SEC); return(cv.nbm); }
int medit0_popen() { pMesh mesh; char data[128],*name; int k,l,ret; clock_t ct; /* default */ /*fprintf(stdout," \n medit0() \n");*/ fprintf(stdout," Loading data file(s)\n"); ct = clock(); /* enter number of mesh */ if ( !cv.nbm ) { fprintf(stdout," Number of mesh missing:. Please enter : "); fflush(stdout); fflush(stdin); fgets(data,128,stdin); cv.nbm = atoi(data); } /* read mesh(es) */ k = 0; do { // printf("mesh number %i\n",k+1); if ( !cv.mesh[k] ) { cv.mesh[k] = M_calloc(1,sizeof(Mesh),"medit0.mesh"); if ( !cv.mesh[k] ) return(0); } mesh = cv.mesh[k]; mesh->typ = 0; //fgets(data,128,stdin); //name = data; //printf("data=%s\n",data); //name = "toto.dat"; //strcpy(cv.mesh[k]->name,name); if(dpopenbin) ret = loadMesh_popen_bin(mesh); else ret = loadMesh_popen(mesh); /* compute mesh box */ if ( (mesh->ntet && !mesh->nt) || (mesh->nhex && !mesh->nq) ) meshSurf(mesh); meshBox(mesh,1); if ( !quiet ) meshInfo(mesh); /* /\* read metric *\/ // a changer lecture .sol et .bb */ /* if ( !loadSol_popen(mesh,mesh->name,1) ) */ /* bbfile_popen(mesh); */ /* if ( !quiet && mesh->nbb ) */ /* fprintf(stdout," Solutions %8d\n",mesh->nbb); */ if( dpopensol ){ if(dpopenbin) loadSol_popen_bin(mesh,mesh->name,1); else loadSol_popen(mesh,mesh->name,1); } if ( !quiet && mesh->nbb ) fprintf(stdout," Solutions %8d\n",mesh->nbb); } while ( ++k < cv.nbm ); cv.nbs = cv.nbm; ct = difftime(clock(),ct); fprintf(stdout," Input seconds: %.2f\n", (double)ct/(double)CLOCKS_PER_SEC); return(cv.nbm); }
/* Internal function : biPartBoxCompute * it computes a new numbering of graph vertices, using a bipartitioning. * * - graf : the input graph * - vertNbr : the number of vertices * - boxVertNbr : the number of vertices of each box * - permVrtTab : the new numbering * * returning 0 if OK, 1 else */ int biPartBoxCompute(SCOTCH_Graph graf, int vertNbr, int boxVertNbr, SCOTCH_Num *permVrtTab) { int boxNbr, vertIdx, boxIdx; SCOTCH_Num tmp, tmp2, *partTab, *partNumTab, *partPrmTab; SCOTCH_Strat strat ; /* Computing the number of boxes */ boxNbr = vertNbr / boxVertNbr; if (boxNbr * boxVertNbr != vertNbr) { boxNbr = boxNbr + 1; } /* Initializing SCOTCH functions */ CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ; CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, "r{job=t,map=t,poli=S,sep=m{type=h,vert=80,low=h{pass=10}f{bal=0.005,move=0},asc=b{bnd=f{bal=0.05,move=0},org=f{bal=0.05,move=0}}}|m{type=h,vert=80,low=h{pass=10}f{bal=0.005,move=0},asc=b{bnd=f{bal=0.05,move=0},org=f{bal=0.05,move=0}}}}"), "scotch_stratGraphMap", 0) ; partTab = (SCOTCH_Num *)M_calloc(vertNbr, sizeof(SCOTCH_Num), "boxCompute"); /* Partionning the graph */ CHECK_SCOTCH(SCOTCH_graphPart(&graf, boxNbr, &strat, partTab), "scotch_graphPart", 0); partNumTab = (SCOTCH_Num *)M_calloc(boxNbr, sizeof(SCOTCH_Num), "boxCompute"); if (!memset(partNumTab, 0, boxNbr*sizeof(SCOTCH_Num))) { perror("memset"); return 0; } /* Computing the number of elements of each box */ for( vertIdx = 0 ; vertIdx< vertNbr ;vertIdx++) partNumTab[partTab[vertIdx]] += 1; /* partition permutation tabular */ partPrmTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "boxCompute"); /* Copying the previous tabular in order to have the index of the first * element of each box * */ tmp = partNumTab[0]; partNumTab[0] = 0; for(boxIdx = 1; boxIdx < boxNbr ; boxIdx++) { tmp2 = partNumTab[boxIdx]; partNumTab[boxIdx] = partNumTab[boxIdx-1] + tmp; tmp = tmp2; } /* partPrmTab is built such as each vertex belongs to his box */ for( vertIdx = 0;vertIdx< vertNbr;vertIdx++) partPrmTab[partNumTab[partTab[vertIdx]]++] = vertIdx; /* Infering the new numbering */ for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++) permVrtTab[partPrmTab[vertIdx] + 1] = vertIdx + 1; M_free(partTab); M_free(partNumTab); M_free(partPrmTab); SCOTCH_stratExit(&strat) ; return 0; }
/* Function : renumbering * it modifies the numbering of each node to prevent from cache missing. * * - boxVertNbr : number of vertices by box * - mesh : the input mesh which is modified * * returning 0 if OK, 1 else */ int renumbering(int boxVertNbr, MMG_pMesh mesh, MMG_pSol sol) { MMG_pPoint ppt; MMG_pPoint points; MMG_pTria ptri, trias; MMG_pTetra ptet, tetras; SCOTCH_Num edgeNbr; SCOTCH_Num *vertTab, *vendTab, *edgeTab, *permVrtTab; SCOTCH_Graph graf ; int vertNbr, nodeGlbIdx, triaIdx, tetraIdx, ballTetIdx; int i, j, k, addrNew, addrOld; int edgeSiz; int *vertOldTab, *permNodTab, ntreal, nereal, npreal; int *adja,iadr; double *metNew; /* Computing the number of vertices and a contiguous tabular of vertices */ vertNbr = 0; vertOldTab = (int *)M_calloc(mesh->ne + 1, sizeof(int), "renumbering"); if (!memset(vertOldTab, 0, sizeof(int)*(mesh->ne+1))) { perror("memset"); return 1; } for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { /* Testing if the tetra exists */ if (!mesh->tetra[tetraIdx].v[0]) continue; vertOldTab[tetraIdx] = vertNbr+1; vertNbr++; } /* Allocating memory to compute adjacency lists */ vertTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering"); if (!memset(vertTab, ~0, sizeof(SCOTCH_Num)*(vertNbr + 1))) { perror("memset"); return 1; } vendTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering"); edgeNbr = 1; edgeSiz = vertNbr*2; edgeTab = (SCOTCH_Num *)M_calloc(edgeSiz, sizeof(SCOTCH_Num), "renumbering"); /* Computing the adjacency list for each vertex */ for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { /* Testing if the tetra exists */ if (!mesh->tetra[tetraIdx].v[0]) continue; iadr = 4*(tetraIdx-1) + 1; adja = &mesh->adja[iadr]; for (i=0; i<4; i++) { ballTetIdx = adja[i] >> 2; if (!ballTetIdx) continue; /* Testing if one neighbour of tetraIdx has already been added */ if (vertTab[vertOldTab[tetraIdx]] < 0) vertTab[vertOldTab[tetraIdx]] = edgeNbr; vendTab[vertOldTab[tetraIdx]] = edgeNbr+1; /* Testing if edgeTab memory is enough */ if (edgeNbr >= edgeSiz) { edgeSiz += EDGEGAP; edgeTab = (SCOTCH_Num *)M_realloc(edgeTab, edgeSiz * sizeof(SCOTCH_Num), "renumbering"); } edgeTab[edgeNbr++] = vertOldTab[ballTetIdx]; } } edgeNbr--; /* Building the graph by calling Scotch functions */ SCOTCH_graphInit(&graf) ; CHECK_SCOTCH(SCOTCH_graphBuild(&graf, (SCOTCH_Num) 1, vertNbr, vertTab+1, vendTab+1, NULL, NULL, edgeNbr, edgeTab+1, NULL), "scotch_graphbuild", 0) ; CHECK_SCOTCH(SCOTCH_graphCheck(&graf), "scotch_graphcheck", 0) ; permVrtTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering"); CHECK_SCOTCH(kPartBoxCompute(graf, vertNbr, boxVertNbr, permVrtTab), "boxCompute", 0); SCOTCH_graphExit(&graf) ; M_free(vertTab); M_free(vendTab); M_free(edgeTab); permNodTab = (int *)M_calloc(mesh->np + 1, sizeof(int), "renumbering"); /* Computing the new point list and modifying the sol structures*/ tetras = (MMG_pTetra)M_calloc(mesh->nemax+1,sizeof(MMG_Tetra),"renumbering"); points = (MMG_pPoint)M_calloc(mesh->npmax+1,sizeof(MMG_Point),"renumbering"); metNew = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"renumbering"); nereal = 0; npreal = 1; for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { ptet = &mesh->tetra[tetraIdx]; /* Testing if the tetra exists */ if (!ptet->v[0]) continue; /* Building the new point list */ tetras[permVrtTab[vertOldTab[tetraIdx]]] = *ptet; nereal++; for(j = 0 ; j <= 3 ; j++) { nodeGlbIdx = mesh->tetra[tetraIdx].v[j]; if (permNodTab[nodeGlbIdx]) continue; ppt = &mesh->point[nodeGlbIdx]; if (!(ppt->tag & M_UNUSED)) { /* Building the new point list */ permNodTab[nodeGlbIdx] = npreal++; points[permNodTab[nodeGlbIdx]] = *ppt; /* Building the new sol met */ addrOld = (nodeGlbIdx-1)*sol->offset + 1; addrNew = (permNodTab[nodeGlbIdx]-1)*sol->offset + 1; memcpy(&metNew[addrNew], &sol->met[addrOld], sol->offset*sizeof(double)); } } } M_free(mesh->tetra); mesh->tetra = tetras; mesh->ne = nereal; M_free(mesh->point); mesh->point = points; mesh->np = npreal - 1; M_free(sol->met); sol->met = metNew; trias = (MMG_pTria)M_calloc(mesh->ntmax+1,sizeof(MMG_Tria),"renumbering"); ntreal = 1; for(triaIdx = 1 ; triaIdx < mesh->nt + 1 ; triaIdx++) { ptri = &mesh->tria[triaIdx]; /* Testing if the tetra exists */ if (!ptri->v[0]) continue; /* Building the new point list */ trias[ntreal] = *ptri; ntreal++; } M_free(mesh->tria); mesh->tria = trias; mesh->nt = ntreal - 1; mesh->npnil = mesh->np + 1; mesh->nenil = mesh->ne + 1; for (k=mesh->npnil; k<mesh->npmax-1; k++) mesh->point[k].tmp = k+1; for (k=mesh->nenil; k<mesh->nemax-1; k++) mesh->tetra[k].v[3] = k+1; if ( mesh->nt ) { mesh->ntnil = mesh->nt + 1; for (k=mesh->ntnil; k<mesh->ntmax-1; k++) mesh->tria[k].v[2] = k+1; } /* Modifying the numbering of the nodes of each tetra */ for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { if (!mesh->tetra[tetraIdx].v[0]) continue; for(j = 0 ; j <= 3 ; j++) { mesh->tetra[tetraIdx].v[j] = permNodTab[mesh->tetra[tetraIdx].v[j]]; } } /* Modifying the numbering of the nodes of each triangle */ for(triaIdx = 1 ; triaIdx < mesh->nt + 1 ; triaIdx++) { if (!mesh->tria[triaIdx].v[0]) continue; for(j = 0 ; j <= 2 ; j++) { mesh->tria[triaIdx].v[j] = permNodTab[mesh->tria[triaIdx].v[j]]; } } M_free(permVrtTab); return 1; }
/* Internal function : kPartBoxCompute * it computes a new numbering of graph vertices, using a k-partitioning. * Assuming that baseval of the graph is 1 * * - graf : the input graph * - vertNbr : the number of vertices * - boxVertNbr : the number of vertices of each box * - permVrtTab : the new numbering * * returning 0 if OK, 1 else */ int kPartBoxCompute(SCOTCH_Graph graf, int vertNbr, int boxVertNbr, SCOTCH_Num *permVrtTab) { int boxNbr, vertIdx; SCOTCH_Num logMaxVal, SupMaxVal, InfMaxVal, maxVal; char s[200]; SCOTCH_Num *sortPartTb; SCOTCH_Strat strat ; SCOTCH_Arch arch; /* Computing the number of boxes */ boxNbr = vertNbr / boxVertNbr; if (boxNbr * boxVertNbr != vertNbr) { boxNbr = boxNbr + 1; } /* Initializing SCOTCH functions */ CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ; CHECK_SCOTCH(SCOTCH_archVcmplt(&arch), "scotch_archVcmplt", 0) ; sprintf(s, "m{vert=%d,low=r{job=t,map=t,poli=S,sep=m{type=h,vert=80,low=h{pass=10}f{bal=0.0005,move=80},asc=f{bal=0.005,move=80}}}}", vertNbr / boxVertNbr); CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, s), "scotch_stratGraphMap", 0) ; sortPartTb= (SCOTCH_Num *)M_calloc(2*vertNbr, sizeof(SCOTCH_Num), "boxCompute"); /* Partionning the graph */ CHECK_SCOTCH(SCOTCH_graphMap(&graf, &arch, &strat, sortPartTb), "scotch_graphMap", 0); // Looking for the max value in sortPartTb and computing sortPartTb as // followed : // - sortPartTb[2i] is the box value // - sortPartTb[2i+1] is the vertex number maxVal = sortPartTb[0]; for (vertIdx = vertNbr - 1 ; vertIdx >= 0 ; vertIdx--) { sortPartTb[2*vertIdx] = sortPartTb[vertIdx]; sortPartTb[2*vertIdx+1] = vertIdx + 1; if (sortPartTb[vertIdx] > maxVal) maxVal = sortPartTb[vertIdx]; } // Determining the log of MaxVal logMaxVal = 0; while ( maxVal > 0) { logMaxVal++; maxVal >>= 1; } // Infering the interval in which box values will be InfMaxVal = logMaxVal << logMaxVal; SupMaxVal = (logMaxVal << (logMaxVal + 1)) - 1; // Increasing box values until they are in the previous interval for (vertIdx = 0 ; vertIdx < vertNbr ; vertIdx++) { while (!(sortPartTb[2*vertIdx] >= InfMaxVal && sortPartTb[2*vertIdx] <= SupMaxVal)) { sortPartTb[2*vertIdx] <<= 1; } } // Sorting the tabular, which contains box values and vertex numbers _SCOTCHintSort2asc1(sortPartTb, vertNbr); /* Infering the new numbering */ for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++) { permVrtTab[sortPartTb[2*vertIdx + 1]] = vertIdx + 1; } SCOTCH_stratExit(&strat) ; SCOTCH_archExit(&arch) ; M_free(sortPartTb); return 0; }