diff --git a/experiments/ClimaEarth/components/atmosphere/climaatmos.jl b/experiments/ClimaEarth/components/atmosphere/climaatmos.jl index 371d44c5cc..78237bbb85 100644 --- a/experiments/ClimaEarth/components/atmosphere/climaatmos.jl +++ b/experiments/ClimaEarth/components/atmosphere/climaatmos.jl @@ -3,6 +3,7 @@ import StaticArrays import Statistics import LinearAlgebra import ClimaAtmos as CA +import ClimaAtmos: set_surface_albedo! import ClimaCore as CC import ClimaCore.Geometry: ⊗ import SurfaceFluxes as SF diff --git a/experiments/ClimaEarth/components/ocean/eisenman_seaice.jl b/experiments/ClimaEarth/components/ocean/eisenman_seaice.jl index 5b22a7a0fb..e4873ae4ef 100644 --- a/experiments/ClimaEarth/components/ocean/eisenman_seaice.jl +++ b/experiments/ClimaEarth/components/ocean/eisenman_seaice.jl @@ -11,6 +11,9 @@ import ClimaCoupler: Checkpointer, FluxCalculator, Interfacer Thermodynamic 0-layer, based on the Semtner 1979 model and later refined by Eisenmen 2009 and Zhang et al 2021. + +Note that Eisenman sea ice assumes gray radiation, no snow coverage, and +PartitionedStateFluxes for the surface flux calculation. """ struct EisenmanIceSimulation{P, Y, D, I} <: Interfacer.SeaIceModelSimulation params_ice::P @@ -80,8 +83,6 @@ function eisenman_seaice_init( integrator = SciMLBase.init(problem, ode_algo, dt = Float64(dt), saveat = Float64(saveat), adaptive = false) sim = EisenmanIceSimulation(params, Y, space, integrator) - @warn Interfacer.name(sim) * - " assumes gray radiation, no snow coverage, and PartitionedStateFluxes for the surface flux calculation." return sim end diff --git a/experiments/ClimaEarth/components/ocean/eisenman_seaice.md b/experiments/ClimaEarth/components/ocean/eisenman_seaice.md index d5f9530963..5d71504bab 100644 --- a/experiments/ClimaEarth/components/ocean/eisenman_seaice.md +++ b/experiments/ClimaEarth/components/ocean/eisenman_seaice.md @@ -4,6 +4,9 @@ Eisenman & Wettlaufer (2009) and Zhang et al. (2021). There are three prognostic variables, the height of ice (`h_i`), the ocean mixed layer depth (`T_ml`) and the surface air temperature (`T_s`). +Note that Eisenman sea ice assumes gray radiation, no snow coverage, and +PartitionedStateFluxes for the surface flux calculation. + ## Formulation In ice-covered conditions: $$ @@ -57,4 +60,4 @@ with $\Delta T = T_{melt} - T_{ml}^{t+1} $. # References - [Semtner 1976](https://journals.ametsoc.org/view/journals/phoc/6/3/1520-0485_1976_006_0379_amfttg_2_0_co_2.xml) - [Eisenman & Wettlaufer 2009](https://www.pnas.org/doi/full/10.1073/pnas.0806887106) -- [Zhang et al 2021](https://agupubs.onlinelibrary.wiley.com/doi/pdf/10.1029/2021MS002671), whose implementation can be found on [GitHub](https://github.com/sally-xiyue/fms-idealized/blob/sea_ice_v1.0/exp/sea_ice/srcmods/mixed_layer.f90) \ No newline at end of file +- [Zhang et al 2021](https://agupubs.onlinelibrary.wiley.com/doi/pdf/10.1029/2021MS002671), whose implementation can be found on [GitHub](https://github.com/sally-xiyue/fms-idealized/blob/sea_ice_v1.0/exp/sea_ice/srcmods/mixed_layer.f90) diff --git a/experiments/ClimaEarth/components/ocean/slab_ocean.jl b/experiments/ClimaEarth/components/ocean/slab_ocean.jl index e1db9d22d3..da61f27ab6 100644 --- a/experiments/ClimaEarth/components/ocean/slab_ocean.jl +++ b/experiments/ClimaEarth/components/ocean/slab_ocean.jl @@ -36,8 +36,6 @@ Base.@kwdef struct OceanSlabParameters{FT <: AbstractFloat} evolving_switch::FT = 1 # switch to turn off the evolution of the ocean temperature [0 or 1] end -Interfacer.name(::SlabOceanSimulation) = "SlabOceanSimulation" - """ slab_ocean_space_init(space, params) diff --git a/test/diagnostics_tests.jl b/test/diagnostics_tests.jl index cc15f874b1..e1f72c4bc4 100644 --- a/test/diagnostics_tests.jl +++ b/test/diagnostics_tests.jl @@ -1,7 +1,7 @@ #= Unit tests for ClimaCoupler Diagnostics module =# -import Test: @test, @testset +import Test: @test, @testset, @test_warn import ClimaComms @static pkgversion(ClimaComms) >= v"0.6" && ClimaComms.@import_required_backends import Dates @@ -58,7 +58,7 @@ for FT in (Float32, Float64) @test cs.diagnostics[1].field_vector[1] == expected_results[c_i] end - @test isnothing(Diagnostics.get_var(cs, Val(:z))) + @test_warn "Variable Val{:z}() is not defined." Diagnostics.get_var(cs, Val(:z)) end end diff --git a/test/field_exchanger_tests.jl b/test/field_exchanger_tests.jl index cd0ec2ea9f..aae861449f 100644 --- a/test/field_exchanger_tests.jl +++ b/test/field_exchanger_tests.jl @@ -17,7 +17,7 @@ Interfacer.get_field(sim::DummySimulation, ::Val{:liquid_precipitation}) = sim.c Interfacer.get_field(sim::DummySimulation, ::Val{:snow_precipitation}) = sim.cache.snow_precipitation function FluxCalculator.calculate_surface_air_density(atmos_sim::DummySimulation, T_S::CC.Fields.Field) - FT = eltype(T_S) + FT = CC.Spaces.undertype(axes(T_S)) return T_S .* FT(0.0) .+ FT(1.0) end @@ -31,26 +31,25 @@ struct TestSurfaceSimulation2{C} <: Interfacer.SurfaceModelSimulation end Interfacer.get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:surface_temperature}) = - sim.cache_field .* eltype(sim.cache_field)(1.0) + sim.cache_field Interfacer.get_field( sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Union{Val{:surface_direct_albedo}, Val{:surface_diffuse_albedo}}, -) = sim.cache_field .* eltype(sim.cache_field)(1.0) +) = sim.cache_field Interfacer.get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:roughness_momentum}) = - sim.cache_field .* eltype(sim.cache_field)(1.0) + sim.cache_field Interfacer.get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:roughness_buoyancy}) = - sim.cache_field .* eltype(sim.cache_field)(1.0) -Interfacer.get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:beta}) = - sim.cache_field .* eltype(sim.cache_field)(1.0) + sim.cache_field +Interfacer.get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:beta}) = sim.cache_field -Interfacer.get_field(sim::TestSurfaceSimulation1, ::Val{:area_fraction}) = sim.cache_field .* eltype(sim.cache_field)(0) +Interfacer.get_field(sim::TestSurfaceSimulation1, ::Val{:area_fraction}) = sim.cache_field .* 0 Interfacer.get_field(sim::TestSurfaceSimulation2, ::Val{:area_fraction}) = - sim.cache_field .* eltype(sim.cache_field)(0.5) + sim.cache_field .* CC.Spaces.undertype(axes(sim.cache_field))(0.5) Interfacer.get_field(sim::Union{TestSurfaceSimulation1, TestSurfaceSimulation2}, ::Val{:surface_humidity}) = - sim.cache_field .* eltype(sim.cache_field)(0) + sim.cache_field .* 0 Interfacer.get_field(sim::Union{TestSurfaceSimulation2, TestSurfaceSimulation2}, ::Val{:surface_humidity}) = - sim.cache_field .* eltype(sim.cache_field)(0) + sim.cache_field .* 0 Interfacer.reinit!(::TestSurfaceSimulation1) = nothing Interfacer.step!(::TestSurfaceSimulation1, _) = nothing @@ -69,6 +68,7 @@ function Interfacer.update_field!(sim::TestAtmosSimulation, ::Val{:roughness_mom parent(sim.cache.roughness_momentum) .= parent(field) end +Interfacer.update_field!(sim::TestAtmosSimulation, ::Val{:surface_temperature}, field) = nothing Interfacer.update_field!(sim::TestAtmosSimulation, ::Val{:roughness_buoyancy}, field) = nothing Interfacer.update_field!(sim::TestAtmosSimulation, ::Val{:beta}, field) = nothing @@ -77,7 +77,7 @@ struct TestSurfaceSimulationLand{C} <: Interfacer.SurfaceModelSimulation cache::C end function Interfacer.get_field(sim::TestSurfaceSimulationLand, ::Val{:area_fraction}) - FT = eltype(sim.cache.turbulent_energy_flux) + FT = CC.Spaces.undertype(axes(sim.cache.turbulent_energy_flux)) return FT(0.5) end function Interfacer.update_field!(sim::TestSurfaceSimulationLand, ::Val{:turbulent_energy_flux}, field) diff --git a/test/flux_calculator_tests.jl b/test/flux_calculator_tests.jl index 40c81b2bf6..83d614aa2a 100644 --- a/test/flux_calculator_tests.jl +++ b/test/flux_calculator_tests.jl @@ -32,6 +32,7 @@ struct TestAtmos{P, Y, D, I} <: Interfacer.AtmosModelSimulation domain::D integrator::I end +Interfacer.name(sim::TestAtmos) = "TestAtmos" struct TestAtmos2 <: Interfacer.AtmosModelSimulation end Interfacer.name(sim::TestAtmos2) = "TestAtmos2" @@ -71,6 +72,7 @@ struct TestOcean{M, Y, D, I} <: Interfacer.SurfaceModelSimulation domain::D integrator::I end +Interfacer.name(sim::TestOcean) = "TestOcean" Interfacer.get_field(sim::TestOcean, ::Val{:surface_temperature}) = sim.integrator.T Interfacer.get_field(sim::TestOcean, ::Val{:air_humidity}) = sim.integrator.p.q @@ -102,6 +104,7 @@ struct DummySurfaceSimulation3{M, Y, D, I} <: Interfacer.SurfaceModelSimulation domain::D integrator::I end +Interfacer.name(sim::DummySurfaceSimulation3) = "DummySurfaceSimulation3" Interfacer.get_field(sim::DummySurfaceSimulation3, ::Val{:surface_temperature}) = sim.integrator.T Interfacer.get_field(sim::DummySurfaceSimulation3, ::Val{:area_fraction}) = sim.integrator.p.area_fraction @@ -109,7 +112,11 @@ Interfacer.get_field(sim::DummySurfaceSimulation3, ::Val{:heat_transfer_coeffici Interfacer.get_field(sim::DummySurfaceSimulation3, ::Val{:drag_coefficient}) = sim.integrator.p.Cd Interfacer.get_field(sim::DummySurfaceSimulation3, ::Val{:beta}) = sim.integrator.p.beta -function surface_thermo_state(sim::DummySurfaceSimulation3, thermo_params::ThermodynamicsParameters, thermo_state_int) +function FluxCalculator.surface_thermo_state( + sim::DummySurfaceSimulation3, + thermo_params::ThermodynamicsParameters, + thermo_state_int, +) T_sfc = Interfacer.get_field(sim, Val(:surface_temperature)) FT = eltype(T_sfc)