xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision bebe2cf65d55febe21a5af8db2bd2e168caaa2e7)
1 #include <petsc/private/dmmbimpl.h> /*I  "petscdmmoab.h"   I*/
2 
3 #include <petscdmmoab.h>
4 #include <MBTagConventions.hpp>
5 #include <moab/Skinner.hpp>
6 
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 
25 #undef __FUNCT__
26 #define __FUNCT__ "DMMoabCreate"
27 /*@
28   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
29 
30   Collective on MPI_Comm
31 
32   Input Parameter:
33 . comm - The communicator for the DMMoab object
34 
35   Output Parameter:
36 . dmb  - The DMMoab object
37 
38   Level: beginner
39 
40 .keywords: DMMoab, create
41 @*/
42 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
43 {
44   PetscErrorCode ierr;
45 
46   PetscFunctionBegin;
47   PetscValidPointer(dmb,2);
48   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
49   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
50   PetscFunctionReturn(0);
51 }
52 
53 #undef __FUNCT__
54 #define __FUNCT__ "DMMoabCreateMoab"
55 /*@
56   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
57 
58   Collective on MPI_Comm
59 
60   Input Parameter:
61 . comm - The communicator for the DMMoab object
62 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
63          along with the DMMoab
64 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
65 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
66 . range - If non-NULL, contains range of entities to which DOFs will be assigned
67 
68   Output Parameter:
69 . dmb  - The DMMoab object
70 
71   Level: intermediate
72 
73 .keywords: DMMoab, create
74 @*/
75 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
76 {
77   PetscErrorCode ierr;
78   moab::ErrorCode merr;
79   moab::EntityHandle partnset;
80   PetscInt rank, nprocs;
81   DM             dmmb;
82   DM_Moab        *dmmoab;
83 
84   PetscFunctionBegin;
85   PetscValidPointer(dmb,6);
86 
87   ierr = DMMoabCreate(comm, &dmmb);CHKERRQ(ierr);
88   dmmoab = (DM_Moab*)(dmmb)->data;
89 
90   if (!mbiface) {
91     dmmoab->mbiface = new moab::Core();
92     dmmoab->icreatedinstance = PETSC_TRUE;
93   }
94   else {
95     dmmoab->mbiface = mbiface;
96     dmmoab->icreatedinstance = PETSC_FALSE;
97   }
98 
99   /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */
100   dmmoab->fileset=0;
101 
102   if (!pcomm) {
103     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
104     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
105 
106     /* Create root sets for each mesh.  Then pass these
107        to the load_file functions to be populated. */
108     merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);MBERR("Creating partition set failed", merr);
109 
110     /* Create the parallel communicator object with the partition handle associated with MOAB */
111     dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
112   }
113   else {
114     ierr = DMMoabSetParallelComm(dmmb, pcomm);CHKERRQ(ierr);
115   }
116 
117   /* do the remaining initializations for DMMoab */
118   dmmoab->bs = 1;
119   dmmoab->numFields = 1;
120   dmmoab->rw_dbglevel = 0;
121   dmmoab->partition_by_rank = PETSC_FALSE;
122   dmmoab->extra_read_options[0] = '\0';
123   dmmoab->extra_write_options[0] = '\0';
124   dmmoab->read_mode = READ_PART;
125   dmmoab->write_mode = WRITE_PART;
126 
127   /* set global ID tag handle */
128   if (ltog_tag && *ltog_tag) {
129     ierr = DMMoabSetLocalToGlobalTag(dmmb, *ltog_tag);CHKERRQ(ierr);
130   }
131   else {
132     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
133     if (ltog_tag) *ltog_tag = dmmoab->ltog_tag;
134   }
135 
136   merr = dmmoab->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dmmoab->material_tag);MBERRNM(merr);
137 
138   /* set the local range of entities (vertices) of interest */
139   if (range) {
140     ierr = DMMoabSetLocalVertices(dmmb, range);CHKERRQ(ierr);
141   }
142   *dmb=dmmb;
143   PetscFunctionReturn(0);
144 }
145 
146 #undef __FUNCT__
147 #define __FUNCT__ "DMMoabSetParallelComm"
148 /*@
149   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
150 
151   Collective on MPI_Comm
152 
153   Input Parameter:
154 . dm    - The DMMoab object being set
155 . pcomm - The ParallelComm being set on the DMMoab
156 
157   Level: beginner
158 
159 .keywords: DMMoab, create
160 @*/
161 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
162 {
163   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
164 
165   PetscFunctionBegin;
166   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
167   PetscValidPointer(pcomm,2);
168   dmmoab->pcomm = pcomm;
169   dmmoab->mbiface = pcomm->get_moab();
170   dmmoab->icreatedinstance = PETSC_FALSE;
171   PetscFunctionReturn(0);
172 }
173 
174 
175 #undef __FUNCT__
176 #define __FUNCT__ "DMMoabGetParallelComm"
177 /*@
178   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
179 
180   Collective on MPI_Comm
181 
182   Input Parameter:
183 . dm    - The DMMoab object being set
184 
185   Output Parameter:
186 . pcomm - The ParallelComm for the DMMoab
187 
188   Level: beginner
189 
190 .keywords: DMMoab, create
191 @*/
192 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
193 {
194   PetscFunctionBegin;
195   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
196   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
197   PetscFunctionReturn(0);
198 }
199 
200 
201 #undef __FUNCT__
202 #define __FUNCT__ "DMMoabSetInterface"
203 /*@
204   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
205 
206   Collective on MPI_Comm
207 
208   Input Parameter:
209 . dm      - The DMMoab object being set
210 . mbiface - The MOAB instance being set on this DMMoab
211 
212   Level: beginner
213 
214 .keywords: DMMoab, create
215 @*/
216 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
217 {
218   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
219 
220   PetscFunctionBegin;
221   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
222   PetscValidPointer(mbiface,2);
223   dmmoab->pcomm = NULL;
224   dmmoab->mbiface = mbiface;
225   dmmoab->icreatedinstance = PETSC_FALSE;
226   PetscFunctionReturn(0);
227 }
228 
229 
230 #undef __FUNCT__
231 #define __FUNCT__ "DMMoabGetInterface"
232 /*@
233   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
234 
235   Collective on MPI_Comm
236 
237   Input Parameter:
238 . dm      - The DMMoab object being set
239 
240   Output Parameter:
241 . mbiface - The MOAB instance set on this DMMoab
242 
243   Level: beginner
244 
245 .keywords: DMMoab, create
246 @*/
247 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
248 {
249   PetscErrorCode   ierr;
250   static PetscBool cite = PETSC_FALSE;
251 
252   PetscFunctionBegin;
253   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
254   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);
255   *mbiface = ((DM_Moab*)dm->data)->mbiface;
256   PetscFunctionReturn(0);
257 }
258 
259 
260 #undef __FUNCT__
261 #define __FUNCT__ "DMMoabSetLocalVertices"
262 /*@
263   DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab
264 
265   Collective on MPI_Comm
266 
267   Input Parameter:
268 . dm    - The DMMoab object being set
269 . range - The entities treated by this DMMoab
270 
271   Level: beginner
272 
273 .keywords: DMMoab, create
274 @*/
275 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range)
276 {
277   moab::ErrorCode merr;
278   PetscErrorCode  ierr;
279   moab::Range     tmpvtxs;
280   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
281 
282   PetscFunctionBegin;
283   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
284   dmmoab->vlocal->clear();
285   dmmoab->vowned->clear();
286 
287   dmmoab->vlocal->insert(range->begin(), range->end());
288 
289   /* filter based on parallel status */
290   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr);
291 
292   /* filter all the non-owned and shared entities out of the list */
293   tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
294   merr = dmmoab->pcomm->filter_pstatus(tmpvtxs,PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr);
295   tmpvtxs = moab::subtract(tmpvtxs, *dmmoab->vghost);
296   *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs);
297 
298   /* compute and cache the sizes of local and ghosted entities */
299   dmmoab->nloc = dmmoab->vowned->size();
300   dmmoab->nghost = dmmoab->vghost->size();
301   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
302   PetscFunctionReturn(0);
303 }
304 
305 
306 #undef __FUNCT__
307 #define __FUNCT__ "DMMoabGetAllVertices"
308 /*@
309   DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab
310 
311   Collective on MPI_Comm
312 
313   Input Parameter:
314 . dm    - The DMMoab object being set
315 
316   Output Parameter:
317 . owned - The local vertex entities in this DMMoab = (owned+ghosted)
318 
319   Level: beginner
320 
321 .keywords: DMMoab, create
322 @*/
323 PetscErrorCode DMMoabGetAllVertices(DM dm,moab::Range *local)
324 {
325   PetscFunctionBegin;
326   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
327   if (local) *local = *((DM_Moab*)dm->data)->vlocal;
328   PetscFunctionReturn(0);
329 }
330 
331 
332 
333 #undef __FUNCT__
334 #define __FUNCT__ "DMMoabGetLocalVertices"
335 /*@
336   DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab
337 
338   Collective on MPI_Comm
339 
340   Input Parameter:
341 . dm    - The DMMoab object being set
342 
343   Output Parameter:
344 . owned - The owned vertex entities in this DMMoab
345 . ghost - The ghosted entities (non-owned) stored locally in this partition
346 
347   Level: beginner
348 
349 .keywords: DMMoab, create
350 @*/
351 PetscErrorCode DMMoabGetLocalVertices(DM dm,const moab::Range **owned,const moab::Range **ghost)
352 {
353   PetscFunctionBegin;
354   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
355   if (owned) *owned = ((DM_Moab*)dm->data)->vowned;
356   if (ghost) *ghost = ((DM_Moab*)dm->data)->vghost;
357   PetscFunctionReturn(0);
358 }
359 
360 #undef __FUNCT__
361 #define __FUNCT__ "DMMoabGetLocalElements"
362 /*@
363   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
364 
365   Collective on MPI_Comm
366 
367   Input Parameter:
368 . dm    - The DMMoab object being set
369 
370   Output Parameter:
371 . range - The entities owned locally
372 
373   Level: beginner
374 
375 .keywords: DMMoab, create
376 @*/
377 PetscErrorCode DMMoabGetLocalElements(DM dm,const moab::Range **range)
378 {
379   PetscFunctionBegin;
380   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
381   if (range) *range = ((DM_Moab*)dm->data)->elocal;
382   PetscFunctionReturn(0);
383 }
384 
385 
386 #undef __FUNCT__
387 #define __FUNCT__ "DMMoabSetLocalElements"
388 /*@
389   DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab
390 
391   Collective on MPI_Comm
392 
393   Input Parameter:
394 . dm    - The DMMoab object being set
395 . range - The entities treated by this DMMoab
396 
397   Level: beginner
398 
399 .keywords: DMMoab, create
400 @*/
401 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range)
402 {
403   moab::ErrorCode merr;
404   PetscErrorCode  ierr;
405   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
406 
407   PetscFunctionBegin;
408   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
409   dmmoab->elocal->clear();
410   dmmoab->eghost->clear();
411   dmmoab->elocal->insert(range->begin(), range->end());
412   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
413   *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal);
414   dmmoab->neleloc=dmmoab->elocal->size();
415   dmmoab->neleghost=dmmoab->eghost->size();
416   ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
417   PetscInfo2(dm, "Created %D local and %D global elements.\n", dmmoab->neleloc, dmmoab->nele);
418   PetscFunctionReturn(0);
419 }
420 
421 
422 #undef __FUNCT__
423 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
424 /*@
425   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
426 
427   Collective on MPI_Comm
428 
429   Input Parameter:
430 . dm      - The DMMoab object being set
431 . ltogtag - The MOAB tag used for local to global ids
432 
433   Level: beginner
434 
435 .keywords: DMMoab, create
436 @*/
437 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
438 {
439   PetscFunctionBegin;
440   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
441   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
442   PetscFunctionReturn(0);
443 }
444 
445 
446 #undef __FUNCT__
447 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
448 /*@
449   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
450 
451   Collective on MPI_Comm
452 
453   Input Parameter:
454 . dm      - The DMMoab object being set
455 
456   Output Parameter:
457 . ltogtag - The MOAB tag used for local to global ids
458 
459   Level: beginner
460 
461 .keywords: DMMoab, create
462 @*/
463 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
464 {
465   PetscFunctionBegin;
466   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
467   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
468   PetscFunctionReturn(0);
469 }
470 
471 
472 #undef __FUNCT__
473 #define __FUNCT__ "DMMoabSetBlockSize"
474 /*@
475   DMMoabSetBlockSize - Set the block size used with this DMMoab
476 
477   Collective on MPI_Comm
478 
479   Input Parameter:
480 . dm - The DMMoab object being set
481 . bs - The block size used with this DMMoab
482 
483   Level: beginner
484 
485 .keywords: DMMoab, create
486 @*/
487 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
488 {
489   PetscFunctionBegin;
490   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
491   ((DM_Moab*)dm->data)->bs = bs;
492   PetscFunctionReturn(0);
493 }
494 
495 
496 #undef __FUNCT__
497 #define __FUNCT__ "DMMoabGetBlockSize"
498 /*@
499   DMMoabGetBlockSize - Get the block size used with this DMMoab
500 
501   Collective on MPI_Comm
502 
503   Input Parameter:
504 . dm - The DMMoab object being set
505 
506   Output Parameter:
507 . bs - The block size used with this DMMoab
508 
509   Level: beginner
510 
511 .keywords: DMMoab, create
512 @*/
513 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
514 {
515   PetscFunctionBegin;
516   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
517   *bs = ((DM_Moab*)dm->data)->bs;
518   PetscFunctionReturn(0);
519 }
520 
521 
522 #undef __FUNCT__
523 #define __FUNCT__ "DMMoabGetSize"
524 /*@
525   DMMoabGetSize - Get the global vertex size used with this DMMoab
526 
527   Collective on DM
528 
529   Input Parameter:
530 . dm - The DMMoab object being set
531 
532   Output Parameter:
533 . neg - The number of global elements in the DMMoab instance
534 . nvg - The number of global vertices in the DMMoab instance
535 
536   Level: beginner
537 
538 .keywords: DMMoab, create
539 @*/
540 PetscErrorCode DMMoabGetSize(DM dm,PetscInt *neg,PetscInt *nvg)
541 {
542   PetscFunctionBegin;
543   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
544   if(neg) *neg = ((DM_Moab*)dm->data)->nele;
545   if(nvg) *nvg = ((DM_Moab*)dm->data)->n;
546   PetscFunctionReturn(0);
547 }
548 
549 
550 #undef __FUNCT__
551 #define __FUNCT__ "DMMoabGetLocalSize"
552 /*@
553   DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab
554 
555   Collective on DM
556 
557   Input Parameter:
558 . dm - The DMMoab object being set
559 
560   Output Parameter:
561 + nel - The number of owned elements in this processor
562 . neg - The number of ghosted elements in this processor
563 . nvl - The number of owned vertices in this processor
564 . nvg - The number of ghosted vertices in this processor
565 
566   Level: beginner
567 
568 .keywords: DMMoab, create
569 @*/
570 PetscErrorCode DMMoabGetLocalSize(DM dm,PetscInt *nel,PetscInt *neg,PetscInt *nvl,PetscInt *nvg)
571 {
572   PetscFunctionBegin;
573   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
574   if(nel) *nel = ((DM_Moab*)dm->data)->neleloc;
575   if(neg) *neg = ((DM_Moab*)dm->data)->neleghost;
576   if(nvl) *nvl = ((DM_Moab*)dm->data)->nloc;
577   if(nvg) *nvg = ((DM_Moab*)dm->data)->nghost;
578   PetscFunctionReturn(0);
579 }
580 
581 
582 #undef __FUNCT__
583 #define __FUNCT__ "DMMoabGetOffset"
584 /*@
585   DMMoabGetOffset - Get the local offset for the global vector
586 
587   Collective on MPI_Comm
588 
589   Input Parameter:
590 . dm - The DMMoab object being set
591 
592   Output Parameter:
593 . offset - The local offset for the global vector
594 
595   Level: beginner
596 
597 .keywords: DMMoab, create
598 @*/
599 PetscErrorCode DMMoabGetOffset(DM dm,PetscInt *offset)
600 {
601   PetscFunctionBegin;
602   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
603   *offset = ((DM_Moab*)dm->data)->vstart;
604   PetscFunctionReturn(0);
605 }
606 
607 
608 #undef __FUNCT__
609 #define __FUNCT__ "DMMoabGetDimension"
610 /*@
611   DMMoabGetDimension - Get the dimension of the DM Mesh
612 
613   Collective on MPI_Comm
614 
615   Input Parameter:
616 . dm - The DMMoab object
617 
618   Output Parameter:
619 . dim - The dimension of DM
620 
621   Level: beginner
622 
623 .keywords: DMMoab, create
624 @*/
625 PetscErrorCode DMMoabGetDimension(DM dm,PetscInt *dim)
626 {
627   PetscFunctionBegin;
628   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
629   *dim = ((DM_Moab*)dm->data)->dim;
630   PetscFunctionReturn(0);
631 }
632 
633 
634 #undef __FUNCT__
635 #define __FUNCT__ "DMMoabGetMaterialBlock"
636 /*@
637   DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh
638 
639   Collective on MPI_Comm
640 
641   Input Parameter:
642 . dm - The DMMoab object
643 . ehandle - The element entity handle
644 
645   Output Parameter:
646 . mat - The material ID for the current entity
647 
648   Level: beginner
649 
650 .keywords: DMMoab, create
651 @*/
652 PetscErrorCode DMMoabGetMaterialBlock(DM dm,const moab::EntityHandle ehandle, PetscInt *mat)
653 {
654   DM_Moab         *dmmoab;
655   moab::ErrorCode merr;
656 
657   PetscFunctionBegin;
658   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
659   if (*mat) {
660     dmmoab = (DM_Moab*)(dm)->data;
661     merr=dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &ehandle, 1, mat);MBERRNM(merr);
662   }
663   PetscFunctionReturn(0);
664 }
665 
666 
667 #undef __FUNCT__
668 #define __FUNCT__ "DMMoabGetVertexCoordinates"
669 /*@
670   DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities
671 
672   Collective on MPI_Comm
673 
674   Input Parameter:
675 . dm - The DMMoab object
676 . nconn - Number of entities whose coordinates are needed
677 . conn - The vertex entity handles
678 
679   Output Parameter:
680 . vpos - The coordinates of the requested vertex entities
681 
682   Level: beginner
683 
684 .seealso: DMMoabGetVertexConnectivity()
685 @*/
686 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscReal *vpos)
687 {
688   DM_Moab         *dmmoab;
689   PetscErrorCode  ierr;
690   moab::ErrorCode merr;
691 
692   PetscFunctionBegin;
693   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
694   PetscValidPointer(conn,3);
695   dmmoab = (DM_Moab*)(dm)->data;
696 
697   if (!vpos) {
698     ierr = PetscMalloc1(nconn*3, &vpos);CHKERRQ(ierr);
699   }
700 
701   /* Get connectivity information in MOAB canonical ordering */
702   merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr);
703   PetscFunctionReturn(0);
704 }
705 
706 
707 #undef __FUNCT__
708 #define __FUNCT__ "DMMoabGetVertexConnectivity"
709 /*@
710   DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity
711 
712   Collective on MPI_Comm
713 
714   Input Parameter:
715 . dm - The DMMoab object
716 . vhandle - Vertex entity handle
717 
718   Output Parameter:
719 . nconn - Number of entities whose coordinates are needed
720 . conn - The vertex entity handles
721 
722   Level: beginner
723 
724 .seealso: DMMoabGetVertexCoordinates(), DMMoabRestoreVertexConnectivity()
725 @*/
726 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle vhandle,PetscInt* nconn, moab::EntityHandle **conn)
727 {
728   DM_Moab        *dmmoab;
729   std::vector<moab::EntityHandle> adj_entities,connect;
730   PetscErrorCode  ierr;
731   moab::ErrorCode merr;
732 
733   PetscFunctionBegin;
734   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
735   PetscValidPointer(conn,4);
736   dmmoab = (DM_Moab*)(dm)->data;
737 
738   /* Get connectivity information in MOAB canonical ordering */
739   merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr);
740   merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr);
741 
742   if (conn) {
743     ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr);
744     ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr);
745   }
746   if (nconn) *nconn=connect.size();
747   PetscFunctionReturn(0);
748 }
749 
750 
751 #undef __FUNCT__
752 #define __FUNCT__ "DMMoabRestoreVertexConnectivity"
753 /*@
754   DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity
755 
756   Collective on MPI_Comm
757 
758   Input Parameter:
759 . dm - The DMMoab object
760 . vhandle - Vertex entity handle
761 . nconn - Number of entities whose coordinates are needed
762 . conn - The vertex entity handles
763 
764   Level: beginner
765 
766 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity()
767 @*/
768 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn)
769 {
770   PetscErrorCode  ierr;
771 
772   PetscFunctionBegin;
773   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
774   PetscValidPointer(conn,4);
775 
776   if (conn) {
777     ierr = PetscFree(*conn);CHKERRQ(ierr);
778   }
779   if (nconn) *nconn=0;
780   PetscFunctionReturn(0);
781 }
782 
783 
784 #undef __FUNCT__
785 #define __FUNCT__ "DMMoabGetElementConnectivity"
786 /*@
787   DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity
788 
789   Collective on MPI_Comm
790 
791   Input Parameter:
792 . dm - The DMMoab object
793 . ehandle - Vertex entity handle
794 
795   Output Parameter:
796 . nconn - Number of entities whose coordinates are needed
797 . conn - The vertex entity handles
798 
799   Level: beginner
800 
801 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity(), DMMoabRestoreVertexConnectivity()
802 @*/
803 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn)
804 {
805   DM_Moab        *dmmoab;
806   const moab::EntityHandle *connect;
807   moab::ErrorCode merr;
808   PetscInt nnodes;
809 
810   PetscFunctionBegin;
811   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
812   PetscValidPointer(conn,4);
813   dmmoab = (DM_Moab*)(dm)->data;
814 
815   /* Get connectivity information in MOAB canonical ordering */
816   merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr);
817   if (conn) *conn=connect;
818   if (nconn) *nconn=nnodes;
819   PetscFunctionReturn(0);
820 }
821 
822 
823 #undef __FUNCT__
824 #define __FUNCT__ "DMMoabIsEntityOnBoundary"
825 /*@
826   DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element)
827 
828   Collective on MPI_Comm
829 
830   Input Parameter:
831 . dm - The DMMoab object
832 . ent - Entity handle
833 
834   Output Parameter:
835 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise
836 
837   Level: beginner
838 
839 .seealso: DMMoabCheckBoundaryVertices()
840 @*/
841 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary)
842 {
843   moab::EntityType etype;
844   DM_Moab         *dmmoab;
845   PetscInt         edim;
846 
847   PetscFunctionBegin;
848   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
849   PetscValidPointer(ent_on_boundary,3);
850   dmmoab = (DM_Moab*)(dm)->data;
851 
852   /* get the entity type and handle accordingly */
853   etype=dmmoab->mbiface->type_from_handle(ent);
854   if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype);
855 
856   /* get the entity dimension */
857   edim=dmmoab->mbiface->dimension_from_handle(ent);
858 
859   *ent_on_boundary=PETSC_FALSE;
860   if(etype == moab::MBVERTEX && edim == 0) {
861     if (dmmoab->bndyvtx->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE;
862   }
863   else {
864     if (edim == dmmoab->dim) {  /* check the higher-dimensional elements first */
865       if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE;
866     }
867     else {                      /* next check the lower-dimensional faces */
868       if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE;
869     }
870   }
871   PetscFunctionReturn(0);
872 }
873 
874 
875 #undef __FUNCT__
876 #define __FUNCT__ "DMMoabCheckBoundaryVertices"
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 #undef __FUNCT__
911 #define __FUNCT__ "DMMoabGetBoundaryMarkers"
912 /*@
913   DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary
914 
915   Input Parameter:
916 . dm - The DMMoab object
917 
918   Output Parameter:
919 . bdvtx - Boundary vertices
920 . bdelems - Boundary elements
921 . bdfaces - Boundary faces
922 
923   Level: beginner
924 
925 .seealso: DMMoabCheckBoundaryVertices(), DMMoabIsEntityOnBoundary()
926 @*/
927 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,const moab::Range **bdvtx,const moab::Range** bdelems,const moab::Range** bdfaces)
928 {
929   DM_Moab        *dmmoab;
930 
931   PetscFunctionBegin;
932   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
933   dmmoab = (DM_Moab*)(dm)->data;
934 
935   if (bdvtx)  *bdvtx = dmmoab->bndyvtx;
936   if (bdfaces)  *bdfaces = dmmoab->bndyfaces;
937   if (bdelems)  *bdfaces = dmmoab->bndyelems;
938   PetscFunctionReturn(0);
939 }
940 
941 
942 #undef __FUNCT__
943 #define __FUNCT__ "DMDestroy_Moab"
944 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm)
945 {
946   PetscErrorCode ierr;
947   PetscInt       i;
948   DM_Moab        *dmmoab = (DM_Moab*)dm->data;
949 
950   PetscFunctionBegin;
951   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
952   if (dmmoab->icreatedinstance) {
953     delete dmmoab->mbiface;
954   }
955   dmmoab->mbiface = NULL;
956   dmmoab->pcomm = NULL;
957   delete dmmoab->vlocal;
958   delete dmmoab->vowned;
959   delete dmmoab->vghost;
960   delete dmmoab->elocal;
961   delete dmmoab->eghost;
962   delete dmmoab->bndyvtx;
963   delete dmmoab->bndyfaces;
964   delete dmmoab->bndyelems;
965 
966   ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr);
967   ierr = PetscFree2(dmmoab->gidmap,dmmoab->lidmap);CHKERRQ(ierr);
968   ierr = PetscFree2(dmmoab->lgmap,dmmoab->llmap);CHKERRQ(ierr);
969   ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr);
970   ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr);
971   if (dmmoab->fieldNames) {
972     for(i=0; i<dmmoab->numFields; i++) {
973       ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr);
974     }
975     ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr);
976   }
977   ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
978   ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr);
979   ierr = PetscFree(dm->data);CHKERRQ(ierr);
980   PetscFunctionReturn(0);
981 }
982 
983 
984 #undef __FUNCT__
985 #define __FUNCT__ "DMSetFromOptions_Moab"
986 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptions *PetscOptionsObject,DM dm)
987 {
988   PetscErrorCode ierr;
989   DM_Moab        *dmmoab = (DM_Moab*)dm->data;
990 
991   PetscFunctionBegin;
992   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
993   ierr = PetscOptionsHead(PetscOptionsObject,"DMMoab Options");CHKERRQ(ierr);
994   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);
995   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);
996   /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */
997   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);
998   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);
999   ierr  = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr);
1000   ierr  = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr);
1001   PetscFunctionReturn(0);
1002 }
1003 
1004 
1005 #undef __FUNCT__
1006 #define __FUNCT__ "DMSetUp_Moab"
1007 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm)
1008 {
1009   PetscErrorCode          ierr;
1010   moab::ErrorCode         merr;
1011   Vec                     local, global;
1012   IS                      from,to;
1013   moab::Range::iterator   iter;
1014   PetscInt                i,j,f,bs,gmin,lmin,lmax,vent,totsize;
1015   DM_Moab                *dmmoab = (DM_Moab*)dm->data;
1016   moab::Range             adjs;
1017 
1018   PetscFunctionBegin;
1019   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1020   /* Get the local and shared vertices and cache it */
1021   if (dmmoab->mbiface == PETSC_NULL || dmmoab->pcomm == PETSC_NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp.");
1022 
1023   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
1024   if (dmmoab->vlocal->empty())
1025   {
1026     merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
1027 
1028     /* filter based on parallel status */
1029     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr);
1030 
1031     /* filter all the non-owned and shared entities out of the list */
1032     adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
1033     merr = dmmoab->pcomm->filter_pstatus(adjs,PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr);
1034     adjs = moab::subtract(adjs, *dmmoab->vghost);
1035     *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs);
1036 
1037     /* compute and cache the sizes of local and ghosted entities */
1038     dmmoab->nloc = dmmoab->vowned->size();
1039     dmmoab->nghost = dmmoab->vghost->size();
1040     ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1041   }
1042 
1043   {
1044     /* get the information about the local elements in the mesh */
1045     dmmoab->eghost->clear();
1046 
1047     /* first decipher the leading dimension */
1048     for (i=3;i>0;i--) {
1049       dmmoab->elocal->clear();
1050       merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, true);CHKERRQ(merr);
1051 
1052       /* store the current mesh dimension */
1053       if (dmmoab->elocal->size()) {
1054         dmmoab->dim=i;
1055         break;
1056       }
1057     }
1058 
1059     /* filter the ghosted and owned element list */
1060     *dmmoab->eghost = *dmmoab->elocal;
1061     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
1062     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
1063 
1064     dmmoab->neleloc = dmmoab->elocal->size();
1065     dmmoab->neleghost = dmmoab->eghost->size();
1066     ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1067   }
1068 
1069   bs = dmmoab->bs;
1070   if (!dmmoab->ltog_tag) {
1071     /* Get the global ID tag. The global ID tag is applied to each
1072        vertex. It acts as an global identifier which MOAB uses to
1073        assemble the individual pieces of the mesh */
1074     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
1075   }
1076 
1077   totsize=dmmoab->vlocal->size();
1078   if (totsize != dmmoab->nloc+dmmoab->nghost) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Mismatch between local and owned+ghost vertices. %D != %D.",totsize,dmmoab->nloc+dmmoab->nghost);
1079   ierr = PetscMalloc1(totsize,&dmmoab->gsindices);CHKERRQ(ierr);
1080   {
1081     /* first get the local indices */
1082     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr);
1083     /* next get the ghosted indices */
1084     if (dmmoab->nghost) {
1085       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr);
1086     }
1087 
1088     /* find out the local and global minima of GLOBAL_ID */
1089     lmin=lmax=dmmoab->gsindices[0];
1090     for (i=0; i<totsize; ++i) {
1091       if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i];
1092       if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i];
1093     }
1094 
1095     ierr = MPI_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr);
1096 
1097     /* set the GID map */
1098     for (i=0; i<totsize; ++i) {
1099       dmmoab->gsindices[i]-=gmin;   /* zero based index needed for IS */
1100     }
1101     lmin-=gmin;
1102     lmax-=gmin;
1103 
1104     PetscInfo3(NULL, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin);
1105   }
1106   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);
1107 
1108   {
1109     i=(PetscInt)dmmoab->vlocal->back()+1;
1110     //i=(PetscInt)(dmmoab->vlocal->back()-dmmoab->vlocal->front())+1;
1111     j=totsize*dmmoab->numFields;
1112     ierr = PetscMalloc2(i,&dmmoab->gidmap,i,&dmmoab->lidmap);CHKERRQ(ierr);
1113     ierr = PetscMalloc2(j,&dmmoab->lgmap,j,&dmmoab->llmap);CHKERRQ(ierr);
1114 
1115     i=j=0;
1116     /* set the owned vertex data first */
1117     for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) {
1118       vent=(PetscInt)(*iter);
1119       dmmoab->gidmap[vent]=dmmoab->gsindices[i];
1120       dmmoab->lidmap[vent]=i;
1121       if (bs > 1) {
1122         for (f=0;f<dmmoab->numFields;f++,j++) {
1123           dmmoab->lgmap[j]=dmmoab->gsindices[i]*dmmoab->numFields+f;
1124           dmmoab->llmap[j]=i*dmmoab->numFields+f;
1125         }
1126       }
1127       else {
1128         for (f=0;f<dmmoab->numFields;f++,j++) {
1129           dmmoab->lgmap[j]=totsize*f+dmmoab->gsindices[i];
1130           dmmoab->llmap[j]=totsize*f+i;
1131         }
1132       }
1133     }
1134     /* next arrange all the ghosted data information */
1135     for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) {
1136       vent=(PetscInt)(*iter);
1137       dmmoab->gidmap[vent]=dmmoab->gsindices[i];
1138       dmmoab->lidmap[vent]=i;
1139       if (bs > 1) {
1140         for (f=0;f<dmmoab->numFields;f++,j++) {
1141           dmmoab->lgmap[j]=dmmoab->gsindices[i]*dmmoab->numFields+f;
1142           dmmoab->llmap[j]=i*dmmoab->numFields+f;
1143         }
1144       }
1145       else {
1146         for (f=0;f<dmmoab->numFields;f++,j++) {
1147           dmmoab->lgmap[j]=totsize*f+dmmoab->gsindices[i];
1148           dmmoab->llmap[j]=totsize*f+i;
1149         }
1150       }
1151     }
1152 
1153     /* We need to create the Global to Local Vector Scatter Contexts
1154        1) First create a local and global vector
1155        2) Create a local and global IS
1156        3) Create VecScatter and LtoGMapping objects
1157        4) Cleanup the IS and Vec objects
1158     */
1159     ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr);
1160     ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr);
1161 
1162     ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr);
1163     PetscInfo3(NULL, "Total-size = %D\t Owned = %D, Ghosted = %D.\n", totsize, dmmoab->nloc, dmmoab->nghost);
1164 
1165     /* global to local must retrieve ghost points */
1166     ierr = ISCreateStride(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,dmmoab->vstart,1,&from);CHKERRQ(ierr);
1167     ierr = ISSetBlockSize(from,bs);CHKERRQ(ierr);
1168 
1169     ierr = ISCreateGeneral(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,&dmmoab->lgmap[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
1170     ierr = ISSetBlockSize(to,bs);CHKERRQ(ierr);
1171 
1172     if (!dmmoab->ltog_map) {
1173       /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */
1174       ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,dmmoab->bs,totsize*dmmoab->numFields,dmmoab->lgmap,
1175                                           PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr);
1176     }
1177 
1178     /* now create the scatter object from local to global vector */
1179     ierr = VecScatterCreate(local,from,global,to,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
1180 
1181     /* clean up IS, Vec */
1182     ierr = ISDestroy(&from);CHKERRQ(ierr);
1183     ierr = ISDestroy(&to);CHKERRQ(ierr);
1184     ierr = VecDestroy(&local);CHKERRQ(ierr);
1185     ierr = VecDestroy(&global);CHKERRQ(ierr);
1186   }
1187 
1188   /* skin the boundary and store nodes */
1189   {
1190     /* get the skin vertices of boundary faces for the current partition and then filter
1191        the local, boundary faces, vertices and elements alone via PSTATUS flags;
1192        this should not give us any ghosted boundary, but if user needs such a functionality
1193        it would be easy to add it based on the find_skin query below */
1194     moab::Skinner skinner(dmmoab->mbiface);
1195 
1196     dmmoab->bndyvtx = new moab::Range();
1197     dmmoab->bndyfaces = new moab::Range();
1198     dmmoab->bndyelems = new moab::Range();
1199 
1200     /* get the entities on the skin - only the faces */
1201     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
1202 
1203     /* filter all the non-owned and shared entities out of the list */
1204     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
1205     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr);
1206 
1207     /* get all the nodes via connectivity and the parent elements via adjacency information */
1208     merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr);
1209     merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyfaces, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr);
1210     PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyvtx->size(), dmmoab->bndyelems->size());
1211   }
1212   PetscFunctionReturn(0);
1213 }
1214 
1215 #undef __FUNCT__
1216 #define __FUNCT__ "DMCreate_Moab"
1217 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
1218 {
1219   PetscErrorCode ierr;
1220 
1221   PetscFunctionBegin;
1222   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1223   ierr = PetscNewLog(dm,(DM_Moab**)&dm->data);CHKERRQ(ierr);
1224 
1225   ((DM_Moab*)dm->data)->bs = 1;
1226   ((DM_Moab*)dm->data)->numFields = 1;
1227   ((DM_Moab*)dm->data)->n = 0;
1228   ((DM_Moab*)dm->data)->nloc = 0;
1229   ((DM_Moab*)dm->data)->nghost = 0;
1230   ((DM_Moab*)dm->data)->nele = 0;
1231   ((DM_Moab*)dm->data)->neleloc = 0;
1232   ((DM_Moab*)dm->data)->neleghost = 0;
1233   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
1234   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
1235 
1236   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
1237   ((DM_Moab*)dm->data)->vowned = new moab::Range();
1238   ((DM_Moab*)dm->data)->vghost = new moab::Range();
1239   ((DM_Moab*)dm->data)->elocal = new moab::Range();
1240   ((DM_Moab*)dm->data)->eghost = new moab::Range();
1241 
1242   dm->ops->createglobalvector       = DMCreateGlobalVector_Moab;
1243   dm->ops->createlocalvector        = DMCreateLocalVector_Moab;
1244   dm->ops->creatematrix             = DMCreateMatrix_Moab;
1245   dm->ops->setup                    = DMSetUp_Moab;
1246   dm->ops->destroy                  = DMDestroy_Moab;
1247   dm->ops->setfromoptions           = DMSetFromOptions_Moab;
1248   dm->ops->globaltolocalbegin       = DMGlobalToLocalBegin_Moab;
1249   dm->ops->globaltolocalend         = DMGlobalToLocalEnd_Moab;
1250   dm->ops->localtoglobalbegin       = DMLocalToGlobalBegin_Moab;
1251   dm->ops->localtoglobalend         = DMLocalToGlobalEnd_Moab;
1252   PetscFunctionReturn(0);
1253 }
1254 
1255