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
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 squaresTypical use
- Three wells: the three-point problemTypical use
- A perfectly uniform water tableBoundary case
- Flow to the northBoundary case
- Wells that almost fall on a lineBoundary case
Six wells, fitted by least squares
Typical useInput
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)
| Value | Shepard inverse-distance weighting and the least-squares plane | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| wellCount wellCount | 6 | 6 | 0 | within 0.000001 relative | Agree |
| hydraulicGradient hydraulicGradient | 0.008836168216333552 | 0.008836168216333552 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 75.99852313165763 | 75.99852313165763 | 0 | within 0.000001 relative | Agree |
| minLevel minLevel | 11.3 | 11.3 | 0 | within 0.000001 relative | Agree |
| maxLevel maxLevel | 12.4 | 12.4 | 0 | within 0.000001 relative | Agree |
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 useInput
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)
| Value | Shepard inverse-distance weighting and the least-squares plane | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| wellCount wellCount | 3 | 3 | 0 | within 0.000001 relative | Agree |
| hydraulicGradient hydraulicGradient | 0.005385164807134501 | 0.005385164807134501 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 68.19859051364826 | 68.19859051364824 | 1.42e-14 | within 0.000001 relative | Agree |
| minLevel minLevel | 9.5 | 9.5 | 0 | within 0.000001 relative | Agree |
| maxLevel maxLevel | 10 | 10 | 0 | within 0.000001 relative | Agree |
Against Golden Software Surfer (Surfer 31.04.342 (trial))
| Value | Golden Software Surfer | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| grid.5.5 grid.5.5 | 9.9362820512821 | 9.93628205128205 | 4.97e-14 | within 0.000001 relative | Agree |
| grid.5.10 grid.5.10 | 9.8657692307692 | 9.865769230769232 | 3.20e-14 | within 0.000001 relative | Agree |
| grid.5.15 grid.5.15 | 9.7952564102564 | 9.79525641025641 | 1.07e-14 | within 0.000001 relative | Agree |
| grid.5.20 grid.5.20 | 9.7247435897436 | 9.72474358974359 | 1.07e-14 | within 0.000001 relative | Agree |
| grid.5.25 grid.5.25 | 9.6542307692308 | 9.65423076923077 | 3.02e-14 | within 0.000001 relative | Agree |
| grid.5.30 grid.5.30 | 9.5837179487179 | 9.583717948717949 | 4.80e-14 | within 0.000001 relative | Agree |
| grid.10.5 grid.10.5 | 9.9080769230769 | 9.908076923076923 | 2.31e-14 | within 0.000001 relative | Agree |
| grid.10.10 grid.10.10 | 9.8375641025641 | 9.837564102564103 | 3.55e-15 | within 0.000001 relative | Agree |
| grid.10.15 grid.10.15 | 9.7670512820513 | 9.767051282051282 | 1.78e-14 | within 0.000001 relative | Agree |
| grid.10.20 grid.10.20 | 9.6965384615385 | 9.696538461538461 | 3.91e-14 | within 0.000001 relative | Agree |
| grid.10.25 grid.10.25 | 9.6260256410256 | 9.626025641025642 | 4.09e-14 | within 0.000001 relative | Agree |
| grid.15.5 grid.15.5 | 9.8798717948718 | 9.879871794871795 | 5.33e-15 | within 0.000001 relative | Agree |
| grid.15.10 grid.15.10 | 9.809358974359 | 9.809358974358975 | 2.49e-14 | within 0.000001 relative | Agree |
| grid.15.15 grid.15.15 | 9.7388461538462 | 9.738846153846154 | 4.62e-14 | within 0.000001 relative | Agree |
| grid.15.20 grid.15.20 | 9.6683333333333 | 9.668333333333333 | 3.38e-14 | within 0.000001 relative | Agree |
| grid.20.5 grid.20.5 | 9.8516666666667 | 9.851666666666667 | 3.38e-14 | within 0.000001 relative | Agree |
| grid.20.10 grid.20.10 | 9.7811538461538 | 9.781153846153847 | 4.80e-14 | within 0.000001 relative | Agree |
| grid.20.15 grid.20.15 | 9.710641025641 | 9.710641025641026 | 2.66e-14 | within 0.000001 relative | Agree |
| grid.25.5 grid.25.5 | 9.8234615384615 | 9.823461538461538 | 3.91e-14 | within 0.000001 relative | Agree |
| grid.25.10 grid.25.10 | 9.7529487179487 | 9.752948717948719 | 1.95e-14 | within 0.000001 relative | Agree |
| grid.30.5 grid.30.5 | 9.7952564102564 | 9.79525641025641 | 1.07e-14 | within 0.000001 relative | Agree |
Against Published worked example (as cited per case)
| Value | Published worked example | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| hydraulicGradient hydraulicGradient | 0.005385164807134504 | 0.005385164807134501 | 2.60e-18 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 68.19859051364818 | 68.19859051364824 | 5.68e-14 | within 0.000001 relative | Agree |
A perfectly uniform water table
Boundary caseInput
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)
| Value | Shepard inverse-distance weighting and the least-squares plane | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| wellCount wellCount | 4 | 4 | 0 | within 0.000001 relative | Agree |
| hydraulicGradient hydraulicGradient | 0.01 | 0.01 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 90 | 90 | 0 | within 0.000001 relative | Agree |
| minLevel minLevel | 9 | 9 | 0 | within 0.000001 relative | Agree |
| maxLevel maxLevel | 10 | 10 | 0 | within 0.000001 relative | Agree |
Against Published worked example (as cited per case)
| Value | Published worked example | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| hydraulicGradient hydraulicGradient | 0.01 | 0.01 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 90 | 90 | 0 | within 0.000001 relative | Agree |
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 caseInput
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)
| Value | Shepard inverse-distance weighting and the least-squares plane | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| wellCount wellCount | 4 | 4 | 0 | within 0.000001 relative | Agree |
| hydraulicGradient hydraulicGradient | 0.01 | 0.01 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 0 | 0 | 0 | within 0.000001 relative | Agree |
| minLevel minLevel | 9 | 9 | 0 | within 0.000001 relative | Agree |
| maxLevel maxLevel | 10 | 10 | 0 | within 0.000001 relative | Agree |
Against Published worked example (as cited per case)
| Value | Published worked example | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| hydraulicGradient hydraulicGradient | 0.01 | 0.01 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 0 | 0 | 0 | within 0.000001 relative | Agree |
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 caseInput
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)
| Value | Shepard inverse-distance weighting and the least-squares plane | EnviroAutomate | Difference | Agreement band | Verdict |
|---|---|---|---|---|---|
| wellCount wellCount | 4 | 4 | 0 | within 0.000001 relative | Agree |
| hydraulicGradient hydraulicGradient | 0.025597851472340172 | 0.025597851472340172 | 0 | within 0.000001 relative | Agree |
| flowDirectionDegrees flowDirectionDegrees | 12.407418527400866 | 12.407418527400864 | 1.78e-15 | within 0.000001 relative | Agree |
| minLevel minLevel | 9.4 | 9.4 | 0 | within 0.000001 relative | Agree |
| maxLevel maxLevel | 10 | 10 | 0 | within 0.000001 relative | Agree |
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.
