147c6ae99SBarry Smith 2ccd284c7SBarry Smith #include <../src/dm/impls/composite/packimpl.h> /*I "petscdmcomposite.h" I*/ 3af0996ceSBarry Smith #include <petsc/private/isimpl.h> 42764a2aaSMatthew G. Knepley #include <petscds.h> 547c6ae99SBarry Smith 647c6ae99SBarry Smith #undef __FUNCT__ 747c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling" 847c6ae99SBarry Smith /*@C 947c6ae99SBarry Smith DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the 10*bebe2cf6SSatish Balay separate components (DMs) in a DMto build the correct matrix nonzero structure. 1147c6ae99SBarry Smith 1247c6ae99SBarry Smith 1347c6ae99SBarry Smith Logically Collective on MPI_Comm 1447c6ae99SBarry Smith 1547c6ae99SBarry Smith Input Parameter: 1647c6ae99SBarry Smith + dm - the composite object 1747c6ae99SBarry Smith - formcouplelocations - routine to set the nonzero locations in the matrix 1847c6ae99SBarry Smith 1947c6ae99SBarry Smith Level: advanced 2047c6ae99SBarry Smith 211b2093e4SBarry Smith Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into 2247c6ae99SBarry Smith this routine 2347c6ae99SBarry Smith 2447c6ae99SBarry Smith @*/ 257087cfbeSBarry Smith PetscErrorCode DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt)) 2647c6ae99SBarry Smith { 2747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 2847c6ae99SBarry Smith 2947c6ae99SBarry Smith PetscFunctionBegin; 3047c6ae99SBarry Smith com->FormCoupleLocations = FormCoupleLocations; 3147c6ae99SBarry Smith PetscFunctionReturn(0); 3247c6ae99SBarry Smith } 3347c6ae99SBarry Smith 3447c6ae99SBarry Smith #undef __FUNCT__ 350c010503SBarry Smith #define __FUNCT__ "DMDestroy_Composite" 366bf464f9SBarry Smith PetscErrorCode DMDestroy_Composite(DM dm) 3747c6ae99SBarry Smith { 3847c6ae99SBarry Smith PetscErrorCode ierr; 3947c6ae99SBarry Smith struct DMCompositeLink *next, *prev; 4047c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 4147c6ae99SBarry Smith 4247c6ae99SBarry Smith PetscFunctionBegin; 4347c6ae99SBarry Smith next = com->next; 4447c6ae99SBarry Smith while (next) { 4547c6ae99SBarry Smith prev = next; 4647c6ae99SBarry Smith next = next->next; 47fcfd50ebSBarry Smith ierr = DMDestroy(&prev->dm);CHKERRQ(ierr); 4847c6ae99SBarry Smith ierr = PetscFree(prev->grstarts);CHKERRQ(ierr); 4947c6ae99SBarry Smith ierr = PetscFree(prev);CHKERRQ(ierr); 5047c6ae99SBarry Smith } 51435a35e8SMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 52435a35e8SMatthew G Knepley ierr = PetscFree(com);CHKERRQ(ierr); 5347c6ae99SBarry Smith PetscFunctionReturn(0); 5447c6ae99SBarry Smith } 5547c6ae99SBarry Smith 5647c6ae99SBarry Smith #undef __FUNCT__ 570c010503SBarry Smith #define __FUNCT__ "DMView_Composite" 587087cfbeSBarry Smith PetscErrorCode DMView_Composite(DM dm,PetscViewer v) 5947c6ae99SBarry Smith { 6047c6ae99SBarry Smith PetscErrorCode ierr; 6147c6ae99SBarry Smith PetscBool iascii; 6247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 6347c6ae99SBarry Smith 6447c6ae99SBarry Smith PetscFunctionBegin; 65251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 6647c6ae99SBarry Smith if (iascii) { 6747c6ae99SBarry Smith struct DMCompositeLink *lnk = com->next; 6847c6ae99SBarry Smith PetscInt i; 6947c6ae99SBarry Smith 7047c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix");CHKERRQ(ierr); 719ae5db72SJed Brown ierr = PetscViewerASCIIPrintf(v," contains %D DMs\n",com->nDM);CHKERRQ(ierr); 7247c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 7347c6ae99SBarry Smith for (i=0; lnk; lnk=lnk->next,i++) { 749ae5db72SJed Brown ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr); 7547c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 7647c6ae99SBarry Smith ierr = DMView(lnk->dm,v);CHKERRQ(ierr); 7747c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 7847c6ae99SBarry Smith } 7947c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 8047c6ae99SBarry Smith } 8147c6ae99SBarry Smith PetscFunctionReturn(0); 8247c6ae99SBarry Smith } 8347c6ae99SBarry Smith 8447c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/ 8547c6ae99SBarry Smith #undef __FUNCT__ 86d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp_Composite" 877087cfbeSBarry Smith PetscErrorCode DMSetUp_Composite(DM dm) 8847c6ae99SBarry Smith { 8947c6ae99SBarry Smith PetscErrorCode ierr; 9047c6ae99SBarry Smith PetscInt nprev = 0; 9147c6ae99SBarry Smith PetscMPIInt rank,size; 9247c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 9347c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 9447c6ae99SBarry Smith PetscLayout map; 9547c6ae99SBarry Smith 9647c6ae99SBarry Smith PetscFunctionBegin; 97ce94432eSBarry Smith if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); 98ce94432eSBarry Smith ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm),&map);CHKERRQ(ierr); 9947c6ae99SBarry Smith ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); 10047c6ae99SBarry Smith ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); 10147c6ae99SBarry Smith ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 10247c6ae99SBarry Smith ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 10347c6ae99SBarry Smith ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); 1040298fd71SBarry Smith ierr = PetscLayoutGetRange(map,&com->rstart,NULL);CHKERRQ(ierr); 105fcfd50ebSBarry Smith ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 10647c6ae99SBarry Smith 1079ae5db72SJed Brown /* now set the rstart for each linked vector */ 108ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 109ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr); 11047c6ae99SBarry Smith while (next) { 11147c6ae99SBarry Smith next->rstart = nprev; 11206ebdd98SJed Brown nprev += next->n; 11347c6ae99SBarry Smith next->grstart = com->rstart + next->rstart; 114785e854fSJed Brown ierr = PetscMalloc1(size,&next->grstarts);CHKERRQ(ierr); 115ce94432eSBarry Smith ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 11647c6ae99SBarry Smith next = next->next; 11747c6ae99SBarry Smith } 11847c6ae99SBarry Smith com->setup = PETSC_TRUE; 11947c6ae99SBarry Smith PetscFunctionReturn(0); 12047c6ae99SBarry Smith } 12147c6ae99SBarry Smith 12247c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/ 12347c6ae99SBarry Smith 12447c6ae99SBarry Smith #undef __FUNCT__ 12547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM" 12673e31fe2SJed 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: 1650298fd71SBarry Smith . Vec* ... - the packed parallel vectors, 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 169f73e5cebSJed Brown Fortran Notes: 170f73e5cebSJed Brown 171f73e5cebSJed Brown Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4) 172f73e5cebSJed Brown or use the alternative interface DMCompositeGetAccessArray(). 173f73e5cebSJed Brown 17447c6ae99SBarry Smith Level: advanced 17547c6ae99SBarry Smith 176f73e5cebSJed Brown .seealso: DMCompositeGetEntries(), DMCompositeScatter() 17747c6ae99SBarry Smith @*/ 1787087cfbeSBarry Smith PetscErrorCode DMCompositeGetAccess(DM dm,Vec gvec,...) 17947c6ae99SBarry Smith { 18047c6ae99SBarry Smith va_list Argp; 18147c6ae99SBarry Smith PetscErrorCode ierr; 18247c6ae99SBarry Smith struct DMCompositeLink *next; 18347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1845edff71fSBarry Smith PetscInt readonly; 18547c6ae99SBarry Smith 18647c6ae99SBarry Smith PetscFunctionBegin; 18747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 18947c6ae99SBarry Smith next = com->next; 19047c6ae99SBarry Smith if (!com->setup) { 191d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 19247c6ae99SBarry Smith } 19347c6ae99SBarry Smith 1945edff71fSBarry Smith ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr); 19547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 19647c6ae99SBarry Smith va_start(Argp,gvec); 19747c6ae99SBarry Smith while (next) { 19847c6ae99SBarry Smith Vec *vec; 19947c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 2009ae5db72SJed Brown if (vec) { 2019ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr); 2025edff71fSBarry Smith if (readonly) { 2035edff71fSBarry Smith const PetscScalar *array; 2045edff71fSBarry Smith ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 2055edff71fSBarry Smith ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 2065edff71fSBarry Smith ierr = VecLockPush(*vec);CHKERRQ(ierr); 2075edff71fSBarry Smith ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 2085edff71fSBarry Smith } else { 2095edff71fSBarry Smith PetscScalar *array; 2109ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 2119ae5db72SJed Brown ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 2129ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 21347c6ae99SBarry Smith } 2145edff71fSBarry Smith } 21547c6ae99SBarry Smith next = next->next; 21647c6ae99SBarry Smith } 21747c6ae99SBarry Smith va_end(Argp); 21847c6ae99SBarry Smith PetscFunctionReturn(0); 21947c6ae99SBarry Smith } 22047c6ae99SBarry Smith 22147c6ae99SBarry Smith #undef __FUNCT__ 222f73e5cebSJed Brown #define __FUNCT__ "DMCompositeGetAccessArray" 223f73e5cebSJed Brown /*@C 224f73e5cebSJed Brown DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global 225f73e5cebSJed Brown representation. 226f73e5cebSJed Brown 227f73e5cebSJed Brown Collective on DMComposite 228f73e5cebSJed Brown 229f73e5cebSJed Brown Input Parameters: 230f73e5cebSJed Brown + dm - the packer object 231f73e5cebSJed Brown . pvec - packed vector 232f73e5cebSJed Brown . nwanted - number of vectors wanted 2330298fd71SBarry Smith - wanted - sorted array of vectors wanted, or NULL to get all vectors 234f73e5cebSJed Brown 235f73e5cebSJed Brown Output Parameters: 236f73e5cebSJed Brown . vecs - array of requested global vectors (must be allocated) 237f73e5cebSJed Brown 238f73e5cebSJed Brown Notes: Use DMCompositeRestoreAccessArray() to return the vectors when you no longer need them 239f73e5cebSJed Brown 240f73e5cebSJed Brown Level: advanced 241f73e5cebSJed Brown 242f73e5cebSJed Brown .seealso: DMCompositeGetAccess(), DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather() 243f73e5cebSJed Brown @*/ 244f73e5cebSJed Brown PetscErrorCode DMCompositeGetAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs) 245f73e5cebSJed Brown { 246f73e5cebSJed Brown PetscErrorCode ierr; 247f73e5cebSJed Brown struct DMCompositeLink *link; 248f73e5cebSJed Brown PetscInt i,wnum; 249f73e5cebSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 250bee642f7SBarry Smith PetscInt readonly; 251f73e5cebSJed Brown 252f73e5cebSJed Brown PetscFunctionBegin; 253f73e5cebSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 254f73e5cebSJed Brown PetscValidHeaderSpecific(pvec,VEC_CLASSID,2); 255f73e5cebSJed Brown if (!com->setup) { 256f73e5cebSJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 257f73e5cebSJed Brown } 258f73e5cebSJed Brown 259bee642f7SBarry Smith ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr); 260f73e5cebSJed Brown for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) { 261f73e5cebSJed Brown if (!wanted || i == wanted[wnum]) { 262f73e5cebSJed Brown Vec v; 263f73e5cebSJed Brown ierr = DMGetGlobalVector(link->dm,&v);CHKERRQ(ierr); 264bee642f7SBarry Smith if (readonly) { 265bee642f7SBarry Smith const PetscScalar *array; 266bee642f7SBarry Smith ierr = VecGetArrayRead(pvec,&array);CHKERRQ(ierr); 267bee642f7SBarry Smith ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr); 268bee642f7SBarry Smith ierr = VecLockPush(v);CHKERRQ(ierr); 269bee642f7SBarry Smith ierr = VecRestoreArrayRead(pvec,&array);CHKERRQ(ierr); 270bee642f7SBarry Smith } else { 271bee642f7SBarry Smith PetscScalar *array; 272f73e5cebSJed Brown ierr = VecGetArray(pvec,&array);CHKERRQ(ierr); 273f73e5cebSJed Brown ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr); 274f73e5cebSJed Brown ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr); 275bee642f7SBarry Smith } 276f73e5cebSJed Brown vecs[wnum++] = v; 277f73e5cebSJed Brown } 278f73e5cebSJed Brown } 279f73e5cebSJed Brown PetscFunctionReturn(0); 280f73e5cebSJed Brown } 281f73e5cebSJed Brown 282f73e5cebSJed Brown #undef __FUNCT__ 28347c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess" 28447c6ae99SBarry Smith /*@C 285aa219208SBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() 28647c6ae99SBarry Smith representation. 28747c6ae99SBarry Smith 28847c6ae99SBarry Smith Collective on DMComposite 28947c6ae99SBarry Smith 2909ae5db72SJed Brown Input Parameters: 29147c6ae99SBarry Smith + dm - the packer object 29247c6ae99SBarry Smith . gvec - the global vector 2930298fd71SBarry Smith - Vec* ... - the individual parallel vectors, NULL for those that are not needed 29447c6ae99SBarry Smith 29547c6ae99SBarry Smith Level: advanced 29647c6ae99SBarry Smith 2979ae5db72SJed Brown .seealso DMCompositeAddDM(), DMCreateGlobalVector(), 2986eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), 299aa219208SBarry Smith DMCompositeRestoreAccess(), DMCompositeGetAccess() 30047c6ae99SBarry Smith 30147c6ae99SBarry Smith @*/ 3027087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) 30347c6ae99SBarry Smith { 30447c6ae99SBarry Smith va_list Argp; 30547c6ae99SBarry Smith PetscErrorCode ierr; 30647c6ae99SBarry Smith struct DMCompositeLink *next; 30747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 3085edff71fSBarry Smith PetscInt readonly; 30947c6ae99SBarry Smith 31047c6ae99SBarry Smith PetscFunctionBegin; 31147c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 31247c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 31347c6ae99SBarry Smith next = com->next; 31447c6ae99SBarry Smith if (!com->setup) { 315d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 31647c6ae99SBarry Smith } 31747c6ae99SBarry Smith 3185edff71fSBarry Smith ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr); 31947c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 32047c6ae99SBarry Smith va_start(Argp,gvec); 32147c6ae99SBarry Smith while (next) { 32247c6ae99SBarry Smith Vec *vec; 32347c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 3249ae5db72SJed Brown if (vec) { 3259ae5db72SJed Brown ierr = VecResetArray(*vec);CHKERRQ(ierr); 3265edff71fSBarry Smith if (readonly) { 3275edff71fSBarry Smith ierr = VecLockPop(*vec);CHKERRQ(ierr); 3285edff71fSBarry Smith } 329bee642f7SBarry Smith ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); 33047c6ae99SBarry Smith } 33147c6ae99SBarry Smith next = next->next; 33247c6ae99SBarry Smith } 33347c6ae99SBarry Smith va_end(Argp); 33447c6ae99SBarry Smith PetscFunctionReturn(0); 33547c6ae99SBarry Smith } 33647c6ae99SBarry Smith 33747c6ae99SBarry Smith #undef __FUNCT__ 338f73e5cebSJed Brown #define __FUNCT__ "DMCompositeRestoreAccessArray" 339f73e5cebSJed Brown /*@C 340f73e5cebSJed Brown DMCompositeRestoreAccessArray - Returns the vectors obtained with DMCompositeGetAccessArray() 341f73e5cebSJed Brown 342f73e5cebSJed Brown Collective on DMComposite 343f73e5cebSJed Brown 344f73e5cebSJed Brown Input Parameters: 345f73e5cebSJed Brown + dm - the packer object 346f73e5cebSJed Brown . pvec - packed vector 347f73e5cebSJed Brown . nwanted - number of vectors wanted 3480298fd71SBarry Smith . wanted - sorted array of vectors wanted, or NULL to get all vectors 349f73e5cebSJed Brown - vecs - array of global vectors to return 350f73e5cebSJed Brown 351f73e5cebSJed Brown Level: advanced 352f73e5cebSJed Brown 353f73e5cebSJed Brown .seealso: DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), DMCompositeScatter(), DMCompositeGather() 354f73e5cebSJed Brown @*/ 355f73e5cebSJed Brown PetscErrorCode DMCompositeRestoreAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs) 356f73e5cebSJed Brown { 357f73e5cebSJed Brown PetscErrorCode ierr; 358f73e5cebSJed Brown struct DMCompositeLink *link; 359f73e5cebSJed Brown PetscInt i,wnum; 360f73e5cebSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 361bee642f7SBarry Smith PetscInt readonly; 362f73e5cebSJed Brown 363f73e5cebSJed Brown PetscFunctionBegin; 364f73e5cebSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 365f73e5cebSJed Brown PetscValidHeaderSpecific(pvec,VEC_CLASSID,2); 366f73e5cebSJed Brown if (!com->setup) { 367f73e5cebSJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 368f73e5cebSJed Brown } 369f73e5cebSJed Brown 370bee642f7SBarry Smith ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr); 371f73e5cebSJed Brown for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) { 372f73e5cebSJed Brown if (!wanted || i == wanted[wnum]) { 373f73e5cebSJed Brown ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr); 374bee642f7SBarry Smith if (readonly) { 375bee642f7SBarry Smith ierr = VecLockPop(vecs[wnum]);CHKERRQ(ierr); 376bee642f7SBarry Smith } 377f73e5cebSJed Brown ierr = DMRestoreGlobalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr); 378f73e5cebSJed Brown wnum++; 379f73e5cebSJed Brown } 380f73e5cebSJed Brown } 381f73e5cebSJed Brown PetscFunctionReturn(0); 382f73e5cebSJed Brown } 383f73e5cebSJed Brown 384f73e5cebSJed Brown #undef __FUNCT__ 38547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter" 38647c6ae99SBarry Smith /*@C 38747c6ae99SBarry Smith DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 38847c6ae99SBarry Smith 38947c6ae99SBarry Smith Collective on DMComposite 39047c6ae99SBarry Smith 3919ae5db72SJed Brown Input Parameters: 39247c6ae99SBarry Smith + dm - the packer object 39347c6ae99SBarry Smith . gvec - the global vector 3940298fd71SBarry Smith - Vec ... - the individual sequential vectors, NULL for those that are not needed 39547c6ae99SBarry Smith 39647c6ae99SBarry Smith Level: advanced 39747c6ae99SBarry Smith 3986f3c3dcfSJed Brown Notes: 3996f3c3dcfSJed Brown DMCompositeScatterArray() is a non-variadic alternative that is often more convenient for library callers and is 4006f3c3dcfSJed Brown accessible from Fortran. 4016f3c3dcfSJed Brown 4029ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 4036eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 40447c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 4056f3c3dcfSJed Brown DMCompositeScatterArray() 40647c6ae99SBarry Smith 40747c6ae99SBarry Smith @*/ 4087087cfbeSBarry Smith PetscErrorCode DMCompositeScatter(DM dm,Vec gvec,...) 40947c6ae99SBarry Smith { 41047c6ae99SBarry Smith va_list Argp; 41147c6ae99SBarry Smith PetscErrorCode ierr; 41247c6ae99SBarry Smith struct DMCompositeLink *next; 4138fd8f222SJed Brown PetscInt cnt; 41447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 41547c6ae99SBarry Smith 41647c6ae99SBarry Smith PetscFunctionBegin; 41747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 41847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 41947c6ae99SBarry Smith if (!com->setup) { 420d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 42147c6ae99SBarry Smith } 42247c6ae99SBarry Smith 42347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 42447c6ae99SBarry Smith va_start(Argp,gvec); 4258fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 4269ae5db72SJed Brown Vec local; 4279ae5db72SJed Brown local = va_arg(Argp, Vec); 4289ae5db72SJed Brown if (local) { 4299ae5db72SJed Brown Vec global; 4305edff71fSBarry Smith const PetscScalar *array; 4319ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 4329ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 4335edff71fSBarry Smith ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 4349ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 4359ae5db72SJed Brown ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 4369ae5db72SJed Brown ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 4375edff71fSBarry Smith ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 4389ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 4399ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 44047c6ae99SBarry Smith } 44147c6ae99SBarry Smith } 44247c6ae99SBarry Smith va_end(Argp); 44347c6ae99SBarry Smith PetscFunctionReturn(0); 44447c6ae99SBarry Smith } 44547c6ae99SBarry Smith 44647c6ae99SBarry Smith #undef __FUNCT__ 4476f3c3dcfSJed Brown #define __FUNCT__ "DMCompositeScatterArray" 4486f3c3dcfSJed Brown /*@ 4496f3c3dcfSJed Brown DMCompositeScatterArray - Scatters from a global packed vector into its individual local vectors 4506f3c3dcfSJed Brown 4516f3c3dcfSJed Brown Collective on DMComposite 4526f3c3dcfSJed Brown 4536f3c3dcfSJed Brown Input Parameters: 4546f3c3dcfSJed Brown + dm - the packer object 4556f3c3dcfSJed Brown . gvec - the global vector 4566f3c3dcfSJed Brown . lvecs - array of local vectors, NULL for any that are not needed 4576f3c3dcfSJed Brown 4586f3c3dcfSJed Brown Level: advanced 4596f3c3dcfSJed Brown 4606f3c3dcfSJed Brown Note: 461907376e6SBarry Smith This is a non-variadic alternative to DMCompositeScatter() 4626f3c3dcfSJed Brown 4636f3c3dcfSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector() 4646f3c3dcfSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 4656f3c3dcfSJed Brown DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 4666f3c3dcfSJed Brown 4676f3c3dcfSJed Brown @*/ 4686f3c3dcfSJed Brown PetscErrorCode DMCompositeScatterArray(DM dm,Vec gvec,Vec *lvecs) 4696f3c3dcfSJed Brown { 4706f3c3dcfSJed Brown PetscErrorCode ierr; 4716f3c3dcfSJed Brown struct DMCompositeLink *next; 4726f3c3dcfSJed Brown PetscInt i; 4736f3c3dcfSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 4746f3c3dcfSJed Brown 4756f3c3dcfSJed Brown PetscFunctionBegin; 4766f3c3dcfSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4776f3c3dcfSJed Brown PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 4786f3c3dcfSJed Brown if (!com->setup) { 4796f3c3dcfSJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 4806f3c3dcfSJed Brown } 4816f3c3dcfSJed Brown 4826f3c3dcfSJed Brown /* loop over packed objects, handling one at at time */ 4836f3c3dcfSJed Brown for (i=0,next=com->next; next; next=next->next,i++) { 4846f3c3dcfSJed Brown if (lvecs[i]) { 4856f3c3dcfSJed Brown Vec global; 486c5d31e75SLisandro Dalcin const PetscScalar *array; 4876f3c3dcfSJed Brown PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3); 4886f3c3dcfSJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 489c5d31e75SLisandro Dalcin ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 490c5d31e75SLisandro Dalcin ierr = VecPlaceArray(global,(PetscScalar*)array+next->rstart);CHKERRQ(ierr); 4916f3c3dcfSJed Brown ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr); 4926f3c3dcfSJed Brown ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr); 493c5d31e75SLisandro Dalcin ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 4946f3c3dcfSJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 4956f3c3dcfSJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 4966f3c3dcfSJed Brown } 4976f3c3dcfSJed Brown } 4986f3c3dcfSJed Brown PetscFunctionReturn(0); 4996f3c3dcfSJed Brown } 5006f3c3dcfSJed Brown 5016f3c3dcfSJed Brown #undef __FUNCT__ 50247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather" 50347c6ae99SBarry Smith /*@C 50447c6ae99SBarry Smith DMCompositeGather - Gathers into a global packed vector from its individual local vectors 50547c6ae99SBarry Smith 50647c6ae99SBarry Smith Collective on DMComposite 50747c6ae99SBarry Smith 50847c6ae99SBarry Smith Input Parameter: 50947c6ae99SBarry Smith + dm - the packer object 51047c6ae99SBarry Smith . gvec - the global vector 511907376e6SBarry Smith . imode - INSERT_VALUES or ADD_VALUES 5120298fd71SBarry Smith - Vec ... - the individual sequential vectors, NULL for any that are not needed 51347c6ae99SBarry Smith 51447c6ae99SBarry Smith Level: advanced 51547c6ae99SBarry Smith 5169ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 5176eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 51847c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 51947c6ae99SBarry Smith 52047c6ae99SBarry Smith @*/ 5217087cfbeSBarry Smith PetscErrorCode DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...) 52247c6ae99SBarry Smith { 52347c6ae99SBarry Smith va_list Argp; 52447c6ae99SBarry Smith PetscErrorCode ierr; 52547c6ae99SBarry Smith struct DMCompositeLink *next; 52647c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 5278fd8f222SJed Brown PetscInt cnt; 52847c6ae99SBarry Smith 52947c6ae99SBarry Smith PetscFunctionBegin; 53047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 53147c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 53247c6ae99SBarry Smith if (!com->setup) { 533d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 53447c6ae99SBarry Smith } 53547c6ae99SBarry Smith 53647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 537df0c820aSJed Brown va_start(Argp,imode); 5388fd8f222SJed Brown for (cnt=3,next=com->next; next; cnt++,next=next->next) { 5399ae5db72SJed Brown Vec local; 5409ae5db72SJed Brown local = va_arg(Argp, Vec); 5419ae5db72SJed Brown if (local) { 54247c6ae99SBarry Smith PetscScalar *array; 5439ae5db72SJed Brown Vec global; 5449ae5db72SJed Brown PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 5459ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 5469ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 5479ae5db72SJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 5489ae5db72SJed Brown ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); 5499ae5db72SJed Brown ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); 5509ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 5519ae5db72SJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 5529ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 55347c6ae99SBarry Smith } 55447c6ae99SBarry Smith } 55547c6ae99SBarry Smith va_end(Argp); 55647c6ae99SBarry Smith PetscFunctionReturn(0); 55747c6ae99SBarry Smith } 55847c6ae99SBarry Smith 55947c6ae99SBarry Smith #undef __FUNCT__ 5606f3c3dcfSJed Brown #define __FUNCT__ "DMCompositeGatherArray" 5616f3c3dcfSJed Brown /*@ 5626f3c3dcfSJed Brown DMCompositeGatherArray - Gathers into a global packed vector from its individual local vectors 5636f3c3dcfSJed Brown 5646f3c3dcfSJed Brown Collective on DMComposite 5656f3c3dcfSJed Brown 5666f3c3dcfSJed Brown Input Parameter: 5676f3c3dcfSJed Brown + dm - the packer object 5686f3c3dcfSJed Brown . gvec - the global vector 569907376e6SBarry Smith . imode - INSERT_VALUES or ADD_VALUES 5706f3c3dcfSJed Brown - lvecs - the individual sequential vectors, NULL for any that are not needed 5716f3c3dcfSJed Brown 5726f3c3dcfSJed Brown Level: advanced 5736f3c3dcfSJed Brown 5746f3c3dcfSJed Brown Notes: 5756f3c3dcfSJed Brown This is a non-variadic alternative to DMCompositeGather(). 5766f3c3dcfSJed Brown 5776f3c3dcfSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 5786f3c3dcfSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 5796f3c3dcfSJed Brown DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), 5806f3c3dcfSJed Brown @*/ 5816f3c3dcfSJed Brown PetscErrorCode DMCompositeGatherArray(DM dm,Vec gvec,InsertMode imode,Vec *lvecs) 5826f3c3dcfSJed Brown { 5836f3c3dcfSJed Brown PetscErrorCode ierr; 5846f3c3dcfSJed Brown struct DMCompositeLink *next; 5856f3c3dcfSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 5866f3c3dcfSJed Brown PetscInt i; 5876f3c3dcfSJed Brown 5886f3c3dcfSJed Brown PetscFunctionBegin; 5896f3c3dcfSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5906f3c3dcfSJed Brown PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 5916f3c3dcfSJed Brown if (!com->setup) { 5926f3c3dcfSJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 5936f3c3dcfSJed Brown } 5946f3c3dcfSJed Brown 5956f3c3dcfSJed Brown /* loop over packed objects, handling one at at time */ 5966f3c3dcfSJed Brown for (next=com->next,i=0; next; next=next->next,i++) { 5976f3c3dcfSJed Brown if (lvecs[i]) { 5986f3c3dcfSJed Brown PetscScalar *array; 5996f3c3dcfSJed Brown Vec global; 6006f3c3dcfSJed Brown PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3); 6016f3c3dcfSJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 6026f3c3dcfSJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 6036f3c3dcfSJed Brown ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 6046f3c3dcfSJed Brown ierr = DMLocalToGlobalBegin(next->dm,lvecs[i],imode,global);CHKERRQ(ierr); 6056f3c3dcfSJed Brown ierr = DMLocalToGlobalEnd(next->dm,lvecs[i],imode,global);CHKERRQ(ierr); 6066f3c3dcfSJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 6076f3c3dcfSJed Brown ierr = VecResetArray(global);CHKERRQ(ierr); 6086f3c3dcfSJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 6096f3c3dcfSJed Brown } 6106f3c3dcfSJed Brown } 6116f3c3dcfSJed Brown PetscFunctionReturn(0); 6126f3c3dcfSJed Brown } 6136f3c3dcfSJed Brown 6146f3c3dcfSJed Brown #undef __FUNCT__ 61547c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM" 61647c6ae99SBarry Smith /*@C 617aa219208SBarry Smith DMCompositeAddDM - adds a DM vector to a DMComposite 61847c6ae99SBarry Smith 61947c6ae99SBarry Smith Collective on DMComposite 62047c6ae99SBarry Smith 62147c6ae99SBarry Smith Input Parameter: 62247c6ae99SBarry Smith + dm - the packer object 62347c6ae99SBarry Smith - dm - the DM object, if the DM is a da you will need to caste it with a (DM) 62447c6ae99SBarry Smith 62547c6ae99SBarry Smith Level: advanced 62647c6ae99SBarry Smith 6270c010503SBarry Smith .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), 6286eb61c8cSJed Brown DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 62947c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 63047c6ae99SBarry Smith 63147c6ae99SBarry Smith @*/ 6327087cfbeSBarry Smith PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) 63347c6ae99SBarry Smith { 63447c6ae99SBarry Smith PetscErrorCode ierr; 63506ebdd98SJed Brown PetscInt n,nlocal; 63647c6ae99SBarry Smith struct DMCompositeLink *mine,*next; 63706ebdd98SJed Brown Vec global,local; 63847c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmc->data; 63947c6ae99SBarry Smith 64047c6ae99SBarry Smith PetscFunctionBegin; 64147c6ae99SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 64247c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 64347c6ae99SBarry Smith next = com->next; 644ce94432eSBarry Smith if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); 64547c6ae99SBarry Smith 64647c6ae99SBarry Smith /* create new link */ 647b00a9115SJed Brown ierr = PetscNew(&mine);CHKERRQ(ierr); 64847c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 64947c6ae99SBarry Smith ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 65047c6ae99SBarry Smith ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 65147c6ae99SBarry Smith ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 65206ebdd98SJed Brown ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); 65306ebdd98SJed Brown ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); 65406ebdd98SJed Brown ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); 6558865f1eaSKarl Rupp 65647c6ae99SBarry Smith mine->n = n; 65706ebdd98SJed Brown mine->nlocal = nlocal; 65847c6ae99SBarry Smith mine->dm = dm; 6590298fd71SBarry Smith mine->next = NULL; 66047c6ae99SBarry Smith com->n += n; 66147c6ae99SBarry Smith 66247c6ae99SBarry Smith /* add to end of list */ 6638865f1eaSKarl Rupp if (!next) com->next = mine; 6648865f1eaSKarl Rupp else { 66547c6ae99SBarry Smith while (next->next) next = next->next; 66647c6ae99SBarry Smith next->next = mine; 66747c6ae99SBarry Smith } 66847c6ae99SBarry Smith com->nDM++; 66947c6ae99SBarry Smith com->nmine++; 67047c6ae99SBarry Smith PetscFunctionReturn(0); 67147c6ae99SBarry Smith } 67247c6ae99SBarry Smith 6739804daf3SBarry Smith #include <petscdraw.h> 67426887b52SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec,PetscViewer); 67547c6ae99SBarry Smith #undef __FUNCT__ 67647c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite" 6777087cfbeSBarry Smith PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) 67847c6ae99SBarry Smith { 67947c6ae99SBarry Smith DM dm; 68047c6ae99SBarry Smith PetscErrorCode ierr; 68147c6ae99SBarry Smith struct DMCompositeLink *next; 68247c6ae99SBarry Smith PetscBool isdraw; 683cef07954SSatish Balay DM_Composite *com; 68447c6ae99SBarry Smith 68547c6ae99SBarry Smith PetscFunctionBegin; 686c688c046SMatthew G Knepley ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr); 687ce94432eSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)gvec),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 68847c6ae99SBarry Smith com = (DM_Composite*)dm->data; 68947c6ae99SBarry Smith next = com->next; 69047c6ae99SBarry Smith 691251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 69247c6ae99SBarry Smith if (!isdraw) { 69347c6ae99SBarry Smith /* do I really want to call this? */ 69447c6ae99SBarry Smith ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 69547c6ae99SBarry Smith } else { 69647c6ae99SBarry Smith PetscInt cnt = 0; 69747c6ae99SBarry Smith 69847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 69947c6ae99SBarry Smith while (next) { 70047c6ae99SBarry Smith Vec vec; 7019ae5db72SJed Brown PetscScalar *array; 70247c6ae99SBarry Smith PetscInt bs; 70347c6ae99SBarry Smith 7049ae5db72SJed Brown /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 7059ae5db72SJed Brown ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); 7069ae5db72SJed Brown ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 7079ae5db72SJed Brown ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr); 7089ae5db72SJed Brown ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 70947c6ae99SBarry Smith ierr = VecView(vec,viewer);CHKERRQ(ierr); 71047c6ae99SBarry Smith ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 7119ae5db72SJed Brown ierr = VecResetArray(vec);CHKERRQ(ierr); 7129ae5db72SJed Brown ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); 71347c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 71447c6ae99SBarry Smith cnt += bs; 71547c6ae99SBarry Smith next = next->next; 71647c6ae99SBarry Smith } 71747c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 71847c6ae99SBarry Smith } 71947c6ae99SBarry Smith PetscFunctionReturn(0); 72047c6ae99SBarry Smith } 72147c6ae99SBarry Smith 72247c6ae99SBarry Smith #undef __FUNCT__ 7230c010503SBarry Smith #define __FUNCT__ "DMCreateGlobalVector_Composite" 7247087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector_Composite(DM dm,Vec *gvec) 72547c6ae99SBarry Smith { 72647c6ae99SBarry Smith PetscErrorCode ierr; 72747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 72847c6ae99SBarry Smith 72947c6ae99SBarry Smith PetscFunctionBegin; 73047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 731d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 732ce94432eSBarry Smith ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),com->n,com->N,gvec);CHKERRQ(ierr); 733c688c046SMatthew G Knepley ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr); 73447c6ae99SBarry Smith ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr); 73547c6ae99SBarry Smith PetscFunctionReturn(0); 73647c6ae99SBarry Smith } 73747c6ae99SBarry Smith 73847c6ae99SBarry Smith #undef __FUNCT__ 7390c010503SBarry Smith #define __FUNCT__ "DMCreateLocalVector_Composite" 7407087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector_Composite(DM dm,Vec *lvec) 74147c6ae99SBarry Smith { 74247c6ae99SBarry Smith PetscErrorCode ierr; 74347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 74447c6ae99SBarry Smith 74547c6ae99SBarry Smith PetscFunctionBegin; 74647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 74747c6ae99SBarry Smith if (!com->setup) { 748d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 74947c6ae99SBarry Smith } 750ce94432eSBarry Smith ierr = VecCreateSeq(PetscObjectComm((PetscObject)dm),com->nghost,lvec);CHKERRQ(ierr); 751c688c046SMatthew G Knepley ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr); 75247c6ae99SBarry Smith PetscFunctionReturn(0); 75347c6ae99SBarry Smith } 75447c6ae99SBarry Smith 75547c6ae99SBarry Smith #undef __FUNCT__ 7566eb61c8cSJed Brown #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings" 75747c6ae99SBarry Smith /*@C 7589ae5db72SJed Brown DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space 75947c6ae99SBarry Smith 76006ebdd98SJed Brown Collective on DM 76147c6ae99SBarry Smith 76247c6ae99SBarry Smith Input Parameter: 76347c6ae99SBarry Smith . dm - the packer object 76447c6ae99SBarry Smith 76547c6ae99SBarry Smith Output Parameters: 7669ae5db72SJed Brown . ltogs - the individual mappings for each packed vector. Note that this includes 7679ae5db72SJed Brown all the ghost points that individual ghosted DMDA's may have. 76847c6ae99SBarry Smith 76947c6ae99SBarry Smith Level: advanced 77047c6ae99SBarry Smith 77147c6ae99SBarry Smith Notes: 7726eb61c8cSJed Brown Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). 77347c6ae99SBarry Smith 7749ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 77547c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 77647c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 77747c6ae99SBarry Smith 77847c6ae99SBarry Smith @*/ 7797087cfbeSBarry Smith PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) 78047c6ae99SBarry Smith { 78147c6ae99SBarry Smith PetscErrorCode ierr; 78247c6ae99SBarry Smith PetscInt i,*idx,n,cnt; 78347c6ae99SBarry Smith struct DMCompositeLink *next; 78447c6ae99SBarry Smith PetscMPIInt rank; 78547c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 78647c6ae99SBarry Smith 78747c6ae99SBarry Smith PetscFunctionBegin; 78847c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 789728e99d6SJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 790854ce69bSBarry Smith ierr = PetscMalloc1(com->nDM,ltogs);CHKERRQ(ierr); 79147c6ae99SBarry Smith next = com->next; 792ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 79347c6ae99SBarry Smith 79447c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 79547c6ae99SBarry Smith cnt = 0; 79647c6ae99SBarry Smith while (next) { 7976eb61c8cSJed Brown ISLocalToGlobalMapping ltog; 7986eb61c8cSJed Brown PetscMPIInt size; 79986994e45SJed Brown const PetscInt *suboff,*indices; 8006eb61c8cSJed Brown Vec global; 80147c6ae99SBarry Smith 8026eb61c8cSJed Brown /* Get sub-DM global indices for each local dof */ 8031411c6eeSJed Brown ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); 8046eb61c8cSJed Brown ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); 80586994e45SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); 806785e854fSJed Brown ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 80747c6ae99SBarry Smith 8086eb61c8cSJed Brown /* Get the offsets for the sub-DM global vector */ 8096eb61c8cSJed Brown ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 8106eb61c8cSJed Brown ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); 811ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)global),&size);CHKERRQ(ierr); 8126eb61c8cSJed Brown 8136eb61c8cSJed Brown /* Shift the sub-DM definition of the global space to the composite global space */ 8146eb61c8cSJed Brown for (i=0; i<n; i++) { 81586994e45SJed Brown PetscInt subi = indices[i],lo = 0,hi = size,t; 8166eb61c8cSJed Brown /* Binary search to find which rank owns subi */ 8176eb61c8cSJed Brown while (hi-lo > 1) { 8186eb61c8cSJed Brown t = lo + (hi-lo)/2; 8196eb61c8cSJed Brown if (suboff[t] > subi) hi = t; 8206eb61c8cSJed Brown else lo = t; 8216eb61c8cSJed Brown } 8226eb61c8cSJed Brown idx[i] = subi - suboff[lo] + next->grstarts[lo]; 8236eb61c8cSJed Brown } 82486994e45SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); 825f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm),1,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); 8266eb61c8cSJed Brown ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 82747c6ae99SBarry Smith next = next->next; 82847c6ae99SBarry Smith cnt++; 82947c6ae99SBarry Smith } 83047c6ae99SBarry Smith PetscFunctionReturn(0); 83147c6ae99SBarry Smith } 83247c6ae99SBarry Smith 83347c6ae99SBarry Smith #undef __FUNCT__ 83487c85e80SJed Brown #define __FUNCT__ "DMCompositeGetLocalISs" 83587c85e80SJed Brown /*@C 8369ae5db72SJed Brown DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 83787c85e80SJed Brown 83887c85e80SJed Brown Not Collective 83987c85e80SJed Brown 84087c85e80SJed Brown Input Arguments: 84187c85e80SJed Brown . dm - composite DM 84287c85e80SJed Brown 84387c85e80SJed Brown Output Arguments: 84487c85e80SJed Brown . is - array of serial index sets for each each component of the DMComposite 84587c85e80SJed Brown 84687c85e80SJed Brown Level: intermediate 84787c85e80SJed Brown 84887c85e80SJed Brown Notes: 84987c85e80SJed Brown At present, a composite local vector does not normally exist. This function is used to provide index sets for 85087c85e80SJed Brown MatGetLocalSubMatrix(). In the future, the scatters for each entry in the DMComposite may be be merged into a single 8519ae5db72SJed Brown scatter to a composite local vector. The user should not typically need to know which is being done. 85287c85e80SJed Brown 85387c85e80SJed Brown To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings(). 85487c85e80SJed Brown 85587c85e80SJed Brown To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs(). 85687c85e80SJed Brown 85787c85e80SJed Brown Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree(). 85887c85e80SJed Brown 85987c85e80SJed Brown .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef() 86087c85e80SJed Brown @*/ 8617087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalISs(DM dm,IS **is) 86287c85e80SJed Brown { 86387c85e80SJed Brown PetscErrorCode ierr; 86487c85e80SJed Brown DM_Composite *com = (DM_Composite*)dm->data; 86587c85e80SJed Brown struct DMCompositeLink *link; 86687c85e80SJed Brown PetscInt cnt,start; 86787c85e80SJed Brown 86887c85e80SJed Brown PetscFunctionBegin; 86987c85e80SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87087c85e80SJed Brown PetscValidPointer(is,2); 871785e854fSJed Brown ierr = PetscMalloc1(com->nmine,is);CHKERRQ(ierr); 87206ebdd98SJed Brown for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) { 873520db06cSJed Brown PetscInt bs; 8749ae5db72SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr); 8751411c6eeSJed Brown ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr); 876520db06cSJed Brown ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr); 877520db06cSJed Brown } 87887c85e80SJed Brown PetscFunctionReturn(0); 87987c85e80SJed Brown } 88087c85e80SJed Brown 88187c85e80SJed Brown #undef __FUNCT__ 88247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs" 88347c6ae99SBarry Smith /*@C 88447c6ae99SBarry Smith DMCompositeGetGlobalISs - Gets the index sets for each composed object 88547c6ae99SBarry Smith 88647c6ae99SBarry Smith Collective on DMComposite 88747c6ae99SBarry Smith 88847c6ae99SBarry Smith Input Parameter: 88947c6ae99SBarry Smith . dm - the packer object 89047c6ae99SBarry Smith 89147c6ae99SBarry Smith Output Parameters: 89247c6ae99SBarry Smith . is - the array of index sets 89347c6ae99SBarry Smith 89447c6ae99SBarry Smith Level: advanced 89547c6ae99SBarry Smith 89647c6ae99SBarry Smith Notes: 89747c6ae99SBarry Smith The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 89847c6ae99SBarry Smith 89947c6ae99SBarry Smith These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 90047c6ae99SBarry Smith 9016eb61c8cSJed Brown Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and 9026eb61c8cSJed Brown DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global 9036eb61c8cSJed Brown indices. 90447c6ae99SBarry Smith 9059ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 90647c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 90747c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 90847c6ae99SBarry Smith 90947c6ae99SBarry Smith @*/ 9106eb61c8cSJed Brown 9117087cfbeSBarry Smith PetscErrorCode DMCompositeGetGlobalISs(DM dm,IS *is[]) 91247c6ae99SBarry Smith { 91347c6ae99SBarry Smith PetscErrorCode ierr; 91466bb578eSMark Adams PetscInt cnt = 0; 91547c6ae99SBarry Smith struct DMCompositeLink *next; 91647c6ae99SBarry Smith PetscMPIInt rank; 91747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 91847c6ae99SBarry Smith 91947c6ae99SBarry Smith PetscFunctionBegin; 92047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 921854ce69bSBarry Smith ierr = PetscMalloc1(com->nDM,is);CHKERRQ(ierr); 92247c6ae99SBarry Smith next = com->next; 923ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 92447c6ae99SBarry Smith 92547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 92647c6ae99SBarry Smith while (next) { 92766bb578eSMark Adams ierr = ISCreateStride(PetscObjectComm((PetscObject)dm),next->n,next->grstart,1,&(*is)[cnt]);CHKERRQ(ierr); 9280f21e855SMatthew G. Knepley if (dm->prob) { 92965c226d8SMatthew G. Knepley MatNullSpace space; 93065c226d8SMatthew G. Knepley Mat pmat; 9310f21e855SMatthew G. Knepley PetscObject disc; 9320f21e855SMatthew G. Knepley PetscInt Nf; 93365c226d8SMatthew G. Knepley 9342764a2aaSMatthew G. Knepley ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr); 935f24dd8d2SMatthew G. Knepley if (cnt < Nf) { 9362764a2aaSMatthew G. Knepley ierr = PetscDSGetDiscretization(dm->prob, cnt, &disc);CHKERRQ(ierr); 9370f21e855SMatthew G. Knepley ierr = PetscObjectQuery(disc, "nullspace", (PetscObject*) &space);CHKERRQ(ierr); 938aac2dd2dSMatthew G. Knepley if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nullspace", (PetscObject) space);CHKERRQ(ierr);} 9390f21e855SMatthew G. Knepley ierr = PetscObjectQuery(disc, "nearnullspace", (PetscObject*) &space);CHKERRQ(ierr); 940aac2dd2dSMatthew G. Knepley if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nearnullspace", (PetscObject) space);CHKERRQ(ierr);} 9410f21e855SMatthew G. Knepley ierr = PetscObjectQuery(disc, "pmat", (PetscObject*) &pmat);CHKERRQ(ierr); 942aac2dd2dSMatthew G. Knepley if (pmat) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "pmat", (PetscObject) pmat);CHKERRQ(ierr);} 94365c226d8SMatthew G. Knepley } 944f24dd8d2SMatthew G. Knepley } 94547c6ae99SBarry Smith cnt++; 94647c6ae99SBarry Smith next = next->next; 94747c6ae99SBarry Smith } 94847c6ae99SBarry Smith PetscFunctionReturn(0); 94947c6ae99SBarry Smith } 95047c6ae99SBarry Smith 9514d343eeaSMatthew G Knepley #undef __FUNCT__ 9524d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS_Composite" 95321c9b008SJed Brown PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields) 9544d343eeaSMatthew G Knepley { 9554d343eeaSMatthew G Knepley PetscInt nDM; 9564d343eeaSMatthew G Knepley DM *dms; 9574d343eeaSMatthew G Knepley PetscInt i; 9584d343eeaSMatthew G Knepley PetscErrorCode ierr; 9594d343eeaSMatthew G Knepley 9604d343eeaSMatthew G Knepley PetscFunctionBegin; 9614d343eeaSMatthew G Knepley ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 9628865f1eaSKarl Rupp if (numFields) *numFields = nDM; 9634d343eeaSMatthew G Knepley ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr); 9644d343eeaSMatthew G Knepley if (fieldNames) { 965785e854fSJed Brown ierr = PetscMalloc1(nDM, &dms);CHKERRQ(ierr); 966785e854fSJed Brown ierr = PetscMalloc1(nDM, fieldNames);CHKERRQ(ierr); 9674d343eeaSMatthew G Knepley ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr); 9684d343eeaSMatthew G Knepley for (i=0; i<nDM; i++) { 9694d343eeaSMatthew G Knepley char buf[256]; 9704d343eeaSMatthew G Knepley const char *splitname; 9714d343eeaSMatthew G Knepley 9724d343eeaSMatthew G Knepley /* Split naming precedence: object name, prefix, number */ 9734d343eeaSMatthew G Knepley splitname = ((PetscObject) dm)->name; 9744d343eeaSMatthew G Knepley if (!splitname) { 9754d343eeaSMatthew G Knepley ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr); 9764d343eeaSMatthew G Knepley if (splitname) { 9774d343eeaSMatthew G Knepley size_t len; 9788caf3d72SBarry Smith ierr = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr); 9798caf3d72SBarry Smith buf[sizeof(buf) - 1] = 0; 9804d343eeaSMatthew G Knepley ierr = PetscStrlen(buf,&len);CHKERRQ(ierr); 9814d343eeaSMatthew G Knepley if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */ 9824d343eeaSMatthew G Knepley splitname = buf; 9834d343eeaSMatthew G Knepley } 9844d343eeaSMatthew G Knepley } 9854d343eeaSMatthew G Knepley if (!splitname) { 9868caf3d72SBarry Smith ierr = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr); 9874d343eeaSMatthew G Knepley splitname = buf; 9884d343eeaSMatthew G Knepley } 98921c9b008SJed Brown ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr); 9904d343eeaSMatthew G Knepley } 9914d343eeaSMatthew G Knepley ierr = PetscFree(dms);CHKERRQ(ierr); 9924d343eeaSMatthew G Knepley } 9934d343eeaSMatthew G Knepley PetscFunctionReturn(0); 9944d343eeaSMatthew G Knepley } 9954d343eeaSMatthew G Knepley 996e7c4fc90SDmitry Karpeev /* 997e7c4fc90SDmitry Karpeev This could take over from DMCreateFieldIS(), as it is more general, 9980298fd71SBarry Smith making DMCreateFieldIS() a special case -- calling with dmlist == NULL; 999e7c4fc90SDmitry Karpeev At this point it's probably best to be less intrusive, however. 1000e7c4fc90SDmitry Karpeev */ 1001e7c4fc90SDmitry Karpeev #undef __FUNCT__ 100216621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition_Composite" 100316621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist) 1004e7c4fc90SDmitry Karpeev { 1005e7c4fc90SDmitry Karpeev PetscInt nDM; 1006e7c4fc90SDmitry Karpeev PetscInt i; 1007e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 1008e7c4fc90SDmitry Karpeev 1009e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1010e7c4fc90SDmitry Karpeev ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr); 1011e7c4fc90SDmitry Karpeev if (dmlist) { 1012e7c4fc90SDmitry Karpeev ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 1013785e854fSJed Brown ierr = PetscMalloc1(nDM, dmlist);CHKERRQ(ierr); 1014e7c4fc90SDmitry Karpeev ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr); 1015e7c4fc90SDmitry Karpeev for (i=0; i<nDM; i++) { 1016e7c4fc90SDmitry Karpeev ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr); 1017e7c4fc90SDmitry Karpeev } 1018e7c4fc90SDmitry Karpeev } 1019e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 1020e7c4fc90SDmitry Karpeev } 1021e7c4fc90SDmitry Karpeev 1022e7c4fc90SDmitry Karpeev 1023e7c4fc90SDmitry Karpeev 102447c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 102547c6ae99SBarry Smith #undef __FUNCT__ 102647c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors" 102747c6ae99SBarry Smith /*@C 10289ae5db72SJed Brown DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite. 102947c6ae99SBarry Smith Use DMCompositeRestoreLocalVectors() to return them. 103047c6ae99SBarry Smith 103147c6ae99SBarry Smith Not Collective 103247c6ae99SBarry Smith 103347c6ae99SBarry Smith Input Parameter: 103447c6ae99SBarry Smith . dm - the packer object 103547c6ae99SBarry Smith 103647c6ae99SBarry Smith Output Parameter: 10379ae5db72SJed Brown . Vec ... - the individual sequential Vecs 103847c6ae99SBarry Smith 103947c6ae99SBarry Smith Level: advanced 104047c6ae99SBarry Smith 10419ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 10426eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 104347c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 104447c6ae99SBarry Smith 104547c6ae99SBarry Smith @*/ 10467087cfbeSBarry Smith PetscErrorCode DMCompositeGetLocalVectors(DM dm,...) 104747c6ae99SBarry Smith { 104847c6ae99SBarry Smith va_list Argp; 104947c6ae99SBarry Smith PetscErrorCode ierr; 105047c6ae99SBarry Smith struct DMCompositeLink *next; 105147c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 105247c6ae99SBarry Smith 105347c6ae99SBarry Smith PetscFunctionBegin; 105447c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 105547c6ae99SBarry Smith next = com->next; 105647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 105747c6ae99SBarry Smith va_start(Argp,dm); 105847c6ae99SBarry Smith while (next) { 105947c6ae99SBarry Smith Vec *vec; 106047c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 106106930112SJed Brown if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);} 106247c6ae99SBarry Smith next = next->next; 106347c6ae99SBarry Smith } 106447c6ae99SBarry Smith va_end(Argp); 106547c6ae99SBarry Smith PetscFunctionReturn(0); 106647c6ae99SBarry Smith } 106747c6ae99SBarry Smith 106847c6ae99SBarry Smith #undef __FUNCT__ 106947c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors" 107047c6ae99SBarry Smith /*@C 10719ae5db72SJed Brown DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite. 107247c6ae99SBarry Smith 107347c6ae99SBarry Smith Not Collective 107447c6ae99SBarry Smith 107547c6ae99SBarry Smith Input Parameter: 107647c6ae99SBarry Smith . dm - the packer object 107747c6ae99SBarry Smith 107847c6ae99SBarry Smith Output Parameter: 10799ae5db72SJed Brown . Vec ... - the individual sequential Vecs 108047c6ae99SBarry Smith 108147c6ae99SBarry Smith Level: advanced 108247c6ae99SBarry Smith 10839ae5db72SJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 10846eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 108547c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 108647c6ae99SBarry Smith 108747c6ae99SBarry Smith @*/ 10887087cfbeSBarry Smith PetscErrorCode DMCompositeRestoreLocalVectors(DM dm,...) 108947c6ae99SBarry Smith { 109047c6ae99SBarry Smith va_list Argp; 109147c6ae99SBarry Smith PetscErrorCode ierr; 109247c6ae99SBarry Smith struct DMCompositeLink *next; 109347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 109447c6ae99SBarry Smith 109547c6ae99SBarry Smith PetscFunctionBegin; 109647c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 109747c6ae99SBarry Smith next = com->next; 109847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 109947c6ae99SBarry Smith va_start(Argp,dm); 110047c6ae99SBarry Smith while (next) { 110147c6ae99SBarry Smith Vec *vec; 110247c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 110306930112SJed Brown if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);} 110447c6ae99SBarry Smith next = next->next; 110547c6ae99SBarry Smith } 110647c6ae99SBarry Smith va_end(Argp); 110747c6ae99SBarry Smith PetscFunctionReturn(0); 110847c6ae99SBarry Smith } 110947c6ae99SBarry Smith 111047c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 111147c6ae99SBarry Smith #undef __FUNCT__ 111247c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries" 111347c6ae99SBarry Smith /*@C 11149ae5db72SJed Brown DMCompositeGetEntries - Gets the DM for each entry in a DMComposite. 111547c6ae99SBarry Smith 111647c6ae99SBarry Smith Not Collective 111747c6ae99SBarry Smith 111847c6ae99SBarry Smith Input Parameter: 111947c6ae99SBarry Smith . dm - the packer object 112047c6ae99SBarry Smith 112147c6ae99SBarry Smith Output Parameter: 11229ae5db72SJed Brown . DM ... - the individual entries (DMs) 112347c6ae99SBarry Smith 112447c6ae99SBarry Smith Level: advanced 112547c6ae99SBarry Smith 11262fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray() 11276eb61c8cSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 112847c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 112947c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 113047c6ae99SBarry Smith 113147c6ae99SBarry Smith @*/ 11327087cfbeSBarry Smith PetscErrorCode DMCompositeGetEntries(DM dm,...) 113347c6ae99SBarry Smith { 113447c6ae99SBarry Smith va_list Argp; 113547c6ae99SBarry Smith struct DMCompositeLink *next; 113647c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 113747c6ae99SBarry Smith 113847c6ae99SBarry Smith PetscFunctionBegin; 113947c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 114047c6ae99SBarry Smith next = com->next; 114147c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 114247c6ae99SBarry Smith va_start(Argp,dm); 114347c6ae99SBarry Smith while (next) { 114447c6ae99SBarry Smith DM *dmn; 114547c6ae99SBarry Smith dmn = va_arg(Argp, DM*); 11469ae5db72SJed Brown if (dmn) *dmn = next->dm; 114747c6ae99SBarry Smith next = next->next; 114847c6ae99SBarry Smith } 114947c6ae99SBarry Smith va_end(Argp); 115047c6ae99SBarry Smith PetscFunctionReturn(0); 115147c6ae99SBarry Smith } 115247c6ae99SBarry Smith 115347c6ae99SBarry Smith #undef __FUNCT__ 11542fa5ba8aSJed Brown #define __FUNCT__ "DMCompositeGetEntriesArray" 1155dbab29e1SMark F. Adams /*@C 11562fa5ba8aSJed Brown DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite. 11572fa5ba8aSJed Brown 11582fa5ba8aSJed Brown Not Collective 11592fa5ba8aSJed Brown 11602fa5ba8aSJed Brown Input Parameter: 1161907376e6SBarry Smith . dm - the packer object 1162907376e6SBarry Smith 1163907376e6SBarry Smith Output Parameter: 1164907376e6SBarry Smith . dms - array of sufficient length (see DMCompositeGetNumberDM()) to hold the individual DMs 11652fa5ba8aSJed Brown 11662fa5ba8aSJed Brown Level: advanced 11672fa5ba8aSJed Brown 11682fa5ba8aSJed Brown .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries() 11692fa5ba8aSJed Brown DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 11702fa5ba8aSJed Brown DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 11712fa5ba8aSJed Brown DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 11722fa5ba8aSJed Brown 11732fa5ba8aSJed Brown @*/ 11742fa5ba8aSJed Brown PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[]) 11752fa5ba8aSJed Brown { 11762fa5ba8aSJed Brown struct DMCompositeLink *next; 11772fa5ba8aSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 11782fa5ba8aSJed Brown PetscInt i; 11792fa5ba8aSJed Brown 11802fa5ba8aSJed Brown PetscFunctionBegin; 11812fa5ba8aSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 11822fa5ba8aSJed Brown /* loop over packed objects, handling one at at time */ 11832fa5ba8aSJed Brown for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm; 11842fa5ba8aSJed Brown PetscFunctionReturn(0); 11852fa5ba8aSJed Brown } 11862fa5ba8aSJed Brown 11872fa5ba8aSJed Brown #undef __FUNCT__ 11880c010503SBarry Smith #define __FUNCT__ "DMRefine_Composite" 11897087cfbeSBarry Smith PetscErrorCode DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine) 119047c6ae99SBarry Smith { 119147c6ae99SBarry Smith PetscErrorCode ierr; 119247c6ae99SBarry Smith struct DMCompositeLink *next; 119347c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmi->data; 119447c6ae99SBarry Smith DM dm; 119547c6ae99SBarry Smith 119647c6ae99SBarry Smith PetscFunctionBegin; 119747c6ae99SBarry Smith PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 1198ce94432eSBarry Smith if (comm == MPI_COMM_NULL) { 1199ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 1200ce94432eSBarry Smith } 12012ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 120247c6ae99SBarry Smith next = com->next; 120347c6ae99SBarry Smith ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 120447c6ae99SBarry Smith 120547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 120647c6ae99SBarry Smith while (next) { 120747c6ae99SBarry Smith ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 120847c6ae99SBarry Smith ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 120947c6ae99SBarry Smith ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 121047c6ae99SBarry Smith next = next->next; 121147c6ae99SBarry Smith } 121247c6ae99SBarry Smith PetscFunctionReturn(0); 121347c6ae99SBarry Smith } 121447c6ae99SBarry Smith 121514354c39SJed Brown #undef __FUNCT__ 121614354c39SJed Brown #define __FUNCT__ "DMCoarsen_Composite" 121714354c39SJed Brown PetscErrorCode DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine) 121814354c39SJed Brown { 121914354c39SJed Brown PetscErrorCode ierr; 122014354c39SJed Brown struct DMCompositeLink *next; 122114354c39SJed Brown DM_Composite *com = (DM_Composite*)dmi->data; 122214354c39SJed Brown DM dm; 122314354c39SJed Brown 122414354c39SJed Brown PetscFunctionBegin; 122514354c39SJed Brown PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 12262ce3a92bSJed Brown ierr = DMSetUp(dmi);CHKERRQ(ierr); 12272ee06e3bSJed Brown if (comm == MPI_COMM_NULL) { 122825296bd5SBarry Smith ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 122925296bd5SBarry Smith } 123014354c39SJed Brown next = com->next; 123114354c39SJed Brown ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 123214354c39SJed Brown 123314354c39SJed Brown /* loop over packed objects, handling one at at time */ 123414354c39SJed Brown while (next) { 123514354c39SJed Brown ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr); 123614354c39SJed Brown ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 123714354c39SJed Brown ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 123814354c39SJed Brown next = next->next; 123914354c39SJed Brown } 124014354c39SJed Brown PetscFunctionReturn(0); 124114354c39SJed Brown } 124247c6ae99SBarry Smith 124347c6ae99SBarry Smith #undef __FUNCT__ 1244e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation_Composite" 1245e727c939SJed Brown PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) 124647c6ae99SBarry Smith { 124747c6ae99SBarry Smith PetscErrorCode ierr; 12489ae5db72SJed Brown PetscInt m,n,M,N,nDM,i; 124947c6ae99SBarry Smith struct DMCompositeLink *nextc; 125047c6ae99SBarry Smith struct DMCompositeLink *nextf; 125125296bd5SBarry Smith Vec gcoarse,gfine,*vecs; 125247c6ae99SBarry Smith DM_Composite *comcoarse = (DM_Composite*)coarse->data; 125347c6ae99SBarry Smith DM_Composite *comfine = (DM_Composite*)fine->data; 12549ae5db72SJed Brown Mat *mats; 125547c6ae99SBarry Smith 125647c6ae99SBarry Smith PetscFunctionBegin; 125747c6ae99SBarry Smith PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 125847c6ae99SBarry Smith PetscValidHeaderSpecific(fine,DM_CLASSID,2); 1259f692024eSJed Brown ierr = DMSetUp(coarse);CHKERRQ(ierr); 1260f692024eSJed Brown ierr = DMSetUp(fine);CHKERRQ(ierr); 126147c6ae99SBarry Smith /* use global vectors only for determining matrix layout */ 12629ae5db72SJed Brown ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 12639ae5db72SJed Brown ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); 126447c6ae99SBarry Smith ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 126547c6ae99SBarry Smith ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 126647c6ae99SBarry Smith ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 126747c6ae99SBarry Smith ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 12689ae5db72SJed Brown ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 12699ae5db72SJed Brown ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); 127047c6ae99SBarry Smith 12719ae5db72SJed Brown nDM = comfine->nDM; 1272ce94432eSBarry Smith if (nDM != comcoarse->nDM) SETERRQ2(PetscObjectComm((PetscObject)fine),PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM); 12731795a4d1SJed Brown ierr = PetscCalloc1(nDM*nDM,&mats);CHKERRQ(ierr); 127425296bd5SBarry Smith if (v) { 12751795a4d1SJed Brown ierr = PetscCalloc1(nDM,&vecs);CHKERRQ(ierr); 127625296bd5SBarry Smith } 127747c6ae99SBarry Smith 127847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 12799ae5db72SJed Brown for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { 128025296bd5SBarry Smith if (!v) { 12810298fd71SBarry Smith ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],NULL);CHKERRQ(ierr); 128225296bd5SBarry Smith } else { 128325296bd5SBarry Smith ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); 128425296bd5SBarry Smith } 128547c6ae99SBarry Smith } 1286ce94432eSBarry Smith ierr = MatCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,nDM,NULL,mats,A);CHKERRQ(ierr); 128725296bd5SBarry Smith if (v) { 1288ce94432eSBarry Smith ierr = VecCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,vecs,v);CHKERRQ(ierr); 128925296bd5SBarry Smith } 12909ae5db72SJed Brown for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} 12919ae5db72SJed Brown ierr = PetscFree(mats);CHKERRQ(ierr); 129225296bd5SBarry Smith if (v) { 129325296bd5SBarry Smith for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} 129425296bd5SBarry Smith ierr = PetscFree(vecs);CHKERRQ(ierr); 129525296bd5SBarry Smith } 129647c6ae99SBarry Smith PetscFunctionReturn(0); 129747c6ae99SBarry Smith } 129847c6ae99SBarry Smith 129947c6ae99SBarry Smith #undef __FUNCT__ 1300184d77edSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping_Composite" 1301184d77edSJed Brown static PetscErrorCode DMGetLocalToGlobalMapping_Composite(DM dm) 13021411c6eeSJed Brown { 13031411c6eeSJed Brown DM_Composite *com = (DM_Composite*)dm->data; 13041411c6eeSJed Brown ISLocalToGlobalMapping *ltogs; 1305f7efa3c7SJed Brown PetscInt i; 13061411c6eeSJed Brown PetscErrorCode ierr; 13071411c6eeSJed Brown 13081411c6eeSJed Brown PetscFunctionBegin; 13091411c6eeSJed Brown /* Set the ISLocalToGlobalMapping on the new matrix */ 13101411c6eeSJed Brown ierr = DMCompositeGetISLocalToGlobalMappings(dm,<ogs);CHKERRQ(ierr); 1311ce94432eSBarry Smith ierr = ISLocalToGlobalMappingConcatenate(PetscObjectComm((PetscObject)dm),com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr); 13129ae5db72SJed Brown for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(<ogs[i]);CHKERRQ(ierr);} 13131411c6eeSJed Brown ierr = PetscFree(ltogs);CHKERRQ(ierr); 13141411c6eeSJed Brown PetscFunctionReturn(0); 13151411c6eeSJed Brown } 13161411c6eeSJed Brown 13171411c6eeSJed Brown 13181411c6eeSJed Brown #undef __FUNCT__ 1319e727c939SJed Brown #define __FUNCT__ "DMCreateColoring_Composite" 1320b412c318SBarry Smith PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,ISColoring *coloring) 132147c6ae99SBarry Smith { 132247c6ae99SBarry Smith PetscErrorCode ierr; 132347c6ae99SBarry Smith PetscInt n,i,cnt; 132447c6ae99SBarry Smith ISColoringValue *colors; 132547c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 132647c6ae99SBarry Smith ISColoringValue maxcol = 0; 132747c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 132847c6ae99SBarry Smith 132947c6ae99SBarry Smith PetscFunctionBegin; 133047c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1331ce94432eSBarry Smith if (ctype == IS_COLORING_GHOSTED) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only global coloring supported"); 1332e3247f34SBarry Smith else if (ctype == IS_COLORING_GLOBAL) { 133347c6ae99SBarry Smith n = com->n; 1334ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 1335785e854fSJed Brown ierr = PetscMalloc1(n,&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 133647c6ae99SBarry Smith 13370298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-dmcomposite_dense_jacobian",&dense,NULL);CHKERRQ(ierr); 133847c6ae99SBarry Smith if (dense) { 133947c6ae99SBarry Smith for (i=0; i<n; i++) { 134047c6ae99SBarry Smith colors[i] = (ISColoringValue)(com->rstart + i); 134147c6ae99SBarry Smith } 134247c6ae99SBarry Smith maxcol = com->N; 134347c6ae99SBarry Smith } else { 134447c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 134547c6ae99SBarry Smith PetscMPIInt rank; 134647c6ae99SBarry Smith 1347ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 134847c6ae99SBarry Smith cnt = 0; 134947c6ae99SBarry Smith while (next) { 135047c6ae99SBarry Smith ISColoring lcoloring; 135147c6ae99SBarry Smith 1352b412c318SBarry Smith ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,&lcoloring);CHKERRQ(ierr); 135347c6ae99SBarry Smith for (i=0; i<lcoloring->N; i++) { 135447c6ae99SBarry Smith colors[cnt++] = maxcol + lcoloring->colors[i]; 135547c6ae99SBarry Smith } 135647c6ae99SBarry Smith maxcol += lcoloring->n; 1357fcfd50ebSBarry Smith ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); 135847c6ae99SBarry Smith next = next->next; 135947c6ae99SBarry Smith } 136047c6ae99SBarry Smith } 1361aaf3ff59SMatthew G. Knepley ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),maxcol,n,colors,PETSC_OWN_POINTER,coloring);CHKERRQ(ierr); 136247c6ae99SBarry Smith PetscFunctionReturn(0); 136347c6ae99SBarry Smith } 136447c6ae99SBarry Smith 136547c6ae99SBarry Smith #undef __FUNCT__ 13660c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Composite" 13677087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 136847c6ae99SBarry Smith { 136947c6ae99SBarry Smith PetscErrorCode ierr; 137047c6ae99SBarry Smith struct DMCompositeLink *next; 137147c6ae99SBarry Smith PetscInt cnt = 3; 137247c6ae99SBarry Smith PetscMPIInt rank; 137347c6ae99SBarry Smith PetscScalar *garray,*larray; 137447c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 137547c6ae99SBarry Smith 137647c6ae99SBarry Smith PetscFunctionBegin; 137747c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 137847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 137947c6ae99SBarry Smith next = com->next; 138047c6ae99SBarry Smith if (!com->setup) { 1381d7bf68aeSBarry Smith ierr = DMSetUp(dm);CHKERRQ(ierr); 138247c6ae99SBarry Smith } 1383ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 138447c6ae99SBarry Smith ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 138547c6ae99SBarry Smith ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 138647c6ae99SBarry Smith 138747c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 138847c6ae99SBarry Smith while (next) { 138947c6ae99SBarry Smith Vec local,global; 139047c6ae99SBarry Smith PetscInt N; 139147c6ae99SBarry Smith 139247c6ae99SBarry Smith ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 139347c6ae99SBarry Smith ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 139447c6ae99SBarry Smith ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 139547c6ae99SBarry Smith ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 139647c6ae99SBarry Smith ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 139747c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 139847c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 139947c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 140047c6ae99SBarry Smith ierr = VecResetArray(local);CHKERRQ(ierr); 140147c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 140247c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); 140347c6ae99SBarry Smith cnt++; 140406ebdd98SJed Brown larray += next->nlocal; 140547c6ae99SBarry Smith next = next->next; 140647c6ae99SBarry Smith } 140747c6ae99SBarry Smith 14080298fd71SBarry Smith ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr); 14090298fd71SBarry Smith ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr); 141047c6ae99SBarry Smith PetscFunctionReturn(0); 141147c6ae99SBarry Smith } 141247c6ae99SBarry Smith 141347c6ae99SBarry Smith #undef __FUNCT__ 14140c010503SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Composite" 14157087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 14160c010503SBarry Smith { 14170c010503SBarry Smith PetscFunctionBegin; 14180c010503SBarry Smith PetscFunctionReturn(0); 14190c010503SBarry Smith } 142047c6ae99SBarry Smith 14216ae3a549SBarry Smith /*MC 14226ae3a549SBarry Smith DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs 14236ae3a549SBarry Smith 14246ae3a549SBarry Smith Level: intermediate 14256ae3a549SBarry Smith 14261abcec8cSBarry Smith .seealso: DMType, DM, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate() 14276ae3a549SBarry Smith M*/ 14286ae3a549SBarry Smith 14296ae3a549SBarry Smith 1430a4121054SBarry Smith #undef __FUNCT__ 1431a4121054SBarry Smith #define __FUNCT__ "DMCreate_Composite" 14328cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Composite(DM p) 1433a4121054SBarry Smith { 1434a4121054SBarry Smith PetscErrorCode ierr; 1435a4121054SBarry Smith DM_Composite *com; 1436a4121054SBarry Smith 1437a4121054SBarry Smith PetscFunctionBegin; 1438b00a9115SJed Brown ierr = PetscNewLog(p,&com);CHKERRQ(ierr); 1439a4121054SBarry Smith p->data = com; 1440a4121054SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 1441a4121054SBarry Smith com->n = 0; 14420298fd71SBarry Smith com->next = NULL; 1443a4121054SBarry Smith com->nDM = 0; 1444a4121054SBarry Smith 1445a4121054SBarry Smith p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1446a4121054SBarry Smith p->ops->createlocalvector = DMCreateLocalVector_Composite; 1447184d77edSJed Brown p->ops->getlocaltoglobalmapping = DMGetLocalToGlobalMapping_Composite; 14484d343eeaSMatthew G Knepley p->ops->createfieldis = DMCreateFieldIS_Composite; 144916621825SDmitry Karpeev p->ops->createfielddecomposition = DMCreateFieldDecomposition_Composite; 1450a4121054SBarry Smith p->ops->refine = DMRefine_Composite; 145114354c39SJed Brown p->ops->coarsen = DMCoarsen_Composite; 145225296bd5SBarry Smith p->ops->createinterpolation = DMCreateInterpolation_Composite; 145325296bd5SBarry Smith p->ops->creatematrix = DMCreateMatrix_Composite; 1454e727c939SJed Brown p->ops->getcoloring = DMCreateColoring_Composite; 1455a4121054SBarry Smith p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1456a4121054SBarry Smith p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 1457a4121054SBarry Smith p->ops->destroy = DMDestroy_Composite; 1458a4121054SBarry Smith p->ops->view = DMView_Composite; 1459a4121054SBarry Smith p->ops->setup = DMSetUp_Composite; 1460a4121054SBarry Smith PetscFunctionReturn(0); 1461a4121054SBarry Smith } 1462a4121054SBarry Smith 14630c010503SBarry Smith #undef __FUNCT__ 14640c010503SBarry Smith #define __FUNCT__ "DMCompositeCreate" 14650c010503SBarry Smith /*@C 14660c010503SBarry Smith DMCompositeCreate - Creates a vector packer, used to generate "composite" 14670c010503SBarry Smith vectors made up of several subvectors. 14680c010503SBarry Smith 14690c010503SBarry Smith Collective on MPI_Comm 147047c6ae99SBarry Smith 147147c6ae99SBarry Smith Input Parameter: 14720c010503SBarry Smith . comm - the processors that will share the global vector 14730c010503SBarry Smith 14740c010503SBarry Smith Output Parameters: 14750c010503SBarry Smith . packer - the packer object 147647c6ae99SBarry Smith 147747c6ae99SBarry Smith Level: advanced 147847c6ae99SBarry Smith 14791abcec8cSBarry Smith .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), DMCOMPOSITE,DMCreate() 14806eb61c8cSJed Brown DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess() 148147c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 148247c6ae99SBarry Smith 148347c6ae99SBarry Smith @*/ 14847087cfbeSBarry Smith PetscErrorCode DMCompositeCreate(MPI_Comm comm,DM *packer) 148547c6ae99SBarry Smith { 14860c010503SBarry Smith PetscErrorCode ierr; 14870c010503SBarry Smith 148847c6ae99SBarry Smith PetscFunctionBegin; 14890c010503SBarry Smith PetscValidPointer(packer,2); 1490a4121054SBarry Smith ierr = DMCreate(comm,packer);CHKERRQ(ierr); 1491a4121054SBarry Smith ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr); 149247c6ae99SBarry Smith PetscFunctionReturn(0); 149347c6ae99SBarry Smith } 1494