Beispiel #1
0
/*************************************************************************
* Let the game begin
**************************************************************************/
main(int argc, char *argv[])
{
  int i, j, ne, nn, etype, numflag=0;
  idxtype *elmnts, *xadj, *adjncy;
  timer IOTmr, DUALTmr;
  char fileout[256], etypestr[4][5] = {"TRI", "TET", "HEX", "QUAD"};

  if (argc != 2) {
    printf("Usage: %s <meshfile>\n",argv[0]);
    exit(0);
  }

  cleartimer(IOTmr);
  cleartimer(DUALTmr);

  starttimer(IOTmr);
  elmnts = ReadMesh(argv[1], &ne, &nn, &etype);
  stoptimer(IOTmr);

  printf("**********************************************************************\n");
  printf("%s", METISTITLE);
  printf("Mesh Information ----------------------------------------------------\n");
  printf("  Name: %s, #Elements: %d, #Nodes: %d, Etype: %s\n\n", argv[1], ne, nn, etypestr[etype-1]);
  printf("Forming Nodal Graph... ----------------------------------------------\n");

  xadj = idxmalloc(nn+1, "main: xadj");
  adjncy = idxmalloc(20*nn, "main: adjncy");

  starttimer(DUALTmr);
  METIS_MeshToNodal(&ne, &nn, elmnts, &etype, &numflag, xadj, adjncy);
  stoptimer(DUALTmr);

  printf("  Nodal Information: #Vertices: %d, #Edges: %d\n", nn, xadj[nn]/2);

  sprintf(fileout, "%s.ngraph", argv[1]);
  starttimer(IOTmr);
  WriteGraph(fileout, nn, xadj, adjncy);
  stoptimer(IOTmr);


  printf("\nTiming Information --------------------------------------------------\n");
  printf("  I/O:          \t\t %7.3f\n", gettimer(IOTmr));
  printf("  Nodal Creation:\t\t %7.3f\n", gettimer(DUALTmr));
  printf("**********************************************************************\n");

  GKfree(&elmnts, &xadj, &adjncy, LTERM);

}
/**************************************************************************
* mexFunction: gateway routine for MATLAB interface.
***************************************************************************/
void mexFunction
(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    
    // Argument checking
    if (nrhs != 4)
        mexErrMsgIdAndTxt(FUNC_NAME, "Wrong input.");
    if (nlhs != 2)
        mexErrMsgIdAndTxt(FUNC_NAME, "Wrong output.");
    
    // Input and output variables
    idx_t ne = (idx_t) mxGetScalar(ne_in);
    idx_t nn = (idx_t) mxGetScalar(nn_in);
    idx_t *eptr; GetIdxArray(eptr_in,&eptr);
    idx_t *eind; GetIdxArray(eind_in,&eind);
    idx_t numflag = 0;
    idx_t *xadj = NULL;
    idx_t *adjncy = NULL;
    
    // Metis main function
    int info = METIS_MeshToNodal( &ne, &nn, eptr, eind, &numflag,
                    &xadj, &adjncy);
    CheckReturn(info, FUNC_NAME);
    
    // Output
    idx_t nvtxs = (idx_t) (sizeof(xadj)/sizeof(idx_t));
    xadj_out = mxCreateDoubleMatrix(1,nvtxs+1,mxREAL);
    mxSetData(xadj_out,mxMalloc(sizeof(double)*(nvtxs+1)));
    double *xadj_out_pr = mxGetPr(xadj_out);
    for(idx_t i=0; i<nvtxs+1; i++)
        xadj_out_pr[i] = (double) xadj[i];
    idx_t n = (idx_t) xadj[nvtxs];
    adjncy_out = mxCreateDoubleMatrix(1,n,mxREAL);
    mxSetData(adjncy_out,mxMalloc(sizeof(double)*n));
    double *adjncy_out_pr = mxGetPr(adjncy_out);
    for(idx_t i=0; i<n; i++)
        adjncy_out_pr[i] = (double) adjncy[i];
}
Beispiel #3
0
/*************************************************************************
* This function partitions a finite element mesh by partitioning its nodal
* graph using KMETIS and then assigning elements in a load balanced fashion.
**************************************************************************/
int METIS_PartMeshNodal(idx_t *ne, idx_t *nn, idx_t *eptr, idx_t *eind, 
          idx_t *vwgt, idx_t *vsize, idx_t *nparts, real_t *tpwgts, 
          idx_t *options, idx_t *objval, idx_t *epart, idx_t *npart)
{
  int sigrval=0, renumber=0, ptype;
  idx_t *xadj=NULL, *adjncy=NULL;
  idx_t ncon=1, pnumflag=0;
  int rstatus=METIS_OK;

  /* set up malloc cleaning code and signal catchers */
  if (!gk_malloc_init()) 
    return METIS_ERROR_MEMORY;

  gk_sigtrap();

  if ((sigrval = gk_sigcatch()) != 0) 
    goto SIGTHROW;

  renumber = GETOPTION(options, METIS_OPTION_NUMBERING, 0);
  ptype    = GETOPTION(options, METIS_OPTION_PTYPE, METIS_PTYPE_KWAY);

  /* renumber the mesh */
  if (renumber) {
    ChangeMesh2CNumbering(*ne, eptr, eind);
    options[METIS_OPTION_NUMBERING] = 0;
  }

  /* get the nodal graph */
  rstatus = METIS_MeshToNodal(ne, nn, eptr, eind, &pnumflag, &xadj, &adjncy);
  if (rstatus != METIS_OK)
    raise(SIGERR);

  /* partition the graph */
  if (ptype == METIS_PTYPE_KWAY) 
    rstatus = METIS_PartGraphKway(nn, &ncon, xadj, adjncy, vwgt, vsize, NULL, 
                  nparts, tpwgts, NULL, options, objval, npart);
  else 
    rstatus = METIS_PartGraphRecursive(nn, &ncon, xadj, adjncy, vwgt, vsize, NULL, 
                  nparts, tpwgts, NULL, options, objval, npart);

  if (rstatus != METIS_OK)
    raise(SIGERR);

  /* partition the other side of the mesh */
  InduceRowPartFromColumnPart(*ne, eptr, eind, epart, npart, *nparts, tpwgts);


SIGTHROW:
  if (renumber) {
    ChangeMesh2FNumbering2(*ne, *nn, eptr, eind, epart, npart);
    options[METIS_OPTION_NUMBERING] = 1;
  }

  METIS_Free(xadj);
  METIS_Free(adjncy);

  gk_siguntrap();
  gk_malloc_cleanup(0);

  return metis_rcode(sigrval);
}
Beispiel #4
0
void metis_meshtonodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
{
  METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
}
Beispiel #5
0
void METIS_MESHTONODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
{
  METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
}
Beispiel #6
0
/*************************************************************************
* This function partitions a finite element mesh by partitioning its nodal
* graph using KMETIS and then assigning elements in a load balanced fashion.
**************************************************************************/
void METIS_PartMeshNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, 
                         int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
{
  int i, j, k, me;
  idxtype *xadj, *adjncy, *pwgts;
  int options[10], pnumflag=0, wgtflag=0;
  int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
  int esize, esizes[] = {-1, 3, 4, 8, 4};

  esize = esizes[*etype];

  if (*numflag == 1)
    ChangeMesh2CNumbering((*ne)*esize, elmnts);

  xadj = idxmalloc(*nn+1, "METIS_MESHPARTNODAL: xadj");
  adjncy = idxmalloc(20*(*nn), "METIS_MESHPARTNODAL: adjncy");

  METIS_MeshToNodal(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy);

  adjncy = realloc(adjncy, xadj[*nn]*sizeof(idxtype));

  options[0] = 0;
  METIS_PartGraphKway(nn, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, npart);

  /* OK, now compute an element partition based on the nodal partition npart */
  idxset(*ne, -1, epart);
  pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTNODAL: pwgts");
  for (i=0; i<*ne; i++) {
    me = npart[elmnts[i*esize]];
    for (j=1; j<esize; j++) {
      if (npart[elmnts[i*esize+j]] != me)
        break;
    }
    if (j == esize) {
      epart[i] = me;
      pwgts[me]++;
    }
  }

  maxpwgt = 1.03*(*ne)/(*nparts);
  for (i=0; i<*ne; i++) {
    if (epart[i] == -1) { /* Assign the boundary element */
      nnbrs = 0;
      for (j=0; j<esize; j++) {
        me = npart[elmnts[i*esize+j]];
        for (k=0; k<nnbrs; k++) {
          if (nbrind[k] == me) {
            nbrwgt[k]++;
            break;
          }
        }
        if (k == nnbrs) {
          nbrind[nnbrs] = me;
          nbrwgt[nnbrs++] = 1;
        }
      }
      /* Try to assign it first to the domain with most things in common */
      j = iamax(nnbrs, nbrwgt);
      if (pwgts[nbrind[j]] < maxpwgt) {
        epart[i] = nbrind[j];
      }
      else {
        /* If that fails, assign it to a light domain */
        for (j=0; j<nnbrs; j++) {
          if (pwgts[nbrind[j]] < maxpwgt) {
            epart[i] = nbrind[j];
            break;
          }
        }
        if (j == nnbrs) 
          epart[i] = nbrind[iamax(nnbrs, nbrwgt)];
      }
      pwgts[epart[i]]++;
    }
  }

  if (*numflag == 1)
    ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart);

  GKfree(&xadj, &adjncy, &pwgts, LTERM);

}
Beispiel #7
0
/*************************************************************************
* Let the game begin
**************************************************************************/
int main(int argc, char *argv[])
{
  idxtype i, j, istep, options[10], nn, ne, fstep, lstep, nparts, nboxes, u[3], dim, nchanges, ncomm;
  char filename[256];
  idxtype *mien, *mrng, *part, *oldpart, *sflag, *bestdims, *fepart;
  double *mxyz, *bxyz;
  idxtype *xadj, *adjncy, *cntptr, *cntind;
  idxtype numflag = 0, wgtflag = 0, edgecut, etype=2;
  void *cinfo;
  FILE *fpin;
  long long int *ltmp;

  if (argc != 6) {
    mfprintf(stderr, "Usage: %s <nn> <ne> <fstep> <lstep> <nparts>\n", argv[0]);
    exit(0);
  }

  nn     = atoi(argv[1]);
  ne     = atoi(argv[2]);
  fstep  = atoi(argv[3]);
  lstep  = atoi(argv[4]);
  nparts = atoi(argv[5]);

  mprintf("Reading %s, nn: %D, ne: %D, fstep: %D, lstep: %D, nparts: %D\n", filename, nn, ne, fstep, lstep, nparts);

  mien = idxmalloc(4*ne, "main: mien");
  mxyz = gk_dmalloc(3*nn, "main: mxyz");
  mrng = idxmalloc(4*ne, "main: mrng");
  bxyz = gk_dmalloc(6*ne*4, "main: bxyz");

  fepart  = idxmalloc(nn, "main: fepart");
  part    = idxmalloc(nn, "main: part");
  oldpart = idxmalloc(nn, "main: oldpart");
  sflag   = idxmalloc(nn, "main: sflag");

  bestdims  = idxsmalloc(2*nparts, -1, "main: bestdims");

  xadj   = idxmalloc(nn+1, "main: xadj");
  adjncy = idxmalloc(50*nn, "main: adjncy");


  /*========================================================================
   * Read the initial mesh and setup the graph and contact information
   *========================================================================*/
  msprintf(filename, "mien.%04D", fstep);
  fpin = GKfopen(filename, "rb", "main: mien");
  fread(mien, sizeof(int), 4*ne, fpin);
  for (i=0; i<4*ne; i++)
    mien[i] = Flip_int32(mien[i]);
  GKfclose(fpin);

  msprintf(filename, "mxyz.%04D", fstep);
  fpin = GKfopen(filename, "rb", "main: mxyz");
  fread(mxyz, sizeof(double), 3*nn, fpin);
  for (i=0; i<3*nn; i++) {
    ltmp = (long long int *)(mxyz+i);
    *ltmp = Flip_int64(*ltmp);
  }
  GKfclose(fpin);
  mprintf("%e %e %e\n", mxyz[3*0+0], mxyz[3*0+1], mxyz[3*0+2]);

  msprintf(filename, "mrng.%04D", fstep);
  fpin = GKfopen(filename, "rb", "main: mrng");
  fread(mrng, sizeof(int), 4*ne, fpin);
  for (i=0; i<4*ne; i++)
    mrng[i] = Flip_int32(mrng[i]);
  GKfclose(fpin);


  /*========================================================================
   * Determine which nodes are in the surface
   *========================================================================*/
  iset(nn, 0, sflag);
  for (i=0; i<ne; i++) {
    if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
      sflag[mien[4*i+0]-1] = 1;
      sflag[mien[4*i+1]-1] = 1;
      sflag[mien[4*i+2]-1] = 1;
    }
    if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
      sflag[mien[4*i+0]-1] = 1;
      sflag[mien[4*i+1]-1] = 1;
      sflag[mien[4*i+3]-1] = 1;
    }
    if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
      sflag[mien[4*i+1]-1] = 1;
      sflag[mien[4*i+2]-1] = 1;
      sflag[mien[4*i+3]-1] = 1;
    }
    if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
      sflag[mien[4*i+0]-1] = 1;
      sflag[mien[4*i+2]-1] = 1;
      sflag[mien[4*i+3]-1] = 1;
    }
  }

  mprintf("Contact Nodes: %D of %D\n", isum(nn, sflag), nn);


  /*========================================================================
   * Compute the FE partition
   *========================================================================*/
  numflag = mien[idxargmin(4*ne, mien)];
  METIS_MeshToNodal(&ne, &nn, mien, &etype, &numflag, xadj, adjncy);

  options[0] = 0;
  METIS_PartGraphVKway(&nn, xadj, adjncy, NULL, NULL, &wgtflag, &numflag, &nparts,
        options, &edgecut, fepart);

  mprintf("K-way partitioning Volume: %D\n", edgecut);


  /*========================================================================
   * Get into the loop in which you go over the different configurations
   *========================================================================*/
  for (istep=fstep; istep<=lstep; istep++) {
    msprintf(filename, "mxyz.%04D", istep);
    mprintf("Reading %s...............................................................\n", filename);
    fpin = GKfopen(filename, "rb", "main: mxyz");
    fread(mxyz, sizeof(double), 3*nn, fpin);
    for (i=0; i<3*nn; i++) {
      ltmp = (long long int *)(mxyz+i);
      *ltmp = Flip_int64(*ltmp);
    }
    GKfclose(fpin);

    msprintf(filename, "mrng.%04D", istep);
    fpin = GKfopen(filename, "rb", "main: mrng");
    fread(mrng, sizeof(int), 4*ne, fpin);
    for (i=0; i<4*ne; i++)
      mrng[i] = Flip_int32(mrng[i]);
    GKfclose(fpin);

    /* Determine which nodes are in the surface */
    iset(nn, 0, sflag);
    for (i=0; i<ne; i++) {
      if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
        sflag[mien[4*i+0]-1] = 1;
        sflag[mien[4*i+1]-1] = 1;
        sflag[mien[4*i+2]-1] = 1;
      }
      if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
        sflag[mien[4*i+0]-1] = 1;
        sflag[mien[4*i+1]-1] = 1;
        sflag[mien[4*i+3]-1] = 1;
      }
      if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
        sflag[mien[4*i+1]-1] = 1;
        sflag[mien[4*i+2]-1] = 1;
        sflag[mien[4*i+3]-1] = 1;
      }
      if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
        sflag[mien[4*i+0]-1] = 1;
        sflag[mien[4*i+2]-1] = 1;
        sflag[mien[4*i+3]-1] = 1;
      }
    }

    mprintf("Contact Nodes: %D of %D\n", isum(nn, sflag), nn);

    /* Determine the bounding boxes of the surface elements */
    for (nboxes=0, i=0; i<ne; i++) {
      if (mrng[4*i+0] > 0) { /* 1, 2, 3 */
        u[0] = mien[4*i+0]-1;
        u[1] = mien[4*i+1]-1;
        u[2] = mien[4*i+2]-1;
        bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
        bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
        bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
        for (j=1; j<3; j++) {
          for (dim=0; dim<3; dim++) {
            bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
            bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
          }
        }
        nboxes++;
      }
      if (mrng[4*i+1] > 0) { /* 1, 2, 4 */
        u[0] = mien[4*i+0]-1;
        u[1] = mien[4*i+1]-1;
        u[2] = mien[4*i+3]-1;
        bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
        bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
        bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
        for (j=1; j<3; j++) {
          for (dim=0; dim<3; dim++) {
            bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
            bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
          }
        }
        nboxes++;
      }
      if (mrng[4*i+2] > 0) { /* 2, 3, 4 */
        u[0] = mien[4*i+1]-1;
        u[1] = mien[4*i+2]-1;
        u[2] = mien[4*i+3]-1;
        bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
        bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
        bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
        for (j=1; j<3; j++) {
          for (dim=0; dim<3; dim++) {
            bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
            bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
          }
        }
        nboxes++;
      }
      if (mrng[4*i+3] > 0) { /* 1, 3, 4 */
        u[0] = mien[4*i+0]-1;
        u[1] = mien[4*i+2]-1;
        u[2] = mien[4*i+3]-1;
        bxyz[6*nboxes+0] = bxyz[6*nboxes+3] = mxyz[3*u[0]+0];
        bxyz[6*nboxes+1] = bxyz[6*nboxes+4] = mxyz[3*u[0]+1];
        bxyz[6*nboxes+2] = bxyz[6*nboxes+5] = mxyz[3*u[0]+2];
        for (j=1; j<3; j++) {
          for (dim=0; dim<3; dim++) {
            bxyz[6*nboxes+dim] = (bxyz[6*nboxes+dim] > mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+dim]);
            bxyz[6*nboxes+3+dim] = (bxyz[6*nboxes+3+dim] < mxyz[3*u[j]+dim] ? mxyz[3*u[j]+dim] : bxyz[6*nboxes+3+dim]);
          }
        }
        nboxes++;
      }
    }

    cinfo = METIS_PartSurfForContactRCB(&nn, mxyz, sflag, &nparts, part, bestdims);

    METIS_FindContacts(cinfo, &nboxes, bxyz, &nparts, &cntptr, &cntind);

    METIS_FreeContactInfo(cinfo);

    nchanges = 0;
    if (istep > fstep) {
      for (i=0; i<nn; i++)
        nchanges += (part[i] != oldpart[i] ? 1 : 0);
    }
    idxcopy(nn, part, oldpart);

    ncomm = ComputeMapCost(nn, nparts, fepart, part);

    mprintf("Contacting Elements: %D  Indices: %D  Nchanges: %D  MapCost: %D\n", nboxes, cntptr[nboxes]-nboxes, nchanges, ncomm);

    gk_free((void **)&cntptr, &cntind, LTERM);
  }

}