Activity models
Before this page
Thermochemistry and Standard states, which define the activity this page models.
Every equilibrium this package computes rests on
and on nothing else about the solution. The standard potential
A model has to answer two questions, not one:
the solute activity
, which sets every solubility and every saturation index;the solvent activity
, which is what a hydrate reaction consumes, and which in a cement paste short of mixing water is the quantity that decides how far the reaction can go.
The five built-in models — DiluteSolutionModel, DaviesActivityModel, HKFActivityModel, SITActivityModel and PitzerActivityModel — differ in both; §5 measures by how much for the first three, and §6a and §6 treat the other two.
1. Where the comes from
An ion in a solution of ions is not in the same state as one alone at the same molality, and the reason is electrostatic. Around a cation, anions are slightly more likely to be found than cations — not because of any structure, only because their energy there is lower — so the ion sits at the center of a diffuse ionic cloud of opposite net charge. That cloud screens the ion's own field and lowers its energy, which is why activity coefficients of ions are below 1.
The classical treatment takes three steps, and the assumptions it makes on the way are exactly the assumptions that later fail:
Poisson's equation relates the mean potential to the mean charge density,
, with the solvent entering only as a continuum of bulk permittivity. Boltzmann statistics give the local ion densities,
, treating the ions as independent in the mean field of all the others.Linearization,
, turns the pair into , whose solution is a screened Coulomb potential with a single length scale
the Debye length. Charging the central ion reversibly inside its own cloud gives the excess chemical potential, and hence
exact as
Two ions cannot approach closer than the sum of their radii, so the cloud is excluded from a shell of radius HKFActivityModel implements:
and are properties of water, not fitting constants
Collecting the constants of step 3 gives, with
which is what hkf_debye_huckel_params evaluates from this package's own equation of state for water. So the
Both rise with temperature, because water's dielectric constant falls faster than
The screening length is the size of a gel pore
The Debye length is
A cement pore solution sits around
2. The term is a deviation function, not a physical term
Measured activity coefficients turn back upwards at high ionic strength, which no screening argument produces. The B-dot model adds a linear term for it,
Its status is that of an empirical correlation. Anderson and Crerar (1993) (§17.7.1, pp. 445–446) record that Helgeson (1969) defined
That is why this model has a ceiling rather than an asymptote, and why the ceiling is quoted vaguely as "about a molal": the term is not wrong so much as it is standing in for physics it does not contain.
Away from 25 °C the model keeps temperature_dependent = true,
The Davies equation (Davies, 1962) makes the same move with one more simplification. It drops the ion size, replacing
No per-species datum is needed, and every ion of a given charge has the same activity coefficient. The
Neutral species get the Setschenow form, CO₂(aq) is the case that matters for carbonation.
3. The water activity, and why it cannot be assumed separately
The solvent is not a solute and its activity is not obtained by the same formula. At constant
which is not an optional refinement: it is the statement that the solvent and the solutes are parts of one thermodynamic system. Once the activities of the solutes are chosen, it leaves the solvent none to choose. Integrating it over the solutes' terms gives the osmotic coefficient
and that is how the solvent row of the ideal model and of the two extended Debye-Hückel models is built. The ideal model has DaviesActivityModel). HKFActivityModel integrates its TruesdellJonesActivityModel and SITActivityModel (§6a) keep it.
The one approximation in the B-dot route is that
4. Inputs and outputs, model by model
What each model needs and what it returns — the full parameter tables, with the provenance of every default, are in the docstrings (HKFActivityModel, DaviesActivityModel); this is the summary that lets you choose.
DiluteSolutionModel | DaviesActivityModel | HKFActivityModel | SITActivityModel | PitzerActivityModel | |
|---|---|---|---|---|---|
| solute scale | molarity | molality | molality | molality | molality |
| Davies | extended D-H + | D-H + | virial expansion | ||
| osmotic coefficient, closed form | osmotic coefficient | Raoult (§6a) | osmotic coefficient | ||
| per-species data | none | none | ion radii | one parameter per ion pair — caller input | a parameter per ion pair and per triplet — caller input |
| scalar inputs | none | the shape constants | |||
| none | |||||
| returns | same | same | same | same | |
| the range its set was fitted over, a few mol/kg | |||||
| Gibbs-Duhem consistent | exactly | exactly on ions; not for a neutral with | to | see §6a | exactly, by construction (§6) |
All of them return the same object — a vector of cs.species, covering solutes, solvent, pure crystals (concentration_scale tells the accessors which convention was used. activity_coefficients evaluates the per-ion formula of the first three directly. SIT and Pitzer couple the solutes and have none; their coefficient is read back from the closure, which writes
One limit is common to all of them and is not one of accuracy. A cation cannot be added to a solution without an anion, so a measurement gives the mean coefficient of a neutral combination,
5. What the difference is worth, measured
The models are compared, on an imposed NaCl composition and without solving anything, in What the choice of activity model costs. Three results from that page belong here, because they are about the theory rather than about the numbers:
The ideal model is already several percent off at a millimolal. Ideality is not a safe default that degrades gracefully; it is exact only in a limit.
Davies and the B-dot model part company above a tenth molal, and by 3 mol/kg Davies returns
The values of
The B-dot model's own approximation — a single charge-weighted mean ion size in its osmotic coefficient — costs nothing in NaCl, whose two ions carry the ion size of the salt, and appears only in a solution whose ions differ in size.
5b. Does a model come from one excess Gibbs energy at all?
§5 measures a Gibbs-Duhem residual along one path. A small residual there is necessary and not sufficient: a model can cancel along a dissolution and fail badly in another direction. The question underneath is whether the activities are the gradient of any function of
If
and,
The first is the sharper: it fails exactly when no activity_model returns, by automatic differentiation — no
What is measured
On H2O@ / Na⁺ / Cl⁻ / Ca²⁺ / SO₄²⁻ at 0.1, 0.12, 0.02 and 0.01 mol, worst relative asymmetry over pairs, ion/ion and solvent/ion separated:
| model | ion/ion | solvent/ion |
|---|---|---|
| Pitzer (on NaCl) | ||
| ideal dilute | ||
| Davies (no neutral species) | ||
| B-dot, | ||
| B-dot, common | ||
| B-dot, | ||
| B-dot, common | ||
| Debye-Hückel limiting law ( | ||
Two readings, and the second is the one that was not expected.
The limiting law is exact. It is the classical result, and it is the anchor: that model does come from one excess energy, to machine precision.
It takes both corrections to break it, and removing either alone does not mend it. Dropping
Why, in two lines
Every
and Maxwell demands that
With a common
and no , is proportional to exactly, and the ratio is the same for every ion. Hence the zeros in the table. A per-ion
puts inside the denominator , where it does not factor out.The
term is added with the same coefficient to every ion, so it contributes and not . An ion of charge 2 and an ion of charge 1 then disagree by construction.
Neither is a defect of this implementation: both are the published extended form, which every geochemical code uses. §2 already says what
What it means for a certificate
equilibrate_certified proves a KKT point of the problem it is handed. When the activities are not the gradient of a single optimal = true says less than its name suggests: a stationary point of the residuals, not a minimum of a potential.
In practice this is the regime every geochemical calculation on extended Debye-Hückel has always worked in, and the table says how far from a potential one is standing. Where the water activity carries the answer — a sealed paste, a concentrated brine — PitzerActivityModel is the model that has one, and §6 is about what that costs.
test/activities.jl pins the zeros and the orders of magnitude above, so a change to any
The two lines of the derivation are checked as such rather than only through their consequence. log10_gamma_expression returns the kernel as a symbolic expression, so
6a. SIT: one parameter per pair, and no radius
Between the corrected Debye-Hückel laws above and the virial expansion below sits the Specific ion Interaction Theory (SIT). It keeps the screening term and replaces the empirical deviation term with a sum over pairs:
the sum running over ions
Read that against §2. Davies and the
The SITActivityModel exposes it as a field only to make that visible.
What it buys, and where it stops
The model is a truncation: the pairwise term is the first order of the same virial expansion §6 carries to second order, so at high ionic strength the terms it drops stop being small. The range usually quoted,
Why it matters here, beyond being one more option
The thermodynamic databases of the NEA reviews and of ANDRA's ThermoChimie are calibrated in SIT. A
What it costs
The water activity here is Raoult's mole fraction, as in TruesdellJonesActivityModel, not an osmotic coefficient: a departure from a full SIT treatment, in which the solvent follows from the terms of the solutes through
And an unlisted missing_epsilon_pairs reports which pairs of a given system are resting on it, because a convention silently applied is indistinguishable from a coefficient somebody determined.
6. The ion-interaction model: a different kind of object
Everything above is a corrected Debye-Hückel law: one screening term derived from electrostatics, one size correction, and one empirical term standing in for the rest. PitzerActivityModel is not that. It starts from the excess Gibbs energy and expands it as a virial series in the molalities, exactly as the pressure of a non-ideal gas is expanded in its density — (Anderson and Crerar, 1993) (§17.8) derive it as a cluster expansion with osmotic pressure in place of pressure, which is where the analogy is exact:
the first term in a virial equation always represents ideal behavior; in the second term
represents the non-ideal contribution from pairwise interactions of molecules; gives the interactions of triples.
Hence the shape of the parameter set: one coefficient per ion pair, one per triplet, and no per-species radius at all.
where
The long-range term keeps the Debye-Hückel physics — it must, since the limiting law is exact — in the form
and the pair term carries the ionic-strength dependence that a single constant cannot:
Why the whole construction matters here
What it costs
The parameters are caller input. The ThermoFun databases read by this package carry none; PHREEQC distributes a set in its pitzer.dat, and the package ships the cement set of Reardon (1990) in data/pitzer-reardon1990.toml, read by build_pitzer_parameters. What the package refuses is to invent a missing one. A PitzerParameters takes every table as a keyword without a default, and completeness is checked against the species list rather than against the set alone — every cation-anion pair present must have a
Two further terms belong to the model, and both are carried:
the higher-order electrostatic terms
and of Pitzer (1975), for two ions of like sign and unlike charge, Na⁺ with Ca²⁺ in a cement pore solution. They vanish for a symmetrical pair, enter and the osmotic coefficient from the same excess energy, and use Pitzer's function by the Chebyshev approximation PHREEQC uses (Plummer et al., 1988). A set whose were fitted without them is used with etheta = false;temperature terms of the coefficients, in the form PHREEQC's databases give them, used when the model is built with
temperature_dependent = true. A published set fitted at one temperature, as the shipped one is, carries none, and is used at its own values whatever the temperature.
A set in PHREEQC's format is read by build_pitzer_parameters with format = :phreeqc, from the file the caller has.
The speciation a set assumes is part of the set
This one is easy to miss and changes results. A Pitzer set absorbs ion association into its CaSO₄⁰ complex. A species list that carries both the free ions and the ion pairs therefore counts the same association twice, and CEMDATA18 does carry them — Ca(SO4)@, CaOH+, Na(SO4)-, NaOH@ among others. It also names the silica species differently (HSiO3-, SiO2@) from the set's H3SiO4- and H2SiO4-2.
So the shipped set of Reardon (1990) does not drop into a CEMDATA18 cement calculation, and the completeness check refuses such a system rather than returning a number. That refusal is the correct outcome and not a limitation of the implementation: combining a dissociated parameterization with an associated speciation is not a defensible calculation in any code.
7. Outside the domain
None of this survives arbitrary concentration, and the failure is silent: the formulas go on returning finite, plausible numbers. Two guards exist rather than one warning.
solvent_fraction reports the mole fraction of water within the aqueous phase, and SOLVENT_FRACTION_FLOOR is where equilibrate_certified refuses to call the answer a solution at all. The regime it catches is real: a cement paste below
A Pitzer model does not rescue that regime. Its fitted range is a few mol/kg, not hundreds, and no activity model repairs a composition that has left the physical picture of a solution.
Where to go next
The chapter continues with Solid solutions, the other place where a mixture departs from ideality. The expressions of this page are evaluated side by side in What the choice of activity model costs, the ion-interaction model is loaded and checked in The Pitzer model, and what it can be used with, and the syntax for choosing a model is in Activity models.