From 4f1ce645dc3ab0d3cc64077d9c4a0b3781066237 Mon Sep 17 00:00:00 2001 From: nefrathenrici Date: Wed, 13 Sep 2023 14:11:58 -0700 Subject: [PATCH] Remove hardcoded parameters, some fixes --- config/default_configs/default_config.yml | 3 + .../default_configs/default_edmf_config.yml | 9 --- config/model_configs/edmfx_bomex_box_v2.yml | 1 - examples/Manifest.toml | 4 +- perf/Manifest.toml | 4 +- .../radiation/held_suarez.jl | 22 +++--- src/parameters/Parameters.jl | 67 +++++++------------ src/parameters/create_parameters.jl | 11 ++- src/solver/model_getters.jl | 22 ++---- src/solver/type_getters.jl | 14 +--- test/parameter_tests.jl | 22 +++++- toml/edmfx_bomex_box_v2.toml | 4 ++ 12 files changed, 81 insertions(+), 102 deletions(-) diff --git a/config/default_configs/default_config.yml b/config/default_configs/default_config.yml index 1e470bca73..46ed8faadf 100644 --- a/config/default_configs/default_config.yml +++ b/config/default_configs/default_config.yml @@ -246,3 +246,6 @@ prognostic_surface: override_τ_precip: help: "If true, sets τ_precip to dt. Otherwise, τ_precip is set to the value in the toml dictionary" value: true +log_params: + help: "Log parameters to file [`false` (default), `true`]" + value: false diff --git a/config/default_configs/default_edmf_config.yml b/config/default_configs/default_edmf_config.yml index 3a28253697..5699d6bb7b 100644 --- a/config/default_configs/default_edmf_config.yml +++ b/config/default_configs/default_edmf_config.yml @@ -32,15 +32,6 @@ edmfx_upwinding: debugging_tc: help: "Save most of the tc aux state to HDF5 file [`false` (default), `true`]" value: false -entr_coeff: - help: "Entrainment coefficient" - value: 1.0 -entr_tau: - help: "Entrainment timescale" - value: 900.0 -detr_coeff: - help: "Detrainment coefficient" - value: 0.001 edmfx_sgs_flux: help: "If set to true, it switches on EDMFX SGS flux. [`true`, `false` (default)]" value: false \ No newline at end of file diff --git a/config/model_configs/edmfx_bomex_box_v2.yml b/config/model_configs/edmfx_bomex_box_v2.yml index b812875c63..00f58c23fc 100644 --- a/config/model_configs/edmfx_bomex_box_v2.yml +++ b/config/model_configs/edmfx_bomex_box_v2.yml @@ -16,7 +16,6 @@ turbconv: "edmfx" z_stretch: false vert_diff: "true" x_elem: 2 -detr_coeff: 0.01 config: "box" subsidence: "Bomex" kappa_4: 1.0e12 diff --git a/examples/Manifest.toml b/examples/Manifest.toml index 1b1adda72c..655269fc70 100644 --- a/examples/Manifest.toml +++ b/examples/Manifest.toml @@ -200,9 +200,9 @@ version = "0.1.2" [[deps.CLIMAParameters]] deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "d35d039179f27abc063f7ae5c564573fe5316bb2" +git-tree-sha1 = "9872c4383d3c212096b2750bf1c2237a4670a3af" uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.7.19" +version = "0.7.20" [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] diff --git a/perf/Manifest.toml b/perf/Manifest.toml index 71a12b8e03..cc5902a322 100644 --- a/perf/Manifest.toml +++ b/perf/Manifest.toml @@ -211,9 +211,9 @@ version = "0.1.2" [[deps.CLIMAParameters]] deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "d35d039179f27abc063f7ae5c564573fe5316bb2" +git-tree-sha1 = "9872c4383d3c212096b2750bf1c2237a4670a3af" uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.7.19" +version = "0.7.20" [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] diff --git a/src/parameterized_tendencies/radiation/held_suarez.jl b/src/parameterized_tendencies/radiation/held_suarez.jl index 1d743817ea..0521c59387 100644 --- a/src/parameterized_tendencies/radiation/held_suarez.jl +++ b/src/parameterized_tendencies/radiation/held_suarez.jl @@ -39,26 +39,24 @@ function forcing_tendency!(Yₜ, Y, p, t, colidx, ::HeldSuarezForcing) MSLP = FT(CAP.MSLP(params)) p_ref_theta = FT(CAP.p_ref_theta(params)) grav = FT(CAP.grav(params)) - ΔT_y_dry = FT(CAP.ΔT_y_dry(params)) - ΔT_y_wet = FT(CAP.ΔT_y_wet(params)) + Δθ_z = FT(CAP.Δθ_z(params)) + T_min = FT(CAP.T_min_hs(params)) thermo_params = CAP.thermodynamics_params(params) + σ_b = CAP.σ_b(params) + k_a = 1 / (40 * day) + k_s = 1 / (4 * day) + k_f = 1 / day z_surface = Fields.level(Fields.coordinate_field(Y.f).z[colidx], Fields.half) - σ_b = FT(7 / 10) - k_a = 1 / (40 * day) - k_s = 1 / (4 * day) - k_f = 1 / day if :ρq_tot in propertynames(Y.c) - ΔT_y = ΔT_y_wet - T_equator = FT(294) + ΔT_y = FT(CAP.ΔT_y_wet(params)) + T_equator = FT(CAP.T_equator_wet(params)) else - ΔT_y = ΔT_y_dry - T_equator = FT(315) + ΔT_y = FT(CAP.ΔT_y_dry(params)) + T_equator = FT(CAP.T_equator_dry(params)) end - Δθ_z = FT(10) - T_min = FT(200) @. ᶜσ[colidx] = ᶜp[colidx] / ( diff --git a/src/parameters/Parameters.jl b/src/parameters/Parameters.jl index 7de851c410..6f3ca5561f 100644 --- a/src/parameters/Parameters.jl +++ b/src/parameters/Parameters.jl @@ -10,34 +10,30 @@ const ACAP = AbstractClimaAtmosParameters Base.broadcastable(param_set::ACAP) = tuple(param_set) -Base.@kwdef struct ClimaAtmosParameters{FT, TP, RP, IP, MPP, SFP, TCP, SP} <: - ACAP - Omega::FT - f_plane_coriolis_frequency::FT - planet_radius::FT - astro_unit::FT +Base.@kwdef struct ClimaAtmosParameters{FT, TP, RP, IP, MPP, SFP, TCP} <: ACAP thermodynamics_params::TP rrtmgp_params::RP insolation_params::IP microphysics_params::MPP - surfacefluxes_params::SFP + surface_fluxes_params::SFP turbconv_params::TCP - sponge_params::SP + Omega::FT + f_plane_coriolis_frequency::FT + planet_radius::FT + astro_unit::FT entr_tau::FT entr_coeff::FT detr_coeff::FT - # TODO: Figure out a better place for these held-suarez parameters + C_E::FT + # Held Suarez ΔT_y_dry::FT ΔT_y_wet::FT - C_E::FT -end - -""" - SpongeParameters{FT} - -Parameters for both the viscous and rayleigh sponge. -""" -Base.@kwdef struct SpongeParameters{FT} + σ_b::FT + T_equator_dry::FT + T_equator_wet::FT + T_min_hs::FT + Δθ_z::FT + # Sponge alpha_rayleigh_w::FT alpha_rayleigh_uh::FT zd_viscous::FT @@ -47,36 +43,14 @@ end Base.eltype(::ClimaAtmosParameters{FT}) where {FT} = FT -rrtmgp_params(ps::ACAP) = ps.rrtmgp_params -thermodynamics_params(ps::ACAP) = ps.thermodynamics_params -surface_fluxes_params(ps::ACAP) = ps.surfacefluxes_params -microphysics_params(ps::ACAP) = ps.microphysics_params -insolation_params(ps::ACAP) = ps.insolation_params -turbconv_params(ps::ACAP) = ps.turbconv_params - # Forward Thermodynamics parameters for var in fieldnames(TD.Parameters.ThermodynamicsParameters) @eval $var(ps::ACAP) = TD.Parameters.$var(thermodynamics_params(ps)) end - # Thermodynamics derived parameters -molmass_ratio(ps::ACAP) = TD.Parameters.molmass_ratio(thermodynamics_params(ps)) -R_d(ps::ACAP) = TD.Parameters.R_d(thermodynamics_params(ps)) -R_v(ps::ACAP) = TD.Parameters.R_v(thermodynamics_params(ps)) -cp_d(ps::ACAP) = TD.Parameters.cp_d(thermodynamics_params(ps)) -cv_v(ps::ACAP) = TD.Parameters.cv_v(thermodynamics_params(ps)) -cv_l(ps::ACAP) = TD.Parameters.cv_l(thermodynamics_params(ps)) -cv_d(ps::ACAP) = TD.Parameters.cv_d(thermodynamics_params(ps)) - -Omega(ps::ACAP) = ps.Omega -f_plane_coriolis_frequency(ps::ACAP) = ps.f_plane_coriolis_frequency -planet_radius(ps::ACAP) = ps.planet_radius -astro_unit(ps::ACAP) = ps.astro_unit -entr_coeff(ps::ACAP) = ps.entr_coeff -entr_tau(ps::ACAP) = ps.entr_tau -detr_coeff(ps::ACAP) = ps.detr_coeff -ΔT_y_dry(ps::ACAP) = ps.ΔT_y_dry -ΔT_y_wet(ps::ACAP) = ps.ΔT_y_wet +for var in [:molmass_ratio, :R_d, :R_v, :cp_d, :cv_v, :cv_l, :cv_d] + @eval $var(ps::ACAP) = TD.Parameters.$var(thermodynamics_params(ps)) +end # Forwarding CloudMicrophysics parameters ρ_cloud_liq(ps::ACAP) = CM.Parameters.ρ_cloud_liq(microphysics_params(ps)) @@ -85,4 +59,11 @@ detr_coeff(ps::ACAP) = ps.detr_coeff day(ps::ACAP) = IP.day(insolation_params(ps)) tot_solar_irrad(ps::ACAP) = IP.tot_solar_irrad(insolation_params(ps)) +# Define parameters as functions +# Place derived parameters in exceptions vector +exceptions = [] +for var in filter(x -> !(x in exceptions), fieldnames(ClimaAtmosParameters)) + @eval $var(ps::ACAP) = ps.$var +end + end diff --git a/src/parameters/create_parameters.jl b/src/parameters/create_parameters.jl index 5350ec4a54..5075195ab4 100644 --- a/src/parameters/create_parameters.jl +++ b/src/parameters/create_parameters.jl @@ -41,7 +41,6 @@ function create_parameter_set(config::AtmosConfig) create_parameter_struct(CM.Parameters.ModalNucleationParameters) rrtmgp_params = create_parameter_struct(RP.RRTMGPParameters) insolation_params = create_parameter_struct(IP.InsolationParameters) - sponge_params = create_parameter_struct(CAP.SpongeParameters) microphys_params = create_parameter_struct( CM.Parameters.CloudMicrophysicsParameters; subparam_structs = (; thermo_params, modal_nucleation_params), @@ -80,13 +79,13 @@ function create_parameter_set(config::AtmosConfig) rrtmgp_params, insolation_params, microphysics_params = microphys_params, - surfacefluxes_params = surf_flux_params, + surface_fluxes_params = surf_flux_params, turbconv_params, - sponge_params, ), ) - # TODO: Add parameter logging option from config - # logfilepath = joinpath(@__DIR__, "logfilepath_$FT.toml") - # CP.log_parameter_information(toml_dict, logfilepath) + if parsed_args["log_params"] + logfilepath = joinpath(@__DIR__, "$(parsed_args["job_id"])_$FT.toml") + CP.log_parameter_information(toml_dict, logfilepath) + end return param_set end diff --git a/src/solver/model_getters.jl b/src/solver/model_getters.jl index 8ee091980d..c1457da235 100644 --- a/src/solver/model_getters.jl +++ b/src/solver/model_getters.jl @@ -76,35 +76,27 @@ function get_surface_model(parsed_args) end end -function get_viscous_sponge_model( - parsed_args, - sponge_params, - ::Type{FT}, -) where {FT} +function get_viscous_sponge_model(parsed_args, params, ::Type{FT}) where {FT} vs_name = parsed_args["viscous_sponge"] return if vs_name in ("false", false, "none") nothing elseif vs_name in ("true", true, "ViscousSponge") - zd = sponge_params.zd_viscous - κ₂ = sponge_params.kappa_2_sponge + zd = params.zd_viscous + κ₂ = params.kappa_2_sponge ViscousSponge{FT}(; zd, κ₂) else error("Uncaught viscous sponge model `$vs_name`.") end end -function get_rayleigh_sponge_model( - parsed_args, - sponge_params, - ::Type{FT}, -) where {FT} +function get_rayleigh_sponge_model(parsed_args, params, ::Type{FT}) where {FT} rs_name = parsed_args["rayleigh_sponge"] return if rs_name in ("false", false) nothing elseif rs_name in ("true", true, "RayleighSponge") - zd = sponge_params.zd_rayleigh - α_uₕ = sponge_params.alpha_rayleigh_uh - α_w = sponge_params.alpha_rayleigh_w + zd = params.zd_rayleigh + α_uₕ = params.alpha_rayleigh_uh + α_w = params.alpha_rayleigh_w RayleighSponge{FT}(; zd, α_uₕ, α_w) else error("Uncaught rayleigh sponge model `$rs_name`.") diff --git a/src/solver/type_getters.jl b/src/solver/type_getters.jl index 2c93cf5f5a..61dcbb9c8e 100644 --- a/src/solver/type_getters.jl +++ b/src/solver/type_getters.jl @@ -13,7 +13,7 @@ import ClimaTimeSteppers as CTS import DiffEqCallbacks as DECB function get_atmos(config::AtmosConfig, params) - (; turbconv_params, sponge_params) = params + (; turbconv_params) = params (; parsed_args) = config FT = eltype(config) moisture_model = get_moisture_model(parsed_args) @@ -71,16 +71,8 @@ function get_atmos(config::AtmosConfig, params) ), hyperdiff = get_hyperdiffusion_model(parsed_args, FT), vert_diff, - viscous_sponge = get_viscous_sponge_model( - parsed_args, - sponge_params, - FT, - ), - rayleigh_sponge = get_rayleigh_sponge_model( - parsed_args, - sponge_params, - FT, - ), + viscous_sponge = get_viscous_sponge_model(parsed_args, params, FT), + rayleigh_sponge = get_rayleigh_sponge_model(parsed_args, params, FT), sfc_temperature = get_sfc_temperature_form(parsed_args), surface_model = get_surface_model(parsed_args), ) diff --git a/test/parameter_tests.jl b/test/parameter_tests.jl index 2cdb5e1aa5..1c0f1ef06c 100644 --- a/test/parameter_tests.jl +++ b/test/parameter_tests.jl @@ -16,7 +16,7 @@ default_args = CA.cli_defaults(CA.argparse_settings()) "dt_save_to_disk" => "str", "bubble" => true, ) - parsed_args = CA.AtmosConfig(; config_dict = config_dict).parsed_args + parsed_args = CA.AtmosConfig(; config_dict).parsed_args @test parsed_args["krylov_rtol"] isa FT @test parsed_args["newton_rtol"] isa FT @test parsed_args["max_newton_iters_ode"] isa Int @@ -24,3 +24,23 @@ default_args = CA.cli_defaults(CA.argparse_settings()) @test parsed_args["dt_save_to_disk"] isa String @test parsed_args["bubble"] isa Bool end + +@testset "Test unique aliases" begin + config_dict = Dict("toml" => ["parameter_tests.toml"]) + config = CA.AtmosConfig(; config_dict) + @test_throws ErrorException CP.get_parameter_values!( + config.toml_dict, + ["same_alias"], + ) +end + +@testset "Test all parameter tomls in toml/" begin + toml_path = joinpath("..", "toml") + for toml in readdir(toml_path) + config_dict = Dict("toml" => [joinpath(toml_path, toml)]) + config = CA.AtmosConfig(; config_dict) + # Ensure that there are no errors + @test CA.create_parameter_set(config) isa + CA.Parameters.ClimaAtmosParameters + end +end diff --git a/toml/edmfx_bomex_box_v2.toml b/toml/edmfx_bomex_box_v2.toml index 3da20f5a66..f44f9e2471 100644 --- a/toml/edmfx_bomex_box_v2.toml +++ b/toml/edmfx_bomex_box_v2.toml @@ -3,3 +3,7 @@ alias = "C_E" value = 0.044 type = "float" +[detr_coeff] +alias = "detr_coeff" +value = 0.01 +type = "float"