smoke-index/et-matrix.html
2026-07-18 08:10:38 +00:00

348 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Evapotranspiration Matrix | Arthur Ibay</title>
<style>
:root {
--bg: #1a1a1a;
--panel: #252525;
--text: #e0e0e0;
--accent: #00ff88;
--border: #444;
--font: 'Courier New', monospace;
}
* { box-sizing: border-box; }
body {
background-color: var(--bg);
color: var(--text);
font-family: var(--font);
line-height: 1.5;
margin: 0;
padding: 20px;
max-width: 900px;
margin: 0 auto;
}
header {
border-bottom: 2px solid var(--accent);
padding-bottom: 20px;
margin-bottom: 40px;
text-align: center;
}
.hero-img {
width: 100%;
max-width: 600px;
height: 300px;
object-fit: cover;
border-radius: 8px;
margin: 0 auto 30px auto;
display: block;
filter: contrast(1.2) saturate(0.8);
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
}
h1 {
color: var(--accent);
font-size: 2.5em;
margin: 0;
letter-spacing: -1px;
}
h2 {
color: var(--accent);
font-size: 1.5em;
margin-top: 30px;
border-left: 4px solid var(--accent);
padding-left: 15px;
text-align: left;
}
.matrix-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin: 40px 0;
}
.input-panel {
background: var(--panel);
padding: 25px;
border-radius: 8px;
border: 1px solid var(--border);
}
.output-panel {
background: #000;
padding: 25px;
border-radius: 8px;
border: 1px solid var(--accent);
position: relative;
overflow: hidden;
}
.output-panel::before {
content: "";
position: absolute;
top: 0; left: 0; right: 0; height: 2px;
background: linear-gradient(90deg, transparent, var(--accent), transparent);
animation: scanline 4s infinite linear;
}
@keyframes scanline {
0% { top: 0; }
100% { top: 100%; }
}
label {
display: block;
margin-bottom: 8px;
color: var(--accent);
font-size: 0.9em;
text-transform: uppercase;
letter-spacing: 1px;
}
input[type="number"], select {
width: 100%;
background: #111;
border: 1px solid var(--border);
color: var(--accent);
padding: 10px;
font-family: var(--font);
font-size: 1em;
margin-bottom: 20px;
outline: none;
}
input:focus, select:focus {
border-color: var(--accent);
box-shadow: 0 0 10px rgba(0, 255, 136, 0.2);
}
button {
width: 100%;
background: var(--accent);
color: #000;
border: none;
padding: 15px;
font-family: var(--font);
font-weight: bold;
font-size: 1.1em;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 2px;
transition: all 0.2s;
}
button:hover {
background: #fff;
box-shadow: 0 0 20px var(--accent);
}
.result-row {
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid #333;
}
.result-val {
color: var(--accent);
font-weight: bold;
}
.data-source {
margin-top: 40px;
font-size: 0.8em;
opacity: 0.6;
border-top: 1px solid #333;
padding-top: 10px;
}
.spec-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.spec-table th, .spec-table td {
border: 1px solid #333;
padding: 10px;
text-align: left;
}
.spec-table th {
background: #111;
color: var(--accent);
}
.spec-table tr:hover {
background: #1a1a1a;
}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<header>
<img src="https://images.pexels.com/photos/11506881/pexels-photo-11506881.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"
alt="Cracked earth awaiting rain"
class="hero-img">
<h1>Evapotranspiration Matrix</h1>
<p>FAO-56 Penman-Monteith Implementation<br>Salt Lake City Baseline</p>
</header>
<section>
<h2>Input Parameters</h2>
<div class="matrix-grid">
<div class="input-panel">
<label>Air Temperature (°C)</label>
<input type="number" id="temp" placeholder="25.0" step="0.1">
<label>Relative Humidity (%)</label>
<input type="number" id="rh" placeholder="45" step="1">
<label>Wind Speed (m/s) @ 2m</label>
<input type="number" id="wind" placeholder="2.5" step="0.1">
<label>Solar Radiation (MJ/m²/day)</label>
<input type="number" id="rad" placeholder="20.5" step="0.1">
<label>Crop Coefficient (Kc)</label>
<select id="crop">
<option value="0.3">Alfalfa (Initial)</option>
<option value="1.15">Alfalfa (Mid-Season)</option>
<option value="0.9">Corn (Full Season)</option>
<option value="0.65">Lettuce (Early)</option>
<option value="1.2">Tomato (Peak)</option>
<option value="1.0">Reference Grass</option>
</select>
<button onclick="calculateET()">Compute Yield Loss</button>
</div>
<div class="output-panel">
<div class="result-row">
<span>Reference ET₀ (mm/day)</span>
<span class="result-val" id="res-et0">--.--</span>
</div>
<div class="result-row">
<span>Crop ETc (mm/day)</span>
<span class="result-val" id="res-etc">--.--</span>
</div>
<div class="result-row">
<span>Water Demand (L/m²/day)</span>
<span class="result-val" id="res-liters">--.--</span>
</div>
<div class="result-row">
<span>Vapor Pressure Deficit (kPa)</span>
<span class="result-val" id="res-vpd">--.--</span>
</div>
<div style="margin-top: 20px; border-top: 1px dashed #444; padding-top: 10px;">
<small>Status: <span id="status-text" style="color: #666">AWAITING INPUT</span></small>
</div>
</div>
</div>
</section>
<section>
<h2>Technical Specifications</h2>
<table class="spec-table">
<thead>
<tr>
<th>Parameter</th>
<th>Symbol</th>
<th>Units</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td>Slope Vapor Pressure Curve</td>
<td>Δ</td>
<td>kPa °C⁻¹</td>
<td>Tetens Eq.</td>
</tr>
<tr>
<td>Psychrometric Constant</td>
<td>γ</td>
<td>kPa °C⁻¹</td>
<td>Standard Atmosphere</td>
</tr>
<tr>
<td>Net Radiation</td>
<td>Rₙ</td>
<td>MJ m⁻² day⁻¹</td>
<td>Allen et al. (1998)</td>
</tr>
<tr>
<td>Soil Heat Flux</td>
<td>G</td>
<td>MJ m⁻² day⁻¹</td>
<td>Daily Avg ≈ 0</td>
</tr>
</tbody>
</table>
<div class="data-source">
<p><strong>Grounded In:</strong> FAO Irrigation and Drainage Paper 56.<br>
<strong>Calibrated For:</strong> Utah Valley Microclimates (40°N, 111°W).</p>
<p style="opacity: 0.5; font-size: 0.7em;">This tool calculates potential evapotranspiration using the standardized Penman-Monteith equation. It does not predict poetry. It predicts thirst.</p>
</div>
</section>
<script>
// Constants
const R = 8.314; // J/mol·K
const M_w = 18.015; // g/mol
function calculateET() {
const T = parseFloat(document.getElementById('temp').value);
const RH = parseFloat(document.getElementById('rh').value);
const u2 = parseFloat(document.getElementById('wind').value);
const Rs = parseFloat(document.getElementById('rad').value);
const Kc = parseFloat(document.getElementById('crop').value);
if (isNaN(T) || isNaN(RH) || isNaN(u2) || isNaN(Rs)) {
document.getElementById('status-text').innerText = "ERROR: MISSING VARIABLES";
return;
}
document.getElementById('status-text').innerText = "COMPUTATION COMPLETE";
// 1. Saturation Vapor Pressure (Tetens Equation)
// es = 0.6108 * exp((17.27 * T) / (T + 237.3))
const es = 0.6108 * Math.exp((17.27 * T) / (T + 237.3));
// 2. Slope of vapor pressure curve (delta)
const delta = (4098 * es) / Math.pow((T + 237.3), 2);
// 3. Actual Vapor Pressure
const ea = es * (RH / 100);
// 4. Vapor Pressure Deficit
const vpd = es - ea;
// 5. Psychrometric constant (gamma)
// gamma = (Cp * P) / (epsilon * lambda)
// Simplified for sea level: gamma = 0.665 * 10^-3 kPa/K
const gamma = 0.000665;
// 6. Net Radiation (Rn)
// Approximation: Rn = (1 - alpha) * Rs - outgoing LW
// alpha (albedo) approx 0.23 for grass
// Outgoing LW simplified: sigma * T^4 * emissivity
// We'll use a simplified conversion factor for daily MJ -> mm H2O energy equiv
const albedo = 0.23;
const Rn = (Rs * (1 - albedo)) * 0.9; // Rough adjustment
// 7. Soil Heat Flux (G) - negligible for daily avg
const G = 0;
// 8. Penman-Monteith Numerator
// delta * (Rn - G) + rho * Cp * (es - ea) / r_a
// Simplified aerodynamic term: 900 / (T + 273) * u2 * (es - ea)
const aeroTerm = (900 / (T + 273)) * u2 * vpd;
const numerator = (delta * Rn) + aeroTerm;
// 9. Denominator
// delta + gamma * (1 + 0.34 * u2)
const denominator = delta + (gamma * (1 + 0.34 * u2));
// 10. ET0 (mm/day)
const ET0 = numerator / denominator;
// 11. Crop ETc
const ETc = ET0 * Kc;
// Update UI
document.getElementById('res-et0').innerText = ET0.toFixed(2);
document.getElementById('res-etc').innerText = ETc.toFixed(2);
document.getElementById('res-liters').innerText = ETc.toFixed(2); // 1mm = 1L/m2
document.getElementById('res-vpd').innerText = vpd.toFixed(2);
}
</script>
</body>
</html>