ABMEv_runworld.jl 2.84 KB
Newer Older
1
"""
Victor's avatar
Victor committed
2
    function run!(w::World{A,S,T},alg::L,tend::Number,b,d;dt_saving=nothing,cb=(names = String[],agg =nothing))
Victor's avatar
Victor committed
3

Victor's avatar
Victor committed
4
5
Run `w` with algorithm `alg`, until `tend` is reached. User needs to provide `b` the birth function,
which takes as arguments `X,t`, and provide `d` the death function, with arguments `X,Y,t`.
6
Returns a `Simulation` type.
7
- if `dt_saving` specified, world is saved every time steps.
8
If `dt_saving` not specified, `sim` contains an array of two elements,
Victor's avatar
Victor committed
9
first corresponding to initial conditions and last corresponding to world in the last time step.
10
11
- if `t_saving_cb::Array{Float64}` specified, callbacks are computed at each steps time specified in the array.
This functionality is as of now only compatible with `dt_saving` not specified.
Victor's avatar
Victor committed
12
- `cb` correspond to callbacks function. Look at the documentation for more information
Victor's avatar
Victor committed
13
- the run stops if the number of agents reaches`p["NMax"]`.
14
"""
Victor's avatar
Victor committed
15
function run!(w::World{A,S,T},alg::L,tend::Number,b,d;
16
                dt_saving=nothing,
17
                t_saving_cb=nothing,
Victor's avatar
Victor committed
18
                cb=nothing) where {A,S,T,L<:AbstractAlg}
19
    # argument check
Victor's avatar
Victor committed
20
    _check_timedep(b,d)
21
22
23
24
25
    (!isnothing(dt_saving) && !isnothing(dt_saving)) ? ArgumentError("For now, can not specify both `dt_saving` and `t_saving_cb`") : nothing
    isnothing(dt_saving) ? dt_saving =  tend + 1. : nothing
    isnothing(t_saving_cb) ? t_saving_cb =  [tend + 1.] : nothing

    # var init
Victor's avatar
Victor committed
26
    n=size(w);
Victor's avatar
Victor committed
27
    NMax = maxsize(w)
28
    t = .0
Victor's avatar
Victor committed
29
30
31
    i = 1;j=1;dt = 0.
    sim = Simulation(w,cb=cb)
    if A <: AbstractAgent{AA,Rates{true}} where {AA}
Victor's avatar
Victor committed
32
        update_rates!(w,alg,b,d)
Victor's avatar
Victor committed
33
    end
34
35

    # start
Victor's avatar
Victor committed
36
    while t<tend
37
38
        if dt < 0
            throw("We obtained negative time step dt = $dt at event $i")
Victor's avatar
Victor committed
39
        elseif size(w) == NMax
Victor's avatar
Victor committed
40
            @info "We have reached the maximum number of individuals allowed"
41
            break
Victor's avatar
Victor committed
42
        elseif size(w) == 0
Victor's avatar
Victor committed
43
            @info "All individuals have died :("
44
45
            break
        end
Victor's avatar
Victor committed
46
        if  t - get_tend(sim) >= dt_saving
Victor's avatar
Victor committed
47
            # @info "saving world @ t = $(t)/ $(tend)"
Victor's avatar
Victor committed
48
            add_entry!(sim,w,cb)
49
        end
50
        if  t >= first(t_saving_cb)
Victor's avatar
Victor committed
51
            # @info "saving callback only @ t = $(t)/ $(tend)"
Victor's avatar
Victor committed
52
            add_entry_cb_only!(sim,w,cb)
53
54
            popfirst!(t_saving_cb)
        end
Victor's avatar
Victor committed
55
        dt = updateWorld!(w,alg,b,d)
Victor's avatar
Victor committed
56
        t +=  dt
57
58
        i += 1
    end
Victor's avatar
Victor committed
59
    # Saving last time step
Victor's avatar
Victor committed
60
    add_entry!(sim,w,cb)
vboussange's avatar
vboussange committed
61
    @info "simulation stopped at t=$(t), after $(i) steps"
Victor's avatar
Victor committed
62
    return sim
63
end
64
65

"""
Victor's avatar
Victor committed
66
    function _correct_timedep!(p::Dict)
67
68
69
70

checks time dependency of birth and death functions,
and overloads the function if not provided
"""
Victor's avatar
Victor committed
71
72
function _check_timedep(b,d)
    if numargs(b) < 2
73
74
        throw(ArgumentError("Birth function needs `X` and `t` arguments"))
    end
Victor's avatar
Victor committed
75
    if numargs(d) < 3
76
77
78
        throw(ArgumentError("Death function needs `X`, `Y` and `t` arguments"))
    end
end