From f86cc587d1ac5e8235213f6abf100787c97b2f39 Mon Sep 17 00:00:00 2001 From: kmdeck Date: Fri, 5 Jul 2024 15:36:35 -0700 Subject: [PATCH] experiments, docs --- .../integrated/soil_canopy_tutorial.jl | 9 +-------- experiments/benchmarks/land.jl | 14 ++++++------- experiments/integrated/fluxnet/ozark_pft.jl | 9 +-------- experiments/integrated/fluxnet/run_fluxnet.jl | 9 +-------- .../integrated/global/global_soil_canopy.jl | 14 ++++++------- .../conservation/ozark_conservation_setup.jl | 9 +-------- .../performance/profile_allocations.jl | 9 +-------- .../standalone/Biogeochemistry/experiment.jl | 2 +- .../src/Fluxnet/run_fluxnet.jl | 13 +++++------- src/integrated/soil_canopy_model.jl | 20 ++++++++++--------- .../soil_energy_hydrology_biogeochemistry.jl | 2 +- .../Soil/Biogeochemistry/Biogeochemistry.jl | 16 +++++++-------- 12 files changed, 43 insertions(+), 83 deletions(-) diff --git a/docs/tutorials/integrated/soil_canopy_tutorial.jl b/docs/tutorials/integrated/soil_canopy_tutorial.jl index aed1c5bb6e..ec462b8b25 100644 --- a/docs/tutorials/integrated/soil_canopy_tutorial.jl +++ b/docs/tutorials/integrated/soil_canopy_tutorial.jl @@ -185,18 +185,11 @@ soilco2_sources = (MicrobeProduction{FT}(),); soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc); -soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, -); - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = soil_domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ); # Next we need to set up the [`CanopyModel`](https://clima.github.io/ClimaLand.jl/dev/APIs/canopy/Canopy/#Canopy-Model-Structs). @@ -306,7 +299,7 @@ canopy_model_args = (; parameters = shared_params, domain = canopy_domain); # atmospheric and radiative flux conditions from the observations at the Ozark # site as was done in the previous tutorial. -land_input = (atmos = atmos, radiation = radiation) +land_input = (atmos = atmos, radiation = radiation, soil_organic_carbon = Csom) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, diff --git a/experiments/benchmarks/land.jl b/experiments/benchmarks/land.jl index 85cd4d727f..1e3e9d8544 100644 --- a/experiments/benchmarks/land.jl +++ b/experiments/benchmarks/land.jl @@ -422,18 +422,11 @@ function setup_prob(t0, tf, Δt; nelements = (101, 15)) soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc) - soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, - ) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -538,7 +531,12 @@ function setup_prob(t0, tf, Δt; nelements = (101, 15)) ) # Integrated plant hydraulics and soil model - land_input = (atmos = atmos, radiation = radiation, runoff = runoff_model) + land_input = ( + atmos = atmos, + radiation = radiation, + runoff = runoff_model, + soil_organic_carbon = Csom, + ) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/experiments/integrated/fluxnet/ozark_pft.jl b/experiments/integrated/fluxnet/ozark_pft.jl index 22d412e0c7..91245bed5c 100644 --- a/experiments/integrated/fluxnet/ozark_pft.jl +++ b/experiments/integrated/fluxnet/ozark_pft.jl @@ -150,18 +150,11 @@ soilco2_sources = (MicrobeProduction{FT}(),) soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc) -soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, -) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = soil_domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -242,7 +235,7 @@ shared_params = SharedCanopyParameters{FT, typeof(earth_param_set)}( canopy_model_args = (; parameters = shared_params, domain = canopy_domain) # Integrated plant hydraulics and soil model -land_input = (atmos = atmos, radiation = radiation) +land_input = (atmos = atmos, radiation = radiation, soil_organic_carbon = Csom) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/experiments/integrated/fluxnet/run_fluxnet.jl b/experiments/integrated/fluxnet/run_fluxnet.jl index 6b89cd17e0..916bf1a051 100644 --- a/experiments/integrated/fluxnet/run_fluxnet.jl +++ b/experiments/integrated/fluxnet/run_fluxnet.jl @@ -109,18 +109,11 @@ soilco2_sources = (MicrobeProduction{FT}(),) soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc) -soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, -) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = soil_domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -199,7 +192,7 @@ shared_params = SharedCanopyParameters{FT, typeof(earth_param_set)}( canopy_model_args = (; parameters = shared_params, domain = canopy_domain) # Integrated plant hydraulics and soil model -land_input = (atmos = atmos, radiation = radiation) +land_input = (atmos = atmos, radiation = radiation, soil_organic_carbon = Csom) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/experiments/integrated/global/global_soil_canopy.jl b/experiments/integrated/global/global_soil_canopy.jl index adc3424b09..ef2bb9c0d9 100644 --- a/experiments/integrated/global/global_soil_canopy.jl +++ b/experiments/integrated/global/global_soil_canopy.jl @@ -190,18 +190,11 @@ soilco2_sources = (Soil.Biogeochemistry.MicrobeProduction{FT}(),) soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc) -soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, -) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -295,7 +288,12 @@ canopy_model_args = (; ) # Integrated plant hydraulics and soil model -land_input = (atmos = atmos, radiation = radiation, runoff = runoff_model) +land_input = ( + atmos = atmos, + radiation = radiation, + runoff = runoff_model, + soil_organic_carbon = Csom, +) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/experiments/integrated/performance/conservation/ozark_conservation_setup.jl b/experiments/integrated/performance/conservation/ozark_conservation_setup.jl index 74983ef2f8..ba3006a2da 100644 --- a/experiments/integrated/performance/conservation/ozark_conservation_setup.jl +++ b/experiments/integrated/performance/conservation/ozark_conservation_setup.jl @@ -91,18 +91,11 @@ soilco2_sources = (MicrobeProduction{FT}(),) soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc) -soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, -) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = soil_domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -180,7 +173,7 @@ shared_params = SharedCanopyParameters{FT, typeof(earth_param_set)}( canopy_model_args = (; parameters = shared_params, domain = canopy_domain) # Integrated plant hydraulics and soil model -land_input = (atmos = atmos, radiation = radiation) +land_input = (atmos = atmos, radiation = radiation, soil_organic_carbon = Csom) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/experiments/integrated/performance/profile_allocations.jl b/experiments/integrated/performance/profile_allocations.jl index 95b114da4d..61a0c58680 100644 --- a/experiments/integrated/performance/profile_allocations.jl +++ b/experiments/integrated/performance/profile_allocations.jl @@ -238,18 +238,11 @@ soilco2_sources = (MicrobeProduction{FT}(),) soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = soilco2_bot_bc) -soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - atmos, -) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = soil_domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -315,7 +308,7 @@ shared_params = SharedCanopyParameters{FT, typeof(earth_param_set)}( canopy_model_args = (; parameters = shared_params, domain = canopy_domain) # Integrated plant hydraulics and soil model -land_input = (atmos = atmos, radiation = radiation) +land_input = (atmos = atmos, radiation = radiation, soil_organic_carbon = Csom) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/experiments/standalone/Biogeochemistry/experiment.jl b/experiments/standalone/Biogeochemistry/experiment.jl index e4c59a7350..a45fc4559f 100644 --- a/experiments/standalone/Biogeochemistry/experiment.jl +++ b/experiments/standalone/Biogeochemistry/experiment.jl @@ -110,7 +110,7 @@ for (FT, tf) in ((Float32, 2 * dt), (Float64, tf)) ) # Create integrated model instance - land_args = (atmos, Csom) + land_args = (atmos = atmos, soil_organic_carbon = Csom) model = LandSoilBiogeochemistry{FT}(; land_args = land_args, soil_args = soil_args, diff --git a/lib/ClimaLandSimulations/src/Fluxnet/run_fluxnet.jl b/lib/ClimaLandSimulations/src/Fluxnet/run_fluxnet.jl index 72ad5333ce..0285b5a475 100644 --- a/lib/ClimaLandSimulations/src/Fluxnet/run_fluxnet.jl +++ b/lib/ClimaLandSimulations/src/Fluxnet/run_fluxnet.jl @@ -72,18 +72,11 @@ function run_fluxnet( soilco2_boundary_conditions = (; top = soilco2_top_bc, bottom = CO2 = soilco2_bot_bc) - soilco2_drivers = Soil.Biogeochemistry.SoilDrivers( - Soil.Biogeochemistry.PrognosticMet{FT}(), - Soil.Biogeochemistry.PrescribedSOC{FT}(Csom), - drivers.atmos, - ) - soilco2_args = (; boundary_conditions = soilco2_boundary_conditions, sources = soilco2_sources, domain = soil_domain, parameters = soilco2_ps, - drivers = soilco2_drivers, ) # Now we set up the canopy model, which we set up by component: @@ -218,7 +211,11 @@ function run_fluxnet( (; parameters = shared_params, domain = domain.canopy_domain) # Integrated plant hydraulics and soil model - land_input = (atmos = drivers.atmos, radiation = drivers.radiation) + land_input = ( + atmos = drivers.atmos, + radiation = drivers.radiation, + soil_organic_carbon = Csom, + ) land = SoilCanopyModel{FT}(; soilco2_type = soilco2_type, soilco2_args = soilco2_args, diff --git a/src/integrated/soil_canopy_model.jl b/src/integrated/soil_canopy_model.jl index 5c68aa3948..6f225d1880 100644 --- a/src/integrated/soil_canopy_model.jl +++ b/src/integrated/soil_canopy_model.jl @@ -88,7 +88,7 @@ function SoilCanopyModel{FT}(; MM <: Soil.Biogeochemistry.SoilCO2Model{FT}, } - (; atmos, radiation) = land_args + (; atmos, radiation, soil_organic_carbon) = land_args # These should always be set by the constructor. sources = (RootExtraction{FT}(), Soil.PhaseChange{FT}()) if :runoff ∈ propertynames(land_args) @@ -116,7 +116,7 @@ function SoilCanopyModel{FT}(; ) transpiration = Canopy.PlantHydraulics.DiagnosticTranspiration{FT}() - soil_driver = PrognosticSoil{typeof(soil.parameters.PAR_albedo)}( + canopy_soil_driver = PrognosticSoil{typeof(soil.parameters.PAR_albedo)}( soil.parameters.PAR_albedo, soil.parameters.NIR_albedo, ) @@ -142,7 +142,7 @@ function SoilCanopyModel{FT}(; energy = canopy_component_types.energy( canopy_component_args.energy.parameters, ), - soil_driver = soil_driver, + soil_driver = canopy_soil_driver, atmos = atmos, radiation = radiation, canopy_model_args..., @@ -165,18 +165,20 @@ function SoilCanopyModel{FT}(; transpiration = transpiration, canopy_component_args.hydraulics..., ), - soil_driver = soil_driver, + soil_driver = canopy_soil_driver, atmos = atmos, radiation = radiation, canopy_model_args..., ) end - soilco2 = Soil.Biogeochemistry.SoilCO2Model{FT}(; soilco2_args...) - - if !(soilco2_args.drivers.met isa PrognosticMet) - throw(AssertionError("Must be of type PrognosticMet.")) - end + co2_prognostic_soil = Soil.Biogeochemistry.PrognosticMet(soil.parameters) + soil_co2_drivers = Soil.Biogeochemistry.SoilDrivers( + co2_prognostic_soil, + Soil.Biogeochemistry.PrescribedSOC{FT}(soil_organic_carbon), + atmos, + ) + soilco2 = soil_co2_model(; soilco2_args..., drivers = soil_co2_drivers) return SoilCanopyModel{FT, typeof(soilco2), typeof(soil), typeof(canopy)}( soilco2, diff --git a/src/integrated/soil_energy_hydrology_biogeochemistry.jl b/src/integrated/soil_energy_hydrology_biogeochemistry.jl index 9ee326fe1e..3827aed3ad 100644 --- a/src/integrated/soil_energy_hydrology_biogeochemistry.jl +++ b/src/integrated/soil_energy_hydrology_biogeochemistry.jl @@ -43,7 +43,7 @@ function LandSoilBiogeochemistry{FT}(; soilco2_args::NamedTuple = (;), ) where {FT} - (atmos, Csom) = land_args + (; atmos, soil_organic_carbon) = land_args soil = Soil.EnergyHydrology{FT}(; soil_args..., # soil_args must have sources, boundary_conditions, domain, parameters ) diff --git a/src/standalone/Soil/Biogeochemistry/Biogeochemistry.jl b/src/standalone/Soil/Biogeochemistry/Biogeochemistry.jl index 3aba6e9a16..855ce1524b 100644 --- a/src/standalone/Soil/Biogeochemistry/Biogeochemistry.jl +++ b/src/standalone/Soil/Biogeochemistry/Biogeochemistry.jl @@ -93,7 +93,7 @@ struct SoilCO2Model{FT, PS, D, BC, S, DT} <: "A tuple of sources, each of type AbstractSource" sources::S "Drivers" - driver::DT + drivers::DT end @@ -411,14 +411,14 @@ function ClimaLand.make_update_aux(model::SoilCO2Model) function update_aux!(p, Y, t) params = model.parameters z = model.domain.fields.z - T_soil = soil_temperature(model.driver.met, p, Y, t, z) - θ_l = soil_moisture(model.driver.met, p, Y, t, z) - Csom = soil_SOM_C(model.driver.soc, p, Y, t, z) + T_soil = soil_temperature(model.drivers.met, p, Y, t, z) + θ_l = soil_moisture(model.drivers.met, p, Y, t, z) + Csom = soil_SOM_C(model.drivers.soc, p, Y, t, z) P_sfc = p.drivers.P θ_w = θ_l - ν = model.driver.met.ν - θ_a100 = model.driver.met.θ_a100 - b = model.driver.met.b + ν = model.drivers.met.ν + θ_a100 = model.drivers.met.θ_a100 + b = model.drivers.met.b p.soilco2.D .= co2_diffusivity.(T_soil, θ_w, P_sfc, θ_a100, b, ν, params) @@ -592,7 +592,7 @@ function ClimaLand.boundary_flux( end function ClimaLand.get_drivers(model::SoilCO2Model) - return (model.driver.atmos, nothing) + return (model.drivers.atmos, nothing) end Base.broadcastable(ps::SoilCO2ModelParameters) = tuple(ps)