0% found this document useful (0 votes)
14 views65 pages

Sim Unit DLL Programming Guide

The document provides a comprehensive guide on creating custom unit operation models for the HSC Sim flowsheet process using either Excel or DLL type models. It focuses on using Microsoft Visual Studio and VB.NET for developing DLLs, detailing requirements, project creation, and coding templates. The manual includes technical documentation, example code, and instructions for deploying the models within the HSC Sim environment.

Uploaded by

Michel Mancilla
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views65 pages

Sim Unit DLL Programming Guide

The document provides a comprehensive guide on creating custom unit operation models for the HSC Sim flowsheet process using either Excel or DLL type models. It focuses on using Microsoft Visual Studio and VB.NET for developing DLLs, detailing requirements, project creation, and coding templates. The manual includes technical documentation, example code, and instructions for deploying the models within the HSC Sim environment.

Uploaded by

Michel Mancilla
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Sim Unit DLL Programming

1/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50. Sim Unit DLL Programming

HSC Sim flowsheet process model consist of unit operations connected with each other using
streams. Two types of unit operation models may be used: 1) Excel and 2) DLL type models.

Excel models may be created using build in Excel editor and unit wizards.

DLL type unit models must be created using some of MS Visual Studio languages. This manual
describes how to create your own models using [Link] and build them into a DLL file used in Sim
process models.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
2/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Contents
50.1. HSC Sim unit DLL programming quick start 4
50.1.1. Requirements 5
50.1.2. Creating a new project 6
50.1.3. Unit DLL Template 9
50.1.4. Namespaces 11
50.1.5. Input and output streams 14
50.1.6. Parameters 16
50.1.7. Model internal states 17
50.1.8. Runtime variables 18
50.1.9. Model parameter initialization 19
50.1.10. Calculation within the example unit model 20
50.1.11. Applying and testing the model 22
50.1.12. Example code 25
50.2. HSC unit DLL class technical documentation 27
50.2.1. Basic requirements 27
50.2.2. Unit DLL interfaces and their versions 31
50.2.3. Unit DLL initialization 31
50.2.4. Input and Output streams 31
[Link]. Several streams connected to a single Input/Output stream variable 32
50.2.5. Mode specific differences 33
[Link]. Reactions (Hydro) Unit DLLs 33
[Link]. Distributions (Pyro) Unit DLLs 35
[Link]. Particles (MinPro and Recycling) Unit DLLs 37
50.2.6. Unit DLL Properties (parameters) 38
[Link]. Parameter basics 38
[Link]. How Sim updates the property values between Sim and Unit DLL 38
[Link]. Allowed property types 39
[Link]. Model parameters 39
[Link].1. Groups 40
[Link]. Internal states 41
[Link]. Runtime variables 42
[Link]. Model fit parameters 43
[Link]. InitModelParameters subroutine in Unit DLL 43
[Link]. HiddenPropertyNames subroutine in Unit DLL 44
50.3. Unit DLL Calculation 46
50.3.1. CalcStatic 46
50.3.2. CalcDynamic 46
50.3.3. Writing messages to Sim calculation log 47
50.3.4. Using HSC8Streams and manipulating stream contents 47
50.4. Stream composition 48
50.4.1. Basic stream manipulation routines 48
50.4.2. Different component types 50
[Link]. IStreamComponent 50
[Link]. StreamSpecies (IStreamSpecies) 50
[Link]. Particle (IParticle) 51
50.4.3. Processing the stream contents 52
[Link]. All stream components, no matter what type they are 52
[Link]. All phases (and all components) 52
50.4.4. PhaseGroups 52
[Link]. StreamPhaseGroup 52
[Link]. MineralPhaseGroup 53
[Link]. ConvertedPhaseGroup 53
[Link]. GlobalPhaseGroup 53
50.4.5. Named variables available in the Unit DLL calculations 53
[Link]. HSC (given as a parameter to CalcStatic and CalcDynamic) 53
[Link]. timestepseconds (parameter to CalcDynamic) 53
[Link]. ReferenceStream (protected property in Unit DLL base class, available for all Unit DLLs) 53

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
3/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.5. ConfigurationAction attribute 54


50.6. Deploying the Unit DLLs and using them in Sim 55
50.7. How-to... 56
50.7.1. How to create new Particle / Stream / other instances 56
50.7.2. How to use unit DLL properties 56
[Link]. Enum property type 56
[Link]. Class property types 57
[Link]. Array property types 57
[Link]. Unit tables 58
[Link].1. Setting row/column names 58
[Link].2. Accessing cell values 59
[Link].3. Formatting cells 60
[Link].4. Formatting and/or hiding row/column headers 61
[Link]. Dropdowns, Comboboxes, Checkboxes and Comments 62
50.8. IHSC 64
50.9. Dynamic calculation: Tank content manipulation by user from Sim 64
50.10. Tips and tricks 65
50.10.1. Using List(Of Double) in Unit DLL property instead of array 65

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
4/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1. HSC Sim unit DLL programming quick start

The HSC Chemistry flowsheet simulator module Sim offers its users the possibility of
creating their own custom unit operation models. Unit operation models can be created
by using either a built-in Excel editor or by using one of the programming languages
supported by Microsoft Visual Studio. These self-made unit operation models enable
the user to create tailored process models for many different types of industrial
processes.

This document helps write the code for a custom unit by using Microsoft Visual Studio
IDE (Integrated Development Environment) and Visual [Link] programming
language. Although we use Visual Studio and Visual [Link] in the examples, this is
not the only suitable programming language. Other options include for instance C# and
F# (see [Link] for further information).
Readers with no previous knowledge of these languages might find it useful later to
refer to some online or printed learning resources, which are readily available.

In this quick start instructions, a simple functioning model for a thickener unit will be
created. In HSC Sim the unit files are referred as Unit DLLs as the models are
wrapped inside dynamic link library (DLL) files.

In addition, the unit DLL class template and some example program code projects can
be found in ‘C:\Program Files (x86)\HSC10\Sim\Unit DLL Examples’ folder.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
5/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.1. Requirements

As mentioned earlier, the tool of choice for development in this manual is Visual Studio.
A free version of Visual Studio (Visual Studio Express for Windows Desktop) is
available for download from Microsoft for free, but it is possible to use any other version
of it (Professional, Premium or Ultimate). Version 4.5 (or later) of the .NET framework
has to be installed in the system when developing DLL unit models. For example,
Visual Studio 2012 or newer includes installation files for .NET Framework 4.5.

Fig. 1. The examples in this document were written with Visual Studio 2012 Professional. The
other editions of Visual Studio look similar, but the menu arrangements vary depending on the
user settings.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
6/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.2. Creating a new project

Open the New Project dialog box by choosing File > New > Project. Open Installed |
Templates | Visual Basic | Windows group as shown in Fig. 2. Choose the Class
Library template. Next, enter the location (folder) and name for the project.

Fig. 2. New Project dialog box.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
7/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Next, choose Project > YourUnitName Properties… to open the project properties
dialog. Open the References tab, see Fig. 3.

Fig. 3. References tab in the Project Properties panel.

Press the Add button and select the following assembly from the Assemblies |
Framework group by ticking its check box and clicking OK.

[Link]
[Link]

Continue adding references by clicking Browse at the bottom of the window and
locating the following HSC Chemistry assemblies:

UnitDLL9_2.dll (in C:\Program Files (x86)\HSC10\Programs)


SimAddinView9_2.dll (in
C:\Program Files (x86)\HSC10\Sim\UnitDLLPipelines\9\AddinViews)

Add the assemblies to the project by clicking Add.

Change SimAddinView9_2.dll property "Copy Local" to "False". This is important! If


SimAddinView9_2.dll file is copied into the Unit DLL folder, the Unit DLL doesn't work.

After successful addition of the libraries, your References tab should look similar to Fig.
4.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
8/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Fig. 4. References tab after adding the references to the required class libraries.

The project properties tab can be closed now.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
9/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.3. Unit DLL Template

DLL unit [Link] template may be used to create new DLL units. The user must
specify Namespace, Input and output streams, model parameters, internal states,
runtime variables and static or dynamic calculation formulas.

When model is ready user must compile DLL and copy DLL file into a correct folder
where HSC Sim can find it.

The parameters which user specifies in the parameters section will arise automatically
into Parameters sheet in the same order as typed in the source code.

The following chapters will describe these steps in more detail.

Imports [Link]
Imports [Link]
Imports [Link]
Imports [Link].UnitDLL9_1

<AddIn("Unit DLL Example")>


<QualificationData("Static", "True")>
<QualificationData("Dynamic", "False")>
<QualificationData("TypeCode", "MU-100-10-DEV")>
<QualificationData("Technology", "Others")>
<QualificationData("Version", "1.0")>
<QualificationData("Description", "Description")>
<QualificationData("Author", "© Outotec (Finland), Authors: X")>
Public Class _Template
Inherits UnitDLL

#Region "Stream Configuration"

'---Inputs:

<StreamIn("Input", 1)>
Public Property Input As IHSC8Stream

'---Outputs:

<StreamOut("Output", 1)>
Public Property Output As IHSC8Stream

#End Region

#Region "Model Parameters"


'Not existing for this unit.
#End Region

#Region "Model Internal States"


'Not existing for this unit.
#End Region

#Region "Runtime Variables"


'Not existing for this unit.
#End Region

#Region "Static and Dynamic Calculation"

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
10/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Protected Overrides Sub CalcStatic(ByVal HSC As IHSC)

End Sub

Protected Overrides Sub CalcDynamic(ByVal HSC As IHSC, ByVal timestepsseconds


As Integer)

End Sub

#End Region

End Class
Fig. 5. Image of DLL Unit Template.

Fig. 6. DLL Unit source code #Region "Model Parameters" will fill automatically Parameters
sheet in DLL unit editor workbook. Printscreen example is from Flotation cell unit model with
long list of different type of calculation parameters.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
11/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.4. Namespaces

The references have made the existing HSC namespaces available in our class library
project. To make it easier to refer to the classes in those namespaces, we will add a
few Imports statements to the beginning of the file. This makes referring to the classes
easier. As an example, a variable declaration such as

Dim sb as New [Link]()

can be written as

Dim sb as New StringBuilder()

after the appropriate namespace (in this case [Link]) has been imported.

From here on, screenshots are not used to show how the source code has been
modified; instead they are shown as text. Copying and pasting a code to your own
model’s source code is OK, but you might find it useful to know that the complete code
for the example unit is listed in Appendix B.

Instead of using a generic class name such as Class1 for our class, we will change the
class name to ExampleThickener. The class file name can be changed in the solution
explorer by right-clicking the file name and choosing Rename (e.g.
[Link]). Keeping the names consistent might turn out to be useful later,
especially if you have several files and classes in your class library project. It is
possible to create several unit model classes within one file, but a more common
practice is to have each class in its own file.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
12/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

The next step is to add general information about your unit. This is done by using an
attribute element (marked as <attribute info>) that resides just before the class
statement, see the example below. The information inserted here is shown in the
‘select unit models’ dialog in HSC Sim.
<Addin("Example Unit")>
<QualificationData("Static", "True")>
<QualificationData("Dynamic", "False")>
<QualificationData("TypeCode", "MU-100-10-DEV")>
<QualificationData("Technology", "Others")>
<QualificationData("Version", "1.0")>
<QualificationData("Description", "Description")>
<QualificationData("Author", "© Outotec (Finland), Authors: X")>
Public Class ExampleThickener

End Class

The information contained in the attribute includes the name of the model, description
of the model, the name of the author, and whether the model is intended for static or
dynamic modeling (at the moment only Static can be used).

An optional field in the attribute is the type code field. The type code can be any user-
selected code to identify the model in addition to its name. For example, the HSC Sim
models use the following notation: first, a two-lettered abbreviation that tells us the
category of the unit (MU – mineral unit, HU – hydro unit, PU – pyro unit, RU – recycling
unit), followed by a three-digit process area number and a two-digit unit model number.
The information within the required attribute fields is important for HSC Sim to be able
to handle the file properly, so it should be written in the same manner as in the
example.

Note: If the TypeCode ends with "DEV", then the Unit DLL file is not saved with the
flowsheet. Normally Unit DLL files are supposed to be saved with the flowsheet so they
can be copied to other users but when you are developing the Unit DLL, it is better to
save the test flowsheets without DLL files and then Sim will always load and use the
latest version of your Unit DLL.
The base class for each model class is the UnitDLL class. It has to be inherited and the
Visual Basic way to express this is to use the Inherits keyword right after your class
name.

Public Class ExampleThickener


Inherits UnitDLL

#Region "Static and Dynamic Calculation"

Protected Overrides Sub CalcStatic(ByVal HSC As IHSC)


CalcOutput()
End Sub

Protected Overrides Sub CalcDynamic(ByVal HSC As IHSC8,


ByVal timeStepSeconds as Integer)
CalcOutput()
End Sub

#End Region

End Class

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
13/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

When the text Inherits UnitDLL is inserted, Visual Studio automatically adds two
methods (CalcStatic and CalcDynamic), that have to be overridden in the model class.
In this example, an internal Private Sub method called CalcOutput has been added. It
is called by both the static and dynamic calculation modes. If the model is static only,
both functions, CalcStatic and CalcDynamic, have to perform the same static
calculation just like in the example.

The code can include #Region directives, which make it is possible to collapse and
hide blocks of code in Visual Basic files. It is not compulsory to use the #Region
directive, but it might be useful to be able to hide blocks of code in larger files. This way
it is easier to focus on only portions of it at a time.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
14/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.5. Input and output streams

In HSC Sim 9, material and energy are transferred from one unit to another via
streams. The examples below show how to declare the streams that connect to a unit
in HSC Sim.

A unit can have input and output streams in the following ways:

 One or more input streams (the number of streams is known). Each of them is
declared as a Property preceded by a StreamIn attribute, as shown here:

<StreamIn("Feed", 1)>
Public Property Feed As IHSC8Stream

 One or more input streams (the number of streams is unknown)

<StreamIn("Feeds", 1)>
Public Property Feeds As List(Of IHSC8Stream)

 One or more output streams (the number of streams is known)

<StreamOut("Overflow", 1)>
Public Property Overflow As IHSC8Stream

 Several outputs, the number of outputs is not pre-defined

<StreamOut("Outputs", 1)>
Public Property AllOutputs As List(Of IHSC8Stream)

 Optional inputs (when it is not actually obligatory to include one)

<StreamIn("Cake_Wash_Water", 2, Required:=False)>
Public Property CakeWashWater As IHSC8Stream

 Optional outputs (when it is not obligatory to include one)

<StreamOut("Water_Outlet_A", 3, Required:=False)>
Public Property WaterOutA As IHSC8Stream

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
15/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Our example unit has one input stream and two output streams. The input stream is
called Feed and is assigned a stream number of 1 and set as the default input. If an
input stream is defined as default, HSC Sim automatically assigns the first user-drawn
input stream to this input stream. If no default streams are set, HSC Sim opens a dialog
box in which the latest user-drawn stream can be assigned to one of the pre-defined
streams in the model (such as Overflow or Underflow, as below).

#Region "Stream Configuration"

'Inputs:

<StreamIn("Feed", 1, IsDefaultInput:=True)>
Public Property Feed As IHSC8Stream

'Outputs:

<StreamOut("Overflow", 1)>
Public Property Overflow As IHSC8Stream

<StreamOut("Underflow", 2)>
Public Property Underflow As IHSC8Stream

#End Region

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
16/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.6. Parameters

Model parameters have initial values and the information concerning them are defined
inside the Parameter attribute. The heading, name, measure unit, and description have
to be specified for a parameter, but its limits are optional. Users can later change the
parameter values in HSC Sim 9, where a user interface is automatically provided for
doing this. An example of model parameter declaration is shown here:

Heading Name Measure unit Description Limits (optional)

<Parameter("General", "Net Volume", "m3", "Cell net volume",


GreaterThan:=0)>
Public Property NetVolume As Double = 100.0

In the example below, the heading is declared as a constant character string. Using
constants is useful as the heading field is used to categorize and group the parameters
of the model. Using constant strings also makes group naming less error-prone.
Maximum and minimum limits are also set for the parameter (minimum as MinLim:=1,
maximum as MaxLim:=100). A parameter value has to be set by the user between its
maximum and minimum values if such values are defined.

#Region "Model Parameters"

Const NODE0 As String = "PARAMETERS"

<Parameter(NODE0, "Underflow solids", "%", "Underflow solids


percentage",
MinLim:=1, MaxLim:=100)>
Public Property UnderFlowSolidsPercentage As Double = 50.0

#End Region

A brief explanation regarding the limits:

MinLim stands for >=


MaxLim stands for <=
LessThan stands for <
GreaterThan stands for >

As for the colon, e.g. MinLim:=1, this means that the value for MinLim is passed by
name. In other words, it is okay to code these limits in any sequence and it is not
compulsory to indicate if a particular limit is omitted (i.e. they are optional).

Parameter values can also be provided by using a specific table type class, see
UnitTableDouble, UnitTableString and UnitTableObject.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
17/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.7. Model internal states

Model internal states are public properties, which are stored by HSC Sim in the model
.xls file, but are not shown to the user in the user interface. These properties can be
used to store the model state between calculations, e.g. previous round output streams
can be stored.

<InternalState("Tails streams of the bank")>


Public Property BankTails As New List(Of IHSC8Stream)

Since the example does not need to store any of its states, this part can be neglected
or a region stub can be inserted into the example model’s source code for future
reference.
#Region "Model Internal States"
'Not in use in this unit
#End Region

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
18/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.8. Runtime variables

Runtime variables are for presenting the model internal states during the calculation,
i.e. information that cannot be provided from/to the model with the output/input stream.
They are also used for controlling certain model operating conditions (=model internal
states) during the runtime, especially in dynamic simulations. An example of such a
case is a tank level measurement (runtime output variable) that is controlled by using a
HSC control that changes the tank outlet valve position (runtime input variable).

The variables can be inputs (write only), outputs (read only), or inputs and outputs
(read/write).

<RuntimeVariable("P", "kPa", "Pressure drop", False, True)>


Public Property Pressure As Double

The example does not utilize runtime variables either, so only a region stub is inserted
into to the code, although it is not necessary. In the future it will be easy to make
amendments to the code by filling the empty regions with relevant program code.

#Region "Runtime Variables"


'Not in use in this unit
#End Region

It is not mandatory to specify the "write-only" or "read-only" setting in the


RuntimeVariable attribute. HSC Sim can detect the setting also from the property
ReadOnly and/or WriteOnly modifiers:
<RuntimeVariable("Level", "m", "Some level")>
Public ReadOnly Property Level As Double ' Automatically ReadOnly (unit DLL
output)

<RuntimeVariable("Valve setting", "m", "Valve setting")>


Public WriteOnly Property Pressure As Double ' Automatically write only
(unit DLL input)

<RuntimeVariable("Angle", "Degrees", "")> ' Automatically read/write (both


input and output)
Public Property Angle As Double

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
19/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.9. Model parameter initialization

InitModelParameters sub is called by HSC Sim when the model is applied. This sub
is not necessary for all units. Typically this is needed if some tables are to be initialized
based on the input stream structure of the model.
Protected Overrides Sub InitModelParameters(HSC As IHSC8, RefFeed As
IHSC8Stream)
'[Link](HSC, RefFeed)
End Sub

The example code does not need to initialize any parameters beforehand. The
example code is left without any reference to model parameter initialization.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
20/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.10. Calculation within the example unit model

The simple thickener unit that is modeled here first counts the amount of solids and
water in the input stream. It then calculates how much water is needed in the underflow
to reach the desired solids percentage (set via a parameter) in the underflow stream.
Solids percentage x in the underflow is calculated as follows:
𝑚𝑠𝑜𝑙𝑖𝑑𝑠 (1)
=𝑥
𝑚𝑠𝑜𝑙𝑖𝑑𝑠 + 𝑚𝑤𝑎𝑡𝑒𝑟
Since x is the parameter value that the user sets and the amount of solids is known
due to prior calculations, equation (1) can be rearranged to
(1 − 𝑥) (2)
𝑚𝑤𝑎𝑡𝑒𝑟 = 𝑚𝑠𝑜𝑙𝑖𝑑𝑠
𝑥
Equation (2) is included in the model code. Finally, the example unit directs all the
solids and the required amount of water to the underflow and the excess water to the
overflow.
It is worth mentioning that it is possible to send messages from the model to the HSC
Sim user interface. The sent messages are shown in the log viewer. Some examples
are included in the example code and the way the messages are displayed is
demonstrated in the next chapter.
The Unit model can send three types of messages to the user during the calculation:

 Normal log message


WriteToLog("Starting calculations")

 Info messages
InfoMessage("Cyclone is roping according to SPOC criterion.")

 Warning messages
WarningMessage("Solids percentage target(s) could not be reached.")

 Error messages
RaiseFatalErrorException("Recovery calculation for selected particle
floatability type is not supported by this model version.")

About debugging a class library project (such as a unit model project), please refer to a
web page like [Link] (Debugging
DLL Projects) and follow the given instructions (when you need to select Start external
program please choose C:\Program Files (x86)\HSC10\Programs\[Link]).
It is possible to utilize the info and warning message, too. Add info messages to your
model and have it send appropriate information to the log viewer so that you can track
your model operation. If unexpected or inconsistent results come up, make changes to
the code and re-build your project. Then test the new version of your model within HSC
Sim.
Below is the code for the CalcOutput method. It is called by the CalcStatic and
CalcDynamic methods and it is the method in our example that does the calculations. It
includes both an InfoMessage and a WarningMessage to show how they can be
implemented. No further code is needed in this example.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
21/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

#Region "Internal Procedures"

Private Sub CalcOutput()

Dim massOfSolids As Double


Dim massOfWater As Double
Dim requiredWater As Double
Dim waterToOverflow As Double
Dim x As Double = UnderFlowSolidsPercentage

'calculate the amount of material in solid and water phases


For Each c_amount In [Link]
If c_amount.[Link] = [Link] Then
massOfSolids += c_amount.Amount
End If

If c_amount.[Link] = [Link] Then


massOfWater += c_amount.Amount
End If
Next

'calculate the required amount of water


requiredWater = (100 - x) / x * massOfSolids
waterToOverflow = massOfWater - requiredWater

'an example of an InfoMessage


InfoMessage("Required amount of H2O is " & CStr(requiredWater) & " t/h.")

If waterToOverflow < 0 Then


WarningMessage("Not enough water to proceed.")
Else

'transfer phases to the right streams


For Each co In [Link]

If [Link] = [Link] Then


[Link]([Link],
[Link],
[Link])
End If

If [Link] = [Link] Then


[Link]([Link],
[Link],
requiredWater)
[Link]([Link],
[Link],
waterToOverflow)
End If
Next
End If

End Sub

#End Region

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
22/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.11. Applying and testing the model

Once the model is ready, choose Build > Build Solution. This command builds the
solution and creates the [Link] file with the required support files
(UnitDLL9_2.dll) in the bin/Debug folder, which in the case of our example is located at

C:\UnitModels\ExampleUnit\ExampleUnit\bin\Debug

Copy this folder under the


C:\users\<username>\AppData\Roaming\Outotec\HSC10\DevelopmentUnitDLL folder.
For easy and fast testing, you can set the compile target directly to that subfolder. This
way you can just build the project and test it immediately in HSC Sim.

Start HSC Sim 9. Draw a generic unit and right-click on the new unit. Choose “Unit
Model Editor”. Make sure that Unit 1 is selected and then locate Example Unit (since
the type code for this unit started with an H, it is listed in the Reactions tab, which
shows the Hydro units). Double-click the name of the unit and click OK. Now our model
is applied to the newly drawn unit.

Draw an input stream in the unit. Add an output stream. A dialog box opens that asks
you to assign an output port to the stream; choose Overflow. Add another stream. Now
the flowsheet should look something like the one in Fig. 7.

Fig. 7. An example unit with renamed streams.

Double-click the unit to open its properties view. Choose Variable List Editor and add
H2O to the Water Phase. Add SiO2 to Pure Phase (in the figure: Solid Phase), see Fig.
8.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
23/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Fig. 8. Variable List Editor after compounds have been added and a phase name has been
modified.

Accept changes by clicking the Activate button in the top left corner. Choose the Input
sheet and specify the amount of incoming compounds, e.g. 5 t/h of H2O and 2 t/h of
SiO2. Close the properties window. Press the Simulate button (light blue right-pointing
arrow) in the toolbar. After the calculations are ready, turn on the Toggle Stream
Visualization Mode by clicking the eyeball-like icon in the toolbar.

For illustrative purposes “Species: H2O (t/h)” option has been selected from the
dropdown menu in the toolbar, see Fig. 9. The Log viewer can be made viewable by
choosing View > Toolbars > Log viewer. Use the Log viewer to locate the information
messages sent from the model.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
24/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Fig. 9. Streams visualized and the log viewer showing InfoMessages. Warnings can be viewed
similarly through the Log viewer.

To change a parameter value, double-click the unit in the flowsheet and select the
Configuration sheet. This sheet contains all user-specified parameters along with their
measure units, possible limits, and descriptions of the parameters.

Fig. 10. Users can change parameter values via the Configuration sheet.

If a value below the minimum limit is typed into the value cell, the value in the cell is
automatically changed to the minimum value. A similar automatic change takes place
when a value that is too great is typed into the value cell.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
25/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.1.12. Example code

Source code for the example unit

Imports [Link]
Imports [Link]
Imports [Link]
Imports [Link].UnitDLL9_2

<AddIn("Example Unit")>
<QualificationData("Static", "True")>
<QualificationData("Dynamic", "False")>
<QualificationData("TypeCode", "MU-100-10-DEV")>
<QualificationData("Technology", "Others")>
<QualificationData("Version", "1.0")>
<QualificationData("Description", "Unit modelling example")>
<QualificationData("Author", "Company Name - Your Name")>
Public Class ExampleThickener
Inherits UnitDLL

#Region "Stream Configuration"

'Inputs:

<StreamIn("Feed", 1, IsDefaultInput:=True)>
Public Property Feed As IHSC8Stream

'Outputs:

<StreamOut("Overflow", 1, Required:=False)>
Public Property Overflow As IHSC8Stream

<StreamOut("Underflow", 2)>
Public Property Underflow As IHSC8Stream

#End Region

#Region "Model Parameters"

Const NODE0 As String = "PARAMETERS"

<Parameter(NODE0, "Underflow solids", "%", "Underflow solids percentage",


MinLim:=1, MaxLim:=100)>
Public Property UnderFlowSolidsPercentage As Double = 50.0

#End Region

#Region "Model Internal States"


'Not in use in this unit
#End Region

#Region "Runtime Variables"


'Not in use in this unit
#End Region

#Region "Static and Dynamic Calculation"

Protected Overrides Sub CalcStatic(ByVal HSC As IHSC)


CalcOutput()
End Sub

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
26/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Protected Overrides Sub CalcDynamic(ByVal HSC As IHSC,


timeStepSeconds As Integer)
CalcOutput()
End Sub

#End Region

#Region "Internal Procedures"

Private Sub CalcOutput()

Dim massOfSolids As Double


Dim massOfWater As Double
Dim requiredWater As Double
Dim waterToOverflow As Double
Dim x As Double = UnderFlowSolidsPercentage

'calculate the amount of material in solid and water phases


For Each c_amount In [Link]
If c_amount.[Link] = [Link] Then
massOfSolids += c_amount.Amount
End If

If c_amount.[Link] = [Link] Then


massOfWater += c_amount.Amount
End If
Next

'calculate the required amount of water


requiredWater = (100 - x) / x * massOfSolids
waterToOverflow = massOfWater - requiredWater

'an example of an InfoMessage


InfoMessage("Required amount of H2O is " & CStr(requiredWater) & " t/h.")

If waterToOverflow < 0 Then


WarningMessage("Not enough water to proceed.")
Else

'transfer phases to the right streams


For Each co In [Link]

If [Link] = [Link] Then


[Link]([Link], [Link],
[Link])
End If

If [Link] = [Link] Then


[Link]([Link], [Link],
requiredWater)
[Link]([Link], [Link],
waterToOverflow)
End If
Next
End If

End Sub

#End Region

End Class

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
27/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.2. HSC unit DLL class technical documentation

50.2.1. Basic requirements

 The compiled DLL (Dynamic Link Library) must reside in subfolder under
<user>\AppData\Roaming\Outotec\HSC10\DevelopmentUnitDLL
 (so your DLL could be in
C:\users\username\AppData\Roamng\Outotec\HSC10\DevelopmentUnitDLL\MyAddinFolder\[Link])
 The assembly must have references to
 [Link]
 [Link]
 UnitDLL9_2.dll (found in C:\Program Files (x86)\HSC10\Programs or ..\..\Lib if you
are using the Sim source code)
 SimAddinView9_2.dll (found in C:\Program Files
(x86)\HSC10\Sim\UnitDLLPipelines\9\AddInViews). Note that "Copy Local" must
be False.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
28/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Every public class in the DLL is a separate Unit DLL


 The class must have <Addin> attribute. Fields in the attribute are:

Key Example value Description

Name "Magnetic separator" (Mandatory) The human-readable name of the Unit


DLL. This is displayed to the user in the Unit model
type selector and other places.

Description "Separates particles (Optional) Description of the DLL. This is displayed


based on their magnetic in the Description part in Unit model type selector.
properties" This can be also given in a <QualificationData>
attribute (see below)

Publisher "Joe Programmer" (Optional) Author of the DLL. This is displayed in the
Author part in Unit model type selector
This can be also given in a <QualificationData>
attribute (see below)

Version "[Link]" (Optional) DLL version. This is displayed in the


Version part in Unit model type selector
This can be also given in a <QualificationData>
attribute (see below)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
29/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Some class information (such as "supports dynamic calculations", "Typecode", "Technology") can
be defined with <QualificationData> attribute. Supported values are:

Key Example value Description

Static "True" / "False" If "True", then the Unit DLL supports calculations in Static
(default) mode

Dynamic "True" / "False" If "True", then the Unit DLL supports calculations in Dynamic
(default) mode

Type code defines whether the Unit DLL is a Hydro, Pyro or


TypeCode "HU-123-45" Particle DLL:
"HU-xxx-xx" = Hydro Unit DLL
"MU-xxx-xx" = Mineral / Particle unit DLL
"PU-xxx-xx" = Pyro Unit DLL
"RU-xxx-xx" = Recycling Unit DLL
"OU-xxx-xx" = None of the above, "Other"

If the type code ends with "DEV", the Unit DLL is handled a bit
differently than normally. Typically Unit DLL is saved with the
flowsheet which means that the flowsheet will always use the
version of the Unit DLL which was in use when the flowsheet
was created. "DEV" prefix in the name means that you can
create a test flowsheet with the initial version of your Unit DLL
and then use the same flowsheet for testing your Unit DLL
while you keep updating your code. Just remember to remove
the DEV extension before you publish the Unit DLL.

Text that is displayed in the "Technology" part in the Unit model


Technolog type selector
y

Text that is displayed in the "Subtechnology" part in the Unit


Sub- model type selector
technology

Version number which is displayed in the "Version" part in the


Version "[Link]" Unit model type selector.
If this is not specified, then the version number is taken from
the <Addin> attribute, if it is found there. If both are defined,
then this overrides the <Addin> attribute version.

About version numbers: If the major version stays the same, then Sim
assumes that the configuration options of the Unit DLL stay the same.
Therefore it is possible to update the Unit DLL version and still keep the
old parameters. However, if the user chooses to update version 1.1 to
2.0, then the unit file is fully cleared and all configuration options are
reset to their default values.

Description of the DLL. This is displayed in the Description part


Description "Separates in Unit model type selector.
particles based If this is not specified, then the description is taken from the
on their

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
30/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

magnetic <Addin> attribute, if it is found there. If both are defined, then


properties" this overrides the <Addin> attribute version.

Author of the DLL. This is displayed in the Author part in Unit


Author “Joe” model type selector.
If this is not specified, then the description is taken from the
<Addin> attribute (Publisher), if it is found there. If both are
defined, then this overrides the <Addin> attribute version.

 The class must inherit from UnitDLL base class


 The class should use the following imports
 Imports [Link]
 Imports [Link]
 Imports [Link].UnitDLL9_2 (or whatever version you are using - it
is usually better to set this globally in the Project Properties - References -
Imported Namespaces list)
 Imports [Link]

Imports [Link]
Imports [Link]
Imports [Link]

<AddIn("Joe test", description:="Description here", Publisher:="Joe",


Version:="1.0.0")>
<QualificationData("Static", "True")>
<QualificationData("TypeCode", "HU-123")>
<QualificationData("Technology", "Technology text!")>
<QualificationData("Subtechnology", "Subtechnology text!")>
Public Class Separator
Inherits [Link]

Protected Overrides Sub CalcDynamic(HSC As IHSC, timestepseconds As Integer)

End Sub

Protected Overrides Sub CalcStatic(HSC As IHSC)

End Sub
End Class

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
31/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.2.2. Unit DLL interfaces and their versions

 New versions of the Unit DLL interface are published every now and then. In the new
versions, some new features are added, some old may be removed
 New version of HSC installation will always support the DLL with old interface versions For
example some release version of HSC Sim can support totally following all interface
versions:
 9 ([Link] and [Link])
 9_1 (UnitDLL9_1.dll and SimAddinView9_1.dll)
 9_2 (UnitDLL9_2.dll and SimAddinView9_2.dll)

50.2.3. Unit DLL initialization

 Unit DLL is initialized in this order:


1. An instance of the Unit DLL is created
 properties are initialized to their default values (defined in Unit DLL code, like
"Public Property ValveSetting As Integer = 1")
 the constructor for the Unit DLL is called
2. Sim initializes communication between Sim and Unit DLL
 After this the Unit DLL can create new instances of Sim calculation objects,
like NewHSC8Stream, NewParticle etc
3. Unit DLL overridable sub UnitDLLInitialization is called
 If the Unit DLL has some default property values that need to call
NewHSC8Stream, NewParticle etc., they should be initialized here
4. Sim starts mapping the properties of the Unit DLL and reading/writing their stored
values from a possible previously saved flowsheet
 At this point all properties that contain class references should be initialized.
Otherwise a NullReferenceException will be thrown and the property
mapping fails.

50.2.4. Input and Output streams

 Input and output streams are defined like this:


 There must be a Public Property for each input or output
 Property type must be either a IHSC8Stream or List(Of IHSC8Stream)
 Property must have either StreamIn or StreamOut attribute
 When Unit DLL code is running, Sim has already initialized these variables:
 Input stream variables contain the input from the flowsheet
 output stream variables are initialized as empty

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
32/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Several streams connected to a single Input/Output stream variable

 When drawing the flowsheet, the user can choose which stream is connected to which
Input/Output property
 Multiple streams can be connected to the same property
 Input:
 If the property type is IHSC8Stream, then the input streams are added
together and the sum is put to the IHSC8Stream variable
 Currently supported only for HSC Sim particles based unit models
 If the property type is List(Of IHSC8Stream), then the list contains all the
streams as separate streams
 It is usually done like this in HSC Sim reaction based unit models.
 Output:
 If the property type is IHSC8Stream, then only one output stream can be
connected to this variable
 If the property type is List(Of IHSC8Stream), then multiple output streams
can be connected
 The list contains empty IHSC8streams for each connected output
stream
 Each stream has a parameter which contains the stream GUID
(identifier that can be used in the user interface to distinguish
different output streams in some table etc.)
 It is not possible to use the stream name in Unit DLL because
the stream name may change at any time and that would
destroy the configuration in the Unit DLL
 instead the Unit DLL uses the GUID in UnitTable row/column
names and Sim converts that to human-readable stream
name in the graphical user interface
 The GUID can be obtained with the following method:

<StreamOut("Outputs", 1)>

Public Property AllOutputs as List(Of IHSC8Stream)

For Each output In AllOutputs

Dim s = [Link] ' Get the GUID of the output stream and use it
somewhere

Next

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
33/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.2.5. Mode specific differences

 the Unit DLL code is pretty similar in different HSC Sim calculation modes but there are
some differences that the programmer should be aware of

[Link]. Reactions (Hydro) Unit DLLs

 The input and output streams ALWAYS contain only IStreamSpecies (particles are not
possible in Hydro)
 You can't create output species that don't exist in the input (input contains all species that
have been defined in the Hydro variable list editor and no other species can be used)
 If you create species that don't exist in the variable list, the calculations are
immediately stopped when Sim tries to write the species to the Hydro Output sheet
 Hydro input streams contain also information from the variable list
 This information is stored in Input stream parameters -> the information is not
automatically copied to output/tank streams when you add
StreamComponentAmounts to the other streams
 Since some of these parameters are important during calculations (volume
calculation parameters being the most important), Sim can't combine different input
streams and still retain that data
 Therefore Unit DLL coder must "manually" copy the Hydro specific volume
data to the tank/output
 And Sim can't combine input streams to one IHSC8Stream
 If an unlimited amount of inputs can be connected to the Unit DLL, then you must define the
input as List(Of IHSC8Stream)
 Just IHSC8Stream doesn't work because Sim can't combine multiple input streams
and still automatically merge the hydro specific parameters of the streams
 Hydro input streams contain information about phase volume calculations
 This information is given in the Hydro variable list editor
 It affects how water phase volume is calculated
 If this information is lost, then the water phase is calculated using the default volume
calculation routine which doesn't take ions into account -> gives different results
than the Excel side
 The information is stored in Input streams as parameters which means that
if you just add the species to a tank using the normal AddStream routine, the
volume calculation information is not copied to the tank -> tank volume is
calculated incorrectly
 Therefore you must copy the hydro volume calculation information from the
Input stream to the Tank using
[Link](tankStream) command.

In Hydro, for dynamic calculations, always remember to use CopyHydroParametersToTank command if


you mean to calculate the tank volume (as you probably will)

 By default, Hydro Output sheet temperature and pressure fields are defined by the user =
values in the output HSC8Stream are NOT used.
 The Unit DLL must set a certain parameter for a PhaseGroup if it wants the Output
sheet to get temperature values from that phase:

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
34/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

' The Output sheet temperature is taken from the first phasegroup in the stream
(note that the phasegroup order is almost random so this works correctly only if all
phasegroups have the same temperature)
[Link]([Link]
eGroup)

' The Output sheet pressure is taken from the first phasegroup in the stream (note
that the phasegroup order is almost random so this works correctly only if all
phasegroups have the same
pressure)[Link]([Link]
[Link])

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
35/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Distributions (Pyro) Unit DLLs

 In Pyro you can have two kinds of inputs:


 IHSC8Stream - currently only one "physical" input stream can be connected to this -
> the stream contains only one phase
 List(Of IHSC8Stream) - a single "physical" input stream is connected to each item in
the list -> each list item contains only one phase
 There are two kinds of outputs:
 IHSC8Stream - this is connected to one "physical" output stream -> currently the
output stream may contain only one phase
 If the stream contains multiple phases, the calculation is stopped
 List(Of IHSC8Stream) - each item in the list is contained to a single "physical"
output stream -> also here a single stream may contain only one phase
 Handling output variable lists:
 Each output stream property contains a list of species that are already on the
Output sheet (probably defined by user)
 The list of species can be read using [Link]
method:

Dim speciesList = [Link]

For Each species In speciesList


... do something
Next


Pyro Unit DLL has three options to generate output:
1. Use only variables that already exist on Output sheet
 If the output stream contains variables that don't exist on Output
sheet, the calculation is stopped because of an error
2. Add new variables to Output sheet if necessary
 Unit DLL can output species that don't yet exist on Output sheet. If
such species are found in the Unit DLL output, the new species are
automatically added to Output sheet variable list, even during
calculations
3. Update the Output sheet variable list according to Unit DLL output
 New species are added to Output sheet variable list automatically
 If Output sheet contains variables that don't exist in the Unit DLL
output stream, they are removed from the variable list
 This keeps the Output sheet "clean" but may cause lots of changes
during calculations if the output streams change a lot
Unit DLL can/must specify the mode for each stream separately by setting

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
36/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link] property:

' The default is always


[Link] but we can also set
it by code to make the code easier to understand:
[Link] =
[Link]

' Allow adding new variables, but unused variables are not removed from Output sheet
[Link] =
[Link]

' Update the variable list according to the stream output (add new variables and
delete unused variables from Output sheet)
[Link] =
[Link]

 Note that updating the variable list during calculations may slow down
calculations so try to avoid unnecessary variable list updating
 However, if the output variable list doesn't change during calculations
(usually it is not necessary after the first round), then you can safely
use even OverwriteVariables mode

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
37/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Particles (MinPro and Recycling) Unit DLLs

 In MinPro, both Input and Output may contain both IStreamSpecies (at least in Liquid and
Gas phases) and IParticles (in particle phase)
 You can create new components "on the fly" so you can create different kind of particles
(and even convert species to different species). For example a grindin mill outoput can
consist of small particles that were not existing in the input stream at all

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
38/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.2.6. Unit DLL Properties (parameters)

[Link]. Parameter basics

 All public variables in the Unit DLL should be defined as one of the attributes listed here
later on
 Variables must be Public Properties
 Properties that have one of these attributes are saved properly with the flowsheet and
loaded back when the flowsheet is loaded or calculations are started
 If Unit DLL uses public variables that are not defined with one of these attributes, then the
contents of those variables are lost when
 Calculations are started/stopped
 Flowsheet is saved/loaded
 So do not use class member variables without one of these attributes unless you
use some other wrapper property to save the value

[Link]. How Sim updates the property values between Sim and Unit DLL

 Unit DLL has defined the properties and their types (Model parameter, Runtime variable,
Internal state)
 Sim extracts the list of these parameters from the Unit DLL and creates an user interface so
the user can change and see the values
 When the user changes a parameter or parameters are written from Sim to Unit DLL for
some other reason (calculations start, during calculations, flowsheet is loaded, etc.), Sim
does the following things in this order:
1. Write the parameter value(s) to the Unit DLL
 Sim writes the new value or values directly to the Unit DLL properties
 Unit DLL property setter can do some processing immediately at this point
(for example ensure that the sum of some variables is exactly the desired
value etc.)
2. Updates the reference stream (MinPro only) to the Unit DLL by setting the
ReferenceStream variable (reference stream is needed e.g. for retrieving fowsheet
‘master’ particle size fraction list)
3. Call Unit DLL InitModelParameters sub
 Here the Unit DLL can ensure that all tables and values are initialized
correctly
4. Read all property values from the Unit DLL
 All values are read at this point because setting one property and calling
InitModelParameters may have changed several other property values in the
Unit DLL so everything must be updated in the user interface
5. Call Unit DLL HiddenProperties sub
 Unit DLL may hide some properties from the user, for example if the Unit
DLL has several configuration levels (simple, advanced)
6. Update the user interface

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
39/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Allowed property types

Supported property types are:

 String
 Double
 Single
 Integer
 Boolean
 UnitTableDouble
 UnitTableString
 IHSC8Stream
 List(Of IHSC8Stream)
 Enum
 Class types
 Arrays of any of the previous
 except UnitTableDouble, UnitTableString, IHSC8Stream and List(Of IHSC8Stream)

[Link]. Model parameters

 Model parameters are shown to the user in the unit editor


 The idea is that the model parameters are 'static' so they don't change during the
calculations
 However, they can change. Sometimes it is very nice to change the size of some
tank during calculations and try to find the correct value for it. But in real life those
values usually don't change dynamically.
 Model parameter property must be both read and write (No ReadOnly or WriteOnly
modifiers are allowed)
 Defined with ModelParameter attribute:

<Parameter("Dimensions", "Net Volume", "m3", "Cell net volume", GreaterThan:=0)>

Public Property NetVolume As Double = 100.0 'm3

 ModelParameter constructor parameters are:


1. Group name (for user interface). Can be empty.
2. Parameter display name (human-readable name of the parameter). This is shown to
the user in the user interface.
3. Unit (kg, m3, etc.). This is shown in the user interface. Can be an empty string.
4. Description for the parameter (this can be a long text or just an empty string)
5. Optional parameters which are:
 MinLim (minimum value that can be set in Sim), for example MinLim := 10.
Applies only for Double type.
 MaxLim (maximum value that can be set in Sim), for example MaxLim :=
100. Applies only for Double type.
 GreaterThan (almost same as MinLim but the value must be greater than the
given value). Applies only for Double type.
 LessThan (almost same as MaxLim but the value must be less than the
given value). Applies only for Double type.
 SortIndex
 This is meant to be automatic and it defines the order in which the
properties are displayed to the user

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
40/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link].1. Groups

 Model parameters can be grouped so all parameters in group "Dimensions" can be


selected in the Sim user interface. This is what Sim looks like when groups "Cell
configuration", "Dimensions", "Operation", etc. are configured in the Unit DLL code. Please
see the attribute constructor description above.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
41/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Internal states

 These are never displayed to the user


 Internal state attributes are Unit DLL "private" variables that just must be saved with the
flowsheet so the internal state (for example tank contents or some counters) of the Unit
DLL are saved and loaded properly with the flowsheet
 InternalState property must be both read and write (No ReadOnly or WriteOnly modifiers
are allowed).
 Defined with InternalState attribute:

<InternalState("Cycle Time Counter")>

Public Property Cycletime As Double

<InternalState("Tails streams of the bank")>

Public Property BankTails As List(Of IHSC8Stream)

<InternalState("Tank")>

Public Property Container As Tank = New Tank()

 InternalState constructor parameter is:Description (actually this is just for programmer’s


note, because it is not displayed to the user)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
42/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Runtime variables

 Runtimeparameters are parameters that are updated between Sim and Unit DLL every
calculation round
 Examples are writing some valve setting to the Unit DLL, reading tank level from Unit DLL,
etc.
 In Sim, the Runtime parameters are usually used with Sim controls
 Defined with RuntimeVariable attribute:

' Read/write property

<RuntimeVariable("Valve Opening", "%", "Set or get the valve opening (0 - 100)")>


Public Property ValveOpening As Double

' Write only property defined in the property definition (WriteOnly specifier)
<RuntimeVariable("Bypass ON", "", "Set line bypass ON")>
Public WriteOnly Property BypassON As Boolean
Set(value as Boolean)
Me._byPassOn = value
End Set
End Property

' Read only property defined in the property definition (ReadOnly specifier)
<RuntimeVariable("Bypass Status", "", "Line bypass ON/OFF")>
Public ReadOnly Property BypassStatus As Boolean
Get
Return Me._bypassStat
End Get
End Property

' Writeonly property defined using the RuntimeVariable attribute (ModelInput and
ModelOutput)
<RuntimeVariable("Valve Opening", "%", "Set the valve opening (0 - 100)",
ModelInput := True, ModelOutput := False)>
Public Property ValveOpening As Double

 RuntimeVariable constructor parameters are:


1. Parameter name (human-readable name for the property). This is shown to the user
in the user interface
2. Unit (kg, Nm3). This is shown in the user interface
3. Description for the parameter (this can be a long text or just an empty string)
4. Optional parameters:
 ModelInput (boolean). If this is set to False, then Sim can't write to this
variable. Easier way to accomplish the same functionality is to use
ReadOnly specifier in the property definition.
 ModelOutput (boolean). If this is set to False, then Sim can't read this
variable. Easier way to accomplish the same functionality is to use
WriteOnly specifier in the property definition.
5. SortIndex
 This is meant to be automatic and it defines the order in which the properties
are displayed to the user

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
43/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Model fit parameters

 Used with Parameter attribute


 Defined with ModelFitParameter attribute:

<Parameter("Settings", "d50c", "µm", "Corrected 50% cut-size", GreaterThan:=0)>


<ModelFitParameter(0.00001, [Link])>
Public Property D50c As Double = 50

 ModelFitParameter constructor parameters are:


1. MinLimit
2. MaxLimit
3. Optional parameters:
 HardMinLimit (boolean)
 HardMaxLimit (boolean)
 Enabled

[Link]. InitModelParameters subroutine in Unit DLL

 The Unit DLL has an optional subroutine called InitModelParameters


 It is used to make sure that all model parameters are initialized correctly
 Especially tables and their sizes are set in this routine
 InitModelParameters is called automatically by Sim every time something has changed
(properties have been written to the Unit DLL, stream connections have changed etc) so it
is the best way to make sure that all parameters are in good order
 To use InitModelParameters in your Unit DLL, you need to add the following code:

Protected Overrides Sub InitModelParameters(ByVal HSC As IHSC8, ByVal ReferenceFeed


As IHSC8Stream)
' Call the base InitModelParameters just to be safe (usually the base implementation
does nothing)

[Link](HSC, ReferenceFeed)

' Your own code here


End Sub

 Parameters given to InitModelParameters:


 HSC - a HSC interface (see IHS8)
 ReferenceFeed - sum of all input streams of the process that contains this Unit DLL.
This can be used to obtain the defined sizeclasses, all minerals (that are inputs to
the process) etc.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
44/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. HiddenPropertyNames subroutine in Unit DLL

 This is an optional function in Unit DLL


 Used to hide some model parameters from the user
 Returns a list (HashSet) of properties that Sim should hide in the user interface
 Example:

Protected Overrides Function HiddenPropertyNames() As HashSet(Of String)


Dim lst = New HashSet(Of String)

If IncludeFishHook = False Then


' Hide property "Beta"
[Link]("Beta")
End If

If SeparationByMineral = False Then


' Hide property "ParamByMineral"
[Link]("ParamByMineral")
End If

Return lst

End Function

 Note that the function should return property names defined in Unit DLL code, not the
display names that are shown to the user in Sim.
 Unit DLL base class contains a helper routine AddHiddenPropertyGroup which can be used
to hide all properties that belong to a given group (that are seen as navigation links in the user
interface in the left side panel) For example "Sizing" group can be hidden with this single
command:

Protected Overrides Function HiddenPropertyNames() As HashSet(Of String)


Dim lst = New HashSet(Of String)

' Hide property "Beta"


[Link]("Beta")

' Hide all properties that belong to group "Sizing"


AddHiddenPropertyGroup(lst, "Sizing")

Return lst
End Function

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
45/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

 A more advanced way to hide multiple properties (or class properties which may have lots of
subproperties) with one command is AddHiddenPropertyPrefix
 Give Property name (or beginning of it) as the argument.
 If it is "Tank1", then property "Tank1", subproperties "[Link]", "[Link]" are
hidden
 If "Tank", then everything beginning with "Tank" is hidden, including "Tank1", "Tank2"
and "[Link]"

Protected Overrides Function HiddenPropertyNames() As HashSet(Of String)

Dim lst = New HashSet(Of String)

' Hide "Tank 1" property and all its subproperties


AddHiddenPropertyPrefix(lst, "Tank1")

' Hide all properties that begin with "DoubleArray" (for example "DoubleArray_1",
"DoubleArray_2", etc.)
AddHiddenPropertyPrefix(lst, "DoubleArray")

Return lst

End Function

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
46/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.3. Unit DLL Calculation

 Unit DLL has two mandatory routines, CalcStatic (for static calculations) and CalcDynamic (for
dynamic calculations):

Protected Overrides Sub CalcStatic(ByVal HSC As IHSC)


' Do static calculations here
End Sub

Protected Overrides Sub CalcDynamic(ByVal HSC As IHSC, timestepseconds as Integer)


' Do dynamic calculations here
End Sub

50.3.1. CalcStatic

 Process the input streams (input amounts are in t/h) and create output streams (output
amounts are in t/h)
 Usually the static calculations don't require much internal states because there are no tanks
or other internal stuff in the unit

50.3.2. CalcDynamic

 Sometimes dynamic calculations may be the same as the static calculations (in really
simple cases where there are no tanks or anything else)
 If the model is not meant to be dynamic, a good practice is to call same static calculation
routines when CalcDynamic is called by Sim
 However, usually dynamic calculations use internal tanks etc.
 Calculation principle is:
 Input streams are in measured in t/h
 Also output streams are measured in t/h
 However, Unit DLL should only process an amount that it gets and outputs during
one Sim calculation time step (for example 1 second)
 Time step is given in timestepseconds parameter
 Therefore you get InputAmount (t/h) * timeStepSeconds / 3600 tons of
material to the Unit DLL internal tank (for example), calculate how much stuff
the Unit DLL would output in the timestep and then multiply it by 3600 /
timeStepSeconds to get the output in t/h

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
47/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.3.3. Writing messages to Sim calculation log

These methods are available in the Unit DLL:

Method Effect
WriteToLog Writes a "normal" log message to the calculation log
InfoMessage Writes an "information" message to the calculation log. Information
message is not an error or a warning but it is slightly more
"important" than a normal log message.
WarningMessage Writes a warning to a log. A warning does not stop calculations but it
is an indication that probably something is going wrong. Warnings
are displayed to the user after calculations,
RaiseFatalErrorException Fatal error. An error is written to the log and the calculations are
stopped immediately. This means that the calculations are going so
wrong that there is no point trying to calculate any further.

50.3.4. Using HSC8Streams and manipulating stream contents

 All Input and Output streams are IHSC8Streams


 Also internal tank contents are IHSC8Streams
 The stream handling is covered in the following page

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
48/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.4. Stream composition

 HSC8Stream (or the interface IHSC8Stream) is meant to contain all contents of one stream
 It can also be used to store the contents of some container, for example a tank
 All amounts in HSC8Stream are measured in tons (per hour)
 For each component stored in the stream there are three things:
 The component (for example, "H2O" or some particle)
 Amount (tons or tons / hour)
 Phase
 Adding a similar component to the same phase increments the first component amount
 So adding 10 x 1 t of "H2O" = adding 10 t of "H2O"
 HSC8Stream takes care of this automatically
 It is also possible to store some extra data ("parameters") for the whole stream or for a
phase
 However, since parameters are not stored within the components, they are not
automatically copied to other streams when the components are added to them

50.4.1. Basic stream manipulation routines

 There are two basic stream manipulation routines: .AllStreamComponentAmounts and


.AddStreamComponentAmount
 .AllStreamComponentAmounts returns a list of all components, their amounts and phases in
the stream
 .AddStreamComponentAmount adds a component (and its phase and amount) to a
stream
 Example:

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
49/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Dim Input As IHSC8Stream ' Let's assume that this has been initialized and
contains some data
Dim Output As IHSC8Stream ' Let's assume that this has been initialized as empty

' Loop all contents of the stream...


For Each ca in [Link]
' ...and add them to the output
[Link]([Link], [Link], [Link])
Next

Moving components from a HSC8Stream to another:

Dim Tank As IHSC8Stream ' Let's assume that this has been initialized and contains
some data
Dim Output As IHSC8Stream ' Let's assume that this has been initialized as empty

Dim Scale = 0.5

For Each ca in [Link]


' ...and add part of the component amount to output
[Link]([Link], [Link], [Link] * Scale)

' And remove the same amount from the Tank


[Link]([Link], [Link], [Link] * (-
Scale))
Next

Converting species to other species:

Dim Input As IHSC8Stream ' Let's assume that this has been initialized and
contains some data
Dim Output As IHSC8Stream ' Let's assume that this has been initialized as empty

Dim Scale = 0.5

For Each ca in [Link]

If [Link] = "H2O" Then


' Convert H2O to H and O
[Link](New StreamSpecies("H"), [Link],
[Link] * [Link]("H2O", "H")
[Link](New StreamSpecies("O"), [Link],
[Link] * [Link]("H2O", "O")
Else
' Do not change the species
[Link]([Link], [Link], [Link])
End If
Next

 There are lots of readymade extension methods (for example .AddStream copies all
contents of one stream so there is no need to write a loop for it)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
50/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.4.2. Different component types

 All components in the stream implement interface IStreamComponent


 Currently there are two different component types that inherit from IStreamComponent:
IStreamSpecies and IParticle

[Link]. IStreamComponent

 All components implement this interface so it is always safe to access the components
using this interface
 If you are writing a Hydro Unit DLL, you know that all components are IStreamSpecies ->
[Link] contains always the species name and you don't even need to
check/cast the component to IStreamSpecies.
 The most relevant members of IStreamComponent are:
 Name (species name if the item is a species, may be anything if the item is a
IParticle)
 ComponentSG (density of the component)

[Link]. StreamSpecies (IStreamSpecies)

 StreamSpecies class defines a single species in the stream.


 The only actual information the class contains is the species name (for example "H2O") and
species density (used in volume calculations).
 This is used in Hydro and Pyro, but also in MinPro (and recycling)
 You can create a new StreamSpecies like this:

' In Sim code:

Dim newSpecies = New StreamSpecies("H2O", 0.992) ' "H2O" species, density 0.992

Dim newSpecies2 = New StreamSpecies("Fe", HSC) ' "Fe" species, get the density from
database using the given IHSC8 interface

' Slightly different in Unit DLL code ("NewStreamSpecies"):

Dim newSpecies = NewStreamSpecies("H2O", 0.992) ' "H2O" species, density 0.992

Dim newSpecies2 = NewStreamSpecies("Fe") ' "Fe" species, get the density from
database

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
51/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Particle (IParticle)

 IParticle is used in MinPro and Recycling models


 A single Particle contains
 Information about the particle size (Particle min size, max size, etc.)
 Particle name (may be anything, even an empty string.
 Mineral composition (list of Minerals and their % amount)
 Each mineral has a Species composition (list of species and their %
amounts)
 All Species can be split to elements
 Creating a new Particle is a bit more complicated than creating a new StreamSpecies:

' First we need some minerals...


Dim species = New List(Of ISpeciesPercentage)
[Link](New SpeciesPercentage("Fe", 46.54642))
[Link](New SpeciesPercentage("S", 53.45358))
Dim PyriteMineral = NewMineral("Pyrite", "Py", 5.01, "FeS2", species)

species = New List(Of ISpeciesPercentage)


[Link](New SpeciesPercentage("Au", 100.0))
Dim AuMineral = NewMineral("Gold", "Au", 17.65, "Au", species)

' Then we need to build the mineral composition in the particle...


Dim minerals = New List(Of IMineralPercentage)
[Link](New MineralPercentage(25.0, PyriteMineral))
[Link](New MineralPercentage(75.0, AuMineral))

' Then we can create the particle


Dim particle = NewParticle("Test particle", 10.0, 100.0,
[Link], minerals)

 Particle constructor arguments are:


1. Particle name (this may be anything but it is better if the names are unique)
2. Lower size of the particle (microns)
3. Upper size of the particle (microns)
4. Floatibility type of the particle
5. Mineral composition of the particle

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
52/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.4.3. Processing the stream contents

 There are a couple of different ways to process the stream contents

[Link]. All stream components, no matter what type they are

 You can enumerate all components with .AllStreamComponentAmounts


 This is safe - you will definitely process all components in the stream, no matter what type
they are or what phase they belong to
 Usually this is the best way to process the stream

[Link]. All phases (and all components)

 You can list all phases using .GetPhaseGroups


 All phasegroups have .Members list which contains all components that belong to that
phase
 This approach is also safe if you do it properly - .GetPhaseGroups returns all phases and
.Members returns all components that belong to the given phase, so ultimately you will
process all components of the stream

50.4.4. PhaseGroups

[Link]. StreamPhaseGroup

 This is a class for all Hydro and Pyro phasegroups


 Usually you can use some existing phasegroup
 But if you want to create a new one, it can be done easily:

' In Sim code:


Dim waterphase = New StreamPhaseGroup("LIQUID PHASE", [Link],
HSC_NTP_Temperature_Celsius + 273.15, 1)

' In Unit DLL code:


Dim waterphase = NewStreamPhaseGroup("LIQUID PHASE", [Link],
HSC_NTP_Temperature_Celsius + 273.15, 1)

 StreamPhaseGroup constructor arguments are:


1. Phase name (usually this matters in Hydro, where Hydro unit tries to map the
HSC8Stream to Hydro Excel phases using the name)
2. Phase (gas, liquid, solid, unknown) - the phase for all species in the stream. This is
not always known, therefore there is that "unknown" option
3. Temperature (in Kelvins)
4. Pressure (in bar)
 Phasegroups are compared using all those properties and two phasegroups are considered
the same only if all of them match
 This creates a problem in Hydro tank if the input temperature changes all the time

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
53/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. MineralPhaseGroup

 This is a special phasegroup for particles


 There is only a single instance if this phasegroup and a reference to it can be obtained by
reading [Link] property
 All particles should be put to this phase
 You can add a particle to MineralPhaseGroup using
[Link] method
 It is otherwise exactly the same as .AddStreamComponentAmount but it adds the
component to MineralPhaseGroup phasegroup

[Link]. ConvertedPhaseGroup

 The only source for this phasegroup is MinPro -> Hydro converter Unit DLL
 You don't see this anywhere else
 The converter puts all generated species to this single phasegroup and the target of the
stream (for example a Hydro unit) will notice the ConvertedPhaseGroup and do some
special processing and divides it to correct phases in its Input sheet

[Link]. GlobalPhaseGroup

 This is used only for storing HSC8Stream global parameters. They need to belong to some
phasegroup that is different than the other phasegroups
 Never use this phasegroup directly

50.4.5. Named variables available in the Unit DLL calculations

[Link]. HSC (given as a parameter to CalcStatic and CalcDynamic)

 See IHSC in later sections.

[Link]. timestepseconds (parameter to CalcDynamic)

 Tells how long the Sim calculation timestep is in seconds

[Link]. ReferenceStream (protected property in Unit DLL base class, available for all
Unit DLLs)

 The sum of all input streams in the model


 This is usually used only in MinPro calculations to get the sizeclasses and other global
settings for the whole process
 This is usually empty or otherwise useless in Hydro and Pyro because they process only
their own inputs and outputs

The global referencestream variable is rarely used because InitModelParameters gets the same
information as a method parameter. However, this could be used to calculate some element
recoveries, for example.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
54/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.5. ConfigurationAction attribute

 Unit DLL can have subroutines that have ConfigurationAction attribute


 A button is created for each such subroutine in Sim user interface
 Clicking the button runs the subroutine in Unit DLL
 These are useful if there are some "reset" commands that the user needs to run

<ConfigurationAction("Empty Tanks", [Link],


"Are You Sure That You Want To Remove All Contents From The Selected Unit?")>
Public Sub EmptyTank()
SetTankLevel(0)
End Sub

<ConfigurationAction("Add Tank", [Link])>


Public Sub AddTank()
RenderTank()

'Apply Format To UI
WriteFormatsToUI()
End Sub

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
55/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.6. Deploying the Unit DLLs and using them in Sim


The compiled DLL must reside in subfolder under
<user>\AppData\Roaming\Outotec\HSC10\DevelopmentUnitDLL

(for example
C:\users\username\AppData\Roamng\Outotec\HSC10\DevelopmentUnitDLL\MyAddinFolder\[Link])

Alternatively you can use the import function in the Sim by using the Unit Model Selector.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
56/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.7. How-to...
50.7.1. How to create new Particle / Stream / other instances

 Call the methods in ObjectFactory module


 NewHSC8Stream
 NewSpeciesPercentage
 NewMineral
 NewMineralPercentage
 NewStreamPhaseGroup
 NewConverterPhaseGroup
 NewMineralPhaseGroup
 NewStreamSpecies
 NewParticle

50.7.2. How to use unit DLL properties

[Link]. Enum property type

 enums are easy to use in Unit DLL:

Public Enum SensorTypes


<Description("Positive mm")>
PositiveThickness
<Description("Negative mm")>
NegativeThickness
<Description("% from Lip")>
PercentageFromLip
<Description("% from Max Range")>
PercentageFromMaxThickness
End Enum

<Parameter("", "Measurement Method", "", "Method how the level is measured in mm


or % (in dynamic calculation)")>
Public Property SensorType As SensorTypes

 Sim creates automatically a dropdowns for enum properties in the user interfaces:

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
57/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Class property types

 You can use classes as properties in the Unit DLL:

<Parameter("Tanks", "Tank 1", "", "")>


Public Property Tank1 As TankClass = New TankClass

...

Public Class TankClass


<Parameter("", "Vol", "l", "Tank volume")>
Public Property Volume As Double
<Parameter("", "Height", "m", "Tank height")>
Public Property Height As Double
<Parameter("", "Width", "m", "Tank width")>
Public Property Width As Double
<Parameter("", "Level", "m", "Tank level")>
Public Property Level As Double
End Class

 You can use classes as property types if the following rules are followed:
 The class must have a default constructor (new without parameters) because Sim
needs to be able to create class instances automatically
 The class variables and properties must follow the same rules as the main Unit DLL
properties if they are to be saved with the flowsheet
 Both the class properties and the Unit DLL property must have RuntimeVariable,
ModelParameter or InternalState attribute applied to them. The visibility of the
single class property is defined as follows:

ModelParameter RuntimeVariable InternalState


ModelParameter ModelParameter RuntimeVariable InternalState
RuntimeVariable RuntimeVariable InternalState InternalState
InternalState InternalState InternalState InternalState

 So the visibility of the parameter is always the least of the two parameters
(ModelParameter being the most visible and InternalState being the most
hidden)

[Link]. Array property types

 you can use arrays in the property types:

' Array of doubles


<Parameter("Settings", "Double list", "number", "List of doubles")>
Public Property Doublelist As Double()

' Array of classes


<Parameter("Settings", "Tank list", "", "List of tanks")>
Public Property Tanklist As TankClass()

 Sim user interface updates automatlcally when the array size changes and the user
interface looks like this:

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
58/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

 And like this:

[Link]. Unit tables

 Unit tables enable the coder to create two-dimensional tables in the user interface
 There are three table types:
 UnitTableDouble (all elements are numbers)
 UnitTableString (all elements are strings)
 UnitTableObject (all elements are either Double, String or Nothing (an empty cell)).
 Unit DLL can set the column and row names of the Unit table and Sim takes care of the rest
(displaying the unit table, handling all user interface issues and saving/loading the data)
 Usually the Unit tables are initialized in the InitModelParameters routine of the Unit DLL
because that is the best place to handle any changes in the unit (for example if streams are
connected/disconnected, etc.)

[Link].1. Setting row/column names

 You can set the rows and columns of the table using the following methods:
 Easiest:
 SetColumns(columnNames as List(Of String), defaultvalue)
 SetRows(newRowNames as List(Of String), defaultvalue)
 These create new rows/columns if necessary and delete unused rows
 These set the row/column order to the same order as given in the list
 After calling these functions you know that the row/column list is what you
want
 These routines do not destroy existing data so if the list already contains
rows "B" and "C" and now you set the list to "A", "B", "C", then only a new
row is added and the existing values remain.
 Of course, if you set the list to "A", "B", then the whole row "C" is
destroyed
 If a new row/column needs to be created, then it is filled with the value from
defaultValue parameter
 More detailed:
 Inserting new rows/columns
 InsertRow(newRowName, defaultValue)
 AddColumnData(newColumnName, defaultValue)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
59/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

 AddHiddenColumnData(newColumnName, defaultValue) - inserts


a new hidden column to the list. Hidden columns are not visible to the
user in the user interface.
 Removing rows/columns
 RemoveNonExistingColumns(columnNameList, optional
hiddenColumnNameList)
 RemoveNonExistingRows(rowNameList, optional
hiddenRowNameList)
 RemoveRow(rowName)
 (seems that RemoveColumn is missing)
 Listing existing rows/columns
 RowNameExists
 ColNameExists
 RowNames
 RowCount
 ColumnNames
 ColNameExists
 ColumnCount

' Set the rows and columns the easy way


[Link](New List(Of String)({"Plate small", "Plate Large", "Fragmented",
"Elongated", "Miscallaneous"}), 0.0)
[Link](New List(Of String)({"Density", "RGB red value", "RGB green value",
"RGB blue value"}), 0.0)

[Link].2. Accessing cell values

 There are two (overloaded) routines for reading and writing data:
 SetParam(row, column, newValue)
 GetParam(row, column)
 The value type (Double, String or Object) depends on the Unit table type
(UnitTableDouble, UnitTableString or UnitTableObject)
 You can use either the row/column name or numeric index as the row/column
parameters:

' Reading value using row/column names


Dim value = [Link]("row 2", "column 3")

' Reading value using row index and column name


value = [Link](0, "column C")

' Setting value using row and column names


[Link]("Density", "Plate Large", 80.0)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
60/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link].3. Formatting cells


 There are (limited) possibilities to format cells in the Unit DLL code. Currently it is possible
to set the cell format to several different modes:
 [Link] (really red background)
 [Link] (light red background)
 [Link] (no formatting)

' Set the top left cell to red background


[Link](0, 0, [Link])

' Set a named cell to "not used" format


[Link]("Row 2", "Column 3", [Link])

 The formatting is cleared every time before InitModelParameters is called so the


cells have to be reformatted every time in InitModelParameters

 The formats are named according to the cell color, boarder style, alignment and number
format
 A cell may contain multiple formats, and are separated by underscore (_)
 For Example, the entries in "...Normal_RightThin_CenterAlign" for exampel
means that:
 Normal (white) color is used
 The right side of the cell contains a thin black boarder
 The text is centered
 The Cell Color/Style is always defined in the first entry. The available styles are:

 Error after the cell style indicates a red font, for example:

 The cell boarder is typically defined after the cell style and font. The boarder is a
combination of placement (Right, Left, Top, Bottom) and thickness (Thin, Medium,
Thick).
 Styles with alignment contain the placement (right, center or left) combined with the
word "Align", for example "RightAlign".
 Styles with number format contain words like percent (0.25 -> 25.00%), Celsius (25
-> 25 °C) etc.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
61/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link].4. Formatting and/or hiding row/column headers


 The programmer can change how the column header is displayed to the user.
Display
Header Name Comments
Text
"Header" "Header" The default way - show the header as it is
[Link] & (nothing
Hide the header
"Header" displayed)
The header consists of the "secret" part and
visible part. For example we might need
several columns that look like "Cu" but
[Link] &
internally we have to distinguish between
"Secret" &
"Shown" them. Therefore we would have
[Link] &
"CuWeight"/"Cu" and "CuPercentage"/"Cu"
"Shown"
columns. Internally they would be different
but the user would see only "Cu" in both
cases.
 Entire headers can be hidden trough the headertype. The syntax for hiding headers is:
 HeaderType

'Set row header style to normal


[Link] = [Link]

'Set column header style to empty


[Link] = [Link]

 The different header types and properties are:


Col & Row Display Use

Type Header Is Col & Row Auto

Visible Name Width


Normal X X X
Hidden
Empty X
Visible X X

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
62/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

[Link]. Dropdowns, Comboboxes, Checkboxes and Comments


The programmer can insert UI elements such as dropdowns and checkboxes. The current table
values are accessed with GetParam() and SetParam() that were described [Link]

Dim dropdownArray = {"Hello", "World"}

'Set Dropdown, there will now be a


[Link](row, col, dropdownArray, isComboBox:=False)

'Set dropdown value to "Hello"


[Link](row, col, "Hello")

'Get Current Dropdown Value


Select Case CStr([Link](row, col))
Case "Hello"
'Current Value Is "Hello"
Case "World"
'Current Value Is "World"
End Select

ComboBox

Dim dropdownArray = {"Hello", "World"}

'Insert Combobox To Cell


[Link](row, col, dropdownArray, isComboBox:=True)

'Set combobox value to "Hello"


[Link](row, col, 1)

'Get Current Combobox Value


Select Case CInt([Link](row, col))
Case 1
'Current value is "Hello"
Case 2
'Current value is "World"
End Select

Note! Use indexes to get and set combobox values. Also note that indexing starts from 1!

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
63/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

Checkbox

'Set Checkbox And Initialize To Checked


[Link](row, col, True)

'Uncheck
[Link](row, col, False)

'Get Current Value


Select Case CBool([Link](row, col))
Case True
'Is Checked
Case False
'Is Unchecked
End Select

Comments

'Set Comment
[Link](row, col, "Boo!")

'Get Comment
[Link](row, col)

ClearCell

'Reset cell. The cell will be empty!


[Link](nRow, nCol)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
64/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.8. IHSC

 The IHSC object provides most of the calculation routines that are available in HSC Sim
 Some of them for examples are: MW (molar weight of some species), BP (boiling point of
species), etc.
 HSC methods are typically applied when processing species (in Hydro and Pyro modes)
but they are rarely needed in MinPro models because MinPro calculations are usually done
with other routines of the stream object.
 All IHSC8 methods use Kelvins, kWh and bar as their units (unless specified otherwise)

50.9. Dynamic calculation: Tank content manipulation by user from Sim

The user can set the fill levels of tanks of all units using the Sim dynamic calculation user interface).
Usually the tanks can be emptied but also their fill level can be set using a value between 0..100.

Since HSC Sim can't know what Unit DLL properties and internal variables handle the tank content, the
Unit DLL programmer must handle the tank level setting with his own code.

Implementing the tank level manipulation is optional: Some Unit DLLs don't have an internal tank and in
some cases modifying the tank level from "outside" just is not supported.

Override method SetTankLevel:


Protected Overrides Sub SetTankLevel(tankLevelPercentage As Double)
' your code here
End Sub

 SetTankLevel is called with a Double parameter (usually between 0..100). 0 means that the
tank should be emptied, 100 means that the tank is filled completely. However, although
strongly discouraged, the Unit DLL programmer can interpret the number as he/she wants.
 When SetTankLevel is called, all stream content properties (both input and output) have
their actual values, so the programmer can get a suitable tank content from any stream.
 But be prepared: in some cases the stream contents may be empty, for example if
the flowsheet has never been run.

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy
Sim Unit DLL Programming
65/65
Jussi-Pekka Kentala, Marko Leino,
Antti Remes, Matti Hietala
September 7, 2023

50.10. Tips and tricks

50.10.1. Using List(Of Double) in Unit DLL property instead of array

 Sim requires that all Unit DLL list properties are arrays but it is much more convenient to
use List(Of something) in programming instead of [Link] arrays
 Solution: use a wrapper property:

' This is what you use in code


Private Property MyList As List(Of Double)

' Wrapper which communicates the contents of the list to Sim and back
<InternalState("Double List")>
Public Property DoubleArray As Double()
Get
Return [Link]
End Get
Set(value As Double())
MyList = New List(Of Double)(value)
End Set
End Property

...

' In the actual code you can just use the MyList property and don't need to worry
about the array property at all
[Link](123.45)

Metso reserves the right to modify these specifications at any time without prior notice. Copyright © 2023, Metso Finland Oy

You might also like