The fundamental structuring unit of modeling in Modelica is the class. Classes provide the structure for objects, also known as instances. Classes can contain equations which provide the basis for the executable code that is used for computation in Modelica. Conventional algorithmic code can also be part of classes. All data objects in Modelica are instantiated from classes, including the basic data types—Real, Integer, String, Boolean—and enumeration types, which are built-in classes or class schemata.
Declarations are the syntactic constructs needed to introduce classes and objects (i.e., components).
Members of a Modelica class can have two levels of visibility: public or protected. The default is public if nothing else is specified
A protected element, P, in classes and components may not be accessed via dot notation (e.g., A.P, a.P, a.P, a.b.P, .A.P; but there is no restriction on using P or P.x for a protected element P). They may not be modified or redeclared except for modifiers applied to protected elements in a base-class modification (not inside any component or class) and the modifier on the declaration of the protected element.
All elements defined under the heading protected are regarded as protected. All other elements [i.e., defined under the heading public, without headings or in a separate file] are public [i.e. not protected]. Regarding inheritance of protected and public elements, see section 7.1.2.
The name of a declared element shall not have the same name as any other element in its partially flattened enclosing class. A component shall not have the same name as its type specifier. However, the internal flattening of a class can in some cases be interpreted as having two elements with the same name; these cases are described in section 5.5, and section 7.3.
Variables and classes can be used before they are declared.
[In fact, declaration order is only significant for:
Functions with more than one input variable called with positional arguments, section 12.4.1.
Functions with more than one output variable, section 12.4.3.
Records that are used as arguments to external functions, section 126.96.36.199
Enumeration literal order within enumeration types, section 4.8.5.
Component declarations are described in this section.
The formal syntax of a component declaration clause is given by the following syntactic rules:
[The declaration of a component states the type, access, variability, data flow, and other properties of the component. A component-clause i.e., the whole declaration, contains type prefixes followed by a type-specifier with optional array-subscripts followed by a component-list.
There is no semantic difference between variables declared in a single declaration or in multiple declarations. For example, regard the following single declaration (component-clause) of two matrix variables:
That declaration has the same meaning as the following two declarations together:
The array dimension descriptors may instead be placed after the variable name, giving the two declarations below, with the same meaning as in the previous example:
The following declaration is different, meaning that the variable a is a scalar but B is a matrix as above:
If the type-specifier of the component declaration denotes a built-in type (RealType, IntegerType, etc.), the flattened or instantiated component has the same type.
If the type-specifier of the component does not denote a built-in type, the name of the type is looked up (section 5.3). The found type is flattened with a new environment and the partially flattened enclosing class of the component. It is an error if the type is partial in a simulation model, or if a simulation model itself is partial. The new environment is the result of merging
the modification of enclosing class element-modification with the same name as the component
the modification of the component declaration
in that order.
Array dimensions shall be non-negative parameter expressions, or the colon operator denoting that the array dimension is left unspecified.
The rules for components in functions are described in section 12.2.
Conditional declarations of components are described in section 4.4.5.
An environment that defines the value of a component of built-in type is said to define a declaration equation associated with the declared component. For declarations of vectors and matrices, declaration equations are associated with each element.
Variables declared with the flow or the stream type prefix shall be a subtype of Real.
Type prefixes (that is , flow, stream, discrete, parameter, constant, input, output) shall only be applied for type, record and connector components – see also record specialized class, section 4.6.
An exception is input for components whose type is of the special class function type (these can only be used for function formal parameters and has special semantics, see section 12.4.2), and the input prefix is not applied to the elements of the component and is allowed even if the elements have input or output prefix.
In addition, instances of classes extending from ExternalObject may have type prefixes parameter and constant, and in functions also type prefixes input and output - see section 12.9.7.
The type prefixes flow, stream, input and output of a structured component (except as described above) are also applied to the elements of the component (this is done after verifying that the type prefixes occurring on elements of the component are correct; e.g. the flow prefix can be used on a record component and all the record elements will generate zero-sum equations, even if elements of a record may not be declared with the flow prefix). When any of the type prefixes flow, stream, input and output are applied for a structured component, no element of the component may have any of these type prefixes. [For example, input can only be used, if none of the elements has a flow, stream, input or output type prefix]. The corresponding rules for the type prefixes discrete, parameter and constant are described in section 188.8.131.52 for structured components.
The prefixes input and output have a slightly different semantic meaning depending on the context where they are used:
In functions, these prefixes define the computational causality of the function body, i.e., given the variables declared as input, the variables declared as output are computed in the function body, see section 12.4.
In simulation models and blocks (i.e., on the top level of a model or block that shall be simulated), these prefixes define the interaction with the environment where the simulation model or block is used. Especially, the input prefix defines that values for such a variable have to be provided from the simulation environment and the output prefix defines that the values of the corresponding variable can be directly utilized in the simulation environment, see the notion of Globally balanced in section 4.7.
In component models and blocks, the input prefix defines that a binding equation has to be provided for the corresponding variable when the component is utilized in order to guarantee a locally balanced model (i.e., the number of local equations is identical to the local number of unknowns), see section 4.7. Example:
The output prefix does not have a particular effect in a model or block component and is ignored.
In connectors, prefixes input and output define that the corresponding connectors can only be connected according to block diagram semantics, see section 9.1 (e.g., a connector with an output variable can only be connected to a connector where the corresponding variable is declared as input). There is the restriction that connectors which have at least one variable declared as input must be externally connected, see section 4.7 (in order to get a locally balanced model, where the number of local unknowns is identical to the number of unknown equations). Together with the block diagram semantics rule this means, that such connectors must be connected exactly once externally.
In records, prefixes input and output are not allowed, since otherwise a record could not be, e.g., passed as input argument to a function.
The unexpanded binding equations for parameters and constants in the translated model must be acyclic after flattening; except that cycles are allowed if the cycles disappear when evaluating parameters having annotation Evaluate=true that are not part of the cycle. Thus it is not possible to introduce equations for parameters by cyclic dependencies.
The prefixes discrete, parameter, constant of a component declaration are called variability prefixes and define in which situation the variable values of a component are initialized (see section 8.5 and section 8.6) and when they are changed in transient analysis (= solution of initial value problem of the hybrid DAE):
A variable vc declared with the parameter or constant prefixes remains constant during transient analysis.
A discrete-time variable vd has a vanishing time derivative (informally der(vd)=, but it is not legal to apply the der() operator to discrete-time variables) and can change its values only at event instants during transient analysis (see section 8.5).
A continuous-time variable vn may have a non-vanishing time derivative (der(vn)<> possible) and may also change its value discontinuously at any time during transient analysis (see section 8.5). If there are any discontinuities the variable is not differentiable.
If a Real variable is declared with the prefix discrete it must in a simulation model be assigned in a when-clause, either by an assignment or an equation. The variable assigned in a when-clause may not be defined in a sub-component of model or block specialized class. [This is to keep the property of balanced models]
A Real variable assigned in a when-clause is a discrete-time variable, even though it was not declared with the prefix discrete. A Real variable not assigned in any when-clause and without any type prefix is a continuous-time variable.
The default variability for Integer, String, Boolean, or enumeration variables is discrete-time, and it is not possible to declare continuous-time Integer, String, Boolean, or enumeration variables. [A Modelica translator is able to guarantee this property due to restrictions imposed on discrete expressions, see section 3.8]
The variability of expressions and restrictions on variability for definition equations is given in section 3.8.
[A discrete-time variable is a piecewise constant signal which changes its values only at event instants during simulation. Such types of variables are needed in order that special algorithms, such as the algorithm of Pantelides for index reduction, can be applied (it must be known that the time derivative of these variables is identical to zero). Furthermore, memory requirements can be reduced in the simulation environment, if it is known that a component can only change at event instants.
A parameter variable is constant during simulation. This prefix gives the library designer the possibility to express that the physical equations in a library are only valid if some of the used components are constant during simulation. The same also holds for discrete-time and constant variables. Additionally, the parameter prefix allows a convenient graphical user interface in an experiment environment, to support quick changes of the most important constants of a compiled model. In combination with an if-clause, a parameter prefix allows to remove parts of a model before the symbolic processing of a model takes place in order to avoid variable causalities in the model (similar to #ifdef in C). Class parameters can be sometimes used as an alternative. Example:
A constant variable is similar to a parameter with the difference that constants cannot be changed after translation and usually not changed after they have been given a value. It can be used to represent mathematical constants, e.g.
There are no continuous-time Boolean, Integer or String variables. In the rare cases they are needed they can be faked by using Real variables, e.g.:
Since off1 is a discrete-time variable, state events are generated such that off1 is only changed at event instants. Variable off2 may change its value during continuous integration. Therefore, u1 is guaranteed to be continuous during continuous integration whereas no such guarantee exists for u2.
For elements of structured entities with variability prefixes the most restrictive of the variability prefix and the variability of the component wins (using the default variability for the component if there is no variability prefix on the component).
A component declaration can have a condition-attribute: ”if” expression.
The expression must be a Boolean scalar expression, and must be a parameter-expression [that can be evaluated at compile time].
A redeclaration of a component may not include a condition attribute; and the condition attribute is kept from the original declaration (see section 6.3).
If the Boolean expression is false the component (including its modifier) is removed from the flattened DAE , and connections to/from the component are removed and connections to/from the component are removed. [Adding the component and then removing it ensures that the component is valid.]A component declared with a condition-attribute can only be modified and/or used in connections [If a connect statement defines the connection of a non-conditional component c1 with a conditional component c2 and c2 is de-activated, then c1 must still be a declared element.]
If the condition is true for a public connector containing flow variables the connector must be connected from the outside. [The reason for this restriction is that the default flow equation is probably incorrect (since it could otherwise be an unconditional connector) and the model cannot check that connector is connected.]
Essentially everything in Modelica is a class, from the predefined classes Integer and Real, to large packages such as the Modelica standard library.
[Example: A rather typical structure of a Modelica class is shown below. A class with a name, containing a number of declarations followed by a number of equations in an equation section.
The following is the formal syntax of class definitions, including the special variants described in later sections.
A class definition of the form
is identical, except that IDENT2 may be replaceable and for the lexical scope of modifiers, where the short class definition does not introduce an additional lexical scope for modifiers, to the longer form
[Example: demonstrating the difference in scopes:
A short class definition of the form
where N represents arbitrary array dimensions, conceptually yields an array class
Such an array class has exactly one anonymous component (_); see also section 4.5.2. When a component of such an array class type is flattened, the resulting flattened component type is an array type with the same dimensions as _ and with the optional modifier applied.
the types of f1 and f2 are identical.]
If a short class definition inherits from a partial class the new class definition will be partial, regardless of whether it is declared with the keyword partial or not.
If a short class definition does not specify any specialized class the new class definition will inherit the specialized class (this rule applies iteratively and also for redeclare).
A base-prefix applied in the short-class definition does not influence its type, but is applied to components declared of this type or types derived from it; see also section 4.5.2.
It is not legal to combine other components or base-classes with an extends from an array class, a class with non-empty base-prefix, a simple type (Real, Boolean, Integer, String and enumeration types), or any class transitively extending from an array class, a class with non-empty base-prefix, or a simple type (Real, Boolean, Integer, String and enumeration types).
The local class should be statically flattenable with the partially flattened enclosing class of the local class apart from local class components that are partial or outer. The environment is the modification of any enclosing class element modification with the same name as the local class, or an empty environment.
The unflattened local class together with its environment becomes an element of the flattened enclosing class.
[The following example demonstrates parameterization of a local class:
Flattening of class C2 yields a local class Voltage with nominal-modifier 1000. The variables v1 and v2 are instances of this local class and thus have a nominal value of 1000.
Specialized kinds of classes [Earlier known as restricted classes] record, type, model, block, package, function, and connector have the properties of a general class, apart from restrictions. Moreover, they have additional properties called enhancements. The following table summarizes the definition of the specialized classes (additional restrictions on inheritance are in section 7.1.3):
|record||Only public sections are allowed in the definition or in any of its components (i.e., equation, algorithm, initial equation, initial algorithm and protected sections are not allowed). The elements of a record may not have prefixes input, output, inner, outer, stream, or flow. Enhanced with implicitly available record constructor function, see section 12.6. Additionally, record components can be used as component references in expressions and in the left hand side of assignments, subject to normal type compatibility rules. The components directly declared in a record may only be of specialized class record and type..|
|type||May only be predefined types, enumerations, array of type, or classes extending from type.|
|model||Identical to class, the basic class concept, i.e., no restrictions and no enhancements.|
|block||Same as model with the restriction that each connector component of a block must have prefixes input and/or output for all connector variables. [The purpose is to model input/output blocks of block diagrams. Due to the restrictions on input and output prefixes, connections between blocks are only possible according to block diagram semantic]|
|function||See section 12.2 for restrictions and enhancements of functions. Enhanced to allow the function to contain an external function interface. [Non-function specialized classes do not have this property.]|
|connector||Only public sections are allowed in the definition or in any of its components (i.e., equation, algorithm, initial equation, initial algorithm and protected sections are not allowed). Enhanced to allow connect(..) to components of connector classes. The elements of a connector may not have prefixes inner, or outer. May only contain components of specialized class connector, record and type.|
|package||May only contain declarations of classes and constants. Enhanced to allow import of elements of packages. (See also chapter 13 on packages.)|
|operator record||Similar to record; but operator overloading is possible, and due to this the typing rules are different – see chapter 6. It is not legal to extend from an operator record (or connector inheriting from operator record), except if the new class is an operator record or connector that is declared as a short class definition, whose modifier is either empty or only modify the default attributes for the component elements directly inside the operator record. An operator record can only extend from an operator record [as short class definition, and not from another specialized class]. It is not legal to extend from any of its enclosing scopes. (See chapter 14).|
|operator||Similar to package; but may only contain declarations of functions. May only be placed directly in an operator record. (See also chapter 14).|
|operator function||Shorthand for an
operator with exactly one function; same restriction as function class
and in addition may only be placed directly in an operator
operator function foo ... end foo;
operator foo function foo1
end foo1; end foo;
[Example for ”operator”:
[In this section 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. A non-trivial case is demonstrated in the following example:
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, as the ones defined here.
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.
The restrictions below apply after flattening – i.e. inherited components are included – possibly modified. The corresponding restrictions on connectors and connections are in section 9.3.
Definition 1: Local Number of Unknowns
The local number of unknowns of a model or block class is the sum based on the components:
For each declared component of specialized class type (Real, Integer, String, Boolean, enumeration and arrays of those, etc.) or record, or operator record not declared as outer, it is the “number of unknown variables” inside it (i.e., excluding parameters and constants and counting the elements after expanding all records, operator record, and arrays to a set of scalars of primitive types).
Each declared component of specialized class type or record declared as outer is ignored [i.e., all variables inside the component are treated as known].
For each declared component of specialized class connector component, it is the “number of unknown variables” inside it (i.e., excluding parameters and constants and counting the elements after expanding all records and arrays to a set of scalars of primitive types).
For each declared component of specialized class block or model, it is the “sum of the number of inputs and flow variables” in the (top level) public connector components of these components (and counting the elements after expanding all records and arrays to a set of scalars of primitive types).
Definition 2: Local Equation Size
The local equation size of a model or block class is the sum of the following numbers:
The number of equations defined locally (i.e. not in any model or block component), including binding equations, and equations generated from connect-equations. This includes the proper count for when-clauses (see section 8.3.5), and algorithms (see section 11.1), and is also used for the flat Hybrid DAE formulation (see Appendix C).
The number of input and flow-variables present in each (top-level) public connector component. [This represents the number of connection equations that will be provided when the class is used.]
The number of (top level) public input variables that neither are connectors nor have binding equations [i.e., top-level inputs are treated as known variables. This represents the number of binding equations that will be provided when the class is used.].
[To clarify top-level inputs without binding equation (for non-inherited inputs binding equation is identical to declaration equation, but binding equations also include the case where another model extends M and has a modifier on ‘u’ giving the value):
Here ‘u’ and ‘u2’ are top-level inputs and not connectors. The variable u2 has a binding equation, but u does not have a binding equation. In the equation count, it is assumed that an equation for u is supplied when using the model.
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 number of equations defined (included in any model or block component), including equations generated from connect-equations.
The number of input and flow-variables present in each (top-level) public connector component.
The number of (top level) public input variables that neither are connectors nor have binding equations [i.e., top-level inputs are treated as known variables].
The following restrictions hold:
In a non-partial model or block, all non-connector inputs of model or block components must have binding equations. [E.g. if the model contains a component, firstOrder (of specialized class model) and firstOrder has ‘input Real u’ then there must be a binding equation for firstOrder.u.]
A component declared with the inner or outer prefix shall not be of a class having top-level public connectors containing inputs.
In a declaration of a component of a record, connector, or simple
type, modifiers can be applied to any element – and these are also
considered for the equation count.
Flange support(phi=phi, tau=torque1+torque2) if use_support;
If use_support=true, there are two additional equations for support.phi and support.tau via the modifier]
In other cases (declaration of a component of a model or block type, modifiers on extends, and modifier on short-class-definitions): modifiers for components shall only contain redeclarations of replaceable elements and binding equations. The binding equations in modifiers for components may in these cases only be for parameters, constants, inputs and variables having a default binding equation.
All non-partial model and block classes must be locally balanced [this means that the local number of unknowns equals the local equation size].
Based on these restrictions, the following strong guarantee can be given for simulation models and blocks:
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.]
Model Capacitor is a locally balanced model according to the following analysis:
Locally unknown variables: p.i, p.v, n.i, n.v, u
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 = ” and the equation C*der(u) = p.i would be replaced by the equation “C*der(u) = ”, 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.
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).
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.]
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-equations 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:
The local number of unknowns in model SimpleAir (after flattening) is:
3 (T, d, u: variables defined in BaseProperties and inherited in SimpleAir), plus
2+nXi (p, h, Xi: variables inside connectors defined in BaseProperties and inherited in SimpleAir)
resulting in 5+nXi unknowns. The local equation size is:
3 (equations defined in SimpleAir), plus
2+nXi (input variables in the connectors inherited from BaseProperties)
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:
The local number of unknowns of DynamicVolume is:
4+2*nXi (inside the port connector), plus
2+nXi (variables U, M and MXi), plus
2+nXi (the input variables in the connectors of the medium model)
resulting in 8+4*nXi unknowns; the local equation size is
6+3*nXi from the equation section, plus
2+nXi flow variables in the port connector.
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.
The number of local variables in FixedBoundary_pTX is:
4+2*nXi (inside the port connector), plus
2+nXi (the input variables in the connectors of the medium model)
resulting in 6+3*nXi unknowns, while the local equation size is
4+2*nXi from the equation section, plus
2+nXi flow variables in the port connector.
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
The attributes of the predefined variable types (Real, Integer, Boolean, String) and enumeration types are described below with Modelica syntax although they are predefined. Attributes cannot be accessed using dot notation, and are not constrained by equations and algorithm sections. E.g. in Real x(unit=”kg”) = y; only the values of x and y are declared to be equal, but not their unit attributes, nor any other attribute of x and y. It is not possible to combine extends from the predefined types, enumeration types, or this Clock type with other components. The names Real, Integer, Boolean and String are reserved such that it is illegal to declare an element with these names. [Thus it is possible to define a normal class called Clock in a package and extend from it.] The definitions use RealType, IntegerType, BooleanType, StringType, EnumType as mnemonics corresponding to machine representations. [Hence the only way to declare a subtype of e.g. Real is to use the extends mechanism.]
The following is the predefined Real type:
The nominal attribute is meant to be used for scaling purposes and to define tolerances in relative terms, see section 4.8.7.
The following is the predefined Integer type:
The following is the predefined Boolean type:
The following is the predefined String type:
A declaration of the form
defines an enumeration type E and the associated enumeration literals of the enum-list. The enumeration literals shall be distinct within the enumeration type. The names of the enumeration literals are defined inside the scope of E. Each enumeration literal in the enum-list has type E.
An optional comment string can be specified with each enumeration literal:
An enumeration type is a simple type and the attributes are defined in section 184.108.40.206. The Boolean type name or an enumeration type name can be used to specify the dimension range for a dimension in an array declaration and to specify the range in a for loop range expression; see section 220.127.116.11. An element of an enumeration type can be accessed in an expression [e.g. an array index value].
Using enumeration types as expressions:
For each enumeration:
a new simple type is conceptually defined as
[Since the attributes and enumeration literals are on the same level, it is not possible to use the enumeration attribute names (quantity, min, max, start, fixed) as enumeration literals]
The type conversion function Integer(<expression of enumeration type>) returns the ordinal number of the enumeration value E.enumvalue, to which the expression is evaluated, where Integer(E.e1) =1, Integer(E.en) = n, for an enumeration type E=enumeration(e1, ..., en).
String(E.enumvalue) gives the string representation of the enumeration value.
[Example: String(E.Small) gives ”Small”.]
See also section 3.7.1.
Whenever an enumeration type is defined, a type conversion function with the same name and in the same scope as the enumeration type is implicitly defined. This function can be used in an expression to convert an integer value to the corresponding (as described in section 18.104.22.168) enumeration value.
For an enumeration type named EnumTypeName, the expression EnumTypeName(<Integer expression>) returns the enumeration value EnumTypeName.e such that Integer(EnumTypeName.e) is equal to the original integer expression.
Attempting to convert an integer argument that does not correspond to a value of the enumeration type is an error.
Converting from Integer to Colors:
An enumeration type defined using enumeration(:) is unspecified and can be used as a replaceable enumeration type that can be freely redeclared to any enumeration type. There can be no enumeration variables declared using enumeration(:) in a simulation model.
The attributes start and fixed define the initial conditions for a variable. “fixed=false” means an initial guess, i.e., value may be changed by static analyzer. “fixed=true” means a required value. The resulting consistent set of values for ALL model variables is used as initial values for the analysis to be performed.
The attribute nominal gives the nominal value for the variable. The user need not set it even though the standard does not define a default value. The lack of default allows the tool to propagate the nominal attribute based on equations, and if there is no value to propagate the tool should use a non-zero value, it may use additional information (e.g. min-attribute) to find a suitable value, and as last resort use 1. If “unbounded=true” it indicates that the state may grow without bound, and the error in absolute terms shall be controlled. [The nominal value can be used by an analysis tool to determine appropriate tolerances or epsilons, or may be used for scaling. For example, the tolerance for an integrator could be computed as “tol*(abs(nominal)+(if x.unbounded then 0 else abs(x)))”. A default value is not provided in order that in cases such as “a=b”, where “b” has a nominal value but not “a”, the nominal value can be propagated to the other variable).] [For external functions in C89, RealType by default maps to double and IntegerType by default maps to int. In the mapping proposed in Annex F of the C99 standard, RealType/double matches the IEC 60559:1989 (ANSI/IEEE 754-1985) double format. Typically IntegerType represents a 32-bit 2-complement signed integer.]
The predefined StateSelect enumeration type is the type of the stateSelect attribute of the Real type. It is used to explicitly control state selection.
See section 12.9.7 for information about the predefined type ExternalObject.
The package Connections is used for over-constrained connection graphs, section 8.3.9.
A number of “predefined” record types and enumeration types for graphical annotations are described in chapter 18. These types are not predefined in the usual sense since they cannot be referenced in ordinary Modelica code, only within annotations.