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