xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 6d9eb265be6640e8ae26236498f33716bac3fa23)
1 #include <petsc-private/dmmbimpl.h> /*I  "petscdm.h"   I*/
2 
3 #include <petscdmmoab.h>
4 #include <MBTagConventions.hpp>
5 #include <moab/Skinner.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   delete dmmoab->bndyvtx;
27   delete dmmoab->bndyfaces;
28   delete dmmoab->bndyelems;
29 
30   ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr);
31   ierr = PetscFree(dmmoab->lidmap);CHKERRQ(ierr);
32   ierr = PetscFree(dmmoab->gidmap);CHKERRQ(ierr);
33   ierr = PetscFree(dmmoab->lmap);CHKERRQ(ierr);
34   ierr = PetscFree(dmmoab->lgmap);CHKERRQ(ierr);
35   ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
36   ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr);
37   ierr = PetscFree(dm->data);CHKERRQ(ierr);
38   PetscFunctionReturn(0);
39 }
40 
41 #undef __FUNCT__
42 #define __FUNCT__ "DMSetUp_Moab"
43 PetscErrorCode DMSetUp_Moab(DM dm)
44 {
45   PetscErrorCode          ierr;
46   moab::ErrorCode         merr;
47   Vec                     local, global;
48   IS                      from,to;
49   moab::Range::iterator   iter;
50   PetscInt                i,j,f,bs,gmin,lmin,lmax,totsize;
51   DM_Moab                *dmmoab = (DM_Moab*)dm->data;
52   moab::Range             adjs;
53 
54   PetscFunctionBegin;
55   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
56   /* Get the local and shared vertices and cache it */
57   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.");
58 
59   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
60   if (dmmoab->vlocal->empty())
61   {
62     merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
63 
64     /* filter based on parallel status */
65     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr);
66 
67     /* filter all the non-owned and shared entities out of the list */
68     adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
69     merr = dmmoab->pcomm->filter_pstatus(adjs,PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr);
70     adjs = moab::subtract(adjs, *dmmoab->vghost);
71     *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs);
72 
73     /* compute and cache the sizes of local and ghosted entities */
74     dmmoab->nloc = dmmoab->vowned->size();
75     dmmoab->nghost = dmmoab->vghost->size();
76     ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
77 
78 #if 0
79     if(dmmoab->pcomm->rank() || dmmoab->pcomm->size()==1) {
80       PetscPrintf(PETSC_COMM_SELF, "Vertices: global: %D, local: %D", dmmoab->n, dmmoab->nloc+dmmoab->nghost);
81       dmmoab->vlocal->print(0);
82       PetscPrintf(PETSC_COMM_SELF, "Vertices: owned: %D", dmmoab->nloc);
83       dmmoab->vowned->print(0);
84       PetscPrintf(PETSC_COMM_SELF, "Vertices: ghost: %D", dmmoab->nghost);
85       dmmoab->vghost->print(0);
86     }
87 #endif
88   }
89 
90   {
91     /* get the information about the local elements in the mesh */
92     dmmoab->eghost->clear();
93 
94     /* first decipher the leading dimension */
95     for (i=3;i>0;i--) {
96       dmmoab->elocal->clear();
97       merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, true);CHKERRQ(merr);
98 
99       /* store the current mesh dimension */
100       if (dmmoab->elocal->size()) {
101         dmmoab->dim=i;
102         break;
103       }
104     }
105 
106     /* filter the ghosted and owned element list */
107     *dmmoab->eghost = *dmmoab->elocal;
108     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
109     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
110 
111     dmmoab->neleloc = dmmoab->elocal->size();
112     ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
113   }
114 
115   bs = dmmoab->bs;
116   if (!dmmoab->ltog_tag) {
117     /* Get the global ID tag. The global ID tag is applied to each
118        vertex. It acts as an global identifier which MOAB uses to
119        assemble the individual pieces of the mesh */
120     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
121   }
122 
123   totsize=dmmoab->vlocal->size();
124   if (totsize != dmmoab->nloc+dmmoab->nghost) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Mismatch between local and owned+ghost vertices. %D != %D.",totsize,dmmoab->nloc+dmmoab->nghost);
125   ierr = PetscMalloc(totsize*sizeof(PetscInt), &dmmoab->gsindices);CHKERRQ(ierr);
126   {
127     /* first get the local indices */
128     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr);
129     /* next get the ghosted indices */
130     if (dmmoab->nghost) {
131       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr);
132     }
133 
134     /* find out the local and global minima of GLOBAL_ID */
135     lmin=lmax=dmmoab->gsindices[0];
136     for (i=0; i<totsize; ++i) {
137       if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i];
138       if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i];
139     }
140 
141     ierr = MPI_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr);
142 
143     /* set the GID map */
144     for (i=0; i<totsize; ++i) {
145       dmmoab->gsindices[i]-=gmin;   /* zero based index needed for IS */
146     }
147     lmin-=gmin;
148     lmax-=gmin;
149 
150     PetscInfo3(NULL, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin);
151   }
152 
153   {
154 
155     ierr = PetscMalloc(((PetscInt)(dmmoab->vlocal->back())+1)*sizeof(PetscInt), &dmmoab->gidmap);CHKERRQ(ierr);
156     ierr = PetscMalloc(((PetscInt)(dmmoab->vlocal->back())+1)*sizeof(PetscInt), &dmmoab->lidmap);CHKERRQ(ierr);
157     ierr = PetscMalloc(totsize*sizeof(PetscInt), &dmmoab->lmap);CHKERRQ(ierr);
158     ierr = PetscMalloc(totsize*dmmoab->nfields*sizeof(PetscInt), &dmmoab->lgmap);CHKERRQ(ierr);
159 
160     i=j=0;
161     for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) {
162       dmmoab->gidmap[(PetscInt)(*iter)]=dmmoab->gsindices[i];
163       dmmoab->lidmap[(PetscInt)(*iter)]=i;
164       dmmoab->lmap[i]=i;
165       PetscInfo3(NULL, "Owned Vertex: %D   LID = %D \t GID = %D.\n", *iter, i, dmmoab->gsindices[i]);
166       if (bs > 1)
167         for (f=0;f<dmmoab->nfields;f++,j++)
168           dmmoab->lgmap[j]=dmmoab->gsindices[i]*dmmoab->nfields+f;
169       else
170         for (f=0;f<dmmoab->nfields;f++,j++)
171           dmmoab->lgmap[j]=totsize*f+dmmoab->gsindices[i];
172     }
173     for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) {
174       dmmoab->gidmap[(PetscInt)(*iter)]=dmmoab->gsindices[i];
175       dmmoab->lidmap[(PetscInt)(*iter)]=i;
176       dmmoab->lmap[i]=i;
177       PetscInfo3(NULL, "Ghost Vertex: %D   LID = %D \t GID = %D.\n", *iter, i, dmmoab->gsindices[i]);
178       if (bs > 1)
179         for (f=0;f<dmmoab->nfields;f++,j++)
180           dmmoab->lgmap[j]=dmmoab->gsindices[i]*dmmoab->nfields+f;
181       else
182         for (f=0;f<dmmoab->nfields;f++,j++)
183           dmmoab->lgmap[j]=totsize*f+dmmoab->gsindices[i];
184     }
185 
186     /* We need to create the Global to Local Vector Scatter Contexts
187        1) First create a local and global vector
188        2) Create a local and global IS
189        3) Create VecScatter and LtoGMapping objects
190        4) Cleanup the IS and Vec objects
191     */
192     ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr);
193     ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr);
194 
195     ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr);
196     PetscInfo3(NULL, "Total-size = %D\t Owned = %D, Ghosted = %D.\n", totsize, dmmoab->nloc, dmmoab->nghost);
197 
198     /* global to local must retrieve ghost points */
199 //    ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&dmmoab->lmap[0],PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
200 //    ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&dmmoab->gsindices[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
201 
202 //    ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,dmmoab->nghost,&dmmoab->lmap[dmmoab->nloc],PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
203 //    ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&dmmoab->gsindices[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
204 
205 
206     ierr = ISCreateStride(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->nfields,dmmoab->vstart,1,&from);CHKERRQ(ierr);
207     ierr = ISSetBlockSize(from,bs);CHKERRQ(ierr);
208 
209     ierr = ISCreateGeneral(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->nfields,&dmmoab->lgmap[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
210     ierr = ISSetBlockSize(to,bs);CHKERRQ(ierr);
211 
212 
213     if (!dmmoab->ltog_map) {
214       /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */
215       ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,totsize*dmmoab->nfields,dmmoab->lgmap,
216                                           PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr);
217     }
218 
219     ierr = VecScatterCreate(local,from,global,to,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
220 ///    ierr = VecScatterCreateToAll(global,&dmmoab->ltog_sendrecv,NULL);CHKERRQ(ierr);
221 //    PetscBarrier((PetscObject)dm);
222 //    VecScatterView(dmmoab->ltog_sendrecv,PETSC_VIEWER_STDOUT_SELF);
223 //    PetscBarrier((PetscObject)dm);
224     ierr = ISDestroy(&from);CHKERRQ(ierr);
225     ierr = ISDestroy(&to);CHKERRQ(ierr);
226     ierr = VecDestroy(&local);CHKERRQ(ierr);
227     ierr = VecDestroy(&global);CHKERRQ(ierr);
228   }
229 
230   /* skin the boundary and store nodes */
231   {
232     /* get the skin vertices of boundary faces for the current partition and then filter
233        the local, boundary faces, vertices and elements alone via PSTATUS flags;
234        this should not give us any ghosted boundary, but if user needs such a functionality
235        it would be easy to add it based on the find_skin query below */
236     moab::Skinner skinner(dmmoab->mbiface);
237 
238     dmmoab->bndyvtx = new moab::Range();
239     dmmoab->bndyfaces = new moab::Range();
240     dmmoab->bndyelems = new moab::Range();
241 
242     /* get the entities on the skin - only the faces */
243     merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces, NULL, false, true, false);MBERRNM(merr); // 'false' param indicates we want faces back, not vertices
244 
245     /* filter all the non-owned and shared entities out of the list */
246     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
247     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr);
248 
249     /* get all the nodes via connectivity and the parent elements via adjacency information */
250     merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr);
251     merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyfaces, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr);
252     PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyvtx->size(), dmmoab->bndyelems->size());
253   }
254   PetscFunctionReturn(0);
255 }
256 
257 
258 #undef __FUNCT__
259 #define __FUNCT__ "DMCreate_Moab"
260 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
261 {
262   PetscErrorCode ierr;
263 
264   PetscFunctionBegin;
265   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
266   ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr);
267 
268   ((DM_Moab*)dm->data)->bs = 1;
269   ((DM_Moab*)dm->data)->nfields = 1;
270   ((DM_Moab*)dm->data)->n = 0;
271   ((DM_Moab*)dm->data)->nloc = 0;
272   ((DM_Moab*)dm->data)->nele = 0;
273   ((DM_Moab*)dm->data)->neleloc = 0;
274   ((DM_Moab*)dm->data)->nghost = 0;
275   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
276   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
277 
278   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
279   ((DM_Moab*)dm->data)->vowned = new moab::Range();
280   ((DM_Moab*)dm->data)->vghost = new moab::Range();
281   ((DM_Moab*)dm->data)->elocal = new moab::Range();
282   ((DM_Moab*)dm->data)->eghost = new moab::Range();
283 
284   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
285   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
286   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
287   dm->ops->setup                           = DMSetUp_Moab;
288   dm->ops->destroy                         = DMDestroy_Moab;
289   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
290   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
291   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
292   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
293   PetscFunctionReturn(0);
294 }
295 
296 #undef __FUNCT__
297 #define __FUNCT__ "DMMoabCreate"
298 /*@
299   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
300 
301   Collective on MPI_Comm
302 
303   Input Parameter:
304 . comm - The communicator for the DMMoab object
305 
306   Output Parameter:
307 . dmb  - The DMMoab object
308 
309   Level: beginner
310 
311 .keywords: DMMoab, create
312 @*/
313 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
314 {
315   PetscErrorCode ierr;
316 
317   PetscFunctionBegin;
318   PetscValidPointer(dmb,2);
319   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
320   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
321   PetscFunctionReturn(0);
322 }
323 
324 #undef __FUNCT__
325 #define __FUNCT__ "DMMoabCreateMoab"
326 /*@
327   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
328 
329   Collective on MPI_Comm
330 
331   Input Parameter:
332 . comm - The communicator for the DMMoab object
333 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
334          along with the DMMoab
335 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
336 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
337 . range - If non-NULL, contains range of entities to which DOFs will be assigned
338 
339   Output Parameter:
340 . dmb  - The DMMoab object
341 
342   Level: intermediate
343 
344 .keywords: DMMoab, create
345 @*/
346 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
347 {
348   PetscErrorCode ierr;
349   moab::ErrorCode merr;
350   moab::EntityHandle partnset;
351   PetscInt rank, nprocs;
352   DM_Moab        *dmmoab;
353 
354   PetscFunctionBegin;
355   PetscValidPointer(dmb,6);
356   ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr);
357   dmmoab = (DM_Moab*)(*dmb)->data;
358 
359   if (!mbiface) {
360     dmmoab->mbiface = new moab::Core();
361     dmmoab->icreatedinstance = PETSC_TRUE;
362   }
363   else {
364     dmmoab->mbiface = mbiface;
365     dmmoab->icreatedinstance = PETSC_FALSE;
366   }
367 
368   /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */
369   dmmoab->fileset=0;
370 
371   if (!pcomm) {
372     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
373     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
374 
375     /* Create root sets for each mesh.  Then pass these
376        to the load_file functions to be populated. */
377     merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);MBERR("Creating partition set failed", merr);
378 
379     /* Create the parallel communicator object with the partition handle associated with MOAB */
380     dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
381   }
382   else {
383     ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr);
384   }
385 
386   /* do the remaining initializations for DMMoab */
387   dmmoab->bs = 1;
388   dmmoab->nfields = 1;
389 
390   /* set global ID tag handle */
391   if (!ltog_tag) {
392     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
393   }
394   else {
395     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
396   }
397 
398   /* set the local range of entities (vertices) of interest */
399   if (range) {
400     ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr);
401   }
402   PetscFunctionReturn(0);
403 }
404 
405 #undef __FUNCT__
406 #define __FUNCT__ "DMMoabSetParallelComm"
407 /*@
408   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
409 
410   Collective on MPI_Comm
411 
412   Input Parameter:
413 . dm    - The DMMoab object being set
414 . pcomm - The ParallelComm being set on the DMMoab
415 
416   Level: beginner
417 
418 .keywords: DMMoab, create
419 @*/
420 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
421 {
422   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
423 
424   PetscFunctionBegin;
425   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
426   PetscValidPointer(pcomm,2);
427   dmmoab->pcomm = pcomm;
428   dmmoab->mbiface = pcomm->get_moab();
429   dmmoab->icreatedinstance = PETSC_FALSE;
430   PetscFunctionReturn(0);
431 }
432 
433 
434 #undef __FUNCT__
435 #define __FUNCT__ "DMMoabGetParallelComm"
436 /*@
437   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
438 
439   Collective on MPI_Comm
440 
441   Input Parameter:
442 . dm    - The DMMoab object being set
443 
444   Output Parameter:
445 . pcomm - The ParallelComm for the DMMoab
446 
447   Level: beginner
448 
449 .keywords: DMMoab, create
450 @*/
451 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
452 {
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
455   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
456   PetscFunctionReturn(0);
457 }
458 
459 
460 #undef __FUNCT__
461 #define __FUNCT__ "DMMoabSetInterface"
462 /*@
463   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
464 
465   Collective on MPI_Comm
466 
467   Input Parameter:
468 . dm      - The DMMoab object being set
469 . mbiface - The MOAB instance being set on this DMMoab
470 
471   Level: beginner
472 
473 .keywords: DMMoab, create
474 @*/
475 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
476 {
477   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
478 
479   PetscFunctionBegin;
480   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
481   PetscValidPointer(mbiface,2);
482   dmmoab->pcomm = NULL;
483   dmmoab->mbiface = mbiface;
484   dmmoab->icreatedinstance = PETSC_FALSE;
485   PetscFunctionReturn(0);
486 }
487 
488 
489 #undef __FUNCT__
490 #define __FUNCT__ "DMMoabGetInterface"
491 /*@
492   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
493 
494   Collective on MPI_Comm
495 
496   Input Parameter:
497 . dm      - The DMMoab object being set
498 
499   Output Parameter:
500 . mbiface - The MOAB instance set on this DMMoab
501 
502   Level: beginner
503 
504 .keywords: DMMoab, create
505 @*/
506 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
507 {
508   PetscErrorCode   ierr;
509   static PetscBool cite = PETSC_FALSE;
510 
511   PetscFunctionBegin;
512   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
513   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);
514   *mbiface = ((DM_Moab*)dm->data)->mbiface;
515   PetscFunctionReturn(0);
516 }
517 
518 
519 #undef __FUNCT__
520 #define __FUNCT__ "DMMoabSetLocalVertices"
521 /*@
522   DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab
523 
524   Collective on MPI_Comm
525 
526   Input Parameter:
527 . dm    - The DMMoab object being set
528 . range - The entities treated by this DMMoab
529 
530   Level: beginner
531 
532 .keywords: DMMoab, create
533 @*/
534 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range)
535 {
536   moab::ErrorCode merr;
537   PetscErrorCode  ierr;
538   moab::Range     tmpvtxs;
539   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
540 
541   PetscFunctionBegin;
542   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
543   dmmoab->vlocal->clear();
544   dmmoab->vowned->clear();
545 
546   dmmoab->vlocal->insert(range->begin(), range->end());
547 
548   /* filter based on parallel status */
549   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr);
550 
551   /* filter all the non-owned and shared entities out of the list */
552   tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
553   merr = dmmoab->pcomm->filter_pstatus(tmpvtxs,PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr);
554   tmpvtxs = moab::subtract(tmpvtxs, *dmmoab->vghost);
555   *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs);
556 
557   /* compute and cache the sizes of local and ghosted entities */
558   dmmoab->nloc = dmmoab->vowned->size();
559   dmmoab->nghost = dmmoab->vghost->size();
560   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
561   PetscFunctionReturn(0);
562 }
563 
564 
565 #undef __FUNCT__
566 #define __FUNCT__ "DMMoabGetAllVertices"
567 /*@
568   DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab
569 
570   Collective on MPI_Comm
571 
572   Input Parameter:
573 . dm    - The DMMoab object being set
574 
575   Output Parameter:
576 . owned - The local vertex entities in this DMMoab = (owned+ghosted)
577 
578   Level: beginner
579 
580 .keywords: DMMoab, create
581 @*/
582 PetscErrorCode DMMoabGetAllVertices(DM dm,moab::Range *local)
583 {
584   PetscFunctionBegin;
585   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
586   if (local) *local = *((DM_Moab*)dm->data)->vlocal;
587   PetscFunctionReturn(0);
588 }
589 
590 
591 
592 #undef __FUNCT__
593 #define __FUNCT__ "DMMoabGetLocalVertices"
594 /*@
595   DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab
596 
597   Collective on MPI_Comm
598 
599   Input Parameter:
600 . dm    - The DMMoab object being set
601 
602   Output Parameter:
603 . owned - The owned vertex entities in this DMMoab
604 . ghost - The ghosted entities (non-owned) stored locally in this partition
605 
606   Level: beginner
607 
608 .keywords: DMMoab, create
609 @*/
610 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range *owned,moab::Range *ghost)
611 {
612   PetscFunctionBegin;
613   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
614   if (owned) *owned = *((DM_Moab*)dm->data)->vowned;
615   if (ghost) *ghost = *((DM_Moab*)dm->data)->vghost;
616   PetscFunctionReturn(0);
617 }
618 
619 #undef __FUNCT__
620 #define __FUNCT__ "DMMoabGetLocalElements"
621 /*@
622   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
623 
624   Collective on MPI_Comm
625 
626   Input Parameter:
627 . dm    - The DMMoab object being set
628 
629   Output Parameter:
630 . range - The entities owned locally
631 
632   Level: beginner
633 
634 .keywords: DMMoab, create
635 @*/
636 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range *range)
637 {
638   PetscFunctionBegin;
639   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
640   if (range) *range = *((DM_Moab*)dm->data)->elocal;
641   PetscFunctionReturn(0);
642 }
643 
644 
645 #undef __FUNCT__
646 #define __FUNCT__ "DMMoabSetLocalElements"
647 /*@
648   DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab
649 
650   Collective on MPI_Comm
651 
652   Input Parameter:
653 . dm    - The DMMoab object being set
654 . range - The entities treated by this DMMoab
655 
656   Level: beginner
657 
658 .keywords: DMMoab, create
659 @*/
660 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range)
661 {
662   moab::ErrorCode merr;
663   PetscErrorCode  ierr;
664   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
665 
666   PetscFunctionBegin;
667   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
668   dmmoab->elocal->clear();
669   dmmoab->eghost->clear();
670   dmmoab->elocal->insert(range->begin(), range->end());
671   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
672   *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal);
673   dmmoab->neleloc=dmmoab->elocal->size();
674   ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
675   PetscInfo2(dm, "Created %D local and %D global elements.\n", dmmoab->neleloc, dmmoab->nele);
676   PetscFunctionReturn(0);
677 }
678 
679 
680 #undef __FUNCT__
681 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
682 /*@
683   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
684 
685   Collective on MPI_Comm
686 
687   Input Parameter:
688 . dm      - The DMMoab object being set
689 . ltogtag - The MOAB tag used for local to global ids
690 
691   Level: beginner
692 
693 .keywords: DMMoab, create
694 @*/
695 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
696 {
697   PetscFunctionBegin;
698   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
699   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
700   PetscFunctionReturn(0);
701 }
702 
703 
704 #undef __FUNCT__
705 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
706 /*@
707   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
708 
709   Collective on MPI_Comm
710 
711   Input Parameter:
712 . dm      - The DMMoab object being set
713 
714   Output Parameter:
715 . ltogtag - The MOAB tag used for local to global ids
716 
717   Level: beginner
718 
719 .keywords: DMMoab, create
720 @*/
721 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
722 {
723   PetscFunctionBegin;
724   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
725   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
726   PetscFunctionReturn(0);
727 }
728 
729 
730 #undef __FUNCT__
731 #define __FUNCT__ "DMMoabSetBlockSize"
732 /*@
733   DMMoabSetBlockSize - Set the block size used with this DMMoab
734 
735   Collective on MPI_Comm
736 
737   Input Parameter:
738 . dm - The DMMoab object being set
739 . bs - The block size used with this DMMoab
740 
741   Level: beginner
742 
743 .keywords: DMMoab, create
744 @*/
745 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
746 {
747   PetscFunctionBegin;
748   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
749   ((DM_Moab*)dm->data)->bs = bs;
750   PetscFunctionReturn(0);
751 }
752 
753 
754 #undef __FUNCT__
755 #define __FUNCT__ "DMMoabGetBlockSize"
756 /*@
757   DMMoabGetBlockSize - Get the block size used with this DMMoab
758 
759   Collective on MPI_Comm
760 
761   Input Parameter:
762 . dm - The DMMoab object being set
763 
764   Output Parameter:
765 . bs - The block size used with this DMMoab
766 
767   Level: beginner
768 
769 .keywords: DMMoab, create
770 @*/
771 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
772 {
773   PetscFunctionBegin;
774   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
775   *bs = ((DM_Moab*)dm->data)->bs;
776   PetscFunctionReturn(0);
777 }
778 
779 
780 #undef __FUNCT__
781 #define __FUNCT__ "DMMoabGetSize"
782 /*@
783   DMMoabGetSize - Get the global vertex size used with this DMMoab
784 
785   Collective on MPI_Comm
786 
787   Input Parameter:
788 . dm - The DMMoab object being set
789 
790   Output Parameter:
791 . ng - The global size of the DMMoab instance
792 
793   Level: beginner
794 
795 .keywords: DMMoab, create
796 @*/
797 PetscErrorCode DMMoabGetSize(DM dm,PetscInt *ng)
798 {
799   PetscFunctionBegin;
800   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
801   if(ng) *ng = ((DM_Moab*)dm->data)->n;
802   PetscFunctionReturn(0);
803 }
804 
805 
806 #undef __FUNCT__
807 #define __FUNCT__ "DMMoabGetLocalSize"
808 /*@
809   DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab
810 
811   Collective on MPI_Comm
812 
813   Input Parameter:
814 . dm - The DMMoab object being set
815 
816   Output Parameter:
817 . nl - The local size of the DMMoab instance
818 . ng - The ghosted size of the DMMoab instance
819 
820   Level: beginner
821 
822 .keywords: DMMoab, create
823 @*/
824 PetscErrorCode DMMoabGetLocalSize(DM dm,PetscInt *nl,PetscInt *ng)
825 {
826   PetscFunctionBegin;
827   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
828   if(nl) *nl = ((DM_Moab*)dm->data)->nloc;
829   if(ng) *ng = ((DM_Moab*)dm->data)->nghost;
830   PetscFunctionReturn(0);
831 }
832 
833 
834 #undef __FUNCT__
835 #define __FUNCT__ "DMMoabGetDimension"
836 /*@
837   DMMoabGetDimension - Get the dimension of the DM Mesh
838 
839   Collective on MPI_Comm
840 
841   Input Parameter:
842 . dm - The DMMoab object being set
843 
844   Output Parameter:
845 . dim - The dimension of DM
846 
847   Level: beginner
848 
849 .keywords: DMMoab, create
850 @*/
851 PetscErrorCode DMMoabGetDimension(DM dm,PetscInt *dim)
852 {
853   PetscFunctionBegin;
854   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
855   *dim = ((DM_Moab*)dm->data)->dim;
856   PetscFunctionReturn(0);
857 }
858 
859 
860 
861 #undef __FUNCT__
862 #define __FUNCT__ "DMMoabGetVertexCoordinates"
863 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscScalar *vpos)
864 {
865   DM_Moab         *dmmoab;
866   PetscErrorCode  ierr;
867   moab::ErrorCode merr;
868 
869   PetscFunctionBegin;
870   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
871   PetscValidPointer(conn,3);
872   dmmoab = (DM_Moab*)(dm)->data;
873 
874   if (!vpos) {
875     ierr = PetscMalloc(sizeof(PetscScalar)*nconn*3, &vpos);CHKERRQ(ierr);
876   }
877 
878   /* Get connectivity information in MOAB canonical ordering */
879   merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr);
880   PetscFunctionReturn(0);
881 }
882 
883 
884 #undef __FUNCT__
885 #define __FUNCT__ "DMMoabGetVertexConnectivity"
886 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn)
887 {
888   DM_Moab        *dmmoab;
889   std::vector<moab::EntityHandle> adj_entities,connect;
890   PetscErrorCode  ierr;
891   moab::ErrorCode merr;
892 
893   PetscFunctionBegin;
894   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
895   PetscValidPointer(conn,4);
896   dmmoab = (DM_Moab*)(dm)->data;
897 
898   /* Get connectivity information in MOAB canonical ordering */
899   merr = dmmoab->mbiface->get_adjacencies(&ehandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr);
900   merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr);
901 
902   if (conn) {
903     ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr);
904     ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr);
905   }
906   if (nconn) *nconn=connect.size();
907   PetscFunctionReturn(0);
908 }
909 
910 
911 #undef __FUNCT__
912 #define __FUNCT__ "DMMoabRestoreVertexConnectivity"
913 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn)
914 {
915   PetscErrorCode  ierr;
916 
917   PetscFunctionBegin;
918   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
919   PetscValidPointer(conn,4);
920 
921   if (conn) {
922     ierr = PetscFree(*conn);CHKERRQ(ierr);
923   }
924   if (nconn) *nconn=0;
925   PetscFunctionReturn(0);
926 }
927 
928 
929 
930 #undef __FUNCT__
931 #define __FUNCT__ "DMMoabGetElementConnectivity"
932 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn)
933 {
934   DM_Moab        *dmmoab;
935   const moab::EntityHandle *connect;
936   moab::ErrorCode merr;
937   PetscInt nnodes;
938 
939   PetscFunctionBegin;
940   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
941   PetscValidPointer(conn,4);
942   dmmoab = (DM_Moab*)(dm)->data;
943 
944   /* Get connectivity information in MOAB canonical ordering */
945   merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr);
946   if (conn) *conn=connect;
947   if (nconn) *nconn=nnodes;
948   PetscFunctionReturn(0);
949 }
950 
951 
952 #undef __FUNCT__
953 #define __FUNCT__ "DMMoabIsEntityOnBoundary"
954 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary)
955 {
956   moab::EntityType etype;
957   DM_Moab         *dmmoab;
958   PetscInt         edim;
959 
960   PetscFunctionBegin;
961   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
962   PetscValidPointer(ent_on_boundary,3);
963   dmmoab = (DM_Moab*)(dm)->data;
964 
965   /* get the entity type and handle accordingly */
966   etype=dmmoab->mbiface->type_from_handle(ent);
967   if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype);
968 
969   /* get the entity dimension */
970   edim=dmmoab->mbiface->dimension_from_handle(ent);
971 
972   *ent_on_boundary=PETSC_FALSE;
973   if(etype == moab::MBVERTEX && edim == 0) {
974     if (dmmoab->bndyvtx->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE;
975   }
976   else {
977     if (edim == dmmoab->dim) {  /* check the higher-dimensional elements first */
978       if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE;
979     }
980     else {                      /* next check the lower-dimensional faces */
981       if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE;
982     }
983   }
984   PetscFunctionReturn(0);
985 }
986 
987 
988 #undef __FUNCT__
989 #define __FUNCT__ "DMMoabCheckBoundaryVertices"
990 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx)
991 {
992   DM_Moab        *dmmoab;
993   PetscInt       i;
994 
995   PetscFunctionBegin;
996   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
997   PetscValidPointer(cnt,3);
998   PetscValidPointer(isbdvtx,4);
999   dmmoab = (DM_Moab*)(dm)->data;
1000 
1001   for (i=0; i < nconn; ++i) {
1002     isbdvtx[i]=(dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE:PETSC_FALSE);
1003   }
1004   PetscFunctionReturn(0);
1005 }
1006 
1007 
1008 #undef __FUNCT__
1009 #define __FUNCT__ "DMMoabGetBoundaryMarkers"
1010 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,const moab::Range **bdvtx,const moab::Range** bdelems,const moab::Range** bdfaces)
1011 {
1012   DM_Moab        *dmmoab;
1013 
1014   PetscFunctionBegin;
1015   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1016   dmmoab = (DM_Moab*)(dm)->data;
1017 
1018   if (bdvtx)  *bdvtx = dmmoab->bndyvtx;
1019   if (bdfaces)  *bdfaces = dmmoab->bndyfaces;
1020   if (bdelems)  *bdfaces = dmmoab->bndyelems;
1021   PetscFunctionReturn(0);
1022 }
1023 
1024