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: 9*dce8aebaSBarry 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 16*dce8aebaSBarry Smith Developer Note: 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 19*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `PetscSplitOwnership()` 2047c6ae99SBarry Smith @*/ 21d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetSizes(DM da, PetscInt M, PetscInt N, PetscInt P) 22d71ae5a4SJacob Faibussowitsch { 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: 47*dce8aebaSBarry Smith + da - the `DMDA` 48*dce8aebaSBarry Smith . m - the number of X procs (or `PETSC_DECIDE`) 49*dce8aebaSBarry Smith . n - the number of Y procs (or `PETSC_DECIDE`) 50*dce8aebaSBarry Smith - p - the number of Z procs (or `PETSC_DECIDE`) 5147c6ae99SBarry Smith 5247c6ae99SBarry Smith Level: intermediate 5347c6ae99SBarry Smith 54*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetSizes()`, `PetscSplitOwnership()` 5547c6ae99SBarry Smith @*/ 56d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetNumProcs(DM da, PetscInt m, PetscInt n, PetscInt p) 57d71ae5a4SJacob Faibussowitsch { 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: 90*dce8aebaSBarry Smith + da - The `DMDA` 91*dce8aebaSBarry Smith - bx,by,bz - One of `DM_BOUNDARY_NONE`, `DM_BOUNDARY_GHOSTED`, `DM_BOUNDARY_PERIODIC` 9247c6ae99SBarry Smith 9347c6ae99SBarry Smith Level: intermediate 9447c6ae99SBarry Smith 95*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `DMDestroy()`, `DMBoundaryType` 9647c6ae99SBarry Smith @*/ 97d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetBoundaryType(DM da, DMBoundaryType bx, DMBoundaryType by, DMBoundaryType bz) 98d71ae5a4SJacob Faibussowitsch { 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: 119*dce8aebaSBarry Smith + da - The `DMDA` 12047c6ae99SBarry Smith - dof - Number of degrees of freedom 12147c6ae99SBarry Smith 12247c6ae99SBarry Smith Level: intermediate 12347c6ae99SBarry Smith 124*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetDof()`, `DMDACreate()`, `DMDestroy()` 12547c6ae99SBarry Smith @*/ 126d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetDof(DM da, PetscInt dof) 127d71ae5a4SJacob Faibussowitsch { 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: 145*dce8aebaSBarry Smith . 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 152*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetDof()`, `DMDACreate()`, `DMDestroy()` 153fb6725baSMatthew G. Knepley @*/ 154d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetDof(DM da, PetscInt *dof) 155d71ae5a4SJacob Faibussowitsch { 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: 171*dce8aebaSBarry Smith . 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*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMCreateDomainDecomposition()`, `DMDASetOverlap()` 1817ddda789SPeter Brune @*/ 182d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetOverlap(DM da, PetscInt *x, PetscInt *y, PetscInt *z) 183d71ae5a4SJacob Faibussowitsch { 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: 200*dce8aebaSBarry Smith + 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*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMCreateDomainDecomposition()`, `DMDAGetOverlap()` 20888661749SPeter Brune @*/ 209d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetOverlap(DM da, PetscInt x, PetscInt y, PetscInt z) 210d71ae5a4SJacob Faibussowitsch { 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: 230*dce8aebaSBarry Smith . 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*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMCreateDomainDecomposition()`, `DMDASetNumLocalSubDomains()` 2383e7870d2SPeter Brune @*/ 239d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetNumLocalSubDomains(DM da, PetscInt *Nsub) 240d71ae5a4SJacob Faibussowitsch { 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: 255*dce8aebaSBarry Smith + da - The `DMDA` 2563e7870d2SPeter Brune - Nsub - The number of local subdomains requested 2573e7870d2SPeter Brune 2583e7870d2SPeter Brune Level: intermediate 2593e7870d2SPeter Brune 260*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMCreateDomainDecomposition()`, `DMDAGetNumLocalSubDomains()` 2613e7870d2SPeter Brune @*/ 262d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetNumLocalSubDomains(DM da, PetscInt Nsub) 263d71ae5a4SJacob Faibussowitsch { 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 276*dce8aebaSBarry Smith Collective on da 277d886c4f4SPeter Brune 278d8d19677SJose E. Roman Input Parameters: 279*dce8aebaSBarry Smith + 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 286*dce8aebaSBarry Smith Note: 287*dce8aebaSBarry Smith This is used primarily to overlap a computation on a local `DMDA` with that on a global `DMDA` without 288d886c4f4SPeter Brune changing boundary conditions or subdomain features that depend upon the global offsets. 289d886c4f4SPeter Brune 290*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetOffset()`, `DMDAVecGetArray()` 291d886c4f4SPeter Brune @*/ 292d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetOffset(DM da, PetscInt xo, PetscInt yo, PetscInt zo, PetscInt Mo, PetscInt No, PetscInt Po) 293d71ae5a4SJacob Faibussowitsch { 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 3116858538eSMatthew G. Knepley if (da->coordinates[0].dm) PetscCall(DMDASetOffset(da->coordinates[0].dm, xo, yo, zo, Mo, No, Po)); 312d886c4f4SPeter Brune PetscFunctionReturn(0); 313d886c4f4SPeter Brune } 314d886c4f4SPeter Brune 315d886c4f4SPeter Brune /*@ 316*dce8aebaSBarry Smith DMDAGetOffset - Gets the index offset of the `DMDA`. 317d886c4f4SPeter Brune 318d886c4f4SPeter Brune Not collective 319d886c4f4SPeter Brune 320d886c4f4SPeter Brune Input Parameter: 321*dce8aebaSBarry Smith . da - The `DMDA` 322d886c4f4SPeter Brune 323d886c4f4SPeter Brune Output Parameters: 324d886c4f4SPeter Brune + xo - The offset in the x direction 325d886c4f4SPeter Brune . yo - The offset in the y direction 32695c13181SPeter Brune . zo - The offset in the z direction 32795c13181SPeter Brune . Mo - The global size in the x direction 32895c13181SPeter Brune . No - The global size in the y direction 32995c13181SPeter Brune - Po - The global size in the z direction 330d886c4f4SPeter Brune 331d886c4f4SPeter Brune Level: intermediate 332d886c4f4SPeter Brune 333*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetOffset()`, `DMDAVecGetArray()` 334d886c4f4SPeter Brune @*/ 335d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetOffset(DM da, PetscInt *xo, PetscInt *yo, PetscInt *zo, PetscInt *Mo, PetscInt *No, PetscInt *Po) 336d71ae5a4SJacob Faibussowitsch { 337d886c4f4SPeter Brune DM_DA *dd = (DM_DA *)da->data; 338d886c4f4SPeter Brune 339d886c4f4SPeter Brune PetscFunctionBegin; 340a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 341d886c4f4SPeter Brune if (xo) *xo = dd->xo; 342d886c4f4SPeter Brune if (yo) *yo = dd->yo; 343d886c4f4SPeter Brune if (zo) *zo = dd->zo; 34495c13181SPeter Brune if (Mo) *Mo = dd->Mo; 34595c13181SPeter Brune if (No) *No = dd->No; 34695c13181SPeter Brune if (Po) *Po = dd->Po; 347d886c4f4SPeter Brune PetscFunctionReturn(0); 348d886c4f4SPeter Brune } 349d886c4f4SPeter Brune 35040234c92SPeter Brune /*@ 351*dce8aebaSBarry Smith DMDAGetNonOverlappingRegion - Gets the indices of the nonoverlapping region of a subdomain `DM`. 35240234c92SPeter Brune 35340234c92SPeter Brune Not collective 35440234c92SPeter Brune 35540234c92SPeter Brune Input Parameter: 356*dce8aebaSBarry Smith . da - The `DMDA` 35740234c92SPeter Brune 35840234c92SPeter Brune Output Parameters: 35940234c92SPeter Brune + xs - The start of the region in x 36040234c92SPeter Brune . ys - The start of the region in y 36140234c92SPeter Brune . zs - The start of the region in z 36240234c92SPeter Brune . xs - The size of the region in x 36340234c92SPeter Brune . ys - The size of the region in y 364a2b725a8SWilliam Gropp - zs - The size of the region in z 36540234c92SPeter Brune 36640234c92SPeter Brune Level: intermediate 36740234c92SPeter Brune 368*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetOffset()`, `DMDAVecGetArray()` 36940234c92SPeter Brune @*/ 370d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetNonOverlappingRegion(DM da, PetscInt *xs, PetscInt *ys, PetscInt *zs, PetscInt *xm, PetscInt *ym, PetscInt *zm) 371d71ae5a4SJacob Faibussowitsch { 37240234c92SPeter Brune DM_DA *dd = (DM_DA *)da->data; 37340234c92SPeter Brune 37440234c92SPeter Brune PetscFunctionBegin; 375a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 37640234c92SPeter Brune if (xs) *xs = dd->nonxs; 37740234c92SPeter Brune if (ys) *ys = dd->nonys; 37840234c92SPeter Brune if (zs) *zs = dd->nonzs; 37940234c92SPeter Brune if (xm) *xm = dd->nonxm; 38040234c92SPeter Brune if (ym) *ym = dd->nonym; 38140234c92SPeter Brune if (zm) *zm = dd->nonzm; 38240234c92SPeter Brune PetscFunctionReturn(0); 38340234c92SPeter Brune } 38440234c92SPeter Brune 38540234c92SPeter Brune /*@ 386*dce8aebaSBarry Smith DMDASetNonOverlappingRegion - Sets the indices of the nonoverlapping region of a subdomain `DM`. 38740234c92SPeter Brune 388*dce8aebaSBarry Smith Collective on da 38940234c92SPeter Brune 390d8d19677SJose E. Roman Input Parameters: 391*dce8aebaSBarry Smith + da - The `DMDA` 39240234c92SPeter Brune . xs - The start of the region in x 39340234c92SPeter Brune . ys - The start of the region in y 39440234c92SPeter Brune . zs - The start of the region in z 39540234c92SPeter Brune . xs - The size of the region in x 39640234c92SPeter Brune . ys - The size of the region in y 397a2b725a8SWilliam Gropp - zs - The size of the region in z 39840234c92SPeter Brune 39940234c92SPeter Brune Level: intermediate 40040234c92SPeter Brune 401*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetOffset()`, `DMDAVecGetArray()` 40240234c92SPeter Brune @*/ 403d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetNonOverlappingRegion(DM da, PetscInt xs, PetscInt ys, PetscInt zs, PetscInt xm, PetscInt ym, PetscInt zm) 404d71ae5a4SJacob Faibussowitsch { 40540234c92SPeter Brune DM_DA *dd = (DM_DA *)da->data; 40640234c92SPeter Brune 40740234c92SPeter Brune PetscFunctionBegin; 408a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 40940234c92SPeter Brune PetscValidLogicalCollectiveInt(da, xs, 2); 41040234c92SPeter Brune PetscValidLogicalCollectiveInt(da, ys, 3); 41140234c92SPeter Brune PetscValidLogicalCollectiveInt(da, zs, 4); 41240234c92SPeter Brune PetscValidLogicalCollectiveInt(da, xm, 5); 41340234c92SPeter Brune PetscValidLogicalCollectiveInt(da, ym, 6); 41440234c92SPeter Brune PetscValidLogicalCollectiveInt(da, zm, 7); 41540234c92SPeter Brune dd->nonxs = xs; 41640234c92SPeter Brune dd->nonys = ys; 41740234c92SPeter Brune dd->nonzs = zs; 41840234c92SPeter Brune dd->nonxm = xm; 41940234c92SPeter Brune dd->nonym = ym; 42040234c92SPeter Brune dd->nonzm = zm; 42140234c92SPeter Brune 42240234c92SPeter Brune PetscFunctionReturn(0); 42340234c92SPeter Brune } 42488661749SPeter Brune 42547c6ae99SBarry Smith /*@ 426aa219208SBarry Smith DMDASetStencilType - Sets the type of the communication stencil 42747c6ae99SBarry Smith 428d083f849SBarry Smith Logically Collective on da 42947c6ae99SBarry Smith 430d8d19677SJose E. Roman Input Parameters: 431*dce8aebaSBarry Smith + da - The `DMDA` 432*dce8aebaSBarry Smith - stype - The stencil type, use either `DMDA_STENCIL_BOX` or `DMDA_STENCIL_STAR`. 43347c6ae99SBarry Smith 43447c6ae99SBarry Smith Level: intermediate 43547c6ae99SBarry Smith 436*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `DMDestroy()` 43747c6ae99SBarry Smith @*/ 438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetStencilType(DM da, DMDAStencilType stype) 439d71ae5a4SJacob Faibussowitsch { 44047c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 44147c6ae99SBarry Smith 44247c6ae99SBarry Smith PetscFunctionBegin; 443a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 44447c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da, stype, 2); 4457a8be351SBarry Smith PetscCheck(!da->setupcalled, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "This function must be called before DMSetUp()"); 44647c6ae99SBarry Smith dd->stencil_type = stype; 44747c6ae99SBarry Smith PetscFunctionReturn(0); 44847c6ae99SBarry Smith } 44947c6ae99SBarry Smith 450fb6725baSMatthew G. Knepley /*@ 451fb6725baSMatthew G. Knepley DMDAGetStencilType - Gets the type of the communication stencil 452fb6725baSMatthew G. Knepley 453fb6725baSMatthew G. Knepley Not collective 454fb6725baSMatthew G. Knepley 455fb6725baSMatthew G. Knepley Input Parameter: 456*dce8aebaSBarry Smith . da - The `DMDA` 457fb6725baSMatthew G. Knepley 458fb6725baSMatthew G. Knepley Output Parameter: 459*dce8aebaSBarry Smith . stype - The stencil type, use either `DMDA_STENCIL_BOX` or `DMDA_STENCIL_STAR`. 460fb6725baSMatthew G. Knepley 461fb6725baSMatthew G. Knepley Level: intermediate 462fb6725baSMatthew G. Knepley 463*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `DMDestroy()` 464fb6725baSMatthew G. Knepley @*/ 465d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetStencilType(DM da, DMDAStencilType *stype) 466d71ae5a4SJacob Faibussowitsch { 467fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *)da->data; 468fb6725baSMatthew G. Knepley 469fb6725baSMatthew G. Knepley PetscFunctionBegin; 470a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 471fb6725baSMatthew G. Knepley PetscValidPointer(stype, 2); 472fb6725baSMatthew G. Knepley *stype = dd->stencil_type; 473fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 474fb6725baSMatthew G. Knepley } 475fb6725baSMatthew G. Knepley 47647c6ae99SBarry Smith /*@ 477aa219208SBarry Smith DMDASetStencilWidth - Sets the width of the communication stencil 47847c6ae99SBarry Smith 479d083f849SBarry Smith Logically Collective on da 48047c6ae99SBarry Smith 481d8d19677SJose E. Roman Input Parameters: 482*dce8aebaSBarry Smith + da - The `DMDA` 48347c6ae99SBarry Smith - width - The stencil width 48447c6ae99SBarry Smith 48547c6ae99SBarry Smith Level: intermediate 48647c6ae99SBarry Smith 487*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `DMDestroy()` 48847c6ae99SBarry Smith @*/ 489d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetStencilWidth(DM da, PetscInt width) 490d71ae5a4SJacob Faibussowitsch { 49147c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 49247c6ae99SBarry Smith 49347c6ae99SBarry Smith PetscFunctionBegin; 494a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 49547c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da, width, 2); 4967a8be351SBarry Smith PetscCheck(!da->setupcalled, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "This function must be called before DMSetUp()"); 49747c6ae99SBarry Smith dd->s = width; 49847c6ae99SBarry Smith PetscFunctionReturn(0); 49947c6ae99SBarry Smith } 50047c6ae99SBarry Smith 501fb6725baSMatthew G. Knepley /*@ 502fb6725baSMatthew G. Knepley DMDAGetStencilWidth - Gets the width of the communication stencil 503fb6725baSMatthew G. Knepley 504fb6725baSMatthew G. Knepley Not collective 505fb6725baSMatthew G. Knepley 506fb6725baSMatthew G. Knepley Input Parameter: 507*dce8aebaSBarry Smith . da - The `DMDA` 508fb6725baSMatthew G. Knepley 509fb6725baSMatthew G. Knepley Output Parameter: 510fb6725baSMatthew G. Knepley . width - The stencil width 511fb6725baSMatthew G. Knepley 512fb6725baSMatthew G. Knepley Level: intermediate 513fb6725baSMatthew G. Knepley 514*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `DMDestroy()` 515fb6725baSMatthew G. Knepley @*/ 516d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetStencilWidth(DM da, PetscInt *width) 517d71ae5a4SJacob Faibussowitsch { 518fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *)da->data; 519fb6725baSMatthew G. Knepley 520fb6725baSMatthew G. Knepley PetscFunctionBegin; 521a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 522dadcf809SJacob Faibussowitsch PetscValidIntPointer(width, 2); 523fb6725baSMatthew G. Knepley *width = dd->s; 524fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 525fb6725baSMatthew G. Knepley } 526fb6725baSMatthew G. Knepley 527d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDACheckOwnershipRanges_Private(DM da, PetscInt M, PetscInt m, const PetscInt lx[]) 528d71ae5a4SJacob Faibussowitsch { 52947c6ae99SBarry Smith PetscInt i, sum; 53047c6ae99SBarry Smith 53147c6ae99SBarry Smith PetscFunctionBegin; 5327a8be351SBarry Smith PetscCheck(M >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "Global dimension not set"); 53347c6ae99SBarry Smith for (i = sum = 0; i < m; i++) sum += lx[i]; 53463a3b9bcSJacob 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); 53547c6ae99SBarry Smith PetscFunctionReturn(0); 53647c6ae99SBarry Smith } 53747c6ae99SBarry Smith 53847c6ae99SBarry Smith /*@ 539aa219208SBarry Smith DMDASetOwnershipRanges - Sets the number of nodes in each direction on each process 54047c6ae99SBarry Smith 541d083f849SBarry Smith Logically Collective on da 54247c6ae99SBarry Smith 543d8d19677SJose E. Roman Input Parameters: 544*dce8aebaSBarry Smith + da - The `DMDA` 5450298fd71SBarry 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 5460298fd71SBarry 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 5470298fd71SBarry 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. 54847c6ae99SBarry Smith 54947c6ae99SBarry Smith Level: intermediate 55047c6ae99SBarry Smith 551e3f3e4b6SBarry Smith Note: these numbers are NOT multiplied by the number of dof per node. 552e3f3e4b6SBarry Smith 553*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `DMDestroy()` 55447c6ae99SBarry Smith @*/ 555d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetOwnershipRanges(DM da, const PetscInt lx[], const PetscInt ly[], const PetscInt lz[]) 556d71ae5a4SJacob Faibussowitsch { 55747c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 55847c6ae99SBarry Smith 55947c6ae99SBarry Smith PetscFunctionBegin; 560a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 5617a8be351SBarry Smith PetscCheck(!da->setupcalled, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "This function must be called before DMSetUp()"); 56247c6ae99SBarry Smith if (lx) { 5637a8be351SBarry Smith PetscCheck(dd->m >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "Cannot set ownership ranges before setting number of procs"); 5649566063dSJacob Faibussowitsch PetscCall(DMDACheckOwnershipRanges_Private(da, dd->M, dd->m, lx)); 56548a46eb9SPierre Jolivet if (!dd->lx) PetscCall(PetscMalloc1(dd->m, &dd->lx)); 5669566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd->lx, lx, dd->m)); 56747c6ae99SBarry Smith } 56847c6ae99SBarry Smith if (ly) { 5697a8be351SBarry Smith PetscCheck(dd->n >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "Cannot set ownership ranges before setting number of procs"); 5709566063dSJacob Faibussowitsch PetscCall(DMDACheckOwnershipRanges_Private(da, dd->N, dd->n, ly)); 57148a46eb9SPierre Jolivet if (!dd->ly) PetscCall(PetscMalloc1(dd->n, &dd->ly)); 5729566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd->ly, ly, dd->n)); 57347c6ae99SBarry Smith } 57447c6ae99SBarry Smith if (lz) { 5757a8be351SBarry Smith PetscCheck(dd->p >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_WRONGSTATE, "Cannot set ownership ranges before setting number of procs"); 5769566063dSJacob Faibussowitsch PetscCall(DMDACheckOwnershipRanges_Private(da, dd->P, dd->p, lz)); 57748a46eb9SPierre Jolivet if (!dd->lz) PetscCall(PetscMalloc1(dd->p, &dd->lz)); 5789566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd->lz, lz, dd->p)); 57947c6ae99SBarry Smith } 58047c6ae99SBarry Smith PetscFunctionReturn(0); 58147c6ae99SBarry Smith } 58247c6ae99SBarry Smith 58347c6ae99SBarry Smith /*@ 584aa219208SBarry Smith DMDASetInterpolationType - Sets the type of interpolation that will be 585*dce8aebaSBarry Smith returned by `DMCreateInterpolation()` 58647c6ae99SBarry Smith 587d083f849SBarry Smith Logically Collective on da 58847c6ae99SBarry Smith 589d8d19677SJose E. Roman Input Parameters: 59047c6ae99SBarry Smith + da - initial distributed array 591*dce8aebaSBarry Smith - ctype - `DMDA_Q1` and `DMDA_Q0` are currently the only supported forms 59247c6ae99SBarry Smith 59347c6ae99SBarry Smith Level: intermediate 59447c6ae99SBarry Smith 595*dce8aebaSBarry Smith Note: 596*dce8aebaSBarry Smith You should call this on the coarser of the two `DMDA` you pass to `DMCreateInterpolation()` 59747c6ae99SBarry Smith 598*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMDestroy()`, `DMDAInterpolationType` 59947c6ae99SBarry Smith @*/ 600d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetInterpolationType(DM da, DMDAInterpolationType ctype) 601d71ae5a4SJacob Faibussowitsch { 60247c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 60347c6ae99SBarry Smith 60447c6ae99SBarry Smith PetscFunctionBegin; 605a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 60647c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da, ctype, 2); 60747c6ae99SBarry Smith dd->interptype = ctype; 60847c6ae99SBarry Smith PetscFunctionReturn(0); 60947c6ae99SBarry Smith } 61047c6ae99SBarry Smith 6112dde6fd4SLisandro Dalcin /*@ 6122dde6fd4SLisandro Dalcin DMDAGetInterpolationType - Gets the type of interpolation that will be 613*dce8aebaSBarry Smith used by `DMCreateInterpolation()` 6142dde6fd4SLisandro Dalcin 6152dde6fd4SLisandro Dalcin Not Collective 6162dde6fd4SLisandro Dalcin 6172dde6fd4SLisandro Dalcin Input Parameter: 6182dde6fd4SLisandro Dalcin . da - distributed array 6192dde6fd4SLisandro Dalcin 6202dde6fd4SLisandro Dalcin Output Parameter: 621*dce8aebaSBarry Smith . ctype - interpolation type (`DMDA_Q1` and `DMDA_Q0` are currently the only supported forms) 6222dde6fd4SLisandro Dalcin 6232dde6fd4SLisandro Dalcin Level: intermediate 6242dde6fd4SLisandro Dalcin 625*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAInterpolationType`, `DMDASetInterpolationType()`, `DMCreateInterpolation()` 6262dde6fd4SLisandro Dalcin @*/ 627d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetInterpolationType(DM da, DMDAInterpolationType *ctype) 628d71ae5a4SJacob Faibussowitsch { 6292dde6fd4SLisandro Dalcin DM_DA *dd = (DM_DA *)da->data; 6302dde6fd4SLisandro Dalcin 6312dde6fd4SLisandro Dalcin PetscFunctionBegin; 632a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 6332dde6fd4SLisandro Dalcin PetscValidPointer(ctype, 2); 6342dde6fd4SLisandro Dalcin *ctype = dd->interptype; 6352dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 6362dde6fd4SLisandro Dalcin } 63747c6ae99SBarry Smith 6386a119db4SBarry Smith /*@C 639aa219208SBarry Smith DMDAGetNeighbors - Gets an array containing the MPI rank of all the current 64047c6ae99SBarry Smith processes neighbors. 64147c6ae99SBarry Smith 64247c6ae99SBarry Smith Not Collective 64347c6ae99SBarry Smith 64447c6ae99SBarry Smith Input Parameter: 645*dce8aebaSBarry Smith . da - the `DMDA` object 64647c6ae99SBarry Smith 64747c6ae99SBarry Smith Output Parameters: 64847c6ae99SBarry Smith . ranks - the neighbors ranks, stored with the x index increasing most rapidly. 64947c6ae99SBarry Smith this process itself is in the list 65047c6ae99SBarry Smith 65147c6ae99SBarry Smith Level: intermediate 65247c6ae99SBarry Smith 653*dce8aebaSBarry Smith Notes: 654*dce8aebaSBarry Smith In 2d the array is of length 9, in 3d of length 27 655*dce8aebaSBarry Smith 656*dce8aebaSBarry Smith Not supported in 1d 657*dce8aebaSBarry Smith 658*dce8aebaSBarry Smith Do not free the array, it is freed when the `DMDA` is destroyed. 659*dce8aebaSBarry Smith 660*dce8aebaSBarry Smith Fortran Note: 661*dce8aebaSBarry Smith In fortran you must pass in an array of the appropriate length. 662*dce8aebaSBarry Smith 663*dce8aebaSBarry Smith .seealso: `DMDA`, `DM` 66447c6ae99SBarry Smith @*/ 665d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetNeighbors(DM da, const PetscMPIInt *ranks[]) 666d71ae5a4SJacob Faibussowitsch { 66747c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 6685fd66863SKarl Rupp 66947c6ae99SBarry Smith PetscFunctionBegin; 670a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 67147c6ae99SBarry Smith *ranks = dd->neighbors; 67247c6ae99SBarry Smith PetscFunctionReturn(0); 67347c6ae99SBarry Smith } 67447c6ae99SBarry Smith 67547c6ae99SBarry Smith /*@C 676aa219208SBarry Smith DMDAGetOwnershipRanges - Gets the ranges of indices in the x, y and z direction that are owned by each process 67747c6ae99SBarry Smith 67847c6ae99SBarry Smith Not Collective 67947c6ae99SBarry Smith 68047c6ae99SBarry Smith Input Parameter: 681*dce8aebaSBarry Smith . da - the `DMDA` object 68247c6ae99SBarry Smith 683d8d19677SJose E. Roman Output Parameters: 68447c6ae99SBarry Smith + lx - ownership along x direction (optional) 68547c6ae99SBarry Smith . ly - ownership along y direction (optional) 68647c6ae99SBarry Smith - lz - ownership along z direction (optional) 68747c6ae99SBarry Smith 68847c6ae99SBarry Smith Level: intermediate 68947c6ae99SBarry Smith 690*dce8aebaSBarry Smith Note: 691*dce8aebaSBarry Smith These correspond to the optional final arguments passed to `DMDACreate()`, `DMDACreate2d()`, `DMDACreate3d()` 69247c6ae99SBarry Smith 69347c6ae99SBarry Smith In C you should not free these arrays, nor change the values in them. They will only have valid values while the 694*dce8aebaSBarry Smith `DMDA` they came from still exists (has not been destroyed). 69547c6ae99SBarry Smith 696e3f3e4b6SBarry Smith These numbers are NOT multiplied by the number of dof per node. 697e3f3e4b6SBarry Smith 698*dce8aebaSBarry Smith Fortran Note: 699*dce8aebaSBarry Smith In Fortran one must pass in arrays lx, ly, and lz that are long enough to hold the values; the sixth, seventh and 700*dce8aebaSBarry Smith eighth arguments from `DMDAGetInfo()` 701*dce8aebaSBarry Smith 702*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetCorners()`, `DMDAGetGhostCorners()`, `DMDACreate()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `VecGetOwnershipRanges()` 70347c6ae99SBarry Smith @*/ 704d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetOwnershipRanges(DM da, const PetscInt *lx[], const PetscInt *ly[], const PetscInt *lz[]) 705d71ae5a4SJacob Faibussowitsch { 70647c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 70747c6ae99SBarry Smith 70847c6ae99SBarry Smith PetscFunctionBegin; 709a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 71047c6ae99SBarry Smith if (lx) *lx = dd->lx; 71147c6ae99SBarry Smith if (ly) *ly = dd->ly; 71247c6ae99SBarry Smith if (lz) *lz = dd->lz; 71347c6ae99SBarry Smith PetscFunctionReturn(0); 71447c6ae99SBarry Smith } 71547c6ae99SBarry Smith 71647c6ae99SBarry Smith /*@ 717*dce8aebaSBarry Smith DMDASetRefinementFactor - Set the ratios that the `DMDA` grid is refined 71847c6ae99SBarry Smith 719d083f849SBarry Smith Logically Collective on da 72047c6ae99SBarry Smith 72147c6ae99SBarry Smith Input Parameters: 722*dce8aebaSBarry Smith + da - the `DMDA` object 72347c6ae99SBarry Smith . refine_x - ratio of fine grid to coarse in x direction (2 by default) 72447c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 72547c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 72647c6ae99SBarry Smith 727*dce8aebaSBarry Smith Options Database Keys: 72848eeb7c8SBarry Smith + -da_refine_x refine_x - refinement ratio in x direction 72948eeb7c8SBarry Smith . -da_refine_y rafine_y - refinement ratio in y direction 73048eeb7c8SBarry Smith . -da_refine_z refine_z - refinement ratio in z direction 73148eeb7c8SBarry Smith - -da_refine <n> - refine the DMDA object n times when it is created. 73247c6ae99SBarry Smith 73347c6ae99SBarry Smith Level: intermediate 73447c6ae99SBarry Smith 735*dce8aebaSBarry Smith Note: 736*dce8aebaSBarry Smith Pass `PETSC_IGNORE` to leave a value unchanged 73747c6ae99SBarry Smith 738*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMRefine()`, `DMDAGetRefinementFactor()` 73947c6ae99SBarry Smith @*/ 740d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetRefinementFactor(DM da, PetscInt refine_x, PetscInt refine_y, PetscInt refine_z) 741d71ae5a4SJacob Faibussowitsch { 74247c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 74347c6ae99SBarry Smith 74447c6ae99SBarry Smith PetscFunctionBegin; 745a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 74647c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da, refine_x, 2); 74747c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da, refine_y, 3); 74847c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da, refine_z, 4); 74947c6ae99SBarry Smith 75047c6ae99SBarry Smith if (refine_x > 0) dd->refine_x = refine_x; 75147c6ae99SBarry Smith if (refine_y > 0) dd->refine_y = refine_y; 75247c6ae99SBarry Smith if (refine_z > 0) dd->refine_z = refine_z; 75347c6ae99SBarry Smith PetscFunctionReturn(0); 75447c6ae99SBarry Smith } 75547c6ae99SBarry Smith 75647c6ae99SBarry Smith /*@C 757*dce8aebaSBarry Smith DMDAGetRefinementFactor - Gets the ratios that the `DMDA` grid is refined 75847c6ae99SBarry Smith 75947c6ae99SBarry Smith Not Collective 76047c6ae99SBarry Smith 76147c6ae99SBarry Smith Input Parameter: 762*dce8aebaSBarry Smith . da - the `DMDA` object 76347c6ae99SBarry Smith 76447c6ae99SBarry Smith Output Parameters: 76547c6ae99SBarry Smith + refine_x - ratio of fine grid to coarse in x direction (2 by default) 76647c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 76747c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 76847c6ae99SBarry Smith 76947c6ae99SBarry Smith Level: intermediate 77047c6ae99SBarry Smith 771*dce8aebaSBarry Smith Note: 77295452b02SPatrick Sanan Pass NULL for values you do not need 77347c6ae99SBarry Smith 774*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMRefine()`, `DMDASetRefinementFactor()` 77547c6ae99SBarry Smith @*/ 776d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetRefinementFactor(DM da, PetscInt *refine_x, PetscInt *refine_y, PetscInt *refine_z) 777d71ae5a4SJacob Faibussowitsch { 77847c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 77947c6ae99SBarry Smith 78047c6ae99SBarry Smith PetscFunctionBegin; 781a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 78247c6ae99SBarry Smith if (refine_x) *refine_x = dd->refine_x; 78347c6ae99SBarry Smith if (refine_y) *refine_y = dd->refine_y; 78447c6ae99SBarry Smith if (refine_z) *refine_z = dd->refine_z; 78547c6ae99SBarry Smith PetscFunctionReturn(0); 78647c6ae99SBarry Smith } 78747c6ae99SBarry Smith 78847c6ae99SBarry Smith /*@C 789*dce8aebaSBarry Smith DMDASetGetMatrix - Sets the routine used by the `DMDA` to allocate a matrix. 79047c6ae99SBarry Smith 791d083f849SBarry Smith Logically Collective on da 79247c6ae99SBarry Smith 79347c6ae99SBarry Smith Input Parameters: 794*dce8aebaSBarry Smith + da - the `DMDA` object 795aa219208SBarry Smith - f - the function that allocates the matrix for that specific DMDA 79647c6ae99SBarry Smith 79747c6ae99SBarry Smith Level: developer 79847c6ae99SBarry Smith 799*dce8aebaSBarry Smith Note: 800*dce8aebaSBarry Smith See `DMDASetBlockFills()` that provides a simple way to provide the nonzero structure for 80147c6ae99SBarry Smith the diagonal and off-diagonal blocks of the matrix 80247c6ae99SBarry Smith 803*dce8aebaSBarry Smith Fortran Note: 8041fd49c25SBarry Smith Not supported from Fortran 8051fd49c25SBarry Smith 806*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMCreateMatrix()`, `DMDASetBlockFills()` 80747c6ae99SBarry Smith @*/ 808d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetGetMatrix(DM da, PetscErrorCode (*f)(DM, Mat *)) 809d71ae5a4SJacob Faibussowitsch { 81047c6ae99SBarry Smith PetscFunctionBegin; 811a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 81225296bd5SBarry Smith da->ops->creatematrix = f; 81347c6ae99SBarry Smith PetscFunctionReturn(0); 81447c6ae99SBarry Smith } 81547c6ae99SBarry Smith 81638fb4e8eSJunchao Zhang /*@ 817*dce8aebaSBarry Smith DMDAMapMatStencilToGlobal - Map a list of `MatStencil` on a grid to global indices. 81838fb4e8eSJunchao Zhang 81938fb4e8eSJunchao Zhang Not Collective 82038fb4e8eSJunchao Zhang 82138fb4e8eSJunchao Zhang Input Parameters: 822*dce8aebaSBarry Smith + da - the `DMDA` object 82338fb4e8eSJunchao Zhang . m - number of MatStencils 82438fb4e8eSJunchao Zhang - idxm - grid points (and component number when dof > 1) 82538fb4e8eSJunchao Zhang 8261179163eSBarry Smith Output Parameter: 8271179163eSBarry Smith . gidxm - global row indices 8281179163eSBarry Smith 8291179163eSBarry Smith Level: intermediate 83038fb4e8eSJunchao Zhang 831*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `MatStencil` 83238fb4e8eSJunchao Zhang @*/ 833d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAMapMatStencilToGlobal(DM da, PetscInt m, const MatStencil idxm[], PetscInt gidxm[]) 834d71ae5a4SJacob Faibussowitsch { 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 8442f27f4d1SJunchao Zhang /* Code adapted from DMDAGetGhostCorners() */ 84538fb4e8eSJunchao Zhang starts2[0] = dd->Xs / dof + dd->xo; 84638fb4e8eSJunchao Zhang starts2[1] = dd->Ys + dd->yo; 84738fb4e8eSJunchao Zhang starts2[2] = dd->Zs + dd->zo; 84838fb4e8eSJunchao Zhang dims2[0] = (dd->Xe - dd->Xs) / dof; 84938fb4e8eSJunchao Zhang dims2[1] = (dd->Ye - dd->Ys); 85038fb4e8eSJunchao Zhang dims2[2] = (dd->Ze - dd->Zs); 85138fb4e8eSJunchao Zhang 8522f27f4d1SJunchao Zhang /* As if we do MatSetStencil() to get dims[]/starts[] of mat->stencil */ 8532f27f4d1SJunchao Zhang dim = da->dim; /* DA dim: 1 to 3 */ 8542f27f4d1SJunchao Zhang sdim = dim + (dof > 1 ? 1 : 0); /* Dimensions in MatStencil's (k,j,i,c) view */ 8552f27f4d1SJunchao Zhang for (i = 0; i < dim; i++) { /* Reverse the order and also skip the unused dimensions */ 8562f27f4d1SJunchao Zhang dims[i] = dims2[dim - i - 1]; /* ex. dims/starts[] are in order of {i} for 1D, {j,i} for 2D and {k,j,i} for 3D */ 85738fb4e8eSJunchao Zhang starts[i] = starts2[dim - i - 1]; 85838fb4e8eSJunchao Zhang } 8592f27f4d1SJunchao Zhang starts[dim] = 0; /* Append the extra dim for dof (won't be used below if dof=1) */ 86038fb4e8eSJunchao Zhang dims[dim] = dof; 86138fb4e8eSJunchao Zhang 86238fb4e8eSJunchao Zhang /* Map stencils to local indices (code adapted from MatSetValuesStencil()) */ 86338fb4e8eSJunchao Zhang for (i = 0; i < m; i++) { 8642f27f4d1SJunchao Zhang dxm += 3 - dim; /* Input is {k,j,i,c}; move the pointer to the first used index, e.g., j in 2D */ 8652f27f4d1SJunchao Zhang tmp = 0; 8662f27f4d1SJunchao Zhang for (j = 0; j < sdim; j++) { /* Iter over, ex. j,i or j,i,c in 2D */ 8672f27f4d1SJunchao Zhang if (tmp < 0 || dxm[j] < starts[j] || dxm[j] >= (starts[j] + dims[j])) tmp = -1; /* Beyond the ghost region, therefore ignored with negative indices */ 8682f27f4d1SJunchao Zhang else tmp = tmp * dims[j] + (dxm[j] - starts[j]); 86938fb4e8eSJunchao Zhang } 87038fb4e8eSJunchao Zhang gidxm[i] = tmp; 8712f27f4d1SJunchao Zhang /* Move to the next MatStencil point */ 8722f27f4d1SJunchao Zhang if (dof > 1) dxm += sdim; /* c is already counted in sdim */ 8732f27f4d1SJunchao Zhang else dxm += sdim + 1; /* skip the unused c */ 87438fb4e8eSJunchao Zhang } 87538fb4e8eSJunchao Zhang 87638fb4e8eSJunchao Zhang /* Map local indices to global indices */ 87738fb4e8eSJunchao Zhang PetscCall(DMGetLocalToGlobalMapping(da, <og)); 87838fb4e8eSJunchao Zhang PetscCall(ISLocalToGlobalMappingApply(ltog, m, gidxm, gidxm)); 87938fb4e8eSJunchao Zhang PetscFunctionReturn(0); 88038fb4e8eSJunchao Zhang } 88138fb4e8eSJunchao Zhang 88247c6ae99SBarry Smith /* 88347c6ae99SBarry Smith Creates "balanced" ownership ranges after refinement, constrained by the need for the 88447c6ae99SBarry Smith fine grid boundaries to fall within one stencil width of the coarse partition. 88547c6ae99SBarry Smith 88647c6ae99SBarry Smith Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 88747c6ae99SBarry Smith */ 888d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDARefineOwnershipRanges(DM da, PetscBool periodic, PetscInt stencil_width, PetscInt ratio, PetscInt m, const PetscInt lc[], PetscInt lf[]) 889d71ae5a4SJacob Faibussowitsch { 89047c6ae99SBarry Smith PetscInt i, totalc = 0, remaining, startc = 0, startf = 0; 89147c6ae99SBarry Smith 89247c6ae99SBarry Smith PetscFunctionBegin; 89363a3b9bcSJacob Faibussowitsch PetscCheck(ratio >= 1, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Requested refinement ratio %" PetscInt_FMT " must be at least 1", ratio); 89447c6ae99SBarry Smith if (ratio == 1) { 8959566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(lf, lc, m)); 89647c6ae99SBarry Smith PetscFunctionReturn(0); 89747c6ae99SBarry Smith } 89847c6ae99SBarry Smith for (i = 0; i < m; i++) totalc += lc[i]; 89947c6ae99SBarry Smith remaining = (!periodic) + ratio * (totalc - (!periodic)); 90047c6ae99SBarry Smith for (i = 0; i < m; i++) { 90147c6ae99SBarry Smith PetscInt want = remaining / (m - i) + !!(remaining % (m - i)); 90247c6ae99SBarry Smith if (i == m - 1) lf[i] = want; 90347c6ae99SBarry Smith else { 9047aca7175SJed Brown const PetscInt nextc = startc + lc[i]; 9057aca7175SJed Brown /* Move the first fine node of the next subdomain to the right until the coarse node on its left is within one 9067aca7175SJed Brown * coarse stencil width of the first coarse node in the next subdomain. */ 9077aca7175SJed Brown while ((startf + want) / ratio < nextc - stencil_width) want++; 9087aca7175SJed Brown /* Move the last fine node in the current subdomain to the left until the coarse node on its right is within one 9097aca7175SJed Brown * coarse stencil width of the last coarse node in the current subdomain. */ 9107aca7175SJed Brown while ((startf + want - 1 + ratio - 1) / ratio > nextc - 1 + stencil_width) want--; 9117aca7175SJed Brown /* Make sure all constraints are satisfied */ 9129371c9d4SSatish Balay if (want < 0 || want > remaining || ((startf + want) / ratio < nextc - stencil_width) || ((startf + want - 1 + ratio - 1) / ratio > nextc - 1 + stencil_width)) 9139371c9d4SSatish Balay SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_SIZ, "Could not find a compatible refined ownership range"); 91447c6ae99SBarry Smith } 91547c6ae99SBarry Smith lf[i] = want; 91647c6ae99SBarry Smith startc += lc[i]; 91747c6ae99SBarry Smith startf += lf[i]; 91847c6ae99SBarry Smith remaining -= lf[i]; 91947c6ae99SBarry Smith } 92047c6ae99SBarry Smith PetscFunctionReturn(0); 92147c6ae99SBarry Smith } 92247c6ae99SBarry Smith 9232be375d4SJed Brown /* 9242be375d4SJed Brown Creates "balanced" ownership ranges after coarsening, constrained by the need for the 9252be375d4SJed Brown fine grid boundaries to fall within one stencil width of the coarse partition. 9262be375d4SJed Brown 9272be375d4SJed Brown Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 9282be375d4SJed Brown */ 929d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDACoarsenOwnershipRanges(DM da, PetscBool periodic, PetscInt stencil_width, PetscInt ratio, PetscInt m, const PetscInt lf[], PetscInt lc[]) 930d71ae5a4SJacob Faibussowitsch { 9312be375d4SJed Brown PetscInt i, totalf, remaining, startc, startf; 9322be375d4SJed Brown 9332be375d4SJed Brown PetscFunctionBegin; 93463a3b9bcSJacob Faibussowitsch PetscCheck(ratio >= 1, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Requested refinement ratio %" PetscInt_FMT " must be at least 1", ratio); 9352be375d4SJed Brown if (ratio == 1) { 9369566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(lc, lf, m)); 9372be375d4SJed Brown PetscFunctionReturn(0); 9382be375d4SJed Brown } 9392be375d4SJed Brown for (i = 0, totalf = 0; i < m; i++) totalf += lf[i]; 9402be375d4SJed Brown remaining = (!periodic) + (totalf - (!periodic)) / ratio; 9412be375d4SJed Brown for (i = 0, startc = 0, startf = 0; i < m; i++) { 9422be375d4SJed Brown PetscInt want = remaining / (m - i) + !!(remaining % (m - i)); 9432be375d4SJed Brown if (i == m - 1) lc[i] = want; 9442be375d4SJed Brown else { 9452be375d4SJed Brown const PetscInt nextf = startf + lf[i]; 9462be375d4SJed Brown /* Slide first coarse node of next subdomain to the left until the coarse node to the left of the first fine 9472be375d4SJed Brown * node is within one stencil width. */ 9482be375d4SJed Brown while (nextf / ratio < startc + want - stencil_width) want--; 9492be375d4SJed Brown /* Slide the last coarse node of the current subdomain to the right until the coarse node to the right of the last 9502be375d4SJed Brown * fine node is within one stencil width. */ 9512be375d4SJed Brown while ((nextf - 1 + ratio - 1) / ratio > startc + want - 1 + stencil_width) want++; 9529371c9d4SSatish Balay if (want < 0 || want > remaining || (nextf / ratio < startc + want - stencil_width) || ((nextf - 1 + ratio - 1) / ratio > startc + want - 1 + stencil_width)) 9539371c9d4SSatish Balay SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_SIZ, "Could not find a compatible coarsened ownership range"); 9542be375d4SJed Brown } 9552be375d4SJed Brown lc[i] = want; 9562be375d4SJed Brown startc += lc[i]; 9572be375d4SJed Brown startf += lf[i]; 9582be375d4SJed Brown remaining -= lc[i]; 9592be375d4SJed Brown } 9602be375d4SJed Brown PetscFunctionReturn(0); 9612be375d4SJed Brown } 9622be375d4SJed Brown 963d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine_DA(DM da, MPI_Comm comm, DM *daref) 964d71ae5a4SJacob Faibussowitsch { 965c73cfb54SMatthew G. Knepley PetscInt M, N, P, i, dim; 9666858538eSMatthew G. Knepley Vec coordsc, coordsf; 9679a42bb27SBarry Smith DM da2; 96847c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data, *dd2; 96947c6ae99SBarry Smith 97047c6ae99SBarry Smith PetscFunctionBegin; 971a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 97247c6ae99SBarry Smith PetscValidPointer(daref, 3); 97347c6ae99SBarry Smith 9749566063dSJacob Faibussowitsch PetscCall(DMGetDimension(da, &dim)); 975bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 97647c6ae99SBarry Smith M = dd->refine_x * dd->M; 97747c6ae99SBarry Smith } else { 97847c6ae99SBarry Smith M = 1 + dd->refine_x * (dd->M - 1); 97947c6ae99SBarry Smith } 980bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 981c73cfb54SMatthew G. Knepley if (dim > 1) { 98247c6ae99SBarry Smith N = dd->refine_y * dd->N; 98347c6ae99SBarry Smith } else { 9841860e6e9SBarry Smith N = 1; 9851860e6e9SBarry Smith } 9861860e6e9SBarry Smith } else { 98747c6ae99SBarry Smith N = 1 + dd->refine_y * (dd->N - 1); 98847c6ae99SBarry Smith } 989bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 990c73cfb54SMatthew G. Knepley if (dim > 2) { 99147c6ae99SBarry Smith P = dd->refine_z * dd->P; 99247c6ae99SBarry Smith } else { 9931860e6e9SBarry Smith P = 1; 9941860e6e9SBarry Smith } 9951860e6e9SBarry Smith } else { 99647c6ae99SBarry Smith P = 1 + dd->refine_z * (dd->P - 1); 99747c6ae99SBarry Smith } 9989566063dSJacob Faibussowitsch PetscCall(DMDACreate(PetscObjectComm((PetscObject)da), &da2)); 9999566063dSJacob Faibussowitsch PetscCall(DMSetOptionsPrefix(da2, ((PetscObject)da)->prefix)); 10009566063dSJacob Faibussowitsch PetscCall(DMSetDimension(da2, dim)); 10019566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(da2, M, N, P)); 10029566063dSJacob Faibussowitsch PetscCall(DMDASetNumProcs(da2, dd->m, dd->n, dd->p)); 10039566063dSJacob Faibussowitsch PetscCall(DMDASetBoundaryType(da2, dd->bx, dd->by, dd->bz)); 10049566063dSJacob Faibussowitsch PetscCall(DMDASetDof(da2, dd->w)); 10059566063dSJacob Faibussowitsch PetscCall(DMDASetStencilType(da2, dd->stencil_type)); 10069566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(da2, dd->s)); 1007c73cfb54SMatthew G. Knepley if (dim == 3) { 100847c6ae99SBarry Smith PetscInt *lx, *ly, *lz; 10099566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(dd->m, &lx, dd->n, &ly, dd->p, &lz)); 10109566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da, (PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->refine_x, dd->m, dd->lx, lx)); 10119566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da, (PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->refine_y, dd->n, dd->ly, ly)); 10129566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da, (PetscBool)(dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->refine_z, dd->p, dd->lz, lz)); 10139566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(da2, lx, ly, lz)); 10149566063dSJacob Faibussowitsch PetscCall(PetscFree3(lx, ly, lz)); 1015c73cfb54SMatthew G. Knepley } else if (dim == 2) { 101647c6ae99SBarry Smith PetscInt *lx, *ly; 10179566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(dd->m, &lx, dd->n, &ly)); 10189566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da, (PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->refine_x, dd->m, dd->lx, lx)); 10199566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da, (PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->refine_y, dd->n, dd->ly, ly)); 10209566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(da2, lx, ly, NULL)); 10219566063dSJacob Faibussowitsch PetscCall(PetscFree2(lx, ly)); 1022c73cfb54SMatthew G. Knepley } else if (dim == 1) { 102347c6ae99SBarry Smith PetscInt *lx; 10249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->m, &lx)); 10259566063dSJacob Faibussowitsch PetscCall(DMDARefineOwnershipRanges(da, (PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->refine_x, dd->m, dd->lx, lx)); 10269566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(da2, lx, NULL, NULL)); 10279566063dSJacob Faibussowitsch PetscCall(PetscFree(lx)); 102847c6ae99SBarry Smith } 102947c6ae99SBarry Smith dd2 = (DM_DA *)da2->data; 103047c6ae99SBarry Smith 103147c6ae99SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 103225296bd5SBarry Smith da2->ops->creatematrix = da->ops->creatematrix; 103325296bd5SBarry Smith /* da2->ops->createinterpolation = da->ops->createinterpolation; this causes problem with SNESVI */ 103447c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 103547c6ae99SBarry Smith dd2->interptype = dd->interptype; 103647c6ae99SBarry Smith 103747c6ae99SBarry Smith /* copy fill information if given */ 103847c6ae99SBarry Smith if (dd->dfill) { 10399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->dfill[dd->w] + dd->w + 1, &dd2->dfill)); 10409566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->dfill, dd->dfill, dd->dfill[dd->w] + dd->w + 1)); 104147c6ae99SBarry Smith } 104247c6ae99SBarry Smith if (dd->ofill) { 10439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->ofill[dd->w] + dd->w + 1, &dd2->ofill)); 10449566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->ofill, dd->ofill, dd->ofill[dd->w] + dd->w + 1)); 104547c6ae99SBarry Smith } 104647c6ae99SBarry Smith /* copy the refine information */ 1047397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->refine_x; 1048397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->refine_y; 1049397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->refine_z; 105047c6ae99SBarry Smith 1051897f7067SBarry Smith if (dd->refine_z_hier) { 1052ad540459SPierre Jolivet if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_z_hier_n) dd2->refine_z = dd->refine_z_hier[da->levelup - da->leveldown + 1]; 1053ad540459SPierre Jolivet if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_z_hier_n) dd2->coarsen_z = dd->refine_z_hier[da->levelup - da->leveldown]; 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) { 1059ad540459SPierre Jolivet if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_y_hier_n) dd2->refine_y = dd->refine_y_hier[da->levelup - da->leveldown + 1]; 1060ad540459SPierre Jolivet if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_y_hier_n) dd2->coarsen_y = dd->refine_y_hier[da->levelup - da->leveldown]; 1061897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 10629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_y_hier_n, &dd2->refine_y_hier)); 10639566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_y_hier, dd->refine_y_hier, dd2->refine_y_hier_n)); 1064897f7067SBarry Smith } 1065897f7067SBarry Smith if (dd->refine_x_hier) { 1066ad540459SPierre Jolivet if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_x_hier_n) dd2->refine_x = dd->refine_x_hier[da->levelup - da->leveldown + 1]; 1067ad540459SPierre Jolivet if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_x_hier_n) dd2->coarsen_x = dd->refine_x_hier[da->levelup - da->leveldown]; 1068897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 10699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_x_hier_n, &dd2->refine_x_hier)); 10709566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_x_hier, dd->refine_x_hier, dd2->refine_x_hier_n)); 1071897f7067SBarry Smith } 1072897f7067SBarry Smith 107347c6ae99SBarry Smith /* copy vector type information */ 10749566063dSJacob Faibussowitsch PetscCall(DMSetVecType(da2, da->vectype)); 1075ddcf8b74SDave May 1076efd51863SBarry Smith dd2->lf = dd->lf; 1077efd51863SBarry Smith dd2->lj = dd->lj; 1078efd51863SBarry Smith 10796e87535bSJed Brown da2->leveldown = da->leveldown; 10806e87535bSJed Brown da2->levelup = da->levelup + 1; 10818865f1eaSKarl Rupp 10829566063dSJacob Faibussowitsch PetscCall(DMSetUp(da2)); 10836e87535bSJed Brown 1084ddcf8b74SDave May /* interpolate coordinates if they are set on the coarse grid */ 10856858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(da, &coordsc)); 10866858538eSMatthew G. Knepley if (coordsc) { 1087ddcf8b74SDave May DM cdaf, cdac; 1088ddcf8b74SDave May Mat II; 1089ddcf8b74SDave May 10909566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(da, &cdac)); 10919566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(da2, &cdaf)); 1092b61d3410SDave May /* force creation of the coordinate vector */ 10939566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(da2, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0)); 10949566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(da2, &coordsf)); 10959566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(cdac, cdaf, &II, NULL)); 10969566063dSJacob Faibussowitsch PetscCall(MatInterpolate(II, coordsc, coordsf)); 10979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&II)); 1098ddcf8b74SDave May } 1099397b6216SJed Brown 1100f3141302SJed Brown for (i = 0; i < da->bs; i++) { 1101f3141302SJed Brown const char *fieldname; 11029566063dSJacob Faibussowitsch PetscCall(DMDAGetFieldName(da, i, &fieldname)); 11039566063dSJacob Faibussowitsch PetscCall(DMDASetFieldName(da2, i, fieldname)); 1104f3141302SJed Brown } 1105397b6216SJed Brown 110647c6ae99SBarry Smith *daref = da2; 110747c6ae99SBarry Smith PetscFunctionReturn(0); 110847c6ae99SBarry Smith } 110947c6ae99SBarry Smith 1110d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen_DA(DM dmf, MPI_Comm comm, DM *dmc) 1111d71ae5a4SJacob Faibussowitsch { 1112c73cfb54SMatthew G. Knepley PetscInt M, N, P, i, dim; 11136858538eSMatthew G. Knepley Vec coordsc, coordsf; 1114a5bc1bf3SBarry Smith DM dmc2; 1115a5bc1bf3SBarry Smith DM_DA *dd = (DM_DA *)dmf->data, *dd2; 111647c6ae99SBarry Smith 111747c6ae99SBarry Smith PetscFunctionBegin; 1118a5bc1bf3SBarry Smith PetscValidHeaderSpecificType(dmf, DM_CLASSID, 1, DMDA); 1119a5bc1bf3SBarry Smith PetscValidPointer(dmc, 3); 112047c6ae99SBarry Smith 11219566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dmf, &dim)); 1122bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1123397b6216SJed Brown M = dd->M / dd->coarsen_x; 112447c6ae99SBarry Smith } else { 1125397b6216SJed Brown M = 1 + (dd->M - 1) / dd->coarsen_x; 112647c6ae99SBarry Smith } 1127bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1128c73cfb54SMatthew G. Knepley if (dim > 1) { 1129397b6216SJed Brown N = dd->N / dd->coarsen_y; 113047c6ae99SBarry Smith } else { 11311860e6e9SBarry Smith N = 1; 11321860e6e9SBarry Smith } 11331860e6e9SBarry Smith } else { 1134397b6216SJed Brown N = 1 + (dd->N - 1) / dd->coarsen_y; 113547c6ae99SBarry Smith } 1136bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1137c73cfb54SMatthew G. Knepley if (dim > 2) { 1138397b6216SJed Brown P = dd->P / dd->coarsen_z; 113947c6ae99SBarry Smith } else { 11401860e6e9SBarry Smith P = 1; 11411860e6e9SBarry Smith } 11421860e6e9SBarry Smith } else { 1143397b6216SJed Brown P = 1 + (dd->P - 1) / dd->coarsen_z; 114447c6ae99SBarry Smith } 11459566063dSJacob Faibussowitsch PetscCall(DMDACreate(PetscObjectComm((PetscObject)dmf), &dmc2)); 11469566063dSJacob Faibussowitsch PetscCall(DMSetOptionsPrefix(dmc2, ((PetscObject)dmf)->prefix)); 11479566063dSJacob Faibussowitsch PetscCall(DMSetDimension(dmc2, dim)); 11489566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(dmc2, M, N, P)); 11499566063dSJacob Faibussowitsch PetscCall(DMDASetNumProcs(dmc2, dd->m, dd->n, dd->p)); 11509566063dSJacob Faibussowitsch PetscCall(DMDASetBoundaryType(dmc2, dd->bx, dd->by, dd->bz)); 11519566063dSJacob Faibussowitsch PetscCall(DMDASetDof(dmc2, dd->w)); 11529566063dSJacob Faibussowitsch PetscCall(DMDASetStencilType(dmc2, dd->stencil_type)); 11539566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(dmc2, dd->s)); 1154c73cfb54SMatthew G. Knepley if (dim == 3) { 11552be375d4SJed Brown PetscInt *lx, *ly, *lz; 11569566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(dd->m, &lx, dd->n, &ly, dd->p, &lz)); 11579566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf, (PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->coarsen_x, dd->m, dd->lx, lx)); 11589566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf, (PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->coarsen_y, dd->n, dd->ly, ly)); 11599566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf, (PetscBool)(dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->coarsen_z, dd->p, dd->lz, lz)); 11609566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(dmc2, lx, ly, lz)); 11619566063dSJacob Faibussowitsch PetscCall(PetscFree3(lx, ly, lz)); 1162c73cfb54SMatthew G. Knepley } else if (dim == 2) { 11632be375d4SJed Brown PetscInt *lx, *ly; 11649566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(dd->m, &lx, dd->n, &ly)); 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(DMDASetOwnershipRanges(dmc2, lx, ly, NULL)); 11689566063dSJacob Faibussowitsch PetscCall(PetscFree2(lx, ly)); 1169c73cfb54SMatthew G. Knepley } else if (dim == 1) { 11702be375d4SJed Brown PetscInt *lx; 11719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->m, &lx)); 11729566063dSJacob Faibussowitsch PetscCall(DMDACoarsenOwnershipRanges(dmf, (PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0), dd->s, dd->coarsen_x, dd->m, dd->lx, lx)); 11739566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(dmc2, lx, NULL, NULL)); 11749566063dSJacob Faibussowitsch PetscCall(PetscFree(lx)); 117547c6ae99SBarry Smith } 1176a5bc1bf3SBarry Smith dd2 = (DM_DA *)dmc2->data; 117747c6ae99SBarry Smith 11784dcab191SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones; why are only some inherited and not all? */ 1179a5bc1bf3SBarry Smith /* dmc2->ops->createinterpolation = dmf->ops->createinterpolation; copying this one causes trouble for DMSetVI */ 1180a5bc1bf3SBarry Smith dmc2->ops->creatematrix = dmf->ops->creatematrix; 1181a5bc1bf3SBarry Smith dmc2->ops->getcoloring = dmf->ops->getcoloring; 118247c6ae99SBarry Smith dd2->interptype = dd->interptype; 118347c6ae99SBarry Smith 118447c6ae99SBarry Smith /* copy fill information if given */ 118547c6ae99SBarry Smith if (dd->dfill) { 11869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->dfill[dd->w] + dd->w + 1, &dd2->dfill)); 11879566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->dfill, dd->dfill, dd->dfill[dd->w] + dd->w + 1)); 118847c6ae99SBarry Smith } 118947c6ae99SBarry Smith if (dd->ofill) { 11909566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->ofill[dd->w] + dd->w + 1, &dd2->ofill)); 11919566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->ofill, dd->ofill, dd->ofill[dd->w] + dd->w + 1)); 119247c6ae99SBarry Smith } 119347c6ae99SBarry Smith /* copy the refine information */ 1194397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->coarsen_x; 1195397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->coarsen_y; 1196397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->coarsen_z; 119747c6ae99SBarry Smith 1198897f7067SBarry Smith if (dd->refine_z_hier) { 1199ad540459SPierre Jolivet if (dmf->levelup - dmf->leveldown - 1 > -1 && dmf->levelup - dmf->leveldown - 1 < dd->refine_z_hier_n) dd2->refine_z = dd->refine_z_hier[dmf->levelup - dmf->leveldown - 1]; 1200ad540459SPierre Jolivet if (dmf->levelup - dmf->leveldown - 2 > -1 && dmf->levelup - dmf->leveldown - 2 < dd->refine_z_hier_n) dd2->coarsen_z = dd->refine_z_hier[dmf->levelup - dmf->leveldown - 2]; 1201897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 12029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_z_hier_n, &dd2->refine_z_hier)); 12039566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_z_hier, dd->refine_z_hier, dd2->refine_z_hier_n)); 1204897f7067SBarry Smith } 1205897f7067SBarry Smith if (dd->refine_y_hier) { 1206ad540459SPierre Jolivet if (dmf->levelup - dmf->leveldown - 1 > -1 && dmf->levelup - dmf->leveldown - 1 < dd->refine_y_hier_n) dd2->refine_y = dd->refine_y_hier[dmf->levelup - dmf->leveldown - 1]; 1207ad540459SPierre Jolivet if (dmf->levelup - dmf->leveldown - 2 > -1 && dmf->levelup - dmf->leveldown - 2 < dd->refine_y_hier_n) dd2->coarsen_y = dd->refine_y_hier[dmf->levelup - dmf->leveldown - 2]; 1208897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 12099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_y_hier_n, &dd2->refine_y_hier)); 12109566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_y_hier, dd->refine_y_hier, dd2->refine_y_hier_n)); 1211897f7067SBarry Smith } 1212897f7067SBarry Smith if (dd->refine_x_hier) { 1213ad540459SPierre Jolivet if (dmf->levelup - dmf->leveldown - 1 > -1 && dmf->levelup - dmf->leveldown - 1 < dd->refine_x_hier_n) dd2->refine_x = dd->refine_x_hier[dmf->levelup - dmf->leveldown - 1]; 1214ad540459SPierre Jolivet if (dmf->levelup - dmf->leveldown - 2 > -1 && dmf->levelup - dmf->leveldown - 2 < dd->refine_x_hier_n) dd2->coarsen_x = dd->refine_x_hier[dmf->levelup - dmf->leveldown - 2]; 1215897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 12169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->refine_x_hier_n, &dd2->refine_x_hier)); 12179566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(dd2->refine_x_hier, dd->refine_x_hier, dd2->refine_x_hier_n)); 1218897f7067SBarry Smith } 1219897f7067SBarry Smith 122047c6ae99SBarry Smith /* copy vector type information */ 12219566063dSJacob Faibussowitsch PetscCall(DMSetVecType(dmc2, dmf->vectype)); 122247c6ae99SBarry Smith 1223644e2e5bSBarry Smith dd2->lf = dd->lf; 1224644e2e5bSBarry Smith dd2->lj = dd->lj; 1225644e2e5bSBarry Smith 1226a5bc1bf3SBarry Smith dmc2->leveldown = dmf->leveldown + 1; 1227a5bc1bf3SBarry Smith dmc2->levelup = dmf->levelup; 12288865f1eaSKarl Rupp 12299566063dSJacob Faibussowitsch PetscCall(DMSetUp(dmc2)); 12306e87535bSJed Brown 1231ddcf8b74SDave May /* inject coordinates if they are set on the fine grid */ 12326858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dmf, &coordsf)); 12336858538eSMatthew G. Knepley if (coordsf) { 1234ddcf8b74SDave May DM cdaf, cdac; 12356dbf9973SLawrence Mitchell Mat inject; 12366dbf9973SLawrence Mitchell VecScatter vscat; 1237ddcf8b74SDave May 12389566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dmf, &cdaf)); 12399566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dmc2, &cdac)); 1240b61d3410SDave May /* force creation of the coordinate vector */ 12419566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(dmc2, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0)); 12429566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dmc2, &coordsc)); 1243ddcf8b74SDave May 12449566063dSJacob Faibussowitsch PetscCall(DMCreateInjection(cdac, cdaf, &inject)); 12459566063dSJacob Faibussowitsch PetscCall(MatScatterGetVecScatter(inject, &vscat)); 12469566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(vscat, coordsf, coordsc, INSERT_VALUES, SCATTER_FORWARD)); 12479566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(vscat, coordsf, coordsc, INSERT_VALUES, SCATTER_FORWARD)); 12489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&inject)); 1249ddcf8b74SDave May } 1250f98405f7SJed Brown 1251a5bc1bf3SBarry Smith for (i = 0; i < dmf->bs; i++) { 1252f98405f7SJed Brown const char *fieldname; 12539566063dSJacob Faibussowitsch PetscCall(DMDAGetFieldName(dmf, i, &fieldname)); 12549566063dSJacob Faibussowitsch PetscCall(DMDASetFieldName(dmc2, i, fieldname)); 1255f98405f7SJed Brown } 1256f98405f7SJed Brown 1257a5bc1bf3SBarry Smith *dmc = dmc2; 125847c6ae99SBarry Smith PetscFunctionReturn(0); 125947c6ae99SBarry Smith } 126047c6ae99SBarry Smith 1261d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy_DA(DM da, PetscInt nlevels, DM daf[]) 1262d71ae5a4SJacob Faibussowitsch { 126347c6ae99SBarry Smith PetscInt i, n, *refx, *refy, *refz; 126447c6ae99SBarry Smith 126547c6ae99SBarry Smith PetscFunctionBegin; 126647c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 12677a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 126847c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 126947c6ae99SBarry Smith PetscValidPointer(daf, 3); 127047c6ae99SBarry Smith 1271aa219208SBarry Smith /* Get refinement factors, defaults taken from the coarse DMDA */ 12729566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nlevels, &refx, nlevels, &refy, nlevels, &refz)); 127348a46eb9SPierre Jolivet for (i = 0; i < nlevels; i++) PetscCall(DMDAGetRefinementFactor(da, &refx[i], &refy[i], &refz[i])); 127447c6ae99SBarry Smith n = nlevels; 12759566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(((PetscObject)da)->options, ((PetscObject)da)->prefix, "-da_refine_hierarchy_x", refx, &n, NULL)); 127647c6ae99SBarry Smith n = nlevels; 12779566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(((PetscObject)da)->options, ((PetscObject)da)->prefix, "-da_refine_hierarchy_y", refy, &n, NULL)); 127847c6ae99SBarry Smith n = nlevels; 12799566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(((PetscObject)da)->options, ((PetscObject)da)->prefix, "-da_refine_hierarchy_z", refz, &n, NULL)); 128047c6ae99SBarry Smith 12819566063dSJacob Faibussowitsch PetscCall(DMDASetRefinementFactor(da, refx[0], refy[0], refz[0])); 12829566063dSJacob Faibussowitsch PetscCall(DMRefine(da, PetscObjectComm((PetscObject)da), &daf[0])); 128347c6ae99SBarry Smith for (i = 1; i < nlevels; i++) { 12849566063dSJacob Faibussowitsch PetscCall(DMDASetRefinementFactor(daf[i - 1], refx[i], refy[i], refz[i])); 12859566063dSJacob Faibussowitsch PetscCall(DMRefine(daf[i - 1], PetscObjectComm((PetscObject)da), &daf[i])); 128647c6ae99SBarry Smith } 12879566063dSJacob Faibussowitsch PetscCall(PetscFree3(refx, refy, refz)); 128847c6ae99SBarry Smith PetscFunctionReturn(0); 128947c6ae99SBarry Smith } 129047c6ae99SBarry Smith 1291d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy_DA(DM da, PetscInt nlevels, DM dac[]) 1292d71ae5a4SJacob Faibussowitsch { 129347c6ae99SBarry Smith PetscInt i; 129447c6ae99SBarry Smith 129547c6ae99SBarry Smith PetscFunctionBegin; 129647c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 12977a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 129847c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 129947c6ae99SBarry Smith PetscValidPointer(dac, 3); 13009566063dSJacob Faibussowitsch PetscCall(DMCoarsen(da, PetscObjectComm((PetscObject)da), &dac[0])); 130148a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dac[i - 1], PetscObjectComm((PetscObject)da), &dac[i])); 130247c6ae99SBarry Smith PetscFunctionReturn(0); 130347c6ae99SBarry Smith } 130462197512SBarry Smith 1305d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetGLLCoordinates_1d(DM dm, PetscInt n, PetscReal *nodes) 1306d71ae5a4SJacob Faibussowitsch { 13078272889dSSatish Balay PetscInt i, j, xs, xn, q; 130862197512SBarry Smith PetscScalar *xx; 130962197512SBarry Smith PetscReal h; 131062197512SBarry Smith Vec x; 131162197512SBarry Smith DM_DA *da = (DM_DA *)dm->data; 131262197512SBarry Smith 131362197512SBarry Smith PetscFunctionBegin; 131462197512SBarry Smith if (da->bx != DM_BOUNDARY_PERIODIC) { 13159566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(dm, NULL, &q, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); 131662197512SBarry Smith q = (q - 1) / (n - 1); /* number of spectral elements */ 131762197512SBarry Smith h = 2.0 / q; 13189566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(dm, &xs, NULL, NULL, &xn, NULL, NULL)); 131962197512SBarry Smith xs = xs / (n - 1); 132062197512SBarry Smith xn = xn / (n - 1); 13219566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(dm, -1., 1., 0., 0., 0., 0.)); 13229566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &x)); 13239566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(dm, x, &xx)); 132462197512SBarry Smith 132562197512SBarry Smith /* loop over local spectral elements */ 132662197512SBarry Smith for (j = xs; j < xs + xn; j++) { 132762197512SBarry Smith /* 132862197512SBarry Smith Except for the first process, each process starts on the second GLL point of the first element on that process 132962197512SBarry Smith */ 1330ad540459SPierre Jolivet for (i = (j == xs && xs > 0) ? 1 : 0; i < n; i++) xx[j * (n - 1) + i] = -1.0 + h * j + h * (nodes[i] + 1.0) / 2.; 133162197512SBarry Smith } 13329566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(dm, x, &xx)); 133362197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented for periodic"); 133462197512SBarry Smith PetscFunctionReturn(0); 133562197512SBarry Smith } 133662197512SBarry Smith 13371fd49c25SBarry Smith /*@ 133862197512SBarry Smith 133962197512SBarry 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 134062197512SBarry Smith 1341d083f849SBarry Smith Collective on da 134262197512SBarry Smith 134362197512SBarry Smith Input Parameters: 1344*dce8aebaSBarry Smith + da - the `DMDA` object 13458272889dSSatish Balay - n - the number of GLL nodes 13468272889dSSatish Balay - nodes - the GLL nodes 134762197512SBarry Smith 1348edc382c3SSatish Balay Level: advanced 1349edc382c3SSatish Balay 1350*dce8aebaSBarry Smith Note: 1351*dce8aebaSBarry Smith The parallel decomposition of grid points must correspond to the degree of the GLL. That is, the number of grid points 1352*dce8aebaSBarry Smith on each process much be divisible by the number of GLL elements needed per process. This depends on whether the `DM` is 1353*dce8aebaSBarry Smith periodic or not. 1354*dce8aebaSBarry Smith 1355*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate()`, `PetscDTGaussLobattoLegendreQuadrature()`, `DMGetCoordinates()` 135662197512SBarry Smith @*/ 1357d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetGLLCoordinates(DM da, PetscInt n, PetscReal *nodes) 1358d71ae5a4SJacob Faibussowitsch { 135962197512SBarry Smith PetscFunctionBegin; 136062197512SBarry Smith if (da->dim == 1) { 13619566063dSJacob Faibussowitsch PetscCall(DMDASetGLLCoordinates_1d(da, n, nodes)); 136262197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented for 2 or 3d"); 136362197512SBarry Smith PetscFunctionReturn(0); 136462197512SBarry Smith } 13657c3cd84eSPatrick Sanan 1366d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode DMGetCompatibility_DA(DM da1, DM dm2, PetscBool *compatible, PetscBool *set) 1367d71ae5a4SJacob Faibussowitsch { 13687c3cd84eSPatrick Sanan DM_DA *dd1 = (DM_DA *)da1->data, *dd2; 13697c3cd84eSPatrick Sanan DM da2; 13707c3cd84eSPatrick Sanan DMType dmtype2; 13717c3cd84eSPatrick Sanan PetscBool isda, compatibleLocal; 13727c3cd84eSPatrick Sanan PetscInt i; 13737c3cd84eSPatrick Sanan 13747c3cd84eSPatrick Sanan PetscFunctionBegin; 13757a8be351SBarry Smith PetscCheck(da1->setupcalled, PetscObjectComm((PetscObject)da1), PETSC_ERR_ARG_WRONGSTATE, "DMSetUp() must be called on first DM before DMGetCompatibility()"); 13769566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &dmtype2)); 13779566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(dmtype2, DMDA, &isda)); 13787c3cd84eSPatrick Sanan if (isda) { 13797c3cd84eSPatrick Sanan da2 = dm2; 13807c3cd84eSPatrick Sanan dd2 = (DM_DA *)da2->data; 13817a8be351SBarry Smith PetscCheck(da2->setupcalled, PetscObjectComm((PetscObject)da2), PETSC_ERR_ARG_WRONGSTATE, "DMSetUp() must be called on second DM before DMGetCompatibility()"); 1382110623a0SKarl Rupp compatibleLocal = (PetscBool)(da1->dim == da2->dim); 1383c790a739SKarl Rupp if (compatibleLocal) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->s == dd2->s)); /* Stencil width */ 1384110623a0SKarl Rupp /* Global size ranks Boundary type */ 1385c790a739SKarl Rupp if (compatibleLocal) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->M == dd2->M) && (dd1->m == dd2->m) && (dd1->bx == dd2->bx)); 1386c790a739SKarl Rupp if (compatibleLocal && da1->dim > 1) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->N == dd2->N) && (dd1->n == dd2->n) && (dd1->by == dd2->by)); 1387c790a739SKarl Rupp if (compatibleLocal && da1->dim > 2) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->P == dd2->P) && (dd1->p == dd2->p) && (dd1->bz == dd2->bz)); 13887c3cd84eSPatrick Sanan if (compatibleLocal) { 13899371c9d4SSatish Balay for (i = 0; i < dd1->m; ++i) { compatibleLocal = (PetscBool)(compatibleLocal && (dd1->lx[i] == dd2->lx[i])); /* Local size */ } 13907c3cd84eSPatrick Sanan } 13917c3cd84eSPatrick Sanan if (compatibleLocal && da1->dim > 1) { 1392ad540459SPierre Jolivet for (i = 0; i < dd1->n; ++i) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->ly[i] == dd2->ly[i])); 13937c3cd84eSPatrick Sanan } 13947c3cd84eSPatrick Sanan if (compatibleLocal && da1->dim > 2) { 1395ad540459SPierre Jolivet for (i = 0; i < dd1->p; ++i) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->lz[i] == dd2->lz[i])); 13967c3cd84eSPatrick Sanan } 13977c3cd84eSPatrick Sanan *compatible = compatibleLocal; 13987c3cd84eSPatrick Sanan *set = PETSC_TRUE; 13997c3cd84eSPatrick Sanan } else { 14007c3cd84eSPatrick Sanan /* Decline to determine compatibility with other DM types */ 14017c3cd84eSPatrick Sanan *set = PETSC_FALSE; 14027c3cd84eSPatrick Sanan } 14037c3cd84eSPatrick Sanan PetscFunctionReturn(0); 14047c3cd84eSPatrick Sanan } 1405