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