Solubility of gypsum and associated activities
This example closely follows Section 8.3 of Bethke (2007).
The solubility of gypsum (CaSO.2HO) as a function of NaCl concentration is explored. A simulation is initialized with some undissolved Gypsum and small quantities of Na and Cl, and then NaCl is progressively added. The following assumptions are made:
Gypsum is used in the basis instead of the aqueous species Ca.
The initial amount of free gypsum is 0.5814mol (g).
Charge balance is performed on SO.
Hence, the basis is (H20, Na+, Cl-, SO4–, gypsum). The simulation computes how much gypsum is dissolved as a function of the concentration of NaCl.
The results are shown in Figure 8.6 of Bethke (2007).
The MOOSE input file
The input file begins by defining the basis aqueous species and the equilibrium minerals (only Gypsum) for the model. The piecewise_linear_interpolation
flag is used for accurate comparison with the Geochemists Workbench software.
[UserObjects<<<{"href": "../../../syntax/UserObjects/index.html"}>>>]
[definition]
type = GeochemicalModelDefinition<<<{"description": "User object that parses a geochemical database file, and only retains information relevant to the current geochemical model", "href": "../../../source/userobjects/GeochemicalModelDefinition.html"}>>>
database_file<<<{"description": "The name of the geochemical database file"}>>> = "../../../database/moose_geochemdb.json"
basis_species<<<{"description": "A list of basis components relevant to the aqueous-equilibrium problem. H2O must appear first in this list. These components must be chosen from the 'basis species' in the database, the sorbing sites (if any) and the decoupled redox states that are in disequilibrium (if any)."}>>> = "H2O Cl- Na+ SO4-- Ca++"
equilibrium_minerals<<<{"description": "A list of minerals that are in equilibrium with the aqueous solution. All members of this list must be in the 'minerals' section of the database file"}>>> = "Gypsum"
piecewise_linear_interpolation<<<{"description": "If true then use a piecewise-linear interpolation of logK and Debye-Huckel parameters, regardless of the interpolation type specified in the database file. This can be useful for comparing with results using other geochemistry software"}>>> = true # for comparison with GWB
[]
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)A TimeDependentReactionSolver is used to simulate the adding of NaCl:
Ca is swapped out of the basis in favor of Gypsum.
Na and Cl are provided with a small initial molality. The molality for SO will actually be controlled by charge neutrality.
0.5814 free moles of Gypsum are introduced into the initial system
During the initial setup, the
geochemistry
module will find the equilibrium configuration corresponding to these initial conditions. By default, it will then close the system (theclose_system_at_time
input defaults to 0.0). This stops any further Gypsum from entering the system.The rate of addition of NaCl is defined to be 1.0mol/s
The other flags enable an accurate comparison with the Geochemists Workbench software.
[TimeDependentReactionSolver<<<{"href": "../../../syntax/TimeDependentReactionSolver/index.html"}>>>]
model_definition<<<{"description": "The name of the GeochemicalModelDefinition user object (you must create this UserObject yourself)"}>>> = definition
swap_out_of_basis<<<{"description": "Species that should be removed from the model_definition's basis and be replaced with the swap_into_basis species"}>>> = "Ca++"
swap_into_basis<<<{"description": "Species that should be removed from the model_definition's equilibrium species list and added to the basis. There must be the same number of species in swap_out_of_basis and swap_into_basis. These swaps are performed before any other computations during the initial problem setup. If this list contains more than one species, the swapping is performed one-by-one, starting with the first pair (swap_out_of_basis[0] and swap_into_basis[0]), then the next pair, etc"}>>> = "Gypsum"
charge_balance_species<<<{"description": "Charge balance will be enforced on this basis species. This means that its bulk mole number may be changed from the initial value you provide in order to ensure charge neutrality. After the initial swaps have been performed, this must be in the basis, and it must be provided with a bulk_composition constraint_meaning."}>>> = "SO4--"
constraint_species<<<{"description": "Names of the species that have their values fixed to constraint_value with meaning constraint_meaning. All basis species (after swap_into_basis and swap_out_of_basis) must be provided with exactly one constraint. These constraints are used to compute the configuration during the initial problem setup, and in time-dependent simulations they may be modified as time progresses."}>>> = "H2O Cl- Na+ SO4-- Gypsum"
constraint_value<<<{"description": "Numerical value of the containts on constraint_species"}>>> = " 1.0 1E-10 1E-10 1E-6 0.5814"
constraint_meaning<<<{"description": "Meanings of the numerical values given in constraint_value. kg_solvent_water: can only be applied to H2O and units must be kg. bulk_composition: can be applied to all non-gas species, and represents the total amount of the basis species contained as free species as well as the amount found in secondary species but not in kinetic species, and units must be moles or mass (kg, g, etc). bulk_composition_with_kinetic: can be applied to all non-gas species, and represents the total amount of the basis species contained as free species as well as the amount found in secondary species and in kinetic species, and units must be moles or mass (kg, g, etc). free_concentration: can be applied to all basis species that are not gas and not H2O and not mineral, and represents the total amount of the basis species existing freely (not as secondary species) within the solution, and units must be molal or mass_per_kg_solvent. free_mineral: can be applied to all mineral basis species, and represents the total amount of the mineral existing freely (precipitated) within the solution, and units must be moles, mass or cm3. activity and log10activity: can be applied to basis species that are not gas and not mineral and not sorbing sites, and represents the activity of the basis species (recall pH = -log10activity), and units must be dimensionless. fugacity and log10fugacity: can be applied to gases, and units must be dimensionless"}>>> = "kg_solvent_water free_concentration free_concentration bulk_composition free_mineral"
constraint_unit<<<{"description": "Units of the numerical values given in constraint_value. Dimensionless: should only be used for activity or fugacity constraints. Moles: mole number. Molal: moles per kg solvent water. kg: kilograms. g: grams. mg: milligrams. ug: micrograms. kg_per_kg_solvent: kilograms per kg solvent water. g_per_kg_solvent: grams per kg solvent water. mg_per_kg_solvent: milligrams per kg solvent water. ug_per_kg_solvent: micrograms per kg solvent water. cm3: cubic centimeters"}>>> = " kg molal molal moles moles"
source_species_names<<<{"description": "The name of the species that are added at rates given in source_species_rates. There must be an equal number of these as source_species_rates."}>>> = 'NaCl'
source_species_rates<<<{"description": "Rates, in mols/time_unit, of addition of the species with names given in source_species_names. A negative value corresponds to removing a species: be careful that you don't cause negative mass problems!"}>>> = '1.0'
add_aux_pH<<<{"description": "Add AuxVariable, called pH, that records the pH of solvent water"}>>> = false # there is no H+ in the problem
ramp_max_ionic_strength_initial<<<{"description": "The number of iterations over which to progressively increase the maximum ionic strength (from zero to max_ionic_strength) during the initial equilibration. Increasing this can help in convergence of the Newton process, at the cost of spending more time finding the aqueous configuration."}>>> = 0 # not needed in this simple problem
stoichiometric_ionic_str_using_Cl_only<<<{"description": "If set to true, the stoichiometric ionic strength will be set equal to Cl- molality (or max_ionic_strength if the Cl- molality is too big). This flag overrides ionic_str_using_basis_molality_only"}>>> = true # for comparison with GWB
abs_tol<<<{"description": "If the residual of the algebraic system (measured in mol) is lower than this value, the Newton process (that finds the aqueous configuration) is deemed to have converged"}>>> = 1E-12
execute_console_output_on<<<{"description": "When to execute the geochemistry console output"}>>> = '' # only CSV output in this example
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)The time-stepping and output are defined in the usual MOOSE way. In this case, a FunctionDT
timestepper is used to capture the nonlinear behaviour at the beginning of the simulation:
[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
type = Transient
[TimeStepper<<<{"href": "../../../syntax/Executioner/TimeStepper/index.html"}>>>]
type = FunctionDT
function = timestepper
[]
end_time = 3
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
csv<<<{"description": "Output the scalar variable and postprocessors to a *.csv file using the default CSV output."}>>> = true
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)An AuxVariable
captures the amount of dissolved gypsum by using the bulk_moles_Gypsum
and free_mg_Gypsum
AuxVariables
that are automatically added by the TimeDependentReactionSolver is used to simulate the adding of NaCl:
[AuxVariables<<<{"href": "../../../syntax/AuxVariables/index.html"}>>>]
[dissolved_gypsum_moles]
[]
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)[AuxKernels<<<{"href": "../../../syntax/AuxKernels/index.html"}>>>]
[dissolved_gypsum_moles]
type = ParsedAux<<<{"description": "Sets a field variable value to the evaluation of a parsed expression.", "href": "../../../source/auxkernels/ParsedAux.html"}>>>
coupled_variables<<<{"description": "Vector of coupled variable names"}>>> = 'bulk_moles_Gypsum free_mg_Gypsum'
expression<<<{"description": "Parsed function expression to compute"}>>> = 'bulk_moles_Gypsum - free_mg_Gypsum / 1000 / 172.168 '
variable<<<{"description": "The name of the variable that this object applies to"}>>> = dissolved_gypsum_moles
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'timestep_end'
[]
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)Finally, Postprocessors
allow the desired information to be written to the CSV output file
[Postprocessors<<<{"href": "../../../syntax/Postprocessors/index.html"}>>>]
[cl_molal]
type = PointValue<<<{"description": "Compute the value of a variable at a specified location", "href": "../../../source/postprocessors/PointValue.html"}>>>
point<<<{"description": "The physical point where the solution will be evaluated."}>>> = '0 0 0'
variable<<<{"description": "The name of the variable that this postprocessor operates on."}>>> = 'molal_Cl-'
[]
[dissolved_gypsum_mol]
type = PointValue<<<{"description": "Compute the value of a variable at a specified location", "href": "../../../source/postprocessors/PointValue.html"}>>>
point<<<{"description": "The physical point where the solution will be evaluated."}>>> = '0 0 0'
variable<<<{"description": "The name of the variable that this postprocessor operates on."}>>> = dissolved_gypsum_moles
[]
[]
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.i)GWB input file
An equivalent Geochemists Workbench input file is
# React script that is equivalent to gypsum_solubility.i
data = thermo.tdat verify
conductivity = conductivity-USGS.dat
temperature = 25 C
H2O = 1 free kg
Cl- = 1e-10 free mol
Na+ = 1e-10 free mol
SO4-- = 1e-6 mol
balance on SO4--
swap Gypsum for Ca++
Gypsum = .5814 free mol
react 3 mol of NaCl
suppress ALL
unsuppress Gypsum
dxprint = .01
(modules/geochemistry/test/tests/solubilities_and_activities/gypsum_solubility.rea)A total of 3 moles of NaCl is added to the system, which is equivalent to the 1mol/s over 3s used by the MOOSE input file. To extract the results from Geochemists Workbench its inbuilt graphing capability may be utilized, or the Cl molality vs the moles of Ca in the solution may be extracted from plaintext output file.
Results
The results are shown in Figure 1.

Figure 1: Gypsum solubility as a function of chlorine molality.
References
- Craig M. Bethke.
Geochemical and Biogeochemical Reaction Modeling.
Cambridge University Press, 2 edition, 2007.
doi:10.1017/CBO9780511619670.[BibTeX]