PGM Example - Relaxed Cross Page Connector
Jump to navigation
Jump to search
Navigation: PGMs ➔ Example PGM Files ➔ Relaxed Cross Page Connector
Related Links: Defining a Class
NOTE: Some PGM functions used by this example requires Build 139.32366 or later.
PGM Example - Relaxed Cross Page Connector
This example file allows the user to "break" the existing cross-page connection, and "manually" transfer the sink material flow to the Feeder. This can be useful when the closed loop is very sensitive to flow change, and user can tell the feeder to apply the change "slower". Please note that if the change is too slow, the resulting source and target flows may not match. When that happens, try increase the rate of change or solve for longer.
;--- SysCAD General Controller (PGM) program logic file ---
; Revision: 1 Date: January 2023 Author: SysCAD Team
EnumDropList XPgConnOptions{MassFlow = 0, MassFrac = 1, XpgConnected =2}
class Class_RelaxedCrossPageConnection
ClassAsGroup
TextLabel " ----------------------------------------------------------"
TextLabel " Used to transfer data from a Sink to the Feeder"
TextLabel " ----------------------------------------------------------"
string FeederTag@{Tag}{Comment("Expect a valid Feeder Tag (Class instance name)")}
Bit ValidTag, ValidModelType, ValidReference@
string SourceConnector@{Tag}{Comment("Uses the FeederTag's CrossPage ConnectedTo Tag")}
Bit ValidXPGConTag@
TextBreak
XPgConnOptions ConnectionType*
Memo ConnectionStatus@
TextBreak
real Relaxation*<1e-5,1><<0.5>>{Comment("use < 1 for gradual change")}
TextLabel " NOTE:Relaxation applied when setting the Feeder Flow", " Allows for a slower change for sensitive loops"
TextBreak
TextLabel " Data Checking:"
checkbox Converged@
real RelativeTolerance*("Frac","Frac")<1e-10,1e-2><<0.001>>
real Tolerance*("Qm","kg/s")<1e-10,1e-2><<0.001>>
TextLabel " NOTE:These are done at the Termination step", " Checks if the actual data set matches the source data"
StrArray InputTags{}, OutputTags{}
TextLabel " ----------------------------------------------------------"
TextBreak
Sub CheckVersion()
Bit BuildOK
Const long VersionNumber = 32530
BuildOK = PM.Version(0)>=9 AND PM.Version(1)>=3 AND PM.Version(2)>=139 AND PM.Version(3)>=VersionNumber
If NOT BuildOK
StopSolver("Incorrect version of SysCAD, needs SysCAD9.3 Build139.", IntToStr(VersionNumber)," or later.")
Endif
EndSub
Sub SanityCheck()
Str UnitType
FeederTag = ClassTag()
ValidTag = DynTagExists(Concatenate(FeederTag,".Tag"))
SourceConnector = [Str Concatenate(FeederTag, ".ConnectTo")]
ValidXPGConTag = NOT IsEmpty(SourceConnector)
if (NOT ValidTag)
StopSolver("UnitTag ", FeederTag, " not found!", " Expect Class_instance declared = valid feeder name in the project" )
ValidReference = 0
Elseif (NOT ValidXPGConTag)
StopSolver("Expect '", FeederTag, "' - CrossPage Connection - ConnectedTo field be specified.", " This is used as the SourceConnector " )
ValidReference = 0
else
UnitType = [str concatenate(FeederTag, ".UnitType")]
ValidModelType = (strcmp(UnitType, "FeederSink")==0)
If (NOT ValidModelType)
StopSolver("Expect '", FeederTag, "' to be a FeederSink") ;note single quotes around the tag to enable right-click access from the message window
ValidReference = 0
Else
ValidReference = 1
Endif
Endif
EndSub
sub Init()
integer i
SanityCheck()
CheckVersion()
If ValidReference
If ConnectionType < 2
;ensure the Feeder is not using cross page connection and set to the General operation mode.
[concatenate(FeederTag,".Operation")]=0
[concatenate(FeederTag,".ConnectionOn")] = 0
[concatenate(FeederTag,".CF.When")] = 0
;Allow two extra tags for T and P.
InputTags.SetLen(SDB.SpeciesCount()+2)
OutputTags.SetLen(SDB.SpeciesCount()+2)
i = 0
while (i < SDB.SpeciesCount())
if (ConnectionType == MassFrac)
InputTags.SetAt(i,concatenate(SourceConnector,".QProd.MF.",SDB.SpShortName(i)))
OutputTags.SetAt(i,concatenate(FeederTag,".Content.MF.",SDB.SpShortName(i)))
ConnectionStatus = "Using Relaxation Mode"
else
InputTags.SetAt(i,concatenate(SourceConnector,".QProd.QM.",SDB.SpShortName(i)))
OutputTags.SetAt(i,concatenate(FeederTag,".Content.QM.",SDB.SpShortName(i)))
endif
i = i + 1
EndWhile
InputTags.SetAt(SDB.SpeciesCount(),concatenate(SourceConnector,".QProd.T (C)"))
OutputTags.SetAt(SDB.SpeciesCount(),concatenate(FeederTag,".T_Reqd (C)"))
InputTags.SetAt(SDB.SpeciesCount()+1,concatenate(SourceConnector,".QProd.P (kPa)"))
OutputTags.SetAt(SDB.SpeciesCount()+1,concatenate(FeederTag,".P_Reqd (kPa)"))
else
[concatenate(FeederTag,".ConnectionOn")] = 1
ConnectionStatus = "Using full cross page connection Mode, relaxation not in use."
Endif
Endif
EndSub
sub DoTransfer()
real OldVal
;do the relaxed transfer of mass flow
integer i
If ValidReference and ConnectionType < 2
i = 0
while (i < InputTags.GetLen())
OldVal = [OutputTags[i]]
[OutputTags[i]] = OldVal + Relaxation * ([InputTags[i]] - OldVal)
i = i + 1
EndWhile
Endif
endSub
sub Final_Check()
;ensure it is converged
integer i
If ValidReference and ConnectionType < 2
i = 0
while (i < InputTags.GetLen())
real Out, In, RelErr, Err
Out = [OutputTags[i]]
In = [InputTags[i]]
Err = abs(Out - In)
RelErr = Err/max(In,1e-10)
if ((RelErr > RelativeTolerance) and (Err > Tolerance))
LogError(" '", FeederTag, "' relaxed cross page connection not converged for ",InputTags[i],": ",FltToStr(RelErr*100)," %")
LogError(" '", FeederTag, "' relaxed cross page connection not converged. Maximum error for ",InputTags[i],": ",FltToStr(Err)," kg/s")
Converged = 0
else
Converged = 1
endif
i = i + 1
EndWhile
LogNote(" '", FeederTag, "' using Relaxation mode for cross page connector.")
Endif
EndSub
EndClass
;-----------------------------------------------------
;Using the Class in the project
PageLabel "CrossPageConnection"
TextBreak
;Declare the class instances, here we are using the Feeder tag name as the class instance name.
Class_RelaxedCrossPageConnection From_CCD_UF, From_NiCo_Filter
;Initialise the tags
Sub PreStart()
;In this example, the feeder was setup with cross-page connector previously, so we can fetch the tag as the "SourceConnector".
ForEachClass(Class_RelaxedCrossPageConnection, Init())
EndSub
;Do the mass transfer, this is done every iteration.
ForEachClass(Class_RelaxedCrossPageConnection, DoTransfer())
;Check feeder condition at termination
Sub TerminateSolution()
ForEachClass(Class_RelaxedCrossPageConnection, Final_Check())
EndSub
$