Nothing
# Load default settings for CHNOSZ
reset()
info <- "Calculations of Helmholtz free energy and its derivatives are consistent with reference cases"
## Reference values of these terms are listed Table 6.6 of Wagner and Pruss, 2002
p <- c("phi", "phi.delta", "phi.delta.delta", "phi.tau", "phi.tau.tau", "phi.delta.tau")
# Reference values for case 1: T=500 K, rho=838.025 kg m-3
idealgas.ref.1 <- c(0.204797734e1, 0.384236747, -0.147637878, 0.904611106e1, -0.193249185e1, 0)
residual.ref.1 <- c(-0.342693206e1, -0.364366650, 0.856063701, -0.581403435e1, -0.223440737e1, -0.112176915e1)
# Reference values for case 1: T=647 K, rho=358 kg m-3
idealgas.ref.2 <- c(-0.156319605e1, 0.899441341, -0.808994726, 0.980343918e1, -0.343316334e1, 0)
residual.ref.2 <- c(-0.121202657e1, -0.714012024, 0.475730696, -0.321722501e1, -0.996029507e1, -0.133214720e1)
## Set up the problem
# Critical point constants
T.critical <- 647.096 # K
rho.critical <- 322 # kg m-3
# T and rho for cases 1 and 2
T <- c(500, 647)
rho <- c(838.025, 358)
# delta and tau for cases 1 and 2
delta <- rho / rho.critical
tau <- T.critical / T
# Dalculated ideal gas and residual parts for case 1
idealgas.calc.1 <- sapply(p, CHNOSZ:::IAPWS95.idealgas, delta[1], tau[1])
residual.calc.1 <- sapply(p, CHNOSZ:::IAPWS95.residual, delta[1], tau[1])
# Calculated ideal gas and residual parts for case 2
idealgas.calc.2 <- sapply(p, CHNOSZ:::IAPWS95.idealgas, delta[2], tau[2])
residual.calc.2 <- sapply(p, CHNOSZ:::IAPWS95.residual, delta[2], tau[2])
## Perform the tests
# We almost get away without increasing the tolerance in any test ...
expect_equal(idealgas.calc.1, idealgas.ref.1, check.attributes = FALSE, info = info)
expect_equal(residual.calc.1, residual.ref.1, check.attributes = FALSE, info = info)
expect_equal(idealgas.calc.2, idealgas.ref.2, check.attributes = FALSE, info = info)
# ... however an offset is apparent in the value of the residual phi.delta.delta for case 2
expect_equal(residual.calc.2, residual.ref.2, check.attributes = FALSE, tolerance = 1e-5, info = info)
info <- "Calculations of thermodynamic properties are consistent with reference values"
## These are the properties we test - from Table 13.1 of Wagner and Pruss, 2002
## (speed of sound omitted as it's not currently implemented)
p <- c("P", "H", "S", "Cv", "Cp")
## A selection of T and rho at vapor-liquid boundary
## (NOTE: excluding triple and critical points; we have some unresolved issues there)
T <- c(274, 320, 368, 416, 464, 512, 560, 608, 647)
rho.liquid <- c(999.843, 989.387, 961.984, 923.577, 875.125, 814.982, 737.831, 626.74, 357.34)
rho.vapor <- c(0.00514, 0.07166, 0.50231, 2.1203, 6.5107, 16.409, 37.147, 84.173, 286.51)
## Reference values
P.ref <- c(0.000650, 0.010546, 0.084142, 0.39166, 1.2788, 3.2798, 7.1062, 13.681, 22.038)
H.liquid.ref <- c(3.544, 196.170, 397.457, 601.396, 811.225, 1032.06, 1273.11, 1558.42, 2029.44)
H.vapor.ref <- c(2502.46, 2585.71, 2667.37, 2737.09, 2785.91, 2803.05, 2771.24, 2646.01, 2148.56)
S.liquid.ref <- c(0.0130, 0.6629, 1.2487, 1.7687, 2.2436, 2.6914, 3.1319, 3.6034, 4.3224)
S.vapor.ref <- c(9.1331, 8.1302, 7.4169, 6.9025, 6.4994, 6.1504, 5.8071, 5.3922, 4.5065)
cv.liquid.ref <- c(4.2156, 4.0416, 3.7950, 3.5560, 3.3523, 3.1884, 3.0722, 3.0617, 6.2344)
cv.vapor.ref <- c(1.4191, 1.4627, 1.5428, 1.7138, 2.0015, 2.3697, 2.8225, 3.4538, 6.2740)
cp.liquid.ref <- c(4.2171, 4.1807, 4.2101, 4.2892, 4.4513, 4.7616, 5.4239, 7.6169, 3905.2)
cp.vapor.ref <- c(1.8852, 1.9417, 2.0601, 2.3334, 2.8561, 3.7263, 5.4099, 10.805, 5334.1)
## Calculated values
liquid.calc <- IAPWS95(p, T, rho.liquid)
vapor.calc <- IAPWS95(p, T, rho.vapor)
## The tests
# Take P to 5 significant digits but not more than 6 decimals
expect_equal(round(signif(liquid.calc$p, 5), 6), P.ref, tolerance = 1e-3, info = info)
expect_equal(round(signif(vapor.calc$p, 5), 6), P.ref, tolerance = 1e-4, info = info)
# Take H to 6 significant digits but not more than 3 decimals
expect_equal(round(signif(liquid.calc$h, 6), 3), H.liquid.ref, tolerance = 1e-5, info = info)
expect_equal(round(signif(vapor.calc$h, 6), 3), H.vapor.ref, info = info) # spot on!
# Round S to 4 decimals
expect_equal(round(liquid.calc$s, 4), S.liquid.ref, info = info) # spot on!
expect_equal(round(vapor.calc$s, 4), S.vapor.ref, tolerance = 1e-4, info = info)
# Round cv to 4 decimals
expect_equal(round(liquid.calc$cv, 4), cv.liquid.ref, tolerance = 1e-4, info = info)
expect_equal(round(vapor.calc$cv, 4), cv.vapor.ref, tolerance = 1e-4, info = info)
# Take cp to 5 significant digits but not more than 4 decimals
# Note high tolerance setting: the highest temperature is the challenge
expect_equal(round(signif(liquid.calc$cp, 5), 4), cp.liquid.ref, tolerance = 1e0, info = info)
expect_equal(round(signif(vapor.calc$cp, 5), 4), cp.vapor.ref, tolerance = 1e-1, info = info)
info <- "Calculations are possible at low temperatures"
# The sequences start at the lowest whole-number temperature (K)
# Where the function returns a value of density at the given pressure
expect_false(any(is.na(water.IAPWS95("rho", T = seq(234, 274, 3), P = rep(1, 14)))), info = info)
expect_false(any(is.na(water.IAPWS95("rho", T = seq(227, 272, 3), P = rep(1000, 16)))), info = info)
# Reference
# Wagner, W. and Pruss, A. (2002)
# The IAPWS formulation 1995 for the thermodynamic properties of
# ordinary water substance for general and scientific use
# J. Phys. Chem. Ref. Data 31, 387--535. https://doi.org/10.1063/1.1461829
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.