xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 864c62dfd577300df05c8a4e4992489f187e8c79)
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 
665   PetscFunctionBegin;
666   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
667   if (*mat) {
668     dmmoab = (DM_Moab*)(dm)->data;
669     *mat = dmmoab->materials[dmmoab->elocal->index(ehandle)];
670   }
671   PetscFunctionReturn(0);
672 }
673 
674 
675 /*@
676   DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities
677 
678   Collective on MPI_Comm
679 
680   Input Parameter:
681 . dm - The DMMoab object
682 . nconn - Number of entities whose coordinates are needed
683 . conn - The vertex entity handles
684 
685   Output Parameter:
686 . vpos - The coordinates of the requested vertex entities
687 
688   Level: beginner
689 
690 .seealso: DMMoabGetVertexConnectivity()
691 @*/
692 PetscErrorCode DMMoabGetVertexCoordinates(DM dm, PetscInt nconn, const moab::EntityHandle *conn, PetscReal *vpos)
693 {
694   DM_Moab         *dmmoab;
695   moab::ErrorCode merr;
696 
697   PetscFunctionBegin;
698   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
699   PetscValidPointer(conn, 3);
700   PetscValidPointer(vpos, 4);
701   dmmoab = (DM_Moab*)(dm)->data;
702 
703   /* Get connectivity information in MOAB canonical ordering */
704   if (dmmoab->hlevel) {
705     merr = dmmoab->hierarchy->get_coordinates(const_cast<moab::EntityHandle*>(conn), nconn, dmmoab->hlevel, vpos);MBERRNM(merr);
706   }
707   else {
708     merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr);
709   }
710   PetscFunctionReturn(0);
711 }
712 
713 
714 /*@
715   DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity
716 
717   Collective on MPI_Comm
718 
719   Input Parameter:
720 . dm - The DMMoab object
721 . vhandle - Vertex entity handle
722 
723   Output Parameter:
724 . nconn - Number of entities whose coordinates are needed
725 . conn - The vertex entity handles
726 
727   Level: beginner
728 
729 .seealso: DMMoabGetVertexCoordinates(), DMMoabRestoreVertexConnectivity()
730 @*/
731 PetscErrorCode DMMoabGetVertexConnectivity(DM dm, moab::EntityHandle vhandle, PetscInt* nconn, moab::EntityHandle **conn)
732 {
733   DM_Moab        *dmmoab;
734   std::vector<moab::EntityHandle> adj_entities, connect;
735   PetscErrorCode  ierr;
736   moab::ErrorCode merr;
737 
738   PetscFunctionBegin;
739   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
740   PetscValidPointer(conn, 4);
741   dmmoab = (DM_Moab*)(dm)->data;
742 
743   /* Get connectivity information in MOAB canonical ordering */
744   merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION); MBERRNM(merr);
745   merr = dmmoab->mbiface->get_connectivity(&adj_entities[0], adj_entities.size(), connect); MBERRNM(merr);
746 
747   if (conn) {
748     ierr = PetscMalloc(sizeof(moab::EntityHandle) * connect.size(), conn);CHKERRQ(ierr);
749     ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle) * connect.size());CHKERRQ(ierr);
750   }
751   if (nconn) *nconn = connect.size();
752   PetscFunctionReturn(0);
753 }
754 
755 
756 /*@
757   DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity
758 
759   Collective on MPI_Comm
760 
761   Input Parameter:
762 . dm - The DMMoab object
763 . vhandle - Vertex entity handle
764 . nconn - Number of entities whose coordinates are needed
765 . conn - The vertex entity handles
766 
767   Level: beginner
768 
769 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity()
770 @*/
771 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt* nconn, moab::EntityHandle **conn)
772 {
773   PetscErrorCode  ierr;
774 
775   PetscFunctionBegin;
776   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
777   PetscValidPointer(conn, 4);
778 
779   if (conn) {
780     ierr = PetscFree(*conn);CHKERRQ(ierr);
781   }
782   if (nconn) *nconn = 0;
783   PetscFunctionReturn(0);
784 }
785 
786 
787 /*@
788   DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity
789 
790   Collective on MPI_Comm
791 
792   Input Parameter:
793 . dm - The DMMoab object
794 . ehandle - Vertex entity handle
795 
796   Output Parameter:
797 . nconn - Number of entities whose coordinates are needed
798 . conn - The vertex entity handles
799 
800   Level: beginner
801 
802 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity(), DMMoabRestoreVertexConnectivity()
803 @*/
804 PetscErrorCode DMMoabGetElementConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt* nconn, const moab::EntityHandle **conn)
805 {
806   DM_Moab        *dmmoab;
807   const moab::EntityHandle *connect;
808   std::vector<moab::EntityHandle> vconn;
809   moab::ErrorCode merr;
810   PetscInt nnodes;
811 
812   PetscFunctionBegin;
813   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
814   PetscValidPointer(conn, 4);
815   dmmoab = (DM_Moab*)(dm)->data;
816 
817   /* Get connectivity information in MOAB canonical ordering */
818   merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes); MBERRNM(merr);
819   if (conn) *conn = connect;
820   if (nconn) *nconn = nnodes;
821   PetscFunctionReturn(0);
822 }
823 
824 
825 /*@
826   DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element)
827 
828   Collective on MPI_Comm
829 
830   Input Parameter:
831 . dm - The DMMoab object
832 . ent - Entity handle
833 
834   Output Parameter:
835 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise
836 
837   Level: beginner
838 
839 .seealso: DMMoabCheckBoundaryVertices()
840 @*/
841 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm, const moab::EntityHandle ent, PetscBool* ent_on_boundary)
842 {
843   moab::EntityType etype;
844   DM_Moab         *dmmoab;
845   PetscInt         edim;
846 
847   PetscFunctionBegin;
848   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
849   PetscValidPointer(ent_on_boundary, 3);
850   dmmoab = (DM_Moab*)(dm)->data;
851 
852   /* get the entity type and handle accordingly */
853   etype = dmmoab->mbiface->type_from_handle(ent);
854   if (etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n", etype);
855 
856   /* get the entity dimension */
857   edim = dmmoab->mbiface->dimension_from_handle(ent);
858 
859   *ent_on_boundary = PETSC_FALSE;
860   if (etype == moab::MBVERTEX && edim == 0) {
861     *ent_on_boundary = ((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE : PETSC_FALSE);
862   }
863   else {
864     if (edim == dmmoab->dim) {  /* check the higher-dimensional elements first */
865       if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE;
866     }
867     else {                      /* next check the lower-dimensional faces */
868       if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE;
869     }
870   }
871   PetscFunctionReturn(0);
872 }
873 
874 
875 /*@
876   DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element)
877 
878   Input Parameter:
879 . dm - The DMMoab object
880 . nconn - Number of handles
881 . cnt - Array of entity handles
882 
883   Output Parameter:
884 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise
885 
886   Level: beginner
887 
888 .seealso: DMMoabIsEntityOnBoundary()
889 @*/
890 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm, PetscInt nconn, const moab::EntityHandle *cnt, PetscBool* isbdvtx)
891 {
892   DM_Moab        *dmmoab;
893   PetscInt       i;
894 
895   PetscFunctionBegin;
896   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
897   PetscValidPointer(cnt, 3);
898   PetscValidPointer(isbdvtx, 4);
899   dmmoab = (DM_Moab*)(dm)->data;
900 
901   for (i = 0; i < nconn; ++i) {
902     isbdvtx[i] = (dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE : PETSC_FALSE);
903   }
904   PetscFunctionReturn(0);
905 }
906 
907 
908 /*@
909   DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary
910 
911   Input Parameter:
912 . dm - The DMMoab object
913 
914   Output Parameter:
915 . bdvtx - Boundary vertices
916 . bdelems - Boundary elements
917 . bdfaces - Boundary faces
918 
919   Level: beginner
920 
921 .seealso: DMMoabCheckBoundaryVertices(), DMMoabIsEntityOnBoundary()
922 @*/
923 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm, const moab::Range **bdvtx, const moab::Range** bdelems, const moab::Range** bdfaces)
924 {
925   DM_Moab        *dmmoab;
926 
927   PetscFunctionBegin;
928   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
929   dmmoab = (DM_Moab*)(dm)->data;
930 
931   if (bdvtx)  *bdvtx = dmmoab->bndyvtx;
932   if (bdfaces)  *bdfaces = dmmoab->bndyfaces;
933   if (bdelems)  *bdfaces = dmmoab->bndyelems;
934   PetscFunctionReturn(0);
935 }
936 
937 
938 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm)
939 {
940   PetscErrorCode  ierr;
941   PetscInt        i;
942   moab::ErrorCode merr;
943   DM_Moab        *dmmoab = (DM_Moab*)dm->data;
944 
945   PetscFunctionBegin;
946   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
947 
948   dmmoab->refct--;
949   if (!dmmoab->refct) {
950     delete dmmoab->vlocal;
951     delete dmmoab->vowned;
952     delete dmmoab->vghost;
953     delete dmmoab->elocal;
954     delete dmmoab->eghost;
955     delete dmmoab->bndyvtx;
956     delete dmmoab->bndyfaces;
957     delete dmmoab->bndyelems;
958 
959     ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr);
960     ierr = PetscFree2(dmmoab->gidmap, dmmoab->lidmap);CHKERRQ(ierr);
961     ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr);
962     ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr);
963     ierr = PetscFree(dmmoab->materials);CHKERRQ(ierr);
964     if (dmmoab->fieldNames) {
965       for (i = 0; i < dmmoab->numFields; i++) {
966         ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr);
967       }
968       ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr);
969     }
970 
971     if (dmmoab->nhlevels) {
972       ierr = PetscFree(dmmoab->hsets);CHKERRQ(ierr);
973       dmmoab->nhlevels = 0;
974       if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy;
975       dmmoab->hierarchy = NULL;
976     }
977 
978     if (dmmoab->icreatedinstance) {
979       delete dmmoab->pcomm;
980       merr = dmmoab->mbiface->delete_mesh(); MBERRNM(merr);
981       delete dmmoab->mbiface;
982     }
983     dmmoab->mbiface = NULL;
984 #ifdef MOAB_HAVE_MPI
985     dmmoab->pcomm = NULL;
986 #endif
987     ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
988     ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr);
989     ierr = PetscFree(dm->data);CHKERRQ(ierr);
990   }
991   PetscFunctionReturn(0);
992 }
993 
994 
995 #undef __FUNCT__
996 #define __FUNCT__ "DMSetFromOptions_Moab"
997 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject, DM dm)
998 {
999   PetscErrorCode ierr;
1000   DM_Moab        *dmmoab = (DM_Moab*)dm->data;
1001 
1002   PetscFunctionBegin;
1003   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1004   ierr = PetscOptionsHead(PetscOptionsObject, "DMMoab Options");CHKERRQ(ierr);
1005   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);
1006   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);
1007   /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */
1008   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);
1009   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);
1010   ierr  = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr);
1011   ierr  = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr);
1012   PetscFunctionReturn(0);
1013 }
1014 
1015 
1016 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm)
1017 {
1018   PetscErrorCode          ierr;
1019   moab::ErrorCode         merr;
1020   Vec                     local, global;
1021   IS                      from, to;
1022   moab::Range::iterator   iter;
1023   PetscInt                i, j, f, bs, vent, totsize, *lgmap;
1024   DM_Moab                *dmmoab = (DM_Moab*)dm->data;
1025   moab::Range             adjs;
1026 
1027   PetscFunctionBegin;
1028   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1029   /* Get the local and shared vertices and cache it */
1030   if (dmmoab->mbiface == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp.");
1031 #ifdef MOAB_HAVE_MPI
1032   if (dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp.");
1033 #endif
1034 
1035   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
1036   if (dmmoab->vlocal->empty())
1037   {
1038     //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
1039     merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false); MBERRNM(merr);
1040 
1041 #ifdef MOAB_HAVE_MPI
1042     /* filter based on parallel status */
1043     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned); MBERRNM(merr);
1044 
1045     /* filter all the non-owned and shared entities out of the list */
1046     // *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
1047     adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
1048     merr = dmmoab->pcomm->filter_pstatus(adjs, PSTATUS_GHOST | PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost); MBERRNM(merr);
1049     adjs = moab::subtract(adjs, *dmmoab->vghost);
1050     *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs);
1051 #else
1052     *dmmoab->vowned = *dmmoab->vlocal;
1053 #endif
1054 
1055     /* compute and cache the sizes of local and ghosted entities */
1056     dmmoab->nloc = dmmoab->vowned->size();
1057     dmmoab->nghost = dmmoab->vghost->size();
1058 
1059 #ifdef MOAB_HAVE_MPI
1060     ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1061     PetscInfo4(NULL, "Filset ID: %u, Vertices: local - %D, owned - %D, ghosted - %D.\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost);
1062 #else
1063     dmmoab->n = dmmoab->nloc;
1064 #endif
1065   }
1066 
1067   {
1068     /* get the information about the local elements in the mesh */
1069     dmmoab->eghost->clear();
1070 
1071     /* first decipher the leading dimension */
1072     for (i = 3; i > 0; i--) {
1073       dmmoab->elocal->clear();
1074       merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false); MBERRNM(merr);
1075 
1076       /* store the current mesh dimension */
1077       if (dmmoab->elocal->size()) {
1078         dmmoab->dim = i;
1079         break;
1080       }
1081     }
1082 
1083     ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr);
1084 
1085 #ifdef MOAB_HAVE_MPI
1086     /* filter the ghosted and owned element list */
1087     *dmmoab->eghost = *dmmoab->elocal;
1088     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1089     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
1090 #endif
1091 
1092     dmmoab->neleloc = dmmoab->elocal->size();
1093     dmmoab->neleghost = dmmoab->eghost->size();
1094 
1095 #ifdef MOAB_HAVE_MPI
1096     ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1097     PetscInfo3(NULL, "%d-dim elements: owned - %D, ghosted - %D.\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost);
1098 #else
1099     dmmoab->nele = dmmoab->neleloc;
1100 #endif
1101   }
1102 
1103   bs = dmmoab->bs;
1104   if (!dmmoab->ltog_tag) {
1105     /* Get the global ID tag. The global ID tag is applied to each
1106        vertex. It acts as an global identifier which MOAB uses to
1107        assemble the individual pieces of the mesh */
1108     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag); MBERRNM(merr);
1109   }
1110 
1111   totsize = dmmoab->vlocal->size();
1112   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);
1113   ierr = PetscCalloc1(totsize, &dmmoab->gsindices);CHKERRQ(ierr);
1114   {
1115     /* first get the local indices */
1116     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vowned, &dmmoab->gsindices[0]); MBERRNM(merr);
1117     if (dmmoab->nghost) {  /* next get the ghosted indices */
1118       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vghost, &dmmoab->gsindices[dmmoab->nloc]); MBERRNM(merr);
1119     }
1120 
1121     /* find out the local and global minima of GLOBAL_ID */
1122     dmmoab->lminmax[0] = dmmoab->lminmax[1] = dmmoab->gsindices[0];
1123     for (i = 0; i < totsize; ++i) {
1124       if (dmmoab->lminmax[0] > dmmoab->gsindices[i]) dmmoab->lminmax[0] = dmmoab->gsindices[i];
1125       if (dmmoab->lminmax[1] < dmmoab->gsindices[i]) dmmoab->lminmax[1] = dmmoab->gsindices[i];
1126     }
1127 
1128     ierr = MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1129     ierr = MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1130 
1131     /* set the GID map */
1132     for (i = 0; i < totsize; ++i) {
1133       dmmoab->gsindices[i] -= dmmoab->gminmax[0]; /* zero based index needed for IS */
1134 
1135     }
1136     dmmoab->lminmax[0] -= dmmoab->gminmax[0];
1137     dmmoab->lminmax[1] -= dmmoab->gminmax[0];
1138 
1139     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]);
1140   }
1141   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);
1142 
1143   {
1144     dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front());
1145     dmmoab->seqend = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back());
1146     PetscInfo2(NULL, "SEQUENCE: Local [min, max] - [%D, %D]\n", dmmoab->seqstart, dmmoab->seqend);
1147 
1148     ierr = PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap);CHKERRQ(ierr);
1149     ierr = PetscMalloc1(totsize * dmmoab->numFields, &lgmap);CHKERRQ(ierr);
1150 
1151     i = j = 0;
1152     /* set the owned vertex data first */
1153     for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) {
1154       vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart;
1155       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1156       dmmoab->lidmap[vent] = i;
1157       for (f = 0; f < dmmoab->numFields; f++, j++) {
1158         lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1159       }
1160     }
1161     /* next arrange all the ghosted data information */
1162     for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) {
1163       vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart;
1164       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1165       dmmoab->lidmap[vent] = i;
1166       for (f = 0; f < dmmoab->numFields; f++, j++) {
1167         lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1168       }
1169     }
1170 
1171     /* We need to create the Global to Local Vector Scatter Contexts
1172        1) First create a local and global vector
1173        2) Create a local and global IS
1174        3) Create VecScatter and LtoGMapping objects
1175        4) Cleanup the IS and Vec objects
1176     */
1177     ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr);
1178     ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr);
1179 
1180     ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr);
1181 
1182     /* global to local must retrieve ghost points */
1183     ierr = ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from);CHKERRQ(ierr);
1184     ierr = ISSetBlockSize(from, bs);CHKERRQ(ierr);
1185 
1186     ierr = ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to);CHKERRQ(ierr);
1187     ierr = ISSetBlockSize(to, bs);CHKERRQ(ierr);
1188 
1189     if (!dmmoab->ltog_map) {
1190       /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */
1191       ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap,
1192                                           PETSC_COPY_VALUES, &dmmoab->ltog_map);CHKERRQ(ierr);
1193     }
1194 
1195     /* now create the scatter object from local to global vector */
1196     ierr = VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv);CHKERRQ(ierr);
1197 
1198     /* clean up IS, Vec */
1199     ierr = PetscFree(lgmap);CHKERRQ(ierr);
1200     ierr = ISDestroy(&from);CHKERRQ(ierr);
1201     ierr = ISDestroy(&to);CHKERRQ(ierr);
1202     ierr = VecDestroy(&local);CHKERRQ(ierr);
1203     ierr = VecDestroy(&global);CHKERRQ(ierr);
1204   }
1205 
1206   dmmoab->bndyvtx = new moab::Range();
1207   dmmoab->bndyfaces = new moab::Range();
1208   dmmoab->bndyelems = new moab::Range();
1209   /* skin the boundary and store nodes */
1210   if (!dmmoab->hlevel) {
1211     /* get the skin vertices of boundary faces for the current partition and then filter
1212        the local, boundary faces, vertices and elements alone via PSTATUS flags;
1213        this should not give us any ghosted boundary, but if user needs such a functionality
1214        it would be easy to add it based on the find_skin query below */
1215     moab::Skinner skinner(dmmoab->mbiface);
1216 
1217     /* get the entities on the skin - only the faces */
1218     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
1219 
1220 #ifdef MOAB_HAVE_MPI
1221     /* filter all the non-owned and shared entities out of the list */
1222     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1223     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); MBERRNM(merr);
1224 #endif
1225 
1226     /* get all the nodes via connectivity and the parent elements via adjacency information */
1227     merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false); MBERRNM(ierr);
1228     merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION); MBERRNM(ierr);
1229   }
1230   else {
1231     /* Let us query the hierarchy manager and get the results directly for this level */
1232     for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) {
1233       moab::EntityHandle elemHandle = *iter;
1234       if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) {
1235         dmmoab->bndyelems->insert(elemHandle);
1236         /* For this boundary element, query the vertices and add them to the list */
1237         std::vector<moab::EntityHandle> connect;
1238         merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect); MBERRNM(ierr);
1239         for (unsigned iv=0; iv < connect.size(); ++iv)
1240           if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv]))
1241             dmmoab->bndyvtx->insert(connect[iv]);
1242         /* Next, let us query the boundary faces and add them also to the list */
1243         std::vector<moab::EntityHandle> faces;
1244         merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim-1, faces); MBERRNM(ierr);
1245         for (unsigned ifa=0; ifa < faces.size(); ++ifa)
1246           if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa]))
1247             dmmoab->bndyfaces->insert(faces[ifa]);
1248       }
1249     }
1250 #ifdef MOAB_HAVE_MPI
1251     /* filter all the non-owned and shared entities out of the list */
1252     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx,   PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1253     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1254     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1255 #endif
1256 
1257   }
1258   PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size());
1259 
1260   /* Get the material sets and populate the data for all locally owned elements */
1261   {
1262     ierr = PetscCalloc1(dmmoab->elocal->size(), &dmmoab->materials);CHKERRQ(ierr);
1263     /* Get the count of entities of particular type from dmmoab->elocal
1264        -- Then, for each non-zero type, loop through and query the fileset to get the material tag data */
1265     moab::Range msets;
1266     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);
1267     if (msets.size() == 0) {
1268       PetscInfo(NULL, "No material sets found in the fileset.");
1269     }
1270 
1271     for (unsigned i=0; i < msets.size(); ++i) {
1272       moab::Range msetelems;
1273       merr = dmmoab->mbiface->get_entities_by_dimension(msets[i], dmmoab->dim, msetelems, true);MB_CHK_ERR(merr);
1274 #ifdef MOAB_HAVE_MPI
1275       /* filter all the non-owned and shared entities out of the list */
1276       merr = dmmoab->pcomm->filter_pstatus(msetelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1277 #endif
1278 
1279       int partID;
1280       moab::EntityHandle mset=msets[i];
1281       merr = dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &mset, 1, &partID);MB_CHK_ERR(merr);
1282 
1283       for (unsigned j=0; j < msetelems.size(); ++j)
1284         dmmoab->materials[dmmoab->elocal->index(msetelems[j])]=partID;
1285     }
1286   }
1287 
1288   PetscFunctionReturn(0);
1289 }
1290 
1291 
1292 #undef __FUNCT__
1293 #define __FUNCT__ "DMMoabCreateVertices"
1294 /*@
1295   DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM.
1296 
1297   Collective on MPI_Comm
1298 
1299   Input Parameters:
1300 + dm - The DM object
1301 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra)
1302 . conn - The connectivity of the element
1303 . nverts - The number of vertices that form the element
1304 
1305   Output Parameter:
1306 . overts  - The list of vertices that were created (can be NULL)
1307 
1308   Level: beginner
1309 
1310 .keywords: DM, create vertices
1311 
1312 .seealso: DMMoabCreateSubmesh(), DMMoabCreateElement()
1313 @*/
1314 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal* coords, PetscInt nverts, moab::Range* overts)
1315 {
1316   moab::ErrorCode     merr;
1317   DM_Moab            *dmmoab;
1318   moab::Range         verts;
1319 
1320   PetscFunctionBegin;
1321   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1322   PetscValidPointer(coords, 2);
1323 
1324   dmmoab = (DM_Moab*) dm->data;
1325 
1326   /* Insert new points */
1327   merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts); MBERRNM(merr);
1328   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts); MBERRNM(merr);
1329 
1330   if (overts) *overts = verts;
1331   PetscFunctionReturn(0);
1332 }
1333 
1334 
1335 #undef __FUNCT__
1336 #define __FUNCT__ "DMMoabCreateElement"
1337 /*@
1338   DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM.
1339 
1340   Collective on MPI_Comm
1341 
1342   Input Parameters:
1343 + dm - The DM object
1344 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra)
1345 . conn - The connectivity of the element
1346 . nverts - The number of vertices that form the element
1347 
1348   Output Parameter:
1349 . oelem  - The handle to the element created and added to the DM object
1350 
1351   Level: beginner
1352 
1353 .keywords: DM, create element
1354 
1355 .seealso: DMMoabCreateSubmesh(), DMMoabCreateVertices()
1356 @*/
1357 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle* conn, PetscInt nverts, moab::EntityHandle* oelem)
1358 {
1359   moab::ErrorCode     merr;
1360   DM_Moab            *dmmoab;
1361   moab::EntityHandle  elem;
1362 
1363   PetscFunctionBegin;
1364   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1365   PetscValidPointer(conn, 3);
1366 
1367   dmmoab = (DM_Moab*) dm->data;
1368 
1369   /* Insert new element */
1370   merr = dmmoab->mbiface->create_element(type, conn, nverts, elem); MBERRNM(merr);
1371   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1); MBERRNM(merr);
1372 
1373   if (oelem) *oelem = elem;
1374   PetscFunctionReturn(0);
1375 }
1376 
1377 
1378 #undef __FUNCT__
1379 #define __FUNCT__ "DMMoabCreateSubmesh"
1380 /*@
1381   DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent
1382   in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to
1383   create a DM object on a refined level.
1384 
1385   Collective on MPI_Comm
1386 
1387   Input Parameters:
1388 + dm - The DM object
1389 
1390   Output Parameter:
1391 . newdm  - The sub DM object with updated set information
1392 
1393   Level: advanced
1394 
1395 .keywords: DM, sub-DM
1396 
1397 .seealso: DMCreate(), DMMoabCreateVertices(), DMMoabCreateElement()
1398 @*/
1399 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm)
1400 {
1401   DM_Moab            *dmmoab;
1402   DM_Moab            *ndmmoab;
1403   moab::ErrorCode    merr;
1404   PetscErrorCode     ierr;
1405 
1406   PetscFunctionBegin;
1407   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1408 
1409   dmmoab = (DM_Moab*) dm->data;
1410 
1411   /* Create the basic DMMoab object and keep the default parameters created by DM impls */
1412   ierr = DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, PETSC_NULL, newdm);CHKERRQ(ierr);
1413 
1414   /* get all the necessary handles from the private DM object */
1415   ndmmoab = (DM_Moab*) (*newdm)->data;
1416 
1417   /* set the sub-mesh's parent DM reference */
1418   ndmmoab->parent = &dm;
1419 
1420   /* create a file set to associate all entities in current mesh */
1421   merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset); MBERR("Creating file set failed", merr);
1422 
1423   /* create a meshset and then add old fileset as child */
1424   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal); MBERR("Adding child vertices to parent failed", merr);
1425   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal); MBERR("Adding child elements to parent failed", merr);
1426 
1427   /* preserve the field association between the parent and sub-mesh objects */
1428   ierr = DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames);CHKERRQ(ierr);
1429   PetscFunctionReturn(0);
1430 }
1431 
1432 
1433 #undef __FUNCT__
1434 #define __FUNCT__ "DMMoabView_Ascii"
1435 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer)
1436 {
1437   DM_Moab          *dmmoab = (DM_Moab*)(dm)->data;
1438   const char       *name;
1439   MPI_Comm          comm;
1440   PetscMPIInt       size;
1441   PetscErrorCode    ierr;
1442 
1443   PetscFunctionBegin;
1444   ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr);
1445   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
1446   ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr);
1447   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1448   if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dmmoab->dim);CHKERRQ(ierr);}
1449   else      {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dmmoab->dim);CHKERRQ(ierr);}
1450   /* print details about the global mesh */
1451   {
1452     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1453     ierr = PetscViewerASCIIPrintf(viewer, "Sizes: cells=%D, vertices=%D, blocks=%D\n", dmmoab->nele, dmmoab->n, dmmoab->bs);CHKERRQ(ierr);
1454     /* print boundary data */
1455     ierr = PetscViewerASCIIPrintf(viewer, "Boundary trace:\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr);
1456     {
1457       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1458       ierr = PetscViewerASCIIPrintf(viewer, "cells=%D, faces=%D, vertices=%D\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr);
1459       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1460     }
1461     /* print field data */
1462     ierr = PetscViewerASCIIPrintf(viewer, "Fields: %D components\n", dmmoab->numFields);CHKERRQ(ierr);
1463     {
1464       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1465       for (int i = 0; i < dmmoab->numFields; ++i) {
1466         ierr = PetscViewerASCIIPrintf(viewer, "[%D] - %s\n", i, dmmoab->fieldNames[i]);CHKERRQ(ierr);
1467       }
1468       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1469     }
1470     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1471   }
1472   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1473   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1474   PetscFunctionReturn(0);
1475 }
1476 
1477 #undef __FUNCT__
1478 #define __FUNCT__ "DMMoabView_VTK"
1479 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v)
1480 {
1481   PetscFunctionReturn(0);
1482 }
1483 
1484 #undef __FUNCT__
1485 #define __FUNCT__ "DMMoabView_HDF5"
1486 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v)
1487 {
1488   PetscFunctionReturn(0);
1489 }
1490 
1491 #undef __FUNCT__
1492 #define __FUNCT__ "DMView_Moab"
1493 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer)
1494 {
1495   PetscBool      iascii, ishdf5, isvtk;
1496   PetscErrorCode ierr;
1497 
1498   PetscFunctionBegin;
1499   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1500   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1501   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
1502   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
1503   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1504   if (iascii) {
1505     ierr = DMMoabView_Ascii(dm, viewer);CHKERRQ(ierr);
1506   } else if (ishdf5) {
1507 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5)
1508     ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr);
1509     ierr = DMMoabView_HDF5(dm, viewer);CHKERRQ(ierr);
1510     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
1511 #else
1512     SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1513 #endif
1514   }
1515   else if (isvtk) {
1516     ierr = DMMoabView_VTK(dm, viewer);CHKERRQ(ierr);
1517   }
1518   PetscFunctionReturn(0);
1519 }
1520 
1521 
1522 #undef __FUNCT__
1523 #define __FUNCT__ "DMInitialize_Moab"
1524 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm)
1525 {
1526   PetscFunctionBegin;
1527   dm->ops->view                            = DMView_Moab;
1528   dm->ops->load                            = NULL /*DMLoad_Moab*/;
1529   dm->ops->setfromoptions                  = DMSetFromOptions_Moab;
1530   dm->ops->clone                           = DMClone_Moab;
1531   dm->ops->setup                           = DMSetUp_Moab;
1532   dm->ops->createdefaultsection            = NULL;
1533   dm->ops->createdefaultconstraints        = NULL;
1534   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
1535   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
1536   dm->ops->getlocaltoglobalmapping         = NULL;
1537   dm->ops->createfieldis                   = NULL;
1538   dm->ops->createcoordinatedm              = NULL /*DMCreateCoordinateDM_Moab*/;
1539   dm->ops->getcoloring                     = NULL;
1540   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
1541   dm->ops->createinterpolation             = DMCreateInterpolation_Moab;
1542   dm->ops->getaggregates                   = NULL;
1543   dm->ops->getinjection                    = NULL /*DMCreateInjection_Moab*/;
1544   dm->ops->refine                          = DMRefine_Moab;
1545   dm->ops->coarsen                         = DMCoarsen_Moab;
1546   dm->ops->refinehierarchy                 = DMRefineHierarchy_Moab;
1547   dm->ops->coarsenhierarchy                = DMCoarsenHierarchy_Moab;
1548   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
1549   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
1550   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
1551   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
1552   dm->ops->destroy                         = DMDestroy_Moab;
1553   dm->ops->createsubdm                     = NULL /*DMCreateSubDM_Moab*/;
1554   dm->ops->getdimpoints                    = NULL /*DMGetDimPoints_Moab*/;
1555   dm->ops->locatepoints                    = NULL /*DMLocatePoints_Moab*/;
1556   PetscFunctionReturn(0);
1557 }
1558 
1559 
1560 #undef __FUNCT__
1561 #define __FUNCT__ "DMClone_Moab"
1562 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm)
1563 {
1564   PetscErrorCode     ierr;
1565 
1566   PetscFunctionBegin;
1567   ierr = PetscObjectChangeTypeName((PetscObject) * newdm, DMMOAB);CHKERRQ(ierr);
1568 
1569   /* get all the necessary handles from the private DM object */
1570   (*newdm)->data = (DM_Moab*) dm->data;
1571   ((DM_Moab*)dm->data)->refct++;
1572 
1573   ierr = DMInitialize_Moab(*newdm);CHKERRQ(ierr);
1574   PetscFunctionReturn(0);
1575 }
1576 
1577 
1578 #undef __FUNCT__
1579 #define __FUNCT__ "DMCreate_Moab"
1580 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
1581 {
1582   PetscErrorCode ierr;
1583 
1584   PetscFunctionBegin;
1585   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1586   ierr = PetscNewLog(dm, (DM_Moab**)&dm->data);CHKERRQ(ierr);
1587 
1588   ((DM_Moab*)dm->data)->bs = 1;
1589   ((DM_Moab*)dm->data)->numFields = 1;
1590   ((DM_Moab*)dm->data)->n = 0;
1591   ((DM_Moab*)dm->data)->nloc = 0;
1592   ((DM_Moab*)dm->data)->nghost = 0;
1593   ((DM_Moab*)dm->data)->nele = 0;
1594   ((DM_Moab*)dm->data)->neleloc = 0;
1595   ((DM_Moab*)dm->data)->neleghost = 0;
1596   ((DM_Moab*)dm->data)->ltog_map = NULL;
1597   ((DM_Moab*)dm->data)->ltog_sendrecv = NULL;
1598 
1599   ((DM_Moab*)dm->data)->refct = 1;
1600   ((DM_Moab*)dm->data)->parent = NULL;
1601   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
1602   ((DM_Moab*)dm->data)->vowned = new moab::Range();
1603   ((DM_Moab*)dm->data)->vghost = new moab::Range();
1604   ((DM_Moab*)dm->data)->elocal = new moab::Range();
1605   ((DM_Moab*)dm->data)->eghost = new moab::Range();
1606 
1607   ierr = DMInitialize_Moab(dm);CHKERRQ(ierr);
1608   PetscFunctionReturn(0);
1609 }
1610 
1611