xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision db66d124cedba962fb8ceb469cd36885b3f01337)
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                count,dof,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     count=0;
90     totsize=dmmoab->vlocal->size();
91     ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr);
92     /* first get the local indices */
93     for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) {
94       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
95       gsindices[count++] = (dof);
96     }
97     /* now get the ghosted indices */
98     for(iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++) {
99       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
100       gsindices[count++] = (dof);
101     }
102 
103     /* Create Global to Local Vector Scatter Context */
104     ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr);
105     ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr);
106 
107     /* global to local must retrieve ghost points */
108     ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
109 
110     ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr);
111     ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr);
112 
113     ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
114     ierr = ISDestroy(&from);CHKERRQ(ierr);
115     ierr = VecDestroy(&local);CHKERRQ(ierr);
116     ierr = VecDestroy(&global);CHKERRQ(ierr);
117     ierr = PetscFree(gsindices);CHKERRQ(ierr);
118   }
119 
120   PetscFunctionReturn(0);
121 }
122 
123 #undef __FUNCT__
124 #define __FUNCT__ "DMCreate_Moab"
125 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
126 {
127   PetscErrorCode ierr;
128 
129   PetscFunctionBegin;
130   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
131   ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr);
132 
133   ((DM_Moab*)dm->data)->bs = 1;
134   ((DM_Moab*)dm->data)->n = 0;
135   ((DM_Moab*)dm->data)->nloc = 0;
136   ((DM_Moab*)dm->data)->nele = 0;
137   ((DM_Moab*)dm->data)->neleloc = 0;
138   ((DM_Moab*)dm->data)->nghost = 0;
139   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
140   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
141 
142   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
143   ((DM_Moab*)dm->data)->vowned = new moab::Range();
144   ((DM_Moab*)dm->data)->vghost = new moab::Range();
145   ((DM_Moab*)dm->data)->elocal = new moab::Range();
146   ((DM_Moab*)dm->data)->eghost = new moab::Range();
147 
148   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
149   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
150   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
151   dm->ops->setup                           = DMSetUp_Moab;
152   dm->ops->destroy                         = DMDestroy_Moab;
153   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
154   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
155   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
156   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
157   PetscFunctionReturn(0);
158 }
159 
160 #undef __FUNCT__
161 #define __FUNCT__ "DMMoabCreate"
162 /*@
163   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
164 
165   Collective on MPI_Comm
166 
167   Input Parameter:
168 . comm - The communicator for the DMMoab object
169 
170   Output Parameter:
171 . dmb  - The DMMoab object
172 
173   Level: beginner
174 
175 .keywords: DMMoab, create
176 @*/
177 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
178 {
179   PetscErrorCode ierr;
180 
181   PetscFunctionBegin;
182   PetscValidPointer(dmb,2);
183   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
184   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
185   PetscFunctionReturn(0);
186 }
187 
188 #undef __FUNCT__
189 #define __FUNCT__ "DMMoabCreateMoab"
190 /*@
191   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
192 
193   Collective on MPI_Comm
194 
195   Input Parameter:
196 . comm - The communicator for the DMMoab object
197 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
198          along with the DMMoab
199 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
200 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
201 . range - If non-NULL, contains range of entities to which DOFs will be assigned
202 
203   Output Parameter:
204 . dmb  - The DMMoab object
205 
206   Level: intermediate
207 
208 .keywords: DMMoab, create
209 @*/
210 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
211 {
212   PetscErrorCode ierr;
213   moab::ErrorCode merr;
214   DM_Moab        *dmmoab;
215 
216   PetscFunctionBegin;
217   PetscValidPointer(dmb,6);
218   ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr);
219   dmmoab = (DM_Moab*)(*dmb)->data;
220 
221   if (!mbiface) {
222     mbiface = new moab::Core();
223     dmmoab->icreatedinstance = PETSC_TRUE;
224   }
225   else
226     dmmoab->icreatedinstance = PETSC_FALSE;
227 
228   if (!pcomm) {
229     moab::EntityHandle rootset,partnset;
230     PetscInt rank, nprocs;
231     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
232     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
233 
234     /* Create root sets for each mesh.  Then pass these
235        to the load_file functions to be populated. */
236     merr = mbiface->create_meshset(moab::MESHSET_SET, rootset);
237     MBERR("Creating root set failed", merr);
238     merr = mbiface->create_meshset(moab::MESHSET_SET, partnset);
239     MBERR("Creating partition set failed", merr);
240 
241     /* Create the parallel communicator object with the partition handle associated with MOAB */
242     pcomm = moab::ParallelComm::get_pcomm(mbiface, partnset, &comm);
243   }
244 
245   if (!ltog_tag) {
246     merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, *ltog_tag);MBERRNM(merr);
247   }
248   else {
249     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
250   }
251 
252   /* do the initialization of the DM */
253   dmmoab->bs       = 1;
254   ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr);
255   dmmoab->ltog_tag = *ltog_tag;
256   if (range) {
257     ierr = DMMoabSetRange(*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__ "DMMoabSetRange"
376 /*@
377   DMMoabSetRange - 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 DMMoabSetRange(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__ "DMMoabGetRange"
412 /*@
413   DMMoabGetRange - 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 . range - The entities treated by this DMMoab
422 
423   Level: beginner
424 
425 .keywords: DMMoab, create
426 @*/
427 PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range)
428 {
429   PetscFunctionBegin;
430   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
431   *range = ((DM_Moab*)dm->data)->vowned;
432   PetscFunctionReturn(0);
433 }
434 
435 #undef __FUNCT__
436 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
437 /*@
438   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
439 
440   Collective on MPI_Comm
441 
442   Input Parameter:
443 . dm      - The DMMoab object being set
444 . ltogtag - The MOAB tag used for local to global ids
445 
446   Level: beginner
447 
448 .keywords: DMMoab, create
449 @*/
450 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
451 {
452   PetscFunctionBegin;
453   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
454   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
455   PetscFunctionReturn(0);
456 }
457 
458 
459 #undef __FUNCT__
460 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
461 /*@
462   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
463 
464   Collective on MPI_Comm
465 
466   Input Parameter:
467 . dm      - The DMMoab object being set
468 
469   Output Parameter:
470 . ltogtag - The MOAB tag used for local to global ids
471 
472   Level: beginner
473 
474 .keywords: DMMoab, create
475 @*/
476 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
477 {
478   PetscFunctionBegin;
479   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
480   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
481   PetscFunctionReturn(0);
482 }
483 
484 
485 #undef __FUNCT__
486 #define __FUNCT__ "DMMoabSetBlockSize"
487 /*@
488   DMMoabSetBlockSize - Set the block size used with this DMMoab
489 
490   Collective on MPI_Comm
491 
492   Input Parameter:
493 . dm - The DMMoab object being set
494 . bs - The block size used with this DMMoab
495 
496   Level: beginner
497 
498 .keywords: DMMoab, create
499 @*/
500 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
501 {
502   PetscFunctionBegin;
503   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
504   ((DM_Moab*)dm->data)->bs = bs;
505   PetscFunctionReturn(0);
506 }
507 
508 
509 #undef __FUNCT__
510 #define __FUNCT__ "DMMoabGetBlockSize"
511 /*@
512   DMMoabGetBlockSize - Get the block size used with this DMMoab
513 
514   Collective on MPI_Comm
515 
516   Input Parameter:
517 . dm - The DMMoab object being set
518 
519   Output Parameter:
520 . bs - The block size used with this DMMoab
521 
522   Level: beginner
523 
524 .keywords: DMMoab, create
525 @*/
526 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
527 {
528   PetscFunctionBegin;
529   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
530   *bs = ((DM_Moab*)dm->data)->bs;
531   PetscFunctionReturn(0);
532 }
533 
534