19 const std::vector<std::string> & swap_out_of_basis,
20 const std::vector<std::string> & swap_into_basis,
21 const std::string & charge_balance_species,
22 const std::vector<std::string> & constrained_species,
23 const std::vector<Real> & constraint_value,
26 Real initial_temperature,
27 unsigned iters_to_make_consistent,
28 Real min_initial_molality,
29 const std::vector<std::string> & kin_name,
30 const std::vector<Real> & kin_initial,
33 _num_basis(
mgd.basis_species_index.size()),
34 _num_eqm(
mgd.eqm_species_index.size()),
35 _num_redox(
mgd.redox_stoichiometry.m()),
36 _num_surface_pot(
mgd.surface_sorption_name.size()),
37 _num_kin(
mgd.kin_species_index.size()),
39 _swap_out(swap_out_of_basis),
40 _swap_in(swap_into_basis),
43 _charge_balance_species(charge_balance_species),
44 _original_charge_balance_species(charge_balance_species),
45 _charge_balance_basis_index(0),
46 _constrained_species(constrained_species),
47 _constraint_value(constraint_value),
48 _original_constraint_value(constraint_value),
49 _constraint_unit(constraint_unit.size()),
50 _constraint_user_meaning(constraint_user_meaning.size()),
51 _constraint_meaning(constraint_user_meaning.size()),
52 _eqm_log10K(_num_eqm),
53 _redox_log10K(_num_redox),
54 _kin_log10K(_num_kin),
55 _num_basis_in_algebraic_system(0),
56 _num_in_algebraic_system(0),
57 _in_algebraic_system(_num_basis),
58 _algebraic_index(_num_basis),
59 _basis_index(_num_basis),
60 _bulk_moles_old(_num_basis),
61 _basis_molality(_num_basis),
62 _basis_activity_known(_num_basis),
63 _basis_activity(_num_basis),
64 _eqm_molality(_num_eqm),
65 _basis_activity_coef(_num_basis),
66 _eqm_activity_coef(_num_eqm),
67 _eqm_activity(_num_eqm),
68 _surface_pot_expr(_num_surface_pot),
69 _sorbing_surface_area(_num_surface_pot),
71 _kin_moles_old(_num_kin),
72 _iters_to_make_consistent(iters_to_make_consistent),
73 _temperature(initial_temperature),
74 _min_initial_molality(min_initial_molality),
77 for (
unsigned i = 0; i < constraint_user_meaning.
size(); ++i)
79 static_cast<ConstraintUserMeaningEnum>(constraint_user_meaning.
get(i));
80 for (
unsigned i = 0; i < constraint_unit.
size(); ++i)
82 static_cast<GeochemistryUnitConverter::GeochemistryUnit>(constraint_unit.
get(i));
83 const unsigned ku_size = kin_unit.
size();
84 std::vector<GeochemistryUnitConverter::GeochemistryUnit> k_unit(ku_size);
85 for (
unsigned i = 0; i < ku_size; ++i)
86 k_unit[i] = static_cast<GeochemistryUnitConverter::GeochemistryUnit>(kin_unit.
get(i));
95 const std::vector<std::string> & swap_out_of_basis,
96 const std::vector<std::string> & swap_into_basis,
97 const std::string & charge_balance_species,
98 const std::vector<std::string> & constrained_species,
99 const std::vector<Real> & constraint_value,
100 const std::vector<GeochemistryUnitConverter::GeochemistryUnit> & constraint_unit,
101 const std::vector<ConstraintUserMeaningEnum> & constraint_user_meaning,
102 Real initial_temperature,
103 unsigned iters_to_make_consistent,
104 Real min_initial_molality,
105 const std::vector<std::string> & kin_name,
106 const std::vector<Real> & kin_initial,
107 const std::vector<GeochemistryUnitConverter::GeochemistryUnit> & kin_unit)
109 _num_basis(
mgd.basis_species_index.size()),
110 _num_eqm(
mgd.eqm_species_index.size()),
111 _num_redox(
mgd.redox_stoichiometry.m()),
112 _num_surface_pot(
mgd.surface_sorption_name.size()),
113 _num_kin(
mgd.kin_species_index.size()),
115 _swap_out(swap_out_of_basis),
116 _swap_in(swap_into_basis),
119 _charge_balance_species(charge_balance_species),
120 _original_charge_balance_species(charge_balance_species),
121 _charge_balance_basis_index(0),
122 _constrained_species(constrained_species),
123 _constraint_value(constraint_value),
124 _original_constraint_value(constraint_value),
125 _constraint_unit(constraint_unit),
126 _constraint_user_meaning(constraint_user_meaning),
127 _constraint_meaning(constraint_user_meaning.size()),
128 _eqm_log10K(_num_eqm),
129 _redox_log10K(_num_redox),
130 _kin_log10K(_num_kin),
131 _num_basis_in_algebraic_system(0),
132 _num_in_algebraic_system(0),
133 _in_algebraic_system(_num_basis),
134 _algebraic_index(_num_basis),
135 _basis_index(_num_basis),
136 _bulk_moles_old(_num_basis),
137 _basis_molality(_num_basis),
138 _basis_activity_known(_num_basis),
139 _basis_activity(_num_basis),
140 _eqm_molality(_num_eqm),
141 _basis_activity_coef(_num_basis),
142 _eqm_activity_coef(_num_eqm),
143 _eqm_activity(_num_eqm),
144 _surface_pot_expr(_num_surface_pot),
145 _sorbing_surface_area(_num_surface_pot),
146 _kin_moles(_num_kin),
147 _kin_moles_old(_num_kin),
148 _iters_to_make_consistent(iters_to_make_consistent),
149 _temperature(initial_temperature),
150 _min_initial_molality(min_initial_molality),
151 _original_redox_lhs()
158 const std::vector<std::string> & kin_name,
159 const std::vector<Real> & kin_initial,
160 const std::vector<GeochemistryUnitConverter::GeochemistryUnit> & kin_unit)
163 const unsigned num_kin_name = kin_name.size();
165 mooseError(
"Initial mole number (or mass or volume) and a unit must be provided for each " 176 const unsigned ind = std::distance(
177 kin_name.begin(), std::find(kin_name.begin(), kin_name.end(), name_index.first));
178 if (ind < num_kin_name)
188 ": units must be moles or mass, or volume in the case of minerals");
190 kin_initial[ind], kin_unit[ind], name_index.first,
_mgd);
194 mooseError(
"Initial mole number or mass or volume for kinetic species ",
196 " must be provided");
201 mooseError(
"swap_out_of_basis must have same length as swap_into_basis");
202 for (
unsigned i = 0; i <
_swap_out.size(); ++i)
206 " because it is the charge-balance species\n");
209 for (
unsigned i = 0; i <
_swap_out.size(); ++i)
221 mooseError(
"Cannot enforce charge balance using ",
223 " because it is not in the basis");
226 mooseError(
"Cannot enforce charge balance using ",
228 " because it has zero charge");
232 mooseError(
"Constrained species names must have same length as constraint values");
234 mooseError(
"Constrained species names must have same length as constraint units");
236 mooseError(
"Constrained species names must have same length as constraint meanings");
238 mooseError(
"Constrained species names must have same length as the number of species in the " 239 "basis (each component must be provided with a single constraint");
245 mooseError(
"The basis species ",
name,
" must appear in the constrained species list");
251 std::vector<GeochemistryUnitConverter::GeochemistryUnit> c_u(
_num_basis);
252 std::vector<ConstraintUserMeaningEnum> c_m(
_num_basis);
279 mooseError(
"Specified mass of solvent water must be positive: you entered ",
282 mooseError(
"Units for kg_solvent_water must be kg");
301 mooseError(
"Species ",
name,
": units for bulk composition must be moles or mass");
312 mooseError(
"Specified free concentration values must be positive: you entered ",
326 ": units for free concentration quantities must be molal or mass_per_kg_solvent");
336 mooseError(
"Specified free mineral values must be positive: you entered ",
346 ": units for free mineral quantities must be moles, mass or volume");
355 mooseError(
"Specified activity values must be positive: you entered ",
359 "Species ",
name,
": dimensionless units must be used when specifying activity");
369 ": dimensionless units must be used when specifying log10activity\n");
378 mooseError(
"Specified fugacity values must be positive: you entered ",
382 "Species ",
name,
": dimensionless units must be used when specifying fugacity\n");
392 ": dimensionless units must be used when specifying log10fugacity\n");
404 mooseError(
"H2O must be provided with either a mass of solvent water, a bulk composition " 405 "in moles or mass, or an activity");
410 mooseError(
"The gas ",
name,
" must be provided with a fugacity");
418 " must be provided with either: a free number of moles, a free mass or a free " 419 "volume; or a bulk composition of moles or mass");
428 " must be provided with a free concentration, bulk composition or an activity");
433 mooseError(
"For code consistency, the species ",
435 " must be provided with a bulk composition because it is the charge-balance " 436 "species. The value provided should be a reasonable estimate of the mole " 437 "number, but will be overridden as the solve progresses");
498 mooseError(
"Cannot retrieve log10K for equilibrium species ",
500 " since there are only ",
502 " equilibrium species");
516 mooseError(
"Cannot retrieve log10K for redox species ",
518 " since there are only ",
528 mooseError(
"Cannot retrieve activity product for redox species ",
530 " since there are only ",
534 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
549 mooseError(
"Cannot retrieve log10K for kinetic species ",
551 " since there are only ",
557 const std::vector<Real> &
567 mooseError(
"Cannot retrieve activity product for kinetic species ",
569 " since there are only ",
573 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
582 const unsigned numT = temps.size();
585 for (
unsigned eqm_j = 0; eqm_j <
_num_eqm; ++eqm_j)
592 for (
unsigned red = 0; red <
_num_redox; ++red)
599 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
610 unsigned & num_basis_in_algebraic_system,
611 unsigned & num_in_algebraic_system,
612 std::vector<unsigned> & algebraic_index,
613 std::vector<unsigned> & basis_index)
const 618 const std::string
name = name_index.first;
619 const unsigned basis_ind = name_index.second;
624 in_algebraic_system[basis_ind] =
false;
626 in_algebraic_system[basis_ind] =
false;
632 num_basis_in_algebraic_system = 0;
635 for (
unsigned basis_ind = 0; basis_ind <
_num_basis; ++basis_ind)
636 if (in_algebraic_system[basis_ind])
640 num_basis_in_algebraic_system += 1;
664 const std::vector<bool> &
670 const std::vector<unsigned> &
676 const std::vector<unsigned> &
719 std::vector<Real> & basis_molality)
const 730 bulk_moles_old[i] =
value;
731 basis_molality[i] = std::max(
744 basis_molality[i] =
value;
749 bulk_moles_old[i] =
value;
750 basis_molality[i] = std::max(
752 0.9 *
value / basis_molality[0]);
759 value * basis_molality[0] / 0.9;
761 basis_molality[i] =
value;
766 bulk_moles_old[i] =
value / 0.9;
768 basis_molality[i] =
value;
773 bulk_moles_old[i] = 0.0;
782 bulk_moles_old[i] =
value / 0.9;
785 basis_molality[i] = 1.0;
802 const std::vector<Real> &
821 std::vector<Real> trans_bulk;
823 DenseVector<Real> result(trans_bulk);
830 const std::vector<Real> &
838 std::vector<Real> & basis_activity)
const 840 basis_activity_known = std::vector<bool>(
_num_basis,
false);
849 basis_activity_known[i] =
true;
855 for (
unsigned basis_ind = 0; basis_ind <
_num_basis; ++basis_ind)
858 basis_activity_known[basis_ind] =
true;
859 basis_activity[basis_ind] = 1.0;
863 const std::vector<bool> &
873 mooseError(
"Cannot retrieve basis activity for species ",
875 " since there are only ",
881 const std::vector<Real> &
891 mooseError(
"Cannot retrieve molality for equilibrium species ",
893 " since there are only ",
895 " equilibrium species");
899 const std::vector<Real> &
909 mooseError(
"Cannot retrieve moles for kinetic species ",
911 " since there are only ",
921 mooseError(
"Cannot set moles for kinetic species ",
923 " since there are only ",
927 mooseError(
"Mole number for kinetic species must be positive, not ", moles);
932 const std::vector<Real> &
943 for (
unsigned basis_ind = 1; basis_ind <
_num_basis; ++basis_ind)
953 mooseError(
"Cannot retrieve activity coefficient for equilibrium species ",
955 " since there are only ",
957 " equilibrium species");
961 const std::vector<Real> &
971 mooseError(
"Cannot retrieve basis activity coefficient for species ",
973 " since there are only ",
979 const std::vector<Real> &
1001 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
1009 for (
unsigned eqm_j = 0; eqm_j <
_num_eqm; ++eqm_j)
1012 eqm_molality[eqm_j] = 0.0;
1018 eqm_molality[eqm_j] =
1037 std::vector<Real> & bulk_moles_old)
const 1039 Real tot_charge = 0.0;
1040 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
1061 Real tot_charge = 0.0;
1062 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
1076 std::vector<Real> & bulk_moles_old)
const 1088 mooseError(
"Incorrect size in setAlgebraicVariables");
1090 if (algebraic_var(
a) <= 0.0)
1091 mooseError(
"Cannot set algebraic variables to non-positive values such as ",
1116 bulk_moles_old[i] =
value;
1146 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1158 transported_bulk[i] = 0.0;
1169 transported_bulk[i] = 0.0;
1173 transported_bulk[i] *= nw;
1179 const DenseVector<Real> & mole_additions)
const 1182 mooseError(
"Cannot retrieve residual for algebraic index ",
1184 " because there are only ",
1186 " molalities in the algebraic system and ",
1188 " surface potentials and ",
1190 " kinetic species");
1192 mooseError(
"The increment in mole numbers (mole_additions) needs to be of size ",
1196 " but it is of size ",
1197 mole_additions.size());
1263 for (
unsigned eqm_j = 0; eqm_j <
_num_eqm; ++eqm_j)
1265 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1269 else if (algebraic_ind <
1289 const DenseVector<Real> & mole_additions,
1300 mooseError(
"Jacobian: the increment in mole numbers (mole_additions) needs to be of size ",
1304 " but it is of size ",
1305 mole_additions.size());
1308 mooseError(
"Jacobian: the derivative of mole additions (dmole_additions) needs to be of size ",
1312 " but it is of size ",
1313 dmole_additions.
m(),
1315 dmole_additions.
n());
1341 jac(
a,
b) -= dmole_additions(basis_of_a, basis_of_b);
1358 if (basis_of_b == 0)
1364 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1366 jac(
a, 0) += numerator / nw;
1395 if (basis_of_b != 0)
1399 for (
unsigned eqm_j = 0; eqm_j <
_num_eqm; ++eqm_j)
1418 const Real prefactor =
1420 if (i == basis_of_b)
1421 jac(
a,
b) += prefactor;
1422 for (
unsigned eqm_j = 0; eqm_j <
_num_eqm; ++eqm_j)
1444 for (
unsigned eqm_j = 0; eqm_j <
_num_eqm; ++eqm_j)
1458 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1463 jac(
a,
b) -= dmole_additions(basis_of_a, ind);
1481 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1501 const Real prefactor =
1503 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1522 if (basis_of_b == 0)
1549 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1555 const unsigned ind_of_addition =
_num_basis + kin;
1559 jac(
a,
b) -= dmole_additions(ind_of_addition, basis_of_b);
1561 for (
unsigned kinp = 0; kinp <
_num_kin; ++kinp)
1565 jac(
a,
b) -= dmole_additions(ind_of_addition, indp);
1591 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1612 if (swap_out_of_basis == 0)
1613 mooseException(
"GeochemicalSystem: attempting to swap out water and replace it by ",
1615 ". This could be because the algorithm would like to " 1616 "swap out the charge-balance species, in which case you should choose a " 1617 "different charge-balance species");
1619 mooseException(
"GeochemicalSystem: attempting to swap the charge-balance species out of " 1622 mooseException(
"GeochemicalSystem: attempting to swap a gas out of the basis");
1624 mooseException(
"GeochemicalSystem: attempting to swap a gas into the basis");
1641 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
1652 Real molality_of_species_just_swapped_in =
1659 molality_of_species_just_swapped_in =
1662 Real molality_of_species_just_swapped_out =
1664 _basis_molality[swap_out_of_basis] = molality_of_species_just_swapped_in;
1666 std::max(0.0, molality_of_species_just_swapped_out);
1724 unsigned best_species_opp_sign = 0;
1725 unsigned best_species_same_sign = 0;
1726 Real best_molality_opp_sign = 0.0;
1727 Real best_molality_same_sign = 0.0;
1728 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
1746 best_species_opp_sign = basis_i;
1755 best_species_same_sign = basis_i;
1760 if (best_species_opp_sign != 0)
1766 else if (best_species_same_sign != 0)
1816 mooseError(
"Cannot retrieve the surface potential for surface ",
1818 " since there are only ",
1820 " surfaces involved in surface complexation");
1830 mooseError(
"Cannot retrieve the surface charge for surface ",
1832 " since there are only ",
1834 " surfaces involved in surface complexation");
1852 sorbing_surface_area[sp] *= grams;
1857 const std::vector<Real> &
1879 const std::vector<std::string> & names,
1880 const std::vector<Real> & values,
1881 const std::vector<bool> & constraints_from_molalities)
1889 const unsigned num_names = names.size();
1890 if (num_names != values.size())
1891 mooseError(
"When setting all molalities, names and values must have same size");
1893 mooseError(
"When setting all molalities, values must be provided for every species and surface " 1895 if (constraints_from_molalities.size() !=
_num_basis)
1896 mooseError(
"constraints_from_molalities has size ",
1897 constraints_from_molalities.size(),
1898 " while number of basis species is ",
1911 const unsigned ind =
1912 std::distance(names.begin(), std::find(names.begin(), names.end(), name_index.first));
1913 if (ind < num_names)
1917 if (values[ind] != 0.0)
1922 ": it must be zero");
1928 if (values[ind] < 0.0)
1933 ": it must be non-negative");
1937 else if (values[ind] <= 0.0)
1942 ": it must be positive");
1947 mooseError(
"Molality (or free mineral moles, etc - whatever is appropriate) for species ",
1949 " needs to be provided when setting all molalities");
1953 const unsigned ind =
1954 std::distance(names.begin(), std::find(names.begin(), names.end(), name_index.first));
1955 if (ind < num_names)
1962 else if (values[ind] < 0.0)
1967 ": it must be non-negative");
1974 " needs to be provided when setting all molalities");
1978 const unsigned ind =
1979 std::distance(names.begin(),
1980 std::find(names.begin(),
1983 if (ind < num_names)
1985 if (values[ind] <= 0.0)
1986 mooseError(
"Surface-potential expression for mineral ",
1990 ": it must be positive");
1996 " needs to be provided when setting all molalities");
2000 const unsigned ind =
2001 std::distance(names.begin(), std::find(names.begin(), names.end(), name_index.first));
2002 if (ind < num_names)
2007 " needs to be provided when setting all molalities");
2023 if (constraints_from_molalities[i])
2041 if (constraints_from_molalities[i])
2051 if (constraints_from_molalities[i])
2055 mooseError(
"Gas fugacity cannot be determined from molality: constraints_from_molalities " 2056 "must be set false for all gases");
2060 mooseError(
"Water activity cannot be determined from molalities: " 2061 "constraints_from_molalities " 2062 "must be set to false for water if activity of water is fixed");
2093 const std::vector<GeochemicalSystem::ConstraintMeaningEnum> &
2102 for (
unsigned basis_ind = 0; basis_ind <
_num_basis; ++basis_ind)
2113 mooseError(
"Cannot changeConstraintToBulk for species ",
2115 " because there are only ",
2122 unsigned swap_into_basis = 0;
2123 bool legitimate_swap_found =
false;
2124 Real best_stoi = 0.0;
2131 if (stoi > best_stoi)
2134 swap_into_basis =
j;
2135 legitimate_swap_found =
true;
2138 if (legitimate_swap_found)
2141 mooseError(
"Attempting to change constraint of gas ",
2143 " to MOLES_BULK_SPECIES, which involves a search for a suitable non-gas species " 2144 "to swap with. No such species was found");
2154 mooseError(
"Cannot changeConstraintToBulk for species ",
2156 " because there are only ",
2160 mooseError(
"Attempting to changeConstraintToBulk for a gas species. Since a swap is involved, " 2161 "you cannot specify a value for the bulk number of moles. You must use " 2162 "changeConstraintToBulk(basis_ind) method instead of " 2163 "changeConstraintToBulk(basis_ind, value)");
2185 mooseError(
"Cannot addToBulkMoles for species ",
2187 " because there are only ",
2202 mooseError(
"Cannot setConstraintValue for species ",
2204 " because there are only ",
2291 for (
const auto & name_info :
2293 for (
const auto & name_frac :
2294 name_info.second.sorption_sites)
2322 mooseError(
"Cannot retrieve activity for equilibrium species ",
2324 " since there are only ",
2326 " equilibrium species");
2332 for (
unsigned basis_i = 0; basis_i <
_num_basis; ++basis_i)
2341 const std::vector<Real> &
2353 mooseError(
"The increment in mole numbers (mole_additions) needs to be of size ",
2357 " but it is of size ",
2358 mole_additions.size());
2384 DenseVector<Real> & mole_additions,
2391 const unsigned tot = mole_additions.size();
2392 if (!(tot ==
_num_kin +
_num_basis && dmole_additions.
m() == tot && dmole_additions.
n() == tot))
2393 mooseError(
"addKineticRates: incorrectly sized additions: ",
2396 dmole_additions.
m(),
2398 dmole_additions.
n());
2412 const unsigned kin = krd.kinetic_species_index;
2414 krd.promoting_monod_indices,
2415 krd.promoting_half_saturation,
2469 mole_additions(ind) += krd.description.kinetic_bio_efficiency * rate * dt;
2470 dmole_additions(ind, ind) += krd.description.kinetic_bio_efficiency * drate_dkin * dt;
2472 ? krd.description.kinetic_bio_efficiency
2473 : krd.description.kinetic_bio_efficiency + 1.0;
2476 dmole_additions(ind, i) += krd.description.kinetic_bio_efficiency * drate_dmol[i] * dt;
2478 mole_additions(i) += stoi_fac * rate;
2479 dmole_additions(i, ind) += stoi_fac * drate_dkin;
2481 dmole_additions(i,
j) += stoi_fac * drate_dmol[
j];
2484 const Real eff = krd.description.progeny_efficiency;
2487 const unsigned bio_i = krd.progeny_index;
2490 mole_additions(bio_i) += eff * rate * dt;
2491 dmole_additions(bio_i, ind) += eff * drate_dkin * dt;
2493 dmole_additions(bio_i, i) += eff * drate_dmol[i] * dt;
2500 dmole_additions(i, ind) +=
2503 dmole_additions(i,
j) +=
std::vector< bool > surface_sorption_related
surface_sorption_related[j] = true iff the j^th equilibrium species is involved in surface sorption ...
void initialize()
initialize all variables, ready for a Newton solve of the algebraic system
void computeConsistentConfiguration()
Compute a reasonably consistent configuration that can be used as an initial condition in a Newton pr...
std::vector< Real > surface_sorption_area
surface_sorption_area[k] = specific surface area [m^2/g] for the k^th mineral involved in surface sor...
std::vector< Real > getAlgebraicBasisValues() const
DenseMatrix< Real > redox_stoichiometry
redox_stoichiometry(i, j) = stoichiometric coefficients for i^th redox species that is in disequilibr...
Real getTemperature() const
const unsigned _num_kin
number of kinetic species
DenseVector< Real > getBulkOldInOriginalBasis() const
std::vector< bool > _basis_activity_known
whether basis_activity[i] is fixed by the user
Real surfaceSorptionModifier(unsigned eqm_j) const
virtual Real waterActivity() const =0
Computes and returns the activity of water.
constexpr Real MOLES_PER_KG_WATER
std::string redox_lhs
the name of the species on the left-hand side of the redox equations.
const std::vector< Real > & getKineticMoles() const
std::vector< bool > kin_species_mineral
kin_species_mineral[j] = true iff the j^th kinetic species is a mineral
Real getIonicStrength() const
Get the ionic strength.
std::vector< bool > basis_species_transported
basis_species_transported[j] = true iff the j^th basis species is transported in reactive-transport s...
void initBulkAndFree(std::vector< Real > &bulk_moles_old, std::vector< Real > &basis_molality) const
based on _constrained_value and _constraint_meaning, populate nw, bulk_moles_old and basis_molality w...
const std::vector< Real > & getBasisActivity() const
virtual const char * what() const
std::vector< std::string > surface_sorption_name
surface_sorption_name[k] = name of the mineral involved in surface sorption.
const std::vector< std::string > _swap_in
Species to immediately add to the basis in favor of _swap_out.
void changeConstraintToBulk(unsigned basis_ind)
Changes the constraint to MOLES_BULK_SPECIES (or MOLES_BULK_WATER if basis_ind = 0) for the basis ind...
const unsigned _num_basis
number of basis species
std::vector< Real > _basis_molality
IMPORTANT: this is.
std::vector< Real > _kin_log10K
equilibrium constant of the kinetic species
const std::vector< Real > & getBulkMolesOld() const
std::string _original_redox_lhs
The left-hand-side of the redox equations in _mgd after initial swaps.
std::vector< unsigned > _algebraic_index
_algebraic_index[i] = index in the algebraic system of the basis species i. _basis_index[_algebraic_i...
void setChargeBalanceSpecies(unsigned new_charge_balance_index)
Set the charge-balance species to the basis index provided.
GeochemistryActivityCoefficients & _gac
Object to compute the activity coefficients and activity of water.
constexpr Real CELSIUS_TO_KELVIN
void mooseError(Args &&... args)
Real _min_initial_molality
Minimum molality ever used in an initial guess.
std::vector< bool > eqm_species_gas
eqm_species_gas[i] = true iff the i^th equilibrium species is a gas
std::vector< Real > _basis_activity_coef
basis activity coefficients
constexpr Real DIELECTRIC_CONSTANT_WATER
std::vector< Real > _eqm_activity
equilibrium activities.
Real log10ActivityProduct(unsigned eqm_j) const
std::unordered_map< std::string, unsigned > basis_species_index
basis_species_index[name] = index of the basis species, within all ModelGeochemicalDatabase internal ...
const ModelGeochemicalDatabase mgd
Fit the equilibrium constant values read from the thermodynamic databse at specified temperature valu...
void alterSystemBecauseBulkChanged()
Alter the GeochemicalSystem to reflect changes in bulk composition constraints that occur through...
void computeTransportedBulkFromMolalities(std::vector< Real > &transported_bulk) const
Computes the value of transported bulk moles for all basis species using the existing molalities...
std::vector< Real > _kin_moles_old
old mole number of kinetic species
std::vector< ConstraintUserMeaningEnum > _constraint_user_meaning
The user-defined meaning of the values in _constraint_value. In the constructor, this is ordered to h...
Real _temperature
The temperature in degC.
const unsigned _num_redox
number of redox species
DenseMatrix< Real > kin_stoichiometry
kin_stoichiometry(i, j) = stoichiometric coefficient for kinetic species "i" in terms of the basis sp...
std::vector< Real > kin_species_molecular_weight
all quantities have a molecular weight (g/mol)
std::vector< bool > _in_algebraic_system
if _in_algebraic_system[i] == true then we need to solve for the i^th basis-species molality ...
Real surfacePotPrefactor(unsigned sp) const
unsigned int size() const
std::string getLogKModel() const
Get the equilibrium constant model type.
std::unordered_map< std::string, unsigned > eqm_species_index
eqm_species_index[name] = index of the equilibrium species (secondary aqueous species, redox couples in equilibrium with the aqueous solution, minerals in equilibrium with the aqueous solution, gases in equilibrium with the aqueous solution) within all ModelGeochemicalDatabase internal datastrcutres, with given name
Real log10KineticActivityProduct(unsigned kin) const
DenseMatrix< Real > redox_log10K
redox_log10K(i, j) = log10(equilibrium constant) for i^th redox species at the j^th temperature point...
void computeBulk(std::vector< Real > &bulk_moles_old) const
Computes the value of bulk_moles_old for all basis species.
unsigned getChargeBalanceBasisIndex() const
return the index of the charge-balance species in the basis list
std::vector< Real > _basis_activity
values of activity (for water, minerals and aqueous basis species) or fugacity (for gases) ...
static const std::string temperature
void updateOldWithCurrent(const DenseVector< Real > &mole_additions)
Usually used at the end of a solve, to provide correct initial conditions to the next time-step...
void buildTemperatureDependentQuantities(Real temperature)
Using the provided value of temperature, build _eqm_log10K for each eqm species and redox species...
unsigned getNumKinetic() const
returns the number of kinetic species
unsigned _charge_balance_basis_index
The index in the list of basis species corresponding to the charge-balance species. This gets altered as the simulation progresses, due to swaps, and alterChargeBalanceSpecies.
void computeSorbingSurfaceArea(std::vector< Real > &sorbing_surface_area) const
Compute sorbing_surface_area depending on the current molality of the sorbing minerals.
Real ionicStrength(const ModelGeochemicalDatabase &mgd, const std::vector< Real > &basis_species_molality, const std::vector< Real > &eqm_species_molality, const std::vector< Real > &kin_species_molality) const
Compute ionic strength.
void calculateRate(const std::vector< Real > &promoting_indices, const std::vector< Real > &promoting_monod_indices, const std::vector< Real > &promoting_half_saturation, const KineticRateUserDescription &description, const std::vector< std::string > &basis_species_name, const std::vector< bool > &basis_species_gas, const std::vector< Real > &basis_molality, const std::vector< Real > &basis_activity, const std::vector< bool > &basis_activity_known, const std::vector< std::string > &eqm_species_name, const std::vector< bool > &eqm_species_gas, const std::vector< Real > &eqm_molality, const std::vector< Real > &eqm_activity, const DenseMatrix< Real > &eqm_stoichiometry, Real kin_moles, Real kin_species_molecular_weight, Real log10K, Real log10_activity_product, const DenseMatrix< Real > &kin_stoichiometry, unsigned kin, Real temp_degC, Real &rate, Real &drate_dkin, std::vector< Real > &drate_dmol)
Calclates a kinetic rate and its derivative.
DenseMatrix< Real > swap_to_original_basis
Swap matrix that allows expression in terms of the original basis.
std::vector< std::string > _constrained_species
Names of the species in that have their values fixed to _constraint_value with meanings _constraint_m...
const std::vector< Real > & computeAndGetEquilibriumActivity()
Computes activity for all equilibrium species (_eqm_activity) and returns a reference to the vector...
Real toMoles(Real quantity, const GeochemistryUnit unit, const std::string &species_name, const ModelGeochemicalDatabase &mgd)
Calculates the amount of moles corresponding to "quantity" "unit"s of species name, OR calculates the molality corresponding to "quantity" "unit"s of species name, whichever is appropriate.
std::vector< Real > _redox_log10K
equilibrium constant of the redox species
unsigned getNumInBasis() const
returns the number of species in the basis
std::unordered_map< std::string, unsigned > kin_species_index
kin_species_index[name] = index of the kinetic species, within all ModelGeochemicalDatabase internal ...
const std::vector< Real > & getKineticLog10K() const
std::vector< Real > _sorbing_surface_area
surface areas of the sorbing minerals
GeochemistryIonicStrength & _is
Object that provides the ionic strengths.
std::vector< Real > _constraint_value
Numerical values of the constraints on _constraint_species. In the constructor, this is ordered to ha...
void computeFreeMineralMoles(std::vector< Real > &basis_molality) const
Compute the free mineral moles (ie, basis_molality for basis species that are minerals), using the bulk_moles_old.
DenseMatrix< Real > eqm_stoichiometry
eqm_stoichiometry(i, j) = stoichiometric coefficient for equilibrium species "i" in terms of the basi...
void vector_mult_transpose(DenseVector< Real > &dest, const DenseVector< Real > &arg) const
unsigned _iters_to_make_consistent
Iterations to make the initial configuration consistent.
ConstraintMeaningEnum
Each basis species has one of the following constraints.
virtual void setInternalParameters(Real temperature, const ModelGeochemicalDatabase &mgd, const std::vector< Real > &basis_species_molality, const std::vector< Real > &eqm_species_molality, const std::vector< Real > &kin_species_molality)=0
Sets internal parameters, such as the ionic strength and Debye-Huckel parameters, prior to computing ...
const std::vector< Real > & getTemperatures() const
Get the temperature points that the equilibrium constant is defined at.
std::vector< Real > _bulk_moles_old
Number of bulk moles of basis species (this includes contributions from kinetic species, in contrast to Bethke)
Real getTotalChargeOld() const
void setKineticMoles(unsigned kin, Real moles)
Sets the current AND old mole number for a kinetic species.
Class to swap basis species with equilibrium species.
std::vector< Real > _kin_moles
mole number of kinetic species
constexpr Real PERMITTIVITY_FREE_SPACE
std::vector< unsigned > surface_sorption_number
surface_sorption_number[j] = the index of the surface potential that should be used to modify the equ...
const std::vector< Real > & getEquilibriumActivityCoefficient() const
GeochemistrySpeciesSwapper & _swapper
swapper that can swap species into and out of the basis
Real getEquilibriumActivity(unsigned eqm_ind) const
Returns the value of activity for the equilibrium species with index eqm_index.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
std::string _charge_balance_species
The species used to enforce charge balance.
Real getStoichiometricIonicStrength() const
Get the stoichiometric ionic strength.
unsigned getNumInAlgebraicSystem() const
std::vector< Real > _original_constraint_value
Numerical values of the constraints on _constraint_species. In the constructor, this is ordered to ha...
std::vector< Real > _surface_pot_expr
surface potential expressions.
const std::string _original_charge_balance_species
The species used to enforce charge balance, as provided in the constructor.
const std::vector< Real > & getSorbingSurfaceArea() const
const std::vector< Real > & getBasisActivityCoefficient() const
Calculators to compute ionic strength and stoichiometric ionic strength.
Base class to compute activity coefficients for non-minerals and non-gases (since these species do no...
const ModelGeochemicalDatabase & getModelGeochemicalDatabase() const
void addKineticRates(Real dt, DenseVector< Real > &mole_additions, DenseMatrix< Real > &dmole_additions)
Computes the kinetic rates and their derivatives based on the current values of molality, mole number, etc, and then, using dt, calculates the appropriate mole_additions and dmole_additions.
PetscErrorCode PetscInt const PetscInt IS * is
std::vector< GeochemistryUnitConverter::GeochemistryUnit > _constraint_unit
Units of the _constraint_value when the GeochemicalSystem is constructed. This is used during the con...
Real computeBulkFromMolalities(unsigned basis_ind) const
DenseMatrix< Real > kin_log10K
kin_log10K(i, j) = log10(equilibrium constant for the i^th kinetic species at the j^th temperature po...
std::vector< ConstraintMeaningEnum > _constraint_meaning
The meaning of the values in _constraint_value. In the constructor, this is ordered to have the same ...
std::vector< T > & get_values()
void enforceChargeBalance()
Enforces charge balance by altering the constraint_value and bulk_moles_old of the charge-balance spe...
const std::vector< unsigned > & getAlgebraicIndexOfBasisSystem() const
void enforceChargeBalanceIfSimple(std::vector< Real > &constraint_value, std::vector< Real > &bulk_moles_old) const
If all non-charged basis species are provided with a bulk number of moles, alter the bulk number of m...
void buildKnownBasisActivities(std::vector< bool > &basis_activity_known, std::vector< Real > &basis_activity) const
Fully populates basis_activity_known, which is true if activity has been set by the user...
DenseMatrix< Real > eqm_log10K
eqm_log10K(i, j) = log10(equilibrium constant) for i^th equilibrium species at the j^th temperature p...
Real getRedoxLog10K(unsigned red) const
std::vector< Real > basis_species_molecular_weight
all quantities have a molecular weight (g)
bool revertToOriginalChargeBalanceSpecies()
Changes the charge-balance species to the original that is specified in the constructor (this might n...
std::vector< unsigned > _basis_index
_basis_index[i] = index in the basis of the algebraic system species i, for i<num_basis_in_algebraic_...
bool alterChargeBalanceSpecies(Real threshold_molality)
If the molality of the charge-balance basis species is less than threshold molality, then attempt to change the charge-balance species, preferably to another component with opposite charge and big molality.
void setModelGeochemicalDatabase(const ModelGeochemicalDatabase &mgd)
Copies a ModelGeochemicalDatabase into our _mgd structure.
unsigned getNumRedox() const
void computeEqmMolalities(std::vector< Real > &eqm_molality) const
compute the equilibrium molalities (not for minerals or gases)
unsigned _num_in_algebraic_system
number of unknowns in the algebraic system (includes molalities and surface potentials) ...
unsigned int get(unsigned int i) const
const GeochemicalDatabaseReader * original_database
a pointer to the original database used to build this ModelGeochemicalDatabase
Real getLog10K(unsigned j) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const unsigned _num_surface_pot
number of surface potentials
Real getSurfacePotential(unsigned sp) const
std::vector< bool > eqm_species_transported
eqm_species_transported[i] = true iff the i^th eqm species is transported in reactive-transport sims ...
std::vector< Real > getAlgebraicVariableValues() const
void checkAndInitialize(const std::vector< std::string > &kin_name, const std::vector< Real > &kin_initial, const std::vector< GeochemistryUnitConverter::GeochemistryUnit > &kin_unit)
Used during construction: checks for sane inputs and initializes molalities, etc, using the initializ...
constexpr Real DENSITY_WATER
void updateBasisMolalityForKnownActivity(std::vector< Real > &basis_molality) const
For basis aqueous species (not water, minerals or gases) with activity set by the user...
void performSwap(ModelGeochemicalDatabase &mgd, const std::string &replace_this, const std::string &with_this)
Check that replacing the named basis species with the named equilibrium species is valid...
void buildAlgebraicInfo(std::vector< bool > &in_algebraic_system, unsigned &num_basis_in_algebraic_system, unsigned &num_in_algebraic_system, std::vector< unsigned > &algebraic_index, std::vector< unsigned > &basis_index) const
Builds in_algebraic_system, algebraic_index and basis_index, and sets num_basis_in_algebraic_system a...
unsigned getNumSurfacePotentials() const
return the number of surface potentials
void setTemperature(Real temperature)
Sets the temperature to the given quantity.
const unsigned _num_eqm
number of equilibrium species
std::vector< Real > _eqm_molality
molality of equilibrium species
constexpr Real GAS_CONSTANT
Real getResidualComponent(unsigned algebraic_ind, const DenseVector< Real > &mole_additions) const
Return the residual of the algebraic system for the given algebraic index.
std::vector< Real > basis_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0) ...
Real stoichiometricIonicStrength(const ModelGeochemicalDatabase &mgd, const std::vector< Real > &basis_species_molality, const std::vector< Real > &eqm_species_molality, const std::vector< Real > &kin_species_molality) const
Compute stoichiometric ionic strength.
Real log10RedoxActivityProduct(unsigned red) const
void resize(const unsigned int new_m, const unsigned int new_n)
std::vector< bool > basis_species_gas
basis_species_gas[j] = true iff the j^th basis species is a gas
std::vector< bool > basis_species_mineral
basis_species_mineral[j] = true iff the j^th basis species is a mineral
std::vector< Real > _eqm_log10K
equilibrium constant of the equilibrium species
ModelGeochemicalDatabase & _mgd
The minimal geochemical database.
void setSolventMassAndFreeMolalityAndMineralMolesAndSurfacePotsAndKineticMoles(const std::vector< std::string > &names, const std::vector< Real > &values, const std::vector< bool > &constraints_from_molalities)
Sets:
void setAlgebraicVariables(const DenseVector< Real > &algebraic_var)
Set the variables in the algebraic system (molalities and potentially the mass of solvent water...
std::vector< Real > eqm_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0) ...
std::vector< std::string > kin_species_name
kin_species_name[j] = name of the j^th kinetic species
Data structure to hold all relevant information from the database file.
std::vector< Real > _eqm_activity_coef
equilibrium activity coefficients
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< bool > eqm_species_mineral
eqm_species_mineral[i] = true iff the i^th equilibrium species is a mineral
void performSwapNoCheck(unsigned swap_out_of_basis, unsigned swap_into_basis)
Perform the basis swap, and ensure that the resulting system is consistent.
const std::vector< Real > & getSolventMassAndFreeMolalityAndMineralMoles() const
Real getSolventWaterMass() const
Returns the mass of solvent water.
DenseVector< Real > getTransportedBulkInOriginalBasis() const
void computeJacobian(const DenseVector< Real > &res, DenseMatrix< Real > &jac, const DenseVector< Real > &mole_additions, const DenseMatrix< Real > &dmole_additions) const
Compute the Jacobian for the algebraic system and put it in jac.
const std::vector< bool > & getInAlgebraicSystem() const
const GeochemistrySpeciesSwapper & getSwapper() const
void addToBulkMoles(unsigned basis_ind, Real value)
Add to the MOLES_BULK_SPECIES (or MOLES_BULK_WATER if basis_ind = 0) for the basis species...
const std::vector< bool > & getBasisActivityKnown() const
DenseVector< Real > getAlgebraicVariableDenseValues() const
void performSwap(unsigned swap_out_of_basis, unsigned swap_into_basis)
Perform the basis swap, and ensure that the resulting system is consistent.
void setConstraintValue(unsigned basis_ind, Real value)
Set the constraint value for the basis species.
unsigned getNumInEquilibrium() const
returns the number of species in equilibrium with the basis components
std::unordered_map< std::string, SurfaceComplexationInfo > surface_complexation_info
Holds info on surface complexation, if any, in the model.
const std::vector< std::string > _swap_out
Species to immediately remove from the basis in favor of _swap_in.
unsigned getNumBasisInAlgebraicSystem() const
return the number of basis species in the algebraic system
DenseMatrix sub_matrix(unsigned int row_id, unsigned int row_size, unsigned int col_id, unsigned int col_size) const
void closeSystem()
Changes a KG_SOLVENT_WATER constraint to MOLES_BULK_WATER (if there is such a constraint) and all FRE...
const std::vector< unsigned > & getBasisIndexOfAlgebraicSystem() const
MooseUnits pow(const MooseUnits &, int)
void setMineralRelatedFreeMoles(Real value)
Set the free mole number of mineral-related species to the value provided.
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species
static const std::string k
const std::vector< Real > & getEquilibriumMolality() const
for(PetscInt i=0;i< nvars;++i)
Real getSurfaceCharge(unsigned sp) const
std::vector< std::string > basis_species_name
basis_species_name[j] = name of the j^th basis species
const std::vector< GeochemicalSystem::ConstraintMeaningEnum > & getConstraintMeaning() const
const std::string & getOriginalRedoxLHS() const
virtual void buildActivityCoefficients(const ModelGeochemicalDatabase &mgd, std::vector< Real > &basis_activity_coef, std::vector< Real > &eqm_activity_coef) const =0
Compute the activity coefficients and store them in basis_activity_coef and eqm_activity_coef Note: ...
GeochemicalSystem(ModelGeochemicalDatabase &mgd, GeochemistryActivityCoefficients &gac, GeochemistryIonicStrength &is, GeochemistrySpeciesSwapper &swapper, const std::vector< std::string > &swap_out_of_basis, const std::vector< std::string > &swap_into_basis, const std::string &charge_balance_species, const std::vector< std::string > &constrained_species, const std::vector< Real > &constraint_value, const MultiMooseEnum &constraint_unit, const MultiMooseEnum &constraint_user_meaning, Real initial_temperature, unsigned iters_to_make_consistent, Real min_initial_molality, const std::vector< std::string > &kin_name, const std::vector< Real > &kin_initial_moles, const MultiMooseEnum &kin_unit)
Construct the geochemical system, check consistency of the constructor's arguments, and initialize all internal variables (molalities, bulk compositions, equilibrium constants, activities, activity coefficients, surface potentials and kinetic mole numbers) and set up the algebraic system
unsigned _num_basis_in_algebraic_system
number of unknown molalities in the algebraic system. Note: surface potentials (if any) are extra qua...
void computeRemainingBasisActivities(std::vector< Real > &basis_activity) const
Compute the activity of water and put in basis_activity[0], and use the _basis_activity_coef and _bas...
std::vector< Real > getSaturationIndices() const
std::vector< KineticRateDefinition > kin_rate
rates given to kinetic species.