Building models

The API for building models with Sims. Includes basic types, models, and functions.

BoolEvent

BoolEvent is a helper for attaching an event to a boolean variable. In conjunction with ifelse, this allows constructs like Modelica's if blocks.

Note that the lengths of d and condition must match for arrays.

BoolEvent(d::Discrete, condition::ModelType)

Arguments

Returns

Examples

See IdealDiode and Limiter in the standard library.

Sims/src/main.jl:1163

Branch

A helper Model to connect a branch between two different nodes and specify potential between nodes and the flow between nodes.

See also RefBranch.

Branch(n1, n2, v, i)

Arguments

Returns

References

This nodal description is based on work by David Broman. See the following:

Examples

Here is the definition of an electrical resistor in the standard library:

function Resistor(n1::ElectricalNode, n2::ElectricalNode, R::Signal)
    i = Current(compatible_values(n1, n2))
    v = Voltage(value(n1) - value(n2))
    @equations begin
        Branch(n1, n2, v, i)
        v = R .* i
    end
end

Sims/src/main.jl:760

addhook!

Add hooks to a Discrete variable.

The propagation and handling of Discrete variables is currently rather simple. It would be nice for Discrete variables to handle data flows like a reactive programming system. This allows for a simple way to add some value propagation.

Arguments

Returns

Examples

function test_BoolEventHook()
    n1 = Voltage("n1")
    sig2 = Discrete(true)
    sig = Discrete(false)
    Sims.addhook!(sig, 
             reinit(sig2, false))
    g = 0.0
    Equation[
        SineVoltage(n1, g, ifelse(sig2, 10.0, 5.0), ifelse(sig, 1.0, 2.0)) 
        BoolEvent(sig, MTime - 0.25)  
        Resistor(n1, g, 1e-3)
    ]
end
y = sim(test_BoolEventHook())

Sims/src/main.jl:992

compatible_values

A helper functions to return the base value from an Unknown to use when creating other Unknowns. It is especially useful for taking two model arguments and creating a new Unknown compatible with both arguments.

compatible_values(x,y)
compatible_values(x)

It's still somewhat broken but works for basic cases. No type promotion is currently done.

Arguments

Returns

The returned object has zeros of type and length common to both x and y.

Examples

a = Unknown(45.0 + 10im)
x = Unknown(compatible_values(a))   # Initialized to 0.0 + 0.0im.
a = Unknown()
b = Unknown([1., 0.])
y = Unknown(compatible_values(a,b)) # Initialized to [0.0, 0.0].

Sims/src/main.jl:633

delay

A Model specifying a delay to an Unknown.

Internally, Unknowns that are delayed store past history. This is interpolated as needed to find the delayed quantity.

delay(x::Unknown, val)

Arguments

Returns

Sims/src/main.jl:871

der

Represents the derivative of an Unknown.

der(x::Unknown)
der(x::Unknown, val)

Arguments

Examples

a = Unknown()
der(a) + 1

Sims/src/main.jl:287

ifelse

A function allowing if-then-else action for objections and expressions.

Note that when this is used in a model, it does not trigger an event. You need to use Event or BoolEvent for that. It is used often in conjunction with Event.

ifelse(x, y)
ifelse(x, y, z)

Arguments

Returns

Examples

See DeadZone and Limiter in the standard library.

Sims/src/main.jl:1206

is_unknown

Is the object an UnknownVariable?

Sims/src/main.jl:237

mexpr

Create MExpr's (model expressions). Analogous to expr in Base.

This is also useful for wrapping user-defined functions where the built-in mechanisms don't work.

mexpr(head::Symbol, args::ANY...)

Arguments

Returns

Examples

a = Unknown()
b = Unknown()
d = a + sin(b)
typeof(d)
myfun(x) = mexpr(:call, :myfun, x)

Sims/src/main.jl:347

name

The name of an UnknownVariable.

name(a::UnknownVariable)

Arguments

Returns

Examples

a = Unknown("var1")
name(a)

Sims/src/main.jl:593

pre

The value of a Discrete variable x prior to an event.

See also Event.

pre(x::DiscreteVar)

Arguments

Returns

Sims/src/main.jl:1018

reinit

reinit is used in Event responses to redefine variables.

reinit(x::DiscreteVar, y)

Arguments

Returns

Examples

Here is the definition of Step in the standard library:

function Step(y::Signal, 
              height = 1.0,
              offset = 0.0, 
              startTime = 0.0)
    ymag = Discrete(offset)
    @equations begin
        y = ymag  
        Event(MTime - startTime,
              Equation[reinit(ymag, offset + height)],   # positive crossing
              Equation[reinit(ymag, offset)])            # negative crossing
    end
end

See also IdealThyristor in the standard library.

Sims/src/main.jl:1112

value

The value of an object or UnknownVariable.

value(x)

Arguments

Returns

For standard Julia objects, value(x) returns x. For Unknowns and other ModelTypes, returns the current value of the object. value evaluates immediately, so don't expect to use this in model expressions, except to grab an immediate value.

Examples

v = Voltage(value(n1) - value(n2))

Sims/src/main.jl:557

Equation

Equations are used in Models. Right now, Equation is defined as Any, but that may change. Normally, Equations are of type Unknown, DerUnknown, MExpr, or Array{Equation} (for nesting models).

Examples

Models return Arrays of Equations. Here is an example:

function Vanderpol()
    y = Unknown(1.0, "y")
    x = Unknown("x")
    Equation[
        der(x, -1.0) - ((1 - y^2) * x - y)      # == 0 is assumed
        der(y) - x
    ]
end
dump( Vanderpol() )

Sims/src/main.jl:483

MTime

The model time - a special unknown variable.

Sims/src/main.jl:648

Model

Represents a vector of Equations. For now, Equation equals Any, but in the future, it may only include ModelType's.

Models return Arrays of Equations.

Examples

function Vanderpol()
    y = Unknown(1.0, "y")
    x = Unknown("x")
    Equation[
        der(x, -1.0) - ((1 - y^2) * x - y)      # == 0 is assumed
        der(y) - x
    ]
end
dump( Vanderpol() )
x = sim(Vanderpol(), 50.0)

Sims/src/main.jl:507

@equations

A helper to make writing Models a little easier. It allows the use of = in model equations.

@equations begin
    ...
end

Arguments

Returns

Examples

The following are both equivalent:

function Vanderpol1()
    y = Unknown(1.0, "y")
    x = Unknown("x")
    Equation[
        der(x, -1.0) - ((1 - y^2) * x - y)      # == 0 is assumed
        der(y) - x
    ]
end
function Vanderpol2()
    y = Unknown(1.0, "y") 
    x = Unknown("x")
    @equations begin
        der(x, -1.0) = (1 - y^2) * x - y
        der(y) = x
    end
end

Sims/src/main.jl:1382

DefaultUnknown

The default UnknownCategory.

Sims/src/main.jl:152

DerUnknown

An UnknownVariable representing the derivitive of an Unknown, normally created with der(x).

Arguments

Examples

a = Unknown()
der(a) + 1
typeof(der(a))

Sims/src/main.jl:257

Discrete

Discrete is a type for discrete variables. These are only changed during events. They are not used by the integrator. Because they are not used by the integrator, almost any type can be used as a discrete variable.

Discrete()
Discrete(x)
Discrete(s::Symbol, label::String)
Discrete(x, label::String)
Discrete(label::String)
Discrete(s::Symbol, x)
Discrete(s::Symbol, x, label::String)

Arguments

Details

Discrete variables are currently quite limited. You cannot have systems of equations where the values of Discrete variables propagates easily. A crude mechanism for some chaining is provided by addhook!. It would be nice to have data flow support (reactive programming). The package Reactive.jl may help here.

Sims/src/main.jl:915

DiscreteVar

A helper type used inside of the residual function.

Sims/src/main.jl:948

Event

Event is the main type used for hybrid modeling. It contains a condition for root finding and model expressions to process after positive and negative root crossings are detected.

See also BoolEvent.

Event(condition::ModelType, pos_response, neg_response)

Arguments

Examples

See IdealThyristor in the standard library.

Sims/src/main.jl:1046

InitialEquation

A ModelType describing initial equations. Current support is limited and may be broken. There are no tests. The idea is that the equations provided will only be used during the initial solution.

InitialEquation(eqs)

Arguments

Sims/src/main.jl:790

LeftVar

A helper type needed to mark unknowns as left-side variables in assignments during event responses.

Sims/src/main.jl:1070

MExpr

Represents expressions used in models.

MExpr(ex::Expr)

Arguments

Examples

a = Unknown()
b = Unknown()
d = a + sin(b)
typeof(d)

Sims/src/main.jl:314

ModelType

The main overall abstract type in Sims.

Sims/src/main.jl:136

Parameter{T<:UnknownCategory}

Represents an Unknown that stays constant through a simulation. Useful for passing in at the top level.

Parameter(s::Symbol, value)
Parameter(value)
Parameter(s::Symbol, label::String)
Parameter(value, label::String)

Arguments

Sims/src/main.jl:368

PassedUnknown

An UnknownVariable used as a helper for the delay function. It is an identity unknown, but it doesn't replace with a reference to the y array.

PassedUnknown(ref::UnknownVariable)

Arguments

Sims/src/main.jl:815

RefBranch

A special ModelType to specify branch flows into nodes. When the model is flattened, equations are created to zero out branch flows into nodes.

See also Branch.

RefBranch(n, i) 

Arguments

References

This nodal description is based on work by David Broman. See the following:

Modelyze has both RefBranch and Branch.

Examples

Here is an example of RefBranch used in the definition of a HeatCapacitor in the standard library. hp is the reference node (a HeatPort aka Temperature), and Q_flow is the flow variable.

function HeatCapacitor(hp::HeatPort, C::Signal)
    Q_flow = HeatFlow(compatible_values(hp))
    @equations begin
        RefBranch(hp, Q_flow)
        C .* der(hp) = Q_flow
    end
end

Here is the definition of SignalCurrent from the standard library a model that injects current (a flow variable) between two nodes:

function SignalCurrent(n1::ElectricalNode, n2::ElectricalNode, I::Signal)  
    @equations begin
        RefBranch(n1, I) 
        RefBranch(n2, -I) 
    end
end

Sims/src/main.jl:707

RefDiscrete

A helper type for Discretes used in Arrays.

Sims/src/main.jl:939

RefUnknown{T<:UnknownCategory}

An UnknownVariable used to allow Arrays as Unknowns. Normally created with getindex. Defined methods include:

Sims/src/main.jl:522

StructuralEvent

StructuralEvent defines a type for elements that change the structure of the model. An event is created where the condition crosses zero. When the event is triggered, the model is re-flattened after replacing default with new_relation in the model.

StructuralEvent(condition::MExpr, default, new_relation::Function,
                pos_response, neg_response)

Arguments

Examples

Here is an example from examples/breaking_pendulum.jl:

function FreeFall(x,y,vx,vy)
    @equations begin
        der(x) = vx
        der(y) = vy
        der(vx) = 0.0
        der(vy) = -9.81
    end
end

function Pendulum(x,y,vx,vy)
    len = sqrt(x.value^2 + y.value^2)
    phi0 = atan2(x.value, -y.value) 
    phi = Unknown(phi0)
    phid = Unknown()
    @equations begin
        der(phi) = phid
        der(x) = vx
        der(y) = vy
        x = len * sin(phi)
        y = -len * cos(phi)
        der(phid) = -9.81 / len * sin(phi)
    end
end

function BreakingPendulum()
    x = Unknown(cos(pi/4), "x")
    y = Unknown(-cos(pi/4), "y")
    vx = Unknown()
    vy = Unknown()
    Equation[
        StructuralEvent(MTime - 5.0,     # when time hits 5 sec, switch to FreeFall
            Pendulum(x,y,vx,vy),
            () -> FreeFall(x,y,vx,vy))
    ]
end

p_y = sim(BreakingPendulum(), 6.0)  

Sims/src/main.jl:1291

UnknownCategory

Categories of Unknown types; used to subtype Unknowns.

Sims/src/main.jl:147

UnknownVariable

An abstract type for variables to be solved. Examples include Unknown, DerUnknown, and Parameter.

Sims/src/main.jl:142

Unknown{T<:UnknownCategory}

An Unknown represents variables to be solved in Sims. An Unknown is a symbolic type. When used in Julia expressions, Unknowns combine into MExprs which are symbolic representations of equations.

Expressions (of type MExpr) are built up based on Unknown's. Unknown is a symbol with a uniquely generated symbol name. If you have

Unknowns can contain Float64, Complex, and Array{Float64} values. Additionally, Unknowns can be extended to support other types. All Unknown types currently map to positions in an Array{Float64}.

In addition to a value, Unknowns can carry additional metadata, including an identification symbol and a label. In the future, unit information may be added.

Unknowns can also have type parameters. For example, Voltage is defined as Unknown{UVoltage} in the standard library. The UVoltage type parameter is a marker to distinguish those Unknown from others. Users can add their own Unknown types. Different Unknown types makes it easier to dispatch on model arguments.

Unknown(s::Symbol, x, label::String, fixed::Bool)
Unknown()
Unknown(x)
Unknown(s::Symbol, label::String)
Unknown(x, label::String)
Unknown(label::String)
Unknown(s::Symbol, x, fixed::Bool)
Unknown(s::Symbol, x)
Unknown{T}(s::Symbol, x, label::String, fixed::Bool)
Unknown{T}()
Unknown{T}(x)
Unknown{T}(s::Symbol, label::String)
Unknown{T}(x, label::String)
Unknown{T}(label::String)
Unknown{T}(s::Symbol, x, fixed::Bool)
Unknown{T}(s::Symbol, x)

Arguments

Examples

  a = 4
  b = Unknown(3.0, "len")
  a * b + b^2

Sims/src/main.jl:210