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