Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, 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 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/BranchNodeConnections.hh>
56 : #include <EnergyPlus/Data/EnergyPlusData.hh>
57 : #include <EnergyPlus/DataEnvironment.hh>
58 : #include <EnergyPlus/DataHVACGlobals.hh>
59 : #include <EnergyPlus/DataIPShortCuts.hh>
60 : #include <EnergyPlus/DataLoopNode.hh>
61 : #include <EnergyPlus/EMSManager.hh>
62 : #include <EnergyPlus/FluidProperties.hh>
63 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
64 : #include <EnergyPlus/NodeInputManager.hh>
65 : #include <EnergyPlus/OutputProcessor.hh>
66 : #include <EnergyPlus/Plant/DataPlant.hh>
67 : #include <EnergyPlus/PlantLoadProfile.hh>
68 : #include <EnergyPlus/PlantUtilities.hh>
69 : #include <EnergyPlus/ScheduleManager.hh>
70 : #include <EnergyPlus/UtilityRoutines.hh>
71 :
72 : namespace EnergyPlus::PlantLoadProfile {
73 :
74 : // MODULE INFORMATION:
75 : // AUTHOR Peter Graham Ellis
76 : // DATE WRITTEN January 2004
77 : // MODIFIED Brent Griffith, plant rewrite, general fluid types
78 : // allow flow requests with out load requests
79 : // RE-ENGINEERED na
80 :
81 : // PURPOSE OF THIS MODULE:
82 : // This module simulates a scheduled load profile on the demand side of the plant loop.
83 :
84 : // METHODOLOGY EMPLOYED:
85 : // The plant load profile object provides a scheduled load on the plant loop. Unlike most plant equipment
86 : // on the demand side, i.e. zone equipment, this object does not have a zone associated with it.
87 : // For this reason the plant load profile can only be called for simulation by the non-zone equipment
88 : // manager (see NonZoneEquipmentManager.cc).
89 :
90 : constexpr std::array<std::string_view, static_cast<int>(PlantLoopFluidType::Num)> PlantLoopFluidTypeNamesUC{"WATER", "STEAM"};
91 :
92 28 : PlantComponent *PlantProfileData::factory(EnergyPlusData &state, std::string const &objectName)
93 : {
94 28 : if (state.dataPlantLoadProfile->GetPlantLoadProfileInputFlag) {
95 23 : GetPlantProfileInput(state);
96 23 : state.dataPlantLoadProfile->GetPlantLoadProfileInputFlag = false;
97 : }
98 : // Now look for this particular pipe in the list
99 33 : for (auto &plp : state.dataPlantLoadProfile->PlantProfile) {
100 33 : if (plp.Name == objectName) {
101 28 : return &plp;
102 : }
103 : }
104 : // If we didn't find it, fatal
105 0 : ShowFatalError(state, format("PlantLoadProfile::factory: Error getting inputs for pipe named: {}", objectName));
106 : // Shut up the compiler
107 0 : return nullptr;
108 : }
109 :
110 140 : void PlantProfileData::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
111 : {
112 140 : this->InitPlantProfile(state);
113 140 : }
114 :
115 121688 : void PlantProfileData::simulate(EnergyPlusData &state,
116 : [[maybe_unused]] const PlantLocation &calledFromLocation,
117 : [[maybe_unused]] bool const FirstHVACIteration,
118 : [[maybe_unused]] Real64 &CurLoad,
119 : [[maybe_unused]] bool const RunFlag)
120 : {
121 :
122 : // SUBROUTINE INFORMATION:
123 : // AUTHOR Peter Graham Ellis
124 : // DATE WRITTEN January 2004
125 : // MODIFIED Brent Griffith, generalize fluid cp
126 : // June 2021, Dareum Nam, Add steam loop version
127 : // RE-ENGINEERED na
128 :
129 : // PURPOSE OF THIS SUBROUTINE:
130 : // Simulates the plant load profile object.
131 :
132 : // METHODOLOGY EMPLOYED:
133 : // This is a very simple simulation. InitPlantProfile does the work of getting the scheduled load and flow rate.
134 : // Flow is requested and the actual available flow is set. As for water loops, the outlet temperature is calculated. As for steam loops, the mass
135 : // flow rate of steam and the outlet temperature are calculated.
136 :
137 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
138 : static constexpr std::string_view RoutineName("SimulatePlantProfile");
139 : Real64 DeltaTemp;
140 :
141 121688 : this->InitPlantProfile(state);
142 :
143 121688 : if (this->FluidType == PlantLoopFluidType::Water) {
144 116319 : if (this->MassFlowRate > 0.0) {
145 102842 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
146 102842 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
147 : this->InletTemp,
148 102842 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
149 : RoutineName);
150 102842 : DeltaTemp = this->Power / (this->MassFlowRate * Cp);
151 : } else {
152 13477 : this->Power = 0.0;
153 13477 : DeltaTemp = 0.0;
154 : }
155 116319 : this->OutletTemp = this->InletTemp - DeltaTemp;
156 5369 : } else if (this->FluidType == PlantLoopFluidType::Steam) {
157 5369 : if (this->MassFlowRate > 0.0 && this->Power > 0.0) {
158 4763 : Real64 EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(state,
159 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
160 : this->InletTemp,
161 : 1.0,
162 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
163 : RoutineName);
164 4763 : Real64 EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(state,
165 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
166 : this->InletTemp,
167 : 0.0,
168 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
169 : RoutineName);
170 4763 : Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
171 4763 : Real64 SatTemp = FluidProperties::GetSatTemperatureRefrig(state,
172 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
173 : DataEnvironment::StdPressureSeaLevel,
174 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
175 : RoutineName);
176 4763 : Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(state,
177 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
178 : SatTemp,
179 4763 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
180 : RoutineName);
181 :
182 : // Steam Mass Flow Rate Required
183 4763 : this->MassFlowRate = this->Power / (LatentHeatSteam + this->DegOfSubcooling * CpWater);
184 4763 : PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, this->InletNode, this->OutletNode, this->plantLoc);
185 4763 : state.dataLoopNodes->Node(this->OutletNode).Quality = 0.0;
186 : // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
187 : // This is required for outlet water temperature, otherwise it will be saturation temperature.
188 : // Steam Trap drains off all the Water formed.
189 : // Here Degree of Subcooling is used to calculate hot water return temperature.
190 :
191 : // Calculating Condensate outlet temperature
192 4763 : this->OutletTemp = SatTemp - this->LoopSubcoolReturn;
193 4763 : } else {
194 606 : this->Power = 0.0;
195 : }
196 : }
197 :
198 121688 : this->UpdatePlantProfile(state);
199 121688 : this->ReportPlantProfile(state);
200 :
201 121688 : } // simulate()
202 :
203 121828 : void PlantProfileData::InitPlantProfile(EnergyPlusData &state)
204 : {
205 :
206 : // SUBROUTINE INFORMATION:
207 : // AUTHOR Peter Graham Ellis
208 : // DATE WRITTEN January 2004
209 : // MODIFIED na
210 : // RE-ENGINEERED na
211 :
212 : // PURPOSE OF THIS SUBROUTINE:
213 : // Initializes the plant load profile object during the plant simulation.
214 :
215 : // METHODOLOGY EMPLOYED:
216 : // Inlet and outlet nodes are initialized. The scheduled load and flow rate is obtained, flow is requested, and the
217 : // actual available flow is set.
218 :
219 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
220 : static constexpr std::string_view RoutineName("InitPlantProfile");
221 : Real64 FluidDensityInit;
222 :
223 : // Do the one time initializations
224 :
225 121828 : if (!state.dataGlobal->SysSizingCalc && this->InitSizing) {
226 28 : PlantUtilities::RegisterPlantCompDesignFlow(state, InletNode, this->PeakVolFlowRate);
227 28 : this->InitSizing = false;
228 : }
229 :
230 121828 : if (state.dataGlobal->BeginEnvrnFlag && this->Init) {
231 : // Clear node initial conditions
232 132 : state.dataLoopNodes->Node(OutletNode).Temp = 0.0;
233 :
234 132 : if (this->FluidType == PlantLoopFluidType::Water) {
235 127 : FluidDensityInit = FluidProperties::GetDensityGlycol(state,
236 127 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
237 : Constant::InitConvTemp,
238 127 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
239 : RoutineName);
240 : } else { //(this->FluidType == PlantLoopFluidType::Steam)
241 5 : Real64 SatTempAtmPress = FluidProperties::GetSatTemperatureRefrig(state,
242 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
243 : DataEnvironment::StdPressureSeaLevel,
244 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
245 : RoutineName);
246 5 : FluidDensityInit = FluidProperties::GetSatDensityRefrig(state,
247 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
248 : SatTempAtmPress,
249 : 1.0,
250 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
251 : RoutineName);
252 : }
253 :
254 132 : Real64 MaxFlowMultiplier = ScheduleManager::GetScheduleMaxValue(state, this->FlowRateFracSchedule);
255 :
256 132 : PlantUtilities::InitComponentNodes(
257 132 : state, 0.0, this->PeakVolFlowRate * FluidDensityInit * MaxFlowMultiplier, this->InletNode, this->OutletNode);
258 :
259 132 : this->EMSOverrideMassFlow = false;
260 132 : this->EMSMassFlowValue = 0.0;
261 132 : this->EMSOverridePower = false;
262 132 : this->EMSPowerValue = 0.0;
263 132 : this->Init = false;
264 : }
265 :
266 121828 : if (!state.dataGlobal->BeginEnvrnFlag) this->Init = true;
267 :
268 121828 : this->InletTemp = state.dataLoopNodes->Node(InletNode).Temp;
269 121828 : this->Power = ScheduleManager::GetCurrentScheduleValue(state, this->LoadSchedule);
270 :
271 121828 : if (this->EMSOverridePower) this->Power = this->EMSPowerValue;
272 :
273 121828 : if (this->FluidType == PlantLoopFluidType::Water) {
274 116454 : FluidDensityInit = FluidProperties::GetDensityGlycol(state,
275 116454 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
276 : this->InletTemp,
277 116454 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
278 : RoutineName);
279 : } else { //(this->FluidType == PlantLoopFluidType::Steam)
280 5374 : FluidDensityInit = FluidProperties::GetSatDensityRefrig(state,
281 5374 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
282 : this->InletTemp,
283 : 1.0,
284 5374 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
285 : RoutineName);
286 : }
287 :
288 : // Get the scheduled mass flow rate
289 121828 : this->VolFlowRate = this->PeakVolFlowRate * ScheduleManager::GetCurrentScheduleValue(state, this->FlowRateFracSchedule);
290 :
291 121828 : this->MassFlowRate = this->VolFlowRate * FluidDensityInit;
292 :
293 121828 : if (this->EMSOverrideMassFlow) this->MassFlowRate = this->EMSMassFlowValue;
294 :
295 : // Request the mass flow rate from the plant component flow utility routine
296 121828 : PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, InletNode, OutletNode, this->plantLoc);
297 :
298 121828 : this->VolFlowRate = this->MassFlowRate / FluidDensityInit;
299 :
300 121828 : } // InitPlantProfile()
301 :
302 121688 : void PlantProfileData::UpdatePlantProfile(EnergyPlusData &state) const
303 : {
304 :
305 : // SUBROUTINE INFORMATION:
306 : // AUTHOR Peter Graham Ellis
307 : // DATE WRITTEN January 2004
308 : // MODIFIED na
309 : // RE-ENGINEERED na
310 :
311 : // PURPOSE OF THIS SUBROUTINE:
312 : // Updates the node variables with local variables.
313 :
314 : // Set outlet node variables that are possibly changed
315 121688 : state.dataLoopNodes->Node(this->OutletNode).Temp = this->OutletTemp;
316 121688 : }
317 :
318 121688 : void PlantProfileData::ReportPlantProfile(EnergyPlusData &state)
319 : {
320 :
321 : // SUBROUTINE INFORMATION:
322 : // AUTHOR Peter Graham Ellis
323 : // DATE WRITTEN January 2004
324 : // MODIFIED na
325 : // RE-ENGINEERED na
326 :
327 : // PURPOSE OF THIS SUBROUTINE:
328 : // Calculates report variables.
329 :
330 : // Using/Aliasing
331 121688 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
332 :
333 121688 : this->Energy = this->Power * TimeStepSysSec;
334 :
335 121688 : if (this->Energy >= 0.0) {
336 90412 : this->HeatingEnergy = this->Energy;
337 90412 : this->CoolingEnergy = 0.0;
338 : } else {
339 31276 : this->HeatingEnergy = 0.0;
340 31276 : this->CoolingEnergy = std::abs(this->Energy);
341 : }
342 121688 : }
343 28 : void PlantProfileData::oneTimeInit_new(EnergyPlusData &state)
344 : {
345 : bool errFlag;
346 :
347 28 : if (allocated(state.dataPlnt->PlantLoop)) {
348 28 : errFlag = false;
349 28 : PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->Type, this->plantLoc, errFlag, _, _, _, _, _);
350 28 : if (errFlag) {
351 0 : ShowFatalError(state, "InitPlantProfile: Program terminated for previous conditions.");
352 : }
353 : }
354 28 : }
355 0 : void PlantProfileData::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
356 : {
357 0 : }
358 :
359 0 : void PlantProfileData::getCurrentPower([[maybe_unused]] EnergyPlusData &state, Real64 &power)
360 : {
361 0 : power = this->Power;
362 0 : return;
363 : }
364 :
365 : // Functions
366 23 : void GetPlantProfileInput(EnergyPlusData &state)
367 : {
368 :
369 : // SUBROUTINE INFORMATION:
370 : // AUTHOR Peter Graham Ellis
371 : // DATE WRITTEN January 2004
372 : // MODIFIED June 2021, Dareum Nam, Add steam loop version
373 : // RE-ENGINEERED na
374 :
375 : // PURPOSE OF THIS SUBROUTINE:
376 : // Gets the plant load profile input from the input file and sets up the objects.
377 :
378 : // Using/Aliasing
379 : using namespace DataLoopNode;
380 :
381 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
382 23 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
383 : int IOStatus; // Used in GetObjectItem
384 : int NumAlphas; // Number of Alphas for each GetObjectItem call
385 : int NumNumbers; // Number of Numbers for each GetObjectItem call
386 : int ProfileNum; // PLANT LOAD PROFILE (PlantProfile) object number
387 23 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
388 :
389 23 : cCurrentModuleObject = "LoadProfile:Plant";
390 23 : state.dataPlantLoadProfile->NumOfPlantProfile = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
391 :
392 23 : if (state.dataPlantLoadProfile->NumOfPlantProfile > 0) {
393 23 : state.dataPlantLoadProfile->PlantProfile.allocate(state.dataPlantLoadProfile->NumOfPlantProfile);
394 :
395 51 : for (ProfileNum = 1; ProfileNum <= state.dataPlantLoadProfile->NumOfPlantProfile; ++ProfileNum) {
396 84 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
397 : cCurrentModuleObject,
398 : ProfileNum,
399 28 : state.dataIPShortCut->cAlphaArgs,
400 : NumAlphas,
401 28 : state.dataIPShortCut->rNumericArgs,
402 : NumNumbers,
403 : IOStatus,
404 28 : state.dataIPShortCut->lNumericFieldBlanks,
405 : _,
406 28 : state.dataIPShortCut->cAlphaFieldNames,
407 28 : state.dataIPShortCut->cNumericFieldNames);
408 28 : Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
409 :
410 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name = state.dataIPShortCut->cAlphaArgs(1);
411 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Type =
412 : DataPlant::PlantEquipmentType::PlantLoadProfile; // parameter assigned in DataPlant
413 :
414 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType =
415 56 : static_cast<PlantLoopFluidType>(getEnumValue(PlantLoopFluidTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(6))));
416 28 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Invalid) {
417 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType = PlantLoopFluidType::Water;
418 : }
419 :
420 28 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Water) {
421 27 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).InletNode =
422 54 : NodeInputManager::GetOnlySingleNode(state,
423 27 : state.dataIPShortCut->cAlphaArgs(2),
424 : ErrorsFound,
425 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
426 27 : state.dataIPShortCut->cAlphaArgs(1),
427 : DataLoopNode::NodeFluidType::Water,
428 : DataLoopNode::ConnectionType::Inlet,
429 : NodeInputManager::CompFluidStream::Primary,
430 : ObjectIsNotParent);
431 27 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).OutletNode =
432 81 : NodeInputManager::GetOnlySingleNode(state,
433 27 : state.dataIPShortCut->cAlphaArgs(3),
434 : ErrorsFound,
435 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
436 27 : state.dataIPShortCut->cAlphaArgs(1),
437 : DataLoopNode::NodeFluidType::Water,
438 : DataLoopNode::ConnectionType::Outlet,
439 : NodeInputManager::CompFluidStream::Primary,
440 : ObjectIsNotParent);
441 : } else { // state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Steam
442 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).InletNode =
443 2 : NodeInputManager::GetOnlySingleNode(state,
444 1 : state.dataIPShortCut->cAlphaArgs(2),
445 : ErrorsFound,
446 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
447 1 : state.dataIPShortCut->cAlphaArgs(1),
448 : DataLoopNode::NodeFluidType::Steam,
449 : DataLoopNode::ConnectionType::Inlet,
450 : NodeInputManager::CompFluidStream::Primary,
451 : ObjectIsNotParent);
452 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).OutletNode =
453 3 : NodeInputManager::GetOnlySingleNode(state,
454 1 : state.dataIPShortCut->cAlphaArgs(3),
455 : ErrorsFound,
456 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
457 1 : state.dataIPShortCut->cAlphaArgs(1),
458 : DataLoopNode::NodeFluidType::Steam,
459 : DataLoopNode::ConnectionType::Outlet,
460 : NodeInputManager::CompFluidStream::Primary,
461 : ObjectIsNotParent);
462 : }
463 :
464 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).LoadSchedule =
465 28 : ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(4));
466 :
467 28 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).LoadSchedule == 0) {
468 0 : ShowSevereError(state,
469 0 : format("{}=\"{}\" The Schedule for {} called {} was not found.",
470 : cCurrentModuleObject,
471 0 : state.dataIPShortCut->cAlphaArgs(1),
472 0 : state.dataIPShortCut->cAlphaFieldNames(4),
473 0 : state.dataIPShortCut->cAlphaArgs(4)));
474 0 : ErrorsFound = true;
475 : }
476 :
477 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).PeakVolFlowRate = state.dataIPShortCut->rNumericArgs(1);
478 :
479 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).FlowRateFracSchedule =
480 28 : ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(5));
481 :
482 28 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FlowRateFracSchedule == 0) {
483 0 : ShowSevereError(state,
484 0 : format("{}=\"{}\" The Schedule for {} called {} was not found.",
485 : cCurrentModuleObject,
486 0 : state.dataIPShortCut->cAlphaArgs(1),
487 0 : state.dataIPShortCut->cAlphaFieldNames(5),
488 0 : state.dataIPShortCut->cAlphaArgs(5)));
489 :
490 0 : ErrorsFound = true;
491 : }
492 :
493 28 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Steam) {
494 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(2)) {
495 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).DegOfSubcooling = state.dataIPShortCut->rNumericArgs(2);
496 : } else {
497 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).DegOfSubcooling = 5.0; // default value
498 : }
499 :
500 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(3)) {
501 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).LoopSubcoolReturn = state.dataIPShortCut->rNumericArgs(3);
502 : } else {
503 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).LoopSubcoolReturn = 20.0; // default value
504 : }
505 : }
506 :
507 : // Check plant connections
508 28 : BranchNodeConnections::TestCompSet(state,
509 : cCurrentModuleObject,
510 28 : state.dataIPShortCut->cAlphaArgs(1),
511 28 : state.dataIPShortCut->cAlphaArgs(2),
512 28 : state.dataIPShortCut->cAlphaArgs(3),
513 56 : cCurrentModuleObject + " Nodes");
514 :
515 : // Setup report variables
516 56 : SetupOutputVariable(state,
517 : "Plant Load Profile Mass Flow Rate",
518 : Constant::Units::kg_s,
519 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).MassFlowRate,
520 : OutputProcessor::TimeStepType::System,
521 : OutputProcessor::StoreType::Average,
522 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name);
523 :
524 56 : SetupOutputVariable(state,
525 : "Plant Load Profile Heat Transfer Rate",
526 : Constant::Units::W,
527 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Power,
528 : OutputProcessor::TimeStepType::System,
529 : OutputProcessor::StoreType::Average,
530 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name);
531 :
532 56 : SetupOutputVariable(state,
533 : "Plant Load Profile Heat Transfer Energy",
534 : Constant::Units::J,
535 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Energy,
536 : OutputProcessor::TimeStepType::System,
537 : OutputProcessor::StoreType::Sum,
538 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
539 : Constant::eResource::EnergyTransfer,
540 : OutputProcessor::Group::Plant,
541 : OutputProcessor::EndUseCat::Heating); // is EndUseKey right?
542 :
543 56 : SetupOutputVariable(state,
544 : "Plant Load Profile Heating Energy",
545 : Constant::Units::J,
546 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).HeatingEnergy,
547 : OutputProcessor::TimeStepType::System,
548 : OutputProcessor::StoreType::Sum,
549 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
550 : Constant::eResource::PlantLoopHeatingDemand,
551 : OutputProcessor::Group::Plant,
552 : OutputProcessor::EndUseCat::Heating);
553 :
554 56 : SetupOutputVariable(state,
555 : "Plant Load Profile Cooling Energy",
556 : Constant::Units::J,
557 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).CoolingEnergy,
558 : OutputProcessor::TimeStepType::System,
559 : OutputProcessor::StoreType::Sum,
560 28 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
561 : Constant::eResource::PlantLoopCoolingDemand,
562 : OutputProcessor::Group::Plant,
563 : OutputProcessor::EndUseCat::Cooling);
564 :
565 28 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
566 0 : SetupEMSActuator(state,
567 : "Plant Load Profile",
568 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
569 : "Mass Flow Rate",
570 : "[kg/s]",
571 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSOverrideMassFlow,
572 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSMassFlowValue);
573 0 : SetupEMSActuator(state,
574 : "Plant Load Profile",
575 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
576 : "Power",
577 : "[W]",
578 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSOverridePower,
579 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSPowerValue);
580 : }
581 :
582 28 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Steam) {
583 2 : SetupOutputVariable(state,
584 : "Plant Load Profile Steam Outlet Temperature",
585 : Constant::Units::C,
586 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).OutletTemp,
587 : OutputProcessor::TimeStepType::System,
588 : OutputProcessor::StoreType::Average,
589 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name);
590 : }
591 :
592 28 : if (ErrorsFound) ShowFatalError(state, format("Errors in {} input.", cCurrentModuleObject));
593 :
594 : } // ProfileNum
595 : }
596 23 : }
597 :
598 : } // namespace EnergyPlus::PlantLoadProfile
|