diff --git a/assets/js/compute.js b/assets/js/compute.js index 521fbe5..25ba062 100644 --- a/assets/js/compute.js +++ b/assets/js/compute.js @@ -55,11 +55,12 @@ export function buildHourlyRows({ forecast, airQuality, location, vehicleType, v const soilT0 = h.soil_temperature_0cm ? h.soil_temperature_0cm[i] : null; const soilT6 = h.soil_temperature_6cm ? h.soil_temperature_6cm[i] : null; const soilM = h.soil_moisture_0_to_1cm ? h.soil_moisture_0_to_1cm[i] : null; - // Scale radiation by cloud cover before passing to concrete calc. - // shortwave_radiation and cloud_cover are separate forecast fields that - // don't always agree — this prevents hot concrete values on cloudy days. - // 100% cloud -> 85% reduction, 0% cloud -> full radiation. - const effectiveRad = glob * (1 - (cc / 100) * 0.85); + // Use direct_radiation (beam sunlight) + a fraction of diffuse for concrete. + // direct_radiation is zero on fully overcast days — far more accurate than + // shortwave_radiation which can be unreliably high even at 100% cloud cover. + // Diffuse (scattered light through cloud) contributes ~20% as much heat to + // a surface as direct beam, so we weight it accordingly. + const effectiveRad = dir + dif * 0.2; const concreteT = calcConcreteTemp(Ta, effectiveRad, va); // iso is a local wall-clock string e.g. "2026-05-13T14:00" (no Z). // For display we slice the string directly — no Date object needed.