Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef PlantPipingSystemsManager_hh_INCLUDED
49 : #define PlantPipingSystemsManager_hh_INCLUDED
50 :
51 : // C++ Headers
52 : #include <map>
53 : #include <memory>
54 : #include <unordered_map>
55 : #include <utility>
56 :
57 : // ObjexxFCL Headers
58 : #include <ObjexxFCL/Array2D.hh>
59 : #include <ObjexxFCL/Array3D.hh>
60 : #include <ObjexxFCL/Optional.hh>
61 :
62 : // EnergyPlus Headers
63 : #include <EnergyPlus/Data/BaseData.hh>
64 : #include <EnergyPlus/DataGlobals.hh>
65 : #include <EnergyPlus/EnergyPlus.hh>
66 : #include <EnergyPlus/GroundTemperatureModeling/BaseGroundTemperatureModel.hh>
67 : #include <EnergyPlus/Plant/Enums.hh>
68 : #include <EnergyPlus/Plant/PlantLocation.hh>
69 : #include <EnergyPlus/PlantComponent.hh>
70 :
71 : namespace EnergyPlus {
72 :
73 : // Forward declarations
74 : struct EnergyPlusData;
75 :
76 : namespace PlantPipingSystemsManager {
77 :
78 : // MODULE PARAMETER DEFINITIONS:
79 : extern std::string const ObjName_ug_GeneralDomain;
80 : extern std::string const ObjName_Circuit;
81 : extern std::string const ObjName_Segment;
82 : extern std::string const ObjName_HorizTrench;
83 : extern std::string const ObjName_ZoneCoupled_Slab;
84 : extern std::string const ObjName_ZoneCoupled_Basement;
85 :
86 : enum class SegmentFlow
87 : {
88 : Invalid = -1,
89 : IncreasingZ,
90 : DecreasingZ,
91 : Num
92 : };
93 :
94 : enum class MeshDistribution
95 : {
96 : Invalid = -1,
97 : Uniform,
98 : SymmetricGeometric,
99 : Geometric,
100 : Num
101 : };
102 :
103 : enum class RegionType
104 : {
105 : Invalid = -1,
106 : Pipe,
107 : BasementWall,
108 : BasementFloor,
109 : XDirection,
110 : YDirection,
111 : ZDirection,
112 : XSide,
113 : XSideWall,
114 : ZSide,
115 : ZSideWall,
116 : FloorInside,
117 : UnderFloor,
118 : HorizInsXSide,
119 : HorizInsZSide,
120 : VertInsLowerEdge,
121 : Num
122 : };
123 :
124 : enum class Direction
125 : {
126 : Invalid = -1,
127 : PositiveY,
128 : NegativeY,
129 : PositiveX,
130 : NegativeX,
131 : PositiveZ,
132 : NegativeZ,
133 : Num
134 : };
135 :
136 : enum class PartitionType
137 : {
138 : Invalid = -1,
139 : BasementWall,
140 : BasementFloor,
141 : Pipe,
142 : Slab,
143 : XSide,
144 : XSideWall,
145 : ZSide,
146 : ZSideWall,
147 : FloorInside,
148 : UnderFloor,
149 : HorizInsXSide,
150 : VertInsLowerEdge,
151 : HorizInsZSide,
152 : Num
153 : };
154 :
155 : enum class CellType
156 : {
157 : Invalid = -1,
158 : Pipe,
159 : GeneralField,
160 : GroundSurface,
161 : FarfieldBoundary,
162 : BasementWall,
163 : BasementFloor,
164 : BasementCorner,
165 : BasementCutaway,
166 : Slab,
167 : HorizInsulation,
168 : VertInsulation,
169 : ZoneGroundInterface,
170 : Num
171 : };
172 :
173 : enum class SlabPosition
174 : {
175 : Invalid = -1,
176 : InGrade,
177 : OnGrade,
178 : Num
179 : };
180 :
181 : enum class HorizInsulation
182 : {
183 : Invalid = -1,
184 : None,
185 : Perimeter,
186 : Full,
187 : Num
188 : };
189 :
190 : struct BaseThermalPropertySet
191 : {
192 : // Members
193 : Real64 Conductivity = 0.0; // W/mK
194 : Real64 Density = 0.0; // kg/m3
195 : Real64 SpecificHeat = 0.0; // J/kgK
196 :
197 : // Default Constructor
198 18327 : BaseThermalPropertySet() = default;
199 :
200 : Real64 inline diffusivity() const
201 : {
202 : return this->Conductivity / (this->Density * this->SpecificHeat);
203 : }
204 : };
205 :
206 : struct ExtendedFluidProperties : BaseThermalPropertySet
207 : {
208 : // Members
209 : Real64 Viscosity = 0.0; // kg/m-s
210 : Real64 Prandtl = 0.0; // -
211 :
212 : // Default Constructor
213 3642 : ExtendedFluidProperties() = default;
214 : };
215 :
216 : struct BaseCell
217 : {
218 : // Members
219 : Real64 Temperature = 0.0; // C
220 : Real64 Temperature_PrevIteration = 0.0; // C
221 : Real64 Temperature_PrevTimeStep = 0.0; // C
222 : Real64 Beta = 0.0; // K/W
223 : BaseThermalPropertySet Properties;
224 :
225 : // Default Constructor
226 14544 : BaseCell() = default;
227 : };
228 :
229 : struct RadialSizing
230 : {
231 : // Members
232 : Real64 InnerDia = 0.0;
233 : Real64 OuterDia = 0.0;
234 :
235 : // Default Constructor
236 6 : RadialSizing() = default;
237 :
238 0 : Real64 inline thickness() const
239 : {
240 0 : return (this->OuterDia - this->InnerDia) / 2.0;
241 : }
242 : };
243 :
244 : struct RadialCellInformation : BaseCell
245 : {
246 : // Members
247 : Real64 RadialCentroid = 0.0;
248 : Real64 InnerRadius = 0.0;
249 : Real64 OuterRadius = 0.0;
250 :
251 : // Default Constructor
252 7254 : RadialCellInformation() = default;
253 :
254 : // Member Constructor
255 36 : RadialCellInformation(Real64 const m_RadialCentroid, Real64 const m_MinRadius, Real64 const m_MaxRadius)
256 36 : {
257 36 : RadialCentroid = m_RadialCentroid;
258 36 : InnerRadius = m_MinRadius;
259 36 : OuterRadius = m_MaxRadius;
260 36 : }
261 :
262 : // Get the XY cross sectional area of the radial cell
263 36 : Real64 inline XY_CrossSectArea() const
264 : {
265 36 : return Constant::Pi * (pow_2(this->OuterRadius) - pow_2(this->InnerRadius));
266 : }
267 : };
268 :
269 : struct FluidCellInformation : BaseCell
270 : {
271 : // Members
272 : Real64 Volume = 0.0;
273 : ExtendedFluidProperties Properties;
274 :
275 : // Default Constructor
276 3627 : FluidCellInformation() = default;
277 :
278 : // Member Constructor
279 12 : FluidCellInformation(Real64 const m_PipeInnerRadius, Real64 const m_CellDepth)
280 12 : {
281 12 : this->Volume = Constant::Pi * pow_2(m_PipeInnerRadius) * m_CellDepth;
282 12 : }
283 : };
284 :
285 : struct CartesianPipeCellInformation // Specialized cell information only used by cells which contain pipes
286 : {
287 : // Members
288 : std::vector<RadialCellInformation> Soil;
289 : RadialCellInformation Insulation;
290 : RadialCellInformation Pipe;
291 : FluidCellInformation Fluid;
292 : Real64 RadialSliceWidth = 0.0;
293 : Real64 InterfaceVolume = 0.0;
294 :
295 : // Default Constructor
296 3615 : CartesianPipeCellInformation() = default;
297 :
298 : CartesianPipeCellInformation(Real64 GridCellWidth,
299 : EnergyPlus::PlantPipingSystemsManager::RadialSizing PipeSizes,
300 : int NumRadialNodes,
301 : Real64 CellDepth,
302 : Real64 InsulationThickness,
303 : Real64 RadialGridExtent,
304 : bool SimHasInsulation);
305 : };
306 :
307 : struct Point
308 : {
309 : // Members
310 : int X = 0;
311 : int Y = 0;
312 :
313 : // Default Constructor
314 8 : Point() = default;
315 :
316 : // Member Constructor
317 : Point(int const X, int const Y) : X(X), Y(Y)
318 : {
319 : }
320 : };
321 :
322 : struct PointF
323 : {
324 : // Members
325 : Real64 X = 0.0;
326 : Real64 Y = 0.0;
327 :
328 : // Default Constructor
329 8 : PointF() = default;
330 :
331 : // Member Constructor
332 4 : PointF(Real64 const X, Real64 const Y) : X(X), Y(Y)
333 : {
334 4 : }
335 : };
336 :
337 : struct Point3DInteger
338 : {
339 : // Members
340 : int X = 0;
341 : int Y = 0;
342 : int Z = 0;
343 :
344 : // Default Constructor
345 6 : Point3DInteger() = default;
346 :
347 : // Member Constructor
348 3617 : Point3DInteger(int const X, int const Y, int const Z) : X(X), Y(Y), Z(Z)
349 : {
350 3617 : }
351 : };
352 :
353 : struct Point3DReal
354 : {
355 : // Members
356 : Real64 X = 0.0;
357 : Real64 Y = 0.0;
358 : Real64 Z = 0.0;
359 :
360 : // Default Constructor
361 3615 : Point3DReal() = default;
362 :
363 : // Member Constructor
364 3615 : Point3DReal(Real64 const X, Real64 const Y, Real64 const Z) : X(X), Y(Y), Z(Z)
365 : {
366 3615 : }
367 : };
368 :
369 : struct MeshPartition
370 : {
371 : // Members
372 : Real64 rDimension = 0.0;
373 : PartitionType partitionType = PartitionType::Pipe;
374 : Real64 TotalWidth = 0.0;
375 :
376 : // Default Constructor
377 : MeshPartition() = default;
378 :
379 : #pragma clang diagnostic push
380 : #pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
381 : // Member Constructor -- shows unused but it's actually implied in emplace_back calls in createPartitionCenterList
382 20 : MeshPartition(Real64 const rDimension,
383 : PartitionType const partitionType, // From Enum: ParitionType
384 : Real64 const TotalWidth)
385 20 : : rDimension(rDimension), partitionType(partitionType), TotalWidth(TotalWidth)
386 : {
387 20 : }
388 : #pragma clang diagnostic pop
389 :
390 : // used to allow std::find to see if a MeshPartition matches a float (rDimension) value
391 2 : bool operator==(Real64 a)
392 : {
393 2 : return this->rDimension == a;
394 : }
395 : };
396 :
397 : struct GridRegion
398 : {
399 : // Members
400 : Real64 Min = 0.0;
401 : Real64 Max = 0.0;
402 : RegionType thisRegionType = RegionType::Pipe;
403 : std::vector<Real64> CellWidths;
404 :
405 : // Default Constructor
406 12 : GridRegion() = default;
407 :
408 : // Member Constructor
409 27 : GridRegion(Real64 Min, Real64 Max, RegionType thisRegionType, std::vector<Real64> CellWidths)
410 27 : : Min(Min), Max(Max), thisRegionType(thisRegionType), CellWidths(std::move(CellWidths))
411 : {
412 27 : }
413 : };
414 :
415 : struct RectangleF
416 : {
417 : // Members
418 : Real64 X_min = 0.0;
419 : Real64 Y_min = 0.0;
420 : Real64 Width = 0.0;
421 : Real64 Height = 0.0;
422 :
423 : // Default Constructor
424 : RectangleF() = default;
425 :
426 : // Member Constructor
427 3615 : RectangleF(Real64 const X_min, Real64 const Y_min, Real64 const Width, Real64 const Height)
428 3615 : : X_min(X_min), Y_min(Y_min), Width(Width), Height(Height)
429 : {
430 3615 : }
431 :
432 474 : bool inline contains(EnergyPlus::PlantPipingSystemsManager::PointF p) const
433 : {
434 474 : return ((this->X_min <= p.X) && (p.X < (this->X_min + this->Width)) && (this->Y_min <= p.Y) && (p.Y < (this->Y_min + this->Height)));
435 : }
436 : };
437 :
438 : struct NeighborInformation
439 : {
440 : // Members
441 : Real64 ThisCentroidToNeighborWall = 0.0;
442 : Real64 ThisWallToNeighborCentroid = 0.0;
443 : Real64 adiabaticMultiplier = 1.0;
444 : Direction direction = Direction::NegativeX;
445 :
446 : // Default Constructor
447 21690 : NeighborInformation() = default;
448 : };
449 :
450 : struct CartesianCell : BaseCell
451 : {
452 : // Members
453 : int X_index = 0;
454 : int Y_index = 0;
455 : int Z_index = 0;
456 : Real64 X_min = 0.0;
457 : Real64 X_max = 0.0;
458 : Real64 Y_min = 0.0;
459 : Real64 Y_max = 0.0;
460 : Real64 Z_min = 0.0;
461 : Real64 Z_max = 0.0;
462 : Point3DReal Centroid;
463 : CellType cellType = CellType::Invalid;
464 : std::map<Direction, NeighborInformation> NeighborInfo;
465 : CartesianPipeCellInformation PipeCellData;
466 :
467 : // Default Constructor
468 3615 : CartesianCell() = default;
469 :
470 28166 : Real64 inline width() const
471 : {
472 28166 : return this->X_max - this->X_min;
473 : }
474 :
475 28082 : Real64 inline height() const
476 : {
477 28082 : return this->Y_max - this->Y_min;
478 : }
479 :
480 28442 : Real64 inline depth() const
481 : {
482 28442 : return this->Z_max - this->Z_min;
483 : }
484 :
485 12295 : Real64 inline XNormalArea() const
486 : {
487 12295 : return this->depth() * this->height();
488 : }
489 :
490 12339 : Real64 inline YNormalArea() const
491 : {
492 12339 : return this->depth() * this->width();
493 : }
494 :
495 12235 : Real64 inline ZNormalArea() const
496 : {
497 12235 : return this->width() * this->height();
498 : }
499 :
500 3117 : Real64 inline volume() const
501 : {
502 3117 : return this->width() * this->depth() * this->height();
503 : }
504 :
505 : Real64 normalArea(Direction direction) const;
506 :
507 : void EvaluateNeighborCoordinates(Direction CurDirection, int &NX, int &NY, int &NZ) const;
508 : };
509 :
510 : struct MeshExtents
511 : {
512 : // Members
513 : Real64 xMax = 0.0;
514 : Real64 yMax = 0.0;
515 : Real64 zMax = 0.0;
516 :
517 : // Default Constructor
518 27 : MeshExtents() = default;
519 :
520 : // Member Constructor
521 3615 : MeshExtents(Real64 const xMax, Real64 const yMax, Real64 const zMax) : xMax(xMax), yMax(yMax), zMax(zMax)
522 : {
523 3615 : }
524 : };
525 :
526 : struct CellExtents : MeshExtents
527 : {
528 : // Members
529 : Real64 Xmin;
530 : Real64 Ymin;
531 : Real64 Zmin;
532 :
533 : // Member Constructor
534 3615 : CellExtents(Real64 const Xmax, Real64 const Ymax, Real64 const Zmax, Real64 const Xmin, Real64 const Ymin, Real64 const Zmin)
535 3615 : : MeshExtents(Xmax, Ymax, Zmax), Xmin(Xmin), Ymin(Ymin), Zmin(Zmin)
536 : {
537 3615 : }
538 : };
539 :
540 : struct DistributionStructure
541 : {
542 : // Members
543 : MeshDistribution thisMeshDistribution = MeshDistribution::Uniform;
544 : int RegionMeshCount = 0;
545 : Real64 GeometricSeriesCoefficient = 0.0;
546 :
547 : // Default Constructor
548 81 : DistributionStructure() = default;
549 : };
550 :
551 : struct MeshProperties
552 : {
553 : // Members
554 : DistributionStructure X;
555 : DistributionStructure Y;
556 : DistributionStructure Z;
557 :
558 : // Default Constructor
559 27 : MeshProperties() = default;
560 : };
561 :
562 : struct SimulationControl
563 : {
564 : // Members
565 : Real64 MinimumTemperatureLimit = -1000;
566 : Real64 MaximumTemperatureLimit = 1000;
567 : Real64 Convergence_CurrentToPrevIteration = 0.0;
568 : int MaxIterationsPerTS = 0;
569 :
570 : // Default Constructor
571 27 : SimulationControl() = default;
572 : };
573 :
574 : struct BasementZoneInfo
575 : {
576 : // Members
577 : Real64 Depth = 0; // m
578 : Real64 Width = 0; // m
579 : Real64 Length = 0; // m
580 : bool ShiftPipesByWidth = false;
581 : std::string WallBoundaryOSCMName;
582 : int WallBoundaryOSCMIndex = 0;
583 : std::string FloorBoundaryOSCMName;
584 : int FloorBoundaryOSCMIndex = 0;
585 : std::vector<int> WallSurfacePointers;
586 : std::vector<int> FloorSurfacePointers;
587 : int BasementWallXIndex = -1;
588 : int BasementFloorYIndex = -1;
589 :
590 : // Default Constructor
591 27 : BasementZoneInfo() = default;
592 : };
593 :
594 : struct MeshPartitions
595 : {
596 : // Members
597 : std::vector<MeshPartition> X;
598 : std::vector<MeshPartition> Y;
599 : std::vector<MeshPartition> Z;
600 :
601 : // Default Constructor
602 27 : MeshPartitions() = default;
603 : };
604 :
605 : struct MoistureInfo
606 : {
607 : // Members
608 : Real64 Theta_liq = 0.3; // volumetric moisture content of the soil
609 : Real64 Theta_sat = 0.5; // volumetric moisture content of soil at saturation
610 : Real64 GroundCoverCoefficient = 0.408;
611 : Real64 rhoCP_soil_liq = 0.0;
612 : Real64 rhoCP_soil_transient = 0.0;
613 : Real64 rhoCP_soil_ice = 0.0;
614 : Real64 rhoCp_soil_liq_1 = 0.0;
615 :
616 : // Default Constructor
617 27 : MoistureInfo() = default;
618 : };
619 :
620 : struct CurSimConditionsInfo
621 : {
622 : // Members
623 : // Simulation conditions
624 : Real64 PrevSimTimeSeconds = -1.0;
625 : Real64 CurSimTimeSeconds = 0.0;
626 : Real64 CurSimTimeStepSize = 0.0;
627 : // Environmental conditions
628 : Real64 CurAirTemp = 10.0;
629 : Real64 CurWindSpeed = 2.6;
630 : Real64 CurIncidentSolar = 0.0;
631 : Real64 CurRelativeHumidity = 100.0;
632 :
633 : // Default Constructor
634 27 : CurSimConditionsInfo() = default;
635 : };
636 :
637 : struct Segment
638 : {
639 : // Members
640 : // ID
641 : std::string Name;
642 : // Misc inputs
643 : PointF PipeLocation;
644 : Point PipeCellCoordinates;
645 : SegmentFlow FlowDirection = SegmentFlow::IncreasingZ;
646 : // Reporting variables
647 : Real64 InletTemperature = 0.0;
648 : Real64 OutletTemperature = 0.0;
649 : Real64 FluidHeatLoss = 0.0;
650 : // Error handling flags
651 : bool PipeCellCoordinatesSet = false;
652 : // Other flags
653 : bool IsActuallyPartOfAHorizontalTrench = false;
654 :
655 : // Default Constructor
656 8 : Segment() = default;
657 :
658 : void initPipeCells(int x, int y);
659 :
660 : bool operator==(std::string const &a)
661 : {
662 : return this->Name == a;
663 : }
664 :
665 : static Segment *factory(EnergyPlusData &state, const std::string &segmentName);
666 : };
667 :
668 : struct Circuit : public PlantComponent
669 : {
670 :
671 : // Members
672 : // ID
673 : std::string Name;
674 : // Inlet and outlet information
675 : std::string InletNodeName;
676 : std::string OutletNodeName;
677 : int InletNodeNum = 0;
678 : int OutletNodeNum = 0;
679 : Point3DInteger CircuitInletCell;
680 : Point3DInteger CircuitOutletCell;
681 : // Names and pointers to pipe segments found in this pipe circuit
682 : std::vector<Segment *> pipeSegments;
683 : // Pointer to the domain which contains this pipe circuit
684 : int ParentDomainIndex = 0;
685 : // Misc inputs
686 : RadialSizing PipeSize;
687 : RadialSizing InsulationSize;
688 : Real64 RadialMeshThickness = 0.0;
689 : bool HasInsulation = false;
690 : Real64 DesignVolumeFlowRate = 0.0;
691 : Real64 DesignMassFlowRate = 0.0;
692 : Real64 Convergence_CurrentToPrevIteration = 0.0;
693 : int MaxIterationsPerTS = 0;
694 : int NumRadialCells = 0;
695 : BaseThermalPropertySet PipeProperties;
696 : BaseThermalPropertySet InsulationProperties;
697 : // Flags
698 : bool NeedToFindOnPlantLoop = true;
699 : bool IsActuallyPartOfAHorizontalTrench = false;
700 : // Location of this pipe circuit in the PlantLoop topology
701 : PlantLocation plantLoc{};
702 : ExtendedFluidProperties CurFluidPropertySet; // is_used
703 : // Variables used to pass information from INIT-type routines to CALC-type routines
704 : Real64 CurCircuitInletTemp = 23.0;
705 : Real64 CurCircuitFlowRate = 0.1321;
706 : Real64 CurCircuitConvectionCoefficient = 0.0;
707 : // Reporting variables
708 : Real64 InletTemperature = 0.0;
709 : Real64 OutletTemperature = 0.0;
710 : Real64 FluidHeatLoss = 0.0;
711 :
712 : // Default Constructor
713 3 : Circuit() = default;
714 :
715 7 : virtual ~Circuit() = default;
716 :
717 : void initInOutCells(CartesianCell const &in, CartesianCell const &out);
718 :
719 : static PlantComponent *factory(EnergyPlusData &state, DataPlant::PlantEquipmentType, const std::string &objectName);
720 :
721 : void simulate([[maybe_unused]] EnergyPlusData &state,
722 : const PlantLocation &calledFromLocation,
723 : bool FirstHVACIteration,
724 : Real64 &CurLoad,
725 : bool RunFlag) override;
726 :
727 : bool operator==(std::string const &a)
728 : {
729 : return this->Name == a;
730 : }
731 :
732 : static Circuit *factory(EnergyPlusData &state, const std::string &circuit, bool &errorsFound);
733 :
734 : void oneTimeInit(EnergyPlusData &state) override;
735 :
736 : void oneTimeInit_new(EnergyPlusData &state) override;
737 : };
738 :
739 : struct ZoneCoupledSurfaceData
740 : {
741 : // Members
742 : // ID
743 : std::string Name;
744 : // Surface data
745 : int IndexInSurfaceArray;
746 : Real64 SurfaceArea;
747 : Real64 Width;
748 : Real64 Length;
749 : Real64 Depth;
750 : Real64 Conductivity;
751 : Real64 Density;
752 : Real64 InsulationConductivity;
753 : Real64 InsulationDensity;
754 : int Zone;
755 :
756 : // Default Constructor
757 22 : ZoneCoupledSurfaceData()
758 44 : : IndexInSurfaceArray(0), SurfaceArea(0.0), Width(0.0), Length(0.0), Depth(0.0), Conductivity(0.0), Density(0.0),
759 22 : InsulationConductivity(0.0), InsulationDensity(0.0), Zone(0)
760 : {
761 22 : }
762 : };
763 :
764 : struct Domain
765 : {
766 : // Members
767 : // ID
768 : std::string Name;
769 : // Names and pointers to circuits found in this domain
770 : std::vector<Circuit *> circuits;
771 : int MaxIterationsPerTS;
772 : // Flag variables
773 : bool OneTimeInit;
774 : bool BeginSimInit;
775 : bool BeginSimEnvironment;
776 : bool DomainNeedsSimulation;
777 : bool DomainNeedsToBeMeshed;
778 : bool IsActuallyPartOfAHorizontalTrench;
779 : bool HasAPipeCircuit;
780 : bool HasZoneCoupledSlab;
781 : bool HasZoneCoupledBasement;
782 : // "Input" data structure variables
783 : MeshExtents Extents;
784 : MeshProperties Mesh;
785 : BaseThermalPropertySet GroundProperties;
786 : BaseThermalPropertySet SlabProperties;
787 : BaseThermalPropertySet BasementInterfaceProperties;
788 : BaseThermalPropertySet HorizInsProperties;
789 : BaseThermalPropertySet VertInsProperties;
790 : SimulationControl SimControls;
791 : GroundTemp::BaseGroundTempsModel *groundTempModel; // non-owning pointer
792 : BasementZoneInfo BasementZone;
793 : MoistureInfo Moisture;
794 : // "Internal" data structure variables
795 : MeshPartitions Partitions;
796 : CurSimConditionsInfo Cur;
797 : bool HasBasement;
798 : // Zone coupled variables
799 : std::vector<ZoneCoupledSurfaceData> ZoneCoupledSurfaces;
800 : int ZoneCoupledOSCMIndex;
801 : Real64 PerimeterOffset;
802 : SlabPosition slabPosition = SlabPosition::Invalid;
803 : int SlabMaterialNum;
804 : Real64 SlabArea;
805 : Real64 SlabWidth;
806 : Real64 SlabLength;
807 : Real64 SlabThickness;
808 : int XIndex;
809 : int YIndex;
810 : int ZIndex;
811 : int x_max_index;
812 : int y_max_index;
813 : int z_max_index;
814 : HorizInsulation HorizIns = HorizInsulation::Invalid;
815 : int HorizInsMaterialNum;
816 : Real64 HorizInsThickness;
817 : Real64 HorizInsWidth;
818 : Real64 HeatFlux;
819 : Real64 WallHeatFlux;
820 : Real64 FloorHeatFlux;
821 : Real64 AggregateHeatFlux;
822 : Real64 AggregateWallHeatFlux;
823 : Real64 AggregateFloorHeatFlux;
824 : int NumHeatFlux;
825 : bool ResetHeatFluxFlag;
826 : Real64 ConvectionCoefficient;
827 : bool VertInsPresentFlag;
828 : int VertInsMaterialNum;
829 : Real64 VertInsThickness;
830 : Real64 VertInsDepth;
831 : int XWallIndex;
832 : int YFloorIndex;
833 : int ZWallIndex;
834 : int InsulationXIndex;
835 : int InsulationYIndex;
836 : int InsulationZIndex;
837 : #ifdef GET_OUT
838 : // Don't seem to be used anywhere
839 : bool SimTimeStepFlag = false;
840 : bool SimHourlyFlag = false;
841 : bool SimDailyFlag = false;
842 : #endif // GET_OUT
843 : Real64 ZoneCoupledSurfaceTemp;
844 : Real64 BasementWallTemp;
845 : Real64 BasementFloorTemp;
846 : int NumDomainCells;
847 : int NumGroundSurfCells;
848 : int NumInsulationCells;
849 : int NumSlabCells;
850 : Array2D<Real64> WeightingFactor;
851 : Array2D<Real64> WeightedHeatFlux;
852 : Real64 TotalEnergyUniformHeatFlux = 0.0;
853 : Real64 TotalEnergyWeightedHeatFlux = 0.0;
854 : Real64 HeatFluxWeightingFactor = 0.0;
855 : std::vector<GridRegion> XRegions;
856 : std::vector<GridRegion> YRegions;
857 : std::vector<GridRegion> ZRegions;
858 :
859 : // Main 3D cells array
860 : Array3D<CartesianCell> Cells;
861 :
862 : // Dynamic indexes to available neighbor directions for a particular cell
863 : std::vector<Direction> NeighborFieldCells;
864 : std::vector<Direction> NeighborBoundaryCells;
865 :
866 : // Default Constructor
867 27 : Domain()
868 54 : : MaxIterationsPerTS(10), OneTimeInit(true), BeginSimInit(true), BeginSimEnvironment(true), DomainNeedsSimulation(true),
869 27 : DomainNeedsToBeMeshed(true), IsActuallyPartOfAHorizontalTrench(false), HasAPipeCircuit(true), HasZoneCoupledSlab(false),
870 81 : HasZoneCoupledBasement(false), HasBasement(false), ZoneCoupledOSCMIndex(0), PerimeterOffset(0.0), SlabMaterialNum(0), SlabArea(0.0),
871 27 : SlabWidth(0.0), SlabLength(0.0), SlabThickness(0.0), XIndex(0), YIndex(0), ZIndex(0), x_max_index(0), y_max_index(0), z_max_index(0),
872 27 : HorizInsMaterialNum(0), HorizInsThickness(0.0254), HorizInsWidth(0.0), HeatFlux(0.0), WallHeatFlux(0.0), FloorHeatFlux(0.0),
873 27 : AggregateHeatFlux(0.0), AggregateWallHeatFlux(0.0), AggregateFloorHeatFlux(0.0), NumHeatFlux(0), ResetHeatFluxFlag(true),
874 27 : ConvectionCoefficient(0.0), VertInsPresentFlag(false), VertInsMaterialNum(0), VertInsThickness(0.0254), VertInsDepth(0.0),
875 27 : XWallIndex(0), YFloorIndex(0), ZWallIndex(0), InsulationXIndex(0), InsulationYIndex(0), InsulationZIndex(0),
876 27 : ZoneCoupledSurfaceTemp(0.0), BasementWallTemp(0.0), BasementFloorTemp(0.0), NumDomainCells(0), NumGroundSurfCells(0),
877 27 : NumInsulationCells(0), NumSlabCells(0)
878 : {
879 27 : NeighborFieldCells.resize(6);
880 27 : NeighborBoundaryCells.resize(6);
881 27 : }
882 :
883 : void developMesh(EnergyPlusData &state);
884 :
885 : void createPartitionCenterList(EnergyPlusData &state);
886 :
887 : std::vector<GridRegion> createPartitionRegionList(EnergyPlusData &state,
888 : std::vector<MeshPartition> const &ThesePartitionCenters,
889 : bool PartitionsExist,
890 : Real64 DirExtentMax);
891 :
892 : void createRegionList(std::vector<GridRegion> &Regions,
893 : std::vector<GridRegion> const &ThesePartitionRegions,
894 : Real64 DirExtentMax,
895 : RegionType DirDirection,
896 : bool PartitionsExist,
897 : ObjexxFCL::Optional_int BasementWallXIndex = _,
898 : ObjexxFCL::Optional_int BasementFloorYIndex = _,
899 : ObjexxFCL::Optional_int XIndex = _,
900 : ObjexxFCL::Optional_int XWallIndex = _,
901 : ObjexxFCL::Optional_int InsulationXIndex = _,
902 : ObjexxFCL::Optional_int YIndex = _,
903 : ObjexxFCL::Optional_int YFloorIndex = _,
904 : ObjexxFCL::Optional_int InsulationYIndex = _,
905 : ObjexxFCL::Optional_int ZIndex = _,
906 : ObjexxFCL::Optional_int ZWallIndex = _,
907 : ObjexxFCL::Optional_int InsulationZIndex = _);
908 :
909 : void createCellArray(std::vector<Real64> const &XBoundaryPoints,
910 : std::vector<Real64> const &YBoundaryPoints,
911 : std::vector<Real64> const &ZBoundaryPoints);
912 :
913 : void setupCellNeighbors();
914 :
915 : void setupPipeCircuitInOutCells();
916 :
917 : int getCellWidthsCount(RegionType dir) const;
918 :
919 : void getCellWidths(GridRegion &g, RegionType direction) const;
920 :
921 : void addNeighborInformation(int X,
922 : int Y,
923 : int Z,
924 : Direction direction,
925 : Real64 ThisCentroidToNeighborWall,
926 : Real64 ThisWallToNeighborCentroid,
927 : Real64 ThisAdiabaticMultiplier);
928 :
929 : Real64 GetBasementWallHeatFlux(EnergyPlusData &state);
930 :
931 : Real64 GetBasementFloorHeatFlux(EnergyPlusData &state);
932 :
933 : void UpdateBasementSurfaceTemperatures(EnergyPlusData &state);
934 :
935 : Real64 GetZoneInterfaceHeatFlux(EnergyPlusData &state);
936 :
937 : void UpdateZoneSurfaceTemperatures(EnergyPlusData &state);
938 :
939 : Real64 GetAverageTempByType(EnergyPlusData &state, CellType cellType) const;
940 :
941 : void InitializeSoilMoistureCalcs();
942 :
943 : void EvaluateSoilRhoCp(Real64 CellTemp, Real64 &rhoCp) const;
944 :
945 : void ShiftTemperaturesForNewTimeStep();
946 :
947 : void ShiftTemperaturesForNewIteration();
948 :
949 : bool IsConverged_CurrentToPrevIteration();
950 :
951 : bool CheckForOutOfRangeTemps() const;
952 :
953 : void EvaluateNeighborCharacteristics(
954 : CartesianCell &ThisCell, Direction CurDirection, Real64 &NeighborTemp, Real64 &Resistance, Real64 &AdiabaticMultiplier);
955 :
956 : void EvaluateCellNeighborDirections(CartesianCell const &cell, int &NumFieldCells, int &NumBoundaryCells);
957 :
958 : void DoEndOfIterationOperations(EnergyPlusData &state, bool &Finished);
959 :
960 : void DoOneTimeInitializations(EnergyPlusData &state, Circuit *thisCircuit);
961 :
962 : void DoStartOfTimeStepInitializations(EnergyPlusData &state);
963 :
964 : void DoStartOfTimeStepInitializations(EnergyPlusData &state, Circuit *thisCircuit);
965 :
966 : Real64 GetFarfieldTemp(EnergyPlusData &state, CartesianCell const &cell);
967 :
968 : void PreparePipeCircuitSimulation(Circuit *thisCircuit);
969 :
970 : void PerformPipeCircuitSimulation(EnergyPlusData &state, Circuit *thisCircuit);
971 :
972 : void PerformPipeCellSimulation(Circuit *thisCircuit, CartesianCell &ThisCell, Real64 FlowRate, Real64 EnteringTemp);
973 :
974 : void SimulateRadialToCartesianInterface(CartesianCell &ThisCell);
975 :
976 : void PerformTemperatureFieldUpdate(EnergyPlusData &state);
977 :
978 : Real64 EvaluateFieldCellTemperature(CartesianCell &ThisCell);
979 :
980 : Real64 EvaluateGroundSurfaceTemperature(EnergyPlusData &state, CartesianCell &cell);
981 :
982 : Real64 EvaluateBasementCellTemperature(EnergyPlusData &state, CartesianCell &cell);
983 :
984 : Real64 EvaluateZoneInterfaceTemperature(CartesianCell &cell);
985 :
986 : Real64 EvaluateFarfieldBoundaryTemperature(EnergyPlusData &state, CartesianCell &cell);
987 :
988 : void EvaluateFarfieldCharacteristics(
989 : EnergyPlusData &state, CartesianCell &cell, Direction direction, Real64 &neighbortemp, Real64 &resistance, Real64 &adiabaticMultiplier);
990 :
991 : void PerformIterationLoop(EnergyPlusData &state);
992 :
993 : void PerformIterationLoop(EnergyPlusData &state, Circuit *thisCircuit);
994 :
995 : void InitPipingSystems(EnergyPlusData &state, Circuit *thisCircuit);
996 :
997 : void UpdatePipingSystems(EnergyPlusData &state, Circuit *thisCircuit);
998 :
999 : void SetupZoneCoupledOutputVariables(EnergyPlusData &state);
1000 : };
1001 :
1002 : void SimulateGroundDomains(EnergyPlusData &state, bool initOnly);
1003 :
1004 : void CheckIfAnySlabs(EnergyPlusData &state);
1005 :
1006 : void CheckIfAnyBasements(EnergyPlusData &state);
1007 :
1008 : void GetPipingSystemsAndGroundDomainsInput(EnergyPlusData &state);
1009 :
1010 : void ReadGeneralDomainInputs(EnergyPlusData &state, const int IndexStart, const int NumGeneralizedDomains, bool &ErrorsFound);
1011 :
1012 : void ReadZoneCoupledDomainInputs(EnergyPlusData &state, const int StartingDomainNumForZone, const int NumZoneCoupledDomains, bool &ErrorsFound);
1013 :
1014 : void ReadBasementInputs(EnergyPlusData &state, const int StartingDomainNumForBasement, const int NumBasements, bool &ErrorsFound);
1015 :
1016 : bool SiteGroundDomainUsingNoMassMat(EnergyPlusData &state, Real64 const MaterialThickness, int const MaterialNum);
1017 :
1018 : void SiteGroundDomainNoMassMatError(EnergyPlusData &state,
1019 : std::string_view FieldName,
1020 : std::string const &UserInputField,
1021 : std::string const &ObjectName);
1022 :
1023 : void ReadPipeCircuitInputs(EnergyPlusData &state, bool &ErrorsFound);
1024 :
1025 : void ReadPipeSegmentInputs(EnergyPlusData &state, bool &ErrorsFound);
1026 :
1027 : void ReadHorizontalTrenchInputs(EnergyPlusData &state,
1028 : const int StartingDomainNumForHorizontal,
1029 : const int StartingCircuitNumForHorizontal,
1030 : bool &ErrorsFound);
1031 :
1032 : void SetupPipingSystemOutputVariables(EnergyPlusData &state);
1033 :
1034 : void IssueSevereInputFieldError(EnergyPlusData &state,
1035 : std::string_view const RoutineName,
1036 : std::string const &ObjectName,
1037 : std::string const &InstanceName,
1038 : std::string_view FieldName,
1039 : std::string const &FieldEntry,
1040 : std::string const &Condition,
1041 : bool &ErrorsFound);
1042 :
1043 : void IssueSevereInputFieldError(EnergyPlusData &state,
1044 : std::string_view const RoutineName,
1045 : std::string const &ObjectName,
1046 : std::string const &InstanceName,
1047 : std::string_view FieldName,
1048 : Real64 FieldEntry,
1049 : std::string const &Condition,
1050 : bool &ErrorsFound);
1051 :
1052 : int GetSurfaceCountForOSCM(EnergyPlusData &state, int OSCMIndex);
1053 :
1054 : std::vector<int> GetSurfaceIndecesForOSCM(EnergyPlusData &state, int OSCMIndex);
1055 :
1056 : std::vector<ZoneCoupledSurfaceData> GetSurfaceDataForOSCM(EnergyPlusData &state, int OSCMIndex);
1057 :
1058 17 : bool inline IsInRangeReal(Real64 const r, Real64 const lower, Real64 const upper)
1059 : {
1060 17 : return ((r >= lower) && (r <= upper));
1061 : }
1062 :
1063 3 : bool inline IsInRange_BasementModel(Real64 const r, Real64 const lower, Real64 const upper)
1064 : {
1065 3 : return ((r >= lower) && (r < upper));
1066 : }
1067 :
1068 : void ShiftPipeTemperaturesForNewIteration(CartesianCell &ThisPipeCell);
1069 :
1070 : std::vector<Real64> CreateBoundaryList(std::vector<GridRegion> const &RegionList, Real64 DirExtentMax, RegionType DirDirection);
1071 :
1072 : void SimulateOuterMostRadialSoilSlice(Circuit *thisCircuit, CartesianCell &ThisCell);
1073 :
1074 : void SimulateAllInteriorRadialSoilSlices(CartesianCell &ThisCell);
1075 :
1076 : void SimulateInnerMostRadialSoilSlice(Circuit *thisCircuit, CartesianCell &ThisCell);
1077 :
1078 : void SimulateRadialInsulationCell(CartesianCell &ThisCell);
1079 :
1080 : void SimulateRadialPipeCell(Circuit const *thisCircuit, CartesianCell &ThisCell);
1081 :
1082 : void SimulateFluidCell(Circuit const *thisCircuit, CartesianCell &ThisCell, Real64 FlowRate, Real64 EnteringFluidTemp);
1083 :
1084 : bool IsConverged_PipeCurrentToPrevIteration(Circuit const *thisCircuit, CartesianCell const &CellToCheck);
1085 :
1086 : } // namespace PlantPipingSystemsManager
1087 :
1088 : struct PlantPipingSysMgrData : BaseGlobalStruct
1089 : {
1090 :
1091 : bool GetInputFlag = true;
1092 : bool GetSegmentInputFlag = true;
1093 : bool GetCircuitInputFlag = true;
1094 : bool WriteEIOFlag = true;
1095 : std::vector<PlantPipingSystemsManager::Domain> domains;
1096 : std::vector<PlantPipingSystemsManager::Circuit> circuits;
1097 : std::vector<PlantPipingSystemsManager::Segment> segments;
1098 : std::unordered_map<std::string, std::string> GroundDomainUniqueNames;
1099 :
1100 2126 : void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
1101 : {
1102 2126 : }
1103 :
1104 1152 : void init_state([[maybe_unused]] EnergyPlusData &state) override
1105 : {
1106 1152 : }
1107 :
1108 2100 : void clear_state() override
1109 : {
1110 2100 : this->GetInputFlag = true;
1111 2100 : this->GetSegmentInputFlag = true;
1112 2100 : this->GetCircuitInputFlag = true;
1113 2100 : this->WriteEIOFlag = true;
1114 2100 : this->domains.clear();
1115 2100 : this->circuits.clear();
1116 2100 : this->segments.clear();
1117 2100 : this->GroundDomainUniqueNames.clear();
1118 2100 : }
1119 : };
1120 :
1121 : } // namespace EnergyPlus
1122 :
1123 : #endif
|