diff --git a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPlant.mo b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPlant.mo index 84917c63de1..36be869fa0f 100644 --- a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPlant.mo +++ b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPlant.mo @@ -6,7 +6,9 @@ block StagingPlant "Number of units operating at design conditions" annotation (Dialog(group="CHW loop and cooling-only chillers"), Evaluate=true); - parameter Modelica.Units.SI.HeatFlowRate QChiWatChi_flow_nominal + parameter Real QChiWatChi_flow_nominal( + final unit="W", + final quantity="HeatFlowRate") "Cooling design heat flow rate of cooling-only chillers (all units)" annotation (Dialog(group="CHW loop and cooling-only chillers")); parameter Integer nChiHea(final min=1, start=1) @@ -15,17 +17,24 @@ block StagingPlant Evaluate=true); parameter Real PLRStaTra(unit="1") = 0.85 "Part load ratio triggering stage transition"; - parameter Modelica.Units.SI.HeatFlowRate QChiWatCasCoo_flow_nominal + parameter Real QChiWatCasCoo_flow_nominal( + final unit="W", + final quantity="HeatFlowRate") "Cooling design heat flow rate of HRC in cascading cooling mode (all units)" annotation (Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.HeatFlowRate QChiWatCasCoo_flow_nominal_approx + parameter Real QChiWatCasCoo_flow_nominal_approx( + final unit="W", + final quantity="HeatFlowRate") "Cooling design heat flow rate of HRC in cascading cooling mode (all units), approximate for scaling" annotation (Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.HeatFlowRate QHeaWat_flow_nominal + parameter Real QHeaWat_flow_nominal( + final unit="W", + final quantity="HeatFlowRate") "Heating design heat flow rate (all units)" annotation (Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.SpecificHeatCapacity cp_default= - Buildings.Utilities.Psychrometrics.Constants.cpWatLiq + parameter Real cp_default( + final quantity="SpecificHeatCapacity", + final unit="J/(kg.K)")=Buildings.Utilities.Psychrometrics.Constants.cpWatLiq "Specific heat capacity of the fluid"; Buildings.Controls.OBC.CDL.Interfaces.RealInput mChiWatPri_flow( @@ -34,56 +43,68 @@ block StagingPlant annotation (Placement(transformation(extent={{-280,80},{-240,120}}), iconTransformation(extent={{-140,80},{-100,120}}))); Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatSupSet( - final unit="K", displayUnit="degC") "CHW supply temperature setpoint" - annotation (Placement(transformation( - extent={{-280,60},{-240,100}}), iconTransformation(extent={{-140,60}, - {-100,100}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatPriRet(final unit="K", - displayUnit="degC") "Primary CHW return temperature" annotation ( - Placement(transformation(extent={{-280,20},{-240,60}}), + final unit="K", displayUnit="degC") + "CHW supply temperature setpoint" + annotation (Placement(transformation(extent={{-280,60},{-240,100}}), + iconTransformation(extent={{-140,60},{-100,100}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatPriRet( + final unit="K", + displayUnit="degC") + "Primary CHW return temperature" + annotation (Placement(transformation(extent={{-280,20},{-240,60}}), iconTransformation(extent={{-140,20},{-100,60}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput mHeaWatPri_flow(final unit="kg/s") - "Primary HW mass flow rate" annotation (Placement(transformation(extent={{-280, - -100},{-240,-60}}),iconTransformation(extent={{-140,-60},{-100,-20}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput mHeaWatPri_flow( + final unit="kg/s") + "Primary HW mass flow rate" + annotation (Placement(transformation(extent={{-280,-100},{-240,-60}}), + iconTransformation(extent={{-140,-60},{-100,-20}}))); Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaWatSupSet( final unit="K", displayUnit="degC") - "HW supply temperature setpoint" annotation (Placement(transformation( - extent={{-280,-140},{-240,-100}}), - iconTransformation(extent={{-140,-80},{ - -100,-40}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaWatPriRet(final unit="K", - displayUnit="degC") "Primary HW return temperature" annotation (Placement( - transformation(extent={{-280,-180},{-240,-140}}), iconTransformation( - extent={{-140,-120},{-100,-80}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatSup(final unit="K", - displayUnit="degC") "CHW supply temperature" annotation (Placement( - transformation(extent={{-280,180},{-240,220}}), iconTransformation( - extent={{-140,40},{-100,80}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWat(final unit="Pa") + "HW supply temperature setpoint" + annotation (Placement(transformation(extent={{-280,-140},{-240,-100}}), + iconTransformation(extent={{-140,-80},{-100,-40}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaWatPriRet( + final unit="K", + displayUnit="degC") + "Primary HW return temperature" + annotation (Placement(transformation(extent={{-280,-180},{-240,-140}}), + iconTransformation(extent={{-140,-120},{-100,-80}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatSup( + final unit="K", + displayUnit="degC") + "CHW supply temperature" + annotation (Placement(transformation(extent={{-280,180},{-240,220}}), + iconTransformation(extent={{-140,40},{-100,80}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWat( + final unit="Pa") "CHW loop differential pressure" - annotation ( - Placement(transformation(extent={{-280,240},{-240,280}}), + annotation (Placement(transformation(extent={{-280,240},{-240,280}}), iconTransformation(extent={{-140,-20},{-100,20}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWatSet(final unit="Pa") + Buildings.Controls.OBC.CDL.Interfaces.RealInput dpChiWatSet( + final unit="Pa") "CHW loop differential pressure setpoint" - annotation ( - Placement(transformation(extent={{-280,260},{-240,300}}), + annotation (Placement(transformation(extent={{-280,260},{-240,300}}), iconTransformation(extent={{-140,0},{-100,40}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaWatSup(final unit="K", - displayUnit="degC") "HW supply temperature" annotation (Placement( - transformation(extent={{-280,-240},{-240,-200}}), iconTransformation( - extent={{-140,-100},{-100,-60}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput dpHeaWat(final unit="Pa") - "HW loop differential pressure" annotation (Placement(transformation(extent - ={{-280,-300},{-240,-260}}), iconTransformation(extent={{-140,-160},{ - -100,-120}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput dpHeaWatSet(final unit="Pa") - "HW loop differential pressure setpoint" annotation (Placement( - transformation(extent={{-280,-280},{-240,-240}}), iconTransformation( - extent={{-140,-140},{-100,-100}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealOutput QCooReq_flow(final unit="W") - "Plant required cooling capacity (>0)" annotation ( - Placement(transformation(extent={{240,160},{280,200}}), + Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaWatSup( + final unit="K", + displayUnit="degC") + "HW supply temperature" + annotation (Placement(transformation(extent={{-280,-240},{-240,-200}}), + iconTransformation(extent={{-140,-100},{-100,-60}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput dpHeaWat( + final unit="Pa") + "HW loop differential pressure" + annotation (Placement(transformation(extent={{-280,-300},{-240,-260}}), + iconTransformation(extent={{-140,-160},{-100,-120}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput dpHeaWatSet( + final unit="Pa") + "HW loop differential pressure setpoint" + annotation (Placement(transformation(extent={{-280,-280},{-240,-240}}), + iconTransformation(extent={{-140,-140},{-100,-100}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput QCooReq_flow( + final unit="W") + "Plant required cooling capacity (>0)" + annotation (Placement(transformation(extent={{240,160},{280,200}}), iconTransformation(extent={{100,120},{140,160}}))); Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Coo "Cooling enable signal" @@ -95,39 +116,20 @@ block StagingPlant iconTransformation(extent={{-140,102},{-100,142}}))); Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Chi[nChi] "Chiller On/Off command" - annotation (Placement(transformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={260,120}), iconTransformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={120,80}))); + annotation (Placement(transformation(extent={{240,100},{280,140}}), + iconTransformation(extent={{100,60},{140,100}}))); Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1CooChiHea[nChiHea] "HRC cooling mode switchover command: true for cooling, false for heating" - annotation (Placement(transformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={260,40}), iconTransformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={120,-80}))); + annotation (Placement(transformation(extent={{240,20},{280,60}}), + iconTransformation(extent={{100,-100},{140,-60}}))); Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ChiHea[nChiHea] - "HRC On/Off command" annotation (Placement(transformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={260,-100}),iconTransformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={120,-20}))); + "HRC On/Off command" + annotation (Placement(transformation(extent={{240,-120},{280,-80}}), + iconTransformation(extent={{100,-40},{140,0}}))); Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaCooChiHea[nChiHea] "HRC cooling mode switchover command: true for cooling, false for heating" - annotation (Placement(transformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={260,-40}), iconTransformation( - extent={{-20,-20},{20,20}}, - rotation=0, - origin={120,-140}))); + annotation (Placement(transformation(extent={{240,-60},{280,-20}}), + iconTransformation(extent={{100,-160},{140,-120}}))); Buildings.Controls.OBC.CDL.Reals.MovingAverage movAve(delta=300) "Moving average" @@ -143,195 +145,253 @@ block StagingPlant annotation (Placement(transformation(extent={{-180,-130},{-160,-110}}))); Buildings.Controls.OBC.CDL.Reals.Subtract dTHeaWat "Compute deltaT" annotation (Placement(transformation(extent={{-220,-150},{-200,-130}}))); - Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator rep(final nout= - nChi) "Replicate" + Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator rep( + final nout=nChi) + "Replicate" annotation (Placement(transformation(extent={{180,110},{200,130}}))); - Buildings.Controls.OBC.CDL.Integers.GreaterEqualThreshold cmdChi[nChi](final - t={i for i in 1:nChi}) + Buildings.Controls.OBC.CDL.Integers.GreaterEqualThreshold cmdChi[nChi]( + final t={i for i in 1:nChi}) "Compute chiller On/Off command from number of units to be commanded On" annotation (Placement(transformation(extent={{210,110},{230,130}}))); - Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter timCp(final k = cp_default) - "Scale" annotation (Placement(transformation(extent={{-210,130},{-190,150}}))); - Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter timCp1(final k = cp_default) - "Scale" annotation (Placement(transformation(extent={{-220,-90},{-200,-70}}))); - Buildings.Controls.OBC.CDL.Reals.MovingAverage movAve1(delta=300) - "Moving average" annotation (Placement(transformation(extent={{-150,-130},{-130,-110}}))); - Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator rep5(final nout = nChiHea) - "Replicate" annotation (Placement(transformation(extent={{180,-110},{200,-90}}))); + Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter timCp( + final k = cp_default) + "Scale" + annotation (Placement(transformation(extent={{-210,130},{-190,150}}))); + Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter timCp1( + final k = cp_default) + "Scale" + annotation (Placement(transformation(extent={{-220,-90},{-200,-70}}))); + Buildings.Controls.OBC.CDL.Reals.MovingAverage movAve1( + final delta=300) + "Moving average" + annotation (Placement(transformation(extent={{-150,-130},{-130,-110}}))); + Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator rep5( + final nout = nChiHea) + "Replicate" + annotation (Placement(transformation(extent={{180,-110},{200,-90}}))); Buildings.Controls.OBC.CDL.Integers.GreaterEqualThreshold cmdChiHea[nChiHea]( - final t={i for i in 1:nChiHea}) - "Compute chiller On/Off command from number of units to be commanded On" annotation (Placement(transformation(extent={{210,-110},{230,-90}}))); + final t={i for i in 1:nChiHea}) + "Compute chiller On/Off command from number of units to be commanded On" + annotation (Placement(transformation(extent={{210,-110},{230,-90}}))); Buildings.Controls.OBC.CDL.Integers.Subtract numChiHeaCoo - "Number of HRC required in direct HR mode" annotation (Placement( - transformation( - extent={{-10,-10},{10,10}}, - rotation=0, - origin={10,-20}))); - Buildings.Controls.OBC.CDL.Integers.Sources.Constant numChiHea(final k = nChiHea) - "Number of HRC" annotation (Placement(transformation(extent={{-80,-50},{-60,-30}}))); - + "Number of HRC required in direct HR mode" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0, origin={10,-20}))); + Buildings.Controls.OBC.CDL.Integers.Sources.Constant numChiHea( + final k = nChiHea) + "Number of HRC" + annotation (Placement(transformation(extent={{-80,-50},{-60,-30}}))); Buildings.Controls.OBC.CDL.Integers.Add nChiHeaAndCooUnb - "Number of HRC required to meet heating and cooling load - Unbounded" annotation (Placement(transformation( - extent={{-10,-10},{10,10}}, - rotation=0, - origin={-70,0}))); + "Number of HRC required to meet heating and cooling load - Unbounded" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0,origin={-70,0}))); Buildings.Controls.OBC.CDL.Integers.Subtract numChiCasCoo - "Number of HRC required in cascading cooling" annotation (Placement(transformation(extent={{40,10},{60,30}}))); - Buildings.DHC.Plants.Combined.Controls.BaseClasses.ModeHeatRecoveryChiller modHeaCoo(final nChiHea=nChiHea) - "Compute the cascading cooling and direct HR switchover signals" annotation (Placement(transformation(extent={{180,-10},{200,10}}))); - + "Number of HRC required in cascading cooling" + annotation (Placement(transformation(extent={{40,10},{60,30}}))); + Buildings.DHC.Plants.Combined.Controls.BaseClasses.ModeHeatRecoveryChiller modHeaCoo( + final nChiHea=nChiHea) + "Compute the cascading cooling and direct HR switchover signals" + annotation (Placement(transformation(extent={{180,-10},{200,10}}))); Buildings.Controls.OBC.CDL.Integers.Min nChiHeaHeaAndCoo - "Number of HRC required to meet heating and cooling load - Bounded by number of HRC" annotation (Placement(transformation( - extent={{-10,-10},{10,10}}, - rotation=0, - origin={-30,-40}))); - + "Number of HRC required to meet heating and cooling load - Bounded by number of HRC" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0, origin={-30,-40}))); Buildings.Controls.OBC.CDL.Reals.Subtract errTChiWatSup - "Compute tracking error" annotation (Placement(transformation(extent={{-200,200},{-180,220}}))); + "Compute tracking error" + annotation (Placement(transformation(extent={{-200,200},{-180,220}}))); Buildings.Controls.OBC.CDL.Reals.Subtract errDpChiWat - "Compute tracking error" annotation (Placement(transformation(extent={{-200,250},{-180,270}}))); + "Compute tracking error" + annotation (Placement(transformation(extent={{-200,250},{-180,270}}))); Buildings.Controls.OBC.CDL.Reals.LessThreshold cmpErrLim(t=-1, h=1E-4) - "Check tracking error limit" annotation (Placement(transformation(extent={{-170,200},{-150,220}}))); + "Check tracking error limit" + annotation (Placement(transformation(extent={{-170,200},{-150,220}}))); Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmpErrLim1(t=1.5E4, h=1E-1) - "Check tracking error limit" annotation (Placement(transformation(extent={{-170,250},{-150,270}}))); + "Check tracking error limit" + annotation (Placement(transformation(extent={{-170,250},{-150,270}}))); Buildings.Controls.OBC.CDL.Logical.Timer timErrExcLim(t=15*60) - "Timer for error exceeding error limit" annotation (Placement(transformation(extent={{-110,200},{-90,220}}))); + "Timer for error exceeding error limit" + annotation (Placement(transformation(extent={{-110,200},{-90,220}}))); Buildings.Controls.OBC.CDL.Logical.Timer timErrExcLim1(t=15*60) - "Timer for error exceeding error limit" annotation (Placement(transformation(extent={{-110,250},{-90,270}}))); - Buildings.Controls.OBC.CDL.Logical.Or or2 "Failsafe condition to stage up" annotation (Placement(transformation(extent={{-70,220},{-50,240}}))); + "Timer for error exceeding error limit" + annotation (Placement(transformation(extent={{-110,250},{-90,270}}))); + Buildings.Controls.OBC.CDL.Logical.Or or2 + "Failsafe condition to stage up" + annotation (Placement(transformation(extent={{-70,220},{-50,240}}))); Buildings.Controls.OBC.CDL.Logical.And and2 - "Apply failsafe condition only in stage >= 1" annotation (Placement(transformation(extent={{-140,250},{-120,270}}))); + "Apply failsafe condition only in stage >= 1" + annotation (Placement(transformation(extent={{-140,250},{-120,270}}))); Buildings.Controls.OBC.CDL.Logical.And and3 - "Apply failsafe condition only in stage >= 1" annotation (Placement(transformation(extent={{-140,200},{-120,220}}))); - Buildings.DHC.Plants.Combined.Controls.BaseClasses.StageIndex staCoo(final nSta=nChi + nChiHea, tSta=15*60) - "Compute cooling stage" annotation (Placement(transformation(extent={{50,144},{70,164}}))); - Modelica.Blocks.Sources.RealExpression capCoo(final y=abs(PLRStaTra*(min(nChi, - staCoo.preIdxSta)/nChi*QChiWatChi_flow_nominal + max(0, staCoo.preIdxSta - - nChi)/nChiHea*QChiWatCasCoo_flow_nominal))) - "Total capacity at current stage (>0) times stage-up PLR limit" annotation (Placement(transformation(extent={{-120,90},{-100,110}}))); - Buildings.Controls.OBC.CDL.Reals.Greater cmpOPLRLimUp(h=-1E-4*( - QChiWatChi_flow_nominal + QChiWatCasCoo_flow_nominal_approx)/2) - "Check OPLR limit" annotation (Placement(transformation(extent={{-80,110},{-60,130}}))); + "Apply failsafe condition only in stage >= 1" + annotation (Placement(transformation(extent={{-140,200},{-120,220}}))); + Buildings.DHC.Plants.Combined.Controls.BaseClasses.StageIndex staCoo( + final nSta=nChi + nChiHea, tSta=15*60) + "Compute cooling stage" + annotation (Placement(transformation(extent={{50,144},{70,164}}))); + Buildings.Controls.OBC.CDL.Reals.Sources.Constant capCoo( + final k=abs(PLRStaTra*(min(nChi, staCoo.preIdxSta)/nChi*QChiWatChi_flow_nominal + + max(0, staCoo.preIdxSta - nChi)/nChiHea*QChiWatCasCoo_flow_nominal))) + "Total capacity at current stage (>0) times stage-up PLR limit" + annotation (Placement(transformation(extent={{-180,80},{-160,100}}))); + Buildings.Controls.OBC.CDL.Reals.Greater cmpOPLRLimUp( + final h=-1E-4*(QChiWatChi_flow_nominal + QChiWatCasCoo_flow_nominal_approx)/2) + "Check OPLR limit" + annotation (Placement(transformation(extent={{-80,110},{-60,130}}))); Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim(t=15*60) - "Timer for OPLR exceeding limit" annotation (Placement(transformation(extent={{-40,110},{-20,130}}))); + "Timer for OPLR exceeding limit" + annotation (Placement(transformation(extent={{-40,110},{-20,130}}))); Buildings.Controls.OBC.CDL.Logical.Or or1 - "Failsafe condition or efficiency condition to stage up" annotation (Placement(transformation(extent={{0,130},{20,150}}))); + "Failsafe condition or efficiency condition to stage up" + annotation (Placement(transformation(extent={{0,130},{20,150}}))); Buildings.Controls.OBC.CDL.Integers.Min numOpeChi - "Number of operating chillers" annotation (Placement(transformation(extent={{90,110},{110,130}}))); - Buildings.Controls.OBC.CDL.Integers.Sources.Constant numChi(final k=nChi) - "Number of chillers" annotation (Placement(transformation(extent={{50,90},{70,110}}))); + "Number of operating chillers" + annotation (Placement(transformation(extent={{90,110},{110,130}}))); + Buildings.Controls.OBC.CDL.Integers.Sources.Constant numChi( + final k=nChi) + "Number of chillers" + annotation (Placement(transformation(extent={{50,90},{70,110}}))); Buildings.Controls.OBC.CDL.Integers.Subtract numOpeCooChiHea - "Number of HRC required for cooling" annotation (Placement(transformation(extent={{-120,10},{-100,30}}))); - Modelica.Blocks.Sources.RealExpression capHea(final y=PLRStaTra*staHea.preIdxSta - /nChiHea*QHeaWat_flow_nominal) - "Total capacity at current stage times stage-up PLR limit" annotation (Placement(transformation(extent={{-120,-150},{-100,-130}}))); - Buildings.Controls.OBC.CDL.Reals.Greater cmpOPLRLimUp1(h=1E-1) - "Check OPLR limit" annotation (Placement(transformation(extent={{-80,-130},{-60,-110}}))); - Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim1(t=15*60) - "Timer for OPLR exceeding limit" annotation (Placement(transformation(extent={{-50,-130},{-30,-110}}))); - Buildings.DHC.Plants.Combined.Controls.BaseClasses.StageIndex staHea(final nSta=nChiHea, tSta=15*60) "Compute heating stage" annotation (Placement(transformation(extent={{50,-130},{70,-110}}))); - Modelica.Blocks.Sources.RealExpression capHeaLow(final y=PLRStaTra*max(0, - staHea.preIdxSta - 1)/nChiHea*QHeaWat_flow_nominal) - "Total capacity at next lower stage times stage-down PLR limit" annotation (Placement(transformation(extent={{-120,-178},{-100,-158}}))); - Buildings.Controls.OBC.CDL.Reals.Less cmpOPLRLimDow(h=1E-1) - "Check OPLR limit" annotation (Placement(transformation(extent={{-80,-170},{-60,-150}}))); - Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim2(t=15*60) - "Timer for OPLR exceeding limit" annotation (Placement(transformation(extent={{-50,-170},{-30,-150}}))); - Modelica.Blocks.Sources.RealExpression capCooLow(final y=abs(PLRStaTra*(min( - nChi, max(0, staCoo.preIdxSta - 1))/nChi*QChiWatChi_flow_nominal + max( - 0, staCoo.preIdxSta - 1 - nChi)/nChiHea*QChiWatCasCoo_flow_nominal))) - "Total capacity at next lower stage (>0) times stage-down PLR limit" annotation (Placement(transformation(extent={{-120,62},{-100,82}}))); - Buildings.Controls.OBC.CDL.Reals.Less cmpOPLRLimDow1(h=-1E-4*( - QChiWatChi_flow_nominal + QChiWatCasCoo_flow_nominal_approx)/2) - "Check OPLR limit" annotation (Placement(transformation(extent={{-80,70},{-60,90}}))); - Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim3(t=15*60) - "Timer for OPLR exceeding limit" annotation (Placement(transformation(extent={{-40,70},{-20,90}}))); + "Number of HRC required for cooling" + annotation (Placement(transformation(extent={{-120,10},{-100,30}}))); + Buildings.Controls.OBC.CDL.Reals.Sources.Constant capHea( + final k=PLRStaTra*staHea.preIdxSta/nChiHea*QHeaWat_flow_nominal) + "Total capacity at current stage times stage-up PLR limit" + annotation (Placement(transformation(extent={{-150,-170},{-130,-150}}))); + Buildings.Controls.OBC.CDL.Reals.Greater cmpOPLRLimUp1( + final h=1E-1) + "Check OPLR limit" + annotation (Placement(transformation(extent={{-80,-130},{-60,-110}}))); + Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim1(final t=15*60) + "Timer for OPLR exceeding limit" + annotation (Placement(transformation(extent={{-50,-130},{-30,-110}}))); + Buildings.DHC.Plants.Combined.Controls.BaseClasses.StageIndex staHea( + final nSta=nChiHea, + tSta=15*60) + "Compute heating stage" + annotation (Placement(transformation(extent={{50,-130},{70,-110}}))); + Buildings.Controls.OBC.CDL.Reals.Sources.Constant capHeaLow( + k=PLRStaTra*max(0,staHea.preIdxSta - 1)/nChiHea*QHeaWat_flow_nominal) + "Total capacity at next lower stage times stage-down PLR limit" + annotation (Placement(transformation(extent={{-120,-190},{-100,-170}}))); + Buildings.Controls.OBC.CDL.Reals.Less cmpOPLRLimDow( + final h=1E-1) + "Check OPLR limit" + annotation (Placement(transformation(extent={{-80,-170},{-60,-150}}))); + Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim2( + t=15*60) + "Timer for OPLR exceeding limit" + annotation (Placement(transformation(extent={{-50,-170},{-30,-150}}))); + Buildings.Controls.OBC.CDL.Reals.Sources.Constant capCooLow( + final k=abs(PLRStaTra*(min(nChi, max(0, staCoo.preIdxSta - 1))/nChi* + QChiWatChi_flow_nominal + max(0, staCoo.preIdxSta - 1 - nChi)/nChiHea* + QChiWatCasCoo_flow_nominal))) + "Total capacity at next lower stage (>0) times stage-down PLR limit" + annotation (Placement(transformation(extent={{-180,40},{-160,60}}))); + Buildings.Controls.OBC.CDL.Reals.Less cmpOPLRLimDow1( + h=-1E-4*(QChiWatChi_flow_nominal + QChiWatCasCoo_flow_nominal_approx)/2) + "Check OPLR limit" + annotation (Placement(transformation(extent={{-80,70},{-60,90}}))); + Buildings.Controls.OBC.CDL.Logical.Timer timOPLRExcLim3( + t=15*60) + "Timer for OPLR exceeding limit" + annotation (Placement(transformation(extent={{-40,70},{-20,90}}))); Buildings.Controls.OBC.CDL.Logical.Not notFail - "Failsafe conditions are not true" annotation (Placement(transformation(extent={{-40,190},{-20,210}}))); + "Failsafe conditions are not true" + annotation (Placement(transformation(extent={{-40,190},{-20,210}}))); Buildings.Controls.OBC.CDL.Logical.And dowAndNotFail - "No stage up failsafe condition and efficiency condition to stage down" annotation (Placement(transformation(extent={{0,90},{20,110}}))); + "No stage up failsafe condition and efficiency condition to stage down" + annotation (Placement(transformation(extent={{0,90},{20,110}}))); Buildings.Controls.OBC.CDL.Reals.Subtract errTChiWatSup1 - "Compute tracking error" annotation (Placement(transformation(extent={{-200,-230},{-180,-210}}))); + "Compute tracking error" + annotation (Placement(transformation(extent={{-200,-230},{-180,-210}}))); Buildings.Controls.OBC.CDL.Reals.Subtract errDpHeaWat - "Compute tracking error" annotation (Placement(transformation(extent={{-200,-290},{-180,-270}}))); - Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmpErrLim2(t=+1, h=1E-4) - "Check tracking error limit" annotation (Placement(transformation(extent={{-170,-230},{-150,-210}}))); - Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmpErrLim3(t=1.5E4, h=1E-1) - "Check tracking error limit" annotation (Placement(transformation(extent={{-170,-290},{-150,-270}}))); - Buildings.Controls.OBC.CDL.Logical.Timer timErrExcLim2(t=15*60) - "Timer for error exceeding error limit" annotation (Placement(transformation(extent={{-110,-230},{-90,-210}}))); - Buildings.Controls.OBC.CDL.Logical.Timer timErrExcLim3(t=15*60) - "Timer for error exceeding error limit" annotation (Placement(transformation(extent={{-110,-290},{-90,-270}}))); - Buildings.Controls.OBC.CDL.Logical.Or or3 "Failsafe condition to stage up" annotation (Placement(transformation(extent={{-70,-270},{-50,-250}}))); - Buildings.Controls.OBC.CDL.Logical.And and1 "Apply failsafe condition only in stage >= 1" annotation (Placement(transformation(extent={{-140,-290},{-120,-270}}))); - Buildings.Controls.OBC.CDL.Logical.And and4 "Apply failsafe condition only in stage >= 1" annotation (Placement(transformation(extent={{-140,-230},{-120,-210}}))); + "Compute tracking error" + annotation (Placement(transformation(extent={{-200,-290},{-180,-270}}))); + Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmpErrLim2( + t=+1, h=1E-4) + "Check tracking error limit" + annotation (Placement(transformation(extent={{-170,-230},{-150,-210}}))); + Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmpErrLim3( + t=1.5E4, h=1E-1) + "Check tracking error limit" + annotation (Placement(transformation(extent={{-170,-290},{-150,-270}}))); + Buildings.Controls.OBC.CDL.Logical.Timer timErrExcLim2( + t=15*60) + "Timer for error exceeding error limit" + annotation (Placement(transformation(extent={{-110,-230},{-90,-210}}))); + Buildings.Controls.OBC.CDL.Logical.Timer timErrExcLim3( + t=15*60) + "Timer for error exceeding error limit" + annotation (Placement(transformation(extent={{-110,-290},{-90,-270}}))); + Buildings.Controls.OBC.CDL.Logical.Or or3 + "Failsafe condition to stage up" + annotation (Placement(transformation(extent={{-70,-270},{-50,-250}}))); + Buildings.Controls.OBC.CDL.Logical.And and1 + "Apply failsafe condition only in stage >= 1" + annotation (Placement(transformation(extent={{-140,-290},{-120,-270}}))); + Buildings.Controls.OBC.CDL.Logical.And and4 + "Apply failsafe condition only in stage >= 1" + annotation (Placement(transformation(extent={{-140,-230},{-120,-210}}))); Buildings.Controls.OBC.CDL.Logical.Not notFail1 - "Failsafe conditions are not true" annotation (Placement(transformation(extent={{-30,-230},{-10,-210}}))); + "Failsafe conditions are not true" + annotation (Placement(transformation(extent={{-30,-230},{-10,-210}}))); Buildings.Controls.OBC.CDL.Logical.Or or4 - "Failsafe condition or efficiency condition to stage up" annotation (Placement(transformation(extent={{10,-130},{30,-110}}))); + "Failsafe condition or efficiency condition to stage up" + annotation (Placement(transformation(extent={{10,-130},{30,-110}}))); Buildings.Controls.OBC.CDL.Logical.And dowAndNotFail1 - "No stage up failsafe condition and efficiency condition to stage down" annotation (Placement(transformation(extent={{10,-170},{30,-150}}))); - Buildings.DHC.Plants.Combined.Controls.BaseClasses.IntegerArrayHold hol(holdDuration=15*60, nin=4) - "Minimum plant stage runtime (needed because cooling and heating stage runtimes are handled separately)" annotation (Placement(transformation(extent={{130,-10},{150,10}}))); + "No stage up failsafe condition and efficiency condition to stage down" + annotation (Placement(transformation(extent={{10,-170},{30,-150}}))); + Buildings.DHC.Plants.Combined.Controls.BaseClasses.IntegerArrayHold hol( + holdDuration=15*60, + nin=4) + "Minimum plant stage runtime (needed because cooling and heating stage runtimes are handled separately)" + annotation (Placement(transformation(extent={{130,-10},{150,10}}))); equation connect(dTChiWatPos.y, loaChiWat.u2) annotation (Line(points={{-188,80},{-186, - 80},{-186,114},{-182,114}}, - color={0,0,127})); + 80},{-186,114},{-182,114}}, color={0,0,127})); connect(dTHeaWat.y, loaHeaWat.u2) annotation (Line(points={{-198,-140},{-186, - -140},{-186,-126},{-182,-126}}, - color={0,0,127})); + -140},{-186,-126},{-182,-126}}, color={0,0,127})); connect(THeaWatSupSet, dTHeaWat.u1) annotation (Line(points={{-260,-120},{ -230,-120},{-230,-134},{-222,-134}}, color={0,0,127})); connect(THeaWatPriRet, dTHeaWat.u2) annotation (Line(points={{-260,-160},{ - -226,-160},{-226,-146},{-222,-146}}, - color={0,0,127})); + -226,-160},{-226,-146},{-222,-146}}, color={0,0,127})); connect(rep.y, cmdChi.u) - annotation (Line(points={{202,120},{208,120}}, - color={255,127,0})); + annotation (Line(points={{202,120},{208,120}}, color={255,127,0})); connect(mChiWatPri_flow, timCp.u) annotation (Line(points={{-260,100},{-220,100},{-220,140},{-212,140}}, - color={0,0,127})); + color={0,0,127})); connect(timCp.y, loaChiWat.u1) annotation (Line(points={{-188,140},{-186,140}, {-186,126},{-182,126}}, color={0,0,127})); connect(mHeaWatPri_flow, timCp1.u) annotation (Line(points={{-260,-80},{-222,-80}}, color={0,0,127})); connect(timCp1.y, loaHeaWat.u1) annotation (Line(points={{-198,-80},{-186,-80}, - {-186,-114},{-182,-114}}, - color={0,0,127})); + {-186,-114},{-182,-114}}, color={0,0,127})); connect(loaChiWat.y, movAve.u) annotation (Line(points={{-158,120},{-152,120}}, color={0,0,127})); connect(loaHeaWat.y, movAve1.u) - annotation (Line(points={{-158,-120},{-152,-120}}, - color={0,0,127})); + annotation (Line(points={{-158,-120},{-152,-120}}, color={0,0,127})); connect(rep5.y, cmdChiHea.u) - annotation (Line(points={{202,-100},{208,-100}}, - color={255,127,0})); + annotation (Line(points={{202,-100},{208,-100}}, color={255,127,0})); connect(cmdChiHea.y, y1ChiHea) annotation (Line(points={{232,-100},{260,-100}}, color={255,0,255})); connect(modHeaCoo.y1HeaCoo, y1HeaCooChiHea) annotation (Line(points={{202,-6}, {220,-6},{220,-40},{260,-40}}, color={255,0,255})); connect(numChiHea.y, nChiHeaHeaAndCoo.u2) - annotation (Line(points={{-58,-40},{-50,-40},{-50,-46},{-42,-46}}, - color={255,127,0})); + annotation (Line(points={{-58,-40},{-50,-40},{-50,-46},{-42,-46}}, color={255,127,0})); connect(nChiHeaAndCooUnb.y, nChiHeaHeaAndCoo.u1) annotation (Line(points={{-58,0}, {-50,0},{-50,-34},{-42,-34}}, color={255,127,0})); connect(nChiHeaAndCooUnb.y, numChiHeaCoo.u1) - annotation (Line(points={{-58,0},{-20,0},{-20,-14},{-2,-14}}, - color={255,127,0})); + annotation (Line(points={{-58,0},{-20,0},{-20,-14},{-2,-14}}, color={255,127,0})); connect(nChiHeaHeaAndCoo.y, numChiHeaCoo.u2) annotation (Line(points={{-18,-40}, - {-10,-40},{-10,-26},{-2,-26}}, - color={255,127,0})); + {-10,-40},{-10,-26},{-2,-26}}, color={255,127,0})); connect(modHeaCoo.y1Coo, y1CooChiHea) annotation (Line(points={{202,6},{220,6}, - {220,40},{260,40}}, color={255,0,255})); + {220,40},{260,40}}, color={255,0,255})); connect(numChiHeaCoo.y, numChiCasCoo.u2) annotation (Line(points={{22,-20},{ - 30,-20},{30,14},{38,14}}, color={255,127,0})); + 30,-20},{30,14},{38,14}}, color={255,127,0})); connect(TChiWatSupSet, errTChiWatSup.u1) annotation (Line(points={{-260,80},{ - -230,80},{-230,180},{-204,180},{-204,216},{-202,216}}, - color={0,0,127})); + -230,80},{-230,180},{-204,180},{-204,216},{-202,216}}, color={0,0,127})); connect(dpChiWatSet, errDpChiWat.u1) annotation (Line(points={{-260,280},{ - -206,280},{-206,266},{-202,266}}, - color={0,0,127})); + -206,280},{-206,266},{-202,266}}, color={0,0,127})); connect(errTChiWatSup.y, cmpErrLim.u) annotation (Line(points={{-178,210},{-172,210}}, color={0,0,127})); connect(errDpChiWat.y, cmpErrLim1.u) @@ -353,26 +413,21 @@ equation connect(u1Coo, and2.u2) annotation (Line(points={{-260,160},{-146,160},{-146, 252},{-142,252}}, color={255,0,255})); connect(cmdChi.y, y1Chi) - annotation (Line(points={{232,120},{260,120}}, - color={255,0,255})); + annotation (Line(points={{232,120},{260,120}}, color={255,0,255})); connect(u1Coo, staCoo.u1) annotation (Line(points={{-260,160},{48,160}}, color={255,0,255})); connect(cmpOPLRLimUp.y, timOPLRExcLim.u) - annotation (Line(points={{-58,120},{-42,120}}, - color={255,0,255})); + annotation (Line(points={{-58,120},{-42,120}}, color={255,0,255})); connect(or2.y, or1.u1) annotation (Line(points={{-48,230},{-6,230},{-6,140},{ -2,140}}, color={255,0,255})); connect(or1.y, staCoo.u1Up) annotation (Line(points={{22,140},{24,140},{24, 154},{48,154}}, color={255,0,255})); connect(timOPLRExcLim.passed, or1.u2) annotation (Line(points={{-18,112},{-14, - 112},{-14,132},{-2,132}}, - color={255,0,255})); + 112},{-14,132},{-2,132}}, color={255,0,255})); connect(numChi.y, numOpeChi.u2) annotation (Line(points={{72,100},{84,100},{ - 84,114},{88,114}}, - color={255,127,0})); + 84,114},{88,114}}, color={255,127,0})); connect(staCoo.idxSta, numOpeChi.u1) annotation (Line(points={{72,154},{80, - 154},{80,126},{88,126}}, - color={255,127,0})); + 154},{80,126},{88,126}}, color={255,127,0})); connect(staCoo.idxSta, numOpeCooChiHea.u1) annotation (Line(points={{72,154}, {80,154},{80,60},{-132,60},{-132,26},{-122,26}}, color={255,127,0})); connect(numOpeChi.y, numOpeCooChiHea.u2) annotation (Line(points={{112,120},{ @@ -394,28 +449,25 @@ equation connect(timOPLRExcLim3.passed, dowAndNotFail.u2) annotation (Line(points={{-18,72}, {-10,72},{-10,92},{-2,92}}, color={255,0,255})); connect(notFail.y, dowAndNotFail.u1) annotation (Line(points={{-18,200},{-10, - 200},{-10,100},{-2,100}}, - color={255,0,255})); + 200},{-10,100},{-2,100}}, color={255,0,255})); connect(staHea.idxSta, nChiHeaAndCooUnb.u2) annotation (Line(points={{72,-120}, {80,-120},{80,-80},{-100,-80},{-100,-6},{-82,-6}}, color={255,127,0})); connect(numOpeCooChiHea.y, numChiCasCoo.u1) annotation (Line(points={{-98,20}, {30,20},{30,26},{38,26}}, color={255,127,0})); connect(movAve.y, cmpOPLRLimUp.u1) - annotation (Line(points={{-128,120},{-82,120}}, - color={0,0,127})); - connect(capCoo.y, cmpOPLRLimUp.u2) annotation (Line(points={{-99,100},{-94, - 100},{-94,112},{-82,112}}, - color={0,0,127})); + annotation (Line(points={{-128,120},{-82,120}}, color={0,0,127})); + connect(capCoo.y, cmpOPLRLimUp.u2) annotation (Line(points={{-158,90},{-94,90}, + {-94,112},{-82,112}}, color={0,0,127})); connect(movAve.y, cmpOPLRLimDow1.u1) annotation (Line(points={{-128,120},{-90, 120},{-90,80},{-82,80}},color={0,0,127})); connect(capCooLow.y, cmpOPLRLimDow1.u2) - annotation (Line(points={{-99,72},{-82,72}}, color={0,0,127})); - connect(capHea.y, cmpOPLRLimUp1.u2) annotation (Line(points={{-99,-140},{-94, - -140},{-94,-128},{-82,-128}}, color={0,0,127})); + annotation (Line(points={{-158,50},{-140,50},{-140,72},{-82,72}}, color={0,0,127})); + connect(capHea.y, cmpOPLRLimUp1.u2) annotation (Line(points={{-128,-160},{-94, + -160},{-94,-128},{-82,-128}}, color={0,0,127})); connect(movAve1.y, cmpOPLRLimUp1.u1) annotation (Line(points={{-128,-120},{-82,-120}}, color={0,0,127})); - connect(capHeaLow.y, cmpOPLRLimDow.u2) annotation (Line(points={{-99,-168},{ - -82,-168}}, color={0,0,127})); + connect(capHeaLow.y, cmpOPLRLimDow.u2) annotation (Line(points={{-98,-180},{-90, + -180},{-90,-168},{-82,-168}}, color={0,0,127})); connect(movAve1.y, cmpOPLRLimDow.u1) annotation (Line(points={{-128,-120},{ -90,-120},{-90,-160},{-82,-160}}, color={0,0,127})); connect(TChiWatSupSet, dTChiWatPos.u2) annotation (Line(points={{-260,80},{ @@ -429,11 +481,9 @@ equation connect(errDpHeaWat.y, cmpErrLim3.u) annotation (Line(points={{-178,-280},{-172,-280}}, color={0,0,127})); connect(cmpErrLim3.y,and1. u1) - annotation (Line(points={{-148,-280},{-142,-280}}, - color={255,0,255})); + annotation (Line(points={{-148,-280},{-142,-280}}, color={255,0,255})); connect(and1.y,timErrExcLim3. u) - annotation (Line(points={{-118,-280},{-112,-280}}, - color={255,0,255})); + annotation (Line(points={{-118,-280},{-112,-280}}, color={255,0,255})); connect(cmpErrLim2.y, and4.u1) annotation (Line(points={{-148,-220},{-142,-220}}, color={255,0,255})); connect(and4.y, timErrExcLim2.u) @@ -468,18 +518,15 @@ equation connect(numChiCasCoo.y, hol.u[2]) annotation (Line(points={{62,20},{116,20},{ 116,-0.25},{128,-0.25}}, color={255,127,0})); connect(numChiHeaCoo.y, hol.u[3]) annotation (Line(points={{22,-20},{116,-20}, - {116,0.25},{128,0.25}}, - color={255,127,0})); + {116,0.25},{128,0.25}}, color={255,127,0})); connect(nChiHeaHeaAndCoo.y, hol.u[4]) annotation (Line(points={{-18,-40},{120, - -40},{120,-2},{128,-2},{128,0.75}}, - color={255,127,0})); + -40},{120,-2},{128,-2},{128,0.75}}, color={255,127,0})); connect(hol.y[1], rep.u) annotation (Line(points={{152,0},{160,0},{160,120},{ 178,120}}, color={255,127,0})); connect(hol.y[2], modHeaCoo.nCasCoo) annotation (Line(points={{152,0},{160,0}, {160,6},{178,6}}, color={255,127,0})); connect(hol.y[3], modHeaCoo.nHeaCoo) annotation (Line(points={{152,0},{160,0}, - {160,-6},{178,-6}}, - color={255,127,0})); + {160,-6},{178,-6}}, color={255,127,0})); connect(hol.y[4], rep5.u) annotation (Line(points={{152,0},{160,0},{160,-100}, {178,-100}},color={255,127,0})); connect(movAve.y, QCooReq_flow) annotation (Line(points={{-128,120},{-100,120}, diff --git a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPump.mo b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPump.mo index 89fd7216c6e..af7a85ac177 100644 --- a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPump.mo +++ b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/StagingPump.mo @@ -9,7 +9,9 @@ block StagingPump "Pump staging" start=1) "Number of pumps" annotation(Evaluate=true); - parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=1 + parameter Real m_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate")=1 "Loop design mass flow rate (all pumps)" annotation(Dialog(group="Nominal condition", enable=have_flowCriterion)); parameter Real yDow=0.30 @@ -21,23 +23,31 @@ block StagingPump "Pump staging" "Lead pump Enable signal (e.g. based on isolation valve opening command)" annotation (Placement(transformation(extent={{-240,140},{-200,180}}), iconTransformation(extent={{-140,40},{-100,80}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput m_flow(final unit="kg/s") + Buildings.Controls.OBC.CDL.Interfaces.RealInput m_flow( + final unit="kg/s") if have_flowCriterion "Mass flow rate as measured by the loop flow meter" - annotation (Placement( - transformation(extent={{-240,60},{-200,100}}),iconTransformation(extent={{-140, - -20},{-100,20}}))); + annotation (Placement(transformation(extent={{-240,60},{-200,100}}), + iconTransformation(extent={{-140,-20},{-100,20}}))); Buildings.Controls.OBC.CDL.Interfaces.RealInput y(final unit="1") "Commanded speed" annotation (Placement(transformation(extent={{-240,-20},{-200,20}}), - iconTransformation(extent={{-140,-80},{-100,-40}}))); + iconTransformation(extent={{-140,-80},{-100,-40}}))); Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1[nPum] "Start signal (VFD Run or motor starter contact)" - annotation (Placement( - transformation(extent={{200,-20},{240,20}}), iconTransformation(extent={{100,40}, - {140,80}}))); + annotation (Placement(transformation(extent={{200,-20},{240,20}}), + iconTransformation(extent={{100,40},{140,80}}))); + Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput nPumEna + "Number of pumps that are enabled" + annotation (Placement(transformation(extent={{200,-80},{240,-40}}), + iconTransformation(extent={{100,-80},{140,-40}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Any + "Return true if any pump enabled (left limit to avoid direct feedback)" + annotation (Placement(transformation(extent={{200,-140},{240,-100}}), + iconTransformation(extent={{100,-20},{140,20}}))); - Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmp(final t=yUp, h=1e-3) + Buildings.Controls.OBC.CDL.Reals.GreaterThreshold cmp( + final t=yUp, h=1e-3) "Compare" annotation (Placement(transformation(extent={{-100,-10},{-80,10}}))); Buildings.Controls.OBC.CDL.Logical.Timer timSpe(t=5*60) @@ -70,10 +80,12 @@ block StagingPump "Pump staging" if have_flowCriterion "Check if true for a given time" annotation (Placement(transformation(extent={{-72,50},{-52,70}}))); - Buildings.Controls.OBC.CDL.Reals.LessThreshold cmp4(final t=yDow, h=1e-3) + Buildings.Controls.OBC.CDL.Reals.LessThreshold cmp4( + final t=yDow, h=1e-3) "Compare" annotation (Placement(transformation(extent={{-100,-50},{-80,-30}}))); - Buildings.Controls.OBC.CDL.Logical.Timer timSpe1(t=5*60) "True delay" + Buildings.Controls.OBC.CDL.Logical.Timer timSpe1(t=5*60) + "True delay" annotation (Placement(transformation(extent={{-70,-50},{-50,-30}}))); Buildings.Controls.OBC.CDL.Logical.Or dow "Check if flow or speed criterion passed for staging down" @@ -89,7 +101,8 @@ block StagingPump "Pump staging" Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator rep( final nout=nPum) "Replicate" annotation (Placement(transformation(extent={{120,-10},{140,10}}))); - Buildings.DHC.Plants.Combined.Controls.BaseClasses.StageIndex staLag(final nSta=max(1, nPum - 1), tSta=30) + Buildings.DHC.Plants.Combined.Controls.BaseClasses.StageIndex staLag( + final nSta=max(1, nPum - 1), tSta=30) if nPum>1 "Stage lag pumps (minimum runtime allowing for pump start time)" annotation (Placement(transformation(extent={{30,-10},{50,10}}))); @@ -110,60 +123,53 @@ block StagingPump "Pump staging" if nPum==1 "Constant" annotation (Placement(transformation(extent={{30,-50},{50,-30}}))); - Buildings.Controls.OBC.CDL.Logical.Sources.Constant fal(final k=false) + Buildings.Controls.OBC.CDL.Logical.Sources.Constant fal( + final k=false) if not have_flowCriterion "Constant" annotation (Placement(transformation(extent={{-70,-90},{-50,-70}}))); - Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput nPumEna - "Number of pumps that are enabled" annotation (Placement(transformation( - extent={{200,-80},{240,-40}}), iconTransformation(extent={{100,-80},{ - 140,-40}}))); - Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Any - "Return true if any pump enabled (left limit to avoid direct feedback)" - annotation (Placement(transformation(extent={{200,-140},{240,-100}}), - iconTransformation(extent={{100,-20},{140,20}}))); - Buildings.Controls.OBC.CDL.Integers.GreaterEqualThreshold anyEna(final t=1) + Buildings.Controls.OBC.CDL.Integers.GreaterEqualThreshold anyEna( + final t=1) "Return true if any pump is enabled" annotation (Placement(transformation(extent={{120,-130},{140,-110}}))); Buildings.Controls.OBC.CDL.Logical.Pre pre1 "Left limit of signal avoiding direct feedback" annotation (Placement(transformation(extent={{160,-130},{180,-110}}))); + equation connect(y, cmp.u) - annotation (Line(points={{-220,0},{-102,0}}, color={0,0,127})); + annotation (Line(points={{-220,0},{-102,0}}, color={0,0,127})); connect(cmp.y, timSpe.u) - annotation (Line(points={{-78,0},{-72,0}}, color={255,0,255})); + annotation (Line(points={{-78,0},{-72,0}}, color={255,0,255})); connect(ratFlo.y, cmp2.u1) annotation (Line(points={{-126,80},{-120,80},{-120,100},{-102,100}}, - color={0,0,127})); + color={0,0,127})); connect(addOff.y, cmp2.u2) annotation (Line(points={{-102,140},{-110,140},{ - -110,92},{-102,92}}, color={0,0,127})); + -110,92},{-102,92}}, color={0,0,127})); connect(timFlo.passed, up.u1) annotation (Line(points={{-50,92},{-36,92},{-36, - 0},{-32,0}}, color={255,0,255})); + 0},{-32,0}}, color={255,0,255})); connect(ratFlo.y, cmp3.u1) annotation (Line(points={{-126,80},{-120,80},{-120, 60},{-102,60}}, color={0,0,127})); connect(y, cmp4.u) annotation (Line(points={{-220,0},{-160,0},{-160,-40},{-102, - -40}}, color={0,0,127})); + -40}}, color={0,0,127})); connect(cmp4.y, timSpe1.u) - annotation (Line(points={{-78,-40},{-72,-40}}, color={255,0,255})); + annotation (Line(points={{-78,-40},{-72,-40}}, color={255,0,255})); connect(timFlo1.passed,dow. u1) annotation (Line(points={{-50,52},{-40,52},{ - -40,-40},{-32,-40}}, color={255,0,255})); + -40,-40},{-32,-40}}, color={255,0,255})); connect(addOff.u, ratOpeDsg.y) annotation (Line(points={{-78,140},{-62,140}}, color={0,0,127})); connect(rep.y, cvtBoo.u) annotation (Line(points={{142,0},{158,0}}, color={255,127,0})); connect(cmp2.y, timFlo.u) - annotation (Line(points={{-78,100},{-74,100}}, - color={255,0,255})); + annotation (Line(points={{-78,100},{-74,100}}, color={255,0,255})); connect(cmp3.y, timFlo1.u) annotation (Line(points={{-78,60},{-74,60}}, color={255,0,255})); connect(timSpe.passed, up.u2) annotation (Line(points={{-48,-8},{-32,-8}}, - color={255,0,255})); + color={255,0,255})); connect(timSpe1.passed,dow. u2) annotation (Line(points={{-48,-48},{-40,-48}, {-40,-48},{-32,-48}},color={255,0,255})); connect(y1Ena, staLag.u1) annotation (Line(points={{-220,160},{0,160},{0,6},{ - 28,6}}, - color={255,0,255})); + 28,6}}, color={255,0,255})); connect(cvtInt.y, ratOpeDsg.u) annotation (Line(points={{28,140},{-38,140}}, color={0,0,127})); connect(cvtBoo.y, y1) @@ -173,21 +179,17 @@ equation connect(addOffLowSta.y, cmp3.u2) annotation (Line(points={{-128,40},{-116,40}, {-116,52},{-102,52}}, color={0,0,127})); connect(y1Ena, leaEna.u) annotation (Line(points={{-220,160},{0,160},{0,40},{ - 28,40}}, - color={255,0,255})); + 28,40}}, color={255,0,255})); connect(dow.y, staLag.u1Dow) annotation (Line(points={{-8,-40},{0,-40},{0, - -5.8},{28,-5.8}}, - color={255,0,255})); + -5.8},{28,-5.8}}, color={255,0,255})); connect(num.y, rep.u) - annotation (Line(points={{102,0},{118,0}}, - color={255,127,0})); + annotation (Line(points={{102,0},{118,0}}, color={255,127,0})); connect(staLag.idxSta, num.u2) annotation (Line(points={{52,0},{60,0},{60,-6}, {78,-6}}, color={255,127,0})); connect(leaEna.y, num.u1) annotation (Line(points={{52,40},{60,40},{60,6},{78, 6}}, color={255,127,0})); connect(numPre.y, cvtInt.u) annotation (Line(points={{102,60},{120,60},{120, - 140},{52,140}}, - color={255,127,0})); + 140},{52,140}}, color={255,127,0})); connect(leaEna.y, numPre.u1) annotation (Line(points={{52,40},{60,40},{60,66}, {78,66}}, color={255,127,0})); connect(staLag.preIdxSta, numPre.u2) annotation (Line(points={{52,-6},{56,-6}, @@ -195,7 +197,7 @@ equation connect(zer.y, num.u2) annotation (Line(points={{52,-40},{68,-40},{68,-6},{78, -6}}, color={255,127,0})); connect(zer.y, numPre.u2) annotation (Line(points={{52,-40},{68,-40},{68,54}, - {78,54}},color={255,127,0})); + {78,54}}, color={255,127,0})); connect(up.y, staLag.u1Up) annotation (Line(points={{-8,0},{28,0}}, color={255,0,255})); connect(fal.y, dow.u1) annotation (Line(points={{-48,-80},{-36,-80},{-36,-40}, diff --git a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/TankCycle.mo b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/TankCycle.mo index 664ee6aee6d..8ed57b448ed 100644 --- a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/TankCycle.mo +++ b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/TankCycle.mo @@ -1,10 +1,14 @@ within Buildings.DHC.Plants.Combined.Controls.BaseClasses; block TankCycle "Block that determines the tank cycle flag" - parameter Modelica.Units.SI.MassFlowRate mConWatHexCoo_flow_nominal + parameter Real mConWatHexCoo_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate") "Design total CW mass flow rate through condenser barrels (all units)"; - - parameter Modelica.Units.SI.Temperature TTanSet[2, 2] + parameter Real TTanSet[2, 2]( + each final quantity="ThermodynamicTemperature", + each final unit="K", + each displayUnit="degC") "Tank temperature setpoints: 2 cycles with 2 setpoints" annotation(Dialog(group="CW loop, TES tank and heat pumps")); parameter Integer nTTan=0 @@ -20,161 +24,179 @@ block TankCycle "Block that determines the tank cycle flag" each final unit="K", each displayUnit="degC") "TES tank temperature" - annotation (Placement( - transformation(extent={{-200,-60},{-160,-20}}), iconTransformation( - extent={{-140,-80},{-100,-40}}))); + annotation (Placement(transformation(extent={{-200,-60},{-160,-20}}), + iconTransformation(extent={{-140,-80},{-100,-40}}))); Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput idxCycTan( final min=1, final max=2) "Index of active tank cycle" annotation (Placement(transformation(extent={{160,-20},{200,20}}), - iconTransformation(extent={{100,-20},{140,20}}))); + iconTransformation(extent={{100,-20},{140,20}}))); Buildings.Controls.OBC.CDL.Reals.GreaterThreshold criTem1[nTTan]( each t=sum(TTanSet[2])/2, each h=1E-4) "Temperature criterion for first tank cycle" annotation (Placement(transformation(extent={{-140,-50},{-120,-30}}))); - Buildings.Controls.OBC.CDL.Logical.MultiAnd allCriTem1(final nin=nTTan) + Buildings.Controls.OBC.CDL.Logical.MultiAnd allCriTem1( + final nin=nTTan) "All temperature criteria met" - annotation (Placement(transformation(extent={{-60,-50},{-40,-30}}))); - Buildings.Controls.OBC.CDL.Reals.GreaterThreshold criFlo1(final t=1E-3* - mConWatHexCoo_flow_nominal, h=1E-3*mConWatHexCoo_flow_nominal/2) + annotation (Placement(transformation(extent={{-100,-50},{-80,-30}}))); + Buildings.Controls.OBC.CDL.Reals.GreaterThreshold criFlo1( + final t=1E-3*mConWatHexCoo_flow_nominal, + h=1E-3*mConWatHexCoo_flow_nominal/2) "Flow criterion for first tank cycle" annotation (Placement(transformation(extent={{-150,110},{-130,130}}))); - Buildings.Controls.OBC.CDL.Reals.LessThreshold criTem2[nTTan](each t=sum(TTanSet[1])/2, each h=1E-4) + Buildings.Controls.OBC.CDL.Reals.LessThreshold criTem2[nTTan]( + each t=sum(TTanSet[1])/2, + each h=1E-4) "Temperature criterion for first tank cycle" annotation (Placement(transformation(extent={{-140,-90},{-120,-70}}))); Buildings.Controls.OBC.CDL.Logical.MultiAnd allCriTem2(final nin=nTTan) "All temperature criteria met" - annotation (Placement(transformation(extent={{-60,-90},{-40,-70}}))); - Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt(final - integerTrue=1, final integerFalse=2) "Convert" - annotation (Placement(transformation(extent={{-70,110},{-50,130}}))); + annotation (Placement(transformation(extent={{-100,-90},{-80,-70}}))); + Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt( + final integerTrue=1, + final integerFalse=2) + "Convert" + annotation (Placement(transformation(extent={{-100,110},{-80,130}}))); Buildings.Controls.OBC.CDL.Logical.Or or2 "Neither of temperature criterion is true" annotation (Placement( transformation( extent={{-10,-10},{10,10}}, rotation=90, - origin={0,10}))); + origin={-20,10}))); Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt3(final integerTrue=2, final integerFalse=0) "Convert" annotation (Placement( transformation( extent={{-10,-10},{10,10}}, rotation=90, - origin={-30,10}))); + origin={-60,10}))); Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt4(final integerTrue=1, final integerFalse=0) "Convert" annotation (Placement( transformation( extent={{-10,-10},{10,10}}, rotation=90, - origin={-60,10}))); + origin={-90,10}))); Buildings.Controls.OBC.CDL.Integers.Max maxInt1 "Set cycle index as maximum" annotation (Placement(transformation( extent={{-10,-10},{10,10}}, rotation=90, - origin={-40,90}))); + origin={-50,90}))); Buildings.Controls.OBC.CDL.Logical.And allCri2 "All criteria met" - annotation (Placement(transformation(extent={{-20,-90},{0,-70}}))); + annotation (Placement(transformation(extent={{-40,-90},{-20,-70}}))); Buildings.Controls.OBC.CDL.Logical.And allCri1 "All criteria met" - annotation (Placement(transformation(extent={{-20,-50},{0,-30}}))); - Buildings.Controls.OBC.CDL.Integers.Switch idxIni "Index at initial time" - annotation (Placement(transformation( - extent={{-10,-10},{10,10}}, - rotation=0, - origin={110,120}))); + annotation (Placement(transformation(extent={{-40,-50},{-20,-30}}))); + Buildings.Controls.OBC.CDL.Integers.Switch idxIni + "Index at initial time" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0, origin={110,120}))); Buildings.Controls.OBC.CDL.Logical.Timer timAllCri1(t=5*60) "All criteria met for given time" - annotation (Placement(transformation(extent={{10,-50},{30,-30}}))); + annotation (Placement(transformation(extent={{0,-50},{20,-30}}))); Buildings.Controls.OBC.CDL.Logical.Timer timAllCri2(t=5*60) "All criteria met for given time" - annotation (Placement(transformation(extent={{10,-90},{30,-70}}))); - Buildings.Controls.OBC.CDL.Integers.Switch - intSwi "Switch index" - annotation (Placement(transformation(extent={{110,-10},{130,10}}))); - Buildings.Controls.OBC.CDL.Integers.Sources.Constant idx1(final k=1) "Index" - annotation (Placement(transformation(extent={{40,10},{60,30}}))); - Buildings.Controls.OBC.CDL.Integers.Switch - intSwi1 "Switch index" - annotation (Placement(transformation(extent={{70,-110},{90,-90}}))); - Buildings.Controls.OBC.CDL.Integers.Sources.Constant idx2(final k=2) "Index" - annotation (Placement(transformation(extent={{40,-90},{60,-70}}))); + annotation (Placement(transformation(extent={{0,-90},{20,-70}}))); + Buildings.Controls.OBC.CDL.Integers.Switch intSwi + "Switch index" + annotation (Placement(transformation(extent={{80,-10},{100,10}}))); + Buildings.Controls.OBC.CDL.Integers.Sources.Constant idx1( + final k=1) + "Index" + annotation (Placement(transformation(extent={{0,80},{20,100}}))); + Buildings.Controls.OBC.CDL.Integers.Switch intSwi1 + "Switch index" + annotation (Placement(transformation(extent={{42,-110},{62,-90}}))); + Buildings.Controls.OBC.CDL.Integers.Sources.Constant idx2( + final k=2) + "Index" + annotation (Placement(transformation(extent={{0,40},{20,60}}))); Modelica.Blocks.Sources.IntegerExpression preIdxCycTan(y=pre(idxCycTan)) "Previous index value" - annotation (Placement(transformation(extent={{38,-130},{60,-110}}))); + annotation (Placement(transformation(extent={{-20,-130},{2,-110}}))); Buildings.Controls.OBC.CDL.Logical.Not criFlo2 "Flow criterion for second tank cycle" - annotation (Placement(transformation(extent={{-140,70},{-120,90}}))); - Buildings.DHC.Plants.Combined.Controls.BaseClasses.IntegerArrayHold hol(holdDuration=30*60, nin=1) "Hold for minimum runtime" - annotation (Placement(transformation(extent={{136,-10},{156,10}}))); + annotation (Placement(transformation(extent={{-100,-130},{-80,-110}}))); + Buildings.DHC.Plants.Combined.Controls.BaseClasses.IntegerArrayHold hol( + holdDuration=30*60, + nin=1) + "Hold for minimum runtime" + annotation (Placement(transformation(extent={{110,-10},{130,10}}))); + initial equation pre(idxCycTan)=idxIni.y; equation connect(criTem1.y, allCriTem1.u) - annotation (Line(points={{-118,-40},{-62,-40}},color={255,0,255})); + annotation (Line(points={{-118,-40},{-102,-40}}, + color={255,0,255})); connect(TTan, criTem2.u) annotation (Line(points={{-180,-40},{-152,-40},{-152, -80},{-142,-80}}, color={0,0,127})); connect(TTan, criTem1.u) annotation (Line(points={{-180,-40},{-142,-40}},color={0,0,127})); connect(criTem2.y, allCriTem2.u) - annotation (Line(points={{-118,-80},{-62,-80}}, color={255,0,255})); - connect(allCriTem2.y, booToInt3.u) annotation (Line(points={{-38,-80},{-30, - -80},{-30,-2}}, + annotation (Line(points={{-118,-80},{-102,-80}}, color={255,0,255})); + connect(allCriTem2.y, booToInt3.u) annotation (Line(points={{-78,-80},{-60, + -80},{-60,-2}}, color={255,0,255})); - connect(allCriTem1.y, booToInt4.u) annotation (Line(points={{-38,-40},{-34, - -40},{-34,-20},{-60,-20},{-60,-2}}, + connect(allCriTem1.y, booToInt4.u) annotation (Line(points={{-78,-40},{-70, + -40},{-70,-10},{-90,-10},{-90,-2}}, color={255,0,255})); connect(allCriTem1.y, allCri1.u1) - annotation (Line(points={{-38,-40},{-22,-40}}, color={255,0,255})); + annotation (Line(points={{-78,-40},{-42,-40}}, color={255,0,255})); connect(allCriTem2.y, allCri2.u1) - annotation (Line(points={{-38,-80},{-22,-80}}, color={255,0,255})); - connect(maxInt1.u2, booToInt3.y) annotation (Line(points={{-34,78},{-34,30},{-30, - 30},{-30,22}}, color={255,127,0})); - connect(booToInt4.y, maxInt1.u1) annotation (Line(points={{-60,22},{-60,30},{-46, - 30},{-46,78}}, color={255,127,0})); - connect(allCriTem1.y, or2.u1) annotation (Line(points={{-38,-40},{-34,-40},{ - -34,-20},{0,-20},{0,-2}}, color={255,0,255})); - connect(allCriTem2.y, or2.u2) annotation (Line(points={{-38,-80},{-30,-80},{ - -30,-24},{8,-24},{8,-2}}, color={255,0,255})); - connect(or2.y, idxIni.u2) annotation (Line(points={{0,22},{0,120},{98,120}}, + annotation (Line(points={{-78,-80},{-42,-80}}, color={255,0,255})); + connect(maxInt1.u2, booToInt3.y) annotation (Line(points={{-44,78},{-44,30},{ + -60,30},{-60,22}}, + color={255,127,0})); + connect(booToInt4.y, maxInt1.u1) annotation (Line(points={{-90,22},{-90,40},{ + -56,40},{-56,78}}, + color={255,127,0})); + connect(allCriTem1.y, or2.u1) annotation (Line(points={{-78,-40},{-70,-40},{ + -70,-10},{-20,-10},{-20,-2}}, color={255,0,255})); + connect(allCriTem2.y, or2.u2) annotation (Line(points={{-78,-80},{-60,-80},{ + -60,-20},{-12,-20},{-12,-2}}, + color={255,0,255})); + connect(or2.y, idxIni.u2) annotation (Line(points={{-20,22},{-20,120},{98,120}}, color={255,0,255})); connect(maxInt1.y, idxIni.u1) - annotation (Line(points={{-40,102},{-40,128},{98,128}}, + annotation (Line(points={{-50,102},{-50,128},{98,128}}, color={255,127,0})); connect(criFlo1.y, booToInt.u) - annotation (Line(points={{-128,120},{-72,120}}, + annotation (Line(points={{-128,120},{-102,120}}, color={255,0,255})); - connect(booToInt.y, idxIni.u3) annotation (Line(points={{-48,120},{-20,120},{-20, - 112},{98,112}},color={255,127,0})); + connect(booToInt.y, idxIni.u3) annotation (Line(points={{-78,120},{-70,120},{ + -70,112},{98,112}}, + color={255,127,0})); connect(mConWatOutTan_flow, criFlo1.u) annotation (Line(points={{-180,120},{-152,120}}, color={0,0,127})); connect(allCri1.y, timAllCri1.u) - annotation (Line(points={{2,-40},{8,-40}}, color={255,0,255})); + annotation (Line(points={{-18,-40},{-2,-40}}, + color={255,0,255})); connect(allCri2.y, timAllCri2.u) - annotation (Line(points={{2,-80},{8,-80}}, color={255,0,255})); - connect(timAllCri1.passed, intSwi.u2) annotation (Line(points={{32,-48},{80, - -48},{80,0},{108,0}}, color={255,0,255})); - connect(idx1.y, intSwi.u1) annotation (Line(points={{62,20},{100,20},{100,8}, - {108,8}}, color={255,127,0})); - connect(timAllCri2.passed, intSwi1.u2) annotation (Line(points={{32,-88},{36, - -88},{36,-100},{68,-100}}, color={255,0,255})); - connect(idx2.y, intSwi1.u1) annotation (Line(points={{62,-80},{66,-80},{66, - -92},{68,-92}}, color={255,127,0})); - connect(intSwi1.y, intSwi.u3) annotation (Line(points={{92,-100},{100,-100},{ - 100,-8},{108,-8}}, color={255,127,0})); - connect(preIdxCycTan.y, intSwi1.u3) annotation (Line(points={{61.1,-120},{66, - -120},{66,-108},{68,-108}}, color={255,127,0})); - connect(criFlo1.y, criFlo2.u) annotation (Line(points={{-128,120},{-120,120}, - {-120,100},{-150,100},{-150,80},{-142,80}}, + annotation (Line(points={{-18,-80},{-2,-80}},color={255,0,255})); + connect(timAllCri1.passed, intSwi.u2) annotation (Line(points={{22,-48},{50, + -48},{50,0},{78,0}}, color={255,0,255})); + connect(idx1.y, intSwi.u1) annotation (Line(points={{22,90},{70,90},{70,8},{ + 78,8}}, color={255,127,0})); + connect(timAllCri2.passed, intSwi1.u2) annotation (Line(points={{22,-88},{30, + -88},{30,-100},{40,-100}}, color={255,0,255})); + connect(idx2.y, intSwi1.u1) annotation (Line(points={{22,50},{34,50},{34,-92}, + {40,-92}}, color={255,127,0})); + connect(intSwi1.y, intSwi.u3) annotation (Line(points={{64,-100},{70,-100},{ + 70,-8},{78,-8}}, color={255,127,0})); + connect(preIdxCycTan.y, intSwi1.u3) annotation (Line(points={{3.1,-120},{32, + -120},{32,-108},{40,-108}}, color={255,127,0})); + connect(criFlo1.y, criFlo2.u) annotation (Line(points={{-128,120},{-110,120}, + {-110,-120},{-102,-120}}, color={255,0,255})); connect(hol.y[1], idxCycTan) - annotation (Line(points={{158,0},{180,0}}, color={255,127,0})); - connect(criFlo1.y, allCri1.u2) annotation (Line(points={{-128,120},{-100,120}, - {-100,-54},{-26,-54},{-26,-48},{-22,-48}}, color={255,0,255})); - connect(criFlo2.y, allCri2.u2) annotation (Line(points={{-118,80},{-106,80},{ - -106,-60},{-26,-60},{-26,-88},{-22,-88}}, color={255,0,255})); + annotation (Line(points={{132,0},{180,0}}, color={255,127,0})); + connect(criFlo1.y, allCri1.u2) annotation (Line(points={{-128,120},{-110,120}, + {-110,-60},{-50,-60},{-50,-48},{-42,-48}}, color={255,0,255})); + connect(criFlo2.y, allCri2.u2) annotation (Line(points={{-78,-120},{-50,-120}, + {-50,-88},{-42,-88}}, color={255,0,255})); connect(intSwi.y, hol.u[1]) - annotation (Line(points={{132,0},{134,0}}, color={255,127,0})); + annotation (Line(points={{102,0},{108,0}}, color={255,127,0})); annotation ( defaultComponentName="cycTan", Icon(coordinateSystem(preserveAspectRatio=false), graphics={ diff --git a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/ValveCondenserEvaporator.mo b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/ValveCondenserEvaporator.mo index 84ebbd4349c..469e31d7ebc 100644 --- a/Buildings/DHC/Plants/Combined/Controls/BaseClasses/ValveCondenserEvaporator.mo +++ b/Buildings/DHC/Plants/Combined/Controls/BaseClasses/ValveCondenserEvaporator.mo @@ -10,49 +10,77 @@ block ValveCondenserEvaporator "Number of units operating at design conditions" annotation (Dialog(group="HW loop and heat recovery chillers"), Evaluate=true); - parameter Modelica.Units.SI.MassFlowRate mChiWatChi_flow_nominal + parameter Real mChiWatChi_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate") "Chiller CHW design mass flow rate (value will be used for each unit)" annotation(Dialog(group="CHW loop and cooling-only chillers")); - parameter Modelica.Units.SI.MassFlowRate mChiWatChi_flow_min + parameter Real mChiWatChi_flow_min( + final unit="kg/s", + final quantity="MassFlowRate") "Chiller CHW minimum mass flow rate (value will be used for each unit)" annotation(Dialog(group="CHW loop and cooling-only chillers")); - parameter Modelica.Units.SI.MassFlowRate mConWatChi_flow_nominal + parameter Real mConWatChi_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate") "Chiller CW design mass flow rate (value will be used for each unit)" annotation(Dialog(group="CHW loop and cooling-only chillers")); - parameter Modelica.Units.SI.PressureDifference dpEvaChi_nominal(displayUnit="Pa") + parameter Real dpEvaChi_nominal( + final quantity="PressureDifference", + final unit="Pa", + displayUnit="Pa") "Chiller evaporator design pressure drop (value will be used for each unit)" annotation(Dialog(group="CHW loop and cooling-only chillers")); - parameter Modelica.Units.SI.PressureDifference dpValEvaChi_nominal( - displayUnit="Pa") + parameter Real dpValEvaChi_nominal( + final quantity="PressureDifference", + final unit="Pa", + displayUnit="Pa") "Chiller evaporator isolation valve design pressure drop (value will be used for each unit)" annotation(Dialog(group="CHW loop and cooling-only chillers")); - parameter Modelica.Units.SI.MassFlowRate mChiWatChiHea_flow_nominal + parameter Real mChiWatChiHea_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate") "HRC CHW design mass flow rate (value will be used for each unit)" annotation(Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.MassFlowRate mChiWatChiHea_flow_min + parameter Real mChiWatChiHea_flow_min( + final unit="kg/s", + final quantity="MassFlowRate") "HRC CHW minimum mass flow rate (value will be used for each unit)" annotation(Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.MassFlowRate mConWatChiHea_flow_nominal + parameter Real mConWatChiHea_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate") "HRC CW design mass flow rate (value will be used for each unit)" annotation(Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.MassFlowRate mHeaWatChiHea_flow_min + parameter Real mHeaWatChiHea_flow_min( + final unit="kg/s", + final quantity="MassFlowRate") "Chiller HW minimum mass flow rate (value will be used for each unit)" annotation(Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.PressureDifference dpEvaChiHea_nominal( - displayUnit="Pa") + parameter Real dpEvaChiHea_nominal( + final quantity="PressureDifference", + final unit="Pa", + displayUnit="Pa") "Design chiller evaporator pressure drop (value will be used for each unit)" annotation(Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.PressureDifference dpValEvaChiHea_nominal( - displayUnit="Pa") + parameter Real dpValEvaChiHea_nominal( + final quantity="PressureDifference", + final unit="Pa", + displayUnit="Pa") "HRC evaporator isolation valve design pressure drop (value will be used for each unit)" annotation(Dialog(group="HW loop and heat recovery chillers")); - parameter Modelica.Units.SI.Temperature TTanSet[2, 2] + parameter Real TTanSet[2, 2]( + each final quantity="ThermodynamicTemperature", + each final unit="K", + each displayUnit="degC") "Tank temperature setpoints: 2 cycles with 2 setpoints" annotation(Dialog(group="CW loop, TES tank and heat pumps")); parameter Real k(min=0)=0.01 "Gain of controller" annotation (Dialog(group="Control parameters")); - parameter Modelica.Units.SI.Time Ti=60 + parameter Real Ti( + final quantity="Time", + final unit="s")=60 "Time constant of integrator block" annotation (Dialog(group="Control parameters")); parameter Real yMin=0.1 @@ -71,13 +99,15 @@ block ValveCondenserEvaporator then 1 else (dpValEvaChiHea_nominal / (dpEvaChi_nominal + dpValEvaChi_nominal - dpEvaChiHea_nominal))^0.5 "HRC evaporator isolation valve opening for flow balancing with chiller"; - Buildings.Controls.OBC.CDL.Interfaces.IntegerInput idxCycTan(final min=1, - final max=2) + Buildings.Controls.OBC.CDL.Interfaces.IntegerInput idxCycTan( + final min=1, + final max=2) "Index of active tank cycle" annotation (Placement(transformation(extent={{-280,80},{-240,120}}), iconTransformation(extent={{-140,60},{-100,100}}))); - Buildings.Controls.OBC.CDL.Interfaces.IntegerInput mode(final min=Buildings.DHC.Plants.Combined.Controls.ModeCondenserLoop.tankCharge, - final max=Buildings.DHC.Plants.Combined.Controls.ModeCondenserLoop.heatRejection) + Buildings.Controls.OBC.CDL.Interfaces.IntegerInput mode( + final min=Buildings.DHC.Plants.Combined.Controls.ModeCondenserLoop.tankCharge, + final max=Buildings.DHC.Plants.Combined.Controls.ModeCondenserLoop.heatRejection) "Condenser loop operating mode" annotation (Placement(transformation(extent={{-280,160},{-240,200}}), iconTransformation(extent={{-140,80},{-100,120}}))); @@ -113,17 +143,16 @@ block ValveCondenserEvaporator annotation (Placement(transformation( extent={{-20,-20},{20,20}}, rotation=0, - origin={-260,-100}), - iconTransformation( + origin={-260,-100}), iconTransformation( extent={{-20,-20},{20,20}}, rotation=0, origin={-120,120}))); - Buildings.Controls.OBC.CDL.Interfaces.RealInput TEvaLvgChiHea[nChiHea](each final - unit="K", each displayUnit="degC") + Buildings.Controls.OBC.CDL.Interfaces.RealInput TEvaLvgChiHea[nChiHea]( + each final unit="K", + each displayUnit="degC") "HRC evaporator barrel leaving temperature" - annotation (Placement( - transformation(extent={{-280,20},{-240,60}}), iconTransformation( - extent={{-140,-160},{-100,-120}}))); + annotation (Placement(transformation(extent={{-280,20},{-240,60}}), + iconTransformation(extent={{-140,-160},{-100,-120}}))); Buildings.Controls.OBC.CDL.Interfaces.RealInput mEvaChiSet_flow(final unit="kg/s") "Chiller evaporator flow setpoint" annotation (Placement( @@ -255,8 +284,8 @@ block ValveCondenserEvaporator extent={{-20,-20},{20,20}}, rotation=0, origin={120,20}))); - Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValConChi[nChi](each final - unit="1") + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValConChi[nChi]( + each final unit="1") "Cooling-only chiller condenser isolation valve commanded position" annotation ( Placement(transformation( @@ -266,8 +295,9 @@ block ValveCondenserEvaporator extent={{-20,-20},{20,20}}, rotation=0, origin={120,0}))); - Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValEvaChiHea[nChiHea](each final - unit="1") "HRC evaporator isolation valve commanded position" + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValEvaChiHea[nChiHea]( + each final unit="1") + "HRC evaporator isolation valve commanded position" annotation (Placement( transformation( extent={{-20,-20},{20,20}}, @@ -276,8 +306,9 @@ block ValveCondenserEvaporator extent={{-20,-20},{20,20}}, rotation=0, origin={120,-20}))); - Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValConChiHea[nChiHea](each final - unit="1") "HRC condenser isolation valve commanded position" + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValConChiHea[nChiHea]( + each final unit="1") + "HRC condenser isolation valve commanded position" annotation ( Placement(transformation( extent={{-20,-20},{20,20}}, @@ -288,7 +319,8 @@ block ValveCondenserEvaporator rotation=0, origin={120,-40}))); Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValEvaSwiChiHea[nChiHea]( - each final unit="1") "HRC evaporator switchover valve commanded position" + each final unit="1") + "HRC evaporator switchover valve commanded position" annotation (Placement(transformation( extent={{-20,-20},{20,20}}, rotation=0, @@ -297,7 +329,8 @@ block ValveCondenserEvaporator rotation=0, origin={120,-60}))); Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValConSwiChiHea[nChiHea]( - each final unit="1") "HRC condenser switchover valve commanded position" + each final unit="1") + "HRC condenser switchover valve commanded position" annotation (Placement(transformation( extent={{-20,-20},{20,20}}, rotation=0, @@ -306,7 +339,8 @@ block ValveCondenserEvaporator rotation=0, origin={120,-80}))); Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValConWatEvaMix - "HRC evaporator CW mixing valve commanded position" annotation (Placement( + "HRC evaporator CW mixing valve commanded position" + annotation (Placement( transformation( extent={{-20,-20},{20,20}}, rotation=0, @@ -314,15 +348,18 @@ block ValveCondenserEvaporator extent={{-20,-20},{20,20}}, rotation=0, origin={120,-100}))); - Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValChiWatMinByp(final unit= - "1") "CHW minimum flow bypass valve control signal" annotation ( - Placement(transformation(extent={{240,440},{280,480}}), + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValChiWatMinByp( + final unit="1") + "CHW minimum flow bypass valve control signal" + annotation (Placement(transformation(extent={{240,440},{280,480}}), iconTransformation(extent={{100,60},{140,100}}))); - Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValHeaWatMinByp(final unit= - "1") "HW minimum flow bypass valve control signal" annotation ( - Placement(transformation(extent={{240,400},{280,440}}), + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yValHeaWatMinByp( + final unit="1") + "HW minimum flow bypass valve control signal" + annotation (Placement(transformation(extent={{240,400},{280,440}}), iconTransformation(extent={{100,40},{140,80}}))); - ETS.Combined.Controls.PIDWithEnable valEvaChi[nChi]( + + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valEvaChi[nChi]( each k=k, each Ti=Ti, each final yMin=yMin, @@ -332,7 +369,7 @@ block ValveCondenserEvaporator each final y_neutral=y_neutral) "Chiller evaporator isolation valve control when HRC in direct HR" annotation (Placement(transformation(extent={{-110,390},{-90,410}}))); - ETS.Combined.Controls.PIDWithEnable valConChi[nChi]( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valConChi[nChi]( each k=k, each Ti=Ti, each final yMin=yMin, @@ -341,7 +378,7 @@ block ValveCondenserEvaporator each final y_reset=y_reset, each final y_neutral=y_neutral) "Chiller condenser isolation valve control" annotation (Placement(transformation(extent={{70,350},{90,370}}))); - ETS.Combined.Controls.PIDWithEnable valEvaChiHea[nChiHea]( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valEvaChiHea[nChiHea]( each k=4*k, each Ti=Ti/3, each final yMin=yMin, @@ -350,7 +387,7 @@ block ValveCondenserEvaporator each final y_reset=y_reset, each final y_neutral=y_neutral) "HRC evaporator isolation valve control" annotation (Placement(transformation(extent={{-130,-10},{-110,10}}))); - ETS.Combined.Controls.PIDWithEnable valConChiHea[nChiHea]( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valConChiHea[nChiHea]( each k=k, each Ti=Ti, each final yMin=yMin, @@ -362,10 +399,8 @@ block ValveCondenserEvaporator annotation (Placement(transformation(extent={{50,-50},{70,-30}}))); Buildings.Controls.OBC.CDL.Conversions.BooleanToReal yValConSwi[nChiHea] "HRC condenser switchover valve commanded position" - annotation (Placement(transformation( - extent={{-10,-10},{10,10}}, - rotation=0, - origin={130,-240}))); + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0, origin={130,-240}))); Buildings.Controls.OBC.CDL.Logical.Not hea[nChiHea] "Return true if heating" annotation (Placement(transformation( extent={{-10,-10},{10,10}}, @@ -540,7 +575,7 @@ block ValveCondenserEvaporator extent={{-10,-10},{10,10}}, rotation=0, origin={-130,-380}))); - ETS.Combined.Controls.PIDWithEnable valConSwi( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valConSwi( u_s(unit="K", displayUnit="degC"), u_m(unit="K", displayUnit="degC"), k=k, @@ -591,7 +626,7 @@ block ValveCondenserEvaporator extent={{-10,-10},{10,10}}, rotation=0, origin={-70,-360}))); - ETS.Combined.Controls.PIDWithEnable ctlTConWatEvaLvg[nChiHea]( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable ctlTConWatEvaLvg[nChiHea]( u_s(each final unit="K", each displayUnit="degC"), u_m(each final unit="K", each displayUnit="degC"), each final k=k/2, @@ -639,7 +674,7 @@ block ValveCondenserEvaporator Buildings.Controls.OBC.CDL.Reals.Switch selFloSet[nChiHea] "Select HRC evaporator flow setpoint based on operating mode" annotation (Placement(transformation(extent={{-160,-10},{-140,10}}))); - ETS.Combined.Controls.PIDWithEnable ctlTConWatEvaEnt( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable ctlTConWatEvaEnt( u_s(final unit="K", displayUnit="degC"), u_m(final unit="K", displayUnit="degC"), k=k, @@ -678,7 +713,7 @@ block ValveCondenserEvaporator Buildings.Controls.OBC.CDL.Routing.RealExtractor TConWatConRetSet(final nin=2) "Extract value at given index" annotation (Placement(transformation(extent={{-170,90},{-150,110}}))); - ETS.Combined.Controls.PIDWithEnable ctlTConWatConRet( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable ctlTConWatConRet( u_s(final unit="K", displayUnit="degC"), u_m(final unit="K", displayUnit="degC"), k=k, @@ -718,7 +753,7 @@ block ValveCondenserEvaporator extent={{-10,-10},{10,10}}, rotation=0, origin={30,-40}))); - ETS.Combined.Controls.PIDWithEnable ctlTConLvgChi[nChi + + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable ctlTConLvgChi[nChi + nChiHea]( u_s(each final unit="K", each displayUnit="degC"), u_m(each final unit="K", each displayUnit="degC"), @@ -731,7 +766,8 @@ block ValveCondenserEvaporator each final y_neutral=0) "Condenser leaving temperature control" annotation (Placement(transformation(extent={{-70,250},{-50,270}}))); - Buildings.Controls.OBC.CDL.Integers.Sources.Constant tanCha(final k=Buildings.DHC.Plants.Combined.Controls.ModeCondenserLoop.tankCharge) + Buildings.Controls.OBC.CDL.Integers.Sources.Constant tanCha( + final k=Buildings.DHC.Plants.Combined.Controls.ModeCondenserLoop.tankCharge) "Tank charge/discharge mode index" annotation (Placement(transformation(extent={{-210,190},{-190,210}}))); Buildings.Controls.OBC.CDL.Integers.Equal isTanCha @@ -762,7 +798,7 @@ block ValveCondenserEvaporator Buildings.Controls.OBC.CDL.Reals.Switch swiFloSet1[nChi + nChiHea] "Switch condenser flow setpoint based on condenser loop operating mode" annotation (Placement(transformation(extent={{-10,230},{10,250}}))); - ETS.Combined.Controls.PIDWithEnable valChiWatMinByp[nChi + + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valChiWatMinByp[nChi + nChiHea]( each k=0.01, each Ti=Ti, @@ -772,7 +808,7 @@ block ValveCondenserEvaporator each final y_reset=0, each final y_neutral=0) "CHW minimum flow bypass valve control" annotation (Placement(transformation(extent={{144,450},{164,470}}))); - ETS.Combined.Controls.PIDWithEnable valHeaWatMinByp[nChiHea]( + Buildings.DHC.ETS.Combined.Controls.PIDWithEnable valHeaWatMinByp[nChiHea]( each k=0.01, each Ti=Ti, each final yMin=0, diff --git a/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterBypass.mo b/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterBypass.mo index 1afa798227f..5770bd9ac51 100644 --- a/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterBypass.mo +++ b/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterBypass.mo @@ -5,36 +5,44 @@ model ChilledWaterBypass parameter Integer numChi( min=1) "Number of chillers"; - parameter Modelica.Units.SI.MassFlowRate mMin_flow + parameter Real mMin_flow( + final quantity="MassFlowRate", + final unit="kg/s") "Minimum mass flow rate of single chiller"; - parameter Real k(min=0) = 0.06 "Gain of controller"; - parameter Modelica.Units.SI.Time Ti(min=Modelica.Constants.small) = 60 - "Time constant of Integrator block" annotation (Dialog(enable= - controllerType == Modelica.Blocks.Types.SimpleController.PI or - controllerType == Modelica.Blocks.Types.SimpleController.PID)); - parameter Modelica.Blocks.Types.SimpleController controllerType= - Modelica.Blocks.Types.SimpleController.PI + parameter Buildings.Controls.OBC.CDL.Types.SimpleController controllerType= + Buildings.Controls.OBC.CDL.Types.SimpleController.PI "Type of controller"; - Modelica.Blocks.Interfaces.BooleanInput chiOn[numChi] + parameter Real k(min=0) = 0.06 + "Gain of controller"; + parameter Real Ti( + final quantity="Time", + final unit="s", + final min=Modelica.Constants.small) = 60 + "Time constant of Integrator block" + annotation (Dialog(enable=controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PI or + controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PID)); + + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput chiOn[numChi] "On signals of the chillers" annotation (Placement(transformation(extent={{-140,30},{-100,70}}), iconTransformation(extent={{-140,30},{-100,70}}))); - Modelica.Blocks.Interfaces.RealInput mFloChi(final unit="kg/s") + Buildings.Controls.OBC.CDL.Interfaces.RealInput mFloChi( + final unit="kg/s") "Mass flow rate through the chillers" annotation (Placement(transformation(extent={{-140,-70},{-100,-30}}))); - Modelica.Blocks.Interfaces.RealOutput y + Buildings.Controls.OBC.CDL.Interfaces.RealOutput y "Bypass valve opening ratio" - annotation (Placement(transformation(extent={{100,-10},{120,10}}), - iconTransformation(extent={{100,-10},{120,10}}))); - Buildings.Controls.OBC.CDL.Reals.PIDWithReset - bypValCon( + annotation (Placement(transformation(extent={{100,-20},{140,20}}), + iconTransformation(extent={{100,-20},{140,20}}))); + + Buildings.Controls.OBC.CDL.Reals.PIDWithReset bypValCon( controllerType=controllerType, final k=k, final Ti=Ti, y_reset=0) "Chilled water bypass valve controller" annotation (Placement(transformation(extent={{60,-10},{80,10}}))); - Modelica.Blocks.Math.BooleanToInteger booToInt[numChi] + Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt[numChi] "Boolean signal to integer" annotation (Placement(transformation(extent={{-90,40},{-70,60}}))); Buildings.Controls.OBC.CDL.Integers.GreaterThreshold intGreThr @@ -46,34 +54,36 @@ model ChilledWaterBypass Buildings.Controls.OBC.CDL.Conversions.IntegerToReal intToRea "Integer to real" annotation (Placement(transformation(extent={{-20,40},{0,60}}))); - Modelica.Blocks.Math.Gain mFloSetSca(k=1/numChi) + Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mFloSetSca( + final k=1/numChi) "Normalize mass flowrate setpoint" annotation (Placement(transformation(extent={{20,40},{40,60}}))); - Modelica.Blocks.Math.Gain mFloBypSca(k=1/(numChi*mMin_flow)) + Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mFloBypSca( + final k=1/(numChi*mMin_flow)) "Normalize the measured mass flowrate" annotation (Placement(transformation(extent={{-60,-60},{-40,-40}}))); + equation connect(chiOn, booToInt.u) annotation (Line(points={{-120,50},{-92,50}}, color={255,0,255})); connect(booToInt.y, numChiOn.u) - annotation (Line(points={{-69,50},{-62,50}}, color={255,127,0})); + annotation (Line(points={{-68,50},{-62,50}}, color={255,127,0})); connect(numChiOn.y, intGreThr.u) - annotation (Line(points={{-38,50},{-30,50},{-30,-30},{-2,-30}}, - color={255,127,0})); + annotation (Line(points={{-38,50},{-30,50},{-30,-30},{-2,-30}}, color={255,127,0})); connect(intGreThr.y, bypValCon.trigger) annotation (Line(points={{22,-30},{64,-30},{64,-12}},color={255,0,255})); connect(numChiOn.y, intToRea.u) annotation (Line(points={{-38,50},{-22,50}}, color={255,127,0})); connect(bypValCon.y, y) - annotation (Line(points={{82,0},{110,0}}, color={0,0,127})); + annotation (Line(points={{82,0},{120,0}}, color={0,0,127})); connect(intToRea.y, mFloSetSca.u) annotation (Line(points={{2,50},{18,50}}, color={0,0,127})); connect(mFloSetSca.y, bypValCon.u_s) - annotation (Line(points={{41,50},{50,50},{50,0},{58,0}}, color={0,0,127})); + annotation (Line(points={{42,50},{50,50},{50,0},{58,0}}, color={0,0,127})); connect(mFloChi, mFloBypSca.u) annotation (Line(points={{-120,-50},{-62,-50}}, color={0,0,127})); connect(mFloBypSca.y, bypValCon.u_m) - annotation (Line(points={{-39,-50},{70,-50},{70,-12}}, color={0,0,127})); + annotation (Line(points={{-38,-50},{70,-50},{70,-12}}, color={0,0,127})); annotation ( defaultComponentName="chiBypCon", Icon( @@ -106,15 +116,23 @@ First implementation. ", - info=" -

This model implements the chilled water loop bypass valve control logic as -follows:

-

When the plant is on, the PID controller controls the valve opening ratio to -reach the scaled mass flow rate setpoint.

-

The setpoint is mMin_flow multiplied by the number of chillers +info=" +

+This model implements the chilled water loop bypass valve control logic as +follows: +

+

+When the plant is on, the PID controller controls the valve opening ratio to +reach the scaled mass flow rate setpoint. +

+

+The setpoint is mMin_flow multiplied by the number of chillers that are on. mMin_flow is the minimum mass flow rate required by -one chiller.

-

This control sequence assumes that all the chillers are identical and the -cooling load is evenly split between all of the chillers that are on.

+one chiller. +

+

+This control sequence assumes that all the chillers are identical and the +cooling load is evenly split between all of the chillers that are on. +

")); end ChilledWaterBypass; diff --git a/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterPumpSpeed.mo b/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterPumpSpeed.mo index 6a83280cfc6..c29ca9eff9a 100644 --- a/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterPumpSpeed.mo +++ b/Buildings/DHC/Plants/Cooling/Controls/ChilledWaterPumpSpeed.mo @@ -2,26 +2,38 @@ within Buildings.DHC.Plants.Cooling.Controls; model ChilledWaterPumpSpeed "Controller for two headered variable speed chilled water pumps" extends Modelica.Blocks.Icons.Block; - parameter Modelica.Units.SI.PressureDifference dpSetPoi(displayUnit="Pa") + parameter Real dpSetPoi( + final unit="Pa", + final quantity="PressureDifference", + displayUnit="Pa") "Pressure difference setpoint"; - parameter Modelica.Units.SI.Time tWai "Waiting time"; - parameter Modelica.Units.SI.MassFlowRate m_flow_nominal + parameter Real tWai( + final quantity="Time", + final unit="s") + "Waiting time"; + parameter Real m_flow_nominal( + final unit="kg/s", + final quantity="MassFlowRate") "Nominal mass flow rate of single chilled water pump"; parameter Real minSpe( final unit="1", final min=0, final max=1)=0.05 "Minimum speed ratio required by chilled water pumps"; - parameter Modelica.Units.SI.MassFlowRate criPoiFlo=0.7*m_flow_nominal + parameter Real criPoiFlo( + final unit="kg/s", + final quantity="MassFlowRate")=0.7*m_flow_nominal "Critcal point of flowrate for switching pump on or off"; - parameter Modelica.Units.SI.MassFlowRate deaBanFlo=0.1*m_flow_nominal + parameter Real deaBanFlo( + final unit="kg/s", + final quantity="MassFlowRate")=0.1*m_flow_nominal "Deadband for critical point of flowrate"; parameter Real criPoiSpe=0.5 "Critical point of speed signal for switching on or off"; parameter Real deaBanSpe=0.3 "Deadband for critical point of speed signal"; - parameter Modelica.Blocks.Types.SimpleController controllerType= - Modelica.Blocks.Types.SimpleController.PI + parameter Buildings.Controls.OBC.CDL.Types.SimpleController controllerType= + Buildings.Controls.OBC.CDL.Types.SimpleController.PI "Type of pump speed controller" annotation (Dialog(group="Speed Controller")); parameter Real k( @@ -29,32 +41,43 @@ model ChilledWaterPumpSpeed final min=0)=1 "Gain of controller" annotation (Dialog(group="Speed Controller")); - parameter Modelica.Units.SI.Time Ti(final min=Modelica.Constants.small) = 60 - "Time constant of Integrator block" annotation (Dialog(enable= - controllerType == Modelica.Blocks.Types.SimpleController.PI or - controllerType == Modelica.Blocks.Types.SimpleController.PID, group= - "Speed Controller")); - parameter Modelica.Units.SI.Time Td(final min=0) = 0.1 - "Time constant of Derivative block" annotation (Dialog(enable= - controllerType == Modelica.Blocks.Types.SimpleController.PD or - controllerType == Modelica.Blocks.Types.SimpleController.PID, group= - "Speed Controller")); - Modelica.Blocks.Interfaces.RealInput masFloPum( + parameter Real Ti( + final quantity="Time", + final unit="s", + final min=Modelica.Constants.small) = 60 + "Time constant of Integrator block" + annotation (Dialog(group= "Speed Controller", + enable=controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PI or + controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PID)); + parameter Real Td( + final quantity="Time", + final unit="s", + final min=0) = 0.1 + "Time constant of Derivative block" + annotation (Dialog(group= "Speed Controller", + enable=controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PD or + controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PID)); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput on + "On signal of the plant" + annotation (Placement(transformation(extent={{-140,60},{-100,100}}), + iconTransformation(extent={{-140,60},{-100,100}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput masFloPum( final unit="kg/s") "Total mass flowrate of chilled water pumps" annotation (Placement(transformation(extent={{-140,0},{-100,40}}), iconTransformation(extent={{-140,0},{-100,40}}))); - Modelica.Blocks.Interfaces.RealInput dpMea( + Buildings.Controls.OBC.CDL.Interfaces.RealInput dpMea( final unit="Pa") "Measured pressure difference" annotation (Placement(transformation(extent={{-140,-60},{-100,-20}}))); - Modelica.Blocks.Interfaces.RealOutput y[numPum]( + Buildings.Controls.OBC.CDL.Interfaces.RealOutput y[numPum]( each final unit="1", each final min=0, each final max=1) "Pump speed signal" annotation (Placement(transformation(extent={{100,-10},{120,10}}))); - Modelica.Blocks.Math.Product pumSpe[numPum] "Output pump speed" + Buildings.Controls.OBC.CDL.Reals.Multiply pumSpe[numPum] + "Output pump speed" annotation (Placement(transformation(extent={{60,-10},{80,10}}))); Buildings.Applications.BaseClasses.Controls.VariableSpeedPumpStage pumStaCon( final tWai=tWai, @@ -73,21 +96,24 @@ model ChilledWaterPumpSpeed final Td=Td) "PID controller of pump speed" annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); - Modelica.Blocks.Sources.Constant dpSetSca(final k=1) + Buildings.Controls.OBC.CDL.Reals.Sources.Constant dpSetSca(final k=1) "Scaled differential pressure setpoint" annotation (Placement(transformation(extent={{-80,-10},{-60,10}}))); - Modelica.Blocks.Math.Gain gai(k=1/dpSetPoi) "Gain for mesaured dp value" + Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai( + final k=1/dpSetPoi) + "Gain for mesaured dp value" annotation (Placement(transformation(extent={{-80,-50},{-60,-30}}))); - Modelica.Blocks.Math.RealToBoolean twoPum(threshold=1.5) "Two pumps are on" + Buildings.Controls.OBC.CDL.Reals.GreaterThreshold twoPum( + final t=1.5) + "Two pumps are on" annotation (Placement(transformation(extent={{10,-60},{-10,-40}}))); - Modelica.Blocks.Math.Sum totPum(final nin=numPum) "Total number of pumps on" - annotation (Placement(transformation(extent={{42,-60},{22,-40}}))); - Modelica.Blocks.Interfaces.BooleanInput on - "On signal of the plant" - annotation (Placement(transformation(extent={{-140,60},{-100,100}}), - iconTransformation(extent={{-140,60},{-100,100}}))); - Modelica.Blocks.Logical.Or orRes "Or block for controller reset" + Buildings.Controls.OBC.CDL.Reals.MultiSum totPum( + final nin=numPum) + "Total number of pumps on" + annotation (Placement(transformation(extent={{40,-60},{20,-40}}))); + Buildings.Controls.OBC.CDL.Logical.Or orRes "Or block for controller reset" annotation (Placement(transformation(extent={{-60,-80},{-40,-60}}))); + protected final parameter Integer numPum=2 "Number of chilled water pumps"; @@ -105,24 +131,24 @@ equation annotation (Line(points={{-18,0},{-10,0},{-10,-20},{48,-20},{48,-6},{58,-6}}, color={0,0,127})); connect(dpSetSca.y,conPID.u_s) - annotation (Line(points={{-59,0},{-42,0}},color={0,0,127})); + annotation (Line(points={{-58,0},{-42,0}},color={0,0,127})); connect(dpMea, gai.u) annotation (Line(points={{-120,-40},{-82,-40}}, color={0,0,127})); connect(gai.y, conPID.u_m) - annotation (Line(points={{-59,-40},{-30,-40},{-30,-12}}, color={0,0,127})); + annotation (Line(points={{-58,-40},{-30,-40},{-30,-12}}, color={0,0,127})); connect(pumStaCon.y, totPum.u) annotation (Line(points={{31,0},{50,0},{50,-50}, - {44,-50}}, color={0,0,127})); + {42,-50}}, color={0,0,127})); connect(totPum.y, twoPum.u) - annotation (Line(points={{21,-50},{12,-50}},color={0,0,127})); + annotation (Line(points={{18,-50},{12,-50}},color={0,0,127})); connect(pumSpe.y, y) - annotation (Line(points={{81,0},{110,0}}, color={0,0,127})); + annotation (Line(points={{82,0},{110,0}}, color={0,0,127})); connect(on, pumStaCon.on) annotation (Line(points={{-120,80},{4,80},{4,8},{8, 8}}, color={255,0,255})); - connect(twoPum.y, orRes.u2) annotation (Line(points={{-11,-50},{-20,-50},{-20, + connect(twoPum.y, orRes.u2) annotation (Line(points={{-12,-50},{-20,-50},{-20, -90},{-70,-90},{-70,-78},{-62,-78}}, color={255,0,255})); connect(on, orRes.u1) annotation (Line(points={{-120,80},{-90,80},{-90,-70},{ -62,-70}}, color={255,0,255})); - connect(orRes.y, conPID.trigger) annotation (Line(points={{-39,-70},{-36,-70}, + connect(orRes.y, conPID.trigger) annotation (Line(points={{-38,-70},{-36,-70}, {-36,-12}}, color={255,0,255})); annotation ( defaultComponentName="CHWPumCon", diff --git a/Buildings/DHC/Plants/Cooling/Controls/ChillerStage.mo b/Buildings/DHC/Plants/Cooling/Controls/ChillerStage.mo index a4f0f3b4a15..f5abcb23369 100644 --- a/Buildings/DHC/Plants/Cooling/Controls/ChillerStage.mo +++ b/Buildings/DHC/Plants/Cooling/Controls/ChillerStage.mo @@ -1,39 +1,55 @@ within Buildings.DHC.Plants.Cooling.Controls; model ChillerStage "Chiller staging controller for plants with two chillers of the same size" - replaceable package Medium=Buildings.Media.Water - constrainedby Modelica.Media.Interfaces.PartialMedium - "Service side medium"; - parameter Modelica.Units.SI.Time tWai "Waiting time"; - parameter Modelica.Units.SI.Power QChi_nominal(final max=0) + + parameter Real cp_default( + final quantity="SpecificHeatCapacity", + final unit="J/(kg.K)") + "Specific heat capacity of the fluid"; + parameter Real tWai( + final unit="s", + final quantity="Time") + "Waiting time"; + parameter Real QChi_nominal( + final max=0, + final quantity="Power", + final unit="W") "Nominal cooling capacity (negative)"; - parameter Modelica.Units.SI.Power staUpThr(final min=0) = -0.8*QChi_nominal + parameter Real staUpThr( + final min=0, + final quantity="Power", + final unit="W") = -0.8*QChi_nominal "Stage up load threshold(from one to two chillers)"; - parameter Modelica.Units.SI.Power staDowThr(final min=0) = -0.6*QChi_nominal + parameter Real staDowThr( + final min=0, + final quantity="Power", + final unit="W") = -0.6*QChi_nominal "Stage down load threshold(from two to one chiller)"; inner Modelica.StateGraph.StateGraphRoot stateGraphRoot "State graph root" annotation (Placement(transformation(extent={{120,60},{140,80}}))); - Modelica.Blocks.Interfaces.BooleanInput on + + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput on "Enabling signal of the plant. True: chiller should be enabled" annotation (Placement(transformation(extent={{-200,40},{-160,80}}), iconTransformation(extent={{-200,40},{-160,80}}))); - Modelica.Blocks.Interfaces.RealInput TChiWatRet + Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatRet "Chilled water return temperature" - annotation (Placement(transformation(extent={{-200,-24},{-160,16}}), + annotation (Placement(transformation(extent={{-200,-30},{-160,10}}), iconTransformation(extent={{-200,-24},{-160,16}}))); - Modelica.Blocks.Interfaces.RealInput TChiWatSup + Buildings.Controls.OBC.CDL.Interfaces.RealInput TChiWatSup "Chilled water supply temperature" annotation (Placement(transformation(extent={{-200,-60},{-160,-20}}), iconTransformation(extent={{-200,-60},{-160,-20}}))); - Modelica.Blocks.Interfaces.RealInput mFloChiWat + Buildings.Controls.OBC.CDL.Interfaces.RealInput mFloChiWat "Chilled water mass flow rate" annotation (Placement(transformation(extent={{-200,-96},{-160,-56}}), iconTransformation(extent={{-200,-96},{-160,-56}}))); - Modelica.Blocks.Interfaces.BooleanOutput y[2] + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y[2] "On/off signal for the chillers - false: off; true: on" - annotation (Placement(transformation(extent={{160,10},{180,-10}}), + annotation (Placement(transformation(extent={{160,-20},{200,20}}), iconTransformation(extent={{160,-10},{180,10}}))); + Modelica.StateGraph.InitialStep off(nIn=1, nOut=1) "No cooling is demanded" annotation (Placement(transformation(extent={{-10,10},{10,-10}}, @@ -71,40 +87,35 @@ model ChillerStage "Condition of transition from one chiller to off" annotation (Placement(transformation(extent={{-10,10},{10,-10}}, rotation=90,origin={40,60}))); - Buildings.Controls.OBC.CDL.Reals.Hysteresis thrOneToTwo(uLow=-staDowThr/ - QChi_nominal, uHigh=-staUpThr/QChi_nominal) - "Threshold of turning two chillers on" + Buildings.Controls.OBC.CDL.Reals.Hysteresis thrOneToTwo( + final uLow=-staDowThr/QChi_nominal, + final uHigh=-staUpThr/QChi_nominal) + "Threshold of turning two chillers on" annotation (Placement(transformation(extent={{-60,-80},{-40,-60}}))); - Modelica.Blocks.Logical.Not thrTwoToOne + Buildings.Controls.OBC.CDL.Logical.Not thrTwoToOne "Threshold of turning off the second chiller" annotation (Placement(transformation(extent={{-100,-18},{-80,2}}))); - Modelica.Blocks.Math.Add dT( + Buildings.Controls.OBC.CDL.Reals.Subtract dT( final k1=-1, final k2=+1) "Temperature difference" annotation (Placement(transformation(extent={{-140,-20},{-120,0}}))); - Modelica.Blocks.Math.Product pro + Buildings.Controls.OBC.CDL.Reals.Multiply pro "Product" annotation (Placement(transformation(extent={{-140,-80},{-120,-60}}))); - Modelica.Blocks.Math.Gain plr(final k=cp_default/QChi_nominal) + Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter plr( + final k=cp_default/QChi_nominal) "Specific heat multiplier to calculate heat flow rate" - annotation (Placement(transformation(extent={{-102,-80},{-82,-60}}))); - Buildings.Controls.OBC.CDL.Logical.Or Or "On signal for either chiller" + annotation (Placement(transformation(extent={{-100,-80},{-80,-60}}))); + Buildings.Controls.OBC.CDL.Logical.Or Or + "On signal for either chiller" annotation (Placement(transformation(extent={{120,20},{140,40}}))); - Modelica.Blocks.Logical.Not notOn "on switches to false" + Buildings.Controls.OBC.CDL.Logical.Not notOn "on switches to false" annotation (Placement(transformation(extent={{-100,20},{-80,40}}))); - Modelica.Blocks.Logical.Or TwoToOne + Buildings.Controls.OBC.CDL.Logical.Or TwoToOne "Conditions that turn off the second chiller" annotation (Placement(transformation(extent={{-40,-20},{-20,0}}))); -protected - final parameter Medium.ThermodynamicState sta_default=Medium.setState_pTX( - T=Medium.T_default, - p=Medium.p_default, - X=Medium.X_default) - "Medium state at default properties"; - final parameter Modelica.Units.SI.SpecificHeatCapacity cp_default= - Medium.specificHeatCapacityCp(sta_default) - "Specific heat capacity of the fluid"; + equation connect(off.outPort[1],offToOne.inPort) annotation (Line(points={{10,79.5},{10,64}},color={0,0,0})); @@ -123,19 +134,13 @@ equation annotation (Line(points={{-2,-40},{-20,-40},{-20,-70},{-38,-70}}, color={255,0,255})); connect(dT.y,pro.u1) - annotation (Line(points={{-119,-10},{-114,-10},{-114,-40},{-150,-40}, - {-150,-64},{-142,-64}},color={0,0,127})); + annotation (Line(points={{-118,-10},{-114,-10},{-114,-40},{-150,-40},{-150,-64}, + {-142,-64}}, color={0,0,127})); connect(plr.u, pro.y) - annotation (Line(points={{-104,-70},{-119,-70}}, + annotation (Line(points={{-102,-70},{-118,-70}}, color={0,0,127})); - connect(plr.y, thrOneToTwo.u) annotation (Line(points={{-81,-70},{-62,-70}}, + connect(plr.y, thrOneToTwo.u) annotation (Line(points={{-78,-70},{-62,-70}}, color={0,0,127})); - connect(dT.u1,TChiWatRet) - annotation (Line(points={{-142,-4},{-180,-4}}, - color={0,0,127})); - connect(TChiWatSup,dT.u2) - annotation (Line(points={{-180,-40},{-160,-40},{-160,-16},{-142,-16}}, - color={0,0,127})); connect(pro.u2,mFloChiWat) annotation (Line(points={{-142,-76},{-180,-76}},color={0,0,127})); connect(oneToTwo.condition, thrTwoToOne.u) @@ -148,10 +153,10 @@ equation annotation (Line(points={{21,-90},{100,-90},{100,22},{118,22}}, color={255,0,255})); connect(Or.y, y[1]) - annotation (Line(points={{142,30},{144,30},{144,-2.5},{170,-2.5}}, + annotation (Line(points={{142,30},{152,30},{152,-5},{180,-5}}, color={255,0,255})); connect(twoOn.active, y[2]) - annotation (Line(points={{21,-90},{120,-90},{120,2.5},{170,2.5}}, + annotation (Line(points={{21,-90},{100,-90},{100,5},{180,5}}, color={255,0,255})); connect(on, notOn.u) annotation (Line(points={{-180,60},{-120,60},{-120,30},{-102,30}}, @@ -167,14 +172,18 @@ equation color={0,0,0})); connect(on, offToOne.condition) annotation (Line(points={{-180,60},{-2,60}}, color={255,0,255})); - connect(thrTwoToOne.y, TwoToOne.u2) annotation (Line(points={{-79,-8},{-80,-8}, - {-80,-18},{-42,-18}}, color={255,0,255})); - connect(notOn.y, TwoToOne.u1) annotation (Line(points={{-79,30},{-60,30},{-60, + connect(thrTwoToOne.y, TwoToOne.u2) annotation (Line(points={{-78,-8},{-70,-8}, + {-70,-18},{-42,-18}}, color={255,0,255})); + connect(notOn.y, TwoToOne.u1) annotation (Line(points={{-78,30},{-60,30},{-60, -10},{-42,-10}}, color={255,0,255})); - connect(TwoToOne.y, twoToOne.condition) annotation (Line(points={{-19,-10},{-10, + connect(TwoToOne.y, twoToOne.condition) annotation (Line(points={{-18,-10},{-10, -10},{-10,-28},{40,-28},{40,-40},{48,-40}}, color={255,0,255})); connect(notOn.y, oneToOff.condition) - annotation (Line(points={{-79,30},{28,30},{28,60}}, color={255,0,255})); + annotation (Line(points={{-78,30},{28,30},{28,60}}, color={255,0,255})); + connect(TChiWatSup, dT.u1) annotation (Line(points={{-180,-40},{-154,-40},{-154, + -4},{-142,-4}}, color={0,0,127})); + connect(TChiWatRet, dT.u2) annotation (Line(points={{-180,-10},{-148,-10},{-148, + -16},{-142,-16}}, color={0,0,127})); annotation ( defaultComponentName="chiStaCon", Diagram( @@ -199,6 +208,12 @@ equation revisions="