xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 5eb88e9d85d73be3509d48e6bc37881f574c5fe5)
1 #include <petsc-private/dmmbimpl.h> /*I  "petscdm.h"   I*/
2 #include <petsc-private/vecimpl.h> /*I  "petscdm.h"   I*/
3 
4 #include <petscdmmoab.h>
5 #include <MBTagConventions.hpp>
6 
7 #undef __FUNCT__
8 #define __FUNCT__ "DMDestroy_Moab"
9 PetscErrorCode DMDestroy_Moab(DM dm)
10 {
11   PetscErrorCode ierr;
12   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
13 
14   PetscFunctionBegin;
15   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
16   if (dmmoab->icreatedinstance) {
17     delete dmmoab->mbiface;
18   }
19   dmmoab->mbiface = NULL;
20   dmmoab->pcomm = NULL;
21   delete dmmoab->vlocal;
22   delete dmmoab->vowned;
23   delete dmmoab->vghost;
24   delete dmmoab->elocal;
25   delete dmmoab->eghost;
26   ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
27   ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr);
28   ierr = PetscFree(dm->data);CHKERRQ(ierr);
29   PetscFunctionReturn(0);
30 }
31 
32 #undef __FUNCT__
33 #define __FUNCT__ "DMSetUp_Moab"
34 PetscErrorCode DMSetUp_Moab(DM dm)
35 {
36   PetscErrorCode          ierr;
37   moab::ErrorCode         merr;
38   Vec                     local, global;
39   IS                      from;
40   moab::Range::iterator   iter;
41   PetscInt                bs, *gsindices,gsiz,lsiz;
42   DM_Moab                *dmmoab = (DM_Moab*)dm->data;
43   PetscInt                totsize;
44 
45   PetscFunctionBegin;
46   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
47   /* Get the local and shared vertices and cache it */
48   if (dmmoab->mbiface == PETSC_NULL || dmmoab->pcomm == PETSC_NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp.");
49 
50   /* store the current mesh dimension */
51   merr = dmmoab->mbiface->get_dimension(dmmoab->dim);MBERRNM(merr);
52 
53   /* Get the entities recursively in the current part of the mesh */
54   if (dmmoab->vlocal->empty()) {
55     merr = dmmoab->mbiface->get_entities_by_type(0,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
56     *dmmoab->vowned = *dmmoab->vlocal;
57 
58     /* filter based on parallel status */
59     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
60     *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
61 
62     dmmoab->nloc = dmmoab->vowned->size();
63     dmmoab->nghost = dmmoab->vghost->size();
64     ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
65   }
66 
67   /* get the information about the local elements in the mesh */
68   {
69     dmmoab->elocal->clear();
70     dmmoab->eghost->clear();
71     merr = dmmoab->mbiface->get_entities_by_dimension(0, dmmoab->dim, *dmmoab->elocal, true);CHKERRQ(merr);
72     *dmmoab->eghost = *dmmoab->elocal;
73     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
74     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
75 
76     dmmoab->neleloc = dmmoab->elocal->size();
77     ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
78   }
79 
80   bs = dmmoab->bs;
81   if (!dmmoab->ltog_tag) {
82     /* Get the global ID tag. The global ID tag is applied to each
83        vertex. It acts as an global identifier which MOAB uses to
84        assemble the individual pieces of the mesh */
85     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
86   }
87 
88   {
89     totsize=dmmoab->vlocal->size();
90     ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr);
91     /* first get the local indices */
92     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&gsindices[0]);MBERRNM(merr);
93     /* next get the ghosted indices */
94     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&gsindices[dmmoab->nloc]);MBERRNM(merr);
95 
96     /* Create Global to Local Vector Scatter Context */
97     ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr);
98     ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr);
99 
100     /* global to local must retrieve ghost points */
101     ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
102 
103     ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr);
104     ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr);
105 
106     ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
107     ierr = ISDestroy(&from);CHKERRQ(ierr);
108     ierr = VecDestroy(&local);CHKERRQ(ierr);
109     ierr = VecDestroy(&global);CHKERRQ(ierr);
110     ierr = PetscFree(gsindices);CHKERRQ(ierr);
111   }
112 
113   PetscFunctionReturn(0);
114 }
115 
116 #undef __FUNCT__
117 #define __FUNCT__ "DMCreate_Moab"
118 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
119 {
120   PetscErrorCode ierr;
121 
122   PetscFunctionBegin;
123   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
124   ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr);
125 
126   ((DM_Moab*)dm->data)->bs = 1;
127   ((DM_Moab*)dm->data)->n = 0;
128   ((DM_Moab*)dm->data)->nloc = 0;
129   ((DM_Moab*)dm->data)->nele = 0;
130   ((DM_Moab*)dm->data)->neleloc = 0;
131   ((DM_Moab*)dm->data)->nghost = 0;
132   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
133   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
134 
135   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
136   ((DM_Moab*)dm->data)->vowned = new moab::Range();
137   ((DM_Moab*)dm->data)->vghost = new moab::Range();
138   ((DM_Moab*)dm->data)->elocal = new moab::Range();
139   ((DM_Moab*)dm->data)->eghost = new moab::Range();
140 
141   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
142   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
143   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
144   dm->ops->setup                           = DMSetUp_Moab;
145   dm->ops->destroy                         = DMDestroy_Moab;
146   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
147   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
148   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
149   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
150   PetscFunctionReturn(0);
151 }
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "DMMoabCreate"
155 /*@
156   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
157 
158   Collective on MPI_Comm
159 
160   Input Parameter:
161 . comm - The communicator for the DMMoab object
162 
163   Output Parameter:
164 . dmb  - The DMMoab object
165 
166   Level: beginner
167 
168 .keywords: DMMoab, create
169 @*/
170 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
171 {
172   PetscErrorCode ierr;
173 
174   PetscFunctionBegin;
175   PetscValidPointer(dmb,2);
176   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
177   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
178   PetscFunctionReturn(0);
179 }
180 
181 #undef __FUNCT__
182 #define __FUNCT__ "DMMoabCreateMoab"
183 /*@
184   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
185 
186   Collective on MPI_Comm
187 
188   Input Parameter:
189 . comm - The communicator for the DMMoab object
190 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
191          along with the DMMoab
192 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
193 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
194 . range - If non-NULL, contains range of entities to which DOFs will be assigned
195 
196   Output Parameter:
197 . dmb  - The DMMoab object
198 
199   Level: intermediate
200 
201 .keywords: DMMoab, create
202 @*/
203 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
204 {
205   PetscErrorCode ierr;
206   moab::ErrorCode merr;
207   DM_Moab        *dmmoab;
208 
209   PetscFunctionBegin;
210   PetscValidPointer(dmb,6);
211   ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr);
212   dmmoab = (DM_Moab*)(*dmb)->data;
213 
214   if (!mbiface) {
215     dmmoab->mbiface = new moab::Core();
216     dmmoab->icreatedinstance = PETSC_TRUE;
217   }
218   else
219     dmmoab->icreatedinstance = PETSC_FALSE;
220 
221   if (!pcomm) {
222     moab::EntityHandle rootset,partnset;
223     PetscInt rank, nprocs;
224     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
225     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
226 
227     /* Create root sets for each mesh.  Then pass these
228        to the load_file functions to be populated. */
229     merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, rootset);
230     MBERR("Creating root set failed", merr);
231     merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);
232     MBERR("Creating partition set failed", merr);
233 
234     /* Create the parallel communicator object with the partition handle associated with MOAB */
235     dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
236   }
237   else {
238     ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr);
239   }
240 
241   /* do the remaining initializations for DMMoab */
242   dmmoab->bs       = 1;
243 
244   /* set global ID tag handle */
245   if (!ltog_tag) {
246     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
247   }
248   else {
249     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
250   }
251 
252   /* create a fileset to store the hierarchy of entities belonging to current DM */
253   merr = mbiface->create_meshset(MESHSET_ORDERED, dmmoab->file_set);MBERRNM(ierr);
254 
255   /* set the local range of entities (vertices) of interest */
256   if (range) {
257     ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr);
258   }
259   PetscFunctionReturn(0);
260 }
261 
262 #undef __FUNCT__
263 #define __FUNCT__ "DMMoabSetParallelComm"
264 /*@
265   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
266 
267   Collective on MPI_Comm
268 
269   Input Parameter:
270 . dm    - The DMMoab object being set
271 . pcomm - The ParallelComm being set on the DMMoab
272 
273   Level: beginner
274 
275 .keywords: DMMoab, create
276 @*/
277 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
278 {
279   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
280 
281   PetscFunctionBegin;
282   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
283   dmmoab->pcomm = pcomm;
284   dmmoab->mbiface = pcomm->get_moab();
285   dmmoab->icreatedinstance = PETSC_FALSE;
286   PetscFunctionReturn(0);
287 }
288 
289 
290 #undef __FUNCT__
291 #define __FUNCT__ "DMMoabGetParallelComm"
292 /*@
293   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
294 
295   Collective on MPI_Comm
296 
297   Input Parameter:
298 . dm    - The DMMoab object being set
299 
300   Output Parameter:
301 . pcomm - The ParallelComm for the DMMoab
302 
303   Level: beginner
304 
305 .keywords: DMMoab, create
306 @*/
307 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
308 {
309   PetscFunctionBegin;
310   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
311   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
312   PetscFunctionReturn(0);
313 }
314 
315 
316 #undef __FUNCT__
317 #define __FUNCT__ "DMMoabSetInterface"
318 /*@
319   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
320 
321   Collective on MPI_Comm
322 
323   Input Parameter:
324 . dm      - The DMMoab object being set
325 . mbiface - The MOAB instance being set on this DMMoab
326 
327   Level: beginner
328 
329 .keywords: DMMoab, create
330 @*/
331 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
332 {
333   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
334 
335   PetscFunctionBegin;
336   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
337   dmmoab->pcomm = NULL;
338   dmmoab->mbiface = mbiface;
339   dmmoab->icreatedinstance = PETSC_FALSE;
340   PetscFunctionReturn(0);
341 }
342 
343 
344 #undef __FUNCT__
345 #define __FUNCT__ "DMMoabGetInterface"
346 /*@
347   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
348 
349   Collective on MPI_Comm
350 
351   Input Parameter:
352 . dm      - The DMMoab object being set
353 
354   Output Parameter:
355 . mbiface - The MOAB instance set on this DMMoab
356 
357   Level: beginner
358 
359 .keywords: DMMoab, create
360 @*/
361 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
362 {
363   PetscErrorCode   ierr;
364   static PetscBool cite = PETSC_FALSE;
365 
366   PetscFunctionBegin;
367   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
368   ierr = PetscCitationsRegister("@techreport{tautges_moab:_2004,\n  type = {{SAND2004-1592}},\n  title = {{MOAB:} A Mesh-Oriented Database},  institution = {Sandia National Laboratories},\n  author = {Tautges, T. J. and Meyers, R. and Merkley, K. and Stimpson, C. and Ernst, C.},\n  year = {2004},  note = {Report}\n}\n",&cite);CHKERRQ(ierr);
369   *mbiface = ((DM_Moab*)dm->data)->mbiface;
370   PetscFunctionReturn(0);
371 }
372 
373 
374 #undef __FUNCT__
375 #define __FUNCT__ "DMMoabSetLocalVertices"
376 /*@
377   DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab
378 
379   Collective on MPI_Comm
380 
381   Input Parameter:
382 . dm    - The DMMoab object being set
383 . range - The entities treated by this DMMoab
384 
385   Level: beginner
386 
387 .keywords: DMMoab, create
388 @*/
389 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range)
390 {
391   moab::ErrorCode merr;
392   PetscErrorCode  ierr;
393   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
394 
395   PetscFunctionBegin;
396   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
397   dmmoab->vlocal->clear();
398   dmmoab->vowned->clear();
399   dmmoab->vlocal->insert(range->begin(), range->end());
400   *dmmoab->vowned = *dmmoab->vlocal;
401   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
402   *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned);
403   dmmoab->nloc=dmmoab->vowned->size();
404   dmmoab->nghost=dmmoab->vghost->size();
405   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
406   PetscFunctionReturn(0);
407 }
408 
409 
410 #undef __FUNCT__
411 #define __FUNCT__ "DMMoabGetLocalVertices"
412 /*@
413   DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab
414 
415   Collective on MPI_Comm
416 
417   Input Parameter:
418 . dm    - The DMMoab object being set
419 
420   Output Parameter:
421 . owned - The owned vertex entities in this DMMoab
422 . ghost - The ghosted entities (non-owned) stored locally in this partition
423 
424   Level: beginner
425 
426 .keywords: DMMoab, create
427 @*/
428 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range **owned,moab::Range **ghost)
429 {
430   PetscFunctionBegin;
431   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
432   if (*owned) *owned = ((DM_Moab*)dm->data)->vowned;
433   if (*ghost) *ghost = ((DM_Moab*)dm->data)->vghost;
434   PetscFunctionReturn(0);
435 }
436 
437 #undef __FUNCT__
438 #define __FUNCT__ "DMMoabGetLocalElements"
439 /*@
440   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
441 
442   Collective on MPI_Comm
443 
444   Input Parameter:
445 . dm    - The DMMoab object being set
446 
447   Output Parameter:
448 . range - The entities owned locally
449 
450   Level: beginner
451 
452 .keywords: DMMoab, create
453 @*/
454 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range **range)
455 {
456   PetscFunctionBegin;
457   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
458   *range = ((DM_Moab*)dm->data)->elocal;
459   PetscFunctionReturn(0);
460 }
461 
462 
463 #undef __FUNCT__
464 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
465 /*@
466   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
467 
468   Collective on MPI_Comm
469 
470   Input Parameter:
471 . dm      - The DMMoab object being set
472 . ltogtag - The MOAB tag used for local to global ids
473 
474   Level: beginner
475 
476 .keywords: DMMoab, create
477 @*/
478 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
479 {
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
482   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
483   PetscFunctionReturn(0);
484 }
485 
486 
487 #undef __FUNCT__
488 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
489 /*@
490   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
491 
492   Collective on MPI_Comm
493 
494   Input Parameter:
495 . dm      - The DMMoab object being set
496 
497   Output Parameter:
498 . ltogtag - The MOAB tag used for local to global ids
499 
500   Level: beginner
501 
502 .keywords: DMMoab, create
503 @*/
504 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
505 {
506   PetscFunctionBegin;
507   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
508   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
509   PetscFunctionReturn(0);
510 }
511 
512 
513 #undef __FUNCT__
514 #define __FUNCT__ "DMMoabSetBlockSize"
515 /*@
516   DMMoabSetBlockSize - Set the block size used with this DMMoab
517 
518   Collective on MPI_Comm
519 
520   Input Parameter:
521 . dm - The DMMoab object being set
522 . bs - The block size used with this DMMoab
523 
524   Level: beginner
525 
526 .keywords: DMMoab, create
527 @*/
528 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
529 {
530   PetscFunctionBegin;
531   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
532   ((DM_Moab*)dm->data)->bs = bs;
533   PetscFunctionReturn(0);
534 }
535 
536 
537 #undef __FUNCT__
538 #define __FUNCT__ "DMMoabGetBlockSize"
539 /*@
540   DMMoabGetBlockSize - Get the block size used with this DMMoab
541 
542   Collective on MPI_Comm
543 
544   Input Parameter:
545 . dm - The DMMoab object being set
546 
547   Output Parameter:
548 . bs - The block size used with this DMMoab
549 
550   Level: beginner
551 
552 .keywords: DMMoab, create
553 @*/
554 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
555 {
556   PetscFunctionBegin;
557   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
558   *bs = ((DM_Moab*)dm->data)->bs;
559   PetscFunctionReturn(0);
560 }
561 
562