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" 12647c6ae99SBarry Smith /*@C 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; 14447c6ae99SBarry Smith PetscFunctionBegin; 14547c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 14647c6ae99SBarry Smith *nDM = com->nDM; 14747c6ae99SBarry Smith PetscFunctionReturn(0); 14847c6ae99SBarry Smith } 14947c6ae99SBarry Smith 15047c6ae99SBarry Smith 15147c6ae99SBarry Smith #undef __FUNCT__ 15247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess" 15347c6ae99SBarry Smith /*@C 15447c6ae99SBarry Smith DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 15547c6ae99SBarry Smith representation. 15647c6ae99SBarry Smith 15747c6ae99SBarry Smith Collective on DMComposite 15847c6ae99SBarry Smith 1599ae5db72SJed Brown Input Parameters: 16047c6ae99SBarry Smith + dm - the packer object 1619ae5db72SJed Brown - gvec - the global vector 1629ae5db72SJed Brown 1639ae5db72SJed Brown Output Parameters: 1649ae5db72SJed Brown . Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed 16547c6ae99SBarry Smith 16647c6ae99SBarry Smith Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them 16747c6ae99SBarry Smith 16847c6ae99SBarry Smith Level: advanced 16947c6ae99SBarry Smith 17047c6ae99SBarry Smith @*/ 1717087cfbeSBarry Smith PetscErrorCode DMCompositeGetAccess(DM dm,Vec gvec,...) 17247c6ae99SBarry Smith { 17347c6ae99SBarry Smith va_list Argp; 17447c6ae99SBarry Smith PetscErrorCode ierr; 17547c6ae99SBarry Smith struct DMCompositeLink *next; 17647c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 17747c6ae99SBarry Smith 17847c6ae99SBarry Smith PetscFunctionBegin; 17947c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18047c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 18147c6ae99SBarry Smith next = com->next; 18247c6ae99SBarry Smith if (!com->setup) { 183d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 18447c6ae99SBarry Smith } 18547c6ae99SBarry Smith 18647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 18747c6ae99SBarry Smith va_start(Argp,gvec); 18847c6ae99SBarry Smith while (next) { 18947c6ae99SBarry Smith Vec *vec; 19047c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 1919ae5db72SJed Brown if (vec) { 1929ae5db72SJed Brown PetscScalar *array; 1939ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr); 1949ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 1959ae5db72SJed Brown ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 1969ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 19747c6ae99SBarry Smith } 19847c6ae99SBarry Smith next = next->next; 19947c6ae99SBarry Smith } 20047c6ae99SBarry Smith va_end(Argp); 20147c6ae99SBarry Smith PetscFunctionReturn(0); 20247c6ae99SBarry Smith } 20347c6ae99SBarry Smith 20447c6ae99SBarry Smith #undef __FUNCT__ 20547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess" 20647c6ae99SBarry Smith /*@C 207aa219208SBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() 20847c6ae99SBarry Smith representation. 20947c6ae99SBarry Smith 21047c6ae99SBarry Smith Collective on DMComposite 21147c6ae99SBarry Smith 2129ae5db72SJed Brown Input Parameters: 21347c6ae99SBarry Smith + dm - the packer object 21447c6ae99SBarry Smith . gvec - the global vector 2159ae5db72SJed Brown - Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed 21647c6ae99SBarry Smith 21747c6ae99SBarry Smith Level: advanced 21847c6ae99SBarry Smith 2199ae5db72SJed Brown .seealso DMCompositeAddDM(), DMCreateGlobalVector(), 2206eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), 221aa219208SBarry Smith DMCompositeRestoreAccess(), DMCompositeGetAccess() 22247c6ae99SBarry Smith 22347c6ae99SBarry Smith @*/ 2247087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) 22547c6ae99SBarry Smith { 22647c6ae99SBarry Smith va_list Argp; 22747c6ae99SBarry Smith PetscErrorCode ierr; 22847c6ae99SBarry Smith struct DMCompositeLink *next; 22947c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 23047c6ae99SBarry Smith 23147c6ae99SBarry Smith PetscFunctionBegin; 23247c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 23347c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 23447c6ae99SBarry Smith next = com->next; 23547c6ae99SBarry Smith if (!com->setup) { 236d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 23747c6ae99SBarry Smith } 23847c6ae99SBarry Smith 23947c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 24047c6ae99SBarry Smith va_start(Argp,gvec); 24147c6ae99SBarry Smith while (next) { 24247c6ae99SBarry Smith Vec *vec; 24347c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 2449ae5db72SJed Brown if (vec) { 2459ae5db72SJed Brown ierr = VecResetArray(*vec);CHKERRQ(ierr); 2469ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); 24747c6ae99SBarry Smith } 24847c6ae99SBarry Smith next = next->next; 24947c6ae99SBarry Smith } 25047c6ae99SBarry Smith va_end(Argp); 25147c6ae99SBarry Smith PetscFunctionReturn(0); 25247c6ae99SBarry Smith } 25347c6ae99SBarry Smith 25447c6ae99SBarry Smith #undef __FUNCT__ 25547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter" 25647c6ae99SBarry Smith /*@C 25747c6ae99SBarry Smith DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 25847c6ae99SBarry Smith 25947c6ae99SBarry Smith Collective on DMComposite 26047c6ae99SBarry Smith 2619ae5db72SJed Brown Input Parameters: 26247c6ae99SBarry Smith + dm - the packer object 26347c6ae99SBarry Smith . gvec - the global vector 2649ae5db72SJed Brown - Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed 26547c6ae99SBarry Smith 26647c6ae99SBarry Smith Level: advanced 26747c6ae99SBarry Smith 2689ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 2696eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 27047c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 27147c6ae99SBarry Smith 27247c6ae99SBarry Smith @*/ 2737087cfbeSBarry Smith PetscErrorCode DMCompositeScatter(DM dm,Vec gvec,...) 27447c6ae99SBarry Smith { 27547c6ae99SBarry Smith va_list Argp; 27647c6ae99SBarry Smith PetscErrorCode ierr; 27747c6ae99SBarry Smith struct DMCompositeLink *next; 2788fd8f222SJed Brown PetscInt cnt; 27947c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 28047c6ae99SBarry Smith 28147c6ae99SBarry Smith PetscFunctionBegin; 28247c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 28347c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 28447c6ae99SBarry Smith if (!com->setup) { 285d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 28647c6ae99SBarry Smith } 28747c6ae99SBarry Smith 28847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 28947c6ae99SBarry Smith va_start(Argp,gvec); 2908fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 2919ae5db72SJed Brown Vec local; 2929ae5db72SJed Brown local = va_arg(Argp, Vec); 2939ae5db72SJed Brown if (local) { 2949ae5db72SJed Brown Vec global; 29547c6ae99SBarry Smith PetscScalar *array; 2969ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 2979ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 2989ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 2999ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 3009ae5db72SJed Brown ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 3019ae5db72SJed Brown ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 3029ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 3039ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 3049ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 30547c6ae99SBarry Smith } 30647c6ae99SBarry Smith } 30747c6ae99SBarry Smith va_end(Argp); 30847c6ae99SBarry Smith PetscFunctionReturn(0); 30947c6ae99SBarry Smith } 31047c6ae99SBarry Smith 31147c6ae99SBarry Smith #undef __FUNCT__ 31247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather" 31347c6ae99SBarry Smith /*@C 31447c6ae99SBarry Smith DMCompositeGather - Gathers into a global packed vector from its individual local vectors 31547c6ae99SBarry Smith 31647c6ae99SBarry Smith Collective on DMComposite 31747c6ae99SBarry Smith 31847c6ae99SBarry Smith Input Parameter: 31947c6ae99SBarry Smith + dm - the packer object 32047c6ae99SBarry Smith . gvec - the global vector 3219ae5db72SJed Brown - Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed 32247c6ae99SBarry Smith 32347c6ae99SBarry Smith Level: advanced 32447c6ae99SBarry Smith 3259ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 3266eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 32747c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 32847c6ae99SBarry Smith 32947c6ae99SBarry Smith @*/ 3307087cfbeSBarry Smith PetscErrorCode DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...) 33147c6ae99SBarry Smith { 33247c6ae99SBarry Smith va_list Argp; 33347c6ae99SBarry Smith PetscErrorCode ierr; 33447c6ae99SBarry Smith struct DMCompositeLink *next; 33547c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 3368fd8f222SJed Brown PetscInt cnt; 33747c6ae99SBarry Smith 33847c6ae99SBarry Smith PetscFunctionBegin; 33947c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 34047c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 34147c6ae99SBarry Smith if (!com->setup) { 342d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 34347c6ae99SBarry Smith } 34447c6ae99SBarry Smith 34547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 346df0c820aSJed Brown va_start(Argp,imode); 3478fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 3489ae5db72SJed Brown Vec local; 3499ae5db72SJed Brown local = va_arg(Argp, Vec); 3509ae5db72SJed Brown if (local) { 35147c6ae99SBarry Smith PetscScalar *array; 3529ae5db72SJed Brown Vec global; 3539ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 3549ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 3559ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 3569ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 3579ae5db72SJed Brown ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); 3589ae5db72SJed Brown ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); 3599ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 3609ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 3619ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 36247c6ae99SBarry Smith } 36347c6ae99SBarry Smith } 36447c6ae99SBarry Smith va_end(Argp); 36547c6ae99SBarry Smith PetscFunctionReturn(0); 36647c6ae99SBarry Smith } 36747c6ae99SBarry Smith 36847c6ae99SBarry Smith #undef __FUNCT__ 36947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM" 37047c6ae99SBarry Smith /*@C 371aa219208SBarry Smith DMCompositeAddDM - adds a DM vector to a DMComposite 37247c6ae99SBarry Smith 37347c6ae99SBarry Smith Collective on DMComposite 37447c6ae99SBarry Smith 37547c6ae99SBarry Smith Input Parameter: 37647c6ae99SBarry Smith + dm - the packer object 37747c6ae99SBarry Smith - dm - the DM object, if the DM is a da you will need to caste it with a (DM) 37847c6ae99SBarry Smith 37947c6ae99SBarry Smith Level: advanced 38047c6ae99SBarry Smith 3810c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), 3826eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 38347c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 38447c6ae99SBarry Smith 38547c6ae99SBarry Smith @*/ 3867087cfbeSBarry Smith PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) 38747c6ae99SBarry Smith { 38847c6ae99SBarry Smith PetscErrorCode ierr; 38906ebdd98SJed Brown PetscInt n,nlocal; 39047c6ae99SBarry Smith struct DMCompositeLink *mine,*next; 39106ebdd98SJed Brown Vec global,local; 39247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmc->data; 39347c6ae99SBarry Smith 39447c6ae99SBarry Smith PetscFunctionBegin; 39547c6ae99SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 39647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 39747c6ae99SBarry Smith next = com->next; 398aa219208SBarry Smith if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); 39947c6ae99SBarry Smith 40047c6ae99SBarry Smith /* create new link */ 40147c6ae99SBarry Smith ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); 40247c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 40347c6ae99SBarry Smith ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 40447c6ae99SBarry Smith ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 40547c6ae99SBarry Smith ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 40606ebdd98SJed Brown ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); 40706ebdd98SJed Brown ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); 40806ebdd98SJed Brown ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); 40947c6ae99SBarry Smith mine->n = n; 41006ebdd98SJed Brown mine->nlocal = nlocal; 41147c6ae99SBarry Smith mine->dm = dm; 41247c6ae99SBarry Smith mine->next = PETSC_NULL; 41347c6ae99SBarry Smith com->n += n; 41447c6ae99SBarry Smith 41547c6ae99SBarry Smith /* add to end of list */ 41647c6ae99SBarry Smith if (!next) { 41747c6ae99SBarry Smith com->next = mine; 41847c6ae99SBarry Smith } else { 41947c6ae99SBarry Smith while (next->next) next = next->next; 42047c6ae99SBarry Smith next->next = mine; 42147c6ae99SBarry Smith } 42247c6ae99SBarry Smith com->nDM++; 42347c6ae99SBarry Smith com->nmine++; 42447c6ae99SBarry Smith PetscFunctionReturn(0); 42547c6ae99SBarry Smith } 42647c6ae99SBarry Smith 4277087cfbeSBarry Smith extern PetscErrorCode VecView_MPI(Vec,PetscViewer); 42847c6ae99SBarry Smith EXTERN_C_BEGIN 42947c6ae99SBarry Smith #undef __FUNCT__ 43047c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite" 4317087cfbeSBarry Smith PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) 43247c6ae99SBarry Smith { 43347c6ae99SBarry Smith DM dm; 43447c6ae99SBarry Smith PetscErrorCode ierr; 43547c6ae99SBarry Smith struct DMCompositeLink *next; 43647c6ae99SBarry Smith PetscBool isdraw; 437cef07954SSatish Balay DM_Composite *com; 43847c6ae99SBarry Smith 43947c6ae99SBarry Smith PetscFunctionBegin; 440*c688c046SMatthew G Knepley ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr); 44147c6ae99SBarry Smith if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 44247c6ae99SBarry Smith com = (DM_Composite*)dm->data; 44347c6ae99SBarry Smith next = com->next; 44447c6ae99SBarry Smith 445251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 44647c6ae99SBarry Smith if (!isdraw) { 44747c6ae99SBarry Smith /* do I really want to call this? */ 44847c6ae99SBarry Smith ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 44947c6ae99SBarry Smith } else { 45047c6ae99SBarry Smith PetscInt cnt = 0; 45147c6ae99SBarry Smith 45247c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 45347c6ae99SBarry Smith while (next) { 45447c6ae99SBarry Smith Vec vec; 4559ae5db72SJed Brown PetscScalar *array; 45647c6ae99SBarry Smith PetscInt bs; 45747c6ae99SBarry Smith 4589ae5db72SJed Brown /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 4599ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); 4609ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 4619ae5db72SJed Brown ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr); 4629ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 46347c6ae99SBarry Smith ierr = VecView(vec,viewer);CHKERRQ(ierr); 46447c6ae99SBarry Smith ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 4659ae5db72SJed Brown ierr = VecResetArray(vec);CHKERRQ(ierr); 4669ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); 46747c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 46847c6ae99SBarry Smith cnt += bs; 46947c6ae99SBarry Smith next = next->next; 47047c6ae99SBarry Smith } 47147c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 47247c6ae99SBarry Smith } 47347c6ae99SBarry Smith PetscFunctionReturn(0); 47447c6ae99SBarry Smith } 47547c6ae99SBarry Smith EXTERN_C_END 47647c6ae99SBarry Smith 47747c6ae99SBarry Smith 47847c6ae99SBarry Smith #undef __FUNCT__ 4790c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite" 4807087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector_Composite(DM dm,Vec *gvec) 48147c6ae99SBarry Smith { 48247c6ae99SBarry Smith PetscErrorCode ierr; 48347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 48447c6ae99SBarry Smith 48547c6ae99SBarry Smith PetscFunctionBegin; 48647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 487d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 48847c6ae99SBarry Smith ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr); 489*c688c046SMatthew G Knepley ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr); 49047c6ae99SBarry Smith ierr = VecSetOperation(*gvec,VECOP_VIEW,(void(*)(void))VecView_DMComposite);CHKERRQ(ierr); 49147c6ae99SBarry Smith PetscFunctionReturn(0); 49247c6ae99SBarry Smith } 49347c6ae99SBarry Smith 49447c6ae99SBarry Smith #undef __FUNCT__ 4950c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite" 4967087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector_Composite(DM dm,Vec *lvec) 49747c6ae99SBarry Smith { 49847c6ae99SBarry Smith PetscErrorCode ierr; 49947c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 50047c6ae99SBarry Smith 50147c6ae99SBarry Smith PetscFunctionBegin; 50247c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 50347c6ae99SBarry Smith if (!com->setup) { 504d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 50547c6ae99SBarry Smith } 50647c6ae99SBarry Smith ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr); 507*c688c046SMatthew G Knepley ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr); 50847c6ae99SBarry Smith PetscFunctionReturn(0); 50947c6ae99SBarry Smith } 51047c6ae99SBarry Smith 51147c6ae99SBarry Smith #undef __FUNCT__ 5126eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings" 51347c6ae99SBarry Smith /*@C 5149ae5db72SJed Brown DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space 51547c6ae99SBarry Smith 51606ebdd98SJed Brown Collective on DM 51747c6ae99SBarry Smith 51847c6ae99SBarry Smith Input Parameter: 51947c6ae99SBarry Smith . dm - the packer object 52047c6ae99SBarry Smith 52147c6ae99SBarry Smith Output Parameters: 5229ae5db72SJed Brown . ltogs - the individual mappings for each packed vector. Note that this includes 5239ae5db72SJed Brown all the ghost points that individual ghosted DMDA's may have. 52447c6ae99SBarry Smith 52547c6ae99SBarry Smith Level: advanced 52647c6ae99SBarry Smith 52747c6ae99SBarry Smith Notes: 5286eb61c8cSJed Brown Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). 52947c6ae99SBarry Smith 5309ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 53147c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 53247c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 53347c6ae99SBarry Smith 53447c6ae99SBarry Smith @*/ 5357087cfbeSBarry Smith PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) 53647c6ae99SBarry Smith { 53747c6ae99SBarry Smith PetscErrorCode ierr; 53847c6ae99SBarry Smith PetscInt i,*idx,n,cnt; 53947c6ae99SBarry Smith struct DMCompositeLink *next; 54047c6ae99SBarry Smith PetscMPIInt rank; 54147c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 54247c6ae99SBarry Smith 54347c6ae99SBarry Smith PetscFunctionBegin; 54447c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 545728e99d6SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 5469ae5db72SJed Brown ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr); 54747c6ae99SBarry Smith next = com->next; 54847c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 54947c6ae99SBarry Smith 55047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 55147c6ae99SBarry Smith cnt = 0; 55247c6ae99SBarry Smith while (next) { 5536eb61c8cSJed Brown ISLocalToGlobalMapping ltog; 5546eb61c8cSJed Brown PetscMPIInt size; 55586994e45SJed Brown const PetscInt *suboff,*indices; 5566eb61c8cSJed Brown Vec global; 55747c6ae99SBarry Smith 5586eb61c8cSJed Brown /* Get sub-DM global indices for each local dof */ 5591411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); 5606eb61c8cSJed Brown ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); 56186994e45SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); 56247c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 56347c6ae99SBarry Smith 5646eb61c8cSJed Brown /* Get the offsets for the sub-DM global vector */ 5656eb61c8cSJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 5666eb61c8cSJed Brown ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); 5676eb61c8cSJed Brown ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr); 5686eb61c8cSJed Brown 5696eb61c8cSJed Brown /* Shift the sub-DM definition of the global space to the composite global space */ 5706eb61c8cSJed Brown for (i=0; i<n; i++) { 57186994e45SJed Brown PetscInt subi = indices[i],lo = 0,hi = size,t; 5726eb61c8cSJed Brown /* Binary search to find which rank owns subi */ 5736eb61c8cSJed Brown while (hi-lo > 1) { 5746eb61c8cSJed Brown t = lo + (hi-lo)/2; 5756eb61c8cSJed Brown if (suboff[t] > subi) hi = t; 5766eb61c8cSJed Brown else lo = t; 5776eb61c8cSJed Brown } 5786eb61c8cSJed Brown idx[i] = subi - suboff[lo] + next->grstarts[lo]; 5796eb61c8cSJed Brown } 58086994e45SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); 5816eb61c8cSJed Brown ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); 5826eb61c8cSJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 58347c6ae99SBarry Smith next = next->next; 58447c6ae99SBarry Smith cnt++; 58547c6ae99SBarry Smith } 58647c6ae99SBarry Smith PetscFunctionReturn(0); 58747c6ae99SBarry Smith } 58847c6ae99SBarry Smith 58947c6ae99SBarry Smith #undef __FUNCT__ 59087c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs" 59187c85e80SJed Brown /*@C 5929ae5db72SJed Brown DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 59387c85e80SJed Brown 59487c85e80SJed Brown Not Collective 59587c85e80SJed Brown 59687c85e80SJed Brown Input Arguments: 59787c85e80SJed Brown . dm - composite DM 59887c85e80SJed Brown 59987c85e80SJed Brown Output Arguments: 60087c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite 60187c85e80SJed Brown 60287c85e80SJed Brown Level: intermediate 60387c85e80SJed Brown 60487c85e80SJed Brown Notes: 60587c85e80SJed Brown At present, a composite local vector does not normally exist. This function is used to provide index sets for 60687c85e80SJed Brown MatGetLocalSubMatrix(). In the future, the scatters for each entry in the DMComposite may be be merged into a single 6079ae5db72SJed Brown scatter to a composite local vector. The user should not typically need to know which is being done. 60887c85e80SJed Brown 60987c85e80SJed Brown To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings(). 61087c85e80SJed Brown 61187c85e80SJed Brown To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs(). 61287c85e80SJed Brown 61387c85e80SJed Brown Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree(). 61487c85e80SJed Brown 61587c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef() 61687c85e80SJed Brown @*/ 6177087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalISs(DM dm,IS **is) 61887c85e80SJed Brown { 61987c85e80SJed Brown PetscErrorCode ierr; 62087c85e80SJed Brown DM_Composite *com = (DM_Composite*)dm->data; 62187c85e80SJed Brown struct DMCompositeLink *link; 62287c85e80SJed Brown PetscInt cnt,start; 62387c85e80SJed Brown 62487c85e80SJed Brown PetscFunctionBegin; 62587c85e80SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62687c85e80SJed Brown PetscValidPointer(is,2); 62787c85e80SJed Brown ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr); 62806ebdd98SJed Brown for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) { 629520db06cSJed Brown PetscInt bs; 6309ae5db72SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr); 6311411c6eeSJed Brown ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr); 632520db06cSJed Brown ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr); 633520db06cSJed Brown } 63487c85e80SJed Brown PetscFunctionReturn(0); 63587c85e80SJed Brown } 63687c85e80SJed Brown 63787c85e80SJed Brown #undef __FUNCT__ 63847c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs" 63947c6ae99SBarry Smith /*@C 64047c6ae99SBarry Smith DMCompositeGetGlobalISs - Gets the index sets for each composed object 64147c6ae99SBarry Smith 64247c6ae99SBarry Smith Collective on DMComposite 64347c6ae99SBarry Smith 64447c6ae99SBarry Smith Input Parameter: 64547c6ae99SBarry Smith . dm - the packer object 64647c6ae99SBarry Smith 64747c6ae99SBarry Smith Output Parameters: 64847c6ae99SBarry Smith . is - the array of index sets 64947c6ae99SBarry Smith 65047c6ae99SBarry Smith Level: advanced 65147c6ae99SBarry Smith 65247c6ae99SBarry Smith Notes: 65347c6ae99SBarry Smith The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 65447c6ae99SBarry Smith 65547c6ae99SBarry Smith These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 65647c6ae99SBarry Smith 6576eb61c8cSJed Brown Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and 6586eb61c8cSJed Brown DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global 6596eb61c8cSJed Brown indices. 66047c6ae99SBarry Smith 6619ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 66247c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 66347c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 66447c6ae99SBarry Smith 66547c6ae99SBarry Smith @*/ 6666eb61c8cSJed Brown 6677087cfbeSBarry Smith PetscErrorCode DMCompositeGetGlobalISs(DM dm,IS *is[]) 66847c6ae99SBarry Smith { 66947c6ae99SBarry Smith PetscErrorCode ierr; 67047c6ae99SBarry Smith PetscInt cnt = 0,*idx,i; 67147c6ae99SBarry Smith struct DMCompositeLink *next; 67247c6ae99SBarry Smith PetscMPIInt rank; 67347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 67447c6ae99SBarry Smith 67547c6ae99SBarry Smith PetscFunctionBegin; 67647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6779ae5db72SJed Brown ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr); 67847c6ae99SBarry Smith next = com->next; 67947c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 68047c6ae99SBarry Smith 68147c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 68247c6ae99SBarry Smith while (next) { 68347c6ae99SBarry Smith ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 68447c6ae99SBarry Smith for (i=0; i<next->n; i++) idx[i] = next->grstart + i; 68547c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 68647c6ae99SBarry Smith cnt++; 68747c6ae99SBarry Smith next = next->next; 68847c6ae99SBarry Smith } 68947c6ae99SBarry Smith PetscFunctionReturn(0); 69047c6ae99SBarry Smith } 69147c6ae99SBarry Smith 6924d343eeaSMatthew G Knepley #undef __FUNCT__ 6934d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite" 69421c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields) 6954d343eeaSMatthew G Knepley { 6964d343eeaSMatthew G Knepley PetscInt nDM; 6974d343eeaSMatthew G Knepley DM *dms; 6984d343eeaSMatthew G Knepley PetscInt i; 6994d343eeaSMatthew G Knepley PetscErrorCode ierr; 7004d343eeaSMatthew G Knepley 7014d343eeaSMatthew G Knepley PetscFunctionBegin; 7024d343eeaSMatthew G Knepley ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 7034d343eeaSMatthew G Knepley if (numFields) {*numFields = nDM;} 7044d343eeaSMatthew G Knepley ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr); 7054d343eeaSMatthew G Knepley if (fieldNames) { 7064d343eeaSMatthew G Knepley ierr = PetscMalloc(nDM*sizeof(DM), &dms);CHKERRQ(ierr); 7074d343eeaSMatthew G Knepley ierr = PetscMalloc(nDM*sizeof(const char *), fieldNames);CHKERRQ(ierr); 7084d343eeaSMatthew G Knepley ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr); 7094d343eeaSMatthew G Knepley for (i=0; i<nDM; i++) { 7104d343eeaSMatthew G Knepley char buf[256]; 7114d343eeaSMatthew G Knepley const char *splitname; 7124d343eeaSMatthew G Knepley 7134d343eeaSMatthew G Knepley /* Split naming precedence: object name, prefix, number */ 7144d343eeaSMatthew G Knepley splitname = ((PetscObject) dm)->name; 7154d343eeaSMatthew G Knepley if (!splitname) { 7164d343eeaSMatthew G Knepley ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr); 7174d343eeaSMatthew G Knepley if (splitname) { 7184d343eeaSMatthew G Knepley size_t len; 7198caf3d72SBarry Smith ierr = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr); 7208caf3d72SBarry Smith buf[sizeof(buf) - 1] = 0; 7214d343eeaSMatthew G Knepley ierr = PetscStrlen(buf,&len);CHKERRQ(ierr); 7224d343eeaSMatthew G Knepley if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */ 7234d343eeaSMatthew G Knepley splitname = buf; 7244d343eeaSMatthew G Knepley } 7254d343eeaSMatthew G Knepley } 7264d343eeaSMatthew G Knepley if (!splitname) { 7278caf3d72SBarry Smith ierr = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr); 7284d343eeaSMatthew G Knepley splitname = buf; 7294d343eeaSMatthew G Knepley } 73021c9b008SJed Brown ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr); 7314d343eeaSMatthew G Knepley } 7324d343eeaSMatthew G Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 7334d343eeaSMatthew G Knepley } 7344d343eeaSMatthew G Knepley PetscFunctionReturn(0); 7354d343eeaSMatthew G Knepley } 7364d343eeaSMatthew G Knepley 737e7c4fc90SDmitry Karpeev /* 738e7c4fc90SDmitry Karpeev This could take over from DMCreateFieldIS(), as it is more general, 739e7c4fc90SDmitry Karpeev making DMCreateFieldIS() a special case -- calling with dmlist == PETSC_NULL; 740e7c4fc90SDmitry Karpeev At this point it's probably best to be less intrusive, however. 741e7c4fc90SDmitry Karpeev */ 742e7c4fc90SDmitry Karpeev #undef __FUNCT__ 74316621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite" 74416621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM** dmlist) 745e7c4fc90SDmitry Karpeev { 746e7c4fc90SDmitry Karpeev PetscInt nDM; 747e7c4fc90SDmitry Karpeev PetscInt i; 748e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 749e7c4fc90SDmitry Karpeev 750e7c4fc90SDmitry Karpeev PetscFunctionBegin; 751e7c4fc90SDmitry Karpeev ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist); CHKERRQ(ierr); 752e7c4fc90SDmitry Karpeev if (dmlist) { 753e7c4fc90SDmitry Karpeev ierr = DMCompositeGetNumberDM(dm, &nDM); CHKERRQ(ierr); 754e7c4fc90SDmitry Karpeev ierr = PetscMalloc(nDM*sizeof(DM), dmlist); CHKERRQ(ierr); 755e7c4fc90SDmitry Karpeev ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr); 756e7c4fc90SDmitry Karpeev for (i=0; i<nDM; i++) { 757e7c4fc90SDmitry Karpeev ierr = PetscObjectReference((PetscObject)((*dmlist)[i])); CHKERRQ(ierr); 758e7c4fc90SDmitry Karpeev } 759e7c4fc90SDmitry Karpeev } 760e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 761e7c4fc90SDmitry Karpeev } 762e7c4fc90SDmitry Karpeev 763e7c4fc90SDmitry Karpeev 764e7c4fc90SDmitry Karpeev 76547c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 76647c6ae99SBarry Smith #undef __FUNCT__ 76747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors" 76847c6ae99SBarry Smith /*@C 7699ae5db72SJed Brown DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite. 77047c6ae99SBarry Smith Use DMCompositeRestoreLocalVectors() to return them. 77147c6ae99SBarry Smith 77247c6ae99SBarry Smith Not Collective 77347c6ae99SBarry Smith 77447c6ae99SBarry Smith Input Parameter: 77547c6ae99SBarry Smith . dm - the packer object 77647c6ae99SBarry Smith 77747c6ae99SBarry Smith Output Parameter: 7789ae5db72SJed Brown . Vec ... - the individual sequential Vecs 77947c6ae99SBarry Smith 78047c6ae99SBarry Smith Level: advanced 78147c6ae99SBarry Smith 7829ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 7836eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 78447c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 78547c6ae99SBarry Smith 78647c6ae99SBarry Smith @*/ 7877087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalVectors(DM dm,...) 78847c6ae99SBarry Smith { 78947c6ae99SBarry Smith va_list Argp; 79047c6ae99SBarry Smith PetscErrorCode ierr; 79147c6ae99SBarry Smith struct DMCompositeLink *next; 79247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 79347c6ae99SBarry Smith 79447c6ae99SBarry Smith PetscFunctionBegin; 79547c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 79647c6ae99SBarry Smith next = com->next; 79747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 79847c6ae99SBarry Smith va_start(Argp,dm); 79947c6ae99SBarry Smith while (next) { 80047c6ae99SBarry Smith Vec *vec; 80147c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 80206930112SJed Brown if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);} 80347c6ae99SBarry Smith next = next->next; 80447c6ae99SBarry Smith } 80547c6ae99SBarry Smith va_end(Argp); 80647c6ae99SBarry Smith PetscFunctionReturn(0); 80747c6ae99SBarry Smith } 80847c6ae99SBarry Smith 80947c6ae99SBarry Smith #undef __FUNCT__ 81047c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors" 81147c6ae99SBarry Smith /*@C 8129ae5db72SJed Brown DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite. 81347c6ae99SBarry Smith 81447c6ae99SBarry Smith Not Collective 81547c6ae99SBarry Smith 81647c6ae99SBarry Smith Input Parameter: 81747c6ae99SBarry Smith . dm - the packer object 81847c6ae99SBarry Smith 81947c6ae99SBarry Smith Output Parameter: 8209ae5db72SJed Brown . Vec ... - the individual sequential Vecs 82147c6ae99SBarry Smith 82247c6ae99SBarry Smith Level: advanced 82347c6ae99SBarry Smith 8249ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 8256eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 82647c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 82747c6ae99SBarry Smith 82847c6ae99SBarry Smith @*/ 8297087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreLocalVectors(DM dm,...) 83047c6ae99SBarry Smith { 83147c6ae99SBarry Smith va_list Argp; 83247c6ae99SBarry Smith PetscErrorCode ierr; 83347c6ae99SBarry Smith struct DMCompositeLink *next; 83447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 83547c6ae99SBarry Smith 83647c6ae99SBarry Smith PetscFunctionBegin; 83747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 83847c6ae99SBarry Smith next = com->next; 83947c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 84047c6ae99SBarry Smith va_start(Argp,dm); 84147c6ae99SBarry Smith while (next) { 84247c6ae99SBarry Smith Vec *vec; 84347c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 84406930112SJed Brown if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);} 84547c6ae99SBarry Smith next = next->next; 84647c6ae99SBarry Smith } 84747c6ae99SBarry Smith va_end(Argp); 84847c6ae99SBarry Smith PetscFunctionReturn(0); 84947c6ae99SBarry Smith } 85047c6ae99SBarry Smith 85147c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 85247c6ae99SBarry Smith #undef __FUNCT__ 85347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries" 85447c6ae99SBarry Smith /*@C 8559ae5db72SJed Brown DMCompositeGetEntries - Gets the DM for each entry in a DMComposite. 85647c6ae99SBarry Smith 85747c6ae99SBarry Smith Not Collective 85847c6ae99SBarry Smith 85947c6ae99SBarry Smith Input Parameter: 86047c6ae99SBarry Smith . dm - the packer object 86147c6ae99SBarry Smith 86247c6ae99SBarry Smith Output Parameter: 8639ae5db72SJed Brown . DM ... - the individual entries (DMs) 86447c6ae99SBarry Smith 86547c6ae99SBarry Smith Level: advanced 86647c6ae99SBarry Smith 8672fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray() 8686eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 86947c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 87047c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 87147c6ae99SBarry Smith 87247c6ae99SBarry Smith @*/ 8737087cfbeSBarry Smith PetscErrorCode DMCompositeGetEntries(DM dm,...) 87447c6ae99SBarry Smith { 87547c6ae99SBarry Smith va_list Argp; 87647c6ae99SBarry Smith struct DMCompositeLink *next; 87747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 87847c6ae99SBarry Smith 87947c6ae99SBarry Smith PetscFunctionBegin; 88047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88147c6ae99SBarry Smith next = com->next; 88247c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 88347c6ae99SBarry Smith va_start(Argp,dm); 88447c6ae99SBarry Smith while (next) { 88547c6ae99SBarry Smith DM *dmn; 88647c6ae99SBarry Smith dmn = va_arg(Argp, DM*); 8879ae5db72SJed Brown if (dmn) *dmn = next->dm; 88847c6ae99SBarry Smith next = next->next; 88947c6ae99SBarry Smith } 89047c6ae99SBarry Smith va_end(Argp); 89147c6ae99SBarry Smith PetscFunctionReturn(0); 89247c6ae99SBarry Smith } 89347c6ae99SBarry Smith 89447c6ae99SBarry Smith #undef __FUNCT__ 8952fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray" 8962fa5ba8aSJed Brown /*@ 8972fa5ba8aSJed Brown DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite. 8982fa5ba8aSJed Brown 8992fa5ba8aSJed Brown Not Collective 9002fa5ba8aSJed Brown 9012fa5ba8aSJed Brown Input Parameter: 9022fa5ba8aSJed Brown + dm - the packer object 9032fa5ba8aSJed Brown - dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output 9042fa5ba8aSJed Brown 9052fa5ba8aSJed Brown Level: advanced 9062fa5ba8aSJed Brown 9072fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries() 9082fa5ba8aSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 9092fa5ba8aSJed Brown DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 9102fa5ba8aSJed Brown DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 9112fa5ba8aSJed Brown 9122fa5ba8aSJed Brown @*/ 9132fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[]) 9142fa5ba8aSJed Brown { 9152fa5ba8aSJed Brown struct DMCompositeLink *next; 9162fa5ba8aSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 9172fa5ba8aSJed Brown PetscInt i; 9182fa5ba8aSJed Brown 9192fa5ba8aSJed Brown PetscFunctionBegin; 9202fa5ba8aSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9212fa5ba8aSJed Brown /* loop over packed objects, handling one at at time */ 9222fa5ba8aSJed Brown for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm; 9232fa5ba8aSJed Brown PetscFunctionReturn(0); 9242fa5ba8aSJed Brown } 9252fa5ba8aSJed Brown 9262fa5ba8aSJed Brown #undef __FUNCT__ 9270c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite" 9287087cfbeSBarry Smith PetscErrorCode DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine) 92947c6ae99SBarry Smith { 93047c6ae99SBarry Smith PetscErrorCode ierr; 93147c6ae99SBarry Smith struct DMCompositeLink *next; 93247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmi->data; 93347c6ae99SBarry Smith DM dm; 93447c6ae99SBarry Smith 93547c6ae99SBarry Smith PetscFunctionBegin; 93647c6ae99SBarry Smith PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 9372ee06e3bSJed Brown if (comm == MPI_COMM_NULL) comm = ((PetscObject)dmi)->comm; 9382ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 93947c6ae99SBarry Smith next = com->next; 94047c6ae99SBarry Smith ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 94147c6ae99SBarry Smith 94247c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 94347c6ae99SBarry Smith while (next) { 94447c6ae99SBarry Smith ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 94547c6ae99SBarry Smith ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 94647c6ae99SBarry Smith ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 94747c6ae99SBarry Smith next = next->next; 94847c6ae99SBarry Smith } 94947c6ae99SBarry Smith PetscFunctionReturn(0); 95047c6ae99SBarry Smith } 95147c6ae99SBarry Smith 95214354c39SJed Brown #undef __FUNCT__ 95314354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite" 95414354c39SJed Brown PetscErrorCode DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine) 95514354c39SJed Brown { 95614354c39SJed Brown PetscErrorCode ierr; 95714354c39SJed Brown struct DMCompositeLink *next; 95814354c39SJed Brown DM_Composite *com = (DM_Composite*)dmi->data; 95914354c39SJed Brown DM dm; 96014354c39SJed Brown 96114354c39SJed Brown PetscFunctionBegin; 96214354c39SJed Brown PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 9632ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 9642ee06e3bSJed Brown if (comm == MPI_COMM_NULL) { 96525296bd5SBarry Smith ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 96625296bd5SBarry Smith } 96714354c39SJed Brown next = com->next; 96814354c39SJed Brown ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 96914354c39SJed Brown 97014354c39SJed Brown /* loop over packed objects, handling one at at time */ 97114354c39SJed Brown while (next) { 97214354c39SJed Brown ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr); 97314354c39SJed Brown ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 97414354c39SJed Brown ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 97514354c39SJed Brown next = next->next; 97614354c39SJed Brown } 97714354c39SJed Brown PetscFunctionReturn(0); 97814354c39SJed Brown } 97947c6ae99SBarry Smith 98047c6ae99SBarry Smith #undef __FUNCT__ 981e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite" 982e727c939SJed Brown PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) 98347c6ae99SBarry Smith { 98447c6ae99SBarry Smith PetscErrorCode ierr; 9859ae5db72SJed Brown PetscInt m,n,M,N,nDM,i; 98647c6ae99SBarry Smith struct DMCompositeLink *nextc; 98747c6ae99SBarry Smith struct DMCompositeLink *nextf; 98825296bd5SBarry Smith Vec gcoarse,gfine,*vecs; 98947c6ae99SBarry Smith DM_Composite *comcoarse = (DM_Composite*)coarse->data; 99047c6ae99SBarry Smith DM_Composite *comfine = (DM_Composite*)fine->data; 9919ae5db72SJed Brown Mat *mats; 99247c6ae99SBarry Smith 99347c6ae99SBarry Smith PetscFunctionBegin; 99447c6ae99SBarry Smith PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 99547c6ae99SBarry Smith PetscValidHeaderSpecific(fine,DM_CLASSID,2); 996f692024eSJed Brown ierr = DMSetUp(coarse);CHKERRQ(ierr); 997f692024eSJed Brown ierr = DMSetUp(fine);CHKERRQ(ierr); 99847c6ae99SBarry Smith /* use global vectors only for determining matrix layout */ 9999ae5db72SJed Brown ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 10009ae5db72SJed Brown ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); 100147c6ae99SBarry Smith ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 100247c6ae99SBarry Smith ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 100347c6ae99SBarry Smith ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 100447c6ae99SBarry Smith ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 10059ae5db72SJed Brown ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 10069ae5db72SJed Brown ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); 100747c6ae99SBarry Smith 10089ae5db72SJed Brown nDM = comfine->nDM; 10099ae5db72SJed 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); 10109ae5db72SJed Brown ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr); 10119ae5db72SJed Brown ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr); 101225296bd5SBarry Smith if (v) { 101325296bd5SBarry Smith ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr); 101425296bd5SBarry Smith ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr); 101525296bd5SBarry Smith } 101647c6ae99SBarry Smith 101747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 10189ae5db72SJed Brown for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { 101925296bd5SBarry Smith if (!v) { 1020e727c939SJed Brown ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr); 102125296bd5SBarry Smith } else { 102225296bd5SBarry Smith ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); 102325296bd5SBarry Smith } 102447c6ae99SBarry Smith } 10259ae5db72SJed Brown ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr); 102625296bd5SBarry Smith if (v) { 102725296bd5SBarry Smith ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr); 102825296bd5SBarry Smith } 10299ae5db72SJed Brown for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} 10309ae5db72SJed Brown ierr = PetscFree(mats);CHKERRQ(ierr); 103125296bd5SBarry Smith if (v) { 103225296bd5SBarry Smith for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} 103325296bd5SBarry Smith ierr = PetscFree(vecs);CHKERRQ(ierr); 103425296bd5SBarry Smith } 103547c6ae99SBarry Smith PetscFunctionReturn(0); 103647c6ae99SBarry Smith } 103747c6ae99SBarry Smith 103847c6ae99SBarry Smith #undef __FUNCT__ 10391411c6eeSJed Brown #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite" 10401411c6eeSJed Brown static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm) 10411411c6eeSJed Brown { 10421411c6eeSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 10431411c6eeSJed Brown ISLocalToGlobalMapping *ltogs; 1044f7efa3c7SJed Brown PetscInt i; 10451411c6eeSJed Brown PetscErrorCode ierr; 10461411c6eeSJed Brown 10471411c6eeSJed Brown PetscFunctionBegin; 10481411c6eeSJed Brown /* Set the ISLocalToGlobalMapping on the new matrix */ 10491411c6eeSJed Brown ierr = DMCompositeGetISLocalToGlobalMappings(dm,<ogs);CHKERRQ(ierr); 10509ae5db72SJed Brown ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr); 10519ae5db72SJed Brown for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(<ogs[i]);CHKERRQ(ierr);} 10521411c6eeSJed Brown ierr = PetscFree(ltogs);CHKERRQ(ierr); 10531411c6eeSJed Brown PetscFunctionReturn(0); 10541411c6eeSJed Brown } 10551411c6eeSJed Brown 10561411c6eeSJed Brown 10571411c6eeSJed Brown #undef __FUNCT__ 1058e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite" 105919fd82e9SBarry Smith PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring) 106047c6ae99SBarry Smith { 106147c6ae99SBarry Smith PetscErrorCode ierr; 106247c6ae99SBarry Smith PetscInt n,i,cnt; 106347c6ae99SBarry Smith ISColoringValue *colors; 106447c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 106547c6ae99SBarry Smith ISColoringValue maxcol = 0; 106647c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 106747c6ae99SBarry Smith 106847c6ae99SBarry Smith PetscFunctionBegin; 106947c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10709805c61eSBarry Smith if (ctype == IS_COLORING_GHOSTED) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Only global coloring supported" ); 1071e3247f34SBarry Smith else if (ctype == IS_COLORING_GLOBAL) { 107247c6ae99SBarry Smith n = com->n; 107347c6ae99SBarry Smith } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 107447c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 107547c6ae99SBarry Smith 1076671f6225SBarry Smith ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); 107747c6ae99SBarry Smith if (dense) { 107847c6ae99SBarry Smith for (i=0; i<n; i++) { 107947c6ae99SBarry Smith colors[i] = (ISColoringValue)(com->rstart + i); 108047c6ae99SBarry Smith } 108147c6ae99SBarry Smith maxcol = com->N; 108247c6ae99SBarry Smith } else { 108347c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 108447c6ae99SBarry Smith PetscMPIInt rank; 108547c6ae99SBarry Smith 108647c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 108747c6ae99SBarry Smith cnt = 0; 108847c6ae99SBarry Smith while (next) { 108947c6ae99SBarry Smith ISColoring lcoloring; 109047c6ae99SBarry Smith 1091e727c939SJed Brown ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr); 109247c6ae99SBarry Smith for (i=0; i<lcoloring->N; i++) { 109347c6ae99SBarry Smith colors[cnt++] = maxcol + lcoloring->colors[i]; 109447c6ae99SBarry Smith } 109547c6ae99SBarry Smith maxcol += lcoloring->n; 1096fcfd50ebSBarry Smith ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); 109747c6ae99SBarry Smith next = next->next; 109847c6ae99SBarry Smith } 109947c6ae99SBarry Smith } 110047c6ae99SBarry Smith ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr); 110147c6ae99SBarry Smith PetscFunctionReturn(0); 110247c6ae99SBarry Smith } 110347c6ae99SBarry Smith 110447c6ae99SBarry Smith #undef __FUNCT__ 11050c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite" 11067087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 110747c6ae99SBarry Smith { 110847c6ae99SBarry Smith PetscErrorCode ierr; 110947c6ae99SBarry Smith struct DMCompositeLink *next; 111047c6ae99SBarry Smith PetscInt cnt = 3; 111147c6ae99SBarry Smith PetscMPIInt rank; 111247c6ae99SBarry Smith PetscScalar *garray,*larray; 111347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 111447c6ae99SBarry Smith 111547c6ae99SBarry Smith PetscFunctionBegin; 111647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 111747c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 111847c6ae99SBarry Smith next = com->next; 111947c6ae99SBarry Smith if (!com->setup) { 1120d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 112147c6ae99SBarry Smith } 112247c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 112347c6ae99SBarry Smith ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 112447c6ae99SBarry Smith ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 112547c6ae99SBarry Smith 112647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 112747c6ae99SBarry Smith while (next) { 112847c6ae99SBarry Smith Vec local,global; 112947c6ae99SBarry Smith PetscInt N; 113047c6ae99SBarry Smith 113147c6ae99SBarry Smith ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 113247c6ae99SBarry Smith ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 113347c6ae99SBarry Smith ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 113447c6ae99SBarry Smith ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 113547c6ae99SBarry Smith ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 113647c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 113747c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 113847c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 113947c6ae99SBarry Smith ierr = VecResetArray(local);CHKERRQ(ierr); 114047c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 114147c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); 114247c6ae99SBarry Smith cnt++; 114306ebdd98SJed Brown larray += next->nlocal; 114447c6ae99SBarry Smith next = next->next; 114547c6ae99SBarry Smith } 114647c6ae99SBarry Smith 114747c6ae99SBarry Smith ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr); 114847c6ae99SBarry Smith ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr); 114947c6ae99SBarry Smith PetscFunctionReturn(0); 115047c6ae99SBarry Smith } 115147c6ae99SBarry Smith 115247c6ae99SBarry Smith #undef __FUNCT__ 11530c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite" 11547087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 11550c010503SBarry Smith { 11560c010503SBarry Smith PetscFunctionBegin; 11570c010503SBarry Smith PetscFunctionReturn(0); 11580c010503SBarry Smith } 115947c6ae99SBarry Smith 11606ae3a549SBarry Smith /*MC 11616ae3a549SBarry Smith DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs 11626ae3a549SBarry Smith 11636ae3a549SBarry Smith 11646ae3a549SBarry Smith 11656ae3a549SBarry Smith Level: intermediate 11666ae3a549SBarry Smith 11676ae3a549SBarry Smith .seealso: DMType, DMCOMPOSITE, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate() 11686ae3a549SBarry Smith M*/ 11696ae3a549SBarry Smith 11706ae3a549SBarry Smith 1171a4121054SBarry Smith EXTERN_C_BEGIN 1172a4121054SBarry Smith #undef __FUNCT__ 1173a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite" 11747087cfbeSBarry Smith PetscErrorCode DMCreate_Composite(DM p) 1175a4121054SBarry Smith { 1176a4121054SBarry Smith PetscErrorCode ierr; 1177a4121054SBarry Smith DM_Composite *com; 1178a4121054SBarry Smith 1179a4121054SBarry Smith PetscFunctionBegin; 1180a4121054SBarry Smith ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr); 1181a4121054SBarry Smith p->data = com; 1182a4121054SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 1183a4121054SBarry Smith com->n = 0; 1184a4121054SBarry Smith com->next = PETSC_NULL; 1185a4121054SBarry Smith com->nDM = 0; 1186a4121054SBarry Smith 1187a4121054SBarry Smith p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1188a4121054SBarry Smith p->ops->createlocalvector = DMCreateLocalVector_Composite; 11891411c6eeSJed Brown p->ops->createlocaltoglobalmapping = DMCreateLocalToGlobalMapping_Composite; 11901411c6eeSJed Brown p->ops->createlocaltoglobalmappingblock = 0; 11914d343eeaSMatthew G Knepley p->ops->createfieldis = DMCreateFieldIS_Composite; 119216621825SDmitry Karpeev p->ops->createfielddecomposition = DMCreateFieldDecomposition_Composite; 1193a4121054SBarry Smith p->ops->refine = DMRefine_Composite; 119414354c39SJed Brown p->ops->coarsen = DMCoarsen_Composite; 119525296bd5SBarry Smith p->ops->createinterpolation = DMCreateInterpolation_Composite; 119625296bd5SBarry Smith p->ops->creatematrix = DMCreateMatrix_Composite; 1197e727c939SJed Brown p->ops->getcoloring = DMCreateColoring_Composite; 1198a4121054SBarry Smith p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1199a4121054SBarry Smith p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 1200a4121054SBarry Smith p->ops->destroy = DMDestroy_Composite; 1201a4121054SBarry Smith p->ops->view = DMView_Composite; 1202a4121054SBarry Smith p->ops->setup = DMSetUp_Composite; 1203a4121054SBarry Smith PetscFunctionReturn(0); 1204a4121054SBarry Smith } 1205a4121054SBarry Smith EXTERN_C_END 1206a4121054SBarry Smith 12070c010503SBarry Smith #undef __FUNCT__ 12080c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate" 12090c010503SBarry Smith /*@C 12100c010503SBarry Smith DMCompositeCreate - Creates a vector packer, used to generate "composite" 12110c010503SBarry Smith vectors made up of several subvectors. 12120c010503SBarry Smith 12130c010503SBarry Smith Collective on MPI_Comm 121447c6ae99SBarry Smith 121547c6ae99SBarry Smith Input Parameter: 12160c010503SBarry Smith . comm - the processors that will share the global vector 12170c010503SBarry Smith 12180c010503SBarry Smith Output Parameters: 12190c010503SBarry Smith . packer - the packer object 122047c6ae99SBarry Smith 122147c6ae99SBarry Smith Level: advanced 122247c6ae99SBarry Smith 12239ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), 12246eb61c8cSJed Brown DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess() 122547c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 122647c6ae99SBarry Smith 122747c6ae99SBarry Smith @*/ 12287087cfbeSBarry Smith PetscErrorCode DMCompositeCreate(MPI_Comm comm,DM *packer) 122947c6ae99SBarry Smith { 12300c010503SBarry Smith PetscErrorCode ierr; 12310c010503SBarry Smith 123247c6ae99SBarry Smith PetscFunctionBegin; 12330c010503SBarry Smith PetscValidPointer(packer,2); 1234a4121054SBarry Smith ierr = DMCreate(comm,packer);CHKERRQ(ierr); 1235a4121054SBarry Smith ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr); 123647c6ae99SBarry Smith PetscFunctionReturn(0); 123747c6ae99SBarry Smith } 1238