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

UniSim EO 4GL Developer Guide

Uploaded by

alex
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 views69 pages

UniSim EO 4GL Developer Guide

Uploaded by

alex
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

UniSim® Design

Equation Oriented 4GL

Developer Guide

Release 492
October 2022
DISCLAIMER

This document contains Honeywell proprietary information. Information contained herein is to be used solely for the purpose
submitted, and no part of this document or its contents shall be reproduced, published, or disclosed to a third party without the
express permission of Honeywell International Sàrl.

While this information is presented in good faith and believed to be accurate, Honeywell disclaims the implied warranties of
merchantability and fitness for a purpose and makes no express warranties except as may be stated in its written agreement
with and for its customer.

In no event is Honeywell liable to anyone for any direct, special, or consequential damages. The information and specifications in
this document are subject to change without notice.

Copyright 2022 - Honeywell International Sàrl

-2-
CONTENTS

Chapter 1 - Creating a UniSim EO 4GL Element 5


Chapter 2 - 4G Language 7
2.1 Comments 7
2.2 Keywords and Attributes 7
2.2.1 Classification 8

2.3 Declarations 9
2.3.1 constant 9

2.3.2 variable 9

2.3.3 parameter 20

2.3.4 include 20

2.4 Specifications 21
2.5 Process Streams 22
2.6 Embedded Objects 24
2.7 Equations 26
2.8 Model Constructs 29
2.8.1 Class, Type and Object 29

2.8.2 if and ifswitch statement 30

2.8.3 Usage of When and If statements 31

2.8.4 Local Functions 31

2.9 Auto-Completion Feature 39


2.10 Drag and Drop to reference variables in 4GL 40

Chapter 3 - 4G View 41
3.1 Parameter and Results View 41
3.2 PFD Icon Development 42

Chapter 4 - Solving a UniSim EO Flowsheet Model 46

-3-
4.1 Simultaneous Solver 46
4.1.1 Initialization 46

4.2 Sequential Solver 48


4.3 Dynamic Solver 48
4.4 Tips to build a robust model 49

Chapter 5 - References 51
Chapter 6 - Appendix 52
6.1 Keywords and Attributes 52
6.2 FORTRAN and C/C++ Subroutines and Functions 59
6.2.1 Calling a FORTRAN or C subroutine from within a UniSim EO 4GL Model 60

6.2.2 Calling a FORTRAN or C function from within a UniSim EO 4GL Model 65

6.2.3 Functions with Scalar Input Arguments 65

6.2.4 Functions with a Single Vector Input Argument 66

-4-
CHAPTER

1 CREATING A UNISIM EO 4GL ELEMENT

UniSim EO 4GL is a process modeling language for custom modeling in UniSim EO. UniSim EO 4GL enables modeling
engineers to create their own unit operation models, instantiated as flowsheet objects, referred to as “Elements” in UniSim
EO and as “Unit Ops” within UniSim Design, which can be used within a UniSim EO flowsheet together with native UniSim
EO elements to create a flowsheet model of a process. It also enables modeling engineers to embed proprietary and/or
application specific modeling relationships, such as pressure gradient or heat transfer correlations, within a flowsheet model.

With the UniSim EO flowsheet (PFD) active, select Custom Op -> Custom Element from the Available Element Types
palette so that Custom Element is highlighted as shown below.

Figure: 1.1 Available Elements Palette

To place a Custom Element on the flowsheet, either double click on Custom Element or click on the Create Element button.
The results of this action are shown below. A Custom Element is dropped onto the flowsheet and its view is automatically
opened.

Change the name of the custom element by selecting the name field in the General page of the view, which is active by
default when the view is opened, and entering an appropriate name.

At this point, the custom element is empty, that is, it has no model. To create the model, select the Model page of the view. To
select a page of a view, click on the name of the page in the page selector panel on the left side of the view. Then change the
description of the custom element by selecting the description field and entering an appropriate description. Enter the model
by typing the statements necessary to describe the model, declaring constants, variables, inlet and outlet stream ports, etc.
and providing the modeling equations as described herein or by clicking on the “Load From File” button to load the model
from a plain text (ASCII) file. All statements, excepting comments, must be terminated with the end-of-statement delimiter “;”.
Syntax checking is performed when changes in the model are committed. To commit changes in the model, click on the
Commit Changes button, which becomes active when changes have been made.

-5-
Chapter 1 - Creating a UniSim EO 4GL Element

Figure: 1.2 UniSim EO Flowsheet with Empty Custom Element

As shown below a UniSim EO 4GL model for a simple valve unit operation, with this element connected to process ports in a
flowsheet.

Figure: 1.3 UniSim EO Flowsheet with a Custom Element for a Simple Valve Unit Operation

Modeling engineers can customise flowsheet icons for Custom Elements which is described in a separate section. By
default, any element will have the shaded box shown in above figure.

-6-
CHAPTER

2 4G LANGUAGE

The following section introduces the fundamental elements of a UniSim Equation Oriented 4GL model.

2.1 Comments
Two forward slashes (//) comments to the end of the line.

Examples

// Radiant Section
variable Patm; // Reactor Pressure (atm)
// variable Patm; /* Reactor Pressure (atm) */

Block comment sections wrapped by pair of delimiters (/* and */).

Examples

/*
// Radiant Section
variable Patm; // Reactor Pressure (atm)
*/
variable Patm; /* Reactor Pressure (atm) */

NOTE
The first encountered comment style supersedes any following/embedded comment styles.

An open block comment section will quietly comment until end of model (or next closed comment block) – only evident
by green syntax highlighting.

2.2 Keywords and Attributes


Keywords are used for declaring and defining variables, resuable functions or files and error or warning conditions in a
model. Usually the Keyword is provided as a prefix to a variable. Keyword statements have the syntax

KeywordTag Variable/Function/Class/File/Condition.

Attributes are designed to simplify model development. When you include Attributes in your model files,the 4GL compiler
works to organize and document a model. From a model documentation perspective and for improved understanding and
readability of the model, the modeling engineer can use available Attributes at various levels. The Attribute is provided as a
prefix to a variable, expression or as a separate statement on the line preceding a variable or an expression. Attribute
statements have the syntax [AttributeTag Value]

Detailed list of all the available keywords and attributes are in the Appendix’s Keywords section.

-7-
Chapter 2 - 4G Language

2.2.1 Classification
Using the Classification attribute helps to organize the variables of a model so they are easily viewed in the Parameters page
of the view for a model.

The Classification attribute statement sets the classification of the variables whose declarations follow the Classification
attribute statement. The variables of the model are grouped in the Parameters page of the view for the model according to
their classifications. Within a classification, the variables are ordered alphabetically.

The Classification groups are ordered alphabetically according to the Classification values with the exception of the implicit
classification of parameters. All parameters are automatically given the Classification tag “Parameter”. The Parameter group
is always the first group in the Parameters page - see the section on parameter declarations.

Variables that are declared before a Classification attribute statement has been used or after a “[Classification None]”
statement are given the default classification tag “General”, which is always the last group in the Parameters page.

Example

For the simple valve model shown in Figure: 1.3 , a Classification attribute statement has been used, creating the
classification “Model Variables” as shown below.

parameter Cv; // valve constant


[Classification Model Variables]
variable dP as DeltaPressure; // pressure drop (Pa)
variable Rho; // mass density at the inlet (m^3/kg)

The parameter is automatically given the “Parameters” Classification tag value as noted above. The Parameters page that
results from the above use of the Classification attribute statements is shown in below figure.

Figure: 2.1 Parameters Ply for the Simple Valve Unit Operation

-8-
Chapter 2 - 4G Language

2.3 Declarations
UniSim EO 4GL is a strongly typed language. All constants, parameters and variables must be declared.

2.3.1 constant
A constant is a fixed numeric value. Constants are declared using the “constant” keyword.

Examples

constant NumGridPoints = 4;
constant alpha = 1; // Fan Law exponent for volumetric suction flow
constant beta = 2; // Fan Law exponent for polytropic head
constant gc = GRAVITY as Acceleration in ft/s2; // = 32.174049

Last example demonstrates a literal value as another constant (any constant expression is allowed) along with literal value
conversion to chosen units. Further examples of assigning literal values with units are shown at the end of variable section
below.

UniSim EO 4GL has four core constants:

TRUE = 1

FALSE = 0
PI = 3.14159265…

GRAVITY = 9.80665

The core constants can be used without explicit declaration.

To view the constants declared in a UniSim EO 4GL model, select the General page of the view for the element. Then click
on Parsed Model Summary / Constants, on the count (numeric value) or the “…” button.

2.3.2 variable
Variables are the quantities solved for during the solution of the mathematical model. Variables of a model are declared
using the “variable” keyword. A variable can be declared to be a scalar or a vector. Referencing of the elements of vector
variables is zero based, that is, the index for the first element of a vector is zero. UniSim EO 4GL is a strongly typed
language; all variables of a model must be explicitly declared.

Examples

constant NumGridPoints = 4;
variable GridTemp[NumGridPoints]; // grid point temperatures
variable Size as Integer; // integer variable
variable stageTemp[Size]; // to “dynamically” size vector
// stageTemp
variable LiqLevel; // liquid level
variable Ax; // cross-sectional area

Since referencing of vector elements is zero based, the elements of GridTemp would be referenced as

GridTemp[0], … , GridTemp[3]

Variables can be assigned a process specific type, such as Temperature, Pressure, MassFlow, MolarFlow, etc.

Examples

-9-
Chapter 2 - 4G Language

variable LiqLevel as Percent; // liquid level (% of vessel volume)


variable Ax as Area; // cross-sectional area (m^2)
variable ReactionTemp as Temperature; // reaction temperature (degK)
variable ReactionPres as Pressure; // reaction pressure (Pa)
variable OutFlow as MassFlow; // outlet mass flow (kg/s)

Variables can also be assigned standard types like boolean, enumeration, integer, string etc. The default variable type for a
variable is Real.

Examples

variable isChoked as Boolean;


variable PumpSwitch as Enumeration { On, Off };
variable ExplicitEnum as Enumeration { On = 2, Off = 5};
variable Count as Integer;
string Tag = "Hi there";
string Tags[] = { "Hello", "Happy Modelling!" };

NOTE
ExplicitEnum enumeration definition has an explicit value assigned for On (via On = 2) so it declares a constant
called ‘On’. As in PumpSwitch enumeration, if no value is mentioned then it would implicitly have a value of zero, and
no constant would be declared. In this case, setting an enumeration variable by label will still work (no constant is
required). This also allows an enum label to be repeated in a different context without concern for collision.

The complete list of variable types is provided by the auto-completion feature on typing “as”. When a variable is assigned a
type, it has the internal engineering unit of UniSim Design (strict SI) for that variable type, for example, °K for
Temperature, Pa for pressure, kg/s for MassFlow, kmoles/s for MolarFlow, J/kg for MassEnthalpy, J/s (W) for
HeatFlow, etc. However, the engineering units in which variables are displayed in the Parameters page of the view for an
element are those of the engineering units set selected using UniSim Design’s Preferences tool. Also like UniSim Design,
when specifying a variable, enter it in the units in which it is displayed. The value is automatically converted to the appropriate
internal engineering unit. Currently,a complete listing of the engineering units associated with the variables types is not
available. To see the internal engineering units for the variables shown in the Parameters, Conditions and Properties pages
of the view for an element place the cursor over their values; an information box, as shown below. Information box showing
the internal value and engineering units for variable P, pops up showing the internal value and engineering units for the
variable.

- 10 -
Chapter 2 - 4G Language

Figure: 2.2 Information box showing the internal value and engineering units for variable P

Variables can be declared in external units with compound conversions. These sort of conversion helps model builders to
write models complying with certain industry standards which are in a different unit system. This helps in avoiding the need
for explicit unit conversions.

variable VapourPressure as Pressure in psia;


VapourPressure:Internal = [Link];

variable AreaInmm2 as Area in mm2;


variable Area as Area = AreaInmm2:Internal;

For variables that are not assigned a type, the author of the model is responsible for ensuring engineering units consistency.
Also, such variables are displayed on the Parameters page of the view for the flowsheet element without engineering units
as shown for variable cV in Figure: 2.2 .

Model values can be assigned in specific units for either calcs or specs (with “as spec” suffix) by adding inline units to literal
values – as follows:

// model calc
[Link] = 100 kPa;

// model spec
variable P as Pressure = 10 kPa as spec;

// equivalent - broken up:


variable P as Pressure;
P = 10 kPa as spec;

The length of a vector variable can be declared in several ways:

- 11 -
Chapter 2 - 4G Language

l unbounded
A vector can be declared without a size, leaving size to be determined by user at runtime.

variable Values[]; // user determined size

User can enter values or press insert or delete to resize.


l a literal numeric value or constant followed by +
A vector can be declared with a minimum size, and otherwise be determined by user.

variable Values[1+]; // user determined size with min of 1

l a literal numeric value or constant followed by -


A vector can be declared with a maximum size, and otherwise be determined by user.

variable Values[5-]; // user determined (initially 0, max 5)

l a literal numeric value, a constant, or expressions involving only literal numeric values and constants

variable Values[3]; // fixed size vector

constant NumPoints = 4;
variable Values2[NumPoints]; // fixed by constant
variable Values3[NumPoints/2+1]; // fixed by expression

l an Integer variable
A vector can be sized by an integer variable.

variable NumPoints as Integer;


variable Values[NumPoints]; // sized by integer variable

Changes to NumPoints by the model engineer at runtime will cause Values to resize.
NumPoints can also be assigned from 4GL code.

l an Integer variable followed by +constant


A vector can be sized by an integer variable and also have a minimum size.

variable NumPoints as Integer;


variable Values[NumPoints+1]; // always NumPoints+1 long

If Size is unknown then vector will be size 1.


This syntax is useful for models that write equations for specific offsets that are always expected to exist. Equations
with references to specific offsets of vectors won’t be accepted on commit unless the vector offsets are guaranteed
to exist.
l an Integer variable followed by -constant
A vector can be sized by an integer variable with a fixed reduction in size.

- 12 -
Chapter 2 - 4G Language

variable NumPoints as Integer;


variable Values[NumPoints-2]; // always NumPoints -2 long

Changes to NumPoints will cause Values to resize. If NumPoints is less than 2 or is unknown then vector will be
sized zero.
l another vector variable
A vector variable can be declared to be of length number of compounds in the current fluid basis by using the vector
variable “Compounds”, which holds the pointers to the compound objects which contain the compound names used
for the offset tags, for the length of the vector.
More generally, a vector can be sized by any other vector but only pointer and text vectors make indexing by tag
available.
For modeling this is the most reliable form of vector sizing because entries will be inserted or removed at the
appropriate offsets (not always on the end as for other techniques above).
Example

variable CompFlows[Compounds] as MolarFlow; // kmoles/s

Although not a requirement, it is preferable to reference individual elements of a vector variable that is sized to the
number of compounds, as above, using the component names rather than integer offsets; using the component
names is more reliable. For example, suppose that Methane, Ethane, Propane, n- Butane and H2O are the
compounds declared in the fluid package. Then, the flow of hydrocarbon components could be calculated using

Variable HydrocarbonFlow as MolarFlow;


HydrocarbonFlow = CompFlows[Methane] + CompFlows[Ethane] +
CompFlows[n-Butane] + CompFlows[Propane];

More generally, any vector variable can dictate the size of another vector variable. For example

variable x[[Link]];

declares x to be a vector variable of length the number of active phases in inlet stream ProIn.

[Link] Vector assignments and access

The vector variable can be defined and accessed in several ways which are described below

l using range monikers


A vector can be defined using range monikers.

variable lhsVec[2];
variable rhsVec[7];

lhsVec = rhsVec[5:6];

The vector equation using range monikers maps each element by element. Use consistently sized vector for
assignments. Do not relate constantly sized and name sized vectors. Equations (especially vector equations) need
all vectors to be the same size and consistently sized.

- 13 -
Chapter 2 - 4G Language

variable lhsVec2[2];
variable rhsVec2[7];

rhsVec2[0:5] = 3 as spec;
rhsVec2[6:size-1] = 5 as initial;

lhsVec2 = rhsVec2[2:3]

Range monikers on a vectors helps to make few elements as model specifications and rest as model variables. This
helps in consolidating specification and variables into a single vector.
l using trailing scalar emulators
A vector size can be obtained by vector’s internal variable called “size”. It can be used only in vector’s context i.e. not
as a parameter in the model.

variable scalarVar0;
variable scalarVar1;
variable rhsVec[7];
scalarVar0 = rhsVec[size-1]; // for last entry
scalarVar1 = rhsVec[size-2]; // for second from last entry

l using vector for defining a matrix and transposing them using array operator []
Matrix operations are not explicitly supported in 4GL. However, a matrix can be supported by using a vector of
vectors. The following is an example of how a matrix can be defined and used.

constant nCol = 5;
constant nRow = 5;
class Row
{
variable T[nCol];
};
class Column
{
variable T[nRow];
};
object Rows[nRow] as Row;
object Columns[nCol] as Column;
Columns.T = Rows[].T;

Rows, Columns and T are vector variables. See the array operator [] on the RHS

Columns.T = Rows[].T;

If array operator ‘[]’ is not there, the vector would expand from right to left on both sides of equality/assignment
operator i.e. T would get incremented first (T would be the basis of assignments in the inner increment loop) and
then subsequent Rows or Columns. But in this case, Rows would get incremented first. Ensure the dimensions of
Rows and Columns are consistent for the transpose operation.
l manipulating matrix

constant nCol = 5;
constant nRow = 5;
class Cartesian

- 14 -
Chapter 2 - 4G Language

{
variable T[nCol] as Temperature;
variable dx = 1;
variable dy = 1;
variable dTdx[nCol];
variable dTdy[nRow];
dTdx[0] = 0;
dTdx[1:size-2] = (T[2:size-1] - T[0:size-3]) / (2 * dx);
dTdx[size-1] = 0;
variable Tby2dy[nCol] as Temperature = T / (2 * dy);
};
object HeatCond[nRow] as Cartesian;
HeatCond[1:size-2][].dTdy = (HeatCond[2:size-1][].Tby2dy - HeatCond[0:size-3][].Tby2dy);

// Direction Option
// HeatCond[1:size-2][].dTdy = ((HeatCond[2:size-1][].T - HeatCond[0:size-3][].T))/(2 * dy);

The above calculation of dTdy accounts division by 2dy in two different ways using array emulator. Please note those
math operation should be done before hand and should be made available for matrix transpose operations.
l auto-expansion of equations of form "matrix = scalar"

objects[].Vector = Scalar;

Vector variable in all the elements in the objects array would get initialized to the scalar.

class MyClass
{
variable Data[2];
};

object objects[2] as MyClass;


variable DataValue = 2;

objects[].Data = DataValue;

Data vector elements for all the objects in the above example would get initialized to 2.
l emulated matrix references (auto-expanded in vector of scalar equations)

objects[].Scalar = @Sum(Objects[].Vector);
class MyClass
{
variable Data[2];
variable Summation;
};

object objects[2] as MyClass;


variable DataValue = 2;

objects[].Data = DataValue;
objects[].Summation = @Sum(objects[].Data);

Summation variable in all the instances is assigned to instance’s sum of vector elements.
l entry vector equations (i.e. emulated matrix variable on left)

- 15 -
Chapter 2 - 4G Language

objects[].Vector = VectorA + VectorB[];


class MyClass
{
variable Data[2];
};

object objects[2] as MyClass;

variable DataValueA[2];
variable DataValueB[2];

DataValueA[0] = 1;
DataValueA[1] = 2;
DataValueB[0] = 10;
DataValueB[1] = 20;

objects[].Data = DataValueA + DataValueB[];

The above line would expand as below

objects[0].Data[0] = DataValueA[0] + DataValueB[0];


objects[1].Data[0] = DataValueA[0] + DataValueB[1];
objects[0].Data[1] = DataValueA[1] + DataValueB[0];
objects[1].Data[1] = DataValueA[1] + DataValueB[1];

which would result in

objects[0].Data[0] = 11
objects[0].Data[1] = 12

objects[1].Data[0] = 21
objects[1].Data[1] = 22

l custom compound vector


Compound vector is possible both in left hand side or right hand side of an equation or an expression.
Compound vector in LHS

{ScalarA, VectorB, ScalarB} = VectorA + 1;


variable x0;
variable x1[2];
variable x2;
variable x[4];

x[0] = 1;
x[1] = 2;
x[2] = 3;
x[3] = 4;

{x0, x1, x2} = x + 1;

Compound vector in RHS

VectorA = {ScalarA, VectorB, ScalarB};

variable MinWallTemperatures[Nz] as Temperature;

- 16 -
Chapter 2 - 4G Language

MinWallTemperatures =
{[Link], [Link],
[Link]};

l ranged vectors using round brackets


Use of round brackets assumes size will be correct at runtime as determined by user even if it is wrong and index
would be out of bounds at commit time.

// Compute the inside diameter for each layer.


Di(0) = 0.5;
[When @size(Di) > 1]
Di(1:size-1) = Di(0:size-2) + 2 * layer(0:size-2).Thickness;

It is left to user to ensure bounds check on the vector as the 4GL compiler parser would not detect syntax errors
during commit. Since ranged vectors is discussed in this context, the index size-1 (the upper range) will not be
checked.

[Link] Connect

Aliases is an important option for connecting objects. In a process simulator, as with many software applications, information
flows from inlet object to outlet object through connections that may be specified by the user or calculated at run-time.
Connect can be used when a vector of objects need to alias their scalar or vector properties.

l Connect Object(Inlet, Outlet) from GlobalInlet to GlobalOutlet

The Inlet and the Outlet property of the element instances are aliased to each other as shown in the above diagram.
The inlet and the outlet property could be a scalar or vector.

class Increment
{
variable InletValue;
variable OutletValue = InletValue + 1.0;
variable GlobalScalar;
variable GlobalVector;
variable CalcVariable;
[when GlobalScalar > 2] CalcVariable = 2;
[when GlobalScalar <= 2] CalcVariable = 1;
};

variable IncrementInlet = 1.0;


variable IncrementOutlet;
object Increments [5] as Increment;
connect Increments(InletValue, OutletValue) from IncrementInlet to IncrementOutlet;

l Connect Object(Parameter, Parameter) from GlobalScalar

- 17 -
Chapter 2 - 4G Language

variable OverallScalar = 2;
connect Increments(GlobalVector, GlobalVector) from OverallVector;

This is equivalent to auto-expansion of equations of form "matrix = scalar" i.e. objects[].Vector = Scalar.
l Connect Object(Parameter, Parameter) from GlobalVector

variable OverallVector[5];

OverallVector[0] = 0;
OverallVector[1] = 1;
OverallVector[2] = 2;
OverallVector[3] = 3;
OverallVector[4] = 4;
connect Increments(GlobalVector, GlobalVector) from OverallVector;

l Need to daisy chain across properties in each object (any type including scalar/vector)

class BaseWallLayer as Base


{
variable cp as MassHeatCapacity;
variable rho as MassDensity;
};

class CarbonSteel : BaseWallLayer


{
cp = 490.0;
rho = 7850.0;
};

class GlassWool : BaseWallLayer


{
Cp = 470.0;
Rho = 125.0;

- 18 -
Chapter 2 - 4G Language

};
class WallModel
{
object layerWallParams[] as CarbonSteel;
};

class WallInterfaceModel
{
type WallLayerTypes[2] as BaseWallLayer = GlassWool;//CarbonSteel;
object WallParams[WallLayerTypes] from WallLayerTypes;

object myWall[2] as WallModel;


connect myWall(layerWallParams, layerWallParams) from WallParams;
};

Defined WallParams properties is chained across all the wall layers


l Need to alias property of object up to property in main (any type including scalar/vector)

variable GlobalParameter[2];
GlobalParameter[0] = 10.0;
GlobalParameter[1] = 20.9;

class Math
{
variable CalcParameterIn;
variable CalcParameterOut;
CalcParameterOut = CalcParameterIn + 10;
};

object mathInstances[2] as Math;

connect mathInstances(CalcParameterIn, CalcParameterIn) from GlobalParameter;

The above statement would expand as follows

mathInstances[0].CalcParameterIn = GlobalParameter[0];
mathInstances[1].CalcParameterIn = GlobalParameter[1];

l Need to alias scalar property up to entry of vector property in main (any type)
l Need to alias vector property up to entry of [Link] (emulated matrix)

class Math
{
variable vectorSize2[2];
variable vectorSize3[3];
};

class Science
{
variable vectorSize2[2];
}

object ScienceObject as Science;


ScienceObject.vectorSize2[0] = 50;
ScienceObject.vectorSize2[1] = 20;

object MathObjects[3] as Math;

- 19 -
Chapter 2 - 4G Language

Connect MathObjects(vectorSize2, vectorSize2) from ScienceObject.vectorSize2;

l Connect keyword to do "parallel" aliases when aliasing directly up

Connect Objects(Scalar, Scalar) from Vector

results in

Objects[].Scalar = Vector[]

Connect Objects(Vector, Vector) from Scalar

results in

Objects[].Vector[] = Scalar

When a scalar is connected to the vector’s in vector of object, it results in hardwiring. This leaves large degree of
freedom. Hence map vector to vector.
l Parameter / Variable Percolation / Multi-Dimensional array support
Currently multi-dimensional array’s are not supported. Only matrix can be emulated using one dimensional vectors.
Constant vector size defined in main module will not percolate through classes though it is a constant at the global
level. Hence class scope vector’s need to be sized using constants defined at the same level.

2.3.3 parameter
Parameters are quantities in the model that would typically be held fixed, that is specified, in simulation mode. Examples
include coefficients of an engineering relationship such as the coefficients of the function representing the performance curve
for a compressor or the heat transfer area of a heat exchanger. However, functionally, parameters are variables. They are
only different in how they are perceived. So, since parameters are really variables, they are solved during the solution of the
mathematical model, facilitating the formulation and solution of design problems and parameter estimation problems. For
example, in design mode, a model can be used to find the heat transfer area needed to achieve an operating design
approach temperature for a heat exchanger. In parameter estimation mode, a model could be used to find the efficiency for
a compressor that enables the model to most closely match operating data.

Parameters are declared using the “parameter” keyword. The syntax is identical to that for “variable” keyword; just
replace “variable” with “parameter”.

Parameters are displayed together under the classification “Parameters” in the Parameters ply of the view for the element
for the model. Essentially, a [Classification Parameters] statement is implicitly added into the model when the
“parameter” keyword is used.

2.3.4 include
Include files can be used to share constant, variable and parameter declarations across different models. An include file is
referenced using the “include” keyword. User can click on include file and expect the include file to open in a new window.

Example

include "[Link]";

- 20 -
Chapter 2 - 4G Language

The file name can optionally include a path. When the path is missing or is relative, the file is first checked for in the current
(UniSim Design startup) directory; if the file is not found, a search for the file is performed using the PATH environment
variable.

Multiple include files can be referenced within a model. Include files can be nested, that is, an include file can be referenced
within an include file.

Include files are only read when editing the text form of a model. After model changes are committed, any further changes to
included files do not take effect until the model is edited and the changes are committed again.

Duplicate constant declarations with different values are flagged as an error when model changes are committed.

Include files can also hold the RequiredComponents attribute, inlet and outlet stream port declarations and/or local function
definitions.

2.4 Specifications
When creating a unit operation model, there will typically be more variables than equations. The unit operation is said to have
degrees of freedom. Its degrees-of-freedom is calculated as its number of variables minus its number of equations. The
concept of degrees of freedom extends to a flowsheet model as well. For a flowsheet model constructed from unit operation
models, the degrees-of-freedom of the flowsheet model is the sum of the degrees-of-freedom over all instances of its unit
operation models.

To solve a flowsheet model it must be square, that is its number of variables and its number of equations must be equal. To
square up a flowsheet model, the modeling engineer must provide an equation that “consumes” each degree-of-freedom of
the model. Furthermore, these equations must be independent1 of all other equations of the model, including the other
equations provided by the modeling engineer to consume degrees of freedom.

UniSim EO 4GL models can be constructed by modeling engineers to provide equations of arbitrary complexity to consume
degrees of freedom. For example, a UniSim EO 4GL model could be constructed to implement a heat transfer coefficient
correlation, consuming the degree-of-freedom associated with the heat transfer coefficient of a heat exchanger unit
operation.

However, by far the most common approach to consuming degrees of freedom is to assign specific values to variables (or
set variables to specific values). These assignments are referred to as specifications. Specifications have been provided, for
example, for the Cv of the valve for the simple valve model described above using the statement

Cv = 10 as spec;

The “as spec” qualifier declares the assignment as a specification.

Specifications can also be made through the views for the elements of a flowsheet model. Consequently, the specifications
provided within a UniSim EO 4GL model, as shown here for the simple valve model, are considered as default valves for the
specifications and are shown in red in the Parameters ply of the view for the model. Specifications made through the view for
an element of a flowsheet model are shown in blue. This colour convention helps the modeling engineering to know which
specifications have been made programmatically and which have been made manually.

The specification of the Cv for the simple valve model are shown in Figure: 2.1 . The specified value is shown in red indicating
that it is still at its default value, the value assigned within the UniSim EO 4GL model. However, if the specification is changed
for 10 to 5, say, the specified value becomes blue as shown in below figure.

1Mathematically, this means that every equation of the linearized model cannot be expressed as a linear combination of the
other linearized equations, that is, the equations of the linearized model must not be linearly dependent.

- 21 -
Chapter 2 - 4G Language

It is not always appropriate to include specification statements in a UniSim EO 4GL model. There are some artifacts
associated with this language feature. For example, when a specification statement is included in a UniSim EO 4GL model
and then the specification scenario is subsequently changed manually through the views, removing the specification made in
the 4GL code and specifying a different variable, when the UniSim EO 4GL model is reloaded, because, for example, the
code has been changed, the original specification embedded in the code is reapplied and a degree of freedom error results.
As a general rule, making specification through the views is safest and gives the most flexibility.

Figure: 2.3 Parameter Ply for the Simple Valve Unit Operation – Manually changed Specification

2.5 Process Streams


Inlet and outlet stream ports can be added to a model so that its element can be connected in the usual manner to other
elements. Inlet and outlet stream ports are declared using the “inlet” and “outlet” keywords.

Examples

inlet ProIn as Process; // Adds a port for a process inlet stream


// named “ProIn”
inlet AirIn as Process; // Adds a port for a process inlet stream
// named “AirIn”
outlet ProOut as Process; // Adds a port for a process outlet stream
// named “ProOut”

The “as Process” qualifier is not required; stream ports default to process stream ports so that

inlet ProIn;

is equivalent to

inlet ProIn as Process;

The auto-completion feature shows the variables and physical properties that can be referenced for a process stream.
These variables and physical properties have the internal engineering units of UniSim Design, strict SI. With reference to
process stream ProIn, these include

- 22 -
Chapter 2 - 4G Language

[Link] // deg K
[Link] // Pa
[Link] // kmole/s
[Link] // kg/s
[Link] // mole fraction
[Link][Vapour] // mole fraction
[Link][Liquid] // mole fraction
[Link][Liquid2] // mole fraction
[Link] // vector of length Compounds,
// mole fraction
[Link] // kg/kmole
[Link] // J/kmole
[Link] // J/kg
[Link] // J/kmole/degK
[Link] // J/kg/degK

There are also several auxiliary physical properties which are not initially shown by the auto-completion feature. However,
once they are entered manually the first time for a model, they are added to the auto-completion list. Again, with reference to
process stream ProIn, these include

[Link] // kmole/m3
[Link] // kg/m3
[Link] // m3/kmole
[Link] // J/kmole/degK
[Link] // J/kmole/degK
[Link] // W/m/degK

The variables and properties of a phase can be referenced using, for example

[Link][Vapour].MoleFractions // vector of length


// Compounds, mole fraction
[Link][Liquid].MoleFractions // vector of length
// Compounds, mole fraction
[Link][Liquid2].MoleFractions // vector of length
// Compounds, mole fraction
[Link][Liquid].ThermalConductivity // W/m/degK

There is an artifact associated with the thermal conductivity. There is no mixing rule for thermal conductivity so the thermal
conductivity for a mixed phase stream cannot be calculated. For a mixed phase stream,

[Link] = <empty>

However, the thermal conductivities for the phases can be referenced individually as shown above for the Liquid phase.

An inlet or outlet stream port can also be created for connecting Energy streams. Commonly, these are streams having a
single variable, typically, but not necessarily, related to energy flow. The variable of an energy stream can be “connected” to
a variable of the model using the “with” qualifier.

Example

outlet Power as Energy with shaftPower; // Adds a port for an energy


// outlet stream and connects
// the port with the
// shaftPower variable of the
// model

- 23 -
Chapter 2 - 4G Language

When an energy port is connected to a variable of the model, there is no need to explicitly write an equation that equates the
variable of the port to a variable in the model. So, for the above example, there is no need to set up the equation

[Link] = shaftPower;

More generally, the syntax allows declaring a port with multiple variables. For example,

outlet OutCustom as Custom(Power,Temp) with shaftPower, gasTemp;

creates a “Custom” outlet port, OutCustom, with two variables, Power and Temp, connected to the variables shaftPower
and gasTemp of the model. Note that the port type “Custom” can be any unique tag (although “Process” and “Energy” are
already reserved). The syntax “(tag) with variable” is optional. A tag is typically not provided when the port only has a single
variable, in which case the tag defaults to the type name – for example,

inlet EnergyIn as Energy with HeatFlow;

defaults to a tag of Energy for variable HeatFlow. The tags when mentioned must be unique. The tags (mentioned or
implied) will be matched with those of a connecting port at runtime. Hence, the inlet “Custom” port to which the above outlet
“Custom” port is to be connected must have two variables with tags Power and Temp. Similarly, the inlet “Energy” port to
which the above outlet “Energy” port is to be connected must have one variable with tag Energy (implied).

The “inlet” and “outlet” keywords can also be used to add a vector of inlet or outlet ports to a model.

Example

inlet FuelIn[2] as Process;

In this example, two fuel inlet stream ports are created. Since indexing is zero based, the fuel inlet ports would be referenced
as FuelIn[0] and FuelIn[1].

Using, for example,

inlet FuelIn[] as Process;

enables the modeling engineer creating a flowsheet model to add as many inlet stream ports as needed to the UniSim EO
4GL Unit Op. This construct is useful, for example, when creating a UniSim EO 4GL Unit Op with an indefinite number of
inlet streams that need to be mixed or a Unit Op that, like a stream splitter, has an indefinite number of outlet streams.

2.6 Embedded Objects


Embedded objects are instances of UniSim EO elements embedded within a UniSim EO 4GL model. For example,
embedding an instance of the fluid object in a model both gives access to UniSim Thermo physical properties within the
model and incorporates thermodynamic equilibrium into the [Link] objects are declared using the “object”
keyword.

The variables of the embedded object are referenced use the syntax

[Link]

Example

- 24 -
Chapter 2 - 4G Language

The model below calculates the saturation pressure of steam for a given temperature. An embedded fluid object (UniSim
EO OverallFluidPhase object type) is instantiated to perform the physical property and thermodynamic equilibrium
calculations.

// Saturation pressure of stream given the temperature

object Steam as OverallFluidPhase; // OverallFuidPhase is the UniSim


// EO object type for the fluid
// object
variable Temp; // temperature degF
variable SatP; // pressure psia

Temp = 624. as spec; // temperature at which the


// saturation pressure is to be
// calculated

// Set composition of the fluid object to pure water


[Excluding H2O] [Link] = 0.;
[Link][H2O] = 1;

// Set phase fraction of the fluid object to all vapour


[Link] = 1.;

// Set total flow of with the fluid object (just needs some value
// to satisfy the degree of freedom associated with the flow)
[Link] = 1.;

// Assign the specified temperature to the temperature variable of


// the fluid object; this variable has units of degK
[Link] = (Temp - 32.)/1.8 + 273.15;

// Calculate the saturation pressure in psia; the pressure variable


// of the fluid object has units of Pa
SatP = [Link] / 1000. / 101.325 * 14.696;

The variables and physical properties that can be referenced for the OverallFluidPhase object are the same as those
described above for process streams.

The conditions within an embedded object can be viewed by selecting the Elements page in the view for the element or, on
the General page of the by clicking on Parsed Model Summary / Elements, on the count (numeric value) or the “…” button.

FluidPhase types can be referenced without needing leading COMThermo in type name. Though it works with them, the
shorter syntax (without COMThermo) will be recognized correctly and do the same thing.

object SettleOutPhase as OverallFluidPhase;


object SettleOutPhase as COMThermoOverallFluidPhase;

Fluid phase’s RequiredPhases property enforces the listed phases to exist as a subset of the phases of the current fluid
basis. Typically, the required phases are those phases that are explicitly referenced in a model.

object soPhase as OverallFluidPhase;


[Link] = {"Vapour", "MixedLiquid", "Liquid"};"

Internal model working streams could be assigned directly from the ports using either :Fluid or directly aliasing the stream.
Directly aliasing with stream results in a trimmed syntax but does not require any logic change.

inlet Inlet as Process;


object workingFluid as OverallFluidPhase;
object workingFluidFromStream as OverallFluidPhase;

- 25 -
Chapter 2 - 4G Language

workingFluid = Inlet:Fluid;
workingFluidFromStream = Inlet;

2.7 Equations
Equations are most commonly written in the z =f (x, y,...) form. For example, referring again to the simple valve model, the
valve equation relating flow and pressure drop is commonly written as

[Name Valve Equation] [Link] = .024*Cv*@Sqrt(dP*Rho);

It is also possible, although not customary, to write the equation with expressions on both sides of the equal sign, so the valve
equation, above, can also be written as

[Name Valve Equation] .024*Cv*@Sqrt(dP*Rho) = [Link];

In general, the following equations forms are all valid.

constant c = 2;
variable x;
variable y;
variable z;
variable a;
variable b;
z = x + y;
x + y = z;
x + y = 5;
x + y = c;
x + y = a * b;

However, the left hand side of the equation cannot be a literal or constant or resolve to a literal or constant, so the following
equation forms are not valid.

5 = x + y;
c = x + y;
c + 5 = x + y;

Equations cannot not be written in residual form f(x,y,z,…) = 0. Currently the residual form is not explicitly supported, but all
equations are converted to this form internally.

Also, the auto-completion feature is only supported for the z = f(x,y,…) form. User can imply f(x) = 0 form by specifying z = 0
for the equation z = f(x).

Equations can be expressed in vector notation. When the same equation form applies for each element of a vector, a vector
equation can be used to express all of the equations in a single statement. In other words, vector notation for equations is
shorthand for writing groups of equations having the same structure as a single expression. Vector equations notation
makes UniSim EO 4GL models more compact and easier to understand. Vector equations also facilitate modeling of vectors
when the size is not known ahead of time or can change at runtime.

- 26 -
Chapter 2 - 4G Language

Vector operations, such as dot product and cross product are not supported. However, the unary mathematical operators for
addition (+), subtraction and negation (-), multiplication (*), division (/) and exponentiation (^) operate on vectors on an
element-by-element basis. For example, adding two vectors yields a vector which contains the sums of the corresponding
elements of the two [Link], the built-in mathematical functions of UniSim EO 4GL operate on a vector argument
on an element-by-element basis. For example, using @ln with a vector argument yields a vector whose elements are the
natural logarithms of the corresponding element of the argument vector. On typing @, the auto-completion feature shows the
list of available built in functions.

Given a vector argument, the @sum function sums the elements of a vector. This can be very useful, for example, in writing
an equation for calculating composition. The @sum function can be used together with the unary operator for multiplication to
calculate the dot product of two vectors by summing their element-by-element products.

Examples

Consider a flowsheet model in which fuel enters the flowsheet as a battery limit stream and the composition of the fuel is
provided by a laboratory analysis in mole percent. To satisfy this flowsheet modeling situation, the modeling engineer needs
to create a unit operation which can be used as a material source of fuel entering a UniSim EO flowsheet model. Since,
compositions in UniSim EO are maintained as mole fractions, the unit operation must convert the mole percent composition
from the laboratory analysis to a mole fraction composition. As a source of fuel, the unit operation needs to have an outlet
stream that can be connected to the downstream unit operation according to the process piping. The following UniSim EO
4GL model meets these requirements using vector equations where appropriate.

// Custom Fuel Material Source Unit Operation Model

outlet Fuel; // Allocate an outlet stream port for the fuel stream

// The following components must exist in the current fluid basis


// since they are specifically referenced in the fuel analysis
[RequiredComponents Methane, Ethane, Propane, Nitrogen, CO2]

[Classification Model Variables]


variable LabFuelGas[Compounds]; // Mole percent fuel composition
variable sumLabFuelGas; // Sum of the fuel component
// compositions (mole percent)

LabFuelGas = 0.0 as spec; // vector equation that sets


// the mole percent for each
// component to zero
// Lab analysis for the fuel components (mole percent)
LabFuelGas[Methane] = 9.558395907282831e+01 as spec;
LabFuelGas[Ethane] = 1.666277602004510e+00 as spec;
LabFuelGas[Propane] = 5.398479484332100e-01 as spec;
LabFuelGas[Nitrogen] = 1.718975454568860e+00 as spec;
LabFuelGas[CO2] = 4.996378436529390e-01 as spec;

// Calculate the fuel composition in mole fractions and assign


// this composition to the overall composition variables of the
// Fuel stream
sumLabFuelGas = @Sum(LabFuelGas); // Sum function sums the
// elements of the vector
// Vector equation for calculating the overall mole fraction of
// each component of the Fuel stream
[Link] = LabFuelGas / sumLabFuelGas;

The first vector equation in the above model,

LabFuelGas = 0.0 as spec;

sets the composition of all components in the fluid basis to zero as specifications. The subsequent five equations overwrite
the zero-value specifications for the fuel components with the laboratory analysis values individually as specifications.

The sum of the mole percent composition is calculated as

- 27 -
Chapter 2 - 4G Language

sumLabFuelGas = @Sum(LabFuelGas);

The Sum function sums over all the elements of the LabFuelGas vector.

The last equation of the model

[Link] = LabFuelGas / sumLabFuelGas;

is a vector equation that sets the overall mole fraction for each component of the Fuel stream to its lab analysis mole percent
normalized to one by dividing by the sum of the mole percent composition. It is interesting to note that the overall composition
of the Fuel stream will be normalized to one even when the lab analysis composition does not sum to 100%.

Consider another modeling situation in which the dry composition, that is the composition in the absence of water, is required
in a model. In the example below, the dry composition of the outlet stream, ProOut, of a UniSim EO 4GL model is calculated
using vector notation. Of course, water (H2O) must be a component in the current fluid basis and must be named as a
required component.

[RequiredComponents H2O]
outlet ProOut;
variable ProOutDryComp[Compounds]; // dry outlet composition
// The overall composition of the outlet stream will sum to one
// so the dry composition can be calculated by dividing the mole
// fraction for each component by one minus the mole fraction for
// water.
OneMinusH2O = 1. - [Link][H2O];
ProOutDryComp[H2O] = 0.;
[Excluding H2O] ProOutDryComp = [Link] / OneMinusH2O;

In the vector equation for calculating the dry mole fractions,

[Excluding H2O] ProOutDryComp = [Link] / OneMinusH2O;

the Excluding attribute excludes water (H2O) from the vector equation. That is, an equation is not set up for water. In general,
the Excluding attribute has the syntax

[Excluding ComponentName, ComponentName, …] vector equation;

Equations are not generated for the components listed by name after the Excluding attribute.

More generally, the Excluding attribute can be used with any vector variable that has offset names. The offsets cannot (at
least at present) be numeric expressions.

When the equation form does not match with standard equations form, the equation form is treated as expressions. User
could come to know about it by seeing the commit messages. For example, the below expression ‘y’ does not match to any
standard equation types. Hence it is tagged as expression. The advantage of having equation form expressed as standard
equations is that analytical derivatives are available which makes solution faster. Whereas expressions which does not
match to any of the standard equation form has to be numerically perturbed during the solution process which impedes
performance of the solver. Hence expressions should be avoided with preference to matching equations. Expressions are
marked with * in label when viewed in Equations section of the model.

variable x = 1 as spec;

- 28 -
Chapter 2 - 4G Language

variable y = x ^ 2 + 4 * x + 4;
variable z = x ^ 3;

In the above example, y expression is marked as * in the model’s Active Equations section.

Figure: 2.4 Element Custom-1

2.8 Model Constructs


Mathematical models can be written directly in the main method using keywords, logical constructs, sub-elements like user
defined data types, local functions etc. Reusable elements are usually isolated and would be written as part of a class
module or a local function.

Basic object oriented concepts like multilevel inheritance and late binding apply to 4GL class modules. Instances of the class
can be created directly using object keyword or from the type statements. Type statements are used to create list of entries
required for user to make a choice of the sub-model during the model configuration.

2.8.1 Class, Type and Object


A basic representative multilevel inheritance class design is made below. The creation of instance is illustrated using
approaches discussed above

Basic Approach

Object <instanceVar> as <ClassName>

From instance Type

Object <instanceVar> from <TypeName>

class BaseClass as base // "as base" means it can't be chosen


{
variable BaseVar;
};
class DerivedClass1 : BaseClass
{
BaseVar = 1.0;
};
class IntermediateClass1 as base : BaseClass
{
BaseVar = 2.0;
};
class DerivedClass2 : IntermediateClass1
{
}
type WhichDerivedClass as BaseClass = DerivedClass1;
object DerivedClass from WhichDerivedClass;
variable DerivedClassBaseVar = [Link];

object DerivedClass as DerivedClass2;

- 29 -
Chapter 2 - 4G Language

When condition can be used to check type instances using ‘is’ and ‘is not’ operator.

[when <TypeVar> [is, is not] <testType>] statement

[When WallStressCalculatorType is WallStressCalculatorOff]


HeadMaxWallTemperature = TopHeadMaxWallTemperature;
[When WallStressCalculatorType is not WallStressCalculatorOff]
HeadMaxWallTemperature = @Max(TopHeadMaxWallTemperature, BottomHeadMaxWallTemperature);

Type variable can be assigned during a specific solution scope to allow different initialization strategy.

[Solution Simultaneous] TypeVar = Type1;

2.8.2 if and ifswitch statement


Conditional constructs like @if and @ifswitch help to define the logics in the model. The syntax is as follows
variable = @if(Condition, True Statement, False Statement)

variable = @ifswitch(Condition, True Statement, Condition, True Statement, False


Statement)

variable Y = @if(A < 1, 1, @if(A > 100, 100, 50))

the above 4GL syntax would expand as below

if (A < 1) Y = 1;
else if (A > 100) Y = 100;
else Y = 50;

@IfSwitch is just a more compact form of nested @If functions. The above @if statement could be re- written using
@IfSwitch as follows

variable Y1 = @ifswitch(A < 1, 1, A > 100, 100, 50)

The else clause is optional while using @ifSwitch which is not the case with @if

variable Y3 = @ifswitch(A < 1, 1, A > 100, 100)

Ensure to use all the variables consistently throughout the condition in @if or @ifSwitch statement. In the above
expression, A is the variable in condition statement. If one uses additional variable B as part of condition, then rest all
conditions should have both the variables in it.

NOTE
@if and @ifswitch may cause discontinuity if it depends on a calculated variable and can cause solver reliability
issues. Users are suggested to formulate models that would have continuous derivatives and avoid using @if type
statements unless it’s based on input variable or if there is no alternative formulation for calculated variables.

- 30 -
Chapter 2 - 4G Language

2.8.3 Usage of When and If statements


‘When’ should only be used for logic involving specification variables (or even calculated variable which depends only on
specifiable variables and not on iteration variables). Otherwise it results in equations being swapped during iterations, which
resets the solver. Switching equations in/out can lead to cycling and make it difficult to diagnose. Consequently models
equation structural change should only be made in between the solutions steps and not during the iterations.

When preserves the equation form as it is. @If treats the statement as an expression.

2.8.4 Local Functions


Local functions can be declared anywhere in a UniSim EO 4GL model and then used just like a built in function within the
same model. Commonly used local functions can be shared through include files.

Local functions must have a fixed set of zero or more scalar arguments. Vector variables cannot be used as arguments to
local functions. The function result must also be a scalar quantity.

Variables declared within a function become visible after declaration. Expressions declared in the function are executed
sequentially in order of declaration as in any procedural language such as FORTRAN or C/C++.

The calculated result must be assigned to the keyword Result as the last statement of the local function.

Example

function HeatXferCoefSP(Cp,Mu,k,Flux,Di)
// Single Phase Heat Transfer Coefficient for Flow in a Pipe
// Cp – specific heat capacity
// Mu – viscosity
// k - thermal conductivity
// Flux – flow flux
// Di - inside pipe diameter
{
Variable Nu; // Nusselt Number
variable Pr; // Prandtl Number
variable Re; // Reynolds Number

// The coefficients of the correlation below have been


// changed to protect the innocent
Pr = Mu * Cp / k;
Re = Flux * Di / Mu;
Nu = @exp(-4 + 0.8 * @ln(Re) + 0.5 * ln(Pr) –
0.02 * (@ln(Pr))^2);
Result = Nu * k / Di
}

This local function can be used in the UniSim EO 4GL model by referencing it in the same way as internal functions. That is,

variable HTC;
HTC = @HeatXferCoefSP(Cp,Mu,k,Flux,Di);

wherein Cp, Mu, k, Flux, Di and HTC have been declared as variables in the UniSim EO 4GL model and equations have
been provided to calculate Cp, Mu, k, Flux, and Di or they have been specified.

From a solution perspective, local functions are treated in the same way as internal functions with the exception that for
simultaneous solution the partial derivatives of the function with respect to its arguments are determined by numerical
perturbation. Users are suggested to avoid models with expressions that require numerical perturbation. Check Keywords
and Attributes

Details of some Keywords and Attributes are linked to detailed sections. User can traverse them using hyperlinks provided.

- 31 -
Chapter 2 - 4G Language

Generic keywords Description / Example

constant Declares scalar real constant


constant EXPN = 2.718281828;

variable Declares scalar or vector real property

variable InletHeatFlow;

variable Array[3];

parameter Identical to variable but implicitly adds [Classification Parameter]

parameter Cv = 10 as spec;

object Declares scalar or vector sub-element property

object Tank as TankElement;


object Mixers[2] as MixerElement;

type Declares scalar or vector type property

type EqnType as SimulationEqnType;

string Declares a scalar or vector string property


string Tag = "Hi there";

string Tags[] = { "Hello", "Pressure" };

include Includes another file of constants, declarations or classes

include "[Link]";

function Defines a local function

Class, Type and Object Defines a local class (another custom element) that can be instantiated via object keyword

Connect Connects object properties between objects in vector and at boundaries

import Imports a function or subroutine from an external FORTRAN or C module import


"[Link], foofunc" as FORTRAN function Foo;

Element Keywords Description / Example

inlet Declares a scalar or vector inlet port

inlet Inlet;
inlet Inlets[];

outlet Declares a scalar or vector outlet port

outlet Outlet;

outlet Outlets[2];

warning Declares a warning status message to be displayed in model’s status bar when a condition is
met

warning "Heat too low" when HeatFlow < 0;

- 32 -
Chapter 2 - 4G Language

Generic keywords Description / Example

The element’s icon and status bar color would get changed to yellow.

error Declares an error status message to be displayed in model’s status bar when condition is met
error "Heat too high" when HeatFlow > 0;

The element’s icon and status bar color would get changed to red.

Attribute Description / Example

Classification Sets classification for variable declarations for grouping of variables [Classification
Inputs]

variable InletPressure as Pressure;

Solution Designates expressions or equations in a solution scope for a specific solution type i.e.
simultaneous, sequential or direct.

[Solution Simultaneous]

… a solution scope with all equations here only being activated for a simultaneous solution
[Solution Any]

[Solution Sequential]

… a solution scope with all equations here only being activated for a sequential solution
[Solution Any]

[Solution Dynamic]

… a solution scope with all equations here only being activated for a dynamic solution

[Solution Any]

[Solution Direct] scope expressions will be calculated if needed (shown on a view,


exported to the spreadsheet, etc.) and on demand. Their result will be recalculated whenever
any of their inputs change. As expressions, they only calculate their left-hand-side from their
right-hand-side. Variables calculated as Solution Direct should not be used in non-Direct
expressions or equations as the Solution Direct calculations are not considered part of the
solution so no derivative information will be captured. Typically these should be used for post
calculations, such as aggregate information the user might want to see on a “Results” view.

To counter any solution types, place Solution Any

A directly assigned value will no longer be treated as model calculation if placed within a
solution scope (instead an equality equation is used). To reduce confusion, values "as spec"
or "as initial" will generate an error when inside a solution scope.

SolveSimultaneous When the solver is Sequential, designates expressions or equations that should be solved
together as a block of simultaneous equations in an internal simultaneous solver. For all other
solvers, the equations are added to the solver as they would be without the attribute present. If
used within a class, each instance of the class will have its own block of simultaneous
equations and its own internal simultaneous solver.

variable a = 1 as spec;
[SolveSimultaneous] variable b = 1 as initial;

- 33 -
Chapter 2 - 4G Language

Generic keywords Description / Example

[SolveSimultaneous] variable c = 1 as initial;

[SolveSimultaneous] a*a = b*b + c*c;


[SolveSimultaneous] b = c;

Allows equations that cannot be solved sequentially to be solved in sequential mode. Care
must be taken to initialize all variables using the “as initial” syntax, also with a preceding
SolveSimultaneous attribute.

Expressions or equations marked as SolveSimultaneous can still be scoped with solution


scoping to change out the equations depending on the solver. SolveSimultaneous cannot be
combined with [Solution Direct].

This technique should be used sparingly and as narrowly as possible as it adds significant
performance overhead.

Name Specifies the given name to an expression or an equation. Defaults to form of the expression
or equation, if not provided.

[Name Pressure Drop]


dP = [Link] - [Link];

If the [Name Pressure Drop] is not specified, its own form, “dP = [Link]
- [Link]”, will be given as the name of the equation by default

Description Sets a description for a local class

[Description API 520 HDI Method]


class Rigorous2PhaseHDE

Typically the descriptions would appear in type selection view as shown below

type PressureFlowModel as BasePressureFlowModel =


Rigorous2PhaseHDE;

SortingKey Sorts the class descriptors in a list of types displayed to user.

[SortingKey 1]
[Description User Specified dP]

- 34 -
Chapter 2 - 4G Language

Generic keywords Description / Example

class SpecifiedValvePressureDrop : ValvePressureDrop


{
};

[SortingKey 2]
[Description Simple Resistance]
class ResistanceValvePressureDrop : ValvePressureDrop
{
};

[SortingKey 3]
[Description ANSI/ISA75.01]
class ANSIISAValvePressureDrop : ValvePressureDrop
{
};

Usage of When and If Designates an equation which follows “when” as active only when the type variable is of given
statements type or conditional expression is satisfied. The “when” attribute can also be used to
conditionally assign a value to an integer or type variable.

EmptyDisplayText Text shown on view, report etc. when variable value is empty

[EmptyDisplayText SteadyState]
variable AmbientTemperature as Temperature;

AllowAliasOverride Aliases could be used to link the data in a parent object with its child or between its own
synonym variables. Aliases allows us to easily influence behavior while maintaining sensible
interfaces to both the parent and child. Aliases can be used to link variables between
referencing objects as well, not only parent/child objects.

Alias can be temporarily superseded by user entered value. Deleting the user
entered values restores alias.

variable x = 2 as spec;
[AllowAliasOverride] variable m = x;
variable n = m ^ 2;

As variable m is aliased to variable x, on changing x, m value changes automatically.


AllowAliasOverride attribute on the variable m allows it to be over written i.e. m temporarily
delinks its alias with x, when user specifies value to it. Without this attribute, both x and m will
be marked as specifiable variable. Deletion of user specification in m would restore its alias
with x again.

FixedAlias Alias is fixed and cannot be modified by user.

- 35 -
Chapter 2 - 4G Language

Generic keywords Description / Example

variable x = 2 as spec;
[FixedAlias] variable m = x;
variable n = m ^ 2;

Unlike AllowAliasOverride, FixedAlias establishes strong link with its aliased


variable which cannot be modified.

ModelAttribute Adds a custom model attribute to the current model type. It could be attributed to the main
model or to the sub-elements which the main model is referring.
[ModelAttribute AllowUnsolvedEquations]

Ignores "Not Solved" equations for the overall model status


[ModelAttribute AllowRedundantEquations]

Ignores "Redundant" equations

Publish Starts or ends a published section of a model

If a model has a “LicenseToDesign” element attribute keyword configured and the license is
missing, then the Model page (and the model preview on the ModelUpgrade view) will show
only the published notes and not the model’s 4GL code.

[Publish Notes]

// Steady state model of a ...

[Publish None]

The above sequence makes "Steady state model of a …" appear on license locked views of
model. Multiple [Publish Notes] sections can be added and can include any part of model
(including equations). The sections chosen for publishing will remain active in the model. On a
license locked model, each published section will be appear appended in order of occurrence.

Replace Replaces one variable with another when upgrading to a new model. For example, if user has
initially developed a tank model using a single inlet port “Inlet” and wishes to upgrade to
multiple inlet ports, to retain the existing model definitions, user can use

Replace attribute. Replace Inlet with Inlets(0)

Required Highlights the cell in yellow color to indicate the variable is a nominal specification.

Shortcut syntax for

[Classification Required]
variable InletPressure as Pressure;
[Classification None]

[required]variable InletPressure as Pressure;

Do not specify “required” for outlet variables. Typically to apply “required” attribute to the
variables, assume your model as simulation model which on specifying inlets and model
parameters calculates outlet.

- 36 -
Chapter 2 - 4G Language

Generic keywords Description / Example

RequiredVariables Base class variables which are required in the derived class should be stated with
RequiredVariables in the derived class scope. This is in addition to those declared as
“required” in derived class’s own scope.

class BaseWallStress as Base


{
variable Temperatures[3+] as Temperature;
variable Data[Temperatures] as Pressure;
}

class WallStress : BaseWallStress


{
[required] variable InternalDiameter as Length;
[RequiredVariables Temperatures,Data]
Strength = @NaturalCubicSpline({100, Temperatures, Data});

RequiredComponents Enforces the listed (comma delimited) compounds (components) to exist as a sub-set of the
current fluid basis.

Typically, the required compounds are those compounds that are explicitly
referenced in a model.

[RequiredComponents Methane,Ethane,Propane]

Excluding Excludes listed (comma delimited) entries from being active in the next vector equation.
[Excluding H2O] [Link] = 0.0;

[Link][H2O] = 1.0;

Internal Excludes property from default Parameters view.

Shortcut syntax for

[Classification Internal]
variable TemporaryValue;
[Classification None]

[internal] variable TemporaryVariable;

This shortcut syntax restores original classification for following declaration.

Element Attributes Description / Example

SupportsType Defines current element type as supporting an abstract type for purposes of grouping in
Available Elements palette.
[SupportsType ElectricalNetworkEquipmentType]

- 37 -
Chapter 2 - 4G Language

Generic keywords Description / Example

LicenseToCreate Defines a license that is required before an instance of element can be created.

[LicenseToCreate [Link]]

LicenseToDesign Defines a license that is required before element's design view (i.e. Editor etc.) can be viewed
[LicenseToDesign [Link]]

DefaultNameFormat Sets a default format for naming instances in the PFD of this model.

[DefaultNameFormat Valve-100]

Further created instances of the same element type would be incrementally named as Valve-
101, Valve-102 etc.

Shortcut Sets an equivalent shortcut tag for a lengthy moniker.

A Shortcut is much like a macro. It can only be used as a replacement syntax at the beginning
of a path. When a shortcut is used in a model, it just serves to simplify and/or document
purpose.

[Shortcut diameter=[Link]]
relRoughness = roughness / diameter;

[Shortcut ConnectionFluids=InletFluids,SettleOutPhase]

External Specific to object shortcuts but otherwise identical to Shortcut (see above).

With External, the shortcut name becomes a clickable link within the 4GL code. Clicking on the
link will open a view of the external object.

When user drags and drops a variable onto 4GL code, an External shortcut for the owning
object will automatically be inserted at the top of 4GL code. For example, if user drops a Pump
Outlet Pressure on end of this line:

- 38 -
Chapter 2 - 4G Language

Generic keywords Description / Example

variable PumpPressure as Pressure =

Then the following will be added:


[External P100 = [Link][P-100]]

variable PumpPressure as Pressure = [Link];

Note that dragging and dropping a variable is not required. User can manually type in their own
External attribute as/when necessary.

Connection Tags Description / Example

ConnectionFluids ConnectionFluids is a vector that can be used generically in views regardless of model
because it's defined differently per model (also implied via process ports when not mentioned
explicitly).
[Shortcut ConnectionFluids=InletFluids,SettleOutPhase]

For example, SettleOut is a blow down vessel utility calculator used to determine the initial
pressure by thermodynamically mixing multiple inlet material streams. Being a utility, it gets the
inlet fluid information through ConnectionFluids and its calculated output is set to
SettleOutPhase which is again accessed by blow down vessel at the main level.

ConnectionWires Similar to ConnectionFluids for Electrical operations.


[Shortcut ConnectionWires=InletWires,OutletWires]

FORTRAN and C/C++ Subroutines and Functions for detailed steps on creating local function in procedural language such
as FORTRAN or C/C++ and linking them in 4GL code.

2.9 Auto-Completion Feature


When typing a statement, the valid entries for each element of the statement are presented in a popup list when the first
character is typed as shown below. Auto-Completion List of Variables for Inlet and Outlet Process Stream Ports. As a
statement element is entered, the popup list is refined as each character is typed. An entry can be auto-completed by
selecting it from the popup list – scroll through the list using the down/up arrow keys to the desired entry and then hit the tab
key or click on the desired entry with the mouse.

- 39 -
Chapter 2 - 4G Language

Figure: 2.5 Auto-Completion List of Variables for Inlet and Outlet Process Stream Ports

As a general rule, all UniSim EO 4GL language elements (keywords, constant names, variable names, function and
subroutine names, etc.) are not case sensitive. The auto-completion feature uses the case in common use.

2.10 Drag and Drop to reference variables in 4GL


Users can drag variables from other object views and drop them into 4GL code. This can be convenient when configuring a
4GL model to do the equivalent of a USD spreadsheet. After dropping a variable, an External attribute will automatically be
added for the external object at top of 4GL and the path to dragged variable will be inserted where the user dropped the
variable. To see an example, look at the External attribute definition in the Keywords and Attributes Appendix.

- 40 -
CHAPTER

3 4G VIEW

Defaults model views are automatically created for a model without any extra work from the user. However, if the user wants
to make custom views and give a more professional look to the model forms, there is a way to add these views.

The 4G view development comprises three phases

l Parameter / Configuration view development


l Results view development
l PFD Icon development

All the view developments are possible for users who have valid license configured under “LicenseToDesign” element
attribute keyword.

3.1 Parameter and Results View


For both parameter and result view, the development process is the same.

In the Design page of the model, click “Use custom parameters view”. It would list “Parameters” in the “Custom Views” list
below.

Users need to either start with “Edit View…” or “Edit as Text…”. It is suggested to start the view development using “Edit
View…”. Once user gains good understanding of the xml view elements, then they can use “Edit as Text…” directly. Let us
assume user has clicked “Edit View”.

Figure: 3.1 Example of Custom Element Design page

To enter view design mode, Select Parameters from list of views and press the “Edit View” button.

- 41 -
Chapter 3 - 4G View

A default matrix view element would be available with model parameters grouped according to the classification. To create
new information, user can click insert button or use mouse which would open appropriate data set properties. Configure
necessary view parameters. Key portion is the choice of variables in the moniker section. Auto-completion feature is
available to fill in the monikers. Note the monikers could also refer to owners variable. In such case, ensure to use proper
levels along with “owner” keyword.

Figure: 3.2 Adding a Dataset to Parameters Matrix

The developed view could be limited to only few variables. At any point of time developer can see all the model variables by
right clicking the Parameter view and choosing “All Properties”.

3.2 PFD Icon Development


In the Design page of the model, click “Use custom icon on PFD”

PFD Icon is developed using basic shapes. Icon development involves developing the body view and inlet/s and outlet/s port
section. Typical icon of a valve unit operation is provided in the below figure.

- 42 -
Chapter 3 - 4G View

Figure: 3.3 Example PFD Icon definition - for Valve Unit Operation

Different element types which are available for PFD icon development are

Element Parameters and example

Line StartX, StartY, EndX, EndY

<LineElement startX="6" startY="44" endX="14" endY="36">

Rectangle X, Y, Width, Height, CornerRadius, Gradient

<RectangleElement x="0" y="0" width="20" height="80" cornerRadius="5" gradient="vertical">

Polygon PathX, PathY, style, Gradient

<PolygonElement x="0" y="20" points="10,10 20,0 30,10 40,0" style="open">

Ellipse CentreX, CentreY, RadiusX, RadiusY

<EllipseElement centreX="10" centreY="20" radiusX="6" radiusY="6">

Arc CentreX, CentreY, RadiusX, RadiusY, StartAngle, EndAngle, Style

<ArcElement centreX="43" centreY="30" radiusX="13" radiusY="13"


startAngle="180" endAngle="0" style="Open">

The above types can be used with different attributes as follows

- 43 -
Chapter 3 - 4G View

1. Line Attribute
2. Fill Attributes

Attribut
Example
e

Line
<LineElement startX="6" startY="44" endX="14" endY="36">
<Attributes value="[Link][PFDBorderLine]"/>
</LineElement >
<EllipseElement centreX="10" centreY="60" radiusX="6" radiusY="6">
<Attributes value="[Link][PFDBorderLine]"/>
</EllipseElement>

Fill
<RectangleElement x="0" y="20" width="40" height="10" style="open">
<Attributes value="[Link][RedFill]"/>
</RectangleElement>
<ArcElement
centreX
="20" centreY="10" radiusX="20" radiusY="10" startAngle="0" endAngle="180" style="closed">
<Attributes aliasOf="[Link]"/>
</ArcElement>
<PrimaryFill value="[Link][PFDGradientGreyFill]"/>

The PFDGradientGreyFill is the standard fill choice - referenced via:


<Attributes aliasOf="[Link]"/>

Using primary fill ensures model status will be automatically reflected on PFD icon. Other fill attributes should be referenced
via:

<Attributes value="[Link][name]"/>

Where name can be any of the following:

l GreyFill
l BlueFill
l BlueGradientFill
l RedFill
l RedGradientFill
l YellowFill
l YellowGradientFill
l CyanGradientFill
l GreenFill
l GreenGradientFill
l BlackFill

Likewise, attributes for lines can be referenced via:

<Attributes value="[Link][name]"/>

Where name can be any of the following:

- 44 -
Chapter 3 - 4G View

l PFDBorderLine
l PFDThickBorderLine

While developing icons, typical user would use a pixel graded graph sheet in designing.

For defining ports, use the following tag and attributes and associate proper port moniker.

<PFDPortProperties x="0" y="40" moniker="Inlet"/>


<PFDPortProperties x="17" y="100" moniker="Reflux"/>

- 45 -
CHAPTER

4 SOLVING A UNISIM EO FLOWSHEET MODEL

The Parameters page of the view for the UniSim EO sub-flowsheet object of the UniSim Design main PFD shows and gives
the modeling engineer access to select the solver type to be used – Sequential, Simultaneous or Optimization.

When the Sequential solver type is selected, the modeling equations for the flowsheet are solved sequentially, iteratively if
there are convergence units like recycles and adjusts, until convergence is achieved.

When the Simultaneous solver type is selected, the modeling equations for the flowsheet are solved simultaneously using a
nonlinear equation solver. This is the recommend solver type for most simulation and design problems and is discussed
further below.

The Optimization solver type is selected when working with optimization problems, including data reconciliation and
parameter estimation which is used to calibrate a model to process operating conditions.

4.1 Simultaneous Solver


When the Simultaneous solver type is selected, the Parameters page of the view for the UniSim EO sub- flowsheet also
shows the degrees-of-freedom (DoF) for the flowsheet model and the specific nonlinear equation solver that has been
selected – Internal, NOVA NLA, or NOVA. The NOVA NLA solver is recommended for simulation and design problems.

The Simultaneous Solver can be in either Automatic or Manual mode. If in Automatic mode, the solver will run whenever the
sub-flowsheet becomes square (DoF=0). It will also re-solve automatically when inputs change after it is already solved. If in
Manual mode, the “Run” button will be enabled when the sub-flowsheet is ready to be solved. It will also re-solve
automatically if a connected stream changes once the sub-flowsheet has already been solved (similar to the Column Unit
Operation).

4.1.1 Initialization
Initialization of the solution vector for the flowsheet model is a critical aspect to achieving reliable, robust simultaneous
solution.

[Link] Sequential Solution of the Modeling Equations

When the Simultaneous solver type is selected, UniSim EO initializes the variables vector by performing a sequential solution
of the modeling equations for any yet to be solved elements in the flowsheet. For some units this may be with loosened
tolerances. However, this initialization may not be complete because the values for some variables on the right-hand-side of
an equation may not be known, that is may not be able to be calculated, before they are needed to calculate the variable on
the left-hand-side of the equation. The variables that cannot be calculated before they are needed are the tear variables for
sequential solution.

The tear variables for a unit operation model, and specifically a UniSim EO 4GL model, can be identified by forming the
incidence matrix for the model and rearranging the rows (corresponding to the equations) and the columns (corresponding to
the variables) so that the variable to be solved by each equation becomes the diagonal element. A variable for which there
are non-zero elements above the diagonal following this rearrangement is a tear variable. There is no unique set of tear
variables.

However, it is desirable to choose a rearrangement of the incident matrix that minimizes the number of tear variables.

- 46 -
Chapter 4 - Solving a UniSim EO Flowsheet Model

NOTE
It should be noted that the tear variables are specific to the specifications that are being made for the unit operation
model. The unit operation model will have different tear variables for different specification scenarios.

Initial values must be provided for the tear variables to enable the once through sequential calculation of the modeling
equations to generate a consistent initial guess. Initial values for a UniSim EO 4GL model can be provided explicitly for use
by the simultaneous solver using initialization statements of the form

variableName = value as initial;

Initial values can be provided for any variables. They will only be used in the sequential initialization, if not able to calculate
the variable.

Consider the very small system of equations below to be solved sequentially.

Equation (4-1)

In this system of equations, x2 cannot be solved without knowing x3 and x3 cannot be solved without knowing x2. Therefore
one of x3 or x3 needs to be torn. This system of equations would be built in a UniSim EO 4GL models for sequential solution
as follows.

variable x1;
variable x2;
variable x3;
variable x2Tear;
x1 = 100 as spec;
x2 = x3 / 2;
x3 = x1 + x2Tear;
x2Tear = 1 as tear of x2;

As noted above, the sequential solution to generate an initial guess is only used for yet to be solved unit operations of the
flowsheet. For those unit operations that have already been solved, the previous solution values are used as the initial guess.
So, when building a flowsheet model by incrementally adding unit operations to the flowsheet, which is the usual case, the
sequential solution to generate an initial guess is only applied to those unit operations that have been added since the last
simultaneous solution of the flowsheet.

[Link] Sequential Specification Strategy

Not all specification scenarios are equal with respect to ease of simultaneous solution. So, even when an initial guess is
generated as described above, solution of the flowsheet remains (more) difficult for some specification scenarios. The
sequential specification strategy can help to achieve more reliable solution behaviour in these cases.

Suppose, for example, that the flow in the shell side of a heat exchanger is to be calculated to achieve a specified tube outlet
temperature. That is, the tube stream outlet temperature is to be specified and the shell inlet stream flow is to be calculated.
This is a more difficult specification scenario than specifying the shell inlet stream flow and calculating the tube stream outlet
temperature.

Using the sequential specification strategy, an easier to solve specification scenario is solved first to generate a good initial
guess for a more difficult to solve specification scenario. So, for the example described above, first specify the shell inlet
stream flow and manually try different values until a tube outlet stream temperature reasonably close to the target value is
calculated. Then remove the specification on the shell inlet stream flow, replace it with the desired specification on the tube
outlet stream temperature and solve the model.

- 47 -
Chapter 4 - Solving a UniSim EO Flowsheet Model

4.2 Sequential Solver


The sequential solver stacks the modeling equations and solves them sequentially, much like the sequential solver in UniSim
Design. As in UniSim Design, there is an Adjust unit operation to accommodate nonlocal specifications. @Adjust() function
in the 4GL to facilitate iterations internal to the model. See below for an example of using @Adjust

variable idealMoleFlow = moleFlux * area;


variable InFlow as MolarFlow = 0.95 * idealMoleFlow;
variable outPGuess as Pressure = 0.9 * [Link];
InFlow = @Adjust([Link], [Link], outPGuess);

Recycles can be added to the flowsheet by right-clicking on the stream icon and choosing “Add Recycle Transition”.

Within UniSim EO 4GL models, tear variables and corresponding equations can be defined using the syntax shown in the
example above. The Wegstein algorithm is used to update the tear variable at each iteration until the original variable is
within tolerance of the tear variable.

4.3 Dynamic Solver


The dynamic solver solves the differential equation using Backward Euler Integration strategy. Set of N first order ordinary
differential equations (ODE’s) in N variables

Equation (4-2)

with conditions given on all the N variables of initial time t, say at

Equation (4-3)

can be modelled using a variable context “as derivative of”.

For example, a system’s temperature derivative with respect to time can be obtained or assigned using the following syntax
variable T as Temperature;

variable dTdt as derivative of T;

Also to ignore default initialization, dynamic initialization of the variables at time zero could be done explicitly using “initialized
from <InitializationVariable> and then specifying

< InitializationVariable>:DynInitial.
variable h as MassEnthalpy;

variable dhdt[2] as derivative of h initialized from T;

[Solution Direct]

T:DynInitial = 25;
[Solution any]

Developers can also state initial values for the implicit ODE variable which could help in better convergence as below
variable h as MassEnthalpy = 4500 as initial;

variable dhdt[2] as derivative of h initialized from T;

[Solution Direct]
T:DynInitial = 25;

- 48 -
Chapter 4 - Solving a UniSim EO Flowsheet Model

[Solution any]

The dynamic integrator's time variable can be accessed by declaring a local variable called "time".

variable time;

variable omegat = 2 * time;


variable y = @sin(omegat);

“Dynamic Initial Condition" classification is available to all Dynamic Initial variables so they group together on Parameters
view page.

Figure: 4.1 Dynamic Initial Conditions

4.4 Tips to build a robust model


1. Run the Unit Operation in sequential solver with fully specified inlets. If all outlets are solved, the status on the model
page will go Green OK. If not, tear variables, @Adjust functions or [Solution Sequential] logic should be used to
make the sequential model solve fully. If [Solution Sequential] is used, a paired [Solution Simultaneous] needs to
provide the Simultaneous version of the equation using the same total set of variables. In case of issues, follow the
troubleshooting steps below,
a. If the model says “Not Solved” then it means it is not fully specified. Go through the Parameters page
looking for un-solved values. Also, right-click on the Sequential Engine’s title bar and choose “All
Properties”. Go to the “Unsolved Active Equations” page and it will show you which equations didn’t
converge.
b. If the model says “Inconsistent” then it means there is at least one equation that is numerically inconsistent.
Go to the “Inconsistent Active Equations” page on the Sequential Engine to find them.
c. If the model says “Redundant” then it means that the equations are numerically consistent but that there
are equations that doesn’t calculate any variables. Go to the “Redundant Active Equations” page on the
Sequential Engine to find them.

2. Prepare for simultaneous solution:


a. Ensure variables are declared with numerical types (using: variable <varName> as
<numericalTypeName>) on every variable that can be bounded.
b. Break up the equations into recognizable equation forms. Leaving equations unresolved as expressions
could have an impact on execution efficiency and could limit the types of initialization that can be done by
sequential mode.
c. Add initial values for variables that will not be calculated in sequential (using: variable <varName> =
<initialValue> as initial).
d. Run in sequential again with fully specified inlets to ensure it still works.

- 49 -
Chapter 4 - Solving a UniSim EO Flowsheet Model

3. Run the unit operation in simultaneous solver. Do this by selecting the Simultaneous Engine and the Custom
Element along with any other connected elements (such as FluidNodes) and then pressing “Model with Engine” or
via right-click on the PFD item. Assuming you came from a converged Sequential solution, it should converge
immediately. Test a range of variable values and tune new equation forms for reliability. In case of issues, follow the
troubleshooting steps below,
a. Start with small (+10%) changes to the values and solve. It should solve with a small number of iterations
(1-3). If not, then look for non-linear equations in your system and try changing their form to scale better or
be less non-linear. One can also gain better insight after looking into the set of variables and equations
under “View Problem” -> Active or Equations. Or “View Solver” -> Display Progress
b. Make a large change (+100%) for the specification variables and watch for numerical errors. These
generally indicate that your numerical types are not correct. Make sure that variables are bounded such
that bad math does not occur (for example – log of 0, sqrt of –ve).

- 50 -
CHAPTER

5 REFERENCES

Example.4gl is an illustration file which explains most of the key features stated in the document.

- 51 -
CHAPTER

6 APPENDIX

6.1 Keywords and Attributes


Details of some Keywords and Attributes are linked to detailed sections. User can traverse them using hyperlinks provided.

Generic keywords Description / Example

constant Declares scalar real constant


constant EXPN = 2.718281828;

variable Declares scalar or vector real property

variable InletHeatFlow;

variable Array[3];

parameter Identical to variable but implicitly adds [Classification Parameter]

parameter Cv = 10 as spec;

object Declares scalar or vector sub-element property

object Tank as TankElement;


object Mixers[2] as MixerElement;

type Declares scalar or vector type property

type EqnType as SimulationEqnType;

string Declares a scalar or vector string property


string Tag = "Hi there";

string Tags[] = { "Hello", "Pressure" };

include Includes another file of constants, declarations or classes

include "[Link]";

function Defines a local function

Class, Type and Object Defines a local class (another custom element) that can be instantiated via object keyword

Connect Connects object properties between objects in vector and at boundaries

import Imports a function or subroutine from an external FORTRAN or C module import


"[Link], foofunc" as FORTRAN function Foo;

Element Keywords Description / Example

- 52 -
Chapter 6 - Appendix

Generic keywords Description / Example

inlet Declares a scalar or vector inlet port

inlet Inlet;
inlet Inlets[];

outlet Declares a scalar or vector outlet port

outlet Outlet;

outlet Outlets[2];

warning Declares a warning status message to be displayed in model’s status bar when a condition is
met

warning "Heat too low" when HeatFlow < 0;

The element’s icon and status bar color would get changed to yellow.

error Declares an error status message to be displayed in model’s status bar when condition is met
error "Heat too high" when HeatFlow > 0;

The element’s icon and status bar color would get changed to red.

Attribute Description / Example

Classification Sets classification for variable declarations for grouping of variables [Classification
Inputs]

variable InletPressure as Pressure;

Solution Designates expressions or equations in a solution scope for a specific solution type i.e.
simultaneous, sequential or direct.

[Solution Simultaneous]

… a solution scope with all equations here only being activated for a simultaneous solution
[Solution Any]

[Solution Sequential]

… a solution scope with all equations here only being activated for a sequential solution
[Solution Any]

[Solution Dynamic]

… a solution scope with all equations here only being activated for a dynamic solution

[Solution Any]

[Solution Direct] scope expressions will be calculated if needed (shown on a view,


exported to the spreadsheet, etc.) and on demand. Their result will be recalculated whenever
any of their inputs change. As expressions, they only calculate their left-hand-side from their
right-hand-side. Variables calculated as Solution Direct should not be used in non-Direct
expressions or equations as the Solution Direct calculations are not considered part of the
solution so no derivative information will be captured. Typically these should be used for post
calculations, such as aggregate information the user might want to see on a “Results” view.

- 53 -
Chapter 6 - Appendix

Generic keywords Description / Example

To counter any solution types, place Solution Any

A directly assigned value will no longer be treated as model calculation if placed within a
solution scope (instead an equality equation is used). To reduce confusion, values "as spec"
or "as initial" will generate an error when inside a solution scope.

SolveSimultaneous When the solver is Sequential, designates expressions or equations that should be solved
together as a block of simultaneous equations in an internal simultaneous solver. For all other
solvers, the equations are added to the solver as they would be without the attribute present. If
used within a class, each instance of the class will have its own block of simultaneous
equations and its own internal simultaneous solver.

variable a = 1 as spec;
[SolveSimultaneous] variable b = 1 as initial;
[SolveSimultaneous] variable c = 1 as initial;

[SolveSimultaneous] a*a = b*b + c*c;


[SolveSimultaneous] b = c;

Allows equations that cannot be solved sequentially to be solved in sequential mode. Care
must be taken to initialize all variables using the “as initial” syntax, also with a preceding
SolveSimultaneous attribute.

Expressions or equations marked as SolveSimultaneous can still be scoped with solution


scoping to change out the equations depending on the solver. SolveSimultaneous cannot be
combined with [Solution Direct].

This technique should be used sparingly and as narrowly as possible as it adds significant
performance overhead.

Name Specifies the given name to an expression or an equation. Defaults to form of the expression or
equation, if not provided.

[Name Pressure Drop]


dP = [Link] - [Link];

If the [Name Pressure Drop] is not specified, its own form, “dP = [Link]
- [Link]”, will be given as the name of the equation by default

Description Sets a description for a local class

[Description API 520 HDI Method]


class Rigorous2PhaseHDE

Typically the descriptions would appear in type selection view as shown below

- 54 -
Chapter 6 - Appendix

Generic keywords Description / Example

type PressureFlowModel as BasePressureFlowModel =


Rigorous2PhaseHDE;

SortingKey Sorts the class descriptors in a list of types displayed to user.

[SortingKey 1]
[Description User Specified dP]
class SpecifiedValvePressureDrop : ValvePressureDrop
{
};

[SortingKey 2]
[Description Simple Resistance]
class ResistanceValvePressureDrop : ValvePressureDrop
{
};

[SortingKey 3]
[Description ANSI/ISA75.01]
class ANSIISAValvePressureDrop : ValvePressureDrop
{
};

Usage of When and If Designates an equation which follows “when” as active only when the type variable is of given
statements type or conditional expression is satisfied. The “when” attribute can also be used to
conditionally assign a value to an integer or type variable.

EmptyDisplayText Text shown on view, report etc. when variable value is empty

[EmptyDisplayText SteadyState]
variable AmbientTemperature as Temperature;

AllowAliasOverride Aliases could be used to link the data in a parent object with its child or between its own
synonym variables. Aliases allows us to easily influence behavior while maintaining sensible
interfaces to both the parent and child. Aliases can be used to link variables between
referencing objects as well, not only parent/child objects.

Alias can be temporarily superseded by user entered value. Deleting the user
entered values restores alias.

- 55 -
Chapter 6 - Appendix

Generic keywords Description / Example

variable x = 2 as spec;
[AllowAliasOverride] variable m = x;
variable n = m ^ 2;

As variable m is aliased to variable x, on changing x, m value changes automatically.


AllowAliasOverride attribute on the variable m allows it to be over written i.e. m temporarily
delinks its alias with x, when user specifies value to it. Without this attribute, both x and m will be
marked as specifiable variable. Deletion of user specification in m would restore its alias with x
again.

FixedAlias Alias is fixed and cannot be modified by user.

variable x = 2 as spec;
[FixedAlias] variable m = x;
variable n = m ^ 2;

Unlike AllowAliasOverride, FixedAlias establishes strong link with its aliased


variable which cannot be modified.

ModelAttribute Adds a custom model attribute to the current model type. It could be attributed to the main
model or to the sub-elements which the main model is referring.
[ModelAttribute AllowUnsolvedEquations]

Ignores "Not Solved" equations for the overall model status


[ModelAttribute AllowRedundantEquations]

Ignores "Redundant" equations

Publish Starts or ends a published section of a model

If a model has a “LicenseToDesign” element attribute keyword configured and the license is
missing, then the Model page (and the model preview on the ModelUpgrade view) will show
only the published notes and not the model’s 4GL code.

[Publish Notes]

// Steady state model of a ...

[Publish None]

The above sequence makes "Steady state model of a …" appear on license locked views of
model. Multiple [Publish Notes] sections can be added and can include any part of model
(including equations). The sections chosen for publishing will remain active in the model. On a
license locked model, each published section will be appear appended in order of occurrence.

Replace Replaces one variable with another when upgrading to a new model. For example, if user has
initially developed a tank model using a single inlet port “Inlet” and wishes to upgrade to
multiple inlet ports, to retain the existing model definitions, user can use

Replace attribute. Replace Inlet with Inlets(0)

Required Highlights the cell in yellow color to indicate the variable is a nominal specification.

- 56 -
Chapter 6 - Appendix

Generic keywords Description / Example

Shortcut syntax for

[Classification Required]
variable InletPressure as Pressure;
[Classification None]

[required]variable InletPressure as Pressure;

Do not specify “required” for outlet variables. Typically to apply “required” attribute to the
variables, assume your model as simulation model which on specifying inlets and model
parameters calculates outlet.

RequiredVariables Base class variables which are required in the derived class should be stated with
RequiredVariables in the derived class scope. This is in addition to those declared as
“required” in derived class’s own scope.

class BaseWallStress as Base


{
variable Temperatures[3+] as Temperature;
variable Data[Temperatures] as Pressure;
}

class WallStress : BaseWallStress


{
[required] variable InternalDiameter as Length;
[RequiredVariables Temperatures,Data]
Strength = @NaturalCubicSpline({100, Temperatures, Data});

RequiredComponents Enforces the listed (comma delimited) compounds (components) to exist as a sub-set of the
current fluid basis.

Typically, the required compounds are those compounds that are explicitly
referenced in a model.

[RequiredComponents Methane,Ethane,Propane]

Excluding Excludes listed (comma delimited) entries from being active in the next vector equation.
[Excluding H2O] [Link] = 0.0;

[Link][H2O] = 1.0;

Internal Excludes property from default Parameters view.

Shortcut syntax for

[Classification Internal]
variable TemporaryValue;
[Classification None]

[internal] variable TemporaryVariable;

- 57 -
Chapter 6 - Appendix

Generic keywords Description / Example

This shortcut syntax restores original classification for following declaration.

Element Attributes Description / Example

SupportsType Defines current element type as supporting an abstract type for purposes of grouping in
Available Elements palette.
[SupportsType ElectricalNetworkEquipmentType]

LicenseToCreate Defines a license that is required before an instance of element can be created.

[LicenseToCreate [Link]]

LicenseToDesign Defines a license that is required before element's design view (i.e. Editor etc.) can be viewed
[LicenseToDesign [Link]]

DefaultNameFormat Sets a default format for naming instances in the PFD of this model.

[DefaultNameFormat Valve-100]

Further created instances of the same element type would be incrementally named as Valve-
101, Valve-102 etc.

Shortcut Sets an equivalent shortcut tag for a lengthy moniker.

A Shortcut is much like a macro. It can only be used as a replacement syntax at the beginning
of a path. When a shortcut is used in a model, it just serves to simplify and/or document
purpose.

[Shortcut diameter=[Link]]
relRoughness = roughness / diameter;

[Shortcut ConnectionFluids=InletFluids,SettleOutPhase]

- 58 -
Chapter 6 - Appendix

Generic keywords Description / Example

External Specific to object shortcuts but otherwise identical to Shortcut (see above).

With External, the shortcut name becomes a clickable link within the 4GL code. Clicking on the
link will open a view of the external object.

When user drags and drops a variable onto 4GL code, an External shortcut for the owning
object will automatically be inserted at the top of 4GL code. For example, if user drops a Pump
Outlet Pressure on end of this line:
variable PumpPressure as Pressure =

Then the following will be added:


[External P100 = [Link][P-100]]

variable PumpPressure as Pressure = [Link];

Note that dragging and dropping a variable is not required. User can manually type in their own
External attribute as/when necessary.

Connection Tags Description / Example

ConnectionFluids ConnectionFluids is a vector that can be used generically in views regardless of model
because it's defined differently per model (also implied via process ports when not mentioned
explicitly).
[Shortcut ConnectionFluids=InletFluids,SettleOutPhase]

For example, SettleOut is a blow down vessel utility calculator used to determine the initial
pressure by thermodynamically mixing multiple inlet material streams. Being a utility, it gets the
inlet fluid information through ConnectionFluids and its calculated output is set to
SettleOutPhase which is again accessed by blow down vessel at the main level.

ConnectionWires Similar to ConnectionFluids for Electrical operations.


[Shortcut ConnectionWires=InletWires,OutletWires]

6.2 FORTRAN and C/C++ Subroutines and Functions


Because languages like FORTRAN and C/C++ do not support dynamic building of subroutine and function argument lists,
calling FORTRAN and C subroutines and functions from within a UniSim EO 4GL model is problematic. A FORTRAN or C
subroutine or function signature for each possible combination of arguments must be programmed individually and, of
course, this is not feasible. Consequently, calling FORTRAN and C subroutines and functions from within a UniSim EO 4GL
model necessarily has some limitations with respect to their arguments. It is recommended to port any FORTRAN functions
to 4GL for maximum efficiency and reliability. Only use this option as a last resort for the codes that are not portable.

FORTRAN subroutines and functions to be called from within a UniSim EO 4GL model must be built (compiled and linked
into a dynamic link library (DLL)) using Intel FORTRAN Version 10.1.021 or newer. C subroutines and functions also need to
be compiled to a DLL but any compiler will do.

A subroutine can have mixed scalar and vector input arguments and mixed scalar and vector output arguments. Although an
argument of a FORTRAN subroutine or C function can be designated to be both an input and an output, this feature of
FORTRAN and C is not supported for subroutines called within UniSim EO 4GL models.

A function has a single scalar output argument (result). Its input arguments are somewhat more restricted than for a
subroutine. A function can have one or more scalar input arguments, to a limit of 19, or a single vector input argument.
Scalars and vectors cannot be mixed as for subroutines. However, this limitation can be overcome by recasting functions
requiring mixed scalar and vector input arguments as subroutines with a single output argument.

- 59 -
Chapter 6 - Appendix

6.2.1 Calling a FORTRAN or C subroutine from within a UniSim EO 4GL Model


When a FORTRAN or C subroutine is called, a vector equation across the output arguments is added to the model. This
equation sets the UniSim EO 4GL variables associated with the output arguments to the values calculated by the subroutine.
Numerical perturbation is used to establish the dependencies of the outputs on the inputs.

Before a FORTRAN or C subroutine or function can be referenced in a UniSim EO 4GL model, it must first be imported
using the “import” statement, which has the following syntax.

Import "[Link], EntryPoint" as <FORTRAN/C> subroutine LocalName;

wherein

l [Link] is the DLL containing the subroutine. The DLL needs to be put into

o the startup directory, which is the startup directory specified in the shortcut for UniSim Design, the UniSim
Design install directory if UniSim Design is started by browsing for [Link] and then double
clicking on the exe file, or the case’s directory if UniSim Design is started by browsing for the case file of
interest and double clicking on it, or
o a directory on the path.

To view the startup directory specified in the shortcut for UniSim Design, select All Programs, Honeywell, UniSim
Design Suite R…. Right Click on UniSim Design R… and select Properties.
The path is shown in My Computer / Properties / Advanced System Setting / Advanced / Environment Variables /
System Variables / PATH. Alternatively (and more easily), open a cmd shell and type PATH.

l EntryPoint is the entry point (name) for the subroutine in the dll and is case sensitive.
l The “as” keyword must be followed by one of FORTRAN or C.
l The subroutine keyword designates that a subroutine is being imported.
l LocalName is the name of the subroutine to be used within the UniSim EO 4GL model.

The output arguments of a subroutine called from a UniSim EO 4GL model must be variables of the model. A FORTRAN or
C subroutine cannot be called to calculate “local” quantities that are not variables of the model. The input arguments of a
subroutine must also be variables of the model.

The syntax for calling a FORTRAN or C subroutine from within a UniSim EO 4GL model is illustrated below.

variable A;
variable B;
variable T;
variable X[Compounds];
variable Y[Compounds];
variable V;
variable C;
variable Z[Compounds];

import "[Link], mySUB" as FORTRAN subroutine mySub;

{V,C,Z} = @mySub({A,X,B,Y,T});

The braces {…} denote that the contained quantities are treated as a vector. Behind the scene, the input arguments
A,X,B,Y,T are mapped into a single vector in the order listed within the braces {…}. This single vector argument becomes the
input argument of the FORTRAN or C subroutine. So, for the example shown here, the input arguments are mapped into a
single vector as shown below for FORTRAN. For illustration, we will call this vector Inputs.

- 60 -
Chapter 6 - Appendix

Inputs[0] = A
Inputs[1] = X[0]

Inputs[Compounds] = X[Compounds-1]
Inputs[Compounds+1]=B
Inputs[Compounds+2]=Y[0]

Inputs[Compounds+Compounds+1] = Y[Compounds-1]
Inputs[Compounds+Compounds+2] = T

The braces {…} must be used even when there is only a single scalar or vector input argument.

The output arguments are similarly mapped into a single vector in the order listed within the braces {…} on the left side of the
subroutine statement. This single vector becomes the output argument of the FORTRAN or C subroutine. Again, the braces
{…} should be used even when there is only a single scalar or vector output argument.

For the example above, FORTRAN subroutine mySUB has been compiled and linked into the dynamic link library
[Link]. Two compiler directives must be embedded in the code following the subroutine statements as follows.

CDEC$ ATTRIBUTES DLLEXPORT:: mySUB

The ATTRIBUTES directive option DLLEXPORT specifies that procedures or data are being exported to other applications or
dynamic libraries. This enables the subroutine to be called from other programs.

CDEC$ ATTRIBUTES DECORATE, ALIAS: 'mysub' :: mySUB

This compiler directive combines the use of two attributes. The ATTRIBUTES directive option DECORATE specifies that the
external name used in cDEC$ ALIAS or cDEC$ ATTRIBUTES ALIAS should have the same prefix and postfix
decoration performed on it that are associated with the platform and calling mechanism that is in effect (in this case cref).
These are the same decorations performed on the procedure name when ALIAS is not specified. This directive is required
because the FORTRAN subroutine is being called from a C/C++ routine within the UniSim EO infrastructure. It insures that
the internal names for the routines generated by the compiler are the same on both sides (C/C++ and FORTRAN).

The ATTRIBUTES directive option ALIAS specifies an alternate external name to be used when referring to external
subprograms. In the above compiler directive, the ALIAS attribute specifies that the subroutine mySUB will be referred to as
mysub outside the scope of this routine. Note that in this example, the only difference in the names is the case. However, the
alias, the string in quotes, can be any other name.

To compile the FORTRAN subroutine and create the DLL, use the following compiler switches at the command line (or
configure these properties for a project in Visual Studio):

Ifort mySUB.f /iface:cref /dll /out: "[Link]"

The Ifort command executes the Intel Fortran Compiler at the command prompt. The /iface:cref option specifies
that the calling convention for the subroutine to be “C interface by reference”, making the FORTRAN dll compatible with the
C/C++ code in UniSim EO. This option must be used. The /dll option specifies that a DLL is to be created. By default, a
DLL is created with the same name as the file containing the subroutine, replacing “.f” with “.dll”. Adding the qualifier /out:
"[Link]" creates a DLL with the name [Link].

To use Visual Studio, the Intel Visual FORTRAN compiler must be installed, the installation of which installs the Visual
Studio extensions. The compiler and linking options for the dll can then be set under project properties.

The syntax for the subroutine statement of the corresponding FORTRAN subroutine is shown below.

- 61 -
Chapter 6 - Appendix

Subroutine mySUB(InputsLength, Inputs,


InArgsCount, InArgsStarts, InArgsSizes,
OutputsLength, Outputs,
OutArgsCount, OutArgsStarts, OutArgsSizes,
returnCode)
CDEC$ ATTRIBUTES DLLEXPORT:: mySUB
CDEC$ ATTRIBUTES DECORATE, ALIAS: 'mysub' :: mySUB

The arguments of the subroutine are declared as follows. Note that the names of the arguments provided herein can be
changed as desired.

Integer, Intent(In) :: InputsLength


Real(8), Intent(In) :: Inputs(InputsLength)
Integer, Intent(In) :: InArgsCount
Integer, Intent(In) :: InArgsStarts(InArgsCount)
Integer, Intent(In) :: InArgsSizes(InArgsCount)
Integer, Intent(In) :: OutputsLength
Real(8), Intent(Out) :: Outputs(OutputsLength)
Integer, Intent(In) :: OutArgsCount
Integer, Intent(In) :: OutArgsStarts(OutArgsCount)
Integer, Intent(In) :: OutArgsSizes(OutArgsCount)
Integer, Intent(Out) :: returnCode

InputsLength is the length of Inputs, the single vector into which the input arguments of the UniSim EO 4GL subroutine
reference are mapped. Its value is the number of scalar input arguments plus the sum of the lengths of all the vector input
arguments.

Inputs is the single vector into which the input arguments of the UniSim EO 4GL subroutine reference are mapped. Each
input argument is appended in the order declared in the subroutine reference with vector arguments expanded.

InArgsCount is the number of input arguments in the UniSim EO 4GL subroutine reference.

InArgsStarts is an integer vector of starting offsets within Inputs for each input argument of the UniSim EO 4GL
subroutine reference. The offsets point directly to scalar input arguments and to the first element of vector input arguments.

InArgsSizes is an integer vector of sizes for each input argument of the UniSim EO subroutine reference.

OutputsLength is the length of Outputs, the vector into which the output arguments of the UniSim EO 4GL subroutine
reference are mapped. Its value is the number of scalar output arguments plus the sum of the lengths of all the vector output
arguments. Note that OutputsLength is an input of the FORTRAN subroutine.

Outputs is the vector into which the output arguments of the UniSim EO 4GL subroutine reference are mapped. Each
output argument is appended in the order the outputs are declared in the subroutine reference with vector arguments
expanded.

OutArgsCount is the number of output arguments in the UniSim EO 4GL subroutine reference. Note that
OutArgsCount is an input of the FORTRAN subroutine.

OutArgsStarts is an integer vector of starting offsets within Outputs for each output argument of the UniSim EO 4GL
subroutine reference. The offsets point directly to scalar output arguments and to the first element of vector output
arguments.

OutArgsSizes is an integer vector of sizes for each output argument of the UniSim EO subroutine reference. Note that
OutArgSizes is an input of the FORTRAN subroutine.

returnCode returns an error code when an error condition is encountered. A returnCode value of zero indicates
successful execution of the subroutine. When returnCode has a non-zero value, all the output arguments are returned as
UniSim Design FEMPTY.

- 62 -
Chapter 6 - Appendix

It may be convenient to map the elements of Inputs and the elements of Outputs to local variables within the
FORTRAN subroutine, mirroring the input and output arguments of the UniSim EO 4GL subroutine reference. This mapping
is shown below for the example above. Note that the types (scalar or vector) and the order of the arguments from the UniSim
EO 4GL subroutine reference must be known a priori.

First, the local variables must be declared. Sizing the local vectors as shown below places the vectors on the stack and if the
vectors are of significant size could result in a stack overflow.

Real(8) :: A,B,T,V,C
Real(8) :: X(InArgsSizes(2))
Real(8) :: Y(InArgsSizes(4))
Real(8) :: Z(OutArgsSizes(3))

Alternatively, memory can be explicitly allocated for the local vectors as shown below. In this instance, the vectors are placed
on the heap, which is much safer.

Real(8) :: A,B,T,V,C
Real(8), Allocate :: X(:)
Real(8), Allocate :: Y(:)
Real(8), Allocate :: Z(:)
Allocate(X(InArgsSizes(2))
Allocate(Y(InArgsSizes(4))
Allocate(Z(OutArgsSizes(3))

Mapping Inputs to the local variables is then accomplished as follows.

A = Inputs(1)
Do I = 1,InArgsSizes(2)
X(I) = Inputs(InArgsStarts(2)+I-1)
End Do
B = Inputs(InArgsStarts(3))
Do I = 1,InArgsSizes(4)
Y(I) = Inputs(InArgsStarts(4)+I-1)
End Do
T = Inputs(InArgsStarts(5))

Mapping the local output variables to Outputs is similarly accomplished as follows.

Outputs(1) = V
Outputs(2) = C
Do I = 1,OutArgsSizes(3)
Outputs(OutArgsStarts(3)+I-1) = Z(I)
End Do

When memory has been explicitly allocated for the local vector variables, it must be deallocated as shown below before
returning from the subroutine.

Deallocate(X)
Deallocate(Y)
Deallocate(Z)

- 63 -
Chapter 6 - Appendix

The two approaches described above for mapping the embedded scalars and vectors of Inputs and Outputs to local
variables are computationally inefficient. Non-value added computation time is spent allocating and deallocating memory
associated with the local vectors and time is spent copying the values from Inputs to the local variables and copying the
values of the local variables to Outputs. This computational inefficiency can be avoided by declaring pointers into Inputs
and Outputs for referencing the mapped inputs and outputs of the associated subroutine reference of the UniSim EO 4GL
model. The FORTRAN code for generating these pointers for the example above is shown below.

First, the Inputs and Outputs arguments of the FORTRAN subroutine are declared somewhat differently.

Integer, Intent(In) :: InputsLength


Real(8), Target, Intent(In) :: Inputs(InputsLength)
Integer, Intent(In) :: InArgsCount
Integer, Intent(In) :: InArgsStarts(InArgsCount)
Integer, Intent(In) :: InArgsSizes(InArgsCount)
Integer, Intent(In) :: OutputsLength
Real(8), Target, Intent(Out) :: Outputs(OutputsLength)
Integer, Intent(In) :: OutArgsCount
Integer, Intent(In) :: OutArgsStarts(OutArgsCount)
Integer, Intent(In) :: OutArgsSizes(OutArgsCount)
Integer, Intent(Out) :: returnCode

Including “Target” in a declaration of a variable instructs the compiler not to eliminate this variable as a result of
optimizations that it performs because a pointer to the variable may be created.

Second, local pointer variables are declared for each of the input and output arguments of the associated subroutine
reference of the UniSim EO 4GL model.

Real(8), Pointer :: A
Real(8), Pointer :: X(:)
Real(8), Pointer :: B
Real(8), Pointer :: Y(:)
Real(8), Pointer :: T
Real(8), Pointer :: V
Real(8), Pointer :: C
Real(8), Pointer :: Z(:)

Finally, the pointer values are assigned.

A => Inputs(InArgsStarts(1))
X => Inputs(InArgsStarts(2):InArgsStarts(2)+InArgsSizes(2)-1)
B => Inputs(InArgsStarts(3))
Y => Inputs(InArgsStarts(4):InArgsStarts(4)+InArgsSizes(4)-1)
T => Inputs(InArgsStarts(5))
V => Inputs(OutArgsStarts(1))
C => Inputs(OutArgsStarts(2))
Z => Inputs(OutArgsStarts(3):OutArgsStarts(3)+OutArgsSizes(3)-1)

These assignments map the local pointer variables into elements or ranges of elements of Inputs and Outputs. Having
made these assignments, the local pointer variables can be referenced in the usual manner. For example, the following code
sums the elements of X.

Integer I
Real(8) Sum
Sum = 0.
Do I = 1,InArgsSizes(2)

- 64 -
Chapter 6 - Appendix

Sum = Sum + X(I)


End Do

Although not required, it is advisable to perform checks on the inputs and outputs of the subroutine to ensure that the
structure of Inputs and Outputs is consistent with what the subroutine expects. For example, in this instance a test
could be performed to verify that InArgsCount is 5. returnCode should be set to a non-zero value if a discrepancy is
found. Such tests should be performed as the first executable section of the subroutine, before allocating memory or
establishing local pointer variables.

6.2.2 Calling a FORTRAN or C function from within a UniSim EO 4GL Model


When a FORTRAN or C function is referenced in a UniSim EO 4GL equation, the function reference is treated similarly to a
model variable corresponding to the result of the function. Numerical perturbation is used to establish the dependencies of
the result of the function on its inputs that are variables of the model.

Before a FORTRAN or C function can be referenced in a UniSim EO 4GL model, it must first be imported using the
“import” statement, which has the following syntax.

Import "[Link], EntryPoint" as <FORTRAN/C> function


LocalName(ArgList);

wherein

l The "[Link], EntryPoint" as <FORTRAN/C> part of the “import” statement is handled identically to the
“import” statement for subroutines.
l The function keyword designates that a function is being imported.
l LocalName is the name of the subroutine or function to be used within the UniSim EO 4GL model. It is not case
sensitive.
l ArgList is a prototype of the argument list – a list of scalar quantities or a single vector. It is optional but
recommended. When present, the arguments must be comma delimited.

As noted above, the arguments of a function can be a list of up to 19 scalar quantities or a single vector.

6.2.3 Functions with Scalar Input Arguments


The syntax for calling a FORTRAN or C function having scalar arguments from within a UniSim EO 4GL model is illustrated
below.

variable U;
variable V;
variable W;
variable Z;

import "[Link], myFUNsc" as FORTRAN function myFunSc(A,B,C);

Z = @myFunSc(U,V,W);

The scalar input arguments of a function can be from any source (a variable of the UniSm EO 4GL model, a UniSim EO 4GL
expression, a constant of the UniSim EO 4GL model, a literal, etc.), provided the sources resolves to a numeric value.

- 65 -
Chapter 6 - Appendix

For the example above, FORTRAN function myFUNsc has been compiled and linked into the dynamic link library
[Link]. The two compiler directives discussed above for FORTRAN subroutines must also be used with FORTRAN
functions. Also, the compiler options discussed above for compiling FORTRAN subroutines must be used when compiling
FORTRAN functions.

The syntax for the function statement of the corresponding FORTRAN function for the UniSim EO 4GL function reference in
the example above is shown below.

Integer Function myFUNsc(A,B,C,Result)


CDEC$ ATTRIBUTES DLLEXPORT:: myFUNsc
CDEC$ ATTRIBUTES DECORATE, ALIAS: 'myfunsc' :: myFUNsc

A, B, and C are the scalar input arguments of the function reference in the UniSim EO 4GL model.

Result is the result of the function, that is, the function value.

The function must be declared as an integer function whose return value is a status code designating whether execution of
the function is successful. A function value of zero indicates successful execution of the function. A non-zero function value
indicates that an error condition was encountered. When the function value is non-zero, Result is returned as UniSim
Design FEMPTY.

The arguments of the function are declared as follows. Note that the names of the arguments provided herein can be
changed as desired.

Real(8), Intent(In) :: A
Real(8), Intent(In) :: B
Real(8), Intent(In) :: C
Real(8), Intent(Out) :: Result

6.2.4 Functions with a Single Vector Input Argument


The syntax for calling a FORTRAN or C function having a single vector argument from within a UniSim EO 4GL model is
illustrated below.

variable U[Compounds];

variable U[Compounds];
variable Z;

import "[Link], myFUNvec" as FORTRAN function myFunVec(X);

Z = @myFunVec(U);

The vector input argument of a function can be from any source (variable of the UniSm EO 4GL model, a UniSim EO 4GL
expression, etc.), provided the source resolves to a numeric value for each element of the vector.

The syntax for the function statement of the corresponding FORTRAN function for the UniSim EO 4GL function reference in
the example above is shown below.

Integer Function myFUNvec(InputVec,InputVecCount,Result)


CDEC$ ATTRIBUTES DLLEXPORT:: myFUNvec
CDEC$ ATTRIBUTES DECORATE, ALIAS: 'myfunvec' :: myFUNvec

InputVec is the vector input argument of the function reference in the UniSim EO 4GL model.

- 66 -
Chapter 6 - Appendix

InputVecCount is the length of InputVec.

Result is the result of the function, that is, the function value.

The function must be declared as an integer function whose return value is a status code designating whether execution of
the function is successful. A function value of zero indicates successful execution of the function. A non-zero function value
indicates that an error condition was encountered. When the function value is non-zero, Result is returned as UniSim
Design FEMPTY and an error message incorporating the name of the function and the integer return value is written to the
trace message window of UniSim EO.

The arguments of the function are declared as follows. Note that the names of the arguments provided herein can be
changed as desired.

Real(8), Intent(In) :: InputVec (InputVecCount)


Integer, Intent(In) :: InputVecCount
Real(8), Intent(Out) :: Result

- 67 -
NOTICES

Trademarks
l Experion®, PlantScape®, SafeBrowse®, TotalPlant®, and TDC 3000® are registered trademarks of Honeywell
International, Inc.

l ControlEdge™ is a trademark of Honeywell International, Inc.

l OneWireless™ is a trademark of Honeywell International, Inc.

l Matrikon® and MatrikonOPC™ are trademarks of Matrikon International. Matrikon International is a business unit of
Honeywell International, Inc.

l Movilizer® is a registered trademark of Movilizer GmbH. Movilizer GmbH is a business unit of Honeywell International,
Inc.

l Experion®, PlantScape®, and SafeBrowse® are registered trademarks of Honeywell International, Inc.

l Experion® and SafeBrowse® are registered trademarks of Honeywell International, Inc.

l PlantCruise™ is a trademark of Honeywell International, Inc.

l Experion® is a registered trademark of Honeywell International, Inc.

l ControlEdge™ is a trademark of Honeywell International, Inc.

l OneWireless™ is a trademark of Honeywell International, Inc.

Other trademarks
Microsoft and SQL Server are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or
other countries.

Trademarks that appear in this document are used only to the benefit of the trademark owner, with no intention of trademark
infringement.

Third-party licenses
This product may contain or be derived from materials, including software, of third parties. The third party materials may be
subject to licenses, notices, restrictions and obligations imposed by the licensor. The licenses, notices, restrictions and
obligations, if any, may be found in the materials accompanying the product, in the documents or files accompanying such third
party materials, in a file named third_party_licenses on the media containing the product, or at
[Link]

- 68 -
Documentation feedback
You can find the most up-to-date documents on the Honeywell Process Solutions support website at:
[Link]

If you have comments about Honeywell Process Solutions documentation, send your feedback to: hpsdocs@[Link]

Use this email address to provide feedback, or to report errors and omissions in the documentation. For immediate help with a
technical problem, contact your local Honeywell Process Solutions Customer Contact Center (CCC) or Honeywell Technical
Assistance Center (TAC).

How to report a security vulnerability


For the purpose of submission, a security vulnerability is defined as a software defect or weakness that can be exploited to
reduce the operational or security capabilities of the software.

Honeywell investigates all reports of security vulnerabilities affecting Honeywell products and services.

To report a potential security vulnerability against any Honeywell product, please follow the instructions at:

[Link]

Support
For support, contact your local Honeywell Process Solutions Customer Contact Center (CCC). To find your local CCC visit the
website, [Link]

Training classes
Honeywell holds technical training classes that are taught by process control systems experts. For more information about these
classes, contact your Honeywell representative, or see [Link]

- 69 -

You might also like