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