Model

Signal-Flow Approach in Modelling

Jusdl adopts signal-flow approach in systems modelling. In signal-flow approach, a Model consists of connected components. The components are data processing units and the behavior, i.e, the mathematical model, of the component determines how the data is processed. Connections connects the components each other and the data is transferred between components by means of connections. The data flow through the connections is unidirectional, i.e., a component is driven by other components that write data to its input bus.

Construction of Models

A Model consists of connected components. Here is the constructor,

Jusdl.Models.ModelType
Model(blocks::AbstractVector)

Constructs a Model whose with components blocks which are of type AbstractComponent.

Model()

Constructs a Model with empty components. After the construction, components can be added to Model.

Warning

Models are units that can be simulated. As the data flows through the connections i.e. input output busses of the components, its is important that the components must be connected to each other. See also: simulate

source

That is, the components of are defined first and the Model consisting of these components can be constructed. Or, an empty model can be constructed.

Let us continue with some examples. We will construct very simple Model consisting of a SinewaveGenerator and a Writer. We construct the components first.

julia> using Jusdl # hide

julia> gen = SinewaveGenerator()
SinewaveGenerator(amp:1.0, freq:1.0, phase:0.0, offset:0.0, delay:0.0)

julia> writer = Writer(Bus())
Writer(path:/tmp/126766e3-9ad0-4c83-a570-5c7d2050fdc5.jld2, nin:1)

Next, we construct the model

julia> model = Model(gen, writer)
Model(blocks:AbstractComponent[SinewaveGenerator(amp:1.0, freq:1.0, phase:0.0, offset:0.0, delay:0.0), Writer(path:/tmp/126766e3-9ad0-4c83-a570-5c7d2050fdc5.jld2, nin:1)])

The other way is to construct an empty Model, that is a Model with no components, and then add components later.

julia> using Jusdl # hide

julia> model = Model()
Model(blocks:Any[])

julia> addcomponent(model, SinewaveGenerator())

julia> addcomponent(model, Writer())
ERROR: MethodError: no method matching Writer()
Closest candidates are:
  Writer(!Matched::Bus{#s143} where #s143<:Link{T}; buflen, plugin, path) where T at /home/sari/.julia/dev/Jusdl/src/components/sinks/writer.jl:20

Simulation of Models

A Model to to be simulated consists of components connected to each other an a time reference.

julia> model.blocks    # Model components
1-element Array{Any,1}:
 SinewaveGenerator(amp:1.0, freq:1.0, phase:0.0, offset:0.0, delay:0.0)

julia> model.clk       # Model time reference
Clock(t:NaN, dt:NaN, tf:NaN, paused:false, isrunning:false)

The time reference is used to sample the continuous time signals flowing through the busses of the model and to rigger the components. The simulation is performed by triggering the components with the pulses generated by the time reference at simulation sampling time intervals. Having been triggered, the components evolve themselves, compute their outputs and writes them to their outputs.

Simulation Stages

Inspection

The inspection stage is the first stage of the simulation process. In this stag,e the model is first inspected in terms of whether it is ready for simulation. This inspection is carried out to see whether the model has some inconsistencies such as unterminated busses or presence of algebraic loops. If the model has unterminated busses, the data that is supposed to flow those unterminated busses cannot flow through those busses and the simulation gets stuck. An algebraic is the subset of model components whose output depends directly on their inputs. In such a case, none of the components can produce outputs to break the loop which leads again the obstruction of simulation. Thus, to continue the simulation, the model must not contain any of those inconsistencies. The model inspection is done with inspect function.

Jusdl.Models.inspectFunction
inspect(model::Model)

Inspects the model. If model has some inconsistencies such as including algebraic loops or unterminated busses and error is thrown.

source

Initialization

If the inspection stage results positive, the initialization stage comes next. In this stage, the tasks required for the busses of the model to be both readable and writable are activated and bound the busses. To this end, a reader and writer task are activated and bound to both sides of each bus. To initialize the model, initialize function is used.

Jusdl.Models.initializeFunction
initialize(model::Model)

Initializes model by launching component task for each of the component of model. The pairs component and component tasks are recordedin the task manager of the model. See also: ComponentTask, TaskManager. The model clock is set! and the files of Writer are openned.

source

When the model is initialized, the pairs of components and component tasks are recorded into the task manager of the model. During the rest of the simulation, task manager keeps track of the tasks. Any exception or error that is thrown during the run stage of the simulation can be observed by means of the task manager of the model.

Run

The run stage follows the initialization stage. The tasks activated in the initialization stage wait for the components to be triggered by the model time reference. During the run stage, time reference, that is the model clock, triggers the components by writing pulses that are generated in the intervals of the sampling period of the simulation to their trigger links. The job defined in a task is to read input dat a from the its input bus, to calculate its next state, if any, and output, and write its calculated output to its output bus. The run stage, starts at the initial time of the time reference and continues until the end time of the time reference. run function is used to run the models,

Base.runMethod
run(model::Model)

Runs the model by triggering the components of the model. This triggering is done by generating clock tick using the model clock model.clk. Triggering starts with initial time of model clock, goes on with a step size of the sampling period of the model clock, and finishes at the finishing time of the model clock.

Warning

The model must first be initialized to be run. See also: initialize.

```

source

Termination

After the run stage, the tasks opened in the initialization stage are closed and the simulation is terminated. terminate function is used to terminate the model

Models are constructed to simulate them. During the simulation, components of the Model process data and the data is transferred between the components via connection. Thus, to simulate the Models, the components must be connected. Hence, we connect the components.

julia> connect(gen.output, writer.input)

In our model, the writer is used to record the output of gen. Thus, the flows from gen to writer. Thus, we connect gen output to writer input.

Note

During the Model construction, the order of components are not important. The components cane be given in any order. For instance, in the example above, the Model can be constructed as model = Model(writer, gen).

Full API

Jusdl.Models.addcomponentFunction
addcomponent(model::Model, comp::AbstractComponent)

Adds comp to model components.

Example

julia> m = Model()
Model(blocks:Any[])

julia> addcomponent(m, SinewaveGenerator(), RampGenerator())

julia> m.blocks
2-element Array{Any,1}:
 SinewaveGenerator(amp:1.0, freq:1.0, phase:0.0, offset:0.0, delay:0.0)
 RampGenerator(scale:1.0, delay:0.0) 
source
Jusdl.Connections.releaseMethod
release(model::Model)

Releaes the each component of model, i.e., the input and output bus of each component is released.

source
Jusdl.Models.findinFunction
findin(model::Model, id::UUID)

Returns the component of the model corresponding whose id is id.

findin(model::Model, comp::AbstractComponent)

Returns the compeonent whose variable name is comp.

source
Jusdl.Models.simulateFunction
simulate(model::Model;  simdir::String="/tmp", logtofile::Bool=false, reportsim::Bool=false)

Simulates model. simdir is the path of the directory into which simulation files are saved. If logtofile is true, a log file for the simulation is constructed. If reportsim is true, model components are saved into files.

source
simulate(model::Model, t0::Real, dt::Real, tf::Real; kwargs...)

Simulates the model starting from the initial time t0 until the final time tf with the sampling interval of tf. For kwargs are

  • logtofile::Bool: If true, a log file is contructed logging each step of the simulation.
  • reportsim::Bool: If true, model components are written files after the simulation. When this file is read back, the model components can be consructed back with their status at the end of the simulation.
  • simdir::String: The path of the directory in which simulation file are recorded.
source