AlgebraicJulia / StockFlow.jl

https://algebraicjulia.github.io/StockFlow.jl/
MIT License
65 stars 6 forks source link

AlgebraicStockFlow

Stable Documentation CI/CD Code Coverage

StockFlow.jl is a Julia library for the creation and execution of stock and flow modeling diagrams, designed with model composition and stratification in mind through a categorical approach.

Stock-flow diagrams are used to represent systems where its population can move between different states, such as tracking how many people have been infected or recovered from a disease. By providing initial values, and values for the parameters, we can solve the differential equation which the stock-flow diagram represents, which gives us a graph for how the population varies over time.

In this particular schema, stock-flow diagrams consist of stocks, flows, dynamic variables, sum variables, parameters, and the links between them.

Stock-flow diagrams can be created and manipulated using the StockFlow and StockFlow.Syntax modules, the latter of which includes the domain specific language for easier creation.

Stock-flow diagrams can be composed and stratified - that is, combined on stocks and sum variables or split into subpopulations. One can also do algebraic rewriting for more manual, specific fixes, such as preventing a dynamic variable from unnecessarily being computed twice, or substituting one parameter for another.

Examples of the domain specific language, composition, stratification and algebraic rewriting can be seen in the examples folder. In particular, full_fledged_schema_examples_new contains examples which use the domain specific language.

Example interpretation of a stock and flow diagram using an ODE solver

From the SEIR Composition Example:

seir = @stock_and_flow begin
    :stocks
    S
    E
    I
    R

    :parameters
    μ
    β
    tlatent
    trecovery
    δ

    :flows
    ☁ => fbirth(μ * N) => S # dynamic variables can be defined implicitly or with :dynamic_variables
    S => fincid(β * S * I / N) => E
    S => fdeathS(S * δ) => ☁
    E => finf(E / tlatent) => I
    E => fdeathE(E * δ) => ☁
    I => frec(I / trecovery) => R
    I => fdeathI(I * δ) => ☁
    R => fdeathR(R * δ) => ☁

    :sums
    N = [S, E, I, R]

end

# define parameter values and initial values of stocks
# define constant parameters
p_measles = LVector(
    β=49.598, μ=0.03/12, δ=0.03/12, tlatent=8.0/30, trecovery=5.0/30
)

# define initial values for stocks
u0_measles = LVector(
    S=90000.0-930.0, E=0.0, I=930.0, R=773545.0
)

prob_measles = ODEProblem(vectorfield(seir),u0_measles,(0.0,120.0),p_measles);
sol_measles = solve(prob_measles,Tsit5(),abstol=1e-8);
plot(sol_measles)

See the full example for additional comments and the chickenpox model.

Note

This library is under active development and does not yet have an official release.