147c6ae99SBarry Smith 23c48a1e8SJed Brown #include "packimpl.h" /*I "petscdmcomposite.h" I*/ 347c6ae99SBarry Smith 447c6ae99SBarry Smith #undef __FUNCT__ 547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling" 647c6ae99SBarry Smith /*@C 747c6ae99SBarry Smith DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the 89ae5db72SJed Brown seperate components (DMs) in a DMto build the correct matrix nonzero structure. 947c6ae99SBarry Smith 1047c6ae99SBarry Smith 1147c6ae99SBarry Smith Logically Collective on MPI_Comm 1247c6ae99SBarry Smith 1347c6ae99SBarry Smith Input Parameter: 1447c6ae99SBarry Smith + dm - the composite object 1547c6ae99SBarry Smith - formcouplelocations - routine to set the nonzero locations in the matrix 1647c6ae99SBarry Smith 1747c6ae99SBarry Smith Level: advanced 1847c6ae99SBarry Smith 191b2093e4SBarry Smith Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into 2047c6ae99SBarry Smith this routine 2147c6ae99SBarry Smith 2247c6ae99SBarry Smith @*/ 237087cfbeSBarry Smith PetscErrorCode DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt)) 2447c6ae99SBarry Smith { 2547c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 2647c6ae99SBarry Smith 2747c6ae99SBarry Smith PetscFunctionBegin; 2847c6ae99SBarry Smith com->FormCoupleLocations = FormCoupleLocations; 2947c6ae99SBarry Smith PetscFunctionReturn(0); 3047c6ae99SBarry Smith } 3147c6ae99SBarry Smith 3247c6ae99SBarry Smith #undef __FUNCT__ 330c010503SBarry Smith #define __FUNCT__ "DMDestroy_Composite" 346bf464f9SBarry Smith PetscErrorCode DMDestroy_Composite(DM dm) 3547c6ae99SBarry Smith { 3647c6ae99SBarry Smith PetscErrorCode ierr; 3747c6ae99SBarry Smith struct DMCompositeLink *next, *prev; 3847c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 3947c6ae99SBarry Smith 4047c6ae99SBarry Smith PetscFunctionBegin; 4147c6ae99SBarry Smith next = com->next; 4247c6ae99SBarry Smith while (next) { 4347c6ae99SBarry Smith prev = next; 4447c6ae99SBarry Smith next = next->next; 45fcfd50ebSBarry Smith ierr = DMDestroy(&prev->dm);CHKERRQ(ierr); 4647c6ae99SBarry Smith ierr = PetscFree(prev->grstarts);CHKERRQ(ierr); 4747c6ae99SBarry Smith ierr = PetscFree(prev);CHKERRQ(ierr); 4847c6ae99SBarry Smith } 4947c6ae99SBarry Smith PetscFunctionReturn(0); 5047c6ae99SBarry Smith } 5147c6ae99SBarry Smith 5247c6ae99SBarry Smith #undef __FUNCT__ 530c010503SBarry Smith #define __FUNCT__ "DMView_Composite" 547087cfbeSBarry Smith PetscErrorCode DMView_Composite(DM dm,PetscViewer v) 5547c6ae99SBarry Smith { 5647c6ae99SBarry Smith PetscErrorCode ierr; 5747c6ae99SBarry Smith PetscBool iascii; 5847c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 5947c6ae99SBarry Smith 6047c6ae99SBarry Smith PetscFunctionBegin; 6147c6ae99SBarry Smith ierr = PetscTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 6247c6ae99SBarry Smith if (iascii) { 6347c6ae99SBarry Smith struct DMCompositeLink *lnk = com->next; 6447c6ae99SBarry Smith PetscInt i; 6547c6ae99SBarry Smith 6647c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix?((PetscObject)dm)->prefix:"no prefix");CHKERRQ(ierr); 679ae5db72SJed Brown ierr = PetscViewerASCIIPrintf(v," contains %D DMs\n",com->nDM);CHKERRQ(ierr); 6847c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 6947c6ae99SBarry Smith for (i=0; lnk; lnk=lnk->next,i++) { 709ae5db72SJed Brown ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr); 7147c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 7247c6ae99SBarry Smith ierr = DMView(lnk->dm,v);CHKERRQ(ierr); 7347c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 7447c6ae99SBarry Smith } 7547c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 7647c6ae99SBarry Smith } 7747c6ae99SBarry Smith PetscFunctionReturn(0); 7847c6ae99SBarry Smith } 7947c6ae99SBarry Smith 8047c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/ 8147c6ae99SBarry Smith #undef __FUNCT__ 82d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite" 837087cfbeSBarry Smith PetscErrorCode DMSetUp_Composite(DM dm) 8447c6ae99SBarry Smith { 8547c6ae99SBarry Smith PetscErrorCode ierr; 8647c6ae99SBarry Smith PetscInt nprev = 0; 8747c6ae99SBarry Smith PetscMPIInt rank,size; 8847c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 8947c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 9047c6ae99SBarry Smith PetscLayout map; 9147c6ae99SBarry Smith 9247c6ae99SBarry Smith PetscFunctionBegin; 9347c6ae99SBarry Smith if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); 9447c6ae99SBarry Smith ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr); 9547c6ae99SBarry Smith ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); 9647c6ae99SBarry Smith ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); 9747c6ae99SBarry Smith ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 9847c6ae99SBarry Smith ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 9947c6ae99SBarry Smith ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); 10047c6ae99SBarry Smith ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr); 101fcfd50ebSBarry Smith ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 10247c6ae99SBarry Smith 1039ae5db72SJed Brown /* now set the rstart for each linked vector */ 10447c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 10547c6ae99SBarry Smith ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr); 10647c6ae99SBarry Smith while (next) { 10747c6ae99SBarry Smith next->rstart = nprev; 10806ebdd98SJed Brown nprev += next->n; 10947c6ae99SBarry Smith next->grstart = com->rstart + next->rstart; 11047c6ae99SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr); 11147c6ae99SBarry Smith ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 11247c6ae99SBarry Smith next = next->next; 11347c6ae99SBarry Smith } 11447c6ae99SBarry Smith com->setup = PETSC_TRUE; 11547c6ae99SBarry Smith PetscFunctionReturn(0); 11647c6ae99SBarry Smith } 11747c6ae99SBarry Smith 11847c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/ 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith #include <stdarg.h> 12147c6ae99SBarry Smith 12247c6ae99SBarry Smith #undef __FUNCT__ 12347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM" 12447c6ae99SBarry Smith /*@C 12547c6ae99SBarry Smith DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite 12647c6ae99SBarry Smith representation. 12747c6ae99SBarry Smith 12847c6ae99SBarry Smith Not Collective 12947c6ae99SBarry Smith 13047c6ae99SBarry Smith Input Parameter: 13147c6ae99SBarry Smith . dm - the packer object 13247c6ae99SBarry Smith 13347c6ae99SBarry Smith Output Parameter: 13447c6ae99SBarry Smith . nDM - the number of DMs 13547c6ae99SBarry Smith 13647c6ae99SBarry Smith Level: beginner 13747c6ae99SBarry Smith 13847c6ae99SBarry Smith @*/ 1397087cfbeSBarry Smith PetscErrorCode DMCompositeGetNumberDM(DM dm,PetscInt *nDM) 14047c6ae99SBarry Smith { 14147c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 14247c6ae99SBarry Smith PetscFunctionBegin; 14347c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 14447c6ae99SBarry Smith *nDM = com->nDM; 14547c6ae99SBarry Smith PetscFunctionReturn(0); 14647c6ae99SBarry Smith } 14747c6ae99SBarry Smith 14847c6ae99SBarry Smith 14947c6ae99SBarry Smith #undef __FUNCT__ 15047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess" 15147c6ae99SBarry Smith /*@C 15247c6ae99SBarry Smith DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 15347c6ae99SBarry Smith representation. 15447c6ae99SBarry Smith 15547c6ae99SBarry Smith Collective on DMComposite 15647c6ae99SBarry Smith 1579ae5db72SJed Brown Input Parameters: 15847c6ae99SBarry Smith + dm - the packer object 1599ae5db72SJed Brown - gvec - the global vector 1609ae5db72SJed Brown 1619ae5db72SJed Brown Output Parameters: 1629ae5db72SJed Brown . Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed 16347c6ae99SBarry Smith 16447c6ae99SBarry Smith Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them 16547c6ae99SBarry Smith 16647c6ae99SBarry Smith Level: advanced 16747c6ae99SBarry Smith 16847c6ae99SBarry Smith @*/ 1697087cfbeSBarry Smith PetscErrorCode DMCompositeGetAccess(DM dm,Vec gvec,...) 17047c6ae99SBarry Smith { 17147c6ae99SBarry Smith va_list Argp; 17247c6ae99SBarry Smith PetscErrorCode ierr; 17347c6ae99SBarry Smith struct DMCompositeLink *next; 17447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 17547c6ae99SBarry Smith 17647c6ae99SBarry Smith PetscFunctionBegin; 17747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 17847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 17947c6ae99SBarry Smith next = com->next; 18047c6ae99SBarry Smith if (!com->setup) { 181d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 18247c6ae99SBarry Smith } 18347c6ae99SBarry Smith 18447c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 18547c6ae99SBarry Smith va_start(Argp,gvec); 18647c6ae99SBarry Smith while (next) { 18747c6ae99SBarry Smith Vec *vec; 18847c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 1899ae5db72SJed Brown if (vec) { 1909ae5db72SJed Brown PetscScalar *array; 1919ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr); 1929ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 1939ae5db72SJed Brown ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 1949ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 19547c6ae99SBarry Smith } 19647c6ae99SBarry Smith next = next->next; 19747c6ae99SBarry Smith } 19847c6ae99SBarry Smith va_end(Argp); 19947c6ae99SBarry Smith PetscFunctionReturn(0); 20047c6ae99SBarry Smith } 20147c6ae99SBarry Smith 20247c6ae99SBarry Smith #undef __FUNCT__ 20347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess" 20447c6ae99SBarry Smith /*@C 205aa219208SBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() 20647c6ae99SBarry Smith representation. 20747c6ae99SBarry Smith 20847c6ae99SBarry Smith Collective on DMComposite 20947c6ae99SBarry Smith 2109ae5db72SJed Brown Input Parameters: 21147c6ae99SBarry Smith + dm - the packer object 21247c6ae99SBarry Smith . gvec - the global vector 2139ae5db72SJed Brown - Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed 21447c6ae99SBarry Smith 21547c6ae99SBarry Smith Level: advanced 21647c6ae99SBarry Smith 2179ae5db72SJed Brown .seealso DMCompositeAddDM(), DMCreateGlobalVector(), 2186eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), 219aa219208SBarry Smith DMCompositeRestoreAccess(), DMCompositeGetAccess() 22047c6ae99SBarry Smith 22147c6ae99SBarry Smith @*/ 2227087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) 22347c6ae99SBarry Smith { 22447c6ae99SBarry Smith va_list Argp; 22547c6ae99SBarry Smith PetscErrorCode ierr; 22647c6ae99SBarry Smith struct DMCompositeLink *next; 22747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 22847c6ae99SBarry Smith 22947c6ae99SBarry Smith PetscFunctionBegin; 23047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 23147c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 23247c6ae99SBarry Smith next = com->next; 23347c6ae99SBarry Smith if (!com->setup) { 234d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 23547c6ae99SBarry Smith } 23647c6ae99SBarry Smith 23747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 23847c6ae99SBarry Smith va_start(Argp,gvec); 23947c6ae99SBarry Smith while (next) { 24047c6ae99SBarry Smith Vec *vec; 24147c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 2429ae5db72SJed Brown if (vec) { 2439ae5db72SJed Brown ierr = VecResetArray(*vec);CHKERRQ(ierr); 2449ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); 24547c6ae99SBarry Smith } 24647c6ae99SBarry Smith next = next->next; 24747c6ae99SBarry Smith } 24847c6ae99SBarry Smith va_end(Argp); 24947c6ae99SBarry Smith PetscFunctionReturn(0); 25047c6ae99SBarry Smith } 25147c6ae99SBarry Smith 25247c6ae99SBarry Smith #undef __FUNCT__ 25347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter" 25447c6ae99SBarry Smith /*@C 25547c6ae99SBarry Smith DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 25647c6ae99SBarry Smith 25747c6ae99SBarry Smith Collective on DMComposite 25847c6ae99SBarry Smith 2599ae5db72SJed Brown Input Parameters: 26047c6ae99SBarry Smith + dm - the packer object 26147c6ae99SBarry Smith . gvec - the global vector 2629ae5db72SJed Brown - Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed 26347c6ae99SBarry Smith 26447c6ae99SBarry Smith Level: advanced 26547c6ae99SBarry Smith 2669ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 2676eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 26847c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 26947c6ae99SBarry Smith 27047c6ae99SBarry Smith @*/ 2717087cfbeSBarry Smith PetscErrorCode DMCompositeScatter(DM dm,Vec gvec,...) 27247c6ae99SBarry Smith { 27347c6ae99SBarry Smith va_list Argp; 27447c6ae99SBarry Smith PetscErrorCode ierr; 27547c6ae99SBarry Smith struct DMCompositeLink *next; 2768fd8f222SJed Brown PetscInt cnt; 27747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 27847c6ae99SBarry Smith 27947c6ae99SBarry Smith PetscFunctionBegin; 28047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 28147c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 28247c6ae99SBarry Smith if (!com->setup) { 283d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 28447c6ae99SBarry Smith } 28547c6ae99SBarry Smith 28647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 28747c6ae99SBarry Smith va_start(Argp,gvec); 2888fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 2899ae5db72SJed Brown Vec local; 2909ae5db72SJed Brown local = va_arg(Argp, Vec); 2919ae5db72SJed Brown if (local) { 2929ae5db72SJed Brown Vec global; 29347c6ae99SBarry Smith PetscScalar *array; 2949ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 2959ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 2969ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 2979ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 2989ae5db72SJed Brown ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 2999ae5db72SJed Brown ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 3009ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 3019ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 3029ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 30347c6ae99SBarry Smith } 30447c6ae99SBarry Smith } 30547c6ae99SBarry Smith va_end(Argp); 30647c6ae99SBarry Smith PetscFunctionReturn(0); 30747c6ae99SBarry Smith } 30847c6ae99SBarry Smith 30947c6ae99SBarry Smith #undef __FUNCT__ 31047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather" 31147c6ae99SBarry Smith /*@C 31247c6ae99SBarry Smith DMCompositeGather - Gathers into a global packed vector from its individual local vectors 31347c6ae99SBarry Smith 31447c6ae99SBarry Smith Collective on DMComposite 31547c6ae99SBarry Smith 31647c6ae99SBarry Smith Input Parameter: 31747c6ae99SBarry Smith + dm - the packer object 31847c6ae99SBarry Smith . gvec - the global vector 3199ae5db72SJed Brown - Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed 32047c6ae99SBarry Smith 32147c6ae99SBarry Smith Level: advanced 32247c6ae99SBarry Smith 3239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 3246eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 32547c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 32647c6ae99SBarry Smith 32747c6ae99SBarry Smith @*/ 3287087cfbeSBarry Smith PetscErrorCode DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...) 32947c6ae99SBarry Smith { 33047c6ae99SBarry Smith va_list Argp; 33147c6ae99SBarry Smith PetscErrorCode ierr; 33247c6ae99SBarry Smith struct DMCompositeLink *next; 33347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 3348fd8f222SJed Brown PetscInt cnt; 33547c6ae99SBarry Smith 33647c6ae99SBarry Smith PetscFunctionBegin; 33747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 33847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 33947c6ae99SBarry Smith if (!com->setup) { 340d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 34147c6ae99SBarry Smith } 34247c6ae99SBarry Smith 34347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 344df0c820aSJed Brown va_start(Argp,imode); 3458fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 3469ae5db72SJed Brown Vec local; 3479ae5db72SJed Brown local = va_arg(Argp, Vec); 3489ae5db72SJed Brown if (local) { 34947c6ae99SBarry Smith PetscScalar *array; 3509ae5db72SJed Brown Vec global; 3519ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 3529ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 3539ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 3549ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 3559ae5db72SJed Brown ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); 3569ae5db72SJed Brown ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); 3579ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 3589ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 3599ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 36047c6ae99SBarry Smith } 36147c6ae99SBarry Smith } 36247c6ae99SBarry Smith va_end(Argp); 36347c6ae99SBarry Smith PetscFunctionReturn(0); 36447c6ae99SBarry Smith } 36547c6ae99SBarry Smith 36647c6ae99SBarry Smith #undef __FUNCT__ 36747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM" 36847c6ae99SBarry Smith /*@C 369aa219208SBarry Smith DMCompositeAddDM - adds a DM vector to a DMComposite 37047c6ae99SBarry Smith 37147c6ae99SBarry Smith Collective on DMComposite 37247c6ae99SBarry Smith 37347c6ae99SBarry Smith Input Parameter: 37447c6ae99SBarry Smith + dm - the packer object 37547c6ae99SBarry Smith - dm - the DM object, if the DM is a da you will need to caste it with a (DM) 37647c6ae99SBarry Smith 37747c6ae99SBarry Smith Level: advanced 37847c6ae99SBarry Smith 3790c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), 3806eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 38147c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 38247c6ae99SBarry Smith 38347c6ae99SBarry Smith @*/ 3847087cfbeSBarry Smith PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) 38547c6ae99SBarry Smith { 38647c6ae99SBarry Smith PetscErrorCode ierr; 38706ebdd98SJed Brown PetscInt n,nlocal; 38847c6ae99SBarry Smith struct DMCompositeLink *mine,*next; 38906ebdd98SJed Brown Vec global,local; 39047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmc->data; 39147c6ae99SBarry Smith 39247c6ae99SBarry Smith PetscFunctionBegin; 39347c6ae99SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 39447c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 39547c6ae99SBarry Smith next = com->next; 396aa219208SBarry Smith if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); 39747c6ae99SBarry Smith 39847c6ae99SBarry Smith /* create new link */ 39947c6ae99SBarry Smith ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); 40047c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 40147c6ae99SBarry Smith ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 40247c6ae99SBarry Smith ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 40347c6ae99SBarry Smith ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 40406ebdd98SJed Brown ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); 40506ebdd98SJed Brown ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); 40606ebdd98SJed Brown ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); 40747c6ae99SBarry Smith mine->n = n; 40806ebdd98SJed Brown mine->nlocal = nlocal; 40947c6ae99SBarry Smith mine->dm = dm; 41047c6ae99SBarry Smith mine->next = PETSC_NULL; 41147c6ae99SBarry Smith com->n += n; 41247c6ae99SBarry Smith 41347c6ae99SBarry Smith /* add to end of list */ 41447c6ae99SBarry Smith if (!next) { 41547c6ae99SBarry Smith com->next = mine; 41647c6ae99SBarry Smith } else { 41747c6ae99SBarry Smith while (next->next) next = next->next; 41847c6ae99SBarry Smith next->next = mine; 41947c6ae99SBarry Smith } 42047c6ae99SBarry Smith com->nDM++; 42147c6ae99SBarry Smith com->nmine++; 42247c6ae99SBarry Smith PetscFunctionReturn(0); 42347c6ae99SBarry Smith } 42447c6ae99SBarry Smith 4257087cfbeSBarry Smith extern PetscErrorCode VecView_MPI(Vec,PetscViewer); 42647c6ae99SBarry Smith EXTERN_C_BEGIN 42747c6ae99SBarry Smith #undef __FUNCT__ 42847c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite" 4297087cfbeSBarry Smith PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) 43047c6ae99SBarry Smith { 43147c6ae99SBarry Smith DM dm; 43247c6ae99SBarry Smith PetscErrorCode ierr; 43347c6ae99SBarry Smith struct DMCompositeLink *next; 43447c6ae99SBarry Smith PetscBool isdraw; 435cef07954SSatish Balay DM_Composite *com; 43647c6ae99SBarry Smith 43747c6ae99SBarry Smith PetscFunctionBegin; 4383c0c59f3SBarry Smith ierr = PetscObjectQuery((PetscObject)gvec,"DM",(PetscObject*)&dm);CHKERRQ(ierr); 43947c6ae99SBarry Smith if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 44047c6ae99SBarry Smith com = (DM_Composite*)dm->data; 44147c6ae99SBarry Smith next = com->next; 44247c6ae99SBarry Smith 44347c6ae99SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 44447c6ae99SBarry Smith if (!isdraw) { 44547c6ae99SBarry Smith /* do I really want to call this? */ 44647c6ae99SBarry Smith ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 44747c6ae99SBarry Smith } else { 44847c6ae99SBarry Smith PetscInt cnt = 0; 44947c6ae99SBarry Smith 45047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 45147c6ae99SBarry Smith while (next) { 45247c6ae99SBarry Smith Vec vec; 4539ae5db72SJed Brown PetscScalar *array; 45447c6ae99SBarry Smith PetscInt bs; 45547c6ae99SBarry Smith 4569ae5db72SJed Brown /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 4579ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); 4589ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 4599ae5db72SJed Brown ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr); 4609ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 46147c6ae99SBarry Smith ierr = VecView(vec,viewer);CHKERRQ(ierr); 46247c6ae99SBarry Smith ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 4639ae5db72SJed Brown ierr = VecResetArray(vec);CHKERRQ(ierr); 4649ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); 46547c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 46647c6ae99SBarry Smith cnt += bs; 46747c6ae99SBarry Smith next = next->next; 46847c6ae99SBarry Smith } 46947c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 47047c6ae99SBarry Smith } 47147c6ae99SBarry Smith PetscFunctionReturn(0); 47247c6ae99SBarry Smith } 47347c6ae99SBarry Smith EXTERN_C_END 47447c6ae99SBarry Smith 47547c6ae99SBarry Smith 47647c6ae99SBarry Smith #undef __FUNCT__ 4770c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite" 4787087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector_Composite(DM dm,Vec *gvec) 47947c6ae99SBarry Smith { 48047c6ae99SBarry Smith PetscErrorCode ierr; 48147c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 48247c6ae99SBarry Smith 48347c6ae99SBarry Smith PetscFunctionBegin; 48447c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 485d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 48647c6ae99SBarry Smith ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr); 4873c0c59f3SBarry Smith ierr = PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);CHKERRQ(ierr); 48847c6ae99SBarry Smith ierr = VecSetOperation(*gvec,VECOP_VIEW,(void(*)(void))VecView_DMComposite);CHKERRQ(ierr); 48947c6ae99SBarry Smith PetscFunctionReturn(0); 49047c6ae99SBarry Smith } 49147c6ae99SBarry Smith 49247c6ae99SBarry Smith #undef __FUNCT__ 4930c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite" 4947087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector_Composite(DM dm,Vec *lvec) 49547c6ae99SBarry Smith { 49647c6ae99SBarry Smith PetscErrorCode ierr; 49747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 49847c6ae99SBarry Smith 49947c6ae99SBarry Smith PetscFunctionBegin; 50047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 50147c6ae99SBarry Smith if (!com->setup) { 502d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 50347c6ae99SBarry Smith } 50447c6ae99SBarry Smith ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr); 5053c0c59f3SBarry Smith ierr = PetscObjectCompose((PetscObject)*lvec,"DM",(PetscObject)dm);CHKERRQ(ierr); 50647c6ae99SBarry Smith PetscFunctionReturn(0); 50747c6ae99SBarry Smith } 50847c6ae99SBarry Smith 50947c6ae99SBarry Smith #undef __FUNCT__ 5106eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings" 51147c6ae99SBarry Smith /*@C 5129ae5db72SJed Brown DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space 51347c6ae99SBarry Smith 51406ebdd98SJed Brown Collective on DM 51547c6ae99SBarry Smith 51647c6ae99SBarry Smith Input Parameter: 51747c6ae99SBarry Smith . dm - the packer object 51847c6ae99SBarry Smith 51947c6ae99SBarry Smith Output Parameters: 5209ae5db72SJed Brown . ltogs - the individual mappings for each packed vector. Note that this includes 5219ae5db72SJed Brown all the ghost points that individual ghosted DMDA's may have. 52247c6ae99SBarry Smith 52347c6ae99SBarry Smith Level: advanced 52447c6ae99SBarry Smith 52547c6ae99SBarry Smith Notes: 5266eb61c8cSJed Brown Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). 52747c6ae99SBarry Smith 5289ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 52947c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 53047c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 53147c6ae99SBarry Smith 53247c6ae99SBarry Smith @*/ 5337087cfbeSBarry Smith PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) 53447c6ae99SBarry Smith { 53547c6ae99SBarry Smith PetscErrorCode ierr; 53647c6ae99SBarry Smith PetscInt i,*idx,n,cnt; 53747c6ae99SBarry Smith struct DMCompositeLink *next; 53847c6ae99SBarry Smith PetscMPIInt rank; 53947c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 54047c6ae99SBarry Smith 54147c6ae99SBarry Smith PetscFunctionBegin; 54247c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 543728e99d6SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 5449ae5db72SJed Brown ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr); 54547c6ae99SBarry Smith next = com->next; 54647c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 54747c6ae99SBarry Smith 54847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 54947c6ae99SBarry Smith cnt = 0; 55047c6ae99SBarry Smith while (next) { 5516eb61c8cSJed Brown ISLocalToGlobalMapping ltog; 5526eb61c8cSJed Brown PetscMPIInt size; 55386994e45SJed Brown const PetscInt *suboff,*indices; 5546eb61c8cSJed Brown Vec global; 55547c6ae99SBarry Smith 5566eb61c8cSJed Brown /* Get sub-DM global indices for each local dof */ 5571411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); 5586eb61c8cSJed Brown ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); 55986994e45SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); 56047c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 56147c6ae99SBarry Smith 5626eb61c8cSJed Brown /* Get the offsets for the sub-DM global vector */ 5636eb61c8cSJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 5646eb61c8cSJed Brown ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); 5656eb61c8cSJed Brown ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr); 5666eb61c8cSJed Brown 5676eb61c8cSJed Brown /* Shift the sub-DM definition of the global space to the composite global space */ 5686eb61c8cSJed Brown for (i=0; i<n; i++) { 56986994e45SJed Brown PetscInt subi = indices[i],lo = 0,hi = size,t; 5706eb61c8cSJed Brown /* Binary search to find which rank owns subi */ 5716eb61c8cSJed Brown while (hi-lo > 1) { 5726eb61c8cSJed Brown t = lo + (hi-lo)/2; 5736eb61c8cSJed Brown if (suboff[t] > subi) hi = t; 5746eb61c8cSJed Brown else lo = t; 5756eb61c8cSJed Brown } 5766eb61c8cSJed Brown idx[i] = subi - suboff[lo] + next->grstarts[lo]; 5776eb61c8cSJed Brown } 57886994e45SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); 5796eb61c8cSJed Brown ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); 5806eb61c8cSJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 58147c6ae99SBarry Smith next = next->next; 58247c6ae99SBarry Smith cnt++; 58347c6ae99SBarry Smith } 58447c6ae99SBarry Smith PetscFunctionReturn(0); 58547c6ae99SBarry Smith } 58647c6ae99SBarry Smith 58747c6ae99SBarry Smith #undef __FUNCT__ 58887c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs" 58987c85e80SJed Brown /*@C 5909ae5db72SJed Brown DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 59187c85e80SJed Brown 59287c85e80SJed Brown Not Collective 59387c85e80SJed Brown 59487c85e80SJed Brown Input Arguments: 59587c85e80SJed Brown . dm - composite DM 59687c85e80SJed Brown 59787c85e80SJed Brown Output Arguments: 59887c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite 59987c85e80SJed Brown 60087c85e80SJed Brown Level: intermediate 60187c85e80SJed Brown 60287c85e80SJed Brown Notes: 60387c85e80SJed Brown At present, a composite local vector does not normally exist. This function is used to provide index sets for 60487c85e80SJed Brown MatGetLocalSubMatrix(). In the future, the scatters for each entry in the DMComposite may be be merged into a single 6059ae5db72SJed Brown scatter to a composite local vector. The user should not typically need to know which is being done. 60687c85e80SJed Brown 60787c85e80SJed Brown To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings(). 60887c85e80SJed Brown 60987c85e80SJed Brown To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs(). 61087c85e80SJed Brown 61187c85e80SJed Brown Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree(). 61287c85e80SJed Brown 61387c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef() 61487c85e80SJed Brown @*/ 6157087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalISs(DM dm,IS **is) 61687c85e80SJed Brown { 61787c85e80SJed Brown PetscErrorCode ierr; 61887c85e80SJed Brown DM_Composite *com = (DM_Composite*)dm->data; 61987c85e80SJed Brown struct DMCompositeLink *link; 62087c85e80SJed Brown PetscInt cnt,start; 62187c85e80SJed Brown 62287c85e80SJed Brown PetscFunctionBegin; 62387c85e80SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62487c85e80SJed Brown PetscValidPointer(is,2); 62587c85e80SJed Brown ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr); 62606ebdd98SJed Brown for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) { 627520db06cSJed Brown PetscInt bs; 6289ae5db72SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr); 6291411c6eeSJed Brown ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr); 630520db06cSJed Brown ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr); 631520db06cSJed Brown } 63287c85e80SJed Brown PetscFunctionReturn(0); 63387c85e80SJed Brown } 63487c85e80SJed Brown 63587c85e80SJed Brown #undef __FUNCT__ 63647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs" 63747c6ae99SBarry Smith /*@C 63847c6ae99SBarry Smith DMCompositeGetGlobalISs - Gets the index sets for each composed object 63947c6ae99SBarry Smith 64047c6ae99SBarry Smith Collective on DMComposite 64147c6ae99SBarry Smith 64247c6ae99SBarry Smith Input Parameter: 64347c6ae99SBarry Smith . dm - the packer object 64447c6ae99SBarry Smith 64547c6ae99SBarry Smith Output Parameters: 64647c6ae99SBarry Smith . is - the array of index sets 64747c6ae99SBarry Smith 64847c6ae99SBarry Smith Level: advanced 64947c6ae99SBarry Smith 65047c6ae99SBarry Smith Notes: 65147c6ae99SBarry Smith The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 65247c6ae99SBarry Smith 65347c6ae99SBarry Smith These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 65447c6ae99SBarry Smith 6556eb61c8cSJed Brown Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and 6566eb61c8cSJed Brown DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global 6576eb61c8cSJed Brown indices. 65847c6ae99SBarry Smith 6599ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 66047c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 66147c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 66247c6ae99SBarry Smith 66347c6ae99SBarry Smith @*/ 6646eb61c8cSJed Brown 6657087cfbeSBarry Smith PetscErrorCode DMCompositeGetGlobalISs(DM dm,IS *is[]) 66647c6ae99SBarry Smith { 66747c6ae99SBarry Smith PetscErrorCode ierr; 66847c6ae99SBarry Smith PetscInt cnt = 0,*idx,i; 66947c6ae99SBarry Smith struct DMCompositeLink *next; 67047c6ae99SBarry Smith PetscMPIInt rank; 67147c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 67247c6ae99SBarry Smith 67347c6ae99SBarry Smith PetscFunctionBegin; 67447c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6759ae5db72SJed Brown ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr); 67647c6ae99SBarry Smith next = com->next; 67747c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 67847c6ae99SBarry Smith 67947c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 68047c6ae99SBarry Smith while (next) { 68147c6ae99SBarry Smith ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 68247c6ae99SBarry Smith for (i=0; i<next->n; i++) idx[i] = next->grstart + i; 68347c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 68447c6ae99SBarry Smith cnt++; 68547c6ae99SBarry Smith next = next->next; 68647c6ae99SBarry Smith } 68747c6ae99SBarry Smith PetscFunctionReturn(0); 68847c6ae99SBarry Smith } 68947c6ae99SBarry Smith 6904d343eeaSMatthew G Knepley #undef __FUNCT__ 6914d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite" 69221c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields) 6934d343eeaSMatthew G Knepley { 6944d343eeaSMatthew G Knepley PetscInt nDM; 6954d343eeaSMatthew G Knepley DM *dms; 6964d343eeaSMatthew G Knepley PetscInt i; 6974d343eeaSMatthew G Knepley PetscErrorCode ierr; 6984d343eeaSMatthew G Knepley 6994d343eeaSMatthew G Knepley PetscFunctionBegin; 7004d343eeaSMatthew G Knepley ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 7014d343eeaSMatthew G Knepley if (numFields) {*numFields = nDM;} 7024d343eeaSMatthew G Knepley ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr); 7034d343eeaSMatthew G Knepley if (fieldNames) { 7044d343eeaSMatthew G Knepley ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr); 7054d343eeaSMatthew G Knepley ierr = PetscMalloc(nDM*sizeof(const char *), fieldNames);CHKERRQ(ierr); 7064d343eeaSMatthew G Knepley ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr); 7074d343eeaSMatthew G Knepley for (i=0; i<nDM; i++) { 7084d343eeaSMatthew G Knepley char buf[256]; 7094d343eeaSMatthew G Knepley const char *splitname; 7104d343eeaSMatthew G Knepley 7114d343eeaSMatthew G Knepley /* Split naming precedence: object name, prefix, number */ 7124d343eeaSMatthew G Knepley splitname = ((PetscObject) dm)->name; 7134d343eeaSMatthew G Knepley if (!splitname) { 7144d343eeaSMatthew G Knepley ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr); 7154d343eeaSMatthew G Knepley if (splitname) { 7164d343eeaSMatthew G Knepley size_t len; 7174d343eeaSMatthew G Knepley ierr = PetscStrncpy(buf,splitname,sizeof buf);CHKERRQ(ierr); 7184d343eeaSMatthew G Knepley buf[sizeof buf - 1] = 0; 7194d343eeaSMatthew G Knepley ierr = PetscStrlen(buf,&len);CHKERRQ(ierr); 7204d343eeaSMatthew G Knepley if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */ 7214d343eeaSMatthew G Knepley splitname = buf; 7224d343eeaSMatthew G Knepley } 7234d343eeaSMatthew G Knepley } 7244d343eeaSMatthew G Knepley if (!splitname) { 7254d343eeaSMatthew G Knepley ierr = PetscSNPrintf(buf,sizeof buf,"%D",i);CHKERRQ(ierr); 7264d343eeaSMatthew G Knepley splitname = buf; 7274d343eeaSMatthew G Knepley } 72821c9b008SJed Brown ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr); 7294d343eeaSMatthew G Knepley } 7304d343eeaSMatthew G Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 7314d343eeaSMatthew G Knepley } 7324d343eeaSMatthew G Knepley PetscFunctionReturn(0); 7334d343eeaSMatthew G Knepley } 7344d343eeaSMatthew G Knepley 735*e7c4fc90SDmitry Karpeev /* 736*e7c4fc90SDmitry Karpeev This could take over from DMCreateFieldIS(), as it is more general, 737*e7c4fc90SDmitry Karpeev making DMCreateFieldIS() a special case -- calling with dmlist == PETSC_NULL; 738*e7c4fc90SDmitry Karpeev At this point it's probably best to be less intrusive, however. 739*e7c4fc90SDmitry Karpeev */ 740*e7c4fc90SDmitry Karpeev #undef __FUNCT__ 741*e7c4fc90SDmitry Karpeev #define __FUNCT__ "DMCreateDecomposition_Composite" 742*e7c4fc90SDmitry Karpeev PetscErrorCode DMCreateDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM** dmlist) 743*e7c4fc90SDmitry Karpeev { 744*e7c4fc90SDmitry Karpeev PetscInt nDM; 745*e7c4fc90SDmitry Karpeev PetscInt i; 746*e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 747*e7c4fc90SDmitry Karpeev 748*e7c4fc90SDmitry Karpeev PetscFunctionBegin; 749*e7c4fc90SDmitry Karpeev ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist); CHKERRQ(ierr); 750*e7c4fc90SDmitry Karpeev if(dmlist) { 751*e7c4fc90SDmitry Karpeev ierr = DMCompositeGetNumberDM(dm, &nDM); CHKERRQ(ierr); 752*e7c4fc90SDmitry Karpeev ierr = PetscMalloc(nDM*sizeof(DM), dmlist); CHKERRQ(ierr); 753*e7c4fc90SDmitry Karpeev ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr); 754*e7c4fc90SDmitry Karpeev for (i=0; i<nDM; i++) { 755*e7c4fc90SDmitry Karpeev ierr = PetscObjectReference((PetscObject)((*dmlist)[i])); CHKERRQ(ierr); 756*e7c4fc90SDmitry Karpeev } 757*e7c4fc90SDmitry Karpeev } 758*e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 759*e7c4fc90SDmitry Karpeev } 760*e7c4fc90SDmitry Karpeev 761*e7c4fc90SDmitry Karpeev 762*e7c4fc90SDmitry Karpeev 76347c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 76447c6ae99SBarry Smith #undef __FUNCT__ 76547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors" 76647c6ae99SBarry Smith /*@C 7679ae5db72SJed Brown DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite. 76847c6ae99SBarry Smith Use DMCompositeRestoreLocalVectors() to return them. 76947c6ae99SBarry Smith 77047c6ae99SBarry Smith Not Collective 77147c6ae99SBarry Smith 77247c6ae99SBarry Smith Input Parameter: 77347c6ae99SBarry Smith . dm - the packer object 77447c6ae99SBarry Smith 77547c6ae99SBarry Smith Output Parameter: 7769ae5db72SJed Brown . Vec ... - the individual sequential Vecs 77747c6ae99SBarry Smith 77847c6ae99SBarry Smith Level: advanced 77947c6ae99SBarry Smith 7809ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 7816eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 78247c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 78347c6ae99SBarry Smith 78447c6ae99SBarry Smith @*/ 7857087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalVectors(DM dm,...) 78647c6ae99SBarry Smith { 78747c6ae99SBarry Smith va_list Argp; 78847c6ae99SBarry Smith PetscErrorCode ierr; 78947c6ae99SBarry Smith struct DMCompositeLink *next; 79047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 79147c6ae99SBarry Smith 79247c6ae99SBarry Smith PetscFunctionBegin; 79347c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 79447c6ae99SBarry Smith next = com->next; 79547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 79647c6ae99SBarry Smith va_start(Argp,dm); 79747c6ae99SBarry Smith while (next) { 79847c6ae99SBarry Smith Vec *vec; 79947c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 8009ae5db72SJed Brown ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr); 80147c6ae99SBarry Smith next = next->next; 80247c6ae99SBarry Smith } 80347c6ae99SBarry Smith va_end(Argp); 80447c6ae99SBarry Smith PetscFunctionReturn(0); 80547c6ae99SBarry Smith } 80647c6ae99SBarry Smith 80747c6ae99SBarry Smith #undef __FUNCT__ 80847c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors" 80947c6ae99SBarry Smith /*@C 8109ae5db72SJed Brown DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite. 81147c6ae99SBarry Smith 81247c6ae99SBarry Smith Not Collective 81347c6ae99SBarry Smith 81447c6ae99SBarry Smith Input Parameter: 81547c6ae99SBarry Smith . dm - the packer object 81647c6ae99SBarry Smith 81747c6ae99SBarry Smith Output Parameter: 8189ae5db72SJed Brown . Vec ... - the individual sequential Vecs 81947c6ae99SBarry Smith 82047c6ae99SBarry Smith Level: advanced 82147c6ae99SBarry Smith 8229ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 8236eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 82447c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 82547c6ae99SBarry Smith 82647c6ae99SBarry Smith @*/ 8277087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreLocalVectors(DM dm,...) 82847c6ae99SBarry Smith { 82947c6ae99SBarry Smith va_list Argp; 83047c6ae99SBarry Smith PetscErrorCode ierr; 83147c6ae99SBarry Smith struct DMCompositeLink *next; 83247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 83347c6ae99SBarry Smith 83447c6ae99SBarry Smith PetscFunctionBegin; 83547c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 83647c6ae99SBarry Smith next = com->next; 83747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 83847c6ae99SBarry Smith va_start(Argp,dm); 83947c6ae99SBarry Smith while (next) { 84047c6ae99SBarry Smith Vec *vec; 84147c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 8429ae5db72SJed Brown ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr); 84347c6ae99SBarry Smith next = next->next; 84447c6ae99SBarry Smith } 84547c6ae99SBarry Smith va_end(Argp); 84647c6ae99SBarry Smith PetscFunctionReturn(0); 84747c6ae99SBarry Smith } 84847c6ae99SBarry Smith 84947c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 85047c6ae99SBarry Smith #undef __FUNCT__ 85147c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries" 85247c6ae99SBarry Smith /*@C 8539ae5db72SJed Brown DMCompositeGetEntries - Gets the DM for each entry in a DMComposite. 85447c6ae99SBarry Smith 85547c6ae99SBarry Smith Not Collective 85647c6ae99SBarry Smith 85747c6ae99SBarry Smith Input Parameter: 85847c6ae99SBarry Smith . dm - the packer object 85947c6ae99SBarry Smith 86047c6ae99SBarry Smith Output Parameter: 8619ae5db72SJed Brown . DM ... - the individual entries (DMs) 86247c6ae99SBarry Smith 86347c6ae99SBarry Smith Level: advanced 86447c6ae99SBarry Smith 8652fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray() 8666eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 86747c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 86847c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 86947c6ae99SBarry Smith 87047c6ae99SBarry Smith @*/ 8717087cfbeSBarry Smith PetscErrorCode DMCompositeGetEntries(DM dm,...) 87247c6ae99SBarry Smith { 87347c6ae99SBarry Smith va_list Argp; 87447c6ae99SBarry Smith struct DMCompositeLink *next; 87547c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 87647c6ae99SBarry Smith 87747c6ae99SBarry Smith PetscFunctionBegin; 87847c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87947c6ae99SBarry Smith next = com->next; 88047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 88147c6ae99SBarry Smith va_start(Argp,dm); 88247c6ae99SBarry Smith while (next) { 88347c6ae99SBarry Smith DM *dmn; 88447c6ae99SBarry Smith dmn = va_arg(Argp, DM*); 8859ae5db72SJed Brown if (dmn) *dmn = next->dm; 88647c6ae99SBarry Smith next = next->next; 88747c6ae99SBarry Smith } 88847c6ae99SBarry Smith va_end(Argp); 88947c6ae99SBarry Smith PetscFunctionReturn(0); 89047c6ae99SBarry Smith } 89147c6ae99SBarry Smith 89247c6ae99SBarry Smith #undef __FUNCT__ 8932fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray" 8942fa5ba8aSJed Brown /*@ 8952fa5ba8aSJed Brown DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite. 8962fa5ba8aSJed Brown 8972fa5ba8aSJed Brown Not Collective 8982fa5ba8aSJed Brown 8992fa5ba8aSJed Brown Input Parameter: 9002fa5ba8aSJed Brown + dm - the packer object 9012fa5ba8aSJed Brown - dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output 9022fa5ba8aSJed Brown 9032fa5ba8aSJed Brown Level: advanced 9042fa5ba8aSJed Brown 9052fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries() 9062fa5ba8aSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 9072fa5ba8aSJed Brown DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 9082fa5ba8aSJed Brown DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 9092fa5ba8aSJed Brown 9102fa5ba8aSJed Brown @*/ 9112fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[]) 9122fa5ba8aSJed Brown { 9132fa5ba8aSJed Brown struct DMCompositeLink *next; 9142fa5ba8aSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 9152fa5ba8aSJed Brown PetscInt i; 9162fa5ba8aSJed Brown 9172fa5ba8aSJed Brown PetscFunctionBegin; 9182fa5ba8aSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9192fa5ba8aSJed Brown /* loop over packed objects, handling one at at time */ 9202fa5ba8aSJed Brown for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm; 9212fa5ba8aSJed Brown PetscFunctionReturn(0); 9222fa5ba8aSJed Brown } 9232fa5ba8aSJed Brown 9242fa5ba8aSJed Brown #undef __FUNCT__ 9250c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite" 9267087cfbeSBarry Smith PetscErrorCode DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine) 92747c6ae99SBarry Smith { 92847c6ae99SBarry Smith PetscErrorCode ierr; 92947c6ae99SBarry Smith struct DMCompositeLink *next; 93047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmi->data; 93147c6ae99SBarry Smith DM dm; 93247c6ae99SBarry Smith 93347c6ae99SBarry Smith PetscFunctionBegin; 93447c6ae99SBarry Smith PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 9352ee06e3bSJed Brown if (comm == MPI_COMM_NULL) comm = ((PetscObject)dmi)->comm; 9362ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 93747c6ae99SBarry Smith next = com->next; 93847c6ae99SBarry Smith ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 93947c6ae99SBarry Smith 94047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 94147c6ae99SBarry Smith while (next) { 94247c6ae99SBarry Smith ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 94347c6ae99SBarry Smith ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 94447c6ae99SBarry Smith ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 94547c6ae99SBarry Smith next = next->next; 94647c6ae99SBarry Smith } 94747c6ae99SBarry Smith PetscFunctionReturn(0); 94847c6ae99SBarry Smith } 94947c6ae99SBarry Smith 95014354c39SJed Brown #undef __FUNCT__ 95114354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite" 95214354c39SJed Brown PetscErrorCode DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine) 95314354c39SJed Brown { 95414354c39SJed Brown PetscErrorCode ierr; 95514354c39SJed Brown struct DMCompositeLink *next; 95614354c39SJed Brown DM_Composite *com = (DM_Composite*)dmi->data; 95714354c39SJed Brown DM dm; 95814354c39SJed Brown 95914354c39SJed Brown PetscFunctionBegin; 96014354c39SJed Brown PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 9612ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 9622ee06e3bSJed Brown if (comm == MPI_COMM_NULL) { 96325296bd5SBarry Smith ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 96425296bd5SBarry Smith } 96514354c39SJed Brown next = com->next; 96614354c39SJed Brown ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 96714354c39SJed Brown 96814354c39SJed Brown /* loop over packed objects, handling one at at time */ 96914354c39SJed Brown while (next) { 97014354c39SJed Brown ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr); 97114354c39SJed Brown ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 97214354c39SJed Brown ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 97314354c39SJed Brown next = next->next; 97414354c39SJed Brown } 97514354c39SJed Brown PetscFunctionReturn(0); 97614354c39SJed Brown } 97747c6ae99SBarry Smith 97847c6ae99SBarry Smith #undef __FUNCT__ 979e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite" 980e727c939SJed Brown PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) 98147c6ae99SBarry Smith { 98247c6ae99SBarry Smith PetscErrorCode ierr; 9839ae5db72SJed Brown PetscInt m,n,M,N,nDM,i; 98447c6ae99SBarry Smith struct DMCompositeLink *nextc; 98547c6ae99SBarry Smith struct DMCompositeLink *nextf; 98625296bd5SBarry Smith Vec gcoarse,gfine,*vecs; 98747c6ae99SBarry Smith DM_Composite *comcoarse = (DM_Composite*)coarse->data; 98847c6ae99SBarry Smith DM_Composite *comfine = (DM_Composite*)fine->data; 9899ae5db72SJed Brown Mat *mats; 99047c6ae99SBarry Smith 99147c6ae99SBarry Smith PetscFunctionBegin; 99247c6ae99SBarry Smith PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 99347c6ae99SBarry Smith PetscValidHeaderSpecific(fine,DM_CLASSID,2); 994f692024eSJed Brown ierr = DMSetUp(coarse);CHKERRQ(ierr); 995f692024eSJed Brown ierr = DMSetUp(fine);CHKERRQ(ierr); 99647c6ae99SBarry Smith /* use global vectors only for determining matrix layout */ 9979ae5db72SJed Brown ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 9989ae5db72SJed Brown ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); 99947c6ae99SBarry Smith ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 100047c6ae99SBarry Smith ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 100147c6ae99SBarry Smith ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 100247c6ae99SBarry Smith ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 10039ae5db72SJed Brown ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 10049ae5db72SJed Brown ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); 100547c6ae99SBarry Smith 10069ae5db72SJed Brown nDM = comfine->nDM; 10079ae5db72SJed Brown if (nDM != comcoarse->nDM) SETERRQ2(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM); 10089ae5db72SJed Brown ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr); 10099ae5db72SJed Brown ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr); 101025296bd5SBarry Smith if (v) { 101125296bd5SBarry Smith ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr); 101225296bd5SBarry Smith ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr); 101325296bd5SBarry Smith } 101447c6ae99SBarry Smith 101547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 10169ae5db72SJed Brown for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { 101725296bd5SBarry Smith if (!v) { 1018e727c939SJed Brown ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr); 101925296bd5SBarry Smith } else { 102025296bd5SBarry Smith ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); 102125296bd5SBarry Smith } 102247c6ae99SBarry Smith } 10239ae5db72SJed Brown ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr); 102425296bd5SBarry Smith if (v) { 102525296bd5SBarry Smith ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr); 102625296bd5SBarry Smith } 10279ae5db72SJed Brown for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} 10289ae5db72SJed Brown ierr = PetscFree(mats);CHKERRQ(ierr); 102925296bd5SBarry Smith if (v) { 103025296bd5SBarry Smith for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} 103125296bd5SBarry Smith ierr = PetscFree(vecs);CHKERRQ(ierr); 103225296bd5SBarry Smith } 103347c6ae99SBarry Smith PetscFunctionReturn(0); 103447c6ae99SBarry Smith } 103547c6ae99SBarry Smith 103647c6ae99SBarry Smith #undef __FUNCT__ 10371411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite" 10381411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm) 10391411c6eeSJed Brown { 10401411c6eeSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 10411411c6eeSJed Brown ISLocalToGlobalMapping *ltogs; 1042f7efa3c7SJed Brown PetscInt i; 10431411c6eeSJed Brown PetscErrorCode ierr; 10441411c6eeSJed Brown 10451411c6eeSJed Brown PetscFunctionBegin; 10461411c6eeSJed Brown /* Set the ISLocalToGlobalMapping on the new matrix */ 10471411c6eeSJed Brown ierr = DMCompositeGetISLocalToGlobalMappings(dm,<ogs);CHKERRQ(ierr); 10489ae5db72SJed Brown ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr); 10499ae5db72SJed Brown for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(<ogs[i]);CHKERRQ(ierr);} 10501411c6eeSJed Brown ierr = PetscFree(ltogs);CHKERRQ(ierr); 10511411c6eeSJed Brown PetscFunctionReturn(0); 10521411c6eeSJed Brown } 10531411c6eeSJed Brown 10541411c6eeSJed Brown 10551411c6eeSJed Brown #undef __FUNCT__ 1056e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite" 1057e727c939SJed Brown PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring) 105847c6ae99SBarry Smith { 105947c6ae99SBarry Smith PetscErrorCode ierr; 106047c6ae99SBarry Smith PetscInt n,i,cnt; 106147c6ae99SBarry Smith ISColoringValue *colors; 106247c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 106347c6ae99SBarry Smith ISColoringValue maxcol = 0; 106447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 106547c6ae99SBarry Smith 106647c6ae99SBarry Smith PetscFunctionBegin; 106747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 106847c6ae99SBarry Smith if (ctype == IS_COLORING_GHOSTED) { 106947c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Currently you must use -dmmg_iscoloring_type global" ); 107047c6ae99SBarry Smith } else if (ctype == IS_COLORING_GLOBAL) { 107147c6ae99SBarry Smith n = com->n; 107247c6ae99SBarry Smith } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 107347c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 107447c6ae99SBarry Smith 1075671f6225SBarry Smith ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); 107647c6ae99SBarry Smith if (dense) { 107747c6ae99SBarry Smith for (i=0; i<n; i++) { 107847c6ae99SBarry Smith colors[i] = (ISColoringValue)(com->rstart + i); 107947c6ae99SBarry Smith } 108047c6ae99SBarry Smith maxcol = com->N; 108147c6ae99SBarry Smith } else { 108247c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 108347c6ae99SBarry Smith PetscMPIInt rank; 108447c6ae99SBarry Smith 108547c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 108647c6ae99SBarry Smith cnt = 0; 108747c6ae99SBarry Smith while (next) { 108847c6ae99SBarry Smith ISColoring lcoloring; 108947c6ae99SBarry Smith 1090e727c939SJed Brown ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr); 109147c6ae99SBarry Smith for (i=0; i<lcoloring->N; i++) { 109247c6ae99SBarry Smith colors[cnt++] = maxcol + lcoloring->colors[i]; 109347c6ae99SBarry Smith } 109447c6ae99SBarry Smith maxcol += lcoloring->n; 1095fcfd50ebSBarry Smith ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); 109647c6ae99SBarry Smith next = next->next; 109747c6ae99SBarry Smith } 109847c6ae99SBarry Smith } 109947c6ae99SBarry Smith ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr); 110047c6ae99SBarry Smith PetscFunctionReturn(0); 110147c6ae99SBarry Smith } 110247c6ae99SBarry Smith 110347c6ae99SBarry Smith #undef __FUNCT__ 11040c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite" 11057087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 110647c6ae99SBarry Smith { 110747c6ae99SBarry Smith PetscErrorCode ierr; 110847c6ae99SBarry Smith struct DMCompositeLink *next; 110947c6ae99SBarry Smith PetscInt cnt = 3; 111047c6ae99SBarry Smith PetscMPIInt rank; 111147c6ae99SBarry Smith PetscScalar *garray,*larray; 111247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 111347c6ae99SBarry Smith 111447c6ae99SBarry Smith PetscFunctionBegin; 111547c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 111647c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 111747c6ae99SBarry Smith next = com->next; 111847c6ae99SBarry Smith if (!com->setup) { 1119d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 112047c6ae99SBarry Smith } 112147c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 112247c6ae99SBarry Smith ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 112347c6ae99SBarry Smith ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 112447c6ae99SBarry Smith 112547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 112647c6ae99SBarry Smith while (next) { 112747c6ae99SBarry Smith Vec local,global; 112847c6ae99SBarry Smith PetscInt N; 112947c6ae99SBarry Smith 113047c6ae99SBarry Smith ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 113147c6ae99SBarry Smith ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 113247c6ae99SBarry Smith ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 113347c6ae99SBarry Smith ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 113447c6ae99SBarry Smith ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 113547c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 113647c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 113747c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 113847c6ae99SBarry Smith ierr = VecResetArray(local);CHKERRQ(ierr); 113947c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 114047c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); 114147c6ae99SBarry Smith cnt++; 114206ebdd98SJed Brown larray += next->nlocal; 114347c6ae99SBarry Smith next = next->next; 114447c6ae99SBarry Smith } 114547c6ae99SBarry Smith 114647c6ae99SBarry Smith ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr); 114747c6ae99SBarry Smith ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr); 114847c6ae99SBarry Smith PetscFunctionReturn(0); 114947c6ae99SBarry Smith } 115047c6ae99SBarry Smith 115147c6ae99SBarry Smith #undef __FUNCT__ 11520c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite" 11537087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 11540c010503SBarry Smith { 11550c010503SBarry Smith PetscFunctionBegin; 11560c010503SBarry Smith PetscFunctionReturn(0); 11570c010503SBarry Smith } 115847c6ae99SBarry Smith 1159a4121054SBarry Smith EXTERN_C_BEGIN 1160a4121054SBarry Smith #undef __FUNCT__ 1161a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite" 11627087cfbeSBarry Smith PetscErrorCode DMCreate_Composite(DM p) 1163a4121054SBarry Smith { 1164a4121054SBarry Smith PetscErrorCode ierr; 1165a4121054SBarry Smith DM_Composite *com; 1166a4121054SBarry Smith 1167a4121054SBarry Smith PetscFunctionBegin; 1168a4121054SBarry Smith ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr); 1169a4121054SBarry Smith p->data = com; 1170a4121054SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 1171a4121054SBarry Smith com->n = 0; 1172a4121054SBarry Smith com->next = PETSC_NULL; 1173a4121054SBarry Smith com->nDM = 0; 1174a4121054SBarry Smith 1175a4121054SBarry Smith p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1176a4121054SBarry Smith p->ops->createlocalvector = DMCreateLocalVector_Composite; 11771411c6eeSJed Brown p->ops->createlocaltoglobalmapping = DMCreateLocalToGlobalMapping_Composite; 11781411c6eeSJed Brown p->ops->createlocaltoglobalmappingblock = 0; 11794d343eeaSMatthew G Knepley p->ops->createfieldis = DMCreateFieldIS_Composite; 1180*e7c4fc90SDmitry Karpeev p->ops->createdecomposition = DMCreateDecomposition_Composite; 1181a4121054SBarry Smith p->ops->refine = DMRefine_Composite; 118214354c39SJed Brown p->ops->coarsen = DMCoarsen_Composite; 118325296bd5SBarry Smith p->ops->createinterpolation = DMCreateInterpolation_Composite; 118425296bd5SBarry Smith p->ops->creatematrix = DMCreateMatrix_Composite; 1185e727c939SJed Brown p->ops->getcoloring = DMCreateColoring_Composite; 1186a4121054SBarry Smith p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1187a4121054SBarry Smith p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 1188a4121054SBarry Smith p->ops->destroy = DMDestroy_Composite; 1189a4121054SBarry Smith p->ops->view = DMView_Composite; 1190a4121054SBarry Smith p->ops->setup = DMSetUp_Composite; 1191a4121054SBarry Smith PetscFunctionReturn(0); 1192a4121054SBarry Smith } 1193a4121054SBarry Smith EXTERN_C_END 1194a4121054SBarry Smith 11950c010503SBarry Smith #undef __FUNCT__ 11960c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate" 11970c010503SBarry Smith /*@C 11980c010503SBarry Smith DMCompositeCreate - Creates a vector packer, used to generate "composite" 11990c010503SBarry Smith vectors made up of several subvectors. 12000c010503SBarry Smith 12010c010503SBarry Smith Collective on MPI_Comm 120247c6ae99SBarry Smith 120347c6ae99SBarry Smith Input Parameter: 12040c010503SBarry Smith . comm - the processors that will share the global vector 12050c010503SBarry Smith 12060c010503SBarry Smith Output Parameters: 12070c010503SBarry Smith . packer - the packer object 120847c6ae99SBarry Smith 120947c6ae99SBarry Smith Level: advanced 121047c6ae99SBarry Smith 12119ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), 12126eb61c8cSJed Brown DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess() 121347c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 121447c6ae99SBarry Smith 121547c6ae99SBarry Smith @*/ 12167087cfbeSBarry Smith PetscErrorCode DMCompositeCreate(MPI_Comm comm,DM *packer) 121747c6ae99SBarry Smith { 12180c010503SBarry Smith PetscErrorCode ierr; 12190c010503SBarry Smith 122047c6ae99SBarry Smith PetscFunctionBegin; 12210c010503SBarry Smith PetscValidPointer(packer,2); 1222a4121054SBarry Smith ierr = DMCreate(comm,packer);CHKERRQ(ierr); 1223a4121054SBarry Smith ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr); 122447c6ae99SBarry Smith PetscFunctionReturn(0); 122547c6ae99SBarry Smith } 1226