#include /*I "petscdm.h" I*/ #include /*I "petscdm.h" I*/ #include #include #include #undef __FUNCT__ #define __FUNCT__ "DMGlobalToLocalBegin_Moab" PetscErrorCode DMGlobalToLocalBegin_Moab(DM dm,Vec g,InsertMode mode,Vec l) { PetscErrorCode ierr; DM_Moab *dmmoab = (DM_Moab*)dm->data; PetscFunctionBegin; ierr = VecScatterBegin(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD/*SCATTER_FORWARD*/);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMGlobalToLocalEnd_Moab" PetscErrorCode DMGlobalToLocalEnd_Moab(DM dm,Vec g,InsertMode mode,Vec l) { PetscErrorCode ierr; DM_Moab *dmmoab = (DM_Moab*)dm->data; PetscFunctionBegin; ierr = VecScatterEnd(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD/*SCATTER_FORWARD*/);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMLocalToGlobalBegin_Moab" PetscErrorCode DMLocalToGlobalBegin_Moab(DM dm,Vec l,InsertMode mode,Vec g) { PetscErrorCode ierr; DM_Moab *dmmoab = (DM_Moab*)dm->data; PetscFunctionBegin; // PetscPrintf(PETSC_COMM_WORLD,"\n Inside local-global begin. Printing global and local vecs.\n"); // ierr = VecView(g, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); // ierr = VecView(l, PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecScatterBegin(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMLocalToGlobalEnd_Moab" PetscErrorCode DMLocalToGlobalEnd_Moab(DM dm,Vec l,InsertMode mode,Vec g) { PetscErrorCode ierr; DM_Moab *dmmoab = (DM_Moab*)dm->data; PetscFunctionBegin; ierr = VecScatterEnd(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMDestroy_Moab" PetscErrorCode DMDestroy_Moab(DM dm) { PetscErrorCode ierr; DM_Moab *dmmoab = (DM_Moab*)dm->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); if (dmmoab->icreatedinstance) { delete dmmoab->mbiface; } dmmoab->mbiface = NULL; dmmoab->pcomm = NULL; delete dmmoab->vlocal; delete dmmoab->vowned; delete dmmoab->vghost; delete dmmoab->elocal; delete dmmoab->eghost; ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); ierr = PetscFree(dm->data);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMSetUp_Moab" PetscErrorCode DMSetUp_Moab(DM dm) { PetscErrorCode ierr; moab::ErrorCode merr; Vec local, global; IS from; moab::Range::iterator iter; PetscInt bs, *gsindices; DM_Moab *dmmoab = (DM_Moab*)dm->data; PetscInt count,dof,totsize; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); /* Get the local and shared vertices and cache it */ if (dmmoab->mbiface == PETSC_NULL || dmmoab->pcomm == PETSC_NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp."); /* store the current mesh dimension */ merr = dmmoab->mbiface->get_dimension(dmmoab->dim);MBERRNM(merr); /* Get the entities recursively in the current part of the mesh */ if (dmmoab->vlocal->empty()) { merr = dmmoab->mbiface->get_entities_by_type(0,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); *dmmoab->vowned = *dmmoab->vlocal; /* filter based on parallel status */ merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); dmmoab->nloc = dmmoab->vowned->size(); dmmoab->nghost = dmmoab->vghost->size(); ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); } // PetscPrintf(PETSC_COMM_SELF, "\n Local vertices size = %D and shared vertices = %D", dmmoab->vowned->size(), dmmoab->vghost->size()); // PetscPrintf(PETSC_COMM_SELF, "\n Global vertices size = %D and local vertices = %D", dmmoab->n, dmmoab->nloc); /* get the information about the local elements in the mesh */ { dmmoab->elocal->clear(); dmmoab->eghost->clear(); // PetscPrintf(PETSC_COMM_SELF, "\n Getting all elements of dimension = %D", dmmoab->dim); merr = dmmoab->mbiface->get_entities_by_dimension(0, dmmoab->dim, *dmmoab->elocal, true);CHKERRQ(merr); *dmmoab->eghost = *dmmoab->elocal; merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); dmmoab->neleloc = dmmoab->elocal->size(); ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); // PetscPrintf(PETSC_COMM_SELF, "\n Global elements = %D and local elements = %D", dmmoab->nele, dmmoab->neleloc); } bs = dmmoab->bs; if (!dmmoab->ltog_tag) { // Get the global ID tag. The global ID tag is applied to each // vertex. It acts as an global identifier which MOAB uses to // assemble the individual pieces of the mesh: merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); } { count=0; totsize=dmmoab->vlocal->size(); ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr); /* first get the local indices */ for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) { merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&(*iter),1,&dof);MBERRNM(merr); gsindices[count++] = (dof); } /* now get the ghosted indices */ for(iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++) { merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&(*iter),1,&dof);MBERRNM(merr); gsindices[count++] = (dof); } /* Create Global to Local Vector Scatter Context */ ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); /* global to local must retrieve ghost points */ ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); // ierr = ISCreateGeneral(((PetscObject)dm)->comm,totsize*bs,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); PetscInt gsiz, lsiz; VecGetLocalSize(global,&gsiz); VecGetLocalSize(local,&lsiz); // PetscPrintf(PETSC_COMM_SELF, "\n Global vec size = %D and local vec size = %D; Local=%D; Ghosted=%D; Start=%D\n Printing From and To IS \n", gsiz, lsiz, dmmoab->nloc, dmmoab->nghost, gsindices[0]); // ISView(from, PETSC_VIEWER_STDOUT_WORLD); ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = PetscFree(gsindices);CHKERRQ(ierr); /* create the local to global mapping for all indices */ // ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,dmmoab->nghost*bs,gsindices,PETSC_OWN_POINTER,&dmmoab->ltog_map);CHKERRQ(ierr); } PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMCreate_Moab" PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); ((DM_Moab*)dm->data)->bs = 1; ((DM_Moab*)dm->data)->n = 0; ((DM_Moab*)dm->data)->nloc = 0; ((DM_Moab*)dm->data)->nele = 0; ((DM_Moab*)dm->data)->neleloc = 0; ((DM_Moab*)dm->data)->nghost = 0; ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; ((DM_Moab*)dm->data)->vlocal = new moab::Range(); ((DM_Moab*)dm->data)->vowned = new moab::Range(); ((DM_Moab*)dm->data)->vghost = new moab::Range(); ((DM_Moab*)dm->data)->elocal = new moab::Range(); ((DM_Moab*)dm->data)->eghost = new moab::Range(); dm->ops->createglobalvector = DMCreateGlobalVector_Moab; dm->ops->createlocalvector = DMCreateLocalVector_Moab; dm->ops->creatematrix = DMCreateMatrix_Moab; dm->ops->setup = DMSetUp_Moab; dm->ops->destroy = DMDestroy_Moab; dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabCreate" /*@ DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance Collective on MPI_Comm Input Parameter: . comm - The communicator for the DMMoab object Output Parameter: . dmb - The DMMoab object Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidPointer(dmb,2); ierr = DMCreate(comm, dmb);CHKERRQ(ierr); ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabCreateMoab" /*@ DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data Collective on MPI_Comm Input Parameter: . comm - The communicator for the DMMoab object . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed along with the DMMoab . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag . range - If non-NULL, contains range of entities to which DOFs will be assigned Output Parameter: . dmb - The DMMoab object Level: intermediate .keywords: DMMoab, create @*/ PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) { PetscErrorCode ierr; moab::ErrorCode merr; DM_Moab *dmmoab; PetscFunctionBegin; PetscValidPointer(dmb,6); ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); dmmoab = (DM_Moab*)(*dmb)->data; if (!mbiface) { mbiface = new moab::Core(); dmmoab->icreatedinstance = PETSC_TRUE; } else dmmoab->icreatedinstance = PETSC_FALSE; if (!pcomm) { moab::EntityHandle rootset,partnset; PetscInt rank, nprocs; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); // Create root sets for each mesh. Then pass these // to the load_file functions to be populated. merr = mbiface->create_meshset(moab::MESHSET_SET, rootset); MBERR("Creating root set failed", merr); merr = mbiface->create_meshset(moab::MESHSET_SET, partnset); MBERR("Creating partition set failed", merr); // Create the parallel communicator object with the partition handle associated with MOAB pcomm = moab::ParallelComm::get_pcomm(mbiface, partnset, &comm); } if (!ltog_tag) { merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, *ltog_tag);MBERRNM(merr); } else { ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); } // do the initialization of the DM dmmoab->bs = 1; ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); dmmoab->ltog_tag = *ltog_tag; if (range) { ierr = DMMoabSetRange(*dmb, range);CHKERRQ(ierr); } PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabSetParallelComm" /*@ DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set . pcomm - The ParallelComm being set on the DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) { DM_Moab *dmmoab = (DM_Moab*)(dm)->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); dmmoab->pcomm = pcomm; dmmoab->mbiface = pcomm->get_moab(); dmmoab->icreatedinstance = PETSC_FALSE; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabGetParallelComm" /*@ DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set Output Parameter: . pcomm - The ParallelComm for the DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) { PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); *pcomm = ((DM_Moab*)(dm)->data)->pcomm; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabSetInterface" /*@ DMMoabSetInterface - Set the MOAB instance used with this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set . mbiface - The MOAB instance being set on this DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) { DM_Moab *dmmoab = (DM_Moab*)(dm)->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); dmmoab->pcomm = NULL; dmmoab->mbiface = mbiface; dmmoab->icreatedinstance = PETSC_FALSE; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabGetInterface" /*@ DMMoabGetInterface - Get the MOAB instance used with this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set Output Parameter: . mbiface - The MOAB instance set on this DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) { PetscErrorCode ierr; static PetscBool cite = PETSC_FALSE; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = PetscCitationsRegister("@techreport{tautges_moab:_2004,\n type = {{SAND2004-1592}},\n title = {{MOAB:} A Mesh-Oriented Database}, institution = {Sandia National Laboratories},\n author = {Tautges, T. J. and Meyers, R. and Merkley, K. and Stimpson, C. and Ernst, C.},\n year = {2004}, note = {Report}\n}\n",&cite);CHKERRQ(ierr); *mbiface = ((DM_Moab*)dm->data)->mbiface; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabSetRange" /*@ DMMoabSetRange - Set the entities having DOFs on this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set . range - The entities treated by this DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabSetRange(DM dm,moab::Range *range) { moab::ErrorCode merr; PetscErrorCode ierr; DM_Moab *dmmoab = (DM_Moab*)(dm)->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); dmmoab->vlocal->clear(); dmmoab->vowned->clear(); dmmoab->vlocal->insert(range->begin(), range->end()); *dmmoab->vowned = *dmmoab->vlocal; merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); dmmoab->nloc=dmmoab->vowned->size(); dmmoab->nghost=dmmoab->vghost->size(); ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabGetRange" /*@ DMMoabGetRange - Get the entities having DOFs on this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set Output Parameter: . range - The entities treated by this DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range) { PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); *range = ((DM_Moab*)dm->data)->vowned; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabSetLocalToGlobalTag" /*@ DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set . ltogtag - The MOAB tag used for local to global ids Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) { PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ((DM_Moab*)dm->data)->ltog_tag = ltogtag; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabGetLocalToGlobalTag" /*@ DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set Output Parameter: . ltogtag - The MOAB tag used for local to global ids Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) { PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabSetBlockSize" /*@ DMMoabSetBlockSize - Set the block size used with this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set . bs - The block size used with this DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) { PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ((DM_Moab*)dm->data)->bs = bs; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "DMMoabGetBlockSize" /*@ DMMoabGetBlockSize - Get the block size used with this DMMoab Collective on MPI_Comm Input Parameter: . dm - The DMMoab object being set Output Parameter: . bs - The block size used with this DMMoab Level: beginner .keywords: DMMoab, create @*/ PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) { PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); *bs = ((DM_Moab*)dm->data)->bs; PetscFunctionReturn(0); }