pirateweather
pirateweather copied to clipboard
Better snow height estimates suggestion
I have done some research into converting precipitation to snow height for my app, and I'd like to share the formulas I arrived at - they might provide a bit better results than just multiplying by 10:
It's in swift, but the conversion should be easy - will this help?
public func kelvinFromCelsius(_ celsius: CGFloat) -> CGFloat {
return celsius + 273.15
}
/// - Returns: kg/m3
public func estimateSnowDensity(temperatureC: CGFloat, windSpeedMps: CGFloat) -> CGFloat {
/// interpolation at https://docs.google.com/spreadsheets/d/1nrCN37VpoeDgAQHr70HcLDyyt-_dQdsRJMerpKMW0ho/edit?usp=sharing
/// Ratio ranges:
/// 3-30x: https://www.eoas.ubc.ca/courses/atsc113/snow/met_concepts/07-met_concepts/07b-newly-fallen-snow-density/
/// 3-20x: https://www.researchgate.net/figure/Common-densities-of-snow_tbl1_258653078
/// 4-20x: https://www.researchgate.net/figure/Fresh-snow-density-as-a-function-of-air-temperature-and-wind-for-the-3-options-included_fig2_316868161
/// Equations: from ESOLIP, https://www.tandfonline.com/eprint/Qf3k4JEPg3xXRmzp7gQQ/full (https://www.tandfonline.com/doi/pdf/10.1080/02626667.2015.1081203?needAccess=true)
/// Originally from https://sci-hub.hkvisa.net/10.1029/1999jc900011 (Jordan, R.E., Andreas, E.L., and Makshtas, A.P., 1999. Heat budget of snow-covered sea ice at North Pole 4. Journal of Geophysical Research)
/// Problem: These seem to be considering wind speed and it's factor on compacting the snow? Is that okay to use? According to ESOLIP paper probably yes.
var kelvins = kelvinFromCelsius(temperatureC)
/// above 2.5? bring it down, it shouldn't happen, but if it does, let's just assume it's 2.5 deg
kelvins = min(kelvins, 275.65)
let windSpeedExp17 = pow(windSpeedMps, 1.7)
var snowDensityKgM3: CGFloat = 1000
if kelvins <= 260.15 {
snowDensityKgM3 = 500 * (
1 - 0.904 * exp(-0.008 * windSpeedExp17)
)
} else if kelvins <= 275.65 {
snowDensityKgM3 = 500 * (
1 - 0.951 * exp(
-1.4 * pow(278.15 - kelvins, -1.15) - 0.008 * windSpeedExp17
)
)
} else {
/// above 2.5 degrees -> fallback, return precip mm (-> ratio = 1)
/// should not happen - see above
snowDensityKgM3 = 1000
}
/// ensure we don't divide by zero - ensure minimum
snowDensityKgM3 = max(snowDensityKgM3, 50)
return snowDensityKgM3
}
public func estimateSnowHeight(precipitationMm: CGFloat, temperatureC: CGFloat, windSpeedMps: CGFloat) -> CGFloat {
let snowDensityKgM3 = estimateSnowDensity(temperatureC: temperatureC, windSpeedMps: windSpeedMps)
return precipitationMm * 1000 / snowDensityKgM3
/// This one is too much, with its 10-100x range
/*
/// formula from https://www.omnicalculator.com/other/rain-to-snow#how-many-inches-of-snow-is-equal-to-one-inch-of-rain
let ratioBase: CGFloat = 10.3 + (-1.21 * temperatureC) + (0.0389 * temperatureC * temperatureC)
let ratio: CGFloat = clamp(value: ratioBase, from: 10, to: 100)
let snowMm: CGFloat = precipitationMm * ratio
return snowMm
*/
}
There has been no activity on this issue for ninety days and unless you comment on the issue it will automatically close in seven days.
This issue has been automatically closed since there has been no further activity after seven days.
Apologies that this one got closed- I really like this suggestion, and I'm planning on implementing it! I'm going to transfer it over to the main API repo, since that's where I'm keeping track of the data side of things