|
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | import warnings |
3 | 3 | from time import perf_counter |
| 4 | +from typing import Union, List |
4 | 5 |
|
5 | 6 | import numpy as np |
| 7 | +import numpy.typing as npt |
6 | 8 | from scipy.interpolate import interp1d as interp1d |
7 | 9 |
|
8 | 10 | from .borefield import Borefield |
9 | 11 | from .boreholes import Borehole, find_duplicates |
| 12 | +from .media import Fluid |
10 | 13 | from .networks import Network |
11 | 14 | from .solvers import ( |
12 | 15 | Detailed, |
13 | 16 | Equivalent, |
14 | 17 | Similarities |
15 | | - ) |
| 18 | +) |
16 | 19 | from .utilities import ( |
17 | 20 | segment_ratios, |
18 | 21 | _initialize_figure, |
19 | 22 | _format_axes |
20 | | - ) |
| 23 | +) |
21 | 24 |
|
22 | 25 |
|
23 | 26 | class gFunction(object): |
@@ -282,6 +285,170 @@ def __init__(self, boreholes_or_network, alpha, time=None, |
282 | 285 | if self.time is not None: |
283 | 286 | self.gFunc = self.evaluate_g_function(self.time) |
284 | 287 |
|
| 288 | + @classmethod |
| 289 | + def from_static_params(cls, |
| 290 | + H: npt.ArrayLike, |
| 291 | + D: npt.ArrayLike, |
| 292 | + r_b: npt.ArrayLike, |
| 293 | + x: npt.ArrayLike, |
| 294 | + y: npt.ArrayLike, |
| 295 | + alpha: float, |
| 296 | + time: npt.ArrayLike = None, |
| 297 | + method: str = 'equivalent', |
| 298 | + m_flow_network: float = None, |
| 299 | + options={}, |
| 300 | + tilt: npt.ArrayLike = 0., |
| 301 | + orientation: npt.ArrayLike = 0., |
| 302 | + boundary_condition: str = 'MIFT', |
| 303 | + pipe_type_str: str = None, |
| 304 | + pos: List[tuple] = None, |
| 305 | + r_in: Union[float, tuple, npt.ArrayLike] = None, |
| 306 | + r_out: Union[float, tuple, npt.ArrayLike] = None, |
| 307 | + k_s: float = None, |
| 308 | + k_g: float = None, |
| 309 | + k_p: Union[float, tuple, npt.ArrayLike] = None, |
| 310 | + fluid_str: str = None, |
| 311 | + fluid_concentration_pct: float = None, |
| 312 | + fluid_temperature: float = 20, |
| 313 | + epsilon: float = None, |
| 314 | + reversible_flow: bool = True, |
| 315 | + bore_connectivity: list = None, |
| 316 | + J: int = 2, |
| 317 | + ): |
| 318 | + |
| 319 | + """ |
| 320 | + Constructs the 'gFunction' class from static parameters. |
| 321 | +
|
| 322 | + Parameters |
| 323 | + ---------- |
| 324 | + H : float or (nBoreholes,) array |
| 325 | + Borehole lengths (in meters). |
| 326 | + D : float or (nBoreholes,) array |
| 327 | + Borehole buried depths (in meters). |
| 328 | + r_b : float or (nBoreholes,) array |
| 329 | + Borehole radii (in meters). |
| 330 | + x : float or (nBoreholes,) array |
| 331 | + Position (in meters) of the head of the boreholes along the x-axis. |
| 332 | + y : float or (nBoreholes,) array |
| 333 | + Position (in meters) of the head of the boreholes along the y-axis. |
| 334 | + alpha : float |
| 335 | + Soil thermal diffusivity (in m2/s). |
| 336 | + time : float or array, optional |
| 337 | + Values of time (in seconds) for which the g-function is evaluated. The |
| 338 | + g-function is only evaluated at initialization if a value is provided. |
| 339 | + Default is None. |
| 340 | + method : str, optional |
| 341 | + Method for the evaluation of the g-function. Should be one of 'similarities', 'detailed', or 'equivalent'. |
| 342 | + Default is 'equivalent'. See 'gFunction' __init__ for more details. |
| 343 | + m_flow_network : float, optional |
| 344 | + Fluid mass flow rate into the network of boreholes (in kg/s). |
| 345 | + Default is None. |
| 346 | + options : dict, optional |
| 347 | + A dictionary of solver options. See 'gFunction' __init__ for more details. |
| 348 | + tilt : float or (nBoreholes,) array, optional |
| 349 | + Angle (in radians) from vertical of the axis of the boreholes. |
| 350 | + Default is 0. |
| 351 | + orientation : float or (nBoreholes,) array, optional |
| 352 | + Direction (in radians) of the tilt of the boreholes. Defaults to zero |
| 353 | + if the borehole is vertical. |
| 354 | + Default is 0. |
| 355 | + boundary_condition : str, optional |
| 356 | + Boundary condition for the evaluation of the g-function. Should be one of 'UHTR', 'UBWT', or 'MIFT'. |
| 357 | + Default is 'MIFT'. |
| 358 | + pipe_type_str : str, optional |
| 359 | + Pipe type used for 'MIFT' boundary condition. Should be one of 'COAXIAL_ANNULAR_IN', 'COAXIAL_ANNULAR_OUT', |
| 360 | + 'DOUBLE_UTUBE_PARALLEL', 'DOUBLE_UTUBE_SERIES', or 'SINGLE_UTUBE'. |
| 361 | + pos : list of tuples, optional |
| 362 | + Position (x, y) (in meters) of the pipes inside the borehole. |
| 363 | + r_in : float, optional |
| 364 | + Inner radius (in meters) of the U-Tube pipes. |
| 365 | + r_out : float, optional |
| 366 | + Outer radius (in meters) of the U-Tube pipes. |
| 367 | + k_s : float, optional |
| 368 | + Soil thermal conductivity (in W/m-K). |
| 369 | + k_g : float, optional |
| 370 | + Grout thermal conductivity (in W/m-K). |
| 371 | + k_p : float, optional |
| 372 | + Pipe thermal conductivity (in W/m-K). |
| 373 | + fluid_str: str, optional |
| 374 | + The mixer for this application should be one of: |
| 375 | + - 'Water' - Complete water solution |
| 376 | + - 'MEG' - Ethylene glycol mixed with water |
| 377 | + - 'MPG' - Propylene glycol mixed with water |
| 378 | + - 'MEA' - Ethanol mixed with water |
| 379 | + - 'MMA' - Methanol mixed with water |
| 380 | + fluid_concentration_pct: float, optional |
| 381 | + Mass fraction of the mixing fluid added to water (in %). |
| 382 | + Lower bound = 0. Upper bound is dependent on the mixture. |
| 383 | + fluid_temperature: float, optional |
| 384 | + Temperature used for evaluating fluid properties (in degC). |
| 385 | + Default is 20. |
| 386 | + epsilon : float, optional |
| 387 | + Pipe roughness (in meters). |
| 388 | + reversible_flow : bool, optional |
| 389 | + True to treat a negative mass flow rate as the reversal of flow |
| 390 | + direction within the borehole. If False, the direction of flow is not |
| 391 | + reversed when the mass flow rate is negative, and the absolute value is |
| 392 | + used for calculations. |
| 393 | + Default True. |
| 394 | + bore_connectivity : list, optional |
| 395 | + Index of fluid inlet into each borehole. -1 corresponds to a borehole |
| 396 | + connected to the bore field inlet. If this parameter is not provided, |
| 397 | + parallel connections between boreholes is used. |
| 398 | + Default is None. |
| 399 | + J : int, optional |
| 400 | + Number of multipoles per pipe to evaluate the thermal resistances. |
| 401 | + J=1 or J=2 usually gives sufficient accuracy. J=0 corresponds to the |
| 402 | + line source approximation. |
| 403 | + Default is 2. |
| 404 | +
|
| 405 | + Returns |
| 406 | + ------- |
| 407 | + gFunction : 'gFunction' object |
| 408 | + The g-function. |
| 409 | +
|
| 410 | + Notes |
| 411 | + ----- |
| 412 | + - When using the 'MIFT' boundary condition, the parameters `pipe_type_str`, |
| 413 | + `fluid_str`, `fluid_concentration_pct`, `fluid_temperature`, and |
| 414 | + `epsilon` are required. |
| 415 | +
|
| 416 | + """ |
| 417 | + |
| 418 | + if boundary_condition.upper() not in ['UBWT', 'UHTR', 'MIFT']: |
| 419 | + raise ValueError(f"'{boundary_condition}' is not a valid boundary condition.") |
| 420 | + |
| 421 | + # construct all required pieces |
| 422 | + borefield = Borefield(H, D, r_b, x, y, tilt, orientation) |
| 423 | + |
| 424 | + if boundary_condition.upper() == 'MIFT': |
| 425 | + boreholes = borefield.to_boreholes() |
| 426 | + cp_f = Fluid(fluid_str, fluid_concentration_pct).cp |
| 427 | + boreholes_or_network= Network.from_static_params( |
| 428 | + boreholes, |
| 429 | + pipe_type_str, |
| 430 | + pos, |
| 431 | + r_in, |
| 432 | + r_out, |
| 433 | + k_s, |
| 434 | + k_g, |
| 435 | + k_p, |
| 436 | + m_flow_network, |
| 437 | + epsilon, |
| 438 | + fluid_str, |
| 439 | + fluid_concentration_pct, |
| 440 | + fluid_temperature, |
| 441 | + reversible_flow, |
| 442 | + bore_connectivity, |
| 443 | + J, |
| 444 | + ) |
| 445 | + else: |
| 446 | + boreholes_or_network = borefield |
| 447 | + cp_f = None |
| 448 | + |
| 449 | + return cls(boreholes_or_network, alpha, time=time, method=method, boundary_condition=boundary_condition, |
| 450 | + m_flow_network=m_flow_network, cp_f=cp_f, options=options) |
| 451 | + |
285 | 452 | def evaluate_g_function(self, time): |
286 | 453 | """ |
287 | 454 | Evaluate the g-function. |
@@ -520,7 +687,7 @@ def visualize_heat_extraction_rates( |
520 | 687 |
|
521 | 688 | # Adjust figure to window |
522 | 689 | plt.tight_layout() |
523 | | - |
| 690 | + |
524 | 691 | return fig |
525 | 692 |
|
526 | 693 | def visualize_heat_extraction_rate_profiles( |
|
0 commit comments