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