From fbfedb7e90ffac860ec931462b5d1297f32427e2 Mon Sep 17 00:00:00 2001 From: sriharshakandala Date: Thu, 12 Dec 2024 15:41:29 -0800 Subject: [PATCH] Add `DYAMONDSummer` low resolution simulation. --- Artifacts.toml | 8 ++ config/default_configs/default_config.yml | 2 +- .../gpu_aquaplanet_dyamond_summer.yml | 30 +++++++ src/initial_conditions/InitialConditions.jl | 5 ++ src/initial_conditions/initial_conditions.jl | 82 +++++++++++++++++++ src/solver/type_getters.jl | 11 ++- src/utils/AtmosArtifacts.jl | 8 ++ 7 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 config/gpu_configs/gpu_aquaplanet_dyamond_summer.yml diff --git a/Artifacts.toml b/Artifacts.toml index 70062a55cab..1bbe36cfbc9 100644 --- a/Artifacts.toml +++ b/Artifacts.toml @@ -43,3 +43,11 @@ git-tree-sha1 = "10742e0a2e343d13bb04df379e300a83402d4106" [[era5_cloud.download]] sha256 = "bb51e2f2d315b487e05a8d38944d4ad937ee4a40c43b68541220c5d54425e24a" url = "https://caltech.box.com/shared/static/b6ur4ap4vo04j09vdulem96z9fxqlgyn.gz" + +[DYAMOND_SUMMER_ICS_p98deg] +git-tree-sha1 = "46aa28a9177dd7e4cbb813eeba3e02597c3ba071" +lazy = true + + [[DYAMOND_SUMMER_ICS_p98deg.download]] + sha256 = "9a5efd20d68d9b954af2fd7803bccdda3fc7ef4ff60421ed13d18f768312d2e3" + url = "https://caltech.box.com/shared/static/whn01xr83v0s4p8tc59ds3nvfsfe6ebs.gz" diff --git a/config/default_configs/default_config.yml b/config/default_configs/default_config.yml index 8a59cda1fba..6a13f72ddb8 100644 --- a/config/default_configs/default_config.yml +++ b/config/default_configs/default_config.yml @@ -182,7 +182,7 @@ surface_temperature: help: "Prescribed surface temperature functional form ['ZonallySymmetric' (default), 'ZonallyAsymmetric', 'RCEMIPII']" value: "ZonallySymmetric" initial_condition: - help: "Initial condition [`DryBaroclinicWave`, `MoistBaroclinicWave`, `DecayingProfile`, `IsothermalProfile`, `Bomex`, `DryDensityCurrentProfile`, `AgnesiHProfile`, `ScharProfile`, `RisingThermalBubbleProfile`, `ISDAC`]" + help: "Initial condition [`DryBaroclinicWave`, `MoistBaroclinicWave`, `DecayingProfile`, `IsothermalProfile`, `Bomex`, `DryDensityCurrentProfile`, `AgnesiHProfile`, `ScharProfile`, `RisingThermalBubbleProfile`, `ISDAC`, `DYAMONDSummer`]" value: "DecayingProfile" perturb_initstate: help: "Add a perturbation to the initial condition [`false`, `true` (default)]" diff --git a/config/gpu_configs/gpu_aquaplanet_dyamond_summer.yml b/config/gpu_configs/gpu_aquaplanet_dyamond_summer.yml new file mode 100644 index 00000000000..5c5c94fe166 --- /dev/null +++ b/config/gpu_configs/gpu_aquaplanet_dyamond_summer.yml @@ -0,0 +1,30 @@ +dt_save_state_to_disk: "Inf" +dt_save_to_sol: "Inf" +output_default_diagnostics: false +h_elem: 16 +z_max: 60000.0 +z_elem: 63 +dz_bottom: 30.0 +rayleigh_sponge: true +viscous_sponge: true +moist: "equil" +precip_model: "1M" +rad: "allskywithclear" +insolation: "timevarying" +dt_rad: "1hours" +dt_cloud_fraction: "1hours" +vert_diff: "FriersonDiffusion" +implicit_diffusion: true +approximate_linear_solve_iters: 2 +surface_setup: "DefaultMoninObukhov" +dt: "30secs" +t_end: "120secs" +toml: [toml/longrun_aquaplanet.toml] +prescribe_ozone: true +aerosol_radiation: true +prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT01"] +initial_condition: "DYAMONDSummer" +topography: "Earth" +diagnostics: + - short_name: [ts, ta, thetaa, ha, pfull, rhoa, ua, va, wa, hur, hus, cl, clw, cli, hussfc, evspsbl, pr] + period: "30secs" diff --git a/src/initial_conditions/InitialConditions.jl b/src/initial_conditions/InitialConditions.jl index 73e0e581518..8cc446a6e22 100644 --- a/src/initial_conditions/InitialConditions.jl +++ b/src/initial_conditions/InitialConditions.jl @@ -1,5 +1,6 @@ module InitialConditions +import ..AtmosArtifacts as AA import ..AtmosModel import ..DryModel import ..EquilMoistModel @@ -9,8 +10,11 @@ import ..Microphysics0Moment import ..Microphysics1Moment import ..PrescribedSurfaceTemperature import ..PrognosticSurfaceTemperature +import ..ᶜinterp +import ..ᶠinterp import ..C3 import ..C12 +import ..compute_kinetic! import ..PrognosticEDMFX import ..DiagnosticEDMFX import ..n_mass_flux_subdomains @@ -30,6 +34,7 @@ import SciMLBase import Interpolations as Intp import NCDatasets as NC import Statistics: mean +import ClimaUtilities.SpaceVaryingInputs include("local_state.jl") include("atmos_state.jl") diff --git a/src/initial_conditions/initial_conditions.jl b/src/initial_conditions/initial_conditions.jl index c3f9edef999..39919acbffd 100644 --- a/src/initial_conditions/initial_conditions.jl +++ b/src/initial_conditions/initial_conditions.jl @@ -160,6 +160,31 @@ function (initial_condition::DecayingProfile)(params) return local_state end +""" + DYAMONDSummer(; perturb = true) + +An `InitialCondition` with a decaying temperature profile, and with an optional +perturbation to the temperature. +""" +struct DYAMONDSummer <: InitialCondition end + +function (initial_condition::DYAMONDSummer)(params) + function local_state(local_geometry) + FT = eltype(params) + grav = CAP.grav(params) + thermo_params = CAP.thermodynamics_params(params) + + T, p = FT(300), FT(100000) # placeholder values + + return LocalState(; + params, + geometry = local_geometry, + thermo_state = TD.PhaseDry_pT(thermo_params, p, T), + ) + end + return local_state +end + """ AgnesiHProfile(; perturb = false) @@ -351,6 +376,63 @@ function (initial_condition::RisingThermalBubbleProfile)(params) return local_state end +overwrite_initial_conditions!( + initial_condition::InitialCondition, + Y, + thermo_params, +) = (return nothing) + +function overwrite_initial_conditions!( + initial_condition::DYAMONDSummer, + Y, + thermo_params, + config, +) + file_path = AA.dyamond_summer_artifact_path(; context = config.comms_ctx) + center_space = Fields.axes(Y.c) + face_space = Fields.axes(Y.f) + p_sfc = Fields.level( + SpaceVaryingInputs.SpaceVaryingInput(file_path, "p", face_space), + Fields.half, + ) + ᶜT = SpaceVaryingInputs.SpaceVaryingInput(file_path, "t", center_space) + ᶜq_tot = SpaceVaryingInputs.SpaceVaryingInput(file_path, "q", center_space) + ᶜ∂lnp∂z = @. -thermo_params.grav / + (TD.gas_constant_air(thermo_params, TD.PhasePartition(ᶜq_tot)) * ᶜT) + ᶠlnp_over_psfc = zeros(face_space) + Operators.column_integral_indefinite!(ᶠlnp_over_psfc, ᶜ∂lnp∂z) + ᶠp = p_sfc .* exp.(ᶠlnp_over_psfc) + ᶜts = TD.PhaseEquil_pTq.(thermo_params, ᶜinterp.(ᶠp), ᶜT, ᶜq_tot) + Y.c.ρ .= TD.air_density.(thermo_params, ᶜts) + vel = + Geometry.UVWVector.( + SpaceVaryingInputs.SpaceVaryingInput(file_path, "u", center_space), + SpaceVaryingInputs.SpaceVaryingInput(file_path, "v", center_space), + SpaceVaryingInputs.SpaceVaryingInput(file_path, "w", center_space), + ) + Y.c.uₕ .= C12.(Geometry.UVVector.(vel)) + Y.f.u₃ .= ᶠinterp.(C3.(Geometry.WVector.(vel))) + e_kin = similar(ᶜT) + compute_kinetic!(e_kin, Y.c.uₕ, Y.f.u₃) + e_pot = Fields.coordinate_field(Y.c).z .* thermo_params.grav + Y.c.ρe_tot .= TD.total_energy.(thermo_params, ᶜts, e_kin, e_pot) .* Y.c.ρ + Y.c.ρq_tot .= ᶜq_tot .* Y.c.ρ + if config.parsed_args["precip_model"] == "1M" + Y.c.ρq_sno .= + SpaceVaryingInputs.SpaceVaryingInput( + file_path, + "cswc", + center_space, + ) .* Y.c.ρ + Y.c.ρq_rai .= + SpaceVaryingInputs.SpaceVaryingInput( + file_path, + "crwc", + center_space, + ) .* Y.c.ρ + end + return nothing +end ## ## Baroclinic Wave ## diff --git a/src/solver/type_getters.jl b/src/solver/type_getters.jl index 952f51a03e9..62351019d14 100644 --- a/src/solver/type_getters.jl +++ b/src/solver/type_getters.jl @@ -268,6 +268,8 @@ function get_initial_condition(parsed_args) return getproperty(ICs, Symbol(parsed_args["initial_condition"]))( parsed_args["perturb_initstate"], ) + elseif parsed_args["initial_condition"] in ["DYAMONDSummer"] + return getproperty(ICs, Symbol(parsed_args["initial_condition"]))() elseif parsed_args["initial_condition"] in [ "Nieuwstadt", "GABLS", @@ -626,7 +628,6 @@ end function get_simulation(config::AtmosConfig) params = create_parameter_set(config) atmos = get_atmos(config, params) - sim_info = get_sim_info(config) job_id = sim_info.job_id output_dir = sim_info.output_dir @@ -655,7 +656,6 @@ function get_simulation(config::AtmosConfig) initial_condition = get_initial_condition(config.parsed_args) surface_setup = get_surface_setup(config.parsed_args) - if !sim_info.restart s = @timed_str begin Y = ICs.atmos_state( @@ -671,6 +671,13 @@ function get_simulation(config::AtmosConfig) tracers = get_tracers(config.parsed_args) + CA.InitialConditions.overwrite_initial_conditions!( + initial_condition, + Y, + params.thermodynamics_params, + config, + ) + s = @timed_str begin p = build_cache( Y, diff --git a/src/utils/AtmosArtifacts.jl b/src/utils/AtmosArtifacts.jl index 2a3092406c4..5879f8a476f 100644 --- a/src/utils/AtmosArtifacts.jl +++ b/src/utils/AtmosArtifacts.jl @@ -82,4 +82,12 @@ function earth_orography_file_path(; context = nothing) ) end +function dyamond_summer_artifact_path(; context = nothing) + filename = "DYAMOND_SUMMER_ICS_p98deg.nc" + return joinpath( + @clima_artifact("DYAMOND_SUMMER_ICS_p98deg", context), + filename, + ) +end + end