-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Apply ClimaLSM API soil resistance changes Apply ClimaComms API changes; remove ClimaCommsMPI Update ClimaAtmos CLI options Use ClimaAtmos v0.14.1 ClimaAtmos change: rename Y.f.w -> Y.f.u₃ ClimaLSM API change: use make_exp_tendency in place of make_ode_function Use ClimaComms.CPUDevice() Remove simulation.is_distributed from Atmos change PR #1634 WIP: Apply changes from surface fluxes rework CA PR #1447 Rebase onto main after PRs #315 & #320 WIP: update to ClimaAtmos surface rework Co-authored-by: Lenka Novak <[email protected]> TEMP ONLY: Test CA surface setup fix dev branch Adapt flux calculation given CA current Surface Setup Some WIP fixes w/ Lenka Co-authored-by: Lenka Novak <[email protected]> CI: Try Float64 for AMIP modular experiment Increase alloc limit for perf test Update to ClimaAtmos v0.15.0 conserving, need Atmos #1803 test ci with Atmos fix ClimaCore up add refs to TD and CAP init with 0 atmos fluxes Atmos-commit dep perf project test project pip perf Manifest flame fix rm idealinsol true rm idealized insol increase allocs rm debug.jl clean climaatmos_init.jl
- Loading branch information
1 parent
9c35361
commit 81363a7
Showing
19 changed files
with
623 additions
and
597 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 85 additions & 50 deletions
135
experiments/AMIP/modular/components/atmosphere/climaatmos_init.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,133 @@ | ||
# atmos_init: for ClimaAtmos pre-AMIP interface | ||
import ClimaAtmos | ||
using ClimaAtmos: RRTMGPI | ||
import ClimaCoupler.FluxCalculator: compute_atmos_turbulent_fluxes! | ||
using ClimaCore: Fields.level, Geometry | ||
|
||
driver_file = joinpath(pkgdir(ClimaAtmos), "examples", "hybrid", "driver.jl") | ||
ENV["CI_PERF_SKIP_RUN"] = true | ||
try | ||
include(driver_file) | ||
catch err | ||
if err.error !== :exit_profile | ||
rethrow(err.error) | ||
end | ||
end | ||
# the clima atmos `integrator` is now defined | ||
struct ClimaAtmosSimulation{P, Y, D, I} <: AtmosModelSimulation | ||
params::P | ||
Y_init::Y | ||
domain::D | ||
integrator::I | ||
end | ||
function atmos_init(::Type{FT}, parsed_args::Dict) where {FT} | ||
|
||
function atmos_init(::Type{FT}, Y, integrator; params = nothing) where {FT} | ||
atmos_config = ClimaAtmos.AtmosConfig(argparse_settings(); parsed_args) | ||
integrator = ClimaAtmos.get_integrator(atmos_config) | ||
Y = integrator.u | ||
center_space = axes(Y.c.ρe_tot) | ||
face_space = axes(Y.f.w) | ||
face_space = axes(Y.f.u₃) | ||
spaces = (; center_space = center_space, face_space = face_space) | ||
if :ρe_int in propertynames(Y.c) | ||
@warn("Running with ρe_int in coupled mode is not tested yet.") | ||
end | ||
|
||
ClimaAtmosSimulation(params, Y, spaces, integrator) | ||
# set initial fluxes to zero | ||
@. integrator.p.sfc_conditions.ρ_flux_h_tot = Geometry.Covariant3Vector(FT(0.0)) | ||
@. integrator.p.sfc_conditions.ρ_flux_q_tot = Geometry.Covariant3Vector(FT(0.0)) | ||
@. integrator.p.sfc_conditions.ρ_flux_uₕ.components = zeros(axes(integrator.p.sfc_conditions.ρ_flux_uₕ.components)) | ||
parent(integrator.p.ᶠradiation_flux) .= parent(zeros(axes(integrator.p.ᶠradiation_flux))) | ||
|
||
ClimaAtmosSimulation(integrator.p.params, Y, spaces, integrator) | ||
end | ||
|
||
# required by the Interfacer | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:radiative_energy_flux}) = level(sim.integrator.p.ᶠradiation_flux, half) | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:radiative_energy_flux}) = | ||
Fields.level(sim.integrator.p.ᶠradiation_flux, half) | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:liquid_precipitation}) = | ||
sim.integrator.p.col_integrated_rain .+ sim.integrator.p.col_integrated_snow # all fallen snow melts for now | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:snow_precipitation}) = sim.integrator.p.col_integrated_snow .* FT(0) | ||
|
||
get_field(sim::ClimaAtmosSimulation, ::Val{:turbulent_energy_flux}) = sim.integrator.p.ρ_dif_flux_h_tot | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:turbulent_moisture_flux}) = sim.integrator.p.ρ_dif_flux_q_tot | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:turbulent_energy_flux}) = | ||
Geometry.WVector.(sim.integrator.p.sfc_conditions.ρ_flux_h_tot) | ||
get_field(sim::ClimaAtmosSimulation, ::Val{:turbulent_moisture_flux}) = | ||
Geometry.WVector.(sim.integrator.p.sfc_conditions.ρ_flux_q_tot) | ||
|
||
function update_field!(sim::ClimaAtmosSimulation, ::Val{:surface_temperature}, field) | ||
sim.integrator.p.radiation_model.surface_temperature .= RRTMGPI.field2array(field) | ||
parent(sim.integrator.p.T_sfc) .= parent(field) | ||
|
||
end | ||
function update_field!(sim::ClimaAtmosSimulation, ::Val{:albedo}, field) | ||
sim.integrator.p.radiation_model.diffuse_sw_surface_albedo .= | ||
reshape(RRTMGPI.field2array(field), 1, length(parent(field))) | ||
sim.integrator.p.radiation_model.direct_sw_surface_albedo .= | ||
reshape(RRTMGPI.field2array(field), 1, length(parent(field))) | ||
end | ||
function update_field!(sim::ClimaAtmosSimulation, ::Val{:roughness_momentum}, field) | ||
parent(sim.integrator.p.sfc_inputs.z0m) .= parent(field) | ||
end | ||
function update_field!(sim::ClimaAtmosSimulation, ::Val{:roughness_buoyancy}, field) | ||
parent(sim.integrator.p.sfc_inputs.z0b) .= parent(field) | ||
end | ||
|
||
step!(sim::ClimaAtmosSimulation, t) = step!(sim.integrator, t - sim.integrator.t, true) | ||
|
||
reinit!(sim::ClimaAtmosSimulation) = reinit!(sim.integrator) | ||
|
||
""" | ||
update_sim!(atmos_sim::ClimaAtmosSimulation, csf) | ||
Updates the surface fields for temperature and albedo. | ||
# Arguments | ||
- `atmos_sim`: [ClimaAtmosSimulation] containing an atmospheric model simulation object. | ||
- `csf`: [NamedTuple] containing coupler fields. | ||
""" | ||
function update_sim!(atmos_sim::ClimaAtmosSimulation, csf, turbulent_fluxes) | ||
update_field!(atmos_sim, Val(:albedo), csf.albedo) | ||
update_field!(atmos_sim, Val(:surface_temperature), csf.T_S) | ||
end | ||
|
||
|
||
# flux calculation borrowed from atmos | ||
""" | ||
CoupledMoninObukhov() | ||
A modified version of a Monin-Obukhov surface for the Coupler, see the link below for more information | ||
https://clima.github.io/SurfaceFluxes.jl/dev/SurfaceFluxes/#Monin-Obukhov-Similarity-Theory-(MOST) | ||
""" | ||
struct CoupledMoninObukhov end | ||
""" | ||
coupler_surface_setup(::CoupledMoninObukhov, p, csf_sfc = (; T = nothing, z0m = nothing, z0b = nothing, beta = nothing)) | ||
Sets up `surface_setup` as a `Fields.Field` or `SurfaceState`s. | ||
""" | ||
function coupler_surface_setup( | ||
::CoupledMoninObukhov, | ||
p; | ||
csf_sfc = (; T = nothing, z0m = nothing, z0b = nothing, beta = nothing), | ||
) | ||
|
||
surface_state(z0m, z0b, T, beta) = ClimaAtmos.SurfaceConditions.SurfaceState(; | ||
parameterization = ClimaAtmos.SurfaceConditions.MoninObukhov(; z0m, z0b), | ||
T, | ||
beta, | ||
) | ||
surface_state_field = @. surface_state(csf_sfc.z0m, csf_sfc.z0b, csf_sfc.T, csf_sfc.beta) | ||
return surface_state_field | ||
end | ||
|
||
""" | ||
compute_atmos_turbulent_fluxes!(atmos_sim::ClimaAtmosSimulation, csf) | ||
Computes turbulent surface fluxes using ClimaAtmos's `update_surface_conditions!`. This | ||
requires that we define a new temporary parameter Tuple, `new_p`, and save the new surface state | ||
in it. We do not want `new_p` to live in the atmospheric model permanently, because that would also | ||
trigger flux calculation during Atmos `step!`. We only want to trigger this once per coupling | ||
timestep from ClimaCoupler. | ||
""" | ||
function compute_atmos_turbulent_fluxes!(atmos_sim::ClimaAtmosSimulation, csf) | ||
# TODO: dependence on atmos will be removed | ||
|
||
thermo_params = CAP.thermodynamics_params(atmos_sim.integrator.p.params) | ||
p = atmos_sim.integrator.p | ||
|
||
# calculate turbulent fluxes on atmos grid and save in atmos cache | ||
update_field!(atmos_sim, Val(:surface_temperature), csf.T_S) | ||
coupler_sfc_setup = coupler_surface_setup( | ||
CoupledMoninObukhov(), | ||
p; | ||
csf_sfc = (; T = csf.T_S, z0m = csf.z0m_S, z0b = csf.z0b_S, beta = csf.beta), | ||
) | ||
|
||
if :z0b in propertynames(atmos_sim.integrator.p.surface_scheme) | ||
update_field!(atmos_sim, Val(:roughness_momentum), csf.z0m_S) | ||
update_field!(atmos_sim, Val(:roughness_buoyancy), csf.z0b_S) | ||
end | ||
p_names = propertynames(p) | ||
p_values = map(x -> x == :sfc_setup ? coupler_sfc_setup : getproperty(p, x), p_names) | ||
|
||
new_p = (; zip(p_names, p_values)...) | ||
|
||
ClimaAtmos.SurfaceConditions.update_surface_conditions!(atmos_sim.integrator.u, new_p, atmos_sim.integrator.t) | ||
|
||
p.sfc_conditions.ρ_flux_h_tot .= new_p.sfc_conditions.ρ_flux_h_tot | ||
p.sfc_conditions.ρ_flux_q_tot .= new_p.sfc_conditions.ρ_flux_q_tot | ||
p.sfc_conditions.ρ_flux_uₕ .= new_p.sfc_conditions.ρ_flux_uₕ | ||
|
||
Fields.bycolumn(axes(atmos_sim.integrator.p.ts_sfc)) do colidx | ||
ClimaAtmos.set_surface_thermo_state!( | ||
ClimaAtmos.Decoupled(), | ||
atmos_sim.integrator.p.surface_scheme.sfc_thermo_state_type, | ||
atmos_sim.integrator.p.ts_sfc[colidx], | ||
atmos_sim.integrator.p.T_sfc[colidx], | ||
Spaces.level(atmos_sim.integrator.p.ᶜts[colidx], 1), | ||
thermo_params, | ||
atmos_sim.integrator.t, | ||
) | ||
|
||
get_surface_fluxes!( | ||
atmos_sim.integrator.u, | ||
atmos_sim.integrator.p, | ||
atmos_sim.integrator.t, | ||
colidx, | ||
atmos_sim.integrator.p.atmos.vert_diff, | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.