How to perform an Elemental Mass Balance
Navigation: PGMs ➔ Example PGM Files ➔ Elemental Mass Balance
Simple Examples | Subroutines Examples | Dynamic Examples | Steady State Overall Mass Balance | Array and Matrix Examples | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Basic Layout | Simple Calculations | Initialise PreStart | Multi-Step Trigger | Checking Project | Counter, While and Random | Belt Filter Wash Loss | Startup Actions | Mass Balance | Mass Balance | Species Balance | Elemental Balance | Lookup Value | Set Values | Tridiagonal System |
Related Links: PGM Files using Class and Functions, Tag Select Class, FAQ (Mass & Energy Balance)
It is often important to perform an elemental mass balance to account for the total in / out of the elements. Here we will show how to obtain a quick balance of an element by adding a PGM file using the TagSelect Class to sum up the total in and out and perform a balance.
Use PGM file to perform mass balance
To perform a mass balance of an element, we recommend using the TagSelect Class at the end of project solve, an example is given below. In this example we have used a user defined Class. This allows it to be used for any valid element and also for multiple elements by declaring separate instances of the class.
NOTE: Some PGM functionality (keywords) used in the following example requires SysCAD9.3 Build139.32360 or later.
Class Class_ElementalBalance
ClassGridColumnWidth 8
TextLabel "Elemental Balance"
TagSelect Inputs, Outputs, Tears
Array InputFlows, OutputFlows, TearInFlows, TearOutFlows
integer InCount@, OutCount@
TextLabel " Flow Balance"
real FlowIn@("Qm","t/h"), FlowOut@("Qm","t/h"), Balance@("Qm","t/h"),RelError@
bit OK@
TextLabel " Tears Balance"
integer TearCount@
real TearFlowIn@("Qm","t/h"), TearFlowOut@("Qm","t/h"), TearBalance@("Qm","t/h"),TearRelError@
TextLabel " Oveall Balance"
Real Overall_Balance@("Qm","t/h")
; internal variables
string FlowTag, FlowTagIn, FlowTagOut, Criteria, Element
Sub Init()
Element = ClassTag()
EndSub
Sub CalcBalance()
; find all true feeders (not connected) and makeup sources
Criteria = Concatenate("(([UnitType]=='FeederSink' AND ([State]==1 AND [Operation]!=11)) OR ([UnitType] == 'MakeupSource') ) AND [QProd.QEl.",Element,"]<>0")
OK = Inputs.Exec(Criteria, false,false)
; find total number of inputs
InCount = Inputs.GetLen()
; sum all input flows
FlowTag = Concatenate(".QProd.QEl.",Element," (t/h)")
Inputs.GetValues(FlowTag, InputFlows)
FlowIn = InputFlows.Sum()
; find all true sinks (not connected)
Criteria = Concatenate("(([UnitType]=='FeederSink' AND [State]==2) OR ([UnitType] == 'DiscardSink') ) AND [QProd.QEl.",Element,"]<>0")
OK = Outputs.Exec(Criteria, false,false)
; find total number of outputs
OutCount = Outputs.GetLen()
; sum all output flows
FlowTag = Concatenate(".QProd.QEl.",Element," (t/h)")
Outputs.GetValues(FlowTag, OutputFlows)
FlowOut = OutputFlows.Sum()
; perform elemental mass balance
Balance = FlowIn - FlowOut
RelError = Balance/Max(1.0e-12, Max(FlowIn, FlowOut))
EndSub
Sub CalcTearBalance()
; find all pipes with tears and element flow
Criteria = Concatenate("[UnitType]=='Pipe-1' AND ([Tear.Type]==1 OR [Tear.Type]==2) AND ", "([Qo.QEl.",Element,"]<>0 OR [Qo.QEl.",Element,"]<>0)")
OK = Tears.Exec(Criteria, false,false)
; find total number of tears
TearCount = Tears.GetLen()
; sum all input and output flows
FlowTagIn = Concatenate(".Qi.QEl.",Element," (t/h)")
Tears.GetValues(FlowTagIn, TearInFlows)
TearFlowIn = TearInFlows.Sum()
FlowTagOut = Concatenate(".Qo.QEl.",Element," (t/h)")
Tears.GetValues(FlowTagOut, TearoutFlows)
TearFlowOut = TearOutFlows.Sum()
; perform elemental mass balance
TearBalance = TearFlowIn - TearFlowOut
TearRelError = TearBalance/Max(1.0e-12, Max(TearFlowIn, TearFlowOut))
EndSub
Sub OverallBalance()
CalcBalance()
CalcTearBalance()
Overall_Balance = Balance - TearBalance
EndSub
EndClass