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