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