xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 0c8a2322e4d325752d68cf4f31e2d9980de1822e)
1 #include <petsc-private/dmmbimpl.h> /*I  "petscdm.h"   I*/
2 #include <petsc-private/vecimpl.h> /*I  "petscdm.h"   I*/
3 
4 #include <petscdmmoab.h>
5 #include <MBTagConventions.hpp>
6 #include <moab/Skinner.hpp>
7 
8 #undef __FUNCT__
9 #define __FUNCT__ "DMDestroy_Moab"
10 PetscErrorCode DMDestroy_Moab(DM dm)
11 {
12   PetscErrorCode ierr;
13   DM_Moab        *dmmoab = (DM_Moab*)dm->data;
14   PetscSection   section;
15 
16   PetscFunctionBegin;
17   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
19   ierr = PetscSectionDestroy(&section);CHKERRQ(ierr);
20   if (dmmoab->icreatedinstance) {
21     delete dmmoab->mbiface;
22   }
23   dmmoab->mbiface = NULL;
24   dmmoab->pcomm = NULL;
25   delete dmmoab->vlocal;
26   delete dmmoab->vowned;
27   delete dmmoab->vghost;
28   delete dmmoab->elocal;
29   delete dmmoab->eghost;
30 
31   ierr = PetscFree(dmmoab->isbndyvtx);CHKERRQ(ierr);
32   ierr = PetscFree(dmmoab->isbndyfaces);CHKERRQ(ierr);
33   ierr = PetscFree(dmmoab->isbndyelems);CHKERRQ(ierr);
34   ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr);
35   ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
36   ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr);
37   ierr = PetscFree(dm->data);CHKERRQ(ierr);
38   PetscFunctionReturn(0);
39 }
40 
41 #undef __FUNCT__
42 #define __FUNCT__ "DMSetUp_Moab"
43 PetscErrorCode DMSetUp_Moab(DM dm)
44 {
45   PetscErrorCode          ierr;
46   moab::ErrorCode         merr;
47   Vec                     local, global;
48   IS                      from;
49   moab::Range::iterator   iter;
50   PetscInt                i,j,bs,gsiz,lsiz;
51   DM_Moab                *dmmoab = (DM_Moab*)dm->data;
52   PetscInt                totsize;
53   PetscSection            section;
54   PetscInt                gmin,lmin,lmax;
55 
56   moab::Range adj;
57 
58   PetscFunctionBegin;
59   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
60   /* Get the local and shared vertices and cache it */
61   if (dmmoab->mbiface == PETSC_NULL || dmmoab->pcomm == PETSC_NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp.");
62 
63   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
64   if (dmmoab->vlocal->empty()) {
65     merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
66 
67     /* filter based on parallel status */
68     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr);
69     *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
70 
71     dmmoab->nloc = dmmoab->vowned->size();
72     dmmoab->nghost = dmmoab->vghost->size();
73     ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
74 
75 #if 0
76     if(dmmoab->pcomm->rank() || dmmoab->pcomm->size()==1) {
77       PetscPrintf(PETSC_COMM_SELF, "Vertices: global: %D, local: %D", dmmoab->n, dmmoab->nloc+dmmoab->nghost);
78       dmmoab->vlocal->print(0);
79       PetscPrintf(PETSC_COMM_SELF, "Vertices: owned: %D", dmmoab->nloc);
80       dmmoab->vowned->print(0);
81       PetscPrintf(PETSC_COMM_SELF, "Vertices: ghost: %D", dmmoab->nghost);
82       dmmoab->vghost->print(0);
83     }
84 #endif
85   }
86 
87   /* get the information about the local elements in the mesh */
88   {
89     dmmoab->eghost->clear();
90 
91     /* first decipher the leading dimension */
92     for (i=3;i>0;i--) {
93       dmmoab->elocal->clear();
94       merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, true);CHKERRQ(merr);
95 
96       /* store the current mesh dimension */
97       if (dmmoab->elocal->size()) {
98         dmmoab->dim=i;
99         break;
100       }
101     }
102 
103     *dmmoab->eghost = *dmmoab->elocal;
104     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
105     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
106 
107     dmmoab->neleloc = dmmoab->elocal->size();
108     ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
109   }
110 
111   bs = dmmoab->bs;
112   if (!dmmoab->ltog_tag) {
113     /* Get the global ID tag. The global ID tag is applied to each
114        vertex. It acts as an global identifier which MOAB uses to
115        assemble the individual pieces of the mesh */
116     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
117   }
118 
119   totsize=dmmoab->vlocal->size();
120   ierr = PetscMalloc(totsize*sizeof(PetscInt), &dmmoab->gsindices);CHKERRQ(ierr);
121   {
122     /* first get the local indices */
123     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr);
124     /* next get the ghosted indices */
125     if (dmmoab->nghost) {
126       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr);
127     }
128 
129     /* find out the local and global minima of GLOBAL_ID */
130     lmin=lmax=dmmoab->gsindices[0];
131     for (i=0; i<totsize; ++i) {
132       if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i];
133       if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i];
134     }
135 
136     ierr = MPI_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr);
137     PetscInfo3(dm, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin);
138   }
139 
140   {
141     ierr = PetscSectionCreate(((PetscObject)dm)->comm, &section);CHKERRQ(ierr);
142     ierr = PetscSectionSetNumFields(section, dmmoab->nfields);CHKERRQ(ierr);
143     ierr = PetscSectionSetChart(section, lmin, lmax+1);CHKERRQ(ierr);
144     for (j=0; j<totsize; ++j) {
145       PetscInt locgid = dmmoab->gsindices[j];
146       for (i=0; i < dmmoab->nfields; ++i) {
147         ierr = PetscSectionSetFieldName(section, i, dmmoab->fields[i]);CHKERRQ(ierr);
148         if (bs>1) {
149           ierr = PetscSectionSetFieldDof(section, locgid, i, (locgid-gmin)*dmmoab->nfields+i);CHKERRQ(ierr);
150           ierr = PetscSectionSetFieldOffset(section, locgid, i, (locgid-gmin)*dmmoab->nfields);
151         }
152         else {
153           ierr = PetscSectionSetFieldDof(section, locgid, i, dmmoab->n*i+locgid-gmin);CHKERRQ(ierr);
154           ierr = PetscSectionSetFieldOffset(section, locgid, i, i*dmmoab->n);
155         }
156       }
157       ierr = PetscSectionSetDof(section, locgid, dmmoab->nfields);CHKERRQ(ierr);
158     }
159     ierr = PetscSectionSetUp(section);CHKERRQ(ierr);
160     ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr);
161   }
162 
163   {
164     for (i=0; i<totsize; ++i) {
165       dmmoab->gsindices[i]-=gmin;   /* zero based index needed for IS */
166     }
167 
168     /* Create Global to Local Vector Scatter Context */
169     ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr);
170     ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr);
171 
172     /* global to local must retrieve ghost points */
173     ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&dmmoab->gsindices[0],PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
174 
175     ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr);
176     ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr);
177 
178     ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
179     ierr = ISDestroy(&from);CHKERRQ(ierr);
180     ierr = VecDestroy(&local);CHKERRQ(ierr);
181     ierr = VecDestroy(&global);CHKERRQ(ierr);
182   }
183 
184   /* skin the boundary and store nodes */
185   {
186     moab::Range bndyfaces, bndyvtx, bndyelems;
187     /* get the skin vertices of boundary faces for the current partition and then filter
188        the local, boundary faces, vertices and elements alone via PSTATUS flags;
189        this should not give us any ghosted boundary, but if user needs such a functionality
190        it would be easy to add it based on the find_skin query below */
191     moab::Skinner skinner(dmmoab->mbiface);
192 
193     /* get the entities on the skin - only the faces */
194     merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, bndyfaces, NULL, false, true, false, false);MBERRNM(merr); // 'false' param indicates we want faces back, not vertices
195 
196     /* filter all the non-owned and shared entities out of the list */
197     merr = dmmoab->pcomm->filter_pstatus(bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
198     merr = dmmoab->pcomm->filter_pstatus(bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr);
199 
200     /* get all the nodes via connectivity and the parent elements via adjacency information */
201     merr = dmmoab->mbiface->get_connectivity(bndyfaces, bndyvtx, false);MBERRNM(ierr);
202     merr = dmmoab->mbiface->get_adjacencies(bndyfaces, dmmoab->dim, false, bndyelems, moab::Interface::UNION);MBERRNM(ierr);
203     PetscInfo3(dm, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", bndyvtx.size(), bndyvtx.size(), bndyelems.size());
204 
205     /* cache a bit-vector for easy query */
206     ierr = PetscMalloc(sizeof(PetscBool)*((PetscInt)(*bndyvtx.rbegin())+1),&dmmoab->isbndyvtx);CHKERRQ(ierr);
207     ierr = PetscMemzero(dmmoab->isbndyvtx,sizeof(PetscBool)*((PetscInt)(*bndyvtx.rbegin())+1));CHKERRQ(ierr);
208     for(moab::Range::iterator iter = bndyvtx.begin(); iter != bndyvtx.end(); iter++) {
209       dmmoab->isbndyvtx[(PetscInt)*iter]=PETSC_TRUE;
210     }
211 
212     ierr = PetscMalloc(sizeof(PetscBool)*((PetscInt)(*bndyelems.rbegin())+1),&dmmoab->isbndyelems);CHKERRQ(ierr);
213     ierr = PetscMemzero(dmmoab->isbndyelems,sizeof(PetscBool)*((PetscInt)(*bndyelems.rbegin())+1));CHKERRQ(ierr);
214     for(moab::Range::iterator iter = bndyelems.begin(); iter != bndyelems.end(); iter++) {
215       dmmoab->isbndyelems[(PetscInt)*iter]=PETSC_TRUE;
216     }
217 
218     ierr = PetscMalloc(sizeof(PetscBool)*((PetscInt)(*bndyfaces.rbegin())+1),&dmmoab->isbndyfaces);CHKERRQ(ierr);
219     ierr = PetscMemzero(dmmoab->isbndyfaces,sizeof(PetscBool)*((PetscInt)(*bndyfaces.rbegin())+1));CHKERRQ(ierr);
220     for(moab::Range::iterator iter = bndyfaces.begin(); iter != bndyfaces.end(); iter++) {
221       dmmoab->isbndyfaces[(PetscInt)*iter]=PETSC_TRUE;
222     }
223   }
224   PetscFunctionReturn(0);
225 }
226 
227 
228 #undef __FUNCT__
229 #define __FUNCT__ "DMCreate_Moab"
230 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
231 {
232   PetscErrorCode ierr;
233 
234   PetscFunctionBegin;
235   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
236   ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr);
237 
238   ((DM_Moab*)dm->data)->bs = 1;
239   ((DM_Moab*)dm->data)->nfields = 1;
240   ((DM_Moab*)dm->data)->n = 0;
241   ((DM_Moab*)dm->data)->nloc = 0;
242   ((DM_Moab*)dm->data)->nele = 0;
243   ((DM_Moab*)dm->data)->neleloc = 0;
244   ((DM_Moab*)dm->data)->nghost = 0;
245   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
246   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
247 
248   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
249   ((DM_Moab*)dm->data)->vowned = new moab::Range();
250   ((DM_Moab*)dm->data)->vghost = new moab::Range();
251   ((DM_Moab*)dm->data)->elocal = new moab::Range();
252   ((DM_Moab*)dm->data)->eghost = new moab::Range();
253 
254   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
255   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
256   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
257   dm->ops->setup                           = DMSetUp_Moab;
258   dm->ops->destroy                         = DMDestroy_Moab;
259   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
260   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
261   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
262   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
263   PetscFunctionReturn(0);
264 }
265 
266 #undef __FUNCT__
267 #define __FUNCT__ "DMMoabCreate"
268 /*@
269   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
270 
271   Collective on MPI_Comm
272 
273   Input Parameter:
274 . comm - The communicator for the DMMoab object
275 
276   Output Parameter:
277 . dmb  - The DMMoab object
278 
279   Level: beginner
280 
281 .keywords: DMMoab, create
282 @*/
283 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
284 {
285   PetscErrorCode ierr;
286 
287   PetscFunctionBegin;
288   PetscValidPointer(dmb,2);
289   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
290   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
291   PetscFunctionReturn(0);
292 }
293 
294 #undef __FUNCT__
295 #define __FUNCT__ "DMMoabCreateMoab"
296 /*@
297   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
298 
299   Collective on MPI_Comm
300 
301   Input Parameter:
302 . comm - The communicator for the DMMoab object
303 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
304          along with the DMMoab
305 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
306 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
307 . range - If non-NULL, contains range of entities to which DOFs will be assigned
308 
309   Output Parameter:
310 . dmb  - The DMMoab object
311 
312   Level: intermediate
313 
314 .keywords: DMMoab, create
315 @*/
316 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
317 {
318   PetscErrorCode ierr;
319   moab::ErrorCode merr;
320   moab::EntityHandle partnset;
321   PetscInt rank, nprocs;
322   DM_Moab        *dmmoab;
323 
324   PetscFunctionBegin;
325   PetscValidPointer(dmb,6);
326   ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr);
327   dmmoab = (DM_Moab*)(*dmb)->data;
328 
329   if (!mbiface) {
330     dmmoab->mbiface = new moab::Core();
331     dmmoab->icreatedinstance = PETSC_TRUE;
332   }
333   else {
334     dmmoab->mbiface = mbiface;
335     dmmoab->icreatedinstance = PETSC_FALSE;
336   }
337 
338   /* create a fileset to store the hierarchy of entities belonging to current DM */
339   merr = dmmoab->mbiface->create_meshset(moab::MESHSET_ORDERED, dmmoab->fileset);MBERR("Creating file set failed", merr);
340 
341   if (!pcomm) {
342     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
343     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
344 
345     /* Create root sets for each mesh.  Then pass these
346        to the load_file functions to be populated. */
347     merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);MBERR("Creating partition set failed", merr);
348 
349     /* Create the parallel communicator object with the partition handle associated with MOAB */
350     dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
351   }
352   else {
353     ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr);
354   }
355 
356   /* do the remaining initializations for DMMoab */
357   dmmoab->bs = 1;
358   dmmoab->nfields = 1;
359 
360   /* set global ID tag handle */
361   if (!ltog_tag) {
362     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
363   }
364   else {
365     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
366   }
367 
368   /* set the local range of entities (vertices) of interest */
369   if (range) {
370     ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr);
371   }
372   PetscFunctionReturn(0);
373 }
374 
375 #undef __FUNCT__
376 #define __FUNCT__ "DMMoabSetParallelComm"
377 /*@
378   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
379 
380   Collective on MPI_Comm
381 
382   Input Parameter:
383 . dm    - The DMMoab object being set
384 . pcomm - The ParallelComm being set on the DMMoab
385 
386   Level: beginner
387 
388 .keywords: DMMoab, create
389 @*/
390 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
391 {
392   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
393 
394   PetscFunctionBegin;
395   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
396   PetscValidPointer(pcomm,2);
397   dmmoab->pcomm = pcomm;
398   dmmoab->mbiface = pcomm->get_moab();
399   dmmoab->icreatedinstance = PETSC_FALSE;
400   PetscFunctionReturn(0);
401 }
402 
403 
404 #undef __FUNCT__
405 #define __FUNCT__ "DMMoabGetParallelComm"
406 /*@
407   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
408 
409   Collective on MPI_Comm
410 
411   Input Parameter:
412 . dm    - The DMMoab object being set
413 
414   Output Parameter:
415 . pcomm - The ParallelComm for the DMMoab
416 
417   Level: beginner
418 
419 .keywords: DMMoab, create
420 @*/
421 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
422 {
423   PetscFunctionBegin;
424   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
425   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
426   PetscFunctionReturn(0);
427 }
428 
429 
430 #undef __FUNCT__
431 #define __FUNCT__ "DMMoabSetInterface"
432 /*@
433   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
434 
435   Collective on MPI_Comm
436 
437   Input Parameter:
438 . dm      - The DMMoab object being set
439 . mbiface - The MOAB instance being set on this DMMoab
440 
441   Level: beginner
442 
443 .keywords: DMMoab, create
444 @*/
445 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
446 {
447   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
448 
449   PetscFunctionBegin;
450   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
451   PetscValidPointer(mbiface,2);
452   dmmoab->pcomm = NULL;
453   dmmoab->mbiface = mbiface;
454   dmmoab->icreatedinstance = PETSC_FALSE;
455   PetscFunctionReturn(0);
456 }
457 
458 
459 #undef __FUNCT__
460 #define __FUNCT__ "DMMoabGetInterface"
461 /*@
462   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
463 
464   Collective on MPI_Comm
465 
466   Input Parameter:
467 . dm      - The DMMoab object being set
468 
469   Output Parameter:
470 . mbiface - The MOAB instance set on this DMMoab
471 
472   Level: beginner
473 
474 .keywords: DMMoab, create
475 @*/
476 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
477 {
478   PetscErrorCode   ierr;
479   static PetscBool cite = PETSC_FALSE;
480 
481   PetscFunctionBegin;
482   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
483   ierr = PetscCitationsRegister("@techreport{tautges_moab:_2004,\n  type = {{SAND2004-1592}},\n  title = {{MOAB:} A Mesh-Oriented Database},  institution = {Sandia National Laboratories},\n  author = {Tautges, T. J. and Meyers, R. and Merkley, K. and Stimpson, C. and Ernst, C.},\n  year = {2004},  note = {Report}\n}\n",&cite);CHKERRQ(ierr);
484   *mbiface = ((DM_Moab*)dm->data)->mbiface;
485   PetscFunctionReturn(0);
486 }
487 
488 
489 #undef __FUNCT__
490 #define __FUNCT__ "DMMoabSetLocalVertices"
491 /*@
492   DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab
493 
494   Collective on MPI_Comm
495 
496   Input Parameter:
497 . dm    - The DMMoab object being set
498 . range - The entities treated by this DMMoab
499 
500   Level: beginner
501 
502 .keywords: DMMoab, create
503 @*/
504 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range)
505 {
506   moab::ErrorCode merr;
507   PetscErrorCode  ierr;
508   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
509 
510   PetscFunctionBegin;
511   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
512   dmmoab->vlocal->clear();
513   dmmoab->vowned->clear();
514   dmmoab->vlocal->insert(range->begin(), range->end());
515   *dmmoab->vowned = *dmmoab->vlocal;
516   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
517   *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned);
518   dmmoab->nloc=dmmoab->vowned->size();
519   dmmoab->nghost=dmmoab->vghost->size();
520   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
521   PetscFunctionReturn(0);
522 }
523 
524 
525 #undef __FUNCT__
526 #define __FUNCT__ "DMMoabGetAllVertices"
527 /*@
528   DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab
529 
530   Collective on MPI_Comm
531 
532   Input Parameter:
533 . dm    - The DMMoab object being set
534 
535   Output Parameter:
536 . owned - The local vertex entities in this DMMoab = (owned+ghosted)
537 
538   Level: beginner
539 
540 .keywords: DMMoab, create
541 @*/
542 PetscErrorCode DMMoabGetAllVertices(DM dm,moab::Range *local)
543 {
544   PetscFunctionBegin;
545   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
546   if (local) *local = *((DM_Moab*)dm->data)->vlocal;
547   PetscFunctionReturn(0);
548 }
549 
550 
551 
552 #undef __FUNCT__
553 #define __FUNCT__ "DMMoabGetLocalVertices"
554 /*@
555   DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab
556 
557   Collective on MPI_Comm
558 
559   Input Parameter:
560 . dm    - The DMMoab object being set
561 
562   Output Parameter:
563 . owned - The owned vertex entities in this DMMoab
564 . ghost - The ghosted entities (non-owned) stored locally in this partition
565 
566   Level: beginner
567 
568 .keywords: DMMoab, create
569 @*/
570 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range *owned,moab::Range *ghost)
571 {
572   PetscFunctionBegin;
573   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
574   if (owned) *owned = *((DM_Moab*)dm->data)->vowned;
575   if (ghost) *ghost = *((DM_Moab*)dm->data)->vghost;
576   PetscFunctionReturn(0);
577 }
578 
579 #undef __FUNCT__
580 #define __FUNCT__ "DMMoabGetLocalElements"
581 /*@
582   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
583 
584   Collective on MPI_Comm
585 
586   Input Parameter:
587 . dm    - The DMMoab object being set
588 
589   Output Parameter:
590 . range - The entities owned locally
591 
592   Level: beginner
593 
594 .keywords: DMMoab, create
595 @*/
596 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range *range)
597 {
598   PetscFunctionBegin;
599   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
600   if (range) *range = *((DM_Moab*)dm->data)->elocal;
601   PetscFunctionReturn(0);
602 }
603 
604 
605 #undef __FUNCT__
606 #define __FUNCT__ "DMMoabSetLocalElements"
607 /*@
608   DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab
609 
610   Collective on MPI_Comm
611 
612   Input Parameter:
613 . dm    - The DMMoab object being set
614 . range - The entities treated by this DMMoab
615 
616   Level: beginner
617 
618 .keywords: DMMoab, create
619 @*/
620 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range)
621 {
622   moab::ErrorCode merr;
623   PetscErrorCode  ierr;
624   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
625 
626   PetscFunctionBegin;
627   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
628   dmmoab->elocal->clear();
629   dmmoab->eghost->clear();
630   dmmoab->elocal->insert(range->begin(), range->end());
631   PetscInfo2(dm, "Range size = %D; elocal size = %D.\n", range->size(), dmmoab->elocal->size());
632   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
633   *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal);
634   dmmoab->neleloc=dmmoab->elocal->size();
635   ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
636   PetscInfo2(dm, "Created %D local and %D glocal elements.\n", dmmoab->neleloc, dmmoab->nele);
637   PetscFunctionReturn(0);
638 }
639 
640 
641 #undef __FUNCT__
642 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
643 /*@
644   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
645 
646   Collective on MPI_Comm
647 
648   Input Parameter:
649 . dm      - The DMMoab object being set
650 . ltogtag - The MOAB tag used for local to global ids
651 
652   Level: beginner
653 
654 .keywords: DMMoab, create
655 @*/
656 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
657 {
658   PetscFunctionBegin;
659   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
660   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
661   PetscFunctionReturn(0);
662 }
663 
664 
665 #undef __FUNCT__
666 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
667 /*@
668   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
669 
670   Collective on MPI_Comm
671 
672   Input Parameter:
673 . dm      - The DMMoab object being set
674 
675   Output Parameter:
676 . ltogtag - The MOAB tag used for local to global ids
677 
678   Level: beginner
679 
680 .keywords: DMMoab, create
681 @*/
682 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
683 {
684   PetscFunctionBegin;
685   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
686   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
687   PetscFunctionReturn(0);
688 }
689 
690 
691 #undef __FUNCT__
692 #define __FUNCT__ "DMMoabSetBlockSize"
693 /*@
694   DMMoabSetBlockSize - Set the block size used with this DMMoab
695 
696   Collective on MPI_Comm
697 
698   Input Parameter:
699 . dm - The DMMoab object being set
700 . bs - The block size used with this DMMoab
701 
702   Level: beginner
703 
704 .keywords: DMMoab, create
705 @*/
706 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
707 {
708   PetscFunctionBegin;
709   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
710   ((DM_Moab*)dm->data)->bs = bs;
711   PetscFunctionReturn(0);
712 }
713 
714 
715 #undef __FUNCT__
716 #define __FUNCT__ "DMMoabGetBlockSize"
717 /*@
718   DMMoabGetBlockSize - Get the block size used with this DMMoab
719 
720   Collective on MPI_Comm
721 
722   Input Parameter:
723 . dm - The DMMoab object being set
724 
725   Output Parameter:
726 . bs - The block size used with this DMMoab
727 
728   Level: beginner
729 
730 .keywords: DMMoab, create
731 @*/
732 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
733 {
734   PetscFunctionBegin;
735   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
736   *bs = ((DM_Moab*)dm->data)->bs;
737   PetscFunctionReturn(0);
738 }
739 
740 
741 #undef __FUNCT__
742 #define __FUNCT__ "DMMoabGetSize"
743 /*@
744   DMMoabGetSize - Get the global vertex size used with this DMMoab
745 
746   Collective on MPI_Comm
747 
748   Input Parameter:
749 . dm - The DMMoab object being set
750 
751   Output Parameter:
752 . ng - The global size of the DMMoab instance
753 
754   Level: beginner
755 
756 .keywords: DMMoab, create
757 @*/
758 PetscErrorCode DMMoabGetSize(DM dm,PetscInt *ng)
759 {
760   PetscFunctionBegin;
761   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
762   if(ng) *ng = ((DM_Moab*)dm->data)->n;
763   PetscFunctionReturn(0);
764 }
765 
766 
767 #undef __FUNCT__
768 #define __FUNCT__ "DMMoabGetLocalSize"
769 /*@
770   DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab
771 
772   Collective on MPI_Comm
773 
774   Input Parameter:
775 . dm - The DMMoab object being set
776 
777   Output Parameter:
778 . nl - The local size of the DMMoab instance
779 . ng - The ghosted size of the DMMoab instance
780 
781   Level: beginner
782 
783 .keywords: DMMoab, create
784 @*/
785 PetscErrorCode DMMoabGetLocalSize(DM dm,PetscInt *nl,PetscInt *ng)
786 {
787   PetscFunctionBegin;
788   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
789   if(nl) *nl = ((DM_Moab*)dm->data)->nloc;
790   if(ng) *ng = ((DM_Moab*)dm->data)->nghost;
791   PetscFunctionReturn(0);
792 }
793 
794 
795 #undef __FUNCT__
796 #define __FUNCT__ "DMMoabGetDimension"
797 /*@
798   DMMoabGetDimension - Get the dimension of the DM Mesh
799 
800   Collective on MPI_Comm
801 
802   Input Parameter:
803 . dm - The DMMoab object being set
804 
805   Output Parameter:
806 . dim - The dimension of DM
807 
808   Level: beginner
809 
810 .keywords: DMMoab, create
811 @*/
812 PetscErrorCode DMMoabGetDimension(DM dm,PetscInt *dim)
813 {
814   PetscFunctionBegin;
815   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
816   *dim = ((DM_Moab*)dm->data)->dim;
817   PetscFunctionReturn(0);
818 }
819 
820 
821 
822 #undef __FUNCT__
823 #define __FUNCT__ "DMMoabSetFieldVector"
824 PetscErrorCode DMMoabSetFieldVector(DM dm, PetscInt ifield, Vec fvec)
825 {
826   DM_Moab        *dmmoab;
827   moab::Tag     vtag,ntag;
828   const PetscScalar *varray;
829   PetscScalar *farray;
830   moab::ErrorCode merr;
831   PetscErrorCode  ierr;
832   PetscInt doff;
833   std::string tag_name;
834   moab::Range::iterator iter;
835 
836   PetscFunctionBegin;
837   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
838   dmmoab = (DM_Moab*)(dm)->data;
839 
840   /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
841   merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag,
842                                           moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr);
843 
844   ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr);
845 
846   merr = dmmoab->mbiface->tag_get_name(vtag, tag_name);
847   if (!tag_name.length() && merr !=moab::MB_SUCCESS) {
848     ierr = VecGetArrayRead(fvec,&varray);CHKERRQ(ierr);
849 
850     for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) {
851       moab::EntityHandle vtx = (*iter);
852 
853       /* get field dof index */
854       ierr = DMMoabGetFieldDof(dm, vtx, ifield, &doff);
855 
856       /* use the entity handle and the Dof index to set the right value */
857       merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr);
858     }
859     ierr = VecRestoreArrayRead(fvec,&varray);CHKERRQ(ierr);
860   }
861   else {
862     ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&farray);CHKERRQ(ierr);
863     /* we are using a MOAB Vec - directly copy the tag data to new one */
864     merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)farray);MBERRNM(merr);
865     merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)farray);MBERRNM(merr);
866     /* make sure the parallel exchange for ghosts are done appropriately */
867     merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr);
868     ierr = PetscFree(farray);CHKERRQ(ierr);
869   }
870   PetscFunctionReturn(0);
871 }
872 
873 
874 #undef __FUNCT__
875 #define __FUNCT__ "DMMoabSetGlobalFieldVector"
876 PetscErrorCode DMMoabSetGlobalFieldVector(DM dm, Vec fvec)
877 {
878   DM_Moab        *dmmoab;
879   moab::Tag     vtag,ntag;
880   const PetscScalar   *varray;
881   PetscScalar   *farray;
882   moab::ErrorCode merr;
883   PetscErrorCode  ierr;
884   PetscSection section;
885   PetscInt i,doff,ifield;
886   std::string tag_name;
887   moab::Range::iterator iter;
888 
889   PetscFunctionBegin;
890   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
891   dmmoab = (DM_Moab*)(dm)->data;
892 
893   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
894 
895   /* get the Tag corresponding to the global vector - possible that there is no tag associated.. */
896   ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr);
897   merr = dmmoab->mbiface->tag_get_name(vtag, tag_name);
898   if (!tag_name.length() && merr !=moab::MB_SUCCESS) {
899     /* not a MOAB vector - use VecGetSubVector to get the parts as needed */
900 
901     ierr = VecGetArrayRead(fvec,&varray);CHKERRQ(ierr);
902     for (ifield=0; ifield<dmmoab->nfields; ++ifield) {
903 
904       /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
905       merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag,
906                                             moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr);
907 
908       for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) {
909         moab::EntityHandle vtx = (*iter);
910 
911         /* get field dof index */
912         ierr = DMMoabGetFieldDof(dm, vtx, ifield, &doff);
913 
914         /* use the entity handle and the Dof index to set the right value */
915         merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr);
916       }
917     }
918     ierr = VecRestoreArrayRead(fvec,&varray);CHKERRQ(ierr);
919   }
920   else {
921     ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&farray);CHKERRQ(ierr);
922     ierr = PetscMalloc(dmmoab->nloc*dmmoab->bs*sizeof(PetscScalar),&varray);CHKERRQ(ierr);
923 
924     /* we are using a MOAB Vec - directly copy the tag data to new one */
925     merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)varray);MBERRNM(merr);
926     for (ifield=0; ifield<dmmoab->nfields; ++ifield) {
927 
928       /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
929       merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag,
930                                             moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr);
931 
932       /* we are using a MOAB Vec - directly copy the tag data to new one */
933       for(i=0; i < dmmoab->nloc; i++) {
934         farray[i] = varray[i*dmmoab->bs+ifield];
935       }
936 
937       merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)farray);MBERRNM(merr);
938       /* make sure the parallel exchange for ghosts are done appropriately */
939       merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr);
940     }
941     ierr = PetscFree(farray);CHKERRQ(ierr);
942     ierr = PetscFree(varray);CHKERRQ(ierr);
943   }
944   PetscFunctionReturn(0);
945 }
946 
947 
948 
949 #undef __FUNCT__
950 #define __FUNCT__ "DMMoabGetVertexCoordinates"
951 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscScalar *vpos)
952 {
953   DM_Moab         *dmmoab;
954   PetscErrorCode  ierr;
955   moab::ErrorCode merr;
956 
957   PetscFunctionBegin;
958   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
959   PetscValidPointer(conn,3);
960   dmmoab = (DM_Moab*)(dm)->data;
961 
962   if (!vpos) {
963     ierr = PetscMalloc(sizeof(PetscScalar)*nconn*3, &vpos);CHKERRQ(ierr);
964   }
965 
966   /* Get connectivity information in MOAB canonical ordering */
967   merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr);
968   PetscFunctionReturn(0);
969 }
970 
971 
972 #undef __FUNCT__
973 #define __FUNCT__ "DMMoabGetVertexConnectivity"
974 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn)
975 {
976   DM_Moab        *dmmoab;
977   std::vector<moab::EntityHandle> adj_entities,connect;
978   PetscErrorCode  ierr;
979   moab::ErrorCode merr;
980 
981   PetscFunctionBegin;
982   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
983   PetscValidPointer(conn,4);
984   dmmoab = (DM_Moab*)(dm)->data;
985 
986   /* Get connectivity information in MOAB canonical ordering */
987   merr = dmmoab->mbiface->get_adjacencies(&ehandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr);
988   merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr);
989 
990 #if 0
991   for(unsigned int jter = 0; jter < connect.size(); jter++) {
992     PetscPrintf(PETSC_COMM_SELF,"Handle=%D\tAdj_Size=%D\tAdj_Entity=%D\n",ehandle,connect.size(),connect[jter]);
993   }
994 #endif
995 
996   if (conn) {
997     ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr);
998     ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr);
999   }
1000   if (nconn) *nconn=connect.size();
1001   PetscFunctionReturn(0);
1002 }
1003 
1004 
1005 #undef __FUNCT__
1006 #define __FUNCT__ "DMMoabRestoreVertexConnectivity"
1007 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn)
1008 {
1009   PetscErrorCode  ierr;
1010 
1011   PetscFunctionBegin;
1012   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1013   PetscValidPointer(conn,4);
1014 
1015   if (conn) {
1016     ierr = PetscFree(*conn);CHKERRQ(ierr);
1017   }
1018   if (nconn) *nconn=0;
1019   PetscFunctionReturn(0);
1020 }
1021 
1022 
1023 
1024 #undef __FUNCT__
1025 #define __FUNCT__ "DMMoabGetElementConnectivity"
1026 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn)
1027 {
1028   DM_Moab        *dmmoab;
1029   const moab::EntityHandle *connect;
1030   moab::ErrorCode merr;
1031   PetscInt nnodes;
1032 
1033   PetscFunctionBegin;
1034   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1035   PetscValidPointer(conn,4);
1036   dmmoab = (DM_Moab*)(dm)->data;
1037 
1038   /* Get connectivity information in MOAB canonical ordering */
1039   merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr);
1040   if (conn) *conn=connect;
1041   if (nconn) *nconn=nnodes;
1042   PetscFunctionReturn(0);
1043 }
1044 
1045 
1046 #undef __FUNCT__
1047 #define __FUNCT__ "DMMoabIsEntityOnBoundary"
1048 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary)
1049 {
1050   moab::EntityType etype;
1051   DM_Moab         *dmmoab;
1052   PetscInt         edim;
1053 
1054   PetscFunctionBegin;
1055   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1056   PetscValidPointer(ent_on_boundary,3);
1057   dmmoab = (DM_Moab*)(dm)->data;
1058 
1059   /* get the entity type and handle accordingly */
1060   etype=dmmoab->mbiface->type_from_handle(ent);
1061   if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype);
1062 
1063   /* get the entity dimension */
1064   edim=dmmoab->mbiface->dimension_from_handle(ent);
1065 
1066   *ent_on_boundary=PETSC_FALSE;
1067   if(etype == moab::MBVERTEX && edim == 0) {
1068     if (ent < (*dmmoab->vlocal)[0] || ent > (*dmmoab->vlocal)[dmmoab->nloc-1]) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid boundary vertex entity handle: %D\n",ent);
1069     *ent_on_boundary=dmmoab->isbndyvtx[(PetscInt)ent];
1070   }
1071   else {
1072     if (edim == dmmoab->dim) {  /* check the higher-dimensional elements first */
1073       if (ent < (*dmmoab->elocal)[0] || ent > (*dmmoab->elocal)[dmmoab->neleloc-1]) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid boundary element entity handle: %D\n",ent);
1074       *ent_on_boundary=dmmoab->isbndyelems[(PetscInt)ent];
1075     }
1076     else {                      /* next check the lower-dimensional faces */
1077       /* how do we check the bounds before accessing ? will segfault for non-boundary faces */
1078       *ent_on_boundary=dmmoab->isbndyfaces[(PetscInt)ent];
1079     }
1080   }
1081   PetscFunctionReturn(0);
1082 }
1083 
1084 
1085 #undef __FUNCT__
1086 #define __FUNCT__ "DMMoabCheckBoundaryVertices"
1087 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx)
1088 {
1089   DM_Moab        *dmmoab;
1090   PetscInt       i;
1091 
1092   PetscFunctionBegin;
1093   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1094   PetscValidPointer(cnt,3);
1095   PetscValidPointer(isbdvtx,4);
1096   dmmoab = (DM_Moab*)(dm)->data;
1097 
1098   for (i=0; i < nconn; ++i) {
1099     isbdvtx[i]=dmmoab->isbndyvtx[(PetscInt)cnt[i]];
1100   }
1101   PetscFunctionReturn(0);
1102 }
1103 
1104 
1105 #undef __FUNCT__
1106 #define __FUNCT__ "DMMoabGetBoundaryMarkers"
1107 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,PetscBool **bdvtx,PetscBool** bdelems,PetscBool** bdfaces)
1108 {
1109   DM_Moab        *dmmoab;
1110 
1111   PetscFunctionBegin;
1112   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1113   dmmoab = (DM_Moab*)(dm)->data;
1114 
1115   if (bdvtx)  *bdvtx = dmmoab->isbndyvtx;
1116   if (bdfaces)  *bdfaces = dmmoab->isbndyfaces;
1117   if (bdelems)  *bdfaces = dmmoab->isbndyelems;
1118   PetscFunctionReturn(0);
1119 }
1120 
1121 
1122 #undef __FUNCT__
1123 #define __FUNCT__ "DMMoabSetFields"
1124 PetscErrorCode DMMoabSetFields(DM dm,PetscInt nfields,const char** fields)
1125 {
1126   DM_Moab        *dmmoab;
1127 
1128   PetscFunctionBegin;
1129   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1130   dmmoab = (DM_Moab*)(dm)->data;
1131 
1132   dmmoab->fields = fields;
1133   dmmoab->nfields = nfields;
1134   PetscFunctionReturn(0);
1135 }
1136 
1137 
1138 #undef __FUNCT__
1139 #define __FUNCT__ "DMMoabGetFieldDof"
1140 PetscErrorCode DMMoabGetFieldDof(DM dm,moab::EntityHandle point,PetscInt field,PetscInt* dof)
1141 {
1142   PetscSection section;
1143   PetscInt gid;
1144   PetscErrorCode ierr;
1145   moab::ErrorCode merr;
1146   DM_Moab        *dmmoab;
1147 
1148   PetscFunctionBegin;
1149   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1150   dmmoab = (DM_Moab*)(dm)->data;
1151 
1152   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1153 
1154   /* first get the global ID for the point */
1155   merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&point,1,&gid);MBERRNM(merr);
1156 
1157   /* get the dof value for the field */
1158   ierr = PetscSectionGetFieldDof(section, gid, field, dof);CHKERRQ(ierr);
1159   PetscFunctionReturn(0);
1160 }
1161 
1162 
1163 #undef __FUNCT__
1164 #define __FUNCT__ "DMMoabGetFieldDofs"
1165 PetscErrorCode DMMoabGetFieldDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof)
1166 {
1167   PetscInt i,gid;
1168   PetscSection section;
1169   PetscErrorCode  ierr;
1170   moab::ErrorCode merr;
1171   DM_Moab        *dmmoab;
1172 
1173   PetscFunctionBegin;
1174   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1175   PetscValidPointer(points,2);
1176   dmmoab = (DM_Moab*)(dm)->data;
1177 
1178   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1179   if (!dof) {
1180     ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr);
1181   }
1182 
1183   /* first get the local indices */
1184   merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr);
1185 
1186   for (i=0; i<npoints; ++i) {
1187     gid=dof[i];
1188     ierr = PetscSectionGetFieldDof(section, gid, field, &dof[i]);CHKERRQ(ierr);
1189   }
1190   PetscFunctionReturn(0);
1191 }
1192 
1193 
1194 #undef __FUNCT__
1195 #define __FUNCT__ "DMMoabGetFieldDofsLocal"
1196 PetscErrorCode DMMoabGetFieldDofsLocal(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof)
1197 {
1198   PetscInt i,offset;
1199   PetscErrorCode  ierr;
1200   DM_Moab        *dmmoab;
1201 
1202   PetscFunctionBegin;
1203   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1204   PetscValidPointer(points,2);
1205   dmmoab = (DM_Moab*)(dm)->data;
1206 
1207   if (!dof) {
1208     ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr);
1209   }
1210 
1211   if (dmmoab->bs > 1) {
1212     for (i=0; i<npoints; ++i)
1213       dof[i] = (points[i]-1)*dmmoab->bs+field;
1214   }
1215   else {
1216     offset = field*dmmoab->n; /* assume all fields have equal distribution */
1217     for (i=0; i<npoints; ++i)
1218       dof[i] = offset+points[i]-1;
1219   }
1220   PetscFunctionReturn(0);
1221 }
1222 
1223 
1224 #undef __FUNCT__
1225 #define __FUNCT__ "DMMoabGetDofs"
1226 PetscErrorCode DMMoabGetDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof)
1227 {
1228   PetscInt i,f,gid;
1229   PetscSection section;
1230   PetscErrorCode  ierr;
1231   moab::ErrorCode merr;
1232   DM_Moab        *dmmoab;
1233 
1234   PetscFunctionBegin;
1235   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1236   PetscValidPointer(points,2);
1237   dmmoab = (DM_Moab*)(dm)->data;
1238 
1239   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1240   if (!dof) {
1241     ierr = PetscMalloc(sizeof(PetscInt)*dmmoab->nfields*npoints, &dof);CHKERRQ(ierr);
1242   }
1243 
1244   /* first get the local indices */
1245   merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr);
1246 
1247   for (i=0; i<npoints; ++i) {
1248     gid=dof[i];
1249     for (f=0; f<dmmoab->nfields; ++f) {
1250       ierr = PetscSectionGetFieldDof(section, gid, f, &dof[i*dmmoab->nfields+f]);CHKERRQ(ierr);
1251     }
1252   }
1253   PetscFunctionReturn(0);
1254 }
1255 
1256 
1257 #undef __FUNCT__
1258 #define __FUNCT__ "DMMoabGetDofsLocal"
1259 PetscErrorCode DMMoabGetDofsLocal(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof)
1260 {
1261   PetscInt        i,f,offset;
1262   PetscErrorCode  ierr;
1263   DM_Moab        *dmmoab;
1264 
1265   PetscFunctionBegin;
1266   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1267   PetscValidPointer(points,2);
1268   dmmoab = (DM_Moab*)(dm)->data;
1269 
1270   if (!dof) {
1271     ierr = PetscMalloc(sizeof(PetscInt)*dmmoab->nfields*npoints, &dof);CHKERRQ(ierr);
1272   }
1273 
1274   if (dmmoab->bs > 1) {
1275     for (f=0; f<dmmoab->nfields; ++f)
1276       for (i=0; i<npoints; ++i)
1277         dof[i*dmmoab->nfields+f] = (points[i]-1)*dmmoab->bs+f;
1278   }
1279   else {
1280     for (f=0; f<dmmoab->nfields; ++f) {
1281       offset = f*dmmoab->n;     /* assume all fields have equal distribution - say all vertex based */
1282       for (i=0; i<npoints; ++i)
1283         dof[i*dmmoab->nfields+f] = offset+points[i]-1;
1284     }
1285   }
1286   PetscFunctionReturn(0);
1287 }
1288 
1289 
1290 #undef __FUNCT__
1291 #define __FUNCT__ "DMMoabGetDofsBlocked"
1292 PetscErrorCode DMMoabGetDofsBlocked(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof)
1293 {
1294   PetscInt i,gid,dofindx;
1295   PetscSection section;
1296   PetscErrorCode  ierr;
1297   moab::ErrorCode merr;
1298   DM_Moab        *dmmoab;
1299 
1300   PetscFunctionBegin;
1301   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1302   PetscValidPointer(points,2);
1303   dmmoab = (DM_Moab*)(dm)->data;
1304 
1305   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1306   if (!dof) {
1307     ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr);
1308   }
1309 
1310   /* first get the local indices */
1311   merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr);
1312 
1313   for (i=0; i<npoints; ++i) {
1314     gid=dof[i];
1315     ierr = PetscSectionGetFieldDof(section, gid, 0, &dofindx);CHKERRQ(ierr);
1316     if (dmmoab->bs > 1)  dof[i]=dofindx/dmmoab->bs;
1317     else dof[i]=dofindx;
1318   }
1319   PetscFunctionReturn(0);
1320 }
1321 
1322 
1323 #undef __FUNCT__
1324 #define __FUNCT__ "DMMoabGetDofsBlockedLocal"
1325 PetscErrorCode DMMoabGetDofsBlockedLocal(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof)
1326 {
1327   PetscInt        i;
1328   PetscErrorCode  ierr;
1329 
1330   PetscFunctionBegin;
1331   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1332   PetscValidPointer(points,2);
1333 
1334   if (!dof) {
1335     ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr);
1336   }
1337 
1338   for (i=0; i<npoints; ++i)
1339     dof[i] = points[i]-1;
1340   PetscFunctionReturn(0);
1341 }
1342 
1343 
1344 #undef __FUNCT__
1345 #define __FUNCT__ "DMMoabGetVertexDofsBlocked"
1346 PetscErrorCode DMMoabGetVertexDofsBlocked(DM dm,PetscInt** dof)
1347 {
1348   PetscInt        i,gid;
1349   DM_Moab        *dmmoab;
1350   PetscSection section;
1351   PetscErrorCode  ierr;
1352   moab::ErrorCode merr;
1353 
1354   PetscFunctionBegin;
1355   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1356   dmmoab = (DM_Moab*)(dm)->data;
1357 
1358   *dof = dmmoab->gsindices;
1359 
1360   if (false) {
1361     if (!dof) {
1362       ierr = PetscMalloc(sizeof(PetscInt)*(dmmoab->nloc+dmmoab->nghost), dof);CHKERRQ(ierr);
1363     }
1364 
1365     /* first get the local indices */
1366     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vlocal,*dof);MBERRNM(merr);
1367 
1368     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1369 
1370     /* Compute function over the locally owned part of the grid */
1371     for(i=0; i<dmmoab->nloc+dmmoab->nghost; i++) {
1372       gid=(*dof)[i];
1373       ierr = PetscSectionGetFieldDof(section, gid, 0, &(*dof)[i]);CHKERRQ(ierr);
1374     }
1375   }
1376   PetscFunctionReturn(0);
1377 }
1378 
1379 
1380 #undef __FUNCT__
1381 #define __FUNCT__ "DMMoabGetVertexDofsBlockedLocal"
1382 PetscErrorCode DMMoabGetVertexDofsBlockedLocal(DM dm,PetscInt** dof)
1383 {
1384   PetscInt        i;
1385   DM_Moab        *dmmoab;
1386   PetscErrorCode  ierr;
1387 
1388   PetscFunctionBegin;
1389   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1390   PetscValidPointer(dof,2);
1391   dmmoab = (DM_Moab*)(dm)->data;
1392 
1393   if (!(*dof)) {
1394     ierr = PetscMalloc(sizeof(PetscInt)*(dmmoab->nloc+dmmoab->nghost), dof);CHKERRQ(ierr);
1395   }
1396 
1397   i=0;
1398   /* Compute function over the locally owned part of the grid */
1399   for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) {
1400     (*dof)[i] = (*iter)-1;
1401   }
1402   for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) {
1403     (*dof)[i] = (*iter)-1;
1404   }
1405   PetscFunctionReturn(0);
1406 }
1407 
1408 
1409 #undef __FUNCT__
1410 #define __FUNCT__ "DMMoab_GetWriteOptions_Private"
1411 PetscErrorCode DMMoab_GetWriteOptions_Private(PetscInt fsetid, PetscInt numproc, PetscInt dim, MoabWriteMode mode, PetscInt dbglevel, const char* extra_opts, const char** write_opts)
1412 {
1413   std::ostringstream str;
1414 
1415   PetscFunctionBegin;
1416 
1417   // do parallel read unless only one processor
1418   if (numproc > 1) {
1419     str << "PARALLEL=" << mode << ";";
1420     if (fsetid>=0) str << "PARALLEL_COMM=" << fsetid << ";";
1421   }
1422 
1423   if (dbglevel)
1424     str << "CPUTIME;DEBUG_IO=" << dbglevel << ";";
1425 
1426   if (extra_opts)
1427     str << extra_opts ;
1428 
1429   *write_opts = str.str().c_str();
1430   PetscFunctionReturn(0);
1431 }
1432 
1433 
1434 #undef __FUNCT__
1435 #define __FUNCT__ "DMMoabOutput"
1436 PetscErrorCode DMMoabOutput(DM dm,const char* filename,const char* usrwriteopts)
1437 {
1438   DM_Moab        *dmmoab;
1439   PetscInt       dbglevel=0;
1440   const char *writeopts;
1441 
1442   PetscErrorCode ierr;
1443   moab::ErrorCode merr;
1444 
1445   PetscFunctionBegin;
1446   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1447   dmmoab = (DM_Moab*)(dm)->data;
1448 
1449   PetscBarrier((PetscObject)dm);
1450 
1451   /* TODO: Use command-line options to control by_rank, verbosity, MoabReadMode and extra options */
1452   ierr  = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for reading/writing MOAB based meshes from file", "DMMoab");
1453   ierr  = PetscOptionsInt("-dmmb_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "dmmbutil.cxx", dbglevel, &dbglevel, NULL);CHKERRQ(ierr);
1454   ierr  = PetscOptionsEnd();
1455 
1456   /* add mesh loading options specific to the DM */
1457   ierr = DMMoab_GetWriteOptions_Private(dmmoab->pcomm->get_id(), dmmoab->pcomm->size(), dmmoab->dim, MOAB_PARWOPTS_WRITE_PART, dbglevel, usrwriteopts, &writeopts);CHKERRQ(ierr);
1458   PetscInfo2(dm, "Writing file %s with options: %s\n",filename,writeopts);
1459 
1460   /* output file, using parallel write */
1461   merr = dmmoab->mbiface->write_file(filename, NULL, writeopts, &dmmoab->fileset, 1);MBERRVM(dmmoab->mbiface,"Writing output of DMMoab failed.",merr);
1462   PetscFunctionReturn(0);
1463 }
1464 
1465