1*47c6ae99SBarry Smith #define PETSCDM_DLL 2*47c6ae99SBarry Smith 3*47c6ae99SBarry Smith #include "petscda.h" /*I "petscda.h" I*/ 4*47c6ae99SBarry Smith #include "private/dmimpl.h" 5*47c6ae99SBarry Smith #include "petscmat.h" 6*47c6ae99SBarry Smith 7*47c6ae99SBarry Smith /* 8*47c6ae99SBarry Smith rstart is where an array/subvector starts in the global parallel vector, so arrays 9*47c6ae99SBarry Smith rstarts are meaningless (and set to the previous one) except on the processor where the array lives 10*47c6ae99SBarry Smith */ 11*47c6ae99SBarry Smith 12*47c6ae99SBarry Smith typedef enum {DMCOMPOSITE_ARRAY, DMCOMPOSITE_DM} DMCompositeLinkType; 13*47c6ae99SBarry Smith 14*47c6ae99SBarry Smith struct DMCompositeLink { 15*47c6ae99SBarry Smith DMCompositeLinkType type; 16*47c6ae99SBarry Smith struct DMCompositeLink *next; 17*47c6ae99SBarry Smith PetscInt n,rstart; /* rstart is relative to this process */ 18*47c6ae99SBarry Smith PetscInt grstart; /* grstart is relative to all processes */ 19*47c6ae99SBarry Smith 20*47c6ae99SBarry Smith /* only used for DMCOMPOSITE_DM */ 21*47c6ae99SBarry Smith PetscInt *grstarts; /* global row for first unknown of this DM on each process */ 22*47c6ae99SBarry Smith DM dm; 23*47c6ae99SBarry Smith 24*47c6ae99SBarry Smith /* only used for DMCOMPOSITE_ARRAY */ 25*47c6ae99SBarry Smith PetscMPIInt rank; /* process where array unknowns live */ 26*47c6ae99SBarry Smith }; 27*47c6ae99SBarry Smith 28*47c6ae99SBarry Smith typedef struct { 29*47c6ae99SBarry Smith PetscInt n,N,rstart; /* rstart is relative to all processors, n unknowns owned by this process, N is total unknowns */ 30*47c6ae99SBarry Smith PetscInt nghost; /* number of all local entries include DA ghost points and any shared redundant arrays */ 31*47c6ae99SBarry Smith PetscInt nDM,nredundant,nmine; /* how many DM's and seperate redundant arrays used to build DM(nmine is ones on this process) */ 32*47c6ae99SBarry Smith PetscBool setup; /* after this is set, cannot add new links to the DM*/ 33*47c6ae99SBarry Smith struct DMCompositeLink *next; 34*47c6ae99SBarry Smith 35*47c6ae99SBarry Smith PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt); 36*47c6ae99SBarry Smith } DM_Composite; 37*47c6ae99SBarry Smith 38*47c6ae99SBarry Smith #undef __FUNCT__ 39*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetCoupling" 40*47c6ae99SBarry Smith /*@C 41*47c6ae99SBarry Smith DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the 42*47c6ae99SBarry Smith seperate components (DA's and arrays) in a DMto build the correct matrix nonzero structure. 43*47c6ae99SBarry Smith 44*47c6ae99SBarry Smith 45*47c6ae99SBarry Smith Logically Collective on MPI_Comm 46*47c6ae99SBarry Smith 47*47c6ae99SBarry Smith Input Parameter: 48*47c6ae99SBarry Smith + dm - the composite object 49*47c6ae99SBarry Smith - formcouplelocations - routine to set the nonzero locations in the matrix 50*47c6ae99SBarry Smith 51*47c6ae99SBarry Smith Level: advanced 52*47c6ae99SBarry Smith 53*47c6ae99SBarry Smith Notes: See DMCompositeSetContext() and DMCompositeGetContext() for how to get user information into 54*47c6ae99SBarry Smith this routine 55*47c6ae99SBarry Smith 56*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(), 57*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreateGlobalVector(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess() 58*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), DMCompositeSetContext(), 59*47c6ae99SBarry Smith DMCompositeGetContext() 60*47c6ae99SBarry Smith 61*47c6ae99SBarry Smith @*/ 62*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt)) 63*47c6ae99SBarry Smith { 64*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 65*47c6ae99SBarry Smith 66*47c6ae99SBarry Smith PetscFunctionBegin; 67*47c6ae99SBarry Smith com->FormCoupleLocations = FormCoupleLocations; 68*47c6ae99SBarry Smith PetscFunctionReturn(0); 69*47c6ae99SBarry Smith } 70*47c6ae99SBarry Smith 71*47c6ae99SBarry Smith #undef __FUNCT__ 72*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetContext" 73*47c6ae99SBarry Smith /*@ 74*47c6ae99SBarry Smith DMCompositeSetContext - Allows user to stash data they may need within the form coupling routine they 75*47c6ae99SBarry Smith set with DMCompositeSetCoupling() 76*47c6ae99SBarry Smith 77*47c6ae99SBarry Smith 78*47c6ae99SBarry Smith Not Collective 79*47c6ae99SBarry Smith 80*47c6ae99SBarry Smith Input Parameter: 81*47c6ae99SBarry Smith + dm - the composite object 82*47c6ae99SBarry Smith - ctx - the user supplied context 83*47c6ae99SBarry Smith 84*47c6ae99SBarry Smith Level: advanced 85*47c6ae99SBarry Smith 86*47c6ae99SBarry Smith Notes: Use DMCompositeGetContext() to retrieve the context when needed. 87*47c6ae99SBarry Smith 88*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(), 89*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreateGlobalVector(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess() 90*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), DMCompositeSetCoupling(), 91*47c6ae99SBarry Smith DMCompositeGetContext() 92*47c6ae99SBarry Smith 93*47c6ae99SBarry Smith @*/ 94*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeSetContext(DM dm,void *ctx) 95*47c6ae99SBarry Smith { 96*47c6ae99SBarry Smith PetscFunctionBegin; 97*47c6ae99SBarry Smith dm->ctx = ctx; 98*47c6ae99SBarry Smith PetscFunctionReturn(0); 99*47c6ae99SBarry Smith } 100*47c6ae99SBarry Smith 101*47c6ae99SBarry Smith #undef __FUNCT__ 102*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetContext" 103*47c6ae99SBarry Smith /*@ 104*47c6ae99SBarry Smith DMCompositeGetContext - Access the context set with DMCompositeSetContext() 105*47c6ae99SBarry Smith 106*47c6ae99SBarry Smith 107*47c6ae99SBarry Smith Not Collective 108*47c6ae99SBarry Smith 109*47c6ae99SBarry Smith Input Parameter: 110*47c6ae99SBarry Smith . dm - the composite object 111*47c6ae99SBarry Smith 112*47c6ae99SBarry Smith Output Parameter: 113*47c6ae99SBarry Smith . ctx - the user supplied context 114*47c6ae99SBarry Smith 115*47c6ae99SBarry Smith Level: advanced 116*47c6ae99SBarry Smith 117*47c6ae99SBarry Smith Notes: Use DMCompositeGetContext() to retrieve the context when needed. 118*47c6ae99SBarry Smith 119*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(), 120*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreateGlobalVector(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess() 121*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), DMCompositeSetCoupling(), 122*47c6ae99SBarry Smith DMCompositeSetContext() 123*47c6ae99SBarry Smith 124*47c6ae99SBarry Smith @*/ 125*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetContext(DM dm,void **ctx) 126*47c6ae99SBarry Smith { 127*47c6ae99SBarry Smith PetscFunctionBegin; 128*47c6ae99SBarry Smith *ctx = dm->ctx; 129*47c6ae99SBarry Smith PetscFunctionReturn(0); 130*47c6ae99SBarry Smith } 131*47c6ae99SBarry Smith 132*47c6ae99SBarry Smith 133*47c6ae99SBarry Smith #undef __FUNCT__ 134*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeCreate" 135*47c6ae99SBarry Smith /*@C 136*47c6ae99SBarry Smith DMCompositeCreate - Creates a vector packer, used to generate "composite" 137*47c6ae99SBarry Smith vectors made up of several subvectors. 138*47c6ae99SBarry Smith 139*47c6ae99SBarry Smith Collective on MPI_Comm 140*47c6ae99SBarry Smith 141*47c6ae99SBarry Smith Input Parameter: 142*47c6ae99SBarry Smith . comm - the processors that will share the global vector 143*47c6ae99SBarry Smith 144*47c6ae99SBarry Smith Output Parameters: 145*47c6ae99SBarry Smith . packer - the packer object 146*47c6ae99SBarry Smith 147*47c6ae99SBarry Smith Level: advanced 148*47c6ae99SBarry Smith 149*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(), 150*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreateGlobalVector(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess() 151*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 152*47c6ae99SBarry Smith 153*47c6ae99SBarry Smith @*/ 154*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeCreate(MPI_Comm comm,DM *packer) 155*47c6ae99SBarry Smith { 156*47c6ae99SBarry Smith PetscErrorCode ierr; 157*47c6ae99SBarry Smith DM p; 158*47c6ae99SBarry Smith DM_Composite *com; 159*47c6ae99SBarry Smith 160*47c6ae99SBarry Smith PetscFunctionBegin; 161*47c6ae99SBarry Smith PetscValidPointer(packer,2); 162*47c6ae99SBarry Smith *packer = PETSC_NULL; 163*47c6ae99SBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES 164*47c6ae99SBarry Smith ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr); 165*47c6ae99SBarry Smith #endif 166*47c6ae99SBarry Smith 167*47c6ae99SBarry Smith ierr = PetscHeaderCreate(p,_p_DM,struct _DMOps,DM_CLASSID,0,"DM",comm,DMCompositeDestroy,DMCompositeView);CHKERRQ(ierr); 168*47c6ae99SBarry Smith ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr); 169*47c6ae99SBarry Smith p->data = com; 170*47c6ae99SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 171*47c6ae99SBarry Smith com->n = 0; 172*47c6ae99SBarry Smith com->next = PETSC_NULL; 173*47c6ae99SBarry Smith com->nredundant = 0; 174*47c6ae99SBarry Smith com->nDM = 0; 175*47c6ae99SBarry Smith 176*47c6ae99SBarry Smith p->ops->createglobalvector = DMCompositeCreateGlobalVector; 177*47c6ae99SBarry Smith p->ops->createlocalvector = DMCompositeCreateLocalVector; 178*47c6ae99SBarry Smith p->ops->refine = DMCompositeRefine; 179*47c6ae99SBarry Smith p->ops->getinterpolation = DMCompositeGetInterpolation; 180*47c6ae99SBarry Smith p->ops->getmatrix = DMCompositeGetMatrix; 181*47c6ae99SBarry Smith p->ops->getcoloring = DMCompositeGetColoring; 182*47c6ae99SBarry Smith p->ops->globaltolocalbegin = DMCompositeGlobalToLocalBegin; 183*47c6ae99SBarry Smith p->ops->globaltolocalend = DMCompositeGlobalToLocalEnd; 184*47c6ae99SBarry Smith p->ops->destroy = DMCompositeDestroy; 185*47c6ae99SBarry Smith 186*47c6ae99SBarry Smith *packer = p; 187*47c6ae99SBarry Smith PetscFunctionReturn(0); 188*47c6ae99SBarry Smith } 189*47c6ae99SBarry Smith 190*47c6ae99SBarry Smith extern PetscErrorCode DMDestroy_Private(DM,PetscBool *); 191*47c6ae99SBarry Smith 192*47c6ae99SBarry Smith #undef __FUNCT__ 193*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeDestroy" 194*47c6ae99SBarry Smith /*@C 195*47c6ae99SBarry Smith DMCompositeDestroy - Destroys a vector packer. 196*47c6ae99SBarry Smith 197*47c6ae99SBarry Smith Collective on DMComposite 198*47c6ae99SBarry Smith 199*47c6ae99SBarry Smith Input Parameter: 200*47c6ae99SBarry Smith . packer - the packer object 201*47c6ae99SBarry Smith 202*47c6ae99SBarry Smith Level: advanced 203*47c6ae99SBarry Smith 204*47c6ae99SBarry Smith .seealso DMCompositeCreate(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(),DMCompositeGetEntries() 205*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreateGlobalVector(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess() 206*47c6ae99SBarry Smith 207*47c6ae99SBarry Smith @*/ 208*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeDestroy(DM dm) 209*47c6ae99SBarry Smith { 210*47c6ae99SBarry Smith PetscErrorCode ierr; 211*47c6ae99SBarry Smith struct DMCompositeLink *next, *prev; 212*47c6ae99SBarry Smith PetscBool done; 213*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 214*47c6ae99SBarry Smith 215*47c6ae99SBarry Smith PetscFunctionBegin; 216*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 217*47c6ae99SBarry Smith ierr = DMDestroy_Private((DM)dm,&done);CHKERRQ(ierr); 218*47c6ae99SBarry Smith if (!done) PetscFunctionReturn(0); 219*47c6ae99SBarry Smith 220*47c6ae99SBarry Smith next = com->next; 221*47c6ae99SBarry Smith while (next) { 222*47c6ae99SBarry Smith prev = next; 223*47c6ae99SBarry Smith next = next->next; 224*47c6ae99SBarry Smith if (prev->type == DMCOMPOSITE_DM) { 225*47c6ae99SBarry Smith ierr = DMDestroy(prev->dm);CHKERRQ(ierr); 226*47c6ae99SBarry Smith } 227*47c6ae99SBarry Smith if (prev->grstarts) { 228*47c6ae99SBarry Smith ierr = PetscFree(prev->grstarts);CHKERRQ(ierr); 229*47c6ae99SBarry Smith } 230*47c6ae99SBarry Smith ierr = PetscFree(prev);CHKERRQ(ierr); 231*47c6ae99SBarry Smith } 232*47c6ae99SBarry Smith ierr = PetscFree(com);CHKERRQ(ierr); 233*47c6ae99SBarry Smith ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 234*47c6ae99SBarry Smith PetscFunctionReturn(0); 235*47c6ae99SBarry Smith } 236*47c6ae99SBarry Smith 237*47c6ae99SBarry Smith #undef __FUNCT__ 238*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeView" 239*47c6ae99SBarry Smith /*@ 240*47c6ae99SBarry Smith DMCompositeView - Views a composite DM 241*47c6ae99SBarry Smith 242*47c6ae99SBarry Smith Collective on DMComposite 243*47c6ae99SBarry Smith 244*47c6ae99SBarry Smith Input Parameter: 245*47c6ae99SBarry Smith + packer - the DMobject to view 246*47c6ae99SBarry Smith - v - the viewer 247*47c6ae99SBarry Smith 248*47c6ae99SBarry Smith Level: intermediate 249*47c6ae99SBarry Smith 250*47c6ae99SBarry Smith .seealso DMCompositeCreate() 251*47c6ae99SBarry Smith 252*47c6ae99SBarry Smith @*/ 253*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeView(DM dm,PetscViewer v) 254*47c6ae99SBarry Smith { 255*47c6ae99SBarry Smith PetscErrorCode ierr; 256*47c6ae99SBarry Smith PetscBool iascii; 257*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 258*47c6ae99SBarry Smith 259*47c6ae99SBarry Smith PetscFunctionBegin; 260*47c6ae99SBarry Smith ierr = PetscTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 261*47c6ae99SBarry Smith if (iascii) { 262*47c6ae99SBarry Smith struct DMCompositeLink *lnk = com->next; 263*47c6ae99SBarry Smith PetscInt i; 264*47c6ae99SBarry Smith 265*47c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix?((PetscObject)dm)->prefix:"no prefix");CHKERRQ(ierr); 266*47c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v," contains %d DMs and %d redundant arrays\n",com->nDM,com->nredundant);CHKERRQ(ierr); 267*47c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 268*47c6ae99SBarry Smith for (i=0; lnk; lnk=lnk->next,i++) { 269*47c6ae99SBarry Smith if (lnk->dm) { 270*47c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v,"Link %d: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr); 271*47c6ae99SBarry Smith ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 272*47c6ae99SBarry Smith ierr = DMView(lnk->dm,v);CHKERRQ(ierr); 273*47c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 274*47c6ae99SBarry Smith } else { 275*47c6ae99SBarry Smith ierr = PetscViewerASCIIPrintf(v,"Link %d: Redundant array of size %d owned by rank %d\n",i,lnk->n,lnk->rank);CHKERRQ(ierr); 276*47c6ae99SBarry Smith } 277*47c6ae99SBarry Smith } 278*47c6ae99SBarry Smith ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 279*47c6ae99SBarry Smith } 280*47c6ae99SBarry Smith PetscFunctionReturn(0); 281*47c6ae99SBarry Smith } 282*47c6ae99SBarry Smith 283*47c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/ 284*47c6ae99SBarry Smith #undef __FUNCT__ 285*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeSetUp" 286*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeSetUp(DM dm) 287*47c6ae99SBarry Smith { 288*47c6ae99SBarry Smith PetscErrorCode ierr; 289*47c6ae99SBarry Smith PetscInt nprev = 0; 290*47c6ae99SBarry Smith PetscMPIInt rank,size; 291*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 292*47c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 293*47c6ae99SBarry Smith PetscLayout map; 294*47c6ae99SBarry Smith 295*47c6ae99SBarry Smith PetscFunctionBegin; 296*47c6ae99SBarry Smith if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); 297*47c6ae99SBarry Smith ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr); 298*47c6ae99SBarry Smith ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); 299*47c6ae99SBarry Smith ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); 300*47c6ae99SBarry Smith ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 301*47c6ae99SBarry Smith ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 302*47c6ae99SBarry Smith ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); 303*47c6ae99SBarry Smith ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr); 304*47c6ae99SBarry Smith ierr = PetscLayoutDestroy(map);CHKERRQ(ierr); 305*47c6ae99SBarry Smith 306*47c6ae99SBarry Smith /* now set the rstart for each linked array/vector */ 307*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 308*47c6ae99SBarry Smith ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr); 309*47c6ae99SBarry Smith while (next) { 310*47c6ae99SBarry Smith next->rstart = nprev; 311*47c6ae99SBarry Smith if ((rank == next->rank) || next->type != DMCOMPOSITE_ARRAY) nprev += next->n; 312*47c6ae99SBarry Smith next->grstart = com->rstart + next->rstart; 313*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 314*47c6ae99SBarry Smith ierr = MPI_Bcast(&next->grstart,1,MPIU_INT,next->rank,((PetscObject)dm)->comm);CHKERRQ(ierr); 315*47c6ae99SBarry Smith } else { 316*47c6ae99SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr); 317*47c6ae99SBarry Smith ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 318*47c6ae99SBarry Smith } 319*47c6ae99SBarry Smith next = next->next; 320*47c6ae99SBarry Smith } 321*47c6ae99SBarry Smith com->setup = PETSC_TRUE; 322*47c6ae99SBarry Smith PetscFunctionReturn(0); 323*47c6ae99SBarry Smith } 324*47c6ae99SBarry Smith 325*47c6ae99SBarry Smith 326*47c6ae99SBarry Smith #undef __FUNCT__ 327*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess_Array" 328*47c6ae99SBarry Smith PetscErrorCode DMCompositeGetAccess_Array(DM dm,struct DMCompositeLink *mine,Vec vec,PetscScalar **array) 329*47c6ae99SBarry Smith { 330*47c6ae99SBarry Smith PetscErrorCode ierr; 331*47c6ae99SBarry Smith PetscScalar *varray; 332*47c6ae99SBarry Smith PetscMPIInt rank; 333*47c6ae99SBarry Smith 334*47c6ae99SBarry Smith PetscFunctionBegin; 335*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 336*47c6ae99SBarry Smith if (array) { 337*47c6ae99SBarry Smith if (rank == mine->rank) { 338*47c6ae99SBarry Smith ierr = VecGetArray(vec,&varray);CHKERRQ(ierr); 339*47c6ae99SBarry Smith *array = varray + mine->rstart; 340*47c6ae99SBarry Smith ierr = VecRestoreArray(vec,&varray);CHKERRQ(ierr); 341*47c6ae99SBarry Smith } else { 342*47c6ae99SBarry Smith *array = 0; 343*47c6ae99SBarry Smith } 344*47c6ae99SBarry Smith } 345*47c6ae99SBarry Smith PetscFunctionReturn(0); 346*47c6ae99SBarry Smith } 347*47c6ae99SBarry Smith 348*47c6ae99SBarry Smith #undef __FUNCT__ 349*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess_DM" 350*47c6ae99SBarry Smith PetscErrorCode DMCompositeGetAccess_DM(DM dm,struct DMCompositeLink *mine,Vec vec,Vec *global) 351*47c6ae99SBarry Smith { 352*47c6ae99SBarry Smith PetscErrorCode ierr; 353*47c6ae99SBarry Smith PetscScalar *array; 354*47c6ae99SBarry Smith 355*47c6ae99SBarry Smith PetscFunctionBegin; 356*47c6ae99SBarry Smith if (global) { 357*47c6ae99SBarry Smith ierr = DMGetGlobalVector(mine->dm,global);CHKERRQ(ierr); 358*47c6ae99SBarry Smith ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 359*47c6ae99SBarry Smith ierr = VecPlaceArray(*global,array+mine->rstart);CHKERRQ(ierr); 360*47c6ae99SBarry Smith ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 361*47c6ae99SBarry Smith } 362*47c6ae99SBarry Smith PetscFunctionReturn(0); 363*47c6ae99SBarry Smith } 364*47c6ae99SBarry Smith 365*47c6ae99SBarry Smith #undef __FUNCT__ 366*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess_Array" 367*47c6ae99SBarry Smith PetscErrorCode DMCompositeRestoreAccess_Array(DM dm,struct DMCompositeLink *mine,Vec vec,PetscScalar **array) 368*47c6ae99SBarry Smith { 369*47c6ae99SBarry Smith PetscFunctionBegin; 370*47c6ae99SBarry Smith PetscFunctionReturn(0); 371*47c6ae99SBarry Smith } 372*47c6ae99SBarry Smith 373*47c6ae99SBarry Smith #undef __FUNCT__ 374*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess_DM" 375*47c6ae99SBarry Smith PetscErrorCode DMCompositeRestoreAccess_DM(DM dm,struct DMCompositeLink *mine,Vec vec,Vec *global) 376*47c6ae99SBarry Smith { 377*47c6ae99SBarry Smith PetscErrorCode ierr; 378*47c6ae99SBarry Smith 379*47c6ae99SBarry Smith PetscFunctionBegin; 380*47c6ae99SBarry Smith if (global) { 381*47c6ae99SBarry Smith ierr = VecResetArray(*global);CHKERRQ(ierr); 382*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(mine->dm,global);CHKERRQ(ierr); 383*47c6ae99SBarry Smith } 384*47c6ae99SBarry Smith PetscFunctionReturn(0); 385*47c6ae99SBarry Smith } 386*47c6ae99SBarry Smith 387*47c6ae99SBarry Smith #undef __FUNCT__ 388*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter_Array" 389*47c6ae99SBarry Smith PetscErrorCode DMCompositeScatter_Array(DM dm,struct DMCompositeLink *mine,Vec vec,PetscScalar *array) 390*47c6ae99SBarry Smith { 391*47c6ae99SBarry Smith PetscErrorCode ierr; 392*47c6ae99SBarry Smith PetscScalar *varray; 393*47c6ae99SBarry Smith PetscMPIInt rank; 394*47c6ae99SBarry Smith 395*47c6ae99SBarry Smith PetscFunctionBegin; 396*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 397*47c6ae99SBarry Smith if (rank == mine->rank) { 398*47c6ae99SBarry Smith ierr = VecGetArray(vec,&varray);CHKERRQ(ierr); 399*47c6ae99SBarry Smith ierr = PetscMemcpy(array,varray+mine->rstart,mine->n*sizeof(PetscScalar));CHKERRQ(ierr); 400*47c6ae99SBarry Smith ierr = VecRestoreArray(vec,&varray);CHKERRQ(ierr); 401*47c6ae99SBarry Smith } 402*47c6ae99SBarry Smith ierr = MPI_Bcast(array,mine->n,MPIU_SCALAR,mine->rank,((PetscObject)dm)->comm);CHKERRQ(ierr); 403*47c6ae99SBarry Smith PetscFunctionReturn(0); 404*47c6ae99SBarry Smith } 405*47c6ae99SBarry Smith 406*47c6ae99SBarry Smith #undef __FUNCT__ 407*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter_DM" 408*47c6ae99SBarry Smith PetscErrorCode DMCompositeScatter_DM(DM dm,struct DMCompositeLink *mine,Vec vec,Vec local) 409*47c6ae99SBarry Smith { 410*47c6ae99SBarry Smith PetscErrorCode ierr; 411*47c6ae99SBarry Smith PetscScalar *array; 412*47c6ae99SBarry Smith Vec global; 413*47c6ae99SBarry Smith 414*47c6ae99SBarry Smith PetscFunctionBegin; 415*47c6ae99SBarry Smith ierr = DMGetGlobalVector(mine->dm,&global);CHKERRQ(ierr); 416*47c6ae99SBarry Smith ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 417*47c6ae99SBarry Smith ierr = VecPlaceArray(global,array+mine->rstart);CHKERRQ(ierr); 418*47c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(mine->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 419*47c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(mine->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 420*47c6ae99SBarry Smith ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 421*47c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 422*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(mine->dm,&global);CHKERRQ(ierr); 423*47c6ae99SBarry Smith PetscFunctionReturn(0); 424*47c6ae99SBarry Smith } 425*47c6ae99SBarry Smith 426*47c6ae99SBarry Smith #undef __FUNCT__ 427*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather_Array" 428*47c6ae99SBarry Smith PetscErrorCode DMCompositeGather_Array(DM dm,struct DMCompositeLink *mine,Vec vec,PetscScalar *array) 429*47c6ae99SBarry Smith { 430*47c6ae99SBarry Smith PetscErrorCode ierr; 431*47c6ae99SBarry Smith PetscScalar *varray; 432*47c6ae99SBarry Smith PetscMPIInt rank; 433*47c6ae99SBarry Smith 434*47c6ae99SBarry Smith PetscFunctionBegin; 435*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 436*47c6ae99SBarry Smith if (rank == mine->rank) { 437*47c6ae99SBarry Smith ierr = VecGetArray(vec,&varray);CHKERRQ(ierr); 438*47c6ae99SBarry Smith if (varray+mine->rstart == array) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"You need not DMCompositeGather() into objects obtained via DMCompositeGetAccess()"); 439*47c6ae99SBarry Smith ierr = PetscMemcpy(varray+mine->rstart,array,mine->n*sizeof(PetscScalar));CHKERRQ(ierr); 440*47c6ae99SBarry Smith ierr = VecRestoreArray(vec,&varray);CHKERRQ(ierr); 441*47c6ae99SBarry Smith } 442*47c6ae99SBarry Smith PetscFunctionReturn(0); 443*47c6ae99SBarry Smith } 444*47c6ae99SBarry Smith 445*47c6ae99SBarry Smith #undef __FUNCT__ 446*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather_DM" 447*47c6ae99SBarry Smith PetscErrorCode DMCompositeGather_DM(DM dm,struct DMCompositeLink *mine,Vec vec,Vec local) 448*47c6ae99SBarry Smith { 449*47c6ae99SBarry Smith PetscErrorCode ierr; 450*47c6ae99SBarry Smith PetscScalar *array; 451*47c6ae99SBarry Smith Vec global; 452*47c6ae99SBarry Smith 453*47c6ae99SBarry Smith PetscFunctionBegin; 454*47c6ae99SBarry Smith ierr = DMGetGlobalVector(mine->dm,&global);CHKERRQ(ierr); 455*47c6ae99SBarry Smith ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 456*47c6ae99SBarry Smith ierr = VecPlaceArray(global,array+mine->rstart);CHKERRQ(ierr); 457*47c6ae99SBarry Smith ierr = DMLocalToGlobal(mine->dm,local,INSERT_VALUES,global);CHKERRQ(ierr); 458*47c6ae99SBarry Smith ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 459*47c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 460*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(mine->dm,&global);CHKERRQ(ierr); 461*47c6ae99SBarry Smith PetscFunctionReturn(0); 462*47c6ae99SBarry Smith } 463*47c6ae99SBarry Smith 464*47c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/ 465*47c6ae99SBarry Smith 466*47c6ae99SBarry Smith #include <stdarg.h> 467*47c6ae99SBarry Smith 468*47c6ae99SBarry Smith #undef __FUNCT__ 469*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetNumberDM" 470*47c6ae99SBarry Smith /*@C 471*47c6ae99SBarry Smith DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite 472*47c6ae99SBarry Smith representation. 473*47c6ae99SBarry Smith 474*47c6ae99SBarry Smith Not Collective 475*47c6ae99SBarry Smith 476*47c6ae99SBarry Smith Input Parameter: 477*47c6ae99SBarry Smith . dm - the packer object 478*47c6ae99SBarry Smith 479*47c6ae99SBarry Smith Output Parameter: 480*47c6ae99SBarry Smith . nDM - the number of DMs 481*47c6ae99SBarry Smith 482*47c6ae99SBarry Smith Level: beginner 483*47c6ae99SBarry Smith 484*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 485*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeScatter(), 486*47c6ae99SBarry Smith DMCompositeRestoreAccess(), DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), 487*47c6ae99SBarry Smith DMCompositeGetEntries() 488*47c6ae99SBarry Smith 489*47c6ae99SBarry Smith @*/ 490*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetNumberDM(DM dm,PetscInt *nDM) 491*47c6ae99SBarry Smith { 492*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 493*47c6ae99SBarry Smith PetscFunctionBegin; 494*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 495*47c6ae99SBarry Smith *nDM = com->nDM; 496*47c6ae99SBarry Smith PetscFunctionReturn(0); 497*47c6ae99SBarry Smith } 498*47c6ae99SBarry Smith 499*47c6ae99SBarry Smith 500*47c6ae99SBarry Smith #undef __FUNCT__ 501*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetAccess" 502*47c6ae99SBarry Smith /*@C 503*47c6ae99SBarry Smith DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 504*47c6ae99SBarry Smith representation. 505*47c6ae99SBarry Smith 506*47c6ae99SBarry Smith Collective on DMComposite 507*47c6ae99SBarry Smith 508*47c6ae99SBarry Smith Input Parameter: 509*47c6ae99SBarry Smith + dm - the packer object 510*47c6ae99SBarry Smith . gvec - the global vector 511*47c6ae99SBarry Smith - ... - the individual sequential or parallel objects (arrays or vectors) 512*47c6ae99SBarry Smith 513*47c6ae99SBarry Smith Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them 514*47c6ae99SBarry Smith 515*47c6ae99SBarry Smith Level: advanced 516*47c6ae99SBarry Smith 517*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 518*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeScatter(), 519*47c6ae99SBarry Smith DMCompositeRestoreAccess(), DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), 520*47c6ae99SBarry Smith DMCompositeGetEntries() 521*47c6ae99SBarry Smith 522*47c6ae99SBarry Smith @*/ 523*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetAccess(DM dm,Vec gvec,...) 524*47c6ae99SBarry Smith { 525*47c6ae99SBarry Smith va_list Argp; 526*47c6ae99SBarry Smith PetscErrorCode ierr; 527*47c6ae99SBarry Smith struct DMCompositeLink *next; 528*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 529*47c6ae99SBarry Smith 530*47c6ae99SBarry Smith PetscFunctionBegin; 531*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 532*47c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 533*47c6ae99SBarry Smith next = com->next; 534*47c6ae99SBarry Smith if (!com->setup) { 535*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 536*47c6ae99SBarry Smith } 537*47c6ae99SBarry Smith 538*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 539*47c6ae99SBarry Smith va_start(Argp,gvec); 540*47c6ae99SBarry Smith while (next) { 541*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 542*47c6ae99SBarry Smith PetscScalar **array; 543*47c6ae99SBarry Smith array = va_arg(Argp, PetscScalar**); 544*47c6ae99SBarry Smith ierr = DMCompositeGetAccess_Array(dm,next,gvec,array);CHKERRQ(ierr); 545*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 546*47c6ae99SBarry Smith Vec *vec; 547*47c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 548*47c6ae99SBarry Smith ierr = DMCompositeGetAccess_DM(dm,next,gvec,vec);CHKERRQ(ierr); 549*47c6ae99SBarry Smith } else { 550*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 551*47c6ae99SBarry Smith } 552*47c6ae99SBarry Smith next = next->next; 553*47c6ae99SBarry Smith } 554*47c6ae99SBarry Smith va_end(Argp); 555*47c6ae99SBarry Smith PetscFunctionReturn(0); 556*47c6ae99SBarry Smith } 557*47c6ae99SBarry Smith 558*47c6ae99SBarry Smith #undef __FUNCT__ 559*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreAccess" 560*47c6ae99SBarry Smith /*@C 561*47c6ae99SBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with DACompositeGetAccess() 562*47c6ae99SBarry Smith representation. 563*47c6ae99SBarry Smith 564*47c6ae99SBarry Smith Collective on DMComposite 565*47c6ae99SBarry Smith 566*47c6ae99SBarry Smith Input Parameter: 567*47c6ae99SBarry Smith + dm - the packer object 568*47c6ae99SBarry Smith . gvec - the global vector 569*47c6ae99SBarry Smith - ... - the individual sequential or parallel objects (arrays or vectors) 570*47c6ae99SBarry Smith 571*47c6ae99SBarry Smith Level: advanced 572*47c6ae99SBarry Smith 573*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 574*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeScatter(), 575*47c6ae99SBarry Smith DMCompositeRestoreAccess(), DACompositeGetAccess() 576*47c6ae99SBarry Smith 577*47c6ae99SBarry Smith @*/ 578*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeRestoreAccess(DM dm,Vec gvec,...) 579*47c6ae99SBarry Smith { 580*47c6ae99SBarry Smith va_list Argp; 581*47c6ae99SBarry Smith PetscErrorCode ierr; 582*47c6ae99SBarry Smith struct DMCompositeLink *next; 583*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 584*47c6ae99SBarry Smith 585*47c6ae99SBarry Smith PetscFunctionBegin; 586*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 587*47c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 588*47c6ae99SBarry Smith next = com->next; 589*47c6ae99SBarry Smith if (!com->setup) { 590*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 591*47c6ae99SBarry Smith } 592*47c6ae99SBarry Smith 593*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 594*47c6ae99SBarry Smith va_start(Argp,gvec); 595*47c6ae99SBarry Smith while (next) { 596*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 597*47c6ae99SBarry Smith PetscScalar **array; 598*47c6ae99SBarry Smith array = va_arg(Argp, PetscScalar**); 599*47c6ae99SBarry Smith ierr = DMCompositeRestoreAccess_Array(dm,next,gvec,array);CHKERRQ(ierr); 600*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 601*47c6ae99SBarry Smith Vec *vec; 602*47c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 603*47c6ae99SBarry Smith ierr = DMCompositeRestoreAccess_DM(dm,next,gvec,vec);CHKERRQ(ierr); 604*47c6ae99SBarry Smith } else { 605*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 606*47c6ae99SBarry Smith } 607*47c6ae99SBarry Smith next = next->next; 608*47c6ae99SBarry Smith } 609*47c6ae99SBarry Smith va_end(Argp); 610*47c6ae99SBarry Smith PetscFunctionReturn(0); 611*47c6ae99SBarry Smith } 612*47c6ae99SBarry Smith 613*47c6ae99SBarry Smith #undef __FUNCT__ 614*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeScatter" 615*47c6ae99SBarry Smith /*@C 616*47c6ae99SBarry Smith DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 617*47c6ae99SBarry Smith 618*47c6ae99SBarry Smith Collective on DMComposite 619*47c6ae99SBarry Smith 620*47c6ae99SBarry Smith Input Parameter: 621*47c6ae99SBarry Smith + dm - the packer object 622*47c6ae99SBarry Smith . gvec - the global vector 623*47c6ae99SBarry Smith - ... - the individual sequential objects (arrays or vectors) 624*47c6ae99SBarry Smith 625*47c6ae99SBarry Smith Level: advanced 626*47c6ae99SBarry Smith 627*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 628*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 629*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 630*47c6ae99SBarry Smith 631*47c6ae99SBarry Smith @*/ 632*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeScatter(DM dm,Vec gvec,...) 633*47c6ae99SBarry Smith { 634*47c6ae99SBarry Smith va_list Argp; 635*47c6ae99SBarry Smith PetscErrorCode ierr; 636*47c6ae99SBarry Smith struct DMCompositeLink *next; 637*47c6ae99SBarry Smith PetscInt cnt = 3; 638*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 639*47c6ae99SBarry Smith 640*47c6ae99SBarry Smith PetscFunctionBegin; 641*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 642*47c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 643*47c6ae99SBarry Smith next = com->next; 644*47c6ae99SBarry Smith if (!com->setup) { 645*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 646*47c6ae99SBarry Smith } 647*47c6ae99SBarry Smith 648*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 649*47c6ae99SBarry Smith va_start(Argp,gvec); 650*47c6ae99SBarry Smith while (next) { 651*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 652*47c6ae99SBarry Smith PetscScalar *array; 653*47c6ae99SBarry Smith array = va_arg(Argp, PetscScalar*); 654*47c6ae99SBarry Smith ierr = DMCompositeScatter_Array(dm,next,gvec,array);CHKERRQ(ierr); 655*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 656*47c6ae99SBarry Smith Vec vec; 657*47c6ae99SBarry Smith vec = va_arg(Argp, Vec); 658*47c6ae99SBarry Smith PetscValidHeaderSpecific(vec,VEC_CLASSID,cnt); 659*47c6ae99SBarry Smith ierr = DMCompositeScatter_DM(dm,next,gvec,vec);CHKERRQ(ierr); 660*47c6ae99SBarry Smith } else { 661*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 662*47c6ae99SBarry Smith } 663*47c6ae99SBarry Smith cnt++; 664*47c6ae99SBarry Smith next = next->next; 665*47c6ae99SBarry Smith } 666*47c6ae99SBarry Smith va_end(Argp); 667*47c6ae99SBarry Smith PetscFunctionReturn(0); 668*47c6ae99SBarry Smith } 669*47c6ae99SBarry Smith 670*47c6ae99SBarry Smith #undef __FUNCT__ 671*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGather" 672*47c6ae99SBarry Smith /*@C 673*47c6ae99SBarry Smith DMCompositeGather - Gathers into a global packed vector from its individual local vectors 674*47c6ae99SBarry Smith 675*47c6ae99SBarry Smith Collective on DMComposite 676*47c6ae99SBarry Smith 677*47c6ae99SBarry Smith Input Parameter: 678*47c6ae99SBarry Smith + dm - the packer object 679*47c6ae99SBarry Smith . gvec - the global vector 680*47c6ae99SBarry Smith - ... - the individual sequential objects (arrays or vectors) 681*47c6ae99SBarry Smith 682*47c6ae99SBarry Smith Level: advanced 683*47c6ae99SBarry Smith 684*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 685*47c6ae99SBarry Smith DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 686*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 687*47c6ae99SBarry Smith 688*47c6ae99SBarry Smith @*/ 689*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGather(DM dm,Vec gvec,...) 690*47c6ae99SBarry Smith { 691*47c6ae99SBarry Smith va_list Argp; 692*47c6ae99SBarry Smith PetscErrorCode ierr; 693*47c6ae99SBarry Smith struct DMCompositeLink *next; 694*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 695*47c6ae99SBarry Smith 696*47c6ae99SBarry Smith PetscFunctionBegin; 697*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 698*47c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 699*47c6ae99SBarry Smith next = com->next; 700*47c6ae99SBarry Smith if (!com->setup) { 701*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 702*47c6ae99SBarry Smith } 703*47c6ae99SBarry Smith 704*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 705*47c6ae99SBarry Smith va_start(Argp,gvec); 706*47c6ae99SBarry Smith while (next) { 707*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 708*47c6ae99SBarry Smith PetscScalar *array; 709*47c6ae99SBarry Smith array = va_arg(Argp, PetscScalar*); 710*47c6ae99SBarry Smith ierr = DMCompositeGather_Array(dm,next,gvec,array);CHKERRQ(ierr); 711*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 712*47c6ae99SBarry Smith Vec vec; 713*47c6ae99SBarry Smith vec = va_arg(Argp, Vec); 714*47c6ae99SBarry Smith PetscValidHeaderSpecific(vec,VEC_CLASSID,3); 715*47c6ae99SBarry Smith ierr = DMCompositeGather_DM(dm,next,gvec,vec);CHKERRQ(ierr); 716*47c6ae99SBarry Smith } else { 717*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 718*47c6ae99SBarry Smith } 719*47c6ae99SBarry Smith next = next->next; 720*47c6ae99SBarry Smith } 721*47c6ae99SBarry Smith va_end(Argp); 722*47c6ae99SBarry Smith PetscFunctionReturn(0); 723*47c6ae99SBarry Smith } 724*47c6ae99SBarry Smith 725*47c6ae99SBarry Smith #undef __FUNCT__ 726*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddArray" 727*47c6ae99SBarry Smith /*@C 728*47c6ae99SBarry Smith DMCompositeAddArray - adds an "redundant" array to a DMComposite. The array values will 729*47c6ae99SBarry Smith be stored in part of the array on process orank. 730*47c6ae99SBarry Smith 731*47c6ae99SBarry Smith Collective on DMComposite 732*47c6ae99SBarry Smith 733*47c6ae99SBarry Smith Input Parameter: 734*47c6ae99SBarry Smith + dm - the packer object 735*47c6ae99SBarry Smith . orank - the process on which the array entries officially live, this number must be 736*47c6ae99SBarry Smith the same on all processes. 737*47c6ae99SBarry Smith - n - the length of the array 738*47c6ae99SBarry Smith 739*47c6ae99SBarry Smith Level: advanced 740*47c6ae99SBarry Smith 741*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 742*47c6ae99SBarry Smith DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 743*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 744*47c6ae99SBarry Smith 745*47c6ae99SBarry Smith @*/ 746*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeAddArray(DM dm,PetscMPIInt orank,PetscInt n) 747*47c6ae99SBarry Smith { 748*47c6ae99SBarry Smith struct DMCompositeLink *mine,*next; 749*47c6ae99SBarry Smith PetscErrorCode ierr; 750*47c6ae99SBarry Smith PetscMPIInt rank; 751*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 752*47c6ae99SBarry Smith 753*47c6ae99SBarry Smith PetscFunctionBegin; 754*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 755*47c6ae99SBarry Smith next = com->next; 756*47c6ae99SBarry Smith if (com->setup) { 757*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add an array once you have used the DMComposite"); 758*47c6ae99SBarry Smith } 759*47c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG) 760*47c6ae99SBarry Smith { 761*47c6ae99SBarry Smith PetscMPIInt orankmax; 762*47c6ae99SBarry Smith ierr = MPI_Allreduce(&orank,&orankmax,1,MPI_INT,MPI_MAX,((PetscObject)dm)->comm);CHKERRQ(ierr); 763*47c6ae99SBarry Smith if (orank != orankmax) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"orank %d must be equal on all processes, another process has value %d",orank,orankmax); 764*47c6ae99SBarry Smith } 765*47c6ae99SBarry Smith #endif 766*47c6ae99SBarry Smith 767*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 768*47c6ae99SBarry Smith /* create new link */ 769*47c6ae99SBarry Smith ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); 770*47c6ae99SBarry Smith mine->n = n; 771*47c6ae99SBarry Smith mine->rank = orank; 772*47c6ae99SBarry Smith mine->dm = PETSC_NULL; 773*47c6ae99SBarry Smith mine->type = DMCOMPOSITE_ARRAY; 774*47c6ae99SBarry Smith mine->next = PETSC_NULL; 775*47c6ae99SBarry Smith if (rank == mine->rank) {com->n += n;com->nmine++;} 776*47c6ae99SBarry Smith 777*47c6ae99SBarry Smith /* add to end of list */ 778*47c6ae99SBarry Smith if (!next) { 779*47c6ae99SBarry Smith com->next = mine; 780*47c6ae99SBarry Smith } else { 781*47c6ae99SBarry Smith while (next->next) next = next->next; 782*47c6ae99SBarry Smith next->next = mine; 783*47c6ae99SBarry Smith } 784*47c6ae99SBarry Smith com->nredundant++; 785*47c6ae99SBarry Smith PetscFunctionReturn(0); 786*47c6ae99SBarry Smith } 787*47c6ae99SBarry Smith 788*47c6ae99SBarry Smith #undef __FUNCT__ 789*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeAddDM" 790*47c6ae99SBarry Smith /*@C 791*47c6ae99SBarry Smith DMCompositeAddDM - adds a DM (includes DA) vector to a DMComposite 792*47c6ae99SBarry Smith 793*47c6ae99SBarry Smith Collective on DMComposite 794*47c6ae99SBarry Smith 795*47c6ae99SBarry Smith Input Parameter: 796*47c6ae99SBarry Smith + dm - the packer object 797*47c6ae99SBarry Smith - dm - the DM object, if the DM is a da you will need to caste it with a (DM) 798*47c6ae99SBarry Smith 799*47c6ae99SBarry Smith Level: advanced 800*47c6ae99SBarry Smith 801*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 802*47c6ae99SBarry Smith DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 803*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 804*47c6ae99SBarry Smith 805*47c6ae99SBarry Smith @*/ 806*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeAddDM(DM dmc,DM dm) 807*47c6ae99SBarry Smith { 808*47c6ae99SBarry Smith PetscErrorCode ierr; 809*47c6ae99SBarry Smith PetscInt n; 810*47c6ae99SBarry Smith struct DMCompositeLink *mine,*next; 811*47c6ae99SBarry Smith Vec global; 812*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmc->data; 813*47c6ae99SBarry Smith 814*47c6ae99SBarry Smith PetscFunctionBegin; 815*47c6ae99SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 816*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 817*47c6ae99SBarry Smith next = com->next; 818*47c6ae99SBarry Smith if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DA once you have used the DMComposite"); 819*47c6ae99SBarry Smith 820*47c6ae99SBarry Smith /* create new link */ 821*47c6ae99SBarry Smith ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); 822*47c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 823*47c6ae99SBarry Smith ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 824*47c6ae99SBarry Smith ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 825*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 826*47c6ae99SBarry Smith mine->n = n; 827*47c6ae99SBarry Smith mine->dm = dm; 828*47c6ae99SBarry Smith mine->type = DMCOMPOSITE_DM; 829*47c6ae99SBarry Smith mine->next = PETSC_NULL; 830*47c6ae99SBarry Smith com->n += n; 831*47c6ae99SBarry Smith 832*47c6ae99SBarry Smith /* add to end of list */ 833*47c6ae99SBarry Smith if (!next) { 834*47c6ae99SBarry Smith com->next = mine; 835*47c6ae99SBarry Smith } else { 836*47c6ae99SBarry Smith while (next->next) next = next->next; 837*47c6ae99SBarry Smith next->next = mine; 838*47c6ae99SBarry Smith } 839*47c6ae99SBarry Smith com->nDM++; 840*47c6ae99SBarry Smith com->nmine++; 841*47c6ae99SBarry Smith PetscFunctionReturn(0); 842*47c6ae99SBarry Smith } 843*47c6ae99SBarry Smith 844*47c6ae99SBarry Smith extern PetscErrorCode PETSCDM_DLLEXPORT VecView_MPI(Vec,PetscViewer); 845*47c6ae99SBarry Smith EXTERN_C_BEGIN 846*47c6ae99SBarry Smith #undef __FUNCT__ 847*47c6ae99SBarry Smith #define __FUNCT__ "VecView_DMComposite" 848*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT VecView_DMComposite(Vec gvec,PetscViewer viewer) 849*47c6ae99SBarry Smith { 850*47c6ae99SBarry Smith DM dm; 851*47c6ae99SBarry Smith PetscErrorCode ierr; 852*47c6ae99SBarry Smith struct DMCompositeLink *next; 853*47c6ae99SBarry Smith PetscBool isdraw; 854*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 855*47c6ae99SBarry Smith 856*47c6ae99SBarry Smith PetscFunctionBegin; 857*47c6ae99SBarry Smith ierr = PetscObjectQuery((PetscObject)gvec,"DMComposite",(PetscObject*)&dm);CHKERRQ(ierr); 858*47c6ae99SBarry Smith if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 859*47c6ae99SBarry Smith com = (DM_Composite*)dm->data; 860*47c6ae99SBarry Smith next = com->next; 861*47c6ae99SBarry Smith 862*47c6ae99SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 863*47c6ae99SBarry Smith if (!isdraw) { 864*47c6ae99SBarry Smith /* do I really want to call this? */ 865*47c6ae99SBarry Smith ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 866*47c6ae99SBarry Smith } else { 867*47c6ae99SBarry Smith PetscInt cnt = 0; 868*47c6ae99SBarry Smith 869*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 870*47c6ae99SBarry Smith while (next) { 871*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 872*47c6ae99SBarry Smith PetscScalar *array; 873*47c6ae99SBarry Smith ierr = DMCompositeGetAccess_Array(dm,next,gvec,&array);CHKERRQ(ierr); 874*47c6ae99SBarry Smith 875*47c6ae99SBarry Smith /*skip it for now */ 876*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 877*47c6ae99SBarry Smith Vec vec; 878*47c6ae99SBarry Smith PetscInt bs; 879*47c6ae99SBarry Smith 880*47c6ae99SBarry Smith ierr = DMCompositeGetAccess_DM(dm,next,gvec,&vec);CHKERRQ(ierr); 881*47c6ae99SBarry Smith ierr = VecView(vec,viewer);CHKERRQ(ierr); 882*47c6ae99SBarry Smith ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 883*47c6ae99SBarry Smith ierr = DMCompositeRestoreAccess_DM(dm,next,gvec,&vec);CHKERRQ(ierr); 884*47c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 885*47c6ae99SBarry Smith cnt += bs; 886*47c6ae99SBarry Smith } else { 887*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 888*47c6ae99SBarry Smith } 889*47c6ae99SBarry Smith next = next->next; 890*47c6ae99SBarry Smith } 891*47c6ae99SBarry Smith ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 892*47c6ae99SBarry Smith } 893*47c6ae99SBarry Smith PetscFunctionReturn(0); 894*47c6ae99SBarry Smith } 895*47c6ae99SBarry Smith EXTERN_C_END 896*47c6ae99SBarry Smith 897*47c6ae99SBarry Smith 898*47c6ae99SBarry Smith #undef __FUNCT__ 899*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeCreateGlobalVector" 900*47c6ae99SBarry Smith /*@C 901*47c6ae99SBarry Smith DMCompositeCreateGlobalVector - Creates a vector of the correct size to be gathered into 902*47c6ae99SBarry Smith by the packer. 903*47c6ae99SBarry Smith 904*47c6ae99SBarry Smith Collective on DMComposite 905*47c6ae99SBarry Smith 906*47c6ae99SBarry Smith Input Parameter: 907*47c6ae99SBarry Smith . dm - the packer object 908*47c6ae99SBarry Smith 909*47c6ae99SBarry Smith Output Parameters: 910*47c6ae99SBarry Smith . gvec - the global vector 911*47c6ae99SBarry Smith 912*47c6ae99SBarry Smith Level: advanced 913*47c6ae99SBarry Smith 914*47c6ae99SBarry Smith Notes: Once this has been created you cannot add additional arrays or vectors to be packed. 915*47c6ae99SBarry Smith 916*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(), 917*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 918*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), 919*47c6ae99SBarry Smith DMCompositeCreateLocalVector() 920*47c6ae99SBarry Smith 921*47c6ae99SBarry Smith @*/ 922*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeCreateGlobalVector(DM dm,Vec *gvec) 923*47c6ae99SBarry Smith { 924*47c6ae99SBarry Smith PetscErrorCode ierr; 925*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 926*47c6ae99SBarry Smith 927*47c6ae99SBarry Smith PetscFunctionBegin; 928*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 929*47c6ae99SBarry Smith if (!com->setup) { 930*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 931*47c6ae99SBarry Smith } 932*47c6ae99SBarry Smith ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr); 933*47c6ae99SBarry Smith ierr = PetscObjectCompose((PetscObject)*gvec,"DMComposite",(PetscObject)dm);CHKERRQ(ierr); 934*47c6ae99SBarry Smith ierr = VecSetOperation(*gvec,VECOP_VIEW,(void(*)(void))VecView_DMComposite);CHKERRQ(ierr); 935*47c6ae99SBarry Smith PetscFunctionReturn(0); 936*47c6ae99SBarry Smith } 937*47c6ae99SBarry Smith 938*47c6ae99SBarry Smith #undef __FUNCT__ 939*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeCreateLocalVector" 940*47c6ae99SBarry Smith /*@C 941*47c6ae99SBarry Smith DMCompositeCreateLocalVector - Creates a vector of the correct size to contain all ghost points 942*47c6ae99SBarry Smith and redundant arrays. 943*47c6ae99SBarry Smith 944*47c6ae99SBarry Smith Not Collective 945*47c6ae99SBarry Smith 946*47c6ae99SBarry Smith Input Parameter: 947*47c6ae99SBarry Smith . dm - the packer object 948*47c6ae99SBarry Smith 949*47c6ae99SBarry Smith Output Parameters: 950*47c6ae99SBarry Smith . lvec - the local vector 951*47c6ae99SBarry Smith 952*47c6ae99SBarry Smith Level: advanced 953*47c6ae99SBarry Smith 954*47c6ae99SBarry Smith Notes: Once this has been created you cannot add additional arrays or vectors to be packed. 955*47c6ae99SBarry Smith 956*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeScatter(), 957*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 958*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), 959*47c6ae99SBarry Smith DMCompositeCreateGlobalVector() 960*47c6ae99SBarry Smith 961*47c6ae99SBarry Smith @*/ 962*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeCreateLocalVector(DM dm,Vec *lvec) 963*47c6ae99SBarry Smith { 964*47c6ae99SBarry Smith PetscErrorCode ierr; 965*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 966*47c6ae99SBarry Smith 967*47c6ae99SBarry Smith PetscFunctionBegin; 968*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 969*47c6ae99SBarry Smith if (!com->setup) { 970*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 971*47c6ae99SBarry Smith } 972*47c6ae99SBarry Smith ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr); 973*47c6ae99SBarry Smith ierr = PetscObjectCompose((PetscObject)*lvec,"DMComposite",(PetscObject)dm);CHKERRQ(ierr); 974*47c6ae99SBarry Smith PetscFunctionReturn(0); 975*47c6ae99SBarry Smith } 976*47c6ae99SBarry Smith 977*47c6ae99SBarry Smith #undef __FUNCT__ 978*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalISs" 979*47c6ae99SBarry Smith /*@C 980*47c6ae99SBarry Smith DMCompositeGetLocalISs - gets an IS for each DM/array in the DMComposite, include ghost points 981*47c6ae99SBarry Smith 982*47c6ae99SBarry Smith Collective on DMComposite 983*47c6ae99SBarry Smith 984*47c6ae99SBarry Smith Input Parameter: 985*47c6ae99SBarry Smith . dm - the packer object 986*47c6ae99SBarry Smith 987*47c6ae99SBarry Smith Output Parameters: 988*47c6ae99SBarry Smith . is - the individual indices for each packed vector/array. Note that this includes 989*47c6ae99SBarry Smith all the ghost points that individual ghosted DA's may have. Also each process has an 990*47c6ae99SBarry Smith is for EACH redundant array (not just the local redundant arrays). 991*47c6ae99SBarry Smith 992*47c6ae99SBarry Smith Level: advanced 993*47c6ae99SBarry Smith 994*47c6ae99SBarry Smith Notes: 995*47c6ae99SBarry Smith The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 996*47c6ae99SBarry Smith 997*47c6ae99SBarry Smith Use DMCompositeGetGlobalISs() for non-ghosted ISs. 998*47c6ae99SBarry Smith 999*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1000*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 1001*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 1002*47c6ae99SBarry Smith 1003*47c6ae99SBarry Smith @*/ 1004*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetGlobalIndices(DM dm,IS *is[]) 1005*47c6ae99SBarry Smith { 1006*47c6ae99SBarry Smith PetscErrorCode ierr; 1007*47c6ae99SBarry Smith PetscInt i,*idx,n,cnt; 1008*47c6ae99SBarry Smith struct DMCompositeLink *next; 1009*47c6ae99SBarry Smith Vec global,dglobal; 1010*47c6ae99SBarry Smith PF pf; 1011*47c6ae99SBarry Smith PetscScalar *array; 1012*47c6ae99SBarry Smith PetscMPIInt rank; 1013*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1014*47c6ae99SBarry Smith 1015*47c6ae99SBarry Smith PetscFunctionBegin; 1016*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1017*47c6ae99SBarry Smith ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr); 1018*47c6ae99SBarry Smith next = com->next; 1019*47c6ae99SBarry Smith ierr = DMCompositeCreateGlobalVector(dm,&global);CHKERRQ(ierr); 1020*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1021*47c6ae99SBarry Smith 1022*47c6ae99SBarry Smith /* put 0 to N-1 into the global vector */ 1023*47c6ae99SBarry Smith ierr = PFCreate(PETSC_COMM_WORLD,1,1,&pf);CHKERRQ(ierr); 1024*47c6ae99SBarry Smith ierr = PFSetType(pf,PFIDENTITY,PETSC_NULL);CHKERRQ(ierr); 1025*47c6ae99SBarry Smith ierr = PFApplyVec(pf,PETSC_NULL,global);CHKERRQ(ierr); 1026*47c6ae99SBarry Smith ierr = PFDestroy(pf);CHKERRQ(ierr); 1027*47c6ae99SBarry Smith 1028*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1029*47c6ae99SBarry Smith cnt = 0; 1030*47c6ae99SBarry Smith while (next) { 1031*47c6ae99SBarry Smith 1032*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1033*47c6ae99SBarry Smith 1034*47c6ae99SBarry Smith ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1035*47c6ae99SBarry Smith if (rank == next->rank) { 1036*47c6ae99SBarry Smith ierr = VecGetArray(global,&array);CHKERRQ(ierr); 1037*47c6ae99SBarry Smith array += next->rstart; 1038*47c6ae99SBarry Smith for (i=0; i<next->n; i++) idx[i] = (PetscInt)PetscRealPart(array[i]); 1039*47c6ae99SBarry Smith array -= next->rstart; 1040*47c6ae99SBarry Smith ierr = VecRestoreArray(global,&array);CHKERRQ(ierr); 1041*47c6ae99SBarry Smith } 1042*47c6ae99SBarry Smith ierr = MPI_Bcast(idx,next->n,MPIU_INT,next->rank,((PetscObject)dm)->comm);CHKERRQ(ierr); 1043*47c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 1044*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1045*47c6ae99SBarry Smith Vec local; 1046*47c6ae99SBarry Smith 1047*47c6ae99SBarry Smith ierr = DMCreateLocalVector(next->dm,&local);CHKERRQ(ierr); 1048*47c6ae99SBarry Smith ierr = VecGetArray(global,&array);CHKERRQ(ierr); 1049*47c6ae99SBarry Smith array += next->rstart; 1050*47c6ae99SBarry Smith ierr = DMGetGlobalVector(next->dm,&dglobal);CHKERRQ(ierr); 1051*47c6ae99SBarry Smith ierr = VecPlaceArray(dglobal,array);CHKERRQ(ierr); 1052*47c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(next->dm,dglobal,INSERT_VALUES,local);CHKERRQ(ierr); 1053*47c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(next->dm,dglobal,INSERT_VALUES,local);CHKERRQ(ierr); 1054*47c6ae99SBarry Smith array -= next->rstart; 1055*47c6ae99SBarry Smith ierr = VecRestoreArray(global,&array);CHKERRQ(ierr); 1056*47c6ae99SBarry Smith ierr = VecResetArray(dglobal);CHKERRQ(ierr); 1057*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&dglobal);CHKERRQ(ierr); 1058*47c6ae99SBarry Smith 1059*47c6ae99SBarry Smith ierr = VecGetArray(local,&array);CHKERRQ(ierr); 1060*47c6ae99SBarry Smith ierr = VecGetSize(local,&n);CHKERRQ(ierr); 1061*47c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1062*47c6ae99SBarry Smith for (i=0; i<n; i++) idx[i] = (PetscInt)PetscRealPart(array[i]); 1063*47c6ae99SBarry Smith ierr = VecRestoreArray(local,&array);CHKERRQ(ierr); 1064*47c6ae99SBarry Smith ierr = VecDestroy(local);CHKERRQ(ierr); 1065*47c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 1066*47c6ae99SBarry Smith 1067*47c6ae99SBarry Smith } else SETERRQ(((PetscObject)global)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1068*47c6ae99SBarry Smith next = next->next; 1069*47c6ae99SBarry Smith cnt++; 1070*47c6ae99SBarry Smith } 1071*47c6ae99SBarry Smith ierr = VecDestroy(global);CHKERRQ(ierr); 1072*47c6ae99SBarry Smith PetscFunctionReturn(0); 1073*47c6ae99SBarry Smith } 1074*47c6ae99SBarry Smith 1075*47c6ae99SBarry Smith #undef __FUNCT__ 1076*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetGlobalISs" 1077*47c6ae99SBarry Smith /*@C 1078*47c6ae99SBarry Smith DMCompositeGetGlobalISs - Gets the index sets for each composed object 1079*47c6ae99SBarry Smith 1080*47c6ae99SBarry Smith Collective on DMComposite 1081*47c6ae99SBarry Smith 1082*47c6ae99SBarry Smith Input Parameter: 1083*47c6ae99SBarry Smith . dm - the packer object 1084*47c6ae99SBarry Smith 1085*47c6ae99SBarry Smith Output Parameters: 1086*47c6ae99SBarry Smith . is - the array of index sets 1087*47c6ae99SBarry Smith 1088*47c6ae99SBarry Smith Level: advanced 1089*47c6ae99SBarry Smith 1090*47c6ae99SBarry Smith Notes: 1091*47c6ae99SBarry Smith The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 1092*47c6ae99SBarry Smith 1093*47c6ae99SBarry Smith The number of IS on each process will/may be different when redundant arrays are used 1094*47c6ae99SBarry Smith 1095*47c6ae99SBarry Smith These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 1096*47c6ae99SBarry Smith 1097*47c6ae99SBarry Smith Use DMCompositeGetLocalISs() for index sets that include ghost points 1098*47c6ae99SBarry Smith 1099*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1100*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 1101*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 1102*47c6ae99SBarry Smith 1103*47c6ae99SBarry Smith @*/ 1104*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetGlobalISs(DM dm,IS *is[]) 1105*47c6ae99SBarry Smith { 1106*47c6ae99SBarry Smith PetscErrorCode ierr; 1107*47c6ae99SBarry Smith PetscInt cnt = 0,*idx,i; 1108*47c6ae99SBarry Smith struct DMCompositeLink *next; 1109*47c6ae99SBarry Smith PetscMPIInt rank; 1110*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1111*47c6ae99SBarry Smith 1112*47c6ae99SBarry Smith PetscFunctionBegin; 1113*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1114*47c6ae99SBarry Smith ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr); 1115*47c6ae99SBarry Smith next = com->next; 1116*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1117*47c6ae99SBarry Smith 1118*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1119*47c6ae99SBarry Smith while (next) { 1120*47c6ae99SBarry Smith 1121*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1122*47c6ae99SBarry Smith 1123*47c6ae99SBarry Smith if (rank == next->rank) { 1124*47c6ae99SBarry Smith ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1125*47c6ae99SBarry Smith for (i=0; i<next->n; i++) idx[i] = next->grstart + i; 1126*47c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 1127*47c6ae99SBarry Smith cnt++; 1128*47c6ae99SBarry Smith } 1129*47c6ae99SBarry Smith 1130*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1131*47c6ae99SBarry Smith ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1132*47c6ae99SBarry Smith for (i=0; i<next->n; i++) idx[i] = next->grstart + i; 1133*47c6ae99SBarry Smith ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 1134*47c6ae99SBarry Smith cnt++; 1135*47c6ae99SBarry Smith } else { 1136*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1137*47c6ae99SBarry Smith } 1138*47c6ae99SBarry Smith next = next->next; 1139*47c6ae99SBarry Smith } 1140*47c6ae99SBarry Smith PetscFunctionReturn(0); 1141*47c6ae99SBarry Smith } 1142*47c6ae99SBarry Smith 1143*47c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 1144*47c6ae99SBarry Smith #undef __FUNCT__ 1145*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors_Array" 1146*47c6ae99SBarry Smith PetscErrorCode DMCompositeGetLocalVectors_Array(DM dm,struct DMCompositeLink *mine,PetscScalar **array) 1147*47c6ae99SBarry Smith { 1148*47c6ae99SBarry Smith PetscErrorCode ierr; 1149*47c6ae99SBarry Smith PetscFunctionBegin; 1150*47c6ae99SBarry Smith if (array) { 1151*47c6ae99SBarry Smith ierr = PetscMalloc(mine->n*sizeof(PetscScalar),array);CHKERRQ(ierr); 1152*47c6ae99SBarry Smith } 1153*47c6ae99SBarry Smith PetscFunctionReturn(0); 1154*47c6ae99SBarry Smith } 1155*47c6ae99SBarry Smith 1156*47c6ae99SBarry Smith #undef __FUNCT__ 1157*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors_DM" 1158*47c6ae99SBarry Smith PetscErrorCode DMCompositeGetLocalVectors_DM(DM dm,struct DMCompositeLink *mine,Vec *local) 1159*47c6ae99SBarry Smith { 1160*47c6ae99SBarry Smith PetscErrorCode ierr; 1161*47c6ae99SBarry Smith PetscFunctionBegin; 1162*47c6ae99SBarry Smith if (local) { 1163*47c6ae99SBarry Smith ierr = DMGetLocalVector(mine->dm,local);CHKERRQ(ierr); 1164*47c6ae99SBarry Smith } 1165*47c6ae99SBarry Smith PetscFunctionReturn(0); 1166*47c6ae99SBarry Smith } 1167*47c6ae99SBarry Smith 1168*47c6ae99SBarry Smith #undef __FUNCT__ 1169*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors_Array" 1170*47c6ae99SBarry Smith PetscErrorCode DMCompositeRestoreLocalVectors_Array(DM dm,struct DMCompositeLink *mine,PetscScalar **array) 1171*47c6ae99SBarry Smith { 1172*47c6ae99SBarry Smith PetscErrorCode ierr; 1173*47c6ae99SBarry Smith PetscFunctionBegin; 1174*47c6ae99SBarry Smith if (array) { 1175*47c6ae99SBarry Smith ierr = PetscFree(*array);CHKERRQ(ierr); 1176*47c6ae99SBarry Smith } 1177*47c6ae99SBarry Smith PetscFunctionReturn(0); 1178*47c6ae99SBarry Smith } 1179*47c6ae99SBarry Smith 1180*47c6ae99SBarry Smith #undef __FUNCT__ 1181*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors_DM" 1182*47c6ae99SBarry Smith PetscErrorCode DMCompositeRestoreLocalVectors_DM(DM dm,struct DMCompositeLink *mine,Vec *local) 1183*47c6ae99SBarry Smith { 1184*47c6ae99SBarry Smith PetscErrorCode ierr; 1185*47c6ae99SBarry Smith PetscFunctionBegin; 1186*47c6ae99SBarry Smith if (local) { 1187*47c6ae99SBarry Smith ierr = DMRestoreLocalVector(mine->dm,local);CHKERRQ(ierr); 1188*47c6ae99SBarry Smith } 1189*47c6ae99SBarry Smith PetscFunctionReturn(0); 1190*47c6ae99SBarry Smith } 1191*47c6ae99SBarry Smith 1192*47c6ae99SBarry Smith #undef __FUNCT__ 1193*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetLocalVectors" 1194*47c6ae99SBarry Smith /*@C 1195*47c6ae99SBarry Smith DMCompositeGetLocalVectors - Gets local vectors and arrays for each part of a DMComposite. 1196*47c6ae99SBarry Smith Use DMCompositeRestoreLocalVectors() to return them. 1197*47c6ae99SBarry Smith 1198*47c6ae99SBarry Smith Not Collective 1199*47c6ae99SBarry Smith 1200*47c6ae99SBarry Smith Input Parameter: 1201*47c6ae99SBarry Smith . dm - the packer object 1202*47c6ae99SBarry Smith 1203*47c6ae99SBarry Smith Output Parameter: 1204*47c6ae99SBarry Smith . ... - the individual sequential objects (arrays or vectors) 1205*47c6ae99SBarry Smith 1206*47c6ae99SBarry Smith Level: advanced 1207*47c6ae99SBarry Smith 1208*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1209*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 1210*47c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 1211*47c6ae99SBarry Smith 1212*47c6ae99SBarry Smith @*/ 1213*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetLocalVectors(DM dm,...) 1214*47c6ae99SBarry Smith { 1215*47c6ae99SBarry Smith va_list Argp; 1216*47c6ae99SBarry Smith PetscErrorCode ierr; 1217*47c6ae99SBarry Smith struct DMCompositeLink *next; 1218*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1219*47c6ae99SBarry Smith 1220*47c6ae99SBarry Smith PetscFunctionBegin; 1221*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1222*47c6ae99SBarry Smith next = com->next; 1223*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1224*47c6ae99SBarry Smith va_start(Argp,dm); 1225*47c6ae99SBarry Smith while (next) { 1226*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1227*47c6ae99SBarry Smith PetscScalar **array; 1228*47c6ae99SBarry Smith array = va_arg(Argp, PetscScalar**); 1229*47c6ae99SBarry Smith ierr = DMCompositeGetLocalVectors_Array(dm,next,array);CHKERRQ(ierr); 1230*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1231*47c6ae99SBarry Smith Vec *vec; 1232*47c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 1233*47c6ae99SBarry Smith ierr = DMCompositeGetLocalVectors_DM(dm,next,vec);CHKERRQ(ierr); 1234*47c6ae99SBarry Smith } else { 1235*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1236*47c6ae99SBarry Smith } 1237*47c6ae99SBarry Smith next = next->next; 1238*47c6ae99SBarry Smith } 1239*47c6ae99SBarry Smith va_end(Argp); 1240*47c6ae99SBarry Smith PetscFunctionReturn(0); 1241*47c6ae99SBarry Smith } 1242*47c6ae99SBarry Smith 1243*47c6ae99SBarry Smith #undef __FUNCT__ 1244*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRestoreLocalVectors" 1245*47c6ae99SBarry Smith /*@C 1246*47c6ae99SBarry Smith DMCompositeRestoreLocalVectors - Restores local vectors and arrays for each part of a DMComposite. 1247*47c6ae99SBarry Smith 1248*47c6ae99SBarry Smith Not Collective 1249*47c6ae99SBarry Smith 1250*47c6ae99SBarry Smith Input Parameter: 1251*47c6ae99SBarry Smith . dm - the packer object 1252*47c6ae99SBarry Smith 1253*47c6ae99SBarry Smith Output Parameter: 1254*47c6ae99SBarry Smith . ... - the individual sequential objects (arrays or vectors) 1255*47c6ae99SBarry Smith 1256*47c6ae99SBarry Smith Level: advanced 1257*47c6ae99SBarry Smith 1258*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1259*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 1260*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 1261*47c6ae99SBarry Smith 1262*47c6ae99SBarry Smith @*/ 1263*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeRestoreLocalVectors(DM dm,...) 1264*47c6ae99SBarry Smith { 1265*47c6ae99SBarry Smith va_list Argp; 1266*47c6ae99SBarry Smith PetscErrorCode ierr; 1267*47c6ae99SBarry Smith struct DMCompositeLink *next; 1268*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1269*47c6ae99SBarry Smith 1270*47c6ae99SBarry Smith PetscFunctionBegin; 1271*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1272*47c6ae99SBarry Smith next = com->next; 1273*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1274*47c6ae99SBarry Smith va_start(Argp,dm); 1275*47c6ae99SBarry Smith while (next) { 1276*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1277*47c6ae99SBarry Smith PetscScalar **array; 1278*47c6ae99SBarry Smith array = va_arg(Argp, PetscScalar**); 1279*47c6ae99SBarry Smith ierr = DMCompositeRestoreLocalVectors_Array(dm,next,array);CHKERRQ(ierr); 1280*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1281*47c6ae99SBarry Smith Vec *vec; 1282*47c6ae99SBarry Smith vec = va_arg(Argp, Vec*); 1283*47c6ae99SBarry Smith ierr = DMCompositeRestoreLocalVectors_DM(dm,next,vec);CHKERRQ(ierr); 1284*47c6ae99SBarry Smith } else { 1285*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1286*47c6ae99SBarry Smith } 1287*47c6ae99SBarry Smith next = next->next; 1288*47c6ae99SBarry Smith } 1289*47c6ae99SBarry Smith va_end(Argp); 1290*47c6ae99SBarry Smith PetscFunctionReturn(0); 1291*47c6ae99SBarry Smith } 1292*47c6ae99SBarry Smith 1293*47c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 1294*47c6ae99SBarry Smith #undef __FUNCT__ 1295*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries_Array" 1296*47c6ae99SBarry Smith PetscErrorCode DMCompositeGetEntries_Array(DM dm,struct DMCompositeLink *mine,PetscInt *n) 1297*47c6ae99SBarry Smith { 1298*47c6ae99SBarry Smith PetscFunctionBegin; 1299*47c6ae99SBarry Smith if (n) *n = mine->n; 1300*47c6ae99SBarry Smith PetscFunctionReturn(0); 1301*47c6ae99SBarry Smith } 1302*47c6ae99SBarry Smith 1303*47c6ae99SBarry Smith #undef __FUNCT__ 1304*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries_DM" 1305*47c6ae99SBarry Smith PetscErrorCode DMCompositeGetEntries_DM(DM dmi,struct DMCompositeLink *mine,DM *dm) 1306*47c6ae99SBarry Smith { 1307*47c6ae99SBarry Smith PetscFunctionBegin; 1308*47c6ae99SBarry Smith if (dm) *dm = mine->dm; 1309*47c6ae99SBarry Smith PetscFunctionReturn(0); 1310*47c6ae99SBarry Smith } 1311*47c6ae99SBarry Smith 1312*47c6ae99SBarry Smith #undef __FUNCT__ 1313*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetEntries" 1314*47c6ae99SBarry Smith /*@C 1315*47c6ae99SBarry Smith DMCompositeGetEntries - Gets the DA, redundant size, etc for each entry in a DMComposite. 1316*47c6ae99SBarry Smith 1317*47c6ae99SBarry Smith Not Collective 1318*47c6ae99SBarry Smith 1319*47c6ae99SBarry Smith Input Parameter: 1320*47c6ae99SBarry Smith . dm - the packer object 1321*47c6ae99SBarry Smith 1322*47c6ae99SBarry Smith Output Parameter: 1323*47c6ae99SBarry Smith . ... - the individual entries, DAs or integer sizes) 1324*47c6ae99SBarry Smith 1325*47c6ae99SBarry Smith Level: advanced 1326*47c6ae99SBarry Smith 1327*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1328*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 1329*47c6ae99SBarry Smith DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 1330*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 1331*47c6ae99SBarry Smith 1332*47c6ae99SBarry Smith @*/ 1333*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetEntries(DM dm,...) 1334*47c6ae99SBarry Smith { 1335*47c6ae99SBarry Smith va_list Argp; 1336*47c6ae99SBarry Smith PetscErrorCode ierr; 1337*47c6ae99SBarry Smith struct DMCompositeLink *next; 1338*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1339*47c6ae99SBarry Smith 1340*47c6ae99SBarry Smith PetscFunctionBegin; 1341*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1342*47c6ae99SBarry Smith next = com->next; 1343*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1344*47c6ae99SBarry Smith va_start(Argp,dm); 1345*47c6ae99SBarry Smith while (next) { 1346*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1347*47c6ae99SBarry Smith PetscInt *n; 1348*47c6ae99SBarry Smith n = va_arg(Argp, PetscInt*); 1349*47c6ae99SBarry Smith ierr = DMCompositeGetEntries_Array(dm,next,n);CHKERRQ(ierr); 1350*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1351*47c6ae99SBarry Smith DM *dmn; 1352*47c6ae99SBarry Smith dmn = va_arg(Argp, DM*); 1353*47c6ae99SBarry Smith ierr = DMCompositeGetEntries_DM(dm,next,dmn);CHKERRQ(ierr); 1354*47c6ae99SBarry Smith } else { 1355*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1356*47c6ae99SBarry Smith } 1357*47c6ae99SBarry Smith next = next->next; 1358*47c6ae99SBarry Smith } 1359*47c6ae99SBarry Smith va_end(Argp); 1360*47c6ae99SBarry Smith PetscFunctionReturn(0); 1361*47c6ae99SBarry Smith } 1362*47c6ae99SBarry Smith 1363*47c6ae99SBarry Smith #undef __FUNCT__ 1364*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeRefine" 1365*47c6ae99SBarry Smith /*@C 1366*47c6ae99SBarry Smith DMCompositeRefine - Refines a DM by refining all of its DAs 1367*47c6ae99SBarry Smith 1368*47c6ae99SBarry Smith Collective on DMComposite 1369*47c6ae99SBarry Smith 1370*47c6ae99SBarry Smith Input Parameters: 1371*47c6ae99SBarry Smith + dm - the packer object 1372*47c6ae99SBarry Smith - comm - communicator to contain the new DM object, usually PETSC_NULL 1373*47c6ae99SBarry Smith 1374*47c6ae99SBarry Smith Output Parameter: 1375*47c6ae99SBarry Smith . fine - new packer 1376*47c6ae99SBarry Smith 1377*47c6ae99SBarry Smith Level: advanced 1378*47c6ae99SBarry Smith 1379*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1380*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 1381*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeScatter(), 1382*47c6ae99SBarry Smith DMCompositeGetEntries() 1383*47c6ae99SBarry Smith 1384*47c6ae99SBarry Smith @*/ 1385*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeRefine(DM dmi,MPI_Comm comm,DM *fine) 1386*47c6ae99SBarry Smith { 1387*47c6ae99SBarry Smith PetscErrorCode ierr; 1388*47c6ae99SBarry Smith struct DMCompositeLink *next; 1389*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dmi->data; 1390*47c6ae99SBarry Smith DM dm; 1391*47c6ae99SBarry Smith 1392*47c6ae99SBarry Smith PetscFunctionBegin; 1393*47c6ae99SBarry Smith PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 1394*47c6ae99SBarry Smith next = com->next; 1395*47c6ae99SBarry Smith ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 1396*47c6ae99SBarry Smith 1397*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1398*47c6ae99SBarry Smith while (next) { 1399*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1400*47c6ae99SBarry Smith ierr = DMCompositeAddArray(*fine,next->rank,next->n);CHKERRQ(ierr); 1401*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1402*47c6ae99SBarry Smith ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 1403*47c6ae99SBarry Smith ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 1404*47c6ae99SBarry Smith ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 1405*47c6ae99SBarry Smith } else { 1406*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1407*47c6ae99SBarry Smith } 1408*47c6ae99SBarry Smith next = next->next; 1409*47c6ae99SBarry Smith } 1410*47c6ae99SBarry Smith PetscFunctionReturn(0); 1411*47c6ae99SBarry Smith } 1412*47c6ae99SBarry Smith 1413*47c6ae99SBarry Smith #include "petscmat.h" 1414*47c6ae99SBarry Smith 1415*47c6ae99SBarry Smith struct MatPackLink { 1416*47c6ae99SBarry Smith Mat A; 1417*47c6ae99SBarry Smith struct MatPackLink *next; 1418*47c6ae99SBarry Smith }; 1419*47c6ae99SBarry Smith 1420*47c6ae99SBarry Smith struct MatPack { 1421*47c6ae99SBarry Smith DM right,left; 1422*47c6ae99SBarry Smith struct MatPackLink *next; 1423*47c6ae99SBarry Smith }; 1424*47c6ae99SBarry Smith 1425*47c6ae99SBarry Smith #undef __FUNCT__ 1426*47c6ae99SBarry Smith #define __FUNCT__ "MatMultBoth_Shell_Pack" 1427*47c6ae99SBarry Smith PetscErrorCode MatMultBoth_Shell_Pack(Mat A,Vec x,Vec y,PetscBool add) 1428*47c6ae99SBarry Smith { 1429*47c6ae99SBarry Smith struct MatPack *mpack; 1430*47c6ae99SBarry Smith struct DMCompositeLink *xnext,*ynext; 1431*47c6ae99SBarry Smith struct MatPackLink *anext; 1432*47c6ae99SBarry Smith PetscScalar *xarray,*yarray; 1433*47c6ae99SBarry Smith PetscErrorCode ierr; 1434*47c6ae99SBarry Smith PetscInt i; 1435*47c6ae99SBarry Smith Vec xglobal,yglobal; 1436*47c6ae99SBarry Smith PetscMPIInt rank; 1437*47c6ae99SBarry Smith DM_Composite *comright; 1438*47c6ae99SBarry Smith DM_Composite *comleft; 1439*47c6ae99SBarry Smith 1440*47c6ae99SBarry Smith PetscFunctionBegin; 1441*47c6ae99SBarry Smith ierr = MatShellGetContext(A,(void**)&mpack);CHKERRQ(ierr); 1442*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)mpack->right)->comm,&rank);CHKERRQ(ierr); 1443*47c6ae99SBarry Smith comright = (DM_Composite*)mpack->right->data; 1444*47c6ae99SBarry Smith comleft = (DM_Composite*)mpack->left->data; 1445*47c6ae99SBarry Smith xnext = comright->next; 1446*47c6ae99SBarry Smith ynext = comleft->next; 1447*47c6ae99SBarry Smith anext = mpack->next; 1448*47c6ae99SBarry Smith 1449*47c6ae99SBarry Smith while (xnext) { 1450*47c6ae99SBarry Smith if (xnext->type == DMCOMPOSITE_ARRAY) { 1451*47c6ae99SBarry Smith if (rank == xnext->rank) { 1452*47c6ae99SBarry Smith ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 1453*47c6ae99SBarry Smith ierr = VecGetArray(y,&yarray);CHKERRQ(ierr); 1454*47c6ae99SBarry Smith if (add) { 1455*47c6ae99SBarry Smith for (i=0; i<xnext->n; i++) { 1456*47c6ae99SBarry Smith yarray[ynext->rstart+i] += xarray[xnext->rstart+i]; 1457*47c6ae99SBarry Smith } 1458*47c6ae99SBarry Smith } else { 1459*47c6ae99SBarry Smith ierr = PetscMemcpy(yarray+ynext->rstart,xarray+xnext->rstart,xnext->n*sizeof(PetscScalar));CHKERRQ(ierr); 1460*47c6ae99SBarry Smith } 1461*47c6ae99SBarry Smith ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 1462*47c6ae99SBarry Smith ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr); 1463*47c6ae99SBarry Smith } 1464*47c6ae99SBarry Smith } else if (xnext->type == DMCOMPOSITE_DM) { 1465*47c6ae99SBarry Smith ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 1466*47c6ae99SBarry Smith ierr = VecGetArray(y,&yarray);CHKERRQ(ierr); 1467*47c6ae99SBarry Smith ierr = DMGetGlobalVector(xnext->dm,&xglobal);CHKERRQ(ierr); 1468*47c6ae99SBarry Smith ierr = DMGetGlobalVector(ynext->dm,&yglobal);CHKERRQ(ierr); 1469*47c6ae99SBarry Smith ierr = VecPlaceArray(xglobal,xarray+xnext->rstart);CHKERRQ(ierr); 1470*47c6ae99SBarry Smith ierr = VecPlaceArray(yglobal,yarray+ynext->rstart);CHKERRQ(ierr); 1471*47c6ae99SBarry Smith if (add) { 1472*47c6ae99SBarry Smith ierr = MatMultAdd(anext->A,xglobal,yglobal,yglobal);CHKERRQ(ierr); 1473*47c6ae99SBarry Smith } else { 1474*47c6ae99SBarry Smith ierr = MatMult(anext->A,xglobal,yglobal);CHKERRQ(ierr); 1475*47c6ae99SBarry Smith } 1476*47c6ae99SBarry Smith ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 1477*47c6ae99SBarry Smith ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr); 1478*47c6ae99SBarry Smith ierr = VecResetArray(xglobal);CHKERRQ(ierr); 1479*47c6ae99SBarry Smith ierr = VecResetArray(yglobal);CHKERRQ(ierr); 1480*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(xnext->dm,&xglobal);CHKERRQ(ierr); 1481*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(ynext->dm,&yglobal);CHKERRQ(ierr); 1482*47c6ae99SBarry Smith anext = anext->next; 1483*47c6ae99SBarry Smith } else { 1484*47c6ae99SBarry Smith SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1485*47c6ae99SBarry Smith } 1486*47c6ae99SBarry Smith xnext = xnext->next; 1487*47c6ae99SBarry Smith ynext = ynext->next; 1488*47c6ae99SBarry Smith } 1489*47c6ae99SBarry Smith PetscFunctionReturn(0); 1490*47c6ae99SBarry Smith } 1491*47c6ae99SBarry Smith 1492*47c6ae99SBarry Smith #undef __FUNCT__ 1493*47c6ae99SBarry Smith #define __FUNCT__ "MatMultAdd_Shell_Pack" 1494*47c6ae99SBarry Smith PetscErrorCode MatMultAdd_Shell_Pack(Mat A,Vec x,Vec y,Vec z) 1495*47c6ae99SBarry Smith { 1496*47c6ae99SBarry Smith PetscErrorCode ierr; 1497*47c6ae99SBarry Smith PetscFunctionBegin; 1498*47c6ae99SBarry Smith if (z != y) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Handles y == z only"); 1499*47c6ae99SBarry Smith ierr = MatMultBoth_Shell_Pack(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1500*47c6ae99SBarry Smith PetscFunctionReturn(0); 1501*47c6ae99SBarry Smith } 1502*47c6ae99SBarry Smith 1503*47c6ae99SBarry Smith #undef __FUNCT__ 1504*47c6ae99SBarry Smith #define __FUNCT__ "MatMult_Shell_Pack" 1505*47c6ae99SBarry Smith PetscErrorCode MatMult_Shell_Pack(Mat A,Vec x,Vec y) 1506*47c6ae99SBarry Smith { 1507*47c6ae99SBarry Smith PetscErrorCode ierr; 1508*47c6ae99SBarry Smith PetscFunctionBegin; 1509*47c6ae99SBarry Smith ierr = MatMultBoth_Shell_Pack(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1510*47c6ae99SBarry Smith PetscFunctionReturn(0); 1511*47c6ae99SBarry Smith } 1512*47c6ae99SBarry Smith 1513*47c6ae99SBarry Smith #undef __FUNCT__ 1514*47c6ae99SBarry Smith #define __FUNCT__ "MatMultTranspose_Shell_Pack" 1515*47c6ae99SBarry Smith PetscErrorCode MatMultTranspose_Shell_Pack(Mat A,Vec x,Vec y) 1516*47c6ae99SBarry Smith { 1517*47c6ae99SBarry Smith struct MatPack *mpack; 1518*47c6ae99SBarry Smith struct DMCompositeLink *xnext,*ynext; 1519*47c6ae99SBarry Smith struct MatPackLink *anext; 1520*47c6ae99SBarry Smith PetscScalar *xarray,*yarray; 1521*47c6ae99SBarry Smith PetscErrorCode ierr; 1522*47c6ae99SBarry Smith Vec xglobal,yglobal; 1523*47c6ae99SBarry Smith PetscMPIInt rank; 1524*47c6ae99SBarry Smith DM_Composite *comright; 1525*47c6ae99SBarry Smith DM_Composite *comleft; 1526*47c6ae99SBarry Smith 1527*47c6ae99SBarry Smith PetscFunctionBegin; 1528*47c6ae99SBarry Smith ierr = MatShellGetContext(A,(void**)&mpack);CHKERRQ(ierr); 1529*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)mpack->right)->comm,&rank);CHKERRQ(ierr); 1530*47c6ae99SBarry Smith comright = (DM_Composite*)mpack->right->data; 1531*47c6ae99SBarry Smith comleft = (DM_Composite*)mpack->left->data; 1532*47c6ae99SBarry Smith ynext = comright->next; 1533*47c6ae99SBarry Smith xnext = comleft->next; 1534*47c6ae99SBarry Smith anext = mpack->next; 1535*47c6ae99SBarry Smith 1536*47c6ae99SBarry Smith while (xnext) { 1537*47c6ae99SBarry Smith if (xnext->type == DMCOMPOSITE_ARRAY) { 1538*47c6ae99SBarry Smith if (rank == ynext->rank) { 1539*47c6ae99SBarry Smith ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 1540*47c6ae99SBarry Smith ierr = VecGetArray(y,&yarray);CHKERRQ(ierr); 1541*47c6ae99SBarry Smith ierr = PetscMemcpy(yarray+ynext->rstart,xarray+xnext->rstart,xnext->n*sizeof(PetscScalar));CHKERRQ(ierr); 1542*47c6ae99SBarry Smith ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 1543*47c6ae99SBarry Smith ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr); 1544*47c6ae99SBarry Smith } 1545*47c6ae99SBarry Smith } else if (xnext->type == DMCOMPOSITE_DM) { 1546*47c6ae99SBarry Smith ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 1547*47c6ae99SBarry Smith ierr = VecGetArray(y,&yarray);CHKERRQ(ierr); 1548*47c6ae99SBarry Smith ierr = DMGetGlobalVector(xnext->dm,&xglobal);CHKERRQ(ierr); 1549*47c6ae99SBarry Smith ierr = DMGetGlobalVector(ynext->dm,&yglobal);CHKERRQ(ierr); 1550*47c6ae99SBarry Smith ierr = VecPlaceArray(xglobal,xarray+xnext->rstart);CHKERRQ(ierr); 1551*47c6ae99SBarry Smith ierr = VecPlaceArray(yglobal,yarray+ynext->rstart);CHKERRQ(ierr); 1552*47c6ae99SBarry Smith ierr = MatMultTranspose(anext->A,xglobal,yglobal);CHKERRQ(ierr); 1553*47c6ae99SBarry Smith ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 1554*47c6ae99SBarry Smith ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr); 1555*47c6ae99SBarry Smith ierr = VecResetArray(xglobal);CHKERRQ(ierr); 1556*47c6ae99SBarry Smith ierr = VecResetArray(yglobal);CHKERRQ(ierr); 1557*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(xnext->dm,&xglobal);CHKERRQ(ierr); 1558*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(ynext->dm,&yglobal);CHKERRQ(ierr); 1559*47c6ae99SBarry Smith anext = anext->next; 1560*47c6ae99SBarry Smith } else { 1561*47c6ae99SBarry Smith SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1562*47c6ae99SBarry Smith } 1563*47c6ae99SBarry Smith xnext = xnext->next; 1564*47c6ae99SBarry Smith ynext = ynext->next; 1565*47c6ae99SBarry Smith } 1566*47c6ae99SBarry Smith PetscFunctionReturn(0); 1567*47c6ae99SBarry Smith } 1568*47c6ae99SBarry Smith 1569*47c6ae99SBarry Smith #undef __FUNCT__ 1570*47c6ae99SBarry Smith #define __FUNCT__ "MatDestroy_Shell_Pack" 1571*47c6ae99SBarry Smith PetscErrorCode MatDestroy_Shell_Pack(Mat A) 1572*47c6ae99SBarry Smith { 1573*47c6ae99SBarry Smith struct MatPack *mpack; 1574*47c6ae99SBarry Smith struct MatPackLink *anext,*oldanext; 1575*47c6ae99SBarry Smith PetscErrorCode ierr; 1576*47c6ae99SBarry Smith 1577*47c6ae99SBarry Smith PetscFunctionBegin; 1578*47c6ae99SBarry Smith ierr = MatShellGetContext(A,(void**)&mpack);CHKERRQ(ierr); 1579*47c6ae99SBarry Smith anext = mpack->next; 1580*47c6ae99SBarry Smith 1581*47c6ae99SBarry Smith while (anext) { 1582*47c6ae99SBarry Smith ierr = MatDestroy(anext->A);CHKERRQ(ierr); 1583*47c6ae99SBarry Smith oldanext = anext; 1584*47c6ae99SBarry Smith anext = anext->next; 1585*47c6ae99SBarry Smith ierr = PetscFree(oldanext);CHKERRQ(ierr); 1586*47c6ae99SBarry Smith } 1587*47c6ae99SBarry Smith ierr = PetscFree(mpack);CHKERRQ(ierr); 1588*47c6ae99SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1589*47c6ae99SBarry Smith PetscFunctionReturn(0); 1590*47c6ae99SBarry Smith } 1591*47c6ae99SBarry Smith 1592*47c6ae99SBarry Smith #undef __FUNCT__ 1593*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetInterpolation" 1594*47c6ae99SBarry Smith /*@C 1595*47c6ae99SBarry Smith DMCompositeGetInterpolation - GetInterpolations a DM by refining all of its DAs 1596*47c6ae99SBarry Smith 1597*47c6ae99SBarry Smith Collective on DMComposite 1598*47c6ae99SBarry Smith 1599*47c6ae99SBarry Smith Input Parameters: 1600*47c6ae99SBarry Smith + coarse - coarse grid packer 1601*47c6ae99SBarry Smith - fine - fine grid packer 1602*47c6ae99SBarry Smith 1603*47c6ae99SBarry Smith Output Parameter: 1604*47c6ae99SBarry Smith + A - interpolation matrix 1605*47c6ae99SBarry Smith - v - scaling vector 1606*47c6ae99SBarry Smith 1607*47c6ae99SBarry Smith Level: advanced 1608*47c6ae99SBarry Smith 1609*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1610*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 1611*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeScatter(),DMCompositeGetEntries() 1612*47c6ae99SBarry Smith 1613*47c6ae99SBarry Smith @*/ 1614*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetInterpolation(DM coarse,DM fine,Mat *A,Vec *v) 1615*47c6ae99SBarry Smith { 1616*47c6ae99SBarry Smith PetscErrorCode ierr; 1617*47c6ae99SBarry Smith PetscInt m,n,M,N; 1618*47c6ae99SBarry Smith struct DMCompositeLink *nextc; 1619*47c6ae99SBarry Smith struct DMCompositeLink *nextf; 1620*47c6ae99SBarry Smith struct MatPackLink *nextmat,*pnextmat = 0; 1621*47c6ae99SBarry Smith struct MatPack *mpack; 1622*47c6ae99SBarry Smith Vec gcoarse,gfine; 1623*47c6ae99SBarry Smith DM_Composite *comcoarse = (DM_Composite*)coarse->data; 1624*47c6ae99SBarry Smith DM_Composite *comfine = (DM_Composite*)fine->data; 1625*47c6ae99SBarry Smith 1626*47c6ae99SBarry Smith PetscFunctionBegin; 1627*47c6ae99SBarry Smith PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 1628*47c6ae99SBarry Smith PetscValidHeaderSpecific(fine,DM_CLASSID,2); 1629*47c6ae99SBarry Smith nextc = comcoarse->next; 1630*47c6ae99SBarry Smith nextf = comfine->next; 1631*47c6ae99SBarry Smith /* use global vectors only for determining matrix layout */ 1632*47c6ae99SBarry Smith ierr = DMCompositeCreateGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 1633*47c6ae99SBarry Smith ierr = DMCompositeCreateGlobalVector(fine,&gfine);CHKERRQ(ierr); 1634*47c6ae99SBarry Smith ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 1635*47c6ae99SBarry Smith ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 1636*47c6ae99SBarry Smith ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 1637*47c6ae99SBarry Smith ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 1638*47c6ae99SBarry Smith ierr = VecDestroy(gcoarse);CHKERRQ(ierr); 1639*47c6ae99SBarry Smith ierr = VecDestroy(gfine);CHKERRQ(ierr); 1640*47c6ae99SBarry Smith 1641*47c6ae99SBarry Smith ierr = PetscNew(struct MatPack,&mpack);CHKERRQ(ierr); 1642*47c6ae99SBarry Smith mpack->right = coarse; 1643*47c6ae99SBarry Smith mpack->left = fine; 1644*47c6ae99SBarry Smith ierr = MatCreate(((PetscObject)fine)->comm,A);CHKERRQ(ierr); 1645*47c6ae99SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 1646*47c6ae99SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 1647*47c6ae99SBarry Smith ierr = MatShellSetContext(*A,mpack);CHKERRQ(ierr); 1648*47c6ae99SBarry Smith ierr = MatShellSetOperation(*A,MATOP_MULT,(void(*)(void))MatMult_Shell_Pack);CHKERRQ(ierr); 1649*47c6ae99SBarry Smith ierr = MatShellSetOperation(*A,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_Shell_Pack);CHKERRQ(ierr); 1650*47c6ae99SBarry Smith ierr = MatShellSetOperation(*A,MATOP_MULT_ADD,(void(*)(void))MatMultAdd_Shell_Pack);CHKERRQ(ierr); 1651*47c6ae99SBarry Smith ierr = MatShellSetOperation(*A,MATOP_DESTROY,(void(*)(void))MatDestroy_Shell_Pack);CHKERRQ(ierr); 1652*47c6ae99SBarry Smith 1653*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1654*47c6ae99SBarry Smith while (nextc) { 1655*47c6ae99SBarry Smith if (nextc->type != nextf->type) SETERRQ(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Two DM have different layout"); 1656*47c6ae99SBarry Smith 1657*47c6ae99SBarry Smith if (nextc->type == DMCOMPOSITE_ARRAY) { 1658*47c6ae99SBarry Smith ; 1659*47c6ae99SBarry Smith } else if (nextc->type == DMCOMPOSITE_DM) { 1660*47c6ae99SBarry Smith ierr = PetscNew(struct MatPackLink,&nextmat);CHKERRQ(ierr); 1661*47c6ae99SBarry Smith nextmat->next = 0; 1662*47c6ae99SBarry Smith if (pnextmat) { 1663*47c6ae99SBarry Smith pnextmat->next = nextmat; 1664*47c6ae99SBarry Smith pnextmat = nextmat; 1665*47c6ae99SBarry Smith } else { 1666*47c6ae99SBarry Smith pnextmat = nextmat; 1667*47c6ae99SBarry Smith mpack->next = nextmat; 1668*47c6ae99SBarry Smith } 1669*47c6ae99SBarry Smith ierr = DMGetInterpolation(nextc->dm,nextf->dm,&nextmat->A,PETSC_NULL);CHKERRQ(ierr); 1670*47c6ae99SBarry Smith } else { 1671*47c6ae99SBarry Smith SETERRQ(((PetscObject)fine)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1672*47c6ae99SBarry Smith } 1673*47c6ae99SBarry Smith nextc = nextc->next; 1674*47c6ae99SBarry Smith nextf = nextf->next; 1675*47c6ae99SBarry Smith } 1676*47c6ae99SBarry Smith PetscFunctionReturn(0); 1677*47c6ae99SBarry Smith } 1678*47c6ae99SBarry Smith 1679*47c6ae99SBarry Smith #undef __FUNCT__ 1680*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetMatrix" 1681*47c6ae99SBarry Smith /*@C 1682*47c6ae99SBarry Smith DMCompositeGetMatrix - Creates a matrix with the correct parallel layout and nonzero structure required for 1683*47c6ae99SBarry Smith computing the Jacobian on a function defined using the stencils set in the DA's and coupling in the array variables 1684*47c6ae99SBarry Smith 1685*47c6ae99SBarry Smith Collective on DA 1686*47c6ae99SBarry Smith 1687*47c6ae99SBarry Smith Input Parameter: 1688*47c6ae99SBarry Smith + dm - the distributed array 1689*47c6ae99SBarry Smith - mtype - Supported types are MATSEQAIJ, MATMPIAIJ 1690*47c6ae99SBarry Smith 1691*47c6ae99SBarry Smith Output Parameters: 1692*47c6ae99SBarry Smith . J - matrix with the correct nonzero structure 1693*47c6ae99SBarry Smith (obviously without the correct Jacobian values) 1694*47c6ae99SBarry Smith 1695*47c6ae99SBarry Smith Level: advanced 1696*47c6ae99SBarry Smith 1697*47c6ae99SBarry Smith Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 1698*47c6ae99SBarry Smith do not need to do it yourself. 1699*47c6ae99SBarry Smith 1700*47c6ae99SBarry Smith 1701*47c6ae99SBarry Smith .seealso DAGetMatrix(), DMCompositeCreate() 1702*47c6ae99SBarry Smith 1703*47c6ae99SBarry Smith @*/ 1704*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetMatrix(DM dm, const MatType mtype,Mat *J) 1705*47c6ae99SBarry Smith { 1706*47c6ae99SBarry Smith PetscErrorCode ierr; 1707*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1708*47c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 1709*47c6ae99SBarry Smith PetscInt m,*dnz,*onz,i,j,mA; 1710*47c6ae99SBarry Smith Mat Atmp; 1711*47c6ae99SBarry Smith PetscMPIInt rank; 1712*47c6ae99SBarry Smith PetscScalar zero = 0.0; 1713*47c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 1714*47c6ae99SBarry Smith 1715*47c6ae99SBarry Smith PetscFunctionBegin; 1716*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1717*47c6ae99SBarry Smith 1718*47c6ae99SBarry Smith /* use global vector to determine layout needed for matrix */ 1719*47c6ae99SBarry Smith m = com->n; 1720*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1721*47c6ae99SBarry Smith ierr = MatCreate(((PetscObject)dm)->comm,J);CHKERRQ(ierr); 1722*47c6ae99SBarry Smith ierr = MatSetSizes(*J,m,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1723*47c6ae99SBarry Smith ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 1724*47c6ae99SBarry Smith 1725*47c6ae99SBarry Smith /* 1726*47c6ae99SBarry Smith Extremely inefficient but will compute entire Jacobian for testing 1727*47c6ae99SBarry Smith */ 1728*47c6ae99SBarry Smith ierr = PetscOptionsGetTruth(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); 1729*47c6ae99SBarry Smith if (dense) { 1730*47c6ae99SBarry Smith PetscInt rstart,rend,*indices; 1731*47c6ae99SBarry Smith PetscScalar *values; 1732*47c6ae99SBarry Smith 1733*47c6ae99SBarry Smith mA = com->N; 1734*47c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(*J,mA,PETSC_NULL,mA-m,PETSC_NULL);CHKERRQ(ierr); 1735*47c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(*J,mA,PETSC_NULL);CHKERRQ(ierr); 1736*47c6ae99SBarry Smith 1737*47c6ae99SBarry Smith ierr = MatGetOwnershipRange(*J,&rstart,&rend);CHKERRQ(ierr); 1738*47c6ae99SBarry Smith ierr = PetscMalloc2(mA,PetscScalar,&values,mA,PetscInt,&indices);CHKERRQ(ierr); 1739*47c6ae99SBarry Smith ierr = PetscMemzero(values,mA*sizeof(PetscScalar));CHKERRQ(ierr); 1740*47c6ae99SBarry Smith for (i=0; i<mA; i++) indices[i] = i; 1741*47c6ae99SBarry Smith for (i=rstart; i<rend; i++) { 1742*47c6ae99SBarry Smith ierr = MatSetValues(*J,1,&i,mA,indices,values,INSERT_VALUES);CHKERRQ(ierr); 1743*47c6ae99SBarry Smith } 1744*47c6ae99SBarry Smith ierr = PetscFree2(values,indices);CHKERRQ(ierr); 1745*47c6ae99SBarry Smith ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1746*47c6ae99SBarry Smith ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1747*47c6ae99SBarry Smith PetscFunctionReturn(0); 1748*47c6ae99SBarry Smith } 1749*47c6ae99SBarry Smith 1750*47c6ae99SBarry Smith ierr = MatPreallocateInitialize(((PetscObject)dm)->comm,m,m,dnz,onz);CHKERRQ(ierr); 1751*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1752*47c6ae99SBarry Smith next = com->next; 1753*47c6ae99SBarry Smith while (next) { 1754*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1755*47c6ae99SBarry Smith if (rank == next->rank) { /* zero the "little" block */ 1756*47c6ae99SBarry Smith for (j=com->rstart+next->rstart; j<com->rstart+next->rstart+next->n; j++) { 1757*47c6ae99SBarry Smith for (i=com->rstart+next->rstart; i<com->rstart+next->rstart+next->n; i++) { 1758*47c6ae99SBarry Smith ierr = MatPreallocateSet(j,1,&i,dnz,onz);CHKERRQ(ierr); 1759*47c6ae99SBarry Smith } 1760*47c6ae99SBarry Smith } 1761*47c6ae99SBarry Smith } 1762*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1763*47c6ae99SBarry Smith PetscInt nc,rstart,*ccols,maxnc; 1764*47c6ae99SBarry Smith const PetscInt *cols,*rstarts; 1765*47c6ae99SBarry Smith PetscMPIInt proc; 1766*47c6ae99SBarry Smith 1767*47c6ae99SBarry Smith ierr = DMGetMatrix(next->dm,mtype,&Atmp);CHKERRQ(ierr); 1768*47c6ae99SBarry Smith ierr = MatGetOwnershipRange(Atmp,&rstart,PETSC_NULL);CHKERRQ(ierr); 1769*47c6ae99SBarry Smith ierr = MatGetOwnershipRanges(Atmp,&rstarts);CHKERRQ(ierr); 1770*47c6ae99SBarry Smith ierr = MatGetLocalSize(Atmp,&mA,PETSC_NULL);CHKERRQ(ierr); 1771*47c6ae99SBarry Smith 1772*47c6ae99SBarry Smith maxnc = 0; 1773*47c6ae99SBarry Smith for (i=0; i<mA; i++) { 1774*47c6ae99SBarry Smith ierr = MatGetRow(Atmp,rstart+i,&nc,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1775*47c6ae99SBarry Smith ierr = MatRestoreRow(Atmp,rstart+i,&nc,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1776*47c6ae99SBarry Smith maxnc = PetscMax(nc,maxnc); 1777*47c6ae99SBarry Smith } 1778*47c6ae99SBarry Smith ierr = PetscMalloc(maxnc*sizeof(PetscInt),&ccols);CHKERRQ(ierr); 1779*47c6ae99SBarry Smith for (i=0; i<mA; i++) { 1780*47c6ae99SBarry Smith ierr = MatGetRow(Atmp,rstart+i,&nc,&cols,PETSC_NULL);CHKERRQ(ierr); 1781*47c6ae99SBarry Smith /* remap the columns taking into how much they are shifted on each process */ 1782*47c6ae99SBarry Smith for (j=0; j<nc; j++) { 1783*47c6ae99SBarry Smith proc = 0; 1784*47c6ae99SBarry Smith while (cols[j] >= rstarts[proc+1]) proc++; 1785*47c6ae99SBarry Smith ccols[j] = cols[j] + next->grstarts[proc] - rstarts[proc]; 1786*47c6ae99SBarry Smith } 1787*47c6ae99SBarry Smith ierr = MatPreallocateSet(com->rstart+next->rstart+i,nc,ccols,dnz,onz);CHKERRQ(ierr); 1788*47c6ae99SBarry Smith ierr = MatRestoreRow(Atmp,rstart+i,&nc,&cols,PETSC_NULL);CHKERRQ(ierr); 1789*47c6ae99SBarry Smith } 1790*47c6ae99SBarry Smith ierr = PetscFree(ccols);CHKERRQ(ierr); 1791*47c6ae99SBarry Smith ierr = MatDestroy(Atmp);CHKERRQ(ierr); 1792*47c6ae99SBarry Smith } else { 1793*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1794*47c6ae99SBarry Smith } 1795*47c6ae99SBarry Smith next = next->next; 1796*47c6ae99SBarry Smith } 1797*47c6ae99SBarry Smith if (com->FormCoupleLocations) { 1798*47c6ae99SBarry Smith ierr = (*com->FormCoupleLocations)(dm,PETSC_NULL,dnz,onz,__rstart,__nrows,__start,__end);CHKERRQ(ierr); 1799*47c6ae99SBarry Smith } 1800*47c6ae99SBarry Smith ierr = MatMPIAIJSetPreallocation(*J,0,dnz,0,onz);CHKERRQ(ierr); 1801*47c6ae99SBarry Smith ierr = MatSeqAIJSetPreallocation(*J,0,dnz);CHKERRQ(ierr); 1802*47c6ae99SBarry Smith ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 1803*47c6ae99SBarry Smith 1804*47c6ae99SBarry Smith next = com->next; 1805*47c6ae99SBarry Smith while (next) { 1806*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1807*47c6ae99SBarry Smith if (rank == next->rank) { 1808*47c6ae99SBarry Smith for (j=com->rstart+next->rstart; j<com->rstart+next->rstart+next->n; j++) { 1809*47c6ae99SBarry Smith for (i=com->rstart+next->rstart; i<com->rstart+next->rstart+next->n; i++) { 1810*47c6ae99SBarry Smith ierr = MatSetValues(*J,1,&j,1,&i,&zero,INSERT_VALUES);CHKERRQ(ierr); 1811*47c6ae99SBarry Smith } 1812*47c6ae99SBarry Smith } 1813*47c6ae99SBarry Smith } 1814*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1815*47c6ae99SBarry Smith PetscInt nc,rstart,row,maxnc,*ccols; 1816*47c6ae99SBarry Smith const PetscInt *cols,*rstarts; 1817*47c6ae99SBarry Smith const PetscScalar *values; 1818*47c6ae99SBarry Smith PetscMPIInt proc; 1819*47c6ae99SBarry Smith 1820*47c6ae99SBarry Smith ierr = DMGetMatrix(next->dm,mtype,&Atmp);CHKERRQ(ierr); 1821*47c6ae99SBarry Smith ierr = MatGetOwnershipRange(Atmp,&rstart,PETSC_NULL);CHKERRQ(ierr); 1822*47c6ae99SBarry Smith ierr = MatGetOwnershipRanges(Atmp,&rstarts);CHKERRQ(ierr); 1823*47c6ae99SBarry Smith ierr = MatGetLocalSize(Atmp,&mA,PETSC_NULL);CHKERRQ(ierr); 1824*47c6ae99SBarry Smith maxnc = 0; 1825*47c6ae99SBarry Smith for (i=0; i<mA; i++) { 1826*47c6ae99SBarry Smith ierr = MatGetRow(Atmp,rstart+i,&nc,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1827*47c6ae99SBarry Smith ierr = MatRestoreRow(Atmp,rstart+i,&nc,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1828*47c6ae99SBarry Smith maxnc = PetscMax(nc,maxnc); 1829*47c6ae99SBarry Smith } 1830*47c6ae99SBarry Smith ierr = PetscMalloc(maxnc*sizeof(PetscInt),&ccols);CHKERRQ(ierr); 1831*47c6ae99SBarry Smith for (i=0; i<mA; i++) { 1832*47c6ae99SBarry Smith ierr = MatGetRow(Atmp,rstart+i,&nc,(const PetscInt **)&cols,&values);CHKERRQ(ierr); 1833*47c6ae99SBarry Smith for (j=0; j<nc; j++) { 1834*47c6ae99SBarry Smith proc = 0; 1835*47c6ae99SBarry Smith while (cols[j] >= rstarts[proc+1]) proc++; 1836*47c6ae99SBarry Smith ccols[j] = cols[j] + next->grstarts[proc] - rstarts[proc]; 1837*47c6ae99SBarry Smith } 1838*47c6ae99SBarry Smith row = com->rstart+next->rstart+i; 1839*47c6ae99SBarry Smith ierr = MatSetValues(*J,1,&row,nc,ccols,values,INSERT_VALUES);CHKERRQ(ierr); 1840*47c6ae99SBarry Smith ierr = MatRestoreRow(Atmp,rstart+i,&nc,(const PetscInt **)&cols,&values);CHKERRQ(ierr); 1841*47c6ae99SBarry Smith } 1842*47c6ae99SBarry Smith ierr = PetscFree(ccols);CHKERRQ(ierr); 1843*47c6ae99SBarry Smith ierr = MatDestroy(Atmp);CHKERRQ(ierr); 1844*47c6ae99SBarry Smith } else { 1845*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1846*47c6ae99SBarry Smith } 1847*47c6ae99SBarry Smith next = next->next; 1848*47c6ae99SBarry Smith } 1849*47c6ae99SBarry Smith if (com->FormCoupleLocations) { 1850*47c6ae99SBarry Smith PetscInt __rstart; 1851*47c6ae99SBarry Smith ierr = MatGetOwnershipRange(*J,&__rstart,PETSC_NULL);CHKERRQ(ierr); 1852*47c6ae99SBarry Smith ierr = (*com->FormCoupleLocations)(dm,*J,PETSC_NULL,PETSC_NULL,__rstart,0,0,0);CHKERRQ(ierr); 1853*47c6ae99SBarry Smith } 1854*47c6ae99SBarry Smith ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1855*47c6ae99SBarry Smith ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1856*47c6ae99SBarry Smith PetscFunctionReturn(0); 1857*47c6ae99SBarry Smith } 1858*47c6ae99SBarry Smith 1859*47c6ae99SBarry Smith #undef __FUNCT__ 1860*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGetColoring" 1861*47c6ae99SBarry Smith /*@ 1862*47c6ae99SBarry Smith DMCompositeGetColoring - Gets the coloring required for computing the Jacobian via 1863*47c6ae99SBarry Smith finite differences on a function defined using a DM "grid" 1864*47c6ae99SBarry Smith 1865*47c6ae99SBarry Smith Collective on DA 1866*47c6ae99SBarry Smith 1867*47c6ae99SBarry Smith Input Parameter: 1868*47c6ae99SBarry Smith + dm - the DM object 1869*47c6ae99SBarry Smith . ctype - IS_COLORING_GLOBAL or IS_COLORING_GHOSTED 1870*47c6ae99SBarry Smith - mtype - MATAIJ or MATBAIJ 1871*47c6ae99SBarry Smith 1872*47c6ae99SBarry Smith Output Parameters: 1873*47c6ae99SBarry Smith . coloring - matrix coloring for use in computing Jacobians (or PETSC_NULL if not needed) 1874*47c6ae99SBarry Smith 1875*47c6ae99SBarry Smith Level: advanced 1876*47c6ae99SBarry Smith 1877*47c6ae99SBarry Smith Notes: This colors each diagonal block (associated with a single DM) with a different set of colors; 1878*47c6ae99SBarry Smith this it will compute the diagonal blocks of the Jacobian correctly. The off diagonal blocks are 1879*47c6ae99SBarry Smith not computed, hence the Jacobian computed is not the entire Jacobian. If -dmcomposite_dense_jacobian 1880*47c6ae99SBarry Smith is used then each column of the Jacobian is given a different color so the full Jacobian is computed 1881*47c6ae99SBarry Smith correctly. 1882*47c6ae99SBarry Smith 1883*47c6ae99SBarry Smith Notes: These compute the graph coloring of the graph of A^{T}A. The coloring used 1884*47c6ae99SBarry Smith for efficient (parallel or thread based) triangular solves etc is NOT yet 1885*47c6ae99SBarry Smith available. 1886*47c6ae99SBarry Smith 1887*47c6ae99SBarry Smith 1888*47c6ae99SBarry Smith .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), ISColoringType, ISColoring, DAGetColoring() 1889*47c6ae99SBarry Smith 1890*47c6ae99SBarry Smith @*/ 1891*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGetColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring) 1892*47c6ae99SBarry Smith { 1893*47c6ae99SBarry Smith PetscErrorCode ierr; 1894*47c6ae99SBarry Smith PetscInt n,i,cnt; 1895*47c6ae99SBarry Smith ISColoringValue *colors; 1896*47c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 1897*47c6ae99SBarry Smith ISColoringValue maxcol = 0; 1898*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1899*47c6ae99SBarry Smith 1900*47c6ae99SBarry Smith PetscFunctionBegin; 1901*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1902*47c6ae99SBarry Smith if (ctype == IS_COLORING_GHOSTED) { 1903*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Currently you must use -dmmg_iscoloring_type global" ); 1904*47c6ae99SBarry Smith } else if (ctype == IS_COLORING_GLOBAL) { 1905*47c6ae99SBarry Smith n = com->n; 1906*47c6ae99SBarry Smith } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 1907*47c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 1908*47c6ae99SBarry Smith 1909*47c6ae99SBarry Smith ierr = PetscOptionsGetTruth(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); 1910*47c6ae99SBarry Smith if (dense) { 1911*47c6ae99SBarry Smith for (i=0; i<n; i++) { 1912*47c6ae99SBarry Smith colors[i] = (ISColoringValue)(com->rstart + i); 1913*47c6ae99SBarry Smith } 1914*47c6ae99SBarry Smith maxcol = com->N; 1915*47c6ae99SBarry Smith } else { 1916*47c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 1917*47c6ae99SBarry Smith PetscMPIInt rank; 1918*47c6ae99SBarry Smith 1919*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1920*47c6ae99SBarry Smith cnt = 0; 1921*47c6ae99SBarry Smith while (next) { 1922*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1923*47c6ae99SBarry Smith if (rank == next->rank) { /* each column gets is own color */ 1924*47c6ae99SBarry Smith for (i=com->rstart+next->rstart; i<com->rstart+next->rstart+next->n; i++) { 1925*47c6ae99SBarry Smith colors[cnt++] = maxcol++; 1926*47c6ae99SBarry Smith } 1927*47c6ae99SBarry Smith } 1928*47c6ae99SBarry Smith ierr = MPI_Bcast(&maxcol,1,MPIU_COLORING_VALUE,next->rank,((PetscObject)dm)->comm);CHKERRQ(ierr); 1929*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1930*47c6ae99SBarry Smith ISColoring lcoloring; 1931*47c6ae99SBarry Smith 1932*47c6ae99SBarry Smith ierr = DMGetColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr); 1933*47c6ae99SBarry Smith for (i=0; i<lcoloring->N; i++) { 1934*47c6ae99SBarry Smith colors[cnt++] = maxcol + lcoloring->colors[i]; 1935*47c6ae99SBarry Smith } 1936*47c6ae99SBarry Smith maxcol += lcoloring->n; 1937*47c6ae99SBarry Smith ierr = ISColoringDestroy(lcoloring);CHKERRQ(ierr); 1938*47c6ae99SBarry Smith } else { 1939*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 1940*47c6ae99SBarry Smith } 1941*47c6ae99SBarry Smith next = next->next; 1942*47c6ae99SBarry Smith } 1943*47c6ae99SBarry Smith } 1944*47c6ae99SBarry Smith ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr); 1945*47c6ae99SBarry Smith PetscFunctionReturn(0); 1946*47c6ae99SBarry Smith } 1947*47c6ae99SBarry Smith 1948*47c6ae99SBarry Smith #undef __FUNCT__ 1949*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGlobalToLocalBegin" 1950*47c6ae99SBarry Smith /*@C 1951*47c6ae99SBarry Smith DMCompositeGlobalToLocalBegin - begin update of single local vector from global vector 1952*47c6ae99SBarry Smith 1953*47c6ae99SBarry Smith Neighbor-wise Collective on DMComposite 1954*47c6ae99SBarry Smith 1955*47c6ae99SBarry Smith Input Parameter: 1956*47c6ae99SBarry Smith + dm - the packer object 1957*47c6ae99SBarry Smith . gvec - the global vector 1958*47c6ae99SBarry Smith - lvec - single local vector 1959*47c6ae99SBarry Smith 1960*47c6ae99SBarry Smith Level: advanced 1961*47c6ae99SBarry Smith 1962*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 1963*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 1964*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 1965*47c6ae99SBarry Smith 1966*47c6ae99SBarry Smith @*/ 1967*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGlobalToLocalBegin(DM dm,Vec gvec,InsertMode mode,Vec lvec) 1968*47c6ae99SBarry Smith { 1969*47c6ae99SBarry Smith PetscErrorCode ierr; 1970*47c6ae99SBarry Smith struct DMCompositeLink *next; 1971*47c6ae99SBarry Smith PetscInt cnt = 3; 1972*47c6ae99SBarry Smith PetscMPIInt rank; 1973*47c6ae99SBarry Smith PetscScalar *garray,*larray; 1974*47c6ae99SBarry Smith DM_Composite *com = (DM_Composite*)dm->data; 1975*47c6ae99SBarry Smith 1976*47c6ae99SBarry Smith PetscFunctionBegin; 1977*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1978*47c6ae99SBarry Smith PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 1979*47c6ae99SBarry Smith next = com->next; 1980*47c6ae99SBarry Smith if (!com->setup) { 1981*47c6ae99SBarry Smith ierr = DMCompositeSetUp(dm);CHKERRQ(ierr); 1982*47c6ae99SBarry Smith } 1983*47c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1984*47c6ae99SBarry Smith ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 1985*47c6ae99SBarry Smith ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 1986*47c6ae99SBarry Smith 1987*47c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 1988*47c6ae99SBarry Smith while (next) { 1989*47c6ae99SBarry Smith if (next->type == DMCOMPOSITE_ARRAY) { 1990*47c6ae99SBarry Smith if (rank == next->rank) { 1991*47c6ae99SBarry Smith ierr = PetscMemcpy(larray,garray,next->n*sizeof(PetscScalar));CHKERRQ(ierr); 1992*47c6ae99SBarry Smith garray += next->n; 1993*47c6ae99SBarry Smith } 1994*47c6ae99SBarry Smith /* does not handle ADD_VALUES */ 1995*47c6ae99SBarry Smith ierr = MPI_Bcast(larray,next->n,MPIU_SCALAR,next->rank,((PetscObject)dm)->comm);CHKERRQ(ierr); 1996*47c6ae99SBarry Smith larray += next->n; 1997*47c6ae99SBarry Smith } else if (next->type == DMCOMPOSITE_DM) { 1998*47c6ae99SBarry Smith Vec local,global; 1999*47c6ae99SBarry Smith PetscInt N; 2000*47c6ae99SBarry Smith 2001*47c6ae99SBarry Smith ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 2002*47c6ae99SBarry Smith ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 2003*47c6ae99SBarry Smith ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 2004*47c6ae99SBarry Smith ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 2005*47c6ae99SBarry Smith ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 2006*47c6ae99SBarry Smith ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 2007*47c6ae99SBarry Smith ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 2008*47c6ae99SBarry Smith ierr = VecResetArray(global);CHKERRQ(ierr); 2009*47c6ae99SBarry Smith ierr = VecResetArray(local);CHKERRQ(ierr); 2010*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 2011*47c6ae99SBarry Smith ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); 2012*47c6ae99SBarry Smith larray += next->n; 2013*47c6ae99SBarry Smith } else { 2014*47c6ae99SBarry Smith SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Cannot handle that object type yet"); 2015*47c6ae99SBarry Smith } 2016*47c6ae99SBarry Smith cnt++; 2017*47c6ae99SBarry Smith next = next->next; 2018*47c6ae99SBarry Smith } 2019*47c6ae99SBarry Smith 2020*47c6ae99SBarry Smith ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr); 2021*47c6ae99SBarry Smith ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr); 2022*47c6ae99SBarry Smith PetscFunctionReturn(0); 2023*47c6ae99SBarry Smith } 2024*47c6ae99SBarry Smith 2025*47c6ae99SBarry Smith #undef __FUNCT__ 2026*47c6ae99SBarry Smith #define __FUNCT__ "DMCompositeGlobalToLocalEnd" 2027*47c6ae99SBarry Smith /*@C 2028*47c6ae99SBarry Smith DMCompositeGlobalToLocalEnd - All communication is handled in the Begin phase 2029*47c6ae99SBarry Smith 2030*47c6ae99SBarry Smith Neighbor-wise Collective on DMComposite 2031*47c6ae99SBarry Smith 2032*47c6ae99SBarry Smith Input Parameter: 2033*47c6ae99SBarry Smith + dm - the packer object 2034*47c6ae99SBarry Smith . gvec - the global vector 2035*47c6ae99SBarry Smith - lvec - single local vector 2036*47c6ae99SBarry Smith 2037*47c6ae99SBarry Smith Level: advanced 2038*47c6ae99SBarry Smith 2039*47c6ae99SBarry Smith .seealso DMCompositeDestroy(), DMCompositeAddArray(), DMCompositeAddDM(), DMCompositeCreateGlobalVector(), 2040*47c6ae99SBarry Smith DMCompositeGather(), DMCompositeCreate(), DMCompositeGetGlobalIndices(), DMCompositeGetAccess(), 2041*47c6ae99SBarry Smith DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 2042*47c6ae99SBarry Smith 2043*47c6ae99SBarry Smith @*/ 2044*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMCompositeGlobalToLocalEnd(DM dm,Vec gvec,InsertMode mode,Vec lvec) 2045*47c6ae99SBarry Smith { 2046*47c6ae99SBarry Smith PetscFunctionBegin; 2047*47c6ae99SBarry Smith PetscFunctionReturn(0); 2048*47c6ae99SBarry Smith } 2049