### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe. ### ### This file is responsible for managing the farm module(s). ### ##TODO what data do we need to gather from the farm submodel? """ Farmer This is the agent type for the farm ABM. (Not yet implemented.) """ mutable struct Farmer <: ModelAgent #XXX make this into an abstract type and create subtypes for different farm submodels? (#69) const id::Int64 fields::Vector{Int64} # IDs of the farmplots this farmer owns croprotation::Vector{String} #TODO figure this out totalincome::Float64 end """ stepagent!(farmer, model) Update a farmer by one day. """ function stepagent!(farmer::Farmer, model::SimulationModel) for f in farmer.fields field = model.farmplots[f] ctype = croptype(field) if ctype.group != "semi-natural" && isharvestable(field) harvest!(field, model) #XXX later: calculate income based on yield and annual price (ctype.group != "grass") && @sow("no growth") elseif cropname(field) == "no growth" #TODO if a field has been harvested, check if the next crop can be sown end end end """ initfarms!(model) Initialise the model with a set of farm agents. """ function initfarms!(model::SimulationModel) #XXX initially, we only have one farmer controlling all fields in the region farmer = Farmer(1, collect(1:length(model.farmplots)), [], 0) model.farmers = [farmer] setasides = findsetasides(farmer, model) for field in model.farmplots if isgrassland(field, model) @sow("permanent grassland (seeded)") elseif field.id in setasides @sow("permanent set-aside") else @sow("no growth") end end end """ findsetasides(farmer, model) Return a vector of field IDs that this farmer should keep fallow to satisfy the configured set-aside rules. """ function findsetasides(farmer::Farmer, model::SimulationModel) @param(farm.setaside) == 0 && return [] croparea = @areaof(sum(f -> isgrassland(f, model) ? 0 : length(f.pixels), model.farmplots[farmer.fields])) setasidearea = 0m² setasides = [] for f in farmer.fields #XXX should be sorted smallest-largest for highest efficiency field = model.farmplots[f] isgrassland(field, model) && continue push!(setasides, f) setasidearea += @areaof(length(field.pixels)) if setasidearea >= croparea*@param(farm.setaside) @debug "Farmer $(farmer.id) has set aside $(setasidearea |> ha)." return setasides end end end