From f68a66adeb92c24800dc255d8bb271446a058162 Mon Sep 17 00:00:00 2001 From: Julia Sloan Date: Mon, 1 Apr 2024 14:24:58 -0700 Subject: [PATCH] move SurfaceStub to its own file --- docs/src/interfacer.md | 3 +- src/FieldExchanger.jl | 22 -------- src/FluxCalculator.jl | 2 - src/Interfacer.jl | 61 ++-------------------- src/surface_stub.jl | 96 +++++++++++++++++++++++++++++++++++ test/field_exchanger_tests.jl | 6 ++- test/interfacer_tests.jl | 10 ++++ 7 files changed, 115 insertions(+), 85 deletions(-) create mode 100644 src/surface_stub.jl diff --git a/docs/src/interfacer.md b/docs/src/interfacer.md index 1e237d5cdd..be170d284d 100644 --- a/docs/src/interfacer.md +++ b/docs/src/interfacer.md @@ -163,7 +163,8 @@ module docs for more information. - `SurfaceStub` is a `SurfaceModelSimulation`, but it only contains required data in `.cache`, e.g., for the calculation of surface fluxes through a prescribed surface state. The above -adapter functions are already predefined for `SurfaceStub`, with +adapter functions are already predefined for `SurfaceStub` +in the `surface_stub.jl` file, with the cache variables specified as: ``` get_field(sim::SurfaceStub, ::Val{:air_density}) = sim.cache.ρ_sfc diff --git a/src/FieldExchanger.jl b/src/FieldExchanger.jl index c38558415f..1be83d19ad 100644 --- a/src/FieldExchanger.jl +++ b/src/FieldExchanger.jl @@ -148,14 +148,6 @@ function update_sim!(sim::Interfacer.SurfaceModelSimulation, csf, turbulent_flux Interfacer.update_field!(sim, Val(:snow_precipitation), csf.P_snow) end -""" - update_sim!(::SurfaceStub, csf, area_fraction) - -The stub surface simulation only updates the air density (needed for the turbulent flux calculation). -""" -function update_sim!(sim::Interfacer.SurfaceStub, csf, area_fraction) - Interfacer.update_field!(sim, Val(:air_density), csf.ρ_sfc) -end """ update_model_sims!(model_sims, csf, turbulent_fluxes) @@ -192,13 +184,6 @@ function reinit_model_sims!(model_sims) end end -""" - reinit!(cs::SurfaceStub) - -The stub surface simulation is not updated by this function. Extends `SciMLBase.reinit!`. -""" -reinit!(::Interfacer.SurfaceStub) = nothing - """ step_model_sims!(model_sims, t) @@ -214,11 +199,4 @@ function step_model_sims!(model_sims, t) end end -""" - step!(::SurfaceStub, t) - -The stub surface simulation is not updated by this function. Extends `SciMLBase.step!`. -""" -step!(::Interfacer.SurfaceStub, _) = nothing - end # module diff --git a/src/FluxCalculator.jl b/src/FluxCalculator.jl index b8a924cc00..1858960fdc 100644 --- a/src/FluxCalculator.jl +++ b/src/FluxCalculator.jl @@ -377,8 +377,6 @@ function update_turbulent_fluxes_point!( ) end -update_turbulent_fluxes_point!(sim::Interfacer.SurfaceStub, fields::NamedTuple, colidx::Fields.ColumnIndex) = nothing - """ differentiate_turbulent_fluxes!(sim::Interfacer.SurfaceModelSimulation, args) diff --git a/src/Interfacer.jl b/src/Interfacer.jl index 530b123d01..3e8e36dd2d 100644 --- a/src/Interfacer.jl +++ b/src/Interfacer.jl @@ -12,7 +12,6 @@ export CoupledSimulation, ComponentModelSimulation, AtmosModelSimulation, SurfaceModelSimulation, - SurfaceStub, SeaIceModelSimulation, LandModelSimulation, OceanModelSimulation, @@ -163,41 +162,6 @@ get_field(sim::ComponentModelSimulation, val::Val) = get_field_error(sim, val) get_field_error(sim, val::Val{X}) where {X} = error("undefined field `$X` for " * name(sim)) - -""" - SurfaceStub - -On object containing simulation-like info, used as a stub or for prescribed data. -""" -struct SurfaceStub{I} <: SurfaceModelSimulation - cache::I -end - -""" - stub_init(cache) - -Initialization function for SurfaceStub simulation type. -""" -stub_init(cache) = SurfaceStub(cache) - -""" - get_field(::SurfaceStub, ::Val) - -A getter function, that should not allocate. If undefined, it returns a descriptive error. -""" -get_field(sim::SurfaceStub, ::Val{:air_density}) = sim.cache.ρ_sfc -get_field(sim::SurfaceStub, ::Val{:area_fraction}) = sim.cache.area_fraction -get_field(sim::SurfaceStub, ::Val{:beta}) = sim.cache.beta -get_field(sim::SurfaceStub, ::Val{:energy}) = nothing -get_field(sim::SurfaceStub, ::Val{:roughness_buoyancy}) = sim.cache.z0b -get_field(sim::SurfaceStub, ::Val{:roughness_momentum}) = sim.cache.z0m -get_field(sim::SurfaceStub, ::Val{:surface_direct_albedo}) = sim.cache.α_direct -get_field(sim::SurfaceStub, ::Val{:surface_diffuse_albedo}) = sim.cache.α_diffuse -get_field(sim::SurfaceStub, ::Val{:surface_humidity}) = - TD.q_vap_saturation_generic.(sim.cache.thermo_params, sim.cache.T_sfc, sim.cache.ρ_sfc, sim.cache.phase) -get_field(sim::SurfaceStub, ::Val{:surface_temperature}) = sim.cache.T_sfc -get_field(sim::SurfaceStub, ::Val{:water}) = nothing - """ get_field(::ComponentModelSimulation, ::Val, colidx::Fields.ColumnIndex) @@ -256,33 +220,14 @@ update_field!( update_field_warning(sim, val::Val{X}) where {X} = @warn("`update_field!` is not extended for the `$X` field of " * name(sim) * ": skipping update.", maxlog = 1) -""" - update_field!(sim::SurfaceStub, ::Val{:area_fraction}, field::Fields.Field) - -Updates the specified value in the cache of `SurfaceStub`. -""" -function update_field!(sim::SurfaceStub, ::Val{:area_fraction}, field::Fields.Field) - sim.cache.area_fraction .= field -end -function update_field!(sim::SurfaceStub, ::Val{:surface_temperature}, field::Fields.Field) - sim.cache.T_sfc .= field -end -function update_field!(sim::SurfaceStub, ::Val{:air_density}, field) - parent(sim.cache.ρ_sfc) .= parent(field) -end -function update_field!(sim::SurfaceStub, ::Val{:surface_direct_albedo}, field::Fields.Field) - sim.cache.α_direct .= field -end -function update_field!(sim::SurfaceStub, ::Val{:surface_diffuse_albedo}, field::Fields.Field) - sim.cache.α_diffuse .= field -end - """ name(::ComponentModelSimulation) Returns simulation name, if defined, or `Unnamed` if not. """ name(::ComponentModelSimulation) = "Unnamed" -name(::SurfaceStub) = "SurfaceStub" + +# Include file containing the surface stub simulation type. +include("surface_stub.jl") end # module diff --git a/src/surface_stub.jl b/src/surface_stub.jl new file mode 100644 index 0000000000..55525c2f15 --- /dev/null +++ b/src/surface_stub.jl @@ -0,0 +1,96 @@ +export SurfaceStub + +""" + SurfaceStub + +On object containing simulation-like info, used as a stub or for prescribed data. +""" +struct SurfaceStub{I} <: SurfaceModelSimulation + cache::I +end + +""" + stub_init(cache) + +Initialization function for SurfaceStub simulation type. +""" +stub_init(cache) = SurfaceStub(cache) + +## Extensions of Interfacer.jl functions + +""" + get_field(::SurfaceStub, ::Val) + +A getter function, that should not allocate. If undefined, it returns a descriptive error. +""" +get_field(sim::SurfaceStub, ::Val{:air_density}) = sim.cache.ρ_sfc +get_field(sim::SurfaceStub, ::Val{:area_fraction}) = sim.cache.area_fraction +get_field(sim::SurfaceStub, ::Val{:beta}) = sim.cache.beta +get_field(sim::SurfaceStub, ::Val{:energy}) = nothing +get_field(sim::SurfaceStub, ::Val{:roughness_buoyancy}) = sim.cache.z0b +get_field(sim::SurfaceStub, ::Val{:roughness_momentum}) = sim.cache.z0m +get_field(sim::SurfaceStub, ::Val{:surface_direct_albedo}) = sim.cache.α_direct +get_field(sim::SurfaceStub, ::Val{:surface_diffuse_albedo}) = sim.cache.α_diffuse +get_field(sim::SurfaceStub, ::Val{:surface_humidity}) = + TD.q_vap_saturation_generic.(sim.cache.thermo_params, sim.cache.T_sfc, sim.cache.ρ_sfc, sim.cache.phase) +get_field(sim::SurfaceStub, ::Val{:surface_temperature}) = sim.cache.T_sfc +get_field(sim::SurfaceStub, ::Val{:water}) = nothing + +""" + update_field!(sim::SurfaceStub, ::Val{:area_fraction}, field::Fields.Field) + +Updates the specified value in the cache of `SurfaceStub`. +""" +function update_field!(sim::SurfaceStub, ::Val{:area_fraction}, field::Fields.Field) + sim.cache.area_fraction .= field +end +function update_field!(sim::SurfaceStub, ::Val{:surface_temperature}, field::Fields.Field) + sim.cache.T_sfc .= field +end +function update_field!(sim::SurfaceStub, ::Val{:air_density}, field) + parent(sim.cache.ρ_sfc) .= parent(field) +end +function update_field!(sim::SurfaceStub, ::Val{:surface_direct_albedo}, field::Fields.Field) + sim.cache.α_direct .= field +end +function update_field!(sim::SurfaceStub, ::Val{:surface_diffuse_albedo}, field::Fields.Field) + sim.cache.α_diffuse .= field +end + +""" + name(::ComponentModelSimulation) + +Returns simulation name, if defined, or `Unnamed` if not. +""" +name(::SurfaceStub) = "SurfaceStub" + + +## Extensions of FieldExchanger.jl functions + +""" + update_sim!(::SurfaceStub, csf, area_fraction) + +The stub surface simulation only updates the air density (needed for the turbulent flux calculation). +""" +function update_sim!(sim::Interfacer.SurfaceStub, csf, area_fraction) + Interfacer.update_field!(sim, Val(:air_density), csf.ρ_sfc) +end + +""" + reinit!(cs::SurfaceStub) + +The stub surface simulation is not updated by this function. Extends `SciMLBase.reinit!`. +""" +reinit!(::Interfacer.SurfaceStub) = nothing + +""" + step!(::SurfaceStub, t) + +The stub surface simulation is not updated by this function. Extends `SciMLBase.step!`. +""" +step!(::Interfacer.SurfaceStub, _) = nothing + + +## Extensions of FluxCalculator.jl functions + +update_turbulent_fluxes_point!(sim::Interfacer.SurfaceStub, fields::NamedTuple, colidx::Fields.ColumnIndex) = nothing diff --git a/test/field_exchanger_tests.jl b/test/field_exchanger_tests.jl index d3fca071a6..1db1c56c37 100644 --- a/test/field_exchanger_tests.jl +++ b/test/field_exchanger_tests.jl @@ -60,6 +60,8 @@ get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:sur get_field(sim::Union{TestSurfaceSimulation2, TestSurfaceSimulation2}, ::Val{:surface_humidity}) = sim.cache_field .* eltype(sim.cache_field)(0) +reinit!(::TestSurfaceSimulation1) = nothing +step!(::TestSurfaceSimulation1, _) = nothing # atmos sim struct TestAtmosSimulation{C} <: AtmosModelSimulation @@ -239,10 +241,10 @@ for FT in (Float32, Float64) end end @testset "reinit_model_sims! for FT=$FT" begin - @test reinit_model_sims!((; stub = SurfaceStub(FT(0)))) == nothing + @test reinit_model_sims!((; stub = TestSurfaceSimulation1(FT(0)))) == nothing end @testset "step_model_sims! for FT=$FT" begin - @test step_model_sims!((; stub = SurfaceStub(FT(0))), 1) == nothing + @test step_model_sims!((; stub = TestSurfaceSimulation1(FT(0))), 1) == nothing end end diff --git a/test/interfacer_tests.jl b/test/interfacer_tests.jl index ef09cfdc4f..dac382407b 100644 --- a/test/interfacer_tests.jl +++ b/test/interfacer_tests.jl @@ -231,6 +231,16 @@ end end end +@testset "SurfaceStub reinit!" begin + FT = Float32 + @test reinit!(SurfaceStub(FT(0))) == nothing +end + +@testset "SurfaceStub step!" begin + FT = Float32 + @test step!(SurfaceStub(FT(0)), 1) == nothing +end + # # Test that update_field! gives correct warnings for unextended fields # for value in ( # :air_density,