3636
3737"""
3838 ClimaLandSimulation(
39- ::Type{FT},
39+ ::Type{FT};
4040 dt::TT,
4141 tspan::Tuple{TT, TT},
4242 start_date::Dates.DateTime,
4343 output_dir::String,
44- area_fraction;
44+ area_fraction,
45+ nelements::Tuple{Int, Int} = (101, 15),
46+ depth::FT = FT(50),
47+ dz_tuple::Tuple{FT, FT} = FT.((10.0, 0.05)),
48+ shared_surface_space = nothing,
49+ land_spun_up_ic::Bool = true,
4550 saveat::Vector{TT} = [tspan[1], tspan[2]],
51+ surface_elevation = nothing,
52+ atmos_h,
4653 land_temperature_anomaly::String = "amip",
4754 use_land_diagnostics::Bool = true,
48- stepper = CTS.ARS111(),
4955 parameter_files = [],
5056 )
5157
@@ -70,9 +76,9 @@ function ClimaLandSimulation(
7076 land_spun_up_ic:: Bool = true ,
7177 saveat:: Vector{TT} = [tspan[1 ], tspan[2 ]],
7278 surface_elevation = nothing ,
79+ atmos_h,
7380 land_temperature_anomaly:: String = " amip" ,
7481 use_land_diagnostics:: Bool = true ,
75- stepper = CTS. ARS111 (),
7682 parameter_files = [],
7783) where {FT, TT <: Union{Float64, ITime} }
7884 # Note that this does not take into account topography of the surface, which is OK for this land model.
@@ -91,71 +97,40 @@ function ClimaLandSimulation(
9197 else
9298 surface_elevation = Interfacer. remap (surface_elevation, surface_space)
9399 end
100+ # Interpolate atmosphere height field to surface space of land model,
101+ # since that's where we compute fluxes for this land model
102+ atmos_h = Interfacer. remap (atmos_h, surface_space)
94103
95104 # Set up spatially-varying parameters
96- earth_param_set = CL. Parameters. LandParameters (
97- CP. create_toml_dict (FT; override_file = CP. merge_toml_files (parameter_files; override = true )),
98- )
99-
100- # Set up the soil model args
101- soil_model_type = CL. Soil. EnergyHydrology{FT}
102- soil_params = create_soil_params (FT, domain)
103-
104- # Set up the soil microbes model args
105- soilco2_type = CL. Soil. Biogeochemistry. SoilCO2Model{FT}
106- soilco2_params = CL. Soil. Biogeochemistry. SoilCO2ModelParameters (FT)
107-
108- # Set up the canopy model args
109- stop_date = start_date + Dates. Second (float (tspan[2 ] - tspan[1 ]))
110- canopy_model_args, canopy_component_args = create_canopy_args (FT, domain, earth_param_set, start_date, stop_date)
111- canopy_component_types = (;
112- autotrophic_respiration = CL. Canopy. AutotrophicRespirationModel{FT},
113- radiative_transfer = CL. Canopy. TwoStreamModel{FT},
114- photosynthesis = CL. Canopy. FarquharModel{FT},
115- conductance = CL. Canopy. MedlynConductanceModel{FT},
116- hydraulics = CL. Canopy. PlantHydraulicsModel{FT},
117- energy = CL. Canopy. BigLeafEnergyModel{FT},
118- )
119-
120- # Set up the snow model args
121- snow_model_type = CL. Snow. SnowModel
122- snow_params = CL. Snow. SnowParameters {FT} (dt; earth_param_set)
123-
124- # Setup overall land model
125- f_over = FT (3.28 ) # 1/m
126- R_sb = FT (1.484e-4 / 1000 ) # m/s
127- runoff_model = CL. Soil. Runoff. TOPMODELRunoff {FT} (;
128- f_over = f_over,
129- f_max = CL. Soil. topmodel_fmax (surface_space, FT),
130- R_sb = R_sb,
105+ default_parameter_file = joinpath (pkgdir (CL), " toml" , " default_parameters.toml" )
106+ toml_dict = CP. create_toml_dict (
107+ FT;
108+ override_file = CP. merge_toml_files ([default_parameter_file, parameter_files... ]; override = true ),
131109 )
110+ earth_param_set = CL. Parameters. LandParameters (toml_dict)
132111
133- Csom = CL . PrescribedSoilOrganicCarbon {FT} ( TimeVaryingInput ((t) -> 5 ))
134- land_input = (
135- atmos = CL. CoupledAtmosphere {FT} (surface_space),
112+ # Set up atmosphere and radiation forcing
113+ forcing = (;
114+ atmos = CL. CoupledAtmosphere {FT} (surface_space, atmos_h ),
136115 radiation = CL. CoupledRadiativeFluxes {FT} (
137116 start_date;
138117 insol_params = LP. insolation_parameters (earth_param_set),
139118 latitude = ClimaCore. Fields. coordinate_field (domain. space. surface). lat,
140119 longitude = ClimaCore. Fields. coordinate_field (domain. space. surface). long,
141120 ),
142- runoff = runoff_model,
143- soil_organic_carbon = Csom,
144121 )
145122
146- model = CL. LandModel {FT} (;
147- soilco2_type = soilco2_type,
148- soilco2_args = (; domain = domain, parameters = soilco2_params),
149- land_args = land_input,
150- soil_model_type = soil_model_type,
151- soil_args = (domain = domain, parameters = soil_params),
152- canopy_component_types = canopy_component_types,
153- canopy_component_args = canopy_component_args,
154- canopy_model_args = canopy_model_args,
155- snow_model_type = snow_model_type,
156- snow_args = (; domain = CL. obtain_surface_domain (domain), parameters = snow_params),
123+ # Set up leaf area index (LAI)
124+ stop_date = start_date + Dates. Second (float (tspan[2 ] - tspan[1 ]))
125+ LAI = CL. prescribed_lai_modis (
126+ surface_space,
127+ start_date,
128+ stop_date;
129+ time_interpolation_method = LinearInterpolation (PeriodicCalendar ()),
157130 )
158131
132+ model = CL. LandModel {FT} (forcing, LAI, toml_dict, domain, dt)
133+
159134 Y, p, coords = CL. initialize (model)
160135
161136 # Set initial conditions
@@ -175,11 +150,11 @@ function ClimaLandSimulation(
175150
176151 # Set initial conditions that aren't read in from file
177152 Y. soilco2. C .= FT (0.000412 ) # set to atmospheric co2, mol co2 per mol air
178- Y. canopy. hydraulics. ϑ_l.:1 .= canopy_component_args . hydraulics. parameters. ν
153+ Y. canopy. hydraulics. ϑ_l.:1 .= model . canopy . hydraulics. parameters. ν
179154 @. Y. canopy. energy. T = orog_adjusted_T_surface
180155
181156 # Read in initial conditions for snow and soil from file, if requested
182- θ_r, ν, ρc_ds = soil_params . θ_r, soil_params . ν, soil_params . ρc_ds
157+ (; θ_r, ν, ρc_ds) = model . soil . parameters
183158 if land_spun_up_ic
184159 # Set snow T first to use in computing snow internal energy
185160 @. p. snow. T = orog_adjusted_T_surface
@@ -246,148 +221,21 @@ function ClimaLandSimulation(
246221 end
247222
248223 # Set up time stepper and integrator
224+ stepper = CTS. ARS111 ()
249225 ode_algo =
250226 CTS. IMEXAlgorithm (stepper, CTS. NewtonsMethod (max_iters = 3 , update_j = CTS. UpdateEvery (CTS. NewNewtonIteration)))
251227 integrator = SciMLBase. init (
252228 prob,
253229 ode_algo;
254- dt = dt ,
255- saveat = saveat ,
230+ dt,
231+ saveat,
256232 adaptive = false ,
257233 callback = SciMLBase. CallbackSet (driver_cb, diag_cb),
258234 )
259235
260236 return ClimaLandSimulation (model, integrator, area_fraction, output_writer)
261237end
262238
263- # ##############################################################################
264- # Helper functions for constructing the land model
265- # ##############################################################################
266- """
267- create_canopy_args(
268- ::Type{FT},
269- domain,
270- earth_param_set,
271- start_date,
272- )
273-
274- Creates the arguments for the canopy model.
275- """
276- function create_canopy_args (:: Type{FT} , domain, earth_param_set, start_date, stop_date) where {FT}
277- surface_space = domain. space. surface
278-
279- # Spatially varying canopy parameters from CLM
280- g1 = CL. Canopy. clm_medlyn_g1 (surface_space)
281- rooting_depth = CL. Canopy. clm_rooting_depth (surface_space)
282- (; is_c3, Vcmax25) = CL. Canopy. clm_photosynthesis_parameters (surface_space)
283- (; Ω, G_Function, α_PAR_leaf, τ_PAR_leaf, α_NIR_leaf, τ_NIR_leaf) =
284- CL. Canopy. clm_canopy_radiation_parameters (surface_space)
285-
286- # Energy Balance model
287- ac_canopy = FT (2.5e3 )
288- # Plant Hydraulics and general plant parameters
289- SAI = FT (0.0 ) # m2/m2
290- f_root_to_shoot = FT (3.5 )
291- RAI = FT (1.0 )
292- K_sat_plant = FT (5e-9 ) # m/s # seems much too small?
293- ψ63 = FT (- 4 / 0.0098 ) # / MPa to m, Holtzman's original parameter value is -4 MPa
294- Weibull_param = FT (4 ) # unitless, Holtzman's original c param value
295- a = FT (0.05 * 0.0098 ) # Holtzman's original parameter for the bulk modulus of elasticity
296- conductivity_model = CL. Canopy. PlantHydraulics. Weibull {FT} (K_sat_plant, ψ63, Weibull_param)
297- retention_model = CL. Canopy. PlantHydraulics. LinearRetentionCurve {FT} (a)
298- plant_ν = FT (1.44e-4 )
299- plant_S_s = FT (1e-2 * 0.0098 ) # m3/m3/MPa to m3/m3/m
300- n_stem = 0
301- n_leaf = 1
302- h_stem = FT (0.0 )
303- h_leaf = FT (1.0 )
304- zmax = FT (0.0 )
305- h_canopy = h_stem + h_leaf
306- compartment_midpoints = n_stem > 0 ? [h_stem / 2 , h_stem + h_leaf / 2 ] : [h_leaf / 2 ]
307- compartment_surfaces = n_stem > 0 ? [zmax, h_stem, h_canopy] : [zmax, h_leaf]
308-
309- z0_m = FT (0.13 ) * h_canopy
310- z0_b = FT (0.1 ) * z0_m
311-
312- # Individual Component arguments
313- # Set up autotrophic respiration
314- autotrophic_respiration_args = (; parameters = CL. Canopy. AutotrophicRespirationParameters (FT))
315- # Set up radiative transfer
316- radiative_transfer_args = (;
317- parameters = CL. Canopy. TwoStreamParameters (FT; Ω, α_PAR_leaf, τ_PAR_leaf, α_NIR_leaf, τ_NIR_leaf, G_Function)
318- )
319- # Set up conductance
320- conductance_args = (; parameters = CL. Canopy. MedlynConductanceParameters (FT; g1))
321- # Set up photosynthesis
322- photosynthesis_args = (; parameters = CL. Canopy. FarquharParameters (FT, is_c3; Vcmax25 = Vcmax25))
323- # Set up plant hydraulics
324- LAIfunction = CL. prescribed_lai_modis (surface_space, start_date, stop_date)
325- ai_parameterization = CL. Canopy. PrescribedSiteAreaIndex {FT} (LAIfunction, SAI, RAI)
326-
327- plant_hydraulics_ps = CL. Canopy. PlantHydraulics. PlantHydraulicsParameters (;
328- ai_parameterization = ai_parameterization,
329- ν = plant_ν,
330- S_s = plant_S_s,
331- rooting_depth = rooting_depth,
332- conductivity_model = conductivity_model,
333- retention_model = retention_model,
334- )
335- plant_hydraulics_args = (
336- parameters = plant_hydraulics_ps,
337- n_stem = n_stem,
338- n_leaf = n_leaf,
339- compartment_midpoints = compartment_midpoints,
340- compartment_surfaces = compartment_surfaces,
341- )
342-
343- energy_args = (parameters = CL. Canopy. BigLeafEnergyParameters {FT} (ac_canopy),)
344-
345- canopy_component_args = (;
346- autotrophic_respiration = autotrophic_respiration_args,
347- radiative_transfer = radiative_transfer_args,
348- photosynthesis = photosynthesis_args,
349- conductance = conductance_args,
350- hydraulics = plant_hydraulics_args,
351- energy = energy_args,
352- )
353-
354- shared_params = CL. Canopy. SharedCanopyParameters {FT, typeof(earth_param_set)} (z0_m, z0_b, earth_param_set)
355-
356- canopy_model_args = (; parameters = shared_params, domain = CL. obtain_surface_domain (domain))
357- return canopy_model_args, canopy_component_args
358- end
359-
360-
361- """
362- create_soil_params(::Type{FT}, domain)
363-
364- Creates the parameters struct for the soil model.
365- """
366- function create_soil_params (:: Type{FT} , domain) where {FT}
367- subsurface_space = domain. space. subsurface
368- surface_space = domain. space. surface
369-
370- (; ν_ss_om, ν_ss_quartz, ν_ss_gravel) = CL. Soil. soil_composition_parameters (subsurface_space, FT)
371- (; ν, hydrology_cm, K_sat, θ_r) = CL. Soil. soil_vangenuchten_parameters (subsurface_space, FT)
372- soil_albedo = CL. Soil. CLMTwoBandSoilAlbedo {FT} (; CL. Soil. clm_soil_albedo_parameters (surface_space)... )
373- S_s = ClimaCore. Fields. zeros (subsurface_space) .+ FT (1e-3 )
374-
375-
376- soil_params = CL. Soil. EnergyHydrologyParameters (
377- FT;
378- ν,
379- ν_ss_om,
380- ν_ss_quartz,
381- ν_ss_gravel,
382- hydrology_cm,
383- K_sat,
384- S_s,
385- θ_r,
386- albedo = soil_albedo,
387- )
388- return soil_params
389- end
390-
391239# ##############################################################################
392240# ## Functions required by ClimaCoupler.jl for a SurfaceModelSimulation
393241# ##############################################################################
@@ -437,7 +285,12 @@ function Interfacer.update_field!(sim::ClimaLandSimulation, ::Val{:sw_d}, field)
437285 Interfacer. remap! (sim. integrator. p. drivers. SW_d, field)
438286end
439287
440- Interfacer. step! (sim:: ClimaLandSimulation , t) = Interfacer. step! (sim. integrator, t - sim. integrator. t, true )
288+ function Interfacer. step! (sim:: ClimaLandSimulation , t)
289+ while float (sim. integrator. t) < float (t)
290+ Interfacer. step! (sim. integrator)
291+ end
292+ return nothing
293+ end
441294Interfacer. close_output_writers (sim:: ClimaLandSimulation ) = isnothing (sim. output_writer) || close (sim. output_writer)
442295
443296function FieldExchanger. update_sim! (sim:: ClimaLandSimulation , csf, area_fraction)
0 commit comments