16858538eSMatthew G. Knepley #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 26858538eSMatthew G. Knepley 3e44f6aebSMatthew G. Knepley #include <petscdmplex.h> /* For DMCreateAffineCoordinates_Internal() */ 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; 114d86920dSPierre Jolivet 126858538eSMatthew G. Knepley PetscFunctionBegin; 136858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 146858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dmc, &dmc_coord)); 156858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coords)); 166858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dmc, &ccoords)); 176858538eSMatthew G. Knepley if (coords && !ccoords) { 186858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(dmc_coord, &ccoords)); 196858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)ccoords, "coordinates")); 206858538eSMatthew G. Knepley PetscCall(DMCreateInjection(dmc_coord, dm_coord, &inject)); 216858538eSMatthew G. Knepley PetscCall(MatRestrict(inject, coords, ccoords)); 226858538eSMatthew G. Knepley PetscCall(MatDestroy(&inject)); 236858538eSMatthew G. Knepley PetscCall(DMSetCoordinates(dmc, ccoords)); 246858538eSMatthew G. Knepley PetscCall(VecDestroy(&ccoords)); 256858538eSMatthew G. Knepley } 263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 276858538eSMatthew G. Knepley } 286858538eSMatthew G. Knepley 29d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_Coordinates(DM dm, DM subdm, void *ctx) 30d71ae5a4SJacob Faibussowitsch { 316858538eSMatthew G. Knepley DM dm_coord, subdm_coord; 326858538eSMatthew G. Knepley Vec coords, ccoords, clcoords; 336858538eSMatthew G. Knepley VecScatter *scat_i, *scat_g; 344d86920dSPierre Jolivet 356858538eSMatthew G. Knepley PetscFunctionBegin; 366858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 376858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(subdm, &subdm_coord)); 386858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coords)); 396858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(subdm, &ccoords)); 406858538eSMatthew G. Knepley if (coords && !ccoords) { 416858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(subdm_coord, &ccoords)); 426858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)ccoords, "coordinates")); 436858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(subdm_coord, &clcoords)); 446858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)clcoords, "coordinates")); 456858538eSMatthew G. Knepley PetscCall(DMCreateDomainDecompositionScatters(dm_coord, 1, &subdm_coord, NULL, &scat_i, &scat_g)); 466858538eSMatthew G. Knepley PetscCall(VecScatterBegin(scat_i[0], coords, ccoords, INSERT_VALUES, SCATTER_FORWARD)); 476858538eSMatthew G. Knepley PetscCall(VecScatterEnd(scat_i[0], coords, ccoords, INSERT_VALUES, SCATTER_FORWARD)); 486858538eSMatthew G. Knepley PetscCall(VecScatterBegin(scat_g[0], coords, clcoords, INSERT_VALUES, SCATTER_FORWARD)); 496858538eSMatthew G. Knepley PetscCall(VecScatterEnd(scat_g[0], coords, clcoords, INSERT_VALUES, SCATTER_FORWARD)); 506858538eSMatthew G. Knepley PetscCall(DMSetCoordinates(subdm, ccoords)); 516858538eSMatthew G. Knepley PetscCall(DMSetCoordinatesLocal(subdm, clcoords)); 526858538eSMatthew G. Knepley PetscCall(VecScatterDestroy(&scat_i[0])); 536858538eSMatthew G. Knepley PetscCall(VecScatterDestroy(&scat_g[0])); 546858538eSMatthew G. Knepley PetscCall(VecDestroy(&ccoords)); 556858538eSMatthew G. Knepley PetscCall(VecDestroy(&clcoords)); 566858538eSMatthew G. Knepley PetscCall(PetscFree(scat_i)); 576858538eSMatthew G. Knepley PetscCall(PetscFree(scat_g)); 586858538eSMatthew G. Knepley } 593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 606858538eSMatthew G. Knepley } 616858538eSMatthew G. Knepley 626858538eSMatthew G. Knepley /*@ 63dce8aebaSBarry Smith DMGetCoordinateDM - Gets the `DM` that prescribes coordinate layout and scatters between global and local coordinates 646858538eSMatthew G. Knepley 6520f4b53cSBarry Smith Collective 666858538eSMatthew G. Knepley 676858538eSMatthew G. Knepley Input Parameter: 68dce8aebaSBarry Smith . dm - the `DM` 696858538eSMatthew G. Knepley 706858538eSMatthew G. Knepley Output Parameter: 71dce8aebaSBarry Smith . cdm - coordinate `DM` 726858538eSMatthew G. Knepley 736858538eSMatthew G. Knepley Level: intermediate 746858538eSMatthew G. Knepley 75dce8aebaSBarry Smith .seealso: `DM`, `DMSetCoordinateDM()`, `DMSetCoordinates()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGSetCellCoordinateDM()`, 7660225df5SJacob Faibussowitsch 776858538eSMatthew G. Knepley @*/ 78d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 79d71ae5a4SJacob Faibussowitsch { 806858538eSMatthew G. Knepley PetscFunctionBegin; 816858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 824f572ea9SToby Isaac PetscAssertPointer(cdm, 2); 836858538eSMatthew G. Knepley if (!dm->coordinates[0].dm) { 846858538eSMatthew G. Knepley DM cdm; 856858538eSMatthew G. Knepley 86dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createcoordinatedm, &cdm); 876858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)cdm, "coordinateDM")); 886858538eSMatthew G. Knepley /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 896858538eSMatthew G. Knepley * until the call to CreateCoordinateDM) */ 906858538eSMatthew G. Knepley PetscCall(DMDestroy(&dm->coordinates[0].dm)); 916858538eSMatthew G. Knepley dm->coordinates[0].dm = cdm; 926858538eSMatthew G. Knepley } 936858538eSMatthew G. Knepley *cdm = dm->coordinates[0].dm; 943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 956858538eSMatthew G. Knepley } 966858538eSMatthew G. Knepley 976858538eSMatthew G. Knepley /*@ 98dce8aebaSBarry Smith DMSetCoordinateDM - Sets the `DM` that prescribes coordinate layout and scatters between global and local coordinates 996858538eSMatthew G. Knepley 10020f4b53cSBarry Smith Logically Collective 1016858538eSMatthew G. Knepley 1026858538eSMatthew G. Knepley Input Parameters: 103dce8aebaSBarry Smith + dm - the `DM` 104dce8aebaSBarry Smith - cdm - coordinate `DM` 1056858538eSMatthew G. Knepley 1066858538eSMatthew G. Knepley Level: intermediate 1076858538eSMatthew G. Knepley 108dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinateDM()`, `DMSetCoordinates()`, `DMGetCellCoordinateDM()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, 109dce8aebaSBarry Smith `DMGSetCellCoordinateDM()` 1106858538eSMatthew G. Knepley @*/ 111d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 112d71ae5a4SJacob Faibussowitsch { 1136858538eSMatthew G. Knepley PetscFunctionBegin; 1146858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11590612307SJed Brown if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 1166858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)cdm)); 1176858538eSMatthew G. Knepley PetscCall(DMDestroy(&dm->coordinates[0].dm)); 1186858538eSMatthew G. Knepley dm->coordinates[0].dm = cdm; 1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1206858538eSMatthew G. Knepley } 1216858538eSMatthew G. Knepley 1226858538eSMatthew G. Knepley /*@ 123dce8aebaSBarry Smith DMGetCellCoordinateDM - Gets the `DM` that prescribes cellwise coordinate layout and scatters between global and local cellwise coordinates 1246858538eSMatthew G. Knepley 12520f4b53cSBarry Smith Collective 1266858538eSMatthew G. Knepley 1276858538eSMatthew G. Knepley Input Parameter: 128dce8aebaSBarry Smith . dm - the `DM` 1296858538eSMatthew G. Knepley 1306858538eSMatthew G. Knepley Output Parameter: 1310b3275a6SBarry Smith . cdm - cellwise coordinate `DM`, or `NULL` if they are not defined 1326858538eSMatthew G. Knepley 1336858538eSMatthew G. Knepley Level: intermediate 1346858538eSMatthew G. Knepley 135dce8aebaSBarry Smith Note: 136dce8aebaSBarry Smith Call `DMLocalizeCoordinates()` to automatically create cellwise coordinates for periodic geometries. 137dce8aebaSBarry Smith 138dce8aebaSBarry Smith .seealso: `DM`, `DMSetCellCoordinateDM()`, `DMSetCellCoordinates()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, 139dce8aebaSBarry Smith `DMLocalizeCoordinates()`, `DMSetCoordinateDM()`, `DMGetCoordinateDM()` 1406858538eSMatthew G. Knepley @*/ 141d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinateDM(DM dm, DM *cdm) 142d71ae5a4SJacob Faibussowitsch { 1436858538eSMatthew G. Knepley PetscFunctionBegin; 1446858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1454f572ea9SToby Isaac PetscAssertPointer(cdm, 2); 1466858538eSMatthew G. Knepley *cdm = dm->coordinates[1].dm; 1473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1486858538eSMatthew G. Knepley } 1496858538eSMatthew G. Knepley 1506858538eSMatthew G. Knepley /*@ 151dce8aebaSBarry Smith DMSetCellCoordinateDM - Sets the `DM` that prescribes cellwise coordinate layout and scatters between global and local cellwise coordinates 1526858538eSMatthew G. Knepley 15320f4b53cSBarry Smith Logically Collective 1546858538eSMatthew G. Knepley 1556858538eSMatthew G. Knepley Input Parameters: 156dce8aebaSBarry Smith + dm - the `DM` 157dce8aebaSBarry Smith - cdm - cellwise coordinate `DM` 1586858538eSMatthew G. Knepley 1596858538eSMatthew G. Knepley Level: intermediate 1606858538eSMatthew G. Knepley 161dce8aebaSBarry Smith Note: 16235cb6cd3SPierre Jolivet As opposed to `DMSetCoordinateDM()` these coordinates are useful for discontinuous Galerkin methods since they support coordinate fields that are discontinuous at cell boundaries. 163dce8aebaSBarry Smith 164dce8aebaSBarry Smith .seealso: `DMGetCellCoordinateDM()`, `DMSetCellCoordinates()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, 165dce8aebaSBarry Smith `DMSetCoordinateDM()`, `DMGetCoordinateDM()` 1666858538eSMatthew G. Knepley @*/ 167d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinateDM(DM dm, DM cdm) 168d71ae5a4SJacob Faibussowitsch { 1696858538eSMatthew G. Knepley PetscInt dim; 1706858538eSMatthew G. Knepley 1716858538eSMatthew G. Knepley PetscFunctionBegin; 1726858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1736858538eSMatthew G. Knepley if (cdm) { 1746858538eSMatthew G. Knepley PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 1756858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &dim)); 1766858538eSMatthew G. Knepley dm->coordinates[1].dim = dim; 1776858538eSMatthew G. Knepley } 1786858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)cdm)); 1796858538eSMatthew G. Knepley PetscCall(DMDestroy(&dm->coordinates[1].dm)); 1806858538eSMatthew G. Knepley dm->coordinates[1].dm = cdm; 1813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1826858538eSMatthew G. Knepley } 1836858538eSMatthew G. Knepley 1846858538eSMatthew G. Knepley /*@ 1850b3275a6SBarry Smith DMGetCoordinateDim - Retrieve the dimension of the embedding space for coordinate values. For example a mesh on the surface of a sphere would have a 3 dimensional embedding space 1866858538eSMatthew G. Knepley 1876858538eSMatthew G. Knepley Not Collective 1886858538eSMatthew G. Knepley 1896858538eSMatthew G. Knepley Input Parameter: 190dce8aebaSBarry Smith . dm - The `DM` object 1916858538eSMatthew G. Knepley 1926858538eSMatthew G. Knepley Output Parameter: 1936858538eSMatthew G. Knepley . dim - The embedding dimension 1946858538eSMatthew G. Knepley 1956858538eSMatthew G. Knepley Level: intermediate 1966858538eSMatthew G. Knepley 197dce8aebaSBarry Smith .seealso: `DM`, `DMSetCoordinateDim()`, `DMGetCoordinateSection()`, `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 1986858538eSMatthew G. Knepley @*/ 199d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 200d71ae5a4SJacob Faibussowitsch { 2016858538eSMatthew G. Knepley PetscFunctionBegin; 2026858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2034f572ea9SToby Isaac PetscAssertPointer(dim, 2); 2046858538eSMatthew G. Knepley if (dm->coordinates[0].dim == PETSC_DEFAULT) dm->coordinates[0].dim = dm->dim; 2056858538eSMatthew G. Knepley *dim = dm->coordinates[0].dim; 2063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2076858538eSMatthew G. Knepley } 2086858538eSMatthew G. Knepley 2096858538eSMatthew G. Knepley /*@ 2106858538eSMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 2116858538eSMatthew G. Knepley 2126858538eSMatthew G. Knepley Not Collective 2136858538eSMatthew G. Knepley 2146858538eSMatthew G. Knepley Input Parameters: 215dce8aebaSBarry Smith + dm - The `DM` object 2166858538eSMatthew G. Knepley - dim - The embedding dimension 2176858538eSMatthew G. Knepley 2186858538eSMatthew G. Knepley Level: intermediate 2196858538eSMatthew G. Knepley 220dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinateDim()`, `DMSetCoordinateSection()`, `DMGetCoordinateSection()`, `DMGetLocalSection()`, `DMSetLocalSection()` 2216858538eSMatthew G. Knepley @*/ 222d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 223d71ae5a4SJacob Faibussowitsch { 2246858538eSMatthew G. Knepley PetscDS ds; 2256858538eSMatthew G. Knepley PetscInt Nds, n; 2266858538eSMatthew G. Knepley 2276858538eSMatthew G. Knepley PetscFunctionBegin; 2286858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2296858538eSMatthew G. Knepley dm->coordinates[0].dim = dim; 2306858538eSMatthew G. Knepley if (dm->dim >= 0) { 2316858538eSMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 2326858538eSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 23307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds, NULL)); 2346858538eSMatthew G. Knepley PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 2356858538eSMatthew G. Knepley } 2366858538eSMatthew G. Knepley } 2373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2386858538eSMatthew G. Knepley } 2396858538eSMatthew G. Knepley 2406858538eSMatthew G. Knepley /*@ 2410b3275a6SBarry Smith DMGetCoordinateSection - Retrieve the `PetscSection` of coordinate values over the mesh. 2426858538eSMatthew G. Knepley 24320f4b53cSBarry Smith Collective 2446858538eSMatthew G. Knepley 2456858538eSMatthew G. Knepley Input Parameter: 246dce8aebaSBarry Smith . dm - The `DM` object 2476858538eSMatthew G. Knepley 2486858538eSMatthew G. Knepley Output Parameter: 249dce8aebaSBarry Smith . section - The `PetscSection` object 2506858538eSMatthew G. Knepley 2516858538eSMatthew G. Knepley Level: intermediate 2526858538eSMatthew G. Knepley 253dce8aebaSBarry Smith Note: 254dce8aebaSBarry Smith This just retrieves the local section from the coordinate `DM`. In other words, 255dce8aebaSBarry Smith .vb 256dce8aebaSBarry Smith DMGetCoordinateDM(dm, &cdm); 257dce8aebaSBarry Smith DMGetLocalSection(cdm, §ion); 258dce8aebaSBarry Smith .ve 259dce8aebaSBarry Smith 2600b3275a6SBarry Smith .seealso: `DM`, `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 2616858538eSMatthew G. Knepley @*/ 262d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 263d71ae5a4SJacob Faibussowitsch { 2646858538eSMatthew G. Knepley DM cdm; 2656858538eSMatthew G. Knepley 2666858538eSMatthew G. Knepley PetscFunctionBegin; 2676858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2684f572ea9SToby Isaac PetscAssertPointer(section, 2); 2696858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 2706858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(cdm, section)); 2713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2726858538eSMatthew G. Knepley } 2736858538eSMatthew G. Knepley 2746858538eSMatthew G. Knepley /*@ 2750b3275a6SBarry Smith DMSetCoordinateSection - Set the `PetscSection` of coordinate values over the mesh. 2766858538eSMatthew G. Knepley 2776858538eSMatthew G. Knepley Not Collective 2786858538eSMatthew G. Knepley 2796858538eSMatthew G. Knepley Input Parameters: 280dce8aebaSBarry Smith + dm - The `DM` object 281dce8aebaSBarry Smith . dim - The embedding dimension, or `PETSC_DETERMINE` 282dce8aebaSBarry Smith - section - The `PetscSection` object 2836858538eSMatthew G. Knepley 2846858538eSMatthew G. Knepley Level: intermediate 2856858538eSMatthew G. Knepley 286dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinateDim()`, `DMGetCoordinateSection()`, `DMGetLocalSection()`, `DMSetLocalSection()` 2876858538eSMatthew G. Knepley @*/ 288d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 289d71ae5a4SJacob Faibussowitsch { 2906858538eSMatthew G. Knepley DM cdm; 2916858538eSMatthew G. Knepley 2926858538eSMatthew G. Knepley PetscFunctionBegin; 2936858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2946858538eSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 3); 2956858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 2966858538eSMatthew G. Knepley PetscCall(DMSetLocalSection(cdm, section)); 2976858538eSMatthew G. Knepley if (dim == PETSC_DETERMINE) { 2986858538eSMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 2996858538eSMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 3006858538eSMatthew G. Knepley 3016858538eSMatthew G. Knepley PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 3026858538eSMatthew G. Knepley PetscCall(DMGetDimPoints(dm, 0, &vStart, &vEnd)); 3036858538eSMatthew G. Knepley pStart = PetscMax(vStart, pStart); 3046858538eSMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 3056858538eSMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 3066858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(section, v, &dd)); 3079371c9d4SSatish Balay if (dd) { 3089371c9d4SSatish Balay d = dd; 3099371c9d4SSatish Balay break; 3109371c9d4SSatish Balay } 3116858538eSMatthew G. Knepley } 3126858538eSMatthew G. Knepley if (d >= 0) PetscCall(DMSetCoordinateDim(dm, d)); 3136858538eSMatthew G. Knepley } 3143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3156858538eSMatthew G. Knepley } 3166858538eSMatthew G. Knepley 3176858538eSMatthew G. Knepley /*@ 3180b3275a6SBarry Smith DMGetCellCoordinateSection - Retrieve the `PetscSection` of cellwise coordinate values over the mesh. 3196858538eSMatthew G. Knepley 32020f4b53cSBarry Smith Collective 3216858538eSMatthew G. Knepley 3226858538eSMatthew G. Knepley Input Parameter: 323dce8aebaSBarry Smith . dm - The `DM` object 3246858538eSMatthew G. Knepley 3256858538eSMatthew G. Knepley Output Parameter: 32620f4b53cSBarry Smith . section - The `PetscSection` object, or `NULL` if no cellwise coordinates are defined 3276858538eSMatthew G. Knepley 3286858538eSMatthew G. Knepley Level: intermediate 3296858538eSMatthew G. Knepley 330dce8aebaSBarry Smith Note: 331dce8aebaSBarry Smith This just retrieves the local section from the cell coordinate `DM`. In other words, 332dce8aebaSBarry Smith .vb 333dce8aebaSBarry Smith DMGetCellCoordinateDM(dm, &cdm); 334dce8aebaSBarry Smith DMGetLocalSection(cdm, §ion); 335dce8aebaSBarry Smith .ve 336dce8aebaSBarry Smith 337dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinateSection()`, `DMSetCellCoordinateSection()`, `DMGetCellCoordinateDM()`, `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 3386858538eSMatthew G. Knepley @*/ 339d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinateSection(DM dm, PetscSection *section) 340d71ae5a4SJacob Faibussowitsch { 3416858538eSMatthew G. Knepley DM cdm; 3426858538eSMatthew G. Knepley 3436858538eSMatthew G. Knepley PetscFunctionBegin; 3446858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3454f572ea9SToby Isaac PetscAssertPointer(section, 2); 3466858538eSMatthew G. Knepley *section = NULL; 3476858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 3486858538eSMatthew G. Knepley if (cdm) PetscCall(DMGetLocalSection(cdm, section)); 3493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3506858538eSMatthew G. Knepley } 3516858538eSMatthew G. Knepley 3526858538eSMatthew G. Knepley /*@ 3530b3275a6SBarry Smith DMSetCellCoordinateSection - Set the `PetscSection` of cellwise coordinate values over the mesh. 3546858538eSMatthew G. Knepley 3556858538eSMatthew G. Knepley Not Collective 3566858538eSMatthew G. Knepley 3576858538eSMatthew G. Knepley Input Parameters: 358dce8aebaSBarry Smith + dm - The `DM` object 359dce8aebaSBarry Smith . dim - The embedding dimension, or `PETSC_DETERMINE` 360dce8aebaSBarry Smith - section - The `PetscSection` object for a cellwise layout 3616858538eSMatthew G. Knepley 3626858538eSMatthew G. Knepley Level: intermediate 3636858538eSMatthew G. Knepley 364dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinateDim()`, `DMSetCoordinateSection()`, `DMGetCellCoordinateSection()`, `DMGetCoordinateSection()`, `DMGetCellCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 3656858538eSMatthew G. Knepley @*/ 366d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinateSection(DM dm, PetscInt dim, PetscSection section) 367d71ae5a4SJacob Faibussowitsch { 3686858538eSMatthew G. Knepley DM cdm; 3696858538eSMatthew G. Knepley 3706858538eSMatthew G. Knepley PetscFunctionBegin; 3716858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3726858538eSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 3); 3736858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 3746858538eSMatthew G. Knepley PetscCheck(cdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "No DM defined for cellwise coordinates"); 3756858538eSMatthew G. Knepley PetscCall(DMSetLocalSection(cdm, section)); 3766858538eSMatthew G. Knepley if (dim == PETSC_DETERMINE) { 3776858538eSMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 3786858538eSMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 3796858538eSMatthew G. Knepley 3806858538eSMatthew G. Knepley PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 3816858538eSMatthew G. Knepley PetscCall(DMGetDimPoints(dm, 0, &vStart, &vEnd)); 3826858538eSMatthew G. Knepley pStart = PetscMax(vStart, pStart); 3836858538eSMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 3846858538eSMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 3856858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(section, v, &dd)); 3869371c9d4SSatish Balay if (dd) { 3879371c9d4SSatish Balay d = dd; 3889371c9d4SSatish Balay break; 3899371c9d4SSatish Balay } 3906858538eSMatthew G. Knepley } 3916858538eSMatthew G. Knepley if (d >= 0) PetscCall(DMSetCoordinateDim(dm, d)); 3926858538eSMatthew G. Knepley } 3933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3946858538eSMatthew G. Knepley } 3956858538eSMatthew G. Knepley 3966858538eSMatthew G. Knepley /*@ 397dce8aebaSBarry Smith DMGetCoordinates - Gets a global vector with the coordinates associated with the `DM`. 3986858538eSMatthew G. Knepley 39920f4b53cSBarry Smith Collective 4006858538eSMatthew G. Knepley 4016858538eSMatthew G. Knepley Input Parameter: 402dce8aebaSBarry Smith . dm - the `DM` 4036858538eSMatthew G. Knepley 4046858538eSMatthew G. Knepley Output Parameter: 4056858538eSMatthew G. Knepley . c - global coordinate vector 4066858538eSMatthew G. Knepley 407dce8aebaSBarry Smith Level: intermediate 408dce8aebaSBarry Smith 409dce8aebaSBarry Smith Notes: 410dce8aebaSBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the `DM` is 4110b3275a6SBarry Smith destroyed `c` will no longer be valid. 4126858538eSMatthew G. Knepley 4136858538eSMatthew G. Knepley Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 4146858538eSMatthew G. Knepley 415dce8aebaSBarry Smith For `DMDA`, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 4166858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 4176858538eSMatthew G. Knepley 418dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMSetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetCoordinateDM()`, `DMDASetUniformCoordinates()` 4196858538eSMatthew G. Knepley @*/ 420d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 421d71ae5a4SJacob Faibussowitsch { 4226858538eSMatthew G. Knepley PetscFunctionBegin; 4236858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4244f572ea9SToby Isaac PetscAssertPointer(c, 2); 4256858538eSMatthew G. Knepley if (!dm->coordinates[0].x && dm->coordinates[0].xl) { 4266858538eSMatthew G. Knepley DM cdm = NULL; 4276858538eSMatthew G. Knepley 4286858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 4296858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdm, &dm->coordinates[0].x)); 4306858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[0].x, "coordinates")); 4316858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(cdm, dm->coordinates[0].xl, INSERT_VALUES, dm->coordinates[0].x)); 4326858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(cdm, dm->coordinates[0].xl, INSERT_VALUES, dm->coordinates[0].x)); 4336858538eSMatthew G. Knepley } 4346858538eSMatthew G. Knepley *c = dm->coordinates[0].x; 4353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4366858538eSMatthew G. Knepley } 4376858538eSMatthew G. Knepley 4386858538eSMatthew G. Knepley /*@ 439dce8aebaSBarry Smith DMSetCoordinates - Sets into the `DM` a global vector that holds the coordinates 4406858538eSMatthew G. Knepley 44120f4b53cSBarry Smith Collective 4426858538eSMatthew G. Knepley 4436858538eSMatthew G. Knepley Input Parameters: 444dce8aebaSBarry Smith + dm - the `DM` 4456858538eSMatthew G. Knepley - c - coordinate vector 4466858538eSMatthew G. Knepley 4476858538eSMatthew G. Knepley Level: intermediate 4486858538eSMatthew G. Knepley 449dce8aebaSBarry Smith Notes: 450dce8aebaSBarry Smith The coordinates do not include those for ghost points, which are in the local vector. 451dce8aebaSBarry Smith 45220f4b53cSBarry Smith The vector `c` can be destroyed after the call 453dce8aebaSBarry Smith 454dce8aebaSBarry Smith .seealso: `DM`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetCoordinateDM()`, `DMDASetUniformCoordinates()` 4556858538eSMatthew G. Knepley @*/ 456d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinates(DM dm, Vec c) 457d71ae5a4SJacob Faibussowitsch { 4586858538eSMatthew G. Knepley PetscFunctionBegin; 4596858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4606858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 4616858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 4626858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].x)); 4636858538eSMatthew G. Knepley dm->coordinates[0].x = c; 4646858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].xl)); 4656858538eSMatthew G. Knepley PetscCall(DMCoarsenHookAdd(dm, DMRestrictHook_Coordinates, NULL, NULL)); 4666858538eSMatthew G. Knepley PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_Coordinates, NULL, NULL)); 4673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4686858538eSMatthew G. Knepley } 4696858538eSMatthew G. Knepley 4706858538eSMatthew G. Knepley /*@ 471dce8aebaSBarry Smith DMGetCellCoordinates - Gets a global vector with the cellwise coordinates associated with the `DM`. 4726858538eSMatthew G. Knepley 47320f4b53cSBarry Smith Collective 4746858538eSMatthew G. Knepley 4756858538eSMatthew G. Knepley Input Parameter: 476dce8aebaSBarry Smith . dm - the `DM` 4776858538eSMatthew G. Knepley 4786858538eSMatthew G. Knepley Output Parameter: 4796858538eSMatthew G. Knepley . c - global coordinate vector 4806858538eSMatthew G. Knepley 481dce8aebaSBarry Smith Level: intermediate 482dce8aebaSBarry Smith 483dce8aebaSBarry Smith Notes: 484dce8aebaSBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the `DM` is 4850b3275a6SBarry Smith destroyed `c` will no longer be valid. 4866858538eSMatthew G. Knepley 4876858538eSMatthew G. Knepley Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 4886858538eSMatthew G. Knepley 489dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMGetCellCoordinateDM()` 4906858538eSMatthew G. Knepley @*/ 491d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinates(DM dm, Vec *c) 492d71ae5a4SJacob Faibussowitsch { 4936858538eSMatthew G. Knepley PetscFunctionBegin; 4946858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4954f572ea9SToby Isaac PetscAssertPointer(c, 2); 4966858538eSMatthew G. Knepley if (!dm->coordinates[1].x && dm->coordinates[1].xl) { 4976858538eSMatthew G. Knepley DM cdm = NULL; 4986858538eSMatthew G. Knepley 49911ea91a7SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 5006858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdm, &dm->coordinates[1].x)); 5016858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[1].x, "DG coordinates")); 5026858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(cdm, dm->coordinates[1].xl, INSERT_VALUES, dm->coordinates[1].x)); 5036858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(cdm, dm->coordinates[1].xl, INSERT_VALUES, dm->coordinates[1].x)); 5046858538eSMatthew G. Knepley } 5056858538eSMatthew G. Knepley *c = dm->coordinates[1].x; 5063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5076858538eSMatthew G. Knepley } 5086858538eSMatthew G. Knepley 5096858538eSMatthew G. Knepley /*@ 510dce8aebaSBarry Smith DMSetCellCoordinates - Sets into the `DM` a global vector that holds the cellwise coordinates 5116858538eSMatthew G. Knepley 51220f4b53cSBarry Smith Collective 5136858538eSMatthew G. Knepley 5146858538eSMatthew G. Knepley Input Parameters: 515dce8aebaSBarry Smith + dm - the `DM` 5166858538eSMatthew G. Knepley - c - cellwise coordinate vector 5176858538eSMatthew G. Knepley 5186858538eSMatthew G. Knepley Level: intermediate 5196858538eSMatthew G. Knepley 520dce8aebaSBarry Smith Notes: 521dce8aebaSBarry Smith The coordinates do not include those for ghost points, which are in the local vector. 522dce8aebaSBarry Smith 52320f4b53cSBarry Smith The vector `c` should be destroyed by the caller. 524dce8aebaSBarry Smith 525dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinates()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMGetCellCoordinateDM()` 5266858538eSMatthew G. Knepley @*/ 527d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinates(DM dm, Vec c) 528d71ae5a4SJacob Faibussowitsch { 5296858538eSMatthew G. Knepley PetscFunctionBegin; 5306858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5316858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 5326858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 5336858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].x)); 5346858538eSMatthew G. Knepley dm->coordinates[1].x = c; 5356858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].xl)); 5363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5376858538eSMatthew G. Knepley } 5386858538eSMatthew G. Knepley 5396858538eSMatthew G. Knepley /*@ 540dce8aebaSBarry Smith DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that `DMGetCoordinatesLocalNoncollective()` can be used as non-collective afterwards. 5416858538eSMatthew G. Knepley 54220f4b53cSBarry Smith Collective 5436858538eSMatthew G. Knepley 5446858538eSMatthew G. Knepley Input Parameter: 545dce8aebaSBarry Smith . dm - the `DM` 5466858538eSMatthew G. Knepley 5476858538eSMatthew G. Knepley Level: advanced 5486858538eSMatthew G. Knepley 549dce8aebaSBarry Smith .seealso: `DM`, `DMSetCoordinates()`, `DMGetCoordinatesLocalNoncollective()` 5506858538eSMatthew G. Knepley @*/ 551d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 552d71ae5a4SJacob Faibussowitsch { 5536858538eSMatthew G. Knepley PetscFunctionBegin; 5546858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5556858538eSMatthew G. Knepley if (!dm->coordinates[0].xl && dm->coordinates[0].x) { 5566858538eSMatthew G. Knepley DM cdm = NULL; 5579d92f5ffSMatthew G. Knepley PetscInt bs; 5586858538eSMatthew G. Knepley 5596858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 5606858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(cdm, &dm->coordinates[0].xl)); 56121c42226SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[0].xl, "Local Coordinates")); 5629d92f5ffSMatthew G. Knepley // If the size of the vector is 0, it will not get the right block size 5639d92f5ffSMatthew G. Knepley PetscCall(VecGetBlockSize(dm->coordinates[0].x, &bs)); 5649d92f5ffSMatthew G. Knepley PetscCall(VecSetBlockSize(dm->coordinates[0].xl, bs)); 5656858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[0].xl, "coordinates")); 5666858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(cdm, dm->coordinates[0].x, INSERT_VALUES, dm->coordinates[0].xl)); 5676858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(cdm, dm->coordinates[0].x, INSERT_VALUES, dm->coordinates[0].xl)); 5686858538eSMatthew G. Knepley } 5693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5706858538eSMatthew G. Knepley } 5716858538eSMatthew G. Knepley 5726858538eSMatthew G. Knepley /*@ 573dce8aebaSBarry Smith DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the `DM`. 5746858538eSMatthew G. Knepley 57520f4b53cSBarry Smith Collective the first time it is called 5766858538eSMatthew G. Knepley 5776858538eSMatthew G. Knepley Input Parameter: 578dce8aebaSBarry Smith . dm - the `DM` 5796858538eSMatthew G. Knepley 5806858538eSMatthew G. Knepley Output Parameter: 5816858538eSMatthew G. Knepley . c - coordinate vector 5826858538eSMatthew G. Knepley 583dce8aebaSBarry Smith Level: intermediate 584dce8aebaSBarry Smith 585dce8aebaSBarry Smith Notes: 5860b3275a6SBarry Smith This is a borrowed reference, so the user should NOT destroy `c` 5876858538eSMatthew G. Knepley 5886858538eSMatthew G. Knepley Each process has the local and ghost coordinates 5896858538eSMatthew G. Knepley 590dce8aebaSBarry Smith For `DMDA`, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 5916858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 5926858538eSMatthew G. Knepley 593dce8aebaSBarry Smith .seealso: `DM`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()`, `DMGetCoordinatesLocalNoncollective()` 5946858538eSMatthew G. Knepley @*/ 595d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 596d71ae5a4SJacob Faibussowitsch { 5976858538eSMatthew G. Knepley PetscFunctionBegin; 5986858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5994f572ea9SToby Isaac PetscAssertPointer(c, 2); 6006858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(dm)); 6016858538eSMatthew G. Knepley *c = dm->coordinates[0].xl; 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6036858538eSMatthew G. Knepley } 6046858538eSMatthew G. Knepley 6056858538eSMatthew G. Knepley /*@ 606dce8aebaSBarry Smith DMGetCoordinatesLocalNoncollective - Non-collective version of `DMGetCoordinatesLocal()`. Fails if global coordinates have been set and `DMGetCoordinatesLocalSetUp()` not called. 6076858538eSMatthew G. Knepley 60820f4b53cSBarry Smith Not Collective 6096858538eSMatthew G. Knepley 6106858538eSMatthew G. Knepley Input Parameter: 611dce8aebaSBarry Smith . dm - the `DM` 6126858538eSMatthew G. Knepley 6136858538eSMatthew G. Knepley Output Parameter: 6146858538eSMatthew G. Knepley . c - coordinate vector 6156858538eSMatthew G. Knepley 6166858538eSMatthew G. Knepley Level: advanced 6176858538eSMatthew G. Knepley 618dce8aebaSBarry Smith Note: 619dce8aebaSBarry Smith A previous call to `DMGetCoordinatesLocal()` or `DMGetCoordinatesLocalSetUp()` ensures that a call to this function will not error. 620dce8aebaSBarry Smith 621dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinatesLocalSetUp()`, `DMGetCoordinatesLocal()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()` 6226858538eSMatthew G. Knepley @*/ 623d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 624d71ae5a4SJacob Faibussowitsch { 6256858538eSMatthew G. Knepley PetscFunctionBegin; 6266858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6274f572ea9SToby Isaac PetscAssertPointer(c, 2); 6286858538eSMatthew G. Knepley PetscCheck(dm->coordinates[0].xl || !dm->coordinates[0].x, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 6296858538eSMatthew G. Knepley *c = dm->coordinates[0].xl; 6303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6316858538eSMatthew G. Knepley } 6326858538eSMatthew G. Knepley 6336858538eSMatthew G. Knepley /*@ 634dce8aebaSBarry Smith DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and the section describing its layout. 6356858538eSMatthew G. Knepley 63620f4b53cSBarry Smith Not Collective 6376858538eSMatthew G. Knepley 6386858538eSMatthew G. Knepley Input Parameters: 639dce8aebaSBarry Smith + dm - the `DM` 640dce8aebaSBarry Smith - p - the `IS` of points whose coordinates will be returned 6416858538eSMatthew G. Knepley 6426858538eSMatthew G. Knepley Output Parameters: 6430b3275a6SBarry Smith + pCoordSection - the `PetscSection` describing the layout of pCoord, i.e. each point corresponds to one point in `p`, and DOFs correspond to coordinates 6440b3275a6SBarry Smith - pCoord - the `Vec` with coordinates of points in `p` 6456858538eSMatthew G. Knepley 646dce8aebaSBarry Smith Level: advanced 647dce8aebaSBarry Smith 648dce8aebaSBarry Smith Notes: 649dce8aebaSBarry Smith `DMGetCoordinatesLocalSetUp()` must be called first. This function employs `DMGetCoordinatesLocalNoncollective()` so it is not collective. 6506858538eSMatthew G. Knepley 6516858538eSMatthew G. Knepley This creates a new vector, so the user SHOULD destroy this vector 6526858538eSMatthew G. Knepley 6536858538eSMatthew G. Knepley Each process has the local and ghost coordinates 6546858538eSMatthew G. Knepley 655dce8aebaSBarry Smith For `DMDA`, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 6566858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 6576858538eSMatthew G. Knepley 658dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMSetCoordinatesLocal()`, `DMGetCoordinatesLocal()`, `DMGetCoordinatesLocalNoncollective()`, `DMGetCoordinatesLocalSetUp()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()` 6596858538eSMatthew G. Knepley @*/ 660d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 661d71ae5a4SJacob Faibussowitsch { 6626858538eSMatthew G. Knepley DM cdm; 6636858538eSMatthew G. Knepley PetscSection cs, newcs; 6646858538eSMatthew G. Knepley Vec coords; 6656858538eSMatthew G. Knepley const PetscScalar *arr; 6666858538eSMatthew G. Knepley PetscScalar *newarr = NULL; 6676858538eSMatthew G. Knepley PetscInt n; 6686858538eSMatthew G. Knepley 6696858538eSMatthew G. Knepley PetscFunctionBegin; 6706858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6716858538eSMatthew G. Knepley PetscValidHeaderSpecific(p, IS_CLASSID, 2); 6724f572ea9SToby Isaac if (pCoordSection) PetscAssertPointer(pCoordSection, 3); 6734f572ea9SToby Isaac if (pCoord) PetscAssertPointer(pCoord, 4); 6746858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 6756858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(cdm, &cs)); 6766858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coords)); 6776858538eSMatthew G. Knepley PetscCheck(coords, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 6786858538eSMatthew G. Knepley PetscCheck(cdm && cs, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 6796858538eSMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &arr)); 6806858538eSMatthew G. Knepley PetscCall(PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void **)&newarr) : NULL)); 6816858538eSMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &arr)); 6826858538eSMatthew G. Knepley if (pCoord) { 6836858538eSMatthew G. Knepley PetscCall(PetscSectionGetStorageSize(newcs, &n)); 6846858538eSMatthew G. Knepley /* set array in two steps to mimic PETSC_OWN_POINTER */ 6856858538eSMatthew G. Knepley PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord)); 6866858538eSMatthew G. Knepley PetscCall(VecReplaceArray(*pCoord, newarr)); 6876858538eSMatthew G. Knepley } else { 6886858538eSMatthew G. Knepley PetscCall(PetscFree(newarr)); 6896858538eSMatthew G. Knepley } 6909371c9d4SSatish Balay if (pCoordSection) { 6919371c9d4SSatish Balay *pCoordSection = newcs; 6929371c9d4SSatish Balay } else PetscCall(PetscSectionDestroy(&newcs)); 6933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6946858538eSMatthew G. Knepley } 6956858538eSMatthew G. Knepley 6966858538eSMatthew G. Knepley /*@ 697dce8aebaSBarry Smith DMSetCoordinatesLocal - Sets into the `DM` a local vector, including ghost points, that holds the coordinates 6986858538eSMatthew G. Knepley 69920f4b53cSBarry Smith Not Collective 7006858538eSMatthew G. Knepley 7016858538eSMatthew G. Knepley Input Parameters: 702dce8aebaSBarry Smith + dm - the `DM` 7036858538eSMatthew G. Knepley - c - coordinate vector 7046858538eSMatthew G. Knepley 705dce8aebaSBarry Smith Level: intermediate 706dce8aebaSBarry Smith 7076858538eSMatthew G. Knepley Notes: 708dce8aebaSBarry Smith The coordinates of ghost points can be set using `DMSetCoordinates()` 709dce8aebaSBarry Smith followed by `DMGetCoordinatesLocal()`. This is intended to enable the 7106858538eSMatthew G. Knepley setting of ghost coordinates outside of the domain. 7116858538eSMatthew G. Knepley 7120b3275a6SBarry Smith The vector `c` should be destroyed by the caller. 7136858538eSMatthew G. Knepley 714dce8aebaSBarry Smith .seealso: `DM`, `DMGetCoordinatesLocal()`, `DMSetCoordinates()`, `DMGetCoordinates()`, `DMGetCoordinateDM()` 7156858538eSMatthew G. Knepley @*/ 716d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 717d71ae5a4SJacob Faibussowitsch { 7186858538eSMatthew G. Knepley PetscFunctionBegin; 7196858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7206858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 7216858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 7226858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].xl)); 7236858538eSMatthew G. Knepley dm->coordinates[0].xl = c; 7246858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].x)); 7253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7266858538eSMatthew G. Knepley } 7276858538eSMatthew G. Knepley 7286858538eSMatthew G. Knepley /*@ 729dce8aebaSBarry Smith DMGetCellCoordinatesLocalSetUp - Prepares a local vector of cellwise coordinates, so that `DMGetCellCoordinatesLocalNoncollective()` can be used as non-collective afterwards. 7306858538eSMatthew G. Knepley 73120f4b53cSBarry Smith Collective 7326858538eSMatthew G. Knepley 7336858538eSMatthew G. Knepley Input Parameter: 734dce8aebaSBarry Smith . dm - the `DM` 7356858538eSMatthew G. Knepley 7366858538eSMatthew G. Knepley Level: advanced 7376858538eSMatthew G. Knepley 738dce8aebaSBarry Smith .seealso: `DM`, `DMGetCellCoordinatesLocalNoncollective()` 7396858538eSMatthew G. Knepley @*/ 740d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinatesLocalSetUp(DM dm) 741d71ae5a4SJacob Faibussowitsch { 7426858538eSMatthew G. Knepley PetscFunctionBegin; 7436858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7446858538eSMatthew G. Knepley if (!dm->coordinates[1].xl && dm->coordinates[1].x) { 7456858538eSMatthew G. Knepley DM cdm = NULL; 7466858538eSMatthew G. Knepley 74711ea91a7SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 7486858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(cdm, &dm->coordinates[1].xl)); 7496858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dm->coordinates[1].xl, "DG coordinates")); 7506858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(cdm, dm->coordinates[1].x, INSERT_VALUES, dm->coordinates[1].xl)); 7516858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(cdm, dm->coordinates[1].x, INSERT_VALUES, dm->coordinates[1].xl)); 7526858538eSMatthew G. Knepley } 7533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7546858538eSMatthew G. Knepley } 7556858538eSMatthew G. Knepley 7566858538eSMatthew G. Knepley /*@ 757dce8aebaSBarry Smith DMGetCellCoordinatesLocal - Gets a local vector with the cellwise coordinates associated with the `DM`. 7586858538eSMatthew G. Knepley 75920f4b53cSBarry Smith Collective 7606858538eSMatthew G. Knepley 7616858538eSMatthew G. Knepley Input Parameter: 762dce8aebaSBarry Smith . dm - the `DM` 7636858538eSMatthew G. Knepley 7646858538eSMatthew G. Knepley Output Parameter: 7656858538eSMatthew G. Knepley . c - coordinate vector 7666858538eSMatthew G. Knepley 767dce8aebaSBarry Smith Level: intermediate 768dce8aebaSBarry Smith 769dce8aebaSBarry Smith Notes: 7706858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector 7716858538eSMatthew G. Knepley 7726858538eSMatthew G. Knepley Each process has the local and ghost coordinates 7736858538eSMatthew G. Knepley 774dce8aebaSBarry Smith .seealso: `DM`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinateDM()`, `DMGetCellCoordinatesLocalNoncollective()` 7756858538eSMatthew G. Knepley @*/ 776d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinatesLocal(DM dm, Vec *c) 777d71ae5a4SJacob Faibussowitsch { 7786858538eSMatthew G. Knepley PetscFunctionBegin; 7796858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7804f572ea9SToby Isaac PetscAssertPointer(c, 2); 7816858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocalSetUp(dm)); 7826858538eSMatthew G. Knepley *c = dm->coordinates[1].xl; 7833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7846858538eSMatthew G. Knepley } 7856858538eSMatthew G. Knepley 7866858538eSMatthew G. Knepley /*@ 787dce8aebaSBarry Smith DMGetCellCoordinatesLocalNoncollective - Non-collective version of `DMGetCellCoordinatesLocal()`. Fails if global cellwise coordinates have been set and `DMGetCellCoordinatesLocalSetUp()` not called. 7886858538eSMatthew G. Knepley 78920f4b53cSBarry Smith Not Collective 7906858538eSMatthew G. Knepley 7916858538eSMatthew G. Knepley Input Parameter: 792dce8aebaSBarry Smith . dm - the `DM` 7936858538eSMatthew G. Knepley 7946858538eSMatthew G. Knepley Output Parameter: 7956858538eSMatthew G. Knepley . c - cellwise coordinate vector 7966858538eSMatthew G. Knepley 7976858538eSMatthew G. Knepley Level: advanced 7986858538eSMatthew G. Knepley 799dce8aebaSBarry Smith .seealso: `DM`, `DMGetCellCoordinatesLocalSetUp()`, `DMGetCellCoordinatesLocal()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinateDM()` 8006858538eSMatthew G. Knepley @*/ 801d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellCoordinatesLocalNoncollective(DM dm, Vec *c) 802d71ae5a4SJacob Faibussowitsch { 8036858538eSMatthew G. Knepley PetscFunctionBegin; 8046858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8054f572ea9SToby Isaac PetscAssertPointer(c, 2); 8066858538eSMatthew G. Knepley PetscCheck(dm->coordinates[1].xl || !dm->coordinates[1].x, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCellCoordinatesLocalSetUp() has not been called"); 8076858538eSMatthew G. Knepley *c = dm->coordinates[1].xl; 8083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8096858538eSMatthew G. Knepley } 8106858538eSMatthew G. Knepley 8116858538eSMatthew G. Knepley /*@ 812dce8aebaSBarry Smith DMSetCellCoordinatesLocal - Sets into the `DM` a local vector including ghost points that holds the cellwise coordinates 8136858538eSMatthew G. Knepley 81420f4b53cSBarry Smith Not Collective 8156858538eSMatthew G. Knepley 8166858538eSMatthew G. Knepley Input Parameters: 817dce8aebaSBarry Smith + dm - the `DM` 8186858538eSMatthew G. Knepley - c - cellwise coordinate vector 8196858538eSMatthew G. Knepley 820dce8aebaSBarry Smith Level: intermediate 821dce8aebaSBarry Smith 8226858538eSMatthew G. Knepley Notes: 823dce8aebaSBarry Smith The coordinates of ghost points can be set using `DMSetCoordinates()` 824dce8aebaSBarry Smith followed by `DMGetCoordinatesLocal()`. This is intended to enable the 8256858538eSMatthew G. Knepley setting of ghost coordinates outside of the domain. 8266858538eSMatthew G. Knepley 8270b3275a6SBarry Smith The vector `c` should be destroyed by the caller. 8286858538eSMatthew G. Knepley 829dce8aebaSBarry Smith .seealso: `DM`, `DMGetCellCoordinatesLocal()`, `DMSetCellCoordinates()`, `DMGetCellCoordinates()`, `DMGetCellCoordinateDM()` 8306858538eSMatthew G. Knepley @*/ 831d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCellCoordinatesLocal(DM dm, Vec c) 832d71ae5a4SJacob Faibussowitsch { 8336858538eSMatthew G. Knepley PetscFunctionBegin; 8346858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8356858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c, VEC_CLASSID, 2); 8366858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)c)); 8376858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].xl)); 8386858538eSMatthew G. Knepley dm->coordinates[1].xl = c; 8396858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].x)); 8403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8416858538eSMatthew G. Knepley } 8426858538eSMatthew G. Knepley 843d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 844d71ae5a4SJacob Faibussowitsch { 8456858538eSMatthew G. Knepley PetscFunctionBegin; 8466858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8474f572ea9SToby Isaac PetscAssertPointer(field, 2); 848213acdd3SPierre Jolivet if (!dm->coordinates[0].field) PetscTryTypeMethod(dm, createcoordinatefield, &dm->coordinates[0].field); 8496858538eSMatthew G. Knepley *field = dm->coordinates[0].field; 8503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8516858538eSMatthew G. Knepley } 8526858538eSMatthew G. Knepley 853d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 854d71ae5a4SJacob Faibussowitsch { 8556858538eSMatthew G. Knepley PetscFunctionBegin; 8566858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8576858538eSMatthew G. Knepley if (field) PetscValidHeaderSpecific(field, DMFIELD_CLASSID, 2); 8586858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)field)); 8596858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&dm->coordinates[0].field)); 8606858538eSMatthew G. Knepley dm->coordinates[0].field = field; 8613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8626858538eSMatthew G. Knepley } 8636858538eSMatthew G. Knepley 8646c6a6b79SMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox_Coordinates(DM dm, PetscReal lmin[], PetscReal lmax[], PetscInt cs[], PetscInt ce[]) 865d71ae5a4SJacob Faibussowitsch { 8666858538eSMatthew G. Knepley Vec coords = NULL; 8676858538eSMatthew G. Knepley PetscReal min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 8686858538eSMatthew G. Knepley PetscReal max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 8696858538eSMatthew G. Knepley PetscInt cdim, i, j; 8706c6a6b79SMatthew G. Knepley PetscMPIInt size; 8716858538eSMatthew G. Knepley 8726858538eSMatthew G. Knepley PetscFunctionBegin; 8736c6a6b79SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 8746858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 8756c6a6b79SMatthew G. Knepley if (size == 1) { 8766c6a6b79SMatthew G. Knepley const PetscReal *L, *Lstart; 8776c6a6b79SMatthew G. Knepley 8786c6a6b79SMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, NULL, &Lstart, &L)); 8796c6a6b79SMatthew G. Knepley if (L) { 8806c6a6b79SMatthew G. Knepley for (PetscInt d = 0; d < cdim; ++d) 8816c6a6b79SMatthew G. Knepley if (L[d] > 0.0) { 8826c6a6b79SMatthew G. Knepley min[d] = Lstart[d]; 8836c6a6b79SMatthew G. Knepley max[d] = Lstart[d] + L[d]; 8846c6a6b79SMatthew G. Knepley } 8856c6a6b79SMatthew G. Knepley } 8866c6a6b79SMatthew G. Knepley } 887bdf15c88SMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coords)); 888bdf15c88SMatthew G. Knepley if (coords) { 889bdf15c88SMatthew G. Knepley const PetscScalar *local_coords; 890bdf15c88SMatthew G. Knepley PetscInt N, Ni; 891bdf15c88SMatthew G. Knepley 892bdf15c88SMatthew G. Knepley for (j = cdim; j < 3; ++j) { 893bdf15c88SMatthew G. Knepley min[j] = 0; 894bdf15c88SMatthew G. Knepley max[j] = 0; 895bdf15c88SMatthew G. Knepley } 896bdf15c88SMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &local_coords)); 897bdf15c88SMatthew G. Knepley PetscCall(VecGetLocalSize(coords, &N)); 898bdf15c88SMatthew G. Knepley Ni = N / cdim; 899bdf15c88SMatthew G. Knepley for (i = 0; i < Ni; ++i) { 900bdf15c88SMatthew G. Knepley for (j = 0; j < cdim; ++j) { 901bdf15c88SMatthew G. Knepley min[j] = PetscMin(min[j], PetscRealPart(local_coords[i * cdim + j])); 902bdf15c88SMatthew G. Knepley max[j] = PetscMax(max[j], PetscRealPart(local_coords[i * cdim + j])); 903bdf15c88SMatthew G. Knepley } 904bdf15c88SMatthew G. Knepley } 905bdf15c88SMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &local_coords)); 906bdf15c88SMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 9076858538eSMatthew G. Knepley if (coords) { 9086858538eSMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &local_coords)); 9096858538eSMatthew G. Knepley PetscCall(VecGetLocalSize(coords, &N)); 9106858538eSMatthew G. Knepley Ni = N / cdim; 9116858538eSMatthew G. Knepley for (i = 0; i < Ni; ++i) { 912bdf15c88SMatthew G. Knepley for (j = 0; j < cdim; ++j) { 913bdf15c88SMatthew G. Knepley min[j] = PetscMin(min[j], PetscRealPart(local_coords[i * cdim + j])); 914bdf15c88SMatthew G. Knepley max[j] = PetscMax(max[j], PetscRealPart(local_coords[i * cdim + j])); 9156858538eSMatthew G. Knepley } 9166858538eSMatthew G. Knepley } 9176858538eSMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &local_coords)); 918bdf15c88SMatthew G. Knepley } 9196858538eSMatthew G. Knepley if (lmin) PetscCall(PetscArraycpy(lmin, min, cdim)); 9206858538eSMatthew G. Knepley if (lmax) PetscCall(PetscArraycpy(lmax, max, cdim)); 9216c6a6b79SMatthew G. Knepley } 9226c6a6b79SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9236c6a6b79SMatthew G. Knepley } 9246c6a6b79SMatthew G. Knepley 9256c6a6b79SMatthew G. Knepley /*@ 9266c6a6b79SMatthew G. Knepley DMGetLocalBoundingBox - Returns the bounding box for the piece of the `DM` on this process. 9276c6a6b79SMatthew G. Knepley 9286c6a6b79SMatthew G. Knepley Not Collective 9296c6a6b79SMatthew G. Knepley 9306c6a6b79SMatthew G. Knepley Input Parameter: 9316c6a6b79SMatthew G. Knepley . dm - the `DM` 9326c6a6b79SMatthew G. Knepley 9336c6a6b79SMatthew G. Knepley Output Parameters: 9346c6a6b79SMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional) 9356c6a6b79SMatthew G. Knepley - lmax - local maximum coordinates (length coord dim, optional) 9366c6a6b79SMatthew G. Knepley 9376c6a6b79SMatthew G. Knepley Level: beginner 9386c6a6b79SMatthew G. Knepley 9396c6a6b79SMatthew G. Knepley Note: 9406c6a6b79SMatthew G. Knepley If the `DM` is a `DMDA` and has no coordinates, the index bounds are returned instead. 9416c6a6b79SMatthew G. Knepley 9426c6a6b79SMatthew G. Knepley .seealso: `DM`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetBoundingBox()` 9436c6a6b79SMatthew G. Knepley @*/ 9446c6a6b79SMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[]) 9456c6a6b79SMatthew G. Knepley { 9466c6a6b79SMatthew G. Knepley PetscFunctionBegin; 9476c6a6b79SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9486c6a6b79SMatthew G. Knepley PetscUseTypeMethod(dm, getlocalboundingbox, lmin, lmax, NULL, NULL); 9493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9506858538eSMatthew G. Knepley } 9516858538eSMatthew G. Knepley 9526858538eSMatthew G. Knepley /*@ 953dce8aebaSBarry Smith DMGetBoundingBox - Returns the global bounding box for the `DM`. 9546858538eSMatthew G. Knepley 9556858538eSMatthew G. Knepley Collective 9566858538eSMatthew G. Knepley 9576858538eSMatthew G. Knepley Input Parameter: 958dce8aebaSBarry Smith . dm - the `DM` 9596858538eSMatthew G. Knepley 9606858538eSMatthew G. Knepley Output Parameters: 9616858538eSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional) 96235cb6cd3SPierre Jolivet - gmax - global maximum coordinates (length coord dim, optional) 9636858538eSMatthew G. Knepley 9646858538eSMatthew G. Knepley Level: beginner 9656858538eSMatthew G. Knepley 966dce8aebaSBarry Smith .seealso: `DM`, `DMGetLocalBoundingBox()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()` 9676858538eSMatthew G. Knepley @*/ 968d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[]) 969d71ae5a4SJacob Faibussowitsch { 9706858538eSMatthew G. Knepley PetscReal lmin[3], lmax[3]; 9716c6a6b79SMatthew G. Knepley const PetscReal *L, *Lstart; 9726858538eSMatthew G. Knepley PetscInt cdim; 9736858538eSMatthew G. Knepley 9746858538eSMatthew G. Knepley PetscFunctionBegin; 9756858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9766858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 9776858538eSMatthew G. Knepley PetscCall(DMGetLocalBoundingBox(dm, lmin, lmax)); 978*e91c04dfSPierre Jolivet if (gmin) PetscCallMPI(MPIU_Allreduce(lmin, gmin, cdim, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)dm))); 979*e91c04dfSPierre Jolivet if (gmax) PetscCallMPI(MPIU_Allreduce(lmax, gmax, cdim, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)dm))); 9806c6a6b79SMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, NULL, &Lstart, &L)); 9816c6a6b79SMatthew G. Knepley if (L) { 9826c6a6b79SMatthew G. Knepley for (PetscInt d = 0; d < cdim; ++d) 9836c6a6b79SMatthew G. Knepley if (L[d] > 0.0) { 9846c6a6b79SMatthew G. Knepley gmin[d] = Lstart[d]; 9856c6a6b79SMatthew G. Knepley gmax[d] = Lstart[d] + L[d]; 9866c6a6b79SMatthew G. Knepley } 9876c6a6b79SMatthew G. Knepley } 9883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9896858538eSMatthew G. Knepley } 9906858538eSMatthew G. Knepley 991e44f6aebSMatthew G. Knepley static PetscErrorCode DMCreateAffineCoordinates_Internal(DM dm) 99290612307SJed Brown { 993e44f6aebSMatthew G. Knepley DM cdm; 994e44f6aebSMatthew G. Knepley PetscFE feLinear; 995e44f6aebSMatthew G. Knepley DMPolytopeType ct; 9961df12153SMatthew G. Knepley PetscInt dim, dE, height, cStart, cEnd, gct; 997e44f6aebSMatthew G. Knepley 998e44f6aebSMatthew G. Knepley PetscFunctionBegin; 999e44f6aebSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 1000e44f6aebSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 1001e44f6aebSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &dE)); 10021df12153SMatthew G. Knepley PetscCall(DMPlexGetVTKCellHeight(dm, &height)); 10031df12153SMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, height, &cStart, &cEnd)); 1004e44f6aebSMatthew G. Knepley if (cEnd > cStart) PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 1005e44f6aebSMatthew G. Knepley else ct = DM_POLYTOPE_UNKNOWN; 1006e44f6aebSMatthew G. Knepley gct = (PetscInt)ct; 1007462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &gct, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm))); 1008e44f6aebSMatthew G. Knepley ct = (DMPolytopeType)gct; 1009e44f6aebSMatthew G. Knepley // Work around current bug in PetscDualSpaceSetUp_Lagrange() 1010e44f6aebSMatthew G. Knepley // Can be seen in plex_tutorials-ex10_1 1011e44f6aebSMatthew G. Knepley if (ct != DM_POLYTOPE_SEG_PRISM_TENSOR && ct != DM_POLYTOPE_TRI_PRISM_TENSOR && ct != DM_POLYTOPE_QUAD_PRISM_TENSOR) { 1012e44f6aebSMatthew G. Knepley PetscCall(PetscFECreateLagrangeByCell(PETSC_COMM_SELF, dim, dE, ct, 1, -1, &feLinear)); 1013e44f6aebSMatthew G. Knepley PetscCall(DMSetField(cdm, 0, NULL, (PetscObject)feLinear)); 1014e44f6aebSMatthew G. Knepley PetscCall(PetscFEDestroy(&feLinear)); 1015e44f6aebSMatthew G. Knepley PetscCall(DMCreateDS(cdm)); 1016e44f6aebSMatthew G. Knepley } 1017e44f6aebSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1018e44f6aebSMatthew G. Knepley } 1019e44f6aebSMatthew G. Knepley 1020e44f6aebSMatthew G. Knepley PetscErrorCode DMGetCoordinateDegree_Internal(DM dm, PetscInt *degree) 1021e44f6aebSMatthew G. Knepley { 1022e44f6aebSMatthew G. Knepley DM cdm; 1023e44f6aebSMatthew G. Knepley PetscFE fe; 1024e44f6aebSMatthew G. Knepley PetscSpace sp; 1025e44f6aebSMatthew G. Knepley PetscClassId id; 1026e44f6aebSMatthew G. Knepley 1027e44f6aebSMatthew G. Knepley PetscFunctionBegin; 1028e44f6aebSMatthew G. Knepley *degree = 1; 1029e44f6aebSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 1030e44f6aebSMatthew G. Knepley PetscCall(DMGetField(cdm, 0, NULL, (PetscObject *)&fe)); 1031e44f6aebSMatthew G. Knepley PetscCall(PetscObjectGetClassId((PetscObject)fe, &id)); 1032e44f6aebSMatthew G. Knepley if (id != PETSCFE_CLASSID) PetscFunctionReturn(PETSC_SUCCESS); 1033e44f6aebSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &sp)); 1034e44f6aebSMatthew G. Knepley PetscCall(PetscSpaceGetDegree(sp, degree, NULL)); 1035e44f6aebSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 103690612307SJed Brown } 103790612307SJed Brown 103890df3356SJames Wright static void evaluate_coordinates(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar xnew[]) 103990df3356SJames Wright { 104090df3356SJames Wright for (PetscInt i = 0; i < dim; i++) xnew[i] = x[i]; 104190df3356SJames Wright } 104290df3356SJames Wright 10436858538eSMatthew G. Knepley /*@ 1044e44f6aebSMatthew G. Knepley DMSetCoordinateDisc - Set a coordinate space 10456858538eSMatthew G. Knepley 10466858538eSMatthew G. Knepley Input Parameters: 1047dce8aebaSBarry Smith + dm - The `DM` object 10484688473bSSatish Balay . disc - The new coordinate discretization or `NULL` to ensure a coordinate discretization exists 1049e44f6aebSMatthew G. Knepley - project - Project coordinates to new discretization 10506858538eSMatthew G. Knepley 10516858538eSMatthew G. Knepley Level: intermediate 10526858538eSMatthew G. Knepley 1053dce8aebaSBarry Smith Notes: 1054e44f6aebSMatthew G. Knepley A `PetscFE` defines an approximation space using a `PetscSpace`, which represents the basis functions, and a `PetscDualSpace`, which defines the interpolation operation in the space. 1055dce8aebaSBarry Smith 1056dce8aebaSBarry Smith This function takes the current mesh coordinates, which are discretized using some `PetscFE` space, and projects this function into a new `PetscFE` space. 1057e44f6aebSMatthew G. Knepley The coordinate projection is done on the continuous coordinates, but the discontinuous coordinates are not updated. 1058dce8aebaSBarry Smith 10590b3275a6SBarry Smith Developer Note: 1060dce8aebaSBarry Smith With more effort, we could directly project the discontinuous coordinates also. 1061dce8aebaSBarry Smith 1062dce8aebaSBarry Smith .seealso: `DM`, `PetscFE`, `DMGetCoordinateField()` 10636858538eSMatthew G. Knepley @*/ 1064e44f6aebSMatthew G. Knepley PetscErrorCode DMSetCoordinateDisc(DM dm, PetscFE disc, PetscBool project) 1065d71ae5a4SJacob Faibussowitsch { 1066e44f6aebSMatthew G. Knepley DM cdmOld, cdmNew; 10676858538eSMatthew G. Knepley PetscFE discOld; 10686858538eSMatthew G. Knepley PetscClassId classid; 10696858538eSMatthew G. Knepley PetscBool same_space = PETSC_TRUE; 1070dd4c3f67SMatthew G. Knepley const char *prefix; 10716858538eSMatthew G. Knepley 10726858538eSMatthew G. Knepley PetscFunctionBegin; 10736858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10746858538eSMatthew G. Knepley if (disc) PetscValidHeaderSpecific(disc, PETSCFE_CLASSID, 2); 10756858538eSMatthew G. Knepley 10766858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdmOld)); 10776858538eSMatthew G. Knepley /* Check current discretization is compatible */ 10786858538eSMatthew G. Knepley PetscCall(DMGetField(cdmOld, 0, NULL, (PetscObject *)&discOld)); 10796858538eSMatthew G. Knepley PetscCall(PetscObjectGetClassId((PetscObject)discOld, &classid)); 10806858538eSMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 10816858538eSMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 1082e44f6aebSMatthew G. Knepley PetscCall(DMCreateAffineCoordinates_Internal(dm)); 10836858538eSMatthew G. Knepley PetscCall(DMGetField(cdmOld, 0, NULL, (PetscObject *)&discOld)); 10846858538eSMatthew G. Knepley } else { 10856858538eSMatthew G. Knepley const char *discname; 10866858538eSMatthew G. Knepley 10876858538eSMatthew G. Knepley PetscCall(PetscObjectGetType((PetscObject)discOld, &discname)); 10886858538eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 10896858538eSMatthew G. Knepley } 10906858538eSMatthew G. Knepley } 1091e44f6aebSMatthew G. Knepley // Linear space has been created by now 10923ba16761SJacob Faibussowitsch if (!disc) PetscFunctionReturn(PETSC_SUCCESS); 1093e44f6aebSMatthew G. Knepley // Check if the new space is the same as the old modulo quadrature 1094e44f6aebSMatthew G. Knepley { 10956858538eSMatthew G. Knepley PetscDualSpace dsOld, ds; 10966858538eSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(discOld, &dsOld)); 10976858538eSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(disc, &ds)); 10986858538eSMatthew G. Knepley PetscCall(PetscDualSpaceEqual(dsOld, ds, &same_space)); 10996858538eSMatthew G. Knepley } 1100e44f6aebSMatthew G. Knepley // Make a fresh clone of the coordinate DM 11016858538eSMatthew G. Knepley PetscCall(DMClone(cdmOld, &cdmNew)); 1102dd4c3f67SMatthew G. Knepley cdmNew->cloneOpts = PETSC_TRUE; 1103dd4c3f67SMatthew G. Knepley PetscCall(PetscObjectGetOptionsPrefix((PetscObject)cdmOld, &prefix)); 1104dd4c3f67SMatthew G. Knepley PetscCall(PetscObjectSetOptionsPrefix((PetscObject)cdmNew, prefix)); 11056858538eSMatthew G. Knepley PetscCall(DMSetField(cdmNew, 0, NULL, (PetscObject)disc)); 11066858538eSMatthew G. Knepley PetscCall(DMCreateDS(cdmNew)); 1107e44f6aebSMatthew G. Knepley { 1108e44f6aebSMatthew G. Knepley PetscDS ds, nds; 1109e44f6aebSMatthew G. Knepley 1110e44f6aebSMatthew G. Knepley PetscCall(DMGetDS(cdmOld, &ds)); 1111e44f6aebSMatthew G. Knepley PetscCall(DMGetDS(cdmNew, &nds)); 1112e44f6aebSMatthew G. Knepley PetscCall(PetscDSCopyConstants(ds, nds)); 1113e44f6aebSMatthew G. Knepley } 111481316d9bSJames Wright if (cdmOld->periodic.setup) { 111581316d9bSJames Wright PetscSF dummy; 111681316d9bSJames Wright // Force IsoperiodicPointSF to be built, required for periodic coordinate setup 111781316d9bSJames Wright PetscCall(DMGetIsoperiodicPointSF_Internal(dm, &dummy)); 111881316d9bSJames Wright cdmNew->periodic.setup = cdmOld->periodic.setup; 111981316d9bSJames Wright PetscCall(cdmNew->periodic.setup(cdmNew)); 112081316d9bSJames Wright } 1121dd4c3f67SMatthew G. Knepley if (dm->setfromoptionscalled) PetscCall(DMSetFromOptions(cdmNew)); 1122e44f6aebSMatthew G. Knepley if (project) { 112353b735f8SJames Wright Vec coordsOld, coordsNew; 112481316d9bSJames Wright PetscInt num_face_sfs = 0; 112553b735f8SJames Wright 112681316d9bSJames Wright PetscCall(DMPlexGetIsoperiodicFaceSF(dm, &num_face_sfs, NULL)); 112781316d9bSJames Wright if (num_face_sfs) { // Isoperiodicity requires projecting the local coordinates 112853b735f8SJames Wright PetscCall(DMGetCoordinatesLocal(dm, &coordsOld)); 112953b735f8SJames Wright PetscCall(DMCreateLocalVector(cdmNew, &coordsNew)); 113053b735f8SJames Wright PetscCall(PetscObjectSetName((PetscObject)coordsNew, "coordinates")); 1131f0ac6e35SMatthew G. Knepley if (same_space) { 1132f0ac6e35SMatthew G. Knepley // Need to copy so that the new vector has the right dm 1133f0ac6e35SMatthew G. Knepley PetscCall(VecCopy(coordsOld, coordsNew)); 1134e44f6aebSMatthew G. Knepley } else { 113590df3356SJames Wright void (*funcs[])(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]) = {evaluate_coordinates}; 113690df3356SJames Wright 113790df3356SJames Wright // We can't call DMProjectField directly because it depends on KSP for DMGlobalToLocalSolve(), but we can use the core strategy 113890df3356SJames Wright PetscCall(DMSetCoordinateDM(cdmNew, cdmOld)); 113990df3356SJames Wright // See DMPlexRemapGeometry() for a similar pattern handling the coordinate field 114090df3356SJames Wright DMField cf; 114190df3356SJames Wright PetscCall(DMGetCoordinateField(dm, &cf)); 114290df3356SJames Wright cdmNew->coordinates[0].field = cf; 114353b735f8SJames Wright PetscCall(DMProjectFieldLocal(cdmNew, 0.0, NULL, funcs, INSERT_VALUES, coordsNew)); 114490df3356SJames Wright cdmNew->coordinates[0].field = NULL; 114590df3356SJames Wright PetscCall(DMSetCoordinateDM(cdmNew, NULL)); 114653b735f8SJames Wright } 114753b735f8SJames Wright PetscCall(DMSetCoordinatesLocal(dm, coordsNew)); 114853b735f8SJames Wright PetscCall(VecDestroy(&coordsNew)); 114953b735f8SJames Wright } else { 115053b735f8SJames Wright PetscCall(DMGetCoordinates(dm, &coordsOld)); 115153b735f8SJames Wright PetscCall(DMCreateGlobalVector(cdmNew, &coordsNew)); 115253b735f8SJames Wright if (same_space) { 115353b735f8SJames Wright // Need to copy so that the new vector has the right dm 115453b735f8SJames Wright PetscCall(VecCopy(coordsOld, coordsNew)); 115590df3356SJames Wright } else { 1156e44f6aebSMatthew G. Knepley Mat In; 1157e44f6aebSMatthew G. Knepley 1158e44f6aebSMatthew G. Knepley PetscCall(DMCreateInterpolation(cdmOld, cdmNew, &In, NULL)); 1159e44f6aebSMatthew G. Knepley PetscCall(MatMult(In, coordsOld, coordsNew)); 1160e44f6aebSMatthew G. Knepley PetscCall(MatDestroy(&In)); 1161e44f6aebSMatthew G. Knepley } 1162e44f6aebSMatthew G. Knepley PetscCall(DMSetCoordinates(dm, coordsNew)); 1163e44f6aebSMatthew G. Knepley PetscCall(VecDestroy(&coordsNew)); 11646858538eSMatthew G. Knepley } 116553b735f8SJames Wright } 11666858538eSMatthew G. Knepley /* Set new coordinate structures */ 11676858538eSMatthew G. Knepley PetscCall(DMSetCoordinateField(dm, NULL)); 11686858538eSMatthew G. Knepley PetscCall(DMSetCoordinateDM(dm, cdmNew)); 11696858538eSMatthew G. Knepley PetscCall(DMDestroy(&cdmNew)); 11703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11716858538eSMatthew G. Knepley } 11726858538eSMatthew G. Knepley 11736858538eSMatthew G. Knepley /*@ 11740b3275a6SBarry Smith DMLocatePoints - Locate the points in `v` in the mesh and return a `PetscSF` of the containing cells 11756858538eSMatthew G. Knepley 117620f4b53cSBarry Smith Collective 11776858538eSMatthew G. Knepley 11786858538eSMatthew G. Knepley Input Parameters: 1179dce8aebaSBarry Smith + dm - The `DM` 1180dce8aebaSBarry Smith - ltype - The type of point location, e.g. `DM_POINTLOCATION_NONE` or `DM_POINTLOCATION_NEAREST` 11816858538eSMatthew G. Knepley 11826858538eSMatthew G. Knepley Input/Output Parameters: 1183dce8aebaSBarry Smith + v - The `Vec` of points, on output contains the nearest mesh points to the given points if `DM_POINTLOCATION_NEAREST` is used 118420f4b53cSBarry Smith - cellSF - Points to either `NULL`, or a `PetscSF` with guesses for which cells contain each point; 11850b3275a6SBarry Smith on output, the `PetscSF` containing the MPI ranks and local indices of the containing points 11866858538eSMatthew G. Knepley 11876858538eSMatthew G. Knepley Level: developer 11886858538eSMatthew G. Knepley 11896858538eSMatthew G. Knepley Notes: 11900b3275a6SBarry Smith To do a search of the local cells of the mesh, `v` should have `PETSC_COMM_SELF` as its communicator. 11910b3275a6SBarry Smith To do a search of all the cells in the distributed mesh, `v` should have the same MPI communicator as `dm`. 11926858538eSMatthew G. Knepley 1193d8206211SMatthew G. Knepley Points will only be located in owned cells, not overlap cells arising from `DMPlexDistribute()` or other overlapping distributions. 1194d8206211SMatthew G. Knepley 119520f4b53cSBarry Smith If *cellSF is `NULL` on input, a `PetscSF` will be created. 119620f4b53cSBarry Smith If *cellSF is not `NULL` on input, it should point to an existing `PetscSF`, whose graph will be used as initial guesses. 11976858538eSMatthew G. Knepley 11986858538eSMatthew G. Knepley An array that maps each point to its containing cell can be obtained with 1199dce8aebaSBarry Smith .vb 1200dce8aebaSBarry Smith const PetscSFNode *cells; 1201dce8aebaSBarry Smith PetscInt nFound; 1202dce8aebaSBarry Smith const PetscInt *found; 12036858538eSMatthew G. Knepley 1204dce8aebaSBarry Smith PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 1205dce8aebaSBarry Smith .ve 12066858538eSMatthew G. Knepley 12070b3275a6SBarry Smith Where cells[i].rank is the MPI rank of the process owning the cell containing point found[i] (or i if found == NULL), and cells[i].index is 12080b3275a6SBarry Smith the index of the cell in its MPI process' local numbering. This rank is in the communicator for `v`, so if `v` is on `PETSC_COMM_SELF` then the rank will always be 0. 12096858538eSMatthew G. Knepley 1210dce8aebaSBarry Smith .seealso: `DM`, `DMSetCoordinates()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMPointLocationType` 12116858538eSMatthew G. Knepley @*/ 1212d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 1213d71ae5a4SJacob Faibussowitsch { 12146858538eSMatthew G. Knepley PetscFunctionBegin; 12156858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12166858538eSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 12174f572ea9SToby Isaac PetscAssertPointer(cellSF, 4); 12186858538eSMatthew G. Knepley if (*cellSF) { 12196858538eSMatthew G. Knepley PetscMPIInt result; 12206858538eSMatthew G. Knepley 12216858538eSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF, PETSCSF_CLASSID, 4); 12226858538eSMatthew G. Knepley PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)v), PetscObjectComm((PetscObject)*cellSF), &result)); 12236858538eSMatthew 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"); 12246858538eSMatthew G. Knepley } else { 12256858538eSMatthew G. Knepley PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)v), cellSF)); 12266858538eSMatthew G. Knepley } 12276858538eSMatthew G. Knepley PetscCall(PetscLogEventBegin(DM_LocatePoints, dm, 0, 0, 0)); 1228dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, locatepoints, v, ltype, *cellSF); 12296858538eSMatthew G. Knepley PetscCall(PetscLogEventEnd(DM_LocatePoints, dm, 0, 0, 0)); 12303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12316858538eSMatthew G. Knepley } 1232