Beruflich Dokumente
Kultur Dokumente
WinDali
A Modeling and Simulation System for
Microsoft Windows
Version 2.10
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
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
8 Common problems................................................................................................... 81
14 References ............................................................................................................115
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.
Phone: +45 45 25 41 20
Fax: +45 45 93 52 15
e-mail: ms@mek.dtu.dk
Web: http://www.et.dtu.dk
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.
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:
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:
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.
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 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.
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).
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.
h, A
Ta
Q
ρ ,V , c p , T
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.
To create the model file you have to go through the following steps:
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:
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.
unit Problem;
interface
uses
mjsDLLTypes;
implementation
{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;
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).
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');
5.2 ModelEquations
In ModelEquations you specify the equations. The heading looks like this:
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.
5.3 EndCalc
EndCalc is called once at the end of the simulation. The only thing left to be calculated is the
Biot number:
interface
uses
mjsDllTypes;
implementation
var
T : Double;
Rho,Cp,Lambda,V,A,h,Ta,Bi : Double;
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:
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:
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.
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
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.
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.
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)
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);
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:
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"');
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.
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.
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"');
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);
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;
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;
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;
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);
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;
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.
Example
implementation
var
Enum : Integer;
procedure SetUpProblem;
begin
AddEnumParamExt(Enum,1,'"Item 1","Item 2","Item 3","Item 4"',
'TestEnum',1,1,'');
end;
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:
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,'');
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.
Shortcut
Write abtn or abtne and press <Ctrl>+J.
Example
AddActionBtnExt('Load properties',1,10,'Press to load parameters');
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;
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);
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:
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.
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;
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.
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:
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.
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:
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:
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.
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!!
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:
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).
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.
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:
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;
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.
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);
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.
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).
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;
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).
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.
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;
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:
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.
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:
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
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:
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.
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).
Secondly the states are specified with calls to the following three procedures:
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');
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.
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');
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.
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:
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).
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:
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:
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.
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:
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:
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:
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.
7.2.2 ModelEquations
ModelEquations changes slightly when the component interface is used. The heading looks like
this:
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:
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:
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:
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);
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)
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
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.
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.
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;
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:
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
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:
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:
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:
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.
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.
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!
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.
ConnectSignalVar(PipeModel,'Mass',TankModel.M);
Besides of the connection functions, the system component has the following properties:
StrictConnect : Boolean;
OneParamPage : Boolean;
ShowModelInfo : Boolean;
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.
unit Problem6;
interface
uses
CmjsComponents,CmjsTestComponents,CmjsSourceSinkLib;
implementation
var
AModel : TmjsSystemModel;
Tank1 : TmjsTankModel;
Pipe1 : TmjsPipeModel;
mSource1 : TmjsMSource;
PSource1 : TmjsPSource;
PSource2 : TmjsPSource;
mSink1 : TmjsMSink;
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:
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.
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;
m pin P pin
In connector
Out connector
m pin P pin
m pin P pin
In connector
Out connector
m pin P pin
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.
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.
{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;
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
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 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:
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;
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.
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:
• 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.
When you select the Project|Options menu you will see the following dialog:
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.
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
Additional
Directories/Conditionals
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).
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;
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
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.
11 Simulation program
When you start the simulation program you will see the following screen (not all windows will
be expanded):
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.
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
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 /
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.
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.
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.
When you press the Vary button you will see the following dialog:
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):
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:
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:
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.
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
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
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.
• 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.
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.
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.
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.
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.
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.
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:
13.3.1 InstallSolver
InstallSolver is called immediately after the user loads the Solver DLL.
SetNumSettingsProc
Is a pointer to a procedure that has the following heading:
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:
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:
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 .
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
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:
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.
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
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:
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:
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.
StateShift
Pointer to a procedure with the following heading:
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:
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.
OnStateChanged
Pointer to a procedure with the following heading:
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:
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:
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.
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.
Appendix B Procedures
procedure DebugMsgProc(Msg : PChar; Num : Double);
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;
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);
TmjsSourceSink =
class(TmjsComponentModel)
protected
procedure CreatePin(AName : PChar;
var Variable : Double; PinType : Byte); virtual;
end;
TmjsController =
class(TmjsComponentModel)
end;
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
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).