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 <EnergyPlus/Data/EnergyPlusData.hh>
49 : #include <EnergyPlus/DataAirLoop.hh>
50 : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
51 : #include <EnergyPlus/DataEnvironment.hh>
52 : #include <EnergyPlus/DataHVACGlobals.hh>
53 : #include <EnergyPlus/DataHeatBalance.hh>
54 : #include <EnergyPlus/DataLoopNode.hh>
55 : #include <EnergyPlus/DataPrecisionGlobals.hh>
56 : #include <EnergyPlus/DataSizing.hh>
57 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
58 : #include <EnergyPlus/FluidProperties.hh>
59 : #include <EnergyPlus/General.hh>
60 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
61 : #include <EnergyPlus/Plant/DataPlant.hh>
62 : #include <EnergyPlus/Plant/EquipAndOperations.hh>
63 : #include <EnergyPlus/Plant/Loop.hh>
64 : #include <EnergyPlus/PlantUtilities.hh>
65 : #include <EnergyPlus/Psychrometrics.hh>
66 : #include <EnergyPlus/UtilityRoutines.hh>
67 :
68 : namespace EnergyPlus {
69 : namespace DataPlant {
70 :
71 10 : void ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme(EnergyPlusData &state)
72 : {
73 10 : if (this->oneTimeSetupComplete) return;
74 :
75 3 : SetupOutputVariable(state,
76 : "Supervisory Plant Heat Pump Operation Mode",
77 : Constant::Units::unknown,
78 3 : this->Report.AirSourcePlant_OpMode,
79 : OutputProcessor::TimeStepType::System,
80 : OutputProcessor::StoreType::Average,
81 3 : this->Name);
82 :
83 3 : SetupOutputVariable(state,
84 : "Supervisory Plant Auxiliary Boiler Mode",
85 : Constant::Units::unknown,
86 3 : this->Report.BoilerAux_OpMode,
87 : OutputProcessor::TimeStepType::System,
88 : OutputProcessor::StoreType::Average,
89 3 : this->Name);
90 6 : SetupOutputVariable(state,
91 : "Supervisory Plant Operation Polled Building Heating Load",
92 : Constant::Units::W,
93 3 : this->Report.BuildingPolledHeatingLoad,
94 : OutputProcessor::TimeStepType::System,
95 : OutputProcessor::StoreType::Average,
96 3 : this->Name);
97 6 : SetupOutputVariable(state,
98 : "Supervisory Plant Operation Polled Building Cooling Load",
99 : Constant::Units::W,
100 3 : this->Report.BuildingPolledCoolingLoad,
101 : OutputProcessor::TimeStepType::System,
102 : OutputProcessor::StoreType::Average,
103 3 : this->Name);
104 6 : SetupOutputVariable(state,
105 : "Supervisory Plant Operation Primary Plant Heating Load",
106 : Constant::Units::W,
107 3 : this->Report.PrimaryPlantHeatingLoad,
108 : OutputProcessor::TimeStepType::System,
109 : OutputProcessor::StoreType::Average,
110 3 : this->Name);
111 6 : SetupOutputVariable(state,
112 : "Supervisory Plant Operation Primary Plant Cooling Load",
113 : Constant::Units::W,
114 3 : this->Report.PrimaryPlantCoolingLoad,
115 : OutputProcessor::TimeStepType::System,
116 : OutputProcessor::StoreType::Average,
117 3 : this->Name);
118 :
119 : // routine for setup of chiller heater supervisory plant operation scheme
120 6 : for (int zoneListNum = 1; zoneListNum <= state.dataHeatBal->NumOfZoneLists; ++zoneListNum) {
121 3 : if (this->ZoneListName == state.dataHeatBal->ZoneList(zoneListNum).Name) {
122 :
123 3 : this->PlantOps.NumOfZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
124 3 : this->ZonePtrs.allocate(this->PlantOps.NumOfZones);
125 90 : for (int zoneNumInList = 1; zoneNumInList <= state.dataHeatBal->ZoneList(zoneListNum).NumOfZones; ++zoneNumInList) {
126 87 : this->ZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
127 : }
128 : }
129 : }
130 :
131 3 : if (state.dataHVACGlobal->NumPrimaryAirSys > 0) {
132 3 : this->AirLoopPtrs.allocate(state.dataHVACGlobal->NumPrimaryAirSys); // size to all, if zero then that airloop is not served
133 3 : this->PlantOps.NumOfAirLoops = state.dataHVACGlobal->NumPrimaryAirSys;
134 3 : this->AirLoopPtrs = 0;
135 15 : for (int AirLoopIndex = 1; AirLoopIndex <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopIndex) { // loop over the air systems
136 12 : auto &AirToZoneNodeInfo(state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex));
137 360 : for (int ZonesPolledIndex = 1; ZonesPolledIndex <= this->PlantOps.NumOfZones; ++ZonesPolledIndex) {
138 3885 : for (int ZonesCooledIndex = 1; ZonesCooledIndex <= AirToZoneNodeInfo.NumZonesCooled; ++ZonesCooledIndex) {
139 3537 : if (AirToZoneNodeInfo.CoolCtrlZoneNums(ZonesCooledIndex) == this->ZonePtrs(ZonesPolledIndex)) {
140 87 : this->AirLoopPtrs(AirLoopIndex) = AirLoopIndex;
141 : }
142 : }
143 348 : for (int ZonesHeatedIndex = 1; ZonesHeatedIndex <= AirToZoneNodeInfo.NumZonesHeated; ++ZonesHeatedIndex) {
144 0 : if (AirToZoneNodeInfo.HeatCtrlZoneNums(ZonesHeatedIndex) == this->ZonePtrs(ZonesPolledIndex)) {
145 0 : this->AirLoopPtrs(AirLoopIndex) = AirLoopIndex;
146 : }
147 : }
148 : }
149 : }
150 : }
151 :
152 3 : if (this->PlantOps.NumSimultHeatCoolHeatingEquipLists > 0 && this->PlantOps.NumSimultHeatCoolCoolingEquipLists > 0) {
153 2 : this->PlantOps.SimultHeatCoolOpAvailable = true;
154 : }
155 :
156 3 : this->PlantLoopIndicesBeingSupervised.allocate(state.dataPlnt->TotNumLoops);
157 3 : this->PlantLoopIndicesBeingSupervised = 0;
158 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
159 14 : auto &this_plant_loop(state.dataPlnt->PlantLoop(LoopNum));
160 28 : for (int OpNum = 1, OpNum_end = this_plant_loop.NumOpSchemes; OpNum <= OpNum_end; ++OpNum) {
161 14 : auto const &this_op_scheme(this_plant_loop.OpScheme(OpNum));
162 14 : if (this_op_scheme.Type == OpScheme::ChillerHeaterSupervisory) {
163 10 : this->PlantLoopIndicesBeingSupervised(LoopNum) = LoopNum;
164 : }
165 : }
166 : }
167 :
168 : // find an setup any Plant Load Profile objects on the supervised loops
169 3 : int numLoadProfileOnSupervisedLoops = 0;
170 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
171 14 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
172 : // search for any plant load profile on loop demand side
173 10 : auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Demand));
174 127 : for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
175 234 : for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
176 117 : if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::PlantLoadProfile) {
177 0 : ++numLoadProfileOnSupervisedLoops;
178 : }
179 : }
180 : }
181 : }
182 : }
183 3 : this->PlantOps.numPlantLoadProfiles = numLoadProfileOnSupervisedLoops;
184 :
185 3 : this->PlantLoadProfileComps.allocate(this->PlantOps.numPlantLoadProfiles);
186 3 : int loadProfileCompNum = 1;
187 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
188 14 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
189 : // search for any plant load profile on loop demand side
190 10 : auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Demand));
191 127 : for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
192 234 : for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
193 117 : if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::PlantLoadProfile) {
194 0 : PlantLocation foundLoc;
195 0 : foundLoc.loopNum = LoopNum;
196 0 : foundLoc.loopSideNum = DataPlant::LoopSideLocation::Demand;
197 0 : foundLoc.branchNum = BranchNum;
198 0 : foundLoc.compNum = CompNum;
199 0 : PlantLoadProfileComps(loadProfileCompNum) = foundLoc;
200 0 : ++loadProfileCompNum;
201 : }
202 : }
203 : }
204 : }
205 : } // end load profile setup
206 :
207 : // find and setup any boilers on the supervised loops
208 3 : int numBoilersOnSupervisedLoops = 0;
209 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
210 14 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
211 : // search for any Boiler on loop supply side
212 10 : auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
213 49 : for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
214 83 : for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
215 44 : if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::Boiler_Simple) {
216 3 : ++numBoilersOnSupervisedLoops;
217 : }
218 : }
219 : }
220 : }
221 : }
222 3 : this->PlantOps.numBoilers = numBoilersOnSupervisedLoops;
223 3 : this->PlantBoilerComps.allocate(this->PlantOps.numBoilers);
224 3 : int BoilerCompNum = 1;
225 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
226 14 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
227 : // search for boiler on loop supply side
228 10 : auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
229 49 : for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
230 83 : for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
231 44 : if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::Boiler_Simple) {
232 3 : PlantLocation foundLoc;
233 3 : foundLoc.loopNum = LoopNum;
234 3 : foundLoc.loopSideNum = DataPlant::LoopSideLocation::Supply;
235 3 : foundLoc.branchNum = BranchNum;
236 3 : foundLoc.compNum = CompNum;
237 3 : PlantBoilerComps(BoilerCompNum) = foundLoc;
238 3 : ++BoilerCompNum;
239 : }
240 : }
241 : }
242 : }
243 : } // end boiler setup
244 :
245 : // find and setup any fluid to fluid heat exchangers on the supervised loops
246 3 : this->SecondaryPlantLoopIndicesBeingSupervised.allocate(state.dataPlnt->TotNumLoops);
247 3 : this->SecondaryPlantLoopIndicesBeingSupervised = 0;
248 3 : int numHXsOnSupervisedLoops = 0;
249 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
250 14 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
251 : // search for any Heat axchangers on loop supply side
252 10 : auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
253 49 : for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
254 83 : for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
255 44 : if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::FluidToFluidPlantHtExchg) {
256 4 : ++numHXsOnSupervisedLoops;
257 : }
258 : }
259 : }
260 : }
261 : }
262 3 : this->PlantOps.numPlantHXs = numHXsOnSupervisedLoops;
263 3 : this->PlantHXComps.allocate(this->PlantOps.numPlantHXs);
264 3 : int HXCompNum = 1;
265 17 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
266 14 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
267 : // search for boiler on loop supply side
268 10 : auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
269 49 : for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
270 83 : for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
271 44 : if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::FluidToFluidPlantHtExchg) {
272 4 : PlantLocation foundLoc;
273 4 : foundLoc.loopNum = LoopNum;
274 4 : foundLoc.loopSideNum = DataPlant::LoopSideLocation::Supply;
275 4 : foundLoc.branchNum = BranchNum;
276 4 : foundLoc.compNum = CompNum;
277 4 : PlantHXComps(HXCompNum) = foundLoc;
278 4 : ++HXCompNum;
279 :
280 : // store this loop as being a secondary loop
281 : // assuming that since there is a heat exchanger on the supply side of this loop it is a secondary loop.
282 4 : this->SecondaryPlantLoopIndicesBeingSupervised(LoopNum) = LoopNum;
283 : }
284 : }
285 : }
286 : }
287 : } // end HX setup
288 :
289 : // setup Comp.SetPointNodeNum for machines
290 3 : if (this->PlantOps.NumCoolingOnlyEquipLists > 0) {
291 9 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumCoolingOnlyEquipLists; ++equipListNum) {
292 :
293 6 : int NumComps = this->CoolingOnlyEquipList(equipListNum).NumComps;
294 15 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
295 9 : auto &this_equip(this->CoolingOnlyEquipList(equipListNum).Comp(compNum));
296 9 : PlantLocation compLoc;
297 : DataPlant::PlantEquipmentType Type =
298 9 : static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
299 9 : bool errFlag1(false);
300 9 : int NumSearchResults(0);
301 9 : PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
302 9 : if (NumSearchResults == 1) {
303 :
304 7 : this_equip.LoopNumPtr = compLoc.loopNum;
305 7 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
306 7 : this_equip.BranchNumPtr = compLoc.branchNum;
307 7 : this_equip.CompNumPtr = compLoc.compNum;
308 7 : this->PlantOps.PrimaryChWLoopIndex = compLoc.loopNum;
309 2 : } else if (NumSearchResults > 1) {
310 2 : bool foundit = false;
311 10 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
312 8 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
313 4 : int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
314 4 : if (PltSizNum > 0) {
315 4 : if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Cooling) {
316 2 : int innerNumSearchResults = 0;
317 2 : PlantUtilities::ScanPlantLoopsForObject(
318 : state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
319 2 : if (innerNumSearchResults == 1) {
320 2 : this_equip.LoopNumPtr = compLoc.loopNum;
321 2 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
322 2 : this_equip.BranchNumPtr = compLoc.branchNum;
323 2 : this_equip.CompNumPtr = compLoc.compNum;
324 2 : foundit = true;
325 2 : continue;
326 : }
327 : }
328 : }
329 : }
330 : }
331 2 : if (!foundit) {
332 0 : ShowSevereError(state,
333 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
334 : "component \"{}\" was not found on a cooling plant loop.",
335 0 : this->Name,
336 0 : this_equip.Name));
337 : }
338 0 : } else if (NumSearchResults == 0) {
339 0 : ShowSevereError(state,
340 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
341 : "component \"{}\" was not found on a plant loop.",
342 0 : this->Name,
343 0 : this_equip.Name));
344 : }
345 9 : int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
346 9 : .LoopSide(this_equip.LoopSideNumPtr)
347 9 : .Branch(this_equip.BranchNumPtr)
348 9 : .Comp(this_equip.CompNumPtr)
349 9 : .NodeNumIn;
350 9 : int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
351 9 : .LoopSide(this_equip.LoopSideNumPtr)
352 9 : .Branch(this_equip.BranchNumPtr)
353 9 : .Comp(this_equip.CompNumPtr)
354 9 : .NodeNumOut;
355 9 : this_equip.DemandNodeNum = inletNode;
356 9 : this_equip.SetPointNodeNum = outletNode;
357 9 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
358 9 : .LoopSide(this_equip.LoopSideNumPtr)
359 9 : .Branch(this_equip.BranchNumPtr)
360 9 : .Comp(this_equip.CompNumPtr)
361 9 : .OpScheme.allocate(1);
362 9 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
363 9 : .LoopSide(this_equip.LoopSideNumPtr)
364 9 : .Branch(this_equip.BranchNumPtr)
365 9 : .Comp(this_equip.CompNumPtr)
366 9 : .OpScheme(1)
367 9 : .OpSchemePtr = 1; // TODO check
368 9 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
369 9 : .LoopSide(this_equip.LoopSideNumPtr)
370 9 : .Branch(this_equip.BranchNumPtr)
371 9 : .Comp(this_equip.CompNumPtr)
372 18 : .CurOpSchemeType = this->Type;
373 : }
374 : }
375 : }
376 3 : if (this->PlantOps.NumHeatingOnlyEquipLists > 0) {
377 9 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumHeatingOnlyEquipLists; ++equipListNum) {
378 :
379 6 : int NumComps = this->HeatingOnlyEquipList(equipListNum).NumComps;
380 15 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
381 9 : auto &this_equip(this->HeatingOnlyEquipList(equipListNum).Comp(compNum));
382 9 : PlantLocation compLoc;
383 : DataPlant::PlantEquipmentType Type;
384 9 : Type = static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
385 9 : bool errFlag1(false);
386 9 : int NumSearchResults(0);
387 9 : PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
388 9 : if (NumSearchResults == 1) {
389 :
390 9 : this_equip.LoopNumPtr = compLoc.loopNum;
391 9 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
392 9 : this_equip.BranchNumPtr = compLoc.branchNum;
393 9 : this_equip.CompNumPtr = compLoc.compNum;
394 9 : this->PlantOps.PrimaryHWLoopIndex = compLoc.loopNum;
395 :
396 0 : } else if (NumSearchResults > 1) {
397 :
398 0 : bool foundit = false;
399 0 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
400 0 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
401 0 : int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
402 0 : if (PltSizNum > 0) {
403 0 : if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Heating) {
404 0 : int innerNumSearchResults = 0;
405 0 : PlantUtilities::ScanPlantLoopsForObject(
406 : state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
407 0 : if (innerNumSearchResults == 1) {
408 0 : this_equip.LoopNumPtr = compLoc.loopNum;
409 0 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
410 0 : this_equip.BranchNumPtr = compLoc.branchNum;
411 0 : this_equip.CompNumPtr = compLoc.compNum;
412 0 : foundit = true;
413 0 : continue;
414 : }
415 : }
416 : }
417 : }
418 : }
419 0 : if (!foundit) {
420 0 : ShowSevereError(state,
421 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
422 : "component \"{}\" was not found on a heating plant loop.",
423 0 : this->Name,
424 0 : this_equip.Name));
425 : }
426 0 : } else if (NumSearchResults == 0) {
427 0 : ShowSevereError(state,
428 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
429 : "component \"{}\" was not found on a plant loop.",
430 0 : this->Name,
431 0 : this_equip.Name));
432 : }
433 9 : int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
434 9 : .LoopSide(this_equip.LoopSideNumPtr)
435 9 : .Branch(this_equip.BranchNumPtr)
436 9 : .Comp(this_equip.CompNumPtr)
437 9 : .NodeNumIn;
438 9 : int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
439 9 : .LoopSide(this_equip.LoopSideNumPtr)
440 9 : .Branch(this_equip.BranchNumPtr)
441 9 : .Comp(this_equip.CompNumPtr)
442 9 : .NodeNumOut;
443 9 : this_equip.DemandNodeNum = inletNode;
444 9 : this_equip.SetPointNodeNum = outletNode;
445 9 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
446 9 : .LoopSide(this_equip.LoopSideNumPtr)
447 9 : .Branch(this_equip.BranchNumPtr)
448 9 : .Comp(this_equip.CompNumPtr)
449 9 : .OpScheme.allocate(1);
450 9 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
451 9 : .LoopSide(this_equip.LoopSideNumPtr)
452 9 : .Branch(this_equip.BranchNumPtr)
453 9 : .Comp(this_equip.CompNumPtr)
454 9 : .OpScheme(1)
455 9 : .OpSchemePtr = 1; // TODO check
456 9 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
457 9 : .LoopSide(this_equip.LoopSideNumPtr)
458 9 : .Branch(this_equip.BranchNumPtr)
459 9 : .Comp(this_equip.CompNumPtr)
460 18 : .CurOpSchemeType = this->Type;
461 : }
462 : }
463 : }
464 :
465 3 : if (this->PlantOps.NumSimultHeatCoolCoolingEquipLists > 0) {
466 4 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolCoolingEquipLists; ++equipListNum) {
467 :
468 2 : int NumComps = this->SimultHeatCoolCoolingEquipList(equipListNum).NumComps;
469 4 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
470 2 : auto &this_equip(this->SimultHeatCoolCoolingEquipList(equipListNum).Comp(compNum));
471 2 : PlantLocation compLoc;
472 : DataPlant::PlantEquipmentType Type;
473 2 : Type = static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
474 2 : bool errFlag1(false);
475 2 : int NumSearchResults(0);
476 2 : PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
477 2 : if (NumSearchResults == 1) {
478 :
479 2 : this_equip.LoopNumPtr = compLoc.loopNum;
480 2 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
481 2 : this_equip.BranchNumPtr = compLoc.branchNum;
482 2 : this_equip.CompNumPtr = compLoc.compNum;
483 :
484 0 : } else if (NumSearchResults > 1) {
485 :
486 0 : bool foundit = false;
487 0 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
488 0 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
489 0 : int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
490 0 : if (PltSizNum > 0) {
491 0 : if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Cooling) {
492 0 : int innerNumSearchResults = 0;
493 0 : PlantUtilities::ScanPlantLoopsForObject(
494 : state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
495 0 : if (innerNumSearchResults == 1) {
496 0 : this_equip.LoopNumPtr = compLoc.loopNum;
497 0 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
498 0 : this_equip.BranchNumPtr = compLoc.branchNum;
499 0 : this_equip.CompNumPtr = compLoc.compNum;
500 0 : foundit = true;
501 0 : continue;
502 : }
503 : }
504 : }
505 : }
506 : }
507 0 : if (!foundit) {
508 0 : ShowSevereError(state,
509 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
510 : "component \"{}\" was not found on a cooling plant loop.",
511 0 : this->Name,
512 0 : this_equip.Name));
513 : }
514 0 : } else if (NumSearchResults == 0) {
515 0 : ShowSevereError(state,
516 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
517 : "component \"{}\" was not found on a plant loop.",
518 0 : this->Name,
519 0 : this_equip.Name));
520 : }
521 2 : int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
522 2 : .LoopSide(this_equip.LoopSideNumPtr)
523 2 : .Branch(this_equip.BranchNumPtr)
524 2 : .Comp(this_equip.CompNumPtr)
525 2 : .NodeNumIn;
526 2 : int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
527 2 : .LoopSide(this_equip.LoopSideNumPtr)
528 2 : .Branch(this_equip.BranchNumPtr)
529 2 : .Comp(this_equip.CompNumPtr)
530 2 : .NodeNumOut;
531 2 : this_equip.DemandNodeNum = inletNode;
532 2 : this_equip.SetPointNodeNum = outletNode;
533 2 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
534 2 : .LoopSide(this_equip.LoopSideNumPtr)
535 2 : .Branch(this_equip.BranchNumPtr)
536 2 : .Comp(this_equip.CompNumPtr)
537 2 : .OpScheme.allocate(1);
538 2 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
539 2 : .LoopSide(this_equip.LoopSideNumPtr)
540 2 : .Branch(this_equip.BranchNumPtr)
541 2 : .Comp(this_equip.CompNumPtr)
542 2 : .OpScheme(1)
543 2 : .OpSchemePtr = 1; // TODO check
544 2 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
545 2 : .LoopSide(this_equip.LoopSideNumPtr)
546 2 : .Branch(this_equip.BranchNumPtr)
547 2 : .Comp(this_equip.CompNumPtr)
548 4 : .CurOpSchemeType = this->Type;
549 : }
550 : }
551 : }
552 :
553 3 : if (this->PlantOps.NumSimultHeatCoolHeatingEquipLists > 0) {
554 4 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolHeatingEquipLists; ++equipListNum) {
555 :
556 2 : int NumComps = this->SimultHeatCoolHeatingEquipList(equipListNum).NumComps;
557 4 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
558 2 : auto &this_equip(this->SimultHeatCoolHeatingEquipList(equipListNum).Comp(compNum));
559 2 : PlantLocation compLoc;
560 : DataPlant::PlantEquipmentType Type;
561 2 : Type = static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
562 2 : bool errFlag1(false);
563 2 : int NumSearchResults(0);
564 2 : PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
565 2 : if (NumSearchResults == 1) {
566 :
567 2 : this_equip.LoopNumPtr = compLoc.loopNum;
568 2 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
569 2 : this_equip.BranchNumPtr = compLoc.branchNum;
570 2 : this_equip.CompNumPtr = compLoc.compNum;
571 :
572 0 : } else if (NumSearchResults > 1) {
573 :
574 0 : bool foundit = false;
575 0 : for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
576 0 : if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
577 0 : int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
578 0 : if (PltSizNum > 0) {
579 0 : if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Heating) {
580 0 : int innerNumSearchResults = 0;
581 0 : PlantUtilities::ScanPlantLoopsForObject(
582 : state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
583 0 : if (innerNumSearchResults == 1) {
584 0 : this_equip.LoopNumPtr = compLoc.loopNum;
585 0 : this_equip.LoopSideNumPtr = compLoc.loopSideNum;
586 0 : this_equip.BranchNumPtr = compLoc.branchNum;
587 0 : this_equip.CompNumPtr = compLoc.compNum;
588 0 : foundit = true;
589 0 : continue;
590 : }
591 : }
592 : }
593 : }
594 : }
595 0 : if (!foundit) {
596 0 : ShowSevereError(state,
597 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
598 : "component \"{}\" was not found on a heating plant loop.",
599 0 : this->Name,
600 0 : this_equip.Name));
601 : }
602 0 : } else if (NumSearchResults == 0) {
603 0 : ShowSevereError(state,
604 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
605 : "component \"{}\" was not found on a plant loop.",
606 0 : this->Name,
607 0 : this_equip.Name));
608 : }
609 2 : int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
610 2 : .LoopSide(this_equip.LoopSideNumPtr)
611 2 : .Branch(this_equip.BranchNumPtr)
612 2 : .Comp(this_equip.CompNumPtr)
613 2 : .NodeNumIn;
614 2 : int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
615 2 : .LoopSide(this_equip.LoopSideNumPtr)
616 2 : .Branch(this_equip.BranchNumPtr)
617 2 : .Comp(this_equip.CompNumPtr)
618 2 : .NodeNumOut;
619 2 : this_equip.DemandNodeNum = inletNode;
620 2 : this_equip.SetPointNodeNum = outletNode;
621 2 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
622 2 : .LoopSide(this_equip.LoopSideNumPtr)
623 2 : .Branch(this_equip.BranchNumPtr)
624 2 : .Comp(this_equip.CompNumPtr)
625 2 : .OpScheme.allocate(1);
626 2 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
627 2 : .LoopSide(this_equip.LoopSideNumPtr)
628 2 : .Branch(this_equip.BranchNumPtr)
629 2 : .Comp(this_equip.CompNumPtr)
630 2 : .OpScheme(1)
631 2 : .OpSchemePtr = 1; // TODO check
632 2 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
633 2 : .LoopSide(this_equip.LoopSideNumPtr)
634 2 : .Branch(this_equip.BranchNumPtr)
635 2 : .Comp(this_equip.CompNumPtr)
636 4 : .CurOpSchemeType = this->Type;
637 : }
638 : }
639 : }
640 :
641 : // process primary loops for supply inlet node numbers
642 :
643 : // examine supply inlet branch on primary chilled water loop to see if there is a tank, use outlet of tank if so
644 :
645 3 : if (this->PlantOps.PrimaryChWLoopIndex > 0) {
646 :
647 3 : this->PlantOps.PrimaryChWLoopSupInletNode =
648 3 : state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).NodeNumIn;
649 7 : for (int numComps = 1; numComps <= state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex)
650 7 : .LoopSide(DataPlant::LoopSideLocation::Supply)
651 7 : .Branch(1)
652 7 : .TotalComponents;
653 : ++numComps) {
654 4 : auto const &this_Comp(state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex)
655 4 : .LoopSide(DataPlant::LoopSideLocation::Supply)
656 4 : .Branch(1)
657 4 : .Comp(numComps));
658 4 : if (this_Comp.Type == DataPlant::PlantEquipmentType::ChilledWaterTankMixed ||
659 3 : this_Comp.Type == DataPlant::PlantEquipmentType::ChilledWaterTankStratified) {
660 : // assume tank is on chilled water return for use as a buffer tank, use the outlet of the tank instead of the inlet when
661 : // calculating the current load on the primary chilled water plant
662 1 : this->PlantOps.PrimaryChWLoopSupInletNode = this_Comp.NodeNumOut;
663 : }
664 : }
665 : }
666 :
667 3 : if (this->PlantOps.PrimaryHWLoopIndex > 0) {
668 3 : this->PlantOps.PrimaryHWLoopSupInletNode =
669 3 : state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).NodeNumIn;
670 : }
671 : // process dedicated heat recovery water to water heatpumps to control
672 3 : if (this->PlantOps.DedicatedHR_ChWRetControl_Input && this->PlantOps.DedicatedHR_HWRetControl_Input) {
673 1 : bool founditCooling = false;
674 1 : bool founditHeating = false;
675 7 : for (auto &thisHP : state.dataEIRPlantLoopHeatPump->heatPumps) {
676 6 : std::string const thisPLHPName = Util::makeUPPER(thisHP.name);
677 : // find cooling side heat pump
678 6 : std::string const targetDedHRCoolName = Util::makeUPPER(this->DedicatedHR_ChWRetControl_Name);
679 6 : if (thisPLHPName == targetDedHRCoolName) { // found it
680 1 : this->DedicatedHR_CoolingPLHP = thisHP; // store pointer to cooling side of heat pump
681 1 : founditCooling = true;
682 :
683 1 : int pltSizNum = state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum).PlantSizNum;
684 1 : this->PlantOps.DedicatedHR_SecChW_DesignCapacity = state.dataSize->PlantSizData(pltSizNum).DesCapacity;
685 1 : this->PlantOps.SecondaryChWLoopIndex = this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum;
686 :
687 : // set up load side plant loop information for cooling side of heat pump
688 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
689 1 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
690 1 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
691 1 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
692 1 : .OpScheme.allocate(1);
693 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
694 1 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
695 1 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
696 1 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
697 1 : .OpScheme(1)
698 1 : .OpSchemePtr = 1;
699 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
700 1 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
701 1 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
702 1 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
703 1 : .CurOpSchemeType = this->Type;
704 :
705 : // setup source side plant loop data structure information for cooling side of heat pump
706 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
707 1 : .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
708 1 : .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
709 1 : .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
710 1 : .OpScheme.allocate(1);
711 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
712 1 : .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
713 1 : .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
714 1 : .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
715 1 : .OpScheme(1)
716 1 : .OpSchemePtr = 1;
717 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
718 1 : .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
719 1 : .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
720 1 : .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
721 2 : .CurOpSchemeType = this->Type;
722 : }
723 :
724 : // find heating side heat pump
725 6 : std::string const targetDedHRHeatName = Util::makeUPPER(this->DedicatedHR_HWRetControl_Name);
726 6 : if (thisPLHPName == targetDedHRHeatName) { // found it
727 1 : this->DedicatedHR_HeatingPLHP = thisHP; // store pointer to heating side of heat pump
728 1 : founditHeating = true;
729 :
730 1 : int pltSizNum = state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum).PlantSizNum;
731 1 : this->PlantOps.DedicatedHR_SecHW_DesignCapacity = state.dataSize->PlantSizData(pltSizNum).DesCapacity;
732 1 : this->PlantOps.SecondaryHWLoopIndex = this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum;
733 :
734 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
735 1 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
736 1 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
737 1 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
738 1 : .OpScheme.allocate(1);
739 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
740 1 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
741 1 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
742 1 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
743 1 : .OpScheme(1)
744 1 : .OpSchemePtr = 1;
745 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
746 1 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
747 1 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
748 1 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
749 1 : .CurOpSchemeType = this->Type;
750 :
751 : // setup source side plant loop data structure information for heating side of heat pump
752 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
753 1 : .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
754 1 : .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
755 1 : .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
756 1 : .OpScheme.allocate(1);
757 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
758 1 : .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
759 1 : .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
760 1 : .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
761 1 : .OpScheme(1)
762 1 : .OpSchemePtr = 1;
763 1 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
764 1 : .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
765 1 : .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
766 1 : .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
767 2 : .CurOpSchemeType = this->Type;
768 : }
769 7 : }
770 :
771 1 : if (!founditCooling) {
772 0 : ShowSevereError(state,
773 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" component "
774 : "\"{}\" was not found on a cooling plant loop.",
775 0 : this->Name,
776 0 : this->DedicatedHR_ChWRetControl_Name));
777 : }
778 1 : if (!founditHeating) {
779 0 : ShowSevereError(state,
780 0 : format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" component "
781 : "\"{}\" was not found on a heating plant loop.",
782 0 : this->Name,
783 0 : this->DedicatedHR_ChWRetControl_Name));
784 : }
785 1 : if (founditCooling && founditHeating) {
786 1 : this->PlantOps.DedicatedHR_Present = true;
787 1 : SetupOutputVariable(state,
788 : "Supervisory Plant Heat Recovery Operation Mode",
789 : Constant::Units::unknown,
790 1 : this->Report.DedicHR_OpMode,
791 : OutputProcessor::TimeStepType::System,
792 : OutputProcessor::StoreType::Average,
793 1 : this->Name);
794 2 : SetupOutputVariable(state,
795 : "Supervisory Plant Operation Secondary Plant Heating Load",
796 : Constant::Units::W,
797 1 : this->Report.SecondaryPlantHeatingLoad,
798 : OutputProcessor::TimeStepType::System,
799 : OutputProcessor::StoreType::Average,
800 1 : this->Name);
801 2 : SetupOutputVariable(state,
802 : "Supervisory Plant Operation Secondary Plant Cooling Load",
803 : Constant::Units::W,
804 1 : this->Report.SecondaryPlantCoolingLoad,
805 : OutputProcessor::TimeStepType::System,
806 : OutputProcessor::StoreType::Average,
807 1 : this->Name);
808 : }
809 : }
810 :
811 3 : this->oneTimeSetupComplete = true;
812 : }
813 :
814 330345 : void ChillerHeaterSupervisoryOperationData::EvaluateChillerHeaterChangeoverOpScheme(EnergyPlusData &state)
815 : {
816 :
817 330345 : DetermineCurrentBuildingLoads(state);
818 330345 : DetermineCurrentPlantLoads(state);
819 330345 : ProcessSupervisoryControlLogicForAirSourcePlants(state);
820 330345 : InitAirSourcePlantEquipmentOff(state);
821 330345 : ProcessAndSetAirSourcePlantEquipLists(state);
822 330345 : ProcessAndSetDedicatedHeatRecovWWHP(state);
823 330345 : ProcessAndSetAuxilBoiler(state);
824 330345 : }
825 :
826 330345 : void ChillerHeaterSupervisoryOperationData::DetermineCurrentBuildingLoads(EnergyPlusData &state)
827 : {
828 : // Poll the loads on the zones to help decide how to run
829 :
830 330345 : Real64 sumZonePredictedHeatingLoad(0.0);
831 330345 : Real64 sumZonePredictedCoolingLoad(0.0);
832 12358185 : for (int zoneIndexinList = 1; zoneIndexinList <= this->PlantOps.NumOfZones; ++zoneIndexinList) {
833 12027840 : int thisZoneIndex = this->ZonePtrs(zoneIndexinList);
834 12027840 : Real64 ZoneMult = state.dataHeatBal->Zone(thisZoneIndex).Multiplier * state.dataHeatBal->Zone(thisZoneIndex).ListMultiplier;
835 : // aggregate required outputs to setpoint, with zone multipliers included
836 12027840 : sumZonePredictedCoolingLoad +=
837 12027840 : min(0.0,
838 12027840 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisZoneIndex).OutputRequiredToCoolingSP * ZoneMult); // sum only negative values
839 12027840 : sumZonePredictedHeatingLoad +=
840 12027840 : max(0.0,
841 12027840 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisZoneIndex).OutputRequiredToHeatingSP * ZoneMult); // sum only positive values
842 : }
843 :
844 : // now add in ventilation loading at the central air system level
845 330345 : Real64 sumAirSysVentHeatingLoad(0.0);
846 330345 : Real64 sumAirSysVentCoolingLoad(0.0);
847 :
848 1651725 : for (int airLoopsServedIndex = 1; airLoopsServedIndex <= this->PlantOps.NumOfAirLoops; ++airLoopsServedIndex) {
849 1321380 : int AirLoopNum = this->AirLoopPtrs(airLoopsServedIndex);
850 1321380 : Real64 outAir_H = state.dataEnvrn->OutEnthalpy;
851 1321380 : Real64 outAirMdot = state.dataAirLoop->AirLoopFlow(AirLoopNum).OAFlow;
852 1321380 : Real64 retAir_Tdb = state.dataLoopNodes->Node(state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(1)).Temp;
853 1321380 : Real64 retAir_w = state.dataLoopNodes->Node(state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(1)).HumRat;
854 1321380 : Real64 ventLoad = outAirMdot * (Psychrometrics::PsyHFnTdbW(retAir_Tdb, retAir_w) - outAir_H); // negative is cooling
855 1321380 : if (ventLoad > HVAC::SmallLoad) { // add to heating
856 548669 : sumAirSysVentHeatingLoad += ventLoad;
857 772711 : } else if (ventLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) { // add to cooling
858 649637 : sumAirSysVentCoolingLoad += ventLoad;
859 : }
860 : }
861 :
862 : // now add in any process loads from plant load profiles on the controlled loops.
863 330345 : Real64 sumLoadProfileHeatingLoad(0.0);
864 330345 : Real64 sumLoadProfileCoolingLoad(0.0);
865 330345 : for (int NumProcLoad = 1; NumProcLoad <= this->PlantOps.numPlantLoadProfiles; ++NumProcLoad) {
866 0 : Real64 load = 0.0;
867 0 : DataPlant::CompData::getPlantComponent(state, PlantLoadProfileComps(NumProcLoad)).compPtr->getCurrentPower(state, load);
868 0 : if (load > 0.0) {
869 0 : sumLoadProfileHeatingLoad += load;
870 : } else {
871 0 : sumLoadProfileCoolingLoad += load;
872 : }
873 : }
874 :
875 330345 : this->Report.BuildingPolledCoolingLoad = sumZonePredictedCoolingLoad + sumAirSysVentCoolingLoad + sumLoadProfileCoolingLoad;
876 330345 : this->Report.BuildingPolledHeatingLoad = sumZonePredictedHeatingLoad + sumAirSysVentHeatingLoad + sumLoadProfileHeatingLoad;
877 : // end collect loads.
878 330345 : }
879 :
880 330345 : void ChillerHeaterSupervisoryOperationData::DetermineCurrentPlantLoads(EnergyPlusData &state)
881 : {
882 :
883 : // Calculate load on primary chilled water loop and store in PrimaryPlantCoolingLoad
884 :
885 330345 : Real64 CW_RetMdot = state.dataLoopNodes->Node(this->PlantOps.PrimaryChWLoopSupInletNode).MassFlowRate;
886 660690 : Real64 const CpCW = FluidProperties::GetSpecificHeatGlycol(state,
887 330345 : state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex).FluidName,
888 330345 : state.dataLoopNodes->Node(this->PlantOps.PrimaryChWLoopSupInletNode).Temp,
889 330345 : state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex).FluidIndex,
890 : "DetermineCurrentPlantLoads");
891 : Real64 CW_Qdot =
892 330345 : min(0.0,
893 330345 : CW_RetMdot * CpCW *
894 660690 : (this->Setpoint.PrimCW -
895 330345 : state.dataLoopNodes->Node(this->PlantOps.PrimaryChWLoopSupInletNode).Temp)); // power = Mdot Cp Delta T, cooling load is negative
896 330345 : this->Report.PrimaryPlantCoolingLoad = CW_Qdot;
897 :
898 : // Calculate load on primary hot water loop and store in PrimaryPlantHeatingLoad
899 : // int HWSupInletNode = this->PlantOps.PrimaryHWLoopSupInletNode;
900 : // state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).NodeNumIn;
901 330345 : Real64 HW_RetMdot = state.dataLoopNodes->Node(this->PlantOps.PrimaryHWLoopSupInletNode).MassFlowRate;
902 660690 : Real64 const CpHW = FluidProperties::GetSpecificHeatGlycol(state,
903 330345 : state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex).FluidName,
904 330345 : state.dataLoopNodes->Node(this->PlantOps.PrimaryHWLoopSupInletNode).Temp,
905 330345 : state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex).FluidIndex,
906 : "DetermineCurrentPlantLoads");
907 :
908 : Real64 HW_Qdot =
909 330345 : max(0.0,
910 330345 : HW_RetMdot * CpHW *
911 330345 : (this->DetermineHWSetpointOARest(state) -
912 330345 : state.dataLoopNodes->Node(this->PlantOps.PrimaryHWLoopSupInletNode).Temp)); // power = Mdot Cp Delta T, heating load is positive
913 330345 : this->Report.PrimaryPlantHeatingLoad = HW_Qdot;
914 330345 : }
915 :
916 330345 : void ChillerHeaterSupervisoryOperationData::ProcessSupervisoryControlLogicForAirSourcePlants(EnergyPlusData &state)
917 : {
918 : // this routine decides which of three modes the plants should operate in, Heating Only, Cooling Only, Simultaneous Heating and Cooling.
919 :
920 : // step 1, initialize control bools
921 330345 : this->PlantOps.AirSourcePlantCoolingOnly = false;
922 330345 : this->PlantOps.AirSourcePlantHeatingOnly = false;
923 330345 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
924 330345 : this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant = false;
925 330345 : this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant = false;
926 :
927 : // step 2, process logic based on poll results for building loads.
928 330345 : if (this->Report.BuildingPolledHeatingLoad < HVAC::SmallLoad &&
929 171633 : this->Report.BuildingPolledCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
930 169561 : this->PlantOps.AirSourcePlantCoolingOnly = true;
931 160784 : } else if (this->Report.BuildingPolledCoolingLoad > DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad &&
932 155848 : this->Report.BuildingPolledHeatingLoad > HVAC::SmallLoad) {
933 153776 : this->PlantOps.AirSourcePlantHeatingOnly = true;
934 :
935 153776 : if (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp) { // too cold for airsource HPs so
936 103002 : this->PlantOps.AirSourcePlantHeatingOnly = false;
937 : }
938 :
939 7008 : } else if ((this->Report.BuildingPolledCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) &&
940 4936 : (this->Report.BuildingPolledHeatingLoad > HVAC::SmallLoad)) {
941 4936 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
942 4936 : if (this->Report.BuildingPolledHeatingLoad > abs(this->Report.BuildingPolledCoolingLoad)) {
943 563 : this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant = true;
944 563 : if (this->PlantOps.SimultHeatCoolOpAvailable) {
945 160 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
946 : } else {
947 403 : this->PlantOps.AirSourcePlantHeatingOnly = true;
948 403 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
949 : }
950 4373 : } else if (abs(this->Report.BuildingPolledCoolingLoad) > this->Report.BuildingPolledHeatingLoad) {
951 4373 : this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant = true;
952 4373 : if (this->PlantOps.SimultHeatCoolOpAvailable) {
953 171 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
954 : } else {
955 4202 : this->PlantOps.AirSourcePlantCoolingOnly = true;
956 4202 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
957 : }
958 : }
959 4936 : if (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp) { // too cold for airsource HPs
960 0 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
961 0 : this->PlantOps.AirSourcePlantCoolingOnly = true;
962 : }
963 : }
964 :
965 : // step 3, revise control decision based on current loads on primary plant loops
966 330345 : if (this->PlantOps.AirSourcePlantHeatingOnly &&
967 51177 : this->Report.PrimaryPlantCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
968 : // polled building loads indicate all heating, but cooling plant has cooling load, try to switch to simultaneous cooling and heating with
969 : // heating dominant
970 27 : if (this->PlantOps.SimultHeatCoolOpAvailable) {
971 0 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
972 0 : this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant = true;
973 0 : this->PlantOps.AirSourcePlantHeatingOnly = false;
974 : }
975 : }
976 :
977 374012 : if (this->PlantOps.AirSourcePlantCoolingOnly && this->Report.PrimaryPlantHeatingLoad > HVAC::SmallLoad &&
978 43667 : state.dataEnvrn->OutDryBulbTemp >= this->TempReset.LowOutdoorTemp) {
979 : // polled building loads indicate all cooling, but heating plant has heating load, and outdoor air is warm enough for heat pump, try to
980 : // switch to simultaneous cooling and heating with cooling dominant
981 43667 : if (this->PlantOps.SimultHeatCoolOpAvailable) {
982 25880 : this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
983 25880 : this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant = true;
984 25880 : this->PlantOps.AirSourcePlantCoolingOnly = false;
985 : }
986 : }
987 :
988 : // do we need to turn on cooling-only if in off mode but PrimaryPlantCoolingLoad is loaded?
989 330345 : if (!this->PlantOps.AirSourcePlantCoolingOnly && !this->PlantOps.AirSourcePlantHeatingOnly &&
990 131285 : !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
991 105074 : if (this->Report.PrimaryPlantCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
992 43080 : this->PlantOps.AirSourcePlantCoolingOnly = true;
993 : }
994 : }
995 :
996 : // override reset AirSourcePlantHeatingOnly to false and AirSourcePlantCoolingOnly to true if the plant cooling load is higher
997 : // the plant heating load and the plant heating load is small.
998 330345 : if (!this->PlantOps.AirSourcePlantCoolingOnly && this->PlantOps.AirSourcePlantHeatingOnly &&
999 51177 : !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
1000 51204 : if (std::abs(this->Report.PrimaryPlantCoolingLoad) > this->Report.PrimaryPlantHeatingLoad &&
1001 27 : this->Report.PrimaryPlantHeatingLoad < HVAC::SmallLoad) {
1002 27 : this->PlantOps.AirSourcePlantCoolingOnly = true;
1003 27 : this->PlantOps.AirSourcePlantHeatingOnly = false;
1004 : }
1005 : }
1006 :
1007 : // override reset AirSourcePlantHeatingOnly to true and AirSourcePlantCoolingOnly to false if the plant heating load is higher
1008 : // the plant cooling load and the plant cooling load is small.
1009 330345 : if (this->PlantOps.AirSourcePlantCoolingOnly && !this->PlantOps.AirSourcePlantHeatingOnly &&
1010 190990 : !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
1011 218964 : if (this->Report.PrimaryPlantHeatingLoad > std::abs(this->Report.PrimaryPlantCoolingLoad) &&
1012 27974 : this->Report.PrimaryPlantCoolingLoad > DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
1013 0 : this->PlantOps.AirSourcePlantHeatingOnly = true;
1014 0 : this->PlantOps.AirSourcePlantCoolingOnly = false;
1015 : }
1016 : }
1017 :
1018 : // do we need to turn on heating-only if in off mode but PrimaryPlantHeatingLoad is loaded?
1019 330345 : if (!this->PlantOps.AirSourcePlantCoolingOnly && !this->PlantOps.AirSourcePlantHeatingOnly &&
1020 88205 : !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
1021 61994 : if (this->Report.PrimaryPlantHeatingLoad > HVAC::SmallLoad && state.dataEnvrn->OutDryBulbTemp >= this->TempReset.LowOutdoorTemp) {
1022 130 : this->PlantOps.AirSourcePlantHeatingOnly = true;
1023 : }
1024 : }
1025 :
1026 : // step 4, convert logical flags into integers for output variable reporting
1027 330345 : if (this->PlantOps.AirSourcePlantHeatingOnly) {
1028 51280 : this->Report.AirSourcePlant_OpMode = 1;
1029 279065 : } else if (this->PlantOps.AirSourcePlantCoolingOnly) {
1030 190990 : this->Report.AirSourcePlant_OpMode = 2;
1031 88075 : } else if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) {
1032 26211 : this->Report.AirSourcePlant_OpMode = 3;
1033 : } else {
1034 61864 : this->Report.AirSourcePlant_OpMode = 0;
1035 : }
1036 330345 : }
1037 :
1038 330345 : void ChillerHeaterSupervisoryOperationData::InitAirSourcePlantEquipmentOff(EnergyPlusData &state)
1039 : {
1040 : //_____________________________________________________________________________
1041 : // initialize all possible equipment to turn off machines before applying controls to turn them on.
1042 : // set .Available and .ON to false in plant structure
1043 :
1044 330345 : if (this->PlantOps.NumCoolingOnlyEquipLists > 0) {
1045 991035 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumCoolingOnlyEquipLists; ++equipListNum) {
1046 660690 : int NumComps = this->CoolingOnlyEquipList(equipListNum).NumComps;
1047 1651725 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1048 991035 : auto &this_equip(this->CoolingOnlyEquipList(equipListNum).Comp(compNum));
1049 991035 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1050 991035 : .LoopSide(this_equip.LoopSideNumPtr)
1051 991035 : .Branch(this_equip.BranchNumPtr)
1052 991035 : .Comp(this_equip.CompNumPtr)
1053 991035 : .Available = false;
1054 991035 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1055 991035 : .LoopSide(this_equip.LoopSideNumPtr)
1056 991035 : .Branch(this_equip.BranchNumPtr)
1057 991035 : .Comp(this_equip.CompNumPtr)
1058 991035 : .ON = false;
1059 : }
1060 : }
1061 : }
1062 :
1063 330345 : if (this->PlantOps.NumHeatingOnlyEquipLists > 0) {
1064 991035 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumHeatingOnlyEquipLists; ++equipListNum) {
1065 660690 : int NumComps = this->HeatingOnlyEquipList(equipListNum).NumComps;
1066 1651725 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1067 991035 : auto &this_equip(this->HeatingOnlyEquipList(equipListNum).Comp(compNum));
1068 991035 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1069 991035 : .LoopSide(this_equip.LoopSideNumPtr)
1070 991035 : .Branch(this_equip.BranchNumPtr)
1071 991035 : .Comp(this_equip.CompNumPtr)
1072 991035 : .Available = false;
1073 991035 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1074 991035 : .LoopSide(this_equip.LoopSideNumPtr)
1075 991035 : .Branch(this_equip.BranchNumPtr)
1076 991035 : .Comp(this_equip.CompNumPtr)
1077 991035 : .ON = false;
1078 : }
1079 : }
1080 : }
1081 :
1082 330345 : if (this->PlantOps.NumSimultHeatCoolCoolingEquipLists > 0) {
1083 314930 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolCoolingEquipLists; ++equipListNum) {
1084 :
1085 157465 : int NumComps = this->SimultHeatCoolCoolingEquipList(equipListNum).NumComps;
1086 314930 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1087 157465 : auto &this_equip(this->SimultHeatCoolCoolingEquipList(equipListNum).Comp(compNum));
1088 157465 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1089 157465 : .LoopSide(this_equip.LoopSideNumPtr)
1090 157465 : .Branch(this_equip.BranchNumPtr)
1091 157465 : .Comp(this_equip.CompNumPtr)
1092 157465 : .Available = false;
1093 157465 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1094 157465 : .LoopSide(this_equip.LoopSideNumPtr)
1095 157465 : .Branch(this_equip.BranchNumPtr)
1096 157465 : .Comp(this_equip.CompNumPtr)
1097 157465 : .ON = false;
1098 : }
1099 : }
1100 : }
1101 :
1102 330345 : if (this->PlantOps.NumSimultHeatCoolHeatingEquipLists > 0) {
1103 314930 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolHeatingEquipLists; ++equipListNum) {
1104 :
1105 157465 : int NumComps = this->SimultHeatCoolHeatingEquipList(equipListNum).NumComps;
1106 314930 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1107 157465 : auto &this_equip(this->SimultHeatCoolHeatingEquipList(equipListNum).Comp(compNum));
1108 157465 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1109 157465 : .LoopSide(this_equip.LoopSideNumPtr)
1110 157465 : .Branch(this_equip.BranchNumPtr)
1111 157465 : .Comp(this_equip.CompNumPtr)
1112 157465 : .Available = false;
1113 157465 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1114 157465 : .LoopSide(this_equip.LoopSideNumPtr)
1115 157465 : .Branch(this_equip.BranchNumPtr)
1116 157465 : .Comp(this_equip.CompNumPtr)
1117 157465 : .ON = false;
1118 : }
1119 : }
1120 : }
1121 : // end init machines off
1122 330345 : }
1123 :
1124 330345 : void ChillerHeaterSupervisoryOperationData::ProcessAndSetAirSourcePlantEquipLists(EnergyPlusData &state)
1125 : {
1126 : // TODO this routine is currently code to compare real current plant loads, polled building loads have also been studied.
1127 330345 : Real64 CoolingLoadSignal = this->Report.PrimaryPlantCoolingLoad;
1128 330345 : Real64 HeatingLoadSignal = this->Report.PrimaryPlantHeatingLoad;
1129 :
1130 : //___________________________________________________________________________
1131 330345 : if (this->PlantOps.AirSourcePlantCoolingOnly) {
1132 : // use zone loads to find range based cooling loads
1133 572970 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumCoolingOnlyEquipLists; ++equipListNum) {
1134 : // zone cooling loads are negative, switch to positive for range based limiting
1135 738187 : if (CoolingLoadSignal * DataPrecisionGlobals::constant_minusone > this->CoolingOnlyEquipList(equipListNum).RangeLowerLimit &&
1136 356207 : this->CoolingOnlyEquipList(equipListNum).RangeUpperLimit > CoolingLoadSignal * DataPrecisionGlobals::constant_minusone) {
1137 : // found that this equipment list load ranges match the zone predicted cooling loads
1138 :
1139 189318 : int NumComps = this->CoolingOnlyEquipList(equipListNum).NumComps;
1140 545525 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1141 356207 : auto &this_equip(this->CoolingOnlyEquipList(equipListNum).Comp(compNum));
1142 : // set cooling setpoint at outlet
1143 :
1144 : // todo, oa reset ?
1145 :
1146 356207 : state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = this->Setpoint.PrimCW;
1147 356207 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint =
1148 356207 : this->Setpoint.PrimCW;
1149 356207 : if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp > this->Setpoint.PrimCW) {
1150 :
1151 356207 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1152 356207 : .LoopSide(this_equip.LoopSideNumPtr)
1153 356207 : .Branch(this_equip.BranchNumPtr)
1154 356207 : .Comp(this_equip.CompNumPtr)
1155 356207 : .Available = true;
1156 356207 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1157 356207 : .LoopSide(this_equip.LoopSideNumPtr)
1158 356207 : .Branch(this_equip.BranchNumPtr)
1159 356207 : .Comp(this_equip.CompNumPtr)
1160 356207 : .ON = true;
1161 356207 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1162 356207 : .LoopSide(this_equip.LoopSideNumPtr)
1163 356207 : .Branch(this_equip.BranchNumPtr)
1164 356207 : .Comp(this_equip.CompNumPtr)
1165 712414 : .CurOpSchemeType = this->Type;
1166 : }
1167 : //
1168 : }
1169 : }
1170 : }
1171 : }
1172 :
1173 : //____________________________________________________________________________
1174 330345 : if (this->PlantOps.AirSourcePlantHeatingOnly) { // Use Heating Only equipment operation
1175 :
1176 51280 : Real64 HWsetpt = DetermineHWSetpointOARest(state);
1177 : // use zone loads to find range based heating loads
1178 153840 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumHeatingOnlyEquipLists; ++equipListNum) {
1179 151720 : if (HeatingLoadSignal > this->HeatingOnlyEquipList(equipListNum).RangeLowerLimit &&
1180 49160 : this->HeatingOnlyEquipList(equipListNum).RangeUpperLimit > HeatingLoadSignal) {
1181 : // found that this equipment list load ranges match the zone predicted heating loads
1182 :
1183 49046 : int NumComps = this->HeatingOnlyEquipList(equipListNum).NumComps;
1184 98206 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1185 49160 : auto &this_equip(this->HeatingOnlyEquipList(equipListNum).Comp(compNum));
1186 : // set heating setpoint at outlet
1187 :
1188 49160 : state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = HWsetpt;
1189 49160 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint = HWsetpt;
1190 :
1191 49160 : if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp < HWsetpt) {
1192 49156 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1193 49156 : .LoopSide(this_equip.LoopSideNumPtr)
1194 49156 : .Branch(this_equip.BranchNumPtr)
1195 49156 : .Comp(this_equip.CompNumPtr)
1196 49156 : .Available = true;
1197 49156 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1198 49156 : .LoopSide(this_equip.LoopSideNumPtr)
1199 49156 : .Branch(this_equip.BranchNumPtr)
1200 49156 : .Comp(this_equip.CompNumPtr)
1201 49156 : .ON = true;
1202 49156 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1203 49156 : .LoopSide(this_equip.LoopSideNumPtr)
1204 49156 : .Branch(this_equip.BranchNumPtr)
1205 49156 : .Comp(this_equip.CompNumPtr)
1206 98312 : .CurOpSchemeType = this->Type;
1207 : }
1208 : //
1209 : }
1210 : }
1211 : }
1212 : }
1213 :
1214 330345 : if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) {
1215 :
1216 : // use zone cooling loads to find range based equipment
1217 52422 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolCoolingEquipLists; ++equipListNum) {
1218 : // zone cooling loads are negative, switch to positive for range based limiting
1219 52422 : if (CoolingLoadSignal * DataPrecisionGlobals::constant_minusone >
1220 50795 : this->SimultHeatCoolCoolingEquipList(equipListNum).RangeLowerLimit &&
1221 24584 : this->SimultHeatCoolCoolingEquipList(equipListNum).RangeUpperLimit >
1222 24584 : CoolingLoadSignal * DataPrecisionGlobals::constant_minusone) {
1223 : // found that this equipment list load ranges match the zone predicted cooling loads
1224 :
1225 24584 : int NumComps = this->SimultHeatCoolCoolingEquipList(equipListNum).NumComps;
1226 49168 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1227 24584 : auto &this_equip(this->SimultHeatCoolCoolingEquipList(equipListNum).Comp(compNum));
1228 : // set cooling setpoint at outlet
1229 :
1230 24584 : state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = this->Setpoint.PrimCW;
1231 24584 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint =
1232 24584 : this->Setpoint.PrimCW;
1233 24584 : if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp > this->Setpoint.PrimCW) {
1234 24584 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1235 24584 : .LoopSide(this_equip.LoopSideNumPtr)
1236 24584 : .Branch(this_equip.BranchNumPtr)
1237 24584 : .Comp(this_equip.CompNumPtr)
1238 24584 : .Available = true;
1239 24584 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1240 24584 : .LoopSide(this_equip.LoopSideNumPtr)
1241 24584 : .Branch(this_equip.BranchNumPtr)
1242 24584 : .Comp(this_equip.CompNumPtr)
1243 24584 : .ON = true;
1244 24584 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1245 24584 : .LoopSide(this_equip.LoopSideNumPtr)
1246 24584 : .Branch(this_equip.BranchNumPtr)
1247 24584 : .Comp(this_equip.CompNumPtr)
1248 49168 : .CurOpSchemeType = this->Type;
1249 : }
1250 : //
1251 : }
1252 : }
1253 : }
1254 :
1255 : // use zone loads to find range based heating loads
1256 26211 : Real64 HWsetpt = DetermineHWSetpointOARest(state);
1257 52422 : for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolHeatingEquipLists; ++equipListNum) {
1258 52231 : if (HeatingLoadSignal > this->SimultHeatCoolHeatingEquipList(equipListNum).RangeLowerLimit &&
1259 26020 : this->SimultHeatCoolHeatingEquipList(equipListNum).RangeUpperLimit > HeatingLoadSignal) {
1260 : // found that this equipment list load ranges match the zone predicted heating loads
1261 :
1262 26020 : int NumComps = this->SimultHeatCoolHeatingEquipList(equipListNum).NumComps;
1263 52040 : for (int compNum = 1; compNum <= NumComps; ++compNum) {
1264 26020 : auto &this_equip(this->SimultHeatCoolHeatingEquipList(equipListNum).Comp(compNum));
1265 : // set heating setpoint at outlet
1266 :
1267 26020 : state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = HWsetpt;
1268 26020 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint = HWsetpt;
1269 :
1270 26020 : if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp < HWsetpt) {
1271 26020 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1272 26020 : .LoopSide(this_equip.LoopSideNumPtr)
1273 26020 : .Branch(this_equip.BranchNumPtr)
1274 26020 : .Comp(this_equip.CompNumPtr)
1275 26020 : .Available = true;
1276 26020 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1277 26020 : .LoopSide(this_equip.LoopSideNumPtr)
1278 26020 : .Branch(this_equip.BranchNumPtr)
1279 26020 : .Comp(this_equip.CompNumPtr)
1280 26020 : .ON = true;
1281 26020 : state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
1282 26020 : .LoopSide(this_equip.LoopSideNumPtr)
1283 26020 : .Branch(this_equip.BranchNumPtr)
1284 26020 : .Comp(this_equip.CompNumPtr)
1285 52040 : .CurOpSchemeType = this->Type;
1286 : }
1287 : //
1288 : }
1289 : }
1290 : }
1291 : }
1292 330345 : }
1293 :
1294 330345 : void ChillerHeaterSupervisoryOperationData::ProcessAndSetDedicatedHeatRecovWWHP(EnergyPlusData &state)
1295 : {
1296 : // evaluate if and how dedicated heat recovery WWHP should run
1297 :
1298 330345 : if (!this->PlantOps.DedicatedHR_Present) {
1299 255429 : return;
1300 : }
1301 :
1302 : // initialize off
1303 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1304 74916 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1305 74916 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1306 74916 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1307 74916 : .Available = false;
1308 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1309 74916 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1310 74916 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1311 74916 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1312 74916 : .ON = false;
1313 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
1314 74916 : .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
1315 74916 : .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
1316 74916 : .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
1317 74916 : .Available = false;
1318 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
1319 74916 : .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
1320 74916 : .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
1321 74916 : .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
1322 74916 : .ON = false;
1323 :
1324 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1325 74916 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1326 74916 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1327 74916 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1328 74916 : .Available = false;
1329 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1330 74916 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1331 74916 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1332 74916 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1333 74916 : .ON = false;
1334 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
1335 74916 : .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
1336 74916 : .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
1337 74916 : .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
1338 74916 : .Available = false;
1339 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
1340 74916 : .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
1341 74916 : .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
1342 74916 : .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
1343 74916 : .ON = false;
1344 :
1345 : // Dedicated Heat Recovery Water To Water Heat Pump Control.
1346 : // Assume there are two companion machines, one leads for cooling the return chilled water, the other leads for heating the return hot
1347 : // water When one side leads, the other gets favorable heat addition/extraction it is just not controlled to meet a setpoint Assume these
1348 : // are on the secondary loops. Need to decide if it runs and which of cooling or heating companion coils gets to lead.
1349 : //
1350 : // Step 1. get the mass flow rates of the returns. both must be non-zero for the WWHP to run
1351 74916 : int inletChWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
1352 74916 : .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
1353 74916 : .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
1354 74916 : .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
1355 74916 : .NodeNumIn;
1356 74916 : int inletHWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
1357 74916 : .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
1358 74916 : .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
1359 74916 : .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
1360 74916 : .NodeNumIn;
1361 74916 : Real64 CW_RetMdot = state.dataLoopNodes->Node(inletChWReturnNodeNum).MassFlowRate;
1362 74916 : Real64 HW_RetMdot = state.dataLoopNodes->Node(inletHWReturnNodeNum).MassFlowRate;
1363 :
1364 74916 : bool flowInEach = false;
1365 : // need flow in both returns.
1366 74916 : if (CW_RetMdot <= HVAC::SmallWaterVolFlow || HW_RetMdot <= HVAC::SmallWaterVolFlow) {
1367 74758 : flowInEach = false;
1368 : } else {
1369 158 : flowInEach = true;
1370 : }
1371 :
1372 : // step 2. calculate the loads to adjust the
1373 : // returns to hit the associated setpoints at their current mass flow
1374 : Real64 const CpCW =
1375 149832 : FluidProperties::GetSpecificHeatGlycol(state,
1376 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum).FluidName,
1377 74916 : state.dataLoopNodes->Node(inletChWReturnNodeNum).Temp,
1378 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum).FluidIndex,
1379 : "EvaluateChillerHeaterChangeoverOpScheme");
1380 : Real64 CW_Qdot =
1381 74916 : CW_RetMdot * CpCW *
1382 74916 : (this->Setpoint.SecCW - state.dataLoopNodes->Node(inletChWReturnNodeNum).Temp); // power = Mdot Cp Delta T, cooling load is negative
1383 : Real64 const CpHW =
1384 149832 : FluidProperties::GetSpecificHeatGlycol(state,
1385 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum).FluidName,
1386 74916 : state.dataLoopNodes->Node(inletHWReturnNodeNum).Temp,
1387 74916 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum).FluidIndex,
1388 : "EvaluateChillerHeaterChangeoverOpScheme");
1389 74916 : Real64 HW_Qdot = HW_RetMdot * CpHW * (this->Setpoint.SecHW - state.dataLoopNodes->Node(inletHWReturnNodeNum).Temp); // power = Mdot Cp Delta T
1390 :
1391 : // store for reporting
1392 74916 : this->Report.SecondaryPlantCoolingLoad = CW_Qdot;
1393 74916 : this->Report.SecondaryPlantHeatingLoad = HW_Qdot;
1394 :
1395 : // step 3 decide if Dedicated HR is on and which leads based
1396 74916 : bool CoolLedNeed = false;
1397 74916 : bool HeatLedNeed = false;
1398 :
1399 74916 : if (this->PlantOps.AirSourcePlantHeatingOnly && (CW_Qdot < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) && flowInEach) {
1400 : // polled building loads are heating only, but secondary ChW plant has some cooling load and there is mass flow in each. So turn dedicated
1401 : // HR on in cooling lead mode
1402 0 : CoolLedNeed = true;
1403 : }
1404 :
1405 74916 : if (this->PlantOps.AirSourcePlantCoolingOnly && (HW_Qdot > HVAC::SmallLoad) && flowInEach) {
1406 : // polled building loads are cooling only, but secondary HW plant has some heating load and there is mass flow in each. So turn dedicated
1407 : // HR on in heating lead mode
1408 103 : HeatLedNeed = true;
1409 : }
1410 :
1411 74916 : if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling && this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant &&
1412 : flowInEach) {
1413 : // polled building loads are simultaneous with heating dominating and there is mass flow in each, So turn
1414 : // dedicated HR on in heating lead mode
1415 0 : HeatLedNeed = true;
1416 : }
1417 :
1418 74916 : if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling && this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant &&
1419 : flowInEach) {
1420 : // polled building loads are simultaneous with cooling dominating and there is mass flow in each, So turn
1421 : // dedicated HR on in cooling lead mode
1422 0 : CoolLedNeed = true;
1423 : }
1424 :
1425 : // step 4. check that there is sufficient flow in source side for chosen leader to avoid runaway plant conditions on source side
1426 : // if not, see if other side could run benefically as leader and switch to it if so
1427 : // Real64 FlowImbalanceRatioThreshold = 10.0; // TODO, check with TRANE engineering about WWHP operating limits wrt to relative flows (real
1428 : // // systems have a pumped sided arm flow situation and do not have low flow problems)
1429 :
1430 : // if (CoolLedNeed) {
1431 : // if (CW_RetMdot / HW_RetMdot > FlowImbalanceRatioThreshold) { // insuficient flow in source side relative to load side
1432 : // CoolLedNeed = false;
1433 : // // if (HW_Qdot > 1.0) {
1434 : // // HeatLedNeed = true;
1435 : // //}
1436 : // }
1437 : //}
1438 : // if (HeatLedNeed) {
1439 : // if (HW_RetMdot / CW_RetMdot > FlowImbalanceRatioThreshold) { // insuficient flow in source side relative to load side
1440 : // HeatLedNeed = false;
1441 : // // if (CW_Qdot < -1.0) {
1442 : // // CoolLedNeed = true;
1443 : // //}
1444 : // }
1445 : //}
1446 :
1447 74916 : this->Report.DedicHR_OpMode = 0;
1448 74916 : if (CoolLedNeed) {
1449 0 : this->Report.DedicHR_OpMode = 2;
1450 : // turn ON load side of this water to water heat pump
1451 0 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1452 0 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1453 0 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1454 0 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1455 0 : .Available = true;
1456 0 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1457 0 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1458 0 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1459 0 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1460 0 : .ON = true;
1461 :
1462 0 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1463 0 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1464 0 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1465 0 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1466 0 : .CurOpSchemeType = this->Type;
1467 :
1468 0 : state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1469 0 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1470 0 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1471 0 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1472 0 : .MyLoad = CW_Qdot; // cooling load is negative
1473 :
1474 0 : int OutletChWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
1475 0 : .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
1476 0 : .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
1477 0 : .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
1478 0 : .NodeNumOut;
1479 0 : state.dataLoopNodes->Node(OutletChWReturnNodeNum).TempSetPoint = this->Setpoint.SecCW;
1480 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum).TempSetPointNodeNum)
1481 0 : .TempSetPoint = this->Setpoint.SecCW;
1482 :
1483 0 : if (this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum ==
1484 0 : SecondaryPlantLoopIndicesBeingSupervised(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)) {
1485 : // search for HX on this loop and place setpoint on outlet
1486 0 : for (int HXnum = 1; HXnum <= this->PlantOps.numPlantHXs; ++HXnum) {
1487 0 : if (this->PlantHXComps(HXnum).loopNum == this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum) {
1488 0 : int outletnode = state.dataPlnt->PlantLoop(this->PlantHXComps(HXnum).loopNum)
1489 0 : .LoopSide(this->PlantHXComps(HXnum).loopSideNum)
1490 0 : .Branch(this->PlantHXComps(HXnum).branchNum)
1491 0 : .Comp(this->PlantHXComps(HXnum).compNum)
1492 0 : .NodeNumOut;
1493 0 : state.dataLoopNodes->Node(outletnode).TempSetPoint = this->Setpoint.SecCW;
1494 : }
1495 : }
1496 : }
1497 :
1498 74916 : } else if (HeatLedNeed) {
1499 103 : this->Report.DedicHR_OpMode = 1;
1500 : // turn load side of this water to water heat pump
1501 103 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1502 103 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1503 103 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1504 103 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1505 103 : .Available = true;
1506 103 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1507 103 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1508 103 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1509 103 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1510 103 : .ON = true;
1511 103 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1512 103 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1513 103 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1514 103 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1515 103 : .CurOpSchemeType = this->Type;
1516 103 : state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1517 103 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1518 103 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1519 103 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1520 103 : .MyLoad = HW_Qdot;
1521 :
1522 103 : int OutletHWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
1523 103 : .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
1524 103 : .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
1525 103 : .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
1526 103 : .NodeNumOut;
1527 :
1528 103 : state.dataLoopNodes->Node(OutletHWReturnNodeNum).TempSetPoint = this->Setpoint.SecHW;
1529 103 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum).TempSetPointNodeNum)
1530 103 : .TempSetPoint = this->Setpoint.SecHW;
1531 :
1532 206 : if (this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum ==
1533 103 : SecondaryPlantLoopIndicesBeingSupervised(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)) {
1534 : // search for HX on this loop and place setpoint on outlet
1535 309 : for (int HXnum = 1; HXnum <= this->PlantOps.numPlantHXs; ++HXnum) {
1536 206 : if (this->PlantHXComps(HXnum).loopNum == this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum) {
1537 103 : int outletnode = state.dataPlnt->PlantLoop(this->PlantHXComps(HXnum).loopNum)
1538 103 : .LoopSide(this->PlantHXComps(HXnum).loopSideNum)
1539 103 : .Branch(this->PlantHXComps(HXnum).branchNum)
1540 103 : .Comp(this->PlantHXComps(HXnum).compNum)
1541 103 : .NodeNumOut;
1542 103 : state.dataLoopNodes->Node(outletnode).TempSetPoint = min(this->Setpoint.SecHW, this->DetermineHWSetpointOARest(state));
1543 : }
1544 : }
1545 : }
1546 : }
1547 : }
1548 :
1549 330345 : void ChillerHeaterSupervisoryOperationData::ProcessAndSetAuxilBoiler(EnergyPlusData &state)
1550 : {
1551 : // Check for boiler used as auxiliary or supplemental
1552 : // Assume boilers are in-line on supply side outlet branch, typically on secodary loop but may be on primary loop
1553 330345 : this->Report.BoilerAux_OpMode = 0;
1554 330345 : if (this->PlantOps.numBoilers <= 0) return;
1555 :
1556 : // first intialize them to be off
1557 330345 : if (this->PlantOps.numBoilers > 0) {
1558 660690 : for (int BoilerNum = 1; BoilerNum <= this->PlantOps.numBoilers; ++BoilerNum) {
1559 330345 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1560 330345 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1561 330345 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1562 330345 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1563 330345 : .Available = false;
1564 330345 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1565 330345 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1566 330345 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1567 330345 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1568 330345 : .ON = false;
1569 330345 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1570 330345 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1571 330345 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1572 330345 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1573 330345 : .MyLoad = 0.0;
1574 : }
1575 : }
1576 :
1577 330345 : if (this->PlantOps.numBoilers > 0) {
1578 : // Boilers will run if outdoor air temperature is too low and there is flow in HW return loop
1579 :
1580 330345 : bool LowOAAuxiliaryNeeded = false;
1581 330345 : if (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp) {
1582 103006 : LowOAAuxiliaryNeeded = true;
1583 : }
1584 660690 : for (int BoilerNum = 1; BoilerNum <= this->PlantOps.numBoilers; ++BoilerNum) {
1585 : // determine if primary or secondary setpoint in use
1586 330345 : Real64 HWsetpt = 0.0;
1587 330345 : if (this->SecondaryPlantLoopIndicesBeingSupervised(this->PlantBoilerComps(BoilerNum).loopNum) >
1588 : 0) { // appears to be on secondary loop, supplemental boiler
1589 74916 : HWsetpt = min(this->Setpoint.SecHW,
1590 : DetermineHWSetpointOARest(
1591 : state)); // Assume if OA reset is lower than setting for secondary HW loop, then use the lower of the two
1592 : } else { // primary loop, auxiliary boiler
1593 255429 : HWsetpt = DetermineHWSetpointOARest(state);
1594 : }
1595 :
1596 330345 : HWsetpt = HWsetpt - this->TempReset.BoilerTemperatureOffset;
1597 :
1598 : // check inlet temperature
1599 330345 : int inletBoilerNodeNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1600 330345 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1601 330345 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1602 330345 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1603 330345 : .NodeNumIn;
1604 330345 : Real64 Tin = state.dataLoopNodes->Node(inletBoilerNodeNum).Temp;
1605 330345 : Real64 Mdot = state.dataLoopNodes->Node(inletBoilerNodeNum).MassFlowRate;
1606 :
1607 : Real64 const CpHW =
1608 660690 : FluidProperties::GetSpecificHeatGlycol(state,
1609 330345 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).FluidName,
1610 : Tin,
1611 330345 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).FluidIndex,
1612 : "ChillerHeaterSupervisoryOperationData::ProcessAndSetAuxilBoiler");
1613 330345 : Real64 LoadToSetpoint = max(0.0, Mdot * CpHW * (HWsetpt - Tin));
1614 330345 : int pltSizNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).PlantSizNum;
1615 : Real64 const thresholdPlantLoad =
1616 330345 : 0.001 * state.dataSize->PlantSizData(pltSizNum).DesCapacity; // model an operating threshold at 0.1% of loop capacity, only run if
1617 : // larger than that
1618 :
1619 330345 : if (((LoadToSetpoint > thresholdPlantLoad) &&
1620 96879 : ((this->Report.AirSourcePlant_OpMode == 0) ||
1621 233604 : LowOAAuxiliaryNeeded)) || // run boiler if there is any heating load and also heatpumps are off or too cold outside
1622 138 : ((LoadToSetpoint > thresholdPlantLoad) &&
1623 138 : (this->Report.AirSourcePlant_OpMode ==
1624 : 2))) { // run boiler if there is a somewhat significant heating load and heat pumps in cooling only mode
1625 :
1626 96879 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1627 96879 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1628 96879 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1629 96879 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1630 96879 : .Available = true;
1631 96879 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1632 96879 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1633 96879 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1634 96879 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1635 96879 : .ON = true;
1636 96879 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1637 96879 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1638 96879 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1639 96879 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1640 96879 : .CurOpSchemeType = this->Type;
1641 : // boilers don't really have setpoint control mode, so set value for myLoad
1642 96879 : state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1643 96879 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1644 96879 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1645 96879 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1646 96879 : .MyLoad = LoadToSetpoint;
1647 96879 : int OutletBoilerNodeNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1648 96879 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1649 96879 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1650 96879 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1651 96879 : .NodeNumOut;
1652 96879 : state.dataLoopNodes->Node(OutletBoilerNodeNum).TempSetPoint = HWsetpt;
1653 96879 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).TempSetPointNodeNum).TempSetPoint =
1654 : HWsetpt;
1655 96879 : this->Report.BoilerAux_OpMode = 1;
1656 96879 : } else { // still apply the setpoint, but don't turn on
1657 233466 : int OutletBoilerNodeNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
1658 233466 : .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
1659 233466 : .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
1660 233466 : .Comp(this->PlantBoilerComps(BoilerNum).compNum)
1661 233466 : .NodeNumOut;
1662 233466 : state.dataLoopNodes->Node(OutletBoilerNodeNum).TempSetPoint = HWsetpt;
1663 233466 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).TempSetPointNodeNum).TempSetPoint =
1664 : HWsetpt;
1665 : }
1666 : }
1667 : }
1668 : }
1669 :
1670 738284 : Real64 ChillerHeaterSupervisoryOperationData::DetermineHWSetpointOARest(EnergyPlusData &state)
1671 : {
1672 : // algorithm from calcSetPointLinInt
1673 738284 : Real64 HWSetpoint = 0.0;
1674 :
1675 738284 : if ((this->TempReset.LowOutdoorTemp == this->TempReset.BackupLowOutdoorTemp) &&
1676 738284 : (this->Setpoint.PrimHW_Low == this->Setpoint.PrimHW_BackupLow)) { // no second-stage reset scheme
1677 :
1678 738284 : if (this->TempReset.LowOutdoorTemp < this->TempReset.HighOutdoorTemp) {
1679 738284 : if (state.dataEnvrn->OutDryBulbTemp <= this->TempReset.LowOutdoorTemp) {
1680 206115 : HWSetpoint = this->Setpoint.PrimHW_Low;
1681 532169 : } else if (state.dataEnvrn->OutDryBulbTemp >= this->TempReset.HighOutdoorTemp) {
1682 378467 : HWSetpoint = this->Setpoint.PrimHW_High;
1683 : } else {
1684 153702 : HWSetpoint = this->Setpoint.PrimHW_Low - ((state.dataEnvrn->OutDryBulbTemp - this->TempReset.LowOutdoorTemp) /
1685 153702 : (this->TempReset.HighOutdoorTemp - this->TempReset.LowOutdoorTemp)) *
1686 153702 : (this->Setpoint.PrimHW_Low - this->Setpoint.PrimHW_High);
1687 153702 : HWSetpoint = min(HWSetpoint, this->Setpoint.PrimHW_High); // don't extrapolate, hold at high limit of primary HW
1688 : }
1689 :
1690 : } else {
1691 0 : HWSetpoint = 0.5 * (this->Setpoint.PrimHW_Low + this->Setpoint.PrimHW_High);
1692 : }
1693 : } else { // apply two stage reset scheme
1694 0 : if ((this->TempReset.LowOutdoorTemp < this->TempReset.HighOutdoorTemp) &&
1695 0 : (this->TempReset.BackupLowOutdoorTemp < this->TempReset.LowOutdoorTemp)) { // expected configuration
1696 :
1697 0 : if (state.dataEnvrn->OutDryBulbTemp <= this->TempReset.BackupLowOutdoorTemp) {
1698 0 : HWSetpoint = this->Setpoint.PrimHW_BackupLow;
1699 0 : } else if (state.dataEnvrn->OutDryBulbTemp >= this->TempReset.HighOutdoorTemp) {
1700 0 : HWSetpoint = this->Setpoint.PrimHW_High;
1701 0 : } else if ((state.dataEnvrn->OutDryBulbTemp >= this->TempReset.LowOutdoorTemp) &&
1702 0 : (state.dataEnvrn->OutDryBulbTemp < this->TempReset.HighOutdoorTemp)) { // first stage for Heat pump reset down
1703 0 : HWSetpoint = this->Setpoint.PrimHW_Low - ((state.dataEnvrn->OutDryBulbTemp - this->TempReset.LowOutdoorTemp) /
1704 0 : (this->TempReset.HighOutdoorTemp - this->TempReset.LowOutdoorTemp)) *
1705 0 : (this->Setpoint.PrimHW_Low - this->Setpoint.PrimHW_High);
1706 0 : HWSetpoint = min(HWSetpoint, this->Setpoint.PrimHW_High); // don't extrapolate, hold at high limit of primary HW
1707 0 : } else if ((state.dataEnvrn->OutDryBulbTemp > this->TempReset.BackupLowOutdoorTemp) &&
1708 0 : (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp)) { // second stage for backup boiler reset up
1709 0 : HWSetpoint = this->Setpoint.PrimHW_BackupLow - ((state.dataEnvrn->OutDryBulbTemp - this->TempReset.BackupLowOutdoorTemp) /
1710 0 : (this->TempReset.LowOutdoorTemp - this->TempReset.BackupLowOutdoorTemp)) *
1711 0 : (this->Setpoint.PrimHW_BackupLow - this->Setpoint.PrimHW_Low);
1712 0 : HWSetpoint = min(HWSetpoint, this->Setpoint.PrimHW_BackupLow); // don't extrapolate
1713 0 : HWSetpoint = max(HWSetpoint, this->Setpoint.PrimHW_Low); // don't extrapolate
1714 : } else {
1715 : // shouldn't get here, throw error?
1716 : }
1717 : } else { // malformed input, take average of three setpoints
1718 0 : HWSetpoint = (this->Setpoint.PrimHW_Low + this->Setpoint.PrimHW_High + this->Setpoint.PrimHW_BackupLow) / 3.0;
1719 : }
1720 : }
1721 738284 : return HWSetpoint;
1722 : }
1723 :
1724 : } // namespace DataPlant
1725 : } // namespace EnergyPlus
|