Solving equilibria
There are two 'layers' of solver in Pytzer: stoichiometric and thermodynamic.
The stoichiometric solver determines the molality of each solute given a set of total molalities and fixed stoichiometric equilibrium constants. It uses a Newton-Raphson iterative method that is fully compatible with JAX.
The thermodynamic solver wraps the stoichiometric solver and adjusts the stoichiometric equilibrium constants to agree with thermodynamic constraints. Because it uses scipy.optimize.root, it cannot be differentiated or compiled with JAX.
You can solve equilibria using the following functions. Lower-level approaches with more fine control are possible, but not yet documented.
Solve a single solution
You can solve a single solution for equilibrium using pz.solve:
solutes, pks_constants = pz.solve(
totals,
exclude_equilibria=None,
ks_constants=None,
ks_only=None,
library=Seawater,
pressure=10.10325,
temperature=298.15,
verbose=False,
)
Arguments
totalsis anOrderedDictof the total molality of each group of components in the solution. Non-equilibrating components are included too. Equilibrating components are grouped as follows:totals["CO2"]= sum of all carbonate species.totals["PO4"]= sum of all phosphate species.totals["F"]= sum of all fluoride species.totals["SO4"]= sum of all sulfate species.totals["BOH3"]= sum of all borate species.totals["NH3"]= sum of all ammonia species.totals["H2S"]= sum of all sulfide species.totals["NO2"]= sum of all nitrite species.totals["H4SiO4"]= sum of all silicate species.totals["Mg"]= sum of all magnesium species.totals["Ca"]= sum of all calcium species.totals["Sr"]= sum of all strontium species.
exclude_equilibriaallows you to list equilibria that will not be included in the model.ks_constantsallows you to provide your own initial-guess values of the stoichiometric equilibrium constants, as adict.ks_onlyallows you to list equilibria for which the thermodyamic constants are not used (i.e. the initial stoichiometric constants are kept constant).libraryis theParameterLibrarythat you want to use.pressureis the pressure in dbar.temperatureis the temperature in K.verbosecontrols how much information is sent to stdout.
Results
solutesis anOrderedDictof the molality of each component at thermodynamic equilibrium.ks_constantsis adictof the stoichiometric equilibrium constants at thermodynamic equilibrium.
Solve a pandas DataFrame
You can put the totals described above into columns of a pandas DataFrame (df), add columns for "temperature" (in K) and "pressure" (in dbar) if needed, and then solve all the rows in the DataFrame with pz.solve_df:
pz.solve_df(
df,
exclude_equilibria=None,
inplace=True,
ks_only=None,
library=Seawater,
verbose=False,
)