From 492513de27b973c3f7b1f05d4fa789b49cd6a56c Mon Sep 17 00:00:00 2001 From: Zhaoyi Shen <11598433+szy21@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:23:35 -0800 Subject: [PATCH] Add TOA and surface radiation diagnostics --- .buildkite/longruns/pipeline.yml | 5 - ...5km_nz63_clearsky_tvinsol_0M_slabocean.yml | 5 - ...oe_equil_clearsky_tvinsol_0M_slabocean.yml | 5 - ...oe_equil_clearsky_tvinsol_0M_slabocean.yml | 9 +- ...lmoist_allsky_gw_raw_zonallyasymmetric.yml | 4 - perf/flame.jl | 10 +- post_processing/ci_plots.jl | 117 ++-- src/diagnostics/default_diagnostics.jl | 45 +- src/diagnostics/radiation_diagnostics.jl | 524 +++++++++++++++++- src/solver/type_getters.jl | 10 +- 10 files changed, 625 insertions(+), 109 deletions(-) diff --git a/.buildkite/longruns/pipeline.yml b/.buildkite/longruns/pipeline.yml index 6bea1b3092..5513573973 100644 --- a/.buildkite/longruns/pipeline.yml +++ b/.buildkite/longruns/pipeline.yml @@ -140,11 +140,6 @@ steps: env: JOB_NAME: "longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean" - - - group: "Experimental long runs" - - steps: - - group: "DYAMOND" steps: diff --git a/config/longrun_configs/longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean.yml b/config/longrun_configs/longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean.yml index b085d66ac6..e1481c3553 100644 --- a/config/longrun_configs/longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean.yml +++ b/config/longrun_configs/longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean.yml @@ -21,8 +21,3 @@ check_conservation: true bubble: false job_id: "longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean" toml: [toml/longrun_aquaplanet_rhoe_equil_55km_nz63_gray_0M.toml] -output_default_diagnostics: false -diagnostics: - - short_name: ["ts", "ta", "thetaa", "ha", "pfull", "rhoa", "ua", "va", "wa", "hfes", "hur", "hus", "clw", "cli", "evspsbl", "rsd", "rsu", "rld", "rlu"] - reduction_time: average - period: 10days diff --git a/config/longrun_configs/longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml b/config/longrun_configs/longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml index 56b3b04541..a5534a53a9 100644 --- a/config/longrun_configs/longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml +++ b/config/longrun_configs/longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml @@ -13,8 +13,3 @@ prognostic_surface: "PrognosticSurfaceTemperature" check_conservation: true bubble: false job_id: "longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean" -output_default_diagnostics: false -diagnostics: - - short_name: ["ts", "ta", "thetaa", "ha", "pfull", "rhoa", "ua", "va", "wa", "hfes", "hur", "hus", "clw", "cli", "evspsbl", "rsd", "rsu", "rld", "rlu"] - reduction_time: average - period: 10days \ No newline at end of file diff --git a/config/model_configs/aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml b/config/model_configs/aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml index 33ee02a2ba..71c4de0b20 100644 --- a/config/model_configs/aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml +++ b/config/model_configs/aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean.yml @@ -1,6 +1,6 @@ FLOAT_TYPE: "Float32" -dt_save_state_to_disk: "10days" -t_end: "10days" +dt_save_state_to_disk: "5days" +t_end: "5days" moist: "equil" precip_model: "0M" surface_setup: "DefaultMoninObukhov" @@ -14,8 +14,3 @@ prognostic_surface: "PrognosticSurfaceTemperature" check_conservation: true bubble: false job_id: "aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean" -output_default_diagnostics: false -diagnostics: - - short_name: ["ts", "ta", "thetaa", "ha", "pfull", "rhoa", "ua", "va", "wa", "hfes", "hur", "hus", "clw", "cli", "evspsbl", "rsd", "rsu", "rld", "rlu"] - reduction_time: average - period: 10days \ No newline at end of file diff --git a/config/model_configs/sphere_aquaplanet_rhoe_equilmoist_allsky_gw_raw_zonallyasymmetric.yml b/config/model_configs/sphere_aquaplanet_rhoe_equilmoist_allsky_gw_raw_zonallyasymmetric.yml index 1576d17fe7..514e23a7c8 100644 --- a/config/model_configs/sphere_aquaplanet_rhoe_equilmoist_allsky_gw_raw_zonallyasymmetric.yml +++ b/config/model_configs/sphere_aquaplanet_rhoe_equilmoist_allsky_gw_raw_zonallyasymmetric.yml @@ -19,7 +19,3 @@ job_id: "sphere_aquaplanet_rhoe_equilmoist_allsky_gw_raw_zonallyasymmetric" moist: "equil" toml: [toml/sphere_aquaplanet_rhoe_equilmoist_allsky_gw_raw_zonallyasymmetric.toml] netcdf_interpolate_z_over_msl: true -diagnostics: - - short_name: [ua, ta, hus, hfes, evspsbl, rsd, rsu, rld, rlu] - reduction_time: average - period: 12hours diff --git a/perf/flame.jl b/perf/flame.jl index a79be886fc..36c066b9eb 100644 --- a/perf/flame.jl +++ b/perf/flame.jl @@ -38,19 +38,19 @@ ProfileCanvas.html_file(joinpath(output_dir, "flame.html"), results) ##### allocs_limit = Dict() -allocs_limit["flame_perf_target"] = 201560 -allocs_limit["flame_perf_target_tracers"] = 234032 +allocs_limit["flame_perf_target"] = 275_800 +allocs_limit["flame_perf_target_tracers"] = 305_776 allocs_limit["flame_perf_target_edmfx"] = 7_005_552 -allocs_limit["flame_perf_diagnostics"] = 108_785_416 +allocs_limit["flame_perf_diagnostics"] = 108_858_808 allocs_limit["flame_perf_target_diagnostic_edmfx"] = 531_000 allocs_limit["flame_sphere_baroclinic_wave_rhoe_equilmoist_expvdiff"] = 4_018_252_656 allocs_limit["flame_perf_target_frierson"] = 8_030_551_088 allocs_limit["flame_perf_target_threaded"] = 1_276_864 -allocs_limit["flame_perf_target_callbacks"] = 386_584 +allocs_limit["flame_perf_target_callbacks"] = 394_984 allocs_limit["flame_perf_gw"] = 3_268_961_856 allocs_limit["flame_perf_target_prognostic_edmfx_aquaplanet"] = 445_664 -allocs_limit["flame_gpu_implicit_barowave_moist"] = 4178384 +allocs_limit["flame_gpu_implicit_barowave_moist"] = 4_178_384 # Ideally, we would like to track all the allocations, but this becomes too # expensive there is too many of them. Here, we set the default sample rate to # 1, but lower it to a smaller value when we expect the job to produce lots of diff --git a/post_processing/ci_plots.jl b/post_processing/ci_plots.jl index a6541998d9..3fd9eaf812 100644 --- a/post_processing/ci_plots.jl +++ b/post_processing/ci_plots.jl @@ -447,26 +447,38 @@ function make_plots( simdir = SimDir(simulation_path) reduction = "average" - short_names_3D = ["ua", "ta", "hus", "rsd", "rsu", "rld", "rlu"] - short_names_sfc = ["hfes", "evspsbl"] + short_names_3D = ["ua", "ta", "hus"] + short_names_2D = [ + "rsdt", + "rsds", + "rsut", + "rsus", + "rlds", + "rlut", + "rlus", + "hfes", + "evspsbl", + ] available_periods = ClimaAnalysis.available_periods( simdir; short_name = short_names_3D[1], reduction, ) - if "10d" in available_periods + if "30d" in available_periods + period = "30d" + elseif "10d" in available_periods period = "10d" elseif "1d" in available_periods period = "1d" - elseif "12h" in available_periods - period = "12h" + elseif "1h" in available_periods + period = "1h" end vars_3D = [ get(simdir; short_name, reduction, period) |> ClimaAnalysis.average_lon for short_name in short_names_3D ] - vars_sfc = [ + vars_2D = [ get(simdir; short_name, reduction, period) for - short_name in short_names_sfc + short_name in short_names_2D ] make_plots_generic( simulation_path, @@ -476,67 +488,15 @@ function make_plots( ) make_plots_generic( simulation_path, - vars_sfc, + vars_2D, time = LAST_SNAP, - output_name = "summary_sfc", - ) -end - -function make_plots( - ::Union{ - Val{:aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean}, - Val{:longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean}, - Val{ - :longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean, - }, - }, - simulation_path, -) - simdir = SimDir(simulation_path) - - - reduction = "average" - period = "10d" - short_names_3D = [ - "ta", - "thetaa", - "rhoa", - "ua", - "va", - "wa", - "hur", - "hus", - "clw", - "cli", - "rsd", - "rsu", - "rld", - "rlu", - ] - short_names_sfc = ["hfes", "evspsbl", "ts"] - vars_3D = [ - get(simdir; short_name, reduction, period) |> ClimaAnalysis.average_lon for short_name in short_names_3D - ] - vars_sfc = [ - get(simdir; short_name, reduction, period) for - short_name in short_names_sfc - ] - make_plots_generic( - simulation_path, - vars_3D, - time = LAST_SNAP, - more_kwargs = YLOGSCALE, - ) - make_plots_generic( - simulation_path, - vars_sfc, - time = LAST_SNAP, - output_name = "summary_sfc", + output_name = "summary_2D", ) end AquaplanetPlots = Union{ Val{:sphere_aquaplanet_rhoe_equilmoist_allsky_gw_res}, + Val{:aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean}, Val{:mpi_sphere_aquaplanet_rhoe_equilmoist_clearsky}, Val{:longrun_aquaplanet_rhoe_equil_55km_nz63_gray_0M}, Val{:longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_0M}, @@ -544,7 +504,8 @@ AquaplanetPlots = Union{ Val{:longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_diagedmf_0M}, Val{:longrun_aquaplanet_rhoe_equil_55km_nz63_allsky_diagedmf_0M}, Val{:longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_earth}, - Val{:longrun_aquaplanet_rhoe_equil_highres_allsky_ft32}, + Val{:longrun_aquaplanet_rhoe_equil_clearsky_tvinsol_0M_slabocean}, + Val{:longrun_aquaplanet_rhoe_equil_55km_nz63_clearsky_tvinsol_0M_slabocean}, Val{:longrun_aquaplanet_dyamond}, Val{:longrun_aquaplanet_amip}, } @@ -553,25 +514,37 @@ function make_plots(::AquaplanetPlots, simulation_path) simdir = SimDir(simulation_path) reduction = "average" - short_names_3D = ["ua", "ta", "hus", "rsd", "rsu", "rld", "rlu"] - short_names_sfc = ["hfes", "evspsbl"] + short_names_3D = ["ua", "ta", "hus"] + short_names_2D = [ + "rsdt", + "rsds", + "rsut", + "rsus", + "rlds", + "rlut", + "rlus", + "hfes", + "evspsbl", + ] available_periods = ClimaAnalysis.available_periods( simdir; short_name = short_names_3D[1], reduction, ) - if "10d" in available_periods + if "30d" in available_periods + period = "30d" + elseif "10d" in available_periods period = "10d" elseif "1d" in available_periods period = "1d" - elseif "12h" in available_periods - period = "12h" + elseif "1h" in available_periods + period = "1h" end vars_3D = [ get(simdir; short_name, reduction, period) |> ClimaAnalysis.average_lon for short_name in short_names_3D ] - vars_sfc = - [get(simdir; short_name, reduction) for short_name in short_names_sfc] + vars_2D = + [get(simdir; short_name, reduction) for short_name in short_names_2D] make_plots_generic( simulation_path, vars_3D, @@ -580,9 +553,9 @@ function make_plots(::AquaplanetPlots, simulation_path) ) make_plots_generic( simulation_path, - vars_sfc, + vars_2D, time = LAST_SNAP, - output_name = "summary_sfc", + output_name = "summary_2D", ) end diff --git a/src/diagnostics/default_diagnostics.jl b/src/diagnostics/default_diagnostics.jl index 784f46a115..d958dc9233 100644 --- a/src/diagnostics/default_diagnostics.jl +++ b/src/diagnostics/default_diagnostics.jl @@ -174,7 +174,19 @@ end # Radiation mode # ################## function default_diagnostics(::RRTMGPI.AbstractRRTMGPMode, t_end; output_writer) - rad_diagnostics = ["rsd", "rsu", "rld", "rlu"] + rad_diagnostics = [ + "rsd", + "rsdt", + "rsds", + "rsu", + "rsut", + "rsus", + "rld", + "rlds", + "rlu", + "rlut", + "rlus", + ] average_func = frequency_averages(t_end) @@ -187,12 +199,37 @@ function default_diagnostics( t_end; output_writer, ) - rad_diagnostics = - ["rsd", "rsu", "rld", "rlu", "rsdcs", "rsucs", "rldcs", "rlucs"] + rad_diagnostics = [ + "rsd", + "rsdt", + "rsds", + "rsu", + "rsut", + "rsus", + "rld", + "rlds", + "rlu", + "rlut", + "rlus", + ] + rad_clearsky_diagnostics = [ + "rsdcs", + "rsdscs", + "rsucs", + "rsutcs", + "rsuscs", + "rldcs", + "rldscs", + "rlucs", + "rlutcs", + ] average_func = frequency_averages(t_end) - return [average_func(rad_diagnostics...; output_writer)...] + return [ + average_func(rad_diagnostics...; output_writer)..., + average_func(rad_clearsky_diagnostics...; output_writer)..., + ] end ################## diff --git a/src/diagnostics/radiation_diagnostics.jl b/src/diagnostics/radiation_diagnostics.jl index 5fe282688e..fe92371b34 100644 --- a/src/diagnostics/radiation_diagnostics.jl +++ b/src/diagnostics/radiation_diagnostics.jl @@ -40,7 +40,94 @@ add_diagnostic_variable!( ) ### -# Upwelling shortwave radiation (3d) +# TOA downwelling shortwave radiation (2d) +### +compute_rsdt!(out, state, cache, time) = + compute_rsdt!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsdt!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsdt", radiation_mode) + +function compute_rsdt!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + nlevels = Spaces.nlevels(axes(state.c)) + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_dn, + axes(state.f), + ), + nlevels + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_dn, + axes(state.f), + ), + nlevels + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsdt", + long_name = "TOA Incident Shortwave Radiation", + standard_name = "toa_incoming_shortwave_flux", + units = "W m^-2", + comments = "Downward shortwave radiation at the top of the atmosphere", + compute! = compute_rsdt!, +) + +### +# Surface downwelling shortwave radiation (2d) +### +compute_rsds!(out, state, cache, time) = + compute_rsds!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsds!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsds", radiation_mode) + +function compute_rsds!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_dn, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_dn, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsds", + long_name = "Surface Downwelling Shortwave Radiation", + standard_name = "surface_downwelling_shortwave_flux_in_air", + units = "W m^-2", + comments = "Downwelling shortwave radiation at the surface", + compute! = compute_rsds!, +) + +### +# Upwelling shortwave radiation (2d) ### compute_rsu!(out, state, cache, time) = compute_rsu!(out, state, cache, time, cache.atmos.radiation_mode) @@ -76,6 +163,93 @@ add_diagnostic_variable!( compute! = compute_rsu!, ) +### +# TOA upwelling shortwave radiation (2d) +### +compute_rsut!(out, state, cache, time) = + compute_rsut!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsut!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsut", radiation_mode) + +function compute_rsut!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + nlevels = Spaces.nlevels(axes(state.c)) + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsut", + long_name = "TOA Outgoing Shortwave Radiation", + standard_name = "toa_outgoing_shortwave_flux", + units = "W m^-2", + comments = "Upwelling shortwave radiation at the top of the atmosphere", + compute! = compute_rsut!, +) + +### +# Surface upwelling shortwave radiation (2d) +### +compute_rsus!(out, state, cache, time) = + compute_rsus!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsus!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsus", radiation_mode) + +function compute_rsus!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_up, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_sw_flux_up, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsus", + long_name = "Surface Upwelling Shortwave Radiation", + standard_name = "surface_upwelling_shortwave_flux_in_air", + units = "W m^-2", + comments = "Upwelling shortwave radiation at the surface", + compute! = compute_rsus!, +) + ### # Downwelling longwave radiation (3d) ### @@ -113,6 +287,49 @@ add_diagnostic_variable!( compute! = compute_rld!, ) +### +# Surface downwelling longwave radiation (2d) +### +compute_rlds!(out, state, cache, time) = + compute_rlds!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rlds!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rlds", radiation_mode) + +function compute_rlds!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_lw_flux_dn, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_lw_flux_dn, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rlds", + long_name = "Surface Downwelling Longwave Radiation", + standard_name = "surface_downwelling_longwave_flux_in_air", + units = "W m^-2", + comments = "Downwelling longwave radiation at the surface", + compute! = compute_rlds!, +) + ### # Upwelling longwave radiation (3d) ### @@ -150,6 +367,93 @@ add_diagnostic_variable!( compute! = compute_rlu!, ) +### +# TOA upwelling longwave radiation (2d) +### +compute_rlut!(out, state, cache, time) = + compute_rlut!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rlut!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rlut", radiation_mode) + +function compute_rlut!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + nlevels = Spaces.nlevels(axes(state.c)) + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_lw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_lw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rlut", + long_name = "TOA Outgoing Longwave Radiation", + standard_name = "toa_outgoing_longwave_flux", + units = "W m^-2", + comments = "Upwelling longwave radiation at the top of the atmosphere", + compute! = compute_rlut!, +) + +### +# Surface upwelling longwave radiation (2d) +### +compute_rlus!(out, state, cache, time) = + compute_rlus!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rlus!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rlus", radiation_mode) + +function compute_rlus!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_lw_flux_up, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_lw_flux_up, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rlus", + long_name = "Surface Upwelling Longwave Radiation", + standard_name = "surface_upwelling_longwave_flux_in_air", + units = "W m^-2", + comments = "Upwelling longwave radiation at the surface", + compute! = compute_rlus!, +) + ### # Downelling clear sky shortwave radiation (3d) ### @@ -187,6 +491,49 @@ add_diagnostic_variable!( compute! = compute_rsdcs!, ) +### +# Surface downwelling clear sky shortwave radiation (2d) +### +compute_rsdscs!(out, state, cache, time) = + compute_rsdscs!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsdscs!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsdscs", radiation_mode) + +function compute_rsdscs!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_sw_flux_dn, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_sw_flux_dn, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsdscs", + long_name = "Surface Downwelling Clear-Sky Shortwave Radiation", + standard_name = "surface_downwelling_shortwave_flux_in_air_assuming_clear_sky", + units = "W m^-2", + comments = "Downwelling clear-sky shortwave radiation at the surface", + compute! = compute_rsdscs!, +) + ### # Upwelling clear sky shortwave radiation (3d) ### @@ -224,6 +571,94 @@ add_diagnostic_variable!( compute! = compute_rsucs!, ) +### +# TOA upwelling clear sky shortwave radiation (2d) +### +compute_rsutcs!(out, state, cache, time) = + compute_rsutcs!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsutcs!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsutcs", radiation_mode) + +function compute_rsutcs!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + nlevels = Spaces.nlevels(axes(state.c)) + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_sw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_sw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsutcs", + long_name = "TOA Outgoing Clear-Sky Shortwave Radiation", + standard_name = "toa_outgoing_shortwave_flux_assuming_clear_sky", + units = "W m^-2", + comments = "Upwelling clear-sky shortwave radiation at the top of the atmosphere", + compute! = compute_rsutcs!, +) + +### +# Surface clear sky upwelling shortwave radiation (2d) +### +compute_rsuscs!(out, state, cache, time) = + compute_rsuscs!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rsuscs!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rsuscs", radiation_mode) + +function compute_rsuscs!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_sw_flux_up, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_sw_flux_up, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rsuscs", + long_name = "Surface Upwelling Clear-Sky Shortwave Radiation", + standard_name = "surface_upwelling_shortwave_flux_in_air_assuming_clear_sky", + units = "W m^-2", + comments = "Upwelling clear-sky shortwave radiation at the surface", + compute! = compute_rsuscs!, +) + + ### # Downwelling clear sky longwave radiation (3d) ### @@ -261,6 +696,49 @@ add_diagnostic_variable!( compute! = compute_rldcs!, ) +### +# Surface clear sky downwelling longwave radiation (2d) +### +compute_rldscs!(out, state, cache, time) = + compute_rldscs!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rldscs!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rldscs", radiation_mode) + +function compute_rldscs!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_lw_flux_dn, + axes(state.f), + ), + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_lw_flux_dn, + axes(state.f), + ), + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rldscs", + long_name = "Surface Downwelling Clear-Sky Longwave Radiation", + standard_name = "surface_downwelling_longwave_flux_in_air_assuming_clear_sky", + units = "W m^-2", + comments = "Downwelling clear-sky longwave radiation at the surface", + compute! = compute_rldscs!, +) + ### # Upwelling clear sky longwave radiation (3d) ### @@ -297,3 +775,47 @@ add_diagnostic_variable!( comments = "Upwelling clear sky longwave radiation", compute! = compute_rlucs!, ) + +### +# TOA clear sky upwelling longwave radiation (2d) +### +compute_rlutcs!(out, state, cache, time) = + compute_rlutcs!(out, state, cache, time, cache.atmos.radiation_mode) +compute_rlutcs!(_, _, _, _, radiation_mode::T) where {T} = + error_diagnostic_variable("rlutcs", radiation_mode) + +function compute_rlutcs!( + out, + state, + cache, + time, + radiation_mode::T, +) where {T <: RRTMGPI.AbstractRRTMGPMode} + nlevels = Spaces.nlevels(axes(state.c)) + if isnothing(out) + return Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_lw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + else + out .= Fields.level( + RRTMGPI.array2field( + cache.radiation.radiation_model.face_clear_lw_flux_up, + axes(state.f), + ), + nlevels + half, + ) + end +end + +add_diagnostic_variable!( + short_name = "rlutcs", + long_name = "TOA Outgoing Clear-Sky Longwave Radiation", + standard_name = "toa_outgoing_longwave_flux_assuming_clear_sky", + units = "W m^-2", + comments = "Upwelling clear-sky longwave radiation at the top of the atmosphere", + compute! = compute_rlutcs!, +) diff --git a/src/solver/type_getters.jl b/src/solver/type_getters.jl index 45b76218e7..964c52573a 100644 --- a/src/solver/type_getters.jl +++ b/src/solver/type_getters.jl @@ -958,8 +958,16 @@ function get_simulation(config::AtmosConfig) ) else # Add to the accumulator + + # We use similar + .= instead of copy because CUDA 5.2 does + # not supported nested wrappers with view(reshape(view)) + # objects. See discussion in + # https://github.com/CliMA/ClimaAtmos.jl/pull/2579 and + # https://github.com/JuliaGPU/Adapt.jl/issues/21 diagnostic_accumulators[diag] = - copy(diagnostic_storage[diag]) + similar(diagnostic_storage[diag]) + diagnostic_accumulators[diag] .= + diagnostic_storage[diag] end catch e error("Could not compute diagnostic $(variable.long_name): $e")