institutionen för datavetenskap - diva...

108
Institutionen för datavetenskap Department of Computer and Information Science Master Thesis A Template-Based Java Code Generator for OpenModelica and MetaModelica By Manokar Munisamy LIU-IDA/LITH-EX-A--14/022SE 2014-09-01

Upload: others

Post on 23-Jul-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

Institutionen för datavetenskap

Department of Computer and Information Science

Master Thesis

A Template-Based Java Code Generator

for OpenModelica and MetaModelica

By

Manokar Munisamy

LIU-IDA/LITH-EX-A--14/022—SE

2014-09-01

Page 2: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

Linköping University Department of Computer and Information Science

Master Thesis

A Template-Based Java Code Generator for

OpenModelica and MetaModelica

By

Manokar Munisamy

LIU-IDA/LITH-EX-A--14/022—SE

2014-09-01

Supervisor: Lena Buffoni (fd Olena Rogovchenko) Department of Computer and Information Science

Examiner: Peter Fritzson Department of Computer and Information Science

Page 3: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

Abstract The current OpenModelica Complier (OMC) translates Modelica models into executable C-

code through several stages. The Code Generator is the final stage of the compiler which

generates target C-code from the optimized sorted equations. Recently, the Code Generator in

OMC has been rewritten using the OpenModelica text template language. This gives a more

concise and easier to understand code generator. Modeling and simulation is becoming

increasingly used in several application areas. There is demand for the OpenModelica

Complier (OMC) to generate code in languages like C#, CSharp, XML, JAVA and so on. In

this thesis work, we implement a Java code generator to translate the internal equation-based

models in OpenModelica and its extension MetaModelica into a Java code representation. To

create the Java code generator we used the OpenModelica text template language, also called

Susan. This work is an important step on the way to finalize a full version of a Java Code

Generator for the OpenModelica Complier (OMC).

Page 4: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

4

Acknowledgments I take this opportunity to thank my examiner Prof. Peter Fritzson and my supervisor Dr. Olena

Rogovchenko for this thesis opportunity, and for guidance. I also thank my technical

supervisor Martin Sjölund and give special thanks to Prof. Hans Georg Schaathun from

høgskolen i Ålesund (Aalesund University College) for his continuous support through skype

meetings. Finally I thank my friends and family for their support.

Page 5: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

5

Contents Contents ................................................................................................................................................... 5

Chapter 1 .................................................................................................................................................. 7

Introduction .............................................................................................................................................. 7

1.1 Motivation ...................................................................................................................................... 7

1.2 Problem Statement ........................................................................................................................ 7

1.3 Goals ............................................................................................................................................... 8

1.4 Methodology .................................................................................................................................. 8

1.5 Intended Readers ........................................................................................................................... 8

1.6 Thesis Outline ................................................................................................................................. 9

Chapter 2 ................................................................................................................................................ 11

Background ............................................................................................................................................. 11

2.1 Modelica and OpenModelica ....................................................................................................... 11

2.2 OpenModelica Compiler Phases and Modules ............................................................................ 12

2.2.1. The OpenModelica Compiler Phases ................................................................................... 12

2.1.2 The OpenModelica Compiler Modules ................................................................................. 14

2.3 MetaModelica .............................................................................................................................. 15

2.4 Numerical Integration .................................................................................................................. 16

2.4.1 Introduction to Numerical Integration .................................................................................. 16

2.4.2 Euler Integration .................................................................................................................... 17

2.5 Event Handling ............................................................................................................................. 18

2.5.1 Events .................................................................................................................................... 18

2.5.2 Run-time Algorithm ............................................................................................................... 19

2.6 The Susan Template Language ..................................................................................................... 21

Chapter 3 ................................................................................................................................................ 23

Design and Implementation ................................................................................................................... 23

3.1 Java Code Generation ................................................................................................................... 23

3.1.1 Root Template ....................................................................................................................... 24

3.1.2 Java Specific File Template .................................................................................................... 24

3.1.3 simulationFileHeader Template ............................................................................................ 25

3.1.4 modelClassName Template ................................................................................................... 25

3.1.5 addGlobalInitialization Template .......................................................................................... 26

Page 6: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

6

3.1.6 modelClassConstructorTemplate ........................................................................................ 26

3.1.7 functionBoundParameters Template .................................................................................... 27

3.1.8 functionODE Template .......................................................................................................... 28

3.1.9 functionDAE Template .......................................................................................................... 29

3.1.10 functions Template ............................................................................................................. 30

3.1.11 mainFunction Template ...................................................................................................... 31

3.1.12 daeExp Template ................................................................................................................. 32

3.2 Java runtime system ..................................................................................................................... 33

3.2.1 SimModel .............................................................................................................................. 34

3.2.2 SimData ................................................................................................................................. 34

3.2.3 EulerSolver ............................................................................................................................ 35

Chapter 4 ................................................................................................................................................ 37

Testing .................................................................................................................................................... 37

4.1 Modelica Test Models .................................................................................................................. 37

4.1.1 Verification Test .................................................................................................................... 38

4.1.2 Performance Test .................................................................................................................. 38

4.2 Improvements from previous version .......................................................................................... 42

Chapter 5 ................................................................................................................................................ 45

Conclusion and Future Work .................................................................................................................. 45

5.1 Conclusion .................................................................................................................................... 45

5.2 Future Work ................................................................................................................................. 45

User Guide .......................................................................................................................................... 47

References .............................................................................................................................................. 49

Appendix ................................................................................................................................................ 51

A Sample Results ................................................................................................................................ 51

B Simulation Time ............................................................................................................................... 55

C Implementation code ...................................................................................................................... 59

Page 7: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

7

Chapter 1

Introduction

In this chapter, we provide an overview and motivation for this thesis work. We also explain

the methodology which we use to achieve our goals. In the next section, we have stated the

goals and problem statement in this chapter. Finally, we present the outline of this thesis

work.

1.1 Motivation In modern technology, modeling and simulation plays a vital role in many industries.

Industries need a multi domain modeling and simulation language and tool for their

application development such as: mechanical, robotics, automotive, aerospace, electrical,

hydraulic, control subsystems, process oriented applications and many more. Modelica is a

non-proprietary, object oriented, mathematical and equation based language. The Modelica

language is used for modeling and simulating the above mentioned applications/models.

OpenModelica is an open-source Modelica-based modeling and simulation environment

intended for industrial and academic usage. OpenModelica is growing fast and contains

different subsystems such as OMC, OMShell, OMNotebook, OMEdit, OMWeb, OMOptim,

MDT, ModelicaML, and OMPython.

The idea of creating this thesis work came from some users of OpenModelica, including

University of Ålesund, who are using the Java platform for software development and

simulation. They have a need for a simulator which is running as a Java application. Therefore

there is a need for OpenModelica to be able to generate Java code as an alternative to C code.

1.2 Problem Statement The OpenModelica Compiler, code generator has recently (two years ago) been rewritten

using the OpenModelica text template based language, Susan [2.6]. A previous master thesis

project developed a subset text template based code generator. This work extends that to cover

a larger part of the language, to create a Java Run-time that supports event handling, and to

also support code generation for MetaModelica to Java. Thus the first problem is that,

Page 8: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

8

Problem 1: How to implement a template based Java code generator for

OpenModelica and MetaModelica? After Java code is generated, we need a runtime system to simulate the model. Currently there

exists a C runtime system but now we also need a Java runtime system to simulate. Thus the

second problem is that,

Problem 2: How to implement a Java runtime system to simulate Java coded

models?

1.3 Goals The main goals of this thesis work are the following: To further develop a template based Java code generator for OpenModelica Complier

OMC.

o further develop a Java Runtime System to simulate the models.

To perform the example test cases that demonstrate the possibility of OMC to generate

Java code for Modelica models, and track the performance with other the

programming language.

1.4 Methodology The methodology used for the development of theTemplate Based Java code generator and

Java runtime system for OpenModelica is based upon:

Literature Study – A literature study is the basic for the initiation of this thesis work. The

OpenModelica project was studied as along with already existing code generation thesis

works made for different languages such as C, C++, C# and XML code generation, as well as

previous master thesis with limited code generation from Modelica to Java in OpenModelica.

Also, some publications and documentations on OpenModelica were studied which are

related to this thesis work. Taking part in Intense Modelica Course and OpenModelica

workshop helped to a large extent to learn more about the Modelica language.

Implementation – The implementation leads to obtain a deeper understanding about the

problems and its proposed solutions. The Java code generator and Java runtime system were

developed using Susan template language and Java respectively.

1.5 Intended Readers The intended readers of this thesis work are people with general idea in Modelica language,

Susan template language, OpenModelica modeling and simulation environment. However,

interested readers with basic knowledge of compiler construction and programming can

understand as well.

Page 9: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

9

1.6 Thesis Outline The rest of this thesis is organized as follows. Chapter 2: Background studies on the Modelica, OpenModelica, MetaModelica, complier

phases and modules, numerical integration for solver and Susan template

language. Chapter 3: Explains the design and implementation of Template Based Java Code

Generator and Java Runtime System for OpenModelica/MetaModelica. Chapter 4: Demonstrates the different test case and simulation to show the performance of

the implementation. Chapter 5: Concludes the thesis work and discussion of possible future work.

Page 10: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

10

Page 11: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

11

Chapter 2

Background

In this chapter, some theoretical background and technology needed for the implementation is

described. Initially, an overview of Modelica and OpenModelica for modeling and simulation

environment is given. In the section 2.2, an introduction to compiler construction and its

phases is described along with the modules of OMC. In the next section, the Run-time

algorithms for numerical integration and event handling are discussed. Finally, the Susan

template language is described which is used for the implementation of this thesis work.

2.1 Modelica and OpenModelica Modeling and simulation plays a vital role in many industries, because modeling and

simulation gives an overview of the actual system before it is implemented in the real world.

There are many modeling and simulation tools are available. In this thesis work, we focus in

OpenModelica and its extension MetaModelica.

Modelica is an object oriented and equation based language for modeling and simulation of

multi domain such as mechanical, electrical, hydraulic, control subsystems etc. The Modelica

Association is a non-profit organization which supports the development of the open standard

Modelica and the open source Modelica Standard Library.

The OpenModelica is an open source project for Modelica based modeling, compilation and

simulation environment. The major development of OpenModelica is done in Linköping

University, PELAB. OpenModelica is supported by non-profit organization, Open Source

Modelica Consortium (OSMC). There are many development is in under construction,

recently new version of OpenModelica1.9.0 beta 4 has been released including the different

tools as shown below in the figure 2.1.

Page 12: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

12

Figure 2.1: The overall architecture of the OpenModelica environment

An OpenModelica Compiler (OMC) –The OMC translates Modelica source code to an

executable C code for simulation. An interactive session handler (OMShell) – An OMShell provides a command

interface to OMC. The OpenModelica Notebook (OMNotebook) – OMNotebook gives a tutorial for

Modelica. In addition, Modelica models can be written and simulated on it. The OpenModelica Development Environment (OMDev) – The OMDev is a tool for

building OMC. A Modelica eclipse plugin (MDT-Modelica Development Tooling) – MDT is used for

Modelica development, code browsing, and simulation. Modelica Debugger – The Modelica debugger used for debugging an extended

algorithm subset of Modelica by using eclipse for displaying and positioning. Graphical model editor – The OpenModelica Connection Editor (OMEdit) is used for

graphical model editing, plotting and browsing of the Modelica standard library.

2.2 OpenModelica Compiler Phases and Modules

2.2.1. The OpenModelica Compiler Phases A Modelica Compiler - The OMC translates Modelica source code to executable C code for

simulation by several phases. In this section, we give a short description for every phase with

the help of OpenModelica compiler phases shown in figure 2.2.1 below.

Page 13: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

13

Figure 2.2.1: The OpenModelica compiler translation phases

Phases of compiler are as follows:

1. The first phase of the compiler is Scanner (input: symbols, output: tokens), which

produce tokens from the Modelica model symbols.

2. The second phase of the compiler is Parser (input: tokens, output: abstract syntax tree),

which translates the tokens to flattened model with list of variables, equation, function.

3. The Analyzer (input: abstract syntax tree, output: error messages, abstract syntax tree),

which is used for type checking, import statements, handling of inheritance,

modifications and all other object oriented operations are also performed in this

phase.

4. Optimization (input: abstract syntax tree, output: (optimized) abstract syntax tree),

which gives the Optimized sorted equation.

5. Code Generator is an important phase of the compiler (input: abstract syntax tree,

output: executable code). Code generation generates the final code (this is typically

architecture specific, one has to consider memory issues, etc.)

6. In the last phase of OMC, the code generator generates C code which is then pass to a

C compiler to produce executable code for simulation.

Page 14: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

14

Interested readers to know the detailed compiler phases are encouraged to go through the

“Compliers Principles, Techniques, & Tools” book[3].

2.1.2 The OpenModelica Compiler Modules The OMC has around 40 modules. The brief descriptions of each module can be found in the

OpenModelica system documentation and figure2.2.2a shown below for a quick reference.

Figure 2.2.2a: Module connections and data flows in the OMC

In this section, we will describe only the most important modules of OMC and its short

description, see also figure 2.2.2b below.

1. The parser generates Abstract Syntax (Absyn) which is then converted into a

simplified intermediate form (SCode).

2. The code instantiation module (Inst) calls Lookup to find a name in an environment. It

also generates the Differential Algebraic Equation (DAE) representation which is

simplified by DAELow.

3. The Ceval module performs compile time or interactive expression evaluation and

returns values.

4. The static module performs static semantic and type checking.

5. SimCode is the data structure for representing solved equation code which then can be

used to generate different target code in code generation phase.

Page 15: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

15

Figure 2.2.2b: The OpenModelica compiler most important modules

2.3 MetaModelica MetaModelica is a unified equation-based modeling language specifically designed for OMC

development. MetaModelica is an extended subset of Modelica used for the development of

OMC. There are some extended features such as local equations, pattern equations, match

expressions and high level data structures are matchcontinue, uniontype, list and the option

type.

The MetaModelica uniontype construct used to specify the type of each node in the AST. It

declares one or more record members. The structure of uniontype may be recursive (i.e., the

records are allowed to contain uniontype members). See the listing 2.3 for an example on how

to declare an expression uniontype of six record types.

uniontype Exp

record INT Integer value; end INT;

record ADD Exp lhs; Exp rhs; end ADD;

record SUB Exp lhs; Exp rhs; end SUB;

record MUL Exp lhs; Exp rhs; end MUL;

record DIV Exp lhs; Exp rhs; end DIV;

record NEG Exp exp1; end NEG;

end Exp;

Listing 2.3: Exp Abstract syntax definition using MetaModelica Uniontype constructs The AST representation of the expression 10+3*8 by using the Exp abstract syntax definition

is shown below in the Figure 2.3.

Page 16: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

16

ADD

INT MUL

10

INT INT

3 8

Figure 2.3: AST of 10+8*3 in the language Exp

See the listing 2.3.b for an example on how to declare a match constructs in MetaModelica.

function eval

input Exp in_exp;

output Real out_real;

algorithm

out_real := match in_exp

local Real v1,v2,v3; Exp e1,e2;

case RCONST(v1) then v1;

case ADD(e1,e2) equation

v1 = eval(e1); v2 = eval(e2); v3 = v1 + v2; then v3;

case SUB(e1,e2) equation

v1 = eval(e1); v2 = eval(e2); v3 = v1 - v2; then v3;

case MUL(e1,e2) equation

v1 = eval(e1); v2 = eval(e2); v3 = v1 * v2;then v3;

case DIV(e1,e2) equation

v1 = eval(e1); v2 = eval(e2); v3 = v1 / v2; then v3;

case NEG(e1) equation

v1 = eval(e1); v2 = -v1; then v2;

end match;

end eval;

Listing 2.3.b: MetaModelica match constructs

2.4 Numerical Integration

In this section, we explain the numerical integration procedure and methods used in this thesis

work to solve the ODE equations in solver.

2.4.1 Introduction to Numerical Integration

One of the inputs to the final code generation step, with the limited set of models used in this

thesis, is a set of explicit ODEs on the form:

x ' ( t )= f ( x( t ) , u( t ) ,t ) …. (2.1)

with initial conditions:

x ( t= t0)= x0 ….. (2.2)

Page 17: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

17

In equation (2.1) x is the state vector, u is the input vector, and t represents time. We are not

considering any input to our Modelica model while simulation so we may skip the u(t) part

from equation (2.2) and thus form a new equation (2.3). The new equation can be written as:

x ' ( t )= f ( x( t ) , t ) ….. (2.3)

Our task is to calculate the state vector x and derivative x' of these states of the specified time

t. We can get the value of state vector x by analytically calculating them one by one but is not

possible in all cases specially if there are many time stamps and multiple state variables. The

alternative is to use the numerical integration methods. By using the numerical integration

methods, we can get the approximated values. Although it is not always possible to get the

accurate results but approximated values very close to the accurate ones. The approximated

values can be calculated at any given point using Taylor-Series expansion for every element

of xi:

xi( t∗ +h )= x

i( t∗ )+

dxi ( t∗ )

dt.h+

d2xi( t∗ )

dt2

.h2

2 !+. .. …. (2.4)

By plugging in equation (2.3) we get:

xi( t∗ +h )= x

i( t∗ )+ f

i( t∗ ) .h+

df i( t∗ )

dt.h2

2 !+.. . …. (2.5)

2.4.2 Euler Integration

Euler integration is the first-order numerical procedure for solving ODEs. The Euler

integration algorithm is formed by taking only the linear part from the Taylor Series equation

(2.5), such as:

xi(t*+ h) ¿ xi(t*) + x'i(t*) . h ….(2.6)

We use the approximation sign here instead of the equal sign, this is because we are just

taking the linear part and ignoring the rest of the Taylor equation of (2.5). Now the above

equation (2.6) scheme is very simple comparatively to Taylor series equation (2.5) because it

doesn't hold any higher-order derivatives. We call this integration scheme Forward Euler

algorithm since this numerical integration algorithm depends only on the past values of states

and state derivatives unlike Backward Euler 3 [3].

Recall equation (2.2), with initial conditions, x(t = t0) = x0, we can write the rest of steps as

follows:

step 1a: x'(t0) = f(x(t0); t0)

step 1b: x(t0 + h) = x(t0) + h . x'(t0)

step 2a: x' (t0 + h) = f(x(t0 + h); t0 + h)

step 2b: x(t0 + 2h) = x(t0 + h) + h . x'(t0 + h)

Page 18: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

18

step 3a: x' (t0+ 2h) = f(x(t0 + 2h); t0 + 2h)

step 3b: x(t0 + 3h) = x(t0 + 2h) + h . x'(t0 + 2h)

x(t)

x'

time

t t+h

Figure 2.4: Numerical integration using the Forward Euler method.

Backward Euler integration scheme depends on past as well as current values of variables.

*Note this integration is not discussed in this thesis.

2.5 Event Handling In this section, we address about events and how we handle events in run-time system.

2.5.1 Events

An event (or discrete changes) is simply something that happens. Events are associated with a

point in time, state and conditional equation. The An Event in Modelica is something that

happens and has the following four properties: taken from [2 ]

A point in time that is instantaneous, i.e., has zero duration.

An event condition that switches from false to true for the event to happen.

A set of variables that are associated with the event, i.e., are referenced or explicitly

changed by equations associated with the event.

Some behavior associated with the event, expressed as conditional equations that

become active or are deactivated at the event. Instantaneous equations are special case

of conditional equations that are active only at events.

The short definitions of different events are given below:

Timed event: An event is triggered by time and the corresponding event-action takes place.

An example is shown below, when time >=10.0 then

event-action1;

end when;

State event: An event takes place in a particular state that triggers an action.

Conditional Event: An event takes place after satisfying a condition which triggers an action.

An example is shown below, when event-conditions then

Actual Value

Approximated Value

Page 19: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

19

event-action1;

event-action2;

end when;

2.5.2 Run-time Algorithm

The following flowchart is shown in the figure 2.5 gives an overview of how an event is

handled in the run time system. The each and every step of the flowchart is described below.

First of all the simulation must be initialized consistently. By use of the initial conditions the

initial values for the entire system can be determined. This will also execute all initial events

at time .

After the initialization the main simulation loop starts with the continuous integration step that

calculates the states and state derivatives with its size value. With the new values of states and

state derivatives, the functions “Solver and CSVBuilder” can be evaluated. Thus, the entire

continuous system is determined.

The continuous integration step is accepted if no event has occurred then the values can be

saved and the next step can be performed. If an event has occurred then the value of condition

changes, an event occurred within the interval and . Then the exact time has to be

detected.

The continuous part is evaluated at the time just before the event and all values are saved to

provide them to the pre() operator. Then the entire system is evaluated by the functions again.

At this point the event is handled and the further events are handling by loop.

The main simulation loop will repeat until it reaches the end time. This helps us to get the

simulation time for Run-time system.

Page 20: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

20

Figure 2.5: Schematic Flowchart for Run-time System.

Page 21: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

21

2.6 The Susan Template Language In this section, we explain the Susan template language which is used in implementation of

Java code generator. Susan is a functional, strongly typed, expression oriented template

language which is specifically designed for OMC with the following main advantages are: Increases readability

Compiled to reach maximum performance

Provides a full vehicle for different target code generation such as C++, Java, C# etc...

Susan template expressions can consists of conditional expressions, match-expressions,

function calls, iterator expressions, and etc. For more expressions and its complete description

refer the Susan template guide. The match expression in the template language is used for

distinction of AST structure nodes declared in MetaModelica union types. See the listing 2.6

for an example of how pattern matching against a tree structure of figure 2.6.

ADD

INT MUL

10

INT INT

3 8

Figure 2.6: AST of 10+8*3 in the language Exp template exp(Exp inExp) ::=

match inExp

case INT(__) then value

case ADD(__) then '<%exp(lhs)%> + <%exp(rhs)%>'

case SUB(__) then '<%exp(lhs)%> - <%exp(rhs)%>'

case MULT(__) then '<%exp(lhs)%> * <%exp(rhs)%>'

case DIV(__) then '<%exp(lhs)%> / <%exp(rhs)%>'

case NEG(__) then '- <%exp(exp1)%> '

end exp;

Listing 2.6: Template “exp” - Pattern matching example

The template function exp is recursive. The scope of the INT constructor is automatically

opened by using INT(__) pattern to make its field (i.e., value) available, and the ADD, SUB,

MUL, DIV and NEG constructors are opened automatically by using the ADD(__), SUB(__),

Page 22: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

22

MUL(__), DIV(__) and NEG(__) pattern respectively.

Page 23: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

23

Chapter 3

Design and Implementation

This chapter describes the design and implementation of this thesis work. Initially, we present

the process of Java code generator design and implementation in OMC. Secondly, we present

the process of Java runtime system design and implementation for simulation.

3.1 Java Code Generation To design a Java code generator with the basic block diagram as shown in Figure 3.1a. Java

code generator takes the input as Modelica model and process in the generator to produce an

output as Java code corresponding to the Modelica model.

Input Output

Figure 3.1a: Block diagram for Java code generator

Code generator generates the Java code from the modelica model though OMC. The block

diagram for OpenModelica Compiler for Java Code Generation is shown in the figure 3.1b.

below. Code generator is depends directly on the SimCode’s solved equations (SimCodeTV).

So, the SimCodeTV module is important to understand, SimCodeTV is data structure for

solved equations. SimCodeTV contains many data structure representation, but in this section

we describe only some data structure.

DAELow

Solved Equations

Java Code

Figure 3.1b: Block diagram for OpenModelica Compiler for Java Code Generation

Modelica Model

OMC Front End

SimCodeTV

Code Generator

Simulation

Modelica Model

(testmodel.mo)

Java Code

Generator

Java Coded Model

(testmodel.Java)

Page 24: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

24

Java code generation is implemented by passing the correct data structure into SimCodeTV

data structure as function template in Susan template language. The main functions of Java

code generation templates are described in the following sections.

3.1.1 Root Template

Root template is top level of code generation, it generates java file which is also a target file

can be used for simulation in Java Runtime System. It also consists of main function which is

“simulationFile(simCode)” as shown below in the listing 3.1.1.

Listing 3.1.1: Root template for Java Code generation

3.1.2 Java Specific File Template

In this section, we are going to elaborate more on the main funtion

“simulationFile(simCode)”. This main template function consists of set of templates which is

used to generate a Java file as complete Java executable file. The file consists of necessary

packages, class declaration, variable declarations, constructor, functions, external functions

and main class declaration. The main template “simulationFile(simCode)” is defined as shown

below in the listing 3.1.2.

template translateModel(SimCode simCode)

"Generates Java code and Makefile for compiling and running a

simulation of a Modelica model."

::=

match simCode

case SIMCODE(modelInfo=modelInfo as MODELINFO(__)) then

let()= textFile(simulationFile(simCode),

'<%fileNamePrefix%>.java')

"" //empty result for true case

//this top-level template always returns an empty result

//since generated texts are written to files directly

end translateModel;

template simulationFile(SimCode simCode)

"Generates code for main Java file for simulation target."

::=

match simCode

case SIMCODE(modelInfo = MODELINFO(__)) then

<<

<%simulationFileHeader(simCode)%>

<%modelClassName(simCode)%>

<%addGlobalInitialization(modelInfo, simCode)%>

<%modelClassConstructor(simCode)%>

<%functionInput(modelInfo, simCode)%>

<%functionOutput(modelInfo, simCode)%>

<%functionBoundParameters(parameterEquations, simCode)%>

<%functionODE(odeEquations, simCode)%>

<%functionDAE(allEquations, whenClauses, relations, simCode)%>

<%functions(modelInfo.functions, recordDecls, simCode)%>

<%mainFunction(simCode)%>

>>

end simulationFile;

Page 25: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

25

Listing 3.1.2: Main temaple for Java specific file in Java Code generation

3.1.3 simulationFileHeader Template

This Java code generation template is responsible for importing the necessary packages,

which are used in the Java file, as header for the Java file. The header template is shown

below in the listing 3.1.3., and an example is shown in the Listing 3.1.4a.

Listing 3.1.3: simulationFileHeader template for Java Code generation

3.1.4 modelClassName Template

This Java code generation template corresponds to the model class declaration and initializing

Data object with necessary parameters. In this model class declaration template, declares

class name as model name, number of states, output file name and initializing a new SimData

as data object. As shown below in the listing 3.1.4.

Listing 3.1.4: modelClassName template for Java Code generation

Example 1: Representation of simulationFileHeader and modelClassName declaration are

shown in the listing 3.1.4b., for the below model is shown in the listing 3.1.4a.

In the below model “AddReal.mo”, consists of two algebraic parameters and an algebraic

template simulationFileHeader(SimCode simCode)

"Generates header part of simulation file."

::=

match simCode

case SIMCODE(modelInfo=MODELINFO(__), extObjInfo=EXTOBJINFO(__)) then

<<

package CodegenJava; // solver package name

import java.io.IOException;

import java.math.*;

import java.lang.Thread.State;

import java.util.Vector;

>>

end simulationFileHeader;

template modelClassName(SimCode simCode)

"Generates model class name of simulation file."

::=

match simCode

case SIMCODE(modelInfo=MODELINFO(varInfo = vi as VARINFO(__)),

extObjInfo=EXTOBJINFO(__)) then

let noOfstates = if vi.numAlgVars then vi.numAlgVars else vi.numStateVars

<<

/* Simulation code for <%dotPath(modelInfo.name)%> generated by the

OpenModelica Compiler <%getVersionNr()%>.*/

@SuppressWarnings("unused")

public class <%dotPath(modelInfo.name)%> extends SuperModel // name of

the given model

{

static int n= <%noOfstates%>; // n --> number of states

static String filename = "<%dotPath(modelInfo.name)%>_result.txt";

/* Simulation output file */

public static SimData localData = new SimData(n, 0, 0); /*

Initializing a Data Object*/

>>

end modelClassName;

Page 26: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

26

variables. It also consists of an ODEs equation with an external function called addReal1_.

Listing 3.1.4a. Model AddReal1.mo

Listing 3.1.4b:Example of simulationFileHeader and modelClassName declaration

3.1.5 addGlobalInitialization Template

This Java code generation template corresponds to the initialization of global variables and

parameters. In this template, we declare algebraic variable parameter lists such as variables,

parameters, integer variables, integer parameters, string variables, string parameters and

external objects under separate subsections in order to easy understand for the users. The

example is shown in the listing 3.1.6a.

3.1.6 modelClassConstructorTemplate

This Java code generation template corresponds to the declaration of a constructor. In this

template, the generation of class constructor with the state initialization as in model or set as

default for the equations. The example is shown in the listing 3.1.6a.

Example 2: Representation of global initialization and constructor as shown in the listing

3.1.6a. for the model “AddReal.mo” mentioned in listing 3.1.4a.

package CodegenJava; // solver package name

import java.io.IOException;

import java.math.*;

import java.lang.Thread.State;

import java.util.Vector;

/* Simulation code for AddReal1 generated by the OpenModelica Compiler

1.9.0 beta4+dev (r16707).*/

@SuppressWarnings("unused")

public class AddReal1 extends SuperModel /* name of the given model */

{

static int n= 1; // n --> number of states

static String filename = "AddReal1_result.txt"; /* Simulation output

file */

public static SimData localData = new SimData(n, 0, 0); /*

Initializing a Data Object */

model AddReal1

parameter Real a=2.3;

parameter Real b=4.5;

Real c;

equation

c = addReal1_(a, b);

end AddReal1;

/* Algebraic Vars */

double c[] = new double [1]; /* c */

/* Algebraic Parameter */

double a = 2.3; /* a */

double b = 4.5; /* b */

public AddReal1() // constructor

{

/* States Initialization Ordinary equations */

localData.x/*state*/.add(0,0.0); /* $dummy */

/* States Initialization algebraic equations */

localData.x/*state*/.add(0,0.0); /* c */

}

simulationFileHeader

GlobalInitialization

Page 27: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

27

Listing 3.1.6a:Example of global initialization and constructor for AddReal1.mo

3.1.7 functionBoundParameters Template

In this function BoundParameters, the parameters for state algebraic equations are bounded

with corresponding state derivatives. This function is being called in functionODE,

functionDAE to update the algebraic equations. The parameter equations are either

“SES_SIMPLE_ASSIGN” or “SES_ALGORITHM” defined as shown below in the listing 3.1.7.

Listing 3.1.7: functionBoundParameters Template for Java code generation

Example 3: Representation of bound parameter is shown in the listing 3.1.7b. for the below

model “EquationFor6.mo”. In this model, there are three algebraic variables with three simple

algebraic equations respectively and shown in the listing 3.1.7a.

Listing 3.1.7a: EquationFor6.mo

template functionBoundParameters(list<SimEqSystem> parameterEquations,

SimCode simCode)

::=

let &tmp = buffer ""

<<

public void BoundParameters()

{

<% parameterEquations

|> saeq as SES_SIMPLE_ASSIGN(__) => equation_(saeq, contextOther,

simCode, &tmp) ;separator="\n"%>

<% parameterEquations

|> eq as SES_ALGORITHM(__) => equation_(eq, contextOther, simCode,

&tmp) ;separator="\n"%>

}

>>

end functionBoundParameters;

class EquationFor6

Real a[3];

equation

for i loop

a[i] = i;

end for;

end EquationFor6;

// Result:

// class EquationFor6

// Real a[1];

// Real a[2];

// Real a[3];

// equation

// a[1] = 1.0;

// a[2] = 2.0;

// a[3] = 3.0;

// end EquationFor6;

// endResult

Flattened Model

Page 28: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

28

Listing 3.1.7b:Example of bound parameter function for EquationFor6.mo

3.1.8 functionODE Template

This Java code generation template is an important function for the simulation. In this

template, only the “statecontEquations” implemented. If the model consists of ordinary

differential equation then the corresponding “equation_” will be executed. The “equation_”

template is the root template for the entire equations such as SES_SIMPLE_ASSIGN,

SES_ARRAY_CALL_ASSIGN, SES_ALGORITHM, SES_WHEN. StatesAssign template is useful

for declaring the variables locally. Finally “BoundParameters” function will be called to

update the changes in stateDerivative if any. The functionODE template is defined as shown

in the listing 3.1.8 and its representation of functionODE is shown in the listing 3.1.9a. for

“BouncingBall.mo” model.

Listing 3.1.8: functionODE Template for Java code generation

public void BoundParameters()

{

localData.xdot /*stateDerivative*/.add(0,1.0); //a[1] = 1.0; localData.xdot /*stateDerivative*/.add(1,2.0); //a[2] = 2.0; localData.xdot /*stateDerivative*/.add(2,3.0); //a[3] = 3.0; }

template functionODE(list<list<SimEqSystem>> stateContEquations, SimCode

simCode)

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(varInfo=VARINFO(numStateVars=numStateVars), vars=SIMVARS(__)))

then

match modelInfo

case MODELINFO(varInfo=VARINFO(numStateVars=numStateVars),

vars=SIMVARS(__)) then

let &tmp = buffer ""

<<

public void functionODE()

{

<%StatesAssign("states", vars.stateVars, simCode)

;separator="\n"%>

<%StatesAssign("states", vars.algVars, simCode)

;separator="\n"%>

<%stateContEquations |> eqs =>

(eqs |> it => equation_(it, contextOther, simCode, &tmp)

;separator="\n")

;separator="\n"%>

BoundParameters();

}

>>

end functionODE;

Page 29: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

29

3.1.9 functionDAE Template

In this template, all type of equations with when-clauses is implemented. For every equation,

the corresponding “equation_” will be executed. StatesAssign template is useful for

declaration of variables locally. The functionDAE template is defined as shown in the listing

3.1.9 and its representation of functionDAE is shown in the listing 3.1.9a. for

“BouncingBall.mo” model.

Listing 3.1.9: functionDAE Template for Java code generation

Example 4: Representation of functionODE and functionDAE are shown in the listing 3.1.9b.

for the “BouncingBall.mo” as shown in listing 3.1.9a. This model contains two basic

equations and when equation as discrete issues suitable for functionODE and functionDAE.

Listing 3.1.9a: BouncingBall.mo

model BouncingBall "The bouncing ball model"

constant Real g = 9.81; // Gravitational acceleration

parameter Real c = 0.9; // Elasticity constant of ball

parameter Real radius = 0.1; // Radius of the ball

Real height(start = 1); // height above ground of the ball center

Real velocity(start = 0); // Velocity of the ball

equation

der(height) = velocity;

der(velocity) = -g;

when height <= radius then

reinit(velocity, -c*pre(velocity));

end when;

end BouncingBall;

template functionDAE(list<SimEqSystem> allEquationsPlusWhen,

list<SimWhenClause> whenClauses, list<ZeroCrossing> relations,

SimCode simCode)

"Generates function in simulation file."

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(varInfo=VARINFO(numStateVars=numStateVars), vars=SIMVARS(__)))

then

match modelInfo

case MODELINFO(varInfo=VARINFO(numStateVars=numStateVars),

vars=SIMVARS(__)) then

let &varDecls = buffer "" /*BUFD*/

let &tmp = buffer ""

<<

public void functionDAE()

{

<%StatesAssign("states", vars.stateVars, simCode)

;separator="\n"%>

<%StatesAssign("states", vars.algVars, simCode) ;separator="\n"%>

<%allEquationsPlusWhen |> eq => equation_(eq,

contextSimulationDiscrete, simCode, &tmp)

;separator="\n"%>

<%whenClauses |> when hasindex i0 => genreinits(when, relations,

contextOther, &varDecls, simCode)

;separator="\n"

%>

}

>>

end functionDAE;

Page 30: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

30

Listing 3.1.9b:Example of functionODE and functionDAE for BouncingBall.mo

3.1.10 functions Template

In this template, Java code generation for user defined functions and external functions. The

root template for this “functionJava” is “functions” template which contains the list of

functions “list<Function>”. This template is the root for the following templates such as

user defined functions, external functions and the record constructor. The “functionJava”

template is defined as shown in the listing 3.1.10.

Listing 3.1.10: Functions and external functions Template for Java code generation

Example 5: Representation of external function is shown in the listing 3.1.10a. for the

“AddReal.mo” model, which consists of a ODEs equation with an external function called

“addReal1_” in C language.

public void functionODE()

{

double velocity = localData.getState().elementAt(0);

double height = localData.getState().elementAt(1);

localData.xdot.add(0,-9.81);

localData.xdot.add(1,velocity);

BoundParameters();

}

public void functionDAE()

{

double velocity = localData.getState().elementAt(0);

double height = localData.getState().elementAt(1);

localData.xdot.add(0,-9.81);

localData.xdot.add(1,velocity);

//(height <= radius) "Condition Relation"

if (height <= radius)

{

velocity = ((-c) * velocity);

}

}

template functionJava(Function fn, list<RecordDeclaration> recordDecls,

SimCode simCode)

"Generates the body for a function."

::=

match fn

case fn as FUNCTION(__) then regularFunction(fn, simCode)

case fn as EXTERNAL_FUNCTION(__) then externalFunction(fn, simCode)

case fn as RECORD_CONSTRUCTOR(__) then recordsJava(recordDecls)

end functionJava;

Page 31: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

31

AddReal1.mo

Listing 3.1.10a:Example of external functions for AddReal1.mo

3.1.11 mainFunction Template

This Java code generation template corresponds to the main class declaration and invokes the

EulerSolver with correct parameters. It is shown below in the listing 3.1.11.

Listing 3.1.11: mainfunction Template for Java code generation

Example 9: Representation of main function for the class model is shown in the listing

3.1.11a. for the AddReal1.mo.

template mainFunction(SimCode simCode)

::=

match simCode

case SIMCODE(modelInfo = MODELINFO(__)) then

<<

public static void main(String[] args) throws IOException

{

<%dotPath(modelInfo.name)%> temp = new

<%dotPath(modelInfo.name)%>();

temp.functionODE();

/* Invoke the Solver with correct parameters */

EulerSolver.main(localData.stepsize, localData, temp, filename);

}

}

>>

end mainFunction;

function addReal1_

input Real x;

input Real y;

output Real res;

external "C";

end addReal1_;

model AddReal1

parameter Real a=2.3;

parameter Real b=4.5;

Real c;

equation

c = addReal1_(a, b);

end AddReal1;

public void BoundParameters()

{

/*Function Call*/

localData.xdot/*stateDerivative*/.add(0, addReal1__(a,b));

}

public double addReal1__(double arg_x , double arg_y) /*Function*/

{

double res;

double x = arg_x;

double y = arg_y;

return res = addReal1_(x,y); /*externalFunction*/

}

Page 32: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

32

Listing 3.1.11a:Example of global initialization and constructor for AddReal1.mo

3.1.12 daeExp Template

This Java code generation template is the root template for all the expressions. The

expressions which are used in models are flattened, and those expressions “exp” match the

corresponding case in this template in order to translate into a Java code. This template is

defined below in the listing 3.1.12.

Listing 3.1.12:daeExp template for Java code generation

public static void main(String[] args) throws IOException

{

AddReal1 temp = new AddReal1();

temp.functionODE();

/* Invoke the Solver with correct parameters */

EulerSolver.main(localData.stepsize, localData, temp, filename);

}

template daeExp(Exp exp, Context context, Text &preExp /*BUFP*/, SimCode

simCode)

"Generates code for an expression."

::=

match exp

case e as ICONST(__) then integer

case e as RCONST(__) then real

case e as SCONST(__) then daeExpSconst(string, context,

&preExp /*BUFC*/, simCode)

case e as BCONST(__) then if bool then "true" else "false"

case e as ENUM_LITERAL(__) then index

case e as CREF(__) then daeExpCrefRhs(e, context, &preExp,

simCode)

case e as BINARY(__) then daeExpBinary(e, context, &preExp

/*BUFC*/, simCode)

case e as UNARY(__) then daeExpUnary(e, context, &preExp

/*BUFC*/, simCode)

/**************************** Some code removed here ***************

*******************************************************************/

case e as CAST(__) then daeExpCast(e, context, &preExp

/*BUFC*/, simCode)

case e as ASUB(__) then daeExpAsub(e, context, &preExp

/*BUFC*/, simCode)

case e as TSUB(__) then '<%daeExp(exp, context, &preExp,

simCode)%>'

case e as SIZE(__) then daeExpSize(e, context, &preExp

/*BUFC*/, simCode)

case e as BOX(__) then daeExpBox(e, context, &preExp

/*BUFC*/, simCode)

case e as UNBOX(__) then daeExpUnbox(e, context, &preExp

/*BUFC*/, simCode)

case e as SHARED_LITERAL(__) then '_OMC_LIT<%index%>'

// META_TUPLE

// META_OPTION

// METARECORDCALL

else error(sourceInfo(), 'Unknown expression:

<%ExpressionDump.printExpStr(exp)%>')

end daeExp;

Page 33: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

33

The interested readers who wants to know more about Java code generator implemention are

welcome to go though the full implemention code in the section “Appendix B Implementation

code”.

3.2 Java runtime system

Java Runtime System takes the java files as input and returns the simulation results to verify

the model. Runtime system is needed for every specific programming language. The block

diagram for Java Runtime System is shown below in the Figure 3.2a.

Input Output

Figure 3.2a: Block diagram for Java Runtime System

The class diagram for Java Runtime System is shown below in the Figure 3.2b, and consists

of

SimModel – Java coded model which is generated from Java code generator.

SimData – The dynamic data for a simulation at a given time.

Solver: Euler's method for numerical integration.

Super Model – This is the superclass for any model class generated from Modelica.

Static Model – A ModelicaModel with its static information.

Modelica Variable –Static information about a single variable in the model.

Modelica Equation: A single equation in the Modelica model.

Figure 3.2b: Class Diagram for Java Runtime System

Java coded model

(testmodel.Java)

Java Runtime

System

Simulation test

results

Super Model

SimModel

(testmodel.Java)

EulerSolver

Modelica Variable

SimData

Static Model Modelica Equation

testmodel_result.txt

Output

Page 34: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

34

The description of the class diagram and its implementation is discussed in the following

sections.

3.2.1 SimModel

The SimModel is a Java coded model which is generated by using Java code generator for the

corresponding modelica model. The Java code model contains the packages, class declaration,

variable declaration, class constructor, functions, external functions and the main class

declaration.

The sample Java code for modelica models are given in the section “Appendix A” for some

test models.

3.2.2 SimData

SimData class is being initialized by the model class declaration object in SimModel. After

the initialization, this class is ready for simulation at a given time. This class contains the

values of state and state derivative in appropriate format for the solver. The state and state

derivatives are initialize as Vector type as Double for better efficiency for runtime system.

This class also contains default simulation settings. This SimData implementation is shown in

the listing 3.2.1.

package jrt;

import java.util.*;

import org.jscience.physics.amount.* ;

import javax.measure.quantity.* ;

/*** @author [email protected]***/

public class SimData {

double time ;

int size;

double start;

double stepsize;

double stop;

/* Initialize as Vector type as Double*/

Vector<Double> x = new Vector<Double>();

Vector<Double> xdot = new Vector<Double>() ;

public SimData( int xdim, int mdim, int zdim ) {

// simulation default settings

size = xdim;

start = 0.0;

stepsize = 0.002;

stop = 1.0;

}

/*** Advance to next time step, advancing time by dt.***/

public void advance( double dt )

{

time = time+dt;

}

/*** Get the continuous state vector ***/

public Vector<Double> getState()

{

return x ;

}

************************ to be continued

Page 35: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

35

Listing 3.2.1:SimData for Java Runtime System

3.2.3 EulerSolver

Java runtime system uses Euler's numerical integration method. The EulerSolver main class is

invoked by SimModel’s main-function with necessary parameters. By using those parameters,

the solver main class initializes the output result file (testmodel_result.txt). And the values of

state and state derivative values by using SimData object.

In the main simulation loop, the solver function and CSVBuilder function is being called for

simulate the model. The function Solver() takes the appropriate parameters in order to do the

numerical integration. There are two main operations in the Solver function, one is the setting

of state values in the size loop. And the other is the function-call of functionODE ().

The state vectors are compute by using below equation:

states[i] = states[i] + statesDerivatives[i] * (step);

This method is implemented and shown in the listing 3.2.2. This function helps to get the state

and statesDerivatives values which is set for the operations and generates the output result file

by using CSVBuilder function.

Finally there is an small calculation for simulation time for the model. The outline of the code

for time stamp is given below.

// for time measurement

long startSimulationTime = System.currentTimeMillis();

// simulation loop

// end simulation time measurements

long endSimulationTime = System.currentTimeMillis();

// simulation time calculation

System.out.println("Simulation took: " + (endSimulationTime -

startSimulationTime)+ " milliseconds.\n");

/*** Get the continuous state derivative vector.***/

public Vector<Double> getDer()

{

return xdot ;

}

/*** Get current time.***/

public double getTime()

{

return time ;

}

/*** Set the continuous state vector and update time.***/

public void updateState( Vector<Double> x )

{

this.x = x ;

}

}

Page 36: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

36

Listing 3.2.2: Solver Function of EulerSolver.Java for Java Runtime System

For EulerSolver, SuperModel, StaticModel and it’s ModelicaEquation, Modelica Variable.

The interested readers who wants to know more about Java Runtime System implemention are

welcome to go though the full implemention code in section “Appendix C Java Runtime

System”.

public static void Solver( SimData data ,SuperModel model, double dt )

throws IOException

{

Vector<Double> x = data.getState() ;

Vector<Double> xdot = data.getDer() ;

for(int i=0;i<x.size();i++)

{

x.set(i, x.get(i)+ xdot.get(i)*dt);

}

data.advance( dt ) ;

model.functionODE();

}

Page 37: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

37

Chapter 4

Testing

In this chapter, we provide different test cases conducted to test the implementation of the

thesis work.

4.1 Modelica Test Models

We have tested around 250 test case models and all the models were successfully generated.

We have taken almost all the types of Modelica language constructs from the OpenModelica

test suite. The listing.4 shown below is the general description of subset from the

OpenModelica test suite. The detailed listing is shown in “Appendix B” with the model name

and its simulation time for both Java Runtime System and C Runtime System.

Test Cases Section Description

38 algorithms-

functions

In this section, we have tested all type of Algorithms and

functions such as inline function, function call, function

evaluations.

56 array In this section, we have tested for Arrays, array

declarations, array operations such as array addition,

division, multiplication, subtraction, xpowers, and etc,.

37 built-in-functions In this section, we have generated Java code for the built-

in-functions which are Acos, Asin, Atan, Cos, Cosh, Log,

Log10, Sqrt, Sin, Sinh, Sign, Tan, Tanh, Transpose, Ceil

and etc,.

9 declarations In this section, we perform to test the Constant

declarations, DeclarationEquations.

32 Equations In this section, we have tested all type of equations with

When, for, if condition equations and some hybrid

models which is taken from book [2].

23 extends In this section, Some extends models like Colors,

Moonlanding, Multiplex, StepAdvanced and some more

models are tested.

Page 38: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

38

7 external-functions In this section, we have tested the different external

functions for instance AddReal1, ExternalFunctionArray,

ExternalFunctionBuiltin, etc.

13 records In this section, we have tested record construct of

Modelica language such as RecordAssignment,

RecordConstants, and RecordVariability.

30 MetaModelica

models

In this section, we have tested all type MetaModelica

such as List, match, partialfunction and uniontype.

Listing 4: Modelica Test Models

In this section, we have chosen one model from OpenModelica and another model from

MetaModelica to showcase the implementation of Java code generator and its Java Runtime

system works fine. The verification and performance test methods are used for testing the

generated models.

4.1.1 Verification Test

The following method is used to verify the test results:

Generate the simulation output for both C Runtime System (testmodel_res.csv)

and Java Runtime System (testmodel_resJava.csv).

By executing the file Script.mos, a graph is generated. We can verify the model using

this graph.

Script.mos

4.1.2 Performance Test

The following method is used for testing the performance of models:

By executing the file Script_table.mos, a table is generated. The table consists of

model name and its simulation time.

The flag “+s +simCodeTarget=Java” is used for Java Runtime System. The flag “+s

+simCodeTarget=C” is used for C Runtime System.

By using these tables, we can compare the simulation time of models for both C

Runtime System and Java Runtime System.

html := diffSimulationResultsHtml("/*any one attribute*/ ",

"testmodel_res.csv", "testmodel_resJava.csv");

writeFile("b.html",html);getErrorString();

system("cp " + getInstallationDirectoryPath() +

"/share/doc/omc/testmodels/dygraph-combined.js .");

system("chromium-browser b.html &");

Page 39: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

39

Script_table.mos

Model 1: BouncingBall.mo:

The BouncingBall model contains the two basic equations of motion relating height and

velocity as well as the acceleration caused by the gravitational force. At the bounce instant the

velocity is suddenly reversed and slightly decreased, i.e.,veclocity(after bounce) = -

c*veclocity(before bounce), which is accomplished by the special reinit synatactic form.. This

model suitable for functionODE and functionDAE. This model is a good example of a hybrid

system for which the when-equation is appropriate when modeled. And this discrete model

handles the event handling. The full Java code generation of this model is given in section

“Appendix A”.

Verification Test:

Figure 4.1.1a: Graph for BouncingBall.mo

mofiles := {"testmodel1.mo", "testmodel2.mo"};

system("rm -f log.csv");

{writeFile(file + ".mos", "

loadFile(\""+file+"\");

names:=getClassNames();

name:=names[1];

res:=simulate(name);

t:=res.timeSimulation;

writeFile(\"log.txt\",typeNameString(name) + \",\"

+ String(t) + \"\\n\",append=true);

") for file in mofiles};

{runScript(file + ".mos") for file in mofiles};

Page 40: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

40

From this graph, we can conclude that the projection of BouncingBall for both JCG and CCG

are almost same. Thus the model is successfully generated using JCG and simulated using

JRS.

Performance Test:

Simulation Time For: C Runtime System Java Runtime System

BouncingBall.mo 0.0156448 seconds 0.0209959 seconds

The following model is an example of MetaModelica.

Model 2: PartialFn12.mo

This model consists of an equation section with the function call of TestFn(x). This function

section has another function call. The full Java code generation of this model is given in the

section “Appendix A”. partial function PartFn

input Real x;

output Real y;

end PartFn;

function FullFn

extends PartFn;

input Real extraReal1;

input Real extraReal2;

algorithm

y := x * ((extraReal1 + extraReal2) / 2.0);

end FullFn;

function CallerFn

input Real inReal;

input PartFn inPartFn;

output Real outReal;

algorithm

outReal := inPartFn(inReal) * 2.0;

end CallerFn;

function TestFn

input Real inReal;

output Real outReal;

algorithm

outReal := 0;

for i in 1:10 loop

outReal := outReal + CallerFn(inReal, function FullFn(1.5,7.5));

end for;

end TestFn;

model PartialFn12

Real x;

Real y;

equation

x = 2.0;

y = TestFn(x);

end PartialFn12;

Page 41: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

41

Verification Test:

Figure 4.1.1b: Graph for PartialFn12.mo

From this graph, we can conclude that the projection of PartialFn for both JCG and CCG are

almost same. Thus the model is successfully generated using JCG and simulated using JRS.

Performance Test:

Simulation Time For: C Runtime System Java Runtime System

PartialFn12.mo 0.0099915 seconds 0.00943867 seconds

The following bar chart shows the performance of models in JRS and CRS. The performance

of Java Runtime System varies from C Runtime System, because C code executes more

directly on the hardware platform whereas Java runs on a JVM. Thus the C compiler compiles

the code directly into the machine code while the Java compiler compiles into the byte code

which is understandable by JVM. Due to this, Java Runtime System takes more time to

execute than C Runtime System. In contrast for some models, Java Runtime System executes

in lesser time than C Run time System.

Page 42: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

42

Figure 4.1: Bar Chart Graph for Equations Subset

4.2 Improvements from previous version

When we started this thesis work, we used the thesis report of “Template-Based Java Code

Generator and Java Runtime System for OpenModelica” by Inam Ul Haq. A. As the

development of “Template-Based Java Code Generator” began from his thesis work and listed

below the improvements made in this thesis work.

Design:

We started the design of Java Code Generator and Java Runtime System in order to get better

efficiency, and to handle hybrid models such as event handling, external functions, records

and MetaModelica constructs. With the help of Prof. Hans Georg Schaathun, the new design

of Java Runtime System is created and the detailed class diagram is given in the chapter 3.

Implementation: Java Code Generator

We have implemented the Java Code Generator for the whole Openmodelica and

Metamodelica constructs. The previous version of the Java Code Generator did not cover the

following features:

Algebraic loops

Hybrid Models (Event Handling)

Algebraic Arrays

External functions

Records

MetaModelica constructs such as match, List and PartialFunctions.

Page 43: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

43

But, we have implemented the complete Java Code Generator for the entire Modelica

constructs, which are not supported in the previous version.

Java Runtime System:

The OpenModelica has changed a lot during the period of two years and this leads to some

changes in simCodeTv. As we mentioned before, simCodeTv contains all the data structures

which are required for the code generation. So the previous version of Java Code Generator

and Java Runtime System does not support the latest version of Openmodelica. Therefore we

couldn’t use the previous version of Java Runtime System anymore. This leads to the new

design of Java Runtime System based on the previous version. We have implemented the

complete Java Runtime System which supports the latest version of Java Code Generator.

Testing:

We have used the script files for verification testing and performance testing, which were not

used in the previous version. It is used to test the group of models which makes the testing

process easier and efficient. The produced results are very accurate and clear, which is used to

compare the simulation time of Java Runtime System with C Runtime System. We have used

a total of 250 test cases which are passed successfully, from which we can conclude that the

entire Modelica constructs are covered. The previous version does not cover the entire

Modelica constructs.

Page 44: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

44

Page 45: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

45

Chapter 5

Conclusion and Future Work

This chapter concludes the work conducted in this thesis work and discussion the possible

directions for future work.

5.1 Conclusion

In this thesis work, we have implemented an extended version of the previous subset Java

Code Generator by using Susan template based language. We have tested around 250 test

cases which cover almost all types of Modelica language constructs. This code generation will

be helpful to open the OpenModelica Java code generator to a wide range of users both

academic and commercial.

5.2 Future Work

The current version of SimCodeTv is unstable and the Java Code Generation is fully

dependent on the SimCodeTv. If the SimCodeTv is modified in future then the Java Code

Generation will be interrupted. Thus in order to support the Java Code Generation, a stable

SimCodeTv can be implemented.

Another task for future work is to implement a Click-on button in OMEdit which makes

exporting models to an Java format from OpenModelica straightforward for users. To

implement a click-on button in OMEdit.

Page 46: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

46

Page 47: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

47

User Guide 1. Install OpenModelica Compiler. Follow the instructions found in

https://www.openmodelica.org/index.php/developer/source-code

2. Compiling a model and generate Java code

The following step compiles a model to a Java code generation.

- Open the mingw terminal if you are a windows user and normal terminal for linux user

- In the terminal window go to the path where your model file found(C:/<%path to .mo

file%>).

- Go to omc path (<%path to omc%>/omc) and write the flag +s +simCodeTarget=Java

<%your.mo file%>.mo>

This is demonstrated in the following example, where +s +simCodeTarget=Java is the flag

specific for Java code generation and Circle.mo is the model name.

Once compilation has completed successfully a Java file will have been generated and can be

found in the same directory as your model found.

Page 48: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

48

Page 49: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

49

References

[1] OpenModelica project. https://www.openmodelica.org/

[2] TDDB44 Compiler Construction course http://www.ida.liu.se/~TDDB44/index.en.shtml.

[3] The OpenModelica source code. Available from

https://openmodelica.org/svn/OpenModelica/trunk/Compiler/Template/ User name:

anonymous, Password: none

Books:

[4] Peter Fritzson. Principles of Object-Oriented Modeling and Simulation with Modelica,

Wiley-IEEE Press, 2003.

[5] Alfred V.Aho, Monica S.Lam, Ravi Sethi, Jeffrey D.Ullman. Compilers Principles,

Techniques, & Tools, Second Edition, Addison Wesley, 2006.

[6] David J. Barnes, Michael Kölling. Objects First with Java, third edition, Pearson

Education Limited, 2006.

Technical reports:

[7] Peter Fritzson, Pavol Privitzer Adrian Pop, and Martin Sjölund. Towards a Text

Generation Template Language for Modelica. Technical report in Computer and

Information Science, Linköping University Electronic Press, September 2009.

[8] Peter Fritzson, Adrian Pop, and Martin Sjölund. Towards Modelica 4 Meta-

Programming and Language Modeling with MetaModelica 2.0, Technical report in

Computer and Information Science, Linköping University Electronic Press, May 2011.

[9] Peter Fritzson, Adrian Pop, and Martin Sjölund. Meta-Programming and Language

Modeling with MetaModelica 1.0, Technical report in Computer and Information

Science, Linköping University Electronic Press, March 2011.

[10] Peter Fritzson. Modelica Text Template Language Susan Users Guide v0.2,

Technical report in Linköping University, PELAB - Programming Environment

Laboratory, April 2010.

Thesis:

[11] Inam Ul Haq. A Template-Based Java Code Generator and Java Runtime System

for OpenModelica. Master's thesis, PELAB, Linköping University, Department of

Computer and Information Science, August 2011.

[12] Rickard Lindberg. A Template-Based Code Generator for the OpenModelica

Compiler. Master's thesis, PELAB, Linköping University, Department of Computer

and Information Science, March 2010.

[13] Martin Sjölund. Bidirectional external function interface between

Modelica/MetaModelica and Java. Master's thesis, PELAB, Linköping University,

Department of Computer and Information Science, August 2009.

Page 50: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

50

Page 51: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

51

Appendix

A Sample Results

Model 1: BouncingBall.Java

package CodegenJava; // solver package name

import java.io.IOException;

import java.math.*;

import java.lang.Thread.State;

import java.util.Vector;

// Simulation code for BouncingBall generated by the OpenModelica Compiler 1.9.1+dev

(RML version).

@SuppressWarnings("unused")

public class BouncingBall extends SuperModel // name of the given model

{

static int n= 2; // n --> number of states

static String filename = "BouncingBall_result.txt"; // Simulation output file

public static SimData localData = new SimData(n, 0, 0); // Initializing a Data Object

/* Algebraic Vars */

/* Algebraic Parameter */

double c = 0.9; /* c */

double radius = 0.1; /* radius */

/* External Objects */

/* Algebraic Integer Vars */

/* Algebraic Integer Parameter */

/* Algebraic String Variables */

/* Algebraic String Parameter */

public BouncingBall() // constructor

{

/* States */

/* States Initialization Ordinary equations */

localData.x/*state*/.add(0,0.0); /* velocity */

localData.x/*state*/.add(1,1.0); /* height */

/* States Initialization algebraic equations */

}

public void InputFun()

{

}

public void OutputFun()

{

}

Page 52: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

52

public void BoundParameters()

{

}

public void functionODE()

{

double velocity = localData.getState().elementAt(0);

double height = localData.getState().elementAt(1);

localData.xdot/*stateDerivative*/.add(0,-9.81);

localData.xdot/*stateDerivative*/.add(1,velocity);

BoundParameters();

}

public void functionDAE()

{

double velocity = localData.getState().elementAt(0);

double height = localData.getState().elementAt(1);

localData.xdot/*stateDerivative*/.add(0,-9.81);

localData.xdot/*stateDerivative*/.add(1,velocity);

//(height <= radius) "Condition Relation"

if (height <= radius) {

velocity = ((-c) * velocity);

}

}

public static void main(String[] args) throws IOException

{

BouncingBall temp = new BouncingBall();

temp.functionODE();

/* Invoke the Solver with correct parameters */

EulerSolver.main(localData.stepsize, localData, temp, filename);

}

}

Model 2: PartialFn12.Java

package jrt; // solver package name

import java.io.IOException;

import java.math.*;

import java.lang.Thread.State;

import java.util.Vector;

// Simulation code for PartialFn12 generated by the OpenModelica Compiler 1.9.1+dev (RML

version).

@SuppressWarnings("unused")

public class PartialFn12 extends SuperModel // name of the given model

{

Page 53: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

53

static int n= 2; // n --> number of states

static String filename = "PartialFn12_result.txt"; // Simulation output file

public static SimData localData = new SimData(n, 0, 0); // Initializing a Data Object

/* Algebraic Vars */

double y[] = new double [2]; /* y */

double x[] = new double [2]; /* x */

/* Algebraic Parameter */

/* External Objects */

/* Algebraic Integer Vars */

/* Algebraic Integer Parameter */

/* Algebraic String Variables */

/* Algebraic String Parameter */

public PartialFn12() // constructor

{

/* States */

/* States Initialization Ordinary equations */

localData.x/*state*/.add(0,0.0); /* $dummy */

/* States Initialization algebraic equations */

localData.x/*state*/.add(0,0.0); /* y */

localData.x/*state*/.add(1,0.0); /* x */

}

public void InputFun()

{

}

public void OutputFun()

{

}

public void BoundParameters()

{

localData.xdot/*stateDerivative*/.add(0, TestFn(2.0));

localData.xdot/*stateDerivative*/.add(1,2.0);

}

public void functionODE()

{

double $dummy = localData.getState().elementAt(0);

double y = localData.getState().elementAt(0);

double x = localData.getState().elementAt(1);

localData.xdot/*stateDerivative*/.add(0,0.0);

BoundParameters();

}

public void functionDAE()

{

double $dummy = localData.getState().elementAt(0);

Page 54: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

54

double y = localData.getState().elementAt(0);

double x = localData.getState().elementAt(1);

localData.xdot/*stateDerivative*/.add(0,0.0);

BoundParameters();

}

public double CallerFn__FullFn(double arg_inReal , double arg_FullFn_extraReal1 ,

double arg_FullFn_extraReal2)

{

double outReal;

double inReal = arg_inReal;

double FullFn_extraReal1 = arg_FullFn_extraReal1;

double FullFn_extraReal2 = arg_FullFn_extraReal2;

return outReal = (2.0 * FullFn(inReal,FullFn_extraReal1,FullFn_extraReal2));

}

public double TestFn(double arg_inReal)

{

double outReal;

double inReal = arg_inReal;

outReal = 0.0;

/*algStmtForRange_impl*/

for ( int i = 1; i<=10; i++) {

outReal = (outReal + CallerFn__FullFn(inReal,1.5,7.5));

}

return outReal;

}

public double FullFn(double arg_x , double arg_extraReal1 , double arg_extraReal2)

{

double y;

double x = arg_x;

double extraReal1 = arg_extraReal1;

double extraReal2 = arg_extraReal2;

return y = (0.5 * (x * (extraReal1 + extraReal2)));

}

public static void main(String[] args) throws IOException

{

PartialFn12 temp = new PartialFn12();

temp.functionODE();

/* Invoke the Solver with correct parameters */

EulerSolver.main(localData.stepsize, localData, temp, filename);

}

}

Page 55: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

55

B Simulation Time Number

of Model

Model Name Simulation Time in Seconds

C Runtime Java Runtime

1 Modelica.Electrical.Analog.Examples. HeatingRectifier

0.043 0.066

2 Modelica.Mechanics.MultiBody.Examples. Loops.Engine1b

1. .305 1.440

3 Modelica.Mechanics.MultiBody.Examples. Elementary.DoublePendulum

0.458 0.476

4 While 0.000913 0.001231

5 WhenPriority 0.000744 0.000697

6 Vectorizable 0.000684 0.001647

7 Inline5 0.000774 0.000999

8 Inline1 0.000685 0.001759

9 FunctionMultiReturn 0.000623 0.002259

10 FunctionEvalBuiltin 0.001012 0.001245

11 FunctionEval12 0.00069 0.000886

12 FunctionEval11 0.000672 0.002041

13 FunctionEval8 0.000724 0.001088

14 FunctionEval7 0.00072 0.001785

15 FunctionEval6 0.000721 0.001488

16 FunctionEval4 0.000851 0.001054

17 FunctionEval3 0.001149 0.001078

18 FunctionEval2 0.000673 0.001425

19 FunctionEval1 0.000807 0.00105

20 FunctionDefaultArgs 0.000671 0.001474

21 FunctionCall 0.000669 0.001073

22 FunctionBreak 0.001807 0.002823

23 ForSimple 0.000902 0.001026

24 ForNested 0.001667 0.001824

25 AssignmentSimple 0.000799 0.000864

26 AssignmentFunctionMultiple1 0.001236 0.001008

27 AssignmentFunction 0.000705 0.001258

28 AlgorithmSection 0.00076 0.001488

29 AlgorithmFor6 0.002617 0.003154

30 AlgorithmFor5 0.001025 0.001147

31 AlgorithmFor4 0.000868 0.001043

32 AlgorithmFor3 0.000894 0.001179

33 AlgorithmFor2 0.000899 0.002716

34 AlgorithmFor1 0.001115 0.001598

35 AlgorithmElseOpt 0.00074 0.001271

36 Algorithm3 0.000932 0.001674

37 RangeVector 0.001737 0.003289

Page 56: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

56

38 Range2 0.001852 0.002721

39 Range1 0.001714 0.002401

40 MatrixPow 0.001471 0.002456

41 MatrixMulVector 0.003418 0.002966

42 Matrix 0.001984 0.003071

43 MatrixBrackets 0.001499 0.002849

44 Matrix2 0.001545 0.003127

45 DoubleWhenSequential 0.001629 0.002651

46 DimSize 0.001747 0.002353

47 ConcatArr2 0.001444 0.003627

48 ConcatArr1 0.00156 0.002214

49 Concat3 0.00167 0.003687

50 ArraySubtraction 0.001425 0.003377

51 ArrayRemoveIndex1 0.006831 0.007187

52 ArrayReduce 0.001483 0.00226

53 ArrayRange 0.001846 0.002216

54 ArrayOperators 0.001357 0.002122

55 ArrayMult 0.001831 0.002142

56 ArrayMultiplication 0.002168 0.00285

57 ArrayIndex2 0.003867 0.005009

58 ArrayEWOpsCEval5 0.002086 0.0022

59 ArrayEWOpsCEval3 0.001619 0.002309

60 ArrayEWOpsCEval2 0.001557 0.002164

61 ArrayEWOpsCEval1 0.002038 0.002416

62 ArrayDiv 0.001476 0.002279

63 ArrayDivision 0.001671 0.002481

64 ArrayDeclaration5 0.001747 0.002857

65 ArrayDeclaration3 0.001599 0.002976

66 ArrayDeclaration2 0.002314 0.003164

67 ArrayDeclaration1 0.001601 0.002998

68 ArrayCurlyBrackets 0.001612 0.001962

69 ArrayCall 0.002993 0.003126

70 ArrayBrackets 0.001435 0.002717

71 ArrayAlgebraFunc 0.002027 0.002299

72 ArrayAddition2 0.0014 0.002495

73 ArrayAddition 0.001577 0.002162

74 ArrayAccess 0.002277 0.001788

75 Array15 0.001368 0.002331

76 Array14 0.001464 0.003175

77 Array13 0.001621 0.002115

78 Array12 0.001533 0.002288

79 Array11 0.001647 0.002135

80 Array10 0.001493 0.002073

81 Array7 0.001338 0.002123

Page 57: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

57

82 Array4 0.001407 0.002087

83 Array2 0.001486 0.002566

84 Array1 0.001384 0.002231

85 AppendElement 0.001911 0.002455

86 VectorTest 0.001372 0.002313

87 Vectorizable4 0.000776 0.001493

88 VectorDimension 0.00105 0.001064

89 VectorBuiltin 0.000847 0.001103

90 TrigIdentity 0.000941 0.000926

91 Transpose 0.000747 0.000814

92 Tanh 0.000919 0.001522

93 Tan 0.001441 0.002182

94 Sqrt 0.000706 0.000812

95 Skew 0.001304 0.001585

96 Sinh 0.001204 0.001623

97 Sin 0.000725 0.001887

98 Sign 0.000703 0.000984

99 Scalar 0.001143 0.001301

100 Rem 0.000667 0.001051

101 NumericFunctions 0.000625 0.000997

102 Mod 0.000776 0.00089

103 MathematicalFunctions 0.001145 0.00119

104 Log10 0.001052 0.002078

105 Log 0.00066 0.001557

106 Integer2Real 0.000979 0.002087

107 Floor 0.001059 0.001394

108 Exp 0.001282 0.001528

109 EventFunctions 0.000753 0.001594

110 Div 0.00074 0.001099

111 DerConstant2 0.001247 0.002308

112 DerConstant1 0.000808 0.001011

113 Cosh 0.000734 0.001175

114 Cos 0.0008 0.000873

115 Ceil 0.000762 0.001774

116 Atan2 0.000893 0.001587

117 Atan 0.000688 0.002341

118 Asin 0.000995 0.001963

119 Acos 0.000846 0.001355

120 Abs 0.001115 0.00224

121 ScopeModification1 0.001688 0.002314

122 ScopeDeclaration1 0.001863 0.002317

123 SimpleIntegrator2 0.001126 0.001186

124 SimpleIntegrator1 0.001013 0.000851

125 ScalarizeBindings 0.000767 0.001005

Page 58: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

58

126 ParameterDeclType 0.000856 0.001922

127 OutputDeclType 0.000704 0.000884

128 MyPointsInst1 0.000638 0.001436

129 InvalidReplaceableExtends1 0.001327 0.002327

130 Extends10 0.002555 0.002764

131 Extends1 0.001456 0.003532

132 AccessDemo 0.001901 0.003175

133 ExternalFunctionExtends 0.000518 0.001275

134 ExternalFunctionBuiltin 0.002863 0.004088

135 ExternalFunctionArray 0.001985 0.002829

136 ExternalFunction7 0.001359 0.0036

137 ExternalFunction6 0.002475 0.002124

138 ExternalFunction4 0.001578 0.003376

139 RecordAssignment 0.000681 0.000889

140 RecordPrefixes 0.000677 0.002173

141 RecordConnections 0.000746 0.002114

142 RecordConstructors2 0.000681 0.001402

143 RecordConstructors 0.000856 0.00218

144 RecordConstant3 0.000947 0.002262

145 RecordConstant1 0.012791 0.013145

146 Derived1 0.000658 0.001871

147 PartialFn12 0.000554 0.000895

148 PartialFn11 0.000469 0.001492

149 WhenSet 0.00052 0.0012

150 WhenSemantics1 0.00058 0.00148

151 WhenValidResult 0.00046 0.00244

152 WhenEquation 0.00056 0.00268

153 WaveEquationSample 0.00096 0.00555

154 VanDerPol 0.00044 0.001

155 TwoRateSampler 0.00102 0.00217

156 Sampler 0.00051 0.00117

157 LotkaVolterra 0.00045 0.00191

158 InitialReduction 0.00058 0.00104

159 IfEquation 0.00106 0.00148

160 HideVariableForEquations 0.00063 0.00084

161 HelloWorld 0.00041 0.00107

162 FiveForEquations 0.0004 0.00088

163 Equations 0.00046 0.00309

164 EquationIf4 0.00042 0.00386

165 EquationIf3 0.00056 0.00145

166 EquationIf2 0.00062 0.00093

167 EquationIf1 0.00043 0.00134

168 EquationFor7 0.00042 0.00258

169 EquationFor6 0.00047 0.00088

Page 59: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

59

170 EquationFor3 0.00097 0.00088

171 EquationFor2 0.00086 0.00089

172 EquationFor1 0.00043 0.00087

173 EqualityEquationsCorrect 0.00052 0.00152

174 Epidemics1 0.00059 0.00127

175 DAEexample 0.00604 0.00408

176 ConditionalArrayExpression2 0.00094 0.00173

177 Circle 0.00046 0.00115

178 BouncingBall 0.00093 0.00154

179 Activate 0.00051 0.00106

C Implementation code

Java Code Generation

CodegenJava.tpl

package CodegenJava

import interface SimCodeTV;

import CodegenUtil.*;

/********************* SECTION:

SIMULATION TARGET: ROOT

TEMLPATE

**********************************

******/

template translateModel(SimCode

simCode)

"Generates Java code and Makefile for

compiling and running a simulation of a

Modelica model."

::=

match simCode

case SIMCODE(modelInfo=modelInfo as

MODELINFO(__)) then

let()= textFile(simulationFile(simCode),

'<%fileNamePrefix%>.java')

"" //empty result for true case

//this top-level template always returns

an empty result

//since generated texts are written to files

directly

end translateModel;

/************************ SECTION:

SIMULATION TARGET, Java FILE

SPECIFIC TEMPLATES

************************/

template simulationFile(SimCode

simCode)

"Generates code for main Java file for

simulation target."

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(__)) then

<<

<%simulationFileHeader(simCode)%>

<%modelClassName(simCode)%>

<%addGlobalInitialization(modelInfo,

simCode)%>

<%modelClassConstructor(simCode)%>

<%functionInput(modelInfo,

simCode)%>

<%functionOutput(modelInfo,

simCode)%>

<%functionBoundParameters(parameterEq

uations, simCode)%>

<%functionODE(odeEquations,

simCode)%>

<%functionDAE(allEquations,

whenClauses, relations, simCode)%>

<%functions(modelInfo.functions,

recordDecls, simCode)%>

<%mainFunction(simCode)%>

>>

Page 60: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

60

end simulationFile;

/************************ SECTION:

SIMULATION TARGET, JAVA FILE

SPECIFIC FUNCTION TEMPLATES

************************/

template simulationFileHeader(SimCode

simCode)

"Generates header part of simulation file."

::=

match simCode

case

SIMCODE(modelInfo=MODELINFO(__),

extObjInfo=EXTOBJINFO(__)) then

<<

package CodegenJava; // solver package

name

import java.io.IOException;

import java.math.*;

import java.lang.Thread.State;

import java.util.Vector;

>>

end simulationFileHeader;

template modelClassName(SimCode

simCode)

"Generates model class name of

simulation file."

::=

match simCode

case

SIMCODE(modelInfo=MODELINFO(varI

nfo = vi as VARINFO(__)),

extObjInfo=EXTOBJINFO(__)) then

let noOfstates = if vi.numAlgVars then

vi.numAlgVars else vi.numStateVars

<<

// Simulation code for

<%dotPath(modelInfo.name)%> generated

by the OpenModelica Compiler

<%getVersionNr()%>.

@SuppressWarnings("unused")

public class

<%dotPath(modelInfo.name)%> extends

SuperModel // name of the given model

{

static int n= <%noOfstates%>; // n

--> number of states

static String filename =

"<%dotPath(modelInfo.name)%>_result.tx

t"; // Simulation output file

public static SimData localData =

new SimData(n, 0, 0); // Initializing a Data

Object

>>

end modelClassName;

// SECTION: GENERAL TEMPLATES,

PATHS

template dotPath(Path path)

"Generates paths with components

separated by dots."

::=

match path

case QUALIFIED(__) then

'<%name%>.<%dotPath(path)%>'

case IDENT(__) then name

case FULLYQUALIFIED(__) then

dotPath(path)

end dotPath;

template

addGlobalInitialization(ModelInfo

modelInfo, SimCode simCode)

"Generates global data in simulation file."

::=

match modelInfo

case MODELINFO(varInfo= vi as

VARINFO(numAlgVars=numAlgVars,

numStringAlgVars=numStringAlgVars ),

vars=SIMVARS(__)) then

<<

/* Algebraic Vars */

<%vars.algVars |> var =>

globalDataVarDefine(var, "realVars",

numAlgVars, simCode)

;separator="\n"%>

/* Algebraic Parameter */

<%vars.paramVars |> var =>

globalDataParDefine(var,

"realParameter", simCode)

;separator="\n"%>

/* External Objects */

<%vars.extObjVars |> var =>

Page 61: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

61

globalDataParDefine(var, "extObjs",

simCode)

;separator="\n"%>

/* Algebraic Integer Vars */

<%vars.intAlgVars |> var =>

globalDataDefineInt(var,

"integerVars",numAlgVars, simCode)

;separator="\n"%>

/* Algebraic Integer Parameter */

<%vars.intParamVars |> var =>

globalDataDefineInt(var,

"integerParameter",numAlgVars,

simCode)

;separator="\n"%>

/* Algebraic String Variables */

<%vars.stringAlgVars |> var =>

globalDataVarDefine(var,

"stringVars",numStringAlgVars, simCode)

;separator="\n"%>

/* Algebraic String Parameter */

<%vars.stringParamVars |> var =>

globalDataParDefine(var,

"stringParameter", simCode)

;separator="\n"%>

>>

end addGlobalInitialization;

template globalDataVarDefine(SimVar

simVar, String arrayName, Integer offset,

SimCode simCode)

"Generates a define statement for a

variable in the global data section."

//if varsLst then

//we need all of them to initialize also

empty arrays

::=

match simVar

case SIMVAR(__) then

<<

<%\t%> <%VariableType (type_)%>

<%qualifiedNamePart(name)%>[] = new

<%VariableType (type_)%>

[<%offset%>]; /* <%cref(name)%> */

>>

end match

end globalDataVarDefine;

template

qualifiedNamePart(ComponentRef cr)

"Generates Qualified name of a variable .

"

::=

match cr

case CREF_IDENT(__) then

<<

<%ident%>

>>

else "CREF_NOT_IDENT_OR_QUAL"

end qualifiedNamePart;

template globalDataParDefine(SimVar

simVar, String arrayName, SimCode

simCode)

"Generates a define statement for a

parameter."

::=

match simVar

case SIMVAR(__) then

<<

<%\t%><%VariableType (type_)%>

<%cref(name)%>

<%initialEquation(simVar, simCode)%>;

/* <%cref(name)%> */

>>

end match

end globalDataParDefine;

template globalDataDefineInt(SimVar

simVar, String arrayName, Integer offset,

SimCode simCode)

"Generates a define statement for a

variable in the global data section."

::=

match simVar

case SIMVAR(__) then

<<

<%\t%>int <%cref(name)%>

<%initialEquation(simVar, simCode)%>;

/* <%cref(name)%> */

>>

end match

end globalDataDefineInt;

template initVals(Option<DAE.Exp>

initialValue)

::=

match initialValue

case SOME(v) then

Page 62: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

62

<<

initVal(v)

else " "

>>

end initVals;

template initVal(Exp initialValue)

::=

match initialValue

case ICONST(__) then integer

case RCONST(__) then real

case SCONST(__) then

'<%Util.escapeModelicaStringToCString(s

tring)%>'

case BCONST(__) then if bool then

"true" else "false"

case ENUM_LITERAL(__) then

'<%index%>

/*ENUM:<%dotPath(name)%>*/'

else "error(sourceInfo(), 'initial value of

unknown type:

<%printExpStr(initialValue)%>')"

end initVal;

template VariableType(DAE.Type type_)

"Generates Java code for ScalarVariable

Type file."

::=

match type_

case T_INTEGER(__) then 'double'

/*need to cast int to double to support

SimData*/

case T_REAL(__) then 'double'

case T_BOOL(__) then 'boolean'

case T_STRING(__) then 'String'

case T_ENUMERATION(__) then

'double'

else 'UNKOWN_TYPE'

end VariableType;

template initialEquation(SimVar var,

SimCode simCode)

"Generates Java code for Inititial

Equations."

::=

match var

case SIMVAR(__) then

let identName = '<%cref(name)%>'

match initialValue

case SOME(exp) then

let &varDecls = buffer "" /*BUFD*/

let &preExp = buffer "" /*BUFD*/

<<

= <%daeExp(exp, contextOther,

&preExp, simCode)%>

>>

else " "

end initialEquation;

/************************ Class

constructor for the model

*****************/

template modelClassConstructor(SimCode

simCode)

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(__)) then

<<

public <%dotPath(modelInfo.name)%>() //

constructor

{

<%assignGlobalData(modelInfo,

simCode)%>

}

>>

end modelClassConstructor;

template assignGlobalData(ModelInfo

modelInfo, SimCode simCode)

"Generates global data in simulation file."

::=

match modelInfo

case

MODELINFO(varInfo=VARINFO(numSt

ateVars=numStateVars, numAlgVars=

numAlgVars), vars=SIMVARS(__)) then

<<

/* States */

/* States Initialization Ordinary

equations */

<%VarsAssign("state", vars.stateVars,

simCode)

;separator="\n"%>

Page 63: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

63

/* States Initialization algebraic

equations */

<%VarsAssign("state", vars.algVars,

simCode)

;separator="\n"%>

>>

end assignGlobalData;

template VarsAssign(String arrName,

list<SimVar> varsLst, SimCode simCode)

::=

<<

<%varsLst |> sv as SIMVAR(__) =>

<<

localData.x/*<%arrName%>*/.add

(<%sv.index%>,<%initialEquationStates(s

v, simCode)%>); /* <%cref(name)%> */

>>

;separator="\n"

%>

>>

end VarsAssign;

template initialEquationStates(SimVar var,

SimCode simCode)

"Generates Java code for Inititial

Equations."

::=

match var

case SIMVAR(__) then

let identName = '<%cref(name)%>'

match initialValue

case SOME(exp) then

let &varDecls = buffer "" /*BUFD*/

let &preExp = buffer "" /*BUFD*/

<<

<%daeExp(exp, contextOther,

&preExp, simCode)%>

>>

else "0.0"

end initialEquationStates;

/******************************

Template for Functions starts

****************************/

template functionInput(ModelInfo

modelInfo, SimCode simCode) ::=

match modelInfo

case MODELINFO(varInfo =

VARINFO(__), vars = SIMVARS(__))

then

<<

public void InputFun()

{

<%vars.inputVars |> SIMVAR(__)

hasindex i0 =>

<<

<%cref(name)%> =

inputVars[<%i0%>];

>> ;separator="\n"%>

}

>>

end functionInput;

template functionOutput(ModelInfo

modelInfo, SimCode simCode) ::=

match modelInfo

case MODELINFO(varInfo =

VARINFO(__), vars = SIMVARS(__))

then

<<

public void OutputFun()

{

<%vars.outputVars |>

SIMVAR(__) hasindex i0 =>

<<

outputVars[<%i0%>] =

<%cref(name)%>;

>> ;separator="\n"%>

}

>>

end functionOutput;

template

functionBoundParameters(list<SimEqSyst

em> parameterEquations, SimCode

simCode)

::=

let &tmp = buffer ""

<<

public void BoundParameters()

{

<% parameterEquations

Page 64: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

64

|> saeq as SES_SIMPLE_ASSIGN(__)

=> equation_(saeq, contextOther,

simCode, &tmp) ;separator="\n"%>

<% parameterEquations

|> eq as SES_ALGORITHM(__) =>

equation_(eq, contextOther, simCode,

&tmp) ;separator="\n"%>

}

>>

end functionBoundParameters;

template

functionODE(list<list<SimEqSystem>>

stateContEquations, SimCode simCode)

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(varInfo=VARINFO(numSt

ateVars=numStateVars),

vars=SIMVARS(__))) then

match modelInfo

case

MODELINFO(varInfo=VARINFO(numSt

ateVars=numStateVars),

vars=SIMVARS(__)) then

let &tmp = buffer ""

<<

public void functionODE()

{

<%StatesAssign("states",

vars.stateVars, simCode)

;separator="\n"%>

<%StatesAssign("states",

vars.algVars, simCode)

;separator="\n"%>

<%stateContEquations |> eqs =>

(eqs |> it => equation_(it, contextOther,

simCode, &tmp) ;separator="\n")

;separator="\n"%>

BoundParameters();

}

>>

end functionODE;

template

functionDAE(list<SimEqSystem>

allEquationsPlusWhen,

list<SimWhenClause> whenClauses,

list<ZeroCrossing> relations,

SimCode simCode)

"Generates function in simulation file."

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(varInfo=VARINFO(numSt

ateVars=numStateVars),

vars=SIMVARS(__))) then

match modelInfo

case

MODELINFO(varInfo=VARINFO(numSt

ateVars=numStateVars),

vars=SIMVARS(__)) then

let &varDecls = buffer "" /*BUFD*/

let &tmp = buffer ""

<<

public void functionDAE()

{

<%StatesAssign("states",

vars.stateVars, simCode)

;separator="\n"%>

<%StatesAssign("states",

vars.algVars, simCode) ;separator="\n"%>

<%allEquationsPlusWhen |> eq =>

equation_(eq, contextSimulationDiscrete,

simCode, &tmp)

;separator="\n"%>

<%whenClauses |> when hasindex

i0 => genreinits(when, relations,

contextOther, &varDecls, simCode)

;separator="\n"

%>

}

>>

end functionDAE;

template StatesAssign(String arrName,

list<SimVar> varsLst, SimCode simCode)

"Helper template for assigning states in

functionODE and functionDAE"

::=

<<

<%varsLst |> sv as SIMVAR(__) =>

<<

<%VariableType (type_)%>

<%cref(name)%> =

localData.getState().elementAt(<%sv.inde

x%>);

>>

Page 65: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

65

;separator="\n"

%>

>>

end StatesAssign;

template mainFunction(SimCode

simCode)

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(__)) then

<<

public static void main(String[] args)

throws IOException

{

<%dotPath(modelInfo.name)%>

temp = new

<%dotPath(modelInfo.name)%>();

temp.functionODE();

/* Invoke the Solver with correct

parameters */

EulerSolver.main(localData.stepsiz

e, localData, temp, filename);

}

}

>>

end mainFunction;

/********************* SECTION:

TEMPLATES WHICH SUPPORT Java

FILE SPECIFIC FUNCTION

TEMPLATES

**********************************/

template functions(list<Function>

functions, list<RecordDeclaration>

recordDecls, SimCode simCode)

"Generates the body for a function."

::=

<<

<%functions |> fn =>

functionJava(fn, recordDecls, simCode)

;separator="\n"%>

>>

end functions;

template functionJava(Function fn,

list<RecordDeclaration> recordDecls,

SimCode simCode)

"Generates the body for a function."

::=

match fn

case fn as FUNCTION(__) then

regularFunction(fn, simCode)

case fn as EXTERNAL_FUNCTION(__)

then externalFunction(fn, simCode)

case fn as

RECORD_CONSTRUCTOR(__) then

recordsJava(recordDecls)

end functionJava;

template regularFunction(Function fn,

SimCode simCode)

"Generates JAVA code for a Modelica

function."

::=

match fn

case FUNCTION(__) then

let fname = underscorePath(name)

let &varDecls = buffer "" /*BUFD*/

let extFunCall = (body |> stmt =>

funStatement(stmt, simCode)

;separator="\n")

<<

public <%outVars |> var =>

funArgDefinitiontype(var)%>

<%fname%>(<%functionArguments |> var

=> funArgDefinitionarg(var) ;separator=" ,

"%>)

{

<%outVars |> var =>

funOutputVariable(var) ;separator="\n"%>

<%functionArguments |> var =>

funArgDefinition(var) ;separator="\n"%>

return <%extFunCall%>

}

>>

end regularFunction;

template externalFunction(Function fn,

SimCode simCode)

"Generates the body for an external

function (just a wrapper)."

::=

match fn

Page 66: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

66

case EXTERNAL_FUNCTION(__) then

let &preExp = buffer "" /*BUFD*/

let fname = underscorePath(name)

let &varDecls = buffer "" /*BUFD*/

let callPart = extFunCall(fn, &preExp

/*BUFC*/, simCode)

<<

public <%outVars |> var =>

funArgDefinitiontype(var)%>

<%fname%>(<%funArgs |> var =>

funArgDefinitionarg(var) ;separator=" ,

"%>)

{

<%outVars |> var =>

funOutputVariable(var) ;separator="\n"%>

<%funArgs |> var =>

funArgDefinition(var) ;separator="\n"%>

<%callPart%>

}

>>

end externalFunction;

template funStatement(Statement stmt,

SimCode simCode)

"Generates function statements."

::=

match stmt

case ALGORITHM(__) then

(statementLst |> stmt =>

algStatement(stmt, contextFunction,

simCode) ;separator="\n")

else "NOT IMPLEMENTED FUN

STATEMENT"

end funStatement;

template funArgDefinitiontype(Variable

var)

::=

match var

case VARIABLE(__) then

<<

<%VariableType(ty)%>

>>

end funArgDefinitiontype;

template funArgDefinitionarg(Variable

var)

::=

match var

case

VARIABLE(ty=T_COMPLEX(complexCl

assType=RECORD(__))) then

<<

<%varType(var)%>

arg_<%contextCref(name,contextFunction

)%>

>>

case VARIABLE(__) then

<<

<%varType(var)%>

arg_<%contextCref(name,contextFunction

)%>

>>

end funArgDefinitionarg;

template funArgDefinition(Variable var)

::=

match var

case

VARIABLE(ty=T_COMPLEX(complexCl

assType=RECORD(__))) then

<<

<%varType(var)%>

<%contextCref(name,contextFunction)%>

=

arg_<%contextCref(name,contextFunction

)%>;

>>

case VARIABLE(__) then

<<

<%varType(var)%>

<%contextCref(name,contextFunction)%>

=

arg_<%contextCref(name,contextFunction

)%>;

>>

end funArgDefinition;

template funOutputVariable(Variable var)

::=

match var

case

VARIABLE(ty=T_COMPLEX(complexCl

assType=RECORD(__))) then

<<

<%VariableType(ty)%>

<%contextCref(name,contextFunction)%>;

>>

Page 67: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

67

case VARIABLE(__) then

<<

<%VariableType(ty)%>

<%contextCref(name,contextFunction)%>;

>>

end funOutputVariable;

template extFunCall(Function fun, Text

&preExp /*BUFP*/, SimCode simCode)

"Generates the call to an external

function."

::=

match fun

case EXTERNAL_FUNCTION(__) then

match language

case "C" then extFunCallC(fun, &preExp

/*BUFC*/, simCode)

case "FORTRAN 77" then

extFunCallF77(fun, &preExp /*BUFC*/,

simCode)

end extFunCall;

template extFunCallC(Function fun, Text

&preExp /*BUFP*/, SimCode simCode)

"Generates the call to an external C

function."

::=

match fun

case EXTERNAL_FUNCTION(__) then

let args = (extArgs |> arg =>

extArgC(arg, &preExp /*BUFC*/,

simCode)

;separator=",")

let returnAssign = match extReturn case

SIMEXTARG(cref=c) then

'<%extVarName(c)%> = '

else

""

<<

return <%returnAssign%>

<%extName%>(<%args%>);

>>

end extFunCallC;

template extFunCallF77(Function fun,

Text &preExp /*BUFP*/, SimCode

simCode)

"Generates the call to an external Fortran

77 function."

::=

match fun

case EXTERNAL_FUNCTION(__) then

let args = (extArgs |> arg =>

extArgF77(arg, &preExp, simCode)

;separator=", ")

let returnAssign = match extReturn case

SIMEXTARG(cref=c) then

'<%extVarName(c)%> = '

else

""

<<

return <%returnAssign%>

<%extName%>(<%args%>);

>>

end extFunCallF77;

template extArgC(SimExtArg extArg, Text

&preExp /*BUFP*/, SimCode simCode)

"Helper to extFunCall."

::=

match extArg

case SIMEXTARG(cref=c,

outputIndex=oi, isArray=true, type_=t)

then

<<

<%extVarName(c)%>

>>

case SIMEXTARG(cref=c, isInput=ii,

outputIndex=0, type_=t) then

<<

<%extVarName(c)%>

>>

case SIMEXTARG(cref=c, isInput=ii,

outputIndex=oi, type_=t) then

<<

<%extVarName(c)%>

>>

case SIMEXTARGEXP(__) then

daeExternalExp(exp, contextFunction,

&preExp /*BUFC*/, simCode) +'test

daeexternal'

case SIMEXTARGSIZE(cref=c) then

let name = extVarName(c)

let dim = daeExp(exp, contextFunction,

&preExp /*BUFC*/, simCode)

<<

<%name%> = <%dim%>

>>

Page 68: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

68

end extArgC;

template daeExternalExp(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Like daeExp, "

::=

match typeof(exp)

case T_ARRAY(__) then // Array-

expressions

<<

<%daeExp(exp, context, &preExp,

simCode)%>

>>

end daeExternalExp;

template extArgF77(SimExtArg extArg,

Text &preExp, SimCode simCode)

::=

match extArg

case SIMEXTARG(cref=c, isArray=true,

type_=t) then

<<

<%extVarName(c)%>

>>

case SIMEXTARG(cref=c,

outputIndex=oi, type_=T_INTEGER(__))

then

<<

<%extVarName(c)%>

>>

case SIMEXTARG(cref=c,

outputIndex=oi, type_ = T_STRING(__))

then

<<

<%extVarName(c)%>

>>

case SIMEXTARG(cref=c,

outputIndex=oi, type_=t) then

<<

<%extVarName(c)%>

>>

case SIMEXTARGEXP(exp=exp, type_

= T_STRING(__)) then

let texp = daeExp(exp, contextFunction,

&preExp /*BUFC*/, simCode)

<<

<%texp%>

>>

case SIMEXTARGSIZE(cref=c) then

let dim = daeExp(exp, contextFunction,

&preExp, simCode)

let name = extVarName(c)

<<

<%name%> = <%dim%>

>>

end extArgF77;

template extVarName(ComponentRef cr)

::=

<<

<%cref(cr)%>

>>

end extVarName;

/*********************SECTION:

GENERATE ALL RECORDS ( RECORD

LIST) IN SIMULATION

FILE************************/

template

recordsJava(list<RecordDeclaration>

recordDecls)

"Generates Java code for all records."

::=

<<

<%recordDecls |> rd =>

recordDeclaration(rd) ;separator="\n"%>

>>

end recordsJava;

template

recordDeclaration(RecordDeclaration

recDecl)

"Generates Java structs for a record

declaration."

::=

match recDecl

case RECORD_DECL_FULL(__) then

<<

public void <%name%>()

{

<%variables |> var =>

recordBody(var) ;separator="\n"%>

return;

}

>>

case RECORD_DECL_DEF(__) then

Page 69: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

69

<<

Record Declaration definition is not yet

implemented

>>

end recordDeclaration;

template recordBody(Variable var)

::=

match var

case VARIABLE(__) then

<<

<%varType(var)%>

<%crefStr(var.name)%>;

>>

case FUNCTION_PTR(__) then

'modelica_fnptr <%name%>'

end recordBody;

/*****************************SECT

ION: GENERATE All EQUATIONS IN

SIMULATION

FILE******************************

***********/

template equationIndex(SimEqSystem eq)

"Generates an equation."

::=

match eq

case SES_RESIDUAL(__) then

'<%index%>'

case SES_SIMPLE_ASSIGN(__) then

'<%index%>'

case SES_ARRAY_CALL_ASSIGN(__)

then '<%index%>'

case SES_ALGORITHM(__) then

'<%index%>'

case SES_LINEAR(__) then

'<%index%>'

case SES_NONLINEAR(__) then

'<%index%>'

case SES_MIXED(__) then '<%index%>'

case SES_WHEN(__) then '<%index%>'

end equationIndex;

template equation_(SimEqSystem eq,

Context context, SimCode simCode, Text

&eqs)

"Generates an equation.

This template should not be used for a

SES_RESIDUAL.

Residual equations are handled

differently."

::=

match simCode

case SIMCODE(modelInfo =

MODELINFO(__)) then

let &varDecls = buffer "" /*BUFD*/

match eq

case eq as

SES_SIMPLE_ASSIGN(__) then

let &preExp = buffer "" /*BUFD*/

let expPart =daeExp(exp, context,

&preExp, simCode) //was daeExpToReal

let codetxt =

<<

localData.xdot/*stateDerivative*/.add(<%c

refindex(cref,simCode)%>,<%expPart%>)

;

>>

match exp

case RELATION(__) then

<<

//<%expPart%> "Condition

Relation"

>>

case ARRAY(__) then

<<

ty[] temp = new ty[];

{

temp[<%crefindex(cref,simCode)%

>]=<%expPart%>; /*array*/

}

>>

else

codetxt

case eq as

SES_ARRAY_CALL_ASSIGN(__)

then equationArrayCallAssign(eq,

context, &varDecls /*BUFP*/, simCode)

case eq as SES_ALGORITHM(__)

then

Page 70: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

70

(statements |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n")

case eq as SES_LINEAR(__) then

" "

case eq as SES_NONLINEAR(__)

then " "

case eq as SES_MIXED(__) then "

"

case eq as SES_WHEN(__)

then equationWhen(eq, context,

&varDecls /*BUFD*/, simCode)

else "NOT IMPLEMENTED

EQUATION"

end equation_;

template

equationArrayCallAssign(SimEqSystem

eq, Context context, Text &varDecls

/*BUFP*/, SimCode simCode)

"Generates a when equation."

::=

<<

<%match eq

case eq as

SES_ARRAY_CALL_ASSIGN(__) then

let &preExp = buffer "" /*BUFD*/

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

match expTypeFromExpShort(eq.exp)

case "boolean" then

<<

<%cref(eq.componentRef)%> =

<%expPart%>

>>

case "integer" then

<<

<%cref(eq.componentRef)%> =

<%expPart%>

>>

case "double" then

<<

<%cref(eq.componentRef)%> =

<%expPart%>

>>

case "real" then

<<

<%cref(eq.componentRef)%> =

<%expPart%>

>>

else "error:No runtime support for this

sort of array call"

%>

>>

end equationArrayCallAssign;

template equationWhen(SimEqSystem eq,

Context context, Text &varDecls

/*BUFP*/, SimCode simCode)

"Generates a when equation."

::=

match eq

case SES_WHEN(__) then

let &preExp = buffer ""

let helpIf = (conditions |> cr =>

'<%cref(cr)%>'

;separator=" || ")

let rightExp = daeExp(right, context,

&preExp, simCode)

let elseWhenConds = match elseWhen

case SOME(ew) then

equationElseWhen(ew, context, simCode)

if initialCall then

<<

if(Initial<%helpIf%>) {

<%preExp%>

<%cref(left)%> = <%rightExp%>;

}

<%elseWhenConds%>

>>

else

<<

if( ! Initial) {

if(<%helpIf%>) {

<%preExp%>

<%cref(left)%> = <%rightExp%>;

}

<%elseWhenConds%>

}

>>

end equationWhen;

template equationElseWhen(SimEqSystem

eq, Context context, SimCode simCode)

"Generates a else when equation."

Page 71: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

71

::=

match eq

case SES_WHEN(left=left,

right=right,conditions=conditions,elseWhe

n = NONE()) then

let helpIf = (conditions |> cr =>

'<%cref(cr)%>'

;separator=" || ")

let &preExp2 = buffer "" /*BUFD*/

let exp = daeExp(right, context,

&preExp2 /*BUFC*/, simCode)

<<

else if (<%helpIf%>) {

<%preExp2%>

<%cref(left)%> = <%exp%>;

}

>>

case SES_WHEN(left=left,

right=right,conditions=conditions,elseWhe

n = SOME(elseWhenEq)) then

let helpIf = (conditions |> cr =>

'<%cref(cr)%>'

;separator=" || ")

let &preExp2 = buffer "" /*BUFD*/

let exp = daeExp(right, context,

&preExp2 /*BUFC*/, simCode)

let elseWhen =

equationElseWhen(elseWhenEq,context,si

mCode)

<<

else if (<%helpIf%>) {

<%preExp2%>

<%cref(left)%> = <%exp%>;

}

<%elseWhen%>

>>

end equationElseWhen;

template relationsTpl(list<ZeroCrossing>

relations, Context context, SimCode

simCode)

"Generates code for zero crossings."

::=

(relations |> ZERO_CROSSING(__)

hasindex i0 =>

relationTpl(i0, relation_, context,

simCode)

;separator="\n";empty)

end relationsTpl;

template relationTpl(Integer index1, Exp

relationExp, Context context, SimCode

simCode)

"Generates code for a zero crossing."

::=

match relationExp

case RELATION(__) then

let &preExp = buffer ""

let e1 = daeExp(exp1, context, &preExp,

simCode)

let e2 = daeExp(exp2, context, &preExp,

simCode)

<<

<%ExpressionDump.printExpStr(relationE

xp)%>

>>

end relationTpl;

template genreinits(SimWhenClause

whenClauses, list<ZeroCrossing>

relations, Context context, Text

&varDecls, SimCode simCode)

"Generates reinit statemeant"

::=

match whenClauses

case SIM_WHEN_CLAUSE(__)then

let CondExp = relationsTpl(relations,

contextOther, simCode)

if reinits then

<<

if (<%CondExp%>) {

<%functionWhenReinitStatementThen(rei

nits, &varDecls /*BUFP*/, simCode)%>

}

>>

end genreinits;

template

functionWhenReinitStatementThen(list<W

henOperator> reinits, Text &varDecls

/*BUFP*/, SimCode simCode)

"Generates re-init statement for when

equation."

::=

reinits |> reinit =>

match reinit

Page 72: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

72

case REINIT(__) then

let &preExp = buffer "" /*BUFD*/

let val = daeExp(value,

contextSimulationDiscrete, &preExp

/*BUFC*/, simCode)

<<

<%preExp%>

<%cref(stateVar)%> = <%val%>;

>>

case TERMINATE(__) then

let &preExp = buffer ""

let msgVar = daeExp(message,

contextSimulationDiscrete, &preExp,

simCode)

<<

<%preExp%>

MODELICA_TERMINATE(<%msgVar%

>);

>>

case

ASSERT(source=SOURCE(info=info))

then

assertCommon(condition, message,

contextSimulationDiscrete, simCode, info)

;separator="\n"

end functionWhenReinitStatementThen;

/***************************SECTIO

N: GENERATE All DAE Expression IN

SIMULATION

FILE******************************/

template daeExp(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for an expression."

::=

match exp

case e as ICONST(__) then integer

/* need to cast int into real to support

SimData */

case e as RCONST(__) then real

case e as SCONST(__) then

daeExpSconst(string, context, &preExp

/*BUFC*/, simCode)

case e as BCONST(__) then if bool

then "true" else "false"

case e as ENUM_LITERAL(__) then

index

case e as CREF(__) then

daeExpCrefRhs(e, context, &preExp,

simCode)

case e as BINARY(__) then

daeExpBinary(e, context, &preExp

/*BUFC*/, simCode)

case e as UNARY(__) then

daeExpUnary(e, context, &preExp

/*BUFC*/, simCode)

case e as LBINARY(__) then

daeExpLbinary(e, context, &preExp

/*BUFC*/, simCode)

case e as LUNARY(__) then

daeExpLunary(e, context, &preExp

/*BUFC*/, simCode)

case e as RELATION(__) then

daeExpRelation(e, context, &preExp

/*BUFC*/, simCode)

case e as CALL(__) then

daeExpCall(e, context, &preExp

/*BUFC*/, simCode)

case e as ARRAY(__) then

daeExpArray(e, context, &preExp

/*BUFC*/, simCode)

case e as IFEXP(__) then

daeExpIf(e, context, &preExp /*BUFC*/,

simCode)

case e as MATRIX(__) then

daeExpMatrix(e, context, &preExp

/*BUFC*/, simCode)

case e as RANGE(__) then

daeExpRange(e, context, &preExp

/*BUFC*/, simCode)

case e as CAST(__) then

daeExpCast(e, context, &preExp

/*BUFC*/, simCode)

case e as ASUB(__) then

daeExpAsub(e, context, &preExp

/*BUFC*/, simCode)

case e as TSUB(__) then

'<%daeExp(exp, context, &preExp,

simCode)%>'

case e as SIZE(__) then

daeExpSize(e, context, &preExp

/*BUFC*/, simCode)

Page 73: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

73

case e as BOX(__) then

daeExpBox(e, context, &preExp

/*BUFC*/, simCode)

case e as UNBOX(__) then

daeExpUnbox(e, context, &preExp

/*BUFC*/, simCode)

case e as SHARED_LITERAL(__) then

'_OMC_LIT<%index%>'

// META_TUPLE

// META_OPTION

// METARECORDCALL

else error(sourceInfo(), 'Unknown

expression:

<%ExpressionDump.printExpStr(exp)%>')

end daeExp;

template daeExpSconst(String string,

Context context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a string constant."

::=

<<

"<%Util.escapeModelicaStringToCString(

string)%>"

>>

end daeExpSconst;

template daeExpCrefRhs(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a component

reference."

::=

match exp

/*case CREF(componentRef=cr,

ty=T_ENUMERATION(__)) then

getEnumIndexfromCref(cr)*/

case cref as CREF(componentRef=cr,

ty=ty) then

let cast = match ty case

T_INTEGER(__) then "(int)" //else ""

'<%cast%><%cref(cr)%>'

end daeExpCrefRhs;

template daeExpBinary(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a binary expression."

::=

match exp

case BINARY(__) then

let e1 = daeExp(exp1, context, &preExp

/*BUFC*/, simCode)

let e2 = daeExp(exp2, context, &preExp

/*BUFC*/, simCode)

match operator

case ADD(__) then '(<%e1%> +

<%e2%>)'

case SUB(__) then '(<%e1%> -

<%e2%>)'

case MUL(__) then '(<%e1%> *

<%e2%>)'

case DIV(__) then '(<%e1%> / <%e2%>)'

case POW(__) then 'Math.pow(<%e1%>,

<%e2%>)'

case UMINUS(__) then

daeExpUnary(exp, context, &preExp

/*BUFC*/, simCode)

else "daeExpBinary:ERR"

end daeExpBinary;

template daeExpUnary(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a unary expression."

::=

match exp

case UNARY(__) then

let e = daeExp(exp, context, &preExp

/*BUFC*/, simCode)

match operator

case UMINUS(__) then '(-<%e%>)'

case NOT(__) then '(!<%e%>)'

case UMINUS_ARR(__) then

"UMINUS_ARR_NOT_IMPLEMENTED

"

else "daeExpUnary:ERR"

end daeExpUnary;

template daeExpLbinary(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a logical binary

expression."

::=

match exp

Page 74: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

74

case LBINARY(__) then

let e1 = daeExp(exp1, context, &preExp

/*BUFC*/, simCode)

let e2 = daeExp(exp2, context, &preExp

/*BUFC*/, simCode)

match operator

case AND(__) then '(<%e1%> &&

<%e2%>)'

case OR(__) then '(<%e1%> || <%e2%>)'

else "daeExpLbinary:ERR"

end daeExpLbinary;

template daeExpLunary(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a logical unary

expression."

::=

match exp

case LUNARY(__) then

let e = daeExp(exp, context, &preExp

/*BUFC*/, simCode)

match operator

case NOT(__) then '(!<%e%>)'

end daeExpLunary;

template daeExpRelation(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a relation expression."

::=

match exp

case rel as RELATION(__) then /* to get

output BouncingBall --mano */

let e1 = daeExp(rel.exp1, context,

&preExp /*BUFC*/, simCode)

let e2 = daeExp(rel.exp2, context,

&preExp /*BUFC*/, simCode)

match rel.operator

case LESS(ty = T_BOOL(__)) then

'(!<%e1%> && <%e2%>)'

case LESS(ty = T_STRING(__)) then

'(<%e1%>.compareTo(<%e2%>) < 0)'

case LESS(ty = T_INTEGER(__))

then '(<%e1%> < <%e2%>)'

case LESS(ty = T_REAL(__)) then

'(<%e1%> < <%e2%>)'

case GREATER(ty = T_BOOL(__))

then '(<%e1%> && !<%e2%>)'

case GREATER(ty = T_STRING(__))

then '(<%e1%>.compareTo(<%e2%>) >

0)'

case GREATER(ty = T_INTEGER(__))

then '(<%e1%> > <%e2%>)'

case GREATER(ty = T_REAL(__))

then '(<%e1%> > <%e2%>)'

case LESSEQ(ty = T_BOOL(__))

then '(!<%e1%> || <%e2%>)'

case LESSEQ(ty = T_STRING(__))

then '(<%e1%>.compareTo(<%e2%>) <=

0)'

case LESSEQ(ty = T_INTEGER(__))

then '(<%e1%> <= <%e2%>)'

case LESSEQ(ty = T_REAL(__))

then '(<%e1%> <= <%e2%>)'

case GREATEREQ(ty = T_BOOL(__))

then '(<%e1%> || !<%e2%>)'

case GREATEREQ(ty =

T_STRING(__)) then

'(<%e1%>.compareTo(<%e2%>) >= 0)'

case GREATEREQ(ty =

T_INTEGER(__))then '(<%e1%> >=

<%e2%>)'

case GREATEREQ(ty = T_REAL(__))

then '(<%e1%> >= <%e2%>)'

case EQUAL(ty = T_BOOL(__))

then '((!<%e1%> && !<%e2%>) ||

(<%e1%> && <%e2%>))'

case EQUAL(ty = T_STRING(__))

then '(<%e1%>.equals(<%e2%>))'

case EQUAL(ty = T_INTEGER(__))

then '(<%e1%> == <%e2%>)'

case EQUAL(ty = T_REAL(__))

then '(<%e1%> == <%e2%>)'

case EQUAL(ty =

T_ENUMERATION(__))then '(<%e1%>

== <%e2%>)'

case NEQUAL(ty = T_BOOL(__))

then '((!<%e1%> && <%e2%>) ||

(<%e1%> && !<%e2%>))'

case NEQUAL(ty = T_STRING(__))

then '(!<%e1%>.equals(<%e2%>))'

case NEQUAL(ty = T_INTEGER(__))

then '(<%e1%> != <%e2%>)'

case NEQUAL(ty = T_REAL(__))

then '(<%e1%> != <%e2%>)'

Page 75: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

75

else

let simRel = daeExpRelationSim(rel,

context, &preExp /*BUFC*/, simCode)

if simRel then

simRel

else "daeExpRelation:ERR"

end daeExpRelation;

template daeExpRelationSim(Exp exp,

Context context, Text &preExp /*BUFP*/,

SimCode simCode)

"Helper to daeExpRelation."

::=

match exp

case rel as RELATION(__) then

match context

case SIMULATION(genDiscrete=false)

then

match rel.optionExpisASUB

case NONE() then

let &varDecls = buffer "" /*BUFD*/

let e1 = daeExp(rel.exp1, context,

&preExp /*BUFC*/, simCode)

let e2 = daeExp(rel.exp2, context,

&preExp /*BUFC*/, simCode)

let res =

tempDecl("modelica_boolean", &varDecls

/*BUFC*/)

match rel.operator

case LESS(__) then

let &preExp +=

<<

(<%res%> < <%e2%>)

>>

res

case LESSEQ(__) then

let &preExp +=

<<

(<%res%> <= <%e2%>)

>>

res

case GREATER(__) then

let &preExp +=

<<

(<%res%> > <%e2%>)

>>

res

case GREATEREQ(__) then

let &preExp +=

<<

(<%res%> >= <%e2%>)

>>

res

end match

case SOME((exp,i,j)) then

let &varDecls = buffer "" /*BUFD*/

let e1 = daeExp(rel.exp1, context,

&preExp /*BUFC*/, simCode)

let e2 = daeExp(rel.exp2, context,

&preExp /*BUFC*/, simCode)

let iterator = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

let res =

tempDecl("modelica_boolean", &varDecls

/*BUFC*/)

match rel.operator

case LESS(__) then

let &preExp +=

<<

(<%res%> < <%e2%>)

>>

res

case LESSEQ(__) then

let &preExp +=

<<

(<%res%> <= <%e2%>)

>>

res

case GREATER(__) then

let &preExp +=

<<

(<%res%> > <%e2%>)

>>

res

case GREATEREQ(__) then

let &preExp +=

<<

(<%res%> >= <%e2%>)

>>

res

end match

end match

case SIMULATION(genDiscrete=true)

then

match rel.optionExpisASUB

case NONE() then

Page 76: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

76

let &varDecls = buffer "" /*BUFD*/

let e1 = daeExp(rel.exp1, context,

&preExp /*BUFC*/, simCode)

let e2 = daeExp(rel.exp2, context,

&preExp /*BUFC*/, simCode)

let res =

tempDecl("modelica_boolean", &varDecls

/*BUFC*/)

match rel.operator

case LESS(__) then

let &preExp +=

<<

(<%res%> < <%e2%>)

>>

res

case LESSEQ(__) then

let &preExp +=

<<

(<%res%> <= <%e2%>)

>>

res

case GREATER(__) then

let &preExp +=

<<

(<%res%> > <%e2%>)

>>

res

case GREATEREQ(__) then

let &preExp +=

<<

(<%res%> >= <%e2%>)

>>

res

end match

case SOME((exp,i,j)) then

let &varDecls = buffer "" /*BUFD*/

let e1 = daeExp(rel.exp1, context,

&preExp /*BUFC*/, simCode)

let e2 = daeExp(rel.exp2, context,

&preExp /*BUFC*/, simCode)

let iterator = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

let res =

tempDecl("modelica_boolean", &varDecls

/*BUFC*/)

match rel.operator

case LESS(__) then

let &preExp +=

<<

(<%res%> < <%e2%>)

>>

res

case LESSEQ(__) then

let &preExp +=

<<

(<%res%> <= <%e2%>)

>>

res

case GREATER(__) then

let &preExp +=

<<

(<%res%> > <%e2%>)

>>

res

case GREATEREQ(__) then

let &preExp +=

<<

(<%res%> >= <%e2%>)

>>

res

end match

end match

end match

end match

end daeExpRelationSim;

template daeExpCall(Exp call, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a function call."

::=

match call

// special builtins

case

CALL(path=IDENT(name="DIVISION"),

expLst={e1, e2,

DAE.SCONST(string=string)}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

let var3 =

Util.escapeModelicaStringToCString(strin

g)

<<

<%var1%>/<%var2%> /*Division

Call*/

>>

Page 77: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

77

case CALL(attr=CALL_ATTR(ty=ty),

path=IDENT(name="DIVISION_ARRAY

_SCALAR"),

expLst={e1, e2, e3 as

SHARED_LITERAL(__)}) then

let type = match ty case

T_ARRAY(ty=T_INTEGER(__)) then

"integer_array"

case

T_ARRAY(ty=T_ENUMERATION(__))

then "integer_array"

else "real_array"

let &varDecls = buffer "" /*BUFD*/

let var = tempDecl(type, &varDecls)

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

let var3 = daeExp(e3, context, &preExp,

simCode)

let &preExp +=

'division_alloc_<%type%>_scalar(&<%va

r1%>, <%var2%>, &<%var%>,

<%var3%>);<%\n%>'

'<%var%>'

case exp as

CALL(path=IDENT(name="DIVISION_A

RRAY_SCALAR")) then

error(sourceInfo(), 'Code generation

does not support <%printExpStr(exp)%>')

case CALL(path=IDENT(name="der"),

expLst={arg as CREF(__)}) then

<<

<%cref(arg.componentRef)%>

>>

case CALL(path=IDENT(name="der"),

expLst={exp}) then

error(sourceInfo(), 'Code generation

does not support

der(<%printExpStr(exp)%>)')

case CALL(path=IDENT(name="pre"),

expLst={arg}) then

daeExpCallPre(arg, context, preExp,

simCode)

case

CALL(path=IDENT(name="$_start"),

expLst={arg}) then

daeExpCallPre(arg, context, preExp,

simCode)

case CALL(path=IDENT(name="edge"),

expLst={arg as CREF(__)}) then

<<

<%cref(arg.componentRef)%> /*edge*/

>>

case CALL(path=IDENT(name="edge"),

expLst={exp}) then

error(sourceInfo(), 'Code generation

does not support

edge(<%printExpStr(exp)%>)')

case

CALL(path=IDENT(name="change"),

expLst={arg as CREF(__)}) then

<<

<%cref(arg.componentRef)%>

/*change*/

>>

case

CALL(path=IDENT(name="change"),

expLst={exp}) then

error(sourceInfo(), 'Code generation

does not support

change(<%printExpStr(exp)%>)')

case CALL(path=IDENT(name="print"),

expLst={e1}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

if acceptMetaModelicaGrammar() then

'System.out.println(<%var1%>)' else

'put(<%var1%>)'

case CALL(path=IDENT(name="max"),

attr=CALL_ATTR(ty = T_REAL(__)),

expLst={e1,e2}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

<<

'Math.Max (<%var1%>,<%var2%>)'

>>

Page 78: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

78

case CALL(path=IDENT(name="max"),

expLst={e1,e2}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

<<

'Math.max (<%var1%>,<%var2%>)'

>>

case CALL(path=IDENT(name="sum"),

attr=CALL_ATTR(ty = ty), expLst={e})

then

let arr = daeExp(e, context, &preExp,

simCode)

let ty_str = '<%expTypeArray(ty)%>'

'sum_<%ty_str%>(&<%arr%>)'

case CALL(path=IDENT(name="min"),

attr=CALL_ATTR(ty = T_REAL(__)),

expLst={e1,e2}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

<<

'Math.min (<%var1%>,<%var2%>)'

>>

case CALL(path=IDENT(name="min"),

expLst={e1,e2}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

<<

'Math.min (<%var1%>,<%var2%>)'

>>

case CALL(path=IDENT(name="abs"),

expLst={e1}, attr=CALL_ATTR(ty =

T_INTEGER(__))) then

let var1 = daeExp(e1, context, &preExp,

simCode)

<<

'Math.abs (<%var1%>)'

>>

case CALL(path=IDENT(name="abs"),

expLst={e1}) then

let var1 = daeExp(e1, context, &preExp,

simCode)

<<

'Math.abs (<%var1%>)'

>>

case CALL(path=IDENT(name="sqrt"),

expLst={e1}, attr=attr as

CALL_ATTR(__)) then

let retPre =

assertCommon(createAssertforSqrt(e1),cre

ateDAEString("Model error: Argument of

sqrt should be >= 0"), context, simCode,

dummyInfo)

let argStr = daeExp(e1, context,

&preExp /*BUFC*/, simCode)

let &preExp += '<%retPre%>'

<<

'Math.sqrt (<%argStr%>)'

>>

case CALL(path=IDENT(name="mod"),

expLst={e1,e2}, attr=CALL_ATTR(ty =

ty)) then

let var1 = daeExp(e1, context, &preExp,

simCode)

let var2 = daeExp(e2, context, &preExp,

simCode)

'<%var1%>.mod(<%var2%>)'

case CALL(path=IDENT(name="log"),

expLst={s1}) then

'Math.log(<%daeExp(s1, context,

&preExp, simCode)%>)'

case

CALL(path=IDENT(name="log10"),

expLst={s1}) then

'Math.log10(<%daeExp(s1, context,

&preExp, simCode)%>)'

case CALL(path=IDENT(name="exp"),

expLst={s1}) then

'Math.exp(<%daeExp(s1, context,

&preExp, simCode)%>)'

Page 79: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

79

case CALL(path=IDENT(name="sin"),

expLst={s1}) then

'Math.Sin(<%daeExp(s1, context,

&preExp, simCode)%>)'

case CALL(path=IDENT(name="cos"),

expLst={s1}) then

'Math.cos(<%daeExp(s1, context,

&preExp, simCode)%>)'

case CALL(path=IDENT(name="tanh"),

expLst={s1}) then

'Math.tanh(<%daeExp(s1, context,

&preExp, simCode)%>)'

case

CALL(path=IDENT(name="noEvent"),

expLst={s1}) then

'(/*noEvent*/<%daeExp(s1, /*context*/

contextOther, &preExp, simCode)%>)'

case

CALL(path=IDENT(name="initial"),

expLst={}) then

'Initial'

/* Begin code generation of event

triggering math functions */

case

CALL(path=IDENT(name="integer"),

expLst={valExp,index}) then

let &preExp += '//event trigger function:

<%ExpressionDump.printExpStr(call)%><

%\n%>'

let constIndex = daeExp(index, context,

&preExp, simCode)

match context

case SIMULATION(genDiscrete=true)

case

ALGLOOP_CONTEXT(genInitialisation=

true)

case

ZEROCROSSINGS_CONTEXT(__)

then

let val = daeExp(valExp, context,

&preExp, simCode)

'((int) (mathEVPre[<%constIndex%>]

= Math.floor(<%val%>)))'

case SIMULATION(genDiscrete=false)

then

'(int) mathEVPre[<%constIndex%>]'

case

ALGLOOP_CONTEXT(genInitialisation=

false) then

let &res = buffer ""

let &preExp +=

let &preExpVal = buffer ""

let val = daeExp(valExp, context,

&preExpVal, simCode)

<<

<%tempDecl("int", &res)%>;

if(IsDiscreteEvaluation &&

!IsContinuousEvaluation) {

<%preExpVal%>

<%res%> = (int)

(mathEVPre[<%constIndex%>] =

Math.floor(<%val%>));

} else {

<%res%> = (int)

mathEVPre[<%constIndex%>];

}<%\n%>

>>

res

else error(sourceInfo(), 'Unexpected

context for:

<%ExpressionDump.printExpStr(call)%>')

case CALL(path=IDENT(name="floor"),

expLst={valExp,index},

attr=CALL_ATTR(__)) then

let &preExp += '//event trigger function:

<%ExpressionDump.printExpStr(call)%><

%\n%>'

let constIndex = daeExp(index, context,

&preExp, simCode)

let retType =

match attr.ty

case T_REAL(__) then ""

case T_INTEGER(__) then "(int)"

else error(sourceInfo(), 'Unexpected

return type "<%expTypeShort(attr.ty)%>"

for floor().')

retType

+ ( match context

case

SIMULATION(genDiscrete=true)

Page 80: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

80

case

ALGLOOP_CONTEXT(genInitialisation=

true)

case

ZEROCROSSINGS_CONTEXT(__)

then

let val = daeExp(valExp, context,

&preExp, simCode)

'(mathEVPre[<%constIndex%>] =

Math.floor(<%val%>))'

case

SIMULATION(genDiscrete=false) then

'mathEVPre[<%constIndex%>]'

case

ALGLOOP_CONTEXT(genInitialisation=

false) then

let &res = buffer ""

let &preExp +=

let &preExpVal = buffer ""

let val = daeExp(valExp, context,

&preExpVal, simCode)

<<

<%tempDecl("double", &res)%>;

if(IsDiscreteEvaluation &&

!IsContinuousEvaluation) {

<%preExpVal%>

<%res%> =

(mathEVPre[<%constIndex%>] =

Math.floor(<%val%>));

} else {

<%res%> =

mathEVPre[<%constIndex%>];

}<%\n%>

>>

res

else error(sourceInfo(), 'Unexpected

context for:

<%ExpressionDump.printExpStr(call)%>')

)

case CALL(path=IDENT(name="ceil"),

expLst={valExp,index},

attr=CALL_ATTR(__)) then

let &preExp += '//event trigger function:

<%ExpressionDump.printExpStr(call)%><

%\n%>'

let constIndex = daeExp(index, context,

&preExp, simCode)

let retType =

match attr.ty

case T_REAL(__) then ""

case T_INTEGER(__) then "(int)"

else error(sourceInfo(), 'Unexpected

return type "<%expTypeShort(attr.ty)%>"

for ceil().')

retType

+ ( match context

case

SIMULATION(genDiscrete=true)

case

ALGLOOP_CONTEXT(genInitialisation=

true)

case

ZEROCROSSINGS_CONTEXT(__)

then

let val = daeExp(valExp, context,

&preExp, simCode)

'(mathEVPre[<%constIndex%>] =

Math.ceil(<%val%>))'

case

SIMULATION(genDiscrete=false) then

'mathEVPre[<%constIndex%>]'

case

ALGLOOP_CONTEXT(genInitialisation=

false) then

let &res = buffer ""

let &preExp +=

let &preExpVal = buffer ""

let val = daeExp(valExp, context,

&preExpVal, simCode)

<<

<%tempDecl("double", &res)%>;

if(IsDiscreteEvaluation &&

!IsContinuousEvaluation) {

<%preExpVal%>

<%res%> =

(mathEVPre[<%constIndex%>] =

Math.ceil(<%val%>));

} else {

<%res%> =

mathEVPre[<%constIndex%>];

}<%\n%>

>>

res

else error(sourceInfo(), 'Unexpected

context for:

<%ExpressionDump.printExpStr(call)%>')

)

Page 81: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

81

case CALL(path=IDENT(name="div"),

expLst={e1,e2, index},

attr=CALL_ATTR(__)) then

let &preExp += '//event trigger function:

<%ExpressionDump.printExpStr(call)%><

%\n%>'

let constIndex = daeExp(index, context,

&preExp, simCode)

let stype = expTypeShort(attr.ty)

match context

case SIMULATION(genDiscrete=true)

case

ALGLOOP_CONTEXT(genInitialisation=

true)

case

ZEROCROSSINGS_CONTEXT(__)

then

let val1 = daeExp(e1, context,

&preExp, simCode)

let val2 = daeExp(e2, context,

&preExp, simCode)

let &res = buffer ""

let &preExp +=

<<

<%tempDecl(stype, &res)%>

{ var d = <%val2%>;

if (d = 0) throw new

DivideByZeroException("event_div()

failed at time " + Time + " because

denominator is zero!");

<%res%> = (int) (<%val1%> / d);

mathEVPre[<%constIndex%>] =

<%res%>;

}

>>

res

case SIMULATION(genDiscrete=false)

then

'(<%stype%>)

mathEVPre[<%constIndex%>]'

case

ALGLOOP_CONTEXT(genInitialisation=

false) then

let &res = buffer ""

let &preExp +=

let &preExpVal = buffer ""

let val1 = daeExp(e1, context,

&preExpVal, simCode)

let val2 = daeExp(e2, context,

&preExpVal, simCode)

<<

<%tempDecl(stype, &res)%>;

if(IsDiscreteEvaluation &&

!IsContinuousEvaluation) {

<%preExpVal%>

var d = <%val2%>;

if (d = 0) {

throw new

DivideByZeroException("event_div()

failed at time " + Time + " because

denominator is zero!");

<%res%> = (int) (<%val1%> / d);

mathEVPre[<%constIndex%>] =

<%res%>;

}

} else {

<%res%> = (<%stype%>)

mathEVPre[<%constIndex%>];

}<%\n%>

>>

res

else error(sourceInfo(), 'Unexpected

context for:

<%ExpressionDump.printExpStr(call)%>')

/* end codegeneration of event triggering

math functions */

case exp as CALL(attr=attr as

CALL_ATTR(__)) then

let argStr = (expLst |> exp =>

'<%daeExp(exp, context, &preExp

/*BUFC*/, simCode)%>' ;separator=",")

let builtinName ='<%dotPath(path)%>'

let builtinFunctionName

='<%builtinFunctionName(path)%>'

let funName =

'<%underscorePath(path)%>'

let retType = if attr.builtin then (match

attr.ty case T_NORETCALL(__) then ""

else expTypeModelica(attr.ty))

else '<%funName%>'

let retVar = match attr.ty

case T_NORETCALL(__) then ""

else ""/*tempDecl(retType, &varDecls)

*/

match exp

Page 82: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

82

// no return calls

case

CALL(attr=CALL_ATTR(ty=T_NORETC

ALL(__))) then '/* NORETURNCALL */'

// non tuple calls (single return value)

case

CALL(attr=CALL_ATTR(tuple_=false))

then

if attr.builtin then

<<

<%builtinFunctionName%>(<%argStr%>)

/*<%builtinName%>(<%argStr%>);

*/

>>

else

<<

<%funName%>(<%argStr%>)

>>

// tuple calls (multiple return values)

else

<<

<%funName%>(<%argStr%>)

>>

end daeExpCall;

template builtinFunctionName(Path path)

::=

match path

case IDENT(name="DIVISION") then

'divide'

case IDENT(name="ADDITION") then

'add'

case IDENT(name="SUBTRACTION")

then 'sub'

case IDENT(name="POWER") then

'Math.pow'

case IDENT(name="sin") then 'Math.sin'

case IDENT(name="cos") then 'Math.cos'

case IDENT(name="exp") then

'Math.exp'

case IDENT(name="sample") then

'Sample'

else "Builtin Function is not yet

implemented "

end builtinFunctionName;

template daeExpCallPre(Exp exp, Context

context, Text &preExp, SimCode

simCode)

"Generates code for an asub of a cref,

which becomes cref + offset."

::=

match exp

case cr as CREF(__) then

'<%cref(cr.componentRef)%>'

else

error(sourceInfo(), 'Code generation

does not support

pre(<%printExpStr(exp)%>)')

end daeExpCallPre;

template expTypeModelica(DAE.Type ty)

"Generate type helper."

::=

expTypeFlag(ty, 2)

end expTypeModelica;

template expTypeArray(DAE.Type ty)

"Generate type helper."

::=

expTypeFlag(ty, 3)

end expTypeArray;

template expTypeArrayIf(DAE.Type ty)

"Generate type helper."

::=

expTypeFlag(ty, 4)

end expTypeArrayIf;

template daeExpArray(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for an array expression."

::=

match exp

case cr as CREF(__) then

daeExpCrefRhs(cr, context, &preExp,

simCode)

case a as ARRAY(__) then

if scalar then

let &arrayVar = buffer ""

let params = a.array |> e =>

'(<%expTypeFromExpFlag(e,1)%>)<%dae

Exp(e, context, &preExp, simCode)%>'

;separator=", "

Page 83: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

83

let &preExp +=

'<%tempDecl("var",&arrayVar)%> = new

<%expTypeArray(a.ty)%>(<%listLength(a

.array)%>,-

1,new[]{<%params%>});<%\n%>'

arrayVar

else

"NON_SCALAR_ARRAY_notYetImplem

eted"

end daeExpArray;

template daeExpIf(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for an if expression."

::=

match exp

case IFEXP(__) then

let condExp = daeExp(expCond, context,

&preExp /*BUFC*/, simCode)

let &preExpThen = buffer "" /*BUFD*/

let eThen = daeExp(expThen, context,

&preExpThen /*BUFC*/, simCode)

let &preExpElse = buffer "" /*BUFD*/

let eElse = daeExp(expElse, context,

&preExpElse /*BUFC*/, simCode)

let shortIfExp = if preExpThen then ""

else if preExpElse then "" else "x"

(if shortIfExp

then

// Safe to do if eThen and eElse don't

emit pre-expressions

'(<%condExp%>?<%eThen%>:<%eElse%

>)'

else

let &varDecls = buffer "" /*BUFD*/

let condVar = tempDecl("boolean",

&varDecls /*BUFD*/)

let resVarType =

expTypeFromExpArrayIf(expThen)

let resVar = tempDecl(resVarType,

&varDecls /*BUFD*/)

let &preExp +=

<<

<%condVar%> =

(boolean)<%condExp%>;

if (<%condVar%>) {

<%preExpThen%>

<%resVar%> =

(<%resVarType%>)<%eThen%>;

} else {

<%preExpElse%>

<%resVar%> =

(<%resVarType%>)<%eElse%>;

}<%\n%>

>>

resVar)

end daeExpIf;

template daeExpMatrix(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a matrix expression."

::=

match exp

case cr as CREF(__) then

daeExpCrefRhs(cr, context, &preExp,

simCode)

case MATRIX(matrix={{}}) // special

case for empty matrix: create dimensional

array Real[0,1]

case MATRIX(matrix={}) // special

case for empty array: create dimensional

array Real[0,1]

then

let &tmp = buffer ""

let &preExp +=

'<%tempDecl("var",&tmp)%> = new

<%expTypeArray(ty)%>(0,1);<%\n%>'

tmp

//only scalar orthogonal matrix for now

case m as MATRIX(matrix=(row1::_))

then

let &tmp = buffer ""

let matArr = m.matrix |> row =>

(row |> elem =>

daeExp(elem, context,

&preExp, simCode)

;separator=", ")

;separator=",\n"

let &preExp +=

<<

<%tempDecl("var",&tmp)%> = new

<%expTypeArray(m.ty)%>(<%listLength(

m.matrix)%>,<%listLength(row1)%>,-1,

new[]{

Page 84: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

84

<%matArr ;anchor%>

});<%\n%>

>>

tmp

end daeExpMatrix;

template daeExpRange(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a range expression."

::=

match exp

case RANGE(__) then

let ty_str = expTypeArray(ty)

let start_exp = daeExp(start, context,

&preExp, simCode)

let stop_exp = daeExp(stop, context,

&preExp, simCode)

let &varDecls = buffer "" /*BUFD*/

let tmp = tempDecl(ty_str, &varDecls)

let step_exp = match step case

SOME(stepExp) then daeExp(stepExp,

context, &preExp, simCode) else "1"

let &preExp +=

<<

'range(<%start_exp%>,<%stop_exp%>,<

%step_exp%>);<%\n%>'

>>

'<%tmp%>'

end daeExpRange;

template daeExpCast(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a cast expression."

::=

match exp

case CAST(__) then

let expVar = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

match ty

case T_INTEGER(__) then

'((int)<%expVar%>)'

case T_REAL(__) then

'((double)<%expVar%>)'

else "NOT_IMPLEMENTED_CAST"

end daeExpCast;

template daeExpAsub(Exp inExp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for an asub expression."

::=

match inExp

case ASUB(exp=RANGE(ty=t),

sub={idx}) then

'ASUB_EASY_CASE'

case ASUB(exp=ASUB(

exp=ASUB(

exp=ASUB(exp=e,

sub={ICONST(integer=i)}),

sub={ICONST(integer=j)}),

sub={ICONST(integer=k)}),

sub={ICONST(integer=l)}) then

'ASUB_4D'

case ASUB(exp=ASUB(

exp=ASUB(exp=e,

sub={ICONST(integer=i)}),

sub={ICONST(integer=j)}),

sub={ICONST(integer=k)}) then

'ASUB_3D'

case ASUB(exp=ASUB(exp=e,

sub={ICONST(integer=i)}),

sub={ICONST(integer=j)}) then

'<%daeExp(e, context, &preExp,

simCode)%>[<%i%>,<%j%>]'

case ASUB(exp=e,

sub={ICONST(integer=i)}) then

'ASUB_ARRAY'

case ASUB(exp=ecr as

CREF(componentRef = cr), sub = subs)

then

match context case

FUNCTION_CONTEXT(__) then

daeExpCrefRhs(buildCrefExpFromAsub(e

cr, subs), context, &preExp, simCode)

else //SIMULATION or OTHER

contexts

match ecr.ty

case T_ARRAY(ty = T_REAL(__),

dims = dims) then

//daeExpCrefRhsArrayBox

let &constSum = buffer ""

let arrayRepr =

crefRepresentationArrayAndIndex(cr,

&constSum, simCode)

Page 85: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

85

let baseSub = asubSubsripts(dims,

subs, &constSum, context, &preExp,

simCode)

'/*<%crefStr(cr)%>[]*/<%arrayRepr%>[<

%constSum%><%baseSub%>]'

else

"ASUB_SIMULATION_OTHER_ERRO

R"

case ASUB(exp=exp as

ARRAY(scalar=true), sub={idx}) then

"ASUB_FAST_ONE"

case ASUB(exp=e, sub=indexes) then

<<

<%daeExp(e, context, &preExp,

simCode)

%>[<%indexes |> index =>

'<%daeExp(index, context, &preExp,

simCode)%>' ;separator=", "%>]

>>

else

'OTHER_ASUB__ERROR'

end daeExpAsub;

template asubSubsripts(list<Dimension>

dims, list<Exp> subs, Text &constSum,

Context context, Text

&preExp, SimCode simCode)

"Helper to daeExpAsub."

::=

match subs case s :: subsRest then

match dims case _ :: dimsRest then

let subStr = daeExp(s, context,

&preExp, simCode)

if dimsRest then //not last

let ds = dimsRest |> dim =>

dimension(dim) ;separator="*"

//if ds then //TODO: assuming

every dimension is SOME, is it true ??

let &constSum += '-(<%ds%>)' //-

1 * ds

'+<%subStr%>*(<%ds%>)<%

asubSubsripts(dimsRest, subsRest,

&constSum, context, &preExp, simCode)

%>'

else //the last sub, add it to constSum

(better optimization on compilation)

let &constSum += '-1 + <% subStr

%>'

""

else

"ERROR_asubSubsripts_not_enough_dim

s"

end asubSubsripts;

template dimension(Dimension d)

::=

match d

case DAE.DIM_INTEGER(__) then

integer

case DAE.DIM_UNKNOWN(__) then

":"

else "INVALID_DIMENSION"

end dimension;

template daeExpSize(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a size expression."

::=

match exp

case SIZE(exp=CREF(__),

sz=SOME(dim)) then

let expPart = daeExp(exp, context,

&preExp, simCode)

match dim

case ICONST(__) then

'<%expPart%>.size<%integer%>'

else

'<%expPart%>.size(<%daeExp(dim,

context, &preExp, simCode)%>)'

else "size_X_NOT_IMPLEMENTED"

end daeExpSize;

template daeExpBox(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a match expression

box."

::=

match exp

case exp as BOX(__) then

let ty = expTypeFromExpShort(exp.exp)

let res =

daeExp(exp.exp,context,&preExp,simCode

)

Page 86: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

86

<<

box_<%ty%><%res%>

>>

end daeExpBox;

template daeExpUnbox(Exp exp, Context

context, Text &preExp /*BUFP*/,

SimCode simCode)

"Generates code for a match expression

unbox."

::=

match exp

case exp as UNBOX(__) then

let ty = expTypeShort(exp.ty)

let res =

daeExp(exp.exp,context,&preExp,simCode

)

'unbox_<%ty%>(<%res%>) /*

DAE.UNBOX <%unparseType(exp.ty)

%> */'

end daeExpUnbox;

template daeExpCallBuiltinPrefix(Boolean

builtin)

"Helper to daeExpCall."

::=

match builtin

case true then ""

case false then "_"

end daeExpCallBuiltinPrefix;

/**********************************

****SECTION: GENERATE All

Algorithm IN SIMULATION

FILE******************************

****/

template algStatement(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates an algorithm statement."

::=

match stmt

case s as STMT_ASSIGN(__) then

algStmtAssign(s, context, simCode)

case s as STMT_ASSIGN_ARR(__)

then algStmtAssignArr(s, context,

simCode)

case s as STMT_TUPLE_ASSIGN(__)

then algStmtTupleAssign(s, context,

simCode)

case s as STMT_IF(__) then

algStmtIf(s, context, simCode)

case s as STMT_FOR(__) then

algStmtFor(s, context, simCode)

case s as STMT_WHILE(__) then

algStmtWhile(s, context, simCode)

case s as STMT_ASSERT(__) then

algStmtAssert(s, context, simCode)

case s as STMT_TERMINATE(__)

then algStmtTerminate(s, context,

simCode)

case s as STMT_WHEN(__) then

algStmtWhen(s, context, simCode)

case s as STMT_BREAK(__) then

'Break;<%\n%>'

case s as STMT_RETURN(__) then

'Return;<%\n%>'

case s as STMT_NORETCALL(__)

then algStmtNoretcall(s, context, simCode)

case s as STMT_REINIT(__) then

algStmtReinit(s, context, simCode)

else "NEW ALG STATEMENT"

end algStatement;

template algStmtAssign(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates an assigment algorithm

statement."

::=

match stmt

case

STMT_ASSIGN(exp1=CREF(component

Ref=WILD(__)), exp=e) then

let &preExp = buffer "" /*BUFD*/

let expPart = daeExp(e, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

>>

case STMT_ASSIGN(exp1=CREF(ty =

T_FUNCTION_REFERENCE_VAR(__)))

case STMT_ASSIGN(exp1=CREF(ty =

T_FUNCTION_REFERENCE_FUNC(__)

)) then

let &preExp = buffer "" /*BUFD*/

Page 87: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

87

let varPart = scalarLhsCref(exp1,

context, &preExp /*BUFC*/, simCode)

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

<%varPart%> = <%expPart%>;

>>

case STMT_ASSIGN(exp1=CREF(__))

then

let &preExp = buffer "" /*BUFD*/

let varPart = scalarLhsCref(exp1,

context, &preExp /*BUFC*/, simCode)

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

<%varPart%> = <%expPart%>;

>>

case STMT_ASSIGN(__) then

let &preExp = buffer "" /*BUFD*/

let varPart = scalarLhsCref(exp1,

context, &preExp /*BUFC*/, simCode)

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

<%varPart%> = <%expPart%>;

>>

case

STMT_ASSIGN(exp1=CALL(path=path,e

xpLst=expLst,attr=CALL_ATTR(ty=

T_COMPLEX(varLst = varLst,

complexClassType=RECORD(__))))) then

let &preExp = buffer ""

let rec = daeExp(exp, context, &preExp,

simCode)

<<

<%preExp%>

<% varLst |> var as TYPES_VAR(__)

hasindex i1 fromindex 0 =>

let re = daeExp(listNth(expLst,i1),

context, &preExp, simCode)

'<%re%> =

<%rec%>.<%var.name%>;'

; separator="\n"

%>

>>

case STMT_ASSIGN(exp1=exp1 as

ASUB(__),exp=val) then

let &preExp = buffer "" /*BUFD*/

let varPart = daeExpAsub(exp1, context,

&preExp /*BUFC*/, simCode)

let expPart = daeExp(val, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

<%varPart%> = <%expPart%>;

>>

end algStmtAssign;

template

algStmtAssignArr(DAE.Statement stmt,

Context context, SimCode simCode)

"Generates an array assigment algorithm

statement."

::=

match stmt

case STMT_ASSIGN_ARR(exp=e,

componentRef=cr, type_=t) then

let &preExp = buffer "" /*BUFD*/

let expPart = daeExp(e, context, &preExp

/*BUFC*/, simCode)

let ispec = indexSpecFromCref(cr,

context, &preExp /*BUFC*/, simCode)

if ispec then

<<

<%preExp%>

<%indexedAssign(t, expPart, cr, ispec,

context, simCode)%>

>>

else

<<

<%copyArrayData(t, expPart, cr,

context, simCode)%>

<%preExp%>

>>

end algStmtAssignArr;

template

indexSpecFromCref(ComponentRef cr,

Context context, Text &preExp /*BUFP*/,

SimCode

simCode)

Page 88: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

88

"Helper to algStmtAssignArr.

Currently works only for CREF_IDENT."

::=

match cr

case CREF_IDENT(subscriptLst=subs as

(_ :: _)) then

daeExpCrefRhsIndexSpec(subs, context,

&preExp /*BUFC*/, simCode)

end indexSpecFromCref;

template

daeExpCrefRhsIndexSpec(list<Subscript>

subs, Context context,

Text &preExp

/*BUFP*/, SimCode simCode)

"Helper to daeExpCrefRhs."

::=

let nridx_str = listLength(subs)

let &varDecls = buffer "" /*BUFD*/

let idx_str = (subs |> sub =>

match sub

case INDEX(__) then

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

let str =

<<

<%expPart%>

>>

str

case WHOLEDIM(__) then

let str = <<(1), (int*)0, 'W'>>

str

case SLICE(__) then

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

let tmp =

tempDecl("modelica_integer", &varDecls

/*BUFD*/)

let &preExp += '<%tmp%> =

size_of_dimension_integer_array(<%expP

art%>, 1);<%\n%>'

let str = <<(int) <%tmp%>,

integer_array_make_index_array(&<%exp

Part%>), 'A'>>

str

;separator=", ")

let tmp = tempDecl("index_spec_t",

&varDecls /*BUFD*/)

let &preExp +=

'create_index_spec(&<%tmp%>,

<%nridx_str%>, <%idx_str%>);<%\n%>'

tmp

end daeExpCrefRhsIndexSpec;

template indexedAssign(DAE.Type ty,

String exp, DAE.ComponentRef cr,

String ispec, Context

context, SimCode simCode)

::=

let type = expTypeArray(ty)

let cref = contextArrayCref(cr, context)

match context

case FUNCTION_CONTEXT(__) then

<<

<%type%> <%cref%>

>>

else

<<

<%type%>

<%exp%>

<%ispec%>

<%cref%>

>>

end indexedAssign;

template copyArrayData(DAE.Type ty,

String exp, DAE.ComponentRef cr,

Context context, SimCode simCode)

::=

let type = expTypeArray(ty)

let cref = contextArrayCref(cr, context)

match context

case FUNCTION_CONTEXT(__) then

'<%cref%>'

else

<<

<%type%> <%cref%>

>>

end copyArrayData;

template

algStmtTupleAssign(DAE.Statement stmt,

Context context, SimCode simCode)

"Generates Java for a tuple assigment

algorithm statement."

::=

Page 89: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

89

match stmt

case

STMT_TUPLE_ASSIGN(exp=CALL(__))

then

let &preExp = buffer "" /*BUFD*/

let &afterExp = buffer "" /*BUFD*/

let crefs = (expExpLst |> e =>

ExpressionDump.printExpStr(e)

;separator=", ")

let marker = '(<%crefs%>) =

<%ExpressionDump.printExpStr(exp)%>'

let &preExp += '/* algStmtTupleAssign:

preExp buffer created for <%marker%>

*/<%\n%>'

let &afterExp += '/* algStmtTupleAssign:

afterExp buffer created for <%marker%>

*/<%\n%>'

let retStruct = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

let lhsCrefs = (expExpLst |> cr hasindex

i1 fromindex 1 =>

let rhsStr =

'<%retStruct%>.targ<%i1%>'

writeLhsCref(cr, rhsStr,

context, &afterExp /*BUFC*/, simCode)

;separator="\n")

<<

return <%lhsCrefs%> = <%retStruct%>;

>>

case

STMT_TUPLE_ASSIGN(exp=MATCHE

XPRESSION(__)) then

let &preExp = buffer "" /*BUFD*/

let &afterExp = buffer "" /*BUFD*/

let prefix = 'tmp<%System.tmpTick()%>'

//let _ = daeExpMatch2(exp, expExpLst,

prefix, context, &preExp, simCode)

let lhsCrefs = (expExpLst |> cr hasindex

i1 fromindex 1 =>

let rhsStr =

'<%prefix%>_targ<%i1%>'

writeLhsCref(cr, rhsStr,

context, &afterExp /*BUFC*/, simCode)

;separator="\n")

<<

<%expExpLst |> cr hasindex i1

fromindex 1 =>

let rhsStr = '<%prefix%>_targ<%i1%>'

let typ =

'<%expTypeFromExpModelica(cr)%>'

let &varDecls = buffer "" /*BUFD*/

let initVar = match typ case

"modelica_metatype" then ' = NULL' else ''

let addRoot = match typ case

"modelica_metatype" then '

mmc_GC_add_root(&<%rhsStr%>,

mmc_GC_local_state, "<%rhsStr%>");'

else ''

let &varDecls += '<%typ%>

<%rhsStr%><%initVar%>;<%addRoot%>

<%\n%>'

""

;separator="\n";empty%>

<%preExp%>

<%lhsCrefs%>

<%afterExp%>

>>

else error(sourceInfo(),

'algStmtTupleAssign failed')

end algStmtTupleAssign;

template writeLhsCref(Exp exp, String

rhsStr, Context context, Text &preExp

/*BUFP*/, SimCode simCode)

"Generates Java code for writing a

returnStructur to var."

::=

match exp

case ecr as

CREF(componentRef=WILD(__)) then

<<

"EmptyOutputArgument"

>>

case CREF(ty= t as DAE.T_ARRAY(__))

then

let lhsStr = scalarLhsCref(exp, context,

&preExp /*BUFC*/, simCode)

match context

case SIMULATION(__) then

<<

<%lhsStr%>

>>

else

<<

<%lhsStr%>

>>

Page 90: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

90

case UNARY(exp = e as CREF(ty= t as

DAE.T_ARRAY(__))) then

let lhsStr = scalarLhsCref(e, context,

&preExp /*BUFC*/, simCode)

match context

case SIMULATION(__) then

<<

<%rhsStr%>

<%lhsStr%>

>>

else

<<

<%lhsStr%>

>>

case CREF(__) then

let lhsStr = scalarLhsCref(exp, context,

&preExp /*BUFC*/, simCode)

<<

<%lhsStr%>

>>

case UNARY(exp = e as CREF(__)) then

let lhsStr = scalarLhsCref(e, context,

&preExp /*BUFC*/, simCode)

<<

<%lhsStr%>

>>

case _ then

<<

/* CodegenJava.tpl template:

writeLhsCref: UNHANDLED LHS

*

<%ExpressionDump.printExpStr(exp)%>

= <%rhsStr%>

*/

>>

end writeLhsCref;

template algStmtIf(DAE.Statement stmt,

Context context, SimCode simCode)

"Generates an if algorithm statement."

::=

match stmt

case STMT_IF(__) then

let &preExp = buffer "" /*BUFD*/

let condExp = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

if (<%condExp%>) {

<%statementLst |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n"%>

}

<%elseExpr(else_, context, simCode)%>

>>

end algStmtIf;

template elseExpr(DAE.Else else_,

Context context, SimCode simCode)

"Helper to algStmtIf."

::=

match else_

case NOELSE(__) then

""

case ELSEIF(__) then

let &preExp = buffer "" /*BUFD*/

let condExp = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

<<

else {

<%preExp%>

if (<%condExp%>) {

<%statementLst |> stmt =>

algStatement(stmt, context,

simCode)

;separator="\n"%>

}

<%elseExpr(else_, context,

simCode)%>

}

>>

case ELSE(__) then

<<

else {

<%statementLst |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n"%>

}

>>

end elseExpr;

template algStmtFor(DAE.Statement stmt,

Context context, SimCode simCode)

"Generates a while algorithm statement."

::=

/*algStmtFor */

match stmt

Page 91: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

91

case s as STMT_FOR(range=rng as

RANGE(__)) then

algStmtForRange(s, context, simCode)

case s as STMT_FOR(__) then

algStmtForGeneric(s, context,

simCode)

end algStmtFor;

template algStmtForRange(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates a for algorithm statement

where range is RANGE."

::=

match stmt

case STMT_FOR(range=rng as

RANGE(__)) then

let identType = expType(type_,

iterIsArray)

let identTypeShort =

expTypeShort(type_)

let stmtStr = (statementLst |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n")

algStmtForRange_impl(rng, iter,

identType, identTypeShort, stmtStr,

context, simCode)

end algStmtForRange;

template contextIteratorName(Ident name,

Context context)

"Generates code for an iterator variable."

::=

match context

case FUNCTION_CONTEXT(__) then

"_" + name

case

PARALLEL_FUNCTION_CONTEXT(__

) then "_" + name

else "$P" + name

end contextIteratorName;

template algStmtForRange_impl(Exp

range, Ident iterator, String type, String

shortType, Text body, Context context,

SimCode simCode)

"The implementation of algStmtForRange,

which is also used by daeExpReduction."

::=

match range

case RANGE(__) then

let &varDecls = buffer "" /*BUFD*/

let iterName =

contextIteratorName(iterator, context)

let stateVar = if not

acceptMetaModelicaGrammar() then

tempDecl("state", &varDecls)

let startVar = tempDecl(type, &varDecls)

let stepVar = tempDecl(type, &varDecls)

let stopVar = tempDecl(type, &varDecls)

let &preExp = buffer ""

let startValue = daeExp(start, context,

&preExp, simCode)

let stepValue = match step case

SOME(eo) then

daeExp(eo, context, &preExp,

simCode)

else

"(1)"

let stopValue = daeExp(stop, context,

&preExp, simCode)

<<

/*algStmtForRange_impl*/

<%preExp%>

<%startVar%> = <%startValue%>;

<%stepVar%> = <%stepValue%>;

<%stopVar%> = <%stopValue%>;

if (!<%stepVar%>) {

FILE_INFO info =

omc_dummyFileInfo;

omc_assert("assertion range step != 0

failed", info);

} else if (!(((<%stepVar%> > 0) &&

(<%startVar%> > <%stopVar%>)) ||

((<%stepVar%> < 0) && (<%startVar%>

< <%stopVar%>)))) {

<%type%> <%iterName%>;

for (<%iterName%> =

<%startValue%>;

in_range_<%shortType%>(<%iterName%

>, <%startVar%>, <%stopVar%>);

<%iterName%> += <%stepVar%>) {

<%if not

acceptMetaModelicaGrammar() then

'<%stateVar%> = get_memory_state();'%>

<%body%>

<%if not

acceptMetaModelicaGrammar() then

Page 92: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

92

'restore_memory_state(<%stateVar%>);'%

>

}

}

>> /* else we're looping over a zero-

length range */

end algStmtForRange_impl;

template

algStmtForGeneric(DAE.Statement stmt,

Context context, SimCode simCode)

"Generates a for algorithm statement

where range is not RANGE."

::=

match stmt

case STMT_FOR(__) then

let iterType = expType(type_,

iterIsArray)

let arrayType = expTypeArray(type_)

let stmtStr = (statementLst |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n")

algStmtForGeneric_impl(range, iter,

iterType, arrayType, iterIsArray, stmtStr,

context, simCode)

end algStmtForGeneric;

template algStmtForGeneric_impl(Exp

exp, Ident iterator, String type,

String arrayType, Boolean iterIsArray,

Text &body, Context context, SimCode

simCode)

"The implementation of

algStmtForGeneric, which is also used by

daeExpReduction."

::=

let &varDecls = buffer "" /*BUFD*/

let iterName =

contextIteratorName(iterator, context)

let stateVar = if not

acceptMetaModelicaGrammar() then

tempDecl("state", &varDecls)

let tvar = tempDecl("int", &varDecls)

let ivar = tempDecl(type, &varDecls)

let &preExp = buffer ""

let evar = daeExp(exp, context, &preExp,

simCode)

let stmtStuff = if iterIsArray then

'simple_index_alloc_<%type%>1(&<%eva

r%>, <%tvar%>, &<%ivar%>);'

else

'<%iterName%> =

*(<%arrayType%>_element_addr1(&<%e

var%>, 1, <%tvar%>));'

<<

/* algStmtForGeneric_impl;*/

<%preExp%>

{

<%type%> <%iterName%>;

for(<%tvar%> = 1; <%tvar%> <=

size_of_dimension_<%arrayType%>(<%e

var%>, 1); ++<%tvar%>) {

<%if not

acceptMetaModelicaGrammar() then

'<%stateVar%> = get_memory_state();'%>

<%stmtStuff%>

<%body%>

<%if not

acceptMetaModelicaGrammar() then

'restore_memory_state(<%stateVar%>);'%

>

}

}

}

>>

end algStmtForGeneric_impl;

template algStmtWhile(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates a while algorithm statement."

::=

match stmt

case STMT_WHILE(__) then

let &preExp = buffer "" /*BUFD*/

let var = daeExp(exp, context, &preExp

/*BUFC*/, simCode)

<<

while (<%var%>) {

<%statementLst |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n"%>

}

>>

end algStmtWhile;

Page 93: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

93

template algStmtAssert(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates an assert algorithm statement."

::=

match stmt

case

STMT_ASSERT(source=SOURCE(info=i

nfo)) then

assertCommon(cond, msg, context,

simCode, info)

end algStmtAssert;

template

algStmtTerminate(DAE.Statement stmt,

Context context, SimCode simCode)

"Generates an assert algorithm statement."

::=

match stmt

case STMT_TERMINATE(__) then

let &preExp = buffer "" /*BUFD*/

let msgVar = daeExp(msg, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

<%msgVar%>

>>

end algStmtTerminate;

template algStmtWhen(DAE.Statement

when, Context context, SimCode simCode)

"Generates a when algorithm statement."

::=

match context

case SIMULATION(__) then

match when

case STMT_WHEN(__) then

let preIf = algStatementWhenPre(when,

simCode)

let statements = (statementLst |> stmt =>

algStatement(stmt, context, simCode)

;separator="\n")

let else =

algStatementWhenElse(elseWhen,

simCode)

<<

/*algStmtWhen*/

<%/*preIf*/%>

if <%preIf%> {

<%statements%>

}

<%else%>

}

>>

end match

end match

end algStmtWhen;

template

algStatementWhenPre(DAE.Statement

stmt, SimCode simCode)

"Helper to algStmtWhen."

::=

match stmt

case

STMT_WHEN(exp=ARRAY(array=el))

then

let restPre = match elseWhen case

SOME(ew) then

algStatementWhenPre(ew, simCode)

else

""

let &preExp = buffer "" /*BUFD*/

/*let assignments =

algStatementWhenPreAssigns(el,

helpVarIndices,

&preExp

/*BUFC*/,

simCode)*/

<<

/*algStatementWhenPre case1*/

<%preExp%>

</*%assignments%>

<%restPre%>

>>

case when as STMT_WHEN(__) then

match statementLst

// match helpVarIndices

case {i} then

let restPre = match when.elseWhen

case SOME(ew) then

algStatementWhenPre(ew, simCode)

else

""

let &preExp = buffer "" /*BUFD*/

let res = daeExp(when.exp,

contextSimulationDiscrete,

Page 94: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

94

&preExp /*BUFC*/,

simCode)

<<

/*algStatementWhenPre case 2 */

<%preExp%>

<%res%>

<%restPre%>

>>

end algStatementWhenPre;

template

algStatementWhenElse(Option<DAE.State

ment> stmt, SimCode simCode)

"Helper to algStmtWhen."

::=

match stmt

case SOME(when as STMT_WHEN(__))

then

let statements = (when.statementLst |>

stmt =>

algStatement(stmt,

contextSimulationDiscrete, simCode)

;separator="\n")

let else =

algStatementWhenElse(when.elseWhen,

simCode)

/*let elseCondStr = (when.helpVarIndices

|> hidx =>

'data-

>simulationInfo.helpVars[<%hidx%>] &&

!data-

>simulationInfo.helpVarsPre[<%hidx%>]

/* edge */'

;separator=" || ")*/

<<

else if (</*%elseCondStr%>) {

<%statements%>

}

<%else%>

>>

end algStatementWhenElse;

template

algStatementWhenPreAssigns(list<Exp>

exps, list<Integer> ints,

Text &preExp /*BUFP*/,

SimCode simCode)

"Helper to algStatementWhenPre.

The lists exps and ints should be of the

same length. Iterating over two

lists like this is not so well supported in

Susan, so it looks a bit ugly."

::=

match exps

case {} then ""

case (firstExp :: restExps) then

match ints

case (firstInt :: restInts) then

let rest =

algStatementWhenPreAssigns(restExps,

restInts, &preExp /*BUFC*/, simCode)

let firstExpPart = daeExp(firstExp,

contextSimulationDiscrete,

&preExp /*BUFC*/,

simCode)

<<

<%firstExpPart%>;

<%rest%>

>>

end algStatementWhenPreAssigns;

template algStmtNoretcall(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates a no return call algorithm

statement."

::=

match stmt

case STMT_NORETCALL(__) then

let &preExp = buffer "" /*BUFD*/

let expPart = daeExp(exp, context,

&preExp /*BUFC*/, simCode)

<<

<%preExp%>

<%expPart%>

>>

end algStmtNoretcall;

template algStmtReinit(DAE.Statement

stmt, Context context, SimCode simCode)

"Generates an assigment algorithm

statement."

::=

match stmt

case STMT_REINIT(__) then

let &preExp = buffer "" /*BUFD*/

let expPart1 = daeExp(var, context,

&preExp /*BUFC*/, simCode)

Page 95: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

95

let expPart2 = daeExp(value, context,

&preExp /*BUFC*/, simCode)

<<

<%expPart1%> = <%expPart2%>;

>>

end algStmtReinit;

/**********************************

**componentreference****************

**********************************

***/

template scalarLhsCref(Exp ecr, Context

context, Text &preExp, SimCode

simCode)

"Generates the left hand side (for use on

left hand side) of a component

reference."

::=

match ecr

case CREF(componentRef = cr, ty =

T_FUNCTION_REFERENCE_VAR(__))

then

<<

<%crefStr(cr)%>

>>

case ecr as

CREF(componentRef=CREF_IDENT(__))

then

if crefNoSub(ecr.componentRef) then

contextCref(ecr.componentRef,

context)

else

daeExpCrefRhs(ecr, context, &preExp,

simCode)

case ecr as

CREF(componentRef=CREF_QUAL(__))

then

contextCref(ecr.componentRef, context)

else

"ONLY_IDENT_OR_QUAL_CREF_SUP

PORTED_SLHS"

end scalarLhsCref;

template functionName(ComponentRef cr)

::=

match cr

case CREF_IDENT(__) then

System.stringReplace(ident, "_", "__")

case CREF_QUAL(__) then

'<%System.stringReplace(ident, "_",

"__")%>_<%functionName(componentRef

)%>'

end functionName;

template contextCref(ComponentRef cr,

Context context)

"Generates code for a component

reference depending on which context

we're in."

::=

match context

case FUNCTION_CONTEXT(__) then

cref(cr)

else cref(cr)

end contextCref;

template cref(ComponentRef cr)

"Generates Java equivalent name for

component reference."

::=

match cr

case CREF_IDENT(ident = "xloc") then

crefStr(cr)

case CREF_IDENT(ident = "time") then

"time"

case CREF_IDENT(ident = " ") then

crefToCStr(cr)

else crefToCStr(cr)

end cref;

template expCref(DAE.Exp ecr)

::=

match ecr

case CREF(__) then cref(componentRef)

case CALL(path = IDENT(name =

"der"), expLst = {arg as CREF(__)}) then

'der<%cref(arg.componentRef)%>'

else "ERROR_NOT_A_CREF"

end expCref;

template contextArrayCref(ComponentRef

cr, Context context)

"Generates Java code for an array

component reference depending on the

context."

Page 96: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

96

::=

match context

case FUNCTION_CONTEXT(__) then

arrayCrefStr(cr)

else arrayCrefStrname(cr)

end contextArrayCref;

template arrayCrefStrname(ComponentRef

cr)

::= '<%arrayCrefStrName1(cr)%>'

end arrayCrefStrname;

template

arrayCrefStrName1(ComponentRef cr)

::=

match cr

case CREF_IDENT(__) then

<<

<exp:QualifiedName>

<exp:QualifiedNamePart

name="<%unquoteIdentifier(ident)%>">

>>

case CREF_QUAL(__) then

'<%unquoteIdentifier(ident)%><%subscrip

tsStr(subscriptLst)%>$P<%arrayCrefStrNa

me1(componentRef)%>testing array'

else "CREF_NOT_IDENT_OR_QUAL"

end arrayCrefStrName1;

template arrayCrefStr(ComponentRef cr)

::=

match cr

case CREF_IDENT(__) then

<<

"<%ident%>"

>>

case CREF_QUAL(__) then

'<%ident%>.<%arrayCrefStr(componentR

ef)%>'

else "CREF_NOT_IDENT_OR_QUAL"

end arrayCrefStr;

template

crefRepresentationArrayAndIndex(Compo

nentRef cr, Text &indexTxt, SimCode

simCode)

::=

match cr

//deprecated: case CREF_IDENT(ident =

"xloc") then crefStr(cr, simCode) //TODO:

??xloc

case CREF_IDENT(ident = "time") then

"Time" //no index

case CREF_IDENT(ident = "$_lambda")

then "_lambda" //no index

//??is this a HACK (on the SimCode

level) ??

case CREF_QUAL(ident = "$PRE") then

'pre<%crefRepresentationArrayAndIndex(

componentRef, &indexTxt, simCode)%>'

else

(cref2simvar(cr, simCode) |>

SIMVAR(__) =>

let &indexTxt += index

representationArrayName(varKind,

type_))

end crefRepresentationArrayAndIndex;

template

representationArrayName(VarKind

varKind, Type type_)

::=

match varKind

case VARIABLE(__) then "Y"

case STATE(__) then "X"

case STATE_DER(__) then "Xd"

case DUMMY_DER(__) then "Y" // =>

algebraics

case DUMMY_STATE(__) then "Y" //

=> algebraics

case EXTOBJ(__) then "EO"

case CONST(__) then

"CONST_VAR_KIND"

else "BAD_VARKIND"

end representationArrayName;

template

representationCref(ComponentRef inCref,

SimCode simCode)

::=

let &indexTxt = buffer ""

let arrAndIdx =

crefRepresentationArrayAndIndex(inCref,

&indexTxt, simCode)

if indexTxt then

'<% indexTxt %>'

Page 97: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

97

else

arrAndIdx

end representationCref;

template crefindex(ComponentRef cref,

SimCode simCode)

::=

'<% representationCref(cref, simCode)

%>'

end crefindex;

template crefStr(ComponentRef cr)

"Generates the name of a variable for

variable name array."

::=

match cr

case CREF_IDENT(__) then

'<%ident%><%subscriptsStr(subscriptLst)

%>'

case CREF_QUAL(ident = "der") then

'der(<%crefStr(componentRef)%>)'

case CREF_QUAL(__) then

'<%ident%><%subscriptsStr(subscriptLst)

%>.<%crefStr(componentRef)%>'

else "CREF_NOT_IDENT_OR_QUAL"

end crefStr;

template subscriptsStr(list<Subscript>

subscripts)

"Generares subscript part of the name."

::=

if subscripts then

'[<%subscripts |> s => subscriptStr(s)

;separator=","%>]'

end subscriptsStr;

template subscriptStr(Subscript subscript)

"Generates a single subscript.

Only works for constant integer indicies."

::=

match subscript

case

INDEX(exp=ICONST(integer=i)) then i

case

SLICE(exp=ICONST(integer=i)) then i

case WHOLEDIM(__) then

"WHOLEDIM"

else "UNKNOWN_SUBSCRIPT"

end subscriptStr;

template crefToCStr(ComponentRef cr)

"Helper function to cref."

::=

match cr

case CREF_IDENT(__) then

'<%ident%><%subscriptsToCStr(subscript

Lst)%>'

case CREF_QUAL(__) then

'<%ident%><%subscriptsToCStr(subscript

Lst)%><%crefToCStr(componentRef)%>'

else "CREF_NOT_IDENT_OR_QUAL"

end crefToCStr;

template subscriptsToCStr(list<Subscript>

subscripts)

::=

if subscripts then

'[<%subscripts |> s =>

subscriptToCStr(s) ;separator=","%>]'

end subscriptsToCStr;

template subscriptToCStr(Subscript

subscript)

::=

match subscript

case INDEX(exp=ICONST(integer=i))

then i

case SLICE(exp=ICONST(integer=i))

then i

case WHOLEDIM(__) then

"WHOLEDIM"

else "UNKNOWN_SUBSCRIPT"

end subscriptToCStr;

template expType(DAE.Type ty, Boolean

array)

"Generate type helper."

::=

match array

case true then expTypeArray(ty)

case false then expTypeModelica(ty)

end expType;

template expTypeFromExpArrayIf(Exp

exp)

"Generate type helper."

::=

expTypeFromExpFlag(exp, 4)

Page 98: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

98

end expTypeFromExpArrayIf;

template expTypeFlag(DAE.Type ty,

Integer flag)

"Generate type helper."

::=

match flag

case 1 then

// we want the short type

expTypeShort(ty)

case 2 then

// we want the "modelica type"

match ty case

T_COMPLEX(complexClassType=EXTE

RNAL_OBJ(__)) then

'<%expTypeShort(ty)%>'

else match ty case T_COMPLEX(__)

then

'struct

<%underscorePath(ClassInf.getStateName(

complexClassType))%>' // alachew 'struct

<%underscorePath(name)%>' //

else

'<%expTypeShort(ty)%>'

case 3 then

// we want the "array type"

'<%expTypeShort(ty)%>'

case 4 then

// we want the "array type" only if type

is array, otherwise "modelica type"

match ty

case T_ARRAY(__) then

'<%expTypeShort(ty)%>'

else expTypeFlag(ty, 2)

end expTypeFlag;

template tempDecl(String ty, Text

&varDecls /*BUFP*/)

"Declares a temporary variable in

varDecls and returns the name."

::=

let newVar

=

match ty /* TODO! FIXME! UGLY!

UGLY! hack! */

case "modelica_metatype"

case "metamodelica_string"

case "metamodelica_string_const"

then

'tmpMeta[<%System.tmpTickIndex(1)%>]

'

else

let newVarIx =

'tmp<%System.tmpTick()%>'

let &varDecls += '<%ty%>

<%newVarIx%>;<%\n%>'

newVarIx

newVar

end tempDecl;

template expTypeFromExpFlag(Exp exp,

Integer flag)

"Generate type helper."

::=

/*replaced "modelica_integer" type to

normal type "int" and real to double for

header porblem --mano*/

match exp

case ICONST(__) then match flag

case 8 then "int" case 1 then "int" else "int"

case RCONST(__) then match flag

case 1 then "double" else "double"

case SCONST(__) then if

acceptMetaModelicaGrammar() then

(match flag case 1 then

"metatype" else "modelica_metatype")

else

(match flag case 1 then

"string" else "string")

case BCONST(__) then match flag

case 1 then "boolean" else "boolean"

case ENUM_LITERAL(__) then match

flag case 8 then "int" case 1 then "int" else

"int"

case e as BINARY(__)

case e as UNARY(__)

case e as LBINARY(__)

case e as LUNARY(__)

case e as RELATION(__) then

expTypeFromOpFlag(e.operator, flag)

case IFEXP(__) then

expTypeFromExpFlag(expThen, flag)

case CALL(attr=CALL_ATTR(__)) then

expTypeFlag(attr.ty, flag) // alachew case

CALL(__) then expTypeFlag(ty,

flag)

Page 99: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

99

else '#error

"expTypeFromExpFlag:<%printExpStr(ex

p)%>"'

end expTypeFromExpFlag;

template varType(Variable var)

"Generates type for a variable."

::=

match var

case VARIABLE(__) then

if instDims then

expTypeArray(ty)

else

expTypeArrayIf(ty)

end varType;

template expTypeShort(DAE.Type type)

"Generate type helper."

::=

match type

case T_INTEGER(__) then "int"

case T_REAL(__) then "double"

case T_STRING(__) then if

acceptMetaModelicaGrammar() then

"metatype" else "string"

case T_BOOL(__) then "boolean" /*

need to cross check --mano*/

case T_ENUMERATION(__) then "int"

case T_ARRAY(__) then

expTypeShort(ty)

case

T_COMPLEX(complexClassType=EXTE

RNAL_OBJ(__))

then "complex"

case T_COMPLEX(__) then '/*struct*/

<%underscorePath(ClassInf.getStateName(

complexClassType))%>'

case T_METATYPE(__) case

T_METABOXED(__) then

"META_TYPE_NOT_SUPPORTED"

case

T_FUNCTION_REFERENCE_VAR(__)

then "fnptr"

case T_UNKNOWN(__) then

"UNKNOWN_TYPE_NOT_SUPPORTE

D"

case T_ANYTYPE(__) then

"ANYTYPE_TYPE_NOT_SUPPORTED"

else "expTypeShort:ERROR"

end expTypeShort;

template replaceDotAndUnderscore(String

str)

"Replace _ with __ and dot in identifiers

with _"

::=

match str

case name then

let str_dots =

System.stringReplace(name,".", "_")

let str_underscores =

System.stringReplace(str_dots, "_", "__")

'<%str_underscores%>'

end replaceDotAndUnderscore;

template underscorePath(Path path)

"Generate paths with components

separated by underscores.

Replaces also the . in identifiers with _.

The dot might happen for

world.gravityAccleration"

::=

match path

case QUALIFIED(__) then

'<%replaceDotAndUnderscore(name)%>_

<%underscorePath(path)%>'

case IDENT(__) then

replaceDotAndUnderscore(name)

case FULLYQUALIFIED(__) then

underscorePath(path)

end underscorePath;

template expTypeFromOpFlag(Operator

op, Integer flag)

"Generate type helper."

::=

match op

case o as ADD(__)

case o as SUB(__)

case o as MUL(__)

case o as DIV(__)

case o as POW(__)

case o as UMINUS(__)

// alachew case o as UPLUS(__)

case o as LESS(__)

case o as LESSEQ(__)

Page 100: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

100

case o as GREATER(__)

case o as GREATEREQ(__)

case o as EQUAL(__)

case o as NEQUAL(__) then

expTypeFlag(o.ty, flag)

case o as AND(__)

case o as OR(__)

case o as NOT(__) then

match flag case 1 then "boolean" else

"boolean"

else "expTypeFromOpFlag:ERROR"

end expTypeFromOpFlag;

template infoArgs(Info info)

::=

match info

case INFO(__) then

'"<%fileName%>",<%lineNumberStart%>

,<%columnNumberStart%>,<%lineNumbe

rEnd%>,<%columnNumberEnd%>,<%isR

eadOnly%>'

end infoArgs;

template assertCommon(Exp condition,

Exp message, Context context, SimCode

simCode, Info info)

::=

let &preExpCond = buffer ""

let &preExpMsg = buffer ""

let condVar = daeExp(condition, context,

&preExpCond, simCode)

let msgVar = daeExp(message, context,

&preExpMsg, simCode)

<<

<%preExpCond%>

if (!<%condVar%>) {

<%preExpMsg%>

// <%infoArgs(info)%>

throw new Exception(<%msgVar%>);

}

>>

end assertCommon;

template expTypeFromExpShort(Exp exp)

"Generate type helper."

::=

expTypeFromExpFlag(exp, 1)

end expTypeFromExpShort;

template expTypeFromExpModelica(Exp

exp)

"Generate type helper."

::=

expTypeFromExpFlag(exp, 2)

end expTypeFromExpModelica;

template unboxVariable(String varName,

Type varType, Text &preExp, Text

&varDecls)

::=

match varType

case T_STRING(__) case

T_METATYPE(__) case

T_METABOXED(__) then varName

case T_COMPLEX(complexClassType =

RECORD(__)) then

unboxRecord(varName, varType,

&preExp, &varDecls)

else

let shortType =

mmcExpTypeShort(varType)

let ty = '<%shortType%>'

let tmpVar = tempDecl(ty, &varDecls)

let &preExp += '<%tmpVar%> =

mmc_unbox_<%shortType%>(<%varNam

e%>);<%\n%>'

tmpVar

end unboxVariable;

template unboxRecord(String recordVar,

Type ty, Text &preExp, Text &varDecls)

::=

match ty

case T_COMPLEX(complexClassType =

RECORD(path = path), varLst = vars) then

let tmpVar = tempDecl('struct

<%underscorePath(path)%>', &varDecls)

let &preExp += (vars |>

TYPES_VAR(name = compname)

hasindex offset fromindex 2 =>

let varType = mmcExpTypeShort(ty)

let untagTmp =

tempDecl('modelica_metatype',

&varDecls)

//let offsetStr = incrementInt(i1, 1)

let &unboxBuf = buffer ""

Page 101: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

101

let unboxStr =

unboxVariable(untagTmp, ty, &unboxBuf,

&varDecls)

<<

<%untagTmp%> =

(MMC_FETCH(MMC_OFFSET(MMC_U

NTAGPTR(<%recordVar%>),

<%offset%>)));

<%unboxBuf%>

<%tmpVar%>.<%compname%> =

<%unboxStr%>;

>>

;separator="\n")

tmpVar

end unboxRecord;

template mmcExpTypeShort(DAE.Type

type)

::=

match type

case T_INTEGER(__) then

"int"

case T_REAL(__) then

"double"

case T_STRING(__) then

"string"

case T_BOOL(__) then

"boolean"

case T_ENUMERATION(__)

then "int"

case T_ARRAY(__) then

"type[]"

case T_METATYPE(__) case

T_METABOXED(__) then

"metatype"

case

T_FUNCTION_REFERENCE_VAR(__)

then "fnptr"

else "mmcExpTypeShort:ERROR"

end mmcExpTypeShort;

template xsdateTime(DateTime dt)

"YYYY-MM-DDThh:mm:ssZ"

::=

match dt

case DATETIME(__) then '<%year%>-

<%twodigit(mon)%>-

<%twodigit(mday)%>T<%twodigit(hour)

%>:<%twodigit(min)%>:<%twodigit(sec)

%>Z'

end xsdateTime;

end CodegenJava;

Page 102: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

102

Java Runtime System

SimData.Java

package jrt;

import java.util.*;

import org.jscience.physics.amount.* ;

import javax.measure.quantity.* ;

/**

* The dynamic data for a simulation at a

given time.

*

* This includes the values of every state

variable at a given time.

* The values are stored in a format

appropriate for the solvers.

*

* DISCUSS: Constituent type for

variables; either

* 1. Amount<?> which is consistent

with the external packages interfaces

* providing domain specific typing.

* 2. Float64 which will give more

efficient calculations and storage.

*

* @author [email protected]

*

*/

public class SimData {

double time ;

int size;

double start;

double stepsize;

double stop;

/*

* Initialize as Vector type as Double

* To avoid NullPointerException error

*/

Vector<Double> x = new

Vector<Double>();

Vector<Double> xdot = new

Vector<Double>() ;

Vector<Double> m ;

Vector<Double> z ;

public SimData( int xdim, int mdim, int

zdim )

{

// simulation default settings

size = xdim;

start = 0.0;

stepsize = 0.002;

stop = 1.0;

// this.x = new Float64Vector( xdim

) ;

// this.xdot = new Float64Vector(

xdim ) ;

// this.m = new Float64Vector( mdim

) ;

// this.z = new Float64Vector( zdim ) ;

}

/**

* Advance to next time step, advancing

time by dt.

*

* @param dt

* @return

*

*/

public void advance( double dt ) {

time = time+dt;

}

/**

* Get the continuous state vector.

*

* The state is returned as a Float64

vector for efficiency.

*/

public Vector<Double> getState() {

return x ;

}

/**

* Get the discrete state vector.

*

* The state is returned as a Float64

vector for efficiency.

*/

public Vector<Double> getDiscrete() {

return m ;

Page 103: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

103

}

/**

* Get the event indicators.

*

* The state is returned as a Float64

vector for efficiency.

*/

public Vector<Double>

getEventIndicators() {

return z ;

}

/**

* Get the continuous state derivative

vector.

*

* The state is returned as a Float64

vector for efficiency.

*/

public Vector<Double> getDer() {

return xdot ;

}

/**

* Get current time.

*/

public double getTime() {

return time ;

}

/**

* Set the continuous state vector and

update time.

*

* @param x

* @param dt

*/

public void updateState(

Vector<Double> x ) {

this.x = x ;

}

}

EulerSolver.Java

package jrt;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.util.Vector;

import org.jscience.mathematics.vector.* ;

import org.jscience.physics.amount.* ;

import javax.measure.quantity.* ;

/**

* Euler's method for numerical

integration.

*

* @author [email protected]

*

*/

public class EulerSolver {

static BufferedWriter bw ;

/**

* Solve the system using Euler's

method.

*

* @param dt

* @param data

* @param model

* @throws IOException

*/

public static void main (double dt,

SimData data, SuperModel model, String

filename) throws IOException

{

FileWriter fw = new

FileWriter( filename );

bw = new BufferedWriter(fw);

long startSimulationTime =

System.currentTimeMillis();

Vector<Double> x =

data.getState() ;

Vector<Double> xdot =

data.getDer() ;

bw.write(data.start+ ",");

for (int i =0;i<x.size();i++)

bw.write(data.getState().elementAt(i).toStr

ing()+",");

for (int i =0;i<xdot.size();i++)

{

Page 104: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

104

bw.write(data.getDer().elementAt(i).toStri

ng());

if ( i != (xdot.size())-1)

bw.write( "," ) ;

}

bw.newLine() ;

while(data.time < data.stop){

Solver(data,model,dt);

CSVBuilder(data);

}

long endSimulationTime =

System.currentTimeMillis(); // end

simulation time measurements

System.out.println("starttime:"+

startSimulationTime + "endtime:" +

endSimulationTime );

System.out.println("Simulation

took: " + (endSimulationTime -

startSimulationTime)+ " milliseconds.\n");

bw.close() ;

}

public static void Solver( SimData

data ,SuperModel model, double dt )

throws IOException {

Vector<Double> x =

data.getState() ;

Vector<Double> xdot =

data.getDer() ;

for(int i=0;i<x.size();i++)

{

x.set(i, x.get(i)+

xdot.get(i)*dt);

}

data.advance( dt ) ;

model.functionODE();

}

public static void

CSVBuilder(SimData data) throws

IOException {

bw.write(data.time + ",");

int n = data.size;

for( int i=0 ; i < n ; i++ ) {

bw.write(data.getState().elementAt(i).toStr

ing()+",");

//

bw.write(data.getState().toString()+",");

bw.write(data.getDer().elementAt(i

).toString());

if ( i != n-1 )

bw.write( ", " ) ;

}

bw.newLine() ;

}

}

SuperModel.Java

package jrt;

import java.io.IOException;

import org.jscience.physics.amount.* ;

import javax.measure.quantity.* ;

/**

* A Modelica Model for simulation.

*

* This is the superclass for any model

class generated from modelica.

* As the core of the Modelica model, this

class needs properties similar

* to those of FMI for model exchange.

* Other features can be wrapped around

SuperModel objects, such as the

* SimModel class which provides features

comparable to FMI for cosimulation.

*

* A SuperClass object has two major

components, namely a StaticModel

* object for static information about the

model and a SimData object

* for the dynamic variable values.

*

* Comparing to the C code generation,

* SIMULATION_INFO is covered by

this class.

* SIMULATION_DATA is covered by

the SimData class.

Page 105: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

105

* MODEL_DATA is covered by the

StaticModel class.

*

* @author [email protected]

*

*/

public abstract class SuperModel {

private StaticModel model ;

private SimData data ;

private Amount<Duration> time ;

private Boolean initialised=false ;

/* MAIN INTERFACE METHODS */

/**

* Constructor.

*

* @param m The static model to be

simulated

*/

SuperModel( ) {

}

/**

* Initialise the object.

* This should always be called once

before any other method.

*/

public void init() {

if ( this.initialised ) return ;

this.data = new SimData(

model.xdim(), model.mdim(),

model.zdim() ) ;

}

/** Getter for the SimData object.

*/

public SimData getData() {

return this.data ;

}

/**

* Generic getter, taking the identifier of

a variable as argument.

*

* The result is returned as a JScience

Amount object, making sure

* that it has a defined quantity and is

unit independent.

*

* @param s

* @return

*/

public Amount<?> getValue( String s )

{

throw new RuntimeException(

"Not implemented yet" ) ;

}

/**

* Generic setter, using the variable

identifier as a String.

*

* The value is given as a JScience

Amount object, making sure

* it has a defined quantity and is

independent of unit.

*

* @param s

* @param a

*/

public void setValue( String s,

Amount<?> a ) {

throw new RuntimeException(

"Not implemented yet" ) ;

}

/**

* Solve the model for the next time

step, advancing time by dt.

*

* @param dt

*

*/

public void advance(

Amount<Duration> dt ) {

time = time.plus(dt) ;

}

/**

* This corresponds to the functionODE

function which is

* code generated in the case of C.

Investigate.

*

Page 106: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

106

* Should this be protected?

*/

public abstract void functionODE() ;

/* public Amount<Duration> getTime()

{

return data.getTime() ;

}*/

}

StaticModel.Java

package jrt;

import java.util.ArrayList;

/**

* A ModelicaModel with its static

information.

*

* The static model includes comments and

descriptions of the

* variables as well as range, initialisation

values, etc.

* It does not include any information

about simulation of the

* model.

*

* Essentially, the StaticModel is a

collection of ModelicaVariabel

* and ModelicaEquation objects.

*

* @author [email protected]

*

*/

public class StaticModel {

private ArrayList<ModelicaVariable>

variables ;

private ArrayList<ModelicaEquation>

equations ;

StaticModel() {

variables = new

ArrayList<ModelicaVariable>() ;

equations = new

ArrayList<ModelicaEquation>() ;

}

/**

* Add the given variable to the model.

*

* @param v

*/

public void addVariable(

ModelicaVariable v ) {

variables.add(v) ;

}

/**

* Add the given equation to the model.

* @param e

*/

public void addEquation(

ModelicaEquation e ) {

equations.add(e) ;

}

public int mdim() {

throw new RuntimeException() ;

}

public int xdim() {

throw new RuntimeException() ;

}

public int zdim() {

throw new RuntimeException() ;

}

ModelicaVariable.Java

package jrt;

/**

* Static information about a single

variable in the model.

*

* This represents a single variable in the

model and records

* static information.

*

* @author georg

*

*/

public abstract class ModelicaVariable {

// The following three come from

VAR_INFO in the C code.

private int id ;

private String name ;

Page 107: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

107

private String comment ;

// We should also have a file info

field for diagnostics.

/**

* Return the ID of the variable.

*

* @return

*/

public int get_id() {

return id ;

}

/**

* Return the name of the variable.

*

* @return

*/

public String get_name() {

return name ;

}

/**

* Return the descriptive comment.

*

* @return

*/

public String get_comment() {

return comment ;

}

}

ModelicaVariable.Java

package jrt;

/**

* A single equation in the modelica

model.

*

* @author georg

*

*/

public class ModelicaEquation {

}

Page 108: Institutionen för datavetenskap - DiVA portalliu.diva-portal.org/smash/get/diva2:742308/FULLTEXT01.pdfInstitutionen för datavetenskap Department of Computer and Information Science

Linköping University Electronic Press

Upphovsrätt

Detta dokument hålls tillgängligt på Internet – eller dess framtida ersättare –från

publiceringsdatum under förutsättning att inga extraordinära omständigheter

uppstår.

Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner,

skriva ut enstaka kopior för enskilt bruk och att använda det oförändrat för icke-

kommersiell forskning och för undervisning. Överföring av upphovsrätten vid

en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning av

dokumentet kräver upphovsmannens medgivande. För att garantera äktheten,

säkerheten och tillgängligheten finns lösningar av teknisk och administrativ art.

Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman i

den omfattning som god sed kräver vid användning av dokumentet på ovan be-

skrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådan form

eller i sådant sammanhang som är kränkande för upphovsmannens litterära eller

konstnärliga anseende eller egenart.

För ytterligare information om Linköping University Electronic Press se för-

lagets hemsida http://www.ep.liu.se/

Copyright

The publishers will keep this document online on the Internet – or its possible

replacement –from the date of publication barring exceptional circumstances.

The online availability of the document implies permanent permission for

anyone to read, to download, or to print out single copies for his/hers own use

and to use it unchanged for non-commercial research and educational purpose.

Subsequent transfers of copyright cannot revoke this permission. All other uses

of the document are conditional upon the consent of the copyright owner. The

publisher has taken technical and administrative measures to assure authenticity,

security and accessibility.

According to intellectual property law the author has the right to be

mentioned when his/her work is accessed as described above and to be protected

against infringement.

For additional information about the Linköping University Electronic Press

and its procedures for publication and for assurance of document integrity,

please refer to its www home page: http://www.ep.liu.se/.

© MANOKAR MUNISAMY