How to perform a Species Mass Balance

From SysCAD Documentation
Jump to navigation Jump to search

Navigation: PGMs ➔ Example PGM Files ➔ Species 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 species mass balance to account for the total in / out of the species and how much the species has reacted in reactions. To obtain a quick balance of a species, we can do the following:

  1. Add the Species of interest to the PlantModel Settings Tab.
  2. Add a PGM file using TagSelect Class to sum up the total in, out and reacted amount and perform a balance.

Adding Species to the tracking List

We will be using NaCl(aq) as an example to for this document.

From the View - Plant Model command, go to Settings Tab, add in the species as shown below: (NOTE the order of the list is sorted after the species is added, in the picture below, NaCl(aq) was added as Species03, but after it has been added, it has moved to Species02.)

TrackSpecies1.png

Once the species has been added to the list, user can track the change of that particular species in every unit / pipe when a project is solved. For example, NaCl is being reacted in a reaction, the amount of change is listed in the Links tab of the unit. A negative value means the species is being consumed, positive means the species is being created.

TrackSpecies2.png

Use PGM file to perform mass balance

To perform a mass balance of the species, we recommend using the Tag Select Class at the end of project solve, an example is given below:

;--- SysCAD General Controller (PGM) program logic file ---
; Revision: 1     Date: 27/07/2016    Author:Kenwalt

;--- variable declarations ---
PageLabel("NaCl")
TextLabel(, "   -----------NaCl Balance-----------",)
TagSelect 	Inputs, Outputs, Reactions
integer 	[email protected], [email protected], [email protected], i
real 		[email protected]("Qm","t/h"), [email protected]("Qm","t/h"), [email protected]("Qm","t/h"), [email protected]("Qm","t/h")
Checkbox 	[email protected], [email protected], [email protected]
string 		flow_tag
 
Sub CalcBalance()
  
  ; find all true feeders (not connected) and makeup sources 
  InsOK= Inputs.Exec("([UnitType]=='FeederSink' AND [State]==1) OR ([UnitType] == 'MakeupSource') AND [Links.Nett.Qm.NaCl(aq)]<>0", false, false)
  ; find total number of inputs 
  InCount = Inputs.GetLen()
  ; sum all input flows 
  i=0
  FlowIn = 0
  while(i<InCount)
   flow_tag = Concatenate(Inputs.Tag(i),".Links.Nett.Qm.NaCl(aq) (t/h)")
   FlowIn = FlowIn + [flow_tag]
   i = i + 1
  endwhile
 
  ; find all true sinks (not connected) 
  OutsOK = Outputs.Exec("([UnitType]=='FeederSink' AND [State]==2) AND [Links.Nett.Qm.NaCl(aq)]<>0", false, false)
  ; find total number of outputs 
  OutCount = Outputs.GetLen()
  ; sum all output flows 
  i=0
  FlowOut = 0
  while (i<OutCount)
   flow_tag = Concatenate(Outputs.Tag(i),".Links.Nett.Qm.NaCl(aq) (t/h)")
   FlowOut = FlowOut + [flow_tag]
   i = i + 1
  endwhile
 
  ; find all Reactions 
  ReactionOK = Reactions.Exec("([EB.Reactions]<>0 or [Reactions]<>0 or [FEB.Reactions]<>0) AND [Links.Nett.Qm.NaCl(aq)]<>0", false, false)
  ; find total number of Reactions 
  ReactionCount = Reactions.GetLen()
  ; sum all Reacted flows 
  i=0
  TotalReacted = 0
  while (i<ReactionCount)
   flow_tag = Concatenate(Reactions.Tag(i),".Links.Nett.Qm.NaCl(aq) (t/h)")
   TotalReacted = TotalReacted + [flow_tag]
   i = i + 1
  endwhile

 ; perform mass balance, note that flow out and reacted amount are reported as negative numbers.   
 Balance = FlowIn + FlowOut + TotalReacted
 
EndSub

Sub TerminateSolution() 
   ;--- Logic executed after last iteration (when solver is stopped) 
   CalcBalance()
EndSub

$ ; --- end of file ---

In the PGM file above, we have performed three calculations:

  1. Total NaCl input flow
  2. Total NaCl output flow
  3. Total NaCl reacted

From these three values, we can perform a balance for that species.

  • These values will be shown on the General Controller Access Window when the solver stops.
  • Note that the TagRefs Tab page lists all the units used by the pgm calculation, user can jump to these units for further review if required.
TrackSpecies3.png

Use PGM file for mass balance of a selected species (Build137)

This is a variation of the above PGM file, using the GetValues function call (available in Build137 or later) and allowing the user to specify the species at run time.

;--- SysCAD General Controller (PGM) program logic file ---
;    Revision: 1     Date: 26/04/2018    Author:Kenwalt
;--- variable declarations ---
PageLabel("SpeciesBalance")
    TextLabel(, "   -----------Species Balance-----------",)
    TagSelect Inputs, Outputs, Reactions
    Array     InputsList, OutputsList, ReactionsList
    String    SpeciesName*{Comment(" Enter species and phase, eg: NaCl(aq) ")}
    integer   [email protected], [email protected], [email protected]
    real      [email protected]("Qm","t/h"), [email protected]("Qm","t/h"), [email protected]("Qm","t/h"), [email protected]("Qm","t/h")
    Checkbox  [email protected], [email protected], [email protected]
    string    flow_tag, Criteria
 
Sub CalcBalance()
  ; find all true feeders (not connected) and makeup sources 
    Criteria = Concatenate("([UnitType]=='FeederSink' AND [State]==1) OR ([UnitType] == 'MakeupSource') AND ([Links.Nett.Qm.", SpeciesName, " (g/h)]>1 OR [Links.Nett.Qm.", SpeciesName, " (g/h)]<-1)")
    InsOK= Inputs.Exec(Criteria, false, false)
    InCount = Inputs.GetLen()
  ; sum all input flows 
    flow_tag = Concatenate(".Links.Nett.Qm.", SpeciesName, " (t/h)")
    Inputs.GetValues(flow_tag, InputsList)
    FlowIn = InputsList.Sum()
 
  ; find all true sinks (not connected) 
    Criteria = Concatenate("([UnitType]=='FeederSink' AND [State]==2) AND ([Links.Nett.Qm.", SpeciesName, " (g/h)]>1 OR [Links.Nett.Qm.", SpeciesName, " (g/h)]<-1)")
    OutsOK = Outputs.Exec(Criteria, false, false)
    OutCount = Outputs.GetLen()
  ; sum all output flows 
    flow_tag = Concatenate(".Links.Nett.Qm.", SpeciesName, " (t/h)")
    Outputs.GetValues(flow_tag, OutputsList)
    FlowOut = OutputsList.Sum()
 
  ; find all Reactions 
    Criteria = Concatenate("([EB.Reactions]<>0 or [Reactions]<>0 or [FEB.Reactions]<>0) AND ([Links.Nett.Qm.", SpeciesName, " (g/h)]>1 OR [Links.Nett.Qm.", SpeciesName,  " (g/h)]<-1)")
    ReactionOK = Reactions.Exec(Criteria, false, false)
    ReactionCount = Reactions.GetLen()
  ; sum all Reacted flows 
    flow_tag = Concatenate(".Links.Nett.Qm.", SpeciesName, " (t/h)")
    Reactions.GetValues(flow_tag, ReactionsList)
    TotalReacted = ReactionsList.Sum()

  ; perform mass balance, note that flow out and reacted amount are reported as negative numbers.   
    Balance = FlowIn + FlowOut + TotalReacted
EndSub

Sub TerminateSolution() 
   ;--- Logic executed after last iteration (when solver is stopped) 
   CalcBalance()
EndSub

$ ; --- end of file ---