Skip to content

Commit 1f8b44b

Browse files
authored
use imp tend in canopy alone, update diag, harmonic mean at faces (#958)
1 parent b1cbb7a commit 1f8b44b

File tree

11 files changed

+136
-54
lines changed

11 files changed

+136
-54
lines changed

docs/tutorials/standalone/Canopy/canopy_tutorial.jl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ canopy = ClimaLand.Canopy.CanopyModel{FT}(;
262262

263263
Y, p, coords = ClimaLand.initialize(canopy)
264264
exp_tendency! = make_exp_tendency(canopy);
265+
imp_tendency! = make_imp_tendency(canopy)
266+
jacobian! = make_jacobian(canopy);
267+
jac_kwargs =
268+
(; jac_prototype = ClimaLand.ImplicitEquationJacobian(Y), Wfact = jacobian!);
265269

266270
# Provide initial conditions for the canopy hydraulics model
267271

@@ -317,12 +321,21 @@ cb = SciMLBase.CallbackSet(driver_cb, saving_cb);
317321

318322

319323
# Select a timestepping algorithm and setup the ODE problem.
320-
321-
timestepper = CTS.RK4();
322-
ode_algo = CTS.ExplicitAlgorithm(timestepper)
324+
timestepper = CTS.ARS111();
325+
ode_algo = CTS.IMEXAlgorithm(
326+
timestepper,
327+
CTS.NewtonsMethod(
328+
max_iters = 6,
329+
update_j = CTS.UpdateEvery(CTS.NewNewtonIteration),
330+
),
331+
);
323332

324333
prob = SciMLBase.ODEProblem(
325-
CTS.ClimaODEFunction(T_exp! = exp_tendency!, dss! = ClimaLand.dss!),
334+
CTS.ClimaODEFunction(
335+
T_exp! = exp_tendency!,
336+
T_imp! = SciMLBase.ODEFunction(imp_tendency!; jac_kwargs...),
337+
dss! = ClimaLand.dss!,
338+
),
326339
Y,
327340
(t0, tf),
328341
p,

experiments/integrated/fluxnet/run_fluxnet.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ include(joinpath(climaland_dir, "experiments/integrated/fluxnet/data_tools.jl"))
3030
include(joinpath(climaland_dir, "experiments/integrated/fluxnet/plot_utils.jl"))
3131

3232
# Read in the site to be run from the command line
33-
if length(ARGS) < 1
34-
error("Must provide site ID on command line")
35-
end
33+
#if length(ARGS) < 1
34+
# error("Must provide site ID on command line")
35+
#end
3636

37-
site_ID = ARGS[1]
37+
site_ID = "US-MOz"#ARGS[1]
3838

3939
# Read all site-specific domain parameters from the simulation file for the site
4040
include(

experiments/standalone/Vegetation/no_vegetation.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ canopy = ClimaLand.Canopy.CanopyModel{FT}(;
162162

163163
Y, p, coords = ClimaLand.initialize(canopy)
164164
exp_tendency! = make_exp_tendency(canopy);
165-
165+
imp_tendency! = make_imp_tendency(canopy)
166+
jacobian! = make_jacobian(canopy);
167+
jac_kwargs =
168+
(; jac_prototype = ClimaLand.ImplicitEquationJacobian(Y), Wfact = jacobian!);
166169

167170
ψ_leaf_0 = FT(-2e5 / 9800)
168171

@@ -195,11 +198,22 @@ updatefunc = ClimaLand.make_update_drivers(drivers)
195198
driver_cb = ClimaLand.DriverUpdateCallback(updateat, updatefunc)
196199
cb = SciMLBase.CallbackSet(driver_cb, saving_cb);
197200

198-
timestepper = CTS.RK4();
199-
ode_algo = CTS.ExplicitAlgorithm(timestepper)
201+
# Set up timestepper
202+
timestepper = CTS.ARS111();
203+
ode_algo = CTS.IMEXAlgorithm(
204+
timestepper,
205+
CTS.NewtonsMethod(
206+
max_iters = 6,
207+
update_j = CTS.UpdateEvery(CTS.NewNewtonIteration),
208+
),
209+
);
200210

201211
prob = SciMLBase.ODEProblem(
202-
CTS.ClimaODEFunction(T_exp! = exp_tendency!, dss! = ClimaLand.dss!),
212+
CTS.ClimaODEFunction(
213+
T_exp! = exp_tendency!,
214+
T_imp! = SciMLBase.ODEFunction(imp_tendency!; jac_kwargs...),
215+
dss! = ClimaLand.dss!,
216+
),
203217
Y,
204218
(t0, tf),
205219
p,

experiments/standalone/Vegetation/varying_lai.jl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ canopy = ClimaLand.Canopy.CanopyModel{FT}(;
162162

163163
Y, p, coords = ClimaLand.initialize(canopy)
164164
exp_tendency! = make_exp_tendency(canopy);
165+
imp_tendency! = make_imp_tendency(canopy)
166+
jacobian! = make_jacobian(canopy);
167+
jac_kwargs =
168+
(; jac_prototype = ClimaLand.ImplicitEquationJacobian(Y), Wfact = jacobian!);
165169

166170

167171
ψ_leaf_0 = FT(-2e5 / 9800)
@@ -195,11 +199,22 @@ updatefunc = ClimaLand.make_update_drivers(drivers)
195199
driver_cb = ClimaLand.DriverUpdateCallback(updateat, updatefunc)
196200
cb = SciMLBase.CallbackSet(driver_cb, saving_cb);
197201

198-
timestepper = CTS.RK4();
199-
ode_algo = CTS.ExplicitAlgorithm(timestepper)
202+
# Set up timestepper
203+
timestepper = CTS.ARS111();
204+
ode_algo = CTS.IMEXAlgorithm(
205+
timestepper,
206+
CTS.NewtonsMethod(
207+
max_iters = 6,
208+
update_j = CTS.UpdateEvery(CTS.NewNewtonIteration),
209+
),
210+
);
200211

201212
prob = SciMLBase.ODEProblem(
202-
CTS.ClimaODEFunction(T_exp! = exp_tendency!, dss! = ClimaLand.dss!),
213+
CTS.ClimaODEFunction(
214+
T_exp! = exp_tendency!,
215+
T_imp! = SciMLBase.ODEFunction(imp_tendency!; jac_kwargs...),
216+
dss! = ClimaLand.dss!,
217+
),
203218
Y,
204219
(t0, tf),
205220
p,

experiments/standalone/Vegetation/varying_lai_with_stem.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,10 @@ canopy = ClimaLand.Canopy.CanopyModel{FT}(;
161161

162162
Y, p, coords = ClimaLand.initialize(canopy)
163163
exp_tendency! = make_exp_tendency(canopy);
164-
164+
imp_tendency! = make_imp_tendency(canopy)
165+
jacobian! = make_jacobian(canopy);
166+
jac_kwargs =
167+
(; jac_prototype = ClimaLand.ImplicitEquationJacobian(Y), Wfact = jacobian!);
165168

166169
ψ_leaf_0 = FT(-2e5 / 9800)
167170
ψ_stem_0 = FT(-1e5 / 9800)
@@ -202,11 +205,22 @@ updatefunc = ClimaLand.make_update_drivers(drivers)
202205
driver_cb = ClimaLand.DriverUpdateCallback(updateat, updatefunc)
203206
cb = SciMLBase.CallbackSet(driver_cb, saving_cb);
204207

205-
timestepper = CTS.RK4();
206-
ode_algo = CTS.ExplicitAlgorithm(timestepper)
208+
# Set up timestepper
209+
timestepper = CTS.ARS111();
210+
ode_algo = CTS.IMEXAlgorithm(
211+
timestepper,
212+
CTS.NewtonsMethod(
213+
max_iters = 6,
214+
update_j = CTS.UpdateEvery(CTS.NewNewtonIteration),
215+
),
216+
);
207217

208218
prob = SciMLBase.ODEProblem(
209-
CTS.ClimaODEFunction(T_exp! = exp_tendency!, dss! = ClimaLand.dss!),
219+
CTS.ClimaODEFunction(
220+
T_exp! = exp_tendency!,
221+
T_imp! = SciMLBase.ODEFunction(imp_tendency!; jac_kwargs...),
222+
dss! = ClimaLand.dss!,
223+
),
210224
Y,
211225
(t0, tf),
212226
p,

src/diagnostics/default_diagnostics.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ function default_diagnostics(
117117
"trans",
118118
"clhf",
119119
"cshf",
120-
# "lwp", # last(p.canopy.hydraulics.ψ) errors
120+
"lwp",
121121
# "fa", # return a Tuple
122122
"far",
123123
"lai",
@@ -264,7 +264,7 @@ function default_diagnostics(
264264
"trans",
265265
"clhf",
266266
"cshf",
267-
# "lwp", # last(p.canopy.hydraulics.ψ) errors
267+
"lwp",
268268
# "fa", # return a Tuple
269269
"far",
270270
"lai",

src/diagnostics/define_diagnostics.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ function define_diagnostics!(land_model)
224224
### Canopy - Hydraulics
225225
# Leaf water potential
226226

227-
#=
227+
228228
add_diagnostic_variable!(
229229
short_name = "lwp",
230230
long_name = "Leaf Water Potential",
@@ -234,18 +234,18 @@ function define_diagnostics!(land_model)
234234
compute! = (out, Y, p, t) ->
235235
compute_leaf_water_potential!(out, Y, p, t, land_model),
236236
)
237-
238-
# Flux per ground area
239-
add_diagnostic_variable!(
240-
short_name = "fa",
241-
long_name = "Flux Per Ground Area",
242-
standard_name = "flux_per_ground_area",
243-
units = "m s^-1",
244-
comments = "Flux of water volume per m^2 of plant per second, multiplied by the area index (plant area/ground area).",
245-
compute! = (out, Y, p, t) ->
246-
compute_flux_per_ground_area!(out, Y, p, t, land_model),
247-
)
248-
=#
237+
#=
238+
# Flux per ground area
239+
add_diagnostic_variable!(
240+
short_name = "fa",
241+
long_name = "Flux Per Ground Area",
242+
standard_name = "flux_per_ground_area",
243+
units = "m s^-1",
244+
comments = "Flux of water volume per m^2 of plant per second, multiplied by the area index (plant area/ground area).",
245+
compute! = (out, Y, p, t) ->
246+
compute_flux_per_ground_area!(out, Y, p, t, land_model),
247+
)
248+
=#
249249

250250
# Root flux per ground area
251251
add_diagnostic_variable!(

src/diagnostics/land_compute_methods.jl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,24 @@ end
8888
} p.canopy.energy.turbulent_fluxes.shf
8989

9090
# Canopy - Hydraulics
91-
#@diagnostic_compute "leaf_water_potential" Union{SoilCanopyModel, LandModel} last(
92-
# p.canopy.hydraulics.ψ,
93-
#)
91+
function compute_leaf_water_potential!(
92+
out,
93+
Y,
94+
p,
95+
t,
96+
land_model::Union{SoilCanopyModel, LandModel},
97+
)
98+
hydraulics = land_model.canopy.hydraulics
99+
n_stem = hydraulics.n_stem
100+
n_leaf = hydraulics.n_leaf
101+
n = n_stem + n_leaf
102+
if isnothing(out)
103+
return p.canopy.hydraulics.ψ.:($n)
104+
else
105+
out .= p.canopy.hydraulics.ψ.:($n)
106+
end
107+
end
108+
94109
# @diagnostic_compute "flux_per_ground_area" Union{SoilCanopyModel, LandModel} p.canopy.hydraulics.fa # return a Tuple
95110
@diagnostic_compute "root_flux_per_ground_area" Union{
96111
SoilCanopyModel,

src/integrated/soil_canopy_root_interactions.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ function update_root_extraction!(p, Y, t, land)
99
z = land.soil.domain.fields.z
1010
(; conductivity_model) = land.canopy.hydraulics.parameters
1111
area_index = p.canopy.hydraulics.area_index
12-
12+
# allocates
1313
above_ground_area_index =
14-
getproperty(area_index, land.canopy.hydraulics.compartment_labels[1])
14+
PlantHydraulics.harmonic_mean.(
15+
getproperty(
16+
area_index,
17+
land.canopy.hydraulics.compartment_labels[1],
18+
),
19+
getproperty(area_index, :root),
20+
)
1521
# Note that we model the flux between each soil layer and the canopy as:
1622
# Flux = -K_eff x [(ψ_canopy - ψ_soil)/(z_canopy - z_soil) + 1], where
1723
# K_eff = K_soil K_canopy /(K_canopy + K_soil)

src/standalone/Vegetation/Canopy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ function ClimaLand.make_update_aux(
539539
conductivity_model,
540540
ψ.:($$ip1),
541541
),
542-
) * areaip1
542+
) * PlantHydraulics.harmonic_mean(areaip1, areai)
543543
end
544544
# We update the fa[n_stem+n_leaf] element once we have computed transpiration, below
545545
# update photosynthesis and conductance terms

0 commit comments

Comments
 (0)