147c6ae99SBarry Smith 2ccd284c7SBarry Smith #include <../src/dm/impls/composite/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 } 49435a35e8SMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 50435a35e8SMatthew G Knepley ierr = PetscFree(com);CHKERRQ(ierr); 5147c6ae99SBarry Smith PetscFunctionReturn(0); 5247c6ae99SBarry Smith } 5347c6ae99SBarry Smith 5447c6ae99SBarry Smith #undef __FUNCT__ 550c010503SBarry Smith #define __FUNCT__ "DMView_Composite" 567087cfbeSBarry Smith PetscErrorCode DMView_Composite(DM dm,PetscViewer v) 5747c6ae99SBarry Smith { 5847c6ae99SBarry Smith PetscErrorCode ierr; 5947c6ae99SBarry Smith PetscBool iascii; 6047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 6147c6ae99SBarry Smith 6247c6ae99SBarry Smith PetscFunctionBegin; 63251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 6447c6ae99SBarry Smith if (iascii) { 6547c6ae99SBarry Smith struct DMCompositeLink *lnk = com->next; 6647c6ae99SBarry Smith PetscInt i; 6747c6ae99SBarry Smith 6847c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix");CHKERRQ(ierr); 699ae5db72SJed Brown ierr = PetscViewerASCIIPrintf(v," contains %D DMs\n",com->nDM);CHKERRQ(ierr); 7047c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 7147c6ae99SBarry Smith for (i=0; lnk; lnk=lnk->next,i++) { 729ae5db72SJed Brown ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr); 7347c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 7447c6ae99SBarry Smith ierr = DMView(lnk->dm,v);CHKERRQ(ierr); 7547c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 7647c6ae99SBarry Smith } 7747c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 7847c6ae99SBarry Smith } 7947c6ae99SBarry Smith PetscFunctionReturn(0); 8047c6ae99SBarry Smith } 8147c6ae99SBarry Smith 8247c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/ 8347c6ae99SBarry Smith #undef __FUNCT__ 84d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite" 857087cfbeSBarry Smith PetscErrorCode DMSetUp_Composite(DM dm) 8647c6ae99SBarry Smith { 8747c6ae99SBarry Smith PetscErrorCode ierr; 8847c6ae99SBarry Smith PetscInt nprev = 0; 8947c6ae99SBarry Smith PetscMPIInt rank,size; 9047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 9147c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 9247c6ae99SBarry Smith PetscLayout map; 9347c6ae99SBarry Smith 9447c6ae99SBarry Smith PetscFunctionBegin; 9547c6ae99SBarry Smith if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); 9647c6ae99SBarry Smith ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr); 9747c6ae99SBarry Smith ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); 9847c6ae99SBarry Smith ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); 9947c6ae99SBarry Smith ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 10047c6ae99SBarry Smith ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 10147c6ae99SBarry Smith ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); 10247c6ae99SBarry Smith ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr); 103fcfd50ebSBarry Smith ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 10447c6ae99SBarry Smith 1059ae5db72SJed Brown /* now set the rstart for each linked vector */ 10647c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 10747c6ae99SBarry Smith ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr); 10847c6ae99SBarry Smith while (next) { 10947c6ae99SBarry Smith next->rstart = nprev; 11006ebdd98SJed Brown nprev += next->n; 11147c6ae99SBarry Smith next->grstart = com->rstart + next->rstart; 11247c6ae99SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr); 11347c6ae99SBarry Smith ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 11447c6ae99SBarry Smith next = next->next; 11547c6ae99SBarry Smith } 11647c6ae99SBarry Smith com->setup = PETSC_TRUE; 11747c6ae99SBarry Smith PetscFunctionReturn(0); 11847c6ae99SBarry Smith } 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/ 12147c6ae99SBarry Smith 12247c6ae99SBarry Smith #include <stdarg.h> 12347c6ae99SBarry Smith 12447c6ae99SBarry Smith #undef __FUNCT__ 12547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM" 126*73e31fe2SJed Brown /*@ 12747c6ae99SBarry Smith DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite 12847c6ae99SBarry Smith representation. 12947c6ae99SBarry Smith 13047c6ae99SBarry Smith Not Collective 13147c6ae99SBarry Smith 13247c6ae99SBarry Smith Input Parameter: 13347c6ae99SBarry Smith . dm - the packer object 13447c6ae99SBarry Smith 13547c6ae99SBarry Smith Output Parameter: 13647c6ae99SBarry Smith . nDM - the number of DMs 13747c6ae99SBarry Smith 13847c6ae99SBarry Smith Level: beginner 13947c6ae99SBarry Smith 14047c6ae99SBarry Smith @*/ 1417087cfbeSBarry Smith PetscErrorCode DMCompositeGetNumberDM(DM dm,PetscInt *nDM) 14247c6ae99SBarry Smith { 14347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1445fd66863SKarl Rupp 14547c6ae99SBarry Smith PetscFunctionBegin; 14647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 14747c6ae99SBarry Smith *nDM = com->nDM; 14847c6ae99SBarry Smith PetscFunctionReturn(0); 14947c6ae99SBarry Smith } 15047c6ae99SBarry Smith 15147c6ae99SBarry Smith 15247c6ae99SBarry Smith #undef __FUNCT__ 15347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess" 15447c6ae99SBarry Smith /*@C 15547c6ae99SBarry Smith DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 15647c6ae99SBarry Smith representation. 15747c6ae99SBarry Smith 15847c6ae99SBarry Smith Collective on DMComposite 15947c6ae99SBarry Smith 1609ae5db72SJed Brown Input Parameters: 16147c6ae99SBarry Smith + dm - the packer object 1629ae5db72SJed Brown - gvec - the global vector 1639ae5db72SJed Brown 1649ae5db72SJed Brown Output Parameters: 1659ae5db72SJed Brown . Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed 16647c6ae99SBarry Smith 16747c6ae99SBarry Smith Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them 16847c6ae99SBarry Smith 16947c6ae99SBarry Smith Level: advanced 17047c6ae99SBarry Smith 17147c6ae99SBarry Smith @*/ 1727087cfbeSBarry Smith PetscErrorCode DMCompositeGetAccess(DM dm,Vec gvec,...) 17347c6ae99SBarry Smith { 17447c6ae99SBarry Smith va_list Argp; 17547c6ae99SBarry Smith PetscErrorCode ierr; 17647c6ae99SBarry Smith struct DMCompositeLink *next; 17747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 17847c6ae99SBarry Smith 17947c6ae99SBarry Smith PetscFunctionBegin; 18047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18147c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 18247c6ae99SBarry Smith next = com->next; 18347c6ae99SBarry Smith if (!com->setup) { 184d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 18547c6ae99SBarry Smith } 18647c6ae99SBarry Smith 18747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 18847c6ae99SBarry Smith va_start(Argp,gvec); 18947c6ae99SBarry Smith while (next) { 19047c6ae99SBarry Smith Vec *vec; 19147c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 1929ae5db72SJed Brown if (vec) { 1939ae5db72SJed Brown PetscScalar *array; 1949ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr); 1959ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 1969ae5db72SJed Brown ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 1979ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 19847c6ae99SBarry Smith } 19947c6ae99SBarry Smith next = next->next; 20047c6ae99SBarry Smith } 20147c6ae99SBarry Smith va_end(Argp); 20247c6ae99SBarry Smith PetscFunctionReturn(0); 20347c6ae99SBarry Smith } 20447c6ae99SBarry Smith 20547c6ae99SBarry Smith #undef __FUNCT__ 20647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess" 20747c6ae99SBarry Smith /*@C 208aa219208SBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() 20947c6ae99SBarry Smith representation. 21047c6ae99SBarry Smith 21147c6ae99SBarry Smith Collective on DMComposite 21247c6ae99SBarry Smith 2139ae5db72SJed Brown Input Parameters: 21447c6ae99SBarry Smith + dm - the packer object 21547c6ae99SBarry Smith . gvec - the global vector 2169ae5db72SJed Brown - Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed 21747c6ae99SBarry Smith 21847c6ae99SBarry Smith Level: advanced 21947c6ae99SBarry Smith 2209ae5db72SJed Brown .seealso DMCompositeAddDM(), DMCreateGlobalVector(), 2216eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), 222aa219208SBarry Smith DMCompositeRestoreAccess(), DMCompositeGetAccess() 22347c6ae99SBarry Smith 22447c6ae99SBarry Smith @*/ 2257087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) 22647c6ae99SBarry Smith { 22747c6ae99SBarry Smith va_list Argp; 22847c6ae99SBarry Smith PetscErrorCode ierr; 22947c6ae99SBarry Smith struct DMCompositeLink *next; 23047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 23147c6ae99SBarry Smith 23247c6ae99SBarry Smith PetscFunctionBegin; 23347c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 23447c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 23547c6ae99SBarry Smith next = com->next; 23647c6ae99SBarry Smith if (!com->setup) { 237d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 23847c6ae99SBarry Smith } 23947c6ae99SBarry Smith 24047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 24147c6ae99SBarry Smith va_start(Argp,gvec); 24247c6ae99SBarry Smith while (next) { 24347c6ae99SBarry Smith Vec *vec; 24447c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 2459ae5db72SJed Brown if (vec) { 2469ae5db72SJed Brown ierr = VecResetArray(*vec);CHKERRQ(ierr); 2479ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); 24847c6ae99SBarry Smith } 24947c6ae99SBarry Smith next = next->next; 25047c6ae99SBarry Smith } 25147c6ae99SBarry Smith va_end(Argp); 25247c6ae99SBarry Smith PetscFunctionReturn(0); 25347c6ae99SBarry Smith } 25447c6ae99SBarry Smith 25547c6ae99SBarry Smith #undef __FUNCT__ 25647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter" 25747c6ae99SBarry Smith /*@C 25847c6ae99SBarry Smith DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 25947c6ae99SBarry Smith 26047c6ae99SBarry Smith Collective on DMComposite 26147c6ae99SBarry Smith 2629ae5db72SJed Brown Input Parameters: 26347c6ae99SBarry Smith + dm - the packer object 26447c6ae99SBarry Smith . gvec - the global vector 2659ae5db72SJed Brown - Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed 26647c6ae99SBarry Smith 26747c6ae99SBarry Smith Level: advanced 26847c6ae99SBarry Smith 2699ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 2706eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 27147c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 27247c6ae99SBarry Smith 27347c6ae99SBarry Smith @*/ 2747087cfbeSBarry Smith PetscErrorCode DMCompositeScatter(DM dm,Vec gvec,...) 27547c6ae99SBarry Smith { 27647c6ae99SBarry Smith va_list Argp; 27747c6ae99SBarry Smith PetscErrorCode ierr; 27847c6ae99SBarry Smith struct DMCompositeLink *next; 2798fd8f222SJed Brown PetscInt cnt; 28047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 28147c6ae99SBarry Smith 28247c6ae99SBarry Smith PetscFunctionBegin; 28347c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 28447c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 28547c6ae99SBarry Smith if (!com->setup) { 286d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 28747c6ae99SBarry Smith } 28847c6ae99SBarry Smith 28947c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 29047c6ae99SBarry Smith va_start(Argp,gvec); 2918fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 2929ae5db72SJed Brown Vec local; 2939ae5db72SJed Brown local = va_arg(Argp, Vec); 2949ae5db72SJed Brown if (local) { 2959ae5db72SJed Brown Vec global; 29647c6ae99SBarry Smith PetscScalar *array; 2979ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 2989ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 2999ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 3009ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 3019ae5db72SJed Brown ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 3029ae5db72SJed Brown ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 3039ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 3049ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 3059ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 30647c6ae99SBarry Smith } 30747c6ae99SBarry Smith } 30847c6ae99SBarry Smith va_end(Argp); 30947c6ae99SBarry Smith PetscFunctionReturn(0); 31047c6ae99SBarry Smith } 31147c6ae99SBarry Smith 31247c6ae99SBarry Smith #undef __FUNCT__ 31347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather" 31447c6ae99SBarry Smith /*@C 31547c6ae99SBarry Smith DMCompositeGather - Gathers into a global packed vector from its individual local vectors 31647c6ae99SBarry Smith 31747c6ae99SBarry Smith Collective on DMComposite 31847c6ae99SBarry Smith 31947c6ae99SBarry Smith Input Parameter: 32047c6ae99SBarry Smith + dm - the packer object 32147c6ae99SBarry Smith . gvec - the global vector 3229ae5db72SJed Brown - Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed 32347c6ae99SBarry Smith 32447c6ae99SBarry Smith Level: advanced 32547c6ae99SBarry Smith 3269ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 3276eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 32847c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 32947c6ae99SBarry Smith 33047c6ae99SBarry Smith @*/ 3317087cfbeSBarry Smith PetscErrorCode DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...) 33247c6ae99SBarry Smith { 33347c6ae99SBarry Smith va_list Argp; 33447c6ae99SBarry Smith PetscErrorCode ierr; 33547c6ae99SBarry Smith struct DMCompositeLink *next; 33647c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 3378fd8f222SJed Brown PetscInt cnt; 33847c6ae99SBarry Smith 33947c6ae99SBarry Smith PetscFunctionBegin; 34047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 34147c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 34247c6ae99SBarry Smith if (!com->setup) { 343d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 34447c6ae99SBarry Smith } 34547c6ae99SBarry Smith 34647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 347df0c820aSJed Brown va_start(Argp,imode); 3488fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 3499ae5db72SJed Brown Vec local; 3509ae5db72SJed Brown local = va_arg(Argp, Vec); 3519ae5db72SJed Brown if (local) { 35247c6ae99SBarry Smith PetscScalar *array; 3539ae5db72SJed Brown Vec global; 3549ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 3559ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 3569ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 3579ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 3589ae5db72SJed Brown ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); 3599ae5db72SJed Brown ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); 3609ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 3619ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 3629ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 36347c6ae99SBarry Smith } 36447c6ae99SBarry Smith } 36547c6ae99SBarry Smith va_end(Argp); 36647c6ae99SBarry Smith PetscFunctionReturn(0); 36747c6ae99SBarry Smith } 36847c6ae99SBarry Smith 36947c6ae99SBarry Smith #undef __FUNCT__ 37047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM" 37147c6ae99SBarry Smith /*@C 372aa219208SBarry Smith DMCompositeAddDM - adds a DM vector to a DMComposite 37347c6ae99SBarry Smith 37447c6ae99SBarry Smith Collective on DMComposite 37547c6ae99SBarry Smith 37647c6ae99SBarry Smith Input Parameter: 37747c6ae99SBarry Smith + dm - the packer object 37847c6ae99SBarry Smith - dm - the DM object, if the DM is a da you will need to caste it with a (DM) 37947c6ae99SBarry Smith 38047c6ae99SBarry Smith Level: advanced 38147c6ae99SBarry Smith 3820c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), 3836eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 38447c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 38547c6ae99SBarry Smith 38647c6ae99SBarry Smith @*/ 3877087cfbeSBarry Smith PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) 38847c6ae99SBarry Smith { 38947c6ae99SBarry Smith PetscErrorCode ierr; 39006ebdd98SJed Brown PetscInt n,nlocal; 39147c6ae99SBarry Smith struct DMCompositeLink *mine,*next; 39206ebdd98SJed Brown Vec global,local; 39347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmc->data; 39447c6ae99SBarry Smith 39547c6ae99SBarry Smith PetscFunctionBegin; 39647c6ae99SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 39747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 39847c6ae99SBarry Smith next = com->next; 399aa219208SBarry Smith if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); 40047c6ae99SBarry Smith 40147c6ae99SBarry Smith /* create new link */ 40247c6ae99SBarry Smith ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); 40347c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 40447c6ae99SBarry Smith ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 40547c6ae99SBarry Smith ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 40647c6ae99SBarry Smith ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 40706ebdd98SJed Brown ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); 40806ebdd98SJed Brown ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); 40906ebdd98SJed Brown ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); 4108865f1eaSKarl Rupp 41147c6ae99SBarry Smith mine->n = n; 41206ebdd98SJed Brown mine->nlocal = nlocal; 41347c6ae99SBarry Smith mine->dm = dm; 41447c6ae99SBarry Smith mine->next = PETSC_NULL; 41547c6ae99SBarry Smith com->n += n; 41647c6ae99SBarry Smith 41747c6ae99SBarry Smith /* add to end of list */ 4188865f1eaSKarl Rupp if (!next) com->next = mine; 4198865f1eaSKarl Rupp else { 42047c6ae99SBarry Smith while (next->next) next = next->next; 42147c6ae99SBarry Smith next->next = mine; 42247c6ae99SBarry Smith } 42347c6ae99SBarry Smith com->nDM++; 42447c6ae99SBarry Smith com->nmine++; 42547c6ae99SBarry Smith PetscFunctionReturn(0); 42647c6ae99SBarry Smith } 42747c6ae99SBarry Smith 4287087cfbeSBarry Smith extern PetscErrorCode VecView_MPI(Vec,PetscViewer); 42947c6ae99SBarry Smith EXTERN_C_BEGIN 43047c6ae99SBarry Smith #undef __FUNCT__ 43147c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite" 4327087cfbeSBarry Smith PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) 43347c6ae99SBarry Smith { 43447c6ae99SBarry Smith DM dm; 43547c6ae99SBarry Smith PetscErrorCode ierr; 43647c6ae99SBarry Smith struct DMCompositeLink *next; 43747c6ae99SBarry Smith PetscBool isdraw; 438cef07954SSatish Balay DM_Composite *com; 43947c6ae99SBarry Smith 44047c6ae99SBarry Smith PetscFunctionBegin; 441c688c046SMatthew G Knepley ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr); 44247c6ae99SBarry Smith if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 44347c6ae99SBarry Smith com = (DM_Composite*)dm->data; 44447c6ae99SBarry Smith next = com->next; 44547c6ae99SBarry Smith 446251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 44747c6ae99SBarry Smith if (!isdraw) { 44847c6ae99SBarry Smith /* do I really want to call this? */ 44947c6ae99SBarry Smith ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 45047c6ae99SBarry Smith } else { 45147c6ae99SBarry Smith PetscInt cnt = 0; 45247c6ae99SBarry Smith 45347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 45447c6ae99SBarry Smith while (next) { 45547c6ae99SBarry Smith Vec vec; 4569ae5db72SJed Brown PetscScalar *array; 45747c6ae99SBarry Smith PetscInt bs; 45847c6ae99SBarry Smith 4599ae5db72SJed Brown /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 4609ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); 4619ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 4629ae5db72SJed Brown ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr); 4639ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 46447c6ae99SBarry Smith ierr = VecView(vec,viewer);CHKERRQ(ierr); 46547c6ae99SBarry Smith ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 4669ae5db72SJed Brown ierr = VecResetArray(vec);CHKERRQ(ierr); 4679ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); 46847c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 46947c6ae99SBarry Smith cnt += bs; 47047c6ae99SBarry Smith next = next->next; 47147c6ae99SBarry Smith } 47247c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 47347c6ae99SBarry Smith } 47447c6ae99SBarry Smith PetscFunctionReturn(0); 47547c6ae99SBarry Smith } 47647c6ae99SBarry Smith EXTERN_C_END 47747c6ae99SBarry Smith 47847c6ae99SBarry Smith 47947c6ae99SBarry Smith #undef __FUNCT__ 4800c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite" 4817087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector_Composite(DM dm,Vec *gvec) 48247c6ae99SBarry Smith { 48347c6ae99SBarry Smith PetscErrorCode ierr; 48447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 48547c6ae99SBarry Smith 48647c6ae99SBarry Smith PetscFunctionBegin; 48747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 488d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 48947c6ae99SBarry Smith ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr); 490c688c046SMatthew G Knepley ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr); 49147c6ae99SBarry Smith ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr); 49247c6ae99SBarry Smith PetscFunctionReturn(0); 49347c6ae99SBarry Smith } 49447c6ae99SBarry Smith 49547c6ae99SBarry Smith #undef __FUNCT__ 4960c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite" 4977087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector_Composite(DM dm,Vec *lvec) 49847c6ae99SBarry Smith { 49947c6ae99SBarry Smith PetscErrorCode ierr; 50047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 50147c6ae99SBarry Smith 50247c6ae99SBarry Smith PetscFunctionBegin; 50347c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 50447c6ae99SBarry Smith if (!com->setup) { 505d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 50647c6ae99SBarry Smith } 50747c6ae99SBarry Smith ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr); 508c688c046SMatthew G Knepley ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr); 50947c6ae99SBarry Smith PetscFunctionReturn(0); 51047c6ae99SBarry Smith } 51147c6ae99SBarry Smith 51247c6ae99SBarry Smith #undef __FUNCT__ 5136eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings" 51447c6ae99SBarry Smith /*@C 5159ae5db72SJed Brown DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space 51647c6ae99SBarry Smith 51706ebdd98SJed Brown Collective on DM 51847c6ae99SBarry Smith 51947c6ae99SBarry Smith Input Parameter: 52047c6ae99SBarry Smith . dm - the packer object 52147c6ae99SBarry Smith 52247c6ae99SBarry Smith Output Parameters: 5239ae5db72SJed Brown . ltogs - the individual mappings for each packed vector. Note that this includes 5249ae5db72SJed Brown all the ghost points that individual ghosted DMDA's may have. 52547c6ae99SBarry Smith 52647c6ae99SBarry Smith Level: advanced 52747c6ae99SBarry Smith 52847c6ae99SBarry Smith Notes: 5296eb61c8cSJed Brown Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). 53047c6ae99SBarry Smith 5319ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 53247c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 53347c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 53447c6ae99SBarry Smith 53547c6ae99SBarry Smith @*/ 5367087cfbeSBarry Smith PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) 53747c6ae99SBarry Smith { 53847c6ae99SBarry Smith PetscErrorCode ierr; 53947c6ae99SBarry Smith PetscInt i,*idx,n,cnt; 54047c6ae99SBarry Smith struct DMCompositeLink *next; 54147c6ae99SBarry Smith PetscMPIInt rank; 54247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 54347c6ae99SBarry Smith 54447c6ae99SBarry Smith PetscFunctionBegin; 54547c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 546728e99d6SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 5479ae5db72SJed Brown ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr); 54847c6ae99SBarry Smith next = com->next; 54947c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 55047c6ae99SBarry Smith 55147c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 55247c6ae99SBarry Smith cnt = 0; 55347c6ae99SBarry Smith while (next) { 5546eb61c8cSJed Brown ISLocalToGlobalMapping ltog; 5556eb61c8cSJed Brown PetscMPIInt size; 55686994e45SJed Brown const PetscInt *suboff,*indices; 5576eb61c8cSJed Brown Vec global; 55847c6ae99SBarry Smith 5596eb61c8cSJed Brown /* Get sub-DM global indices for each local dof */ 5601411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); 5616eb61c8cSJed Brown ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); 56286994e45SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); 56347c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 56447c6ae99SBarry Smith 5656eb61c8cSJed Brown /* Get the offsets for the sub-DM global vector */ 5666eb61c8cSJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 5676eb61c8cSJed Brown ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); 5686eb61c8cSJed Brown ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr); 5696eb61c8cSJed Brown 5706eb61c8cSJed Brown /* Shift the sub-DM definition of the global space to the composite global space */ 5716eb61c8cSJed Brown for (i=0; i<n; i++) { 57286994e45SJed Brown PetscInt subi = indices[i],lo = 0,hi = size,t; 5736eb61c8cSJed Brown /* Binary search to find which rank owns subi */ 5746eb61c8cSJed Brown while (hi-lo > 1) { 5756eb61c8cSJed Brown t = lo + (hi-lo)/2; 5766eb61c8cSJed Brown if (suboff[t] > subi) hi = t; 5776eb61c8cSJed Brown else lo = t; 5786eb61c8cSJed Brown } 5796eb61c8cSJed Brown idx[i] = subi - suboff[lo] + next->grstarts[lo]; 5806eb61c8cSJed Brown } 58186994e45SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); 5826eb61c8cSJed Brown ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); 5836eb61c8cSJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 58447c6ae99SBarry Smith next = next->next; 58547c6ae99SBarry Smith cnt++; 58647c6ae99SBarry Smith } 58747c6ae99SBarry Smith PetscFunctionReturn(0); 58847c6ae99SBarry Smith } 58947c6ae99SBarry Smith 59047c6ae99SBarry Smith #undef __FUNCT__ 59187c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs" 59287c85e80SJed Brown /*@C 5939ae5db72SJed Brown DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 59487c85e80SJed Brown 59587c85e80SJed Brown Not Collective 59687c85e80SJed Brown 59787c85e80SJed Brown Input Arguments: 59887c85e80SJed Brown . dm - composite DM 59987c85e80SJed Brown 60087c85e80SJed Brown Output Arguments: 60187c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite 60287c85e80SJed Brown 60387c85e80SJed Brown Level: intermediate 60487c85e80SJed Brown 60587c85e80SJed Brown Notes: 60687c85e80SJed Brown At present, a composite local vector does not normally exist. This function is used to provide index sets for 60787c85e80SJed Brown MatGetLocalSubMatrix(). In the future, the scatters for each entry in the DMComposite may be be merged into a single 6089ae5db72SJed Brown scatter to a composite local vector. The user should not typically need to know which is being done. 60987c85e80SJed Brown 61087c85e80SJed Brown To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings(). 61187c85e80SJed Brown 61287c85e80SJed Brown To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs(). 61387c85e80SJed Brown 61487c85e80SJed Brown Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree(). 61587c85e80SJed Brown 61687c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef() 61787c85e80SJed Brown @*/ 6187087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalISs(DM dm,IS **is) 61987c85e80SJed Brown { 62087c85e80SJed Brown PetscErrorCode ierr; 62187c85e80SJed Brown DM_Composite *com = (DM_Composite*)dm->data; 62287c85e80SJed Brown struct DMCompositeLink *link; 62387c85e80SJed Brown PetscInt cnt,start; 62487c85e80SJed Brown 62587c85e80SJed Brown PetscFunctionBegin; 62687c85e80SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62787c85e80SJed Brown PetscValidPointer(is,2); 62887c85e80SJed Brown ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr); 62906ebdd98SJed Brown for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) { 630520db06cSJed Brown PetscInt bs; 6319ae5db72SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr); 6321411c6eeSJed Brown ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr); 633520db06cSJed Brown ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr); 634520db06cSJed Brown } 63587c85e80SJed Brown PetscFunctionReturn(0); 63687c85e80SJed Brown } 63787c85e80SJed Brown 63887c85e80SJed Brown #undef __FUNCT__ 63947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs" 64047c6ae99SBarry Smith /*@C 64147c6ae99SBarry Smith DMCompositeGetGlobalISs - Gets the index sets for each composed object 64247c6ae99SBarry Smith 64347c6ae99SBarry Smith Collective on DMComposite 64447c6ae99SBarry Smith 64547c6ae99SBarry Smith Input Parameter: 64647c6ae99SBarry Smith . dm - the packer object 64747c6ae99SBarry Smith 64847c6ae99SBarry Smith Output Parameters: 64947c6ae99SBarry Smith . is - the array of index sets 65047c6ae99SBarry Smith 65147c6ae99SBarry Smith Level: advanced 65247c6ae99SBarry Smith 65347c6ae99SBarry Smith Notes: 65447c6ae99SBarry Smith The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 65547c6ae99SBarry Smith 65647c6ae99SBarry Smith These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 65747c6ae99SBarry Smith 6586eb61c8cSJed Brown Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and 6596eb61c8cSJed Brown DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global 6606eb61c8cSJed Brown indices. 66147c6ae99SBarry Smith 6629ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 66347c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 66447c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 66547c6ae99SBarry Smith 66647c6ae99SBarry Smith @*/ 6676eb61c8cSJed Brown 6687087cfbeSBarry Smith PetscErrorCode DMCompositeGetGlobalISs(DM dm,IS *is[]) 66947c6ae99SBarry Smith { 67047c6ae99SBarry Smith PetscErrorCode ierr; 67147c6ae99SBarry Smith PetscInt cnt = 0,*idx,i; 67247c6ae99SBarry Smith struct DMCompositeLink *next; 67347c6ae99SBarry Smith PetscMPIInt rank; 67447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 67547c6ae99SBarry Smith 67647c6ae99SBarry Smith PetscFunctionBegin; 67747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6789ae5db72SJed Brown ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr); 67947c6ae99SBarry Smith next = com->next; 68047c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 68147c6ae99SBarry Smith 68247c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 68347c6ae99SBarry Smith while (next) { 68447c6ae99SBarry Smith ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 68547c6ae99SBarry Smith for (i=0; i<next->n; i++) idx[i] = next->grstart + i; 68647c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 68747c6ae99SBarry Smith cnt++; 68847c6ae99SBarry Smith next = next->next; 68947c6ae99SBarry Smith } 69047c6ae99SBarry Smith PetscFunctionReturn(0); 69147c6ae99SBarry Smith } 69247c6ae99SBarry Smith 6934d343eeaSMatthew G Knepley #undef __FUNCT__ 6944d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite" 69521c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields) 6964d343eeaSMatthew G Knepley { 6974d343eeaSMatthew G Knepley PetscInt nDM; 6984d343eeaSMatthew G Knepley DM *dms; 6994d343eeaSMatthew G Knepley PetscInt i; 7004d343eeaSMatthew G Knepley PetscErrorCode ierr; 7014d343eeaSMatthew G Knepley 7024d343eeaSMatthew G Knepley PetscFunctionBegin; 7034d343eeaSMatthew G Knepley ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 7048865f1eaSKarl Rupp if (numFields) *numFields = nDM; 7054d343eeaSMatthew G Knepley ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr); 7064d343eeaSMatthew G Knepley if (fieldNames) { 7074d343eeaSMatthew G Knepley ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr); 7084d343eeaSMatthew G Knepley ierr = PetscMalloc(nDM*sizeof(const char*), fieldNames);CHKERRQ(ierr); 7094d343eeaSMatthew G Knepley ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr); 7104d343eeaSMatthew G Knepley for (i=0; i<nDM; i++) { 7114d343eeaSMatthew G Knepley char buf[256]; 7124d343eeaSMatthew G Knepley const char *splitname; 7134d343eeaSMatthew G Knepley 7144d343eeaSMatthew G Knepley /* Split naming precedence: object name, prefix, number */ 7154d343eeaSMatthew G Knepley splitname = ((PetscObject) dm)->name; 7164d343eeaSMatthew G Knepley if (!splitname) { 7174d343eeaSMatthew G Knepley ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr); 7184d343eeaSMatthew G Knepley if (splitname) { 7194d343eeaSMatthew G Knepley size_t len; 7208caf3d72SBarry Smith ierr = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr); 7218caf3d72SBarry Smith buf[sizeof(buf) - 1] = 0; 7224d343eeaSMatthew G Knepley ierr = PetscStrlen(buf,&len);CHKERRQ(ierr); 7234d343eeaSMatthew G Knepley if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */ 7244d343eeaSMatthew G Knepley splitname = buf; 7254d343eeaSMatthew G Knepley } 7264d343eeaSMatthew G Knepley } 7274d343eeaSMatthew G Knepley if (!splitname) { 7288caf3d72SBarry Smith ierr = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr); 7294d343eeaSMatthew G Knepley splitname = buf; 7304d343eeaSMatthew G Knepley } 73121c9b008SJed Brown ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr); 7324d343eeaSMatthew G Knepley } 7334d343eeaSMatthew G Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 7344d343eeaSMatthew G Knepley } 7354d343eeaSMatthew G Knepley PetscFunctionReturn(0); 7364d343eeaSMatthew G Knepley } 7374d343eeaSMatthew G Knepley 738e7c4fc90SDmitry Karpeev /* 739e7c4fc90SDmitry Karpeev This could take over from DMCreateFieldIS(), as it is more general, 740e7c4fc90SDmitry Karpeev making DMCreateFieldIS() a special case -- calling with dmlist == PETSC_NULL; 741e7c4fc90SDmitry Karpeev At this point it's probably best to be less intrusive, however. 742e7c4fc90SDmitry Karpeev */ 743e7c4fc90SDmitry Karpeev #undef __FUNCT__ 74416621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite" 74516621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist) 746e7c4fc90SDmitry Karpeev { 747e7c4fc90SDmitry Karpeev PetscInt nDM; 748e7c4fc90SDmitry Karpeev PetscInt i; 749e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 750e7c4fc90SDmitry Karpeev 751e7c4fc90SDmitry Karpeev PetscFunctionBegin; 752e7c4fc90SDmitry Karpeev ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr); 753e7c4fc90SDmitry Karpeev if (dmlist) { 754e7c4fc90SDmitry Karpeev ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 755e7c4fc90SDmitry Karpeev ierr = PetscMalloc(nDM*sizeof(DM), dmlist);CHKERRQ(ierr); 756e7c4fc90SDmitry Karpeev ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr); 757e7c4fc90SDmitry Karpeev for (i=0; i<nDM; i++) { 758e7c4fc90SDmitry Karpeev ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr); 759e7c4fc90SDmitry Karpeev } 760e7c4fc90SDmitry Karpeev } 761e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 762e7c4fc90SDmitry Karpeev } 763e7c4fc90SDmitry Karpeev 764e7c4fc90SDmitry Karpeev 765e7c4fc90SDmitry Karpeev 76647c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 76747c6ae99SBarry Smith #undef __FUNCT__ 76847c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors" 76947c6ae99SBarry Smith /*@C 7709ae5db72SJed Brown DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite. 77147c6ae99SBarry Smith Use DMCompositeRestoreLocalVectors() to return them. 77247c6ae99SBarry Smith 77347c6ae99SBarry Smith Not Collective 77447c6ae99SBarry Smith 77547c6ae99SBarry Smith Input Parameter: 77647c6ae99SBarry Smith . dm - the packer object 77747c6ae99SBarry Smith 77847c6ae99SBarry Smith Output Parameter: 7799ae5db72SJed Brown . Vec ... - the individual sequential Vecs 78047c6ae99SBarry Smith 78147c6ae99SBarry Smith Level: advanced 78247c6ae99SBarry Smith 7839ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 7846eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 78547c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 78647c6ae99SBarry Smith 78747c6ae99SBarry Smith @*/ 7887087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalVectors(DM dm,...) 78947c6ae99SBarry Smith { 79047c6ae99SBarry Smith va_list Argp; 79147c6ae99SBarry Smith PetscErrorCode ierr; 79247c6ae99SBarry Smith struct DMCompositeLink *next; 79347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 79447c6ae99SBarry Smith 79547c6ae99SBarry Smith PetscFunctionBegin; 79647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 79747c6ae99SBarry Smith next = com->next; 79847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 79947c6ae99SBarry Smith va_start(Argp,dm); 80047c6ae99SBarry Smith while (next) { 80147c6ae99SBarry Smith Vec *vec; 80247c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 80306930112SJed Brown if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);} 80447c6ae99SBarry Smith next = next->next; 80547c6ae99SBarry Smith } 80647c6ae99SBarry Smith va_end(Argp); 80747c6ae99SBarry Smith PetscFunctionReturn(0); 80847c6ae99SBarry Smith } 80947c6ae99SBarry Smith 81047c6ae99SBarry Smith #undef __FUNCT__ 81147c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors" 81247c6ae99SBarry Smith /*@C 8139ae5db72SJed Brown DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite. 81447c6ae99SBarry Smith 81547c6ae99SBarry Smith Not Collective 81647c6ae99SBarry Smith 81747c6ae99SBarry Smith Input Parameter: 81847c6ae99SBarry Smith . dm - the packer object 81947c6ae99SBarry Smith 82047c6ae99SBarry Smith Output Parameter: 8219ae5db72SJed Brown . Vec ... - the individual sequential Vecs 82247c6ae99SBarry Smith 82347c6ae99SBarry Smith Level: advanced 82447c6ae99SBarry Smith 8259ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 8266eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 82747c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 82847c6ae99SBarry Smith 82947c6ae99SBarry Smith @*/ 8307087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreLocalVectors(DM dm,...) 83147c6ae99SBarry Smith { 83247c6ae99SBarry Smith va_list Argp; 83347c6ae99SBarry Smith PetscErrorCode ierr; 83447c6ae99SBarry Smith struct DMCompositeLink *next; 83547c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 83647c6ae99SBarry Smith 83747c6ae99SBarry Smith PetscFunctionBegin; 83847c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 83947c6ae99SBarry Smith next = com->next; 84047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 84147c6ae99SBarry Smith va_start(Argp,dm); 84247c6ae99SBarry Smith while (next) { 84347c6ae99SBarry Smith Vec *vec; 84447c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 84506930112SJed Brown if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);} 84647c6ae99SBarry Smith next = next->next; 84747c6ae99SBarry Smith } 84847c6ae99SBarry Smith va_end(Argp); 84947c6ae99SBarry Smith PetscFunctionReturn(0); 85047c6ae99SBarry Smith } 85147c6ae99SBarry Smith 85247c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 85347c6ae99SBarry Smith #undef __FUNCT__ 85447c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries" 85547c6ae99SBarry Smith /*@C 8569ae5db72SJed Brown DMCompositeGetEntries - Gets the DM for each entry in a DMComposite. 85747c6ae99SBarry Smith 85847c6ae99SBarry Smith Not Collective 85947c6ae99SBarry Smith 86047c6ae99SBarry Smith Input Parameter: 86147c6ae99SBarry Smith . dm - the packer object 86247c6ae99SBarry Smith 86347c6ae99SBarry Smith Output Parameter: 8649ae5db72SJed Brown . DM ... - the individual entries (DMs) 86547c6ae99SBarry Smith 86647c6ae99SBarry Smith Level: advanced 86747c6ae99SBarry Smith 8682fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray() 8696eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 87047c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 87147c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 87247c6ae99SBarry Smith 87347c6ae99SBarry Smith @*/ 8747087cfbeSBarry Smith PetscErrorCode DMCompositeGetEntries(DM dm,...) 87547c6ae99SBarry Smith { 87647c6ae99SBarry Smith va_list Argp; 87747c6ae99SBarry Smith struct DMCompositeLink *next; 87847c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 87947c6ae99SBarry Smith 88047c6ae99SBarry Smith PetscFunctionBegin; 88147c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88247c6ae99SBarry Smith next = com->next; 88347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 88447c6ae99SBarry Smith va_start(Argp,dm); 88547c6ae99SBarry Smith while (next) { 88647c6ae99SBarry Smith DM *dmn; 88747c6ae99SBarry Smith dmn = va_arg(Argp, DM*); 8889ae5db72SJed Brown if (dmn) *dmn = next->dm; 88947c6ae99SBarry Smith next = next->next; 89047c6ae99SBarry Smith } 89147c6ae99SBarry Smith va_end(Argp); 89247c6ae99SBarry Smith PetscFunctionReturn(0); 89347c6ae99SBarry Smith } 89447c6ae99SBarry Smith 89547c6ae99SBarry Smith #undef __FUNCT__ 8962fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray" 897dbab29e1SMark F. Adams /*@C 8982fa5ba8aSJed Brown DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite. 8992fa5ba8aSJed Brown 9002fa5ba8aSJed Brown Not Collective 9012fa5ba8aSJed Brown 9022fa5ba8aSJed Brown Input Parameter: 9032fa5ba8aSJed Brown + dm - the packer object 9042fa5ba8aSJed Brown - dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output 9052fa5ba8aSJed Brown 9062fa5ba8aSJed Brown Level: advanced 9072fa5ba8aSJed Brown 9082fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries() 9092fa5ba8aSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 9102fa5ba8aSJed Brown DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 9112fa5ba8aSJed Brown DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 9122fa5ba8aSJed Brown 9132fa5ba8aSJed Brown @*/ 9142fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[]) 9152fa5ba8aSJed Brown { 9162fa5ba8aSJed Brown struct DMCompositeLink *next; 9172fa5ba8aSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 9182fa5ba8aSJed Brown PetscInt i; 9192fa5ba8aSJed Brown 9202fa5ba8aSJed Brown PetscFunctionBegin; 9212fa5ba8aSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9222fa5ba8aSJed Brown /* loop over packed objects, handling one at at time */ 9232fa5ba8aSJed Brown for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm; 9242fa5ba8aSJed Brown PetscFunctionReturn(0); 9252fa5ba8aSJed Brown } 9262fa5ba8aSJed Brown 9272fa5ba8aSJed Brown #undef __FUNCT__ 9280c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite" 9297087cfbeSBarry Smith PetscErrorCode DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine) 93047c6ae99SBarry Smith { 93147c6ae99SBarry Smith PetscErrorCode ierr; 93247c6ae99SBarry Smith struct DMCompositeLink *next; 93347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmi->data; 93447c6ae99SBarry Smith DM dm; 93547c6ae99SBarry Smith 93647c6ae99SBarry Smith PetscFunctionBegin; 93747c6ae99SBarry Smith PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 9382ee06e3bSJed Brown if (comm == MPI_COMM_NULL) comm = ((PetscObject)dmi)->comm; 9392ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 94047c6ae99SBarry Smith next = com->next; 94147c6ae99SBarry Smith ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 94247c6ae99SBarry Smith 94347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 94447c6ae99SBarry Smith while (next) { 94547c6ae99SBarry Smith ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 94647c6ae99SBarry Smith ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 94747c6ae99SBarry Smith ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 94847c6ae99SBarry Smith next = next->next; 94947c6ae99SBarry Smith } 95047c6ae99SBarry Smith PetscFunctionReturn(0); 95147c6ae99SBarry Smith } 95247c6ae99SBarry Smith 95314354c39SJed Brown #undef __FUNCT__ 95414354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite" 95514354c39SJed Brown PetscErrorCode DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine) 95614354c39SJed Brown { 95714354c39SJed Brown PetscErrorCode ierr; 95814354c39SJed Brown struct DMCompositeLink *next; 95914354c39SJed Brown DM_Composite *com = (DM_Composite*)dmi->data; 96014354c39SJed Brown DM dm; 96114354c39SJed Brown 96214354c39SJed Brown PetscFunctionBegin; 96314354c39SJed Brown PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 9642ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 9652ee06e3bSJed Brown if (comm == MPI_COMM_NULL) { 96625296bd5SBarry Smith ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 96725296bd5SBarry Smith } 96814354c39SJed Brown next = com->next; 96914354c39SJed Brown ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 97014354c39SJed Brown 97114354c39SJed Brown /* loop over packed objects, handling one at at time */ 97214354c39SJed Brown while (next) { 97314354c39SJed Brown ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr); 97414354c39SJed Brown ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 97514354c39SJed Brown ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 97614354c39SJed Brown next = next->next; 97714354c39SJed Brown } 97814354c39SJed Brown PetscFunctionReturn(0); 97914354c39SJed Brown } 98047c6ae99SBarry Smith 98147c6ae99SBarry Smith #undef __FUNCT__ 982e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite" 983e727c939SJed Brown PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) 98447c6ae99SBarry Smith { 98547c6ae99SBarry Smith PetscErrorCode ierr; 9869ae5db72SJed Brown PetscInt m,n,M,N,nDM,i; 98747c6ae99SBarry Smith struct DMCompositeLink *nextc; 98847c6ae99SBarry Smith struct DMCompositeLink *nextf; 98925296bd5SBarry Smith Vec gcoarse,gfine,*vecs; 99047c6ae99SBarry Smith DM_Composite *comcoarse = (DM_Composite*)coarse->data; 99147c6ae99SBarry Smith DM_Composite *comfine = (DM_Composite*)fine->data; 9929ae5db72SJed Brown Mat *mats; 99347c6ae99SBarry Smith 99447c6ae99SBarry Smith PetscFunctionBegin; 99547c6ae99SBarry Smith PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 99647c6ae99SBarry Smith PetscValidHeaderSpecific(fine,DM_CLASSID,2); 997f692024eSJed Brown ierr = DMSetUp(coarse);CHKERRQ(ierr); 998f692024eSJed Brown ierr = DMSetUp(fine);CHKERRQ(ierr); 99947c6ae99SBarry Smith /* use global vectors only for determining matrix layout */ 10009ae5db72SJed Brown ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 10019ae5db72SJed Brown ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); 100247c6ae99SBarry Smith ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 100347c6ae99SBarry Smith ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 100447c6ae99SBarry Smith ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 100547c6ae99SBarry Smith ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 10069ae5db72SJed Brown ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 10079ae5db72SJed Brown ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); 100847c6ae99SBarry Smith 10099ae5db72SJed Brown nDM = comfine->nDM; 10109ae5db72SJed 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); 10119ae5db72SJed Brown ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr); 10129ae5db72SJed Brown ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr); 101325296bd5SBarry Smith if (v) { 101425296bd5SBarry Smith ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr); 101525296bd5SBarry Smith ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr); 101625296bd5SBarry Smith } 101747c6ae99SBarry Smith 101847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 10199ae5db72SJed Brown for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { 102025296bd5SBarry Smith if (!v) { 1021e727c939SJed Brown ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr); 102225296bd5SBarry Smith } else { 102325296bd5SBarry Smith ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); 102425296bd5SBarry Smith } 102547c6ae99SBarry Smith } 10269ae5db72SJed Brown ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr); 102725296bd5SBarry Smith if (v) { 102825296bd5SBarry Smith ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr); 102925296bd5SBarry Smith } 10309ae5db72SJed Brown for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} 10319ae5db72SJed Brown ierr = PetscFree(mats);CHKERRQ(ierr); 103225296bd5SBarry Smith if (v) { 103325296bd5SBarry Smith for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} 103425296bd5SBarry Smith ierr = PetscFree(vecs);CHKERRQ(ierr); 103525296bd5SBarry Smith } 103647c6ae99SBarry Smith PetscFunctionReturn(0); 103747c6ae99SBarry Smith } 103847c6ae99SBarry Smith 103947c6ae99SBarry Smith #undef __FUNCT__ 10401411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite" 10411411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm) 10421411c6eeSJed Brown { 10431411c6eeSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 10441411c6eeSJed Brown ISLocalToGlobalMapping *ltogs; 1045f7efa3c7SJed Brown PetscInt i; 10461411c6eeSJed Brown PetscErrorCode ierr; 10471411c6eeSJed Brown 10481411c6eeSJed Brown PetscFunctionBegin; 10491411c6eeSJed Brown /* Set the ISLocalToGlobalMapping on the new matrix */ 10501411c6eeSJed Brown ierr = DMCompositeGetISLocalToGlobalMappings(dm,<ogs);CHKERRQ(ierr); 10519ae5db72SJed Brown ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr); 10529ae5db72SJed Brown for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(<ogs[i]);CHKERRQ(ierr);} 10531411c6eeSJed Brown ierr = PetscFree(ltogs);CHKERRQ(ierr); 10541411c6eeSJed Brown PetscFunctionReturn(0); 10551411c6eeSJed Brown } 10561411c6eeSJed Brown 10571411c6eeSJed Brown 10581411c6eeSJed Brown #undef __FUNCT__ 1059e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite" 106019fd82e9SBarry Smith PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring) 106147c6ae99SBarry Smith { 106247c6ae99SBarry Smith PetscErrorCode ierr; 106347c6ae99SBarry Smith PetscInt n,i,cnt; 106447c6ae99SBarry Smith ISColoringValue *colors; 106547c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 106647c6ae99SBarry Smith ISColoringValue maxcol = 0; 106747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 106847c6ae99SBarry Smith 106947c6ae99SBarry Smith PetscFunctionBegin; 107047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10719805c61eSBarry Smith if (ctype == IS_COLORING_GHOSTED) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Only global coloring supported"); 1072e3247f34SBarry Smith else if (ctype == IS_COLORING_GLOBAL) { 107347c6ae99SBarry Smith n = com->n; 107447c6ae99SBarry Smith } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 107547c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 107647c6ae99SBarry Smith 1077671f6225SBarry Smith ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); 107847c6ae99SBarry Smith if (dense) { 107947c6ae99SBarry Smith for (i=0; i<n; i++) { 108047c6ae99SBarry Smith colors[i] = (ISColoringValue)(com->rstart + i); 108147c6ae99SBarry Smith } 108247c6ae99SBarry Smith maxcol = com->N; 108347c6ae99SBarry Smith } else { 108447c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 108547c6ae99SBarry Smith PetscMPIInt rank; 108647c6ae99SBarry Smith 108747c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 108847c6ae99SBarry Smith cnt = 0; 108947c6ae99SBarry Smith while (next) { 109047c6ae99SBarry Smith ISColoring lcoloring; 109147c6ae99SBarry Smith 1092e727c939SJed Brown ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr); 109347c6ae99SBarry Smith for (i=0; i<lcoloring->N; i++) { 109447c6ae99SBarry Smith colors[cnt++] = maxcol + lcoloring->colors[i]; 109547c6ae99SBarry Smith } 109647c6ae99SBarry Smith maxcol += lcoloring->n; 1097fcfd50ebSBarry Smith ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); 109847c6ae99SBarry Smith next = next->next; 109947c6ae99SBarry Smith } 110047c6ae99SBarry Smith } 110147c6ae99SBarry Smith ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr); 110247c6ae99SBarry Smith PetscFunctionReturn(0); 110347c6ae99SBarry Smith } 110447c6ae99SBarry Smith 110547c6ae99SBarry Smith #undef __FUNCT__ 11060c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite" 11077087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 110847c6ae99SBarry Smith { 110947c6ae99SBarry Smith PetscErrorCode ierr; 111047c6ae99SBarry Smith struct DMCompositeLink *next; 111147c6ae99SBarry Smith PetscInt cnt = 3; 111247c6ae99SBarry Smith PetscMPIInt rank; 111347c6ae99SBarry Smith PetscScalar *garray,*larray; 111447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 111547c6ae99SBarry Smith 111647c6ae99SBarry Smith PetscFunctionBegin; 111747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 111847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 111947c6ae99SBarry Smith next = com->next; 112047c6ae99SBarry Smith if (!com->setup) { 1121d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 112247c6ae99SBarry Smith } 112347c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 112447c6ae99SBarry Smith ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 112547c6ae99SBarry Smith ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 112647c6ae99SBarry Smith 112747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 112847c6ae99SBarry Smith while (next) { 112947c6ae99SBarry Smith Vec local,global; 113047c6ae99SBarry Smith PetscInt N; 113147c6ae99SBarry Smith 113247c6ae99SBarry Smith ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 113347c6ae99SBarry Smith ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 113447c6ae99SBarry Smith ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 113547c6ae99SBarry Smith ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 113647c6ae99SBarry Smith ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 113747c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 113847c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 113947c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 114047c6ae99SBarry Smith ierr = VecResetArray(local);CHKERRQ(ierr); 114147c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 114247c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); 114347c6ae99SBarry Smith cnt++; 114406ebdd98SJed Brown larray += next->nlocal; 114547c6ae99SBarry Smith next = next->next; 114647c6ae99SBarry Smith } 114747c6ae99SBarry Smith 114847c6ae99SBarry Smith ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr); 114947c6ae99SBarry Smith ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr); 115047c6ae99SBarry Smith PetscFunctionReturn(0); 115147c6ae99SBarry Smith } 115247c6ae99SBarry Smith 115347c6ae99SBarry Smith #undef __FUNCT__ 11540c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite" 11557087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 11560c010503SBarry Smith { 11570c010503SBarry Smith PetscFunctionBegin; 11580c010503SBarry Smith PetscFunctionReturn(0); 11590c010503SBarry Smith } 116047c6ae99SBarry Smith 11616ae3a549SBarry Smith /*MC 11626ae3a549SBarry Smith DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs 11636ae3a549SBarry Smith 11646ae3a549SBarry Smith 11656ae3a549SBarry Smith 11666ae3a549SBarry Smith Level: intermediate 11676ae3a549SBarry Smith 11686ae3a549SBarry Smith .seealso: DMType, DMCOMPOSITE, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate() 11696ae3a549SBarry Smith M*/ 11706ae3a549SBarry Smith 11716ae3a549SBarry Smith 1172a4121054SBarry Smith EXTERN_C_BEGIN 1173a4121054SBarry Smith #undef __FUNCT__ 1174a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite" 11757087cfbeSBarry Smith PetscErrorCode DMCreate_Composite(DM p) 1176a4121054SBarry Smith { 1177a4121054SBarry Smith PetscErrorCode ierr; 1178a4121054SBarry Smith DM_Composite *com; 1179a4121054SBarry Smith 1180a4121054SBarry Smith PetscFunctionBegin; 1181a4121054SBarry Smith ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr); 1182a4121054SBarry Smith p->data = com; 1183a4121054SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 1184a4121054SBarry Smith com->n = 0; 1185a4121054SBarry Smith com->next = PETSC_NULL; 1186a4121054SBarry Smith com->nDM = 0; 1187a4121054SBarry Smith 1188a4121054SBarry Smith p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1189a4121054SBarry Smith p->ops->createlocalvector = DMCreateLocalVector_Composite; 11901411c6eeSJed Brown p->ops->createlocaltoglobalmapping = DMCreateLocalToGlobalMapping_Composite; 11911411c6eeSJed Brown p->ops->createlocaltoglobalmappingblock = 0; 11924d343eeaSMatthew G Knepley p->ops->createfieldis = DMCreateFieldIS_Composite; 119316621825SDmitry Karpeev p->ops->createfielddecomposition = DMCreateFieldDecomposition_Composite; 1194a4121054SBarry Smith p->ops->refine = DMRefine_Composite; 119514354c39SJed Brown p->ops->coarsen = DMCoarsen_Composite; 119625296bd5SBarry Smith p->ops->createinterpolation = DMCreateInterpolation_Composite; 119725296bd5SBarry Smith p->ops->creatematrix = DMCreateMatrix_Composite; 1198e727c939SJed Brown p->ops->getcoloring = DMCreateColoring_Composite; 1199a4121054SBarry Smith p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1200a4121054SBarry Smith p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 1201a4121054SBarry Smith p->ops->destroy = DMDestroy_Composite; 1202a4121054SBarry Smith p->ops->view = DMView_Composite; 1203a4121054SBarry Smith p->ops->setup = DMSetUp_Composite; 1204a4121054SBarry Smith PetscFunctionReturn(0); 1205a4121054SBarry Smith } 1206a4121054SBarry Smith EXTERN_C_END 1207a4121054SBarry Smith 12080c010503SBarry Smith #undef __FUNCT__ 12090c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate" 12100c010503SBarry Smith /*@C 12110c010503SBarry Smith DMCompositeCreate - Creates a vector packer, used to generate "composite" 12120c010503SBarry Smith vectors made up of several subvectors. 12130c010503SBarry Smith 12140c010503SBarry Smith Collective on MPI_Comm 121547c6ae99SBarry Smith 121647c6ae99SBarry Smith Input Parameter: 12170c010503SBarry Smith . comm - the processors that will share the global vector 12180c010503SBarry Smith 12190c010503SBarry Smith Output Parameters: 12200c010503SBarry Smith . packer - the packer object 122147c6ae99SBarry Smith 122247c6ae99SBarry Smith Level: advanced 122347c6ae99SBarry Smith 12249ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), 12256eb61c8cSJed Brown DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess() 122647c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 122747c6ae99SBarry Smith 122847c6ae99SBarry Smith @*/ 12297087cfbeSBarry Smith PetscErrorCode DMCompositeCreate(MPI_Comm comm,DM *packer) 123047c6ae99SBarry Smith { 12310c010503SBarry Smith PetscErrorCode ierr; 12320c010503SBarry Smith 123347c6ae99SBarry Smith PetscFunctionBegin; 12340c010503SBarry Smith PetscValidPointer(packer,2); 1235a4121054SBarry Smith ierr = DMCreate(comm,packer);CHKERRQ(ierr); 1236a4121054SBarry Smith ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr); 123747c6ae99SBarry Smith PetscFunctionReturn(0); 123847c6ae99SBarry Smith } 1239