about the implementation of a speciation code

about the implementation of a speciation code
(work in progress ..)
introduction
The question of speciation is central in aqueous chemistry. The development of a robust
speciation solver is thus prerequisite to that of code addressing fluid-rock interaction issues.
Numerous programs have been developed in the last forty years for speciation calculations.
Many of them are freely available, sometimes with sources (e.g. Phreeqe, from USGS;
EQBRM, from Anderson & Crerar; ...), and the question may arise of the interest of adding
still another program to the list ...
But our objective is different from such developments: rather than adding another program to
the list, our aim is to propose a "library" of inter-dependent modules that will implement the
main procedures necessary for calculations of reactions between fluids and minerals.
Special attention has been given for enhancing the "readability" and "re-usability" of the code.
These modules are implemented, in order to check their validity, in programs that solve some
specific speciation and kinetic problems, but they are designed, hopefully, in such a way that:
1/ a user can incorporate them in her/his own specific applications,
2/ a user can also participate in the development, by proposing new tools or giving feed back
for improvements of the modules.
note on the database issues
Most speciation codes currently available are designed for solving a specific range of
problems. For example, whereas many programs are available for "subsurface" problems, few
can be used to address hydrothermal conditions. The main reason for the limited application
range of a given program lies in the restriction of the embedded database to a given (P,T)
range.
In order that our speciation modules find applications in the largest range of fluid-rock
interaction "issues", tools have been developed for the calculation of thermodynamic
properties of aqueous species in a large (P,T) range, from subsurface to mid-crustal
conditions. The development of these database tools is the aim of the project database. The
main practical problem for this development has been to "make a bridge" between the HKF
system, which is at the base of most database used in "subsurface" aqueous geochemistry, and
the thermodynamic bases commonly used in metamorphic petrology.
the system
What we refer here as "the system", is a given amount of fluid in a given environment.
We will examine first "closed systems", which have a defined composition, and where the
environment only imposes physical constraints such as pressure and temperature.
Then, we will extend the discussion to "open systems", which may exchange matter with the
environment.
basics of the speciation problem
Basically, to solve a speciation problem for a given multicomponent system of known chemical
composition, is to compute the equilibrium distribution of nCp components among nSp
species.
A vast amount of literature is available on this issue and is not reviewed in detail. General
discussions of the problem can be found for example in Smith & Missen (1982) or Lichtner
(1985).
Two main types of approaches are classically considered (Smith & Missen, 1982):
● In a "non-stoichiometric" approach, generally a Free Energy Minimisation
(GEM, when the relevant potential function is the Gibbs free energy), the equilibrium
is solved globally, by minimizing the free energy of the system, under the mass
kinxim_speciation - 1
conservation constraints. GEM methods are of common use for systems involving
several phases of variable composition (e.g. in metamorphic or igneous petrology), but
they are less commonly implemented for speciation of an aqueous solution, except for
highly concentrated brines (e.g. Harvie, __).
● In the "stoichiometric" approach (or LMA, for Law of Mass Action), which is
dominant among programs for homogeneous equilibrium, e.g. aqueous geochemistry
(EQ3, Phreeq, Chess, ...), the equilibrium constraints are implemented as a series of
chemical equilibria among the species.
The modules under development here implements a LMA approach, but part of them should
also be useful for implementation of GEM methods.
In the LMA approach, for a closed system {nCp components, nSp species}, where the data are
the abundances of nCp "independent components", and the unknowns are the abundances of
the nSp species, a speciation problem is written as a system of nSp equations that comprise:
● = nCp equations describing the mole conservation of the nCp components,
● = nSp-nCp equations describing the mutual equilibrium between the nSp species.
Thus the solution of a speciation problem involves the implementation of two types of
constraints, respectively on chemical compositions ("mass conservation" constraints) and on
chemical potentials ("mass action" constraints).
composition constraints: description of the system stoichiometry, choice of components
Various approaches are possible for describing the stoichiometric dependencies between the
chemical species considered.
One approach (the "basis species approach"), always possible for an homogeneous closed
system, is to use the chemical species themselves, and to describe their stoichiometric
relations by choosing among them a set of linearly independent species, which will be the
"basis" against which the stoichiometry of the other species is described.
One advantage of this approach is to use a minimum number of variables to describe both the
stoichiometry and the chemical equilibrium of the system.
This approach is well suited for equilibrium calculations of an homogeneous system, e.g.
purely aqueous, but it makes more complex the solution of "open system speciation".
In this "basis species approach", the role of the basis species (or "primary species") is twofold:
they are both components involved in the stoichiometric description of the mass balance and
chemical species involved in mass action relations. The denomination of "component species"
would better emphasize this duality.
Consequently, they are assigned two types of abundances (i.e. concentration, mole number,
...): a "chemical" abundance relevant to the chemical species itself, and a "total" or
"generalized" abundance for the corresponding component species.
For example, the mass balance relation for "total carbonate" for the example below, will be, in
mole numbers:
(CO2)_total = (CO2) + (HCO3-) + (CO3-2)
For example, considering a carbonate-bearing aqueous solution with six chemical species
(H2O, H+, HO-, CO2, HCO3-, CO3-2) considered potentially present, we can select
{H2O,H+,CO2} as basis and describe HO- as (1,-1,0), HCO3- as (1,-1,1), CO3-2 as (1,-2,1).
Instead of using "basis species", which is common practice in aqueous chemistry, we will use a
more general approach, using the general concept of "independent components" of
thermodynamics.
The system stoichiometry is defined with a set of arbitrary components that do not necessarily
correspond to any species' stoichiometry: the components only have to form a set of linearly
independent entities that can collectively span the whole "chemical space" defined by the
species under consideration.
The possibility to chose arbitrary components, not restricted to the aqueous species set, will
kinxim_speciation - 2
be useful for solving open system speciation problems involving non-aqueous species.
The apparently most "basic" option is that the set comprises all the chemical elements present
in the system.
That choice is made in the present implementation, where, for a closed system, the chemical
elements are chosen as the components.
In the case of an aqueous system, when the set should be able to describe ionic species, the
electron, or the electronic charge, is added as a component. A peculiarity of this "charge
component" is that, in order to statisfy the electroneutrality of electrolytes, it is systematically
imposed a null total balance.
For example, considering a carbonate-bearing aqueous solution with six chemical species
(H2O, H+, HO-, CO2, HCO3-, CO3-2), a "basis" composed of the four components
(O,H,C,Chg) describe the species compositions using the following stoichiometric table
H2O
H+
CO2
HOHCO3CO3-2
O
1
0
2
1
3
3
H
2
1
0
1
1
0
C
0
0
1
0
1
1
Chg
0
+1
0
-1
-1
-2
(in the "basis species approach", the apparent dimension of the system decreases from 4 to 3,
because the electoneutrality condition is not expressed).
Each species is characterized by its "formula vector"., e.g. the line vector (1,2,0,0) for H2O.
The table is the "formula table" of the system (in our modules, we actually use the transposed
form of this table as formula matrix, tFormul(1:nCpn,1:nSp)).
Note: In the present modules, in contrast with the stoichiometry tables or implicit reactions
used by most programs for the stoichiometric description of the system, the stoichiometry of
each species will be retrieved from its formula, written in a specific form (e.g. Si(1)O(2)).
accounting for redox state
From the stoichiometry of the species listed in the former example, it is implicit that only one
oxidation state has been considered for each element. Actually, a more explicit element list,
such as {O(-2), H(+), C(+4)}, would state more clearly the oxidation state considered for each
element in this example.
If we consider an aqueous system where reduced and oxidized species (e.g. CH4, H2, O2) are
potentially present, then we have to introduce as additional component a redox parameter
(that we call Ox) which describes the oxidation state of the different species in respect to the
"default oxidation state" of the elements.
The following table is obtained, where the vector line vVal (which is not considered part of the
formula table) describes the default oxidation state:
vVal
H2O
H+
CO2
HOHCO3CO3-2
O2
H2
CH4
O
-2
1
0
2
1
3
3
2
0
0
H
1
2
1
0
1
1
0
0
2
4
C
4
0
0
1
0
1
1
0
0
1
Ox
1
0
0
0
0
0
0
4
-2
-8
(Chg)
-1
0
1
0
-1
-1
-2
0
0
0
For a species with the formula vector vFormul(1:nCp), the value of Ox is calculated from the
relation
DotProduct( vFormul(O:Ox), vVal(O:Ox) ) = Chg
or, with vVal(Chg)=-1, extending the cross product over all elements including charge,
kinxim_speciation - 3
DotProduct( vFormul(O:Chg), vVal(O:Chg) ) = 0
The value of the redox parameter, Ox, of a species is also read from the species formula; it will
depend on the choice of the default values of the oxidation states of elements.
In kinxim modules, O, H, and Ox have been assigned specific oxidation states (-2, +1, +1), but
the "default oxidation state" of other elements (S, C, Fe, ...) is selected by the user, at each
run, when selecting which default species is associated with each element.
For example, chosing CO2(aq) for C will fix vVal(C) at 4, which satisfies the relation vVal(C) +
2 . vVal(O) = 0. In that case, the species CO3-2 will have Ox=0, because it contains C in the
default oxydation state, but the species CH4 will have Ox=-8, because vVal("C")=+4 and
vVal("H")=+1.
open systems, "inert" versus "mobile" components
As already stated, to constrain a system, we need as many independent constraints as we have
independent components.
In a closed system, all these constraints are compositional constraints (e.g. mole numbers,
mole fractions, ...).
In an open system, part or all of the constraints are potential constraints. (e.g. partial
pressure, species activity, ...).
In a closed system, all components are "inert", which means that their amounts are known,
and the unknown are the activities of all species.
In an open system, a number of components are "mobile", which means that their activities
are imposed (for example, the system is at equilibrium with an atmosphere of fixed CO2
partial pressure), and an equivalent number of element abundances will be deduced from the
speciation calculation. In open systems, mass conservation constraints are imposed on the
inert components only.
Mobile components can be aqueous species (e.g. H+, in case of imposed pH), they can be also,
in case of heterogeneous equilibria, components of other phases (minerals, gases). For
example, the equilibrium of an aqueous solution with a plagioclase of given composition and
equation of state will impose the activities of the plagioclase components (e.g. KAlSi3O8,
NaAlSi3O8 and CaAl2Si2O8). If these components are not found as aqueous species, the
application of a "primary basis species" approach becomes impossible. On the contrary,
chosing KAlSi3O8, NaAlSi3O8 and CaAl2Si2O8 as components, while making the
stoichiometry matrix more complex, will simplify the implementation of the equilibrium
conditions.
To summarize, for a system of nCp components, of which nPi are inert, nPx mobile (hence,
nCp=nPi+nPx), the set of independent components used to describe the system will consist of:
= nPi elements, for inert components,
= nPx species, for mobile components.
These nPx mobile species may comprise both aqueous and non-aqueous (mineral or gas)
species. As we consider here essentially true equilibrium conditions (or, in dynamic systems,
the "distance" to a true equilibrium), these species are necessarily linearly independent from
each other: if two species were dependent on each other, then the corresponding activities
would either be redundant on each other, or would be mutually inconsistent.
On the other hand, to each inert component, a species can be associated in such a way that all
species, including inert and mobile species, form a set of independent species.
classification of species
The species involved in the system can be classified as follows:
● nCi inert components and corresponding "primary species" chosen among
aqueous species,
● nAs secondary aqueous species,
● nCx mobile components, comprising nAx primary aqueous species (e.g. H+ for
kinxim_speciation - 4
●
fixed pH problems, O2(aq) for fixed redox potential, ...), and nMx non-aqueous
species (mineral or gas, e.g. partial pressure of CO2),
nMs non-aqueous and non-mobile species (minerals and gases).
the stoichiometry matrix ( tAlfa )
The matrix tAlfa describes the stoichiometries of all species in terms of the components.
For a closed system, tAlfa equals the formula matrix tFormul.
For example, the total amount vTot(i) of the element i in the system (i.e. in the fluid) is given
by
vTot(i) = DotProduct( tFormul(i,1:nAq), vMol(1:nAq) )
where vMol(1:nAq) is the vector of the mole numbers of all aqueous species.
For an open system, the stoichiometry matrix tAlfa is calculated from the formula matrix
tFormul as follows:
The formula matrix tFormul(1:nPr,1:nSp) is subdivided into blocks corresponding to the
different types of species, respectively Primary Inert species (nPr), Aqueous Secondary species
(nAs), Aqueous mobile species (nAx), Mineral mobile species (nMx), and Mineral "secondary"
species (nMs).
If the species selected as basis have been appropriately selected (i.e. if they are linearly
independent from each other), then the matrix obtained by concatenation of the primary
species blocks is invertible.
Its inverse, which expresses the elements (1:nCp) in terms of the components (1:nCp), is used
to compute the matrix tAlfa(1:nSp,1:nCp) giving the stoichiometry of all species, aqueous and
non-aqueous, in terms of components.
The example below shows tAlfa for a system of 8 elements (O, H,Cl, Si,Al,Ca,Na,K) with
= 4 inert components: O, Cl, K, H,
= 4 mobile components: Albite, Anorthite, Quartz, Andalusite.
In this table, the matrix tAlfa is divided into sub-matrices tAlfa(1:nPr,1:nCp),
tAlfaAs(1:nAs,1:nCp), tAlfaMs(1:nMs,1:nCp), respectively for primary species, secondary
aqueous species, secondary mineral species.
tAlfPr, Prim'Species
O
CL
K
H
ALBI ANOR QUART ANDAL
1
2
1
1
1
1
1
1
1
tAlfAs, Aqu'Sec'Species !(extract)
-1.5 -0.5
0.5
-1
1
-1
-1
-0.5 -0.5
0.5
-0.5 1
-0.5
0.5
0.5 1
-0.5
0.5
0.5 -0.5
0.5
1
1
-1
-1
-1
1
1
-1
-1
-1
2
1
-1
-1
1
1
1
1
1
../..
0
-1
1
1
0
0
0
0
H2O
CLK+
H+
ALBITE
ANORTHITE
QUARTZ
ANDALUSITE
3
2
1
2
0
-1
1
1
0
-1
0
AL+3
CA+2
ALO+
ALOH+2
HALO2(AQ)
ALO2CAOH+
CACL+
CACL2(AQ)
HSIO3KCL(AQ)
implementation of mass balance constraints
For closed systems, there are as many mass balance constraints as components.
kinxim_speciation - 5
Thus, for each iPr from 1 to nCp, we sum the contributions from all aqueous species, 1:nAq,
using the stoichiometric formula matrix tFormul:
Psi(iPr)=DotProduct(tFormul(iPr,1:nAq), vMol(1:nAq)) - vTot(iPr) = 0 !for
iPr=1,nPr
On open systems, mass balance constraints are imposed on inert components only.
The mass balance comprise two terms, one for non-mobile aqueous species, the other for
mobile aqueous species. Instead of using directly tFormul for stochiometric claculations, we
use the stoichiometric tables tAlfXx, as calculated above, which describe the different types of
species in terms of components that are partly elements (for inert components), partly species
().
!inert species
Psi(iPi)= & !mole conservation constraint on inert component iPi
& DotProduct(tAlfPr(iPi,1:nPi),vMol(1:nPi)
) &
+ DotProduct(tAlfAs(iPi,1:nAs),vMol(nPi+1:nPi+nAs)) &
- vTotF(iPi)
The second term groups all the contribution from the mobile aqueous species to the mole
balance of element iPi:
!mobile species
IF(nAx>0) & !add contrib. from "mobile" species, only the
aqu'prim'species
& FuncPsi(iPi)= FuncPsi(iPi) &
+ MATMUL(tAlfPr(iPi,nPi+1:nPi+nAx),&
& vAct(nAi+1:nAi+nAx) / vGam(nAi+1:nAi+nAx) * MWSv*vMol(H2O)
Mobile species having fixed activities (vAct) imposed on the system, their abundances can be
calculated if their activity coefficients (vGam) and the solvent abundance
(MWSv*vMol(H2O)) are known. These parameters, which depend on the solution
composition, are approached by successive iterations (in this term, only the solvent mole
number, vMol(H2O), changes inside the Newton-Raphson loops, the other factors, which
include activity coefficients, are held constant, their calculation is done in an external loop).
equilibrium conditions: primary and secondary species
In the "LMA approach", the equilibrium conditions are implemented as a set of reactions
among species.
If the number of species equals the number of components, the species abundances are
completely determined by their stoichiometries. Each time an additional species is
considered, an additional equation is provided by a chemical equilibrium condition, i.e. a
constraint on the species' chemical potentials.
For a system of {nCp components, nSp species}, the number of such independent reactions is
nSp - nCp. To write these reactions, it is necessary to split the species set into, on one hand,
nCp linearly independent "primary species", and, on the other hand, nSp-nCp "secondary
species" whose formation (or dissociation) reactions are expressed in terms of the "primary
species".
There are as many "basis species" as components, 3 in the example system {(H,O,C), (H+,
H2O, CO2, HO-, HCO3-, CO3-2)}.
The selection of the "primary species", as long they form a basis for the system, is rather
arbitrary. Practically, in aqueous systems, H2O is always chosen as primary species, for its
role as solvent. It is also practical to have H+ (or OH- in basic conditions) as component,
because of their central role in acid-base reactions. For other elements, the species with the
highest dissociation degree (e.g. Na+ for Na, Ca+2 for Ca, PO4-3 for P) can be selected as the
default primary species, but the primary species set can be modified, during speciation
calculation, in order to have the most dominant species as primary species, which secure the
numerical resolution of the problem.
In the case of open system, chosing the mobile species as primary species simplifies the
expression of the equilibrium conditions: if a mobile species is not aqueous, its selection as
primary species allows the implementation of equilibrium conditions with the same type of
kinxim_speciation - 6
equations as those used for homogeneous equilibrium . The remaining inert "primary species"
are selected among the remaining aqueous species, providing that they are independent from
each other and from the mobile species.
Example
For the system {(H,O,C), (H+, H2O, CO2, HO-, HCO3-, CO3-2)}, if (H2O, H+, CO3-2) is
selected as "basis", the other nAs species ("secondary species") are defined in relation with
this basis by the following stoichiometry matrix tNu(1:nAs, 1:nPr), the same as that used for
stoichiometry description in the pure "basis species approach":
HOHCO3CO3-2
H2O
1
1
1
H+
-1
-1
-2
CO2
0
1
1
stoichiometry of the secondary species (matrix tNu)
The matrix tNuAs describes the aqueous secondary species in terms of the primary ones.
Its calculation is similar to that described for tAlfa:
If the basis species have been appropriately selected, then their stoichiometries are linearly
independent from each other; hence, the matrix obtained by concatenation of the primary
species columns of the formula matrix, tFormul(1:nPr,iPi), is invertible.
Its inverse, which expresses the elements (1:nPr) in terms of the basis species (1:nPr), will
constitute the "transformation matrix" A, that is used to compute the matrix
tNuAs(1:nAs,1:nPr) that gives the stoichiometry of the aqueous secondary species in terms of
primary species. The same transformation matrix is used to compute the matrix
tNuMs(1:nMs,1:nPr), which gives the stoichiometry of the non-aqueous species.
A=Inverse(tFormul(1:nPr,1:nPr)
tNuAs(1:nAs,1:nPr)= & !in tNu, species are organized as lines
TRANSPOSE(MATMUL(A(1:nPr,1:nPr),tFormul(1:nPr,nPr+1:nPr+nAs)))
tNuMs(1:nMs,1:nPr)= &
TRANSPOSE(MATMUL(A(1:nPr,1:nPr),tFormul(1:nPr,nAq+1:nAq+nMs)))
The matrices tNuAs and tNuMs are used also for computing vDG°As(1:nAs) and
vDG°Ms(1:nMs), the DeltaG°'s of the dissociation reactions of all secondary species,
respectively aqueous and non-aqueous (minerals and gases).
equilibrium conditions: chemical potential constraints
If the system is at equilibrium, then nAs=nAq-nPr linearly independent chemical reactions
between the primary and secondary species are at equilibrium. It is common, in aqueous
geochemistry, to present the corresponding conditions under the classical "mass action" form,
using "ion activity products" and "equilibrium constants".
An equivalent formulation, using chemical potentials and affinities, is preferred here, because
it gives directly linear relations easily implemented, and because it will make more clear the
generalization to "open system".
example = the system {(H,O,C), (H+, H2O, CO2, HO-, HCO3-, CO3-2)}
Having selected (H2O,H+,CO2) as basis, the equilibrium conditions, deltaG=0, for the
formation of the three secondary species give the following relations:
Mu(HO-) = Mu(H+) + Mu(H2O)
Mu(HCO3-)= - Mu(H+) + Mu(H2O) + Mu(CO2)
Mu(CO3-2)= - Mu(H+) + Mu(H2O) + Mu(CO2)
where Mu(X) is the chemical potential of species X.
The equilibrium conditions are thus implemented as (1:nAs) chemical potential constraints,
one for each secondary species:
Psi(nPr+iAs) = 0 = DotProduct( tNu(iAs,1:nPr) , vMu(1:nPr) ) - vMu(iAs)
kinxim_speciation - 7
were the matrix tNu(1:nAs,1:nPr) describes the stoichiometries of the formation (or
dissociation) of secondary aqueous species from primary species, and vMu(1:nAq) is the array
of the chemical potentials of all species of the system.
µ(iAq), "in reduced form" (i.e. divided by RT), is related with the activity of species iAq,
vAct(iAq), by the relation
µ(iAq) = µ°(iAq) + ln(vAct(iAq)),
where µ°(iAq) (in the program, vG°) is the "reduced" molar Gibbs enthalpy of species iAq in
the reference state, retrieved from the database.
The equilibrium conditions can also be written in a form closer to the classical "law of mass
action" form:
for iAs=1..nAs,
SUM[ tNuAs(iAs,1:nPr). ln(vAct(1:nPr)) ]
- ln(vAct(nPr+iAs)) + vDeltaG°(iAs)
= 0
where vDeltaG°(iAs) is the "delta G" (i.e. - LogK . ln10) of the speciation reaction of secondary
species iAs,
vDeltaG°(iAs)=SUM[ tNu(iAs,1:nPr) . vG°(1:nPr) ] - vG°(nPr+iAs)
and
vAct(1:nAq) are the activities of all species.
relation between activity and mole numbers
If the solution is aqueous, with activities of solutes following a molality scale, and dilute,
where a Debye-Hueckel or similar model is applied, then the solute activities vAct(2:nAq) are
related with the mole numbers vX(1:nAq) by relations of the following form:
vAct(i) = vGam(i) . vMolal(i) = vGam(i) . vX(i) / (Mass Solvent)
or
vAct(i) = vGam(i).vX(i) / vX(H2O) / MolWeit(H2O)
with MolWeit(H2O)=0.018 kg/mole
The equilibrium condition between a secondary species iAs and the primary species (1:nPr)
comprises two terms, respectively for the solvent species (iPr=1) and for the solute basis
species (iPr=2:nPr),
Psi(nPr+iAs)= &
tNuAs(iAs,iSv) . vLnAct(iSv) & !solvent activity
+ DotProduct(tNuAs(iAs,2:nPr),vLnAct(2:nPr)) - vLnAct(nPr+iAs) & !
solute activities
+ DotProduct(tNuAs(iAs,1:nPr),vG0Pr(1:nPr) ) - vG0As(iAs) !deltaG0 of
reaction
or, in terms of mole numbers vX(1:nPr) and vX(nPr+iAs):
Psi(nPr+iAs)= &
tNuAs(iAs,iSv) . vLnAct(iSv) & !solvent activity
+ DotProduct(tNuAs(iAs,2:nPr),vX(2:nPr))
- vX(nPr+iAs) &
+ DotProduct(tNuAs(iAs,2:nPr),vLnGam(2:nPr)) - vLnGam(nPr+iAs) &
- (SUM(tNuAs(iAs,2:nPr)) -1.0).(vX(iSv) +LnMWSv) & !mole.nr to molality
conversion
+ DotProduct(tNuAs(iAs,1:nPr),vG0Pr(1:nPr)) - vG0As(iAs) !deltaG0 of
reaction
kinxim_speciation - 8