xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 4a40b57043114e997ee4a98c9008bb55006e8e05)
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     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&gsindices[0]);MBERRNM(merr);
94     /* next get the ghosted indices */
95     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&gsindices[dmmoab->nloc]);MBERRNM(merr);
96 
97     /* Create Global to Local Vector Scatter Context */
98     ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr);
99     ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr);
100 
101     /* global to local must retrieve ghost points */
102     ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
103 
104     ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr);
105     ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr);
106 
107     ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
108     ierr = ISDestroy(&from);CHKERRQ(ierr);
109     ierr = VecDestroy(&local);CHKERRQ(ierr);
110     ierr = VecDestroy(&global);CHKERRQ(ierr);
111     ierr = PetscFree(gsindices);CHKERRQ(ierr);
112   }
113 
114   PetscFunctionReturn(0);
115 }
116 
117 #undef __FUNCT__
118 #define __FUNCT__ "DMCreate_Moab"
119 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
120 {
121   PetscErrorCode ierr;
122 
123   PetscFunctionBegin;
124   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
125   ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr);
126 
127   ((DM_Moab*)dm->data)->bs = 1;
128   ((DM_Moab*)dm->data)->n = 0;
129   ((DM_Moab*)dm->data)->nloc = 0;
130   ((DM_Moab*)dm->data)->nele = 0;
131   ((DM_Moab*)dm->data)->neleloc = 0;
132   ((DM_Moab*)dm->data)->nghost = 0;
133   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
134   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
135 
136   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
137   ((DM_Moab*)dm->data)->vowned = new moab::Range();
138   ((DM_Moab*)dm->data)->vghost = new moab::Range();
139   ((DM_Moab*)dm->data)->elocal = new moab::Range();
140   ((DM_Moab*)dm->data)->eghost = new moab::Range();
141 
142   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
143   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
144   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
145   dm->ops->setup                           = DMSetUp_Moab;
146   dm->ops->destroy                         = DMDestroy_Moab;
147   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
148   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
149   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
150   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
151   PetscFunctionReturn(0);
152 }
153 
154 #undef __FUNCT__
155 #define __FUNCT__ "DMMoabCreate"
156 /*@
157   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
158 
159   Collective on MPI_Comm
160 
161   Input Parameter:
162 . comm - The communicator for the DMMoab object
163 
164   Output Parameter:
165 . dmb  - The DMMoab object
166 
167   Level: beginner
168 
169 .keywords: DMMoab, create
170 @*/
171 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
172 {
173   PetscErrorCode ierr;
174 
175   PetscFunctionBegin;
176   PetscValidPointer(dmb,2);
177   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
178   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
179   PetscFunctionReturn(0);
180 }
181 
182 #undef __FUNCT__
183 #define __FUNCT__ "DMMoabCreateMoab"
184 /*@
185   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
186 
187   Collective on MPI_Comm
188 
189   Input Parameter:
190 . comm - The communicator for the DMMoab object
191 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
192          along with the DMMoab
193 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
194 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
195 . range - If non-NULL, contains range of entities to which DOFs will be assigned
196 
197   Output Parameter:
198 . dmb  - The DMMoab object
199 
200   Level: intermediate
201 
202 .keywords: DMMoab, create
203 @*/
204 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
205 {
206   PetscErrorCode ierr;
207   moab::ErrorCode merr;
208   DM_Moab        *dmmoab;
209 
210   PetscFunctionBegin;
211   PetscValidPointer(dmb,6);
212   ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr);
213   dmmoab = (DM_Moab*)(*dmb)->data;
214 
215   if (!mbiface) {
216     mbiface = new moab::Core();
217     dmmoab->icreatedinstance = PETSC_TRUE;
218   }
219   else
220     dmmoab->icreatedinstance = PETSC_FALSE;
221 
222   if (!pcomm) {
223     moab::EntityHandle rootset,partnset;
224     PetscInt rank, nprocs;
225     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
226     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
227 
228     /* Create root sets for each mesh.  Then pass these
229        to the load_file functions to be populated. */
230     merr = mbiface->create_meshset(moab::MESHSET_SET, rootset);
231     MBERR("Creating root set failed", merr);
232     merr = mbiface->create_meshset(moab::MESHSET_SET, partnset);
233     MBERR("Creating partition set failed", merr);
234 
235     /* Create the parallel communicator object with the partition handle associated with MOAB */
236     pcomm = moab::ParallelComm::get_pcomm(mbiface, partnset, &comm);
237   }
238 
239   if (!ltog_tag) {
240     merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, *ltog_tag);MBERRNM(merr);
241   }
242   else {
243     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
244   }
245 
246   /* do the initialization of the DM */
247   dmmoab->bs       = 1;
248   ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr);
249   dmmoab->ltog_tag = *ltog_tag;
250   if (range) {
251     ierr = DMMoabSetRange(*dmb, range);CHKERRQ(ierr);
252   }
253   PetscFunctionReturn(0);
254 }
255 
256 #undef __FUNCT__
257 #define __FUNCT__ "DMMoabSetParallelComm"
258 /*@
259   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
260 
261   Collective on MPI_Comm
262 
263   Input Parameter:
264 . dm    - The DMMoab object being set
265 . pcomm - The ParallelComm being set on the DMMoab
266 
267   Level: beginner
268 
269 .keywords: DMMoab, create
270 @*/
271 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
272 {
273   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
274 
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
277   dmmoab->pcomm = pcomm;
278   dmmoab->mbiface = pcomm->get_moab();
279   dmmoab->icreatedinstance = PETSC_FALSE;
280   PetscFunctionReturn(0);
281 }
282 
283 
284 #undef __FUNCT__
285 #define __FUNCT__ "DMMoabGetParallelComm"
286 /*@
287   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
288 
289   Collective on MPI_Comm
290 
291   Input Parameter:
292 . dm    - The DMMoab object being set
293 
294   Output Parameter:
295 . pcomm - The ParallelComm for the DMMoab
296 
297   Level: beginner
298 
299 .keywords: DMMoab, create
300 @*/
301 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
302 {
303   PetscFunctionBegin;
304   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
305   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
306   PetscFunctionReturn(0);
307 }
308 
309 
310 #undef __FUNCT__
311 #define __FUNCT__ "DMMoabSetInterface"
312 /*@
313   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
314 
315   Collective on MPI_Comm
316 
317   Input Parameter:
318 . dm      - The DMMoab object being set
319 . mbiface - The MOAB instance being set on this DMMoab
320 
321   Level: beginner
322 
323 .keywords: DMMoab, create
324 @*/
325 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
326 {
327   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
328 
329   PetscFunctionBegin;
330   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
331   dmmoab->pcomm = NULL;
332   dmmoab->mbiface = mbiface;
333   dmmoab->icreatedinstance = PETSC_FALSE;
334   PetscFunctionReturn(0);
335 }
336 
337 
338 #undef __FUNCT__
339 #define __FUNCT__ "DMMoabGetInterface"
340 /*@
341   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
342 
343   Collective on MPI_Comm
344 
345   Input Parameter:
346 . dm      - The DMMoab object being set
347 
348   Output Parameter:
349 . mbiface - The MOAB instance set on this DMMoab
350 
351   Level: beginner
352 
353 .keywords: DMMoab, create
354 @*/
355 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
356 {
357   PetscErrorCode   ierr;
358   static PetscBool cite = PETSC_FALSE;
359 
360   PetscFunctionBegin;
361   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
362   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);
363   *mbiface = ((DM_Moab*)dm->data)->mbiface;
364   PetscFunctionReturn(0);
365 }
366 
367 
368 #undef __FUNCT__
369 #define __FUNCT__ "DMMoabSetRange"
370 /*@
371   DMMoabSetRange - Set the entities having DOFs on this DMMoab
372 
373   Collective on MPI_Comm
374 
375   Input Parameter:
376 . dm    - The DMMoab object being set
377 . range - The entities treated by this DMMoab
378 
379   Level: beginner
380 
381 .keywords: DMMoab, create
382 @*/
383 PetscErrorCode DMMoabSetRange(DM dm,moab::Range *range)
384 {
385   moab::ErrorCode merr;
386   PetscErrorCode  ierr;
387   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
388 
389   PetscFunctionBegin;
390   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
391   dmmoab->vlocal->clear();
392   dmmoab->vowned->clear();
393   dmmoab->vlocal->insert(range->begin(), range->end());
394   *dmmoab->vowned = *dmmoab->vlocal;
395   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
396   *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned);
397   dmmoab->nloc=dmmoab->vowned->size();
398   dmmoab->nghost=dmmoab->vghost->size();
399   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
400   PetscFunctionReturn(0);
401 }
402 
403 
404 #undef __FUNCT__
405 #define __FUNCT__ "DMMoabGetRange"
406 /*@
407   DMMoabGetRange - Get the entities having DOFs on this DMMoab
408 
409   Collective on MPI_Comm
410 
411   Input Parameter:
412 . dm    - The DMMoab object being set
413 
414   Output Parameter:
415 . range - The entities treated by this DMMoab
416 
417   Level: beginner
418 
419 .keywords: DMMoab, create
420 @*/
421 PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range)
422 {
423   PetscFunctionBegin;
424   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
425   *range = ((DM_Moab*)dm->data)->vowned;
426   PetscFunctionReturn(0);
427 }
428 
429 #undef __FUNCT__
430 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
431 /*@
432   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
433 
434   Collective on MPI_Comm
435 
436   Input Parameter:
437 . dm      - The DMMoab object being set
438 . ltogtag - The MOAB tag used for local to global ids
439 
440   Level: beginner
441 
442 .keywords: DMMoab, create
443 @*/
444 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
445 {
446   PetscFunctionBegin;
447   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
448   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
449   PetscFunctionReturn(0);
450 }
451 
452 
453 #undef __FUNCT__
454 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
455 /*@
456   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
457 
458   Collective on MPI_Comm
459 
460   Input Parameter:
461 . dm      - The DMMoab object being set
462 
463   Output Parameter:
464 . ltogtag - The MOAB tag used for local to global ids
465 
466   Level: beginner
467 
468 .keywords: DMMoab, create
469 @*/
470 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
471 {
472   PetscFunctionBegin;
473   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
474   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
475   PetscFunctionReturn(0);
476 }
477 
478 
479 #undef __FUNCT__
480 #define __FUNCT__ "DMMoabSetBlockSize"
481 /*@
482   DMMoabSetBlockSize - Set the block size used with this DMMoab
483 
484   Collective on MPI_Comm
485 
486   Input Parameter:
487 . dm - The DMMoab object being set
488 . bs - The block size used with this DMMoab
489 
490   Level: beginner
491 
492 .keywords: DMMoab, create
493 @*/
494 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
495 {
496   PetscFunctionBegin;
497   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
498   ((DM_Moab*)dm->data)->bs = bs;
499   PetscFunctionReturn(0);
500 }
501 
502 
503 #undef __FUNCT__
504 #define __FUNCT__ "DMMoabGetBlockSize"
505 /*@
506   DMMoabGetBlockSize - Get the block size used with this DMMoab
507 
508   Collective on MPI_Comm
509 
510   Input Parameter:
511 . dm - The DMMoab object being set
512 
513   Output Parameter:
514 . bs - The block size used with this DMMoab
515 
516   Level: beginner
517 
518 .keywords: DMMoab, create
519 @*/
520 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
521 {
522   PetscFunctionBegin;
523   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
524   *bs = ((DM_Moab*)dm->data)->bs;
525   PetscFunctionReturn(0);
526 }
527 
528