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