From 3de1ec14b8758bdc87d5f3c1fefc4ac81bb2d42c Mon Sep 17 00:00:00 2001 From: LenkaNovak Date: Wed, 1 Nov 2023 17:58:34 -0700 Subject: [PATCH] add extra diags --- .../AMIP/modular/coupler_driver_modular.jl | 19 +- .../AMIP/modular/user_io/user_diagnostics.jl | 176 +++++++++++++++++- 2 files changed, 189 insertions(+), 6 deletions(-) diff --git a/experiments/AMIP/modular/coupler_driver_modular.jl b/experiments/AMIP/modular/coupler_driver_modular.jl index 3a0e20998d..4096006267 100644 --- a/experiments/AMIP/modular/coupler_driver_modular.jl +++ b/experiments/AMIP/modular/coupler_driver_modular.jl @@ -207,7 +207,7 @@ boundary_space = atmos_sim.domain.face_space.horizontal_space # init land-sea fraction land_fraction = - Regridder.land_fraction(FT, REGRID_DIR, comms_ctx, land_mask_data, "LSMASK", boundary_space, mono = mono_surface) + Regridder.land_fraction(FT, REGRID_DIR, comms_ctx, land_mask_data, "LSMASK", boundary_space, mono = mono_surface) .* 0 #= ### Land @@ -407,7 +407,8 @@ dates = (; date = [date], date0 = [date0], date1 = [Dates.firstdayofmonth(date0) User can write custom diagnostics in the `user_diagnostics.jl`. =# monthly_3d_diags = init_diagnostics( - (:T, :u, :q_tot, :q_liq_ice), + (:T, :u, :v, :w, :q_tot, :q_liq_ice,:lapse_rate, :eddy_diffusivity, :moist_static_energy, +), atmos_sim.domain.center_space; save = Monthly(), operations = (; accumulate = TimeMean([Int(0)])), @@ -416,7 +417,7 @@ monthly_3d_diags = init_diagnostics( ) monthly_2d_diags = init_diagnostics( - (:precipitation_rate, :toa_fluxes, :T_sfc, :tubulent_energy_fluxes), + (:precipitation_rate, :toa_fluxes, :T_sfc, :tubulent_energy_fluxes, :evaporation, :longwave_down_sfc, :shortwave_down_sfc, :longwave_up_sfc, :shortwave_up_sfc,), boundary_space; save = Monthly(), operations = (; accumulate = TimeMean([Int(0)])), @@ -668,6 +669,12 @@ if ClimaComms.iamroot(comms_ctx) T_sfc = (:regrid, :horizontal_slice), tubulent_energy_fluxes = (:regrid, :horizontal_slice), q_liq_ice = (:regrid, :zonal_mean), + evaporation = (:regrid, :horizontal_slice), + v = (:regrid, :zonal_mean), + w = (:regrid, :zonal_mean), + lapse_rate = (:regrid, :zonal_mean), + eddy_diffusivity = (:regrid, :zonal_mean), + moist_static_energy = (:regrid, :zonal_mean), ) plot_spec = (; @@ -679,6 +686,12 @@ if ClimaComms.iamroot(comms_ctx) T_sfc = (clims = (225, 310), units = "K"), tubulent_energy_fluxes = (; clims = (-250, 250), units = "W/m^2"), q_liq_ice = (; clims = (0, 10), units = "g/kg"), + evaporation = (; clims = (0, 1e-4), units = "kg/m^2/s"), + v = (; clims = (-30, 30), units = "m/s"), + w = (; clims = (-0.1, 0.1), units = "m/s"), + lapse_rate = (;), + eddy_diffusivity = (;), + moist_static_energy = (;), ) amip_data = amip_paperplots( post_spec, diff --git a/experiments/AMIP/modular/user_io/user_diagnostics.jl b/experiments/AMIP/modular/user_io/user_diagnostics.jl index 42e28c4e65..ebc0a53241 100644 --- a/experiments/AMIP/modular/user_io/user_diagnostics.jl +++ b/experiments/AMIP/modular/user_io/user_diagnostics.jl @@ -25,6 +25,75 @@ Zonal wind (m s⁻¹). get_var(cs::CoupledSimulation, ::Val{:u}) = ClimaCore.Geometry.UVVector.(cs.model_sims.atmos_sim.integrator.u.c.uₕ).components.data.:1 +""" + get_var(cs::CoupledSimulation, ::Val{:v}) + +Meridional wind (m s⁻¹). +""" +get_var(cs::CoupledSimulation, ::Val{:v}) = + ClimaCore.Geometry.UVVector.(cs.model_sims.atmos_sim.integrator.u.c.uₕ).components.data.:2 + +""" + get_var(cs::CoupledSimulation, ::Val{:w}) + +Vertical wind (m s⁻¹). +""" +get_var(cs::CoupledSimulation, ::Val{:w}) = + ClimaCore.Geometry.WVector.(CA.ᶜinterp.(cs.model_sims.atmos_sim.integrator.u.f.u₃)).components.data.:1 + +""" + get_var(cs::CoupledSimulation, ::Val{:moist_static_energy}) + +Moist static energy. [J / kg] +""" +function get_var(cs::CoupledSimulation, ::Val{:moist_static_energy}) + p = cs.model_sims.atmos_sim.integrator.p + (; ᶜts, params) = p + c_space = axes(cs.model_sims.atmos_sim.integrator.u.c) + thermo_params = CAP.thermodynamics_params(params) + e_pot = 9.81 .* Fields.coordinate_field(c_space).z + TD.moist_static_energy.(thermo_params, ᶜts, e_pot) +end + +""" + get_var(cs::CoupledSimulation, ::Val{:lapse_rate}) + +Lapse rate (K/m). +""" +function get_var(cs::CoupledSimulation, ::Val{:lapse_rate}) + p = cs.model_sims.atmos_sim.integrator.p + (; ᶜts, params) = p + thermo_params = CAP.thermodynamics_params(params) + ᶜT = @. TD.air_temperature(thermo_params, ᶜts) + ClimaCore.Geometry.WVector.(CA.ᶜgradᵥ.(CA.ᶠinterp.(ᶜT))).components.data.:1 +end + +""" + get_var(cs::CoupledSimulation, ::Val{:eddy_diffusivity}) + +Eddy diffusivity. [m2/s] +""" +function get_var(cs::CoupledSimulation, ::Val{:eddy_diffusivity}) + p = cs.model_sims.atmos_sim.integrator.p + Y = cs.model_sims.atmos_sim.integrator.u + (; ᶜp) = p # assume ᶜts and ᶜp have been updated + (; C_E) = p.atmos.vert_diff + + interior_uₕ = Fields.level(Y.c.uₕ, 1) + ᶠp = ᶠK_E = p.ᶠtemp_scalar + Fields.bycolumn(axes(ᶜp)) do colidx + @. ᶠp[colidx] = CA.ᶠinterp(ᶜp[colidx]) + ᶜΔz_surface = Fields.Δz_field(interior_uₕ) + @. ᶠK_E[colidx] = CA.eddy_diffusivity_coefficient( + C_E, + CA.norm(interior_uₕ[colidx]), + ᶜΔz_surface[colidx] / 2, + ᶠp[colidx], + ) + end + return CA.ᶜinterp.(ᶠK_E) +end + """ get_var(cs::CoupledSimulation, ::Val{:q_tot}) @@ -33,7 +102,6 @@ Total specific humidity (g kg⁻¹). get_var(cs::CoupledSimulation, ::Val{:q_tot}) = cs.model_sims.atmos_sim.integrator.u.c.ρq_tot ./ cs.model_sims.atmos_sim.integrator.u.c.ρ .* float_type(cs)(1000) - """ get_var(cs::CoupledSimulation, ::Val{:q_liq_ice}) @@ -43,9 +111,24 @@ function get_var(cs::CoupledSimulation, ::Val{:q_liq_ice}) p = cs.model_sims.atmos_sim.integrator.p (; ᶜts, params) = p thermo_params = CAP.thermodynamics_params(params) - TD.liquid_specific_humidity.(thermo_params, ᶜts) .* float_type(cs)(1000) + TD.liquid_specific_humidity.(thermo_params, ᶜts) .* float_type(cs)(1000) .+ TD.ice_specific_humidity.(thermo_params, ᶜts) .* float_type(cs)(1000) end +# need to integrate between z and z0 +# """ +# get_var(cs::CoupledSimulation, ::Val{:mass_streamfunction}) + +# Mass streamfunction (kg s⁻¹). +# """ +# function get_var(cs::CoupledSimulation, ::Val{:mass_streamfunction}) +# v = ClimaCore.Geometry.UVVector.(cs.model_sims.atmos_sim.integrator.u.c.uₕ).components.data.:2 +# ρ = cs.model_sims.atmos_sim.integrator.u.c.ρ +# c_space = axes(ρ) +# coslat = cos.(Fields.coordinate_field(c_space).lat .* π ./ 180) +# strf = @. vert_int(2π * 6.371e6 * coslat * v * ρ) +# return strf +# end + """ get_var(cs::CoupledSimulation, ::Val{:toa_fluxes}) @@ -79,6 +162,83 @@ function get_var(cs::CoupledSimulation, ::Val{:toa_fluxes}) swap_space!(zeros(cs.boundary_space), radiation_sources) end +""" + get_var(cs::CoupledSimulation, ::Val{:longwave_down_sfc}) + +Downward shortwave radiation fluxes (W m⁻²). +""" +function get_var(cs::CoupledSimulation, ::Val{:longwave_down_sfc}) + atmos_sim = cs.model_sims.atmos_sim + face_space = axes(atmos_sim.integrator.u.f) + z = parent(Fields.coordinate_field(face_space).z) + Δz_top = round(FT(0.5) * (z[end, 1, 1, 1, 1] - z[end - 1, 1, 1, 1, 1])) + n_faces = length(z[:, 1, 1, 1, 1]) + + LWd_TOA = Fields.level( + RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_lw_flux_dn), face_space), + half, + ) + swap_space!(zeros(cs.boundary_space), LWd_TOA) +end + +""" + get_var(cs::CoupledSimulation, ::Val{:longwave_up_sfc}) + +Upward shortwave radiation fluxes (W m⁻²). +""" +function get_var(cs::CoupledSimulation, ::Val{:longwave_up_sfc}) + atmos_sim = cs.model_sims.atmos_sim + face_space = axes(atmos_sim.integrator.u.f) + z = parent(Fields.coordinate_field(face_space).z) + Δz_top = round(FT(0.5) * (z[end, 1, 1, 1, 1] - z[end - 1, 1, 1, 1, 1])) + n_faces = length(z[:, 1, 1, 1, 1]) + + LWu_TOA = Fields.level( + RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_lw_flux_up), face_space), + half, + ) + swap_space!(zeros(cs.boundary_space), LWu_TOA) +end + +""" + get_var(cs::CoupledSimulation, ::Val{:shortwave_down_sfc}) + +Downward shortwave radiation fluxes (W m⁻²). +""" +function get_var(cs::CoupledSimulation, ::Val{:shortwave_down_sfc}) + atmos_sim = cs.model_sims.atmos_sim + face_space = axes(atmos_sim.integrator.u.f) + z = parent(Fields.coordinate_field(face_space).z) + Δz_top = round(FT(0.5) * (z[end, 1, 1, 1, 1] - z[end - 1, 1, 1, 1, 1])) + n_faces = length(z[:, 1, 1, 1, 1]) + + SWd_TOA = Fields.level( + RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_sw_flux_dn), face_space), + half, + ) + swap_space!(zeros(cs.boundary_space), SWd_TOA) +end + +""" + get_var(cs::CoupledSimulation, ::Val{:shortwave_up_sfc}) + +Upward shortwave radiation fluxes (W m⁻²). +""" +function get_var(cs::CoupledSimulation, ::Val{:shortwave_up_sfc}) + atmos_sim = cs.model_sims.atmos_sim + face_space = axes(atmos_sim.integrator.u.f) + z = parent(Fields.coordinate_field(face_space).z) + Δz_top = round(FT(0.5) * (z[end, 1, 1, 1, 1] - z[end - 1, 1, 1, 1, 1])) + n_faces = length(z[:, 1, 1, 1, 1]) + + SWu_TOA = Fields.level( + RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_sw_flux_up), face_space), + half, + ) + swap_space!(zeros(cs.boundary_space), SWu_TOA) +end + + """ get_var(cs::CoupledSimulation, ::Val{:precipitation_rate}) @@ -107,4 +267,14 @@ Combined aerodynamic turbulent energy surface fluxes (W m⁻²). get_var(cs::CoupledSimulation, ::Val{:tubulent_energy_fluxes}) = swap_space!(zeros(cs.boundary_space), cs.fields.F_turb_energy) -# land diagnotics + +""" + get_var(cs::CoupledSimulation, ::Val{:evaporation}) + +Combined aerodynamic turbulent moisture surface fluxes (kg m⁻² s-1). +""" +get_var(cs::CoupledSimulation, ::Val{:evaporation}) = + swap_space!(zeros(cs.boundary_space), cs.fields.F_turb_moisture) + + +