How to perform an Overall Mass Balance (Build136)

From SysCAD Documentation
Jump to navigation Jump to search
Warning! Page you're reading is outdated or was archived and very likely is referring to older version of the software. Please navigate to the most recent version instead.

Navigation: PGMs - Example PGM Files - PGM Files using Class and Functions

Related Links: Tag Select Class, Species Mass Balance, Elemental Mass Balance, Example PGM Files

This page is for SysCAD 9.3 Build 136 or earlier. For SysCAD 9.3 Build 137 or later please see How to perform an Overall Mass Balance


Steady-State Project Overall Mass Balance

It is often important to perform an overall mass balance to account for the total inputs and total outputs. Here we will show how to obtain a quick balance of the overall mass by adding a PGM file using the TagSelect Class to sum up the total in and out and perform a balance.

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

NOTES:

Example 1: Steady-State Project Mass Balance

This example is for users using Build 136 or earlier. For users using the latest build of SysCAD, please see Example 1 for a simpler version of this file using the GetValue function call (available in Build137 or later).

TagSelect Inputs, Outputs
integer   [email protected], [email protected], i
real      [email protected]("Qm","t/h"), [email protected]("Qm","t/h"), [email protected]("Qm","t/h")
CheckBox  [email protected]
string    flow_tag
 
Sub    CalcMassBalance()
  ; find all true feeders (not connected) and makeup sources 
  OK = Inputs.Exec("([UnitType]=='FeederSink' AND [State]==1) OR [UnitType] == 'MakeupSource'", 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),".QProd.Qm (t/h)" )
      FlowIn = FlowIn + [flow_tag]
      i = i + 1
  endwhile 
 
  ; find all true sinks (not connected)
  OK = Outputs.Exec("[UnitType]=='FeederSink' AND [State]==2", 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),".QProd.Qm (t/h)" )
     FlowOut = FlowOut + [flow_tag]
     i = i + 1
  endwhile 
  
  ; perform mass balance
  Balance = FlowIn - FlowOut
EndSub

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

$ ; --- end of file ---

Dynamic Project Overall Mass Balance

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 2: Dynamic Project Mass Balance

This example is for users using Build 136 or earlier. For users using the latest build of SysCAD, please see Example 2 for a simpler version of this file using the GetValue function call (available in Build137 or later).

TagSelect Inputs, Outputs, Surges, Tears
integer [email protected], [email protected], [email protected], [email protected]
real [email protected]("M","t"), [email protected]("M","t"), [email protected]("M","t"), [email protected]("M","t"), [email protected]("M","t"), [email protected]("M","t"), [email protected]
bit [email protected],Recalc
integer i
string TempTag,TempTag2
 
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 total number of inputs 
  InCount = Inputs.GetLen()
  
  ; find all true sinks (not connected)
  OK = Outputs.Exec("[UnitType]=='FeederSink' AND [State]==2 AND [Active]==1", false, false)
  ; find total number of outputs
  OutCount = Outputs.GetLen()
  
  ; find all surges (tanks)
  OK = Surges.Exec("[UnitType]=='Tank-1' AND [Active]==1", false, false)
  ; find total number of surges
  SurgeCount = Surges.GetLen()
  
  ; find all Tears
  OK = Tears.Exec("[UnitType]=='Flange' AND [SubClass]=='Tear' AND [Active]==1", false, false)
  ; find total number of tears
  TearCount = Tears.GetLen()
  
  ; 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
  if ["$Solver.Dyn.Scenario.Start.Preset"]
        Recalc  = TRUE
  else
        Recalc = FALSE
  endif
  
EndSub

Sub CalcStartMass()
  ; sum all Contents 
  i = 0
  StartSurgeMass = 0
  while(i<SurgeCount)
   TempTag = Concatenate(Surges.Tag(i),".Content.Mt (t)")
   StartSurgeMass = StartSurgeMass + [TempTag]
   i = i + 1
  endwhile
EndSub

Sub ReCalcStartMass()
  ; sum all Contents, recalculation after first iteration (due to Preset being used) 
  i = 0
  StartSurgeMass = 0
  while(i<SurgeCount)
   TempTag = Concatenate(Surges.Tag(i),".Content.Mt (t)")
   TempTag2 = Concatenate(Surges.Tag(i),".QmAcc (t/s)")
   StartSurgeMass = StartSurgeMass + [TempTag] - ([TempTag2]*DeltaTime())
   i = i + 1
  endwhile
EndSub

Sub CalcMassBalance()
  ; sum all inputs 
  i = 0
  MassIn = 0
  while(i<InCount)
   TempTag = Concatenate(Inputs.Tag(i),".QProd.Total.Mt (t)")
   MassIn = MassIn + [TempTag]
   i = i + 1
  endwhile
  
  ; sum all outputs 
  i = 0
  MassOut = 0
  while(i<OutCount)
   TempTag = Concatenate(Outputs.Tag(i),".QProd.Total.Mt (t)")
   MassOut = MassOut + [TempTag]
   i = i + 1
  endwhile
  
  ; sum all Contents 
  i = 0
  SurgeMass = 0
  while(i<SurgeCount)
   TempTag = Concatenate(Surges.Tag(i),".Content.Mt (t)")
   SurgeMass = SurgeMass + [TempTag]
   i = i + 1
  endwhile
  
  ; sum all accumulated mass in Tears 
  i = 0
  TearMass = 0
  while(i<TearCount)
   TempTag = Concatenate(Tears.Tag(i),".Tear.Accum.Mt (t)")
   TearMass = TearMass + [TempTag]
   i = i + 1
  endwhile
  
  ; 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 ---