16858538eSMatthew G. Knepley #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 26858538eSMatthew G. Knepley 36858538eSMatthew G. Knepley #include <petscdmplex.h> /* For DMProjectCoordinates() */ 46858538eSMatthew G. Knepley #include <petscsf.h> /* For DMLocatePoints() */ 56858538eSMatthew G. Knepley 6d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestrictHook_Coordinates(DM dm, DM dmc, void *ctx) 7d71ae5a4SJacob Faibussowitsch { 86858538eSMatthew G. Knepley DM dm_coord, dmc_coord; 96858538eSMatthew G. Knepley Vec coords, ccoords; 106858538eSMatthew G. Knepley Mat inject; 116858538eSMatthew G. Knepley PetscFunctionBegin; 126858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 136858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dmc, &dmc_coord)); 146858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coords)); 156858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dmc, &ccoords)); 166858538eSMatthew G. Knepley if (coords && !ccoords) { 176858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(dmc_coord, &ccoords)); 186858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)ccoords, "coordinates")); 196858538eSMatthew G. Knepley PetscCall(DMCreateInjection(dmc_coord, dm_coord, &inject)); 206858538eSMatthew G. Knepley PetscCall(MatRestrict(inject, coords, ccoords)); 216858538eSMatthew G. Knepley PetscCall(MatDestroy(&inject)); 226858538eSMatthew G. Knepley PetscCall(DMSetCoordinates(dmc, ccoords)); 236858538eSMatthew G. Knepley PetscCall(VecDestroy(&ccoords)); 246858538eSMatthew G. Knepley } 256858538eSMatthew G. Knepley PetscFunctionReturn(0); 266858538eSMatthew G. Knepley } 276858538eSMatthew G. Knepley 28d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_Coordinates(DM dm, DM subdm, void *ctx) 29d71ae5a4SJacob Faibussowitsch { 306858538eSMatthew G. Knepley DM dm_coord, subdm_coord; 316858538eSMatthew G. Knepley Vec coords, ccoords, clcoords; 326858538eSMatthew G. Knepley VecScatter *scat_i, *scat_g; 336858538eSMatthew G. Knepley PetscFunctionBegin; 346858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 356858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(subdm, &subdm_coord)); 366858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coords)); 376858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(subdm, &ccoords)); 386858538eSMatthew G. Knepley if (coords && !ccoords) { 396858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(subdm_coord, &ccoords)); 406858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)ccoords, "coordinates")); 416858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(subdm_coord, &clcoords)); 426858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)clcoords, "coordinates")); 436858538eSMatthew G. Knepley PetscCall(DMCreateDomainDecompositionScatters(dm_coord, 1, &subdm_coord, NULL, &scat_i, &scat_g)); 446858538eSMatthew G. Knepley PetscCall(VecScatterBegin(scat_i[0], coords, ccoords, INSERT_VALUES, SCATTER_FORWARD)); 456858538eSMatthew G. Knepley PetscCall(VecScatterEnd(scat_i[0], coords, ccoords, INSERT_VALUES, SCATTER_FORWARD)); 466858538eSMatthew G. Knepley PetscCall(VecScatterBegin(scat_g[0], coords, clcoords, INSERT_VALUES, SCATTER_FORWARD)); 476858538eSMatthew G. Knepley PetscCall(VecScatterEnd(scat_g[0], coords, clcoords, INSERT_VALUES, SCATTER_FORWARD)); 486858538eSMatthew G. Knepley PetscCall(DMSetCoordinates(subdm, ccoords)); 496858538eSMatthew G. Knepley PetscCall(DMSetCoordinatesLocal(subdm, clcoords)); 506858538eSMatthew G. Knepley PetscCall(VecScatterDestroy(&scat_i[0])); 516858538eSMatthew G. Knepley PetscCall(VecScatterDestroy(&scat_g[0])); 526858538eSMatthew G. Knepley PetscCall(VecDestroy(&ccoords)); 536858538eSMatthew G. Knepley PetscCall(VecDestroy(&clcoords)); 546858538eSMatthew G. Knepley PetscCall(PetscFree(scat_i)); 556858538eSMatthew G. Knepley PetscCall(PetscFree(scat_g)); 566858538eSMatthew G. Knepley } 576858538eSMatthew G. Knepley PetscFunctionReturn(0); 586858538eSMatthew G. Knepley } 596858538eSMatthew G. Knepley 606858538eSMatthew G. Knepley /*@ 616858538eSMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 626858538eSMatthew G. Knepley 636858538eSMatthew G. Knepley Collective on dm 646858538eSMatthew G. Knepley 656858538eSMatthew G. Knepley Input Parameter: 666858538eSMatthew G. Knepley . dm - the DM 676858538eSMatthew G. Knepley 686858538eSMatthew G. Knepley Output Parameter: 696858538eSMatthew G. Knepley . cdm - coordinate DM 706858538eSMatthew G. Knepley 716858538eSMatthew G. Knepley Level: intermediate 726858538eSMatthew G. Knepley 736858538eSMatthew G. Knepley .seealso: `DMSetCoordinateDM()`, `DMSetCoordinates()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()` 746858538eSMatthew G. Knepley @*/ 75d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 76d71ae5a4SJacob Faibussowitsch { 776858538eSMatthew G. Knepley PetscFunctionBegin; 786858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 796858538eSMatthew G. Knepley PetscValidPointer(cdm, 2); 806858538eSMatthew G. Knepley if (!dm->coordinates[0].dm) { 816858538eSMatthew G. Knepley DM cdm; 826858538eSMatthew G. Knepley 83dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createcoordinatedm, &cdm); 846858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)cdm, "coordinateDM")); 856858538eSMatthew G. Knepley /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 866858538eSMatthew G. Knepley * until the call to CreateCoordinateDM) */ 876858538eSMatthew G. Knepley PetscCall(DMDestroy(&dm->coordinates[0].dm)); 886858538eSMatthew G. Knepley dm->coordinates[0].dm = cdm; 896858538eSMatthew G. Knepley } 906858538eSMatthew G. Knepley *cdm = dm->coordinates[0].dm; 916858538eSMatthew G. Knepley PetscFunctionReturn(0); 926858538eSMatthew G. Knepley } 936858538eSMatthew G. Knepley 946858538eSMatthew G. Knepley /*@ 956858538eSMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 966858538eSMatthew G. Knepley 976858538eSMatthew G. Knepley Logically Collective on dm 986858538eSMatthew G. Knepley 996858538eSMatthew G. Knepley Input Parameters: 1006858538eSMatthew G. Knepley + dm - the DM 1016858538eSMatthew G. Knepley - cdm - coordinate DM 1026858538eSMatthew G. Knepley 1036858538eSMatthew G. Knepley Level: intermediate 1046858538eSMatthew G. Knepley 1056858538eSMatthew G. Knepley .seealso: `DMGetCoordinateDM()`, `DMSetCoordinates()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()` 1066858538eSMatthew G. Knepley @*/ 107d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 108d71ae5a4SJacob Faibussowitsch { 1096858538eSMatthew G. Knepley PetscFunctionBegin; 1106858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1116858538eSMatthew G. Knepley PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 1126858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)cdm)); 1136858538eSMatthew G. Knepley PetscCall(DMDestroy(&dm->coordinates[0].dm)); 1146858538eSMatthew G. Knepley dm->coordinates[0].dm = cdm; 1156858538eSMatthew G. Knepley PetscFunctionReturn(0); 1166858538eSMatthew G. Knepley } 1176858538eSMatthew G. Knepley 1186858538eSMatthew G. Knepley /*@ 1196858538eSMatthew G. Knepley DMGetCellCoordinateDM - Gets the DM that prescribes cellwise coordinate layout and scatters between global and local cellwise coordinates 1206858538eSMatthew G. Knepley 1216858538eSMatthew G. Knepley Collective on dm 1226858538eSMatthew G. Knepley 1236858538eSMatthew G. Knepley Input Parameter: 1246858538eSMatthew G. Knepley . dm - the DM 1256858538eSMatthew G. Knepley 1266858538eSMatthew G. Knepley Output Parameter: 1276858538eSMatthew G. Knepley . cdm - cellwise coordinate DM, or NULL if they are not defined 1286858538eSMatthew G. Knepley 1296858538eSMatthew G. Knepley Note: 1306858538eSMatthew G. Knepley Call DMLocalizeCoordinates() to automatically create cellwise coordinates for periodic geometries. 1316858538eSMatthew G. Knepley 1326858538eSMatthew G. Knepley Level: intermediate 1336858538eSMatthew G. Knepley 1346858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinateDM()`, `DMSetCellCoordinates()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMLocalizeCoordinates()` 1356858538eSMatthew G. Knepley @*/ 136d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinateDM(DM dm, DM *cdm) 137d71ae5a4SJacob Faibussowitsch { 1386858538eSMatthew G. Knepley PetscFunctionBegin; 1396858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1406858538eSMatthew G. Knepley PetscValidPointer(cdm, 2); 1416858538eSMatthew G. Knepley *cdm = dm->coordinates[1].dm; 1426858538eSMatthew G. Knepley PetscFunctionReturn(0); 1436858538eSMatthew G. Knepley } 1446858538eSMatthew G. Knepley 1456858538eSMatthew G. Knepley /*@ 1466858538eSMatthew G. Knepley DMSetCellCoordinateDM - Sets the DM that prescribes cellwise coordinate layout and scatters between global and local cellwise coordinates 1476858538eSMatthew G. Knepley 1486858538eSMatthew G. Knepley Logically Collective on dm 1496858538eSMatthew G. Knepley 1506858538eSMatthew G. Knepley Input Parameters: 1516858538eSMatthew G. Knepley + dm - the DM 1526858538eSMatthew G. Knepley - cdm - cellwise coordinate DM 1536858538eSMatthew G. Knepley 1546858538eSMatthew G. Knepley Level: intermediate 1556858538eSMatthew G. Knepley 1566858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinateDM()`, `DMSetCellCoordinates()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()` 1576858538eSMatthew G. Knepley @*/ 158d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinateDM(DM dm, DM cdm) 159d71ae5a4SJacob Faibussowitsch { 1606858538eSMatthew G. Knepley PetscInt dim; 1616858538eSMatthew G. Knepley 1626858538eSMatthew G. Knepley PetscFunctionBegin; 1636858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1646858538eSMatthew G. Knepley if (cdm) { 1656858538eSMatthew G. Knepley PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 1666858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &dim)); 1676858538eSMatthew G. Knepley dm->coordinates[1].dim = dim; 1686858538eSMatthew G. Knepley } 1696858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)cdm)); 1706858538eSMatthew G. Knepley PetscCall(DMDestroy(&dm->coordinates[1].dm)); 1716858538eSMatthew G. Knepley dm->coordinates[1].dm = cdm; 1726858538eSMatthew G. Knepley PetscFunctionReturn(0); 1736858538eSMatthew G. Knepley } 1746858538eSMatthew G. Knepley 1756858538eSMatthew G. Knepley /*@ 1766858538eSMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 1776858538eSMatthew G. Knepley 1786858538eSMatthew G. Knepley Not Collective 1796858538eSMatthew G. Knepley 1806858538eSMatthew G. Knepley Input Parameter: 1816858538eSMatthew G. Knepley . dm - The DM object 1826858538eSMatthew G. Knepley 1836858538eSMatthew G. Knepley Output Parameter: 1846858538eSMatthew G. Knepley . dim - The embedding dimension 1856858538eSMatthew G. Knepley 1866858538eSMatthew G. Knepley Level: intermediate 1876858538eSMatthew G. Knepley 1886858538eSMatthew G. Knepley .seealso: `DMSetCoordinateDim()`, `DMGetCoordinateSection()`, `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 1896858538eSMatthew G. Knepley @*/ 190d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 191d71ae5a4SJacob Faibussowitsch { 1926858538eSMatthew G. Knepley PetscFunctionBegin; 1936858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1946858538eSMatthew G. Knepley PetscValidIntPointer(dim, 2); 1956858538eSMatthew G. Knepley if (dm->coordinates[0].dim == PETSC_DEFAULT) dm->coordinates[0].dim = dm->dim; 1966858538eSMatthew G. Knepley *dim = dm->coordinates[0].dim; 1976858538eSMatthew G. Knepley PetscFunctionReturn(0); 1986858538eSMatthew G. Knepley } 1996858538eSMatthew G. Knepley 2006858538eSMatthew G. Knepley /*@ 2016858538eSMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 2026858538eSMatthew G. Knepley 2036858538eSMatthew G. Knepley Not Collective 2046858538eSMatthew G. Knepley 2056858538eSMatthew G. Knepley Input Parameters: 2066858538eSMatthew G. Knepley + dm - The DM object 2076858538eSMatthew G. Knepley - dim - The embedding dimension 2086858538eSMatthew G. Knepley 2096858538eSMatthew G. Knepley Level: intermediate 2106858538eSMatthew G. Knepley 2116858538eSMatthew G. Knepley .seealso: `DMGetCoordinateDim()`, `DMSetCoordinateSection()`, `DMGetCoordinateSection()`, `DMGetLocalSection()`, `DMSetLocalSection()` 2126858538eSMatthew G. Knepley @*/ 213d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 214d71ae5a4SJacob Faibussowitsch { 2156858538eSMatthew G. Knepley PetscDS ds; 2166858538eSMatthew G. Knepley PetscInt Nds, n; 2176858538eSMatthew G. Knepley 2186858538eSMatthew G. Knepley PetscFunctionBegin; 2196858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2206858538eSMatthew G. Knepley dm->coordinates[0].dim = dim; 2216858538eSMatthew G. Knepley if (dm->dim >= 0) { 2226858538eSMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 2236858538eSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 2246858538eSMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds)); 2256858538eSMatthew G. Knepley PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 2266858538eSMatthew G. Knepley } 2276858538eSMatthew G. Knepley } 2286858538eSMatthew G. Knepley PetscFunctionReturn(0); 2296858538eSMatthew G. Knepley } 2306858538eSMatthew G. Knepley 2316858538eSMatthew G. Knepley /*@ 2326858538eSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 2336858538eSMatthew G. Knepley 2346858538eSMatthew G. Knepley Collective on dm 2356858538eSMatthew G. Knepley 2366858538eSMatthew G. Knepley Input Parameter: 2376858538eSMatthew G. Knepley . dm - The DM object 2386858538eSMatthew G. Knepley 2396858538eSMatthew G. Knepley Output Parameter: 2406858538eSMatthew G. Knepley . section - The PetscSection object 2416858538eSMatthew G. Knepley 2426858538eSMatthew G. Knepley Level: intermediate 2436858538eSMatthew G. Knepley 2446858538eSMatthew G. Knepley .seealso: `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 2456858538eSMatthew G. Knepley @*/ 246d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 247d71ae5a4SJacob Faibussowitsch { 2486858538eSMatthew G. Knepley DM cdm; 2496858538eSMatthew G. Knepley 2506858538eSMatthew G. Knepley PetscFunctionBegin; 2516858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2526858538eSMatthew G. Knepley PetscValidPointer(section, 2); 2536858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 2546858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(cdm, section)); 2556858538eSMatthew G. Knepley PetscFunctionReturn(0); 2566858538eSMatthew G. Knepley } 2576858538eSMatthew G. Knepley 2586858538eSMatthew G. Knepley /*@ 2596858538eSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 2606858538eSMatthew G. Knepley 2616858538eSMatthew G. Knepley Not Collective 2626858538eSMatthew G. Knepley 2636858538eSMatthew G. Knepley Input Parameters: 2646858538eSMatthew G. Knepley + dm - The DM object 2656858538eSMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 2666858538eSMatthew G. Knepley - section - The PetscSection object 2676858538eSMatthew G. Knepley 2686858538eSMatthew G. Knepley Level: intermediate 2696858538eSMatthew G. Knepley 2706858538eSMatthew G. Knepley .seealso: `DMGetCoordinateSection()`, `DMGetLocalSection()`, `DMSetLocalSection()` 2716858538eSMatthew G. Knepley @*/ 272d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 273d71ae5a4SJacob Faibussowitsch { 2746858538eSMatthew G. Knepley DM cdm; 2756858538eSMatthew G. Knepley 2766858538eSMatthew G. Knepley PetscFunctionBegin; 2776858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2786858538eSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 3); 2796858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 2806858538eSMatthew G. Knepley PetscCall(DMSetLocalSection(cdm, section)); 2816858538eSMatthew G. Knepley if (dim == PETSC_DETERMINE) { 2826858538eSMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 2836858538eSMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 2846858538eSMatthew G. Knepley 2856858538eSMatthew G. Knepley PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 2866858538eSMatthew G. Knepley PetscCall(DMGetDimPoints(dm, 0, &vStart, &vEnd)); 2876858538eSMatthew G. Knepley pStart = PetscMax(vStart, pStart); 2886858538eSMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 2896858538eSMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 2906858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(section, v, &dd)); 2919371c9d4SSatish Balay if (dd) { 2929371c9d4SSatish Balay d = dd; 2939371c9d4SSatish Balay break; 2949371c9d4SSatish Balay } 2956858538eSMatthew G. Knepley } 2966858538eSMatthew G. Knepley if (d >= 0) PetscCall(DMSetCoordinateDim(dm, d)); 2976858538eSMatthew G. Knepley } 2986858538eSMatthew G. Knepley PetscFunctionReturn(0); 2996858538eSMatthew G. Knepley } 3006858538eSMatthew G. Knepley 3016858538eSMatthew G. Knepley /*@ 3026858538eSMatthew G. Knepley DMGetCellCoordinateSection - Retrieve the layout of cellwise coordinate values over the mesh. 3036858538eSMatthew G. Knepley 3046858538eSMatthew G. Knepley Collective on dm 3056858538eSMatthew G. Knepley 3066858538eSMatthew G. Knepley Input Parameter: 3076858538eSMatthew G. Knepley . dm - The DM object 3086858538eSMatthew G. Knepley 3096858538eSMatthew G. Knepley Output Parameter: 3106858538eSMatthew G. Knepley . section - The PetscSection object, or NULL if no cellwise coordinates are defined 3116858538eSMatthew G. Knepley 3126858538eSMatthew G. Knepley Level: intermediate 3136858538eSMatthew G. Knepley 3146858538eSMatthew G. Knepley .seealso: `DMGetCoordinateSection()`, `DMSetCellCoordinateSection()`, `DMGetCellCoordinateDM()`, `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 3156858538eSMatthew G. Knepley @*/ 316d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinateSection(DM dm, PetscSection *section) 317d71ae5a4SJacob Faibussowitsch { 3186858538eSMatthew G. Knepley DM cdm; 3196858538eSMatthew G. Knepley 3206858538eSMatthew G. Knepley PetscFunctionBegin; 3216858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3226858538eSMatthew G. Knepley PetscValidPointer(section, 2); 3236858538eSMatthew G. Knepley *section = NULL; 3246858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 3256858538eSMatthew G. Knepley if (cdm) PetscCall(DMGetLocalSection(cdm, section)); 3266858538eSMatthew G. Knepley PetscFunctionReturn(0); 3276858538eSMatthew G. Knepley } 3286858538eSMatthew G. Knepley 3296858538eSMatthew G. Knepley /*@ 3306858538eSMatthew G. Knepley DMSetCellCoordinateSection - Set the layout of cellwise coordinate values over the mesh. 3316858538eSMatthew G. Knepley 3326858538eSMatthew G. Knepley Not Collective 3336858538eSMatthew G. Knepley 3346858538eSMatthew G. Knepley Input Parameters: 3356858538eSMatthew G. Knepley + dm - The DM object 3366858538eSMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 3376858538eSMatthew G. Knepley - section - The PetscSection object for a cellwise layout 3386858538eSMatthew G. Knepley 3396858538eSMatthew G. Knepley Level: intermediate 3406858538eSMatthew G. Knepley 3416858538eSMatthew G. Knepley .seealso: `DMSetCoordinateSection()`, `DMGetCellCoordinateSection()`, `DMGetCoordinateSection()`, `DMGetCellCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 3426858538eSMatthew G. Knepley @*/ 343d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinateSection(DM dm, PetscInt dim, PetscSection section) 344d71ae5a4SJacob Faibussowitsch { 3456858538eSMatthew G. Knepley DM cdm; 3466858538eSMatthew G. Knepley 3476858538eSMatthew G. Knepley PetscFunctionBegin; 3486858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3496858538eSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 3); 3506858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 3516858538eSMatthew G. Knepley PetscCheck(cdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "No DM defined for cellwise coordinates"); 3526858538eSMatthew G. Knepley PetscCall(DMSetLocalSection(cdm, section)); 3536858538eSMatthew G. Knepley if (dim == PETSC_DETERMINE) { 3546858538eSMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 3556858538eSMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 3566858538eSMatthew G. Knepley 3576858538eSMatthew G. Knepley PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 3586858538eSMatthew G. Knepley PetscCall(DMGetDimPoints(dm, 0, &vStart, &vEnd)); 3596858538eSMatthew G. Knepley pStart = PetscMax(vStart, pStart); 3606858538eSMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 3616858538eSMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 3626858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(section, v, &dd)); 3639371c9d4SSatish Balay if (dd) { 3649371c9d4SSatish Balay d = dd; 3659371c9d4SSatish Balay break; 3669371c9d4SSatish Balay } 3676858538eSMatthew G. Knepley } 3686858538eSMatthew G. Knepley if (d >= 0) PetscCall(DMSetCoordinateDim(dm, d)); 3696858538eSMatthew G. Knepley } 3706858538eSMatthew G. Knepley PetscFunctionReturn(0); 3716858538eSMatthew G. Knepley } 3726858538eSMatthew G. Knepley 3736858538eSMatthew G. Knepley /*@ 3746858538eSMatthew G. Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 3756858538eSMatthew G. Knepley 3766858538eSMatthew G. Knepley Collective on dm 3776858538eSMatthew G. Knepley 3786858538eSMatthew G. Knepley Input Parameter: 3796858538eSMatthew G. Knepley . dm - the DM 3806858538eSMatthew G. Knepley 3816858538eSMatthew G. Knepley Output Parameter: 3826858538eSMatthew G. Knepley . c - global coordinate vector 3836858538eSMatthew G. Knepley 3846858538eSMatthew G. Knepley Note: 3856858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 3866858538eSMatthew G. Knepley destroyed the array will no longer be valid. 3876858538eSMatthew G. Knepley 3886858538eSMatthew G. Knepley Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 3896858538eSMatthew G. Knepley 3906858538eSMatthew G. Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 3916858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 3926858538eSMatthew G. Knepley 3936858538eSMatthew G. Knepley Level: intermediate 3946858538eSMatthew G. Knepley 3956858538eSMatthew G. Knepley .seealso: `DMSetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetCoordinateDM()`, `DMDASetUniformCoordinates()` 3966858538eSMatthew G. Knepley @*/ 397d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 398d71ae5a4SJacob Faibussowitsch { 3996858538eSMatthew G. Knepley PetscFunctionBegin; 4006858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4016858538eSMatthew G. Knepley PetscValidPointer(c, 2); 4026858538eSMatthew G. Knepley if (!dm->coordinates[0].x && dm->coordinates[0].xl) { 4036858538eSMatthew G. Knepley DM cdm = NULL; 4046858538eSMatthew G. Knepley 4056858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 4066858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdm, &dm->coordinates[0].x)); 4076858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[0].x, "coordinates")); 4086858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(cdm, dm->coordinates[0].xl, INSERT_VALUES, dm->coordinates[0].x)); 4096858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(cdm, dm->coordinates[0].xl, INSERT_VALUES, dm->coordinates[0].x)); 4106858538eSMatthew G. Knepley } 4116858538eSMatthew G. Knepley *c = dm->coordinates[0].x; 4126858538eSMatthew G. Knepley PetscFunctionReturn(0); 4136858538eSMatthew G. Knepley } 4146858538eSMatthew G. Knepley 4156858538eSMatthew G. Knepley /*@ 4166858538eSMatthew G. Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 4176858538eSMatthew G. Knepley 4186858538eSMatthew G. Knepley Collective on dm 4196858538eSMatthew G. Knepley 4206858538eSMatthew G. Knepley Input Parameters: 4216858538eSMatthew G. Knepley + dm - the DM 4226858538eSMatthew G. Knepley - c - coordinate vector 4236858538eSMatthew G. Knepley 4246858538eSMatthew G. Knepley Notes: 4256858538eSMatthew G. Knepley The coordinates do include those for ghost points, which are in the local vector. 4266858538eSMatthew G. Knepley 4276858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 4286858538eSMatthew G. Knepley 4296858538eSMatthew G. Knepley Level: intermediate 4306858538eSMatthew G. Knepley 4316858538eSMatthew G. Knepley .seealso: `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetCoordinateDM()`, `DMDASetUniformCoordinates()` 4326858538eSMatthew G. Knepley @*/ 433d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinates(DM dm, Vec c) 434d71ae5a4SJacob Faibussowitsch { 4356858538eSMatthew G. Knepley PetscFunctionBegin; 4366858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4376858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 4386858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 4396858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].x)); 4406858538eSMatthew G. Knepley dm->coordinates[0].x = c; 4416858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].xl)); 4426858538eSMatthew G. Knepley PetscCall(DMCoarsenHookAdd(dm, DMRestrictHook_Coordinates, NULL, NULL)); 4436858538eSMatthew G. Knepley PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_Coordinates, NULL, NULL)); 4446858538eSMatthew G. Knepley PetscFunctionReturn(0); 4456858538eSMatthew G. Knepley } 4466858538eSMatthew G. Knepley 4476858538eSMatthew G. Knepley /*@ 4486858538eSMatthew G. Knepley DMGetCellCoordinates - Gets a global vector with the cellwise coordinates associated with the DM. 4496858538eSMatthew G. Knepley 4506858538eSMatthew G. Knepley Collective on dm 4516858538eSMatthew G. Knepley 4526858538eSMatthew G. Knepley Input Parameter: 4536858538eSMatthew G. Knepley . dm - the DM 4546858538eSMatthew G. Knepley 4556858538eSMatthew G. Knepley Output Parameter: 4566858538eSMatthew G. Knepley . c - global coordinate vector 4576858538eSMatthew G. Knepley 4586858538eSMatthew G. Knepley Note: 4596858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 4606858538eSMatthew G. Knepley destroyed the array will no longer be valid. 4616858538eSMatthew G. Knepley 4626858538eSMatthew G. Knepley Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 4636858538eSMatthew G. Knepley 4646858538eSMatthew G. Knepley Level: intermediate 4656858538eSMatthew G. Knepley 4666858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMGetCellCoordinateDM()` 4676858538eSMatthew G. Knepley @*/ 468d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinates(DM dm, Vec *c) 469d71ae5a4SJacob Faibussowitsch { 4706858538eSMatthew G. Knepley PetscFunctionBegin; 4716858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4726858538eSMatthew G. Knepley PetscValidPointer(c, 2); 4736858538eSMatthew G. Knepley if (!dm->coordinates[1].x && dm->coordinates[1].xl) { 4746858538eSMatthew G. Knepley DM cdm = NULL; 4756858538eSMatthew G. Knepley 47611ea91a7SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 4776858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdm, &dm->coordinates[1].x)); 4786858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[1].x, "DG coordinates")); 4796858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(cdm, dm->coordinates[1].xl, INSERT_VALUES, dm->coordinates[1].x)); 4806858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(cdm, dm->coordinates[1].xl, INSERT_VALUES, dm->coordinates[1].x)); 4816858538eSMatthew G. Knepley } 4826858538eSMatthew G. Knepley *c = dm->coordinates[1].x; 4836858538eSMatthew G. Knepley PetscFunctionReturn(0); 4846858538eSMatthew G. Knepley } 4856858538eSMatthew G. Knepley 4866858538eSMatthew G. Knepley /*@ 4876858538eSMatthew G. Knepley DMSetCellCoordinates - Sets into the DM a global vector that holds the cellwise coordinates 4886858538eSMatthew G. Knepley 4896858538eSMatthew G. Knepley Collective on dm 4906858538eSMatthew G. Knepley 4916858538eSMatthew G. Knepley Input Parameters: 4926858538eSMatthew G. Knepley + dm - the DM 4936858538eSMatthew G. Knepley - c - cellwise coordinate vector 4946858538eSMatthew G. Knepley 4956858538eSMatthew G. Knepley Notes: 4966858538eSMatthew G. Knepley The coordinates do include those for ghost points, which are in the local vector. 4976858538eSMatthew G. Knepley 4986858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 4996858538eSMatthew G. Knepley 5006858538eSMatthew G. Knepley Level: intermediate 5016858538eSMatthew G. Knepley 5026858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMGetCellCoordinateDM()` 5036858538eSMatthew G. Knepley @*/ 504d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinates(DM dm, Vec c) 505d71ae5a4SJacob Faibussowitsch { 5066858538eSMatthew G. Knepley PetscFunctionBegin; 5076858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5086858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 5096858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 5106858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].x)); 5116858538eSMatthew G. Knepley dm->coordinates[1].x = c; 5126858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].xl)); 5136858538eSMatthew G. Knepley PetscFunctionReturn(0); 5146858538eSMatthew G. Knepley } 5156858538eSMatthew G. Knepley 5166858538eSMatthew G. Knepley /*@ 5176858538eSMatthew G. Knepley DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 5186858538eSMatthew G. Knepley 5196858538eSMatthew G. Knepley Collective on dm 5206858538eSMatthew G. Knepley 5216858538eSMatthew G. Knepley Input Parameter: 5226858538eSMatthew G. Knepley . dm - the DM 5236858538eSMatthew G. Knepley 5246858538eSMatthew G. Knepley Level: advanced 5256858538eSMatthew G. Knepley 5266858538eSMatthew G. Knepley .seealso: `DMGetCoordinatesLocalNoncollective()` 5276858538eSMatthew G. Knepley @*/ 528d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 529d71ae5a4SJacob Faibussowitsch { 5306858538eSMatthew G. Knepley PetscFunctionBegin; 5316858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5326858538eSMatthew G. Knepley if (!dm->coordinates[0].xl && dm->coordinates[0].x) { 5336858538eSMatthew G. Knepley DM cdm = NULL; 5346858538eSMatthew G. Knepley 5356858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 5366858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(cdm, &dm->coordinates[0].xl)); 5376858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[0].xl, "coordinates")); 5386858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(cdm, dm->coordinates[0].x, INSERT_VALUES, dm->coordinates[0].xl)); 5396858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(cdm, dm->coordinates[0].x, INSERT_VALUES, dm->coordinates[0].xl)); 5406858538eSMatthew G. Knepley } 5416858538eSMatthew G. Knepley PetscFunctionReturn(0); 5426858538eSMatthew G. Knepley } 5436858538eSMatthew G. Knepley 5446858538eSMatthew G. Knepley /*@ 5456858538eSMatthew G. Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 5466858538eSMatthew G. Knepley 5476858538eSMatthew G. Knepley Collective on dm 5486858538eSMatthew G. Knepley 5496858538eSMatthew G. Knepley Input Parameter: 5506858538eSMatthew G. Knepley . dm - the DM 5516858538eSMatthew G. Knepley 5526858538eSMatthew G. Knepley Output Parameter: 5536858538eSMatthew G. Knepley . c - coordinate vector 5546858538eSMatthew G. Knepley 5556858538eSMatthew G. Knepley Note: 5566858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector 5576858538eSMatthew G. Knepley 5586858538eSMatthew G. Knepley Each process has the local and ghost coordinates 5596858538eSMatthew G. Knepley 5606858538eSMatthew G. Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 5616858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 5626858538eSMatthew G. Knepley 5636858538eSMatthew G. Knepley Level: intermediate 5646858538eSMatthew G. Knepley 5656858538eSMatthew G. Knepley .seealso: `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()`, `DMGetCoordinatesLocalNoncollective()` 5666858538eSMatthew G. Knepley @*/ 567d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 568d71ae5a4SJacob Faibussowitsch { 5696858538eSMatthew G. Knepley PetscFunctionBegin; 5706858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5716858538eSMatthew G. Knepley PetscValidPointer(c, 2); 5726858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(dm)); 5736858538eSMatthew G. Knepley *c = dm->coordinates[0].xl; 5746858538eSMatthew G. Knepley PetscFunctionReturn(0); 5756858538eSMatthew G. Knepley } 5766858538eSMatthew G. Knepley 5776858538eSMatthew G. Knepley /*@ 5786858538eSMatthew G. Knepley DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 5796858538eSMatthew G. Knepley 5806858538eSMatthew G. Knepley Not collective 5816858538eSMatthew G. Knepley 5826858538eSMatthew G. Knepley Input Parameter: 5836858538eSMatthew G. Knepley . dm - the DM 5846858538eSMatthew G. Knepley 5856858538eSMatthew G. Knepley Output Parameter: 5866858538eSMatthew G. Knepley . c - coordinate vector 5876858538eSMatthew G. Knepley 5886858538eSMatthew G. Knepley Level: advanced 5896858538eSMatthew G. Knepley 5906858538eSMatthew G. Knepley .seealso: `DMGetCoordinatesLocalSetUp()`, `DMGetCoordinatesLocal()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()` 5916858538eSMatthew G. Knepley @*/ 592d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 593d71ae5a4SJacob Faibussowitsch { 5946858538eSMatthew G. Knepley PetscFunctionBegin; 5956858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5966858538eSMatthew G. Knepley PetscValidPointer(c, 2); 5976858538eSMatthew G. Knepley PetscCheck(dm->coordinates[0].xl || !dm->coordinates[0].x, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 5986858538eSMatthew G. Knepley *c = dm->coordinates[0].xl; 5996858538eSMatthew G. Knepley PetscFunctionReturn(0); 6006858538eSMatthew G. Knepley } 6016858538eSMatthew G. Knepley 6026858538eSMatthew G. Knepley /*@ 6036858538eSMatthew G. Knepley DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 6046858538eSMatthew G. Knepley 6056858538eSMatthew G. Knepley Not collective 6066858538eSMatthew G. Knepley 6076858538eSMatthew G. Knepley Input Parameters: 6086858538eSMatthew G. Knepley + dm - the DM 6096858538eSMatthew G. Knepley - p - the IS of points whose coordinates will be returned 6106858538eSMatthew G. Knepley 6116858538eSMatthew G. Knepley Output Parameters: 6126858538eSMatthew G. Knepley + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates 6136858538eSMatthew G. Knepley - pCoord - the Vec with coordinates of points in p 6146858538eSMatthew G. Knepley 6156858538eSMatthew G. Knepley Note: 6166858538eSMatthew G. Knepley DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 6176858538eSMatthew G. Knepley 6186858538eSMatthew G. Knepley This creates a new vector, so the user SHOULD destroy this vector 6196858538eSMatthew G. Knepley 6206858538eSMatthew G. Knepley Each process has the local and ghost coordinates 6216858538eSMatthew G. Knepley 6226858538eSMatthew G. Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 6236858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 6246858538eSMatthew G. Knepley 6256858538eSMatthew G. Knepley Level: advanced 6266858538eSMatthew G. Knepley 6276858538eSMatthew G. Knepley .seealso: `DMSetCoordinatesLocal()`, `DMGetCoordinatesLocal()`, `DMGetCoordinatesLocalNoncollective()`, `DMGetCoordinatesLocalSetUp()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()` 6286858538eSMatthew G. Knepley @*/ 629d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 630d71ae5a4SJacob Faibussowitsch { 6316858538eSMatthew G. Knepley DM cdm; 6326858538eSMatthew G. Knepley PetscSection cs, newcs; 6336858538eSMatthew G. Knepley Vec coords; 6346858538eSMatthew G. Knepley const PetscScalar *arr; 6356858538eSMatthew G. Knepley PetscScalar *newarr = NULL; 6366858538eSMatthew G. Knepley PetscInt n; 6376858538eSMatthew G. Knepley 6386858538eSMatthew G. Knepley PetscFunctionBegin; 6396858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6406858538eSMatthew G. Knepley PetscValidHeaderSpecific(p, IS_CLASSID, 2); 6416858538eSMatthew G. Knepley if (pCoordSection) PetscValidPointer(pCoordSection, 3); 6426858538eSMatthew G. Knepley if (pCoord) PetscValidPointer(pCoord, 4); 6436858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 6446858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(cdm, &cs)); 6456858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coords)); 6466858538eSMatthew G. Knepley PetscCheck(coords, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 6476858538eSMatthew G. Knepley PetscCheck(cdm && cs, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 6486858538eSMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &arr)); 6496858538eSMatthew G. Knepley PetscCall(PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void **)&newarr) : NULL)); 6506858538eSMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &arr)); 6516858538eSMatthew G. Knepley if (pCoord) { 6526858538eSMatthew G. Knepley PetscCall(PetscSectionGetStorageSize(newcs, &n)); 6536858538eSMatthew G. Knepley /* set array in two steps to mimic PETSC_OWN_POINTER */ 6546858538eSMatthew G. Knepley PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord)); 6556858538eSMatthew G. Knepley PetscCall(VecReplaceArray(*pCoord, newarr)); 6566858538eSMatthew G. Knepley } else { 6576858538eSMatthew G. Knepley PetscCall(PetscFree(newarr)); 6586858538eSMatthew G. Knepley } 6599371c9d4SSatish Balay if (pCoordSection) { 6609371c9d4SSatish Balay *pCoordSection = newcs; 6619371c9d4SSatish Balay } else PetscCall(PetscSectionDestroy(&newcs)); 6626858538eSMatthew G. Knepley PetscFunctionReturn(0); 6636858538eSMatthew G. Knepley } 6646858538eSMatthew G. Knepley 6656858538eSMatthew G. Knepley /*@ 6666858538eSMatthew G. Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 6676858538eSMatthew G. Knepley 6686858538eSMatthew G. Knepley Not collective 6696858538eSMatthew G. Knepley 6706858538eSMatthew G. Knepley Input Parameters: 6716858538eSMatthew G. Knepley + dm - the DM 6726858538eSMatthew G. Knepley - c - coordinate vector 6736858538eSMatthew G. Knepley 6746858538eSMatthew G. Knepley Notes: 6756858538eSMatthew G. Knepley The coordinates of ghost points can be set using DMSetCoordinates() 6766858538eSMatthew G. Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 6776858538eSMatthew G. Knepley setting of ghost coordinates outside of the domain. 6786858538eSMatthew G. Knepley 6796858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 6806858538eSMatthew G. Knepley 6816858538eSMatthew G. Knepley Level: intermediate 6826858538eSMatthew G. Knepley 6836858538eSMatthew G. Knepley .seealso: `DMGetCoordinatesLocal()`, `DMSetCoordinates()`, `DMGetCoordinates()`, `DMGetCoordinateDM()` 6846858538eSMatthew G. Knepley @*/ 685d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 686d71ae5a4SJacob Faibussowitsch { 6876858538eSMatthew G. Knepley PetscFunctionBegin; 6886858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6896858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 6906858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 6916858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].xl)); 6926858538eSMatthew G. Knepley dm->coordinates[0].xl = c; 6936858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].x)); 6946858538eSMatthew G. Knepley PetscFunctionReturn(0); 6956858538eSMatthew G. Knepley } 6966858538eSMatthew G. Knepley 6976858538eSMatthew G. Knepley /*@ 6986858538eSMatthew G. Knepley DMGetCellCoordinatesLocalSetUp - Prepares a local vector of cellwise coordinates, so that DMGetCellCoordinatesLocalNoncollective() can be used as non-collective afterwards. 6996858538eSMatthew G. Knepley 7006858538eSMatthew G. Knepley Collective on dm 7016858538eSMatthew G. Knepley 7026858538eSMatthew G. Knepley Input Parameter: 7036858538eSMatthew G. Knepley . dm - the DM 7046858538eSMatthew G. Knepley 7056858538eSMatthew G. Knepley Level: advanced 7066858538eSMatthew G. Knepley 7076858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinatesLocalNoncollective()` 7086858538eSMatthew G. Knepley @*/ 709d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinatesLocalSetUp(DM dm) 710d71ae5a4SJacob Faibussowitsch { 7116858538eSMatthew G. Knepley PetscFunctionBegin; 7126858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7136858538eSMatthew G. Knepley if (!dm->coordinates[1].xl && dm->coordinates[1].x) { 7146858538eSMatthew G. Knepley DM cdm = NULL; 7156858538eSMatthew G. Knepley 71611ea91a7SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 7176858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(cdm, &dm->coordinates[1].xl)); 7186858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[1].xl, "DG coordinates")); 7196858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(cdm, dm->coordinates[1].x, INSERT_VALUES, dm->coordinates[1].xl)); 7206858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(cdm, dm->coordinates[1].x, INSERT_VALUES, dm->coordinates[1].xl)); 7216858538eSMatthew G. Knepley } 7226858538eSMatthew G. Knepley PetscFunctionReturn(0); 7236858538eSMatthew G. Knepley } 7246858538eSMatthew G. Knepley 7256858538eSMatthew G. Knepley /*@ 7266858538eSMatthew G. Knepley DMGetCellCoordinatesLocal - Gets a local vector with the cellwise coordinates associated with the DM. 7276858538eSMatthew G. Knepley 7286858538eSMatthew G. Knepley Collective on dm 7296858538eSMatthew G. Knepley 7306858538eSMatthew G. Knepley Input Parameter: 7316858538eSMatthew G. Knepley . dm - the DM 7326858538eSMatthew G. Knepley 7336858538eSMatthew G. Knepley Output Parameter: 7346858538eSMatthew G. Knepley . c - coordinate vector 7356858538eSMatthew G. Knepley 7366858538eSMatthew G. Knepley Note: 7376858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector 7386858538eSMatthew G. Knepley 7396858538eSMatthew G. Knepley Each process has the local and ghost coordinates 7406858538eSMatthew G. Knepley 7416858538eSMatthew G. Knepley Level: intermediate 7426858538eSMatthew G. Knepley 7436858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinateDM()`, `DMGetCellCoordinatesLocalNoncollective()` 7446858538eSMatthew G. Knepley @*/ 745d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinatesLocal(DM dm, Vec *c) 746d71ae5a4SJacob Faibussowitsch { 7476858538eSMatthew G. Knepley PetscFunctionBegin; 7486858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7496858538eSMatthew G. Knepley PetscValidPointer(c, 2); 7506858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocalSetUp(dm)); 7516858538eSMatthew G. Knepley *c = dm->coordinates[1].xl; 7526858538eSMatthew G. Knepley PetscFunctionReturn(0); 7536858538eSMatthew G. Knepley } 7546858538eSMatthew G. Knepley 7556858538eSMatthew G. Knepley /*@ 7566858538eSMatthew G. Knepley DMGetCellCoordinatesLocalNoncollective - Non-collective version of DMGetCellCoordinatesLocal(). Fails if global cellwise coordinates have been set and DMGetCellCoordinatesLocalSetUp() not called. 7576858538eSMatthew G. Knepley 7586858538eSMatthew G. Knepley Not collective 7596858538eSMatthew G. Knepley 7606858538eSMatthew G. Knepley Input Parameter: 7616858538eSMatthew G. Knepley . dm - the DM 7626858538eSMatthew G. Knepley 7636858538eSMatthew G. Knepley Output Parameter: 7646858538eSMatthew G. Knepley . c - cellwise coordinate vector 7656858538eSMatthew G. Knepley 7666858538eSMatthew G. Knepley Level: advanced 7676858538eSMatthew G. Knepley 7686858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinatesLocalSetUp()`, `DMGetCellCoordinatesLocal()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinateDM()` 7696858538eSMatthew G. Knepley @*/ 770d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinatesLocalNoncollective(DM dm, Vec *c) 771d71ae5a4SJacob Faibussowitsch { 7726858538eSMatthew G. Knepley PetscFunctionBegin; 7736858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7746858538eSMatthew G. Knepley PetscValidPointer(c, 2); 7756858538eSMatthew G. Knepley PetscCheck(dm->coordinates[1].xl || !dm->coordinates[1].x, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCellCoordinatesLocalSetUp() has not been called"); 7766858538eSMatthew G. Knepley *c = dm->coordinates[1].xl; 7776858538eSMatthew G. Knepley PetscFunctionReturn(0); 7786858538eSMatthew G. Knepley } 7796858538eSMatthew G. Knepley 7806858538eSMatthew G. Knepley /*@ 7816858538eSMatthew G. Knepley DMSetCellCoordinatesLocal - Sets into the DM a local vector that holds the cellwise coordinates 7826858538eSMatthew G. Knepley 7836858538eSMatthew G. Knepley Not collective 7846858538eSMatthew G. Knepley 7856858538eSMatthew G. Knepley Input Parameters: 7866858538eSMatthew G. Knepley + dm - the DM 7876858538eSMatthew G. Knepley - c - cellwise coordinate vector 7886858538eSMatthew G. Knepley 7896858538eSMatthew G. Knepley Notes: 7906858538eSMatthew G. Knepley The coordinates of ghost points can be set using DMSetCoordinates() 7916858538eSMatthew G. Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 7926858538eSMatthew G. Knepley setting of ghost coordinates outside of the domain. 7936858538eSMatthew G. Knepley 7946858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 7956858538eSMatthew G. Knepley 7966858538eSMatthew G. Knepley Level: intermediate 7976858538eSMatthew G. Knepley 7986858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinatesLocal()`, `DMSetCellCoordinates()`, `DMGetCellCoordinates()`, `DMGetCellCoordinateDM()` 7996858538eSMatthew G. Knepley @*/ 800d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinatesLocal(DM dm, Vec c) 801d71ae5a4SJacob Faibussowitsch { 8026858538eSMatthew G. Knepley PetscFunctionBegin; 8036858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8046858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 8056858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 8066858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].xl)); 8076858538eSMatthew G. Knepley dm->coordinates[1].xl = c; 8086858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].x)); 8096858538eSMatthew G. Knepley PetscFunctionReturn(0); 8106858538eSMatthew G. Knepley } 8116858538eSMatthew G. Knepley 812d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 813d71ae5a4SJacob Faibussowitsch { 8146858538eSMatthew G. Knepley PetscFunctionBegin; 8156858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8166858538eSMatthew G. Knepley PetscValidPointer(field, 2); 8176858538eSMatthew G. Knepley if (!dm->coordinates[0].field) { 8186858538eSMatthew G. Knepley if (dm->ops->createcoordinatefield) PetscCall((*dm->ops->createcoordinatefield)(dm, &dm->coordinates[0].field)); 8196858538eSMatthew G. Knepley } 8206858538eSMatthew G. Knepley *field = dm->coordinates[0].field; 8216858538eSMatthew G. Knepley PetscFunctionReturn(0); 8226858538eSMatthew G. Knepley } 8236858538eSMatthew G. Knepley 824d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 825d71ae5a4SJacob Faibussowitsch { 8266858538eSMatthew G. Knepley PetscFunctionBegin; 8276858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8286858538eSMatthew G. Knepley if (field) PetscValidHeaderSpecific(field, DMFIELD_CLASSID, 2); 8296858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)field)); 8306858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&dm->coordinates[0].field)); 8316858538eSMatthew G. Knepley dm->coordinates[0].field = field; 8326858538eSMatthew G. Knepley PetscFunctionReturn(0); 8336858538eSMatthew G. Knepley } 8346858538eSMatthew G. Knepley 8356858538eSMatthew G. Knepley /*@ 8366858538eSMatthew G. Knepley DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process. 8376858538eSMatthew G. Knepley 8386858538eSMatthew G. Knepley Not collective 8396858538eSMatthew G. Knepley 8406858538eSMatthew G. Knepley Input Parameter: 8416858538eSMatthew G. Knepley . dm - the DM 8426858538eSMatthew G. Knepley 8436858538eSMatthew G. Knepley Output Parameters: 8446858538eSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional) 8456858538eSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional) 8466858538eSMatthew G. Knepley 8476858538eSMatthew G. Knepley Level: beginner 8486858538eSMatthew G. Knepley 8496858538eSMatthew G. Knepley Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead. 8506858538eSMatthew G. Knepley 8516858538eSMatthew G. Knepley .seealso: `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetBoundingBox()` 8526858538eSMatthew G. Knepley @*/ 853d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[]) 854d71ae5a4SJacob Faibussowitsch { 8556858538eSMatthew G. Knepley Vec coords = NULL; 8566858538eSMatthew G. Knepley PetscReal min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 8576858538eSMatthew G. Knepley PetscReal max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 8586858538eSMatthew G. Knepley PetscInt cdim, i, j; 8596858538eSMatthew G. Knepley 8606858538eSMatthew G. Knepley PetscFunctionBegin; 8616858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8626858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 863bdf15c88SMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coords)); 864bdf15c88SMatthew G. Knepley if (coords) { 865bdf15c88SMatthew G. Knepley const PetscScalar *local_coords; 866bdf15c88SMatthew G. Knepley PetscInt N, Ni; 867bdf15c88SMatthew G. Knepley 868bdf15c88SMatthew G. Knepley for (j = cdim; j < 3; ++j) { 869bdf15c88SMatthew G. Knepley min[j] = 0; 870bdf15c88SMatthew G. Knepley max[j] = 0; 871bdf15c88SMatthew G. Knepley } 872bdf15c88SMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &local_coords)); 873bdf15c88SMatthew G. Knepley PetscCall(VecGetLocalSize(coords, &N)); 874bdf15c88SMatthew G. Knepley Ni = N / cdim; 875bdf15c88SMatthew G. Knepley for (i = 0; i < Ni; ++i) { 876bdf15c88SMatthew G. Knepley for (j = 0; j < cdim; ++j) { 877bdf15c88SMatthew G. Knepley min[j] = PetscMin(min[j], PetscRealPart(local_coords[i * cdim + j])); 878bdf15c88SMatthew G. Knepley max[j] = PetscMax(max[j], PetscRealPart(local_coords[i * cdim + j])); 879bdf15c88SMatthew G. Knepley } 880bdf15c88SMatthew G. Knepley } 881bdf15c88SMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &local_coords)); 882bdf15c88SMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 8836858538eSMatthew G. Knepley if (coords) { 8846858538eSMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &local_coords)); 8856858538eSMatthew G. Knepley PetscCall(VecGetLocalSize(coords, &N)); 8866858538eSMatthew G. Knepley Ni = N / cdim; 8876858538eSMatthew G. Knepley for (i = 0; i < Ni; ++i) { 888bdf15c88SMatthew G. Knepley for (j = 0; j < cdim; ++j) { 889bdf15c88SMatthew G. Knepley min[j] = PetscMin(min[j], PetscRealPart(local_coords[i * cdim + j])); 890bdf15c88SMatthew G. Knepley max[j] = PetscMax(max[j], PetscRealPart(local_coords[i * cdim + j])); 8916858538eSMatthew G. Knepley } 8926858538eSMatthew G. Knepley } 8936858538eSMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &local_coords)); 894bdf15c88SMatthew G. Knepley } 8956858538eSMatthew G. Knepley } else { 8966858538eSMatthew G. Knepley PetscBool isda; 8976858538eSMatthew G. Knepley 8986858538eSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda)); 8996858538eSMatthew G. Knepley if (isda) PetscCall(DMGetLocalBoundingIndices_DMDA(dm, min, max)); 9006858538eSMatthew G. Knepley } 9016858538eSMatthew G. Knepley if (lmin) PetscCall(PetscArraycpy(lmin, min, cdim)); 9026858538eSMatthew G. Knepley if (lmax) PetscCall(PetscArraycpy(lmax, max, cdim)); 9036858538eSMatthew G. Knepley PetscFunctionReturn(0); 9046858538eSMatthew G. Knepley } 9056858538eSMatthew G. Knepley 9066858538eSMatthew G. Knepley /*@ 9076858538eSMatthew G. Knepley DMGetBoundingBox - Returns the global bounding box for the DM. 9086858538eSMatthew G. Knepley 9096858538eSMatthew G. Knepley Collective 9106858538eSMatthew G. Knepley 9116858538eSMatthew G. Knepley Input Parameter: 9126858538eSMatthew G. Knepley . dm - the DM 9136858538eSMatthew G. Knepley 9146858538eSMatthew G. Knepley Output Parameters: 9156858538eSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional) 9166858538eSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional) 9176858538eSMatthew G. Knepley 9186858538eSMatthew G. Knepley Level: beginner 9196858538eSMatthew G. Knepley 9206858538eSMatthew G. Knepley .seealso: `DMGetLocalBoundingBox()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()` 9216858538eSMatthew G. Knepley @*/ 922d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[]) 923d71ae5a4SJacob Faibussowitsch { 9246858538eSMatthew G. Knepley PetscReal lmin[3], lmax[3]; 9256858538eSMatthew G. Knepley PetscInt cdim; 9266858538eSMatthew G. Knepley PetscMPIInt count; 9276858538eSMatthew G. Knepley 9286858538eSMatthew G. Knepley PetscFunctionBegin; 9296858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9306858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 9316858538eSMatthew G. Knepley PetscCall(PetscMPIIntCast(cdim, &count)); 9326858538eSMatthew G. Knepley PetscCall(DMGetLocalBoundingBox(dm, lmin, lmax)); 9336858538eSMatthew G. Knepley if (gmin) PetscCall(MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)dm))); 9346858538eSMatthew G. Knepley if (gmax) PetscCall(MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)dm))); 9356858538eSMatthew G. Knepley PetscFunctionReturn(0); 9366858538eSMatthew G. Knepley } 9376858538eSMatthew G. Knepley 9386858538eSMatthew G. Knepley /*@ 9396858538eSMatthew G. Knepley DMProjectCoordinates - Project coordinates to a different space 9406858538eSMatthew G. Knepley 9416858538eSMatthew G. Knepley Input Parameters: 9426858538eSMatthew G. Knepley + dm - The DM object 9436858538eSMatthew G. Knepley - disc - The new coordinate discretization or NULL to ensure a coordinate discretization exists 9446858538eSMatthew G. Knepley 9456858538eSMatthew G. Knepley Level: intermediate 9466858538eSMatthew G. Knepley 9476858538eSMatthew G. Knepley .seealso: `DMGetCoordinateField()` 9486858538eSMatthew G. Knepley @*/ 949d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 950d71ae5a4SJacob Faibussowitsch { 9516858538eSMatthew G. Knepley PetscFE discOld; 9526858538eSMatthew G. Knepley PetscClassId classid; 9536858538eSMatthew G. Knepley DM cdmOld, cdmNew; 9546858538eSMatthew G. Knepley Vec coordsOld, coordsNew; 9556858538eSMatthew G. Knepley Mat matInterp; 9566858538eSMatthew G. Knepley PetscBool same_space = PETSC_TRUE; 957dd4c3f67SMatthew G. Knepley const char *prefix; 9586858538eSMatthew G. Knepley 9596858538eSMatthew G. Knepley PetscFunctionBegin; 9606858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9616858538eSMatthew G. Knepley if (disc) PetscValidHeaderSpecific(disc, PETSCFE_CLASSID, 2); 9626858538eSMatthew G. Knepley 9636858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdmOld)); 9646858538eSMatthew G. Knepley /* Check current discretization is compatible */ 9656858538eSMatthew G. Knepley PetscCall(DMGetField(cdmOld, 0, NULL, (PetscObject *)&discOld)); 9666858538eSMatthew G. Knepley PetscCall(PetscObjectGetClassId((PetscObject)discOld, &classid)); 9676858538eSMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 9686858538eSMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 9696858538eSMatthew G. Knepley PetscFE feLinear; 9706858538eSMatthew G. Knepley DMPolytopeType ct; 971*dc431b0cSMatthew G. Knepley PetscInt dim, dE, cStart, cEnd, ctTmp; 9726858538eSMatthew G. Knepley 9736858538eSMatthew G. Knepley /* Assume linear vertex coordinates */ 9746858538eSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 9756858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &dE)); 9766858538eSMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 977*dc431b0cSMatthew G. Knepley if (cEnd > cStart) PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 978*dc431b0cSMatthew G. Knepley else ct = DM_POLYTOPE_UNKNOWN; 979*dc431b0cSMatthew G. Knepley ctTmp = (PetscInt)ct; 980*dc431b0cSMatthew G. Knepley PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &ctTmp, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm))); 981*dc431b0cSMatthew G. Knepley ct = (DMPolytopeType)ctTmp; 982*dc431b0cSMatthew G. Knepley PetscCall(PetscFECreateLagrangeByCell(PETSC_COMM_SELF, dim, dE, ct, 1, -1, &feLinear)); 9836858538eSMatthew G. Knepley PetscCall(DMSetField(cdmOld, 0, NULL, (PetscObject)feLinear)); 9846858538eSMatthew G. Knepley PetscCall(PetscFEDestroy(&feLinear)); 9856858538eSMatthew G. Knepley PetscCall(DMCreateDS(cdmOld)); 9866858538eSMatthew G. Knepley PetscCall(DMGetField(cdmOld, 0, NULL, (PetscObject *)&discOld)); 9876858538eSMatthew G. Knepley } else { 9886858538eSMatthew G. Knepley const char *discname; 9896858538eSMatthew G. Knepley 9906858538eSMatthew G. Knepley PetscCall(PetscObjectGetType((PetscObject)discOld, &discname)); 9916858538eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 9926858538eSMatthew G. Knepley } 9936858538eSMatthew G. Knepley } 9946858538eSMatthew G. Knepley if (!disc) PetscFunctionReturn(0); 9956858538eSMatthew G. Knepley { // Check if the new space is the same as the old modulo quadrature 9966858538eSMatthew G. Knepley PetscDualSpace dsOld, ds; 9976858538eSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(discOld, &dsOld)); 9986858538eSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(disc, &ds)); 9996858538eSMatthew G. Knepley PetscCall(PetscDualSpaceEqual(dsOld, ds, &same_space)); 10006858538eSMatthew G. Knepley } 10016858538eSMatthew G. Knepley /* Make a fresh clone of the coordinate DM */ 10026858538eSMatthew G. Knepley PetscCall(DMClone(cdmOld, &cdmNew)); 1003dd4c3f67SMatthew G. Knepley cdmNew->cloneOpts = PETSC_TRUE; 1004dd4c3f67SMatthew G. Knepley PetscCall(PetscObjectGetOptionsPrefix((PetscObject)cdmOld, &prefix)); 1005dd4c3f67SMatthew G. Knepley PetscCall(PetscObjectSetOptionsPrefix((PetscObject)cdmNew, prefix)); 10066858538eSMatthew G. Knepley PetscCall(DMSetField(cdmNew, 0, NULL, (PetscObject)disc)); 10076858538eSMatthew G. Knepley PetscCall(DMCreateDS(cdmNew)); 1008dd4c3f67SMatthew G. Knepley if (dm->setfromoptionscalled) PetscCall(DMSetFromOptions(cdmNew)); 10096858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coordsOld)); 10106858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdmNew, &coordsNew)); 1011f0ac6e35SMatthew G. Knepley if (same_space) { 1012f0ac6e35SMatthew G. Knepley // Need to copy so that the new vector has the right dm 1013f0ac6e35SMatthew G. Knepley PetscCall(VecCopy(coordsOld, coordsNew)); 1014f0ac6e35SMatthew G. Knepley } else { 1015f0ac6e35SMatthew G. Knepley // Project the coordinate vector from old to new space 10166858538eSMatthew G. Knepley PetscCall(DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL)); 10176858538eSMatthew G. Knepley PetscCall(MatInterpolate(matInterp, coordsOld, coordsNew)); 10186858538eSMatthew G. Knepley PetscCall(MatDestroy(&matInterp)); 10196858538eSMatthew G. Knepley } 10206858538eSMatthew G. Knepley /* Set new coordinate structures */ 10216858538eSMatthew G. Knepley PetscCall(DMSetCoordinateField(dm, NULL)); 10226858538eSMatthew G. Knepley PetscCall(DMSetCoordinateDM(dm, cdmNew)); 10236858538eSMatthew G. Knepley PetscCall(DMSetCoordinates(dm, coordsNew)); 10246858538eSMatthew G. Knepley PetscCall(VecDestroy(&coordsNew)); 10256858538eSMatthew G. Knepley PetscCall(DMDestroy(&cdmNew)); 10266858538eSMatthew G. Knepley PetscFunctionReturn(0); 10276858538eSMatthew G. Knepley } 10286858538eSMatthew G. Knepley 10296858538eSMatthew G. Knepley /*@ 10306858538eSMatthew G. Knepley DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 10316858538eSMatthew G. Knepley 10326858538eSMatthew G. Knepley Collective on v (see explanation below) 10336858538eSMatthew G. Knepley 10346858538eSMatthew G. Knepley Input Parameters: 10356858538eSMatthew G. Knepley + dm - The DM 10366858538eSMatthew G. Knepley - ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 10376858538eSMatthew G. Knepley 10386858538eSMatthew G. Knepley Input/Output Parameters: 10396858538eSMatthew G. Knepley + v - The Vec of points, on output contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 10406858538eSMatthew G. Knepley - cellSF - Points to either NULL, or a PetscSF with guesses for which cells contain each point; 10416858538eSMatthew G. Knepley on output, the PetscSF containing the ranks and local indices of the containing points 10426858538eSMatthew G. Knepley 10436858538eSMatthew G. Knepley Level: developer 10446858538eSMatthew G. Knepley 10456858538eSMatthew G. Knepley Notes: 10466858538eSMatthew G. Knepley To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 10476858538eSMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 10486858538eSMatthew G. Knepley 1049d8206211SMatthew G. Knepley Points will only be located in owned cells, not overlap cells arising from `DMPlexDistribute()` or other overlapping distributions. 1050d8206211SMatthew G. Knepley 10516858538eSMatthew G. Knepley If *cellSF is NULL on input, a PetscSF will be created. 10526858538eSMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 10536858538eSMatthew G. Knepley 10546858538eSMatthew G. Knepley An array that maps each point to its containing cell can be obtained with 10556858538eSMatthew G. Knepley 10566858538eSMatthew G. Knepley $ const PetscSFNode *cells; 10576858538eSMatthew G. Knepley $ PetscInt nFound; 10586858538eSMatthew G. Knepley $ const PetscInt *found; 10596858538eSMatthew G. Knepley $ 10606858538eSMatthew G. Knepley $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 10616858538eSMatthew G. Knepley 10626858538eSMatthew G. Knepley Where cells[i].rank is the rank of the cell containing point found[i] (or i if found == NULL), and cells[i].index is 10636858538eSMatthew G. Knepley the index of the cell in its rank's local numbering. 10646858538eSMatthew G. Knepley 10656858538eSMatthew G. Knepley .seealso: `DMSetCoordinates()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMPointLocationType` 10666858538eSMatthew G. Knepley @*/ 1067d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 1068d71ae5a4SJacob Faibussowitsch { 10696858538eSMatthew G. Knepley PetscFunctionBegin; 10706858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10716858538eSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 10726858538eSMatthew G. Knepley PetscValidPointer(cellSF, 4); 10736858538eSMatthew G. Knepley if (*cellSF) { 10746858538eSMatthew G. Knepley PetscMPIInt result; 10756858538eSMatthew G. Knepley 10766858538eSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF, PETSCSF_CLASSID, 4); 10776858538eSMatthew G. Knepley PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)v), PetscObjectComm((PetscObject)*cellSF), &result)); 10786858538eSMatthew G. Knepley PetscCheck(result == MPI_IDENT || result == MPI_CONGRUENT, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "cellSF must have a communicator congruent to v's"); 10796858538eSMatthew G. Knepley } else { 10806858538eSMatthew G. Knepley PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)v), cellSF)); 10816858538eSMatthew G. Knepley } 10826858538eSMatthew G. Knepley PetscCall(PetscLogEventBegin(DM_LocatePoints, dm, 0, 0, 0)); 1083dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, locatepoints, v, ltype, *cellSF); 10846858538eSMatthew G. Knepley PetscCall(PetscLogEventEnd(DM_LocatePoints, dm, 0, 0, 0)); 10856858538eSMatthew G. Knepley PetscFunctionReturn(0); 10866858538eSMatthew G. Knepley } 1087