None of this is final, but some current public facing functions:
LimnoSES.initialise
— Functioninitialise()
Returns a populated model initialised and ready to run.
LimnoSES.lake_initial_state
— Functionlake_initial_state(<:LakeDefinition, <:LakeModel)
Provides initial conditions of the lake. Parameters are model dependent. For example: lake_initial_state(Clear, Martin)
.
lake_initial_state(nutrients, bream, pike, vegetation, Martin)
Provides initial conditions of the lake with specified values.
lake_initial_state(nutrients, <:LakeDefinition, Martin)
A special override that returns interpolated results from precaclulated Clear
and Turbid
bifurcation results. Not as precise as the preset conditions, since the numbers do not come directly from the analytical solution, but close.
LimnoSES.planner
— Functionplanner(plan(Angling))
planner(plan(Planting; rate=5e-3),
plan(Trawling, 1:3))
Provides a complete schedule of interventions for a Municipality. Must be used in conjunction with plan
.
LimnoSES.plan
— Functionplan(Angling) # Assume always on
plan(Angling; rate = 2.5e-3) # Always on with custom rate
plan(Angling, 7; rate = 3.2e-3) # Only one year (custom rate)
plan(Angling, 3:5) # Only years 3 to 5
plan(Angling, [(period = 1:4, ),
(year = 5, rate = 7.2e-3),
(period = 7:9, )]) # Active in years 1-5, 7-9 with a custom rate
# in year 5
Helper that provides complex scheduling for interventions with a simple interface.
The return type is Dict{Int, Vector{Intervention}}
, were the key is each year the collection of interventions will be active. As a convention, year -1
denotes an 'always active' intervention.
The result can be provided to municipality.interventions
, although this function should almost always used in conjunction with planner
.
LimnoSES.policy
— Functionpolicy(scan(Trawling), scan(Planting; rate = (1e-5, 2.6e-3)))
Enables the decision module to alter suggested planner values, optimising the system state when possible. Used to set the policies
of each Municipality.
LimnoSES.scan
— Functionscan(Trawling) # Activate decisions on trawling using default ranges.
scan(Trawling; rate = (5e-3, 2e-2)) # Activate trawling decisions with custom
# search range for `rate`.
Use the decision making optimiser to fine tune values in the planner. scan
expects a lower and upper bound of a range to scan for each intervention property. For the moment, this strategy excludes WastewaterTreatment
, and does not adjust active years. These must still be set in the planner.
Should be used in conjunction with policy
.
LimnoSES.objectives
— Functionobjectives(objective(min_time), objective(min_cost, 0.5))
Constructs a set of objectives which will be used to optimise policy towards the chosen target.
LimnoSES.objective
— Functionobjective(min_time)
objective(min_acceleration, 2)
Provides a weighted objective to be used when optimising policy. Should be used in conjunction with objectives
.
When providing a weight, this value can be any positive Real
number which will rank this objective higher or lower than other objectives. It is not imperative to make sure all numbers entered in the policy to add up to 100%, but bear in mind that the values will be normalised for the optimisation.
NutrientSeries
NutrientSeries
is an abstract type from which concrete types can be implemented to describe the dynamics of nutrient introduction to the lake.
LimnoSES.Constant
— TypeConstant()
Nutrient level remains constant at the level of init_nutrients
.
LimnoSES.Dynamic
— TypeDynamic()
Nutrient runoff is managed by the municipality by incentivising households to upgrade sewage systems that seep P into the lake.
LimnoSES.TransientUp
— TypeTransientUp(;start_year = 11, post_target_series = Constant())
Synthetic nutrient profile that alters lake dynamics regardless of municipal management.
start_year
: year when nutrients begin to increase with a rate ofnutrient_change
.post_target_series
: behaviour aftertarget_nutrients
value is reached. Default isTransientDown(start_year = 0, post_target_series = Constant())
Post target series selection must include a final Constant
phase, otherwise an infinite recursion cascade will occur.
LimnoSES.TransientDown
— TypeTransientDown(;start_year = 11, post_target_series = Constant())
Synthetic nutrient profile that alters lake dynamics regardless of municipal management.
start_year
: year when nutrients begin to decrease with a rate ofnutrient_change
.post_target_series
: behaviour aftertarget_nutrients
value is reached. Default isTransientUp(start_year = 0, post_target_series = Constant())
Post target series selection must include a final Constant
phase, otherwise an infinite recursion cascade will occur.
LimnoSES.Noise
— TypeNoise(process, min, max)
Noise process given by DiffEqNoiseProcess.jl. For the moment this does not connect to the actual start time or init_nutrients
value, so these must be manually duplicated here. Will be fixed in the future. min
and max
nutrient values can also be applied.
Care must be taken to verify that bounded processes are possible over certain time horizons. This is noticably the case with brownian bridges. If your σ is small such that the gap between your current position and the end position cannot be met within the timeframe specified, the solver will error. Unfortunately this cannot be handled in a softer manner.
Decisions
This system uses BlackBoxOptim.jl to set intervention policies that satisfy a number of objectives whilst attempting to reach a given target.
LimnoSES.make_decision!
— Functionmake_decision!(model)
Runs the optimisation routine, calling on policy ranges set via policy
. Decisions are made only from the year of the call onwards.
Targets
Targets are written in the form of an Agents.jl until
function. Any stopping condition is possible and can be user generated, although there must be a hard stop at some point in the future. s == 100 && return true
is the default. The following examples are pre-defined:
LimnoSES.clear_state
— Functionclear_state(model, s)
Targets the clear lake steady state, with an extra stopping condition if that state was not reached within 100 years.
Calculated via instantaneous comparisons at latest model time of all lake variables, with an additional check to verify a near-zero first derivative.
NOTE: This target is hard coded to the default Martin
parameters.
LimnoSES.managed_clear_eutrophic
— Functionmanaged_clear_eutrophic(model, s)
Targets the T3
state, which is a high nutrient (N>=3
), unstable state with a high pike population. Will stop at 100 years if not successful.
Note: For the moment this targets the region of T3, not the explicit starting point.
Objectives
There is no 'right' way of meeting a target, since we may have multiple objectives to contend with. Objectives are a function that take model
as an argument and return a Float64
.
Once created, these should be initialised using objective
, since the model also expects an associated weight.
Pre-defined values:
LimnoSES.min_time
— Functionmin_time(model)
Objective function that returns the time of the model at the end of a run. If a target function is interested in moving from one state to the next in the quickest amount of time, this is a useful objective.
LimnoSES.min_acceleration
— Functionmin_acceleration(model)
Objective function that returns the sum of the absolute value of the second derivative of all lake variables. Span is from start of the optimisation to the final model.year
with monthly increments.
Helps to mitigate large spikes in transitions.
LimnoSES.min_cost
— Functionmin_cost(model)
Objective function that returns a "cost" of future Planting
and Trawling
interventions, which ultimately is just a sum of all proposed rates.
When using nutrient_series = Noise(...)
and only the min_cost
objective, opt_replicates
must be large (≳ 10
), since the noise process may cause the optimiser to identify a solution in theory but fail in practice. The solution to failing meet the target scenario in this case is increase opt_replicates
and retry.
Missing docstring for LimnoSES.appropreate_vegetation
. Check Documenter's build log for details.