Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hooks to overwrite atmos albedo #702

Merged
merged 1 commit into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/fluxcalculator.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Fluxes over a heterogeneous surface (e.g., from a gridpoint where atmospheric ce
ClimaCoupler.FluxCalculator.update_turbulent_fluxes_point!
ClimaCoupler.FluxCalculator.extrapolate_ρ_to_sfc
ClimaCoupler.FluxCalculator.surface_thermo_state
ClimaCoupler.FluxCalculator.water_albedo_from_atmosphere!
```

## FieldExchanger Internal Functions
Expand Down
14 changes: 8 additions & 6 deletions docs/src/interfacer.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ following properties:
| Coupler name | Description | Units |
|-------------------|-------------|-------|
| `co2` | global mean co2 | ppm |
| `surface_albedo` | bulk surface albedo over the whole surface space | |
| `surface_direct_albedo` | bulk direct surface albedo over the whole surface space | |
| `surface_diffuse_albedo` | bulk diffuse surface albedo over the whole surface space | |
| `surface_temperature` | temperature over the combined surface space | K |
| `turbulent_fluxes` | turbulent fluxes (note: only required when using `PartitionedStateFluxes` option - see our `FluxCalculator` module docs for more information) | W m^-2 |

- `calculate_surface_air_density(atmos_sim::Interfacer.AtmosModelSimulation, T_S::Fields.Field)`:
- `calculate_surface_air_density(atmos_sim::Interfacer.AtmosModelSimulation, T_S::ClimaCore.Fields.Field)`:
A function to return the air density of the atmosphere simulation
extrapolated to the surface, with units of [kg m^-3].

Expand All @@ -124,7 +125,8 @@ for the following properties:
| `beta` | factor that scales evaporation based on its estimated level of saturation | |
| `roughness_buoyancy` | aerodynamic roughness length for buoyancy | m |
| `roughness_momentum` | aerodynamic roughness length for momentum | m |
| `surface_albedo` | bulk surface albedo | |
| `surface_direct albedo` | bulk direct surface albedo | |
| `surface_diffuse albedo` | bulk diffuse surface albedo | |
| `surface_humidity` | surface humidity | kg kg^-1 |
| `surface_temperature` | surface temperature | K |

Expand Down Expand Up @@ -170,7 +172,7 @@ 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_albedo}) = sim.cache.α
get_field(sim::SurfaceStub, ::Union{Val{:surface_direct_albedo}, Val{:surface_diffuse_albedo}}) = sim.cache.α
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
Expand All @@ -180,10 +182,10 @@ and with the corresponding `update_field!` functions
function update_field!(sim::SurfaceStub, ::Val{:air_density}, field)
sim.cache.ρ_sfc .= field
end
function update_field!(sim::SurfaceStub, ::Val{:area_fraction}, field::Fields.Field)
function update_field!(sim::SurfaceStub, ::Val{:area_fraction}, field::ClimaCore.Fields.Field)
sim.cache.area_fraction .= field
end
function update_field!(sim::SurfaceStub, ::Val{:surface_temperature}, field::Fields.Field)
function update_field!(sim::SurfaceStub, ::Val{:surface_temperature}, field::ClimaCore.Fields.Field)
sim.cache.T_sfc .= field
end
```
Expand Down
47 changes: 26 additions & 21 deletions experiments/AMIP/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ version = "0.4.2"

[[deps.BandedMatrices]]
deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"]
git-tree-sha1 = "fe7ed7b33416db994f706f66e31bbd1b378f71b7"
git-tree-sha1 = "c946c5014cf4cdbfacacb363b110e7bffba3e742"
uuid = "aae01518-5342-5314-be14-df237901396f"
version = "1.6.0"
version = "1.6.1"
weakdeps = ["SparseArrays"]

[deps.BandedMatrices.extensions]
Expand Down Expand Up @@ -397,9 +397,9 @@ weakdeps = ["ClimaParams"]

[[deps.ClimaParams]]
deps = ["DocStringExtensions", "TOML", "Test"]
git-tree-sha1 = "ec67949db856e01df4cbf7d6ddafefeda02f93ee"
git-tree-sha1 = "1a3d2455fff201bcf130bbd5a71ac16fc3c21fd1"
uuid = "5c42b081-d73a-476f-9059-fd94b934656c"
version = "0.10.3"
version = "0.10.4"

[[deps.ClimaTimeSteppers]]
deps = ["ClimaComms", "Colors", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "KernelAbstractions", "Krylov", "LinearAlgebra", "LinearOperators", "NVTX", "SciMLBase", "StaticArrays"]
Expand Down Expand Up @@ -500,7 +500,7 @@ weakdeps = ["Dates", "LinearAlgebra"]
[[deps.CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
version = "1.1.0+0"
version = "1.0.5+1"

[[deps.CompositionsBase]]
git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad"
Expand Down Expand Up @@ -850,9 +850,9 @@ version = "0.3.1"

[[deps.FileIO]]
deps = ["Pkg", "Requires", "UUIDs"]
git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc"
git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322"
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
version = "1.16.2"
version = "1.16.3"

[[deps.FilePaths]]
deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"]
Expand Down Expand Up @@ -905,9 +905,9 @@ version = "0.8.4"

[[deps.Flux]]
deps = ["Adapt", "ChainRulesCore", "Compat", "Functors", "LinearAlgebra", "MLUtils", "MacroTools", "NNlib", "OneHotArrays", "Optimisers", "Preferences", "ProgressLogging", "Random", "Reexport", "SparseArrays", "SpecialFunctions", "Statistics", "Zygote"]
git-tree-sha1 = "5a626d6ef24ae0a8590c22dc12096fb65eb66325"
git-tree-sha1 = "502d0232ec6430d40b6e5b57637333f32192592e"
uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c"
version = "0.14.13"
version = "0.14.14"

[deps.Flux.extensions]
FluxAMDGPUExt = "AMDGPU"
Expand Down Expand Up @@ -1127,9 +1127,9 @@ version = "1.3.14+0"

[[deps.GridLayoutBase]]
deps = ["GeometryBasics", "InteractiveUtils", "Observables"]
git-tree-sha1 = "af13a277efd8a6e716d79ef635d5342ccb75be61"
git-tree-sha1 = "6f93a83ca11346771a93bbde2bdad2f65b61498f"
uuid = "3955a311-db13-416c-9275-1d80ed98e5e9"
version = "0.10.0"
version = "0.10.2"

[[deps.Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
Expand All @@ -1154,9 +1154,9 @@ version = "1.14.3+1"

[[deps.HTTP]]
deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"]
git-tree-sha1 = "db864f2d91f68a5912937af80327d288ea1f3aee"
git-tree-sha1 = "995f762e0182ebc50548c434c171a5bb6635f8e4"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "1.10.3"
version = "1.10.4"

[[deps.HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"]
Expand Down Expand Up @@ -1430,9 +1430,9 @@ version = "3.0.0+1"

[[deps.LLVM]]
deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"]
git-tree-sha1 = "ddab4d40513bce53c8e3157825e245224f74fae7"
git-tree-sha1 = "7c6650580b4c3169d9905858160db895bff6d2e2"
uuid = "929cbde3-209d-540e-8aea-75f648917ca0"
version = "6.6.0"
version = "6.6.1"
weakdeps = ["BFloat16s"]

[deps.LLVM.extensions]
Expand Down Expand Up @@ -1926,7 +1926,7 @@ version = "0.3.24+0"
[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
version = "0.3.23+4"
version = "0.3.23+2"

[[deps.OpenEXR]]
deps = ["Colors", "FileIO", "OpenEXR_jll"]
Expand Down Expand Up @@ -2405,10 +2405,10 @@ uuid = "76ed43ae-9a5d-5a62-8c75-30186b810ce8"
version = "3.45.0+0"

[[deps.SciMLBase]]
deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"]
git-tree-sha1 = "3a281a9fce9cd62b849d7f16e412933a5fe755cb"
deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"]
git-tree-sha1 = "dce2d07e3519cb7817f2d89a7978c13fef30be87"
uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
version = "2.29.0"
version = "2.30.0"

[deps.SciMLBase.extensions]
SciMLBaseChainRulesCoreExt = "ChainRulesCore"
Expand All @@ -2435,6 +2435,11 @@ git-tree-sha1 = "10499f619ef6e890f3f4a38914481cc868689cd5"
uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961"
version = "0.3.8"

[[deps.SciMLStructures]]
git-tree-sha1 = "5833c10ce83d690c124beedfe5f621b50b02ba4d"
uuid = "53ae85a6-f571-4167-b2af-e1d143709226"
version = "1.1.0"

[[deps.Scratch]]
deps = ["Dates"]
git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386"
Expand Down Expand Up @@ -2791,9 +2796,9 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
version = "0.5.23"

[[deps.TranscodingStreams]]
git-tree-sha1 = "3caa21522e7efac1ba21834a03734c57b4611c7e"
git-tree-sha1 = "a09c933bebed12501890d8e92946bbab6a1690f1"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.10.4"
version = "0.10.5"
weakdeps = ["Random", "Test"]

[deps.TranscodingStreams.extensions]
Expand Down
51 changes: 46 additions & 5 deletions experiments/AMIP/components/atmosphere/climaatmos.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# atmos_init: for ClimaAtmos pre-AMIP interface
using StaticArrays
using Statistics: mean
using LinearAlgebra: norm

import ClimaAtmos as CA
import ClimaAtmos: CT1, CT2, CT12, CT3, C3, C12, unit_basis_vector_data, ⊗
Expand All @@ -14,7 +15,8 @@ import ClimaCoupler.FluxCalculator:
calculate_surface_air_density,
PartitionedStateFluxes,
extrapolate_ρ_to_sfc,
get_surface_params
get_surface_params,
water_albedo_from_atmosphere!
import ClimaCoupler.Interfacer: get_field, update_field!, name
import ClimaCoupler.Checkpointer: get_model_prog_state
import ClimaCoupler.FieldExchanger: update_sim!, step!, reinit!
Expand All @@ -35,6 +37,7 @@ name(::ClimaAtmosSimulation) = "ClimaAtmosSimulation"

function atmos_init(::Type{FT}, atmos_config_dict::Dict) where {FT}
# By passing `parsed_args` to `AtmosConfig`, `parsed_args` overwrites the default atmos config
atmos_config_dict["surface_albedo"] = "CouplerAlbedo"
atmos_config = CA.AtmosConfig(atmos_config_dict)
simulation = CA.get_simulation(atmos_config)
(; integrator) = simulation
Expand Down Expand Up @@ -171,13 +174,16 @@ function update_field!(sim::ClimaAtmosSimulation, ::Val{:surface_temperature}, c
sim.integrator.p.radiation.radiation_model.surface_temperature .= CA.RRTMGPI.field2array(csf.T_S)
end

function update_field!(sim::ClimaAtmosSimulation, ::Val{:surface_albedo}, field)
sim.integrator.p.radiation.radiation_model.diffuse_sw_surface_albedo .=
reshape(CA.RRTMGPI.field2array(field), 1, length(parent(field)))
function update_field!(sim::ClimaAtmosSimulation, ::Val{:surface_direct_albedo}, field)
sim.integrator.p.radiation.radiation_model.direct_sw_surface_albedo .=
reshape(CA.RRTMGPI.field2array(field), 1, length(parent(field)))
end

function update_field!(sim::ClimaAtmosSimulation, ::Val{:surface_diffuse_albedo}, field)
sim.integrator.p.radiation.radiation_model.diffuse_sw_surface_albedo .=
reshape(CA.RRTMGPI.field2array(field), 1, length(parent(field)))
end

function update_field!(sim::ClimaAtmosSimulation, ::Val{:turbulent_fluxes}, fields)
(; F_turb_energy, F_turb_moisture, F_turb_ρτxz, F_turb_ρτyz) = fields

Expand Down Expand Up @@ -210,7 +216,8 @@ step!(sim::ClimaAtmosSimulation, t) = step!(sim.integrator, t - sim.integrator.t
reinit!(sim::ClimaAtmosSimulation) = reinit!(sim.integrator)

function update_sim!(atmos_sim::ClimaAtmosSimulation, csf, turbulent_fluxes)
update_field!(atmos_sim, Val(:surface_albedo), csf.surface_albedo)
update_field!(atmos_sim, Val(:surface_direct_albedo), csf.surface_direct_albedo)
update_field!(atmos_sim, Val(:surface_diffuse_albedo), csf.surface_diffuse_albedo)
update_field!(atmos_sim, Val(:surface_temperature), csf)

if turbulent_fluxes isa PartitionedStateFluxes
Expand Down Expand Up @@ -384,3 +391,37 @@ function dss_state!(sim::ClimaAtmosSimulation)
ClimaCore.Spaces.weighted_dss!(field, buffer)
end
end

"""
water_albedo_from_atmosphere!(atmos_sim::ClimaAtmosSimulation, direct_albedo::ClimaCore.Fields.Field, diffuse_albedo::ClimaCore.Fields.Field)

Extension to calculate the water surface albedo from wind speed and insolation. It can be used for prescribed ocean and lakes.
"""
function water_albedo_from_atmosphere!(
LenkaNovak marked this conversation as resolved.
Show resolved Hide resolved
atmos_sim::ClimaAtmosSimulation,
direct_albedo::ClimaCore.Fields.Field,
diffuse_albedo::ClimaCore.Fields.Field,
)

Y = atmos_sim.integrator.u
p = atmos_sim.integrator.p
t = atmos_sim.integrator.t

radiation_model = atmos_sim.integrator.p.radiation.radiation_model
FT = eltype(Y)
λ = FT(0) # spectral wavelength (not used for now)

# update for current zenith angle
CA.set_insolation_variables!(Y, p, t)

bottom_coords = ClimaCore.Fields.coordinate_field(ClimaCore.Spaces.level(Y.c, 1))
μ = CA.RRTMGPI.array2field(radiation_model.cos_zenith, axes(bottom_coords))
FT = eltype(atmos_sim.integrator.u)
α_model = CA.RegressionFunctionAlbedo{FT}()


# set the direct and diffuse surface albedos
direct_albedo .= CA.surface_albedo_direct(α_model).(λ, μ, norm.(ClimaCore.Fields.level(Y.c.uₕ, 1)))
diffuse_albedo .= CA.surface_albedo_diffuse(α_model).(λ, μ, norm.(ClimaCore.Fields.level(Y.c.uₕ, 1)))

end
4 changes: 3 additions & 1 deletion experiments/AMIP/components/land/climaland_bucket.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ get_field(sim::BucketSimulation, ::Val{:beta}) =
ClimaLand.surface_evaporative_scaling(sim.model, sim.integrator.u, sim.integrator.p)
get_field(sim::BucketSimulation, ::Val{:roughness_buoyancy}) = sim.model.parameters.z_0b
get_field(sim::BucketSimulation, ::Val{:roughness_momentum}) = sim.model.parameters.z_0m
get_field(sim::BucketSimulation, ::Val{:surface_albedo}) =
get_field(sim::BucketSimulation, ::Val{:surface_direct_albedo}) =
ClimaLand.surface_albedo(sim.model, sim.integrator.u, sim.integrator.p)
get_field(sim::BucketSimulation, ::Val{:surface_diffuse_albedo}) =
ClimaLand.surface_albedo(sim.model, sim.integrator.u, sim.integrator.p)
get_field(sim::BucketSimulation, ::Val{:surface_humidity}) =
ClimaLand.surface_specific_humidity(sim.model, sim.integrator.u, sim.integrator.p, sim.integrator.t)
Expand Down
2 changes: 1 addition & 1 deletion experiments/AMIP/components/ocean/eisenman_seaice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ get_field(sim::EisenmanIceSimulation, ::Val{:roughness_buoyancy}) =
get_field(sim::EisenmanIceSimulation, ::Val{:roughness_momentum}) =
@. sim.integrator.p.params.p_i.z0m * (sim.integrator.p.ice_area_fraction) +
sim.integrator.p.params.p_o.z0m .* (1 - sim.integrator.p.ice_area_fraction)
get_field(sim::EisenmanIceSimulation, ::Val{:surface_albedo}) =
get_field(sim::EisenmanIceSimulation, ::Union{Val{:surface_direct_albedo}, Val{:surface_diffuse_albedo}}) =
@. sim.integrator.p.params.p_i.α * (sim.integrator.p.ice_area_fraction) +
sim.integrator.p.params.p_o.α .* (1 - sim.integrator.p.ice_area_fraction)
get_field(sim::EisenmanIceSimulation, ::Val{:surface_humidity}) = sim.integrator.u.q_sfc
Expand Down
3 changes: 2 additions & 1 deletion experiments/AMIP/components/ocean/prescr_seaice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ get_field(sim::PrescribedIceSimulation, ::Val{:area_fraction}) = sim.integrator.
get_field(sim::PrescribedIceSimulation, ::Val{:beta}) = convert(eltype(sim.integrator.u), 1.0)
get_field(sim::PrescribedIceSimulation, ::Val{:roughness_buoyancy}) = sim.integrator.p.params.z0b
get_field(sim::PrescribedIceSimulation, ::Val{:roughness_momentum}) = sim.integrator.p.params.z0m
get_field(sim::PrescribedIceSimulation, ::Val{:surface_albedo}) = sim.integrator.p.params.α
get_field(sim::PrescribedIceSimulation, ::Union{Val{:surface_direct_albedo}, Val{:surface_diffuse_albedo}}) =
sim.integrator.p.params.α
get_field(sim::PrescribedIceSimulation, ::Val{:surface_humidity}) = sim.integrator.p.q_sfc
get_field(sim::PrescribedIceSimulation, ::Val{:surface_temperature}) = sim.integrator.u.T_sfc
get_field(sim::PrescribedIceSimulation, ::Val{:water}) = nothing
Expand Down
3 changes: 2 additions & 1 deletion experiments/AMIP/components/ocean/slab_ocean.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ get_field(sim::SlabOceanSimulation, ::Val{:area_fraction}) = sim.integrator.p.ar
get_field(sim::SlabOceanSimulation, ::Val{:beta}) = convert(eltype(sim.integrator.u), 1.0)
get_field(sim::SlabOceanSimulation, ::Val{:roughness_buoyancy}) = sim.integrator.p.params.z0b
get_field(sim::SlabOceanSimulation, ::Val{:roughness_momentum}) = sim.integrator.p.params.z0m
get_field(sim::SlabOceanSimulation, ::Val{:surface_albedo}) = sim.integrator.p.params.α
get_field(sim::SlabOceanSimulation, ::Union{Val{:surface_direct_albedo}, Val{:surface_diffuse_albedo}}) =
sim.integrator.p.params.α
get_field(sim::SlabOceanSimulation, ::Val{:surface_humidity}) = sim.integrator.p.q_sfc
get_field(sim::SlabOceanSimulation, ::Val{:surface_temperature}) = sim.integrator.u.T_sfc
get_field(sim::SlabOceanSimulation, ::Val{:water}) = nothing
Expand Down
Loading
Loading