Skip to content

Commit

Permalink
tests pass locally
Browse files Browse the repository at this point in the history
  • Loading branch information
kmdeck committed Jul 18, 2024
1 parent 1bf1b6f commit 262f57e
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 90 deletions.
1 change: 1 addition & 0 deletions docs/src/APIs/Soil.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ ClimaLand.Soil.soil_tortuosity

```@docs
ClimaLand.Soil.NoRunoff
ClimaLand.Soil.SurfaceRunoff
ClimaLand.Soil.TOPMODELRunoff
ClimaLand.Soil.TOPMODELSubsurfaceRunoff
ClimaLand.Soil.subsurface_runoff_source
Expand Down
84 changes: 61 additions & 23 deletions src/standalone/Soil/Runoff/Runoff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ using ..ClimaLand.Soil:
is_saturated
export TOPMODELRunoff,
NoRunoff,
SiteLevelSurfaceRunoff,
SurfaceRunoff,
AbstractRunoffModel,
TOPMODELSubsurfaceRunoff,
subsurface_runoff_source,
Expand Down Expand Up @@ -70,27 +70,64 @@ function update_runoff!(p, runoff::NoRunoff, _...)
p.soil.infiltration .= p.drivers.P_liq
end

runoff_vars(::NoRunoff) = ()
runoff_var_domain_names(::NoRunoff) = ()
runoff_var_types(::NoRunoff) = ()
runoff_vars(::NoRunoff) = (:infiltration,)
runoff_var_domain_names(::NoRunoff) = (:surface,)
runoff_var_types(::NoRunoff, FT) = (FT,)

struct SiteLevelSurfaceRunoff <: AbstractRunoffModel
"""
SurfaceRunoff <: AbstractRunoffModel
A simple model for runoff appropriate for single column runs.
Only surface runoff is computed, using a combination of Dunne
and Hortonian runoff.
"""
struct SurfaceRunoff <: AbstractRunoffModel
subsurface_source::Nothing
function SiteLevelSurfaceRunoff()
function SurfaceRunoff()
return new(nothing)
end
end
function sitelevel_surface_infiltration(
f_ic::FT,
input::FT,
is_saturated::FT,
) where {FT}

"""
surface_infiltration(
f_ic::FT,
input::FT,
is_saturated::FT,
) where {FT}
Computes the surface infiltration for the simple surface
runoff model. If the soil is saturated at the surface,
all input is converted to runoff (infiltration is zero).
If the soil is not saturated, the maximum of the infiltration
capacity or the input is used as infiltration. Recall that
both are negative (towards the soil).
"""
function surface_infiltration(f_ic::FT, input::FT, is_saturated::FT) where {FT}
return (1 - is_saturated) * max(f_ic, input)
end

"""
update_runoff!(
p,
runoff::SurfaceRunoff,
Y,
t,
model::AbstractSoilModel,
)
The update_runoff! function for the SurfaceRunoff model.
Updates the runoff model variables in place in `p.soil` for the SurfaceRunoff
parameterization:
p.soil.R_s
p.soil.is_saturated
p.soil.infiltration
"""
function update_runoff!(
p,
runoff::SiteLevelSurfaceRunoff,
runoff::SurfaceRunoff,
Y,
t,
model::AbstractSoilModel,
Expand All @@ -106,13 +143,15 @@ function update_runoff!(
ClimaLand.Domains.top_center_to_surface(p.soil.is_saturated) # a view

@. p.soil.infiltration =
sitelevel_surface_infiltration(ic, input, is_saturated_sfc)
surface_infiltration(ic, p.drivers.P_liq, is_saturated_sfc)
@. p.soil.R_s = abs(p.drivers.P_liq .- p.soil.infiltration)
end

runoff_vars(::SiteLevelSurfaceRunoff) = (:is_saturated, :R_s)
runoff_var_domain_names(::SiteLevelSurfaceRunoff) = (:subsurface, :surface)
runoff_var_types(::SiteLevelSurfaceRunoff) = (FT, FT)
runoff_vars(::SurfaceRunoff) =
(:is_saturated, :R_s, :infiltration, :subsfc_scratch)
runoff_var_domain_names(::SurfaceRunoff) =
(:subsurface, :surface, :surface, :subsurface)
runoff_var_types(::SurfaceRunoff, FT) = (FT, FT, FT, FT)

# TOPMODEL

Expand Down Expand Up @@ -181,7 +220,6 @@ function update_runoff!(
t,
model::AbstractSoilModel,
)

ϑ_l = Y.soil.ϑ_l
FT = eltype(ϑ_l)
θ_i = model_agnostic_volumetric_ice_content(Y, FT)
Expand All @@ -207,11 +245,11 @@ function update_runoff!(

end

runoff_vars(::SiteLevelSurfaceRunoff) =
(:is_saturated, :R_s, :R_ss, :h∇, :subsfc_scratch)
runoff_var_domain_names(::SiteLevelSurfaceRunoff) =
(:subsurface, :surface, :subsurface, :surface, :subsurface)
runoff_var_types(::SiteLevelSurfaceRunoff) = (FT, FT, FT, FT, FT)
runoff_vars(::TOPMODELRunoff) =
(:infiltration, :is_saturated, :R_s, :R_ss, :h∇, :subsfc_scratch)
runoff_var_domain_names(::TOPMODELRunoff) =
(:surface, :subsurface, :surface, :surface, :surface, :subsurface)
runoff_var_types(::TOPMODELRunoff, FT) = (FT, FT, FT, FT, FT, FT)

"""
model_agnostic_volumetric_ice_content(Y, FT)
Expand Down Expand Up @@ -244,7 +282,7 @@ flux(m/s).
"""
function ClimaLand.source!(
dY::ClimaCore.Fields.FieldVector,
src::TOPMODELSubsurfaceRunoff,
src::TOPMODELSubsurfaceRunoff{FT},
Y::ClimaCore.Fields.FieldVector,
p::NamedTuple,
model::AbstractSoilModel{FT},
Expand Down
80 changes: 14 additions & 66 deletions src/standalone/Soil/boundary_conditions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,74 +84,24 @@ function RichardsAtmosDrivenFluxBC(
precip::PrescribedPrecipitation;
runoff = NoRunoff(),
)
if typeof(runoff) <: NoRunoff
@info("Warning: No runoff model was provided; zero runoff generated.")
end

return RichardsAtmosDrivenFluxBC{typeof(precip), typeof(runoff)}(
precip,
runoff,
)
end

# Methods
"""
boundary_vars(::RichardsAtmosDrivenFluxBC{<:PrescribedPrecipitation,
<:Runoff.TOPMODELRunoff,
}, ::ClimaLand.TopBoundary)
An extension of the `boundary_vars` method for RichardsAtmosDrivenFluxBC with
TOPMODELRunoff.
These variables are updated in place in `boundary_flux`.
"""
boundary_vars(
bc::RichardsAtmosDrivenFluxBC{
<:PrescribedPrecipitation,
<:Runoff.TOPMODELRunoff,
},
::ClimaLand.TopBoundary,
) = (:top_bc, :h∇, :R_s, :R_ss, :infiltration, :is_saturated, :subsfc_scratch)

"""
boundary_var_domain_names(::RichardsAtmosDrivenFluxBC{<:PrescribedPrecipitation,
<:Runoff.TOPMODELRunoff,
},
::ClimaLand.TopBoundary)
An extension of the `boundary_var_domain_names` method for RichardsAtmosDrivenFluxBC
with TOPMODELRunoff.
"""
boundary_var_domain_names(
bc::RichardsAtmosDrivenFluxBC{
<:PrescribedPrecipitation,
<:Runoff.TOPMODELRunoff,
},
::ClimaLand.TopBoundary,
) = (:surface, :surface, :surface, :surface, :surface, :subsurface, :subsurface)
"""
boundary_var_types(::RichardsModel{FT},
::RichardsAtmosDrivenFluxBC{<:PrescribedPrecipitation,
<:Runoff.TOPMODELRunoff{FT},
},
::ClimaLand.TopBoundary,
) where {FT}
An extension of the `boundary_var_types` method for RichardsAtmosDrivenFluxBC
with TOPMODELRunoff.
"""
boundary_var_types(
model::RichardsModel{FT},
bc::RichardsAtmosDrivenFluxBC{
<:PrescribedPrecipitation,
<:Runoff.TOPMODELRunoff{FT},
},
::ClimaLand.TopBoundary,
) where {FT} = (FT, FT, FT, FT, FT, FT, FT)

"""
boundary_vars(::RichardsAtmosDrivenFluxBC{<:PrescribedPrecipitation,
<:Runoff.AbstractRunoffModel,
}, ::ClimaLand.TopBoundary)
An extension of the `boundary_vars` method for RichardsAtmosDrivenFluxBC with
no runoff modeled.
runoff.
These variables are updated in place in `boundary_flux`.
"""
Expand All @@ -161,7 +111,7 @@ boundary_vars(
<:Runoff.AbstractRunoffModel,
},
::ClimaLand.TopBoundary,
) = (:top_bc, :infiltration)
) = (:top_bc, Runoff.runoff_vars(bc.runoff)...)

"""
boundary_var_domain_names(::RichardsAtmosDrivenFluxBC{<:PrescribedPrecipitation,
Expand All @@ -170,25 +120,25 @@ boundary_vars(
::ClimaLand.TopBoundary)
An extension of the `boundary_var_domain_names` method for RichardsAtmosDrivenFluxBC
with no runoff modeled.
with runoff.
"""
boundary_var_domain_names(
bc::RichardsAtmosDrivenFluxBC{
<:PrescribedPrecipitation,
<:Runoff.AbstractRunoffModel,
},
::ClimaLand.TopBoundary,
) = (:surface, :surface)
) = (:surface, Runoff.runoff_var_domain_names(bc.runoff)...)
"""
boundary_var_types(::RichardsModel{FT}
boundary_var_types(::RichardsModel{FT},
::RichardsAtmosDrivenFluxBC{<:PrescribedPrecipitation,
<:Runoff.AbstractRunoffModel,
<: Runoff.AbstractRunoffModel,
},
::ClimaLand.TopBoundary,
) where {FT}
An extension of the `boundary_var_types` method for RichardsAtmosDrivenFluxBC
with no runoff modeled.
with runoff.
"""
boundary_var_types(
model::RichardsModel{FT},
Expand All @@ -197,7 +147,8 @@ boundary_var_types(
<:Runoff.AbstractRunoffModel,
},
::ClimaLand.TopBoundary,
) where {FT} = (FT, FT)
) where {FT} = (FT, Runoff.runoff_var_types(bc.runoff, FT)...)


"""
boundary_flux(bc::WaterFluxBC, _...)::ClimaCore.Fields.Field
Expand Down Expand Up @@ -714,7 +665,6 @@ boundary_vars(
:ice_frac,
:R_n,
:top_bc,
:infiltration,
:sfc_scratch,
Runoff.runoff_vars(bc.runoff)...,
)
Expand Down Expand Up @@ -743,7 +693,6 @@ boundary_var_domain_names(
:surface,
:surface,
:surface,
:surface,
Runoff.runoff_var_domain_names(bc.runoff)...,
)
"""
Expand Down Expand Up @@ -773,8 +722,7 @@ boundary_var_types(
FT,
NamedTuple{(:water, :heat), Tuple{FT, FT}},
FT,
FT,
Runoff.runoff_var_types(bc.runoff)...,
Runoff.runoff_var_types(bc.runoff, FT)...,
)

"""
Expand Down
2 changes: 1 addition & 1 deletion test/standalone/Soil/climate_drivers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ for FT in (Float32, Float64)
:ice_frac,
:R_n,
:top_bc,
:infiltration,
:sfc_scratch,
:infiltration,
:bottom_bc,
)
function init_soil!(Y, z, params)
Expand Down
Loading

0 comments on commit 262f57e

Please sign in to comment.