xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision a4e35b1925eceef64945ea472b84f2bf06a67b5e)
1 #include <petsc/private/dmmbimpl.h> /*I  "petscdmmoab.h"   I*/
2 
3 #include <petscdmmoab.h>
4 #include <MBTagConventions.hpp>
5 #include <moab/NestedRefine.hpp>
6 #include <moab/Skinner.hpp>
7 
8 /*MC
9   DMMOAB = "moab" - A DM object that encapsulates an unstructured mesh described by the MOAB mesh database.
10                     Direct access to the MOAB Interface and other mesh manipulation related objects are available
11                     through public API. Ability to create global and local representation of Vecs containing all
12                     unknowns in the interior and shared boundary via a transparent tag-data wrapper is provided
13                     along with utility functions to traverse the mesh and assemble a discrete system via
14                     field-based/blocked Vec(Get/Set) methods. Input from and output to different formats are
15                     available.
16 
17   Reference: https://www.mcs.anl.gov/~fathom/moab-docs/html/contents.html
18 
19   Level: intermediate
20 
21 .seealso: `DMType`, `DMMoabCreate()`, `DMCreate()`, `DMSetType()`, `DMMoabCreateMoab()`
22 M*/
23 
24 /* External function declarations here */
25 PETSC_EXTERN PetscErrorCode DMCreateInterpolation_Moab(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling);
26 PETSC_EXTERN PetscErrorCode DMCreateDefaultConstraints_Moab(DM dm);
27 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J);
28 PETSC_EXTERN PetscErrorCode DMCreateCoordinateDM_Moab(DM dm, DM *cdm);
29 PETSC_EXTERN PetscErrorCode DMRefine_Moab(DM dm, MPI_Comm comm, DM *dmRefined);
30 PETSC_EXTERN PetscErrorCode DMCoarsen_Moab(DM dm, MPI_Comm comm, DM *dmCoarsened);
31 PETSC_EXTERN PetscErrorCode DMRefineHierarchy_Moab(DM dm, PetscInt nlevels, DM dmRefined[]);
32 PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy_Moab(DM dm, PetscInt nlevels, DM dmCoarsened[]);
33 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm);
34 PETSC_EXTERN PetscErrorCode DMCreateGlobalVector_Moab(DM, Vec *);
35 PETSC_EXTERN PetscErrorCode DMCreateLocalVector_Moab(DM, Vec *);
36 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J);
37 PETSC_EXTERN PetscErrorCode DMGlobalToLocalBegin_Moab(DM, Vec, InsertMode, Vec);
38 PETSC_EXTERN PetscErrorCode DMGlobalToLocalEnd_Moab(DM, Vec, InsertMode, Vec);
39 PETSC_EXTERN PetscErrorCode DMLocalToGlobalBegin_Moab(DM, Vec, InsertMode, Vec);
40 PETSC_EXTERN PetscErrorCode DMLocalToGlobalEnd_Moab(DM, Vec, InsertMode, Vec);
41 
42 /* Un-implemented routines */
43 /*
44 PETSC_EXTERN PetscErrorCode DMCreatelocalsection_Moab(DM dm);
45 PETSC_EXTERN PetscErrorCode DMCreateInjection_Moab(DM dmCoarse, DM dmFine, Mat *mat);
46 PETSC_EXTERN PetscErrorCode DMLoad_Moab(DM dm, PetscViewer viewer);
47 PETSC_EXTERN PetscErrorCode DMGetDimPoints_Moab(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd);
48 PETSC_EXTERN PetscErrorCode DMCreateSubDM_Moab(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm);
49 PETSC_EXTERN PetscErrorCode DMLocatePoints_Moab(DM dm, Vec v, IS *cellIS);
50 */
51 
52 /*@C
53   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
54 
55   Collective
56 
57   Input Parameter:
58 . comm - The communicator for the DMMoab object
59 
60   Output Parameter:
61 . dmb - The DMMoab object
62 
63   Level: beginner
64 
65 .seealso: `DMMoabCreateMoab()`
66 @*/
67 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
68 {
69   PetscFunctionBegin;
70   PetscAssertPointer(dmb, 2);
71   PetscCall(DMCreate(comm, dmb));
72   PetscCall(DMSetType(*dmb, DMMOAB));
73   PetscFunctionReturn(PETSC_SUCCESS);
74 }
75 
76 /*@C
77   DMMoabCreateMoab - Creates a DMMoab object, optionally from an instance and other data
78 
79   Collective
80 
81   Input Parameters:
82 + comm     - The communicator for the DMMoab object
83 . mbiface  - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
84          along with the DMMoab
85 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
86 - range    - If non-NULL, contains range of entities to which DOFs will be assigned
87 
88   Output Parameter:
89 . dmb - The DMMoab object
90 
91   Level: intermediate
92 
93 .seealso: `DMMoabCreate()`
94 @*/
95 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
96 {
97   moab::ErrorCode merr;
98   DM              dmmb;
99   DM_Moab        *dmmoab;
100 
101   PetscFunctionBegin;
102   PetscAssertPointer(dmb, 6);
103 
104   PetscCall(DMMoabCreate(comm, &dmmb));
105   dmmoab = (DM_Moab *)(dmmb)->data;
106 
107   if (!mbiface) {
108     dmmoab->mbiface          = new moab::Core();
109     dmmoab->icreatedinstance = PETSC_TRUE;
110   } else {
111     dmmoab->mbiface          = mbiface;
112     dmmoab->icreatedinstance = PETSC_FALSE;
113   }
114 
115   /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */
116   dmmoab->fileset     = 0;
117   dmmoab->hlevel      = 0;
118   dmmoab->nghostrings = 0;
119 
120 #ifdef MOAB_HAVE_MPI
121   moab::EntityHandle partnset;
122 
123   /* Create root sets for each mesh.  Then pass these
124       to the load_file functions to be populated. */
125   merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);
126   MBERR("Creating partition set failed", merr);
127 
128   /* Create the parallel communicator object with the partition handle associated with MOAB */
129   dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
130 #endif
131 
132   /* do the remaining initializations for DMMoab */
133   dmmoab->bs        = 1;
134   dmmoab->numFields = 1;
135   PetscCall(PetscMalloc(dmmoab->numFields * sizeof(char *), &dmmoab->fieldNames));
136   PetscCall(PetscStrallocpy("DEFAULT", (char **)&dmmoab->fieldNames[0]));
137   dmmoab->rw_dbglevel            = 0;
138   dmmoab->partition_by_rank      = PETSC_FALSE;
139   dmmoab->extra_read_options[0]  = '\0';
140   dmmoab->extra_write_options[0] = '\0';
141   dmmoab->read_mode              = READ_PART;
142   dmmoab->write_mode             = WRITE_PART;
143 
144   /* set global ID tag handle */
145   if (ltog_tag && *ltog_tag) {
146     PetscCall(DMMoabSetLocalToGlobalTag(dmmb, *ltog_tag));
147   } else {
148     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);
149     MBERRNM(merr);
150     if (ltog_tag) *ltog_tag = dmmoab->ltog_tag;
151   }
152 
153   merr = dmmoab->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dmmoab->material_tag);
154   MBERRNM(merr);
155 
156   /* set the local range of entities (vertices) of interest */
157   if (range) PetscCall(DMMoabSetLocalVertices(dmmb, range));
158   *dmb = dmmb;
159   PetscFunctionReturn(PETSC_SUCCESS);
160 }
161 
162 #ifdef MOAB_HAVE_MPI
163 
164 /*@C
165   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
166 
167   Collective
168 
169   Input Parameter:
170 . dm    - The DMMoab object being set
171 
172   Output Parameter:
173 . pcomm - The ParallelComm for the DMMoab
174 
175   Level: beginner
176 
177 .seealso: `DMMoabSetInterface()`
178 @*/
179 PetscErrorCode DMMoabGetParallelComm(DM dm, moab::ParallelComm **pcomm)
180 {
181   PetscFunctionBegin;
182   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
183   *pcomm = ((DM_Moab *)(dm)->data)->pcomm;
184   PetscFunctionReturn(PETSC_SUCCESS);
185 }
186 
187 #endif /* MOAB_HAVE_MPI */
188 
189 /*@C
190   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
191 
192   Collective
193 
194   Input Parameters:
195 + dm      - The DMMoab object being set
196 - mbiface - The MOAB instance being set on this DMMoab
197 
198   Level: beginner
199 
200 .seealso: `DMMoabGetInterface()`
201 @*/
202 PetscErrorCode DMMoabSetInterface(DM dm, moab::Interface *mbiface)
203 {
204   DM_Moab *dmmoab = (DM_Moab *)(dm)->data;
205 
206   PetscFunctionBegin;
207   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
208   PetscAssertPointer(mbiface, 2);
209 #ifdef MOAB_HAVE_MPI
210   dmmoab->pcomm = NULL;
211 #endif
212   dmmoab->mbiface          = mbiface;
213   dmmoab->icreatedinstance = PETSC_FALSE;
214   PetscFunctionReturn(PETSC_SUCCESS);
215 }
216 
217 /*@C
218   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
219 
220   Collective
221 
222   Input Parameter:
223 . dm - The DMMoab object being set
224 
225   Output Parameter:
226 . mbiface - The MOAB instance set on this DMMoab
227 
228   Level: beginner
229 
230 .seealso: `DMMoabSetInterface()`
231 @*/
232 PetscErrorCode DMMoabGetInterface(DM dm, moab::Interface **mbiface)
233 {
234   static PetscBool cite = PETSC_FALSE;
235 
236   PetscFunctionBegin;
237   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
238   PetscCall(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, "
239                                    "K. and Stimpson, C. and Ernst, C.},\n  year = {2004},  note = {Report}\n}\n",
240                                    &cite));
241   *mbiface = ((DM_Moab *)dm->data)->mbiface;
242   PetscFunctionReturn(PETSC_SUCCESS);
243 }
244 
245 /*@C
246   DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab
247 
248   Collective
249 
250   Input Parameters:
251 + dm    - The DMMoab object being set
252 - range - The entities treated by this DMMoab
253 
254   Level: beginner
255 
256 .seealso: `DMMoabGetAllVertices()`
257 @*/
258 PetscErrorCode DMMoabSetLocalVertices(DM dm, moab::Range *range)
259 {
260   moab::Range tmpvtxs;
261   DM_Moab    *dmmoab = (DM_Moab *)(dm)->data;
262 
263   PetscFunctionBegin;
264   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
265   dmmoab->vlocal->clear();
266   dmmoab->vowned->clear();
267 
268   dmmoab->vlocal->insert(range->begin(), range->end());
269 
270 #ifdef MOAB_HAVE_MPI
271   moab::ErrorCode merr;
272   /* filter based on parallel status */
273   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned);
274   MBERRNM(merr);
275 
276   /* filter all the non-owned and shared entities out of the list */
277   tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
278   merr    = dmmoab->pcomm->filter_pstatus(tmpvtxs, PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost);
279   MBERRNM(merr);
280   tmpvtxs         = moab::subtract(tmpvtxs, *dmmoab->vghost);
281   *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs);
282 #else
283   *dmmoab->vowned = *dmmoab->vlocal;
284 #endif
285 
286   /* compute and cache the sizes of local and ghosted entities */
287   dmmoab->nloc   = dmmoab->vowned->size();
288   dmmoab->nghost = dmmoab->vghost->size();
289 #ifdef MOAB_HAVE_MPI
290   PetscCall(MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
291 #else
292   dmmoab->n       = dmmoab->nloc;
293 #endif
294   PetscFunctionReturn(PETSC_SUCCESS);
295 }
296 
297 /*@C
298   DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab
299 
300   Collective
301 
302   Input Parameter:
303 . dm - The DMMoab object being set
304 
305   Output Parameter:
306 . local - The local vertex entities in this DMMoab = (owned+ghosted)
307 
308   Level: beginner
309 
310 .seealso: `DMMoabGetLocalVertices()`
311 @*/
312 PetscErrorCode DMMoabGetAllVertices(DM dm, moab::Range *local)
313 {
314   PetscFunctionBegin;
315   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
316   if (local) *local = *((DM_Moab *)dm->data)->vlocal;
317   PetscFunctionReturn(PETSC_SUCCESS);
318 }
319 
320 /*@C
321   DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab
322 
323   Collective
324 
325   Input Parameter:
326 . dm - The DMMoab object being set
327 
328   Output Parameters:
329 + owned - The owned vertex entities in this DMMoab
330 - ghost - The ghosted entities (non-owned) stored locally in this partition
331 
332   Level: beginner
333 
334 .seealso: `DMMoabGetAllVertices()`
335 @*/
336 PetscErrorCode DMMoabGetLocalVertices(DM dm, const moab::Range **owned, const moab::Range **ghost)
337 {
338   PetscFunctionBegin;
339   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
340   if (owned) *owned = ((DM_Moab *)dm->data)->vowned;
341   if (ghost) *ghost = ((DM_Moab *)dm->data)->vghost;
342   PetscFunctionReturn(PETSC_SUCCESS);
343 }
344 
345 /*@C
346   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
347 
348   Collective
349 
350   Input Parameter:
351 . dm - The DMMoab object being set
352 
353   Output Parameter:
354 . range - The entities owned locally
355 
356   Level: beginner
357 
358 .seealso: `DMMoabSetLocalElements()`
359 @*/
360 PetscErrorCode DMMoabGetLocalElements(DM dm, const moab::Range **range)
361 {
362   PetscFunctionBegin;
363   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
364   if (range) *range = ((DM_Moab *)dm->data)->elocal;
365   PetscFunctionReturn(PETSC_SUCCESS);
366 }
367 
368 /*@C
369   DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab
370 
371   Collective
372 
373   Input Parameters:
374 + dm    - The DMMoab object being set
375 - range - The entities treated by this DMMoab
376 
377   Level: beginner
378 
379 .seealso: `DMMoabGetLocalElements()`
380 @*/
381 PetscErrorCode DMMoabSetLocalElements(DM dm, moab::Range *range)
382 {
383   DM_Moab *dmmoab = (DM_Moab *)(dm)->data;
384 
385   PetscFunctionBegin;
386   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
387   dmmoab->elocal->clear();
388   dmmoab->eghost->clear();
389   dmmoab->elocal->insert(range->begin(), range->end());
390 #ifdef MOAB_HAVE_MPI
391   moab::ErrorCode merr;
392   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT);
393   MBERRNM(merr);
394   *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal);
395 #endif
396   dmmoab->neleloc   = dmmoab->elocal->size();
397   dmmoab->neleghost = dmmoab->eghost->size();
398 #ifdef MOAB_HAVE_MPI
399   PetscCall(MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
400   PetscCall(PetscInfo(dm, "Created %" PetscInt_FMT " local and %" PetscInt_FMT " global elements.\n", dmmoab->neleloc, dmmoab->nele));
401 #else
402   dmmoab->nele    = dmmoab->neleloc;
403 #endif
404   PetscFunctionReturn(PETSC_SUCCESS);
405 }
406 
407 /*@C
408   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
409 
410   Collective
411 
412   Input Parameters:
413 + dm      - The DMMoab object being set
414 - ltogtag - The MOAB tag used for local to global ids
415 
416   Level: beginner
417 
418 .seealso: `DMMoabGetLocalToGlobalTag()`
419 @*/
420 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm, moab::Tag ltogtag)
421 {
422   PetscFunctionBegin;
423   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
424   ((DM_Moab *)dm->data)->ltog_tag = ltogtag;
425   PetscFunctionReturn(PETSC_SUCCESS);
426 }
427 
428 /*@C
429   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
430 
431   Collective
432 
433   Input Parameter:
434 . dm - The DMMoab object being set
435 
436   Output Parameter:
437 . ltog_tag - The MOAB tag used for local to global ids
438 
439   Level: beginner
440 
441 .seealso: `DMMoabSetLocalToGlobalTag()`
442 @*/
443 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm, moab::Tag *ltog_tag)
444 {
445   PetscFunctionBegin;
446   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
447   *ltog_tag = ((DM_Moab *)dm->data)->ltog_tag;
448   PetscFunctionReturn(PETSC_SUCCESS);
449 }
450 
451 /*@C
452   DMMoabSetBlockSize - Set the block size used with this DMMoab
453 
454   Collective
455 
456   Input Parameters:
457 + dm - The DMMoab object being set
458 - bs - The block size used with this DMMoab
459 
460   Level: beginner
461 
462 .seealso: `DMMoabGetBlockSize()`
463 @*/
464 PetscErrorCode DMMoabSetBlockSize(DM dm, PetscInt bs)
465 {
466   PetscFunctionBegin;
467   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
468   ((DM_Moab *)dm->data)->bs = bs;
469   PetscFunctionReturn(PETSC_SUCCESS);
470 }
471 
472 /*@C
473   DMMoabGetBlockSize - Get the block size used with this DMMoab
474 
475   Collective
476 
477   Input Parameter:
478 . dm - The DMMoab object being set
479 
480   Output Parameter:
481 . bs - The block size used with this DMMoab
482 
483   Level: beginner
484 
485 .seealso: `DMMoabSetBlockSize()`
486 @*/
487 PetscErrorCode DMMoabGetBlockSize(DM dm, PetscInt *bs)
488 {
489   PetscFunctionBegin;
490   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
491   *bs = ((DM_Moab *)dm->data)->bs;
492   PetscFunctionReturn(PETSC_SUCCESS);
493 }
494 
495 /*@C
496   DMMoabGetSize - Get the global vertex size used with this DMMoab
497 
498   Collective on dm
499 
500   Input Parameter:
501 . dm - The DMMoab object being set
502 
503   Output Parameters:
504 + neg - The number of global elements in the DMMoab instance
505 - nvg - The number of global vertices in the DMMoab instance
506 
507   Level: beginner
508 
509 .seealso: `DMMoabGetLocalSize()`
510 @*/
511 PetscErrorCode DMMoabGetSize(DM dm, PetscInt *neg, PetscInt *nvg)
512 {
513   PetscFunctionBegin;
514   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
515   if (neg) *neg = ((DM_Moab *)dm->data)->nele;
516   if (nvg) *nvg = ((DM_Moab *)dm->data)->n;
517   PetscFunctionReturn(PETSC_SUCCESS);
518 }
519 
520 /*@C
521   DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab
522 
523   Collective on dm
524 
525   Input Parameter:
526 . dm - The DMMoab object being set
527 
528   Output Parameters:
529 + nel - The number of owned elements in this processor
530 . neg - The number of ghosted elements in this processor
531 . nvl - The number of owned vertices in this processor
532 - nvg - The number of ghosted vertices in this processor
533 
534   Level: beginner
535 
536 .seealso: `DMMoabGetSize()`
537 @*/
538 PetscErrorCode DMMoabGetLocalSize(DM dm, PetscInt *nel, PetscInt *neg, PetscInt *nvl, PetscInt *nvg)
539 {
540   PetscFunctionBegin;
541   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
542   if (nel) *nel = ((DM_Moab *)dm->data)->neleloc;
543   if (neg) *neg = ((DM_Moab *)dm->data)->neleghost;
544   if (nvl) *nvl = ((DM_Moab *)dm->data)->nloc;
545   if (nvg) *nvg = ((DM_Moab *)dm->data)->nghost;
546   PetscFunctionReturn(PETSC_SUCCESS);
547 }
548 
549 /*@C
550   DMMoabGetOffset - Get the local offset for the global vector
551 
552   Collective
553 
554   Input Parameter:
555 . dm - The DMMoab object being set
556 
557   Output Parameter:
558 . offset - The local offset for the global vector
559 
560   Level: beginner
561 
562 .seealso: `DMMoabGetDimension()`
563 @*/
564 PetscErrorCode DMMoabGetOffset(DM dm, PetscInt *offset)
565 {
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
568   *offset = ((DM_Moab *)dm->data)->vstart;
569   PetscFunctionReturn(PETSC_SUCCESS);
570 }
571 
572 /*@C
573   DMMoabGetDimension - Get the dimension of the DM Mesh
574 
575   Collective
576 
577   Input Parameter:
578 . dm - The DMMoab object
579 
580   Output Parameter:
581 . dim - The dimension of DM
582 
583   Level: beginner
584 
585 .seealso: `DMMoabGetOffset()`
586 @*/
587 PetscErrorCode DMMoabGetDimension(DM dm, PetscInt *dim)
588 {
589   PetscFunctionBegin;
590   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
591   *dim = ((DM_Moab *)dm->data)->dim;
592   PetscFunctionReturn(PETSC_SUCCESS);
593 }
594 
595 /*@C
596   DMMoabGetHierarchyLevel - Get the current level of the mesh hierarchy
597   generated through uniform refinement.
598 
599   Collective on dm
600 
601   Input Parameter:
602 . dm - The DMMoab object being set
603 
604   Output Parameter:
605 . nlevel - The current mesh hierarchy level
606 
607   Level: beginner
608 
609 .seealso: `DMMoabGetMaterialBlock()`
610 @*/
611 PetscErrorCode DMMoabGetHierarchyLevel(DM dm, PetscInt *nlevel)
612 {
613   PetscFunctionBegin;
614   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
615   if (nlevel) *nlevel = ((DM_Moab *)dm->data)->hlevel;
616   PetscFunctionReturn(PETSC_SUCCESS);
617 }
618 
619 /*@C
620   DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh
621 
622   Collective
623 
624   Input Parameters:
625 + dm      - The DMMoab object
626 - ehandle - The element entity handle
627 
628   Output Parameter:
629 . mat - The material ID for the current entity
630 
631   Level: beginner
632 
633 .seealso: `DMMoabGetHierarchyLevel()`
634 @*/
635 PetscErrorCode DMMoabGetMaterialBlock(DM dm, const moab::EntityHandle ehandle, PetscInt *mat)
636 {
637   DM_Moab *dmmoab;
638 
639   PetscFunctionBegin;
640   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
641   if (*mat) {
642     dmmoab = (DM_Moab *)(dm)->data;
643     *mat   = dmmoab->materials[dmmoab->elocal->index(ehandle)];
644   }
645   PetscFunctionReturn(PETSC_SUCCESS);
646 }
647 
648 /*@C
649   DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities
650 
651   Collective
652 
653   Input Parameters:
654 + dm    - The DMMoab object
655 . nconn - Number of entities whose coordinates are needed
656 - conn  - The vertex entity handles
657 
658   Output Parameter:
659 . vpos - The coordinates of the requested vertex entities
660 
661   Level: beginner
662 
663 .seealso: `DMMoabGetVertexConnectivity()`
664 @*/
665 PetscErrorCode DMMoabGetVertexCoordinates(DM dm, PetscInt nconn, const moab::EntityHandle *conn, PetscReal *vpos)
666 {
667   DM_Moab        *dmmoab;
668   moab::ErrorCode merr;
669 
670   PetscFunctionBegin;
671   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
672   PetscAssertPointer(conn, 3);
673   PetscAssertPointer(vpos, 4);
674   dmmoab = (DM_Moab *)(dm)->data;
675 
676   /* Get connectivity information in MOAB canonical ordering */
677   if (dmmoab->hlevel) {
678     merr = dmmoab->hierarchy->get_coordinates(const_cast<moab::EntityHandle *>(conn), nconn, dmmoab->hlevel, vpos);
679     MBERRNM(merr);
680   } else {
681     merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);
682     MBERRNM(merr);
683   }
684   PetscFunctionReturn(PETSC_SUCCESS);
685 }
686 
687 /*@C
688   DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity
689 
690   Collective
691 
692   Input Parameters:
693 + dm      - The DMMoab object
694 - vhandle - Vertex entity handle
695 
696   Output Parameters:
697 + nconn - Number of entities whose coordinates are needed
698 - conn  - The vertex entity handles
699 
700   Level: beginner
701 
702 .seealso: `DMMoabGetVertexCoordinates()`, `DMMoabRestoreVertexConnectivity()`
703 @*/
704 PetscErrorCode DMMoabGetVertexConnectivity(DM dm, moab::EntityHandle vhandle, PetscInt *nconn, moab::EntityHandle **conn)
705 {
706   DM_Moab                        *dmmoab;
707   std::vector<moab::EntityHandle> adj_entities, connect;
708   moab::ErrorCode                 merr;
709 
710   PetscFunctionBegin;
711   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
712   PetscAssertPointer(conn, 4);
713   dmmoab = (DM_Moab *)(dm)->data;
714 
715   /* Get connectivity information in MOAB canonical ordering */
716   merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION);
717   MBERRNM(merr);
718   merr = dmmoab->mbiface->get_connectivity(&adj_entities[0], adj_entities.size(), connect);
719   MBERRNM(merr);
720 
721   if (conn) {
722     PetscCall(PetscMalloc(sizeof(moab::EntityHandle) * connect.size(), conn));
723     PetscCall(PetscArraycpy(*conn, &connect[0], connect.size()));
724   }
725   if (nconn) *nconn = connect.size();
726   PetscFunctionReturn(PETSC_SUCCESS);
727 }
728 
729 /*@C
730   DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity
731 
732   Collective
733 
734   Input Parameters:
735 + dm      - The DMMoab object
736 . ehandle - Vertex entity handle
737 . nconn   - Number of entities whose coordinates are needed
738 - conn    - The vertex entity handles
739 
740   Level: beginner
741 
742 .seealso: `DMMoabGetVertexCoordinates()`, `DMMoabGetVertexConnectivity()`
743 @*/
744 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt *nconn, moab::EntityHandle **conn)
745 {
746   PetscFunctionBegin;
747   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
748   PetscAssertPointer(conn, 4);
749 
750   if (conn) PetscCall(PetscFree(*conn));
751   if (nconn) *nconn = 0;
752   PetscFunctionReturn(PETSC_SUCCESS);
753 }
754 
755 /*@C
756   DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity
757 
758   Collective
759 
760   Input Parameters:
761 + dm      - The DMMoab object
762 - ehandle - Vertex entity handle
763 
764   Output Parameters:
765 + nconn - Number of entities whose coordinates are needed
766 - conn  - The vertex entity handles
767 
768   Level: beginner
769 
770 .seealso: `DMMoabGetVertexCoordinates()`, `DMMoabGetVertexConnectivity()`, `DMMoabRestoreVertexConnectivity()`
771 @*/
772 PetscErrorCode DMMoabGetElementConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt *nconn, const moab::EntityHandle **conn)
773 {
774   DM_Moab                        *dmmoab;
775   const moab::EntityHandle       *connect;
776   std::vector<moab::EntityHandle> vconn;
777   moab::ErrorCode                 merr;
778   PetscInt                        nnodes;
779 
780   PetscFunctionBegin;
781   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
782   PetscAssertPointer(conn, 4);
783   dmmoab = (DM_Moab *)(dm)->data;
784 
785   /* Get connectivity information in MOAB canonical ordering */
786   merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);
787   MBERRNM(merr);
788   if (conn) *conn = connect;
789   if (nconn) *nconn = nnodes;
790   PetscFunctionReturn(PETSC_SUCCESS);
791 }
792 
793 /*@C
794   DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element)
795 
796   Collective
797 
798   Input Parameters:
799 + dm  - The DMMoab object
800 - ent - Entity handle
801 
802   Output Parameter:
803 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise
804 
805   Level: beginner
806 
807 .seealso: `DMMoabCheckBoundaryVertices()`
808 @*/
809 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm, const moab::EntityHandle ent, PetscBool *ent_on_boundary)
810 {
811   moab::EntityType etype;
812   DM_Moab         *dmmoab;
813   PetscInt         edim;
814 
815   PetscFunctionBegin;
816   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
817   PetscAssertPointer(ent_on_boundary, 3);
818   dmmoab = (DM_Moab *)(dm)->data;
819 
820   /* get the entity type and handle accordingly */
821   etype = dmmoab->mbiface->type_from_handle(ent);
822   PetscCheck(etype < moab::MBPOLYHEDRON, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %" PetscInt_FMT, etype);
823 
824   /* get the entity dimension */
825   edim = dmmoab->mbiface->dimension_from_handle(ent);
826 
827   *ent_on_boundary = PETSC_FALSE;
828   if (etype == moab::MBVERTEX && edim == 0) {
829     *ent_on_boundary = ((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE : PETSC_FALSE);
830   } else {
831     if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */
832       if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE;
833     } else { /* next check the lower-dimensional faces */
834       if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE;
835     }
836   }
837   PetscFunctionReturn(PETSC_SUCCESS);
838 }
839 
840 /*@C
841   DMMoabCheckBoundaryVertices - Check whether a given entity is on the boundary (vertex, edge, face, element)
842 
843   Input Parameters:
844 + dm    - The DMMoab object
845 . nconn - Number of handles
846 - cnt   - Array of entity handles
847 
848   Output Parameter:
849 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise
850 
851   Level: beginner
852 
853 .seealso: `DMMoabIsEntityOnBoundary()`
854 @*/
855 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm, PetscInt nconn, const moab::EntityHandle *cnt, PetscBool *isbdvtx)
856 {
857   DM_Moab *dmmoab;
858   PetscInt i;
859 
860   PetscFunctionBegin;
861   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
862   PetscAssertPointer(cnt, 3);
863   PetscAssertPointer(isbdvtx, 4);
864   dmmoab = (DM_Moab *)(dm)->data;
865 
866   for (i = 0; i < nconn; ++i) isbdvtx[i] = (dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE : PETSC_FALSE);
867   PetscFunctionReturn(PETSC_SUCCESS);
868 }
869 
870 /*@C
871   DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary
872 
873   Input Parameter:
874 . dm - The DMMoab object
875 
876   Output Parameters:
877 + bdvtx   - Boundary vertices
878 . bdelems - Boundary elements
879 - bdfaces - Boundary faces
880 
881   Level: beginner
882 
883 .seealso: `DMMoabCheckBoundaryVertices()`, `DMMoabIsEntityOnBoundary()`
884 @*/
885 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm, const moab::Range **bdvtx, const moab::Range **bdelems, const moab::Range **bdfaces)
886 {
887   DM_Moab *dmmoab;
888 
889   PetscFunctionBegin;
890   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
891   dmmoab = (DM_Moab *)(dm)->data;
892 
893   if (bdvtx) *bdvtx = dmmoab->bndyvtx;
894   if (bdfaces) *bdfaces = dmmoab->bndyfaces;
895   if (bdelems) *bdfaces = dmmoab->bndyelems;
896   PetscFunctionReturn(PETSC_SUCCESS);
897 }
898 
899 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm)
900 {
901   PetscInt        i;
902   moab::ErrorCode merr;
903   DM_Moab        *dmmoab = (DM_Moab *)dm->data;
904 
905   PetscFunctionBegin;
906   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
907 
908   dmmoab->refct--;
909   if (!dmmoab->refct) {
910     delete dmmoab->vlocal;
911     delete dmmoab->vowned;
912     delete dmmoab->vghost;
913     delete dmmoab->elocal;
914     delete dmmoab->eghost;
915     delete dmmoab->bndyvtx;
916     delete dmmoab->bndyfaces;
917     delete dmmoab->bndyelems;
918 
919     PetscCall(PetscFree(dmmoab->gsindices));
920     PetscCall(PetscFree2(dmmoab->gidmap, dmmoab->lidmap));
921     PetscCall(PetscFree(dmmoab->dfill));
922     PetscCall(PetscFree(dmmoab->ofill));
923     PetscCall(PetscFree(dmmoab->materials));
924     if (dmmoab->fieldNames) {
925       for (i = 0; i < dmmoab->numFields; i++) PetscCall(PetscFree(dmmoab->fieldNames[i]));
926       PetscCall(PetscFree(dmmoab->fieldNames));
927     }
928 
929     if (dmmoab->nhlevels) {
930       PetscCall(PetscFree(dmmoab->hsets));
931       dmmoab->nhlevels = 0;
932       if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy;
933       dmmoab->hierarchy = NULL;
934     }
935 
936     if (dmmoab->icreatedinstance) {
937       delete dmmoab->pcomm;
938       merr = dmmoab->mbiface->delete_mesh();
939       MBERRNM(merr);
940       delete dmmoab->mbiface;
941     }
942     dmmoab->mbiface = NULL;
943 #ifdef MOAB_HAVE_MPI
944     dmmoab->pcomm = NULL;
945 #endif
946     PetscCall(VecScatterDestroy(&dmmoab->ltog_sendrecv));
947     PetscCall(ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map));
948     PetscCall(PetscFree(dm->data));
949   }
950   PetscFunctionReturn(PETSC_SUCCESS);
951 }
952 
953 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(DM dm, PetscOptionItems *PetscOptionsObject)
954 {
955   DM_Moab *dmmoab = (DM_Moab *)dm->data;
956 
957   PetscFunctionBegin;
958   PetscOptionsHeadBegin(PetscOptionsObject, "DMMoab Options");
959   PetscCall(PetscOptionsBoundedInt("-dm_moab_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "DMView", dmmoab->rw_dbglevel, &dmmoab->rw_dbglevel, NULL, 0));
960   PetscCall(PetscOptionsBool("-dm_moab_partiton_by_rank", "Use partition by rank when reading MOAB meshes from file", "DMView", dmmoab->partition_by_rank, &dmmoab->partition_by_rank, NULL));
961   /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */
962   PetscCall(PetscOptionsString("-dm_moab_read_opts", "Extra options to enable MOAB reader to load DM from file", "DMView", dmmoab->extra_read_options, dmmoab->extra_read_options, sizeof(dmmoab->extra_read_options), NULL));
963   PetscCall(PetscOptionsString("-dm_moab_write_opts", "Extra options to enable MOAB writer to serialize DM to file", "DMView", dmmoab->extra_write_options, dmmoab->extra_write_options, sizeof(dmmoab->extra_write_options), NULL));
964   PetscCall(PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum *)&dmmoab->read_mode, NULL));
965   PetscCall(PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum *)&dmmoab->write_mode, NULL));
966   PetscOptionsHeadEnd();
967   PetscFunctionReturn(PETSC_SUCCESS);
968 }
969 
970 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm)
971 {
972   moab::ErrorCode       merr;
973   Vec                   local, global;
974   IS                    from, to;
975   moab::Range::iterator iter;
976   PetscInt              i, j, f, bs, vent, totsize, *lgmap;
977   DM_Moab              *dmmoab = (DM_Moab *)dm->data;
978   moab::Range           adjs;
979 
980   PetscFunctionBegin;
981   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
982   /* Get the local and shared vertices and cache it */
983   PetscCheck(dmmoab->mbiface != NULL, PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp.");
984 #ifdef MOAB_HAVE_MPI
985   PetscCheck(dmmoab->pcomm != NULL, PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp.");
986 #endif
987 
988   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
989   if (dmmoab->vlocal->empty()) {
990     //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
991     merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false);
992     MBERRNM(merr);
993 
994 #ifdef MOAB_HAVE_MPI
995     /* filter based on parallel status */
996     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned);
997     MBERRNM(merr);
998 
999     /* filter all the non-owned and shared entities out of the list */
1000     // *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
1001     adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
1002     merr = dmmoab->pcomm->filter_pstatus(adjs, PSTATUS_GHOST | PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost);
1003     MBERRNM(merr);
1004     adjs            = moab::subtract(adjs, *dmmoab->vghost);
1005     *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs);
1006 #else
1007     *dmmoab->vowned = *dmmoab->vlocal;
1008 #endif
1009 
1010     /* compute and cache the sizes of local and ghosted entities */
1011     dmmoab->nloc   = dmmoab->vowned->size();
1012     dmmoab->nghost = dmmoab->vghost->size();
1013 
1014 #ifdef MOAB_HAVE_MPI
1015     PetscCall(MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
1016     PetscCall(PetscInfo(NULL, "Filset ID: %lu, Vertices: local - %zu, owned - %" PetscInt_FMT ", ghosted - %" PetscInt_FMT ".\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost));
1017 #else
1018     dmmoab->n       = dmmoab->nloc;
1019 #endif
1020   }
1021 
1022   {
1023     /* get the information about the local elements in the mesh */
1024     dmmoab->eghost->clear();
1025 
1026     /* first decipher the leading dimension */
1027     for (i = 3; i > 0; i--) {
1028       dmmoab->elocal->clear();
1029       merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false);
1030       MBERRNM(merr);
1031 
1032       /* store the current mesh dimension */
1033       if (dmmoab->elocal->size()) {
1034         dmmoab->dim = i;
1035         break;
1036       }
1037     }
1038 
1039     PetscCall(DMSetDimension(dm, dmmoab->dim));
1040 
1041 #ifdef MOAB_HAVE_MPI
1042     /* filter the ghosted and owned element list */
1043     *dmmoab->eghost = *dmmoab->elocal;
1044     merr            = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1045     MBERRNM(merr);
1046     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
1047 #endif
1048 
1049     dmmoab->neleloc   = dmmoab->elocal->size();
1050     dmmoab->neleghost = dmmoab->eghost->size();
1051 
1052 #ifdef MOAB_HAVE_MPI
1053     PetscCall(MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
1054     PetscCall(PetscInfo(NULL, "%d-dim elements: owned - %" PetscInt_FMT ", ghosted - %" PetscInt_FMT ".\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost));
1055 #else
1056     dmmoab->nele    = dmmoab->neleloc;
1057 #endif
1058   }
1059 
1060   bs = dmmoab->bs;
1061   if (!dmmoab->ltog_tag) {
1062     /* Get the global ID tag. The global ID tag is applied to each
1063        vertex. It acts as an global identifier which MOAB uses to
1064        assemble the individual pieces of the mesh */
1065     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);
1066     MBERRNM(merr);
1067   }
1068 
1069   totsize = dmmoab->vlocal->size();
1070   PetscCheck(totsize == dmmoab->nloc + dmmoab->nghost, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mismatch between local and owned+ghost vertices. %" PetscInt_FMT " != %" PetscInt_FMT ".", totsize, dmmoab->nloc + dmmoab->nghost);
1071   PetscCall(PetscCalloc1(totsize, &dmmoab->gsindices));
1072   {
1073     /* first get the local indices */
1074     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vowned, &dmmoab->gsindices[0]);
1075     MBERRNM(merr);
1076     if (dmmoab->nghost) { /* next get the ghosted indices */
1077       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vghost, &dmmoab->gsindices[dmmoab->nloc]);
1078       MBERRNM(merr);
1079     }
1080 
1081     /* find out the local and global minima of GLOBAL_ID */
1082     dmmoab->lminmax[0] = dmmoab->lminmax[1] = dmmoab->gsindices[0];
1083     for (i = 0; i < totsize; ++i) {
1084       if (dmmoab->lminmax[0] > dmmoab->gsindices[i]) dmmoab->lminmax[0] = dmmoab->gsindices[i];
1085       if (dmmoab->lminmax[1] < dmmoab->gsindices[i]) dmmoab->lminmax[1] = dmmoab->gsindices[i];
1086     }
1087 
1088     PetscCall(MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm));
1089     PetscCall(MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm));
1090 
1091     /* set the GID map */
1092     for (i = 0; i < totsize; ++i) { dmmoab->gsindices[i] -= dmmoab->gminmax[0]; /* zero based index needed for IS */ }
1093     dmmoab->lminmax[0] -= dmmoab->gminmax[0];
1094     dmmoab->lminmax[1] -= dmmoab->gminmax[0];
1095 
1096     PetscCall(PetscInfo(NULL, "GLOBAL_ID: Local [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "], Global [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "]\n", dmmoab->lminmax[0], dmmoab->lminmax[1], dmmoab->gminmax[0], dmmoab->gminmax[1]));
1097   }
1098   PetscCheck(dmmoab->bs == dmmoab->numFields || dmmoab->bs == 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between block size and number of component fields. %" PetscInt_FMT " != 1 OR %" PetscInt_FMT " != %" PetscInt_FMT ".", dmmoab->bs, dmmoab->bs,
1099              dmmoab->numFields);
1100 
1101   {
1102     dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front());
1103     dmmoab->seqend   = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back());
1104     PetscCall(PetscInfo(NULL, "SEQUENCE: Local [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "]\n", dmmoab->seqstart, dmmoab->seqend));
1105 
1106     PetscCall(PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap));
1107     PetscCall(PetscMalloc1(totsize * dmmoab->numFields, &lgmap));
1108 
1109     i = j = 0;
1110     /* set the owned vertex data first */
1111     for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) {
1112       vent                 = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart;
1113       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1114       dmmoab->lidmap[vent] = i;
1115       for (f = 0; f < dmmoab->numFields; f++, j++) lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1116     }
1117     /* next arrange all the ghosted data information */
1118     for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) {
1119       vent                 = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart;
1120       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1121       dmmoab->lidmap[vent] = i;
1122       for (f = 0; f < dmmoab->numFields; f++, j++) lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1123     }
1124 
1125     /* We need to create the Global to Local Vector Scatter Contexts
1126        1) First create a local and global vector
1127        2) Create a local and global IS
1128        3) Create VecScatter and LtoGMapping objects
1129        4) Cleanup the IS and Vec objects
1130     */
1131     PetscCall(DMCreateGlobalVector(dm, &global));
1132     PetscCall(DMCreateLocalVector(dm, &local));
1133 
1134     PetscCall(VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend));
1135 
1136     /* global to local must retrieve ghost points */
1137     PetscCall(ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from));
1138     PetscCall(ISSetBlockSize(from, bs));
1139 
1140     PetscCall(ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to));
1141     PetscCall(ISSetBlockSize(to, bs));
1142 
1143     if (!dmmoab->ltog_map) {
1144       /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */
1145       PetscCall(ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap, PETSC_COPY_VALUES, &dmmoab->ltog_map));
1146     }
1147 
1148     /* now create the scatter object from local to global vector */
1149     PetscCall(VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv));
1150 
1151     /* clean up IS, Vec */
1152     PetscCall(PetscFree(lgmap));
1153     PetscCall(ISDestroy(&from));
1154     PetscCall(ISDestroy(&to));
1155     PetscCall(VecDestroy(&local));
1156     PetscCall(VecDestroy(&global));
1157   }
1158 
1159   dmmoab->bndyvtx   = new moab::Range();
1160   dmmoab->bndyfaces = new moab::Range();
1161   dmmoab->bndyelems = new moab::Range();
1162   /* skin the boundary and store nodes */
1163   if (!dmmoab->hlevel) {
1164     /* get the skin vertices of boundary faces for the current partition and then filter
1165        the local, boundary faces, vertices and elements alone via PSTATUS flags;
1166        this should not give us any ghosted boundary, but if user needs such a functionality
1167        it would be easy to add it based on the find_skin query below */
1168     moab::Skinner skinner(dmmoab->mbiface);
1169 
1170     /* get the entities on the skin - only the faces */
1171     merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces, NULL, true, true, false);
1172     MBERRNM(merr); // 'false' param indicates we want faces back, not vertices
1173 
1174 #ifdef MOAB_HAVE_MPI
1175     /* filter all the non-owned and shared entities out of the list */
1176     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1177     MBERRNM(merr);
1178     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT);
1179     MBERRNM(merr);
1180 #endif
1181 
1182     /* get all the nodes via connectivity and the parent elements via adjacency information */
1183     merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);
1184     MBERRNM(merr);
1185     merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);
1186     MBERRNM(merr);
1187   } else {
1188     /* Let us query the hierarchy manager and get the results directly for this level */
1189     for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) {
1190       moab::EntityHandle elemHandle = *iter;
1191       if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) {
1192         dmmoab->bndyelems->insert(elemHandle);
1193         /* For this boundary element, query the vertices and add them to the list */
1194         std::vector<moab::EntityHandle> connect;
1195         merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect);
1196         MBERRNM(merr);
1197         for (unsigned iv = 0; iv < connect.size(); ++iv)
1198           if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv])) dmmoab->bndyvtx->insert(connect[iv]);
1199         /* Next, let us query the boundary faces and add them also to the list */
1200         std::vector<moab::EntityHandle> faces;
1201         merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim - 1, faces);
1202         MBERRNM(merr);
1203         for (unsigned ifa = 0; ifa < faces.size(); ++ifa)
1204           if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa])) dmmoab->bndyfaces->insert(faces[ifa]);
1205       }
1206     }
1207 #ifdef MOAB_HAVE_MPI
1208     /* filter all the non-owned and shared entities out of the list */
1209     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1210     MBERRNM(merr);
1211     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1212     MBERRNM(merr);
1213     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1214     MBERRNM(merr);
1215 #endif
1216   }
1217   PetscCall(PetscInfo(NULL, "Found %zu boundary vertices, %zu boundary faces and %zu boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()));
1218 
1219   /* Get the material sets and populate the data for all locally owned elements */
1220   {
1221     PetscCall(PetscCalloc1(dmmoab->elocal->size(), &dmmoab->materials));
1222     /* Get the count of entities of particular type from dmmoab->elocal
1223        -- Then, for each non-zero type, loop through and query the fileset to get the material tag data */
1224     moab::Range msets;
1225     merr = dmmoab->mbiface->get_entities_by_type_and_tag(dmmoab->fileset, moab::MBENTITYSET, &dmmoab->material_tag, NULL, 1, msets, moab::Interface::UNION);
1226     MBERRNM(merr);
1227     if (msets.size() == 0) PetscCall(PetscInfo(NULL, "No material sets found in the fileset.\n"));
1228 
1229     for (unsigned i = 0; i < msets.size(); ++i) {
1230       moab::Range msetelems;
1231       merr = dmmoab->mbiface->get_entities_by_dimension(msets[i], dmmoab->dim, msetelems, true);
1232       MBERRNM(merr);
1233 #ifdef MOAB_HAVE_MPI
1234       /* filter all the non-owned and shared entities out of the list */
1235       merr = dmmoab->pcomm->filter_pstatus(msetelems, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1236       MBERRNM(merr);
1237 #endif
1238 
1239       int                partID;
1240       moab::EntityHandle mset = msets[i];
1241       merr                    = dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &mset, 1, &partID);
1242       MBERRNM(merr);
1243 
1244       for (unsigned j = 0; j < msetelems.size(); ++j) dmmoab->materials[dmmoab->elocal->index(msetelems[j])] = partID;
1245     }
1246   }
1247 
1248   PetscFunctionReturn(PETSC_SUCCESS);
1249 }
1250 
1251 /*@C
1252   DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM.
1253 
1254   Collective
1255 
1256   Input Parameters:
1257 + dm     - The `DM` object
1258 . coords - The connectivity of the element
1259 - nverts - The number of vertices that form the element
1260 
1261   Output Parameter:
1262 . overts - The list of vertices that were created (can be NULL)
1263 
1264   Level: beginner
1265 
1266 .seealso: `DMMoabCreateSubmesh()`, `DMMoabCreateElement()`
1267 @*/
1268 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal *coords, PetscInt nverts, moab::Range *overts)
1269 {
1270   moab::ErrorCode merr;
1271   DM_Moab        *dmmoab;
1272   moab::Range     verts;
1273 
1274   PetscFunctionBegin;
1275   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1276   PetscAssertPointer(coords, 2);
1277 
1278   dmmoab = (DM_Moab *)dm->data;
1279 
1280   /* Insert new points */
1281   merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts);
1282   MBERRNM(merr);
1283   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts);
1284   MBERRNM(merr);
1285 
1286   if (overts) *overts = verts;
1287   PetscFunctionReturn(PETSC_SUCCESS);
1288 }
1289 
1290 /*@C
1291   DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM.
1292 
1293   Collective
1294 
1295   Input Parameters:
1296 + dm     - The DM object
1297 . type   - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra)
1298 . conn   - The connectivity of the element
1299 - nverts - The number of vertices that form the element
1300 
1301   Output Parameter:
1302 . oelem - The handle to the element created and added to the DM object
1303 
1304   Level: beginner
1305 
1306 .seealso: `DMMoabCreateSubmesh()`, `DMMoabCreateVertices()`
1307 @*/
1308 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle *conn, PetscInt nverts, moab::EntityHandle *oelem)
1309 {
1310   moab::ErrorCode    merr;
1311   DM_Moab           *dmmoab;
1312   moab::EntityHandle elem;
1313 
1314   PetscFunctionBegin;
1315   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1316   PetscAssertPointer(conn, 3);
1317 
1318   dmmoab = (DM_Moab *)dm->data;
1319 
1320   /* Insert new element */
1321   merr = dmmoab->mbiface->create_element(type, conn, nverts, elem);
1322   MBERRNM(merr);
1323   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1);
1324   MBERRNM(merr);
1325 
1326   if (oelem) *oelem = elem;
1327   PetscFunctionReturn(PETSC_SUCCESS);
1328 }
1329 
1330 /*@C
1331   DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent
1332   in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to
1333   create a DM object on a refined level.
1334 
1335   Collective
1336 
1337   Input Parameters:
1338 . dm - The DM object
1339 
1340   Output Parameter:
1341 . newdm - The sub DM object with updated set information
1342 
1343   Level: advanced
1344 
1345 .seealso: `DMCreate()`, `DMMoabCreateVertices()`, `DMMoabCreateElement()`
1346 @*/
1347 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm)
1348 {
1349   DM_Moab        *dmmoab;
1350   DM_Moab        *ndmmoab;
1351   moab::ErrorCode merr;
1352 
1353   PetscFunctionBegin;
1354   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1355 
1356   dmmoab = (DM_Moab *)dm->data;
1357 
1358   /* Create the basic DMMoab object and keep the default parameters created by DM impls */
1359   PetscCall(DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, NULL, newdm));
1360 
1361   /* get all the necessary handles from the private DM object */
1362   ndmmoab = (DM_Moab *)(*newdm)->data;
1363 
1364   /* set the sub-mesh's parent DM reference */
1365   ndmmoab->parent = &dm;
1366 
1367   /* create a file set to associate all entities in current mesh */
1368   merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset);
1369   MBERR("Creating file set failed", merr);
1370 
1371   /* create a meshset and then add old fileset as child */
1372   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal);
1373   MBERR("Adding child vertices to parent failed", merr);
1374   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal);
1375   MBERR("Adding child elements to parent failed", merr);
1376 
1377   /* preserve the field association between the parent and sub-mesh objects */
1378   PetscCall(DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames));
1379   PetscFunctionReturn(PETSC_SUCCESS);
1380 }
1381 
1382 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer)
1383 {
1384   DM_Moab    *dmmoab = (DM_Moab *)(dm)->data;
1385   const char *name;
1386   MPI_Comm    comm;
1387   PetscMPIInt size;
1388 
1389   PetscFunctionBegin;
1390   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
1391   PetscCallMPI(MPI_Comm_size(comm, &size));
1392   PetscCall(PetscObjectGetName((PetscObject)dm, &name));
1393   PetscCall(PetscViewerASCIIPushTab(viewer));
1394   if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "%s in %" PetscInt_FMT " dimensions:\n", name, dmmoab->dim));
1395   else PetscCall(PetscViewerASCIIPrintf(viewer, "Mesh in %" PetscInt_FMT " dimensions:\n", dmmoab->dim));
1396   /* print details about the global mesh */
1397   {
1398     PetscCall(PetscViewerASCIIPushTab(viewer));
1399     PetscCall(PetscViewerASCIIPrintf(viewer, "Sizes: cells=%" PetscInt_FMT ", vertices=%" PetscInt_FMT ", blocks=%" PetscInt_FMT "\n", dmmoab->nele, dmmoab->n, dmmoab->bs));
1400     /* print boundary data */
1401     PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary trace:\n"));
1402     {
1403       PetscCall(PetscViewerASCIIPushTab(viewer));
1404       PetscCall(PetscViewerASCIIPrintf(viewer, "cells=%zu, faces=%zu, vertices=%zu\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size()));
1405       PetscCall(PetscViewerASCIIPopTab(viewer));
1406     }
1407     /* print field data */
1408     PetscCall(PetscViewerASCIIPrintf(viewer, "Fields: %" PetscInt_FMT " components\n", dmmoab->numFields));
1409     {
1410       PetscCall(PetscViewerASCIIPushTab(viewer));
1411       for (int i = 0; i < dmmoab->numFields; ++i) PetscCall(PetscViewerASCIIPrintf(viewer, "[%" PetscInt_FMT "] - %s\n", i, dmmoab->fieldNames[i]));
1412       PetscCall(PetscViewerASCIIPopTab(viewer));
1413     }
1414     PetscCall(PetscViewerASCIIPopTab(viewer));
1415   }
1416   PetscCall(PetscViewerASCIIPopTab(viewer));
1417   PetscCall(PetscViewerFlush(viewer));
1418   PetscFunctionReturn(PETSC_SUCCESS);
1419 }
1420 
1421 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v)
1422 {
1423   PetscFunctionReturn(PETSC_SUCCESS);
1424 }
1425 
1426 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v)
1427 {
1428   PetscFunctionReturn(PETSC_SUCCESS);
1429 }
1430 
1431 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer)
1432 {
1433   PetscBool iascii, ishdf5, isvtk;
1434 
1435   PetscFunctionBegin;
1436   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1437   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1438   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
1439   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk));
1440   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1441   if (iascii) {
1442     PetscCall(DMMoabView_Ascii(dm, viewer));
1443   } else if (ishdf5) {
1444 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5)
1445     PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ));
1446     PetscCall(DMMoabView_HDF5(dm, viewer));
1447     PetscCall(PetscViewerPopFormat(viewer));
1448 #else
1449     SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1450 #endif
1451   } else if (isvtk) {
1452     PetscCall(DMMoabView_VTK(dm, viewer));
1453   }
1454   PetscFunctionReturn(PETSC_SUCCESS);
1455 }
1456 
1457 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm)
1458 {
1459   PetscFunctionBegin;
1460   dm->ops->view                     = DMView_Moab;
1461   dm->ops->load                     = NULL /* DMLoad_Moab */;
1462   dm->ops->setfromoptions           = DMSetFromOptions_Moab;
1463   dm->ops->clone                    = DMClone_Moab;
1464   dm->ops->setup                    = DMSetUp_Moab;
1465   dm->ops->createlocalsection       = NULL;
1466   dm->ops->createdefaultconstraints = NULL;
1467   dm->ops->createglobalvector       = DMCreateGlobalVector_Moab;
1468   dm->ops->createlocalvector        = DMCreateLocalVector_Moab;
1469   dm->ops->getlocaltoglobalmapping  = NULL;
1470   dm->ops->createfieldis            = NULL;
1471   dm->ops->createcoordinatedm       = NULL /* DMCreateCoordinateDM_Moab */;
1472   dm->ops->getcoloring              = NULL;
1473   dm->ops->creatematrix             = DMCreateMatrix_Moab;
1474   dm->ops->createinterpolation      = DMCreateInterpolation_Moab;
1475   dm->ops->createinjection          = NULL /* DMCreateInjection_Moab */;
1476   dm->ops->refine                   = DMRefine_Moab;
1477   dm->ops->coarsen                  = DMCoarsen_Moab;
1478   dm->ops->refinehierarchy          = DMRefineHierarchy_Moab;
1479   dm->ops->coarsenhierarchy         = DMCoarsenHierarchy_Moab;
1480   dm->ops->globaltolocalbegin       = DMGlobalToLocalBegin_Moab;
1481   dm->ops->globaltolocalend         = DMGlobalToLocalEnd_Moab;
1482   dm->ops->localtoglobalbegin       = DMLocalToGlobalBegin_Moab;
1483   dm->ops->localtoglobalend         = DMLocalToGlobalEnd_Moab;
1484   dm->ops->destroy                  = DMDestroy_Moab;
1485   dm->ops->createsubdm              = NULL /* DMCreateSubDM_Moab */;
1486   dm->ops->getdimpoints             = NULL /* DMGetDimPoints_Moab */;
1487   dm->ops->locatepoints             = NULL /* DMLocatePoints_Moab */;
1488   PetscFunctionReturn(PETSC_SUCCESS);
1489 }
1490 
1491 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm)
1492 {
1493   PetscFunctionBegin;
1494   /* get all the necessary handles from the private DM object */
1495   (*newdm)->data = (DM_Moab *)dm->data;
1496   ((DM_Moab *)dm->data)->refct++;
1497 
1498   PetscCall(PetscObjectChangeTypeName((PetscObject)*newdm, DMMOAB));
1499   PetscCall(DMInitialize_Moab(*newdm));
1500   PetscFunctionReturn(PETSC_SUCCESS);
1501 }
1502 
1503 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
1504 {
1505   PetscFunctionBegin;
1506   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1507   PetscCall(PetscNew((DM_Moab **)&dm->data));
1508 
1509   ((DM_Moab *)dm->data)->bs            = 1;
1510   ((DM_Moab *)dm->data)->numFields     = 1;
1511   ((DM_Moab *)dm->data)->n             = 0;
1512   ((DM_Moab *)dm->data)->nloc          = 0;
1513   ((DM_Moab *)dm->data)->nghost        = 0;
1514   ((DM_Moab *)dm->data)->nele          = 0;
1515   ((DM_Moab *)dm->data)->neleloc       = 0;
1516   ((DM_Moab *)dm->data)->neleghost     = 0;
1517   ((DM_Moab *)dm->data)->ltog_map      = NULL;
1518   ((DM_Moab *)dm->data)->ltog_sendrecv = NULL;
1519 
1520   ((DM_Moab *)dm->data)->refct  = 1;
1521   ((DM_Moab *)dm->data)->parent = NULL;
1522   ((DM_Moab *)dm->data)->vlocal = new moab::Range();
1523   ((DM_Moab *)dm->data)->vowned = new moab::Range();
1524   ((DM_Moab *)dm->data)->vghost = new moab::Range();
1525   ((DM_Moab *)dm->data)->elocal = new moab::Range();
1526   ((DM_Moab *)dm->data)->eghost = new moab::Range();
1527 
1528   PetscCall(DMInitialize_Moab(dm));
1529   PetscFunctionReturn(PETSC_SUCCESS);
1530 }
1531