API Reference

Material Properties

GeothermalWells.StratifiedMaterialPropertiesType
StratifiedMaterialProperties{N,T}

Thermal properties for stratified rock layers and borehole materials.

Supports N horizontal rock layers with varying properties by depth. Includes material properties for water, steel, insulation, and cement backfill.

Fields

  • k_rock_layers: thermal conductivities for each rock layer [W/(m·K)]
  • rho_c_rock_layers: volumetric heat capacities for each layer [J/(m³·K)]
  • layer_depths: depth boundaries for each layer [m]
  • k_water, rho_c_water: water thermal properties
  • k_steel, rho_c_steel: steel pipe thermal properties
  • k_insulating, rho_c_insulating: insulation thermal properties
  • k_backfill, rho_c_backfill: cement backfill thermal properties
source

Borehole Geometry

GeothermalWells.BoreholeType
Borehole{T}(xc, yc, h, r_inner, t_inner, r_outer, t_outer, r_backfill, ṁ, insulation_depth)

U-shaped coaxial borehole heat exchanger geometry.

Fluid flows down the inner pipe, turns around at depth h, and returns up the outer annulus. Precomputes squared radii and fluid velocities for performance.

Fields

  • xc, yc: horizontal center coordinates [m]
  • h: borehole depth [m]
  • r_inner: inner pipe radius [m]
  • t_inner: inner pipe wall thickness [m]
  • r_outer: outer pipe inner radius [m]
  • t_outer: outer pipe wall thickness [m]
  • r_backfill: cement backfill outer radius [m]
  • : mass flow rate [kg/s]
  • insulation_depth: depth to which inner pipe is insulated [m]
source

Inlet Models

GeothermalWells.HeatExchangerInletType
HeatExchangerInlet{T}(ΔT)

Inlet model applying temperature change ΔT [K] to outlet temperature.

Models a heat exchanger where inlet is T_outlet - ΔT. Typically computed as ΔT = Q / (ṁ * c_water) where Q [W] is heat extraction rate, [kg/s] is mass flow rate, and c_water [J/(kg·K)] is specific heat.

source
GeothermalWells.CustomInletType
CustomInlet{F}(func)

Inlet model with custom function func(bh_idx, T_outlet_values, t).

Allows arbitrary time-varying or borehole-specific inlet temperatures.

source

Grid Generation

GeothermalWells.create_adaptive_grid_1dFunction
create_adaptive_grid_1d(; xmin, xmax, dx_fine, growth_factor, dx_max, boreholes, backend, Float_used, direction)

Generate a non-uniform 1D grid with refined spacing around one or multiple boreholes.

Creates a 1D grid along the specified direction with fine resolution near boreholes and geometrically increasing spacing away from them, up to a maximum cell size. Works for both single borehole and multi-borehole configurations.

Arguments

  • xmin, xmax: Domain boundaries [m]
  • dx_fine: Fine grid spacing near boreholes [m]
  • growth_factor: Geometric growth rate for coarsening (e.g., 1.3)
  • dx_max: Maximum grid spacing [m]
  • boreholes: Single borehole or collection of borehole objects with positions and radii
  • backend: Computation backend (CPU/GPU) for array adaptation
  • Float_used: Floating point type for grid values
  • direction: Grid direction, either :x or :y

Grid generation strategy

For single or multiple boreholes:

  1. Creates fine uniform grids around each borehole (spacing ≈ dx_fine)
  2. Extends from domain boundaries toward boreholes with geometric growth
  3. For multiple boreholes: fills gaps between boreholes symmetrically with progressive coarsening
  4. Ensures all grid points are unique and sorted

Returns

Backend-adapted 1D grid array of the specified floating point type.

source
GeothermalWells.compute_domainFunction
compute_domain(boreholes; buffer_x=100, buffer_y=100, buffer_z=200)

Compute simulation domain bounds from borehole positions.

Returns (xmin, xmax, ymin, ymax, zmin, zmax) encompassing all boreholes with specified buffers [m].

source

Initial Conditions

GeothermalWells.initial_condition_thermal_gradientFunction
initial_condition_thermal_gradient(backend, Float_used, gridx, gridy, gridz; T_surface, gradient)

Create initial temperature field with linear thermal gradient.

Returns 3D array with T(z) = T_surface + gradient * z where T_surface is surface temperature [°C] and gradient is thermal gradient [K/m or °C/m].

source

Simulation

GeothermalWells.create_cacheFunction
create_cache(; backend, gridx, gridy, gridz, materials, boreholes, inlet_model)

Create simulation cache with precomputed data and temporary arrays.

Returns named tuple containing grids, materials, index lists, outlet temperature arrays, eigenvalue estimates, and precomputed Val types for kernel dispatch.

source
GeothermalWells.rhs_diffusion_z!Function
rhs_diffusion_z!(dϕ, ϕ, cache, t)

Compute right-hand side for vertical (z-direction) heat diffusion.

This is the RHS function passed to OrdinaryDiffEq.jl and is integrated using an explicit stabilized ROCK method. Vertical diffusion is treated separately from horizontal (x,y) diffusion because the ADI scheme is only unconditionally stable in 2D. Since Δz is much larger than the smallest Δx and Δy (due to the fine grid resolution needed near the borehole), the explicit ROCK method is sufficient for the z-direction without imposing prohibitive time step restrictions.

Horizontal diffusion via the ADI method and advection are handled separately using the callback functionality (ADI_and_ADV_callback!)—a workaround to implement operator splitting within the OrdinaryDiffEq.jl framework.

source
GeothermalWells.get_simulation_callbackFunction
get_simulation_callback(; saveat, print_every_n=1000, write_to_jld=false, data_folder_dir="")

Create the required callback set for the simulation.

Required

This callback is essential for the simulation. It performs the ADI (Alternating Direction Implicit) method for horizontal diffusion and the semi-Lagrangian advection. Without this callback, only vertical diffusion (handled by ROCK2) is computed.

The callback combines three components:

  1. ADI + Advection: Horizontal diffusion and fluid advection (runs every timestep)
  2. Progress printing: Prints simulation progress every print_every_n steps
  3. Solution saving: Saves temperature field at times specified by saveat

Arguments

  • saveat: Times at which to save the solution (e.g., range(0, 3600, 10) or [0.0, 3600.0])
  • print_every_n=1000: Print progress every N accepted timesteps
  • write_to_jld=false: If true, also write checkpoints to JLD2 files
  • data_folder_dir="": Directory for JLD2 checkpoint files (required if write_to_jld=true)

Returns

  • callback: Combined CallbackSet to pass to solve(..., callback=callback)
  • saved_values: SavedValues object containing saved solutions accessible via saved_values.saveval

Example

callback, saved_values = get_simulation_callback(
    saveat=[0.0, 3600.0, 7200.0],
    print_every_n=100
)
solve(prob, ROCK2(eigen_est=eigen_estimator), callback=callback, dt=80.0, adaptive=false)

# Access saved solutions
T_final = saved_values.saveval[end]
source

Utilities

GeothermalWells.plot_gridFunction
plot_grid(gridx, gridy; boreholes=nothing, xlims=nothing, ylims=nothing, ...)

Visualize the computational grid in the x-y plane.

Plots grid lines and optionally overlays borehole geometry (inner pipe, outer pipe, backfill boundaries). Useful for verifying grid resolution near boreholes.

Arguments

  • gridx: Grid coordinates in x-direction
  • gridy: Grid coordinates in y-direction
  • boreholes=nothing: Tuple of Borehole objects to overlay
  • xlims=nothing: x-axis limits (auto-determined if not provided)
  • ylims=nothing: y-axis limits (auto-determined if not provided)
  • size=(800, 800): Figure size in pixels
  • annotate=true: Add text labels to borehole components
  • legend=:bottomleft: Legend position

Returns

A Plots.jl plot object.

source

Validation Data

Functions for loading reference data from published studies:

GeothermalWells.data_liFunction
data_li(i) -> x_data, T_data

Load Li et al. validation data (Figure 5).

i=1,2,3,4 for 500m, 1000m, 1500m, 2000m depths respectively. From: Heat extraction model and characteristics of coaxial deep borehole heat exchanger

source
GeothermalWells.data_huFunction
data_hu(years::Int) -> depth, temperature

Load Hu et al. validation data for specified simulation years (Figure 7).

From: Numerical modeling of a coaxial borehole heat exchanger (doi:10.1016/j.renene.2019.09.141) Returns depth [m] and temperature [°C].

source
GeothermalWells.data_brown_single_well_bFunction
data_brown_single_well_b() -> (z_beier, T_beier), (z_brown, T_brown)

Load Brown et al. single well validation data (Figure 4b).

From: Investigating scalability of deep borehole heat exchangers (doi:10.1016/j.renene.2021.01.036) Returns depth [m] and temperature [°C] profiles for Beier and Brown models.

source
GeothermalWells.data_brown_single_well_cFunction
data_brown_single_well_c(i) -> x_data, T_data

Load Brown et al. single well validation data (Figure 4c).

i=1,2,3 for 300m, 600m, 920m depths respectively. From: doi:10.1016/j.renene.2021.01.036

source