Skip to content
Snippets Groups Projects
Commit e5e9dee4 authored by xo30xoqa's avatar xo30xoqa
Browse files

Made farm model configurable

closes #69
parent 74d2d078
No related branches found
No related tags found
No related merge requests found
......@@ -165,6 +165,10 @@ A utility function to make sure that a number is within a given set of bounds.
Returns `max`/`min` if `x` is greater/less than this.
"""
function bounds(x::Number; max::Number=Inf, min::Number=0)
if unit(x) != NoUnits
max = max*unit(x)
min = min*unit(x)
end
x > max ? max :
x < min ? min :
x
......
......@@ -3,6 +3,31 @@
### This file is responsible for managing the farm module(s).
###
## GENERIC TYPES AND FUNCTIONS
"This is the agent type for the farm ABM."
abstract type Farmer <: ModelAgent end
stepagent!(f::Farmer, model::SimulationModel) =
@error "Farmer type $(typeof(f)) has no stepagent!() method."
"""
initfarms!(model)
Initialise the model with a set of farm agents, depending on the configured farm model.
"""
function initfarms!(model::SimulationModel)
if @param(farm.farmmodel) == "BasicFarmer"
initbasicfarms!(model)
else
Base.error("Farm model $(@param(farm.farmmodel)) doesn't exist.")
end
end
## BASIC FARM MODEL
#XXX Initially, we're only working with a single simple crop rotation.
# Later on, we need to figure out how to integrate several.
const CROPROTATION = ["winter rape", "winter wheat", "maize", "winter barley"]
......@@ -10,12 +35,11 @@ const CROPROTATION = ["winter rape", "winter wheat", "maize", "winter barley"]
#FIXME Currently, this is specific to the ALMaSS model. We need to figure out how to generalise it.
"""
Farmer
BasicFarmer
This is the agent type for the farm ABM.
The BasicFarmer type simply applies a set crop rotation to his fields and keeps track of income.
"""
mutable struct Farmer <: ModelAgent
#XXX make this into an abstract type and create subtypes for different farm submodels? (#69)
mutable struct BasicFarmer <: Farmer
const id::Int64
# farmplots owned by this farmer and their associated crop rotations and next sowing date
fields::Vector{Int64}
......@@ -29,7 +53,7 @@ end
Update a farmer by one day. Cycle through all fields and see what management is needed.
"""
function stepagent!(farmer::Farmer, model::SimulationModel)
function stepagent!(farmer::BasicFarmer, model::SimulationModel)
for f in farmer.fields
field = model.farmplots[f]
ctype = croptype(field)
......@@ -50,13 +74,13 @@ function stepagent!(farmer::Farmer, model::SimulationModel)
end
"""
initfarms!(model)
initbasicfarms!(model)
Initialise the model with a set of farm agents.
Initialise the basic farm model. All fields are controlled by a single farmer actor
and are assigned as grassland, set-aside, or arable land with a crop rotation.
"""
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)), Dict(), Dict(), 0)
function initbasicfarms!(model::SimulationModel)
farmer = BasicFarmer(1, collect(1:length(model.farmplots)), Dict(), Dict(), 0)
model.farmers = [farmer]
setasides = findsetasides(farmer, model)
for field in model.farmplots
......@@ -83,7 +107,7 @@ end
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)
function findsetasides(farmer::BasicFarmer, model::SimulationModel)
@param(farm.setaside) == 0 && return []
croparea = @areaof(sum(f -> isgrassland(f, model) ? 0 : length(f.pixels),
model.farmplots[farmer.fields]))
......
......@@ -69,7 +69,7 @@ function initskylarkdata(model::SimulationModel)
newdataoutput!(model, "skylark_abundance",
["Date", "TotalAbundance", "Mating", "Breeding",
"Nonbreeding", "Juvenile", "Migrants"],
"daily", skylarkabundance, skylarkpopulation)
@param(nature.popoutfreq), skylarkabundance, skylarkpopulation)
# newdataoutput!(model, "skylark_territories", ["Date", "ID", "X", "Y"],
# skylarkterritories, "monthly") #TODO add plotting function
newdataoutput!(model, "skylark_breeding",
......
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