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