From d66b14a5699749576d7d5251ca9424c856e3ccb6 Mon Sep 17 00:00:00 2001 From: "Katherine M. Deck" Date: Tue, 3 Dec 2024 15:24:53 -0800 Subject: [PATCH] use soil grids parameters --- Artifacts.toml | 9 ++++ src/Artifacts.jl | 20 +++++++ src/simulations/spatial_parameters.jl | 77 +++++++++++++++++---------- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/Artifacts.toml b/Artifacts.toml index 9d421d220e..bd28fdb3d5 100644 --- a/Artifacts.toml +++ b/Artifacts.toml @@ -1,3 +1,12 @@ +[soilgrids] +git-tree-sha1 = "f919da748cc973519fb136f4225cf343f5c3e41f" +[soilgrids_lowres] +git-tree-sha1 = "6ce1717bb8b7aa767380f1053b9d8d3a4e4edaa6" + + [[soilgrids_lowres.download]] + sha256 = "27d49fce7f4a5e2b81bbd29e8a7caf08f568a2df53e3af817126363decfd5a7c" + url = "https://caltech.box.com/shared/static/99aw2gce2k65bdu0h8jkfxq4vin08gi2.gz" + [cesm2_albedo] git-tree-sha1 = "316096635acaa8102477820f480ca02fe66eb828" diff --git a/src/Artifacts.jl b/src/Artifacts.jl index 0e951bc7b8..fd8abe052f 100644 --- a/src/Artifacts.jl +++ b/src/Artifacts.jl @@ -59,6 +59,26 @@ function soil_params_artifact_folder_path(; context = nothing) return @clima_artifact("soil_params_Gupta2020_2022", context) end +""" + soil_grids_params_artifact_path(; lowres = true, context) + +Return the path to the file that contains the soil texture parameters +needed for the Balland and Arp (2005) thermal conductivity model. + +Returns a ~1 degree version by default (lowres = true). +""" +function soil_grids_params_artifact_path(; context = nothing, lowres = true) + if lowres + dir = @clima_artifact("soilgrids_lowres", context) + file = "soil_solid_vol_fractions_soilgrids_lowres.nc" + return joinpath(dir, file) + else + dir = @clima_artifact("soilgrids", context) + file = "soil_solid_vol_fractions_soilgrids.nc" + return joinpath(dir, file) + end +end + """ experiment_fluxnet_data_path( site_ID; diff --git a/src/simulations/spatial_parameters.jl b/src/simulations/spatial_parameters.jl index 20c7416c14..1e7dd036eb 100644 --- a/src/simulations/spatial_parameters.jl +++ b/src/simulations/spatial_parameters.jl @@ -211,7 +211,8 @@ function default_spatially_varying_soil_parameters( regridder_kwargs = (; extrapolation_bc,), file_reader_kwargs = (; preprocess_func = (data) -> data > 0,), ) - oceans_to_value(field, mask, value) = + # If the mask = 0, set to value + masked_to_value(field, mask, value) = mask == 1.0 ? field : eltype(field)(value) vg_α = SpaceVaryingInput( @@ -236,11 +237,11 @@ function default_spatially_varying_soil_parameters( ) x = parent(vg_α) μ = mean(log10.(x[x .> 0])) - vg_α .= oceans_to_value.(vg_α, soil_params_mask, 10.0^μ) + vg_α .= masked_to_value.(vg_α, soil_params_mask, 10.0^μ) x = parent(vg_n) μ = mean(x[x .> 0]) - vg_n .= oceans_to_value.(vg_n, soil_params_mask, μ) + vg_n .= masked_to_value.(vg_n, soil_params_mask, μ) vg_fields_to_hcm_field(α::FT, n::FT) where {FT} = ClimaLand.Soil.vanGenuchten{FT}(; @NamedTuple{α::FT, n::FT}((α, n))...) @@ -280,39 +281,59 @@ function default_spatially_varying_soil_parameters( x = parent(K_sat) μ = mean(log10.(x[x .> 0])) - K_sat .= oceans_to_value.(K_sat, soil_params_mask, 10.0^μ) + K_sat .= masked_to_value.(K_sat, soil_params_mask, 10.0^μ) - ν .= oceans_to_value.(ν, soil_params_mask, 1) + ν .= masked_to_value.(ν, soil_params_mask, 1) - θ_r .= oceans_to_value.(θ_r, soil_params_mask, 0) + θ_r .= masked_to_value.(θ_r, soil_params_mask, 0) S_s = - oceans_to_value.( + masked_to_value.( ClimaCore.Fields.zeros(subsurface_space) .+ FT(1e-3), soil_params_mask, 1, ) - ν_ss_om = - oceans_to_value.( - ClimaCore.Fields.zeros(subsurface_space) .+ FT(0.1), - soil_params_mask, - 0, - ) - ν_ss_quartz = - oceans_to_value.( - ClimaCore.Fields.zeros(subsurface_space) .+ FT(0.1), - soil_params_mask, - 0, - ) - ν_ss_gravel = - oceans_to_value.( - ClimaCore.Fields.zeros(subsurface_space) .+ FT(0.1), - soil_params_mask, - 0, + + soilgrids_artifact_path = + ClimaLand.Artifacts.soil_grids_params_artifact_path(; + lowres = true, + context, ) - PAR_albedo = ClimaCore.Fields.zeros(surface_space) .+ FT(0.2) - NIR_albedo = ClimaCore.Fields.zeros(surface_space) .+ FT(0.2) + ν_ss_om = SpaceVaryingInput( + soilgrids_artifact_path, + "nu_ss_om", + subsurface_space; + regridder_type, + regridder_kwargs = (; extrapolation_bc,), + ) + + ν_ss_quartz = SpaceVaryingInput( + soilgrids_artifact_path, + "nu_ss_sand", + subsurface_space; + regridder_type, + regridder_kwargs = (; extrapolation_bc,), + ) + + ν_ss_gravel = SpaceVaryingInput( + soilgrids_artifact_path, + "nu_ss_cf", + subsurface_space; + regridder_type, + regridder_kwargs = (; extrapolation_bc,), + ) + # we require that the sum of these be less than 1 and equal to or bigger than zero. + # The input should satisfy this almost exactly, but the regridded values may not. + function texture_sum_norm(ν_ss_gravel, ν_ss_quartz, ν_ss_om) + texture_sum = ν_ss_gravel + ν_ss_quartz + ν_ss_om + texture_norm = texture_sum <= 1 ? 1 : texture_sum + end + texture_norm = texture_sum_norm.(ν_ss_gravel, ν_ss_quartz, ν_ss_om) + @. ν_ss_gravel = ν_ss_gravel / texture_norm + @. ν_ss_om = ν_ss_om / texture_norm + @. ν_ss_quartz = ν_ss_quartz / texture_norm + soil_params_mask_sfc = ClimaLand.Domains.top_center_to_surface(soil_params_mask) @@ -328,8 +349,8 @@ function default_spatially_varying_soil_parameters( regridder_type, ) # Unsure how to handle two masks - f_max = oceans_to_value.(f_max, mask, FT(0.0)) - f_max = oceans_to_value.(f_max, soil_params_mask_sfc, FT(0.0)) + f_max = masked_to_value.(f_max, mask, FT(0.0)) + f_max = masked_to_value.(f_max, soil_params_mask_sfc, FT(0.0)) PAR_albedo_dry, NIR_albedo_dry, PAR_albedo_wet, NIR_albedo_wet = map( s -> SpaceVaryingInput( joinpath(