Air Density, Vapor Pressure and I'm Confused


#1

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:

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);

#2

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?


#3

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.


#4

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


#5

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


#6

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


#7

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


#8

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


#9

@dsj, @corrineb, @WFstaff, @WFsupport

Will one of you please help me with this issue?


#10

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:


#11

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:


#12

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


#13

I understand. As long as I have the formula.


#14

@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.


#15

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!


#16

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.


#17

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.


#18

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);
}

#19

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


#20

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.