Class - Examples
Navigation: PGMs ➔ Classes
| Functions | Subroutines | Classes | |||||
|---|---|---|---|---|---|---|---|
| Defining a Function | Predefined Functions | Tag Functions | Mathematical Functions | String Functions | Defining a Subroutine | Trigger Subroutines | Defining a Class |
Related Links: User Defined Class and Functions, Example PGM Files
| Class - Introduction | Class - Defining a Class | Class - Using a Class | Class - Macros | Class - Examples |
|---|
Global Predefined Class Instances: Species Database Class, Particle Size Definition Class, Plant Model Class
Predefined Classes: Array Class, StrArray Class, Matrix Class, TagSelect Class, Noise Class, TimeClass
Declaring Class Instances
; Declare Class instances
CSTR_Class Tank_A, Tank_B, Tank_C, Tank_D, Tank_E, Tank_F
;-----------------------------------------------------------
;Initialise class instance
Sub InitialiseSolution()
ForEachSub(CSTR_Class, Init())
EndSub
;-----------------------------------------------------------
;Execute CSTR_Class subroutines
ForEachSub(CSTR_Class, Exec())
NOTES:
|
Declaring Class Instances in an array
Class instance can also be defined in an array format, for example an equivalent of the above code can be written as:
| After Build 139.32530 | For earlier builds of SysCAD |
|---|---|
;After {{Available139|32530||y}}
const long TankCount = 7
CSTR_Class Tank[TankCount]{ez}
Sub InitialiseSolution()
ForEachSub(Tank, Init())
EndSub
ForEachSub(Tank, Exec())
|
long i
const long TankCount = 7
CSTR_Class Tank[TankCount]
ExcludeWatch Tank[0]
Sub InitialiseSolution()
i = 1
While (i<TankCount)
Tank[i].Init()
i = i + 1
EndWhile
EndSub
i = 1
While (i<TankCount)
Tank[i].Exec()
i = i + 1
EndWhile
|
NOTES:
- Seven CSTR_Class instances are defined here, Tank 0 to Tank 6.
- The array always starts with 0, therefore, we have intentionally defined 7 instances here and we will use Tanks 1 to 6. In our PGM code we will skip Tank 0 and start with Tank 1.
- The
ExcludeWatchKeyword instructs SysCAD not to display Tank 0. - The
ExcludeClassKeyword instructs SysCAD not to include Tank 0 in any ForEach macro. - If the "Init()" subroutine requires a different input parameter for each call, such as Init("tagname"), then
ForEachSub(Tank, Init())cannot be used.
Using ForEachSub with multiple class declarations
Some Examples on how to use the function:
| The following code... | Is equivalent to... |
|---|---|
CSTR_Class Tank10, Tank20
CSTR_Class Tank[3]
;Example 1:
;Call Exec for all instances of CSTR_Class
ForEachSub(CSTR_Class, Exec())
;Example 2:
;Call Exec for all instances in Tank[] Class Array only
ForEachSub(Tank, Exec())
CSTR_Class Tank30
|
CSTR_Class Tank10, Tank20
CSTR_Class Tank[3]
;Example 1:
;Call Exec for all instances of CSTR_Class
Tank10.Exec()
Tank20.Exec()
long i
i = 0
While (i<3)
Tank[i].Exec()
i = i + 1
EndWhile
;Example 2:
;Call Exec for all instances in Tank[] Class Array
i = 0
While (i<3)
Tank[i].Exec()
i = i + 1
EndWhile
CSTR_Class Tank30
|
Examples Using ClassList
;define Class instances
TankClass T1,T2,T3,T4,T5
;define the class list
ClassList ABC {T1,T2,T3,T4,T5}
|
TankClass{List(ABC)}T1,T2,T3
|
ClassGrid ABC
ForEachSub(ABC, Init())
TotalMass = ForEach(+, ABC, Mass)
|
ClassList List1 {T1,T2,T3}
ClassList List2 {T4,T5}
ForEachSub(List1, Exec(true))
ForEachSub(List2, Exec(false))
|
Example using Include File
The user wants to calculate the required agitator power in a number of vessels in a project. This functionality will be used in a number of different projects, and hence the file with the class will be stored on the network where it can be accessed by a number of users and projects.
A formula that may be used to calculate the agitator power for turbulent flow is:
- [math]\displaystyle{ \mathbf{\mathit{P = P_o\;N^3\;D^5\;Density}} }[/math]
- where:
- P - Agitation Power;
- Po - the dimensionless power number, which is a function of impeller geometry;
- N - agitator rotational speed;
- D - Diameter of the impeller;
- Density - Density of the material in the vessel.
The class is saved in a file called AgitatorPower.pgm and is saved on the network at n:\Users\SysCAD Common Files\
| The Class file is as follows: | The main pgm file may have the following structure: |
Class Class_AgitatorPower
Textbreak
ClassGridColumnWidth 12
ClassGridMaxColumns 5
TextLabel "Inputs"
String UnitName{Tag}*
real Po*<<1>>
real N<<0.3>>{i, comment("Rotation per second")}
real D<<1>>{i, ("L", "m"), comment("ImpellerDiameter")}
TextLabel "Results"
string DensityTag@@{ Tag}
real Density@("Rho", "kg/m^3")
real Power@("Pwr", "kW")
Sub Init()
UnitName = ClassTag()
DensityTag = Concatenate(UnitName, ".QProd.SLRho (kg/m^3)")
EndSub
Sub Exec()
Density = [DensityTag]
Power = Po * N^3 * D^5 * Density
EndSub
EndClass
|
PageLabel "Agitators"
>>n:\Users\SysCAD Common Files\AgitatorPower.pgm
Textbreak
;Define class instances in grid format by adding "#"
Class_AgitatorPower # Cementation, NiCo_Precip, Ni_Diss_1
Sub InitialiseSolution()
ForEachSub(Class_AgitatorPower, Init())
EndSub
ForEachSub(Class_AgitatorPower, Exec())
$ ; --- end of file ---
|
And the access window of the controller will show the following fields:
Notes:
- The user may follow the same rules for individual functions that may be useful in a number of pgms or in separate projects.
Example Using Class List and Class Macro
>>_Class_BFDFlow.pgm
TextLabel ," ============= Block Mass Flow ============="
TextLabel " == Inputs Streams =="
Class_BFD_Summary # P101, P709, P412, P102
ClassList Inputs{P101, P709, P412, P102}
TextLabel " == Outputs Streams =="
Class_BFD_Summary # P104, P103
ClassList Outputs{P104, P103}
TextLabel " == Balance =="
Real Total_Input_Mass@("Qm", "t/h")
Real Total_Output_Mass@("Qm", "t/h")
Real Balance_MassFlow@("Qm", "t/h")
Sub InitialiseSolution()
ForEachSub(Class_BFD_Summary, init())
EndSub
Sub TerminateSolution()
ForEachSub(Class_BFD_Summary, exec())
Total_Input_Mass = ForEach(+, Inputs, MassFlow)
Total_Output_Mass = ForEach(+, Outputs, MassFlow)
Balance_MassFlow = Total_Input_Mass - Total_Output_Mass
EndSub
|
This example is from the Nickel_Copper_Project, specifically the Cementation_Summary general controller on the Summary flowsheet. The aim is to perform a mass balance across a "process block" using user-specified input and output streams. |
Example using TagSelect to initialse UnitTag
>>_Class_TankVol.pgm
;--- variable declarations ---
PageLabel "Tanks"
TextLabel ""
StrArray TankTags
string Tag_Name
TagSelect FindTanks
Checkbox TagListOK@
Long TankTagCount@, i
Class_Tank # Tanks[18]{ez}
Sub PreStart()
TagListOK = FindTanks.Exec("[UnitType] == 'Tank-1' ", false, false)
; find total number of feeders
TankTagCount = FindTanks.GetLen()
TankTags.SetSize(TankTagCount)
i=0
while (i<TankTagCount)
Tag_Name = FindTanks.Tag(i)
TankTags.SetAt(i, Tag_Name)
Tanks[i+1].UnitTag = TankTags.GetAt(i)
i = i + 1
endwhile
EndSub
Sub InitialiseSolution()
;--- Logic executed during initialisation before first iteration
;For example to set initial values, or set values in units
ForEachSub(Tanks, Init())
EndSub
;--- Logic - executed at EVERY step ---
ForEachSub(Tanks, Exec())
$ ; --- end of file ---
|
A variation of this example can be found in Nickel_Copper_Project. This version is slightly simplified. A simplified version of the Tank Volume class can be found on this page: Simple Example. The aim is to perform the tank volume calculation for all tanks in the project based on user-specified residence time. The class instances are defined as an array. The UnitTag for the class instances will be initialised by Model Tag names in the project. This is done by using the predefined TagSelect Class to search the project for tags matching the "Tank-1" UnitType. |
Other PGM Example Files using Classes
There are many example PGM files that use classes, which are listed on this page: PGM Files using Class and Functions
Example User Defined Classes
There are numerous example PGM files in the distributed Example projects that utilise the PGM Class. These are listed on this page: Example User Defined Classes


