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
Multi-Step Trigger Checking
Counter, While
and Random
Belt Filter
Wash Loss

Related Links: PGM Files using Class and Functions, TagSelect 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 as an example to for this document.

From the View - Plant Model command, go to Settings Tab, add in the species as shown below:

TrackSpecies1.png NOTE:
  • The order of the list is sorted after the species is added, in the example, NaCl(aq) was added as Species03, but after it has been added, it has moved to Species02. Likewise with NaCl(s).
  • 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. See example below.
  • 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.
  • When we add species in multiple phases, we can get the component as a display field as well. Two examples are shown here, H2O and NaCl. We can use the component Nett value in the species mass balance. See the PGM file example below.

Use PGM file to perform mass balance

To perform a mass balance of the species, we recommend using the TagSelect Class at the end of project solve, some examples are given below:

Example 1 - showing input, output and reacted amount

;--- SysCAD General Controller (PGM) program logic file ---
;    Revision: 2     Date: Jan 2023    Author: SysCAD Team
;--- variable declarations ---
PageLabel "SpeciesBalance" 
    TextLabel , "   -----------Species Balance-----------", ""
    TagSelect Inputs, Outputs, Reactions
    Array     InputsList, OutputsList, ReactionsList
    String    SpeciesName*{Comment(" Enter species or component, e.g.: NaCl(aq) or NaCl ")}
    integer   InCount@, OutCount@, ReactionCount@
    real      FlowIn@("Qm","t/h"), FlowOut@("Qm","t/h"), TotalReacted@("Qm","t/h"), Balance@("Qm","t/h")
    Checkbox  InsOK@, OutsOK@, ReactionOK@
    string    flow_tag, Criteria, Criteria_Tag1, Criteria_Tag2
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 ([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) OR ([UnitType] == 'DiscardSink')  ) 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 user-specified reactions (excluding units with auto-generated reactions such as GFEM or TCE reactors) 
    Criteria_Tag1 = Concatenate("([Links.Nett.Qm.", SpeciesName, " (g/h)]>0.001 OR [Links.Nett.Qm.", SpeciesName,  " (g/h)]<-0.001)")
    Criteria_Tag2 = "[SubTypeList] like 'RB.*' "
    Criteria      = Concatenate(Criteria_Tag1, "AND", Criteria_Tag2)
    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

Sub TerminateSolution() 
   ;--- Logic executed after last iteration (when solver is stopped) 
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.

Example 2 - Showing all species flow change

Class Class_SpeciesBalance
	string 		flow_tag, Criteria_Tag, SpeciesName@, temp
	StrArray    SpeciesChangeTag
	Array		SpeciesChangeFlow
	TagSelect 	SpeciesChanges
	Checkbox 	SpeciesChangeOK@
	Long 		SpciesChangeCount@, i
	Real        SpBalance@("Qm","t/h")

	Sub Init()
	   SpeciesName = ClassTag()

	Sub Exec()
	  ; find all SpeciesChanges
	  Criteria_Tag = Concatenate("([Links.Nett.Qm.", SpeciesName, " (g/h)]>0.001 OR [Links.Nett.Qm.", SpeciesName,  " (g/h)]<-0.001)")
	  SpeciesChangeOK    = SpeciesChanges.Exec(Criteria_Tag, false, false)
	  ; find total number of SpeciesChanges 
	  SpciesChangeCount = SpeciesChanges.GetLen()
	  ; get all species change flows
	  flow_tag = Concatenate(".Links.Nett.Qm.",SpeciesName, " (t/h)")
	  SpeciesChanges.GetValues(flow_tag, SpeciesChangeFlow)
	  ; sum all species change flows
	  SpBalance = SpeciesChangeFlow.Sum()
	  ; get the unit list of where change occurred	
	  while (i<SpciesChangeCount)
		  temp = SpeciesChanges.Tag(i)
		  SpeciesChangeTag.SetAt(i, temp)
		  i = i + 1

PageLabel "SpeciesBal"
TextLabel , "The species must be added to PlantModel-Settings Tab", ""

Class_SpeciesBalance # H2O, CuS

watch CuS.SpeciesChangeTag[all,8]
watch CuS.SpeciesChangeFlow[all,8]

Sub InitialiseSolution()
  ForEachClass(Class_SpeciesBalance, Init())
  CuS.SpeciesName = "CuS(s)"

ForEachClass(Class_SpeciesBalance, Exec())

In the PGM file above, we have performed one calculations: Total CuS change, this includes input, output and any changes caused by reactions.

  • This can be used to track the species movement across the process.
  • This example is written as a class, other species can be easily added.
  • These values will be shown on the General Controller Access Window when the solver stops.