Simulations
ClimaLand.Simulations.LandSimulation — Type
LandSimulation{
M <: ClimaLand.AbstractModel,
T <: ClimaTimeSteppers.TimeSteppingAlgorithm,
UC,
DI,
RC,
CA <: ClimaTimeSteppers.CallbackSet,
I <: ClimaTimeSteppers.TimeStepperIntegrator,
}the ClimaLand LandSimulation struct, which specifies
- the discrete set of equations to solve (defined by the
model); - the timestepping algorithm;
- user callbacks (passed as a tuple) to be executed at specific times in the simulations;
- the diagnostics to output (optional).
User callbacks are optional: examples currently include callbacks that estimate the time to solution and SYPD of the simulation as it runs, checkpoint the state, or check the solution for NaNs. Others can be added here.
Diagnostics are implemented as callbacks, and are also optional. However, a default is provided. diagnostics is expected to be a list of ClimaDiagnostics.ScheduledDiagnostics.
Finally, the private field requiredcallbacks consists of callbacks that are required for the simulation to run correctly. Currently, this includes the callbacks which update the atmospheric forcing and update the LAI using prescribed data.
ClimaLand.Simulations.step! — Function
step!(landsim::LandSimulation)Advances the land simulation landsim forward in time by one step, updating landsim in place.
ClimaLand.Simulations.solve! — Function
solve!(landsim::LandSimulation)Advances the land simulation landsim forward from the initial to final time, updating landsim in place.
ClimaLand.Simulations.make_set_initial_state_from_file — Function
make_set_initial_state_from_file(ic_path, land::LandModel{FT}; enforce_constraints=false) where {FT}Returns a function which takes (Y,p,t0,land) as arguments, and updates the state Y in place with initial conditions from ic_path, a netCDF file. Fields in the cache p are used as pre-allocated memory and are updated as well, but this does not mean that the cache state is consitent with Y and t entirely.
Currently only tested and used for global simulations, but the same returned function should work for column simulations.
The returned function is a closure for ic_path. It could also be for land, as many other ClimaLand functions are, but we wish to preserve the argument land in set_ic! for users who wish to define their own initial condition function, which may require parameters, etc, stored in land.
If enforce_constraints = true, we ensure the soil water content is between porosity and the residual value, and that the temperature is bounded to be within the extrema of the air temperature at the surface.
It is assumed that in CoupledAtmosphere simulations that p.drivers has been updated already.
make_set_initial_state_from_file(ic_path, land::SoilCanopyModel{FT}; enforce_constraints = false) where {FT}Returns a function which takes (Y,p,t0,land) as arguments, and updates the state Y in place with initial conditions from ic_path, a netCDF file. Fields in the cache p are used as pre-allocated memory and are updated as well, but this does not mean that the cache state is consitent with Y and t entirely.
Currently only tested and used for global simulations, but the same returned function should work for column simulations.
The returned function is a closure for ic_path. It could also be for land, as many other ClimaLand functions are, but we wish to preserve the argument land in set_ic! for users who wish to define their own initial condition function, which may require parameters, etc, stored in land.
If enforce_constraints = true, we ensure the soil water content is between porosity and the residual value, and that the temperature is bounded to be within the extrema of the air temperature at the surface.
It is assumed that in CoupledAtmosphere simulations that p.drivers has been updated already.
make_set_initial_state_from_file(ic_path, model::ClimaLand.Soil.EnergyHydrology{FT}; enforce_constraints = false) where {FT}Returns a function which takes (Y,p,t0,model) as arguments, and updates the state Y in place with initial conditions from ic_path, a netCDF file. Fields in the cache p are used as pre-allocated memory and are updated as well, but this does not mean that the cache state is consitent with Y and t entirely.
Currently only tested and used for global simulations, but the same returned function should work for column simulations.
The returned function is a closure for ic_path. It could also be for model, as many other ClimaLand functions are, but we wish to preserve the argument model in set_ic! for users who wish to define their own initial condition function, which may require parameters, etc, stored in model.
If enforce_constraints = true, we ensure the soil water content is between porosity and the residual value, and that the temperature is bounded to be within the extrema of the air temperature at the surface.
It is assumed that in CoupledAtmosphere simulations that p.drivers.T has been updated already.
make_set_initial_state_from_file(ic_path, model::ClimaLand.Bucket.BucketModel)Returns a function which takes (Y,p,t0,model) as arguments, and updates the state Y of the BucketModel in place with initial conditions from ic_path, a path to a netCDF file with variables W, Ws, T, and S.
The returned function is a closure for ic_path and model.
ClimaLand.Simulations.make_set_initial_state_from_era5land — Function
make_set_initial_state_from_era5land(ic_path)Creates and returns a function set_ic!(Y,p,t,model) which updates Y in place with the initial conditions from the file ic_path, which is assumed to be an nc file using the naming convention of ERA5 Land. These initial conditions are analytical for some variables and read in from file for others.
The input file ic_path is expected to contain the following variables:
- "tsn": snow temperature
- "swe": snow water equivalent
- "swvl": soil total water content
- "stl": soil temperature
It is assumed that in CoupledAtmosphere simulations that p.drivers has been updated already.
ClimaLand.Simulations.make_set_initial_state_from_atmos_and_parameters — Function
make_set_initial_state_from_atmos_and_parameters(
land::ClimaLand.Bucket.BucketModel
)Returns a function setic!(Y,p,t0,bucket) which sets the bucket initial conditions like: Y.bucket.W .= bucket.parameters.Wf Y.bucket.Ws .= 0 Y.bucket.σS .= 0 Y.bucket.T .= p.drivers.T # at every level
It is assumed that in CoupledAtmosphere simulations that p.drivers.T has been updated already.
make_set_initial_state_from_atmos_and_parameters(land::LandModel{FT}) where {FT}Returns a function which takes (Y,p,t0,land) as arguments, and updates the state Y in place with initial conditions from parameter values and the atmospheric temperature.
It is assumed that in CoupledAtmosphere simulations that p.drivers.T has been updated already.
ClimaLand.Simulations.set_canopy_component_initial_conditions! — Function
set_canopy_component_initial_conditions!(Y, p, model::ClimaLand.Canopy.AbstractCanopyComponent, canopy)Sets the initial state of the canopy component in Y.
set_canopy_component_initial_conditions!(Y, p, model::ClimaLand.Canopy.BigLeafEnergyModel, canopy)Sets the initial state of the canopy energy component in Y using the air temperature.
set_canopy_component_initial_conditions!(
Y,
p,
model::ClimaLand.Canopy.ZhouOptimalLAIModel{FT},
canopy,
ic_path = ClimaLand.Artifacts.optimal_lai_initial_conditions_path(;
context = ClimaComms.context(axes(Y.canopy.biomass.LAI)),
),
max_lai = ClimaLand.Canopy.modis_max_lai(axes(Y.canopy.biomass.LAI)),
fractional_c3 = ClimaLand.Canopy.static_fractional_c3(canopy.photosynthesis),
Mc = canopy.photosynthesis.constants.Mc,
) where {FT}Sets the optimal-LAI prognostic state in Y.canopy.biomass (LAI, A0_daily, A0_annual, precip_annual, PET_annual, VPDA0_annual, growing_days, A0c3_annual, A0c4_annual, GPPc3_annual) from the netCDF file at ic_path, which must contain lai_init, a0_annual, precip_annual, vpd_gs, gsl and f0 on a (lon, lat) grid.
With the default path, LAI starts from the MODIS observation, which shortens the spin-up. The annual totals start at their climatological values, which are their steady state whatever tau_long_term; A0_daily starts at the daily share of A0_annual.
PET_annual, VPDA0_annual and growing_days are seeded so that f0, vpd_gs and GSL start at the artifact values they replace, then relax to the simulated climate over tau_long_term. Since f0(AI) peaks at f0_max, the f0 seed uses the arid branch of the inverse, and a cell whose artifact f0 exceeds the peak seeds to the peak.
Where the file has no data (over ocean, which a coastal cell can pick up, and f0 south of 60°S), the state starts from a bare canopy with no climate history: LAI and the annual totals are zero, and f0 is seeded at f0_max.
A0c3_annual starts at a0_annual. GPPc3_annual, the realized C3 GPP the tree cover is estimated from, is seeded as A0c3_annual scaled by the fAPAR of the MODIS annual maximum LAI (max_lai) rather than of lai_init, a single-date snapshot: over a year the potential GPP is concentrated in the leafy season, so the peak fAPAR is the closer estimate of the GPP-weighted annual value.
No per-pathway climatology exists, so A0c4_annual is seeded by inverting the C3/C4 competition (c4_advantage_for_c3_fraction): given that tree share, it is the C4 potential GPP at which the competition returns the static C3 map fractional_c3 (the photosynthesis model's; Mc is the molar mass of carbon). Where the map is pure C3 the seed is A0c4_annual = 0, which leaves a small C4 grass share in the open canopy.
set_canopy_component_initial_conditions!(
Y,
p,
model::ClimaLand.Canopy.PModel{FT},
canopy,
) where {FT}Sets the PModel initial conditions: the acclimated capacities are those optimal for the initial atmospheric state under a nominal midday light level, rather than under the instantaneous one, so that a simulation starting at night does not begin with zero capacities and spend ~1 month (two e-folding timescales of α) climbing out of them.
The capacities are canopy-level and linear in absorbed light, so the nominal light level is scaled by the vegetated fraction of the column: over an inland water cell, where the canopy area indices are masked to zero, the acclimated capacities start at zero as well, and no phantom canopy respiration is carried into the run.
An alternative to this approach is to initialize the initial optimal values to some reasonable values based on a spun-up simulation.