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