Skip to content

Commit c29b790

Browse files
committed
Infer default soil BCs from process types
1 parent 186fbb5 commit c29b790

File tree

5 files changed

+57
-17
lines changed

5 files changed

+57
-17
lines changed

src/boundary_conditions.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ is invoked recursively on the entry matching the name of `var`, if it exists. Ot
1414
returned.
1515
"""
1616
get_field_boundary_conditions(::AbstractBoundaryConditions, grid::AbstractLandGrid) = (;)
17+
get_field_boundary_conditions(::Nothing, grid::AbstractLandGrid) = (;)
1718
get_field_boundary_conditions(bc::BoundaryCondition, ::AbstractLandGrid) = bc
1819
get_field_boundary_conditions(bcs::FieldBCs, ::AbstractLandGrid) = bcs
1920

@@ -82,17 +83,17 @@ end
8283

8384
# Convenience aliases for PrescribedBC
8485
NoFlux(progvar::Symbol) = PrescribedBC(progvar, NoFluxBoundaryCondition())
85-
PrescribedFlux(progvar::Symbol, value; kwargs...) = PrescribedBC(progvar, FluxBoundaryCondition(value; kwargs...))
86-
PrescribedValue(progvar::Symbol, value; kwargs...) = PrescribedBC(progvar, ValueBoundaryCondition(value; kwargs...))
87-
PrescribedGradient(progvar::Symbol, value; kwargs...) = PrescribedBC(progvar, GradientBoundaryCondition(value; kwargs...))
86+
PrescribedFlux(progvar::Symbol, condition; kwargs...) = PrescribedBC(progvar, FluxBoundaryCondition(condition; kwargs...))
87+
PrescribedValue(progvar::Symbol, condition; kwargs...) = PrescribedBC(progvar, ValueBoundaryCondition(condition; kwargs...))
88+
PrescribedGradient(progvar::Symbol, condition; kwargs...) = PrescribedBC(progvar, GradientBoundaryCondition(condition; kwargs...))
8889

8990
"""
9091
Implementation of `Oceananigans.BoundaryConditions.getbc` for `Input{name}` placeholders that retrieves the input `Field` from
91-
`state.inputs` and returns the value at the given index.
92+
`state` and returns the value at the given index.
9293
"""
9394
@inline function getbc(::Input{name, units, <:XY}, i::Integer, j::Integer, grid::OceananigansGrids.AbstractGrid, clock, state) where {name, units}
94-
input_field = getproperty(state.inputs, name)
95-
return @inbounds input_field[i, j]
95+
field = getproperty(state, name)
96+
return @inbounds field[i, j]
9697
end
9798

9899
"""

src/models/models.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
export SoilModel
44
include("soil/soil_model.jl")
55

6-
export SoilBoundaryConditions, SoilBC, GroundHeatFlux, GeothermalHeatFlux, FreeDrainage, ImpermeableBoundary
6+
export SoilBoundaryConditions, SoilBC
7+
export GroundHeatFlux, GeothermalHeatFlux, PrescribedTemperature
8+
export FreeDrainage, ImpermeableBoundary, InfiltrationFlux
79
include("soil/soil_model_bcs.jl")
810

911
include("soil/soil_model_init.jl")
1012

13+
export CoupledSoilAtmosphereModel
14+
include("soil/soil_atmosphere_model.jl")
15+
1116
# Vegetation
1217

1318
export VegetationModel

src/models/soil/soil_model.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $(TYPEDFIELDS)
3737
constants::Constants = PhysicalConstants(eltype(grid))
3838

3939
"Boundary conditions"
40-
boundary_conditions::BoundaryConditions = SoilBoundaryConditions(eltype(grid))
40+
boundary_conditions::BoundaryConditions = SoilBoundaryConditions(eltype(grid), energy, hydrology)
4141

4242
"State variable initializer"
4343
initializer::Initializer = SoilInitializer()

src/models/soil/soil_model_bcs.jl

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
Boundary condition type for soil models that provides boundary conditions for each
55
of the relevant internal processes, i.e. energy, hydrology, ...
66
"""
7-
struct SoilBC{EnergyBC, WaterBC} <: AbstractBoundaryConditions
7+
@kwdef struct SoilBC{EnergyBC, WaterBC} <: AbstractBoundaryConditions
88
"Boundary condition for the soil energy balance"
9-
energy::EnergyBC
9+
energy::EnergyBC = GroundHeatFlux()
1010

1111
"Boundary condition for the soil water balance"
12-
hydrology::WaterBC
12+
hydrology::WaterBC = ImpermeableBoundary()
1313
end
1414

1515
variables(bc::SoilBC) = tuplejoin(variables(bc.hydrology), variables(bc.energy))
@@ -19,23 +19,38 @@ function compute_auxiliary!(state, model, bc::SoilBC)
1919
compute_auxiliary!(state, model, bc.energy)
2020
end
2121

22+
function compute_tendencies!(state, model, bc::SoilBC)
23+
compute_tendencies!(state, model, bc.hydrology)
24+
compute_tendencies!(state, model, bc.energy)
25+
end
26+
2227
function get_field_boundary_conditions(bcs::SoilBC, grid::AbstractLandGrid)
2328
water_bc = get_field_boundary_conditions(bcs.hydrology, grid)
2429
energy_bc = get_field_boundary_conditions(bcs.energy, grid)
2530
return merge(water_bc, energy_bc)
2631
end
2732

33+
# Energy BCs
34+
2835
"""
29-
Alias for `PrescribedFlux` with name `ground_heat_flux` representing the net ground heat flux at the soil surface.
36+
Alias for `PrescribedFlux` on `internal_energy` with name `ground_heat_flux` representing the net ground heat flux at the soil surface.
3037
"""
3138
GroundHeatFlux(init=nothing) = PrescribedFlux(:internal_energy, Input(:ground_heat_flux, init, units=u"W/m^2"))
3239

3340
"""
34-
Alias for `PrescribedFlux` with name `Q_geo` representing the geothermal heat flux at the bottom
41+
Alias for `PrescribedFlux` on `internal_energy` with name `geothermal_heat_flux` representing the geothermal heat flux at the bottom
3542
boundary of the soil column.
3643
"""
3744
GeothermalHeatFlux(init=nothing) = PrescribedFlux(:internal_energy, Input(:geothermal_heat_flux, init, units=u"W/m^2"))
3845

46+
"""
47+
Alias for `PrescribedValue` on `temperature` with the given name.
48+
"""
49+
PrescribedTemperature(name::Symbol, init=nothing) = PrescribedValue(:temperature, Input(name, init, units=u"°C"))
50+
PrescribedTemperature(condition) = PrescribedValue(:temperature, condition)
51+
52+
# Hydrology BCs
53+
3954
"""
4055
Alias for `PrescribedFlux` with name `infiltration` representing liquid water infiltration at the soil surface.
4156
"""
@@ -52,10 +67,25 @@ column, thereby allowing free drainage of water.
5267
"""
5368
FreeDrainage(::Type{NF}) where {NF} = PrescribedGradient(:pressure_head, zero(NF))
5469

70+
# SoilBoundaryConditions constructor
71+
5572
"""
56-
Alias for `ColumnBoundaryConditions` with defaults suitable for `SoilModel`s.
73+
Creates `ColumnBoundaryConditions` with defaults suitable for the given soil process configurations.
5774
"""
58-
SoilBoundaryConditions(::Type{NF}; top=default_soil_upperbc(NF), bottom=default_soil_lowerbc(NF)) where {NF} = ColumnBoundaryConditions(; top, bottom)
75+
SoilBoundaryConditions(
76+
::Type{NF},
77+
energy::SoilEnergyBalance = SoilEnergyBalance(NF),
78+
hydrology::SoilHydrology = SoilHydrology(NF);
79+
top=SoilBC(energy = default_upperbc(energy), hydrology = default_upperbc(hydrology)),
80+
bottom=SoilBC(energy = default_lowerbc(energy), hydrology = default_lowerbc(hydrology))
81+
) where {NF} = ColumnBoundaryConditions(; top, bottom)
82+
83+
# Default boundary conditions for various soil process configurations
84+
85+
default_upperbc(::SoilEnergyBalance) = GroundHeatFlux()
86+
default_upperbc(::SoilHydrology{NF, NoFlow}) where {NF} = nothing
87+
default_upperbc(::SoilHydrology) = InfiltrationFlux()
5988

60-
default_soil_upperbc(::Type{NF}, energy=GroundHeatFlux(zero(NF)), hydrology=InfiltrationFlux(zero(NF))) where {NF} = SoilBC(energy, hydrology)
61-
default_soil_lowerbc(::Type{NF}, energy=GeothermalHeatFlux(zero(NF)), hydrology=ImpermeableBoundary()) where {NF} = SoilBC(energy, hydrology)
89+
default_lowerbc(::SoilEnergyBalance) = GeothermalHeatFlux()
90+
default_lowerbc(::SoilHydrology{NF, NoFlow}) where {NF} = nothing
91+
default_lowerbc(::SoilHydrology) = ImpermeableBoundary()

src/processes/abstract_types.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ compute_auxiliary!(state, model, ::AbstractProcess) = nothing
2828

2929
compute_tendencies!(state, model, ::AbstractProcess) = nothing
3030

31+
# also allow dispatch on nothing
32+
compute_auxiliary!(state, model, ::Nothing) = nothing
33+
compute_tendencies!(state, model, ::Nothing) = nothing
34+
3135
# Soil process types
3236
# TODO: Think more about these process types and what methods they should have.
3337

0 commit comments

Comments
 (0)