Dynamic Project Overall Mass Balance

From SysCAD Documentation
Jump to navigation Jump to search

Navigation: PGMs ➔ Example PGM Files ➔ Dynamic 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: Example PGMs for Dynamic Projects


The following examples show how the Tag Select Class could be used to perform a simple mass balance in a dynamic project.

  • This is best performed after the last iteration using the Terminate Solution sub-routine.
  • It can also be performed every iteration for debugging.
  • The main difference to the steady-state mass balance shown above is that is needs to take account of material in surges and tears (in dynamic, tears can have surge).

Notes:

Example: Dynamic Project Mass Balance

This example is coded using the GetValue function call, available in build137 or later. For users using earlier builds of SysCAD, please see Build136 Example2

PageLabel(MassBal)
   TextLabel(,)
   TagSelect Inputs, Outputs, Surges, Tears
   Array     InputList, OutputList, SurgeList, TearList
   TextLabel(,)
   real      MassIn@("M","t"), MassOut@("M","t")
   real      StartSurgeMass@("M","t"), SurgeMass@("M","t"), TearMass@("M","t")
   real      MassBalanceError@("M","t"), RelativeError@("Frac", "Frac")
   real      Preset_surge, Preset_acc
   Checkbox  OK@, Recalc@
	
Sub InitMassBalance()
  ;find all true feeders (not connected) and makeup sources
    OK = Inputs.Exec("([UnitType]=='FeederSink' AND [State]==1 AND [Active]==1) OR [UnitType] == 'MakeupSource'", false, false)
  ;find all true sinks (not connected)
    OK = Outputs.Exec("[UnitType]=='FeederSink' AND [State]==2 AND [Active]==1",false, false)
  ;find all surges (tanks)
    OK = Surges.Exec("[UnitType]=='Tank-1' AND [Active]==1", false, false)
  ;find all Tears
    OK = Tears.Exec("[UnitType]=='Flange' AND [SubClass]=='Tear' AND [Active]==1", false, false)
  ;initialise masses
    MassIn = 0.0
    MassOut = 0.0
    StartSurgeMass = 0.0
    SurgeMass = 0.0
    TearMass = 0.0
    MassBalanceError = 0.0
    RelativeError = 0.0
  ;check if recalculation of initial masses will be required because Preset is used
    Recalc = iif(["$Solver.Dyn.Scenario.Start.Preset"]==1, TRUE, FALSE)
EndSub

Sub CalcStartMass()
  ;sum all Contents 
   StartSurgeMass = 0.0
   Surges.GetValues(".Content.Mt (t)", SurgeList)
   StartSurgeMass = SurgeList.Sum()
EndSub

Sub ReCalcStartMass()
  ; sum all Contents, recalculation after first iteration (due to Preset being used) 
  StartSurgeMass = 0
   Surges.GetValues(".Content.Mt (t)", SurgeList)
   Preset_surge = SurgeList.Sum()
   Surges.GetValues(".QmAcc (t/s)", SurgeList)
   Preset_acc = SurgeList.Sum()
   StartSurgeMass = StartSurgeMass + Preset_surge - (Preset_acc*DeltaTime())
EndSub

Sub CalcMassBalance()
  ; sum all inputs 
   MassIn = 0.0
   Inputs.GetValues(".QProd.Total.Mt (t)", InputList)
   MassIn = InputList.Sum()
  ; sum all Outputs 
   MassOut = 0.0
   Outputs.GetValues(".QProd.Total.Mt (t)", OutputList)
   MassOut = OutputList.Sum()
  ; sum all Tank Surge 
   SurgeMass = 0.0
   Surges.GetValues(".Content.Mt (t)", SurgeList)
   SurgeMass = SurgeList.Sum()
  ; sum all Tears  
   TearMass = 0.0
   Tears.GetValues(".Tear.Accum.Mt (t)", TearList)
   TearMass = TearList.Sum()
  ; perform mass balance
   MassBalanceError = MassIn - MassOut + StartSurgeMass - SurgeMass + TearMass
   RelativeError = MassBalanceError/Max(MassIn,MassOut)
EndSub

Sub PreStart() 
 ;--- Logic executed early before first iteration
 InitMassBalance()
EndSub

Sub InitialiseSolution() 
 ;--- Logic executed during initialisation before first iteration
 CalcStartMass()
EndSub

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

if Recalc
   ; recalculate initial mass because Preset used
   ReCalcStartMass()
   Recalc = FALSE
endif

CalcMassBalance() ; include this line to perform mass balance every iteration for debugging

$ ; --- end of file ---