Skip to content

Commit

Permalink
Preallocate thermal state
Browse files Browse the repository at this point in the history
  • Loading branch information
Sbozzolo committed Apr 30, 2024
1 parent e0fa8aa commit a643f22
Show file tree
Hide file tree
Showing 14 changed files with 59 additions and 16 deletions.
1 change: 1 addition & 0 deletions docs/src/APIs/shared_utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ ClimaLand.turbulent_fluxes
ClimaLand.turbulent_fluxes_at_a_point
ClimaLand.radiative_fluxes_at_a_point
ClimaLand.construct_atmos_ts
ClimaLand.set_atmos_ts!
ClimaLand.surface_air_density
ClimaLand.liquid_precipitation
ClimaLand.snow_precipitation
Expand Down
2 changes: 1 addition & 1 deletion experiments/standalone/Bucket/global_bucket_function.jl
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ updatefunc = ClimaLand.make_update_drivers(bucket_atmos, bucket_rad)
driver_cb = ClimaLand.DriverUpdateCallback(updateat, updatefunc)
cb = SciMLBase.CallbackSet(driver_cb, saving_cb)

@time sol =
ClimaComms.@time sol =
SciMLBase.solve(prob, ode_algo; dt = Δt, saveat = saveat, callback = cb);

# Interpolate to grid
Expand Down
14 changes: 14 additions & 0 deletions src/ClimaLand.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,24 @@ function initialize_auxiliary(
end
for domain in unique(domains_list)
p = add_dss_buffer_to_aux(p, domain)
p = add_scratch_to_aux(p, domain)
end
return p
end

function add_scratch_to_aux(p, domain)
hasproperty(domain.space, :surface) || error("Surface domain required")
FT = Spaces.undertype(domain.space.surface)
scratch = (;
# Thermal state on the surface
thermal_state = Fields.Field(
Thermodynamics.PhaseEquil{FT},
domain.space.surface,
)
)
return merge(p, (; scratch))
end

"""
initialize_lsm_aux(land::AbstractLandModel) end
Expand Down
24 changes: 20 additions & 4 deletions src/shared_utilities/drivers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export AbstractAtmosphericDrivers,
CoupledRadiativeFluxes,
compute_ρ_sfc,
construct_atmos_ts,
set_atmos_ts!,
turbulent_fluxes,
net_radiation,
turbulent_fluxes_at_a_point,
Expand Down Expand Up @@ -175,6 +176,21 @@ function construct_atmos_ts(
return ts_in
end

"""
Fill the pre-allocated ts_in `Field` with a thermodynamic state.
"""
function set_atmos_ts!(
ts_in,
atmos::PrescribedAtmosphere{FT},
p,
thermo_params,
) where {FT}
P = p.drivers.P
T = p.drivers.T
q = p.drivers.q
ts_in .= Thermodynamics.PhaseEquil_pTq.(thermo_params, P, T, q)
return nothing
end

"""
turbulent_fluxes(atmos::PrescribedAtmosphere,
Expand Down Expand Up @@ -208,7 +224,7 @@ function turbulent_fluxes(
d_sfc = displacement_height(model, Y, p)
thermo_params =
LP.thermodynamic_parameters(model.parameters.earth_param_set)
ts_air = construct_atmos_ts(atmos, p, thermo_params)
set_atmos_ts!(p.scratch.thermal_state, atmos, p, thermo_params)
u_air = p.drivers.u
h_air = atmos.h

Expand All @@ -220,7 +236,7 @@ function turbulent_fluxes(
h_sfc,
r_sfc,
d_sfc,
ts_air,
p.scratch.thermal_state,
u_air,
h_air,
atmos.gustiness,
Expand Down Expand Up @@ -518,8 +534,8 @@ function surface_air_density(
)
thermo_params =
LP.thermodynamic_parameters(model.parameters.earth_param_set)
ts_in = construct_atmos_ts(atmos, p, thermo_params)
return compute_ρ_sfc.(thermo_params, ts_in, T_sfc)
set_atmos_ts!(p.scratch.thermal_state, atmos, p, thermo_params)
return compute_ρ_sfc.(thermo_params, p.scratch.thermal_state, T_sfc)
end


Expand Down
1 change: 1 addition & 0 deletions src/shared_utilities/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ function initialize_auxiliary(model::AbstractModel{FT}, state) where {FT}
)
if :domain propertynames(model)
p = add_dss_buffer_to_aux(p, model.domain)
p = add_scratch_to_aux(p, model.domain)
else
error(
"Your model does not contain a domain. If this is intended, you will need a new method of initialize_auxiliary.",
Expand Down
1 change: 1 addition & 0 deletions src/standalone/Bucket/Bucket.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ using ClimaLand:
turbulent_fluxes,
net_radiation,
construct_atmos_ts,
set_atmos_ts!,
compute_ρ_sfc,
AbstractExpModel,
heaviside,
Expand Down
9 changes: 8 additions & 1 deletion src/standalone/Vegetation/Canopy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,14 @@ function initialize_auxiliary(model::CanopyModel{FT}, coords) where {FT}
# `p_state_list` contains `nothing` for components with no auxiliary
# variables, which we need to filter out before constructing `p`
p = (; name(model) => filter_nt(NamedTuple{components}(p_state_list)))
p = ClimaLand.add_dss_buffer_to_aux(p, model.domain)
if :domain propertynames(model)
p = ClimaLand.add_dss_buffer_to_aux(p, model.domain)
p = ClimaLand.add_scratch_to_aux(p, model.domain)
else
error(
"Your model does not contain a domain. If this is intended, you will need a new method of initialize_auxiliary.",
)
end
return p
end

Expand Down
4 changes: 2 additions & 2 deletions test/integrated/lsms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ for FT in (Float32, Float64)
m2 = DummyModel2{FT}(d)
m = DummyModel{FT}(m1, m2)
Y, p, cds = ClimaLand.initialize(m)
@test propertynames(p) == (:i1, :m1, :m2)
@test propertynames(p) == (:i1, :m1, :m2, :scratch)
exp_tendency! = make_exp_tendency(m)
dY = similar(Y)
exp_tendency!(dY, Y, p, FT(0))
Expand Down Expand Up @@ -137,7 +137,7 @@ for FT in (Float32, Float64)
m2 = DummyModel4{FT}(d)
m = DummyModelB{FT}(m1, m2)
Y, p, cds = ClimaLand.initialize(m)
@test propertynames(p) == (:m1, :m2)
@test propertynames(p) == (:m1, :m2, :scratch)
function ClimaLand.make_update_aux(::DummyModel3{FT}) where {FT}
function update_aux!(p, Y, t)
p.m1.b .= FT(10.0)
Expand Down
3 changes: 2 additions & 1 deletion test/integrated/pond_soil_lsm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ for FT in (Float32, Float64)
:surface_water,
:dss_buffer_3d,
:dss_buffer_2d,
:scratch,
)
@test typeof(p.dss_buffer_3d) == typeof(
ClimaCore.Spaces.create_dss_buffer(
Expand Down Expand Up @@ -144,7 +145,7 @@ for FT in (Float32, Float64)
ClimaLand.lsm_aux_domain_names(land)
else
@test propertynames(p) ==
(:soil_infiltration, :soil, :surface_water)
(:soil_infiltration, :soil, :surface_water, :scratch)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/standalone/Bucket/soil_bucket_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ for FT in (Float32, Float64)
),
)
else
@test propertynames(p) == (:bucket, :drivers)
@test propertynames(p) == (:bucket, :scratch, :drivers)
end


Expand Down
3 changes: 2 additions & 1 deletion test/standalone/Soil/soil_test_3d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ for FT in (Float32, Float64)

Y, p, coords = initialize(soil)
# test that the dss buffer was added
@test propertynames(p) == (:soil, :dss_buffer_3d, :dss_buffer_2d)
@test propertynames(p) ==
(:soil, :dss_buffer_3d, :dss_buffer_2d, :scratch)
@test typeof(p.dss_buffer_3d) == typeof(
ClimaCore.Spaces.create_dss_buffer(
ClimaCore.Fields.zeros(soil_domain.space.subsurface),
Expand Down
2 changes: 1 addition & 1 deletion test/standalone/Soil/soiltest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ for FT in (Float32, Float64)
# Here we do not add a dss buffer: check that `initialize`
# has not added a buffer to `p` and that it only contains the
# `soil` variables.
@test propertynames(p) == (:soil,)
@test propertynames(p) == (:soil, :scratch)
# specify ICs
function init_soil!(Ysoil, z, params)
(; ν, hydrology_cm, θ_r, S_s) = params
Expand Down
4 changes: 2 additions & 2 deletions test/standalone/Vegetation/canopy_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ for FT in (Float32, Float64)
# Check that structure of Y is value (will error if not)
@test !isnothing(zero(Y))
@test typeof(canopy.energy) == PrescribedCanopyTempModel{FT}
@test propertynames(p) == (:canopy, :drivers)
@test propertynames(p) == (:canopy, :scratch, :drivers)
for component in ClimaLand.Canopy.canopy_components(canopy)
# Only hydraulics has a prognostic variable
if component == :hydraulics
Expand Down Expand Up @@ -666,7 +666,7 @@ for FT in (Float32, Float64)

# Check that structure of Y is value (will error if not)
@test !isnothing(zero(Y))
@test propertynames(p) == (:canopy, :drivers)
@test propertynames(p) == (:canopy, :scratch, :drivers)
for component in ClimaLand.Canopy.canopy_components(canopy)
# Only hydraulics has a prognostic variable
if component == :hydraulics
Expand Down
5 changes: 3 additions & 2 deletions test/standalone/Vegetation/plant_hydraulics_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,10 @@ for FT in (Float32, Float64)

Y, p, coords = initialize(model)
if typeof(domain) <: ClimaLand.Domains.Point
@test propertynames(p) == (:canopy, :drivers)
@test propertynames(p) == (:canopy, :scratch, :drivers)
elseif typeof(domain) <: ClimaLand.Domains.Plane
@test propertynames(p) == (:canopy, :dss_buffer_2d, :drivers)
@test propertynames(p) ==
(:canopy, :dss_buffer_2d, :scratch, :drivers)
@test typeof(p.dss_buffer_2d) == typeof(
ClimaCore.Spaces.create_dss_buffer(
ClimaCore.Fields.zeros(domain.space.surface),
Expand Down

0 comments on commit a643f22

Please sign in to comment.