xref: /petsc/src/dm/interface/dmcoordinates.c (revision dc431b0c622bfdd860e6d0069e70d6077e15ef43)
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