Aqueous Feed Concentration Calculator

From SysCAD Documentation
Jump to navigation Jump to search

Navigation: PGMs ➔ Example PGM Files ➔ Aqueous Feed Concentration Calculator

Example User Defined Classes
Set Species Splits Agitator
Aq Feed Conc
Bayer Liquor
Element Bal
Optimise Controllers
for sensitive PIDs
Relaxed Cross Page Connector

Related Links: Defining a Class, Defining a Function

PGM File - Aqueous Feed Concentration Calculator

;--- SysCAD General Controller (PGM) file ---
; Revision: 3     Date:  August 2023   Author: SysCAD Team
; This PGM will calculate the Feed composition (in a single feeder) based on user specified aqueous concentration.
; See example at the end of the page.

Class	Class_CompoundDef
	TextLabel "  -------------Inputs-------------------------" 
	String	  CompoundTag*
	REAL	  Conc_Reqd*("Conc", "g/L")
	REAL	  Actual_Conc@("Conc", "g/L")
	Checkbox  Elemental_Conc*{Comment("Tick=SetAsElmentalConc")}
	String	  ElementTag*
	REAL	  Ratio*{Comment("MolesOfElementInCompound")}
	TextLabel "  -------------Results-------------------------" 
	REAL	  MW_Ele@@, MW_Comp@@
	REAL	  MassFlow@@("Qm", "t/h"){Comment("Compound")}
	REAL	  MassFrac@@("Frac", "%")
	Sub Init()
		Actual_Conc = 0
		MassFlow = 0
		MassFrac = 0
		MW_Ele = 0
		MW_Comp = 0
	Sub exec()
		MW_Ele = IIF(Elemental_Conc, [Concatenate("$SDB.Elem.", ElementTag, ".MoleWt")], 0)
		MW_Comp = [Concatenate("$SDB.", CompoundTag, "(aq).MoleWt()")]
		MassFlow = IIF(Elemental_Conc, (Conc_Reqd * MW_Comp / (MW_Ele*Ratio)), Conc_Reqd)
	Sub Hide()
		SetConcealedState(this, True)

	Sub Show()
		SetConcealedState(this, False)

PageLabel "Inputs" 
	TextLabel , "  ---Requirements---" 
	Checkbox  Initialise*
	String	  FeederTagName*{Tag}
	REAL	  StreamFlowRate_Reqd*("Qv", "m^3/h")<0.001,>
	REAL	  Guess_Density**("Rho", "kg/m^3"){Comment("Initial Guess")}<1000,>
	REAL	  Stream_Density@("Rho", "kg/m^3"), NewDensity@@("Rho", "kg/m^3")
	REAL	  Basis_MassFlow**("Qm", "t/h"){Comment("Basis used to workout Mass fraction")}<1000,>
	REAL	  Total_NonWaterFlow@@("Qm", "t/h")
	REAL	  H2O_MassFlow@@("Qm", "t/h"){Comment("by difference")}
	REAL	  Total_BasisFlow@@("Qm", "t/h")
	REAL	  H2O_MassFrac@@("Frac", "%"){Comment("by difference")}
	TextLabel ,"  ---Define Aqueous Compounds, excluding Water---"
	Byte	  NumberOfCompounds*{Comment("excluding water")}, ClassInstanceCount@
	TextLabel "  ---------------------------------------------------------------------------"
	TextLabel "  CompoundTag : Please enter Valid Aqueous compound, e.g. Fe2[SO4]3 "
	TextLabel "  ElementTag  : Please enter Valid Element, e.g. Fe "
	TextLabel "  Ratio: Number of Moles of Element in Compound , e.g. Fe2[SO4]3 / Fe3+ = 2 "	
	TextLabel "  ---------------------------------------------------------------------------"
	Class_CompoundDef #Compound[20]
	Byte	  i, j, k, n
	String	  ReqdSpecie  
	long	  NumSpecies, LiqPhaseIndex, SpeciePhase, x
 Sub InitialiseSolution()
 ;--- Set Stream Flowrate, assume volumetric flowrate is used.
  	Initialise = 1
	ClassInstanceCount = ClassCount({Compound})
	ForEachClass(Compound, init())
 ;--- Preset all aqueous species to 0%, water to 100%
	NumSpecies = SDB.SpecieCount()      
	LiqPhaseIndex = SDB.FindPhase("l") 
	x = 0
	while (x < Numspecies)
	  SpeciePhase = SDB.SpPhaseNo(x)              
	  if (SpeciePhase == LiqPhaseIndex)
		ReqdSpecie = SDB.SpSymbol(x)         
		[Concatenate(FeederTagName,".Content.MF:Ph.", ReqdSpecie ," (%Liq)")] = 0
	  x = x + 1
	[Concatenate(FeederTagName,".Content.MF:Ph.H2O(l) (%Liq)")] =  100
 ;--- Show the required compound tags 
	n = 0 
 	While n < ClassInstanceCount
	  if (n<=(NumberOfCompounds))
	  n = n + 1	
 ;--- Initialise Feedrate if no feed has been defined, a value is needed to calculate concentration 	
	[Concatenate(FeederTagName,".QvReqd (m^3/h)")] = StreamFlowRate_Reqd
 ;---- Initialise Density
	If (Stream_Density < Guess_Density)
	  Stream_Density = Guess_Density

;--- This logic executed at EVERY step ---
  If Stream_Density <> NewDensity  OR NewDensity < 0.1  OR Initialise
    Stream_Density = NewDensity
  ;Calculates the mass flow of non water aqueous species based on current density
    i = 0
    Total_NonWaterFlow = 0
    While i < (NumberOfCompounds)
  	Total_NonWaterFlow = Total_NonWaterFlow + Compound[i].MassFlow
  	i = i + 1
  ;Calculates the mass flow of water based on current density
    H2O_MassFlow    = Basis_MassFlow * (Stream_Density/Basis_MassFlow) - Total_NonWaterFlow
    Total_BasisFlow = H2O_MassFlow + Total_NonWaterFlow
  ;Calculates	and sets the mass fraction of the aqueous species
    k = 0
    While k < (NumberOfCompounds)
  	Compound[k].MassFrac 	= Compound[k].MassFlow / Total_BasisFlow * 100
  	[Concatenate(FeederTagName,".Content.MF:Ph.",Compound[k].CompoundTag,"(aq) (%Liq)")] = Compound[k].MassFrac
  	k = k + 1
    H2O_MassFrac = H2O_MassFlow / Total_BasisFlow * 100
    [Concatenate(FeederTagName,".Content.MF:Ph.H2O(l) (%Liq)")] = H2O_MassFrac
    Initialise = 0
  NewDensity = [Concatenate(FeederTagName,".QProd.Rho (kg/m^3)")]

 Sub TerminateSolution()
 ;--- Gets the actual concentration when the project is stopped, Gets the Concentration of Compound or Element, based on the defined method.
	j= 0
	While j < (NumberOfCompounds)
	  Compound[j].Actual_Conc = [Concatenate(FeederTagName,".QProd.Cnc:Ph.",Compound[j].CompoundTag, "(aq) (g/L)")]
	  Compound[j].Actual_Conc = IIF(Compound[j].Elemental_Conc, Compound[j].Actual_Conc / Compound[j].MW_Comp * (Compound[j].MW_Ele * Compound[j].Ratio), Compound[j].Actual_Conc)
	  j= j + 1
 	n = 0
 	While n < ClassInstanceCount
      if (n>=(NumberOfCompounds))
	  n = n + 1	


Using the Aqueous Feed Concentration Calculator in a Project


  1. Add a General Controller in the project and Load in the pgm file above.
  2. Fill in the Feeder Tag Name
  3. Specify a Stream Flowrate (must have a flow to complete the calculations)
  4. Specify the Number of aqueous compounds to be defined (excluding water)
  5. Fill in the compound information (per compound)
    • Define the compound, must be a valid compound in the project in the (aq) form.
    • Define the required concentration in g/L @ Temperature.
    • If g/L @25°C values are needed, simply set the Feeder T = 25 °C
    • If elemental concentration is used, tick the Elemental_Conc checkbox and defined the Element Tag as well as the molar ratio (compound : Element)
  6. When all the data is filled in, press OK to save the changes
  7. Run the project. SysCAD will adjust the composition in the nominated Feeder to meet the required concentration.


  • The number of converged iterations within the project may need to be increased for this controller to achieve its setpoints in the downstream pipe.
  • In this example PGM, we have allowed up to 20 aqueous compounds, we have used the subroutine "Hide" to conceal any unused blank input fields. If you want to run the aqueous calculation again by adding more compounds, you may have to press the "Show Concealed" button the on "GControl" tab first to show the concealed fields. Alternatively, you can solve the project for at least 1 iteration to get the PGM to unhide the concealed input fields.


Aq Calc PGM139.png

  1. Set the PGM as per instructions in the last heading.
  2. Start SysCAD solve. SysCAD will use the PGM calculation to adjust the mass fractions in the Feeder Dsp Tab.
  3. The concentrations values are fetched by the PGM file when SysCAD stops.


  • Use the calculator to determine the feed composition. Once this is done, switch OFF the calculator to avoid un-necessary recalculations.