Skip to content

Soil Water#

The soil-water model computes the water content of the soil, the ponds and the overland flow on a grid of 4 m cells. The tyre-soil model reads the result at each wheel contact, and the wheels change the soil in return.

Scope and Assumptions#

The model is the class AcresFarm::WaterGrid in AcresFarmModel.cpp. It is an engine-free model. The class FAcresFarmRuntime in AcresFarmRuntime.cpp loads the data, runs the grid on the water thread and answers the queries of the vehicles.

Water balance of one 4 m grid cell: rain fills the pond, the pond infiltrates into the surface layer, the surface layer drains into the subsoil, the subsoil drains by deep percolation and tile drains, the pond flows to the neighbour cells, and the tyre-soil model reads the result. Water balance of one grid cell (4 m) Weather model rain rate, potential evaporation rain evaporation Pond h Surface layer, 0.3 m water content θ wetting front Subsoil, 1.2 m water content θ₂ infiltration redistribution above field capacity deep percolation, limit of the drainage class Neighbour pond Manning flow of the water above the detention depth Neighbour pond Free outflow at the grid edge Wheel stamp rut depth, compaction Compaction lowers Ks. Ruts add pond storage. soils.json SSURGO unit of the cell: Ks, ψ, θs, θfc, θwp snapshot Tyre-soil model θ, wetness and pond depth at each wheel contact Tile drain 9.525 mm/day, drained fields
The water balance of one grid cell: the vertical fluxes, the flow to the neighbour cells and the link to the tyre-soil model. Open the diagram
  • Each cell is a soil column with two layers: a surface layer and a subsoil.
  • The rain rate and the potential evaporation are the same for all cells. They come from the weather model.
  • The model has no channels, no erosion, no groundwater table, no lateral flow in the soil and no frozen soil.
  • The soil units and their properties are survey data (SSURGO). No value is a measurement at ACRE.
  • Plants do not take water from the soil. The evaporation is the only loss to the air.
  • ACRES Core does not step the water grid. It holds a constant water content for each field during an episode.

Symbols#

Symbol Quantity Unit
\(\Delta x\) Cell size m
\(\Delta t\) Step of the grid s
\(z\) Bed elevation of a cell m
\(h\) Pond depth m
\(\eta\) Elevation of the water surface, \(z + h\) m
\(\theta, \theta_2\) Water content of the surface layer and of the subsoil m³/m³
\(\theta_0, \theta_{2,0}\) Water contents at the start m³/m³
\(\theta_s, \theta_{fc}, \theta_{wp}, \theta_r\) Water content at saturation, at field capacity, at the wilting point, and the residual value m³/m³
\(d_1, d_2\) Thickness of the surface layer and of the subsoil m
\(K_s\) Saturated conductivity of the open surface m/s
\(K_{seal}\) Conductivity of a sealed surface m/s
\(\psi\) Suction at the wetting front m
\(F\) Water that the column took in from the start m
\(c\) Wheel compaction 0 to 1
\(q_p, q_t\) Limit of the deep percolation and of the tile drain m/s
\(n_M\) Manning roughness s/m^(1/3)
\(d_c\) Detention depth m
\(v\) Flow velocity m/s
\(Q\) Volume that moves between two cells in a substep m³
\(r\) Rut depth m

The configuration files use mm/h and mm/day. The code converts them to m/s.

Grid and Data#

Grid Cell Size Content
Water grid 4 m 382 × 382 cells Water state, field number, land cover.
Survey grid 1.524 m 1001 × 1001 nodes Terrain heights, soil unit of each cell.
Rut map 0.25 m Sparse Rut depth. See Compaction and Ruts.

The water grid and the survey grid start at the same corner, at −762.0015 m on both axes. The coordinates are metres in the Unreal frame: X is east and Y is south. The index of a cell is \(i = v\,W + u\) with the row \(v\) along Y.

File Content
farm.json The block hydrology with the parameters of this model.
ACRE/field-grid.json Width, cell size and origin of the water grid.
ACRE/field_ids.u8 The field number of each 4 m cell: 1 to 59, or 0.
ACRE/cover.u8 The cover code of each 4 m cell. See Crops and Ground Classes.
ACRE/soils.json The 16 SSURGO soil units and their properties.
ACRE/soil_units.u8 The index of the soil unit of each survey cell.
ACRE/heights.f32 The terrain heights at the survey nodes.

All files are in the folder Acres/Content/Simulation.

FAcresFarmRuntime::Initialize builds each cell from the point at its centre.

  1. The bed elevation is the survey height plus the terrain edit of the field setup.
  2. The soil unit is the unit of the survey cell that contains the centre.
  3. A cell with the cover asphalt or concrete gets the pavement unit. A cell with the cover gravel gets the gravel unit.
  4. A field cell on a soil with a drained class gets the copy of its unit with a tile drain.
  5. A cell of a field with a soil override gets the unit of that field. Pavement and gravel cells keep their unit.

Soil Units#

Each soil unit is one AcresFarm::WaterUnit. soils.json gives these values for the SSURGO units of the tile. All units have a surface layer of 0.3 m and a subsoil of 1.2 m. The columns Open and Sealed are the conductivities \(K_s\) and \(K_{seal}\) in mm/h. The suction \(\psi\) is in m. The water contents \(\theta_s\), \(\theta_{fc}\) and \(\theta_{wp}\) are in m³/m³.

Index Symbol Soil Drainage Open Sealed Suction Saturation Field Capacity Wilting Point
1 RcA Raub-Brenton complex SP 33.0 3.4 0.167 0.419 0.312 0.172
2 CwB2 Crosby-Miami silt loams SP 33.0 3.4 0.167 0.437 0.281 0.130
3 SwA Starks-Fincastle complex SP 33.0 3.4 0.167 0.415 0.279 0.127
4 RdB2 Richardville silt loam W 33.0 3.4 0.167 0.412 0.288 0.144
5 RoB Rockfield silt loam MW 33.0 3.4 0.167 0.418 0.308 0.165
6 TmA Toronto-Millbrook complex SP 33.0 3.4 0.167 0.418 0.297 0.151
7 Pg Pella silty clay loam P 33.0 1.0 0.273 0.430 0.349 0.235
8 RdC2 Richardville silt loam W 33.0 3.4 0.167 0.412 0.288 0.144
9 Cm Chalmers silty clay loam P 33.0 1.0 0.273 0.430 0.345 0.229
10 Mu Milford silty clay loam VP 21.4 1.0 0.273 0.430 0.356 0.250
11 Ua Udorthents, loamy MW 3.4 3.4 0.167 0.470 0.300 0.120
12 Md Mahalasville-Treaty complex P 33.0 1.0 0.273 0.428 0.342 0.223
13 Pk Peotone silty clay loam VP 9.4 1.0 0.273 0.420 0.362 0.262
14 TfB Throckmorton silt loam MW 33.0 3.4 0.167 0.418 0.301 0.155
15 MsD2 Miami silt loam W 33.0 3.4 0.167 0.413 0.287 0.142
16 MsC2 Miami silt loam MW 33.0 3.4 0.167 0.426 0.296 0.149

The drainage codes are the NRCS classes Well drained (W), Moderately well drained (MW), Somewhat poorly drained (SP), Poorly drained (P) and Very poorly drained (VP). The water contents in the table are those of the surface layer. The file also gives the three values of the subsoil. \(\psi\) and \(K_{seal}\) are means of the texture class from Rawls, Brakensiek and Miller (1983) and Rawls, Brakensiek and Saxton (1982).

The runtime makes a table of water units from these 16 units. With \(K = 17\):

Index Unit
0 A copy of the unit with the most cells (Chalmers, index 9). It applies where the survey has no soil unit.
1 to \(K - 1\) The SSURGO units.
\(K\) to \(2K - 1\) The same units with a tile drain: \(q_t\) = tile_drainage_mm_day.
\(2K\) Pavement: no infiltration, no soil store, \(\theta = 0\).
\(2K + 1\) Gravel.
\(2K + 2\) and more One unit for each field with a soil override.

For each SSURGO unit, \(\theta_r\) is the smaller of residual_theta and \(0.5\,\theta_{wp}\). The unit also gets the exponent vg_n and the percolation limit of its drainage class. The gravel unit has \(K_s\) = 5 mm/h and \(d_1\) = 0.3 m from farm.json. Its other values are constants in the code.

Value of the Gravel Unit Surface Layer Subsoil
Thickness 0.3 m 0.5 m
Water content at saturation 0.35 0.37
Water content at field capacity 0.12 0.30
Water content at the wilting point 0.04 0.17
Residual water content 0.02
Suction at the wetting front 0.05 m
Limit of the deep percolation 1.5 mm/h

A field with a soil override gets a copy of the unit below the centre of the field. The copy keeps the depths and the percolation limit. The preset or the custom values replace \(K_s\), \(K_{seal}\), \(\psi\), \(\theta_s\), \(\theta_{fc}\) and \(\theta_{wp}\) of both layers. The copy always has a tile drain. Crops and Ground Classes gives the presets and the limits of the custom values.

Initial Water Content#

Each layer starts at a fraction \(f\) of the range between the wilting point and the field capacity. \(f\) is initial_fraction_between_wilting_and_field_capacity or the option -FarmInitialTheta=.

\[ \theta_0 = \theta_{wp} + f\,(\theta_{fc} - \theta_{wp}), \qquad \theta_{2,0} = \theta_{wp,2} + f\,(\theta_{fc,2} - \theta_{wp,2}) \]

A field can have its own wetness \(w\) for the surface layer. Values above 1 go from the field capacity to saturation.

\[ \theta_0 = \begin{cases} \theta_{wp} + w\,(\theta_{fc} - \theta_{wp}) & w \le 1 \\ \theta_{fc} + (w - 1)\,(\theta_s - \theta_{fc}) & w > 1 \end{cases} \]

The subsoil always uses \(f\). A pavement cell starts at 0. A gravel cell starts at its field capacity. \(\theta_0\) is also the reference of the wetness that the tyres read.

The table shows all the ways to set the water content of the soil.

Method Scale Effect
Menu, tab Fields, column Start Wetness 0 wilting point, 1 field capacity, 1.3 maximum The wetness \(w\) of one field.
-FieldSetup=<folder> 0 wilting point, 1 field capacity, 2 saturation The wetness \(w\) of each field in field-setup.json.
-FarmInitialTheta= 0 wilting point, 1 field capacity The fraction \(f\) of all cells and both layers.
rain.prior_mm, rain.prior_hours mm, h The grid runs this rain at a constant rate before the session starts.
-FarmPreDays= days, 0 to 366 The grid runs this time with the start weather before the session starts.
-FarmLoad=<file> Loads the water state of a saved session.
acres/set_conditions, part soil_water 0 wilting point, 1 saturation Sets \(\theta\) of the fields during the session.

The service acres/set_conditions uses a different scale. FAcresFarmRuntime::SetSoilWetness applies it to the surface layer of the soil cells of the fields.

\[ \theta = \theta_{wp} + w_c\,(\theta_s - \theta_{wp}), \qquad 0 \le w_c \le 1 \]

An empty field list selects all 59 fields. The function does not change \(\theta_0\) and the subsoil. Set Soil and Weather shows each method.

Step of the Grid#

WaterGrid::Step advances the full grid by \(\Delta t\). The runtime always uses \(\Delta t = 10\) s in a session.

  1. Update the wheel sub-grid of the cells that got new wheel stamps.
  2. Compute the vertical balance of each cell one time for the full \(\Delta t\).
  3. Make the list of the active cells: \(h > d_c + 10^{-6}\) m.
  4. Route the pond water of the active cells in substeps until \(\Delta t\) is complete.

A cell that gets its first water during the routing becomes active in the subsequent step.

Vertical Balance#

WaterGrid::Infiltrate does these calculations for each cell, in this sequence.

Rain#

\[ P = \max(0, R)\,\frac{\Delta t}{3.6 \times 10^{6}}, \qquad h \leftarrow h + P \]

\(R\) is the rain rate in mm/h. The rain first goes into the pond.

Effective Conductivity#

\[ K = K_s\,s_K, \qquad K \leftarrow \min(K,\ K_{seal}\,s_K) \ \text{on bare soil and row crops}, \qquad K_e = K\,(1 - a_c\,c) \]

\(s_K\) is ksat_scale and \(a_c\) is compaction_ksat_loss. The limit \(K_{seal}\) applies to the cover codes 0, 1, 2 and 9 when surface_sealing is true. It is the crust that rain makes on bare soil. Grass and woodland keep the open value. \(c\) is the mean compaction of the cell from the wheel sub-grid.

Green-Ampt Infiltration#

The surface layer takes water from the pond at the Green-Ampt rate. The code uses the rate form with an explicit step.

\[ F = \max\bigl(10^{-4},\ (\theta - \theta_0)\,d_1 + (\theta_2 - \theta_{2,0})\,d_2\bigr), \qquad \Delta\theta = \max(0,\ \theta_s - \theta) \]
\[ f_i = K_e \left(1 + \frac{(\psi + h)\,\Delta\theta}{F}\right) \]
\[ I = \min\bigl(h,\ (\theta_s - \theta)\,d_1,\ f_i\,\Delta t\bigr), \qquad h \leftarrow h - I, \qquad \theta \leftarrow \theta + \frac{I}{d_1} \]

Two details are different from the classic form. \(F\) is the gain of storage in both layers from the start, with a minimum of 0.1 mm. \(\Delta\theta\) is the current deficit, not the deficit at the start of the storm. The rate thus decreases while the layer fills. The layer has one water content. The model does not track the depth of the wetting front.

Redistribution to the Subsoil#

When \(\theta > \theta_{fc}\), water moves into the subsoil at the unsaturated conductivity of van Genuchten and Mualem.

\[ S_e = \mathrm{clamp}\!\left(\frac{\theta - \theta_r}{\theta_s - \theta_r},\ 0.001,\ 1\right), \qquad m = 1 - \frac{1}{n}, \qquad K_r = \sqrt{S_e}\,\Bigl(1 - \bigl(1 - S_e^{1/m}\bigr)^{m}\Bigr)^{2} \]
\[ D_{12} = \min\bigl((\theta - \theta_{fc})\,d_1,\ \max(0, (\theta_{s,2} - \theta_2)\,d_2),\ K_s\,s_K\,K_r\,\Delta t\bigr) \]
\[ \theta \leftarrow \theta - \frac{D_{12}}{d_1}, \qquad \theta_2 \leftarrow \theta_2 + \frac{D_{12}}{d_2} \]

This flux uses the open \(K_s\). The crust and the compaction change only the surface.

Deep Percolation and Tile Drains#

When \(\theta_2 > \theta_{fc,2}\), the excess \(X_2 = (\theta_2 - \theta_{fc,2})\,d_2\) leaves the subsoil. The deep percolation takes water first.

\[ D_p = \min(X_2,\ q_p\,\Delta t), \qquad D_t = \min(X_2 - D_p,\ q_t\,\Delta t), \qquad \theta_2 \leftarrow \theta_2 - \frac{D_p + D_t}{d_2} \]

The limit \(q_p\) comes from the NRCS drainage class of the unit. A soil with a poor class has slow subsoil or a high water table. The tile drain \(q_t\) is 9.525 mm/day (3/8 inch) on the field cells of the three classes in tile_drainage_classes.

Evaporation#

The demand is \(E_d = \max(0, E)\,\Delta t / (8.64 \times 10^{7})\) with \(E\) in mm/day. The pond gives water first, then the surface layer.

\[ e_p = \min(h,\ E_d), \qquad e_s = \min\bigl(\max(0, (\theta - \theta_{wp})\,d_1),\ E_d - e_p\bigr) \]
\[ h \leftarrow h - e_p, \qquad \theta \leftarrow \theta - \frac{e_s}{d_1} \]

The evaporation stops at the wilting point. The subsoil does not lose water to the air. The physics step sets \(E\) to 24 times the EvaporationMmH of the weather model. The option -FarmEvap= keeps a constant value.

Overland Flow#

WaterGrid::Route moves the pond water between the four neighbours of each cell. The scheme is an explicit diffusive wave with Manning friction, in the style of LISFLOOD-FP (Bates and De Roo 2000). Only the water above the detention depth can flow: \(h_{free} = h - d_c\).

For the cell \(i\) and its neighbour \(j\):

\[ \Delta\eta = \eta_i - \eta_j, \qquad h_f = \min\bigl(h_{free},\ \eta_i - \max(z_i, z_j)\bigr) \]

\(h_f\) is the depth that can go across the edge between the two cells. No water flows when \(\Delta\eta \le 10^{-6}\) m or \(h_f \le 10^{-5}\) m.

\[ v = \min\!\left(v_{max},\ \frac{h_{free}^{2/3}}{n_M}\,\frac{h_f}{h_{free}}\,\sqrt{\frac{\Delta\eta}{\Delta x}}\right) \]
\[ Q = \min\!\left(v\,h_f\,\Delta x\,\Delta t_s,\ \tfrac{1}{4}\,\Delta\eta\,\Delta x^{2}\right) \]

The limit \(\tfrac{1}{4}\Delta\eta\,\Delta x^2\) is half of the volume that makes the two water surfaces level. It prevents oscillation. The factor \(h_f/h_{free}\) replaces its power 2/3. This decreases the flow across a step of the bed.

When the four volumes of a cell are more than its free water, the model scales them.

\[ \sum_j Q_{ij} > h_{free}\,\Delta x^{2} \;\Rightarrow\; Q_{ij} \leftarrow Q_{ij}\,\frac{h_{free}\,\Delta x^{2}}{\sum_j Q_{ij}} \]

All cells compute their volumes from the old depths. Then each cell applies the sum.

\[ h_i \leftarrow h_i + \frac{\sum_j Q_{ji} - \sum_j Q_{ij}}{\Delta x^{2}} \]

Edge of the Grid#

A negative edge_outflow_slope closes the edge. In the shipped configuration the edge is open. The model assumes that the terrain continues with the slope \(s_e\) between the edge cell and the cell behind it.

\[ s_e = \max\!\left(s_{min},\ \frac{z_{inner} - z_i}{\Delta x}\right), \qquad \Delta\eta = h_{free} + s_e\,\Delta x, \qquad h_f = h_{free} \]

\(s_{min}\) is edge_outflow_slope. The water that leaves the grid goes into the run-off ledger.

Substeps#

The length of a routing substep follows the Courant condition with the largest velocity \(v_p\) of the previous substep.

\[ \Delta t_s = \mathrm{clamp}\!\left(\frac{0.8\,\Delta x}{v_p},\ \min(1, \Delta t),\ \min(10, \Delta t)\right) \]

When \(v_p\) is zero, the substep is \(\Delta t\). At the velocity limit of 1.5 m/s the substep is 2.1 s. The routing runs in two passes in 32 parallel parts of the grid.

Detention and Roughness#

The detention depth of a cell is the value of its cover plus the mean rut depth of its wheel sub-grid.

\[ d_c = d_{cover} + \bar r \]

Mass Balance#

Each cell keeps cumulative ledgers in metres of water. The ledgers are rain \(P\), infiltration, evaporation \(E\), deep percolation \(D_p\), tile drain \(D_t\), net lateral inflow \(L\) and edge run-off \(R_e\). WaterGrid::Residual gives the error of the balance.

\[ \varepsilon = P + L - h - \Delta S - E - D_p - D_t - R_e, \qquad \Delta S = (\theta - \theta_0)\,d_1 + (\theta_2 - \theta_{2,0})\,d_2 \]

A check with one column of the unit RcA under 20 mm/h of rain for 1 h gave \(|\varepsilon| < 10^{-14}\) m after 6 h.

Time Rain Water Content Pond Infiltration
0 min 0 mm 0.242 0 mm 0 mm
20 min 6.67 mm 0.264 0.10 mm 6.57 mm
40 min 13.33 mm 0.278 2.39 mm 10.94 mm
60 min 20.00 mm 0.289 5.83 mm 14.17 mm
90 min 20.00 mm 0.302 1.84 mm 18.10 mm
110 min 20.00 mm 0.308 0 mm 19.91 mm

The column has a corn cover, thus the sealed conductivity of 3.4 mm/h applies. With a grass cover all the rain infiltrates during the storm. The check used a small test program with AcresFarmModel.cpp, a flat grid of 3 × 3 cells and a closed edge.

Compaction and Ruts#

A wheel that sinks into the soil leaves a rut and compacts the soil. FAcresFarmRuntime::Wheel records both on the rut map. It examines the footprint of the tyre at intervals of 0.125 m. For the sinkage \(z_w\), each rut cell gets:

\[ r \leftarrow \max\bigl(r,\ \min(0.35,\ 0.65\,z_w)\bigr), \qquad c = \min\!\left(1,\ \frac{r}{0.065}\right) \]

A rut keeps 65 % of the sinkage and has a maximum depth of 0.35 m. A sinkage of 0.1 m gives full compaction. Ruts only become deeper. Tillage makes the surface level again, but the compaction stays.

Wheel Sub-Grid#

A tyre contact is 0.5 m to 0.7 m wide. A 4 m cell cannot show a rut. Each cell that a wheel changed thus gets a sub-grid of 16 × 16 sub-cells of 0.25 m (WaterGrid::FineTile). A sub-cell holds the rut depth, the compaction and a moisture anomaly. The sub-grid changes the cell in three ways.

Effect Rule Function
Infiltration \(c\) of the cell is the mean compaction of its sub-cells. EffectiveCompaction
Pond storage The mean rut depth \(\bar r\) adds to the detention depth. Detention
Local water The pond fills the deepest ruts first. FineLevel

FineLevel gives the water level \(L\) relative to the bed without ruts. With the rut depths in the sequence \(r_1 \ge r_2 \ge \dots \ge r_K\):

\[ L_M = \frac{K\,h - \sum_{k=1}^{M} r_k}{M} \]

The function increases \(M\) from 1. It stops when \(M = K\) or when \(L_M \le -r_{M+1}\). The local pond depth of a sub-cell is \(\max(0, L + r_k)\). The mean of these depths is equal to \(h\).

Moisture Anomaly#

WaterGrid::DistributeFine divides the infiltration \(I\) of a step between the sub-cells. The mean of the anomaly is zero, thus the water balance of the cell does not change. The capacity of the sub-cell \(s\) is the Green-Ampt capacity of the cell, \(C = f_i\,\Delta t\), with its own compaction.

\[ C_s = C\,\frac{1 - a_c\,c_s}{1 - a_c\,\bar c} \]

The rain of the step, \(P' = \min(P, h)\), falls on each sub-cell. Each sub-cell takes \(a_s = \min(P', C_s)\). The remaining water \(h_r\) goes into the ruts at the level \(L(h_r)\).

\[ h_r = h - P' + \frac{1}{K}\sum_s (P' - a_s) \]

The wet sub-cells (\(L + r_s > 0\)) take more water, up to their capacity.

\[ \beta = \min\!\left(1,\ \frac{K\,h_r}{\sum_{wet}(C_s - a_s)}\right), \qquad w_s = a_s + \beta\,(C_s - a_s) \ \text{for a wet sub-cell}, \qquad w_s = a_s \ \text{for a dry sub-cell} \]

The anomaly \(A_s\) first decays with the time constant \(\tau_a\) (wheel_subgrid_relax_h). Then it gets the share of the step.

\[ A_s \leftarrow A_s\,e^{-\Delta t_a/\tau_a} + \frac{I}{d_1}\left(\frac{w_s}{\bar w} - 1\right) \]

\(\Delta t_a\) is the time from the last update of the tile. The function then limits \(\theta + A_s\) to the range from \(\theta_{wp}\) to \(\theta_s\) and removes the mean again. It repeats this a maximum of four times.

The grid holds a maximum of 16384 tiles. After that, a stamp sets the compaction of the full 4 m cell and the rut does not store water.

Moisture State for the Tyre-Soil Model#

The water thread publishes a snapshot of the grid (FAcresWaterSnapshot). The snapshot holds these values for each cell:

\[ \text{Wetness} = \mathrm{clamp}\!\left(\frac{\theta - \theta_0}{\max(0.01,\ \theta_s - \theta_0)},\ 0,\ 1\right) \]

The wetness is 0 at the start state and 1 at saturation. The snapshot also holds \(\theta\), \(h\), the mean values of each field and the tiles of the wheel sub-grid.

FAcresFarmRuntime::Sample fills the surface input of one wheel, the structure AcresSim::FVehicleInput. It runs in each physics step for each wheel.

  1. Interpolate the cell values between the centres of the four nearest cells. On soil, \(\theta\) and the wetness use only the soil cells.
  2. Compute the local pond depth: \(\max(0,\ L + r)\) with the rut depth \(r\) below the wheel. Without a tile, \(L = h\) and \(r = 0\).
  3. On soil, add the moisture anomaly, interpolated between the centres of the four nearest sub-cells.
  4. Limit \(\theta\) to the range 0 to 0.6.
Field Value on Soil Value on a Hard Surface
Theta \(\theta\) plus the anomaly. Not used.
Wetness The largest of the wetness, the rain film and \(\min(1, \text{pond}/0.002)\). \(\min(1, \text{pond}/0.002)\).
WaterDepthM The local pond depth. The local pond depth.
RutDepthM The rut depth of the rut cell. 0.

The rain film is the SurfaceWetness of the weather model. It makes the soil surface wet in the first minutes of a storm. The water content of the 0.3 m layer increases more slowly.

The tyre-soil model uses the four fields as follows. Tyre and Soil gives the equations.

Field Use in the Tyre-Soil Model
Theta SoilStateAt computes the saturation, the suction, the strength, the Bekker moduli and the cone index from it.
Wetness It decreases the friction between rubber and soil, and the friction of a hard surface.
WaterDepthM The drag of the water on the tyre.
RutDepthM The minimum sinkage, and a higher density of the soil below the rut (CompactedDensity).

In the soil-and-weather study, silt loam had a cone index of 2.14 MPa at \(\theta = 0.236\). At \(\theta = 0.374\) the value was 0.63 MPa.

A wheel reads the farm only on the mapped surface. A surface that the driver selects with the keys 1 to 6 uses the constant values of its template.

Water Thread and Clock#

The grid has 145 924 cells. One step is too slow for a physics step of 1/120 s. A worker thread with the name AcresWater runs the grid.

Thread Functions
Physics thread Advance, Sample, Wheel. It holds the farm lock during the step of a vehicle.
Game thread Initialize, UpdateVisuals, save and load.
Water thread WaterGrid::Step and the snapshots.

FAcresFarmRuntime::Advance converts the physics step to environment time with the time scale \(k\) of the weather model.

\[ \Delta t_{env} = k\,\Delta t_{physics} \]

It adds \(\Delta t_{env}\) to the request of the water thread. The water thread takes the request in parts of exactly 10 s. The result thus does not change with the frame rate or with the time scale. A remainder of less than 10 s stays in the request.

At a high time scale the grid can be late. The snapshot contains the delay (BacklogS). The HUD shows the text "water lags" when the delay is more than 60 s.

The water thread writes each snapshot into one of three buffers and then changes an index. A reader takes the current buffer without a lock. The thread publishes a snapshot each 0.2 s of real time while it steps, and each 0.5 s when it has no work. Wheel stamps go to the water thread through a queue. The thread applies them before each step and each snapshot.

Before the session starts, Initialize runs the grid on the game thread for -FarmPreDays= and for the prior rain. These runs use steps of 300 s.

Lockstep#

In lockstep the water must be a function of the simulation only. FAcresFarmRuntime::SetDeterministicWater moves the grid to the physics thread.

  • Advance steps the grid by 10 s each time 10 s of environment time are complete.
  • Advance publishes a snapshot each 0.5 s of simulation time, with the wheel stamps of that time.
  • The water thread waits.

The same commands thus give the same soil below the tyres. Time Stepping and Determinism gives the rules for all models. Without lockstep, a snapshot can arrive one or more physics steps earlier or later between two runs.

Ground Conditions from the Station#

The folder Calibration/Weather connects the model to the real soil at ACRE. The source is the Purdue Mesonet station ACRE. The station has rain, air and wind sensors, and soil water probes at 5 cm, 10 cm, 20 cm and 40 cm.

File Function
acre_mesonet.py Downloads the 30-minute record of the station and applies quality checks.
ground_conditions.py Computes the weather and the soil wetness for each real run of the Polaris.
ground_conditions.md, ground_conditions.json The results for 269 runs.
Replay/env_<date>.json A weather replay file for each day with runs.
Replay/fields_w<index>/field-setup.json A field setup that gives all fields the wetness index of a day.
soil_state_cli.cpp Evaluates the soil library at a water content, to report the soil strength.

The probes do not give absolute water contents for these soils. The script thus refers each probe to its own record.

Probe Dry End Drained Upper Limit Wettest
5 cm 0.147 0.376 0.461
10 cm 0.198 0.412 0.456
20 cm 0.155 0.334 0.438
40 cm 0.338 0.437 0.478

The three columns are the index values \(w = 0\), \(w = 1\) and \(w = 2\) of a probe, in m³/m³. The dry end is the 0.5th percentile of the record. The wettest value is the 99.5th percentile. The drained upper limit is the median reading from 24 h to 48 h after each rain of 12 mm or more. The wetness index of the 0.3 m surface layer is a weighted mean of three probes.

\[ w = 0.25\,w_5 + 0.25\,w_{10} + 0.5\,w_{20} \]

This index is the wetness \(w\) of Initial Water Content. The script writes it into the field setups.

Parameters#

farm.json, Block hydrology#

Name Type Unit Default Description
initial_fraction_between_wilting_and_field_capacity number 0.5 The start fraction \(f\). Range 0 to 1.
ksat_scale number 1.0 The factor \(s_K\) on all conductivities. Range above 0 to 10.
compaction_ksat_loss number 0.7 The fraction \(a_c\) of the conductivity that full compaction removes.
residual_theta number m³/m³ 0.06 The residual water content \(\theta_r\).
vg_n number 1.6 The exponent \(n\) of van Genuchten.
tile_drainage_mm_day number mm/day 9.525 The tile drain \(q_t\).
tile_drainage_classes list 3 classes The drainage classes that get tile drains on field cells.
gravel.ksat_mm_h number mm/h 5.0 The conductivity of gravel.
gravel.depth_m number m 0.3 The depth of the gravel layer.
covers.<name>.manning_n number s/m^(1/3) see below The Manning roughness of a cover.
covers.<name>.detention_m number m see below The detention depth of a cover.
edge_outflow_slope number m/m 0.002 The minimum slope at the open edge. A negative value closes the edge.
max_sheet_flow_velocity_mps number m/s 1.5 The velocity limit \(v_{max}\).
deep_percolation_mm_h_by_drainage_class object mm/h see below The limit \(q_p\) for each drainage class.
surface_sealing boolean true Applies \(K_{seal}\) on bare soil and row crops.
wheel_subgrid_relax_h number h 24 The time constant \(\tau_a\) of the moisture anomaly. Optional.
wheel_subgrid_max_tiles integer 16384 The maximum number of tiles of the wheel sub-grid. Optional.
Cover Code Manning Roughness Detention Depth
bare 0 0.05 0.002 m
corn 1 0.10 0.003 m
soybean 2 0.10 0.003 m
grass 3 0.24 0.003 m
woodland 4 0.40 0.005 m
shrubs 5 0.40 0.005 m
asphalt 6 0.011 0.0005 m
concrete 7 0.011 0.0005 m
gravel 8 0.02 0.001 m
potato 9 0.08 0.004 m
Drainage Class Percolation Limit
Excessively drained 100 mm/h
Somewhat excessively drained 60 mm/h
Well drained 33 mm/h
Moderately well drained 8 mm/h
Somewhat poorly drained 1.5 mm/h
Poorly drained 0.4 mm/h
Very poorly drained 0.1 mm/h

The percolation limits are estimates, not measurements. The roughness values come from Table 3-1 of SCS TR-55.

farm.json, Block weather#

The block applies only when the map has no weather model. On the ACRE map the physics step replaces these values.

Name Type Unit Default Description
rain_mm_h number mm/h 0 The rain rate. Range 0 to 200.
minimum_c number °C 16 The minimum temperature of the day.
maximum_c number °C 28 The maximum temperature of the day.
evaporation_mm_day number mm/day 2 The potential evaporation. Range 0 to 20.
time_scale number 1 Environment seconds for each physics second. Range 0 to 86400.

Command-Line Options#

Name Type Unit Default Description
-FarmInitialTheta= number 0.5 The start fraction \(f\). Range 0 to 1.
-FarmKsatScale= number 1.0 The factor \(s_K\).
-FarmEvap= number mm/day from the weather A constant potential evaporation.
-FarmPreDays= number days 0 Time that the grid runs before the session starts.
-FarmLoad= path The farm-state.json of a saved session.
-FieldSetup= path The folder with field-setup.json.
-FarmDisabled flag off Starts the session without the farm. The wheels then use the surface templates.

Constants in the Code#

Constant Value Description
CflFactor 0.8 The Courant number of the routing.
MinSubstepS 1 s The shortest routing substep.
FineDiv 16 Sub-cells on each side of a tile.
RutCellM 0.25 m The cell of the rut map.
RutShare 0.65 The share of the sinkage that stays as a rut.
RutMaxM 0.35 m The largest rut depth.
CompactionSinkageM 0.1 m The sinkage that gives full compaction.

Outputs#

FAcresFarmRuntime::Export writes these files into the session folder at the end of a session and on the F5 key.

File Content
farm-fields.csv One row for each field: mean \(\theta\), pond, rain, evaporation, drainage, lateral flow and the balance error.
farm-water.json A summary of the grid: largest pond, mean ledgers, number of substeps, size of the wheel sub-grid.
water-depth.f32, theta.f32 The pond depth and \(\theta\) of each cell, 382 × 382 values of 32 bits.
farm-weather.csv One row each hour: rain, temperatures, the balance error and the ponds.
farm-state.json, farm-water.bin The saved state. The binary file holds 11 arrays of 64-bit values for the grid.

The rows F60, F61 and F62 of farm-fields.csv are the asphalt, concrete and gravel cells. The row F00 is all other cells outside the fields. Session Log gives the columns.

Code Map#

Item File Function
Soil unit, cover, grid state AcresFarmModel.h AcresFarm::WaterUnit, WaterCover, WaterGrid
Step of the grid AcresFarmModel.cpp WaterGrid::Step
Vertical balance AcresFarmModel.cpp WaterGrid::Infiltrate
Overland flow AcresFarmModel.cpp WaterGrid::Route
Balance error AcresFarmModel.cpp WaterGrid::Residual, TotalResidual
Wheel sub-grid AcresFarmModel.cpp StampFine, PrepareFine, FineLevel, DistributeFine, FineAnomalies
Units, cells, start state AcresFarmRuntime.cpp FAcresFarmRuntime::Initialize
Water thread, snapshot AcresFarmRuntime.cpp FAcresWaterThread::Run, Publish
Clock AcresFarmRuntime.cpp FAcresFarmRuntime::Advance
Wheel query AcresFarmRuntime.cpp FAcresFarmRuntime::Sample
Ruts and compaction AcresFarmRuntime.cpp FAcresFarmRuntime::Wheel, StampFine
Wetness in a session AcresFarmRuntime.cpp FAcresFarmRuntime::SetSoilWetness
Lockstep AcresFarmRuntime.cpp FAcresFarmRuntime::SetDeterministicWater
Save and export AcresFarmRuntime.cpp Save, Load, Export
Constant conditions of Core Core/Source/AcresCoreWorld.cpp FAcresWorld::CellTheta, SurfaceAt
Station data Calibration/Weather/ground_conditions.py

Limitations#

  • The hydraulic values are survey values and texture means. They have no calibration against ACRE measurements.
  • One surface layer of 0.3 m holds the water of a storm. The model does not show a thin wet layer at the top, apart from the rain film.
  • A 4 m cell takes its soil unit and its height from one point. The grid does not show a ditch that is narrower than 4 m.
  • Each field with a soil override gets a tile drain, also on a well-drained soil.
  • The water can be late at a high time scale, because a grid step is always 10 s.
  • The grid reads the rain rate one time for each 10 s step. At a time scale of 60, a field got 16.81 mm in one session and 16.90 mm in a second session. The storm had 16.80 mm.
  • Compaction does not recover. The rut map and the wheel sub-grid only grow during a session.
  • SetSoilWetness does not change \(\theta_0\). After the call, the balance error \(\varepsilon\) includes the change of storage. A test gave an error of 5.8 mm for field F21.
  • The game does not limit the wetness of a field setup file. A value above 2 gives a water content above saturation.
  • The command -FarmLoad= does not prevent the pre-run days and the prior rain. They run after the load.
  • The fingerprint of a saved state does not include the terrain heights or the field setup.
  • Hard surfaces become wet only from pond water, not from the rain film.

References#

  • Bates, P. D., and De Roo, A. P. J. (2000). A simple raster-based model for flood inundation simulation. Journal of Hydrology, 236(1-2), 54-77.
  • Purdue University Cooperative Extension Service. Drainage and wet soil management: drainage recommendations for Indiana soils (AY-300). West Lafayette, Indiana.
  • Green, W. H., and Ampt, G. A. (1911). Studies on soil physics. Part I. The flow of air and water through soils. Journal of Agricultural Science, 4(1), 1-24.
  • Mualem, Y. (1976). A new model for predicting the hydraulic conductivity of unsaturated porous media. Water Resources Research, 12(3), 513-522.
  • Rawls, W. J., Brakensiek, D. L., and Miller, N. (1983). Green-Ampt infiltration parameters from soils data. Journal of Hydraulic Engineering, 109(1), 62-70.
  • Rawls, W. J., Brakensiek, D. L., and Saxton, K. E. (1982). Estimation of soil water properties. Transactions of the ASAE, 25(5), 1316-1320.
  • Soil Conservation Service (1986). Urban hydrology for small watersheds (Technical Release 55). Washington, DC: United States Department of Agriculture.
  • Soil Survey Staff. Soil Survey Geographic (SSURGO) database. United States Department of Agriculture, Natural Resources Conservation Service.
  • van Genuchten, M. T. (1980). A closed-form equation for predicting the hydraulic conductivity of unsaturated soils. Soil Science Society of America Journal, 44(5), 892-898.