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