Skip to content

Commit

Permalink
Use do.call() with argument list to call affinity() in mosaic()
Browse files Browse the repository at this point in the history
git-svn-id: svn://scm.r-forge.r-project.org/svnroot/chnosz/pkg/CHNOSZ@798 edb9625f-4e0d-4859-8d74-9fd3b1da38cb
  • Loading branch information
jedick committed Aug 9, 2023
1 parent 7b76817 commit 0de267e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 30 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Date: 2023-07-05
Date: 2023-08-09
Package: CHNOSZ
Version: 2.0.0-17
Version: 2.0.0-18
Title: Thermodynamic Calculations and Diagrams for Geochemistry
Authors@R: c(
person("Jeffrey", "Dick", , "[email protected]", role = c("aut", "cre"),
Expand Down
55 changes: 28 additions & 27 deletions R/mosaic.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,31 @@
# Function to calculate affinities with mosaic of basis species
mosaic <- function(bases, blend = TRUE, stable = list(), loga_aq = NULL, ...) {

# Get the arguments for affinity() before doing anything else 20230809
affinityargs <- list(...)

# Argument recall 20190120
# If the first argument is the result from a previous mosaic() calculation,
# just update the remaining arguments
if(is.list(bases)) {
if(identical(bases[1], list(fun = "mosaic"))) {
aargs <- bases$args
# We can only update arguments given in ...
ddd <- list(...)
if(length(ddd) > 0) {
for(i in 1:length(ddd)) {
if(names(ddd)[i] %in% names(aargs)) aargs[[names(ddd)[i]]] <- ddd[[i]]
else aargs <- c(aargs, ddd[i])
bargs <- bases$args
# We can only update arguments for affinity()
if(length(affinityargs) > 0) {
for(i in 1:length(affinityargs)) {
if(names(affinityargs)[i] %in% names(bargs)) bargs[[names(affinityargs)[i]]] <- affinityargs[[i]]
else bargs <- c(bargs, affinityargs[i])
}
}
return(do.call(mosaic, aargs))
return(do.call(mosaic, bargs))
}
}

# Backward compatibility 20190131:
# bases can be a vector instead of a list
if(!is.list(bases)) {
bases <- list(bases)
otherargs <- list(...)
allargs <- c(list(bases = bases, blend = blend, stable = stable), otherargs)
allargs <- c(list(bases = bases, blend = blend, stable = stable), affinityargs)
out <- do.call(mosaic, allargs)
# Replace A.bases (affinity calculations for all groups of basis species) with backwards-compatible A.bases
out$A.bases <- out$A.bases[[1]]
Expand Down Expand Up @@ -71,31 +72,31 @@ mosaic <- function(bases, blend = TRUE, stable = list(), loga_aq = NULL, ...) {
stop("the starting basis does not have ", paste(names0[ina], collapse = " and "))
}

ddd <- list(...)
if("sout" %in% names(ddd)) {
ddd_has_sout <- TRUE
# Get sout from ... (from solubility()) 20210322
sout <- ddd$sout
if("sout" %in% names(affinityargs)) {
affinityargs_has_sout <- TRUE
# Get sout from affinityargs (from solubility()) 20210322
sout <- affinityargs$sout
} else {
ddd_has_sout <- FALSE
affinityargs_has_sout <- FALSE
# Run subcrt() calculations for all basis species and formed species 20190131
# this avoids repeating the calculations in different calls to affinity()
# add all the basis species here - the formed species are already present
# - This avoids repeating the calculations in different calls to affinity()
# Add all the basis species here - the formed species are already present
lapply(bases, species, add = TRUE)
sout <- affinity(..., return.sout = TRUE)
sout <- do.call(affinity, c(affinityargs, list(return.sout = TRUE)))
}


# Calculate affinities of the basis species themselves
A.bases <- list()
for(i in 1:length(bases)) {
message("mosaic: calculating affinities of basis species group ", i, ": ", paste(bases[[i]], collapse = " "))
mysp <- species(bases[[i]])
# 20191111 include only aq species in total activity
# Include only aq species in total activity 20191111
iaq <- mysp$state == "aq"
# Use as.numeric in case a buffer is active 20201014
if(any(iaq)) species(which(iaq), as.numeric(basis0$logact[ibasis0[i]]))
if(ddd_has_sout) A.bases[[i]] <- suppressMessages(affinity(...))
else A.bases[[i]] <- suppressMessages(affinity(..., sout = sout))
if(affinityargs_has_sout) A.bases[[i]] <- suppressMessages(do.call(affinity, affinityargs))
else A.bases[[i]] <- suppressMessages(do.call(affinity, c(affinityargs, list(sout = sout))))
}

# Get all combinations of basis species
Expand Down Expand Up @@ -128,8 +129,8 @@ mosaic <- function(bases, blend = TRUE, stable = list(), loga_aq = NULL, ...) {
put.basis(allbases[i, ], thislogact)
# We have to define the species using the current basis
species(species0$ispecies, species0$logact)
if(ddd_has_sout) aff.species[[i]] <- suppressMessages(affinity(...))
else aff.species[[i]] <- suppressMessages(affinity(..., sout = sout))
if(affinityargs_has_sout) aff.species[[i]] <- suppressMessages(do.call(affinity, affinityargs))
else aff.species[[i]] <- suppressMessages(do.call(affinity, c(affinityargs, list(sout = sout))))
}

# Calculate equilibrium mole fractions for each group of basis species
Expand All @@ -153,8 +154,7 @@ mosaic <- function(bases, blend = TRUE, stable = list(), loga_aq = NULL, ...) {
group.fraction[[i]] <- A.bases[[i]]$values
}
} else {
# For blend = FALSE, we just look at whether
# a basis species predominates within its group
# For blend = FALSE, we just look at whether a basis species predominates within its group
if(is.null(stable[i][[1]])) {
d <- diagram(A.bases[[i]], plot.it = FALSE, limit.water = FALSE)
predom <- d$predominant
Expand Down Expand Up @@ -212,7 +212,8 @@ mosaic <- function(bases, blend = TRUE, stable = list(), loga_aq = NULL, ...) {
}

# For argument recall, include all arguments in output 20190120
allargs <- c(list(bases = bases, blend = blend), list(...))
allargs <- c(list(bases = bases, blend = blend), affinityargs)
# Return the affinities for the species and basis species
return(list(fun = "mosaic", args = allargs, A.species = A.species, A.bases = A.bases, E.bases = E.bases))

}
2 changes: 1 addition & 1 deletion man/mosaic.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ To calculate mineral solubilities with mosaic calculations that account for liga

\examples{
\dontshow{reset()}# Fe-minerals and aqueous species in Fe-S-O-H system
# Speciate SO4-2, HSO4-, HS-, H2S as a function of Eh and pH
# Speciate SO4-2, HSO4-, HS-, and H2S as a function of Eh and pH
# After Garrels and Christ, 1965 Figure 7.20
pH <- c(0, 14)
Eh <- c(-1, 1)
Expand Down

0 comments on commit 0de267e

Please sign in to comment.