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 : #include <memory>
49 :
50 : #include <ObjexxFCL/Array1D.hh> // needs to be in BranchNodeConnections.hh
51 :
52 : #include <EnergyPlus/BranchNodeConnections.hh>
53 : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
54 : #include <EnergyPlus/Coils/CoilCoolingDXAshrae205Performance.hh>
55 : #include <EnergyPlus/Coils/CoilCoolingDXCurveFitPerformance.hh>
56 : #include <EnergyPlus/Data/EnergyPlusData.hh>
57 : #include <EnergyPlus/DataAirLoop.hh>
58 : #include <EnergyPlus/DataEnvironment.hh>
59 : #include <EnergyPlus/DataGlobalConstants.hh>
60 : #include <EnergyPlus/DataGlobals.hh>
61 : #include <EnergyPlus/DataHVACGlobals.hh>
62 : #include <EnergyPlus/DataHeatBalance.hh>
63 : #include <EnergyPlus/DataIPShortCuts.hh>
64 : #include <EnergyPlus/DataLoopNode.hh>
65 : #include <EnergyPlus/DataWater.hh>
66 : #include <EnergyPlus/Fans.hh>
67 : #include <EnergyPlus/GeneralRoutines.hh>
68 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
69 : #include <EnergyPlus/NodeInputManager.hh>
70 : #include <EnergyPlus/OutAirNodeManager.hh>
71 : #include <EnergyPlus/OutputProcessor.hh>
72 : #include <EnergyPlus/OutputReportPredefined.hh>
73 : #include <EnergyPlus/Psychrometrics.hh>
74 : #include <EnergyPlus/ReportCoilSelection.hh>
75 : #include <EnergyPlus/ScheduleManager.hh>
76 : #include <EnergyPlus/SimAirServingZones.hh>
77 : #include <EnergyPlus/StandardRatings.hh>
78 : #include <EnergyPlus/WaterManager.hh>
79 :
80 : using namespace EnergyPlus;
81 :
82 55 : std::shared_ptr<CoilCoolingDXPerformanceBase> CoilCoolingDX::makePerformanceSubclass(EnergyPlus::EnergyPlusData &state,
83 : const std::string &performance_object_name)
84 : {
85 55 : const auto a205_object_name = CoilCoolingDX205Performance::object_name;
86 55 : const auto curve_fit_object_name = CoilCoolingDXCurveFitPerformance::object_name;
87 :
88 55 : if (findPerformanceSubclass(state, a205_object_name, performance_object_name)) {
89 1 : return std::make_shared<CoilCoolingDX205Performance>(state, performance_object_name);
90 54 : } else if (findPerformanceSubclass(state, curve_fit_object_name, performance_object_name)) {
91 54 : return std::make_shared<CoilCoolingDXCurveFitPerformance>(state, performance_object_name);
92 : }
93 :
94 0 : ShowFatalError(state, format("Could not find Coil:Cooling:DX:Performance object with name: {}", performance_object_name));
95 0 : return nullptr;
96 : }
97 :
98 113 : int CoilCoolingDX::factory(EnergyPlus::EnergyPlusData &state, std::string const &coilName)
99 : {
100 113 : if (state.dataCoilCoolingDX->coilCoolingDXGetInputFlag) {
101 21 : CoilCoolingDX::getInput(state);
102 21 : state.dataCoilCoolingDX->coilCoolingDXGetInputFlag = false;
103 : }
104 113 : int handle = -1;
105 113 : std::string coilNameUpper = Util::makeUPPER(coilName);
106 279 : for (auto const &thisCoil : state.dataCoilCoolingDX->coilCoolingDXs) {
107 279 : handle++;
108 279 : if (coilNameUpper == Util::makeUPPER(thisCoil.name)) {
109 113 : return handle;
110 : }
111 226 : }
112 0 : ShowSevereError(state, "Coil:Cooling:DX Coil not found=" + coilName);
113 0 : return -1;
114 113 : }
115 :
116 21 : void CoilCoolingDX::getInput(EnergyPlusData &state)
117 : {
118 21 : int numCoolingCoilDXs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataCoilCoolingDX->coilCoolingDXObjectName);
119 21 : if (numCoolingCoilDXs <= 0) {
120 0 : ShowFatalError(state, R"(No "Coil:Cooling:DX" objects in input file)");
121 : }
122 76 : for (int coilNum = 1; coilNum <= numCoolingCoilDXs; ++coilNum) {
123 : int NumAlphas; // Number of Alphas for each GetObjectItem call
124 : int NumNumbers; // Number of Numbers for each GetObjectItem call
125 : int IOStatus;
126 110 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
127 55 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
128 : coilNum,
129 55 : state.dataIPShortCut->cAlphaArgs,
130 : NumAlphas,
131 55 : state.dataIPShortCut->rNumericArgs,
132 : NumNumbers,
133 : IOStatus);
134 55 : CoilCoolingDXInputSpecification input_specs;
135 55 : input_specs.name = state.dataIPShortCut->cAlphaArgs(1);
136 55 : input_specs.evaporator_inlet_node_name = state.dataIPShortCut->cAlphaArgs(2);
137 55 : input_specs.evaporator_outlet_node_name = state.dataIPShortCut->cAlphaArgs(3);
138 55 : input_specs.availability_schedule_name = state.dataIPShortCut->cAlphaArgs(4);
139 55 : input_specs.condenser_zone_name = state.dataIPShortCut->cAlphaArgs(5);
140 55 : input_specs.condenser_inlet_node_name = state.dataIPShortCut->cAlphaArgs(6);
141 55 : input_specs.condenser_outlet_node_name = state.dataIPShortCut->cAlphaArgs(7);
142 55 : input_specs.performance_object_name = state.dataIPShortCut->cAlphaArgs(8);
143 55 : input_specs.condensate_collection_water_storage_tank_name = state.dataIPShortCut->cAlphaArgs(9);
144 55 : input_specs.evaporative_condenser_supply_water_storage_tank_name = state.dataIPShortCut->cAlphaArgs(10);
145 55 : CoilCoolingDX thisCoil;
146 55 : thisCoil.instantiateFromInputSpec(state, input_specs);
147 55 : state.dataCoilCoolingDX->coilCoolingDXs.push_back(thisCoil);
148 55 : }
149 21 : }
150 :
151 55 : void CoilCoolingDX::instantiateFromInputSpec(EnergyPlusData &state, const CoilCoolingDXInputSpecification &input_data)
152 : {
153 : static constexpr std::string_view routineName = "CoilCoolingDX::instantiateFromInputSpec";
154 :
155 55 : ErrorObjectHeader eoh{routineName, "CoilCoolingDX", input_data.name};
156 :
157 55 : this->original_input_specs = input_data;
158 55 : bool errorsFound = false;
159 55 : this->name = input_data.name;
160 :
161 : // initialize reclaim heat parameters
162 55 : this->reclaimHeat.Name = this->name;
163 55 : this->reclaimHeat.SourceType = state.dataCoilCoolingDX->coilCoolingDXObjectName;
164 :
165 : // other construction below
166 55 : this->evapInletNodeIndex = NodeInputManager::GetOnlySingleNode(state,
167 55 : input_data.evaporator_inlet_node_name,
168 : errorsFound,
169 : DataLoopNode::ConnectionObjectType::CoilCoolingDX,
170 55 : input_data.name,
171 : DataLoopNode::NodeFluidType::Air,
172 : DataLoopNode::ConnectionType::Inlet,
173 : NodeInputManager::CompFluidStream::Primary,
174 : DataLoopNode::ObjectIsNotParent);
175 55 : this->evapOutletNodeIndex = NodeInputManager::GetOnlySingleNode(state,
176 55 : input_data.evaporator_outlet_node_name,
177 : errorsFound,
178 : DataLoopNode::ConnectionObjectType::CoilCoolingDX,
179 55 : input_data.name,
180 : DataLoopNode::NodeFluidType::Air,
181 : DataLoopNode::ConnectionType::Outlet,
182 : NodeInputManager::CompFluidStream::Primary,
183 : DataLoopNode::ObjectIsNotParent);
184 :
185 55 : this->condInletNodeIndex = NodeInputManager::GetOnlySingleNode(state,
186 55 : input_data.condenser_inlet_node_name,
187 : errorsFound,
188 : DataLoopNode::ConnectionObjectType::CoilCoolingDX,
189 55 : input_data.name,
190 : DataLoopNode::NodeFluidType::Air,
191 : DataLoopNode::ConnectionType::Inlet,
192 : NodeInputManager::CompFluidStream::Secondary,
193 : DataLoopNode::ObjectIsNotParent);
194 :
195 55 : this->condOutletNodeIndex = NodeInputManager::GetOnlySingleNode(state,
196 55 : input_data.condenser_outlet_node_name,
197 : errorsFound,
198 : DataLoopNode::ConnectionObjectType::CoilCoolingDX,
199 55 : input_data.name,
200 : DataLoopNode::NodeFluidType::Air,
201 : DataLoopNode::ConnectionType::Outlet,
202 : NodeInputManager::CompFluidStream::Secondary,
203 : DataLoopNode::ObjectIsNotParent);
204 :
205 55 : this->performance = makePerformanceSubclass(state, input_data.performance_object_name);
206 55 : this->subcoolReheatFlag = this->performance->subcoolReheatFlag();
207 :
208 55 : if (!input_data.condensate_collection_water_storage_tank_name.empty()) {
209 0 : WaterManager::SetupTankSupplyComponent(state,
210 : this->name,
211 0 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
212 : input_data.condensate_collection_water_storage_tank_name,
213 : errorsFound,
214 0 : this->condensateTankIndex,
215 0 : this->condensateTankSupplyARRID);
216 : }
217 :
218 55 : if (!input_data.evaporative_condenser_supply_water_storage_tank_name.empty()) {
219 0 : WaterManager::SetupTankDemandComponent(state,
220 : this->name,
221 0 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
222 : input_data.evaporative_condenser_supply_water_storage_tank_name,
223 : errorsFound,
224 0 : this->evaporativeCondSupplyTankIndex,
225 0 : this->evaporativeCondSupplyTankARRID);
226 : }
227 :
228 55 : if (input_data.availability_schedule_name.empty()) {
229 45 : this->availSched = Sched::GetScheduleAlwaysOn(state);
230 10 : } else if ((this->availSched = Sched::GetSchedule(state, input_data.availability_schedule_name)) == nullptr) {
231 0 : ShowSevereItemNotFound(state, eoh, "Availability Schedule Name", input_data.availability_schedule_name);
232 0 : errorsFound = true;
233 : }
234 :
235 55 : if (!input_data.condenser_zone_name.empty()) {
236 0 : this->isSecondaryDXCoilInZone = true;
237 : // Setup zone data here
238 : }
239 :
240 110 : BranchNodeConnections::TestCompSet(state,
241 55 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
242 : this->name,
243 55 : input_data.evaporator_inlet_node_name,
244 55 : input_data.evaporator_outlet_node_name,
245 : "Air Nodes");
246 :
247 55 : if (errorsFound) {
248 0 : ShowFatalError(state,
249 0 : std::string{routineName} + "Errors found in getting " + state.dataCoilCoolingDX->coilCoolingDXObjectName +
250 : " input. Preceding condition(s) causes termination.");
251 : }
252 55 : }
253 :
254 55 : void CoilCoolingDX::oneTimeInit(EnergyPlusData &state)
255 : {
256 :
257 : // setup output variables, needs to be done after object is instantiated and emplaced
258 110 : SetupOutputVariable(state,
259 : "Cooling Coil Total Cooling Rate",
260 : Constant::Units::W,
261 55 : this->totalCoolingEnergyRate,
262 : OutputProcessor::TimeStepType::System,
263 : OutputProcessor::StoreType::Average,
264 55 : this->name);
265 110 : SetupOutputVariable(state,
266 : "Cooling Coil Total Cooling Energy",
267 : Constant::Units::J,
268 55 : this->totalCoolingEnergy,
269 : OutputProcessor::TimeStepType::System,
270 : OutputProcessor::StoreType::Sum,
271 55 : this->name,
272 : Constant::eResource::EnergyTransfer,
273 : OutputProcessor::Group::HVAC,
274 : OutputProcessor::EndUseCat::CoolingCoils);
275 110 : SetupOutputVariable(state,
276 : "Cooling Coil Sensible Cooling Rate",
277 : Constant::Units::W,
278 55 : this->sensCoolingEnergyRate,
279 : OutputProcessor::TimeStepType::System,
280 : OutputProcessor::StoreType::Average,
281 55 : this->name);
282 110 : SetupOutputVariable(state,
283 : "Cooling Coil Sensible Cooling Energy",
284 : Constant::Units::J,
285 55 : this->sensCoolingEnergy,
286 : OutputProcessor::TimeStepType::System,
287 : OutputProcessor::StoreType::Sum,
288 55 : this->name);
289 110 : SetupOutputVariable(state,
290 : "Cooling Coil Latent Cooling Rate",
291 : Constant::Units::W,
292 55 : this->latCoolingEnergyRate,
293 : OutputProcessor::TimeStepType::System,
294 : OutputProcessor::StoreType::Average,
295 55 : this->name);
296 110 : SetupOutputVariable(state,
297 : "Cooling Coil Latent Cooling Energy",
298 : Constant::Units::J,
299 55 : this->latCoolingEnergy,
300 : OutputProcessor::TimeStepType::System,
301 : OutputProcessor::StoreType::Sum,
302 55 : this->name);
303 110 : SetupOutputVariable(state,
304 : "Cooling Coil Electricity Rate",
305 : Constant::Units::W,
306 55 : this->performance->powerUse,
307 : OutputProcessor::TimeStepType::System,
308 : OutputProcessor::StoreType::Average,
309 55 : this->name);
310 110 : SetupOutputVariable(state,
311 : "Cooling Coil Electricity Energy",
312 : Constant::Units::J,
313 55 : this->performance->electricityConsumption,
314 : OutputProcessor::TimeStepType::System,
315 : OutputProcessor::StoreType::Sum,
316 55 : this->name,
317 : Constant::eResource::Electricity,
318 : OutputProcessor::Group::HVAC,
319 : OutputProcessor::EndUseCat::Cooling);
320 :
321 55 : if (this->performance->compressorFuelType != Constant::eFuel::Electricity) {
322 0 : std::string_view const sFuelType = Constant::eFuelNames[static_cast<int>(this->performance->compressorFuelType)];
323 0 : SetupOutputVariable(state,
324 0 : format("Cooling Coil {} Rate", sFuelType),
325 : Constant::Units::W,
326 0 : this->performance->compressorFuelRate,
327 : OutputProcessor::TimeStepType::System,
328 : OutputProcessor::StoreType::Average,
329 0 : this->name);
330 0 : SetupOutputVariable(state,
331 0 : format("Cooling Coil {} Energy", sFuelType),
332 : Constant::Units::J,
333 0 : this->performance->compressorFuelConsumption,
334 : OutputProcessor::TimeStepType::System,
335 : OutputProcessor::StoreType::Sum,
336 0 : this->name,
337 0 : Constant::eFuel2eResource[(int)this->performance->compressorFuelType],
338 : OutputProcessor::Group::HVAC,
339 : OutputProcessor::EndUseCat::Cooling);
340 : }
341 :
342 110 : SetupOutputVariable(state,
343 : "Cooling Coil Runtime Fraction",
344 : Constant::Units::None,
345 55 : this->coolingCoilRuntimeFraction,
346 : OutputProcessor::TimeStepType::System,
347 : OutputProcessor::StoreType::Average,
348 55 : this->name);
349 110 : SetupOutputVariable(state,
350 : "Cooling Coil Crankcase Heater Electricity Rate",
351 : Constant::Units::W,
352 55 : this->performance->crankcaseHeaterPower,
353 : OutputProcessor::TimeStepType::System,
354 : OutputProcessor::StoreType::Average,
355 55 : this->name);
356 110 : SetupOutputVariable(state,
357 : "Cooling Coil Crankcase Heater Electricity Energy",
358 : Constant::Units::J,
359 55 : this->performance->crankcaseHeaterElectricityConsumption,
360 : OutputProcessor::TimeStepType::System,
361 : OutputProcessor::StoreType::Sum,
362 55 : this->name,
363 : Constant::eResource::Electricity,
364 : OutputProcessor::Group::HVAC,
365 : OutputProcessor::EndUseCat::Cooling);
366 : // Ported from variable speed coil
367 110 : SetupOutputVariable(state,
368 : "Cooling Coil Air Mass Flow Rate",
369 : Constant::Units::kg_s,
370 55 : this->airMassFlowRate,
371 : OutputProcessor::TimeStepType::System,
372 : OutputProcessor::StoreType::Average,
373 55 : this->name);
374 110 : SetupOutputVariable(state,
375 : "Cooling Coil Air Inlet Temperature",
376 : Constant::Units::C,
377 55 : this->inletAirDryBulbTemp,
378 : OutputProcessor::TimeStepType::System,
379 : OutputProcessor::StoreType::Average,
380 55 : this->name);
381 110 : SetupOutputVariable(state,
382 : "Cooling Coil Air Inlet Humidity Ratio",
383 : Constant::Units::kgWater_kgDryAir,
384 55 : this->inletAirHumRat,
385 : OutputProcessor::TimeStepType::System,
386 : OutputProcessor::StoreType::Average,
387 55 : this->name);
388 110 : SetupOutputVariable(state,
389 : "Cooling Coil Air Outlet Temperature",
390 : Constant::Units::C,
391 55 : this->outletAirDryBulbTemp,
392 : OutputProcessor::TimeStepType::System,
393 : OutputProcessor::StoreType::Average,
394 55 : this->name);
395 110 : SetupOutputVariable(state,
396 : "Cooling Coil Air Outlet Humidity Ratio",
397 : Constant::Units::kgWater_kgDryAir,
398 55 : this->outletAirHumRat,
399 : OutputProcessor::TimeStepType::System,
400 : OutputProcessor::StoreType::Average,
401 55 : this->name);
402 110 : SetupOutputVariable(state,
403 : "Cooling Coil Part Load Ratio",
404 : Constant::Units::None,
405 55 : this->partLoadRatioReport,
406 : OutputProcessor::TimeStepType::System,
407 : OutputProcessor::StoreType::Average,
408 55 : this->name);
409 55 : SetupOutputVariable(state,
410 : "Cooling Coil Upper Speed Level",
411 : Constant::Units::None,
412 55 : this->speedNumReport,
413 : OutputProcessor::TimeStepType::System,
414 : OutputProcessor::StoreType::Average,
415 55 : this->name);
416 110 : SetupOutputVariable(state,
417 : "Cooling Coil Neighboring Speed Levels Ratio",
418 : Constant::Units::None,
419 55 : this->speedRatioReport,
420 : OutputProcessor::TimeStepType::System,
421 : OutputProcessor::StoreType::Average,
422 55 : this->name);
423 110 : SetupOutputVariable(state,
424 : "Cooling Coil Condenser Inlet Temperature",
425 : Constant::Units::C,
426 55 : this->condenserInletTemperature,
427 : OutputProcessor::TimeStepType::System,
428 : OutputProcessor::StoreType::Average,
429 55 : this->name);
430 55 : SetupOutputVariable(state,
431 : "Cooling Coil Dehumidification Mode",
432 : Constant::Units::None,
433 55 : (int &)this->dehumidificationMode,
434 : OutputProcessor::TimeStepType::System,
435 : OutputProcessor::StoreType::Average,
436 55 : this->name);
437 110 : SetupOutputVariable(state,
438 : "Cooling Coil Waste Heat Power",
439 : Constant::Units::W,
440 55 : this->wasteHeatEnergyRate,
441 : OutputProcessor::TimeStepType::System,
442 : OutputProcessor::StoreType::Average,
443 55 : this->name);
444 110 : SetupOutputVariable(state,
445 : "Cooling Coil Waste Heat Energy",
446 : Constant::Units::J,
447 55 : this->wasteHeatEnergy,
448 : OutputProcessor::TimeStepType::System,
449 : OutputProcessor::StoreType::Sum,
450 55 : this->name);
451 :
452 55 : if (this->performance->evapCondBasinHeatCap > 0) {
453 0 : SetupOutputVariable(state,
454 : "Cooling Coil Basin Heater Electricity Rate",
455 : Constant::Units::W,
456 0 : this->performance->basinHeaterPower,
457 : OutputProcessor::TimeStepType::System,
458 : OutputProcessor::StoreType::Average,
459 0 : this->name);
460 0 : SetupOutputVariable(state,
461 : "Cooling Coil Basin Heater Electricity Energy",
462 : Constant::Units::J,
463 0 : this->performance->basinHeaterElectricityConsumption,
464 : OutputProcessor::TimeStepType::System,
465 : OutputProcessor::StoreType::Sum,
466 0 : this->name,
467 : Constant::eResource::Electricity,
468 : OutputProcessor::Group::HVAC,
469 : OutputProcessor::EndUseCat::Cooling);
470 : }
471 55 : if (this->condensateTankIndex > 0) {
472 0 : SetupOutputVariable(state,
473 : "Cooling Coil Condensate Volume Flow Rate",
474 : Constant::Units::m3_s,
475 0 : this->condensateVolumeFlow,
476 : OutputProcessor::TimeStepType::System,
477 : OutputProcessor::StoreType::Average,
478 0 : this->name);
479 0 : SetupOutputVariable(state,
480 : "Cooling Coil Condensate Volume",
481 : Constant::Units::m3,
482 0 : this->condensateVolumeConsumption,
483 : OutputProcessor::TimeStepType::System,
484 : OutputProcessor::StoreType::Sum,
485 0 : this->name,
486 : Constant::eResource::OnSiteWater,
487 : OutputProcessor::Group::HVAC,
488 : OutputProcessor::EndUseCat::Condensate);
489 : }
490 55 : if (this->evaporativeCondSupplyTankIndex > 0) {
491 0 : SetupOutputVariable(state,
492 : "Cooling Coil Evaporative Condenser Pump Electricity Rate",
493 : Constant::Units::W,
494 0 : this->evapCondPumpElecPower,
495 : OutputProcessor::TimeStepType::System,
496 : OutputProcessor::StoreType::Average,
497 0 : this->name);
498 0 : SetupOutputVariable(state,
499 : "Cooling Coil Evaporative Condenser Pump Electricity Energy",
500 : Constant::Units::J,
501 0 : this->evapCondPumpElecConsumption,
502 : OutputProcessor::TimeStepType::System,
503 : OutputProcessor::StoreType::Sum,
504 0 : this->name,
505 : Constant::eResource::Electricity,
506 : OutputProcessor::Group::HVAC,
507 : OutputProcessor::EndUseCat::Condensate);
508 0 : SetupOutputVariable(state,
509 : "Cooling Coil Evaporative Condenser Water Volume Flow Rate",
510 : Constant::Units::m3_s,
511 0 : this->evaporativeCondSupplyTankVolumeFlow,
512 : OutputProcessor::TimeStepType::System,
513 : OutputProcessor::StoreType::Average,
514 0 : this->name);
515 0 : SetupOutputVariable(state,
516 : "Cooling Coil Evaporative Condenser Water Volume",
517 : Constant::Units::m3,
518 0 : this->evaporativeCondSupplyTankConsump,
519 : OutputProcessor::TimeStepType::System,
520 : OutputProcessor::StoreType::Sum,
521 0 : this->name,
522 : Constant::eResource::Water,
523 : OutputProcessor::Group::HVAC,
524 : OutputProcessor::EndUseCat::Condensate);
525 0 : SetupOutputVariable(state,
526 : "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
527 : Constant::Units::m3,
528 0 : this->evaporativeCondSupplyTankConsump,
529 : OutputProcessor::TimeStepType::System,
530 : OutputProcessor::StoreType::Sum,
531 0 : this->name,
532 : Constant::eResource::MainsWater,
533 : OutputProcessor::Group::HVAC,
534 : OutputProcessor::EndUseCat::Cooling);
535 : }
536 55 : if (this->subcoolReheatFlag) {
537 1 : SetupOutputVariable(state,
538 : "SubcoolReheat Cooling Coil Operation Mode",
539 : Constant::Units::None,
540 1 : this->performance->OperatingMode,
541 : OutputProcessor::TimeStepType::System,
542 : OutputProcessor::StoreType::Average,
543 1 : this->name);
544 2 : SetupOutputVariable(state,
545 : "SubcoolReheat Cooling Coil Operation Mode Ratio",
546 : Constant::Units::None,
547 1 : this->performance->ModeRatio,
548 : OutputProcessor::TimeStepType::System,
549 : OutputProcessor::StoreType::Average,
550 1 : this->name);
551 2 : SetupOutputVariable(state,
552 : "SubcoolReheat Cooling Coil Recovered Heat Energy Rate",
553 : Constant::Units::W,
554 1 : this->recoveredHeatEnergyRate,
555 : OutputProcessor::TimeStepType::System,
556 : OutputProcessor::StoreType::Average,
557 1 : this->name);
558 2 : SetupOutputVariable(state,
559 : "SubcoolReheat Cooling Coil Recovered Heat Energy",
560 : Constant::Units::J,
561 1 : this->recoveredHeatEnergy,
562 : OutputProcessor::TimeStepType::System,
563 : OutputProcessor::StoreType::Sum,
564 1 : this->name,
565 : Constant::eResource::EnergyTransfer,
566 : OutputProcessor::Group::HVAC,
567 : OutputProcessor::EndUseCat::HeatRecovery);
568 : }
569 :
570 55 : if (this->isSecondaryDXCoilInZone) {
571 0 : SetupOutputVariable(state,
572 : "Secondary Coil Heat Rejection Rate",
573 : Constant::Units::W,
574 0 : this->secCoilSensHeatRejEnergyRate,
575 : OutputProcessor::TimeStepType::System,
576 : OutputProcessor::StoreType::Average,
577 0 : this->name);
578 :
579 0 : SetupOutputVariable(state,
580 : "Secondary Coil Heat Rejection Energy",
581 : Constant::Units::J,
582 0 : this->secCoilSensHeatRejEnergy,
583 : OutputProcessor::TimeStepType::System,
584 : OutputProcessor::StoreType::Sum,
585 0 : this->name);
586 : }
587 55 : }
588 :
589 58573 : int CoilCoolingDX::getNumModes()
590 : {
591 : // TODO: should this support all 3 modes?
592 58573 : int numModes = 1;
593 58573 : if (this->performance->maxAvailCoilMode != HVAC::CoilMode::Normal) {
594 4 : numModes++;
595 : }
596 58573 : return numModes;
597 : }
598 :
599 50 : int CoilCoolingDX::getOpModeCapFTIndex(HVAC::CoilMode const mode)
600 : {
601 : // TODO: should this support all 3 modes?
602 50 : return this->performance->indexCapFT(mode);
603 : }
604 :
605 54 : void CoilCoolingDX::setData(int fanIndex, HVAC::FanType fanType, std::string const &fanName, int _airLoopNum)
606 : {
607 54 : this->supplyFanIndex = fanIndex;
608 54 : this->supplyFanName = fanName;
609 54 : this->supplyFanType = fanType;
610 54 : this->airLoopNum = _airLoopNum;
611 54 : }
612 :
613 0 : void CoilCoolingDX::getFixedData(int &_evapInletNodeIndex,
614 : int &_evapOutletNodeIndex,
615 : int &_condInletNodeIndex,
616 : int &_normalModeNumSpeeds,
617 : CoilCoolingDXPerformanceBase::CapControlMethod &_capacityControlMethod,
618 : Real64 &_minOutdoorDryBulb)
619 : {
620 0 : _evapInletNodeIndex = this->evapInletNodeIndex;
621 0 : _evapOutletNodeIndex = this->evapOutletNodeIndex;
622 0 : _condInletNodeIndex = this->condInletNodeIndex;
623 0 : _normalModeNumSpeeds = (int)this->performance->numSpeeds();
624 0 : _capacityControlMethod = this->performance->capControlMethod;
625 0 : _minOutdoorDryBulb = this->performance->minOutdoorDrybulb;
626 0 : }
627 :
628 0 : void CoilCoolingDX::getDataAfterSizing(EnergyPlusData &state,
629 : Real64 &_normalModeRatedEvapAirFlowRate,
630 : Real64 &_normalModeRatedCapacity,
631 : std::vector<Real64> &_normalModeFlowRates,
632 : std::vector<Real64> &_normalModeRatedCapacities)
633 : {
634 0 : _normalModeRatedEvapAirFlowRate = this->performance->ratedEvapAirFlowRate(state);
635 0 : _normalModeFlowRates.clear();
636 0 : _normalModeRatedCapacities.clear();
637 0 : for (auto speed = 0; speed < this->performance->numSpeeds(); speed++) {
638 0 : _normalModeFlowRates.push_back(performance->evapAirFlowRateAtSpeedIndex(state, speed));
639 0 : _normalModeRatedCapacities.push_back(performance->ratedTotalCapacityAtSpeedIndex(state, speed));
640 : }
641 0 : _normalModeRatedCapacity = this->performance->ratedGrossTotalCap();
642 0 : }
643 :
644 11257918 : Real64 CoilCoolingDX::condMassFlowRate(EnergyPlusData &state, HVAC::CoilMode const mode)
645 : {
646 : // TODO: should this support all 3 modes?
647 11257918 : return this->performance->ratedCondAirMassFlowRateNomSpeed(state, mode);
648 : }
649 :
650 55 : void CoilCoolingDX::size(EnergyPlusData &state)
651 : {
652 55 : this->performance->parentName = this->name;
653 55 : this->performance->size(state);
654 55 : }
655 :
656 11257918 : void CoilCoolingDX::simulate(EnergyPlusData &state,
657 : HVAC::CoilMode coilMode,
658 : int const speedNum,
659 : Real64 const speedRatio,
660 : HVAC::FanOp const fanOp,
661 : bool const singleMode,
662 : Real64 const LoadSHR)
663 : {
664 11257918 : if (this->myOneTimeInitFlag) {
665 55 : this->oneTimeInit(state);
666 55 : this->myOneTimeInitFlag = false;
667 : }
668 :
669 : static constexpr std::string_view RoutineName = "CoilCoolingDX::simulate";
670 :
671 : // get node references
672 11257918 : auto &evapInletNode = state.dataLoopNodes->Node(this->evapInletNodeIndex);
673 11257918 : auto &evapOutletNode = state.dataLoopNodes->Node(this->evapOutletNodeIndex);
674 11257918 : auto &condInletNode = state.dataLoopNodes->Node(this->condInletNodeIndex);
675 11257918 : auto &condOutletNode = state.dataLoopNodes->Node(this->condOutletNodeIndex);
676 :
677 : // set some reporting variables
678 11257918 : this->condenserInletTemperature = condInletNode.Temp;
679 11257918 : this->dehumidificationMode = coilMode;
680 :
681 : // set condenser inlet/outlet nodes
682 : // once condenser inlet is connected to upstream components, will need to revisit
683 11257918 : condInletNode.MassFlowRate = this->condMassFlowRate(state, coilMode);
684 11257918 : condOutletNode.MassFlowRate = condInletNode.MassFlowRate;
685 :
686 : // call the simulation, which returns useful data
687 : // TODO: check the avail schedule and reset data/pass through data as needed
688 : // TODO: check the minOATcompressor and reset data/pass through data as needed
689 11257918 : this->performance->OperatingMode = 0;
690 11257918 : this->performance->ModeRatio = 0.0;
691 11257918 : this->performance->simulate(
692 : state, evapInletNode, evapOutletNode, coilMode, speedNum, speedRatio, fanOp, condInletNode, condOutletNode, singleMode, LoadSHR);
693 11257918 : CoilCoolingDX::passThroughNodeData(evapInletNode, evapOutletNode);
694 :
695 : // calculate energy conversion factor
696 11257918 : Real64 reportingConstant = state.dataHVACGlobal->TimeStepSys * Constant::rSecsInHour;
697 :
698 : // update condensate collection tank
699 11257918 : if (this->condensateTankIndex > 0) {
700 0 : if (speedNum > 0) {
701 : // calculate and report condensation rates (how much water extracted from the air stream)
702 : // water flow of water in m3/s for water system interactions
703 0 : Real64 averageTemp = (evapInletNode.Temp + evapOutletNode.Temp) / 2.0;
704 0 : Real64 waterDensity = Psychrometrics::RhoH2O(averageTemp);
705 0 : Real64 inHumidityRatio = evapInletNode.HumRat;
706 0 : Real64 outHumidityRatio = evapOutletNode.HumRat;
707 0 : this->condensateVolumeFlow = max(0.0, (evapInletNode.MassFlowRate * (inHumidityRatio - outHumidityRatio) / waterDensity));
708 0 : this->condensateVolumeConsumption = this->condensateVolumeFlow * reportingConstant;
709 0 : state.dataWaterData->WaterStorage(this->condensateTankIndex).VdotAvailSupply(this->condensateTankSupplyARRID) =
710 0 : this->condensateVolumeFlow;
711 0 : state.dataWaterData->WaterStorage(this->condensateTankIndex).TwaterSupply(this->condensateTankSupplyARRID) = evapOutletNode.Temp;
712 : } else {
713 0 : state.dataWaterData->WaterStorage(this->condensateTankIndex).VdotAvailSupply(this->condensateTankSupplyARRID) = 0.0;
714 0 : state.dataWaterData->WaterStorage(this->condensateTankIndex).TwaterSupply(this->condensateTankSupplyARRID) = evapOutletNode.Temp;
715 : }
716 : }
717 :
718 : // update requests for evaporative condenser tank
719 11257918 : if (this->evaporativeCondSupplyTankIndex > 0) {
720 0 : if (speedNum > 0) {
721 : Real64 condInletTemp =
722 0 : state.dataEnvrn->OutWetBulbTemp + (state.dataEnvrn->OutDryBulbTemp - state.dataEnvrn->OutWetBulbTemp) *
723 0 : (1.0 - this->performance->evapCondenserEffectivenessAtSpeedIndex(state, speedNum - 1));
724 : Real64 condInletHumRat =
725 0 : Psychrometrics::PsyWFnTdbTwbPb(state, condInletTemp, state.dataEnvrn->OutWetBulbTemp, state.dataEnvrn->OutBaroPress, RoutineName);
726 0 : Real64 outdoorHumRat = state.dataEnvrn->OutHumRat;
727 :
728 0 : Real64 condAirMassFlow = condInletNode.MassFlowRate;
729 0 : Real64 waterDensity = Psychrometrics::RhoH2O(state.dataEnvrn->OutDryBulbTemp);
730 0 : this->evaporativeCondSupplyTankVolumeFlow = (condInletHumRat - outdoorHumRat) * condAirMassFlow / waterDensity;
731 0 : this->evaporativeCondSupplyTankConsump = this->evaporativeCondSupplyTankVolumeFlow * reportingConstant;
732 0 : if (coilMode == HVAC::CoilMode::Normal) {
733 0 : this->evapCondPumpElecPower = this->performance->currentEvapCondPumpPowerAtSpeed(state, speedNum);
734 : }
735 0 : state.dataWaterData->WaterStorage(this->evaporativeCondSupplyTankIndex).VdotRequestDemand(this->evaporativeCondSupplyTankARRID) =
736 0 : this->evaporativeCondSupplyTankVolumeFlow;
737 : } else {
738 0 : state.dataWaterData->WaterStorage(this->evaporativeCondSupplyTankIndex).VdotRequestDemand(this->evaporativeCondSupplyTankARRID) = 0.0;
739 : }
740 : }
741 :
742 : // update report variables
743 11257918 : this->airMassFlowRate = evapOutletNode.MassFlowRate;
744 11257918 : this->inletAirDryBulbTemp = evapInletNode.Temp;
745 11257918 : this->inletAirHumRat = evapInletNode.HumRat;
746 11257918 : this->outletAirDryBulbTemp = evapOutletNode.Temp;
747 11257918 : this->outletAirHumRat = evapOutletNode.HumRat;
748 :
749 11257918 : CalcComponentSensibleLatentOutput(evapOutletNode.MassFlowRate,
750 : evapInletNode.Temp,
751 : evapInletNode.HumRat,
752 : evapOutletNode.Temp,
753 : evapOutletNode.HumRat,
754 11257918 : this->sensCoolingEnergyRate,
755 11257918 : this->latCoolingEnergyRate,
756 11257918 : this->totalCoolingEnergyRate);
757 11257918 : this->totalCoolingEnergy = this->totalCoolingEnergyRate * reportingConstant;
758 11257918 : this->sensCoolingEnergy = this->sensCoolingEnergyRate * reportingConstant;
759 11257918 : this->latCoolingEnergy = this->latCoolingEnergyRate * reportingConstant;
760 :
761 11257918 : this->evapCondPumpElecConsumption = this->evapCondPumpElecPower * reportingConstant;
762 :
763 11257918 : this->coolingCoilRuntimeFraction = this->performance->RTF;
764 11257918 : this->elecCoolingPower = this->performance->powerUse;
765 11257918 : this->elecCoolingConsumption = this->performance->powerUse * reportingConstant;
766 11257918 : this->wasteHeatEnergyRate = this->performance->wasteHeatRate;
767 11257918 : this->wasteHeatEnergy = this->performance->wasteHeatRate * reportingConstant;
768 :
769 11257918 : this->partLoadRatioReport = speedNum > 1 ? 1.0 : speedRatio;
770 11257918 : this->speedNumReport = speedNum;
771 11257918 : this->speedRatioReport = speedNum <= 1 ? 0.0 : speedRatio;
772 :
773 11257918 : if (coilMode == HVAC::CoilMode::SubcoolReheat) {
774 76864 : this->recoveredHeatEnergyRate = this->performance->recoveredEnergyRate;
775 76864 : this->recoveredHeatEnergy = this->recoveredHeatEnergyRate * reportingConstant;
776 : }
777 :
778 11257918 : if (this->isSecondaryDXCoilInZone) {
779 : // call CalcSecondaryDXCoils ???
780 0 : this->secCoilSensHeatRejEnergyRate = this->totalCoolingEnergyRate + this->elecCoolingPower;
781 0 : this->secCoilSensHeatRejEnergy = this->totalCoolingEnergy + this->elecCoolingConsumption;
782 : }
783 :
784 : // Fishy global things that need to be set here, try to set the AFN stuff now
785 : // This appears to be the only location where airLoopNum gets used
786 : // DataAirLoop::LoopDXCoilRTF = max(this->coolingCoilRuntimeFraction, DXCoil(DXCoilNum).HeatingCoilRuntimeFraction);
787 11257918 : state.dataAirLoop->LoopDXCoilRTF = this->coolingCoilRuntimeFraction;
788 11257918 : state.dataHVACGlobal->DXElecCoolingPower = this->elecCoolingPower;
789 11257918 : if (this->airLoopNum > 0) {
790 0 : state.dataAirLoop->AirLoopAFNInfo(this->airLoopNum).AFNLoopDXCoilRTF = this->coolingCoilRuntimeFraction;
791 : // The original calculation is below, but no heating yet
792 : // max(DXCoil(DXCoilNum).CoolingCoilRuntimeFraction, DXCoil(DXCoilNum).HeatingCoilRuntimeFraction);
793 : }
794 :
795 : // report out to the coil sizing report if needed
796 11257918 : if (this->reportCoilFinalSizes) {
797 1028008 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
798 :
799 : // report out final coil sizing info
800 55 : Real64 ratedSensCap(0.0);
801 55 : ratedSensCap = this->performance->ratedGrossTotalCap() * this->performance->grossRatedSHR(state);
802 55 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(state,
803 55 : this->name,
804 55 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
805 55 : this->performance->ratedGrossTotalCap(),
806 : ratedSensCap,
807 55 : this->performance->ratedEvapAirFlowRate(state),
808 : -999.0);
809 :
810 : // report out fan information
811 : // should work for all fan types
812 55 : if (this->supplyFanIndex > 0) {
813 52 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
814 52 : this->name,
815 52 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
816 52 : state.dataFans->fans(this->supplyFanIndex)->Name,
817 52 : state.dataFans->fans(this->supplyFanIndex)->type,
818 : this->supplyFanIndex);
819 : }
820 :
821 : // report out coil rating conditions, just create a set of dummy nodes and run calculate on them
822 55 : DataLoopNode::NodeData dummyEvapInlet;
823 55 : DataLoopNode::NodeData dummyEvapOutlet;
824 55 : DataLoopNode::NodeData dummyCondInlet;
825 55 : DataLoopNode::NodeData dummyCondOutlet;
826 55 : int dummySpeedNum = 1;
827 55 : Real64 dummySpeedRatio = 1.0;
828 55 : HVAC::FanOp dummyFanOp = HVAC::FanOp::Cycling;
829 55 : bool dummySingleMode = false;
830 :
831 55 : Real64 constexpr RatedInletAirTemp(26.6667); // 26.6667C or 80F
832 55 : Real64 constexpr RatedInletWetBulbTemp(19.44); // 19.44 or 67F
833 55 : Real64 constexpr RatedOutdoorAirTemp(35.0); // 35 C or 95F
834 55 : Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
835 :
836 55 : Real64 ratedInletEvapMassFlowRate = this->performance->ratedEvapAirMassFlowRate(state);
837 55 : dummyEvapInlet.MassFlowRate = ratedInletEvapMassFlowRate;
838 55 : dummyEvapInlet.Temp = RatedInletAirTemp;
839 : Real64 dummyInletAirHumRat =
840 55 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedInletAirTemp, RatedInletWetBulbTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
841 55 : dummyEvapInlet.Press = DataEnvironment::StdPressureSeaLevel;
842 55 : dummyEvapInlet.HumRat = dummyInletAirHumRat;
843 55 : dummyEvapInlet.Enthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, dummyInletAirHumRat);
844 :
845 : // maybe we don't actually need to override weather below, we'll see
846 55 : dummyCondInlet.Temp = RatedOutdoorAirTemp;
847 55 : dummyCondInlet.HumRat =
848 55 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
849 55 : dummyCondInlet.OutAirWetBulb = ratedOutdoorAirWetBulb;
850 55 : dummyCondInlet.Press = condInletNode.Press; // for now; TODO: Investigate
851 :
852 : // overriding outdoor conditions temporarily
853 55 : Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
854 55 : Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
855 55 : Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
856 55 : Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
857 55 : state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
858 55 : state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
859 55 : state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
860 110 : state.dataEnvrn->OutHumRat =
861 55 : Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
862 :
863 55 : this->performance->simulate(state,
864 : dummyEvapInlet,
865 : dummyEvapOutlet,
866 : HVAC::CoilMode::Normal,
867 : dummySpeedNum,
868 : dummySpeedRatio,
869 : dummyFanOp,
870 : dummyCondInlet,
871 : dummyCondOutlet,
872 : dummySingleMode);
873 :
874 : // reset outdoor conditions back to previous state
875 55 : state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
876 55 : state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
877 55 : state.dataEnvrn->OutBaroPress = holdOutBaroPress;
878 55 : state.dataEnvrn->OutHumRat = holdOutHumRat;
879 :
880 : // Real64 const coolingRate = dummyEvapInlet.MassFlowRate * (dummyEvapInlet.Enthalpy - dummyEvapOutlet.Enthalpy);
881 : // Real64 const thisMinAirHumRat = min(dummyEvapInlet.HumRat, dummyEvapOutlet.HumRat);
882 : // Real64 const sensCoolingRate = dummyEvapInlet.MassFlowRate * (Psychrometrics::PsyHFnTdbW(dummyEvapInlet.Temp, thisMinAirHumRat) -
883 : // Psychrometrics::PsyHFnTdbW(dummyEvapOutlet.Temp, thisMinAirHumRat));
884 55 : Real64 coolingRate = 0.0;
885 55 : Real64 sensCoolingRate = 0.0;
886 55 : Real64 latCoolingRate = 0.0;
887 55 : CalcComponentSensibleLatentOutput(dummyEvapInlet.MassFlowRate,
888 : dummyEvapInlet.Temp,
889 : dummyEvapInlet.HumRat,
890 : dummyEvapOutlet.Temp,
891 : dummyEvapOutlet.HumRat,
892 : sensCoolingRate,
893 : latCoolingRate,
894 : coolingRate);
895 :
896 55 : Real64 const ratedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
897 : state, dummyEvapOutlet.Temp, dummyEvapOutlet.HumRat, DataEnvironment::StdPressureSeaLevel, "Coil:Cooling:DX::simulate");
898 55 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(state,
899 55 : this->name,
900 55 : state.dataCoilCoolingDX->coilCoolingDXObjectName,
901 : coolingRate,
902 : sensCoolingRate,
903 : ratedInletEvapMassFlowRate,
904 : RatedInletAirTemp,
905 : dummyInletAirHumRat,
906 : RatedInletWetBulbTemp,
907 : dummyEvapOutlet.Temp,
908 : dummyEvapOutlet.HumRat,
909 : ratedOutletWetBulb,
910 : RatedOutdoorAirTemp,
911 : ratedOutdoorAirWetBulb,
912 55 : this->performance->ratedCBF(state),
913 : -999.0);
914 :
915 55 : this->reportCoilFinalSizes = false;
916 : }
917 : }
918 :
919 : // update available reclaim heat
920 11257918 : this->reclaimHeat.AvailCapacity = this->totalCoolingEnergyRate + this->elecCoolingPower;
921 11257918 : }
922 :
923 0 : void CoilCoolingDX::setToHundredPercentDOAS()
924 : {
925 0 : performance->setToHundredPercentDOAS();
926 0 : }
927 :
928 11257918 : void CoilCoolingDX::passThroughNodeData(DataLoopNode::NodeData &in, DataLoopNode::NodeData &out)
929 : {
930 : // pass through all the other node variables that we don't update as a part of this model calculation
931 11257918 : out.MassFlowRate = in.MassFlowRate;
932 11257918 : out.Press = in.Press;
933 11257918 : out.Quality = in.Quality;
934 11257918 : out.MassFlowRateMax = in.MassFlowRateMax;
935 11257918 : out.MassFlowRateMin = in.MassFlowRateMin;
936 11257918 : out.MassFlowRateMaxAvail = in.MassFlowRateMaxAvail;
937 11257918 : out.MassFlowRateMinAvail = in.MassFlowRateMinAvail;
938 11257918 : }
939 :
940 110 : void PopulateCoolingCoilStandardRatingInformation(InputOutputFile &eio,
941 : std::string coilName,
942 : Real64 &capacity,
943 : Real64 &eer,
944 : Real64 &seer_User,
945 : Real64 &seer_Standard,
946 : Real64 &ieer,
947 : bool const AHRI2023StandardRatings)
948 : {
949 110 : Real64 constexpr ConvFromSIToIP(3.412141633);
950 : // TODO: TOO BIG |Capacity from 135K (39565 W) to 250K Btu/hr (73268 W) - calculated as per AHRI Standard 365-2009 -
951 : // Ratings not yet supported in EnergyPlus
952 : // Define the format string based on the condition
953 110 : std::string_view Format_991;
954 110 : if (!AHRI2023StandardRatings) {
955 55 : Format_991 = " DX Cooling Coil Standard Rating Information, {}, {}, {:.1f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.1f}\n";
956 : } else {
957 55 : Format_991 = " DX Cooling Coil AHRI 2023 Standard Rating Information, {}, {}, {:.1f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.1f}\n";
958 : }
959 110 : print(eio,
960 : Format_991,
961 : "Coil:Cooling:DX",
962 : coilName,
963 : capacity,
964 : eer,
965 0 : eer * ConvFromSIToIP,
966 0 : seer_User * ConvFromSIToIP,
967 0 : seer_Standard * ConvFromSIToIP, // SEER | Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2023.
968 110 : ieer * ConvFromSIToIP); // IEER | Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard
969 : // 340/360-2022.
970 110 : }
971 :
972 781 : void CoilCoolingDX::reportAllStandardRatings(EnergyPlusData &state)
973 : {
974 781 : if (!state.dataCoilCoolingDX->coilCoolingDXs.empty()) {
975 21 : Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
976 21 : if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag) {
977 : static constexpr std::string_view Format_994(
978 : "! <DX Cooling Coil Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
979 : "Cooling Capacity {W}, Standard Rating Net COP {W/W}, EER {Btu/W-h}, SEER User {Btu/W-h}, SEER Standard {Btu/W-h}, "
980 : "IEER "
981 : "{Btu/W-h}");
982 19 : print(state.files.eio, "{}\n", Format_994);
983 19 : state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
984 : }
985 76 : for (auto &coil : state.dataCoilCoolingDX->coilCoolingDXs) {
986 55 : coil.performance->calcStandardRatings210240(state);
987 55 : PopulateCoolingCoilStandardRatingInformation(state.files.eio,
988 55 : coil.name,
989 55 : coil.performance->standardRatingCoolingCapacity,
990 55 : coil.performance->standardRatingEER,
991 55 : coil.performance->standardRatingSEER,
992 55 : coil.performance->standardRatingSEER_Standard,
993 55 : coil.performance->standardRatingIEER,
994 : false);
995 :
996 55 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, coil.name, "Coil:Cooling:DX");
997 110 : OutputReportPredefined::PreDefTableEntry(
998 110 : state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI, coil.name, coil.performance->standardRatingCoolingCapacity, 1);
999 : // W/W is the same as Btuh/Btuh so that's fine too
1000 55 : if (coil.performance->standardRatingEER > 0.0) {
1001 108 : OutputReportPredefined::PreDefTableEntry(
1002 162 : state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, coil.name, coil.performance->standardRatingEER, 2);
1003 : } else {
1004 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, coil.name, "N/A");
1005 : }
1006 : // Btu/W-h will convert to itself
1007 55 : if (coil.performance->standardRatingEER > 0.0) {
1008 54 : OutputReportPredefined::PreDefTableEntry(
1009 108 : state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, coil.name, coil.performance->standardRatingEER * ConvFromSIToIP, 2);
1010 : } else {
1011 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, coil.name, "N/A");
1012 : }
1013 55 : if (coil.performance->standardRatingSEER > 0.0) {
1014 54 : OutputReportPredefined::PreDefTableEntry(
1015 108 : state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, coil.name, coil.performance->standardRatingSEER * ConvFromSIToIP, 2);
1016 : } else {
1017 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, coil.name, "N/A");
1018 : }
1019 55 : if (coil.performance->standardRatingSEER_Standard > 0.0) {
1020 54 : OutputReportPredefined::PreDefTableEntry(state,
1021 54 : state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP,
1022 : coil.name,
1023 54 : coil.performance->standardRatingSEER_Standard * ConvFromSIToIP,
1024 108 : 2);
1025 : } else {
1026 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, coil.name, "N/A");
1027 : }
1028 55 : if (coil.performance->standardRatingIEER > 0.0) {
1029 54 : OutputReportPredefined::PreDefTableEntry(
1030 108 : state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, coil.name, coil.performance->standardRatingIEER * ConvFromSIToIP, 1);
1031 : } else {
1032 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, coil.name, "N/A");
1033 : }
1034 55 : OutputReportPredefined::addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil, StandardRatings::AHRI2017FOOTNOTE);
1035 :
1036 : // AHRI 2023 Standard SEER2 Calculations
1037 55 : if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag2) {
1038 : static constexpr std::string_view Format_991_(
1039 : "! <DX Cooling Coil AHRI 2023 Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
1040 : "Cooling Capacity {W}, Standard Rating Net COP2 {W/W}, EER2 {Btu/W-h}, SEER2 User {Btu/W-h}, SEER2 Standard "
1041 : "{Btu/W-h}, "
1042 : "IEER 2022 "
1043 : "{Btu/W-h}");
1044 19 : print(state.files.eio, "{}\n", Format_991_);
1045 19 : state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag2 = false;
1046 : }
1047 55 : PopulateCoolingCoilStandardRatingInformation(state.files.eio,
1048 55 : coil.name,
1049 55 : coil.performance->standardRatingCoolingCapacity2023,
1050 55 : coil.performance->standardRatingEER2,
1051 55 : coil.performance->standardRatingSEER2_User,
1052 55 : coil.performance->standardRatingSEER2_Standard,
1053 55 : coil.performance->standardRatingIEER2,
1054 : true);
1055 :
1056 55 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType_2023, coil.name, "Coil:Cooling:DX");
1057 110 : OutputReportPredefined::PreDefTableEntry(
1058 110 : state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI_2023, coil.name, coil.performance->standardRatingCoolingCapacity2023, 1);
1059 : // W/W is the same as Btuh/Btuh so that's fine too
1060 55 : if (coil.performance->standardRatingEER2 > 0.0) {
1061 108 : OutputReportPredefined::PreDefTableEntry(
1062 162 : state, state.dataOutRptPredefined->pdchDXCoolCoilCOP_2023, coil.name, coil.performance->standardRatingEER2, 2);
1063 : } else {
1064 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP_2023, coil.name, "N/A");
1065 : }
1066 : // Btu/W-h will convert to itself
1067 55 : if (coil.performance->standardRatingEER2 > 0.0) {
1068 54 : OutputReportPredefined::PreDefTableEntry(
1069 108 : state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP_2023, coil.name, coil.performance->standardRatingEER2 * ConvFromSIToIP, 2);
1070 : } else {
1071 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP_2023, coil.name, "N/A");
1072 : }
1073 55 : if (coil.performance->standardRatingSEER2_User > 0.0) {
1074 54 : OutputReportPredefined::PreDefTableEntry(state,
1075 54 : state.dataOutRptPredefined->pdchDXCoolCoilSEER2UserIP_2023,
1076 : coil.name,
1077 54 : coil.performance->standardRatingSEER2_User * ConvFromSIToIP,
1078 108 : 2);
1079 : } else {
1080 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEER2UserIP_2023, coil.name, "N/A");
1081 : }
1082 55 : if (coil.performance->standardRatingSEER2_Standard > 0.0) {
1083 54 : OutputReportPredefined::PreDefTableEntry(state,
1084 54 : state.dataOutRptPredefined->pdchDXCoolCoilSEER2StandardIP_2023,
1085 : coil.name,
1086 54 : coil.performance->standardRatingSEER2_Standard * ConvFromSIToIP,
1087 108 : 2);
1088 : } else {
1089 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEER2StandardIP_2023, coil.name, "N/A");
1090 : }
1091 55 : if (coil.performance->standardRatingIEER2 > 0.0) {
1092 54 : OutputReportPredefined::PreDefTableEntry(state,
1093 54 : state.dataOutRptPredefined->pdchDXCoolCoilIEERIP_2023,
1094 : coil.name,
1095 54 : coil.performance->standardRatingIEER2 * ConvFromSIToIP,
1096 108 : 1);
1097 : } else {
1098 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP_2023, coil.name, "N/A");
1099 : }
1100 55 : OutputReportPredefined::addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil_2023, StandardRatings::AHRI2023FOOTNOTE);
1101 21 : }
1102 : }
1103 781 : state.dataCoilCoolingDX->stillNeedToReportStandardRatings = false;
1104 781 : }
1105 :
1106 109 : bool CoilCoolingDX::findPerformanceSubclass(EnergyPlus::EnergyPlusData &state,
1107 : const std::string_view object_to_find,
1108 : const std::string &idd_performance_name)
1109 : {
1110 109 : const auto &ip = state.dataInputProcessing->inputProcessor;
1111 :
1112 109 : if (ip->getNumObjectsFound(state, object_to_find) > 0) { // e.g. "Coil::Cooling::DX::CurveFit::Performance"
1113 110 : auto const &json_dict_performance = ip->epJSON.find(std::string(object_to_find)).value();
1114 138 : for (auto &instance : json_dict_performance.items()) {
1115 138 : std::string const &performance_name = EnergyPlus::Util::makeUPPER(instance.key());
1116 138 : if (performance_name == idd_performance_name) { // e.g. "Heat Pump ACDXCoil 1 Performance"
1117 : // ip->markObjectAsUsed(object_to_find, performance_name);
1118 55 : return true;
1119 : }
1120 248 : }
1121 : }
1122 54 : return false;
1123 : }
|