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