Haha! Obsession of EU citizen for MKSA

# Air Density, Vapor Pressure and I'm Confused

**vinceskahan**#26

Gary - is it possible your input data is incorrect ?

```
P = 823.4; # mbar ?
T = 14.1; # air temp degC
Dp = 5.5; # dewpoint degC
H = 56; # pct relative humidity
```

H = ( Dp / T ) * 100.0 according to the weather.gov link that the WF page points to, so using the temperatures above H should be 39 in your input data.

Incidentally, your code translates really trivially to python, FWIW. Cool.

**GaryFunk**#27

I understand what you state but I used the actual values reported by the WeatherFlow application.

Currently they are:

```
P = 821.7;
T = 15.9;
Dp = 5.5;
H = 50;
```

**GaryFunk**#28

Thank you for your formulas and explanations. You have helped me better understand how this is calculated. This isnât something I wanted to understand, but it doesnât hurt.

**pierre**#29

Youâre welcome @GaryFunk

And if that can reassure you, I also took a long time to understand psychrometry

**GaryFunk**#30

I like that your formula incorporates over water AND over ice. I am going to modify the WeatherFlow formula to return for ice.

**GaryFunk**#32

Okay!!!

So I am slowly figuring what is going on here.

First, the vapor pressure is being calculated as Saturated Vapor Pressure in millibars based on the Dew Point temperature.

Then that result is being passed to the Air Density formula.

This is what I ended up with.

The good news is my values agree darn close to professional and government stations around the area. Yea ME!

```
function _calcVaporPressure(T) {
// (temp in C)
let Eso = 6.1078;
let C0 = 0.99999683;
let C1 = -0.90826951E-02;
let C2 = 0.78736169E-04;
let C3 = -0.61117958E-06;
let C4 = 0.43884187E-08;
let C5 = -0.29883885E-10;
let C6 = 0.21874425E-12;
let C7 = -0.17892321E-14;
let C8 = 0.11112018E-16;
let C9 = -0.30994571E-19;
let Pol = C0 + T * (C1 + T * (C2 + T * (C3 + T * (C4 + T * (C5 + T * (C6 + T * (C7 + T * (C8+ T * (C9)))))))));
let Es = Eso * Math.pow(Pol, -8);
return (Es);
}
WeatherCalc.calcAirDensity = function(T, P, Dp, H) {
// (station pressure in mb, vapor pressure in mb, temp in C) return air density in kg/m3
T = parseFloat(T);
P = parseFloat(P);
Dp = parseFloat(Dp)
let Es = _calcVaporPressure(Dp),
Rv = 461.4964,
Rd = 287.0531,
Tk = T + 273.15,
Pv = Es * 100,
Pd = (P - Es) * 100;
let d = (Pv / (Rv * Tk)) + (Pd / (Rd * Tk));
let D = parseFloat(d.toFixed(5));
return(D);
}
```

I will be updating and expanding the formulas I posted later this week.

I want to thank @dsj, @pierre, @peter and the WeatherFlow staff for the valuable help.

**peter**#33

Good to hear youâve managed to make progress with this! So is there still an issue with the WeatherFlow derived air density? As you mentioned above, it looks like their calculation of vapour pressures are a bit wide of the markâŚ

**pierre**#35

Hello @GaryFunk, I will try to add fuel to your fire

There are to notions of vapor pressures.

I will try to explain the difference, but excuse me in advance, I donât know if my English skills will allow me to express all the nuances.

Partial pressure (of water) - or Partial Vapor Pressure - is the pressure exerced by the water (in gazeous phase) in a mix of other gazes. It represents the portion of the total pressure (as expressed in Daltonâs law). The mix between water in different phases are mainly âdirectedâ by relative humidity, so relative humidity takes part in its computation.

Saturation pressure (of water) - or Vapor Pressure at Saturation - is the pressure exerced by the water (in gazeous phase) in the same mix of other gazes but when you can not âaddâ more vapor without condensation effect (hence its name). So with a relative humidity at 100%. It is a sort of theoretical computation (you know, with âperfectâ conditions).

A (good) approximation for partial pressure is Pp = H * Ps

(where Pp is partial pressure, H the relative humidity and Ps the saturation pressure)

In psychrometry, Pp is a terminal computation, it represents the true situation of a mix of gazes. Ps is an intermediate computation which is useful to other computationâŚlike air density!

If I use the following function:

```
/**
* Computes the saturation vapor pressure.
*
* @param float $t Temperature in celcius.
* @return float The computed saturation vapor pressure (in Pascal).
* @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);
}
```

I obtain the following âtable of calibrationâ:

40Â°C => 7427Pa

30Â°C => 4265Pa

20Â°C => 2348Pa

15Â°C => 1712Pa

10Â°C => 1232Pa

00Â°C => 613Pa

which is (at a precision of more than 99.3%) what you have in the table extracted from the document you cited. Note these numbers are in line with what gives the vapor pressure calculator of NOAAâŚ

At this precision I consider it sufficient to calculate air density at ânormal temperaturesââŚ

You can now complete your computation with the following functions:

`/** * Computes the vapor pressure. * * @param float $t Temperature in celcius. * @param float $h Humidity in percent. * @return float The computed partial vapor pressure (in Pascal). * @since 3.3.0 */ protected function compute_partial_vapor_pressure($t, $h) { $p = $this->compute_saturation_vapor_pressure($t); return round($h * $p / 100, 0); }`

`/** * Computes the air density. * * @param float $t Temperature in celcius. * @param float $p Pressure in pascal. * @param float $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); }`

I donât know if it helps, but I hope so

**pierre**#36

And finally, to answer the following question:

I think the answer is ânoâ. What is computed by WF seems to me particularly suitable for common uses of air densityâŚ

**GaryFunk**#40

This brings up another question. Why are vapor pressure and air density calculated on the server when every other calculation is done on the client?

**vinceskahan**#42

@GaryFunk - I got lost in the long thread below this one, but did you guys ever reach resolution on this ?

I found (this link) which has far too much detail even for my too-many-years-ago Chemical Engineering degree brain, but it sure looks like WF is:

- using equation (3) so a simple Ideal Gas Law calculation
- and feeding it observed temperature and observed station pressure

Just to test that, I ran my data here from this morning using a quick python routine:

```
T = 11.0 # degC observed
Psta = 1004.7 # mb observed
air density ideal-gas-law (T,Psta) = 1.23177444759
air density WF app reported = 1.233174
```

Using your values from your original post in this thread:

```
T = 11.4 # degC observed
Psta = 828.8 # mb observed
air density ideal-gas-law (T,Psta) = 1.01346622743
WF reported density from your post = 1.01344
```

That sure looks like two matches to meâŚ

Python code that should be obvious is:

```
# ref: https://wahiduddin.net/calc/density_altitude.htm (equation 3)
import math
def vpFromIdealGasLaw(t,p):
T = float(t) + 273.15 # convert degC => degK
P = 100 * float(p) # convert mb => Pascals
N = 287.05 # specific gas constant for dry air J/(kg*degK)
return P/(N * T)
print "air_density ideal gas law (11.4,828.8)=", vpFromIdealGasLaw(11.4,827.8)
```

**GaryFunk**#43

The end result is the air density reported by WeatherFlow is darn close. Itâs the vapor pressure that is off by 50%.

So, that means the vapor pressure formula used by WeatherFlow cannot be used by any other formula that requires an accurate value. It also means the the air density formula used by WeatherFlow has to compensate for a vapor pressure value that is half of what it actually is.

I am convinced that there is an issue on the WeatherFlow end and I am open to being corrected by WeatherFlow as I am not an expert and not an authority on vapor pressure or air density. However, I know math and I can clearly see the difference in the values.

All this being said, I have decided on the formulas to use and if asked why my values are different than WeatherFlow, I will simply respond with by demonstrating the formulas I use. Itâs not an issue that matters to most but I want to provide the value from UDP data and that requires that vapor pressure and air density (along with density altitude) be calculated from the available UDP data. My goal as always been to match the WeatherFlow data within +/- 0.0001 of value.

Numbers, and how your present them, do matter. Close only counts in horse shoes, hand grenades and atomic bombs.

**vinceskahan**#44

Not seeing it. Off from âwhatâ ?

```
# https://weatherflow.github.io/SmartWeather/api/derived-metric-formulas.html
VP_weatherflow = (H / 100) * 6.112 * math.exp((17.67 * T) / (243.5 + T))
# but the calculation the WF page links to is different
# https://www.weather.gov/media/epz/wxcalc/vaporPressure.pdf
VP_weather_gov = 6.11 * math.pow(10, ((7.5 * T) / (237.3 + T)));
# using dewpoint of 10.4 degC the two are 0.2% different
VP_weatherflow = 12.5932992479 mb
VP_weather.gov = 12.6164817301 mb
```

These match the calculations on:

- https://www.iap.tuwien.ac.at/www/surface/vapor_pressure
- https://www.weather.gov/epz/wxcalc_vaporpressure (the calculator for the weather.gov linked page above)
- the âcalibration tableâ @pierre posted above
- the table on https://en.wikipedia.org/wiki/Vapour_pressure_of_water

(assuming Pa = mb * 100)

Guess Iâm lost where the 50% off is coming from, unless Iâm lost in a maze of twisty little metric-vs-imperial unit conversions. I see the two formulas getting the same answer and matching 4 different online references (plus/minus a fraction of a percent)