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