ModelicaReference ModelicaReference

This package is a reference to Modelica keywords, Modelica builtin operators, and the Modelica grammar. It is based on the Modelica Language Specification version 3.4 from 10th April 2017. Currently, not the whole Modelica language is documented in ModelicaReference (but a large subset).

Copyright © 2003-2020, Modelica Association and contributors

This Modelica package is free software and the use is completely at your own risk; it can be redistributed and/or modified under the terms of the 3-Clause BSD license. For license conditions (including the disclaimer of warranty) visit https://modelica.org/licenses/modelica-3-clause-bsd.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

Package Content

Name Description
ModelicaReference.ModelicaGrammar ModelicaGrammar Modelica Grammar
ModelicaReference.Annotations Annotations Annotations
ModelicaReference.Classes Classes Classes (model, function, ...)
ModelicaReference.Operators Operators Operators (+, der, size, ...)
ModelicaReference.BalancedModel BalancedModel Balanced model
ModelicaReference.'encapsulated' 'encapsulated' encapsulated
ModelicaReference.'extends' 'extends' extends
ModelicaReference.'flow' 'flow' flow
ModelicaReference.'for' 'for' for
ModelicaReference.'if' 'if' if
ModelicaReference.'import' 'import' import
ModelicaReference.'input' 'input' input
ModelicaReference.'output' 'output' output
ModelicaReference.'partial' 'partial' partial
ModelicaReference.StateMachines StateMachines State Machines
ModelicaReference.'stream' 'stream' stream
ModelicaReference.Synchronous Synchronous Synchronous Language Elements
ModelicaReference.'time' 'time' time
ModelicaReference.'when' 'when' when
ModelicaReference.'while' 'while' while
ModelicaReference.Contact Contact Contact
ModelicaReference.Icons Icons Library of icons

ModelicaReference.ModelicaGrammar ModelicaReference.ModelicaGrammar

Modelica 3.4 Grammar

Modelica 3.4 Grammar

This is the grammar of Modelica 3.4 in EBNF form. Each non-terminal appearing on the right hand side of a production is a link to the production for that non-terminal. This grammar is identical to that in the Modelica 3.4 specification except for removal of some unnecessary parentheses, grouping of some common terms, and reformatting for easier readability. The following typographic conventions are used:

Stored Definition

stored_definition:
        [ within [ name ] ";" ] { [ final ] class_definition ";" }

Class Definition

class_definition:
        [ encapsulated ] class_prefixes class_specifier

class_prefixes:
        [ partial ]
        ( class | model | [ operator ] record | block | [ expandable ] connector
          | type | package | [ pure | impure ] [ operator ] function | operator )

class_specifier:
        long_class_specifier | short_class_specifier | der_class_specifier

long_class_specifier:
        IDENT string_comment composition end IDENT
        | extends IDENT [ class_modification ] string_comment composition end IDENT

short_class_specifier:
        IDENT "=" base_prefix type_specifier [ array_subscripts ] [ class_modification ] comment
        | IDENT "=" enumeration "(" ( [ enum_list ] | ":" ) ")" comment

der_class_specifier:
        IDENT "=" der "(" type_specifier "," IDENT { "," IDENT } ")" comment

base_prefix:
        [ input | output ]

enum_list:
        enumeration_literal { "," enumeration_literal }

enumeration_literal:
        IDENT comment

composition:
        element_list
        { public element_list | protected element_list | equation_section | algorithm_section }
        [ external [ language_specification ]
          [ external_function_call ] [ annotation_comment ] ";" ]
        [ annotation_comment ";" ]

language_specification:
        STRING

external_function_call:
        [ component_reference "=" ] IDENT "(" [ expression_list ] ")"

element_list:
        { element ";" }

element:
        import_clause
        | extends_clause
        | [ redeclare ] [ final ] [ inner ] [ outer ]
          ( class_definition
            | component_clause
            | replaceable ( class_definition | component_clause )
              [ constraining_clause comment ] )

import_clause:
        import ( IDENT "=" name | name [ "." "*" | ".*" | "{" import_list "}" ] ) comment

import_list:
        IDENT { "," IDENT }

Extends

extends_clause:
        extends type_specifier [ class_modification ] [ annotation_comment ]

constraining_clause:
        constrainedby type_specifier [ class_modification ]

Component Clause

component_clause:
        type_prefix type_specifier [ array_subscripts ] component_list

type_prefix:
        [ flow | stream ] [ discrete | parameter | constant ] [ input | output ]

component_list:
        component_declaration { "," component_declaration }

component_declaration:
        declaration [ condition_attribute ] comment

condition_attribute:
        if expression

declaration:
        IDENT [ array_subscripts ] [ modification ]

Modification

modification:
        class_modification [ "=" expression ]
        | "=" expression
        | ":=" expression

class_modification:
        "(" [ argument_list ] ")"

argument_list:
        argument { "," argument }

argument:
        element_modification_or_replaceable | element_redeclaration

element_modification_or_replaceable:
        [ each ] [ final ] ( element_modification | element_replaceable )

element_modification:
        name [ modification ] string_comment

element_redeclaration:
        redeclare [ each ] [ final ]
        ( short_class_definition | component_clause1 | element_replaceable )

element_replaceable:
        replaceable ( short_class_definition | component_clause1 )
        [ constraining_clause ]

component_clause1:
        type_prefix type_specifier component_declaration1

component_declaration1:
        declaration comment

short_class_definition:
        class_prefixes short_class_specifier

Equation

equation_section:
        [ initial ] equation { equation ";" }

algorithm_section:
        [ initial ] algorithm { statement ";" }

equation:
        ( simple_expression "=" expression
        | if_equation
        | for_equation
        | connect_clause
        | when_equation
        | component_reference function_call_args ) comment

statement:
        ( component_reference ( ":=" expression | function_call_args )
        | "(" output_expression_list ")" ":=" component_reference function_call_args
        | break
        | return
        | if_statement
        | for_statement
        | while_statement
        | when_statement ) comment

if_equation:
        if expression then { equation ";" }
        { elseif expression then { equation ";" } }
        [ else { equation ";" } ]
        end if

if_statement:
        if expression then { statement ";" }
        { elseif expression then { statement ";" } }
        [ else { statement ";" } ]
        end if

for_equation:
        for for_indices loop { equation ";" } end for

for_statement:
        for for_indices loop { statement ";" } end for

for_indices:
        for_index { "," for_index }

for_index:
        IDENT [ in expression ]

while_statement:
        while expression loop { statement ";" } end while

when_equation:
        when expression then { equation ";" }
        { elsewhen expression then { equation ";" } }
        end when

when_statement:
        when expression then { statement ";" }
        { elsewhen expression then { statement ";" } }
        end when

connect_clause:
        connect "(" component_reference "," component_reference ")"

Expression

expression:
        simple_expression
        | if expression then expression
          { elseif expression then expression }
          else expression

simple_expression:
        logical_expression [ ":" logical_expression [ ":" logical_expression ] ]

logical_expression:
        logical_term { or logical_term }

logical_term:
        logical_factor { and logical_factor }

logical_factor:
        [ not ] relation

relation:
        arithmetic_expression [ relational_operator arithmetic_expression ]

relational_operator:
        "<" | "<=" | ">" | ">=" | "==" | "<>"

arithmetic_expression:
        [ add_operator ] term { add_operator term }

add_operator:
        "+" | "-" | ".+" | ".-"

term:
        factor { mul_operator factor }

mul_operator:
        "*" | "/" | ".*" | "./"

factor:
        primary [ ( "^" | ".^" ) primary ]

primary:
        UNSIGNED_NUMBER
        | STRING
        | false
        | true
        | component_reference
        | ( component_reference | der | initial | pure ) function_call_args
        | "(" output_expression_list ")"
        | "[" expression_list { ";" expression_list } "]"
        | "{" array_arguments "}"
        | end

type_specifier:
        [ "." ] name

name:
        IDENT { "." IDENT }

component_reference:
        [ "." ] IDENT [ array_subscripts ] { "." IDENT [ array_subscripts ] }

function_call_args:
        "(" [ function_arguments ] ")"

function_arguments:
        expression [ "," function_arguments_non_first | for for_indices ]
        | function name "(" [ named_arguments ] ")" [ "," function_arguments_non_first ]
        | named_arguments

function_arguments_non_first:
        function_argument [ "," function_arguments_non_first ]
        | named_arguments

array_arguments:
        expression [ "," array_arguments_non_first | for for_indices ]

array_arguments_non_first:
        expression [ "," array_arguments_non_first ]

named_arguments:
        named_argument [ "," named_arguments ]

named_argument:
        IDENT "=" function_argument

function_argument:
        function name "(" [ named_arguments ] ")"
        | expression

output_expression_list:
        [ expression ] { "," [ expression ] }

expression_list:
        expression { "," expression }

array_subscripts:
        "[" subscript { "," subscript } "]"

subscript:
        ":" | expression

comment:
        string_comment [ annotation_comment ]

string_comment:
        [ STRING { "+" STRING } ]

annotation_comment:
        annotation class_modification

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.BalancedModel ModelicaReference.BalancedModel

The basic concept to count unknowns and equations.

Restrictions for model and block classes are present, in order that missing or too many equations can be detected and localized by a Modelica translator before using the respective model or block class.

Examples

   partial model BaseCorrelation
     input Real x;
     Real y;
   end BaseCorrelation;

   model SpecialCorrelation // correct in Modelica 2.2 and 3.0
      extends BaseCorrelation(x=2);
   equation
       y=2/x;
   end SpecialCorrelation;

   model UseCorrelation // correct according to Modelica 2.2
                        // not valid according to Modelica 3.0
      replaceable model Correlation=BaseCorrelation;
      Correlation correlation;
   equation
      correlation.y=time;
   end UseCorrelation;

   model Broken // after redeclaration, there is 1 equation too much in Modelica 2.2
      UseCorrelation example(redeclare Correlation=SpecialCorrelation);
   end Broken;

In this case one can argue that both UseCorrelation (adding an acausal equation) and SpecialCorrelation (adding a default to an input) are correct, but still when combined they lead to a model with too many equations - and it is not possible to determine which model is incorrect without strict rules. In Modelica 2.2, model Broken will work with some models. However, by just redeclaring it to model SpecialCorrelation, an error will occur and it will be very difficult in a larger model to figure out the source of this error. In Modelica 3.0, model UseCorrelation is no longer allowed and the translator will give an error. In fact, it is guaranteed that a redeclaration cannot lead to an unbalanced model any more.

Description

The restrictions below apply after flattening " i.e., inherited components are included " possibly modified.

Definition 1: Local Number of Unknowns

The local number of unknowns of a model or block class is the sum based on the components:

Definition 2: Local Equation Size

The local equation size of a model or block class is the sum of the following numbers:

Definition 3: Locally Balanced

A model or block class is "locally balanced" if the "local number of unknowns" is identical to the "local equation size" for all legal values of constants and parameters [respecting final bindings and min/max-restrictions. A tool shall verify the "locally balanced" property for the actual values of parameters and constants in the simulation model. It is a quality of implementation for a tool to verify this property in general, due to arrays of (locally) undefined sizes, conditional declarations, for loops, etc.].

Definition 4: Globally Balanced

Similarly as locally balanced, but including all unknowns and equations from all components. The global number of unknowns is computed by expanding all unknowns (i.e., excluding parameters and constants) into a set of scalars of primitive types. This should match the global equation size defined as:

The following restrictions hold:

Based on these restrictions, the following strong guarantee can be given for simulation models and blocks:

Proposition 1: All simulation models and blocks are globally balanced.
[Therefore the number of unknowns equal to the number of equations of a simulation model or block, provided that every used non-partial model or block class is locally balanced.]

Example 1:

connector Pin
   Real v;
   flow Real i;
end Pin;

model Capacitor
   parameter Real C;
   Pin  p, n;
   Real u;
equation
   0 = p.i + n.i;
   u = p.v - n.v;
   C*der(u) = p.i;
end Capacitor;

Model Capacitor is a locally balanced model according to the following analysis:

Locally unknown variables: p.i, p.v, n.i, n.v, u
Local equations:  0 = p.i + n.i;
                  u = p.v - n.v;
                  C*der(u) = p.i;
                  and 2 equations corresponding to the
                  2 flow-variables p.i and n.i.

These are 5 equations in 5 unknowns (locally balanced model). A more detailed analysis would reveal that this is structurally non-singular, i.e., that the hybrid DAE will not contain a singularity independent of actual values. If the equation "u = p.v - n.v" would be missing in the Capacitor model, there would be 4 equations in 5 unknowns and the model would be locally unbalanced and thus simulation models in which this model is used would be usually structurally singular and thus not solvable. If the equation "u = p.v - n.v" would be replaced by the equation "u = 0" and the equation C*der(u) = p.i would be replaced by the equation "C*der(u) = 0", there would be 5 equations in 5 unknowns (locally balanced), but the equations would be singular, regardless of how the equations corresponding to the flow-variables are constructed because the information that "u" is constant is given twice in a slightly different form.

Example 2:

connector Pin
   Real v;
   flow Real i;
end Pin;

partial model TwoPin
   Pin p,n;
end TwoPin;

model Capacitor
   parameter Real C;
   extends TwoPin;
   Real u;
equation
   0 = p.i + n.i;
   u = p.v " n.v;
   C*der(u) = p.i;
end Capacitor;

model Circuit
   extends TwoPin;
   replaceable TwoPin t;
   Capacitor c(C=12);
equation
   connect(p, t.p);
   connect(t.n, c.p);
   connect(c.n, n);
end Circuit;

Since t is partial we cannot check whether this is a globally balanced model, but we can check that Circuit is locally balanced. Counting on model Circuit results in the following balance sheet:

Locally unknown variables (8): p.i, p.v, n.i, n.v, and 2 flow variables for t (t.p.i, t.n.i)
                                                   and 2 flow variable for c (c.p.i, c.n.i).
Local equations:     p.v = t.p.v;
                       0 = p.i - t.p.i;
                   c.p.v = load.n.v;
                       0 = c.p.i+load.n.i;
                     n.v = c.n.v;
                       0 = n.i - c.n.i;
                    and 2 equation corresponding to the
                    flow variables p.i, n.i

In total we have 8 scalar unknowns and 8 scalar equations, i.e., a locally balanced model (and this feature holds for any models used for the replaceable component "t"). Some more analysis reveals that this local set of equations and unknowns is structurally non-singular. However, this does not provide any guarantees for the global set of equations, and specific combinations of models that are "locally non-singular" may lead to a globally non-singular model.]

Example 3:

import Modelica.Units.SI;
partial model BaseProperties
   "Interface of medium model for all type of media"
   parameter Boolean preferredMediumStates=false;
   constant  Integer nXi "Number of independent mass fractions";
   InputAbsolutePressure     p;
   InputSpecificEnthalpy     h;
   InputMassFraction         Xi[nXi];
   SI.Temperature            T;
   SI.Density                d;
   SI.SpecificInternalEnergy u;

   connector InputAbsolutePressure = input SI.AbsolutePressure;
   connector InputSpecificEnthalpy = input SI.SpecificEnthalpy;
   connector InputMassFraction = input SI.MassFraction;
end BaseProperties;

The use of connector here is a special design pattern. The variables p, h, Xi are marked as input to get correct equation count. Since they are connectors they should neither be given binding equations in derived classes nor when using the model. The design pattern is to give textual equations for them (as below); using connect-statements for these connectors would be possible (and would work) but is not part of the design. This partial model defines that T,d,u can be computed from the medium model, provided p,h,Xi are given. Every medium with one or multiple substances and one or multiple phases, including incompressible media, has the property that T,d,u can be computed from p,h,Xi. A particular medium may have different "independent variables" from which all other intrinsic thermodynamic variables can be recursively computed. For example, a simple air model could be defined as:

model SimpleAir "Medium model of simple air. Independent variables: p,T"
   extends BaseProperties(nXi = 0,
        p(stateSelect = if preferredMediumStates then StateSelect.prefer
                                   else StateSelect.default),
        T(stateSelect = if preferredMediumStates then StateSelect.prefer
                                   else StateSelect.default));
   constant SI.SpecificHeatCapacity R_s  = 287;
   constant SI.SpecificHeatCapacity cp = 1005.45;
   constant SI.Temperature          T0 = 298.15
equation
   d = p/(R_s*T);
   h = cp*(T-T0);
   u = h - p/d;
end SimpleAir;

The local number of unknowns in model SimpleAir (after flattening) is:

The local equation size is:

Therefore, the model is locally balanced. The generic medium model BaseProperties is used as a replaceable model in different components, like a dynamic volume or a fixed boundary condition:

import Modelica.Units.SI;
connector FluidPort
  replaceable model Medium = BaseProperties;

  SI.AbsolutePressure  p;
  flow SI.MassFlowRate m_flow;

  SI.SpecificEnthalpy      h;
  flow SI.EnthalpyFlowRate H_flow;

  SI.MassFraction       Xi     [Medium.nXi] "Independent mixture mass fractions";
  flow SI.MassFlowRate mXi_flow[Medium.nXi] "Independent substance mass flow rates";
end FluidPort;

model DynamicVolume
   parameter SI.Volume V;
   replaceable model Medium = BaseProperties;
   FluidPort port(redeclare model Medium = Medium);
   Medium    medium(preferredMediumStates=true); // No modifier for p,h,Xi
   SI.InternalEnergy U;
   SI.Mass           M;
   SI.Mass           MXi[medium.nXi];
equation
   U   = medium.u*M;
   M   = medium.d*V;
   MXi = medium.Xi*M;
   der(U)   = port.H_flow;   // Energy balance
   der(M)   = port.m_flow;   // Mass balance
   der(MXi) = port.mXi_flow; // Substance mass balance

// Equations binding to medium (inputs)
   medium.p  = port.p;
   medium.h  = port.h;
   medium.Xi = port.Xi;
end DynamicVolume;

The local number of unknowns of DynamicVolume is:

resulting in 8+4*nXi unknowns; the local equation size is

Therefore, DynamicVolume is a locally balanced model. Note, when the DynamicVolume is used and the Medium model is redeclared to "SimpleAir", then a tool will try to select p,T as states, since these variables have StateSelect.prefer in the SimpleAir model (this means that the default states U,M are derived quantities). If this state selection is performed, all intrinsic medium variables are computed from medium.p and medium.T, although p and h are the input arguments to the medium model. This demonstrates that in Modelica input/output does not define the computational causality. Instead, it defines that equations have to be provided here for p,h,Xi, in order that the equation count is correct. The actual computational causality can be different as it is demonstrated with the SimpleAir model.

model FixedBoundary_pTX
   parameter SI.AbsolutePressure p "Predefined boundary pressure";
   parameter SI.Temperature      T "Predefined boundary temperature";
   parameter SI.MassFraction     Xi[medium.nXi]
                                   "Predefined boundary mass fraction";
   replaceable model Medium = BaseProperties;
   FluidPort port(redeclare model Medium = Medium);
   Medium medium;
equation
   port.p        = p;
   port.H_flow   = semiLinear(port.m_flow, port.h , medium.h);
   port.MXi_flow = semiLinear(port.m_flow, port.Xi, medium.Xi);

// Equations binding to medium (note: T is not an input).
   medium.p  = p;
   medium.T  = T;
   medium.Xi = Xi;
end FixedBoundary_pTX;

The number of local variables in FixedBoundary_pTX is:

resulting in 6+3*nXi unknowns, while the local equation size is

Therefore, FixedBoundary_pTX is a locally balanced model. The predefined boundary variables p and Xi are provided via equations to the input arguments medium.p and medium.Xi, in addition there is an equation for T in the same way " even though T is not an input. Depending on the flow direction, either the specific enthalpy in the port (port.h) or h is used to compute the enthalpy flow rate H_flow. "h" is provided as binding equation to the medium. With the equation "medium.T = T", the specific enthalpy "h" of the reservoir is indirectly computed via the medium equations. Again, this demonstrates, that an "input" just defines the number of equations have to be provided, but that it not necessarily defines the computational causality.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'encapsulated' ModelicaReference.'encapsulated'

Break lookup in hierarchy

Examples

encapsulated model Test
  import Modelica.Mechanics.Rotational;

  Rotational.Components.Inertia inertia; // lookup successful
  Modelica.Mechanics.Translational.SlidingMass slidingMass; // lookup fails
equation
  ...
end Test;

Syntax

See section on class_definition in the Modelica Grammar.

Description

When an element, equation or algorithm is instantiated, any name is looked up sequentially in each member of the ordered set of parents until a match is found or a parent is encapsulated. In the latter case the lookup stops except for the predefined types, functions and operators defined in this specification. For these cases the lookup continues in the global scope, where they are defined. [E.g., abs is searched upwards in the hierarchy as usual. If an encapsulated boundary is reached, abs is searched in the global scope instead. The operator abs cannot be redefined in the global scope, because an existing class cannot be redefined at the same level.]

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'extends' ModelicaReference.'extends'

Inheritance from base class

Examples

class A
  parameter Real a, b;
end A;

class B
  extends A(b=2);
end B;

class C
  extends B(a=1);
end C;

From the example above we get the following instantiated class:

class Cinstance
  parameter Real a=1;
  parameter Real b=2;
end Cinstance;

The ordering of the merging rules ensures that, given classes A and B defined above,

class C2
  B bcomp(b=3);
end C2;

yields an instance with bcomp.b=3, which overrides b=2.

Syntax

See section on extends_clause in the Modelica Grammar.

Description

The name of the base class is looked up in the partially instantiated parent of the extends clause. The found base class is instantiated with a new environment and the partially instantiated parent of the extends clause. The new environment is the result of merging

  1. arguments of all parent environments that match names in the instantiated base class
  2. the optional class modification of the extends clause

in that order.

The elements of the instantiated base class become elements of the instantiated parent class.

The declaration elements of the instantiated base class shall either

Otherwise the model is incorrect.

Equations of the instantiated base class that are syntactically equivalent to equations in the instantiated parent class are discarded. [Note: equations that are mathematically equivalent but not syntactically equivalent are not discarded, hence yield an overdetermined system of equations.]

Since specialized classes of different kinds have different properties, only specialized classes that are "in some sense compatible" to each other can be derived from each other via inheritance. The following table shows which kind of specialized class can be used in an extends clause of another kind of specialized class (the "grey" cells mark the few exceptional cases, where a specialized class can be derived from a specialized class of another kind):

Base Class
Derived Class package operator function operator function type record operator record expandable connector connector block model class
package yes yes
operator yes yes
function yes yes
operator
function
yes yes yes
type yes yes
record yes yes
operator
record
yes yes
expandable
connector
yes yes
connector yes yes yes yes yes yes
block yes yes yes
model yes yes yes yes
class yes

The specialized classes package, operator, function, type, record, operator record and expandable connector can only be derived from their own kind [(e.g., a package can only be base class for packages. All other kinds of classes can use the import statement to use the contents of a package)] and from class.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'flow' ModelicaReference.'flow'

Declare flow (through) variable, which have to sum up to zero in connections

Examples

connector Pin
  Modelica.Units.SI.Voltage v;
  flow Modelica.Units.SI.Current i;
end Pin;

model A
  Pin p;
end A;

model Composition
  A a;
  A b;
  A c;
equation
  connect(a.p, b.p);
  connect(a.p, c.p);
end Composition;

From the connect statements in model Composition, the following connect equations are derived:

a.p.v = b.p.v;
a.p.v = c.p.v;
a.p.i + b.p.i + c.p.i = 0;

Syntax

See section on type_prefix in the Modelica Grammar.

Description

The flow prefix is used in order to generate equations for through variables, which sum up to zero in connections, whereas variables without the flow prefix are identical in a connection.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'for' ModelicaReference.'for'

Repeat equations or statements a specific number of times

Examples

for clauses are mostly used in algorithm sections, such as

    parameter Integer np=10;
    Real p[np], x, y;
  algorithm
     y := p[1];
     for i in 2:np loop   // i shall not be declared
        y := y*x + p[i];
     end for;

Other forms of the for condition:

    for i in 1:10 loop            // i takes the values 1,2,3,...,10
    for r in 1.0 : 1.5 : 5.5 loop // r takes the values 1.0, 2.5, 4.0, 5.5
    for i in {1,3,6,7} loop       // i takes the values 1, 3, 6, 7

In equation sections, for clauses are expanded at translation time in order that symbolic transformations can be applied. Typically, a for clause in an equation section is used on component arrays, e.g., to connect elements of an array of components together:

    parameter Integer nR=10 "Number of resistances";
    Modelica.Electrical.Analog.Basic.Resistor R[nR];
  equation
     for i in 1:nR-1 loop
        connect(R[i].p R[i+1].n);   // 9 connect equations
     end for;

Syntax

In equation sections:

  for for_indices loop
     { equation ";" }
  end for;
  for_indices : for_index {"," for_index}
  for_index   : IDENT [ in expression ]

In algorithm sections:

  for for_indices loop
     { algorithm ";" }
  end for;
  for_indices : for_index {"," for_index}
  for_index   : IDENT [ in expression ]

Description

A clause

    for IDENT in expression loop

is one example of a for clause.

The expression of a for clause shall be a vector expression. It is evaluated once for each for clause, and is evaluated in the scope immediately enclosing the for clause. In an equation section, the expression of a for clause shall be a parameter expression (in order that the for clause can be expanded into equations during translation). The loop-variable is in scope inside the loop-construct and shall not be assigned to.

[Example:

The loop-variable may hide other variables as in the following example. Using another name for the loop-variable is, however, strongly recommended.

    constant Integer j=4;
    Real x[j];
  equation
    for j in 1:j loop // The loop-variable j takes the values 1,2,3,4
      x[j]=j; // Uses the loop-variable j
    end for;

]

Several iterators

The notation with several iterators is a shorthand notation for nested for-clauses (or reduction-expressions). For for-clauses it can be expanded into the usual form by replacing each "," by 'loop for' and adding extra 'end for'. For reduction-expressions it can be expanded into the usual form by replacing each ',' by ') for' and prepending the reduction-expression with 'function-name('.

[Example:

    Real x[4,3];
  equation
    for j, i in 1:2 loop
      // The loop-variable j takes the values 1,2,3,4 (due to use)
      // The loop-variable i takes the values 1,2 (given range)
      x[j,i]=j+i;
    end for;

]

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'if' ModelicaReference.'if'

Declare equations or execute statements conditionally

Examples

If clause

    parameter Boolean linear=true;
    parameter Boolean quadratic=false;
    Real x, y;
  equation
    if linear then
      y = x + 1;
    elseif quadratic then
      y = x^2 + x + 1;
    else
      y = Modelica.Math.sin(x) + 1;
    end if;

If expression

  Integer i;
  Integer sign_of_i=if i<0 then -1 else if i==0 then 0 else 1;

Syntax

In equation sections:

   if expression then
     { equation ";" }
   { elseif expression then
     { equation ";" }
   }
   [ else
     { equation ";" }
   ]
   end if

In algorithm sections:

   if expression then
     { algorithm ";" }
   { elseif expression then
     { algorithm ";" }
   }
   [ else
     { algorithm ";" }
   ]
   end if

Description

If clause

The expression of an if and elseif-clause must be scalar Boolean expression. One if-clause, and zero or more elseif-clauses, and an optional else-clause together form a list of branches. One or zero of the bodies of these if-, elseif- and else-clauses is selected, by evaluating the conditions of the if- and elseif-clauses sequentially until a condition that evaluates to true is found. If none of the conditions evaluate to true the body of the else-clause is selected (if an else-clause exists, otherwise no body is selected). In an algorithm section, the selected body is then executed. In an equation section, the equations in the body are seen as equations that must be satisfied. The bodies that are not selected have no effect on that model evaluation.

If clauses in equation sections which do not have exclusively parameter expressions as switching conditions shall have an else clause and each branch shall have the same number of equations. [If this condition is violated, the single assignment rule would not hold, because the number of equations may change during simulation although the number of unknowns remains the same].

If expression

An expression

   if expression1 then expression2 else expression3

is one example of if-expression. First expression1, which must be Boolean expression, is evaluated. If expression1 is true expression2 is evaluated and is the value of the if-expression, else expression3 is evaluated and is the value of the if-expression. The two expressions, expression2 and expression3, must be type compatible and give the type of the if-expression. If-expressions with elseif are defined by replacing elseif by else if.[Note: elseif is added for symmetry with if-clauses.]

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'import' ModelicaReference.'import'

Import classes

Examples

class Lookup
  import SI = Modelica.Units.SI; // #1 (Try to avoid renaming imports!)
  import Modelica.Math.*; // #2 (Try to avoid wildcard imports!)
  import Modelica.Mechanics.Rotational; // #3
  import Modelica.Units.SI.{Molality, Molarity}; // #4

  SI.Torque torque; // due to #1 (Modelica.Units.SI.Torque)
  Rotational.Components.Inertia inertia; // due to #3 (Modelica.Mechanics.Rotational.Components.Inertia)
  Molarity c = 1; // due to #4 (Modelica.Units.SI.Molarity)
equation
  torque = sin(time); // due to #2 (Modelica.Math.sin)
  ...
end Lookup;

Syntax

See section on import_clause in the Modelica Grammar.

Description

Using import statements extends the static name lookup to additional import names. The generated import names are:

Note

Especially the renaming and wildcard import statements should be avoided since they might lead to name-lookup conflicts.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'input' ModelicaReference.'input'

Define causality and/or block diagram connection semantic (depending on context)

Examples

connector RealInput = input Real;
connector RealOutput = output Real;

block Integrator
  RealInput  u;
  RealOutput y;
protected
  Real x;
equation
  der(x) = u;
  y = x;
end Integrator;

Syntax

See section on type_prefix in the Modelica Grammar.

Description

The prefixes input and output have a slightly different semantic meaning depending on the context where they are used:

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'output' ModelicaReference.'output'

Define causality and/or block diagram connection semantic (depending on context)

Examples

connector RealInput = input Real;
connector RealOutput = output Real;

block Integrator
  RealInput  u;
  RealOutput y;
protected
  Real x;
equation
  der(x) = u;
  y = x;
end Integrator;

Syntax

See section on type_prefix in the Modelica Grammar.

Description

The prefixes input and output have a slightly different semantic meaning depending on the context where they are used:

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'partial' ModelicaReference.'partial'

Prohibit instantiation of components of the class

Examples

partial block PartialBlock
  input Real u;
  output Real y;
protected
  Real x;
equation
  x = y;
end PartialBlock;

block Integrator
  extends PartialBlock;
equation
  der(x) = u;
end Integrator;

block Gain
  extends PartialBlock;
  parameter k = 1;
equation
  x = k*u;
end Gain;

model Composition
  PartialBlock block1; // Illegal
  Integrator block2; // Legal
  Gain block3; // Legal
end Composition;

Syntax

See section on class_definition in the Modelica Grammar.

Description

The keyword partial defines that a class is incomplete and that it cannot be instantiated. For example, defining

   PartialBlock block1;

is illegal. A partial class can only be used in an "extends" clause to inherit from it or in a "constrainedby" clause to define the constraints of a replaceable class.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.StateMachines ModelicaReference.StateMachines

The state machines defined in the Modelica Language are based on the synchronous language elements. Note that the state machines defined in the Modelica Standard Library are not based on this.

Examples

  inner Integer v(start=0);
  block Increase
    outer output Integer v;
  equation
    v = previous(v) + 2;
  end Increase;
  Increase increase;
  block Decrease
    outer output Integer v;
  equation
    v = previous(v) - 1;
  end Decrease;
  Decrease decrease;
equation
  initialState(increase);
  transition(increase, decrease, v>=6, immediate=false);
  transition(decrease, increase, v==0, immediate=false);
In this example we will start in increase and increase v until a limit, and then decrease it, and repeat.

Description

A detailed description of the State Machines using Synchronous Language Elements is given in Chapter 17 (State Machines) of the Modelica 3.4 specification.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'stream' ModelicaReference.'stream'

Declare stream variable in a connector to describe bi-directional flow of matter

Examples

connector FluidPort
  replaceable package Medium = Modelica.Media.Interfaces.PartialMedium;
  Medium.AbsolutePressure        p          "Pressure in connection point";
  flow   Medium.MassFlowRate     m_flow     "> 0, if flow into component";
  stream Medium.SpecificEnthalpy h_outflow  "h close to port if m_flow < 0";
end FluidPort;

FluidPort is a stream connector, because a connector variable has the stream prefix. The Medium definition and the stream variables are associated with the only flow variable (m_flow) that defines a fluid stream. The Medium and the stream variables are transported with this flow variable. The stream variable h_outflow is the stream property inside the component close to the boundary, when fluid flows out of the component into the connection point. The stream properties for the other flow direction can be inquired with the built-in operator 'inStream()'. The value of the stream variable corresponding to the actual flow direction can be inquired through the built-in operator 'actualStream()'.

model IsenthalpicFlow "No energy storage/losses, e.g., pressure drop, valve, ..."
  replaceable package Medium=Modelica.Media.Interfaces.PartialMedium;
  FluidPort port_a, port_b:
  Medium.ThermodynamicState port_a_state_inflow "State at port_a if inflowing";
  Medium.ThermodynamicState port_b_state_inflow "State at port_b if inflowing";
equation
  // Medium states for inflowing fluid
  port_a_state_inflow = Medium.setState_phX(port_a.p,
                                            inStream(port_a.h_outflow));
  port_b_state_inflow = Medium.setState_phX(port_b.p,
                                            inStream(port_b.h_outflow));
  // Mass balance
  0 = port_a.m_flow + port_b.m_flow;

  // Instantaneous propagation of enthalpy flow between the ports with
  // isenthalpic state transformation (no storage and no loss of energy)
  port_a.h_outflow = inStream(port_b.h_outflow);
  port_b.h_outflow = inStream(port_a.h_outflow);

  // (Regularized) Momentum balance
  port_a.m_flow = f(port_a.p, port_b.p,
                    Medium.density(port_a_state_inflow),
                    Medium.density(port_b_state_inflow));
end IsenthalpicFlow;

When two or more FluidPort (inside) connectors are connected together, then no connection equations are generated for stream variables. Instead, these equations are constructed by the inStream(..) built-in operator (see example model IsenthalpicFlow) above. If two IsenthalpicFlow components are connected together:

   IsenthalpicFlow dp1;
   IsenthalpicFlow dp2;
equation
  connect(dp1, dp2);

Then, the following connection equations are generated

dp1.p = dp2.p;
0 = dp1.m_flow + dp2.m_flow;

Note, no equation for a stream variable is generated. However, the inStream(..) operators inside the components provide the "ideal mixing" equations:

// within dp1:
  inStream(dp1.port_b.h_outflow) := dp2.port_a.h_outflow;

// within dp2:
  inStream(dp2.port_a.h_outflow) := dp1.port_b.h_outflow;

Syntax

See section on type_prefix in the Modelica Grammar.

Description

A detailed description of the stream keyword and the inStream operator is given in Chapter 15 (Stream Connectors) and Appendix D (Derivation of Stream Equations) of the Modelica 3.4 specification. An overview and a rational is provided in a slide set.

The two basic variable types in a connector potential (or across) variable and flow (or through) variable are not sufficient to describe in a numerically sound way the bi-directional flow of matter with convective transport of specific quantities, such as specific enthalpy and chemical composition. The values of these specific quantities are determined from the upstream side of the flow, i.e., they depend on the flow direction. When using across and through variables, the corresponding models would include nonlinear systems of equations with Boolean unknowns for the flow directions and singularities around zero flow. Such equation systems cannot be solved reliably in general. The model formulations can be simplified when formulating two different balance equations for the two possible flow directions. This is not possible with across and through variables though.

This fundamental problem is addressed in Modelica 3.1 by introducing a third type of connector variable, called stream variable, declared with the prefix stream. A stream variable describes a quantity that is carried by a flow variable, i.e., a purely convective transport phenomenon. The value of the stream variable is the specific property inside the component close to the boundary, assuming that matter flows out of the component into the connection point. In other words, it is the value the carried quantity would have if the fluid was flowing out of the connector, irrespective of the actual flow direction.

The basic idea is sketched at hand of an example: Three connectors c1, c2, c3 with the definition

connector Demo
  Real        p;  // potential variable
  flow   Real m_flow;  // flow variable
  stream Real h;  // stream variable
end Demo;

are connected together with

connect(c1,c2);
connect(c1,c3);

then this leads to the following equations:

// Potential variables are identical
c1.p = c2.p;
c1.p = c3.p;

// The sum of the flow variables is zero
0 = c1.m_flow + c2.m_flow + c3.m_flow;

/* The sum of the product of flow variables and upstream stream variables is zero
   (this implicit set of equations is explicitly solved when generating code;
   the "<undefined>" parts are defined in such a way that
   inStream(..) is continuous).
*/
0 = c1.m_flow*(if c1.m_flow > 0 then h_mix else c1.h) +
    c2.m_flow*(if c2.m_flow > 0 then h_mix else c2.h) +
    c3.m_flow*(if c3.m_flow > 0 then h_mix else c3.h);

inStream(c1.h) = if c1.m_flow > 0 then h_mix else <undefined>;
inStream(c2.h) = if c2.m_flow > 0 then h_mix else <undefined>;
inStream(c3.h) = if c3.m_flow > 0 then h_mix else <undefined>;

If at least one variable in a connector has the stream prefix, the connector is called stream connector and the corresponding variable is called stream variable. The following definitions hold:

For further details, see the definition of the 'inStream()' operator.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.Synchronous ModelicaReference.Synchronous

Synchronous language elements are added to Modelica as an alternative to normal when-clauses to making modeling of complex sampled systems safer and easier.

Examples

  // Discrete controller
  when Clock() then
    E*dc.xd=A*previous(dc.xd)+B*dc.yd;
      dc.ud=C*previous(dc.xd)+D*dc.yd;
  end when;

  // hold controller output:
  plant.u=hold(dc.ud);

  // Plant
  0=f(der(plant.x),plant.x,plant.u);
  plant.y=g(plant.x);

  // Sample continuous signal
  dc.yd=sample(plant.y, Clock(3));
In this example dc.xd and dc.ud are Clocked variables, and only defined when the Clock is active (every 3rd second). At time instants where the associated clock is not active, the value of a clocked variable can be inquired by using an explicit cast operator, e.g., hold.

Description

A detailed description of the Synchronous Language Elements is given in Chapter 16 (Synchronous Language Elements) of the Modelica 3.4 specification.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'time' ModelicaReference.'time'

Built-in variable time

Examples

encapsulated model SineSource
  import Modelica.Math.sin;
  connector OutPort=output Real;
  OutPort y=sin(time); // Uses the built-in variable time.
end SineSource;

Syntax

time

Description

All declared variables are functions of the independent variable time. Time is a built-in variable available in all classes, which is treated as an input variable. It is implicitly defined as:

input Real time (final quantity = "Time",
                 final unit     = "s");

The value of the start attribute of time is set to the time instant at which the simulation is started.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'when' ModelicaReference.'when'

Activate equations or statements when condition becomes true

Examples

 equation
   when x > 2 then
     y3 = 2*x +y1+y2; // Order of y1 and y3 equations does not matter
     y1 = sin(x);
   end when;
   y2 = sin(y1);

Syntax

In equation sections:

  when expression then
    { equation ";" }
  { elsewhen expression then
    { equation ";" } }
  end when

In algorithm sections:

  when expression then
    { algorithm ";" }
  { elsewhen expression then
    { algorithm ";" } }
  end when

Description

The expression of a when clause shall be a discrete-time Boolean scalar or vector expression. The equations and algorithm statements within a when clause are activated when the scalar or any one of the elements of the vector expression becomes true. When-clauses in equation sections are allowed, provided the equations within the when-clause have one of the following forms:

A when clause shall not be used within a function class.

[Example:

Algorithms are activated when x becomes > 2:

   when x > 2 then
     y1 := sin(x);
     y3 := 2*x + y1 + y2;
   end when;

Algorithms are activated when either x becomes > 2 or sample(0,2) becomes true or x becomes less than 5:

   when {x > 2, sample(0,2), x < 5} then
     y1 := sin(x);
     y3 := 2*x + y1 + y2;
   end when;

For when in equation sections the order between the equations does not matter, e.g.,

 equation
   when x > 2 then
     y3 = 2*x +y1+y2; // Order of y1 and y3 equations does not matter
     y1 = sin(x);
   end when;
   y2 = sin(y1);

The needed restrictions on equations within a when-clause becomes apparent with the following example:

   Real x, y;
equation
   x + y = 5;
   when condition then
      2*x + y = 7;         // error: not valid Modelica
   end when;

When the equations of the when-clause are not activated it is not clear which variable to hold constant, either x or y. A corrected version of this example is:

   Real x, y;
equation
   x + y = 5;
   when condition then
      y = 7 - 2*x;        // fine
   end when;

Here, variable y is held constant when the when-clause is de-activated and x is computed from the first equation using the value of y from the previous event instant.

For when in algorithm sections the order is significant and it is advisable to have only one assignment within the when-clause and instead use several algorithms having when-clauses with identical conditions, e.g.,

 algorithm
   when x > 2 then
     y1 := sin(x);
   end when;
 equation
   y2 = sin(y1);
 algorithm
   when x > 2 then
     y3 := 2*x + y1 + y2;
   end when;

Merging the when-clauses can lead to less efficient code and different models with different behaviour depending on the order of the assignment to y1 and y3 in the algorithm.]

A when clause

 algorithm
   when {x>1, ..., y>p} then
     ...
   elsewhen x > y.start then
     ...
   end when;

is equivalent to the following special if-clause, where Boolean b1[N] and Boolean b2 are necessary because the edge() operator can only be applied to variables

   Boolean b1[N](start={x.start>1, ..., y.start>p});
   Boolean b2(start=x.start>y.start);
 algorithm
   b1:={x>1, ..., y>p};
   b2:=x>y.start;

   if edge(b1[1]) or edge(b1[2]) or ... edge(b1[N]) then
     ...
   elseif edge(b2) then
     ...
   end if;

with "edge(A)= A and not pre(A)" and the additional guarantee, that the algorithms within this special if clause are only evaluated at event instants.

A when-clause

 equation
   when x>2 then
     v1 = expr1 ;
     v2 = expr2 ;
   end when;

is equivalent to the following special if-expressions

   Boolean b(start=x.start>2);
 equation
   b  = x>2;
   v1 = if edge(b) then expr1 else pre(v1);
   v2 = if edge(b) then expr2 else pre(v2);

The start-values of the introduced Boolean variables are defined by the taking the start-value of the when-condition, as above where p is a parameter variable. The start-values of the special functions initial, terminal, and sample is false.

When clauses cannot be nested.

[Example:

The following when clause is invalid:

   when x > 2 then
     when y1 > 3 then
       y2 = sin(x);
     end when;
   end when;

]

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.'while' ModelicaReference.'while'

Repeat statements as long as a condition is fulfilled

Examples

    Integer i;
  algorithm
    i := 1;
    while i < 10 loop
      i := i + 1;
      ...
    end while;

Syntax

  while expression loop
    { algorithm ";" }
  end while

Description

The expression of a while clause shall be a scalar Boolean expression. The while-clause corresponds to while-statements in programming languages, and is formally defined as follows

  1. The expression of the while clause is evaluated.
  2. If the expression of the while-clause is false, the execution continues after the while-clause.
  3. If the expression of the while-clause is true, the entire body of the while clause is executed (except if a break statement or return statement is executed), and then execution proceeds at step 1.

Extends from ModelicaReference.Icons.Information (Icon for general information packages).

ModelicaReference.Contact ModelicaReference.Contact

Library Officers:
Dietmar Winkler and Hans Olsson

Acknowledgements:

Extends from ModelicaReference.Icons.Contact (Icon for contact information).

Automatically generated Thu Oct 1 16:08:42 2020.