xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 834855d6effb0d027771461c8e947ee1ce5a1e17)
1 #include <petsc/private/dmmbimpl.h> /*I  "petscdmmoab.h"   I*/
2 
3 #include <petscdmmoab.h>
4 #include <MBTagConventions.hpp>
5 #include <moab/NestedRefine.hpp>
6 #include <moab/Skinner.hpp>
7 
8 /*MC
9   DMMOAB = "moab" - A `DM` object that encapsulates an unstructured mesh described by the MOAB mesh database {cite}`moabwebsite`.
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   Level: intermediate
18 
19 .seealso: `DMMOAB`, `DMType`, `DMMoabCreate()`, `DMCreate()`, `DMSetType()`, `DMMoabCreateMoab()`
20 M*/
21 
22 /* External function declarations here */
23 PETSC_EXTERN PetscErrorCode DMCreateInterpolation_Moab(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling);
24 PETSC_EXTERN PetscErrorCode DMCreateDefaultConstraints_Moab(DM dm);
25 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J);
26 PETSC_EXTERN PetscErrorCode DMCreateCoordinateDM_Moab(DM dm, DM *cdm);
27 PETSC_EXTERN PetscErrorCode DMRefine_Moab(DM dm, MPI_Comm comm, DM *dmRefined);
28 PETSC_EXTERN PetscErrorCode DMCoarsen_Moab(DM dm, MPI_Comm comm, DM *dmCoarsened);
29 PETSC_EXTERN PetscErrorCode DMRefineHierarchy_Moab(DM dm, PetscInt nlevels, DM dmRefined[]);
30 PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy_Moab(DM dm, PetscInt nlevels, DM dmCoarsened[]);
31 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm);
32 PETSC_EXTERN PetscErrorCode DMCreateGlobalVector_Moab(DM, Vec *);
33 PETSC_EXTERN PetscErrorCode DMCreateLocalVector_Moab(DM, Vec *);
34 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J);
35 PETSC_EXTERN PetscErrorCode DMGlobalToLocalBegin_Moab(DM, Vec, InsertMode, Vec);
36 PETSC_EXTERN PetscErrorCode DMGlobalToLocalEnd_Moab(DM, Vec, InsertMode, Vec);
37 PETSC_EXTERN PetscErrorCode DMLocalToGlobalBegin_Moab(DM, Vec, InsertMode, Vec);
38 PETSC_EXTERN PetscErrorCode DMLocalToGlobalEnd_Moab(DM, Vec, InsertMode, Vec);
39 
40 /* Un-implemented routines */
41 /*
42 PETSC_EXTERN PetscErrorCode DMCreatelocalsection_Moab(DM dm);
43 PETSC_EXTERN PetscErrorCode DMCreateInjection_Moab(DM dmCoarse, DM dmFine, Mat *mat);
44 PETSC_EXTERN PetscErrorCode DMLoad_Moab(DM dm, PetscViewer viewer);
45 PETSC_EXTERN PetscErrorCode DMGetDimPoints_Moab(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd);
46 PETSC_EXTERN PetscErrorCode DMCreateSubDM_Moab(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm);
47 PETSC_EXTERN PetscErrorCode DMLocatePoints_Moab(DM dm, Vec v, IS *cellIS);
48 */
49 
50 /*@C
51   DMMoabCreate - Creates a `DMMOAB` object, which encapsulates a moab instance
52 
53   Collective
54 
55   Input Parameter:
56 . comm - The communicator for the `DMMOAB` object
57 
58   Output Parameter:
59 . dmb - The `DMMOAB` object
60 
61   Level: beginner
62 
63 .seealso: `DMMOAB`, `DMMoabCreateMoab()`
64 @*/
DMMoabCreate(MPI_Comm comm,DM * dmb)65 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
66 {
67   PetscFunctionBegin;
68   PetscAssertPointer(dmb, 2);
69   PetscCall(DMCreate(comm, dmb));
70   PetscCall(DMSetType(*dmb, DMMOAB));
71   PetscFunctionReturn(PETSC_SUCCESS);
72 }
73 
74 /*@C
75   DMMoabCreateMoab - Creates a `DMMOAB` object, optionally from an instance and other data
76 
77   Collective
78 
79   Input Parameters:
80 + comm     - The communicator for the `DMMOAB` object
81 . mbiface  - (ptr to) the `DMMOAB` Instance; if passed in `NULL`, MOAB instance is created inside PETSc, and destroyed
82          along with the `DMMOAB`
83 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
84 - range    - If non-`NULL`, contains range of entities to which DOFs will be assigned
85 
86   Output Parameter:
87 . dmb - The `DMMOAB` object
88 
89   Level: intermediate
90 
91 .seealso: `DMMOAB`, `DMMoabCreate()`
92 @*/
DMMoabCreateMoab(MPI_Comm comm,moab::Interface * mbiface,moab::Tag * ltog_tag,moab::Range * range,DM * dmb)93 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
94 {
95   moab::ErrorCode merr;
96   DM              dmmb;
97   DM_Moab        *dmmoab;
98 
99   PetscFunctionBegin;
100   PetscAssertPointer(dmb, 6);
101 
102   PetscCall(DMMoabCreate(comm, &dmmb));
103   dmmoab = (DM_Moab *)dmmb->data;
104 
105   if (!mbiface) {
106     dmmoab->mbiface          = new moab::Core();
107     dmmoab->icreatedinstance = PETSC_TRUE;
108   } else {
109     dmmoab->mbiface          = mbiface;
110     dmmoab->icreatedinstance = PETSC_FALSE;
111   }
112 
113   /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */
114   dmmoab->fileset     = 0;
115   dmmoab->hlevel      = 0;
116   dmmoab->nghostrings = 0;
117 
118 #ifdef MOAB_HAVE_MPI
119   moab::EntityHandle partnset;
120 
121   /* Create root sets for each mesh.  Then pass these
122       to the load_file functions to be populated. */
123   merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);
124   MBERR("Creating partition set failed", merr);
125 
126   /* Create the parallel communicator object with the partition handle associated with MOAB */
127   dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
128 #endif
129 
130   /* do the remaining initializations for DMMoab */
131   dmmoab->bs        = 1;
132   dmmoab->numFields = 1;
133   PetscCall(PetscMalloc(dmmoab->numFields * sizeof(char *), &dmmoab->fieldNames));
134   PetscCall(PetscStrallocpy("DEFAULT", (char **)&dmmoab->fieldNames[0]));
135   dmmoab->rw_dbglevel            = 0;
136   dmmoab->partition_by_rank      = PETSC_FALSE;
137   dmmoab->extra_read_options[0]  = '\0';
138   dmmoab->extra_write_options[0] = '\0';
139   dmmoab->read_mode              = READ_PART;
140   dmmoab->write_mode             = WRITE_PART;
141 
142   /* set global ID tag handle */
143   if (ltog_tag && *ltog_tag) {
144     PetscCall(DMMoabSetLocalToGlobalTag(dmmb, *ltog_tag));
145   } else {
146     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);
147     MBERRNM(merr);
148     if (ltog_tag) *ltog_tag = dmmoab->ltog_tag;
149   }
150 
151   merr = dmmoab->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dmmoab->material_tag);
152   MBERRNM(merr);
153 
154   /* set the local range of entities (vertices) of interest */
155   if (range) PetscCall(DMMoabSetLocalVertices(dmmb, range));
156   *dmb = dmmb;
157   PetscFunctionReturn(PETSC_SUCCESS);
158 }
159 
160 #ifdef MOAB_HAVE_MPI
161 
162 /*@C
163   DMMoabGetParallelComm - Get the ParallelComm used with this `DMMOAB`
164 
165   Collective
166 
167   Input Parameter:
168 . dm    - The `DMMOAB` object being set
169 
170   Output Parameter:
171 . pcomm - The ParallelComm for the `DMMOAB`
172 
173   Level: beginner
174 
175 .seealso: `DMMOAB`, `DMMoabSetInterface()`
176 @*/
DMMoabGetParallelComm(DM dm,moab::ParallelComm ** pcomm)177 PetscErrorCode DMMoabGetParallelComm(DM dm, moab::ParallelComm **pcomm)
178 {
179   PetscFunctionBegin;
180   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
181   *pcomm = ((DM_Moab *)dm->data)->pcomm;
182   PetscFunctionReturn(PETSC_SUCCESS);
183 }
184 
185 #endif /* MOAB_HAVE_MPI */
186 
187 /*@C
188   DMMoabSetInterface - Set the MOAB instance used with this `DMMOAB`
189 
190   Collective
191 
192   Input Parameters:
193 + dm      - The `DMMOAB` object being set
194 - mbiface - The MOAB instance being set on this `DMMOAB`
195 
196   Level: beginner
197 
198 .seealso: `DMMOAB`, `DMMoabGetInterface()`
199 @*/
DMMoabSetInterface(DM dm,moab::Interface * mbiface)200 PetscErrorCode DMMoabSetInterface(DM dm, moab::Interface *mbiface)
201 {
202   DM_Moab *dmmoab = (DM_Moab *)dm->data;
203 
204   PetscFunctionBegin;
205   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
206   PetscAssertPointer(mbiface, 2);
207 #ifdef MOAB_HAVE_MPI
208   dmmoab->pcomm = NULL;
209 #endif
210   dmmoab->mbiface          = mbiface;
211   dmmoab->icreatedinstance = PETSC_FALSE;
212   PetscFunctionReturn(PETSC_SUCCESS);
213 }
214 
215 /*@C
216   DMMoabGetInterface - Get the MOAB instance used with this `DMMOAB`
217 
218   Collective
219 
220   Input Parameter:
221 . dm - The `DMMOAB` object being set
222 
223   Output Parameter:
224 . mbiface - The MOAB instance set on this `DMMOAB`
225 
226   Level: beginner
227 
228 .seealso: `DMMOAB`, `DMMoabSetInterface()`
229 @*/
DMMoabGetInterface(DM dm,moab::Interface ** mbiface)230 PetscErrorCode DMMoabGetInterface(DM dm, moab::Interface **mbiface)
231 {
232   static PetscBool cite = PETSC_FALSE;
233 
234   PetscFunctionBegin;
235   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
236   PetscCall(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, "
237                                    "K. and Stimpson, C. and Ernst, C.},\n  year = {2004},  note = {Report}\n}\n",
238                                    &cite));
239   *mbiface = ((DM_Moab *)dm->data)->mbiface;
240   PetscFunctionReturn(PETSC_SUCCESS);
241 }
242 
243 /*@C
244   DMMoabSetLocalVertices - Set the entities having DOFs on this `DMMOAB`
245 
246   Collective
247 
248   Input Parameters:
249 + dm    - The `DMMOAB` object being set
250 - range - The entities treated by this `DMMOAB`
251 
252   Level: beginner
253 
254 .seealso: `DMMOAB`, `DMMoabGetAllVertices()`
255 @*/
DMMoabSetLocalVertices(DM dm,moab::Range * range)256 PetscErrorCode DMMoabSetLocalVertices(DM dm, moab::Range *range)
257 {
258   moab::Range tmpvtxs;
259   DM_Moab    *dmmoab = (DM_Moab *)dm->data;
260 
261   PetscFunctionBegin;
262   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
263   dmmoab->vlocal->clear();
264   dmmoab->vowned->clear();
265 
266   dmmoab->vlocal->insert(range->begin(), range->end());
267 
268 #ifdef MOAB_HAVE_MPI
269   moab::ErrorCode merr;
270   /* filter based on parallel status */
271   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned);
272   MBERRNM(merr);
273 
274   /* filter all the non-owned and shared entities out of the list */
275   tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
276   merr    = dmmoab->pcomm->filter_pstatus(tmpvtxs, PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost);
277   MBERRNM(merr);
278   tmpvtxs         = moab::subtract(tmpvtxs, *dmmoab->vghost);
279   *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs);
280 #else
281   *dmmoab->vowned = *dmmoab->vlocal;
282 #endif
283 
284   /* compute and cache the sizes of local and ghosted entities */
285   dmmoab->nloc   = dmmoab->vowned->size();
286   dmmoab->nghost = dmmoab->vghost->size();
287 #ifdef MOAB_HAVE_MPI
288   PetscCallMPI(MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
289 #else
290   dmmoab->n = dmmoab->nloc;
291 #endif
292   PetscFunctionReturn(PETSC_SUCCESS);
293 }
294 
295 /*@C
296   DMMoabGetAllVertices - Get the entities having DOFs on this `DMMOAB`
297 
298   Collective
299 
300   Input Parameter:
301 . dm - The `DMMOAB` object being set
302 
303   Output Parameter:
304 . local - The local vertex entities in this `DMMOAB` = (owned+ghosted)
305 
306   Level: beginner
307 
308 .seealso: `DMMOAB`, `DMMoabGetLocalVertices()`
309 @*/
DMMoabGetAllVertices(DM dm,moab::Range * local)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(PETSC_SUCCESS);
316 }
317 
318 /*@C
319   DMMoabGetLocalVertices - Get the entities having DOFs on this `DMMOAB`
320 
321   Collective
322 
323   Input Parameter:
324 . dm - The `DMMOAB` object being set
325 
326   Output Parameters:
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 .seealso: `DMMOAB`, `DMMoabGetAllVertices()`
333 @*/
DMMoabGetLocalVertices(DM dm,const moab::Range ** owned,const moab::Range ** ghost)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(PETSC_SUCCESS);
341 }
342 
343 /*@C
344   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
345 
346   Collective
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 .seealso: `DMMOAB`, `DMMoabSetLocalElements()`
357 @*/
DMMoabGetLocalElements(DM dm,const moab::Range ** range)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(PETSC_SUCCESS);
364 }
365 
366 /*@C
367   DMMoabSetLocalElements - Set the entities having DOFs on this `DMMOAB`
368 
369   Collective
370 
371   Input Parameters:
372 + dm    - The `DMMOAB` object being set
373 - range - The entities treated by this `DMMOAB`
374 
375   Level: beginner
376 
377 .seealso: `DMMOAB`, `DMMoabGetLocalElements()`
378 @*/
DMMoabSetLocalElements(DM dm,moab::Range * range)379 PetscErrorCode DMMoabSetLocalElements(DM dm, moab::Range *range)
380 {
381   DM_Moab *dmmoab = (DM_Moab *)dm->data;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
385   dmmoab->elocal->clear();
386   dmmoab->eghost->clear();
387   dmmoab->elocal->insert(range->begin(), range->end());
388 #ifdef MOAB_HAVE_MPI
389   moab::ErrorCode merr;
390   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT);
391   MBERRNM(merr);
392   *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal);
393 #endif
394   dmmoab->neleloc   = dmmoab->elocal->size();
395   dmmoab->neleghost = dmmoab->eghost->size();
396 #ifdef MOAB_HAVE_MPI
397   PetscCallMPI(MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
398   PetscCall(PetscInfo(dm, "Created %" PetscInt_FMT " local and %" PetscInt_FMT " global elements.\n", dmmoab->neleloc, dmmoab->nele));
399 #else
400   dmmoab->nele = dmmoab->neleloc;
401 #endif
402   PetscFunctionReturn(PETSC_SUCCESS);
403 }
404 
405 /*@C
406   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
407 
408   Collective
409 
410   Input Parameters:
411 + dm      - The `DMMOAB` object being set
412 - ltogtag - The `DMMOAB` tag used for local to global ids
413 
414   Level: beginner
415 
416 .seealso: `DMMOAB`, `DMMoabGetLocalToGlobalTag()`
417 @*/
DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)418 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm, moab::Tag ltogtag)
419 {
420   PetscFunctionBegin;
421   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
422   ((DM_Moab *)dm->data)->ltog_tag = ltogtag;
423   PetscFunctionReturn(PETSC_SUCCESS);
424 }
425 
426 /*@C
427   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
428 
429   Collective
430 
431   Input Parameter:
432 . dm - The `DMMOAB` object being set
433 
434   Output Parameter:
435 . ltog_tag - The MOAB tag used for local to global ids
436 
437   Level: beginner
438 
439 .seealso: `DMMOAB`, `DMMoabSetLocalToGlobalTag()`
440 @*/
DMMoabGetLocalToGlobalTag(DM dm,moab::Tag * ltog_tag)441 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm, moab::Tag *ltog_tag)
442 {
443   PetscFunctionBegin;
444   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
445   *ltog_tag = ((DM_Moab *)dm->data)->ltog_tag;
446   PetscFunctionReturn(PETSC_SUCCESS);
447 }
448 
449 /*@C
450   DMMoabSetBlockSize - Set the block size used with this `DMMOAB`
451 
452   Collective
453 
454   Input Parameters:
455 + dm - The `DMMOAB` object being set
456 - bs - The block size used with this `DMMOAB`
457 
458   Level: beginner
459 
460 .seealso: `DMMOAB`, `DMMoabGetBlockSize()`
461 @*/
DMMoabSetBlockSize(DM dm,PetscInt bs)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(PETSC_SUCCESS);
468 }
469 
470 /*@C
471   DMMoabGetBlockSize - Get the block size used with this `DMMOAB`
472 
473   Collective
474 
475   Input Parameter:
476 . dm - The `DMMOAB` object being set
477 
478   Output Parameter:
479 . bs - The block size used with this `DMMOAB`
480 
481   Level: beginner
482 
483 .seealso: `DMMOAB`, `DMMoabSetBlockSize()`
484 @*/
DMMoabGetBlockSize(DM dm,PetscInt * bs)485 PetscErrorCode DMMoabGetBlockSize(DM dm, PetscInt *bs)
486 {
487   PetscFunctionBegin;
488   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
489   *bs = ((DM_Moab *)dm->data)->bs;
490   PetscFunctionReturn(PETSC_SUCCESS);
491 }
492 
493 /*@C
494   DMMoabGetSize - Get the global vertex size used with this `DMMOAB`
495 
496   Collective
497 
498   Input Parameter:
499 . dm - The `DMMOAB` object being set
500 
501   Output Parameters:
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 .seealso: `DMMOAB`, `DMMoabGetLocalSize()`
508 @*/
DMMoabGetSize(DM dm,PetscInt * neg,PetscInt * nvg)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(PETSC_SUCCESS);
516 }
517 
518 /*@C
519   DMMoabGetLocalSize - Get the local and ghosted vertex size used with this `DMMOAB`
520 
521   Collective
522 
523   Input Parameter:
524 . dm - The `DMMOAB` object being set
525 
526   Output Parameters:
527 + nel - The number of owned elements in this processor
528 . neg - The number of ghosted elements in this processor
529 . nvl - The number of owned vertices in this processor
530 - nvg - The number of ghosted vertices in this processor
531 
532   Level: beginner
533 
534 .seealso: `DMMOAB`, `DMMoabGetSize()`
535 @*/
DMMoabGetLocalSize(DM dm,PetscInt * nel,PetscInt * neg,PetscInt * nvl,PetscInt * nvg)536 PetscErrorCode DMMoabGetLocalSize(DM dm, PetscInt *nel, PetscInt *neg, PetscInt *nvl, PetscInt *nvg)
537 {
538   PetscFunctionBegin;
539   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
540   if (nel) *nel = ((DM_Moab *)dm->data)->neleloc;
541   if (neg) *neg = ((DM_Moab *)dm->data)->neleghost;
542   if (nvl) *nvl = ((DM_Moab *)dm->data)->nloc;
543   if (nvg) *nvg = ((DM_Moab *)dm->data)->nghost;
544   PetscFunctionReturn(PETSC_SUCCESS);
545 }
546 
547 /*@C
548   DMMoabGetOffset - Get the local offset for the global vector
549 
550   Collective
551 
552   Input Parameter:
553 . dm - The `DMMOAB` object being set
554 
555   Output Parameter:
556 . offset - The local offset for the global vector
557 
558   Level: beginner
559 
560 .seealso: `DMMOAB`, `DMMoabGetDimension()`
561 @*/
DMMoabGetOffset(DM dm,PetscInt * offset)562 PetscErrorCode DMMoabGetOffset(DM dm, PetscInt *offset)
563 {
564   PetscFunctionBegin;
565   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
566   *offset = ((DM_Moab *)dm->data)->vstart;
567   PetscFunctionReturn(PETSC_SUCCESS);
568 }
569 
570 /*@C
571   DMMoabGetDimension - Get the dimension of the `DM` Mesh
572 
573   Collective
574 
575   Input Parameter:
576 . dm - The `DMMOAB` object
577 
578   Output Parameter:
579 . dim - The dimension of `DM`
580 
581   Level: beginner
582 
583 .seealso: `DMMOAB`, `DMMoabGetOffset()`
584 @*/
DMMoabGetDimension(DM dm,PetscInt * dim)585 PetscErrorCode DMMoabGetDimension(DM dm, PetscInt *dim)
586 {
587   PetscFunctionBegin;
588   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
589   *dim = ((DM_Moab *)dm->data)->dim;
590   PetscFunctionReturn(PETSC_SUCCESS);
591 }
592 
593 /*@C
594   DMMoabGetHierarchyLevel - Get the current level of the mesh hierarchy
595   generated through uniform refinement.
596 
597   Collective
598 
599   Input Parameter:
600 . dm - The `DMMOAB` object being set
601 
602   Output Parameter:
603 . nlevel - The current mesh hierarchy level
604 
605   Level: beginner
606 
607 .seealso: `DMMOAB`, `DMMoabGetMaterialBlock()`
608 @*/
DMMoabGetHierarchyLevel(DM dm,PetscInt * nlevel)609 PetscErrorCode DMMoabGetHierarchyLevel(DM dm, PetscInt *nlevel)
610 {
611   PetscFunctionBegin;
612   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
613   if (nlevel) *nlevel = ((DM_Moab *)dm->data)->hlevel;
614   PetscFunctionReturn(PETSC_SUCCESS);
615 }
616 
617 /*@C
618   DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh
619 
620   Collective
621 
622   Input Parameters:
623 + dm      - The `DMMOAB` object
624 - ehandle - The element entity handle
625 
626   Output Parameter:
627 . mat - The material ID for the current entity
628 
629   Level: beginner
630 
631 .seealso: `DMMOAB`, `DMMoabGetHierarchyLevel()`
632 @*/
DMMoabGetMaterialBlock(DM dm,const moab::EntityHandle ehandle,PetscInt * mat)633 PetscErrorCode DMMoabGetMaterialBlock(DM dm, const moab::EntityHandle ehandle, PetscInt *mat)
634 {
635   DM_Moab *dmmoab;
636 
637   PetscFunctionBegin;
638   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
639   if (*mat) {
640     dmmoab = (DM_Moab *)dm->data;
641     *mat   = dmmoab->materials[dmmoab->elocal->index(ehandle)];
642   }
643   PetscFunctionReturn(PETSC_SUCCESS);
644 }
645 
646 /*@C
647   DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities
648 
649   Collective
650 
651   Input Parameters:
652 + dm    - The `DMMOAB` object
653 . nconn - Number of entities whose coordinates are needed
654 - conn  - The vertex entity handles
655 
656   Output Parameter:
657 . vpos - The coordinates of the requested vertex entities
658 
659   Level: beginner
660 
661 .seealso: `DMMOAB`, `DMMoabGetVertexConnectivity()`
662 @*/
DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle * conn,PetscReal * vpos)663 PetscErrorCode DMMoabGetVertexCoordinates(DM dm, PetscInt nconn, const moab::EntityHandle *conn, PetscReal *vpos)
664 {
665   DM_Moab        *dmmoab;
666   moab::ErrorCode merr;
667 
668   PetscFunctionBegin;
669   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
670   PetscAssertPointer(conn, 3);
671   PetscAssertPointer(vpos, 4);
672   dmmoab = (DM_Moab *)dm->data;
673 
674   /* Get connectivity information in MOAB canonical ordering */
675   if (dmmoab->hlevel) {
676     merr = dmmoab->hierarchy->get_coordinates(const_cast<moab::EntityHandle *>(conn), nconn, dmmoab->hlevel, vpos);
677     MBERRNM(merr);
678   } else {
679     merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);
680     MBERRNM(merr);
681   }
682   PetscFunctionReturn(PETSC_SUCCESS);
683 }
684 
685 /*@C
686   DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity
687 
688   Collective
689 
690   Input Parameters:
691 + dm      - The `DMMOAB` object
692 - vhandle - Vertex entity handle
693 
694   Output Parameters:
695 + nconn - Number of entities whose coordinates are needed
696 - conn  - The vertex entity handles
697 
698   Level: beginner
699 
700 .seealso: `DMMOAB`, `DMMoabGetVertexCoordinates()`, `DMMoabRestoreVertexConnectivity()`
701 @*/
DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle vhandle,PetscInt * nconn,moab::EntityHandle ** conn)702 PetscErrorCode DMMoabGetVertexConnectivity(DM dm, moab::EntityHandle vhandle, PetscInt *nconn, moab::EntityHandle **conn)
703 {
704   DM_Moab                        *dmmoab;
705   std::vector<moab::EntityHandle> adj_entities, connect;
706   moab::ErrorCode                 merr;
707 
708   PetscFunctionBegin;
709   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
710   PetscAssertPointer(conn, 4);
711   dmmoab = (DM_Moab *)dm->data;
712 
713   /* Get connectivity information in MOAB canonical ordering */
714   merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION);
715   MBERRNM(merr);
716   merr = dmmoab->mbiface->get_connectivity(&adj_entities[0], adj_entities.size(), connect);
717   MBERRNM(merr);
718 
719   if (conn) {
720     PetscCall(PetscMalloc(sizeof(moab::EntityHandle) * connect.size(), conn));
721     PetscCall(PetscArraycpy(*conn, &connect[0], connect.size()));
722   }
723   if (nconn) *nconn = connect.size();
724   PetscFunctionReturn(PETSC_SUCCESS);
725 }
726 
727 /*@C
728   DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity
729 
730   Collective
731 
732   Input Parameters:
733 + dm      - The `DMMOAB` object
734 . ehandle - Vertex entity handle
735 . nconn   - Number of entities whose coordinates are needed
736 - conn    - The vertex entity handles
737 
738   Level: beginner
739 
740 .seealso: `DMMOAB`, `DMMoabGetVertexCoordinates()`, `DMMoabGetVertexConnectivity()`
741 @*/
DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt * nconn,moab::EntityHandle ** conn)742 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt *nconn, moab::EntityHandle **conn)
743 {
744   PetscFunctionBegin;
745   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
746   PetscAssertPointer(conn, 4);
747 
748   if (conn) PetscCall(PetscFree(*conn));
749   if (nconn) *nconn = 0;
750   PetscFunctionReturn(PETSC_SUCCESS);
751 }
752 
753 /*@C
754   DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity
755 
756   Collective
757 
758   Input Parameters:
759 + dm      - The `DMMOAB` object
760 - ehandle - Vertex entity handle
761 
762   Output Parameters:
763 + nconn - Number of entities whose coordinates are needed
764 - conn  - The vertex entity handles
765 
766   Level: beginner
767 
768 .seealso: `DMMOAB`, `DMMoabGetVertexCoordinates()`, `DMMoabGetVertexConnectivity()`, `DMMoabRestoreVertexConnectivity()`
769 @*/
DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt * nconn,const moab::EntityHandle ** conn)770 PetscErrorCode DMMoabGetElementConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt *nconn, const moab::EntityHandle **conn)
771 {
772   DM_Moab                        *dmmoab;
773   const moab::EntityHandle       *connect;
774   std::vector<moab::EntityHandle> vconn;
775   moab::ErrorCode                 merr;
776   PetscInt                        nnodes;
777 
778   PetscFunctionBegin;
779   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
780   PetscAssertPointer(conn, 4);
781   dmmoab = (DM_Moab *)dm->data;
782 
783   /* Get connectivity information in MOAB canonical ordering */
784   merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);
785   MBERRNM(merr);
786   if (conn) *conn = connect;
787   if (nconn) *nconn = nnodes;
788   PetscFunctionReturn(PETSC_SUCCESS);
789 }
790 
791 /*@C
792   DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element)
793 
794   Collective
795 
796   Input Parameters:
797 + dm  - The `DMMOAB` object
798 - ent - Entity handle
799 
800   Output Parameter:
801 . ent_on_boundary - `PETSC_TRUE` if entity on boundary; `PETSC_FALSE` otherwise
802 
803   Level: beginner
804 
805 .seealso: `DMMOAB`, `DMMoabCheckBoundaryVertices()`
806 @*/
DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool * ent_on_boundary)807 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm, const moab::EntityHandle ent, PetscBool *ent_on_boundary)
808 {
809   moab::EntityType etype;
810   DM_Moab         *dmmoab;
811   PetscInt         edim;
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
815   PetscAssertPointer(ent_on_boundary, 3);
816   dmmoab = (DM_Moab *)dm->data;
817 
818   /* get the entity type and handle accordingly */
819   etype = dmmoab->mbiface->type_from_handle(ent);
820   PetscCheck(etype < moab::MBPOLYHEDRON, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %" PetscInt_FMT, etype);
821 
822   /* get the entity dimension */
823   edim = dmmoab->mbiface->dimension_from_handle(ent);
824 
825   *ent_on_boundary = PETSC_FALSE;
826   if (etype == moab::MBVERTEX && edim == 0) {
827     *ent_on_boundary = ((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE : PETSC_FALSE);
828   } else {
829     if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */
830       if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE;
831     } else { /* next check the lower-dimensional faces */
832       if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE;
833     }
834   }
835   PetscFunctionReturn(PETSC_SUCCESS);
836 }
837 
838 /*@C
839   DMMoabCheckBoundaryVertices - Check whether a given entity is on the boundary (vertex, edge, face, element)
840 
841   Input Parameters:
842 + dm    - The `DMMOAB` object
843 . nconn - Number of handles
844 - cnt   - Array of entity handles
845 
846   Output Parameter:
847 . isbdvtx - Array of boundary markers - `PETSC_TRUE` if entity on boundary; `PETSC_FALSE` otherwise
848 
849   Level: beginner
850 
851 .seealso: `DMMOAB`, `DMMoabIsEntityOnBoundary()`
852 @*/
DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle * cnt,PetscBool * isbdvtx)853 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm, PetscInt nconn, const moab::EntityHandle *cnt, PetscBool *isbdvtx)
854 {
855   DM_Moab *dmmoab;
856   PetscInt i;
857 
858   PetscFunctionBegin;
859   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
860   PetscAssertPointer(cnt, 3);
861   PetscAssertPointer(isbdvtx, 4);
862   dmmoab = (DM_Moab *)dm->data;
863 
864   for (i = 0; i < nconn; ++i) isbdvtx[i] = (dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE : PETSC_FALSE);
865   PetscFunctionReturn(PETSC_SUCCESS);
866 }
867 
868 /*@C
869   DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary
870 
871   Input Parameter:
872 . dm - The `DMMOAB` object
873 
874   Output Parameters:
875 + bdvtx   - Boundary vertices
876 . bdelems - Boundary elements
877 - bdfaces - Boundary faces
878 
879   Level: beginner
880 
881 .seealso: `DMMOAB`, `DMMoabCheckBoundaryVertices()`, `DMMoabIsEntityOnBoundary()`
882 @*/
DMMoabGetBoundaryMarkers(DM dm,const moab::Range ** bdvtx,const moab::Range ** bdelems,const moab::Range ** bdfaces)883 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm, const moab::Range **bdvtx, const moab::Range **bdelems, const moab::Range **bdfaces)
884 {
885   DM_Moab *dmmoab;
886 
887   PetscFunctionBegin;
888   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
889   dmmoab = (DM_Moab *)dm->data;
890 
891   if (bdvtx) *bdvtx = dmmoab->bndyvtx;
892   if (bdfaces) *bdfaces = dmmoab->bndyfaces;
893   if (bdelems) *bdfaces = dmmoab->bndyelems;
894   PetscFunctionReturn(PETSC_SUCCESS);
895 }
896 
DMDestroy_Moab(DM dm)897 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm)
898 {
899   PetscInt        i;
900   moab::ErrorCode merr;
901   DM_Moab        *dmmoab = (DM_Moab *)dm->data;
902 
903   PetscFunctionBegin;
904   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
905 
906   dmmoab->refct--;
907   if (!dmmoab->refct) {
908     delete dmmoab->vlocal;
909     delete dmmoab->vowned;
910     delete dmmoab->vghost;
911     delete dmmoab->elocal;
912     delete dmmoab->eghost;
913     delete dmmoab->bndyvtx;
914     delete dmmoab->bndyfaces;
915     delete dmmoab->bndyelems;
916 
917     PetscCall(PetscFree(dmmoab->gsindices));
918     PetscCall(PetscFree2(dmmoab->gidmap, dmmoab->lidmap));
919     PetscCall(PetscFree(dmmoab->dfill));
920     PetscCall(PetscFree(dmmoab->ofill));
921     PetscCall(PetscFree(dmmoab->materials));
922     if (dmmoab->fieldNames) {
923       for (i = 0; i < dmmoab->numFields; i++) PetscCall(PetscFree(dmmoab->fieldNames[i]));
924       PetscCall(PetscFree(dmmoab->fieldNames));
925     }
926 
927     if (dmmoab->nhlevels) {
928       PetscCall(PetscFree(dmmoab->hsets));
929       dmmoab->nhlevels = 0;
930       if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy;
931       dmmoab->hierarchy = NULL;
932     }
933 
934     if (dmmoab->icreatedinstance) {
935       delete dmmoab->pcomm;
936       merr = dmmoab->mbiface->delete_mesh();
937       MBERRNM(merr);
938       delete dmmoab->mbiface;
939     }
940     dmmoab->mbiface = NULL;
941 #ifdef MOAB_HAVE_MPI
942     dmmoab->pcomm = NULL;
943 #endif
944     PetscCall(VecScatterDestroy(&dmmoab->ltog_sendrecv));
945     PetscCall(ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map));
946     PetscCall(PetscFree(dm->data));
947   }
948   PetscFunctionReturn(PETSC_SUCCESS);
949 }
950 
DMSetFromOptions_Moab(DM dm,PetscOptionItems PetscOptionsObject)951 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(DM dm, PetscOptionItems PetscOptionsObject)
952 {
953   DM_Moab *dmmoab = (DM_Moab *)dm->data;
954 
955   PetscFunctionBegin;
956   PetscOptionsHeadBegin(PetscOptionsObject, "DMMoab Options");
957   PetscCall(PetscOptionsBoundedInt("-dm_moab_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "DMView", dmmoab->rw_dbglevel, &dmmoab->rw_dbglevel, NULL, 0));
958   PetscCall(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));
959   /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */
960   PetscCall(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, sizeof(dmmoab->extra_read_options), NULL));
961   PetscCall(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, sizeof(dmmoab->extra_write_options), NULL));
962   PetscCall(PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum *)&dmmoab->read_mode, NULL));
963   PetscCall(PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum *)&dmmoab->write_mode, NULL));
964   PetscOptionsHeadEnd();
965   PetscFunctionReturn(PETSC_SUCCESS);
966 }
967 
DMSetUp_Moab(DM dm)968 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm)
969 {
970   moab::ErrorCode       merr;
971   Vec                   local, global;
972   IS                    from, to;
973   moab::Range::iterator iter;
974   PetscInt              i, j, f, bs, vent, totsize, *lgmap;
975   DM_Moab              *dmmoab = (DM_Moab *)dm->data;
976   moab::Range           adjs;
977 
978   PetscFunctionBegin;
979   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
980   /* Get the local and shared vertices and cache it */
981   PetscCheck(dmmoab->mbiface != NULL, PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp.");
982 #ifdef MOAB_HAVE_MPI
983   PetscCheck(dmmoab->pcomm != NULL, PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp.");
984 #endif
985 
986   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
987   if (dmmoab->vlocal->empty()) {
988     //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
989     merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false);
990     MBERRNM(merr);
991 
992 #ifdef MOAB_HAVE_MPI
993     /* filter based on parallel status */
994     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned);
995     MBERRNM(merr);
996 
997     /* filter all the non-owned and shared entities out of the list */
998     // *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
999     adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
1000     merr = dmmoab->pcomm->filter_pstatus(adjs, PSTATUS_GHOST | PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost);
1001     MBERRNM(merr);
1002     adjs            = moab::subtract(adjs, *dmmoab->vghost);
1003     *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs);
1004 #else
1005     *dmmoab->vowned = *dmmoab->vlocal;
1006 #endif
1007 
1008     /* compute and cache the sizes of local and ghosted entities */
1009     dmmoab->nloc   = dmmoab->vowned->size();
1010     dmmoab->nghost = dmmoab->vghost->size();
1011 
1012 #ifdef MOAB_HAVE_MPI
1013     PetscCallMPI(MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
1014     PetscCall(PetscInfo(NULL, "Filset ID: %lu, Vertices: local - %zu, owned - %" PetscInt_FMT ", ghosted - %" PetscInt_FMT ".\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost));
1015 #else
1016     dmmoab->n = dmmoab->nloc;
1017 #endif
1018   }
1019 
1020   {
1021     /* get the information about the local elements in the mesh */
1022     dmmoab->eghost->clear();
1023 
1024     /* first decipher the leading dimension */
1025     for (i = 3; i > 0; i--) {
1026       dmmoab->elocal->clear();
1027       merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false);
1028       MBERRNM(merr);
1029 
1030       /* store the current mesh dimension */
1031       if (dmmoab->elocal->size()) {
1032         dmmoab->dim = i;
1033         break;
1034       }
1035     }
1036 
1037     PetscCall(DMSetDimension(dm, dmmoab->dim));
1038 
1039 #ifdef MOAB_HAVE_MPI
1040     /* filter the ghosted and owned element list */
1041     *dmmoab->eghost = *dmmoab->elocal;
1042     merr            = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1043     MBERRNM(merr);
1044     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
1045 #endif
1046 
1047     dmmoab->neleloc   = dmmoab->elocal->size();
1048     dmmoab->neleghost = dmmoab->eghost->size();
1049 
1050 #ifdef MOAB_HAVE_MPI
1051     PetscCallMPI(MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm));
1052     PetscCall(PetscInfo(NULL, "%d-dim elements: owned - %" PetscInt_FMT ", ghosted - %" PetscInt_FMT ".\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost));
1053 #else
1054     dmmoab->nele = dmmoab->neleloc;
1055 #endif
1056   }
1057 
1058   bs = dmmoab->bs;
1059   if (!dmmoab->ltog_tag) {
1060     /* Get the global ID tag. The global ID tag is applied to each
1061        vertex. It acts as an global identifier which MOAB uses to
1062        assemble the individual pieces of the mesh */
1063     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);
1064     MBERRNM(merr);
1065   }
1066 
1067   totsize = dmmoab->vlocal->size();
1068   PetscCheck(totsize == dmmoab->nloc + dmmoab->nghost, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mismatch between local and owned+ghost vertices. %" PetscInt_FMT " != %" PetscInt_FMT ".", totsize, dmmoab->nloc + dmmoab->nghost);
1069   PetscCall(PetscCalloc1(totsize, &dmmoab->gsindices));
1070   {
1071     /* first get the local indices */
1072     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vowned, &dmmoab->gsindices[0]);
1073     MBERRNM(merr);
1074     if (dmmoab->nghost) { /* next get the ghosted indices */
1075       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vghost, &dmmoab->gsindices[dmmoab->nloc]);
1076       MBERRNM(merr);
1077     }
1078 
1079     /* find out the local and global minima of GLOBAL_ID */
1080     dmmoab->lminmax[0] = dmmoab->lminmax[1] = dmmoab->gsindices[0];
1081     for (i = 0; i < totsize; ++i) {
1082       if (dmmoab->lminmax[0] > dmmoab->gsindices[i]) dmmoab->lminmax[0] = dmmoab->gsindices[i];
1083       if (dmmoab->lminmax[1] < dmmoab->gsindices[i]) dmmoab->lminmax[1] = dmmoab->gsindices[i];
1084     }
1085 
1086     PetscCallMPI(MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm));
1087     PetscCallMPI(MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm));
1088 
1089     /* set the GID map */
1090     for (i = 0; i < totsize; ++i) dmmoab->gsindices[i] -= dmmoab->gminmax[0]; /* zero based index needed for IS */
1091     dmmoab->lminmax[0] -= dmmoab->gminmax[0];
1092     dmmoab->lminmax[1] -= dmmoab->gminmax[0];
1093 
1094     PetscCall(PetscInfo(NULL, "GLOBAL_ID: Local [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "], Global [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "]\n", dmmoab->lminmax[0], dmmoab->lminmax[1], dmmoab->gminmax[0], dmmoab->gminmax[1]));
1095   }
1096   PetscCheck(dmmoab->bs == dmmoab->numFields || dmmoab->bs == 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between block size and number of component fields. %" PetscInt_FMT " != 1 OR %" PetscInt_FMT " != %" PetscInt_FMT ".", dmmoab->bs, dmmoab->bs,
1097              dmmoab->numFields);
1098 
1099   {
1100     dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front());
1101     dmmoab->seqend   = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back());
1102     PetscCall(PetscInfo(NULL, "SEQUENCE: Local [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "]\n", dmmoab->seqstart, dmmoab->seqend));
1103 
1104     PetscCall(PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap));
1105     PetscCall(PetscMalloc1(totsize * dmmoab->numFields, &lgmap));
1106 
1107     i = j = 0;
1108     /* set the owned vertex data first */
1109     for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) {
1110       vent                 = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart;
1111       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1112       dmmoab->lidmap[vent] = i;
1113       for (f = 0; f < dmmoab->numFields; f++, j++) lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1114     }
1115     /* next arrange all the ghosted data information */
1116     for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) {
1117       vent                 = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart;
1118       dmmoab->gidmap[vent] = dmmoab->gsindices[i];
1119       dmmoab->lidmap[vent] = i;
1120       for (f = 0; f < dmmoab->numFields; f++, j++) lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]);
1121     }
1122 
1123     /* We need to create the Global to Local Vector Scatter Contexts
1124        1) First create a local and global vector
1125        2) Create a local and global IS
1126        3) Create VecScatter and LtoGMapping objects
1127        4) Cleanup the IS and Vec objects
1128     */
1129     PetscCall(DMCreateGlobalVector(dm, &global));
1130     PetscCall(DMCreateLocalVector(dm, &local));
1131 
1132     PetscCall(VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend));
1133 
1134     /* global to local must retrieve ghost points */
1135     PetscCall(ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from));
1136     PetscCall(ISSetBlockSize(from, bs));
1137 
1138     PetscCall(ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to));
1139     PetscCall(ISSetBlockSize(to, bs));
1140 
1141     if (!dmmoab->ltog_map) {
1142       /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */
1143       PetscCall(ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap, PETSC_COPY_VALUES, &dmmoab->ltog_map));
1144     }
1145 
1146     /* now create the scatter object from local to global vector */
1147     PetscCall(VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv));
1148 
1149     /* clean up IS, Vec */
1150     PetscCall(PetscFree(lgmap));
1151     PetscCall(ISDestroy(&from));
1152     PetscCall(ISDestroy(&to));
1153     PetscCall(VecDestroy(&local));
1154     PetscCall(VecDestroy(&global));
1155   }
1156 
1157   dmmoab->bndyvtx   = new moab::Range();
1158   dmmoab->bndyfaces = new moab::Range();
1159   dmmoab->bndyelems = new moab::Range();
1160   /* skin the boundary and store nodes */
1161   if (!dmmoab->hlevel) {
1162     /* get the skin vertices of boundary faces for the current partition and then filter
1163        the local, boundary faces, vertices and elements alone via PSTATUS flags;
1164        this should not give us any ghosted boundary, but if user needs such a functionality
1165        it would be easy to add it based on the find_skin query below */
1166     moab::Skinner skinner(dmmoab->mbiface);
1167 
1168     /* get the entities on the skin - only the faces */
1169     merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces, NULL, true, true, false);
1170     MBERRNM(merr); // 'false' param indicates we want faces back, not vertices
1171 
1172 #ifdef MOAB_HAVE_MPI
1173     /* filter all the non-owned and shared entities out of the list */
1174     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1175     MBERRNM(merr);
1176     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT);
1177     MBERRNM(merr);
1178 #endif
1179 
1180     /* get all the nodes via connectivity and the parent elements via adjacency information */
1181     merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);
1182     MBERRNM(merr);
1183     merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);
1184     MBERRNM(merr);
1185   } else {
1186     /* Let us query the hierarchy manager and get the results directly for this level */
1187     for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) {
1188       moab::EntityHandle elemHandle = *iter;
1189       if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) {
1190         dmmoab->bndyelems->insert(elemHandle);
1191         /* For this boundary element, query the vertices and add them to the list */
1192         std::vector<moab::EntityHandle> connect;
1193         merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect);
1194         MBERRNM(merr);
1195         for (unsigned iv = 0; iv < connect.size(); ++iv)
1196           if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv])) dmmoab->bndyvtx->insert(connect[iv]);
1197         /* Next, let us query the boundary faces and add them also to the list */
1198         std::vector<moab::EntityHandle> faces;
1199         merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim - 1, faces);
1200         MBERRNM(merr);
1201         for (unsigned ifa = 0; ifa < faces.size(); ++ifa)
1202           if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa])) dmmoab->bndyfaces->insert(faces[ifa]);
1203       }
1204     }
1205 #ifdef MOAB_HAVE_MPI
1206     /* filter all the non-owned and shared entities out of the list */
1207     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1208     MBERRNM(merr);
1209     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1210     MBERRNM(merr);
1211     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1212     MBERRNM(merr);
1213 #endif
1214   }
1215   PetscCall(PetscInfo(NULL, "Found %zu boundary vertices, %zu boundary faces and %zu boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()));
1216 
1217   /* Get the material sets and populate the data for all locally owned elements */
1218   {
1219     PetscCall(PetscCalloc1(dmmoab->elocal->size(), &dmmoab->materials));
1220     /* Get the count of entities of particular type from dmmoab->elocal
1221        -- Then, for each non-zero type, loop through and query the fileset to get the material tag data */
1222     moab::Range msets;
1223     merr = dmmoab->mbiface->get_entities_by_type_and_tag(dmmoab->fileset, moab::MBENTITYSET, &dmmoab->material_tag, NULL, 1, msets, moab::Interface::UNION);
1224     MBERRNM(merr);
1225     if (msets.size() == 0) PetscCall(PetscInfo(NULL, "No material sets found in the fileset.\n"));
1226 
1227     for (unsigned i = 0; i < msets.size(); ++i) {
1228       moab::Range msetelems;
1229       merr = dmmoab->mbiface->get_entities_by_dimension(msets[i], dmmoab->dim, msetelems, true);
1230       MBERRNM(merr);
1231 #ifdef MOAB_HAVE_MPI
1232       /* filter all the non-owned and shared entities out of the list */
1233       merr = dmmoab->pcomm->filter_pstatus(msetelems, PSTATUS_NOT_OWNED, PSTATUS_NOT);
1234       MBERRNM(merr);
1235 #endif
1236 
1237       int                partID;
1238       moab::EntityHandle mset = msets[i];
1239       merr                    = dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &mset, 1, &partID);
1240       MBERRNM(merr);
1241 
1242       for (unsigned j = 0; j < msetelems.size(); ++j) dmmoab->materials[dmmoab->elocal->index(msetelems[j])] = partID;
1243     }
1244   }
1245   PetscFunctionReturn(PETSC_SUCCESS);
1246 }
1247 
1248 /*@C
1249   DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM.
1250 
1251   Collective
1252 
1253   Input Parameters:
1254 + dm     - The `DM` object
1255 . coords - The connectivity of the element
1256 - nverts - The number of vertices that form the element
1257 
1258   Output Parameter:
1259 . overts - The list of vertices that were created (can be `NULL`)
1260 
1261   Level: beginner
1262 
1263 .seealso: `DMMOAB`, `DMMoabCreateSubmesh()`, `DMMoabCreateElement()`
1264 @*/
DMMoabCreateVertices(DM dm,const PetscReal * coords,PetscInt nverts,moab::Range * overts)1265 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal *coords, PetscInt nverts, moab::Range *overts)
1266 {
1267   moab::ErrorCode merr;
1268   DM_Moab        *dmmoab;
1269   moab::Range     verts;
1270 
1271   PetscFunctionBegin;
1272   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1273   PetscAssertPointer(coords, 2);
1274 
1275   dmmoab = (DM_Moab *)dm->data;
1276 
1277   /* Insert new points */
1278   merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts);
1279   MBERRNM(merr);
1280   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts);
1281   MBERRNM(merr);
1282 
1283   if (overts) *overts = verts;
1284   PetscFunctionReturn(PETSC_SUCCESS);
1285 }
1286 
1287 /*@C
1288   DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM.
1289 
1290   Collective
1291 
1292   Input Parameters:
1293 + dm     - The DM object
1294 . type   - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra)
1295 . conn   - The connectivity of the element
1296 - nverts - The number of vertices that form the element
1297 
1298   Output Parameter:
1299 . oelem - The handle to the element created and added to the `DM` object
1300 
1301   Level: beginner
1302 
1303 .seealso: `DMMOAB`, `DMMoabCreateSubmesh()`, `DMMoabCreateVertices()`
1304 @*/
DMMoabCreateElement(DM dm,const moab::EntityType type,const moab::EntityHandle * conn,PetscInt nverts,moab::EntityHandle * oelem)1305 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle *conn, PetscInt nverts, moab::EntityHandle *oelem)
1306 {
1307   moab::ErrorCode    merr;
1308   DM_Moab           *dmmoab;
1309   moab::EntityHandle elem;
1310 
1311   PetscFunctionBegin;
1312   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1313   PetscAssertPointer(conn, 3);
1314 
1315   dmmoab = (DM_Moab *)dm->data;
1316 
1317   /* Insert new element */
1318   merr = dmmoab->mbiface->create_element(type, conn, nverts, elem);
1319   MBERRNM(merr);
1320   merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1);
1321   MBERRNM(merr);
1322 
1323   if (oelem) *oelem = elem;
1324   PetscFunctionReturn(PETSC_SUCCESS);
1325 }
1326 
1327 /*@C
1328   DMMoabCreateSubmesh - Creates a sub-`DM` object with a set that contains all vertices/elements of the parent
1329   in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to
1330   create a DM object on a refined level.
1331 
1332   Collective
1333 
1334   Input Parameters:
1335 . dm - The `DM` object
1336 
1337   Output Parameter:
1338 . newdm - The sub `DM` object with updated set information
1339 
1340   Level: advanced
1341 
1342 .seealso: `DMMOAB`, `DMCreate()`, `DMMoabCreateVertices()`, `DMMoabCreateElement()`
1343 @*/
DMMoabCreateSubmesh(DM dm,DM * newdm)1344 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm)
1345 {
1346   DM_Moab        *dmmoab;
1347   DM_Moab        *ndmmoab;
1348   moab::ErrorCode merr;
1349 
1350   PetscFunctionBegin;
1351   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1352 
1353   dmmoab = (DM_Moab *)dm->data;
1354 
1355   /* Create the basic DMMOAB object and keep the default parameters created by DM impls */
1356   PetscCall(DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, NULL, newdm));
1357 
1358   /* get all the necessary handles from the private DM object */
1359   ndmmoab = (DM_Moab *)(*newdm)->data;
1360 
1361   /* set the sub-mesh's parent DM reference */
1362   ndmmoab->parent = &dm;
1363 
1364   /* create a file set to associate all entities in current mesh */
1365   merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset);
1366   MBERR("Creating file set failed", merr);
1367 
1368   /* create a meshset and then add old fileset as child */
1369   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal);
1370   MBERR("Adding child vertices to parent failed", merr);
1371   merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal);
1372   MBERR("Adding child elements to parent failed", merr);
1373 
1374   /* preserve the field association between the parent and sub-mesh objects */
1375   PetscCall(DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames));
1376   PetscFunctionReturn(PETSC_SUCCESS);
1377 }
1378 
DMMoabView_Ascii(DM dm,PetscViewer viewer)1379 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer)
1380 {
1381   DM_Moab    *dmmoab = (DM_Moab *)dm->data;
1382   const char *name;
1383   MPI_Comm    comm;
1384   PetscMPIInt size;
1385 
1386   PetscFunctionBegin;
1387   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
1388   PetscCallMPI(MPI_Comm_size(comm, &size));
1389   PetscCall(PetscObjectGetName((PetscObject)dm, &name));
1390   PetscCall(PetscViewerASCIIPushTab(viewer));
1391   if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "%s in %" PetscInt_FMT " dimensions:\n", name, dmmoab->dim));
1392   else PetscCall(PetscViewerASCIIPrintf(viewer, "Mesh in %" PetscInt_FMT " dimensions:\n", dmmoab->dim));
1393   /* print details about the global mesh */
1394   {
1395     PetscCall(PetscViewerASCIIPushTab(viewer));
1396     PetscCall(PetscViewerASCIIPrintf(viewer, "Sizes: cells=%" PetscInt_FMT ", vertices=%" PetscInt_FMT ", blocks=%" PetscInt_FMT "\n", dmmoab->nele, dmmoab->n, dmmoab->bs));
1397     /* print boundary data */
1398     PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary trace:\n"));
1399     {
1400       PetscCall(PetscViewerASCIIPushTab(viewer));
1401       PetscCall(PetscViewerASCIIPrintf(viewer, "cells=%zu, faces=%zu, vertices=%zu\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size()));
1402       PetscCall(PetscViewerASCIIPopTab(viewer));
1403     }
1404     /* print field data */
1405     PetscCall(PetscViewerASCIIPrintf(viewer, "Fields: %" PetscInt_FMT " components\n", dmmoab->numFields));
1406     {
1407       PetscCall(PetscViewerASCIIPushTab(viewer));
1408       for (int i = 0; i < dmmoab->numFields; ++i) PetscCall(PetscViewerASCIIPrintf(viewer, "[%" PetscInt_FMT "] - %s\n", i, dmmoab->fieldNames[i]));
1409       PetscCall(PetscViewerASCIIPopTab(viewer));
1410     }
1411     PetscCall(PetscViewerASCIIPopTab(viewer));
1412   }
1413   PetscCall(PetscViewerASCIIPopTab(viewer));
1414   PetscCall(PetscViewerFlush(viewer));
1415   PetscFunctionReturn(PETSC_SUCCESS);
1416 }
1417 
DMMoabView_VTK(DM dm,PetscViewer v)1418 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v)
1419 {
1420   PetscFunctionReturn(PETSC_SUCCESS);
1421 }
1422 
DMMoabView_HDF5(DM dm,PetscViewer v)1423 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v)
1424 {
1425   PetscFunctionReturn(PETSC_SUCCESS);
1426 }
1427 
DMView_Moab(DM dm,PetscViewer viewer)1428 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer)
1429 {
1430   PetscBool isascii, ishdf5, isvtk;
1431 
1432   PetscFunctionBegin;
1433   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1434   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1435   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
1436   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk));
1437   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1438   if (isascii) {
1439     PetscCall(DMMoabView_Ascii(dm, viewer));
1440   } else if (ishdf5) {
1441 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5)
1442     PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ));
1443     PetscCall(DMMoabView_HDF5(dm, viewer));
1444     PetscCall(PetscViewerPopFormat(viewer));
1445 #else
1446     SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1447 #endif
1448   } else if (isvtk) PetscCall(DMMoabView_VTK(dm, viewer));
1449   PetscFunctionReturn(PETSC_SUCCESS);
1450 }
1451 
DMInitialize_Moab(DM dm)1452 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm)
1453 {
1454   PetscFunctionBegin;
1455   dm->ops->view                     = DMView_Moab;
1456   dm->ops->load                     = NULL /* DMLoad_Moab */;
1457   dm->ops->setfromoptions           = DMSetFromOptions_Moab;
1458   dm->ops->clone                    = DMClone_Moab;
1459   dm->ops->setup                    = DMSetUp_Moab;
1460   dm->ops->createlocalsection       = NULL;
1461   dm->ops->createsectionpermutation = NULL;
1462   dm->ops->createdefaultconstraints = NULL;
1463   dm->ops->createglobalvector       = DMCreateGlobalVector_Moab;
1464   dm->ops->createlocalvector        = DMCreateLocalVector_Moab;
1465   dm->ops->getlocaltoglobalmapping  = NULL;
1466   dm->ops->createfieldis            = NULL;
1467   dm->ops->createcoordinatedm       = NULL /* DMCreateCoordinateDM_Moab */;
1468   dm->ops->createcellcoordinatedm   = NULL;
1469   dm->ops->getcoloring              = NULL;
1470   dm->ops->creatematrix             = DMCreateMatrix_Moab;
1471   dm->ops->createinterpolation      = DMCreateInterpolation_Moab;
1472   dm->ops->createinjection          = NULL /* DMCreateInjection_Moab */;
1473   dm->ops->refine                   = DMRefine_Moab;
1474   dm->ops->coarsen                  = DMCoarsen_Moab;
1475   dm->ops->refinehierarchy          = DMRefineHierarchy_Moab;
1476   dm->ops->coarsenhierarchy         = DMCoarsenHierarchy_Moab;
1477   dm->ops->globaltolocalbegin       = DMGlobalToLocalBegin_Moab;
1478   dm->ops->globaltolocalend         = DMGlobalToLocalEnd_Moab;
1479   dm->ops->localtoglobalbegin       = DMLocalToGlobalBegin_Moab;
1480   dm->ops->localtoglobalend         = DMLocalToGlobalEnd_Moab;
1481   dm->ops->destroy                  = DMDestroy_Moab;
1482   dm->ops->createsubdm              = NULL /* DMCreateSubDM_Moab */;
1483   dm->ops->getdimpoints             = NULL /* DMGetDimPoints_Moab */;
1484   dm->ops->locatepoints             = NULL /* DMLocatePoints_Moab */;
1485   PetscFunctionReturn(PETSC_SUCCESS);
1486 }
1487 
DMClone_Moab(DM dm,DM * newdm)1488 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm)
1489 {
1490   PetscFunctionBegin;
1491   /* get all the necessary handles from the private DM object */
1492   (*newdm)->data = (DM_Moab *)dm->data;
1493   ((DM_Moab *)dm->data)->refct++;
1494 
1495   PetscCall(PetscObjectChangeTypeName((PetscObject)*newdm, DMMOAB));
1496   PetscCall(DMInitialize_Moab(*newdm));
1497   PetscFunctionReturn(PETSC_SUCCESS);
1498 }
1499 
DMCreate_Moab(DM dm)1500 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
1501 {
1502   PetscFunctionBegin;
1503   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1504   PetscCall(PetscNew((DM_Moab **)&dm->data));
1505 
1506   ((DM_Moab *)dm->data)->bs            = 1;
1507   ((DM_Moab *)dm->data)->numFields     = 1;
1508   ((DM_Moab *)dm->data)->n             = 0;
1509   ((DM_Moab *)dm->data)->nloc          = 0;
1510   ((DM_Moab *)dm->data)->nghost        = 0;
1511   ((DM_Moab *)dm->data)->nele          = 0;
1512   ((DM_Moab *)dm->data)->neleloc       = 0;
1513   ((DM_Moab *)dm->data)->neleghost     = 0;
1514   ((DM_Moab *)dm->data)->ltog_map      = NULL;
1515   ((DM_Moab *)dm->data)->ltog_sendrecv = NULL;
1516 
1517   ((DM_Moab *)dm->data)->refct  = 1;
1518   ((DM_Moab *)dm->data)->parent = NULL;
1519   ((DM_Moab *)dm->data)->vlocal = new moab::Range();
1520   ((DM_Moab *)dm->data)->vowned = new moab::Range();
1521   ((DM_Moab *)dm->data)->vghost = new moab::Range();
1522   ((DM_Moab *)dm->data)->elocal = new moab::Range();
1523   ((DM_Moab *)dm->data)->eghost = new moab::Range();
1524 
1525   PetscCall(DMInitialize_Moab(dm));
1526   PetscFunctionReturn(PETSC_SUCCESS);
1527 }
1528