Air Density, Vapor Pressure and I'm Confused

David, @dsj

I added Air Density to WFArchive so I loaded the old code I wrote that, a year ago matched the WeatherFlow data.

It no longer matches.

So I dug in deep and started from the beginning. I went to your published documents. The first thing I find is an issue with calculating Vapor Pressure. The doument at: https://weatherflow.github.io/SmartWeather/api/derived-metric-formulas.html

shows Vapor Pressuer as:
1

And the link to Weather.gov shows:
2

As one can see they are very different.

As for Air Density, I cannot find any link to the formula you now use .

My issue, is the application shows Air Density as 1.01344 kg/m3 and my calculation is 1.00507, which in this respect is not even close.

Please help. How does WeatherFlow calculate Air Density.

Given these values:

P = 827.8;
T = 11.4;
Dp = 0.8;
RH = 48;

_calcVaporPressureE(Dp) =  6.4726824888727394

_calcVaporPressureEs(T) = 13.47946029051131

_calcVaporPressureRh(T, RH)  = 6.465935635535494

As you can see, even the calculations for Vapor Pressure return two really distinct values that are so far off I don’t know which to trust.

Please, what am I doing incorrectly?

function _calcVaporPressureEs(T) {
	// (temp in C)
    T = parseFloat(T);
    var a = (7.5 * T) / (237.3 + T);
    var Es = 6.1078 * Math.pow(10, a);
    console.log('Es');
    console.log(Es);
    return Es;
}	

function _calcVaporPressureE(Dp) {
    // (dew point  in C)
    Dp = parseFloat(Dp);
    var a = (7.5 * Dp) / (237.3 + Dp);
    var E = 6.1078 * Math.pow(10, a);
    console.log('E');
    console.log(E);
    return E;
}	

function _calcVaporPressureRh(T, RH) {
    // (temp in C, humidity)
    T = parseFloat(T);
    var a = (17.67 * T) / (243.5 + T);
    var Es = (RH / 100) * 6.112 * Math.exp(a);
    console.log('Rh'); 
    console.log(Es);
    return Es;
}

This is how I have been calculating Air Density with the adjustment for the new Vapor Pressure:

WeatherCalc.calcAirDensity = function(T, P, Dp, Rh) {
	// (air temp in C, station pressure, dew point in C, humidity)
	// var d = (P * 100) / (287.05 * (T + 273.15));
	T = parseFloat(T);
	P = parseFloat(P);
	Dp = parseFloat(Dp)
	var Es = _calcVaporPressureRh(T, Rh),
		Rv = 461.4964,
		Rd = 287.0531,
		tk = T + 273.15,
		pv = Es * 100,
		pd = (P - Es) * 100,
		d = (pv / (Rv * tk) ) + (pd / (Rd * tk) );
	return d.toFixed(5);

Haven’t tested if this is the cause, but at a quick glance, shouldn’t var Es = (RH / 100) * 6.112 * Math.pow(10, a) in function _calcVaporPressureRh(T, RH) have an exponential term at the end rather than a power 10?

Ah, yes. That should be Math.exp(a);

I’ll rerun the data and see what I get.

However that still does not explain the two different formulas.

EDIT: I ran the corrected formula and now at least two of the formulas are close. However, I’m still confused as which one is more accurate. Thanks for pointing out the error.

For those interested in the dark arts and magic, here is an interesting article on vapor pressure.

http://mc-computing.com/Science_Facts/Water_Vapor/Formulas.html

Am I the only one calculating these values? I feel so alone out here :wink:

I get so much “hot air” over here, it’s too hard to calculate. :wink:

Uhh. I do myself. And it was so painful… :slight_smile:

What formulas are you using for Vapor Pressure and Air Density and do they match the WeatherFlow values?

@dsj, @corrineb, @WFmarketing, @anon84912554

Will one of you please help me with this issue?

Hello @GaryFunk.

Here’s what I 'm using:

/**
 * Computes the saturation vapor pressure.
 *
 * @param integer $t Temperature in celcius.
 * @return float The computed saturation vapor pressure (in Pa).
 * @since 3.3.0
 */
protected function compute_saturation_vapor_pressure($t) {
    if ($t < 0) {
        $result = pow(10, 2.7877 + ((9.756 * $t) / (272.7 + $t)));
    }
    else {
        $result = pow(10, 2.7877 + ((7.625 * $t) / (241.6 + $t)));
    }
    return round($result);
}

/**
 * Computes the air density.
 *
 * @param integer $t Temperature in celcius.
 * @param integer $p Pressure in pascal.
 * @param integer $h Humidity in percent.
 * @return float The computed air density (in kg/m^3).
 * @since 3.3.0
 */
protected function compute_air_density($t, $p, $h) {
    if ($p == 0) {
        return 0;
    }
    $Ps = $this->compute_saturation_vapor_pressure($t) / $p;
    $Rh = 287.06 / (1 - (($h / 100 ) * $Ps * (1 - (287.06 / 461))));
    return round($p / ($Rh * ($t+273.15)), 5);
}

Regarding matching with other computation, for air density it’s closed to what is rendered by WF APIs (between 0.9% and 0.4%), so I assume vapor pressure should be close too :slight_smile:

Just a quick note about pressure, temperature and relative humidity as input. As you see, it’s typed integer in doc but, as you may know, php is not strong-typed language so I actually using it with floats. Maybe should I update my doc :grin:

Thank you. I’ll test your formula results and what results I get.

I understand. As long as I have the formula.

@pierre First issue. When I run you vapor pressure formula with T = 11.4;

function vapor_pressure(T) {
    let s;
    if (T < 0) {
        S = Math.pow(10, 2.7877 + ((9.756 * T) / (272.7 + T)));
    } else {
        S = Math.pow(10, 2.7877 + ((7.625 * T) / (241.6 + T)));
    }
    console.log("S");
    console.log(S);
    return S;
}

it returns: 1352.9354458317532

This value is about 200 times to high. For the Air Density to use this value and produce anywhere near a correct result means the second formula is incorrect.

Hi Gary. Looks like you guys have it figured out. I don’t have time to dig in this week, but we should be using the exact formulas shown on the Derived Metric Formulas page, though I see we don’t have one for Air Density yet. These are all approximations, of course, and I suspect any small differences you’re seeing are likely due to rounding errors. If you think you’ve found a bug, please let me know!

On the other hand, running your complete air density formula results in

0.9950220740970757

and WeatherFlow shows:
0.99811

In this case, two wrongs seem to make a near right.

The only thing I figured out is the world does not agree and I still can’t get a figure close to what WeatherFlow is using. It’s all FM and BM.

For those playing along at home, here are the latest results.

0.99811 - WeatherFlow
0.99502 - Pierre
0.99447 - My code

These values are not close enough to form a consensus.

Here is the javascript I am testing with and you can test this at: https://www.webtoolkitonline.com/javascript-tester.html

P = 823.4;
T = 14.1;
Dp = 5.5;
H = 56;
console.log("Start");   
_calcVaporPressureEs(T);

_calcVaporPressureE(Dp);

_calcVaporPressureRh(T, H);

vapor_pressure(T);
console.log(" ");

air_density(T, P, RH);

calcAirDensity(T, P, Dp, H);

function _calcVaporPressureEs(T) {
    // (temp in C)
    T = parseFloat(T);
    var a = (7.5 * T) / (237.3 + T);
    var E = 6.1078 * Math.pow(10, a);
    console.log('Es ' + E);
    return E;
}	

function _calcVaporPressureE(Dp) {
    // (dew point  in C)
    Dp = parseFloat(Dp);
    var a = (7.5 * Dp) / (237.3 + Dp);
    var E = 6.1078 * Math.pow(10, a);
    console.log('E ' + E);
    return E;
}	

function _calcVaporPressureRh(T, H) {
    // (temp in C, humidity)
    T = parseFloat(T);
    var a = (17.67 * T) / (243.5 + T);
    var E = (H / 100) * 6.112 * Math.exp(a);
    console.log('Rh ' + E); 
    return E;
}

function vapor_pressure(T) {
    let S;
    if (T < 0) {
        S = Math.pow(10, 2.7877 + ((9.756 * T) / (272.7 + T)));
    } else {
        S = Math.pow(10, 2.7877 + ((7.625 * T) / (241.6 + T)));
    }
    console.log("S " + S);
    return S;
}


function air_density(T, P, H) {
    P = P * 100;
    let Ps = vapor_pressure(T) / P;
    let Rh = 287.06 / (1 - ((H / 100 ) * Ps * (1 - (287.06 / 461))));
    let A = P / (Rh * (T + 273.15));
    console.log("A " + A.toFixed(5));
}

function calcAirDensity(T, P, Dp, H) {
// (air temp in C, station pressure, dew point in C, humidity)
// var d = (P * 100) / (287.05 * (T + 273.15));
T = parseFloat(T);
P = parseFloat(P);
Dp = parseFloat(Dp)
let Es = _calcVaporPressureRh(T, H),
	Rv = 461.4964,
	Rd = 287.0531,
	tk = T + 273.15,
	pv = Es * 100,
	pd = (P - Es) * 100,
	d = (pv / (Rv * tk) ) + (pd / (Rd * tk) );
	let B = parseFloat(d.toFixed(5));
	console.log("B " + B);
}

Yes, I confirm, with 11.4°C, it’s about 1350 Pa… What is the error?

Nowhere did it state the vaper is expressed in pascals. It is normally expressed in mmHg, mb or hPa.

This seems to be a BIG issue with formulas. The value returned is seldom described.