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