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

Reorganise makecropstate function, move to crop models

parent 14f5fa19
Branches
No related tags found
No related merge requests found
...@@ -148,6 +148,9 @@ model has to define a type `CropState <: AbstractCropState`. ...@@ -148,6 +148,9 @@ model has to define a type `CropState <: AbstractCropState`.
""" """
abstract type AbstractCropState end abstract type AbstractCropState end
function makecropstate end
setsoiltype!(cropstate::AbstractCropState, soiltype) = nothing
function stepagent! end function stepagent! end
## include all module files (note that the order matters - if file ## include all module files (note that the order matters - if file
......
...@@ -49,6 +49,7 @@ using Persefone: ...@@ -49,6 +49,7 @@ using Persefone:
Management, Management,
cm, cm,
SimulationModel, SimulationModel,
SoilType,
fertiliser, fertiliser,
maxtemp, maxtemp,
mintemp, mintemp,
...@@ -62,6 +63,7 @@ import Persefone: ...@@ -62,6 +63,7 @@ import Persefone:
cropheight, cropheight,
cropcover, cropcover,
cropyield, cropyield,
makecropstate,
sow!, sow!,
harvest!, harvest!,
isharvestable, isharvestable,
...@@ -202,6 +204,12 @@ function isharvestable(cs::CropState) ...@@ -202,6 +204,12 @@ function isharvestable(cs::CropState)
return cs.ddegs >= last(gdd) return cs.ddegs >= last(gdd)
end end
function makecropstate(croptype::CropType, model::SimulationModel, soiltype::SoilType)
phase = month(model.date) < 3 ? janfirst : marchfirst
return CropState(; croptype, phase)
end
# Constant in original ALMaSS code: # Constant in original ALMaSS code:
# `EL_VEG_START_LAIT` from `Landscape/Elements.cpp`, line 238-239 # `EL_VEG_START_LAIT` from `Landscape/Elements.cpp`, line 238-239
const VEG_START_LAIT::Float64 = 1.08 const VEG_START_LAIT::Float64 = 1.08
......
...@@ -25,9 +25,11 @@ import Persefone: ...@@ -25,9 +25,11 @@ import Persefone:
cropheight, cropheight,
cropcover, cropcover,
cropyield, cropyield,
makecropstate,
sow!, sow!,
harvest!, harvest!,
isharvestable isharvestable,
setsoiltype!
using Unitful: @u_str using Unitful: @u_str
...@@ -167,6 +169,14 @@ cropheight(cs::CropState) = cs.height # TODO: calculate from AquaCrop state inf ...@@ -167,6 +169,14 @@ cropheight(cs::CropState) = cs.height # TODO: calculate from AquaCrop state inf
cropcover(cs::CropState) = AquaCrop.canopycover(cs.cropstate) cropcover(cs::CropState) = AquaCrop.canopycover(cs.cropstate)
cropyield(cs::CropState) = AquaCrop.dryyield(cs.cropstate) # TODO: there is also freshyield cropyield(cs::CropState) = AquaCrop.dryyield(cs.cropstate) # TODO: there is also freshyield
isharvestable(cs::CropState) = true # TODO: implement this correctly isharvestable(cs::CropState) = true # TODO: implement this correctly
makecropstate(crop_type::CropType, model::SimulationModel, soiltype::SoilType) =
CropState(crop_type, soiltype, model)
function setsoiltype!(cs::CropState, soiltype::SoilType)
# TODO: this does not affect the actual soil type of the state of
# the aquacrop simulation
cs.soiltype = soiltype
return nothing
end
""" """
stepagent!(cropstate, model) stepagent!(cropstate, model)
......
...@@ -32,6 +32,12 @@ end ...@@ -32,6 +32,12 @@ end
Initialise the farm plots in the simulation model. Initialise the farm plots in the simulation model.
""" """
function initfields!(model::SimulationModel) function initfields!(model::SimulationModel)
# TODO: we take the soiltype from the first pixel in the farmplot,
# then later we fix the soiltypes of the farmplots and cropstates
# to be the most common soiltype of a farmplot. It would be
# better to first collect all the data for pixels belonging
# together, and then create the farmplots and cropstates with the
# correct soiltype directly
convertid = Dict{Int64,Int64}() convertid = Dict{Int64,Int64}()
width, height = size(model.landscape) width, height = size(model.landscape)
for x in 1:width for x in 1:width
...@@ -46,7 +52,7 @@ function initfields!(model::SimulationModel) ...@@ -46,7 +52,7 @@ function initfields!(model::SimulationModel)
push!(model.farmplots[objectid].pixels, (x,y)) push!(model.farmplots[objectid].pixels, (x,y))
else else
soiltype = model.landscape[x,y].soiltype soiltype = model.landscape[x,y].soiltype
cropstate = makecropstate(model, soiltype) cropstate = makecropstate(model.crops["natural grass"], model, soiltype)
fp = FarmPlot(length(model.farmplots) + 1, [(x, y)], -1, soiltype, cropstate) fp = FarmPlot(length(model.farmplots) + 1, [(x, y)], -1, soiltype, cropstate)
push!(model.farmplots, fp) push!(model.farmplots, fp)
model.landscape[x,y].fieldid = fp.id model.landscape[x,y].fieldid = fp.id
...@@ -58,48 +64,50 @@ function initfields!(model::SimulationModel) ...@@ -58,48 +64,50 @@ function initfields!(model::SimulationModel)
# Adjust farmplot soil type to most common soil type of its # Adjust farmplot soil type to most common soil type of its
# pixels, and set the cropstate soil type to this as well. # pixels, and set the cropstate soil type to this as well.
for fp in model.farmplots for fp in model.farmplots
fp.soiltype = mode(map(p -> model.landscape[p[1], p[2]].soiltype, fp.pixels)) soiltype = mode(map(p -> model.landscape[p[1], p[2]].soiltype, fp.pixels))
set_cropstate_soiltype!(fp, model) setsoiltype!(fp, soiltype)
end end
@info "Initialised $(length(model.farmplots)) farm plots." @info "Initialised $(length(model.farmplots)) farm plots."
end end
# TODO: this function should be moved to the individual crop models, # # TODO: this function should be moved to the individual crop models,
# and overloaded on the type of cropstate # # and overloaded on the type of cropstate (see notes above)
""" # """
set_cropstate_soiltype!(farmplot, model) # setsoiltype!(farmplot, soiltype, model)
""" # """
function set_cropstate_soiltype!(farmplot::FarmPlot, model::SimulationModel) # function setsoiltype!(farmplot::FarmPlot, soiltype::SoilType, model::SimulationModel)
if @param(crop.cropmodel) == "aquacrop" # farmplot.soiltype = soiltype
farmplot.cropstate.soiltype = farmplot.soiltype # if @param(crop.cropmodel) == "aquacrop"
else # farmplot.cropstate.soiltype = soiltype
# do nothing for other cropmodels # else
end # # do nothing for other cropmodels
end # end
# end
""" # # TODO: move this function to individual crop model files
makecropstate(model, soiltype) # """
# makecropstate(model, soiltype)
An internal utility function to initialise one instance of the configured crop growth model. #
""" # An internal utility function to initialise one instance of the configured crop growth model.
function makecropstate(model::SimulationModel, soiltype::SoilType) # """
if @param(crop.cropmodel) == "almass" # function makecropstate(model::SimulationModel, soiltype::SoilType)
phase = (month(model.date) < 3 ? ALMaSS.janfirst : ALMaSS.marchfirst) # if @param(crop.cropmodel) == "almass"
cs = ALMaSS.CropState( # phase = (month(model.date) < 3 ? ALMaSS.janfirst : ALMaSS.marchfirst)
croptype = model.crops["natural grass"], # cs = ALMaSS.CropState(
phase = phase, # croptype = model.crops["natural grass"],
) # phase = phase,
elseif @param(crop.cropmodel) == "simple" # )
cs = SimpleCrop.CropState( # elseif @param(crop.cropmodel) == "simple"
model.crops["natural grass"], # cs = SimpleCrop.CropState(
0.0m # model.crops["natural grass"],
) # 0.0m
elseif @param(crop.cropmodel) == "aquacrop" # )
croptype = model.crops["natural grass"] # elseif @param(crop.cropmodel) == "aquacrop"
cs = AquaCropWrapper.CropState(croptype, soiltype, model) # croptype = model.crops["natural grass"]
else # cs = AquaCropWrapper.CropState(croptype, soiltype, model)
Base.error("Unhandled crop model '$(@param(crop.cropmodel))' in makecropstate().") # else
end # Base.error("Unhandled crop model '$(@param(crop.cropmodel))' in makecropstate().")
return cs # end
end # return cs
# end
...@@ -23,6 +23,12 @@ cropcover(f::FarmPlot) = cropcover(f.cropstate) ...@@ -23,6 +23,12 @@ cropcover(f::FarmPlot) = cropcover(f.cropstate)
cropyield(f::FarmPlot) = cropyield(f.cropstate) cropyield(f::FarmPlot) = cropyield(f.cropstate)
isharvestable(f::FarmPlot) = isharvestable(f.cropstate) isharvestable(f::FarmPlot) = isharvestable(f.cropstate)
function setsoiltype!(f::FarmPlot, soiltype::SoilType)
f.soiltype = soiltype
setsoiltype!(f.cropstate, soiltype)
return nothing
end
""" """
stepagent!(farmplot, model) stepagent!(farmplot, model)
......
...@@ -4,9 +4,9 @@ using Persefone: ...@@ -4,9 +4,9 @@ using Persefone:
AbstractCropState, AbstractCropState,
AbstractCropType, AbstractCropType,
AnnualDate, AnnualDate,
FarmPlot,
Length, Length,
cm, cm,
SoilType,
SimulationModel SimulationModel
import Persefone: import Persefone:
...@@ -16,6 +16,7 @@ import Persefone: ...@@ -16,6 +16,7 @@ import Persefone:
cropheight, cropheight,
cropcover, cropcover,
cropyield, cropyield,
makecropstate,
sow!, sow!,
harvest!, harvest!,
isharvestable isharvestable
...@@ -43,6 +44,9 @@ cropheight(cs::CropState) = cs.height ...@@ -43,6 +44,9 @@ cropheight(cs::CropState) = cs.height
cropcover(cs::CropState) = 0.0 cropcover(cs::CropState) = 0.0
cropyield(cs::CropState) = 0.0 # TODO: units? cropyield(cs::CropState) = 0.0 # TODO: units?
isharvestable(cs::CropState) = true isharvestable(cs::CropState) = true
makecropstate(crop_type::CropType, model::SimulationModel, soiltype::SoilType) =
CropState(crop_type, 0.0cm)
""" """
stepagent!(cropstate, model) stepagent!(cropstate, model)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment