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 different sizes for dust and sea salt #3555

Merged
merged 1 commit into from
Feb 5, 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
9 changes: 8 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ ClimaAtmos.jl Release Notes

Main
-------
### Features

### Allow different sizes of dust and sea salt for radiation

Added functionality to allow five different size bins of dust and sea salt aerosols
for radiation calculation. This feature requires RRTMGP version v0.20.0 or later.
PR [3555](https://github.com/CliMA/ClimaAtmos.jl/pull/3555)

v0.28.4
-------
Expand All @@ -12,7 +19,7 @@ The `.dev` was deprecated. The two utilities in this folder can be replaced with
more established and better developed tools:
- instead of `clima_format`, use `JuliaFormatter`,
- instead of `up_deps`, use `PkgDevTools`.
See the [documentation](https://clima.github.io/ClimaAtmos.jl/dev/contributor_guide/#Formatting) for more information.
See the [documentation](https://clima.github.io/ClimaAtmos.jl/dev/contributor_guide/#Formatting) for more information.

`ClimaAtmos` now only support equilibrium moisture + 0-moment microphysics and
nonequilibrium + 1-moment microphysics (No precipitation is still supported too).
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ LinearAlgebra = "1"
Logging = "1"
NCDatasets = "0.14.2"
NVTX = "0.3"
RRTMGP = "0.19"
RRTMGP = "0.19, 0.20"
Random = "1"
SciMLBase = "2.12"
StaticArrays = "1.7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ diagnostics:
period: "12hours"
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
2 changes: 1 addition & 1 deletion config/gpu_configs/gpu_aquaplanet_dyamond_ss.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ t_end: "1days"
toml: [toml/longrun_aquaplanet.toml]
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
2 changes: 1 addition & 1 deletion config/gpu_configs/gpu_aquaplanet_dyamond_summer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ t_end: "1hours"
toml: [toml/longrun_aquaplanet.toml]
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
start_date: "20160801"
initial_condition: "artifact\"DYAMOND_SUMMER_ICS_p98deg\"/DYAMOND_SUMMER_ICS_p98deg.nc"
topography: "Earth"
2 changes: 1 addition & 1 deletion config/gpu_configs/gpu_aquaplanet_dyamond_ws_1process.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ t_end: "1days"
toml: [toml/longrun_aquaplanet.toml]
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
2 changes: 1 addition & 1 deletion config/gpu_configs/gpu_aquaplanet_dyamond_ws_2process.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ t_end: "1days"
toml: [toml/longrun_aquaplanet.toml]
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
2 changes: 1 addition & 1 deletion config/gpu_configs/gpu_aquaplanet_dyamond_ws_4process.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ t_end: "1days"
toml: [toml/longrun_aquaplanet.toml]
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
2 changes: 1 addition & 1 deletion config/longrun_configs/amip_target_diagedmf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ insolation: "timevarying"
co2_model: maunaloa
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
surface_setup: "DefaultMoninObukhov"
turbconv: "diagnostic_edmfx"
implicit_diffusion: true
Expand Down
2 changes: 1 addition & 1 deletion config/model_configs/gpu_aquaplanet_dyamond.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dt: "90secs"
t_end: "8hours"
prescribe_ozone: true
aerosol_radiation: true
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
prescribe_clouds_in_radiation: true
radiation_reset_rng_seed: true
toml: [toml/longrun_aquaplanet.toml]
Expand Down
47 changes: 17 additions & 30 deletions src/callbacks/callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,41 +198,28 @@ NVTX.@annotate function rrtmgp_model_callback!(integrator)

if !(radiation_mode isa RRTMGPI.GrayRadiation)
if radiation_mode.aerosol_radiation
_update_some_aerosol_conc(Y, p)
ᶜΔz = Fields.Δz_field(Y.c)

ᶜaero_conc = Fields.array2field(
rrtmgp_model.center_dust_column_mass_density,
axes(Y.c),
)
@. ᶜaero_conc = 0
for prescribed_aerosol_name in [:DST01, :DST02, :DST03, :DST04]
if prescribed_aerosol_name in
propertynames(p.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
p.tracers.prescribed_aerosols_field,
prescribed_aerosol_name,
)
@. ᶜaero_conc += aerosol_field * Y.c.ρ * ᶜΔz
end
end

ᶜaero_conc = Fields.array2field(
rrtmgp_model.center_ss_column_mass_density,
axes(Y.c),
)
@. ᶜaero_conc = 0
for prescribed_aerosol_name in [:SSLT01, :SSLT02, :SSLT03, :SSLT04]
if prescribed_aerosol_name in
propertynames(p.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
p.tracers.prescribed_aerosols_field,
prescribed_aerosol_name,
)
@. ᶜaero_conc += aerosol_field * Y.c.ρ * ᶜΔz
end
if pkgversion(RRTMGP) <= v"0.19.2"
more_aerosols = ()
else
more_aerosols = (
(:center_dust1_column_mass_density, :DST01),
(:center_dust2_column_mass_density, :DST02),
(:center_dust3_column_mass_density, :DST03),
(:center_dust4_column_mass_density, :DST04),
(:center_dust5_column_mass_density, :DST05),
(:center_ss1_column_mass_density, :SSLT01),
(:center_ss2_column_mass_density, :SSLT02),
(:center_ss3_column_mass_density, :SSLT03),
(:center_ss4_column_mass_density, :SSLT04),
(:center_ss5_column_mass_density, :SSLT05),
)
end

aerosol_names_pair = [
more_aerosols...,
(:center_so4_column_mass_density, :SO4),
(:center_bcpi_column_mass_density, :CB2),
(:center_bcpo_column_mass_density, :CB1),
Expand Down
45 changes: 45 additions & 0 deletions src/compat.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ClimaCore
import ClimaUtilities
import ClimaCore: Domains, Spaces, Topologies
import RRTMGP

# To allow for backwards compatibility of ClimaCore:
if pkgversion(ClimaCore) < v"0.14.18"
Expand Down Expand Up @@ -95,3 +96,47 @@ else
WallTimeInfo = ClimaUtilities.OnlineLogging.WallTimeInfo
report_walltime = ClimaUtilities.OnlineLogging.report_walltime
end


if pkgversion(RRTMGP) <= v"0.19.2"
function _update_some_aerosol_conc(Y, p)
ᶜΔz = Fields.Δz_field(Y.c)
rrtmgp_model = p.radiation.rrtmgp_model
ᶜaero_conc = Fields.array2field(
rrtmgp_model.center_dust_column_mass_density,
axes(Y.c),
)
@. ᶜaero_conc = 0
for prescribed_aerosol_name in [:DST01, :DST02, :DST03, :DST04]
if prescribed_aerosol_name in
propertynames(p.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
p.tracers.prescribed_aerosols_field,
prescribed_aerosol_name,
)
@. ᶜaero_conc += aerosol_field * Y.c.ρ * ᶜΔz
end
end

ᶜaero_conc = Fields.array2field(
rrtmgp_model.center_ss_column_mass_density,
axes(Y.c),
)
@. ᶜaero_conc = 0
for prescribed_aerosol_name in [:SSLT01, :SSLT02, :SSLT03, :SSLT04]
if prescribed_aerosol_name in
propertynames(p.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
p.tracers.prescribed_aerosols_field,
prescribed_aerosol_name,
)
@. ᶜaero_conc += aerosol_field * Y.c.ρ * ᶜΔz
end
end
return nothing
end
else
function _update_some_aerosol_conc(_, _)
return nothing
end
end
14 changes: 8 additions & 6 deletions src/diagnostics/tracer_diagnostics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ function compute_dust!(out, state, cache, time)
error("Aerosols do not exist in the model")
any(
x -> x in propertynames(cache.tracers.prescribed_aerosols_field),
[:DST01, :DST02, :DST03, :DST04],
[:DST01, :DST02, :DST03, :DST04, :DST05],
) || error("Dust does not exist in the model")
if isnothing(out)
aero_conc = cache.scratch.ᶜtemp_scalar
@. aero_conc = 0
for prescribed_aerosol_name in [:DST01, :DST02, :DST03, :DST04]
for prescribed_aerosol_name in [:DST01, :DST02, :DST03, :DST04, :DST05]
if prescribed_aerosol_name in
propertynames(cache.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
Expand All @@ -51,7 +51,7 @@ function compute_dust!(out, state, cache, time)
else
aero_conc = cache.scratch.ᶜtemp_scalar
@. aero_conc = 0
for prescribed_aerosol_name in [:DST01, :DST02, :DST03, :DST04]
for prescribed_aerosol_name in [:DST01, :DST02, :DST03, :DST04, :DST05]
if prescribed_aerosol_name in
propertynames(cache.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
Expand All @@ -70,12 +70,13 @@ function compute_sea_salt!(out, state, cache, time)
error("Aerosols do not exist in the model")
any(
x -> x in propertynames(cache.tracers.prescribed_aerosols_field),
[:SSLT01, :SSLT02, :SSLT03, :SSLT04],
[:SSLT01, :SSLT02, :SSLT03, :SSLT04, :SSLT05],
) || error("Sea salt does not exist in the model")
if isnothing(out)
aero_conc = cache.scratch.ᶜtemp_scalar
@. aero_conc = 0
for prescribed_aerosol_name in [:SSLT01, :SSLT02, :SSLT03, :SSLT04]
for prescribed_aerosol_name in
[:SSLT01, :SSLT02, :SSLT03, :SSLT04, :SSLT05]
if prescribed_aerosol_name in
propertynames(cache.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
Expand All @@ -89,7 +90,8 @@ function compute_sea_salt!(out, state, cache, time)
else
aero_conc = cache.scratch.ᶜtemp_scalar
@. aero_conc = 0
for prescribed_aerosol_name in [:SSLT01, :SSLT02, :SSLT03, :SSLT04]
for prescribed_aerosol_name in
[:SSLT01, :SSLT02, :SSLT03, :SSLT04, :SSLT05]
if prescribed_aerosol_name in
propertynames(cache.tracers.prescribed_aerosols_field)
aerosol_field = getproperty(
Expand Down
63 changes: 47 additions & 16 deletions src/parameterized_tendencies/radiation/RRTMGPInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ struct AllSkyRadiation{ACR <: AbstractCloudInRadiation} <: AbstractRRTMGPMode
add_isothermal_boundary_layer::Bool
aerosol_radiation::Bool
"""
Reset the RNG seed before calling RRTGMP to a known value (the timestep number).
When modeling cloud optics, RRTGMP uses a random number generator.
Resetting the seed every time RRTGMP is called to a deterministic value ensures that
Reset the RNG seed before calling RRTMGP to a known value (the timestep number).
When modeling cloud optics, RRTMGP uses a random number generator.
Resetting the seed every time RRTMGP is called to a deterministic value ensures that
the simulation is fully reproducible and can be restarted in a reproducible way.
Disable this option when running production runs.
"""
Expand All @@ -47,9 +47,9 @@ struct AllSkyRadiationWithClearSkyDiagnostics{
add_isothermal_boundary_layer::Bool
aerosol_radiation::Bool
"""
Reset the RNG seed before calling RRTGMP to a known value (the timestep number).
When modeling cloud optics, RRTGMP uses a random number generator.
Resetting the seed every time RRTGMP is called to a deterministic value ensures that
Reset the RNG seed before calling RRTMGP to a known value (the timestep number).
When modeling cloud optics, RRTMGP uses a random number generator.
Resetting the seed every time RRTMGP is called to a deterministic value ensures that
the simulation is fully reproducible and can be restarted in a reproducible way.
Disable this option when running production runs.
"""
Expand Down Expand Up @@ -831,16 +831,47 @@ function RRTMGPModel(
# See the lookup table in RRTMGP for the order of aerosols
aero_size = DA{FT}(undef, n_aerosol_sizes, nlay, ncol)
aero_mass = DA{FT}(undef, n_aerosols, nlay, ncol)
aerosol_size_names = ["dust", "ss"]
aerosol_names =
["dust", "ss", "so4", "bcpi", "bcpo", "ocpi", "ocpo"]
for (i, name) in enumerate(aerosol_size_names)
set_and_save!(
view(aero_size, i, :, :),
"center_$(name)_radius",
t...,
dict,
)

if pkgversion(RRTMGP) <= v"0.19.2"
aerosol_size_names = ["dust", "ss"]
aerosol_names =
["dust", "ss", "so4", "bcpi", "bcpo", "ocpi", "ocpo"]
for (i, name) in enumerate(aerosol_size_names)
set_and_save!(
view(aero_size, i, :, :),
"center_$(name)_radius",
t...,
dict,
)
end
else
aerosol_names = [
"dust1",
"ss1",
"so4",
"bcpi",
"bcpo",
"ocpi",
"ocpo",
"dust2",
"dust3",
"dust4",
"dust5",
"ss2",
"ss3",
"ss4",
"ss5",
]
for (i, name) in enumerate(aerosol_names)
if occursin("dust", name) || occursin("ss", name)
set_and_save!(
view(aero_size, i, :, :),
"center_$(name)_radius",
t...,
dict,
)
end
end
end
for (i, name) in enumerate(aerosol_names)
set_and_save!(
Expand Down
Loading
Loading