xref: /petsc/src/dm/impls/moab/dmmbvec.cxx (revision 032b8ab68d4668ecf17e7ef7c62e7a29937bca10)
1*032b8ab6SVijay Mahadevan #include <petsc-private/dmmbimpl.h> /*I  "petscdm.h"   I*/
2*032b8ab6SVijay Mahadevan #include <petsc-private/vecimpl.h> /*I  "petscdm.h"   I*/
3*032b8ab6SVijay Mahadevan 
4*032b8ab6SVijay Mahadevan #include <petscdmmoab.h>
5*032b8ab6SVijay Mahadevan #include <MBTagConventions.hpp>
6*032b8ab6SVijay Mahadevan #include <sstream>
7*032b8ab6SVijay Mahadevan 
8*032b8ab6SVijay Mahadevan 
9*032b8ab6SVijay Mahadevan // declare for use later but before they're defined
10*032b8ab6SVijay Mahadevan static PetscErrorCode DMMoab_VecUserDestroy(void *user);
11*032b8ab6SVijay Mahadevan static PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y);
12*032b8ab6SVijay Mahadevan static PetscErrorCode DMMoab_VecCreateTagName_Private(moab::ParallelComm *pcomm,char** tag_name);
13*032b8ab6SVijay Mahadevan 
14*032b8ab6SVijay Mahadevan #undef __FUNCT__
15*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoab_CreateVector_Private"
16*032b8ab6SVijay Mahadevan PetscErrorCode DMMoab_CreateVector_Private(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range* userrange,PetscBool is_global_vec,PetscBool destroy_tag,Vec *vec)
17*032b8ab6SVijay Mahadevan {
18*032b8ab6SVijay Mahadevan   PetscErrorCode         ierr;
19*032b8ab6SVijay Mahadevan   moab::ErrorCode        merr;
20*032b8ab6SVijay Mahadevan   PetscBool              is_newtag;
21*032b8ab6SVijay Mahadevan   moab::Range           *range;
22*032b8ab6SVijay Mahadevan   PetscInt               *gindices,*gsindices;
23*032b8ab6SVijay Mahadevan   PetscInt               i,count,icount,dof;
24*032b8ab6SVijay Mahadevan   PetscInt               size,rank;
25*032b8ab6SVijay Mahadevan   PetscScalar *data_ptr;
26*032b8ab6SVijay Mahadevan 
27*032b8ab6SVijay Mahadevan   DM_Moab *dmmoab = (DM_Moab*)dm->data;
28*032b8ab6SVijay Mahadevan   moab::ParallelComm *pcomm = dmmoab->pcomm;
29*032b8ab6SVijay Mahadevan   moab::Interface *mbiface = dmmoab->mbiface;
30*032b8ab6SVijay Mahadevan   moab::Tag ltog_tag = dmmoab->ltog_tag;
31*032b8ab6SVijay Mahadevan 
32*032b8ab6SVijay Mahadevan   Vec_MOAB *vmoab;
33*032b8ab6SVijay Mahadevan 
34*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
35*032b8ab6SVijay Mahadevan //  if(!range) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Range cannot be empty.");
36*032b8ab6SVijay Mahadevan   if(!userrange) range = dmmoab->vowned;
37*032b8ab6SVijay Mahadevan   else range = userrange;
38*032b8ab6SVijay Mahadevan 
39*032b8ab6SVijay Mahadevan   if (!tag) {
40*032b8ab6SVijay Mahadevan     // get the new name for the anonymous MOABVec -> the tag_name will be destroyed along with Tag
41*032b8ab6SVijay Mahadevan     char *tag_name = PETSC_NULL;
42*032b8ab6SVijay Mahadevan     ierr = DMMoab_VecCreateTagName_Private(pcomm,&tag_name);CHKERRQ(ierr);
43*032b8ab6SVijay Mahadevan     is_newtag = PETSC_TRUE;
44*032b8ab6SVijay Mahadevan 
45*032b8ab6SVijay Mahadevan       // Create the default value for the tag (all zeros):
46*032b8ab6SVijay Mahadevan     std::vector<PetscScalar> default_value(tag_size, 0.0);
47*032b8ab6SVijay Mahadevan 
48*032b8ab6SVijay Mahadevan       // Create the tag:
49*032b8ab6SVijay Mahadevan     merr = mbiface->tag_get_handle(tag_name,tag_size,moab::MB_TYPE_DOUBLE,tag,
50*032b8ab6SVijay Mahadevan                                    moab::MB_TAG_DENSE|moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr);
51*032b8ab6SVijay Mahadevan     ierr = PetscFree(tag_name);CHKERRQ(ierr);
52*032b8ab6SVijay Mahadevan   }
53*032b8ab6SVijay Mahadevan   else {
54*032b8ab6SVijay Mahadevan       // Make sure the tag data is of type "double":
55*032b8ab6SVijay Mahadevan     moab::DataType tag_type;
56*032b8ab6SVijay Mahadevan     merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr);
57*032b8ab6SVijay Mahadevan     if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE");
58*032b8ab6SVijay Mahadevan     is_newtag = destroy_tag;
59*032b8ab6SVijay Mahadevan   }
60*032b8ab6SVijay Mahadevan 
61*032b8ab6SVijay Mahadevan     // Create the MOAB internal data object
62*032b8ab6SVijay Mahadevan   ierr = PetscNew(Vec_MOAB,&vmoab);CHKERRQ(ierr);
63*032b8ab6SVijay Mahadevan   vmoab->tag = tag;
64*032b8ab6SVijay Mahadevan   vmoab->mbiface = mbiface;
65*032b8ab6SVijay Mahadevan   vmoab->pcomm = pcomm;
66*032b8ab6SVijay Mahadevan   vmoab->new_tag = is_newtag;
67*032b8ab6SVijay Mahadevan   vmoab->is_global_vec = is_global_vec;
68*032b8ab6SVijay Mahadevan   merr = mbiface->tag_get_length(tag,vmoab->tag_size);MBERR("tag_get_size", merr);
69*032b8ab6SVijay Mahadevan 
70*032b8ab6SVijay Mahadevan     // set the reference for vector range
71*032b8ab6SVijay Mahadevan   vmoab->tag_range = new moab::Range(*range);
72*032b8ab6SVijay Mahadevan 
73*032b8ab6SVijay Mahadevan     // Call tag_iterate. This will cause MOAB to allocate memory for the
74*032b8ab6SVijay Mahadevan     // tag data if it hasn't already happened:
75*032b8ab6SVijay Mahadevan   merr = mbiface->tag_iterate(tag,range->begin(),range->end(),count,(void*&)data_ptr);MBERRNM(merr);
76*032b8ab6SVijay Mahadevan 
77*032b8ab6SVijay Mahadevan     // Check to make sure the tag data is in a single sequence:
78*032b8ab6SVijay Mahadevan   if ((unsigned)count != range->size()) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only create MOAB Vector for single sequence");
79*032b8ab6SVijay Mahadevan 
80*032b8ab6SVijay Mahadevan   ierr = MPI_Comm_size(((PetscObject)dm)->comm, &size);CHKERRQ(ierr);
81*032b8ab6SVijay Mahadevan   ierr = MPI_Comm_rank(((PetscObject)dm)->comm, &rank);CHKERRQ(ierr);
82*032b8ab6SVijay Mahadevan 
83*032b8ab6SVijay Mahadevan   // VSM::
84*032b8ab6SVijay Mahadevan   // TODO: Need to query MOAB mesh to see if we have ghosted entities -> then decide accordingly whether
85*032b8ab6SVijay Mahadevan   // to create a serial, parallel or ghosted vector
86*032b8ab6SVijay Mahadevan   // Also assert if the tag_range has the right count accordingly.
87*032b8ab6SVijay Mahadevan     // Create the PETSc Vector:
88*032b8ab6SVijay Mahadevan 
89*032b8ab6SVijay Mahadevan   /* check if we have ghosted entities in the mesh
90*032b8ab6SVijay Mahadevan       -> if we do, create a ghosted vector to map correctly to the same layout
91*032b8ab6SVijay Mahadevan       -> else, create a non-ghosted parallel vector */
92*032b8ab6SVijay Mahadevan   if (!is_global_vec && (size>1) && dmmoab->nghost) {
93*032b8ab6SVijay Mahadevan     moab::Range::iterator  iter;
94*032b8ab6SVijay Mahadevan     ierr = PetscMalloc(dmmoab->nghost*sizeof(PetscInt), &gsindices);CHKERRQ(ierr);
95*032b8ab6SVijay Mahadevan     for(iter = dmmoab->vghost->begin(),icount=0; iter != dmmoab->vghost->end(); iter++) {
96*032b8ab6SVijay Mahadevan       merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
97*032b8ab6SVijay Mahadevan //    PetscPrintf(PETSC_COMM_SELF, "\n [%D] Setting ghost index for dof = %D, at count = [%D, %D] for new entry = %D", rank, dof, count, icount, dof*vmoab->tag_size);
98*032b8ab6SVijay Mahadevan     gsindices[icount++] = dof;
99*032b8ab6SVijay Mahadevan     }
100*032b8ab6SVijay Mahadevan //    ierr = PetscPrintf(PETSC_COMM_WORLD, "\n VecCreateGhostBlockWithArray: Creating Ghost MPI vector with array: Global=%D, Local=%D, Ghosted=%D", dmmoab->n, dmmoab->nloc, dmmoab->nghost);
101*032b8ab6SVijay Mahadevan //    ierr = PetscPrintf(PETSC_COMM_WORLD, "\n VecCreateGhostBlockWithArray: Creating Ghost MPI vector with array: Local=%D, Ghosted=%D", dmmoab->vowned->size(), dmmoab->vghost->size());
102*032b8ab6SVijay Mahadevan 
103*032b8ab6SVijay Mahadevan     // This is an MPI Vector with ghosted padding
104*032b8ab6SVijay Mahadevan     ierr = VecCreateGhostBlockWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*dmmoab->nloc,
105*032b8ab6SVijay Mahadevan                               vmoab->tag_size*dmmoab->n,dmmoab->nghost,gsindices,data_ptr,vec);CHKERRQ(ierr);
106*032b8ab6SVijay Mahadevan 
107*032b8ab6SVijay Mahadevan     ierr = PetscFree(gsindices);CHKERRQ(ierr);
108*032b8ab6SVijay Mahadevan   }
109*032b8ab6SVijay Mahadevan   else if (size>1) {
110*032b8ab6SVijay Mahadevan     // This is an MPI Vector without ghosted padding
111*032b8ab6SVijay Mahadevan //    ierr = PetscPrintf(PETSC_COMM_WORLD, "\n VecCreateMPIWithArray: Creating MPI vector with array");
112*032b8ab6SVijay Mahadevan     ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range->size(),
113*032b8ab6SVijay Mahadevan                               PETSC_DECIDE,data_ptr,vec);CHKERRQ(ierr);
114*032b8ab6SVijay Mahadevan 
115*032b8ab6SVijay Mahadevan           // Vector created, manually set local to global mapping:
116*032b8ab6SVijay Mahadevan //        ierr = PetscMalloc(range->size()*sizeof(PetscInt)*vmoab->tag_size, &gindices);CHKERRQ(ierr);
117*032b8ab6SVijay Mahadevan //        moab::Range::iterator  iter;
118*032b8ab6SVijay Mahadevan //        for(iter = range->begin(),count=0; iter != range->end(); iter++,count+=vmoab->tag_size) {
119*032b8ab6SVijay Mahadevan //          merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
120*032b8ab6SVijay Mahadevan //          for(i=0; i<vmoab->tag_size; ++i)
121*032b8ab6SVijay Mahadevan //            gindices[count+i] = (dof)*vmoab->tag_size+i;
122*032b8ab6SVijay Mahadevan //        }
123*032b8ab6SVijay Mahadevan //
124*032b8ab6SVijay Mahadevan //        ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range->size(),gindices,
125*032b8ab6SVijay Mahadevan //                                            PETSC_COPY_VALUES,&ltog);CHKERRQ(ierr);
126*032b8ab6SVijay Mahadevan //        ierr = VecSetLocalToGlobalMappingBlock(*vec,ltog);CHKERRQ(ierr);
127*032b8ab6SVijay Mahadevan //
128*032b8ab6SVijay Mahadevan //          // Clean up:
129*032b8ab6SVijay Mahadevan //        ierr = ISLocalToGlobalMappingDestroy(&ltog);CHKERRQ(ierr);
130*032b8ab6SVijay Mahadevan //        ierr = PetscFree(gindices);CHKERRQ(ierr);
131*032b8ab6SVijay Mahadevan 
132*032b8ab6SVijay Mahadevan   }
133*032b8ab6SVijay Mahadevan   else {
134*032b8ab6SVijay Mahadevan //    ierr = PetscPrintf(PETSC_COMM_WORLD, "\n VecCreateSeqWithArray: Creating Serial vector with array");
135*032b8ab6SVijay Mahadevan 
136*032b8ab6SVijay Mahadevan     // This is a serial vector - valid only for the single processor case since MOAB tags are always partitioned
137*032b8ab6SVijay Mahadevan     // and we cannot define a Vec using the Tag array with size>1 to be of full length.
138*032b8ab6SVijay Mahadevan     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*dmmoab->n,data_ptr,vec);CHKERRQ(ierr);
139*032b8ab6SVijay Mahadevan   }
140*032b8ab6SVijay Mahadevan 
141*032b8ab6SVijay Mahadevan   PetscContainer moabdata;
142*032b8ab6SVijay Mahadevan   ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr);
143*032b8ab6SVijay Mahadevan   ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr);
144*032b8ab6SVijay Mahadevan   ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr);
145*032b8ab6SVijay Mahadevan   ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr);
146*032b8ab6SVijay Mahadevan   (*vec)->ops->duplicate = DMMoab_VecDuplicate;
147*032b8ab6SVijay Mahadevan   ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr);
148*032b8ab6SVijay Mahadevan 
149*032b8ab6SVijay Mahadevan   if (!dmmoab->ltog_map) {
150*032b8ab6SVijay Mahadevan       // Vector created, manually set local to global mapping:
151*032b8ab6SVijay Mahadevan     ierr = PetscMalloc(range->size()*sizeof(PetscInt)*vmoab->tag_size, &gindices);CHKERRQ(ierr);
152*032b8ab6SVijay Mahadevan     moab::Range::iterator  iter;
153*032b8ab6SVijay Mahadevan     for(iter = range->begin(),count=0; iter != range->end(); iter++,count+=vmoab->tag_size) {
154*032b8ab6SVijay Mahadevan       merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
155*032b8ab6SVijay Mahadevan       for(i=0; i<vmoab->tag_size; ++i)
156*032b8ab6SVijay Mahadevan         gindices[count+i] = (dof)*vmoab->tag_size+i;
157*032b8ab6SVijay Mahadevan     }
158*032b8ab6SVijay Mahadevan 
159*032b8ab6SVijay Mahadevan     ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range->size(),gindices,
160*032b8ab6SVijay Mahadevan                                         PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr);
161*032b8ab6SVijay Mahadevan 
162*032b8ab6SVijay Mahadevan     ierr = VecSetLocalToGlobalMappingBlock(*vec,dmmoab->ltog_map);CHKERRQ(ierr);
163*032b8ab6SVijay Mahadevan 
164*032b8ab6SVijay Mahadevan     // Clean up:
165*032b8ab6SVijay Mahadevan     ierr = PetscFree(gindices);CHKERRQ(ierr);
166*032b8ab6SVijay Mahadevan   }
167*032b8ab6SVijay Mahadevan   else {
168*032b8ab6SVijay Mahadevan     ierr = VecSetLocalToGlobalMappingBlock(*vec,dmmoab->ltog_map);CHKERRQ(ierr);
169*032b8ab6SVijay Mahadevan   }
170*032b8ab6SVijay Mahadevan 
171*032b8ab6SVijay Mahadevan   /* set the DM reference to the vector */
172*032b8ab6SVijay Mahadevan   ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
173*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
174*032b8ab6SVijay Mahadevan }
175*032b8ab6SVijay Mahadevan 
176*032b8ab6SVijay Mahadevan 
177*032b8ab6SVijay Mahadevan #undef __FUNCT__
178*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoabCreateVector"
179*032b8ab6SVijay Mahadevan /*@
180*032b8ab6SVijay Mahadevan   DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities
181*032b8ab6SVijay Mahadevan 
182*032b8ab6SVijay Mahadevan   Collective on MPI_Comm
183*032b8ab6SVijay Mahadevan 
184*032b8ab6SVijay Mahadevan   Input Parameter:
185*032b8ab6SVijay Mahadevan . dm              - The DMMoab object being set
186*032b8ab6SVijay Mahadevan . tag             - If non-zero, block size will be taken from the tag size
187*032b8ab6SVijay Mahadevan . tag_size        - If tag was zero, this parameter specifies the block size; unique tag name will be generated automatically
188*032b8ab6SVijay Mahadevan . range           - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab
189*032b8ab6SVijay Mahadevan . is_global_vec   - If true, this is a local representation of the Vec (including ghosts in parallel), otherwise a truly parallel one
190*032b8ab6SVijay Mahadevan . destroy_tag     - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB
191*032b8ab6SVijay Mahadevan 
192*032b8ab6SVijay Mahadevan   Output Parameter:
193*032b8ab6SVijay Mahadevan . vec             - The created vector
194*032b8ab6SVijay Mahadevan 
195*032b8ab6SVijay Mahadevan   Level: beginner
196*032b8ab6SVijay Mahadevan 
197*032b8ab6SVijay Mahadevan .keywords: DMMoab, create
198*032b8ab6SVijay Mahadevan @*/
199*032b8ab6SVijay Mahadevan PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range* range,PetscBool is_global_vec,PetscBool destroy_tag,Vec *vec)
200*032b8ab6SVijay Mahadevan {
201*032b8ab6SVijay Mahadevan   PetscErrorCode     ierr;
202*032b8ab6SVijay Mahadevan 
203*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
204*032b8ab6SVijay Mahadevan   if(!tag && !tag_size) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Both tag_size and tag cannot be null.");
205*032b8ab6SVijay Mahadevan 
206*032b8ab6SVijay Mahadevan   ierr = DMMoab_CreateVector_Private(dm,tag,tag_size,range,is_global_vec,destroy_tag,vec);CHKERRQ(ierr);
207*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
208*032b8ab6SVijay Mahadevan }
209*032b8ab6SVijay Mahadevan 
210*032b8ab6SVijay Mahadevan 
211*032b8ab6SVijay Mahadevan #undef __FUNCT__
212*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMCreateGlobalVector_Moab"
213*032b8ab6SVijay Mahadevan PetscErrorCode DMCreateGlobalVector_Moab(DM dm,Vec *gvec)
214*032b8ab6SVijay Mahadevan {
215*032b8ab6SVijay Mahadevan   PetscErrorCode  ierr;
216*032b8ab6SVijay Mahadevan   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
217*032b8ab6SVijay Mahadevan 
218*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
219*032b8ab6SVijay Mahadevan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
220*032b8ab6SVijay Mahadevan   PetscValidPointer(gvec,2);
221*032b8ab6SVijay Mahadevan   ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,dmmoab->bs,dmmoab->vowned,PETSC_TRUE,PETSC_TRUE,gvec);CHKERRQ(ierr);
222*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
223*032b8ab6SVijay Mahadevan }
224*032b8ab6SVijay Mahadevan 
225*032b8ab6SVijay Mahadevan 
226*032b8ab6SVijay Mahadevan #undef __FUNCT__
227*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMCreateLocalVector_Moab"
228*032b8ab6SVijay Mahadevan PetscErrorCode DMCreateLocalVector_Moab(DM dm,Vec *lvec)
229*032b8ab6SVijay Mahadevan {
230*032b8ab6SVijay Mahadevan   PetscErrorCode  ierr;
231*032b8ab6SVijay Mahadevan   moab::Range     vlocal;
232*032b8ab6SVijay Mahadevan   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
233*032b8ab6SVijay Mahadevan 
234*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
235*032b8ab6SVijay Mahadevan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
236*032b8ab6SVijay Mahadevan   PetscValidPointer(lvec,2);
237*032b8ab6SVijay Mahadevan   vlocal = *dmmoab->vowned;
238*032b8ab6SVijay Mahadevan   vlocal.merge(*dmmoab->vghost);
239*032b8ab6SVijay Mahadevan   ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,dmmoab->bs,dmmoab->vowned,PETSC_FALSE,PETSC_TRUE,lvec);CHKERRQ(ierr);
240*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
241*032b8ab6SVijay Mahadevan }
242*032b8ab6SVijay Mahadevan 
243*032b8ab6SVijay Mahadevan 
244*032b8ab6SVijay Mahadevan #undef __FUNCT__
245*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoabGetVecTag"
246*032b8ab6SVijay Mahadevan /*@
247*032b8ab6SVijay Mahadevan   DMMoabGetVecTag - Get the MOAB tag associated with this Vec
248*032b8ab6SVijay Mahadevan 
249*032b8ab6SVijay Mahadevan   Collective on MPI_Comm
250*032b8ab6SVijay Mahadevan 
251*032b8ab6SVijay Mahadevan   Input Parameter:
252*032b8ab6SVijay Mahadevan . vec - Vec being queried
253*032b8ab6SVijay Mahadevan 
254*032b8ab6SVijay Mahadevan   Output Parameter:
255*032b8ab6SVijay Mahadevan . tag - Tag associated with this Vec
256*032b8ab6SVijay Mahadevan 
257*032b8ab6SVijay Mahadevan   Level: beginner
258*032b8ab6SVijay Mahadevan 
259*032b8ab6SVijay Mahadevan .keywords: DMMoab, create
260*032b8ab6SVijay Mahadevan @*/
261*032b8ab6SVijay Mahadevan PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag)
262*032b8ab6SVijay Mahadevan {
263*032b8ab6SVijay Mahadevan   PetscContainer  moabdata;
264*032b8ab6SVijay Mahadevan   Vec_MOAB        *vmoab;
265*032b8ab6SVijay Mahadevan   PetscErrorCode  ierr;
266*032b8ab6SVijay Mahadevan 
267*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
268*032b8ab6SVijay Mahadevan   PetscValidPointer(tag,2);
269*032b8ab6SVijay Mahadevan 
270*032b8ab6SVijay Mahadevan   // Get the MOAB private data:
271*032b8ab6SVijay Mahadevan   ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
272*032b8ab6SVijay Mahadevan   ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr);
273*032b8ab6SVijay Mahadevan 
274*032b8ab6SVijay Mahadevan   *tag = vmoab->tag;
275*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
276*032b8ab6SVijay Mahadevan }
277*032b8ab6SVijay Mahadevan 
278*032b8ab6SVijay Mahadevan 
279*032b8ab6SVijay Mahadevan #undef __FUNCT__
280*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoabGetVecRange"
281*032b8ab6SVijay Mahadevan /*@
282*032b8ab6SVijay Mahadevan   DMMoabGetVecRange - Get the MOAB entities associated with this Vec
283*032b8ab6SVijay Mahadevan 
284*032b8ab6SVijay Mahadevan   Collective on MPI_Comm
285*032b8ab6SVijay Mahadevan 
286*032b8ab6SVijay Mahadevan   Input Parameter:
287*032b8ab6SVijay Mahadevan . vec   - Vec being queried
288*032b8ab6SVijay Mahadevan 
289*032b8ab6SVijay Mahadevan   Output Parameter:
290*032b8ab6SVijay Mahadevan . range - Entities associated with this Vec
291*032b8ab6SVijay Mahadevan 
292*032b8ab6SVijay Mahadevan   Level: beginner
293*032b8ab6SVijay Mahadevan 
294*032b8ab6SVijay Mahadevan .keywords: DMMoab, create
295*032b8ab6SVijay Mahadevan @*/
296*032b8ab6SVijay Mahadevan PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range)
297*032b8ab6SVijay Mahadevan {
298*032b8ab6SVijay Mahadevan   PetscContainer  moabdata;
299*032b8ab6SVijay Mahadevan   Vec_MOAB        *vmoab;
300*032b8ab6SVijay Mahadevan   PetscErrorCode  ierr;
301*032b8ab6SVijay Mahadevan 
302*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
303*032b8ab6SVijay Mahadevan   PetscValidPointer(range,2);
304*032b8ab6SVijay Mahadevan 
305*032b8ab6SVijay Mahadevan   // Get the MOAB private data handle
306*032b8ab6SVijay Mahadevan   ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
307*032b8ab6SVijay Mahadevan   ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr);
308*032b8ab6SVijay Mahadevan 
309*032b8ab6SVijay Mahadevan   *range = *vmoab->tag_range;
310*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
311*032b8ab6SVijay Mahadevan }
312*032b8ab6SVijay Mahadevan 
313*032b8ab6SVijay Mahadevan 
314*032b8ab6SVijay Mahadevan #undef __FUNCT__
315*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoab_VecDuplicate"
316*032b8ab6SVijay Mahadevan PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y)
317*032b8ab6SVijay Mahadevan {
318*032b8ab6SVijay Mahadevan   PetscErrorCode ierr;
319*032b8ab6SVijay Mahadevan   DM             dm;
320*032b8ab6SVijay Mahadevan   PetscContainer  moabdata;
321*032b8ab6SVijay Mahadevan   Vec_MOAB        *vmoab;
322*032b8ab6SVijay Mahadevan //  DM_Moab         *dmmoab;
323*032b8ab6SVijay Mahadevan 
324*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
325*032b8ab6SVijay Mahadevan   PetscValidHeaderSpecific(x,VEC_CLASSID,1);
326*032b8ab6SVijay Mahadevan   PetscValidPointer(y,2);
327*032b8ab6SVijay Mahadevan 
328*032b8ab6SVijay Mahadevan   // Get the Vec_MOAB struct for the original vector
329*032b8ab6SVijay Mahadevan   ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
330*032b8ab6SVijay Mahadevan   ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr);
331*032b8ab6SVijay Mahadevan 
332*032b8ab6SVijay Mahadevan   ierr = VecGetDM(x, &dm);CHKERRQ(ierr);
333*032b8ab6SVijay Mahadevan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
334*032b8ab6SVijay Mahadevan //  dmmoab = (DM_Moab*)dm->data;
335*032b8ab6SVijay Mahadevan 
336*032b8ab6SVijay Mahadevan   ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,vmoab->tag_size,vmoab->tag_range,vmoab->is_global_vec,PETSC_TRUE,y);CHKERRQ(ierr);
337*032b8ab6SVijay Mahadevan //  ierr = DMMoabCreateVector(dm,PETSC_NULL,dmmoab->bs,dmmoab->vowned,vmoab->is_global_vec,PETSC_TRUE,y);CHKERRQ(ierr);
338*032b8ab6SVijay Mahadevan 
339*032b8ab6SVijay Mahadevan //  ierr = DMMoabCreateVector(dm,PETSC_NULL,vmoab->tag_size,vmoab->tag_range,vmoab->is_global_vec,PETSC_TRUE,y);CHKERRQ(ierr);
340*032b8ab6SVijay Mahadevan 
341*032b8ab6SVijay Mahadevan   ierr = VecSetDM(*y, dm);CHKERRQ(ierr);
342*032b8ab6SVijay Mahadevan 
343*032b8ab6SVijay Mahadevan //  ierr = PetscObjectQuery((PetscObject)*y,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
344*032b8ab6SVijay Mahadevan //  ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr);
345*032b8ab6SVijay Mahadevan //  PetscPrintf(PETSC_COMM_WORLD, "\n In VecDuplicate: new tag range pointer = %u \n", vmoab->tag_range);
346*032b8ab6SVijay Mahadevan //  vmoab->tag_range->print("test");
347*032b8ab6SVijay Mahadevan 
348*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
349*032b8ab6SVijay Mahadevan }
350*032b8ab6SVijay Mahadevan 
351*032b8ab6SVijay Mahadevan 
352*032b8ab6SVijay Mahadevan #undef __FUNCT__
353*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoab_VecCreateTagName_Private"
354*032b8ab6SVijay Mahadevan /*  DMMoab_VecCreateTagName_Private
355*032b8ab6SVijay Mahadevan  *
356*032b8ab6SVijay Mahadevan  *  Creates a unique tag name that will be shared across processes. If
357*032b8ab6SVijay Mahadevan  *  pcomm is NULL, then this is a serial vector. A unique tag name
358*032b8ab6SVijay Mahadevan  *  will be returned in tag_name in either case.
359*032b8ab6SVijay Mahadevan  *
360*032b8ab6SVijay Mahadevan  *  The tag names have the format _PETSC_VEC_N where N is some integer.
361*032b8ab6SVijay Mahadevan  *
362*032b8ab6SVijay Mahadevan  *  NOTE: The tag_name is allocated in this routine; The user needs to free
363*032b8ab6SVijay Mahadevan  *        the character array.
364*032b8ab6SVijay Mahadevan  */
365*032b8ab6SVijay Mahadevan PetscErrorCode DMMoab_VecCreateTagName_Private(moab::ParallelComm *pcomm,char** tag_name)
366*032b8ab6SVijay Mahadevan {
367*032b8ab6SVijay Mahadevan   moab::ErrorCode mberr;
368*032b8ab6SVijay Mahadevan   PetscErrorCode  ierr;
369*032b8ab6SVijay Mahadevan   PetscInt        n,global_n;
370*032b8ab6SVijay Mahadevan   moab::Tag indexTag;
371*032b8ab6SVijay Mahadevan 
372*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
373*032b8ab6SVijay Mahadevan   const char*       PVEC_PREFIX      = "__PETSC_VEC_";
374*032b8ab6SVijay Mahadevan   ierr = PetscMalloc(PETSC_MAX_PATH_LEN, tag_name);CHKERRQ(ierr);
375*032b8ab6SVijay Mahadevan 
376*032b8ab6SVijay Mahadevan   // Check to see if there are any PETSc vectors defined:
377*032b8ab6SVijay Mahadevan   moab::Interface  *mbiface = pcomm->get_moab();
378*032b8ab6SVijay Mahadevan   moab::EntityHandle rootset = mbiface->get_root_set();
379*032b8ab6SVijay Mahadevan 
380*032b8ab6SVijay Mahadevan     // Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags
381*032b8ab6SVijay Mahadevan   mberr = mbiface->tag_get_handle("__PETSC_VECS__",1,moab::MB_TYPE_INTEGER,indexTag,
382*032b8ab6SVijay Mahadevan                                   moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT,0);MBERRNM(mberr);
383*032b8ab6SVijay Mahadevan   mberr = mbiface->tag_get_data(indexTag, &rootset, 1, &n);
384*032b8ab6SVijay Mahadevan   if (mberr == moab::MB_TAG_NOT_FOUND) n=0;  /* this is the first temporary vector */
385*032b8ab6SVijay Mahadevan   else MBERRNM(mberr);
386*032b8ab6SVijay Mahadevan 
387*032b8ab6SVijay Mahadevan   /* increment the new value of n */
388*032b8ab6SVijay Mahadevan   ++n;
389*032b8ab6SVijay Mahadevan 
390*032b8ab6SVijay Mahadevan   // Make sure that n is consistent across all processes:
391*032b8ab6SVijay Mahadevan   ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,pcomm->comm());CHKERRQ(ierr);
392*032b8ab6SVijay Mahadevan 
393*032b8ab6SVijay Mahadevan   // Set the new name accordingly and return:
394*032b8ab6SVijay Mahadevan   ierr = PetscSNPrintf(*tag_name, PETSC_MAX_PATH_LEN-1, "%s_%D", PVEC_PREFIX, global_n);CHKERRQ(ierr);
395*032b8ab6SVijay Mahadevan   mberr = mbiface->tag_set_data(indexTag, &rootset, 1, (const void*)&global_n);MBERRNM(mberr);
396*032b8ab6SVijay Mahadevan //  ierr = PetscSNPrintf(*tag_name, PETSC_MAX_PATH_LEN-1, "%s_%D", PVEC_PREFIX, n);CHKERRQ(ierr);
397*032b8ab6SVijay Mahadevan //  mberr = mbiface->tag_set_data(indexTag, &rootset, 1, &n);MBERRNM(mberr);
398*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
399*032b8ab6SVijay Mahadevan }
400*032b8ab6SVijay Mahadevan 
401*032b8ab6SVijay Mahadevan 
402*032b8ab6SVijay Mahadevan #undef __FUNCT__
403*032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoab_VecUserDestroy"
404*032b8ab6SVijay Mahadevan PetscErrorCode DMMoab_VecUserDestroy(void *user)
405*032b8ab6SVijay Mahadevan {
406*032b8ab6SVijay Mahadevan   Vec_MOAB        *vmoab;
407*032b8ab6SVijay Mahadevan   PetscErrorCode  ierr;
408*032b8ab6SVijay Mahadevan   moab::ErrorCode merr;
409*032b8ab6SVijay Mahadevan 
410*032b8ab6SVijay Mahadevan   PetscFunctionBegin;
411*032b8ab6SVijay Mahadevan   vmoab = (Vec_MOAB*)user;
412*032b8ab6SVijay Mahadevan 
413*032b8ab6SVijay Mahadevan   if(vmoab->new_tag && vmoab->tag) {
414*032b8ab6SVijay Mahadevan     // Tag created via a call to VecDuplicate, delete the underlying tag in MOAB...
415*032b8ab6SVijay Mahadevan     merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr);
416*032b8ab6SVijay Mahadevan   }
417*032b8ab6SVijay Mahadevan   delete vmoab->tag_range;
418*032b8ab6SVijay Mahadevan   vmoab->tag = PETSC_NULL;
419*032b8ab6SVijay Mahadevan   vmoab->mbiface = PETSC_NULL;
420*032b8ab6SVijay Mahadevan   vmoab->pcomm = PETSC_NULL;
421*032b8ab6SVijay Mahadevan   ierr = PetscFree(vmoab);CHKERRQ(ierr);
422*032b8ab6SVijay Mahadevan   PetscFunctionReturn(0);
423*032b8ab6SVijay Mahadevan }
424*032b8ab6SVijay Mahadevan 
425