Skip to content
Snippets Groups Projects
Commit 1e52e259 authored by Marco Matthies's avatar Marco Matthies
Browse files

Rework functions for FarmPlot and crop models

- `stepagent!` for FarmPlot that delegates to crop state stepagent!
  function

- `harvest!`, `sow!` functions work on a `FarmPlot`, and delegate to
  the respective methods acting on a `CropState`
parent 3338624f
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,6 @@ module ALMaSS
using Persefone:
Management,
FarmPlot,
Length,
cm,
SimulationModel,
......@@ -74,8 +73,8 @@ cropname(ct::CropType) = ct.name
"""
CropState
The state data for an ALMaSS vegetation point calculation as used in
FarmPlot.
The state data for an ALMaSS vegetation point calculation. Usually
part of a `FarmPlot`.
"""
mutable struct CropState
#TODO add Unitful
......@@ -168,15 +167,14 @@ function readcropparameters(generalcropfile::String, growthfile::String)
end
"""
stepagent!(farmplot, model)
stepagent!(cropstate, model)
Update a farm plot by one day.
"""
function stepagent!(farmplot::FarmPlot{CropState}, model::SimulationModel)
function stepagent!(cs::CropState, model::SimulationModel)
# update growing degree days
# if no crop-specific base temperature is given, default to 5°C
# (https://www.eea.europa.eu/publications/europes-changing-climate-hazards-1/heat-and-cold/heat-and-cold-2014-mean)
cs = farmplot.crop_state
basetemp = cs.croptype.mingrowthtemp
ismissing(basetemp) && (basetemp = 5.0)
gdd = (maxtemp(model)+mintemp(model))/2 - basetemp
......@@ -185,19 +183,18 @@ function stepagent!(farmplot::FarmPlot{CropState}, model::SimulationModel)
monthday(model.date) == (1,1) && (cs.phase = ALMaSS.janfirst)
monthday(model.date) == (3,1) && (cs.phase = ALMaSS.marchfirst)
# update crop growth
growcrop!(farmplot, model)
growcrop!(cs, model)
end
## CROP MANAGEMENT AND GROWTH FUNCTIONS
"""
sow!(cropname, farmplot, model)
sow!(cropstate, model, cropname)
Sow the specified crop on this farmplot.
Change the cropstate to sow the specified crop.
"""
function sow!(cropname::String, farmplot::FarmPlot{CropState}, model::SimulationModel)
cs = farmplot.crop_state
function sow!(cs::CropState, model::SimulationModel, cropname::String)
createevent!(model, farmplot.pixels, sowing)
cs.croptype = model.crops[cropname]
cs.phase = ALMaSS.sow
......@@ -205,12 +202,11 @@ function sow!(cropname::String, farmplot::FarmPlot{CropState}, model::Simulation
end
"""
harvest!(farmplot, model)
harvest!(cropstate, model)
Harvest the crop on this farmplot.
Harvest the crop of this cropstate.
"""
function harvest!(farmplot::FarmPlot{CropState}, model::SimulationModel)
cs = farmplot.crop_state
function harvest!(cs::CropState, model::SimulationModel)
createevent!(model, farmplot.pixels, harvesting)
cs.phase in [ALMaSS.harvest1, ALMaSS.harvest2] ?
cs.phase = ALMaSS.harvest2 :
......@@ -224,13 +220,13 @@ end
#TODO till!()
"""
growcrop!(farmplot, model)
growcrop!(cropstate, model)
Apply the relevant crop growth model to update the plants on this farm plot.
Currently only supports the ALMaSS crop growth model by Topping et al.
Apply the relevant crop growth model to update the plants crop state
on this farm plot. Implements the ALMaSS crop growth model by Topping
et al.
"""
function growcrop!(farmplot::FarmPlot{CropState}, model::SimulationModel)
cs = farmplot.crop_state
function growcrop!(cs::CropState, model::SimulationModel)
fertiliser in cs.events ?
curve = cs.croptype.lownutrientgrowth :
curve = cs.croptype.highnutrientgrowth
......
......@@ -15,6 +15,36 @@ cropheight(f::FarmPlot{T}) where {T} = cropheight(f.crop_state)
cropcover(f::FarmPlot{T}) where {T} = cropcover(f.crop_state)
cropyield(f::FarmPlot{T}) where {T} = cropyield(f.crop_state)
"""
stepagent!(farmplot, model)
Update a farm plot by one day.
"""
function stepagent!(farmplot::FarmPlot{T}, model::SimulationModel) where T
stepagent!(farmplot.crop_state, model)
end
"""
sow!(farmplot, model, cropname)
Sow the specified crop on the farmplot.
"""
function sow!(farmplot::FarmPlot, model::SimulationModel, cropname::String)
createevent!(model, farmplot.pixels, sowing)
sow!(farmplot.crop_state, model, cropname)
#XXX test if the crop is sowable?
end
"""
harvest!(farmplot, model)
Harvest the crop of this farmplot.
"""
function harvest!(farmplot::FarmPlot{T}, model::SimulationModel) where T
createevent!(model, farmplot.pixels, harvesting)
harvest!(farmplot.crop_state, model) # TODO: multiply with area to return units of `g`
end
## UTILITY FUNCTIONS
"""
......
......@@ -3,7 +3,7 @@ module SimpleCrop
using Persefone:
FarmPlot,
Length,
m,
cm,
SimulationModel
import Persefone:
......@@ -35,10 +35,36 @@ cropyield(cs::CropState) = 0.0 # TODO: units?
"""
stepagent!(farmplot, model)
Update a farm plot by one day.
Update a crop state by one day.
"""
function stepagent!(farmplot::FarmPlot{CropState}, model::SimulationModel)
# TODO: do something simple
function stepagent!(cs::CropState, model::SimulationModel)
# height undergoes random diffusion, bounded by 0
delta_height = (2 * rand() - 1) * cm
cs.height = max(0.0cm, cs.height + delta_height)
end
"""
sow!(cropstate, model, cropname)
Change the cropstate to sow the specified crop.
"""
function sow!(cs::CropState, model::SimulationModel, cropname::String)
cs.croptype = model.crops[cropname]
cs.height = 0cm
end
"""
harvest!(cropstate, model)
Harvest the crop of this cropstate.
"""
function harvest!(cs::CropState, model::SimulationModel)
# TODO: set cs.croptype ?
# TODO: this 1.0g/cm/m^2 height_to_yield factor should be a param
# for every crop type
yield = cs.height * 1.0g/cm/m^2
cs.height = 0cm
return yield
end
end # module SimpleCrop
......@@ -12,7 +12,8 @@ mutable struct Farmer <: ModelAgent
#XXX make this into an abstract type and create subtypes for different
# farm submodels? (#69)
const id::Int64
fields::Vector{ALMaSS.FarmPlot}
# TODO: hardcoded ALMaSS crop model
fields::Vector{FarmPlot{ALMaSS.CropState}}
croprotation::Vector{ALMaSS.CropType}
#TODO add AES
end
......
......@@ -34,7 +34,7 @@ end
@testset "Submodule SimpleCrop" begin
ct = Ps.SimpleCrop.CropType("olive tree")
fp = FarmPlot(0, [(0,0)], Ps.SimpleCrop.CropState(ct, 0.0m))
fp = FarmPlot(0, [(0,0)], Ps.SimpleCrop.CropState(ct, 0.0cm))
@test fp isa FarmPlot
@test fp isa FarmPlot{Ps.SimpleCrop.CropState}
@test croptype(fp) isa Ps.SimpleCrop.CropType
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment