LCOV - code coverage report
Current view: top level - EnergyPlus - OutsideEnergySources.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 196 224 87.5 %
Date: 2023-01-17 19:17:23 Functions: 11 12 91.7 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : #include <iostream>
      51             : #include <string>
      52             : 
      53             : // ObjexxFCL Headers
      54             : #include <ObjexxFCL/Array.functions.hh>
      55             : #include <ObjexxFCL/Fmath.hh>
      56             : 
      57             : // EnergyPlus Headers
      58             : #include <EnergyPlus/Autosizing/Base.hh>
      59             : #include <EnergyPlus/BranchNodeConnections.hh>
      60             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61             : #include <EnergyPlus/DataEnvironment.hh>
      62             : #include <EnergyPlus/DataHVACGlobals.hh>
      63             : #include <EnergyPlus/DataIPShortCuts.hh>
      64             : #include <EnergyPlus/DataLoopNode.hh>
      65             : #include <EnergyPlus/DataSizing.hh>
      66             : #include <EnergyPlus/FluidProperties.hh>
      67             : #include <EnergyPlus/General.hh>
      68             : #include <EnergyPlus/GlobalNames.hh>
      69             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      70             : #include <EnergyPlus/NodeInputManager.hh>
      71             : #include <EnergyPlus/OutputProcessor.hh>
      72             : #include <EnergyPlus/OutsideEnergySources.hh>
      73             : #include <EnergyPlus/Plant/DataPlant.hh>
      74             : #include <EnergyPlus/PlantUtilities.hh>
      75             : #include <EnergyPlus/ScheduleManager.hh>
      76             : #include <EnergyPlus/UtilityRoutines.hh>
      77             : 
      78             : namespace EnergyPlus::OutsideEnergySources {
      79             : 
      80             : // MODULE INFORMATION:
      81             : //       AUTHOR         Dan Fisher
      82             : //       DATE WRITTEN   Unknown
      83             : //       MODIFIED       na
      84             : //       RE-ENGINEERED  Brent Griffith, Sept 2010, revised plant interactions.
      85             : 
      86             : // PURPOSE OF THIS MODULE:
      87             : // Module containing the routines dealing with the OutsideEnergySources
      88             : 
      89         275 : PlantComponent *OutsideEnergySourceSpecs::factory(EnergyPlusData &state, DataPlant::PlantEquipmentType objectType, std::string_view objectName)
      90             : {
      91             :     // Process the input data for outside energy sources if it hasn't been done already
      92         275 :     if (state.dataOutsideEnergySrcs->SimOutsideEnergyGetInputFlag) {
      93         157 :         GetOutsideEnergySourcesInput(state);
      94         157 :         state.dataOutsideEnergySrcs->SimOutsideEnergyGetInputFlag = false;
      95             :     }
      96             :     // Now look for this particular pipe in the list
      97         393 :     for (auto &source : state.dataOutsideEnergySrcs->EnergySource) {
      98         393 :         if (source.EnergyType == objectType && source.Name == objectName) {
      99         275 :             return &source;
     100             :         }
     101             :     }
     102             :     // If we didn't find it, fatal
     103             :     ShowFatalError(state, format("OutsideEnergySourceSpecsFactory: Error getting inputs for source named: {}", objectName)); // LCOV_EXCL_LINE
     104             :     // Shut up the compiler
     105             :     return nullptr; // LCOV_EXCL_LINE
     106             : }
     107             : 
     108     7025029 : void OutsideEnergySourceSpecs::simulate(EnergyPlusData &state,
     109             :                                         [[maybe_unused]] const PlantLocation &calledFromLocation,
     110             :                                         [[maybe_unused]] bool FirstHVACIteration,
     111             :                                         Real64 &CurLoad,
     112             :                                         bool RunFlag)
     113             : {
     114     7025029 :     this->initialize(state, CurLoad);
     115     7025029 :     this->calculate(state, RunFlag, CurLoad);
     116     7025029 : }
     117             : 
     118        1375 : void OutsideEnergySourceSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &)
     119             : {
     120        1375 :     this->initialize(state, 0.0);
     121        1375 :     this->size(state);
     122        1375 : }
     123             : 
     124        1375 : void OutsideEnergySourceSpecs::getDesignCapacities([[maybe_unused]] EnergyPlusData &state,
     125             :                                                    [[maybe_unused]] const PlantLocation &calledFromLocation,
     126             :                                                    Real64 &MaxLoad,
     127             :                                                    Real64 &MinLoad,
     128             :                                                    Real64 &OptLoad)
     129             : {
     130        1375 :     MinLoad = 0.0;
     131        1375 :     MaxLoad = this->NomCap;
     132        1375 :     OptLoad = this->NomCap;
     133        1375 : }
     134             : 
     135         157 : void GetOutsideEnergySourcesInput(EnergyPlusData &state)
     136             : {
     137             :     // SUBROUTINE INFORMATION:
     138             :     //       AUTHOR         Dan Fisher
     139             :     //       DATE WRITTEN   April 1998
     140             :     //       MODIFIED       May 2010; Edwin Lee; Linda Lawrie (consolidation)
     141             :     //       RE-ENGINEERED  na
     142             : 
     143             :     // PURPOSE OF THIS SUBROUTINE:
     144             :     // This routine obtains the input data puts it into the
     145             :     // component arrays. Data items in the component arrays
     146             :     // are initialized. Output variables are set up.
     147             : 
     148             :     // GET NUMBER OF ALL EQUIPMENT TYPES
     149         157 :     int const NumDistrictUnitsHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "DistrictHeating");
     150         157 :     int const NumDistrictUnitsCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "DistrictCooling");
     151         157 :     state.dataOutsideEnergySrcs->NumDistrictUnits = NumDistrictUnitsHeat + NumDistrictUnitsCool;
     152             : 
     153         157 :     if (allocated(state.dataOutsideEnergySrcs->EnergySource)) return;
     154             : 
     155         157 :     state.dataOutsideEnergySrcs->EnergySource.allocate(state.dataOutsideEnergySrcs->NumDistrictUnits);
     156         157 :     state.dataOutsideEnergySrcs->EnergySourceUniqueNames.reserve(static_cast<unsigned>(state.dataOutsideEnergySrcs->NumDistrictUnits));
     157             : 
     158         157 :     bool ErrorsFound(false); // If errors detected in input
     159         157 :     int heatIndex = 0;
     160         157 :     int coolIndex = 0;
     161             : 
     162         432 :     for (int EnergySourceNum = 1; EnergySourceNum <= state.dataOutsideEnergySrcs->NumDistrictUnits; ++EnergySourceNum) {
     163             : 
     164         550 :         std::string nodeNames;
     165             :         DataPlant::PlantEquipmentType EnergyType;
     166             :         DataLoopNode::ConnectionObjectType objType;
     167             :         int thisIndex;
     168         275 :         if (EnergySourceNum <= NumDistrictUnitsHeat) {
     169         143 :             state.dataIPShortCut->cCurrentModuleObject = "DistrictHeating";
     170         143 :             objType = DataLoopNode::ConnectionObjectType::DistrictHeating;
     171         143 :             nodeNames = "Hot Water Nodes";
     172         143 :             EnergyType = DataPlant::PlantEquipmentType::PurchHotWater;
     173         143 :             heatIndex++;
     174         143 :             thisIndex = heatIndex;
     175             :         } else {
     176         132 :             state.dataIPShortCut->cCurrentModuleObject = "DistrictCooling";
     177         132 :             objType = DataLoopNode::ConnectionObjectType::DistrictCooling;
     178         132 :             nodeNames = "Chilled Water Nodes";
     179         132 :             EnergyType = DataPlant::PlantEquipmentType::PurchChilledWater;
     180         132 :             coolIndex++;
     181         132 :             thisIndex = coolIndex;
     182             :         }
     183             : 
     184         275 :         int NumAlphas = 0, NumNums = 0, IOStat = 0;
     185        1650 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     186         275 :                                                                  state.dataIPShortCut->cCurrentModuleObject,
     187             :                                                                  thisIndex,
     188         275 :                                                                  state.dataIPShortCut->cAlphaArgs,
     189             :                                                                  NumAlphas,
     190         275 :                                                                  state.dataIPShortCut->rNumericArgs,
     191             :                                                                  NumNums,
     192             :                                                                  IOStat,
     193             :                                                                  _,
     194         275 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     195         275 :                                                                  state.dataIPShortCut->cAlphaFieldNames);
     196             : 
     197         275 :         if (EnergySourceNum > 1) {
     198         354 :             GlobalNames::VerifyUniqueInterObjectName(state,
     199         118 :                                                      state.dataOutsideEnergySrcs->EnergySourceUniqueNames,
     200         118 :                                                      state.dataIPShortCut->cAlphaArgs(1),
     201         118 :                                                      state.dataIPShortCut->cCurrentModuleObject,
     202         118 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
     203             :                                                      ErrorsFound);
     204             :         }
     205         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).Name = state.dataIPShortCut->cAlphaArgs(1);
     206         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).InletNodeNum =
     207         550 :             NodeInputManager::GetOnlySingleNode(state,
     208         275 :                                                 state.dataIPShortCut->cAlphaArgs(2),
     209             :                                                 ErrorsFound,
     210             :                                                 objType,
     211         275 :                                                 state.dataIPShortCut->cAlphaArgs(1),
     212             :                                                 DataLoopNode::NodeFluidType::Water,
     213             :                                                 DataLoopNode::ConnectionType::Inlet,
     214             :                                                 NodeInputManager::CompFluidStream::Primary,
     215         275 :                                                 DataLoopNode::ObjectIsNotParent);
     216         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).OutletNodeNum =
     217         550 :             NodeInputManager::GetOnlySingleNode(state,
     218         275 :                                                 state.dataIPShortCut->cAlphaArgs(3),
     219             :                                                 ErrorsFound,
     220             :                                                 objType,
     221         275 :                                                 state.dataIPShortCut->cAlphaArgs(1),
     222             :                                                 DataLoopNode::NodeFluidType::Water,
     223             :                                                 DataLoopNode::ConnectionType::Outlet,
     224             :                                                 NodeInputManager::CompFluidStream::Primary,
     225         275 :                                                 DataLoopNode::ObjectIsNotParent);
     226         550 :         BranchNodeConnections::TestCompSet(state,
     227         275 :                                            state.dataIPShortCut->cCurrentModuleObject,
     228         275 :                                            state.dataIPShortCut->cAlphaArgs(1),
     229         275 :                                            state.dataIPShortCut->cAlphaArgs(2),
     230         275 :                                            state.dataIPShortCut->cAlphaArgs(3),
     231             :                                            nodeNames);
     232         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).NomCap = state.dataIPShortCut->rNumericArgs(1);
     233         275 :         if (state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).NomCap == DataSizing::AutoSize) {
     234           7 :             state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).NomCapWasAutoSized = true;
     235             :         }
     236         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).EnergyTransfer = 0.0;
     237         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).EnergyRate = 0.0;
     238         275 :         state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).EnergyType = EnergyType;
     239         275 :         if (!state.dataIPShortCut->lAlphaFieldBlanks(4)) {
     240           0 :             state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).CapFractionSchedNum =
     241           0 :                 ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(4));
     242           0 :             if (state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).CapFractionSchedNum == 0) {
     243           0 :                 ShowSevereError(state,
     244           0 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).Name +
     245             :                                     "\", is not valid");
     246           0 :                 ShowContinueError(state,
     247           0 :                                   state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) + "\" was not found.");
     248           0 :                 ErrorsFound = true;
     249             :             }
     250           0 :             if (!ScheduleManager::CheckScheduleValueMinMax(
     251           0 :                     state, state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).CapFractionSchedNum, ">=", 0.0)) {
     252           0 :                 ShowWarningError(state,
     253           0 :                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" +
     254           0 :                                      state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).Name + "\", is not valid");
     255           0 :                 ShowContinueError(state,
     256           0 :                                   state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) +
     257             :                                       "\" should not have negative values.");
     258           0 :                 ShowContinueError(state, "Negative values will be treated as zero, and the simulation continues.");
     259             :             }
     260             :         } else {
     261         275 :             state.dataOutsideEnergySrcs->EnergySource(EnergySourceNum).CapFractionSchedNum = DataGlobalConstants::ScheduleAlwaysOn;
     262             :         }
     263             :     }
     264             : 
     265         157 :     if (ErrorsFound) {
     266           0 :         ShowFatalError(state,
     267           0 :                        "Errors found in processing input for " + state.dataIPShortCut->cCurrentModuleObject +
     268             :                            ", Preceding condition caused termination.");
     269             :     }
     270             : }
     271             : 
     272     7026404 : void OutsideEnergySourceSpecs::initialize(EnergyPlusData &state, Real64 MyLoad)
     273             : {
     274             : 
     275             :     // SUBROUTINE INFORMATION:
     276             :     //       AUTHOR:          Dan Fisher
     277             :     //       DATE WRITTEN:    October 1998
     278             :     //       MODIFIED       May 2010; Edwin Lee; Linda Lawrie (consolidation)
     279             :     //       RE-ENGINEERED  Sept 2010, Brent Griffith, plant rewrite
     280             : 
     281             :     // PURPOSE OF THIS SUBROUTINE:
     282             :     // This subroutine does one-time inits and sets the operating mass flow rate of this machine
     283             : 
     284             :     // METHODOLOGY EMPLOYED:
     285             :     // One time inits include validating source type (should happen in getinput?) and locating this
     286             :     //  component on the PlantLoop topology.
     287             :     // The mass flow rate is determined based on component load, and making use of
     288             :     //  the SetComponentFlowRate routine.
     289             :     // The mass flow rate could be an inter-connected-loop side trigger. This is not really the type of
     290             :     //  interconnect that that routine was written for, but it is the clearest example of using it.
     291             : 
     292             :     // begin environment inits
     293     7026404 :     if (state.dataGlobal->BeginEnvrnFlag && this->BeginEnvrnInitFlag) {
     294             :         // component model has not design flow rates, using data for overall plant loop
     295        4770 :         PlantUtilities::InitComponentNodes(state,
     296        1590 :                                            state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinMassFlowRate,
     297        1590 :                                            state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxMassFlowRate,
     298             :                                            this->InletNodeNum,
     299             :                                            this->OutletNodeNum);
     300        1590 :         this->BeginEnvrnInitFlag = false;
     301             :     }
     302     7026404 :     if (!state.dataGlobal->BeginEnvrnFlag) this->BeginEnvrnInitFlag = true;
     303             : 
     304     7026404 :     Real64 TempPlantMassFlow(0.0);
     305     7026404 :     if (std::abs(MyLoad) > 0.0) {
     306     1631132 :         TempPlantMassFlow = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxMassFlowRate;
     307             :     }
     308             : 
     309             :     // get actual mass flow to use, hold in MassFlowRate variable
     310     7026404 :     PlantUtilities::SetComponentFlowRate(state, TempPlantMassFlow, this->InletNodeNum, this->OutletNodeNum, this->plantLoc);
     311             : 
     312     7026404 :     this->InletTemp = state.dataLoopNodes->Node(this->InletNodeNum).Temp;
     313     7026404 :     this->MassFlowRate = TempPlantMassFlow;
     314     7026404 : }
     315             : 
     316        1375 : void OutsideEnergySourceSpecs::size(EnergyPlusData &state)
     317             : {
     318             :     // SUBROUTINE INFORMATION:
     319             :     //       AUTHOR         Daeho Kang
     320             :     //       DATE WRITTEN   April 2014
     321             :     //       MODIFIED
     322             :     //       RE-ENGINEERED  na
     323             : 
     324             :     // PURPOSE OF THIS SUBROUTINE:
     325             :     //  This subroutine is for sizing capacities of district cooling and heating objects.
     326             : 
     327             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     328        1375 :     bool ErrorsFound(false); // If errors detected in input
     329             : 
     330             :     // Type name string variable to collapse the sizing for cooling and heating into one block
     331        2750 :     std::string typeName;
     332        1375 :     if (this->EnergyType == DataPlant::PlantEquipmentType::PurchChilledWater) {
     333         660 :         typeName = "Cooling";
     334             :     } else { // Heating
     335         715 :         typeName = "Heating";
     336             :     }
     337             : 
     338        1375 :     int const PltSizNum = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).PlantSizNum;
     339        1375 :     if (PltSizNum > 0) {
     340        1230 :         Real64 const rho = FluidProperties::GetDensityGlycol(state,
     341         410 :                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
     342             :                                                              DataGlobalConstants::InitConvTemp,
     343         410 :                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
     344         820 :                                                              "SizeDistrict" + typeName);
     345        1230 :         Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
     346         410 :                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
     347             :                                                                  DataGlobalConstants::InitConvTemp,
     348         410 :                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
     349         820 :                                                                  "SizeDistrict" + typeName);
     350         410 :         Real64 const NomCapDes = Cp * rho * state.dataSize->PlantSizData(PltSizNum).DeltaT * state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate;
     351         410 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     352          82 :             if (this->NomCapWasAutoSized) {
     353           7 :                 this->NomCap = NomCapDes;
     354           7 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     355           7 :                     BaseSizer::reportSizerOutput(state, "District" + typeName, this->Name, "Design Size Nominal Capacity [W]", NomCapDes);
     356             :                 }
     357           7 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
     358           0 :                     BaseSizer::reportSizerOutput(state, "District" + typeName, this->Name, "Initial Design Size Nominal Capacity [W]", NomCapDes);
     359             :                 }
     360             :             } else { // Hard-size with sizing data
     361          75 :                 if (this->NomCap > 0.0 && NomCapDes > 0.0) {
     362          73 :                     Real64 const NomCapUser = this->NomCap;
     363          73 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     364         292 :                         BaseSizer::reportSizerOutput(state,
     365         146 :                                                      "District" + typeName,
     366             :                                                      this->Name,
     367             :                                                      "Design Size Nominal Capacity [W]",
     368             :                                                      NomCapDes,
     369             :                                                      "User-Specified Nominal Capacity [W]",
     370          73 :                                                      NomCapUser);
     371          73 :                         if (state.dataGlobal->DisplayExtraWarnings) {
     372           5 :                             if ((std::abs(NomCapDes - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
     373           1 :                                 ShowMessage(state, "SizeDistrict" + typeName + ": Potential issue with equipment sizing for " + this->Name);
     374           1 :                                 ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", NomCapUser));
     375           1 :                                 ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", NomCapDes));
     376           1 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
     377           1 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
     378             :                             }
     379             :                         }
     380             :                     }
     381             :                 }
     382             :             }
     383             :         }
     384             :     } else {
     385         965 :         if (this->NomCapWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     386           0 :             ShowSevereError(state, "Autosizing of District " + typeName + " nominal capacity requires a loop Sizing:Plant object");
     387           0 :             ShowContinueError(state, "Occurs in District" + typeName + " object=" + this->Name);
     388           0 :             ErrorsFound = true;
     389             :         }
     390         965 :         if (!this->NomCapWasAutoSized && this->NomCap > 0.0 && state.dataPlnt->PlantFinalSizesOkayToReport) {
     391         193 :             BaseSizer::reportSizerOutput(state, "District" + typeName, this->Name, "User-Specified Nominal Capacity [W]", this->NomCap);
     392             :         }
     393             :     }
     394        1375 :     if (ErrorsFound) {
     395           0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
     396             :     }
     397        1375 : }
     398             : 
     399     7025029 : void OutsideEnergySourceSpecs::calculate(EnergyPlusData &state, bool runFlag, Real64 MyLoad)
     400             : {
     401             :     // SUBROUTINE INFORMATION:
     402             :     //       AUTHOR         Dan Fisher
     403             :     //       DATE WRITTEN   July 1998
     404             :     //       MODIFIED       May 2010; Edwin Lee; Linda Lawrie (consolidation)
     405             :     //       RE-ENGINEERED  Sept 2010, Brent Griffith, plant rewrite
     406             : 
     407             :     // SUBROUTINE PARAMETER DEFINITIONS:
     408             :     static constexpr std::string_view RoutineName("SimDistrictEnergy");
     409             : 
     410             :     // set inlet and outlet nodes
     411     7025029 :     int const LoopNum = this->plantLoc.loopNum;
     412     7025029 :     Real64 const LoopMinTemp = state.dataPlnt->PlantLoop(LoopNum).MinTemp;
     413     7025029 :     Real64 const LoopMaxTemp = state.dataPlnt->PlantLoop(LoopNum).MaxTemp;
     414             : 
     415    14050058 :     Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(
     416    21075087 :         state, state.dataPlnt->PlantLoop(LoopNum).FluidName, this->InletTemp, state.dataPlnt->PlantLoop(LoopNum).FluidIndex, RoutineName);
     417             : 
     418             :     //  apply power limit from input
     419     7025029 :     Real64 CapFraction = ScheduleManager::GetCurrentScheduleValue(state, this->CapFractionSchedNum);
     420     7025029 :     CapFraction = max(0.0, CapFraction); // ensure non negative
     421     7025029 :     Real64 const CurrentCap = this->NomCap * CapFraction;
     422     7025029 :     if (std::abs(MyLoad) > CurrentCap) {
     423          35 :         MyLoad = sign(CurrentCap, MyLoad);
     424             :     }
     425             : 
     426     7025029 :     if (this->EnergyType == DataPlant::PlantEquipmentType::PurchChilledWater) {
     427     3332692 :         if (MyLoad > 0.0) MyLoad = 0.0;
     428     3692337 :     } else if (this->EnergyType == DataPlant::PlantEquipmentType::PurchHotWater) {
     429     3692337 :         if (MyLoad < 0.0) MyLoad = 0.0;
     430             :     }
     431             : 
     432             :     // determine outlet temp based on inlet temp, cp, and MyLoad
     433     7025029 :     if ((this->MassFlowRate > 0.0) && runFlag) {
     434     1630782 :         this->OutletTemp = (MyLoad + this->MassFlowRate * Cp * this->InletTemp) / (this->MassFlowRate * Cp);
     435             :         // apply loop limits on temperature result to keep in check
     436     1630782 :         if (this->OutletTemp < LoopMinTemp) {
     437           1 :             this->OutletTemp = max(this->OutletTemp, LoopMinTemp);
     438           1 :             MyLoad = this->MassFlowRate * Cp * (this->OutletTemp - this->InletTemp);
     439             :         }
     440     3261564 :         if (this->OutletTemp > LoopMaxTemp) {
     441           0 :             this->OutletTemp = min(this->OutletTemp, LoopMaxTemp);
     442           0 :             MyLoad = this->MassFlowRate * Cp * (this->OutletTemp - this->InletTemp);
     443             :         }
     444             :     } else {
     445     5394247 :         this->OutletTemp = this->InletTemp;
     446     5394247 :         MyLoad = 0.0;
     447             :     }
     448     7025029 :     int const OutletNode = this->OutletNodeNum;
     449     7025029 :     state.dataLoopNodes->Node(OutletNode).Temp = this->OutletTemp;
     450     7025029 :     this->EnergyRate = std::abs(MyLoad);
     451     7025029 :     this->EnergyTransfer = this->EnergyRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
     452     7025029 : }
     453             : 
     454         275 : void OutsideEnergySourceSpecs::oneTimeInit_new(EnergyPlusData &state)
     455             : {
     456             : 
     457             :     // Locate the unit on the plant loops for later usage
     458         275 :     bool errFlag = false;
     459         275 :     PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->EnergyType, this->plantLoc, errFlag, _, _, _, _, _);
     460         275 :     if (errFlag) {
     461           0 :         ShowFatalError(state, "InitSimVars: Program terminated due to previous condition(s).");
     462             :     }
     463             :     // set limits on outlet node temps to plant loop limits
     464         275 :     DataPlant::CompData::getPlantComponent(state, this->plantLoc).MinOutletTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinTemp;
     465         275 :     DataPlant::CompData::getPlantComponent(state, this->plantLoc).MaxOutletTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxTemp;
     466             :     // Register design flow rate for inlet node (helps to autosize comp setpoint op scheme flows
     467         275 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->InletNodeNum, state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MaxVolFlowRate);
     468             : 
     469             :     // this may need some help, if the objects change location later, due to a push_back,
     470             :     //  then the pointers to these output variables will be bad
     471             :     // for (int EnergySourceNum = 1; EnergySourceNum <= NumDistrictUnits; ++EnergySourceNum) {
     472         550 :     std::string hotOrChilled = "Hot ";
     473         550 :     std::string reportVarPrefix = "District Heating ";
     474         550 :     std::string heatingOrCooling = "Heating";
     475         275 :     std::string_view typeName = DataPlant::PlantEquipTypeNames[static_cast<int>(DataPlant::PlantEquipmentType::PurchHotWater)];
     476         275 :     if (this->EnergyType == DataPlant::PlantEquipmentType::PurchChilledWater) {
     477         132 :         hotOrChilled = "Chilled ";
     478         132 :         reportVarPrefix = "District Cooling ";
     479         132 :         heatingOrCooling = "Cooling";
     480         132 :         typeName = DataPlant::PlantEquipTypeNames[static_cast<int>(DataPlant::PlantEquipmentType::PurchChilledWater)];
     481             :     }
     482         825 :     SetupOutputVariable(state,
     483         550 :                         reportVarPrefix + hotOrChilled + "Water Energy",
     484             :                         OutputProcessor::Unit::J,
     485             :                         this->EnergyTransfer,
     486             :                         OutputProcessor::SOVTimeStepType::System,
     487             :                         OutputProcessor::SOVStoreType::Summed,
     488             :                         this->Name,
     489             :                         _,
     490             :                         typeName,
     491             :                         heatingOrCooling,
     492             :                         _,
     493             :                         "Plant");
     494         825 :     SetupOutputVariable(state,
     495         550 :                         reportVarPrefix + hotOrChilled + "Water Rate",
     496             :                         OutputProcessor::Unit::W,
     497             :                         this->EnergyRate,
     498             :                         OutputProcessor::SOVTimeStepType::System,
     499             :                         OutputProcessor::SOVStoreType::Average,
     500             :                         this->Name);
     501             : 
     502         825 :     SetupOutputVariable(state,
     503         550 :                         reportVarPrefix + "Rate",
     504             :                         OutputProcessor::Unit::W,
     505             :                         this->EnergyRate,
     506             :                         OutputProcessor::SOVTimeStepType::System,
     507             :                         OutputProcessor::SOVStoreType::Average,
     508             :                         this->Name);
     509         825 :     SetupOutputVariable(state,
     510         550 :                         reportVarPrefix + "Inlet Temperature",
     511             :                         OutputProcessor::Unit::C,
     512             :                         this->InletTemp,
     513             :                         OutputProcessor::SOVTimeStepType::System,
     514             :                         OutputProcessor::SOVStoreType::Average,
     515             :                         this->Name);
     516         825 :     SetupOutputVariable(state,
     517         550 :                         reportVarPrefix + "Outlet Temperature",
     518             :                         OutputProcessor::Unit::C,
     519             :                         this->OutletTemp,
     520             :                         OutputProcessor::SOVTimeStepType::System,
     521             :                         OutputProcessor::SOVStoreType::Average,
     522             :                         this->Name);
     523         825 :     SetupOutputVariable(state,
     524         550 :                         reportVarPrefix + "Mass Flow Rate",
     525             :                         OutputProcessor::Unit::kg_s,
     526             :                         this->MassFlowRate,
     527             :                         OutputProcessor::SOVTimeStepType::System,
     528             :                         OutputProcessor::SOVStoreType::Average,
     529             :                         this->Name);
     530         275 : }
     531             : 
     532           0 : void OutsideEnergySourceSpecs::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
     533             : {
     534           0 : }
     535             : 
     536        2313 : } // namespace EnergyPlus::OutsideEnergySources

Generated by: LCOV version 1.13