• No results found

Modelica TM - A Unified Object-Oriented Language for Physical Systems Modeling. TUTORIAL and RATIONALE

N/A
N/A
Protected

Academic year: 2021

Share "Modelica TM - A Unified Object-Oriented Language for Physical Systems Modeling. TUTORIAL and RATIONALE"

Copied!
49
0
0

Loading.... (view fulltext now)

Full text

(1)

Modelica

TM

- A Unified Object-Oriented

Language for Physical Systems Modeling

TUTORIAL and RATIONALE

Version 1.3

December 15, 1999

H. Elmqvist1,

B. Bachmann2, F. Boudaud3, J. Broenink4, D. Brück1, T. Ernst5, R. Franke6, P. Fritzson7, A. Jeandel3, P. Grozman12, K. Juslin8, D. Kågedahl7, M. Klose9, N. Loubere3, S. E. Mattsson1, P.

Mostermann11, H. Nilsson7, M. Otter11, P. Sahlin12, A. Schneider13, H. Tummescheit10, H. Vangheluwe15

1

Dynasim AB, Lund, Sweden

2

ABB Corporate Research Center Heidelberg

3

Gaz de France, Paris, France

4

University of Twente, Enschede, Netherlands

5

GMD FIRST, Berlin, Germany

6

ABB Network Partner Ltd. Baden, Switzerland

7

Linköping University, Sweden

8

VTT, Espoo, Finland

9

Technical University of Berlin, Germany

10

Lund University, Sweden

11

DLR Oberpfaffenhofen, Germany

12

Bris Data AB, Stockholm, Sweden

13

Fraunhofer Institute for Integrated Circuits, Dresden, Germany

14

DLR, Cologne, Germany

15

University of Gent, Belgium

(2)

Contents

1.Introduction

2.Modelica at a Glance

3.Requirements for Multi-domain Modeling 4.Modelica Language Rationale and Overview

4.1 Basic Language Elements

4.2 Classes for Reuse of Modeling Knowledge 4.3 Connections

4.4 Partial Models and Inheritance 4.5 Class Parameterization

4.6 Matrices

4.7 Repetition, Algorithms and Functions 4.8 Hybrid Models

4.9 Units and Quantities

4.10 Attributes for Graphics and Documentation 5.Overview of Present Languages

6.Design Rationale 7.Examples

8.Conclusions 9.Acknowledgments 10.References

(3)

1. Introduction

There definitely is an interoperability problem amongst the large variety of modeling and simulation environments available today, and it gets more pressing every year with the trend towards ever more complex and heterogeneous systems to be simulated. The main cause of this problem is the absence of a state-of-the-art, standardized external model representation.

Modeling languages, where employed, often do not adequately support the structuring of large, complex models and the process of model evolution in general. This support is usually provided by sophisticated graphical user interfaces - an approach which is capable of greatly improving the user’s productivity, but at the price of specialization to a certain modeling formalism or application domain, or even uniqueness to a specific software package. It therefore is of no help with regard to the interoperability problem.

Among the recent research results in modeling and simulation, two concepts have strong relevance to this problem:

Object oriented modeling languages already demonstrated how object oriented concepts

can be successfully employed to support hierarchical structuring, reuse and evolution of large and complex models independent from the application domain and specialized graphical formalisms.

Non-causal modeling demonstrated that the traditional simulation abstraction - the

input/output block - can be generalized by relaxing the causality constraints, i.e., by not committing ports to an 'input' or 'output' role early, and that this generalization enables both more simple models and more efficient simulation while retaining the capability to include submodels with fixed input/output roles.

Examples of object-oriented and/or non-causal modeling languages include: ASCEND, Dymola, gPROMS, NMF, ObjectMath, Omola, SIDOPS+, Smile, U.L.M., ALLAN, and VHDL-AMS. The combined power of these concepts together with proven technology from existing modeling languages justifies a new attempt at introducing interoperability and openness to the world of modeling and simulation systems.

Having started as an action within ESPRIT project "Simulation in Europe Basic Research Working Group (SiE-WG)" and currently operating as Technical Committee 1 within Eurosim and Technical Chapter on Modelica within Society for Computer Simulation International, a working group made up of simulation tool builders, users from different application domains, and computer scientists has made an attempt to unify the concepts and introduce a common modeling language. This language, called Modelica, is intended for modeling within many application domains (for example: electrical circuits, multi-body systems, drive trains, hydraulics, thermodynamical systems and chemical systems) and possibly using several formalisms (for example: ODE, DAE, bond graphs, finite state automata and Petri nets). Tools which might be general purpose or specialized to certain formalism and/or domain will store the models in the Modelica format in order to allow exchange of models between tools and between users. Much of the Modelica syntax will be hidden from the end-user because, in most cases, a graphical user interface will be used to build models by selecting icons for model components,

(4)

using dialogue boxes for parameter entry and connecting components graphically. The work started in the continuous time domain since there is a common mathematical

framework in the form of differential-algebraic equations (DAE) and there are several existing modeling languages based on similar ideas. There is also significant experience of using these languages in various applications. It thus seems to be appropriate to collect all knowledge and experience and design a new unified modeling language or neutral format for model

representation. The short range goal was to design a modeling language for differential-algebraic equation systems with some discrete event features to handle discontinuities and sampled

systems. The design should be extendible in order that the goal can be expanded to design a multi-formalism, multi-domain, general-purpose modeling language. This is a report of the design state as of December 1998, Modelica version 1.1.

The object-oriented, non-causal modeling methodology and the corresponding standard model representation, Modelica, should be compared with at least four alternatives. Firstly, established commercial general purpose simulation tools, such as ACSL, EASY5, SIMULINK, System Build and others, are continually developed and Modelica will have to offer significant practical advantages with respect to these. Secondly, special purpose simulation programs for electronics (Spice, Saber, etc), multibody systems (ADAMS, DADS, SIMPACK, etc), chemical processes (ASPEN Plus, SpeedUp, etc) have specialized GUI and strong model libraries. However, they lack the multi-domain capabilities. Thirdly, many industrial simulation studies are still done without the use of any general purpose simulation tool, but rather relying on numerical

subroutine libraries and traditional programming languages. Based on experience with present

tools, many users in this category frequently doubt that any general purpose method is capable of offering sufficient efficiency and robustness for their application. Forthly, an IEEE supported

alternative language standardization effort is underway: VHDL-AMS.

Most engineers and scientists recognize the advantages of an expressive and standardized

modeling language. Unlike a few years ago, they are today ready to sacrifice reasonable amounts of short-term advantages for the benefit of abstract things like potential abundance of compatible tools, sound model architecture, and future availability of ready-made model libraries. In this respect, the time is ripe for a new standardization proposal. Another significant argument in favor of a new modeling language lies in recent achievements by present languages using a

causal modeling paradigm. In the last few years, it has in several cases been proved that

non-causal simulation techniques not only compare to, but outperform special purpose tools on applications that are far beyond the capability of established block oriented simulation tools. Examples exist in multi-body and mechatronics simulation, building simulation, and in chemical process plant simulation. A combination of modern numerical techniques and computer algebra methods give rise to this advantage. However, these non-causal modeling and simulation packages are not general enough, and exchange of models between different packages is not possible, i.e. a new unified language is needed. Furthermore, text books promoting the object-oriented, non-causal methodology are now available, such as Cellier (1991), and university courses are given in many countries.

The next section will give an introduction to the basic concepts of Modelica by means of a small example. Requirements for this type of language are then discussed. Section 4 is the main section and it gradually introduces the constructs of Modelica and discusses the rationale behind them. It

(5)

is followed by an overview of present object-oriented equation based modeling languages that have been used as a basis for the Modelica language design. The design rationale from a

computer science point of view is given in section 6. Syntax and detailed semantics as well as the Modelica standard library are presented in the appendices of the Language Specification.

2. Modelica at a Glance

To give an introduction to Modelica we will consider modeling of a simple electrical circuit as shown below.

The system can be broken up into a set of connected electrical standard components. We have a voltage source, two resistors, an inductor, a capacitor and a ground point. Models of these components are typically available in model libraries and by using a graphical model editor we can define a model by drawing an object diagram very similar to the circuit diagram shown above by positioning icons that represent the models of the components and drawing connections.

A Modelica description of the complete circuit looks like

model circuit Resistor R1(R=10); Capacitor C(C=0.01); Resistor R2(R=100); Inductor L(L=0.1); VsourceAC AC; Ground G; equation

connect (AC.p, R1.p); // Capacitor circuit connect (R1.n, C.p);

connect (C.n, AC.n);

connect (R1.p, R2.p); // Inductor circuit connect (R2.n, L.p);

connect (L.n, C.n);

connect (AC.n, G.p); // Ground

(6)

For clarity, the definition of the graphical layout of the composition diagram (here: electric circuit diagram) is not shown, although it is usually contained in a Modelica model as annotations (which are not processed by a Modelica translator and only used by tools). A

composite model of this type specifies the topology of the system to be modeled. It specifies the components and the connections between the components. The statement

Resistor R1(R=10);

declares a component R1 to be of class Resistor and sets the default value of the resistance, R,

to 10. The connections specify the interactions between the components. In other modeling languages connectors are referred as cuts, ports or terminals. The language element connect is a special operator that generates equations taking into account what kind of quantities that are involved as explained below.

The next step in introducing Modelica is to explain how library model classes are defined. A connector must contain all quantities needed to describe the interaction. For electrical

components we need the quantities voltage and current to define interaction via a wire. The types to represent them are declared as

type Voltage = Real(unit="V"); type Current = Real(unit="A");

where Real is the name of a predefined variable type. A real variable has a set of attributes such as unit of measure, initial value, minimum and maximum value. Here, the units of measure are set to be the SI units.

In Modelica, the basic structuring element is a class. There are seven restricted classes with specific names, such as model, type (a class which is an extension of built-in classes, such as Real, or of other defined types), connector (a class which does not have equations and can be used in connections). For a valid model it is fully equivalent to replace the model, type, and connector keywords by the keyword class, because the restrictions imposed by such a specialized class are fulfilled by a valid model.

The concept of restricted classes is advantageous because the modeller does not have to learn several different concepts, but just one: the class concept. All properties of a class, such as syntax and semantic of definition, instantiation, inheritance, genericity are identical to all kinds of restricted classes. Furthermore, the construction of Modelica translators is simplified

considerably because only the syntax and semantic of a class has to be implemented along with some additional checks on restricted classes. The basic types, such as Real or Integer are

built-in type classes, i.e., they have all the properties of a class and the attributes of these basic types are just parameters of the class.

There are two possibilities to define a class: The standard way is shown above for the definition of the electric circuit (model circuit). A short hand notation is possible, if a new class is identical to an existing one and only the default values of attributes are changed. The types above, such as

Voltage, are declared in this way.

A connector class is defined as

(7)

flow Current i;

end Pin;

A connection connect (Pin1, Pin2), with Pin1 and Pin2 of connector class Pin, connects the

two pins such that they form one node. This implies two equations, namely Pin1.v = Pin2.v

and Pin1.i + Pin2.i = 0. The first equation indicates that the voltages on both branches

connected together are the same, and the second corresponds to Kirchhoff’s current law saying that the currents sum to zero at a node (assuming positive value while flowing into the

component). The sum-to-zero equations are generated when the prefix flow is used. Similar laws apply to flow rates in a piping network and to forces and torques in mechanical systems.

When developing models and model libraries for a new application domain, it is good to start by defining a set of connector classes. A common set of connector classes used in all components in the library supports compatibility of the component models.

A common property of many electrical components is that they have two pins. This means that it is useful to define an "interface" model class,

partial model TwoPin "Superclass of elements with two electrical pins"

Pin p, n; Voltage v; Current i; equation v = p.v - n.v; 0 = p.i + n.i; i = p.i; end TwoPin;

that has two pins, p and n, a quantity, v, that defines the voltage drop across the component and a

quantity, i, that defines the current into the pin p, through the component and out from the pin n.

The equations define generic relations between quantities of a simple electrical component. In order to be useful a constitutive equation must be added. The keyword partial indicates that

this model class is incomplete. The key word is optional. It is meant as an indication to a user that it is not possible to use the class as it is to instantiate components. Between the name of a class and its body it is allowed to have a string. It is treated as a comment attribute and is meant to be a documentation that tools may display in special ways.

To define a model for a resistor we exploit TwoPin and add a definition of parameter for the

resistance and Ohm’s law to define the behavior:

model Resistor "Ideal electrical resistor"

extends TwoPin;

parameter Real R(unit="Ohm") "Resistance";

equation

R*i = v;

end Resistor;

The keyword parameter specifies that the quantity is constant during a simulation run, but can change values between runs. A parameter is a quantity which makes it simple for a user to modify the behavior of a model.

A model for an electrical capacitor can also reuse the TwoPin as follows:

(8)

extends TwoPin;

parameter Real C(unit="F") "Capacitance";

equation

C*der(v) = i;

end Capacitor;

where der(v) means the time derivative of v. A model for the voltage source can be defined as

model VsourceAC "Sin-wave voltage source"

extends TwoPin;

parameter Voltage VA = 220 "Amplitude";

parameter Real f(unit="Hz") = 50 "Frequency"; constant Real PI=3.141592653589793;

equation

v = VA*sin(2*PI*f*time);

end VsourceAC;

In order to provide not too much information at this stage, the constant PI is explicitly declared,

although it is usually imported from the Modelica standard library (see appendix of the Language Specification). Finally, we must not forget the ground point.

model Ground "Ground"

Pin p;

equation

p.v = 0;

end Ground;

The purpose of the ground model is twofold. First, it defines a reference value for the voltage levels. Secondly, the connections will generate one Kirchhoff’s current law too many. The ground model handles this by introducing an extra current quantity p.i, which implicitly by the

equations will be calculated to zero.

Comparison with block oriented modeling

If the above model would be represented as a block diagram, the physical structure will not be retained as shown below. The block diagram is equivalent to a set of assignment statements calculating the state derivatives. In fact, Ohm’s law is used in two different ways in this circuit, once solving for i and once solving for u.

(9)

This example clearly shows the benefits of physically oriented, non-causal modeling compared to block oriented, causal modeling.

3. Requirements for Multi-domain Modeling

In this section, the most important requirements used for the Modelica language design are collected together.

The Modelica language should support both ODE and DAE (differential-algebraic equations) formulations of models. The mixture of DAE and discrete events should be possible and be defined in such a way that efficient simulation can be performed. Other data types than real, such as integer, Boolean and string should be supported. External functions written in common

programming languages need to be supported in addition to a data type corresponding to external object references. It should be possible to express information about units used and minimum and maximum allowed values for a variable in order that a modeling tool might do consistency checking. It should be possible to parameterize models with both values of certain quantities and also with respect to model representation, i.e., allowing, for example, to select different levels of detail for a model. Component arrays and the connection of elements of such arrays should be supported. In order to allow exchange of models between different tools, also a certain

standardization of graphical attributes for icon definitions and object diagrams should be done within the Modelica definition.

Certain modeling features will be added in later stages of the Modelica design. One example is to allow partial differential equations. More advanced discrete event modeling facilities will also be considered then, for example to allow queue handling and dynamical creation of model

instances, see (Elmqvist, et.al. 1998).

Besides requirements for modeling in general, every discipline has its specific peculiarities and difficulties which often require special consideration. In the following sections, such

requirements from multiple domains are presented.

Block Diagrams

Block diagrams consist of input/output blocks. For the definition of linear state space systems and transfer functions matrices and matrix equations are needed. This is most conveniently done with a MATLAB and/or Mathematica-like notation.

It is also important to support fixed and variable time delays. This could be done by calling an external function which interpolates in past values. However, if a delay is defined via a specific language construct, it is in principle possible to use a specific integrator to take care of the delay which can be done in a better numerical way than in the first case. Therefore, a delay operator should be defined in the language which leaves the actual implementation to the Modelica

translator. Furthermore, interpolation in 1-, 2-, n-dimensional tables with fixed and variable grids has to be supported, because technical models often contain tables of measured data.

(10)

If it is known that a component is an input/output block, local analysis of the equations is possible which improves the error diagnostics considerably. For example, it can be detected whether the number of unknown variables of the block matches the number of equations in the block. Therefore, it should be possible to state explicitly that a model component is an

input/output block.

Multi-Body Systems

Multi-body systems are used to model 3-dimensional mechanical systems, such as robots, satellites and vehicles. Nearly all variables in multi-body system modeling are vectors or

matrices and the equations are most naturally formulated as matrix equations. Therefore, support of matrices is essential. This should include the cross operator for the vector cross-product because this operation often occurs in mechanical equations. It is convenient to have multi-body objects with several interfaces, but without requiring that every interface has to be connected for a model. For example, revolute and prismatic joints should have an additional interface to attach a drive train to drive the joint.

Usually, multi-body algorithms are written in such a way that components cannot be connected together in an arbitrary way. To ensure that an erroneous connection cannot be created, it should be possible to define rules about the connection structure. Rules help to provide a meaningful error message as early as possible.

In order that Modelica will be attractive to use for modeling of multi-body systems, efficiency is crucial. It must be possible that Modelica generated code is as efficient as that of special purpose multi-body programs. For that, operators like symmetric and orthogonal are necessary in order to be able to state that a matrix is symmetric or orthogonal, respectively.

Electrical and Electronic Circuits

Models of different complexity to describe electrical components are often needed. Therefore, it should be easy to replace a specific model description of a component by another one in the model of an electrical circuit.

It might be advantageous to implement complicated elements, such as detailed transistor models, by procedural code. This may be either an external C or C++ function or a Modelica function. In any case, the model equations are already sorted and are not expanded, i.e., every instance uses the same "function call". This is especially important, if a large number of instances are present. It is essential that SPICE net list descriptions of electrical circuits can be used within Modelica, because vendor models of electric hardware components are described in this format. It seems sufficient to provide the SPICE component models as classes in a Modelica library and to rely on an external tool which transforms a SPICE net list description into a composite Modelica model. Besides non-linear simulation, small signal analysis is often needed for electrical circuits. This

(11)

implies linearization and frequency response calculation. Numerical linearization introduces unnecessary errors. For electrical circuits it is almost always possible to symbolically

differentiate the components. Special language constructs are probably not needed because in principle Modelica translators can be realized which derive the (symbolically) linearized

components automatically. Modern electric circuit programs use symbolic Jacobians to enhance the efficiency. Similar to linearization, it should be possible to compute the symbolic Jacobian from a Modelica model by symbolic differentiation. If a component is provided as external function, it should be possible to provide an external function for the corresponding Jacobian of the component as well.

Chemical and Thermodynamic Systems

Processing systems for chemical or energy production are often composed of complex structures. The modeling of these systems needs encapsulation of detailed descriptions and abstraction into hierarchies in order to handle the complexity. To increase the reuse of submodels in complex structures there is a need for an advanced concept of parameterization of submodels. Especially, component arrays and class parameters are needed. An example is a structure parameter for the change of the number of trays in a distillation plant.

In order to achieve a high degree of model reuse, all medium specific data and calculation should be encapsulated in a medium properties submodel. In most cases the thermodynamic properties of the medium will be calculated externally by one of the many available specialized software packages. Thus it is necessary to provide a calling interface to external functions in ordinary programming languages. Keeping in mind both efficient simulation and model reuse, there should be a uniform way how thermodynamic properties of different external packages can be accessed from Modelica models.

Many applications in process engineering and power plant simulation can only be captured adequately with distributed parameter models. A method of lines (MOL) grid discretisation (either finite difference, finite volume or finite element methods) is the state of the art of all but a few very specialized simulation packages for modeling partial differential equations (PDEs). Modelica is envisaged as a language that is both open to future advances in numerical techniques and as an exchange format for many existing software environments. Existing simulation

environments should be able to simulate Modelica code after preprocessing to DAE form. Support for PDE is planned for future versions of Modelica.

Energy domain systems

Simulation in the energy domain sector is mainly used for improving or designing technical systems: boilers, kilns, HVAC systems, pressure governors, etc. The first characteristic of these systems is that they are complex and multi-domain. For example the building energy domain deals with all types of heat exchanges, with fluid flows, with combustion, with particle pollution, with system controls, automatons etc. Modelica needs to address all these issues. It stresses the need for non-causal hierarchical modeling. To a certain extent temperature distribution and PDE

(12)

are relevant for improvement studies. Matrices and PDE features are useful. Combustion models need to address thermodynamic tables by means of a suitable feature. But, the main requirements of this domain are linked with user-friendliness, reuse, documentation, capitalization for study efficiency and reproducibility. This means that it is necessary to isolate models, isolate numerical data, isolate validation runs, integrate validity checks (domains, constraints, units, etc.) and in order to produce automatic documentation include documentation features.

Bond graphs

Bond graphs (Karnopp and Rosenberg, 1968; Breedveld, 1985) are designed to model the energy

flow of physical systems using a small set of unified modeling primitives, such as storage,

transformation and dissipation of (free) energy. Bond graphs are in principle labeled and directed graphs, in which the vertices represent submodels and the edges represent an ideal energy

connection between power ports. This connection is a point-to-point connection, i.e. only one bond can be connected to a power port. When preparing for simulation, the bonds are embodied as two-signal connections with opposite directions. This signal direction depends on both the internal description of the submodel and the structure of the bond graph where the submodel is used; it is an algorithmic process. Consequently, the model equations are non-causal. Within some submodel equations, the power directions of the connected bonds are used in generating the proper equations. As a consequence, it must be possible to define rules about the connection structure, especially that only one-to-one connections are possible. Furthermore, it must be possible to inquire the direction of a connection in a component, in order that the positive energy flow direction can be deduced. Since bond graphs can be mixed with block-diagram parts, bond-graph submodels can have power ports, signal inputs and signal outputs as their interfacing elements. Furthermore, aspects like the physical domain of a bond (energy flow) can be used to support the modeling process, and should therefore be incorporated in Modelica. Note that the power bonds can be multi dimensional, i.e., are composed of a matrix of single power bonds. This multi-bond feature is used to describe, e.g., 3D mechanical systems in an elegant and compact way.

Finite Automata and Extensions

Finite automata are used to model discrete systems, such as discrete control devices as well as switching structure of clutches or idealized thyristors. Several extensions are popular, e.g., Petri nets, grafcet and state charts. It seems more flexible and powerful to build component libraries of e.g., Petri nets and state charts, using basic Modelica language constructs instead of having direct built-in language elements.

4. Modelica Language Rationale and Overview

Modeling the dynamic behavior of physical systems implies that one is interested in specific properties of a limited class of systems. These restrictions give a means to be more specific then is possible when focusing on systems in general. Therefore, the physical background of the

(13)

models should be reflected in Modelica.

Nowadays, physical systems are often complex and span multiple physical domains, whereas mostly these systems are computer controlled. Therefore, hierarchical models (i.e., models described as connected submodels) using properties of the physical domains involved should easily be described in Modelica. To properly support the modeler (i.e. to be able to perform automated modeling), these physical properties should be incorporated in Modelica in such a way, that checking consistency, like checking against basic laws of physics, can be programmed easily in the Modelica translators. Examples of physical properties are the physical quantity and the physical domain of a variable. This implies that a suitable representation for physical systems modeling is more than a set of pure mathematical differential equations.

4.1 Basic Language Elements

The language constructs will be developed gradually starting with small examples, and then extended by considering practical issues when modeling large systems.

Handling large models means careful structuring in order to reuse model knowledge. A model is built-up from

• basic components such as Real, Integer, Boolean and String

• structured components, to enable hierarchical structuring

• component arrays, to handle real matrices, arrays of submodels, etc

• equations and/or algorithms (= assignment statements)

• connections

• functions

Some means of declaring variable properties is needed, since there are different kinds of variables, Parameters should be given values and there should be a possibility to give initial conditions.

Basic declarations of variables can be made as follows:

Real u, y(start=1);

parameter Real T=1;

Real is the name of a predefined class or type. A Real variable has an attribute called start to

give its initial value. A component declaration can be preceded by a specifier like constant or parameter indicating that the component is constant, i.e., its derivative is zero. The specifier parameter indicates that the value of the quantity is constant during simulation runs. It can be modified when a component is reused and between simulation runs. The component name can be followed by a modification to change the value of the component or its attributes.

Equations are composed of expressions both on the left hand side and the right hand side like in the following filter equation.

(14)

equation

T*der(y) + y = u;

Time derivative is denoted by der( ).

4.2 Classes for Reuse of Modeling Knowledge

Assume we would like to connect two filters in series. Instead of repeating the filter equation, it is more convenient to make a definition of a filter once and create two instances. This is done by declaring a class. A class declaration contains a list of component declarations and a list of equations preceded by the keyword equation. An example of a low pass filter class is shown below. class LowPassFilter parameter Real T=1; Real u, y(start=1); equation T*der(y) + y = u; end LowPassFilter;

The model class can be used to create two instances of the filter with different time constants and "connecting" them together as follows

class FiltersInSeries LowPassFilter F1(T=2), F2(T=3); equation F1.u = sin(time); F2.u = F1.y; end FiltersInSeries;

In this case we have used a modification to modify the time constant of the filters to T=2 and T=3 respectively from the default value T=1 given in the low-pass filter class. Dot notation is used to reference components, like u, within structured components, like F1. For the moment it can be assumed that all components can be reached by dot-notation. Restrictions of accessibility will be introduced later. The independent variable is referenced as time.

If the FiltersInSeries model is used to declare components at a higher hierarchical level, it is still possible to modify the time constants by using a hierarchical modification:

model ModifiedFiltersInSeries

FiltersInSeries F12(F1(T=6), F2(T=11));

end ModifiedFiltersInSeries;

The class concept is similar as in programming languages. It is used for many purposes in Modelica, such as model components, connection mechanisms, parameter sets, input-output blocks and functions. In order to make Modelica classes easier to read and to maintain, special keywords have been introduced for such special uses, model, connector, record, block, type and package. It should be noted though that the use of these keywords only apply certain restrictions, like records are not allowed to contain equations. However, for a valid model, the replacement of these keywords by class would give exactly the same model behavior. In the following description we will use the specialized keywords in order to convey their meaning.

(15)

Records

It is possible to introduce parameter sets as records which is a restricted form of class which may not have any equations:

record FilterData Real T; end FilterData; record TwoFilterData FilterData F1, F2; end TwoFilterData; model ModifiedFiltersInSeries2 TwoFilterData TwoFilterData1(F1(T=6), F2(T=11)); FiltersInSeries F12=TwoFilterData1; end ModifiedFiltersInSeries2;

The modification F12=TwoFilterData1 is possible since all the components of TwoFilterData1 (F1, F2, T) are present in FiltersInSeries. More about type

compatibility can be found in section 4.4. Packages

Class declarations may be nested. One use of that is maintenance of the name space for classes, i.e., to avoid name clashes, by storing a set of related classes within an enclosing class. There is a special kind of class for that, called package. A package may only contain declarations of

constants and classes. Dot-notation is used to refer to the inner class. Examples of packages are given in the appendix of the Language Specification, where the Modelica standard package is described which is always available for a Modelica translator.

Information Hiding

So far we have assumed all components to be accessible from the outside by dot-notation. To develop libraries in such a way is a bad principle. Information hiding is essential from a maintenance point of view.

Considering the FiltersInSeries example, it might be a good idea to just declare two parameters for the time constants, T1 and T2, the input, u and the output y as accessible from the outside. The realization of the model, using two instances of model LowPassFilter, is a protected detail. Modelica allows such information hiding by using the heading protected.

model FiltersInSeries2 parameter Real T1=2, T2=3; input Real u; output Real y; protected LowPassFilter F1(T=T1), F2(T=T2); equation F1.u = u; F2.u = F1.y;

(16)

y = F2.y;

end FiltersInSeries2;

Information hiding does not control interactive environments though. It is possible to inspect and plot protected variables. Note, that variables of a protected section of a class A can be accessed by a class which extends class A. In order to keep Modelica simple, additional visibility rules present in other object-oriented languages, such as private (no access by subtypes), are not used.

4.3 Connections

We have seen how classes can be used to build-up hierarchical models. It will now be shown how to define physical connections by means of a restricted class called connector.

We will study modeling of a simple electrical circuit. The first issue is then how to represent pins and connections. Each pin is characterized by two variables, voltage and current. A first attempt would be to use a connector as follows.

connector Pin

Real v, i;

end Pin;

and build a resistor with two pins p and n like

model Resistor

Pin p, n; // "Positive" and "negative" pins. parameter Real R "Resistance";

equation

R*p.i = p.v - n.v;

n.i = p.i; // Assume both n.i and p.i to be positive // when current flows from p to n.

end Resistor;

A descriptive text string enclosed in " " can be associated with a component like R. A comment which is completely ignored can be entered after //. Everything until the end of the line is then ignored. Larger comments can be enclosed in /* */.

A simple circuit with series connections of two resistors would then be described as:

model FirstCircuit

Resistor R1(R=100), R2(R=200);

equation

R1.n = R2.p;

end FirstCircuit;

The equation R1.n = R2.p represents the connection of pin n of R1 to pin p of R2. The semantics of this equation on structured components is the same as

R1.n.v = R2.p.v R1.n.i = R2.p.i

This describes the series connection correctly because only two components were connected. Some mechanism is needed to handle Kirchhoff’s current law, i.e. that the currents of all wires connected at a node are summed to zero. Similar laws apply to flows in a piping network and to forces and torques in mechanical systems. The default rule is that connected variables are set equal. Such variables are called across variables. Real variables that should be summed to zero

(17)

are declared with prefix flow. Such variables are also called through variables. In Modelica we assume that such variables are positive when the flow (or corresponding vector) is into the component.

connector Pin

Real v; flow Real i;

end Pin;

It is useful to introduce units in order to enhance the possibility to generate diagnostics based on redundant information. Modelica allows deriving new classes with certain modified attributes. The keyword type is used to define a new class, which is derived from the built-in data types or defined records. Defining Voltage and Current as modifications of Real with other attributes and a corresponding Pin can thus be made as follows:

type Voltage = Real(unit="V"); type Current = Real(unit="A"); connector Pin

Voltage v; flow Current i;

end Pin;

model Resistor

Pin p, n; // "Positive" and "negative" pins. parameter Real R(unit="Ohm") "Resistance";

equation

R*p.i = p.v - n.v;

p.i + n.i = 0; // Positive currents into component.

end Resistor;

We are now able to correctly connect three components at one node.

model SimpleCircuit Resistor R1(R=100), R2(R=200), R3(R=300); equation connect(R1.p, R2.p); connect(R1.p, R3.p); end SimpleCircuit;

connect is a special operator that generates equations taking into account what kind of variables that are involved. The equations are in this case equivalent to

R1.p.v = R2.p.v; R1.p.v = R3.p.v;

R1.p.i + R2.p.i + R3.p.i = 0;

In certain cases, a model library might be built on the assumption that only one connection can be made to each connector. There is a built-in function cardinality(c) that returns the number

of connections that has been made to a connector c. It is also possible to get information about the direction of a connection by using the built-in function direction(c) (provided cardinality(c)

== 1). For a connection, connect(c1, c2), direction(c1) returns -1 and direction(c2) returns 1. An example of the use of cardinality and direction is the bond graph components in the standard Modelica library.

(18)

4.4 Partial Models and Inheritance

A very important feature in order to build reusable descriptions is to define and reuse partial

models. Since there are other electrical components with two pins like capacitor and inductor we

can define a TwoPin as a base for all of these models.

partial model TwoPin

Pin p, n;

Voltage v "Voltage drop";

equation

v = p.v - n.v; p.i + n.i = 0;

end TwoPin;

Such a partial model can be extended or reused to build a complete model like an inductor.

model Inductor "Ideal electrical inductance"

extends TwoPin;

parameter Real L(unit="H") "Inductance";

equation

L*der(i) = v;

end Inductor;

The facility is similar to inheritance in other languages. Multiple inheritance, i.e., several extends statements, is supported.

The type system of Modelica is greatly influenced by type theory (Abadi and Cardelli 1996), in particular their notion of subtyping. Abadi and Cardelli separate the notion of subclassing (the mechanism for inheritance) from the notion of subtyping (the structural relationship that

determines type compatibility). The main benefit is added flexibility in the composition of types, while still maintaining a rigorous type system.

Inheritance is not used for classification and type checking in Modelica. An extends clause can be used for creating a subtype relationship by inheriting all components of the base class, but it is not the only means to create it. Instead, a class A is defined to be a subtype of class B, if class A contains all the public components of B. In other words, B contains a subset of the components declared in A. This subtype relationship is especially used for class parameterization as

explained in the next section.

Assume, for example, that a more detailed resistor model is needed, describing the temperature dependency of the resistance:

model TempResistor "Temperature dependent electrical resistor"

extends TwoPin;

parameter Real R(unit="Ohm") "Resistance for ref. Temp."; parameter Real RT(unit="Ohm/degC")=0 "Temp. dep. Resistance."; parameter Real Tref(unit="degC")=20 "Reference temperature."; Real Temp=20 "Actual temperature";

equation

v = p.i*(R + RT*(Temp-Tref));

end TempResistor;

It is not possible to extend this model from the ideal resistor model Resistor discussed in

(19)

Still, the TempResistor is a subtype of Resistor because it contains all the public components

of Resistor.

4.5 Class Parameterization

We will now discuss a more powerful parameterization, not only involving values like time constants and matrices but also classes. (This section might be skipped during the first reading.) Assume that we have the description (of an incomplete circuit) as above.

model SimpleCircuit Resistor R1(R=100), R2(R=200), R3(R=300); equation connect(R1.p, R2.p); connect(R1.p, R3.p); end SimpleCircuit;

Assume we would like to utilize the parameter values given for R1.R and R2.R and the circuit topology, but exchange Resistor with the temperature dependent resistor model, TempResistor, discussed above. This can be accomplished by redeclaring R1 and R2 as follows.

model RefinedSimpleCircuit Real Temp;

extends SimpleCircuit(

redeclare TempResistor R1(RT=0.1, Temp=Temp), redeclare TempResistor R2);

end RefinedSimpleCircuit;

Since TempResistor is a subtype of Resistor, it is possible to replace the ideal resistor model. Values of the additional parameters of TempResistor and definition of the actual temperature can be added in the redeclaration:

redeclare TempResistor R1(RT=0.1, Temp=Temp);

This is a very strong modification of the circuit model and there is the issue of possible invalidation of the model. We thus think such modifications should be clearly marked by the keyword redeclare. Furthermore, we think the modeller of the SimpleCircuit should be able to state that such modifications are not allowed by declaring a component as final.

final Resistor R3(R=300);

It should also be possible to state that a parameter is frozen to a certain value, i.e., is not a parameter anymore:

Resistor R3(final R=300);

To use another resistor model in the model SimpleCircuit, we needed to know that there were two replaceable resistors and we needed to know their names. To avoid this problem and prepare for replacement of a set of models, one can define a replaceable class, ResistorModel. The actual class that will later be used for R1 and R2 must have Pins p and n and a parameter R in order to be compatible with how R1 and R2 are used within SimpleCircuit2. The replaceable model ResistorModel is declared to be a Resistor model. This means that it will be enforced that the actual class will be a subtype of Resistor, i.e., have compatible connectors and parameters. Default for ResistorModel, i.e., when no actual redeclaration is made, is in this case Resistor. Note, that R1 and R2 are in this case of class ResistorModel.

(20)

model SimpleCircuit2

replaceable model ResistorModel = Resistor;

protected

ResistorModel R1(R=100), R2(R=200); final Resistor R3(final R=300);

equation

connect(R1.p, R2.p); connect(R1.p, R3.p);

end SimpleCircuit2;

Binding an actual model TempResistor to the replaceable model ResistorModel is done as follows.

model RefinedSimpleCircuit2 =

SimpleCircuit2(redeclare model ResistorModel = TempResistor);

Another case where redeclarations are needed is extensions of interfaces. Assume we have a definition for a Tank in a model library:

connector Stream

Real pressure;

flow Real volumeFlowRate;

end Stream; model Tank

parameter Real Area=1;

replaceable connector TankStream = Stream; TankStream Inlet, Outlet;

Real level;

equation

// Mass balance.

Area*der(level) = Inlet.volumeFlowRate + Outlet.volumeFlowRate; Outlet.pressure = Inlet.pressure;

end Tank;

We would like to extend the Tank to model the temperature of the stream. This involves both extension to interfaces and to model equations.

connector HeatStream extends Stream;

Real temp;

end HeatStream; model HeatTank

extends Tank(redeclare connector TankStream = HeatStream); Real temp;

equation

// Energy balance.

Area*Level*der(temp) = Inlet.volumeFlowRate*Inlet.temp + Outlet.volumeFlowRate*Outlet.temp;

Outlet.temp = temp; // Perfect mixing assumed.

end HeatTank;

(21)

automatically produced by a Modelica translator).

model HeatTankT

parameter Real Area=1; connector TankStream Real pressure;

flow Real volumeFlowRate; Real temp;

end TankStream;

TankStream Inlet, Outlet; Real level;

Real temp;

equation

Area*der(level) = Inlet.volumeFlowRate + Outlet.volumeFlowRate; Outlet.pressure = Inlet.pressure;

Area*level*der(temp) = Inlet.volumeFlowRate*Inlet.temp + Outlet.volumeFlowRate*Outlet.temp;

Outlet.temp = temp;

end HeatTankT;

Replaceable classes are also very convenient to separate fluid properties from the actual device where the fluid is flowing, such as a pump.

4.6 Matrices

An array variable can be declared by appending dimensions after the class name or after a component name.

Real[3] position, velocity, acceleration; Real[3,3] transformation;

or

Real position[3], velocity[3], acceleration[3], transformation[3, 3];

It is also possible to make a matrix type

type Transformation = Real[3, 3];

Transformation transformation;

The following definitions are appropriate for modeling 3D motion of mechanical systems.

type Position = Real(unit="m"); type Position3 = Position[3]; type Force = Real(unit="N"); type Force3 = Force[3];

type Torque = Real(unit="N.m"); type Torque3 = Torque[3];

It is now possible to introduce the variables that are interacting between rigidly connected bodies in a free-body diagram.

connector MbsCut

Transformation S "Rotation matrix describing frame A" " with respect to the inertial frame"; Position3 r0 "Vector from the origin of the inertial"

(22)

" frame to the origin of frame A";

flow Force3 f "Resultant cut-force acting at the origin" " of frame A";

flow Torque3 t "Resultant cut-torque with respect to the" " origin of frame A";

end MbsCut;

Such a definition can be used to model a rigid bar as follows.

model Bar "Massless bar with two mechanical cuts."

MbsCut a b; parameter

Position3 r = {0, 0, 0}

"Position vector from the origin of cut-frame A" " to the origin of cut-frame B";

equation

// Kinematic relationships of cut-frame A and B b.S = a.S;

b.r0 = a.r0 + a.S*r;

// Relations between the forces and torques acting at // cut-frame A and B

zeros(3) = a.f + b.f;

zeros(3) = a.t + b.t - cross(r, a.f);

// The function cross defines the cross product // of two vectors

end Bar;

Vector and matrix expressions are formed in a similar way as in Mathematica and MATLAB. The operators +, -, * and / can operate on either scalars, vectors or two-dimensional matrices of type real and integer. Division is only possible with a scalar. An array expression is constructed as {expr1, expr2, ... exprn}. A matrix (two dimensional array) can be formed as

[expr11, expr12, ... expr1n;

expr21, expr22, ... expr2n;

exprm1, exprm2, ... exprmn]

i.e. with commas as separators between columns and semicolon as separator between rows. Indexing is written as A[i] with the index starting at 1. Submatrices can be formed by utilizing : notation for index ranges, A[i1:i2, j1:j2]. The then and else branches of if-then-else expressions may contain matrix expressions provided the dimensions are the same. There are several built-in matrix functions like zeros, ones, identity, transpose, skew (skew operator for 3 x 3 matrices) and cross (cross product for 3-dimensional vectors. For details about matrix expressions and

available functions, see the Language Specification.

Matrix sizes and indices in equations must be constant during simulation. If they depend on parameters, it is a matter of "quality of implementation" of the translator whether such parameters can be changed at simulation time or only at compilation time.

(23)

case. It is possible to postulate the data flow directions by using the prefixes input and output in declarations. This also allows checking that only one connection is made to an input, that outputs are not connected to outputs and that inputs are not connected to inputs on the same hierarchical level.

A matrix can be declared without specific dimensions by replacing the dimension with a colon: A[:, :]. The actual dimensions can be retrieved by the standard function size. A general state space model is an input-output block (restricted class, only inputs and outputs) and can be described as

block StateSpace

parameter Real A[:, :],

B[size(A, 1), :], C[:, size(A, 2)],

D[size(C, 1), size(B, 2)]=zeros(size(C, 1), size(B, 2)); input Real u[size(B, 2)];

output Real y[size(C, 1)];

protected

Real x[size(A, 2)];

equation

assert(size(A, 1) == size(A, 2), "Matrix A must be square.");

der(x) = A*x + B*u; y = C*x + D*u;

end StateSpace;

Assert is a predefined function for giving error messages taking a Boolean condition and a string as arguments. The actual dimensions of A, B and C are implicitly given by the actual matrix parameters. D defaults to a zero matrix:

block TestStateSpace

StateSpace S(A = [0.12, 2; 3, 1.5], B = [2, 7; 3, 1], C = [0.1, 2]);

equation

S.u = {time, sin(time)};

end TestStateSpace;

The block class is introduced to allow better diagnostics for pure input/output model

components. In such a case the correctness of the component can be analyzed locally which is not possible for components where the causality of the public variables is unknown.

4.7 Repetition, Algorithms and Functions

Regular Equation Structures

Matrix equations are in many cases convenient and compact notations. There are, however, cases when indexed expressions are easier to understand. A loop construct, for, which allow indexed expressions will be introduced below.

Consider evaluation of a polynomial function

n

y = sum ci xi

(24)

with a given set of coefficients ci in a vector a[n+1] with a[i] = ci-1. Such a sum can be expressed

in matrix form as a scalar product of the form

a * {1, x, x^2, ... x^n}

if we could form the vector of increasing powers of x. A recursive formulation is possible.

xpowers[1] = 1;

xpowers[2:n+1] = xpowers[1:n]*x; y = a * xpowers;

The recursive formulation would be expanded to

xpowers[1] = 1; xpowers[2] = xpowers[1]*x; xpowers[3] = xpowers[2]*x; ... xpowers[n+1] = xpowers[n]*x; y = a * xpowers;

The recursive formulation above is not so understandable though. One possibility would be to introduce a special matrix operator for element exponentiation as in MATLAB (.^). The readability does not increase much though.

Matrix equations like

xpowers[2:n+1] = xpowers[1:n]*x;

can be expressed in a form that is more familiar to programmers by using a for loop:

for i in 1:n loop

xpowers[i+1] = xpowers[i]*x;

end for;

This for-loop is equivalent to n equations. It is also possible to use a block for the polynomial evaluation:

block PolynomialEvaluator

parameter Real a[:]; input Real x;

output Real y;

protected

parameter Integer n = size(a, 1)-1;

Real xpowers[n+1]; equation xpowers[1] = 1; for i in 1:n loop xpowers[i+1] = xpowers[i]*x; end for; y = a * xpowers; end PolynomialEvaluator;

The block can be used as follows:

PolynomialEvaluator polyeval(a={1, 2, 3, 4}); Real p;

equation

polyeval.x = time; p = polyeval.y;

(25)

It is also possible to bind the inputs and outputs in the parameter list of the invocation.

PolynomialEvaluator polyeval(a={1, 2, 3, 4}, x=time, y=p);

Regular Model Structures

The for construct is also essential in order to make regular connection structures for component arrays, for example:

Component components[n]; equation for i in 1:n-1 loop connect(components[i].Outlet, components[i+1].Inlet); end for; Algorithms

The basic describing mechanism of Modelica are equations and not assignment statements. This gives the needed flexibility, e.g., that a component description can be used with different

causalities depending on how the component is connected. Still, in some situations it is more convenient to use assignment statements. For example, it might be more natural to define a digital controller with ordered assignment statements since the actual controller will be implemented in such a way.

It is possible to call external functions written in other programming languages from Modelica and to use all the power of these programming languages. This can be quite dangerous because many difficult-to-detect errors are possible which may lead to simulation failures. Therefore, this should only be done by the simulation specialist if tested legacy code is used or if a Modelica implementation is not feasible. In most cases, it is better to use a Modelica algorithm which is designed to be much more secure than calling external functions.

The vector xvec in the polynomial evaluator above had to be introduced in order that the number

of unknowns are the same as the number of equations. Such a recursive calculation scheme is often more convenient to express as an algorithm, i.e., a sequence of assignment statements, if-statements and loops, which allows multiple assignments:

algorithm y := 0; xpower := 1; for i in 1:n+1 loop y := y + a[i]*xpower; xpower := xpower*x; end for;

A Modelica algorithm is a function in the mathematical sense, i.e. without internal memory and side-effects. That is, whenever such an algorithm is used with the same inputs, the result will be exactly the same. If a function is called during continuous integration this is an absolute

prerequisite. Otherwise the mathematical assumptions on which the integration algorithms are based on, would be violated. An internal memory in an algorithm would lead to a model giving different results when using different integrators. With this restriction it is also possible to symbolically form the Jacobian by means of automatic differentiation. This requirement is also present for functions called only at event instants (see below). Otherwise, it would not be possible to restart a simulation at any desired time instant, because the simulation environment

(26)

does not know the actual value of the internal algorithm memory.

In the algorithm section, ordered assignment statements are present. To distinguish from equations in the equation sections, a special operator, :=, is used in assignments (i.e. given causality) in the algorithm section. Several assignments to the same variable can be performed in one algorithm section. Besides assignment statements, an algorithm may contain if-then-else expressions, if-then-else constructs (see below) and loops using the same syntax as in an equation-section.

Variables that appear on the left hand side of the assignment operator, which are conditionally assigned, are initialized to their start value (for algorithms in functions, the value given in the binding assignment) whenever the algorithm is invoked. Due to this feature it is impossible for a function to have a memory. Furthermore, it is guaranteed that the output variables always have a well-defined value.

Within an equation section of a class, algorithms are treated as a set of equations. Especially, algorithms are sorted together with all other equations. For the sorting process, the calling of a function with n output arguments is treated as n implicit equations, where every equation

depends on all output and on all input arguments. This ensures that the implicit equations remain together during sorting (and can be replaced by the algorithm invocation afterwards), because the implicit equations of the function form one algebraic loop.

In addition to the for loop, there is a while loop which can be used within algorithms:

while condition loop

{ algorithm }

end while;

Functions

The polynomial evaluator above is a special input-output block since it does not have any states. Since it does not have any memory, it would be possible to invoke the polynomial function as a function, i.e. memory for variables are allocated temporarily while the algorithm of the function is executing. Modelica allows a specialization of a class called function which has only public inputs and outputs, one algorithm and no equations.

The polynomial evaluation can thus be described as:

function PolynomialEvaluator2

input Real a[:]; input Real x; output Real y; protected Real xpower; algorithm y := 0; xpower := 1;

for i in 1:size(a, 1) loop

y := y + a[i]*xpower; xpower := xpower*x;

(27)

end PolynomialEvaluator2;

A function declaration is similar to a class declaration but starts with the function keyword. The input arguments are marked with the keyword input (since the causality is input). The result argument of the function is marked with the keyword output.

No internal states are allowed, i.e., the der- and pre- operators are not allowed. Any class can be used as an input and output argument. All public, non-constant variables of a class in the output argument are the outputs of a function.

Instead of creating a polyeval object as was needed for the block PolynomialEvaluator:

PolynomialEvaluator polyeval(a={1, 2, 3, 4}, x=time, y=p);

it is possible to invoke the function as usual in an expression.

p = PolynomialEvaluator2(a={1, 2, 3, 4}, x=time);

It is also possible to invoke the function with positional association of the actual arguments:

p = PolynomialEvaluator2({1, 2, 3, 4}, time);

External functions

It is possible to call functions defined outside of the Modelica language. The body of an external function is marked with the keyword external:

function log

input Real x; output Real y;

external end log;

There is a "natural" mapping from Modelica to the target language and its standard libraries. The C language is used as the least common denominator.

The arguments of the external function are taken from the Modelica declaration. If there is a scalar output, it is used as the return type of the external function; otherwise the results are returned through extra function parameters. Arrays of simple types are mapped to an argument of the simple type, followed by the array dimensions. Storage for arrays as return values is allocated by the calling routine, so the dimensions of the returned array is fixed. More details are discussed in the appendix of the Language Specification.

4.8 Hybrid Models

Modelica can be used for mixed continuous and discrete models. For the discrete parts, the synchronous data flow principle with the single assignment rule is used. This fits well with the continuous DAE with equal number of equations as variables. Certain inspiration for the design has been obtained from the languages Signal (Gautier, et.al., 1994) and Lustre (Halbwachs, et.al. 1991).

Discontinuous Models

(28)

operating regions. A limiter can thus be written as

y = if u > HighLimit then HighLimit

else if u < LowLimit then LowLimit else u;

This construct might introduce discontinuities. If this is the case, appropriate information about the crossing points should be provided to the integrator. The use of crossing functions is

described later.

More drastic changes to the model might require replacing one set of equations with another depending on some condition. It can be described as follows using vector expressions:

zeros(3) = if cond_A then

{ expression_A1l - expression_A1r, expression_A2l - expression_A2r }

else if cond_B then

{ expression_B1l - expression_B1r, expression_B2l - expression_B2r }

else

{ expression_C1l - expression_C1r, expression_C2l - expression_C2r };

The size of the vectors must be the same in all branches, i.e., there must be equal number of

expressions (equations) for all conditions.

It should be noted that the order of the equations in the different branches is important. In certain cases systems of simultaneous equations will be obtained which might not be present if the ordering of the equations in one branch of the if-construct is changed. In any case, the model remains valid. Only the efficiency might be unnecessarily reduced.

Conditional Models

It is useful to be able to have models of different complexities. For complex models, conditional

components are needed as shown in the next example where the two controllers are modeled

itself as subcomponents:

block Controller

input Boolean simple=true; input Real e;

output Real y; protected

Controller1 c1(u=e, enable=simple); Controller2 c2(u=e, enable=not simple); equation

y = if simple then c1.y else c2.y; end Controller;

Attribute enable is built-in Boolean input of every block with default equation "enable=true". It

allows enabling or disabling a component. The enable-condition may be time and state

dependent. If enable=false for an instance, its equations are not evaluated, all declared variables are held constant and all subcomponents are disabled. Special consideration is needed when enabling a subcomponent. The reset attribute makes it possible to reset all variables to their Start-values before enabling. The reset attribute is propagated to all subcomponents. The previous controller example could then be generalized as follows, taking into account that the Boolean variable simple could vary during a simulation.

(29)

block Controller

input Boolean simple=true; input Real e

output Real y protected

Controller1 c1(u=e, enable=simple, reset=true); Controller2 c2(u=e, enable=not simple, reset=true); equation

y = if simple then c1.y else c2.y; end Controller;

Discrete Event and Discrete Time Models

The actions to be performed at events are specified by a when-statement.

when condition then equations

end when;

The equations are active instantaneously when the condition becomes true. It is possible to use a vector of conditions. In such a case the equations are active whenever any of the conditions becomes true.

Special actions can be performed when the simulation starts and when it finishes by testing the built-in predicates initial() and terminal( ). A special operator reinit(state, value) can be used to assign new values to the continuous states of a model at an event.

Let’s consider discrete time systems or sampled data systems. They are characterized by the ability to periodically sample continuous input variables, calculate new outputs influencing the continuous parts of the model and update discrete state variables. The output variables keep their values between the samplings. We need to be able to activate equations once every sampling. There is a built-in function sample(Start, Interval) that is true when time=Start + n*Interval, n>=0. A discrete first order state space model could then be written as

block DiscreteStateSpace

parameter Real a, b, c, d; parameter Real Period=1; input Real u;

discrete output Real y;

protected

discrete Real x;

equation

when sample(0, Period) then x = a*pre(x) + b*u;

y = c*pre(x) + d*u; end when;

end DiscreteStateSpace;

Note, that the special notation, pre(x), is used to denote the value of the discrete state variable x before the sampling.

In this case, the first sampling is performed when simulation starts. With Start > 0, there would not have been any equation defining x and y initially. All variables being defined by when-statements hold their values between the activation of the equations and have the value of their

(30)

start-attribute before the first sampling, i.e., they are discrete state variables and must have the variable prefix discrete.

For non-periodic sampling a somewhat more complex method for specifying the samplings would be used. The sequence of sampling instants could be calculated by the model itself and kept in a discrete state variable, say NextSampling. We would then like to activate a set of equations once when the condition time>= NextSampling becomes true. An alternative formulation of the above discrete system would thus be.

block DiscreteStateSpace2

parameter Real a, b, c, d; parameter Real Period=1; input Real u;

discrete output Real y;

protected

discrete Real x, NextSampling(start=0);

equation

when time >= pre(NextSampling) then x = a*pre(x) + b*u;

y = c*pre(x) + d*u;

NextSampling = time + Period; end when;

end DiscreteStateSpace2;

Indicator functions for efficient simulation

If the conditions used in if-the-else expressions contain relations with dynamic variables, the corresponding derivative function f might not be continuous and have as many continuous partial derivatives as required by the integration routine in order for efficient simulation. Modern

integrators have indicator functions for such discontinuous events. For a relation like v1 > v2, a proper indicator function is v1 - v2.

If the resulting if-then-else expression is smooth, the modeller should have the possibility to give this extra information to the integrator in order to avoid event handling and thus enhance

efficiency. This can be done by embedding the corresponding relation in a function noEvent as follows.

y = if noEvent(u > HighLimit) then HighLimit

else if noEvent(u < LowLimit) then LowLimit else u;

Iin some cases the event does not need to be triggered exactly when the condition becomes true. It might be sufficient to wait until the next step of the integration has been completed. Such events are sometimes called step events. An appropriate translator pragma for that would be to use a function switch(relation).

Synchronization and event propagation

Propagation of events can be done by the use of Boolean variables. A Boolean equation like

Out.Overflowing = Height > MaxLevel;

in a level sensor might define a Boolean variable, Overflowing, in an interface. Other components, like a pump controller might react on this by testing Overflowing in their

References

Related documents

• correlation and OLS regression • exploratory factor analysis (EFA) • dummy variable regression • confirmatory factor analysis (CFA) • logistic regression •

1 december 2015, The new Portuguese online gambling tax regime in a constitutional context. General income tax

For instance if a Building Construction Management Program is able to achieve high levels of satisfaction among first year students, there is likelihood that this will

The effect of 20 mg/kg dose of the Calligonum extract on antioxidant levels in ovarian tissue of PCO group showed the lowest concentration of antioxidant in

Merapi, 2001 and field interviews, (3) analyze the morphology of channel data to get the probability of lahars over flow in the study area, (4) construct the lahar flows

Mean hydroclimatic and hydrological conditions during two Mean hydroclimatic and hydrological conditions during two climatic modes in the Devils Lake Basin, North Dakota (USA)

The project will aim to integrate shared ICT infrastructure and services into management and provision of critical public utilities and services in rural and urban setting to