Variable Grout Properties
The SoilMoisture class updates grout thermal
conductivity, volumetric heat capacity, and density over time as a function
of volumetric water content, to account for irrigation-driven moisture
changes around the borehole.
At each timestep, a water volume balance is tracked around the borehole:
irrigation adds water, while gravity drainage and evaporation remove it.
Drainage loss follows the Brooks-Corey (1964) unsaturated hydraulic
conductivity model, so it depends on the current water content relative to
the soil’s residual and saturated values (theta_r, theta_s) and on
two soil-specific parameters, the saturated hydraulic conductivity Ks
and the pore-size distribution index lambda. Evaporation loss is driven
by the thermal power exchanged with the ground. The resulting water volume
is clipped between the residual and saturated volumes and converted back to
a volumetric water content, which feeds the Chung-Horton/de Vries
correlations for thermal conductivity, heat capacity, and density.
- class carm.properties.SoilMoisture[source]
Bases:
objectSoil moisture and thermophysical properties module.
Computes borehole thermophysical properties (thermal conductivity, specific heat capacity, density) as a function of volumetric water content, using Chung-Horton (1987) for thermal conductivity, de Vries (1963) for volumetric heat capacity, and a mass-weighted average for density.
At each timestep, the water volume stored around the borehole is updated from a water balance: irrigation input increases it, while gravity drainage (Brooks-Corey, 1964, unsaturated hydraulic conductivity) and evaporation (driven by the exchanged thermal power) deplete it. The resulting volume is converted back to a volumetric water content and fed into the property correlations above.
- w_rho
Density of water [kg/m³].
- Type:
float
- w_latent
Latent heat of vaporization of water [J/kg].
- Type:
float
- SOIL_PARAMS
Tabulated parameters for sand, loam, and clay soil types. Each entry contains: b1, b2, b3 (Chung-Horton), theta_s, theta_r (Rawls et al.), xs (solid volume fraction), x0 (organic matter fraction), lambda (Brooks-Corey pore-size distribution index), Ks (saturated hydraulic conductivity [m/s]).
- Type:
dict
- water_input
Water flux time series [m/s].
- Type:
NDArray
- rho_dry
Dry soil density [kg/m³].
- Type:
float
- b1_loc
Chung-Horton parameter b1 for the selected soil type [W/(m K)].
- Type:
float
- b2_loc
Chung-Horton parameter b2 for the selected soil type [W/(m K)].
- Type:
float
- b3_loc
Chung-Horton parameter b3 for the selected soil type [W/(m K)].
- Type:
float
- theta_s_loc
Saturated volumetric water content for the selected soil type [-].
- Type:
float
- theta_r_loc
Residual volumetric water content for the selected soil type [-].
- Type:
float
- xs_loc
Solid volume fraction for the selected soil type [-].
- Type:
float
- x0_loc
Organic matter volume fraction for the selected soil type [-].
- Type:
float
- lambda_loc
Brooks-Corey pore-size distribution index for the selected soil type [-]. Governs how steeply unsaturated hydraulic conductivity (and thus drainage loss) drops as water content decreases.
- Type:
float
- Ks_loc
Saturated hydraulic conductivity for the selected soil type [m/s].
- Type:
float
- Wvol_prev
Water volume at the previous timestep [m³].
Nonebefore the first call to_properties_calculation(), when it is initialized to the residual water volume (theta_r_loc * V).- Type:
float | None
- Wvol_r
Water volume at the current timestep [m³], clipped between the residual (
theta_r_loc * V) and saturated (theta_s_loc * V) volumes.Noneuntil the first call to_properties_calculation().- Type:
float | None
- Wvol_loss
Water volume lost by gravity drainage at the current timestep [m³], computed from the Brooks-Corey unsaturated hydraulic conductivity.
- Type:
float
- Wvol_evap
Water volume lost by evaporation at the current timestep [m³].
- Type:
float
- W_content
Volumetric water content at the current timestep [-].
- Type:
float
- w_rho = 1000.0
- w_latent = 2250000.0
- SOIL_PARAMS = {'clay': {'Ks': 1.6699999999999997e-07, 'b1': -0.197, 'b2': -0.962, 'b3': 2.521, 'lambda': 0.165, 'theta_r': 0.09, 'theta_s': 0.385, 'x0': 0.024, 'xs': 0.591}, 'loam': {'Ks': 3.6699999999999996e-06, 'b1': 0.243, 'b2': 0.393, 'b3': 1.534, 'lambda': 0.252, 'theta_r': 0.027, 'theta_s': 0.434, 'x0': 0.018, 'xs': 0.548}, 'sand': {'Ks': 5.830000000000001e-05, 'b1': 0.228, 'b2': -2.406, 'b3': 4.909, 'lambda': 0.694, 'theta_r': 0.0295, 'theta_s': 0.417, 'x0': 0.012, 'xs': 0.571}}
When to use it
SoilMoisture is only instantiated when water_input is provided in
EnvironmentalTimeSeries. In that case,
D_irrigation and perf_fraction must also be set on
BoreholeGeometry, since they define the irrigation
pipe surface area used in the water balance:
A_irr = pi * borehole.D_irrigation * borehole.perf_fraction * borehole.Lbore
Field-level update
Properties are recomputed once per timestep at the field level, not once per borehole. All boreholes share the same grout composition and receive the same irrigation input; the evaporation term uses the mean heat flux across the field rather than a per-borehole value:
q = np.mean(self.q_nbhes[step - 1])
Sensitivity of the water content to the per-borehole heat flux (as opposed to the field average) was verified to be negligible over the operating range (0–10 kW).
Example
from carm import BoreholeGeometry, BoreholeThermalProperties
geom = BoreholeGeometry(
Lbore=30, D0=0.5,
D_irrigation=0.030, perf_fraction=0.5,
)
thermalprops = BoreholeThermalProperties(
cp_0=796.14, rho_0=1587.09, k0=1.0, soil_type="sand",
)
Note
rho_0 above is the dry soil density, required when water_input
is active. For simulations without irrigation, use the density at
residual water content instead.