xref: /petsc/src/dm/impls/moab/dmmbvec.cxx (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1af0996ceSBarry Smith #include <petsc/private/dmmbimpl.h> /*I  "petscdmmoab.h"   I*/
2af0996ceSBarry Smith #include <petsc/private/vecimpl.h>
3032b8ab6SVijay Mahadevan 
4032b8ab6SVijay Mahadevan #include <petscdmmoab.h>
5032b8ab6SVijay Mahadevan #include <MBTagConventions.hpp>
6032b8ab6SVijay Mahadevan 
79c368985SVijay Mahadevan #define USE_NATIVE_PETSCVEC
89c368985SVijay Mahadevan 
9f6829af0SVijay Mahadevan /* declare some private DMMoab specific overrides */
10f6829af0SVijay Mahadevan static PetscErrorCode DMCreateVector_Moab_Private(DM dm, moab::Tag tag, const moab::Range *userrange, PetscBool is_global_vec, PetscBool destroy_tag, Vec *vec);
11f6829af0SVijay Mahadevan static PetscErrorCode DMVecUserDestroy_Moab(void *user);
12f6829af0SVijay Mahadevan static PetscErrorCode DMVecDuplicate_Moab(Vec x, Vec *y);
139daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
149daf19fdSVijay Mahadevan static PetscErrorCode DMVecCreateTagName_Moab_Private(moab::Interface *mbiface, moab::ParallelComm *pcomm, char **tag_name);
159daf19fdSVijay Mahadevan #else
169daf19fdSVijay Mahadevan static PetscErrorCode DMVecCreateTagName_Moab_Private(moab::Interface *mbiface, char **tag_name);
179daf19fdSVijay Mahadevan #endif
18032b8ab6SVijay Mahadevan 
19b8ecf6d3SVijay Mahadevan /*@C
20f6829af0SVijay Mahadevan   DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities
21f6829af0SVijay Mahadevan 
22d083f849SBarry Smith   Collective
23f6829af0SVijay Mahadevan 
24d8d19677SJose E. Roman   Input Parameters:
25b8ecf6d3SVijay Mahadevan + dm              - The DMMoab object being set
26f6829af0SVijay Mahadevan . tag             - If non-zero, block size will be taken from the tag size
27f6829af0SVijay Mahadevan . range           - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab
28f6829af0SVijay Mahadevan . is_global_vec   - If true, this is a local representation of the Vec (including ghosts in parallel), otherwise a truly parallel one
29a2b725a8SWilliam Gropp - destroy_tag     - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB
30f6829af0SVijay Mahadevan 
31f6829af0SVijay Mahadevan   Output Parameter:
32f6829af0SVijay Mahadevan . vec             - The created vector
33f6829af0SVijay Mahadevan 
34f6829af0SVijay Mahadevan   Level: beginner
35f6829af0SVijay Mahadevan 
36db781477SPatrick Sanan .seealso: `VecCreate()`
37f6829af0SVijay Mahadevan @*/
389371c9d4SSatish Balay PetscErrorCode DMMoabCreateVector(DM dm, moab::Tag tag, const moab::Range *range, PetscBool is_global_vec, PetscBool destroy_tag, Vec *vec) {
39f6829af0SVijay Mahadevan   PetscFunctionBegin;
407a8be351SBarry Smith   PetscCheck(tag || (range && !range->empty()), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Both tag and range cannot be null.");
41f6829af0SVijay Mahadevan 
429566063dSJacob Faibussowitsch   PetscCall(DMCreateVector_Moab_Private(dm, tag, range, is_global_vec, destroy_tag, vec));
43f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
44f6829af0SVijay Mahadevan }
45f6829af0SVijay Mahadevan 
46b8ecf6d3SVijay Mahadevan /*@C
47f6829af0SVijay Mahadevan   DMMoabGetVecTag - Get the MOAB tag associated with this Vec
48f6829af0SVijay Mahadevan 
49f6829af0SVijay Mahadevan   Input Parameter:
50f6829af0SVijay Mahadevan . vec - Vec being queried
51f6829af0SVijay Mahadevan 
52f6829af0SVijay Mahadevan   Output Parameter:
53f6829af0SVijay Mahadevan . tag - Tag associated with this Vec. NULL if vec is a native PETSc Vec.
54f6829af0SVijay Mahadevan 
55f6829af0SVijay Mahadevan   Level: beginner
56f6829af0SVijay Mahadevan 
57db781477SPatrick Sanan .seealso: `DMMoabCreateVector()`, `DMMoabGetVecRange()`
58f6829af0SVijay Mahadevan @*/
599371c9d4SSatish Balay PetscErrorCode DMMoabGetVecTag(Vec vec, moab::Tag *tag) {
60f6829af0SVijay Mahadevan   PetscContainer moabdata;
61f6829af0SVijay Mahadevan   Vec_MOAB      *vmoab;
62f6829af0SVijay Mahadevan 
63f6829af0SVijay Mahadevan   PetscFunctionBegin;
64f6829af0SVijay Mahadevan   PetscValidPointer(tag, 2);
65f6829af0SVijay Mahadevan 
66f6829af0SVijay Mahadevan   /* Get the MOAB private data */
679566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)vec, "MOABData", (PetscObject *)&moabdata));
689566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
69f6829af0SVijay Mahadevan 
70f6829af0SVijay Mahadevan   *tag = vmoab->tag;
71f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
72f6829af0SVijay Mahadevan }
73f6829af0SVijay Mahadevan 
74b8ecf6d3SVijay Mahadevan /*@C
75f6829af0SVijay Mahadevan   DMMoabGetVecRange - Get the MOAB entities associated with this Vec
76f6829af0SVijay Mahadevan 
77f6829af0SVijay Mahadevan   Input Parameter:
78f6829af0SVijay Mahadevan . vec   - Vec being queried
79f6829af0SVijay Mahadevan 
80f6829af0SVijay Mahadevan   Output Parameter:
81f6829af0SVijay Mahadevan . range - Entities associated with this Vec. NULL if vec is a native PETSc Vec.
82f6829af0SVijay Mahadevan 
83f6829af0SVijay Mahadevan   Level: beginner
84f6829af0SVijay Mahadevan 
85db781477SPatrick Sanan .seealso: `DMMoabCreateVector()`, `DMMoabGetVecTag()`
86f6829af0SVijay Mahadevan @*/
879371c9d4SSatish Balay PetscErrorCode DMMoabGetVecRange(Vec vec, moab::Range *range) {
88f6829af0SVijay Mahadevan   PetscContainer moabdata;
89f6829af0SVijay Mahadevan   Vec_MOAB      *vmoab;
90f6829af0SVijay Mahadevan 
91f6829af0SVijay Mahadevan   PetscFunctionBegin;
92f6829af0SVijay Mahadevan   PetscValidPointer(range, 2);
93f6829af0SVijay Mahadevan 
94f6829af0SVijay Mahadevan   /* Get the MOAB private data handle */
959566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)vec, "MOABData", (PetscObject *)&moabdata));
969566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
97f6829af0SVijay Mahadevan 
98f6829af0SVijay Mahadevan   *range = *vmoab->tag_range;
99f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
100f6829af0SVijay Mahadevan }
101f6829af0SVijay Mahadevan 
102b8ecf6d3SVijay Mahadevan /*@C
103f6829af0SVijay Mahadevan   DMMoabVecGetArray - Returns the writable direct access array to the local representation of MOAB tag data for the underlying vector using locally owned+ghosted range of entities
104f6829af0SVijay Mahadevan 
105d083f849SBarry Smith   Collective
106f6829af0SVijay Mahadevan 
107d8d19677SJose E. Roman   Input Parameters:
108a2b725a8SWilliam Gropp + dm              - The DMMoab object being set
109a2b725a8SWilliam Gropp - vec             - The Vector whose underlying data is requested
110f6829af0SVijay Mahadevan 
111f6829af0SVijay Mahadevan   Output Parameter:
112f6829af0SVijay Mahadevan . array           - The local data array
113f6829af0SVijay Mahadevan 
114f6829af0SVijay Mahadevan   Level: intermediate
115f6829af0SVijay Mahadevan 
116db781477SPatrick Sanan .seealso: `DMMoabVecRestoreArray()`, `DMMoabVecGetArrayRead()`, `DMMoabVecRestoreArrayRead()`
117f6829af0SVijay Mahadevan @*/
1189371c9d4SSatish Balay PetscErrorCode DMMoabVecGetArray(DM dm, Vec vec, void *array) {
119f6829af0SVijay Mahadevan   DM_Moab        *dmmoab;
120f6829af0SVijay Mahadevan   moab::ErrorCode merr;
121f6829af0SVijay Mahadevan   PetscInt        count, i, f;
122f6829af0SVijay Mahadevan   moab::Tag       vtag;
123f6829af0SVijay Mahadevan   PetscScalar   **varray;
124f6829af0SVijay Mahadevan   PetscScalar    *marray;
125f6829af0SVijay Mahadevan   PetscContainer  moabdata;
126f6829af0SVijay Mahadevan   Vec_MOAB       *vmoab, *xmoab;
127f6829af0SVijay Mahadevan 
128f6829af0SVijay Mahadevan   PetscFunctionBegin;
129f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
130f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
131f6829af0SVijay Mahadevan   PetscValidPointer(array, 3);
132f6829af0SVijay Mahadevan   dmmoab = (DM_Moab *)dm->data;
133f6829af0SVijay Mahadevan 
134f6829af0SVijay Mahadevan   /* Get the Vec_MOAB struct for the original vector */
1359566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)vec, "MOABData", (PetscObject *)&moabdata));
1369566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
137f6829af0SVijay Mahadevan 
138f6829af0SVijay Mahadevan   /* Get the real scalar array handle */
139f6829af0SVijay Mahadevan   varray = reinterpret_cast<PetscScalar **>(array);
140f6829af0SVijay Mahadevan 
141f6829af0SVijay Mahadevan   if (vmoab->is_native_vec) {
142f6829af0SVijay Mahadevan     /* get the local representation of the arrays from Vectors */
1439566063dSJacob Faibussowitsch     PetscCall(DMGetLocalVector(dm, &vmoab->local));
1449566063dSJacob Faibussowitsch     PetscCall(DMGlobalToLocalBegin(dm, vec, INSERT_VALUES, vmoab->local));
1459566063dSJacob Faibussowitsch     PetscCall(DMGlobalToLocalEnd(dm, vec, INSERT_VALUES, vmoab->local));
146f6829af0SVijay Mahadevan 
147f6829af0SVijay Mahadevan     /* Get the Vec_MOAB struct for the original vector */
1489566063dSJacob Faibussowitsch     PetscCall(PetscObjectQuery((PetscObject)vmoab->local, "MOABData", (PetscObject *)&moabdata));
1499566063dSJacob Faibussowitsch     PetscCall(PetscContainerGetPointer(moabdata, (void **)&xmoab));
150f6829af0SVijay Mahadevan 
151f6829af0SVijay Mahadevan     /* get the local representation of the arrays from Vectors */
1529566063dSJacob Faibussowitsch     PetscCall(VecGhostGetLocalForm(vmoab->local, &xmoab->local));
1539566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateBegin(vmoab->local, INSERT_VALUES, SCATTER_FORWARD));
1549566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateEnd(vmoab->local, INSERT_VALUES, SCATTER_FORWARD));
155f6829af0SVijay Mahadevan 
1569566063dSJacob Faibussowitsch     PetscCall(VecGetArray(xmoab->local, varray));
1571baa6e33SBarry Smith   } else {
158f6829af0SVijay Mahadevan     /* Get the MOAB private data */
1599566063dSJacob Faibussowitsch     PetscCall(DMMoabGetVecTag(vec, &vtag));
160f6829af0SVijay Mahadevan 
1619daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
162f6829af0SVijay Mahadevan     /* exchange the data into ghost cells first */
1639371c9d4SSatish Balay     merr = dmmoab->pcomm->exchange_tags(vtag, *dmmoab->vlocal);
1649371c9d4SSatish Balay     MBERRNM(merr);
1659daf19fdSVijay Mahadevan #endif
166f6829af0SVijay Mahadevan 
1679566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((dmmoab->nloc + dmmoab->nghost) * dmmoab->numFields, varray));
168f6829af0SVijay Mahadevan 
169f6829af0SVijay Mahadevan     /* Get the array data for local entities */
1709371c9d4SSatish Balay     merr = dmmoab->mbiface->tag_iterate(vtag, dmmoab->vlocal->begin(), dmmoab->vlocal->end(), count, reinterpret_cast<void *&>(marray), false);
1719371c9d4SSatish Balay     MBERRNM(merr);
1721dca8a05SBarry Smith     PetscCheck(count == dmmoab->nloc + dmmoab->nghost, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between local vertices and tag partition for Vec. %" PetscInt_FMT " != %" PetscInt_FMT ".", count, dmmoab->nloc + dmmoab->nghost);
173f6829af0SVijay Mahadevan 
174f6829af0SVijay Mahadevan     i = 0;
175f6829af0SVijay Mahadevan     for (moab::Range::iterator iter = dmmoab->vlocal->begin(); iter != dmmoab->vlocal->end(); iter++) {
1769371c9d4SSatish Balay       for (f = 0; f < dmmoab->numFields; f++, i++) (*varray)[dmmoab->lidmap[(PetscInt)*iter - dmmoab->seqstart] * dmmoab->numFields + f] = marray[i];
1773f1c6e43SVijay Mahadevan       //(*varray)[dmmoab->llmap[dmmoab->lidmap[((PetscInt)*iter-dmmoab->seqstart)]*dmmoab->numFields+f]]=marray[i];
178f6829af0SVijay Mahadevan     }
179f6829af0SVijay Mahadevan   }
180f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
181f6829af0SVijay Mahadevan }
182f6829af0SVijay Mahadevan 
183b8ecf6d3SVijay Mahadevan /*@C
184f6829af0SVijay Mahadevan   DMMoabVecRestoreArray - Restores the writable direct access array obtained via DMMoabVecGetArray
185f6829af0SVijay Mahadevan 
186d083f849SBarry Smith   Collective
187f6829af0SVijay Mahadevan 
188d8d19677SJose E. Roman   Input Parameters:
189f6829af0SVijay Mahadevan + dm              - The DMMoab object being set
190f6829af0SVijay Mahadevan . vec             - The Vector whose underlying data is requested
191a2b725a8SWilliam Gropp - array           - The local data array
192f6829af0SVijay Mahadevan 
193f6829af0SVijay Mahadevan   Level: intermediate
194f6829af0SVijay Mahadevan 
195db781477SPatrick Sanan .seealso: `DMMoabVecGetArray()`, `DMMoabVecGetArrayRead()`, `DMMoabVecRestoreArrayRead()`
196f6829af0SVijay Mahadevan @*/
1979371c9d4SSatish Balay PetscErrorCode DMMoabVecRestoreArray(DM dm, Vec vec, void *array) {
198f6829af0SVijay Mahadevan   DM_Moab        *dmmoab;
199f6829af0SVijay Mahadevan   moab::ErrorCode merr;
200f6829af0SVijay Mahadevan   moab::Tag       vtag;
201f6829af0SVijay Mahadevan   PetscInt        count, i, f;
202f6829af0SVijay Mahadevan   PetscScalar   **varray;
203f6829af0SVijay Mahadevan   PetscScalar    *marray;
204f6829af0SVijay Mahadevan   PetscContainer  moabdata;
205f6829af0SVijay Mahadevan   Vec_MOAB       *vmoab, *xmoab;
206f6829af0SVijay Mahadevan 
207f6829af0SVijay Mahadevan   PetscFunctionBegin;
208f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
209f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
210f6829af0SVijay Mahadevan   PetscValidPointer(array, 3);
211f6829af0SVijay Mahadevan   dmmoab = (DM_Moab *)dm->data;
212f6829af0SVijay Mahadevan 
213f6829af0SVijay Mahadevan   /* Get the Vec_MOAB struct for the original vector */
2149566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)vec, "MOABData", (PetscObject *)&moabdata));
2159566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
216f6829af0SVijay Mahadevan 
217f6829af0SVijay Mahadevan   /* Get the real scalar array handle */
218f6829af0SVijay Mahadevan   varray = reinterpret_cast<PetscScalar **>(array);
219f6829af0SVijay Mahadevan 
220f6829af0SVijay Mahadevan   if (vmoab->is_native_vec) {
221f6829af0SVijay Mahadevan     /* Get the Vec_MOAB struct for the original vector */
2229566063dSJacob Faibussowitsch     PetscCall(PetscObjectQuery((PetscObject)vmoab->local, "MOABData", (PetscObject *)&moabdata));
2239566063dSJacob Faibussowitsch     PetscCall(PetscContainerGetPointer(moabdata, (void **)&xmoab));
224f6829af0SVijay Mahadevan 
225f6829af0SVijay Mahadevan     /* get the local representation of the arrays from Vectors */
2269566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(xmoab->local, varray));
2279566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateBegin(vmoab->local, ADD_VALUES, SCATTER_REVERSE));
2289566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateEnd(vmoab->local, ADD_VALUES, SCATTER_REVERSE));
2299566063dSJacob Faibussowitsch     PetscCall(VecGhostRestoreLocalForm(vmoab->local, &xmoab->local));
230f6829af0SVijay Mahadevan 
231f6829af0SVijay Mahadevan     /* restore local pieces */
2329566063dSJacob Faibussowitsch     PetscCall(DMLocalToGlobalBegin(dm, vmoab->local, INSERT_VALUES, vec));
2339566063dSJacob Faibussowitsch     PetscCall(DMLocalToGlobalEnd(dm, vmoab->local, INSERT_VALUES, vec));
2349566063dSJacob Faibussowitsch     PetscCall(DMRestoreLocalVector(dm, &vmoab->local));
2359371c9d4SSatish Balay   } else {
236f6829af0SVijay Mahadevan     /* Get the MOAB private data */
2379566063dSJacob Faibussowitsch     PetscCall(DMMoabGetVecTag(vec, &vtag));
238f6829af0SVijay Mahadevan 
239f6829af0SVijay Mahadevan     /* Get the array data for local entities */
2409371c9d4SSatish Balay     merr = dmmoab->mbiface->tag_iterate(vtag, dmmoab->vlocal->begin(), dmmoab->vlocal->end(), count, reinterpret_cast<void *&>(marray), false);
2419371c9d4SSatish Balay     MBERRNM(merr);
2421dca8a05SBarry Smith     PetscCheck(count == dmmoab->nloc + dmmoab->nghost, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between local vertices and tag partition for Vec. %" PetscInt_FMT " != %" PetscInt_FMT ".", count, dmmoab->nloc + dmmoab->nghost);
243f6829af0SVijay Mahadevan 
244f6829af0SVijay Mahadevan     i = 0;
245f6829af0SVijay Mahadevan     for (moab::Range::iterator iter = dmmoab->vlocal->begin(); iter != dmmoab->vlocal->end(); iter++) {
2469371c9d4SSatish Balay       for (f = 0; f < dmmoab->numFields; f++, i++) marray[i] = (*varray)[dmmoab->lidmap[(PetscInt)*iter - dmmoab->seqstart] * dmmoab->numFields + f];
2473f1c6e43SVijay Mahadevan       //marray[i] = (*varray)[dmmoab->llmap[dmmoab->lidmap[((PetscInt)*iter-dmmoab->seqstart)]*dmmoab->numFields+f]];
248f6829af0SVijay Mahadevan     }
249f6829af0SVijay Mahadevan 
2509daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
251f6829af0SVijay Mahadevan     /* reduce the tags correctly -> should probably let the user choose how to reduce in the future
252f6829af0SVijay Mahadevan       For all FEM residual based assembly calculations, MPI_SUM should serve well */
2539371c9d4SSatish Balay     merr = dmmoab->pcomm->reduce_tags(vtag, MPI_SUM, *dmmoab->vlocal);
2549371c9d4SSatish Balay     MBERRV(dmmoab->mbiface, merr);
2559daf19fdSVijay Mahadevan #endif
2569566063dSJacob Faibussowitsch     PetscCall(PetscFree(*varray));
257f6829af0SVijay Mahadevan   }
258f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
259f6829af0SVijay Mahadevan }
260f6829af0SVijay Mahadevan 
261b8ecf6d3SVijay Mahadevan /*@C
262f6829af0SVijay Mahadevan   DMMoabVecGetArrayRead - Returns the read-only direct access array to the local representation of MOAB tag data for the underlying vector using locally owned+ghosted range of entities
263f6829af0SVijay Mahadevan 
264d083f849SBarry Smith   Collective
265f6829af0SVijay Mahadevan 
266d8d19677SJose E. Roman   Input Parameters:
267f6829af0SVijay Mahadevan + dm              - The DMMoab object being set
268a2b725a8SWilliam Gropp - vec             - The Vector whose underlying data is requested
269f6829af0SVijay Mahadevan 
270f6829af0SVijay Mahadevan   Output Parameter:
271f6829af0SVijay Mahadevan . array           - The local data array
272f6829af0SVijay Mahadevan 
273f6829af0SVijay Mahadevan   Level: intermediate
274f6829af0SVijay Mahadevan 
275db781477SPatrick Sanan .seealso: `DMMoabVecRestoreArrayRead()`, `DMMoabVecGetArray()`, `DMMoabVecRestoreArray()`
276f6829af0SVijay Mahadevan @*/
2779371c9d4SSatish Balay PetscErrorCode DMMoabVecGetArrayRead(DM dm, Vec vec, void *array) {
278f6829af0SVijay Mahadevan   DM_Moab        *dmmoab;
279f6829af0SVijay Mahadevan   moab::ErrorCode merr;
280f6829af0SVijay Mahadevan   PetscInt        count, i, f;
281f6829af0SVijay Mahadevan   moab::Tag       vtag;
282f6829af0SVijay Mahadevan   PetscScalar   **varray;
283f6829af0SVijay Mahadevan   PetscScalar    *marray;
284f6829af0SVijay Mahadevan   PetscContainer  moabdata;
285f6829af0SVijay Mahadevan   Vec_MOAB       *vmoab, *xmoab;
286f6829af0SVijay Mahadevan 
287f6829af0SVijay Mahadevan   PetscFunctionBegin;
288f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
289f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
290f6829af0SVijay Mahadevan   PetscValidPointer(array, 3);
291f6829af0SVijay Mahadevan   dmmoab = (DM_Moab *)dm->data;
292f6829af0SVijay Mahadevan 
293f6829af0SVijay Mahadevan   /* Get the Vec_MOAB struct for the original vector */
2949566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)vec, "MOABData", (PetscObject *)&moabdata));
2959566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
296f6829af0SVijay Mahadevan 
297f6829af0SVijay Mahadevan   /* Get the real scalar array handle */
298f6829af0SVijay Mahadevan   varray = reinterpret_cast<PetscScalar **>(array);
299f6829af0SVijay Mahadevan 
300f6829af0SVijay Mahadevan   if (vmoab->is_native_vec) {
301f6829af0SVijay Mahadevan     /* get the local representation of the arrays from Vectors */
3029566063dSJacob Faibussowitsch     PetscCall(DMGetLocalVector(dm, &vmoab->local));
3039566063dSJacob Faibussowitsch     PetscCall(DMGlobalToLocalBegin(dm, vec, INSERT_VALUES, vmoab->local));
3049566063dSJacob Faibussowitsch     PetscCall(DMGlobalToLocalEnd(dm, vec, INSERT_VALUES, vmoab->local));
305f6829af0SVijay Mahadevan 
306f6829af0SVijay Mahadevan     /* Get the Vec_MOAB struct for the original vector */
3079566063dSJacob Faibussowitsch     PetscCall(PetscObjectQuery((PetscObject)vmoab->local, "MOABData", (PetscObject *)&moabdata));
3089566063dSJacob Faibussowitsch     PetscCall(PetscContainerGetPointer(moabdata, (void **)&xmoab));
309f6829af0SVijay Mahadevan 
310f6829af0SVijay Mahadevan     /* get the local representation of the arrays from Vectors */
3119566063dSJacob Faibussowitsch     PetscCall(VecGhostGetLocalForm(vmoab->local, &xmoab->local));
3129566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateBegin(vmoab->local, INSERT_VALUES, SCATTER_FORWARD));
3139566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateEnd(vmoab->local, INSERT_VALUES, SCATTER_FORWARD));
3149566063dSJacob Faibussowitsch     PetscCall(VecGetArray(xmoab->local, varray));
3159371c9d4SSatish Balay   } else {
316f6829af0SVijay Mahadevan     /* Get the MOAB private data */
3179566063dSJacob Faibussowitsch     PetscCall(DMMoabGetVecTag(vec, &vtag));
318f6829af0SVijay Mahadevan 
3199daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
320f6829af0SVijay Mahadevan     /* exchange the data into ghost cells first */
3219371c9d4SSatish Balay     merr = dmmoab->pcomm->exchange_tags(vtag, *dmmoab->vlocal);
3229371c9d4SSatish Balay     MBERRNM(merr);
3239daf19fdSVijay Mahadevan #endif
3249566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((dmmoab->nloc + dmmoab->nghost) * dmmoab->numFields, varray));
325f6829af0SVijay Mahadevan 
326f6829af0SVijay Mahadevan     /* Get the array data for local entities */
3279371c9d4SSatish Balay     merr = dmmoab->mbiface->tag_iterate(vtag, dmmoab->vlocal->begin(), dmmoab->vlocal->end(), count, reinterpret_cast<void *&>(marray), false);
3289371c9d4SSatish Balay     MBERRNM(merr);
3291dca8a05SBarry Smith     PetscCheck(count == dmmoab->nloc + dmmoab->nghost, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between local vertices and tag partition for Vec. %" PetscInt_FMT " != %" PetscInt_FMT ".", count, dmmoab->nloc + dmmoab->nghost);
330f6829af0SVijay Mahadevan 
331f6829af0SVijay Mahadevan     i = 0;
332f6829af0SVijay Mahadevan     for (moab::Range::iterator iter = dmmoab->vlocal->begin(); iter != dmmoab->vlocal->end(); iter++) {
3339371c9d4SSatish Balay       for (f = 0; f < dmmoab->numFields; f++, i++) (*varray)[dmmoab->lidmap[(PetscInt)*iter - dmmoab->seqstart] * dmmoab->numFields + f] = marray[i];
3343f1c6e43SVijay Mahadevan       //(*varray)[dmmoab->llmap[dmmoab->lidmap[((PetscInt)*iter-dmmoab->seqstart)]*dmmoab->numFields+f]]=marray[i];
335f6829af0SVijay Mahadevan     }
336f6829af0SVijay Mahadevan   }
337f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
338f6829af0SVijay Mahadevan }
339f6829af0SVijay Mahadevan 
340b8ecf6d3SVijay Mahadevan /*@C
3414597dd3dSJose E. Roman   DMMoabVecRestoreArrayRead - Restores the read-only direct access array obtained via DMMoabVecGetArray
342f6829af0SVijay Mahadevan 
343d083f849SBarry Smith   Collective
344f6829af0SVijay Mahadevan 
34597bb3fdcSJose E. Roman   Input Parameters:
346f6829af0SVijay Mahadevan + dm              - The DMMoab object being set
347f6829af0SVijay Mahadevan . vec             - The Vector whose underlying data is requested
348a2b725a8SWilliam Gropp - array           - The local data array
349f6829af0SVijay Mahadevan 
350f6829af0SVijay Mahadevan   Level: intermediate
351f6829af0SVijay Mahadevan 
352db781477SPatrick Sanan .seealso: `DMMoabVecGetArrayRead()`, `DMMoabVecGetArray()`, `DMMoabVecRestoreArray()`
353f6829af0SVijay Mahadevan @*/
3549371c9d4SSatish Balay PetscErrorCode DMMoabVecRestoreArrayRead(DM dm, Vec vec, void *array) {
355f6829af0SVijay Mahadevan   PetscScalar  **varray;
356f6829af0SVijay Mahadevan   PetscContainer moabdata;
357f6829af0SVijay Mahadevan   Vec_MOAB      *vmoab, *xmoab;
358f6829af0SVijay Mahadevan 
359f6829af0SVijay Mahadevan   PetscFunctionBegin;
360f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
361f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
362f6829af0SVijay Mahadevan   PetscValidPointer(array, 3);
363f6829af0SVijay Mahadevan 
364f6829af0SVijay Mahadevan   /* Get the Vec_MOAB struct for the original vector */
3659566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)vec, "MOABData", (PetscObject *)&moabdata));
3669566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
367f6829af0SVijay Mahadevan 
368f6829af0SVijay Mahadevan   /* Get the real scalar array handle */
369f6829af0SVijay Mahadevan   varray = reinterpret_cast<PetscScalar **>(array);
370f6829af0SVijay Mahadevan 
371f6829af0SVijay Mahadevan   if (vmoab->is_native_vec) {
372f6829af0SVijay Mahadevan     /* Get the Vec_MOAB struct for the original vector */
3739566063dSJacob Faibussowitsch     PetscCall(PetscObjectQuery((PetscObject)vmoab->local, "MOABData", (PetscObject *)&moabdata));
3749566063dSJacob Faibussowitsch     PetscCall(PetscContainerGetPointer(moabdata, (void **)&xmoab));
375f6829af0SVijay Mahadevan 
376f6829af0SVijay Mahadevan     /* restore the local representation of the arrays from Vectors */
3779566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(xmoab->local, varray));
3789566063dSJacob Faibussowitsch     PetscCall(VecGhostRestoreLocalForm(vmoab->local, &xmoab->local));
379f6829af0SVijay Mahadevan 
380f6829af0SVijay Mahadevan     /* restore local pieces */
3819566063dSJacob Faibussowitsch     PetscCall(DMRestoreLocalVector(dm, &vmoab->local));
3829371c9d4SSatish Balay   } else {
383f6829af0SVijay Mahadevan     /* Nothing to do but just free the memory allocated before */
3849566063dSJacob Faibussowitsch     PetscCall(PetscFree(*varray));
385f6829af0SVijay Mahadevan   }
386f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
387f6829af0SVijay Mahadevan }
388f6829af0SVijay Mahadevan 
3899371c9d4SSatish Balay PetscErrorCode DMCreateVector_Moab_Private(DM dm, moab::Tag tag, const moab::Range *userrange, PetscBool is_global_vec, PetscBool destroy_tag, Vec *vec) {
390032b8ab6SVijay Mahadevan   moab::ErrorCode    merr;
391032b8ab6SVijay Mahadevan   PetscBool          is_newtag;
392351b8a77SVijay Mahadevan   const moab::Range *range;
393bb8f3634SVijay Mahadevan   PetscInt           count, lnative_vec, gnative_vec;
3949088682fSVijay Mahadevan   std::string        ttname;
395c4427235SVijay Mahadevan   PetscScalar       *data_ptr, *defaultvals;
396032b8ab6SVijay Mahadevan 
397db66d124SVijay Mahadevan   Vec_MOAB *vmoab;
398032b8ab6SVijay Mahadevan   DM_Moab  *dmmoab = (DM_Moab *)dm->data;
3999daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
400032b8ab6SVijay Mahadevan   moab::ParallelComm *pcomm = dmmoab->pcomm;
4019daf19fdSVijay Mahadevan #endif
402032b8ab6SVijay Mahadevan   moab::Interface *mbiface = dmmoab->mbiface;
403032b8ab6SVijay Mahadevan 
404032b8ab6SVijay Mahadevan   PetscFunctionBegin;
40508401ef6SPierre Jolivet   PetscCheck(sizeof(PetscReal) == sizeof(PetscScalar), PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "MOAB tags only support Real types (Complex-type unsupported)");
406032b8ab6SVijay Mahadevan   if (!userrange) range = dmmoab->vowned;
407032b8ab6SVijay Mahadevan   else range = userrange;
4087a8be351SBarry Smith   PetscCheck(range, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Input range cannot be empty or call DMSetUp first.");
409032b8ab6SVijay Mahadevan 
4103ac71f70SVijay Mahadevan #ifndef USE_NATIVE_PETSCVEC
411bb8f3634SVijay Mahadevan   /* If the tag data is in a single sequence, use PETSc native vector since tag_iterate isn't useful anymore */
412bb8f3634SVijay Mahadevan   lnative_vec = (range->psize() - 1);
4133ac71f70SVijay Mahadevan #else
4143ac71f70SVijay Mahadevan   lnative_vec = 1; /* NOTE: Testing PETSc vector: will force to create native vector all the time */
4156465f021SVijay Mahadevan                    //  lnative_vec=0; /* NOTE: Testing MOAB vector: will force to create MOAB tag_iterate based vector all the time */
416f6829af0SVijay Mahadevan #endif
4173ac71f70SVijay Mahadevan 
4189daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
4191c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&lnative_vec, &gnative_vec, 1, MPI_INT, MPI_MAX, (((PetscObject)dm)->comm)));
4209daf19fdSVijay Mahadevan #else
4219daf19fdSVijay Mahadevan   gnative_vec = lnative_vec;
4229daf19fdSVijay Mahadevan #endif
423bb8f3634SVijay Mahadevan 
424bb8f3634SVijay Mahadevan   /* Create the MOAB internal data object */
4259566063dSJacob Faibussowitsch   PetscCall(PetscNew(&vmoab));
426bb8f3634SVijay Mahadevan   vmoab->is_native_vec = (gnative_vec > 0 ? PETSC_TRUE : PETSC_FALSE);
427bb8f3634SVijay Mahadevan 
428bb8f3634SVijay Mahadevan   if (!vmoab->is_native_vec) {
4293ac71f70SVijay Mahadevan     merr = moab::MB_SUCCESS;
43064e1c140SVijay Mahadevan     if (tag != 0) merr = mbiface->tag_get_name(tag, ttname);
43164e1c140SVijay Mahadevan     if (!ttname.length() || merr != moab::MB_SUCCESS) {
432db66d124SVijay Mahadevan       /* get the new name for the anonymous MOABVec -> the tag_name will be destroyed along with Tag */
433c528d872SBarry Smith       char *tag_name = NULL;
4349daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
4359566063dSJacob Faibussowitsch       PetscCall(DMVecCreateTagName_Moab_Private(mbiface, pcomm, &tag_name));
4369daf19fdSVijay Mahadevan #else
4379566063dSJacob Faibussowitsch       PetscCall(DMVecCreateTagName_Moab_Private(mbiface, &tag_name));
4389daf19fdSVijay Mahadevan #endif
439032b8ab6SVijay Mahadevan       is_newtag = PETSC_TRUE;
440032b8ab6SVijay Mahadevan 
441db66d124SVijay Mahadevan       /* Create the default value for the tag (all zeros) */
4429566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dmmoab->numFields, &defaultvals));
443032b8ab6SVijay Mahadevan 
444db66d124SVijay Mahadevan       /* Create the tag */
4459371c9d4SSatish Balay       merr = mbiface->tag_get_handle(tag_name, dmmoab->numFields, moab::MB_TYPE_DOUBLE, tag, moab::MB_TAG_DENSE | moab::MB_TAG_CREAT, defaultvals);
4469371c9d4SSatish Balay       MBERRNM(merr);
4479566063dSJacob Faibussowitsch       PetscCall(PetscFree(tag_name));
4489566063dSJacob Faibussowitsch       PetscCall(PetscFree(defaultvals));
4499371c9d4SSatish Balay     } else {
450db66d124SVijay Mahadevan       /* Make sure the tag data is of type "double" */
451032b8ab6SVijay Mahadevan       moab::DataType tag_type;
4529371c9d4SSatish Balay       merr = mbiface->tag_get_data_type(tag, tag_type);
4539371c9d4SSatish Balay       MBERRNM(merr);
4541dca8a05SBarry Smith       PetscCheck(tag_type == moab::MB_TYPE_DOUBLE, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE");
455032b8ab6SVijay Mahadevan       is_newtag = destroy_tag;
456032b8ab6SVijay Mahadevan     }
457032b8ab6SVijay Mahadevan 
458032b8ab6SVijay Mahadevan     vmoab->tag     = tag;
459bb8f3634SVijay Mahadevan     vmoab->new_tag = is_newtag;
460bb8f3634SVijay Mahadevan   }
461032b8ab6SVijay Mahadevan   vmoab->mbiface = mbiface;
4629daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
463032b8ab6SVijay Mahadevan   vmoab->pcomm = pcomm;
4649daf19fdSVijay Mahadevan #endif
465032b8ab6SVijay Mahadevan   vmoab->is_global_vec = is_global_vec;
466bb8f3634SVijay Mahadevan   vmoab->tag_size      = dmmoab->bs;
467032b8ab6SVijay Mahadevan 
468bb8f3634SVijay Mahadevan   if (vmoab->is_native_vec) {
469bb8f3634SVijay Mahadevan     /* Create the PETSc Vector directly and attach our functions accordingly */
470bb8f3634SVijay Mahadevan     if (!is_global_vec) {
471bb8f3634SVijay Mahadevan       /* This is an MPI Vector with ghosted padding */
4729566063dSJacob Faibussowitsch       PetscCall(VecCreateGhostBlock((((PetscObject)dm)->comm), dmmoab->bs, dmmoab->numFields * dmmoab->nloc, dmmoab->numFields * dmmoab->n, dmmoab->nghost, &dmmoab->gsindices[dmmoab->nloc], vec));
4735f80ce2aSJacob Faibussowitsch     } else {
474bb8f3634SVijay Mahadevan       /* This is an MPI/SEQ Vector */
4759566063dSJacob Faibussowitsch       PetscCall(VecCreate((((PetscObject)dm)->comm), vec));
4769566063dSJacob Faibussowitsch       PetscCall(VecSetSizes(*vec, dmmoab->numFields * dmmoab->nloc, PETSC_DECIDE));
4779566063dSJacob Faibussowitsch       PetscCall(VecSetBlockSize(*vec, dmmoab->bs));
4789566063dSJacob Faibussowitsch       PetscCall(VecSetType(*vec, VECMPI));
479bb8f3634SVijay Mahadevan     }
4805f80ce2aSJacob Faibussowitsch   } else {
481db66d124SVijay Mahadevan     /* Call tag_iterate. This will cause MOAB to allocate memory for the
482db66d124SVijay Mahadevan        tag data if it hasn't already happened */
4839371c9d4SSatish Balay     merr = mbiface->tag_iterate(tag, range->begin(), range->end(), count, (void *&)data_ptr);
4849371c9d4SSatish Balay     MBERRNM(merr);
485032b8ab6SVijay Mahadevan 
486bb8f3634SVijay Mahadevan     /* set the reference for vector range */
487bb8f3634SVijay Mahadevan     vmoab->tag_range = new moab::Range(*range);
4889371c9d4SSatish Balay     merr             = mbiface->tag_get_length(tag, dmmoab->numFields);
4899371c9d4SSatish Balay     MBERRNM(merr);
490032b8ab6SVijay Mahadevan 
491db66d124SVijay Mahadevan     /* Create the PETSc Vector
492db66d124SVijay Mahadevan       Query MOAB mesh to check if there are any ghosted entities
493032b8ab6SVijay Mahadevan         -> if we do, create a ghosted vector to map correctly to the same layout
494032b8ab6SVijay Mahadevan         -> else, create a non-ghosted parallel vector */
495bb8f3634SVijay Mahadevan     if (!is_global_vec) {
496db66d124SVijay Mahadevan       /* This is an MPI Vector with ghosted padding */
4979566063dSJacob Faibussowitsch       PetscCall(VecCreateGhostBlockWithArray((((PetscObject)dm)->comm), dmmoab->bs, dmmoab->numFields * dmmoab->nloc, dmmoab->numFields * dmmoab->n, dmmoab->nghost, &dmmoab->gsindices[dmmoab->nloc], data_ptr, vec));
4985f80ce2aSJacob Faibussowitsch     } else {
499bb8f3634SVijay Mahadevan       /* This is an MPI Vector without ghosted padding */
5009566063dSJacob Faibussowitsch       PetscCall(VecCreateMPIWithArray((((PetscObject)dm)->comm), dmmoab->bs, dmmoab->numFields * range->size(), PETSC_DECIDE, data_ptr, vec));
501032b8ab6SVijay Mahadevan     }
502bb8f3634SVijay Mahadevan   }
5039566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(*vec));
504032b8ab6SVijay Mahadevan 
505f6829af0SVijay Mahadevan   /* create a container and store the internal MOAB data for faster access based on Entities etc */
506032b8ab6SVijay Mahadevan   PetscContainer moabdata;
5079566063dSJacob Faibussowitsch   PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &moabdata));
5089566063dSJacob Faibussowitsch   PetscCall(PetscContainerSetPointer(moabdata, vmoab));
5099566063dSJacob Faibussowitsch   PetscCall(PetscContainerSetUserDestroy(moabdata, DMVecUserDestroy_Moab));
5109566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)*vec, "MOABData", (PetscObject)moabdata));
511f6829af0SVijay Mahadevan   (*vec)->ops->duplicate = DMVecDuplicate_Moab;
5129566063dSJacob Faibussowitsch   PetscCall(PetscContainerDestroy(&moabdata));
513032b8ab6SVijay Mahadevan 
514db66d124SVijay Mahadevan   /* Vector created, manually set local to global mapping */
515*48a46eb9SPierre Jolivet   if (dmmoab->ltog_map) PetscCall(VecSetLocalToGlobalMapping(*vec, dmmoab->ltog_map));
516032b8ab6SVijay Mahadevan 
517032b8ab6SVijay Mahadevan   /* set the DM reference to the vector */
5189566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*vec, dm));
519032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
520032b8ab6SVijay Mahadevan }
521032b8ab6SVijay Mahadevan 
522f6829af0SVijay Mahadevan /*  DMVecCreateTagName_Moab_Private
523032b8ab6SVijay Mahadevan  *
524032b8ab6SVijay Mahadevan  *  Creates a unique tag name that will be shared across processes. If
525032b8ab6SVijay Mahadevan  *  pcomm is NULL, then this is a serial vector. A unique tag name
526032b8ab6SVijay Mahadevan  *  will be returned in tag_name in either case.
527032b8ab6SVijay Mahadevan  *
528032b8ab6SVijay Mahadevan  *  The tag names have the format _PETSC_VEC_N where N is some integer.
529032b8ab6SVijay Mahadevan  *
530032b8ab6SVijay Mahadevan  *  NOTE: The tag_name is allocated in this routine; The user needs to free
531032b8ab6SVijay Mahadevan  *        the character array.
532032b8ab6SVijay Mahadevan  */
5339daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
5349daf19fdSVijay Mahadevan PetscErrorCode DMVecCreateTagName_Moab_Private(moab::Interface *mbiface, moab::ParallelComm *pcomm, char **tag_name)
5359daf19fdSVijay Mahadevan #else
5369daf19fdSVijay Mahadevan PetscErrorCode DMVecCreateTagName_Moab_Private(moab::Interface *mbiface, char **tag_name)
5379daf19fdSVijay Mahadevan #endif
538032b8ab6SVijay Mahadevan {
539032b8ab6SVijay Mahadevan   moab::ErrorCode mberr;
540032b8ab6SVijay Mahadevan   PetscInt        n, global_n;
541032b8ab6SVijay Mahadevan   moab::Tag       indexTag;
542032b8ab6SVijay Mahadevan 
543032b8ab6SVijay Mahadevan   PetscFunctionBegin;
544032b8ab6SVijay Mahadevan   const char *PVEC_PREFIX = "__PETSC_VEC_";
5459566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, tag_name));
546032b8ab6SVijay Mahadevan 
547032b8ab6SVijay Mahadevan   moab::EntityHandle rootset = mbiface->get_root_set();
548032b8ab6SVijay Mahadevan 
5499daf19fdSVijay Mahadevan   /* Check to see if there are any PETSc vectors defined */
550efd17f3eSVijay Mahadevan   /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
5519371c9d4SSatish Balay   mberr = mbiface->tag_get_handle("__PETSC_VECS__", 1, moab::MB_TYPE_INTEGER, indexTag, moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT, 0);
5529371c9d4SSatish Balay   MBERRNM(mberr);
553032b8ab6SVijay Mahadevan   mberr = mbiface->tag_get_data(indexTag, &rootset, 1, &n);
554032b8ab6SVijay Mahadevan   if (mberr == moab::MB_TAG_NOT_FOUND) n = 0; /* this is the first temporary vector */
555032b8ab6SVijay Mahadevan   else MBERRNM(mberr);
556032b8ab6SVijay Mahadevan 
557032b8ab6SVijay Mahadevan   /* increment the new value of n */
558032b8ab6SVijay Mahadevan   ++n;
559032b8ab6SVijay Mahadevan 
5609daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
561efd17f3eSVijay Mahadevan   /* Make sure that n is consistent across all processes */
5621c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&n, &global_n, 1, MPI_INT, MPI_MAX, pcomm->comm()));
5639daf19fdSVijay Mahadevan #else
5649daf19fdSVijay Mahadevan   global_n = n;
5659daf19fdSVijay Mahadevan #endif
566032b8ab6SVijay Mahadevan 
567efd17f3eSVijay Mahadevan   /* Set the new name accordingly and return */
56863a3b9bcSJacob Faibussowitsch   PetscCall(PetscSNPrintf(*tag_name, PETSC_MAX_PATH_LEN - 1, "%s_%" PetscInt_FMT, PVEC_PREFIX, global_n));
5699371c9d4SSatish Balay   mberr = mbiface->tag_set_data(indexTag, &rootset, 1, (const void *)&global_n);
5709371c9d4SSatish Balay   MBERRNM(mberr);
571032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
572032b8ab6SVijay Mahadevan }
573032b8ab6SVijay Mahadevan 
5749371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMCreateGlobalVector_Moab(DM dm, Vec *gvec) {
575f6829af0SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab *)dm->data;
576f6829af0SVijay Mahadevan 
577f6829af0SVijay Mahadevan   PetscFunctionBegin;
578f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
579f6829af0SVijay Mahadevan   PetscValidPointer(gvec, 2);
5809566063dSJacob Faibussowitsch   PetscCall(DMCreateVector_Moab_Private(dm, NULL, dmmoab->vowned, PETSC_TRUE, PETSC_TRUE, gvec));
581f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
582f6829af0SVijay Mahadevan }
583f6829af0SVijay Mahadevan 
5849371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMCreateLocalVector_Moab(DM dm, Vec *lvec) {
585f6829af0SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab *)dm->data;
586f6829af0SVijay Mahadevan 
587f6829af0SVijay Mahadevan   PetscFunctionBegin;
588f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
589f6829af0SVijay Mahadevan   PetscValidPointer(lvec, 2);
5909566063dSJacob Faibussowitsch   PetscCall(DMCreateVector_Moab_Private(dm, NULL, dmmoab->vlocal, PETSC_FALSE, PETSC_TRUE, lvec));
591f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
592f6829af0SVijay Mahadevan }
593f6829af0SVijay Mahadevan 
5949371c9d4SSatish Balay PetscErrorCode DMVecDuplicate_Moab(Vec x, Vec *y) {
595f6829af0SVijay Mahadevan   DM             dm;
596f6829af0SVijay Mahadevan   PetscContainer moabdata;
597f6829af0SVijay Mahadevan   Vec_MOAB      *vmoab;
598f6829af0SVijay Mahadevan 
599f6829af0SVijay Mahadevan   PetscFunctionBegin;
600f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
601f6829af0SVijay Mahadevan   PetscValidPointer(y, 2);
602f6829af0SVijay Mahadevan 
603f6829af0SVijay Mahadevan   /* Get the Vec_MOAB struct for the original vector */
6049566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)x, "MOABData", (PetscObject *)&moabdata));
6059566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(moabdata, (void **)&vmoab));
606f6829af0SVijay Mahadevan 
6079566063dSJacob Faibussowitsch   PetscCall(VecGetDM(x, &dm));
608f6829af0SVijay Mahadevan   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
609f6829af0SVijay Mahadevan 
6109566063dSJacob Faibussowitsch   PetscCall(DMCreateVector_Moab_Private(dm, NULL, vmoab->tag_range, vmoab->is_global_vec, PETSC_TRUE, y));
6119566063dSJacob Faibussowitsch   PetscCall(VecSetDM(*y, dm));
612f6829af0SVijay Mahadevan   PetscFunctionReturn(0);
613f6829af0SVijay Mahadevan }
614f6829af0SVijay Mahadevan 
6159371c9d4SSatish Balay PetscErrorCode DMVecUserDestroy_Moab(void *user) {
616efd17f3eSVijay Mahadevan   Vec_MOAB       *vmoab = (Vec_MOAB *)user;
617032b8ab6SVijay Mahadevan   moab::ErrorCode merr;
618032b8ab6SVijay Mahadevan 
619032b8ab6SVijay Mahadevan   PetscFunctionBegin;
620032b8ab6SVijay Mahadevan   if (vmoab->new_tag && vmoab->tag) {
621efd17f3eSVijay Mahadevan     /* Tag was created via a call to VecDuplicate, delete the underlying tag in MOAB */
6229371c9d4SSatish Balay     merr = vmoab->mbiface->tag_delete(vmoab->tag);
6239371c9d4SSatish Balay     MBERRNM(merr);
624032b8ab6SVijay Mahadevan   }
625032b8ab6SVijay Mahadevan   delete vmoab->tag_range;
626c528d872SBarry Smith   vmoab->tag     = NULL;
627c528d872SBarry Smith   vmoab->mbiface = NULL;
6289daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI
629c528d872SBarry Smith   vmoab->pcomm = NULL;
6309daf19fdSVijay Mahadevan #endif
6319566063dSJacob Faibussowitsch   PetscCall(PetscFree(vmoab));
632032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
633032b8ab6SVijay Mahadevan }
634032b8ab6SVijay Mahadevan 
6359371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMGlobalToLocalBegin_Moab(DM dm, Vec g, InsertMode mode, Vec l) {
636db66d124SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab *)dm->data;
637db66d124SVijay Mahadevan 
638db66d124SVijay Mahadevan   PetscFunctionBegin;
6399566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(dmmoab->ltog_sendrecv, g, l, mode, SCATTER_REVERSE));
640db66d124SVijay Mahadevan   PetscFunctionReturn(0);
641db66d124SVijay Mahadevan }
642db66d124SVijay Mahadevan 
6439371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMGlobalToLocalEnd_Moab(DM dm, Vec g, InsertMode mode, Vec l) {
644db66d124SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab *)dm->data;
645db66d124SVijay Mahadevan 
646db66d124SVijay Mahadevan   PetscFunctionBegin;
6479566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(dmmoab->ltog_sendrecv, g, l, mode, SCATTER_REVERSE));
648db66d124SVijay Mahadevan   PetscFunctionReturn(0);
649db66d124SVijay Mahadevan }
650db66d124SVijay Mahadevan 
6519371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMLocalToGlobalBegin_Moab(DM dm, Vec l, InsertMode mode, Vec g) {
652db66d124SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab *)dm->data;
653db66d124SVijay Mahadevan 
654db66d124SVijay Mahadevan   PetscFunctionBegin;
6559566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(dmmoab->ltog_sendrecv, l, g, mode, SCATTER_FORWARD));
656db66d124SVijay Mahadevan   PetscFunctionReturn(0);
657db66d124SVijay Mahadevan }
658db66d124SVijay Mahadevan 
6599371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMLocalToGlobalEnd_Moab(DM dm, Vec l, InsertMode mode, Vec g) {
660db66d124SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab *)dm->data;
661db66d124SVijay Mahadevan 
662db66d124SVijay Mahadevan   PetscFunctionBegin;
6639566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(dmmoab->ltog_sendrecv, l, g, mode, SCATTER_FORWARD));
664db66d124SVijay Mahadevan   PetscFunctionReturn(0);
665db66d124SVijay Mahadevan }
666