1*47c6ae99SBarry Smith #define PETSCDM_DLL 2*47c6ae99SBarry Smith #include "private/daimpl.h" /*I "petscda.h" I*/ 3*47c6ae99SBarry Smith 4*47c6ae99SBarry Smith #undef __FUNCT__ 5*47c6ae99SBarry Smith #define __FUNCT__ "DASetOptionsPrefix" 6*47c6ae99SBarry Smith /*@C 7*47c6ae99SBarry Smith DASetOptionsPrefix - Sets the prefix used for searching for all 8*47c6ae99SBarry Smith DA options in the database. 9*47c6ae99SBarry Smith 10*47c6ae99SBarry Smith Logically Collective on DA 11*47c6ae99SBarry Smith 12*47c6ae99SBarry Smith Input Parameter: 13*47c6ae99SBarry Smith + da - the DA context 14*47c6ae99SBarry Smith - prefix - the prefix to prepend to all option names 15*47c6ae99SBarry Smith 16*47c6ae99SBarry Smith Notes: 17*47c6ae99SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 18*47c6ae99SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 19*47c6ae99SBarry Smith 20*47c6ae99SBarry Smith Level: advanced 21*47c6ae99SBarry Smith 22*47c6ae99SBarry Smith .keywords: DA, set, options, prefix, database 23*47c6ae99SBarry Smith 24*47c6ae99SBarry Smith .seealso: DASetFromOptions() 25*47c6ae99SBarry Smith @*/ 26*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetOptionsPrefix(DA da,const char prefix[]) 27*47c6ae99SBarry Smith { 28*47c6ae99SBarry Smith PetscErrorCode ierr; 29*47c6ae99SBarry Smith 30*47c6ae99SBarry Smith PetscFunctionBegin; 31*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 32*47c6ae99SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)da,prefix);CHKERRQ(ierr); 33*47c6ae99SBarry Smith PetscFunctionReturn(0); 34*47c6ae99SBarry Smith } 35*47c6ae99SBarry Smith 36*47c6ae99SBarry Smith #undef __FUNCT__ 37*47c6ae99SBarry Smith #define __FUNCT__ "DASetDim" 38*47c6ae99SBarry Smith /*@ 39*47c6ae99SBarry Smith DASetDim - Sets the dimension 40*47c6ae99SBarry Smith 41*47c6ae99SBarry Smith Collective on DA 42*47c6ae99SBarry Smith 43*47c6ae99SBarry Smith Input Parameters: 44*47c6ae99SBarry Smith + da - the DA 45*47c6ae99SBarry Smith - dim - the dimension (or PETSC_DECIDE) 46*47c6ae99SBarry Smith 47*47c6ae99SBarry Smith Level: intermediate 48*47c6ae99SBarry Smith 49*47c6ae99SBarry Smith .seealso: DaGetDim(), DASetSizes() 50*47c6ae99SBarry Smith @*/ 51*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetDim(DA da, PetscInt dim) 52*47c6ae99SBarry Smith { 53*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 54*47c6ae99SBarry Smith 55*47c6ae99SBarry Smith PetscFunctionBegin; 56*47c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 57*47c6ae99SBarry Smith if (dd->dim > 0 && dim != dd->dim) SETERRQ2(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot change DA dim from %D after it was set to %D",dd->dim,dim); 58*47c6ae99SBarry Smith dd->dim = dim; 59*47c6ae99SBarry Smith PetscFunctionReturn(0); 60*47c6ae99SBarry Smith } 61*47c6ae99SBarry Smith 62*47c6ae99SBarry Smith #undef __FUNCT__ 63*47c6ae99SBarry Smith #define __FUNCT__ "DASetSizes" 64*47c6ae99SBarry Smith /*@ 65*47c6ae99SBarry Smith DASetSizes - Sets the global sizes 66*47c6ae99SBarry Smith 67*47c6ae99SBarry Smith Logically Collective on DA 68*47c6ae99SBarry Smith 69*47c6ae99SBarry Smith Input Parameters: 70*47c6ae99SBarry Smith + da - the DA 71*47c6ae99SBarry Smith . M - the global X size (or PETSC_DECIDE) 72*47c6ae99SBarry Smith . N - the global Y size (or PETSC_DECIDE) 73*47c6ae99SBarry Smith - P - the global Z size (or PETSC_DECIDE) 74*47c6ae99SBarry Smith 75*47c6ae99SBarry Smith Level: intermediate 76*47c6ae99SBarry Smith 77*47c6ae99SBarry Smith .seealso: DAGetSize(), PetscSplitOwnership() 78*47c6ae99SBarry Smith @*/ 79*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetSizes(DA da, PetscInt M, PetscInt N, PetscInt P) 80*47c6ae99SBarry Smith { 81*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 82*47c6ae99SBarry Smith 83*47c6ae99SBarry Smith PetscFunctionBegin; 84*47c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 85*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,M,2); 86*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,N,3); 87*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,P,4); 88*47c6ae99SBarry Smith 89*47c6ae99SBarry Smith dd->M = M; 90*47c6ae99SBarry Smith dd->N = N; 91*47c6ae99SBarry Smith dd->P = P; 92*47c6ae99SBarry Smith PetscFunctionReturn(0); 93*47c6ae99SBarry Smith } 94*47c6ae99SBarry Smith 95*47c6ae99SBarry Smith #undef __FUNCT__ 96*47c6ae99SBarry Smith #define __FUNCT__ "DASetNumProcs" 97*47c6ae99SBarry Smith /*@ 98*47c6ae99SBarry Smith DASetNumProcs - Sets the number of processes in each dimension 99*47c6ae99SBarry Smith 100*47c6ae99SBarry Smith Logically Collective on DA 101*47c6ae99SBarry Smith 102*47c6ae99SBarry Smith Input Parameters: 103*47c6ae99SBarry Smith + da - the DA 104*47c6ae99SBarry Smith . m - the number of X procs (or PETSC_DECIDE) 105*47c6ae99SBarry Smith . n - the number of Y procs (or PETSC_DECIDE) 106*47c6ae99SBarry Smith - p - the number of Z procs (or PETSC_DECIDE) 107*47c6ae99SBarry Smith 108*47c6ae99SBarry Smith Level: intermediate 109*47c6ae99SBarry Smith 110*47c6ae99SBarry Smith .seealso: DASetSizes(), DAGetSize(), PetscSplitOwnership() 111*47c6ae99SBarry Smith @*/ 112*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetNumProcs(DA da, PetscInt m, PetscInt n, PetscInt p) 113*47c6ae99SBarry Smith { 114*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 115*47c6ae99SBarry Smith 116*47c6ae99SBarry Smith PetscFunctionBegin; 117*47c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 118*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,m,2); 119*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,n,3); 120*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,p,4); 121*47c6ae99SBarry Smith dd->m = m; 122*47c6ae99SBarry Smith dd->n = n; 123*47c6ae99SBarry Smith dd->p = p; 124*47c6ae99SBarry Smith PetscFunctionReturn(0); 125*47c6ae99SBarry Smith } 126*47c6ae99SBarry Smith 127*47c6ae99SBarry Smith #undef __FUNCT__ 128*47c6ae99SBarry Smith #define __FUNCT__ "DASetPeriodicity" 129*47c6ae99SBarry Smith /*@ 130*47c6ae99SBarry Smith DASetPeriodicity - Sets the type of periodicity 131*47c6ae99SBarry Smith 132*47c6ae99SBarry Smith Not collective 133*47c6ae99SBarry Smith 134*47c6ae99SBarry Smith Input Parameter: 135*47c6ae99SBarry Smith + da - The DA 136*47c6ae99SBarry Smith - ptype - One of DA_NONPERIODIC, DA_XPERIODIC, DA_YPERIODIC, DA_ZPERIODIC, DA_XYPERIODIC, DA_XZPERIODIC, DA_YZPERIODIC, or DA_XYZPERIODIC 137*47c6ae99SBarry Smith 138*47c6ae99SBarry Smith Level: intermediate 139*47c6ae99SBarry Smith 140*47c6ae99SBarry Smith .keywords: distributed array, periodicity 141*47c6ae99SBarry Smith .seealso: DACreate(), DADestroy(), DA, DAPeriodicType 142*47c6ae99SBarry Smith @*/ 143*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetPeriodicity(DA da, DAPeriodicType ptype) 144*47c6ae99SBarry Smith { 145*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 146*47c6ae99SBarry Smith 147*47c6ae99SBarry Smith PetscFunctionBegin; 148*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 149*47c6ae99SBarry Smith dd->wrap = ptype; 150*47c6ae99SBarry Smith PetscFunctionReturn(0); 151*47c6ae99SBarry Smith } 152*47c6ae99SBarry Smith 153*47c6ae99SBarry Smith #undef __FUNCT__ 154*47c6ae99SBarry Smith #define __FUNCT__ "DASetDof" 155*47c6ae99SBarry Smith /*@ 156*47c6ae99SBarry Smith DASetDof - Sets the number of degrees of freedom per vertex 157*47c6ae99SBarry Smith 158*47c6ae99SBarry Smith Not collective 159*47c6ae99SBarry Smith 160*47c6ae99SBarry Smith Input Parameter: 161*47c6ae99SBarry Smith + da - The DA 162*47c6ae99SBarry Smith - dof - Number of degrees of freedom 163*47c6ae99SBarry Smith 164*47c6ae99SBarry Smith Level: intermediate 165*47c6ae99SBarry Smith 166*47c6ae99SBarry Smith .keywords: distributed array, degrees of freedom 167*47c6ae99SBarry Smith .seealso: DACreate(), DADestroy(), DA 168*47c6ae99SBarry Smith @*/ 169*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetDof(DA da, int dof) 170*47c6ae99SBarry Smith { 171*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 172*47c6ae99SBarry Smith 173*47c6ae99SBarry Smith PetscFunctionBegin; 174*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 175*47c6ae99SBarry Smith dd->w = dof; 176*47c6ae99SBarry Smith PetscFunctionReturn(0); 177*47c6ae99SBarry Smith } 178*47c6ae99SBarry Smith 179*47c6ae99SBarry Smith #undef __FUNCT__ 180*47c6ae99SBarry Smith #define __FUNCT__ "DASetStencilType" 181*47c6ae99SBarry Smith /*@ 182*47c6ae99SBarry Smith DASetStencilType - Sets the type of the communication stencil 183*47c6ae99SBarry Smith 184*47c6ae99SBarry Smith Logically Collective on DA 185*47c6ae99SBarry Smith 186*47c6ae99SBarry Smith Input Parameter: 187*47c6ae99SBarry Smith + da - The DA 188*47c6ae99SBarry Smith - stype - The stencil type, use either DA_STENCIL_BOX or DA_STENCIL_STAR. 189*47c6ae99SBarry Smith 190*47c6ae99SBarry Smith Level: intermediate 191*47c6ae99SBarry Smith 192*47c6ae99SBarry Smith .keywords: distributed array, stencil 193*47c6ae99SBarry Smith .seealso: DACreate(), DADestroy(), DA 194*47c6ae99SBarry Smith @*/ 195*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetStencilType(DA da, DAStencilType stype) 196*47c6ae99SBarry Smith { 197*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 198*47c6ae99SBarry Smith 199*47c6ae99SBarry Smith PetscFunctionBegin; 200*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 201*47c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,stype,2); 202*47c6ae99SBarry Smith dd->stencil_type = stype; 203*47c6ae99SBarry Smith PetscFunctionReturn(0); 204*47c6ae99SBarry Smith } 205*47c6ae99SBarry Smith 206*47c6ae99SBarry Smith #undef __FUNCT__ 207*47c6ae99SBarry Smith #define __FUNCT__ "DASetStencilWidth" 208*47c6ae99SBarry Smith /*@ 209*47c6ae99SBarry Smith DASetStencilWidth - Sets the width of the communication stencil 210*47c6ae99SBarry Smith 211*47c6ae99SBarry Smith Logically Collective on DA 212*47c6ae99SBarry Smith 213*47c6ae99SBarry Smith Input Parameter: 214*47c6ae99SBarry Smith + da - The DA 215*47c6ae99SBarry Smith - width - The stencil width 216*47c6ae99SBarry Smith 217*47c6ae99SBarry Smith Level: intermediate 218*47c6ae99SBarry Smith 219*47c6ae99SBarry Smith .keywords: distributed array, stencil 220*47c6ae99SBarry Smith .seealso: DACreate(), DADestroy(), DA 221*47c6ae99SBarry Smith @*/ 222*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetStencilWidth(DA da, PetscInt width) 223*47c6ae99SBarry Smith { 224*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 225*47c6ae99SBarry Smith 226*47c6ae99SBarry Smith PetscFunctionBegin; 227*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 228*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,width,2); 229*47c6ae99SBarry Smith dd->s = width; 230*47c6ae99SBarry Smith PetscFunctionReturn(0); 231*47c6ae99SBarry Smith } 232*47c6ae99SBarry Smith 233*47c6ae99SBarry Smith #undef __FUNCT__ 234*47c6ae99SBarry Smith #define __FUNCT__ "DACheckOwnershipRanges_Private" 235*47c6ae99SBarry Smith static PetscErrorCode DACheckOwnershipRanges_Private(DA da,PetscInt M,PetscInt m,const PetscInt lx[]) 236*47c6ae99SBarry Smith { 237*47c6ae99SBarry Smith PetscInt i,sum; 238*47c6ae99SBarry Smith 239*47c6ae99SBarry Smith PetscFunctionBegin; 240*47c6ae99SBarry Smith if (M < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONGSTATE,"Global dimension not set"); 241*47c6ae99SBarry Smith for (i=sum=0; i<m; i++) sum += lx[i]; 242*47c6ae99SBarry Smith if (sum != M) SETERRQ2(((PetscObject)da)->comm,PETSC_ERR_ARG_INCOMP,"Ownership ranges sum to %D but global dimension is %D",sum,M); 243*47c6ae99SBarry Smith PetscFunctionReturn(0); 244*47c6ae99SBarry Smith } 245*47c6ae99SBarry Smith 246*47c6ae99SBarry Smith #undef __FUNCT__ 247*47c6ae99SBarry Smith #define __FUNCT__ "DASetOwnershipRanges" 248*47c6ae99SBarry Smith /*@ 249*47c6ae99SBarry Smith DASetOwnershipRanges - Sets the number of nodes in each direction on each process 250*47c6ae99SBarry Smith 251*47c6ae99SBarry Smith Logically Collective on DA 252*47c6ae99SBarry Smith 253*47c6ae99SBarry Smith Input Parameter: 254*47c6ae99SBarry Smith + da - The DA 255*47c6ae99SBarry Smith . lx - array containing number of nodes in the X direction on each process, or PETSC_NULL. If non-null, must be of length da->m 256*47c6ae99SBarry Smith . ly - array containing number of nodes in the Y direction on each process, or PETSC_NULL. If non-null, must be of length da->n 257*47c6ae99SBarry Smith - lz - array containing number of nodes in the Z direction on each process, or PETSC_NULL. If non-null, must be of length da->p. 258*47c6ae99SBarry Smith 259*47c6ae99SBarry Smith Level: intermediate 260*47c6ae99SBarry Smith 261*47c6ae99SBarry Smith .keywords: distributed array 262*47c6ae99SBarry Smith .seealso: DACreate(), DADestroy(), DA 263*47c6ae99SBarry Smith @*/ 264*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetOwnershipRanges(DA da, const PetscInt lx[], const PetscInt ly[], const PetscInt lz[]) 265*47c6ae99SBarry Smith { 266*47c6ae99SBarry Smith PetscErrorCode ierr; 267*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 268*47c6ae99SBarry Smith 269*47c6ae99SBarry Smith PetscFunctionBegin; 270*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 271*47c6ae99SBarry Smith if (lx) { 272*47c6ae99SBarry Smith if (dd->m < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 273*47c6ae99SBarry Smith ierr = DACheckOwnershipRanges_Private(da,dd->M,dd->m,lx);CHKERRQ(ierr); 274*47c6ae99SBarry Smith if (!dd->lx) { 275*47c6ae99SBarry Smith ierr = PetscMalloc(dd->m*sizeof(PetscInt), &dd->lx);CHKERRQ(ierr); 276*47c6ae99SBarry Smith } 277*47c6ae99SBarry Smith ierr = PetscMemcpy(dd->lx, lx, dd->m*sizeof(PetscInt));CHKERRQ(ierr); 278*47c6ae99SBarry Smith } 279*47c6ae99SBarry Smith if (ly) { 280*47c6ae99SBarry Smith if (dd->n < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 281*47c6ae99SBarry Smith ierr = DACheckOwnershipRanges_Private(da,dd->N,dd->n,ly);CHKERRQ(ierr); 282*47c6ae99SBarry Smith if (!dd->ly) { 283*47c6ae99SBarry Smith ierr = PetscMalloc(dd->n*sizeof(PetscInt), &dd->ly);CHKERRQ(ierr); 284*47c6ae99SBarry Smith } 285*47c6ae99SBarry Smith ierr = PetscMemcpy(dd->ly, ly, dd->n*sizeof(PetscInt));CHKERRQ(ierr); 286*47c6ae99SBarry Smith } 287*47c6ae99SBarry Smith if (lz) { 288*47c6ae99SBarry Smith if (dd->p < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 289*47c6ae99SBarry Smith ierr = DACheckOwnershipRanges_Private(da,dd->P,dd->p,lz);CHKERRQ(ierr); 290*47c6ae99SBarry Smith if (!dd->lz) { 291*47c6ae99SBarry Smith ierr = PetscMalloc(dd->p*sizeof(PetscInt), &dd->lz);CHKERRQ(ierr); 292*47c6ae99SBarry Smith } 293*47c6ae99SBarry Smith ierr = PetscMemcpy(dd->lz, lz, dd->p*sizeof(PetscInt));CHKERRQ(ierr); 294*47c6ae99SBarry Smith } 295*47c6ae99SBarry Smith PetscFunctionReturn(0); 296*47c6ae99SBarry Smith } 297*47c6ae99SBarry Smith 298*47c6ae99SBarry Smith #undef __FUNCT__ 299*47c6ae99SBarry Smith #define __FUNCT__ "DACreateOwnershipRanges" 300*47c6ae99SBarry Smith /* 301*47c6ae99SBarry Smith Ensure that da->lx, ly, and lz exist. Collective on DA. 302*47c6ae99SBarry Smith */ 303*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACreateOwnershipRanges(DA da) 304*47c6ae99SBarry Smith { 305*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 306*47c6ae99SBarry Smith PetscErrorCode ierr; 307*47c6ae99SBarry Smith PetscInt n; 308*47c6ae99SBarry Smith MPI_Comm comm; 309*47c6ae99SBarry Smith PetscMPIInt size; 310*47c6ae99SBarry Smith 311*47c6ae99SBarry Smith PetscFunctionBegin; 312*47c6ae99SBarry Smith if (!dd->lx) { 313*47c6ae99SBarry Smith ierr = PetscMalloc(dd->m*sizeof(PetscInt),&dd->lx);CHKERRQ(ierr); 314*47c6ae99SBarry Smith ierr = DAGetProcessorSubset(da,DA_X,dd->xs,&comm);CHKERRQ(ierr); 315*47c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 316*47c6ae99SBarry Smith n = (dd->xe-dd->xs)/dd->w; 317*47c6ae99SBarry Smith ierr = MPI_Allgather(&n,1,MPIU_INT,dd->lx,1,MPIU_INT,comm);CHKERRQ(ierr); 318*47c6ae99SBarry Smith } 319*47c6ae99SBarry Smith if (dd->dim > 1 && !dd->ly) { 320*47c6ae99SBarry Smith ierr = PetscMalloc(dd->n*sizeof(PetscInt),&dd->ly);CHKERRQ(ierr); 321*47c6ae99SBarry Smith ierr = DAGetProcessorSubset(da,DA_Y,dd->ys,&comm);CHKERRQ(ierr); 322*47c6ae99SBarry Smith n = dd->ye-dd->ys; 323*47c6ae99SBarry Smith ierr = MPI_Allgather(&n,1,MPIU_INT,dd->ly,1,MPIU_INT,comm);CHKERRQ(ierr); 324*47c6ae99SBarry Smith } 325*47c6ae99SBarry Smith if (dd->dim > 2 && !dd->lz) { 326*47c6ae99SBarry Smith ierr = PetscMalloc(dd->p*sizeof(PetscInt),&dd->lz);CHKERRQ(ierr); 327*47c6ae99SBarry Smith ierr = DAGetProcessorSubset(da,DA_Z,dd->zs,&comm);CHKERRQ(ierr); 328*47c6ae99SBarry Smith n = dd->ze-dd->zs; 329*47c6ae99SBarry Smith ierr = MPI_Allgather(&n,1,MPIU_INT,dd->lz,1,MPIU_INT,comm);CHKERRQ(ierr); 330*47c6ae99SBarry Smith } 331*47c6ae99SBarry Smith PetscFunctionReturn(0); 332*47c6ae99SBarry Smith } 333*47c6ae99SBarry Smith 334*47c6ae99SBarry Smith #undef __FUNCT__ 335*47c6ae99SBarry Smith #define __FUNCT__ "DASetInterpolationType" 336*47c6ae99SBarry Smith /*@ 337*47c6ae99SBarry Smith DASetInterpolationType - Sets the type of interpolation that will be 338*47c6ae99SBarry Smith returned by DAGetInterpolation() 339*47c6ae99SBarry Smith 340*47c6ae99SBarry Smith Logically Collective on DA 341*47c6ae99SBarry Smith 342*47c6ae99SBarry Smith Input Parameter: 343*47c6ae99SBarry Smith + da - initial distributed array 344*47c6ae99SBarry Smith . ctype - DA_Q1 and DA_Q0 are currently the only supported forms 345*47c6ae99SBarry Smith 346*47c6ae99SBarry Smith Level: intermediate 347*47c6ae99SBarry Smith 348*47c6ae99SBarry Smith Notes: you should call this on the coarser of the two DAs you pass to DAGetInterpolation() 349*47c6ae99SBarry Smith 350*47c6ae99SBarry Smith .keywords: distributed array, interpolation 351*47c6ae99SBarry Smith 352*47c6ae99SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), DA, DAInterpolationType 353*47c6ae99SBarry Smith @*/ 354*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetInterpolationType(DA da,DAInterpolationType ctype) 355*47c6ae99SBarry Smith { 356*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 357*47c6ae99SBarry Smith 358*47c6ae99SBarry Smith PetscFunctionBegin; 359*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 360*47c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,ctype,2); 361*47c6ae99SBarry Smith dd->interptype = ctype; 362*47c6ae99SBarry Smith PetscFunctionReturn(0); 363*47c6ae99SBarry Smith } 364*47c6ae99SBarry Smith 365*47c6ae99SBarry Smith #undef __FUNCT__ 366*47c6ae99SBarry Smith #define __FUNCT__ "DASetVecType" 367*47c6ae99SBarry Smith /*@ 368*47c6ae99SBarry Smith DASetVecType - Sets the type of vector created with DACreateLocalVector() and DACreateGlobalVector() 369*47c6ae99SBarry Smith 370*47c6ae99SBarry Smith Logically Collective on DA 371*47c6ae99SBarry Smith 372*47c6ae99SBarry Smith Input Parameter: 373*47c6ae99SBarry Smith + da - initial distributed array 374*47c6ae99SBarry Smith . ctype - the vector type, currently either VECSTANDARD or VECCUDA 375*47c6ae99SBarry Smith 376*47c6ae99SBarry Smith Options Database: 377*47c6ae99SBarry Smith . -da_vec_type ctype 378*47c6ae99SBarry Smith 379*47c6ae99SBarry Smith Level: intermediate 380*47c6ae99SBarry Smith 381*47c6ae99SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), DA, DAInterpolationType, VecType 382*47c6ae99SBarry Smith @*/ 383*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetVecType(DA da,const VecType ctype) 384*47c6ae99SBarry Smith { 385*47c6ae99SBarry Smith PetscErrorCode ierr; 386*47c6ae99SBarry Smith 387*47c6ae99SBarry Smith PetscFunctionBegin; 388*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 389*47c6ae99SBarry Smith ierr = PetscFree(da->vectype);CHKERRQ(ierr); 390*47c6ae99SBarry Smith ierr = PetscStrallocpy(ctype,&da->vectype);CHKERRQ(ierr); 391*47c6ae99SBarry Smith PetscFunctionReturn(0); 392*47c6ae99SBarry Smith } 393*47c6ae99SBarry Smith 394*47c6ae99SBarry Smith #undef __FUNCT__ 395*47c6ae99SBarry Smith #define __FUNCT__ "DAGetNeighbors" 396*47c6ae99SBarry Smith /*@C 397*47c6ae99SBarry Smith DAGetNeighbors - Gets an array containing the MPI rank of all the current 398*47c6ae99SBarry Smith processes neighbors. 399*47c6ae99SBarry Smith 400*47c6ae99SBarry Smith Not Collective 401*47c6ae99SBarry Smith 402*47c6ae99SBarry Smith Input Parameter: 403*47c6ae99SBarry Smith . da - the DA object 404*47c6ae99SBarry Smith 405*47c6ae99SBarry Smith Output Parameters: 406*47c6ae99SBarry Smith . ranks - the neighbors ranks, stored with the x index increasing most rapidly. 407*47c6ae99SBarry Smith this process itself is in the list 408*47c6ae99SBarry Smith 409*47c6ae99SBarry Smith Notes: In 2d the array is of length 9, in 3d of length 27 410*47c6ae99SBarry Smith Not supported in 1d 411*47c6ae99SBarry Smith Do not free the array, it is freed when the DA is destroyed. 412*47c6ae99SBarry Smith 413*47c6ae99SBarry Smith Fortran Notes: In fortran you must pass in an array of the appropriate length. 414*47c6ae99SBarry Smith 415*47c6ae99SBarry Smith Level: intermediate 416*47c6ae99SBarry Smith 417*47c6ae99SBarry Smith @*/ 418*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetNeighbors(DA da,const PetscMPIInt *ranks[]) 419*47c6ae99SBarry Smith { 420*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 421*47c6ae99SBarry Smith PetscFunctionBegin; 422*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 423*47c6ae99SBarry Smith *ranks = dd->neighbors; 424*47c6ae99SBarry Smith PetscFunctionReturn(0); 425*47c6ae99SBarry Smith } 426*47c6ae99SBarry Smith 427*47c6ae99SBarry Smith /*@C 428*47c6ae99SBarry Smith DASetElementType - Sets the element type to be returned by DAGetElements() 429*47c6ae99SBarry Smith 430*47c6ae99SBarry Smith Not Collective 431*47c6ae99SBarry Smith 432*47c6ae99SBarry Smith Input Parameter: 433*47c6ae99SBarry Smith . da - the DA object 434*47c6ae99SBarry Smith 435*47c6ae99SBarry Smith Output Parameters: 436*47c6ae99SBarry Smith . etype - the element type, currently either DA_ELEMENT_P1 or ELEMENT_Q1 437*47c6ae99SBarry Smith 438*47c6ae99SBarry Smith Level: intermediate 439*47c6ae99SBarry Smith 440*47c6ae99SBarry Smith .seealso: DAElementType, DAGetElementType(), DAGetElements(), DARestoreElements() 441*47c6ae99SBarry Smith @*/ 442*47c6ae99SBarry Smith #undef __FUNCT__ 443*47c6ae99SBarry Smith #define __FUNCT__ "DASetElementType" 444*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetElementType(DA da, DAElementType etype) 445*47c6ae99SBarry Smith { 446*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 447*47c6ae99SBarry Smith PetscErrorCode ierr; 448*47c6ae99SBarry Smith 449*47c6ae99SBarry Smith PetscFunctionBegin; 450*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 451*47c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,etype,2); 452*47c6ae99SBarry Smith if (dd->elementtype != etype) { 453*47c6ae99SBarry Smith ierr = PetscFree(dd->e);CHKERRQ(ierr); 454*47c6ae99SBarry Smith dd->elementtype = etype; 455*47c6ae99SBarry Smith dd->ne = 0; 456*47c6ae99SBarry Smith dd->e = PETSC_NULL; 457*47c6ae99SBarry Smith } 458*47c6ae99SBarry Smith PetscFunctionReturn(0); 459*47c6ae99SBarry Smith } 460*47c6ae99SBarry Smith 461*47c6ae99SBarry Smith /*@C 462*47c6ae99SBarry Smith DAGetElementType - Gets the element type to be returned by DAGetElements() 463*47c6ae99SBarry Smith 464*47c6ae99SBarry Smith Not Collective 465*47c6ae99SBarry Smith 466*47c6ae99SBarry Smith Input Parameter: 467*47c6ae99SBarry Smith . da - the DA object 468*47c6ae99SBarry Smith 469*47c6ae99SBarry Smith Output Parameters: 470*47c6ae99SBarry Smith . etype - the element type, currently either DA_ELEMENT_P1 or ELEMENT_Q1 471*47c6ae99SBarry Smith 472*47c6ae99SBarry Smith Level: intermediate 473*47c6ae99SBarry Smith 474*47c6ae99SBarry Smith .seealso: DAElementType, DASetElementType(), DAGetElements(), DARestoreElements() 475*47c6ae99SBarry Smith @*/ 476*47c6ae99SBarry Smith #undef __FUNCT__ 477*47c6ae99SBarry Smith #define __FUNCT__ "DAGetElementType" 478*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetElementType(DA da, DAElementType *etype) 479*47c6ae99SBarry Smith { 480*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 481*47c6ae99SBarry Smith PetscFunctionBegin; 482*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 483*47c6ae99SBarry Smith PetscValidPointer(etype,2); 484*47c6ae99SBarry Smith *etype = dd->elementtype; 485*47c6ae99SBarry Smith PetscFunctionReturn(0); 486*47c6ae99SBarry Smith } 487*47c6ae99SBarry Smith 488*47c6ae99SBarry Smith #undef __FUNCT__ 489*47c6ae99SBarry Smith #define __FUNCT__ "DMGetElements" 490*47c6ae99SBarry Smith /*@C 491*47c6ae99SBarry Smith DMGetElements - Gets an array containing the indices (in local coordinates) 492*47c6ae99SBarry Smith of all the local elements 493*47c6ae99SBarry Smith 494*47c6ae99SBarry Smith Not Collective 495*47c6ae99SBarry Smith 496*47c6ae99SBarry Smith Input Parameter: 497*47c6ae99SBarry Smith . dm - the DM object 498*47c6ae99SBarry Smith 499*47c6ae99SBarry Smith Output Parameters: 500*47c6ae99SBarry Smith + n - number of local elements 501*47c6ae99SBarry Smith - e - the indices of the elements vertices 502*47c6ae99SBarry Smith 503*47c6ae99SBarry Smith Level: intermediate 504*47c6ae99SBarry Smith 505*47c6ae99SBarry Smith .seealso: DMElementType, DMSetElementType(), DMRestoreElements() 506*47c6ae99SBarry Smith @*/ 507*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMGetElements(DM dm,PetscInt *n,const PetscInt *e[]) 508*47c6ae99SBarry Smith { 509*47c6ae99SBarry Smith PetscErrorCode ierr; 510*47c6ae99SBarry Smith PetscFunctionBegin; 511*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 512*47c6ae99SBarry Smith ierr = (dm->ops->getelements)(dm,n,e);CHKERRQ(ierr); 513*47c6ae99SBarry Smith PetscFunctionReturn(0); 514*47c6ae99SBarry Smith } 515*47c6ae99SBarry Smith 516*47c6ae99SBarry Smith #undef __FUNCT__ 517*47c6ae99SBarry Smith #define __FUNCT__ "DMRestoreElements" 518*47c6ae99SBarry Smith /*@C 519*47c6ae99SBarry Smith DMRestoreElements - Returns an array containing the indices (in local coordinates) 520*47c6ae99SBarry Smith of all the local elements obtained with DMGetElements() 521*47c6ae99SBarry Smith 522*47c6ae99SBarry Smith Not Collective 523*47c6ae99SBarry Smith 524*47c6ae99SBarry Smith Input Parameter: 525*47c6ae99SBarry Smith + dm - the DM object 526*47c6ae99SBarry Smith . n - number of local elements 527*47c6ae99SBarry Smith - e - the indices of the elements vertices 528*47c6ae99SBarry Smith 529*47c6ae99SBarry Smith Level: intermediate 530*47c6ae99SBarry Smith 531*47c6ae99SBarry Smith .seealso: DMElementType, DMSetElementType(), DMGetElements() 532*47c6ae99SBarry Smith @*/ 533*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMRestoreElements(DM dm,PetscInt *n,const PetscInt *e[]) 534*47c6ae99SBarry Smith { 535*47c6ae99SBarry Smith PetscErrorCode ierr; 536*47c6ae99SBarry Smith PetscFunctionBegin; 537*47c6ae99SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 538*47c6ae99SBarry Smith if (dm->ops->restoreelements) { 539*47c6ae99SBarry Smith ierr = (dm->ops->restoreelements)(dm,n,e);CHKERRQ(ierr); 540*47c6ae99SBarry Smith } 541*47c6ae99SBarry Smith PetscFunctionReturn(0); 542*47c6ae99SBarry Smith } 543*47c6ae99SBarry Smith 544*47c6ae99SBarry Smith #undef __FUNCT__ 545*47c6ae99SBarry Smith #define __FUNCT__ "DAGetOwnershipRanges" 546*47c6ae99SBarry Smith /*@C 547*47c6ae99SBarry Smith DAGetOwnershipRanges - Gets the ranges of indices in the x, y and z direction that are owned by each process 548*47c6ae99SBarry Smith 549*47c6ae99SBarry Smith Not Collective 550*47c6ae99SBarry Smith 551*47c6ae99SBarry Smith Input Parameter: 552*47c6ae99SBarry Smith . da - the DA object 553*47c6ae99SBarry Smith 554*47c6ae99SBarry Smith Output Parameter: 555*47c6ae99SBarry Smith + lx - ownership along x direction (optional) 556*47c6ae99SBarry Smith . ly - ownership along y direction (optional) 557*47c6ae99SBarry Smith - lz - ownership along z direction (optional) 558*47c6ae99SBarry Smith 559*47c6ae99SBarry Smith Level: intermediate 560*47c6ae99SBarry Smith 561*47c6ae99SBarry Smith Note: these correspond to the optional final arguments passed to DACreate(), DACreate2d(), DACreate3d() 562*47c6ae99SBarry Smith 563*47c6ae99SBarry Smith In Fortran one must pass in arrays lx, ly, and lz that are long enough to hold the values; the sixth, seventh and 564*47c6ae99SBarry Smith eighth arguments from DAGetInfo() 565*47c6ae99SBarry Smith 566*47c6ae99SBarry Smith In C you should not free these arrays, nor change the values in them. They will only have valid values while the 567*47c6ae99SBarry Smith DA they came from still exists (has not been destroyed). 568*47c6ae99SBarry Smith 569*47c6ae99SBarry Smith .seealso: DAGetCorners(), DAGetGhostCorners(), DACreate(), DACreate1d(), DACreate2d(), DACreate3d(), VecGetOwnershipRanges() 570*47c6ae99SBarry Smith @*/ 571*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetOwnershipRanges(DA da,const PetscInt *lx[],const PetscInt *ly[],const PetscInt *lz[]) 572*47c6ae99SBarry Smith { 573*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 574*47c6ae99SBarry Smith 575*47c6ae99SBarry Smith PetscFunctionBegin; 576*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 577*47c6ae99SBarry Smith if (lx) *lx = dd->lx; 578*47c6ae99SBarry Smith if (ly) *ly = dd->ly; 579*47c6ae99SBarry Smith if (lz) *lz = dd->lz; 580*47c6ae99SBarry Smith PetscFunctionReturn(0); 581*47c6ae99SBarry Smith } 582*47c6ae99SBarry Smith 583*47c6ae99SBarry Smith #undef __FUNCT__ 584*47c6ae99SBarry Smith #define __FUNCT__ "DASetRefinementFactor" 585*47c6ae99SBarry Smith /*@ 586*47c6ae99SBarry Smith DASetRefinementFactor - Set the ratios that the DA grid is refined 587*47c6ae99SBarry Smith 588*47c6ae99SBarry Smith Logically Collective on DA 589*47c6ae99SBarry Smith 590*47c6ae99SBarry Smith Input Parameters: 591*47c6ae99SBarry Smith + da - the DA object 592*47c6ae99SBarry Smith . refine_x - ratio of fine grid to coarse in x direction (2 by default) 593*47c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 594*47c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 595*47c6ae99SBarry Smith 596*47c6ae99SBarry Smith Options Database: 597*47c6ae99SBarry Smith + -da_refine_x - refinement ratio in x direction 598*47c6ae99SBarry Smith . -da_refine_y - refinement ratio in y direction 599*47c6ae99SBarry Smith - -da_refine_z - refinement ratio in z direction 600*47c6ae99SBarry Smith 601*47c6ae99SBarry Smith Level: intermediate 602*47c6ae99SBarry Smith 603*47c6ae99SBarry Smith Notes: Pass PETSC_IGNORE to leave a value unchanged 604*47c6ae99SBarry Smith 605*47c6ae99SBarry Smith .seealso: DARefine(), DAGetRefinementFactor() 606*47c6ae99SBarry Smith @*/ 607*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetRefinementFactor(DA da, PetscInt refine_x, PetscInt refine_y,PetscInt refine_z) 608*47c6ae99SBarry Smith { 609*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 610*47c6ae99SBarry Smith 611*47c6ae99SBarry Smith PetscFunctionBegin; 612*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 613*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_x,2); 614*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_y,3); 615*47c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_z,4); 616*47c6ae99SBarry Smith 617*47c6ae99SBarry Smith if (refine_x > 0) dd->refine_x = refine_x; 618*47c6ae99SBarry Smith if (refine_y > 0) dd->refine_y = refine_y; 619*47c6ae99SBarry Smith if (refine_z > 0) dd->refine_z = refine_z; 620*47c6ae99SBarry Smith PetscFunctionReturn(0); 621*47c6ae99SBarry Smith } 622*47c6ae99SBarry Smith 623*47c6ae99SBarry Smith #undef __FUNCT__ 624*47c6ae99SBarry Smith #define __FUNCT__ "DAGetRefinementFactor" 625*47c6ae99SBarry Smith /*@C 626*47c6ae99SBarry Smith DAGetRefinementFactor - Gets the ratios that the DA grid is refined 627*47c6ae99SBarry Smith 628*47c6ae99SBarry Smith Not Collective 629*47c6ae99SBarry Smith 630*47c6ae99SBarry Smith Input Parameter: 631*47c6ae99SBarry Smith . da - the DA object 632*47c6ae99SBarry Smith 633*47c6ae99SBarry Smith Output Parameters: 634*47c6ae99SBarry Smith + refine_x - ratio of fine grid to coarse in x direction (2 by default) 635*47c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 636*47c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 637*47c6ae99SBarry Smith 638*47c6ae99SBarry Smith Level: intermediate 639*47c6ae99SBarry Smith 640*47c6ae99SBarry Smith Notes: Pass PETSC_NULL for values you do not need 641*47c6ae99SBarry Smith 642*47c6ae99SBarry Smith .seealso: DARefine(), DASetRefinementFactor() 643*47c6ae99SBarry Smith @*/ 644*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetRefinementFactor(DA da, PetscInt *refine_x, PetscInt *refine_y,PetscInt *refine_z) 645*47c6ae99SBarry Smith { 646*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 647*47c6ae99SBarry Smith 648*47c6ae99SBarry Smith PetscFunctionBegin; 649*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 650*47c6ae99SBarry Smith if (refine_x) *refine_x = dd->refine_x; 651*47c6ae99SBarry Smith if (refine_y) *refine_y = dd->refine_y; 652*47c6ae99SBarry Smith if (refine_z) *refine_z = dd->refine_z; 653*47c6ae99SBarry Smith PetscFunctionReturn(0); 654*47c6ae99SBarry Smith } 655*47c6ae99SBarry Smith 656*47c6ae99SBarry Smith #undef __FUNCT__ 657*47c6ae99SBarry Smith #define __FUNCT__ "DASetGetMatrix" 658*47c6ae99SBarry Smith /*@C 659*47c6ae99SBarry Smith DASetGetMatrix - Sets the routine used by the DA to allocate a matrix. 660*47c6ae99SBarry Smith 661*47c6ae99SBarry Smith Logically Collective on DA 662*47c6ae99SBarry Smith 663*47c6ae99SBarry Smith Input Parameters: 664*47c6ae99SBarry Smith + da - the DA object 665*47c6ae99SBarry Smith - f - the function that allocates the matrix for that specific DA 666*47c6ae99SBarry Smith 667*47c6ae99SBarry Smith Level: developer 668*47c6ae99SBarry Smith 669*47c6ae99SBarry Smith Notes: See DASetBlockFills() that provides a simple way to provide the nonzero structure for 670*47c6ae99SBarry Smith the diagonal and off-diagonal blocks of the matrix 671*47c6ae99SBarry Smith 672*47c6ae99SBarry Smith .seealso: DAGetMatrix(), DASetBlockFills() 673*47c6ae99SBarry Smith @*/ 674*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetGetMatrix(DA da,PetscErrorCode (*f)(DA, const MatType,Mat*)) 675*47c6ae99SBarry Smith { 676*47c6ae99SBarry Smith PetscFunctionBegin; 677*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 678*47c6ae99SBarry Smith da->ops->getmatrix = f; 679*47c6ae99SBarry Smith PetscFunctionReturn(0); 680*47c6ae99SBarry Smith } 681*47c6ae99SBarry Smith 682*47c6ae99SBarry Smith #undef __FUNCT__ 683*47c6ae99SBarry Smith #define __FUNCT__ "DARefineOwnershipRanges" 684*47c6ae99SBarry Smith /* 685*47c6ae99SBarry Smith Creates "balanced" ownership ranges after refinement, constrained by the need for the 686*47c6ae99SBarry Smith fine grid boundaries to fall within one stencil width of the coarse partition. 687*47c6ae99SBarry Smith 688*47c6ae99SBarry Smith Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 689*47c6ae99SBarry Smith */ 690*47c6ae99SBarry Smith static PetscErrorCode DARefineOwnershipRanges(DA da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lc[],PetscInt lf[]) 691*47c6ae99SBarry Smith { 692*47c6ae99SBarry Smith PetscInt i,totalc = 0,remaining,startc = 0,startf = 0; 693*47c6ae99SBarry Smith PetscErrorCode ierr; 694*47c6ae99SBarry Smith 695*47c6ae99SBarry Smith PetscFunctionBegin; 696*47c6ae99SBarry Smith if (ratio < 1) SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_USER,"Requested refinement ratio %D must be at least 1",ratio); 697*47c6ae99SBarry Smith if (ratio == 1) { 698*47c6ae99SBarry Smith ierr = PetscMemcpy(lf,lc,m*sizeof(lc[0]));CHKERRQ(ierr); 699*47c6ae99SBarry Smith PetscFunctionReturn(0); 700*47c6ae99SBarry Smith } 701*47c6ae99SBarry Smith for (i=0; i<m; i++) totalc += lc[i]; 702*47c6ae99SBarry Smith remaining = (!periodic) + ratio * (totalc - (!periodic)); 703*47c6ae99SBarry Smith for (i=0; i<m; i++) { 704*47c6ae99SBarry Smith PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 705*47c6ae99SBarry Smith if (i == m-1) lf[i] = want; 706*47c6ae99SBarry Smith else { 707*47c6ae99SBarry Smith PetscInt diffc = (startf+want)/ratio - (startc + lc[i]); 708*47c6ae99SBarry Smith while (PetscAbs(diffc) > stencil_width) { 709*47c6ae99SBarry Smith want += (diffc < 0); 710*47c6ae99SBarry Smith diffc = (startf+want)/ratio - (startc + lc[i]); 711*47c6ae99SBarry Smith } 712*47c6ae99SBarry Smith } 713*47c6ae99SBarry Smith lf[i] = want; 714*47c6ae99SBarry Smith startc += lc[i]; 715*47c6ae99SBarry Smith startf += lf[i]; 716*47c6ae99SBarry Smith remaining -= lf[i]; 717*47c6ae99SBarry Smith } 718*47c6ae99SBarry Smith PetscFunctionReturn(0); 719*47c6ae99SBarry Smith } 720*47c6ae99SBarry Smith 721*47c6ae99SBarry Smith #undef __FUNCT__ 722*47c6ae99SBarry Smith #define __FUNCT__ "DARefine" 723*47c6ae99SBarry Smith /*@ 724*47c6ae99SBarry Smith DARefine - Creates a new distributed array that is a refinement of a given 725*47c6ae99SBarry Smith distributed array. 726*47c6ae99SBarry Smith 727*47c6ae99SBarry Smith Collective on DA 728*47c6ae99SBarry Smith 729*47c6ae99SBarry Smith Input Parameter: 730*47c6ae99SBarry Smith + da - initial distributed array 731*47c6ae99SBarry Smith - comm - communicator to contain refined DA, must be either same as the da communicator or include the 732*47c6ae99SBarry Smith da communicator and be 2, 4, or 8 times larger. Currently ignored 733*47c6ae99SBarry Smith 734*47c6ae99SBarry Smith Output Parameter: 735*47c6ae99SBarry Smith . daref - refined distributed array 736*47c6ae99SBarry Smith 737*47c6ae99SBarry Smith Level: advanced 738*47c6ae99SBarry Smith 739*47c6ae99SBarry Smith Note: 740*47c6ae99SBarry Smith Currently, refinement consists of just doubling the number of grid spaces 741*47c6ae99SBarry Smith in each dimension of the DA. 742*47c6ae99SBarry Smith 743*47c6ae99SBarry Smith .keywords: distributed array, refine 744*47c6ae99SBarry Smith 745*47c6ae99SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), DAGetOwnershipRanges() 746*47c6ae99SBarry Smith @*/ 747*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DARefine(DA da,MPI_Comm comm,DA *daref) 748*47c6ae99SBarry Smith { 749*47c6ae99SBarry Smith PetscErrorCode ierr; 750*47c6ae99SBarry Smith PetscInt M,N,P; 751*47c6ae99SBarry Smith DA da2; 752*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 753*47c6ae99SBarry Smith 754*47c6ae99SBarry Smith PetscFunctionBegin; 755*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 756*47c6ae99SBarry Smith PetscValidPointer(daref,3); 757*47c6ae99SBarry Smith 758*47c6ae99SBarry Smith if (DAXPeriodic(dd->wrap) || dd->interptype == DA_Q0){ 759*47c6ae99SBarry Smith M = dd->refine_x*dd->M; 760*47c6ae99SBarry Smith } else { 761*47c6ae99SBarry Smith M = 1 + dd->refine_x*(dd->M - 1); 762*47c6ae99SBarry Smith } 763*47c6ae99SBarry Smith if (DAYPeriodic(dd->wrap) || dd->interptype == DA_Q0){ 764*47c6ae99SBarry Smith N = dd->refine_y*dd->N; 765*47c6ae99SBarry Smith } else { 766*47c6ae99SBarry Smith N = 1 + dd->refine_y*(dd->N - 1); 767*47c6ae99SBarry Smith } 768*47c6ae99SBarry Smith if (DAZPeriodic(dd->wrap) || dd->interptype == DA_Q0){ 769*47c6ae99SBarry Smith P = dd->refine_z*dd->P; 770*47c6ae99SBarry Smith } else { 771*47c6ae99SBarry Smith P = 1 + dd->refine_z*(dd->P - 1); 772*47c6ae99SBarry Smith } 773*47c6ae99SBarry Smith ierr = DACreateOwnershipRanges(da);CHKERRQ(ierr); 774*47c6ae99SBarry Smith if (dd->dim == 3) { 775*47c6ae99SBarry Smith PetscInt *lx,*ly,*lz; 776*47c6ae99SBarry Smith ierr = PetscMalloc3(dd->m,PetscInt,&lx,dd->n,PetscInt,&ly,dd->p,PetscInt,&lz);CHKERRQ(ierr); 777*47c6ae99SBarry Smith ierr = DARefineOwnershipRanges(da,(PetscBool)(DAXPeriodic(dd->wrap) || dd->interptype == DA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 778*47c6ae99SBarry Smith ierr = DARefineOwnershipRanges(da,(PetscBool)(DAYPeriodic(dd->wrap) || dd->interptype == DA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly);CHKERRQ(ierr); 779*47c6ae99SBarry Smith ierr = DARefineOwnershipRanges(da,(PetscBool)(DAZPeriodic(dd->wrap) || dd->interptype == DA_Q0),dd->s,dd->refine_z,dd->p,dd->lz,lz);CHKERRQ(ierr); 780*47c6ae99SBarry Smith ierr = DACreate3d(((PetscObject)da)->comm,dd->wrap,dd->stencil_type,M,N,P,dd->m,dd->n,dd->p,dd->w,dd->s,lx,ly,lz,&da2);CHKERRQ(ierr); 781*47c6ae99SBarry Smith ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); 782*47c6ae99SBarry Smith } else if (dd->dim == 2) { 783*47c6ae99SBarry Smith PetscInt *lx,*ly; 784*47c6ae99SBarry Smith ierr = PetscMalloc2(dd->m,PetscInt,&lx,dd->n,PetscInt,&ly);CHKERRQ(ierr); 785*47c6ae99SBarry Smith ierr = DARefineOwnershipRanges(da,(PetscBool)(DAXPeriodic(dd->wrap) || dd->interptype == DA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 786*47c6ae99SBarry Smith ierr = DARefineOwnershipRanges(da,(PetscBool)(DAYPeriodic(dd->wrap) || dd->interptype == DA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly);CHKERRQ(ierr); 787*47c6ae99SBarry Smith ierr = DACreate2d(((PetscObject)da)->comm,dd->wrap,dd->stencil_type,M,N,dd->m,dd->n,dd->w,dd->s,lx,ly,&da2);CHKERRQ(ierr); 788*47c6ae99SBarry Smith ierr = PetscFree2(lx,ly);CHKERRQ(ierr); 789*47c6ae99SBarry Smith } else if (dd->dim == 1) { 790*47c6ae99SBarry Smith PetscInt *lx; 791*47c6ae99SBarry Smith ierr = PetscMalloc(dd->m*sizeof(PetscInt),&lx);CHKERRQ(ierr); 792*47c6ae99SBarry Smith ierr = DARefineOwnershipRanges(da,(PetscBool)(DAXPeriodic(dd->wrap) || dd->interptype == DA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 793*47c6ae99SBarry Smith ierr = DACreate1d(((PetscObject)da)->comm,dd->wrap,M,dd->w,dd->s,lx,&da2);CHKERRQ(ierr); 794*47c6ae99SBarry Smith ierr = PetscFree(lx);CHKERRQ(ierr); 795*47c6ae99SBarry Smith } 796*47c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 797*47c6ae99SBarry Smith 798*47c6ae99SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 799*47c6ae99SBarry Smith da2->ops->getmatrix = da->ops->getmatrix; 800*47c6ae99SBarry Smith da2->ops->getinterpolation = da->ops->getinterpolation; 801*47c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 802*47c6ae99SBarry Smith dd2->interptype = dd->interptype; 803*47c6ae99SBarry Smith 804*47c6ae99SBarry Smith /* copy fill information if given */ 805*47c6ae99SBarry Smith if (dd->dfill) { 806*47c6ae99SBarry Smith ierr = PetscMalloc((dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt),&dd2->dfill);CHKERRQ(ierr); 807*47c6ae99SBarry Smith ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 808*47c6ae99SBarry Smith } 809*47c6ae99SBarry Smith if (dd->ofill) { 810*47c6ae99SBarry Smith ierr = PetscMalloc((dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt),&dd2->ofill);CHKERRQ(ierr); 811*47c6ae99SBarry Smith ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 812*47c6ae99SBarry Smith } 813*47c6ae99SBarry Smith /* copy the refine information */ 814*47c6ae99SBarry Smith dd2->refine_x = dd->refine_x; 815*47c6ae99SBarry Smith dd2->refine_y = dd->refine_y; 816*47c6ae99SBarry Smith dd2->refine_z = dd->refine_z; 817*47c6ae99SBarry Smith 818*47c6ae99SBarry Smith /* copy vector type information */ 819*47c6ae99SBarry Smith ierr = PetscFree(da2->vectype);CHKERRQ(ierr); 820*47c6ae99SBarry Smith ierr = PetscStrallocpy(da->vectype,&da2->vectype);CHKERRQ(ierr); 821*47c6ae99SBarry Smith *daref = da2; 822*47c6ae99SBarry Smith PetscFunctionReturn(0); 823*47c6ae99SBarry Smith } 824*47c6ae99SBarry Smith 825*47c6ae99SBarry Smith #undef __FUNCT__ 826*47c6ae99SBarry Smith #define __FUNCT__ "DACoarsen" 827*47c6ae99SBarry Smith /*@ 828*47c6ae99SBarry Smith DACoarsen - Creates a new distributed array that is a coarsenment of a given 829*47c6ae99SBarry Smith distributed array. 830*47c6ae99SBarry Smith 831*47c6ae99SBarry Smith Collective on DA 832*47c6ae99SBarry Smith 833*47c6ae99SBarry Smith Input Parameter: 834*47c6ae99SBarry Smith + da - initial distributed array 835*47c6ae99SBarry Smith - comm - communicator to contain coarsend DA. Currently ignored 836*47c6ae99SBarry Smith 837*47c6ae99SBarry Smith Output Parameter: 838*47c6ae99SBarry Smith . daref - coarsend distributed array 839*47c6ae99SBarry Smith 840*47c6ae99SBarry Smith Level: advanced 841*47c6ae99SBarry Smith 842*47c6ae99SBarry Smith Note: 843*47c6ae99SBarry Smith Currently, coarsenment consists of just dividing the number of grid spaces 844*47c6ae99SBarry Smith in each dimension of the DA by refinex_x, refinex_y, .... 845*47c6ae99SBarry Smith 846*47c6ae99SBarry Smith .keywords: distributed array, coarsen 847*47c6ae99SBarry Smith 848*47c6ae99SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), DAGetOwnershipRanges() 849*47c6ae99SBarry Smith @*/ 850*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACoarsen(DA da, MPI_Comm comm,DA *daref) 851*47c6ae99SBarry Smith { 852*47c6ae99SBarry Smith PetscErrorCode ierr; 853*47c6ae99SBarry Smith PetscInt M,N,P; 854*47c6ae99SBarry Smith DA da2; 855*47c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 856*47c6ae99SBarry Smith 857*47c6ae99SBarry Smith PetscFunctionBegin; 858*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 859*47c6ae99SBarry Smith PetscValidPointer(daref,3); 860*47c6ae99SBarry Smith 861*47c6ae99SBarry Smith if (DAXPeriodic(dd->wrap) || dd->interptype == DA_Q0){ 862*47c6ae99SBarry Smith if(dd->refine_x) 863*47c6ae99SBarry Smith M = dd->M / dd->refine_x; 864*47c6ae99SBarry Smith else 865*47c6ae99SBarry Smith M = dd->M; 866*47c6ae99SBarry Smith } else { 867*47c6ae99SBarry Smith if(dd->refine_x) 868*47c6ae99SBarry Smith M = 1 + (dd->M - 1) / dd->refine_x; 869*47c6ae99SBarry Smith else 870*47c6ae99SBarry Smith M = dd->M; 871*47c6ae99SBarry Smith } 872*47c6ae99SBarry Smith if (DAYPeriodic(dd->wrap) || dd->interptype == DA_Q0){ 873*47c6ae99SBarry Smith if(dd->refine_y) 874*47c6ae99SBarry Smith N = dd->N / dd->refine_y; 875*47c6ae99SBarry Smith else 876*47c6ae99SBarry Smith N = dd->N; 877*47c6ae99SBarry Smith } else { 878*47c6ae99SBarry Smith if(dd->refine_y) 879*47c6ae99SBarry Smith N = 1 + (dd->N - 1) / dd->refine_y; 880*47c6ae99SBarry Smith else 881*47c6ae99SBarry Smith N = dd->M; 882*47c6ae99SBarry Smith } 883*47c6ae99SBarry Smith if (DAZPeriodic(dd->wrap) || dd->interptype == DA_Q0){ 884*47c6ae99SBarry Smith if(dd->refine_z) 885*47c6ae99SBarry Smith P = dd->P / dd->refine_z; 886*47c6ae99SBarry Smith else 887*47c6ae99SBarry Smith P = dd->P; 888*47c6ae99SBarry Smith } else { 889*47c6ae99SBarry Smith if(dd->refine_z) 890*47c6ae99SBarry Smith P = 1 + (dd->P - 1) / dd->refine_z; 891*47c6ae99SBarry Smith else 892*47c6ae99SBarry Smith P = dd->P; 893*47c6ae99SBarry Smith } 894*47c6ae99SBarry Smith if (dd->dim == 3) { 895*47c6ae99SBarry Smith ierr = DACreate3d(((PetscObject)da)->comm,dd->wrap,dd->stencil_type,M,N,P,dd->m,dd->n,dd->p,dd->w,dd->s,0,0,0,&da2);CHKERRQ(ierr); 896*47c6ae99SBarry Smith } else if (dd->dim == 2) { 897*47c6ae99SBarry Smith ierr = DACreate2d(((PetscObject)da)->comm,dd->wrap,dd->stencil_type,M,N,dd->m,dd->n,dd->w,dd->s,0,0,&da2);CHKERRQ(ierr); 898*47c6ae99SBarry Smith } else if (dd->dim == 1) { 899*47c6ae99SBarry Smith ierr = DACreate1d(((PetscObject)da)->comm,dd->wrap,M,dd->w,dd->s,0,&da2);CHKERRQ(ierr); 900*47c6ae99SBarry Smith } 901*47c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 902*47c6ae99SBarry Smith 903*47c6ae99SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 904*47c6ae99SBarry Smith da2->ops->getmatrix = da->ops->getmatrix; 905*47c6ae99SBarry Smith da2->ops->getinterpolation = da->ops->getinterpolation; 906*47c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 907*47c6ae99SBarry Smith dd2->interptype = dd->interptype; 908*47c6ae99SBarry Smith 909*47c6ae99SBarry Smith /* copy fill information if given */ 910*47c6ae99SBarry Smith if (dd->dfill) { 911*47c6ae99SBarry Smith ierr = PetscMalloc((dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt),&dd2->dfill);CHKERRQ(ierr); 912*47c6ae99SBarry Smith ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 913*47c6ae99SBarry Smith } 914*47c6ae99SBarry Smith if (dd->ofill) { 915*47c6ae99SBarry Smith ierr = PetscMalloc((dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt),&dd2->ofill);CHKERRQ(ierr); 916*47c6ae99SBarry Smith ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 917*47c6ae99SBarry Smith } 918*47c6ae99SBarry Smith /* copy the refine information */ 919*47c6ae99SBarry Smith dd2->refine_x = dd->refine_x; 920*47c6ae99SBarry Smith dd2->refine_y = dd->refine_y; 921*47c6ae99SBarry Smith dd2->refine_z = dd->refine_z; 922*47c6ae99SBarry Smith 923*47c6ae99SBarry Smith /* copy vector type information */ 924*47c6ae99SBarry Smith ierr = PetscFree(da2->vectype);CHKERRQ(ierr); 925*47c6ae99SBarry Smith ierr = PetscStrallocpy(da->vectype,&da2->vectype);CHKERRQ(ierr); 926*47c6ae99SBarry Smith 927*47c6ae99SBarry Smith *daref = da2; 928*47c6ae99SBarry Smith PetscFunctionReturn(0); 929*47c6ae99SBarry Smith } 930*47c6ae99SBarry Smith 931*47c6ae99SBarry Smith #undef __FUNCT__ 932*47c6ae99SBarry Smith #define __FUNCT__ "DARefineHierarchy" 933*47c6ae99SBarry Smith /*@ 934*47c6ae99SBarry Smith DARefineHierarchy - Perform multiple levels of refinement. 935*47c6ae99SBarry Smith 936*47c6ae99SBarry Smith Collective on DA 937*47c6ae99SBarry Smith 938*47c6ae99SBarry Smith Input Parameter: 939*47c6ae99SBarry Smith + da - initial distributed array 940*47c6ae99SBarry Smith - nlevels - number of levels of refinement to perform 941*47c6ae99SBarry Smith 942*47c6ae99SBarry Smith Output Parameter: 943*47c6ae99SBarry Smith . daf - array of refined DAs 944*47c6ae99SBarry Smith 945*47c6ae99SBarry Smith Options Database: 946*47c6ae99SBarry Smith + -da_refine_hierarchy_x - list of refinement ratios in x direction 947*47c6ae99SBarry Smith . -da_refine_hierarchy_y - list of refinement ratios in y direction 948*47c6ae99SBarry Smith - -da_refine_hierarchy_z - list of refinement ratios in z direction 949*47c6ae99SBarry Smith 950*47c6ae99SBarry Smith Level: advanced 951*47c6ae99SBarry Smith 952*47c6ae99SBarry Smith .keywords: distributed array, refine 953*47c6ae99SBarry Smith 954*47c6ae99SBarry Smith .seealso: DARefine(), DACoarsenHierarchy() 955*47c6ae99SBarry Smith @*/ 956*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DARefineHierarchy(DA da,PetscInt nlevels,DA daf[]) 957*47c6ae99SBarry Smith { 958*47c6ae99SBarry Smith PetscErrorCode ierr; 959*47c6ae99SBarry Smith PetscInt i,n,*refx,*refy,*refz; 960*47c6ae99SBarry Smith 961*47c6ae99SBarry Smith PetscFunctionBegin; 962*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 963*47c6ae99SBarry Smith if (nlevels < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 964*47c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 965*47c6ae99SBarry Smith PetscValidPointer(daf,3); 966*47c6ae99SBarry Smith 967*47c6ae99SBarry Smith /* Get refinement factors, defaults taken from the coarse DA */ 968*47c6ae99SBarry Smith ierr = PetscMalloc3(nlevels,PetscInt,&refx,nlevels,PetscInt,&refy,nlevels,PetscInt,&refz);CHKERRQ(ierr); 969*47c6ae99SBarry Smith for (i=0; i<nlevels; i++) { 970*47c6ae99SBarry Smith ierr = DAGetRefinementFactor(da,&refx[i],&refy[i],&refz[i]);CHKERRQ(ierr); 971*47c6ae99SBarry Smith } 972*47c6ae99SBarry Smith n = nlevels; 973*47c6ae99SBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,PETSC_NULL);CHKERRQ(ierr); 974*47c6ae99SBarry Smith n = nlevels; 975*47c6ae99SBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,PETSC_NULL);CHKERRQ(ierr); 976*47c6ae99SBarry Smith n = nlevels; 977*47c6ae99SBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,PETSC_NULL);CHKERRQ(ierr); 978*47c6ae99SBarry Smith 979*47c6ae99SBarry Smith ierr = DASetRefinementFactor(da,refx[0],refy[0],refz[0]);CHKERRQ(ierr); 980*47c6ae99SBarry Smith ierr = DARefine(da,((PetscObject)da)->comm,&daf[0]);CHKERRQ(ierr); 981*47c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 982*47c6ae99SBarry Smith ierr = DASetRefinementFactor(daf[i-1],refx[i],refy[i],refz[i]);CHKERRQ(ierr); 983*47c6ae99SBarry Smith ierr = DARefine(daf[i-1],((PetscObject)da)->comm,&daf[i]);CHKERRQ(ierr); 984*47c6ae99SBarry Smith } 985*47c6ae99SBarry Smith ierr = PetscFree3(refx,refy,refz);CHKERRQ(ierr); 986*47c6ae99SBarry Smith PetscFunctionReturn(0); 987*47c6ae99SBarry Smith } 988*47c6ae99SBarry Smith 989*47c6ae99SBarry Smith #undef __FUNCT__ 990*47c6ae99SBarry Smith #define __FUNCT__ "DACoarsenHierarchy" 991*47c6ae99SBarry Smith /*@ 992*47c6ae99SBarry Smith DACoarsenHierarchy - Perform multiple levels of coarsening 993*47c6ae99SBarry Smith 994*47c6ae99SBarry Smith Collective on DA 995*47c6ae99SBarry Smith 996*47c6ae99SBarry Smith Input Parameter: 997*47c6ae99SBarry Smith + da - initial distributed array 998*47c6ae99SBarry Smith - nlevels - number of levels of coarsening to perform 999*47c6ae99SBarry Smith 1000*47c6ae99SBarry Smith Output Parameter: 1001*47c6ae99SBarry Smith . dac - array of coarsened DAs 1002*47c6ae99SBarry Smith 1003*47c6ae99SBarry Smith Level: advanced 1004*47c6ae99SBarry Smith 1005*47c6ae99SBarry Smith .keywords: distributed array, coarsen 1006*47c6ae99SBarry Smith 1007*47c6ae99SBarry Smith .seealso: DACoarsen(), DARefineHierarchy() 1008*47c6ae99SBarry Smith @*/ 1009*47c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACoarsenHierarchy(DA da,PetscInt nlevels,DA dac[]) 1010*47c6ae99SBarry Smith { 1011*47c6ae99SBarry Smith PetscErrorCode ierr; 1012*47c6ae99SBarry Smith PetscInt i; 1013*47c6ae99SBarry Smith 1014*47c6ae99SBarry Smith PetscFunctionBegin; 1015*47c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1016*47c6ae99SBarry Smith if (nlevels < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 1017*47c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 1018*47c6ae99SBarry Smith PetscValidPointer(dac,3); 1019*47c6ae99SBarry Smith ierr = DACoarsen(da,((PetscObject)da)->comm,&dac[0]);CHKERRQ(ierr); 1020*47c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 1021*47c6ae99SBarry Smith ierr = DACoarsen(dac[i-1],((PetscObject)da)->comm,&dac[i]);CHKERRQ(ierr); 1022*47c6ae99SBarry Smith } 1023*47c6ae99SBarry Smith PetscFunctionReturn(0); 1024*47c6ae99SBarry Smith } 1025