Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
simulation.jl 2.32 KiB
### Persephone - a socio-economic-ecological model of European agricultural landscapes.
###
### This file includes the core functions for initialising and running simulations.
###

"""
    initialise(config, seed)

Initialise the model: read in parameters, create the output data directory,
and instantiate the AgentBasedModel object.
"""
function initialise(config::String=PARAMFILE)
    @info "Simulation run started at $(Dates.now())."
    #TODO add a seed parameter - requires mutable parameters
    # do some housekeeping
    initsettings(config)
    Random.seed!(param("core.seed"))
    setupdatadir()
    # initialise world-level properties
    landscape = initlandscape()
    events = Vector{FarmEvent}()
    space = GridSpace(size(landscape), periodic=false)
    properties = Dict{Symbol,Any}(:date=>param("core.startdate"),
                                  :landscape=>landscape,
                                  :events=>events)
    @debug "Setting up model."
    model = AgentBasedModel(Union{Farmer,Animal,FarmPlot}, space, properties=properties,
                            rng=Random.Xoshiro(param("core.seed")), warn=false)
    # initialise submodels
    initfarms!(model)
    initfields!(model)
    initnature!(model)
    model
end

"""
    stepsimulation!(model)

Execute one update of the model.
"""
function stepsimulation!(model::AgentBasedModel)
    @info "Simulating day $(model.date)."
    for a in Schedulers.ByType((Farmer,FarmPlot,Animal), true)(model)
        #The animal may have been killed, so we need a try/catch
        try stepagent!(model[a], model) catch keyerror end
    end
    updateevents!(model)
    outputdata(model)
    model.date += Day(1)
end

"""
    finalise(model)

Wrap up the simulation. Currently doesn't do anything except print some information.
"""
function finalise(model::AgentBasedModel)
    @info "Simulated $(model.date-param("core.startdate")) days."
    @info "Simulation run completed at $(Dates.now()),\nwrote output to $(param("core.outdir"))."
    #XXX is there anything to do here?
    #genocide!(model)
end

"""
    simulate(config)

Carry out a complete simulation run.
"""
function simulate(config::String=PARAMFILE)
    model = initialise(config)
    runtime = Dates.value(param("core.enddate")-param("core.startdate"))+1
    step!(model, dummystep, stepsimulation!, runtime)
    finalise(model)
end