1af0996ceSBarry Smith #include <petsc/private/dmpatchimpl.h> /*I "petscdmpatch.h" I*/
23a19ef87SMatthew G Knepley #include <petscdmda.h>
30c312b8eSJed Brown #include <petscsf.h>
43a19ef87SMatthew G Knepley
55ee0e871SMatthew G Knepley /*
65ee0e871SMatthew G Knepley Solver loop to update \tau:
75ee0e871SMatthew G Knepley
85ee0e871SMatthew G Knepley DMZoom(dmc, &dmz)
95ee0e871SMatthew G Knepley DMRefine(dmz, &dmf),
105ee0e871SMatthew G Knepley Scatter Xcoarse -> Xzoom,
115ee0e871SMatthew G Knepley Interpolate Xzoom -> Xfine (note that this may be on subcomms),
125ee0e871SMatthew G Knepley Smooth Xfine using two-step smoother
135ee0e871SMatthew G Knepley normal smoother plus Kaczmarz---moves back and forth from dmzoom to dmfine
145ee0e871SMatthew G Knepley Compute residual Rfine
155ee0e871SMatthew G Knepley Restrict Rfine to Rzoom_restricted
165ee0e871SMatthew G Knepley Scatter Rzoom_restricted -> Rcoarse_restricted
175ee0e871SMatthew G Knepley Compute global residual Rcoarse
185ee0e871SMatthew G Knepley TauCoarse = Rcoarse - Rcoarse_restricted
195ee0e871SMatthew G Knepley */
205ee0e871SMatthew G Knepley
215d83a8b1SBarry Smith /*@
2220f4b53cSBarry Smith DMPatchZoom - Create patches of a `DMDA` on subsets of processes, indicated by `commz`
2359583ba0SMatthew G Knepley
2420f4b53cSBarry Smith Collective
25a487c981SJed Brown
2659583ba0SMatthew G Knepley Input Parameters:
2720f4b53cSBarry Smith + dm - the `DM`
28c969029dSPierre Jolivet . lower - the lower left corner of the requested patch
29c969029dSPierre Jolivet . upper - the upper right corner of the requested patch
3020f4b53cSBarry Smith - commz - the new communicator for the patch, `MPI_COMM_NULL` indicates that the given rank will not own a patch
3159583ba0SMatthew G Knepley
3259583ba0SMatthew G Knepley Output Parameters:
3320f4b53cSBarry Smith + dmz - the patch `DM`
3420f4b53cSBarry Smith . sfz - the `PetscSF` mapping the patch+halo to the zoomed version (optional)
3520f4b53cSBarry Smith - sfzr - the `PetscSF` mapping the patch to the restricted zoomed version
3659583ba0SMatthew G Knepley
3759583ba0SMatthew G Knepley Level: intermediate
3859583ba0SMatthew G Knepley
39db781477SPatrick Sanan .seealso: `DMPatchSolve()`, `DMDACreatePatchIS()`
4060c22052SBarry Smith @*/
DMPatchZoom(DM dm,MatStencil lower,MatStencil upper,MPI_Comm commz,DM * dmz,PeOp PetscSF * sfz,PeOp PetscSF * sfzr)41ce78bad3SBarry Smith PetscErrorCode DMPatchZoom(DM dm, MatStencil lower, MatStencil upper, MPI_Comm commz, DM *dmz, PeOp PetscSF *sfz, PeOp PetscSF *sfzr)
42d71ae5a4SJacob Faibussowitsch {
4359583ba0SMatthew G Knepley DMDAStencilType st;
44bd1050a3SMatthew G Knepley MatStencil blower, bupper, loclower, locupper;
45bd1050a3SMatthew G Knepley IS is;
46bd1050a3SMatthew G Knepley const PetscInt *ranges, *indices;
470298fd71SBarry Smith PetscInt *localPoints = NULL;
480298fd71SBarry Smith PetscSFNode *remotePoints = NULL;
49392fa6c6SMatthew G Knepley PetscInt dim, dof;
5060c22052SBarry Smith PetscInt M, N, P, rM, rN, rP, halo = 1, sxb, syb, szb, sxr, syr, szr, exr, eyr, ezr, mxb, myb, mzb, i, j, k, l, q;
51bd1050a3SMatthew G Knepley PetscMPIInt size;
523b5e53cdSSajid Ali PetscBool patchis_offproc = PETSC_TRUE;
5360c22052SBarry Smith Vec X;
5459583ba0SMatthew G Knepley
5559583ba0SMatthew G Knepley PetscFunctionBegin;
5660c22052SBarry Smith if (!sfz) halo = 0;
579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size));
5859583ba0SMatthew G Knepley /* Create patch DM */
599566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(dm, &dim, &M, &N, &P, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, &st));
60a07761baSMatthew G Knepley
61a07761baSMatthew G Knepley /* Get piece for rank r, expanded by halo */
629371c9d4SSatish Balay bupper.i = PetscMin(M, upper.i + halo);
639371c9d4SSatish Balay blower.i = PetscMax(lower.i - halo, 0);
649371c9d4SSatish Balay bupper.j = PetscMin(N, upper.j + halo);
659371c9d4SSatish Balay blower.j = PetscMax(lower.j - halo, 0);
669371c9d4SSatish Balay bupper.k = PetscMin(P, upper.k + halo);
679371c9d4SSatish Balay blower.k = PetscMax(lower.k - halo, 0);
68392fa6c6SMatthew G Knepley rM = bupper.i - blower.i;
69392fa6c6SMatthew G Knepley rN = bupper.j - blower.j;
70392fa6c6SMatthew G Knepley rP = bupper.k - blower.k;
7159583ba0SMatthew G Knepley
72bb71ef15SMatthew G Knepley if (commz != MPI_COMM_NULL) {
739566063dSJacob Faibussowitsch PetscCall(DMDACreate(commz, dmz));
749566063dSJacob Faibussowitsch PetscCall(DMSetDimension(*dmz, dim));
759566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(*dmz, rM, rN, rP));
769566063dSJacob Faibussowitsch PetscCall(DMDASetNumProcs(*dmz, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE));
779566063dSJacob Faibussowitsch PetscCall(DMDASetBoundaryType(*dmz, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE));
789566063dSJacob Faibussowitsch PetscCall(DMDASetDof(*dmz, dof));
799566063dSJacob Faibussowitsch PetscCall(DMDASetStencilType(*dmz, st));
809566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(*dmz, 0));
819566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(*dmz, NULL, NULL, NULL));
829566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(*dmz));
839566063dSJacob Faibussowitsch PetscCall(DMSetUp(*dmz));
849566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(*dmz, &sxb, &syb, &szb, &mxb, &myb, &mzb));
85bd1050a3SMatthew G Knepley sxr = PetscMax(sxb, lower.i - blower.i);
86bd1050a3SMatthew G Knepley syr = PetscMax(syb, lower.j - blower.j);
87bd1050a3SMatthew G Knepley szr = PetscMax(szb, lower.k - blower.k);
88bd1050a3SMatthew G Knepley exr = PetscMin(sxb + mxb, upper.i - blower.i);
89bd1050a3SMatthew G Knepley eyr = PetscMin(syb + myb, upper.j - blower.j);
90bd1050a3SMatthew G Knepley ezr = PetscMin(szb + mzb, upper.k - blower.k);
919566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(dof * rM * rN * PetscMax(rP, 1), &localPoints, dof * rM * rN * PetscMax(rP, 1), &remotePoints));
92bb71ef15SMatthew G Knepley } else {
93bb71ef15SMatthew G Knepley sxr = syr = szr = exr = eyr = ezr = sxb = syb = szb = mxb = myb = mzb = 0;
94bb71ef15SMatthew G Knepley }
95392fa6c6SMatthew G Knepley
9659583ba0SMatthew G Knepley /* Create SF for restricted map */
979566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &X));
989566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRanges(X, &ranges));
998865f1eaSKarl Rupp
1009371c9d4SSatish Balay loclower.i = blower.i + sxr;
1019371c9d4SSatish Balay locupper.i = blower.i + exr;
1029371c9d4SSatish Balay loclower.j = blower.j + syr;
1039371c9d4SSatish Balay locupper.j = blower.j + eyr;
1049371c9d4SSatish Balay loclower.k = blower.k + szr;
1059371c9d4SSatish Balay locupper.k = blower.k + ezr;
1068865f1eaSKarl Rupp
1079566063dSJacob Faibussowitsch PetscCall(DMDACreatePatchIS(dm, &loclower, &locupper, &is, patchis_offproc));
1089566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &indices));
1098865f1eaSKarl Rupp
1109371c9d4SSatish Balay if (dim < 3) {
1119371c9d4SSatish Balay mzb = 1;
1129371c9d4SSatish Balay ezr = 1;
1139371c9d4SSatish Balay }
114392fa6c6SMatthew G Knepley q = 0;
115bd1050a3SMatthew G Knepley for (k = szb; k < szb + mzb; ++k) {
116bd1050a3SMatthew G Knepley if ((k < szr) || (k >= ezr)) continue;
117bd1050a3SMatthew G Knepley for (j = syb; j < syb + myb; ++j) {
118bd1050a3SMatthew G Knepley if ((j < syr) || (j >= eyr)) continue;
119bd1050a3SMatthew G Knepley for (i = sxb; i < sxb + mxb; ++i) {
12060c22052SBarry Smith for (l = 0; l < dof; l++) {
12160c22052SBarry Smith const PetscInt lp = l + dof * (((k - szb) * rN + (j - syb)) * rM + i - sxb);
1226497c311SBarry Smith PetscMPIInt r;
1236497c311SBarry Smith PetscInt ir;
124392fa6c6SMatthew G Knepley
125bd1050a3SMatthew G Knepley if ((i < sxr) || (i >= exr)) continue;
126392fa6c6SMatthew G Knepley localPoints[q] = lp;
1276497c311SBarry Smith PetscCall(PetscFindInt(indices[q], size + 1, ranges, &ir));
1286497c311SBarry Smith PetscCall(PetscMPIIntCast(ir, &r));
1298865f1eaSKarl Rupp
130bd1050a3SMatthew G Knepley remotePoints[q].rank = r < 0 ? -(r + 1) - 1 : r;
131bd1050a3SMatthew G Knepley remotePoints[q].index = indices[q] - ranges[remotePoints[q].rank];
132bd1050a3SMatthew G Knepley ++q;
133392fa6c6SMatthew G Knepley }
134392fa6c6SMatthew G Knepley }
135392fa6c6SMatthew G Knepley }
13660c22052SBarry Smith }
1379566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &indices));
1389566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is));
1399566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), sfzr));
1409566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*sfzr, "Restricted Map"));
1419566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(*sfzr, dof * M * N * P, q, localPoints, PETSC_COPY_VALUES, remotePoints, PETSC_COPY_VALUES));
142392fa6c6SMatthew G Knepley
14360c22052SBarry Smith if (sfz) {
144392fa6c6SMatthew G Knepley /* Create SF for buffered map */
1459371c9d4SSatish Balay loclower.i = blower.i + sxb;
1469371c9d4SSatish Balay locupper.i = blower.i + sxb + mxb;
1479371c9d4SSatish Balay loclower.j = blower.j + syb;
1489371c9d4SSatish Balay locupper.j = blower.j + syb + myb;
1499371c9d4SSatish Balay loclower.k = blower.k + szb;
1509371c9d4SSatish Balay locupper.k = blower.k + szb + mzb;
1518865f1eaSKarl Rupp
1529566063dSJacob Faibussowitsch PetscCall(DMDACreatePatchIS(dm, &loclower, &locupper, &is, patchis_offproc));
1539566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &indices));
1548865f1eaSKarl Rupp
155392fa6c6SMatthew G Knepley q = 0;
156392fa6c6SMatthew G Knepley for (k = szb; k < szb + mzb; ++k) {
157392fa6c6SMatthew G Knepley for (j = syb; j < syb + myb; ++j) {
158392fa6c6SMatthew G Knepley for (i = sxb; i < sxb + mxb; ++i, ++q) {
1596497c311SBarry Smith PetscInt ir;
1606497c311SBarry Smith PetscMPIInt r;
161392fa6c6SMatthew G Knepley
162bd1050a3SMatthew G Knepley localPoints[q] = q;
1636497c311SBarry Smith PetscCall(PetscFindInt(indices[q], size + 1, ranges, &ir));
1646497c311SBarry Smith PetscCall(PetscMPIIntCast(ir, &r));
165bd1050a3SMatthew G Knepley remotePoints[q].rank = r < 0 ? -(r + 1) - 1 : r;
166bd1050a3SMatthew G Knepley remotePoints[q].index = indices[q] - ranges[remotePoints[q].rank];
167392fa6c6SMatthew G Knepley }
168392fa6c6SMatthew G Knepley }
169392fa6c6SMatthew G Knepley }
1709566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &indices));
1719566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is));
1729566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), sfz));
1739566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*sfz, "Buffered Map"));
1749566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(*sfz, M * N * P, q, localPoints, PETSC_COPY_VALUES, remotePoints, PETSC_COPY_VALUES));
17560c22052SBarry Smith }
176392fa6c6SMatthew G Knepley
1779566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X));
1789566063dSJacob Faibussowitsch PetscCall(PetscFree2(localPoints, remotePoints));
1793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
18059583ba0SMatthew G Knepley }
18159583ba0SMatthew G Knepley
1829371c9d4SSatish Balay typedef enum {
1839371c9d4SSatish Balay PATCH_COMM_TYPE_WORLD = 0,
1849371c9d4SSatish Balay PATCH_COMM_TYPE_SELF = 1
1859371c9d4SSatish Balay } PatchCommType;
186bd1050a3SMatthew G Knepley
DMPatchSolve(DM dm)187d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPatchSolve(DM dm)
188d71ae5a4SJacob Faibussowitsch {
1896497c311SBarry Smith MPI_Comm comm, commz;
190bb71ef15SMatthew G Knepley DM dmc;
191392fa6c6SMatthew G Knepley PetscSF sfz, sfzr;
192bb71ef15SMatthew G Knepley Vec XC;
193bb71ef15SMatthew G Knepley MatStencil patchSize, commSize, gridRank, lower, upper;
194bb71ef15SMatthew G Knepley PetscInt M, N, P, i, j, k, l, m, n, p = 0;
195bb71ef15SMatthew G Knepley PetscMPIInt rank, size;
196bb71ef15SMatthew G Knepley PetscInt debug = 0;
19759583ba0SMatthew G Knepley
19859583ba0SMatthew G Knepley PetscFunctionBegin;
1999566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
2009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
2019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
2029566063dSJacob Faibussowitsch PetscCall(DMPatchGetCoarse(dm, &dmc));
2039566063dSJacob Faibussowitsch PetscCall(DMPatchGetPatchSize(dm, &patchSize));
2049566063dSJacob Faibussowitsch PetscCall(DMPatchGetCommSize(dm, &commSize));
2059566063dSJacob Faibussowitsch PetscCall(DMPatchGetCommSize(dm, &commSize));
2069566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dmc, &XC));
2079566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(dmc, NULL, &M, &N, &P, &l, &m, &n, NULL, NULL, NULL, NULL, NULL, NULL));
2089371c9d4SSatish Balay M = PetscMax(M, 1);
2099371c9d4SSatish Balay l = PetscMax(l, 1);
2109371c9d4SSatish Balay N = PetscMax(N, 1);
2119371c9d4SSatish Balay m = PetscMax(m, 1);
2129371c9d4SSatish Balay P = PetscMax(P, 1);
2139371c9d4SSatish Balay n = PetscMax(n, 1);
2148865f1eaSKarl Rupp
215bb71ef15SMatthew G Knepley gridRank.i = rank % l;
216bb71ef15SMatthew G Knepley gridRank.j = rank / l % m;
217bb71ef15SMatthew G Knepley gridRank.k = rank / (l * m) % n;
2188865f1eaSKarl Rupp
219bb71ef15SMatthew G Knepley if (commSize.i * commSize.j * commSize.k == size || commSize.i * commSize.j * commSize.k == 0) {
2209371c9d4SSatish Balay commSize.i = l;
2219371c9d4SSatish Balay commSize.j = m;
2229371c9d4SSatish Balay commSize.k = n;
223bb71ef15SMatthew G Knepley commz = comm;
224bb71ef15SMatthew G Knepley } else if (commSize.i * commSize.j * commSize.k == 1) {
225bb71ef15SMatthew G Knepley commz = PETSC_COMM_SELF;
226bb71ef15SMatthew G Knepley } else {
227835f2295SStefano Zampini PetscInt newComm = ((gridRank.k / commSize.k) * (m / commSize.j) + gridRank.j / commSize.j) * (l / commSize.i) + gridRank.i / commSize.i;
228835f2295SStefano Zampini PetscInt newRank = ((gridRank.k % commSize.k) * commSize.j + gridRank.j % commSize.j) * commSize.i + gridRank.i % commSize.i;
229835f2295SStefano Zampini PetscMPIInt newCommi;
230835f2295SStefano Zampini PetscMPIInt newRanki;
231bb71ef15SMatthew G Knepley
232835f2295SStefano Zampini PetscCall(PetscMPIIntCast(newComm, &newCommi));
233835f2295SStefano Zampini PetscCall(PetscMPIIntCast(newRank, &newRanki));
234835f2295SStefano Zampini PetscCallMPI(MPI_Comm_split(comm, newCommi, newRanki, &commz));
235835f2295SStefano Zampini if (debug) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Rank %d color %d key %d commz %p\n", rank, newCommi, newRanki, (void *)(MPI_Aint)commz));
236bb71ef15SMatthew G Knepley }
237bb71ef15SMatthew G Knepley /*
238bb71ef15SMatthew G Knepley Assumptions:
239bb71ef15SMatthew G Knepley - patchSize divides gridSize
240bb71ef15SMatthew G Knepley - commSize divides gridSize
241bb71ef15SMatthew G Knepley - commSize divides l,m,n
242bb71ef15SMatthew G Knepley Ignore multiple patches per rank for now
243bb71ef15SMatthew G Knepley
244bb71ef15SMatthew G Knepley Multiple ranks per patch:
245bb71ef15SMatthew G Knepley - l,m,n divides patchSize
246bb71ef15SMatthew G Knepley - commSize divides patchSize
247bb71ef15SMatthew G Knepley */
248392fa6c6SMatthew G Knepley for (k = 0; k < P; k += PetscMax(patchSize.k, 1)) {
249392fa6c6SMatthew G Knepley for (j = 0; j < N; j += PetscMax(patchSize.j, 1)) {
250392fa6c6SMatthew G Knepley for (i = 0; i < M; i += PetscMax(patchSize.i, 1), ++p) {
251bb71ef15SMatthew G Knepley MPI_Comm commp = MPI_COMM_NULL;
2520298fd71SBarry Smith DM dmz = NULL;
2532f857c34SHong Zhang #if 0
2540298fd71SBarry Smith DM dmf = NULL;
2550298fd71SBarry Smith Mat interpz = NULL;
2562f857c34SHong Zhang #endif
2570298fd71SBarry Smith Vec XZ = NULL;
2580298fd71SBarry Smith PetscScalar *xcarray = NULL;
2590298fd71SBarry Smith PetscScalar *xzarray = NULL;
260bb87e006SMatthew G Knepley
2619371c9d4SSatish Balay if ((gridRank.k / commSize.k == p / (l / commSize.i * m / commSize.j) % n / commSize.k) && (gridRank.j / commSize.j == p / (l / commSize.i) % m / commSize.j) && (gridRank.i / commSize.i == p % l / commSize.i)) {
26263a3b9bcSJacob Faibussowitsch if (debug) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Rank %d is accepting Patch %" PetscInt_FMT "\n", rank, p));
263bb71ef15SMatthew G Knepley commp = commz;
264bb71ef15SMatthew G Knepley }
265bb87e006SMatthew G Knepley /* Zoom to coarse patch */
2669371c9d4SSatish Balay lower.i = i;
2679371c9d4SSatish Balay lower.j = j;
2689371c9d4SSatish Balay lower.k = k;
2699371c9d4SSatish Balay upper.i = i + patchSize.i;
2709371c9d4SSatish Balay upper.j = j + patchSize.j;
2719371c9d4SSatish Balay upper.k = k + patchSize.k;
2729566063dSJacob Faibussowitsch PetscCall(DMPatchZoom(dmc, lower, upper, commp, &dmz, &sfz, &sfzr));
273da80777bSKarl Rupp lower.c = 0; /* initialize member, otherwise compiler issues warnings */
274da80777bSKarl Rupp upper.c = 0; /* initialize member, otherwise compiler issues warnings */
2759371c9d4SSatish Balay if (debug)
2769371c9d4SSatish Balay PetscCall(PetscPrintf(comm, "Patch %" PetscInt_FMT ": (%" PetscInt_FMT ", %" PetscInt_FMT ", %" PetscInt_FMT ")--(%" PetscInt_FMT ", %" PetscInt_FMT ", %" PetscInt_FMT ")\n", p, lower.i, lower.j, lower.k, upper.i, upper.j, upper.k));
2779566063dSJacob Faibussowitsch if (dmz) PetscCall(DMView(dmz, PETSC_VIEWER_STDOUT_(commz)));
2789566063dSJacob Faibussowitsch PetscCall(PetscSFView(sfz, PETSC_VIEWER_STDOUT_(comm)));
2799566063dSJacob Faibussowitsch PetscCall(PetscSFView(sfzr, PETSC_VIEWER_STDOUT_(comm)));
28059583ba0SMatthew G Knepley /* Scatter Xcoarse -> Xzoom */
2819566063dSJacob Faibussowitsch if (dmz) PetscCall(DMGetGlobalVector(dmz, &XZ));
2829566063dSJacob Faibussowitsch if (XZ) PetscCall(VecGetArray(XZ, &xzarray));
2839566063dSJacob Faibussowitsch PetscCall(VecGetArray(XC, &xcarray));
2849566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sfz, MPIU_SCALAR, xcarray, xzarray, MPI_REPLACE));
2859566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sfz, MPIU_SCALAR, xcarray, xzarray, MPI_REPLACE));
2869566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(XC, &xcarray));
2879566063dSJacob Faibussowitsch if (XZ) PetscCall(VecRestoreArray(XZ, &xzarray));
288bd1050a3SMatthew G Knepley #if 0
28959583ba0SMatthew G Knepley /* Interpolate Xzoom -> Xfine, note that this may be on subcomms */
2909566063dSJacob Faibussowitsch PetscCall(DMRefine(dmz, MPI_COMM_NULL, &dmf));
2919566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dmz, dmf, &interpz, NULL));
2929566063dSJacob Faibussowitsch PetscCall(DMInterpolate(dmz, interpz, dmf));
29359583ba0SMatthew G Knepley /* Smooth Xfine using two-step smoother, normal smoother plus Kaczmarz---moves back and forth from dmzoom to dmfine */
29459583ba0SMatthew G Knepley /* Compute residual Rfine */
29559583ba0SMatthew G Knepley /* Restrict Rfine to Rzoom_restricted */
296bd1050a3SMatthew G Knepley #endif
29759583ba0SMatthew G Knepley /* Scatter Rzoom_restricted -> Rcoarse_restricted */
2989566063dSJacob Faibussowitsch if (XZ) PetscCall(VecGetArray(XZ, &xzarray));
2999566063dSJacob Faibussowitsch PetscCall(VecGetArray(XC, &xcarray));
3009566063dSJacob Faibussowitsch PetscCall(PetscSFReduceBegin(sfzr, MPIU_SCALAR, xzarray, xcarray, MPIU_SUM));
3019566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sfzr, MPIU_SCALAR, xzarray, xcarray, MPIU_SUM));
3029566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(XC, &xcarray));
3039566063dSJacob Faibussowitsch if (XZ) PetscCall(VecRestoreArray(XZ, &xzarray));
3049566063dSJacob Faibussowitsch if (dmz) PetscCall(DMRestoreGlobalVector(dmz, &XZ));
30559583ba0SMatthew G Knepley /* Compute global residual Rcoarse */
30659583ba0SMatthew G Knepley /* TauCoarse = Rcoarse - Rcoarse_restricted */
307bb87e006SMatthew G Knepley
3089566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfz));
3099566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfzr));
3109566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmz));
311a07761baSMatthew G Knepley }
312392fa6c6SMatthew G Knepley }
313392fa6c6SMatthew G Knepley }
3149566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dmc, &XC));
3153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
31659583ba0SMatthew G Knepley }
31759583ba0SMatthew G Knepley
DMPatchView_ASCII(DM dm,PetscViewer viewer)31866976f2fSJacob Faibussowitsch static PetscErrorCode DMPatchView_ASCII(DM dm, PetscViewer viewer)
319d71ae5a4SJacob Faibussowitsch {
3203a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
3213a19ef87SMatthew G Knepley PetscViewerFormat format;
322392fa6c6SMatthew G Knepley const char *name;
3233a19ef87SMatthew G Knepley
3243a19ef87SMatthew G Knepley PetscFunctionBegin;
3259566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format));
3263a19ef87SMatthew G Knepley /* if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) */
3279566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)dm, &name));
3289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Patch DM %s\n", name));
3299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
3309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Coarse DM\n"));
3319566063dSJacob Faibussowitsch PetscCall(DMView(mesh->dmCoarse, viewer));
3329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
3333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3343a19ef87SMatthew G Knepley }
3353a19ef87SMatthew G Knepley
DMView_Patch(DM dm,PetscViewer viewer)336d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView_Patch(DM dm, PetscViewer viewer)
337d71ae5a4SJacob Faibussowitsch {
338*9f196a02SMartin Diehl PetscBool isascii, isbinary;
3393a19ef87SMatthew G Knepley
3403a19ef87SMatthew G Knepley PetscFunctionBegin;
3413a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3423a19ef87SMatthew G Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
343*9f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3449566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
345*9f196a02SMartin Diehl if (isascii) PetscCall(DMPatchView_ASCII(dm, viewer));
3463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3473a19ef87SMatthew G Knepley }
3483a19ef87SMatthew G Knepley
DMDestroy_Patch(DM dm)349d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy_Patch(DM dm)
350d71ae5a4SJacob Faibussowitsch {
3513a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
3523a19ef87SMatthew G Knepley
3533a19ef87SMatthew G Knepley PetscFunctionBegin;
3543ba16761SJacob Faibussowitsch if (--mesh->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
3559566063dSJacob Faibussowitsch PetscCall(DMDestroy(&mesh->dmCoarse));
3563a19ef87SMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
3579566063dSJacob Faibussowitsch PetscCall(PetscFree(mesh));
3583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3593a19ef87SMatthew G Knepley }
3603a19ef87SMatthew G Knepley
DMSetUp_Patch(DM dm)361d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp_Patch(DM dm)
362d71ae5a4SJacob Faibussowitsch {
3633a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
3643a19ef87SMatthew G Knepley
3653a19ef87SMatthew G Knepley PetscFunctionBegin;
3663a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3679566063dSJacob Faibussowitsch PetscCall(DMSetUp(mesh->dmCoarse));
3683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3693a19ef87SMatthew G Knepley }
3703a19ef87SMatthew G Knepley
DMCreateGlobalVector_Patch(DM dm,Vec * g)371d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector_Patch(DM dm, Vec *g)
372d71ae5a4SJacob Faibussowitsch {
3733a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
3743a19ef87SMatthew G Knepley
3753a19ef87SMatthew G Knepley PetscFunctionBegin;
3763a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3779566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(mesh->dmCoarse, g));
3783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3793a19ef87SMatthew G Knepley }
3803a19ef87SMatthew G Knepley
DMCreateLocalVector_Patch(DM dm,Vec * l)381d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector_Patch(DM dm, Vec *l)
382d71ae5a4SJacob Faibussowitsch {
3833a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
3843a19ef87SMatthew G Knepley
3853a19ef87SMatthew G Knepley PetscFunctionBegin;
3863a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3879566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(mesh->dmCoarse, l));
3883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3893a19ef87SMatthew G Knepley }
3903a19ef87SMatthew G Knepley
DMCreateSubDM_Patch(DM dm,PetscInt numFields,const PetscInt fields[],IS * is,DM * subdm)391d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM_Patch(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
392d71ae5a4SJacob Faibussowitsch {
39382f516ccSBarry Smith SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Tell me to code this");
3943a19ef87SMatthew G Knepley }
395392fa6c6SMatthew G Knepley
DMPatchGetCoarse(DM dm,DM * dmCoarse)396d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPatchGetCoarse(DM dm, DM *dmCoarse)
397d71ae5a4SJacob Faibussowitsch {
398392fa6c6SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
399392fa6c6SMatthew G Knepley
400392fa6c6SMatthew G Knepley PetscFunctionBegin;
401392fa6c6SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
402392fa6c6SMatthew G Knepley *dmCoarse = mesh->dmCoarse;
4033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
404392fa6c6SMatthew G Knepley }
405392fa6c6SMatthew G Knepley
DMPatchGetPatchSize(DM dm,MatStencil * patchSize)406d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPatchGetPatchSize(DM dm, MatStencil *patchSize)
407d71ae5a4SJacob Faibussowitsch {
408392fa6c6SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
409392fa6c6SMatthew G Knepley
410392fa6c6SMatthew G Knepley PetscFunctionBegin;
411392fa6c6SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4124f572ea9SToby Isaac PetscAssertPointer(patchSize, 2);
413392fa6c6SMatthew G Knepley *patchSize = mesh->patchSize;
4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
415392fa6c6SMatthew G Knepley }
416392fa6c6SMatthew G Knepley
DMPatchSetPatchSize(DM dm,MatStencil patchSize)417d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPatchSetPatchSize(DM dm, MatStencil patchSize)
418d71ae5a4SJacob Faibussowitsch {
419392fa6c6SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
420392fa6c6SMatthew G Knepley
421392fa6c6SMatthew G Knepley PetscFunctionBegin;
422392fa6c6SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
423392fa6c6SMatthew G Knepley mesh->patchSize = patchSize;
4243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
425392fa6c6SMatthew G Knepley }
426bb71ef15SMatthew G Knepley
DMPatchGetCommSize(DM dm,MatStencil * commSize)427d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPatchGetCommSize(DM dm, MatStencil *commSize)
428d71ae5a4SJacob Faibussowitsch {
429bb71ef15SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
430bb71ef15SMatthew G Knepley
431bb71ef15SMatthew G Knepley PetscFunctionBegin;
432bb71ef15SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4334f572ea9SToby Isaac PetscAssertPointer(commSize, 2);
434bb71ef15SMatthew G Knepley *commSize = mesh->commSize;
4353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
436bb71ef15SMatthew G Knepley }
437bb71ef15SMatthew G Knepley
DMPatchSetCommSize(DM dm,MatStencil commSize)438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPatchSetCommSize(DM dm, MatStencil commSize)
439d71ae5a4SJacob Faibussowitsch {
440bb71ef15SMatthew G Knepley DM_Patch *mesh = (DM_Patch *)dm->data;
441bb71ef15SMatthew G Knepley
442bb71ef15SMatthew G Knepley PetscFunctionBegin;
443bb71ef15SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
444bb71ef15SMatthew G Knepley mesh->commSize = commSize;
4453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
446bb71ef15SMatthew G Knepley }
447