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