Added two functions: O2 solubility in water

from empirical fits, and one function that returns water vapour pressure (simply interpolates based on the previously available dataset).
master
Taha Ahmed 5 years ago
parent 681e636bf4
commit 969244320c
  1. 2
      DESCRIPTION
  2. 2
      NAMESPACE
  3. 137
      R/chemistry-tools.R
  4. 65
      man/OxygenSolubilityWater.Rd
  5. 25
      man/VapourPressureWater.Rd

@ -1,7 +1,7 @@
Package: common
Type: Package
Title: chepec common
Version: 0.0.0.9007
Version: 0.0.0.9008
Description: Commonly used functions and scripts.
Authors@R: person("Taha", "Ahmed", email = "taha@chepec.se", role = c("aut", "cre"))
License: GPL-3

@ -8,12 +8,14 @@ export(GenericXtableSetAttributes)
export(Kelvin2Celsius)
export(LoadRData2Variable)
export(LongtableXtableHeader)
export(OxygenSolubilityWater)
export(ProvideSampleId)
export(RefCanonicalName)
export(SHE2AVS)
export(SubfigureGenerator)
export(SubstrateHistory)
export(TabularXtableHeader)
export(VapourPressureWater)
export(as.SHE)
export(as.degrees)
export(as.radians)

@ -16,3 +16,140 @@ molarity2mass <- function(formulamass, volume, molarity) {
# [g * mol-1] * [liter] * [mole * liter-1] = [g]
return(mass)
}
#' Vapour pressure of water
#'
#' Vapour pressure of water as a function of temperature
#' This function returns the vapour pressure of water at the given
#' temperature(s) from the common::vapourwater dataset.
#'
#' @param temperature numeric vector, in degrees Celsius
#'
#' @return vapour pressure of water, in kilopascal
#' @export
#'
#' @examples
#' \dontrun{
#' VapourPressureWater(45)
#' VapourPressureWater(c(20, 25, 45, 60))
#' }
VapourPressureWater <- function(temperature) {
data <- common::vapourwater
# if T outside range in data, warn the user
if (any(temperature < min(data$temperature)) | any(temperature > max(data$temperature))) {
warning("At least one supplied temperature is outside the data range (",
paste(range(data$temperature), collapse=" - "),
" Celsius). Returning NAs for those values.")
}
# The vapourwater dataset only contains data for every degree celsius (or less),
# so we use the interpolation function to fill in the rest.
# Note that approx(rule = 1) returns NAs for input outside the data range.
pressure <-
stats::approx(x = data$temperature, y = data$pressure,
method = "linear", rule = 1,
xout = temperature)$y
return(pressure)
}
#' Oxygen solubility in water
#'
#' Oxygen solubility in water which is in contact with
#' air saturated with water vapour, as a function of
#' temperature and at a total pressure of 760 torr.
#'
#' Some background: as the temperature of a gasesous solution is raised the
#' gas is driven off until complete degassing occurs at the boiling point
#' of the solvent. This variation of solubility with temperature can be
#' derived from thermodynamic first principles.
#' But the variation of oxygen solubility in water cannot be represented by a
#' simple relationship (derived from thermodynamic first principles), and so
#' more complicated expressions which are fitted to empirical data have
#' to be used.
#'
#' Hitchman, Measurement of Dissolved Oxygen, 1978 reproduce a table by
#' Battino and Clever (1966) that presents experimental values of the
#' so-called Bunsen absorption coefficient (this is the volume of gas, at 0 C
#' and 760 torr, that, at the temperature of measurement, is dissolved in one
#' volume of the solvent when the partial pressure of the gas is 760 torr)
#' recorded by eleven research groups up until 1965. The standard error of the
#' mean value is never greater +-0.5%. The mean values from this table are
#' probably accurate enough for most applications.
#' Hitchman notes that the data in this table can be fitted by two forms of
#' equations: one form obtained from Henry's law (under the restriction that
#' the partial pressure of the gas remains constant), and another form by
#' describing the variation with temperature by fitting a general power series.
#' The latter approach is used in this function.
#'
#' Hitchman chooses to fit a fourth degree polynomial, and found that the
#' square of the correlation coefficient was 0.999996.
#'
#' For more background and detailed derivation of the formula used here,
#' see section 2.2 (pp. 11) in Hitchman.
#'
#' This formula is strictly speaking only valid for 0 < T < 50 celsius.
#' The function will return values outside this range, but with a warning.
#'
#' @param temperature numeric, vector. In degrees Celsius.
#'
#' @return a dataframe with the following columns:
#' + "temperature" same as the supplied temperature
#' + "g/cm-3" oxygen solubility expressed as gram per cubic cm
#' + "mg/L" ditto expressed as milligram per litre
#' + "mol/L" ditto expressed as moles per litre (molarity)
#' + "permoleculewater" number of O2 molecules per molecule of water
#' Note: mg/L is equivalent to ppm by weight (since water has approx
#' unit density in the temperature range 0-50 Celsius).
#' @export
#' @examples
#' \dontrun{
#' OxygenSolubilityWater(22)
#' OxygenSolubilityWater(c(2, 7, 12, 30))
#' }
OxygenSolubilityWater <- function(temperature) {
if (any(temperature < 0) | any(temperature > 50)) {
warning("This function is fitted to data within the range 0 - 50 Celsius. ",
"You are now extrapolating.")
}
# formula weight of oxygen
oxygen.fw <- 15.9994 # gram per mole
# formula weight of water
water.fw <- 18.02
# oxygen ratio in dry air (20.95%)
oxygen.dryair <- 20.95 / 100
# coefficients (from Hitchman)
A <- 4.9E1
B <- -1.335
C <- 2.759E-2
D <- -3.235E-4
E <- 1.614E-6
# conversion factor from Bunsen to g/cm-3
conv.factor <- (2 * oxygen.fw) / 22.414E3
# Bunsen absorption coefficient, commonly denoted as Greek alpha
alpha <-
1E-3 * (A + B * temperature + C * temperature^2 +
D * temperature^3 + E * temperature^4)
# solubility of oxygen, in gram per cm-3
oxygen.solubility <-
data.frame(temperature = temperature,
grampercm3 =
(conv.factor * oxygen.dryair / 760) * alpha *
# keep in mind that VapourPressureWater() returns values in kilopascal
(760 - pascal2torr(1E3 * common::VapourPressureWater(temperature))),
mgperlitre =
1E6 * (conv.factor * oxygen.dryair / 760) * alpha *
(760 - pascal2torr(1E3 * common::VapourPressureWater(temperature))),
molperlitre =
1E3 * (conv.factor * oxygen.dryair / 760) * alpha *
(760 - pascal2torr(1E3 * common::VapourPressureWater(temperature))) /
(2 * oxygen.fw))
# Number of O2 molecules per water molecule
oxygen.solubility$permoleculewater <-
# note: using a water density value that's approx the average in the
# temperature range 0 - 50 Celsius
((1E3 * oxygen.solubility$grampercm3) / oxygen.fw) / (995.00 / water.fw)
return(oxygen.solubility)
}

@ -0,0 +1,65 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/chemistry-tools.R
\name{OxygenSolubilityWater}
\alias{OxygenSolubilityWater}
\title{Oxygen solubility in water}
\usage{
OxygenSolubilityWater(temperature)
}
\arguments{
\item{temperature}{numeric, vector. In degrees Celsius.}
}
\value{
a dataframe with the following columns:
+ "temperature" same as the supplied temperature
+ "g/cm-3" oxygen solubility expressed as gram per cubic cm
+ "mg/L" ditto expressed as milligram per litre
+ "mol/L" ditto expressed as moles per litre (molarity)
+ "permoleculewater" number of O2 molecules per molecule of water
Note: mg/L is equivalent to ppm by weight (since water has approx
unit density in the temperature range 0-50 Celsius).
}
\description{
Oxygen solubility in water which is in contact with
air saturated with water vapour, as a function of
temperature and at a total pressure of 760 torr.
}
\details{
Some background: as the temperature of a gasesous solution is raised the
gas is driven off until complete degassing occurs at the boiling point
of the solvent. This variation of solubility with temperature can be
derived from thermodynamic first principles.
But the variation of oxygen solubility in water cannot be represented by a
simple relationship (derived from thermodynamic first principles), and so
more complicated expressions which are fitted to empirical data have
to be used.
Hitchman, Measurement of Dissolved Oxygen, 1978 reproduce a table by
Battino and Clever (1966) that presents experimental values of the
so-called Bunsen absorption coefficient (this is the volume of gas, at 0 C
and 760 torr, that, at the temperature of measurement, is dissolved in one
volume of the solvent when the partial pressure of the gas is 760 torr)
recorded by eleven research groups up until 1965. The standard error of the
mean value is never greater +-0.5%. The mean values from this table are
probably accurate enough for most applications.
Hitchman notes that the data in this table can be fitted by two forms of
equations: one form obtained from Henry's law (under the restriction that
the partial pressure of the gas remains constant), and another form by
describing the variation with temperature by fitting a general power series.
The latter approach is used in this function.
Hitchman chooses to fit a fourth degree polynomial, and found that the
square of the correlation coefficient was 0.999996.
For more background and detailed derivation of the formula used here,
see section 2.2 (pp. 11) in Hitchman.
This formula is strictly speaking only valid for 0 < T < 50 celsius.
The function will return values outside this range, but with a warning.
}
\examples{
\dontrun{
OxygenSolubilityWater(22)
OxygenSolubilityWater(c(2, 7, 12, 30))
}
}

@ -0,0 +1,25 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/chemistry-tools.R
\name{VapourPressureWater}
\alias{VapourPressureWater}
\title{Vapour pressure of water}
\usage{
VapourPressureWater(temperature)
}
\arguments{
\item{temperature}{numeric vector, in degrees Celsius}
}
\value{
vapour pressure of water, in kilopascal
}
\description{
Vapour pressure of water as a function of temperature
This function returns the vapour pressure of water at the given
temperature(s) from the common::vapourwater dataset.
}
\examples{
\dontrun{
VapourPressureWater(45)
VapourPressureWater(c(20, 25, 45, 60))
}
}
Loading…
Cancel
Save