1af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 247c6ae99SBarry Smith 347c6ae99SBarry Smith /*@ 4e43dc8daSBarry Smith DMDASetSizes - Sets the number of grid points in the three dimensional directions 547c6ae99SBarry Smith 6d083f849SBarry Smith Logically Collective on da 747c6ae99SBarry Smith 847c6ae99SBarry Smith Input Parameters: 9aa219208SBarry Smith + da - the DMDA 10e43dc8daSBarry Smith . M - the global X size 11e43dc8daSBarry Smith . N - the global Y size 12e43dc8daSBarry Smith - P - the global Z size 1347c6ae99SBarry Smith 1447c6ae99SBarry Smith Level: intermediate 1547c6ae99SBarry Smith 16628e512eSPatrick Sanan Developer Notes: 17628e512eSPatrick Sanan Since the dimension may not yet have been set the code cannot error check for non-positive Y and Z number of grid points 18e43dc8daSBarry Smith 19db781477SPatrick Sanan .seealso: `PetscSplitOwnership()` 2047c6ae99SBarry Smith @*/ 217087cfbeSBarry Smith PetscErrorCode DMDASetSizes(DM da, PetscInt M, PetscInt N, PetscInt P) 2247c6ae99SBarry Smith { 2347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 2447c6ae99SBarry Smith 2547c6ae99SBarry Smith PetscFunctionBegin; 26a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA); 2747c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,M,2); 2847c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,N,3); 2947c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,P,4); 307a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 317a8be351SBarry Smith PetscCheck(M >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Number of grid points in X direction must be positive"); 327a8be351SBarry Smith PetscCheck(N >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Number of grid points in Y direction must be positive"); 337a8be351SBarry Smith PetscCheck(P >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Number of grid points in Z direction must be positive"); 3447c6ae99SBarry Smith 3547c6ae99SBarry Smith dd->M = M; 3647c6ae99SBarry Smith dd->N = N; 3747c6ae99SBarry Smith dd->P = P; 3847c6ae99SBarry Smith PetscFunctionReturn(0); 3947c6ae99SBarry Smith } 4047c6ae99SBarry Smith 4147c6ae99SBarry Smith /*@ 42aa219208SBarry Smith DMDASetNumProcs - Sets the number of processes in each dimension 4347c6ae99SBarry Smith 44d083f849SBarry Smith Logically Collective on da 4547c6ae99SBarry Smith 4647c6ae99SBarry Smith Input Parameters: 47aa219208SBarry Smith + da - the DMDA 4847c6ae99SBarry Smith . m - the number of X procs (or PETSC_DECIDE) 4947c6ae99SBarry Smith . n - the number of Y procs (or PETSC_DECIDE) 5047c6ae99SBarry Smith - p - the number of Z procs (or PETSC_DECIDE) 5147c6ae99SBarry Smith 5247c6ae99SBarry Smith Level: intermediate 5347c6ae99SBarry Smith 54db781477SPatrick Sanan .seealso: `DMDASetSizes()`, `PetscSplitOwnership()` 5547c6ae99SBarry Smith @*/ 567087cfbeSBarry Smith PetscErrorCode DMDASetNumProcs(DM da, PetscInt m, PetscInt n, PetscInt p) 5747c6ae99SBarry Smith { 5847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 5947c6ae99SBarry Smith 6047c6ae99SBarry Smith PetscFunctionBegin; 61a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA); 6247c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,m,2); 6347c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,n,3); 6447c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,p,4); 657a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 6647c6ae99SBarry Smith dd->m = m; 6747c6ae99SBarry Smith dd->n = n; 6847c6ae99SBarry Smith dd->p = p; 69c73cfb54SMatthew G. Knepley if (da->dim == 2) { 70d3be247eSBarry Smith PetscMPIInt size; 719566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)da),&size)); 72e3f3e4b6SBarry Smith if ((dd->m > 0) && (dd->n < 0)) { 73e3f3e4b6SBarry Smith dd->n = size/dd->m; 7463a3b9bcSJacob Faibussowitsch PetscCheck(dd->n*dd->m == size,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"%" PetscInt_FMT " processes in X direction not divisible into comm size %d",m,size); 75e3f3e4b6SBarry Smith } 76e3f3e4b6SBarry Smith if ((dd->n > 0) && (dd->m < 0)) { 77e3f3e4b6SBarry Smith dd->m = size/dd->n; 7863a3b9bcSJacob Faibussowitsch PetscCheck(dd->n*dd->m == size,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"%" PetscInt_FMT " processes in Y direction not divisible into comm size %d",n,size); 79e3f3e4b6SBarry Smith } 80e3f3e4b6SBarry Smith } 8147c6ae99SBarry Smith PetscFunctionReturn(0); 8247c6ae99SBarry Smith } 8347c6ae99SBarry Smith 8447c6ae99SBarry Smith /*@ 851321219cSEthan Coon DMDASetBoundaryType - Sets the type of ghost nodes on domain boundaries. 8647c6ae99SBarry Smith 8747c6ae99SBarry Smith Not collective 8847c6ae99SBarry Smith 89d8d19677SJose E. Roman Input Parameters: 90aa219208SBarry Smith + da - The DMDA 91bff4a2f0SMatthew G. Knepley - bx,by,bz - One of DM_BOUNDARY_NONE, DM_BOUNDARY_GHOSTED, DM_BOUNDARY_PERIODIC 9247c6ae99SBarry Smith 9347c6ae99SBarry Smith Level: intermediate 9447c6ae99SBarry Smith 95db781477SPatrick Sanan .seealso: `DMDACreate()`, `DMDestroy()`, `DMDA`, `DMBoundaryType` 9647c6ae99SBarry Smith @*/ 97bff4a2f0SMatthew G. Knepley PetscErrorCode DMDASetBoundaryType(DM da,DMBoundaryType bx,DMBoundaryType by,DMBoundaryType bz) 9847c6ae99SBarry Smith { 9947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 10047c6ae99SBarry Smith 10147c6ae99SBarry Smith PetscFunctionBegin; 102a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 1035a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,bx,2); 1045a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,by,3); 1055a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,bz,4); 1067a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 1071321219cSEthan Coon dd->bx = bx; 1081321219cSEthan Coon dd->by = by; 1091321219cSEthan Coon dd->bz = bz; 11047c6ae99SBarry Smith PetscFunctionReturn(0); 11147c6ae99SBarry Smith } 11247c6ae99SBarry Smith 11347c6ae99SBarry Smith /*@ 114aa219208SBarry Smith DMDASetDof - Sets the number of degrees of freedom per vertex 11547c6ae99SBarry Smith 11647c6ae99SBarry Smith Not collective 11747c6ae99SBarry Smith 11859f3ab6dSMatthew G. Knepley Input Parameters: 119aa219208SBarry Smith + da - The DMDA 12047c6ae99SBarry Smith - dof - Number of degrees of freedom 12147c6ae99SBarry Smith 12247c6ae99SBarry Smith Level: intermediate 12347c6ae99SBarry Smith 124db781477SPatrick Sanan .seealso: `DMDAGetDof()`, `DMDACreate()`, `DMDestroy()`, `DMDA` 12547c6ae99SBarry Smith @*/ 12654cfb0beSLisandro Dalcin PetscErrorCode DMDASetDof(DM da, PetscInt dof) 12747c6ae99SBarry Smith { 12847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 12947c6ae99SBarry Smith 13047c6ae99SBarry Smith PetscFunctionBegin; 131a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 13254cfb0beSLisandro Dalcin PetscValidLogicalCollectiveInt(da,dof,2); 1337a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 13447c6ae99SBarry Smith dd->w = dof; 1351411c6eeSJed Brown da->bs = dof; 13647c6ae99SBarry Smith PetscFunctionReturn(0); 13747c6ae99SBarry Smith } 13847c6ae99SBarry Smith 139fb6725baSMatthew G. Knepley /*@ 140fb6725baSMatthew G. Knepley DMDAGetDof - Gets the number of degrees of freedom per vertex 141fb6725baSMatthew G. Knepley 142fb6725baSMatthew G. Knepley Not collective 143fb6725baSMatthew G. Knepley 144fb6725baSMatthew G. Knepley Input Parameter: 145fb6725baSMatthew G. Knepley . da - The DMDA 146fb6725baSMatthew G. Knepley 147fb6725baSMatthew G. Knepley Output Parameter: 148fb6725baSMatthew G. Knepley . dof - Number of degrees of freedom 149fb6725baSMatthew G. Knepley 150fb6725baSMatthew G. Knepley Level: intermediate 151fb6725baSMatthew G. Knepley 152db781477SPatrick Sanan .seealso: `DMDASetDof()`, `DMDACreate()`, `DMDestroy()`, `DMDA` 153fb6725baSMatthew G. Knepley @*/ 154fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetDof(DM da, PetscInt *dof) 155fb6725baSMatthew G. Knepley { 156fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *) da->data; 157fb6725baSMatthew G. Knepley 158fb6725baSMatthew G. Knepley PetscFunctionBegin; 159a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 160dadcf809SJacob Faibussowitsch PetscValidIntPointer(dof,2); 161fb6725baSMatthew G. Knepley *dof = dd->w; 162fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 163fb6725baSMatthew G. Knepley } 164fb6725baSMatthew G. Knepley 1657ddda789SPeter Brune /*@ 1667ddda789SPeter Brune DMDAGetOverlap - Gets the size of the per-processor overlap. 1677ddda789SPeter Brune 1687ddda789SPeter Brune Not collective 1697ddda789SPeter Brune 170f899ff85SJose E. Roman Input Parameter: 1717ddda789SPeter Brune . da - The DMDA 1727ddda789SPeter Brune 1737ddda789SPeter Brune Output Parameters: 1747ddda789SPeter Brune + x - Overlap in the x direction 1757ddda789SPeter Brune . y - Overlap in the y direction 1767ddda789SPeter Brune - z - Overlap in the z direction 1777ddda789SPeter Brune 1787ddda789SPeter Brune Level: intermediate 1797ddda789SPeter Brune 180*2b3cbbdaSStefano Zampini .seealso: `DMCreateDomainDecomposition()`, `DMDASetOverlap()`, `DMDA` 1817ddda789SPeter Brune @*/ 1827ddda789SPeter Brune PetscErrorCode DMDAGetOverlap(DM da,PetscInt *x,PetscInt *y,PetscInt *z) 1837ddda789SPeter Brune { 1847ddda789SPeter Brune DM_DA *dd = (DM_DA*)da->data; 1857ddda789SPeter Brune 1867ddda789SPeter Brune PetscFunctionBegin; 187a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 1887ddda789SPeter Brune if (x) *x = dd->xol; 1897ddda789SPeter Brune if (y) *y = dd->yol; 1907ddda789SPeter Brune if (z) *z = dd->zol; 1917ddda789SPeter Brune PetscFunctionReturn(0); 1927ddda789SPeter Brune } 1937ddda789SPeter Brune 19488661749SPeter Brune /*@ 19588661749SPeter Brune DMDASetOverlap - Sets the size of the per-processor overlap. 19688661749SPeter Brune 19788661749SPeter Brune Not collective 19888661749SPeter Brune 1997ddda789SPeter Brune Input Parameters: 20088661749SPeter Brune + da - The DMDA 2017ddda789SPeter Brune . x - Overlap in the x direction 2027ddda789SPeter Brune . y - Overlap in the y direction 2037ddda789SPeter Brune - z - Overlap in the z direction 20488661749SPeter Brune 20588661749SPeter Brune Level: intermediate 20688661749SPeter Brune 207*2b3cbbdaSStefano Zampini .seealso: `DMCreateDomainDecomposition()`, `DMDAGetOverlap()`, `DMDA` 20888661749SPeter Brune @*/ 2097ddda789SPeter Brune PetscErrorCode DMDASetOverlap(DM da,PetscInt x,PetscInt y,PetscInt z) 21088661749SPeter Brune { 21188661749SPeter Brune DM_DA *dd = (DM_DA*)da->data; 21288661749SPeter Brune 21388661749SPeter Brune PetscFunctionBegin; 214a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 2157ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,x,2); 2167ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,y,3); 2177ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,z,4); 2187ddda789SPeter Brune dd->xol = x; 2197ddda789SPeter Brune dd->yol = y; 2207ddda789SPeter Brune dd->zol = z; 22188661749SPeter Brune PetscFunctionReturn(0); 22288661749SPeter Brune } 22388661749SPeter Brune 2243e7870d2SPeter Brune /*@ 2253e7870d2SPeter Brune DMDAGetNumLocalSubDomains - Gets the number of local subdomains created upon decomposition. 2263e7870d2SPeter Brune 2273e7870d2SPeter Brune Not collective 2283e7870d2SPeter Brune 2293e7870d2SPeter Brune Input Parameters: 2303e7870d2SPeter Brune . da - The DMDA 2313e7870d2SPeter Brune 2323e7870d2SPeter Brune Output Parameters: 233a2b725a8SWilliam Gropp . Nsub - Number of local subdomains created upon decomposition 2343e7870d2SPeter Brune 2353e7870d2SPeter Brune Level: intermediate 2363e7870d2SPeter Brune 237*2b3cbbdaSStefano Zampini .seealso: `DMCreateDomainDecomposition()`, `DMDASetNumLocalSubDomains()`, `DMDA` 2383e7870d2SPeter Brune @*/ 2393e7870d2SPeter Brune PetscErrorCode DMDAGetNumLocalSubDomains(DM da,PetscInt *Nsub) 2403e7870d2SPeter Brune { 2413e7870d2SPeter Brune DM_DA *dd = (DM_DA*)da->data; 2423e7870d2SPeter Brune 2433e7870d2SPeter Brune PetscFunctionBegin; 244a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 2453e7870d2SPeter Brune if (Nsub) *Nsub = dd->Nsub; 2463e7870d2SPeter Brune PetscFunctionReturn(0); 2473e7870d2SPeter Brune } 2483e7870d2SPeter Brune 2493e7870d2SPeter Brune /*@ 2503e7870d2SPeter Brune DMDASetNumLocalSubDomains - Sets the number of local subdomains created upon decomposition. 2513e7870d2SPeter Brune 2523e7870d2SPeter Brune Not collective 2533e7870d2SPeter Brune 2543e7870d2SPeter Brune Input Parameters: 2553e7870d2SPeter Brune + da - The DMDA 2563e7870d2SPeter Brune - Nsub - The number of local subdomains requested 2573e7870d2SPeter Brune 2583e7870d2SPeter Brune Level: intermediate 2593e7870d2SPeter Brune 260*2b3cbbdaSStefano Zampini .seealso: `DMCreateDomainDecomposition()`, `DMDAGetNumLocalSubDomains()`, `DMDA` 2613e7870d2SPeter Brune @*/ 2623e7870d2SPeter Brune PetscErrorCode DMDASetNumLocalSubDomains(DM da,PetscInt Nsub) 2633e7870d2SPeter Brune { 2643e7870d2SPeter Brune DM_DA *dd = (DM_DA*)da->data; 2653e7870d2SPeter Brune 2663e7870d2SPeter Brune PetscFunctionBegin; 267a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 2683e7870d2SPeter Brune PetscValidLogicalCollectiveInt(da,Nsub,2); 2693e7870d2SPeter Brune dd->Nsub = Nsub; 2703e7870d2SPeter Brune PetscFunctionReturn(0); 2713e7870d2SPeter Brune } 2723e7870d2SPeter Brune 273d886c4f4SPeter Brune /*@ 274d886c4f4SPeter Brune DMDASetOffset - Sets the index offset of the DA. 275d886c4f4SPeter Brune 276d886c4f4SPeter Brune Collective on DA 277d886c4f4SPeter Brune 278d8d19677SJose E. Roman Input Parameters: 279d886c4f4SPeter Brune + da - The DMDA 280d886c4f4SPeter Brune . xo - The offset in the x direction 281d886c4f4SPeter Brune . yo - The offset in the y direction 282d886c4f4SPeter Brune - zo - The offset in the z direction 283d886c4f4SPeter Brune 284d886c4f4SPeter Brune Level: intermediate 285d886c4f4SPeter Brune 28695452b02SPatrick Sanan Notes: 28795452b02SPatrick Sanan This is used primarily to overlap a computation on a local DA with that on a global DA without 288d886c4f4SPeter Brune changing boundary conditions or subdomain features that depend upon the global offsets. 289d886c4f4SPeter Brune 290db781477SPatrick Sanan .seealso: `DMDAGetOffset()`, `DMDAVecGetArray()` 291d886c4f4SPeter Brune @*/ 29295c13181SPeter Brune PetscErrorCode DMDASetOffset(DM da, PetscInt xo, PetscInt yo, PetscInt zo, PetscInt Mo, PetscInt No, PetscInt Po) 293d886c4f4SPeter Brune { 294d886c4f4SPeter Brune DM_DA *dd = (DM_DA*)da->data; 295d886c4f4SPeter Brune 296d886c4f4SPeter Brune PetscFunctionBegin; 297a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 298d886c4f4SPeter Brune PetscValidLogicalCollectiveInt(da,xo,2); 29995c13181SPeter Brune PetscValidLogicalCollectiveInt(da,yo,3); 30095c13181SPeter Brune PetscValidLogicalCollectiveInt(da,zo,4); 30195c13181SPeter Brune PetscValidLogicalCollectiveInt(da,Mo,5); 30295c13181SPeter Brune PetscValidLogicalCollectiveInt(da,No,6); 30395c13181SPeter Brune PetscValidLogicalCollectiveInt(da,Po,7); 304d886c4f4SPeter Brune dd->xo = xo; 305d886c4f4SPeter Brune dd->yo = yo; 306d886c4f4SPeter Brune dd->zo = zo; 30795c13181SPeter Brune dd->Mo = Mo; 30895c13181SPeter Brune dd->No = No; 30995c13181SPeter Brune dd->Po = Po; 31095c13181SPeter Brune 31195c13181SPeter Brune if (da->coordinateDM) { 3129566063dSJacob Faibussowitsch PetscCall(DMDASetOffset(da->coordinateDM,xo,yo,zo,Mo,No,Po)); 31395c13181SPeter Brune } 314d886c4f4SPeter Brune PetscFunctionReturn(0); 315d886c4f4SPeter Brune } 316d886c4f4SPeter Brune 317d886c4f4SPeter Brune /*@ 318d886c4f4SPeter Brune DMDAGetOffset - Gets the index offset of the DA. 319d886c4f4SPeter Brune 320d886c4f4SPeter Brune Not collective 321d886c4f4SPeter Brune 322d886c4f4SPeter Brune Input Parameter: 323d886c4f4SPeter Brune . da - The DMDA 324d886c4f4SPeter Brune 325d886c4f4SPeter Brune Output Parameters: 326d886c4f4SPeter Brune + xo - The offset in the x direction 327d886c4f4SPeter Brune . yo - The offset in the y direction 32895c13181SPeter Brune . zo - The offset in the z direction 32995c13181SPeter Brune . Mo - The global size in the x direction 33095c13181SPeter Brune . No - The global size in the y direction 33195c13181SPeter Brune - Po - The global size in the z direction 332d886c4f4SPeter Brune 333d886c4f4SPeter Brune Level: intermediate 334d886c4f4SPeter Brune 335db781477SPatrick Sanan .seealso: `DMDASetOffset()`, `DMDAVecGetArray()` 336d886c4f4SPeter Brune @*/ 33795c13181SPeter Brune PetscErrorCode DMDAGetOffset(DM da,PetscInt *xo,PetscInt *yo,PetscInt *zo,PetscInt *Mo,PetscInt *No,PetscInt *Po) 338d886c4f4SPeter Brune { 339d886c4f4SPeter Brune DM_DA *dd = (DM_DA*)da->data; 340d886c4f4SPeter Brune 341d886c4f4SPeter Brune PetscFunctionBegin; 342a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 343d886c4f4SPeter Brune if (xo) *xo = dd->xo; 344d886c4f4SPeter Brune if (yo) *yo = dd->yo; 345d886c4f4SPeter Brune if (zo) *zo = dd->zo; 34695c13181SPeter Brune if (Mo) *Mo = dd->Mo; 34795c13181SPeter Brune if (No) *No = dd->No; 34895c13181SPeter Brune if (Po) *Po = dd->Po; 349d886c4f4SPeter Brune PetscFunctionReturn(0); 350d886c4f4SPeter Brune } 351d886c4f4SPeter Brune 35240234c92SPeter Brune /*@ 35340234c92SPeter Brune DMDAGetNonOverlappingRegion - Gets the indices of the nonoverlapping region of a subdomain DM. 35440234c92SPeter Brune 35540234c92SPeter Brune Not collective 35640234c92SPeter Brune 35740234c92SPeter Brune Input Parameter: 35840234c92SPeter Brune . da - The DMDA 35940234c92SPeter Brune 36040234c92SPeter Brune Output Parameters: 36140234c92SPeter Brune + xs - The start of the region in x 36240234c92SPeter Brune . ys - The start of the region in y 36340234c92SPeter Brune . zs - The start of the region in z 36440234c92SPeter Brune . xs - The size of the region in x 36540234c92SPeter Brune . ys - The size of the region in y 366a2b725a8SWilliam Gropp - zs - The size of the region in z 36740234c92SPeter Brune 36840234c92SPeter Brune Level: intermediate 36940234c92SPeter Brune 370db781477SPatrick Sanan .seealso: `DMDAGetOffset()`, `DMDAVecGetArray()` 37140234c92SPeter Brune @*/ 37240234c92SPeter Brune PetscErrorCode DMDAGetNonOverlappingRegion(DM da, PetscInt *xs, PetscInt *ys, PetscInt *zs, PetscInt *xm, PetscInt *ym, PetscInt *zm) 37340234c92SPeter Brune { 37440234c92SPeter Brune DM_DA *dd = (DM_DA*)da->data; 37540234c92SPeter Brune 37640234c92SPeter Brune PetscFunctionBegin; 377a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 37840234c92SPeter Brune if (xs) *xs = dd->nonxs; 37940234c92SPeter Brune if (ys) *ys = dd->nonys; 38040234c92SPeter Brune if (zs) *zs = dd->nonzs; 38140234c92SPeter Brune if (xm) *xm = dd->nonxm; 38240234c92SPeter Brune if (ym) *ym = dd->nonym; 38340234c92SPeter Brune if (zm) *zm = dd->nonzm; 38440234c92SPeter Brune PetscFunctionReturn(0); 38540234c92SPeter Brune } 38640234c92SPeter Brune 38740234c92SPeter Brune /*@ 38840234c92SPeter Brune DMDASetNonOverlappingRegion - Sets the indices of the nonoverlapping region of a subdomain DM. 38940234c92SPeter Brune 39040234c92SPeter Brune Collective on DA 39140234c92SPeter Brune 392d8d19677SJose E. Roman Input Parameters: 39340234c92SPeter Brune + da - The DMDA 39440234c92SPeter Brune . xs - The start of the region in x 39540234c92SPeter Brune . ys - The start of the region in y 39640234c92SPeter Brune . zs - The start of the region in z 39740234c92SPeter Brune . xs - The size of the region in x 39840234c92SPeter Brune . ys - The size of the region in y 399a2b725a8SWilliam Gropp - zs - The size of the region in z 40040234c92SPeter Brune 40140234c92SPeter Brune Level: intermediate 40240234c92SPeter Brune 403db781477SPatrick Sanan .seealso: `DMDAGetOffset()`, `DMDAVecGetArray()` 40440234c92SPeter Brune @*/ 40540234c92SPeter Brune PetscErrorCode DMDASetNonOverlappingRegion(DM da, PetscInt xs, PetscInt ys, PetscInt zs, PetscInt xm, PetscInt ym, PetscInt zm) 40640234c92SPeter Brune { 40740234c92SPeter Brune DM_DA *dd = (DM_DA*)da->data; 40840234c92SPeter Brune 40940234c92SPeter Brune PetscFunctionBegin; 410a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 41140234c92SPeter Brune PetscValidLogicalCollectiveInt(da,xs,2); 41240234c92SPeter Brune PetscValidLogicalCollectiveInt(da,ys,3); 41340234c92SPeter Brune PetscValidLogicalCollectiveInt(da,zs,4); 41440234c92SPeter Brune PetscValidLogicalCollectiveInt(da,xm,5); 41540234c92SPeter Brune PetscValidLogicalCollectiveInt(da,ym,6); 41640234c92SPeter Brune PetscValidLogicalCollectiveInt(da,zm,7); 41740234c92SPeter Brune dd->nonxs = xs; 41840234c92SPeter Brune dd->nonys = ys; 41940234c92SPeter Brune dd->nonzs = zs; 42040234c92SPeter Brune dd->nonxm = xm; 42140234c92SPeter Brune dd->nonym = ym; 42240234c92SPeter Brune dd->nonzm = zm; 42340234c92SPeter Brune 42440234c92SPeter Brune PetscFunctionReturn(0); 42540234c92SPeter Brune } 42688661749SPeter Brune 42747c6ae99SBarry Smith /*@ 428aa219208SBarry Smith DMDASetStencilType - Sets the type of the communication stencil 42947c6ae99SBarry Smith 430d083f849SBarry Smith Logically Collective on da 43147c6ae99SBarry Smith 432d8d19677SJose E. Roman Input Parameters: 433aa219208SBarry Smith + da - The DMDA 434aa219208SBarry Smith - stype - The stencil type, use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 43547c6ae99SBarry Smith 43647c6ae99SBarry Smith Level: intermediate 43747c6ae99SBarry Smith 438db781477SPatrick Sanan .seealso: `DMDACreate()`, `DMDestroy()`, `DMDA` 43947c6ae99SBarry Smith @*/ 4407087cfbeSBarry Smith PetscErrorCode DMDASetStencilType(DM da, DMDAStencilType stype) 44147c6ae99SBarry Smith { 44247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 44347c6ae99SBarry Smith 44447c6ae99SBarry Smith PetscFunctionBegin; 445a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 44647c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,stype,2); 4477a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 44847c6ae99SBarry Smith dd->stencil_type = stype; 44947c6ae99SBarry Smith PetscFunctionReturn(0); 45047c6ae99SBarry Smith } 45147c6ae99SBarry Smith 452fb6725baSMatthew G. Knepley /*@ 453fb6725baSMatthew G. Knepley DMDAGetStencilType - Gets the type of the communication stencil 454fb6725baSMatthew G. Knepley 455fb6725baSMatthew G. Knepley Not collective 456fb6725baSMatthew G. Knepley 457fb6725baSMatthew G. Knepley Input Parameter: 458fb6725baSMatthew G. Knepley . da - The DMDA 459fb6725baSMatthew G. Knepley 460fb6725baSMatthew G. Knepley Output Parameter: 461fb6725baSMatthew G. Knepley . stype - The stencil type, use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 462fb6725baSMatthew G. Knepley 463fb6725baSMatthew G. Knepley Level: intermediate 464fb6725baSMatthew G. Knepley 465db781477SPatrick Sanan .seealso: `DMDACreate()`, `DMDestroy()`, `DMDA` 466fb6725baSMatthew G. Knepley @*/ 467fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetStencilType(DM da, DMDAStencilType *stype) 468fb6725baSMatthew G. Knepley { 469fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA*)da->data; 470fb6725baSMatthew G. Knepley 471fb6725baSMatthew G. Knepley PetscFunctionBegin; 472a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 473fb6725baSMatthew G. Knepley PetscValidPointer(stype,2); 474fb6725baSMatthew G. Knepley *stype = dd->stencil_type; 475fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 476fb6725baSMatthew G. Knepley } 477fb6725baSMatthew G. Knepley 47847c6ae99SBarry Smith /*@ 479aa219208SBarry Smith DMDASetStencilWidth - Sets the width of the communication stencil 48047c6ae99SBarry Smith 481d083f849SBarry Smith Logically Collective on da 48247c6ae99SBarry Smith 483d8d19677SJose E. Roman Input Parameters: 484aa219208SBarry Smith + da - The DMDA 48547c6ae99SBarry Smith - width - The stencil width 48647c6ae99SBarry Smith 48747c6ae99SBarry Smith Level: intermediate 48847c6ae99SBarry Smith 489db781477SPatrick Sanan .seealso: `DMDACreate()`, `DMDestroy()`, `DMDA` 49047c6ae99SBarry Smith @*/ 4917087cfbeSBarry Smith PetscErrorCode DMDASetStencilWidth(DM da, PetscInt width) 49247c6ae99SBarry Smith { 49347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 49447c6ae99SBarry Smith 49547c6ae99SBarry Smith PetscFunctionBegin; 496a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 49747c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,width,2); 4987a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 49947c6ae99SBarry Smith dd->s = width; 50047c6ae99SBarry Smith PetscFunctionReturn(0); 50147c6ae99SBarry Smith } 50247c6ae99SBarry Smith 503fb6725baSMatthew G. Knepley /*@ 504fb6725baSMatthew G. Knepley DMDAGetStencilWidth - Gets the width of the communication stencil 505fb6725baSMatthew G. Knepley 506fb6725baSMatthew G. Knepley Not collective 507fb6725baSMatthew G. Knepley 508fb6725baSMatthew G. Knepley Input Parameter: 509fb6725baSMatthew G. Knepley . da - The DMDA 510fb6725baSMatthew G. Knepley 511fb6725baSMatthew G. Knepley Output Parameter: 512fb6725baSMatthew G. Knepley . width - The stencil width 513fb6725baSMatthew G. Knepley 514fb6725baSMatthew G. Knepley Level: intermediate 515fb6725baSMatthew G. Knepley 516db781477SPatrick Sanan .seealso: `DMDACreate()`, `DMDestroy()`, `DMDA` 517fb6725baSMatthew G. Knepley @*/ 518fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetStencilWidth(DM da, PetscInt *width) 519fb6725baSMatthew G. Knepley { 520fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *) da->data; 521fb6725baSMatthew G. Knepley 522fb6725baSMatthew G. Knepley PetscFunctionBegin; 523a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 524dadcf809SJacob Faibussowitsch PetscValidIntPointer(width,2); 525fb6725baSMatthew G. Knepley *width = dd->s; 526fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 527fb6725baSMatthew G. Knepley } 528fb6725baSMatthew G. Knepley 529aa219208SBarry Smith static PetscErrorCode DMDACheckOwnershipRanges_Private(DM da,PetscInt M,PetscInt m,const PetscInt lx[]) 53047c6ae99SBarry Smith { 53147c6ae99SBarry Smith PetscInt i,sum; 53247c6ae99SBarry Smith 53347c6ae99SBarry Smith PetscFunctionBegin; 5347a8be351SBarry Smith PetscCheck(M >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Global dimension not set"); 53547c6ae99SBarry Smith for (i=sum=0; i<m; i++) sum += lx[i]; 53663a3b9bcSJacob Faibussowitsch PetscCheck(sum == M,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"Ownership ranges sum to %" PetscInt_FMT " but global dimension is %" PetscInt_FMT,sum,M); 53747c6ae99SBarry Smith PetscFunctionReturn(0); 53847c6ae99SBarry Smith } 53947c6ae99SBarry Smith 54047c6ae99SBarry Smith /*@ 541aa219208SBarry Smith DMDASetOwnershipRanges - Sets the number of nodes in each direction on each process 54247c6ae99SBarry Smith 543d083f849SBarry Smith Logically Collective on da 54447c6ae99SBarry Smith 545d8d19677SJose E. Roman Input Parameters: 546aa219208SBarry Smith + da - The DMDA 5470298fd71SBarry Smith . lx - array containing number of nodes in the X direction on each process, or NULL. If non-null, must be of length da->m 5480298fd71SBarry Smith . ly - array containing number of nodes in the Y direction on each process, or NULL. If non-null, must be of length da->n 5490298fd71SBarry Smith - lz - array containing number of nodes in the Z direction on each process, or NULL. If non-null, must be of length da->p. 55047c6ae99SBarry Smith 55147c6ae99SBarry Smith Level: intermediate 55247c6ae99SBarry Smith 553e3f3e4b6SBarry Smith Note: these numbers are NOT multiplied by the number of dof per node. 554e3f3e4b6SBarry Smith 555db781477SPatrick Sanan .seealso: `DMDACreate()`, `DMDestroy()`, `DMDA` 55647c6ae99SBarry Smith @*/ 5577087cfbeSBarry Smith PetscErrorCode DMDASetOwnershipRanges(DM da, const PetscInt lx[], const PetscInt ly[], const PetscInt lz[]) 55847c6ae99SBarry Smith { 55947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 56047c6ae99SBarry Smith 56147c6ae99SBarry Smith PetscFunctionBegin; 562a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 5637a8be351SBarry Smith PetscCheck(!da->setupcalled,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 56447c6ae99SBarry Smith if (lx) { 5657a8be351SBarry Smith PetscCheck(dd->m >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 5669566063dSJacob Faibussowitsch PetscCall(DMDACheckOwnershipRanges_Private(da,dd->M,dd->m,lx)); 56747c6ae99SBarry Smith if (!dd->lx) { 5689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->m, &dd->lx)); 56947c6ae99SBarry Smith } 5709566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd->lx, lx, dd->m)); 57147c6ae99SBarry Smith } 57247c6ae99SBarry Smith if (ly) { 5737a8be351SBarry Smith PetscCheck(dd->n >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 5749566063dSJacob Faibussowitsch PetscCall(DMDACheckOwnershipRanges_Private(da,dd->N,dd->n,ly)); 57547c6ae99SBarry Smith if (!dd->ly) { 5769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->n, &dd->ly)); 57747c6ae99SBarry Smith } 5789566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd->ly, ly, dd->n)); 57947c6ae99SBarry Smith } 58047c6ae99SBarry Smith if (lz) { 5817a8be351SBarry Smith PetscCheck(dd->p >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 5829566063dSJacob Faibussowitsch PetscCall(DMDACheckOwnershipRanges_Private(da,dd->P,dd->p,lz)); 58347c6ae99SBarry Smith if (!dd->lz) { 5849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->p, &dd->lz)); 58547c6ae99SBarry Smith } 5869566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd->lz, lz, dd->p)); 58747c6ae99SBarry Smith } 58847c6ae99SBarry Smith PetscFunctionReturn(0); 58947c6ae99SBarry Smith } 59047c6ae99SBarry Smith 59147c6ae99SBarry Smith /*@ 592aa219208SBarry Smith DMDASetInterpolationType - Sets the type of interpolation that will be 593e727c939SJed Brown returned by DMCreateInterpolation() 59447c6ae99SBarry Smith 595d083f849SBarry Smith Logically Collective on da 59647c6ae99SBarry Smith 597d8d19677SJose E. Roman Input Parameters: 59847c6ae99SBarry Smith + da - initial distributed array 599a2b725a8SWilliam Gropp - ctype - DMDA_Q1 and DMDA_Q0 are currently the only supported forms 60047c6ae99SBarry Smith 60147c6ae99SBarry Smith Level: intermediate 60247c6ae99SBarry Smith 60395452b02SPatrick Sanan Notes: 60495452b02SPatrick Sanan you should call this on the coarser of the two DMDAs you pass to DMCreateInterpolation() 60547c6ae99SBarry Smith 606db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMDestroy()`, `DMDA`, `DMDAInterpolationType` 60747c6ae99SBarry Smith @*/ 6087087cfbeSBarry Smith PetscErrorCode DMDASetInterpolationType(DM da,DMDAInterpolationType ctype) 60947c6ae99SBarry Smith { 61047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 61147c6ae99SBarry Smith 61247c6ae99SBarry Smith PetscFunctionBegin; 613a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 61447c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,ctype,2); 61547c6ae99SBarry Smith dd->interptype = ctype; 61647c6ae99SBarry Smith PetscFunctionReturn(0); 61747c6ae99SBarry Smith } 61847c6ae99SBarry Smith 6192dde6fd4SLisandro Dalcin /*@ 6202dde6fd4SLisandro Dalcin DMDAGetInterpolationType - Gets the type of interpolation that will be 621e727c939SJed Brown used by DMCreateInterpolation() 6222dde6fd4SLisandro Dalcin 6232dde6fd4SLisandro Dalcin Not Collective 6242dde6fd4SLisandro Dalcin 6252dde6fd4SLisandro Dalcin Input Parameter: 6262dde6fd4SLisandro Dalcin . da - distributed array 6272dde6fd4SLisandro Dalcin 6282dde6fd4SLisandro Dalcin Output Parameter: 6292dde6fd4SLisandro Dalcin . ctype - interpolation type (DMDA_Q1 and DMDA_Q0 are currently the only supported forms) 6302dde6fd4SLisandro Dalcin 6312dde6fd4SLisandro Dalcin Level: intermediate 6322dde6fd4SLisandro Dalcin 633db781477SPatrick Sanan .seealso: `DMDA`, `DMDAInterpolationType`, `DMDASetInterpolationType()`, `DMCreateInterpolation()` 6342dde6fd4SLisandro Dalcin @*/ 6352dde6fd4SLisandro Dalcin PetscErrorCode DMDAGetInterpolationType(DM da,DMDAInterpolationType *ctype) 6362dde6fd4SLisandro Dalcin { 6372dde6fd4SLisandro Dalcin DM_DA *dd = (DM_DA*)da->data; 6382dde6fd4SLisandro Dalcin 6392dde6fd4SLisandro Dalcin PetscFunctionBegin; 640a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 6412dde6fd4SLisandro Dalcin PetscValidPointer(ctype,2); 6422dde6fd4SLisandro Dalcin *ctype = dd->interptype; 6432dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 6442dde6fd4SLisandro Dalcin } 64547c6ae99SBarry Smith 6466a119db4SBarry Smith /*@C 647aa219208SBarry Smith DMDAGetNeighbors - Gets an array containing the MPI rank of all the current 64847c6ae99SBarry Smith processes neighbors. 64947c6ae99SBarry Smith 65047c6ae99SBarry Smith Not Collective 65147c6ae99SBarry Smith 65247c6ae99SBarry Smith Input Parameter: 653aa219208SBarry Smith . da - the DMDA object 65447c6ae99SBarry Smith 65547c6ae99SBarry Smith Output Parameters: 65647c6ae99SBarry Smith . ranks - the neighbors ranks, stored with the x index increasing most rapidly. 65747c6ae99SBarry Smith this process itself is in the list 65847c6ae99SBarry Smith 65995452b02SPatrick Sanan Notes: 66095452b02SPatrick Sanan In 2d the array is of length 9, in 3d of length 27 66147c6ae99SBarry Smith Not supported in 1d 662aa219208SBarry Smith Do not free the array, it is freed when the DMDA is destroyed. 66347c6ae99SBarry Smith 66495452b02SPatrick Sanan Fortran Notes: 66595452b02SPatrick Sanan In fortran you must pass in an array of the appropriate length. 66647c6ae99SBarry Smith 66747c6ae99SBarry Smith Level: intermediate 66847c6ae99SBarry Smith 66947c6ae99SBarry Smith @*/ 6707087cfbeSBarry Smith PetscErrorCode DMDAGetNeighbors(DM da,const PetscMPIInt *ranks[]) 67147c6ae99SBarry Smith { 67247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 6735fd66863SKarl Rupp 67447c6ae99SBarry Smith PetscFunctionBegin; 675a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 67647c6ae99SBarry Smith *ranks = dd->neighbors; 67747c6ae99SBarry Smith PetscFunctionReturn(0); 67847c6ae99SBarry Smith } 67947c6ae99SBarry Smith 68047c6ae99SBarry Smith /*@C 681aa219208SBarry Smith DMDAGetOwnershipRanges - Gets the ranges of indices in the x, y and z direction that are owned by each process 68247c6ae99SBarry Smith 68347c6ae99SBarry Smith Not Collective 68447c6ae99SBarry Smith 68547c6ae99SBarry Smith Input Parameter: 686aa219208SBarry Smith . da - the DMDA object 68747c6ae99SBarry Smith 688d8d19677SJose E. Roman Output Parameters: 68947c6ae99SBarry Smith + lx - ownership along x direction (optional) 69047c6ae99SBarry Smith . ly - ownership along y direction (optional) 69147c6ae99SBarry Smith - lz - ownership along z direction (optional) 69247c6ae99SBarry Smith 69347c6ae99SBarry Smith Level: intermediate 69447c6ae99SBarry Smith 695aa219208SBarry Smith Note: these correspond to the optional final arguments passed to DMDACreate(), DMDACreate2d(), DMDACreate3d() 69647c6ae99SBarry Smith 69747c6ae99SBarry Smith In Fortran one must pass in arrays lx, ly, and lz that are long enough to hold the values; the sixth, seventh and 698aa219208SBarry Smith eighth arguments from DMDAGetInfo() 69947c6ae99SBarry Smith 70047c6ae99SBarry Smith In C you should not free these arrays, nor change the values in them. They will only have valid values while the 701aa219208SBarry Smith DMDA they came from still exists (has not been destroyed). 70247c6ae99SBarry Smith 703e3f3e4b6SBarry Smith These numbers are NOT multiplied by the number of dof per node. 704e3f3e4b6SBarry Smith 705db781477SPatrick Sanan .seealso: `DMDAGetCorners()`, `DMDAGetGhostCorners()`, `DMDACreate()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `VecGetOwnershipRanges()` 70647c6ae99SBarry Smith @*/ 7077087cfbeSBarry Smith PetscErrorCode DMDAGetOwnershipRanges(DM da,const PetscInt *lx[],const PetscInt *ly[],const PetscInt *lz[]) 70847c6ae99SBarry Smith { 70947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 71047c6ae99SBarry Smith 71147c6ae99SBarry Smith PetscFunctionBegin; 712a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 71347c6ae99SBarry Smith if (lx) *lx = dd->lx; 71447c6ae99SBarry Smith if (ly) *ly = dd->ly; 71547c6ae99SBarry Smith if (lz) *lz = dd->lz; 71647c6ae99SBarry Smith PetscFunctionReturn(0); 71747c6ae99SBarry Smith } 71847c6ae99SBarry Smith 71947c6ae99SBarry Smith /*@ 720aa219208SBarry Smith DMDASetRefinementFactor - Set the ratios that the DMDA grid is refined 72147c6ae99SBarry Smith 722d083f849SBarry Smith Logically Collective on da 72347c6ae99SBarry Smith 72447c6ae99SBarry Smith Input Parameters: 725aa219208SBarry Smith + da - the DMDA object 72647c6ae99SBarry Smith . refine_x - ratio of fine grid to coarse in x direction (2 by default) 72747c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 72847c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 72947c6ae99SBarry Smith 73047c6ae99SBarry Smith Options Database: 73148eeb7c8SBarry Smith + -da_refine_x refine_x - refinement ratio in x direction 73248eeb7c8SBarry Smith . -da_refine_y rafine_y - refinement ratio in y direction 73348eeb7c8SBarry Smith . -da_refine_z refine_z - refinement ratio in z direction 73448eeb7c8SBarry Smith - -da_refine <n> - refine the DMDA object n times when it is created. 73547c6ae99SBarry Smith 73647c6ae99SBarry Smith Level: intermediate 73747c6ae99SBarry Smith 73895452b02SPatrick Sanan Notes: 73995452b02SPatrick Sanan Pass PETSC_IGNORE to leave a value unchanged 74047c6ae99SBarry Smith 741db781477SPatrick Sanan .seealso: `DMRefine()`, `DMDAGetRefinementFactor()` 74247c6ae99SBarry Smith @*/ 7437087cfbeSBarry Smith PetscErrorCode DMDASetRefinementFactor(DM da, PetscInt refine_x, PetscInt refine_y,PetscInt refine_z) 74447c6ae99SBarry Smith { 74547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 74647c6ae99SBarry Smith 74747c6ae99SBarry Smith PetscFunctionBegin; 748a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 74947c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_x,2); 75047c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_y,3); 75147c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_z,4); 75247c6ae99SBarry Smith 75347c6ae99SBarry Smith if (refine_x > 0) dd->refine_x = refine_x; 75447c6ae99SBarry Smith if (refine_y > 0) dd->refine_y = refine_y; 75547c6ae99SBarry Smith if (refine_z > 0) dd->refine_z = refine_z; 75647c6ae99SBarry Smith PetscFunctionReturn(0); 75747c6ae99SBarry Smith } 75847c6ae99SBarry Smith 75947c6ae99SBarry Smith /*@C 760aa219208SBarry Smith DMDAGetRefinementFactor - Gets the ratios that the DMDA grid is refined 76147c6ae99SBarry Smith 76247c6ae99SBarry Smith Not Collective 76347c6ae99SBarry Smith 76447c6ae99SBarry Smith Input Parameter: 765aa219208SBarry Smith . da - the DMDA object 76647c6ae99SBarry Smith 76747c6ae99SBarry Smith Output Parameters: 76847c6ae99SBarry Smith + refine_x - ratio of fine grid to coarse in x direction (2 by default) 76947c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 77047c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 77147c6ae99SBarry Smith 77247c6ae99SBarry Smith Level: intermediate 77347c6ae99SBarry Smith 77495452b02SPatrick Sanan Notes: 77595452b02SPatrick Sanan Pass NULL for values you do not need 77647c6ae99SBarry Smith 777db781477SPatrick Sanan .seealso: `DMRefine()`, `DMDASetRefinementFactor()` 77847c6ae99SBarry Smith @*/ 7797087cfbeSBarry Smith PetscErrorCode DMDAGetRefinementFactor(DM da, PetscInt *refine_x, PetscInt *refine_y,PetscInt *refine_z) 78047c6ae99SBarry Smith { 78147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 78247c6ae99SBarry Smith 78347c6ae99SBarry Smith PetscFunctionBegin; 784a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 78547c6ae99SBarry Smith if (refine_x) *refine_x = dd->refine_x; 78647c6ae99SBarry Smith if (refine_y) *refine_y = dd->refine_y; 78747c6ae99SBarry Smith if (refine_z) *refine_z = dd->refine_z; 78847c6ae99SBarry Smith PetscFunctionReturn(0); 78947c6ae99SBarry Smith } 79047c6ae99SBarry Smith 79147c6ae99SBarry Smith /*@C 792aa219208SBarry Smith DMDASetGetMatrix - Sets the routine used by the DMDA to allocate a matrix. 79347c6ae99SBarry Smith 794d083f849SBarry Smith Logically Collective on da 79547c6ae99SBarry Smith 79647c6ae99SBarry Smith Input Parameters: 797aa219208SBarry Smith + da - the DMDA object 798aa219208SBarry Smith - f - the function that allocates the matrix for that specific DMDA 79947c6ae99SBarry Smith 80047c6ae99SBarry Smith Level: developer 80147c6ae99SBarry Smith 80295452b02SPatrick Sanan Notes: 80395452b02SPatrick Sanan See DMDASetBlockFills() that provides a simple way to provide the nonzero structure for 80447c6ae99SBarry Smith the diagonal and off-diagonal blocks of the matrix 80547c6ae99SBarry Smith 8061fd49c25SBarry Smith Not supported from Fortran 8071fd49c25SBarry Smith 808db781477SPatrick Sanan .seealso: `DMCreateMatrix()`, `DMDASetBlockFills()` 80947c6ae99SBarry Smith @*/ 810b412c318SBarry Smith PetscErrorCode DMDASetGetMatrix(DM da,PetscErrorCode (*f)(DM, Mat*)) 81147c6ae99SBarry Smith { 81247c6ae99SBarry Smith PetscFunctionBegin; 813a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 81425296bd5SBarry Smith da->ops->creatematrix = f; 81547c6ae99SBarry Smith PetscFunctionReturn(0); 81647c6ae99SBarry Smith } 81747c6ae99SBarry Smith 81838fb4e8eSJunchao Zhang /*@ 81938fb4e8eSJunchao Zhang DMDAMapMatStencilToGlobal - Map a list of MatStencils on a grid to global indices. 82038fb4e8eSJunchao Zhang 82138fb4e8eSJunchao Zhang Not Collective 82238fb4e8eSJunchao Zhang 82338fb4e8eSJunchao Zhang Input Parameters: 82438fb4e8eSJunchao Zhang + da - the DMDA object 82538fb4e8eSJunchao Zhang . m - number of MatStencils 82638fb4e8eSJunchao Zhang - idxm - grid points (and component number when dof > 1) 82738fb4e8eSJunchao Zhang 82838fb4e8eSJunchao Zhang Output Parameters: 82938fb4e8eSJunchao Zhang + gidxm - global row indices 83038fb4e8eSJunchao Zhang 83138fb4e8eSJunchao Zhang .seealso: `MatStencil` 83238fb4e8eSJunchao Zhang @*/ 83338fb4e8eSJunchao Zhang PetscErrorCode DMDAMapMatStencilToGlobal(DM da,PetscInt m,const MatStencil idxm[],PetscInt gidxm[]) 83438fb4e8eSJunchao Zhang { 83538fb4e8eSJunchao Zhang const DM_DA *dd = (const DM_DA*)da->data; 83638fb4e8eSJunchao Zhang const PetscInt *dxm = (const PetscInt*)idxm; 83738fb4e8eSJunchao Zhang PetscInt i,j,sdim,tmp,dim; 83838fb4e8eSJunchao Zhang PetscInt dims[4],starts[4],dims2[3],starts2[3],dof = dd->w; 83938fb4e8eSJunchao Zhang ISLocalToGlobalMapping ltog; 84038fb4e8eSJunchao Zhang 84138fb4e8eSJunchao Zhang PetscFunctionBegin; 84238fb4e8eSJunchao Zhang if (m <= 0) PetscFunctionReturn(0); 84338fb4e8eSJunchao Zhang dim = da->dim; /* DA dim: 1 to 3 */ 84438fb4e8eSJunchao Zhang sdim = dim + (dof > 1? 1 : 0); /* Dimension in MatStencil's (k,j,i,c) view */ 84538fb4e8eSJunchao Zhang 84638fb4e8eSJunchao Zhang starts2[0] = dd->Xs/dof + dd->xo; 84738fb4e8eSJunchao Zhang starts2[1] = dd->Ys + dd->yo; 84838fb4e8eSJunchao Zhang starts2[2] = dd->Zs + dd->zo; 84938fb4e8eSJunchao Zhang dims2[0] = (dd->Xe - dd->Xs)/dof; 85038fb4e8eSJunchao Zhang dims2[1] = (dd->Ye - dd->Ys); 85138fb4e8eSJunchao Zhang dims2[2] = (dd->Ze - dd->Zs); 85238fb4e8eSJunchao Zhang 85338fb4e8eSJunchao Zhang for (i=0; i<dim; i++) { 85438fb4e8eSJunchao Zhang dims[i] = dims2[dim-i-1]; /* copy the values in backwards */ 85538fb4e8eSJunchao Zhang starts[i] = starts2[dim-i-1]; 85638fb4e8eSJunchao Zhang } 85738fb4e8eSJunchao Zhang starts[dim] = 0; 85838fb4e8eSJunchao Zhang dims[dim] = dof; 85938fb4e8eSJunchao Zhang 86038fb4e8eSJunchao Zhang /* Map stencils to local indices (code adapted from MatSetValuesStencil()) */ 86138fb4e8eSJunchao Zhang for (i=0; i<m; i++) { 86238fb4e8eSJunchao Zhang for (j=0; j<3-dim; j++) dxm++; /* dxm[] is in k,j,i,c order; move to the first significant index */ 86338fb4e8eSJunchao Zhang tmp = *dxm++ - starts[0]; 86438fb4e8eSJunchao Zhang for (j=0; j<sdim-1; j++) { 86538fb4e8eSJunchao Zhang if (tmp < 0 || (*dxm - starts[j+1]) < 0) tmp = -1; /* Beyond the ghost region, therefore ignored with negative indices */ 86638fb4e8eSJunchao Zhang else tmp = tmp*dims[j] + (*dxm - starts[j+1]); 86738fb4e8eSJunchao Zhang dxm++; 86838fb4e8eSJunchao Zhang } 86938fb4e8eSJunchao Zhang if (dof == 1) dxm++; /* If no dof, skip the unused c */ 87038fb4e8eSJunchao Zhang gidxm[i] = tmp; 87138fb4e8eSJunchao Zhang } 87238fb4e8eSJunchao Zhang 87338fb4e8eSJunchao Zhang /* Map local indices to global indices */ 87438fb4e8eSJunchao Zhang PetscCall(DMGetLocalToGlobalMapping(da,<og)); 87538fb4e8eSJunchao Zhang PetscCall(ISLocalToGlobalMappingApply(ltog,m,gidxm,gidxm)); 87638fb4e8eSJunchao Zhang PetscFunctionReturn(0); 87738fb4e8eSJunchao Zhang } 87838fb4e8eSJunchao Zhang 87947c6ae99SBarry Smith /* 88047c6ae99SBarry Smith Creates "balanced" ownership ranges after refinement, constrained by the need for the 88147c6ae99SBarry Smith fine grid boundaries to fall within one stencil width of the coarse partition. 88247c6ae99SBarry Smith 88347c6ae99SBarry Smith Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 88447c6ae99SBarry Smith */ 88594013140SBarry Smith static PetscErrorCode DMDARefineOwnershipRanges(DM da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lc[],PetscInt lf[]) 88647c6ae99SBarry Smith { 88747c6ae99SBarry Smith PetscInt i,totalc = 0,remaining,startc = 0,startf = 0; 88847c6ae99SBarry Smith 88947c6ae99SBarry Smith PetscFunctionBegin; 89063a3b9bcSJacob Faibussowitsch PetscCheck(ratio >= 1,PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Requested refinement ratio %" PetscInt_FMT " must be at least 1",ratio); 89147c6ae99SBarry Smith if (ratio == 1) { 8929566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(lf,lc,m)); 89347c6ae99SBarry Smith PetscFunctionReturn(0); 89447c6ae99SBarry Smith } 89547c6ae99SBarry Smith for (i=0; i<m; i++) totalc += lc[i]; 89647c6ae99SBarry Smith remaining = (!periodic) + ratio * (totalc - (!periodic)); 89747c6ae99SBarry Smith for (i=0; i<m; i++) { 89847c6ae99SBarry Smith PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 89947c6ae99SBarry Smith if (i == m-1) lf[i] = want; 90047c6ae99SBarry Smith else { 9017aca7175SJed Brown const PetscInt nextc = startc + lc[i]; 9027aca7175SJed Brown /* Move the first fine node of the next subdomain to the right until the coarse node on its left is within one 9037aca7175SJed Brown * coarse stencil width of the first coarse node in the next subdomain. */ 9047aca7175SJed Brown while ((startf+want)/ratio < nextc - stencil_width) want++; 9057aca7175SJed Brown /* Move the last fine node in the current subdomain to the left until the coarse node on its right is within one 9067aca7175SJed Brown * coarse stencil width of the last coarse node in the current subdomain. */ 9077aca7175SJed Brown while ((startf+want-1+ratio-1)/ratio > nextc-1+stencil_width) want--; 9087aca7175SJed Brown /* Make sure all constraints are satisfied */ 90930729d88SBarry Smith if (want < 0 || want > remaining || ((startf+want)/ratio < nextc - stencil_width) 910ce94432eSBarry Smith || ((startf+want-1+ratio-1)/ratio > nextc-1+stencil_width)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Could not find a compatible refined ownership range"); 91147c6ae99SBarry Smith } 91247c6ae99SBarry Smith lf[i] = want; 91347c6ae99SBarry Smith startc += lc[i]; 91447c6ae99SBarry Smith startf += lf[i]; 91547c6ae99SBarry Smith remaining -= lf[i]; 91647c6ae99SBarry Smith } 91747c6ae99SBarry Smith PetscFunctionReturn(0); 91847c6ae99SBarry Smith } 91947c6ae99SBarry Smith 9202be375d4SJed Brown /* 9212be375d4SJed Brown Creates "balanced" ownership ranges after coarsening, constrained by the need for the 9222be375d4SJed Brown fine grid boundaries to fall within one stencil width of the coarse partition. 9232be375d4SJed Brown 9242be375d4SJed Brown Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 9252be375d4SJed Brown */ 9262be375d4SJed Brown static PetscErrorCode DMDACoarsenOwnershipRanges(DM da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lf[],PetscInt lc[]) 9272be375d4SJed Brown { 9282be375d4SJed Brown PetscInt i,totalf,remaining,startc,startf; 9292be375d4SJed Brown 9302be375d4SJed Brown PetscFunctionBegin; 93163a3b9bcSJacob Faibussowitsch PetscCheck(ratio >= 1,PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Requested refinement ratio %" PetscInt_FMT " must be at least 1",ratio); 9322be375d4SJed Brown if (ratio == 1) { 9339566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(lc,lf,m)); 9342be375d4SJed Brown PetscFunctionReturn(0); 9352be375d4SJed Brown } 9362be375d4SJed Brown for (i=0,totalf=0; i<m; i++) totalf += lf[i]; 9372be375d4SJed Brown remaining = (!periodic) + (totalf - (!periodic)) / ratio; 9382be375d4SJed Brown for (i=0,startc=0,startf=0; i<m; i++) { 9392be375d4SJed Brown PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 9402be375d4SJed Brown if (i == m-1) lc[i] = want; 9412be375d4SJed Brown else { 9422be375d4SJed Brown const PetscInt nextf = startf+lf[i]; 9432be375d4SJed Brown /* Slide first coarse node of next subdomain to the left until the coarse node to the left of the first fine 9442be375d4SJed Brown * node is within one stencil width. */ 9452be375d4SJed Brown while (nextf/ratio < startc+want-stencil_width) want--; 9462be375d4SJed Brown /* Slide the last coarse node of the current subdomain to the right until the coarse node to the right of the last 9472be375d4SJed Brown * fine node is within one stencil width. */ 9482be375d4SJed Brown while ((nextf-1+ratio-1)/ratio > startc+want-1+stencil_width) want++; 9492be375d4SJed Brown if (want < 0 || want > remaining 950ce94432eSBarry Smith || (nextf/ratio < startc+want-stencil_width) || ((nextf-1+ratio-1)/ratio > startc+want-1+stencil_width)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Could not find a compatible coarsened ownership range"); 9512be375d4SJed Brown } 9522be375d4SJed Brown lc[i] = want; 9532be375d4SJed Brown startc += lc[i]; 9542be375d4SJed Brown startf += lf[i]; 9552be375d4SJed Brown remaining -= lc[i]; 9562be375d4SJed Brown } 9572be375d4SJed Brown PetscFunctionReturn(0); 9582be375d4SJed Brown } 9592be375d4SJed Brown 9607087cfbeSBarry Smith PetscErrorCode DMRefine_DA(DM da,MPI_Comm comm,DM *daref) 96147c6ae99SBarry Smith { 962c73cfb54SMatthew G. Knepley PetscInt M,N,P,i,dim; 9639a42bb27SBarry Smith DM da2; 96447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 96547c6ae99SBarry Smith 96647c6ae99SBarry Smith PetscFunctionBegin; 967a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 96847c6ae99SBarry Smith PetscValidPointer(daref,3); 96947c6ae99SBarry Smith 9709566063dSJacob Faibussowitsch PetscCall(DMGetDimension(da, &dim)); 971bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 97247c6ae99SBarry Smith M = dd->refine_x*dd->M; 97347c6ae99SBarry Smith } else { 97447c6ae99SBarry Smith M = 1 + dd->refine_x*(dd->M - 1); 97547c6ae99SBarry Smith } 976bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 977c73cfb54SMatthew G. Knepley if (dim > 1) { 97847c6ae99SBarry Smith N = dd->refine_y*dd->N; 97947c6ae99SBarry Smith } else { 9801860e6e9SBarry Smith N = 1; 9811860e6e9SBarry Smith } 9821860e6e9SBarry Smith } else { 98347c6ae99SBarry Smith N = 1 + dd->refine_y*(dd->N - 1); 98447c6ae99SBarry Smith } 985bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 986c73cfb54SMatthew G. Knepley if (dim > 2) { 98747c6ae99SBarry Smith P = dd->refine_z*dd->P; 98847c6ae99SBarry Smith } else { 9891860e6e9SBarry Smith P = 1; 9901860e6e9SBarry Smith } 9911860e6e9SBarry Smith } else { 99247c6ae99SBarry Smith P = 1 + dd->refine_z*(dd->P - 1); 99347c6ae99SBarry Smith } 9949566063dSJacob Faibussowitsch PetscCall(DMDACreate(PetscObjectComm((PetscObject)da),&da2)); 9959566063dSJacob Faibussowitsch PetscCall(DMSetOptionsPrefix(da2,((PetscObject)da)->prefix)); 9969566063dSJacob Faibussowitsch PetscCall(DMSetDimension(da2,dim)); 9979566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(da2,M,N,P)); 9989566063dSJacob Faibussowitsch PetscCall(DMDASetNumProcs(da2,dd->m,dd->n,dd->p)); 9999566063dSJacob Faibussowitsch PetscCall(DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz)); 10009566063dSJacob Faibussowitsch PetscCall(DMDASetDof(da2,dd->w)); 10019566063dSJacob Faibussowitsch PetscCall(DMDASetStencilType(da2,dd->stencil_type)); 10029566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(da2,dd->s)); 1003c73cfb54SMatthew G. Knepley if (dim == 3) { 100447c6ae99SBarry Smith PetscInt *lx,*ly,*lz; 10059566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz)); 10069566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx)); 10079566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly)); 10089566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da,(PetscBool)(dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_z,dd->p,dd->lz,lz)); 10099566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(da2,lx,ly,lz)); 10109566063dSJacob Faibussowitsch PetscCall(PetscFree3(lx,ly,lz)); 1011c73cfb54SMatthew G. Knepley } else if (dim == 2) { 101247c6ae99SBarry Smith PetscInt *lx,*ly; 10139566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(dd->m,&lx,dd->n,&ly)); 10149566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx)); 10159566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly)); 10169566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(da2,lx,ly,NULL)); 10179566063dSJacob Faibussowitsch PetscCall(PetscFree2(lx,ly)); 1018c73cfb54SMatthew G. Knepley } else if (dim == 1) { 101947c6ae99SBarry Smith PetscInt *lx; 10209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->m,&lx)); 10219566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx)); 10229566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(da2,lx,NULL,NULL)); 10239566063dSJacob Faibussowitsch PetscCall(PetscFree(lx)); 102447c6ae99SBarry Smith } 102547c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 102647c6ae99SBarry Smith 102747c6ae99SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 102825296bd5SBarry Smith da2->ops->creatematrix = da->ops->creatematrix; 102925296bd5SBarry Smith /* da2->ops->createinterpolation = da->ops->createinterpolation; this causes problem with SNESVI */ 103047c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 103147c6ae99SBarry Smith dd2->interptype = dd->interptype; 103247c6ae99SBarry Smith 103347c6ae99SBarry Smith /* copy fill information if given */ 103447c6ae99SBarry Smith if (dd->dfill) { 10359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->dfill[dd->w]+dd->w+1,&dd2->dfill)); 10369566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->dfill,dd->dfill,dd->dfill[dd->w]+dd->w+1)); 103747c6ae99SBarry Smith } 103847c6ae99SBarry Smith if (dd->ofill) { 10399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->ofill[dd->w]+dd->w+1,&dd2->ofill)); 10409566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->ofill,dd->ofill,dd->ofill[dd->w]+dd->w+1)); 104147c6ae99SBarry Smith } 104247c6ae99SBarry Smith /* copy the refine information */ 1043397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->refine_x; 1044397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->refine_y; 1045397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->refine_z; 104647c6ae99SBarry Smith 1047897f7067SBarry Smith if (dd->refine_z_hier) { 1048897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_z_hier_n) { 1049897f7067SBarry Smith dd2->refine_z = dd->refine_z_hier[da->levelup - da->leveldown + 1]; 1050897f7067SBarry Smith } 1051897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_z_hier_n) { 1052897f7067SBarry Smith dd2->coarsen_z = dd->refine_z_hier[da->levelup - da->leveldown]; 1053897f7067SBarry Smith } 1054897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 10559566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_z_hier_n,&dd2->refine_z_hier)); 10569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_z_hier,dd->refine_z_hier,dd2->refine_z_hier_n)); 1057897f7067SBarry Smith } 1058897f7067SBarry Smith if (dd->refine_y_hier) { 1059897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_y_hier_n) { 1060897f7067SBarry Smith dd2->refine_y = dd->refine_y_hier[da->levelup - da->leveldown + 1]; 1061897f7067SBarry Smith } 1062897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_y_hier_n) { 1063897f7067SBarry Smith dd2->coarsen_y = dd->refine_y_hier[da->levelup - da->leveldown]; 1064897f7067SBarry Smith } 1065897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 10669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_y_hier_n,&dd2->refine_y_hier)); 10679566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_y_hier,dd->refine_y_hier,dd2->refine_y_hier_n)); 1068897f7067SBarry Smith } 1069897f7067SBarry Smith if (dd->refine_x_hier) { 1070897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_x_hier_n) { 1071897f7067SBarry Smith dd2->refine_x = dd->refine_x_hier[da->levelup - da->leveldown + 1]; 1072897f7067SBarry Smith } 1073897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_x_hier_n) { 1074897f7067SBarry Smith dd2->coarsen_x = dd->refine_x_hier[da->levelup - da->leveldown]; 1075897f7067SBarry Smith } 1076897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 10779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_x_hier_n,&dd2->refine_x_hier)); 10789566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_x_hier,dd->refine_x_hier,dd2->refine_x_hier_n)); 1079897f7067SBarry Smith } 1080897f7067SBarry Smith 108147c6ae99SBarry Smith /* copy vector type information */ 10829566063dSJacob Faibussowitsch PetscCall(DMSetVecType(da2,da->vectype)); 1083ddcf8b74SDave May 1084efd51863SBarry Smith dd2->lf = dd->lf; 1085efd51863SBarry Smith dd2->lj = dd->lj; 1086efd51863SBarry Smith 10876e87535bSJed Brown da2->leveldown = da->leveldown; 10886e87535bSJed Brown da2->levelup = da->levelup + 1; 10898865f1eaSKarl Rupp 10909566063dSJacob Faibussowitsch PetscCall(DMSetUp(da2)); 10916e87535bSJed Brown 1092ddcf8b74SDave May /* interpolate coordinates if they are set on the coarse grid */ 10936636e97aSMatthew G Knepley if (da->coordinates) { 1094ddcf8b74SDave May DM cdaf,cdac; 1095ddcf8b74SDave May Vec coordsc,coordsf; 1096ddcf8b74SDave May Mat II; 1097ddcf8b74SDave May 10989566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(da,&cdac)); 10999566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(da,&coordsc)); 11009566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(da2,&cdaf)); 1101b61d3410SDave May /* force creation of the coordinate vector */ 11029566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0)); 11039566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(da2,&coordsf)); 11049566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(cdac,cdaf,&II,NULL)); 11059566063dSJacob Faibussowitsch PetscCall(MatInterpolate(II,coordsc,coordsf)); 11069566063dSJacob Faibussowitsch PetscCall(MatDestroy(&II)); 1107ddcf8b74SDave May } 1108397b6216SJed Brown 1109f3141302SJed Brown for (i=0; i<da->bs; i++) { 1110f3141302SJed Brown const char *fieldname; 11119566063dSJacob Faibussowitsch PetscCall(DMDAGetFieldName(da,i,&fieldname)); 11129566063dSJacob Faibussowitsch PetscCall(DMDASetFieldName(da2,i,fieldname)); 1113f3141302SJed Brown } 1114397b6216SJed Brown 111547c6ae99SBarry Smith *daref = da2; 111647c6ae99SBarry Smith PetscFunctionReturn(0); 111747c6ae99SBarry Smith } 111847c6ae99SBarry Smith 1119a5bc1bf3SBarry Smith PetscErrorCode DMCoarsen_DA(DM dmf, MPI_Comm comm,DM *dmc) 112047c6ae99SBarry Smith { 1121c73cfb54SMatthew G. Knepley PetscInt M,N,P,i,dim; 1122a5bc1bf3SBarry Smith DM dmc2; 1123a5bc1bf3SBarry Smith DM_DA *dd = (DM_DA*)dmf->data,*dd2; 112447c6ae99SBarry Smith 112547c6ae99SBarry Smith PetscFunctionBegin; 1126a5bc1bf3SBarry Smith PetscValidHeaderSpecificType(dmf,DM_CLASSID,1,DMDA); 1127a5bc1bf3SBarry Smith PetscValidPointer(dmc,3); 112847c6ae99SBarry Smith 11299566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dmf, &dim)); 1130bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1131397b6216SJed Brown M = dd->M / dd->coarsen_x; 113247c6ae99SBarry Smith } else { 1133397b6216SJed Brown M = 1 + (dd->M - 1) / dd->coarsen_x; 113447c6ae99SBarry Smith } 1135bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1136c73cfb54SMatthew G. Knepley if (dim > 1) { 1137397b6216SJed Brown N = dd->N / dd->coarsen_y; 113847c6ae99SBarry Smith } else { 11391860e6e9SBarry Smith N = 1; 11401860e6e9SBarry Smith } 11411860e6e9SBarry Smith } else { 1142397b6216SJed Brown N = 1 + (dd->N - 1) / dd->coarsen_y; 114347c6ae99SBarry Smith } 1144bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1145c73cfb54SMatthew G. Knepley if (dim > 2) { 1146397b6216SJed Brown P = dd->P / dd->coarsen_z; 114747c6ae99SBarry Smith } else { 11481860e6e9SBarry Smith P = 1; 11491860e6e9SBarry Smith } 11501860e6e9SBarry Smith } else { 1151397b6216SJed Brown P = 1 + (dd->P - 1) / dd->coarsen_z; 115247c6ae99SBarry Smith } 11539566063dSJacob Faibussowitsch PetscCall(DMDACreate(PetscObjectComm((PetscObject)dmf),&dmc2)); 11549566063dSJacob Faibussowitsch PetscCall(DMSetOptionsPrefix(dmc2,((PetscObject)dmf)->prefix)); 11559566063dSJacob Faibussowitsch PetscCall(DMSetDimension(dmc2,dim)); 11569566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(dmc2,M,N,P)); 11579566063dSJacob Faibussowitsch PetscCall(DMDASetNumProcs(dmc2,dd->m,dd->n,dd->p)); 11589566063dSJacob Faibussowitsch PetscCall(DMDASetBoundaryType(dmc2,dd->bx,dd->by,dd->bz)); 11599566063dSJacob Faibussowitsch PetscCall(DMDASetDof(dmc2,dd->w)); 11609566063dSJacob Faibussowitsch PetscCall(DMDASetStencilType(dmc2,dd->stencil_type)); 11619566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(dmc2,dd->s)); 1162c73cfb54SMatthew G. Knepley if (dim == 3) { 11632be375d4SJed Brown PetscInt *lx,*ly,*lz; 11649566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz)); 11659566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx)); 11669566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_y,dd->n,dd->ly,ly)); 11679566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf,(PetscBool)(dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_z,dd->p,dd->lz,lz)); 11689566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(dmc2,lx,ly,lz)); 11699566063dSJacob Faibussowitsch PetscCall(PetscFree3(lx,ly,lz)); 1170c73cfb54SMatthew G. Knepley } else if (dim == 2) { 11712be375d4SJed Brown PetscInt *lx,*ly; 11729566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(dd->m,&lx,dd->n,&ly)); 11739566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx)); 11749566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_y,dd->n,dd->ly,ly)); 11759566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(dmc2,lx,ly,NULL)); 11769566063dSJacob Faibussowitsch PetscCall(PetscFree2(lx,ly)); 1177c73cfb54SMatthew G. Knepley } else if (dim == 1) { 11782be375d4SJed Brown PetscInt *lx; 11799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->m,&lx)); 11809566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx)); 11819566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(dmc2,lx,NULL,NULL)); 11829566063dSJacob Faibussowitsch PetscCall(PetscFree(lx)); 118347c6ae99SBarry Smith } 1184a5bc1bf3SBarry Smith dd2 = (DM_DA*)dmc2->data; 118547c6ae99SBarry Smith 11864dcab191SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones; why are only some inherited and not all? */ 1187a5bc1bf3SBarry Smith /* dmc2->ops->createinterpolation = dmf->ops->createinterpolation; copying this one causes trouble for DMSetVI */ 1188a5bc1bf3SBarry Smith dmc2->ops->creatematrix = dmf->ops->creatematrix; 1189a5bc1bf3SBarry Smith dmc2->ops->getcoloring = dmf->ops->getcoloring; 119047c6ae99SBarry Smith dd2->interptype = dd->interptype; 119147c6ae99SBarry Smith 119247c6ae99SBarry Smith /* copy fill information if given */ 119347c6ae99SBarry Smith if (dd->dfill) { 11949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->dfill[dd->w]+dd->w+1,&dd2->dfill)); 11959566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->dfill,dd->dfill,dd->dfill[dd->w]+dd->w+1)); 119647c6ae99SBarry Smith } 119747c6ae99SBarry Smith if (dd->ofill) { 11989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->ofill[dd->w]+dd->w+1,&dd2->ofill)); 11999566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->ofill,dd->ofill,dd->ofill[dd->w]+dd->w+1)); 120047c6ae99SBarry Smith } 120147c6ae99SBarry Smith /* copy the refine information */ 1202397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->coarsen_x; 1203397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->coarsen_y; 1204397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->coarsen_z; 120547c6ae99SBarry Smith 1206897f7067SBarry Smith if (dd->refine_z_hier) { 1207a5bc1bf3SBarry Smith if (dmf->levelup - dmf->leveldown -1 > -1 && dmf->levelup - dmf->leveldown - 1< dd->refine_z_hier_n) { 1208a5bc1bf3SBarry Smith dd2->refine_z = dd->refine_z_hier[dmf->levelup - dmf->leveldown - 1]; 1209897f7067SBarry Smith } 1210a5bc1bf3SBarry Smith if (dmf->levelup - dmf->leveldown - 2 > -1 && dmf->levelup - dmf->leveldown - 2 < dd->refine_z_hier_n) { 1211a5bc1bf3SBarry Smith dd2->coarsen_z = dd->refine_z_hier[dmf->levelup - dmf->leveldown - 2]; 1212897f7067SBarry Smith } 1213897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 12149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_z_hier_n,&dd2->refine_z_hier)); 12159566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_z_hier,dd->refine_z_hier,dd2->refine_z_hier_n)); 1216897f7067SBarry Smith } 1217897f7067SBarry Smith if (dd->refine_y_hier) { 1218a5bc1bf3SBarry Smith if (dmf->levelup - dmf->leveldown - 1 > -1 && dmf->levelup - dmf->leveldown - 1< dd->refine_y_hier_n) { 1219a5bc1bf3SBarry Smith dd2->refine_y = dd->refine_y_hier[dmf->levelup - dmf->leveldown - 1]; 1220897f7067SBarry Smith } 1221a5bc1bf3SBarry Smith if (dmf->levelup - dmf->leveldown - 2 > -1 && dmf->levelup - dmf->leveldown - 2 < dd->refine_y_hier_n) { 1222a5bc1bf3SBarry Smith dd2->coarsen_y = dd->refine_y_hier[dmf->levelup - dmf->leveldown - 2]; 1223897f7067SBarry Smith } 1224897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 12259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_y_hier_n,&dd2->refine_y_hier)); 12269566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_y_hier,dd->refine_y_hier,dd2->refine_y_hier_n)); 1227897f7067SBarry Smith } 1228897f7067SBarry Smith if (dd->refine_x_hier) { 1229a5bc1bf3SBarry Smith if (dmf->levelup - dmf->leveldown - 1 > -1 && dmf->levelup - dmf->leveldown - 1 < dd->refine_x_hier_n) { 1230a5bc1bf3SBarry Smith dd2->refine_x = dd->refine_x_hier[dmf->levelup - dmf->leveldown - 1]; 1231897f7067SBarry Smith } 1232a5bc1bf3SBarry Smith if (dmf->levelup - dmf->leveldown - 2 > -1 && dmf->levelup - dmf->leveldown - 2 < dd->refine_x_hier_n) { 1233a5bc1bf3SBarry Smith dd2->coarsen_x = dd->refine_x_hier[dmf->levelup - dmf->leveldown - 2]; 1234897f7067SBarry Smith } 1235897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 12369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_x_hier_n,&dd2->refine_x_hier)); 12379566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_x_hier,dd->refine_x_hier,dd2->refine_x_hier_n)); 1238897f7067SBarry Smith } 1239897f7067SBarry Smith 124047c6ae99SBarry Smith /* copy vector type information */ 12419566063dSJacob Faibussowitsch PetscCall(DMSetVecType(dmc2,dmf->vectype)); 124247c6ae99SBarry Smith 1243644e2e5bSBarry Smith dd2->lf = dd->lf; 1244644e2e5bSBarry Smith dd2->lj = dd->lj; 1245644e2e5bSBarry Smith 1246a5bc1bf3SBarry Smith dmc2->leveldown = dmf->leveldown + 1; 1247a5bc1bf3SBarry Smith dmc2->levelup = dmf->levelup; 12488865f1eaSKarl Rupp 12499566063dSJacob Faibussowitsch PetscCall(DMSetUp(dmc2)); 12506e87535bSJed Brown 1251ddcf8b74SDave May /* inject coordinates if they are set on the fine grid */ 1252a5bc1bf3SBarry Smith if (dmf->coordinates) { 1253ddcf8b74SDave May DM cdaf,cdac; 1254ddcf8b74SDave May Vec coordsc,coordsf; 12556dbf9973SLawrence Mitchell Mat inject; 12566dbf9973SLawrence Mitchell VecScatter vscat; 1257ddcf8b74SDave May 12589566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dmf,&cdaf)); 12599566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dmf,&coordsf)); 12609566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dmc2,&cdac)); 1261b61d3410SDave May /* force creation of the coordinate vector */ 12629566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(dmc2,0.0,1.0,0.0,1.0,0.0,1.0)); 12639566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dmc2,&coordsc)); 1264ddcf8b74SDave May 12659566063dSJacob Faibussowitsch PetscCall(DMCreateInjection(cdac,cdaf,&inject)); 12669566063dSJacob Faibussowitsch PetscCall(MatScatterGetVecScatter(inject,&vscat)); 12679566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD)); 12689566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD)); 12699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&inject)); 1270ddcf8b74SDave May } 1271f98405f7SJed Brown 1272a5bc1bf3SBarry Smith for (i=0; i<dmf->bs; i++) { 1273f98405f7SJed Brown const char *fieldname; 12749566063dSJacob Faibussowitsch PetscCall(DMDAGetFieldName(dmf,i,&fieldname)); 12759566063dSJacob Faibussowitsch PetscCall(DMDASetFieldName(dmc2,i,fieldname)); 1276f98405f7SJed Brown } 1277f98405f7SJed Brown 1278a5bc1bf3SBarry Smith *dmc = dmc2; 127947c6ae99SBarry Smith PetscFunctionReturn(0); 128047c6ae99SBarry Smith } 128147c6ae99SBarry Smith 12827087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy_DA(DM da,PetscInt nlevels,DM daf[]) 128347c6ae99SBarry Smith { 128447c6ae99SBarry Smith PetscInt i,n,*refx,*refy,*refz; 128547c6ae99SBarry Smith 128647c6ae99SBarry Smith PetscFunctionBegin; 128747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 12887a8be351SBarry Smith PetscCheck(nlevels >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 128947c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 129047c6ae99SBarry Smith PetscValidPointer(daf,3); 129147c6ae99SBarry Smith 1292aa219208SBarry Smith /* Get refinement factors, defaults taken from the coarse DMDA */ 12939566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nlevels,&refx,nlevels,&refy,nlevels,&refz)); 129447c6ae99SBarry Smith for (i=0; i<nlevels; i++) { 12959566063dSJacob Faibussowitsch PetscCall(DMDAGetRefinementFactor(da,&refx[i],&refy[i],&refz[i])); 129647c6ae99SBarry Smith } 129747c6ae99SBarry Smith n = nlevels; 12989566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,NULL)); 129947c6ae99SBarry Smith n = nlevels; 13009566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,NULL)); 130147c6ae99SBarry Smith n = nlevels; 13029566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,NULL)); 130347c6ae99SBarry Smith 13049566063dSJacob Faibussowitsch PetscCall(DMDASetRefinementFactor(da,refx[0],refy[0],refz[0])); 13059566063dSJacob Faibussowitsch PetscCall(DMRefine(da,PetscObjectComm((PetscObject)da),&daf[0])); 130647c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 13079566063dSJacob Faibussowitsch PetscCall(DMDASetRefinementFactor(daf[i-1],refx[i],refy[i],refz[i])); 13089566063dSJacob Faibussowitsch PetscCall(DMRefine(daf[i-1],PetscObjectComm((PetscObject)da),&daf[i])); 130947c6ae99SBarry Smith } 13109566063dSJacob Faibussowitsch PetscCall(PetscFree3(refx,refy,refz)); 131147c6ae99SBarry Smith PetscFunctionReturn(0); 131247c6ae99SBarry Smith } 131347c6ae99SBarry Smith 13147087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy_DA(DM da,PetscInt nlevels,DM dac[]) 131547c6ae99SBarry Smith { 131647c6ae99SBarry Smith PetscInt i; 131747c6ae99SBarry Smith 131847c6ae99SBarry Smith PetscFunctionBegin; 131947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 13207a8be351SBarry Smith PetscCheck(nlevels >= 0,PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 132147c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 132247c6ae99SBarry Smith PetscValidPointer(dac,3); 13239566063dSJacob Faibussowitsch PetscCall(DMCoarsen(da,PetscObjectComm((PetscObject)da),&dac[0])); 132447c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 13259566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dac[i-1],PetscObjectComm((PetscObject)da),&dac[i])); 132647c6ae99SBarry Smith } 132747c6ae99SBarry Smith PetscFunctionReturn(0); 132847c6ae99SBarry Smith } 132962197512SBarry Smith 13308272889dSSatish Balay PetscErrorCode DMDASetGLLCoordinates_1d(DM dm,PetscInt n,PetscReal *nodes) 133162197512SBarry Smith { 13328272889dSSatish Balay PetscInt i,j,xs,xn,q; 133362197512SBarry Smith PetscScalar *xx; 133462197512SBarry Smith PetscReal h; 133562197512SBarry Smith Vec x; 133662197512SBarry Smith DM_DA *da = (DM_DA*)dm->data; 133762197512SBarry Smith 133862197512SBarry Smith PetscFunctionBegin; 133962197512SBarry Smith if (da->bx != DM_BOUNDARY_PERIODIC) { 13409566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(dm,NULL,&q,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)); 134162197512SBarry Smith q = (q-1)/(n-1); /* number of spectral elements */ 134262197512SBarry Smith h = 2.0/q; 13439566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(dm,&xs,NULL,NULL,&xn,NULL,NULL)); 134462197512SBarry Smith xs = xs/(n-1); 134562197512SBarry Smith xn = xn/(n-1); 13469566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(dm,-1.,1.,0.,0.,0.,0.)); 13479566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm,&x)); 13489566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(dm,x,&xx)); 134962197512SBarry Smith 135062197512SBarry Smith /* loop over local spectral elements */ 135162197512SBarry Smith for (j=xs; j<xs+xn; j++) { 135262197512SBarry Smith /* 135362197512SBarry Smith Except for the first process, each process starts on the second GLL point of the first element on that process 135462197512SBarry Smith */ 135562197512SBarry Smith for (i= (j == xs && xs > 0)? 1 : 0; i<n; i++) { 13568272889dSSatish Balay xx[j*(n-1) + i] = -1.0 + h*j + h*(nodes[i]+1.0)/2.; 135762197512SBarry Smith } 135862197512SBarry Smith } 13599566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(dm,x,&xx)); 136062197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not yet implemented for periodic"); 136162197512SBarry Smith PetscFunctionReturn(0); 136262197512SBarry Smith } 136362197512SBarry Smith 13641fd49c25SBarry Smith /*@ 136562197512SBarry Smith 136662197512SBarry Smith DMDASetGLLCoordinates - Sets the global coordinates from -1 to 1 to the GLL points of as many GLL elements that fit the number of grid points 136762197512SBarry Smith 1368d083f849SBarry Smith Collective on da 136962197512SBarry Smith 137062197512SBarry Smith Input Parameters: 137162197512SBarry Smith + da - the DMDA object 13728272889dSSatish Balay - n - the number of GLL nodes 13738272889dSSatish Balay - nodes - the GLL nodes 137462197512SBarry Smith 137595452b02SPatrick Sanan Notes: 137695452b02SPatrick Sanan the parallel decomposition of grid points must correspond to the degree of the GLL. That is, the number of grid points 137762197512SBarry Smith on each process much be divisible by the number of GLL elements needed per process. This depends on whether the DM is 137862197512SBarry Smith periodic or not. 137962197512SBarry Smith 1380edc382c3SSatish Balay Level: advanced 1381edc382c3SSatish Balay 1382db781477SPatrick Sanan .seealso: `DMDACreate()`, `PetscDTGaussLobattoLegendreQuadrature()`, `DMGetCoordinates()` 138362197512SBarry Smith @*/ 13848272889dSSatish Balay PetscErrorCode DMDASetGLLCoordinates(DM da,PetscInt n,PetscReal *nodes) 138562197512SBarry Smith { 138662197512SBarry Smith PetscFunctionBegin; 138762197512SBarry Smith if (da->dim == 1) { 13889566063dSJacob Faibussowitsch PetscCall(DMDASetGLLCoordinates_1d(da,n,nodes)); 138962197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not yet implemented for 2 or 3d"); 139062197512SBarry Smith PetscFunctionReturn(0); 139162197512SBarry Smith } 13927c3cd84eSPatrick Sanan 13937c3cd84eSPatrick Sanan PETSC_INTERN PetscErrorCode DMGetCompatibility_DA(DM da1,DM dm2,PetscBool *compatible,PetscBool *set) 13947c3cd84eSPatrick Sanan { 13957c3cd84eSPatrick Sanan DM_DA *dd1 = (DM_DA*)da1->data,*dd2; 13967c3cd84eSPatrick Sanan DM da2; 13977c3cd84eSPatrick Sanan DMType dmtype2; 13987c3cd84eSPatrick Sanan PetscBool isda,compatibleLocal; 13997c3cd84eSPatrick Sanan PetscInt i; 14007c3cd84eSPatrick Sanan 14017c3cd84eSPatrick Sanan PetscFunctionBegin; 14027a8be351SBarry Smith PetscCheck(da1->setupcalled,PetscObjectComm((PetscObject)da1),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() must be called on first DM before DMGetCompatibility()"); 14039566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2,&dmtype2)); 14049566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(dmtype2,DMDA,&isda)); 14057c3cd84eSPatrick Sanan if (isda) { 14067c3cd84eSPatrick Sanan da2 = dm2; 14077c3cd84eSPatrick Sanan dd2 = (DM_DA*)da2->data; 14087a8be351SBarry Smith PetscCheck(da2->setupcalled,PetscObjectComm((PetscObject)da2),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() must be called on second DM before DMGetCompatibility()"); 1409110623a0SKarl Rupp compatibleLocal = (PetscBool)(da1->dim == da2->dim); 1410c790a739SKarl Rupp if (compatibleLocal) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->s == dd2->s)); /* Stencil width */ 1411110623a0SKarl Rupp /* Global size ranks Boundary type */ 1412c790a739SKarl Rupp if (compatibleLocal) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->M == dd2->M) && (dd1->m == dd2->m) && (dd1->bx == dd2->bx)); 1413c790a739SKarl Rupp if (compatibleLocal && da1->dim > 1) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->N == dd2->N) && (dd1->n == dd2->n) && (dd1->by == dd2->by)); 1414c790a739SKarl Rupp if (compatibleLocal && da1->dim > 2) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->P == dd2->P) && (dd1->p == dd2->p) && (dd1->bz == dd2->bz)); 14157c3cd84eSPatrick Sanan if (compatibleLocal) { 14167c3cd84eSPatrick Sanan for (i=0; i<dd1->m; ++i) { 1417c790a739SKarl Rupp compatibleLocal = (PetscBool)(compatibleLocal && (dd1->lx[i] == dd2->lx[i])); /* Local size */ 14187c3cd84eSPatrick Sanan } 14197c3cd84eSPatrick Sanan } 14207c3cd84eSPatrick Sanan if (compatibleLocal && da1->dim > 1) { 14217c3cd84eSPatrick Sanan for (i=0; i<dd1->n; ++i) { 1422c790a739SKarl Rupp compatibleLocal = (PetscBool)(compatibleLocal && (dd1->ly[i] == dd2->ly[i])); 14237c3cd84eSPatrick Sanan } 14247c3cd84eSPatrick Sanan } 14257c3cd84eSPatrick Sanan if (compatibleLocal && da1->dim > 2) { 14267c3cd84eSPatrick Sanan for (i=0; i<dd1->p; ++i) { 1427c790a739SKarl Rupp compatibleLocal = (PetscBool)(compatibleLocal && (dd1->lz[i] == dd2->lz[i])); 14287c3cd84eSPatrick Sanan } 14297c3cd84eSPatrick Sanan } 14307c3cd84eSPatrick Sanan *compatible = compatibleLocal; 14317c3cd84eSPatrick Sanan *set = PETSC_TRUE; 14327c3cd84eSPatrick Sanan } else { 14337c3cd84eSPatrick Sanan /* Decline to determine compatibility with other DM types */ 14347c3cd84eSPatrick Sanan *set = PETSC_FALSE; 14357c3cd84eSPatrick Sanan } 14367c3cd84eSPatrick Sanan PetscFunctionReturn(0); 14377c3cd84eSPatrick Sanan } 1438