From 90bc693509c72877a2af183665ee144e10a1cfc1 Mon Sep 17 00:00:00 2001 From: Roland Rossgotterer Date: Wed, 26 Dec 2018 02:32:38 +0100 Subject: [PATCH] Handle a hypothetical relative humidity of 0.0 % Summary: The formular to calculate the dew point is not defined for relative humidity of 0.0 %. It is every unlikely to ever happen in real world weather, but is handled just in case by using the smallest possible numerical double value. Reviewers: #swift_pilot_client Maniphest Tasks: T406 Differential Revision: https://dev.swift-project.org/D82 --- src/plugins/weatherdata/gfs/weatherdatagfs.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/plugins/weatherdata/gfs/weatherdatagfs.cpp b/src/plugins/weatherdata/gfs/weatherdatagfs.cpp index 569bef33d..2a9f36a46 100644 --- a/src/plugins/weatherdata/gfs/weatherdatagfs.cpp +++ b/src/plugins/weatherdata/gfs/weatherdatagfs.cpp @@ -729,10 +729,20 @@ namespace BlackWxPlugin CTemperature CWeatherDataGfs::calculateDewPoint(const CTemperature &temperature, double relativeHumidity) { + // https://en.wikipedia.org/wiki/Dew_point#Calculating_the_dew_point + const double a = 6.112; + const double b = 17.67; + const double c = 243.5; + double temperatureInCelsius = temperature.value(CTemperatureUnit::C()); - double saturationVaporPressure = 6.112 * std::exp((17.67 * temperatureInCelsius) / (temperatureInCelsius + 243.5)); - double vaporPressure = saturationVaporPressure * (relativeHumidity / 100.0); - double dewPointInCelsius = std::log(vaporPressure / 6.112) * 243.5 / (17.67 - std::log(vaporPressure / 6.112)); + double saturationVaporPressure = a * std::exp((b * temperatureInCelsius) / (c + temperatureInCelsius)); + + double vaporPressure = (relativeHumidity / 100.0) * saturationVaporPressure; + // std::log(0.0) is not defined. Hence we use the smallest value possible close to 0.0, if RH is 0.0. + // In real weather, RH 0.0 % will never exist. + vaporPressure = qMax(vaporPressure, std::numeric_limits::min()); + + double dewPointInCelsius = c * std::log(vaporPressure / a) / (b - std::log(vaporPressure / a)); return { dewPointInCelsius, CTemperatureUnit::C() }; }