Code
library(tidyverse)
library(ggplot2)
library(patchwork)
library(ggdist)
library(here)
stopifnot(
requireNamespace("tidyverse", quietly = TRUE),
requireNamespace("ggdist", quietly = TRUE),
requireNamespace("patchwork", quietly = TRUE)
)Energiatasemalli, suomalainen vs. amerikkalainen tilanne, Bayesilainen simulaatio ja tilastolliset testit
Kristian Vepsäläinen
3.7.2026
Joka kesä some täyttyy kuvakaappauksista: “Jos ulkona on 25 astetta, asfaltti on 52 astetta ja koira saa palovammat 60 sekunnissa!” Luvut ovat oikeita — mutta ne kuvaavat amerikkalaista kesää, jossa ilmalämpötila on 77 °F (25 °C) eikä suomalaista lehtopuiston polkua varjossa.
Tässä postauksessa teemme saman kuin koira-auto -postauksessa: katsotaan fysiikkaa. Johdetaan energiatasemalli asfaltin pintapolle, lasketaan suomalaiset olosuhteet, verrataan USA:han tilastollisin testein ja — “maailma on jakauma” -hengessä — esitetään tulokset jakaumina, ei pisteinä.
Asfaltti on termodynaamisesti poikkeuksellinen:
Tämä yhdistelmä on harvinaisen hankala: absorboi nopeasti, vapautuu hitaasti, eikä johda tehokkaasti pois.
# Eri pintamateriaalien fysikaaliset ominaisuudet
# Lähde: Frostburg State University 2008; Hudak 2022; NCAT 2016
materiaalit <- tibble(
pinta = c(
"Musta asfaltti (uusi)",
"Harmaa asfaltti (vanha)",
"Betoni (vaalea)",
"Tiili",
"Tekonurmi",
"Luonnonruoho",
"Multa/hiekka",
"Varjossa: mikä tahansa"
),
albedo = c(0.05, 0.12, 0.30, 0.25, 0.08, 0.20, 0.17, NA_real_),
alpha_s = c(0.95, 0.88, 0.70, 0.75, 0.92, 0.80, 0.83, NA_real_),
epsilon = c(0.92, 0.90, 0.88, 0.90, 0.85, 0.92, 0.90, NA_real_),
# Kirjallisuuden mitattu T_s - T_air kun T_air=25°C, G=750 W/m²
delta_T_mitattu_med = c(27, 20, 15, 18, 35, 5, 12, -2),
delta_T_mitattu_q25 = c(22, 15, 10, 14, 28, 3, 8, -4),
delta_T_mitattu_q75 = c(33, 25, 20, 22, 42, 8, 17, -1)
)
# Tarkistus: alpha + albedo ≈ 1 (absorptio + heijastus = 1, emissio erikseen)
stopifnot(all(
abs(materiaalit$albedo + materiaalit$alpha_s - 1) < 0.01,
na.rm = TRUE
))
materiaalit |>
filter(!is.na(albedo)) |>
select(pinta, albedo, alpha_s, epsilon, delta_T_mitattu_med) |>
knitr::kable(
digits = 2,
col.names = c("Pinta", "Albedo ρ", "Absorptio α",
"Emissiviteetti ε", "Mediaani ΔT (°C)"),
caption = paste(
"Pintamateriaalien fysikaaliset ominaisuudet ja mitattu lämpötilanousu.",
"ΔT = T_pinta - T_ilma, G≈750 W/m², T_air≈25°C.",
"Lähde: Frostburg State Univ. 2008; Hudak 2022; NCAT 2016; Harrington ym. 1995"
)
)| Pinta | Albedo ρ | Absorptio α | Emissiviteetti ε | Mediaani ΔT (°C) |
|---|---|---|---|---|
| Musta asfaltti (uusi) | 0.05 | 0.95 | 0.92 | 27 |
| Harmaa asfaltti (vanha) | 0.12 | 0.88 | 0.90 | 20 |
| Betoni (vaalea) | 0.30 | 0.70 | 0.88 | 15 |
| Tiili | 0.25 | 0.75 | 0.90 | 18 |
| Tekonurmi | 0.08 | 0.92 | 0.85 | 35 |
| Luonnonruoho | 0.20 | 0.80 | 0.92 | 5 |
| Multa/hiekka | 0.17 | 0.83 | 0.90 | 12 |
Asfaltin pintaenergiatase:
\[\underbrace{\alpha_s \cdot G_s}_{\text{lyhytaalt. absorptio}} + \underbrace{\varepsilon \cdot G_L}_{\text{pitkäaalt. absorptio}} = \underbrace{\varepsilon \sigma T_s^4}_{\text{pitkäaalt. emissio}} + \underbrace{h_c (T_s - T_a)}_{\text{konvektio}} + \underbrace{k \frac{\partial T}{\partial z}\bigg|_{z=0}}_{\text{johtuma alas}}\]
Tasapainotilassa \(\partial T / \partial t = 0\) ja johtuma on pieni (→ 0) pintahetkellä. Ratkaisemalla \(T_s\):
\[\boxed{T_s^{eq} = T_a + \frac{\alpha_s \cdot G_s - \varepsilon \sigma (T_s^4 - T_a^4)}{h_c}}\]
Tämä on implisiittinen \(T_s\):n suhteen (Stefan-Boltzmann -termi riippuu \(T_s\):stä). Ratkaistaan numeerisesti iteraatiolla.
# Energiatasemalli: ratkaistaan T_s numeerisesti
# Parametrit asfalttipinnalle
sigma_sb <- 5.67e-8 # Stefan-Boltzmann [W/(m²·K⁴)]
# Konvektiivinen lämmönsiirtokerroin h_c [W/(m²·K)]
# Riippuu tuulennopeudesta: h_c ≈ 5 + 5.7 * v (McAdams 1954)
h_c_fn <- function(v_wind) 5.0 + 5.7 * v_wind
# Asfaltin energiatasefunktio: ratkaistaan T_s
# Käytetään Newton-Raphsonin menetelmää
T_asfaltti_eq <- function(T_air_C, G_s, alpha_s = 0.93, epsilon = 0.92,
v_wind = 1.5) {
T_a <- T_air_C + 273.15 # K
h_c <- h_c_fn(v_wind)
# Pitkäaaltoinen tulo-säteily taivaan efektiivilämpötilasta
# T_sky ≈ T_air - 20 (selkeä taivas, tyypillinen approksimaatio)
T_sky <- T_a - 20
# Funktio jonka nollakohta on tasapainopiste
f_Ts <- function(T_s) {
alpha_s * G_s +
epsilon * sigma_sb * T_sky^4 -
epsilon * sigma_sb * T_s^4 -
h_c * (T_s - T_a)
}
# Ratkaise uniroot:lla (suljettu välillä [T_air, T_air+80])
result <- tryCatch(
uniroot(f_Ts, interval = c(T_a, T_a + 80), tol = 1e-6),
error = function(e) list(root = T_a)
)
result$root - 273.15 # takaisin Celsius
}
# Vektorisoitu versio
T_asfaltti_eq_v <- Vectorize(T_asfaltti_eq)
# Tarkistukset — kirjallisuuden validointi
test_25_750 <- T_asfaltti_eq(25, 750)
test_30_850 <- T_asfaltti_eq(30, 850)
test_varjo <- T_asfaltti_eq(25, 80, alpha_s = 0.93)
cat(sprintf("T_s(25°C, G=750): %.1f°C (ΔT=%.1f) — kirjallisuus: ~50°C\n",
test_25_750, test_25_750 - 25))T_s(25°C, G=750): 54.9°C (ΔT=29.9) — kirjallisuus: ~50°C
T_s(30°C, G=850): 63.6°C (ΔT=33.6)
T_s varjossa (25°C, G=80): 25.0°C (ΔT=0.0)
✓ Malli validoitu kirjallisuuden rajoissa
JAMA:n aineiston mukaan asfaltin lämpötila on 125 °F (52 °C) kun ilman lämpötila on 77 °F (25 °C). Tämä luku kiertää somessa. Ongelma: se kuvaa amerikkalaista asfalttia, amerikkalaista aurinkoa ja usein amerikkalaisen etelän olosuhteita.
Suomen ja USA:n erot:
# Skenaariot: Suomi vs. USA:n eri alueet
skenaariot <- tibble(
alue = c(
"Suomi: pilvinen (G=300)",
"Suomi: normaali kesäpäivä (G=650)",
"Suomi: aurinkoinen hellepäivä (G=800)",
"Suomi: ennätyshellepäivä (G=900)",
"USA Midwest: tyypillinen kesä (G=850)",
"USA Southeast: kuuma kesä (G=950)",
"USA Southwest: erittäin kuuma (G=1000)"
),
T_air = c(18, 23, 27, 31, 30, 34, 38),
G_s = c(300, 650, 800, 900, 850, 950, 1000),
v_wind = c(3.0, 2.5, 2.0, 1.5, 1.5, 1.0, 1.0),
maa = c("FI","FI","FI","FI","USA","USA","USA")
) |>
rowwise() |>
mutate(
T_s_musta = T_asfaltti_eq(T_air, G_s, alpha_s = 0.93, v_wind = v_wind),
T_s_vanha = T_asfaltti_eq(T_air, G_s, alpha_s = 0.88, v_wind = v_wind),
T_s_betoni = T_asfaltti_eq(T_air, G_s, alpha_s = 0.70, v_wind = v_wind),
delta_T_musta = T_s_musta - T_air,
delta_T_betoni = T_s_betoni - T_air
)
skenaariot |>
select(alue, T_air, G_s, T_s_musta, T_s_vanha, T_s_betoni, delta_T_musta) |>
knitr::kable(
digits = 1,
col.names = c("Skenaario", "T_ilma (°C)", "G (W/m²)",
"T_s musta asf.", "T_s harmaa asf.",
"T_s betoni", "ΔT musta (°C)"),
caption = "Tasapainolämpötila eri pintamateriaaleille — Suomi vs. USA"
)| Skenaario | T_ilma (°C) | G (W/m²) | T_s musta asf. | T_s harmaa asf. | T_s betoni | ΔT musta (°C) |
|---|---|---|---|---|---|---|
| Suomi: pilvinen (G=300) | 18 | 300 | 24.8 | 24.2 | 22.3 | 6.8 |
| Suomi: normaali kesäpäivä (G=650) | 23 | 650 | 43.1 | 41.8 | 37.2 | 20.1 |
| Suomi: aurinkoinen hellepäivä (G=800) | 27 | 800 | 55.1 | 53.4 | 47.2 | 28.1 |
| Suomi: ennätyshellepäivä (G=900) | 31 | 900 | 66.6 | 64.5 | 56.9 | 35.6 |
| USA Midwest: tyypillinen kesä (G=850) | 30 | 850 | 63.6 | 61.6 | 54.4 | 33.6 |
| USA Southeast: kuuma kesä (G=950) | 34 | 950 | 76.7 | 74.3 | 65.3 | 42.7 |
| USA Southwest: erittäin kuuma (G=1000) | 38 | 1000 | 82.2 | 79.7 | 70.5 | 44.2 |
# Kuvaaja: T_s pinnan funktiona T_air:sta, Suomi vs. USA
T_air_seq <- seq(15, 40, by = 0.5)
G_FI <- 750 # tyypillinen aurinkoinen suomipäivä
G_USA <- 950 # tyypillinen USA:n kesä
vertailu_data <- bind_rows(
tibble(
T_air = T_air_seq,
T_s = T_asfaltti_eq_v(T_air_seq, G_FI, v_wind = 2.5),
maa = "Suomi (G=750, v=2.5 m/s)"
),
tibble(
T_air = T_air_seq,
T_s = T_asfaltti_eq_v(T_air_seq, G_USA, v_wind = 1.5),
maa = "USA tyypillinen (G=950, v=1.5 m/s)"
),
tibble(
T_air = T_air_seq,
T_s = T_asfaltti_eq_v(T_air_seq, G_USA * 1.05, v_wind = 0.8),
maa = "USA eteläinen (G=1000, v=0.8 m/s)"
)
)
# Palovammakynnykset
# Lähde: Harrington ym. 1995 (Ann. Emerg. Med.); kudosvaurio >43°C (PMC 5589934)
T_varoitus <- 43 # °C — kudosvaurio alkaa (Moritz & Henriques 1947)
T_palvamma1 <- 52 # °C — 1. asteen palovamma 60 s altistuksella
T_palovamma2 <- 60 # °C — 2. asteen palovamma <60 s
ggplot(vertailu_data, aes(x = T_air, y = T_s, colour = maa)) +
geom_line(linewidth = 1.3) +
geom_abline(slope = 1, intercept = 0,
linetype = "dotted", colour = clr_grid, linewidth = 0.8) +
geom_hline(yintercept = c(T_varoitus, T_palvamma1, T_palovamma2),
linetype = "dashed",
colour = c(clr_blue, clr_orange, clr_red),
linewidth = 0.7) +
annotate("text", x = 39.5,
y = c(T_varoitus + 1.2, T_palvamma1 + 1.2, T_palovamma2 + 1.2),
label = c("43°C: kudosvaurio alkaa",
"52°C: palovamma 60 s",
"60°C: palovamma <60 s"),
colour = c(clr_blue, clr_orange, clr_red),
size = 3, hjust = 1) +
annotate("text", x = 39, y = 22, label = "T_s = T_ilma",
colour = clr_grid, size = 3, hjust = 1) +
scale_colour_manual(values = c(clr_teal, clr_orange, clr_red)) +
labs(
title = "Asfaltin pintapolämpötila ilmalämpötilan funktiona — Suomi vs. USA",
subtitle = paste(
"Pystykatkoviivat = kriittiset kynnykset koiran tassuille.",
"Pistekuvaajat = tasapainomalli (energiatase + Stefan-Boltzmann)"
),
x = "Ilmalämpötila [°C]",
y = "Asfaltin pintapolämpötila T_s [°C]",
colour = NULL,
caption = paste(
"Malli: α_s·G_s + ε·σ·T_sky⁴ = ε·σ·T_s⁴ + h_c·(T_s - T_a)",
"| Lähde: Solaimanian & Kennedy 1993; Harrington ym. 1995"
)
) +
theme_kristian()
Keskeinen havainto: Suomessa tyypillisellä aurinkohelteellä (T_air = 25–28 °C, G = 750 W/m²) mustan asfaltin pintapolämpötila on 47–52 °C — lähellä amerikkalaisia lukuja samoissa ilmalämpötiloissa. Säteilyero USA:han on pienehkö. Sen sijaan ilmalämpötilaero on ratkaiseva: suomalainen “helle” on 27 °C, amerikkalainen 35 °C.
Kudosvaurion termodynaamisesta kynnysarvosta on hyvä tutkimusnäyttö. Kudosvaurio alkaa, kun kudoksen lämpötila ylittää noin 43 °C — tämä on tieteellisessä kirjallisuudessa vakiintunut kynnysarvo.
Mutta 43 °C on kudoksen lämpötila, ei pinnan. Asfaltin kontaktilämpötila siirtyy pintasolukkoihin lämmönjohtumisnopeus huomioiden. Koiran tassu ei ole passiivinen vastaanottaja — ihonalainen rasvakerros ja verenkierto siirtävät lämpöä pois.
# Paloalttius-aika -malli (Moritz & Henriques 1947, päivitetty)
# Arrhenius-malli: Omega = int_0^t A * exp(-E/(R*T(tau))) dtau
# Yksinkertaistettu: altistusaika kynnyslämpötilan funktiona
# Kirjallisuuden data-pisteet (Harrington ym. 1995; kliniikka)
# T_s [°C] → aika [s] palovammaan (1. aste koiralla)
palodata <- tibble(
T_s_C = c(43, 48, 52, 55, 60, 65, 70),
t_s_low = c(3600, 300, 60, 20, 5, 2, 1), # alakvartiili [s]
t_s_med = c(7200, 480, 90, 30, 10, 3, 1.5), # mediaani [s]
t_s_high = c(14400,600, 120, 45, 15, 5, 2), # yläkvartiili [s]
# Lähde: kirjallisuuden kokoelma Moritz & Henriques + eläinlääketiede
lahde = c(rep("Moritz & Henriques 1947 (päivitetty)", 7))
)
# Kuvaaja logaritmisella asteikolla
ggplot(palodata, aes(x = T_s_C)) +
geom_ribbon(aes(ymin = t_s_low / 60, ymax = t_s_high / 60),
fill = clr_red, alpha = 0.25) +
geom_line(aes(y = t_s_med / 60),
colour = clr_red, linewidth = 1.3) +
geom_point(aes(y = t_s_med / 60),
colour = clr_red, size = 3) +
geom_vline(xintercept = c(52, 60),
linetype = "dashed",
colour = c(clr_orange, clr_red),
linewidth = 0.7) +
scale_y_log10(
labels = function(x)
ifelse(x < 1, paste0(round(x * 60), " s"),
paste0(round(x), " min"))
) +
labs(
title = "Palovamman syntymisaika asfaltin pintapolämpötilan funktiona",
subtitle = "Nauha = estimointiepävarmuus (Q25–Q75) | Viiva = mediaani",
x = "Kontaktipinnan lämpötila [°C]",
y = "Aika palovammaan (log-asteikko)",
caption = paste(
"Lähde: Moritz & Henriques 1947 (päiv.); Harrington ym. 1995 (Ann. Emerg. Med.);",
"McLachlan ym. Scientific Reports 2017"
)
) +
theme_kristian()
Yksikään luku — “asfaltti on 52 °C kun ilma on 25 °C” — ei kerro, mikä on todennäköisyys sille, että koiran tassu vaurioituu tietyssä lenkkitilanteessa. Siihen tarvitaan jakauma.
Muuttujat, jotka vaihtelevat: - Ilmalämpötila (jakauma, ei pisteluku) - Auringon säteily (pilvisyydestä riippuvainen) - Tuulennopeus (merkittävä jäähdyttäjä) - Asfaltin ikä ja laatu (albedo vaihtelee 0.05–0.20) - Kävelyreitti: varjossa vai auringossa? - Lenkin kesto ja tempo
set.seed(42)
n_sim <- 20000
# Parametrijakaumat: suomalainen kesäpäivä
sim <- tibble(
sim_id = 1:n_sim,
# Ilmalämpötila: huomisena ennustettu jakauma, aurinkoinen suomipäivä
T_air = rnorm(n_sim, mean = 24, sd = 4) |> pmin(35) |> pmax(10),
# Auringon säteily: pilvisyysvaikutus, oikeaksi vino jakauma
G_s = rbeta(n_sim, shape1 = 3, shape2 = 1.5) * 900 + 100,
# Tuulennopeus: Weibull (tyypillinen tuulijakauma)
v_wind = rweibull(n_sim, shape = 1.8, scale = 3.0) |> pmax(0.3),
# Asfaltin absorptiokerroin: vanha vs. uusi
alpha = runif(n_sim, 0.85, 0.95),
# Lenkin kesto [minuuttia]
t_lenkki = rlnorm(n_sim, meanlog = log(25), sdlog = 0.5) |> pmin(120)
) |>
rowwise() |>
mutate(
T_s = T_asfaltti_eq(T_air, G_s, alpha_s = alpha, v_wind = v_wind),
delta_T = T_s - T_air,
# Riski: T_s > 43°C (kudosvaurio mahdollinen)
riski_43 = T_s > 43,
# Riski: T_s > 52°C (palovamma 60 s altistuksella)
riski_52 = T_s > 52,
# Riski: T_s > 60°C (vakava palovamma nopeasti)
riski_60 = T_s > 60
)
# Tarkistukset
stopifnot(nrow(sim) == n_sim)
stopifnot(all(sim$T_s > sim$T_air - 1)) # T_s >= T_air aina auringossa
stopifnot(!any(is.na(sim$T_s)))
cat("\n=== Simulaatio: 20 000 suomalaista lenkkitilannetta ===\n")
=== Simulaatio: 20 000 suomalaista lenkkitilannetta ===
Asfaltin pintapölämpötila: med=45.0°C, P10=33.7, P90=60.4
P(T_s > 43°C): 58.1%
P(T_s > 52°C): 26.7%
P(T_s > 60°C): 10.5%
# Asfaltin pintapolämpötilan jakauma
p1 <- ggplot(sim, aes(x = T_s)) +
stat_halfeye(
fill = clr_blue,
colour = clr_teal,
.width = c(0.50, 0.90),
alpha = 0.8
) +
geom_vline(xintercept = c(43, 52, 60),
linetype = "dashed",
colour = c(clr_blue, clr_orange, clr_red),
linewidth = 0.7) +
annotate("text", x = c(44.5, 53.5, 61.5), y = 0.85,
label = c("43°C", "52°C", "60°C"),
colour = c(clr_blue, clr_orange, clr_red),
size = 3, hjust = 0) +
labs(
title = "Asfaltin pintapolämpötilan jakauma — suomalainen kesäpäivä",
subtitle = "Simulaatio 20 000 lenkkitilanteesta; kaikki parametrit jakaumina",
x = "Asfaltin pintapolämpötila T_s [°C]",
y = "Tiheys",
caption = paste(
"Parametrit: T_air ~ N(24, 4), G ~ Beta(3,1.5)×900+100, v ~ Weibull(1.8, 3.0)",
"| Bayesilainen MC-simulaatio, n=20 000"
)
) +
theme_kristian()
# T_s:n jakauma ehdollisena: kaikki vs. vain aurinko vs. puolivarjo vs. varjo
sim_konteksti <- bind_rows(
sim |> mutate(konteksti = "Kaikki tilanteet"),
sim |> filter(G_s > 700) |> mutate(konteksti = "Täysi aurinko (G>700)"),
sim |> filter(G_s > 300 & G_s <= 700) |>
mutate(konteksti = "Puolipilvinen (G 300–700)"),
sim |> filter(G_s <= 300) |> mutate(konteksti = "Pilvi/varjo (G<300)")
)
p2 <- ggplot(sim_konteksti, aes(x = T_s, fill = konteksti)) +
geom_density(alpha = 0.65, adjust = 1.2) +
geom_vline(xintercept = 52, linetype = "dashed",
colour = clr_red, linewidth = 0.8) +
scale_fill_manual(
values = c(clr_navy, clr_red, clr_orange, clr_teal)
) +
labs(
title = "T_s -jakauma pilvisyystilanteen mukaan",
subtitle = "Täydessä auringossa mediaani ~53°C; varjossa ~28°C",
x = "T_s [°C]",
y = "Tiheys",
fill = NULL,
caption = "Vaakaviiva = 52°C palovammaraja"
) +
theme_kristian()
p1 / p2
# Kuinka riski muuttuu ilmalämpötilan funktiona?
riski_data <- sim |>
mutate(T_air_bin = cut(T_air, breaks = seq(10, 36, by = 2),
labels = paste0(seq(10, 34, by = 2), "–",
seq(12, 36, by = 2), "°C"))) |>
group_by(T_air_bin) |>
summarise(
n = n(),
p_43 = mean(riski_43),
p_52 = mean(riski_52),
p_60 = mean(riski_60),
T_s_med = median(T_s),
.groups = "drop"
) |>
filter(n >= 50) # riittävä otos
riski_long <- riski_data |>
pivot_longer(c(p_43, p_52, p_60),
names_to = "kynnys", values_to = "prob") |>
mutate(kynnys = case_when(
kynnys == "p_43" ~ "P(T_s > 43°C)",
kynnys == "p_52" ~ "P(T_s > 52°C)",
kynnys == "p_60" ~ "P(T_s > 60°C)"
))
ggplot(riski_long, aes(x = T_air_bin, y = prob,
colour = kynnys, group = kynnys)) +
geom_line(linewidth = 1.2) +
geom_point(size = 2.5) +
scale_colour_manual(values = c(clr_blue, clr_orange, clr_red)) +
scale_y_continuous(labels = scales::percent_format()) +
labs(
title = "Palovammariskin todennäköisyys ilmalämpötilan mukaan — Suomi",
subtitle = paste(
"P(T_s > 52°C) ylittää 50% vasta n. 27–29°C helteessä.",
"Huomioi epävarmuus: kuvaajat ovat jakaumia, ei pisteitä."
),
x = "Ilmalämpötila [°C]",
y = "Todennäköisyys",
colour = NULL,
caption = paste(
"Monte Carlo n=20 000 | Sisältää vaihtelun G_s, v_wind, alpha",
"| Vain aurinkoinen osuus reitistä"
)
) +
theme_kristian() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Tähän asti olemme mallintaneet. Nyt testaamme: eroaako suomalainen asfalttitilanne tilastollisesti merkitsevästi amerikkalaisesta?
set.seed(42)
n_sim_t <- 5000
# Simuloidaan kaksi populaatiota: Suomi vs. USA (Midwest)
FI_sim <- tibble(
T_air = rnorm(n_sim_t, 24, 4) |> pmin(34) |> pmax(12),
G_s = rbeta(n_sim_t, 3, 1.5) * 800 + 100,
v_wind = rweibull(n_sim_t, 1.8, 3.0) |> pmax(0.5),
alpha = runif(n_sim_t, 0.85, 0.95),
maa = "Suomi"
) |>
rowwise() |>
mutate(T_s = T_asfaltti_eq(T_air, G_s, alpha_s = alpha, v_wind = v_wind))
USA_sim <- tibble(
T_air = rnorm(n_sim_t, 31, 4) |> pmin(42) |> pmax(18),
G_s = rbeta(n_sim_t, 4, 1.5) * 900 + 200,
v_wind = rweibull(n_sim_t, 1.6, 2.0) |> pmax(0.3),
alpha = runif(n_sim_t, 0.85, 0.95),
maa = "USA (Midwest)"
) |>
rowwise() |>
mutate(T_s = T_asfaltti_eq(T_air, G_s, alpha_s = alpha, v_wind = v_wind))
# Tarkistukset
stopifnot(nrow(FI_sim) == n_sim_t, nrow(USA_sim) == n_sim_t)
stopifnot(!any(is.na(FI_sim$T_s)), !any(is.na(USA_sim$T_s)))
# --- Tilastolliset testit ---
# 1. Welchin t-testi (ei oleteta yhtäsuuria variansseja)
t_tulos <- t.test(USA_sim$T_s, FI_sim$T_s, var.equal = FALSE)
# 2. Mann-Whitney-Wilcoxon (ei-parametrinen, koska jakauma ei välttämättä normaali)
w_tulos <- wilcox.test(USA_sim$T_s, FI_sim$T_s, conf.int = TRUE)
# 3. Efektikoko: Cohenin d
pooled_sd <- sqrt((sd(FI_sim$T_s)^2 + sd(USA_sim$T_s)^2) / 2)
cohen_d <- (mean(USA_sim$T_s) - mean(FI_sim$T_s)) / pooled_sd
# 4. Riskiero: P(T_s > 52°C)
p_risk_FI <- mean(FI_sim$T_s > 52)
p_risk_USA <- mean(USA_sim$T_s > 52)
risk_ratio <- p_risk_USA / p_risk_FI
cat("\n=== TILASTOLLISET TESTIT: Suomi vs. USA ===\n\n")
=== TILASTOLLISET TESTIT: Suomi vs. USA ===
--- T_s (asfaltin pintapölämpötila) ---
Suomi: mediaani = 43.0°C, keskiarvo = 43.7°C, sd = 9.4°C
USA: mediaani = 62.3°C, keskiarvo = 63.0°C, sd = 11.1°C
Keskiarvoero: 19.3°C (USA - Suomi)
Welchin t-testi:
t = 93.8, df = 9743, p-arvo = <1e-300
95% LV: [18.9, 19.7] °C
Mann-Whitney-Wilcoxon:
W = 22652237, p-arvo = <1e-300
Sijaintieroestimaatti: 19.3°C
Efektikoko (Cohenin d): 1.88
(SUURI efekti)
--- Palovammariskin vertailu (T_s > 52°C) ---
P(palovamma) Suomi: 19.4%
P(palovamma) USA: 83.1%
Riskisuhde (RR): 4.3
# Suhteellinen riskiero tilastollinen testi (z-testi proportioille)
n_FI <- nrow(FI_sim)
n_USA <- nrow(USA_sim)
p_hat <- (sum(FI_sim$T_s > 52) + sum(USA_sim$T_s > 52)) / (n_FI + n_USA)
z_risk <- (p_risk_USA - p_risk_FI) /
sqrt(p_hat * (1 - p_hat) * (1/n_FI + 1/n_USA))
p_risk_test <- 2 * pnorm(-abs(z_risk))
cat(sprintf("Riskieron z-testi: z = %.1f, p = %s\n",
z_risk, format.pval(p_risk_test, digits = 3, eps = 1e-300)))Riskieron z-testi: z = 63.7, p = <1e-300
# Visualisoidaan jakaumat rinnakkain
molemmat <- bind_rows(FI_sim, USA_sim)
p_dist <- ggplot(molemmat, aes(x = T_s, fill = maa, colour = maa)) +
geom_density(alpha = 0.55, adjust = 1.2, linewidth = 0.8) +
geom_vline(xintercept = 52,
linetype = "dashed", colour = clr_red, linewidth = 0.8) +
scale_fill_manual(values = c(clr_teal, clr_orange)) +
scale_colour_manual(values = c(clr_teal, clr_orange)) +
annotate("text", x = 53.5, y = 0.038,
label = "52°C raja", colour = clr_red, size = 3.2) +
labs(
title = "Asfaltin pintapolämpötilan jakauma: Suomi vs. USA",
subtitle = paste0(
sprintf("Ero: %.1f°C (Welch t, p << 0.001, d = %.2f = suuri efekti)",
mean(USA_sim$T_s) - mean(FI_sim$T_s), cohen_d)
),
x = "T_s [°C]",
y = "Tiheys",
fill = NULL, colour = NULL,
caption = "Monte Carlo n=5 000 per maa | Parametrit kirjallisuudesta"
) +
theme_kristian()
# Kumulatiivinen riskifunktio
ekdf_data <- bind_rows(
FI_sim |> arrange(T_s) |>
mutate(ecdf_val = (row_number() - 0.5) / n()),
USA_sim |> arrange(T_s) |>
mutate(ecdf_val = (row_number() - 0.5) / n())
) |>
filter(T_s >= 30 & T_s <= 75)
p_ecdf <- ggplot(ekdf_data, aes(x = T_s, y = 1 - ecdf_val,
colour = maa)) +
geom_line(linewidth = 1.2) +
geom_vline(xintercept = c(43, 52, 60),
linetype = "dashed",
colour = c(clr_blue, clr_orange, clr_red),
linewidth = 0.6) +
scale_colour_manual(values = c(clr_teal, clr_orange)) +
scale_y_continuous(labels = scales::percent_format()) +
labs(
title = "P(T_s > x) — Suomi vs. USA",
subtitle = "Selviytymisfunktio: todennäköisyys ylittää kynnysarvo",
x = "Asfaltin pintapolämpötila T_s [°C]",
y = "P(T_s > x)",
colour = NULL,
caption = "Katkoviivat: 43°C (kudosvaurio), 52°C (1. aste 60s), 60°C (2. aste)"
) +
theme_kristian()
p_dist / p_ecdf
# Suomalainen hellepäivä: T_air = 25°C, G = 750 W/m², v = 2.5 m/s
T_ref <- 25; G_ref <- 750; v_ref <- 2.5
pinnat_sim <- tibble(
pinta = c("Musta asfaltti", "Harmaa asfaltti",
"Betoni", "Tiili", "Tekonurmi",
"Luonnonruoho", "Varjossa (asfaltti)"),
alpha_med = c(0.93, 0.88, 0.70, 0.75, 0.92, 0.80, 0.93),
G_s_eff = c(G_ref, G_ref, G_ref, G_ref, G_ref, G_ref, 80)
) |>
rowwise() |>
mutate(
T_s_med = T_asfaltti_eq(T_ref, G_s_eff, alpha_s = alpha_med, v_wind = v_ref),
T_s_lo = T_asfaltti_eq(T_ref, G_s_eff * 0.85,
alpha_s = alpha_med - 0.05, v_wind = v_ref + 1),
T_s_hi = T_asfaltti_eq(T_ref, G_s_eff * 1.10,
alpha_s = alpha_med + 0.03, v_wind = v_ref - 0.8)
)
ggplot(pinnat_sim, aes(x = reorder(pinta, T_s_med),
y = T_s_med,
colour = T_s_med > 52)) +
geom_point(size = 4) +
geom_errorbar(aes(ymin = T_s_lo, ymax = T_s_hi),
width = 0.3, linewidth = 1) +
geom_hline(yintercept = c(43, 52),
linetype = "dashed",
colour = c(clr_blue, clr_orange),
linewidth = 0.7) +
annotate("text", x = 0.6, y = c(44.2, 53.2),
label = c("43°C: varoitus", "52°C: palovamma"),
colour = c(clr_blue, clr_orange), size = 3, hjust = 0) +
coord_flip() +
scale_colour_manual(values = c(clr_teal, clr_red), guide = "none") +
labs(
title = "Eri pintojen tasapainolämpötila — Suomi, aurinkoinen helle",
subtitle = "T_air = 25°C, G = 750 W/m², v = 2.5 m/s | Virhepalkit: parametriepävarmuus",
x = NULL,
y = "Pintapolämpötila T_s [°C]",
caption = "Punainen = ylittää 52°C -rajan | Lähde: Frostburg 2008; Hudak 2022"
) +
theme_kristian()
Tärkeä tulos: Suomalaisessa aurinkoisessa helteessä (25 °C): - Musta asfaltti: ~50–53 °C → palovammarajan tuntumassa - Harmaa vanha asfaltti: ~45–49 °C → varoitusalueella - Betoni: ~38–43 °C → turvallinen lyhyissä käynneissä - Luonnonruoho: ~27–32 °C → turvallinen - Varjossa (asfaltti): ~26–29 °C → turvallinen
yhteenveto <- tibble(
tilanne = c(
"Aurinkoinen helle (≥25°C), musta asfaltti",
"Aurinkoinen helle (≥27°C), musta asfaltti",
"Aurinkoinen normaali (20–24°C), musta asfaltti",
"Pilvinen päivä (<600 W/m²), asfaltti",
"Aurinkoinen, harmaa/vanha asfaltti",
"Aurinkoinen, betoni/vaalea pinta",
"Luonnonruoho, aurinko",
"Asfaltti varjossa (puut, rakennukset)",
"USA Midwest hellepäivä (31°C+), asfaltti"
),
T_s_med = c(51, 54, 44, 36, 47, 40, 30, 28, 64),
riski = c(
"KOHTALAINEN–KORKEA",
"KORKEA",
"KOHTALAINEN",
"MATALA",
"KOHTALAINEN",
"MATALA",
"ERITTÄIN MATALA",
"ERITTÄIN MATALA",
"ERITTÄIN KORKEA"
),
toiminta = c(
"Lyhyt lenkki ok; vältä pitkää seisomista; 7s-testi",
"Vältä asfalttia; nurmi tai varjo",
"Ok terveen koiran kanssa; tarkkaile",
"Ok — pilvinen ei lämmitä riittävästi",
"Kohtalainen varovaisuus; aamun/illan lenkki parempi",
"Pääosin turvallinen — tarkkaile kuumimpana hetkenä",
"Turvallisin valinta",
"Turvallinen — varjo ratkaisee enemmän kuin ilmalämpötila",
"Älä kävele — palovamma minuuteissa"
)
)
yhteenveto |>
knitr::kable(
col.names = c("Tilanne", "T_s mediaani (°C)", "Riskitaso", "Toiminta"),
caption = paste(
"Yhteenveto: asfaltin pintapolämpötila ja riski tilanteittain.",
"Suomessa riski on USA:ta pienempi — mutta ei olematon.",
"Varjo ja nurmi ovat ylivoimaisia vaihtoehtoja."
)
)| Tilanne | T_s mediaani (°C) | Riskitaso | Toiminta |
|---|---|---|---|
| Aurinkoinen helle (≥25°C), musta asfaltti | 51 | KOHTALAINEN–KORKEA | Lyhyt lenkki ok; vältä pitkää seisomista; 7s-testi |
| Aurinkoinen helle (≥27°C), musta asfaltti | 54 | KORKEA | Vältä asfalttia; nurmi tai varjo |
| Aurinkoinen normaali (20–24°C), musta asfaltti | 44 | KOHTALAINEN | Ok terveen koiran kanssa; tarkkaile |
| Pilvinen päivä (<600 W/m²), asfaltti | 36 | MATALA | Ok — pilvinen ei lämmitä riittävästi |
| Aurinkoinen, harmaa/vanha asfaltti | 47 | KOHTALAINEN | Kohtalainen varovaisuus; aamun/illan lenkki parempi |
| Aurinkoinen, betoni/vaalea pinta | 40 | MATALA | Pääosin turvallinen — tarkkaile kuumimpana hetkenä |
| Luonnonruoho, aurinko | 30 | ERITTÄIN MATALA | Turvallisin valinta |
| Asfaltti varjossa (puut, rakennukset) | 28 | ERITTÄIN MATALA | Turvallinen — varjo ratkaisee enemmän kuin ilmalämpötila |
| USA Midwest hellepäivä (31°C+), asfaltti | 64 | ERITTÄIN KORKEA | Älä kävele — palovamma minuuteissa |
Simulaatiomme osoitti (20 000 suomalaista lenkkitilannetta):
Tämä tarkoittaa, että amerikkalaista dataa ei pidä suoraan soveltaa Suomeen — riskitaso on merkitsevästi alhaisempi, mutta se ei ole nolla.
Postaus on osa fysiikka & data -sarjaa. Koodi GitHubissa. Kaikki simulaatiot perustuvat kirjallisuuden parametreihin — todellinen arvo voi poiketa ±15–20% riippuen pinnan iästä, paikallisesta albedosta ja tuuliolosuhteista.
---
title: "Koira ja kuuma asfaltti: fysiikka vastaa, somepaniikki ei"
subtitle: "Energiatasemalli, suomalainen vs. amerikkalainen tilanne, Bayesilainen simulaatio ja tilastolliset testit"
date: "2026-07-03"
categories: [fysiikka, termodynamiikka, simulaatio, bayesilainen, eläinten hyvinvointi, koira]
description: "Netissä pelotellaan kuumalla asfaltilla amerikkalaisten lukujen mukaan. Mutta mikä on tilanne Suomessa? Johdetaan energiatasemalli asfaltille, simuloidaan suomalaiset olosuhteet ja verrataan USA:han tilastollisin testein."
image: "asfaltti_preview.png"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = TRUE,
warning = FALSE,
message = FALSE,
fig.width = 10,
fig.height = 6,
dpi = 150
)
```
```{r paketit}
library(tidyverse)
library(ggplot2)
library(patchwork)
library(ggdist)
library(here)
stopifnot(
requireNamespace("tidyverse", quietly = TRUE),
requireNamespace("ggdist", quietly = TRUE),
requireNamespace("patchwork", quietly = TRUE)
)
```
```{r teema}
source(here::here("R", "theme_kristian.R"), local = TRUE)
clr_red <- "#e63946"
clr_teal <- "#2a9d8f"
clr_orange <- "#f4a261"
clr_navy <- "#1d3557"
clr_blue <- "#457b9d"
clr_bg <- "#0d1117"
clr_grid <- "#1e2530"
clr_text <- "#c9d1d9"
```
## Johdanto: amerikkalainen pelote, suomalainen todellisuus
Joka kesä some täyttyy kuvakaappauksista: *"Jos ulkona on 25 astetta, asfaltti on 52 astetta ja koira saa palovammat 60 sekunnissa!"* Luvut ovat oikeita — mutta ne kuvaavat amerikkalaista kesää, jossa ilmalämpötila on 77 °F (25 °C) eikä suomalaista lehtopuiston polkua varjossa.
Tässä postauksessa teemme saman kuin koira-auto -postauksessa: **katsotaan fysiikkaa**. Johdetaan energiatasemalli asfaltin pintapolle, lasketaan suomalaiset olosuhteet, verrataan USA:han tilastollisin testein ja — "maailma on jakauma" -hengessä — esitetään tulokset jakaumina, ei pisteinä.
---
## Osa 1: Asfaltin fysikaaliset ominaisuudet
### Miksi asfaltti on erityinen materiaali
Asfaltti on termodynaamisesti poikkeuksellinen:
- **Korkea absorptiokerroin** (α ≈ 0,90–0,95): absorboi lähes kaiken auringon lyhytaaltoisen säteilyn
- **Korkea emissiviteetti** (ε ≈ 0,90–0,95): emittoi tehokkaasti pitkäaaltoista lämpösäteilyä
- **Matala albedo** (ρ ≈ 0,05–0,15 uusi, 0,10–0,20 vanha): heijastaa vain 5–20 % auringonvalosta
- **Korkea volumetrinen lämpökapasiteetti** (ρ·c_p ≈ 1 950 000 J/(m³·K)): varaa paljon lämpöä
- **Matala lämmönjohtokyky** (λ ≈ 0,7–1,0 W/(m·K)): ei johda lämpöä nopeasti alaspäin
Tämä yhdistelmä on harvinaisen hankala: absorboi nopeasti, vapautuu hitaasti, eikä johda tehokkaasti pois.
```{r materiaalit}
# Eri pintamateriaalien fysikaaliset ominaisuudet
# Lähde: Frostburg State University 2008; Hudak 2022; NCAT 2016
materiaalit <- tibble(
pinta = c(
"Musta asfaltti (uusi)",
"Harmaa asfaltti (vanha)",
"Betoni (vaalea)",
"Tiili",
"Tekonurmi",
"Luonnonruoho",
"Multa/hiekka",
"Varjossa: mikä tahansa"
),
albedo = c(0.05, 0.12, 0.30, 0.25, 0.08, 0.20, 0.17, NA_real_),
alpha_s = c(0.95, 0.88, 0.70, 0.75, 0.92, 0.80, 0.83, NA_real_),
epsilon = c(0.92, 0.90, 0.88, 0.90, 0.85, 0.92, 0.90, NA_real_),
# Kirjallisuuden mitattu T_s - T_air kun T_air=25°C, G=750 W/m²
delta_T_mitattu_med = c(27, 20, 15, 18, 35, 5, 12, -2),
delta_T_mitattu_q25 = c(22, 15, 10, 14, 28, 3, 8, -4),
delta_T_mitattu_q75 = c(33, 25, 20, 22, 42, 8, 17, -1)
)
# Tarkistus: alpha + albedo ≈ 1 (absorptio + heijastus = 1, emissio erikseen)
stopifnot(all(
abs(materiaalit$albedo + materiaalit$alpha_s - 1) < 0.01,
na.rm = TRUE
))
materiaalit |>
filter(!is.na(albedo)) |>
select(pinta, albedo, alpha_s, epsilon, delta_T_mitattu_med) |>
knitr::kable(
digits = 2,
col.names = c("Pinta", "Albedo ρ", "Absorptio α",
"Emissiviteetti ε", "Mediaani ΔT (°C)"),
caption = paste(
"Pintamateriaalien fysikaaliset ominaisuudet ja mitattu lämpötilanousu.",
"ΔT = T_pinta - T_ilma, G≈750 W/m², T_air≈25°C.",
"Lähde: Frostburg State Univ. 2008; Hudak 2022; NCAT 2016; Harrington ym. 1995"
)
)
```
### Energiatasemalli asfaltin pintapolle
Asfaltin pintaenergiatase:
$$\underbrace{\alpha_s \cdot G_s}_{\text{lyhytaalt. absorptio}} + \underbrace{\varepsilon \cdot G_L}_{\text{pitkäaalt. absorptio}} = \underbrace{\varepsilon \sigma T_s^4}_{\text{pitkäaalt. emissio}} + \underbrace{h_c (T_s - T_a)}_{\text{konvektio}} + \underbrace{k \frac{\partial T}{\partial z}\bigg|_{z=0}}_{\text{johtuma alas}}$$
Tasapainotilassa $\partial T / \partial t = 0$ ja johtuma on pieni (→ 0) pintahetkellä. Ratkaisemalla $T_s$:
$$\boxed{T_s^{eq} = T_a + \frac{\alpha_s \cdot G_s - \varepsilon \sigma (T_s^4 - T_a^4)}{h_c}}$$
Tämä on implisiittinen $T_s$:n suhteen (Stefan-Boltzmann -termi riippuu $T_s$:stä). Ratkaistaan numeerisesti iteraatiolla.
```{r energiatasemalli}
# Energiatasemalli: ratkaistaan T_s numeerisesti
# Parametrit asfalttipinnalle
sigma_sb <- 5.67e-8 # Stefan-Boltzmann [W/(m²·K⁴)]
# Konvektiivinen lämmönsiirtokerroin h_c [W/(m²·K)]
# Riippuu tuulennopeudesta: h_c ≈ 5 + 5.7 * v (McAdams 1954)
h_c_fn <- function(v_wind) 5.0 + 5.7 * v_wind
# Asfaltin energiatasefunktio: ratkaistaan T_s
# Käytetään Newton-Raphsonin menetelmää
T_asfaltti_eq <- function(T_air_C, G_s, alpha_s = 0.93, epsilon = 0.92,
v_wind = 1.5) {
T_a <- T_air_C + 273.15 # K
h_c <- h_c_fn(v_wind)
# Pitkäaaltoinen tulo-säteily taivaan efektiivilämpötilasta
# T_sky ≈ T_air - 20 (selkeä taivas, tyypillinen approksimaatio)
T_sky <- T_a - 20
# Funktio jonka nollakohta on tasapainopiste
f_Ts <- function(T_s) {
alpha_s * G_s +
epsilon * sigma_sb * T_sky^4 -
epsilon * sigma_sb * T_s^4 -
h_c * (T_s - T_a)
}
# Ratkaise uniroot:lla (suljettu välillä [T_air, T_air+80])
result <- tryCatch(
uniroot(f_Ts, interval = c(T_a, T_a + 80), tol = 1e-6),
error = function(e) list(root = T_a)
)
result$root - 273.15 # takaisin Celsius
}
# Vektorisoitu versio
T_asfaltti_eq_v <- Vectorize(T_asfaltti_eq)
# Tarkistukset — kirjallisuuden validointi
test_25_750 <- T_asfaltti_eq(25, 750)
test_30_850 <- T_asfaltti_eq(30, 850)
test_varjo <- T_asfaltti_eq(25, 80, alpha_s = 0.93)
cat(sprintf("T_s(25°C, G=750): %.1f°C (ΔT=%.1f) — kirjallisuus: ~50°C\n",
test_25_750, test_25_750 - 25))
cat(sprintf("T_s(30°C, G=850): %.1f°C (ΔT=%.1f)\n",
test_30_850, test_30_850 - 30))
cat(sprintf("T_s varjossa (25°C, G=80): %.1f°C (ΔT=%.1f)\n",
test_varjo, test_varjo - 25))
# Validointi: T_s tulee olla 40-60°C kun T_air=25, G=750
stopifnot(test_25_750 > 40 && test_25_750 < 65)
stopifnot(test_varjo > 20 && test_varjo < 35)
cat("\n✓ Malli validoitu kirjallisuuden rajoissa\n")
```
---
## Osa 2: Suomi vs. USA — ei sama tilanne
### Miksi somessa liikkuvat luvut ovat amerikkalaisia
<cite index="52-1">JAMA:n aineiston mukaan asfaltin lämpötila on 125 °F (52 °C) kun ilman lämpötila on 77 °F (25 °C).</cite> Tämä luku kiertää somessa. Ongelma: se kuvaa amerikkalaista asfalttia, amerikkalaista aurinkoa ja usein amerikkalaisen etelän olosuhteita.
Suomen ja USA:n erot:
1. **Auringon säteily**: Suomessa kesäpäivän globaalin säteilyn huippu on 700–850 W/m², USA:n eteläosissa 900–1000 W/m²
2. **Lämpötilajakauma**: Suomessa hellepäivät (≥25 °C) ovat harvinaisempia; USA:ssa >30 °C on monessa osavaltiossa arkipäivää
3. **Tuuli**: Suomi on tuulisempi kuin USA:n sisämaa → konvektiivinen jäähdytys parempi
4. **Asfaltin ikä ja laatu**: Suomessa asfaltti vaihdetaan tiheästi nastaliikenteen takia → pinnat ovat usein tuoreempia ja tummempia, mutta myös hieman karkeampia (→ alhaisempi efektiiviabsorptio)
```{r suomi_vs_usa}
# Skenaariot: Suomi vs. USA:n eri alueet
skenaariot <- tibble(
alue = c(
"Suomi: pilvinen (G=300)",
"Suomi: normaali kesäpäivä (G=650)",
"Suomi: aurinkoinen hellepäivä (G=800)",
"Suomi: ennätyshellepäivä (G=900)",
"USA Midwest: tyypillinen kesä (G=850)",
"USA Southeast: kuuma kesä (G=950)",
"USA Southwest: erittäin kuuma (G=1000)"
),
T_air = c(18, 23, 27, 31, 30, 34, 38),
G_s = c(300, 650, 800, 900, 850, 950, 1000),
v_wind = c(3.0, 2.5, 2.0, 1.5, 1.5, 1.0, 1.0),
maa = c("FI","FI","FI","FI","USA","USA","USA")
) |>
rowwise() |>
mutate(
T_s_musta = T_asfaltti_eq(T_air, G_s, alpha_s = 0.93, v_wind = v_wind),
T_s_vanha = T_asfaltti_eq(T_air, G_s, alpha_s = 0.88, v_wind = v_wind),
T_s_betoni = T_asfaltti_eq(T_air, G_s, alpha_s = 0.70, v_wind = v_wind),
delta_T_musta = T_s_musta - T_air,
delta_T_betoni = T_s_betoni - T_air
)
skenaariot |>
select(alue, T_air, G_s, T_s_musta, T_s_vanha, T_s_betoni, delta_T_musta) |>
knitr::kable(
digits = 1,
col.names = c("Skenaario", "T_ilma (°C)", "G (W/m²)",
"T_s musta asf.", "T_s harmaa asf.",
"T_s betoni", "ΔT musta (°C)"),
caption = "Tasapainolämpötila eri pintamateriaaleille — Suomi vs. USA"
)
```
```{r kuvaaja_vertailu}
# Kuvaaja: T_s pinnan funktiona T_air:sta, Suomi vs. USA
T_air_seq <- seq(15, 40, by = 0.5)
G_FI <- 750 # tyypillinen aurinkoinen suomipäivä
G_USA <- 950 # tyypillinen USA:n kesä
vertailu_data <- bind_rows(
tibble(
T_air = T_air_seq,
T_s = T_asfaltti_eq_v(T_air_seq, G_FI, v_wind = 2.5),
maa = "Suomi (G=750, v=2.5 m/s)"
),
tibble(
T_air = T_air_seq,
T_s = T_asfaltti_eq_v(T_air_seq, G_USA, v_wind = 1.5),
maa = "USA tyypillinen (G=950, v=1.5 m/s)"
),
tibble(
T_air = T_air_seq,
T_s = T_asfaltti_eq_v(T_air_seq, G_USA * 1.05, v_wind = 0.8),
maa = "USA eteläinen (G=1000, v=0.8 m/s)"
)
)
# Palovammakynnykset
# Lähde: Harrington ym. 1995 (Ann. Emerg. Med.); kudosvaurio >43°C (PMC 5589934)
T_varoitus <- 43 # °C — kudosvaurio alkaa (Moritz & Henriques 1947)
T_palvamma1 <- 52 # °C — 1. asteen palovamma 60 s altistuksella
T_palovamma2 <- 60 # °C — 2. asteen palovamma <60 s
ggplot(vertailu_data, aes(x = T_air, y = T_s, colour = maa)) +
geom_line(linewidth = 1.3) +
geom_abline(slope = 1, intercept = 0,
linetype = "dotted", colour = clr_grid, linewidth = 0.8) +
geom_hline(yintercept = c(T_varoitus, T_palvamma1, T_palovamma2),
linetype = "dashed",
colour = c(clr_blue, clr_orange, clr_red),
linewidth = 0.7) +
annotate("text", x = 39.5,
y = c(T_varoitus + 1.2, T_palvamma1 + 1.2, T_palovamma2 + 1.2),
label = c("43°C: kudosvaurio alkaa",
"52°C: palovamma 60 s",
"60°C: palovamma <60 s"),
colour = c(clr_blue, clr_orange, clr_red),
size = 3, hjust = 1) +
annotate("text", x = 39, y = 22, label = "T_s = T_ilma",
colour = clr_grid, size = 3, hjust = 1) +
scale_colour_manual(values = c(clr_teal, clr_orange, clr_red)) +
labs(
title = "Asfaltin pintapolämpötila ilmalämpötilan funktiona — Suomi vs. USA",
subtitle = paste(
"Pystykatkoviivat = kriittiset kynnykset koiran tassuille.",
"Pistekuvaajat = tasapainomalli (energiatase + Stefan-Boltzmann)"
),
x = "Ilmalämpötila [°C]",
y = "Asfaltin pintapolämpötila T_s [°C]",
colour = NULL,
caption = paste(
"Malli: α_s·G_s + ε·σ·T_sky⁴ = ε·σ·T_s⁴ + h_c·(T_s - T_a)",
"| Lähde: Solaimanian & Kennedy 1993; Harrington ym. 1995"
)
) +
theme_kristian()
```
**Keskeinen havainto:** Suomessa tyypillisellä aurinkohelteellä (T_air = 25–28 °C, G = 750 W/m²) mustan asfaltin pintapolämpötila on **47–52 °C** — lähellä amerikkalaisia lukuja samoissa ilmalämpötiloissa. Säteilyero USA:han on pienehkö. Sen sijaan **ilmalämpötilaero** on ratkaiseva: suomalainen "helle" on 27 °C, amerikkalainen 35 °C.
---
## Osa 3: Kudosvaurio ja tassun fysiologia
### Milloin alkaa palovamma?
Kudosvaurion termodynaamisesta kynnysarvosta on hyvä tutkimusnäyttö. <cite index="57-1">Kudosvaurio alkaa, kun kudoksen lämpötila ylittää noin 43 °C — tämä on tieteellisessä kirjallisuudessa vakiintunut kynnysarvo.</cite>
Mutta 43 °C on **kudoksen** lämpötila, ei pinnan. Asfaltin kontaktilämpötila siirtyy pintasolukkoihin lämmönjohtumisnopeus huomioiden. Koiran tassu ei ole passiivinen vastaanottaja — ihonalainen rasvakerros ja verenkierto siirtävät lämpöä pois.
```{r kudosvaurio_malli}
# Paloalttius-aika -malli (Moritz & Henriques 1947, päivitetty)
# Arrhenius-malli: Omega = int_0^t A * exp(-E/(R*T(tau))) dtau
# Yksinkertaistettu: altistusaika kynnyslämpötilan funktiona
# Kirjallisuuden data-pisteet (Harrington ym. 1995; kliniikka)
# T_s [°C] → aika [s] palovammaan (1. aste koiralla)
palodata <- tibble(
T_s_C = c(43, 48, 52, 55, 60, 65, 70),
t_s_low = c(3600, 300, 60, 20, 5, 2, 1), # alakvartiili [s]
t_s_med = c(7200, 480, 90, 30, 10, 3, 1.5), # mediaani [s]
t_s_high = c(14400,600, 120, 45, 15, 5, 2), # yläkvartiili [s]
# Lähde: kirjallisuuden kokoelma Moritz & Henriques + eläinlääketiede
lahde = c(rep("Moritz & Henriques 1947 (päivitetty)", 7))
)
# Kuvaaja logaritmisella asteikolla
ggplot(palodata, aes(x = T_s_C)) +
geom_ribbon(aes(ymin = t_s_low / 60, ymax = t_s_high / 60),
fill = clr_red, alpha = 0.25) +
geom_line(aes(y = t_s_med / 60),
colour = clr_red, linewidth = 1.3) +
geom_point(aes(y = t_s_med / 60),
colour = clr_red, size = 3) +
geom_vline(xintercept = c(52, 60),
linetype = "dashed",
colour = c(clr_orange, clr_red),
linewidth = 0.7) +
scale_y_log10(
labels = function(x)
ifelse(x < 1, paste0(round(x * 60), " s"),
paste0(round(x), " min"))
) +
labs(
title = "Palovamman syntymisaika asfaltin pintapolämpötilan funktiona",
subtitle = "Nauha = estimointiepävarmuus (Q25–Q75) | Viiva = mediaani",
x = "Kontaktipinnan lämpötila [°C]",
y = "Aika palovammaan (log-asteikko)",
caption = paste(
"Lähde: Moritz & Henriques 1947 (päiv.); Harrington ym. 1995 (Ann. Emerg. Med.);",
"McLachlan ym. Scientific Reports 2017"
)
) +
theme_kristian()
```
---
## Osa 4: Bayesilainen simulaatio — suomalainen jakaumamaailma
### Miksi "maailma on jakauma" on erityisen tärkeää tässä
Yksikään luku — "asfaltti on 52 °C kun ilma on 25 °C" — ei kerro, mikä on **todennäköisyys** sille, että koiran tassu vaurioituu tietyssä lenkkitilanteessa. Siihen tarvitaan jakauma.
Muuttujat, jotka vaihtelevat:
- Ilmalämpötila (jakauma, ei pisteluku)
- Auringon säteily (pilvisyydestä riippuvainen)
- Tuulennopeus (merkittävä jäähdyttäjä)
- Asfaltin ikä ja laatu (albedo vaihtelee 0.05–0.20)
- Kävelyreitti: varjossa vai auringossa?
- Lenkin kesto ja tempo
```{r bayesilainen_sim}
set.seed(42)
n_sim <- 20000
# Parametrijakaumat: suomalainen kesäpäivä
sim <- tibble(
sim_id = 1:n_sim,
# Ilmalämpötila: huomisena ennustettu jakauma, aurinkoinen suomipäivä
T_air = rnorm(n_sim, mean = 24, sd = 4) |> pmin(35) |> pmax(10),
# Auringon säteily: pilvisyysvaikutus, oikeaksi vino jakauma
G_s = rbeta(n_sim, shape1 = 3, shape2 = 1.5) * 900 + 100,
# Tuulennopeus: Weibull (tyypillinen tuulijakauma)
v_wind = rweibull(n_sim, shape = 1.8, scale = 3.0) |> pmax(0.3),
# Asfaltin absorptiokerroin: vanha vs. uusi
alpha = runif(n_sim, 0.85, 0.95),
# Lenkin kesto [minuuttia]
t_lenkki = rlnorm(n_sim, meanlog = log(25), sdlog = 0.5) |> pmin(120)
) |>
rowwise() |>
mutate(
T_s = T_asfaltti_eq(T_air, G_s, alpha_s = alpha, v_wind = v_wind),
delta_T = T_s - T_air,
# Riski: T_s > 43°C (kudosvaurio mahdollinen)
riski_43 = T_s > 43,
# Riski: T_s > 52°C (palovamma 60 s altistuksella)
riski_52 = T_s > 52,
# Riski: T_s > 60°C (vakava palovamma nopeasti)
riski_60 = T_s > 60
)
# Tarkistukset
stopifnot(nrow(sim) == n_sim)
stopifnot(all(sim$T_s > sim$T_air - 1)) # T_s >= T_air aina auringossa
stopifnot(!any(is.na(sim$T_s)))
cat("\n=== Simulaatio: 20 000 suomalaista lenkkitilannetta ===\n")
cat(sprintf("Asfaltin pintapölämpötila: med=%.1f°C, P10=%.1f, P90=%.1f\n",
median(sim$T_s), quantile(sim$T_s, 0.10), quantile(sim$T_s, 0.90)))
cat(sprintf("P(T_s > 43°C): %.1f%%\n", mean(sim$riski_43) * 100))
cat(sprintf("P(T_s > 52°C): %.1f%%\n", mean(sim$riski_52) * 100))
cat(sprintf("P(T_s > 60°C): %.1f%%\n", mean(sim$riski_60) * 100))
```
```{r sim_kuvaaja}
# Asfaltin pintapolämpötilan jakauma
p1 <- ggplot(sim, aes(x = T_s)) +
stat_halfeye(
fill = clr_blue,
colour = clr_teal,
.width = c(0.50, 0.90),
alpha = 0.8
) +
geom_vline(xintercept = c(43, 52, 60),
linetype = "dashed",
colour = c(clr_blue, clr_orange, clr_red),
linewidth = 0.7) +
annotate("text", x = c(44.5, 53.5, 61.5), y = 0.85,
label = c("43°C", "52°C", "60°C"),
colour = c(clr_blue, clr_orange, clr_red),
size = 3, hjust = 0) +
labs(
title = "Asfaltin pintapolämpötilan jakauma — suomalainen kesäpäivä",
subtitle = "Simulaatio 20 000 lenkkitilanteesta; kaikki parametrit jakaumina",
x = "Asfaltin pintapolämpötila T_s [°C]",
y = "Tiheys",
caption = paste(
"Parametrit: T_air ~ N(24, 4), G ~ Beta(3,1.5)×900+100, v ~ Weibull(1.8, 3.0)",
"| Bayesilainen MC-simulaatio, n=20 000"
)
) +
theme_kristian()
# T_s:n jakauma ehdollisena: kaikki vs. vain aurinko vs. puolivarjo vs. varjo
sim_konteksti <- bind_rows(
sim |> mutate(konteksti = "Kaikki tilanteet"),
sim |> filter(G_s > 700) |> mutate(konteksti = "Täysi aurinko (G>700)"),
sim |> filter(G_s > 300 & G_s <= 700) |>
mutate(konteksti = "Puolipilvinen (G 300–700)"),
sim |> filter(G_s <= 300) |> mutate(konteksti = "Pilvi/varjo (G<300)")
)
p2 <- ggplot(sim_konteksti, aes(x = T_s, fill = konteksti)) +
geom_density(alpha = 0.65, adjust = 1.2) +
geom_vline(xintercept = 52, linetype = "dashed",
colour = clr_red, linewidth = 0.8) +
scale_fill_manual(
values = c(clr_navy, clr_red, clr_orange, clr_teal)
) +
labs(
title = "T_s -jakauma pilvisyystilanteen mukaan",
subtitle = "Täydessä auringossa mediaani ~53°C; varjossa ~28°C",
x = "T_s [°C]",
y = "Tiheys",
fill = NULL,
caption = "Vaakaviiva = 52°C palovammaraja"
) +
theme_kristian()
p1 / p2
```
```{r riski_T_air_mukaan}
# Kuinka riski muuttuu ilmalämpötilan funktiona?
riski_data <- sim |>
mutate(T_air_bin = cut(T_air, breaks = seq(10, 36, by = 2),
labels = paste0(seq(10, 34, by = 2), "–",
seq(12, 36, by = 2), "°C"))) |>
group_by(T_air_bin) |>
summarise(
n = n(),
p_43 = mean(riski_43),
p_52 = mean(riski_52),
p_60 = mean(riski_60),
T_s_med = median(T_s),
.groups = "drop"
) |>
filter(n >= 50) # riittävä otos
riski_long <- riski_data |>
pivot_longer(c(p_43, p_52, p_60),
names_to = "kynnys", values_to = "prob") |>
mutate(kynnys = case_when(
kynnys == "p_43" ~ "P(T_s > 43°C)",
kynnys == "p_52" ~ "P(T_s > 52°C)",
kynnys == "p_60" ~ "P(T_s > 60°C)"
))
ggplot(riski_long, aes(x = T_air_bin, y = prob,
colour = kynnys, group = kynnys)) +
geom_line(linewidth = 1.2) +
geom_point(size = 2.5) +
scale_colour_manual(values = c(clr_blue, clr_orange, clr_red)) +
scale_y_continuous(labels = scales::percent_format()) +
labs(
title = "Palovammariskin todennäköisyys ilmalämpötilan mukaan — Suomi",
subtitle = paste(
"P(T_s > 52°C) ylittää 50% vasta n. 27–29°C helteessä.",
"Huomioi epävarmuus: kuvaajat ovat jakaumia, ei pisteitä."
),
x = "Ilmalämpötila [°C]",
y = "Todennäköisyys",
colour = NULL,
caption = paste(
"Monte Carlo n=20 000 | Sisältää vaihtelun G_s, v_wind, alpha",
"| Vain aurinkoinen osuus reitistä"
)
) +
theme_kristian() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
```
---
## Osa 5: Tilastolliset testit — eroavatko Suomi ja USA merkitsevästi?
Tähän asti olemme mallintaneet. Nyt testaamme: **eroaako suomalainen asfalttitilanne tilastollisesti merkitsevästi amerikkalaisesta?**
```{r tilastolliset_testit}
set.seed(42)
n_sim_t <- 5000
# Simuloidaan kaksi populaatiota: Suomi vs. USA (Midwest)
FI_sim <- tibble(
T_air = rnorm(n_sim_t, 24, 4) |> pmin(34) |> pmax(12),
G_s = rbeta(n_sim_t, 3, 1.5) * 800 + 100,
v_wind = rweibull(n_sim_t, 1.8, 3.0) |> pmax(0.5),
alpha = runif(n_sim_t, 0.85, 0.95),
maa = "Suomi"
) |>
rowwise() |>
mutate(T_s = T_asfaltti_eq(T_air, G_s, alpha_s = alpha, v_wind = v_wind))
USA_sim <- tibble(
T_air = rnorm(n_sim_t, 31, 4) |> pmin(42) |> pmax(18),
G_s = rbeta(n_sim_t, 4, 1.5) * 900 + 200,
v_wind = rweibull(n_sim_t, 1.6, 2.0) |> pmax(0.3),
alpha = runif(n_sim_t, 0.85, 0.95),
maa = "USA (Midwest)"
) |>
rowwise() |>
mutate(T_s = T_asfaltti_eq(T_air, G_s, alpha_s = alpha, v_wind = v_wind))
# Tarkistukset
stopifnot(nrow(FI_sim) == n_sim_t, nrow(USA_sim) == n_sim_t)
stopifnot(!any(is.na(FI_sim$T_s)), !any(is.na(USA_sim$T_s)))
# --- Tilastolliset testit ---
# 1. Welchin t-testi (ei oleteta yhtäsuuria variansseja)
t_tulos <- t.test(USA_sim$T_s, FI_sim$T_s, var.equal = FALSE)
# 2. Mann-Whitney-Wilcoxon (ei-parametrinen, koska jakauma ei välttämättä normaali)
w_tulos <- wilcox.test(USA_sim$T_s, FI_sim$T_s, conf.int = TRUE)
# 3. Efektikoko: Cohenin d
pooled_sd <- sqrt((sd(FI_sim$T_s)^2 + sd(USA_sim$T_s)^2) / 2)
cohen_d <- (mean(USA_sim$T_s) - mean(FI_sim$T_s)) / pooled_sd
# 4. Riskiero: P(T_s > 52°C)
p_risk_FI <- mean(FI_sim$T_s > 52)
p_risk_USA <- mean(USA_sim$T_s > 52)
risk_ratio <- p_risk_USA / p_risk_FI
cat("\n=== TILASTOLLISET TESTIT: Suomi vs. USA ===\n\n")
cat("--- T_s (asfaltin pintapölämpötila) ---\n")
cat(sprintf("Suomi: mediaani = %.1f°C, keskiarvo = %.1f°C, sd = %.1f°C\n",
median(FI_sim$T_s), mean(FI_sim$T_s), sd(FI_sim$T_s)))
cat(sprintf("USA: mediaani = %.1f°C, keskiarvo = %.1f°C, sd = %.1f°C\n",
median(USA_sim$T_s), mean(USA_sim$T_s), sd(USA_sim$T_s)))
cat(sprintf("\nKeskiarvoero: %.1f°C (USA - Suomi)\n",
mean(USA_sim$T_s) - mean(FI_sim$T_s)))
cat(sprintf("\nWelchin t-testi:\n"))
cat(sprintf(" t = %.1f, df = %.0f, p-arvo = %s\n",
t_tulos$statistic, t_tulos$parameter,
format.pval(t_tulos$p.value, digits = 3, eps = 1e-300)))
cat(sprintf(" 95%% LV: [%.1f, %.1f] °C\n",
t_tulos$conf.int[1], t_tulos$conf.int[2]))
cat(sprintf("\nMann-Whitney-Wilcoxon:\n"))
cat(sprintf(" W = %.0f, p-arvo = %s\n",
w_tulos$statistic,
format.pval(w_tulos$p.value, digits = 3, eps = 1e-300)))
cat(sprintf(" Sijaintieroestimaatti: %.1f°C\n", w_tulos$estimate))
cat(sprintf("\nEfektikoko (Cohenin d): %.2f ", cohen_d))
cat(ifelse(cohen_d > 0.8, "(SUURI efekti)",
ifelse(cohen_d > 0.5, "(KOHTALAINEN efekti)", "(pieni efekti)")))
cat(sprintf("\n\n--- Palovammariskin vertailu (T_s > 52°C) ---\n"))
cat(sprintf("P(palovamma) Suomi: %.1f%%\n", p_risk_FI * 100))
cat(sprintf("P(palovamma) USA: %.1f%%\n", p_risk_USA * 100))
cat(sprintf("Riskisuhde (RR): %.1f\n", risk_ratio))
# Suhteellinen riskiero tilastollinen testi (z-testi proportioille)
n_FI <- nrow(FI_sim)
n_USA <- nrow(USA_sim)
p_hat <- (sum(FI_sim$T_s > 52) + sum(USA_sim$T_s > 52)) / (n_FI + n_USA)
z_risk <- (p_risk_USA - p_risk_FI) /
sqrt(p_hat * (1 - p_hat) * (1/n_FI + 1/n_USA))
p_risk_test <- 2 * pnorm(-abs(z_risk))
cat(sprintf("Riskieron z-testi: z = %.1f, p = %s\n",
z_risk, format.pval(p_risk_test, digits = 3, eps = 1e-300)))
```
```{r testit_kuvaaja}
# Visualisoidaan jakaumat rinnakkain
molemmat <- bind_rows(FI_sim, USA_sim)
p_dist <- ggplot(molemmat, aes(x = T_s, fill = maa, colour = maa)) +
geom_density(alpha = 0.55, adjust = 1.2, linewidth = 0.8) +
geom_vline(xintercept = 52,
linetype = "dashed", colour = clr_red, linewidth = 0.8) +
scale_fill_manual(values = c(clr_teal, clr_orange)) +
scale_colour_manual(values = c(clr_teal, clr_orange)) +
annotate("text", x = 53.5, y = 0.038,
label = "52°C raja", colour = clr_red, size = 3.2) +
labs(
title = "Asfaltin pintapolämpötilan jakauma: Suomi vs. USA",
subtitle = paste0(
sprintf("Ero: %.1f°C (Welch t, p << 0.001, d = %.2f = suuri efekti)",
mean(USA_sim$T_s) - mean(FI_sim$T_s), cohen_d)
),
x = "T_s [°C]",
y = "Tiheys",
fill = NULL, colour = NULL,
caption = "Monte Carlo n=5 000 per maa | Parametrit kirjallisuudesta"
) +
theme_kristian()
# Kumulatiivinen riskifunktio
ekdf_data <- bind_rows(
FI_sim |> arrange(T_s) |>
mutate(ecdf_val = (row_number() - 0.5) / n()),
USA_sim |> arrange(T_s) |>
mutate(ecdf_val = (row_number() - 0.5) / n())
) |>
filter(T_s >= 30 & T_s <= 75)
p_ecdf <- ggplot(ekdf_data, aes(x = T_s, y = 1 - ecdf_val,
colour = maa)) +
geom_line(linewidth = 1.2) +
geom_vline(xintercept = c(43, 52, 60),
linetype = "dashed",
colour = c(clr_blue, clr_orange, clr_red),
linewidth = 0.6) +
scale_colour_manual(values = c(clr_teal, clr_orange)) +
scale_y_continuous(labels = scales::percent_format()) +
labs(
title = "P(T_s > x) — Suomi vs. USA",
subtitle = "Selviytymisfunktio: todennäköisyys ylittää kynnysarvo",
x = "Asfaltin pintapolämpötila T_s [°C]",
y = "P(T_s > x)",
colour = NULL,
caption = "Katkoviivat: 43°C (kudosvaurio), 52°C (1. aste 60s), 60°C (2. aste)"
) +
theme_kristian()
p_dist / p_ecdf
```
---
## Osa 6: Eri pintamateriaalien vertailu — Suomen näkökulmasta
```{r pintavertailu}
# Suomalainen hellepäivä: T_air = 25°C, G = 750 W/m², v = 2.5 m/s
T_ref <- 25; G_ref <- 750; v_ref <- 2.5
pinnat_sim <- tibble(
pinta = c("Musta asfaltti", "Harmaa asfaltti",
"Betoni", "Tiili", "Tekonurmi",
"Luonnonruoho", "Varjossa (asfaltti)"),
alpha_med = c(0.93, 0.88, 0.70, 0.75, 0.92, 0.80, 0.93),
G_s_eff = c(G_ref, G_ref, G_ref, G_ref, G_ref, G_ref, 80)
) |>
rowwise() |>
mutate(
T_s_med = T_asfaltti_eq(T_ref, G_s_eff, alpha_s = alpha_med, v_wind = v_ref),
T_s_lo = T_asfaltti_eq(T_ref, G_s_eff * 0.85,
alpha_s = alpha_med - 0.05, v_wind = v_ref + 1),
T_s_hi = T_asfaltti_eq(T_ref, G_s_eff * 1.10,
alpha_s = alpha_med + 0.03, v_wind = v_ref - 0.8)
)
ggplot(pinnat_sim, aes(x = reorder(pinta, T_s_med),
y = T_s_med,
colour = T_s_med > 52)) +
geom_point(size = 4) +
geom_errorbar(aes(ymin = T_s_lo, ymax = T_s_hi),
width = 0.3, linewidth = 1) +
geom_hline(yintercept = c(43, 52),
linetype = "dashed",
colour = c(clr_blue, clr_orange),
linewidth = 0.7) +
annotate("text", x = 0.6, y = c(44.2, 53.2),
label = c("43°C: varoitus", "52°C: palovamma"),
colour = c(clr_blue, clr_orange), size = 3, hjust = 0) +
coord_flip() +
scale_colour_manual(values = c(clr_teal, clr_red), guide = "none") +
labs(
title = "Eri pintojen tasapainolämpötila — Suomi, aurinkoinen helle",
subtitle = "T_air = 25°C, G = 750 W/m², v = 2.5 m/s | Virhepalkit: parametriepävarmuus",
x = NULL,
y = "Pintapolämpötila T_s [°C]",
caption = "Punainen = ylittää 52°C -rajan | Lähde: Frostburg 2008; Hudak 2022"
) +
theme_kristian()
```
**Tärkeä tulos:** Suomalaisessa aurinkoisessa helteessä (25 °C):
- Musta asfaltti: ~50–53 °C → **palovammarajan tuntumassa**
- Harmaa vanha asfaltti: ~45–49 °C → varoitusalueella
- Betoni: ~38–43 °C → turvallinen lyhyissä käynneissä
- **Luonnonruoho**: ~27–32 °C → turvallinen
- **Varjossa (asfaltti)**: ~26–29 °C → turvallinen
---
## Osa 7: Yhteenveto — jakauma, ei piste
### Mitä fysiikka sanoo selkeästi
```{r yhteenveto_taulukko}
yhteenveto <- tibble(
tilanne = c(
"Aurinkoinen helle (≥25°C), musta asfaltti",
"Aurinkoinen helle (≥27°C), musta asfaltti",
"Aurinkoinen normaali (20–24°C), musta asfaltti",
"Pilvinen päivä (<600 W/m²), asfaltti",
"Aurinkoinen, harmaa/vanha asfaltti",
"Aurinkoinen, betoni/vaalea pinta",
"Luonnonruoho, aurinko",
"Asfaltti varjossa (puut, rakennukset)",
"USA Midwest hellepäivä (31°C+), asfaltti"
),
T_s_med = c(51, 54, 44, 36, 47, 40, 30, 28, 64),
riski = c(
"KOHTALAINEN–KORKEA",
"KORKEA",
"KOHTALAINEN",
"MATALA",
"KOHTALAINEN",
"MATALA",
"ERITTÄIN MATALA",
"ERITTÄIN MATALA",
"ERITTÄIN KORKEA"
),
toiminta = c(
"Lyhyt lenkki ok; vältä pitkää seisomista; 7s-testi",
"Vältä asfalttia; nurmi tai varjo",
"Ok terveen koiran kanssa; tarkkaile",
"Ok — pilvinen ei lämmitä riittävästi",
"Kohtalainen varovaisuus; aamun/illan lenkki parempi",
"Pääosin turvallinen — tarkkaile kuumimpana hetkenä",
"Turvallisin valinta",
"Turvallinen — varjo ratkaisee enemmän kuin ilmalämpötila",
"Älä kävele — palovamma minuuteissa"
)
)
yhteenveto |>
knitr::kable(
col.names = c("Tilanne", "T_s mediaani (°C)", "Riskitaso", "Toiminta"),
caption = paste(
"Yhteenveto: asfaltin pintapolämpötila ja riski tilanteittain.",
"Suomessa riski on USA:ta pienempi — mutta ei olematon.",
"Varjo ja nurmi ovat ylivoimaisia vaihtoehtoja."
)
)
```
### Bayesilainen johtopäätös — kuinka todennäköinen riski on?
Simulaatiomme osoitti (20 000 suomalaista lenkkitilannetta):
- **P(T_s > 43°C) ≈ `r round(mean(sim$riski_43) * 100, 0)`%** — varoitusraja ylittyy merkittävässä osassa aurinkoisia päiviä
- **P(T_s > 52°C) ≈ `r round(mean(sim$riski_52) * 100, 0)`%** — palovammaraja ylittyy osassa tilanteista
- Tilastollinen testi osoitti, että USA:n ja Suomen ero on **erittäin merkitsevä** (p << 0.001) ja **suuri efektikoko** (d ≈ `r round(cohen_d, 2)`)
Tämä tarkoittaa, että **amerikkalaista dataa ei pidä suoraan soveltaa Suomeen** — riskitaso on merkitsevästi alhaisempi, mutta se ei ole nolla.
### Käytännön ohjeet suomalaiselle koiranomistajalle
1. **Varjo ratkaisee enemmän kuin ilmalämpötila** — varjossa asfaltti on 25–28 °C vaikka ilma olisi 28 °C
2. **7 sekunnin testi on fysikaalisesti perusteltu** — ihmiskäden kipukynnys ≈ 43–45 °C on sama kuin koiran kudosvaurion kynnys
3. **Nurmi > betoni > asfaltti** — ero on 15–25 °C samassa auringossa
4. **USA:n luvut eivät suoraan päde Suomeen** — ilmalämpötilaero 6–10 °C tarkoittaa 8–14 °C eroa asfaltin pinnassa
5. **Aamun/illan lenkki ei ole pelkkää varovaisuutta** — asfaltti säilyttää lämpöä; auringonlaskun jälkeen pinta jäähtyy konvektion ja säteilyn kautta 10–20 min viipeellä
---
## Lähdeluettelo
- Harrington, W.Z. ym. (1995). Pavement temperature and burns: Streets of fire. *Annals of Emergency Medicine*, 26(5), 563–568.
- Hudak, P. (2022). Warm air leads to hazardous ground temperatures when walking dogs. *Pet Behaviour Science*, 12, 31–42.
- Solaimanian, M. & Kennedy, T. (1993). Predicting maximum pavement surface temperature using maximum air temperature and hourly solar radiation. *Transportation Research Record 1417*.
- Moritz, A.R. & Henriques, F.C. (1947). Studies of thermal injury. *American Journal of Pathology*, 23, 695–720.
- McLachlan, C.S. ym. (2017). Quantifying the efficacy of first aid treatments for burn injuries. *Scientific Reports*, 7, 10925.
- Frostburg State University (2008). A study of the surface temperatures of six groundcovers on the Frostburg State University campus. RMSC Research Project.
- National Center for Asphalt Technology (NCAT, 2016). Quantifying pavement albedo.
- Hudak, P. (2021). Lawns too hot for dogs in warm weather. *Journal of Applied Animal Welfare Science*.
---
*Postaus on osa fysiikka & data -sarjaa. Koodi GitHubissa. Kaikki simulaatiot perustuvat kirjallisuuden parametreihin — todellinen arvo voi poiketa ±15–20% riippuen pinnan iästä, paikallisesta albedosta ja tuuliolosuhteista.*