xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 72ff976d954bc3c7fafc0d672bae89803a0b2715)
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   if (!ltog_tag) {
242     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, *ltog_tag);MBERRNM(merr);
243   }
244   else {
245     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
246   }
247 
248   /* do the initialization of other DM data */
249   dmmoab->bs       = 1;
250   dmmoab->ltog_tag = *ltog_tag;
251   if (range) {
252     ierr = DMMoabSetRange(*dmb, range);CHKERRQ(ierr);
253   }
254   PetscFunctionReturn(0);
255 }
256 
257 #undef __FUNCT__
258 #define __FUNCT__ "DMMoabSetParallelComm"
259 /*@
260   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
261 
262   Collective on MPI_Comm
263 
264   Input Parameter:
265 . dm    - The DMMoab object being set
266 . pcomm - The ParallelComm being set on the DMMoab
267 
268   Level: beginner
269 
270 .keywords: DMMoab, create
271 @*/
272 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
273 {
274   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
275 
276   PetscFunctionBegin;
277   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
278   dmmoab->pcomm = pcomm;
279   dmmoab->mbiface = pcomm->get_moab();
280   dmmoab->icreatedinstance = PETSC_FALSE;
281   PetscFunctionReturn(0);
282 }
283 
284 
285 #undef __FUNCT__
286 #define __FUNCT__ "DMMoabGetParallelComm"
287 /*@
288   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
289 
290   Collective on MPI_Comm
291 
292   Input Parameter:
293 . dm    - The DMMoab object being set
294 
295   Output Parameter:
296 . pcomm - The ParallelComm for the DMMoab
297 
298   Level: beginner
299 
300 .keywords: DMMoab, create
301 @*/
302 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
303 {
304   PetscFunctionBegin;
305   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
306   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
307   PetscFunctionReturn(0);
308 }
309 
310 
311 #undef __FUNCT__
312 #define __FUNCT__ "DMMoabSetInterface"
313 /*@
314   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
315 
316   Collective on MPI_Comm
317 
318   Input Parameter:
319 . dm      - The DMMoab object being set
320 . mbiface - The MOAB instance being set on this DMMoab
321 
322   Level: beginner
323 
324 .keywords: DMMoab, create
325 @*/
326 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
327 {
328   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
329 
330   PetscFunctionBegin;
331   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
332   dmmoab->pcomm = NULL;
333   dmmoab->mbiface = mbiface;
334   dmmoab->icreatedinstance = PETSC_FALSE;
335   PetscFunctionReturn(0);
336 }
337 
338 
339 #undef __FUNCT__
340 #define __FUNCT__ "DMMoabGetInterface"
341 /*@
342   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
343 
344   Collective on MPI_Comm
345 
346   Input Parameter:
347 . dm      - The DMMoab object being set
348 
349   Output Parameter:
350 . mbiface - The MOAB instance set on this DMMoab
351 
352   Level: beginner
353 
354 .keywords: DMMoab, create
355 @*/
356 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
357 {
358   PetscErrorCode   ierr;
359   static PetscBool cite = PETSC_FALSE;
360 
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
363   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);
364   *mbiface = ((DM_Moab*)dm->data)->mbiface;
365   PetscFunctionReturn(0);
366 }
367 
368 
369 #undef __FUNCT__
370 #define __FUNCT__ "DMMoabSetRange"
371 /*@
372   DMMoabSetRange - Set the entities having DOFs on this DMMoab
373 
374   Collective on MPI_Comm
375 
376   Input Parameter:
377 . dm    - The DMMoab object being set
378 . range - The entities treated by this DMMoab
379 
380   Level: beginner
381 
382 .keywords: DMMoab, create
383 @*/
384 PetscErrorCode DMMoabSetRange(DM dm,moab::Range *range)
385 {
386   moab::ErrorCode merr;
387   PetscErrorCode  ierr;
388   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
389 
390   PetscFunctionBegin;
391   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
392   dmmoab->vlocal->clear();
393   dmmoab->vowned->clear();
394   dmmoab->vlocal->insert(range->begin(), range->end());
395   *dmmoab->vowned = *dmmoab->vlocal;
396   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
397   *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned);
398   dmmoab->nloc=dmmoab->vowned->size();
399   dmmoab->nghost=dmmoab->vghost->size();
400   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
401   PetscFunctionReturn(0);
402 }
403 
404 
405 #undef __FUNCT__
406 #define __FUNCT__ "DMMoabGetRange"
407 /*@
408   DMMoabGetRange - Get the entities having DOFs on this DMMoab
409 
410   Collective on MPI_Comm
411 
412   Input Parameter:
413 . dm    - The DMMoab object being set
414 
415   Output Parameter:
416 . range - The entities treated by this DMMoab
417 
418   Level: beginner
419 
420 .keywords: DMMoab, create
421 @*/
422 PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range)
423 {
424   PetscFunctionBegin;
425   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
426   *range = ((DM_Moab*)dm->data)->vowned;
427   PetscFunctionReturn(0);
428 }
429 
430 #undef __FUNCT__
431 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
432 /*@
433   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
434 
435   Collective on MPI_Comm
436 
437   Input Parameter:
438 . dm      - The DMMoab object being set
439 . ltogtag - The MOAB tag used for local to global ids
440 
441   Level: beginner
442 
443 .keywords: DMMoab, create
444 @*/
445 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
446 {
447   PetscFunctionBegin;
448   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
449   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
450   PetscFunctionReturn(0);
451 }
452 
453 
454 #undef __FUNCT__
455 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
456 /*@
457   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
458 
459   Collective on MPI_Comm
460 
461   Input Parameter:
462 . dm      - The DMMoab object being set
463 
464   Output Parameter:
465 . ltogtag - The MOAB tag used for local to global ids
466 
467   Level: beginner
468 
469 .keywords: DMMoab, create
470 @*/
471 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
472 {
473   PetscFunctionBegin;
474   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
475   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
476   PetscFunctionReturn(0);
477 }
478 
479 
480 #undef __FUNCT__
481 #define __FUNCT__ "DMMoabSetBlockSize"
482 /*@
483   DMMoabSetBlockSize - Set the block size used with this DMMoab
484 
485   Collective on MPI_Comm
486 
487   Input Parameter:
488 . dm - The DMMoab object being set
489 . bs - The block size used with this DMMoab
490 
491   Level: beginner
492 
493 .keywords: DMMoab, create
494 @*/
495 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
496 {
497   PetscFunctionBegin;
498   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
499   ((DM_Moab*)dm->data)->bs = bs;
500   PetscFunctionReturn(0);
501 }
502 
503 
504 #undef __FUNCT__
505 #define __FUNCT__ "DMMoabGetBlockSize"
506 /*@
507   DMMoabGetBlockSize - Get the block size used with this DMMoab
508 
509   Collective on MPI_Comm
510 
511   Input Parameter:
512 . dm - The DMMoab object being set
513 
514   Output Parameter:
515 . bs - The block size used with this DMMoab
516 
517   Level: beginner
518 
519 .keywords: DMMoab, create
520 @*/
521 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
522 {
523   PetscFunctionBegin;
524   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
525   *bs = ((DM_Moab*)dm->data)->bs;
526   PetscFunctionReturn(0);
527 }
528 
529