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