[CHNOSZ-commits] r890 - in pkg/CHNOSZ: . R man vignettes
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Thu May 8 14:34:31 CEST 2025
Author: jedick
Date: 2025-05-08 14:34:30 +0200 (Thu, 08 May 2025)
New Revision: 890
Added:
pkg/CHNOSZ/R/mod.buffer.R
pkg/CHNOSZ/man/mod.buffer.Rd
Removed:
pkg/CHNOSZ/R/buffer.R
pkg/CHNOSZ/man/buffer.Rd
Modified:
pkg/CHNOSZ/DESCRIPTION
pkg/CHNOSZ/vignettes/anintro.Rmd
pkg/CHNOSZ/vignettes/postprocess.sh
pkg/CHNOSZ/vignettes/vig.bib
Log:
Add section on buffers to anintro.Rmd
Modified: pkg/CHNOSZ/DESCRIPTION
===================================================================
--- pkg/CHNOSZ/DESCRIPTION 2025-05-05 10:07:10 UTC (rev 889)
+++ pkg/CHNOSZ/DESCRIPTION 2025-05-08 12:34:30 UTC (rev 890)
@@ -1,6 +1,6 @@
-Date: 2025-05-05
+Date: 2025-05-08
Package: CHNOSZ
-Version: 2.1.0-61
+Version: 2.1.0-62
Title: Thermodynamic Calculations and Diagrams for Geochemistry
Authors at R: c(
person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"),
Deleted: pkg/CHNOSZ/R/buffer.R
===================================================================
--- pkg/CHNOSZ/R/buffer.R 2025-05-05 10:07:10 UTC (rev 889)
+++ pkg/CHNOSZ/R/buffer.R 2025-05-08 12:34:30 UTC (rev 890)
@@ -1,213 +0,0 @@
-# CHNOSZ/buffer.R
-# Calculate chemical activities of buffered species
-# 20061102 jmd
-
-mod.buffer <- function(name, species = NULL, state = "cr", logact = 0) {
- # 20071102 add or change a buffer system
- thermo <- get("thermo", CHNOSZ)
- if(is.null(species)) {
- iname <- which(name == thermo$buffer$name)
- if(length(iname) > 0) species <- thermo$buffer$species[iname]
- else species <- character()
- }
- ls <- length(species)
- if(ls < length(name) | ls < length(state) | ls < length(logact))
- stop('species must be at least as long as the other arguments')
- if(length(name) != ls) name <- rep(name, length.out = ls)
- add <- TRUE
- if(TRUE %in% (name %in% thermo$buffer$name)) {
- add <- FALSE
- imod <- which(thermo$buffer$name %in% name & thermo$buffer$species %in% species)
- if(length(imod)>0) {
- if(state[1] == '') {
- thermo$buffer <- thermo$buffer[-imod, ]
- assign("thermo", thermo, CHNOSZ)
- message(paste('mod.buffer: removed ', c2s(species), ' in ', c2s(unique(name)), ' buffer', sep = ''))
- } else {
- if(missing(state)) state <- thermo$buffer$state[imod]
- if(missing(logact)) logact <- thermo$buffer$logact[imod]
- if(length(state) != ls) state <- rep(state,length.out = ls)
- if(length(logact) != ls) logact <- rep(logact,length.out = ls)
- state.old <- thermo$buffer$state[imod]
- logact.old <- thermo$buffer$logact[imod]
- thermo$buffer$state[imod] <- state
- thermo$buffer$logact[imod] <- logact
- assign("thermo", thermo, CHNOSZ)
- if(identical(state.old, state) & identical(logact.old, logact)) {
- message(paste('mod.buffer: nothing changed for ', c2s(species), ' in ', c2s(unique(name)), ' buffer', sep = ''))
- } else {
- message(paste('mod.buffer: changed state and/or logact of ', c2s(species), ' in ', c2s(unique(name)), ' buffer', sep = ''))
- }
- }
- } else {
- add <- TRUE
- }
- }
- if(add) {
- if(state[1] == '') state <- rep(thermo$opt$state, length.out = ls)
- t <- data.frame(name = name, species = species, state = state, logact = logact)
- thermo$buffer <- rbind(thermo$buffer, t)
- assign("thermo", thermo, CHNOSZ)
- message(paste('mod.buffer: added',c2s(unique(name))))
- }
- return(invisible(thermo$buffer[thermo$buffer$name %in% name, ]))
-}
-
-### Unexported functions ###
-
-buffer <- function(logK = NULL, ibasis = NULL, logact.basis = NULL, is.buffer = NULL, balance = 'PBB') {
- thermo <- get("thermo", CHNOSZ)
- # If logK is NULL load the buffer species,
- # otherwise perform buffer calculations
- if(is.null(logK)) {
- # Load the buffer species
- buffers <- unique(as.character(thermo$basis$logact)[!can.be.numeric(as.character(thermo$basis$logact))])
- ispecies.new <- list()
- for(k in 1:length(buffers)) {
- ibasis <- which(thermo$basis$logact == buffers[k])
- ispecies <- numeric()
- for(i in 1:length(ibasis)) {
- ib <- as.character(thermo$buffer$name) == as.character(thermo$basis$logact[ibasis[i]])
- species <- as.character(thermo$buffer$species)[ib]
- state <- as.character(thermo$buffer$state)[ib]
- #ibuff <- info(species,state,quiet = TRUE)
- ispecies <- c(ispecies, species(species, state, index.return = TRUE, add = TRUE))
- }
- ispecies.new <- c(ispecies.new, list(ispecies))
- # Make sure to set the activities
- species(ispecies, thermo$buffer$logact[ib])
- }
- names(ispecies.new) <- buffers
- return(ispecies.new)
- }
-
- # Sometimes (e.g. PPM) the buffer species are identified multiple
- # times, causing problems for square matrices
- # Make the species appear singly
- is.buffer <- unique(is.buffer)
- bufbasis <- species.basis(thermo$species$ispecies[is.buffer])
- bufname <- thermo$basis$logact[ibasis[1]]
- basisnames <- rownames(thermo$basis)
- are.proteins <- grep('_', as.character(thermo$species$name[is.buffer]))
- if((length(are.proteins) > 0 & balance == 'PBB') | balance == 1) {
- if(balance == 1) {
- basisnames <- c('product', basisnames)
- nb <- rep(1, nrow(bufbasis))
- bufbasis <- cbind(data.frame(product = nb), bufbasis)
- } else {
- basisnames <- c('PBB', basisnames)
- # Prepend a PBB column to bufbasis and increment ibasis by 1
- nb <- as.numeric(protein.length(thermo$species$name[is.buffer]))
- bufbasis <- cbind(data.frame(PBB = nb), bufbasis)
- }
- ibasis <- ibasis + 1
- # Make logact.basis long enough
- tl <- length(logact.basis)
- logact.basis[[tl+1]] <- logact.basis[[tl]]
- # Rotate the entries so that the new one is first
- ilb <- c(tl+1, 1:tl)
- logact.basis <- logact.basis[ilb]
- }
- # Say hello
- #message(paste("buffer: '",bufname,"', of ",length(is.buffer),' species, ',length(ibasis),' activity(s) requested.',sep = ''))
- ibasisrequested <- ibasis
- # Check and maybe add to the number of buffered activities
- ibasisadded <- numeric()
- if( (length(ibasis)+1) != length(is.buffer) & length(is.buffer) > 1) {
- # Try to add buffered activities the user didn't specify
- # (e.g. H2S in PPM buffer if only H2 was requested)
- for(i in 1:(length(is.buffer) - (length(ibasis)+1))) {
- newbasis <- NULL
- # We want to avoid any basis species that might be used as the conservant
- # look for additional activities to buffer ... do columns in reverse
- for(j in ncol(bufbasis):1) {
- if(j %in% ibasis) next
- if(FALSE %in% (bufbasis[,j] == 0)) {
- newbasis <- j
- break
- }
- }
- if(!is.null(newbasis)) {
- ibasis <- c(ibasis, newbasis)
- ibasisadded <- c(ibasisadded, newbasis)
- } else {
- stop('can not find enough buffered basis species for ', thermo$basis$logact[ibasis[1]], '.', sep = '')
- }
- }
- }
- # And the leftovers
- #xx <- as.data.frame(bufbasis[,-ibasis])
- # The final buffered activity: the would-be conserved component
- newbasis <- NULL
- if(length(is.buffer) > 1) {
- # First try to get one that is present in all species
- for(i in ncol(bufbasis):1) {
- if(i %in% ibasis) next
- if(!TRUE %in% (bufbasis[, i] == 0)) newbasis <- i
- }
- # Or look for one that is present at all
- if(is.null(newbasis)) for(i in ncol(bufbasis):1) {
- if(i %in% ibasis) next
- if(FALSE %in% (bufbasis[, i] == 0)) newbasis <- i
- }
- if(!is.null(newbasis)) {
- ibasis <- c(ibasis,newbasis)
- #message(paste('buffer: the conserved activity is ', basisnames[newbasis], '.', sep = ''))
- #thermo$basis$logact[newbasis] <<- thermo$basis$logact[ibasis[1]]
- }
- else stop('no conserved activity found in your buffer (not enough basis species?)!')
- }
- if(is.null(newbasis)) context <- '' else context <- paste(', ', basisnames[newbasis], ' (conserved)', sep = '')
- reqtext <- paste(c2s(basisnames[ibasisrequested]), ' (active)', sep = '')
- if(length(ibasisadded) == 0) addtext <- '' else addtext <- paste(', ', c2s(basisnames[ibasisadded]), sep = '')
- message(paste("buffer: '", bufname, "' for activity of ", reqtext, addtext, context, sep = ""))
- # There could still be stuff here (over-defined system?)
- xx <- bufbasis[, -ibasis, drop = FALSE]
- # For the case when all activities are buffered
- if(ncol(xx) == 0) xx <- data.frame(xx = 0)
- # Our stoichiometric matrix - should be square
- A <- as.data.frame(bufbasis[,ibasis])
- # Determine conservation coefficients
- # Values for the known vector
- B <- list()
- for(i in 1:length(is.buffer)) {
- b <- -logK[[is.buffer[i]]] + thermo$species$logact[is.buffer[i]]
- if(ncol(xx) > 0) {
- if(is.list(xx)) xxx <- xx[[1]] else xxx <- xx
- if(ncol(xx) == 1 & identical(as.numeric(xxx), 0)) {
- # Do nothing
- } else {
- for(j in 1:ncol(xx)) {
- bs <- xx[i, j] * logact.basis[[match(colnames(xx)[j], basisnames)]]
- if(!is.matrix(bs)) bs <- matrix(bs, byrow = TRUE, nrow = nrow(as.data.frame(logact.basis[[1]])))
- if(ncol(bs) == 1) b <- matrix(b)
- b <- b - bs
- }
- }
- }
- # Force this to be matrix so indexing works at a single point (no variables defined in affinity()) 20201102
- B[[i]] <- as.matrix(b)
- }
- # A place to put the results
- X <- rep(B[1],length(ibasis))
- for(i in 1:nrow(B[[1]])) {
- for(j in 1:ncol(B[[1]])) {
- b <- numeric()
- for(k in 1:length(B)) b <- c(b, B[[k]][i, j])
- AAA <- A
- # solve for the activities in the buffer
- t <- solve(AAA, b)
- for(k in 1:length(ibasis))
- X[[k]][i, j] <- t[k]
- }
- }
- # Store results
- for(i in 1:length(ibasis)) {
- if(ncol(X[[i]]) == 1) X[[i]] <- as.numeric(X[[i]])
- else if(nrow(X[[i]]) == 1) X[[i]] <- as.matrix(X[[i]], nrow = 1)
- logact.basis[[ibasis[i]]] <- X[[i]]
- }
- names(logact.basis) <- basisnames
-
- return(list(ibasis = ibasis, logact.basis = logact.basis))
-}
Copied: pkg/CHNOSZ/R/mod.buffer.R (from rev 889, pkg/CHNOSZ/R/buffer.R)
===================================================================
--- pkg/CHNOSZ/R/mod.buffer.R (rev 0)
+++ pkg/CHNOSZ/R/mod.buffer.R 2025-05-08 12:34:30 UTC (rev 890)
@@ -0,0 +1,213 @@
+# CHNOSZ/buffer.R
+# Calculate chemical activities of buffered species
+# 20061102 jmd
+
+mod.buffer <- function(name, species = NULL, state = "cr", logact = 0) {
+ # 20071102 add or change a buffer system
+ thermo <- get("thermo", CHNOSZ)
+ if(is.null(species)) {
+ iname <- which(name == thermo$buffer$name)
+ if(length(iname) > 0) species <- thermo$buffer$species[iname]
+ else species <- character()
+ }
+ ls <- length(species)
+ if(ls < length(name) | ls < length(state) | ls < length(logact))
+ stop('species must be at least as long as the other arguments')
+ if(length(name) != ls) name <- rep(name, length.out = ls)
+ add <- TRUE
+ if(TRUE %in% (name %in% thermo$buffer$name)) {
+ add <- FALSE
+ imod <- which(thermo$buffer$name %in% name & thermo$buffer$species %in% species)
+ if(length(imod)>0) {
+ if(state[1] == '') {
+ thermo$buffer <- thermo$buffer[-imod, ]
+ assign("thermo", thermo, CHNOSZ)
+ message(paste('mod.buffer: removed ', c2s(species), ' in ', c2s(unique(name)), ' buffer', sep = ''))
+ } else {
+ if(missing(state)) state <- thermo$buffer$state[imod]
+ if(missing(logact)) logact <- thermo$buffer$logact[imod]
+ if(length(state) != ls) state <- rep(state,length.out = ls)
+ if(length(logact) != ls) logact <- rep(logact,length.out = ls)
+ state.old <- thermo$buffer$state[imod]
+ logact.old <- thermo$buffer$logact[imod]
+ thermo$buffer$state[imod] <- state
+ thermo$buffer$logact[imod] <- logact
+ assign("thermo", thermo, CHNOSZ)
+ if(identical(state.old, state) & identical(logact.old, logact)) {
+ message(paste('mod.buffer: nothing changed for ', c2s(species), ' in ', c2s(unique(name)), ' buffer', sep = ''))
+ } else {
+ message(paste('mod.buffer: changed state and/or logact of ', c2s(species), ' in ', c2s(unique(name)), ' buffer', sep = ''))
+ }
+ }
+ } else {
+ add <- TRUE
+ }
+ }
+ if(add) {
+ if(state[1] == '') state <- rep(thermo$opt$state, length.out = ls)
+ t <- data.frame(name = name, species = species, state = state, logact = logact)
+ thermo$buffer <- rbind(thermo$buffer, t)
+ assign("thermo", thermo, CHNOSZ)
+ message(paste('mod.buffer: added',c2s(unique(name))))
+ }
+ return(invisible(thermo$buffer[thermo$buffer$name %in% name, ]))
+}
+
+### Unexported functions ###
+
+buffer <- function(logK = NULL, ibasis = NULL, logact.basis = NULL, is.buffer = NULL, balance = 'PBB') {
+ thermo <- get("thermo", CHNOSZ)
+ # If logK is NULL load the buffer species,
+ # otherwise perform buffer calculations
+ if(is.null(logK)) {
+ # Load the buffer species
+ buffers <- unique(as.character(thermo$basis$logact)[!can.be.numeric(as.character(thermo$basis$logact))])
+ ispecies.new <- list()
+ for(k in 1:length(buffers)) {
+ ibasis <- which(thermo$basis$logact == buffers[k])
+ ispecies <- numeric()
+ for(i in 1:length(ibasis)) {
+ ib <- as.character(thermo$buffer$name) == as.character(thermo$basis$logact[ibasis[i]])
+ species <- as.character(thermo$buffer$species)[ib]
+ state <- as.character(thermo$buffer$state)[ib]
+ #ibuff <- info(species,state,quiet = TRUE)
+ ispecies <- c(ispecies, species(species, state, index.return = TRUE, add = TRUE))
+ }
+ ispecies.new <- c(ispecies.new, list(ispecies))
+ # Make sure to set the activities
+ species(ispecies, thermo$buffer$logact[ib])
+ }
+ names(ispecies.new) <- buffers
+ return(ispecies.new)
+ }
+
+ # Sometimes (e.g. PPM) the buffer species are identified multiple
+ # times, causing problems for square matrices
+ # Make the species appear singly
+ is.buffer <- unique(is.buffer)
+ bufbasis <- species.basis(thermo$species$ispecies[is.buffer])
+ bufname <- thermo$basis$logact[ibasis[1]]
+ basisnames <- rownames(thermo$basis)
+ are.proteins <- grep('_', as.character(thermo$species$name[is.buffer]))
+ if((length(are.proteins) > 0 & balance == 'PBB') | balance == 1) {
+ if(balance == 1) {
+ basisnames <- c('product', basisnames)
+ nb <- rep(1, nrow(bufbasis))
+ bufbasis <- cbind(data.frame(product = nb), bufbasis)
+ } else {
+ basisnames <- c('PBB', basisnames)
+ # Prepend a PBB column to bufbasis and increment ibasis by 1
+ nb <- as.numeric(protein.length(thermo$species$name[is.buffer]))
+ bufbasis <- cbind(data.frame(PBB = nb), bufbasis)
+ }
+ ibasis <- ibasis + 1
+ # Make logact.basis long enough
+ tl <- length(logact.basis)
+ logact.basis[[tl+1]] <- logact.basis[[tl]]
+ # Rotate the entries so that the new one is first
+ ilb <- c(tl+1, 1:tl)
+ logact.basis <- logact.basis[ilb]
+ }
+ # Say hello
+ #message(paste("buffer: '",bufname,"', of ",length(is.buffer),' species, ',length(ibasis),' activity(s) requested.',sep = ''))
+ ibasisrequested <- ibasis
+ # Check and maybe add to the number of buffered activities
+ ibasisadded <- numeric()
+ if( (length(ibasis)+1) != length(is.buffer) & length(is.buffer) > 1) {
+ # Try to add buffered activities the user didn't specify
+ # (e.g. H2S in PPM buffer if only H2 was requested)
+ for(i in 1:(length(is.buffer) - (length(ibasis)+1))) {
+ newbasis <- NULL
+ # We want to avoid any basis species that might be used as the conservant
+ # look for additional activities to buffer ... do columns in reverse
+ for(j in ncol(bufbasis):1) {
+ if(j %in% ibasis) next
+ if(FALSE %in% (bufbasis[,j] == 0)) {
+ newbasis <- j
+ break
+ }
+ }
+ if(!is.null(newbasis)) {
+ ibasis <- c(ibasis, newbasis)
+ ibasisadded <- c(ibasisadded, newbasis)
+ } else {
+ stop('can not find enough buffered basis species for ', thermo$basis$logact[ibasis[1]], '.', sep = '')
+ }
+ }
+ }
+ # And the leftovers
+ #xx <- as.data.frame(bufbasis[,-ibasis])
+ # The final buffered activity: the would-be conserved component
+ newbasis <- NULL
+ if(length(is.buffer) > 1) {
+ # First try to get one that is present in all species
+ for(i in ncol(bufbasis):1) {
+ if(i %in% ibasis) next
+ if(!TRUE %in% (bufbasis[, i] == 0)) newbasis <- i
+ }
+ # Or look for one that is present at all
+ if(is.null(newbasis)) for(i in ncol(bufbasis):1) {
+ if(i %in% ibasis) next
+ if(FALSE %in% (bufbasis[, i] == 0)) newbasis <- i
+ }
+ if(!is.null(newbasis)) {
+ ibasis <- c(ibasis,newbasis)
+ #message(paste('buffer: the conserved activity is ', basisnames[newbasis], '.', sep = ''))
+ #thermo$basis$logact[newbasis] <<- thermo$basis$logact[ibasis[1]]
+ }
+ else stop('no conserved activity found in your buffer (not enough basis species?)!')
+ }
+ if(is.null(newbasis)) context <- '' else context <- paste(', ', basisnames[newbasis], ' (conserved)', sep = '')
+ reqtext <- paste(c2s(basisnames[ibasisrequested]), ' (active)', sep = '')
+ if(length(ibasisadded) == 0) addtext <- '' else addtext <- paste(', ', c2s(basisnames[ibasisadded]), sep = '')
+ message(paste("buffer: '", bufname, "' for activity of ", reqtext, addtext, context, sep = ""))
+ # There could still be stuff here (over-defined system?)
+ xx <- bufbasis[, -ibasis, drop = FALSE]
+ # For the case when all activities are buffered
+ if(ncol(xx) == 0) xx <- data.frame(xx = 0)
+ # Our stoichiometric matrix - should be square
+ A <- as.data.frame(bufbasis[,ibasis])
+ # Determine conservation coefficients
+ # Values for the known vector
+ B <- list()
+ for(i in 1:length(is.buffer)) {
+ b <- -logK[[is.buffer[i]]] + thermo$species$logact[is.buffer[i]]
+ if(ncol(xx) > 0) {
+ if(is.list(xx)) xxx <- xx[[1]] else xxx <- xx
+ if(ncol(xx) == 1 & identical(as.numeric(xxx), 0)) {
+ # Do nothing
+ } else {
+ for(j in 1:ncol(xx)) {
+ bs <- xx[i, j] * logact.basis[[match(colnames(xx)[j], basisnames)]]
+ if(!is.matrix(bs)) bs <- matrix(bs, byrow = TRUE, nrow = nrow(as.data.frame(logact.basis[[1]])))
+ if(ncol(bs) == 1) b <- matrix(b)
+ b <- b - bs
+ }
+ }
+ }
+ # Force this to be matrix so indexing works at a single point (no variables defined in affinity()) 20201102
+ B[[i]] <- as.matrix(b)
+ }
+ # A place to put the results
+ X <- rep(B[1],length(ibasis))
+ for(i in 1:nrow(B[[1]])) {
+ for(j in 1:ncol(B[[1]])) {
+ b <- numeric()
+ for(k in 1:length(B)) b <- c(b, B[[k]][i, j])
+ AAA <- A
+ # solve for the activities in the buffer
+ t <- solve(AAA, b)
+ for(k in 1:length(ibasis))
+ X[[k]][i, j] <- t[k]
+ }
+ }
+ # Store results
+ for(i in 1:length(ibasis)) {
+ if(ncol(X[[i]]) == 1) X[[i]] <- as.numeric(X[[i]])
+ else if(nrow(X[[i]]) == 1) X[[i]] <- as.matrix(X[[i]], nrow = 1)
+ logact.basis[[ibasis[i]]] <- X[[i]]
+ }
+ names(logact.basis) <- basisnames
+
+ return(list(ibasis = ibasis, logact.basis = logact.basis))
+}
Deleted: pkg/CHNOSZ/man/buffer.Rd
===================================================================
--- pkg/CHNOSZ/man/buffer.Rd 2025-05-05 10:07:10 UTC (rev 889)
+++ pkg/CHNOSZ/man/buffer.Rd 2025-05-08 12:34:30 UTC (rev 890)
@@ -1,136 +0,0 @@
-\encoding{UTF-8}
-\name{buffer}
-\alias{buffer}
-\alias{mod.buffer}
-\title{Calculating buffered chemical activities}
-\description{
-Calculate values of activity or fugacity of basis species buffered by an assemblage of one or more species.
-}
-
-\usage{
- mod.buffer(name, species = NULL, state = "cr", logact = 0)
-}
-
-\arguments{
- \item{name}{character, name of buffer to add to or find in \code{thermo()$buffer}.}
- \item{species}{character, names or formulas of species in a buffer.}
- \item{state}{character, physical states of species in buffer.}
- \item{logact}{numeric, logarithms of activities of species in buffer.}
-}
-
-\details{
-A buffer is treated here as assemblage of one or more species whose presence constrains values of the chemical activity (or fugacity) of one or more basis species.
-To perform calculations for buffers use \code{\link{basis}} to associate the name of the buffer with one or more basis species.
-After this, calls to \code{affinity} will invoke the required calculations.
-The calculated values of the buffered activites can be retrieved by setting \code{return.buffer} to \code{TRUE} (in \code{\link{affinity}}).
-The maximum number of buffered chemical activities possible for any buffer is equal to the number of species in the buffer; however, the user may then elect to work with the values for only one or some of the basis species calculated with the buffer.
-
-The identification of a conserved basis species (or other reaction balancing rule) is required in calculations for buffers of more than one species.
-For example, in the pyrite-pyrrhotite-magnetite buffer (\eqn{\mathrm{FeS_2}}{FeS2}-\eqn{\mathrm{FeS}}{FeS}-\eqn{\mathrm{Fe_3O_4}}{Fe3O4}) a basis species common to each species is one representing \eqn{Fe}{Fe}.
-Therefore, when writing reactions between the species in this buffer \eqn{Fe}{Fe} is conserved while \eqn{\mathrm{H_2S}}{H2S} and \eqn{\mathrm{O2}}{O2} are the variables of interest.
-The calculation for buffers attempts to determine which of the available basis species qualifies as a conserved quantity.
-This can be overriden with \code{balance}.
-The default value of \code{balance} is \samp{PBB}, which instructs the function to use the protein backbone group as the conserved quantity in buffers consisting of proteins, but has no overriding effect on the computations for buffers without proteins.
-
-To view the available buffers, print the \code{\link{thermo}()$buffer} object.
-Buffer definitions can be added to this dataframe with \code{mod.buffer}.
-The defaults for \code{state} and \code{logact} are intended for mineral buffers.
-If \code{name} identifies an already defined buffer, this function modifies the logarithms of activities or states of species in that buffer, optionally restricted to only those species given in \code{species}.
-
-It is possible to assign different buffers to different basis species, in which case the order of their calculation depends on their order in \code{thermo()$buffers}.
-This function is compatible with systems of proteins, but note that for buffers \emph{made} of proteins the buffer calculations presently use whole protein formulas (instead of residue equivalents) and consider nonionized proteins only.
-}
-
-\seealso{
- \code{\link{diagram}} with \code{type} set to the name of a basis species solves for the activity of the basis species.
-}
-
-\examples{
-\dontshow{reset()}
-## List the buffers
-thermo()$buffer
-# Another way to do it, for a specific buffer
-print(mod.buffer("PPM"))
-
-## Buffer made of one species
-# Calculate the activity of CO2 in equilibrium with
-# (a buffer made of) acetic acid at a given activity
-basis("CHNOS")
-basis("CO2", "AC")
-# What activity of acetic acid are we using?
-print(mod.buffer("AC"))
-# Return the activity of CO2
-affinity(return.buffer = TRUE)$CO2 # -7.057521
-# As a function of oxygen fugacity
-affinity(O2 = c(-85, -70, 4), return.buffer = TRUE)
-# As a function of logfO2 and temperature
-affinity(O2 = c(-85, -70, 4), T = c(25, 100, 4), return.buffer = TRUE)
-# Change the activity of species in the buffer
-mod.buffer("AC", logact = -10)
-affinity(O2 = c(-85,-70,4), T = c(25, 100, 4), return.buffer = TRUE)
-
-## Buffer made of three species
-## Pyrite-Pyrrhotite-Magnetite (PPM)
-# Specify basis species and initial activities
-basis(c("FeS2", "H2S", "O2", "H2O"), c(0, -10, -50, 0))
-# Note that the affinity of formation of pyrite,
-# which corresponds to FeS2 in the basis, is zero
-species(c("pyrite", "pyrrhotite", "magnetite"))
-affinity(T = c(200, 400, 11), P = 2000)$values
-# Setup H2S and O2 to be buffered by PPM
-basis(c("H2S", "O2"), c("PPM", "PPM"))
-# Inspect values of H2S activity and O2 fugacity
-affinity(T = c(200, 400, 11), P = 2000, return.buffer = TRUE, exceed.Ttr = TRUE)
-# Calculate affinities of formation reactions of species in the buffer
-a <- affinity(T = c(200, 400, 11), P = 2000, exceed.Ttr = TRUE)$values
-# The affinities for species in the buffer are all equal to zero
-all.equal(as.numeric(a[[1]]), rep(0, 11)) # TRUE
-all.equal(as.numeric(a[[2]]), rep(0, 11)) # TRUE
-all.equal(as.numeric(a[[3]]), rep(0, 11)) # TRUE
-
-## Buffer made of one species: show values of logfO2 on an
-## Eh-pH diagram; after Garrels, 1960, Figure 6
-basis("CHNOSe")
-# Here we will buffer the activity of the electron by O2
-mod.buffer("O2", "O2", "gas", 999)
-basis("e-", "O2")
-# Start our plot, then loop over values of logfO2
-thermo.plot.new(xlim = c(0, 14), ylim = c(-0.8, 1.2),
- xlab = "pH",ylab = axis.label("Eh"))
-# The upper and lower lines correspond to the upper
-# and lower stability limits of water
-logfO2 <- c(0, -20, -40, -60, -83.1)
-for(i in 1:5) {
- # Update the logarithm of fugacity (logact) of O2 in the buffer
- mod.buffer("O2", "O2", "gas", logfO2[i])
- # Get the values of the logarithm of activity of the electron
- a <- affinity(pH = c(0, 14, 15), return.buffer = TRUE)
- # Convert values of pe (-logact of the electron) to Eh
- Eh <- convert(-as.numeric(a$`e-`), "Eh")
- lines(seq(0, 14, length.out = 15), Eh)
- # Add some labels
- text(seq(0, 14, length.out = 15)[i*2+2], Eh[i*2+2],
- paste("logfO2 =", logfO2[i]))
-}
-title(main = paste("Relation between logfO2(g), Eh and pH at\n",
- "25 degC and 1 bar. After Garrels, 1960"))
-
-## Buffer made of two species
-# Conditions for metastable equilibrium among
-# CO2 and acetic acid. note their starting activities:
-print(mod.buffer("CO2-AC"))
-basis("CHNOS")
-basis("O2", "CO2-AC")
-affinity(return.buffer = TRUE) # logfO2 = -75.94248
-basis("CO2", 123) # what the buffer reactions are balanced on
-affinity(return.buffer = TRUE) # unchanged
-# Consider more oxidizing conditions
-mod.buffer("CO2-AC", logact = c(0, -10))
-affinity(return.buffer = TRUE)
-}
-
-\references{
-Garrels, R. M. (1960) \emph{Mineral Equilibria}. Harper & Brothers, New York, 254 p. \url{https://www.worldcat.org/oclc/552690}
-}
-
-\concept{Extended workflow}
Copied: pkg/CHNOSZ/man/mod.buffer.Rd (from rev 889, pkg/CHNOSZ/man/buffer.Rd)
===================================================================
--- pkg/CHNOSZ/man/mod.buffer.Rd (rev 0)
+++ pkg/CHNOSZ/man/mod.buffer.Rd 2025-05-08 12:34:30 UTC (rev 890)
@@ -0,0 +1,136 @@
+\encoding{UTF-8}
+\name{mod.buffer}
+\alias{mod.buffer}
+\alias{buffer}
+\title{Calculating buffered chemical activities}
+\description{
+Calculate values of activity or fugacity of basis species buffered by an assemblage of one or more species.
+}
+
+\usage{
+ mod.buffer(name, species = NULL, state = "cr", logact = 0)
+}
+
+\arguments{
+ \item{name}{character, name of buffer to add to or find in \code{thermo()$buffer}.}
+ \item{species}{character, names or formulas of species in a buffer.}
+ \item{state}{character, physical states of species in buffer.}
+ \item{logact}{numeric, logarithms of activities of species in buffer.}
+}
+
+\details{
+A buffer is treated here as assemblage of one or more species whose presence constrains values of the chemical activity (or fugacity) of one or more basis species.
+To perform calculations for buffers use \code{\link{basis}} to associate the name of the buffer with one or more basis species.
+After this, calls to \code{affinity} will invoke the required calculations.
+The calculated values of the buffered activites can be retrieved by setting \code{return.buffer} to \code{TRUE} (in \code{\link{affinity}}).
+The maximum number of buffered chemical activities possible for any buffer is equal to the number of species in the buffer; however, the user may then elect to work with the values for only one or some of the basis species calculated with the buffer.
+
+The identification of a conserved basis species (or other reaction balancing rule) is required in calculations for buffers of more than one species.
+For example, in the pyrite-pyrrhotite-magnetite buffer (\eqn{\mathrm{FeS_2}}{FeS2}-\eqn{\mathrm{FeS}}{FeS}-\eqn{\mathrm{Fe_3O_4}}{Fe3O4}) a basis species common to each species is one representing \eqn{Fe}{Fe}.
+Therefore, when writing reactions between the species in this buffer \eqn{Fe}{Fe} is conserved while \eqn{\mathrm{H_2S}}{H2S} and \eqn{\mathrm{O2}}{O2} are the variables of interest.
+The calculation for buffers attempts to determine which of the available basis species qualifies as a conserved quantity.
+This can be overriden with \code{balance}.
+The default value of \code{balance} is \samp{PBB}, which instructs the function to use the protein backbone group as the conserved quantity in buffers consisting of proteins, but has no overriding effect on the computations for buffers without proteins.
+
+To view the available buffers, print the \code{\link{thermo}()$buffer} object.
+Buffer definitions can be added to this dataframe with \code{mod.buffer}.
+The defaults for \code{state} and \code{logact} are intended for mineral buffers.
+If \code{name} identifies an already defined buffer, this function modifies the logarithms of activities or states of species in that buffer, optionally restricted to only those species given in \code{species}.
+
+It is possible to assign different buffers to different basis species, in which case the order of their calculation depends on their order in \code{thermo()$buffers}.
+This function is compatible with systems of proteins, but note that for buffers \emph{made} of proteins the buffer calculations presently use whole protein formulas (instead of residue equivalents) and consider nonionized proteins only.
+}
+
+\seealso{
+ \code{\link{diagram}} with \code{type} set to the name of a basis species solves for the activity of the basis species.
+}
+
+\examples{
+\dontshow{reset()}
+## List the buffers
+thermo()$buffer
+# Another way to do it, for a specific buffer
+print(mod.buffer("PPM"))
+
+## Buffer made of one species
+# Calculate the activity of CO2 in equilibrium with
+# (a buffer made of) acetic acid at a given activity
+basis("CHNOS")
+basis("CO2", "AC")
+# What activity of acetic acid are we using?
+print(mod.buffer("AC"))
+# Return the activity of CO2
+affinity(return.buffer = TRUE)$CO2 # -7.057521
+# As a function of oxygen fugacity
+affinity(O2 = c(-85, -70, 4), return.buffer = TRUE)
+# As a function of logfO2 and temperature
+affinity(O2 = c(-85, -70, 4), T = c(25, 100, 4), return.buffer = TRUE)
+# Change the activity of species in the buffer
+mod.buffer("AC", logact = -10)
+affinity(O2 = c(-85,-70,4), T = c(25, 100, 4), return.buffer = TRUE)
+
+## Buffer made of three species
+## Pyrite-Pyrrhotite-Magnetite (PPM)
+# Specify basis species and initial activities
+basis(c("FeS2", "H2S", "O2", "H2O"), c(0, -10, -50, 0))
+# Note that the affinity of formation of pyrite,
+# which corresponds to FeS2 in the basis, is zero
+species(c("pyrite", "pyrrhotite", "magnetite"))
+affinity(T = c(200, 400, 11), P = 2000)$values
+# Setup H2S and O2 to be buffered by PPM
+basis(c("H2S", "O2"), c("PPM", "PPM"))
+# Inspect values of H2S activity and O2 fugacity
+affinity(T = c(200, 400, 11), P = 2000, return.buffer = TRUE, exceed.Ttr = TRUE)
+# Calculate affinities of formation reactions of species in the buffer
+a <- affinity(T = c(200, 400, 11), P = 2000, exceed.Ttr = TRUE)$values
+# The affinities for species in the buffer are all equal to zero
+all.equal(as.numeric(a[[1]]), rep(0, 11)) # TRUE
+all.equal(as.numeric(a[[2]]), rep(0, 11)) # TRUE
+all.equal(as.numeric(a[[3]]), rep(0, 11)) # TRUE
+
+## Buffer made of one species: show values of logfO2 on an
+## Eh-pH diagram; after Garrels, 1960, Figure 6
+basis("CHNOSe")
+# Here we will buffer the activity of the electron by O2
+mod.buffer("O2", "O2", "gas", 999)
+basis("e-", "O2")
+# Start our plot, then loop over values of logfO2
+thermo.plot.new(xlim = c(0, 14), ylim = c(-0.8, 1.2),
+ xlab = "pH",ylab = axis.label("Eh"))
+# The upper and lower lines correspond to the upper
+# and lower stability limits of water
+logfO2 <- c(0, -20, -40, -60, -83.1)
+for(i in 1:5) {
+ # Update the logarithm of fugacity (logact) of O2 in the buffer
+ mod.buffer("O2", "O2", "gas", logfO2[i])
+ # Get the values of the logarithm of activity of the electron
+ a <- affinity(pH = c(0, 14, 15), return.buffer = TRUE)
+ # Convert values of pe (-logact of the electron) to Eh
+ Eh <- convert(-as.numeric(a$`e-`), "Eh")
+ lines(seq(0, 14, length.out = 15), Eh)
+ # Add some labels
+ text(seq(0, 14, length.out = 15)[i*2+2], Eh[i*2+2],
+ paste("logfO2 =", logfO2[i]))
+}
+title(main = paste("Relation between logfO2(g), Eh and pH at\n",
+ "25 degC and 1 bar. After Garrels, 1960"))
+
+## Buffer made of two species
+# Conditions for metastable equilibrium among
+# CO2 and acetic acid. note their starting activities:
+print(mod.buffer("CO2-AC"))
+basis("CHNOS")
+basis("O2", "CO2-AC")
+affinity(return.buffer = TRUE) # logfO2 = -75.94248
+basis("CO2", 123) # what the buffer reactions are balanced on
+affinity(return.buffer = TRUE) # unchanged
+# Consider more oxidizing conditions
+mod.buffer("CO2-AC", logact = c(0, -10))
+affinity(return.buffer = TRUE)
+}
+
+\references{
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/chnosz -r 890
More information about the CHNOSZ-commits
mailing list