xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision aa768e4c55e7f3620f7ce62e5a108dc2c69d8893)
11d72bce8STim Tautges #include <petsc-private/dmimpl.h> /*I  "petscdm.h"   I*/
2*aa768e4cSTim Tautges #include <petsc-private/vecimpl.h> /*I  "petscdm.h"   I*/
31d72bce8STim Tautges 
41d72bce8STim Tautges #include <petscdmmoab.h>
51d72bce8STim Tautges #include "MBTagConventions.hpp"
61d72bce8STim Tautges 
71d72bce8STim Tautges typedef struct {
81d72bce8STim Tautges   PetscInt bs; /* Number of degrees of freedom on each entity, aka tag size in moab */
91d72bce8STim Tautges   PetscBool icreatedinstance; /* true if DM created moab instance internally, will destroy instance in DMDestroy */
101d72bce8STim Tautges   moab::ParallelComm *pcomm;
11a4d2169cSTim Tautges   moab::Interface *mbiface;
121d72bce8STim Tautges   moab::Tag ltog_tag; /* moab supports "global id" tags, which are usually local to global numbering */
131d72bce8STim Tautges   moab::Range range;
141d72bce8STim Tautges } DM_Moab;
151d72bce8STim Tautges 
16a4d2169cSTim Tautges typedef struct {
17a4d2169cSTim Tautges   moab::Interface    *mbiface;
18a4d2169cSTim Tautges   moab::ParallelComm *pcomm;
19a4d2169cSTim Tautges   moab::Range         tag_range; /* entities to which this tag applies */
20a4d2169cSTim Tautges   moab::Tag           tag;
21a4d2169cSTim Tautges   moab::Tag           ltog_tag;
22a4d2169cSTim Tautges   PetscInt            tag_size;
23a4d2169cSTim Tautges   PetscBool           new_tag;
24a4d2169cSTim Tautges   PetscBool           serial;
25a4d2169cSTim Tautges 
26a4d2169cSTim Tautges } Vec_MOAB;
27a4d2169cSTim Tautges 
281d72bce8STim Tautges #undef __FUNCT__
29fd349b41STim Tautges #define __FUNCT__ "DMCreateGlobalVector_Moab"
30fd349b41STim Tautges PetscErrorCode DMCreateGlobalVector_Moab(DM dm,Vec *gvec)
31fd349b41STim Tautges {
32fd349b41STim Tautges   PetscErrorCode  ierr;
33fd349b41STim Tautges   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
34fd349b41STim Tautges 
35fd349b41STim Tautges   PetscFunctionBegin;
36fd349b41STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
37fd349b41STim Tautges   PetscValidPointer(gvec,2);
38fd349b41STim Tautges   PetscInt block_size = ((DM_Moab*)dm->data)->bs;
39a4d2169cSTim Tautges   moab::Tag tag = 0;
40a4d2169cSTim Tautges   ierr = DMMoabCreateVector(dm,tag,block_size,dmmoab->range,PETSC_FALSE,PETSC_TRUE,gvec);CHKERRQ(ierr);
41fd349b41STim Tautges   PetscFunctionReturn(0);
42fd349b41STim Tautges }
43fd349b41STim Tautges 
44fd349b41STim Tautges 
45fd349b41STim Tautges #undef __FUNCT__
46fd349b41STim Tautges #define __FUNCT__ "DMCreateLocalVector_Moab"
47fd349b41STim Tautges PetscErrorCode DMCreateLocalVector_Moab(DM dm,Vec *gvec)
48fd349b41STim Tautges {
49fd349b41STim Tautges   PetscErrorCode  ierr;
50fd349b41STim Tautges   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
51fd349b41STim Tautges 
52fd349b41STim Tautges   PetscFunctionBegin;
53fd349b41STim Tautges   PetscInt bs = 1;
54fd349b41STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55fd349b41STim Tautges   PetscValidPointer(gvec,2);
56a4d2169cSTim Tautges   moab::Tag tag = 0;
57a4d2169cSTim Tautges   ierr = DMMoabCreateVector(dm,tag,bs,dmmoab->range,PETSC_TRUE,PETSC_TRUE,gvec);CHKERRQ(ierr);
58fd349b41STim Tautges   PetscFunctionReturn(0);
59fd349b41STim Tautges }
60fd349b41STim Tautges 
61*aa768e4cSTim Tautges EXTERN_C_BEGIN
62*aa768e4cSTim Tautges #undef __FUNCT__
63*aa768e4cSTim Tautges #define __FUNCT__ "DMCreate_Moab"
64*aa768e4cSTim Tautges PetscErrorCode DMCreate_Moab(DM dm)
65*aa768e4cSTim Tautges {
66*aa768e4cSTim Tautges   DM_Moab        *moab;
67*aa768e4cSTim Tautges   PetscErrorCode ierr;
68*aa768e4cSTim Tautges 
69*aa768e4cSTim Tautges   PetscFunctionBegin;
70*aa768e4cSTim Tautges   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
71*aa768e4cSTim Tautges   ierr     = PetscNewLog(dm, DM_Moab, &moab);CHKERRQ(ierr);
72*aa768e4cSTim Tautges   dm->data = moab;
73*aa768e4cSTim Tautges 
74*aa768e4cSTim Tautges   PetscFunctionReturn(0);
75*aa768e4cSTim Tautges }
76*aa768e4cSTim Tautges EXTERN_C_END
77*aa768e4cSTim Tautges 
78fd349b41STim Tautges #undef __FUNCT__
79fd349b41STim Tautges #define __FUNCT__ "DMDestroy_Moab"
80fd349b41STim Tautges PetscErrorCode DMDestroy_Moab(DM dm)
81fd349b41STim Tautges {
82fd349b41STim Tautges   PetscFunctionBegin;
83fd349b41STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
84fd349b41STim Tautges 
85fd349b41STim Tautges   // Delete the DM_Moab:
86fd349b41STim Tautges   if(dm->data) {
87fd349b41STim Tautges     if (((DM_Moab*)dm->data)->icreatedinstance) {
88a4d2169cSTim Tautges       delete ((DM_Moab*)dm->data)->mbiface;
89a4d2169cSTim Tautges       ((DM_Moab*)dm->data)->mbiface = NULL;
90fd349b41STim Tautges       ((DM_Moab*)dm->data)->pcomm = NULL;
91fd349b41STim Tautges     }
92fd349b41STim Tautges     delete (DM_Moab*)dm->data;
93fd349b41STim Tautges     dm->data = NULL;
94fd349b41STim Tautges   }
95fd349b41STim Tautges   PetscFunctionReturn(0);
96fd349b41STim Tautges }
97fd349b41STim Tautges 
98fd349b41STim Tautges 
99fd349b41STim Tautges #undef __FUNCT__
1001d72bce8STim Tautges #define __FUNCT__ "DMMoabCreate"
1011d72bce8STim Tautges /*@
1021d72bce8STim Tautges   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
1031d72bce8STim Tautges 
1041d72bce8STim Tautges   Collective on MPI_Comm
1051d72bce8STim Tautges 
1061d72bce8STim Tautges   Input Parameter:
1071d72bce8STim Tautges . comm - The communicator for the DMMoab object
1081d72bce8STim Tautges 
1091d72bce8STim Tautges   Output Parameter:
1101d72bce8STim Tautges . moab  - The DMMoab object
1111d72bce8STim Tautges 
1121d72bce8STim Tautges   Level: beginner
1131d72bce8STim Tautges 
1141d72bce8STim Tautges .keywords: DMMoab, create
1151d72bce8STim Tautges @*/
1161d72bce8STim Tautges PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *moab)
1171d72bce8STim Tautges {
1181d72bce8STim Tautges   PetscErrorCode ierr;
1191d72bce8STim Tautges 
1201d72bce8STim Tautges   PetscFunctionBegin;
1211d72bce8STim Tautges   PetscValidPointer(moab,2);
1221d72bce8STim Tautges   ierr = DMCreate(comm, moab);CHKERRQ(ierr);
1231d72bce8STim Tautges   ierr = DMSetType(*moab, DMMOAB);CHKERRQ(ierr);
1241d72bce8STim Tautges   PetscFunctionReturn(0);
1251d72bce8STim Tautges }
1261d72bce8STim Tautges 
1271d72bce8STim Tautges #undef __FUNCT__
128*aa768e4cSTim Tautges #define __FUNCT__ "DMMoabCreateMoab"
1291d72bce8STim Tautges /*@
130a4d2169cSTim Tautges   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
1311d72bce8STim Tautges 
1321d72bce8STim Tautges   Collective on MPI_Comm
1331d72bce8STim Tautges 
1341d72bce8STim Tautges   Input Parameter:
1351d72bce8STim Tautges . comm - The communicator for the DMMoab object
136a4d2169cSTim Tautges . moab - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
137a4d2169cSTim Tautges          along with the DMMoab
138a4d2169cSTim Tautges . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
1391d72bce8STim Tautges . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
1401d72bce8STim Tautges . range - If non-NULL, contains range of entities to which DOFs will be assigned
1411d72bce8STim Tautges 
1421d72bce8STim Tautges   Output Parameter:
1431d72bce8STim Tautges . moab  - The DMMoab object
1441d72bce8STim Tautges 
1451d72bce8STim Tautges   Level: beginner
1461d72bce8STim Tautges 
1471d72bce8STim Tautges .keywords: DMMoab, create
1481d72bce8STim Tautges @*/
149a4d2169cSTim Tautges PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag ltog_tag, moab::Range *range, DM *moab)
1501d72bce8STim Tautges {
1511d72bce8STim Tautges   PetscErrorCode ierr;
1521d72bce8STim Tautges 
1531d72bce8STim Tautges   PetscFunctionBegin;
1541d72bce8STim Tautges   PetscValidPointer(moab,2);
1551d72bce8STim Tautges   ierr = DMCreate(comm, moab);CHKERRQ(ierr);
1561d72bce8STim Tautges   ierr = DMSetType(*moab, DMMOAB);CHKERRQ(ierr);
157a4d2169cSTim Tautges 
158a4d2169cSTim Tautges   if (!mbiface) {
159a4d2169cSTim Tautges     mbiface = new moab::Core();
160a4d2169cSTim Tautges     ((DM_Moab*)(*moab)->data)->icreatedinstance = PETSC_TRUE;
1611d72bce8STim Tautges   }
162a4d2169cSTim Tautges   if (!pcomm) {
1631d72bce8STim Tautges     PetscInt rank, nprocs;
1641d72bce8STim Tautges     MPI_Comm_rank(comm, &rank);
1651d72bce8STim Tautges     MPI_Comm_size(comm, &nprocs);
166a4d2169cSTim Tautges     pcomm = new moab::ParallelComm(mbiface, comm);
167a4d2169cSTim Tautges   }
168a4d2169cSTim Tautges 
169a4d2169cSTim Tautges     // do the initialization of the DM
170a4d2169cSTim Tautges   DM_Moab *dmmoab = new DM_Moab;
171a4d2169cSTim Tautges   (*moab)->data      = dmmoab;
172a4d2169cSTim Tautges   dmmoab->bs       = 0;
173a4d2169cSTim Tautges   dmmoab->pcomm    = pcomm;
174a4d2169cSTim Tautges   dmmoab->mbiface    = mbiface;
175a4d2169cSTim Tautges   dmmoab->ltog_tag = ltog_tag;
176a4d2169cSTim Tautges 
177a4d2169cSTim Tautges     // initialize various functions
178a4d2169cSTim Tautges   (*moab)->ops->createglobalvector              = DMCreateGlobalVector_Moab;
179a4d2169cSTim Tautges   (*moab)->ops->createlocalvector               = DMCreateLocalVector_Moab;
180a4d2169cSTim Tautges   (*moab)->ops->destroy                         = DMDestroy_Moab;
181a4d2169cSTim Tautges 
182a4d2169cSTim Tautges   ierr = DMMoabSetInterface(*moab, mbiface);CHKERRQ(ierr);
183a4d2169cSTim Tautges   if (!pcomm) pcomm = new moab::ParallelComm(mbiface, comm);
184a4d2169cSTim Tautges   ierr = DMMoabSetParallelComm(*moab, pcomm);CHKERRQ(ierr);
185a4d2169cSTim Tautges   if (!ltog_tag) {
186a4d2169cSTim Tautges     moab::ErrorCode merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, ltog_tag);MBERRNM(merr);
187a4d2169cSTim Tautges   }
188a4d2169cSTim Tautges   if (ltog_tag) {
189a4d2169cSTim Tautges     ierr = DMMoabSetLocalToGlobalTag(*moab, ltog_tag);CHKERRQ(ierr);
190a4d2169cSTim Tautges   }
191a4d2169cSTim Tautges   if (range) {
192a4d2169cSTim Tautges     ierr = DMMoabSetRange(*moab, *range);CHKERRQ(ierr);
193a4d2169cSTim Tautges   }
1941d72bce8STim Tautges   PetscFunctionReturn(0);
1951d72bce8STim Tautges }
1961d72bce8STim Tautges 
1971d72bce8STim Tautges #undef __FUNCT__
1981d72bce8STim Tautges #define __FUNCT__ "DMMoabSetParallelComm"
199*aa768e4cSTim Tautges /*@
200*aa768e4cSTim Tautges   DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab
201*aa768e4cSTim Tautges 
202*aa768e4cSTim Tautges   Collective on MPI_Comm
203*aa768e4cSTim Tautges 
204*aa768e4cSTim Tautges   Input Parameter:
205*aa768e4cSTim Tautges . dm    - The DMMoab object being set
206*aa768e4cSTim Tautges . pcomm - The ParallelComm being set on the DMMoab
207*aa768e4cSTim Tautges 
208*aa768e4cSTim Tautges   Level: beginner
209*aa768e4cSTim Tautges 
210*aa768e4cSTim Tautges .keywords: DMMoab, create
211*aa768e4cSTim Tautges @*/
2121d72bce8STim Tautges PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
2131d72bce8STim Tautges {
2141d72bce8STim Tautges   PetscFunctionBegin;
2151d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2161d72bce8STim Tautges   ((DM_Moab*)dm->data)->pcomm = pcomm;
217a4d2169cSTim Tautges   ((DM_Moab*)dm->data)->mbiface = pcomm->get_moab();
2181d72bce8STim Tautges   PetscFunctionReturn(0);
2191d72bce8STim Tautges }
2201d72bce8STim Tautges 
2211d72bce8STim Tautges 
2221d72bce8STim Tautges #undef __FUNCT__
2231d72bce8STim Tautges #define __FUNCT__ "DMMoabGetParallelComm"
224*aa768e4cSTim Tautges /*@
225*aa768e4cSTim Tautges   DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab
226*aa768e4cSTim Tautges 
227*aa768e4cSTim Tautges   Collective on MPI_Comm
228*aa768e4cSTim Tautges 
229*aa768e4cSTim Tautges   Input Parameter:
230*aa768e4cSTim Tautges . dm    - The DMMoab object being set
231*aa768e4cSTim Tautges 
232*aa768e4cSTim Tautges   Output Parameter:
233*aa768e4cSTim Tautges . pcomm - The ParallelComm for the DMMoab
234*aa768e4cSTim Tautges 
235*aa768e4cSTim Tautges   Level: beginner
236*aa768e4cSTim Tautges 
237*aa768e4cSTim Tautges .keywords: DMMoab, create
238*aa768e4cSTim Tautges @*/
2391d72bce8STim Tautges PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
2401d72bce8STim Tautges {
2411d72bce8STim Tautges   PetscFunctionBegin;
2421d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2431d72bce8STim Tautges   *pcomm = ((DM_Moab*)dm->data)->pcomm;
2441d72bce8STim Tautges   PetscFunctionReturn(0);
2451d72bce8STim Tautges }
2461d72bce8STim Tautges 
2471d72bce8STim Tautges 
2481d72bce8STim Tautges #undef __FUNCT__
2491d72bce8STim Tautges #define __FUNCT__ "DMMoabSetInterface"
250*aa768e4cSTim Tautges /*@
251*aa768e4cSTim Tautges   DMMoabSetInterface - Set the MOAB instance used with this DMMoab
252*aa768e4cSTim Tautges 
253*aa768e4cSTim Tautges   Collective on MPI_Comm
254*aa768e4cSTim Tautges 
255*aa768e4cSTim Tautges   Input Parameter:
256*aa768e4cSTim Tautges . dm      - The DMMoab object being set
257*aa768e4cSTim Tautges . mbiface - The MOAB instance being set on this DMMoab
258*aa768e4cSTim Tautges 
259*aa768e4cSTim Tautges   Level: beginner
260*aa768e4cSTim Tautges 
261*aa768e4cSTim Tautges .keywords: DMMoab, create
262*aa768e4cSTim Tautges @*/
263a4d2169cSTim Tautges PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
2641d72bce8STim Tautges {
2651d72bce8STim Tautges   PetscFunctionBegin;
2661d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2671d72bce8STim Tautges   ((DM_Moab*)dm->data)->pcomm = NULL;
268a4d2169cSTim Tautges   ((DM_Moab*)dm->data)->mbiface = mbiface;
2691d72bce8STim Tautges   PetscFunctionReturn(0);
2701d72bce8STim Tautges }
2711d72bce8STim Tautges 
2721d72bce8STim Tautges 
2731d72bce8STim Tautges #undef __FUNCT__
2741d72bce8STim Tautges #define __FUNCT__ "DMMoabGetInterface"
275*aa768e4cSTim Tautges /*@
276*aa768e4cSTim Tautges   DMMoabGetInterface - Get the MOAB instance used with this DMMoab
277*aa768e4cSTim Tautges 
278*aa768e4cSTim Tautges   Collective on MPI_Comm
279*aa768e4cSTim Tautges 
280*aa768e4cSTim Tautges   Input Parameter:
281*aa768e4cSTim Tautges . dm      - The DMMoab object being set
282*aa768e4cSTim Tautges 
283*aa768e4cSTim Tautges   Output Parameter:
284*aa768e4cSTim Tautges . mbiface - The MOAB instance set on this DMMoab
285*aa768e4cSTim Tautges 
286*aa768e4cSTim Tautges   Level: beginner
287*aa768e4cSTim Tautges 
288*aa768e4cSTim Tautges .keywords: DMMoab, create
289*aa768e4cSTim Tautges @*/
290a4d2169cSTim Tautges PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
2911d72bce8STim Tautges {
2921d72bce8STim Tautges   PetscFunctionBegin;
2931d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
294a4d2169cSTim Tautges   *mbiface = ((DM_Moab*)dm->data)->mbiface;
2951d72bce8STim Tautges   PetscFunctionReturn(0);
2961d72bce8STim Tautges }
2971d72bce8STim Tautges 
2981d72bce8STim Tautges 
2991d72bce8STim Tautges #undef __FUNCT__
3001d72bce8STim Tautges #define __FUNCT__ "DMMoabSetRange"
301*aa768e4cSTim Tautges /*@
302*aa768e4cSTim Tautges   DMMoabSetRange - Set the entities having DOFs on this DMMoab
303*aa768e4cSTim Tautges 
304*aa768e4cSTim Tautges   Collective on MPI_Comm
305*aa768e4cSTim Tautges 
306*aa768e4cSTim Tautges   Input Parameter:
307*aa768e4cSTim Tautges . dm    - The DMMoab object being set
308*aa768e4cSTim Tautges . range - The entities treated by this DMMoab
309*aa768e4cSTim Tautges 
310*aa768e4cSTim Tautges   Level: beginner
311*aa768e4cSTim Tautges 
312*aa768e4cSTim Tautges .keywords: DMMoab, create
313*aa768e4cSTim Tautges @*/
3141d72bce8STim Tautges PetscErrorCode DMMoabSetRange(DM dm,moab::Range range)
3151d72bce8STim Tautges {
3161d72bce8STim Tautges   PetscFunctionBegin;
3171d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3181d72bce8STim Tautges   ((DM_Moab*)dm->data)->range = range;
3191d72bce8STim Tautges   PetscFunctionReturn(0);
3201d72bce8STim Tautges }
3211d72bce8STim Tautges 
3221d72bce8STim Tautges 
3231d72bce8STim Tautges #undef __FUNCT__
3241d72bce8STim Tautges #define __FUNCT__ "DMMoabGetRange"
325*aa768e4cSTim Tautges /*@
326*aa768e4cSTim Tautges   DMMoabGetRange - Get the entities having DOFs on this DMMoab
327*aa768e4cSTim Tautges 
328*aa768e4cSTim Tautges   Collective on MPI_Comm
329*aa768e4cSTim Tautges 
330*aa768e4cSTim Tautges   Input Parameter:
331*aa768e4cSTim Tautges . dm    - The DMMoab object being set
332*aa768e4cSTim Tautges 
333*aa768e4cSTim Tautges   Output Parameter:
334*aa768e4cSTim Tautges . range - The entities treated by this DMMoab
335*aa768e4cSTim Tautges 
336*aa768e4cSTim Tautges   Level: beginner
337*aa768e4cSTim Tautges 
338*aa768e4cSTim Tautges .keywords: DMMoab, create
339*aa768e4cSTim Tautges @*/
3401d72bce8STim Tautges PetscErrorCode DMMoabGetRange(DM dm,moab::Range *range)
3411d72bce8STim Tautges {
3421d72bce8STim Tautges   PetscFunctionBegin;
3431d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3441d72bce8STim Tautges   *range = ((DM_Moab*)dm->data)->range;
3451d72bce8STim Tautges   PetscFunctionReturn(0);
3461d72bce8STim Tautges }
3471d72bce8STim Tautges 
3481d72bce8STim Tautges #undef __FUNCT__
3491d72bce8STim Tautges #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
350*aa768e4cSTim Tautges /*@
351*aa768e4cSTim Tautges   DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering
352*aa768e4cSTim Tautges 
353*aa768e4cSTim Tautges   Collective on MPI_Comm
354*aa768e4cSTim Tautges 
355*aa768e4cSTim Tautges   Input Parameter:
356*aa768e4cSTim Tautges . dm      - The DMMoab object being set
357*aa768e4cSTim Tautges . ltogtag - The MOAB tag used for local to global ids
358*aa768e4cSTim Tautges 
359*aa768e4cSTim Tautges   Level: beginner
360*aa768e4cSTim Tautges 
361*aa768e4cSTim Tautges .keywords: DMMoab, create
362*aa768e4cSTim Tautges @*/
3631d72bce8STim Tautges PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
3641d72bce8STim Tautges {
3651d72bce8STim Tautges   PetscFunctionBegin;
3661d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3671d72bce8STim Tautges   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
3681d72bce8STim Tautges   PetscFunctionReturn(0);
3691d72bce8STim Tautges }
3701d72bce8STim Tautges 
3711d72bce8STim Tautges 
3721d72bce8STim Tautges #undef __FUNCT__
3731d72bce8STim Tautges #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
374*aa768e4cSTim Tautges /*@
375*aa768e4cSTim Tautges   DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering
376*aa768e4cSTim Tautges 
377*aa768e4cSTim Tautges   Collective on MPI_Comm
378*aa768e4cSTim Tautges 
379*aa768e4cSTim Tautges   Input Parameter:
380*aa768e4cSTim Tautges . dm      - The DMMoab object being set
381*aa768e4cSTim Tautges 
382*aa768e4cSTim Tautges   Output Parameter:
383*aa768e4cSTim Tautges . ltogtag - The MOAB tag used for local to global ids
384*aa768e4cSTim Tautges 
385*aa768e4cSTim Tautges   Level: beginner
386*aa768e4cSTim Tautges 
387*aa768e4cSTim Tautges .keywords: DMMoab, create
388*aa768e4cSTim Tautges @*/
3891d72bce8STim Tautges PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
3901d72bce8STim Tautges {
3911d72bce8STim Tautges   PetscFunctionBegin;
3921d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3931d72bce8STim Tautges   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
3941d72bce8STim Tautges   PetscFunctionReturn(0);
3951d72bce8STim Tautges }
3961d72bce8STim Tautges 
3971d72bce8STim Tautges 
3981d72bce8STim Tautges #undef __FUNCT__
3991d72bce8STim Tautges #define __FUNCT__ "DMMoabSetBlockSize"
400*aa768e4cSTim Tautges /*@
401*aa768e4cSTim Tautges   DMMoabSetBlockSize - Set the block size used with this DMMoab
402*aa768e4cSTim Tautges 
403*aa768e4cSTim Tautges   Collective on MPI_Comm
404*aa768e4cSTim Tautges 
405*aa768e4cSTim Tautges   Input Parameter:
406*aa768e4cSTim Tautges . dm - The DMMoab object being set
407*aa768e4cSTim Tautges . bs - The block size used with this DMMoab
408*aa768e4cSTim Tautges 
409*aa768e4cSTim Tautges   Level: beginner
410*aa768e4cSTim Tautges 
411*aa768e4cSTim Tautges .keywords: DMMoab, create
412*aa768e4cSTim Tautges @*/
4131d72bce8STim Tautges PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
4141d72bce8STim Tautges {
4151d72bce8STim Tautges   PetscFunctionBegin;
4161d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4171d72bce8STim Tautges   ((DM_Moab*)dm->data)->bs = bs;
4181d72bce8STim Tautges   PetscFunctionReturn(0);
4191d72bce8STim Tautges }
4201d72bce8STim Tautges 
4211d72bce8STim Tautges 
4221d72bce8STim Tautges #undef __FUNCT__
4231d72bce8STim Tautges #define __FUNCT__ "DMMoabGetBlockSize"
424*aa768e4cSTim Tautges /*@
425*aa768e4cSTim Tautges   DMMoabGetBlockSize - Get the block size used with this DMMoab
426*aa768e4cSTim Tautges 
427*aa768e4cSTim Tautges   Collective on MPI_Comm
428*aa768e4cSTim Tautges 
429*aa768e4cSTim Tautges   Input Parameter:
430*aa768e4cSTim Tautges . dm - The DMMoab object being set
431*aa768e4cSTim Tautges 
432*aa768e4cSTim Tautges   Output Parameter:
433*aa768e4cSTim Tautges . bs - The block size used with this DMMoab
434*aa768e4cSTim Tautges 
435*aa768e4cSTim Tautges   Level: beginner
436*aa768e4cSTim Tautges 
437*aa768e4cSTim Tautges .keywords: DMMoab, create
438*aa768e4cSTim Tautges @*/
4391d72bce8STim Tautges PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
4401d72bce8STim Tautges {
4411d72bce8STim Tautges   PetscFunctionBegin;
4421d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4431d72bce8STim Tautges   *bs = ((DM_Moab*)dm->data)->bs;
4441d72bce8STim Tautges   PetscFunctionReturn(0);
4451d72bce8STim Tautges }
4461d72bce8STim Tautges 
4471d72bce8STim Tautges 
448a4d2169cSTim Tautges // declare for use later but before they're defined
449a4d2169cSTim Tautges PetscErrorCode DMMoab_VecUserDestroy(void *user);
450a4d2169cSTim Tautges PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y);
451a4d2169cSTim Tautges PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name);
452a4d2169cSTim Tautges PetscErrorCode DMMoab_CreateVector(moab::Interface *iface,moab::ParallelComm *pcomm,moab::Tag tag,PetscInt tag_size,moab::Tag ltog_tag,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec);
4531d72bce8STim Tautges 
4541d72bce8STim Tautges #undef __FUNCT__
4551d72bce8STim Tautges #define __FUNCT__ "DMMoabCreateVector"
456*aa768e4cSTim Tautges /*@
457*aa768e4cSTim Tautges   DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities
458*aa768e4cSTim Tautges 
459*aa768e4cSTim Tautges   Collective on MPI_Comm
460*aa768e4cSTim Tautges 
461*aa768e4cSTim Tautges   Input Parameter:
462*aa768e4cSTim Tautges . dm          - The DMMoab object being set
463*aa768e4cSTim Tautges . tag         - If non-zero, block size will be taken from the tag size
464*aa768e4cSTim Tautges . tag_size    - If tag was zero, this parameter specifies the block size; unique tag name will be generated automatically
465*aa768e4cSTim Tautges . range       - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab
466*aa768e4cSTim Tautges . serial      - If true, this is a serial Vec, otherwise a parallel one
467*aa768e4cSTim Tautges . destroy_tag - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB
468*aa768e4cSTim Tautges 
469*aa768e4cSTim Tautges   Output Parameter:
470*aa768e4cSTim Tautges . vec         - The created vector
471*aa768e4cSTim Tautges 
472*aa768e4cSTim Tautges   Level: beginner
473*aa768e4cSTim Tautges 
474*aa768e4cSTim Tautges .keywords: DMMoab, create
475*aa768e4cSTim Tautges @*/
476a4d2169cSTim Tautges PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec)
4771d72bce8STim Tautges {
4781d72bce8STim Tautges   PetscErrorCode     ierr;
479a4d2169cSTim Tautges 
4801d72bce8STim Tautges   PetscFunctionBegin;
481a4d2169cSTim Tautges 
4821d72bce8STim Tautges   DM_Moab *dmmoab = (DM_Moab*)dm->data;
483a4d2169cSTim Tautges   moab::ParallelComm *pcomm = dmmoab->pcomm;
484a4d2169cSTim Tautges   moab::Interface *mbiface = dmmoab->mbiface;
485a4d2169cSTim Tautges   moab::Tag ltog_tag = dmmoab->ltog_tag;
486a4d2169cSTim Tautges 
487a4d2169cSTim Tautges   if (!tag && !tag_size) {
488a4d2169cSTim Tautges     PetscFunctionReturn(PETSC_ERR_ARG_WRONG);
489a4d2169cSTim Tautges   }
490a4d2169cSTim Tautges   else if (!tag && tag_size) {
491a4d2169cSTim Tautges     ierr = DMMoab_CreateVector(mbiface,pcomm,tag,tag_size,ltog_tag,range,serial,destroy_tag,vec);CHKERRQ(ierr);
492a4d2169cSTim Tautges   }
4931d72bce8STim Tautges   PetscFunctionReturn(0);
4941d72bce8STim Tautges }
4951d72bce8STim Tautges 
4961d72bce8STim Tautges 
4971d72bce8STim Tautges #undef __FUNCT__
498a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_CreateVector"
499a4d2169cSTim Tautges PetscErrorCode DMMoab_CreateVector(moab::Interface *mbiface,moab::ParallelComm *pcomm,moab::Tag tag,PetscInt tag_size,moab::Tag ltog_tag,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec)
500a4d2169cSTim Tautges {
501a4d2169cSTim Tautges   PetscErrorCode     ierr;
502a4d2169cSTim Tautges   moab::ErrorCode    merr;
503a4d2169cSTim Tautges 
504a4d2169cSTim Tautges   PetscFunctionBegin;
505a4d2169cSTim Tautges 
506a4d2169cSTim Tautges   if (!tag) {
507a4d2169cSTim Tautges     std::string tag_name;
508a4d2169cSTim Tautges     ierr = DMMoab_CreateTagName(pcomm,tag_name);CHKERRQ(ierr);
509a4d2169cSTim Tautges 
510a4d2169cSTim Tautges       // Create the default value for the tag (all zeros):
511a4d2169cSTim Tautges     std::vector<PetscScalar> default_value(tag_size, 0.0);
512a4d2169cSTim Tautges 
513a4d2169cSTim Tautges       // Create the tag:
514a4d2169cSTim Tautges     merr = mbiface->tag_get_handle(tag_name.c_str(),tag_size,moab::MB_TYPE_DOUBLE,tag,
515a4d2169cSTim Tautges                                    moab::MB_TAG_DENSE | moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr);
516a4d2169cSTim Tautges   }
517a4d2169cSTim Tautges   else {
518a4d2169cSTim Tautges 
519a4d2169cSTim Tautges       // Make sure the tag data is of type "double":
520a4d2169cSTim Tautges     moab::DataType tag_type;
521a4d2169cSTim Tautges     merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr);
522a4d2169cSTim Tautges     if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE");
523a4d2169cSTim Tautges   }
524a4d2169cSTim Tautges 
525a4d2169cSTim Tautges     // Create the MOAB internal data object
526a4d2169cSTim Tautges   Vec_MOAB *vmoab;
527a4d2169cSTim Tautges   ierr = PetscMalloc(sizeof(Vec_MOAB),&vmoab);CHKERRQ(ierr);
528a4d2169cSTim Tautges   new (vmoab) Vec_MOAB();
529a4d2169cSTim Tautges   vmoab->tag = tag;
530a4d2169cSTim Tautges   vmoab->ltog_tag = ltog_tag;
531a4d2169cSTim Tautges   vmoab->mbiface = mbiface;
532a4d2169cSTim Tautges   vmoab->pcomm = pcomm;
533a4d2169cSTim Tautges   vmoab->tag_range = range;
534a4d2169cSTim Tautges   vmoab->new_tag = destroy_tag;
535a4d2169cSTim Tautges   vmoab->serial = serial;
536a4d2169cSTim Tautges   merr = mbiface->tag_get_length(tag,vmoab->tag_size);MBERR("tag_get_size", merr);
537a4d2169cSTim Tautges 
538a4d2169cSTim Tautges     // Call tag_iterate. This will cause MOAB to allocate memory for the
539a4d2169cSTim Tautges     // tag data if it hasn't already happened:
540a4d2169cSTim Tautges   int  count;
541a4d2169cSTim Tautges   void *void_ptr;
542a4d2169cSTim Tautges   merr = mbiface->tag_iterate(tag,range.begin(),range.end(),count,void_ptr);MBERRNM(merr);
543a4d2169cSTim Tautges 
544a4d2169cSTim Tautges     // Check to make sure the tag data is in a single sequence:
545a4d2169cSTim Tautges   if ((unsigned)count != range.size()) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only create MOAB Vector for single sequence");
546a4d2169cSTim Tautges   PetscScalar *data_ptr = (PetscScalar*)void_ptr;
547a4d2169cSTim Tautges 
548a4d2169cSTim Tautges     // Create the PETSc Vector:
549a4d2169cSTim Tautges   if(!serial) {
550a4d2169cSTim Tautges       // This is an MPI Vector:
551a4d2169cSTim Tautges     ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range.size(),
552a4d2169cSTim Tautges                                  PETSC_DECIDE,data_ptr,vec);CHKERRXX(ierr);
553a4d2169cSTim Tautges 
554a4d2169cSTim Tautges       // Vector created, manually set local to global mapping:
555a4d2169cSTim Tautges     ISLocalToGlobalMapping ltog;
556a4d2169cSTim Tautges     PetscInt               *gindices = new PetscInt[range.size()];
557a4d2169cSTim Tautges     PetscInt               count = 0;
558a4d2169cSTim Tautges     moab::Range::iterator  iter;
559a4d2169cSTim Tautges     for(iter = range.begin(); iter != range.end(); iter++) {
560a4d2169cSTim Tautges       int dof;
561a4d2169cSTim Tautges       merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
562a4d2169cSTim Tautges       gindices[count] = dof;
563a4d2169cSTim Tautges       count++;
564a4d2169cSTim Tautges     }
565a4d2169cSTim Tautges 
566a4d2169cSTim Tautges     ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range.size(),gindices,
567a4d2169cSTim Tautges                                         PETSC_COPY_VALUES,&ltog);CHKERRQ(ierr);
568a4d2169cSTim Tautges     ierr = VecSetLocalToGlobalMappingBlock(*vec,ltog);CHKERRQ(ierr);
569a4d2169cSTim Tautges 
570a4d2169cSTim Tautges       // Clean up:
571a4d2169cSTim Tautges     ierr = ISLocalToGlobalMappingDestroy(&ltog);CHKERRQ(ierr);
572a4d2169cSTim Tautges     delete [] gindices;
573a4d2169cSTim Tautges   } else {
574a4d2169cSTim Tautges       // This is a serial vector:
575a4d2169cSTim Tautges     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*range.size(),data_ptr,vec);CHKERRXX(ierr);
576a4d2169cSTim Tautges   }
577a4d2169cSTim Tautges 
578a4d2169cSTim Tautges 
579a4d2169cSTim Tautges   PetscContainer moabdata;
580a4d2169cSTim Tautges   ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr);
581a4d2169cSTim Tautges   ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr);
582a4d2169cSTim Tautges   ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr);
583a4d2169cSTim Tautges   ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr);
584a4d2169cSTim Tautges   (*vec)->ops->duplicate = DMMoab_VecDuplicate;
585a4d2169cSTim Tautges 
586a4d2169cSTim Tautges   ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr);
587a4d2169cSTim Tautges   PetscFunctionReturn(0);
588a4d2169cSTim Tautges }
589a4d2169cSTim Tautges 
590a4d2169cSTim Tautges #undef __FUNCT__
5911d72bce8STim Tautges #define __FUNCT__ "DMMoabGetVecTag"
592*aa768e4cSTim Tautges /*@
593*aa768e4cSTim Tautges   DMMoabGetVecTag - Get the MOAB tag associated with this Vec
594*aa768e4cSTim Tautges 
595*aa768e4cSTim Tautges   Collective on MPI_Comm
596*aa768e4cSTim Tautges 
597*aa768e4cSTim Tautges   Input Parameter:
598*aa768e4cSTim Tautges . vec - Vec being queried
599*aa768e4cSTim Tautges 
600*aa768e4cSTim Tautges   Output Parameter:
601*aa768e4cSTim Tautges . tag - Tag associated with this Vec
602*aa768e4cSTim Tautges 
603*aa768e4cSTim Tautges   Level: beginner
604*aa768e4cSTim Tautges 
605*aa768e4cSTim Tautges .keywords: DMMoab, create
606*aa768e4cSTim Tautges @*/
6071d72bce8STim Tautges PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag)
6081d72bce8STim Tautges {
609a4d2169cSTim Tautges   PetscContainer  moabdata;
610a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
6111d72bce8STim Tautges   PetscErrorCode  ierr;
612a4d2169cSTim Tautges 
6131d72bce8STim Tautges   PetscFunctionBegin;
614a4d2169cSTim Tautges 
615a4d2169cSTim Tautges   // Get the MOAB private data:
616a4d2169cSTim Tautges   ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
617a4d2169cSTim Tautges   ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr);
618a4d2169cSTim Tautges 
619a4d2169cSTim Tautges   *tag = vmoab->tag;
620a4d2169cSTim Tautges 
6211d72bce8STim Tautges   PetscFunctionReturn(0);
6221d72bce8STim Tautges }
6231d72bce8STim Tautges 
6241d72bce8STim Tautges 
6251d72bce8STim Tautges #undef __FUNCT__
6261d72bce8STim Tautges #define __FUNCT__ "DMMoabGetVecRange"
627*aa768e4cSTim Tautges /*@
628*aa768e4cSTim Tautges   DMMoabGetVecRange - Get the MOAB entities associated with this Vec
629*aa768e4cSTim Tautges 
630*aa768e4cSTim Tautges   Collective on MPI_Comm
631*aa768e4cSTim Tautges 
632*aa768e4cSTim Tautges   Input Parameter:
633*aa768e4cSTim Tautges . vec   - Vec being queried
634*aa768e4cSTim Tautges 
635*aa768e4cSTim Tautges   Output Parameter:
636*aa768e4cSTim Tautges . range - Entities associated with this Vec
637*aa768e4cSTim Tautges 
638*aa768e4cSTim Tautges   Level: beginner
639*aa768e4cSTim Tautges 
640*aa768e4cSTim Tautges .keywords: DMMoab, create
641*aa768e4cSTim Tautges @*/
6421d72bce8STim Tautges PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range)
6431d72bce8STim Tautges {
644a4d2169cSTim Tautges   PetscContainer  moabdata;
645a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
6461d72bce8STim Tautges   PetscErrorCode  ierr;
647a4d2169cSTim Tautges 
6481d72bce8STim Tautges   PetscFunctionBegin;
649a4d2169cSTim Tautges 
650a4d2169cSTim Tautges   // Get the MOAB private data:
651a4d2169cSTim Tautges   ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
652a4d2169cSTim Tautges   ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr);
653a4d2169cSTim Tautges 
654a4d2169cSTim Tautges   *range = vmoab->tag_range;
655a4d2169cSTim Tautges 
6561d72bce8STim Tautges   PetscFunctionReturn(0);
6571d72bce8STim Tautges }
6581d72bce8STim Tautges 
6591d72bce8STim Tautges 
660a4d2169cSTim Tautges #undef __FUNCT__
661a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_VecDuplicate"
662a4d2169cSTim Tautges PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y)
663a4d2169cSTim Tautges {
664a4d2169cSTim Tautges   PetscErrorCode ierr;
665a4d2169cSTim Tautges   PetscFunctionBegin;
666a4d2169cSTim Tautges   PetscValidHeaderSpecific(x,VEC_CLASSID,1);
667a4d2169cSTim Tautges   PetscValidPointer(y,2);
668a4d2169cSTim Tautges 
669a4d2169cSTim Tautges   // Get the Vec_MOAB struct for the original vector:
670a4d2169cSTim Tautges   PetscContainer  moabdata;
671a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
672a4d2169cSTim Tautges   ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
673a4d2169cSTim Tautges   ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr);
674a4d2169cSTim Tautges 
675a4d2169cSTim Tautges   ierr = DMMoab_CreateVector(vmoab->mbiface,vmoab->pcomm,vmoab->tag, vmoab->tag_size,vmoab->ltog_tag,vmoab->tag_range,vmoab->serial,PETSC_TRUE,y);CHKERRQ(ierr);
676a4d2169cSTim Tautges   PetscFunctionReturn(0);
677a4d2169cSTim Tautges }
678a4d2169cSTim Tautges 
679a4d2169cSTim Tautges 
680a4d2169cSTim Tautges #undef __FUNCT__
681a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_CreateTagName"
682a4d2169cSTim Tautges /*  DMMoab_CreateTagName
683a4d2169cSTim Tautges  *
684a4d2169cSTim Tautges  *  Creates a unique tag name that will be shared across processes. If
685a4d2169cSTim Tautges  *  pcomm is NULL, then this is a serial vector. A unique tag name
686a4d2169cSTim Tautges  *  will be returned in tag_name in either case.
687a4d2169cSTim Tautges  *
688a4d2169cSTim Tautges  *  The tag names have the format _PETSC_VEC_N where N is some integer.
689a4d2169cSTim Tautges  */
690a4d2169cSTim Tautges PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name)
691a4d2169cSTim Tautges {
692a4d2169cSTim Tautges   moab::ErrorCode mberr;
693a4d2169cSTim Tautges   PetscErrorCode  ierr;
694a4d2169cSTim Tautges 
695a4d2169cSTim Tautges   PetscFunctionBegin;
696a4d2169cSTim Tautges   const std::string PVEC_PREFIX      = "_PETSC_VEC_";
697a4d2169cSTim Tautges   const PetscInt    PVEC_PREFIX_SIZE = PVEC_PREFIX.size();
698a4d2169cSTim Tautges 
699a4d2169cSTim Tautges   // Check to see if there are any PETSc vectors defined:
700a4d2169cSTim Tautges   const moab::Interface  *mbiface = pcomm->get_moab();
701a4d2169cSTim Tautges   std::vector<moab::Tag> tags;
702a4d2169cSTim Tautges   PetscInt               n = 0;
703a4d2169cSTim Tautges   mberr = mbiface->tag_get_tags(tags);MBERRNM(mberr);
704a4d2169cSTim Tautges   for(unsigned i = 0; i < tags.size(); i++) {
705a4d2169cSTim Tautges     std::string s;
706a4d2169cSTim Tautges     mberr = mbiface->tag_get_name(tags[i],s);MBERRNM(mberr);
707a4d2169cSTim Tautges     if(s.find(PVEC_PREFIX) != std::string::npos){
708a4d2169cSTim Tautges       // This tag represents a PETSc vector. Find the vector number:
709a4d2169cSTim Tautges       PetscInt m;
710a4d2169cSTim Tautges       std::istringstream(s.substr(PVEC_PREFIX_SIZE)) >> m;
711a4d2169cSTim Tautges       if(m >= n) n = m+1;
712a4d2169cSTim Tautges     }
713a4d2169cSTim Tautges   }
714a4d2169cSTim Tautges 
715a4d2169cSTim Tautges   // Make sure that n is consistent across all processes:
716a4d2169cSTim Tautges   PetscInt global_n;
717a4d2169cSTim Tautges   MPI_Comm comm = PETSC_COMM_SELF;
718a4d2169cSTim Tautges   if(pcomm) comm = pcomm->comm();
719a4d2169cSTim Tautges   ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr);
720a4d2169cSTim Tautges 
721a4d2169cSTim Tautges   // Set the answer and return:
722a4d2169cSTim Tautges   std::stringstream ss;
723a4d2169cSTim Tautges   ss << PVEC_PREFIX << global_n;
724a4d2169cSTim Tautges   tag_name = ss.str();
725a4d2169cSTim Tautges   PetscFunctionReturn(0);
726a4d2169cSTim Tautges }
727a4d2169cSTim Tautges 
728a4d2169cSTim Tautges 
729a4d2169cSTim Tautges #undef __FUNCT__
730a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_VecUserDestroy"
731a4d2169cSTim Tautges PetscErrorCode DMMoab_VecUserDestroy(void *user)
732a4d2169cSTim Tautges {
733a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
734a4d2169cSTim Tautges   PetscErrorCode  ierr;
735a4d2169cSTim Tautges   moab::ErrorCode merr;
736a4d2169cSTim Tautges 
737a4d2169cSTim Tautges   PetscFunctionBegin;
738a4d2169cSTim Tautges   vmoab = (Vec_MOAB*)user;
739a4d2169cSTim Tautges   if(vmoab->new_tag == PETSC_TRUE) {
740a4d2169cSTim Tautges     // Tag created via a call to VecDuplicate, delete the underlying tag in MOAB...
741a4d2169cSTim Tautges     merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr);
742a4d2169cSTim Tautges   }
743a4d2169cSTim Tautges 
744a4d2169cSTim Tautges   ierr = PetscFree(vmoab);CHKERRQ(ierr);
745a4d2169cSTim Tautges   PetscFunctionReturn(0);
746a4d2169cSTim Tautges }
747a4d2169cSTim Tautges 
748