Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add high resolution clm data artifact #1007

Merged
merged 1 commit into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions Artifacts.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ git-tree-sha1 = "136f1db3ed969614fb589c5250545a3ed1e8aaab"
sha256 = "777371543cc3285c0779e7ecd925fe782b5b45e0ed27f82260827ac8ebe6a700"
url = "https://caltech.box.com/shared/static/of1admpndmikoumtgk5j3yvt92v71awk.gz"

[clm_data]
git-tree-sha1 = "3f6873a3e67722bda1fd23f7d5a05f5e2df1fe8c"

[[clm_data.download]]
sha256 = "830136abec15551a343b7884d657fb6a79b16a37237681a2becf65bd845aa692"
url = "https://caltech.box.com/shared/static/6pu2f6c99g29qawvjjh3j56drkonpd3z.gz"

["clm_data_0.9x1.25"]
git-tree-sha1 = "283c62220fca8c4afe36a62348d3e9a159af2ee9"

[["clm_data_0.9x1.25".download]]
sha256 = "88d5899a729de800017a74bd8a7278582c2c55c0d8730a529bae384425d70e4e"
url = "https://caltech.box.com/shared/static/mxs3l1c1dppjwy81assk8w8ofn9d70pu.gz"
["clm_data_0.125x0.125"]
git-tree-sha1 = "6284ddefbc7937d9c1fb68fa731ff3f00b68e917"

[["clm_data_0.125x0.125".download]]
sha256 = "8d2a61baad53346515f4a66c4342f8aafce37ca9520020c17f99cc4f4aa98b15"
url = "https://caltech.box.com/shared/static/uteaw1l6fg7wmwhb3ey1c0jq4r8vg0ts.gz"
[era5_land_forcing_data2008]
git-tree-sha1 = "93d2e93f491e77cb8fba2a1b8b3946f38bde469e"
[era5_land_forcing_data2008_lowres]
Expand Down
13 changes: 9 additions & 4 deletions src/Artifacts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,17 @@ function modis_lai_forcing_data2008_path(; context = nothing)
end

"""
clm_data__folder_path(; context)
clm_data__folder_path(; context, lowres = false)

Return the path to the folder that contains the clm data.
Return the path to the folder that contains the clm data. If the lowres flag is set to true,
the 0.9x1.25 version of the data is returned. Otherwise, the 0.125x0.125 version is returned.
"""
function clm_data_folder_path(; context = nothing)
return @clima_artifact("clm_data", context)
function clm_data_folder_path(; context = nothing, lowres = false)
if lowres
return @clima_artifact("clm_data_0.9x1.25", context)
else
return @clima_artifact("clm_data_0.125x0.125", context)
end
end

"""
Expand Down
49 changes: 45 additions & 4 deletions src/simulations/spatial_parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,38 @@ function mean(x::AbstractArray{T}) where {T}
sum(x) / length(x)
end

"""
use_lowres_clm(space)

Returns true if the space is closer in resolution to 0.9x1.25 degree lat/long than 0.125x0.125 degree lat/long.
This is used to determine which resolution of CLM data to use.
"""
function use_lowres_clm(
surface_space::ClimaCore.Spaces.AbstractSpectralElementSpace,
)
node_scale = ClimaCore.Spaces.node_horizontal_length_scale(surface_space)
surface_mesh = ClimaCore.Spaces.topology(surface_space).mesh
if surface_mesh isa ClimaCore.Meshes.AbstractCubedSphere
# in this case, node_scale is in meters
sphere_radius = surface_mesh.domain.radius
horizontal_length_scale(lat_res, long_res) = sqrt(
4 * pi * sphere_radius^2 / ((360 / long_res) * (180 / lat_res)),
)
highres_scale = horizontal_length_scale(0.125, 0.125)
lowres_scale = horizontal_length_scale(0.9, 1.25)
elseif surface_mesh isa ClimaCore.Meshes.RectilinearMesh
# in this case, node_scale is in degrees
highres_scale = 0.125
lowres_scale = sqrt(1.25 * 0.9)
else
return false
end
return abs(lowres_scale - node_scale) < abs(highres_scale - node_scale)
end

# This method will likely never be called, but is included for completeness
use_lowres_clm(surface_space::ClimaCore.Spaces.AbstractSpace) = false

"""
clm_canopy_parameters(
surface_space;
Expand All @@ -17,6 +49,7 @@ end
Interpolations.Flat(),
Interpolations.Flat(),
),
lowres=use_lowres_clm(surface_space),
)

Reads spatially varying parameters for the canopy, from NetCDF files
Expand All @@ -38,7 +71,9 @@ The NetCDF files are stored in ClimaArtifacts and more detail on their origin
is provided there. The keyword arguments `regridder_type` and `extrapolation_bc`
affect the regridding by (1) changing how we interpolate to ClimaCore points which
are not in the data, and (2) changing how extrapolate to points beyond the range of the
data.
data. The keyword argument lowres is a flag that determines if the 0.9x1.25 or 0.125x0.125
resolution CLM data artifact is used. If the lowres flag is not provided, the clm artifact
with the closest resolution to the surface_space is used.
"""
function clm_canopy_parameters(
surface_space;
Expand All @@ -48,9 +83,11 @@ function clm_canopy_parameters(
Interpolations.Flat(),
Interpolations.Flat(),
),
lowres = use_lowres_clm(surface_space),
)
context = ClimaComms.context(surface_space)
clm_artifact_path = ClimaLand.Artifacts.clm_data_folder_path(; context)
clm_artifact_path =
ClimaLand.Artifacts.clm_data_folder_path(; context, lowres)
# Foliage clumping index data derived from MODIS
modis_ci_artifact_path =
ClimaLand.Artifacts.modis_ci_data_folder_path(; context)
Expand Down Expand Up @@ -161,6 +198,7 @@ end
Interpolations.Flat(),
Interpolations.Flat(),
),
lowres=use_lowres_clm(surface_space),
)

Reads spatially varying parameters for the soil model, from NetCDF files
Expand All @@ -184,7 +222,9 @@ The NetCDF files are stored in ClimaArtifacts and more detail on their origin
is provided there. The keyword arguments `regridder_type` and `extrapolation_bc`
affect the regridding by (1) changing how we interpolate to ClimaCore points which
are not in the data, and (2) changing how extrapolate to points beyond the range of the
data.
data. The keyword argument lowres is a flag that determines if the 0.9x1.25 or 0.125x0.125
resolution CLM data artifact is used. If the lowres flag is not provided, the clm artifact
with the closest resolution to the surface_space is used.
"""
function default_spatially_varying_soil_parameters(
subsurface_space,
Expand All @@ -196,6 +236,7 @@ function default_spatially_varying_soil_parameters(
Interpolations.Flat(),
Interpolations.Flat(),
),
lowres = use_lowres_clm(surface_space),
)
context = ClimaComms.context(surface_space)
soil_params_artifact_path =
Expand Down Expand Up @@ -350,7 +391,7 @@ function default_spatially_varying_soil_parameters(
PAR_albedo_dry, NIR_albedo_dry, PAR_albedo_wet, NIR_albedo_wet = map(
s -> SpaceVaryingInput(
joinpath(
ClimaLand.Artifacts.clm_data_folder_path(),
ClimaLand.Artifacts.clm_data_folder_path(; context, lowres),
"soil_properties_map.nc",
),
s,
Expand Down
29 changes: 29 additions & 0 deletions test/simulations/spatial_parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,32 @@ end

@test :G_Function ∈ propertynames(clm_parameters)
@test axes(getproperty(clm_parameters, :G_Function).χl) == surface_space
# test `use_lowres_clm` on the sphere domain, and then again with a sphere domain with 2x
# the horizontal resolution. Then repeat with plane domains.
@test ClimaLand.use_lowres_clm(surface_space)
domain = ClimaLand.Domains.SphericalShell(;
radius = radius,
depth = depth,
nelements = (202, 2),
npolynomial = 1,
)
surface_space = domain.space.surface
@test !ClimaLand.use_lowres_clm(surface_space)
domain = ClimaLand.Domains.Plane(;
longlat = (-117.0, 34.0),
xlim = (0.0, FT(2e6)),
ylim = (0.0, 2FT(2e6)),
nelements = (10, 10),
npolynomial = 1,
)
surface_space = domain.space.surface
@test ClimaLand.use_lowres_clm(surface_space)
domain = ClimaLand.Domains.Plane(;
longlat = (-117.0, 34.0),
xlim = (0.0, FT(2e5)),
ylim = (0.0, 2FT(2e5)),
nelements = (10, 10),
npolynomial = 1,
)
surface_space = domain.space.surface
@test !ClimaLand.use_lowres_clm(surface_space)
Loading