Exemple #1
0
static dErr CommitToFaceSets(iMesh_Instance mesh,dMeshEH *ents,int **face,int *facecount,dMeshESH *facesets,dMeshEH *entbuf)
{
  int err;
  for (int f=0; f<6; f++) {
    for (int i=0; i<facecount[f]; i++) entbuf[i] = ents[face[f][i]];
    iMesh_addEntArrToSet(mesh,entbuf,facecount[f],facesets[f],&err);dICHK(mesh,err);
    facecount[f] = 0;           /* Clear for future use */
  }
  return 0;
}
Exemple #2
0
/**\brief Add copied entities/sets recursively
 *
 * Helper function for process_ce_sets. This adds any entities directly
 * contained in the current set to the dest set and then loops through the
 * contained sets and adds the children if they are also CE sets. If not, it
 * adds the entities in the child set and recurses down a level.
 * \param imeshImpl the iMesh instance handle
 * \param src the source set
 * \param current the child set to examine (start with current == src)
 * \param local_tag the tag relating source and target sets
 */
static
void process_ce_subsets(iMesh_Instance imeshImpl, iBase_EntitySetHandle src,
                        iBase_EntitySetHandle current,
                        const std::set<iBase_EntitySetHandle> &cesets,
                        iBase_TagHandle local_tag) 
{
  int err;
  iBase_EntitySetHandle dest;

  // First, add entities directly contained in this set.
  std::vector<iBase_EntityHandle> tmp_tags;
  get_copied_ents(imeshImpl, current, local_tag, tmp_tags);

  if (!tmp_tags.empty()) {
    get_dest_set(imeshImpl, local_tag, src, &dest);
    iMesh_addEntArrToSet(imeshImpl, &tmp_tags[0], tmp_tags.size(), dest,
                         &err);
    check_error(imeshImpl, err);
  }

  // Next, start looking at children.
  SimpleArray<iBase_EntitySetHandle> children;
  iMesh_getEntSets(imeshImpl, current, 1, ARRAY_INOUT(children), &err);
  check_error(imeshImpl, err);

  for (int i = 0; i < children.size(); i++) {

    // If this child set is one of our cesets, add just the set...
    if (cesets.find(children[i]) != cesets.end()) {
      get_dest_set(imeshImpl, local_tag, src, &dest);
      if (src == dest) continue;

      iMesh_addEntSet(imeshImpl, children[i], dest, &err);
      check_error(imeshImpl, err);
    }

    // ... otherwise, add the entities and recurse into the next level of
    // children.
    else {
      process_ce_subsets(imeshImpl, src, children[i], cesets, local_tag);
    }
  }
}
Exemple #3
0
static dErr doMaterial(iMesh_Instance mesh,iBase_EntitySetHandle root)
{
  static const char matSetName[] = "MAT_SET",matNumName[] = "MAT_NUM";
  dMeshTag matSetTag,matNumTag;
  dMeshESH mat[2];
  dMeshEH *ents;
  MeshListEH r=MLZ,v=MLZ;
  MeshListInt rvo=MLZ;
  MeshListReal x=MLZ;
  dReal fx,center[3],*matnum;
  dInt nents;
  dErr err;

  dFunctionBegin;
  iMesh_createTag(mesh,matSetName,1,iBase_INTEGER,&matSetTag,&err,sizeof(matSetName));dICHK(mesh,err);
  iMesh_createTag(mesh,matNumName,1,iBase_DOUBLE,&matNumTag,&err,sizeof(matNumName));dICHK(mesh,err);
  iMesh_getEntities(mesh,root,iBase_REGION,iMesh_ALL_TOPOLOGIES,MLREF(r),&err);dICHK(mesh,err);
  iMesh_getEntArrAdj(mesh,r.v,r.s,iBase_VERTEX,MLREF(v),MLREF(rvo),&err);dICHK(mesh,err);
  iMesh_getVtxArrCoords(mesh,v.v,v.s,iBase_INTERLEAVED,MLREF(x),&err);dICHK(mesh,err);
  err = dMalloc(r.s*sizeof(ents[0]),&ents);dCHK(err);
  err = dMalloc(r.s*sizeof(matnum[0]),&matnum);dCHK(err);
  for (dInt i=0; i<2; i++) {
    iMesh_createEntSet(mesh,0,&mat[i],&err);dICHK(mesh,err);
    iMesh_setEntSetData(mesh,mat[i],matSetTag,(char*)&i,sizeof(i),&err);dICHK(mesh,err);
    nents = 0;
    for (dInt j=0; j<r.s; j++) {
      dGeomVecMeanI(8,x.v+3*rvo.v[j],center);
      fx = sqrt(dGeomDotProd(center,center)); /* material 0 if inside the unit ball, else material 1 */
      if (i == (fx < 1.0) ? 0 : 1) {
        ents[nents] = r.v[j];
        matnum[nents] = 1.0 * i;
        nents++;
      }
    }
    iMesh_addEntArrToSet(mesh,ents,nents,mat[i],&err);dICHK(mesh,err);
    iMesh_setArrData(mesh,ents,nents,matNumTag,(char*)matnum,nents*(int)sizeof(matnum[0]),&err);dICHK(mesh,err);
  }
  err = dFree(ents);dCHK(err);
  err = dFree(matnum);dCHK(err);
  MeshListFree(r); MeshListFree(v); MeshListFree(rvo); MeshListFree(x);
  dFunctionReturn(0);
}
Exemple #4
0
// Generates a mesh of a brick using run-time parameters.
// The new mesh populates the given root set.
// This should be converted to have a useful programmatic API.
dErr dMeshGenerateBlock(dMesh dmesh,dMeshESH root,PetscBool do_geom)
{
  const char pTagName[]="OWNING_PART", pSetName[]="PARALLEL_PARTITION";
  PetscBool  assoc_with_brick=0,do_color_bdy=0,do_material = 1,do_uniform = 1,do_global_number = 0,do_global_id = 1;
  PetscBool  do_partition = 1,do_pressure = 0,do_faces = 1,do_edges = 1;
  dReal rotate_y = 0;
  dInt verbose = 0;
  iMesh_Instance mesh;
  iBase_EntityHandle *entbuf;
  iBase_EntitySetHandle facesets[6];
  iBase_TagHandle pTag;
  MeshListEH v=MLZ,e=MLZ,f=MLZ,r=MLZ,c=MLZ;
  MeshListReal x=MLZ;
  MeshListInt s=MLZ,part=MLZ;
  dInt *face[6],facecount[6]={0};
  int err,i,j,k,m,n,p,M,N,P,I,J,K,order=iBase_INTERLEAVED;
  Box box;
  PetscViewer viewer;

  dFunctionBegin;
  dValidHeader(dmesh,dMESH_CLASSID,1);
  err = PetscViewerASCIIGetStdout(((PetscObject)dmesh)->comm,&viewer);dCHK(err);
  err = PetscOptionsBegin(((PetscObject)dmesh)->comm,((PetscObject)dmesh)->prefix,"dMeshGenerate Block: generate cartesian meshes",NULL);dCHK(err);
  {
    char boxstr[256] = "-1:1,-1:1,-1:1",mnp[256] = "5,5,5",MNP[256] = "2,2,2";
    err = PetscOptionsInt("-dmeshgen_block_verbose","verbosity of output","none",verbose,&verbose,NULL);dCHK(err);
    if (do_geom) {
      err = PetscOptionsBool("-dmeshgen_block_assoc_with_brick","associate boundaries with brick","none",assoc_with_brick,&assoc_with_brick,NULL);dCHK(err);
    }
    err = PetscOptionsBool("-dmeshgen_block_color_bdy","color boundary sets","none",do_color_bdy,&do_color_bdy,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_material","create material sets","none",do_material,&do_material,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_uniform","create uniform sets","none",do_uniform,&do_uniform,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_global_number","create global_number tags","none",do_global_number,&do_global_number,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_global_id","create GLOBAL_ID tags","none",do_global_id,&do_global_id,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_partition","create partition sets","none",do_partition,&do_partition,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_pressure","create pressure sets","none",do_pressure,&do_pressure,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_faces","create face entities","none",do_faces,&do_faces,NULL);dCHK(err);
    err = PetscOptionsBool("-dmeshgen_block_edges","create face entities","none",do_edges,&do_edges,NULL);dCHK(err);
    err = PetscOptionsReal("-dmeshgen_block_rotate_y","rotate domain by given angle (degrees) around y axis)","none",rotate_y,&rotate_y,NULL);dCHK(err); rotate_y *= PETSC_PI/180.;
    err = PetscOptionsString("-dmeshgen_block_box","box x0:x1,y0:y1,z0:z1","none",boxstr,boxstr,sizeof(boxstr),NULL);dCHK(err);
    err = PetscOptionsString("-dmeshgen_block_mnp","number of points m,n,p","none",mnp,mnp,sizeof(mnp),NULL);dCHK(err);
    err = PetscOptionsString("-dmeshgen_block_procs_mnp","number of procs M,N,P","none",MNP,MNP,sizeof(MNP),NULL);dCHK(err);

    i = sscanf(boxstr,"%lf:%lf,%lf:%lf,%lf:%lf",&box.x0,&box.x1,&box.y0,&box.y1,&box.z0,&box.z1);
    if (i != 6) dERROR(PETSC_COMM_SELF,1,"Failed to parse bounding box.");
    i = sscanf(mnp,"%d,%d,%d",&m,&n,&p);
    if (i != 3) dERROR(PETSC_COMM_SELF,1,"Failed to parse size.");
    i = sscanf(MNP,"%d,%d,%d",&M,&N,&P);
    if (i != 3) dERROR(PETSC_COMM_SELF,1,"Failed to parse partition size.");
  }
  err = PetscOptionsEnd();
  err = dMeshGetInstance(dmesh,&mesh);dCHK(err);

  /* Allocate buffers */
  err = dMallocA(m*n*p*3,&entbuf);dCHK(err); /* More than enough to hold all entities of any given type */
  for (i=0; i<6; i++) {
    int n2max = dSqrInt(dMaxInt(m,dMaxInt(n,p)));
    err = dMallocA(2*n2max,&face[i]);dCHK(err);
    iMesh_createEntSet(mesh,0,&facesets[i],&err);dICHK(mesh,err);
  }

  /* Create vertices */
  x.a = x.s = m*n*p*3; x.v = malloc(x.a*sizeof(double));
  for (i=0; i<m; i++) {
    for (j=0; j<n; j++) {
      for (k=0; k<p; k++) {
        dReal X,Y,Z;
        I = (i*n+j)*p+k;
        if (i==0) AddToFace(face,facecount,3,I);
        else if (i==m-1) AddToFace(face,facecount,1,I);
        else if (j==0) AddToFace(face,facecount,0,I);
        else if (j==n-1) AddToFace(face,facecount,2,I);
        else if (k==0) AddToFace(face,facecount,4,I);
        else if (k==p-1) AddToFace(face,facecount,5,I);
        X = box.x0 + (box.x1-box.x0)*(1.*i/(m-1));
        Y = box.y0 + (box.y1-box.y0)*(1.*j/(n-1));
        Z = box.z0 + (box.z1-box.z0)*(1.*k/(p-1));
        x.v[3*I+0] = cos(rotate_y) * X - sin(rotate_y) * Z;
        x.v[3*I+1] = Y;
        x.v[3*I+2] = sin(rotate_y) * X + cos(rotate_y) * Z;
      }
    }
  }
  iMesh_createVtxArr(mesh,m*n*p,order,x.v,x.s,&v.v,&v.a,&v.s,&err);dICHK(mesh,err);
  err = CommitToFaceSets(mesh,v.v,face,facecount,facesets,entbuf);
  MeshListFree(x);

  /* Create regions */
  c.a = c.s = (m-1)*(n-1)*(p-1)*8; c.v = malloc(c.a*sizeof(iBase_EntityHandle)); /* connectivity */
  I=0;
  for (i=0; i<m-1; i++) {
    for (j=0; j<n-1; j++) {
      for (k=0; k<p-1; k++) {
        c.v[I++] = v.v[((i+0)*n+(j+0))*p+(k+0)];
        c.v[I++] = v.v[((i+1)*n+(j+0))*p+(k+0)];
        c.v[I++] = v.v[((i+1)*n+(j+1))*p+(k+0)];
        c.v[I++] = v.v[((i+0)*n+(j+1))*p+(k+0)];
        c.v[I++] = v.v[((i+0)*n+(j+0))*p+(k+1)];
        c.v[I++] = v.v[((i+1)*n+(j+0))*p+(k+1)];
        c.v[I++] = v.v[((i+1)*n+(j+1))*p+(k+1)];
        c.v[I++] = v.v[((i+0)*n+(j+1))*p+(k+1)];
      }
    }
  }
  if (I != c.s) dERROR(PETSC_COMM_SELF,1,"Wrong number of regions.");
  iMesh_createEntArr(mesh,iMesh_HEXAHEDRON,c.v,c.s,&r.v,&r.a,&r.s,&s.v,&s.a,&s.s,&err);dICHK(mesh,err);
  if (r.s != (m-1)*(n-1)*(p-1)) dERROR(PETSC_COMM_SELF,1,"Wrong number of regions created.");
  if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"region size %d, status size %d\n",r.s,s.s);dCHK(err);}

  if (do_global_number) {err = doGlobalNumber(mesh,root);dCHK(err);}
  if (do_global_id) {err = doGlobalID(mesh,root);dCHK(err);}

  if (do_partition) {           /* Partition tags */
    /* Create partition. */
    part.a = part.s = r.s; part.v = malloc(part.a*sizeof(int));
    for (i=0; i<m-1; i++) {
      for (j=0; j<n-1; j++) {
        for (k=0; k<p-1; k++) {
          I = i*M/(m-1); J = j*N/(n-1); K = k*P/(p-1);
          part.v[(i*(n-1)+j)*(p-1)+k] = (I*N+J)*P+K;
        }
      }
    }
    /* MATERIAL_SET is a special name associated with all iMesh instances
    * If we are using a different name, we can assume it is not special. */
    if (strcmp(pTagName,"MATERIAL_SET")) {
      iMesh_createTag(mesh,pTagName,1,iBase_INTEGER,&pTag,&err,sizeof(pTagName));dICHK(mesh,err);
    } else {
      iMesh_getTagHandle(mesh,"MATERIAL_SET",&pTag,&err,sizeof("MATERIAL_SET"));dICHK(mesh,err);
    }
    iMesh_setIntArrData(mesh,r.v,r.s,pTag,part.v,part.s,&err);dICHK(mesh,err);
    MeshListFree(part);
  }

  if (do_partition)             /* Partition sets */
  {
    int ii,jj,kk;
    iBase_EntitySetHandle partset;
    iBase_EntityHandle *entp;
    /* reuse some stuff, set up the a partition set */
    iMesh_createTag(mesh,pSetName,1,iBase_INTEGER,&pTag,&err,sizeof(pSetName));dICHK(mesh,err);
    for (i=0; i<M; i++) {
      for (j=0; j<N; j++) {
        for (k=0; k<P; k++) {
          iMesh_createEntSet(mesh,0,&partset,&err);dICHK(mesh,err);
          entp = entbuf;
          for (ii=i*(m-1)/M; ii<(i+1)*(m-1)/M; ii++) {
            for (jj=j*(n-1)/N; jj<(j+1)*(n-1)/N; jj++) {
              for (kk=k*(p-1)/P; kk<(k+1)*(p-1)/P; kk++) {
                *entp++ = r.v[(ii*(n-1)+jj)*(p-1)+kk];
              }
            }
          }
          if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"part[%d (%d,%d,%d)] has %d regions\n",(i*N+j)*P+k,i,j,k,(int)(entp-entbuf));dCHK(err);}
          iMesh_addEntArrToSet(mesh,entbuf,(int)(entp-entbuf),partset,&err);dICHK(mesh,err);
          iMesh_setEntSetIntData(mesh,partset,pTag,(i*N+j)*P+k,&err);dICHK(mesh,err);
        }
      }
    }
  }
  MeshListFree(r); MeshListFree(s); MeshListFree(c);

  if (do_faces)
  {
    /* Create faces */
    c.a = c.s = 4*((m-1)*(n-1)*p + (m-1)*n*(p-1) + m*(n-1)*(p-1)); c.v = malloc(c.a*sizeof(iBase_EntityHandle));
    I = 0;
    for (i=0; i<m-1; i++) {     /* Faces with normal pointing in positive z direction */
      for (j=0; j<n-1; j++) {
        for (k=0; k<p; k++) {
          if (k==0) AddToFace(face,facecount,4,I/4);
          if (k==p-1) AddToFace(face,facecount,5,I/4);
          c.v[I++] = v.v[((i+0)*n+(j+0))*p+k];
          c.v[I++] = v.v[((i+1)*n+(j+0))*p+k];
          c.v[I++] = v.v[((i+1)*n+(j+1))*p+k];
          c.v[I++] = v.v[((i+0)*n+(j+1))*p+k];
        }
      }
    }
    for (i=0; i<m-1; i++) {     /* Faces with normal pointing in negative y direction */
      for (j=0; j<n; j++) {
        for (k=0; k<p-1; k++) {
          if (j==0) AddToFace(face,facecount,0,I/4);
          if (j==n-1) AddToFace(face,facecount,2,I/4);
          c.v[I++] = v.v[((i+0)*n+j)*p+(k+0)];
          c.v[I++] = v.v[((i+1)*n+j)*p+(k+0)];
          c.v[I++] = v.v[((i+1)*n+j)*p+(k+1)];
          c.v[I++] = v.v[((i+0)*n+j)*p+(k+1)];
        }
      }
    }
    for (i=0; i<m; i++) {       /* Faces with normal pointing in positive x direction */
      for (j=0; j<n-1; j++) {
        for (k=0; k<p-1; k++) {
          if (i==0) AddToFace(face,facecount,3,I/4);
          if (i==m-1) AddToFace(face,facecount,1,I/4);
          c.v[I++] = v.v[(i*n+(j+0))*p+(k+0)];
          c.v[I++] = v.v[(i*n+(j+1))*p+(k+0)];
          c.v[I++] = v.v[(i*n+(j+1))*p+(k+1)];
          c.v[I++] = v.v[(i*n+(j+0))*p+(k+1)];
        }
      }
    }
    if (I != c.s) dERROR(PETSC_COMM_SELF,1, "Wrong number of faces.");
    iMesh_createEntArr(mesh,iMesh_QUADRILATERAL,c.v,c.s,&f.v,&f.a,&f.s,&s.v,&s.a,&s.s,&err);dICHK(mesh,err);
    err = CommitToFaceSets(mesh,f.v,face,facecount,facesets,entbuf);dCHK(err);
    if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"face size %d, status size %d\n",f.s,s.s);dCHK(err);}
    MeshListFree(f); MeshListFree(s); MeshListFree(c);
  }

  if (do_edges)
  {
    /* Create edges */
    c.a = c.s = 2*(m*n*(p-1) + m*(n-1)*p + (m-1)*n*p); c.v = malloc(c.a*sizeof(iBase_EntityHandle));
    I = 0;
    for (i=0; i<m; i++) {
      for (j=0; j<n; j++) {
        for (k=0; k<p-1; k++) {
          if (i==0) AddToFace(face,facecount,0,I/2);
          else if (i==m-1) AddToFace(face,facecount,2,I/2);
          else if (j==0) AddToFace(face,facecount,3,I/2);
          else if (j==n-1) AddToFace(face,facecount,1,I/2);
          c.v[I++] = v.v[(i*n+j)*p+(k+0)];
          c.v[I++] = v.v[(i*n+j)*p+(k+1)];
        }
      }
    }
    for (i=0; i<m; i++) {
      for (j=0; j<n-1; j++) {
        for (k=0; k<p; k++) {
          if (i==0) AddToFace(face,facecount,0,I/2);
          else if (i==m-1) AddToFace(face,facecount,2,I/2);
          else if (k==0) AddToFace(face,facecount,4,I/2);
          else if (k==p-1) AddToFace(face,facecount,5,I/2);
          c.v[I++] = v.v[(i*n+(j+0))*p+k];
          c.v[I++] = v.v[(i*n+(j+1))*p+k];
        }
      }
    }
    for (i=0; i<m-1; i++) {
      for (j=0; j<n; j++) {
        for (k=0; k<p; k++) {
          if (j==0) AddToFace(face,facecount,3,I/2);
          else if (j==n-1) AddToFace(face,facecount,1,I/2);
          else if (k==0) AddToFace(face,facecount,4,I/2);
          else if (k==p-1) AddToFace(face,facecount,5,I/2);
          c.v[I++] = v.v[((i+0)*n+j)*p+k];
          c.v[I++] = v.v[((i+1)*n+j)*p+k];
        }
      }
    }
    if (I != c.s) dERROR(PETSC_COMM_SELF,1, "Wrong number of edges.");
    iMesh_createEntArr(mesh,iMesh_LINE_SEGMENT,c.v,c.s, &e.v,&e.a,&e.s, &s.v,&s.a,&s.s,&err);dICHK(mesh,err);
    err = CommitToFaceSets(mesh,e.v,face,facecount,facesets,entbuf);dCHK(err);
    if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"edge size %d, status size %d\n",e.s,s.s);dCHK(err);}
    MeshListFree(e); MeshListFree(s); MeshListFree(c);
  }

  /* We are done with the master vertex record. */
  MeshListFree(v);

  /* Create boundary sets, these are not related to geometry here */
  {
    dMeshESH wallset,topset,bottomset,senseSet;
    iBase_TagHandle bdyTag,senseTag;
    iMesh_getTagHandle(mesh,"NEUMANN_SET",&bdyTag,&err,sizeof("NEUMANN_SET"));dICHK(mesh,err);
    iMesh_createTag(mesh,"SENSE",1,iBase_INTEGER,&senseTag,&err,sizeof "SENSE");dICHK(mesh,err);
    iMesh_createEntSet(mesh,0,&wallset,&err);dICHK(mesh,err);
    iMesh_createEntSet(mesh,0,&topset,&err);dICHK(mesh,err);
    iMesh_createEntSet(mesh,0,&bottomset,&err);dICHK(mesh,err);
    iMesh_setEntSetIntData(mesh,wallset,bdyTag,100,&err);dICHK(mesh,err);
    iMesh_setEntSetIntData(mesh,topset,bdyTag,200,&err);dICHK(mesh,err);
    iMesh_setEntSetIntData(mesh,bottomset,bdyTag,300,&err);dICHK(mesh,err);
    for (i=0; i<4; i++) {iMesh_addEntSet(mesh,facesets[i],wallset,&err);dICHK(mesh,err);}
    iMesh_addEntSet(mesh,facesets[5],topset,&err);dICHK(mesh,err);
    iMesh_addEntSet(mesh,facesets[4],bottomset,&err);dICHK(mesh,err);

    /* Deal with SENSE on the walls */
    iMesh_createEntSet(mesh,0,&senseSet,&err);dICHK(mesh,err);
    iMesh_addEntSet(mesh,facesets[2],senseSet,&err);dICHK(mesh,err);
    iMesh_addEntSet(mesh,facesets[3],senseSet,&err);dICHK(mesh,err);
    iMesh_setEntSetIntData(mesh,senseSet,senseTag,-1,&err);dICHK(mesh,err);
    iMesh_addEntSet(mesh,senseSet,wallset,&err);dICHK(mesh,err);

    /* Deal with SENSE on the bottom */
    iMesh_createEntSet(mesh,0,&senseSet,&err);dICHK(mesh,err);
    iMesh_addEntSet(mesh,facesets[4],senseSet,&err);dICHK(mesh,err);
    iMesh_setEntSetIntData(mesh,senseSet,senseTag,-1,&err);dICHK(mesh,err);
    iMesh_addEntSet(mesh,senseSet,bottomset,&err);dICHK(mesh,err);

    for (i=0; i<6; i++) {err = dFree(face[i]);}
    err = dFree(entbuf);dCHK(err);
  }

  if (do_material) {err = doMaterial(mesh,root);dCHK(err);}

  /* Add a real valued tag over the vertices. */
  if (do_pressure) {
    static const char *myTagName = "pressure";
    iBase_TagHandle myTag;
    double *myData;

    iMesh_getEntities(mesh,root,iBase_VERTEX,iMesh_POINT,&v.v,&v.a,&v.s,&err);dICHK(mesh,err);
    iMesh_createTag(mesh,myTagName,1,iBase_DOUBLE,&myTag,&err,(int)strlen(myTagName));dICHK(mesh,err);
    err = PetscMalloc(v.s*sizeof(double),&myData);dCHK(err);
    for (i=0; i<v.s; i++) { myData[i] = 1.0 * i; }
    iMesh_setDblArrData(mesh,v.v,v.s,myTag,myData,v.s,&err);dICHK(mesh,err);
    err = PetscFree(myData);dCHK(err);
    MeshListFree(v);
  }

  if (do_uniform) {err = createUniformTags(mesh,root);dCHK(err);}

  if (do_geom)
#ifndef dHAVE_ITAPS_REL
    dERROR(((dObject)dmesh)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Dohp has not been configured with support for geometry");
#else
  {
    const char geom_options[] = ";ENGINE=OCC;";
    const char rel_options[] = "";
    iGeom_Instance geom;
    iRel_Instance assoc;
    iRel_PairHandle pair;
    iBase_EntityHandle brick;
    iGeom_newGeom(geom_options,&geom,&err,sizeof geom_options);dIGCHK(geom,err);
    iRel_create(rel_options,&assoc,&err,sizeof rel_options);dIRCHK(assoc,err);
    iRel_createPair(assoc,geom,0,iRel_IGEOM_IFACE,iRel_ACTIVE,mesh,1,iRel_IMESH_IFACE,iRel_ACTIVE,&pair,&err);dIGCHK(assoc,err);
    iGeom_createBrick(geom,box.x1-box.x0,box.y1-box.y0,box.z1-box.z0,&brick,&err);dIGCHK(geom,err);
    iGeom_moveEnt(geom,brick,0.5*(box.x0+box.x1),0.5*(box.y0+box.y1),0.5*(box.z0+box.z1),&err);dIGCHK(geom,err);
    if (verbose > 0) {err = BoundingBoxView(geom,brick,"brick",viewer);dCHK(err);}
    {
      iBase_EntityHandle gface[6],*gface_p=gface;
      int gface_a=6,gface_s;
      iGeom_getEntAdj(geom,brick,2,&gface_p,&gface_a,&gface_s,&err);dIGCHK(geom,err);
      for (i=0; i<6; i++) {
        char name[20];
        sprintf(name,"face_%d",i);
        err = BoundingBoxView(geom,gface[i],name,viewer);dCHK(err);
      }
      if (assoc_with_brick) {
        for (i=0; i<6; i++) {
          iRel_setEntSetRelation(assoc,pair,brick,facesets[i],&err);dIRCHK(assoc,err);
        }
      } else {
        /* Set associations.  With the current Lasso implementation, these will not be saved */
        iRel_setEntSetRelation(assoc,pair,gface[0],facesets[3],&err);dIRCHK(assoc,err);
        iRel_setEntSetRelation(assoc,pair,gface[1],facesets[1],&err);dIRCHK(assoc,err);
        iRel_setEntSetRelation(assoc,pair,gface[2],facesets[0],&err);dIRCHK(assoc,err);
        iRel_setEntSetRelation(assoc,pair,gface[3],facesets[2],&err);dIRCHK(assoc,err);
        iRel_setEntSetRelation(assoc,pair,gface[4],facesets[4],&err);dIRCHK(assoc,err);
        iRel_setEntSetRelation(assoc,pair,gface[5],facesets[5],&err);dIRCHK(assoc,err);
      }
    }
    {
      dMeshTag meshGlobalIDTag,meshGeomDimTag,geomGlobalIDTag;
      /* Manually set association tags, these are set so that the associations above can be inferred. */
      iMesh_getTagHandle(mesh,"GLOBAL_ID",&meshGlobalIDTag,&err,sizeof "GLOBAL_ID");dICHK(mesh,err);
      iMesh_getTagHandle(mesh,"GEOM_DIMENSION",&meshGeomDimTag,&err,sizeof "GEOM_DIMENSION");dICHK(mesh,err);
      iGeom_getTagHandle(geom,"GLOBAL_ID",&geomGlobalIDTag,&err,sizeof "GLOBAL_ID");dIGCHK(geom,err);
      for (i=0; i<6; i++) {
        iBase_EntityHandle gface;
        int gid,gdim;
        iRel_getSetEntRelation(assoc,pair,facesets[i],1,&gface,&err);dIRCHK(assoc,err);
        iGeom_getEntType(geom,gface,&gdim,&err);dIGCHK(geom,err);
        if (gdim != 2) dERROR(PETSC_COMM_SELF,1,"Geometric dimension is %d, expected 2",gdim);
        iGeom_getIntData(geom,gface,geomGlobalIDTag,&gid,&err);dIGCHK(geom,err);
        iMesh_setEntSetIntData(mesh,facesets[i],meshGeomDimTag,2,&err);dICHK(mesh,err);
        /* If the following line is disabled, Lasso will pick up the wrong relations, but at least they will still be with
        * surfaces.  Wouldn't it be better to not find relations? */
        iMesh_setEntSetIntData(mesh,facesets[i],meshGlobalIDTag,gid,&err);dICHK(mesh,err);
      }
    }
    err = dMeshSetGeometryRelation(dmesh,geom,assoc);dCHK(err);
  }
#endif
  dFunctionReturn(0);
}
Exemple #5
0
/*! 
 * \brief Build a tree node.
 */
void Octree::buildTreeNode( RCP_Node node )
{
    int error = 0;

    // Create the children.
    for ( int i = 0; i < 8; ++i )
    {
	node->children[i] = Teuchos::rcp( new OctreeNode );

	iMesh_createEntSet( d_mesh,
			    1,
			    &(node->children[i]->node_set),
			    &error );
	assert( iBase_SUCCESS == error );
    }

    // Create the new bounding boxes and assign them to the children.
    sliceBox( node );

    // Add the elements in the parent set to the child sets.
    std::vector<iBase_EntityHandle> root_list;
    int node_elements_allocated = 0;
    int node_elements_size = 0;
    iBase_EntityHandle *node_elements;
    iMesh_getEntities( d_mesh,
		       node->node_set,
		       d_entity_type,
		       d_entity_topology,
		       &node_elements,
		       &node_elements_allocated,
		       &node_elements_size,
		       &error );
    assert( iBase_SUCCESS == error );

    bool element_found = false;
    for (int n = 0; n < node_elements_size; ++n )
    {
	element_found = false;

	for ( int m = 0; m < 8; ++m )
	{
	    if ( !element_found )
	    {
		if ( isEntInBox( node->children[m]->bounding_box, 
				 node_elements[n] ) )
		{
		    iMesh_addEntToSet( d_mesh,
				       node_elements[n],
				       node->children[m]->node_set,
				       &error );
		    assert( iBase_SUCCESS == error );

		    if ( node != d_root_node )
		    {
			iMesh_rmvEntFromSet( d_mesh,
					     node_elements[n],
					     node->node_set,
					     &error );
			assert( iBase_SUCCESS == error );
		    }

		    element_found = true;
		}
	    }

	}

	if ( !element_found )
	{
	    root_list.push_back( node_elements[n] );
	}
    }

    free( node_elements );

    // Special case for the root node.
    if ( node == d_root_node )
    {
	iBase_EntitySetHandle new_root_set;
	iMesh_createEntSet( d_mesh,
			    1,
			    &new_root_set,
			    &error );
	assert( iBase_SUCCESS == error );

	iMesh_addEntArrToSet( d_mesh,
			      &root_list[0],
			      (int) root_list.size(),
			      new_root_set,
			      &error );
	assert( iBase_SUCCESS == error );

	node->node_set = new_root_set;
    }

    // See if we have any child entities.
    Teuchos::Tuple<int,8> num_child_ents;
    int total_child_ents = 0;
    for (int i = 0; i < 8; ++i )
    {
	iMesh_getNumOfTopo( d_mesh,
			    node->children[i]->node_set,
			    d_entity_topology,
			    &num_child_ents[i],
			    &error );
	assert( iBase_SUCCESS == error );

	total_child_ents += num_child_ents[i];
    }
    
    // Recurse.
    if ( total_child_ents == 0 )
    {
	node->is_leaf = true;
    }
    else
    {
	for (int i = 0; i < 8; ++i)
	{
	    if ( num_child_ents[i] == 0 )
	    {
		node->children[i]->is_leaf = true;
	    }
	    else 
	    {
		buildTreeNode( node->children[i] );
	    }
	}
    }
}
Exemple #6
0
int ProjectShell::writeNewMesh(iMesh_Instance mesh)
{
  // here we will create new vertices, and use the coordinates in 2D
  //  m_num2dPoints is the number of nodes (some are not used, because they were probably   // collapsed
  //  we do not specifically merge red and blue nodes, but we are looking first for 
  //  nodes in red , then blue, then on red edges; some will not appear, according
  //  to the tolerance
  //
  iBase_EntityHandle * newVerts = NULL; // no vertices yet
  // iBase_INTERLEAVED
  int err= 0;
  int size1, size2;
  iMesh_createVtxArr(mesh,
		     /*in*/ m_num2dPoints,
		     /*in*/ iBase_INTERLEAVED,
		     /*in*/ m_xy,
		     /*in*/ m_num2dPoints*3,
		     /*inout*/ &newVerts,
		     /*inout*/ &size1,
		     /*inout*/ &size2,
		     /*out*/ &err); 
  if (err!=0)
    {
      std::cout<<"can't create vertices\n";
      exit (1);
    }
  // size of 
  //  then entity set, then elements (triangles)
  //
  int numTriangles = m_finalMesh.size();
  long int * adjacency = new long int [3*numTriangles];
  iBase_EntityHandle * conn = (iBase_EntityHandle *)adjacency;
  for (int L =0; L<numTriangles; L++)
    {
      FinalTriangle & tria = m_finalMesh[L];
 
      
      for (int k=0; k<3; k++)
	{
          int indexInV =  tria.v[k];
	  conn[3*L+k] = newVerts[indexInV];
	}
    }
  int numElements = numTriangles;
  iBase_EntitySetHandle orig_set;
  iMesh_createEntSet(mesh, 0, &orig_set, &err);
  int n = numTriangles;
  int junk1 = n, junk2 = n, junk3 = n, junk4 = n;
  int * stat = new int [numElements];
  int* ptr2 = stat;
  int ierr;
  iBase_EntityHandle *   	 new_entity_handles = NULL;
  iMesh_createEntArr( mesh,
		      iMesh_TRIANGLE,
		      conn, 3*numElements,
		      &new_entity_handles, &junk1, &junk2,
		      &ptr2, &junk3, &junk4,
		      &ierr );
  if (ierr!=0)
    {
      std::cout<<" can't create triangles\n";
      exit (1);
    }
  iMesh_addEntArrToSet  	(  mesh,
				   new_entity_handles,
				   numElements,
				   orig_set,
				   &ierr);
  if (ierr!=0)
    {
      std::cout<< " can't add to entity set \n";
      exit(1);
    }	 
  // now, look at the tags : red is positive, blue is negative oriented triangle
  iBase_TagHandle   	pos_tag_handle; 
  
  const char * tagName1 = "Positive";
  iMesh_createTag  	( mesh,
		          tagName1,
		          /*  size ? */ 1,
		          iBase_INTEGER ,
		          &pos_tag_handle,
		          &ierr,
		          strlen(tagName1) ) ;	 
	
  if (ierr!=0)
    {
      std::cout<< " can't create positive tag \n";
      exit(1);
    }
  int * tagValues = new int [numElements];
  for (int e=0; e<numElements; e++)
    {
      int redId = m_finalMesh[e].redTriangle;
      tagValues[e] = m_redMesh[ redId ].oldId;
       
    }
  // positive or negative triangles
  iMesh_setIntArrData  	(  mesh,
			   new_entity_handles,
			   numElements,
			   pos_tag_handle,
			   tagValues,
			   numElements,
			   &ierr); 
  if (ierr!=0)
    {
      std::cout<< " can't create positive tag field \n";
      exit(1);
    }
  // now blue tag
  // now, look at the tags : red is positive, blue is negative oriented triangle
  iBase_TagHandle   	neg_tag_handle; 
  
  const char * tagName2 = "Negative";
  iMesh_createTag  	( mesh,
		          tagName2,
		          /*  size ? */ 1,
		          iBase_INTEGER ,
		          &neg_tag_handle,
		          &ierr,
		          strlen(tagName1) ) ;	 
	
  if (ierr!=0)
    {
      std::cout<< " can't create negative tag \n";
      exit(1);
    }
  for (int e=0; e<numElements; e++)
    {
      int blueId = m_finalMesh[e].blueTriangle;
      tagValues[e] = m_blueMesh[ blueId ].oldId;
       
    }
  // positive or negative triangles
  iMesh_setIntArrData  	(  mesh,
			   new_entity_handles,
			   numElements,
			   neg_tag_handle,
			   tagValues,
			   numElements,
			   &ierr); 
   if (ierr!=0)
    {
      std::cout<< " can't create negative tag field \n";
      exit(1);
    }
   delete [] tagValues;
   delete [] adjacency;
  return 0;
}
void test_tag_iterate()
{
  iMesh_Instance mesh;
  int err;
  iMesh_newMesh("", &mesh, &err, 0);
  CHECK_EQUAL( iBase_SUCCESS, err );

  iBase_EntitySetHandle root_set, entset;
  iMesh_getRootSet(mesh, &root_set, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );

  iBase_EntityHandle *verts = 0;
  int verts_alloc = 0, verts_size = 0;
  double coords[] = { 0,0,0, 1,1,1, 2,2,2, 3,3,3, 4,4,4, 5,5,5 };
  iMesh_createVtxArr(mesh,6,iBase_INTERLEAVED,coords,18,&verts,&verts_alloc,
                     &verts_size,&err);
  CHECK_EQUAL( iBase_SUCCESS, err );

    /* create an entity set with two subranges */
  iMesh_createEntSet( mesh, 0, &entset, &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  iMesh_addEntArrToSet( mesh, verts, 2, entset, &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  iMesh_addEntArrToSet( mesh, &verts[3], 3, entset, &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
    
    /* create a dbl tag and set vertices */
  iBase_TagHandle tagh;
  iMesh_createTagWithOptions(mesh, "dum", "moab:TAG_STORAGE_TYPE=DENSE", 1, iBase_DOUBLE, &tagh, &err, 3, 27);
  CHECK_EQUAL( iBase_SUCCESS, err );
  iMesh_setDblArrData(mesh, verts, 6, tagh, coords+3, 6, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );

    /* get an iterator over the root set, and check tag iterator for that */
  iBase_EntityArrIterator iter;
  int count, atend;
  double *data;
  iMesh_initEntArrIter( mesh, root_set, iBase_ALL_TYPES, iMesh_ALL_TOPOLOGIES,
                        6, 0, &iter, &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  iMesh_tagIterate(mesh, tagh, iter, &data, &count, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );
  if (count != 6) CHECK_EQUAL( iBase_SUCCESS, iBase_FAILURE );
  
  for (int i = 0; i < 6; i++) {
    if (data[i] != coords[i+3]) CHECK_EQUAL( iBase_SUCCESS, iBase_FAILURE );
  }
  iMesh_endEntArrIter(mesh, iter, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );
  
    /* get an iterator over the set with two subranges, and check tag iterator for that */
  iMesh_initEntArrIter( mesh, entset, iBase_ALL_TYPES, iMesh_ALL_TOPOLOGIES, 6,
                        0, &iter, &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  iMesh_tagIterate(mesh, tagh, iter, &data, &count, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );
  if (count != 2 || data[0] != coords[3] || data[1] != coords[4]) CHECK_EQUAL( iBase_SUCCESS, iBase_FAILURE );
  iMesh_stepEntArrIter(mesh, iter, 2, &atend, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );
    /* shouldn't be at end yet */
  if (atend) CHECK_EQUAL( iBase_SUCCESS, iBase_FAILURE );
  
  iMesh_tagIterate(mesh, tagh, iter, &data, &count, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );
  if (count != 3 || data[0] != coords[6] || data[1] != coords[7]) CHECK_EQUAL( iBase_SUCCESS, iBase_FAILURE );
  iMesh_stepEntArrIter(mesh, iter, 3, &atend, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );
    /* should be at end now */
  if (!atend) CHECK_EQUAL( iBase_SUCCESS, iBase_FAILURE );
  iMesh_endEntArrIter(mesh, iter, &err);
  CHECK_EQUAL( iBase_SUCCESS, err );

  iMesh_dtor(mesh,&err);
  CHECK_EQUAL( iBase_SUCCESS, err );

  free(verts);
}
Exemple #8
0
void create_hex_mesh(iMesh_Instance &mesh)
{
    // Create the mesh instance.
    int error;
    iMesh_newMesh("", &mesh, &error, 0);
    assert( iBase_SUCCESS == error );

    // Create a tag for the vertex elements.
    iBase_TagHandle vertex_tag;
    std::string vertex_tag_name = "vertex_tag";
    iMesh_createTag( mesh,
		     &vertex_tag_name[0],
		     1,
		     iBase_DOUBLE,
		     &vertex_tag,
		     &error,
		     (int) vertex_tag_name.size());
    assert( iBase_SUCCESS == error );

    // Generate vertices.
    int num_i = 11;
    int num_j = 11;
    int num_k = 11;
    int dx = 1.0;
    int dy = 1.0;
    int dz = 1.0;
    int idx = 0;
    std::vector<double> coords(3*num_i*num_j*num_k, 0.0);
    for ( int k = 0; k < num_k; ++k )
    {
	for ( int j = 0; j < num_j; ++j )
	{
	    for ( int i = 0; i < num_i; ++i )
	    {
		idx = i + num_i*j + num_i*num_j*k;
		coords[3*idx]     = i*dx;
		coords[3*idx + 1] = j*dy;
		coords[3*idx + 2] = k*dz;
	    }
	}
    }

    iBase_EntityHandle *vertices;
    int vertices_allocated = 0;
    int vertices_size = 0;
    iMesh_createVtxArr( mesh,
			(int) coords.size() / 3,
			iBase_INTERLEAVED,
			&coords[0],
			(int) coords.size(),
			&vertices,
			&vertices_allocated,
			&vertices_size,
			&error);
    assert( iBase_SUCCESS == error );
    assert( vertices_allocated == num_i*num_j*num_k );
    assert( vertices_size == num_i*num_j*num_k );

    // Tag the vertices.
    std::vector<double> vertex_tag_data( (int) coords.size() / 3, 0.0 );
    double data = 0.0;
    std::vector<double>::iterator vertex_data_iterator;
    for (vertex_data_iterator = vertex_tag_data.begin();
	 vertex_data_iterator != vertex_tag_data.end();
	 ++vertex_data_iterator )
    {
	*vertex_data_iterator = data;
	data += 1.0;
    }

    iMesh_setDblArrData( mesh,
			 vertices,
			 vertices_size,
			 vertex_tag,
			 &vertex_tag_data[0],
			 (int) vertex_tag_data.size(),
			 &error);
    assert( iBase_SUCCESS == error );

    // Create a vertex set and add the vertex array.
    iBase_EntitySetHandle vertex_set;
    iMesh_createEntSet(mesh, 1, &vertex_set, &error);
    assert( iBase_SUCCESS == error );

    iMesh_addEntArrToSet(mesh, vertices, vertices_size, vertex_set, &error);
    assert( iBase_SUCCESS == error );

    // Create a hex set.
    iBase_EntitySetHandle hex_set;
    iMesh_createEntSet(mesh, 1, &hex_set, &error);
    assert( iBase_SUCCESS == error );

    // Create a tag for the hex elements.
    iBase_TagHandle hex_tag;
    std::string hex_tag_name = "hex_tag";
    iMesh_createTag( mesh,
		     &hex_tag_name[0],
		     1,
		     iBase_DOUBLE,
		     &hex_tag,
		     &error,
		     (int) hex_tag_name.size());
    assert( iBase_SUCCESS == error );

    // Generate hexahedrons from vertices, tag them, and add them to the hex
    // set. 
    iBase_EntityHandle connectivity[8];
    int hex_creation_status = 0;
    double hex_data = 0.0;
    for (int k = 0; k < num_k - 1; ++k)
    {
	for (int j = 0; j < num_j - 1; ++j)
	{
	    for (int i = 0; i < num_i - 1; ++i)
	    {
		idx = i + num_i*j + num_i*num_j*k;
		connectivity[0] = vertices[ idx ];
		connectivity[1] = vertices[ idx + 1 ];
		connectivity[2] = vertices[ idx + 1 + num_i ];
		connectivity[3] = vertices[ idx +     num_i ];
		connectivity[4] = vertices[ idx +             num_i*num_j ];
		connectivity[5] = vertices[ idx + 1 +         num_i*num_j ];
		connectivity[6] = vertices[ idx + 1 + num_i + num_i*num_j ];
		connectivity[7] = vertices[ idx +     num_i + num_i*num_j ];

		iBase_EntityHandle hexahedron;
		iMesh_createEnt( mesh,
				 iMesh_HEXAHEDRON,
				 connectivity,
				 8,
				 &hexahedron,
				 &hex_creation_status,
				 &error);
		assert( iBase_SUCCESS == error );
		assert( iBase_NEW == hex_creation_status );

		iMesh_setDblData( mesh,
				  hexahedron,
				  hex_tag,
				  hex_data,
				  &error);
		assert( iBase_SUCCESS == error );
		
		hex_data += 1.0;

		iMesh_addEntToSet(mesh,
				  hexahedron,
				  hex_set,
				  &error);
		assert( iBase_SUCCESS == error );
	    }
	}
    }
}
Exemple #9
0
void create_tet_mesh( iMesh_Instance &mesh )
{
    // Setup iMesh instance
    int error;
    iMesh_newMesh("", &mesh, &error, 0);
    assert( iBase_SUCCESS == error );

    // Create a tag for the vertex elements.
    iBase_TagHandle vertex_tag;
    std::string vertex_tag_name = "vertex_tag";
    iMesh_createTag( mesh,
		     &vertex_tag_name[0],
		     1,
		     iBase_DOUBLE,
		     &vertex_tag,
		     &error,
		     (int) vertex_tag_name.size());
    assert( iBase_SUCCESS == error );

    // Generate vertices.
    int num_i = 11;
    int num_j = 11;
    int num_k = 11;
    int dx = 1.0;
    int dy = 1.0;
    int dz = 1.0;
    int idx = 0;
    std::vector<double> coords(3*num_i*num_j*num_k, 0.0);
    for ( int k = 0; k < num_k; ++k )
    {
	for ( int j = 0; j < num_j; ++j )
	{
	    for ( int i = 0; i < num_i; ++i )
	    {
		idx = i + num_i*j + num_i*num_j*k;
		coords[3*idx]     = i*dx;
		coords[3*idx + 1] = j*dy;
		coords[3*idx + 2] = k*dz;
	    }
	}
    }

    iBase_EntityHandle *vertices;
    int vertices_allocated = 0;
    int vertices_size = 0;
    iMesh_createVtxArr( mesh,
			(int) coords.size() / 3,
			iBase_INTERLEAVED,
			&coords[0],
			(int) coords.size(),
			&vertices,
			&vertices_allocated,
			&vertices_size,
			&error);
    assert( iBase_SUCCESS == error );
    assert( vertices_allocated == num_i*num_j*num_k );
    assert( vertices_size == num_i*num_j*num_k );

    // Tag the vertices.
    std::vector<double> vertex_tag_data( (int) coords.size() / 3, 0.0 );
    double data = 0.0;
    std::vector<double>::iterator vertex_data_iterator;
    for (vertex_data_iterator = vertex_tag_data.begin();
	 vertex_data_iterator != vertex_tag_data.end();
	 ++vertex_data_iterator )
    {
	*vertex_data_iterator = data;
	data += 1.0;
    }

    iMesh_setDblArrData( mesh,
			 vertices,
			 vertices_size,
			 vertex_tag,
			 &vertex_tag_data[0],
			 (int) vertex_tag_data.size(),
			 &error);
    assert( iBase_SUCCESS == error );

    // Create a vertex set and add the vertex array.
    iBase_EntitySetHandle vertex_set;
    iMesh_createEntSet(mesh, 1, &vertex_set, &error);
    assert( iBase_SUCCESS == error );

    iMesh_addEntArrToSet(mesh, vertices, vertices_size, vertex_set, &error);
    assert( iBase_SUCCESS == error );

    // Create a tet set.
    iBase_EntitySetHandle tet_set;
    iMesh_createEntSet(mesh, 1, &tet_set, &error);
    assert( iBase_SUCCESS == error );

    // Create a tag for the tet elements.
    iBase_TagHandle tet_tag;
    std::string tet_tag_name = "tet_tag";
    iMesh_createTag(mesh,
		    &tet_tag_name[0],
		    3,
		    iBase_DOUBLE,
		    &tet_tag,
		    &error,
		    (int) tet_tag_name.size());
    assert( iBase_SUCCESS == error );

    // Generate tetrahedrons from vertices, tag them, and add them to the tet
    // set. Decompose each cube into 5 tetrahedrons.
    iBase_EntityHandle connectivity[4];
    int tet_creation_status = 0;
    double tet_data = 0.0;
    double data_arr[3] = {tet_data, tet_data, tet_data};
    int v0 = 0;
    int v1 = 0;
    int v2 = 0;
    int v3 = 0;
    int v4 = 0;
    int v5 = 0;
    int v6 = 0;
    int v7 = 0;
    for (int k = 0; k < num_k - 1; ++k)
    {
	for (int j = 0; j < num_j - 1; ++j)
	{
	    for (int i = 0; i < num_i - 1; ++i)
	    {
		// Starting corner vertex index.
		idx = i + num_i*j + num_i*num_j*k;
		v0 = idx;
		v1 = idx + 1;
		v2 = idx + 1 + num_i;
		v3 = idx +     num_i;
		v4 = idx +             num_i*num_j;
		v5 = idx + 1 +         num_i*num_j;
		v6 = idx + 1 + num_i + num_i*num_j;
		v7 = idx +     num_i + num_i*num_j;

		// Tetrahedron 1.
		connectivity[0] = vertices[ v0 ];
		connectivity[1] = vertices[ v1 ];
		connectivity[2] = vertices[ v3 ];
		connectivity[3] = vertices[ v4 ];

		iBase_EntityHandle tetrahedron_1;
		iMesh_createEnt( mesh,
				 iMesh_TETRAHEDRON,
				 connectivity,
				 4,
				 &tetrahedron_1,
				 &tet_creation_status,
				 &error);
		assert( iBase_SUCCESS == error );
		assert( iBase_NEW == tet_creation_status );

		data_arr[0] = tet_data;
		data_arr[1] = tet_data;
		data_arr[2] = tet_data;
		iMesh_setDblArrData( mesh,
				     &tetrahedron_1,
				     1,
				     tet_tag,
				     data_arr,
				     3,
				     &error);
		assert( iBase_SUCCESS == error );
		
		tet_data += 1.0;

		iMesh_addEntToSet( mesh,
				   tetrahedron_1,
				   tet_set,
				   &error);
		assert( iBase_SUCCESS == error );

		// Tetrahedron 2.
		connectivity[0] = vertices[ v1 ];
		connectivity[1] = vertices[ v2 ];
		connectivity[2] = vertices[ v3 ];
		connectivity[3] = vertices[ v6 ];

		iBase_EntityHandle tetrahedron_2;
		iMesh_createEnt(mesh,
				iMesh_TETRAHEDRON,
				connectivity,
				4,
				&tetrahedron_2,
				&tet_creation_status,
				&error);
		assert( iBase_SUCCESS == error );
		assert( iBase_NEW == tet_creation_status );

		data_arr[0] = tet_data;
		data_arr[1] = tet_data;
		data_arr[2] = tet_data;
		iMesh_setDblArrData( mesh,
				     &tetrahedron_2,
				     1,
				     tet_tag,
				     data_arr,
				     3,
				     &error);
		assert( iBase_SUCCESS == error );
		
		tet_data += 1.0;

		iMesh_addEntToSet( mesh,
				   tetrahedron_2,
				   tet_set,
				   &error);
		assert( iBase_SUCCESS == error );

		// Tetrahedron 3.
		connectivity[0] = vertices[ v6 ];
		connectivity[1] = vertices[ v5 ];
		connectivity[2] = vertices[ v4 ];
		connectivity[3] = vertices[ v1 ];

		iBase_EntityHandle tetrahedron_3;
		iMesh_createEnt( mesh,
				 iMesh_TETRAHEDRON,
				 connectivity,
				 4,
				 &tetrahedron_3,
				 &tet_creation_status,
				 &error);
		assert( iBase_SUCCESS == error );
		assert( iBase_NEW == tet_creation_status );

		data_arr[0] = tet_data;
		data_arr[1] = tet_data;
		data_arr[2] = tet_data;
		iMesh_setDblArrData( mesh,
				     &tetrahedron_3,
				     1,
				     tet_tag,
				     data_arr,
				     3,
				     &error);
		assert( iBase_SUCCESS == error );
		
		tet_data += 1.0;

		iMesh_addEntToSet(mesh,
				  tetrahedron_3,
				  tet_set,
				  &error);
		assert( iBase_SUCCESS == error );

		// Tetrahedron 4.
		connectivity[0] = vertices[ v4 ];
		connectivity[1] = vertices[ v7 ];
		connectivity[2] = vertices[ v6 ];
		connectivity[3] = vertices[ v3 ];

		iBase_EntityHandle tetrahedron_4;
		iMesh_createEnt( mesh,
				 iMesh_TETRAHEDRON,
				 connectivity,
				 4,
				 &tetrahedron_4,
				 &tet_creation_status,
				 &error);
		assert( iBase_SUCCESS == error );
		assert( iBase_NEW == tet_creation_status );

		data_arr[0] = tet_data;
		data_arr[1] = tet_data;
		data_arr[2] = tet_data;
		iMesh_setDblArrData( mesh,
				     &tetrahedron_4,
				     1,
				     tet_tag,
				     data_arr,
				     3,
				     &error);
		assert( iBase_SUCCESS == error );
 		
		tet_data += 1.0;

		iMesh_addEntToSet( mesh,
				   tetrahedron_4,
				   tet_set,
				   &error);
		assert( iBase_SUCCESS == error );

		// Tetrahedron 5.
		connectivity[0] = vertices[ v3 ];
		connectivity[1] = vertices[ v1 ];
		connectivity[2] = vertices[ v6 ];
		connectivity[3] = vertices[ v4 ];

		iBase_EntityHandle tetrahedron_5;
		iMesh_createEnt( mesh,
				 iMesh_TETRAHEDRON,
				 connectivity,
				 4,
				 &tetrahedron_5,
				 &tet_creation_status,
				 &error);
		assert( iBase_SUCCESS == error );
		assert( iBase_NEW == tet_creation_status );

		data_arr[0] = tet_data;
		data_arr[1] = tet_data;
		data_arr[2] = tet_data;
		iMesh_setDblArrData( mesh,
				     &tetrahedron_5,
				     1,
				     tet_tag,
				     data_arr,
				     3,
				     &error);
		assert( iBase_SUCCESS == error );
		
		tet_data += 1.0;

		iMesh_addEntToSet( mesh,
				   tetrahedron_5,
				   tet_set,
				   &error);
		assert( iBase_SUCCESS == error );
	    }
	}
    }
}