Buildings.Templates.Plants.Controls.PolyvalentHeatPumps

Information

This package contains subsequences that are specific to polyvalent heat pump controls.

Package Content

Name Description
Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.AssertMinimumRuntime AssertMinimumRuntime Assert that polyvalent heat pumps are not short cycling
Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ExtractStagingMatrix ExtractStagingMatrix Extract staging matrix at current stage index of opposite operating mode
Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ModeAlternation ModeAlternation SHC and single mode alternation
Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.StagingParameters StagingParameters  
Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.Validation Validation  

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.AssertMinimumRuntime Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.AssertMinimumRuntime

Assert that polyvalent heat pumps are not short cycling

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.AssertMinimumRuntime

Information

This block asserts that each polyvalent heat pump does not short cycle, based on its heating and cooling on/off commands.

If use_runTim=true (default), it asserts that each mode command remains true for at least dt_min before it turns false.

If use_runTim=false, it asserts that each mode command remains false for at least dt_min before it turns true.

Parameters

TypeNameDefaultDescription
Booleanuse_runTimtrueSet to true to assert minimum runtime, false for minimum off time
IntegernUni Number of units
Realdt_min10*60Minimum runtime or off-time [s]
Stringmessageif use_runTim then "Polyvale...Warning message

Connectors

TypeNameDescription
input BooleanInputu1Hea[nUni]Polyvalent HP heating on/off command
input BooleanInputu1Coo[nUni]Polyvalent HP cooling on/off command

Modelica definition

block AssertMinimumRuntime "Assert that polyvalent heat pumps are not short cycling" parameter Boolean use_runTim = true "Set to true to assert minimum runtime, false for minimum off time"; parameter Integer nUni(final min=1) "Number of units"; parameter Real dt_min(final min=0, final unit="s") = 10 * 60 "Minimum runtime or off-time"; parameter String message = if use_runTim then "Polyvalent HP minimum runtime is not met." else "Polyvalent HP minimum off-time is not met." "Warning message"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Hea[nUni] "Polyvalent HP heating on/off command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Coo[nUni] "Polyvalent HP cooling on/off command"; Buildings.Controls.OBC.CDL.Logical.TrueFalseHold holHea[nUni](each final trueHoldDuration=if use_runTim then dt_min else 0, each final falseHoldDuration=if use_runTim then 0 else dt_min) "Heating command held for minimum runtime or off-time"; Buildings.Controls.OBC.CDL.Logical.Xor xorHea[nUni] "True if heating command differs from held command"; Buildings.Controls.OBC.CDL.Logical.TrueFalseHold holCoo[nUni]( each final trueHoldDuration=if use_runTim then dt_min else 0, each final falseHoldDuration=if use_runTim then 0 else dt_min) "Cooling command held for minimum runtime or off-time"; Buildings.Controls.OBC.CDL.Logical.Xor xorCoo[nUni] "True if cooling command differs from held command"; Buildings.Controls.OBC.CDL.Logical.Nor nor[nUni] "True if minimum runtime or off-time is met"; Buildings.Controls.OBC.CDL.Utilities.Assert assRunTim[nUni]( each message=message) "Assert that minimum runtime or off-time is met"; equation connect(u1Hea, holHea.u); connect(u1Hea, xorHea.u1); connect(holHea.y, xorHea.u2); connect(u1Coo, holCoo.u); connect(u1Coo, xorCoo.u1); connect(holCoo.y, xorCoo.u2); connect(xorHea.y, nor.u1); connect(xorCoo.y, nor.u2); connect(nor.y, assRunTim.u); end AssertMinimumRuntime;

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ExtractStagingMatrix Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ExtractStagingMatrix

Extract staging matrix at current stage index of opposite operating mode

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ExtractStagingMatrix

Information

Given the pre-computed staging matrix sta (either staCoo or staHea from Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.StagingParameters) and the current stage index u of the opposite operating mode, this block extracts the corresponding nSta × nEqu slice of normalized equipment fractions for all non-zero stages of the primary mode.

The number of stages nSta is recovered from the row count nRow = (nSta + 1) ⋅ nSta by solving the resulting quadratic:

nSta = ⌊(1 + √(1 + 4 ⋅ nRow)) / 2⌋ - 1

nEqu equals the number of columns.

The output matrix corresponds to that specified in the documentation of Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable and can therefore be consumed by this block.

If is_transpose = true, the block outputs the transpose of the staging matrix, with dimensions nEqu × nSta.

Parameters

TypeNameDefaultDescription
Realsta[:, :] Partially flattened (2D) staging matrix [(nSta+1)*nSta, nEqu], row-major over (iHea, iCoo)
Booleanis_transposefalseSet to true to output the transpose of the staging matrix

Connectors

TypeNameDescription
input IntegerInputuStage index of opposite mode (from 0 to stage number)
output RealOutputy[if is_transpose then nEqu else nSta, if is_transpose then nSta else nEqu] 

Modelica definition

block ExtractStagingMatrix "Extract staging matrix at current stage index of opposite operating mode" parameter Real sta[:, :] "Partially flattened (2D) staging matrix [(nSta+1)*nSta, nEqu], row-major over (iHea, iCoo)"; parameter Boolean is_transpose = false "Set to true to output the transpose of the staging matrix"; final parameter Integer nRow = size(sta, 1) "Number of rows"; final parameter Integer nEqu = size(sta, 2) "Equipment count"; final parameter Integer nSta = integer((1 + sqrt(1 + 4 * nRow)) / 2) - 1 "Number of stage"; final parameter Integer nOut = nEqu * nSta "Intermediary parameter for matrix operations"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput u "Stage index of opposite mode (from 0 to stage number)"; Buildings.Controls.OBC.CDL.Interfaces.RealOutput y[if is_transpose then nEqu else nSta, if is_transpose then nSta else nEqu]; Buildings.Controls.OBC.CDL.Reals.Sources.Constant conStaCoo[nOut, nRow]( final k=if is_transpose then {sta[r, div(p - 1, nSta) + 1] for r in 1:nRow, p in 1:nOut} else {sta[r, mod(p - 1, nEqu) + 1] for r in 1:nRow, p in 1:nOut}) "Per-output column of sta (selected by iEqu)"; Buildings.Controls.OBC.CDL.Routing.RealExtractor extIndRea[nOut]( each final nin=nRow) "Scalar extraction along the row dimension"; // row index = (u-1)*nSta + iCoo Buildings.Controls.OBC.CDL.Integers.Sources.Constant nStaCst(final k=nSta); Buildings.Controls.OBC.CDL.Integers.Multiply mulInt "(u-1)*nSta"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRep( final nout=nOut); Buildings.Controls.OBC.CDL.Integers.Sources.Constant offCst[nOut]( final k=if is_transpose then {mod(p - 1, nSta) + 1 for p in 1:nOut} else {div(p - 1, nEqu) + 1 for p in 1:nOut}) "Per-output iCoo (row within heating stage)"; Buildings.Controls.OBC.CDL.Integers.Add addInt[nOut] "Add offset to stage index"; Buildings.Controls.OBC.CDL.Routing.RealExtractSignal extReaSig[if is_transpose then nEqu else nSta]( each final nin=nOut, each final nout=if is_transpose then nSta else nEqu, final extract=if is_transpose then {(i - 1) * nSta + j for j in 1:nSta, i in 1:nEqu} else {(j - 1) * nEqu + i for i in 1:nEqu, j in 1:nSta}) "Extract staging matrix"; Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator reaVecRep( final nin=nOut, final nout=if is_transpose then nEqu else nSta) "Replicate for extraction at next step"; equation connect(nStaCst.y, mulInt.u2); connect(u, mulInt.u1); connect(mulInt.y, intScaRep.u); connect(intScaRep.y, addInt.u1); connect(offCst.y, addInt.u2); connect(addInt.y, extIndRea.index); connect(conStaCoo.y, extIndRea.u); connect(extIndRea.y, reaVecRep.u); connect(reaVecRep.y, extReaSig.u); connect(extReaSig.y, y); end ExtractStagingMatrix;

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ModeAlternation Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ModeAlternation

SHC and single mode alternation

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ModeAlternation

Information

Heating-only

When a stage transition yields a change in both the number of staged units in heating mode and the number of staged units in SHC mode, i.e., a unit switches from/to heating-only to/from SHC mode: the units previously enabled in cooling mode are removed from the staging order for the heating enable logic. The heating enable logic can thus disable a unit previously enabled in either heating or SHC mode, or enable a unit previously enabled in SHC mode or disabled.

At any other time, the units previously enabled in cooling or SHC mode are removed from the staging order for the heating enable logic. The heating enable logic can thus only disable a unit previously enabled in heating mode, or enable a unit previously disabled.

Cooling-only

When a stage transition yields a change in both the number of staged units in cooling mode and the number of staged units in SHC mode, i.e., a unit switches from/to cooling-only to/from SHC mode: the units previously enabled in heating mode are removed from the staging order for the cooling enable logic. The cooling enable logic can thus disable a unit previously enabled in either cooling or SHC mode, or enable a unit previously enabled in SHC mode or disabled.

At any other time, the units previously enabled in heating or SHC mode are removed from the staging order for the cooling enable logic. The cooling enable logic can thus only disable a unit previously enabled in cooling mode, or enable a unit previously disabled.

SHC

At any time, the units currently enabled in heating or cooling mode are removed from the staging order for the SHC enable logic. The SHC enable logic can thus only disable a unit enabled in SHC mode, or enable a disabled unit. It cannot disable a unit that has been enabled in heating or cooling mode.

Details

Staging logic requirement

The alternation logic in this block assumes that stage transitions are elementary in terms of staged unit counts: either the number of staged units changes by one in exactly one operating mode – a unit is staged on or off – or the number of staged units decreases by one in one operating mode and increases by one in another operating mode – a mode switch at plant level, which the enable logics may realize with two distinct units. The staging logic shall preclude any other transition. Under this assumption, a simultaneous change in the number of staged units in a single mode and in SHC mode identifies without ambiguity a mode switch between that mode and SHC mode.

Resolution order

The heating and cooling enable logics resolve against the unit assignment prior to the stage transition, whereas the SHC enable logic resolves against the resulting heating and cooling enable commands. This establishes the resolution order between the three logics: at a transition where a unit switches between a single mode and SHC mode, the unit claimed by the heating or cooling enable logic is removed from the staging order for the SHC enable logic at the same time instant.

Note that a unit switching from SHC mode to a single mode, or conversely, is not subject to the minimum off-time required by Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability for the alternation between heating-only and cooling-only mode.

Parameters

TypeNameDefaultDescription
IntegernPhp Number of polyvalent HP

Connectors

TypeNameDescription
input IntegerInputuIdxSor[nPhp]Indices of units sorted by increasing runtime
input IntegerInputnHeaNumber of units to be staged in heating mode
input IntegerInputnCooNumber of units to be staged in cooling mode
input IntegerInputnShcNumber of units to be staged in SHC mode
input BooleanInputu1Hea[nPhp]Enable command of each unit in heating mode, indexed by unit
input BooleanInputu1Coo[nPhp]Enable command of each unit in cooling mode, indexed by unit
input BooleanInputu1Shc[nPhp]Enable command of each unit in SHC mode, indexed by unit
output IntegerOutputyIdxSorHea[nPhp]Staging order for the heating enable logic
output IntegerOutputyIdxSorCoo[nPhp]Staging order for the cooling enable logic
output IntegerOutputyIdxSorShc[nPhp]Staging order for the SHC enable logic

Modelica definition

block ModeAlternation "SHC and single mode alternation" parameter Integer nPhp(final min=1) "Number of polyvalent HP"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uIdxSor[nPhp] "Indices of units sorted by increasing runtime"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput nHea "Number of units to be staged in heating mode"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput nCoo "Number of units to be staged in cooling mode"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput nShc "Number of units to be staged in SHC mode"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Hea[nPhp] "Enable command of each unit in heating mode, indexed by unit"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Coo[nPhp] "Enable command of each unit in cooling mode, indexed by unit"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Shc[nPhp] "Enable command of each unit in SHC mode, indexed by unit"; Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yIdxSorHea[nPhp]( start=1:nPhp) "Staging order for the heating enable logic"; Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yIdxSorCoo[nPhp]( start=1:nPhp) "Staging order for the cooling enable logic"; Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yIdxSorShc[nPhp]( start=1:nPhp) "Staging order for the SHC enable logic"; Buildings.Controls.OBC.CDL.Integers.Change chaHea "Detect a change in the number of units staged in heating mode"; Buildings.Controls.OBC.CDL.Integers.Change chaCoo "Detect a change in the number of units staged in cooling mode"; Buildings.Controls.OBC.CDL.Integers.Change chaShc "Detect a change in the number of units staged in SHC mode"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator repHea( final nout=nPhp) "Replicate heating count change to all units"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator repCoo( final nout=nPhp) "Replicate cooling count change to all units"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator repShc( final nout=nPhp) "Replicate SHC count change to all units"; Buildings.Controls.OBC.CDL.Logical.And andHea[nPhp] "True at a heating-only to/from SHC mode switch"; Buildings.Controls.OBC.CDL.Logical.And andCoo[nPhp] "True at a cooling-only to/from SHC mode switch"; Buildings.Controls.OBC.CDL.Logical.Or orSin[nPhp] "Units enabled in heating or cooling mode"; Buildings.Controls.OBC.CDL.Logical.Pre preHea[nPhp] "Enable command of each unit in heating mode prior to stage transition"; Buildings.Controls.OBC.CDL.Logical.Pre preCoo[nPhp] "Enable command of each unit in cooling mode prior to stage transition"; Buildings.Controls.OBC.CDL.Logical.Pre preShc[nPhp] "Enable command of each unit in SHC mode prior to stage transition"; Buildings.Templates.Plants.Controls.StagingRotation.BaseClasses.RemoveFromStagingOrder remHeaRes( final nUni=nPhp) "Restrictive heating order: remove units previously enabled in cooling mode"; Buildings.Templates.Plants.Controls.StagingRotation.BaseClasses.RemoveFromStagingOrder remHeaSwi( final nUni=nPhp) "Heating order at mode switch: also remove units previously enabled in SHC mode"; Buildings.Templates.Plants.Controls.StagingRotation.BaseClasses.RemoveFromStagingOrder remCooRes( final nUni=nPhp) "Restrictive cooling order: remove units previously enabled in heating mode"; Buildings.Templates.Plants.Controls.StagingRotation.BaseClasses.RemoveFromStagingOrder remCooSwi( final nUni=nPhp) "Cooling order at mode switch: also remove units previously enabled in SHC mode"; Buildings.Templates.Plants.Controls.StagingRotation.BaseClasses.RemoveFromStagingOrder remShc( final nUni=nPhp) "SHC order: remove units currently enabled in heating or cooling mode"; Buildings.Controls.OBC.CDL.Integers.Switch swiHea[nPhp] "Apply the mode-switch heating order at a mode switch, the restrictive one otherwise"; Buildings.Controls.OBC.CDL.Integers.Switch swiCoo[nPhp] "Apply the mode-switch cooling order at a mode switch, the restrictive one otherwise"; equation connect(nHea, chaHea.u); connect(nCoo, chaCoo.u); connect(nShc, chaShc.u); connect(chaHea.y, repHea.u); connect(chaCoo.y, repCoo.u); connect(chaShc.y, repShc.u); connect(repHea.y, andHea.u1); connect(repShc.y, andHea.u2); connect(repCoo.y, andCoo.u1); connect(repShc.y, andCoo.u2); connect(u1Hea, preHea.u); connect(u1Coo, preCoo.u); connect(u1Shc, preShc.u); connect(u1Hea, orSin.u1); connect(u1Coo, orSin.u2); connect(uIdxSor, remHeaRes.uIdxSor); connect(preCoo.y, remHeaRes.u1); connect(remHeaRes.yIdxSor, remHeaSwi.uIdxSor); connect(preShc.y, remHeaSwi.u1); connect(uIdxSor, remCooRes.uIdxSor); connect(preHea.y, remCooRes.u1); connect(remCooRes.yIdxSor, remCooSwi.uIdxSor); connect(preShc.y, remCooSwi.u1); connect(uIdxSor, remShc.uIdxSor); connect(orSin.y, remShc.u1); connect(remHeaRes.yIdxSor, swiHea.u1); connect(andHea.y, swiHea.u2); connect(remHeaSwi.yIdxSor, swiHea.u3); connect(remCooRes.yIdxSor, swiCoo.u1); connect(andCoo.y, swiCoo.u2); connect(remCooSwi.yIdxSor, swiCoo.u3); connect(swiHea.y, yIdxSorHea); connect(swiCoo.y, yIdxSorCoo); connect(remShc.yIdxSor, yIdxSorShc); end ModeAlternation;

Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.StagingParameters Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.StagingParameters

Information

This block pre-computes all staging parameters for a plant with nHP standard reversible heat pumps and nPHP polyvalent heat pumps (capable of simultaneous heating and cooling, SHC).

Fundamental assumptions

Within each equipment set (reversible HPs and polyvalent HPs), all units are assumed to be equally sized and are treated as lead/lag alternates. Adding one unit of either type therefore contributes one additional stage of capacity, so the maximum number of plant stages is nSta = nHP + nPHP. Heating and cooling stages are tracked independently, each ranging over {0, …, nSta}, since the same pool of units can serve either load.

For each combination of active heating and cooling stages (iHea, iCoo) with iHea, iCoo ∈ {0, …, nSta}, the block resolves how many units operate in each mode by applying the following assignment rules in order.

1. SHC assignment

Polyvalent HPs are assigned to simultaneous heating and cooling first, saturating at the available count and at the smaller of the two stage indices (since each SHC unit satisfies one heating stage and one cooling stage simultaneously):

nSHCPHP = min(min(iHea, iCoo), nPHP)

The residual heating and cooling stages after SHC assignment are:

iresHea = iHea - nSHCPHP,    iresCoo = iCoo - nSHCPHP

2. Heating assignment

Standard HPs cover the residual heating stage first:

nHeaHP = min(iresHea, nHP)

Any remaining residual heating stage is covered by polyvalent HPs operating in heating-only mode (drawn from those not already in SHC):

nHeaPHP = min(iresHea - nHeaHP,  nPHP - nSHCPHP)

3. Cooling assignment

Standard HPs not used for heating are assigned to the residual cooling stage:

nCooHP = min(iresCoo,  nHP - nHeaHP)

Remaining polyvalent HPs (neither in SHC nor heating-only) cover any unmet cooling stage:

nCooPHP = min(iresCoo - nCooHP,  nPHP - nSHCPHP - nHeaPHP)

Feasibility

A stage combination is feasible if and only if both residual stages are fully covered by the assigned units:

iresHea = nHeaHP + nHeaPHP    and    iresCoo = nCooHP + nCooPHP

Combinations that cannot be satisfied with the available equipment (e.g., requiring more simultaneous heating and cooling stages than there are polyvalent HPs) are flagged in is_feasible and receive zero weights in the staging matrices.

Staging matrices

The parameters staCoo and staHea pack feasible stage combinations into matrices consumed by the equipment enable logic. Each has (nSta + 1) × nSta rows (one per non-zero stage transition) and nHP + 2 nPHP columns, ordered as: standard HPs | polyvalent HPs (cooling- or heating-only) | polyvalent HPs (SHC).

For staCoo, row r corresponds to iHea = ⌊(r - 1) / nSta⌋ (outer index, 0 ≤ iHea ≤ nSta) and iCoo = (r - 1) mod nSta + 1 (inner index, 1 ≤ iCoo ≤ nSta). Column values are normalized fractions, as specified in the documentation of Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable.:

A row of zeros indicates an infeasible stage combination. staHea follows the same column layout but with iCoo as the outer index and iHea as the inner index, and the heating counts substituted for the cooling counts.

Parameters

TypeNameDefaultDescription
IntegernHp Number of HP (excluding polyvalent HP)
IntegernPhp Number of polyvalent HP

Modelica definition

block StagingParameters parameter Integer nHp "Number of HP (excluding polyvalent HP)"; parameter Integer nPhp "Number of polyvalent HP"; final parameter Integer nSta = nHp + nPhp "Number of cooling or heating stages (excluding stage 0)"; final parameter Integer staPhp[nSta + 1, nSta + 1] = {min( iHea, iCoo) for iCoo in 0:nSta, iHea in 0:nSta} "Minimum between cooling and heating stage"; final parameter Integer staHeaRes[nSta + 1, nSta + 1] = {iHea - nPhpShc[iHea + 1, iCoo + 1] for iCoo in 0:nSta, iHea in 0:nSta} "Residual heating stage count after SHC assignment"; final parameter Integer staCooRes[nSta + 1, nSta + 1] = {iCoo - nPhpShc[iHea + 1, iCoo + 1] for iCoo in 0:nSta, iHea in 0:nSta} "Residual cooling stage count after SHC assignment"; final parameter Integer nHpAva[nSta + 1, nSta + 1] = {nHp - nHpHea[iHea + 1, iCoo + 1] for iCoo in 0:nSta, iHea in 0:nSta} "Number of HP still available after heating assignment"; final parameter Integer nPhpAva[nSta + 1, nSta + 1] = {nPhp - nPhpShc[iHea + 1, iCoo + 1] for iCoo in 0:nSta, iHea in 0:nSta} "Number of polyvalent HP still available after SHC assignment"; final parameter Integer nHpHea[nSta + 1, nSta + 1] = {min( staHeaRes[iHea + 1, iCoo + 1], nHp) for iCoo in 0:nSta, iHea in 0:nSta} "Number of HP in heating mode"; final parameter Integer nHpCoo[nSta + 1, nSta + 1] = {min( staCooRes[iHea + 1, iCoo + 1], nHpAva[iHea + 1, iCoo + 1]) for iCoo in 0:nSta, iHea in 0:nSta} "Number of HP in cooling mode"; final parameter Integer nPhpHea[nSta + 1, nSta + 1] = {min( staHeaRes[iHea + 1, iCoo + 1] - nHpHea[iHea + 1, iCoo + 1], nPhpAva[iHea + 1, iCoo + 1]) for iCoo in 0:nSta, iHea in 0:nSta} "Number of polyvalent HP in heating-only mode"; final parameter Integer nPhpCoo[nSta + 1, nSta + 1] = {min( staCooRes[iHea + 1, iCoo + 1] - nHpCoo[iHea + 1, iCoo + 1], nPhpAva[iHea + 1, iCoo + 1] - nPhpHea[iHea + 1, iCoo + 1]) for iCoo in 0:nSta, iHea in 0:nSta} "Number of polyvalent HP in cooling-only mode"; final parameter Integer nPhpShc[nSta + 1, nSta + 1] = {min( staPhp[iHea + 1, iCoo + 1], nPhp) for iCoo in 0:nSta, iHea in 0:nSta} "Number of polyvalent HP in SHC mode"; final parameter Boolean is_feasible[nSta + 1, nSta + 1] = {(staHeaRes[iHea + 1, iCoo + 1] - nHpHea[iHea + 1, iCoo + 1] - nPhpHea[iHea + 1, iCoo + 1] == 0) and (staCooRes[iHea + 1, iCoo + 1] - nHpCoo[iHea + 1, iCoo + 1] - nPhpCoo[iHea + 1, iCoo + 1] == 0) for iCoo in 0:nSta, iHea in 0:nSta} "True if the stage combination is achievable"; final parameter Real staCoo[(nSta + 1) * nSta, nHp + 2 * nPhp] = {(if not is_feasible[div(r - 1, nSta) + 1, mod(r - 1, nSta) + 2] then 0 elseif iEqu <= nHp then nHpCoo[div(r - 1, nSta) + 1, mod(r - 1, nSta) + 2] / max(nHp, 1) elseif iEqu <= nHp + nPhp then nPhpCoo[div(r - 1, nSta) + 1, mod(r - 1, nSta) + 2] / max(nPhp, 1) else nPhpShc[div(r - 1, nSta) + 1, mod(r - 1, nSta) + 2] / max( nPhp, 1)) for iEqu in 1:nHp + 2 * nPhp, r in 1:(nSta + 1) * nSta} "Cooling staging matrix – row-major over (0≤iHea outer, 1≤iCoo inner), 0 if infeasible"; final parameter Real staHea[(nSta + 1) * nSta, nHp + 2 * nPhp] = {(if not is_feasible[mod(r - 1, nSta) + 2, div(r - 1, nSta) + 1] then 0 elseif iEqu <= nHp then nHpHea[mod(r - 1, nSta) + 2, div(r - 1, nSta) + 1] / max(nHp, 1) elseif iEqu <= nHp + nPhp then nPhpHea[mod(r - 1, nSta) + 2, div(r - 1, nSta) + 1] / max(nPhp, 1) else nPhpShc[mod(r - 1, nSta) + 2, div(r - 1, nSta) + 1] / max( nPhp, 1)) for iEqu in 1:nHp + 2 * nPhp, r in 1:(nSta + 1) * nSta} "Heating staging matrix – row-major over (0≤iCoo outer, 1≤iHea inner), 0 if infeasible"; end StagingParameters;