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