xref: /petsc/src/dm/impls/moab/dmmoab.cxx (revision a4d2169cc6146dd131be8bed37042f39c361a88f)
11d72bce8STim Tautges #include <petsc-private/dmimpl.h> /*I  "petscdm.h"   I*/
21d72bce8STim Tautges 
31d72bce8STim Tautges #include <petscdmmoab.h>
41d72bce8STim Tautges #include "MBTagConventions.hpp"
51d72bce8STim Tautges 
61d72bce8STim Tautges typedef struct {
71d72bce8STim Tautges   PetscInt bs; /* Number of degrees of freedom on each entity, aka tag size in moab */
81d72bce8STim Tautges   PetscBool icreatedinstance; /* true if DM created moab instance internally, will destroy instance in DMDestroy */
91d72bce8STim Tautges   moab::ParallelComm *pcomm;
10*a4d2169cSTim Tautges   moab::Interface *mbiface;
111d72bce8STim Tautges   moab::Tag ltog_tag; /* moab supports "global id" tags, which are usually local to global numbering */
121d72bce8STim Tautges   moab::Range range;
131d72bce8STim Tautges } DM_Moab;
141d72bce8STim Tautges 
15*a4d2169cSTim Tautges typedef struct {
16*a4d2169cSTim Tautges   moab::Interface    *mbiface;
17*a4d2169cSTim Tautges   moab::ParallelComm *pcomm;
18*a4d2169cSTim Tautges   moab::Range         tag_range; /* entities to which this tag applies */
19*a4d2169cSTim Tautges   moab::Tag           tag;
20*a4d2169cSTim Tautges   moab::Tag           ltog_tag;
21*a4d2169cSTim Tautges   PetscInt            tag_size;
22*a4d2169cSTim Tautges   PetscBool           new_tag;
23*a4d2169cSTim Tautges   PetscBool           serial;
24*a4d2169cSTim Tautges 
25*a4d2169cSTim Tautges } Vec_MOAB;
26*a4d2169cSTim Tautges 
271d72bce8STim Tautges #undef __FUNCT__
28fd349b41STim Tautges #define __FUNCT__ "DMCreateGlobalVector_Moab"
29fd349b41STim Tautges PetscErrorCode DMCreateGlobalVector_Moab(DM dm,Vec *gvec)
30fd349b41STim Tautges {
31fd349b41STim Tautges   PetscErrorCode  ierr;
32fd349b41STim Tautges   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
33fd349b41STim Tautges 
34fd349b41STim Tautges   PetscFunctionBegin;
35fd349b41STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
36fd349b41STim Tautges   PetscValidPointer(gvec,2);
37fd349b41STim Tautges   PetscInt block_size = ((DM_Moab*)dm->data)->bs;
38*a4d2169cSTim Tautges   moab::Tag tag = 0;
39*a4d2169cSTim Tautges   ierr = DMMoabCreateVector(dm,tag,block_size,dmmoab->range,PETSC_FALSE,PETSC_TRUE,gvec);CHKERRQ(ierr);
40fd349b41STim Tautges   PetscFunctionReturn(0);
41fd349b41STim Tautges }
42fd349b41STim Tautges 
43fd349b41STim Tautges 
44fd349b41STim Tautges #undef __FUNCT__
45fd349b41STim Tautges #define __FUNCT__ "DMCreateLocalVector_Moab"
46fd349b41STim Tautges PetscErrorCode DMCreateLocalVector_Moab(DM dm,Vec *gvec)
47fd349b41STim Tautges {
48fd349b41STim Tautges   PetscErrorCode  ierr;
49fd349b41STim Tautges   DM_Moab         *dmmoab = (DM_Moab*)dm->data;
50fd349b41STim Tautges 
51fd349b41STim Tautges   PetscFunctionBegin;
52fd349b41STim Tautges   PetscInt bs = 1;
53fd349b41STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
54fd349b41STim Tautges   PetscValidPointer(gvec,2);
55*a4d2169cSTim Tautges   moab::Tag tag = 0;
56*a4d2169cSTim Tautges   ierr = DMMoabCreateVector(dm,tag,bs,dmmoab->range,PETSC_TRUE,PETSC_TRUE,gvec);CHKERRQ(ierr);
57fd349b41STim Tautges   PetscFunctionReturn(0);
58fd349b41STim Tautges }
59fd349b41STim Tautges 
60fd349b41STim Tautges #undef __FUNCT__
61fd349b41STim Tautges #define __FUNCT__ "DMDestroy_Moab"
62fd349b41STim Tautges PetscErrorCode DMDestroy_Moab(DM dm)
63fd349b41STim Tautges {
64fd349b41STim Tautges   PetscFunctionBegin;
65fd349b41STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
66fd349b41STim Tautges 
67fd349b41STim Tautges   // Delete the DM_Moab:
68fd349b41STim Tautges   if(dm->data) {
69fd349b41STim Tautges     if (((DM_Moab*)dm->data)->icreatedinstance) {
70*a4d2169cSTim Tautges       delete ((DM_Moab*)dm->data)->mbiface;
71*a4d2169cSTim Tautges       ((DM_Moab*)dm->data)->mbiface = NULL;
72fd349b41STim Tautges       ((DM_Moab*)dm->data)->pcomm = NULL;
73fd349b41STim Tautges     }
74fd349b41STim Tautges     delete (DM_Moab*)dm->data;
75fd349b41STim Tautges     dm->data = NULL;
76fd349b41STim Tautges   }
77fd349b41STim Tautges   PetscFunctionReturn(0);
78fd349b41STim Tautges }
79fd349b41STim Tautges 
80fd349b41STim Tautges 
81fd349b41STim Tautges #undef __FUNCT__
821d72bce8STim Tautges #define __FUNCT__ "DMMoabCreate"
831d72bce8STim Tautges /*@
841d72bce8STim Tautges   DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance
851d72bce8STim Tautges 
861d72bce8STim Tautges   Collective on MPI_Comm
871d72bce8STim Tautges 
881d72bce8STim Tautges   Input Parameter:
891d72bce8STim Tautges . comm - The communicator for the DMMoab object
901d72bce8STim Tautges 
911d72bce8STim Tautges   Output Parameter:
921d72bce8STim Tautges . moab  - The DMMoab object
931d72bce8STim Tautges 
941d72bce8STim Tautges   Level: beginner
951d72bce8STim Tautges 
961d72bce8STim Tautges .keywords: DMMoab, create
971d72bce8STim Tautges @*/
981d72bce8STim Tautges PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *moab)
991d72bce8STim Tautges {
1001d72bce8STim Tautges   PetscErrorCode ierr;
1011d72bce8STim Tautges 
1021d72bce8STim Tautges   PetscFunctionBegin;
1031d72bce8STim Tautges   PetscValidPointer(moab,2);
1041d72bce8STim Tautges   ierr = DMCreate(comm, moab);CHKERRQ(ierr);
1051d72bce8STim Tautges   ierr = DMSetType(*moab, DMMOAB);CHKERRQ(ierr);
1061d72bce8STim Tautges   PetscFunctionReturn(0);
1071d72bce8STim Tautges }
1081d72bce8STim Tautges 
1091d72bce8STim Tautges EXTERN_C_BEGIN
1101d72bce8STim Tautges #undef __FUNCT__
1111d72bce8STim Tautges #define __FUNCT__ "DMCreate_Moab"
1121d72bce8STim Tautges PetscErrorCode DMCreate_Moab(DM dm)
1131d72bce8STim Tautges {
1141d72bce8STim Tautges   DM_Moab        *moab;
1151d72bce8STim Tautges   PetscErrorCode ierr;
1161d72bce8STim Tautges 
1171d72bce8STim Tautges   PetscFunctionBegin;
1181d72bce8STim Tautges   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1191d72bce8STim Tautges   ierr     = PetscNewLog(dm, DM_Moab, &moab);CHKERRQ(ierr);
1201d72bce8STim Tautges   dm->data = moab;
1211d72bce8STim Tautges 
1221d72bce8STim Tautges   PetscFunctionReturn(0);
1231d72bce8STim Tautges }
1241d72bce8STim Tautges EXTERN_C_END
1251d72bce8STim Tautges 
1261d72bce8STim Tautges /*@
127*a4d2169cSTim Tautges   DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data
1281d72bce8STim Tautges 
1291d72bce8STim Tautges   Collective on MPI_Comm
1301d72bce8STim Tautges 
1311d72bce8STim Tautges   Input Parameter:
1321d72bce8STim Tautges . comm - The communicator for the DMMoab object
133*a4d2169cSTim Tautges . moab - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed
134*a4d2169cSTim Tautges          along with the DMMoab
135*a4d2169cSTim Tautges . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator
1361d72bce8STim Tautges . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag
1371d72bce8STim Tautges . range - If non-NULL, contains range of entities to which DOFs will be assigned
1381d72bce8STim Tautges 
1391d72bce8STim Tautges   Output Parameter:
1401d72bce8STim Tautges . moab  - The DMMoab object
1411d72bce8STim Tautges 
1421d72bce8STim Tautges   Level: beginner
1431d72bce8STim Tautges 
1441d72bce8STim Tautges .keywords: DMMoab, create
1451d72bce8STim Tautges @*/
1461d72bce8STim Tautges #undef __FUNCT__
147*a4d2169cSTim Tautges #define __FUNCT__ "DMMoabCreateMoab"
148*a4d2169cSTim Tautges PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag ltog_tag, moab::Range *range, DM *moab)
1491d72bce8STim Tautges {
1501d72bce8STim Tautges   PetscErrorCode ierr;
1511d72bce8STim Tautges 
1521d72bce8STim Tautges   PetscFunctionBegin;
1531d72bce8STim Tautges   PetscValidPointer(moab,2);
1541d72bce8STim Tautges   ierr = DMCreate(comm, moab);CHKERRQ(ierr);
1551d72bce8STim Tautges   ierr = DMSetType(*moab, DMMOAB);CHKERRQ(ierr);
156*a4d2169cSTim Tautges 
157*a4d2169cSTim Tautges   if (!mbiface) {
158*a4d2169cSTim Tautges     mbiface = new moab::Core();
159*a4d2169cSTim Tautges     ((DM_Moab*)(*moab)->data)->icreatedinstance = PETSC_TRUE;
1601d72bce8STim Tautges   }
161*a4d2169cSTim Tautges   if (!pcomm) {
1621d72bce8STim Tautges     PetscInt rank, nprocs;
1631d72bce8STim Tautges     MPI_Comm_rank(comm, &rank);
1641d72bce8STim Tautges     MPI_Comm_size(comm, &nprocs);
165*a4d2169cSTim Tautges     pcomm = new moab::ParallelComm(mbiface, comm);
166*a4d2169cSTim Tautges   }
167*a4d2169cSTim Tautges 
168*a4d2169cSTim Tautges     // do the initialization of the DM
169*a4d2169cSTim Tautges   DM_Moab *dmmoab = new DM_Moab;
170*a4d2169cSTim Tautges   (*moab)->data      = dmmoab;
171*a4d2169cSTim Tautges   dmmoab->bs       = 0;
172*a4d2169cSTim Tautges   dmmoab->pcomm    = pcomm;
173*a4d2169cSTim Tautges   dmmoab->mbiface    = mbiface;
174*a4d2169cSTim Tautges   dmmoab->ltog_tag = ltog_tag;
175*a4d2169cSTim Tautges 
176*a4d2169cSTim Tautges     // initialize various functions
177*a4d2169cSTim Tautges   (*moab)->ops->createglobalvector              = DMCreateGlobalVector_Moab;
178*a4d2169cSTim Tautges   (*moab)->ops->createlocalvector               = DMCreateLocalVector_Moab;
179*a4d2169cSTim Tautges   (*moab)->ops->destroy                         = DMDestroy_Moab;
180*a4d2169cSTim Tautges 
181*a4d2169cSTim Tautges   ierr = DMMoabSetInterface(*moab, mbiface);CHKERRQ(ierr);
182*a4d2169cSTim Tautges   if (!pcomm) pcomm = new moab::ParallelComm(mbiface, comm);
183*a4d2169cSTim Tautges   ierr = DMMoabSetParallelComm(*moab, pcomm);CHKERRQ(ierr);
184*a4d2169cSTim Tautges   if (!ltog_tag) {
185*a4d2169cSTim Tautges     moab::ErrorCode merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, ltog_tag);MBERRNM(merr);
186*a4d2169cSTim Tautges   }
187*a4d2169cSTim Tautges   if (ltog_tag) {
188*a4d2169cSTim Tautges     ierr = DMMoabSetLocalToGlobalTag(*moab, ltog_tag);CHKERRQ(ierr);
189*a4d2169cSTim Tautges   }
190*a4d2169cSTim Tautges   if (range) {
191*a4d2169cSTim Tautges     ierr = DMMoabSetRange(*moab, *range);CHKERRQ(ierr);
192*a4d2169cSTim Tautges   }
1931d72bce8STim Tautges   PetscFunctionReturn(0);
1941d72bce8STim Tautges }
1951d72bce8STim Tautges 
1961d72bce8STim Tautges #undef __FUNCT__
1971d72bce8STim Tautges #define __FUNCT__ "DMMoabSetParallelComm"
1981d72bce8STim Tautges PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm)
1991d72bce8STim Tautges {
2001d72bce8STim Tautges   PetscFunctionBegin;
2011d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2021d72bce8STim Tautges   ((DM_Moab*)dm->data)->pcomm = pcomm;
203*a4d2169cSTim Tautges   ((DM_Moab*)dm->data)->mbiface = pcomm->get_moab();
2041d72bce8STim Tautges   PetscFunctionReturn(0);
2051d72bce8STim Tautges }
2061d72bce8STim Tautges 
2071d72bce8STim Tautges 
2081d72bce8STim Tautges #undef __FUNCT__
2091d72bce8STim Tautges #define __FUNCT__ "DMMoabGetParallelComm"
2101d72bce8STim Tautges PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm)
2111d72bce8STim Tautges {
2121d72bce8STim Tautges   PetscFunctionBegin;
2131d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2141d72bce8STim Tautges   *pcomm = ((DM_Moab*)dm->data)->pcomm;
2151d72bce8STim Tautges   PetscFunctionReturn(0);
2161d72bce8STim Tautges }
2171d72bce8STim Tautges 
2181d72bce8STim Tautges 
2191d72bce8STim Tautges #undef __FUNCT__
2201d72bce8STim Tautges #define __FUNCT__ "DMMoabSetInterface"
221*a4d2169cSTim Tautges PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface)
2221d72bce8STim Tautges {
2231d72bce8STim Tautges   PetscFunctionBegin;
2241d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2251d72bce8STim Tautges   ((DM_Moab*)dm->data)->pcomm = NULL;
226*a4d2169cSTim Tautges   ((DM_Moab*)dm->data)->mbiface = mbiface;
2271d72bce8STim Tautges   PetscFunctionReturn(0);
2281d72bce8STim Tautges }
2291d72bce8STim Tautges 
2301d72bce8STim Tautges 
2311d72bce8STim Tautges #undef __FUNCT__
2321d72bce8STim Tautges #define __FUNCT__ "DMMoabGetInterface"
233*a4d2169cSTim Tautges PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface)
2341d72bce8STim Tautges {
2351d72bce8STim Tautges   PetscFunctionBegin;
2361d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
237*a4d2169cSTim Tautges   *mbiface = ((DM_Moab*)dm->data)->mbiface;
2381d72bce8STim Tautges   PetscFunctionReturn(0);
2391d72bce8STim Tautges }
2401d72bce8STim Tautges 
2411d72bce8STim Tautges 
2421d72bce8STim Tautges #undef __FUNCT__
2431d72bce8STim Tautges #define __FUNCT__ "DMMoabSetRange"
2441d72bce8STim Tautges PetscErrorCode DMMoabSetRange(DM dm,moab::Range range)
2451d72bce8STim Tautges {
2461d72bce8STim Tautges   PetscFunctionBegin;
2471d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2481d72bce8STim Tautges   ((DM_Moab*)dm->data)->range = range;
2491d72bce8STim Tautges   PetscFunctionReturn(0);
2501d72bce8STim Tautges }
2511d72bce8STim Tautges 
2521d72bce8STim Tautges 
2531d72bce8STim Tautges #undef __FUNCT__
2541d72bce8STim Tautges #define __FUNCT__ "DMMoabGetRange"
2551d72bce8STim Tautges PetscErrorCode DMMoabGetRange(DM dm,moab::Range *range)
2561d72bce8STim Tautges {
2571d72bce8STim Tautges   PetscFunctionBegin;
2581d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2591d72bce8STim Tautges   *range = ((DM_Moab*)dm->data)->range;
2601d72bce8STim Tautges   PetscFunctionReturn(0);
2611d72bce8STim Tautges }
2621d72bce8STim Tautges 
2631d72bce8STim Tautges #undef __FUNCT__
2641d72bce8STim Tautges #define __FUNCT__ "DMMoabSetLocalToGlobalTag"
2651d72bce8STim Tautges PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag)
2661d72bce8STim Tautges {
2671d72bce8STim Tautges   PetscFunctionBegin;
2681d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2691d72bce8STim Tautges   ((DM_Moab*)dm->data)->ltog_tag = ltogtag;
2701d72bce8STim Tautges   PetscFunctionReturn(0);
2711d72bce8STim Tautges }
2721d72bce8STim Tautges 
2731d72bce8STim Tautges 
2741d72bce8STim Tautges #undef __FUNCT__
2751d72bce8STim Tautges #define __FUNCT__ "DMMoabGetLocalToGlobalTag"
2761d72bce8STim Tautges PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag)
2771d72bce8STim Tautges {
2781d72bce8STim Tautges   PetscFunctionBegin;
2791d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2801d72bce8STim Tautges   *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag;
2811d72bce8STim Tautges   PetscFunctionReturn(0);
2821d72bce8STim Tautges }
2831d72bce8STim Tautges 
2841d72bce8STim Tautges 
2851d72bce8STim Tautges #undef __FUNCT__
2861d72bce8STim Tautges #define __FUNCT__ "DMMoabSetBlockSize"
2871d72bce8STim Tautges PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs)
2881d72bce8STim Tautges {
2891d72bce8STim Tautges   PetscFunctionBegin;
2901d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2911d72bce8STim Tautges   ((DM_Moab*)dm->data)->bs = bs;
2921d72bce8STim Tautges   PetscFunctionReturn(0);
2931d72bce8STim Tautges }
2941d72bce8STim Tautges 
2951d72bce8STim Tautges 
2961d72bce8STim Tautges #undef __FUNCT__
2971d72bce8STim Tautges #define __FUNCT__ "DMMoabGetBlockSize"
2981d72bce8STim Tautges PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs)
2991d72bce8STim Tautges {
3001d72bce8STim Tautges   PetscFunctionBegin;
3011d72bce8STim Tautges   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3021d72bce8STim Tautges   *bs = ((DM_Moab*)dm->data)->bs;
3031d72bce8STim Tautges   PetscFunctionReturn(0);
3041d72bce8STim Tautges }
3051d72bce8STim Tautges 
3061d72bce8STim Tautges 
307*a4d2169cSTim Tautges // declare for use later but before they're defined
308*a4d2169cSTim Tautges PetscErrorCode DMMoab_VecUserDestroy(void *user);
309*a4d2169cSTim Tautges PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y);
310*a4d2169cSTim Tautges PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name);
311*a4d2169cSTim 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);
3121d72bce8STim Tautges 
3131d72bce8STim Tautges #undef __FUNCT__
3141d72bce8STim Tautges #define __FUNCT__ "DMMoabCreateVector"
315*a4d2169cSTim Tautges PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec)
3161d72bce8STim Tautges {
3171d72bce8STim Tautges   PetscErrorCode     ierr;
318*a4d2169cSTim Tautges 
3191d72bce8STim Tautges   PetscFunctionBegin;
320*a4d2169cSTim Tautges 
3211d72bce8STim Tautges   DM_Moab *dmmoab = (DM_Moab*)dm->data;
322*a4d2169cSTim Tautges   moab::ParallelComm *pcomm = dmmoab->pcomm;
323*a4d2169cSTim Tautges   moab::Interface *mbiface = dmmoab->mbiface;
324*a4d2169cSTim Tautges   moab::Tag ltog_tag = dmmoab->ltog_tag;
325*a4d2169cSTim Tautges 
326*a4d2169cSTim Tautges   if (!tag && !tag_size) {
327*a4d2169cSTim Tautges     PetscFunctionReturn(PETSC_ERR_ARG_WRONG);
328*a4d2169cSTim Tautges   }
329*a4d2169cSTim Tautges   else if (!tag && tag_size) {
330*a4d2169cSTim Tautges     ierr = DMMoab_CreateVector(mbiface,pcomm,tag,tag_size,ltog_tag,range,serial,destroy_tag,vec);CHKERRQ(ierr);
331*a4d2169cSTim Tautges   }
3321d72bce8STim Tautges   PetscFunctionReturn(0);
3331d72bce8STim Tautges }
3341d72bce8STim Tautges 
3351d72bce8STim Tautges 
3361d72bce8STim Tautges #undef __FUNCT__
337*a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_CreateVector"
338*a4d2169cSTim 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)
339*a4d2169cSTim Tautges {
340*a4d2169cSTim Tautges   PetscErrorCode     ierr;
341*a4d2169cSTim Tautges   moab::ErrorCode    merr;
342*a4d2169cSTim Tautges 
343*a4d2169cSTim Tautges   PetscFunctionBegin;
344*a4d2169cSTim Tautges 
345*a4d2169cSTim Tautges   if (!tag) {
346*a4d2169cSTim Tautges     std::string tag_name;
347*a4d2169cSTim Tautges     ierr = DMMoab_CreateTagName(pcomm,tag_name);CHKERRQ(ierr);
348*a4d2169cSTim Tautges 
349*a4d2169cSTim Tautges       // Create the default value for the tag (all zeros):
350*a4d2169cSTim Tautges     std::vector<PetscScalar> default_value(tag_size, 0.0);
351*a4d2169cSTim Tautges 
352*a4d2169cSTim Tautges       // Create the tag:
353*a4d2169cSTim Tautges     merr = mbiface->tag_get_handle(tag_name.c_str(),tag_size,moab::MB_TYPE_DOUBLE,tag,
354*a4d2169cSTim Tautges                                    moab::MB_TAG_DENSE | moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr);
355*a4d2169cSTim Tautges   }
356*a4d2169cSTim Tautges   else {
357*a4d2169cSTim Tautges 
358*a4d2169cSTim Tautges       // Make sure the tag data is of type "double":
359*a4d2169cSTim Tautges     moab::DataType tag_type;
360*a4d2169cSTim Tautges     merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr);
361*a4d2169cSTim Tautges     if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE");
362*a4d2169cSTim Tautges   }
363*a4d2169cSTim Tautges 
364*a4d2169cSTim Tautges     // Create the MOAB internal data object
365*a4d2169cSTim Tautges   Vec_MOAB *vmoab;
366*a4d2169cSTim Tautges   ierr = PetscMalloc(sizeof(Vec_MOAB),&vmoab);CHKERRQ(ierr);
367*a4d2169cSTim Tautges   new (vmoab) Vec_MOAB();
368*a4d2169cSTim Tautges   vmoab->tag = tag;
369*a4d2169cSTim Tautges   vmoab->ltog_tag = ltog_tag;
370*a4d2169cSTim Tautges   vmoab->mbiface = mbiface;
371*a4d2169cSTim Tautges   vmoab->pcomm = pcomm;
372*a4d2169cSTim Tautges   vmoab->tag_range = range;
373*a4d2169cSTim Tautges   vmoab->new_tag = destroy_tag;
374*a4d2169cSTim Tautges   vmoab->serial = serial;
375*a4d2169cSTim Tautges   merr = mbiface->tag_get_length(tag,vmoab->tag_size);MBERR("tag_get_size", merr);
376*a4d2169cSTim Tautges 
377*a4d2169cSTim Tautges     // Call tag_iterate. This will cause MOAB to allocate memory for the
378*a4d2169cSTim Tautges     // tag data if it hasn't already happened:
379*a4d2169cSTim Tautges   int  count;
380*a4d2169cSTim Tautges   void *void_ptr;
381*a4d2169cSTim Tautges   merr = mbiface->tag_iterate(tag,range.begin(),range.end(),count,void_ptr);MBERRNM(merr);
382*a4d2169cSTim Tautges 
383*a4d2169cSTim Tautges     // Check to make sure the tag data is in a single sequence:
384*a4d2169cSTim Tautges   if ((unsigned)count != range.size()) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only create MOAB Vector for single sequence");
385*a4d2169cSTim Tautges   PetscScalar *data_ptr = (PetscScalar*)void_ptr;
386*a4d2169cSTim Tautges 
387*a4d2169cSTim Tautges     // Create the PETSc Vector:
388*a4d2169cSTim Tautges   if(!serial) {
389*a4d2169cSTim Tautges       // This is an MPI Vector:
390*a4d2169cSTim Tautges     ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range.size(),
391*a4d2169cSTim Tautges                                  PETSC_DECIDE,data_ptr,vec);CHKERRXX(ierr);
392*a4d2169cSTim Tautges 
393*a4d2169cSTim Tautges       // Vector created, manually set local to global mapping:
394*a4d2169cSTim Tautges     ISLocalToGlobalMapping ltog;
395*a4d2169cSTim Tautges     PetscInt               *gindices = new PetscInt[range.size()];
396*a4d2169cSTim Tautges     PetscInt               count = 0;
397*a4d2169cSTim Tautges     moab::Range::iterator  iter;
398*a4d2169cSTim Tautges     for(iter = range.begin(); iter != range.end(); iter++) {
399*a4d2169cSTim Tautges       int dof;
400*a4d2169cSTim Tautges       merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr);
401*a4d2169cSTim Tautges       gindices[count] = dof;
402*a4d2169cSTim Tautges       count++;
403*a4d2169cSTim Tautges     }
404*a4d2169cSTim Tautges 
405*a4d2169cSTim Tautges     ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range.size(),gindices,
406*a4d2169cSTim Tautges                                         PETSC_COPY_VALUES,&ltog);CHKERRQ(ierr);
407*a4d2169cSTim Tautges     ierr = VecSetLocalToGlobalMappingBlock(*vec,ltog);CHKERRQ(ierr);
408*a4d2169cSTim Tautges 
409*a4d2169cSTim Tautges       // Clean up:
410*a4d2169cSTim Tautges     ierr = ISLocalToGlobalMappingDestroy(&ltog);CHKERRQ(ierr);
411*a4d2169cSTim Tautges     delete [] gindices;
412*a4d2169cSTim Tautges   } else {
413*a4d2169cSTim Tautges       // This is a serial vector:
414*a4d2169cSTim Tautges     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*range.size(),data_ptr,vec);CHKERRXX(ierr);
415*a4d2169cSTim Tautges   }
416*a4d2169cSTim Tautges 
417*a4d2169cSTim Tautges 
418*a4d2169cSTim Tautges   PetscContainer moabdata;
419*a4d2169cSTim Tautges   ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr);
420*a4d2169cSTim Tautges   ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr);
421*a4d2169cSTim Tautges   ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr);
422*a4d2169cSTim Tautges   ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr);
423*a4d2169cSTim Tautges   (*vec)->ops->duplicate = DMMoab_VecDuplicate;
424*a4d2169cSTim Tautges 
425*a4d2169cSTim Tautges   ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr);
426*a4d2169cSTim Tautges   PetscFunctionReturn(0);
427*a4d2169cSTim Tautges }
428*a4d2169cSTim Tautges 
429*a4d2169cSTim Tautges #undef __FUNCT__
4301d72bce8STim Tautges #define __FUNCT__ "DMMoabGetVecTag"
4311d72bce8STim Tautges PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag)
4321d72bce8STim Tautges {
433*a4d2169cSTim Tautges   PetscContainer  moabdata;
434*a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
4351d72bce8STim Tautges   PetscErrorCode  ierr;
436*a4d2169cSTim Tautges 
4371d72bce8STim Tautges   PetscFunctionBegin;
438*a4d2169cSTim Tautges 
439*a4d2169cSTim Tautges   // Get the MOAB private data:
440*a4d2169cSTim Tautges   ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
441*a4d2169cSTim Tautges   ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr);
442*a4d2169cSTim Tautges 
443*a4d2169cSTim Tautges   *tag = vmoab->tag;
444*a4d2169cSTim Tautges 
4451d72bce8STim Tautges   PetscFunctionReturn(0);
4461d72bce8STim Tautges }
4471d72bce8STim Tautges 
4481d72bce8STim Tautges 
4491d72bce8STim Tautges #undef __FUNCT__
4501d72bce8STim Tautges #define __FUNCT__ "DMMoabGetVecRange"
4511d72bce8STim Tautges PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range)
4521d72bce8STim Tautges {
453*a4d2169cSTim Tautges   PetscContainer  moabdata;
454*a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
4551d72bce8STim Tautges   PetscErrorCode  ierr;
456*a4d2169cSTim Tautges 
4571d72bce8STim Tautges   PetscFunctionBegin;
458*a4d2169cSTim Tautges 
459*a4d2169cSTim Tautges   // Get the MOAB private data:
460*a4d2169cSTim Tautges   ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
461*a4d2169cSTim Tautges   ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr);
462*a4d2169cSTim Tautges 
463*a4d2169cSTim Tautges   *range = vmoab->tag_range;
464*a4d2169cSTim Tautges 
4651d72bce8STim Tautges   PetscFunctionReturn(0);
4661d72bce8STim Tautges }
4671d72bce8STim Tautges 
4681d72bce8STim Tautges 
469*a4d2169cSTim Tautges #undef __FUNCT__
470*a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_VecDuplicate"
471*a4d2169cSTim Tautges PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y)
472*a4d2169cSTim Tautges {
473*a4d2169cSTim Tautges   PetscErrorCode ierr;
474*a4d2169cSTim Tautges   PetscFunctionBegin;
475*a4d2169cSTim Tautges   PetscValidHeaderSpecific(x,VEC_CLASSID,1);
476*a4d2169cSTim Tautges   PetscValidPointer(y,2);
477*a4d2169cSTim Tautges 
478*a4d2169cSTim Tautges   // Get the Vec_MOAB struct for the original vector:
479*a4d2169cSTim Tautges   PetscContainer  moabdata;
480*a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
481*a4d2169cSTim Tautges   ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr);
482*a4d2169cSTim Tautges   ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr);
483*a4d2169cSTim Tautges 
484*a4d2169cSTim 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);
485*a4d2169cSTim Tautges   PetscFunctionReturn(0);
486*a4d2169cSTim Tautges }
487*a4d2169cSTim Tautges 
488*a4d2169cSTim Tautges 
489*a4d2169cSTim Tautges #undef __FUNCT__
490*a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_CreateTagName"
491*a4d2169cSTim Tautges /*  DMMoab_CreateTagName
492*a4d2169cSTim Tautges  *
493*a4d2169cSTim Tautges  *  Creates a unique tag name that will be shared across processes. If
494*a4d2169cSTim Tautges  *  pcomm is NULL, then this is a serial vector. A unique tag name
495*a4d2169cSTim Tautges  *  will be returned in tag_name in either case.
496*a4d2169cSTim Tautges  *
497*a4d2169cSTim Tautges  *  The tag names have the format _PETSC_VEC_N where N is some integer.
498*a4d2169cSTim Tautges  */
499*a4d2169cSTim Tautges PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name)
500*a4d2169cSTim Tautges {
501*a4d2169cSTim Tautges   moab::ErrorCode mberr;
502*a4d2169cSTim Tautges   PetscErrorCode  ierr;
503*a4d2169cSTim Tautges 
504*a4d2169cSTim Tautges   PetscFunctionBegin;
505*a4d2169cSTim Tautges   const std::string PVEC_PREFIX      = "_PETSC_VEC_";
506*a4d2169cSTim Tautges   const PetscInt    PVEC_PREFIX_SIZE = PVEC_PREFIX.size();
507*a4d2169cSTim Tautges 
508*a4d2169cSTim Tautges   // Check to see if there are any PETSc vectors defined:
509*a4d2169cSTim Tautges   const moab::Interface  *mbiface = pcomm->get_moab();
510*a4d2169cSTim Tautges   std::vector<moab::Tag> tags;
511*a4d2169cSTim Tautges   PetscInt               n = 0;
512*a4d2169cSTim Tautges   mberr = mbiface->tag_get_tags(tags);MBERRNM(mberr);
513*a4d2169cSTim Tautges   for(unsigned i = 0; i < tags.size(); i++) {
514*a4d2169cSTim Tautges     std::string s;
515*a4d2169cSTim Tautges     mberr = mbiface->tag_get_name(tags[i],s);MBERRNM(mberr);
516*a4d2169cSTim Tautges     if(s.find(PVEC_PREFIX) != std::string::npos){
517*a4d2169cSTim Tautges       // This tag represents a PETSc vector. Find the vector number:
518*a4d2169cSTim Tautges       PetscInt m;
519*a4d2169cSTim Tautges       std::istringstream(s.substr(PVEC_PREFIX_SIZE)) >> m;
520*a4d2169cSTim Tautges       if(m >= n) n = m+1;
521*a4d2169cSTim Tautges     }
522*a4d2169cSTim Tautges   }
523*a4d2169cSTim Tautges 
524*a4d2169cSTim Tautges   // Make sure that n is consistent across all processes:
525*a4d2169cSTim Tautges   PetscInt global_n;
526*a4d2169cSTim Tautges   MPI_Comm comm = PETSC_COMM_SELF;
527*a4d2169cSTim Tautges   if(pcomm) comm = pcomm->comm();
528*a4d2169cSTim Tautges   ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr);
529*a4d2169cSTim Tautges 
530*a4d2169cSTim Tautges   // Set the answer and return:
531*a4d2169cSTim Tautges   std::stringstream ss;
532*a4d2169cSTim Tautges   ss << PVEC_PREFIX << global_n;
533*a4d2169cSTim Tautges   tag_name = ss.str();
534*a4d2169cSTim Tautges   PetscFunctionReturn(0);
535*a4d2169cSTim Tautges }
536*a4d2169cSTim Tautges 
537*a4d2169cSTim Tautges 
538*a4d2169cSTim Tautges #undef __FUNCT__
539*a4d2169cSTim Tautges #define __FUNCT__ "DMMoab_VecUserDestroy"
540*a4d2169cSTim Tautges PetscErrorCode DMMoab_VecUserDestroy(void *user)
541*a4d2169cSTim Tautges {
542*a4d2169cSTim Tautges   Vec_MOAB        *vmoab;
543*a4d2169cSTim Tautges   PetscErrorCode  ierr;
544*a4d2169cSTim Tautges   moab::ErrorCode merr;
545*a4d2169cSTim Tautges 
546*a4d2169cSTim Tautges   PetscFunctionBegin;
547*a4d2169cSTim Tautges   vmoab = (Vec_MOAB*)user;
548*a4d2169cSTim Tautges   if(vmoab->new_tag == PETSC_TRUE) {
549*a4d2169cSTim Tautges     // Tag created via a call to VecDuplicate, delete the underlying tag in MOAB...
550*a4d2169cSTim Tautges     merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr);
551*a4d2169cSTim Tautges   }
552*a4d2169cSTim Tautges 
553*a4d2169cSTim Tautges   ierr = PetscFree(vmoab);CHKERRQ(ierr);
554*a4d2169cSTim Tautges   PetscFunctionReturn(0);
555*a4d2169cSTim Tautges }
556*a4d2169cSTim Tautges 
557