JinraeKim / FSimBase.jl

The lightweight base package for numerical simulation supporting nested dynamical systems and macro-based data logger. For more functionality, see FlightSims.jl.
MIT License
5 stars 1 forks source link

FSimBase

FSimBase.jl is the lightweight base library for numerical simulation supporting nested dynamical systems and macro-based data logger, compatible with DifferentialEquations.jl.

Notes

APIs

Main APIs are provided in src/APIs.

Make an environment

Simulation, logging, and data saving & loading

Simulator

Non-interactive interface (e.g., compatible with callbacks from DifferentialEquations.jl)

Interactive interface (you should be aware of how to use integrator interface in DifferentialEquations.jl)

Utilities

Examples

Custom environments, discrete problems, etc.

See directory ./test.

(TL; DR) Minimal example

using FSimBase
using DifferentialEquations
using ComponentArrays
using Test
using LinearAlgebra
using DataFrames

function main()
    state0 = [1.0, 2.0]
    p = 1
    tf = 1.0
    Δt = 0.01
    @Loggable function dynamics!(dx, x, p, t)
        @log t
        @log x
        dx .= -p.*x
    end
    simulator = Simulator(
                          state0, dynamics!, p;
                          Problem=ODEProblem,
                          solver=Tsit5(),
                          tf=tf,
                         )
    # solve approach (automatically reinitialised)
    @time _df = solve(simulator; savestep=Δt)
    # interactive simulation
    ## step!
    reinit!(simulator)
    step!(simulator, Δt)
    @test simulator.integrator.t ≈ Δt
    ## step_until! (callback-like)
    ts_weird = 0:Δt:tf+Δt
    df_ = DataFrame()
    reinit!(simulator)
    @time for t in ts_weird
        flag = step_until!(simulator, t)  # flag == false if step is inappropriate
        if simulator.integrator.u[1] < 5e-1
            break
        else
            push!(simulator, df_, flag)  # push data only when flag == true
        end
    end
    println(df_[end-5:end, :])
    ## step_until!
    df = DataFrame()
    reinit!(simulator)
    @time for t in ts_weird
        step_until!(simulator, t)
        push!(simulator, df)  # flag=true is default
        # safer way:
        # flag = step_until!(simulator, t)
        # push!(simulator, df, flag)
        # or, equivalently,
        # push!(simulator, df, step_until!(simulator, t))  # compact form
    end
    println(df[end-5:end, :])
    @test norm(_df.sol[end].x - df.sol[end].x) < 1e-6
    @test simulator.integrator.t ≈ tf
end

@testset "minimal" begin
    main()
end

ex_screenshot

Related packages

Dependencies