Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
simplecrop.jl 1.67 KiB
module SimpleCrop

using Persefone:
    AnnualDate,
    FarmPlot,
    Length,
    cm,
    SimulationModel

import Persefone:
    stepagent!,
    croptype,
    cropname,
    cropheight,
    cropcover,
    cropyield,
    sow!,
    harvest!,
    isharvestable

using Unitful: @u_str

# TODO: alternatively just use ALMaSS.CropType ?
struct CropType
    name::String
    group::String
    minsowdate::Union{Missing,AnnualDate}
    maxsowdate::Union{Missing,AnnualDate}
end

cropname(ct::CropType) = ct.name

mutable struct CropState
    croptype::CropType
    height::Length{Float64}
end

croptype(cs::CropState) = cs.croptype
cropname(cs::CropState) = cropname(croptype(cs))
cropheight(cs::CropState) = cs.height
cropcover(cs::CropState) = 0.0
cropyield(cs::CropState) = 0.0  # TODO: units?
isharvestable(cs::CropState) = true

"""
    stepagent!(farmplot, model)

Update a crop state by one day.
"""
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 = 0.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.0u"g/cm/m^2"
    cs.height = 5.0cm
    return yield
end

end # module SimpleCrop