pirateweather icon indicating copy to clipboard operation
pirateweather copied to clipboard

Better snow height estimates suggestion

Open tkafka opened this issue 1 year ago • 3 comments

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
	  */
}

tkafka avatar Mar 30 '23 09:03 tkafka

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.

github-actions[bot] avatar Jul 11 '23 00:07 github-actions[bot]

This issue has been automatically closed since there has been no further activity after seven days.

github-actions[bot] avatar Jul 18 '23 06:07 github-actions[bot]

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

alexander0042 avatar Jul 24 '23 13:07 alexander0042