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 :
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 17 : PlantComponent *PlantProfileData::factory(EnergyPlusData &state, std::string const &objectName)
93 : {
94 17 : if (state.dataPlantLoadProfile->GetPlantLoadProfileInputFlag) {
95 15 : GetPlantProfileInput(state);
96 15 : state.dataPlantLoadProfile->GetPlantLoadProfileInputFlag = false;
97 : }
98 : // Now look for this particular pipe in the list
99 17 : auto thisObj = std::find_if(state.dataPlantLoadProfile->PlantProfile.begin(),
100 17 : state.dataPlantLoadProfile->PlantProfile.end(),
101 19 : [&objectName](const PlantProfileData &plp) { return plp.Name == objectName; });
102 17 : if (thisObj != state.dataPlantLoadProfile->PlantProfile.end()) return thisObj;
103 : // If we didn't find it, fatal
104 0 : ShowFatalError(state, format("PlantLoadProfile::factory: Error getting inputs for pipe named: {}", objectName));
105 : // Shut up the compiler
106 0 : return nullptr;
107 : }
108 :
109 60 : void PlantProfileData::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
110 : {
111 60 : this->InitPlantProfile(state);
112 60 : }
113 :
114 12406 : void PlantProfileData::simulate(EnergyPlusData &state,
115 : [[maybe_unused]] const PlantLocation &calledFromLocation,
116 : [[maybe_unused]] bool const FirstHVACIteration,
117 : [[maybe_unused]] Real64 &CurLoad,
118 : [[maybe_unused]] bool const RunFlag)
119 : {
120 :
121 : // SUBROUTINE INFORMATION:
122 : // AUTHOR Peter Graham Ellis
123 : // DATE WRITTEN January 2004
124 : // MODIFIED Brent Griffith, generalize fluid cp
125 : // June 2021, Dareum Nam, Add steam loop version
126 : // RE-ENGINEERED na
127 :
128 : // PURPOSE OF THIS SUBROUTINE:
129 : // Simulates the plant load profile object.
130 :
131 : // METHODOLOGY EMPLOYED:
132 : // This is a very simple simulation. InitPlantProfile does the work of getting the scheduled load and flow rate.
133 : // 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
134 : // flow rate of steam and the outlet temperature are calculated.
135 :
136 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
137 : static constexpr std::string_view RoutineName("SimulatePlantProfile");
138 : Real64 DeltaTemp;
139 :
140 12406 : this->InitPlantProfile(state);
141 :
142 12406 : if (this->FluidType == PlantLoopFluidType::Water) {
143 12405 : if (this->MassFlowRate > 0.0) {
144 5701 : Real64 Cp = this->plantLoc.loop->glycol->getSpecificHeat(state, this->InletTemp, RoutineName);
145 5701 : DeltaTemp = this->Power / (this->MassFlowRate * Cp);
146 : } else {
147 6704 : this->Power = 0.0;
148 6704 : DeltaTemp = 0.0;
149 : }
150 12405 : this->OutletTemp = this->InletTemp - DeltaTemp;
151 1 : } else if (this->FluidType == PlantLoopFluidType::Steam) {
152 1 : if (this->MassFlowRate > 0.0 && this->Power > 0.0) {
153 1 : Real64 EnthSteamInDry = this->plantLoc.loop->steam->getSatEnthalpy(state, this->InletTemp, 1.0, RoutineName);
154 1 : Real64 EnthSteamOutWet = this->plantLoc.loop->steam->getSatEnthalpy(state, this->InletTemp, 0.0, RoutineName);
155 1 : Real64 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
156 1 : Real64 SatTemp = this->plantLoc.loop->steam->getSatTemperature(state, DataEnvironment::StdPressureSeaLevel, RoutineName);
157 1 : Real64 CpWater = this->plantLoc.loop->glycol->getSpecificHeat(state, SatTemp, RoutineName);
158 :
159 : // Steam Mass Flow Rate Required
160 1 : this->MassFlowRate = this->Power / (LatentHeatSteam + this->DegOfSubcooling * CpWater);
161 1 : PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, this->InletNode, this->OutletNode, this->plantLoc);
162 1 : state.dataLoopNodes->Node(this->OutletNode).Quality = 0.0;
163 : // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
164 : // This is required for outlet water temperature, otherwise it will be saturation temperature.
165 : // Steam Trap drains off all the Water formed.
166 : // Here Degree of Subcooling is used to calculate hot water return temperature.
167 :
168 : // Calculating Condensate outlet temperature
169 1 : this->OutletTemp = SatTemp - this->LoopSubcoolReturn;
170 1 : } else {
171 0 : this->Power = 0.0;
172 : }
173 : }
174 :
175 12406 : this->UpdatePlantProfile(state);
176 12406 : this->ReportPlantProfile(state);
177 :
178 12406 : } // simulate()
179 :
180 12468 : void PlantProfileData::InitPlantProfile(EnergyPlusData &state)
181 : {
182 :
183 : // SUBROUTINE INFORMATION:
184 : // AUTHOR Peter Graham Ellis
185 : // DATE WRITTEN January 2004
186 : // MODIFIED na
187 : // RE-ENGINEERED na
188 :
189 : // PURPOSE OF THIS SUBROUTINE:
190 : // Initializes the plant load profile object during the plant simulation.
191 :
192 : // METHODOLOGY EMPLOYED:
193 : // Inlet and outlet nodes are initialized. The scheduled load and flow rate is obtained, flow is requested, and the
194 : // actual available flow is set.
195 :
196 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
197 : static constexpr std::string_view RoutineName("InitPlantProfile");
198 : Real64 FluidDensityInit;
199 :
200 : // Do the one time initializations
201 :
202 12468 : if (!state.dataGlobal->SysSizingCalc && this->InitSizing) {
203 14 : PlantUtilities::RegisterPlantCompDesignFlow(state, InletNode, this->PeakVolFlowRate);
204 14 : this->InitSizing = false;
205 : }
206 :
207 12468 : if (state.dataGlobal->BeginEnvrnFlag && this->Init) {
208 : // Clear node initial conditions
209 23 : state.dataLoopNodes->Node(OutletNode).Temp = 0.0;
210 :
211 23 : if (this->FluidType == PlantLoopFluidType::Water) {
212 23 : FluidDensityInit = this->plantLoc.loop->glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
213 : } else { //(this->FluidType == PlantLoopFluidType::Steam)
214 0 : Real64 SatTempAtmPress = this->plantLoc.loop->steam->getSatTemperature(state, DataEnvironment::StdPressureSeaLevel, RoutineName);
215 0 : FluidDensityInit = this->plantLoc.loop->steam->getSatDensity(state, SatTempAtmPress, 1.0, RoutineName);
216 : }
217 :
218 23 : Real64 MaxFlowMultiplier = this->flowRateFracSched->getMaxVal(state);
219 :
220 23 : PlantUtilities::InitComponentNodes(
221 23 : state, 0.0, this->PeakVolFlowRate * FluidDensityInit * MaxFlowMultiplier, this->InletNode, this->OutletNode);
222 :
223 23 : this->EMSOverrideMassFlow = false;
224 23 : this->EMSMassFlowValue = 0.0;
225 23 : this->EMSOverridePower = false;
226 23 : this->EMSPowerValue = 0.0;
227 23 : this->Init = false;
228 : }
229 :
230 12468 : if (!state.dataGlobal->BeginEnvrnFlag) this->Init = true;
231 :
232 12468 : this->InletTemp = state.dataLoopNodes->Node(InletNode).Temp;
233 12468 : this->Power = this->loadSched->getCurrentVal();
234 :
235 12468 : if (this->EMSOverridePower) this->Power = this->EMSPowerValue;
236 :
237 12468 : if (this->FluidType == PlantLoopFluidType::Water) {
238 12466 : FluidDensityInit = this->plantLoc.loop->glycol->getDensity(state, this->InletTemp, RoutineName);
239 : } else { //(this->FluidType == PlantLoopFluidType::Steam)
240 2 : FluidDensityInit = this->plantLoc.loop->steam->getSatDensity(state, this->InletTemp, 1.0, RoutineName);
241 : }
242 :
243 : // Get the scheduled mass flow rate
244 12468 : this->VolFlowRate = this->PeakVolFlowRate * this->flowRateFracSched->getCurrentVal();
245 :
246 12468 : this->MassFlowRate = this->VolFlowRate * FluidDensityInit;
247 :
248 12468 : if (this->EMSOverrideMassFlow) this->MassFlowRate = this->EMSMassFlowValue;
249 :
250 : // Request the mass flow rate from the plant component flow utility routine
251 12468 : PlantUtilities::SetComponentFlowRate(state, this->MassFlowRate, InletNode, OutletNode, this->plantLoc);
252 :
253 12468 : this->VolFlowRate = this->MassFlowRate / FluidDensityInit;
254 :
255 12468 : } // InitPlantProfile()
256 :
257 12406 : void PlantProfileData::UpdatePlantProfile(EnergyPlusData &state) const
258 : {
259 :
260 : // SUBROUTINE INFORMATION:
261 : // AUTHOR Peter Graham Ellis
262 : // DATE WRITTEN January 2004
263 : // MODIFIED na
264 : // RE-ENGINEERED na
265 :
266 : // PURPOSE OF THIS SUBROUTINE:
267 : // Updates the node variables with local variables.
268 :
269 : // Set outlet node variables that are possibly changed
270 12406 : state.dataLoopNodes->Node(this->OutletNode).Temp = this->OutletTemp;
271 12406 : }
272 :
273 12406 : void PlantProfileData::ReportPlantProfile(EnergyPlusData &state)
274 : {
275 :
276 : // SUBROUTINE INFORMATION:
277 : // AUTHOR Peter Graham Ellis
278 : // DATE WRITTEN January 2004
279 : // MODIFIED na
280 : // RE-ENGINEERED na
281 :
282 : // PURPOSE OF THIS SUBROUTINE:
283 : // Calculates report variables.
284 :
285 : // Using/Aliasing
286 12406 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
287 :
288 12406 : this->Energy = this->Power * TimeStepSysSec;
289 :
290 12406 : if (this->Energy >= 0.0) {
291 9807 : this->HeatingEnergy = this->Energy;
292 9807 : this->CoolingEnergy = 0.0;
293 : } else {
294 2599 : this->HeatingEnergy = 0.0;
295 2599 : this->CoolingEnergy = std::abs(this->Energy);
296 : }
297 12406 : }
298 17 : void PlantProfileData::oneTimeInit_new(EnergyPlusData &state)
299 : {
300 17 : if (allocated(state.dataPlnt->PlantLoop)) {
301 17 : bool errFlag = false;
302 17 : PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->Type, this->plantLoc, errFlag, _, _, _, _, _);
303 17 : if (errFlag) {
304 0 : ShowFatalError(state, "InitPlantProfile: Program terminated for previous conditions.");
305 : }
306 : }
307 17 : }
308 0 : void PlantProfileData::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
309 : {
310 0 : }
311 :
312 0 : void PlantProfileData::getCurrentPower([[maybe_unused]] EnergyPlusData &state, Real64 &power)
313 : {
314 0 : power = this->Power;
315 0 : return;
316 : }
317 :
318 : // Functions
319 16 : void GetPlantProfileInput(EnergyPlusData &state)
320 : {
321 :
322 : // SUBROUTINE INFORMATION:
323 : // AUTHOR Peter Graham Ellis
324 : // DATE WRITTEN January 2004
325 : // MODIFIED June 2021, Dareum Nam, Add steam loop version
326 : // RE-ENGINEERED na
327 :
328 : // PURPOSE OF THIS SUBROUTINE:
329 : // Gets the plant load profile input from the input file and sets up the objects.
330 :
331 : static constexpr std::string_view routineName = "GetPlantProfileInput";
332 :
333 : // Using/Aliasing
334 : using namespace DataLoopNode;
335 :
336 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
337 16 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
338 :
339 16 : cCurrentModuleObject = "LoadProfile:Plant";
340 16 : state.dataPlantLoadProfile->NumOfPlantProfile = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
341 :
342 16 : if (state.dataPlantLoadProfile->NumOfPlantProfile > 0) {
343 16 : state.dataPlantLoadProfile->PlantProfile.allocate(state.dataPlantLoadProfile->NumOfPlantProfile);
344 16 : bool ErrorsFound = false; // Set to true if errors in input, fatal at end of routine
345 : int IOStatus; // Used in GetObjectItem
346 : int NumAlphas; // Number of Alphas for each GetObjectItem call
347 : int NumNumbers; // Number of Numbers for each GetObjectItem call
348 :
349 35 : for (int ProfileNum = 1; ProfileNum <= state.dataPlantLoadProfile->NumOfPlantProfile; ++ProfileNum) {
350 57 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
351 : cCurrentModuleObject,
352 : ProfileNum,
353 19 : state.dataIPShortCut->cAlphaArgs,
354 : NumAlphas,
355 19 : state.dataIPShortCut->rNumericArgs,
356 : NumNumbers,
357 : IOStatus,
358 19 : state.dataIPShortCut->lNumericFieldBlanks,
359 : _,
360 19 : state.dataIPShortCut->cAlphaFieldNames,
361 19 : state.dataIPShortCut->cNumericFieldNames);
362 :
363 19 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
364 :
365 19 : Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
366 :
367 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name = state.dataIPShortCut->cAlphaArgs(1);
368 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Type =
369 : DataPlant::PlantEquipmentType::PlantLoadProfile; // parameter assigned in DataPlant
370 :
371 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType =
372 38 : static_cast<PlantLoopFluidType>(getEnumValue(PlantLoopFluidTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(6))));
373 19 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Invalid) {
374 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType = PlantLoopFluidType::Water;
375 : }
376 :
377 19 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Water) {
378 18 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).InletNode =
379 36 : NodeInputManager::GetOnlySingleNode(state,
380 18 : state.dataIPShortCut->cAlphaArgs(2),
381 : ErrorsFound,
382 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
383 18 : state.dataIPShortCut->cAlphaArgs(1),
384 : DataLoopNode::NodeFluidType::Water,
385 : DataLoopNode::ConnectionType::Inlet,
386 : NodeInputManager::CompFluidStream::Primary,
387 : ObjectIsNotParent);
388 18 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).OutletNode =
389 54 : NodeInputManager::GetOnlySingleNode(state,
390 18 : state.dataIPShortCut->cAlphaArgs(3),
391 : ErrorsFound,
392 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
393 18 : state.dataIPShortCut->cAlphaArgs(1),
394 : DataLoopNode::NodeFluidType::Water,
395 : DataLoopNode::ConnectionType::Outlet,
396 : NodeInputManager::CompFluidStream::Primary,
397 : ObjectIsNotParent);
398 : } else { // state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Steam
399 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).InletNode =
400 2 : NodeInputManager::GetOnlySingleNode(state,
401 1 : state.dataIPShortCut->cAlphaArgs(2),
402 : ErrorsFound,
403 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
404 1 : state.dataIPShortCut->cAlphaArgs(1),
405 : DataLoopNode::NodeFluidType::Steam,
406 : DataLoopNode::ConnectionType::Inlet,
407 : NodeInputManager::CompFluidStream::Primary,
408 : ObjectIsNotParent);
409 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).OutletNode =
410 3 : NodeInputManager::GetOnlySingleNode(state,
411 1 : state.dataIPShortCut->cAlphaArgs(3),
412 : ErrorsFound,
413 : DataLoopNode::ConnectionObjectType::LoadProfilePlant,
414 1 : state.dataIPShortCut->cAlphaArgs(1),
415 : DataLoopNode::NodeFluidType::Steam,
416 : DataLoopNode::ConnectionType::Outlet,
417 : NodeInputManager::CompFluidStream::Primary,
418 : ObjectIsNotParent);
419 : }
420 :
421 19 : if ((state.dataPlantLoadProfile->PlantProfile(ProfileNum).loadSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(4))) ==
422 : nullptr) {
423 0 : ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(4), state.dataIPShortCut->cAlphaArgs(4));
424 0 : ErrorsFound = true;
425 : }
426 :
427 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).PeakVolFlowRate = state.dataIPShortCut->rNumericArgs(1);
428 :
429 19 : if ((state.dataPlantLoadProfile->PlantProfile(ProfileNum).flowRateFracSched =
430 38 : Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(5))) == nullptr) {
431 0 : ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5));
432 0 : ErrorsFound = true;
433 : }
434 :
435 19 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Steam) {
436 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(2)) {
437 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).DegOfSubcooling = state.dataIPShortCut->rNumericArgs(2);
438 : } else {
439 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).DegOfSubcooling = 5.0; // default value
440 : }
441 :
442 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(3)) {
443 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).LoopSubcoolReturn = state.dataIPShortCut->rNumericArgs(3);
444 : } else {
445 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).LoopSubcoolReturn = 20.0; // default value
446 : }
447 : }
448 :
449 : // Check plant connections
450 19 : BranchNodeConnections::TestCompSet(state,
451 : cCurrentModuleObject,
452 19 : state.dataIPShortCut->cAlphaArgs(1),
453 19 : state.dataIPShortCut->cAlphaArgs(2),
454 19 : state.dataIPShortCut->cAlphaArgs(3),
455 38 : cCurrentModuleObject + " Nodes");
456 :
457 : // Setup report variables
458 38 : SetupOutputVariable(state,
459 : "Plant Load Profile Mass Flow Rate",
460 : Constant::Units::kg_s,
461 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).MassFlowRate,
462 : OutputProcessor::TimeStepType::System,
463 : OutputProcessor::StoreType::Average,
464 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name);
465 :
466 38 : SetupOutputVariable(state,
467 : "Plant Load Profile Heat Transfer Rate",
468 : Constant::Units::W,
469 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Power,
470 : OutputProcessor::TimeStepType::System,
471 : OutputProcessor::StoreType::Average,
472 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name);
473 :
474 38 : SetupOutputVariable(state,
475 : "Plant Load Profile Heat Transfer Energy",
476 : Constant::Units::J,
477 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Energy,
478 : OutputProcessor::TimeStepType::System,
479 : OutputProcessor::StoreType::Sum,
480 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
481 : Constant::eResource::EnergyTransfer,
482 : OutputProcessor::Group::Plant,
483 : OutputProcessor::EndUseCat::Heating); // is EndUseKey right?
484 :
485 38 : SetupOutputVariable(state,
486 : "Plant Load Profile Heating Energy",
487 : Constant::Units::J,
488 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).HeatingEnergy,
489 : OutputProcessor::TimeStepType::System,
490 : OutputProcessor::StoreType::Sum,
491 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
492 : Constant::eResource::PlantLoopHeatingDemand,
493 : OutputProcessor::Group::Plant,
494 : OutputProcessor::EndUseCat::Heating);
495 :
496 38 : SetupOutputVariable(state,
497 : "Plant Load Profile Cooling Energy",
498 : Constant::Units::J,
499 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).CoolingEnergy,
500 : OutputProcessor::TimeStepType::System,
501 : OutputProcessor::StoreType::Sum,
502 19 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
503 : Constant::eResource::PlantLoopCoolingDemand,
504 : OutputProcessor::Group::Plant,
505 : OutputProcessor::EndUseCat::Cooling);
506 :
507 19 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
508 0 : SetupEMSActuator(state,
509 : "Plant Load Profile",
510 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
511 : "Mass Flow Rate",
512 : "[kg/s]",
513 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSOverrideMassFlow,
514 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSMassFlowValue);
515 0 : SetupEMSActuator(state,
516 : "Plant Load Profile",
517 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name,
518 : "Power",
519 : "[W]",
520 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSOverridePower,
521 0 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).EMSPowerValue);
522 : }
523 :
524 19 : if (state.dataPlantLoadProfile->PlantProfile(ProfileNum).FluidType == PlantLoopFluidType::Steam) {
525 2 : SetupOutputVariable(state,
526 : "Plant Load Profile Steam Outlet Temperature",
527 : Constant::Units::C,
528 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).OutletTemp,
529 : OutputProcessor::TimeStepType::System,
530 : OutputProcessor::StoreType::Average,
531 1 : state.dataPlantLoadProfile->PlantProfile(ProfileNum).Name);
532 : }
533 :
534 19 : if (ErrorsFound) ShowFatalError(state, format("Errors in {} input.", cCurrentModuleObject));
535 :
536 : } // ProfileNum
537 : }
538 16 : }
539 :
540 : } // namespace EnergyPlus::PlantLoadProfile
|