Skip to content

Performing a BHE Simulation Using Geoloop

The configuration of a simulation is defined through JSON input files (*.json), organized in a json directory (e.g. /examples/simple_simulation).

One Geoloop simulation uses different modules from various packages, depending on the configuration defined in the main input JSON file.
This main input JSON file defines the physical and operational design of the simulated Borehole Heat Exchanger (BHE) system, and may include links to additional input JSON files for:

  • Configuration of a borehole field simulation
  • Configuration for a stochastic simulation
  • Configuration of an optimization simulation
  • Configuration of depth-dependent subsurface thermal properties
  • Configuration of a power load time-profile
  • Configuration of a flow rate time-profile

The following sections provide a nomenclature for the input for the different simulation types and modules, including model configuration conditions and options.


Configuration Files and Path Resolution

This section explains how configuration files are interpreted by Geoloop, how relative paths are resolved, how nested configuration files behave, and which model-specific validation rules apply. Understanding these rules is essential when writing configuration JSON files for single runs, batch runs, and stochastic simulations.

General Rules for All Configurations

All configuration models (LithologyConfig, LoadProfileConfig, FlowDataConfig, SingleRunConfig, PlotInputConfig) follow the same core pattern:

  1. Every loaded config JSON is assigned a config_file_path, pointing to the absolute path of the file that defined it.

  2. Any relative path in the configuration is always interpreted relative to the folder containing that configuration file.

  3. Output directories are created automatically if they do not exist.

  4. Certain models have type-dependent rules (e.g. borehole type, model type), and validation errors are raised if required fields are missing.

How Path Resolution Works

When a configuration file at:

/path/to/config/run.json

contains:

{
    "input_dir": "input",
    "out_dir": "output"
}

Geoloop resolves these as:

  • input_dir/path/to/config/input/
  • out_dir/path/to/config/output/

If a linked path is already absolute, it is left unchanged.

Any directory that corresponds to an output location is created if missing.

Linked Configuration JSONs

A main configuration file can reference sub-configs like:

{
    "borefield": "borehole_field.json",
    "loadprofile": "heat_load.json"
}

When running a simulation, those paths are resolved relative to the main configuration file.

Best Practices When Creating Config Files

  • Always provide paths relative to the config file’s directory.
  • Keep related configs (lithology, heat load profile, flow rate profile) in the same folder.
  • Avoid absolute paths for portability.
  • For batch simulations, place all configs in one structured directory.
  • Remember: paths inside nested configs are resolved using their own file location, not the main config.

Configuration of a Single BHE Simulation

The main input JSON file is directly used for a deterministic simulation by the SingleRunSim module or the single-run command in the CLI (see Geoloop Interface).
For an example of a simple deterministic model simulation, see the example of a simple model simulation.

The main input JSON file includes the following parameters:

Parameter Description Unit Type Remark
base_dir Path to output folder string Creates folder if it does not exist
type Type of BHE design string Options: UTUBE or COAXIAL for model_type ANALYTICAL and PYG and PYGFIELD; UTUBE for model_type FINVOL
H Borehole length m scalar
D Buried depth of the BHE m scalar
borefield Path to configuration file for borehole field design string Optional; only used for model_type PYGFIELD
r_b Borehole radius m scalar
pos Positions of pipes in borehole nested_list [x;y]* coordinates of pipes; first position(s) are of inlet pipe(s); required if type is UTUBE, falls back to default of [[0,0][0,0]] if type is COAXIAL
r_out Outer pipe radius m list First position(s) are of inlet pipe(s), Radii must be the same for inlet and outlet pipes respectively.
r_in Inner pipe radius m list Only used if SDR is not provided. First position(s) are of inlet pipe(s), Radii must be the same for inlet and outlet pipes respectively.
SDR SDR value of the pipes scalar Only used if r_in is not provided. Determines pipe thickness through: thickness = (r_out*2) / SDR.
k_p Pipe thermal conductivity W/mK scalar
nInlets Number of inlet pipes scalar Required if type is UTUBE, falls back to default of 1 if type is COAXIAL
insu_dr Fraction of pipe thickness with insulating material scalar Range: 0–1
insu_k Thermal conductivity of insulating material W/mK scalar
insu_z Maximum depth of insulating material m scalar
k_g Grout thermal conductivity W/mK scalar or list
z_k_g End depths of k_g values m list Used only if k_g is a list
epsilon Pipe surface roughness m scalar
fluid_str Type of fluid mixed with water string Must be supported by pygfunction media module
fluid_percent Fluid percentage % scalar
m_flow Total flow rate kg/s scalar The total flow into the system is is equally divided between the sets of inlet and outlet pipes, with a negative value for the outlet flow. Used if dploopcrit and flow_data are not defined.
litho_k_param Path to lithology module configuration file string Optional
Tg (Sub)surface temperature °C scalar or list Represents surface temperature if scalar
Tgrad Subsurface temperature gradient °C/100m scalar Used only if Tg is scalar
z_Tg End depths of Tg values m list Used only if Tg is a list
k_s Subsurface thermal conductivity W/mK scalar or list Used only if litho_k_param is not defined
z_k_s End depths of k_s values m list Used only if k_s is a list and litho_k_param is not defined
k_s_scale Scaling factor for subsurface thermal conductivity scalar Scales k_s values over depth
alfa Subsurface thermal diffusivity m²/s scalar
model_type Type of model used in simulation string Options: ANALYTICAL; FINVOL; PYG; PYGFIELD
run_type Starting point for performance calculation string Options: POWER or TIN (depends on model_type)
nyear Number of simulated years year scalar
nled Number of hours per simulated timestep hour scalar
nsegments Number of model segments over depth scalar
nr Number of grid cells in radial direction scalar Required only if model_type is FINVOL
r_sim Maximum simulation radius m scalar Required only if model_type is FINVOL
dploopcrit Pumping power bar scalar
dooptimize Enable optimization boolean true or false
copcrit Minimum COP of circulation pump scalar Used only if dooptimize is true
optimize_keys Parameters to optimize list Only variable parameters supported
optimize_keys_bounds Bounds for optimized parameters nested_list [[lower, upper]] matching optimize_keys
loadprofile Path to configuration file of the heat load profile string Optional
flow_data Path to configuration file of the flow rate profile - string Optional
Q Power demand W scalar Used if run_type is POWER and no loadprofile defined; positive for heat production, negative for cold production
Tin Inlet temperature °C scalar Used if run_type is TIN
variables_config Path to stochastic simulation configuration file string Used for stochastic runs (RunMain module)
save_Tfield_res Flag to save results of 3D temperature field in a numarical simulation boolean Only used if model_type is FINVOL

The pos parameter includes:

Parameter Unit Description
x m Position along x-axis
y m Position along y-axis

To maintain a constant borehole wall temperature for each depth slice (UBWT boundary condition, see Theory),
inlet and outlet pipes in a multi-U-tube configuration should alternate and be radially symmetric.

By default, Geoloop uses a fixed surface temperature with a linear subsurface thermal gradient, as defined by scalar values for the input parameters Tg and Tgrad in the main input JSON.

However, a pre-defined temperature–depth profile can be used in the simulations, by assigning:

  • a list of temperature values to Tg
  • a corresponding list of depth values to z_Tg.

These parameters should be defined similarly in the configuration JSON of the lithology module, if used (see below).

For an example simulation using a temperature–depth profile, see a BHE in the city of Roermond

base_dir is the main output folder for the simulation. It is resolved relative to the directory where the main configuration JSON is located. When an absolute path is provided, it is unchanged.

Extra Configuration of a Borehole Field

For simulating a field of boreholes, define a separate JSON file for the borehole field design. A field of boreholes can only be simulated when using the standard functionality of pygfunction (when model_type is PYGFIELD) This file is linked in the main JSON under borefield and includes:

Parameter Description Unit Type Remark
field_N Total number of boreholes int
field_M Boreholes per side of the field int Only equally sided fields supported
field_R Distance between boreholes m int Distance between boreholes. If field_M is 0, defines radius of circular field
field_segments Number of depth segments int More segments = smoother curved trajectory
field_inclination_start Start inclination angle ° int Applied to all boreholes
field_inclination_end End inclination angle ° int Applied to all boreholes

If the start and end inclinations differ, boreholes will have a curved shape.

For examples see:

Values in borefield override or supply missing values. This is different for a linked configuration JSON of, for example, the Loadprofile module, which uses a nested dictionary.


Configuration of a Stochastic and/or Optimization Simulation

For a stochastic simulation, the main input JSON is used by the RunMain module in the stochastic-run command in the CLI (see Geoloop Interface). For an example of a simple stochastic simulation see simple model simulation. A separate JSON defines parameters for Monte Carlo sampling, linked under variables_config:

Parameter Description Unit Type
n_samples Number of samples scalar
variable parameter [sampling mode; arg1; arg2] list[string, scalar, scalar]

Multiple variable parameters can be defined simultaneously and the user can choose different sampling distributions.
Supported parameters include:

  • k_s_scale
  • k_p
  • insu_z
  • insu_dr
  • insu_k
  • m_flow
  • Tin
  • H
  • epsilon
  • alfa
  • Tgrad
  • Q
  • fluid_percent

Supported sampling distributions and their corresponding arguments for the configuration JSON are:

Sampling Mode arg1 arg2
Normal mean standard deviation
Uniform minimum maximum
Lognormal μ σ
Triangular minimum peak

The main input JSON file for a Geoloop simulation already includes several arguments that define the preferences for an optimization simulation, including sampling type and value range for parameter iteration. However, in case of using the optimization algorithm for optimization of the BHE design and/or operational conditions, the sampling type and value range for parameter iteration should also be defined in the same input JSON file as is used for a stochastic simulation, under variables_config.

Geoloop supports optimization of the same parameters as listed above for options to vary in stochastic model runs. For an example of a simple optimization simulation, see the example for Optimization of a coaxial BHE

The coaxial BHE design circulates fluid downwards in the outer pipe and upwards in the inner pipe. Optimization of the pipe radius for this design is only supported for the inner pipe.


Simulation results

After a simulation is finished, most input parameters and the results are stored in a HDF5 (.h5) file. The file contains a subset of parameters that includes (most of) the input parameters of the main input JSON file, and results that follow from the model calculations.

The table below defines the parameters in the results subset and describes its structure. For stochastic simulations, the first dimension of the parameters in the results subset is always the number of samples.

Parameter Description Unit Dimensions Remark
Q_b Heat load W time Only calculated for run_type TIN
Re_in Reynolds nr. in the inlet pipe(s) time
Re_out Reynolds nr. in the outlet pipe(s) time
T_b Borehole wall temperature C time; zseg
T_bave Depth-average borehole wall temperature C time
T_f Fluid temperature C time; z; nPipes
T_fi Inlet temperature C time Only calculated for run_type POWER
T_fo Outlet temperature C time
Tg (Sub)surface temperature C time or time; zseg
dploop Pumping pressure bar time
flowrate Flowrate kg/s time Total flow rate
hours Simulation timesteps hours time
k_g Grout thermal conductivity W/mK time or time; zseg
k_s Subsurface thermal conductivity W/mK time or time; zseg
qloop Consumed power by the fluid circulation pump W time
qsign Sign of heat flow time Sign indicates heat extraction (positive) or injection (negative)
qzb Subsurface heat flow W time; zseg
nPipes Number of pipes Coördinates for the nPipes dimension
time Simulation timesteps hours Coördinates for the time dimension
z Depth for top and bottom of simulation depth segments m Coördinates for the depth dimension
zseg Depth for middle of simulation depth segments m Coördinates for the depth-segment dimension

In addition to the database file, a plot is generated from a cross-section of the borehole design. Both are stored according to the following convention:

📁 /jsondir/base_dir/casename/ — HDF5 database file (.h5) with simulation inputs and results
🖼️ /jsondir/base_dir/casename/casename_bhdesign.png — Cross-section figure of the borehole design

The casename in the output files follows the pattern run_name + A/P/F + '_' + T/P, with:

Symbol Meaning
run_name Name of the input JSON file used by the scripts SingleRunSim or RunMain
A/P/F Semi-analytical (A) model from Geoloop, semi-analytical model from pygfunction (P), or Finite Volume model (F)
T/P Main input condition type: T (temperature) or P (power/heat load)

BHE simulations that use the numerical finite volume model, in case the save_Tfield_res was flagged to True, also produce a separate HDF5 database file with the calculated subsurface temperature field in:

📁 /jsondir/base_dir/casename/casename_FINVOL_T.h5