OGS
BHE_1U.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "BHE_1U.h"
5
6#include <numbers>
7
9#include "Physics.h"
11
12namespace ProcessLib
13{
14namespace HeatTransportBHE
15{
16namespace BHE
17{
22 PipeConfigurationUType const& pipes,
23 bool const use_python_bcs)
25 pipes, use_python_bcs}
26{
27 _thermal_resistances.fill(std::numeric_limits<double>::quiet_NaN());
28
29 // Initialize thermal resistances.
30 auto values = visit(
31 [&](auto const& control) {
32 return control(refrigerant.reference_temperature,
33 0. /* initial time */);
34 },
36 updateHeatTransferCoefficients(values.flow_rate);
37}
38
39std::array<double, BHE_1U::number_of_unknowns> BHE_1U::pipeHeatCapacities()
40 const
41{
42 double const rho_r = refrigerant.density;
43 double const specific_heat_capacity = refrigerant.specific_heat_capacity;
44 double const rho_g = grout.rho_g;
45 double const porosity_g = grout.porosity_g;
46 double const heat_cap_g = grout.heat_cap_g;
47
48 return {{/*i1*/ rho_r * specific_heat_capacity,
49 /*o1*/ rho_r * specific_heat_capacity,
50 /*g1*/ (1.0 - porosity_g) * rho_g * heat_cap_g,
51 /*g2*/ (1.0 - porosity_g) * rho_g * heat_cap_g}};
52}
53
54std::array<double, BHE_1U::number_of_unknowns> BHE_1U::pipeHeatConductions()
55 const
56{
57 double const lambda_r = refrigerant.thermal_conductivity;
58 double const rho_r = refrigerant.density;
59 double const Cp_r = refrigerant.specific_heat_capacity;
60 double const alpha_L = _pipes.longitudinal_dispersion_length;
61 double const porosity_g = grout.porosity_g;
62 double const lambda_g = grout.lambda_g;
63
64 double const velocity_norm = std::abs(_flow_velocity);
65
66 // Here we calculate the laplace coefficients in the governing
67 // equations of BHE. These governing equations can be found in
68 // 1) Diersch (2013) FEFLOW book on page 952, M.120-122, or
69 // 2) Diersch (2011) Comp & Geosci 37:1122-1135, Eq. 19-22.
70 return {{// pipe i1, Eq. 19
71 (lambda_r + rho_r * Cp_r * alpha_L * velocity_norm),
72 // pipe o1, Eq. 20
73 (lambda_r + rho_r * Cp_r * alpha_L * velocity_norm),
74 // pipe g1, Eq. 21
75 (1.0 - porosity_g) * lambda_g,
76 // pipe g2, Eq. 22
77 (1.0 - porosity_g) * lambda_g}};
78}
79
80std::array<Eigen::Vector3d, BHE_1U::number_of_unknowns>
81BHE_1U::pipeAdvectionVectors(Eigen::Vector3d const& /*elem_direction*/) const
82{
83 double const& rho_r = refrigerant.density;
84 double const& Cp_r = refrigerant.specific_heat_capacity;
85
86 return {{// pipe i1, Eq. 19
87 {0, 0, -rho_r * Cp_r * _flow_velocity},
88 // pipe o1, Eq. 20
89 {0, 0, rho_r * Cp_r * _flow_velocity},
90 // grout g1, Eq. 21
91 {0, 0, 0},
92 // grout g2, Eq. 22
93 {0, 0, 0}}};
94}
95
96double compute_R_gs(double const chi, double const R_g)
97{
98 return (1 - chi) * R_g;
99}
100
101double compute_R_gg(double const chi, double const R_gs, double const R_ar,
102 double const R_g)
103{
104 double const R_gg = 2.0 * R_gs * (R_ar - 2.0 * chi * R_g) /
105 (2.0 * R_gs - R_ar + 2.0 * chi * R_g);
106 if (!std::isfinite(R_gg))
107 {
108 OGS_FATAL(
109 "Error!!! Grout Thermal Resistance is an infinite number! The "
110 "simulation will be stopped!");
111 }
112
113 return R_gg;
114}
115
121std::array<double, 3> thermalResistancesGroutSoil(double const chi,
122 double const R_ar,
123 double const R_g)
124{
125 double R_gs = compute_R_gs(chi, R_g);
126 double R_gg =
127 compute_R_gg(chi, R_gs, R_ar, R_g); // Resulting thermal resistances.
128 double new_chi = chi;
129
130 auto constraint = [&]()
131 { return 1.0 / ((1.0 / R_gg) + (1.0 / (2.0 * R_gs))); };
132
133 std::array<double, 3> const multiplier{chi * 2.0 / 3.0, chi * 1.0 / 3.0,
134 0.0};
135 for (double m_chi : multiplier)
136 {
137 if (constraint() >= 0)
138 {
139 break;
140 }
141 DBUG(
142 "Warning! Correction procedure was applied due to negative thermal "
143 "resistance! Chi = {:f}.\n",
144 m_chi);
145
146 R_gs = compute_R_gs(m_chi, R_g);
147 R_gg = compute_R_gg(m_chi, R_gs, R_ar, R_g);
148 new_chi = m_chi;
149 }
150
151 return {new_chi, R_gg, R_gs};
152}
153
154void BHE_1U::updateHeatTransferCoefficients(double const flow_rate)
155
156{
157 auto const tm_flow_properties = calculateThermoMechanicalFlowPropertiesPipe(
158 _pipes.inlet, borehole_geometry.length, refrigerant, flow_rate);
159
160 _flow_velocity = tm_flow_properties.velocity;
162 calcThermalResistances(tm_flow_properties.nusselt_number);
163}
164
166std::array<double, BHE_1U::number_of_unknowns> BHE_1U::calcThermalResistances(
167 double const Nu)
168{
169 constexpr double pi = std::numbers::pi;
170
171 double const lambda_r = refrigerant.thermal_conductivity;
172 double const lambda_g = grout.lambda_g;
173 double const lambda_p = _pipes.inlet.wall_thermal_conductivity;
174
175 // thermal resistances due to advective flow of refrigerant in the _pipes
176 // Eq. 36 in Diersch_2011_CG
177 double const R_adv_i1 = 1.0 / (Nu * lambda_r * pi);
178 double const R_adv_o1 = 1.0 / (Nu * lambda_r * pi);
179
180 // thermal resistance due to thermal conductivity of the pipe wall material
181 // Eq. 49
182 double const R_con_a =
183 std::log(_pipes.inlet.outsideDiameter() / _pipes.inlet.diameter) /
184 (2.0 * pi * lambda_p);
185
186 // the average outer diameter of the _pipes
187 double const d0 = _pipes.inlet.outsideDiameter();
188 double const D = borehole_geometry.diameter;
189 // Eq. 51
190 double const chi = std::log(std::sqrt(D * D + 2 * d0 * d0) / 2 / d0) /
191 std::log(D / std::sqrt(2) / d0);
192 // Eq. 52
193 // thermal resistances of the grout
194 double const R_g =
195 std::acosh((D * D + d0 * d0 - _pipes.distance * _pipes.distance) /
196 (2 * D * d0)) /
197 (2 * pi * lambda_g) * (1.601 - 0.888 * _pipes.distance / D);
198
199 // thermal resistance due to inter-grout exchange
200 double const R_ar =
201 std::acosh((2.0 * _pipes.distance * _pipes.distance - d0 * d0) / d0 /
202 d0) /
203 (2.0 * pi * lambda_g);
204
205 auto const [chi_new, R_gg, R_gs] =
206 thermalResistancesGroutSoil(chi, R_ar, R_g);
207
208 // thermal resistance due to the grout transition.
209 double const R_con_b = chi_new * R_g;
210 // Eq. 29 and 30
211 double const R_fig = R_adv_i1 + R_con_a + R_con_b;
212 double const R_fog = R_adv_o1 + R_con_a + R_con_b;
213
214 return {{R_fig, R_fog, R_gg, R_gs}};
215
216 // keep the following lines------------------------------------------------
217 // when debugging the code, printing the R and phi values are needed--------
218 // std::cout << "Rfig =" << R_fig << " Rfog =" << R_fog << " Rgg =" <<
219 // R_gg << " Rgs =" << R_gs << "\n"; double phi_fig = 1.0 / (R_fig *
220 // S_i); double phi_fog = 1.0 / (R_fog * S_o); double phi_gg = 1.0 / (R_gg
221 // * S_g1); double phi_gs = 1.0 / (R_gs * S_gs); std::cout << "phi_fig ="
222 // << phi_fig << " phi_fog =" << phi_fog << " phi_gg =" << phi_gg << "
223 // phi_gs =" << phi_gs << "\n";
224 // -------------------------------------------------------------------------
225}
226
227std::array<std::pair<std::size_t /*node_id*/, int /*component*/>, 2>
229 std::size_t const top_node_id,
230 std::size_t const /*bottom_node_id*/,
231 int const in_component_id)
232{
233 return {std::make_pair(top_node_id, in_component_id),
234 std::make_pair(top_node_id, in_component_id + 1)};
235}
236
237std::optional<
238 std::array<std::pair<std::size_t /*node_id*/, int /*component*/>, 2>>
240 std::size_t const bottom_node_id,
241 int const in_component_id,
242 int const out_component_id)
243{
244 return {{std::make_pair(bottom_node_id, in_component_id),
245 std::make_pair(bottom_node_id, out_component_id)}};
246}
247
248std::array<double, BHE_1U::number_of_unknowns> BHE_1U::crossSectionAreas() const
249{
250 return {{_pipes.inlet.area(), _pipes.outlet.area(),
251 borehole_geometry.area() / 2 - _pipes.inlet.outsideArea(),
252 borehole_geometry.area() / 2 - _pipes.outlet.outsideArea()}};
253}
254
255double BHE_1U::updateFlowRateAndTemperature(double const T_out,
256 double const current_time)
257{
258 auto values =
259 visit([&](auto const& control) { return control(T_out, current_time); },
261 updateHeatTransferCoefficients(values.flow_rate);
262 return values.temperature;
263}
264} // namespace BHE
265} // namespace HeatTransportBHE
266} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
BHECommonUType(BoreholeGeometry const &borehole, RefrigerantProperties const &refrigerant, GroutParameters const &grout, FlowAndTemperatureControl const &flowAndTemperatureControl, PipeConfigurationUType const &pipes, bool const use_python_bcs)
double _flow_velocity
Flow velocity inside the pipes. Depends on the flow_rate.
std::array< Eigen::Vector3d, number_of_unknowns > pipeAdvectionVectors(Eigen::Vector3d const &) const
Definition BHE_1U.cpp:81
double updateFlowRateAndTemperature(double T_out, double current_time)
Return the inflow temperature for the boundary condition.
Definition BHE_1U.cpp:255
static std::optional< std::array< std::pair< std::size_t, int >, 2 > > getBHEBottomDirichletBCNodesAndComponents(std::size_t const bottom_node_id, int const in_component_id, int const out_component_id)
Definition BHE_1U.cpp:239
std::array< double, number_of_unknowns > calcThermalResistances(double const Nu)
Nu is the Nusselt number.
Definition BHE_1U.cpp:166
std::array< double, number_of_unknowns > pipeHeatConductions() const
Definition BHE_1U.cpp:54
std::array< double, number_of_unknowns > _thermal_resistances
Definition BHE_1U.h:161
std::array< double, number_of_unknowns > crossSectionAreas() const
Definition BHE_1U.cpp:248
void updateHeatTransferCoefficients(double const flow_rate)
Definition BHE_1U.cpp:154
BHE_1U(BoreholeGeometry const &borehole, RefrigerantProperties const &refrigerant, GroutParameters const &grout, FlowAndTemperatureControl const &flowAndTemperatureControl, PipeConfigurationUType const &pipes, bool const use_python_bcs)
Definition BHE_1U.cpp:18
static std::array< std::pair< std::size_t, int >, 2 > getBHEInflowDirichletBCNodesAndComponents(std::size_t const top_node_id, std::size_t const, int const in_component_id)
Definition BHE_1U.cpp:228
std::array< double, number_of_unknowns > pipeHeatCapacities() const
Definition BHE_1U.cpp:39
double compute_R_gg(double const chi, double const R_gs, double const R_ar, double const R_g)
Definition BHE_1U.cpp:101
double compute_R_gs(double const chi, double const R_g)
Definition BHE_1U.cpp:96
std::variant< TemperatureCurveConstantFlow, TemperatureCurveFlowCurve, FixedPowerConstantFlow, FixedPowerFlowCurve, PowerCurveConstantFlow, PowerCurveFlowCurve, BuildingPowerCurveConstantFlow, BuildingPowerCurveHotWaterCurveActiveCoolingCurveFlowCurve, BuildingPowerCurveHotWaterCurvePassiveCoolingCurveFlowCurve, BuildingPowerCurveHotWaterCurveFlowCurve, BuildingPowerCurveActiveCoolingCurveFlowCurve, BuildingPowerCurvePassiveCoolingCurveFlowCurve, BuildingPowerCurveFlowCurve, ActiveCoolingCurveFlowCurve > FlowAndTemperatureControl
std::array< double, 3 > thermalResistancesGroutSoil(double const chi, double const R_ar, double const R_g)
Definition BHE_1U.cpp:121
ThermoMechanicalFlowProperties calculateThermoMechanicalFlowPropertiesPipe(Pipe const &pipe, double const length, RefrigerantProperties const &fluid, double const flow_rate)
RefrigerantProperties const refrigerant
Definition BHECommon.h:36
FlowAndTemperatureControl const flowAndTemperatureControl
Definition BHECommon.h:38