Beta 10
New thermal charts
This commit is contained in:
+7
-6
@@ -219,12 +219,13 @@
|
||||
</p>
|
||||
<p>
|
||||
<strong>Indoor temperature.</strong> The <em>Indoors</em> column estimates the temperature
|
||||
inside a building with windows closed and no air conditioning, simulating wall conduction,
|
||||
window solar gain, and thermal mass hour by hour. You choose your building type from a dropdown
|
||||
inside a building with windows closed and no air conditioning, simulating retained warmth,
|
||||
window solar gain, internal gains, and thermal mass hour by hour. You choose your building type from a dropdown
|
||||
— brick, modern insulated, Victorian terrace, stone cottage, timber frame, top-floor flat, or
|
||||
conservatory — and the physics model adjusts accordingly. Each type has its own insulation
|
||||
level, thermal mass, and glazing characteristics, so a stone cottage and a conservatory behave
|
||||
very differently on a hot day. Indoor temperatures typically peak 2–4 hours after the outdoor
|
||||
level, thermal mass, retained warmth, and glazing characteristics, so a stone cottage and a conservatory behave
|
||||
very differently on a hot day. The model now lags toward a realistic hourly target rather
|
||||
than repeatedly adding solar heat, so indoor temperatures typically peak 2–4 hours after the outdoor
|
||||
peak, which is why a house can still feel stifling at 10 pm on a summer day. Tick
|
||||
<em>Managed</em> alongside the dropdown to switch to the heatwave-advice model: curtains
|
||||
closed by day to cut solar gain, windows opened whenever outdoor air is cooler than inside.
|
||||
@@ -340,7 +341,7 @@
|
||||
For managing indoor comfort without air conditioning. The indoor temperature column is
|
||||
central: select your building type from the dropdown (UK brick, modern insulated, Victorian
|
||||
terrace, stone cottage, timber frame, top-floor flat, or conservatory) and the physics model
|
||||
adjusts for that building's insulation, thermal mass, and glazing characteristics. Tick
|
||||
adjusts for that building's insulation, retained warmth, thermal mass, and glazing characteristics. Tick
|
||||
<strong>Managed</strong> to switch to the heatwave-advice model — curtains closed by day
|
||||
to block solar gain, windows opened whenever outdoor air is cooler than inside.
|
||||
Indoor temperatures typically peak 2–4 hours after the outdoor peak due to thermal mass,
|
||||
@@ -453,7 +454,7 @@
|
||||
<tr><td><strong>Soil moisture</strong></td><td>Volumetric water content of the top 1 cm of soil in m³/m³. Above 0.4 indicates saturated ground; below 0.2 is dry. Useful for assessing whether ground is workable, and for motorhome or caravan pitch suitability.</td></tr>
|
||||
<tr><td><strong>Concrete °C</strong></td><td>Estimated temperature of sun-exposed urban paving. Concrete absorbs more solar energy than grass and cannot cool itself through evaporation — surface temps can run 15–25 °C above air temperature on sunny days.</td></tr>
|
||||
<tr><td><strong>Vehicle °C</strong></td><td>Estimated ambient cabin temperature inside a sealed, parked vehicle — adjusted for your chosen vehicle type. Values above 35 °C are dangerous for children and pets; above 45 °C potentially fatal within minutes.</td></tr>
|
||||
<tr><td><strong>Indoors °C</strong></td><td>Estimated temperature inside a building with windows closed and no active cooling. Select your building type from the dropdown — brick, modern insulated, Victorian terrace, stone cottage, timber frame, top-floor flat, or conservatory. Each type has its own insulation, thermal mass, and glazing characteristics. Indoor peak typically lags the outdoor peak by 2–4 hours due to thermal mass.</td></tr>
|
||||
<tr><td><strong>Indoors °C</strong></td><td>Estimated temperature inside a building with windows closed and no active cooling. Select your building type from the dropdown — brick, modern insulated, Victorian terrace, stone cottage, timber frame, top-floor flat, or conservatory. Each type has its own insulation, retained warmth, thermal mass, and glazing characteristics. Indoor peak typically lags the outdoor peak by 2–4 hours due to thermal mass.</td></tr>
|
||||
<tr><td><strong>Managed °C</strong></td><td>The same building model with two interventions applied: curtains closed by day to block solar gain, and windows opened whenever outdoor air is cooler than inside. Toggle with the Managed tick next to the building dropdown. Shows how much passive cooling can reduce indoor heat compared to doing nothing.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
+40
-19
@@ -113,7 +113,7 @@ export function UTCIForecast() {
|
||||
// FLIP THE `false` BELOW TO `true` TO PREVIEW THE PRO EXPERIENCE.
|
||||
// When this is wired to real billing/auth, replace `useState(false)`
|
||||
// with a check against the logged-in user.
|
||||
const [isPro, setIsPro] = useState(true);
|
||||
const [isPro, setIsPro] = useState(false);
|
||||
|
||||
// How many days the free tier shows. Days beyond this get a 🔒.
|
||||
// Bump this number if you want to give free users more access.
|
||||
@@ -250,7 +250,7 @@ export function UTCIForecast() {
|
||||
soilM: { title: 'Soil Moisture', desc: 'Volumetric water content of the top 1 cm of soil (m³/m³). Values above 0.4 suggest saturated ground; below 0.2 indicates dry conditions.' },
|
||||
concreteT: { title: 'Concrete Surface', desc: 'Estimated temperature of sun-exposed urban concrete or paving. Concrete absorbs more solar energy than grass and cannot cool itself through evaporation — surface temps can run 15–25 °C above air temperature on sunny days.' },
|
||||
vehicleT: { title: 'Vehicle Interior', desc: 'Estimated ambient cabin temperature inside a parked vehicle. Cars heat rapidly through thin body panels and glass; motorhomes and caravans are modelled as insulated occupied living spaces with retained warmth, lower glass gain, and slower heat response. Dangerous for children and pets above 35 °C; potentially fatal above 45 °C.' },
|
||||
indoorT: { title: 'Indoors', desc: 'Estimated ambient temperature inside a typical UK brick house with windows closed and no air conditioning. Accounts for wall conduction, window solar gain, and thermal mass — indoor temperatures typically peak 2–4 hours after the outdoor peak.' },
|
||||
indoorT: { title: 'Indoors', desc: 'Estimated ambient temperature inside a selected building type with windows closed and no air conditioning. Accounts for retained warmth, window solar gain, internal gains, and thermal lag without repeatedly accumulating solar heat hour after hour.' },
|
||||
managedT: { title: 'Managed Indoors', desc: 'Estimated indoor temperature with curtains closed and windows opened when outdoor air is cooler than inside — the standard UK heatwave advice. Curtains block most direct solar gain; smart ventilation pulls the temperature down during cooler periods.' },
|
||||
};
|
||||
|
||||
@@ -1233,9 +1233,29 @@ export function UTCIForecast() {
|
||||
if (t < 50) return 'rgba(210, 70, 50,0.10)';
|
||||
return 'rgba(160, 30, 30,0.10)';
|
||||
};
|
||||
const scaleBg = (v, min, max, rgb, maxAlpha = 0.14) => {
|
||||
if (v == null || isNaN(v)) return 'transparent';
|
||||
const x = Math.max(0, Math.min(1, (v - min) / (max - min)));
|
||||
const a = 0.035 + x * maxAlpha;
|
||||
return `rgba(${rgb},${a.toFixed(3)})`;
|
||||
};
|
||||
const deltaBg = (v) => {
|
||||
if (v == null || isNaN(v)) return 'transparent';
|
||||
if (Math.abs(v) < 1) return 'transparent';
|
||||
const x = Math.min(1, Math.abs(v) / 12);
|
||||
const a = 0.035 + x * 0.13;
|
||||
return v > 0 ? `rgba(230,140,50,${a.toFixed(3)})` : `rgba(80,135,210,${a.toFixed(3)})`;
|
||||
};
|
||||
const burnBg = (mins) => {
|
||||
if (!isFinite(mins)) return 'transparent';
|
||||
if (mins >= 240) return 'rgba(110,180,110,0.07)';
|
||||
const x = Math.max(0, Math.min(1, (240 - mins) / 220));
|
||||
return `rgba(210,70,50,${(0.04 + x * 0.15).toFixed(3)})`;
|
||||
};
|
||||
// r.iso is the local wall-clock string from the API — slice it directly.
|
||||
const h24 = parseInt(r.iso.slice(11, 13), 10);
|
||||
const localHHMM = h24 === 0 ? '12am' : h24 < 12 ? `${h24}am` : h24 === 12 ? '12pm' : `${h24 - 12}pm`;
|
||||
const burnMins = sunburnMinutes(r.uv, skinType);
|
||||
return html`
|
||||
<tr key=${r.iso}
|
||||
class=${`${isNight ? 'is-night' : ''} ${isNow ? 'is-now' : ''}`.trim()}>
|
||||
@@ -1246,19 +1266,19 @@ export function UTCIForecast() {
|
||||
</span>
|
||||
</td>
|
||||
${visibleCols.air && html`<td style=${{ background: tempBg(r.Ta) }}>${r.Ta.toFixed(1)}</td>`}
|
||||
${visibleCols.rh && html`<td>${Math.round(r.RH)}</td>`}
|
||||
${visibleCols.dew && html`<td>${r.dew != null ? r.dew.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.rh && html`<td style=${{ background: scaleBg(r.RH, 30, 100, '70,145,200') }}>${Math.round(r.RH)}</td>`}
|
||||
${visibleCols.dew && html`<td style=${{ background: tempBg(r.dew) }}>${r.dew != null ? r.dew.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.soilT && html`
|
||||
<td style=${{ color: '#6b4a1c', background: tempBg(r.soilT0) }}>${r.soilT0 != null ? r.soilT0.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.soilT6 && html`
|
||||
<td style=${{ color: '#6b4a1c' }}>${r.soilT6 != null ? r.soilT6.toFixed(1) : '—'}</td>`}
|
||||
<td style=${{ color: '#6b4a1c', background: tempBg(r.soilT6) }}>${r.soilT6 != null ? r.soilT6.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.soilM && html`
|
||||
<td style=${{ color: '#2a6a90' }}>${r.soilM != null ? r.soilM.toFixed(3) : '—'}</td>`}
|
||||
<td style=${{ color: '#2a6a90', background: scaleBg(r.soilM, 0.12, 0.45, '50,125,190') }}>${r.soilM != null ? r.soilM.toFixed(3) : '—'}</td>`}
|
||||
${visibleCols.concreteT && html`
|
||||
<td style=${{ color: r.concreteT != null && r.concreteT > 40 ? '#c0392b' : r.concreteT != null && r.concreteT > 30 ? '#e67e22' : '#7f8c8d', fontWeight: 'bold', background: tempBg(r.concreteT) }}>
|
||||
${r.concreteT != null ? r.concreteT.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${visibleCols.wind && html`<td>
|
||||
${visibleCols.wind && html`<td style=${{ background: scaleBg(r.gust ?? r.va, 0, 18, '85,130,180') }}>
|
||||
${r.va.toFixed(1)}${r.gust != null && r.gust > r.va + 0.5
|
||||
? html`<span style=${{ opacity: 0.65, marginLeft: '4px' }}>(${r.gust.toFixed(1)})</span>`
|
||||
: ''}
|
||||
@@ -1269,40 +1289,41 @@ export function UTCIForecast() {
|
||||
<span class="wind-dir-label" style=${{ fontFamily: 'JetBrains Mono, monospace', fontSize: '11px' }}>${r.compass.label}</span>
|
||||
</span>
|
||||
</td>`}
|
||||
${visibleCols.cloud && html`<td>
|
||||
${visibleCols.cloud && html`<td style=${{ background: scaleBg(r.cc, 0, 100, '110,130,150') }}>
|
||||
<span style=${{ display: 'inline-flex', alignItems: 'center', gap: '6px', verticalAlign: 'middle' }}>
|
||||
<${CloudIcon} category=${r.cloudCat} elev=${r.elev} dt=${r.dt} size=${28} />
|
||||
<span>${Math.round(r.cc)}</span>
|
||||
</span>
|
||||
</td>`}
|
||||
${visibleCols.sun && html`<td>${r.elev > 0 ? r.elev.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.direct && html`<td>${Math.round(r.dir)}</td>`}
|
||||
${visibleCols.diffuse && html`<td>${Math.round(r.dif)}</td>`}
|
||||
${visibleCols.tmrt && html`<td>${r.Tmrt.toFixed(1)}</td>`}
|
||||
${visibleCols.sun && html`<td style=${{ background: scaleBg(Math.max(0, r.elev), 0, 70, '225,160,45') }}>${r.elev > 0 ? r.elev.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.direct && html`<td style=${{ background: scaleBg(r.dir, 0, 850, '230,155,35') }}>${Math.round(r.dir)}</td>`}
|
||||
${visibleCols.diffuse && html`<td style=${{ background: scaleBg(r.dif, 0, 450, '230,190,70') }}>${Math.round(r.dif)}</td>`}
|
||||
${visibleCols.tmrt && html`<td style=${{ background: tempBg(r.Tmrt) }}>${r.Tmrt.toFixed(1)}</td>`}
|
||||
${visibleCols.delta && html`
|
||||
<td style=${{
|
||||
color: delta > 3 ? '#c8601a' : delta < -3 ? '#3f73c4' : '#4a3218',
|
||||
fontWeight: 600,
|
||||
background: deltaBg(delta),
|
||||
}}>
|
||||
${delta > 0 ? '+' : ''}${delta.toFixed(1)}
|
||||
</td>`}
|
||||
${visibleCols.utci && html`
|
||||
<td>
|
||||
<td style=${{ background: tempBg(r.utci) }}>
|
||||
<span class="utci-cell" style=${{ background: cat.bg, color: cat.fg }}>
|
||||
${r.utci.toFixed(1)}
|
||||
</span>
|
||||
</td>`}
|
||||
${visibleCols.uvA && html`
|
||||
<td style=${{ color: r.uvA > 0 ? '#c8922a' : '#4a3218' }}>
|
||||
<td style=${{ color: r.uvA > 0 ? '#c8922a' : '#4a3218', background: scaleBg(r.uvA, 0, 8, '220,155,40') }}>
|
||||
${r.uvA > 0 ? r.uvA.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${visibleCols.uvB && html`
|
||||
<td style=${{ color: r.uvB > 0 ? '#c44a3a' : '#4a3218' }}>
|
||||
<td style=${{ color: r.uvB > 0 ? '#c44a3a' : '#4a3218', background: scaleBg(r.uvB, 0, 1.2, '210,70,50') }}>
|
||||
${r.uvB > 0 ? r.uvB.toFixed(2) : '—'}
|
||||
</td>`}
|
||||
${visibleCols.burn && html`
|
||||
<td style=${{ color: r.uv > 0 ? (sunburnMinutes(r.uv, skinType) < 30 ? '#c44a3a' : '#c8601a') : '#4a3218' }}>
|
||||
${burnLabel(sunburnMinutes(r.uv, skinType))}
|
||||
<td style=${{ color: r.uv > 0 ? (burnMins < 30 ? '#c44a3a' : '#c8601a') : '#4a3218', background: burnBg(burnMins) }}>
|
||||
${burnLabel(burnMins)}
|
||||
</td>`}
|
||||
${visibleCols.vehicleT && html`
|
||||
<td style=${{ color: r.vehicleT != null && r.vehicleT > 45 ? '#c0392b' : r.vehicleT != null && r.vehicleT > 35 ? '#e67e22' : '#7f8c8d', fontWeight: 'bold', background: tempBg(r.vehicleT) }}>
|
||||
@@ -1317,7 +1338,7 @@ export function UTCIForecast() {
|
||||
${r.managedT != null ? r.managedT.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${visibleCols.precip && html`
|
||||
<td>
|
||||
<td style=${{ background: r.snow > 0 ? scaleBg(r.snow, 0, 4, '90,140,210') : scaleBg(r.precip, 0, 8, '70,145,200') }}>
|
||||
<span style=${{ display: 'inline-flex', alignItems: 'center', gap: '5px', verticalAlign: 'middle' }}>
|
||||
<${PrecipIcon} precip=${r.precip} snow=${r.snow} size=${28} />
|
||||
<span style=${{ color: r.snow > 0 ? '#2a5fa8' : r.precip > 0 ? '#2a6a90' : '#7a5c30' }}>
|
||||
@@ -1326,7 +1347,7 @@ export function UTCIForecast() {
|
||||
</span>
|
||||
</td>`}
|
||||
${visibleCols.utciP && html`
|
||||
<td style=${{ background: 'rgba(180,215,250,0.10)' }}>
|
||||
<td style=${{ background: tempBg(r.utciAdj) }}>
|
||||
<span class="utci-cell utci-cell-hero" style=${{ background: adjCat.bg, color: adjCat.fg }}>
|
||||
${r.utciAdj.toFixed(1)}
|
||||
</span>
|
||||
|
||||
+19
-25
@@ -86,10 +86,11 @@ export function calcConcreteTemp(Ta, globalRad, windSpeed) {
|
||||
//
|
||||
// THERMAL LAG
|
||||
// Brick and concrete have high thermal mass — the house responds
|
||||
// slowly to outdoor temperature swings. This function takes a
|
||||
// weighted average of the current hour's heat load and the
|
||||
// previous few hours', giving the characteristic lag where indoor
|
||||
// temperature peaks 2–4 hours after the outdoor peak.
|
||||
// slowly to outdoor temperature swings. Each hour builds a realistic
|
||||
// target temperature from outdoor air, window solar gain, retained
|
||||
// warmth, and internal gains, then the room temperature lags toward
|
||||
// that target. This avoids runaway accumulation while still giving
|
||||
// the characteristic late-day indoor peak.
|
||||
// Call calcIndoorTempPass() on the full hourly arrays after
|
||||
// building rows — it returns a per-hour indoor temp array.
|
||||
//
|
||||
@@ -125,14 +126,14 @@ function _houseHeatLoad(Ta, globalRad, solElev) {
|
||||
// buildingType must be a key of BUILDING_TYPES; defaults to 'brick'.
|
||||
export function calcIndoorTempPass(TaArr, globArr, elevArr, buildingType = 'brick') {
|
||||
const preset = BUILDING_TYPES[buildingType] || BUILDING_TYPES.brick;
|
||||
const { uWall, lagHours, glazingRatio, gValue, orientFactor } = preset;
|
||||
const { lagHours, glazingRatio, gValue, orientFactor, solarScale, baseTemp, internalGain, retainedScale } = preset;
|
||||
|
||||
const n = TaArr.length;
|
||||
const result = new Array(n);
|
||||
const alpha = 1 - Math.exp(-1 / lagHours); // per-hour blending weight
|
||||
|
||||
// Seed indoor temp to first outdoor temp
|
||||
let Ti = TaArr[0] ?? 15;
|
||||
// Seed to a plausible occupied indoor baseline rather than outdoor air.
|
||||
let Ti = Math.max(TaArr[0] ?? 15, baseTemp ?? 16);
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
const Ta = TaArr[i] ?? Ti;
|
||||
@@ -141,16 +142,12 @@ export function calcIndoorTempPass(TaArr, globArr, elevArr, buildingType = 'bric
|
||||
// Solar gain through windows (W/m² effective)
|
||||
const solarGain = glob * glazingRatio * gValue * orientFactor;
|
||||
|
||||
// Conductive heat flow through walls: proportional to (Ta - Ti)
|
||||
const conductionGain = uWall * (Ta - Ti);
|
||||
const retainedWarmth = Math.max(0, (baseTemp ?? 16) - Ta) * (retainedScale ?? 0.35);
|
||||
const target = Ta + solarGain * (solarScale ?? 0.1) + retainedWarmth + (internalGain ?? 0.7);
|
||||
|
||||
// Heat capacity proxy: how many °C does 1 W/m² raise the indoor air?
|
||||
// Typical 90 m² house ≈ 0.15; conservatory much lower (less thermal mass).
|
||||
const heatCapProxy = 0.15;
|
||||
const Ti_instant = Ti + (conductionGain + solarGain) * heatCapProxy;
|
||||
|
||||
// Apply thermal lag: blend toward Ti_instant at the building's time constant
|
||||
Ti = Ti + alpha * (Ti_instant - Ti);
|
||||
// Apply thermal lag: blend toward the hour's target instead of adding
|
||||
// solar gain repeatedly onto the previous indoor temperature.
|
||||
Ti = Ti + alpha * (target - Ti);
|
||||
|
||||
// Can't be colder than outdoor (house doesn't actively cool)
|
||||
result[i] = Math.max(Math.min(Ti, 55), Math.min(Ta, Ti));
|
||||
@@ -182,13 +179,13 @@ export function calcIndoorTempPass(TaArr, globArr, elevArr, buildingType = 'bric
|
||||
// buildingType must be a key of BUILDING_TYPES; defaults to 'brick'.
|
||||
export function calcManagedIndoorTempPass(TaArr, globArr, elevArr, buildingType = 'brick') {
|
||||
const preset = BUILDING_TYPES[buildingType] || BUILDING_TYPES.brick;
|
||||
const { uWall, lagHours, glazingRatio, gValue, orientFactor, curtainBlock, ventAlpha } = preset;
|
||||
const { lagHours, glazingRatio, gValue, orientFactor, curtainBlock, ventAlpha, solarScale, baseTemp, internalGain, retainedScale } = preset;
|
||||
|
||||
const n = TaArr.length;
|
||||
const result = new Array(n);
|
||||
const alpha = 1 - Math.exp(-1 / lagHours);
|
||||
|
||||
let Ti = TaArr[0] ?? 15;
|
||||
let Ti = Math.max(TaArr[0] ?? 15, baseTemp ?? 16);
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
const Ta = TaArr[i] ?? Ti;
|
||||
@@ -197,14 +194,11 @@ export function calcManagedIndoorTempPass(TaArr, globArr, elevArr, buildingType
|
||||
// Solar gain — curtains block curtainBlock fraction
|
||||
const solarGain = glob * glazingRatio * gValue * orientFactor * (1 - curtainBlock);
|
||||
|
||||
// Wall conduction (unchanged from unmanaged model)
|
||||
const conductionGain = uWall * (Ta - Ti);
|
||||
const retainedWarmth = Math.max(0, (baseTemp ?? 16) - Ta) * (retainedScale ?? 0.35);
|
||||
const target = Ta + solarGain * (solarScale ?? 0.1) + retainedWarmth + (internalGain ?? 0.7);
|
||||
|
||||
const heatCapProxy = 0.15;
|
||||
const Ti_instant = Ti + (conductionGain + solarGain) * heatCapProxy;
|
||||
|
||||
// Apply thermal lag
|
||||
Ti = Ti + alpha * (Ti_instant - Ti);
|
||||
// Apply thermal lag toward the managed target.
|
||||
Ti = Ti + alpha * (target - Ti);
|
||||
|
||||
// Smart ventilation: only open windows when outside is cooler
|
||||
if (Ta < Ti) {
|
||||
|
||||
+13
-7
@@ -166,15 +166,21 @@ export const VEHICLE_TYPES = {
|
||||
// closed). Thick lined curtains ≈ 0.80; blinds ≈ 0.50.
|
||||
// ventAlpha — Blending weight per hour when smart ventilation is open.
|
||||
// Higher = more air changes per hour.
|
||||
// solarScale — Converts effective window solar gain into an indoor
|
||||
// temperature lift. Lower values mean more thermal mass.
|
||||
// baseTemp — Occupied/retained warmth baseline for normal homes.
|
||||
// internalGain — Small heat gain from people, appliances, and background use.
|
||||
// retainedScale — How strongly the building holds above-outdoor warmth in
|
||||
// cool conditions. Higher = better retained warmth.
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
export const BUILDING_TYPES = {
|
||||
brick: { name: 'Brick (typical)', uWall: 0.35, lagHours: 4, glazingRatio: 0.16, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.80, ventAlpha: 0.25 },
|
||||
modern: { name: 'Modern / Well insulated', uWall: 0.18, lagHours: 5, glazingRatio: 0.20, gValue: 0.30, orientFactor: 0.50, curtainBlock: 0.70, ventAlpha: 0.20 },
|
||||
victorian: { name: 'Victorian Terrace', uWall: 0.55, lagHours: 5, glazingRatio: 0.12, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.80, ventAlpha: 0.30 },
|
||||
stone: { name: 'Stone / Granite Cottage', uWall: 0.45, lagHours: 7, glazingRatio: 0.10, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.75, ventAlpha: 0.25 },
|
||||
timber: { name: 'Timber Frame / New Build', uWall: 0.22, lagHours: 2, glazingRatio: 0.22, gValue: 0.35, orientFactor: 0.50, curtainBlock: 0.70, ventAlpha: 0.35 },
|
||||
flat: { name: 'Top-floor Flat', uWall: 0.40, lagHours: 3, glazingRatio: 0.18, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.75, ventAlpha: 0.20 },
|
||||
conservatory:{ name: 'Conservatory / Sun Room', uWall: 1.20, lagHours: 1, glazingRatio: 0.70, gValue: 0.72, orientFactor: 0.70, curtainBlock: 0.50, ventAlpha: 0.50 },
|
||||
brick: { name: 'Brick (typical)', uWall: 0.35, lagHours: 4, glazingRatio: 0.16, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.80, ventAlpha: 0.25, solarScale: 0.10, baseTemp: 16.5, internalGain: 0.8, retainedScale: 0.35 },
|
||||
modern: { name: 'Modern / Well insulated', uWall: 0.18, lagHours: 5, glazingRatio: 0.20, gValue: 0.30, orientFactor: 0.50, curtainBlock: 0.70, ventAlpha: 0.20, solarScale: 0.08, baseTemp: 17.0, internalGain: 0.8, retainedScale: 0.55 },
|
||||
victorian: { name: 'Victorian Terrace', uWall: 0.55, lagHours: 5, glazingRatio: 0.12, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.80, ventAlpha: 0.30, solarScale: 0.10, baseTemp: 16.0, internalGain: 0.7, retainedScale: 0.25 },
|
||||
stone: { name: 'Stone / Granite Cottage', uWall: 0.45, lagHours: 7, glazingRatio: 0.10, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.75, ventAlpha: 0.25, solarScale: 0.08, baseTemp: 15.5, internalGain: 0.6, retainedScale: 0.40 },
|
||||
timber: { name: 'Timber Frame / New Build', uWall: 0.22, lagHours: 2, glazingRatio: 0.22, gValue: 0.35, orientFactor: 0.50, curtainBlock: 0.70, ventAlpha: 0.35, solarScale: 0.08, baseTemp: 17.0, internalGain: 0.8, retainedScale: 0.45 },
|
||||
flat: { name: 'Top-floor Flat', uWall: 0.40, lagHours: 3, glazingRatio: 0.18, gValue: 0.63, orientFactor: 0.50, curtainBlock: 0.75, ventAlpha: 0.20, solarScale: 0.11, baseTemp: 17.0, internalGain: 0.9, retainedScale: 0.45 },
|
||||
conservatory:{ name: 'Conservatory / Sun Room', uWall: 1.20, lagHours: 1, glazingRatio: 0.70, gValue: 0.72, orientFactor: 0.70, curtainBlock: 0.50, ventAlpha: 0.50, solarScale: 0.045, baseTemp: 12.0, internalGain: 0.2, retainedScale: 0.05 },
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user