diff --git a/NAMESPACE b/NAMESPACE index 0298434..9c78e66 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -15,6 +15,8 @@ export(k.crusius) export(k.crusius.base) export(k.heiskanen) export(k.heiskanen.base) +export(k.klaus) +export(k.klaus.base) export(k.macIntyre) export(k.macIntyre.base) export(k.read) diff --git a/R/k.klaus.R b/R/k.klaus.R new file mode 100644 index 0000000..0a6aa46 --- /dev/null +++ b/R/k.klaus.R @@ -0,0 +1,64 @@ +# ---Author: Bennett McAfee, 2026-06-08 --- +# Last update: 2026-06-08 + +#'@export +k.klaus = function(ts.data, wnd.z, lake.area, spatial.int, method = c("linear", "power")){ + + if(!has.vars(ts.data, 'wnd')){ + stop('k.klaus requires a "wnd" (wind speed) column in the supplied data') + } + + wind = get.vars(ts.data, 'wnd') + + k600 = k.klaus.base(wind[,2], wnd.z, lake.area, spatial.int, method = method) + + return(data.frame(datetime=ts.data$datetime, k600=k600)) +} + + +#'@export +k.klaus.base <- function(wnd, wnd.z, lake.area, spatial.int, method = c("linear", "power")) { + + method <- match.arg(method) + + # converting m2 to km2 + lake.area <- lake.area / 1e6 + + # Converting uz to u10 + if (wnd.z != 10){ + wnd <- wind.scale.base(wnd = wnd, wnd.z = wnd.z) + } + + # helper logit function + logit.custom <- function(x){ + return(log(x / (1 - x))) + } + + # sanity checks + if (any(spatial.int <= 0 | spatial.int >= 1)) { + stop("spatial.int must be between 0 and 1 (exclusive)") + } + + if (method == "linear") { + k600 <- (0.328 * log10(lake.area) + 1.581) * wnd - 0.066 * logit.custom(spatial.int) + 1.266 + } else if (method == "power") { + k600 <- (0.281 * log10(lake.area) + 1.361) * (wnd ^ 1.097) - 0.072 * logit.custom(spatial.int) + 1.401 + } else if (method == "exp") { + # if (is.null(sdi)) { + # stop("sdi must be provided for exponential model") + # } + # k600 <- (-0.057 * logit.custom(spatial.int) + 2.366) * exp(wnd * (0.144 * log10(sdi) + 0.156)) + stop('The exponential model was removed per Klaus and Vachon (2020): "...[We] do not recommend using our +models that include SDI."') + } + + k600 <- k600 * (24/100) # convert cm/hr to m/day + + return(k600) +} + + +# -- References +# Klaus, Marcus, and Dominic Vachon. 2020. +# Challenges of Predicting Gas Transfer Velocity from Wind Measurements over Global Lakes. +# Aquatic Sciences 82 (3): 53. https://doi.org/10.1007/s00027-020-00729-9 diff --git a/R/k.read.R b/R/k.read.R index 49a1cb1..8fc0371 100644 --- a/R/k.read.R +++ b/R/k.read.R @@ -7,6 +7,7 @@ #'k.crusius #'k.vachon #'k.heiskanen +#'k.klaus #'@title Returns a timeseries of gas exchange velocity #'@description #'Returns the gas exchange velocity based on the chosen model in units of m/day @@ -24,13 +25,19 @@ #'k.vachon(ts.data, lake.area, params=c(2.51,1.48,0.39)) #' #'k.heiskanen(ts.data, wnd.z, Kd, atm.press) +#' +#'k.klaus(ts.data, wnd.z, lake.area, spatial.int, method = c("linear", "power")) #'@param ts.data vector of datetime in POSIXct format -#'@param method Only for \link{k.crusius}. String of valid method . Either "linear", "bilinear", or "power" +#'@param method Only for \link{k.crusius} and \link{k.klaus}. String of valid method. For k.crusius either "linear", "bilinear", or "power". For k.klaus either "linear" or "power" #'@param wnd.z height of wind measurement, m #'@param Kd Light attenuation coefficient (Units:m^-1) #'@param atm.press atmospheric pressure in mb #'@param lat Latitude, degrees north #'@param lake.area Lake area, m^2 +#'@param spatial.int Only for \link{k.klaus}. Numeric scale of spatial integration, expressed relative +#'to total lake surface area: from near 0 (a point-scale measurement, e.g. 1 m^2 / lake.area) +#'up to but not including 1 (whole-lake integration). Must satisfy 0 < spatial.int < 1; the value 1 is +#'not supported because the model uses logit(spatial.int). #'@param params Only for \link{k.vachon.base} and \link{k.macIntyre}. See details. #' #'@details Can change default parameters of MacIntyre and Vachon models. Default for Vachon is @@ -70,14 +77,18 @@ #'\emph{An approach to estimation of near-surface turbulence and CO2 transfer #'velocity from remote sensing data}. Journal of Marine Systems 66, (2007): 182-194. #' +#'Marcus Klaus and Dominic Vachon. \emph{Challenges of Predicting Gas Transfer Velocity from Wind Measurements over Global Lakes}. +#'Aquatic Sciences 82 (3): 53. (2020). +#' #'@author -#'Hilary Dugan, Jake Zwart, Luke Winslow, R. Iestyn. Woolway, Jordan S. Read +#'Hilary Dugan, Jake Zwart, Luke Winslow, R. Iestyn. Woolway, Jordan S. Read, Bennett McAfee #'@seealso #'\link{k.cole} #'\link{k.crusius} #'\link{k.macIntyre} #'\link{k.vachon} #'\link{k.heiskanen} +#'\link{k.klaus} #'@examples #'data.path = system.file('extdata', package="LakeMetabolizer") #' @@ -101,6 +112,7 @@ #'atm.press = 1018 #'lat = tb.data$metadata$latitude #'lake.area = tb.data$metadata$lakearea +#'spatial.int = 1/lake.area #' #'#for k.read and k.macIntyre, we need LW_net. #'#Calculate from the observations we have available. @@ -116,6 +128,8 @@ #' #'k600_macIntyre = k.macIntyre(ts.data, wnd.z=wnd.z, Kd=kd, atm.press=atm.press) #' +#'k600_klaus = k.klaus(ts.data, wnd.z=wnd.z, lake.area=lake.area, spatial.int=spatial.int) +#' #'@export k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ @@ -178,6 +192,7 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #'k.crusius.base #'k.vachon.base #'k.heiskanen.base +#'k.klaus.base #'@title Returns a timeseries of gas exchange velocity #'@description #'Returns the gas exchange velocity based on the chosen model in units of m/day @@ -199,8 +214,9 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #' #'k.heiskanen.base(wnd.z, Kd, atm.press, dateTime, Ts, z.aml, airT, wnd, RH, sw, lwnet) #' +#'k.klaus.base(wnd, wnd.z, lake.area, spatial.int, method = c("linear", "power")) #'@param wnd Numeric value of wind speed, (Units:m/s) -#'@param method Only for \link{k.crusius.base}. String of valid method . Either "constant", "bilinear", or "power" +#'@param method Only for \link{k.crusius.base} and \link{k.klaus.base}. String of valid method. For k.crusius.base either "constant", "bilinear", or "power". For k.klaus.base either "linear" or "power" #'@param wnd.z Height of wind measurement, (Units: m) #'@param Kd Light attenuation coefficient (Units: m^-1) #'@param lat Latitude, degrees north @@ -213,10 +229,15 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #'@param RH Numeric value of relative humidity, \% #'@param sw Numeric value of short wave radiation, W m^-2 #'@param lwnet Numeric value net long wave radiation, W m^-2 +#'@param spatial.int Only for \link{k.klaus}. Numeric scale of spatial integration, expressed relative +#'to total lake surface area: from near 0 (a point-scale measurement, e.g. 1 m^2 / lake.area) +#'up to but not including 1 (whole-lake integration). Must satisfy 0 < spatial.int < 1; the value 1 is +#'not supported because the model uses logit(spatial.int). #'@param params Optional parameter input, only for \link{k.vachon.base} and \link{k.macIntyre.base}. See details. #'@details Can change default parameters of MacIntyre and Vachon models. Default for Vachon is #'c(2.51,1.48,0.39). Default for MacIntyre is c(1.2,0.4872,1.4784). Heiskanen et al. (2014) uses MacIntyre #'model with c(0.5,0.77,0.3) and z.aml constant at 0.15. +#' #'@return Numeric value of gas exchange velocity (k600) in units of m/day. Before use, #'should be converted to appropriate gas using \link{k600.2.kGAS}. #'@keywords methods math @@ -248,8 +269,11 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #'\emph{An approach to estimation of near-surface turbulence and CO2 transfer #'velocity from remote sensing data}. Journal of Marine Systems 66, (2007): 182-194. #' +#'Marcus Klaus and Dominic Vachon. \emph{Challenges of Predicting Gas Transfer Velocity from Wind Measurements over Global Lakes}. +#'Aquatic Sciences 82 (3): 53. (2020). +#' #'@author -#'R. Iestyn. Woolway, Hilary Dugan, Luke Winslow, Jordan S Read, GLEON fellows +#'R. Iestyn. Woolway, Hilary Dugan, Luke Winslow, Jordan S Read, Bennett McAfee, GLEON fellows #'@seealso #'\link{k.cole} #'\link{k.read} @@ -257,6 +281,7 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #'\link{k.macIntyre} #'\link{k.vachon} #'\link{k.heiskanen} +#'\link{k.klaus} #'@examples #'wnd.z <- 2 #'Kd <- 2 @@ -271,6 +296,7 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #'RH <- 90 #'sw <- 800 #'lwnet <- -55 +#'spatial.int <- 1/lake.area #'timeStep <- 30 #' #'U10 <- wind.scale.base(wnd, wnd.z) @@ -288,6 +314,8 @@ k.read = function(ts.data, wnd.z, Kd, atm.press, lat, lake.area){ #'k600_macInytre <- k.macIntyre.base(wnd.z, Kd, atm.press, #'dateTime, Ts, z.aml, airT, wnd, RH, sw, lwnet) #' +#'k600_klaus <- k.klaus.base(wnd, wnd.z, lake.area, spatial.int) +#' #'@export k.read.base <- function(wnd.z, Kd, lat, lake.area, atm.press, dateTime, Ts, z.aml, airT, wnd, RH, sw, lwnet){ diff --git a/man/k.read.Rd b/man/k.read.Rd index 5ec6ba1..8bf9b84 100644 --- a/man/k.read.Rd +++ b/man/k.read.Rd @@ -8,6 +8,7 @@ \alias{k.crusius} \alias{k.vachon} \alias{k.heiskanen} +\alias{k.klaus} \title{Returns a timeseries of gas exchange velocity} \usage{ k.cole(ts.data) @@ -23,6 +24,8 @@ k.macIntyre(ts.data, wnd.z, Kd, atm.press,params=c(1.2,0.4872,1.4784)) k.vachon(ts.data, lake.area, params=c(2.51,1.48,0.39)) k.heiskanen(ts.data, wnd.z, Kd, atm.press) + +k.klaus(ts.data, wnd.z, lake.area, spatial.int, method = c("linear", "power")) } \arguments{ \item{ts.data}{vector of datetime in POSIXct format} @@ -37,7 +40,12 @@ k.heiskanen(ts.data, wnd.z, Kd, atm.press) \item{lake.area}{Lake area, m^2} -\item{method}{Only for \link{k.crusius}. String of valid method . Either "linear", "bilinear", or "power"} +\item{method}{Only for \link{k.crusius} and \link{k.klaus}. String of valid method. For k.crusius either "linear", "bilinear", or "power". For k.klaus either "linear" or "power"} + +\item{spatial.int}{Only for \link{k.klaus}. Numeric scale of spatial integration, expressed relative +to total lake surface area: from near 0 (a point-scale measurement, e.g. 1 m^2 / lake.area) +up to but not including 1 (whole-lake integration). Must satisfy 0 < spatial.int < 1; the value 1 is +not supported because the model uses logit(spatial.int).} \item{params}{Only for \link{k.vachon.base} and \link{k.macIntyre}. See details.} } @@ -75,6 +83,7 @@ wnd.z = 10 #because we converted to u10 atm.press = 1018 lat = tb.data$metadata$latitude lake.area = tb.data$metadata$lakearea +spatial.int = 1/lake.area #for k.read and k.macIntyre, we need LW_net. #Calculate from the observations we have available. @@ -90,6 +99,8 @@ atm.press=atm.press, lat=lat, lake.area=lake.area) k600_macIntyre = k.macIntyre(ts.data, wnd.z=wnd.z, Kd=kd, atm.press=atm.press) +k600_klaus = k.klaus(ts.data, wnd.z=wnd.z, lake.area=lake.area, spatial.int=spatial.int) + } \references{ Cole, J., J. Nina, and F. Caraco. \emph{Atmospheric exchange of carbon dioxide @@ -118,6 +129,9 @@ transfer coefficients in a boreal lake}. Tellus B 66, no.22827 (2014) Alexander Soloviev, Mark Donelan, Hans Graber, Brian Haus, Peter Schlussel. \emph{An approach to estimation of near-surface turbulence and CO2 transfer velocity from remote sensing data}. Journal of Marine Systems 66, (2007): 182-194. + +Marcus Klaus and Dominic Vachon. \emph{Challenges of Predicting Gas Transfer Velocity from Wind Measurements over Global Lakes}. +Aquatic Sciences 82 (3): 53. (2020). } \seealso{ \link{k.cole} @@ -125,9 +139,10 @@ velocity from remote sensing data}. Journal of Marine Systems 66, (2007): 182-19 \link{k.macIntyre} \link{k.vachon} \link{k.heiskanen} +\link{k.klaus} } \author{ -Hilary Dugan, Jake Zwart, Luke Winslow, R. Iestyn. Woolway, Jordan S. Read +Hilary Dugan, Jake Zwart, Luke Winslow, R. Iestyn. Woolway, Jordan S. Read, Bennett McAfee } \keyword{math} \keyword{methods} diff --git a/man/k.read.base.Rd b/man/k.read.base.Rd index d0ec805..7af7312 100644 --- a/man/k.read.base.Rd +++ b/man/k.read.base.Rd @@ -8,6 +8,7 @@ \alias{k.crusius.base} \alias{k.vachon.base} \alias{k.heiskanen.base} +\alias{k.klaus.base} \title{Returns a timeseries of gas exchange velocity} \usage{ k.cole.base(wnd) @@ -26,6 +27,8 @@ lwnet, params=c(1.2,0.4872,1.4784)) k.vachon.base(wnd, lake.area, params=c(2.51,1.48,0.39)) k.heiskanen.base(wnd.z, Kd, atm.press, dateTime, Ts, z.aml, airT, wnd, RH, sw, lwnet) + +k.klaus.base(wnd, wnd.z, lake.area, spatial.int, method = c("linear", "power")) } \arguments{ \item{wnd.z}{Height of wind measurement, (Units: m)} @@ -54,7 +57,12 @@ k.heiskanen.base(wnd.z, Kd, atm.press, dateTime, Ts, z.aml, airT, wnd, RH, sw, l \item{lwnet}{Numeric value net long wave radiation, W m^-2} -\item{method}{Only for \link{k.crusius.base}. String of valid method . Either "constant", "bilinear", or "power"} +\item{method}{Only for \link{k.crusius.base} and \link{k.klaus.base}. String of valid method. For k.crusius.base either "constant", "bilinear", or "power". For k.klaus.base either "linear" or "power"} + +\item{spatial.int}{Only for \link{k.klaus}. Numeric scale of spatial integration, expressed relative +to total lake surface area: from near 0 (a point-scale measurement, e.g. 1 m^2 / lake.area) +up to but not including 1 (whole-lake integration). Must satisfy 0 < spatial.int < 1; the value 1 is +not supported because the model uses logit(spatial.int).} \item{params}{Optional parameter input, only for \link{k.vachon.base} and \link{k.macIntyre.base}. See details.} } @@ -84,6 +92,7 @@ wnd <- 6 RH <- 90 sw <- 800 lwnet <- -55 +spatial.int <- 1/lake.area timeStep <- 30 U10 <- wind.scale.base(wnd, wnd.z) @@ -101,6 +110,8 @@ atm.press, dateTime, Ts, z.aml, airT, wnd, RH, sw, lwnet) k600_macInytre <- k.macIntyre.base(wnd.z, Kd, atm.press, dateTime, Ts, z.aml, airT, wnd, RH, sw, lwnet) +k600_klaus <- k.klaus.base(wnd, wnd.z, lake.area, spatial.int) + } \references{ Cole, J., J. Nina, and F. Caraco. \emph{Atmospheric exchange of carbon dioxide @@ -129,6 +140,9 @@ transfer coefficients in a boreal lake}. Tellus B 66, no.22827 (2014) Alexander Soloviev, Mark Donelan, Hans Graber, Brian Haus, Peter Schlussel. \emph{An approach to estimation of near-surface turbulence and CO2 transfer velocity from remote sensing data}. Journal of Marine Systems 66, (2007): 182-194. + +Marcus Klaus and Dominic Vachon. \emph{Challenges of Predicting Gas Transfer Velocity from Wind Measurements over Global Lakes}. +Aquatic Sciences 82 (3): 53. (2020). } \seealso{ \link{k.cole} @@ -137,9 +151,10 @@ velocity from remote sensing data}. Journal of Marine Systems 66, (2007): 182-19 \link{k.macIntyre} \link{k.vachon} \link{k.heiskanen} +\link{k.klaus} } \author{ -R. Iestyn. Woolway, Hilary Dugan, Luke Winslow, Jordan S Read, GLEON fellows +R. Iestyn. Woolway, Hilary Dugan, Luke Winslow, Jordan S Read, Bennett McAfee, GLEON fellows } \keyword{math} \keyword{methods}