xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 9c36898578a91ec77675797fbfe6e623f4be5691)
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       PetscInfo2(NULL, "GLOBAL_ID %d: %D\n", i, dmmoab->gsindices[i]);
1136 
1137     }
1138     dmmoab->lminmax[0] -= dmmoab->gminmax[0];
1139     dmmoab->lminmax[1] -= dmmoab->gminmax[0];
1140 
1141     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]);
1142   }
1143   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);
1144 
1145   {
1146     dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front());
1147     dmmoab->seqend = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back());
1148     PetscInfo2(NULL, "SEQUENCE: Local [min, max] - [%D, %D]\n", dmmoab->seqstart, dmmoab->seqend);
1149 
1150     ierr = PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap);CHKERRQ(ierr);
1151     ierr = PetscMalloc1(totsize * dmmoab->numFields, &lgmap);CHKERRQ(ierr);
1152 
1153     i = j = 0;
1154     /* set the owned vertex data first */
1155     for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) {
1156       vent = (PetscInt)(*iter) - dmmoab->seqstart;
1157       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1158       dmmoab->lidmap[vent] = i;
1159       for (f = 0; f < dmmoab->numFields; f++, j++) {
1160         lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1161       }
1162     }
1163     /* next arrange all the ghosted data information */
1164     for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) {
1165       vent = (PetscInt)(*iter) - dmmoab->seqstart;
1166       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1167       dmmoab->lidmap[vent] = i;
1168       for (f = 0; f < dmmoab->numFields; f++, j++) {
1169         lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1170       }
1171     }
1172 
1173     /* We need to create the Global to Local Vector Scatter Contexts
1174        1) First create a local and global vector
1175        2) Create a local and global IS
1176        3) Create VecScatter and LtoGMapping objects
1177        4) Cleanup the IS and Vec objects
1178     */
1179     ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr);
1180     ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr);
1181 
1182     ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr);
1183 
1184     /* global to local must retrieve ghost points */
1185     ierr = ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from);CHKERRQ(ierr);
1186     ierr = ISSetBlockSize(from, bs);CHKERRQ(ierr);
1187 
1188     ierr = ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to);CHKERRQ(ierr);
1189     ierr = ISSetBlockSize(to, bs);CHKERRQ(ierr);
1190 
1191     if (!dmmoab->ltog_map) {
1192       /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */
1193       ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap,
1194                                           PETSC_COPY_VALUES, &dmmoab->ltog_map);CHKERRQ(ierr);
1195     }
1196 
1197     /* now create the scatter object from local to global vector */
1198     ierr = VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv);CHKERRQ(ierr);
1199 
1200     /* clean up IS, Vec */
1201     ierr = PetscFree(lgmap);CHKERRQ(ierr);
1202     ierr = ISDestroy(&from);CHKERRQ(ierr);
1203     ierr = ISDestroy(&to);CHKERRQ(ierr);
1204     ierr = VecDestroy(&local);CHKERRQ(ierr);
1205     ierr = VecDestroy(&global);CHKERRQ(ierr);
1206   }
1207 
1208   dmmoab->bndyvtx = new moab::Range();
1209   dmmoab->bndyfaces = new moab::Range();
1210   dmmoab->bndyelems = new moab::Range();
1211   /* skin the boundary and store nodes */
1212   if (!dmmoab->hlevel) {
1213     /* get the skin vertices of boundary faces for the current partition and then filter
1214        the local, boundary faces, vertices and elements alone via PSTATUS flags;
1215        this should not give us any ghosted boundary, but if user needs such a functionality
1216        it would be easy to add it based on the find_skin query below */
1217     moab::Skinner skinner(dmmoab->mbiface);
1218 
1219     /* get the entities on the skin - only the faces */
1220     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
1221 
1222 #ifdef MOAB_HAVE_MPI
1223     /* filter all the non-owned and shared entities out of the list */
1224     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1225     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); MBERRNM(merr);
1226 #endif
1227 
1228     /* get all the nodes via connectivity and the parent elements via adjacency information */
1229     merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false); MBERRNM(ierr);
1230     merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION); MBERRNM(ierr);
1231   }
1232   else {
1233     /* Let us query the hierarchy manager and get the results directly for this level */
1234     for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) {
1235       moab::EntityHandle elemHandle = *iter;
1236       if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) {
1237         dmmoab->bndyelems->insert(elemHandle);
1238         /* For this boundary element, query the vertices and add them to the list */
1239         std::vector<moab::EntityHandle> connect;
1240         merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect); MBERRNM(ierr);
1241         for (unsigned iv=0; iv < connect.size(); ++iv)
1242           if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv]))
1243             dmmoab->bndyvtx->insert(connect[iv]);
1244         /* Next, let us query the boundary faces and add them also to the list */
1245         std::vector<moab::EntityHandle> faces;
1246         merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim-1, faces); MBERRNM(ierr);
1247         for (unsigned ifa=0; ifa < faces.size(); ++ifa)
1248           if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa]))
1249             dmmoab->bndyfaces->insert(faces[ifa]);
1250       }
1251     }
1252 #ifdef MOAB_HAVE_MPI
1253     /* filter all the non-owned and shared entities out of the list */
1254     // merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1255     // merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); MBERRNM(merr);
1256     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx,   PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1257     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1258     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr);
1259 #endif
1260 
1261   }
1262   PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size());
1263   PetscFunctionReturn(0);
1264 }
1265 
1266 
1267 #undef __FUNCT__
1268 #define __FUNCT__ "DMMoabCreateVertices"
1269 /*@
1270   DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM.
1271 
1272   Collective on MPI_Comm
1273 
1274   Input Parameters:
1275 + dm - The DM object
1276 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra)
1277 . conn - The connectivity of the element
1278 . nverts - The number of vertices that form the element
1279 
1280   Output Parameter:
1281 . overts  - The list of vertices that were created (can be NULL)
1282 
1283   Level: beginner
1284 
1285 .keywords: DM, create vertices
1286 
1287 .seealso: DMMoabCreateSubmesh(), DMMoabCreateElement()
1288 @*/
1289 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal* coords, PetscInt nverts, moab::Range* overts)
1290 {
1291   moab::ErrorCode     merr;
1292   DM_Moab            *dmmoab;
1293   moab::Range         verts;
1294 
1295   PetscFunctionBegin;
1296   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1297   PetscValidPointer(coords, 2);
1298 
1299   dmmoab = (DM_Moab*) dm->data;
1300 
1301   /* Insert new points */
1302   merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts); MBERRNM(merr);
1303   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts); MBERRNM(merr);
1304 
1305   if (overts) *overts = verts;
1306   PetscFunctionReturn(0);
1307 }
1308 
1309 
1310 #undef __FUNCT__
1311 #define __FUNCT__ "DMMoabCreateElement"
1312 /*@
1313   DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM.
1314 
1315   Collective on MPI_Comm
1316 
1317   Input Parameters:
1318 + dm - The DM object
1319 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra)
1320 . conn - The connectivity of the element
1321 . nverts - The number of vertices that form the element
1322 
1323   Output Parameter:
1324 . oelem  - The handle to the element created and added to the DM object
1325 
1326   Level: beginner
1327 
1328 .keywords: DM, create element
1329 
1330 .seealso: DMMoabCreateSubmesh(), DMMoabCreateVertices()
1331 @*/
1332 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle* conn, PetscInt nverts, moab::EntityHandle* oelem)
1333 {
1334   moab::ErrorCode     merr;
1335   DM_Moab            *dmmoab;
1336   moab::EntityHandle  elem;
1337 
1338   PetscFunctionBegin;
1339   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1340   PetscValidPointer(conn, 3);
1341 
1342   dmmoab = (DM_Moab*) dm->data;
1343 
1344   /* Insert new element */
1345   merr = dmmoab->mbiface->create_element(type, conn, nverts, elem); MBERRNM(merr);
1346   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1); MBERRNM(merr);
1347 
1348   if (oelem) *oelem = elem;
1349   PetscFunctionReturn(0);
1350 }
1351 
1352 
1353 #undef __FUNCT__
1354 #define __FUNCT__ "DMMoabCreateSubmesh"
1355 /*@
1356   DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent
1357   in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to
1358   create a DM object on a refined level.
1359 
1360   Collective on MPI_Comm
1361 
1362   Input Parameters:
1363 + dm - The DM object
1364 
1365   Output Parameter:
1366 . newdm  - The sub DM object with updated set information
1367 
1368   Level: advanced
1369 
1370 .keywords: DM, sub-DM
1371 
1372 .seealso: DMCreate(), DMMoabCreateVertices(), DMMoabCreateElement()
1373 @*/
1374 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm)
1375 {
1376   DM_Moab            *dmmoab;
1377   DM_Moab            *ndmmoab;
1378   moab::ErrorCode    merr;
1379   PetscErrorCode     ierr;
1380 
1381   PetscFunctionBegin;
1382   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1383 
1384   dmmoab = (DM_Moab*) dm->data;
1385 
1386   /* Create the basic DMMoab object and keep the default parameters created by DM impls */
1387   ierr = DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, PETSC_NULL, newdm);CHKERRQ(ierr);
1388 
1389   /* get all the necessary handles from the private DM object */
1390   ndmmoab = (DM_Moab*) (*newdm)->data;
1391 
1392   /* set the sub-mesh's parent DM reference */
1393   ndmmoab->parent = &dm;
1394 
1395   /* create a file set to associate all entities in current mesh */
1396   merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset); MBERR("Creating file set failed", merr);
1397 
1398   /* create a meshset and then add old fileset as child */
1399   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal); MBERR("Adding child vertices to parent failed", merr);
1400   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal); MBERR("Adding child elements to parent failed", merr);
1401 
1402   /* preserve the field association between the parent and sub-mesh objects */
1403   ierr = DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames);CHKERRQ(ierr);
1404   PetscFunctionReturn(0);
1405 }
1406 
1407 
1408 #undef __FUNCT__
1409 #define __FUNCT__ "DMMoabView_Ascii"
1410 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer)
1411 {
1412   DM_Moab          *dmmoab = (DM_Moab*)(dm)->data;
1413   const char       *name;
1414   MPI_Comm          comm;
1415   PetscMPIInt       size;
1416   PetscErrorCode    ierr;
1417 
1418   PetscFunctionBegin;
1419   ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr);
1420   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
1421   ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr);
1422   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1423   if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dmmoab->dim);CHKERRQ(ierr);}
1424   else      {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dmmoab->dim);CHKERRQ(ierr);}
1425   /* print details about the global mesh */
1426   {
1427     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1428     ierr = PetscViewerASCIIPrintf(viewer, "Sizes: cells=%D, vertices=%D, blocks=%D\n", dmmoab->nele, dmmoab->n, dmmoab->bs);CHKERRQ(ierr);
1429     /* print boundary data */
1430     ierr = PetscViewerASCIIPrintf(viewer, "Boundary trace:\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr);
1431     {
1432       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1433       ierr = PetscViewerASCIIPrintf(viewer, "cells=%D, faces=%D, vertices=%D\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr);
1434       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1435     }
1436     /* print field data */
1437     ierr = PetscViewerASCIIPrintf(viewer, "Fields: %D components\n", dmmoab->numFields);CHKERRQ(ierr);
1438     {
1439       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1440       for (int i = 0; i < dmmoab->numFields; ++i) {
1441         ierr = PetscViewerASCIIPrintf(viewer, "[%D] - %s\n", i, dmmoab->fieldNames[i]);CHKERRQ(ierr);
1442       }
1443       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1444     }
1445     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1446   }
1447   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1448   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
1449   PetscFunctionReturn(0);
1450 }
1451 
1452 #undef __FUNCT__
1453 #define __FUNCT__ "DMMoabView_VTK"
1454 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v)
1455 {
1456   PetscFunctionReturn(0);
1457 }
1458 
1459 #undef __FUNCT__
1460 #define __FUNCT__ "DMMoabView_HDF5"
1461 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v)
1462 {
1463   PetscFunctionReturn(0);
1464 }
1465 
1466 #undef __FUNCT__
1467 #define __FUNCT__ "DMView_Moab"
1468 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer)
1469 {
1470   PetscBool      iascii, ishdf5, isvtk;
1471   PetscErrorCode ierr;
1472 
1473   PetscFunctionBegin;
1474   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1475   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1476   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
1477   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
1478   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1479   if (iascii) {
1480     ierr = DMMoabView_Ascii(dm, viewer);CHKERRQ(ierr);
1481   } else if (ishdf5) {
1482 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5)
1483     ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr);
1484     ierr = DMMoabView_HDF5(dm, viewer);CHKERRQ(ierr);
1485     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
1486 #else
1487     SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1488 #endif
1489   }
1490   else if (isvtk) {
1491     ierr = DMMoabView_VTK(dm, viewer);CHKERRQ(ierr);
1492   }
1493   PetscFunctionReturn(0);
1494 }
1495 
1496 
1497 #undef __FUNCT__
1498 #define __FUNCT__ "DMInitialize_Moab"
1499 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm)
1500 {
1501   PetscFunctionBegin;
1502   dm->ops->view                            = DMView_Moab;
1503   dm->ops->load                            = NULL /*DMLoad_Moab*/;
1504   dm->ops->setfromoptions                  = DMSetFromOptions_Moab;
1505   dm->ops->clone                           = DMClone_Moab;
1506   dm->ops->setup                           = DMSetUp_Moab;
1507   dm->ops->createdefaultsection            = NULL;
1508   dm->ops->createdefaultconstraints        = NULL;
1509   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
1510   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
1511   dm->ops->getlocaltoglobalmapping         = NULL;
1512   dm->ops->createfieldis                   = NULL;
1513   dm->ops->createcoordinatedm              = NULL /*DMCreateCoordinateDM_Moab*/;
1514   dm->ops->getcoloring                     = NULL;
1515   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
1516   dm->ops->createinterpolation             = DMCreateInterpolation_Moab;
1517   dm->ops->getaggregates                   = NULL;
1518   dm->ops->getinjection                    = NULL /*DMCreateInjection_Moab*/;
1519   dm->ops->refine                          = DMRefine_Moab;
1520   dm->ops->coarsen                         = DMCoarsen_Moab;
1521   dm->ops->refinehierarchy                 = DMRefineHierarchy_Moab;
1522   dm->ops->coarsenhierarchy                = DMCoarsenHierarchy_Moab;
1523   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
1524   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
1525   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
1526   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
1527   dm->ops->destroy                         = DMDestroy_Moab;
1528   dm->ops->createsubdm                     = NULL /*DMCreateSubDM_Moab*/;
1529   dm->ops->getdimpoints                    = NULL /*DMGetDimPoints_Moab*/;
1530   dm->ops->locatepoints                    = NULL /*DMLocatePoints_Moab*/;
1531   PetscFunctionReturn(0);
1532 }
1533 
1534 
1535 #undef __FUNCT__
1536 #define __FUNCT__ "DMClone_Moab"
1537 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm)
1538 {
1539   PetscErrorCode     ierr;
1540 
1541   PetscFunctionBegin;
1542   ierr = PetscObjectChangeTypeName((PetscObject) * newdm, DMMOAB);CHKERRQ(ierr);
1543 
1544   /* get all the necessary handles from the private DM object */
1545   (*newdm)->data = (DM_Moab*) dm->data;
1546   ((DM_Moab*)dm->data)->refct++;
1547 
1548   ierr = DMInitialize_Moab(*newdm);CHKERRQ(ierr);
1549   PetscFunctionReturn(0);
1550 }
1551 
1552 
1553 #undef __FUNCT__
1554 #define __FUNCT__ "DMCreate_Moab"
1555 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
1556 {
1557   PetscErrorCode ierr;
1558 
1559   PetscFunctionBegin;
1560   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1561   ierr = PetscNewLog(dm, (DM_Moab**)&dm->data);CHKERRQ(ierr);
1562 
1563   ((DM_Moab*)dm->data)->bs = 1;
1564   ((DM_Moab*)dm->data)->numFields = 1;
1565   ((DM_Moab*)dm->data)->n = 0;
1566   ((DM_Moab*)dm->data)->nloc = 0;
1567   ((DM_Moab*)dm->data)->nghost = 0;
1568   ((DM_Moab*)dm->data)->nele = 0;
1569   ((DM_Moab*)dm->data)->neleloc = 0;
1570   ((DM_Moab*)dm->data)->neleghost = 0;
1571   ((DM_Moab*)dm->data)->ltog_map = NULL;
1572   ((DM_Moab*)dm->data)->ltog_sendrecv = NULL;
1573 
1574   ((DM_Moab*)dm->data)->refct = 1;
1575   ((DM_Moab*)dm->data)->parent = NULL;
1576   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
1577   ((DM_Moab*)dm->data)->vowned = new moab::Range();
1578   ((DM_Moab*)dm->data)->vghost = new moab::Range();
1579   ((DM_Moab*)dm->data)->elocal = new moab::Range();
1580   ((DM_Moab*)dm->data)->eghost = new moab::Range();
1581 
1582   ierr = DMInitialize_Moab(dm);CHKERRQ(ierr);
1583   PetscFunctionReturn(0);
1584 }
1585 
1586