xref: /petsc/src/dm/impls/moab/dmmbutil.cxx (revision e427d9c9730bfb55d05a5e89368a1afd0da144b2)
151d15aeeSVijay Mahadevan #include <petsc-private/dmmbimpl.h> /*I  "petscdm.h"   I*/
251d15aeeSVijay Mahadevan #include <petsc-private/vecimpl.h> /*I  "petscdm.h"   I*/
351d15aeeSVijay Mahadevan 
451d15aeeSVijay Mahadevan #include <petscdmmoab.h>
551d15aeeSVijay Mahadevan #include <MBTagConventions.hpp>
651d15aeeSVijay Mahadevan #include <moab/ReadUtilIface.hpp>
751d15aeeSVijay Mahadevan #include <moab/ScdInterface.hpp>
851d15aeeSVijay Mahadevan #include <moab/CN.hpp>
951d15aeeSVijay Mahadevan 
1051d15aeeSVijay Mahadevan 
1151d15aeeSVijay Mahadevan #undef __FUNCT__
1251d15aeeSVijay Mahadevan #define __FUNCT__ "DMMoabComputeDomainBounds_Private"
1351d15aeeSVijay Mahadevan PetscErrorCode DMMoabComputeDomainBounds_Private(moab::ParallelComm* pcomm, PetscInt dim, PetscInt neleglob, PetscInt *ise)
1451d15aeeSVijay Mahadevan {
1551d15aeeSVijay Mahadevan   PetscInt size,rank;
1651d15aeeSVijay Mahadevan   PetscInt fraction,remainder;
1751d15aeeSVijay Mahadevan   PetscInt starts[3],sizes[3];
1851d15aeeSVijay Mahadevan 
1951d15aeeSVijay Mahadevan   PetscFunctionBegin;
2051d15aeeSVijay Mahadevan   if(dim<1 && dim>3) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"The problem dimension is invalid: %D",dim);
2151d15aeeSVijay Mahadevan 
2251d15aeeSVijay Mahadevan   size=pcomm->size();
2351d15aeeSVijay Mahadevan   rank=pcomm->rank();
2451d15aeeSVijay Mahadevan   fraction=neleglob/size;    /* partition only by the largest dimension */
2551d15aeeSVijay Mahadevan   remainder=neleglob%size;   /* remainder after partition which gets evenly distributed by round-robin */
2651d15aeeSVijay Mahadevan 
2751d15aeeSVijay Mahadevan   if(fraction==0) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"The leading dimension size should be greater than number of processors: %D < %D",neleglob,size);
2851d15aeeSVijay Mahadevan 
2951d15aeeSVijay Mahadevan   starts[0]=starts[1]=starts[2]=0;       /* default dimensional element = 1 */
3051d15aeeSVijay Mahadevan   sizes[0]=sizes[1]=sizes[2]=neleglob;   /* default dimensional element = 1 */
3151d15aeeSVijay Mahadevan 
3251d15aeeSVijay Mahadevan   if(rank < remainder) {
3351d15aeeSVijay Mahadevan     /* This process gets "fraction+1" elements */
3451d15aeeSVijay Mahadevan     sizes[dim-1] = (fraction + 1);
3551d15aeeSVijay Mahadevan     starts[dim-1] = rank * (fraction+1);
3651d15aeeSVijay Mahadevan   } else {
3751d15aeeSVijay Mahadevan     /* This process gets "fraction" elements */
3851d15aeeSVijay Mahadevan     sizes[dim-1] = fraction;
3951d15aeeSVijay Mahadevan     starts[dim-1] = (remainder*(fraction+1) + fraction*(rank-remainder));
4051d15aeeSVijay Mahadevan   }
4151d15aeeSVijay Mahadevan 
4251d15aeeSVijay Mahadevan   for(int i=dim-1; i>=0; --i) {
4351d15aeeSVijay Mahadevan     ise[2*i]=starts[i];ise[2*i+1]=starts[i]+sizes[i];
4451d15aeeSVijay Mahadevan   }
4551d15aeeSVijay Mahadevan 
4651d15aeeSVijay Mahadevan   PetscFunctionReturn(0);
4751d15aeeSVijay Mahadevan }
4851d15aeeSVijay Mahadevan 
4966f88a78SVijay Mahadevan static void set_structured_coordinates(PetscInt i, PetscInt j, PetscInt k, PetscReal hx, PetscReal hy, PetscReal hz, PetscInt vcount, std::vector<double*>& vcoords)
50e5136372SVijay Mahadevan {
5166f88a78SVijay Mahadevan   vcoords[0][vcount] = i*hx;
5266f88a78SVijay Mahadevan   vcoords[1][vcount] = j*hy;
5366f88a78SVijay Mahadevan   vcoords[2][vcount] = k*hz;
54e5136372SVijay Mahadevan }
55e5136372SVijay Mahadevan 
56e5136372SVijay Mahadevan static void set_element_connectivity(PetscInt dim, moab::EntityType etype, PetscInt offset, PetscInt nele, PetscInt i, PetscInt j, PetscInt k, PetscInt vfirst, moab::EntityHandle *connectivity)
57e5136372SVijay Mahadevan {
58e5136372SVijay Mahadevan   std::vector<int>    subent_conn(pow(2,dim));  /* only linear edge, quad, hex supported now */
59e5136372SVijay Mahadevan 
60e5136372SVijay Mahadevan   moab::CN::SubEntityVertexIndices(etype, dim, 0, subent_conn.data());
61e5136372SVijay Mahadevan 
62e5136372SVijay Mahadevan   switch(dim) {
63e5136372SVijay Mahadevan     case 1:
64e5136372SVijay Mahadevan       connectivity[offset+subent_conn[0]] = vfirst+i;
65e5136372SVijay Mahadevan       connectivity[offset+subent_conn[1]] = vfirst+(i+1);
66e5136372SVijay Mahadevan       break;
67e5136372SVijay Mahadevan     case 2:
68e5136372SVijay Mahadevan       connectivity[offset+subent_conn[0]] = vfirst+i+j*(nele+1);
69e5136372SVijay Mahadevan       connectivity[offset+subent_conn[1]] = vfirst+(i+1)+j*(nele+1);
70e5136372SVijay Mahadevan       connectivity[offset+subent_conn[2]] = vfirst+(i+1)+(j+1)*(nele+1);
71e5136372SVijay Mahadevan       connectivity[offset+subent_conn[3]] = vfirst+i+(j+1)*(nele+1);
72e5136372SVijay Mahadevan       break;
73e5136372SVijay Mahadevan     case 3:
74e5136372SVijay Mahadevan     default:
75e5136372SVijay Mahadevan       connectivity[offset+subent_conn[0]] = vfirst+i+(nele+1)*(j+(nele+1)*k);
76e5136372SVijay Mahadevan       connectivity[offset+subent_conn[1]] = vfirst+(i+1)+(nele+1)*(j+(nele+1)*k);
77e5136372SVijay Mahadevan       connectivity[offset+subent_conn[2]] = vfirst+(i+1)+(nele+1)*((j+1)+(nele+1)*k);
78e5136372SVijay Mahadevan       connectivity[offset+subent_conn[3]] = vfirst+i+(nele+1)*((j+1)+(nele+1)*k);
79e5136372SVijay Mahadevan       connectivity[offset+subent_conn[4]] = vfirst+i+(nele+1)*(j+(nele+1)*(k+1));
80e5136372SVijay Mahadevan       connectivity[offset+subent_conn[5]] = vfirst+(i+1)+(nele+1)*(j+(nele+1)*(k+1));
81e5136372SVijay Mahadevan       connectivity[offset+subent_conn[6]] = vfirst+(i+1)+(nele+1)*((j+1)+(nele+1)*(k+1));
82e5136372SVijay Mahadevan       connectivity[offset+subent_conn[7]] = vfirst+i+(nele+1)*((j+1)+(nele+1)*(k+1));
83e5136372SVijay Mahadevan       break;
84e5136372SVijay Mahadevan   }
85e5136372SVijay Mahadevan }
8651d15aeeSVijay Mahadevan 
8751d15aeeSVijay Mahadevan #undef __FUNCT__
8851d15aeeSVijay Mahadevan #define __FUNCT__ "DMMoabCreateBoxMesh"
8966f88a78SVijay Mahadevan PetscErrorCode DMMoabCreateBoxMesh(MPI_Comm comm, PetscInt dim, const PetscReal* bounds, PetscInt nele, PetscInt user_nghost, DM *dm)
9051d15aeeSVijay Mahadevan {
9151d15aeeSVijay Mahadevan   PetscErrorCode  ierr;
9251d15aeeSVijay Mahadevan   moab::ErrorCode merr;
933a4aeca1SVijay Mahadevan   PetscInt        i,j,k,n,nprocs;
9451d15aeeSVijay Mahadevan   DM_Moab        *dmmoab;
9551d15aeeSVijay Mahadevan   moab::Interface *mbiface;
9651d15aeeSVijay Mahadevan   moab::ParallelComm *pcomm;
97a4717116SVijay Mahadevan   moab::ReadUtilIface* readMeshIface;
98a4717116SVijay Mahadevan 
9951d15aeeSVijay Mahadevan   moab::Tag  id_tag=PETSC_NULL;
100a4717116SVijay Mahadevan   moab::Range         ownedvtx,ownedelms;
1013a4aeca1SVijay Mahadevan   moab::EntityHandle  vfirst,efirst,regionset,faceset,edgeset,vtxset;
102a4717116SVijay Mahadevan   std::vector<double*> vcoords;
103a4717116SVijay Mahadevan   moab::EntityHandle  *connectivity = 0;
10451d15aeeSVijay Mahadevan   moab::EntityType etype;
105c8d5365dSVijay Mahadevan   PetscInt    ise[6];
10666f88a78SVijay Mahadevan   PetscReal   xse[6],defbounds[6];
1073a4aeca1SVijay Mahadevan   /* TODO: Fix nghost > 0 - now relying on exchange_ghost_cells */
1083a4aeca1SVijay Mahadevan   const PetscInt nghost=0;
1093a4aeca1SVijay Mahadevan 
1103a4aeca1SVijay Mahadevan   moab::Tag geom_tag;
1113a4aeca1SVijay Mahadevan 
1123a4aeca1SVijay Mahadevan   moab::Range adj,dim3,dim2;
1133a4aeca1SVijay Mahadevan   bool build_adjacencies=false;
11451d15aeeSVijay Mahadevan 
115a4717116SVijay Mahadevan   const PetscInt npts=nele+1;        /* Number of points in every dimension */
116e5136372SVijay Mahadevan   PetscInt vpere,locnele,locnpts,ghnele,ghnpts;    /* Number of verts/element, vertices, elements owned by this process */
11751d15aeeSVijay Mahadevan 
11851d15aeeSVijay Mahadevan   PetscFunctionBegin;
119e5136372SVijay Mahadevan   if(dim < 1 || dim > 3) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Invalid dimension argument for mesh: dim=[1,3].\n");
120e5136372SVijay Mahadevan 
121c8d5365dSVijay Mahadevan   ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
122e5136372SVijay Mahadevan   /* total number of vertices in all dimensions */
123e5136372SVijay Mahadevan   n=pow(npts,dim);
124e5136372SVijay Mahadevan 
125e5136372SVijay Mahadevan   /* do some error checking */
126e5136372SVijay Mahadevan   if(n < 2) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Number of points must be >= 2.\n");
127e5136372SVijay Mahadevan   if(nprocs > n) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Number of processors must be less than or equal to number of elements.\n");
128e5136372SVijay Mahadevan   if(nghost < 0) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Number of ghost layers cannot be negative.\n");
129e5136372SVijay Mahadevan 
130a4717116SVijay Mahadevan   /* Create the basic DMMoab object and keep the default parameters created by DM impls */
13151d15aeeSVijay Mahadevan   ierr = DMMoabCreateMoab(comm, PETSC_NULL, PETSC_NULL, PETSC_NULL, PETSC_NULL, dm);CHKERRQ(ierr);
13251d15aeeSVijay Mahadevan 
133a4717116SVijay Mahadevan   /* get all the necessary handles from the private DM object */
13451d15aeeSVijay Mahadevan   dmmoab = (DM_Moab*)(*dm)->data;
13551d15aeeSVijay Mahadevan   mbiface = dmmoab->mbiface;
13651d15aeeSVijay Mahadevan   pcomm = dmmoab->pcomm;
13751d15aeeSVijay Mahadevan   id_tag = dmmoab->ltog_tag;
13851d15aeeSVijay Mahadevan   nprocs = pcomm->size();
139c8d5365dSVijay Mahadevan   dmmoab->dim = dim;
14051d15aeeSVijay Mahadevan 
141b5410836SVijay Mahadevan   /* create a file set to associate all entities in current mesh */
142b5410836SVijay Mahadevan   merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, dmmoab->fileset);MBERR("Creating file set failed", merr);
143b5410836SVijay Mahadevan 
144a4717116SVijay Mahadevan   /* No errors yet; proceed with building the mesh */
145a4717116SVijay Mahadevan   merr = mbiface->query_interface(readMeshIface);MBERRNM(merr);
14651d15aeeSVijay Mahadevan 
14751d15aeeSVijay Mahadevan   ierr = PetscMemzero(ise,sizeof(PetscInt)*6);CHKERRQ(ierr);
148a4717116SVijay Mahadevan 
149a4717116SVijay Mahadevan   /* call the collective routine that computes the domain bounds for a structured mesh using MOAB */
15051d15aeeSVijay Mahadevan   ierr = DMMoabComputeDomainBounds_Private(pcomm, dim, nele, ise);CHKERRQ(ierr);
15151d15aeeSVijay Mahadevan 
152a4717116SVijay Mahadevan   /* set some variables based on dimension */
15351d15aeeSVijay Mahadevan   switch(dim) {
15451d15aeeSVijay Mahadevan    case 1:
15551d15aeeSVijay Mahadevan     vpere = 2;
156a4717116SVijay Mahadevan     locnele = (ise[1]-ise[0]);
157a4717116SVijay Mahadevan     locnpts = (ise[1]-ise[0]+1);
158c8d5365dSVijay Mahadevan     ghnele = (nghost > 0 ? (ise[0] > nghost ? 1 : 0) + (ise[1] < nele - nghost ? 1 : 0) : 0 );
159c8d5365dSVijay Mahadevan     ghnpts = (nghost > 0 ? (ise[0] > 0 ? 1 : 0) + (ise[1] < nele ? 1 : 0) : 0);
16051d15aeeSVijay Mahadevan     etype = moab::MBEDGE;
16151d15aeeSVijay Mahadevan     break;
16251d15aeeSVijay Mahadevan    case 2:
16351d15aeeSVijay Mahadevan     vpere = 4;
164a4717116SVijay Mahadevan     locnele = (ise[1]-ise[0])*(ise[3]-ise[2]);
165a4717116SVijay Mahadevan     locnpts = (ise[1]-ise[0]+1)*(ise[3]-ise[2]+1);
166c8d5365dSVijay Mahadevan     ghnele = (nghost > 0 ? (ise[2] > 0 ? nele : 0) + (ise[3] < nele ? nele : 0) : 0);
167c8d5365dSVijay Mahadevan     ghnpts = (nghost > 0 ? (ise[2] > 0 ? npts : 0) + (ise[3] < nele ? npts : 0) : 0);
16851d15aeeSVijay Mahadevan     etype = moab::MBQUAD;
16951d15aeeSVijay Mahadevan     break;
17051d15aeeSVijay Mahadevan    case 3:
17151d15aeeSVijay Mahadevan     vpere = 8;
172a4717116SVijay Mahadevan     locnele = (ise[1]-ise[0])*(ise[3]-ise[2])*(ise[5]-ise[4]);
173a4717116SVijay Mahadevan     locnpts = (ise[1]-ise[0]+1)*(ise[3]-ise[2]+1)*(ise[5]-ise[4]+1);
174c8d5365dSVijay Mahadevan     ghnele = (nghost > 0 ? (ise[4] > 0 ? nele*nele : 0) + (ise[5] < nele ? nele*nele : 0) : 0);
175c8d5365dSVijay Mahadevan     ghnpts = (nghost > 0 ? (ise[4] > 0 ? npts*npts : 0) + (ise[5] < nele ? npts*npts : 0) : 0);
17651d15aeeSVijay Mahadevan     etype = moab::MBHEX;
17751d15aeeSVijay Mahadevan     break;
17851d15aeeSVijay Mahadevan   }
17951d15aeeSVijay Mahadevan 
18051d15aeeSVijay Mahadevan   /* we have a domain of size [1,1,1] - now compute local co-ordinate box */
18151d15aeeSVijay Mahadevan   ierr = PetscMemzero(xse,sizeof(PetscReal)*6);CHKERRQ(ierr);
182c8d5365dSVijay Mahadevan   for(i=0; i<6; ++i) {
18351d15aeeSVijay Mahadevan     xse[i]=(PetscReal)ise[i]/nele;
18451d15aeeSVijay Mahadevan   }
18551d15aeeSVijay Mahadevan 
186a4717116SVijay Mahadevan   /* Create vertexes and set the coodinate of each vertex */
187c8d5365dSVijay Mahadevan   merr = readMeshIface->get_node_coords(3,locnpts+ghnpts,0,vfirst,vcoords,n);MBERRNM(merr);
18851d15aeeSVijay Mahadevan 
189a4717116SVijay Mahadevan   /* Compute the co-ordinates of vertices and global IDs */
190c8d5365dSVijay Mahadevan   std::vector<int>    vgid(locnpts+ghnpts);
19151d15aeeSVijay Mahadevan   int vcount=0;
19266f88a78SVijay Mahadevan 
19366f88a78SVijay Mahadevan   if (!bounds) { /* default box mesh is defined on a unit-cube */
19466f88a78SVijay Mahadevan     defbounds[0]=0.0; defbounds[1]=1.0;
19566f88a78SVijay Mahadevan     defbounds[2]=0.0; defbounds[3]=1.0;
19666f88a78SVijay Mahadevan     defbounds[4]=0.0; defbounds[5]=1.0;
19766f88a78SVijay Mahadevan     bounds=defbounds;
19866f88a78SVijay Mahadevan   }
19966f88a78SVijay Mahadevan   else {
20066f88a78SVijay Mahadevan     /* validate the bounds data */
20166f88a78SVijay Mahadevan     if(bounds[0] >= bounds[1]) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"X-dim: Left boundary cannot be greater than right. [%G >= %G]\n",bounds[0],bounds[1]);
20266f88a78SVijay Mahadevan     if(dim > 1 && (bounds[2] >= bounds[3])) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Y-dim: Left boundary cannot be greater than right. [%G >= %G]\n",bounds[2],bounds[3]);
20366f88a78SVijay Mahadevan     if(dim > 2 && (bounds[4] >= bounds[5])) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Z-dim: Left boundary cannot be greater than right. [%G >= %G]\n",bounds[4],bounds[5]);
20466f88a78SVijay Mahadevan   }
20566f88a78SVijay Mahadevan 
20666f88a78SVijay Mahadevan   const double hx=(bounds[1]-bounds[0])/nele;
20766f88a78SVijay Mahadevan   const double hy=(dim > 1 ? (bounds[3]-bounds[2])/nele : 0.0);
20866f88a78SVijay Mahadevan   const double hz=(dim > 2 ? (bounds[5]-bounds[4])/nele : 0.0);
209e5136372SVijay Mahadevan 
210c8d5365dSVijay Mahadevan   /* create all the owned vertices */
211c8d5365dSVijay Mahadevan   for (k = ise[4]; k <= ise[5]; k++) {
212c8d5365dSVijay Mahadevan     for (j = ise[2]; j <= ise[3]; j++) {
213c8d5365dSVijay Mahadevan       for (i = ise[0]; i <= ise[1]; i++, vcount++) {
21466f88a78SVijay Mahadevan         set_structured_coordinates(i,j,k,hx,hy,hz,vcount,vcoords);
215c8d5365dSVijay Mahadevan         vgid[vcount] = (k*npts+j)*npts+i+1;
216c8d5365dSVijay Mahadevan       }
217c8d5365dSVijay Mahadevan     }
218c8d5365dSVijay Mahadevan   }
219c8d5365dSVijay Mahadevan 
220e5136372SVijay Mahadevan   /* create ghosted vertices requested by user - below the current plane */
221e5136372SVijay Mahadevan   if (ise[2*dim-2] > 0) {
222e5136372SVijay Mahadevan     for (k = (dim==3?ise[4]-nghost:ise[4]); k <= (dim==3?ise[4]-1:ise[5]); k++) {
223e5136372SVijay Mahadevan       for (j = (dim==2?ise[2]-nghost:ise[2]); j <= (dim==2?ise[2]-1:ise[3]); j++) {
224e5136372SVijay Mahadevan         for (i = (dim>1?ise[0]:ise[0]-nghost); i <= (dim>1?ise[1]:ise[0]-1); i++, vcount++) {
22566f88a78SVijay Mahadevan           set_structured_coordinates(i,j,k,hx,hy,hz,vcount,vcoords);
226e5136372SVijay Mahadevan           vgid[vcount] = (k*npts+j)*npts+i+1;
227e5136372SVijay Mahadevan         }
228e5136372SVijay Mahadevan       }
229e5136372SVijay Mahadevan     }
230e5136372SVijay Mahadevan   }
231e5136372SVijay Mahadevan 
232e5136372SVijay Mahadevan   /* create ghosted vertices requested by user - above the current plane */
233e5136372SVijay Mahadevan   if (ise[2*dim-1] < nele) {
234e5136372SVijay Mahadevan     for (k = (dim==3?ise[5]+1:ise[4]); k <= (dim==3?ise[5]+nghost:ise[5]); k++) {
235e5136372SVijay Mahadevan       for (j = (dim==2?ise[3]+1:ise[2]); j <= (dim==2?ise[3]+nghost:ise[3]); j++) {
236e5136372SVijay Mahadevan         for (i = (dim>1?ise[0]:ise[1]+1); i <= (dim>1?ise[1]:ise[1]+nghost); i++, vcount++) {
23766f88a78SVijay Mahadevan           set_structured_coordinates(i,j,k,hx,hy,hz,vcount,vcoords);
238e5136372SVijay Mahadevan           vgid[vcount] = (k*npts+j)*npts+i+1;
239e5136372SVijay Mahadevan         }
24051d15aeeSVijay Mahadevan       }
24151d15aeeSVijay Mahadevan     }
24251d15aeeSVijay Mahadevan   }
24351d15aeeSVijay Mahadevan 
244c8d5365dSVijay Mahadevan   if (locnpts+ghnpts != vcount) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Created the wrong number of vertices! (%D!=%D)",locnpts+ghnpts,vcount);
245c8d5365dSVijay Mahadevan 
24651d15aeeSVijay Mahadevan   merr = mbiface->get_entities_by_type(0,moab::MBVERTEX,ownedvtx,true);MBERRNM(merr);
24751d15aeeSVijay Mahadevan 
248a4717116SVijay Mahadevan   /* The global ID tag is applied to each owned
249a4717116SVijay Mahadevan      vertex. It acts as an global identifier which MOAB uses to
250a4717116SVijay Mahadevan      assemble the individual pieces of the mesh:
251a4717116SVijay Mahadevan      Set the global ID indices */
25251d15aeeSVijay Mahadevan   merr = mbiface->tag_set_data(id_tag,ownedvtx,vgid.data());MBERRNM(merr);
25351d15aeeSVijay Mahadevan 
254a4717116SVijay Mahadevan   /* Create elements between mesh points using the ReadUtilInterface
255a4717116SVijay Mahadevan      get the reference to element connectivities for all local elements from the ReadUtilInterface */
256e5136372SVijay Mahadevan   merr = readMeshIface->get_element_connect (locnele+ghnele,vpere,etype,1,efirst,connectivity);MBERRNM(merr);
25751d15aeeSVijay Mahadevan 
258a4717116SVijay Mahadevan   /* offset appropriately so that only local ID and not global ID numbers are set for connectivity array */
259c8d5365dSVijay Mahadevan //  PetscPrintf(PETSC_COMM_SELF, "[%D] first local handle %D\n", rank, vfirst);
260e5136372SVijay Mahadevan   vfirst-=vgid[0]-1;
26151d15aeeSVijay Mahadevan 
262a4717116SVijay Mahadevan    /* 3. Loop over elements in 3 nested loops over i, j, k; for each (i,j,k):
263a4717116SVijay Mahadevan          and then set the connectivity for each element appropriately */
26451d15aeeSVijay Mahadevan   int ecount=0;
26551d15aeeSVijay Mahadevan 
266e5136372SVijay Mahadevan   /* create ghosted elements requested by user - below the current plane */
267e5136372SVijay Mahadevan   if (ise[2*dim-2] >= nghost) {
268e5136372SVijay Mahadevan     for (k = (dim==3?ise[4]-nghost:ise[4]); k < (dim==3?ise[4]:std::max(ise[5],1)); k++) {
269e5136372SVijay Mahadevan       for (j = (dim==2?ise[2]-nghost:ise[2]); j < (dim==2?ise[2]:std::max(ise[3],1)); j++) {
270e5136372SVijay Mahadevan         for (i = (dim>1?ise[0]:ise[0]-nghost); i < (dim>1?std::max(ise[1],1):ise[0]); i++, ecount++) {
271c8d5365dSVijay Mahadevan           set_element_connectivity(dim, etype, ecount*vpere, nele, i, j, k, vfirst, connectivity);
27251d15aeeSVijay Mahadevan         }
27351d15aeeSVijay Mahadevan       }
27451d15aeeSVijay Mahadevan     }
27551d15aeeSVijay Mahadevan   }
276e5136372SVijay Mahadevan 
277e5136372SVijay Mahadevan   /* create owned elements requested by user */
278e5136372SVijay Mahadevan   for (k = ise[4]; k < std::max(ise[5],1); k++) {
279e5136372SVijay Mahadevan     for (j = ise[2]; j < std::max(ise[3],1); j++) {
280e5136372SVijay Mahadevan       for (i = ise[0]; i < std::max(ise[1],1); i++,ecount++) {
281c8d5365dSVijay Mahadevan         set_element_connectivity(dim, etype, ecount*vpere, nele, i, j, k, vfirst, connectivity);
282e5136372SVijay Mahadevan       }
283e5136372SVijay Mahadevan     }
284e5136372SVijay Mahadevan   }
285e5136372SVijay Mahadevan 
286e5136372SVijay Mahadevan   /* create ghosted elements requested by user - above the current plane */
287e5136372SVijay Mahadevan   if (ise[2*dim-1] <= nele-nghost) {
288e5136372SVijay Mahadevan     for (k = (dim==3?ise[5]:ise[4]); k < (dim==3?ise[5]+nghost:std::max(ise[5],1)); k++) {
289e5136372SVijay Mahadevan       for (j = (dim==2?ise[3]:ise[2]); j < (dim==2?ise[3]+nghost:std::max(ise[3],1)); j++) {
290e5136372SVijay Mahadevan         for (i = (dim>1?ise[0]:ise[1]); i < (dim>1?std::max(ise[1],1):ise[1]+nghost); i++, ecount++) {
291c8d5365dSVijay Mahadevan           set_element_connectivity(dim, etype, ecount*vpere, nele, i, j, k, vfirst, connectivity);
292e5136372SVijay Mahadevan         }
293e5136372SVijay Mahadevan       }
294e5136372SVijay Mahadevan     }
295e5136372SVijay Mahadevan   }
296e5136372SVijay Mahadevan 
297e5136372SVijay Mahadevan   merr = readMeshIface->update_adjacencies(efirst,locnele+ghnele,vpere,connectivity);MBERRNM(merr);
29851d15aeeSVijay Mahadevan 
299a4717116SVijay Mahadevan   /* 2. Get the vertices and hexes from moab and check their numbers against I*J*K and (I-1)*(J-1)*(K-1), resp.
300a4717116SVijay Mahadevan         first '0' specifies "root set", or entire MOAB instance, second the entity dimension being requested */
30151d15aeeSVijay Mahadevan   merr = mbiface->get_entities_by_dimension(0, dim, ownedelms);MBERRNM(merr);
302a4717116SVijay Mahadevan 
303e5136372SVijay Mahadevan   if (locnele+ghnele != (int) ownedelms.size())
304e5136372SVijay Mahadevan     SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Created the wrong number of elements! (%D!=%D)",locnele+ghnele,ownedelms.size());
305e5136372SVijay Mahadevan   else if(locnpts+ghnpts != (int) ownedvtx.size())
306e5136372SVijay Mahadevan     SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Created the wrong number of vertices! (%D!=%D)",locnpts+ghnpts,ownedvtx.size());
30751d15aeeSVijay Mahadevan   else
308*e427d9c9SVijay Mahadevan     PetscInfo2(NULL, "Created %D elements and %D vertices.\n", ownedelms.size(), ownedvtx.size());
30951d15aeeSVijay Mahadevan 
3103a4aeca1SVijay Mahadevan   /* lets create some sets */
3113a4aeca1SVijay Mahadevan   merr = mbiface->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, moab::MB_TYPE_INTEGER, geom_tag, moab::MB_TAG_SPARSE|moab::MB_TAG_CREAT);MBERRNM(merr);
3123a4aeca1SVijay Mahadevan 
3133a4aeca1SVijay Mahadevan   merr = mbiface->create_meshset(moab::MESHSET_SET, regionset);MBERRNM(merr);
3143a4aeca1SVijay Mahadevan   merr = mbiface->add_entities(regionset, ownedelms);MBERRNM(merr);
3153a4aeca1SVijay Mahadevan   merr = mbiface->tag_set_data(geom_tag, &regionset, 1, &dmmoab->dim);MBERRNM(merr);
316b5410836SVijay Mahadevan   merr = mbiface->add_parent_child(dmmoab->fileset,regionset);MBERRNM(merr);
3173a4aeca1SVijay Mahadevan   merr = mbiface->unite_meshset(dmmoab->fileset, regionset);MBERRNM(merr);
3183a4aeca1SVijay Mahadevan 
3193a4aeca1SVijay Mahadevan   merr = mbiface->create_meshset(moab::MESHSET_SET, vtxset);MBERRNM(merr);
3203a4aeca1SVijay Mahadevan   merr = mbiface->add_entities(vtxset, ownedvtx);MBERRNM(merr);
3213a4aeca1SVijay Mahadevan   merr = mbiface->add_parent_child(dmmoab->fileset,vtxset);MBERRNM(merr);
3223a4aeca1SVijay Mahadevan   merr = mbiface->unite_meshset(dmmoab->fileset, vtxset);MBERRNM(merr);
3233a4aeca1SVijay Mahadevan 
3243a4aeca1SVijay Mahadevan   if (build_adjacencies) {
3253a4aeca1SVijay Mahadevan     // generate all lower dimensional adjacencies
3263a4aeca1SVijay Mahadevan     merr = mbiface->get_adjacencies( ownedelms, dim-1, true, adj, moab::Interface::UNION );MBERRNM(merr);
3273a4aeca1SVijay Mahadevan     merr = dmmoab->pcomm->get_part_entities(dim2, dim-1);MBERRNM(merr);
3283a4aeca1SVijay Mahadevan     adj.merge(dim2);
3293a4aeca1SVijay Mahadevan 
3303a4aeca1SVijay Mahadevan     /* create face sets */
3313a4aeca1SVijay Mahadevan     merr = mbiface->create_meshset(moab::MESHSET_SET, faceset);MBERRNM(merr);
3323a4aeca1SVijay Mahadevan     merr = mbiface->add_entities(faceset, adj);MBERRNM(merr);
3333a4aeca1SVijay Mahadevan     merr = mbiface->add_parent_child(dmmoab->fileset,faceset);MBERRNM(merr);
3343a4aeca1SVijay Mahadevan     i=dim-1;
3353a4aeca1SVijay Mahadevan     merr = mbiface->tag_set_data(geom_tag, &faceset, 1, &i);MBERRNM(merr);
3363a4aeca1SVijay Mahadevan     merr = mbiface->unite_meshset(dmmoab->fileset, faceset);MBERRNM(merr);
3373a4aeca1SVijay Mahadevan     PetscInfo2(dm, "Found %d %d-Dim quantities.\n", adj.size(), dim-1);
3383a4aeca1SVijay Mahadevan 
3393a4aeca1SVijay Mahadevan     if (dim > 2) {
3403a4aeca1SVijay Mahadevan       dim2.clear();
3413a4aeca1SVijay Mahadevan       /* create edge sets, if appropriate i.e., if dim=3 */
3423a4aeca1SVijay Mahadevan       merr = mbiface->create_meshset(moab::MESHSET_SET, edgeset);MBERRNM(merr);
3433a4aeca1SVijay Mahadevan       merr = mbiface->get_adjacencies(adj, dim-1, true, dim2, moab::Interface::UNION );MBERRNM(merr);
3443a4aeca1SVijay Mahadevan       merr = mbiface->add_entities(edgeset, dim2);MBERRNM(merr);
3453a4aeca1SVijay Mahadevan       merr = mbiface->add_parent_child(dmmoab->fileset,edgeset);MBERRNM(merr);
3463a4aeca1SVijay Mahadevan       i=dim-2;
3473a4aeca1SVijay Mahadevan       merr = mbiface->tag_set_data(geom_tag, &edgeset, 1, &i);MBERRNM(merr);
3483a4aeca1SVijay Mahadevan       merr = mbiface->unite_meshset(dmmoab->fileset, edgeset);MBERRNM(merr);
3493a4aeca1SVijay Mahadevan       PetscInfo2(dm, "Found %d %d-Dim quantities.\n", adj.size(), dim-2);
3503a4aeca1SVijay Mahadevan     }
3513a4aeca1SVijay Mahadevan   }
3523a4aeca1SVijay Mahadevan 
353a4717116SVijay Mahadevan   /* check the handles */
354a4717116SVijay Mahadevan   merr = pcomm->check_all_shared_handles();MBERRV(mbiface,merr);
35551d15aeeSVijay Mahadevan 
356c8d5365dSVijay Mahadevan #if 0
357e5136372SVijay Mahadevan   std::stringstream sstr;
358e5136372SVijay Mahadevan   sstr << "test_" << pcomm->rank() << ".vtk";
359e5136372SVijay Mahadevan   mbiface->write_mesh(sstr.str().c_str());
360e5136372SVijay Mahadevan #endif
361e5136372SVijay Mahadevan 
362a4717116SVijay Mahadevan   /* resolve the shared entities by exchanging information to adjacent processors */
363a4717116SVijay Mahadevan   merr = mbiface->get_entities_by_type(dmmoab->fileset,etype,ownedelms,true);MBERRNM(merr);
364ce1fd009SVijay Mahadevan   merr = pcomm->resolve_shared_ents(dmmoab->fileset,ownedelms,dim,dim-1,NULL,&id_tag);MBERRV(mbiface,merr);
36551d15aeeSVijay Mahadevan 
3663a4aeca1SVijay Mahadevan   merr = pcomm->exchange_ghost_cells(dim,0,user_nghost,dim,true,false,&dmmoab->fileset);MBERRV(mbiface,merr);
367c8d5365dSVijay Mahadevan 
368*e427d9c9SVijay Mahadevan   /* Reassign global IDs on all entities. */
369*e427d9c9SVijay Mahadevan   merr = pcomm->assign_global_ids(dmmoab->fileset,dim,1,false,true,false);MBERRNM(merr);
370*e427d9c9SVijay Mahadevan 
371a4717116SVijay Mahadevan   /* Everything is set up, now just do a tag exchange to update tags
372a4717116SVijay Mahadevan      on all of the ghost vertexes */
373c8d5365dSVijay Mahadevan   merr = mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,ownedvtx,true);MBERRNM(merr);
374c8d5365dSVijay Mahadevan   merr = mbiface->get_entities_by_dimension(dmmoab->fileset, dim, ownedelms);MBERRNM(merr);
375c8d5365dSVijay Mahadevan 
376a4717116SVijay Mahadevan   merr = pcomm->exchange_tags(id_tag,ownedvtx);MBERRV(mbiface,merr);
377a4717116SVijay Mahadevan   merr = pcomm->exchange_tags(id_tag,ownedelms);MBERRV(mbiface,merr);
37851d15aeeSVijay Mahadevan   PetscFunctionReturn(0);
37951d15aeeSVijay Mahadevan }
38051d15aeeSVijay Mahadevan 
38151d15aeeSVijay Mahadevan 
382a4717116SVijay Mahadevan #undef __FUNCT__
383a4717116SVijay Mahadevan #define __FUNCT__ "DMMoab_GetReadOptions_Private"
3847023aa44SVijay Mahadevan PetscErrorCode DMMoab_GetReadOptions_Private(PetscBool by_rank, PetscInt numproc, PetscInt dim, MoabReadMode mode, PetscInt dbglevel, const char* extra_opts, const char** read_opts)
38551d15aeeSVijay Mahadevan {
386a4717116SVijay Mahadevan   std::ostringstream str;
38751d15aeeSVijay Mahadevan 
388a4717116SVijay Mahadevan   PetscFunctionBegin;
389e23c60ebSVijay Mahadevan   /* do parallel read unless using only one processor */
390a4717116SVijay Mahadevan   if (numproc > 1) {
3917023aa44SVijay Mahadevan     str << "PARALLEL=" << mode << ";PARTITION=PARALLEL_PARTITION;PARTITION_DISTRIBUTE;";
3927023aa44SVijay Mahadevan     str << "PARALLEL_RESOLVE_SHARED_ENTS;PARALLEL_GHOSTS=" << dim << ".0.1;";
393a4717116SVijay Mahadevan     if (by_rank)
394a4717116SVijay Mahadevan       str << "PARTITION_BY_RANK;";
395a4717116SVijay Mahadevan   }
39651d15aeeSVijay Mahadevan 
397c8d5365dSVijay Mahadevan   if (dbglevel) {
398c8d5365dSVijay Mahadevan     str << "CPUTIME;DEBUG_IO=" << dbglevel << ";";
399c8d5365dSVijay Mahadevan     if (numproc>1)
400c8d5365dSVijay Mahadevan       str << "DEBUG_PIO=" << dbglevel << ";";
401c8d5365dSVijay Mahadevan   }
40251d15aeeSVijay Mahadevan 
403c8d5365dSVijay Mahadevan   if (extra_opts)
404c8d5365dSVijay Mahadevan     str << extra_opts;
40551d15aeeSVijay Mahadevan 
4067023aa44SVijay Mahadevan   *read_opts = str.str().c_str();
40751d15aeeSVijay Mahadevan   PetscFunctionReturn(0);
40851d15aeeSVijay Mahadevan }
40951d15aeeSVijay Mahadevan 
41051d15aeeSVijay Mahadevan 
41151d15aeeSVijay Mahadevan #undef __FUNCT__
412a4717116SVijay Mahadevan #define __FUNCT__ "DMMoabLoadFromFile"
413a4717116SVijay Mahadevan PetscErrorCode DMMoabLoadFromFile(MPI_Comm comm,PetscInt dim,const char* filename, const char* usrreadopts, DM *dm)
41451d15aeeSVijay Mahadevan {
415a4717116SVijay Mahadevan   moab::ErrorCode merr;
4167023aa44SVijay Mahadevan   PetscInt        nprocs,dbglevel=0;
4177023aa44SVijay Mahadevan   PetscBool       part_by_rank=PETSC_FALSE;
418a4717116SVijay Mahadevan   DM_Moab        *dmmoab;
419a4717116SVijay Mahadevan   moab::Interface *mbiface;
420a4717116SVijay Mahadevan   moab::ParallelComm *pcomm;
421a4717116SVijay Mahadevan   moab::Range verts,elems;
4227023aa44SVijay Mahadevan   const char *readopts;
423a4717116SVijay Mahadevan   PetscErrorCode ierr;
42451d15aeeSVijay Mahadevan 
42551d15aeeSVijay Mahadevan   PetscFunctionBegin;
426a4717116SVijay Mahadevan   PetscValidPointer(dm,5);
42751d15aeeSVijay Mahadevan 
428a4717116SVijay Mahadevan   /* Create the basic DMMoab object and keep the default parameters created by DM impls */
429a4717116SVijay Mahadevan   ierr = DMMoabCreateMoab(comm, PETSC_NULL, PETSC_NULL, PETSC_NULL, PETSC_NULL, dm);CHKERRQ(ierr);
43051d15aeeSVijay Mahadevan 
431a4717116SVijay Mahadevan   /* get all the necessary handles from the private DM object */
432a4717116SVijay Mahadevan   dmmoab = (DM_Moab*)(*dm)->data;
433a4717116SVijay Mahadevan   mbiface = dmmoab->mbiface;
434a4717116SVijay Mahadevan   pcomm = dmmoab->pcomm;
435a4717116SVijay Mahadevan   nprocs = pcomm->size();
436c8d5365dSVijay Mahadevan   dmmoab->dim = dim;
437a4717116SVijay Mahadevan 
438b5410836SVijay Mahadevan   /* create a file set to associate all entities in current mesh */
439b5410836SVijay Mahadevan   merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, dmmoab->fileset);MBERR("Creating file set failed", merr);
440b5410836SVijay Mahadevan 
4417023aa44SVijay Mahadevan   /* TODO: Use command-line options to control by_rank, verbosity, MoabReadMode and extra options */
4427023aa44SVijay Mahadevan   ierr  = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for reading/writing MOAB based meshes from file", "DMMoab");
4437023aa44SVijay Mahadevan   ierr  = PetscOptionsInt("-dmmb_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "dmmbutil.cxx", dbglevel, &dbglevel, NULL);CHKERRQ(ierr);
4447023aa44SVijay Mahadevan   ierr  = PetscOptionsBool("-dmmb_part_by_rank", "Use partition by rank when reading MOAB meshes from file", "dmmbutil.cxx", part_by_rank, &part_by_rank, NULL);CHKERRQ(ierr);
4457023aa44SVijay Mahadevan   ierr  = PetscOptionsEnd();
4467023aa44SVijay Mahadevan 
447a4717116SVijay Mahadevan   /* add mesh loading options specific to the DM */
4487023aa44SVijay Mahadevan   ierr = DMMoab_GetReadOptions_Private(part_by_rank, nprocs, dim, MOAB_PARROPTS_READ_PART, dbglevel, usrreadopts, &readopts);CHKERRQ(ierr);
4497023aa44SVijay Mahadevan 
450e5136372SVijay Mahadevan   PetscInfo2(*dm, "Reading file %s with options: %s\n",filename,readopts);
451a4717116SVijay Mahadevan 
452a4717116SVijay Mahadevan   /* Load the mesh from a file. */
4537023aa44SVijay Mahadevan   merr = mbiface->load_file(filename, &dmmoab->fileset, readopts);MBERRVM(mbiface,"Reading MOAB file failed.", merr);
454a4717116SVijay Mahadevan 
4556e40195eSVijay Mahadevan   /* Reassign global IDs on all entities. */
456e5136372SVijay Mahadevan   merr = pcomm->assign_global_ids(dmmoab->fileset,dim,1,true,true,true);MBERRNM(merr);
457e5136372SVijay Mahadevan 
458e5136372SVijay Mahadevan   /* load the local vertices */
459e5136372SVijay Mahadevan   merr = mbiface->get_entities_by_type(dmmoab->fileset, moab::MBVERTEX, verts, true);MBERRNM(merr);
460e5136372SVijay Mahadevan   /* load the local elements */
461e5136372SVijay Mahadevan   merr = mbiface->get_entities_by_dimension(dmmoab->fileset, dim, elems, true);MBERRNM(merr);
462e5136372SVijay Mahadevan 
463e5136372SVijay Mahadevan   /* Everything is set up, now just do a tag exchange to update tags
464e5136372SVijay Mahadevan      on all of the ghost vertexes */
465e5136372SVijay Mahadevan   merr = pcomm->exchange_tags(dmmoab->ltog_tag,verts);MBERRV(mbiface,merr);
466e5136372SVijay Mahadevan   merr = pcomm->exchange_tags(dmmoab->ltog_tag,elems);MBERRV(mbiface,merr);
467e5136372SVijay Mahadevan 
468e5136372SVijay Mahadevan   merr = pcomm->exchange_ghost_cells(dim,0,1,0,true,true,&dmmoab->fileset);MBERRV(mbiface,merr);
4696e40195eSVijay Mahadevan 
470a4717116SVijay Mahadevan   merr = pcomm->collective_sync_partition();MBERR("Collective sync failed", merr);
471a4717116SVijay Mahadevan 
472e5136372SVijay Mahadevan   PetscInfo3(*dm, "MOAB file '%s' was successfully loaded. Found %D vertices and %D elements.\n", filename, verts.size(), elems.size());
473e5136372SVijay Mahadevan 
474*e427d9c9SVijay Mahadevan #if 0
475e5136372SVijay Mahadevan   std::stringstream sstr;
476e5136372SVijay Mahadevan   sstr << "test_" << pcomm->rank() << ".vtk";
477e5136372SVijay Mahadevan   mbiface->write_mesh(sstr.str().c_str());
478e5136372SVijay Mahadevan #endif
47951d15aeeSVijay Mahadevan   PetscFunctionReturn(0);
48051d15aeeSVijay Mahadevan }
48151d15aeeSVijay Mahadevan 
482