Added dew point; implemented actual vapour pressure, but don't have test data.
This commit is contained in:
parent
ce32cd285e
commit
970a320a84
8 changed files with 118 additions and 16 deletions
|
|
@ -25,8 +25,8 @@ The 'packet', in the terminology of this library, is a map which has bindings
|
||||||
for some of the following keywords:
|
for some of the following keywords:
|
||||||
|
|
||||||
1. `:absolute-humidity` *grammes per metre<sup>3</sup>.*
|
1. `:absolute-humidity` *grammes per metre<sup>3</sup>.*
|
||||||
2. `:actual-vapour-pressure` *not yet implemented*
|
2. `:actual-vapour-pressure` *Pascals*
|
||||||
1. `:dew-point` *not yet implemented*
|
1. `:dew-point-celsius`
|
||||||
2. `:pressure-pascals`
|
2. `:pressure-pascals`
|
||||||
3. `:pressure-millibars`
|
3. `:pressure-millibars`
|
||||||
4. `:saturation-vapour-pressure` *Pascals*
|
4. `:saturation-vapour-pressure` *Pascals*
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
(ns ^{:author "simon"
|
(ns ^{:author "simon"
|
||||||
:authority "https://www.weather.gov/media/epz/wxcalc/vaporPressure.pdf"
|
:authority "https://www.weather.gov/media/epz/wxcalc/vaporPressure.pdf"
|
||||||
:doc "Compute actual vapour pressure."} humidity.actual-vp)
|
:doc "Compute actual vapour pressure."}
|
||||||
|
humidity.actual-vp
|
||||||
|
(:require [humidity.utils :refer [expt]]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;
|
;;;
|
||||||
|
|
@ -23,3 +24,21 @@
|
||||||
;;; USA.
|
;;; USA.
|
||||||
;;;
|
;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(def ^:const magic-numbers
|
||||||
|
"The magic numbers (empirical constants) from the derived expression. It
|
||||||
|
bothers me that all these formulae depend on 'empirical constants', *and*
|
||||||
|
that there is no commonality between the empirical constants of different
|
||||||
|
formulae."
|
||||||
|
;; 1000 because are units are Pascals
|
||||||
|
[0 6.11 1000 7.5 237.3])
|
||||||
|
|
||||||
|
(def C magic-numbers)
|
||||||
|
|
||||||
|
(defn actual-vapour-pressure-fn
|
||||||
|
"Compute actual vapour pressure in Pascals given dew point in ° Celsius."
|
||||||
|
[& {:keys [dew-point-celsius]}]
|
||||||
|
(when dew-point-celsius
|
||||||
|
(* (C 1) (expt (C 2)
|
||||||
|
(/ (* (C 3) dew-point-celsius)
|
||||||
|
(+ (C 4) dew-point-celsius))))))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
(ns ^{:doc "Constants used in humidity calculations."
|
(ns ^{:doc "Constants used in humidity calculations."
|
||||||
|
:authority ["https://journals.ametsoc.org/view/journals/apme/35/4/1520-0450_1996_035_0601_imfaos_2_0_co_2.xml"]
|
||||||
:author "simon"} humidity.constants)
|
:author "simon"} humidity.constants)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
@ -30,6 +31,10 @@
|
||||||
"Base of natural logarithms"
|
"Base of natural logarithms"
|
||||||
2.71828)
|
2.71828)
|
||||||
|
|
||||||
|
(def ^:const magnus-coefficients
|
||||||
|
"See https://www.omnicalculator.com/physics/dew-point#how-to-calculate-dew-point-how-to-calculate-relative-humidity"
|
||||||
|
{:a 17.625 :b 243.04})
|
||||||
|
|
||||||
(def ^:const Pa
|
(def ^:const Pa
|
||||||
"Standard atmospheric pressure, in Pascals. I don't know why this isn't
|
"Standard atmospheric pressure, in Pascals. I don't know why this isn't
|
||||||
100,000, but it isn't.
|
100,000, but it isn't.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
:author "simon"}
|
:author "simon"}
|
||||||
humidity.core
|
humidity.core
|
||||||
(:require [humidity.absolute :refer [abs-humidity]]
|
(:require [humidity.absolute :refer [abs-humidity]]
|
||||||
|
[humidity.actual-vp :refer [actual-vapour-pressure-fn]]
|
||||||
[humidity.constants :refer [celsius-offset Pa]]
|
[humidity.constants :refer [celsius-offset Pa]]
|
||||||
|
[humidity.dew-point :refer [dew-point-celsius-fn]]
|
||||||
[humidity.relative :refer [rel-humidity]]
|
[humidity.relative :refer [rel-humidity]]
|
||||||
[humidity.saturation-vp :refer [saturation-vp]]
|
[humidity.saturation-vp :refer [saturation-vp]]
|
||||||
[humidity.utils :refer [?assoc]]
|
[humidity.utils :refer [?assoc]]
|
||||||
|
|
@ -32,7 +34,8 @@
|
||||||
|
|
||||||
(defn resolve-humidity
|
(defn resolve-humidity
|
||||||
"Resolve humidity equations given the data in this packet."
|
"Resolve humidity equations given the data in this packet."
|
||||||
[& {:keys [absolute-humidity pressure-pascals pressure-millibars
|
[& {:keys [absolute-humidity actual-vapour-pressure dew-point-celsius
|
||||||
|
pressure-pascals pressure-millibars
|
||||||
relative-humidity saturation-vapour-pressure temperature
|
relative-humidity saturation-vapour-pressure temperature
|
||||||
temperature-celsius temperature-kelvin volume
|
temperature-celsius temperature-kelvin volume
|
||||||
wet-bulb-temperature] :as packet}]
|
wet-bulb-temperature] :as packet}]
|
||||||
|
|
@ -43,6 +46,10 @@
|
||||||
(?assoc packet
|
(?assoc packet
|
||||||
:absolute-humidity (when-not absolute-humidity
|
:absolute-humidity (when-not absolute-humidity
|
||||||
(abs-humidity packet))
|
(abs-humidity packet))
|
||||||
|
:actual-vapour-pressure (when-not actual-vapour-pressure
|
||||||
|
(actual-vapour-pressure-fn packet))
|
||||||
|
:dew-point-celsius (when-not dew-point-celsius
|
||||||
|
(dew-point-celsius-fn packet))
|
||||||
:pressure-pascals (when-not pressure-pascals
|
:pressure-pascals (when-not pressure-pascals
|
||||||
(if pressure-millibars
|
(if pressure-millibars
|
||||||
(* pressure-millibars 100) Pa))
|
(* pressure-millibars 100) Pa))
|
||||||
|
|
|
||||||
34
src/humidity/dew_point.clj
Normal file
34
src/humidity/dew_point.clj
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
(ns ^{:author "simon"
|
||||||
|
:authority ["https://www.omnicalculator.com/physics/dew-point#what-is-dew-point-dew-point-definition"
|
||||||
|
"https://en.wikipedia.org/wiki/Dew_point#Calculating_the_dew_point"]
|
||||||
|
:doc "Function to compute the dew point, in ° Celsius, given temperature
|
||||||
|
in ° Celsius and relative humidity percentage."} humidity.dew-point
|
||||||
|
(:require [clojure.math :refer [log]]
|
||||||
|
[humidity.constants :refer [magnus-coefficients]]))
|
||||||
|
|
||||||
|
(def ^:const magic-numbers
|
||||||
|
"The magic numbers (empirical constants) from the derived expression. It
|
||||||
|
bothers me that all these formulae depend on 'empirical constants', *and*
|
||||||
|
that there is no commonality between the empirical constants of different
|
||||||
|
formulae."
|
||||||
|
[0 6.11 10 7.5 237.3])
|
||||||
|
|
||||||
|
(def C magic-numbers)
|
||||||
|
|
||||||
|
(defn- alpha
|
||||||
|
"See https://www.omnicalculator.com/physics/dew-point#how-to-calculate-dew-point-how-to-calculate-relative-humidity"
|
||||||
|
[T RH]
|
||||||
|
(let [a (:a magnus-coefficients)
|
||||||
|
b (:b magnus-coefficients)]
|
||||||
|
(+ (log (/ RH 100)) (/ (* a T) (+ b T)))))
|
||||||
|
|
||||||
|
;; Ts = (b × α(T,RH)) / (a - α(T,RH))
|
||||||
|
(defn dew-point-celsius-fn
|
||||||
|
"Compute and return the dew point, in ° Celsius, given temperature
|
||||||
|
in ° Celsius and relative humidity percentage; or `nil` if this data is
|
||||||
|
not available."
|
||||||
|
[&{:keys [temperature-celsius relative-humidity]}]
|
||||||
|
(when (and temperature-celsius relative-humidity)
|
||||||
|
(let [a' (alpha temperature-celsius relative-humidity)]
|
||||||
|
(/ (* (:b magnus-coefficients) a')
|
||||||
|
(- (:a magnus-coefficients) a')))))
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
:authority "https://en.wikipedia.org/wiki/Gas_laws"
|
:authority "https://en.wikipedia.org/wiki/Gas_laws"
|
||||||
:doc "In computing the relative humidity of air after it has warmed, I need
|
:doc "In computing the relative humidity of air after it has warmed, I need
|
||||||
to account for the change in volume. By Charles' Law, given stable
|
to account for the change in volume. By Charles' Law, given stable
|
||||||
pressure, volume is proportinal to absolute temperature (i.e. V=Tk, where K
|
pressure, volume is proportional to absolute temperature (i.e. V=Tk, where K
|
||||||
is a constant). However, the sources I have read do not give that constant,
|
is a constant). However, the sources I have read do not give that constant,
|
||||||
for air. But seeing what I'm interested in is that amount of air which is
|
for air. But seeing what I'm interested in is that amount of air which is
|
||||||
contained in a cubic metre at standard temperature and pressure, then *I
|
contained in a cubic metre at standard temperature and pressure, then *I
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
(:require [humidity.constants :refer [celsius-offset Pa]]))
|
(:require [humidity.constants :refer [celsius-offset Pa]]))
|
||||||
|
|
||||||
(defn volume-fn
|
(defn volume-fn
|
||||||
"Compute the volume, in m<sup>3</sup> of a quantity of air which would be
|
"Compute the volume, in m<sup>3</sup>, of a quantity of air which would be
|
||||||
1m<sup>3</sup> at standard temperature and pressure, given temperature in
|
1m<sup>3</sup> at standard temperature and pressure, given temperature in
|
||||||
° Kelvin and pressure in Pascals."
|
° Kelvin and pressure in Pascals."
|
||||||
[& {:keys [temperature-kelvin pressure-pascals]}]
|
[& {:keys [temperature-kelvin pressure-pascals]}]
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,16 @@
|
||||||
|
|
||||||
(deftest resolution-test
|
(deftest resolution-test
|
||||||
(testing "resolution")
|
(testing "resolution")
|
||||||
(let [expected {:relative-humidity 100,
|
(let [expected {:absolute-humidity 3953.618101887827,
|
||||||
:temperature-celsius 35,
|
|
||||||
:pressure-pascals 101325,
|
:pressure-pascals 101325,
|
||||||
|
:temperature-celsius 35,
|
||||||
|
:dew-point-celsius 35.00000000000001,
|
||||||
:pressure-millibars 1013.25,
|
:pressure-millibars 1013.25,
|
||||||
:saturation-vapour-pressure 5622.488734516426,
|
:volume 1.1281347245103424,
|
||||||
:temperature-kelvin 308.15,
|
:temperature-kelvin 308.15,
|
||||||
:absolute-humidity 3953.618101887827,
|
:relative-humidity 100,
|
||||||
:volume 1.1281347245103424}
|
:saturation-vapour-pressure 5622.488734516426,
|
||||||
|
:actual-vapour-pressure 4765.10094206357}
|
||||||
packet {:relative-humidity 100 :temperature-celsius 35}
|
packet {:relative-humidity 100 :temperature-celsius 35}
|
||||||
actual (resolution packet)]
|
actual (resolution packet)]
|
||||||
(is (= actual expected))))
|
(is (= actual expected))))
|
||||||
|
|
|
||||||
|
|
@ -1 +1,36 @@
|
||||||
(ns humidity.dew-point-test)
|
(ns humidity.dew-point-test
|
||||||
|
(:require [clojure.test :refer [deftest is testing]]
|
||||||
|
[humidity.constants :refer [celsius-offset]]
|
||||||
|
[humidity.dew-point :refer [dew-point-celsius-fn]]))
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;
|
||||||
|
;;; Copyright (C) 2026 Simon Brooke
|
||||||
|
;;;
|
||||||
|
;;; This program is free software; you can redistribute it and/or
|
||||||
|
;;; modify it under the terms of the GNU General Public License
|
||||||
|
;;; as published by the Free Software Foundation; either version 2
|
||||||
|
;;; of the License, or (at your option) any later version.
|
||||||
|
;;;
|
||||||
|
;;; This program is distributed in the hope that it will be useful,
|
||||||
|
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;;; GNU General Public License for more details.
|
||||||
|
;;;
|
||||||
|
;;; You should have received a copy of the GNU General Public License
|
||||||
|
;;; along with this program; if not, write to the Free Software
|
||||||
|
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
;;; USA.
|
||||||
|
;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(deftest dew-point-test
|
||||||
|
(testing "definitional"
|
||||||
|
(let [min-expected 34.9
|
||||||
|
max-expected 35.1
|
||||||
|
actual (dew-point-celsius-fn :relative-humidity 100
|
||||||
|
:temperature-celsius 35)]
|
||||||
|
(is (< min-expected actual max-expected))))
|
||||||
|
(testing "missing data"
|
||||||
|
(let [expected nil
|
||||||
|
actual (dew-point-celsius-fn :relative-humidity 100)]
|
||||||
|
(is (= expected actual)))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue