From f8008473fe7261c97270da48355540d4d9b8d21d Mon Sep 17 00:00:00 2001 From: Michael Wetter Date: Fri, 3 Dec 2021 03:10:23 -0800 Subject: [PATCH] Maint 8.1.x issue2792 down port (#2794) * Copied files from master, 7255b26e396a2679420cdfd0fea4b0b5a21f5559 * Downported models from master. For #2792 * Removed Steam again from 8.1 as Examples are not backward compatible * Removed BuriedPipes again from 8.1 as changes are not backward compatible * Corrected revision notes --- .../GroundTemperature/BaseClasses/package.mo | 18 + .../BaseClasses/package.order | 1 + .../BaseClasses/surfaceTemperature.mo | 107 +++ .../GroundTemperature/ClimaticConstants.mo | 48 ++ .../Examples/CorrectedConvection.mo | 22 + .../Examples/CorrectedNFactors.mo | 30 + .../Examples/UndisturbedSoilTemperature.mo | 37 + .../GroundTemperature/Examples/package.mo | 19 + .../GroundTemperature/Examples/package.order | 3 + .../UndisturbedSoilTemperature.mo | 154 ++++ .../GroundTemperature/package.mo | 17 + .../GroundTemperature/package.order | 4 + Buildings/BoundaryConditions/package.order | 1 + .../Validation/ZoneStatusDuplicator.mo | 81 +++ .../SetPoints/Validation/package.order | 1 + .../Generic/SetPoints/ZoneStatusDuplicator.mo | 401 +++++++++++ .../G36_PR1/Generic/SetPoints/package.order | 1 + .../OBC/CDL/Routing/BooleanVectorFilter.mo | 69 ++ .../CDL/Routing/BooleanVectorReplicator.mo | 65 ++ .../OBC/CDL/Routing/IntegerVectorFilter.mo | 69 ++ .../CDL/Routing/IntegerVectorReplicator.mo | 62 ++ .../OBC/CDL/Routing/RealVectorFilter.mo | 70 ++ .../OBC/CDL/Routing/RealVectorReplicator.mo | 61 ++ .../Routing/Validation/BooleanVectorFilter.mo | 49 ++ .../Validation/BooleanVectorReplicator.mo | 49 ++ .../Routing/Validation/IntegerVectorFilter.mo | 49 ++ .../Validation/IntegerVectorReplicator.mo | 57 ++ .../Routing/Validation/RealVectorFilter.mo | 49 ++ .../Validation/RealVectorReplicator.mo | 52 ++ .../OBC/CDL/Routing/Validation/package.order | 6 + .../Controls/OBC/CDL/Routing/package.order | 6 + .../HighMassSupplyTemperature_TRoomRelHum.mo | 305 ++++++++ .../HighMassSupplyTemperature_TRoomRelHum.mo | 66 ++ .../Cooling/Validation/package.mo | 20 + .../Cooling/Validation/package.order | 1 + .../OBC/RadiantSystems/Cooling/package.mo | 32 + .../OBC/RadiantSystems/Cooling/package.order | 2 + .../HighMassSupplyTemperature_TRoom.mo | 269 +++++++ .../HighMassSupplyTemperature_TRoom.mo | 50 ++ .../Heating/Validation/package.mo | 20 + .../Heating/Validation/package.order | 1 + .../OBC/RadiantSystems/Heating/package.mo | 32 + .../OBC/RadiantSystems/Heating/package.order | 2 + .../Controls/OBC/RadiantSystems/package.mo | 11 + .../Controls/OBC/RadiantSystems/package.order | 2 + Buildings/Controls/OBC/package.order | 1 + .../Boilers/BaseClasses/PartialBoiler.mo | 154 ++++ .../Fluid/Boilers/BaseClasses/package.mo | 11 + .../Fluid/Boilers/BaseClasses/package.order | 1 + Buildings/Fluid/Boilers/BoilerTable.mo | 75 ++ Buildings/Fluid/Boilers/Data/Generic.mo | 57 ++ .../Data/Lochinvar/Crest/FBdash2501.mo | 23 + .../Data/Lochinvar/Crest/FBdash3001.mo | 17 + .../Data/Lochinvar/Crest/FBdash3501.mo | 17 + .../Data/Lochinvar/Crest/FBdash4001.mo | 18 + .../Data/Lochinvar/Crest/FBdash5001.mo | 17 + .../Data/Lochinvar/Crest/FBdash6001.mo | 17 + .../Boilers/Data/Lochinvar/Crest/package.mo | 15 + .../Data/Lochinvar/Crest/package.order | 6 + .../Boilers/Data/Lochinvar/FTXL/FTX400.mo | 23 + .../Boilers/Data/Lochinvar/FTXL/FTX500.mo | 17 + .../Boilers/Data/Lochinvar/FTXL/FTX600.mo | 17 + .../Boilers/Data/Lochinvar/FTXL/FTX725.mo | 17 + .../Boilers/Data/Lochinvar/FTXL/FTX850.mo | 17 + .../Boilers/Data/Lochinvar/FTXL/package.mo | 15 + .../Boilers/Data/Lochinvar/FTXL/package.order | 5 + .../Data/Lochinvar/KnightXL/KBXdash0400.mo | 22 + .../Data/Lochinvar/KnightXL/KBXdash0500.mo | 16 + .../Data/Lochinvar/KnightXL/KBXdash0650.mo | 16 + .../Data/Lochinvar/KnightXL/KBXdash0800.mo | 16 + .../Data/Lochinvar/KnightXL/KBXdash1000.mo | 16 + .../Data/Lochinvar/KnightXL/package.mo | 15 + .../Data/Lochinvar/KnightXL/package.order | 5 + .../Fluid/Boilers/Data/Lochinvar/package.mo | 164 +++++ .../Boilers/Data/Lochinvar/package.order | 3 + Buildings/Fluid/Boilers/Data/package.mo | 11 + Buildings/Fluid/Boilers/Data/package.order | 2 + .../Fluid/Boilers/Examples/BoilerTable.mo | 91 +++ Buildings/Fluid/Boilers/Examples/package.mo | 1 + .../Fluid/Boilers/Examples/package.order | 1 + Buildings/Fluid/Boilers/UsersGuide.mo | 109 +++ .../Validation/BoilerTableEfficiencyCurves.mo | 137 ++++ Buildings/Fluid/Boilers/Validation/package.mo | 12 + .../Fluid/Boilers/Validation/package.order | 1 + Buildings/Fluid/Boilers/package.order | 5 + .../UndisturbedSoilTemperature.png | Bin 0 -> 1997 bytes .../UndisturbedSoilTemperature.svg | 85 +++ .../HighMassSupplyTemperature_TRoomRelHum.png | Bin 0 -> 29648 bytes .../HighMassSupplyTemperature_TRoomRelHum.svg | 655 ++++++++++++++++++ .../HighMassSupplyTemperature_TRoom.png | Bin 0 -> 24175 bytes .../HighMassSupplyTemperature_TRoom.svg | 481 +++++++++++++ .../BoilerTableEfficiencyCurves.png | Bin 0 -> 26041 bytes ...mperature_Examples_CorrectedConvection.txt | 12 + ...Temperature_Examples_CorrectedNFactors.txt | 12 + ...re_Examples_UndisturbedSoilTemperature.txt | 12 + ...Points_Validation_ZoneStatusDuplicator.txt | 13 + ...Routing_Validation_BooleanVectorFilter.txt | 13 + ...ing_Validation_BooleanVectorReplicator.txt | 12 + ...Routing_Validation_IntegerVectorFilter.txt | 13 + ...ing_Validation_IntegerVectorReplicator.txt | 13 + ...DL_Routing_Validation_RealVectorFilter.txt | 13 + ...outing_Validation_RealVectorReplicator.txt | 12 + ..._HighMassSupplyTemperature_TRoomRelHum.txt | 15 + ...dation_HighMassSupplyTemperature_TRoom.txt | 14 + ...ngs_Fluid_Boilers_Examples_BoilerTable.txt | 15 + ...Validation_BoilerTableEfficiencyCurves.txt | 11 + .../Examples/CorrectedConvection.mos | 11 + .../Examples/CorrectedNFactors.mos | 11 + .../Examples/UndisturbedSoilTemperature.mos | 11 + .../Validation/ZoneStatusDuplicator.mos | 9 + .../Validation/BooleanVectorFilter.mos | 3 + .../Validation/BooleanVectorReplicator.mos | 5 + .../Validation/IntegerVectorFilter.mos | 3 + .../Validation/IntegerVectorReplicator.mos | 6 + .../Routing/Validation/RealVectorFilter.mos | 3 + .../Validation/RealVectorReplicator.mos | 5 + .../HighMassSupplyTemperature_TRoomRelHum.mos | 5 + .../HighMassSupplyTemperature_TRoom.mos | 5 + .../Fluid/Boilers/Examples/BoilerTable.mos | 40 ++ .../BoilerTableEfficiencyCurves.mos | 23 + ...mperature.Examples.CorrectedConvection.mos | 7 + ...Temperature.Examples.CorrectedNFactors.mos | 7 + ...re.Examples.UndisturbedSoilTemperature.mos | 7 + ...Points.Validation.ZoneStatusDuplicator.mos | 8 + ...Routing.Validation.BooleanVectorFilter.mos | 8 + ...ing.Validation.BooleanVectorReplicator.mos | 7 + ...Routing.Validation.IntegerVectorFilter.mos | 8 + ...ing.Validation.IntegerVectorReplicator.mos | 8 + ...DL.Routing.Validation.RealVectorFilter.mos | 8 + ...outing.Validation.RealVectorReplicator.mos | 7 + ....HighMassSupplyTemperature_TRoomRelHum.mos | 10 + ...dation.HighMassSupplyTemperature_TRoom.mos | 9 + ...ngs.Fluid.Boilers.Examples.BoilerTable.mos | 9 + ...Validation.BoilerTableEfficiencyCurves.mos | 6 + Buildings/package.mo | 88 ++- 135 files changed, 5367 insertions(+), 25 deletions(-) create mode 100644 Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.order create mode 100644 Buildings/BoundaryConditions/GroundTemperature/BaseClasses/surfaceTemperature.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/ClimaticConstants.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedConvection.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedNFactors.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/Examples/UndisturbedSoilTemperature.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/Examples/package.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/Examples/package.order create mode 100644 Buildings/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/package.mo create mode 100644 Buildings/BoundaryConditions/GroundTemperature/package.order create mode 100644 Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/ZoneStatusDuplicator.mo create mode 100644 Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/ZoneStatusDuplicator.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/BooleanVectorFilter.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/BooleanVectorReplicator.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/IntegerVectorFilter.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/IntegerVectorReplicator.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/RealVectorFilter.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/RealVectorReplicator.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorFilter.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorReplicator.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorFilter.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorReplicator.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorFilter.mo create mode 100644 Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorReplicator.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/HighMassSupplyTemperature_TRoomRelHum.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.order create mode 100644 Buildings/Controls/OBC/RadiantSystems/Cooling/package.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Cooling/package.order create mode 100644 Buildings/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Heating/Validation/HighMassSupplyTemperature_TRoom.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.order create mode 100644 Buildings/Controls/OBC/RadiantSystems/Heating/package.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/Heating/package.order create mode 100644 Buildings/Controls/OBC/RadiantSystems/package.mo create mode 100644 Buildings/Controls/OBC/RadiantSystems/package.order create mode 100644 Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo create mode 100644 Buildings/Fluid/Boilers/BaseClasses/package.mo create mode 100644 Buildings/Fluid/Boilers/BaseClasses/package.order create mode 100644 Buildings/Fluid/Boilers/BoilerTable.mo create mode 100644 Buildings/Fluid/Boilers/Data/Generic.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash2501.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3001.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3501.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash4001.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash5001.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash6001.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.order create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX400.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX500.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX600.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX725.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX850.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.order create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0400.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0500.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0650.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0800.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash1000.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.order create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/package.mo create mode 100644 Buildings/Fluid/Boilers/Data/Lochinvar/package.order create mode 100644 Buildings/Fluid/Boilers/Data/package.mo create mode 100644 Buildings/Fluid/Boilers/Data/package.order create mode 100644 Buildings/Fluid/Boilers/Examples/BoilerTable.mo create mode 100644 Buildings/Fluid/Boilers/UsersGuide.mo create mode 100644 Buildings/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.mo create mode 100644 Buildings/Fluid/Boilers/Validation/package.mo create mode 100644 Buildings/Fluid/Boilers/Validation/package.order create mode 100644 Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.png create mode 100644 Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.svg create mode 100644 Buildings/Resources/Images/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.png create mode 100644 Buildings/Resources/Images/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.svg create mode 100644 Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.png create mode 100644 Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.svg create mode 100644 Buildings/Resources/Images/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.png create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_BoundaryConditions_GroundTemperature_Examples_CorrectedConvection.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_BoundaryConditions_GroundTemperature_Examples_CorrectedNFactors.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_BoundaryConditions_GroundTemperature_Examples_UndisturbedSoilTemperature.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_ASHRAE_G36_PR1_Generic_SetPoints_Validation_ZoneStatusDuplicator.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_CDL_Routing_Validation_BooleanVectorFilter.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_CDL_Routing_Validation_BooleanVectorReplicator.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_CDL_Routing_Validation_IntegerVectorFilter.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_CDL_Routing_Validation_IntegerVectorReplicator.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_CDL_Routing_Validation_RealVectorFilter.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_CDL_Routing_Validation_RealVectorReplicator.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_RadiantSystems_Cooling_Validation_HighMassSupplyTemperature_TRoomRelHum.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Controls_OBC_RadiantSystems_Heating_Validation_HighMassSupplyTemperature_TRoom.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Fluid_Boilers_Examples_BoilerTable.txt create mode 100644 Buildings/Resources/ReferenceResults/Dymola/Buildings_Fluid_Boilers_Validation_BoilerTableEfficiencyCurves.txt create mode 100644 Buildings/Resources/Scripts/Dymola/BoundaryConditions/GroundTemperature/Examples/CorrectedConvection.mos create mode 100644 Buildings/Resources/Scripts/Dymola/BoundaryConditions/GroundTemperature/Examples/CorrectedNFactors.mos create mode 100644 Buildings/Resources/Scripts/Dymola/BoundaryConditions/GroundTemperature/Examples/UndisturbedSoilTemperature.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/ZoneStatusDuplicator.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/BooleanVectorFilter.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/BooleanVectorReplicator.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/IntegerVectorFilter.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/IntegerVectorReplicator.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/RealVectorFilter.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/RealVectorReplicator.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/RadiantSystems/Cooling/Validation/HighMassSupplyTemperature_TRoomRelHum.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Controls/OBC/RadiantSystems/Heating/Validation/HighMassSupplyTemperature_TRoom.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Fluid/Boilers/Examples/BoilerTable.mos create mode 100644 Buildings/Resources/Scripts/Dymola/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.BoundaryConditions.GroundTemperature.Examples.CorrectedConvection.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.BoundaryConditions.GroundTemperature.Examples.CorrectedNFactors.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.BoundaryConditions.GroundTemperature.Examples.UndisturbedSoilTemperature.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints.Validation.ZoneStatusDuplicator.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.CDL.Routing.Validation.BooleanVectorFilter.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.CDL.Routing.Validation.BooleanVectorReplicator.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.CDL.Routing.Validation.IntegerVectorFilter.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.CDL.Routing.Validation.IntegerVectorReplicator.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.CDL.Routing.Validation.RealVectorFilter.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.CDL.Routing.Validation.RealVectorReplicator.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.RadiantSystems.Cooling.Validation.HighMassSupplyTemperature_TRoomRelHum.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Controls.OBC.RadiantSystems.Heating.Validation.HighMassSupplyTemperature_TRoom.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Fluid.Boilers.Examples.BoilerTable.mos create mode 100644 Buildings/Resources/Scripts/OpenModelica/compareVars/Buildings.Fluid.Boilers.Validation.BoilerTableEfficiencyCurves.mos diff --git a/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.mo b/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.mo new file mode 100644 index 00000000000..17c961397e9 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.mo @@ -0,0 +1,18 @@ +within Buildings.BoundaryConditions.GroundTemperature; +package BaseClasses "Package with base classes for Buildings.BoundaryConditions.GroundTemperature" + extends Modelica.Icons.BasesPackage; + + annotation (Documentation(info=" +

+This package contains base classes that are used to construct the models in +Buildings.BoundaryConditions.GroundTemperature. +

+", revisions=" + +")); +end BaseClasses; diff --git a/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.order b/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.order new file mode 100644 index 00000000000..24bfde8718b --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/package.order @@ -0,0 +1 @@ +surfaceTemperature diff --git a/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/surfaceTemperature.mo b/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/surfaceTemperature.mo new file mode 100644 index 00000000000..2ae9fb4f6e8 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/BaseClasses/surfaceTemperature.mo @@ -0,0 +1,107 @@ +within Buildings.BoundaryConditions.GroundTemperature.BaseClasses; +function surfaceTemperature + "Function to correct the climatic constants using n-factors" + extends Modelica.Icons.Function; + + input ClimaticConstants.Generic cliCon + "Surface temperature climatic conditions"; + input Real nFacTha "Thawing n-factor (TAir > 0degC)"; + input Real nFacFre "Freezing n-factor (TAir <= 0degC)"; + output ClimaticConstants.Generic corCliCon + "Corrected surface temperature climatic conditions"; + +protected + constant Integer Year=365 "Year period in days"; + constant Integer secInDay = 24 * 60 * 60 "Seconds in a day"; + constant Modelica.SIunits.Angle pi = Modelica.Constants.pi; + constant Modelica.SIunits.Temperature TFre = 273.15 "Freezing temperature of water"; + constant Real freq = 2 * pi / Year "Year frequency in rad/days"; + parameter Modelica.SIunits.Temperature TAirDayMea[Year] = {cliCon.TSurMea + cliCon.TSurAmp / freq * ( + cos(freq * (cliCon.sinPha / secInDay - day)) - + cos(freq * (cliCon.sinPha / secInDay - (day + 1)))) + for day in 1:Year} "Daily mean air temperature (surface = 0 from uncorrected climatic constants)"; + parameter Modelica.SIunits.Temperature TSurDayMea[Year] = { + if TAirDayMea[day] > TFre + then (TFre + (TAirDayMea[day] - TFre) * nFacTha) + else (TFre + (TAirDayMea[day] - TFre) * nFacFre) + for day in 1:Year} "Daily mean corrected surface temperature"; + parameter Real C1 = sum({TSurDayMea[day] * cos(freq * day) for day in 1:Year}); + parameter Real C2 = sum({TSurDayMea[day] * sin(freq * day) for day in 1:Year}); + + parameter Modelica.SIunits.Temperature corTSurMea = sum(TSurDayMea)/Year + "Mean annual surface temperature"; + parameter Modelica.SIunits.TemperatureDifference corTSurAmp = 2/Year .* (C1^2 + C2^2)^0.5 + "Surface temperature amplitude"; + parameter Modelica.SIunits.Duration corSinPha(displayUnit="d") = (Modelica.Math.atan(C2/C1) + pi/2)*secInDay/freq + "Phase lag of soil surface temperature"; + +algorithm + // Analytical mean by integrating undisturbed soil temperature formula + corCliCon := ClimaticConstants.Generic( + TSurMea = corTSurMea, + TSurAmp = corTSurAmp, + sinPha = corSinPha); + + annotation (Documentation(revisions=" + +", info=" +

+This function corrects the surface temperature climatic constants +by applying n-factors with the methodology prescribed in the +District Cooling Guide (ASHRAE, 2013). +

+

+n-factors corresponds to the ratio of freezing (/thawing) degree +days or index between the air and the ground surface and can +be used to couple the air and ground surface temperatures.
+For example, a freezing n-factor of 1.35 means that during the +freezing season, the daily average ground surface temperature is +on average 1.35 times colder than the air (using the freezing +temperature of water as a reference).
+In its guide, ASHRAE suggests to first apply the n-factors to the +uncorrected ground temperature at zero burial depth, and to fit a +new sinusoidal curve to the result. +
+In this function, the freezing n-factor is applied to days where +the daily mean air temperature is below the freezing temperature (0degC), +whereas the thawing n-factor is applied to the remaining days. +

+

+ Tground - Tfreezing = ηfreezing * (Tair - Tfreezing)   if Tair <= Tfreezing
+ Tground - Tfreezing = ηthawing * (Tair - Tfreezing)   if Tair > Tfreezing +

+

+The sinusoidal curve is then fitted using the analytical solution +proposed in Appendix B of the District Heating Guide. +

+

+n-factors are specific to a climate and surface cover, and should be +extrapolated from other sites with caution. As a first approximation, +tabulated values of n-factors are available in Lunardini (1981) and +Freitag and McFadden (1997). +

+ + +

References

+

+ASHRAE (2013). District Cooling Guide. ASHRAE, Atlanta, GA.
+ASHRAE (2013). District Heating Guide. ASHRAE, Atlanta, GA.
+D.W. Riseborough (2003). Thawing and freezing indices in the active layer. Proceedings of the 8th International Conference on Permafrost, Swets & Zeitlinger.
+V.J. Lunardini (1981). Heat Transfer in Cold Climates. Van Nostrand Reinhold Company.
+D.R. Freitag and T. McFadden (1997). Introduction to Cold Regions Engineering. American Society of Civil Engineers. + +

+ +")); +end surfaceTemperature; diff --git a/Buildings/BoundaryConditions/GroundTemperature/ClimaticConstants.mo b/Buildings/BoundaryConditions/GroundTemperature/ClimaticConstants.mo new file mode 100644 index 00000000000..9a228053a29 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/ClimaticConstants.mo @@ -0,0 +1,48 @@ +within Buildings.BoundaryConditions.GroundTemperature; +package ClimaticConstants "Surface temperature climatic constants" + extends Modelica.Icons.MaterialPropertiesPackage; + + record Generic "Generic climatic constants" + extends Modelica.Icons.Record; + parameter Modelica.SIunits.Temperature TSurMea + "Mean annual surface temperature"; + parameter Modelica.SIunits.TemperatureDifference TSurAmp + "Surface temperature amplitude"; + parameter Modelica.SIunits.Duration sinPha(displayUnit="d") + "Phase lag of soil surface temperature"; + end Generic; + + record Boston = + Buildings.BoundaryConditions.GroundTemperature.ClimaticConstants.Generic( + TSurMea=284.23, + TSurAmp=11.57, + sinPha=9944640) "Boston"; + + record NewYork = + Buildings.BoundaryConditions.GroundTemperature.ClimaticConstants.Generic( + TSurMea=286.03, + TSurAmp=11.45, + sinPha=9728640) "New York"; + + record SanFrancisco = + Buildings.BoundaryConditions.GroundTemperature.ClimaticConstants.Generic( + TSurMea=287.64, + TSurAmp=3.35, + sinPha=10419840) "San Francisco"; + + annotation (Documentation(info=" +

+Surface temperature data that is used in the calculation of undisturbed soil temperature. +See +Climatic Constants for Calculating Subsurface Soil Temperatures for +more information and a table of values. +

+", revisions=" + +")); +end ClimaticConstants; diff --git a/Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedConvection.mo b/Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedConvection.mo new file mode 100644 index 00000000000..669adb97337 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedConvection.mo @@ -0,0 +1,22 @@ +within Buildings.BoundaryConditions.GroundTemperature.Examples; +model CorrectedConvection + "Example model for undisturbed soil temperature with surface convection correction" + extends UndisturbedSoilTemperature(TSoi(each useCon=true, each hSur=5)); + annotation (Documentation(revisions=" + +", info=" +

+This example model showcases the use of the convection coefficient +correction, which allows to specify the heat transfer rate between +the air and the surface temperature. +

+"), +experiment(StopTime=31536000, Tolerance=1e-6), +__Dymola_Commands(file="modelica://Buildings/Resources/Scripts/Dymola/BoundaryConditions/GroundTemperature/Examples/CorrectedConvection.mos" + "Simulate and plot")); +end CorrectedConvection; diff --git a/Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedNFactors.mo b/Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedNFactors.mo new file mode 100644 index 00000000000..d7373c55550 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/Examples/CorrectedNFactors.mo @@ -0,0 +1,30 @@ +within Buildings.BoundaryConditions.GroundTemperature.Examples; +model CorrectedNFactors + "Example model for undisturbed soil temperature with n-factors correction" + extends UndisturbedSoilTemperature( + TSoi(each useNFac=true, each nFacTha=1.7, each nFacFre=0.66)); + annotation (Documentation(revisions=" + +", info=" +

+This example model showcases the use of n-factors, which are used +to correct the surface temperature given the ratio of freezing/thawing +degree days (FDD/TDD) between the air and the ground. +

+ +

References

+

+The values used in this example are equivalent to the use-case +presented in the \"Heat Transfer at Ground Surface\" section of the +District Cooling Guide (ASHRAE, 2013). +

+"), +experiment(StopTime=31536000, Tolerance=1e-6), +__Dymola_Commands(file="modelica://Buildings/Resources/Scripts/Dymola/BoundaryConditions/GroundTemperature/Examples/CorrectedNFactors.mos" + "Simulate and plot")); +end CorrectedNFactors; diff --git a/Buildings/BoundaryConditions/GroundTemperature/Examples/UndisturbedSoilTemperature.mo b/Buildings/BoundaryConditions/GroundTemperature/Examples/UndisturbedSoilTemperature.mo new file mode 100644 index 00000000000..f25de2f5af9 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/Examples/UndisturbedSoilTemperature.mo @@ -0,0 +1,37 @@ +within Buildings.BoundaryConditions.GroundTemperature.Examples; +model UndisturbedSoilTemperature "Example model for undisturbed soil temperature" + extends Modelica.Icons.Example; + + parameter Integer nSoi = 4 "Number of probed depths"; + parameter Modelica.SIunits.Length dep[nSoi] = {0,2,5,9} "Probed depths"; + + Buildings.BoundaryConditions.GroundTemperature.UndisturbedSoilTemperature + TSoi[nSoi](dep=dep, each cliCon=cliCon, each soiDat=soiDat) + "Undisturbed soil temperatures" + annotation (Placement(transformation(extent={{-20,-20},{20,20}}))); + +protected + replaceable parameter ClimaticConstants.Boston cliCon + "Surface temperature climatic conditions"; + replaceable parameter Buildings.HeatTransfer.Data.Soil.Generic soiDat( + k=1.58,c=1150,d=1600) "Soil thermal properties"; + annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram( + coordinateSystem(preserveAspectRatio=false)), + experiment(StopTime=31536000, Tolerance=1e-6), + Documentation(info=" +

+This example model illustrates how the undisturbed soil temperature model +decreases seasonal temperature oscillations and increases delay as depth is +increasing. +

+", revisions=" + +"), + __Dymola_Commands(file="modelica://Buildings/Resources/Scripts/Dymola/BoundaryConditions/GroundTemperature/Examples/UndisturbedSoilTemperature.mos" + "Simulate and plot")); +end UndisturbedSoilTemperature; diff --git a/Buildings/BoundaryConditions/GroundTemperature/Examples/package.mo b/Buildings/BoundaryConditions/GroundTemperature/Examples/package.mo new file mode 100644 index 00000000000..aeb31ebea6b --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/Examples/package.mo @@ -0,0 +1,19 @@ +within Buildings.BoundaryConditions.GroundTemperature; +package Examples "Collection of models that illustrate model use and test models" + extends Modelica.Icons.ExamplesPackage; + + annotation (Documentation(info=" +

+This package contains examples for the use of models that can be found in + +Buildings.BoundaryConditions.GroundTemperature. +

+", revisions=" + +")); +end Examples; diff --git a/Buildings/BoundaryConditions/GroundTemperature/Examples/package.order b/Buildings/BoundaryConditions/GroundTemperature/Examples/package.order new file mode 100644 index 00000000000..db3436c84b4 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/Examples/package.order @@ -0,0 +1,3 @@ +CorrectedConvection +CorrectedNFactors +UndisturbedSoilTemperature diff --git a/Buildings/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.mo b/Buildings/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.mo new file mode 100644 index 00000000000..f2d2152ee69 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.mo @@ -0,0 +1,154 @@ +within Buildings.BoundaryConditions.GroundTemperature; +model UndisturbedSoilTemperature "Undisturbed soil temperature" + parameter Modelica.SIunits.Length dep "Depth"; + + parameter Boolean useNFac = false + "= true, use n-factors to correct climatic constants"; + parameter Real nFacTha = 1 "Thawing n-factor (TAir > 0degC)" + annotation(Dialog(enable=useNFac)); + parameter Real nFacFre = 1 "Freezing n-factor (TAir <= 0degC)" + annotation(Dialog(enable=useNFac)); + + parameter Boolean useCon = false + "= true, includes convection between air and surface coupling"; + parameter Real hSur(unit="W/(m2.K)", min=0) = 25 + "Surface convective heat transfer coefficient" + annotation(Dialog(enable=useCon)); + + replaceable parameter Buildings.HeatTransfer.Data.Soil.Generic + soiDat "Soil thermal properties"; + replaceable parameter ClimaticConstants.Generic + cliCon "Surface temperature climatic conditions"; + + Modelica.SIunits.Temperature T + "Undisturbed soil temperature at depth dep"; + +protected + constant Modelica.SIunits.Angle pi = Modelica.Constants.pi; + constant Modelica.SIunits.Duration Year = 365.2422*24*60*60 + "Annual period length"; + + parameter Modelica.SIunits.Length corDep = if useCon + then dep + soiDat.k / hSur + else dep + "Convection-corrected depth"; + parameter ClimaticConstants.Generic corCliCon= if useNFac + then BaseClasses.surfaceTemperature(cliCon=cliCon, nFacTha=nFacTha, nFacFre=nFacFre) + else cliCon + "n-factor corrected climatic constants"; + + parameter Modelica.SIunits.ThermalDiffusivity + soiDif = soiDat.k / soiDat.c / soiDat.d "Soil diffusivity"; + parameter Modelica.SIunits.Duration + timLag = corCliCon.sinPha + "Start time of surface temperature sinusoid"; + parameter Real pha = - corDep * (pi/soiDif/Year)^0.5 + "Phase angle of ground temperature sinusoid"; + +initial equation + assert(not (useCon and useNFac), + "N-Factors and surface convection corrections + would typically not be used simultaneously", + level = AssertionLevel.warning); + +equation + T = corCliCon.TSurMea + corCliCon.TSurAmp * exp(pha) * + sin(2*pi*(time-timLag)/Year + pha); + annotation (Placement(transformation(extent={{-6,-104},{6,-92}}), + iconTransformation(extent={{-6,-104},{6,-92}})), + Icon(coordinateSystem(preserveAspectRatio=false), graphics={ + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Rectangle( + extent={{-100,20},{100,-100}}, + lineColor={0,0,0}, + fillColor={211,168,137}, + fillPattern=FillPattern.Backward), + Rectangle( + extent={{-100,20},{100,26}}, + lineColor={0,0,0}, + fillColor={0,255,128}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-100,26},{100,100}}, + lineColor={0,0,0}, + fillColor={85,170,255}, + fillPattern=FillPattern.Solid), + Line( + points={{0,38},{0,-60}}, + color={191,0,0}, + thickness=1), + Polygon( + points={{16,-60},{-16,-60},{0,-92},{16,-60}}, + lineColor={191,0,0}, + fillColor={191,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-38,-38},{-100,-100}}, + textColor={0,0,0}, + textString="K")}), Diagram( + coordinateSystem(preserveAspectRatio=false)), + Documentation(info=" +

+This model provides a prescribed temperature boundary condition for buried objects, +where the temperature is computed per the ASCE (1996) equation: +

+

+\"image\" +

+

+where:
+Ts,z = ground temperature at depth z,
+τ = annual period length (constant 365.25 days),
+α = soil thermal diffusivity (assumed constant throughout the year),
+t = time,
+Tms = mean annual surface temperature,
+As = temperature amplitude throughout the year (max - min),
+tlag = phase lag of the surface temperature sinusoid +

+ +

Corrections

+ +

+Without correction, this model assumes that the surface temperature (depth = 0) is +equal to the air temperature, which is acceptable for most design calculations.
+For more accurate calculation, this model provides methods to compensate for +the convective thermal resistance and the impact of surface cover. +

+

+The convective thermal resistance can be modeled as a virtual equivalent soil layer +by setting the flag useCon to true and specifying the +heat transfer coefficient hSur.
+This correction would result in a larger delay and dampening of the +resulting sinusoid. +

+

+The impact of surface cover on soil temperature can be modeled using +n-factors by setting the flag useNFac to true and +specifying the thawing and freezing n-factors at the surface.
+ +More information about n-factors correction can be found in the documentation +for +Buildings.BoundaryConditions.GroundTemperature.BaseClasses.surfaceTemperature. +

+

+Since n-factors incorporate the effect of surface convection, +both corrections would typically not be applied simultaneously.
+

+ +

References

+

+ASCE (1996). Cold Regions Utilities Monograph. D.W. Smith, Technical Editor. +

+ +", revisions=" + +")); +end UndisturbedSoilTemperature; diff --git a/Buildings/BoundaryConditions/GroundTemperature/package.mo b/Buildings/BoundaryConditions/GroundTemperature/package.mo new file mode 100644 index 00000000000..003ee9a9581 --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/package.mo @@ -0,0 +1,17 @@ +within Buildings.BoundaryConditions; +package GroundTemperature "Package with models to compute ground temperature" + extends Modelica.Icons.VariantsPackage; + + annotation (Documentation(info=" +

+This package contains models to compute the ground temperature. +

+", revisions=" + +")); +end GroundTemperature; diff --git a/Buildings/BoundaryConditions/GroundTemperature/package.order b/Buildings/BoundaryConditions/GroundTemperature/package.order new file mode 100644 index 00000000000..bb516d8747e --- /dev/null +++ b/Buildings/BoundaryConditions/GroundTemperature/package.order @@ -0,0 +1,4 @@ +ClimaticConstants +UndisturbedSoilTemperature +Examples +BaseClasses diff --git a/Buildings/BoundaryConditions/package.order b/Buildings/BoundaryConditions/package.order index 1f2453d93b9..43d148f1d4b 100644 --- a/Buildings/BoundaryConditions/package.order +++ b/Buildings/BoundaryConditions/package.order @@ -1,4 +1,5 @@ UsersGuide +GroundTemperature SkyTemperature SolarGeometry SolarIrradiation diff --git a/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/ZoneStatusDuplicator.mo b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/ZoneStatusDuplicator.mo new file mode 100644 index 00000000000..9296dba9777 --- /dev/null +++ b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/ZoneStatusDuplicator.mo @@ -0,0 +1,81 @@ +within Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints.Validation; +model ZoneStatusDuplicator + "Validate block for duplicating zone status" + + Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints.ZoneStatusDuplicator zonStaDup( + final nZon=5, + final nGro=2) + "Zone status duplicator" + annotation (Placement(transformation(extent={{0,-40},{20,40}}))); + Buildings.Controls.OBC.CDL.Continuous.Sources.Constant reaInp[6,5]( + final k=fill({1,2,3,4,5}, 6)) + "Real inputs" + annotation (Placement(transformation(extent={{-100,20},{-80,40}}))); + Buildings.Controls.OBC.CDL.Logical.Sources.Constant booInp[9,5]( + final k=fill({true,true,false,true,false},9)) + "Boolean inputs" + annotation (Placement(transformation(extent={{-100,-40},{-80,-20}}))); + +equation + connect(reaInp[1, :].y, zonStaDup.tNexOcc) + annotation (Line(points={{-78,30},{-5,30}}, color={0,0,127})); + connect(reaInp[2, :].y, zonStaDup.uCooTim) annotation (Line(points={{-78,30},{ + -60,30},{-60,22},{-5,22}}, color={0,0,127})); + connect(reaInp[3, :].y, zonStaDup.uWarTim) annotation (Line(points={{-78,30},{ + -60,30},{-60,18},{-5,18}}, color={0,0,127})); + connect(reaInp[4, :].y, zonStaDup.THeaSetOff) annotation (Line(points={{-78,30}, + {-60,30},{-60,-6},{-5,-6}}, color={0,0,127})); + connect(reaInp[5, :].y, zonStaDup.TCooSetOff) annotation (Line(points={{-78,30}, + {-60,30},{-60,-22},{-5,-22}}, color={0,0,127})); + connect(reaInp[6, :].y, zonStaDup.TZon) annotation (Line(points={{-78,30},{-60, + 30},{-60,-34},{-5,-34}}, color={0,0,127})); + connect(booInp[1, :].y, zonStaDup.zonOcc) annotation (Line(points={{-78,-30},{ + -40,-30},{-40,38},{-5,38}}, color={255,0,255})); + connect(booInp[2, :].y, zonStaDup.uOcc) annotation (Line(points={{-78,-30},{-40, + -30},{-40,34},{-5,34}}, color={255,0,255})); + connect(booInp[3, :].y, zonStaDup.uOccHeaHig) annotation (Line(points={{-78,-30}, + {-40,-30},{-40,10},{-5,10}}, color={255,0,255})); + connect(booInp[4, :].y, zonStaDup.uHigOccCoo) annotation (Line(points={{-78,-30}, + {-40,-30},{-40,6},{-5,6}}, color={255,0,255})); + connect(booInp[5, :].y, zonStaDup.uUnoHeaHig) annotation (Line(points={{-78,-30}, + {-40,-30},{-40,-2},{-5,-2}}, color={255,0,255})); + connect(booInp[6, :].y, zonStaDup.uEndSetBac) annotation (Line(points={{-78,-30}, + {-40,-30},{-40,-10},{-5,-10}}, color={255,0,255})); + connect(booInp[7, :].y, zonStaDup.uHigUnoCoo) annotation (Line(points={{-78,-30}, + {-40,-30},{-40,-18},{-5,-18}}, color={255,0,255})); + connect(booInp[8, :].y, zonStaDup.uEndSetUp) annotation (Line(points={{-78,-30}, + {-40,-30},{-40,-26},{-5,-26}}, color={255,0,255})); + connect(booInp[9, :].y, zonStaDup.uWin) annotation (Line(points={{-78,-30},{-40, + -30},{-40,-38},{-5,-38}}, color={255,0,255})); + +annotation ( + experiment(StopTime=1, Tolerance=1e-6), + __Dymola_Commands(file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/ZoneStatusDuplicator.mos" + "Simulate and plot"), + Documentation(info=" +

+This example validates + +Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints.ZoneStatusDuplicator +for duplicating zone status. +

+", revisions=" + +"), + Icon(coordinateSystem(extent={{-100,-100},{100,100}}), + graphics={ + Ellipse(lineColor = {75,138,73}, + fillColor={255,255,255}, + fillPattern = FillPattern.Solid, + extent = {{-100,-100},{100,100}}), + Polygon(lineColor = {0,0,255}, + fillColor = {75,138,73}, + pattern = LinePattern.None, + fillPattern = FillPattern.Solid, + points = {{-36,60},{64,0},{-36,-60},{-36,60}})})); +end ZoneStatusDuplicator; diff --git a/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/package.order b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/package.order index d1f99568247..b7fba780f7d 100644 --- a/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/package.order +++ b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/Validation/package.order @@ -2,3 +2,4 @@ GroupStatus OperationMode TrimAndRespond ZoneStatus +ZoneStatusDuplicator diff --git a/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/ZoneStatusDuplicator.mo b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/ZoneStatusDuplicator.mo new file mode 100644 index 00000000000..0b4ad7c88bc --- /dev/null +++ b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/ZoneStatusDuplicator.mo @@ -0,0 +1,401 @@ +within Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints; +block ZoneStatusDuplicator "Duplicate zone status output" + + parameter Integer nZon(final min=1)=1 "Number of zones in input"; + parameter Integer nGro(final min=1)=1 "Number of groups in output"; + + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput zonOcc[nZon] + "True when the zone is set to be occupied due to the override" + annotation (Placement(transformation(extent={{-80,60},{-40,100}}), + iconTransformation(extent={{-80,190},{-40,230}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uOcc[nZon] + "True when the zone is occupied according to the occupancy schedule" + annotation (Placement(transformation(extent={{-80,20},{-40,60}}), + iconTransformation(extent={{-80,170},{-40,210}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput tNexOcc[nZon]( + final unit=fill("s", nZon), + final quantity=fill("Time", nZon)) + "Time to next occupied period" + annotation (Placement(transformation(extent={{-80,-20},{-40,20}}), + iconTransformation(extent={{-80,150},{-40,190}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput uCooTim[nZon]( + final unit=fill("s", nZon), + final quantity=fill("Time", nZon)) + "Cool down time" + annotation (Placement(transformation(extent={{-80,-60},{-40,-20}}), + iconTransformation(extent={{-80,110},{-40,150}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput uWarTim[nZon]( + final unit=fill("s", nZon), + final quantity=fill("Time", nZon)) + "Warm-up time" + annotation (Placement(transformation(extent={{-80,-100},{-40,-60}}), + iconTransformation(extent={{-80,90},{-40,130}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uOccHeaHig[nZon] + "True when the zone temperature is lower than the occupied heating setpoint" + annotation (Placement(transformation(extent={{-80,-140},{-40,-100}}), + iconTransformation(extent={{-80,50},{-40,90}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uHigOccCoo[nZon] + "True when the zone temperature is higher than the occupied cooling setpoint" + annotation (Placement(transformation(extent={{-80,-180},{-40,-140}}), + iconTransformation(extent={{-80,30},{-40,70}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uUnoHeaHig[nZon] + "True when the zone temperature is lower than the unoccupied heating setpoint" + annotation (Placement(transformation(extent={{-80,-220},{-40,-180}}), + iconTransformation(extent={{-80,-10},{-40,30}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaSetOff[nZon]( + final unit=fill("K", nZon), + displayUnit=fill("degC", nZon), + final quantity=fill("ThermodynamicTemperature", nZon)) + "Zone unoccupied heating setpoint" + annotation (Placement(transformation(extent={{-80,-260},{-40,-220}}), + iconTransformation(extent={{-80,-30},{-40,10}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uEndSetBac[nZon] + "True when the zone could end the setback mode" + annotation (Placement(transformation(extent={{-80,-300},{-40,-260}}), + iconTransformation(extent={{-80,-50},{-40,-10}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uHigUnoCoo[nZon] + "True when the zone temperature is higher than its unoccupied cooling setpoint" + annotation (Placement(transformation(extent={{-80,-330},{-40,-290}}), + iconTransformation(extent={{-80,-90},{-40,-50}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput TCooSetOff[nZon]( + final unit=fill("K", nZon), + displayUnit=fill("degC", nZon), + final quantity=fill("ThermodynamicTemperature", nZon)) + "Zone unoccupied cooling setpoint" + annotation (Placement(transformation(extent={{-80,-390},{-40,-350}}), + iconTransformation(extent={{-80,-110},{-40,-70}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uEndSetUp[nZon] + "True when the zone could end the setup mode" + annotation (Placement(transformation(extent={{-80,-420},{-40,-380}}), + iconTransformation(extent={{-80,-130},{-40,-90}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealInput TZon[nZon]( + final unit=fill("K", nZon), + displayUnit=fill("degC", nZon), + final quantity=fill("ThermodynamicTemperature", nZon)) "Zone temperature" + annotation (Placement(transformation(extent={{-80,-460},{-40,-420}}), + iconTransformation(extent={{-80,-170},{-40,-130}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uWin[nZon] + "True when the window is open, false when the window is close or the zone does not have window status sensor" + annotation (Placement(transformation(extent={{-80,-540},{-40,-500}}), + iconTransformation(extent={{-80,-190},{-40,-150}}))); + + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yzonOcc[nGro, nZon] + "True when the zone is set to be occupied due to the override" + annotation (Placement(transformation(extent={{40,60},{80,100}}), + iconTransformation(extent={{40,190},{80,230}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yOcc[nGro,nZon] + "True when the zone is occupied according to the occupancy schedule" + annotation (Placement(transformation(extent={{40,20},{80,60}}), + iconTransformation(extent={{40,170},{80,210}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput ytNexOcc[nGro, nZon]( + final unit=fill("s", nGro, nZon), + final quantity=fill("Time", nGro, nZon)) "Time to next occupied period" + annotation (Placement(transformation(extent={{40,-20},{80,20}}), + iconTransformation(extent={{40,150},{80,190}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yCooTim[nGro,nZon]( + final unit=fill("s", nGro, nZon), + final quantity=fill("Time", nGro, nZon)) "Cool down time" + annotation (Placement(transformation(extent={{40,-60},{80,-20}}), + iconTransformation(extent={{40,110},{80,150}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yWarTim[nGro,nZon]( + final unit=fill("s", nGro, nZon), + final quantity=fill("Time", nGro, nZon)) "Warm-up time" + annotation (Placement(transformation(extent={{40,-100},{80,-60}}), + iconTransformation(extent={{40,90},{80,130}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yOccHeaHig[nGro,nZon] + "True when the zone temperature is lower than the occupied heating setpoint" + annotation (Placement(transformation(extent={{40,-140},{80,-100}}), + iconTransformation(extent={{40,50},{80,90}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yHigOccCoo[nGro,nZon] + "True when the zone temperature is higher than the occupied cooling setpoint" + annotation (Placement(transformation(extent={{40,-180},{80,-140}}), + iconTransformation(extent={{40,30},{80,70}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yUnoHeaHig[nGro,nZon] + "True when the zone temperature is lower than the unoccupied heating setpoint" + annotation (Placement(transformation(extent={{40,-220},{80,-180}}), + iconTransformation(extent={{40,-10},{80,30}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yTHeaSetOff[nGro, nZon]( + final unit=fill("K", nGro, nZon), + displayUnit=fill("degC", nGro, nZon), + final quantity=fill("ThermodynamicTemperature", nGro, nZon)) + "Zone unoccupied heating setpoint" + annotation (Placement(transformation(extent={{40,-260},{80,-220}}), + iconTransformation(extent={{40,-30},{80,10}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yEndSetBac[nGro,nZon] + "True when the zone could end the setback mode" + annotation (Placement(transformation(extent={{40,-300},{80,-260}}), + iconTransformation(extent={{40,-50},{80,-10}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yHigUnoCoo[nGro,nZon] + "True when the zone temperature is higher than its unoccupied cooling setpoint" + annotation (Placement(transformation(extent={{40,-330},{80,-290}}), + iconTransformation(extent={{40,-90},{80,-50}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yTCooSetOff[nGro, nZon]( + final unit=fill("K", nGro, nZon), + displayUnit=fill("degC", nGro, nZon), + final quantity=fill("ThermodynamicTemperature", nGro, nZon)) + "Zone unoccupied cooling setpoint" + annotation (Placement(transformation(extent={{40,-390},{80,-350}}), + iconTransformation(extent={{40,-110},{80,-70}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yEndSetUp[nGro,nZon] + "True when the zone could end the setup mode" + annotation (Placement(transformation(extent={{40,-420},{80,-380}}), + iconTransformation(extent={{40,-130},{80,-90}}))); + Buildings.Controls.OBC.CDL.Interfaces.RealOutput yTZon[nGro, nZon]( + final unit=fill("K", nGro, nZon), + displayUnit=fill("degC", nGro, nZon), + final quantity=fill("ThermodynamicTemperature", nGro, nZon)) "Zone temperature" + annotation (Placement(transformation(extent={{40,-460},{80,-420}}), + iconTransformation(extent={{40,-170},{80,-130}}))); + Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput yWin[nGro,nZon] + "True when the window is open, false when the window is close or the zone does not have window status sensor" + annotation (Placement(transformation(extent={{40,-540},{80,-500}}), + iconTransformation(extent={{40,-190},{80,-150}}))); + +protected + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator zonOccDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,70},{10,90}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uOccDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,30},{10,50}}))); + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator tNexOccDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator uCooTimDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-50},{10,-30}}))); + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator uWarTimDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-90},{10,-70}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uOccHeaHigDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-130},{10,-110}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uHigOccCooDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-170},{10,-150}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uUnoHeaHigDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-210},{10,-190}}))); + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator THeaSetOffDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-250},{10,-230}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uEndSetBacDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-290},{10,-270}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uHigUnoCooDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-320},{10,-300}}))); + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator TCooSetOffDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-380},{10,-360}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uEndSetUpDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-410},{10,-390}}))); + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator TZonDup( + final nin=nZon, + final nout=nGro) "Duplicator" + annotation (Placement(transformation(extent={{-10,-450},{10,-430}}))); + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator uWinDup( + final nin=nZon, + final nout=nGro) + "Duplicator" + annotation (Placement(transformation(extent={{-10,-530},{10,-510}}))); + +equation + connect(zonOcc, zonOccDup.u) + annotation (Line(points={{-60,80},{-12,80}}, color={255,0,255})); + connect(uOcc,uOccDup. u) + annotation (Line(points={{-60,40},{-12,40}}, color={255,0,255})); + connect(tNexOcc, tNexOccDup.u) + annotation (Line(points={{-60,0},{-12,0}}, color={0,0,127})); + connect(uCooTim, uCooTimDup.u) + annotation (Line(points={{-60,-40},{-12,-40}}, color={0,0,127})); + connect(uWarTim, uWarTimDup.u) + annotation (Line(points={{-60,-80},{-12,-80}}, color={0,0,127})); + connect(uOccHeaHig, uOccHeaHigDup.u) + annotation (Line(points={{-60,-120},{-12,-120}}, color={255,0,255})); + connect(uHigOccCoo, uHigOccCooDup.u) + annotation (Line(points={{-60,-160},{-12,-160}}, color={255,0,255})); + connect(uUnoHeaHig, uUnoHeaHigDup.u) + annotation (Line(points={{-60,-200},{-12,-200}}, color={255,0,255})); + connect(THeaSetOff, THeaSetOffDup.u) + annotation (Line(points={{-60,-240},{-12,-240}}, color={0,0,127})); + connect(uEndSetBac, uEndSetBacDup.u) + annotation (Line(points={{-60,-280},{-12,-280}}, color={255,0,255})); + connect(uHigUnoCoo, uHigUnoCooDup.u) + annotation (Line(points={{-60,-310},{-12,-310}}, color={255,0,255})); + connect(TCooSetOff, TCooSetOffDup.u) + annotation (Line(points={{-60,-370},{-12,-370}}, color={0,0,127})); + connect(uEndSetUp, uEndSetUpDup.u) + annotation (Line(points={{-60,-400},{-12,-400}}, color={255,0,255})); + connect(TZon, TZonDup.u) + annotation (Line(points={{-60,-440},{-12,-440}}, color={0,0,127})); + connect(uWin, uWinDup.u) + annotation (Line(points={{-60,-520},{-12,-520}}, color={255,0,255})); + connect(zonOccDup.y, yzonOcc) + annotation (Line(points={{12,80},{60,80}}, color={255,0,255})); + connect(uOccDup.y, yOcc) + annotation (Line(points={{12,40},{60,40}}, color={255,0,255})); + connect(ytNexOcc, tNexOccDup.y) + annotation (Line(points={{60,0},{12,0}}, color={0,0,127})); + connect(yCooTim, uCooTimDup.y) + annotation (Line(points={{60,-40},{12,-40}}, color={0,0,127})); + connect(uWarTimDup.y, yWarTim) + annotation (Line(points={{12,-80},{60,-80}}, color={0,0,127})); + connect(uOccHeaHigDup.y, yOccHeaHig) + annotation (Line(points={{12,-120},{60,-120}}, color={255,0,255})); + connect(uHigOccCooDup.y, yHigOccCoo) + annotation (Line(points={{12,-160},{60,-160}}, color={255,0,255})); + connect(uUnoHeaHigDup.y, yUnoHeaHig) + annotation (Line(points={{12,-200},{60,-200}}, color={255,0,255})); + connect(THeaSetOffDup.y, yTHeaSetOff) + annotation (Line(points={{12,-240},{60,-240}}, color={0,0,127})); + connect(uEndSetBacDup.y, yEndSetBac) + annotation (Line(points={{12,-280},{60,-280}}, color={255,0,255})); + connect(uHigUnoCooDup.y, yHigUnoCoo) + annotation (Line(points={{12,-310},{60,-310}}, color={255,0,255})); + connect(TCooSetOffDup.y, yTCooSetOff) + annotation (Line(points={{12,-370},{60,-370}}, color={0,0,127})); + connect(uEndSetUpDup.y, yEndSetUp) + annotation (Line(points={{12,-400},{60,-400}}, color={255,0,255})); + connect(TZonDup.y, yTZon) + annotation (Line(points={{12,-440},{60,-440}}, color={0,0,127})); + connect(uWinDup.y, yWin) + annotation (Line(points={{12,-520},{60,-520}}, color={255,0,255})); + + annotation (defaultComponentName="zonStaDup", + Icon(coordinateSystem(preserveAspectRatio=false, extent={{-40,-180}, + {40,220}}), graphics={ + Rectangle( + extent={{-40,220},{40,-180}}, + lineColor={28,108,200}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Text( + extent={{-36,138},{6,124}}, + textColor={0,0,127}, + pattern=LinePattern.Dash, + textString="uCooTim"), + Text( + extent={{-36,118},{4,106}}, + textColor={0,0,127}, + pattern=LinePattern.Dash, + textString="uWarTim"), + Text( + extent={{-34,80},{16,64}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uOccHeaHig"), + Text( + extent={{-34,60},{16,46}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uHigOccCoo"), + Text( + extent={{-34,-60},{18,-76}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uHigUnoCoo"), + Text( + extent={{-34,-20},{16,-34}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uEndSetBac"), + Text( + extent={{-34,-102},{14,-116}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uEndSetUp"), + Text( + extent={{-34,18},{16,4}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uUnoHeaHig"), + Text( + extent={{-34,-142},{-12,-154}}, + textColor={0,0,127}, + pattern=LinePattern.Dash, + textString="TZon"), + Text( + extent={{-36,-82},{14,-98}}, + textColor={0,0,127}, + pattern=LinePattern.Dash, + textString="TCooSetOff"), + Text( + extent={{-36,-2},{12,-16}}, + textColor={0,0,127}, + pattern=LinePattern.Dash, + textString="THeaSetOff"), + Text( + extent={{-36,178},{6,164}}, + textColor={0,0,127}, + pattern=LinePattern.Dash, + textString="tNexOcc"), + Text( + extent={{-36,220},{0,208}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="ZonOcc"), + Text( + extent={{-36,200},{-10,186}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uOcc"), + Text( + extent={{-38,-162},{-8,-174}}, + textColor={255,0,255}, + pattern=LinePattern.Dash, + textString="uWin"), + Text( + extent={{-40,260},{40,220}}, + textColor={0,0,255}, + textString="%name")}), + Diagram(coordinateSystem(preserveAspectRatio=false, + extent={{-40,-540},{40,100}})), + Documentation(revisions=" + +", info=" +

+This block duplicates the signals of nZon by converting the +input vector-valued signals of dimension nZon to a matrix-valued +output of dimension [nGro, nZon]. +

+

+This block prevent the use of for loops in the connectors between +zones and zone groups by connecting all the zones to each + +Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints.GroupStatus. +

+")); +end ZoneStatusDuplicator; diff --git a/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/package.order b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/package.order index b298cb2e937..74387476cd5 100644 --- a/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/package.order +++ b/Buildings/Controls/OBC/ASHRAE/G36_PR1/Generic/SetPoints/package.order @@ -2,4 +2,5 @@ GroupStatus OperationMode TrimAndRespond ZoneStatus +ZoneStatusDuplicator Validation diff --git a/Buildings/Controls/OBC/CDL/Routing/BooleanVectorFilter.mo b/Buildings/Controls/OBC/CDL/Routing/BooleanVectorFilter.mo new file mode 100644 index 00000000000..eafd0cdf34f --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/BooleanVectorFilter.mo @@ -0,0 +1,69 @@ +within Buildings.Controls.OBC.CDL.Routing; +block BooleanVectorFilter + "Filter a boolean vector based on a boolean mask" + parameter Integer nin "Size of input vector"; + parameter Integer nout "Size of output vector"; + parameter Boolean msk[nin]=fill(true,nin) "Array mask"; + + Interfaces.BooleanInput u[nin] + "Connector of Boolean input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); + Interfaces.BooleanOutput y[nout] + "Connector of Boolean output signals" + annotation (Placement(transformation(extent={{100,-20},{140,20}}))); + +protected + parameter Integer mskId[nout] = Modelica.Math.BooleanVectors.index(msk) + "Indices of included element in input vector"; + +initial equation + assert(nout==sum({if msk[i] then 1 else 0 for i in 1:nin}), + "In " + getInstanceName() + ": The size of the output vector does not + match the size of included elements in the mask."); +equation + y = u[mskId]; + annotation ( + defaultComponentName="booVecFil", + Icon(coordinateSystem(preserveAspectRatio=false), graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={255,0,255}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{-102,0},{-60,0}}, color={255,0,255}), + Line(points={{70,0},{100,0}}, color={255,0,255}), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Polygon( + points={{-60,80},{-60,-80},{20,-10},{60,-10},{80,10},{20,10},{-60,80}}, + lineColor={0,0,0}, + fillColor={255,0,255}, + fillPattern=FillPattern.Solid, + lineThickness=0.5)}), Diagram( + coordinateSystem(preserveAspectRatio=false)), + Documentation(revisions=" + +", info=" +

+This block filters a Boolean vector of size nin to +a vector of size nout given a Boolean mask +msk. +

+

+If an entry in msk is true, then the value +of this input will be sent to the output y, otherwise it +will be discarded. +

+

+The parameter msk must have exactly nout entries +set to true, otherwise an error message is issued. +

+")); +end BooleanVectorFilter; diff --git a/Buildings/Controls/OBC/CDL/Routing/BooleanVectorReplicator.mo b/Buildings/Controls/OBC/CDL/Routing/BooleanVectorReplicator.mo new file mode 100644 index 00000000000..6c49f3e2257 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/BooleanVectorReplicator.mo @@ -0,0 +1,65 @@ +within Buildings.Controls.OBC.CDL.Routing; +block BooleanVectorReplicator "Boolean vector signal replicator" + parameter Integer nin=1 "Size of input vector"; + parameter Integer nout=1 "Number of row in output"; + Interfaces.BooleanInput u[nin] + "Connector of Boolean vector input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); + Interfaces.BooleanOutput y[nout, nin] + "Connector of Boolean matrix output signals" + annotation (Placement(transformation(extent={{100,-20},{140,20}}))); + +equation + y=fill(u, nout); + annotation ( + defaultComponentName="booVecRep", + Documentation( + info=" +

+This block replicates a Boolean vector input signal of size nin, +to a matrix with nout rows and nin columns, +where each row is duplicating the input vector. +

+", + revisions=" + +"), + Icon(graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={255,0,255}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line( + points={{-100,0},{-6,0}}, + color={255,0,255}), + Line( + points={{100,0},{10,0}}, + color={255,0,255}), + Line( + points={{0,0},{100,10}}, + color={255,0,255}), + Line( + points={{0,0},{100,-10}}, + color={255,0,255}), + Ellipse( + extent={{-14,16},{16,-14}}, + lineColor={0,0,0}, + fillColor={255,0,255}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Line( + points={{-100,-10},{0,0}}, + color={255,0,255}), + Line( + points={{-100,10},{0,0}}, + color={255,0,255})})); +end BooleanVectorReplicator; diff --git a/Buildings/Controls/OBC/CDL/Routing/IntegerVectorFilter.mo b/Buildings/Controls/OBC/CDL/Routing/IntegerVectorFilter.mo new file mode 100644 index 00000000000..2dc5450169c --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/IntegerVectorFilter.mo @@ -0,0 +1,69 @@ +within Buildings.Controls.OBC.CDL.Routing; +block IntegerVectorFilter + "Filter an integer vector based on a boolean mask" + parameter Integer nin "Size of input vector"; + parameter Integer nout "Size of output vector"; + parameter Boolean msk[nin]=fill(true,nin) "Array mask"; + + Interfaces.IntegerInput u[nin] + "Connector of Integer input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); + Interfaces.IntegerOutput y[nout] + "Connector of Integer output signals" + annotation (Placement(transformation(extent={{100,-20},{140,20}}))); + +protected + parameter Integer mskId[nout] = Modelica.Math.BooleanVectors.index(msk) + "Indices of included element in input vector"; + +initial equation + assert(nout==sum({if msk[i] then 1 else 0 for i in 1:nin}), + "The size of the output vector does not match the + size of included elements in the mask."); +equation + y = u[mskId]; + annotation ( + defaultComponentName="intVecFil", + Icon(coordinateSystem(preserveAspectRatio=false), graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={255,127,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Polygon( + points={{-60,80},{-60,-80},{20,-10},{60,-10},{80,10},{20,10},{-60,80}}, + lineColor={0,0,0}, + fillColor={255,127,0}, + fillPattern=FillPattern.Solid, + lineThickness=0.5), + Line(points={{-100,0},{-60,0}}, color={255,127,0}), + Line(points={{70,0},{100,0}}, color={255,127,0})}), Diagram( + coordinateSystem(preserveAspectRatio=false)), + Documentation(revisions=" + +", info=" +

+This block filters a Integer vector of size nin to +a vector of size nout given a Boolean mask +msk. +

+

+If an entry in msk is true, then the value +of this input will be sent to the output y, otherwise it +will be discarded. +

+

+The parameter msk must have exactly nout entries +set to true, otherwise an error message is issued. +

+")); +end IntegerVectorFilter; diff --git a/Buildings/Controls/OBC/CDL/Routing/IntegerVectorReplicator.mo b/Buildings/Controls/OBC/CDL/Routing/IntegerVectorReplicator.mo new file mode 100644 index 00000000000..42b73409658 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/IntegerVectorReplicator.mo @@ -0,0 +1,62 @@ +within Buildings.Controls.OBC.CDL.Routing; +block IntegerVectorReplicator "Integer vector signal replicator" + parameter Integer nin=1 "Size of input vector"; + parameter Integer nout=1 "Number of row in output"; + Interfaces.IntegerInput u[nin] + "Connector of Integer vector input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); + Interfaces.IntegerOutput y[nout, nin] + "Connector of Integer matrix output signals" + annotation (Placement(transformation(extent={{100,-20},{140,20}}))); + +equation + y=fill(u, nout); + annotation ( + defaultComponentName="intVecRep", + Icon( + graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={255,127,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line( + points={{-100,0},{-6,0}}, + color={255,127,0}), + Line( + points={{100,0},{10,0}}, + color={255,127,0}), + Line( + points={{0,0},{100,10}}, + color={255,127,0}), + Line( + points={{0,0},{100,-10}}, + color={255,127,0}), + Ellipse( + extent={{-14,16},{16,-14}}, + lineColor={0,0,0}, + fillColor={255,127,0}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Line(points={{-100,-10},{0,0}}, color={255,127,0}), + Line(points={{-100,10},{0,0}}, color={255,127,0})}), + Documentation( + info=" +

+This block replicates an Integer vector input signal of size nin, +to a matrix with nout rows and nin columns, +where each row is duplicating the input vector. +

+", + revisions=" + +")); +end IntegerVectorReplicator; diff --git a/Buildings/Controls/OBC/CDL/Routing/RealVectorFilter.mo b/Buildings/Controls/OBC/CDL/Routing/RealVectorFilter.mo new file mode 100644 index 00000000000..80f5c4e61c5 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/RealVectorFilter.mo @@ -0,0 +1,70 @@ +within Buildings.Controls.OBC.CDL.Routing; +block RealVectorFilter + "Filter a real vector of based on a boolean mask" + parameter Integer nin "Size of input vector"; + parameter Integer nout "Size of output vector"; + parameter Boolean msk[nin]=fill(true,nin) "Array mask"; + + Interfaces.RealInput u[nin] + "Connector of Real input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); + Interfaces.RealOutput y[nout] + "Connector of Real output signals" + annotation (Placement(transformation(extent={{100,-20},{140,20}}))); + +protected + parameter Integer mskId[nout] = Modelica.Math.BooleanVectors.index(msk) + "Indices of included element in input vector"; + +initial equation + assert(nout==sum({if msk[i] then 1 else 0 for i in 1:nin}), + "The size of the output vector does not match the + size of included elements in the mask."); +equation + y = u[mskId]; + annotation ( + defaultComponentName="reaVecFil", + Icon(coordinateSystem(preserveAspectRatio=false), graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,0,127}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Polygon( + points={{-60,80},{-60,-80},{20,-10},{60,-10},{80,10},{20,10},{-60,80}}, + lineColor={0,0,0}, + fillColor={0,0,127}, + fillPattern=FillPattern.Solid, + lineThickness=0.5), + Line(points={{-100,0},{-60,0}}, color={0,0,127}), + Line(points={{70,0},{100,0}}, color={0,0,127})}), + Diagram( + coordinateSystem(preserveAspectRatio=false)), + Documentation(revisions=" + +", info=" +

+This block filters a Real vector of size nin to +a vector of size nout given a boolean mask +msk. +

+

+If an entry in msk is true, then the value +of this input will be sent to the output y, otherwise it +will be discarded. +

+

+The parameter msk must have exactly nout entries +set to true, otherwise an error message is issued. +

+")); +end RealVectorFilter; diff --git a/Buildings/Controls/OBC/CDL/Routing/RealVectorReplicator.mo b/Buildings/Controls/OBC/CDL/Routing/RealVectorReplicator.mo new file mode 100644 index 00000000000..de3434fcf62 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/RealVectorReplicator.mo @@ -0,0 +1,61 @@ +within Buildings.Controls.OBC.CDL.Routing; +block RealVectorReplicator "Real vector signal replicator" + parameter Integer nin=1 "Size of input vector"; + parameter Integer nout=1 "Number of row in output"; + Interfaces.RealInput u[nin] + "Connector of Real vector input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); + Interfaces.RealOutput y[nout, nin] + "Connector of Real matrix output signals" + annotation (Placement(transformation(extent={{100,-20},{140,20}}))); + +equation + y=fill(u, nout); + annotation ( + defaultComponentName="reaVecRep", + Documentation( + info=" +

+This block replicates an Real vector input signal of size nin, +to a matrix with nout rows and nin columns, +where each row is duplicating the input vector. +

+", + revisions=" + +"), + Icon(graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,0,127}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line( + points={{-100,0},{-6,0}}, + color={0,0,127}), + Line( + points={{100,0},{10,0}}, + color={0,0,127}), + Line( + points={{0,0},{100,10}}, + color={0,0,127}), + Line( + points={{0,0},{100,-10}}, + color={0,0,127}), + Ellipse( + extent={{-14,16},{16,-14}}, + lineColor={0,0,0}, + fillColor={0,0,127}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Line(points={{-100,-10},{0,0}}, color={0,0,127}), + Line(points={{-100,10},{0,0}}, color={0,0,127})})); +end RealVectorReplicator; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorFilter.mo b/Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorFilter.mo new file mode 100644 index 00000000000..fd2940cd6a4 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorFilter.mo @@ -0,0 +1,49 @@ +within Buildings.Controls.OBC.CDL.Routing.Validation; +model BooleanVectorFilter + "Validation model for the BooleanVectorFilter block" + Buildings.Controls.OBC.CDL.Routing.BooleanVectorFilter + booFil(nin=3, nout=2, msk={true,false,true}) + "Block that filter the input vector" + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + + Logical.Sources.Constant booInp[3](k={true,true,false}) "Boolean inputs" + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); +equation + connect(booInp.y, booFil.u) + annotation (Line(points={{-18,0},{18,0}}, color={255,0,255})); + annotation ( + experiment( + StopTime=1.0, + Tolerance=1e-06), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/BooleanVectorFilter.mos" "Simulate and plot"), + Documentation( + info=" +

+Validation test for the block + +Buildings.Controls.OBC.CDL.Routing.BooleanVectorFilter. +

+", + revisions=" + +"), + Icon( + graphics={ + Ellipse( + lineColor={75,138,73}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid, + extent={{-100,-100},{100,100}}), + Polygon( + lineColor={0,0,255}, + fillColor={75,138,73}, + pattern=LinePattern.None, + fillPattern=FillPattern.Solid, + points={{-36,60},{64,0},{-36,-60},{-36,60}})})); +end BooleanVectorFilter; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorReplicator.mo b/Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorReplicator.mo new file mode 100644 index 00000000000..47e30cf1a38 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/BooleanVectorReplicator.mo @@ -0,0 +1,49 @@ +within Buildings.Controls.OBC.CDL.Routing.Validation; +model BooleanVectorReplicator + "Validation model for the BooleanVectorReplicator block" + Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator booRep(nin=2, nout=3) + "Block that outputs the vector replicating input value" + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + Buildings.Controls.OBC.CDL.Logical.Sources.Pulse booPul[2](period=fill(0.2,2)) + "Block that outputs boolean pulse" + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); + +equation + connect(booPul.y, booRep.u) + annotation (Line(points={{-18,0},{18,0}}, color={255,0,255})); + annotation ( + experiment( + StopTime=1.0, + Tolerance=1e-06), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/BooleanVectorReplicator.mos" "Simulate and plot"), + Documentation( + info=" +

+Validation test for the block + +Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator. +

+", + revisions=" + +"), + Icon( + graphics={ + Ellipse( + lineColor={75,138,73}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid, + extent={{-100,-100},{100,100}}), + Polygon( + lineColor={0,0,255}, + fillColor={75,138,73}, + pattern=LinePattern.None, + fillPattern=FillPattern.Solid, + points={{-36,60},{64,0},{-36,-60},{-36,60}})})); +end BooleanVectorReplicator; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorFilter.mo b/Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorFilter.mo new file mode 100644 index 00000000000..2e80e04d388 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorFilter.mo @@ -0,0 +1,49 @@ +within Buildings.Controls.OBC.CDL.Routing.Validation; +model IntegerVectorFilter + "Validation model for the IntegerVectorFilter block" + Buildings.Controls.OBC.CDL.Routing.IntegerVectorFilter + intFil(nin=3, nout=2, msk={true,false,true}) + "Block that filter the input vector" + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + + Integers.Sources.Constant IntInp[3](k={1,2,3}) "Integer inputs" + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); +equation + connect(IntInp.y, intFil.u) + annotation (Line(points={{-18,0},{18,0}}, color={255,127,0})); + annotation ( + experiment( + StopTime=1.0, + Tolerance=1e-06), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/IntegerVectorFilter.mos" "Simulate and plot"), + Documentation( + info=" +

+Validation test for the block + +Buildings.Controls.OBC.CDL.Routing.IntegerVectorFilter. +

+", + revisions=" + +"), + Icon( + graphics={ + Ellipse( + lineColor={75,138,73}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid, + extent={{-100,-100},{100,100}}), + Polygon( + lineColor={0,0,255}, + fillColor={75,138,73}, + pattern=LinePattern.None, + fillPattern=FillPattern.Solid, + points={{-36,60},{64,0},{-36,-60},{-36,60}})})); +end IntegerVectorFilter; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorReplicator.mo b/Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorReplicator.mo new file mode 100644 index 00000000000..1e40363c832 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/IntegerVectorReplicator.mo @@ -0,0 +1,57 @@ +within Buildings.Controls.OBC.CDL.Routing.Validation; +model IntegerVectorReplicator + "Validation model for the IntegerVectorReplicator block" + Buildings.Controls.OBC.CDL.Routing.IntegerVectorReplicator + intRep(nin=2, nout=3) + "Block that outputs the vector replicating input value" + annotation (Placement(transformation(extent={{40,-10},{60,10}}))); + Buildings.Controls.OBC.CDL.Continuous.Sources.Ramp ram[2]( + height=fill(5,2), + duration=fill(1,2), + offset=fill(-2,2)) "Block that outputs ramp signal" + annotation (Placement(transformation(extent={{-60,-10},{-40,10}}))); + Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt[2] + "Convert Real input to Integer output" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + +equation + connect(ram.y,reaToInt.u) + annotation (Line(points={{-38,0},{-12,0}},color={0,0,127})); + connect(reaToInt.y,intRep.u) + annotation (Line(points={{12,0},{38,0}},color={255,127,0})); + annotation ( + experiment( + StopTime=1.0, + Tolerance=1e-06), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/IntegerVectorReplicator.mos" "Simulate and plot"), + Documentation( + info=" +

+Validation test for the block + +Buildings.Controls.OBC.CDL.Routing.IntegerVectorReplicator. +

+", + revisions=" + +"), + Icon( + graphics={ + Ellipse( + lineColor={75,138,73}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid, + extent={{-100,-100},{100,100}}), + Polygon( + lineColor={0,0,255}, + fillColor={75,138,73}, + pattern=LinePattern.None, + fillPattern=FillPattern.Solid, + points={{-36,60},{64,0},{-36,-60},{-36,60}})})); +end IntegerVectorReplicator; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorFilter.mo b/Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorFilter.mo new file mode 100644 index 00000000000..e3c25ecbdc9 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorFilter.mo @@ -0,0 +1,49 @@ +within Buildings.Controls.OBC.CDL.Routing.Validation; +model RealVectorFilter + "Validation model for the RealVectorFilter block" + Buildings.Controls.OBC.CDL.Routing.RealVectorFilter + reaFil(nin=3, nout=2, msk={true,false,true}) + "Block that filter the input vector" + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + + Continuous.Sources.Constant ReaInp[3](k={1,2,3}) "Real inputs" + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); +equation + connect(ReaInp.y, reaFil.u) + annotation (Line(points={{-18,0},{18,0}}, color={0,0,127})); + annotation ( + experiment( + StopTime=1.0, + Tolerance=1e-06), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/RealVectorFilter.mos" "Simulate and plot"), + Documentation( + info=" +

+Validation test for the block + +Buildings.Controls.OBC.CDL.Routing.RealVectorFilter. +

+", + revisions=" + +"), + Icon( + graphics={ + Ellipse( + lineColor={75,138,73}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid, + extent={{-100,-100},{100,100}}), + Polygon( + lineColor={0,0,255}, + fillColor={75,138,73}, + pattern=LinePattern.None, + fillPattern=FillPattern.Solid, + points={{-36,60},{64,0},{-36,-60},{-36,60}})})); +end RealVectorFilter; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorReplicator.mo b/Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorReplicator.mo new file mode 100644 index 00000000000..b59d0b6a604 --- /dev/null +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/RealVectorReplicator.mo @@ -0,0 +1,52 @@ +within Buildings.Controls.OBC.CDL.Routing.Validation; +model RealVectorReplicator + "Validation model for the RealVectorReplicator block" + Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator + reaRep(nin=2, nout=3) + "Block that outputs the vector replicating input value" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Buildings.Controls.OBC.CDL.Continuous.Sources.Ramp ram[2]( + height=fill(5,2), + duration=fill(1,2), + offset=fill(-2,2)) "Block that outputs ramp signal" + annotation (Placement(transformation(extent={{-60,-10},{-40,10}}))); + +equation + connect(ram.y,reaRep.u) + annotation (Line(points={{-38,0},{-12,0}},color={0,0,127})); + annotation ( + experiment( + StopTime=1.0, + Tolerance=1e-06), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/CDL/Routing/Validation/RealVectorReplicator.mos" "Simulate and plot"), + Documentation( + info=" +

+Validation test for the block + +Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator. +

+", + revisions=" + +"), + Icon( + graphics={ + Ellipse( + lineColor={75,138,73}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid, + extent={{-100,-100},{100,100}}), + Polygon( + lineColor={0,0,255}, + fillColor={75,138,73}, + pattern=LinePattern.None, + fillPattern=FillPattern.Solid, + points={{-36,60},{64,0},{-36,-60},{-36,60}})})); +end RealVectorReplicator; diff --git a/Buildings/Controls/OBC/CDL/Routing/Validation/package.order b/Buildings/Controls/OBC/CDL/Routing/Validation/package.order index 2f48f21d8c5..b82fce620a9 100644 --- a/Buildings/Controls/OBC/CDL/Routing/Validation/package.order +++ b/Buildings/Controls/OBC/CDL/Routing/Validation/package.order @@ -1,5 +1,11 @@ BooleanReplicator +BooleanVectorFilter +BooleanVectorReplicator IntegerReplicator +IntegerVectorFilter +IntegerVectorReplicator RealExtractSignal RealExtractor RealReplicator +RealVectorFilter +RealVectorReplicator diff --git a/Buildings/Controls/OBC/CDL/Routing/package.order b/Buildings/Controls/OBC/CDL/Routing/package.order index 7f863025553..ac691ff8bb7 100644 --- a/Buildings/Controls/OBC/CDL/Routing/package.order +++ b/Buildings/Controls/OBC/CDL/Routing/package.order @@ -1,6 +1,12 @@ BooleanReplicator +BooleanVectorFilter +BooleanVectorReplicator IntegerReplicator +IntegerVectorFilter +IntegerVectorReplicator RealExtractSignal RealExtractor RealReplicator +RealVectorFilter +RealVectorReplicator Validation diff --git a/Buildings/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.mo b/Buildings/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.mo new file mode 100644 index 00000000000..4bef97b67e5 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.mo @@ -0,0 +1,305 @@ +within Buildings.Controls.OBC.RadiantSystems.Cooling; +block HighMassSupplyTemperature_TRoomRelHum + "Room temperature controller for radiant cooling with constant mass flow and variable supply temperature" + + parameter Real TSupSet_max( + final unit="K", + displayUnit="degC") = 297.15 "Maximum cooling supply water temperature"; + + parameter Real TSupSet_min( + final unit="K", + displayUnit="degC") "Minimum cooling supply water temperature"; + + parameter Controls.OBC.CDL.Types.SimpleController controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.P + "Type of controller" annotation (Dialog(group="Control gains")); + + parameter Real k( + min=100*Buildings.Controls.OBC.CDL.Constants.eps)=2 + "Gain of controller" + annotation (Dialog(group="Control gains")); + + parameter Real Ti( + final quantity="Time", + final unit="s", + min=100*Buildings.Controls.OBC.CDL.Constants.eps)=3600 + "Time constant of integrator block" + annotation (Dialog(group="Control gains", + 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", + min=100*Buildings.Controls.OBC.CDL.Constants.eps)=0.1 + "Time constant of derivative block" + annotation (Dialog(group="Control gains", + enable=controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PD or controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PID)); + + Controls.OBC.CDL.Interfaces.RealInput TRooSet( + final unit="K", + displayUnit="degC") + "Set point for room air temperature" annotation (Placement(transformation( + extent={{-140,40},{-100,80}}), iconTransformation(extent={{-140,40}, + {-100,80}}))); + + Controls.OBC.CDL.Interfaces.RealInput TRoo( + final unit="K", + displayUnit="degC") "Measured room air temperature" + annotation (Placement(transformation( + extent={{-140,-20},{-100,20}}), iconTransformation(extent={{-140,-20}, + {-100,20}}))); + + Controls.OBC.CDL.Interfaces.RealInput phiRoo( + final unit="1") "Measured room air relative humidity" + annotation (Placement(transformation( + extent={{-140,-80},{-100,-40}}), iconTransformation(extent={{-140,-80}, + {-100,-40}}))); + + Controls.OBC.CDL.Interfaces.RealOutput TSupSet( + final unit="K", + displayUnit="degC") "Set point for cooling supply water temperature" + annotation (Placement(transformation(extent={{100,60},{140,100}}), + iconTransformation(extent={{100,40},{140,80}}))); + + Controls.OBC.CDL.Interfaces.RealOutput y( + final unit="1", + final min=0, + final max=1) + "Control signal for heating system from P controller" + annotation (Placement( + transformation(extent={{100,10},{140,50}}), iconTransformation(extent={{ + 100,0},{140,40}}))); + + Controls.OBC.CDL.Interfaces.BooleanOutput on + "Outputs true if the system is demanded on" annotation (Placement( + transformation(extent={{100,-50},{140,-10}}),iconTransformation(extent={{100,-40}, + {140,0}}))); + + Controls.OBC.CDL.Interfaces.RealOutput yPum( + final unit="1", + final min=0, + final max=1) + "Pump speed control signal" + annotation (Placement(transformation(extent={{100,-100},{140,-60}}), + iconTransformation(extent={{100,-80},{140,-40}}))); + + CDL.Psychrometrics.DewPoint_TDryBulPhi dewPoi + "Dew point temperature, used to avoid condensation" + annotation (Placement(transformation(extent={{20,-20},{40,0}}))); + CDL.Continuous.Hysteresis hysCoo( + uLow=0.1, + uHigh=0.2) + "Hysteresis to switch system on and off" + annotation (Placement(transformation(extent={{20,-90},{40,-70}}))); + CDL.Continuous.PID conCoo( + final controllerType=controllerType, + final k=k, + final Ti = Ti, + final Td = Td, + final yMax=1, + final yMin=0, + reverseActing=false) + "Controller for cooling" + annotation (Placement(transformation(extent={{-80,10},{-60,30}}))); + +protected + CDL.Continuous.Sources.Constant TSupMin( + final k( + final unit="K", + displayUnit="degC") = TSupSet_min, + y(final unit="K", displayUnit="degC")) + "Minimum cooling supply water temperature" + annotation (Placement(transformation(extent={{-80,-50},{-60,-30}}))); + CDL.Continuous.Sources.Constant TSupMax( + final k( + final unit="K", + displayUnit="degC") = TSupSet_max, + y(final unit="K", displayUnit="degC")) + "Maximum cooling supply water temperature" + annotation (Placement(transformation(extent={{-80,40},{-60,60}}))); + + CDL.Continuous.Sources.Constant one(final k=1) "Outputs one" + annotation (Placement(transformation(extent={{-80,-20},{-60,0}}))); + CDL.Continuous.Sources.Constant zero(final k=0) "Outputs zero" + annotation (Placement(transformation(extent={{-80,70},{-60,90}}))); + + CDL.Continuous.Line TSupNoDewPoi( + limitBelow=false, + limitAbove=false, + y(final unit="K", displayUnit="degC")) + "Set point for supply water temperature without consideration of dew point" + annotation (Placement(transformation(extent={{20,10},{40,30}}))); + CDL.Continuous.Max TSupCoo + "Cooling water supply temperature" + annotation (Placement(transformation(extent={{60,14},{80,34}}))); + CDL.Conversions.BooleanToReal booToRea( + final realFalse=0, + final realTrue=1) + "Pump control signal as a Real number (either 0 or 1)" + annotation (Placement(transformation(extent={{60,-90},{80,-70}}))); + +equation + connect(hysCoo.y,booToRea.u) + annotation (Line(points={{42,-80},{58,-80}}, color={255,0,255})); + connect(conCoo.y,hysCoo.u) + annotation (Line(points={{-58,20},{0,20},{0,-80},{18,-80}}, + color={0,0,127})); + connect(TSupCoo.u2,dewPoi.TDewPoi) + annotation (Line(points={{58,18},{48,18},{48,-10},{42,-10}}, color={0,0,127})); + connect(TSupCoo.y, TSupSet) annotation (Line(points={{82,24},{86,24},{86,80},{ + 120,80}}, color={0,0,127})); + connect(conCoo.y, y) annotation (Line(points={{-58,20},{0,20},{0,-24},{90,-24}, + {90,30},{120,30}},color={0,0,127})); + connect(conCoo.u_s, TRooSet) annotation (Line(points={{-82,20},{-92,20},{-92,60}, + {-120,60}}, color={0,0,127})); + connect(dewPoi.phi, phiRoo) annotation (Line(points={{18,-16},{-10,-16},{-10,-88}, + {-92,-88},{-92,-60},{-120,-60}}, + color={0,0,127})); + connect(booToRea.y, yPum) + annotation (Line(points={{82,-80},{120,-80}}, color={0,0,127})); + connect(hysCoo.y, on) annotation (Line(points={{42,-80},{50,-80},{50,-30},{120, + -30}}, color={255,0,255})); + connect(TSupNoDewPoi.x1, zero.y) annotation (Line(points={{18,28},{-34,28},{-34, + 80},{-58,80}}, color={0,0,127})); + connect(TSupNoDewPoi.f1, TSupMax.y) annotation (Line(points={{18,24},{-40,24}, + {-40,50},{-58,50}}, color={0,0,127})); + connect(TSupNoDewPoi.x2, one.y) annotation (Line(points={{18,16},{-40,16},{-40, + -10},{-58,-10}}, color={0,0,127})); + connect(TSupNoDewPoi.f2, TSupMin.y) annotation (Line(points={{18,12},{-34,12}, + {-34,-40},{-58,-40}}, color={0,0,127})); + connect(conCoo.y, TSupNoDewPoi.u) + annotation (Line(points={{-58,20},{18,20}}, color={0,0,127})); + connect(TSupNoDewPoi.y, TSupCoo.u1) annotation (Line(points={{42,20},{52,20},{ + 52,30},{58,30}}, color={0,0,127})); + connect(TRoo, conCoo.u_m) annotation (Line(points={{-120,0},{-88,0},{-88,4},{-70, + 4},{-70,8}}, color={0,0,127})); + connect(TRoo, dewPoi.TDryBul) annotation (Line(points={{-120,0},{-88,0},{-88,-80}, + {-16,-80},{-16,-4},{18,-4}}, color={0,0,127})); + annotation ( + defaultComponentName="conCoo", + Diagram(coordinateSystem(extent={{-100,-100},{100,100}})), Icon( + coordinateSystem(extent={{-100,-100},{100,100}}), graphics={ + Rectangle(extent={{-172,66},{-172,66}}, lineColor={28,108,200}), + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,0,127}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Text( + extent={{58,94},{94,44}}, + textColor={0,0,127}, + textString="TSupSet"), + Text( + extent={{76,-44},{96,-90}}, + textColor={0,0,127}, + textString="yPum"), + Text( + extent={{76,2},{98,-16}}, + textColor={0,0,127}, + textString="on"), + Text( + extent={{-92,92},{-48,44}}, + textColor={0,0,127}, + textString="TRooSet"), + Text( + extent={{-94,32},{-74,-14}}, + textColor={0,0,127}, + textString="TRoo"), + Rectangle( + extent={{-30,-16},{48,-40}}, + lineColor={95,95,95}, + lineThickness=1, + fillColor={95,95,95}, + fillPattern=FillPattern.Solid), + Line( + points={{56,-82},{56,-26},{-24,-26},{-24,-20},{56,-20}}, + color={28,108,200}, + thickness=1), + Line(points={{-100,0},{-30,0}}, color={28,108,200}), + Rectangle( + extent={{-30,-16},{48,48}}, + lineColor={28,108,200}, + fillColor={85,170,255}, + fillPattern=FillPattern.Solid, + pattern=LinePattern.None), + Line(points={{-100,60},{-64,60},{-64,26},{-30,26}}, color={28,108,200}), + Line(points={{106,60},{74,60},{74,-36},{58,-36}}, color={28,108,200}), + Ellipse( + extent={{46,-50},{68,-72}}, + lineColor={0,0,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Polygon( + points={{56,-50},{46,-60},{68,-60},{56,-50}}, + lineColor={28,108,200}, + pattern=LinePattern.None, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{100,-60},{84,-60},{68,-60}}, color={28,108,200}), + Ellipse( + extent={{56,-32},{64,-40}}, + lineColor={0,0,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{100,-20},{86,-20},{86,-60}}, + color={255,0,255}), + Text( + extent={{80,32},{98,16}}, + textColor={0,0,127}, + textString="y"), + Text( + extent={{230,108},{110,58}}, + textColor={0,0,127}, + textString=DynamicSelect("", + String(TSupSet, + leftJustified=false, + significantDigits=3))), + Text( + extent={{230,64},{110,14}}, + textColor={0,0,127}, + textString=DynamicSelect("", + String(y, + leftJustified=false, + significantDigits=2))), + Line(points={{-30,-8},{-66,-8},{-66,-60},{-100,-60}}, + color={28,108,200}), + Text( + extent={{-92,-24},{-72,-70}}, + textColor={0,0,127}, + textString="phi")}), + Documentation(info=" +

+Controller for a radiant cooling system. +

+

+The controller tracks the room temperature set point TRooSet by +adjusting the supply water temperature set point TSupSet +based on the output signal y of the proportional controller. +The supply water temperature set point TSupSet is +limited by the dew point temperature that is calculated based on the inputs TRoo and phiRoo. +The pump is either off or operates at full speed, in which case yPum = 1. +The pump control is based on a hysteresis that switches the pump on when the output of the +proportional controller y exceeds 0.2, and the pump is commanded off when the output falls +below 0.1. See figure below for the control charts. +

+

+\"Image +

+

+For systems with high thermal mass, this controller should be left configured +as a P-controller, which is the default setting. +PI-controller likely saturate due to the slow system response. +

+", revisions=" + +")); +end HighMassSupplyTemperature_TRoomRelHum; diff --git a/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/HighMassSupplyTemperature_TRoomRelHum.mo b/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/HighMassSupplyTemperature_TRoomRelHum.mo new file mode 100644 index 00000000000..249087a1d0b --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/HighMassSupplyTemperature_TRoomRelHum.mo @@ -0,0 +1,66 @@ +within Buildings.Controls.OBC.RadiantSystems.Cooling.Validation; +model HighMassSupplyTemperature_TRoomRelHum + "Validation model for the room temperature controller" + extends Modelica.Icons.Example; + + Controls.OBC.CDL.Continuous.Sources.TimeTable TPhiRooMea( + table=[0.0, 18, 0.5; + 0.5, 28, 0.5; + 1.0, 18, 0.5; + 1.0, 18, 0.9; + 1.5, 28, 0.9; + 2.0, 18, 0.9], + extrapolation=Buildings.Controls.OBC.CDL.Types.Extrapolation.HoldLastPoint, + offset={273.15, 0}, + timeScale=3600) "Measured room temperature and relative humidity" + annotation (Placement(transformation(extent={{-62,-30},{-42,-10}}))); + + Controls.OBC.RadiantSystems.Cooling.HighMassSupplyTemperature_TRoomRelHum conCoo( + TSupSet_min=291.15) "Controller" + annotation (Placement(transformation(extent={{0,-10},{20,10}}))); + + Controls.OBC.CDL.Continuous.Sources.Constant TRooSet(final k( + final unit="K", + displayUnit="degC") = 297.15) "Set point temperature for room" + annotation (Placement(transformation(extent={{-60,10},{-40,30}}))); + + CDL.Psychrometrics.DewPoint_TDryBulPhi dewPoi "Dew point temperature" + annotation (Placement(transformation(extent={{0,-40},{20,-20}}))); +equation + connect(TRooSet.y, conCoo.TRooSet) annotation (Line(points={{-38,20},{-16,20}, + {-16,6},{-2,6}}, color={0,0,127})); + connect(TPhiRooMea.y[1], conCoo.TRoo) annotation (Line(points={{-40,-20},{-14, + -20},{-14,0},{-2,0}}, + color={0,0,127})); + connect(TPhiRooMea.y[2], conCoo.phiRoo) annotation (Line(points={{-40,-20},{-14, + -20},{-14,-6},{-2,-6}},color={0,0,127})); + connect(dewPoi.TDryBul, TPhiRooMea.y[1]) annotation (Line(points={{-2,-24},{-14, + -24},{-14,-20},{-40,-20}}, color={0,0,127})); + connect(dewPoi.phi, TPhiRooMea.y[2]) annotation (Line(points={{-2,-36},{-14,-36}, + {-14,-20},{-40,-20}}, color={0,0,127})); + annotation ( + Documentation( + info=" +

+This example validates the room temperature controller + +Buildings.Controls.OBC.RadiantSystems.Cooling.HighMassSupplyTemperature_TRoomRelHum +for the radiant system. +The validation model applies a ramp signal to the controller input for the measured room air temperature. +The model also calculates the dew point temperature to verify that the supply water temperature is never below the dew point. +

+", + revisions=" + +"), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/RadiantSystems/Cooling/Validation/HighMassSupplyTemperature_TRoomRelHum.mos" "Simulate and plot"), + experiment( + StopTime=7200, + Tolerance=1e-06)); +end HighMassSupplyTemperature_TRoomRelHum; diff --git a/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.mo b/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.mo new file mode 100644 index 00000000000..28d6998f1a6 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.mo @@ -0,0 +1,20 @@ +within Buildings.Controls.OBC.RadiantSystems.Cooling; +package Validation "Collection of validation models" + extends Modelica.Icons.ExamplesPackage; + +annotation (preferredView="info", Documentation(info=" +

+This package contains validation models for the classes in + +Buildings.Controls.OBC.RadiantSystems.Cooling. +

+

+Note that most validation models contain simple input data +which may not be realistic, but for which the correct +output can be obtained through an analytic solution. +The examples plot various outputs, which have been verified against these +solutions. These model outputs are stored as reference data and +used for continuous validation whenever models in the library change. +

+")); +end Validation; diff --git a/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.order b/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.order new file mode 100644 index 00000000000..7e3ef7d27df --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Cooling/Validation/package.order @@ -0,0 +1 @@ +HighMassSupplyTemperature_TRoomRelHum diff --git a/Buildings/Controls/OBC/RadiantSystems/Cooling/package.mo b/Buildings/Controls/OBC/RadiantSystems/Cooling/package.mo new file mode 100644 index 00000000000..47b17a58dec --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Cooling/package.mo @@ -0,0 +1,32 @@ +within Buildings.Controls.OBC.RadiantSystems; +package Cooling "Package with control sequences for radiant cooling systems" + extends Modelica.Icons.Package; + +annotation (preferredView="info", Documentation(info=" +

+Package with controllers for radiant cooling systems. +

+"), + Icon(graphics={ + Rectangle( + extent={{-60,-24},{68,-76}}, + lineColor={95,95,95}, + lineThickness=1, + fillColor={95,95,95}, + fillPattern=FillPattern.Solid), + Polygon( + points={{50,-76},{50,-50},{-40,-50},{-40,-40},{56,-40},{56,-76},{60,-76}, + {60,-36},{-44,-36},{-44,-54},{46,-54},{46,-76},{50,-76}}, + lineColor={0,0,255}, + pattern=LinePattern.None, + lineThickness=1, + fillColor={0,0,255}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-60,-24},{68,78}}, + lineColor={28,108,200}, + pattern=LinePattern.None, + lineThickness=1, + fillColor={85,170,255}, + fillPattern=FillPattern.Solid)})); +end Cooling; diff --git a/Buildings/Controls/OBC/RadiantSystems/Cooling/package.order b/Buildings/Controls/OBC/RadiantSystems/Cooling/package.order new file mode 100644 index 00000000000..4199e6c0cc8 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Cooling/package.order @@ -0,0 +1,2 @@ +HighMassSupplyTemperature_TRoomRelHum +Validation diff --git a/Buildings/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.mo b/Buildings/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.mo new file mode 100644 index 00000000000..4db2da0372e --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.mo @@ -0,0 +1,269 @@ +within Buildings.Controls.OBC.RadiantSystems.Heating; +block HighMassSupplyTemperature_TRoom + "Room temperature controller for radiant heating with constant mass flow and variable supply temperature" + + parameter Real TSupSet_max( + final unit="K", + displayUnit="degC") "Maximum heating supply water temperature"; + parameter Real TSupSet_min( + final unit="K", + displayUnit="degC") = 293.15 "Minimum heating supply water temperature"; + + parameter Controls.OBC.CDL.Types.SimpleController controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.P + "Type of controller" annotation (Dialog(group="Control gains")); + parameter Real k( + min=100*Buildings.Controls.OBC.CDL.Constants.eps)=2 + "Gain of controller" + annotation (Dialog(group="Control gains")); + parameter Real Ti( + final quantity="Time", + final unit="s", + min=100*Buildings.Controls.OBC.CDL.Constants.eps)=3600 + "Time constant of integrator block" + annotation (Dialog(group="Control gains",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", + min=100*Buildings.Controls.OBC.CDL.Constants.eps)=0.1 + "Time constant of derivative block" + annotation (Dialog(group="Control gains",enable=controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PD or controllerType == Buildings.Controls.OBC.CDL.Types.SimpleController.PID)); + + Controls.OBC.CDL.Interfaces.RealInput TRooSet( + final unit="K", + displayUnit="degC") + "Set point for room air temperature" annotation (Placement(transformation( + extent={{-140,40},{-100,80}}), iconTransformation(extent={{-140,40}, + {-100,80}}))); + Controls.OBC.CDL.Interfaces.RealInput TRoo( + final unit="K", + displayUnit="degC") "Measured room air temperature" + annotation (Placement(transformation( + extent={{-140,-20},{-100,20}}), iconTransformation(extent={{-140,-20}, + {-100,20}}))); + Controls.OBC.CDL.Interfaces.RealOutput TSupSet( + final unit="K", + displayUnit="degC") + "Set point for heating supply water temperature" + annotation (Placement(transformation(extent={{100,60},{140,100}}), + iconTransformation(extent={{100,40},{140,80}}))); + + Controls.OBC.CDL.Interfaces.RealOutput y( + final unit="1", + final min=0, + final max=1) + "Control signal for heating system from P controller" + annotation (Placement( + transformation(extent={{100,10},{140,50}}), iconTransformation(extent={{ + 100,0},{140,40}}))); + + Controls.OBC.CDL.Interfaces.BooleanOutput on + "Outputs true if the system is demanded on" annotation (Placement( + transformation(extent={{100,-50},{140,-10}}),iconTransformation(extent={{100,-40}, + {140,0}}))); + + Controls.OBC.CDL.Interfaces.RealOutput yPum( + final unit="1", + final min=0, + final max=1) + "Pump speed control signal" + annotation (Placement(transformation(extent={{100,-100},{140,-60}}), + iconTransformation(extent={{100,-80},{140,-40}}))); + + Controls.OBC.CDL.Continuous.PID conHea( + final controllerType=controllerType, + final k=k, + final Ti = Ti, + final Td = Td, + final yMax=1, + final yMin=0, + final reverseActing=true) "Controller for heating supply set point signal" + annotation (Placement(transformation(extent={{-80,10},{-60,30}}))); + + Controls.OBC.CDL.Continuous.Hysteresis hysHea( + uLow=0.1, + uHigh=0.2) + "Hysteresis to switch system on and off" + annotation (Placement(transformation(extent={{-40,-70},{-20,-50}}))); + +protected + Controls.OBC.CDL.Continuous.Sources.Constant one(final k=1) "Outputs one" + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); + Controls.OBC.CDL.Continuous.Sources.Constant zero(final k=0) "Outputs zero" + annotation (Placement(transformation(extent={{-40,60},{-20,80}}))); + + Controls.OBC.CDL.Continuous.Sources.Constant THeaSup_minimum(final k( + final unit="K", + displayUnit="degC") = TSupSet_min) + "Negative value of minimum heating supply water temperature" + annotation (Placement(transformation(extent={{-40,30},{-20,50}}))); + + Controls.OBC.CDL.Continuous.Sources.Constant THeaSup_maximum( + final k( + final unit="K", + displayUnit="degC") = TSupSet_max) "Maximum heating supply water temperature" + annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); + + Controls.OBC.CDL.Continuous.Line TSup( + limitBelow=false, + limitAbove=false, + y(final unit="K", + displayUnit="degC")) "Set point for supply water temperature" + annotation (Placement(transformation(extent={{20,10},{40,30}}))); + + CDL.Conversions.BooleanToReal booToRea( + final realFalse=0, + final realTrue=1) + "Pump control signal as a Real number (either 0 or 1)" + annotation (Placement(transformation(extent={{40,-90},{60,-70}}))); +equation + connect(conHea.y,hysHea.u) + annotation (Line(points={{-58,20},{-50,20},{-50,-60},{-42,-60}}, + color={0,0,127})); + connect(TRoo, conHea.u_m) + annotation (Line(points={{-120,0},{-70,0},{-70,8}}, color={0,0,127})); + connect(TRooSet, conHea.u_s) annotation (Line(points={{-120,60},{-90,60},{-90, + 20},{-82,20}}, color={0,0,127})); + connect(TSup.x1, zero.y) annotation (Line(points={{18,28},{0,28},{0,70},{-18,70}}, + color={0,0,127})); + connect(one.y, TSup.x2) annotation (Line(points={{-18,0},{-4,0},{-4,16},{18,16}}, + color={0,0,127})); + connect(conHea.y, TSup.u) annotation (Line(points={{-58,20},{18,20}}, + color={0,0,127})); + connect(TSup.f1, THeaSup_minimum.y) annotation (Line(points={{18,24},{-4,24},{ + -4,40},{-18,40}}, + color={0,0,127})); + connect(THeaSup_maximum.y, TSup.f2) annotation (Line(points={{-18,-30},{0,-30}, + {0,12},{18,12}},color={0,0,127})); + connect(TSup.y, TSupSet) annotation (Line(points={{42,20},{80,20},{80,80},{120, + 80}}, color={0,0,127})); + connect(hysHea.y, on) + annotation (Line(points={{-18,-60},{80,-60},{80,-30},{120,-30}}, + color={255,0,255})); + connect(conHea.y, y) annotation (Line(points={{-58,20},{-50,20},{-50,88},{60,88}, + {60,30},{120,30}}, color={0,0,127})); + connect(booToRea.y, yPum) + annotation (Line(points={{62,-80},{120,-80}}, color={0,0,127})); + connect(booToRea.u, hysHea.y) annotation (Line(points={{38,-80},{20,-80},{20,-60}, + {-18,-60}}, color={255,0,255})); + annotation ( + defaultComponentName="conHea", + Diagram(coordinateSystem(extent={{-100,-100},{100,100}})), Icon( + coordinateSystem(extent={{-100,-100},{100,100}}), graphics={ + Rectangle(extent={{-172,66},{-172,66}}, lineColor={28,108,200}), + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,0,127}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Text( + textColor={0,0,255}, + extent={{-150,110},{150,150}}, + textString="%name"), + Text( + extent={{58,94},{94,44}}, + textColor={0,0,127}, + textString="TSupSet"), + Text( + extent={{76,-44},{96,-90}}, + textColor={0,0,127}, + textString="yPum"), + Text( + extent={{76,2},{98,-16}}, + textColor={0,0,127}, + textString="on"), + Text( + extent={{-92,92},{-48,44}}, + textColor={0,0,127}, + textString="TRooSet"), + Rectangle( + extent={{-30,-16},{48,-40}}, + lineColor={95,95,95}, + lineThickness=1, + fillColor={95,95,95}, + fillPattern=FillPattern.Solid), + Line( + points={{56,-82},{56,-26},{-24,-26},{-24,-20},{56,-20}}, + color={238,46,47}, + thickness=1), + Rectangle( + extent={{-30,-16},{48,48}}, + lineColor={28,108,200}, + fillColor={85,170,255}, + fillPattern=FillPattern.Solid, + pattern=LinePattern.None), + Line(points={{-100,60},{-64,60},{-64,26},{-30,26}}, color={28,108,200}), + Line(points={{106,60},{74,60},{74,-36},{58,-36}}, color={28,108,200}), + Ellipse( + extent={{46,-50},{68,-72}}, + lineColor={0,0,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Polygon( + points={{56,-50},{46,-60},{68,-60},{56,-50}}, + lineColor={28,108,200}, + pattern=LinePattern.None, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{100,-60},{84,-60},{68,-60}}, color={28,108,200}), + Ellipse( + extent={{56,-32},{64,-40}}, + lineColor={0,0,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{100,-20},{86,-20},{86,-60}}, + color={255,0,255}), + Text( + extent={{80,32},{98,16}}, + textColor={0,0,127}, + textString="y"), + Text( + extent={{230,108},{110,58}}, + textColor={0,0,127}, + textString=DynamicSelect("", + String(TSupSet, + leftJustified=false, + significantDigits=3))), + Text( + extent={{230,64},{110,14}}, + textColor={0,0,127}, + textString=DynamicSelect("", + String(y, + leftJustified=false, + significantDigits=2))), + Line(points={{-100,0},{-30,0}}, color={28,108,200}), + Text( + extent={{-92,30},{-72,-16}}, + textColor={0,0,127}, + textString="TRoo")}), + Documentation(info=" +

+Controller for a radiant heating system. +

+

+The controller tracks the room temperature set point TRooSet by +adjusting the supply water temperature set point TSupSet linearly between +TSupSetMin and TSupSetMax +based on the output signal y of the proportional controller. +The pump is either off or operates at full speed, in which case yPum = 1. +The pump control is based on a hysteresis that switches the pump on when the output of the +proportional controller y exceeds 0.2, and the pump is commanded off when the output falls +below 0.1. See figure below for the control charts. +

+

+\"Image +

+

+For systems with high thermal mass, this controller should be left configured +as a P-controller, which is the default setting. +PI-controller likely saturate due to the slow system response. +

+", revisions=" + +")); +end HighMassSupplyTemperature_TRoom; diff --git a/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/HighMassSupplyTemperature_TRoom.mo b/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/HighMassSupplyTemperature_TRoom.mo new file mode 100644 index 00000000000..2d666781948 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/HighMassSupplyTemperature_TRoom.mo @@ -0,0 +1,50 @@ +within Buildings.Controls.OBC.RadiantSystems.Heating.Validation; +model HighMassSupplyTemperature_TRoom + "Validation model for the room temperature controller" + extends Modelica.Icons.Example; + + Controls.OBC.CDL.Continuous.Sources.TimeTable TRooMea( + table=[0,18; 1,22; 2,18], + extrapolation=Buildings.Controls.OBC.CDL.Types.Extrapolation.HoldLastPoint, + offset={273.15}, + timeScale=3600) "Measured room temperature" + annotation (Placement(transformation(extent={{-80,-40},{-60,-20}}))); + + Controls.OBC.RadiantSystems.Heating.HighMassSupplyTemperature_TRoom conHea(TSupSet_max=303.15) "Controller" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + +protected + Controls.OBC.CDL.Continuous.Sources.Constant TRooSet(final k( + final unit="K", + displayUnit="degC") = 293.15) "Set point temperature for room" + annotation (Placement(transformation(extent={{-80,10},{-60,30}}))); +equation + connect(TRooSet.y, conHea.TRooSet) annotation (Line(points={{-58,20},{-36,20}, + {-36,6},{-12,6}}, color={0,0,127})); + connect(TRooMea.y[1], conHea.TRoo) annotation (Line(points={{-58,-30},{-34,-30}, + {-34,-6},{-12,-6}}, color={0,0,127})); + annotation ( + Documentation( + info=" +

+This example validates the room temperature controller + +Buildings.Controls.OBC.RadiantSystems.Heating.HighMassSupplyTemperature_TRoom +for the radiant system. +The validation model applies a ramp signal to the controller input for the measured room air temperature. +

+", + revisions=" + +"), + __Dymola_Commands( + file="modelica://Buildings/Resources/Scripts/Dymola/Controls/OBC/RadiantSystems/Heating/Validation/HighMassSupplyTemperature_TRoom.mos" "Simulate and plot"), + experiment( + StopTime=7200, + Tolerance=1e-06)); +end HighMassSupplyTemperature_TRoom; diff --git a/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.mo b/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.mo new file mode 100644 index 00000000000..ab4fdfa4880 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.mo @@ -0,0 +1,20 @@ +within Buildings.Controls.OBC.RadiantSystems.Heating; +package Validation "Collection of validation models" + extends Modelica.Icons.ExamplesPackage; + +annotation (preferredView="info", Documentation(info=" +

+This package contains validation models for the classes in + +Buildings.Controls.OBC.RadiantSystems.Heating. +

+

+Note that most validation models contain simple input data +which may not be realistic, but for which the correct +output can be obtained through an analytic solution. +The examples plot various outputs, which have been verified against these +solutions. These model outputs are stored as reference data and +used for continuous validation whenever models in the library change. +

+")); +end Validation; diff --git a/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.order b/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.order new file mode 100644 index 00000000000..9d08084193b --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Heating/Validation/package.order @@ -0,0 +1 @@ +HighMassSupplyTemperature_TRoom diff --git a/Buildings/Controls/OBC/RadiantSystems/Heating/package.mo b/Buildings/Controls/OBC/RadiantSystems/Heating/package.mo new file mode 100644 index 00000000000..5b35fb28cf0 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Heating/package.mo @@ -0,0 +1,32 @@ +within Buildings.Controls.OBC.RadiantSystems; +package Heating "Package with control sequences for radiant heating systems" + extends Modelica.Icons.Package; + +annotation (preferredView="info", Documentation(info=" +

+Package with controllers for radiant heating systems. +

+"), + Icon(graphics={ + Rectangle( + extent={{-62,-26},{66,-78}}, + lineColor={95,95,95}, + lineThickness=1, + fillColor={95,95,95}, + fillPattern=FillPattern.Solid), + Polygon( + points={{48,-78},{48,-52},{-42,-52},{-42,-42},{54,-42},{54,-78},{58,-78}, + {58,-38},{-46,-38},{-46,-56},{44,-56},{44,-78},{48,-78}}, + lineColor={238,46,47}, + pattern=LinePattern.None, + lineThickness=1, + fillColor={238,46,47}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-62,-26},{66,76}}, + lineColor={28,108,200}, + pattern=LinePattern.None, + lineThickness=1, + fillColor={85,170,255}, + fillPattern=FillPattern.Solid)})); +end Heating; diff --git a/Buildings/Controls/OBC/RadiantSystems/Heating/package.order b/Buildings/Controls/OBC/RadiantSystems/Heating/package.order new file mode 100644 index 00000000000..de2b0e73ed9 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/Heating/package.order @@ -0,0 +1,2 @@ +HighMassSupplyTemperature_TRoom +Validation diff --git a/Buildings/Controls/OBC/RadiantSystems/package.mo b/Buildings/Controls/OBC/RadiantSystems/package.mo new file mode 100644 index 00000000000..bba97eea989 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/package.mo @@ -0,0 +1,11 @@ +within Buildings.Controls.OBC; +package RadiantSystems "Package with controllers for radiant heating and cooling systems" + extends Modelica.Icons.Package; + +annotation (preferredView="info", Documentation(info=" +

+Package with controllers for radiant heating and cooling systems +such for pipes embedded in the concrete slab. +

+")); +end RadiantSystems; diff --git a/Buildings/Controls/OBC/RadiantSystems/package.order b/Buildings/Controls/OBC/RadiantSystems/package.order new file mode 100644 index 00000000000..12863110ed1 --- /dev/null +++ b/Buildings/Controls/OBC/RadiantSystems/package.order @@ -0,0 +1,2 @@ +Cooling +Heating diff --git a/Buildings/Controls/OBC/package.order b/Buildings/Controls/OBC/package.order index f684728778a..fd5ea55a12a 100644 --- a/Buildings/Controls/OBC/package.order +++ b/Buildings/Controls/OBC/package.order @@ -2,6 +2,7 @@ UsersGuide ASHRAE CDL OutdoorLights +RadiantSystems Shade UnitConversions Utilities diff --git a/Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo b/Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo new file mode 100644 index 00000000000..224afbe3d27 --- /dev/null +++ b/Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo @@ -0,0 +1,154 @@ +within Buildings.Fluid.Boilers.BaseClasses; +partial model PartialBoiler "Boiler base class with efficiency unspecified" + extends Interfaces.TwoPortHeatMassExchanger( + redeclare final Buildings.Fluid.MixingVolumes.MixingVolume vol, + show_T = true, + final tau=VWat*rho_default/m_flow_nominal); + + parameter Buildings.Fluid.Data.Fuels.Generic fue "Fuel type" + annotation (choicesAllMatching = true); + + // These parameters can be supplied via Data records + parameter Modelica.SIunits.Power Q_flow_nominal "Nominal heating power"; + parameter Modelica.SIunits.ThermalConductance UA=0.05*Q_flow_nominal/30 + "Overall UA value"; + parameter Modelica.SIunits.Volume VWat = 1.5E-6*Q_flow_nominal + "Water volume of boiler" + annotation(Dialog(tab = "Dynamics", + enable = not (energyDynamics == Modelica.Fluid.Types.Dynamics.SteadyState))); + parameter Modelica.SIunits.Mass mDry = 1.5E-3*Q_flow_nominal + "Mass of boiler that will be lumped to water heat capacity" + annotation(Dialog(tab = "Dynamics", + enable = not (energyDynamics == Modelica.Fluid.Types.Dynamics.SteadyState))); + parameter Modelica.SIunits.Efficiency eta_nominal + "Boiler efficiency at nominal condition"; + + input Modelica.SIunits.Efficiency eta "Boiler efficiency"; + Modelica.SIunits.Power QFue_flow = y * Q_flow_nominal/eta_nominal + "Heat released by fuel"; + Modelica.SIunits.Power QWat_flow = eta * QFue_flow + UAOve.Q_flow + "Heat transfer from gas into water"; + // The direction of UAOve.Q_flow is from the ambient to the boiler + // and therefore it takes a plus size here. + Modelica.SIunits.MassFlowRate mFue_flow = QFue_flow/fue.h + "Fuel mass flow rate"; + Modelica.SIunits.VolumeFlowRate VFue_flow = mFue_flow/fue.d + "Fuel volume flow rate"; + + Modelica.Blocks.Interfaces.RealInput y(min=0, max=1) "Part load ratio" + annotation (Placement(transformation(extent={{-140,60},{-100,100}}))); + + Modelica.Blocks.Interfaces.RealOutput T( + final quantity="ThermodynamicTemperature", + final unit = "K", displayUnit = "degC", min=0) + "Temperature of the fluid" + annotation (Placement(transformation(extent={{100,70},{120,90}}))); + + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort + "Heat port, can be used to connect to ambient" + annotation (Placement(transformation(extent={{-10,62}, {10,82}}))); + Modelica.Thermal.HeatTransfer.Components.HeatCapacitor heaCapDry( + C=500*mDry, + T(start=T_start)) + if not (energyDynamics == Modelica.Fluid.Types.Dynamics.SteadyState) + "Heat capacity of boiler metal" + annotation (Placement(transformation(extent={{-80,12},{-60,32}}))); + + Buildings.HeatTransfer.Sources.PrescribedHeatFlow preHeaFlo + "Prescribed heat flow" + annotation (Placement(transformation(extent={{-43,-40},{-23,-20}}))); + Modelica.Blocks.Sources.RealExpression Q_flow_in(y=QWat_flow) + "Heat transfer from gas into water" + annotation (Placement(transformation(extent={{-80,-40},{-60,-20}}))); + Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor temSen + "Temperature of fluid" + annotation (Placement(transformation(extent={{0,30},{20,50}}))); + + Modelica.Thermal.HeatTransfer.Components.ThermalConductor UAOve(G=UA) + "Overall thermal conductance (if heatPort is connected)" + annotation (Placement(transformation(extent={{-48,10},{-28,30}}))); + +equation + assert(eta > 0.001, "Efficiency curve is wrong."); + + connect(UAOve.port_b, vol.heatPort) annotation (Line( + points={{-28,20},{-22,20},{-22,-10},{-9,-10}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(UAOve.port_a, heatPort) annotation (Line( + points={{-48,20},{-52,20},{-52,60},{0,60},{0,72}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(heaCapDry.port, vol.heatPort) annotation (Line( + points={{-70,12},{-70,-10},{-9,-10}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(temSen.T, T) annotation (Line( + points={{20,40},{60,40},{60,80},{110,80}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(preHeaFlo.port, vol.heatPort) annotation (Line( + points={{-23,-30},{-15,-30},{-15,-10},{-9,-10}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(Q_flow_in.y,preHeaFlo. Q_flow) annotation (Line( + points={{-59,-30},{-43,-30}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(vol.heatPort, temSen.port) annotation (Line( + points={{-9,-10},{-16,-10},{-16,40},{0,40}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation ( Icon(graphics={ + Polygon( + points={{0,-34},{-12,-52},{14,-52},{0,-34}}, + pattern=LinePattern.None, + smooth=Smooth.None, + fillColor={255,255,0}, + fillPattern=FillPattern.Solid, + lineColor={0,0,0}), + Line( + points={{-100,80},{-80,80},{-80,-44},{-6,-44}}, + smooth=Smooth.None), + Line( + points={{100,80},{80,80},{80,4}}, + color={0,0,127}, + smooth=Smooth.None), + Text( + extent={{160,144},{40,94}}, + textColor={0,0,0}, + textString=DynamicSelect("T", String(T-273.15, format=".1f"))), + Text( + extent={{-38,146},{-158,96}}, + textColor={0,0,0}, + textString=DynamicSelect("y", String(y, format=".2f")))}), +defaultComponentName="boi", +Documentation(info=" +

+This is a base model of a boiler. +The efficiency specified in extended models. +See +Buildings.Fluid.Boilers.UsersGuide for details. +

+", +revisions=" + +")); +end PartialBoiler; diff --git a/Buildings/Fluid/Boilers/BaseClasses/package.mo b/Buildings/Fluid/Boilers/BaseClasses/package.mo new file mode 100644 index 00000000000..35853a222df --- /dev/null +++ b/Buildings/Fluid/Boilers/BaseClasses/package.mo @@ -0,0 +1,11 @@ +within Buildings.Fluid.Boilers; +package BaseClasses "Package with base classes for Buildings.Fluid.Boilers" + extends Modelica.Icons.BasesPackage; + +annotation (preferredView="info", Documentation(info=" +

+This package contains base classes that are used to construct the models in +Buildings.Fluid.Boilers. +

+")); +end BaseClasses; diff --git a/Buildings/Fluid/Boilers/BaseClasses/package.order b/Buildings/Fluid/Boilers/BaseClasses/package.order new file mode 100644 index 00000000000..da9abe7f4f0 --- /dev/null +++ b/Buildings/Fluid/Boilers/BaseClasses/package.order @@ -0,0 +1 @@ +PartialBoiler diff --git a/Buildings/Fluid/Boilers/BoilerTable.mo b/Buildings/Fluid/Boilers/BoilerTable.mo new file mode 100644 index 00000000000..876217ff7bb --- /dev/null +++ b/Buildings/Fluid/Boilers/BoilerTable.mo @@ -0,0 +1,75 @@ +within Buildings.Fluid.Boilers; +model BoilerTable + "Boiler with efficiency described by a table with control signal and inlet temperature" + extends Buildings.Fluid.Boilers.BaseClasses.PartialBoiler( + final eta=effTab.y, + final Q_flow_nominal = per.Q_flow_nominal, + final eta_nominal= per.eta_nominal, + final fue=per.fue, + final UA=per.UA, + final VWat = per.VWat, + final mDry = per.mDry, + final m_flow_nominal = per.m_flow_nominal, + final dp_nominal = per.dp_nominal); + + parameter Buildings.Fluid.Boilers.Data.Generic per + "Records of efficiency curves" + annotation(choicesAllMatching=true, + Placement(transformation(extent={{-40,74},{-20,94}}))); + + Modelica.Blocks.Tables.CombiTable2D effTab( + final table=per.effCur, + final smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative) + "Look-up table that represents a set of efficiency curves varying with both the firing rate (control signal) and the inlet water temperature" + annotation (Placement(transformation(extent={{-70,64},{-50,84}}))); + + Modelica.Blocks.Sources.RealExpression TIn( + y=Medium.temperature(state=Medium.setState_phX( + p=port_a.p, h=inStream(port_a.h_outflow), X=inStream(port_a.Xi_outflow)))) + "Water inlet temperature" + annotation (Placement(transformation(extent={{-98,58},{-78,78}}))); + +initial equation + assert(abs(per.effCur[end,1] - 1) < 1E-6, + "Efficiency curve at full load (y = 1) must be provided."); + +equation + connect(effTab.u1, y) annotation (Line(points={{-72,80},{-120,80}}, + color={0,0,127})); + connect(TIn.y, effTab.u2) + annotation (Line(points={{-77,68},{-72,68}}, color={0,0,127})); + annotation (Documentation(info=" +

+This is a model of a boiler whose efficiency is described +by a table with control signal and inlet temperature. +See +Buildings.Fluid.Boilers.UsersGuide for details. +

+

+The efficiency tables are supplied via + +Buildings.Fluid.Boilers.Data. +

+", revisions=" + +"), Icon(graphics={ + Rectangle( + origin={-48,37}, + lineColor={64,64,64}, + fillColor={255,215,136}, + fillPattern=FillPattern.Solid, + extent={{-12,-11},{12,11}}, + radius=5.0), + Line( + points={{-48,48},{-48,26}}), + Line( + points={{-60,40},{-36,40}}), + Line( + points={{-60,32},{-36,32}})})); +end BoilerTable; diff --git a/Buildings/Fluid/Boilers/Data/Generic.mo b/Buildings/Fluid/Boilers/Data/Generic.mo new file mode 100644 index 00000000000..fbcbc1d59e0 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Generic.mo @@ -0,0 +1,57 @@ +within Buildings.Fluid.Boilers.Data; +record Generic "Generic data record for boiler performance" + extends Modelica.Icons.Record; + + parameter Real effCur[:,:]= + [0, 1; 1, 1] + "Efficiency curves as a table: First row = inlet temp(K), First column = firing rates or PLR"; + final parameter Modelica.SIunits.Efficiency eta_nominal= + Buildings.Utilities.Math.Functions.smoothInterpolation( + x=TIn_nominal, + xSup=effCur[1,2:end], + ySup=effCur[end,2:end]) + "Efficiency at TIn_nominal"; + parameter Modelica.SIunits.Temperature TIn_nominal = 323.15 + "Nominal inlet temperature for efficiency calculations"; + + parameter Buildings.Fluid.Data.Fuels.Generic fue "Fuel type" + annotation (choicesAllMatching = true); + + parameter Modelica.SIunits.Power Q_flow_nominal "Nominal heating power"; + parameter Modelica.SIunits.ThermalConductance UA=0.05*Q_flow_nominal/30 + "Overall UA value"; + parameter Modelica.SIunits.Volume VWat = 1.5E-6*Q_flow_nominal + "Water volume of boiler"; + parameter Modelica.SIunits.Mass mDry = 1.5E-3*Q_flow_nominal + "Mass of boiler that will be lumped to water heat capacity"; + + parameter Modelica.SIunits.MassFlowRate m_flow_nominal + "Nominal mass flow rate"; + parameter Modelica.SIunits.PressureDifference dp_nominal = 3000 + "Pressure drop at m_flow_nominal"; + + annotation ( + defaultComponentName="per", + defaultComponentPrefixes = "parameter", + Documentation(info=" +

+This record is used as a template for performance data +for the boiler model + +Buildings.Fluid.Boilers.BoilerTable. +

+

+Note that if the parameter fue is for the upper (or lower) heating value of the fuel, +then the effiency curve must be specified for the upper (or lower) heating value. +

+", revisions=" + +")); +end Generic; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash2501.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash2501.mo new file mode 100644 index 00000000000..6010302f32a --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash2501.mo @@ -0,0 +1,23 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.Crest; +record FBdash2501 "Specifications for Lochinvar Crest FB-2501 boiler" + extends Buildings.Fluid.Boilers.Data.Generic( + effCur= + [0, 294.174111359682, 299.779381058911, 305.316293810589, 310.921563509818, 316.458476261496, 322.040960311542, 327.600658712403, 333.137571464081, 338.742841163311, 344.279753914988; + 0.05,0.991213389121339,0.983995815899581,0.973640167364016,0.958577405857740,0.940690376569037,0.919665271966527,0.898953974895397,0.886087866108786,0.881066945606694,0.879811715481171; + 0.5,0.988075313807531,0.981171548117155,0.968619246861924,0.952301255230125,0.931903765690376,0.907426778242677,0.890794979079498,0.882635983263598,0.878242677824267,0.876987447698744; + 1,0.969560669456067,0.962656903765690,0.951046025104602,0.935041841004184,0.917154811715481,0.896443514644351,0.884832635983263,0.878242677824267,0.874476987447698,0.873535564853556], + final fue = Buildings.Fluid.Data.Fuels.NaturalGasHigherHeatingValue(), + Q_flow_nominal = 703370.568, + VWat = 0.59430965, + mDry = 1168.907537, + m_flow_nominal = 15.141647, + dp_nominal = 25107.43); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FBdash2501; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3001.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3001.mo new file mode 100644 index 00000000000..9913fda6acd --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3001.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.Crest; +record FBdash3001 "Specifications for Lochinvar Crest FB-3001 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501( + Q_flow_nominal = 844923.8948, + VWat = 0.590524238, + mDry = 1306.799618, + m_flow_nominal = 18.169977, + dp_nominal = 23911.84); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FBdash3001; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3501.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3501.mo new file mode 100644 index 00000000000..5b6c05112ca --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash3501.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.Crest; +record FBdash3501 "Specifications for Lochinvar Crest FB-3501 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501( + Q_flow_nominal = 985891.0795, + VWat = 0.76465318, + mDry = 1459.660247, + m_flow_nominal = 21.198306, + dp_nominal = 29590.90); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FBdash3501; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash4001.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash4001.mo new file mode 100644 index 00000000000..faa42a3b95a --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash4001.mo @@ -0,0 +1,18 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.Crest; +record FBdash4001 "Specifications for Lochinvar Crest FB-4001 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501( + Q_flow_nominal = 1126272.122, + VWat = 0.760867769, + mDry = 1725.918968, + m_flow_nominal = 22.081569, + dp_nominal = 32579.88); + // Data of this model are based on 22F of dT instead of 20F. + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FBdash4001; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash5001.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash5001.mo new file mode 100644 index 00000000000..5cc0e78fdd0 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash5001.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.Crest; +record FBdash5001 "Specifications for Lochinvar Crest FB-5001 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501( + Q_flow_nominal = 1407913.42, + VWat = 0.961494593, + mDry = 1860.182309, + m_flow_nominal = 30.283294, + dp_nominal = 41546.82); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FBdash5001; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash6001.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash6001.mo new file mode 100644 index 00000000000..0734b9397d3 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/FBdash6001.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.Crest; +record FBdash6001 "Specifications for Lochinvar Crest FB-6001 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501( + Q_flow_nominal = 1689847.79, + VWat = 1.150765182, + mDry = 2136.873655, + m_flow_nominal = 36.339953, + dp_nominal = 51410.46); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FBdash6001; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.mo new file mode 100644 index 00000000000..149fc4fb204 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.mo @@ -0,0 +1,15 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar; +package Crest "Package with performance data for Lochinvar Crest boilers" + extends Modelica.Icons.Package; + + annotation ( + defaultComponentPrefixes = "parameter", + Documentation(info=" +

+This package contains performance data for Lochinvar Crest boilers. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end Crest; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.order b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.order new file mode 100644 index 00000000000..1f63e372442 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/Crest/package.order @@ -0,0 +1,6 @@ +FBdash2501 +FBdash3001 +FBdash3501 +FBdash4001 +FBdash5001 +FBdash6001 diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX400.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX400.mo new file mode 100644 index 00000000000..a1a6c5ba3fd --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX400.mo @@ -0,0 +1,23 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.FTXL; +record FTX400 "Specifications for Lochinvar FTXL FTX400 boiler" + extends Buildings.Fluid.Boilers.Data.Generic( + effCur= + [0, 294.264548954895, 299.823542354235, 305.382535753575, 310.941529152915, 316.500522552255, 322.059515951595, 327.580693069307, 333.177502750275, 338.698679867987, 344.257673267327; + 0.1,0.993531468531468,0.986538461538461,0.977797202797202,0.963286713286713,0.944755244755244,0.920629370629370,0.897902097902098,0.882167832167832,0.876223776223776,0.874825174825174; + 0.5,0.986888111888112,0.979895104895105,0.971153846153846,0.957517482517482,0.938986013986014,0.914335664335664,0.894755244755244,0.880419580419580,0.875000000000000,0.873776223776223; + 1,0.981993006993007,0.975000000000000,0.966258741258741,0.951748251748251,0.931643356643356,0.908916083916083,0.892132867132867,0.879370629370629,0.873776223776223,0.872552447552447], + final fue = Buildings.Fluid.Data.Fuels.NaturalGasHigherHeatingValue(), + Q_flow_nominal=114883.8594, + VWat=0.049210353, + mDry=216.8171529, + m_flow_nominal=2.460518, + dp_nominal=10461.43); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FTX400; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX500.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX500.mo new file mode 100644 index 00000000000..20fad69c94a --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX500.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.FTXL; +record FTX500 "Specifications for Lochinvar FTXL FTX500 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX400( + Q_flow_nominal=143311.7532, + VWat=0.045424941, + mDry=228.6105545, + m_flow_nominal=3.091420, + dp_nominal=3.091420); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FTX500; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX600.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX600.mo new file mode 100644 index 00000000000..f785dc50391 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX600.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.FTXL; +record FTX600 "Specifications for Lochinvar FTXL FTX600 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX400( + Q_flow_nominal=171446.576, + VWat=0.045424941, + mDry=228.6105545, + m_flow_nominal=3.722322, + dp_nominal=13151.51); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FTX600; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX725.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX725.mo new file mode 100644 index 00000000000..3749a06b703 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX725.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.FTXL; +record FTX725 "Specifications for Lochinvar FTXL FTX725 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX400( + Q_flow_nominal=206615.1044, + VWat=0.064352, + mDry=260.8156128, + m_flow_nominal=4.479404, + dp_nominal=14646.00); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FTX725; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX850.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX850.mo new file mode 100644 index 00000000000..f37a5d2ab6d --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/FTX850.mo @@ -0,0 +1,17 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.FTXL; +record FTX850 "Specifications for Lochinvar FTXL FTX850 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX400( + Q_flow_nominal=241637.0972, + VWat=0.060566589, + mDry=273.9697915, + m_flow_nominal=5.236486, + dp_nominal=17037.19); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FTX850; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.mo new file mode 100644 index 00000000000..e6c48a0d494 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.mo @@ -0,0 +1,15 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar; +package FTXL "Package with performance data for Lochinvar FTXL™ Fire Tube boilers" + extends Modelica.Icons.Package; + + annotation ( + preferredView="info", + Documentation(info=" +

+This package contains performance data for Lochinvar FTXL™ Fire Tube boilers. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end FTXL; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.order b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.order new file mode 100644 index 00000000000..b6b6209ae31 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/FTXL/package.order @@ -0,0 +1,5 @@ +FTX400 +FTX500 +FTX600 +FTX725 +FTX850 diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0400.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0400.mo new file mode 100644 index 00000000000..324f520dae7 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0400.mo @@ -0,0 +1,22 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL; +record KBXdash0400 "Specifications for Lochinvar Knight XL KBX-0400 boiler" + extends Buildings.Fluid.Boilers.Data.Generic( + effCur= + [0, 294.226732673267, 299.785726072607, 305.344719471947, 310.891107444078, 316.424889988999, 322.009094242757, 327.542876787678, 333.101870187018, 338.660863586358, 344.219856985698; + 0.1,0.988111888111888,0.981118881118881,0.972377622377622,0.958041958041957,0.939510489510489,0.915209790209790,0.892657342657342,0.876573426573426,0.870804195804195,0.869230769230769; + 0.5,0.982167832167832,0.975174825174825,0.966433566433566,0.952622377622377,0.934090909090909,0.909615384615384,0.889860139860139,0.875699300699300,0.870279720279720,0.868881118881118; + 1,0.977097902097902,0.970279720279720,0.961363636363636,0.946853146853146,0.926923076923076,0.904195804195804,0.887237762237762,0.874650349650349,0.869055944055944,0.867832167832167], + final fue = Buildings.Fluid.Data.Fuels.NaturalGasHigherHeatingValue(), + Q_flow_nominal = 113427.2962, + VWat = 0.016655812, + m_flow_nominal= 2.397427, + dp_nominal = 29889.80); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end KBXdash0400; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0500.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0500.mo new file mode 100644 index 00000000000..9bc4017bfa6 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0500.mo @@ -0,0 +1,16 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL; +record KBXdash0500 "Specifications for Lochinvar Knight XL KBX-0500 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0400( + Q_flow_nominal = 142139.469, + VWat = 0.018548518, + m_flow_nominal = 3.028329, + dp_nominal = 41845.72); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end KBXdash0500; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0650.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0650.mo new file mode 100644 index 00000000000..4fe7fcdc0ef --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0650.mo @@ -0,0 +1,16 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL; +record KBXdash0650 "Specifications for Lochinvar Knight XL KBX-0650 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0400( + Q_flow_nominal = 184781.3096, + VWat = 0.023469553, + m_flow_nominal = 3.911592, + dp_nominal = 47823.68); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end KBXdash0650; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0800.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0800.mo new file mode 100644 index 00000000000..627fc0078a0 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash0800.mo @@ -0,0 +1,16 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL; +record KBXdash0800 "Specifications for Lochinvar Knight XL KBX-0800 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0400( + Q_flow_nominal = 227423.1503, + VWat = 0.027633506, + m_flow_nominal = 4.794855, + dp_nominal = 50812.66); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end KBXdash0800; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash1000.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash1000.mo new file mode 100644 index 00000000000..81380e025ff --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/KBXdash1000.mo @@ -0,0 +1,16 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL; +record KBXdash1000 "Specifications for Lochinvar Knight XL KBX-1000 boiler" + extends Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0400( + Q_flow_nominal = 283994.659, + VWat = 0.033311624, + m_flow_nominal = 6.056659, + dp_nominal = 53801.64); + annotation (Documentation(info=" +

+Performance data for boiler model. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end KBXdash1000; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.mo new file mode 100644 index 00000000000..ed1e34ca7af --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.mo @@ -0,0 +1,15 @@ +within Buildings.Fluid.Boilers.Data.Lochinvar; +package KnightXL "Package with performance data for Lochinvar Knight™ XL boilers" + extends Modelica.Icons.Package; + + annotation ( + preferredView="info", + Documentation(info=" +

+This package contains performance data for Lochinvar Knight™ XL boilers. +See the documentation of + +Buildings.Fluid.Boilers.Data.Lochinvar. +

+")); +end KnightXL; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.order b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.order new file mode 100644 index 00000000000..bb47e7ab579 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/KnightXL/package.order @@ -0,0 +1,5 @@ +KBXdash0400 +KBXdash0500 +KBXdash0650 +KBXdash0800 +KBXdash1000 diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/package.mo b/Buildings/Fluid/Boilers/Data/Lochinvar/package.mo new file mode 100644 index 00000000000..4d1a44d4947 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/package.mo @@ -0,0 +1,164 @@ +within Buildings.Fluid.Boilers.Data; +package Lochinvar "Package containing data for Lochinvar boilers" + extends Modelica.Icons.Package; + + annotation (preferredView="info", Documentation(info=" +

+This package contains performance data for Lochinvar boilers. +See sources of the data in the table below. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Crest Boilers +
Main webpage + + + https://www.lochinvar.com/products/commercial-boilers/crest-condensing-boiler/ +
Efficiency curves + + + https://www.lochinvar.com/lit/595403Crest_Efficiency_Curve.pdf +
Other specifications + + + https://www.lochinvar.com/lit/961107FBN-PS-17%20(2501-6001).pdf +
FTXL™ Fire Tube Boilers +
Main webpage + + + https://www.lochinvar.com/products/commercial-boilers/ftxl-fire-tube-boiler/ +
Efficiency curves + + + https://www.lochinvar.com/lit/FTXL%20Efficiency%20Curve.pdf +
Other specifications + + + https://www.lochinvar.com/lit/FTX-PS-02.pdf +
Knight™ XL Boilers +
Main webpage + + + https://www.lochinvar.com/products/commercial-boilers/knight-xl/ +
Efficiency curves + + + https://www.lochinvar.com/lit/643565KNIGHT%20XL%20Curve.pdf +
Other specifications + + + https://www.lochinvar.com/lit/277063KBX-PS-01_2021.pdf +
+

+Boilers with the same brand name use the same set of efficiency curves +(e.g. all records in + +Buildings.Fluid.Boilers.Data.Lochinvar.Crest +have the same curves). +The original documents use the IP units and conversions are made +in this implementation. Values corresponding to temperature rise of +20°F (11.1°C) are used as nominal (except for + +Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash4001 +whose data are based on 22°F [12.2°C]). +The table below explains how the variables +in this implementation correspond to items on the files from the website. +

+ + + + + + + + + + +
+

+Variable in Modelica +

+
+

Item from the website +

+
+

+Q_flow_nominal +

+
+

+Gas - BTU/hr output (high fire) +

+
+

+VWat +

+
+

+Water - Gallon capacity +

+
+

+mDry +

+
+

+Dimensions - shipping weight +

+
+

+m_flow_nominal +

+
+

+Water flow rate at 20°F ΔT (11.1°C) +

+
+

+dp_nominal +

+
+

+Pressure drop +

+
+

+See the + +User's Guide for more information. +

+")); +end Lochinvar; diff --git a/Buildings/Fluid/Boilers/Data/Lochinvar/package.order b/Buildings/Fluid/Boilers/Data/Lochinvar/package.order new file mode 100644 index 00000000000..568591e80c0 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/Lochinvar/package.order @@ -0,0 +1,3 @@ +Crest +FTXL +KnightXL diff --git a/Buildings/Fluid/Boilers/Data/package.mo b/Buildings/Fluid/Boilers/Data/package.mo new file mode 100644 index 00000000000..824f24eb184 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/package.mo @@ -0,0 +1,11 @@ +within Buildings.Fluid.Boilers; +package Data "Package containing performance data for boilers" +extends Modelica.Icons.MaterialPropertiesPackage; + +annotation (preferredView="info", Documentation(info=" +

+This package contains performance data of boilers. +See documentation of each package for source and other information. +

+")); +end Data; diff --git a/Buildings/Fluid/Boilers/Data/package.order b/Buildings/Fluid/Boilers/Data/package.order new file mode 100644 index 00000000000..d584637a147 --- /dev/null +++ b/Buildings/Fluid/Boilers/Data/package.order @@ -0,0 +1,2 @@ +Generic +Lochinvar diff --git a/Buildings/Fluid/Boilers/Examples/BoilerTable.mo b/Buildings/Fluid/Boilers/Examples/BoilerTable.mo new file mode 100644 index 00000000000..18dfa29c911 --- /dev/null +++ b/Buildings/Fluid/Boilers/Examples/BoilerTable.mo @@ -0,0 +1,91 @@ +within Buildings.Fluid.Boilers.Examples; +model BoilerTable + "Boilers with efficiency described by table" + extends Modelica.Icons.Example; + package Medium = Buildings.Media.Water "Medium model"; + parameter Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501 per + "Record containing a table that describes the efficiency curves" + annotation (Placement(transformation(extent={{60,60},{80,80}}))); + + Buildings.Fluid.Boilers.BoilerTable boi1( + redeclare package Medium = Medium, + energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, + from_dp=true, + T_start=293.15, + per=per) "Boiler with transient computation" + annotation (Placement(transformation(extent={{10,36},{30,56}}))); + Buildings.Fluid.Boilers.BoilerTable boi2( + redeclare package Medium = Medium, + energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + massDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + from_dp=true, + T_start=293.15, + per=per) "Boiler with steady-state computation" + annotation (Placement(transformation(extent={{10,-44},{30,-24}}))); + + Buildings.Fluid.Sources.Boundary_pT sin( + redeclare package Medium = Medium, + p(displayUnit="Pa") = 300000, + T=sou.T, + nPorts=2) "Sink" + annotation (Placement(transformation(extent={{80,-10},{60,10}}))); + Buildings.Fluid.Sources.Boundary_pT sou( + redeclare package Medium = Medium, + p=300000 + per.dp_nominal, + use_T_in=true, + nPorts=2) "Source" + annotation (Placement(transformation(extent={{-60,-10},{-40,10}}))); + Buildings.HeatTransfer.Sources.FixedTemperature TAmb(T=288.15) + "Ambient temperature in boiler room" + annotation (Placement(transformation(extent={{-40,70},{-20,90}}))); + Modelica.Blocks.Sources.TimeTable y(table=[0,0; 1800,1; 1800,0; 2400,0; 2400,1; + 6000,1]) "Firing rate" + annotation (Placement(transformation(extent={{-90,44},{-70,64}}))); + Modelica.Blocks.Sources.TimeTable TIn(table=[0,303.15; 3000,303.15; 4200,293.15; + 4800,293.15; 5400,303.15; 6000,303.15]) + "Inlet temperature" + annotation (Placement(transformation(extent={{-90,-6},{-70,14}}))); + +equation + connect(TAmb.port,boi1. heatPort) annotation (Line(points={{-20,80},{20,80},{20, + 53.2}}, color={191,0,0})); + connect(y.y,boi1. y) annotation (Line(points={{-69,54},{8,54}}, + color={0,0,127})); + connect(TIn.y, sou.T_in) + annotation (Line(points={{-69,4},{-62,4}}, color={0,0,127})); + connect(y.y,boi2. y) annotation (Line(points={{-69,54},{-10,54},{-10,-26},{8,-26}}, + color={0,0,127})); + connect(TAmb.port,boi2. heatPort) annotation (Line(points={{-20,80},{0,80},{0, + 0},{20,0},{20,-26.8}}, color={191,0,0})); + connect(sou.ports[1],boi1. port_a) annotation (Line(points={{-40,2},{-20,2},{-20, + 46},{10,46}}, color={0,127,255})); + connect(sou.ports[2],boi2. port_a) annotation (Line(points={{-40,-2},{-20,-2}, + {-20,-34},{10,-34}},color={0,127,255})); + connect(boi1.port_b, sin.ports[1]) annotation (Line(points={{30,46},{54,46},{54, + 2},{60,2}}, color={0,127,255})); + connect(boi2.port_b, sin.ports[2]) annotation (Line(points={{30,-34},{54,-34}, + {54,-2},{60,-2}}, color={0,127,255})); + annotation (__Dymola_Commands(file="modelica://Buildings/Resources/Scripts/Dymola/Fluid/Boilers/Examples/BoilerTable.mos" + "Simulate and plot"), + experiment(Tolerance=1e-6, StopTime=6000), + Documentation(info=" +

+Similar to + +Buildings.Fluid.Boilers.Examples.BoilerPolynomial, +this example demonstrates the open loop response of the boiler model +with boi1 a dynamic model and +boi2 a steady-state model. +In addition to the control signal, +the inlet temperature is also varied. +

+", revisions=" + +")); +end BoilerTable; diff --git a/Buildings/Fluid/Boilers/Examples/package.mo b/Buildings/Fluid/Boilers/Examples/package.mo index df7cb101c3b..c3f9661cb00 100644 --- a/Buildings/Fluid/Boilers/Examples/package.mo +++ b/Buildings/Fluid/Boilers/Examples/package.mo @@ -1,6 +1,7 @@ within Buildings.Fluid.Boilers; package Examples "Collection of models that illustrate model use and test models" extends Modelica.Icons.ExamplesPackage; + annotation (preferredView="info", Documentation(info="

This package contains examples for the use of models that can be found in diff --git a/Buildings/Fluid/Boilers/Examples/package.order b/Buildings/Fluid/Boilers/Examples/package.order index 4aa6d20e16a..07826088479 100644 --- a/Buildings/Fluid/Boilers/Examples/package.order +++ b/Buildings/Fluid/Boilers/Examples/package.order @@ -1,2 +1,3 @@ BoilerPolynomial BoilerPolynomialClosedLoop +BoilerTable diff --git a/Buildings/Fluid/Boilers/UsersGuide.mo b/Buildings/Fluid/Boilers/UsersGuide.mo new file mode 100644 index 00000000000..31d132bf9e9 --- /dev/null +++ b/Buildings/Fluid/Boilers/UsersGuide.mo @@ -0,0 +1,109 @@ +within Buildings.Fluid.Boilers; +package UsersGuide "User's Guide" + extends Modelica.Icons.Information; + +annotation (preferredView="info", + Documentation(info=" +

+This package contains models for boilers. +The main equations are computed in the base class + +Buildings.Fluid.Boilers.BaseClasses.PartialBoiler +and the efficiency is described in the extended models +using different methods. +

+

+The heat of combustion released by the fuel is computed as +

+

+f = y ⋅ Q̇0 ⁄ η0 +

+

+where y ∈ [0, 1] is the control signal or firing rate, +0 is the nominal heating power +and η0 is the nominal efficiency. +The nominal values correspond to the operating condition at y = 1 and, +when applicable, at the nominal temperature T = T0 +or Tinlet = Tinlet,0, +depending on the choice of model. +

+

+The heat transferred to the working fluid (typically water or air) is +

+

+Q̇ = η ⋅ Q̇f - Q̇amb +

+

+where η is the efficiency at the current operating point +and amb > 0 is the heat loss from the boiler +to the ambient. +

+amb is considered only when the port heatPort +is connected to a heat port outside of this model +to impose a boundary condition in order to model heat losses to the ambient. +When using this heatPort, +make sure that the efficiency does not already account for this heat loss. +Also note that in + +Buildings.Fluid.Boilers.BaseClasses.PartialBoiler, +the equation +QWat_flow = eta * QFue_flow + UAOve.Q_flow +uses a summation instead of a subtraction because the direction +of UAOve.Q_flow is from the ambient to the boiler. +

+

+The fuel is specified in +Buildings.Fluid.Data.Fuels +via +

+

+f = Q̇f ⁄ hf
+f = ṁf ⁄ ρf +

+

+where is the mass flow rate of the fuel, +hf is the heating value of the fuel, +f is the volumetric flow rate of the fuel, +and ρf is the density of the fuel. +Care must be taken to choose the higher or lower heating value correctly +that corresponds to the efficiency η. +(E.g., the efficiency of a condensing boiler may be computed on the +higher heating value to avoid efficiencies higher than 1, +whereas a non-condesing boiler's efficiency is typically on the lower heating value.) +

+

+There are two ways to specify the efficiency η. +

+ +

+Specifying the performance using a table as implemtend in + +Buildings.Fluid.Boilers.BoilerTable +is generally easier for representing condensing boilers because the change in +efficiency near the condensation point can be described conveniently. +

+

+On the Assumptions tag, the model can be parameterized to compute a transient +or steady-state response. The transient response of the boiler is computed +using a first order differential equation to compute the boiler's water +and metal temperature, which are lumped into one state. +The boiler outlet temperature is equal to this water temperature. +

+")); +end UsersGuide; diff --git a/Buildings/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.mo b/Buildings/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.mo new file mode 100644 index 00000000000..44928cd9fa8 --- /dev/null +++ b/Buildings/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.mo @@ -0,0 +1,137 @@ +within Buildings.Fluid.Boilers.Validation; +model BoilerTableEfficiencyCurves + "Boilers with efficiency curves specified by look-up table" + extends Modelica.Icons.Example; + package Medium = Buildings.Media.Water "Medium model"; + parameter Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501 per + "Record containing a table that describes the efficiency curves" + annotation (Placement(transformation(extent={{70,60},{90,80}}))); + + Buildings.Fluid.Sources.Boundary_pT sin( + redeclare package Medium = Medium, + nPorts=3, + p(displayUnit="Pa") = 300000, + T=sou.T) "Sink" + annotation (Placement(transformation(extent={{82,-30},{62,-10}}))); + Buildings.Fluid.Sources.Boundary_pT sou( + redeclare package Medium = Medium, + p=300000 + per.dp_nominal, + use_T_in=true, + nPorts=3) "Source" + annotation (Placement(transformation(extent={{-32,-30},{-12,-10}}))); + Buildings.Fluid.Boilers.BoilerTable boi1( + redeclare package Medium = Medium, + energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + massDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + from_dp=true, + T_start=293.15, + per=per) "Boiler 1 set at 5% firing rate" + annotation (Placement(transformation(extent={{20,44},{40,64}}))); + Buildings.HeatTransfer.Sources.FixedTemperature + TAmb1(T=288.15) "Ambient temperature in boiler room" + annotation (Placement(transformation(extent={{0,72},{20,92}}))); + Buildings.Fluid.Boilers.BoilerTable boi2( + redeclare package Medium = Medium, + energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + massDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + from_dp=true, + T_start=293.15, + per=per) "Boiler 2 set at 50% firing rate" + annotation (Placement(transformation(extent={{20,-16},{40,4}}))); + Buildings.HeatTransfer.Sources.FixedTemperature + TAmb2(T=288.15) "Ambient temperature in boiler room" + annotation (Placement(transformation(extent={{0,12},{20,32}}))); + Buildings.Fluid.Boilers.BoilerTable boi3( + redeclare package Medium = Medium, + energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + massDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, + from_dp=true, + T_start=293.15, + per=per) "Boiler 3 set at 100% firing rate" + annotation (Placement(transformation(extent={{20,-76},{40,-56}}))); + HeatTransfer.Sources.FixedTemperature TAmb3(T=288.15) + "Ambient temperature in boiler room" + annotation (Placement(transformation(extent={{0,-48},{20,-28}}))); + + Modelica.Blocks.Sources.Constant y1(k=0.05) + "Setting the firing rate at constant 5%" + annotation (Placement(transformation(extent={{-90,52},{-70,72}}))); + Modelica.Blocks.Sources.Constant y2(k=0.5) + "Setting the firing rate at constant 50%" + annotation (Placement(transformation(extent={{-90,-8},{-70,12}}))); + Modelica.Blocks.Sources.Constant y3(k=1) + "Setting the firing rate at constant 100%" + annotation (Placement(transformation(extent={{-90,-68},{-70,-48}}))); + Modelica.Blocks.Sources.Ramp TIn( + height=per.effCur[1,end]-per.effCur[1,2], + duration=3600, + offset=per.effCur[1,2], + y(final unit="K", + displayUnit="degC")) + "Ramps the T_inlet from the first to the last temperature provided by the efficiency curve table" + annotation (Placement(transformation(extent={{-62,-26},{-42,-6}}))); + +equation + connect(TAmb1.port, boi1.heatPort) annotation (Line( + points={{20,82},{30,82},{30,61.2}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(TAmb2.port, boi2.heatPort) annotation (Line( + points={{20,22},{30,22},{30,1.2}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(boi2.port_b, sin.ports[2]) annotation (Line( + points={{40,-6},{52,-6},{52,-20},{62,-20}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(boi1.port_b, sin.ports[1]) annotation (Line( + points={{40,54},{52,54},{52,-21.3333},{62,-21.3333}}, + color={0,127,255}, + smooth=Smooth.None)); + connect(TAmb3.port, boi3.heatPort) + annotation (Line(points={{20,-38},{30,-38},{30,-58.8}}, color={191,0,0})); + connect(boi3.port_b, sin.ports[3]) annotation (Line(points={{40,-66},{52,-66}, + {52,-18.6667},{62,-18.6667}}, color={0,127,255})); + connect(boi1.port_a, sou.ports[1]) annotation (Line(points={{20,54},{-6,54},{ + -6,-21.3333},{-12,-21.3333}}, + color={0,127,255})); + connect(boi3.port_a, sou.ports[2]) annotation (Line(points={{20,-66},{-6,-66}, + {-6,-20},{-12,-20}}, color={0,127,255})); + connect(boi2.port_a, sou.ports[3]) annotation (Line(points={{20,-6},{-6,-6},{ + -6,-18.6667},{-12,-18.6667}}, + color={0,127,255})); + connect(y1.y, boi1.y) annotation (Line(points={{-69,62},{18,62}}, + color={0,0,127})); + connect(y2.y, boi2.y) annotation (Line(points={{-69,2},{18,2}}, + color={0,0,127})); + connect(y3.y, boi3.y) annotation (Line(points={{-69,-58},{18,-58}}, + color={0,0,127})); + connect(TIn.y, sou.T_in) + annotation (Line(points={{-41,-16},{-34,-16}}, color={0,0,127})); + annotation (__Dymola_Commands(file="modelica://Buildings/Resources/Scripts/Dymola/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.mos" + "Simulate and plot"), + experiment(Tolerance=1e-6, StopTime=3600), + Documentation(info=" +

+This model computes the efficiency of boilers for using the model + +Buildings.Fluid.Boilers.BoilerTable +at firing rates of 5%, 50%, and 100%. +

+

+The models are configured to compute the following efficiency curves. +

+

+\"Image +

+", revisions=" + +")); +end BoilerTableEfficiencyCurves; diff --git a/Buildings/Fluid/Boilers/Validation/package.mo b/Buildings/Fluid/Boilers/Validation/package.mo new file mode 100644 index 00000000000..2c629622d93 --- /dev/null +++ b/Buildings/Fluid/Boilers/Validation/package.mo @@ -0,0 +1,12 @@ +within Buildings.Fluid.Boilers; +package Validation "Collection of validation models" + extends Modelica.Icons.ExamplesPackage; + +annotation (preferredView="info", Documentation(info=" +

+This package contains validation models for the models that can be found in + +Buildings.Fluid.Boilers. +

+")); +end Validation; diff --git a/Buildings/Fluid/Boilers/Validation/package.order b/Buildings/Fluid/Boilers/Validation/package.order new file mode 100644 index 00000000000..b8768a6b606 --- /dev/null +++ b/Buildings/Fluid/Boilers/Validation/package.order @@ -0,0 +1 @@ +BoilerTableEfficiencyCurves diff --git a/Buildings/Fluid/Boilers/package.order b/Buildings/Fluid/Boilers/package.order index 7297dd0e31e..2d17d81c23f 100644 --- a/Buildings/Fluid/Boilers/package.order +++ b/Buildings/Fluid/Boilers/package.order @@ -1,2 +1,7 @@ +UsersGuide BoilerPolynomial +BoilerTable +Data Examples +Validation +BaseClasses diff --git a/Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.png b/Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.png new file mode 100644 index 0000000000000000000000000000000000000000..2b5d543eec6f7a9290186b4698e454b993732de5 GIT binary patch literal 1997 zcmV;;2Qv7HP)`88>Owg6(u5A6okMkR7IHTiumk`SZPI!iWCtgQWbo_PJMt6 z&?rzzVFNe|3?{}k>tNt%C|Y|M{t)RcOvilrKs>Z+3G$Y!A> zTl1p7OSL?FM>(h~*94wd>a`jjb8$!2w3dRrtXT74SSx`{-TEu2sz~KNrP`9)F&Ud6 zmO7AWFTt-@aEU7H^Kna%pY`~(Qdhs0jwp8*?VIlRgvz^*8@ zekoZ6wbLaA*}7~27pi7gEPHdfB~EGiRtaQ39w46zDkxn3ktca=-F2yCRU}QL@G)QIyJ3|YiCGNMGIJWMa|XGM0Boj7^0TBvc*{tr^LAwG?qC39sv*<8@|)yT zMTc`m&&Hh@>d*c{TV1-ENIdryK`qFCgrI3(QNKq zlBKmV0ldlF-akOXhN4gbO}0>Ib4!pbIG$-72DzPXPv_*<-s_0_?qEc1fxbJGvt?5d%$koDuQoUbI6v#S7T~s z<{;Lg)CAT711BgRYwIa|joa|K-2$I~GTYYKeTGlVUqYx<1xmOBGVdv8k6Vh3n}J}W>MpoP!|Z7^*q~S% zLqH7EZpYI_^+$bod<{4oxGXMFfTf%$xg`p;?H7^v+eTDb9|d5tEu>h}@Bq-5c01hk z1otu4yMZqilTEffBpDyCe^JB0rt$L`*zZXcSIsC8*oOZoH14MI_W`|H3*)Z>{bdEe zd5GjJ4n-IsY=`aBATn8s9lYd^;zW+6ve&xxn|G3Cc$rP*GtKwTz{!l)+rgt^9+`1R zL-SAUa|5uYkvL4y2X!46h{lBN$Rjt!T=FBhxD#BME;8dKTzaqVlal$|DwtCSIX%Si zF>2bei%G|)5UZ+Z`GcSfbT~j%COb5=YiP(}+=k&Rc{}=k+}I3!S#dR;2*4g}09^y= zB6!0o$kdQ^XxKe{cK7KYTvzJvT)WG!=th7g!3PA8sR(XFJ3ez7!RwA!XXwi zR#yTyPcSpLWr0uEKoWB~Qa(~maOcjE!^xw4yvG7wp}&l;hq89ic8T>K9gyN~A*~N$ zp1W+(eG8CZEJA~J&}D*NA_yE4aQIA77D+xt3JVJug)z}2Sd53nAC+p<;lkS8pm&y- zIGR_iXKm*VdW3h2(2p_RbgtEhJ;5#*w1ZkjhbMvbvVBtMO{FdAq*k#F!+E?;Gs`1$ zj6IH72F`uIj@%@5NL)J(BX`m77sLLYja6{B2&)oIE8Sd&NxpH0`_-Bw4ZL;4BhXy7 zm^vs)b{ywn&mbO$y^MMFyGf3-z^(GS>!|lw4*nJu31R04lRXuB(A`3loZHt}1Up#q z!FUL-5Y%E4fPN=|I10Gf0-n(Q&A$cq6{;rK-9nSJzYgcUQB4ctd5O0}P{RII?W_GO zJu5O>p?5IdvoI~N7qovz%oB&h8NkPGd+*vC@7yCa z?Ib1MnnY-Ls=AtCChZvq>L@te!KB@I9;Hx8s_e!jLc`M|Er!`s01ZM`>|NOjhRvU> zN~&r}5~1O_LsgDli^5(DsX8~3C#)9V6@Y)0j>%+>#DMXTebD8^T_+B%c?@?8rzhim zdxn4-wH)*Qe>L`h&bi8NJwe*jvECx=|ITxiJM{RMb*RTkzBcCy2DA)zOM`k2 fZ0tb|{6p|RcCXs)(kof(00000NkvXXu0mjf>1e7; literal 0 HcmV?d00001 diff --git a/Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.svg b/Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.svg new file mode 100644 index 00000000000..14a6fcdbff3 --- /dev/null +++ b/Buildings/Resources/Images/BoundaryConditions/GroundTemperature/UndisturbedSoilTemperature.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.png b/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Cooling/HighMassSupplyTemperature_TRoomRelHum.png new file mode 100644 index 0000000000000000000000000000000000000000..8e7a28d72bd1c5148009e7990f2b588b2efbe56f GIT binary patch literal 29648 zcmeFYcTkhj`zH#7rqqCl(mN=o##ByIiC}E&q$ZkP{ zgzNzLxl2t6lvK}u5eI&e``>}yrw0CoQ#;23-T;`74#McHIc`=IFccO~>0Now>1;Z+V_2zstpa zlX&2Xi(`fG^7 zqZmf@lLerooz>qktf19Wgaug>x&3YO^DvTD(1fw|rW~6JX)Wak*A2=8!^K1rRIai{nY)F%`L#OmI# zHKZnBy!1hId-SJhmDuzUppgQA{c!j55% zAqx_Vg_z;jO-bE%QG=a+VpOUmv(&Z^>OBKJo9{&oTJR*o_!pHT5lzi9e&ICW6Vn~fpS2HrYxDUFK=eqS(ljCwQRv9=@UqR;Z7LSGFeTvFHCXj?7g z_=A4(eHCOeyt{p3WTPN6AXiQL0*`+k&~z7vxtVozFS}VBYsjbMv0{%FB%94bmBlTH zXb_H2j|FE2ls!7QgW18T<%w2?V1RYqdQx8 zRLM^#)^CC%LHbb#Gh#vsSGfY8wMr0p&CGLz1D2rjJ!VxX}do%P&?|bb!kB%J| z^cD*X-088W`#6j4&&c(y1IV|9_NS{V63~(2#~Bp}?NlDQ(XdkXtW&C}0UF%=ZBfy4 z0h3WgvtkYHR@=8WF`HR(b?bUG!4UVMP<6(3ISAISVW!@>x`$%>j7DhNlF-S7-+#Xx z>-Z&8`;~cV2Q-zJ1*6lJJN~iOIy1usMm5c$n_l6=w0z%XP#+hmPyX}Ag zA6efNgd~l7y?CuujzAH!Zsi!F2v%jSF{t`mY$;*p(%N_~!?(86Nhk@3xGx>)VZHh^ zes(|n9@4lcl#UNKFR;;t(_tQSFg(#77#%&=tV}v^ON~@;y0p;{UjkCG?YLQvjv0?} z{C#|oA^YSWAvgJetuv?vI(un-tbZ(D^QA+0qF}iXV-P4il|kdITMmB-CF92R^c0$>tM0`k>v{qTN$rQH8jy0=G8&^p$@H& z@FA%|rnV60nfEvn@mAlKSdmK`kfv>i2mQ#GO5NMjCh32?m{{e0-Hc<4*C_E~abZ=S zFoRbk4KPKQe5;)EB9MBiwk#O+ryEx57cz^o68`hlGuMh$Rb~Ww5e28YKC~PtE(wt>~m^Vyq)13VnV!<%O2OTND;<4dFfqxef zL1uaT&G-}L8dPb{PIV^U@)fSHe)m_z-=ylUw$Vi2smQ&e5UjbmL*xwg_GDWjCxaPh zu4~cIea1q5}kQkh&UeT zM%WL73x;U;=%xz_3@Q5>N4@qw^x99ORSVcemST=YHEV6Mc=OXMXG7!HJyg0vXY)ea z9-X>RtL4YP?k6i$AQ(cdhL#}QuNjz^WgJQyIv9%9xlLTeR?lCds$%1lf|!Don|LM0 z70LplXA=%Jb89iotV_D3uoL=vm*vNVf`Fs#n}xDik1vy@6^~R3&&4n>2;wp{`P5#z zoI9a9yy&KqebJ*+=gESBHoDO>5U2MheqTMifB$(5JZ;K7bvu*R%0?M>bm5hLJwdQ@ zO)kSAhjJd+Iv}vNDxOItZO2Y_(GL<_tV$Pra3;+mTtv zXKI;BJ{e?@H>@IL3sX0h9+4xoAv%Qb%)gqH!!&m7R1wGCg!~rfz4Sm)X!4k37xS1~ z^T|X_CUQ=xNzGox!ocV6irxI5ruyl__HwTEViERe=ZV)RRl^%RHsP6LmTFn^D(xT> zA&(>T``jK1Y$j!^K62?`E#r>(YZcTlGa#uw>P2}KJ0fT2exE#B#Hzw5mP<@+8ex6G z=P~6M=*(*hvQ@RU8~5pb1^q1kI2RrgJQpQ6I)grLJ##aAnNH_*XDn+-kn2t}cTKB2 z-J{^~3`VWc@!^C{^s#*>`Y$dnu|Dw`KeRGtm;At@^aym#J_ku=lK4wh1tfVh3(v-< z6p}gEO|Oyk^UH@jCsJ815pU;{3RP{+FrBx)WbF-pbMn&-^~tE=>WP7g+vyCaM@XZv zgMW@p)b^_cpl}ye%?rs`&kLc>?Q_mJBLo%WQeB4HZa}^2+v$BaK406oa!q__HbJ^_ zvo}5+%+Sduz@>u|UyQ2~WemD;D8!|c#+|+^$7hMq&5dU*T~_4bda=(9`+QWk9i)|h zOCvTod7BrahQ;Z8OmKl@Q9|yWg8AHSqFeNobAGBj=pFdx75Pc~sXIW(yJh1{lP5;M zlq(f|_iE3(w!607S+3lMm#LnGkKBlwo6?-w<^DcRh4Jn#ec}QYyPhA#m zJTrge0>zg3{At%~y-*JUf~I9{kQIOKW1YSB-)^}T!G)wtz4H=oSzk3ji2u~kduOI!xd zNqtRI0?*dlP9Ro#Q}xEC>bCX@Miy$s*=8tyzqAriqoqZWR7@!8(ax4^5+tj3tTNW^_hVfM0)t+4E#4*efS zDX&Z-^7DDr5uTpst5?U_`;-o}5q;aWm9w;qs`du9li|;Q7Hd#&WUn9*<5CqN#-z1< z7ab(Wh;K5;l7MaroKGY7K?Qxp=q9CJvYfRQ?0ZIB_b&oGbrW&-DXnTU^)GJ0uG<75 zlVq%Uuk0d*H~*XU@2Nc}NY~-%>l1=Ld2{54Ou`lL0_UAE!Ux0DvRumCshz0lWAM8G zjoh{V&sY7z@Z)3Yi!FOc#mn|t({<`#M|&e$bTI$-Io;d_Vf_`CdMC-9T4-uk__Lpd zAGDl1a9=liI&W1e`(zP#b&5j7{is|i9t96O0E(%9_ozc_EG#3T*1^SsZvn307cnj{ zIFkT**>O!uAr1#x{%(wa{gX>0NrWYob0_=ZZUFe(!@3CPQk^%z2eDDB&ttPzGIwbCdYXf^1-r zJ@>b~eGXWKK!R1e_=nKmn$j}LnpO>}qZaYGC(?eZx`}nOG7HBFxFnb3x1VI=RD1#d zK6AMbjwmk~Qh7b7AAOpZ6$&-oep6OzzacCe*Fp1Rr1Cmsb&4~#|3b0?35qp|-Qn9g zebWu^Z(hJ{NTR~xx$ zkVfVL9Wyh-CtAOBoE{WHU?uOa=2BKy0CXll9xSj20{y_$w0|Gjq0o!RG>ciF*3ya5 zk$oQ!X6HeX0CYo_@*w&2H_5JJZQmSq@d z2(-&cQbj1-5C_VQ|CJw+x&_qDUNFxw0>aGGY%h*D5Oze{E8a;iR<0|m2DEYC9}qeq z)d8SA@LS&Po+L2!?_ACH|G)Bo5W;;)*)wPM6`+EH+2DG$$qj|E%D>sVz+*sIL}J_$;C%6wUA!xVvo z*T9;u%)mv*px&c`*2He5Fs!kXuo_uz3P9B!5~ryrS5mnM7vaxX>?b$kB@2y`T~}?D zgjW8W58<#Hp`N*cQm=ZiQT@mcI&$TqVY|TZq1tGnUwTMxgQ_m|6v@v$>0V^Wyf)Xn z$wKjfN`DV=qS8=@pJA_Lo}QnC_ZVJ1cc7eA`%{x5V5r>ZBT$jw+v`p*^s>q}MdUN= z>Ix7uunR&r=!guKRZbt@LfO7dUwzY<_#fk}$gh7dUUdZ&`l>#)_(nfqyc@7fzT+b4 zK_dFl>~DbiR&?l?@%yYN2pB#D?Cie7)UR}YKVs$Lze=FH?&7`lWVs)J`I)u{n3_8g z+xijP`VbA1IPqs(wC;4j1BtC1lql_3A|EqM3%Lq7&R)~xQc_|YWZ<%V`n=wVoFh?i z7V?cHT2^;QK%7A& z&r!@MH8pR2#qHF2#N4R4o+&rrpNcD7-oEE_Eqj(Qa;Bi>6(evUO&r!boisia@DSMu zd&cW$I>a;u-Uo=XG+lFH*IuzO{&46*m0|L;1>L*i2v>k!GvkH{y0t=9)(DLP;hML_ z>clm>VIdn0zdZU{vqOMr9;Sq8kY&4+*HJPoS#F!SwoiZK1xH=U&Wr-J1S-(~N*-9< zLwkP_Fth>qEsl^wjBAy>KK%Y(To6W0971Cnv4MiC(|g^3Y5~GZJ{{H*R7hXYGff2K zRe|m&w^#Zm19VMwBF?YqqGfgUR%404^1rr*!dAhrno^57h$A7_8ymZrIG}fl4(+0N z?q0e!anv~CIEc2)LD0boN`iUvDzuU)Xj6^rUeE+VrQ{dH`pEuA`*{uys$hWqFVcXQ zKZu`;4iOx!HNZ?*R4@HXPXL#tegFgQl}l5RB0?Jh7AGoA7j|lvckXp z`HK~F+Ry(#*VK>XaFe|<c`0W}XWH=0c(ccOmq!vjIZ2YV$-0E;kd;=Xh+ zy@R?1c^T0oG65$K2Ah2ON3}SS>RNH3$7{Omz&ND#WYxbvT?IUG|3&}^IDnilv77Ar zzAgwIO$Hpr|F9kW*H-tx-7EfItn@aoW#@tN2ebLg)ydY8`SN4!7W(ZKfM_`a@R}6} zPO@C`{vN{_8YQx0WvqF@t&;(OE2L!ve}#h=L+%~&eFW7?8G?c8Dya|Y{6xbzkk;t} z7IRRQ1nL91kzh!7D6WFa$Oy^lCnR-`jjbn;YzFO-GZ`2_Ua;!?(2a^^R&i^&u)-tR z-}pZna`OG4Lt~A|QfGVxDi8G-6`k_CJUf%3dUjLi>6Ajdca%WFZw>rzQoCf!!m~W# zPz}JCPlxSMo{qe}em&{duXbQs}Dcfv5aErQH^lN zEx^@xk}b>tj`b*duJWo}dB#}MI26OsXtnbGTYa*Cp*(?ZmQIyZ>B_MpQ2h?O;(*mdOH|ocM0N9d4Jr1A{vMN z&LH{7lMtasF>8E|Ca(((-6m;EZz+Ob_Ptw1=z)$npGKl)q8vyhYb;l&AJLw*Mjz-* z&X=HGbMBnMAlP#Jt`c|>eMxnCsY!3dy@p2h&bf`kRrZm)-l-u>EuC*(0jyDYS2bG+ zxGgaD$;JLPl@^?`&h4q9MoqgTLRO|i4l#< zv-Gxlsf)HAfU3FY(&r}t&az`%T3v4V8fP@$%HpEpDxL4X_f*`M)E8dM&Ie8LG<4kF z$C)k?+BRcf$>dYey3()#!Hh1D3me9j{Zu!p?+;wRcnyWU3td+(6zDCmA9;$qUWl2D zDV`2l_*hTDd7)#f@g?e7QN*oWX7I+=&Xl96UbC)MQ7LB@Ny|gDO_;PnP_|42LQ!q0YiHbozhhWd}y9!NObPIE+ zIa>HU>IbT!tFApQnm^isES_d2{L1moU91d12W(`3EJ9aQNsZ;0&DSG4ko8>}R}JnO zo}^YtN@|`mXsv;^UFjD1*e1K_+N4M7j7rqFv=|wloGk0XjIzsNCmZy+C@d6C=BfH5w;p@T~PSX>vViY^W@&->Fhrg7)T^2>@Di& z)f;!7oI83NrWgC=P3;%VA&Azrk`#Tmd|SM$Os2#g{N{a-4pMelC0}}2<*h(~vs+80>yXM6yJP8lT%n8cDC)uiHu?IHIxb0;VHwK-|ETi?z#N{*JJ<#j&VLD_2CqtxP5 zs+*ZzQc}JFj`j4r#QKF$A-_kKSUEaiF=v!zhA~z((~mJTQvZu4al99f%$ zp`VDs$_4M{`H5wYOZ_YP0a$~9h81tS#A>F#ef|2FBx7HjFC{5X*5XIF;6x9%!oUEE1ssaC>!Ucdk`plH4F-m?qu(=P zDFZfAU%l4Tw=!42T7l_3iLe{nvZvcyqMu6gePYxw#{EGbgPRd+@D4>r zJewI2pOPLZ4R!C?%Jdc>I~$%(48Dv}U0_G4#6Hv%gjoaIcQM}ABos|OS@0-Jji&Fg z)dQ9g+MxSGW=h&l>E*VMp{kyT_`;P1ciJ^UL$m+PK=A>p!EGf&$m-7+9tP}KR&=#*SMpQH7L!|dwMiQk@%f*Z18 zWdaFZ>5wNv4cyXOJHJsw{-elO3_nu<7jrs-e`?Ma?A{#YSxQVqHxf@!{>qj+cNPvW zdB^{6+}Qu>*#56efaO26Njdg28H#g?<%}y4K4g-cBlso|7ukokkwc;H5b^^b{=x5YOOsvfv4Lvj z;Wxc-?vC4j%|_eAD7LsmI$q@K$t9D!zU)}d1x3^aO4ZTdF>)bRVkgLT`mo4ub_LRU zMd^i-9}Sz4|@@-dllV-~@7L9p>z|7H|7qhzC5qN}2PNSad{Ba`-Vqt`>Zu9gHg;$$4v>mHuMk+VaJq;4$J z$BX;ZQO6v$ch5wcXcql%<%)bgy;?_aveE#OqB;&*SOHH{`LQnED+FOqVMqoNR*)O$ zXgM8jWWB?;;3GI=ozP;or-aS>)~3jWj>dpw8@{>q{1+A=7KdctwX)4h{BxM><$Xyt zNr?){f6CkTQYnchPQ_ekzoOHgjIY@?29dBm~W_dR}e?{pfb#>1AYX1sE zq4ClzXv;cS9Q~)Gp#aat*Lo(#cO0sWwX@cQ?FNqvZY<`YvLHO_N!0t1+MCY`g8hb} z_aa5#@uD?q2pra{tFABUdA~4AKQ?4O*8aocIq`MZCo8>O*=uS0^MRs%Uw;A1FEqsY zXhILCp)DG#R$R9&RvyXJlJWBqMmKi`9_LBW`(QYubba#OPkgOm?&?xBK}-yt0MN3) zv`GK+HE@G`12*r}86=4*pAGGcB3(@U_PX{D>UGbz+UiJ5#EUW7HKnEM-pY?gvOiOw*Yn5^9%x0lYAz$Mlo~(1M|duWAv~yV zy=+os-?s3R>L3gNdL+xc&)u+U_#W^DJQi8-Xl@P$FFlFR5G!{uNPU;q^K9SvN~s0K zfn;%jo3qZt`5AY+bHJYl7+!r!ONQW=scr>-9X5`2gi(Td5V~VxZYv}zt4$5YKQ{j~ z_NOyHrH$l#czP2xIx@r#CKZNA*{&4stFul%PW7tTaL=VE{GoE0S^O-#GBJR+hCZ+L zzL;#f+a*=Kr!Va;wY(AWm`aI@47U0m^hahS;#=Ks)Vyaw>e3!GGfR8JBQlYS;1arRgRxPknSkm6neX~E7}+={2lINPBIoum zz0+v#`$eAf$qJiEKjqA_+$GqDESIc^P zAi4{llfz-|6vt(Zti%xCPS*4uqG#e=ZQeXaSmswBm~TOZ-nMpE1|01pmH3o0Om94!IEyY1fwUp!I{uMwvfW zb#@Bj0#6kd2Pr!#+=hD_m4BtfOWD&6`kYt2%O5w_i)5q4l33CMHS z09J=4IgU|~&WeYSY_fCoZeKkpbu%sG;g9|5&ZR)>WtJllK~KXX;UQshKY}4IfmMTR zPL;t$LJxCh-j7Z-M@G}!OkXe6jbdOze5HL!KbMtu;%WMEr$Ko#;(?X1!i9G)chjdE zH4ksc*JCE!hm6gi;am%^zyu4QZ+$A7O$3gUb?vpsRBP>|BPFml)>>vO4QFSgY-+_f zTfC*h$1TVrbmmX088-N_g7T5X=^0Y0?M!zPJNH#?+2H0|B@D?VB#Z5VY`jj+`S zahJQHOSC&z-!?z+&I4MjYSLr|B8*DwODPkIsb4!AtEIMu3&XW z@6iC9h>x^zK*>3b!JIZ4Mzrn6T!o%I>|{@_o7}mVs&*T8$s~xNv%mrg+#7|&>05E) zZZ$q@^Z_{-)*8LK-T&+~K6daGLG#U^KWz;ax7`r-N#b%GQ-W9>A*j#{8wOMJT&qkz z5aKI$h`AO}0)6vqPkfQ%3U~jQQELI$BCqaL%*1MJd<%cv?GEUhoDQdldApPcLq+mW zmtMtTzD1*2V>?(37w){I9By!jdpDDHgROQX!PoH(*Kd_0MJ~csckO~jYhL-!-LB#g zO`$ljU}Al>x-xxw%i3uygDz(pdJl2oB_G!c$y2v91d_qACc$UBV!@JOcG_o5In9iu zPo};wnBgIV2~iFsY{F_`EQr6>f;1aJ1qT9?=bLvbJ$hD2%Z5V>AL9?qdUchvVga%x zx?DQ7O`7tCQ!n0J85`o+>AW)Jf3;t|!I?9pRSVN>L>i>pu@ETp$<*)ry#XAlzrWX+LC!J|7j+3b>`AAH*iFWY#ARtZ zqX;_AD!MW`)QrsnGKE3RSr~m7-MXcVp|zI%ypCJZ2Qj{lR7IoBErU0L9c06PheNcS z@5}myIg)2zYxZ@ zJpD#9HeFa=WmZOpr0Luio@wx8+Ht>xu=+&(lIrWV>M%+_Dklk((njfBt31Oh|A67p zPPYICKlQ$99orZEymwlW@ksntl z$nqIf$<9AC8)l8?(^XU1lFg3Hl)jl!UFeej(0W~30SUMO2dj6%!S|RgJG#AY;A{)M zEcUS1hJ6FFVNN-uAF(mn#ka`Ek?vN#y`i8qA&kf9O! zR08B~7(<((urP@iZ26P6PzMtW0xvMl7if1_&>o_ z5g&ocC&Iavm?z7f=NU%YjMMtV?6Z%0zU^N`*OFL(lEBMkNuX5{Nzti6X_&pawQu0G z_u+I&-T7S_@SId5PIB_gDSi;Ge~YO zA%;}PYA=+|O3#smt8OFR;~VoZjGE_2k_nPNQ}#%D&nz3fJgNj`20=g90EOLeyhv@_ zE@Ot1MKFjNd41suW&o#}PmvtUm>}~x`!u4MV~5_mS2ZG2Mn1OX9p|POFHP}?Hw$9_ zj2)hh1X4wdMl+E5)6C4tcpc#zx6)`YXy-F*4#(uYmR>uB24oZRzwLXC?)xxCpR0^U z)Hl`U*aU(W^icz}7jHDWu$b@eUimXCu1mA&z=5Vt1caPX_iCxnUC|ax6m|iFgU!F9 z8Ersq8ZCq`*e)E-HYG}m5lCNBq7=cL)D08%pIsCMB(7#dd_%AMa$y~_1G($qJ<{~0 zCm3T54YG6jPrJX8mvKghee%)5G+wP>OY!C{uFp-XWVU+bACgL8k;0EFaDj$6Zy~ZD zLcRcW@m)=jq7?VFpPZ}O5Vsy7zuiVd=!}m6&X`9cYKLcIL~<}M1!Eea>nK?W5l~6j zD6%AhJxD_yga*!R~iY^w1xK<1Nm~=?6T)c>~E*$Y)?EZ;_-~1{M<)F&zA8>JsHdTUe8j%gQ;;aoR}h&%{qyw>DIP*TF(jUaCO4AE ziU`?RO#yBaIW0dGdX+Iwoff8yMl`#+(}f0ph>!MJF)IA)d=>n{V!MI456r4M74$b^ z@vKR{eKX4XK&@x6Z$fkhZJ3%n;Jn7k3b^S@X%vR5j8j9bOjdK-(VyZ_TfBu4p$v}n z!y&jBSbKwh(`TV~zav?G=dr{GEay#1w_`L@r&FhHw)@{@#gm;jUI-1fCDf&Own@;v9t$dg-)9aD0X*^#k*-@G#Afo&no*X zGSy8;AE|4pn|9lX)GkF9KAIBS)X*cxY^PT|amWcdV$y^wJl4ls+RJ_me1C4KqdepQ zO61$&Iwx&OKTZ@gz-btTD|YXxU9YWd3R-G=I}!gT>6+=A)T%3@$a6YKZc4O;aod!Z3ufbWi^|J4v|%#fArKFD^D_S z#kGmH55_wxo5TeMf1g6mPQ}a7 z0GP8ElFnuQ^*{?k8OXV4*~K*0obr1C@dF#h^)j)?A(diwo2xf%Zr8Ht5q|V$Y0}?^ zd~fYoClltW4iJKafAp_~@|qsD#d#mIF7jd4X)lcWU7qaRH7NZAiwq(jYo$aMdYW@b za)7s%HXY~oa?X=3q8-NUENEBu{yFWXIL@ORFJ-w4eZ^df|Lp{8DK$>aAz4HuSU zPPoPTCHsQ&Q&;l3e{Ie60v8nQ)_b$b0g`3%FI=a}g&U%g%j1$^p<637K|gnkQxfHPt2*u)Jab}~jp?I*Vb{*Rf<_+4DpGe>td&Ss@Ij}(fRd9VoD z_ShNuiFv2Xn_dQ+C*;DW_|&nvYx56p0XfJ`NuxfoN5>+1y5R0Cxc%mp6@qRyUbj-C z@2Jeh+iC6X+bS}R(u1g~Kn6r*J-CL-7@oF=s~6pcEMFJIDG#r|O=krMy|ULnVXP%N zE7`uHtNrELvBA!fe;oZNQfQ~REw$xmA0e+p)@!q<5y_4PFOpr@p=9IO&Z**7EpDHC zzGtr$vSkQk!=kiI%Lt->M@l(Il+$q?b?|VAgSR0SGF)JlduW<8_ z4S9+k0S25odziuWbySO%GyjQMp+Py6d@9o5>{wb0q4y>1;mi`<1}R>0qC?n!yAN#@ z%vEzc1dPoY>p)2FSA0Ghwin_rCvY!v*lIb$B6Tt*@2pT z9vb_{wgJ@by1^$y@*D zLB2NmOgxOD2r1aho1ZaW%a*)%o3HOe)Vg^k-niZ_ON8YoS@u?dB-pY&?vH#&MzPm} zgr)g7E0j&_$GM@wPqmrv91zqTK7F6OZtRLhrNpW5os1;Zj0RS6xywloAX^M)B=q{K zA7tiJ9JH2P;Pc+EdPI$n2K0IAsY-1fe)~A9Gn;l}eqc)C(-Q4;jxPC&DT;e3EelFt zd{tcp8EqIDqEDs${IIMqHTpfx7F*xiwWw;_+ImyBNz~xJep6N{UDx1vzs(rr((w~J zbgZx_8=*}#qf)Vnv%kMHU*3V)S8 za&2nwVne?@xAABLZ6uQNpz7Bb$M&Sd3l$)8RB&bD92D9ky(7vvHTzCSZas}9 z?(pD|yUsPXF}IbG4GtAHQEBP!dP-(lYnsLmZsrrt+;W`ERY@Lo%+d(vf#!uEEyG41 zS9qZ4yNlZT%YM@7Y8OXufv`80=4eq=G;4DLxHsvHF$sKco)-QVNB|6+>l)s~ace%3 zUM||&kMF*weC3fwuxh)`riqZN?JkwDV@_7jafHEG$n|*tSd2~jpP`PhAFq;YZ0dJ} zV$iF_%igdCWK5?&CA~4yt;i)$Z|vLxHWHcF!~1e(fRJ-+Tj*S_)JsHEx>W}tlS4Pf zX=|ciU3=iFT^M<(GcQ~7rF!-DgVcPm%KJPHXbD_Nq0ZMUJErXW%penk~1= zu6gZo@?g2n5gLFyUz!#UBc$Lq0vhC3%^c!}g zK=xTY$e}|UdCQI^g$cTQ4Wv!iFs$d;wc_OeDM&fXVfb>CgFd`r7yGdqsVUZXK1;Ry1(T zA!g+PUytJ6oGXUTF$Q!R0QjQ7EfFAJ{(lV6yl`?_s6wHmW}=Z~1gb3=%`+RWU`5}E zX*6&F7_FG_L`4)-OKC1@fTmYsKIW9Fb#9N;$7v|^UI4lwLx_kTygG=|k8X{UBt0Tw zCp`lV36hj1bJn@|oZ+>%D|)EV`(btxUHu}+d&R!PBG0DNRV{gEPQl4-Kd8E@XXyL~^i!y+3G zS}6S1_B<*q+CQ!pq`gTx!yH5^lw%Cwh<_(8E1E`HKBundmdu*yzX-pCUH^7&QS4HG z`zd1o%qF&60sdZUO{rgov&( z)$!fzzy*dCjWMd2Pd<%MfXLjk*+=lley`~3g`KTi=2isY@Qu+#Fd9V)` zrck-b7u(t6?0PsiP&de!DJ$&SEib03Vo!1XfUo~f(+6j5Q93&7Lajp#!>*$8={?hJR%}oR{pnB^Z1lcA zknFvO9KwZ$H4jG`4W!E@aoi|}%cD)g&oIm*fk@?V3OY+Vj%EuNop#T+aK|*ha(*U2 z1f~l>nmaCrlOmpC;^vc<6-PSH1hKdHqP$k!Acvv+3sQU@1aKj_vzUa$3A}F>)6Dc~ z+k=Uf%t4_3FDpq^nM)JtxRCO<6$f0DIPky(!IXu+h#kpE0WRd?e)ggbX6f9?5Ilp> zc@|VyTzw8zbR?&?jj|sraAa_!P7>USRrqOKT0 zC>+3zZ1^ZLl6qZjRPV$}qpOr(c{}W#CD3B1bAp^ghhz?b12;7X(GcJ)u}6ZdQbIyT zm~@6|S%JY^49CYu6G1=xIf!&Qh@75JhgLaODZe(M4&&VdYB&OL$1e9I4_+yfUCT#IvwIE9NYgE}{( z6n=dYq?G=iV84|<9wYL=Dm&dn@q9&l{n&oOHH#{G&i`yW=MNmDz{}NpaH+6i%OffS z1YF3>dCPjo} z4Q}8yEViWcUcAi%F-59i^>-f~VuEjOx;EDT1x{LAv+*|E6^;6kGU8?m)q;@m z5JY2*nrOOB;@Yn-&{KF!BO#DtHqy>2y46S7^eAqv)pDaW~w;sF%YE35qtbwUd znhS>Y(V=~^++`x{MWcS}LI`q*XYG9co!ER@hKQX>altrTR?VZ{N1(QV&EOevh-UWK z{h)6-H98jBW4fHVn@1I|Qk^TdyHbVeJ{{wKtLW#Z2-V%Eo18V?w znRwKc1*j>Th(mSRn>rIGw)jNEVc*0t07IC1T^q~0eU|iJSO9>tb-6H&W(&Gh0U{__ zc|syA(jpZ79w4(AMue2hSp#%Meh2t9R0il82_~9>IuQ%C@e&Y{8SxWJoM59#EDT9X zB*T;l-Vl0CBvSwoW^s=rz?Be@OqdLjx=a6hvj7WgOpsV_FAEU4Zr2teop2Svg#7fdr>{gHm`n+r6NpZ~z2=MIQdHxV(-0S|!*ZW3qR_z4jD4+6c> z5Bx=>D_a@hJNsWdGefJxh#LTj|KRY&6=Hq!8ET)#x7v$ud?&KX35+OLLX<;kj#2&5 z%t3WPvK%Fm#Pv$ML;PjH(r&dsE)WO+z>vwshf`;*fX*w1h#kg~hvt0}0G8#6bDDnM zB-RKKiF-T*jNd^7Je#fplx*k&;|V0>15M#Sh{NmxELE%$TW-(;A_?sx7Vc~cgdx3# ztc78{M4iGG8~f%R;($JO#1{}Ff88_Mk<38ruCK(_JrB~`9f-EPM3k&424G{1g*eTD zy?Pju?p-@~CqM)JKRO*g2-Y8MIvv`Z0`HH2If;f7KvZ-w-VG=u!pa1GzXHZ8Ay!wG z0XqIbJ23Av3TPzz{=ZtAsg@(FL;OwR!VCR<8_GOmb=dk5o4dn&KR!#2hSNXIslAQqf8rJbU`})LBC`JZdy*CdwGlVI>hto?QA0 zm{V-w0^s8DzmeCwx7y`?5Y;OOUv4-8W_Ou7n*tP3JV-1Qi1H{OoJS{4g;mrNSuAb? z`g`()MXI@CN;-&Um0amOb+%RUX%#TU|HvOE0Mz|M?kDR2wmtSw79~bXe_pulf1%s( zhzH&peK_rRQ^#HIpRdxwx61etDgI7NOS>hdq;xzFyj6l@u-)8|=Ooi^mTgIq3j?&`s(qMU&h6@O&L?|I2rOY<~J+l`~H z3Tz1(swaO_eAWVNO8JOOOzQdb=VxRMz^)#+6<{-lAih`vt&plb5Ci;ymTlPfr&i{V ztEBDTefNpnu`S9XPWoS?N^dhO)pZY;5T?t9-Nitz5nE2&GxY;cTrm`=g@uK_(WDtV zT3WG*(Jli`K##?|Twz-u+oMZ53E)@zEw?rtYP}V5`V`p`rhxhL?9a2>5%cxQ9fGKQ zHSfNEuMBP~Q(J-yhTT2Wd&Pj;I4ob3Ys0P9DbK{i#i6YWIaw(wDQ-*Po2;6)t-e`2 zJCrChZK}7*Kk4b|CHQ43Ml=8lwlbf|lCULoHGx1N(F8w#S4`O}R>d4cwgk#fq$K5m z9r2aLX&Dev)kG~fpxG0;ZYJn_XX2ofcItWq0zPNAj$9i)lLzCK6mx)87e94YvGPl& z=p7Pkwd7c3@taFerhg8kOUiHqA1IZBSCIqi41Y@@kJqQty`)MA$7RwH%)s16M>-C=ieatnQa5Tn6q*Nf`hf+iIzo zDw3UUBvUoxn09c}Pel$oaxZlfyh`ZyNQ4#kD*@F1|j3NP%Z1+pUHZBxs;TY3c{m9VV_7-Y-pr9Q-fZd zTPh135lb{O*_R9Q6JWb7WR|C+t!>5eRx$I^N$ZqLk8LX!tyHsM$xu)!QFZ_o7 zXAU;u4;n09d74f8t@E|K?C4yCn*BFAU6L@OH|D>6gW%N~_<4MqDU!Z|TCBSz;_<3z zEH{n`@QxSHlOdqi04O!SHG7L)=`f13W3d!MUA0FxC@{VSCdH|5LJd=hP*rcPB#&oR zRaJSz&o9h-_Nemo=@8?OJlCh23m-e`*KjsI7@pS4d|S=QFKxKlG;R$Y)Tq$$pT4Q4 zrUqpy?Rel~q~=bc>lJm?zi4S`$?H_mA58W9Gc&FQ7>sr+D=SVr7ZY#zLF(gRsfmbBEHPYzN?E9KnpA?gvSsBYHmlaHqz(`m*7d+P`!?z~$rhriP%7mF>5FEW7Vs0z*EKiB&eE2DTkI)GD^Yx~U8>k~p8dNYP03+PH|!ga%9b;6;=HM68_i8++C= zD>|VbVsn9HZb2 zi_8Rw{5|GW1dP(#-Re<{gL&qCpbknWlbB+Kqo&sx%l*NFtoY!y^7m_TJ7QawY`dcn z#?N@UyA&EuCvCv^*-c0Vx)&7}z%Z}z6PQy-KBxpdd4asx#3V8ptl4wwu=8hb164bp zXZ4VUeb=>EeBv;BS1M!C_{xFFK>Xz~ZB`=z-@rNRujlM3-2*}sjy8e5_A;$wU3@ueGh)69bahQN zNKfdj?`JFWJ=N_QQ}x3W7?P-JtgjC(G&)!H_ymC@zz6&)zjW&FG>Z>io&lE za{}5&74a2Fe2glXRyjkVip{)_mWAw}qTb6Ayl~WYB!amlpTmED&>IdjgzVc<^?OhU z@G4VoBr)_QCxUV7w++*8JQ~hdO|LPpnf%QTPT3KF>sfzhZ6|ZR!aV3vxL<5UZ@)h~ zf3+ej-9i`?GNK2T`Bby;QnWikTg$)RX(gtnSj927okp2q6yg}~yXO2`XIp5MHwr%* zt3(F!t(tdCUiL!kMApmvW$=)~qPnpu2E%6$`pl<6q#g(MDf1bB010rf9z{f!+>ZFh z{^OBw=VVkT46piU(eQ9Te8@UK<$jKP&qx=>i|rIl1GEyqHS{s;b3PL1?uZFL%=E&9 zKZ_wBHA`9_C|U+PO%{;LBp@~pzpY-}ZI}7xU_Ev{e)WWtH?;y?jk7UcyrX)Vx!lsp zn8kOQK_Ab7C2RsIyN`g9Xs0* zE`f{P9u5TUPS}fx%w4l=4q3FEi<-~5A3EyhPr|j|dan6q6=@g9yIP8PpyRRru~1sR zlQ+mE7Dq8h{H4|Ub=s4h!cOm2O68y9|DwOMU!^ysL;LzYGVrJ)isOwOvJOiVpT#4L zdH3Nei0-lPU7W2?p<4ys{sUXPV(4CJ4Vy3BRQy-@)0u&=3md~M%W94nUS!02bFP&g z4YJHM34<$^)W*!s?>+IR<3UT>la1R!EMhgnu5wsshPZS4-F4Tl*!``qDXkSrjz*N#S|As> z&=A}DwWMd&4RD~gGLyON*X$9hM{WV_{L}7VUY;OkHAl+iu@^EFHx1|h7_JSpP42z> z^d4K7e8KfH49_{c_9?pMkq})RbNiqR-V#e4iTsg+H-M@6){HdA4s?}YiNUA)+m)O_ zb1n?&@qKQ3-43RQK6+0lA=7sPq`-UMY?aC35!1! zq<|^<#~GaRNE)NmDtY=weHbrldM%lEWqH44hqE9+j(|Tsb2m%ow9)G$d8v52LKCsI zxaIi_q08cSHsa
ki=-y`Wg->I}Zxzpj39wEcN{Y_a5U2e<#9t@KZ?_RS-AnZ0e##;?X-8hrhp8_?WXQn|^&ro` zkL7jKqmI$9N%&_gM>}uDF<$RJUWrIsxEgCP2j_d*>b3qR&ErK8yxRJjg^W7#>Qf;072lI`RfxKmPP=+&-8S@^7NGhK zuL+4$lJ27i`ElbC98kF|xsl7d`6KHM6@&5yCy^jcD5UrB3LzBS_$GqzX~DSjaR)cI zSKyZIG7Djq9lk18$!crrATJc)gIGG&w1$%_0tJ14hS-&=Py=P%z z9RH`ifTXx*#);wLcq4E8B!YYdCf1A_fqPCNMw@;WZ(0+Fez{_g_%)bkAjPYsu!fxq zG#*Lb7{MCFr{av}_$A^a#DhF9kDQmaJ6X}yBb9Z+IM3)k!vNzF{JRue_;e_&Tyy0?Ca~l;g}u;z zY`Q)LeSYc&~kTeN7CjFH(qw&WuK1L!UZ%p18T7+vRvbq#B46`(( zi3~5_frsd3;IK50;v5aH;h$qk2V9??(|8VFW!MCS^R?$z4nk}sB5q0I^SE~JiFs3` z6{zjRo0R1O?V}Ir7R^Ak#12lHKQ%#dd;A($i(LIjJgSK$5TgA%vV)kvu1&B|W$obC zF{Z{4MYbPpaVFw>FTNMVT+msufWPR63Q7NZ_jDVP5zW{8@~rCDq-yvZ(Ox>jCBx_> z?j-lQih+g?PIA@6JQ}lQu9yLDTe^!@_Boi%SZ*heZ`DM$(G9UgZ^w!udrBK0v60S) zQS}zm5wmE>9&OtS%ro*9ON^u3blD#pxqJrtvO#ekH;#msh0lVR>jvvCptZ4ur$9F_ z%6^sQ3-=v^xsj-FPU5}P!p;%}3r2U`iBE>_o1andLTpabrO*+9#N2&H)$Q(-&hjP# zw0ou=6v3a`zPOqHMi_EtDjB(Cw}vD#T!`i5@&ZB`i7v8Vz{XXU;amsVNMGZr%1SKjj#b7*b zz-~Xl_*4hoz#FQ0-{`qTb`gr}(pl*fcK0aVGMFc}K>wLQ|7NC@nIrmZaP+-<_eNgn z_}{CpzBB0t_22%I!rjAc2*Wt}%-(tT`-T)(Ur?H2X1Asv7O_!TXuWy~)E~Y4>T+ds z^X}(FR?hN>gO%!@;_z(as!<=Z&uDqvUPt)ab!}~JSHV=z*dW0X<3nQY%*>1p;Gn0{ zZhwFM+RfCI35XM`fe0@e2tu$weIEoe0tO;u=WX$d&P##~(yf8glrI->tep^@tE?>`EJ=rnzEm@y>^BQ2bK3RW zO}rZ!ikT5i!d4Z=u8e(3utG)b78I;yjNgxUgu9O$gF$s`j~zQw1!bu88EhN%GGu;^ zzs9ruqbyG!kXiUFVD=O2r}*~;Ajy!rJ2{PLZ{JUvEpUhiW)}%Wnb1f6|sgVjq z)*#-bv;J37qs?XF!l2(nl#-KT1O=nrh0K;YO#~_=bIx+ParGho=DIT$X^Ooc7VK{# zaMU53vXW9TbtvO;O^JLLeKmYg%%=>QRCi6k{z@Uo-J<`R5KYZ9yDe1F=;1G9_G}V< z#jalcoQ|Wp09)2O#h3PdTRYc{p$vEI6BwuGFrkV?;upfj`$Q5UM1Rz`QJ3eMl_c2Y zSQF2!$g4_lBkuqC`_1Kv22DE{PEo$zG(XPjtzwKmPv5U*HHUhNa!D6RJW9IMr0Y!s z^|lbrI8zqyqwwXW$PIR-4*)#31{67-ZBJe|PkvBNg!$p)#|N+0OuK}+FTOtz*MZ8U z{?h>@CKPZp-r)D9$`&SF>FHr1OD}xXSxY!g5ZyI3H~ihsJ22?9dY&YLl*g~O;Ca%A z@aTira3F8qta``TM8HMV?6$K2+f6{ZYB!|qPO|UH%8r@Y+mD~WE!1TUq$r}B)w3oP zF8dN=34!9hl~n)(Z!7@yA`HUC^~duIkN^R;KqgRKxKoVWu%e2rtgBz!KdFvA+am@y zeO>u#0!;*B4Km+)r?eJH|8AsOEj*}oQ$Oa52IWM#`6sJxcP3`|>1)6kOp0 zt`q*du6YtgiRUKhdgyOB0@V8dqkdHXni!X7cdXsAvcG^~@B@M6@wJi3)S>eK?i<|z zu5JIj-we>CC;~bF%=#W0sHccWwMLlv^89Z+z=2_LS_n|k2?XDs*anyv?J)V@%q@%_ zSNl@pIlj+T|F6|u>#0MQ|NZ#RmSX(xlOibi$n^W%AkaZgnI{T$k>bn_uL*JjxO#BX zn+%N2?#3h&X9*JTn5d%cA`A?o`@`r1@|lUOJ0n`CDkbzFOEMC4ss242*7Y*w6u^Vz zu?DISGwjW?|53qwRAHjnGkYh3+(yrs0}cO?n>wtzCvpY2G_B;^BhsEFh9+JEvfMQ& z4sBIOGe!G<84@>qO5cYJCbeg%n%;D|*3|Pq7p_8zAjq@k`M9TmK5qBH4#r zTyxAL!J$V$ZSCT}LY7?-m;aYyqHs9jcC-4E^mL1>vp&azpUCq^UI<-gw(*1+K45je zyAqq6V4q-+kb-g{ETc@$OZ#ZG+Jt)T#{-B(Bk`C-t6o!NOT!+Z5gVXnX~Q}S znL4as>6~b=eH<@mCqw6r5{MFRI~jGFd#k!_@uqTYw>&||LvjN`a7P6ZAgE1n%3Cm$ z8OEZ+a(A#KkXJIrYGc!vK*DwiqQtJ4F8g-!M!kI!3aIUbWh`b|EpgOqsOII5d!Jsr zRT`HuH8CHu_nW&u1et7hFTRHLgVT^4bo%%535KWhkxBjPn!d_1RO z$)<2SL?e`O-a{M{w(R8ri6q)1mW=4JOla;hegc@l0uN!*l-ZNr;0ijs;oKT~p(MH@ zPrGX~KE+$r`rNZ2khJgWc5Q#VI@174S_c)+oC|Emk54e-jp8ol-RLN4c;ZB>R79*1jXP_arb$sxt+hZ}r#)nW?UvBPX@>%d?PH0BDg^bpNAEE<5(L^KjZ4HoR zA7Z$hRWci8v!n6DjaCWXW6wJM4G=9m6*hiUd12GRIL;^~3f-3^3RP%4hF>o42mi7yjA&`<$$-UCIB?Lgue_GDitTsgCLhVm>d(s>*eVZ0MrXTSDZn~c^T75oy4`obxXxj2hXu$N` zw9bkaMY!Vu_B*sn4D`C@eo%Gw8D#xHK_S;j8jGXNTuxKEv@-AuY&H*PnaKd2`;4L* zks5wEg!M;b17jvM3ZK^;N`2t@uKROB_{Ui`U!72k-%+0sgrjJJwufWutjz2I6ZdLQ zo_0^P#NJb=(cC&ehUmi+RA_*?NJs{Id+>tDJNK2$PW$AS8lDG<-OAbP=1dy8Lr6h zeOCzH9@4J{zmri7RFQTFZ~w(@>R5CE+@^Cr=iDR*-3CRtQnhXS??tf5 z0r)W3=G>gZC~|^!&d7yu%=oy>>3_X$`XycORkN6i(ggN@t#0~`B;fwKMo&@Yj;Wr! z#2Ncn4OcM3GOVB#f_n&sZ>^|yl^Db%>7F9{u3yKPUqfbdh+pr~!+fC~*$ZQ}m4k(tF34)cn`cb<=|+S4-^O<5|>H26(TU z=SkD92${{#qm#}?0k#uBm`2m}?maR9jGQ<5pHhVX`Mfz?s{=h0xwkXlIIv9iQ7)$NMyB4?9{)fc!^(TJ*ywLOh z{o-37f&e+MH2|t7{x3u=ZaS^mgh>$)T=6{yMizZPvm1^j0({0k5tHPXP9H;x|C>*~ ze$|P)rlujrOp^TBoE)qgER#%(53czD)M55#A!b@V)MWxQ;qHu|%1GZ4JY=b7z5RW3 zQSk)OV@e!r6vv;}+YGs$8t*p%TQk)Xi?K3uzQ7@6!$>%7CSYHzS-A`te6|Xbp@m`2 zV;X$}#G93aE{U|CuedLr$4D(=x>)@%eT%0A^9LG4Fi%1gpfIsxs2F1kBUlmhNdG9U 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Set point for supplywater temperature TSupSet + Output of P controller y + + 0 + 1 + + + TSupSetMax + + TSupSetMin + + + + + + 1 + + + + 0.1 + Pump control signal yPum + + 0.2 + 1 + + 0 + + + + + + + + + + + + + Dew point temperature + + + + + diff --git a/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.png b/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.png new file mode 100644 index 0000000000000000000000000000000000000000..c448f11c917c8e90de31348c467997ddfbeec984 GIT binary patch literal 24175 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 literal 0 HcmV?d00001 diff --git a/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.svg b/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.svg new file mode 100644 index 00000000000..9e6e2582484 --- /dev/null +++ b/Buildings/Resources/Images/Controls/OBC/RadiantSystems/Heating/HighMassSupplyTemperature_TRoom.svg @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Set point for supplywater temperature TSupSet + Output of P controller y + + 0 + 1 + + + TSupSetMax + + TSupSetMin + + + + + + 1 + + + + 0.1 + Pump control signal yPum + + 0.2 + 1 + + 0 + + + + + + + + + + diff --git a/Buildings/Resources/Images/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.png b/Buildings/Resources/Images/Fluid/Boilers/Validation/BoilerTableEfficiencyCurves.png new file mode 100644 index 0000000000000000000000000000000000000000..c4e65b3645e4a6ee083059b0440e378967817814 GIT binary patch literal 26041 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 libraries have been added:

- - @@ -277,14 +259,70 @@ Each class (i.e., model, block and function) must be used in an example or valid to existing libraries:

Buildings.Experimental.DHC +
Buildings.Experimental.DHC
Buildings.Experimental.DHC.CentralPlants.Cooling
+ + + + + + + + + + + + + + - + +
Buildings.Controls.OBC +
Buildings.Controls.OBC.ASHRAE.G36_PR1.Generic.SetPoints.ZoneStatusDuplicator + Block that duplicates the zone status to be connected to all zone groups.
+ This is for issue 2544. +
+ Buildings.Controls.OBC.CDL.Routing.BooleanVectorFilter
+ Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator
+ Buildings.Controls.OBC.CDL.Routing.IntegerVectorFilter
+ Buildings.Controls.OBC.CDL.Routing.IntegerVectorReplicator
+ Buildings.Controls.OBC.CDL.Routing.RealVectorFilter
+ Buildings.Controls.OBC.CDL.Routing.RealVectorReplicator +
Blocks for filtering and replicating vectors of signals.
+ This is for issue 2544. +
Buildings.Fluid.Boilers +
Buildings.Fluid.Boilers.BoilerTable
+ Buildings.Fluid.Boilers.Examples.BoilerTable
+ Buildings.Fluid.Boilers.Validation.BoilerTableEfficiencyCurves
+ Buildings.Fluid.Boilers.BaseClasses.PartialBoiler
+ Buildings.Fluid.Boilers.Data.Generic
+ Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash2501
+ Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash3001
+ Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash3501
+ Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash4001
+ Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash5001
+ Buildings.Fluid.Boilers.Data.Lochinvar.Crest.FBdash6001
+ Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX400
+ Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX500
+ Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX600
+ Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX725
+ Buildings.Fluid.Boilers.Data.Lochinvar.FTXL.FTX850
+ Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0400
+ Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0500
+ Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0650
+ Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash0800
+ Buildings.Fluid.Boilers.Data.Lochinvar.KnightXL.KBXdash1000 +
Classes for modeling boilers whose efficiency curves are provided as a table. + Part of the code from the old Buildings.Fluid.Boilers.BoilerPolynomial + has been moved to Buildings.Fluid.Boilers.BaseClasses.PartialBoiler + to support the new model Buildings.Fluid.Boilers.BoilerTable.
+ This is for issue 2651.
+ In the moved code, the boiler's heating power output is now corrected by + its loss to the ambient.
+ This is for #2725. +
Buildings.Fluid.Chillers -
Buildings.Fluid.Chillers.Data.ElectricEIR.ElectricEIRChiller_York_YCAL0033EE_101kW_3_1COP_AirCooled - Data for air cooled chiller.
- This is for issue #2770. -
Data for air cooled chiller.
+ This is for issue #2770. +
@@ -9591,4 +9629,4 @@ requirements definition or providing feedback regarding the model applicability to solve specific problems.

")); -end Buildings; +end Buildings; \ No newline at end of file