13a19ef87SMatthew G Knepley #include <petsc-private/patchimpl.h> /*I "petscdmpatch.h" I*/ 23a19ef87SMatthew G Knepley #include <petscdmda.h> 33a19ef87SMatthew G Knepley 45ee0e871SMatthew G Knepley /* 55ee0e871SMatthew G Knepley Solver loop to update \tau: 65ee0e871SMatthew G Knepley 75ee0e871SMatthew G Knepley DMZoom(dmc, &dmz) 85ee0e871SMatthew G Knepley DMRefine(dmz, &dmf), 95ee0e871SMatthew G Knepley Scatter Xcoarse -> Xzoom, 105ee0e871SMatthew G Knepley Interpolate Xzoom -> Xfine (note that this may be on subcomms), 115ee0e871SMatthew G Knepley Smooth Xfine using two-step smoother 125ee0e871SMatthew G Knepley normal smoother plus Kaczmarz---moves back and forth from dmzoom to dmfine 135ee0e871SMatthew G Knepley Compute residual Rfine 145ee0e871SMatthew G Knepley Restrict Rfine to Rzoom_restricted 155ee0e871SMatthew G Knepley Scatter Rzoom_restricted -> Rcoarse_restricted 165ee0e871SMatthew G Knepley Compute global residual Rcoarse 175ee0e871SMatthew G Knepley TauCoarse = Rcoarse - Rcoarse_restricted 185ee0e871SMatthew G Knepley */ 195ee0e871SMatthew G Knepley 203a19ef87SMatthew G Knepley #undef __FUNCT__ 21*59583ba0SMatthew G Knepley #define __FUNCT__ "DMPatchZoom" 22*59583ba0SMatthew G Knepley /* 23*59583ba0SMatthew G Knepley DMPatchZoom - Create a version of the coarse patch (identified by rank) with halo on communicator commz 24*59583ba0SMatthew G Knepley 25*59583ba0SMatthew G Knepley Input Parameters: 26*59583ba0SMatthew G Knepley + dm - the DM 27*59583ba0SMatthew G Knepley . rank - the rank which holds the given patch 28*59583ba0SMatthew G Knepley - commz - the new communicator for the patch 29*59583ba0SMatthew G Knepley 30*59583ba0SMatthew G Knepley Output Parameters: 31*59583ba0SMatthew G Knepley + dmz - the patch DM 32*59583ba0SMatthew G Knepley . sfz - the PetscSF mapping the patch+halo to the zoomed version 33*59583ba0SMatthew G Knepley . sfzr - the PetscSF mapping the patch to the restricted zoomed version 34*59583ba0SMatthew G Knepley 35*59583ba0SMatthew G Knepley Level: intermediate 36*59583ba0SMatthew G Knepley 37*59583ba0SMatthew G Knepley Note: All processes in commz should have the same rank (could autosplit comm) 38*59583ba0SMatthew G Knepley 39*59583ba0SMatthew G Knepley .seealso: DMPatchSolve() 40*59583ba0SMatthew G Knepley */ 41*59583ba0SMatthew G Knepley PetscErrorCode DMPatchZoom(DM dm, PetscInt rank, MPI_Comm commz, DM *dmz, PetscSF *sfz, PetscSF *sfzr) 42*59583ba0SMatthew G Knepley { 43*59583ba0SMatthew G Knepley PetscInt dim, dof, sw; 44*59583ba0SMatthew G Knepley DMDAStencilType st; 45*59583ba0SMatthew G Knepley PetscErrorCode ierr; 46*59583ba0SMatthew G Knepley 47*59583ba0SMatthew G Knepley PetscFunctionBegin; 48*59583ba0SMatthew G Knepley if (commz == MPI_COMM_NULL) { 49*59583ba0SMatthew G Knepley /* Split communicator */ 50*59583ba0SMatthew G Knepley SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Not implemented"); 51*59583ba0SMatthew G Knepley } 52*59583ba0SMatthew G Knepley /* Create patch DM */ 53*59583ba0SMatthew G Knepley ierr = DMDAGetDim(dm, &dim);CHKERRQ(ierr); 54*59583ba0SMatthew G Knepley ierr = DMDAGetDof(dm, &dof);CHKERRQ(ierr); 55*59583ba0SMatthew G Knepley ierr = DMDAGetStencilType(dm, &st);CHKERRQ(ierr); 56*59583ba0SMatthew G Knepley ierr = DMDAGetStencilWidth(dm, &sw);CHKERRQ(ierr); 57*59583ba0SMatthew G Knepley 58*59583ba0SMatthew G Knepley ierr = DMDACreate(commz, dmz);CHKERRQ(ierr); 59*59583ba0SMatthew G Knepley ierr = DMDASetDim(*dmz, dim);CHKERRQ(ierr); 60*59583ba0SMatthew G Knepley ierr = DMDASetSizes(*da, M, N, 1);CHKERRQ(ierr); 61*59583ba0SMatthew G Knepley ierr = DMDASetNumProcs(*dmz, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE);CHKERRQ(ierr); 62*59583ba0SMatthew G Knepley ierr = DMDASetBoundaryType(*dmz, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE);CHKERRQ(ierr); 63*59583ba0SMatthew G Knepley ierr = DMDASetDof(*dmz, dof);CHKERRQ(ierr); 64*59583ba0SMatthew G Knepley ierr = DMDASetStencilType(*dmz, st);CHKERRQ(ierr); 65*59583ba0SMatthew G Knepley ierr = DMDASetStencilWidth(*dmz, sw);CHKERRQ(ierr); 66*59583ba0SMatthew G Knepley ierr = DMDASetOwnershipRanges(*dmz, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr); 67*59583ba0SMatthew G Knepley ierr = DMSetFromOptions(*dmz);CHKERRQ(ierr); 68*59583ba0SMatthew G Knepley ierr = DMSetUp(*dmz);CHKERRQ(ierr); 69*59583ba0SMatthew G Knepley /* Create SF for ghosted map */ 70*59583ba0SMatthew G Knepley /* Create SF for restricted map */ 71*59583ba0SMatthew G Knepley PetscFunctionReturn(0); 72*59583ba0SMatthew G Knepley } 73*59583ba0SMatthew G Knepley 74*59583ba0SMatthew G Knepley #undef __FUNCT__ 75*59583ba0SMatthew G Knepley #define __FUNCT__ "DMPatchSolve" 76*59583ba0SMatthew G Knepley PetscErrorCode DMPatchSolve(DM dm) 77*59583ba0SMatthew G Knepley { 78*59583ba0SMatthew G Knepley MPI_Comm comm = ((PetscObject) dm)->comm; 79*59583ba0SMatthew G Knepley PetscMPIInt size; 80*59583ba0SMatthew G Knepley PetscErrorCode ierr; 81*59583ba0SMatthew G Knepley 82*59583ba0SMatthew G Knepley PetscFunctionBegin; 83*59583ba0SMatthew G Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 84*59583ba0SMatthew G Knepley for(r = 0; r < size; ++r) { 85*59583ba0SMatthew G Knepley DM dmz, dmf; 86*59583ba0SMatthew G Knepley Mat interpz; 87*59583ba0SMatthew G Knepley 88*59583ba0SMatthew G Knepley ierr = DMPatchZoom(dm, r, comm, &dmz);CHKERRQ(ierr); 89*59583ba0SMatthew G Knepley /* Scatter Xcoarse -> Xzoom */ 90*59583ba0SMatthew G Knepley ierr = PetscSFBcastBegin(sfz, MPIU_SCALAR, xcarray, xzarray);CHKERRQ(ierr); 91*59583ba0SMatthew G Knepley ierr = PetscSFBcastEnd(sfz, MPIU_SCALAR, xcarray, xzarray);CHKERRQ(ierr); 92*59583ba0SMatthew G Knepley /* Interpolate Xzoom -> Xfine, note that this may be on subcomms */ 93*59583ba0SMatthew G Knepley ierr = DMRefine(dmz, MPI_COMM_NULL, &dmf);CHKERRQ(ierr); 94*59583ba0SMatthew G Knepley ierr = DMCreateInterpolation(dmz, dmf, &interpz, PETSC_NULL);CHKERRQ(ierr); 95*59583ba0SMatthew G Knepley ierr = DMInterpolate(dmz, interpz, dmf);CHKERRQ(ierr); 96*59583ba0SMatthew G Knepley /* Smooth Xfine using two-step smoother, normal smoother plus Kaczmarz---moves back and forth from dmzoom to dmfine */ 97*59583ba0SMatthew G Knepley /* Compute residual Rfine */ 98*59583ba0SMatthew G Knepley /* Restrict Rfine to Rzoom_restricted */ 99*59583ba0SMatthew G Knepley /* Scatter Rzoom_restricted -> Rcoarse_restricted */ 100*59583ba0SMatthew G Knepley ierr = PetscSFBcastBegin(sfzr, MPIU_SCALAR, xzarray, xcarray, MPI_SUM);CHKERRQ(ierr); 101*59583ba0SMatthew G Knepley ierr = PetscSFBcastEnd(sfzr, MPIU_SCALAR, xzarray, xcarray, MPI_SUM);CHKERRQ(ierr); 102*59583ba0SMatthew G Knepley /* Compute global residual Rcoarse */ 103*59583ba0SMatthew G Knepley /* TauCoarse = Rcoarse - Rcoarse_restricted */ 104*59583ba0SMatthew G Knepley } 105*59583ba0SMatthew G Knepley PetscFunctionReturn(0); 106*59583ba0SMatthew G Knepley } 107*59583ba0SMatthew G Knepley 108*59583ba0SMatthew G Knepley #undef __FUNCT__ 1093a19ef87SMatthew G Knepley #define __FUNCT__ "DMPatchView_Ascii" 1103a19ef87SMatthew G Knepley PetscErrorCode DMPatchView_Ascii(DM dm, PetscViewer viewer) 1113a19ef87SMatthew G Knepley { 1123a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *) dm->data; 1133a19ef87SMatthew G Knepley PetscViewerFormat format; 1143a19ef87SMatthew G Knepley PetscInt p; 1153a19ef87SMatthew G Knepley PetscErrorCode ierr; 1163a19ef87SMatthew G Knepley 1173a19ef87SMatthew G Knepley PetscFunctionBegin; 1183a19ef87SMatthew G Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1193a19ef87SMatthew G Knepley /* if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) */ 1203a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D patches\n", mesh->numPatches);CHKERRQ(ierr); 1213a19ef87SMatthew G Knepley for(p = 0; p < mesh->numPatches; ++p) { 1223a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1233a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "Patch %D\n", p);CHKERRQ(ierr); 1243a19ef87SMatthew G Knepley ierr = DMView(mesh->patches[p], viewer);CHKERRQ(ierr); 1253a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1263a19ef87SMatthew G Knepley } 1273a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1283a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "Coarse DM\n");CHKERRQ(ierr); 1293a19ef87SMatthew G Knepley ierr = DMView(mesh->dmCoarse, viewer);CHKERRQ(ierr); 1303a19ef87SMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1313a19ef87SMatthew G Knepley PetscFunctionReturn(0); 1323a19ef87SMatthew G Knepley } 1333a19ef87SMatthew G Knepley 1343a19ef87SMatthew G Knepley #undef __FUNCT__ 1353a19ef87SMatthew G Knepley #define __FUNCT__ "DMView_Patch" 1363a19ef87SMatthew G Knepley PetscErrorCode DMView_Patch(DM dm, PetscViewer viewer) 1373a19ef87SMatthew G Knepley { 1383a19ef87SMatthew G Knepley PetscBool iascii, isbinary; 1393a19ef87SMatthew G Knepley PetscErrorCode ierr; 1403a19ef87SMatthew G Knepley 1413a19ef87SMatthew G Knepley PetscFunctionBegin; 1423a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1433a19ef87SMatthew G Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1443a19ef87SMatthew G Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1453a19ef87SMatthew G Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERBINARY, &isbinary);CHKERRQ(ierr); 1463a19ef87SMatthew G Knepley if (iascii) { 1473a19ef87SMatthew G Knepley ierr = DMPatchView_Ascii(dm, viewer);CHKERRQ(ierr); 1483a19ef87SMatthew G Knepley #if 0 1493a19ef87SMatthew G Knepley } else if (isbinary) { 1503a19ef87SMatthew G Knepley ierr = DMPatchView_Binary(dm, viewer);CHKERRQ(ierr); 1513a19ef87SMatthew G Knepley #endif 1523a19ef87SMatthew G Knepley } else SETERRQ1(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name); 1533a19ef87SMatthew G Knepley PetscFunctionReturn(0); 1543a19ef87SMatthew G Knepley } 1553a19ef87SMatthew G Knepley 1563a19ef87SMatthew G Knepley #undef __FUNCT__ 1573a19ef87SMatthew G Knepley #define __FUNCT__ "DMDestroy_Patch" 1583a19ef87SMatthew G Knepley PetscErrorCode DMDestroy_Patch(DM dm) 1593a19ef87SMatthew G Knepley { 1603a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *) dm->data; 1613a19ef87SMatthew G Knepley PetscInt p; 1623a19ef87SMatthew G Knepley PetscErrorCode ierr; 1633a19ef87SMatthew G Knepley 1643a19ef87SMatthew G Knepley PetscFunctionBegin; 1653a19ef87SMatthew G Knepley if (--mesh->refct > 0) {PetscFunctionReturn(0);} 1663a19ef87SMatthew G Knepley for(p = 0; p < mesh->numPatches; ++p) { 1673a19ef87SMatthew G Knepley ierr = DMDestroy(&mesh->patches[p]);CHKERRQ(ierr); 1683a19ef87SMatthew G Knepley } 1693a19ef87SMatthew G Knepley ierr = PetscFree(mesh->patches);CHKERRQ(ierr); 1703a19ef87SMatthew G Knepley ierr = DMDestroy(&mesh->dmCoarse);CHKERRQ(ierr); 1713a19ef87SMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 1723a19ef87SMatthew G Knepley ierr = PetscFree(mesh);CHKERRQ(ierr); 1733a19ef87SMatthew G Knepley PetscFunctionReturn(0); 1743a19ef87SMatthew G Knepley } 1753a19ef87SMatthew G Knepley 1763a19ef87SMatthew G Knepley #undef __FUNCT__ 1773a19ef87SMatthew G Knepley #define __FUNCT__ "DMSetUp_Patch" 1783a19ef87SMatthew G Knepley PetscErrorCode DMSetUp_Patch(DM dm) 1793a19ef87SMatthew G Knepley { 1803a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *) dm->data; 1813a19ef87SMatthew G Knepley PetscInt p; 1823a19ef87SMatthew G Knepley PetscErrorCode ierr; 1833a19ef87SMatthew G Knepley 1843a19ef87SMatthew G Knepley PetscFunctionBegin; 1853a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1863a19ef87SMatthew G Knepley for(p = 0; p < mesh->numPatches; ++p) { 1873a19ef87SMatthew G Knepley ierr = DMSetUp(mesh->patches[p]);CHKERRQ(ierr); 1883a19ef87SMatthew G Knepley } 1893a19ef87SMatthew G Knepley PetscFunctionReturn(0); 1903a19ef87SMatthew G Knepley } 1913a19ef87SMatthew G Knepley 1923a19ef87SMatthew G Knepley #undef __FUNCT__ 1933a19ef87SMatthew G Knepley #define __FUNCT__ "DMCreateGlobalVector_Patch" 1943a19ef87SMatthew G Knepley PetscErrorCode DMCreateGlobalVector_Patch(DM dm, Vec *g) 1953a19ef87SMatthew G Knepley { 1963a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *) dm->data; 1973a19ef87SMatthew G Knepley PetscErrorCode ierr; 1983a19ef87SMatthew G Knepley 1993a19ef87SMatthew G Knepley PetscFunctionBegin; 2003a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2016d1defb0SMatthew G Knepley ierr = DMCreateGlobalVector(mesh->patches[mesh->activePatch], g);CHKERRQ(ierr); 2023a19ef87SMatthew G Knepley PetscFunctionReturn(0); 2033a19ef87SMatthew G Knepley } 2043a19ef87SMatthew G Knepley 2053a19ef87SMatthew G Knepley #undef __FUNCT__ 2063a19ef87SMatthew G Knepley #define __FUNCT__ "DMCreateLocalVector_Patch" 2073a19ef87SMatthew G Knepley PetscErrorCode DMCreateLocalVector_Patch(DM dm, Vec *l) 2083a19ef87SMatthew G Knepley { 2093a19ef87SMatthew G Knepley DM_Patch *mesh = (DM_Patch *) dm->data; 2103a19ef87SMatthew G Knepley PetscErrorCode ierr; 2113a19ef87SMatthew G Knepley 2123a19ef87SMatthew G Knepley PetscFunctionBegin; 2133a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2146d1defb0SMatthew G Knepley ierr = DMCreateLocalVector(mesh->patches[mesh->activePatch], l);CHKERRQ(ierr); 2153a19ef87SMatthew G Knepley PetscFunctionReturn(0); 2163a19ef87SMatthew G Knepley } 2173a19ef87SMatthew G Knepley 2183a19ef87SMatthew G Knepley #undef __FUNCT__ 2193a19ef87SMatthew G Knepley #define __FUNCT__ "DMPatchGetActivePatch" 2203a19ef87SMatthew G Knepley PetscErrorCode DMPatchGetActivePatch(DM dm, PetscInt *patch) 2213a19ef87SMatthew G Knepley { 2223a19ef87SMatthew G Knepley DM_Patch *mesh; 2233a19ef87SMatthew G Knepley 2243a19ef87SMatthew G Knepley PetscFunctionBegin; 2253a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2263a19ef87SMatthew G Knepley PetscValidPointer(patch, 2); 2273a19ef87SMatthew G Knepley mesh = (DM_Patch *) dm->data; 2283a19ef87SMatthew G Knepley *patch = mesh->activePatch; 2293a19ef87SMatthew G Knepley PetscFunctionReturn(0); 2303a19ef87SMatthew G Knepley } 2313a19ef87SMatthew G Knepley 2323a19ef87SMatthew G Knepley #undef __FUNCT__ 2333a19ef87SMatthew G Knepley #define __FUNCT__ "DMPatchSetActivePatch" 2343a19ef87SMatthew G Knepley PetscErrorCode DMPatchSetActivePatch(DM dm, PetscInt patch) 2353a19ef87SMatthew G Knepley { 2363a19ef87SMatthew G Knepley DM_Patch *mesh; 2373a19ef87SMatthew G Knepley 2383a19ef87SMatthew G Knepley PetscFunctionBegin; 2393a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2403a19ef87SMatthew G Knepley mesh = (DM_Patch *) dm->data; 2413a19ef87SMatthew G Knepley mesh->activePatch = patch; 2423a19ef87SMatthew G Knepley PetscFunctionReturn(0); 2433a19ef87SMatthew G Knepley } 2443a19ef87SMatthew G Knepley 2453a19ef87SMatthew G Knepley #undef __FUNCT__ 2463a19ef87SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM_Patch" 2473a19ef87SMatthew G Knepley PetscErrorCode DMCreateSubDM_Patch(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) 2483a19ef87SMatthew G Knepley { 2493a19ef87SMatthew G Knepley PetscFunctionBegin; 2503a19ef87SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2513a19ef87SMatthew G Knepley SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Tell me to code this"); 2523a19ef87SMatthew G Knepley PetscFunctionReturn(0); 2533a19ef87SMatthew G Knepley } 254