Engee documentation

Sub-components and inheritance of the Engee physical Modeling language

This article discusses how using the physical modeling language Engee it is possible to build more complex models by assembling from sub-components. This mechanism allows you to organize a hierarchy of elements, make models reusable and more compact.

Component inheritance

Sometimes a new component is very similar to an existing one, and there is no point in rewriting the entire component. To do this, the Engee physical modeling language uses the construction @extend which allows you to inherit variables and equations from another physical component.

@extend Branch
@extend Branch(i = 0)

All parameters/variables/sub-components with access=Public from Branch will be automatically visible in the inherited component.

Apply @extend it is possible only once inside one component.
@engeemodel Branch begin
    @nodes begin
        p = EngeePhysicalFoundation.Electrical.Pin, [label="+", side="left"]
        n = EngeePhysicalFoundation.Electrical.Pin, [label="−", side="right"]
    end
    @variables begin
        i = 0, [unit="A", description="Current"]
        v = 0, [unit="V", description="Voltage"]
    end
    @branches begin
        i: (p.i, n.i)
    end
    @equations begin
        v ~ p.v - n.v
        domain_connect(n, p)
    end
end

@engeemodel Resistor begin
    @extend Branch
    @parameters begin
        R = 1, [unit="Ohm", description="Resistance"]
    end
    @intermediates begin
        power_dissipated = R * i^2
    end
    @equations begin
        assert(R > 0.0)
        v ~ R * i
    end
end

@engeemodel Capacitor begin
    @extend Branch
    @parameters begin
        C = 1e-6, [unit="F", description="Capacitance"]
    end
    @equations begin
        assert(C > 0.0)
        i ~ C * der(v)
    end
end

@engeemodel Inductor begin
    @extend Branch
    @parameters begin
        L = 1e-6, [unit="H", description="Inductance"]
    end
    @equations begin
        assert(L > 0.0)
        v ~ L * der(i)
    end
end

In the above example, the component is declared Branch with a description of ports, variables, branches and equations, and in components Resistor, Capacitor, Inductor all content is inherited Branch using the construction @extend and they are supplemented with parameters and equations specific to each component.

Sub-components

Sub-components are ordinary physical components that can be embedded inside other physical components. They are created using the construction @components.

@components begin
    diode     = EngeePhysicalFoundation.Electrical.Elements.PieceWiseLinearDiode(v_forward = 0.6, R_on = 0.3, G_off = 1e-8)
    capacitor = EngeePhysicalFoundation.Electrical.Elements.Capacitor(C = 1e-4)
end

Here, two sub-components have been added to the new component: a diode and a capacitor. In the arguments of the sub-component constructor, you can immediately set the parameters (v_forward, R_on, C etc.).

Example of passing values

You can use the parameters of the main component as the parameter values of the sub-components, and you do not need to specify the units of measurement.

@engeemodel A begin
    @variables begin
        a = 1
        b[:] = [1, 2]
    end
    @parameters begin
        c = 3
        d[:] = [3, 4]
    end
    @equations begin
        a^2 ~ 2
        b[1] * b[2] ~ 5
        b[1]^2 ~ 12
    end
end

@engeemodel B begin
    @components begin
        a1 = A(a = 2, b = [3, 4.0], c = 1, d = [5, 6])
        a2 = A(a = e, b = f*2, c = sin(e), d = f .+ 2)
    end
    @parameters begin
        e = 3
        f[:] = [3,4]
    end
end

In this example:

  • For a1 values are passed directly: numbers and arrays;

  • For a2 the parameters of the component are used B: e, f;

  • When passing values, you can use expressions: f*2, sin(e), f .+ 2;

  • You don’t need to specify units of measurement — Engee automatically uses units from the parameter declaration in the component A.

Arrays of sub-components

Sub-components can be set not only one at a time, but also in arrays.

@engeemodel ArrayExample begin
    @components begin
        res = [EngeePhysicalFoundation.Electrical.Elements.Resistor() for i in 1:5]
        cap = [EngeePhysicalFoundation.Electrical.Elements.Capacitor() for i in 1:3]
    end
end

Features:

  • The sub-components are accessed like regular Julia arrays. Example: connect(diode[1].p, capacitor[3].p).

  • The names of the elements for external use will be of the form diode_1, diode_2, …​ and capacitor_1, capacitor_2, …

This is convenient if you need to connect a group of identical elements at once (for example, several diodes or capacitors).

Connections of sub-components

Function connect(…​) solves two problems:

  1. Connects sub-components with each other;

  2. Connects the port of the sub-component to the port of the main component.

@engeemodel RC begin
    @nodes begin
        p = EngeePhysicalFoundation.Electrical.Pin
        n = EngeePhysicalFoundation.Electrical.Pin
    end

    @components begin
        r = EngeePhysicalFoundation.Electrical.Elements.Resistor(R = 1000)
        c = EngeePhysicalFoundation.Electrical.Elements.Capacitor(C = 1e-6)
    end

    @equations begin
        connect(r.n, c.p)  # (1) соединяем подкомпоненты между собой
        connect(p, r.p)    # (2) соединяем порт r.p с внешним портом p
        connect(c.n, n)    # (2) соединяем порт c.n с внешним портом n
    end
end