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 66858538eSMatthew G. Knepley PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 76858538eSMatthew G. Knepley { 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 286858538eSMatthew G. Knepley static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 296858538eSMatthew G. Knepley { 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 @*/ 756858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 766858538eSMatthew G. Knepley { 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 83*dbbe0bcdSBarry 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 @*/ 1076858538eSMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 1086858538eSMatthew G. Knepley { 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 @*/ 1366858538eSMatthew G. Knepley PetscErrorCode DMGetCellCoordinateDM(DM dm, DM *cdm) 1376858538eSMatthew G. Knepley { 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 @*/ 1586858538eSMatthew G. Knepley PetscErrorCode DMSetCellCoordinateDM(DM dm, DM cdm) 1596858538eSMatthew G. Knepley { 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 @*/ 1906858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 1916858538eSMatthew G. Knepley { 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 @*/ 2136858538eSMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 2146858538eSMatthew G. Knepley { 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 @*/ 2466858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 2476858538eSMatthew G. Knepley { 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 @*/ 2726858538eSMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 2736858538eSMatthew G. Knepley { 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)); 2916858538eSMatthew G. Knepley if (dd) {d = dd; break;} 2926858538eSMatthew G. Knepley } 2936858538eSMatthew G. Knepley if (d >= 0) PetscCall(DMSetCoordinateDim(dm, d)); 2946858538eSMatthew G. Knepley } 2956858538eSMatthew G. Knepley PetscFunctionReturn(0); 2966858538eSMatthew G. Knepley } 2976858538eSMatthew G. Knepley 2986858538eSMatthew G. Knepley /*@ 2996858538eSMatthew G. Knepley DMGetCellCoordinateSection - Retrieve the layout of cellwise coordinate values over the mesh. 3006858538eSMatthew G. Knepley 3016858538eSMatthew G. Knepley Collective on dm 3026858538eSMatthew G. Knepley 3036858538eSMatthew G. Knepley Input Parameter: 3046858538eSMatthew G. Knepley . dm - The DM object 3056858538eSMatthew G. Knepley 3066858538eSMatthew G. Knepley Output Parameter: 3076858538eSMatthew G. Knepley . section - The PetscSection object, or NULL if no cellwise coordinates are defined 3086858538eSMatthew G. Knepley 3096858538eSMatthew G. Knepley Level: intermediate 3106858538eSMatthew G. Knepley 3116858538eSMatthew G. Knepley .seealso: `DMGetCoordinateSection()`, `DMSetCellCoordinateSection()`, `DMGetCellCoordinateDM()`, `DMGetCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 3126858538eSMatthew G. Knepley @*/ 3136858538eSMatthew G. Knepley PetscErrorCode DMGetCellCoordinateSection(DM dm, PetscSection *section) 3146858538eSMatthew G. Knepley { 3156858538eSMatthew G. Knepley DM cdm; 3166858538eSMatthew G. Knepley 3176858538eSMatthew G. Knepley PetscFunctionBegin; 3186858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3196858538eSMatthew G. Knepley PetscValidPointer(section, 2); 3206858538eSMatthew G. Knepley *section = NULL; 3216858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 3226858538eSMatthew G. Knepley if (cdm) PetscCall(DMGetLocalSection(cdm, section)); 3236858538eSMatthew G. Knepley PetscFunctionReturn(0); 3246858538eSMatthew G. Knepley } 3256858538eSMatthew G. Knepley 3266858538eSMatthew G. Knepley /*@ 3276858538eSMatthew G. Knepley DMSetCellCoordinateSection - Set the layout of cellwise coordinate values over the mesh. 3286858538eSMatthew G. Knepley 3296858538eSMatthew G. Knepley Not Collective 3306858538eSMatthew G. Knepley 3316858538eSMatthew G. Knepley Input Parameters: 3326858538eSMatthew G. Knepley + dm - The DM object 3336858538eSMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 3346858538eSMatthew G. Knepley - section - The PetscSection object for a cellwise layout 3356858538eSMatthew G. Knepley 3366858538eSMatthew G. Knepley Level: intermediate 3376858538eSMatthew G. Knepley 3386858538eSMatthew G. Knepley .seealso: `DMSetCoordinateSection()`, `DMGetCellCoordinateSection()`, `DMGetCoordinateSection()`, `DMGetCellCoordinateDM()`, `DMGetLocalSection()`, `DMSetLocalSection()` 3396858538eSMatthew G. Knepley @*/ 3406858538eSMatthew G. Knepley PetscErrorCode DMSetCellCoordinateSection(DM dm, PetscInt dim, PetscSection section) 3416858538eSMatthew G. Knepley { 3426858538eSMatthew G. Knepley DM cdm; 3436858538eSMatthew G. Knepley 3446858538eSMatthew G. Knepley PetscFunctionBegin; 3456858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3466858538eSMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 3476858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 3486858538eSMatthew G. Knepley PetscCheck(cdm, PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "No DM defined for cellwise coordinates"); 3496858538eSMatthew G. Knepley PetscCall(DMSetLocalSection(cdm, section)); 3506858538eSMatthew G. Knepley if (dim == PETSC_DETERMINE) { 3516858538eSMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 3526858538eSMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 3536858538eSMatthew G. Knepley 3546858538eSMatthew G. Knepley PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 3556858538eSMatthew G. Knepley PetscCall(DMGetDimPoints(dm, 0, &vStart, &vEnd)); 3566858538eSMatthew G. Knepley pStart = PetscMax(vStart, pStart); 3576858538eSMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 3586858538eSMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 3596858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(section, v, &dd)); 3606858538eSMatthew G. Knepley if (dd) {d = dd; break;} 3616858538eSMatthew G. Knepley } 3626858538eSMatthew G. Knepley if (d >= 0) PetscCall(DMSetCoordinateDim(dm, d)); 3636858538eSMatthew G. Knepley } 3646858538eSMatthew G. Knepley PetscFunctionReturn(0); 3656858538eSMatthew G. Knepley } 3666858538eSMatthew G. Knepley 3676858538eSMatthew G. Knepley /*@ 3686858538eSMatthew G. Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 3696858538eSMatthew G. Knepley 3706858538eSMatthew G. Knepley Collective on dm 3716858538eSMatthew G. Knepley 3726858538eSMatthew G. Knepley Input Parameter: 3736858538eSMatthew G. Knepley . dm - the DM 3746858538eSMatthew G. Knepley 3756858538eSMatthew G. Knepley Output Parameter: 3766858538eSMatthew G. Knepley . c - global coordinate vector 3776858538eSMatthew G. Knepley 3786858538eSMatthew G. Knepley Note: 3796858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 3806858538eSMatthew G. Knepley destroyed the array will no longer be valid. 3816858538eSMatthew G. Knepley 3826858538eSMatthew G. Knepley Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 3836858538eSMatthew G. Knepley 3846858538eSMatthew G. Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 3856858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 3866858538eSMatthew G. Knepley 3876858538eSMatthew G. Knepley Level: intermediate 3886858538eSMatthew G. Knepley 3896858538eSMatthew G. Knepley .seealso: `DMSetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetCoordinateDM()`, `DMDASetUniformCoordinates()` 3906858538eSMatthew G. Knepley @*/ 3916858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 3926858538eSMatthew G. Knepley { 3936858538eSMatthew G. Knepley PetscFunctionBegin; 3946858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3956858538eSMatthew G. Knepley PetscValidPointer(c,2); 3966858538eSMatthew G. Knepley if (!dm->coordinates[0].x && dm->coordinates[0].xl) { 3976858538eSMatthew G. Knepley DM cdm = NULL; 3986858538eSMatthew G. Knepley 3996858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 4006858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdm, &dm->coordinates[0].x)); 4016858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject) dm->coordinates[0].x, "coordinates")); 4026858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(cdm, dm->coordinates[0].xl, INSERT_VALUES, dm->coordinates[0].x)); 4036858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(cdm, dm->coordinates[0].xl, INSERT_VALUES, dm->coordinates[0].x)); 4046858538eSMatthew G. Knepley } 4056858538eSMatthew G. Knepley *c = dm->coordinates[0].x; 4066858538eSMatthew G. Knepley PetscFunctionReturn(0); 4076858538eSMatthew G. Knepley } 4086858538eSMatthew G. Knepley 4096858538eSMatthew G. Knepley /*@ 4106858538eSMatthew G. Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 4116858538eSMatthew G. Knepley 4126858538eSMatthew G. Knepley Collective on dm 4136858538eSMatthew G. Knepley 4146858538eSMatthew G. Knepley Input Parameters: 4156858538eSMatthew G. Knepley + dm - the DM 4166858538eSMatthew G. Knepley - c - coordinate vector 4176858538eSMatthew G. Knepley 4186858538eSMatthew G. Knepley Notes: 4196858538eSMatthew G. Knepley The coordinates do include those for ghost points, which are in the local vector. 4206858538eSMatthew G. Knepley 4216858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 4226858538eSMatthew G. Knepley 4236858538eSMatthew G. Knepley Level: intermediate 4246858538eSMatthew G. Knepley 4256858538eSMatthew G. Knepley .seealso: `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetCoordinateDM()`, `DMDASetUniformCoordinates()` 4266858538eSMatthew G. Knepley @*/ 4276858538eSMatthew G. Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 4286858538eSMatthew G. Knepley { 4296858538eSMatthew G. Knepley PetscFunctionBegin; 4306858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4316858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2); 4326858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject) c)); 4336858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].x)); 4346858538eSMatthew G. Knepley dm->coordinates[0].x = c; 4356858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].xl)); 4366858538eSMatthew G. Knepley PetscCall(DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL)); 4376858538eSMatthew G. Knepley PetscCall(DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL)); 4386858538eSMatthew G. Knepley PetscFunctionReturn(0); 4396858538eSMatthew G. Knepley } 4406858538eSMatthew G. Knepley 4416858538eSMatthew G. Knepley /*@ 4426858538eSMatthew G. Knepley DMGetCellCoordinates - Gets a global vector with the cellwise coordinates associated with the DM. 4436858538eSMatthew G. Knepley 4446858538eSMatthew G. Knepley Collective on dm 4456858538eSMatthew G. Knepley 4466858538eSMatthew G. Knepley Input Parameter: 4476858538eSMatthew G. Knepley . dm - the DM 4486858538eSMatthew G. Knepley 4496858538eSMatthew G. Knepley Output Parameter: 4506858538eSMatthew G. Knepley . c - global coordinate vector 4516858538eSMatthew G. Knepley 4526858538eSMatthew G. Knepley Note: 4536858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 4546858538eSMatthew G. Knepley destroyed the array will no longer be valid. 4556858538eSMatthew G. Knepley 4566858538eSMatthew G. Knepley Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 4576858538eSMatthew G. Knepley 4586858538eSMatthew G. Knepley Level: intermediate 4596858538eSMatthew G. Knepley 4606858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMGetCellCoordinateDM()` 4616858538eSMatthew G. Knepley @*/ 4626858538eSMatthew G. Knepley PetscErrorCode DMGetCellCoordinates(DM dm, Vec *c) 4636858538eSMatthew G. Knepley { 4646858538eSMatthew G. Knepley PetscFunctionBegin; 4656858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4666858538eSMatthew G. Knepley PetscValidPointer(c,2); 4676858538eSMatthew G. Knepley if (!dm->coordinates[1].x && dm->coordinates[1].xl) { 4686858538eSMatthew G. Knepley DM cdm = NULL; 4696858538eSMatthew G. Knepley 47011ea91a7SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 4716858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdm, &dm->coordinates[1].x)); 4726858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject) dm->coordinates[1].x, "DG coordinates")); 4736858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(cdm, dm->coordinates[1].xl, INSERT_VALUES, dm->coordinates[1].x)); 4746858538eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(cdm, dm->coordinates[1].xl, INSERT_VALUES, dm->coordinates[1].x)); 4756858538eSMatthew G. Knepley } 4766858538eSMatthew G. Knepley *c = dm->coordinates[1].x; 4776858538eSMatthew G. Knepley PetscFunctionReturn(0); 4786858538eSMatthew G. Knepley } 4796858538eSMatthew G. Knepley 4806858538eSMatthew G. Knepley /*@ 4816858538eSMatthew G. Knepley DMSetCellCoordinates - Sets into the DM a global vector that holds the cellwise coordinates 4826858538eSMatthew G. Knepley 4836858538eSMatthew G. Knepley Collective on dm 4846858538eSMatthew G. Knepley 4856858538eSMatthew G. Knepley Input Parameters: 4866858538eSMatthew G. Knepley + dm - the DM 4876858538eSMatthew G. Knepley - c - cellwise coordinate vector 4886858538eSMatthew G. Knepley 4896858538eSMatthew G. Knepley Notes: 4906858538eSMatthew G. Knepley The coordinates do include those for ghost points, which are in the local vector. 4916858538eSMatthew G. Knepley 4926858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 4936858538eSMatthew G. Knepley 4946858538eSMatthew G. Knepley Level: intermediate 4956858538eSMatthew G. Knepley 4966858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMGetCellCoordinatesLocal()`, `DMGetCellCoordinateDM()` 4976858538eSMatthew G. Knepley @*/ 4986858538eSMatthew G. Knepley PetscErrorCode DMSetCellCoordinates(DM dm, Vec c) 4996858538eSMatthew G. Knepley { 5006858538eSMatthew G. Knepley PetscFunctionBegin; 5016858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5026858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2); 5036858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject) c)); 5046858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].x)); 5056858538eSMatthew G. Knepley dm->coordinates[1].x = c; 5066858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].xl)); 5076858538eSMatthew G. Knepley PetscFunctionReturn(0); 5086858538eSMatthew G. Knepley } 5096858538eSMatthew G. Knepley 5106858538eSMatthew G. Knepley /*@ 5116858538eSMatthew G. Knepley DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 5126858538eSMatthew G. Knepley 5136858538eSMatthew G. Knepley Collective on dm 5146858538eSMatthew G. Knepley 5156858538eSMatthew G. Knepley Input Parameter: 5166858538eSMatthew G. Knepley . dm - the DM 5176858538eSMatthew G. Knepley 5186858538eSMatthew G. Knepley Level: advanced 5196858538eSMatthew G. Knepley 5206858538eSMatthew G. Knepley .seealso: `DMGetCoordinatesLocalNoncollective()` 5216858538eSMatthew G. Knepley @*/ 5226858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 5236858538eSMatthew G. Knepley { 5246858538eSMatthew G. Knepley PetscFunctionBegin; 5256858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5266858538eSMatthew G. Knepley if (!dm->coordinates[0].xl && dm->coordinates[0].x) { 5276858538eSMatthew G. Knepley DM cdm = NULL; 5286858538eSMatthew G. Knepley 5296858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 5306858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(cdm, &dm->coordinates[0].xl)); 5316858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject) dm->coordinates[0].xl, "coordinates")); 5326858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(cdm, dm->coordinates[0].x, INSERT_VALUES, dm->coordinates[0].xl)); 5336858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(cdm, dm->coordinates[0].x, INSERT_VALUES, dm->coordinates[0].xl)); 5346858538eSMatthew G. Knepley } 5356858538eSMatthew G. Knepley PetscFunctionReturn(0); 5366858538eSMatthew G. Knepley } 5376858538eSMatthew G. Knepley 5386858538eSMatthew G. Knepley /*@ 5396858538eSMatthew G. Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 5406858538eSMatthew G. Knepley 5416858538eSMatthew G. Knepley Collective on dm 5426858538eSMatthew G. Knepley 5436858538eSMatthew G. Knepley Input Parameter: 5446858538eSMatthew G. Knepley . dm - the DM 5456858538eSMatthew G. Knepley 5466858538eSMatthew G. Knepley Output Parameter: 5476858538eSMatthew G. Knepley . c - coordinate vector 5486858538eSMatthew G. Knepley 5496858538eSMatthew G. Knepley Note: 5506858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector 5516858538eSMatthew G. Knepley 5526858538eSMatthew G. Knepley Each process has the local and ghost coordinates 5536858538eSMatthew G. Knepley 5546858538eSMatthew G. Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 5556858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 5566858538eSMatthew G. Knepley 5576858538eSMatthew G. Knepley Level: intermediate 5586858538eSMatthew G. Knepley 5596858538eSMatthew G. Knepley .seealso: `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()`, `DMGetCoordinatesLocalNoncollective()` 5606858538eSMatthew G. Knepley @*/ 5616858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 5626858538eSMatthew G. Knepley { 5636858538eSMatthew G. Knepley PetscFunctionBegin; 5646858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5656858538eSMatthew G. Knepley PetscValidPointer(c,2); 5666858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(dm)); 5676858538eSMatthew G. Knepley *c = dm->coordinates[0].xl; 5686858538eSMatthew G. Knepley PetscFunctionReturn(0); 5696858538eSMatthew G. Knepley } 5706858538eSMatthew G. Knepley 5716858538eSMatthew G. Knepley /*@ 5726858538eSMatthew G. Knepley DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 5736858538eSMatthew G. Knepley 5746858538eSMatthew G. Knepley Not collective 5756858538eSMatthew G. Knepley 5766858538eSMatthew G. Knepley Input Parameter: 5776858538eSMatthew G. Knepley . dm - the DM 5786858538eSMatthew G. Knepley 5796858538eSMatthew G. Knepley Output Parameter: 5806858538eSMatthew G. Knepley . c - coordinate vector 5816858538eSMatthew G. Knepley 5826858538eSMatthew G. Knepley Level: advanced 5836858538eSMatthew G. Knepley 5846858538eSMatthew G. Knepley .seealso: `DMGetCoordinatesLocalSetUp()`, `DMGetCoordinatesLocal()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()` 5856858538eSMatthew G. Knepley @*/ 5866858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 5876858538eSMatthew G. Knepley { 5886858538eSMatthew G. Knepley PetscFunctionBegin; 5896858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5906858538eSMatthew G. Knepley PetscValidPointer(c,2); 5916858538eSMatthew G. Knepley PetscCheck(dm->coordinates[0].xl || !dm->coordinates[0].x, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 5926858538eSMatthew G. Knepley *c = dm->coordinates[0].xl; 5936858538eSMatthew G. Knepley PetscFunctionReturn(0); 5946858538eSMatthew G. Knepley } 5956858538eSMatthew G. Knepley 5966858538eSMatthew G. Knepley /*@ 5976858538eSMatthew G. Knepley DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 5986858538eSMatthew G. Knepley 5996858538eSMatthew G. Knepley Not collective 6006858538eSMatthew G. Knepley 6016858538eSMatthew G. Knepley Input Parameters: 6026858538eSMatthew G. Knepley + dm - the DM 6036858538eSMatthew G. Knepley - p - the IS of points whose coordinates will be returned 6046858538eSMatthew G. Knepley 6056858538eSMatthew G. Knepley Output Parameters: 6066858538eSMatthew 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 6076858538eSMatthew G. Knepley - pCoord - the Vec with coordinates of points in p 6086858538eSMatthew G. Knepley 6096858538eSMatthew G. Knepley Note: 6106858538eSMatthew G. Knepley DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 6116858538eSMatthew G. Knepley 6126858538eSMatthew G. Knepley This creates a new vector, so the user SHOULD destroy this vector 6136858538eSMatthew G. Knepley 6146858538eSMatthew G. Knepley Each process has the local and ghost coordinates 6156858538eSMatthew G. Knepley 6166858538eSMatthew G. Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 6176858538eSMatthew G. Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 6186858538eSMatthew G. Knepley 6196858538eSMatthew G. Knepley Level: advanced 6206858538eSMatthew G. Knepley 6216858538eSMatthew G. Knepley .seealso: `DMSetCoordinatesLocal()`, `DMGetCoordinatesLocal()`, `DMGetCoordinatesLocalNoncollective()`, `DMGetCoordinatesLocalSetUp()`, `DMGetCoordinates()`, `DMSetCoordinates()`, `DMGetCoordinateDM()` 6226858538eSMatthew G. Knepley @*/ 6236858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 6246858538eSMatthew G. Knepley { 6256858538eSMatthew G. Knepley DM cdm; 6266858538eSMatthew G. Knepley PetscSection cs, newcs; 6276858538eSMatthew G. Knepley Vec coords; 6286858538eSMatthew G. Knepley const PetscScalar *arr; 6296858538eSMatthew G. Knepley PetscScalar *newarr = NULL; 6306858538eSMatthew G. Knepley PetscInt n; 6316858538eSMatthew G. Knepley 6326858538eSMatthew G. Knepley PetscFunctionBegin; 6336858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6346858538eSMatthew G. Knepley PetscValidHeaderSpecific(p, IS_CLASSID, 2); 6356858538eSMatthew G. Knepley if (pCoordSection) PetscValidPointer(pCoordSection, 3); 6366858538eSMatthew G. Knepley if (pCoord) PetscValidPointer(pCoord, 4); 6376858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 6386858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(cdm, &cs)); 6396858538eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coords)); 6406858538eSMatthew G. Knepley PetscCheck(coords, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 6416858538eSMatthew G. Knepley PetscCheck(cdm && cs, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 6426858538eSMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &arr)); 6436858538eSMatthew G. Knepley PetscCall(PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL)); 6446858538eSMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &arr)); 6456858538eSMatthew G. Knepley if (pCoord) { 6466858538eSMatthew G. Knepley PetscCall(PetscSectionGetStorageSize(newcs, &n)); 6476858538eSMatthew G. Knepley /* set array in two steps to mimic PETSC_OWN_POINTER */ 6486858538eSMatthew G. Knepley PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord)); 6496858538eSMatthew G. Knepley PetscCall(VecReplaceArray(*pCoord, newarr)); 6506858538eSMatthew G. Knepley } else { 6516858538eSMatthew G. Knepley PetscCall(PetscFree(newarr)); 6526858538eSMatthew G. Knepley } 6536858538eSMatthew G. Knepley if (pCoordSection) {*pCoordSection = newcs;} 6546858538eSMatthew G. Knepley else PetscCall(PetscSectionDestroy(&newcs)); 6556858538eSMatthew G. Knepley PetscFunctionReturn(0); 6566858538eSMatthew G. Knepley } 6576858538eSMatthew G. Knepley 6586858538eSMatthew G. Knepley /*@ 6596858538eSMatthew G. Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 6606858538eSMatthew G. Knepley 6616858538eSMatthew G. Knepley Not collective 6626858538eSMatthew G. Knepley 6636858538eSMatthew G. Knepley Input Parameters: 6646858538eSMatthew G. Knepley + dm - the DM 6656858538eSMatthew G. Knepley - c - coordinate vector 6666858538eSMatthew G. Knepley 6676858538eSMatthew G. Knepley Notes: 6686858538eSMatthew G. Knepley The coordinates of ghost points can be set using DMSetCoordinates() 6696858538eSMatthew G. Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 6706858538eSMatthew G. Knepley setting of ghost coordinates outside of the domain. 6716858538eSMatthew G. Knepley 6726858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 6736858538eSMatthew G. Knepley 6746858538eSMatthew G. Knepley Level: intermediate 6756858538eSMatthew G. Knepley 6766858538eSMatthew G. Knepley .seealso: `DMGetCoordinatesLocal()`, `DMSetCoordinates()`, `DMGetCoordinates()`, `DMGetCoordinateDM()` 6776858538eSMatthew G. Knepley @*/ 6786858538eSMatthew G. Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 6796858538eSMatthew G. Knepley { 6806858538eSMatthew G. Knepley PetscFunctionBegin; 6816858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6826858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2); 6836858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject) c)); 6846858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].xl)); 6856858538eSMatthew G. Knepley dm->coordinates[0].xl = c; 6866858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[0].x)); 6876858538eSMatthew G. Knepley PetscFunctionReturn(0); 6886858538eSMatthew G. Knepley } 6896858538eSMatthew G. Knepley 6906858538eSMatthew G. Knepley /*@ 6916858538eSMatthew G. Knepley DMGetCellCoordinatesLocalSetUp - Prepares a local vector of cellwise coordinates, so that DMGetCellCoordinatesLocalNoncollective() can be used as non-collective afterwards. 6926858538eSMatthew G. Knepley 6936858538eSMatthew G. Knepley Collective on dm 6946858538eSMatthew G. Knepley 6956858538eSMatthew G. Knepley Input Parameter: 6966858538eSMatthew G. Knepley . dm - the DM 6976858538eSMatthew G. Knepley 6986858538eSMatthew G. Knepley Level: advanced 6996858538eSMatthew G. Knepley 7006858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinatesLocalNoncollective()` 7016858538eSMatthew G. Knepley @*/ 7026858538eSMatthew G. Knepley PetscErrorCode DMGetCellCoordinatesLocalSetUp(DM dm) 7036858538eSMatthew G. Knepley { 7046858538eSMatthew G. Knepley PetscFunctionBegin; 7056858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7066858538eSMatthew G. Knepley if (!dm->coordinates[1].xl && dm->coordinates[1].x) { 7076858538eSMatthew G. Knepley DM cdm = NULL; 7086858538eSMatthew G. Knepley 70911ea91a7SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 7106858538eSMatthew G. Knepley PetscCall(DMCreateLocalVector(cdm, &dm->coordinates[1].xl)); 7116858538eSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject) dm->coordinates[1].xl, "DG coordinates")); 7126858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(cdm, dm->coordinates[1].x, INSERT_VALUES, dm->coordinates[1].xl)); 7136858538eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(cdm, dm->coordinates[1].x, INSERT_VALUES, dm->coordinates[1].xl)); 7146858538eSMatthew G. Knepley } 7156858538eSMatthew G. Knepley PetscFunctionReturn(0); 7166858538eSMatthew G. Knepley } 7176858538eSMatthew G. Knepley 7186858538eSMatthew G. Knepley /*@ 7196858538eSMatthew G. Knepley DMGetCellCoordinatesLocal - Gets a local vector with the cellwise coordinates associated with the DM. 7206858538eSMatthew G. Knepley 7216858538eSMatthew G. Knepley Collective on dm 7226858538eSMatthew G. Knepley 7236858538eSMatthew G. Knepley Input Parameter: 7246858538eSMatthew G. Knepley . dm - the DM 7256858538eSMatthew G. Knepley 7266858538eSMatthew G. Knepley Output Parameter: 7276858538eSMatthew G. Knepley . c - coordinate vector 7286858538eSMatthew G. Knepley 7296858538eSMatthew G. Knepley Note: 7306858538eSMatthew G. Knepley This is a borrowed reference, so the user should NOT destroy this vector 7316858538eSMatthew G. Knepley 7326858538eSMatthew G. Knepley Each process has the local and ghost coordinates 7336858538eSMatthew G. Knepley 7346858538eSMatthew G. Knepley Level: intermediate 7356858538eSMatthew G. Knepley 7366858538eSMatthew G. Knepley .seealso: `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinateDM()`, `DMGetCellCoordinatesLocalNoncollective()` 7376858538eSMatthew G. Knepley @*/ 7386858538eSMatthew G. Knepley PetscErrorCode DMGetCellCoordinatesLocal(DM dm, Vec *c) 7396858538eSMatthew G. Knepley { 7406858538eSMatthew G. Knepley PetscFunctionBegin; 7416858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7426858538eSMatthew G. Knepley PetscValidPointer(c,2); 7436858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocalSetUp(dm)); 7446858538eSMatthew G. Knepley *c = dm->coordinates[1].xl; 7456858538eSMatthew G. Knepley PetscFunctionReturn(0); 7466858538eSMatthew G. Knepley } 7476858538eSMatthew G. Knepley 7486858538eSMatthew G. Knepley /*@ 7496858538eSMatthew G. Knepley DMGetCellCoordinatesLocalNoncollective - Non-collective version of DMGetCellCoordinatesLocal(). Fails if global cellwise coordinates have been set and DMGetCellCoordinatesLocalSetUp() not called. 7506858538eSMatthew G. Knepley 7516858538eSMatthew G. Knepley Not collective 7526858538eSMatthew G. Knepley 7536858538eSMatthew G. Knepley Input Parameter: 7546858538eSMatthew G. Knepley . dm - the DM 7556858538eSMatthew G. Knepley 7566858538eSMatthew G. Knepley Output Parameter: 7576858538eSMatthew G. Knepley . c - cellwise coordinate vector 7586858538eSMatthew G. Knepley 7596858538eSMatthew G. Knepley Level: advanced 7606858538eSMatthew G. Knepley 7616858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinatesLocalSetUp()`, `DMGetCellCoordinatesLocal()`, `DMSetCellCoordinatesLocal()`, `DMGetCellCoordinates()`, `DMSetCellCoordinates()`, `DMGetCellCoordinateDM()` 7626858538eSMatthew G. Knepley @*/ 7636858538eSMatthew G. Knepley PetscErrorCode DMGetCellCoordinatesLocalNoncollective(DM dm, Vec *c) 7646858538eSMatthew G. Knepley { 7656858538eSMatthew G. Knepley PetscFunctionBegin; 7666858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7676858538eSMatthew G. Knepley PetscValidPointer(c,2); 7686858538eSMatthew G. Knepley PetscCheck(dm->coordinates[1].xl || !dm->coordinates[1].x, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCellCoordinatesLocalSetUp() has not been called"); 7696858538eSMatthew G. Knepley *c = dm->coordinates[1].xl; 7706858538eSMatthew G. Knepley PetscFunctionReturn(0); 7716858538eSMatthew G. Knepley } 7726858538eSMatthew G. Knepley 7736858538eSMatthew G. Knepley /*@ 7746858538eSMatthew G. Knepley DMSetCellCoordinatesLocal - Sets into the DM a local vector that holds the cellwise coordinates 7756858538eSMatthew G. Knepley 7766858538eSMatthew G. Knepley Not collective 7776858538eSMatthew G. Knepley 7786858538eSMatthew G. Knepley Input Parameters: 7796858538eSMatthew G. Knepley + dm - the DM 7806858538eSMatthew G. Knepley - c - cellwise coordinate vector 7816858538eSMatthew G. Knepley 7826858538eSMatthew G. Knepley Notes: 7836858538eSMatthew G. Knepley The coordinates of ghost points can be set using DMSetCoordinates() 7846858538eSMatthew G. Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 7856858538eSMatthew G. Knepley setting of ghost coordinates outside of the domain. 7866858538eSMatthew G. Knepley 7876858538eSMatthew G. Knepley The vector c should be destroyed by the caller. 7886858538eSMatthew G. Knepley 7896858538eSMatthew G. Knepley Level: intermediate 7906858538eSMatthew G. Knepley 7916858538eSMatthew G. Knepley .seealso: `DMGetCellCoordinatesLocal()`, `DMSetCellCoordinates()`, `DMGetCellCoordinates()`, `DMGetCellCoordinateDM()` 7926858538eSMatthew G. Knepley @*/ 7936858538eSMatthew G. Knepley PetscErrorCode DMSetCellCoordinatesLocal(DM dm, Vec c) 7946858538eSMatthew G. Knepley { 7956858538eSMatthew G. Knepley PetscFunctionBegin; 7966858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7976858538eSMatthew G. Knepley if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2); 7986858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject) c)); 7996858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].xl)); 8006858538eSMatthew G. Knepley dm->coordinates[1].xl = c; 8016858538eSMatthew G. Knepley PetscCall(VecDestroy(&dm->coordinates[1].x)); 8026858538eSMatthew G. Knepley PetscFunctionReturn(0); 8036858538eSMatthew G. Knepley } 8046858538eSMatthew G. Knepley 8056858538eSMatthew G. Knepley PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 8066858538eSMatthew G. Knepley { 8076858538eSMatthew G. Knepley PetscFunctionBegin; 8086858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8096858538eSMatthew G. Knepley PetscValidPointer(field,2); 8106858538eSMatthew G. Knepley if (!dm->coordinates[0].field) { 8116858538eSMatthew G. Knepley if (dm->ops->createcoordinatefield) PetscCall((*dm->ops->createcoordinatefield)(dm, &dm->coordinates[0].field)); 8126858538eSMatthew G. Knepley } 8136858538eSMatthew G. Knepley *field = dm->coordinates[0].field; 8146858538eSMatthew G. Knepley PetscFunctionReturn(0); 8156858538eSMatthew G. Knepley } 8166858538eSMatthew G. Knepley 8176858538eSMatthew G. Knepley PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 8186858538eSMatthew G. Knepley { 8196858538eSMatthew G. Knepley PetscFunctionBegin; 8206858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8216858538eSMatthew G. Knepley if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 8226858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)field)); 8236858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&dm->coordinates[0].field)); 8246858538eSMatthew G. Knepley dm->coordinates[0].field = field; 8256858538eSMatthew G. Knepley PetscFunctionReturn(0); 8266858538eSMatthew G. Knepley } 8276858538eSMatthew G. Knepley 8286858538eSMatthew G. Knepley /*@ 8296858538eSMatthew G. Knepley DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process. 8306858538eSMatthew G. Knepley 8316858538eSMatthew G. Knepley Not collective 8326858538eSMatthew G. Knepley 8336858538eSMatthew G. Knepley Input Parameter: 8346858538eSMatthew G. Knepley . dm - the DM 8356858538eSMatthew G. Knepley 8366858538eSMatthew G. Knepley Output Parameters: 8376858538eSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional) 8386858538eSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional) 8396858538eSMatthew G. Knepley 8406858538eSMatthew G. Knepley Level: beginner 8416858538eSMatthew G. Knepley 8426858538eSMatthew G. Knepley Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead. 8436858538eSMatthew G. Knepley 8446858538eSMatthew G. Knepley .seealso: `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMGetBoundingBox()` 8456858538eSMatthew G. Knepley @*/ 8466858538eSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[]) 8476858538eSMatthew G. Knepley { 8486858538eSMatthew G. Knepley Vec coords = NULL; 8496858538eSMatthew G. Knepley PetscReal min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 8506858538eSMatthew G. Knepley PetscReal max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 8516858538eSMatthew G. Knepley const PetscScalar *local_coords; 8526858538eSMatthew G. Knepley PetscInt N, Ni; 8536858538eSMatthew G. Knepley PetscInt cdim, i, j; 8546858538eSMatthew G. Knepley 8556858538eSMatthew G. Knepley PetscFunctionBegin; 8566858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8576858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 8586858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coords)); 8596858538eSMatthew G. Knepley if (coords) { 8606858538eSMatthew G. Knepley PetscCall(VecGetArrayRead(coords, &local_coords)); 8616858538eSMatthew G. Knepley PetscCall(VecGetLocalSize(coords, &N)); 8626858538eSMatthew G. Knepley Ni = N/cdim; 8636858538eSMatthew G. Knepley for (i = 0; i < Ni; ++i) { 8646858538eSMatthew G. Knepley for (j = 0; j < 3; ++j) { 8656858538eSMatthew G. Knepley min[j] = j < cdim ? PetscMin(min[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 8666858538eSMatthew G. Knepley max[j] = j < cdim ? PetscMax(max[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 8676858538eSMatthew G. Knepley } 8686858538eSMatthew G. Knepley } 8696858538eSMatthew G. Knepley PetscCall(VecRestoreArrayRead(coords, &local_coords)); 8706858538eSMatthew G. Knepley } else { 8716858538eSMatthew G. Knepley PetscBool isda; 8726858538eSMatthew G. Knepley 8736858538eSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject) dm, DMDA, &isda)); 8746858538eSMatthew G. Knepley if (isda) PetscCall(DMGetLocalBoundingIndices_DMDA(dm, min, max)); 8756858538eSMatthew G. Knepley } 8766858538eSMatthew G. Knepley if (lmin) PetscCall(PetscArraycpy(lmin, min, cdim)); 8776858538eSMatthew G. Knepley if (lmax) PetscCall(PetscArraycpy(lmax, max, cdim)); 8786858538eSMatthew G. Knepley PetscFunctionReturn(0); 8796858538eSMatthew G. Knepley } 8806858538eSMatthew G. Knepley 8816858538eSMatthew G. Knepley /*@ 8826858538eSMatthew G. Knepley DMGetBoundingBox - Returns the global bounding box for the DM. 8836858538eSMatthew G. Knepley 8846858538eSMatthew G. Knepley Collective 8856858538eSMatthew G. Knepley 8866858538eSMatthew G. Knepley Input Parameter: 8876858538eSMatthew G. Knepley . dm - the DM 8886858538eSMatthew G. Knepley 8896858538eSMatthew G. Knepley Output Parameters: 8906858538eSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional) 8916858538eSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional) 8926858538eSMatthew G. Knepley 8936858538eSMatthew G. Knepley Level: beginner 8946858538eSMatthew G. Knepley 8956858538eSMatthew G. Knepley .seealso: `DMGetLocalBoundingBox()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()` 8966858538eSMatthew G. Knepley @*/ 8976858538eSMatthew G. Knepley PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[]) 8986858538eSMatthew G. Knepley { 8996858538eSMatthew G. Knepley PetscReal lmin[3], lmax[3]; 9006858538eSMatthew G. Knepley PetscInt cdim; 9016858538eSMatthew G. Knepley PetscMPIInt count; 9026858538eSMatthew G. Knepley 9036858538eSMatthew G. Knepley PetscFunctionBegin; 9046858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9056858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 9066858538eSMatthew G. Knepley PetscCall(PetscMPIIntCast(cdim, &count)); 9076858538eSMatthew G. Knepley PetscCall(DMGetLocalBoundingBox(dm, lmin, lmax)); 9086858538eSMatthew G. Knepley if (gmin) PetscCall(MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm))); 9096858538eSMatthew G. Knepley if (gmax) PetscCall(MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) dm))); 9106858538eSMatthew G. Knepley PetscFunctionReturn(0); 9116858538eSMatthew G. Knepley } 9126858538eSMatthew G. Knepley 9136858538eSMatthew G. Knepley /*@ 9146858538eSMatthew G. Knepley DMProjectCoordinates - Project coordinates to a different space 9156858538eSMatthew G. Knepley 9166858538eSMatthew G. Knepley Input Parameters: 9176858538eSMatthew G. Knepley + dm - The DM object 9186858538eSMatthew G. Knepley - disc - The new coordinate discretization or NULL to ensure a coordinate discretization exists 9196858538eSMatthew G. Knepley 9206858538eSMatthew G. Knepley Level: intermediate 9216858538eSMatthew G. Knepley 9226858538eSMatthew G. Knepley .seealso: `DMGetCoordinateField()` 9236858538eSMatthew G. Knepley @*/ 9246858538eSMatthew G. Knepley PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 9256858538eSMatthew G. Knepley { 9266858538eSMatthew G. Knepley PetscFE discOld; 9276858538eSMatthew G. Knepley PetscClassId classid; 9286858538eSMatthew G. Knepley DM cdmOld,cdmNew; 9296858538eSMatthew G. Knepley Vec coordsOld,coordsNew; 9306858538eSMatthew G. Knepley Mat matInterp; 9316858538eSMatthew G. Knepley PetscBool same_space = PETSC_TRUE; 9326858538eSMatthew G. Knepley 9336858538eSMatthew G. Knepley PetscFunctionBegin; 9346858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9356858538eSMatthew G. Knepley if (disc) PetscValidHeaderSpecific(disc,PETSCFE_CLASSID,2); 9366858538eSMatthew G. Knepley 9376858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdmOld)); 9386858538eSMatthew G. Knepley /* Check current discretization is compatible */ 9396858538eSMatthew G. Knepley PetscCall(DMGetField(cdmOld, 0, NULL, (PetscObject*)&discOld)); 9406858538eSMatthew G. Knepley PetscCall(PetscObjectGetClassId((PetscObject)discOld, &classid)); 9416858538eSMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 9426858538eSMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 9436858538eSMatthew G. Knepley PetscFE feLinear; 9446858538eSMatthew G. Knepley DMPolytopeType ct; 9456858538eSMatthew G. Knepley PetscInt dim, dE, cStart, cEnd; 9466858538eSMatthew G. Knepley PetscBool simplex; 9476858538eSMatthew G. Knepley 9486858538eSMatthew G. Knepley /* Assume linear vertex coordinates */ 9496858538eSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 9506858538eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &dE)); 9516858538eSMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 9526858538eSMatthew G. Knepley if (cEnd > cStart) { 9536858538eSMatthew G. Knepley PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 9546858538eSMatthew G. Knepley switch (ct) { 9556858538eSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 9566858538eSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 9576858538eSMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot autoamtically create coordinate space for prisms"); 9586858538eSMatthew G. Knepley default: break; 9596858538eSMatthew G. Knepley } 9606858538eSMatthew G. Knepley } 9616858538eSMatthew G. Knepley PetscCall(DMPlexIsSimplex(dm, &simplex)); 9626858538eSMatthew G. Knepley PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, 1, -1, &feLinear)); 9636858538eSMatthew G. Knepley PetscCall(DMSetField(cdmOld, 0, NULL, (PetscObject) feLinear)); 9646858538eSMatthew G. Knepley PetscCall(PetscFEDestroy(&feLinear)); 9656858538eSMatthew G. Knepley PetscCall(DMCreateDS(cdmOld)); 9666858538eSMatthew G. Knepley PetscCall(DMGetField(cdmOld, 0, NULL, (PetscObject*)&discOld)); 9676858538eSMatthew G. Knepley } else { 9686858538eSMatthew G. Knepley const char *discname; 9696858538eSMatthew G. Knepley 9706858538eSMatthew G. Knepley PetscCall(PetscObjectGetType((PetscObject)discOld, &discname)); 9716858538eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 9726858538eSMatthew G. Knepley } 9736858538eSMatthew G. Knepley } 9746858538eSMatthew G. Knepley if (!disc) PetscFunctionReturn(0); 9756858538eSMatthew G. Knepley { // Check if the new space is the same as the old modulo quadrature 9766858538eSMatthew G. Knepley PetscDualSpace dsOld, ds; 9776858538eSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(discOld, &dsOld)); 9786858538eSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(disc, &ds)); 9796858538eSMatthew G. Knepley PetscCall(PetscDualSpaceEqual(dsOld, ds, &same_space)); 9806858538eSMatthew G. Knepley } 9816858538eSMatthew G. Knepley /* Make a fresh clone of the coordinate DM */ 9826858538eSMatthew G. Knepley PetscCall(DMClone(cdmOld, &cdmNew)); 9836858538eSMatthew G. Knepley PetscCall(DMSetField(cdmNew, 0, NULL, (PetscObject) disc)); 9846858538eSMatthew G. Knepley PetscCall(DMCreateDS(cdmNew)); 9856858538eSMatthew G. Knepley PetscCall(DMGetCoordinates(dm, &coordsOld)); 9866858538eSMatthew G. Knepley if (same_space) { 9876858538eSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)coordsOld)); 9886858538eSMatthew G. Knepley coordsNew = coordsOld; 9896858538eSMatthew G. Knepley } else { // Project the coordinate vector from old to new space 9906858538eSMatthew G. Knepley PetscCall(DMCreateGlobalVector(cdmNew, &coordsNew)); 9916858538eSMatthew G. Knepley PetscCall(DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL)); 9926858538eSMatthew G. Knepley PetscCall(MatInterpolate(matInterp, coordsOld, coordsNew)); 9936858538eSMatthew G. Knepley PetscCall(MatDestroy(&matInterp)); 9946858538eSMatthew G. Knepley } 9956858538eSMatthew G. Knepley /* Set new coordinate structures */ 9966858538eSMatthew G. Knepley PetscCall(DMSetCoordinateField(dm, NULL)); 9976858538eSMatthew G. Knepley PetscCall(DMSetCoordinateDM(dm, cdmNew)); 9986858538eSMatthew G. Knepley PetscCall(DMSetCoordinates(dm, coordsNew)); 9996858538eSMatthew G. Knepley PetscCall(VecDestroy(&coordsNew)); 10006858538eSMatthew G. Knepley PetscCall(DMDestroy(&cdmNew)); 10016858538eSMatthew G. Knepley PetscFunctionReturn(0); 10026858538eSMatthew G. Knepley } 10036858538eSMatthew G. Knepley 10046858538eSMatthew G. Knepley /*@ 10056858538eSMatthew G. Knepley DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 10066858538eSMatthew G. Knepley 10076858538eSMatthew G. Knepley Collective on v (see explanation below) 10086858538eSMatthew G. Knepley 10096858538eSMatthew G. Knepley Input Parameters: 10106858538eSMatthew G. Knepley + dm - The DM 10116858538eSMatthew G. Knepley - ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 10126858538eSMatthew G. Knepley 10136858538eSMatthew G. Knepley Input/Output Parameters: 10146858538eSMatthew G. Knepley + v - The Vec of points, on output contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 10156858538eSMatthew G. Knepley - cellSF - Points to either NULL, or a PetscSF with guesses for which cells contain each point; 10166858538eSMatthew G. Knepley on output, the PetscSF containing the ranks and local indices of the containing points 10176858538eSMatthew G. Knepley 10186858538eSMatthew G. Knepley Level: developer 10196858538eSMatthew G. Knepley 10206858538eSMatthew G. Knepley Notes: 10216858538eSMatthew G. Knepley To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 10226858538eSMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 10236858538eSMatthew G. Knepley 10246858538eSMatthew G. Knepley If *cellSF is NULL on input, a PetscSF will be created. 10256858538eSMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 10266858538eSMatthew G. Knepley 10276858538eSMatthew G. Knepley An array that maps each point to its containing cell can be obtained with 10286858538eSMatthew G. Knepley 10296858538eSMatthew G. Knepley $ const PetscSFNode *cells; 10306858538eSMatthew G. Knepley $ PetscInt nFound; 10316858538eSMatthew G. Knepley $ const PetscInt *found; 10326858538eSMatthew G. Knepley $ 10336858538eSMatthew G. Knepley $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 10346858538eSMatthew G. Knepley 10356858538eSMatthew 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 10366858538eSMatthew G. Knepley the index of the cell in its rank's local numbering. 10376858538eSMatthew G. Knepley 10386858538eSMatthew G. Knepley .seealso: `DMSetCoordinates()`, `DMSetCoordinatesLocal()`, `DMGetCoordinates()`, `DMGetCoordinatesLocal()`, `DMPointLocationType` 10396858538eSMatthew G. Knepley @*/ 10406858538eSMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 10416858538eSMatthew G. Knepley { 10426858538eSMatthew G. Knepley PetscFunctionBegin; 10436858538eSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10446858538eSMatthew G. Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 10456858538eSMatthew G. Knepley PetscValidPointer(cellSF,4); 10466858538eSMatthew G. Knepley if (*cellSF) { 10476858538eSMatthew G. Knepley PetscMPIInt result; 10486858538eSMatthew G. Knepley 10496858538eSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 10506858538eSMatthew G. Knepley PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result)); 10516858538eSMatthew 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"); 10526858538eSMatthew G. Knepley } else { 10536858538eSMatthew G. Knepley PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF)); 10546858538eSMatthew G. Knepley } 10556858538eSMatthew G. Knepley PetscCall(PetscLogEventBegin(DM_LocatePoints,dm,0,0,0)); 1056*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,locatepoints ,v,ltype,*cellSF); 10576858538eSMatthew G. Knepley PetscCall(PetscLogEventEnd(DM_LocatePoints,dm,0,0,0)); 10586858538eSMatthew G. Knepley PetscFunctionReturn(0); 10596858538eSMatthew G. Knepley } 1060