Skip to content

solution.Solution

Bases: object

An aqueous solution.

Notes

See phreeqpython.add_solution() for details on creating a solution.

Methods:

  • __add__

    Add two solutions.

  • __div__

    Set devision factor.

  • __init__

    Returns an empty solution.

  • __mul__

    Set multiplication factor.

  • __str__

    Returns solution and number.

  • __truediv__

    Python 3 support.

  • activity

    Returns the activity of a species in the solution.

  • add

    Add a species to the solution.

  • chain

    CHECK

  • change

    Change the solution by adding or removing species.

  • change_ph

    Change the pH of the solution.

  • change_temperature

    Change the temperature of the solution.

  • copy

    Returns an independent copy of the solution.

  • desaturate

    Desaturate a solution from a pure phase via precipitation or vaporization.

  • end

    CHECK

  • equalize

    Equalize the solution with one or more pure phases.

  • forget

    Remove this solution from the PhreeQC simulation.

  • interact

    Equilibrate the solution with a multicomponent gas or solid phase.

  • kinetics

    CHECK

  • molality

    Returns the molality of a species in the solution.

  • moles

    Returns the amount of a species in the solution.

  • remove

    Remove a species from the solution.

  • remove_fraction

    Remove a fraction of the species from the solution.

  • saturate

    Saturate the solution with a pure phase.

  • si

    Returns the saturation index (SI) of a phase in the solution.

  • sr

    Returns the saturation ratio (SR) of a phase in the solution.

  • total

    Returns the amount of a species in the solution.

  • total_activity

    Returns the total of the activities of all species of the element in the solution.

  • total_element

    Returns the total amount of an element in the solution.

Attributes:

  • I

    Returns the ionic strength of the solution.

  • density

    Returns the density of the solution.

  • elements

    Returns all elements in the solution and their amount.

  • extraneous
  • factor
  • mass

    Returns the mass of water in the solution.

  • masters_species

    Returns all master species in the solution and their species.

  • mu

    Returns the ionic strength of the solution.

  • number
  • pH

    Returns the pH of the solution.

  • pe

    REturns the electron activity of the solution.

  • phases

    Returns all phases in the solution and their saturation index (SI).

  • pp
  • sc

    Returns the specific conductance of the solution.

  • species

    Returns all species in the solution and their amount.

  • species_activities

    Returns all species in the solution and their activities.

  • species_molalities

    Returns all species in the solution and their concentration.

  • species_moles

    Returns all species in the solution and their amount.

  • temperature

    Returns the temperature of the solution.

  • volume

    Returns the volume of the solution.

Attributes

I property

Returns the ionic strength of the solution.

Returns:

  • float

    The ionic strength (mol/L).

density property

Returns the density of the solution.

Returns:

  • float

    The density (kg/L).

(kg/L).

elements property

Returns all elements in the solution and their amount.

Returns:

  • dict

    With phase (str) and amount (float) pairs, amount in mol.

Examples:

>>> sol.elements
{   'C(4)': 0.50,
    'Ca': 0.20,
    ... 
}

extraneous = {} if extraneous is None else extraneous instance-attribute

factor = 1 instance-attribute

mass property

Returns the mass of water in the solution.

Returns:

  • float

    The mass of water (kg).

Warning

not very intuitive, one would expect this to return the solution mass, not the water part.
I did a few checks with high salt concentrations:
sol.volume * sol.density always accurately returns the solution mass.

Proposal:
sol.mass = sol.volume * sol.density
sol.mass_water = the water mass

masters_species property

Returns all master species in the solution and their species.

Returns:

  • dict

    with master_species (str) and species (lst[str]) pairs.

Examples:

>>> sol.masters_species        
{   'C(4)': ['CO2', 'CO3-2', 'CaCO3', 'HCO3-'],
    'Ca': ['Ca+2', 'CaCO3', 'CaHCO3+', 'CaOH+'],
    'Cl': ['Cl-'],
    ...
}
Warning

shouldn't this be: master_species ?

mu property

Returns the ionic strength of the solution.

Returns:

  • float

    The ionic strength (mol/L).

number = number instance-attribute

pH property

Returns the pH of the solution.

Returns:

  • float

    The pH (-).

pe property

REturns the electron activity of the solution.

Returns:

  • float

    The electron activity (-).

Notes

pe = -log({e-}), with {e-} the electron activity.
pe < 0: high electron activity, reducing environment.
pe > 0: low electron activity, oxidizing environment.

phases property

Returns all phases in the solution and their saturation index (SI).

Returns:

  • dict

    With phase (str) and SI (float) pairs.

Example

sol.phases { 'Calcite': 0.155, 'CO2(g)': -0.341, ... }

Notes

SI = log10(AIP / Ksp)

pp = phreeqpython instance-attribute

sc property

Returns the specific conductance of the solution.

Returns:

  • float

    The specific conductance (µS/cm).

Notes

Specific conductance calculated at temperature of the solution.

species property

Returns all species in the solution and their amount.

Returns:

  • dict

    With species (str) and amount (float) pairs, amount in mmol.

Examples:

>>> sol.species
{   'Ca+2': 0.0036,
    'CO3-2': 2.18e-05,
    ...
}
Warning

units not used, and probably not accessible via a property?
amount is in mol, not mol/L or mol/kgw, can be confusing when sol.mass <> 1.0 kg,
better return a concentration (mol/kgw or mol/kgs)?

species_activities property

Returns all species in the solution and their activities.

Returns:

  • dict

    With species (str) and activity (float) pairs, activity in mol/kgw.

Examples:

>>> sol.species_activities
{   'Ca+2': 0.045,
    'CO3-2': 3.18e-05,
    ...
}

species_molalities property

Returns all species in the solution and their concentration.

Returns:

  • dict

    With species (str) and concentration (float) pairs, concentration in mol/kgw.

Examples:

>>> sol.species_molalities
{   'Ca+2': 0.045,
    'CO3-2': 3.18e-05,
    ...
}
Warning

units not used.
this property returns a concentration (mol/kgw), while sol.species returns
absolute amount (mol). Not very intuitive.
Maybe we could define the default units on the simulation level (phreeqpython = pp)?
And have an accessible function to convert if needed (pp.units(...))?

species_moles property

Returns all species in the solution and their amount.

Returns:

  • dict

    With species (str) and amount (float) pairs, amount in mol.

Warning

calls same function, no difference with property species?
better drop this one?

temperature property

Returns the temperature of the solution.

Returns:

  • float

    The temperature (°C).

volume property

Returns the volume of the solution.

Returns:

  • float

    The volume (L).

Methods:

__add__(other)

Add two solutions.

Warning

Remark for creating these:
>>> sol3 = sol1 * 0.2 + sol2 * 0.8
>>> sol3 = sol1 * 0.2
>>> sol3 = sol1 / 4.0

currently, sol.factor is used to track the coefficient in making these mixtures.

But doing this: sol3 = sol1*2 does not increase sol3.mass, it only sets sol3.factor, which is not what the user wants.

Also: sol3 = sol11 + sol12 gives: sol3.mass = 2, not 3, because the second term sets sol1.factor = 2, and then the addition is evaluated

Wouldn't it be easier and more intuitive to do as follows?: sol1*2 calls:
def mul(self, factor):
mixture = self.pp.mix_solutions({self: factor})
return mixture

No need anymore to track the factors, and the resulting solutions always reflect the proper amount. sol3 = sol1 * 0.2 + sol2 * 0.8 will then call mix_solutions 3 times, small price to pay?

__div__(other)

Set devision factor.

__init__(phreeqpython, number, extraneous=None)

Returns an empty solution.

Notes

Use phreeqpython.add_solution() to create a solution.

Warning

the fields: pp, factor, number and extraneous are accessible by the user.
probably not the intention?
Better to make them private?

__mul__(other)

Set multiplication factor.

__str__()

Returns solution and number.

Returns:

  • str

    A string like:

__truediv__(other)

Python 3 support.

activity(species, units='mmol')

Returns the activity of a species in the solution.

Parameters:

  • element (str) –

    Chemical species.

  • units (str, default: 'mmol' ) –

    Optional, unit of the activity.

Returns:

  • float

    Activity of the species (mmol/kgw).

Examples:

>>> sol.activity('Ca+2')
>>> sol.activity('NaSO4-', 'mg')        
Warning

this returns a concentration (/kgw), not a total amount.
Confusing with the units shown.

add(element, amount, units='mmol')

Add a species to the solution.

Parameters:

  • element (str) –

    An element or species.

  • amount (float) –

    Amount of the species added.

  • units (str, default: 'mmol' ) –

    Optional, unit of the amount.

Returns:

  • Solution

    The altered solution.

Examples:

>>> sol.add('Fe', 5.0)
>>> sol.add('CaCO3', 10.0, 'mg')

chain()

CHECK

Warning

This calls the PhreeQC 'USE SOLUTION' keyword, but not clear when you would need to use this, not intuitive.
What are the use cases?

change(composition, units='mmol')

Change the solution by adding or removing species.

Parameters:

  • composition (dict) –

    A dictionary of (species, amount) pairs.

  • units (str, default: 'mmol' ) –

    Optional, unit of the amounts.

Returns:

  • Solution

    The altered solution.

Examples:

>>> sol.change({'K': 20.0, 'Na': -10.0})
>>> sol.change({'CaSO4': 5.0}, units='mg')
>>> sol.change({'NaCl': -10.0, 'Fe+2': -5.0})

change_ph(to_pH, with_chemical=None)

Change the pH of the solution.

Parameters:

  • to_pH (float) –

    target pH.

  • with_chemical (str, default: None ) –

    Optional, acid of base to add, default is 'HCl' or 'NaOH'.

Returns:

Examples:

>>> sol.change_ph(4.5)
>>> sol.change_ph(4.5, 'H2SO4')

change_temperature(to_temperature)

Change the temperature of the solution.

Parameters:

  • to_temperature (float) –

    Target temperature.

Returns:

Examples:

>>> sol.change_temperature(50.0)

copy()

Returns an independent copy of the solution.

Examples:

>>> sol2 = sol.copy()

desaturate(phase, to_si=0)

Desaturate a solution from a pure phase via precipitation or vaporization.

Parameters:

  • phase (str) –

    A pure gas or solid phase.

  • to_si (float, default: 0 ) –

    Optional, target saturation index for the phase.

Returns:

  • Solution

    The solution after equilibration.

Examples:

>>> sol.desaturate('Gypsum')
>>> sol.desaturate('CO2(g)', to_si=-3.5)
Notes

This method will only desaturate, not saturate.

end()

CHECK

Warning

Calls the keyword 'END' on the PhreeQC simulation?
Not better to only define that at the simulation side (pp)?
Its use for a solution is not clear.

equalize(phases, to_si=[0.0], in_phase=[10.0], with_chemical=[None])

Equalize the solution with one or more pure phases.

Parameters:

  • phases (lst[str]) –

    List of one or more pure gas or solid phases.

  • to_si (lst[float], default: [0.0] ) –

    Optional, list of target saturation indices for each phase.

  • in_phase (lst[float], default: [10.0] ) –

    Optional, list of maximum amounts available for each phase, in moles.

  • with_chemical (lst[str], default: [None] ) –

    Optional, list of alternative chemical added for each phase to reach the specified saturation index.

Returns:

  • Solution

    The solution after equilibration.

Examples:

>>> sol.equalize(phases=['Calcite'])
>>> sol.equalize(phases=['CO2(g)', 'CH4(g)'], to_si=[-0.4, -0.2])
>>> sol.equalize(phases=['Calcite'], with_chemical='HCl')
Notes

saturation index (SI):
for solid phases: SI = log10(IAP / Ksp)
for gases: SI = log10(p_gas), with p_gas the partial pressure.

forget()

Remove this solution from the PhreeQC simulation.

Notes

See also phreeqpython.add_solution() to add solutions to a PhreeQC simulation.

interact(gas_or_phase)

Equilibrate the solution with a multicomponent gas or solid phase.

Parameters:

  • gas_or_phase (Gas | Equilibriumphase) –

    Previously defined multicomponent gas or solid phase.

Returns:

  • Solution

    The solution after equilibrium with the gas or solid phase.

Examples:

>>> air = pp.add_gas({'O2(g)': 0.2, 'N2(g)': 0.78, 'CO2(g)': 0.000420})
>>> sol.interact(air)

kinetics(element, rate_function, time, m0=0, args=(), units='mmol')

CHECK

Warning

the kinetics examples show different ways of setting up kinetics (with and without this function). Still experimental?
PhreeQC has the kinetics keyword, but would require to parse the rate function(s) into BASIC, hard... but PhreeQC allows kinetics over the whole simulation (e.g. solution, gas, other phases)

Not better to move kinetics functionality to the simulation level (phreeqpython = pp)?

molality(species, units='mmol')

Returns the molality of a species in the solution.

Parameters:

  • element (str) –

    Chemical species.

  • units (str, default: 'mmol' ) –

    Optional, unit of the amount.

Returns:

  • float

    Molality of the species (mmol/kgw).

Examples:

>>> sol.molality('Na+')
>>> sol.molality('HCO3-', 'mg')        
Warning

Confusing, units given in 'mmol'... , but returns 'mmol/kgw'?
Checked with {'-water': 2.0, ...} as solution: sol.total() and sol.moles() return 'mmol',
but sol.molality() returns ~half the value, so takes count of the total mass.
Should we show different units?

moles(species, units='mmol')

Returns the amount of a species in the solution.

Parameters:

  • element (str) –

    Chemical species.

  • units (str, default: 'mmol' ) –

    Optional, unit of the amount.

Returns:

  • float

    Amount of the species (mmol).

Examples:

>>> sol.moles('Na+')
>>> sol.moles('HCO3-', 'mg')        
Warning

Confusing, says moles, but can also return in 'mg'.
Also, seems to always return the same value as sol.total().
Better to remove this method?

remove(element, amount, units='mmol')

Remove a species from the solution.

Parameters:

  • element (str) –

    An element or species.

  • amount (float) –

    Amount of the species removed.

  • units (str, default: 'mmol' ) –

    Optional, unit of the amount.

Returns:

  • Solution

    The altered solution.

Examples:

>>> sol.remove('Fe', 5.0)
>>> sol.remove('CaCO3', 10.0, 'mg')

remove_fraction(species, fraction)

Remove a fraction of the species from the solution.

Parameters:

  • species (str) –

    An element or species.

  • fraction (float) –

    Fraction of amount to remove.

Returns:

  • Solution

    The altered solution.

Examples:

>>> sol.remove('K', 0.3)
>>> sol.remove('H2O', 0.9)

saturate(phase, to_si=0, in_phase=10)

Saturate the solution with a pure phase.

Parameters:

  • phase (str) –

    A pure gas or solid phase.

  • to_si (float, default: 0 ) –

    Optional, target saturation index for the phase.

  • in_phase (float, default: 10 ) –

    Optional, maximum amount available of the phase.

Returns:

  • Solution

    The solution after equilibration.

Examples:

>>> sol.saturate('Calcite')
>>> sol.saturate('CO2(g)', to_si=-3.5)

si(phase)

Returns the saturation index (SI) of a phase in the solution.

Parameters:

  • phase (str) –

    Gas or solid phase.

Returns:

  • float

    The SI of the phase (-).

Examples:

>>> sol.si('Calcite')
>>> sol.si('CO2(g)')
Notes

Solid phases: SI = log10(IAP / Ksp), with IAP the ion activity product and Ksp the solubility product constant.
Gases: SI = log10(p_gas), with p_gas the partial pressure.

sr(phase)

Returns the saturation ratio (SR) of a phase in the solution.

Parameters:

  • phase (str) –

    Gas or solid phase.

Returns:

  • float

    The SR of the phase (-).

Examples:

>>> sol.sr('Calcite')
>>> sol.sr('CO2(g)')
Notes

Solid phases: SR = IAP / Ksp, with IAP the ion activity product and Ksp the solubility product constant.
Gases: SR = p_gas, with p_gas the partial pressure.

total(element, units='mmol')

Returns the amount of a species in the solution.

Parameters:

  • element (str) –

    Chemical species.

  • units (str, default: 'mmol' ) –

    Optional, unit of the amount.

Returns:

  • float

    Amount of the species (mmol).

Examples:

>>> sol.total('Na+')
>>> sol.total('CO2')
>>> sol.total('HCO3-', 'mg')

total_activity(element, units='mmol')

Returns the total of the activities of all species of the element in the solution.

Parameters:

  • element (str) –

    Element (atomic species).

  • units (str, default: 'mmol' ) –

    Optional, unit of the activity.

Returns:

  • float

    Total activity of the element (mmol/kgw).

Examples:

>>> sol.activity('Ca')
>>> sol.activity('C', 'mg')        
Warning

Slow function!

total_element(element, units='mmol')

Returns the total amount of an element in the solution.

Parameters:

  • element (str) –

    Element (atomic species).

  • units (str, default: 'mmol' ) –

    Optional, unit of the amount.

Returns:

  • float

    Total amount of the element (mmol).

Examples:

>>> sol.total_element('C')
>>> sol.total_element('S', 'mg')