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