Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, 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 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/Base.hh>
57 : #include <EnergyPlus/BranchNodeConnections.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataHVACGlobals.hh>
60 : #include <EnergyPlus/DataIPShortCuts.hh>
61 : #include <EnergyPlus/DataLoopNode.hh>
62 : #include <EnergyPlus/DataSizing.hh>
63 : #include <EnergyPlus/EMSManager.hh>
64 : #include <EnergyPlus/FluidProperties.hh>
65 : #include <EnergyPlus/General.hh>
66 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
67 : #include <EnergyPlus/NodeInputManager.hh>
68 : #include <EnergyPlus/OutputProcessor.hh>
69 : #include <EnergyPlus/PlantComponentTemperatureSources.hh>
70 : #include <EnergyPlus/PlantUtilities.hh>
71 : #include <EnergyPlus/ScheduleManager.hh>
72 : #include <EnergyPlus/UtilityRoutines.hh>
73 :
74 : namespace EnergyPlus {
75 :
76 : namespace PlantComponentTemperatureSources {
77 :
78 : // MODULE INFORMATION:
79 : // AUTHOR Edwin Lee
80 : // DATE WRITTEN November 2012
81 : // MODIFIED na
82 : // RE-ENGINEERED na
83 :
84 : // PURPOSE OF THIS MODULE:
85 : // This module simulates plant supply components which operate against a
86 : // predefined (but variable) boundary temperature.
87 :
88 : // METHODOLOGY EMPLOYED:
89 : // Called by PlantLoopEquipment, model accepts inputs, and calculates a
90 : // thermal response using new plant routines such as SetComponentFlowRate
91 :
92 0 : PlantComponent *WaterSourceSpecs::factory(EnergyPlusData &state, std::string const &objectName)
93 : {
94 0 : if (state.dataPlantCompTempSrc->getWaterSourceInput) {
95 0 : GetWaterSourceInput(state);
96 0 : state.dataPlantCompTempSrc->getWaterSourceInput = false;
97 : }
98 :
99 : // Now look for this particular pipe in the list
100 0 : for (auto &waterSource : state.dataPlantCompTempSrc->WaterSource) {
101 0 : if (waterSource.Name == objectName) {
102 0 : return &waterSource;
103 : }
104 : }
105 : // If we didn't find it, fatal
106 0 : ShowFatalError(state,
107 : format("LocalTemperatureSourceFactory: Error getting inputs for temperature source named: {}", objectName)); // LCOV_EXCL_LINE
108 : // Shut up the compiler
109 : return nullptr; // LCOV_EXCL_LINE
110 : }
111 :
112 2 : void WaterSourceSpecs::initialize(EnergyPlusData &state, Real64 &MyLoad)
113 : {
114 :
115 : // SUBROUTINE INFORMATION:
116 : // AUTHOR Edwin Lee
117 : // DATE WRITTEN November 2012
118 : // MODIFIED na
119 : // RE-ENGINEERED na
120 :
121 : // PURPOSE OF THIS SUBROUTINE:
122 : // This subroutine is for initializations of the water source objects
123 :
124 : // METHODOLOGY EMPLOYED:
125 : // Uses the status flags to trigger initializations.
126 :
127 : // SUBROUTINE PARAMETER DEFINITIONS:
128 : static constexpr std::string_view RoutineName("InitWaterSource");
129 :
130 2 : this->oneTimeInit(state);
131 :
132 : // Initialize critical Demand Side Variables at the beginning of each environment
133 2 : if (this->MyEnvironFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
134 :
135 1 : Real64 rho = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
136 1 : this->MassFlowRateMax = this->DesVolFlowRate * rho;
137 1 : PlantUtilities::InitComponentNodes(state, 0.0, this->MassFlowRateMax, this->InletNodeNum, this->OutletNodeNum);
138 :
139 1 : this->MyEnvironFlag = false;
140 : }
141 :
142 2 : if (!state.dataGlobal->BeginEnvrnFlag) {
143 0 : this->MyEnvironFlag = true;
144 : }
145 :
146 : // OK, so we can set up the inlet and boundary temperatures now
147 2 : this->InletTemp = state.dataLoopNodes->Node(this->InletNodeNum).Temp;
148 2 : if (this->tempSpecType == TempSpecType::Schedule) {
149 0 : this->BoundaryTemp = this->tempSpecSched->getCurrentVal();
150 : }
151 :
152 : // Calculate specific heat
153 2 : Real64 cp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).glycol->getSpecificHeat(state, this->BoundaryTemp, RoutineName);
154 :
155 : // Calculate deltaT
156 2 : Real64 delta_temp = this->BoundaryTemp - this->InletTemp;
157 :
158 : // If deltaT is zero then we cannot calculate a flow request, but we may still want one
159 : // If myload is greater than zero, then lets request full flow at the current temperature as it may still be meeting load
160 : // If myload is zero, we'll then request zero flow
161 : // If deltaT is non-zero then we can use the current load and deltaT to calculate a flow request:
162 : // If MyLoad is > 0 then we want to heat the loop
163 : // If MyLoad is < 0 then we want to cool the loop
164 : // Thus, given a fixed outlet temperature (the boundary temp, Tbnd), the eq is:
165 : // MyLoad = mdot * cp * (Tbnd - Tin)
166 : // re-arranging:
167 : // mdot = MyLoad / [cp * (Tbnd - Tin)]
168 : // If there is a deltaT, but no load, the mass flow request will go to zero anyway
169 2 : if (std::abs(delta_temp) < 0.001) {
170 0 : if (std::abs(MyLoad) < 0.001) {
171 0 : this->MassFlowRate = 0.0;
172 : } else {
173 0 : this->MassFlowRate = this->MassFlowRateMax;
174 : }
175 : } else {
176 2 : this->MassFlowRate = MyLoad / (cp * delta_temp);
177 : }
178 :
179 : // If the mdot is negative it means we can't help the load so we will want to just go to zero.
180 : // If the mdot is already zero, then well, we still want to go to zero
181 : // If the mdot is positive, just make sure we constrain it to the design value
182 2 : if (this->MassFlowRate < 0) {
183 0 : this->MassFlowRate = 0.0;
184 : } else {
185 2 : if (!this->EMSOverrideOnMassFlowRateMax) {
186 2 : this->MassFlowRate = min(this->MassFlowRate, this->MassFlowRateMax);
187 : } else {
188 0 : this->MassFlowRate = min(this->MassFlowRate, this->EMSOverrideValueMassFlowRateMax);
189 : }
190 : }
191 :
192 2 : PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, this->InletNodeNum, this->OutletNodeNum, this->plantLoc);
193 :
194 : // at this point the mass flow rate, inlet temp, and boundary temp structure vars have been updated
195 : // the calc routine will update the outlet temp and heat transfer rate/energies
196 2 : }
197 :
198 1 : void WaterSourceSpecs::setupOutputVars(EnergyPlusData &state)
199 : {
200 :
201 2 : SetupOutputVariable(state,
202 : "Plant Temperature Source Component Mass Flow Rate",
203 : Constant::Units::kg_s,
204 1 : this->MassFlowRate,
205 : OutputProcessor::TimeStepType::System,
206 : OutputProcessor::StoreType::Average,
207 1 : this->Name);
208 2 : SetupOutputVariable(state,
209 : "Plant Temperature Source Component Inlet Temperature",
210 : Constant::Units::C,
211 1 : this->InletTemp,
212 : OutputProcessor::TimeStepType::System,
213 : OutputProcessor::StoreType::Average,
214 1 : this->Name);
215 2 : SetupOutputVariable(state,
216 : "Plant Temperature Source Component Outlet Temperature",
217 : Constant::Units::C,
218 1 : this->OutletTemp,
219 : OutputProcessor::TimeStepType::System,
220 : OutputProcessor::StoreType::Average,
221 1 : this->Name);
222 2 : SetupOutputVariable(state,
223 : "Plant Temperature Source Component Source Temperature",
224 : Constant::Units::C,
225 1 : this->BoundaryTemp,
226 : OutputProcessor::TimeStepType::System,
227 : OutputProcessor::StoreType::Average,
228 1 : this->Name);
229 2 : SetupOutputVariable(state,
230 : "Plant Temperature Source Component Heat Transfer Rate",
231 : Constant::Units::W,
232 1 : this->HeatRate,
233 : OutputProcessor::TimeStepType::System,
234 : OutputProcessor::StoreType::Average,
235 1 : this->Name);
236 2 : SetupOutputVariable(state,
237 : "Plant Temperature Source Component Heat Transfer Energy",
238 : Constant::Units::J,
239 1 : this->HeatEnergy,
240 : OutputProcessor::TimeStepType::System,
241 : OutputProcessor::StoreType::Sum,
242 1 : this->Name);
243 1 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
244 0 : SetupEMSActuator(state,
245 : "PlantComponent:TemperatureSource",
246 : this->Name,
247 : "Maximum Mass Flow Rate",
248 : "[kg/s]",
249 0 : this->EMSOverrideOnMassFlowRateMax,
250 0 : this->EMSOverrideValueMassFlowRateMax);
251 : }
252 1 : }
253 :
254 0 : void WaterSourceSpecs::autosize(EnergyPlusData &state)
255 : {
256 :
257 : // SUBROUTINE INFORMATION:
258 : // AUTHOR Edwin Lee
259 : // DATE WRITTEN November 2012
260 : // MODIFIED November 2013 Daeho Kang, add component sizing table entries
261 : // RE-ENGINEERED na
262 :
263 : // PURPOSE OF THIS SUBROUTINE:
264 : // This subroutine is for sizing water source design flow rate
265 :
266 : // METHODOLOGY EMPLOYED:
267 : // Obtains flow rate from the plant sizing array.
268 :
269 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
270 0 : bool ErrorsFound(false); // If errors detected in input
271 : Real64 DesVolFlowRateUser; // Hardsized design volume flow rate for reporting
272 0 : Real64 tmpVolFlowRate = this->DesVolFlowRate;
273 0 : int PltSizNum = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).PlantSizNum;
274 :
275 0 : if (PltSizNum > 0) {
276 0 : if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
277 0 : tmpVolFlowRate = state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate; //* WaterSource(SourceNum)%SizFac
278 0 : if (!this->DesVolFlowRateWasAutoSized) tmpVolFlowRate = this->DesVolFlowRate;
279 : } else {
280 0 : if (this->DesVolFlowRateWasAutoSized) tmpVolFlowRate = 0.0;
281 : }
282 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
283 0 : if (this->DesVolFlowRateWasAutoSized) {
284 0 : this->DesVolFlowRate = tmpVolFlowRate;
285 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
286 0 : BaseSizer::reportSizerOutput(
287 : state, "PlantComponent:TemperatureSource", this->Name, "Design Size Design Fluid Flow Rate [m3/s]", tmpVolFlowRate);
288 : }
289 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
290 0 : BaseSizer::reportSizerOutput(state,
291 : "PlantComponent:TemperatureSource",
292 : this->Name,
293 : "Initial Design Size Design Fluid Flow Rate [m3/s]",
294 : tmpVolFlowRate);
295 : }
296 : } else {
297 0 : if (this->DesVolFlowRate > 0.0 && tmpVolFlowRate > 0.0) {
298 0 : DesVolFlowRateUser = this->DesVolFlowRate;
299 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
300 0 : BaseSizer::reportSizerOutput(state,
301 : "PlantComponent:TemperatureSource",
302 : this->Name,
303 : "Design Size Design Fluid Flow Rate [m3/s]",
304 : tmpVolFlowRate,
305 : "User-Specified Design Fluid Flow Rate [m3/s]",
306 : DesVolFlowRateUser);
307 0 : if (state.dataGlobal->DisplayExtraWarnings) {
308 0 : if ((std::abs(tmpVolFlowRate - DesVolFlowRateUser) / DesVolFlowRateUser) >
309 0 : state.dataSize->AutoVsHardSizingThreshold) {
310 0 : ShowMessage(
311 : state,
312 0 : format("SizePlantComponentTemperatureSource: Potential issue with equipment sizing for {}", this->Name));
313 0 : ShowContinueError(state, format("User-Specified Design Fluid Flow Rate of {:.5R} [m3/s]", DesVolFlowRateUser));
314 0 : ShowContinueError(state,
315 0 : format("differs from Design Size Design Fluid Flow Rate of {:.5R} [m3/s]", tmpVolFlowRate));
316 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
317 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
318 : }
319 : }
320 : }
321 0 : tmpVolFlowRate = DesVolFlowRateUser;
322 : }
323 : }
324 : }
325 : } else {
326 0 : if (this->DesVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
327 0 : ShowSevereError(state, "Autosizing of plant component temperature source flow rate requires a loop Sizing:Plant object");
328 0 : ShowContinueError(state, format("Occurs in PlantComponent:TemperatureSource object={}", this->Name));
329 0 : ErrorsFound = true;
330 : }
331 0 : if (!this->DesVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport) {
332 0 : if (this->DesVolFlowRate > 0.0) {
333 0 : BaseSizer::reportSizerOutput(
334 : state, "PlantComponent:TemperatureSource", this->Name, "User-Specified Design Fluid Flow Rate [m3/s]", this->DesVolFlowRate);
335 : }
336 : }
337 : }
338 :
339 0 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->InletNodeNum, tmpVolFlowRate);
340 :
341 0 : if (ErrorsFound) {
342 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
343 : }
344 0 : }
345 :
346 2 : void WaterSourceSpecs::calculate(EnergyPlusData &state)
347 : {
348 :
349 : // SUBROUTINE INFORMATION:
350 : // AUTHOR Edwin Lee
351 : // DATE WRITTEN October 2012
352 : // MODIFIED na
353 : // RE-ENGINEERED na
354 :
355 : static constexpr std::string_view RoutineName("CalcWaterSource");
356 :
357 2 : if (this->MassFlowRate > 0.0) {
358 1 : this->OutletTemp = this->BoundaryTemp;
359 1 : Real64 Cp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).glycol->getSpecificHeat(state, this->BoundaryTemp, RoutineName);
360 1 : this->HeatRate = this->MassFlowRate * Cp * (this->OutletTemp - this->InletTemp);
361 1 : this->HeatEnergy = this->HeatRate * state.dataHVACGlobal->TimeStepSysSec;
362 : } else {
363 1 : this->OutletTemp = this->BoundaryTemp;
364 1 : this->HeatRate = 0.0;
365 1 : this->HeatEnergy = 0.0;
366 : }
367 2 : }
368 :
369 2 : void WaterSourceSpecs::update(EnergyPlusData &state)
370 : {
371 2 : state.dataLoopNodes->Node(this->OutletNodeNum).Temp = this->OutletTemp;
372 2 : }
373 :
374 2 : void WaterSourceSpecs::simulate(EnergyPlusData &state,
375 : [[maybe_unused]] const PlantLocation &calledFromLocation,
376 : [[maybe_unused]] bool FirstHVACIteration,
377 : Real64 &CurLoad,
378 : [[maybe_unused]] bool RunFlag)
379 : {
380 2 : this->initialize(state, CurLoad);
381 2 : this->calculate(state);
382 2 : this->update(state);
383 2 : }
384 :
385 0 : void WaterSourceSpecs::getDesignCapacities(
386 : [[maybe_unused]] EnergyPlusData &state, const EnergyPlus::PlantLocation &, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
387 : {
388 :
389 0 : MaxLoad = Constant::BigNumber;
390 0 : MinLoad = 0.0;
391 0 : OptLoad = Constant::BigNumber;
392 0 : }
393 :
394 0 : void WaterSourceSpecs::getSizingFactor(Real64 &_SizFac)
395 : {
396 0 : _SizFac = this->SizFac;
397 0 : }
398 :
399 0 : void WaterSourceSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &)
400 : {
401 0 : Real64 myLoad = 0.0;
402 0 : this->initialize(state, myLoad);
403 0 : this->autosize(state);
404 0 : }
405 2 : void WaterSourceSpecs::oneTimeInit(EnergyPlusData &state)
406 : {
407 4 : static std::string const RoutineName("InitWaterSource");
408 :
409 2 : if (this->MyFlag) {
410 : // setup output variables once here
411 1 : this->setupOutputVars(state);
412 : // Locate the component on the plant loops for later usage
413 1 : bool errFlag = false;
414 3 : PlantUtilities::ScanPlantLoopsForObject(
415 2 : state, this->Name, DataPlant::PlantEquipmentType::WaterSource, this->plantLoc, errFlag, _, _, _, this->InletNodeNum, _);
416 1 : if (errFlag) {
417 0 : ShowFatalError(state, format("{}: Program terminated due to previous condition(s).", RoutineName));
418 : }
419 1 : this->MyFlag = false;
420 : }
421 2 : }
422 :
423 1 : void GetWaterSourceInput(EnergyPlusData &state)
424 : {
425 :
426 : // SUBROUTINE INFORMATION:
427 : // AUTHOR: Edwin Lee
428 : // DATE WRITTEN: October 2012
429 :
430 : // PURPOSE OF THIS SUBROUTINE:
431 : // This routine gets the inputs and processes them into local data structures
432 :
433 : // METHODOLOGY EMPLOYED:
434 : // Standard E+ input processor interaction
435 :
436 : // REFERENCES:
437 : // WaterSource,
438 : // A1 , \field Name
439 : // A2 , \field Inlet Node
440 : // A3 , \field Outlet Node
441 : // N1 , \field Design Volume Flow Rate
442 : // A4 , \field Temperature Specification Type
443 : // N2 , \field Boundary Temperature
444 : // A5 ; \field Source Temperature Schedule Name
445 :
446 : static constexpr std::string_view routineName = "GetWaterSourceInput";
447 :
448 : // LOCAL VARIABLES:
449 : int NumAlphas; // Number of elements in the alpha array
450 : int NumNums; // Number of elements in the numeric array
451 : int IOStat; // IO Status when calling get input subroutine
452 1 : bool ErrorsFound(false);
453 1 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
454 :
455 : // GET NUMBER OF ALL EQUIPMENT TYPES
456 1 : cCurrentModuleObject = "PlantComponent:TemperatureSource";
457 1 : state.dataPlantCompTempSrc->NumSources = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
458 :
459 1 : if (state.dataPlantCompTempSrc->NumSources <= 0) {
460 0 : ShowSevereError(state, format("No {} equipment specified in input file", cCurrentModuleObject));
461 0 : ErrorsFound = true;
462 : }
463 :
464 : // See if load distribution manager has already gotten the input
465 1 : if (allocated(state.dataPlantCompTempSrc->WaterSource)) return; // probably not possible, and probably should throw error
466 1 : state.dataPlantCompTempSrc->WaterSource.allocate(state.dataPlantCompTempSrc->NumSources);
467 :
468 : // fill arrays
469 2 : for (int SourceNum = 1; SourceNum <= state.dataPlantCompTempSrc->NumSources; ++SourceNum) {
470 3 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
471 : cCurrentModuleObject,
472 : SourceNum,
473 1 : state.dataIPShortCut->cAlphaArgs,
474 : NumAlphas,
475 1 : state.dataIPShortCut->rNumericArgs,
476 : NumNums,
477 : IOStat,
478 : _,
479 1 : state.dataIPShortCut->lAlphaFieldBlanks,
480 1 : state.dataIPShortCut->cAlphaFieldNames,
481 1 : state.dataIPShortCut->cNumericFieldNames);
482 :
483 1 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
484 :
485 1 : Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
486 :
487 1 : state.dataPlantCompTempSrc->WaterSource(SourceNum).Name = state.dataIPShortCut->cAlphaArgs(1);
488 :
489 1 : state.dataPlantCompTempSrc->WaterSource(SourceNum).InletNodeNum =
490 2 : NodeInputManager::GetOnlySingleNode(state,
491 1 : state.dataIPShortCut->cAlphaArgs(2),
492 : ErrorsFound,
493 : DataLoopNode::ConnectionObjectType::PlantComponentTemperatureSource,
494 1 : state.dataIPShortCut->cAlphaArgs(1),
495 : DataLoopNode::NodeFluidType::Water,
496 : DataLoopNode::ConnectionType::Inlet,
497 : NodeInputManager::CompFluidStream::Primary,
498 : DataLoopNode::ObjectIsNotParent);
499 1 : state.dataPlantCompTempSrc->WaterSource(SourceNum).OutletNodeNum =
500 3 : NodeInputManager::GetOnlySingleNode(state,
501 1 : state.dataIPShortCut->cAlphaArgs(3),
502 : ErrorsFound,
503 : DataLoopNode::ConnectionObjectType::PlantComponentTemperatureSource,
504 1 : state.dataIPShortCut->cAlphaArgs(1),
505 : DataLoopNode::NodeFluidType::Water,
506 : DataLoopNode::ConnectionType::Outlet,
507 : NodeInputManager::CompFluidStream::Primary,
508 : DataLoopNode::ObjectIsNotParent);
509 2 : BranchNodeConnections::TestCompSet(state,
510 : cCurrentModuleObject,
511 1 : state.dataIPShortCut->cAlphaArgs(1),
512 1 : state.dataIPShortCut->cAlphaArgs(2),
513 1 : state.dataIPShortCut->cAlphaArgs(3),
514 : "Chilled Water Nodes");
515 :
516 1 : state.dataPlantCompTempSrc->WaterSource(SourceNum).DesVolFlowRate = state.dataIPShortCut->rNumericArgs(1);
517 1 : if (state.dataPlantCompTempSrc->WaterSource(SourceNum).DesVolFlowRate == DataSizing::AutoSize) {
518 0 : state.dataPlantCompTempSrc->WaterSource(SourceNum).DesVolFlowRateWasAutoSized = true;
519 : }
520 :
521 1 : if (state.dataIPShortCut->cAlphaArgs(4) == "CONSTANT") {
522 1 : state.dataPlantCompTempSrc->WaterSource(SourceNum).tempSpecType = TempSpecType::Constant;
523 1 : state.dataPlantCompTempSrc->WaterSource(SourceNum).BoundaryTemp = state.dataIPShortCut->rNumericArgs(2);
524 0 : } else if (state.dataIPShortCut->cAlphaArgs(4) == "SCHEDULED") {
525 0 : state.dataPlantCompTempSrc->WaterSource(SourceNum).tempSpecType = TempSpecType::Schedule;
526 0 : if ((state.dataPlantCompTempSrc->WaterSource(SourceNum).tempSpecSched =
527 0 : Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(5))) == nullptr) {
528 0 : ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5));
529 0 : ErrorsFound = true;
530 : }
531 : } else {
532 0 : ShowSevereError(state, format("Input error for {}={}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
533 0 : ShowContinueError(state,
534 0 : format(R"(Invalid temperature specification type. Expected either "Constant" or "Scheduled". Encountered {})",
535 0 : state.dataIPShortCut->cAlphaArgs(4)));
536 0 : ErrorsFound = true;
537 : }
538 : }
539 :
540 1 : if (ErrorsFound) {
541 0 : ShowFatalError(state, format("Errors found in processing input for {}", cCurrentModuleObject));
542 : }
543 : }
544 :
545 : } // namespace PlantComponentTemperatureSources
546 :
547 : } // namespace EnergyPlus
|