xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision 1cec0304154dc24c6cd49e0c7607a315ec6ede7d)
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 #include <moab/Skinner.hpp>
7 
8 #undef __FUNCT__
9 #define __FUNCT__ "DMDestroy_Moab"
10 PetscErrorCode DMDestroy_Moab(DM dm)
11 {
12   PetscErrorCode ierr;
13   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
14 
15   PetscFunctionBegin;
16   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17   if (dmmoab->icreatedinstance) {
18     delete dmmoab->mbiface;
19   }
20   dmmoab->mbiface = NULL;
21   dmmoab->pcomm = NULL;
22   delete dmmoab->vlocal;
23   delete dmmoab->vowned;
24   delete dmmoab->vghost;
25   delete dmmoab->elocal;
26   delete dmmoab->eghost;
27   delete dmmoab->bndyvtx;
28   delete dmmoab->bndyfaces;
29   ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
30   ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr);
31   ierr = PetscFree(dm->data);CHKERRQ(ierr);
32   PetscFunctionReturn(0);
33 }
34 
35 #undef __FUNCT__
36 #define __FUNCT__ "DMSetUp_Moab"
37 PetscErrorCode DMSetUp_Moab(DM dm)
38 {
39   PetscErrorCode          ierr;
40   moab::ErrorCode         merr;
41   Vec                     local, global;
42   IS                      from;
43   moab::Range::iterator   iter;
44   PetscInt                i,j,bs,gsiz,lsiz,*gsindices;
45   DM_Moab                *dmmoab = (DM_Moab*)dm->data;
46   PetscInt                totsize;
47   PetscSection            section;
48 
49   PetscFunctionBegin;
50   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
51   /* Get the local and shared vertices and cache it */
52   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.");
53 
54   /* store the current mesh dimension */
55   merr = dmmoab->mbiface->get_dimension(dmmoab->dim);MBERRNM(merr);
56 
57   /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */
58   if (dmmoab->vlocal->empty()) {
59     merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr);
60     *dmmoab->vowned = *dmmoab->vlocal;
61 
62     /* filter based on parallel status */
63     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
64     *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned);
65 
66     dmmoab->nloc = dmmoab->vowned->size();
67     dmmoab->nghost = dmmoab->vghost->size();
68     ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
69   }
70 
71   /* get the information about the local elements in the mesh */
72   {
73     dmmoab->elocal->clear();
74     dmmoab->eghost->clear();
75     merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, dmmoab->dim, *dmmoab->elocal, true);CHKERRQ(merr);
76     *dmmoab->eghost = *dmmoab->elocal;
77     merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
78     *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal);
79 
80     dmmoab->neleloc = dmmoab->elocal->size();
81     ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
82   }
83 
84   bs = dmmoab->bs;
85   if (!dmmoab->ltog_tag) {
86     /* Get the global ID tag. The global ID tag is applied to each
87        vertex. It acts as an global identifier which MOAB uses to
88        assemble the individual pieces of the mesh */
89     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
90   }
91 
92   totsize=dmmoab->vlocal->size();
93   ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr);
94   {
95     /* first get the local indices */
96     merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&gsindices[0]);MBERRNM(merr);
97     /* next get the ghosted indices */
98     if (dmmoab->vghost->size()) {
99       merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&gsindices[dmmoab->nloc]);MBERRNM(merr);
100     }
101   }
102 
103   {
104     ierr = PetscSectionCreate(((PetscObject)dm)->comm, &section);CHKERRQ(ierr);
105     ierr = PetscSectionSetNumFields(section, dmmoab->nfields);CHKERRQ(ierr);
106     ierr = PetscSectionSetChart(section, gsindices[0], gsindices[dmmoab->nloc-1]+1);CHKERRQ(ierr);
107     for (j=gsindices[0]; j<=gsindices[dmmoab->nloc-1]; ++j) {
108       for (i=0; i < dmmoab->nfields; ++i) {
109         ierr = PetscSectionSetFieldName(section, i, dmmoab->fields[i]);CHKERRQ(ierr);
110         if (bs>1) {
111           ierr = PetscSectionSetFieldDof(section, j, i, j*dmmoab->nfields+i-1);CHKERRQ(ierr);
112           ierr = PetscSectionSetFieldOffset(section, j, i, dmmoab->nfields);
113 //          PetscPrintf(PETSC_COMM_WORLD, "Point %D, Field %D, DOF %D, OFFSET = %D\n", j, i, j*dmmoab->nfields+i, dmmoab->nfields);
114         }
115         else {
116           ierr = PetscSectionSetFieldDof(section, j, i, totsize*i+j-1);CHKERRQ(ierr);
117           ierr = PetscSectionSetFieldOffset(section, j, i, totsize);
118 //          PetscPrintf(PETSC_COMM_WORLD, "Point %D, Field %D, DOF %D, OFFSET = %D\n", j, i, totsize*i+j, totsize);
119         }
120       }
121       ierr = PetscSectionSetDof(section, j, dmmoab->nfields);CHKERRQ(ierr);
122     }
123     ierr = PetscSectionSetUp(section);CHKERRQ(ierr);
124     ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr);
125   }
126 
127   {
128     /* Create Global to Local Vector Scatter Context */
129     ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr);
130     ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr);
131 
132     for (i=0; i<totsize; ++i) {
133       gsindices[i]--;   /* zero based index needed for IS */
134     }
135 
136     /* global to local must retrieve ghost points */
137     ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&gsindices[0],PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
138 
139     ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr);
140     ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr);
141 
142     ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr);
143     ierr = ISDestroy(&from);CHKERRQ(ierr);
144     ierr = VecDestroy(&local);CHKERRQ(ierr);
145     ierr = VecDestroy(&global);CHKERRQ(ierr);
146   }
147 
148   /* skin the boundary and store nodes */
149   {
150     // get the skin vertices of those faces and mark them as fixed; we don't want to fix the vertices on a
151     // part boundary, but since we exchanged a layer of ghost faces, those vertices aren't on the skin locally
152     // ok to mark non-owned skin vertices too, I won't move those anyway
153     // use MOAB's skinner class to find the skin
154     moab::Skinner skinner(dmmoab->mbiface);
155     dmmoab->bndyvtx = new moab::Range();
156     dmmoab->bndyfaces = new moab::Range();
157     merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, true, *dmmoab->bndyvtx);MBERRNM(merr); // 'true' param indicates we want vertices back, not faces
158     merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces);MBERRNM(merr); // 'false' param indicates we want faces back, not vertices
159     PetscPrintf(PETSC_COMM_WORLD, "\nFound %D boundary vertices and %D faces.\n", dmmoab->bndyvtx->size(), dmmoab->bndyvtx->size());
160   }
161 
162   ierr = PetscFree(gsindices);CHKERRQ(ierr);
163   PetscFunctionReturn(0);
164 }
165 
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "DMCreate_Moab"
169 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm)
170 {
171   PetscErrorCode ierr;
172 
173   PetscFunctionBegin;
174   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
175   ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr);
176 
177   ((DM_Moab*)dm->data)->bs = 1;
178   ((DM_Moab*)dm->data)->n = 0;
179   ((DM_Moab*)dm->data)->nloc = 0;
180   ((DM_Moab*)dm->data)->nele = 0;
181   ((DM_Moab*)dm->data)->neleloc = 0;
182   ((DM_Moab*)dm->data)->nghost = 0;
183   ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL;
184   ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL;
185 
186   ((DM_Moab*)dm->data)->vlocal = new moab::Range();
187   ((DM_Moab*)dm->data)->vowned = new moab::Range();
188   ((DM_Moab*)dm->data)->vghost = new moab::Range();
189   ((DM_Moab*)dm->data)->elocal = new moab::Range();
190   ((DM_Moab*)dm->data)->eghost = new moab::Range();
191 
192   dm->ops->createglobalvector              = DMCreateGlobalVector_Moab;
193   dm->ops->createlocalvector               = DMCreateLocalVector_Moab;
194   dm->ops->creatematrix                    = DMCreateMatrix_Moab;
195   dm->ops->setup                           = DMSetUp_Moab;
196   dm->ops->destroy                         = DMDestroy_Moab;
197   dm->ops->globaltolocalbegin              = DMGlobalToLocalBegin_Moab;
198   dm->ops->globaltolocalend                = DMGlobalToLocalEnd_Moab;
199   dm->ops->localtoglobalbegin              = DMLocalToGlobalBegin_Moab;
200   dm->ops->localtoglobalend                = DMLocalToGlobalEnd_Moab;
201   PetscFunctionReturn(0);
202 }
203 
204 #undef __FUNCT__
205 #define __FUNCT__ "DMMoabCreate"
206 /*@
207   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
208 
209   Collective on MPI_Comm
210 
211   Input Parameter:
212 . comm - The communicator for the DMMoab object
213 
214   Output Parameter:
215 . dmb  - The DMMoab object
216 
217   Level: beginner
218 
219 .keywords: DMMoab, create
220 @*/
221 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb)
222 {
223   PetscErrorCode ierr;
224 
225   PetscFunctionBegin;
226   PetscValidPointer(dmb,2);
227   ierr = DMCreate(comm, dmb);CHKERRQ(ierr);
228   ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr);
229   PetscFunctionReturn(0);
230 }
231 
232 #undef __FUNCT__
233 #define __FUNCT__ "DMMoabCreateMoab"
234 /*@
235   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
236 
237   Collective on MPI_Comm
238 
239   Input Parameter:
240 . comm - The communicator for the DMMoab object
241 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
242          along with the DMMoab
243 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
244 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
245 . range - If non-NULL, contains range of entities to which DOFs will be assigned
246 
247   Output Parameter:
248 . dmb  - The DMMoab object
249 
250   Level: intermediate
251 
252 .keywords: DMMoab, create
253 @*/
254 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb)
255 {
256   PetscErrorCode ierr;
257   moab::ErrorCode merr;
258   moab::EntityHandle partnset;
259   PetscInt rank, nprocs;
260   DM_Moab        *dmmoab;
261 
262   PetscFunctionBegin;
263   PetscValidPointer(dmb,6);
264   ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr);
265   dmmoab = (DM_Moab*)(*dmb)->data;
266 
267   if (!mbiface) {
268     dmmoab->mbiface = new moab::Core();
269     dmmoab->icreatedinstance = PETSC_TRUE;
270   }
271   else {
272     dmmoab->mbiface = mbiface;
273     dmmoab->icreatedinstance = PETSC_FALSE;
274   }
275 
276   /* create a fileset to store the hierarchy of entities belonging to current DM */
277   merr = dmmoab->mbiface->create_meshset(moab::MESHSET_ORDERED, dmmoab->fileset);MBERR("Creating file set failed", merr);
278 
279   if (!pcomm) {
280     ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
281     ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr);
282 
283     /* Create root sets for each mesh.  Then pass these
284        to the load_file functions to be populated. */
285     merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);
286     MBERR("Creating partition set failed", merr);
287 
288     /* Create the parallel communicator object with the partition handle associated with MOAB */
289     dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm);
290   }
291   else {
292     ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr);
293   }
294 
295   /* do the remaining initializations for DMMoab */
296   dmmoab->bs       = 1;
297 
298   /* set global ID tag handle */
299   if (!ltog_tag) {
300     merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr);
301   }
302   else {
303     ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr);
304   }
305 
306   /* set the local range of entities (vertices) of interest */
307   if (range) {
308     ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr);
309   }
310   PetscFunctionReturn(0);
311 }
312 
313 #undef __FUNCT__
314 #define __FUNCT__ "DMMoabSetParallelComm"
315 /*@
316   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
317 
318   Collective on MPI_Comm
319 
320   Input Parameter:
321 . dm    - The DMMoab object being set
322 . pcomm - The ParallelComm being set on the DMMoab
323 
324   Level: beginner
325 
326 .keywords: DMMoab, create
327 @*/
328 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
329 {
330   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
331 
332   PetscFunctionBegin;
333   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
334   PetscValidPointer(pcomm,2);
335   dmmoab->pcomm = pcomm;
336   dmmoab->mbiface = pcomm->get_moab();
337   dmmoab->icreatedinstance = PETSC_FALSE;
338   PetscFunctionReturn(0);
339 }
340 
341 
342 #undef __FUNCT__
343 #define __FUNCT__ "DMMoabGetParallelComm"
344 /*@
345   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
346 
347   Collective on MPI_Comm
348 
349   Input Parameter:
350 . dm    - The DMMoab object being set
351 
352   Output Parameter:
353 . pcomm - The ParallelComm for the DMMoab
354 
355   Level: beginner
356 
357 .keywords: DMMoab, create
358 @*/
359 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
360 {
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
363   *pcomm = ((DM_Moab*)(dm)->data)->pcomm;
364   PetscFunctionReturn(0);
365 }
366 
367 
368 #undef __FUNCT__
369 #define __FUNCT__ "DMMoabSetInterface"
370 /*@
371   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
372 
373   Collective on MPI_Comm
374 
375   Input Parameter:
376 . dm      - The DMMoab object being set
377 . mbiface - The MOAB instance being set on this DMMoab
378 
379   Level: beginner
380 
381 .keywords: DMMoab, create
382 @*/
383 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
384 {
385   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
386 
387   PetscFunctionBegin;
388   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
389   PetscValidPointer(mbiface,2);
390   dmmoab->pcomm = NULL;
391   dmmoab->mbiface = mbiface;
392   dmmoab->icreatedinstance = PETSC_FALSE;
393   PetscFunctionReturn(0);
394 }
395 
396 
397 #undef __FUNCT__
398 #define __FUNCT__ "DMMoabGetInterface"
399 /*@
400   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
401 
402   Collective on MPI_Comm
403 
404   Input Parameter:
405 . dm      - The DMMoab object being set
406 
407   Output Parameter:
408 . mbiface - The MOAB instance set on this DMMoab
409 
410   Level: beginner
411 
412 .keywords: DMMoab, create
413 @*/
414 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
415 {
416   PetscErrorCode   ierr;
417   static PetscBool cite = PETSC_FALSE;
418 
419   PetscFunctionBegin;
420   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
421   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);
422   *mbiface = ((DM_Moab*)dm->data)->mbiface;
423   PetscFunctionReturn(0);
424 }
425 
426 
427 #undef __FUNCT__
428 #define __FUNCT__ "DMMoabSetLocalVertices"
429 /*@
430   DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab
431 
432   Collective on MPI_Comm
433 
434   Input Parameter:
435 . dm    - The DMMoab object being set
436 . range - The entities treated by this DMMoab
437 
438   Level: beginner
439 
440 .keywords: DMMoab, create
441 @*/
442 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range)
443 {
444   moab::ErrorCode merr;
445   PetscErrorCode  ierr;
446   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
447 
448   PetscFunctionBegin;
449   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
450   dmmoab->vlocal->clear();
451   dmmoab->vowned->clear();
452   dmmoab->vlocal->insert(range->begin(), range->end());
453   *dmmoab->vowned = *dmmoab->vlocal;
454   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
455   *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned);
456   dmmoab->nloc=dmmoab->vowned->size();
457   dmmoab->nghost=dmmoab->vghost->size();
458   ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
459   PetscFunctionReturn(0);
460 }
461 
462 
463 #undef __FUNCT__
464 #define __FUNCT__ "DMMoabGetLocalVertices"
465 /*@
466   DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab
467 
468   Collective on MPI_Comm
469 
470   Input Parameter:
471 . dm    - The DMMoab object being set
472 
473   Output Parameter:
474 . owned - The owned vertex entities in this DMMoab
475 . ghost - The ghosted entities (non-owned) stored locally in this partition
476 
477   Level: beginner
478 
479 .keywords: DMMoab, create
480 @*/
481 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range *owned,moab::Range *ghost)
482 {
483   PetscFunctionBegin;
484   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
485   if (owned) *owned = *((DM_Moab*)dm->data)->vowned;
486   if (ghost) *ghost = *((DM_Moab*)dm->data)->vghost;
487   PetscFunctionReturn(0);
488 }
489 
490 #undef __FUNCT__
491 #define __FUNCT__ "DMMoabGetLocalElements"
492 /*@
493   DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned
494 
495   Collective on MPI_Comm
496 
497   Input Parameter:
498 . dm    - The DMMoab object being set
499 
500   Output Parameter:
501 . range - The entities owned locally
502 
503   Level: beginner
504 
505 .keywords: DMMoab, create
506 @*/
507 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range *range)
508 {
509   PetscFunctionBegin;
510   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
511   if (range) *range = *((DM_Moab*)dm->data)->elocal;
512   PetscFunctionReturn(0);
513 }
514 
515 
516 #undef __FUNCT__
517 #define __FUNCT__ "DMMoabSetLocalElements"
518 /*@
519   DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab
520 
521   Collective on MPI_Comm
522 
523   Input Parameter:
524 . dm    - The DMMoab object being set
525 . range - The entities treated by this DMMoab
526 
527   Level: beginner
528 
529 .keywords: DMMoab, create
530 @*/
531 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range)
532 {
533   moab::ErrorCode merr;
534   PetscErrorCode  ierr;
535   DM_Moab        *dmmoab = (DM_Moab*)(dm)->data;
536 
537   PetscFunctionBegin;
538   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
539   dmmoab->elocal->clear();
540   dmmoab->eghost->clear();
541   dmmoab->elocal->insert(range->begin(), range->end());
542   PetscInfo2(dm, "Range size = %D; elocal size = %D.\n", range->size(), dmmoab->elocal->size());
543   merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr);
544   *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal);
545   dmmoab->neleloc=dmmoab->elocal->size();
546   ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr);
547   PetscInfo2(dm, "Created %D local and %D glocal elements.\n", dmmoab->neleloc, dmmoab->nele);
548   PetscFunctionReturn(0);
549 }
550 
551 
552 #undef __FUNCT__
553 #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
554 /*@
555   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
556 
557   Collective on MPI_Comm
558 
559   Input Parameter:
560 . dm      - The DMMoab object being set
561 . ltogtag - The MOAB tag used for local to global ids
562 
563   Level: beginner
564 
565 .keywords: DMMoab, create
566 @*/
567 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
568 {
569   PetscFunctionBegin;
570   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
571   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
572   PetscFunctionReturn(0);
573 }
574 
575 
576 #undef __FUNCT__
577 #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
578 /*@
579   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
580 
581   Collective on MPI_Comm
582 
583   Input Parameter:
584 . dm      - The DMMoab object being set
585 
586   Output Parameter:
587 . ltogtag - The MOAB tag used for local to global ids
588 
589   Level: beginner
590 
591 .keywords: DMMoab, create
592 @*/
593 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
594 {
595   PetscFunctionBegin;
596   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
597   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
598   PetscFunctionReturn(0);
599 }
600 
601 
602 #undef __FUNCT__
603 #define __FUNCT__ "DMMoabSetBlockSize"
604 /*@
605   DMMoabSetBlockSize - Set the block size used with this DMMoab
606 
607   Collective on MPI_Comm
608 
609   Input Parameter:
610 . dm - The DMMoab object being set
611 . bs - The block size used with this DMMoab
612 
613   Level: beginner
614 
615 .keywords: DMMoab, create
616 @*/
617 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
618 {
619   PetscFunctionBegin;
620   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
621   ((DM_Moab*)dm->data)->bs = bs;
622   PetscFunctionReturn(0);
623 }
624 
625 
626 #undef __FUNCT__
627 #define __FUNCT__ "DMMoabGetBlockSize"
628 /*@
629   DMMoabGetBlockSize - Get the block size used with this DMMoab
630 
631   Collective on MPI_Comm
632 
633   Input Parameter:
634 . dm - The DMMoab object being set
635 
636   Output Parameter:
637 . bs - The block size used with this DMMoab
638 
639   Level: beginner
640 
641 .keywords: DMMoab, create
642 @*/
643 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
644 {
645   PetscFunctionBegin;
646   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
647   *bs = ((DM_Moab*)dm->data)->bs;
648   PetscFunctionReturn(0);
649 }
650 
651 
652 #undef __FUNCT__
653 #define __FUNCT__ "DMMoabSetFieldVector"
654 PetscErrorCode DMMoabSetFieldVector(DM dm, PetscInt ifield, Vec fvec)
655 {
656   DM_Moab        *dmmoab;
657   moab::Tag     vtag,ntag;
658   PetscScalar   *varray;
659   moab::ErrorCode merr;
660   PetscErrorCode  ierr;
661   PetscSection section;
662   PetscInt doff;
663   std::string tag_name;
664   moab::Range::iterator iter;
665 
666   PetscFunctionBegin;
667   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
668   dmmoab = (DM_Moab*)(dm)->data;
669 
670   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
671 
672   /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
673   merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag,
674                                           moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr);
675 
676   ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr);
677 
678   merr = dmmoab->mbiface->tag_get_name(vtag, tag_name);
679   if (!tag_name.length() && merr !=moab::MB_SUCCESS) {
680     ierr = DMMoabVecGetArray(dm,fvec,&varray);CHKERRQ(ierr);
681     for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) {
682       moab::EntityHandle vtx = (*iter);
683 
684       /* get field dof index */
685       ierr = PetscSectionGetFieldOffset(section, vtx, ifield, &doff);
686 
687       /* use the entity handle and the Dof index to set the right value */
688       merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr);
689     }
690     ierr = DMMoabVecRestoreArray(dm,fvec,&varray);CHKERRQ(ierr);
691   }
692   else {
693     ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&varray);CHKERRQ(ierr);
694     /* we are using a MOAB Vec - directly copy the tag data to new one */
695     merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)varray);MBERRNM(merr);
696     merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)varray);MBERRNM(merr);
697     /* make sure the parallel exchange for ghosts are done appropriately */
698     merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr);
699     ierr = PetscFree(varray);CHKERRQ(ierr);
700   }
701   PetscFunctionReturn(0);
702 }
703 
704 
705 #undef __FUNCT__
706 #define __FUNCT__ "DMMoabGetBoundaryEntities"
707 PetscErrorCode DMMoabGetBoundaryEntities(DM dm,moab::Range *bdvtx,moab::Range* bdfaces)
708 {
709   DM_Moab        *dmmoab;
710 
711   PetscFunctionBegin;
712   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
713   dmmoab = (DM_Moab*)(dm)->data;
714 
715   if (bdvtx)  *bdvtx = *dmmoab->bndyvtx;
716   if (bdfaces)  *bdfaces = *dmmoab->bndyfaces;
717   PetscFunctionReturn(0);
718 }
719 
720 
721 #undef __FUNCT__
722 #define __FUNCT__ "DMMoabOutput"
723 PetscErrorCode DMMoabOutput(DM dm,const char* fname,const char* wopts)
724 {
725   DM_Moab        *dmmoab;
726   moab::ErrorCode merr;
727 
728   PetscFunctionBegin;
729   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
730   dmmoab = (DM_Moab*)(dm)->data;
731 
732   // output file, using parallel write
733   merr = dmmoab->mbiface->write_file(fname, NULL, wopts);MBERRVM(dmmoab->mbiface,"Writing output of DMMoab failed.",merr);
734   PetscFunctionReturn(0);
735 }
736 
737 
738 #undef __FUNCT__
739 #define __FUNCT__ "DMMoabSetFields"
740 PetscErrorCode DMMoabSetFields(DM dm,PetscInt nfields,const char** fields)
741 {
742   DM_Moab        *dmmoab;
743 
744   PetscFunctionBegin;
745   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
746   dmmoab = (DM_Moab*)(dm)->data;
747 
748   dmmoab->fields = fields;
749   dmmoab->nfields = nfields;
750   PetscFunctionReturn(0);
751 }
752 
753 
754 #undef __FUNCT__
755 #define __FUNCT__ "DMMoabGetFieldDof"
756 PetscErrorCode DMMoabGetFieldDof(DM dm,moab::EntityHandle point,PetscInt field,PetscInt* dof)
757 {
758   PetscSection section;
759   PetscErrorCode ierr;
760 
761   PetscFunctionBegin;
762   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
763   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
764   ierr = PetscSectionGetFieldDof(section, (PetscInt)point, field, dof);CHKERRQ(ierr);
765   PetscFunctionReturn(0);
766 }
767 
768 
769 #undef __FUNCT__
770 #define __FUNCT__ "DMMoabGetFieldDofs"
771 PetscErrorCode DMMoabGetFieldDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof)
772 {
773   PetscInt i;
774   PetscSection section;
775   PetscErrorCode ierr;
776 
777   PetscFunctionBegin;
778   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
779   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
780   if (!dof) {
781     ierr = PetscMalloc(sizeof(PetscScalar)*npoints, &dof);CHKERRQ(ierr);
782   }
783   for (i=0; i<npoints; ++i) {
784     ierr = PetscSectionGetFieldDof(section, (PetscInt)points[i], field, &dof[i]);CHKERRQ(ierr);
785   }
786   PetscFunctionReturn(0);
787 }
788 
789 
790