smoke-index/van-genuchten.html

122 lines
7.6 KiB
HTML
Raw Permalink Normal View History

2026-07-18 10:10:38 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Van Genuchten Soil Water Retention | Arthur Ibay</title>
<style>
:root{--bg:#0f0f12;--fg:#e6e6e8;--accent:#ff6b35;--panel:#1a1a20;--grid:#2a2a35}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:"Inter",system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--fg);line-height:1.6;font-size:16px;padding:2rem;letter-spacing:-0.01em}
h1{font-weight:700;font-size:clamp(1.8rem,4vw,2.8rem);margin-bottom:0.5rem;letter-spacing:-0.02em;color:#fff}
.subtitle{opacity:.75;font-size:1rem;margin-bottom:2rem;font-feature-settings:"tnum,onum"}
nav{display:flex;gap:1.5rem;margin-bottom:2.5rem;font-size:.9rem;flex-wrap:wrap}
nav a{color:inherit;text-decoration:none;border-bottom:1px solid transparent;padding-bottom:2px;transition:border-color .2s}
nav a:hover{border-color:var(--accent)}
main{max-width:1100px;margin:0 auto;display:grid;grid-template-columns:1fr 1fr;gap:2.5rem}
.panel{background:var(--panel);border-radius:12px;padding:2rem;border:1px solid var(--grid);box-shadow:0 10px 40px rgba(0,0,0,.4)}
.panel h2{font-size:1.1rem;margin-bottom:1.2rem;color:var(--accent);text-transform:uppercase;letter-spacing:.08em;font-weight:600}
label{display:block;font-size:.85rem;opacity:.85;margin-bottom:.4rem;font-weight:500}
select,input{width:100%;padding:.75rem 1rem;background:#0f0f12;border:1px solid var(--grid);color:var(--fg);border-radius:6px;font-size:.95rem;margin-bottom:1.2rem;font-family:inherit}
select:focus,input:focus{outline:none;border-color:var(--accent)}
button{background:var(--accent);color:#000;border:none;padding:.9rem 1.5rem;border-radius:6px;font-weight:700;cursor:pointer;width:100%;font-size:1rem;transition:transform .1s,filter .2s}
button:hover{filter:brightness(1.15)}
button:active{transform:scale(.99)}
.result{margin-top:1.5rem;padding:1.2rem;background:rgba(255,107,53,.08);border-left:3px solid var(--accent);border-radius:0 6px 6px 0}
.result-row{display:grid;grid-template-columns:1fr auto;gap:1rem;font-size:.9rem;margin-bottom:.5rem;padding:.35rem 0;border-bottom:1px dashed rgba(255,255,255,.08)}
.result-row:last-child{border:none;margin-bottom:0}
.result-label{opacity:.75}
.result-val{font-weight:600;font-feature-settings:"tnum,onum";text-align:right}
.caption{margin-top:.75rem;font-size:.8rem;opacity:.65;text-align:center}
.citation{margin-top:2rem;font-size:.8rem;opacity:.5;line-height:1.8}
@media(max-width:900px){main{grid-template-columns:1fr}}
img{width:100%;height:auto;border-radius:8px;margin-top:1.5rem;display:block}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<header>
<h1>Van Genuchten Soil Water Retention</h1>
<div class="subtitle">Computing θ_s, θ_r, α, n, m from USDA Texture Class and Bulk Density</div>
<nav>
<a href="/">Home</a><a href="/et-matrix.html">ET Matrix</a><a href="/irrigation-controller.html">Duty Cycle Controller</a><a href="/wasatch-assay.html">Wasatch Assay</a><a href="/garden-ledger.html">Garden Ledger</a>
</nav>
</header>
<main>
<section class="panel">
<h2>Input Parameters</h2>
<label for="texture">USDA Soil Texture Class</label>
<select id="texture">
<option value="sand">Sand</option>
<option value="loamy_sand">Loamy Sand</option>
<option value="sandy_loam">Sandy Loam</option>
<option value="loam" selected>Loam</option>
<option value="silt_loam">Silt Loam</option>
<option value="clay_loam">Clay Loam</option>
<option value="clay">Clay</option>
</select>
<label for="bd">Bulk Density (g/cm³)</label>
<input type="number" id="bd" step="0.01" value="1.35" min="1.0" max="2.0">
<label for="om">Organic Matter (%)</label>
<input type="number" id="om" step="0.1" value="2.5" min="0" max="20">
<button onclick="computeVG()">Compute Retention Curve</button>
</section>
<section class="panel">
<h2>Retained Water Fractions</h2>
<div id="out"></div>
<img src="https://images.pexels.com/photos/12697901/pexels-photo-12697901.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Cracked dry earth—the physical consequence of misjudged water retention">
<div class="caption">When θ_r exceeds plant-available thresholds, the land speaks in fractures.</div>
</section>
</main>
<footer class="citation">
Source: FAO Irrigation and Drainage Paper 56 (1998), Appendix IV. Parameters adapted from Rawls et al. (1982) pedotransfer functions for USDA texture classes.<br>
Implementation: Arthur Ibay, Salt Lake City. Machine-readable coefficients at /van-genuchten.json.
</footer>
<script>
const VG = {
sand:{theta_s:0.425, theta_r:0.065, alpha:0.037, n:2.12, bd_base:1.55, om_coef:0.008},
loamy_sand:{theta_s:0.410, theta_r:0.075, alpha:0.045, n:1.95, bd_base:1.50, om_coef:0.009},
sandy_loam:{theta_s:0.405, theta_r:0.085, alpha:0.052, n:1.88, bd_base:1.45, om_coef:0.010},
loam:{theta_s:0.400, theta_r:0.095, alpha:0.060, n:1.80, bd_base:1.35, om_coef:0.011},
silt_loam:{theta_s:0.395, theta_r:0.105, alpha:0.070, n:1.72, bd_base:1.30, om_coef:0.012},
clay_loam:{theta_s:0.385, theta_r:0.120, alpha:0.082, n:1.62, bd_base:1.25, om_coef:0.013},
clay:{theta_s:0.375, theta_r:0.135, alpha:0.095, n:1.52, bd_base:1.20, om_coef:0.014}
};
function computeVG(){
const txt=document.getElementById('texture').value;
const bd=parseFloat(document.getElementById('bd').value)||1.35;
const om=parseFloat(document.getElementById('om').value)||2.5;
const p=VG[txt];
// Adjust porosity by bulk density deviation from base
const phi_adj=(p.bd_base-bd)*0.02;
const theta_s=p.theta_s+phi_adj+(om*p.om_coef);
const theta_r=p.theta_r*(1-om*0.005);
const alpha=p.alpha*Math.pow(bd/p.bd_base,0.5);
const n=p.n*(1-om*0.002);
const m=1-1/n;
// Van Genuchten: theta(h)=theta_r+(theta_s-theta_r)/(1+(alpha*|h|)^n)^m
const fc=theta_r+(theta_s-theta_r)/Math.pow(1+Math.pow(alpha*0.33,n),m);
const pwp=theta_r+(theta_s-theta_r)/Math.pow(1+Math.pow(alpha*1.5,n),m);
const awc=fc-pwp;
const out=`
<div class="result"><strong>Computed Parameters</strong></div>
<div class="result-row"><span class="result-label">θ_s (Saturated Vol. Fraction)</span><span class="result-val">${theta_s.toFixed(4)}</span></div>
<div class="result-row"><span class="result-label">θ_r (Residual Vol. Fraction)</span><span class="result-val">${theta_r.toFixed(4)}</span></div>
<div class="result-row"><span class="result-label">α (Inverse Air Entry, cm⁻¹)</span><span class="result-val">${alpha.toFixed(5)}</span></div>
<div class="result-row"><span class="result-label">n (Pore Size Distribution)</span><span class="result-val">${n.toFixed(3)}</span></div>
<div class="result-row"><span class="result-label">m (Shape Parameter)</span><span class="result-val">${m.toFixed(3)}</span></div>
<hr style="border:0;border-top:1px dashed rgba(255,255,255,.1);margin:1rem 0">
<div class="result"><strong>Operational Points</strong></div>
<div class="result-row"><span class="result-label">Field Capacity (0.33MPa)</span><span class="result-val">${fc.toFixed(4)}cm³/cm³</span></div>
<div class="result-row"><span class="result-label">Permanent Wilting Pt (1.5MPa)</span><span class="result-val">${pwp.toFixed(4)}cm³/cm³</span></div>
<div class="result-row"><span class="result-label">Available Water Capacity</span><span class="result-val">${awc.toFixed(4)}cm³/cm³</span></div>
<div class="result-row"><span class="result-label">AWC (mm per meter depth)</span><span class="result-val">${(awc*1000).toFixed(1)}mm</span></div>
`;
document.getElementById('out').innerHTML=out;
}
// Pre-compute default
window.onload=()=>setTimeout(computeVG,150);
</script>
</body>
</html>