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