Skip to content

Commit 9547190

Browse files
committed
Fix heterogeneous soil water/ice initialization
1 parent ea97c31 commit 9547190

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

examples/heat_freeW_lite_implicit.jl

+13-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ using CryoGrid.LiteImplicit
99

1010
# Load forcings and build stratigraphy like before.
1111
forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_MkL3_CCSM4_long_term);
12+
soilprofile = SoilProfile(
13+
0.0u"m" => MineralOrganic(por=0.80,sat=1.0,org=0.75),
14+
0.1u"m" => MineralOrganic(por=0.80,sat=1.0,org=0.25),
15+
0.4u"m" => MineralOrganic(por=0.55,sat=1.0,org=0.25),
16+
3.0u"m" => MineralOrganic(por=0.50,sat=1.0,org=0.0),
17+
10.0u"m" => MineralOrganic(por=0.30,sat=1.0,org=0.0),
18+
)
1219
tempprofile_linear = TemperatureProfile(
1320
0.0u"m" => -30.0u"°C",
1421
10.0u"m" => -10.0u"°C",
@@ -20,22 +27,19 @@ upperbc = TemperatureBC(forcings.Tair, NFactor())
2027
initT = initializer(:T, tempprofile_linear)
2128
heatop = Heat.EnthalpyImplicit()
2229
freezecurve = FreeWater()
23-
strat = @Stratigraphy(
30+
heat = HeatBalance(heatop; freezecurve)
31+
soil_layers = map(para -> Ground(para; heat), soilprofile)
32+
strat = Stratigraphy(
2433
z_top => Top(upperbc),
25-
0.0u"m" => Ground(MineralOrganic(por=0.80,sat=1.0,org=0.75), heat=HeatBalance(heatop; freezecurve)),
26-
0.1u"m" => Ground(MineralOrganic(por=0.80,sat=1.0,org=0.25), heat=HeatBalance(heatop; freezecurve)),
27-
0.4u"m" => Ground(MineralOrganic(por=0.55,sat=1.0,org=0.25), heat=HeatBalance(heatop; freezecurve)),
28-
3.0u"m" => Ground(MineralOrganic(por=0.50,sat=1.0,org=0.0), heat=HeatBalance(heatop; freezecurve)),
29-
10.0u"m" => Ground(MineralOrganic(por=0.30,sat=1.0,org=0.0), heat=HeatBalance(heatop; freezecurve)),
34+
soil_layers,
3035
z_bot => Bottom(GeothermalHeatFlux(0.053u"W/m^2"))
3136
);
3237
modelgrid = CryoGrid.Presets.DefaultGrid_2cm
3338
tile = Tile(strat, modelgrid, initT);
3439

3540
# Since the solver can take daily timesteps, we can easily specify longer simulation time spans at minimal cost.
36-
# Here we specify a time span of 5 years.
37-
tspan = (DateTime(2010,1,1), DateTime(2015,1,1))
38-
tspan_sol = convert_tspan(tspan)
41+
# Here we specify a time span of 20 years.
42+
tspan = (DateTime(2000,1,1), DateTime(2020,1,1))
3943
u0, du0 = initialcondition!(tile, tspan);
4044
prob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,))
4145
sol = @time solve(prob, LiteImplicitEuler(), dt=24*3600.0)

src/Physics/Soils/ground.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ Base.@kwdef struct Ground{Tpara,Theat<:Optional{HeatBalance},Twater<:Optional{Wa
1616
para::Tpara = MineralOrganic() # ground parameterization
1717
heat::Theat = HeatBalance() # heat conduction
1818
water::Twater = nothing # water balance
19-
fcsolver::Tsolver = default_fcsolver(heat, water)
19+
fcsolver::Tsolver = default_fcsolver(para, heat, water)
2020
aux::Taux = nothing # user-defined specialization
2121
end
2222
# Convenience constructors
2323
Ground(para::GroundParameterization; kwargs...) = Ground(; para, kwargs...)
2424

25-
default_fcsolver(::Any, ::Any) = nothing
26-
default_fcsolver(::HeatBalance{<:SFCC}, ::Nothing) = SFCCPreSolver(FreezeCurves.SFCCPreSolverCache1D())
27-
default_fcsolver(::HeatBalance{<:SFCC}, ::WaterBalance) = SFCCPreSolver(FreezeCurves.SFCCPreSolverCacheND())
25+
default_fcsolver(::Any, ::Any, ::Any) = nothing
26+
default_fcsolver(::GroundParameterization, ::HeatBalance{<:SFCC}, ::Nothing) = SFCCPreSolver(FreezeCurves.SFCCPreSolverCache1D())
27+
default_fcsolver(::GroundParameterization, ::HeatBalance{<:SFCC}, ::WaterBalance) = SFCCPreSolver(FreezeCurves.SFCCPreSolverCacheND())
2828

2929
fcsolver(ground::Ground) = ground.fcsolver

src/Physics/Soils/soil_para.jl

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ end
103103
"""
104104
Ground(soilprofile::SoilProfile; kwargs...) = Ground(Heterogeneous(soilprofile); kwargs...)
105105

106+
# add dispatch for default_fcsolver that selects the ND presolver
107+
default_fcsolver(::Heterogeneous, ::HeatBalance{<:SFCC}, ::Nothing) = SFCCPreSolver(FreezeCurves.SFCCPreSolverCacheND())
108+
106109
saturation(::Soil{<:Heterogeneous{<:MineralOrganic}}, state) = state.sat
107110
porosity(::Soil{<:Heterogeneous{<:MineralOrganic}}, state) = state.por
108111
mineral(::Soil{<:Heterogeneous{<:MineralOrganic}}, state) = state.θm
@@ -138,6 +141,7 @@ CryoGrid.initializers(soil::Soil{<:Heterogeneous{<:MineralOrganic}}) = (
138141
initializer(:por, map(para -> para.por, soil.para.profile)),
139142
initializer(:sat, map(para -> para.sat, soil.para.profile)),
140143
initializer(:org, map(para -> para.org, soil.para.profile)),
144+
initializer(:θwi, map(para -> para.por*para.sat, soil.para.profile)),
141145
initializer(:kh_m, map(para -> para.heat.kh_m, soil.para.profile)),
142146
initializer(:kh_o, map(para -> para.heat.kh_o, soil.para.profile)),
143147
initializer(:kh_w, map(para -> para.heat.kh_w, soil.para.profile)),

src/Tiles/stratigraphy.jl

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ struct Stratigraphy{N,TLayers<:NamedTuple,TBoundaries}
2222
sub::AbstractVector{<:Pair{<:DistQuantity}},
2323
bot::Pair{<:DistQuantity,<:Bottom}
2424
) = Stratigraphy(top, Tuple(sub), bot)
25+
Stratigraphy(
26+
top::Pair{<:DistQuantity,<:Top},
27+
sub::Numerics.Profile{N,<:Tuple{Vararg{DistQuantity}},<:Tuple{Vararg{SubSurface}}},
28+
bot::Pair{<:DistQuantity,<:Bottom}
29+
) where N = Stratigraphy(top, Tuple(sub), bot)
2530
function Stratigraphy(
2631
# use @nospecialize to (hopefully) reduce compilation overhead
2732
@nospecialize(top::Pair{<:DistQuantity,<:Top}),

0 commit comments

Comments
 (0)