EnviroAutomate
← All validation

Groundwater Contour Mapping validation

Free groundwater contour mapping from well levels: water table contours, flow direction arrows and hydraulic gradient, for surveyed (mAHD) or relative local-datum data.

Scenarios
5
Values agreeing
52
Values differing
0
Validated against
Shepard inverse-distance weighting and the least-squares plane, Published worked example, Golden Software Surfer

Open Groundwater Contour Mapping

The hydraulic gradient and flow direction are compared against an independent least-squares plane fit. Three scenarios also carry a hand-derived expected answer: for three wells the plane through them has a closed form, so the gradient and bearing can be derived directly. Golden Software Surfer compares the three-well surface node by node. With more wells Surfer interpolates the levels directly where this toolkit fits a plane and interpolates the residuals, so the two are not compared.

Scenarios

Six wells, fitted by least squares

Typical use

Input

Settings: wells = [{"x":0,"y":0,"elevation":12.4},{"x":50,"y":10,"elevation":12.1},{"x":100,"y":0,"elevation":11.6},{"x":10,"y":80,"elevation":12.2},{"x":60,"y":90,"elevation":11.8},{"x":110,"y":75,"elevation":11.3}], contourInterval = 0.1

Against Shepard inverse-distance weighting and the least-squares plane (published methods; no vendor build)

ValueShepard inverse-distance weighting and the least-squares planeEnviroAutomateDifferenceAgreement bandVerdict
wellCount wellCount660within 0.000001 relativeAgree
hydraulicGradient hydraulicGradient0.0088361682163335520.0088361682163335520within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees75.9985231316576375.998523131657630within 0.000001 relativeAgree
minLevel minLevel11.311.30within 0.000001 relativeAgree
maxLevel maxLevel12.412.40within 0.000001 relativeAgree

Not run for this scenario

  • Golden Software Surfer - Surfer interpolates the measured levels directly, where this tool fits a plane through them and interpolates what is left over. The two only coincide when there are exactly three wells, so that is the scenario compared here.

Three wells: the three-point problem

Typical use

Input

Settings: wells = [{"x":0,"y":0,"elevation":10},{"x":100,"y":0,"elevation":9.5},{"x":0,"y":100,"elevation":9.8}], contourInterval = 0.1

Against Shepard inverse-distance weighting and the least-squares plane (published methods; no vendor build)

ValueShepard inverse-distance weighting and the least-squares planeEnviroAutomateDifferenceAgreement bandVerdict
wellCount wellCount330within 0.000001 relativeAgree
hydraulicGradient hydraulicGradient0.0053851648071345010.0053851648071345010within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees68.1985905136482668.198590513648241.42e-14within 0.000001 relativeAgree
minLevel minLevel9.59.50within 0.000001 relativeAgree
maxLevel maxLevel10100within 0.000001 relativeAgree

Against Golden Software Surfer (Surfer 31.04.342 (trial))

ValueGolden Software SurferEnviroAutomateDifferenceAgreement bandVerdict
grid.5.5 grid.5.59.93628205128219.936282051282054.97e-14within 0.000001 relativeAgree
grid.5.10 grid.5.109.86576923076929.8657692307692323.20e-14within 0.000001 relativeAgree
grid.5.15 grid.5.159.79525641025649.795256410256411.07e-14within 0.000001 relativeAgree
grid.5.20 grid.5.209.72474358974369.724743589743591.07e-14within 0.000001 relativeAgree
grid.5.25 grid.5.259.65423076923089.654230769230773.02e-14within 0.000001 relativeAgree
grid.5.30 grid.5.309.58371794871799.5837179487179494.80e-14within 0.000001 relativeAgree
grid.10.5 grid.10.59.90807692307699.9080769230769232.31e-14within 0.000001 relativeAgree
grid.10.10 grid.10.109.83756410256419.8375641025641033.55e-15within 0.000001 relativeAgree
grid.10.15 grid.10.159.76705128205139.7670512820512821.78e-14within 0.000001 relativeAgree
grid.10.20 grid.10.209.69653846153859.6965384615384613.91e-14within 0.000001 relativeAgree
grid.10.25 grid.10.259.62602564102569.6260256410256424.09e-14within 0.000001 relativeAgree
grid.15.5 grid.15.59.87987179487189.8798717948717955.33e-15within 0.000001 relativeAgree
grid.15.10 grid.15.109.8093589743599.8093589743589752.49e-14within 0.000001 relativeAgree
grid.15.15 grid.15.159.73884615384629.7388461538461544.62e-14within 0.000001 relativeAgree
grid.15.20 grid.15.209.66833333333339.6683333333333333.38e-14within 0.000001 relativeAgree
grid.20.5 grid.20.59.85166666666679.8516666666666673.38e-14within 0.000001 relativeAgree
grid.20.10 grid.20.109.78115384615389.7811538461538474.80e-14within 0.000001 relativeAgree
grid.20.15 grid.20.159.7106410256419.7106410256410262.66e-14within 0.000001 relativeAgree
grid.25.5 grid.25.59.82346153846159.8234615384615383.91e-14within 0.000001 relativeAgree
grid.25.10 grid.25.109.75294871794879.7529487179487191.95e-14within 0.000001 relativeAgree
grid.30.5 grid.30.59.79525641025649.795256410256411.07e-14within 0.000001 relativeAgree

Against Published worked example (as cited per case)

ValuePublished worked exampleEnviroAutomateDifferenceAgreement bandVerdict
hydraulicGradient hydraulicGradient0.0053851648071345040.0053851648071345012.60e-18within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees68.1985905136481868.198590513648245.68e-14within 0.000001 relativeAgree

A perfectly uniform water table

Boundary case

Input

Settings: wells = [{"x":0,"y":0,"elevation":10},{"x":100,"y":0,"elevation":9},{"x":0,"y":100,"elevation":10},{"x":100,"y":100,"elevation":9}], contourInterval = 0.1

Against Shepard inverse-distance weighting and the least-squares plane (published methods; no vendor build)

ValueShepard inverse-distance weighting and the least-squares planeEnviroAutomateDifferenceAgreement bandVerdict
wellCount wellCount440within 0.000001 relativeAgree
hydraulicGradient hydraulicGradient0.010.010within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees90900within 0.000001 relativeAgree
minLevel minLevel990within 0.000001 relativeAgree
maxLevel maxLevel10100within 0.000001 relativeAgree

Against Published worked example (as cited per case)

ValuePublished worked exampleEnviroAutomateDifferenceAgreement bandVerdict
hydraulicGradient hydraulicGradient0.010.010within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees90900within 0.000001 relativeAgree

Not run for this scenario

  • Golden Software Surfer - Surfer interpolates the measured levels directly, where this tool fits a plane through them and interpolates what is left over. The two only coincide when there are exactly three wells, so that is the scenario compared here.

Flow to the north

Boundary case

Input

Settings: wells = [{"x":0,"y":0,"elevation":10},{"x":100,"y":0,"elevation":10},{"x":0,"y":100,"elevation":9},{"x":100,"y":100,"elevation":9}], contourInterval = 0.1

Against Shepard inverse-distance weighting and the least-squares plane (published methods; no vendor build)

ValueShepard inverse-distance weighting and the least-squares planeEnviroAutomateDifferenceAgreement bandVerdict
wellCount wellCount440within 0.000001 relativeAgree
hydraulicGradient hydraulicGradient0.010.010within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees000within 0.000001 relativeAgree
minLevel minLevel990within 0.000001 relativeAgree
maxLevel maxLevel10100within 0.000001 relativeAgree

Against Published worked example (as cited per case)

ValuePublished worked exampleEnviroAutomateDifferenceAgreement bandVerdict
hydraulicGradient hydraulicGradient0.010.010within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees000within 0.000001 relativeAgree

Not run for this scenario

  • Golden Software Surfer - Surfer interpolates the measured levels directly, where this tool fits a plane through them and interpolates what is left over. The two only coincide when there are exactly three wells, so that is the scenario compared here.

Wells that almost fall on a line

Boundary case

Input

Settings: wells = [{"x":0,"y":0,"elevation":10},{"x":50,"y":1,"elevation":9.7},{"x":100,"y":2,"elevation":9.4},{"x":50,"y":3,"elevation":9.65}], contourInterval = 0.1

Against Shepard inverse-distance weighting and the least-squares plane (published methods; no vendor build)

ValueShepard inverse-distance weighting and the least-squares planeEnviroAutomateDifferenceAgreement bandVerdict
wellCount wellCount440within 0.000001 relativeAgree
hydraulicGradient hydraulicGradient0.0255978514723401720.0255978514723401720within 0.000001 relativeAgree
flowDirectionDegrees flowDirectionDegrees12.40741852740086612.4074185274008641.78e-15within 0.000001 relativeAgree
minLevel minLevel9.49.40within 0.000001 relativeAgree
maxLevel maxLevel10100within 0.000001 relativeAgree

Not run for this scenario

  • Golden Software Surfer - Surfer interpolates the measured levels directly, where this tool fits a plane through them and interpolates what is left over. The two only coincide when there are exactly three wells, so that is the scenario compared here.

Evidence generated 2026-08-26 from a full comparison run against the versions named above.