Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater

Sequences for chilled water pump control

Information

This package contains control sequences for chilled water pumps. The implementations are based on section 5.20.6 Primary chilled water pumps, in ASHRAE Guideline 36-2021.

Package Content

Name Description
Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Controller Controller Sequences to control chilled water pumps in primary-only plant system
Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Subsequences Subsequences Chilled water pump control sequences
Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Validation Validation Collection of validation models

Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Controller Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Controller

Sequences to control chilled water pumps in primary-only plant system

Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Controller

Information

Primary chilled water pump control sequence per ASHRAE Guideline 36-2021, section 5.20.6.1 to section 5.20.6.11, except section 3 and 4. It includes:

Parameters

TypeNameDefaultDescription
Booleanhave_heaPumtrueFlag of headered chilled water pumps design: true=headered, false=dedicated
Booleanhave_senDpChiWatRemWirtrueTrue=remote DP sensor hardwired to controller
Booleanhave_WSEfalseTrue: the plant has waterside economizer
IntegernPum2Total number of chilled water pumps
IntegernChi2Total number of chillers
IntegernSen2Total number of remote differential pressure sensors
RealminPumSpe0.1Minimum pump speed
RealmaxPumSpe1Maximum pump speed
Nominal conditions
IntegernPum_nominalnPumTotal number of pumps that operate at design conditions
RealVChiWat_flow_nominal0.5Total plant design chilled water flow rate [m3/s]
Speed controller
SimpleControllercontrollerTypeBuildings.Controls.OBC.CDL.T...Type of controller
Realk1Gain of controller
RealTi0.5Time constant of integrator block [s]
RealTd0.1Time constant of derivative block [s]

Connectors

TypeNameDescription
input IntegerInputuPumLeaLag[nPum]Index of chilled water pumps in lead-lag order: lead pump, first lag pump, second lag pump, etc.
input BooleanInputuPlaTrue: plant is enabled
input BooleanInputuChiWatPum[nPum]Chilled water pumps proven on status
input BooleanInputuLeaChiEnaLead chiller enabling status
input BooleanInputuLeaChiStaLead chiller proven on status
input BooleanInputuLeaChiWatReqStatus indicating if lead chiller is requesting chilled water
input BooleanInputuWseTrue: the plant has waterside economizer
input BooleanInputu1ChiWatIsoVal[nChi]Chilled water isolation valve commanded position
input RealInputVChiWat_flowChilled water flow [m3/s]
input RealInputdpChiWat_localChilled water differential static pressure from local sensor [Pa]
input RealInputdpChiWatSet_localChilled water differential static pressure setpoint for local sensor [Pa]
input RealInputdpChiWat_remote[nSen]Chilled water differential static pressure from remote sensor [Pa]
input RealInputdpChiWatSet_remote[nSen]Chilled water differential static pressure setpoint [Pa]
output BooleanOutputyLeaLead pump status setpoint
output BooleanOutputyChiWatPum[nPum]Chilled water pump status setpoint
output RealOutputyPumSpeEnabled chilled water pump speed [1]

Modelica definition

block Controller "Sequences to control chilled water pumps in primary-only plant system" parameter Boolean have_heaPum=true "Flag of headered chilled water pumps design: true=headered, false=dedicated"; parameter Boolean have_senDpChiWatRemWir = true "True=remote DP sensor hardwired to controller"; parameter Boolean have_WSE = false "True: the plant has waterside economizer"; parameter Integer nPum = 2 "Total number of chilled water pumps"; parameter Integer nChi = 2 "Total number of chillers"; parameter Integer nSen=2 "Total number of remote differential pressure sensors"; parameter Real minPumSpe=0.1 "Minimum pump speed"; parameter Real maxPumSpe=1 "Maximum pump speed"; parameter Integer nPum_nominal( max=nPum, min=1)=nPum "Total number of pumps that operate at design conditions"; parameter Real VChiWat_flow_nominal( min=1e-6, unit="m3/s")=0.5 "Total plant design chilled water flow rate"; parameter Buildings.Controls.OBC.CDL.Types.SimpleController controllerType= Buildings.Controls.OBC.CDL.Types.SimpleController.PI "Type of controller"; parameter Real k=1 "Gain of controller"; parameter Real Ti( unit="s", displayUnit="s")=0.5 "Time constant of integrator block"; parameter Real Td( unit="s", displayUnit="s")=0.1 "Time constant of derivative block"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uPumLeaLag[nPum] if have_heaPum "Index of chilled water pumps in lead-lag order: lead pump, first lag pump, second lag pump, etc."; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uPla if not have_heaPum "True: plant is enabled"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uChiWatPum[nPum] "Chilled water pumps proven on status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uLeaChiEna if not have_heaPum "Lead chiller enabling status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uLeaChiSta if not have_heaPum "Lead chiller proven on status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uLeaChiWatReq if not have_heaPum "Status indicating if lead chiller is requesting chilled water"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uWse if have_heaPum and have_WSE "True: the plant has waterside economizer"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1ChiWatIsoVal[nChi] if have_heaPum "Chilled water isolation valve commanded position"; Buildings.Controls.OBC.CDL.Interfaces.RealInput VChiWat_flow( final unit="m3/s") if have_heaPum "Chilled water flow"; Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWat_local( final unit="Pa", final quantity="PressureDifference") if not have_senDpChiWatRemWir "Chilled water differential static pressure from local sensor"; Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWatSet_local( final unit="Pa", final quantity="PressureDifference") if not have_senDpChiWatRemWir "Chilled water differential static pressure setpoint for local sensor"; Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWat_remote[nSen]( final unit=fill("Pa", nSen), final quantity=fill("PressureDifference", nSen)) if have_senDpChiWatRemWir "Chilled water differential static pressure from remote sensor"; Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWatSet_remote[nSen]( final unit=fill("Pa", nSen), final quantity=fill("PressureDifference",nSen)) if have_senDpChiWatRemWir "Chilled water differential static pressure setpoint"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yLea "Lead pump status setpoint"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yChiWatPum[nPum] if have_heaPum "Chilled water pump status setpoint"; Buildings.Controls.OBC.CDL.Interfaces.RealOutput yPumSpe( final min=0, final max=1, final unit="1") "Enabled chilled water pump speed"; Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Subsequences.EnableLead_dedicated enaDedLeaPum if not have_heaPum "Enable lead pump of dedicated pumps"; Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Subsequences.EnableLead_headered enaHeaLeaPum( final nChi=nChi, final have_WSE=have_WSE) if have_heaPum "Enable lead pump of headered pumps"; Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Subsequences.EnableLag_primary_dP enaLagChiPum( final nPum=nPum, final nPum_nominal=nPum_nominal, final VChiWat_flow_nominal=VChiWat_flow_nominal) if have_heaPum "Enable lag pump for primary-only plants using differential pressure pump speed control"; Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Subsequences.Speed_primary_localDp pumSpeLocDp( final nPum=nPum, final minPumSpe=minPumSpe, final maxPumSpe=maxPumSpe, final controllerType=controllerType, final k=k, final Ti=Ti, final Td=Td) if not have_senDpChiWatRemWir "Chilled water pump speed control with local DP sensor"; Buildings.Controls.OBC.ASHRAE.G36.Plants.Chillers.Pumps.ChilledWater.Subsequences.Speed_primary_remoteDp pumSpeRemDp( final nSen=nSen, final nPum=nPum, final minPumSpe=minPumSpe, final maxPumSpe=maxPumSpe, final controllerType=controllerType, final k=k, final Ti=Ti, final Td=Td) if have_senDpChiWatRemWir "Chilled water pump speed control with remote DP sensor"; protected final parameter Real minLocDp( final unit="Pa", final quantity="PressureDifference")=5*6894.75 "Minimum chilled water loop local differential pressure setpoint"; final parameter Integer pumInd[nPum]={i for i in 1:nPum} "Pump index, {1,2,...,n}"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt( final k=1) if have_heaPum "Constant one"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intRep( final nout=nPum) if have_heaPum "Replicate integer input"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep( final nout=nPum) "Replicate boolean input"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intRep1( final nout=nPum) if have_heaPum "Replicate integer input"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep1( final nout=nPum) if have_heaPum "Replicate boolean input"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intRep2( final nout=nPum) if have_heaPum "Replicate integer input"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep2( final nout=nPum) if have_heaPum "Replicate boolean input"; Buildings.Controls.OBC.CDL.Conversions.IntegerToReal intToRea[nPum] if have_heaPum "Convert integer to real number"; Buildings.Controls.OBC.CDL.Routing.RealExtractor leaPum( final nin=nPum) if have_heaPum "Lead pump index"; Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt if have_heaPum "Convert real input to integer output"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant pumIndCon[nPum]( final k=pumInd) if have_heaPum "Pump index array"; Buildings.Controls.OBC.CDL.Integers.Equal intEqu1[nPum] if have_heaPum "Check lead pump"; Buildings.Controls.OBC.CDL.Routing.RealExtractor nexLagPum( final nin=nPum) if have_heaPum "Next lag pump"; Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt1 if have_heaPum "Convert real input to integer output"; Buildings.Controls.OBC.CDL.Integers.Equal intEqu2[nPum] if have_heaPum "Check next lag pump"; Buildings.Controls.OBC.CDL.Routing.RealExtractor lasLagPum( final nin=nPum) if have_heaPum "Last lag pump"; Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt2 if have_heaPum "Convert real input to integer output"; Buildings.Controls.OBC.CDL.Integers.Equal intEqu3[nPum] if have_heaPum "Check next lag pump"; Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt[nPum] if have_heaPum "Convert boolean to integer"; Buildings.Controls.OBC.CDL.Integers.MultiSum mulSumInt( final nin=nPum) if have_heaPum "Sum of integer inputs"; Buildings.Controls.OBC.CDL.Integers.Add addInt if have_heaPum "Integer add"; Buildings.Controls.OBC.CDL.Integers.Equal intEqu4[nPum] if have_heaPum "Check if all the pumps have achieved the setpoint status"; Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt1[nPum] if have_heaPum "Convert boolean to integer"; Buildings.Controls.OBC.CDL.Logical.Pre pre1[nPum] if have_heaPum "Breaks algebraic loops"; Buildings.Controls.OBC.CDL.Logical.Switch leaPumSta[nPum] if have_heaPum "Lead pump status"; Buildings.Controls.OBC.CDL.Logical.Switch nexLagPumSta[nPum] if have_heaPum "Next lag pump status"; Buildings.Controls.OBC.CDL.Logical.Switch lasLagPumSta[nPum] if have_heaPum "Last lag pump status"; Buildings.Controls.OBC.CDL.Logical.Or enaPum[nPum] if have_heaPum "Chilled water pump status"; Buildings.Controls.OBC.CDL.Logical.And pumSta[nPum] if have_heaPum "Chilled water pump status"; Buildings.Controls.OBC.CDL.Logical.Switch addPum[nPum] if have_heaPum "Add pump"; Buildings.Controls.OBC.CDL.Logical.Switch remPum[nPum] if have_heaPum "Remove pump"; Buildings.Controls.OBC.CDL.Logical.MultiAnd mulAnd( final nin=nPum) if have_heaPum "Check if all the pumps have achieved the setpoint status"; Buildings.Controls.OBC.CDL.Logical.Latch enaNexLag if have_heaPum "Hold the enabling signal till the pump is proven on"; Buildings.Controls.OBC.CDL.Logical.Latch disLasLag if have_heaPum "Hold the disabling signal till the pump is proven off"; Buildings.Controls.OBC.CDL.Logical.Not not2 if have_heaPum "Logical not"; Buildings.Controls.OBC.CDL.Logical.And pumSta1[nPum] if have_heaPum "Chilled water pump status"; Buildings.Controls.OBC.CDL.Logical.MultiOr mulOr( final nin=nPum) "Check if there is any enabled pump"; Buildings.Controls.OBC.CDL.Logical.Or or2 "Check if the lead pump is enabled"; Buildings.Controls.OBC.CDL.Integers.GreaterThreshold intGreThr if have_heaPum "Check if there is any pump running"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt1(final k=1) if have_heaPum "Dummy index"; Buildings.Controls.OBC.CDL.Integers.Switch intSwi if have_heaPum "Output 1 when there is no pump running, to avoid warning downstream"; Buildings.Controls.OBC.CDL.Integers.Multiply mulInt if have_heaPum "Output zero when there is no pump running"; Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt2 if have_heaPum "Convert boolean to integer"; Buildings.Controls.OBC.CDL.Logical.Edge edg if have_heaPum "Achieved setpoint"; Buildings.Controls.OBC.CDL.Integers.Multiply mulInt1 if have_heaPum "Output zero when there is no pump running"; Buildings.Controls.OBC.CDL.Integers.LessThreshold intLesThr( final t=nPum +1) if have_heaPum "Check if it is not greater than pump number"; Buildings.Controls.OBC.CDL.Integers.Switch intSwi1 if have_heaPum "Output 1 when there are too many pumps running, to avoid warning downstream"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt2(final k=1) if have_heaPum "Dummy index"; Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt3 if have_heaPum "Convert boolean to integer"; equation connect(enaDedLeaPum.uLeaChiEna, uLeaChiEna); connect(enaDedLeaPum.uLeaChiSta, uLeaChiSta); connect(enaDedLeaPum.uLeaChiWatReq, uLeaChiWatReq); connect(uPumLeaLag, intToRea.u); connect(intToRea.y, leaPum.u); connect(conInt.y, leaPum.index); connect(leaPum.y, reaToInt.u); connect(reaToInt.y, intRep.u); connect(intRep.y, intEqu1.u1); connect(pumIndCon.y, intEqu1.u2); connect(intEqu1.y, leaPumSta.u2); connect(uChiWatPum, leaPumSta.u3); connect(booRep.y, leaPumSta.u1); connect(intToRea.y, nexLagPum.u); connect(nexLagPum.y, reaToInt1.u); connect(intRep1.y, intEqu2.u2); connect(pumIndCon.y, intEqu2.u1); connect(intEqu2.y, nexLagPumSta.u2); connect(booRep1.y, nexLagPumSta.u1); connect(uChiWatPum, nexLagPumSta.u3); connect(lasLagPum.y, reaToInt2.u); connect(intRep2.y, intEqu3.u2); connect(pumIndCon.y, intEqu3.u1); connect(intEqu3.y, lasLagPumSta.u2); connect(enaLagChiPum.VChiWat_flow, VChiWat_flow); connect(uChiWatPum, enaLagChiPum.uChiWatPum); connect(intToRea.y, lasLagPum.u); connect(booRep2.y, lasLagPumSta.u1); connect(uChiWatPum, lasLagPumSta.u3); connect(nexLagPumSta.y,enaPum. u2); connect(leaPumSta.y,enaPum. u1); connect(pumSpeLocDp.dpChiWat_local, dpChiWat_local); connect(dpChiWat_remote, pumSpeRemDp.dpChiWat_remote); connect(dpChiWatSet_remote, pumSpeRemDp.dpChiWatSet_remote); connect(enaPum.y, pumSta.u2); connect(lasLagPumSta.y, pumSta.u1); connect(booRep2.y, remPum.u2); connect(pumSta.y, remPum.u3); connect(leaPumSta.y, remPum.u1); connect(enaPum.y, addPum.u1); connect(booRep1.y, addPum.u2); connect(remPum.y, addPum.u3); connect(uChiWatPum, booToInt.u); connect(booToInt.y, mulSumInt.u); connect(mulSumInt.y, addInt.u2); connect(conInt.y, addInt.u1); connect(enaDedLeaPum.uPla, uPla); connect(pumSpeLocDp.yChiWatPumSpe, yPumSpe); connect(pumSpeRemDp.yChiWatPumSpe, yPumSpe); connect(enaLagChiPum.yUp, enaNexLag.u); connect(enaNexLag.y, booRep1.u); connect(booToInt1.y, intEqu4.u1); connect(booToInt.y, intEqu4.u2); connect(intEqu4.y, mulAnd.u); connect(disLasLag.y, not2.u); connect(not2.y, booRep2.u); connect(booRep.y, pumSta1.u1); connect(addPum.y, pumSta1.u2); connect(pumSta1.y, yChiWatPum); connect(pumSta1.y, pre1.u); connect(uChiWatPum, mulOr.u); connect(mulOr.y, or2.u1); connect(enaDedLeaPum.yLea, or2.u2); connect(enaHeaLeaPum.yLea, or2.u2); connect(or2.y, yLea); connect(or2.y, booRep.u); connect(mulSumInt.y, intGreThr.u); connect(intGreThr.y, intSwi.u2); connect(intSwi.y, lasLagPum.index); connect(mulSumInt.y, intSwi.u1); connect(conInt1.y, intSwi.u3); connect(intGreThr.y, booToInt2.u); connect(booToInt2.y, mulInt.u2); connect(reaToInt2.y, mulInt.u1); connect(mulInt.y, intRep2.u); connect(pre1.y, booToInt1.u); connect(enaLagChiPum.yDown, disLasLag.u); connect(uWse, enaHeaLeaPum.uWse); connect(booRep.y, pumSpeLocDp.uChiWatPum); connect(booRep.y, pumSpeRemDp.uChiWatPum); connect(dpChiWatSet_local, pumSpeLocDp.dpChiWatSet_local); connect(mulAnd.y, edg.u); connect(edg.y, enaNexLag.clr); connect(edg.y, disLasLag.clr); connect(u1ChiWatIsoVal, enaHeaLeaPum.u1ChiWatIsoVal); connect(intRep1.u, mulInt1.y); connect(reaToInt1.y, mulInt1.u1); connect(addInt.y, intLesThr.u); connect(intLesThr.y, intSwi1.u2); connect(addInt.y, intSwi1.u1); connect(conInt2.y, intSwi1.u3); connect(intSwi1.y, nexLagPum.index); connect(intLesThr.y, booToInt3.u); connect(booToInt3.y, mulInt1.u2); end Controller;