Sei sulla pagina 1di 135

ET-Ph.D. 2000-04. June 2001.

WinDali
A Modeling and Simulation System for
Microsoft Windows
Version 2.10

MORTEN JUEL SKOVRUP

DEPARTMENT OF MECHANICAL ENGINEERING


TECHNICAL UNIVERSITY OF DENMARK
Contents i

Contents
1 Disclaimer ...................................................................................................................1
1.1 Contact information ............................................................................................................................ 1

2 Version information....................................................................................................3

3 Introduction.................................................................................................................5
3.1 Typing convention .............................................................................................................................. 6
3.2 Terms used in this document ............................................................................................................. 7

4 System structure ........................................................................................................9

5 Creating a simple model ..........................................................................................11


5.1 SetUpProblem .................................................................................................................................. 15
5.2 ModelEquations ................................................................................................................................ 17
5.3 EndCalc ............................................................................................................................................ 17
5.4 Compiling.......................................................................................................................................... 19
5.5 Simulation ......................................................................................................................................... 19

6 Model file format .......................................................................................................23


6.1 Common parameters........................................................................................................................ 25
6.2 SetUpProblem .................................................................................................................................. 26
6.2.1 SolverSettings ........................................................................................................................... 26
6.2.2 Dynamic variables ..................................................................................................................... 27
6.2.3 States ........................................................................................................................................ 28
6.2.4 Static variables .......................................................................................................................... 28
6.2.5 Parameter pages ....................................................................................................................... 30
6.2.6 Initial Parameters....................................................................................................................... 30
6.2.7 Floating point parameters.......................................................................................................... 30
6.2.8 Integer parameters .................................................................................................................... 32
6.2.9 Boolean parameters .................................................................................................................. 33
6.2.10 List parameters........................................................................................................................ 33
6.2.11 Enumerated parameters.......................................................................................................... 34
6.2.12 Enumerated choice parameters .............................................................................................. 35
6.2.13 Extra variables......................................................................................................................... 37
6.2.14 Action buttons.......................................................................................................................... 37
6.2.15 Info Labels ............................................................................................................................... 38
6.2.16 HideSampleTime ..................................................................................................................... 38
6.2.17 Model help file ......................................................................................................................... 39
6.3 PreCalc ............................................................................................................................................. 39
6.3.1 SetStartState ............................................................................................................................. 39
6.3.2 AddExtraVar .............................................................................................................................. 40
6.3.3 SetSampleTime ......................................................................................................................... 40
6.4 ModelEquations ................................................................................................................................ 40
6.5 StateShift .......................................................................................................................................... 42
6.6 OnStateChange ................................................................................................................................ 44
6.7 OnSolution ........................................................................................................................................ 44
6.8 OnSample......................................................................................................................................... 44
6.9 EndCalc ............................................................................................................................................ 45
6.10 OnQuit ............................................................................................................................................ 45

WinDali Morten Juel Skovrup


ii Contents

6.11 OnUIValueChange.......................................................................................................................... 45
6.11.1 Running simulations from the model ....................................................................................... 47
6.12 OnSaveSettings .............................................................................................................................. 49
6.13 OnLoadSettings .............................................................................................................................. 49
6.14 Using Initial parameters .................................................................................................................. 49
6.14.1 SetInitial ................................................................................................................................... 52
6.14.2 SetGuess ................................................................................................................................. 52
6.14.3 AddDynVar............................................................................................................................... 52
6.14.4 AddStatVar............................................................................................................................... 53
6.15 Mathematical text............................................................................................................................ 54
6.16 Debugging....................................................................................................................................... 55

7 Component file format ............................................................................................. 57


7.1 Connectors........................................................................................................................................ 57
7.2 Components...................................................................................................................................... 58
7.2.1 Constructor ................................................................................................................................ 58
7.2.1.1 Specification of states......................................................................................................... 59
7.2.1.2 Connectors.......................................................................................................................... 62
7.2.1.3 Static variables ................................................................................................................... 63
7.2.2 ModelEquations ......................................................................................................................... 64
7.2.3 StateShift ................................................................................................................................... 64
7.2.4 PreCalc ...................................................................................................................................... 65
7.2.5 Example ..................................................................................................................................... 66
7.3 Sources and sinks............................................................................................................................. 70
7.4 Signals .............................................................................................................................................. 71
7.5 Controllers......................................................................................................................................... 71
7.6 Systems ............................................................................................................................................ 71
7.7 Documentation .................................................................................................................................. 79

8 Common problems................................................................................................... 81

9 Using refrigerant equations .................................................................................... 83

10 Free Pascal Editor .................................................................................................. 85


10.1 Project Options ............................................................................................................................... 88
10.2 Environment Options ...................................................................................................................... 90

11 Simulation program ............................................................................................... 95


11.1 Menu commands ............................................................................................................................ 98
11.2 Online parameters .......................................................................................................................... 99
11.3 Varying parameters....................................................................................................................... 100
11.4 Dali solver ..................................................................................................................................... 104

12 Distributing models.............................................................................................. 105

13 Programmers guide ............................................................................................. 107


13.1 Using other programming languages to create the model file ...................................................... 107
13.2 General notes on programming with mixed languages ................................................................ 108
13.3 Solver file format ........................................................................................................................... 108
13.3.1 InstallSolver ........................................................................................................................... 109
13.3.2 SolverCaps ............................................................................................................................ 110

WinDali Morten Juel Skovrup


Contents iii

13.3.3 Stop ....................................................................................................................................... 111


13.3.4 Solve...................................................................................................................................... 111

14 References ............................................................................................................115

Appendix A Used file types ......................................................................................117

Appendix B Procedures ............................................................................................119


B.1 Procedures called in SetUpProblem .............................................................................................. 119
B.2 Procedures called in PreCalc......................................................................................................... 120
B.3 Procedures called in OnUIValueChange ....................................................................................... 120

Appendix C Component modeling files...................................................................121


C.1 TmjsSystemModel ......................................................................................................................... 121
C.2 TmjsComponentModel................................................................................................................... 123
C.3 TmjsSource, TmjsSink and TmjsController ................................................................................... 126

Appendix D List of demos ........................................................................................127

Appendix E Shortcuts ...............................................................................................129

WinDali Morten Juel Skovrup


1 Disclaimer 1

1 Disclaimer
This software is freeware. You may freely copy and use it without any charge. This software
must not be sold for profit, nor may it be used as part of commercial software.

If you are developing software intended for commercial use, you can’t use this package or our
name without written permission (i.e. we have to work out a contract).

This software is provided “as is” and any express or implied warranties, including, but not
limited to, the implied warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall Department of Mechanical Engineering or any person mentioned in
this document be liable for any direct, indirect, incidental, special, exemplary, or consequential
damages (including, but not limited to, procurement of substitute goods or services; loss of use,
data, or profits; or business interruption) however caused and on any theory of liability, whether
in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.

1.1 Contact information


Morten Juel Skovrup
Assistant Research Professor

Department of Mechanical Engineering


Technical University of Denmark
Nils Koppels Allé
Building 402
DK-2800 Lyngby
DENMARK

Phone: +45 45 25 41 20
Fax: +45 45 93 52 15
e-mail: ms@mek.dtu.dk
Web: http://www.et.dtu.dk

WinDali Morten Juel Skovrup


2 1 Disclaimer

WinDali Morten Juel Skovrup


2 Version information 3

2 Version information
Changes in version 2.10.

The model file format has changed. This means that models build with previous versions have to
be changed to make them work in version 2.10. Note that the changes do not affect the
component file format, i.e. models created using components do not have to be changed.

The changes all have to do with specifying the number of variables and parameters. It is no
longer required (in fact it is not possible) to specify the number of for example dynamic
variables by calling SetNumDynamic. The number of dynamic variables are automatically
counted when you call AddDynamic. The same apply for parameters.

More precisely the following functions are obsolete:

SetNumActionBtns(Num : Integer);
SetNumBoolParams(Num : Integer);
SetNumChoice(EnumParam,ItemIndex,Num : Integer);
SetNumDynamic(Num : Integer);
SetNumEnumChoiceParams(Num : Integer);
SetNumEnumParams(Num : Integer);
SetNumExtra(Num : Integer);
SetNumFloatParams(Num : Integer);
SetNumInfoLabels(Num : Integer);
SetNumInitialParams(Num : Integer);
SetNumIntParams(Num : Integer);
SetNumListParams(Num : Integer);
SetNumStatic(StateNum,NumStatic : Integer);

And all the Add... functions have been changed, so that you no longer have to pass the variable
number in the function call. For example:

AddFloatParam(Num : Integer;var Parameter : Double;DefaultValue : Double;


Name : PChar;ParamPage : Integer);

Has been changed to:

AddFloatParam(var Parameter : Double;DefaultValue : Double;


Name : PChar;ParamPage : Integer);

See the details under the different functions in chapter 6.

WinDali Morten Juel Skovrup


4 2 Version information

WinDali Morten Juel Skovrup


3 Introduction 5

3 Introduction
WinDali is a modeling and simulation system for Microsoft Windows™ 95, 98, NT 4.0 or later.
The basic features of the system are:

• Solves a system of semi-explicit differential algebraic equations (DAE’s).


• Solves initial value problems.
• Handles discontinuities.
• Equation based modeling.
• Component modeling
• Graphical simulation program.
• Creates distributable files (exe-files).
• Models can be created in practical any programming language (Pascal, C++, Fortran...).
• A user-supplied solver may replace the accompanying equation solver.
• It is freeware.

These issues will be covered in depth in the following chapters.

Examples in this document are included in the \Windali\Projects\Demo directory.

WinDali consists of two programs:


1. Free Pascal Editor, in which the models are formulated – note that you can use Borland
Delphi™, Microsoft Visual C++™ or another programming environment instead.
2. Simulation, in which the models are loaded, and the simulation performed.

An important limitation in this version of WinDali is that it only handles semi-explicit DAE’s.
This means that WinDali only can solve problems on the form:
dy
= f ( t , x, y , p )
dt (3.1)
0 = g (t , x, y, p, s )

The main reason for this limitation is that the solver that comes with this version has this
limitation. A future release will include possibility to formulate implicit problems:
 dy 
0 = f  t , x, y , , p
 dt  (3.2)
0 = g (t , x, y, p, s )

The notation used in equation (3.1) and (3.2), and the terms used in the rest of this document will
be explained in the following.

WinDali Morten Juel Skovrup


6 3 Introduction

3.1 Typing convention


This report contains some examples written in source-code. The examples are all written in the
programming language Object Pascal [3]. When this is the case the following typeface is used:

Item Example of typeface:


Source code constructor TOneObject.Create;
var
AStr : string;
ANum : Integer;
begin
AStr := 'This is a string - next is a number';
ANum := 10;
end;
Source code in text This is an example of source code in normal text

WinDali Morten Juel Skovrup


3 Introduction 7

3.2 Terms used in this document


Term Explanation
Dynamic variables Variables that appears differentiated (with respect to time) in the
equations. The symbol y will be used for dynamic variables.
Static variables Variables that do not appear differentiated in the equations. The symbol x
will be used for static variables.
Independent The variable that y is differentiated with respect to. Normally this equals
variable time, and the symbol t is used for the independent variable.
Parameters Quantities that are set to a constant before simulation. The symbol p will
be used for parameters.
States For example a valve may be in on of two states: Open or Closed. These
logical states will normally change the equations describing the physical
system. The number of logical states for a model is the number of different
sets of equations used to define the model. The symbol s will be used for
states.
Discontinuities Discontinuities are a way to describe abrupt changes in the physical
system that is modeled. For example, by describing the process of a valve
suddenly closing as a discontinuity, one avoids describing in detail the
valve position while it closes. A discontinuity indicates that the physical
system shifts to another logic state. So describing abrupt changes as
discontinuities involves a description of the possible states of the physical
system. The conditions causing the change of logical state must also be
formulated.
Initial value A problem where the present state of the system is known, and the future
problems state is to be determined. Problems that can be formulated as initial value
problems can be solved by WinDali (note that initial value problems does
not in general require that the independent variable is time).
DAE Differential Algebraic Equation. An equation system that consists of both
an ordinary differential equation and an algebraic equation, for example:
dy
=x
dt
x = x+ y
Solver The numeric code that solves the system of DAE’s. The solver integrates
the differential equations, solves the algebraic equations and is handling
discontinuities.

WinDali Morten Juel Skovrup


8 3 Introduction

WinDali Morten Juel Skovrup


4 System structure 9

4 System structure

Free Pascal

Component
Borland Delphi ®
file format

C++

System
Compiler
modelling

Free Pascal

Borland Delphi ®

Model file
C
format

C++

Fortran

Simulation
Compiler DLL
program

DLL

Solver file
Compiler
format

Figure 1. Structure of modeling system

Figure 1 shows the structure of the simulation system. At present the model is created in Free
Pascal Editor (or some other programming tool). The principle behind the structure of the
simulation system is that all modules, or boxes in Figure 1, should be replaceable. The shadowed
boxes in the structure are file formats or protocols that specify the interface between the other
modules, i.e. when for example the structure of the Model file is fixed, third party programs
could replace everything below and above the Model file box. Another important feature is that
the solver is replaceable.

WinDali Morten Juel Skovrup


10 4 System structure

The boxes labeled Compiler are responsible for converting a file to some binary representation.
In practice the boxes represents standard available compilers, capable of building Windows
DLL’s (Dynamic Link Libraries).

The different modules in Figure 1 has the following meaning:

Module Explanation
Component file format A file format specifying the information a component should be able
to provide to the System modeling module. In practice this will be a
specification of the functions a component should make available to
the System modeling module.
System modeling An application with a Graphical User Interface (GUI) where
components can be connected to form a model of a system.
Model file format A file written in a standard programming language with a specified
interface to the Simulation module.
Simulation program A GUI application which is displaying the results of a simulation to
the user as Graphs, animations, numbers, etc.
Solver The numerical code which is solving the equations specified in the
Model file.
Solver file format A file format with a specified interface understood by the Simulation
module.

In the current release of WinDali, the user starts at the model file or component file level,
specifying the model in a standard programming language. With the program comes a Pascal
compiler, which is freeware, but other programming languages can be used, as explained in
chapter 13.

WinDali Morten Juel Skovrup


5 Creating a simple model 11

5 Creating a simple model


This chapter describes the process of creating a simple model in Free Pascal Editor. Only the
basic features in the Model file format will be described, the details are left to chapter 6.

Suppose you want to cool a block of some material, as showed in Figure 2:

h, A
Ta

Q
ρ ,V , c p , T

Figure 2. Cooling a block of some material

The block has density ρ, volume V, specific heat cp and temperature T. The block is exposed to
the ambient temperature Ta (constant) and has the surface area A. The heat transfer coefficient
between the block and the surroundings is h (constant), and it is assumed that the block has a
spatial uniform temperature at all times. This assumption is also known as the lumped
capacitance method, and the error introduced by the assumption is small if the Biot number is
less than 0.1.

The Biot number is defined as:


h Lc
Bi = (5.1)
λ
Where Lc is a characteristic length calculated as Lc = V A and λ is the conductivity of the
material.

The energy balance for the problem is:


dT
ρVc p = h A (Ta − T ) (5.2)
dt
For this problem there is one dynamic variable T and 7 parameters ρ , V , c p , h, A, Ta and λ (we
will also calculate the Biot number to evaluate the uniform temperature assumption)

To create the model file you have to go through the following steps:

1. Open Free Pascal Editor


2. Select File|New
3. Select the Basic Model icon

This will bring up the following dialog:

WinDali Morten Juel Skovrup


12 5 Creating a simple model

Figure 3. Create project dialog

Here you specify the name of your project and the directory where your files should be located.
As default the program selects the Project directory, which is located in the directory where you
installed WinDali. For now input “Test” as the project name, and add “\TestDir” to the default
project directory:

Figure 4. Create project dialog - continued

This will create a basic Model file project:

WinDali Morten Juel Skovrup


5 Creating a simple model 13

Figure 5. Free Pascal Editor

Go to the project manager window and double click on Problem.pp. This will bring up the file
where you specify your problem in the Code Editor. The file Test.pp is the main file in your
project, and you should not edit it.

The Problem.pp file looks like this:

WinDali Morten Juel Skovrup


14 5 Creating a simple model

unit Problem;

interface

uses
mjsDLLTypes;

procedure SetUpProblem; export; stdcall;


procedure ModelEquations(Time : Double; State : Integer;
var R : array of Double;
var YDot : array of Double); export; stdcall;
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); export; stdcall;
procedure OnStateChange(Time : Double; OldState,NewState : Integer);
export; stdcall;
procedure PreCalc(Time : Double; State : Integer); export; stdcall;
procedure OnSolution(Time : Double; State : Integer); export; stdcall;
procedure OnSample(Time : Double; State : Integer); export; stdcall;
procedure EndCalc(Time : Double; State : Integer); export; stdcall;
procedure OnQuit; export; stdcall;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer;
Value : Double); export; stdcall;
procedure OnSaveSettings(FileName : PChar); export; stdcall;
procedure OnLoadSettings(FileName : PChar); export; stdcall;

implementation

procedure SetUpProblem; stdcall;


begin
end;

{R and YDot is zero-based}


procedure ModelEquations(Time : Double; State : Integer;
var R : array of Double;
var YDot : array of Double); stdcall;
begin
end;

{G is zero-based}
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); stdcall;
begin
end;
procedure PreCalc(Time : Double; State : Integer); stdcall;
begin
end;
procedure OnStateChange(Time : Double; OldState,NewState : Integer);
stdcall;
begin
end;
procedure OnSolution(Time : Double; State : Integer); stdcall;
begin
end;
procedure OnSample(Time : Double; State : Integer); stdcall;
begin
end;

WinDali Morten Juel Skovrup


5 Creating a simple model 15

procedure EndCalc(Time : Double; State : Integer); stdcall;


begin
end;
procedure OnQuit; stdcall;
begin
end;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer;
Value : Double); stdcall;
begin
end;
procedure OnSaveSettings(FileName : PChar); stdcall;
begin
end;
procedure OnLoadSettings(FileName : PChar); stdcall;
begin
end;

end.

The task is now to fill out the 12 procedures defined in Problem.pp. The procedures and the
functions you can call are described in detail in chapter 6. For the simple problem at hand you
only have to worry about SetUpProblem, ModelEquations and EndCalc.

First you have to define the variables and parameters so Free Pascal knows about them. This is
done by writing the following right after implementation:

implementation
var
T : Double;
Rho,Cp,Lambda,V,A,h,Ta,Bi : Double;

5.1 SetUpProblem
In the procedure SetUpProblem you have to tell the system about the variables, parameters and
states in your problem. This also specifies the user-interface of the Simulation program.

You tell the system about your problem by calling a number of predefined functions. The ones
you need to know about for this simple problem will be shortly explained (details are given in
chapter 6).

SolverSettings(Title : PChar; TStart,TEnd,TimeFac : Double;


ShowStartState : WordBool; StartState : Integer);
This function specifies the title of your problem, the time you want to simulate and the
state of the problem when the simulation starts. For this simple problem, lets say that you
want to simulate 1000 seconds and as there is only one state of the system, StartState
should be 1. So you should call SolverSettings like this (just set TimeFac to 1 and
ShowStartState to true for now):
SolverSettings('Simple problem',0,1000,1,True,1);

WinDali Morten Juel Skovrup


16 5 Creating a simple model

SetStates(Names : PChar);
SetStates specifies the number of states and the names of the states. As there is only
one state – let us call if Default – you should call SetStates like this:
SetStates('Default');

SetParamPages(Names : PChar);
This function only influence on how the user interface in the simulation program looks. It
creates pages where parameters can be grouped. This will become more clear when you
see the result in the Simulation program. For now just create one page with the name
“Parameters”:
SetParamPages('Parameters');

AddDynamic(Num : Integer; var Variable : Double; InitalValue : Double;


Name,LongName : PChar);
This function is used to specify detailed information about each of the dynamic variables
in the problem. The individual parameters are explained in detail in chapter 6. There is
only one dynamic variable and lets say the initial value is 100 °C:
AddDynamic(T,100,'T','Temperature [°C]');

AddFloatParam(var Parameter : Double; DefaultValue : Double;


Name : PChar; ParamPage : Integer);
Specify detailed information on each of the floating-point parameters. The individual
parameters in the function call are explained in detail in chapter 6:
AddFloatParam(Rho,8000,'Density [kg/m^3]',1);
AddFloatParam(Cp,480,'Specific heat [J/kg K]',1);
AddFloatParam(Lambda,15,'Conductivity [W/m K]',1);
AddFloatParam(V,0.001,'Volume [m^3]',1);
AddFloatParam(A,0.06,'Surface area [m^2]',1);
AddFloatParam(h,10,'Heat transfer coefficient [W/m^2 K]',1);
AddFloatParam(Ta,20,'Ambient temperature [°C]',1);

AddExtra(var Variable : Double; Name : PChar;


DoPlot : WordBool);
Specify detailed information about extra values:
AddExtra(Bi,'Biot number',False);

This completes the SetUpProblem procedure.

WinDali Morten Juel Skovrup


5 Creating a simple model 17

5.2 ModelEquations
In ModelEquations you specify the equations. The heading looks like this:

procedure ModelEquations(Time : Double; State : Integer;


var R : array of Double;
var YDot : array of Double);

This procedure is called every time the solver needs to do calculations on your model. The
parameters in the procedure heading are:
• Time The current simulation time (in seconds)
• State The current state (as there is only one state in this example, this will always be
equal to 1)
• R A zero-based vector where you should return a residual for each of the static
equations in your model. As there are no static equations in this model, R can be ignored.
• YDot A zero-based vector where you should return the derivatives of the dynamic
variables in your model.

A zero-based vector means that the first place in the vector is indexed 0, the second place 1 and
so on. For the simple model there is only 1 dynamic variable and no static variables. Note that
because of the registration of the dynamic variable and the parameters (through calls to
AddDynamic and AddFloatParam), the Pascal variables T,Rho,Cp,Lambda,V,A,h and Ta will
always have the correct and updated values when ModelEquations is called.

If equation (5.2) is arranged so the derivative is isolated, the programming ModelEquations of


is straightforward:
dT hA
= (Ta − T ) (5.3)
d t ρ V cp

procedure ModelEquations(Time : Double; State : Integer;


var R : array of Double;
var YDot : array of Double);
begin
YDot[0] := h*A/(Rho*V*Cp)*(Ta-T);
end;

This concludes the ModelEquations procedure.

5.3 EndCalc
EndCalc is called once at the end of the simulation. The only thing left to be calculated is the
Biot number:

procedure EndCalc(Time : Double; State : Integer);


begin
Bi := h*V/(A*Lambda);
end;

WinDali Morten Juel Skovrup


18 5 Creating a simple model

In full the file Problem.pp looks like this:


unit problem;

interface

uses
mjsDllTypes;

procedure SetUpProblem; export; stdcall;


procedure ModelEquations(Time : Double; State : Integer;
var R : array of Double;
var YDot : array of Double); export; stdcall;
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); export; stdcall;
procedure OnStateChange(Time : Double; OldState,NewState : Integer);
export; stdcall;
procedure PreCalc(Time : Double; State : Integer); export; stdcall;
procedure OnSolution(Time : Double; State : Integer); export; stdcall;
procedure OnSample(Time : Double; State : Integer); export; stdcall;
procedure EndCalc(Time : Double; State : Integer); export; stdcall;
procedure OnQuit; export; stdcall;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer;
Value : Double); export; stdcall;
procedure OnSaveSettings(FileName : PChar); export; stdcall;
procedure OnLoadSettings(FileName : PChar); export; stdcall;

implementation

var
T : Double;
Rho,Cp,Lambda,V,A,h,Ta,Bi : Double;

procedure SetUpProblem; stdcall;


begin
SolverSettings('Simple problem 1',0,1000,1,True,1);
SetStates('Default');
SetParamPages('Parameters');
AddDynamic(T,100,'T','Temperature [°C]');
AddFloatParam(Rho,8000,'Density [kg/m^3]',1);
AddFloatParam(Cp,480,'Specific heat [J/kg K]',1);
AddFloatParam(Lambda,15,'Conductivity [W/m K]',1);
AddFloatParam(V,0.001,'Volume [m^3]',1);
AddFloatParam(A,0.06,'Surface area [m^2]',1);
AddFloatParam(h,10,'Heat transfer coefficient [W/m^2 K]',1);
AddFloatParam(Ta,20,'Ambient temperature [°C]',1);
AddExtra(Bi,'Biot number',False);
end;

{R and YDot is zero-based}


procedure ModelEquations(Time : Double; State : Integer;
var R : array of Double;
var YDot : array of Double); stdcall;
begin
YDot[0] := h*A/(Rho*V*Cp)*(Ta-T);
end;
{G is zero-based}

WinDali Morten Juel Skovrup


5 Creating a simple model 19

procedure StateShift(Time : Double; State : Integer;


var G : array of Double); stdcall;
begin
end;
procedure PreCalc(Time : Double; State : Integer); stdcall;
begin
end;
procedure OnStateChange(Time : Double; OldState,NewState : Integer);
stdcall;
begin
end;
procedure OnSolution(Time : Double; State : Integer); stdcall;
begin
end;
procedure OnSample(Time : Double; State : Integer); stdcall;
begin

end;
procedure EndCalc(Time : Double; State : Integer); stdcall;
begin
Bi := h*V/(A*Lambda);
end;
procedure OnQuit; stdcall;
begin
end;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer;
Value : Double); stdcall;
begin
end;
procedure OnSaveSettings(FileName : PChar); stdcall;
begin
end;
procedure OnLoadSettings(FileName : PChar); stdcall;
begin
end;
end.

5.4 Compiling
Now it is time to compile the model. Select the Run|Compile menu and note if there is any error
messages in the Message window. If you have made an error you can double-click it in the
Message window and the error will be highlighted in your code. If no errors occurred you can
run a simulation by selecting the Tools|Simulation menu. The resulting model file will have the
extension “.mdl”.

5.5 Simulation
When you select the Tools|Simulation menu in Free Pascal Editor you start the simulation
program. If the model file was created exactly as described above, you will see the following
screen:

WinDali Morten Juel Skovrup


20 5 Creating a simple model

Figure 6. The Simulation program

The function calls made in SetUpProblem is reflected in the Solver & Model settings page
control. The only pages the simulation program automatically creates is the General, Cases and
Solver pages, the rest is created depending on the function calls made in SetUpProblem (pages
created automatically by the simulation program are marked with “ ” as shown in Figure 6).

In the General page the simulation time and initial state can be set by the user (i.e. the values
specified in the call to SolverSettings was only default values).

The rest off the values in the General, Cases and Solver pages will be explained in chapter 11.

To start the simulation, select the menu Simulation|Start or press the <Play> button on the
toolbar. In either case the result should look like this:

WinDali Morten Juel Skovrup


5 Creating a simple model 21

Figure 7. Simulation result.

This shows that the simulation time was to short. Try increasing the simulation end-time to for
example 1 day, and run the simulation again.

WinDali Morten Juel Skovrup


22 5 Creating a simple model

WinDali Morten Juel Skovrup


6 Model file format 23

6 Model file format


A model file has 12 procedures, which the user should fill out to specify the problem to be
solved. The following figure shows the sequence in which the procedures are called from the
simulation program:

1)
Load
Model

2)
SetUpProblem

3) Start

4)
PreCalc

14)
OnSolution

18)
5) Yes 19) OnSolution
Stop EndCalc
13)
ModelEquations
No
17) OnSample
6) ModelEquations
12)
OnStateChange No Yes

16)
Sample time?
7)
StateShift
11)
OnSolution

15) OnSolution
No
10) OnSample

No Yes

9)
Sample time?

Yes
8) OnSolution

Figure 8. Calling sequence for the procedures in the model file.

The rounded rectangles in Figure 8 represent user-actions in the Simulation program.

WinDali Morten Juel Skovrup


24 6 Model file format

Note that the boxes 6 and 7 in general are called several times at each time step. This is because
the solver iterates to find a solution. The procedure OnQuit, which is not represented in figure 8,
is called when the user closes the simulation program or selects another model. The procedures
OnUIValueChange, OnSaveSettings and OnLoadSettings all have to do with controlling the
user-interface. They will be explained later.

The calling sequence with no state shift (branch 5-6-7-15-16-(17-18)) is straightforward (for now
ignore the branches regarding Sample time – they will be covered in chapter 6.8). But the calling
sequence with a state shift needs some explanation.

Lets say that we want to model a valve that is On when a temperature T is above 10°C, else it is
Off. We want to record the temperature and the On-Off signal to the valve, and the initial
temperature is 20°C. A plot of the temperature and the On-Off signal would look like this:

20°C

T
10°C

On 14

Off 8

t1 t2
Figure 9. Temperature and On-Off signal.

When the solver reaches t2 where the valve goes On, it first calls OnSolution (block 8) to inform
the model file that a solution has been found. But at t2 the equation system also shift state, which
means that the solver has to start all over, and possibly with a new set of static equations.

The static equations have to be solved before the solver continues, and for this the solver needs
guesses on the static variables.

In SetUpProblem (as will be clear in chapter 6.2) default guesses on the static variables are given
for each state, but if these guesses for some reason need to change, OnStateChange (block 12) is
called. After OnStateChange, ModelEquations is called to solve the static equations in the new
state, and before the solver continues, OnSolution is called to enable plotting of point 14 in
Figure 9.

In the following the 12 procedures will be covered in detail.

Before any of the 12 procedures are filled out, then all the variables and parameters in the model
should be declared in standard Pascal fashion (see chapter 5). All Pascal floating-point variables
should be in double format.

WinDali Morten Juel Skovrup


6 Model file format 25

6.1 Common parameters


First some parameters that are in several of the function calls are explained.

AFormat Format of string when the variable is saved to an ASCII file:


0 ffGeneral: General number format. The value is converted to the shortest possible
decimal string using fixed or scientific format. Trailing zeros are removed from the
resulting string, and a decimal point appears only if necessary. The resulting string uses
fixed point format if the number of digits to the left of the decimal point in the value is less
than or equal to the specified precision, and if the value is greater than or equal to 0.00001.
Otherwise the resulting string uses scientific format, and the Digits parameter specifies the
minimum number of digits in the exponent (between 0 and 4).
1 ffExponent: Scientific format. The value is converted to a string of the form “-
d.ddd…E+dddd”. The resulting string starts with a minus sign if the number is negative,
and one digit always precedes the decimal point. The total number of digits in the resulting
string (including the one before the decimal point) is given by the Precision parameter. The
“E” exponent character in the resulting string is always followed by a plus or minus sign
and up to four digits. The Digits parameter specifies the minimum number of digits in the
exponent (between 0 and 4).
2 ffFixed: Fixed-point format. The value is converted to a string of the form "-ddd.ddd...".
The resulting string starts with a minus sign if the number is negative, and at least one digit
always precedes the decimal point. The number of digits after the decimal point is given by
the Digits parameter--it must be between 0 and 18. If the number of digits to the left of the
decimal point is greater than the specified precision, the resulting value will use scientific
format.
3 ffNumber: Number format. The value is converted to a string of the form "-
d,ddd,ddd.ddd...". The ffNumber format corresponds to the ffFixed format, except that the
resulting string contains thousand separators.
APrecision Meaning varies according to the value of AFormat.
ADigits Meaning varies according to the value of AFormat.
ALabel Label to add before or after the variable in the Solver & Model settings
window.
If first character in ALabel is
“-“: Then the label is displayed before the variable and a line is
added above the label.
else : The label is displayed before the variable and no line is added.
If ALabel equals “_” then a line will be drawn after the variable.

WinDali Morten Juel Skovrup


26 6 Model file format

6.2 SetUpProblem
In SetUpProblem the problem is specified so the solver knows the number of dynamic and static
variables. But the user-interface in the Simulation program is also created from the
specifications.

To specify the problem, a number of functions are available. The order in which these functions
are called is not unimportant. Functions that start with Set… should be called before functions
starting with Add…. In general functions used to specify the number of some type of variable or
parameter has to be called before other information about the variable is specified.

Most of the Add… functions have two versions: a simple and an extended. The extended functions
give more control of the appearance of the user-interface in the Simulation program. The
extended functions ends on Ext – for example:
AddDynamic (simple version)
AddDynamicExt (extended version)

The available functions are explained in the following sections.

6.2.1 SolverSettings
Heading
procedure SolverSettings(Title : PChar; TStart,TEnd,TimeFac : Double;
ShowStartState : WordBool; StartState : Integer);
Parameters
Title The title of the model.
TStart Default start time of the simulation.
TEnd Default end time of the simulation.
TimeFac Factor to divide time with on plots and in files. I.e. if you set TimeFac to
1000, you will internally in the model calculate in milliseconds. TStart
and TEnd should be specified in the same units as the internal time. I.e. if
TimeFac is 1000, then TStart = 1000 means 1 second.
ShowStartState Let the user select the start state. If set to false then you are responsible
for calling SetStartState in PreCalc See 6.2.14.
StartState Default initial state of the model.
Shortcut
Write set and press <Ctrl>+J.
Example
SolverSettings('Example',0,3600,1,True,1);

This procedure should always be called.

WinDali Morten Juel Skovrup


6 Model file format 27

6.2.2 Dynamic variables


AddDynamic adds information about a dynamic variable to the solver and the Simulation
program.

Heading
procedure AddDynamic(var Variable : Double;
InitalValue : Double; Name,LongName : PChar);
procedure AddDynamicExt(var Variable : Double;
InitalValue : Double; Name,LongName : PChar;
Min,Max : Double; Show : WordBool; AFormat : Byte;
APrecision,ADigits : Byte; ALabel : PChar);
Parameters
Variable The declared pascal variable, which represents the variable in the model.
InitalValue Default initial value of the dynamic variable.
Name Short name that appears on plots.
LongName Long name, appears in Solver & Model settings window in the
Simulation program.
Min Minimum value the user can set the variable to.
Max Maximum value the user can set the variable to.
If Min = Max = 0 then no limits are set.
Show True: Display the dynamic variable in interface.
Plot/save of this variable is available to the user.
False: Do not display the dynamic variable in interface.
Plot/save of this variable is not available to the user.
See also chapter 6.14.
AFormat, APrecision, ADigits, ALabel : See 6.1.
Shortcut
Write adyn or adyne and press <Ctrl>+J.
Example
implementation
var
Y1,Y2 : Double;
procedure SetUpProblem;
begin
AddDynamicExt(Y1,1,'DynVar1','Dynamic variable 1',1,10,True,
0,10,2,'-Test dynamic');
AddDynamicExt(Y2,1,'DynVar2','Dynamic variable 2',1,10,True,
0,10,2,'_');
end;

Will produce the following output on the Initial page in the simulation program:

WinDali Morten Juel Skovrup


28 6 Model file format

(Note that the checkbox “Update initial values” is created automatically).

6.2.3 States
SetStates defines the number and names of the states in the model.

Heading
procedure SetStates(Names : PChar);
Parameters
Names Comma separated string specifying the names of the states. If a state name
contains spaces then enclose the name in ””.
Shortcut
Write states and press <Ctrl>+J.
Example
//Three states are created:
SetStates('"Valve on",Off,"Valve Saturated"');

6.2.4 Static variables


AddStatic adds information about a static variable in a state.

Heading
procedure AddStatic(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar);
procedure AddStaticExt(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar;
Min,Max : Double; DoPlot : WordBool; AFormat : Byte;
APrecision,ADigits : Byte; ALabel : PChar);
Parameters
State The state the static variable belongs to.
Variable The declared pascal variable, which represents the variable in the model.
InitialGuess The default guess on the static variable.
Name Short name that appears on plots.
LongName Long name, appears on the Guesses page in the Solver & Model settings
window in the Simulation program.
Min Minimum value the user can set the variable to.
Max Maximum value the user can set the variable to.
If Min = Max = 0 then no limits are set.
DoPlot True: Plot/save is available to the user for this variable
False: Plot/save is not available to the user for this variable.
AFormat, APrecision, ADigits, ALabel : See 5.1.
Shortcut
Write astatic or astatice and press <Ctrl>+J.

WinDali Morten Juel Skovrup


6 Model file format 29

Example
implementation
var
X11,X12,X21,X22,X23,X31,X32 : Double;
procedure SetUpProblem;
begin
AddStaticExt(1,X11,0,'Stat11','Static Var 11',0,0,True,0,10,2,'');
AddStaticExt(1,X12,0,'Stat12','Static Var 12',0,0,True,0,10,2,'');
AddStaticExt(2,X21,0,'Stat21','Static Var 21',0,0,True,0,10,2,'');
AddStaticExt(2,X22,0,'Stat22','Static Var 22',0,0,True,0,10,2,'');
AddStaticExt(2,X23,0,'Stat23','Static Var 23',0,0,True,0,10,2,'');
AddStaticExt(3,X31,0,'Stat31','Static Var 31',0,0,True,0,10,2,'');
AddStaticExt(3,X32,0,'Stat32','Static Var 32',0,0,True,0,10,2,'');
end;

If you follow the examples in 6.2.3 and this section, you will see the following result on the
Guesses page in the simulation program:

If you have static variables that are common to several states, you can add the required
information by calling AddCommonStatic:

Heading
procedure AddCommonStatic(var Variable : Double;
InitalGuess : Double; Name,LongName : PChar;
CommonStates : PChar);
procedure AddCommonStaticExt(var Variable : Double;
InitalGuess : Double; Name,LongName : PChar;
CommonStates : Pchar;
Min,Max : Double; DoPlot : WordBool; AFormat : Byte;
APrecision,ADigits : Byte; ALabel : PChar);
Parameters
Variable The declared pascal variable, which represents the variable in the model.
InitialGuess The default guess on the static variable.
Name Short name that appears on plots.
LongName Long name, appears in Solver & Model settings window in the
Simulation program.
CommonStates Comma separates string of the states the static variable exists in. If the
variable exists in all states, CommonStates should be empty.
Min Minimum value the user can set the variable to.
Max Maximum value the user can set the variable to.
If Min = Max = 0 then no limits are set.
DoPlot True: Plot/save is available to the user for this variable
False: Plot/save is not available to the user for this variable.

WinDali Morten Juel Skovrup


30 6 Model file format

AFormat, APrecision, ADigits, ALabel : See 5.1.


Shortcut
Write acommon or acommone and press <Ctrl>+J.
Example
implementation
var
X13,XAll : Double;
procedure SetUpProblem;
begin
{add X13 to state 1 and 3:}
AddCommonStaticExt(X13,0,'Stat13','Static Var 13',
'1,3',0,0,True,0,10,2,'');
{add XAll to all states:}
AddCommonStaticExt(XAll,0,'StatAll','Static Var All',
'',0,0,True,0,10,2,'');
end;

6.2.5 Parameter pages


SetParamPages sets the number and names of the parameter pages to create in the Solver &
Model settings window in the Simulation program.

Heading
procedure SetParamPages(Names : PChar);
Parameters
Names Comma separated string specifying the names of the parameter pages. If a page name
contains spaces then enclose it in "".
Shortcut
Write nparam and press <Ctrl>+J.
Example
SetParamPages('Parameters,Settings,"Control settings"');

6.2.6 Initial Parameters


These kinds of parameters are special as they appear on the Initial page in the Solver & Model
settings window in the Simulation program. Initial value parameters will be further discussed in
chapter 6.14.

6.2.7 Floating point parameters


AddFloatParam adds information about a floating-point parameter.

Heading
procedure AddFloatParam(var Parameter : Double;
DefaultValue : Double; Name : PChar;
ParamPage : Integer);
procedure AddFloatParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar;
ParamPage,IndexOnPage : Integer;
Min,Max : Double; ALabel : PChar);

WinDali Morten Juel Skovrup


6 Model file format 31

Parameters
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultValue The default value of the parameter.
Name Text that appears in Model & Solver settings window.
ParamPage The number of the parameter page to place the parameter on.
IndexOnPage The index of the parameter on the parameter page.
Min Minimum value the user can set the parameter to.
Max Maximum value the user can set the parameter to.
If Min = Max = 0 then no limits are set.
ALabel See 5.1.
Shortcut
Write afloat or afloate and press <Ctrl>+J.
Example
implementation
var
Rho,Cp,Lambda,V,A,h,Ta : Double;
procedure SetUpProblem;
begin
SetParamPages('Material,Geometry,"Heat transfer"');
AddFloatParamExt(Rho,8000,'Density [kg/m^3]',1,1,0,20000,'');
AddFloatParamExt(Cp,480,'Specific heat [J/kg K]',1,2,0.001,5000,'');
AddFloatParamExt(Lambda,15,'Conductivity [W/m K]',1,3,0.0001,5000,'');
AddFloatParamExt(V,0.001,'Volume [m^3]',2,1,0.000001,1000,'');
AddFloatParamExt(A,0.06,'Surface area [m^2]',2,2,0.000001,10000,'');
AddFloatParamExt(h,10,'Heat transfer coefficient [W/m^2 K]',
3,1,0.00001,100000,'');
AddFloatParamExt(Ta,20,'Ambient temperature [°C]',3,2,0,0,'');
end;

Will produce the following result in the Simulation program:

WinDali Morten Juel Skovrup


32 6 Model file format

6.2.8 Integer parameters


Integer parameters differ from floating point parameter in that the user only is allowed to input
integer values.

AddIntParam adds information about an integer parameter.

Heading
procedure AddIntParam(var Parameter : Integer;
DefaultValue : Integer; Name : PChar;
ParamPage : Integer);
procedure AddIntParamExt(var Parameter : Integer;
DefaultValue : Integer; Name : PChar;
ParamPage,IndexOnPage : Integer;
Min,Max : Integer; ALabel : PChar);
Parameters
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultValue The default value of the parameter.
Name Text that appears in Model & Solver settings window.
ParamPage The number of the parameter page to place the parameter on.
IndexOnPage The index of the parameter on the parameter page.
Min Minimum value the user can set the parameter to.
Max Maximum value the user can set the parameter to.
If Min = Max = 0 then no limits are set.
ALabel See 5.1.
Shortcut
Write aint or ainte and press <Ctrl>+J.
Example
implementation
var
NSec : Integer;
procedure SetUpProblem;
begin
AddIntParamExt(NSec,10,'Number of sections',1,1,1,100,'');
end;

This will add an integer parameter that looks like this:

WinDali Morten Juel Skovrup


6 Model file format 33

6.2.9 Boolean parameters


Boolean parameters are logical parameters that have the value True or False.

AddBoolParam adds information about a Boolean parameter.

Heading
procedure AddBoolParam(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar;
ParamPage : Integer);
procedure AddBoolParamExt(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
Parameters
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultValue The default value of the parameter.
Name Text that appears in Model & Solver settings window.
ParamPage The number of the parameter page to place the parameter on.
IndexOnPage The index of the parameter on the parameter page.
ALabel See 5.1.
Shortcut
Write abool or aboole and press <Ctrl>+J.
Example
implementation
var
TestBool : WordBool;
procedure SetUpProblem;
begin
AddBoolParamExt(TestBool,False,'TestBool',3,2,'');
end;

This will add a Boolean parameter that looks like this:

6.2.10 List parameters


List parameters are parameters that can have one of several values displayed to the user in a
listbox.

AddListParam adds information about a list parameter.

Heading
procedure AddListParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage : Integer);
procedure AddListParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);

WinDali Morten Juel Skovrup


34 6 Model file format

Parameters
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultIndex Index of the default selected item. The first item has index 1.
Items A comma separated string with the items the listbox should contain.
If an item contains spaces it should be enclosed in "".
When the simulation starts, Parameter will contain the index of the
selected parameter.
Name Text that appears in Model & Solver settings window.
ParamPage The number of the parameter page to place the parameter on.
IndexOnPage The index of the parameter on the parameter page.
ALabel See 5.1.
Shortcut
Write alist or aliste and press <Ctrl>+J.
Example
implementation
var
List : Integer;
procedure SetUpProblem;
begin
AddListParamExt(List,1,'"Item 1","Item 2","Item 3","Item 4"',
'TestList',1,1,'');
end;

This will add a list parameter that looks like this:

6.2.11 Enumerated parameters


Enumerated parameters are very similar to list parameters, except that the items will be displayed
in a combobox instead of a listbox.

AddEnumParam adds information about an enumerated parameter.

Heading
procedure AddEnumParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage : Integer);
procedure AddEnumParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
Parameters
See list parameters.
Shortcut
Write aenum or aenume and press <Ctrl>+J.

WinDali Morten Juel Skovrup


6 Model file format 35

Example
implementation
var
Enum : Integer;
procedure SetUpProblem;
begin
AddEnumParamExt(Enum,1,'"Item 1","Item 2","Item 3","Item 4"',
'TestEnum',1,1,'');
end;

This will add a enumerated parameter that looks like this:

6.2.12 Enumerated choice parameters


Enumerated choice parameters are used to create structures with multiple choices, and where
each choice has a different number of parameters. For example can the UA value of a heat
exchanger be specified by:
1. An UA-value directly
2. Dimensioning values of Q and ∆T ( Q = UA ∆T ).

AddEnumChoiceParam adds information about an enumerated choice parameter. Enumerated


choice parameters are special, because besides AddEnumChoiceParam, another function has to be
called to complete the specification. Enumerated choice parameters can be regarded as a
combination of an enumerated parameter and a number of floating point parameters. This will be
clear when an example is given below.
Heading
procedure AddEnumChoiceParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage : Integer);
procedure AddEnumChoiceParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
Parameters
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultIndex Index of the default selected item. The first item has index 1.
Items A comma separated string with the items the combobox should contain.
If an item contains spaces it should be enclosed in "".
When the simulation starts, Parameter will contain the index of the
selected parameter.
Name Text that appears in Model & Solver settings window.
ParamPage The number of the parameter page to place the parameter on.
IndexOnPage The index of the parameter on the parameter page.
ALabel See 5.1.
Shortcut
Write achoice or achoicee and press <Ctrl>+J.

WinDali Morten Juel Skovrup


36 6 Model file format

AddChoice is used to add information for each of the choices for each of the items
AddEnumChoiceParam. Note that AddChoice has to be called immediately after
AddEnumChoiceParam.

Heading
procedure AddChoice(ItemIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar);
procedure AddChoiceExt(ItemIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar;
Min,Max : Double);
Parameters
ItemIndex The index of the item the choice belongs to.
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultValue The default value of the parameter.
Name Text that appears in Model & Solver settings window.
Min Minimum value the user can set the parameter to.
Max Maximum value the user can set the parameter to.
If Min = Max = 0 then no limits are set.
Shortcut
Write cachoice or cachoicee and press <Ctrl>+J.

Example
Taking the example where the UA value of a heat exchanger can be specified by:
1. An UA-value directly
2. Dimensioning values of Q and ∆T ( Q = UA ∆T ).
implementation
var
Choice : Integer;
UA,QDim,DTDim : Double;
procedure SetUpProblem;
begin
AddEnumChoiceParamExt(Choice,1,'UA,"Q_Dim,DT_dim"',
'Specify UA value by specifying',1,1,'');
AddChoiceExt(1,UA,100,'UA value [W/K]',0,0);
AddChoiceExt(2,QDim,1000,'Q_dim [W]',0,0);
AddChoiceExt(2,DTDim,10,'DT_dim [K]',0,0);
end;

This will add an enumerated choice parameter that looks like this:

a) When the user selects UA:

WinDali Morten Juel Skovrup


6 Model file format 37

b) When the user selects Q_dim,DT_dim:

6.2.13 Extra variables


These variables are not part of the equation system; but they can be plotted and saved with the
dynamic and static variables. In other words: extra variables are variables that can be calculated
explicitly.

AddExtra adds information about an extra variable.

Heading
procedure AddExtra(var Variable : Double; Name : PChar;
DoPlot : WordBool);
procedure AddExtraExt(var Variable : Double; Name : PChar;
DoPlot : WordBool; AFormat : Byte; APrecision,ADigits : Byte;
ALabel : PChar);
Parameters
Variable The declared pascal variable, which represents the variable in the model.
Name Text that appears in Model & Solver settings window or in Plot.
DoPlot True: The variable is plotted.
False: The variable is added to the Results page when calculation is done.
AFormat, APrecision, ADigits, ALabel : See 5.1.
Shortcut
Write aextra or aextrae and press <Ctrl>+J.
Example
AddExtraExt(Bi,'Biot number',False,2,10,2,'');

6.2.14 Action buttons


Action buttons are buttons you can place on the user-interface. You are responsible for writing
code, which responds when the user presses the button – this should be done in
OnUIValueChange (see 6.11). You install buttons by calling AddActionBtn.

Heading
procedure AddActionBtn(Caption : PChar;
ParamPage : Integer);
procedure AddActionBtnExt(Caption : PChar;
ParamPage, IndexOnPage : Integer; ALabel : PChar);
Parameters
Caption The caption of the action button.
ParamPage The number of the parameter page to place the button on.
IndexOnPage The index of the button on the parameter page.
ALabel See 5.1.

WinDali Morten Juel Skovrup


38 6 Model file format

Shortcut
Write abtn or abtne and press <Ctrl>+J.
Example
AddActionBtnExt('Load properties',1,10,'Press to load parameters');

Will create a button, which looks like this:

6.2.15 Info Labels


Info labels are labels you can place on the user-interface, displaying some information to the
user. You install info labels by calling AddInfoLabel.

Heading
procedure AddInfoLabel(Caption : PChar;
ParamPage : Integer);
procedure AddInfoLabelExt(Caption : PChar;
ParamPage, IndexOnPage : Integer; ALabel : PChar);
Parameters
Caption The caption of the info label.
ParamPage The number of the parameter page to place the info label on.
IndexOnPage The index of the info label on the parameter page.
ALabel See 5.1.
Shortcut
Write ainfo or ainfoe and press <Ctrl>+J.
Example
AddInfoLabelExt('This is a message',1,10,'');

6.2.16 HideSampleTime
HideSampleTime can be used to hide information about fixed sample in the simulation program
from the user.

On the Solver page in the simulation program the used can select to run the simulation with fixed
sample time. If you do not want the user to have this possibility you should call
HideSampleTime. This could for example be the case if you want the user to input the sample
time together with other parameters for a controller and not on the Solver page. In this case you
should also call SetSampleTime in PreCalc (see chapter 6.3 and 6.8).

Heading
procedure HideSampleTime;
Parameters
None
Shortcut
Write hsample and press <Ctrl>+J.
Example
HideSampleTime;

WinDali Morten Juel Skovrup


6 Model file format 39

6.2.17 Model help file


As of version 1.37 it is possible to specify a help file for the model. The help file can be in any
format as the simulation program executes the application, which is associated with the help file.

The help file should be located in the same directory as the model. If the help file consists of
several files then you should manually include files other than the installed help file when
creating a distributable copy (see chapter 12).

The help file is installed by calling the following procedure within SetUpProblem:

Heading
procedure AddHelpFile(FileName : PChar);
Parameters
FileName Name of the help file (without directory information).
Shortcut
Write ahelp and press <Ctrl>+J.
Example
AddHelpFile('Example.html');

6.3 PreCalc
PreCalc is called just before the simulation is started. This procedure can be used to initiate
variables, allocating memory etc. Furthermore PreCalc is used to specify initial values for
dynamic variables based on initial value parameters, and to add static variables. This is treated in
chapter 6.14.

If you set the ShowStartState parameter in a call to SetUpProblem to false, you have to specify
the initial state in PreCalc. This is done by calling SetStartState.
You can also add Extra variables in PreCalc by calling AddExtraVar and control the sample
time by calling SetSampleTime.

6.3.1 SetStartState
Heading
procedure SetStartState(Value : Integer);
Parameters
Value Number of the initial state.
Shortcut
Write ssstate and press <Ctrl>+J.
Example
SetStartState(1);

WinDali Morten Juel Skovrup


40 6 Model file format

6.3.2 AddExtraVar
Heading
procedure AddExtraVar(Name : PChar; Variable : PDouble; DoPlot : Boolean);
Parameters
Name Name of extra variable.
Variable Pointer to the declared pascal variable, which represents the extra variable
in the model. Use the “address of” operator (@) to create the pointer.
DoPlot True: The variable is plotted.
False: The variable is added to the Results page when calculation is done.
Shortcut
Write sextra and press <Ctrl>+J.
Example
AddExtraVar('Compressor work',@W,True);

6.3.3 SetSampleTime
Heading
procedure SetSampleTime(IsFixed : Boolean; Value : Double);
Parameters
IsFixed Run with fixed sample time? If true the sample time specified in value is used;
else fixed sample time is not used.
Value The value of the fixed sample time in seconds.
Shortcut
Write ssample and press <Ctrl>+J.
Example
SetSampleTime(True,10);

6.4 ModelEquations
In the ModelEquations procedure the equations are written. ModelEquations is called every
time the Solver needs to evaluate the model.

Suppose the problem from chapter 3 is extended, so that instead of just cooling the block, it is
required that the temperature is held at 50 °C ± 2 °C. To accomplish this, the block is put into
an air chamber, with the possibility to add air at 70°C or air at 20°C:

WinDali Morten Juel Skovrup


6 Model file format 41

Th

ρ ,V , c p , T

Tc
Controller
Figure 10. Controlling the temperature.

Now the system has two states: either hot air supply or cold air supply.

The equations for the two states are:


dT
ρVc p = h A (Tc − T ) , Cold
dt
(6.1)
dT
ρVc p = h A (Th − T ) , Hot
dt
The SetUpProblem procedure for this case will look like this:

procedure SetUpProblem;
begin
SolverSettings('Simple problem',0,20000,1,True,1);
SetStates('Cold,Hot');
SetParamPages('Material,Geometry,"Heat transfer"');
AddDynamicExt(T,100,'T','Temperature [°C]',0,0,True,0,10,2,'');
AddFloatParamExt(Rho,8000,'Density [kg/m^3]',1,1,0,20000,'');
AddFloatParamExt(Cp,480,'Specific heat [J/kg K]',1,2,0.001,5000,'');
AddFloatParamExt(Lambda,15,'Conductivity [W/m K]',1,3,0.0001,5000,'');
AddFloatParamExt(V,0.001,'Volume [m^3]',2,1,0.000001,1000,'');
AddFloatParamExt(A,0.06,'Surface area [m^2]',2,2,0.000001,10000,'');
AddFloatParamExt(h,10,'Heat transfer coefficient [W/m^2 K]',
3,1,0.00001,100000,'');
AddFloatParamExt(Tc,20,'Cold temperature [°C]',3,2,0,0,'');
AddFloatParamExt(Th,70,'Hot temperature [°C]',3,3,0,0,'');
AddExtraExt(Bi,'Biot number',False,2,10,2,'');
end;

WinDali Morten Juel Skovrup


42 6 Model file format

and the ModelEquations procedure will look like this:


procedure ModelEquations(Time : Double; State : Integer;
var R : array of Double;
var YDot : array of Double);
begin
if State = 1 then
YDot[0] := h*A/(Rho*V*Cp)*(Tc-T)
else
YDot[0] := h*A/(Rho*V*Cp)*(Th-T);
end;

It is also necessary to fill out StateShift but this will be treated in chapter 6.5.

To show how static equations are formulated assume that the specific heat of the material, no
longer is constant; but can be calculated as:

cp − T
cp = cp0 (6.2)
cp

Note that this equation is pure fictional. It has no physical meaning and only serves to illustrate
static variables. cp0 is a parameter provided by the user.

In SetUpProblem the following line is changed:

AddFloatParamExt(Cp,480,'Specific heat [J/kg K]',1,2,0.001,5000,'');


Is changed to:
AddFloatParamExt(Cp0,480,'Specific heat [J/kg K]',1,2,0.001,5000,'');

The following line is added to SetUpProblem:

AddCommonStaticExt(Cp,480,'Cp','Specific heat [J/kg K]',


'',0,0,True,0,10,2,'');

The cp equation also has to be added to ModelEquations. This is done by adding the line:

R[0] := Cp-Cp0*Sqrt((Cp-T)/Cp);

6.5 StateShift
StateShift is used to specify when the logical state is changed. The heading of the StateShift
function looks like this:

procedure StateShift(Time : Double; State : Integer;


var G : array of Double);

The G-array is zero-indexed, and has the same length as the number of states. A shift to another
state is done when the corresponding item in the G array becomes negative. The State
parameter holds the number of the current state.

WinDali Morten Juel Skovrup


6 Model file format 43

In the example from chapter 6.4 there was two states:


1: Cold corresponds to G[0]
2: Hot corresponds to G[1]

The temperature should be held at 50 °C ± 2 °C. That is when the system is in state 1 it should
shift to state 2 when the temperature drops below 48 °C. And when the system is in state 2 it
should shift to state 1 when the temperature is above 52 °C:

procedure StateShift(Time : Double; State : Integer;


var G : array of Double);
begin
case State of
1 : G[1] := T-48;
2 : G[0] := 52-T;
end;
end;

What the code states is that when the current state is 1 (Cold) then G[1] becomes negative when
T is less than 48 °C and the Solver will then shift to state 2. When the current state is 2 (Hot)
then G[0] will become negative when T is larger than 52 °C, and the Solver will then shift to
state 1.

The procedure ShiftToState can be used to perform the same as the code above, but it makes it
a bit more readable:

procedure StateShift(Time : Double; State : Integer;


var G : array of Double);
begin
case State of
1 : SwitchToState(2,T-48,G);
2 : SwitchToState(1,52-T,G);
end;
end;

Read the call SwitchToState(2,T-48,G) as "Switch to state 2 when T-48 becomes negative".
Remember to supply G as the last parameter in the call to SwitchToState.

SwitchToState has the following implementation:

procedure SwitchToState(StateNum : Integer; SignChange : Double;


var G : array of Double);
begin
G[StateNum-1] := SignChange;
end;

NOTE You decide yourself if you want to shift state when G becomes negative. In reality the
solver checks if there is a change in sign in G and shifts state on a sign change. But if you follow
the rule above, that a state is only changed if G becomes negative, you will end up with code that
is easier understandable, and you will be sure that your code will work in future versions!!

WinDali Morten Juel Skovrup


44 6 Model file format

6.6 OnStateChange
OnStateChange is seldom modified. It can be used to supply guesses (different from the default)
on the static variables or to change the “initial” value of a dynamic variable before continuing in
to a new state. An example showing this is included in demo 11

The solver supplied with WinDali automatically updates guesses on static variables. That is it
uses the supplied guesses the first time it enters a state. If it enters the same state a second time,
the solution from the first time is used as guesses.

6.7 OnSolution
Called every time a solution has been found. Can be used to save the solution to another type of
file than an ASCII file. OnSolution can also be used to do intermediate calculations.

6.8 OnSample
The procedure OnSample is called if you choose to run the simulation with a fixed sample time.
If for example the sample time is 10 seconds it forces the equation solver to produce a solution at
every 10 seconds, but it might also produce solutions in between each sample.

When a solution is found at a sample time, then first OnSolution is called then OnSample and
finally OnSolution again. The reason for this is that you want to plot both the solution just
before OnSample is called, and if some values are changed in OnSample, then the changes should
also be plotted with the same timestamp.

If you for example implement a controller, which operates with a fixed sample time of 10
seconds – let us say it controls the speed of a compressor – then at time 100 a solution is found
which is plotted. This solution is then used in the controller when OnSample is called to change
the speed, and finally OnSolution is called to reflect the change in the speed.

You should note that OnSample will not be called at the initial time. If your simulation runs from
0 secods and you specify a sample time of 10 secondes then OnSample will be called the first
time at Time = 10 seconds. This is because the results of the calculations in OnSample might be
used in ModelEquations and the static and dynamic variables might be used in OnSample. At
the initial time the static variables only have guess-values, so to solve the equations in
ModelEquations the results from OnSample has to be known. In other words: you have to
specify initial values for the values calculated in OnSample, which are used in ModelEquations.

Typically a controller will also control which state the system is in (for example if the
compressor is On or Off). It is important to notice that the condition for the state change should
still be programmed in StateShift and not in OnSample. You could for example have a variable
called OnOff which you in OnSample set to 1 if the compressor should be On or –1 if the
compressor should be Off. Then in StateShift your shifting conditions would look like this:

WinDali Morten Juel Skovrup


6 Model file format 45

procedure StateShift(Time : Double; State : Integer;


var G : array of Double);
begin
case State of
1 : SwitchToState(2,OnOff,G); {Switch to off when OnOff is negative}
2 : SwitchToState(1,-OnOff,G); {Switch to on when -OnOff is negative}
end;
end;

Note also that you should not explicitly set the compressor speed to 0 when you calculate OnOff
in OnSample and finds out that it should be –1. The reason for this is that the speed might be used
in ModelEquations and as the state does not change before StateShift is called the next time,
this might lead to unexpected behaviour. In stead you could change the speed in
OnStateChange.

6.9 EndCalc
Called once when the simulation stops. Can be used to free memory allocated in PreCalc, and to
do some final calculations on extra variables.

6.10 OnQuit
Is called when the user exits the Simulation Program or changes the model. Can be used to do
some final clean up.

6.11 OnUIValueChange
OnUIValueChange (On User Interface Value Change) is called whenever the user changes a
value in the Simulation program (including when the user presses an Action button).

The heading looks like this:

procedure OnUIValueChange(UIType : Integer;


Num,State,Choice : Integer; Value : Double);

UIType can have one of the following values:


0: An initial value of dynamic variable was changed
1: A guess value on static variable was changed
2: An initial parameter was changed
3: A floating point parameter was changed
4: A integer parameter was changed
5: A boolean parameter was changed
6: A list parameter was changed
7: A enum parameter was changed
8: A enum choice parameter was changed
9: A choice in a Enum Choice parameter was changed
10: An action button was pressed
11: An info label was changed

WinDali Morten Juel Skovrup


46 6 Model file format

Num Is the number of the variable/parameter/button/info label that was changed.


State
if UIType is 1 then State is the state, the static variable with number Num
belongs to
if UIType is 9 then State is the ItemIndex of the enumerated choice parameter
with number Num
if UIType is none of the above then State is ignored.

Choice
if UIType is 9 then Choice is the ParamIndex of the ItemIndex (= state) of
the enumerated choice parameter with number Num
else Choice is ignored.
Value is the numerical value of the value in the user interface that was changed.

You can call two procedures as respond to a change in a value:

procedure SetUIValue(UIType : Integer;Num,State,Choice : Integer;


Value : Double; StrValue : PChar);

which sets a value in the user interface, and

function GetUIValue(UIType : Integer;


Num,State,Choice : Integer; StrValue : PChar) : Double;

which gets a value from the user interface.

Three notes should be made:


• the Pascal variables you have declared does not reflect the values in the user-interface
when OnUIValueChange is called (the variables are only updated just before PreCalc is
called)
• The only type you can use for getting and setting user interface values is Double. This is
also true if you want to get/set a Boolean parameter. If it's a Boolean parameter then if
the value:
=0 it's False
<> 0 it's True
• The StrValue parameter is used if the item in question is an Action button or an Info
label.

The parameters in SetUIValue and GetUIValue have the same meaning as for
OnUIValueChange.

Example:

Suppose you have defined an action button, a boolean parameter and an enumerated choice
parameter in SetUpProblem:

WinDali Morten Juel Skovrup


6 Model file format 47

implementation
var
UACond : Integer;
UA_c,QDim_c,DTDim_c : Double;
TestBool : WordBool;
procedure SetUpProblem;
begin
AddEnumChoiceParam(UACond,1,'"UA-value","Q_Dim, DT_dim"',
'Specify UA value by specifying',1);
AddChoice(1,UA_c,1000,'UA value [W/K]');
AddChoice(2,QDim_c,8000,'Q_dim [W]');
AddChoice(2,DTDim_c,8,'DT_dim [K]');
AddActionBtn('Update DTDim_c',1);
AddBoolParam(TestBool,False,'TestBool',1);
end;

In OnUIValueChange you want the following to happen:

When the user press the button and "Q_Dim, DT_dim" is selected in the enumerated choice
parameter and QDim_c is larger than 6000 then DTDim_c is set to 6, and the boolean parameter is
set to false.

procedure OnUIValueChange(UIType : TUserinterfaceType;


Num,State,Choice : Integer;
Value : Double); stdcall;
begin
if (UIType = 10) and (Num = 1) then {Only perform if button number
1 is pressed}
begin
{Only perform if item number 2 (i.e. "Q_Dim, DT_dim") is selected in
enumerated choice parameter 1. Rounding is done to avoid problems
comparing a floating point number with an integer}
if Round(GetUIValue(8,1,0,0,nil)) = 2 then
begin
{Only perform if choice number 1 in item 2 in enumerated
parameter 1 is larger than 6000}
if GetUIValue(9,1,2,1,nil) > 6000 then
begin
SetUIValue(9,1,2,2,6,''); {DTDim_c is set equal 6}
SetUIValue(5,1,0,0,0,''); {TestBool is set false}
end;
end;
end;
end;

6.11.1 Running simulations from the model


You can call three procedures from the model to run simulations without user-interaction. This
could for example be useful if you want to investigate the frequency response of a model. In this
case you could display a button to the user, and when it is pressed several simulations are run
and finally some resulting plots are drawn (for example Bode-plots, Polar plots etc.).

The three procedures that can be called are:

WinDali Morten Juel Skovrup


48 6 Model file format

Heading
procedure RunSimulation(TStart,TEnd,hMax : Double);
Parameters
TStart Start time for the simulation.
TEnd End time for the simulation
HMax Maximum step size the solver is allowed to take during the simulation. If this value
is 0 then the value specified by the user is used.
Shortcut
Write run and press <Ctrl>+J.
Example
RunSimulation(0,3600,0);

RunSimulation starts a simulation and control is returned back to the model when the
simulation is done.
Heading
procedure CreatePlot(var PlotNum : Integer; XAxisType : Integer;
XLabel : PChar; YAxisType : Integer; YLabel : PChar);
Parameters
PlotNum Number of the plot created (this value is used in calls to AddCurveToPlot – see
below)
XAxisType Type of the X-axis. If 0 then linear axis. If 1 then logarithmic.
XLabel Label on X-axis.
YAxisType Type of the Y-axis. If 0 then linear axis. If 1 then logarithmic.
YLabel Label on Y-axis
Shortcut
Write plot and press <Ctrl>+J.
Example
var
PlotNum : Integer;

CreatePlot(PlotNum,0,'X-Axis',0,'Y-Axis');

Heading
procedure AddCurveToPlot(PlotNum : Integer; CurveName : PChar;
XData,YData : array of Double);
Parameters
PlotNum Number returned from call to CreatePlot
CurveName Name of the curve.
XData Array with x-coordinates of the curve.
YData Array with y-coordinates of the curve.
Shortcut
Write curve and press <Ctrl>+J.
Example
var
X,Y : array[1..20] of double;

AddCurveToPlot(PlotNum,'TestCurve',X,Y);

An example showing how to use the procedures is included with WinDali.

WinDali Morten Juel Skovrup


6 Model file format 49

6.12 OnSaveSettings
This procedure is called every time the user selects the File|Save menu in the simulation
program. The name of the file the settings are saved to, is passed in the parameter FileName.

If you want to save additional information together with the settings the Simulation program
saves, you can do it in this procedure. You should not write directly to file with the name passed
as FileName – instead you could save your custom setting in a file with the same name but with
a different extension.

6.13 OnLoadSettings
OnLoadSetting is called every time the user selects the File|Open menu in the Simulation
program. The name of the file the user opens is passed in the parameter FileName.

6.14 Using Initial parameters


Initial parameters are used to change the default behavior of the installed dynamic variables.
Normally, installing a dynamic variable will create an Edit box on the Initial page in the
Simulation program, where the user can enter an initial value. But there might be situations
where you want to avoid this.

Imagine for example you have a model where the dynamic variable is internal energy. Installing
the dynamic variable would then require the user to enter an initial value for the internal energy,
which can be difficult to acquire knowledge about. Instead it might be preferred to let the user
enter for example temperature and pressure as initial values, and then calculate the initial value
for internal energy before the simulation starts (requires that you know that the internal energy
can be expressed as a function of Temperature and Pressure – this is not the case if you have
two-phase flow).

To make this work you have to:


1. Use Initial parameters for the temperature and pressure. This is done by calling
AddInitialParam as described below.
2. Avoid the default Edit box for the internal energy to show in the user interface. This is
done by setting the Show parameter in AddDynamic to False for the internal energy
dynamic variable. Note that you still have to call AddDynamic for the internal energy
variable (see 6.2.2). Note also that setting Show to False prevents the internal energy
from appearing in plots and from saving it. If you still want to plot and/or save the
internal energy, you have to add an Extra variable, which you just set equal to the
internal energy.
3. Calculate and set the initial value for the internal energy before the simulation starts.
This can be done in PreCalc (see 6.2.14) by calling SetInitial (see 6.14.1) as
described below.

AddInitialParam adds information about an initial parameter.

WinDali Morten Juel Skovrup


50 6 Model file format

Heading
procedure AddInitialParam(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte);
procedure AddInitialParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte; Min,Max : Double; ALabel : PChar);
Parameters
Parameter The declared pascal variable, which represents the parameter in the
model.
DefaultValue The default value of the parameter.
Name Text that appears on the Initial page in the Model & Solver settings
window.
DynIndex The number of the dynamic variable the parameter takes the position of.
If this value is 0 then the Initial parameter is placed at the end of the
Initial page in the Model & Solver settings window.
Dynamic variables added with AddDynamic are placed on the Initial page
in the Model & Solver settings window in the order they are defined. If
you specify dynamic variable number 5, sets Show in AddDynamic to
false, and adds an Initial parameter with DynIndex 5 it will be placed as
number 5 on the Initial page.
DataType Can be set to 0 or 1:
If 0: The user should enter a floating-point value.
If 1: The user should enter an integer value.
Min Minimum value the user can set the parameter to.
Max Maximum value the user can set the parameter to.
If Min = Max = 0 then no limits are set.
ALabel See 5.1.
Shortcut
Write ainit or ainite and press <Ctrl>+J.
Example
implementation
var
U,P,T : Double; {Internal Energy, Pressure and Temperature}
procedure SetUpProblem;
begin
:
AddDynamicExt(U,0,'U','Internal Energy',0,0,False,0,10,2,'');
AddInitialParamExt(P,1E5,'Pressure [Pa]',0,0,0,0,'');
AddInitialParamExt(T,20,'Temperature [°C]',0,0,0,0,'');
:
end;
procedure PreCalc;
var
IntEnergy : Double;
begin
:
IntEnergy := CalculateInternalEnergy(T,P);
SetInitial(1,IntEnergy);
:
end;

WinDali Morten Juel Skovrup


6 Model file format 51

Another example where you could use Initial parameters is when you want the user to be able to
change the number of dynamic and/or static equations. This situation arise if you have made a
model of for example a pipe, which is divided in to several sections, and you want the user to
decide on the number of sections to be used. In this case you don’t have any dynamic variables
to install in SetUpProblem (if the pipe is all you want to model), as the number of dynamic
variables depends on the number of sections the user want to divide the pipe in.
Instead you add an initial parameter, which allows the user to set the number of divisions, and
you may also add an initial parameter to allow the user to set the initial value for the dynamic
variables.

When the user changes the number of pipe divisions, the number of static variables might also
change (depending on the model). The number of dynamic and static variables that the resulting
model has when the user starts the simulation are specified in PreCalc by calling AddDynVar and
AddStatVar (see 6.14.3 and 6.14.4).

A model of a pipe with selectable number of divisions could be defined as this:


implementation
const
MaxDiv = 20;
var
T : array [1..MaxDiv] of Double; {Temperature is dynamic variable}
N : Double; {Number of divisions}
NDiv : Integer; {An initial parameter is always
floating point - regardless of the
DataType. NDiv is the integer version
of N}
procedure SetUpProblem;
begin
:
{Note DataType is set to integer, and input is limited between }
{1 and MaxDiv: }
AddInitialParamExt(N,10,'Number of divisions',0,1,1,MaxDiv,'');
:
end;
procedure PreCalc;
var
i, : Integer;
AName : string;
Buffer : array[0..255] of Char;
begin
:
NDiv := Round(N);
for i:=1 to Ndiv do
begin
Str(i,AName);
AName := 'T'+ AName
{Note that you have to initialize dynamic variables created with
AddDynVar to their initial value before calling AddDynVar}
T[i] := TInitial;
{Note the typecast from string to PChar, and that the address of T[i]
is passed to AddDynVar}
AddDynVar(StrPCopy(Buffer,AName),@T[i],True);
end;
:
end;

WinDali Morten Juel Skovrup


52 6 Model file format

6.14.1 SetInitial
SetInitial is used to change the initial value of a dynamic variable just before the simulation
begins (i.e. after the user starts the simulation, but before ModelEquations is called the first
time). SetInitial is normally called in PreCalc.

Heading
procedure SetInitial(Index : Integer; Value : Double);
Parameters
Index Number of the dynamic variable to set the initial value of.
Value The new initial value.
Shortcut
Write sinit and press <Ctrl>+J.
Example
SetInitial(1,10.25);

6.14.2 SetGuess
SetGuess is used to change the guess value of a static variable just before the simulation begins
(i.e. after the user starts the simulation, but before ModelEquations is called the first time).
SetGuess is normally called in PreCalc.

Heading
procedure SetGuess(State,Index : Integer; Value : Double);
Parameters
State The state the static variable belongs to
Index Number of the static variable to set the guess value of.
Value The new guess value.
Shortcut
Write sguess and press <Ctrl>+J.
Example
SetGuess(1,1,10.25);

6.14.3 AddDynVar
AddDynVar is used to add dynamic variables just before the simulation begins (i.e. after the user
starts the simulation, but before ModelEquations is called the first time). AddDynVar is normally
called in PreCalc.

Heading
procedure AddDynVar(Name : PChar; Variable : PDouble; DoPlot : Boolean);
Parameters
Name Name of the dynamic variable (appears in plots).
Variable Pointer to the declared pascal variable, which represents the dynamic variable
in the model. Use the “address of” operator (@) to create the pointer. Variable
has to be initialized to the initial value before AddDynVar is called.
DoPlot If true the variable is plotted.
Shortcut
Write sdyn and press <Ctrl>+J.

WinDali Morten Juel Skovrup


6 Model file format 53

Example
implementation
var
T : array [1..10] of Double;
P : Double;

procedure PreCalc;
begin
P := 1;
T[1] := 10;
T[2] := 10;

AddDynVar('T1',@T[1],True);
AddDynVar('T2',@T[2],True);

AddDynVar('P',@P,True);
end;

6.14.4 AddStatVar
AddStatVar is used to add static variables just before the simulation begins (i.e. after the user
starts the simulation, but before ModelEquations is called the first time). AddStatVar is
normally called in PreCalc.

Heading
procedure AddStatVar(Name : PChar; State : Integer;
Variable : PDouble; DoPlot : Boolean)
Parameters
Name Name of the static variable (appears in plots).
State The state the static variable is defined in.
Variable Pointer to the declared pascal variable, which represents the static variable
in the model. Use the “address of” operator (@) to create the pointer. Variable
has to be initialized to the initial guess before AddStatVar is called.
DoPlot If true the variable is plotted.
Shortcut
Write sstatic and press <Ctrl>+J.
Example
implementation
var
T : array [1..10] of Double;
P : Double;

procedure PreCalc;
begin
P := 1;
T[1] := 10;
T[2] := 10;

AddStatVar('T1',1,@T[1],True);
AddStatVar('T2',1,@T[2],True);

AddStatVar('P',1,@P,True);
end;

WinDali Morten Juel Skovrup


54 6 Model file format

6.15 Mathematical text


WinDali includes possibilities to make text appear in the Simulation Program with Greek letters
and super- and subscript.

To use this facility, you have to specify the Name/LongName parameter in calls to Add… functions
using the following special characters:
• ; Start/end special character section.
• _ Move text down. Creates subscript or moves text back to normal after a
superscript.
• ^ Move text up . Creates superscript or moves text back to normal after a subscript.
• A string specifying a Greek letter (see below).
Writing the string in lowercase creates the corresponding Greek letter in lowercase.
Writing the string in uppercase creates the corresponding Greek letter in uppercase.

Examples:
'c;_;p;^; [kJ/kg-K]' will display as:
'alpha;_;i;^; [W/m;^;2;_;K]' will display as:

String Greek lowercase Greek uppercase


'alpha' α Α
'beta' β Β
'gamma' γ Γ
'delta' δ ∆
'epsilon' ε Ε
'zeta' ζ Ζ
'eta' η Η
'theta' θ Θ
'iota' ι Ι
'kappa' κ Κ
'lambda' λ Λ
'mu' µ Μ
'nu' ν Ν
'xi' ξ Ξ
'omicron' ο Ο
'pi' π Π
'rho' ρ Ρ
'sigma' σ Σ
'tau' τ Τ
'upsilon' υ Υ
'phi' φ Φ
'chi' χ Χ
'psi' ψ Ψ
'omega' ω Ω

WinDali Morten Juel Skovrup


6 Model file format 55

6.16 Debugging
For debugging purposes you can call the procedure DebugMsg:

Heading
procedure DebugMsg(Msg : PChar; Num : Double)
Parameters
Msg Message to display
Num An optional number to display (if Num is larger than 1E299 then the number is
not displayed).
Shortcut
Write dbg and press <Ctrl>+J.
Example
DebugMsg('Pressure',P); {will display for ex. 'Pressure = 1.2'}
DebugMsg('In ModelEq',1E300); {will display 'In ModelEq'}

The messages you write with DebugMsg will appear on the Debug page in the Message Window
in the Simulation Program.

WinDali Morten Juel Skovrup


56 7 Component file format

WinDali Morten Juel Skovrup


7 Component file format 57

7 Component file format


As of version 1.30 of Windali it is possible to create models of systems by connecting models of
individual components.

To use this feature you have to create the components and the system models in Free Pascal or
Borland Delphi™. Other programming languages will be supported in a later version.

To use the component modeling feature, first the components have to be created. This procedure
is not very different than the procedure described in chapter 6, but some general rules apply:

1. A component has to inherit from TmjsComponentModel (or a descendant) included in the


unit CmjsComponents.
2. The problem specification (what was specified in SetupProblem in 6) has to be specified
in the constructor of the component.
3. The procedures AddCommonStatic and AddCommonStaticExt cannot be used.
4. System models have to inherit from TmjsSystemModel (or a descendant) included in the
unit CmjsComponents. Normally TmjsSystemModel can be used directly.
5. Connectors have to inherit from TmjsConnector (or a descendant) included in the unit
CmjsComponents. Normally TmjsConnector can be used directly.
6. States are specified slightly different for components.

The source of the two units creating the component modeling interface, CmjsComponents and
CmjsProblemContainer, is included in the distribution of WinDali.

These rules will be explained in detail by describing the 6 basic elements of the component
modeling interface:
• Connectors
• Components
• Sources
• Sinks
• Signals
• Controllers
• Systems

7.1 Connectors
A component consists of the equations creating the model and an interface to the surroundings –
called connections. A component can have one or more connectors that enable it to connect to
other components. All connectors should inherit from TmjsConnector, and the only method that
should be changed is the constructor. An example of a connector could look like this:

type
TmjsMPConnector =
class(TmjsConnector)
constructor Create(AModel : TmjsComponentModel); override;
end;

implementation

WinDali Morten Juel Skovrup


58 7 Component file format

constructor TmjsMPConnector.Create(AModel: TmjsComponentModel);


begin
inherited Create(AModel);
AddPin('m',1);
AddPin('P',0);
end;

The only task of a connector is to define the number and names of the pins it uses to connect to
other components. This is done calling AddPin in the constructor. The number and names of the
pins are used to indicate the number and names of the variables that will be transferred from one
component to another. In the example above TmjsMPConnector has two pins called m and P,
indicating that components having this type of connector will connect to other components
through mass flow and pressure.

Note that in calls to AddPin you have to specify the pin-type. The Pin type should be 1 if the
connection variable is a flow variable, and 0 if it’s a potential variable. Flow variables are
variables that can have a direction, as for example mass flow, current and heat flux. Potential
variables are variables that cannot have direction, for example pressure, voltage and
temperature1.

The reason why it is necessary to distinguish between flow and potential variables are, that when
components are connected, no input/output structure is enforced, and a component with a flow-
pin pointing outwards (positive is out of the component) can be connected to another pin, which
is also pointing outwards.

7.2 Components
All components should inherit from the base class TmjsComponentModel. This ensures that the
component can connect to other components, and TmjsComponentModel also provides the basic
problem specification procedures.

TmjsComponentModel redefines 10 of the 11 procedures that make up the Model file format (as
explained in chapter 6). The only procedure that is not defined is SetupProblem, but instead the
problem is specified in the constructor of the component. None of the 10 procedures in
TmjsComponentModel does any calculations by default. As with the Model file format, it is these
10 procedures that have to be filled to create the model.

Of the 10 procedures only ModelEquations, StateShift and PreCalc have changed. These
three procedures and the constructor are described below.

7.2.1 Constructor
The constructor for a component has the following heading:

constructor Create(AModel : TmjsSystemModel; AName : PChar); virtual;

When a new component is created, the first thing to do in the new components constructor is to
call the inherited constructor. This ensures that the new component will be handled correctly in
1
Flow variables are sometimes called “through” variables, while potential variables sometimes
are called “across” or “effort” variables.

WinDali Morten Juel Skovrup


7 Component file format 59

the system model. Note that the system model the component belongs to is a parameter in the
constructor. The system model can always be accessed from the component using the property
SystemModel. This enables components to access information common to the system (for
example fluid properties).

7.2.1.1 Specification of states


Specification of states has changed a lot from the description in 6.2. Firstly the two procedures
AddCommonStatic and AddCommonStaticExt cannot be used with components.

Secondly the states are specified with calls to the following three procedures:

procedure AddState(AName : PChar);


procedure AddOutState(AName : PChar; StateNums : PChar);
procedure AddInState(AName : PChar; InType : Byte);

The first procedure replaces the original SetStates procedure. If for example your component
has three states called On, Off and Saturation they should be specified with three calls to
AddState:

AddState('On');
AddState('Off');
AddState('Saturation');

And On would get state number 1, Off number 2 etc.

Note that if a component does not specify any states, it is automatically assigned a state called
“Default”.

The two next functions have to do with the concept of in- and output states.

Output states are states that the component will make available to other components. For
example could a valve have two states On and Off but there might be other components, in the
system the valve is part of, which wants to know when the valve is On or Off. Even though the
other components in the system react on the valve being On or Off, it is the valve that sets the
On/Off state. Another example could be a pump, where the pump sets its On/Off state. Internally
in the pump there may be several other states – for example if the pump has some capacity
control in its On state, and the capacity is changed in steps, there may be on state for each
capacity level.

Lets say that the pump can be in the following states:


Capacity1
Capacity2
Capacity3
Off

To the components that are in the same system as the pump, there is no difference between the
first three states – they all just say that the pump is On. Specifying the states of the pump will
look like this:
AddState('Capacity1');

WinDali Morten Juel Skovrup


60 7 Component file format

AddState('Capacity2');
AddState('Capacity3');
AddState('Off');
AddOutState('On','1,2,3');
AddOutState('Off','4');
The first call to AddOutState states that output state On is set if any of the states 1,2 or 3 is set
(that is if the pump is in Capacity1, Capacity2 or Capacity3). The second call to AddOutState
states that output state Off is set if the pump is in state 4. In calls to AddOutState, StateNums
should be a string containing one or more numbers separated with a comma. The string must not
contain spaces.

Input states can be a bit more difficult. A component, which want to react on the pump being On
or Off, needs two input states that can be connected to the pump. The component might though
be connected such that the pump is not the only component that can give an On/Off signal.
Consider the following situation:

Comp.1

Comp.2

Suppose Component 1 wants to react to a null-flow condition, that is it defines two input states
On and Off. This means that it needs state-information from both the pump and the valve and
that Component 1 must allow several different components to set its input states On and Off.
This could lead to a conflict, because when the pump is On and the valve is Off, the pump tells
Component 1 that it is On, and the valve tells Component 1 that it is Off.

This conflict is resolved by specifying a type for the input state. Input states can be either OR or
AND. OR means that if just one of the components connected to the input state sets the state, then
the state will be set. AND means that all components connected to the state has to set it before the
state is set. In the example above, Component 1 should specify that its input state On is an AND
type, and that its input state Off is an OR type. The following table shows the result:

Pump output state Valve output state Input state set in Component 1
On On On
Off On Off
On Off Off
Off Off Off

In a call to AddInState the parameter InType should be set to 0 if the state is OR and 1 if the
state is AND.

WinDali Morten Juel Skovrup


7 Component file format 61

The situation is further complicated if Component 1 has some internal states (that is states that
are not input). Suppose Component 1 defines two states, let’s call them Liquid and Gas.
Logically Component 1 can now be in 4 states namely:

Liquid, On
Gas, On
Liquid, Off
Gas, Off

Component 1 should only define the two states Liquid and Gas in its constructor, but in
ModelEquations and the rest of the procedures it can be in 4 states! These states are
automatically numbered according to the following rule:

• First internal states are varied


• Then input states are varied

The result will always be as in the following example:

1. A component has 3 internal (local) states, L1, L2, L3


2. And 2 input states In1, In2
3. It can be in one of the following states:

State number Internal (local) state Input state


1 L1 In1
2 L2 In1
3 L3 In1
4 L1 In2
5 L2 In2
6 L3 In2

Each time any of the procedures ModelEquations, StateShift, OnStateChange, PreCalc,


OnSolution, EndCalc or OnUIValueChange is called, the State parameter will have a value
from 1 to 6.

Returning to the example with the pump and Component 1, the calls in the constructor of
Component 1 will look like this:

AddState('Liquid');
AddState('Gas');
AddInState('On',1);
AddInState('Off',0);

WinDali does not allow more than one component to shift state at a time. This means that if for
example a compressor and a pump has to be turned off at the same time, the pump and
compressor should let the On /Off states be input states, and the state change should be
controlled by some controller (see also 7.5).

WinDali Morten Juel Skovrup


62 7 Component file format

7.2.1.2 Connectors
Even though connectors are objects, you need not worry about creating them in the code. When a
component is created the connectors that the component should have, are created by just
specifying the type of the connector.

The connectors are added to the component by calls to AddConnector and SetPinVar.
AddConnector has the following heading:

procedure AddConnector(AConnector : TConnectorClass; AName : PChar;


Direction : Byte);

The parameter AConnector specifies the type of the connector the component should have, and
AName the name that the connector should have. Direction can be either 0 or 1:
• If it is 0 then flow variables are assumed to be positive into the component.
• If it is 1 then flow variables are assumed to be positive out of the component.

If for example a pipe should be modeled then it would have to connectors, let’s call them In and
Out, and both connectors should be of type TmjsMPConnector (see chapter 7.1). These connector
are added by the following calls in the constructor of the pipe component:

AddConnector(TmjsMPConnector,'In',0);
AddConnector(TmjsMPConnector,'Out',1);

Looking at the way pins are added to a connector (see chapter 7.1) and the way connectors are
added to a component, there has not yet been allocated a variable that can tell the component
what the value of a certain pin of a certain connector is – this is done by calling SetPinVar.
SetPinVar has the following heading:

procedure SetPinVar(var Variable : Double; ConnectorName : PChar;


PinName : PChar);

Variable is the pascal variable you want to have the value of the pin.
ConnectorName is the name of the connector that has the pin
PinName is the name of the pin.

In the pipe example the calls in the constructor would look like this:

SetPinVar(m_in,'In','m');
SetPinVar(P_in,'In','P');
SetPinVar(m_out,'Out','m');
SetPinVar(P_out,'Out','P');

Assuming that the pipe component defines the 4 variables m_in, m_out, P_in and P_out.

SetPinVar should always be called for each of the pins in each of the connectors a component
defines – even if the pin-variable is not used in the component. If SetPinVar is not called a
pointer error will occur.

WinDali Morten Juel Skovrup


7 Component file format 63

A special version of SetPinVar can be used if the connection variable equals the dynamic
variable.

Consider the example from chapter 5, where a block with uniform temperature was modeled. If
the block where modeled as a component, the connection variable (the temperature) would be the
dynamic variable. To avoid having to provide a “dummy” static equation stating that the
connection variable equals the dynamic variable, SetPinDynVar can be called:

procedure SetPinDynVar(DynIndex : Integer; ConnectorName : PChar;


PinName : PChar);

The only difference from SetPinVar is that the index of the dynamic variable has to be provided
instead of a variable. Before SetPinDynVar is called the dynamic variable should be installed as
shown in the following example:

constructor TBlock.Create(AModel: TmjsSystemModel; AName: PChar);


begin
inherited Create(AModel,AName);
AddConnector(TQTConnector,'In',0);
AddConnector(TQTConnector,'Out',1);
AddDynamic(T,20,'T','Temperature of block [°C]');
SetPinDynVar(1,'In','T');
SetPinVar(Q_in,'In','Q');
SetPinDynVar(1,'Out','T');
SetPinVar(Q_out,'Out','Q');
AddFloatParam(M,1000,'Mass [kg]');
AddFloatParam(Cp,1,'Specific heat [kJ/(kg K)]');
AddFloatParam(Qi,0,'Internal load [W]');
end;

7.2.1.3 Static variables


Static variables are specified the usual way by calls to AddStatic or AddStaticExt. One change
is though, that even if the component specifies static equations for the connection variables, it
must not register those variables. This is because the system tries to reduce the system of
equations, by identifying which connection variables can be eliminated. In principle each
component should specify a static equation for each connection variable. If for example the
component has three connectors with m and P as connector variables, it should specify two static
equations, stating the relationship between the m’s and P’s from the three connectors.

If a component leaves a static connection variable unchanged (for example a pipe where mass
flow into the pipe equals mass flow out), it should specify this by calling the procedure
SetThroughConnectors. This will help the system to reduce the number of static variables even
more. SetThroughConnectors has the following heading:

function SetThroughConnectors(ConnectorNames : PChar;


PinName : PChar) : Boolean;

ConnectorNames is a comma separated string with the names of the connectors that have a pin
with name PinName, who’s variable the component leave unchanged. An example to the end of
this chapter will show how to call SetThroughConnectors.

WinDali Morten Juel Skovrup


64 7 Component file format

7.2.2 ModelEquations
ModelEquations changes slightly when the component interface is used. The heading looks like
this:

procedure ModelEquations(Time : Double; State : Integer;


var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double);

Two parameters Rc and Yc have been added. Rc is used to count the static equations and Yc the
dynamic. When the solver calls ModelEquations, Rc and Yc will have values corresponding to
the first static and dynamic variables the component defines. If for example a component defines
3 dynamic variables, 2 states and 3 static variables in state 1 and 5 in state 2, then
ModelEquations should look something like this:

procedure ModelEquations(Time : Double; State : Integer;


var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double);
begin
Ydot[Yc] := …
Ydot[Yc+1] := …
Ydot[Yc+2] := …
if State = 1 then
begin
R[Rc] := …
R[Rc+1] := …
R[Rc+2] := …
Rc := Rc+3;
end
else
begin
R[Rc] := …
R[Rc+1] := …
R[Rc+2] := …
R[Rc+3] := …
R[Rc+4] := …
Rc := Rc+5;
end;
Yc := Yc+3;
end;

Note that the procedure should begin filling YDot and R at respectively Yc and Rc. Note also, and
this must not be forgotten, that Yc is incremented with the number of dynamic variables, and Rc
with the number of static variables in the current state.

7.2.3 StateShift
StateShift is in principle unchanged from chapter 6.5. The only thing you should be aware of
is that, if the component defines input states, then the number of states that should be handled in
StateShift is larger than the number of states the component defines.

Looking at the example with the pump and Component 1 from 7.2.1, then the total number of
states the component can be in is 4, while it only defines 2 it self. The StateShift procedure could
look something like this:

WinDali Morten Juel Skovrup


7 Component file format 65

procedure StateShift(Time : Double; State : Integer;


var G : array of Double);
begin
case State of
1 : SwitchToState(2,…,G); {State is Liquid, On}
2 : SwitchToState(1,…,G); {State is Gas, On}
3 : SwitchToState(4,…,G); {State is Liquid, Off}
4 : SwitchToState(3,…,G); {State is Gas, Off}
end;
end;

Note that when the component is in state 1 it can only switch to state 2 and when it is in state 2 in
can only switch to state 1 (and the same for state 3 and 4). The component can only switch
between its local states!

7.2.4 PreCalc
The SetGuess function you can call in PreCalc have changed slightly compared to the one in
chapter 6.14.2. None of the other functions mentioned in 6.3 or 6.14 have changed.

The heading of SetGuess is still the same, but a special feature exists for the index parameter:

procedure SetGuess(State,Index: Integer; Value: Double);

If for example a component has two connectors In and Out and each connector has three pins,
then the connectors would have been added to the component by calling AddConnector twice in
the components constructor:

AddConnector(TThreePinConnector,'In',0);
AddConnector(TThreePinConnector,'Out',1);

Note that the In connector is added first.

When the connectors are added the pins are automatically assigned numbers according to the
order the connectors are added in. In the example the pins of connector In and Out will get the
following numbers:
• Pin 1 in connector In will get number –1
• Pin 2 in connector In will get number –2
• Pin 3 in connector In will get number –3
• Pin 1 in connector Out will get number –4
• Pin 2 in connector Out will get number –5
• Pin 3 in connector Out will get number -6

This can be used to set guess values for the static variables assigned to the pins, for example:

SetGuess(1,-1,10) Sets the guess on the static variable assigned to Pin 1 of the In connector to
10 (when the component is in state 1)
SetGuess(2,-6,10) Sets the guess on the static variable assigned to Pin 3 of the Out connector
to 10 (when the component is in state 2)

WinDali Morten Juel Skovrup


66 7 Component file format

Calling SetGuess with a positive Index sets the guess on one of the local static variables in the
component.

7.2.5 Example
The following example will show how to create a model of a tank and a pipe.

The tank is feed with liquid at a rate m! in and it experiences the pressure of the surroundings Pin .
Through the bottom of the tank flows m! out and just inside of the tank the pressure is Pout :

m! in , Pin

h M,ρ

m! out , Pout

The tank can be in one of to states:


1. There is liquid in the tank – this state is called ‘Flow’
2. There is no liquid in the tank – this state is called ‘No Flow’

In state 1 the equations are


dM
= m! in − m! out
dt (7.1)
0 = Pout − Pin − ρ ⋅ g ⋅ h
And in state 2 the equations are
dM
= m! in − m! out
dt
0 = m! out (7.2)
0 = Pout − Pin
In both states, the height is calculated as:
4⋅M
h= (7.3)
ρ ⋅ π ⋅ D2
D is the diameter of the tank.

To avoid shifting between the to states constantly, it is defined that the tank goes from state 1 to
2 when the height becomes 0. And the tank goes from state 2 to 1 when the height is larger than
0.01.

WinDali Morten Juel Skovrup


7 Component file format 67

In state 1 the mass flow out of the tank is decided by what is outside the tank, while in state 2 the
tank decides the outlet mass flow itself. This indicates that the tank should make the two states
Output states, as there might be other components which wants to know when the mass flow is 0.

Note that the tank has no internal static variables, even though it specifies static equations. The
variables in the two states equal the connection variables.

The complete tank model looks like this:

TmjsTankModel =
class(TmjsComponentModel)
m_in,m_out,P_in,P_out : Double;
D,h,M : Double;
constructor Create(AModel : TmjsSystemModel; AName : PChar); override;
procedure ModelEquations(Time : Double; State : Integer;
var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double); override;
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); override;
end;

constructor TmjsTankModel.Create(AModel: TmjsSystemModel; AName : PChar);


begin
inherited Create(AModel,AName);
AddConnector(TmjsMPConnector,'In');
AddConnector(TmjsMPConnector,'Out');
SetPinVar(m_in,'In','m');
SetPinVar(P_in,'In','P');
SetPinVar(m_out,'Out','m');
SetPinVar(P_out,'Out','P');
AddDynamic(M,100,'Mass','Initial mass [kg]');
AddFloatParam(D,0.6,'Tank diameter [m]');
AddExtra(h,'h',True);
AddState('Flow');
AddState('No Flow');
AddOutState('Flow','1');
AddOutState('No Flow','2');
end;

WinDali Morten Juel Skovrup


68 7 Component file format

procedure TmjsTankModel.ModelEquations(Time: Double; State: Integer;


var Rc: Integer; var R: array of Double; var Yc: Integer;
var YDot: array of Double);
begin
h := M/(Rho*Pi/4*Sqr(D));
if State = 1 then
begin
YDot[Yc] := m_in-m_out;
h := M/(Rho*Pi/4*Sqr(D));
R[Rc] := P_out-Rho*g*h-P_in;
end
else
begin
YDot[Yc] := m_in;
R[Rc] := m_out;
end;
Rc := Rc+1;
Yc := Yc+1;
end;

procedure TmjsTankModel.StateShift(Time: Double; State: Integer;


var G: array of Double);
begin
case State of
1 : SwitchToState(2,h,G);
2 : SwitchToState(1,0.01-h,G);
end;
end;

Now let us create a model of a pipe that we ultimately want to connect to the outlet of the tank.

The pipe model is special in that the mass flow into the pipe equals the mass flow out of the pipe.
The pressure drop in the pipe is calculated using Colebrooks formula. The pipe is modeled as a
vertical pipe where the density of the fluid is considered, that is the pressure at the bottom of the
pipe is calculated as the top pressure plus the pressure of the liquid minus the friction pressure
drop. If the pipe model is created with no regard to whether the mass flow is 0 into the pipe and
the pipe is connected to the tank at the inlet and to the surroundings at the outlet, then the
pressure at pipe inlet will not be correct at zero mass flow. At zero flow the tank model specifies
that the flow should be zero. If the pipe model has the following equation for the pressure:
0 = ( Pin − Pout ) − ∆Pfric + ρ⋅ g ⋅ L (7.4)
Then at zero flow (and Pout=0), it would mean that:
Pin = −ρ ⋅ g ⋅ L (7.5)
For this reason, the pipe model defines two input states, to identify when a zero-flow condition
occurs:

WinDali Morten Juel Skovrup


7 Component file format 69

TmjsPipeModel =
class(TmjsComponentModel)
m_in,m_out,P_in,P_out : Double;
D,L : Double;
f,Re,V : Double;
constructor Create(AModel : TmjsSystemModel; AName : PChar); override;
procedure ModelEquations(Time : Double; State : Integer;
var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double); override;
end;

implementation

constructor TmjsPipeModel.Create(AModel: TmjsSystemModel; AName : PChar);


begin
inherited Create(AModel,AName);
AddConnector(TmjsMPConnector,'In');
AddConnector(TmjsMPConnector,'Out');
SetPinVar(m_in,'In','m');
SetPinVar(P_in,'In','P');
SetPinVar(m_out,'Out','m');
SetPinVar(P_out,'Out','P');
SetThroughConnectors('In,Out','m');
AddFloatParam(D,0.01,'Diameter [m]');
AddFloatParam(L,10,'Length [m]');
AddExtra(f,'f',True);
AddExtra(Re,'Re',True);
AddExtra(V,'V',True);
AddInState('Flow',1);
AddInState('No Flow',0);
end;

procedure TPipeModel.ModelEquations(Time: Double; State: Integer;


var Rc: Integer; var R: array of Double; var Yc: Integer;
var YDot: array of Double);
begin
V := m_out/(Rho*Pi/4*Sqr(D));
f := fFac(Rho,V,D,Mu,0);
Re := ReynoldsNumber(Rho,V,D,Mu);
if State = 1 then
R[Rc] := (P_in-P_out)-f*Rho*L/D*Sqr(V)/2+g*L*Rho
else
R[Rc] := (P_in-P_out); {ignoring liquid in pipe when no flow}
Rc := Rc+1;
end;

WinDali Morten Juel Skovrup


70 7 Component file format

7.3 Sources and sinks


Sources and Sinks are a special type of components. Both types can only have one connector
with one pin, and because of that they implement a special function to install that pin (so that
AddConnector and SetPinVar does not have to be called).

The function has the following heading:

procedure CreatePin(AName : PChar; var Variable : Double; PinType : Byte);

Sources are components that explicitly calculate the value of the pin. Often sources only contain
a constant; but they can also define their own ModelEquations procedure, which can be used to
calculate the pin value. Sources have to inherit from TmjsSource, for example:

{Mass flow source}


TmjsMSource =
class(TmjsSource)
m,mRef : Double;
constructor Create(AModel : TmjsSystemModel; AName : PChar); override;
procedure ModelEquations(Time : Double; State : Integer;
var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double); override;
end;

constructor TmjsMSource.Create(AModel: TmjsSystemModel; AName: PChar);


begin
inherited Create(AModel,AName);
CreatePin('m',m,1);
AddFloatParam(mRef,0,'Massflow [kg/s]');
AddExtra(m,'m',True);
end;

procedure TmjsMSource.ModelEquations(Time: Double; State: Integer;


var Rc: Integer; var R: array of Double; var Yc: Integer;
var YDot: array of Double);
begin
m := Time*mRef;
end;

Sinks are used to connect to the pins of components that are not connected to either sinks or
other components (in fact the system automatically connects sinks to any pins that are
unconnected when the model is run). The pin of a sink is automatically a static variable, but this
is all handled by the system, so you should not be concerned about creating any equations for
sinks. Sinks have to inherit from TmjsSink, for example:

{Mass flow sink}


TmjsMSink =
class(TmjsSink)
m : Double;
constructor Create(AModel : TmjsSystemModel; AName : PChar); override;
end;

WinDali Morten Juel Skovrup


7 Component file format 71

constructor TmjsMSink.Create(AModel: TmjsSystemModel; AName: PChar);


begin
inherited Create(AModel,AName);
CreatePin('m',m,1);
AddExtra(m,'m',True);
end;

7.4 Signals
Signals are just a method for transferring the value of a variable from one component to another.
A component can specify that in want to receive a signal from another component by calling
AddSignal in its constructor:

procedure AddSignal(AName : PChar; var Variable : Double);

The parameter Variable will be the parameter that receives the signal.

When a component has specified that it wants to receive a signal from another component, you
can connect any variable to the signal – that is any pin of any components connector, but also
internal variables that a component specify. This can be useful if a COP for a refrigerant system
has to be calculated. Then the system component can receive signals from the evaporator and
compressor to calculate the COP.

7.5 Controllers
Controllers are as Sources and Sinks special kind of components. Controllers should always
inherit from TmjsController.

Controllers are typically used for control purposes. They can:


• Have local, input and output states.
• Have dynamic equations
• Have static equations
• Receive signals from other components.

The only limitation to controllers is that they cannot be connected to other components, and they
can therefore not have connectors.

Typical controller components are thermostats, PI and PID controllers, adaptive controllers etc.

7.6 Systems
System components are the base on which other components are connected. System components
have the same features as a normal component, except that they cannot have connectors – so they
cannot be connected to other components. They can have both parameters, dynamic and static
variables/equations and they can have states with the exception of input and output states.

All system components have to inherit from TmjsSystemModel. This ensures that the system
component is able to connect components, states and signals.

The connection functions in TmjsSystemModel are the following:

WinDali Morten Juel Skovrup


72 7 Component file format

function Connect(Model1 : TmjsComponentModel; ConnectorName1 : PChar;


Model2 : TmjsComponentModel; ConnectorName2 : PChar) : Boolean;

Calling this function connects the connector with ConnectorName1 to the connector with
ConnectorName2. Model1 and Model2 are the models that have a connector with
ConnectorName1 and ConnectorName2 respectively. NOTE two components cannot be
connected to the same connector!

function ConnectToPin(SourceSink : TmjsSourceSink;


Model : TmjsComponentModel; ConnectorName,PinName : PChar) : Boolean;

Calling this function connects a source or a sink with the pin that has the name PinName.
SourceSink can be either a source or a sink. Model is the component that has the
connector with the name ConnectorName, and PinName is the name of one of the pins of
the connector.

function ConnectStates(InModel : TmjsComponentModel; InStateName : PChar;


OutModel : TmjsComponentModel; OutStateName : PChar) : Boolean;

ConnectStates connects a input-state with an output-state. InModel is the model that


has the input-state with name InStateName. OutModel is the model that has the output-
state with name OutStateName.

function ConnectSignal(WantSignal : TmjsComponentModel; SignalName : PChar;


HasSignal : TmjsComponentModel; ConnectorName,PinName : PChar) : Boolean;

ConnectSignal connects a pin-variable to a component that wants a signal. WantSignal


is the component that wants the signal. SignalName is the name of the signal that is to be
connected. HasSignal is the component that has the connector with name
ConnectorName, while PinName is the name of the pin the signal should connect to.

function ConnectSignalVar(WantSignal : TmjsComponentModel;


SignalName : PChar; var Variable : Double) : Boolean;

ConnectSignalVar does exactly the same as ConnectSignal, except that


ConnectSignalVar connects a variable from a component to the signal – this could for
example look like:

ConnectSignalVar(PipeModel,'Mass',TankModel.M);

function ConnectSysSignal(SignalName : PChar; HasSignal : TmjsComponentModel;


ConnectorName, PinName : PChar) : Boolean;

ConnectSysSignal does exactly the same as ConnectSignal, except that


ConnectSysSignal assumes that the component that wants the signal is the system
component itself.

function ConnectSysSignalVar(SignalName : PChar; var Variable : Double) :


Boolean;
ConnectSysSignalVar does exactly the same as ConnectSignalVar, except that
ConnectSysSignalVar assumes that the component that wants the signal is the system
component itself.

WinDali Morten Juel Skovrup


7 Component file format 73

procedure AddController(AController : TmjsController);


Adds a controller to the system.

procedure AddModel(AModel : TmjsComponentModel);


Adds a model to the system. This procedure should only be called to add components to
the system that are not connected to other components by a call to Connect.

Besides of the connection functions, the system component has the following properties:

StrictConnect : Boolean;
OneParamPage : Boolean;
ShowModelInfo : Boolean;

Setting StrictConnect to true requires connectors to be of the same type to be connected. If it is


false then the only requirement is that they have the same number of pins – default is True.

Setting OneParamPage to true makes all parameters of all components appear on the same page
in the Simulation program. If it is set to false, then each component gets its own page – default is
False.

Setting ShowModelInfo to true will create a page in the Simulation program with information
about the system model. The page will contain information on variable reduction, states and the
connections- default is true (see also chapter 7.7).

The system component does not have to be changed to be useful. In most situations the system
component is just an instance of TmjsSystemModel.

The model file format is still used for creating the system model. In SetUpProblem instances of
the components and the system model is created, and the components are connected. Below is
the complete model file for the Tank-Pipe example from 7.2.5.

WinDali Morten Juel Skovrup


74 7 Component file format

unit Problem6;

interface

uses
CmjsComponents,CmjsTestComponents,CmjsSourceSinkLib;

procedure SetUpProblem; export; stdcall;


procedure ModelEquations(Time : Double; State : Integer;
var R : array of Double;
var YDot : array of Double); export; stdcall;
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); export; stdcall;
procedure OnStateChange(Time : Double;
OldState,NewState : Integer); export; stdcall;
procedure PreCalc(Time : Double; State : Integer); export; stdcall;
procedure OnSolution(Time : Double; State : Integer); export; stdcall;
procedure EndCalc(Time : Double; State : Integer); export; stdcall;
procedure OnQuit; export; stdcall;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer;
Value : Double); export; stdcall;
procedure OnSaveSettings(FileName : PChar); export; stdcall;
procedure OnLoadSettings(FileName : PChar); export; stdcall;

implementation

var
AModel : TmjsSystemModel;
Tank1 : TmjsTankModel;
Pipe1 : TmjsPipeModel;
mSource1 : TmjsMSource;
PSource1 : TmjsPSource;
PSource2 : TmjsPSource;
mSink1 : TmjsMSink;

procedure SetUpProblem; stdcall;


begin
AModel := TmjsSystemModel.Create('System');
Tank1 := TmjsTankModel.Create(AModel,'Tank1');
Pipe1 := TmjsPipeModel.Create(AModel,'Pipe1');
mSource1 := TmjsMSource.Create(AModel,'Source1');
PSource1 := TmjsPSource.Create(AModel,'Source2');
PSource2 := TmjsPSource.Create(AModel,'Source3');
mSink1 := TmjsMSink.Create(AModel,'Sink1');
with AModel do
begin
ConnectToPin(mSource1,Tank1,'In','m');
ConnectToPin(PSource1,Tank1,'In','P');
Connect(Tank1,'Out',Pipe1,'In');
ConnectToPin(mSink1,Pipe1,'Out','m');
ConnectToPin(PSource2,Pipe1,'Out','P');
ConnectStates(Pipe1,'Flow',Tank1,'Flow');
ConnectStates(Pipe1,'No Flow',Tank1,'No Flow');
end;
AModel.OneParamPage := True;
AModel.SysSetUpProblem;
AModel.SysSolverSettings('Tank model',0,3600,1,True,1);
end;

WinDali Morten Juel Skovrup


7 Component file format 75

procedure ModelEquations(Time : Double; State : Integer;


var R : array of Double;
var YDot : array of Double); stdcall;
begin
AModel.SysModelEquations(Time,State,R,YDot);
end;

procedure StateShift(Time : Double; State : Integer;


var G : array of Double); stdcall;
begin
AModel.SysStateShift(Time,State,G);
end;

procedure PreCalc(Time : Double; State : Integer); stdcall;


begin
AModel.SysPreCalc(Time,State);
end;

procedure OnStateChange(Time : Double;


OldState,NewState : Integer); stdcall;
begin
AModel.SysOnStateChange(Time,OldState,NewState);
end;

procedure OnSolution(Time : Double; State : Integer); stdcall;


begin
AModel.SysOnSolution(Time,State);
end;

procedure EndCalc(Time : Double; State : Integer); stdcall;


begin
AModel.SysEndCalc(Time,State);
end;

procedure OnQuit; stdcall;


begin
AModel.SysOnQuit;
AModel.Free;
Tank1.Free;
Pipe1.Free;
mSource1.Free;
PSource1.Free;
PSource2.Free;
mSink1.Free;
end;

procedure OnUIValueChange(UIType : Integer;


Num,State,Choice : Integer;
Value : Double); stdcall;
begin
AModel.SysOnUIValueChange(UIType,Num,State,Choice,Value);
end;

procedure OnSaveSettings(FileName : PChar); stdcall;


begin
AModel.SysOnSaveSettings(FileName);
end;

WinDali Morten Juel Skovrup


76 7 Component file format

procedure OnLoadSettings(FileName : PChar); stdcall;


begin
AModel.SysOnLoadSettings(FileName);
end;

end.

Several of the procedures do only one thing: call the corresponding procedure in the system
component. The procedures in the system component are named as the procedures in the model
file, except that they have added a “Sys” in front.

Noting that the system component is called AModel, the procedures, which are handled entirely
by the system component, are:

Procedure in model file Handled by calling


ModelEquations AModel.SysModelEquations
StateShift AModel.SysStateShift
PreCalc AModel.SysPreCalc
OnStateChange AModel.SysOnStateChange
OnSolution AModel.SysOnSolution
EndCalc AModel.SysEndCalc
OnUIValueChange AModel.SysOnUIValueChange
OnSaveSettings AModel.SysOnSaveSettings
OnLoadSettings AModel.SysOnLoadSettings

Only two procedures are left.

OnQuit is handled by first calling AModel.SysOnQuit and then all the components (including the
system component) are freed.

In SetUpProblem the components that are used are created and the components are connected. In
the Tank-pipe example, 7 components are used:

Component Meaning
AModel The system component
Tank1 The tank
Pipe1 The pipe
mSource1 Mass flow source to be connected to the tank
pSource1 Pressure source to be connected to the tank
mSink1 Mass flow sink to be connected to the pipe
PSource2 Pressure source to be connected to the pipe

In SetUpProblem first the 7 components are created. Note that the components take the system
component as a parameter in their constructor.

WinDali Morten Juel Skovrup


7 Component file format 77

Then the following lines are executed:

1 with AModel do
2 begin
3 ConnectToPin(mSource1,Tank1,'In','m');
4 ConnectToPin(PSource1,Tank1,'In','P');
5 Connect(Tank1,'Out',Pipe1,'In');
6 ConnectToPin(mSink1,Pipe1,'Out','m');
7 ConnectToPin(PSource2,Pipe1,'Out','P');
8 ConnectStates(Pipe1,'Flow',Tank1,'Flow');
9 ConnectStates(Pipe1,'No Flow',Tank1,'No Flow');
10 end;

Line number Meaning


3 Mass flow source 1 is connected to the m pin of the In connector of Tank1.
4 Pressure source 1 is connected to the P pin of the In connector of Tank1.
5 Tank1’s Out connector is connected to Pipe1’s In connector.
6 Mass flow sink 1 is connected to the m pin of the Out connector of Pipe1.
7 Pressure source 2 is connected to the P pin of the Out connector of Pipe1.
8 The input state Flow of Pipe1 is connected to the output state Flow of Tank1.
9 The input state No Flow of Pipe1 is connected to the output state No Flow of
Tank1.

Graphically the connections look like this:

WinDali Morten Juel Skovrup


78 7 Component file format

Mass flow Pressure


source 1 source 1

m pin P pin
In connector

Output state Output state


"No Flow" Tank1 "Flow"

Out connector
m pin P pin

m pin P pin
In connector

Input state Input state


"No Flow" Pipe1 "Flow"

Out connector
m pin P pin

Mass flow Pressure


sink 1 source 2

The three next lines in SetUpProblem have the following meaning:

AModel.OneParamPage := True;

Since there are so few components, all parameters are collected in one page in the simulation
program.

AModel.SysSetUpProblem;

Sets up the system. Always call SysSetUpProblem as the second last function in SetUpProblem.

AModel.SysSolverSettings('Tank model',0,3600,1,True,1);

Does exactly what SolverSettings (see 6.2.1) do, except that the initial state can be somewhat
difficult to foresee as the system states are combined from the individual component states.
SysSolverSettings should be called as the last function in SetUpProblem.

WinDali Morten Juel Skovrup


7 Component file format 79

7.7 Documentation
Each system, component, source, sink and controller has a method called AddDocumentation,
which they can override to provide information to the user of the simulation program.

When a system model is loaded in the simulation program a page called ModelInfo is created.
This page will contain information on the following items:

• The connection variables that WinDali has found, and how many they can be reduced to.
• The states for the system, and which states the model is allowed to switch between
• The static variables in each state
• The connections that are defined between the components
• A section including information on each component used in the model

The section with information on the components, contain information on the following items for
each component:
• The parents of the component
• The variables and parameters of the component.
• And information specified by the component modeler.

The information specified by the component modeler is added by overriding the


AddDocumentation method of a model:

{Heat source}
TmjsQSource =
class(TmjsSource)
{Connection variable (and parameter):}
Q : Double; {Heat flow [W]}
constructor Create(AModel : TmjsSystemModel; AName : PChar); override;
procedure AddDocumentation(AList : TStringList); override;
end;

and the implementation of could look like this:

procedure TmjsQSource.AddDocumentation(AList: TStringList);


begin
AList.Add('Constant heat source');
AList.Add('Several lines can be added…');

end;

WinDali Morten Juel Skovrup


80 7 Component file format

WinDali Morten Juel Skovrup


8 Common problems 81

8 Common problems
When compiling a model in WinDali the following problems can occur:

Problem Solution
Fatal Can’t find unit mjsDllTypes Go to Project|Options menu and select
Directories/Conditionals tab. In the Unit directory box
write InstallDir\lib, where InstallDir is the directory where
WinDali is installed (default c:\windali)
Problems compiling a model and When you open a model be sure to use File|Open project.
thereafter running it Models are always saved in projects (not in single files).
Problem compiling a model (can’t Remember to close the Simulation program before
create model file) compiling the model currently loaded in the Simulation
program

WinDali Morten Juel Skovrup


82 8 Common problems

WinDali Morten Juel Skovrup


9 Using refrigerant equations 83

9 Using refrigerant equations


With WinDali comes a package with equations for the thermodynamic and thermophysical
properties of 45 refrigerants. These equations can be directly used in your models.

To include one of the refrigerants do the following:


1. Include CRefrigWrapper in your uses clause
2. Create a TRefrigerantWrapper object’
3. Use the equations
4. Free the object.

Example:

unit Problem;
uses
mjsDllTypes, CRefrigWrapper;
:
implementation
var
Refrig : TRefrigerantWrapper;

procedure SetUpProblem;
begin
{The Refrig object is created a R717 is selected as refrigerant}
Refrig := TRefrigerantWrapper.Create;
Refrig.RNumber := 'R717';
end;

procedure ModelEquations(Time : Double; State : Integer;


var R : array of Double;
var YDot : array of Double);
begin
:
PDew := Refrig.PDewT(273.15); {Calculating dewpoint pressure}
:
end;

procedure OnQuit;
begin
Refrig.Free;
end;

In the example above, the refrigerant is fixed to R717, but you might want to let the user select
the refrigerant from a listbox in the Simulation program. This can be done the following way:

WinDali Morten Juel Skovrup


84 9 Using refrigerant equations

unit problem;
interface
uses
mjsDLLTypes, CRefrigWrapper;

implementation
var
Refrig : TRefrigerantWrapper;

procedure SetUpProblem;
var
RefStr : PChar;
Len : Integer;
begin
{Create the TRefrigerantWrapper object}
Refrig := TRefrigerantWrapper.Create;
SetParamPages('Refrigerant');

{Get all supported refrigerants in a string, but first get the necessary
length of the string}
Len := Refrig.GetFullNamesSorted(PChar(nil));
{Allocate memory - remembering the terminating null character}
GetMem(RefStr,Len+1);
Refrig.GetFullNamesSorted(RefStr);
{Add the refrigerant to a listbox:}
AddListParam(RefNum,3,RefStr,'Refrigerant',1);
{Remember to free RefStr after it's been used:}
FreeMem(RefStr,Len+1);
end;

procedure PreCalc(Time : Double; State : Integer);


begin
{Update the refrigerant to the one the user has selected}
Refrig.SortedNumber := RefNum;
end;
procedure OnQuit;
begin
{Free the refrigerant object}
Refrig.Free;
end;

You can inspect CRefrigWrapper.pp in the \lib directory to see which functions you can call
with a TRefrigerantWrapper object, or browse the documentation installed with WinDali.

You can also get full package of equations by contacting the author (see 1.1). The package also
includes routines, so that the equations can be used from Delphi, C++, Fortran, Matlab,
Simulink, Excell and other programs. The package is freeware.

WinDali Morten Juel Skovrup


10 Free Pascal Editor 85

10 Free Pascal Editor


Free Pascal Editor (FPE) is a text editor with capabilities to interact with Free Pascal Compiler.
Free Pascal Compiler (FPC) is a freeware 32-bit compiler, compatible with Borland Turbo
Pascal™, and partially compatible with Borland Delphi™.

FPC is available from the following web-address:


http://www.freepascal.org/

FPC is an ongoing project, so you should check for updates at the address above.

Documentation and licensing information about FPC can be found at the above web-address.

When you start FPE and select New and Basic Model you get the following screen:

Figure 11. Free Pascal.

WinDali Morten Juel Skovrup


86 10 Free Pascal Editor

• Project Manager is an overview of the files in your current project. When you compile
your project, only the files listed in the Project Manager and the libraries (units) used by
these files will be compiled (i.e. other files you may have opened in the Code Editor will
NOT be compiled). When you double click on a file in Project Manager, the file will
open in the Code Editor.
• Code Explorer gives an overview of the procedures, types, variables etc. in the current
file in the Code Editor. When you double click on a procedure in the Code Explorer you
will be brought to the implementation of that procedure in the code. This can be very
useful when you want to browse your code. Note that the Code Explorer is not updated
automatically. When you make changes in your code you have to press the Update button
to update the Code Explorer. The following icons are used in Code Explorer:
Procedure, Constructor or Destructor
Function
Class
Type
Unit
Variable/Constant
The Code Explorer also has some syntax checking capabilities. If it finds errors in the
code, they will appear in the Message Window. As the capabilities are limited it will
sometimes display errors that are not really errors – so you should only regard these
messages as guidelines, and not as “real” errors.
• Code Editor is where you edit the files in your project. The Code Editor can be
customized in numerous ways by selecting the Tools|Environment Options menu.
• Message Window will display messages from the compiler. If an error occurs you can
double click on the description of the error in the Message Window, and you will be lead
to the place in the code that caused the problem. The Message Window has two pages:
1. Ordered, where the messages from the compiler is sorted
2. All, where all messages from the compiler is displayed without any sorting.

Most menu items in FPE should be self-explaining, but a few require some comments.

WinDali Morten Juel Skovrup


10 Free Pascal Editor 87

Menu Item Explanation


File Print Table of Prints an overview of the procedures and types in the code,
Contents including page numbers. Use File|Print and select Table of
Contents to print both the unit and the table of contents.
Save File as The current file is saved as a template
Template
Edit Copy mode Lets you select if the text copied in the editor should be in RTF
(Rich Text Format), HTML or normal text. If a text is copied in
RTF or HTML format to a word processing program, then the font
and syntax highlighting is preserved.
Search Insert/Goto You can define up to 10 bookmarks in your code. These
Bookmark bookmarks are not saved with the file.
Project Save Project as Allow you to save the current Project as a template. The template
Template will be selectable from the File|New menu.
View Source Opens the Project source as read only. This is only for inspection.
Options Displays the Project Options dialog – see later.
Run Parameters Allow you to add command line parameters to the executable
when your project is run. If the project is a DLL you first have to
specify an executable that uses the DLL.
Compile, Build, Compile recompiles files that have been changed since last
Build all compile. Build, recompiles all files even though they haven’t
changed since last compilation. Compile and Build are direct calls
to FPC; but as Build not always produce the expected result, Build
All has been added to the compile options. Build All ensures that
all binary files are deleted before the compiler starts compiling.
This forces the compiler to recompile all files the project depends
on.
Tools Environment See later
Options
Find Compiler If the program for some reason could not find the Free Pascal
Compiler when it started, you can manually start a new search by
selecting this menu.
Macro Press <Ctrl>+<Shift>+R to start recording a macro. When you
have finished recording press <Ctrl>+<Shift>+R again. To play
the macro press <Ctrl>+<Shift>+P. You can only have one macro
at a time, and it can not be saved.
Configure Tools Allow you to add items to the Tools menu; where an item starts
another program. When you install FPE there is already added a
tool, which starts the Simulation Program. When you add a tool
you can use the following macros:
%EXEPATH Path to FPE (default c:\WinDali)
%EDITNAME Name of the current file in the Code
Editor
%EXENAME Name of the project executable – i.e.
the name of the resulting file when the
project is compiled

WinDali Morten Juel Skovrup


88 10 Free Pascal Editor

10.1 Project Options


Project options apply only to the project you are currently working with. Options can be saved
and loaded and you can change the default options.

When you select the Project|Options menu you will see the following dialog:

Figure 12. Project options.

The dialog contains a number of possible settings that mostly has to do with FPC. The most
important settings will be explained shortly below. For more information see the FPC
documentation.

Application

Application name Name of the resulting file, when the project is compiled.
Application extension Extension of the resulting file, when the project is compiled.
Target
Win32 Build Win32 application (or DLL)
DOS Build DOS application

NOTE: to use both targets, you need the Win32 and the DOS version of FPC. WinDali only
comes with the Win32 version.

WinDali Morten Juel Skovrup


10 Free Pascal Editor 89

Compiler

Code generation
Optimize for speed Optimize code for speed (default)
Optimize for size Optimize code for size of compiled file
Level 1 optimizations Only simple optimizations, but fast compilation.
(quick optimizations)
Level 2 optimizations More time consuming and extensive optimizations (default)
(Level 1 + some slower
optimizations)
Level 3 optimizations Should be used with caution. The optimizations could cause
(Level 2 + uncertain erroneous behaviour of your code (read the FPC documentation).
optimizations)
Runtime Errors
Range checking Checks that array and string indexes are within bounds (default on).
I/O checking Checks for I/O errors after every I/O call (file operations) (default
on).
Overflow checking Checks for numerical overflow in integer operations (default on).
Debugging
Generate browse info Generates information that can be used by a code browser/debugger.
Include local Includes local symbols in the browser information.
Syntax Options
Delphi compatible Compatible with Delphi (default on).
TP 7.0 compatible Compatible with Turbo Pascal.
Delphi 2 extensions Some extensions specific for Delphi version 2 are supported.
Support C-style Support expressions like x += 1 (which in standard Pascal has to be
operators (*=, +=, /= and written as x := x+1
-=)
Gpc (Gnu Pascal Compatible with GNU Pascal Compiler
Compiler) compatible
Support label and goto Allow use of label and goto as in standard Pascal (default on).
commands
Messages
Show hints Show the hints the compiler might return (default on).
Show warnings Show the warnings the compiler might return (default on).
Show notes Show the notes the compiler might return (default on).
Show general Show some general information about the compilation (default on).
information

Linker

Debugging
Generate dbg info for use with GDB Generate information that can be used with GNU
debugger
Generate dbg info for use with DBX Generate information that can be used with DBX
Use the heaptrc unit Use the heap-trace unit

WinDali Morten Juel Skovrup


90 10 Free Pascal Editor

Exe and DLL options


Generate Console application Create console application (like old time dos
applications – but 32 bit)
Include .reloc section Includes .reloc section in the executable. Default on
for DLL’s.
Misc
Strip symbols from executable Strips all symbols from an executable. Default off for
a DLL.
Generate profiler code for gprof Generate code that can be used with GNU profiler.
Omit linking Skip the linking stage. This can then be done
manually after compilation.
Linker output
Do not delete generated assembler files Prevents deletion of assembler files created by the
compiler. You can select between several types of
assembler.
Memory
Size of reserved heap space Size of heap space the programs reserve at startup
(default 8000000 bytes)
Stack size Maximum size of the stack (default 1048576).
Image base Preferred load address of the compiled image (default
$10000000)

Additional

Additional options – read FPC documentation.

Directories/Conditionals

Output directory Directory where executable/DLL should be placed.


Unit output directory Directory where compiled units should be placed.
Unit directory Directory where compiler should look for unit source files.
Library directory Directory where compiler should look for compiled unit files.
Include directory Directory where compiler should look for files included with {$I
filename} compiler directive.
Object directory Directory where compiler should look for object files included with
{$L filename} compiler directive.
Conditional defines Compiler conditional defines that should be enabled for all files in the
project.
Conditional undefines Compiler conditional defines that should be disabled for all files in the
project.

10.2 Environment Options


When you select the Tools|Environment Options menu you will see the following dialog:

WinDali Morten Juel Skovrup


10 Free Pascal Editor 91

Figure 13. Environment options.

Preferences
Default project directory Where you want FPE to look for your projects as default
Number of files in recently Number of files the FPE keeps in the recently used file list.
used file list
Backup levels Number of backup files to keep. One backup level creates backup
files names filename.~ext. two backup levels keeps two backup
files named filename.~ext and filename.~ext_1, etc.
Only allow one instance of If on and you associate for example .pp files with FPE the
Free Pascal Editor doubleclikking on a .pp file in a filemanager will open files in the
FPE already open and not open a new instance of the FPE
program.

Editor
Editor Speedsetting Can be Default, which selects standard windows shortcuts for common
menu items, or IDE classic, which selects shortcuts as known from Turbo
Pascal™.
Undo limit Number of undo actions to remember.
Block indent Number of spaces to move when moving blocks
Extensions in Which file types you want to include in the Open and Save dialog box
Open/Save dialog (installed highlighter extensions are added automatically).

WinDali Morten Juel Skovrup


92 10 Free Pascal Editor

Display

Visible right margin Show a gray line to indicate the right margin
Right margin Number of characters before right margin line is drawn
Visible gutter Show visible gray area to the left. This area is used to display line
numbers and bookmarks.
Gutter width Width of the gutter in pixels.
Show line numbers Shows line numbers in the gutter.
Editor font and size The font to use in the editor.
Editor Window
Tab style Style of tabs, which are used to select the files in the editor.
Multiline tabs Allow the tabs to stretch over several lines.
Hottrack tabs Highlights the caption on a tab when the mouse is moved over it.
Ragged right Specifies whether rows of tabs stretch to fill the width of the control.
Toolbar images
Type Can be
Default: Default windows icons
Blue: More colorful icons

Code Explorer

Automatic update Specifies if the code explorer should update automatically when a
new file is loaded and when you shifts to another file.
Sort alphabetic Specifies if items in the code explorer should be sorted
alphabetically or be displayed in the order they are found in the
code.
Divide at implementation Specifies whether declaration of types, constants, variables and files
in the uses clause should be divided into items that appear in the
interface section and items that appear in the implementation
section.
Class categories Specifies whether items in a class should be sorted according to
their visibility modifier.
Run in separate thread If selected then the Code Explorer will update a bit slower, but you
will be able to edit your code while it runs (use this setting if you
work with very large files).
If not selected then the Code Explorer will update faster, but you
will not be able to edit your code while it runs.

Code Templates

Code templates are pieces of code you can insert into your code by writing only part of the code
and then press <Ctrl>+J. Try writing “be” (without quotes) in the editor and press <Ctrl>+J –
you will see it expands into:
begin

end;

WinDali Morten Juel Skovrup


10 Free Pascal Editor 93

You can add your own pieces of code by pressing Add and fill in a Shortcut (i.e. the shortcut you
write in the editor, for example be in the example above) and a description (that will help you
remember what the shortcut does). The actual code you want the shortcut to generate should be
written into the editor on the Code Templates page. You specify where you want the cursor to be
after you have applied the template by writing a “|” into the editor. Inspect the templates that
already in the program to see how it is done.

If you use Borland Delphi™ you can use the templates from Delphi by copying the file
Delphi32.dci (located in \Borland\Delphi5\bin directory) to CodeTmpl.dci (located in WinDali
directory).

Highlight
Here you install which syntax highlighters you want FPE to use – and which extensions you
want to associate with each highlighter. To add a highlighter you check it in the list box, and
perhaps change the Filter name and extensions for that highlighter. If you change Filter name or
extensions then remember to press Update Selected when done.

The Filter name is the text you see in the Open dialog box and the extensions is a list of
extensions separated with semicolons, which you want to the highlighter to work on.

You can make your own (primitive) highlighter by using the General highlighter. For the
General highlighter you can specify keywords, comment style and string delimiters.

Color

Enables you to specify the color and font style of different code elements for each highlighter.

Library

Here you specify directories that apply for all projects:

Unit directory Default directory where compiler should look for unit source files.
Library directory Default directory where compiler should look for compiled unit files.
Include directory Default directory where compiler should look for files included with
{$I filename} compiler directive.
Object directory Default directory where compiler should look for object files included
with {$L filename} compiler directive.

Associations

In this page you can specify the file extensions that FPE should be associated to. Note that if you
uninstall WinDali, these associations will still exist in the registry. Before you uninstall WinDali
you should deselect any associations you have created. This will delete the corresponding keys in
the registry.

WinDali Morten Juel Skovrup


94 10 Free Pascal Editor

WinDali Morten Juel Skovrup


11 Simulation program 95

11 Simulation program
When you start the simulation program you will see the following screen (not all windows will
be expanded):

Figure 14. Simulation Program.

The items in the program are:


• Plot Window 1 and 2, where results are plotted. You can add as many plots as you want.
Normally only Plot Window 1 is open, but you can display number 2 by pressing
• Curve Window, where the variables you can plot will be displayed. If both plot 1 and 2
are visible, then the first column checkboxes select curves in plot 1 and the second
column selects curves in plot 2.
• Message Window, which has two pages:
o Solver, where messages from the solver are displayed.
o Debug, where debug messages from the model are displayed.
• Solver & Model Settings window, where the parameters and settings you can change are
ordered.
• Data window where you can inspect the numerical values of the selected variables. You
bring up the data window by pressing
• Online parameters where you can change parameters during the simulation (see chapter
11.2).

WinDali Morten Juel Skovrup


96 11 Simulation program

The look of the Solver & Model Settings window (SMS window) will change according to the
model that is loaded. As default the SMS window will create the following pages:

General
TStart Start time for simulation
TEnd End time for simulation
Infinite simulation If checked then the simulation runs until you press Stop. The plot
window size defines the time range shown in the plot windows.
Real time simulation If checked then the simulation will be run in real time. You can also
specify how often the screen (plots and data) should be updated.
When running real time simulations, you can control the speed of the
simulation by adjusting the slider. The maximum speed depends on
the screen update value you specify (it equals 1000·the screen update
value). A speed of 1 means that one simulated second will take 1
second in real time. A speed of 1000 means that 1000 simulated
seconds will take 1 second in real time. The max speed will also
depend on how fast the solver is able to actually solve the equations,
so the value of the speed slider is not always accurate.
Initial state The state the simulation should start in
Save data to ASCII file Saves data to an ASCII file. When you start the simulation, a dialog
where you can select what to save will appear.
Plot result If not selected no data will be plotted. If you save data to disk, and
you are not interested in the plots, this will speed up the simulation.
Messages Decides how to display messages from the solver (debug messages
will always be added to the Message Window).
• None, no messages are displayed (if you after a simulation
change Messages from None to Display you will be able to see
debug messages).
• Screen, messages are shown on screen
• File, messages are saved to a file you specify.
Max points on a curve Decides how many points a curve can contain. Each point on a curve
is stored in memory during simulation. If you work with very long
simulations you could eventually fill up the computer memory, if this
number is too large. When this number is reached, the program starts
to delete old points when a new point arrives. Note that if you do not
save data to disk you will lose old data when this number is reached.
Repeat count Specifies the number of times the simulation should be repeated.
Together with Update initial values (see later) you can use this to get a
periodic stationary solution.

WinDali Morten Juel Skovrup


11 Simulation program 97

Solver
Use external static… Use an external static equations solver to solve the static equations at the
initial point, and to solve the static equations the first time after a state
shift. This functionality is included because the solver included in
WinDali has a fast but not always stable static equations solver.
Sometimes it is necessary to solve the static equations the first time by
using the more stable (but also slower) external equation solver. After
the first solution is obtained, the internal static equation solver is
normally sufficient.
External solver A list of external solvers that can be used
Use fixed sample If checked the solver will be forced to create a solution at the sample
time time you specify – i.e. if you specify a sample time of 10 seconds, then
the solver will make a solution at Time=10, Time=20 etc. but it might
also produce solutions in between the samples.

The contents of the Solver page also depends on the solver you have loaded (see 11.4).

Initial
This page will only be created if the model has dynamic variables. The page allows you to
change the default initial values for the dynamic variables.

The program automatically creates a checkbox called Update initial values, that when checked:
• Updates the initial values to the last solution point in the simulation when the simulation
ends.
• Updates the initial state to the state the model was in, when the simulation ended.

Guesses
The Guesses page will automatically be created if the model contains static variables. The page
allows you to change the default guesses for the static variables in the different states.

The program automatically creates a checkbox called Update guesses, that when checked
updates the guesses on the static variables in all states. The guesses in a state are updated to the
first solution found when the model was in that state.
The page also has a checkbox called “No model guess”, which if checked prevent the loaded
model from providing any guesses it might want to set (i.e. calls to SetGuess from the model are
prevented).

Results
If the model includes extra variables that are not plotted, their value will be displayed on this
page when the simulation stops.

Cases
- see chapter 11.3

WinDali Morten Juel Skovrup


98 11 Simulation program

11.1 Menu commands


File menu
Item Explanation Shortcut/toolbar
Open Model Open a new model. The icon on the toolbar keeps a list over or
previously opened models.
Open Solver Loads a new Solver. or
New Clears the filename that the user previously has saved the Ctrl+N, or
settings under.
Default Load the settings from the model-file and ignore if a default or
settings-file exists (see below)
Open Open a settings file. A settings file includes all information Ctrl+O, or
of the parameters the user can change in the Simulation
program. Settings files have extension .set
Save Save settings. Ctrl+S, or
Save as Save settings with a new file name. or
Print Report Print report of a simulation. The report can contain settings or
and plots. The print will contain the current date and time.
Exit Exit the simulation program. or

If you save a settings file with the same name as the model file (but with extension .set) this file
will be loaded as default when the model is loaded.

The Plot, Edit, Draw, View and Format menus are explained in the accompanying help file
(select the Help|Plot menu), except for the following items in the plot menu:

Plot menu
Item Explanation Shortcut/toolbar
Add plot Add a new plot page
Delete plot Delete a plot page
Data window Show/hide data window
Second plot Show/hide the second plot on a page
Create curve Create a curve by combining two existing curves (phase
plot)
Next plot Move to next plot F9
Previous plot Move to previous plot F10

Simulation menu
Item Explanation Shortcut/toolbar
Start Start simulation F2 /
Step Make one step F3 /
Pause Pause the simulation F4 /
Stop Stop simulation F5 /

WinDali Morten Juel Skovrup


11 Simulation program 99

Tools menu
Environment options See below
Create distributable copy See chapter 12
Configure tools Allow you to add program items to the Tools menu.

The environments options dialog allows you to customize the Simulation Program.

Figure 15. Environment Options.


Application
Save messages to file Makes the simulation run faster. If the solver (Dali.sol) encounters
and load in display after problems it will react by outputting a lot of information. If you
simulation choose to display messages while the simulation runs (option
unchecked) then the simulation might be very slow.

Display
Colored checkboxes Makes the checkboxes in the Curve Window the same color as the
curves.
Toolbar images Can be:
Default: Default windows icons Blue:
More colorful icons

Associations
In this page you can specify the file extensions that the Simulation Program should be associated
to. Note that if you uninstall WinDali, these associations will still exist in the registry. Before
you uninstall WinDali you should deselect any associations you have created. This will delete
the corresponding keys in the registry.

11.2 Online parameters


Changes to the parameters in the Solver & Model settings window while the simulation is
running will not affect the parameters in the model (at least not until the simulation is restarted).
If you want to experiment with parameter changes while the simulation is running you need to
do it through the Online parameters window.

WinDali Morten Juel Skovrup


100 11 Simulation program

To change parameters you first have to select the parameters into the window by pressing Add
online parameters. This will bring up a dialog where you select the parameters you want to vary.
The type of parameters that can be varied are integer, float and values in enumerated choiche
parameters.

When the simulation is running you enter new values for the parameters in the New column and
press Update parameters when ready. This will change the columns so that the column
containing the new parameters will become the Current column, and the old Current column will
become the new New column. This enables you to keep track of the old parameter values while
you enter the new values.

Every time you press the Update parameters button, the changes will be recorded together with
the time the changes was effected. The log can be printed together with plots and settings when
you select File|Print report, or you can print/save it directly from the Log tab in the Online
parameters window.

11.3 Varying parameters


If you press the Vary button on the Cases page you can vary one or more of the floating point or
integer parameters. This gives possibility to easily perform parameter studies on the model. If the
model has a parameter called Pressure and you want to vary it form 1 to 10 with a step of 1, the
simulation will automatically run 10 times with Pressure having the value 1,2,3…10. The results
from the simulations are saved to one or more files.

When you press the Vary button you will see the following dialog:

Figure 16. Varying parameters.

WinDali Morten Juel Skovrup


11 Simulation program 101

In the dialog Volume is varied from 0.001 to 0.005 with step 0.001, i.e. the simulation has to run
5 times or there are 5 cases. The dependent column allows you to select, which variables you
want to save in the resulting files. You can specify to vary one or more parameters. If you for
example also selected to vary Cold temperature from 20 to 25 with step 1, you would generate
30 cases (and thereby 30 simulations):

Volume Cold Temperature


0.001 20
0.002 20
: :
0.005 20
0.001 21
0.002 21
: :
0.005 21
: :
: :
0.001 25
0.002 25
: :
0.005 25

When you vary more than one parameter, then the cases are created by varying the parameters in
the order they appear in the dialog (Volume is varied before Cold Temperature, because Volume
appears before Cold Temperature in the dialog).
When you select OK, you will see the following information in the Cases page:

Figure 17. Info on Cases page.

To actually run through the cases you have to check Run cases.

When the simulation is started you will be asked how to save the data generated from the
simulations:

WinDali Morten Juel Skovrup


102 11 Simulation program

Figure 18. File identifiers and file type.

For each of the dependent variables, you have specified, there will be created one or more files.
For each dependent variable, you have to specify a unique identifier – in the dialog T has been
assigned the identifier A. The file(s) created will have the name(s) File_ID_CaseNum.dat. If you
select individual files (binary or ASCII), and follow the example from the dialogs, the files
created will have the names: File_A_1.dat, File_A_2.dat, File_A_3.dat, File_A_4.dat and
File_A_5.dat.

You can select from these file types:

Individual ASCII files


Data will be saved to individual ASCII files, one file for each case, and one file for each
dependent variable. The files has the following structure:
Time1;Dep
Time2;Dep

TimeN;Dep

Where Dep is the dependent variable for that file, and ‘;’ represents the selected column
separator. In the example above 5 files would be created, and one file would contain:
Time1;T_1
Time2;T_2

TimeN;T_N

WinDali Morten Juel Skovrup


11 Simulation program 103

One merged ASCII file


Data for the different cases will be saved to one merged ASCII file for each dependent
variable. One file has the following structure:
Time1;InDep1;InDep2;…InDepM;Dep_case1
Time2;…

TimeN;…
Time1;InDep1;InDep2;…InDepM;Dep_case2


TimeN;InDep1;InDep2;…InDepM;Dep_caseL

Where InDep1…InDepM is the independent variables (i.e. the parameters that are varied).
In the example above the file would contain:
Time1;0.001;T_1
Time2;0.001;T_2

TimeN;0.001;T_N
Time1;0.002;T_1


TimeN;0.005;T_N
If Cold temperature also was varied the file would contain:
Time1;0.001;20;T_1
Time2;0.001;20;T_2

TimeN;0.001;20;T_N
Time1;0.002;20;T_1


TimeN;0.005;20;T_N
Time1;0.001;21;T_1



TimeN;0.005;25;T_N

Individual binary files


Data is organized exactly as for individual ASCII files, except that the binary files does
not contain line breaks or column separators.

One merged binary file


Data is organized exactly as for one merged ASCII file, except that the binary files does
not contain line shifts or column separators.

Binary files can be saved in Double or in Single format. Each value in the file takes up 8 bytes of
space in Double format, while each value in the file takes up 4 bytes of space in Single format.
All though Single format saves space, it also has fewer significant digits.

When you select OK in the dialog in Figure 18, you will be asked to specify a directory where
you want to save the data. When the simulations end, an information file called CaseInfo.txt is
written to this directory. It contains information about the created data files.

WinDali Morten Juel Skovrup


104 11 Simulation program

11.4 Dali solver


The default solver used by the simulation program, is a slightly modified version of the solver
described in [1]. The solver has the following characteristics:

• Differential equation solver: 3 step, 3. order semi-implicit Runge Kutta (NT1 developed
by Nørsett & Thomsen). Specially suited for stiff problems.
• Algebraic equation solver: Modified Newton iteration, which includes
o Convergence control (method for keeping the same Jacobian in several iterations)
o Divergence control (extrapolation method which extrapolates the variables into
the convergence area at beginning divergence).
• Interpolation with 2. order splines, which is used for:
o Guessing static variables in next step (by extrapolation).
• The location of discontinuities is found using a secant-method.

The following parameters can be set for the solver:

Parameter Meaning
Write Select between the following
• Start, End and Disc. points: writes the solution at Start, End and
Discontinuity points.
• All: writes the solution at all points.
• Debug: writes Jacobians, information on iterations, etc. This
generates very extensive information.
Max iterations Maximum number of iterations in solution of static equations.
Max Jacobians Maximum number of Jacobians the solver is allowed to calculate each time
the static equation set is solved.
Relative error Convergence criterion.
Max step size The maximum step size the solver is allowed to use.
Min step size The minimum step size the solver is allowed to use.
Max number of How many times the solver is allowed to reject a step, change the step size
rejected steps a try another step.
Use extern static The build in static equation solver is fast, but can also cause problems.
solver More stable (but also slower) solvers can be selected.

If you encounter problems solving the equations, a good idea is to try one or more of the
following:
• Decrease the maximum step size
• Increase/decrease the Relative error
• Try an extern static equation solver
• Increase the number of iterations and/or the number of Jacobians.

When an extern static equation solver is used, the maximum number of iterations should be
increased. The maximum number of Jacobians has no influence when an extern static equation
solver is used.

WinDali Morten Juel Skovrup


12 Distributing models 105

12 Distributing models
You can easily distribute your models by going through the following steps:

• In the Simulation Program go to the Tools menu and select Create distributable copy.
• You will be prompted to select a directory where the files should be placed.
• All necessary files will be copied to that directory – including the current loaded model.
• To install the model on a different PC, just copy the files to a directory of your choice.
• To run the model, start Simulation.exe and load the .mdl file.
• If you want to distribute several models, just include the .mdl and .set files for those
models.

The current settings file will also be included with the files. Remember that if you save a settings
file with the same name as the model file (but with extension .set) this file will be loaded as
default when the model is loaded.

The files that should be in the distribution are:


• Simulation.exe Main program
• Sky32V3c.dll DLL used by the main program
• Dali.sol The default solver
• NonLin.dll DLL with external static equation solvers
• SimIntPlt.hlp Help file for main program
• SimIntPlt.cnt Used by help file.
• ‘.mdl’ and ‘.set’ files.

WinDali Morten Juel Skovrup


106 12 Distributing models

WinDali Morten Juel Skovrup


13 Programmers guide 107

13 Programmers guide
This chapter is meant for people, who want to either use another programming language than
Free Pascal (for example C++, Fortran…) or add another solver to the Simulation Program.

13.1 Using other programming languages to create the model file


The model file is basically a standard Windows DLL. When the user loads a model in the
Simulation Program, the DLL is loaded and the Simulation Program calls some functions it
expect the DLL to export.

All the function definitions can be found in mjsDLLTypes.pas, which is located in the
WinDali\lib directory. Before you are able to create a model in another programming language,
you should translate mjsDLLTypes.pas and include it in your code.

A model file (DLL) is expected to export the following functions:

InstallSetProcs
InstallAddProcs
InstallExtProcs
SetUpProblem
ModelEquations
StateShift
OnStateChange
PreCalc
OnSolution
OnSample
EndCalc
OnQuit
OnUIValueChange
OnLoadSettings
OnSaveSettings

Note that the names are case sensitive (even if you create your model in a non-case sensitive
programming language).

Included on the disk are examples with Compaq Visual Fortran, Microsoft Visual C++ 6.0, and
Borland Delphi.

WinDali Morten Juel Skovrup


108 13 Programmers guide

13.2 General notes on programming with mixed languages


The simulation program is written in Borland Delphi™ version 5.0. Several notes should be
made on the data that the simulation program passes to the modelfile:
• stdcall calling convention is used in all procedures and functions.
• Arrays from Delphi are passed as a pointer to the array and a 32 bit integer, which holds
the largest index N in the array. As the arrays are zero based, the value of N will equal
the number of items in the array minus one. If you look at the provided C++ and Fortran
examples, you will see that N is explicitly defined in procedure headings. This is because
C++ and Fortran does not in general expect N to be passed together with an array.
• The following types are used:

Delphi type Size C++ Fortran


Integer 32 bit (signed) int or __int32 Integer or Integer(4)
Byte 8 bit (unsigned) unsigned __int8 Byte
Double 8 bytes Double Real(8)
WordBool 2 bytes __int16 Logical(2)
PChar Pointer (32 bit) to char* character *(*)
character array (See Fortran example for
precise definition)

13.3 Solver file format


The Solver is a Windows DLL with the extension .sol that exports the following functions:

procedure InstallSolver(SetNumSettingsProc : Pointer;


AddSettingProc : Pointer;
AddHelpFileProc : Pointer); stdcall;
procedure SolverCaps(var Caps : array of Double); stdcall;
procedure Stop; stdcall;
procedure Solve(NumDynamic: Integer; InitialVal : array of Double;
NumStates : Integer; StartState : Integer; MaxStatic : Integer;
TStart,TEnd : Double; Settings : array of Double;
MessageProc : Pointer; ModelEquations : Pointer;
StateShift : Pointer; OnStateChange : Pointer;
OnStateChanged : Pointer; OnSolution: Pointer); stdcall;

The parameters to the procedures are a mixture of pointers to procedures and parameters
specifying the problem. Note that all procedures use the stdcall calling convention. The four
procedures will be explained in the following:

WinDali Morten Juel Skovrup


13 Programmers guide 109

13.3.1 InstallSolver
InstallSolver is called immediately after the user loads the Solver DLL.

procedure InstallSolver(SetNumSettingsProc : Pointer;


AddSettingProc : Pointer;
AddHelpFileProc : Pointer); stdcall;

SetNumSettingsProc
Is a pointer to a procedure that has the following heading:

procedure SetNumSettingsProc(Num : Integer); stdcall;

The solver should call this procedure to indicate to the Simulation program how many
settings it want to display to the user.

AddSettingProc
Is a pointer to a procedure that has the following heading:

procedure AddSettingProc(Num : Integer; SettingType : Byte;


Name : PChar; Value : Double; Items : PChar;
Max,Min : Double); stdcall;

The solver should call this procedure to install the settings it wants to display to the user
in the Simulation program.
Num Is the setting number to install
SettingType Is the type of setting to install can be:
0 Floating point number
1 Integer
2 User selects from a range of settings in a Combo box.
3 Boolean parameter
Name Is the name of the setting
Value Is the default value of the setting
Items If setting is 2, Items should contain a comma separated string,
which holds the options the user can choose between else it is
ignored. If one of the options contains spaces, it has to be enclosed
in double-quotes, for example '"Start,End and Disc.
points",All,Debug'
Max The maximum value the user is allowed to input.
Min The minimum value the user is allowed to input. If Max=Min=0 then
no limits are imposed.

AddHelpFileProc
Is a pointer to a procedure that has the following heading:

procedure AddHelpFileProc(HelpFile : PChar); stdcall;

The solver should call this procedure to add a help file for the solver. No path should be
given. The help file should be located in the \WinDali\Solvers subdirectory .

WinDali Morten Juel Skovrup


110 13 Programmers guide

Example
This is the InstallSolver procedure that Dali.sol exports:

type
TSetNumSettingsProc = procedure (Num : Integer); stdcall;
TAddSettingProc = procedure (Num : Integer; SettingType : Byte;
Name : PChar; Value : Double;
Items : PChar; Max,Min : Double); stdcall;
TAddHelpFileProc = procedure (HelpFile : PChar); stdcall;

var
SetNumSettings : TSetNumSettingsProc;
AddSetting : TAddSettingProc;
AddHelpFile : TAddHelpFileProc

procedure InstallSolver(SetNumSettingsProc : Pointer;


AddSettingProc : Pointer;
AddHelpFileProc : Pointer); export; stdcall;
begin
SetNumSettings := TSetNumSettingsProc(SetNumSettingsProc);
AddSetting := TAddSettingProc(AddSettingProc);
AddHelpFile := TAddHelpFileProc(AddHelpFileProc);
AddHelpFile('DaliSolver.html');
SetNumSettings(9);
AddSetting(1,2,'Write',1,'"Start,End and Disc. points",All,Debug',0,0);
AddSetting(2,1,'Max Iterations',15,'',1,500);
AddSetting(3,1,'Max Jacobians',1,'',1,15);
AddSetting(4,0,'Relative error',0.0001,'',0,0);
AddSetting(5,0,'Max step size',500,'',0,0);
AddSetting(6,0,'Min step size',1E-5,'',0,0);
AddSetting(7,1,'Max number of rejected steps',50,'',0,0);
AddSetting(8,3,'Use extern static solver',0,'',0,1);
AddSetting(9,2,'Extern solver type',1,'Powel,Broyden,SOS,Hybrid',0,0);
end;

13.3.2 SolverCaps
The SolverCaps procedure is called by the simulation program to inquire about the solvers
capabilities.

The solver should fill out the Caps array as shown below:

procedure SolverCaps(var Caps : array of Double); export; stdcall;


begin
Caps[0] := 1; {If 1 then the solver supports initial guess values, else 0}
Caps[1] := 1; {If 1 then the solver supports fixed sample time, else 0}
Caps[2] := 1; {If 1 then the solver supports change of size of static
equation set,else 0}
end;

WinDali Morten Juel Skovrup


13 Programmers guide 111

Caps[0] indicates whether the solver supports guesses on the static variables. If it does not (i.e.
returns 0 in Caps[0]) then the simulation program will solve the static equations at the initial
point and after every state change before sending values to the solver.

Caps[1] indicates whether the solver supports fixed sample time. If it does not (i.e. returns 0 in
Caps[1]) then the user will not be able to select fixed sample time with this solver.

Caps[2] indicates whether the solver supports variable size of the static equation set. If it does
not (i.e. returns 0 in Caps[2]) then the simulation program will insert dummy equations if the
static equation set changes to a size less than the maximum size.

13.3.3 Stop
The Stop procedure is called when the user selects the Simulation|Stop menu in the Simulation
program. It does not take any parameters, and the solver should react to this call by stopping the
simulation.

13.3.4 Solve
Solve is called when the user starts the simulation. The solver should then begin to solve the
problem at hand.

procedure Solve(NumDynamic: Integer; InitialVal : array of Double;


NumStates : Integer; StartState : Integer; MaxStatic : Integer;
TStart,TEnd : Double; HasSampleTime : WordBool;
SampleTime : Double; Settings : array of Double;
MessageProc : Pointer; ModelEquations : Pointer;
StateShift : Pointer; OnStateChange : Pointer;
OnStateChanged : Pointer; OnSolution: Pointer;
OnSample: Pointer); stdcall;

NumDynamic
Is the number of dynamic variables in the problem the solver is about to solve.

InitialVal
Is an array of length NumDynamic, which holds the initial values of the dynamic
variables.

NumStates
Is the number of states that the model can be in.
StartState
Is the number of the state the model starts in (numbering starts from 1)

MaxStatic
Is the maximum number of static variables the model has in any of the states (can be used
to dimension arrays which holds static variables).

TStart
Start time for the simulation.

TEnd
End time for the simulation

WinDali Morten Juel Skovrup


112 13 Programmers guide

HasSampleTime
If true then the user has selected fixed sample time.

SampleTime
The value of the selected sample time.

Settings
Array with the values that the user has set. The array has the same length as the number
of settings that you have specified in InstallSolver. The values in the array has the
same order as you installed the settings in. If you have installed a setting with several
choices (i.e. SettingType was 2 in call to AddSetting), then the value returned will be 1
if the user selected the first option, 2 if the user selected the second option etc.

MessageProc
Pointer to a procedure with the following heading:

procedure MessageProc(AMessage : PChar); stdcall;

The solver should call this procedure if it wants to display a message to the user.

ModelEquations
Pointer to a procedure with the following heading:

procedure ModelEquations(Time : Double; State : Integer;


X : array of Double; var R : array of Double;
Y : array of Double; var YDot : array of Double); stdcall;

The solver should call ModelEquations every time it needs to do calculations on the
model. The parameters has the following meaning:
Time The current simulation time – should be set by solver before call
State The current state the model is in – should be set by solver before call
X The current values of the static variables – should be set by solver before call
R The residuals calculated by the model – returned by the model.
Y The current values of the dynamic variables – should be set by solver before call
YDot The values of the derivatives – returned by the model.

WinDali Morten Juel Skovrup


13 Programmers guide 113

StateShift
Pointer to a procedure with the following heading:

procedure StateShift (Time : Double; State : Integer;


X : array of Double;Y : array of Double;
var G : array of Double); stdcall;

The solver should call StateShift every time it wants to check if a state shift has
happened. The parameters has the following meaning:

Time The current simulation time – should be set by solver before call
State The current state the model is in – should be set by solver before call
X The current values of the static variables – should be set by solver before call
Y The current values of the dynamic variables – should be set by solver before call
G Array with the same length as the number of states – returned by the model. The
solver should check G for a change in sign, i.e. if G[1] was positive before the
call and is negative after, it means that the model should shift to state 2
(assuming that G is zero-indexed).

OnStateChange
Pointer to a procedure with the following heading:

procedure OnStateChange(Time : Double;


CurrentState,NextState : Integer;
var NextNumStatic : Integer;
var NextGuesses : array of Double;
var Y : array of Double); stdcall;

The solver should call OnStateChange when it has detected that a change of state is
necessary – but before the state change is actually done. This enables the solver to
receive guesses on the static variables before the state is changed.

Time The current simulation time – should be set by solver before call
CurrentState The current state the model is in – should be set by solver before call
NextState The state the model is about to change to – should be set by solver
before call.
NextNumStatic The number of static variables in NextState – returned by the
model.
NextGuesses Guesses on the static variables when entering the next state –
returned by the model.
Y The current values of the dynamic variables – should be set by solver
before call. The returned values will be the new initial values in the
new state.

WinDali Morten Juel Skovrup


114 13 Programmers guide

OnStateChanged
Pointer to a procedure with the following heading:

procedure OnStateChanged(Time : Double; State : Integer;


X : array of Double;Y : array of Double); stdcall;

The solver should call OnStateChanged just after the state has been changed and the
solver has found a solution to the static equations in the new state (i.e. before the first
timestep is taken). This enables the Simulation program to draw the state change as a
sharp edge in the plots. OnStateChanged should also be called when the solver finds a
solution to the static equations before the first timestep is taken (i.e. when Time =
TStart).

Time The current simulation time – should be set by solver before call
State The current state the model is in – should be set by solver before call
X The current values of the static variables – should be set by solver before call
Y The current values of the dynamic variables – should be set by solver before call

OnSolution
Pointer to a procedure with the following heading:

procedure OnSolution(Time : Double; State : Integer;


X : array of Double;Y : array of Double); stdcall;

The solver should call OnSolution every time it finds a solution to the model equations
(i.e. every time a timestep has been successfully taken).

Time The current simulation time – should be set by solver before call
State The current state the model is in – should be set by solver before call
X The current values of the static variables – should be set by solver before call
Y The current values of the dynamic variables – should be set by solver before call

OnSample
Pointer to a procedure with the following heading:

procedure OnSample(Time : Double; State : Integer;


X : array of Double;Y : array of Double); stdcall;

If the user has selected fixed sample time, then the solver should call this procedure every
time it finds a solution at a sample time. The solver should only call OnSample at the
sample time. The simulation program automatically calls OnSolution afterwards.

WinDali Morten Juel Skovrup


14 References 115

14 References
[1] Askjær K.A. – Numeriske metoder anvendt i DALI. En Differential-Algebraisk
ligningsløser; Master thesis; Refrigeration Laboratory, Technical University of Denmark,
November 1985.
[2] Free Pascal Compiler, http://www.freepascal.org/
[3] Borland® Delphi™ 5 – Object Pascal Language guide; Inprise Corporation. 1999.

WinDali Morten Juel Skovrup


116 14 References

WinDali Morten Juel Skovrup


Appendix A Used file types 117

Appendix A Used file types


The following list shows the file types used in WinDali:

Name / Extension Content


*.ppr A Free Pascal project file. Contains among other things a list
of the pascal source-code files included in a model.
*.pp,*.pas Pascal source-code files. These files contains the model and
other code. The project file binds these files together.
*.inc Include files used by the *.pp and *.pas files.
*.ppw, *.ow, *.cfg, *.err Files created during compilation. These files can safely be
deleted.
*.mdl Compiled model file. Ready to use in the simulation program.
*.sol File containing a solver, which can be used by WinDali.
*.set Settings file created by the Simulation program. Is used when
settings and parameters for a simulation are saved.
nonlinerr.txt File created if you use the external static equation solver and
an error occurs. You can safely delete this file.

WinDali Morten Juel Skovrup


118 Appendix A Used file types

WinDali Morten Juel Skovrup


Appendix B Procedures 119

Appendix B Procedures
procedure DebugMsgProc(Msg : PChar; Num : Double);

B.1 Procedures called in SetUpProblem


procedure SolverSettings(Title : PChar; TStart,TEnd,TimeFac : Double;
ShowStartState : WordBool; StartState : Integer);
procedure SetStates(Names : PChar);
procedure SetParamPages(Names : PChar);
procedure AddDynamic(var Variable : Double;
InitalValue : Double; Name,LongName : PChar);
procedure AddDynamicExt(var Variable : Double;
InitalValue : Double; Name,LongName : PChar; Min,Max : Double;
Show : WordBool; AFormat : Byte; APrecision,ADigits : Byte;
ALabel : PChar);
procedure AddStatic(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar);
procedure AddStaticExt(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar; Min,Max : Double;
DoPlot : WordBool; AFormat : Byte; APrecision,ADigits : Byte;
ALabel : PChar);
procedure AddCommonStatic(var Variable : Double;
InitalGuess : Double; Name,LongName : PChar;
CommonStates : PChar);
procedure AddCommonStaticExt(var Variable : Double;
InitalGuess : Double; Name,LongName : PChar;
CommonStates : PChar; Min,Max : Double; DoPlot : Boolean;
AFormat : Byte; APrecision,ADigits : Byte; ALabel : PChar);
procedure AddExtra(var Variable : Double; Name : PChar;
DoPlot : WordBool);
procedure AddExtraExt(var Variable : Double; Name : PChar;
DoPlot : WordBool; AFormat : Byte; APrecision,ADigits : Byte;
ALabel : PChar);
procedure AddFloatParam(var Parameter : Double;
DefaultValue : Double; Name : PChar; ParamPage : Integer);
procedure AddFloatParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar;
ParamPage,IndexOnPage : Integer; Min,Max : Double;
ALabel : PChar);
procedure AddInitialParam(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte);
procedure AddInitialParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte; Min,Max : Double; ALabel : PChar);
procedure AddIntParam(var Parameter : Integer;
DefaultValue : Integer; Name : PChar; ParamPage : Integer);
procedure AddIntParamExt(var Parameter : Integer;
DefaultValue : Integer; Name : PChar;
ParamPage,IndexOnPage : Integer; Min,Max : Integer;
ALabel : PChar);
procedure AddBoolParam(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar; ParamPage : Integer);
procedure AddBoolParamExt(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
procedure AddListParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; ParamPage : Integer);

WinDali Morten Juel Skovrup


120 Appendix B Procedures

procedure AddListParamExt(var Parameter : Integer;


DefaultIndex : Integer; Items,Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
procedure AddEnumParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; ParamPage : Integer);
procedure AddEnumParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
procedure AddEnumChoiceParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; ParamPage : Integer);
procedure AddEnumChoiceParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
procedure AddChoice(ItemIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar);
procedure AddChoiceExt(ItemIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar;
Min,Max : Double);
procedure AddActionBtn(Caption : PChar; ParamPage : Integer);
procedure AddActionBtnExt(Caption : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
procedure AddInfoLabel(Caption : PChar; ParamPage : Integer);
procedure AddInfoLabelExt(Caption : PChar;
ParamPage,IndexOnPage : Integer; ALabel : PChar);
procedure AddHelpFile(FileName : PChar);
procedure HideSampleTime;

B.2 Procedures called in PreCalc


procedure SetStartState(Value : Integer);
procedure SetInitial(Index : Integer; Value : Double);
procedure SetGuess(State,Index : Integer; Value : Double);
procedure AddDynVar(Name : PChar; Variable : PDouble; DoPlot : Boolean);
procedure AddStatVar(Name : PChar; State : Integer; Variable : PDouble;
DoPlot : Boolean);
procedure AddExtraVar(Name : PChar; Variable : PDouble; DoPlot : Boolean);
procedure SetSampleTime(IsFixed : WordBool; Value : Double);

B.3 Procedures called in OnUIValueChange


procedure SetUIValue (UIType : TUserinterfaceType;Num,State,Choice : Integer;
Value : Double; StrValue : PChar);
function GetUIValue(UIType : TUserinterfaceType;
Num,State,Choice : Integer; StrValue : PChar) : Double;

WinDali Morten Juel Skovrup


Appendix C Component modeling files 121

Appendix C Component modeling files


The following shows the protected and public headings of the different objects the components
can inherit from. This will indicate which functions the component can override or call.

C.1 TmjsSystemModel
TmjsSystemModel =
class
protected
procedure AddDocumentation(AList : TStringList); virtual;
procedure AddSignal(AName : PChar; var Variable : Double);
procedure AddState(AName : PChar);
procedure AddStatic(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar);
procedure AddStaticExt(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar; Min,Max : Double;
DoPlot : WordBool; AFormat : Byte; APrecision,ADigits : Byte;
ALabel : PChar);
procedure AddDynamic(var Variable : Double;
InitialValue : Double; Name,LongName : PChar);
procedure AddDynamicExt(var Variable : Double;
InitialValue : Double; Name,LongName : PChar; Min,Max : Double;
Show : WordBool; AFormat : Byte; APrecision,ADigits : Byte;
ALabel : PChar);
procedure AddExtra(var Variable : Double;
Name : PChar; DoPlot : WordBool);
procedure AddExtraExt(var Variable : Double;
Name : PChar; DoPlot : WordBool; AFormat : Byte;
APrecision,ADigits : Byte; ALabel : PChar);
procedure AddFloatParam(var Parameter : Double;
DefaultValue : Double; Name : PChar);
procedure AddFloatParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar; IndexOnPage : Integer;
Min,Max : Double; ALabel : PChar);
procedure AddInitialParam(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte);
procedure AddInitialParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte; Min,Max : Double; ALabel : PChar);
procedure AddIntParam(var Parameter : Integer;
DefaultValue : Integer; Name : PChar);
procedure AddIntParamExt(var Parameter : Integer;
DefaultValue : Integer; Name : PChar; IndexOnPage : Integer;
Min,Max : Integer; ALabel : PChar);
procedure AddBoolParam(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar);
procedure AddBoolParamExt(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar; IndexOnPage : Integer;
ALabel : PChar);
procedure AddListParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar);
procedure AddListParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; IndexOnPage : Integer;
ALabel : PChar);
procedure AddEnumParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar);
procedure AddEnumParamExt(var Parameter : Integer;

WinDali Morten Juel Skovrup


122 Appendix C Component modeling files

DefaultIndex : Integer; Items,Name : PChar; IndexOnPage : Integer;


ALabel : PChar);
procedure AddEnumChoiceParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar);
procedure AddEnumChoiceParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; IndexOnPage : Integer;
ALabel : PChar);
procedure SetNumChoice(EnumParam,ItemIndex,Num : Integer);
procedure AddChoice(EnumParam,ItemIndex,ParamIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar);
procedure AddChoiceExt(EnumParam,ItemIndex,ParamIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar;
Min,Max : Double);
procedure AddActionBtn(Caption : PChar);
procedure AddActionBtnExt(Caption : PChar;
IndexOnPage : Integer; ALabel : PChar);
procedure AddInfoLabel(Caption : PChar);
procedure AddInfoLabelExt(Caption : PChar;
IndexOnPage : Integer; ALabel : PChar);
procedure AddDynVar(Name : PChar; Variable : PDouble;
DoPlot : WordBool);
procedure AddStatVar(Name : PChar; State : Integer;
Variable : PDouble; DoPlot : WordBool);
procedure AddExtraVar(Name : PChar; Variable : PDouble;
DoPlot : WordBool);
procedure SetInitial(Index : Integer; Value : Double);
procedure SetGuess(State,Index: Integer; Value: Double);
procedure SetStartState(Value : Integer);
procedure SetUIValue(UIType : Integer;Num,State,Choice : Integer;
Value : Double; StrValue : PChar);
function GetUIValue(UIType : Integer;Num,State,Choice : Integer;
StrValue : PChar) : Double;
procedure ModelEquations(Time : Double; State : Integer;
var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double); virtual;
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); virtual;
procedure OnStateChange(Time : Double;
OldState,NewState : Integer); virtual;
procedure PreCalc(Time : Double; State : Integer); virtual;
procedure OnSolution(Time : Double; State : Integer); virtual;
procedure EndCalc(Time : Double; State : Integer); virtual;
procedure OnQuit; virtual;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer; Value : Double); virtual;
procedure OnSaveSettings(FileName : PChar); virtual;
procedure OnLoadSettings(FileName : PChar); virtual;
public
constructor Create(AName : PChar); virtual;
destructor Destroy; override;
property ReductionInfo : TStringList read FReductionInfo;
property StrictConnect : Boolean read FStrictConnect
write FStrictConnect;
property OneParamPage : Boolean read FOneParamPage
write FOneParamPage;
property ShowModelInfo : Boolean read FShowModelInfo
write FShowModelInfo;
function ConnectNum(OutModel : TmjsComponentModel;
OutConnectorNum : Integer;

WinDali Morten Juel Skovrup


Appendix C Component modeling files 123

InModel : TmjsComponentModel; InConnectorNum : Integer) : Boolean;


function Connect(OutModel : TmjsComponentModel;
OutConnectorName : PChar;
InModel : TmjsComponentModel; InConnectorName : PChar) : Boolean;
function ConnectToPinNum(SourceSink : TmjsSourceSink;
Model : TmjsComponentModel;
ConnectorNum,PinNum : Integer) : Boolean;
function ConnectToPin(SourceSink : TmjsSourceSink;
Model : TmjsComponentModel;
ConnectorName,PinName : PChar) : Boolean;
function ConnectStates(InModel : TmjsComponentModel;
InStateName : PChar;
OutModel : TmjsComponentModel; OutStateName : PChar) : Boolean;
function ConnectSignal(WantSignal : TmjsComponentModel;
SignalName : PChar;
HasSignal : TmjsComponentModel; ConnectorName,
PinName : PChar) : Boolean;
function ConnectSignalVar(WantSignal : TmjsComponentModel;
SignalName : PChar;
var Variable : Double) : Boolean;
function ConnectSysSignal(SignalName : PChar;
HasSignal : TmjsComponentModel; ConnectorName,
PinName : PChar) : Boolean;
function ConnectSysSignalVar(SignalName : PChar;
var Variable : Double) : Boolean;
procedure AddController(AController : TmjsController);
procedure AddModel(AModel : TmjsComponentModel);
procedure SysSolverSettings(Title : PChar;
TStart,TEnd,TimeFac : Double;
ShowStartState : WordBool; StartState : Integer);
procedure SysSetUpProblem; virtual;
procedure SysModelEquations(Time : Double; State : Integer;
var R : array of Double; var YDot : array of Double); virtual;
procedure SysStateShift(Time : Double; State : Integer;
var G : array of Double); virtual;
procedure SysOnStateChange(Time : Double;
OldState,NewState : Integer); virtual;
procedure SysPreCalc(Time : Double; State : Integer); virtual;
procedure SysOnSolution(Time : Double; State : Integer); virtual;
procedure SysEndCalc(Time : Double; State : Integer); virtual;
procedure SysOnQuit; virtual;
procedure SysOnUIValueChange(UIType : Integer;
Num,State,Choice : Integer; Value : Double); virtual;
procedure SysOnSaveSettings(FileName : PChar); virtual;
procedure SysOnLoadSettings(FileName : PChar); virtual;
end;

C.2 TmjsComponentModel
TmjsComponentModel =
class(TmjsProblemContainer)
protected
procedure AddConnector(AConnector : TConnectorClass;
AName : PChar; Direction : Byte);
procedure SetPinVar(var Variable : Double;
ConnectorName : PChar;PinName : PChar);
procedure SetPinDynVar(DynIndex : Integer; ConnectorName : PChar;
PinName : PChar);
procedure AddSignal(AName : PChar; var Variable : Double);

WinDali Morten Juel Skovrup


124 Appendix C Component modeling files

function SetThroughConnectors(ConnectorNames : PChar;


PinName : PChar) : Boolean;
procedure AddDocumentation(AList : TStringList); virtual;
procedure AddState(AName : PChar); virtual;
procedure AddOutState(AName : string; StateNums : PChar); virtual;
procedure AddInState(AName : string; InType : Byte); virtual;
procedure AddStatic(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar); virtual;
procedure AddStaticExt(State : Integer; var Variable : Double;
InitalGuess : Double; Name,LongName : PChar;
Min,Max : Double; DoPlot : Boolean; AFormat,APrecision,
ADigits : Byte; ALabel : PChar); virtual;
procedure AddDynamic(var Variable : Double;
InitialValue : Double; Name,LongName : PChar); virtual;
procedure AddDynamicExt(var Variable : Double;
InitialValue : Double; Name,LongName : PChar;
Min,Max : Double; Show : Boolean; AFormat,APrecision,
ADigits : Byte; ALabel : PChar); virtual;
procedure AddExtra(var Variable : Double;
Name : PChar; DoPlot : WordBool);
procedure AddExtraExt(var Variable : Double;
Name : PChar; DoPlot : WordBool;AFormat,APrecision,
ADigits : Byte; ALabel : PChar);
procedure AddFloatParam(var Parameter : Double;
DefaultValue : Double; Name : PChar);
procedure AddFloatParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar; IndexOnPage : Integer;
Min,Max : Double; ALabel : PChar);
procedure AddInitialParam(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte); virtual;
procedure AddInitialParamExt(var Parameter : Double;
DefaultValue : Double; Name : PChar; DynIndex : Integer;
DataType : Byte; Min,Max : Double; ALabel : PChar); virtual;
procedure AddIntParam(var Parameter : Integer;
DefaultValue : Integer; Name : PChar);
procedure AddIntParamExt(var Parameter : Integer;
DefaultValue : Integer; Name : PChar; IndexOnPage : Integer;
Min,Max : Integer; ALabel : PChar);
procedure AddBoolParam(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar);
procedure AddBoolParamExt(var Parameter : WordBool;
DefaultValue : WordBool; Name : PChar; IndexOnPage : Integer;
ALabel : PChar);
procedure AddListParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar);
procedure AddListParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; IndexOnPage : Integer;
ALabel : PChar);
procedure AddEnumParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar);
procedure AddEnumParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; IndexOnPage : Integer;
ALabel : PChar);
procedure AddEnumChoiceParam(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar);
procedure AddEnumChoiceParamExt(var Parameter : Integer;
DefaultIndex : Integer; Items,Name : PChar; IndexOnPage : Integer;
ALabel : PChar);

WinDali Morten Juel Skovrup


Appendix C Component modeling files 125

procedure SetNumChoice(EnumParam,ItemIndex,Num : Integer);


procedure AddChoice(EnumParam,ItemIndex,ParamIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar);
procedure AddChoiceExt(EnumParam,ItemIndex,ParamIndex : Integer;
var Parameter : Double; DefaultValue : Double; Name : PChar;
Min,Max : Double);
procedure AddActionBtn(Caption : PChar);
procedure AddActionBtnExt(Caption : PChar;
IndexOnPage : Integer; ALabel : PChar);
procedure AddInfoLabel(Caption : PChar);
procedure AddInfoLabelExt(Caption : PChar;
IndexOnPage : Integer; ALabel : PChar);
procedure AddDynVar(Name : PChar; Variable : PDouble;
DoPlot : WordBool);
procedure AddStatVar(Name : PChar; State : Integer;
Variable : PDouble; DoPlot : WordBool);
procedure AddExtraVar(Name : PChar; Variable : PDouble;
DoPlot : WordBool);
procedure SetInitial(Index : Integer; Value : Double);
procedure SetGuess(State,Index: Integer; Value: Double);
procedure SetStartState(Value : Integer);
procedure SetUIValue(UIType : Integer;Num,State,Choice : Integer;
Value : Double; StrValue : PChar);
function GetUIValue(UIType : Integer;Num,State,Choice : Integer;
StrValue : PChar) : Double;
procedure ModelEquations(Time : Double; State : Integer;
var Rc : Integer; var R : array of Double;
var Yc : Integer; var YDot : array of Double); virtual;
procedure StateShift(Time : Double; State : Integer;
var G : array of Double); virtual;
procedure OnStateChange(Time : Double;
OldState,NewState : Integer); virtual;
procedure PreCalc(Time : Double; State : Integer); virtual;
procedure OnSolution(Time : Double; State : Integer); virtual;
procedure EndCalc(Time : Double; State : Integer); virtual;
procedure OnQuit; virtual;
procedure OnUIValueChange(UIType : Integer;
Num,State,Choice : Integer; Value : Double); virtual;
procedure OnSaveSettings(FileName : PChar); virtual;
procedure OnLoadSettings(FileName : PChar); virtual;
property SystemModel : TmjsSystemModel read FSystemModel;
public
constructor Create(AModel : TmjsSystemModel; AName : PChar); virtual;
destructor Destroy; override;
property AddNameToVar : Boolean read FAddNameToVar
write FAddNameToVar;
end;

WinDali Morten Juel Skovrup


126 Appendix C Component modeling files

C.3 TmjsSource, TmjsSink and TmjsController


TmjsSource and TmjsSink both inherit from TmjsSourceSink that inherits from
TmjsComponentModel. TmjsSource and TmjsSink does not define any public methods
themselves.

TmjsSourceSink =
class(TmjsComponentModel)
protected
procedure CreatePin(AName : PChar;
var Variable : Double; PinType : Byte); virtual;
end;

TmjsController is just a TmjsComponentModel:

TmjsController =
class(TmjsComponentModel)
end;

WinDali Morten Juel Skovrup


Appendix D List of demos 127

Appendix D List of demos


All demos are located in \Projects\Demo\ directory.

1. “Cooling of block” is the simple example from chapter 5


2. “Cooling of block 2” is the simple example from chapter 5 including state shifts
3. “Cooling with on-off” is a model of a refrigeration plant and a room.
4. “Cooling with on-off 2” is another model of a refrigeration plant and a room.
5. “Action btn demo” shows the use of action buttons and user interface control
6. “Tank problem” is the model of the tank and the pipe from 7.2.5
7. “Cooling with on-off 3” is another model of a refrigeration plant and a room.
8. “Two tanks” is a model of two tanks and a pipe.
9. “Cooling with on-off component” is as Demo7, but formulated as component modeling.
10. “Run sim demo” is showing how to run simulations from a model.
11. “Bouncing ball” is the classic example of the bouncing ball
12. “Lorenz” is a model of the Lorenz equation.

The following (source) files should be in the \lib directory to run the demos:

CmjsComponents.inc
CComponentsH.inc
CComponentsM.inc
CmjsProblemContainer.inc
CProblemContainerH.inc
CProblemContainerM.inc
CmjsColeBrook.pas
CmjsComponents.pas
CmjsProblemContainer.pas
CmjsMyList.pas
CmjsConnectorLib.pas
CmjsControllerLib.pas
CmjsLoadLib.pas
CmjsRefLib.pas
CmjsSourceSinkLib.pas
CmjsTestComponents.pas
CRefrigWrapper.pas
mjsDllTypes.pas

WinDali Morten Juel Skovrup


128 Appendix E Shortcuts

WinDali Morten Juel Skovrup


Appendix E Shortcuts 129

Appendix E Shortcuts
In Free Pascal Editor the following shortcuts have been defined. The shortcuts are implemented
as Code Templates (i.e. you can change them or define your own). The shortcuts are invoked by
typing the text and pressing <Ctrl>+J (try for example to write “set” – without the quotes – and
press <Ctrl>+J).

Shortcut Expands to Shortcut Expands to


set SolverSettings sextra AddExtraVar
dbg DebugMsg ssstate SetStartState
states SetStates sui SetUIValue
nparam SetParamPages gui GetUIValue
adyn AddDynamic modelinfo AddModelInfo
adyne AddDynamicExt help AddHelpFile
acommon AddCommonStatic run RunSimulation
acommone AddCommonStaticExt plot CreatePlot
astatic AddStatic curve AddCurveToPlot
astatice AddStaticExt hsample HideSampleTime
aextra AddExtra ssample SetSampleTime
aextrae AddExtraExt
afloat AddFloatParam
afloate AddFloatParamExt
ainit AddInitialParam
ainite AddInitialParamExt
aint AddIntParam
ainte AddIntParamExt
abool AddBoolParam
aboole AddBoolParamExt
alist AddListParam
aliste AddListParamExt
aenum AddEnumParam
aenume AddEnumParamExt
achoice AddEnumChoiceParam
achoicee AddEnumChoiceParamExt
cnchoice SetNumChoice
cachoice AddChoice
cachoicee AddChoiceExt
abtn AddActionBtn
abtne AddActionBtnExt
ainfo AddInfoLabel
ainfoe AddInfoLabelExt
sinit SetInitial
sguess SetGuess
sdyn AddDynVar
sstatic AddStatVar
sidyn InsertDynVar
sistatic InsertStatVar

WinDali Morten Juel Skovrup

Potrebbero piacerti anche