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