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)
80 for (
unsigned i = 0; i < constraint_unit.
size(); ++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)
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 ",
557const 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;
664const std::vector<bool> &
670const std::vector<unsigned> &
676const std::vector<unsigned> &
690 for (
unsigned k = 0; k <
_num_kin; ++k)
712 for (
unsigned k = 0; k <
_num_kin; ++k)
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;
802const std::vector<Real> &
821 std::vector<Real> trans_bulk;
823 DenseVector<Real> result(trans_bulk);
830const 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;
863const std::vector<bool> &
873 mooseError(
"Cannot retrieve basis activity for species ",
875 " since there are only ",
881const std::vector<Real> &
891 mooseError(
"Cannot retrieve molality for equilibrium species ",
893 " since there are only ",
895 " equilibrium species");
899const 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);
932const 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");
961const std::vector<Real> &
971 mooseError(
"Cannot retrieve basis activity coefficient for species ",
973 " since there are only ",
979const 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 ",
1098 for (
unsigned k = 0; k <
_num_kin; ++k)
1116 bulk_moles_old[i] = value;
1143 for (
unsigned j = 0; j <
_num_eqm; ++j)
1146 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1158 transported_bulk[i] = 0.0;
1169 transported_bulk[i] = 0.0;
1170 for (
unsigned j = 0; j <
_num_eqm; ++j)
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 <
1274 for (
unsigned j = 0; j <
_num_eqm; ++j)
1288 DenseMatrix<Real> & jac,
1289 const DenseVector<Real> & mole_additions,
1290 const DenseMatrix<Real> & dmole_additions)
const
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)
1363 Real numerator = res(
a) +
_bulk_moles_old[basis_of_a] + mole_additions(basis_of_a);
1364 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1366 jac(
a, 0) += numerator / nw;
1382 for (
unsigned j = 0; j <
_num_eqm; ++j)
1389 for (
unsigned j = 0; j <
_num_eqm; ++j)
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)
1524 for (
unsigned j = 0; j <
_num_eqm; ++j)
1530 for (
unsigned j = 0; j <
_num_eqm; ++j)
1542 for (
unsigned j = 0; j <
_num_eqm; ++j)
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);
1589 for (
unsigned j = 0; j <
_num_eqm; ++j)
1591 for (
unsigned kin = 0; kin <
_num_kin; ++kin)
1601 for (
unsigned j = 0; j <
_num_eqm; ++j)
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;
1857const 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)
1922 ": it must be zero");
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)
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");
2093const 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;
2125 for (
unsigned j = 0; j <
_num_eqm; ++j)
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)
2303 for (
unsigned j = 0; j <
_num_eqm; ++j)
2313 for (
unsigned k = 0; k <
_num_kin; ++k)
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)
2335 return std::pow(10.0, log10f);
2341const std::vector<Real> &
2344 for (
unsigned j = 0; j <
_num_eqm; ++j)
2353 mooseError(
"The increment in mole numbers (mole_additions) needs to be of size ",
2357 " but it is of size ",
2358 mole_additions.size());
2361 for (
unsigned k = 0; k <
_num_kin; ++k)
2384 DenseVector<Real> & mole_additions,
2385 DenseMatrix<Real> & dmole_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());
2401 for (
unsigned j = 0; j <
_num_eqm; ++j)
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) +=
const ModelGeochemicalDatabase mgd
void mooseError(Args &&... args)
std::array< Real, 2 > values
Fit the equilibrium constant values read from the thermodynamic databse at specified temperature valu...
virtual Real sample(Real T) override
const std::vector< Real > & getTemperatures() const
Get the temperature points that the equilibrium constant is defined at.
std::string getLogKModel() const
Get the equilibrium constant model type.
Real log10KineticActivityProduct(unsigned kin) const
Real computeBulkFromMolalities(unsigned basis_ind) const
std::vector< Real > getSaturationIndices() const
Real getResidualComponent(unsigned algebraic_ind, const DenseVector< Real > &mole_additions) const
Return the residual of the algebraic system for the given algebraic index.
std::string _original_redox_lhs
The left-hand-side of the redox equations in _mgd after initial swaps.
std::vector< Real > getAlgebraicBasisValues() const
Real getEquilibriumActivity(unsigned eqm_ind) const
Returns the value of activity for the equilibrium species with index eqm_index.
std::vector< Real > _eqm_activity_coef
equilibrium activity coefficients
const std::vector< unsigned > & getAlgebraicIndexOfBasisSystem() const
const std::vector< GeochemicalSystem::ConstraintMeaningEnum > & getConstraintMeaning() const
std::vector< Real > _bulk_moles_old
Number of bulk moles of basis species (this includes contributions from kinetic species,...
void enforceChargeBalance()
Enforces charge balance by altering the constraint_value and bulk_moles_old of the charge-balance spe...
std::vector< Real > _sorbing_surface_area
surface areas of the sorbing minerals
Real _temperature
The temperature in degC.
void setAlgebraicVariables(const DenseVector< Real > &algebraic_var)
Set the variables in the algebraic system (molalities and potentially the mass of solvent water,...
Real surfacePotPrefactor(unsigned sp) const
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
std::vector< unsigned > _algebraic_index
_algebraic_index[i] = index in the algebraic system of the basis species i. _basis_index[_algebraic_i...
unsigned getNumKinetic() const
returns the number of kinetic species
std::vector< Real > _constraint_value
Numerical values of the constraints on _constraint_species. In the constructor, this is ordered to ha...
DenseVector< Real > getAlgebraicVariableDenseValues() const
Real getLog10K(unsigned j) 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,...
const GeochemistrySpeciesSwapper & getSwapper() const
const unsigned _num_kin
number of kinetic species
const unsigned _num_surface_pot
number of surface potentials
void computeEqmMolalities(std::vector< Real > &eqm_molality) const
compute the equilibrium molalities (not for minerals or gases)
void setChargeBalanceSpecies(unsigned new_charge_balance_index)
Set the charge-balance species to the basis index provided.
std::vector< bool > _in_algebraic_system
if _in_algebraic_system[i] == true then we need to solve for the i^th basis-species molality
unsigned _iters_to_make_consistent
Iterations to make the initial configuration consistent.
unsigned _num_basis_in_algebraic_system
number of unknown molalities in the algebraic system. Note: surface potentials (if any) are extra qua...
bool revertToOriginalChargeBalanceSpecies()
Changes the charge-balance species to the original that is specified in the constructor (this might n...
GeochemistryActivityCoefficients & _gac
Object to compute the activity coefficients and activity of water.
Real log10ActivityProduct(unsigned eqm_j) const
const std::vector< Real > & getSorbingSurfaceArea() const
const std::string & getOriginalRedoxLHS() const
void setMineralRelatedFreeMoles(Real value)
Set the free mole number of mineral-related species to the value provided.
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...
std::vector< ConstraintMeaningEnum > _constraint_meaning
The meaning of the values in _constraint_value. In the constructor, this is ordered to have the same ...
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,...
Real log10RedoxActivityProduct(unsigned red) const
Real getRedoxLog10K(unsigned red) const
const unsigned _num_redox
number of redox species
void setKineticMoles(unsigned kin, Real moles)
Sets the current AND old mole number for a kinetic species.
void computeSorbingSurfaceArea(std::vector< Real > &sorbing_surface_area) const
Compute sorbing_surface_area depending on the current molality of the sorbing minerals.
void alterSystemBecauseBulkChanged()
Alter the GeochemicalSystem to reflect changes in bulk composition constraints that occur through,...
void computeConsistentConfiguration()
Compute a reasonably consistent configuration that can be used as an initial condition in a Newton pr...
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 > & getEquilibriumMolality() const
const std::vector< Real > & getBasisActivityCoefficient() const
const std::vector< Real > & computeAndGetEquilibriumActivity()
Computes activity for all equilibrium species (_eqm_activity) and returns a reference to the vector.
std::vector< Real > _eqm_log10K
equilibrium constant of the equilibrium species
Real _min_initial_molality
Minimum molality ever used in an initial guess.
const unsigned _num_eqm
number of equilibrium species
unsigned _num_in_algebraic_system
number of unknowns in the algebraic system (includes molalities and surface potentials)
void changeConstraintToBulk(unsigned basis_ind)
Changes the constraint to MOLES_BULK_SPECIES (or MOLES_BULK_WATER if basis_ind = 0) for the basis ind...
std::vector< Real > _original_constraint_value
Numerical values of the constraints on _constraint_species. In the constructor, this is ordered to ha...
Real getSurfacePotential(unsigned sp) const
std::vector< Real > _surface_pot_expr
surface potential expressions.
void performSwap(unsigned swap_out_of_basis, unsigned swap_into_basis)
Perform the basis swap, and ensure that the resulting system is consistent.
unsigned getNumSurfacePotentials() const
return the number of surface potentials
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,...
unsigned getNumInBasis() const
returns the number of species in the basis
void computeTransportedBulkFromMolalities(std::vector< Real > &transported_bulk) const
Computes the value of transported bulk moles for all basis species using the existing molalities.
void buildTemperatureDependentQuantities(Real temperature)
Using the provided value of temperature, build _eqm_log10K for each eqm species and redox 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...
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...
unsigned getNumInEquilibrium() const
returns the number of species in equilibrium with the basis components
const std::vector< bool > & getBasisActivityKnown() const
unsigned getChargeBalanceBasisIndex() const
return the index of the charge-balance species in the basis list
Real getTotalChargeOld() const
std::vector< GeochemistryUnitConverter::GeochemistryUnit > _constraint_unit
Units of the _constraint_value when the GeochemicalSystem is constructed. This is used during the con...
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...
void setSolventMassAndFreeMolalityAndMineralMolesAndSurfacePotsAndKineticMoles(const std::vector< std::string > &names, const std::vector< Real > &values, const std::vector< bool > &constraints_from_molalities)
Sets:
const std::string _original_charge_balance_species
The species used to enforce charge balance, as provided in the constructor.
GeochemistryIonicStrength & _is
Object that provides the ionic strengths.
const std::vector< bool > & getInAlgebraicSystem() const
DenseVector< Real > getTransportedBulkInOriginalBasis() const
const std::vector< Real > & getEquilibriumActivityCoefficient() const
Real getSolventWaterMass() const
Returns the mass of solvent water.
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...
GeochemistrySpeciesSwapper & _swapper
swapper that can swap species into and out of the basis
const std::vector< Real > & getKineticLog10K() const
unsigned getNumRedox() const
const std::vector< unsigned > & getBasisIndexOfAlgebraicSystem() const
std::vector< Real > _eqm_molality
molality of equilibrium species
Real getStoichiometricIonicStrength() const
Get the stoichiometric ionic strength.
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.
void setConstraintValue(unsigned basis_ind, Real value)
Set the constraint value for the basis species.
ConstraintUserMeaningEnum
Each basis species must be provided with a constraint, that is chosen by the user from the following ...
@ BULK_COMPOSITION_WITH_KINETIC
const std::vector< Real > & getBulkMolesOld() const
bool alterChargeBalanceSpecies(Real threshold_molality)
If the molality of the charge-balance basis species is less than threshold molality,...
std::vector< Real > _basis_molality
IMPORTANT: this is.
const ModelGeochemicalDatabase & getModelGeochemicalDatabase() const
const std::vector< std::string > _swap_in
Species to immediately add to the basis in favor of _swap_out.
std::vector< bool > _basis_activity_known
whether basis_activity[i] is fixed by the user
Real getIonicStrength() const
Get the ionic strength.
std::string _charge_balance_species
The species used to enforce charge balance.
const std::vector< Real > & getSolventMassAndFreeMolalityAndMineralMoles() const
void updateBasisMolalityForKnownActivity(std::vector< Real > &basis_molality) const
For basis aqueous species (not water, minerals or gases) with activity set by the user,...
unsigned getNumInAlgebraicSystem() const
std::vector< unsigned > _basis_index
_basis_index[i] = index in the basis of the algebraic system species i, for i<num_basis_in_algebraic_...
void performSwapNoCheck(unsigned swap_out_of_basis, unsigned swap_into_basis)
Perform the basis swap, and ensure that the resulting system is consistent.
void initialize()
initialize all variables, ready for a Newton solve of the algebraic system
std::vector< Real > _redox_log10K
equilibrium constant of the redox species
std::vector< Real > getAlgebraicVariableValues() const
std::vector< Real > _kin_log10K
equilibrium constant of the kinetic species
DenseVector< Real > getBulkOldInOriginalBasis() const
Real getSurfaceCharge(unsigned sp) 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.
std::vector< Real > _eqm_activity
equilibrium activities.
const unsigned _num_basis
number of basis species
unsigned _charge_balance_basis_index
The index in the list of basis species corresponding to the charge-balance species....
const std::vector< Real > & getKineticMoles() const
const std::vector< Real > & getBasisActivity() const
std::vector< Real > _basis_activity_coef
basis activity coefficients
void computeFreeMineralMoles(std::vector< Real > &basis_molality) const
Compute the free mineral moles (ie, basis_molality for basis species that are minerals),...
std::vector< Real > _kin_moles
mole number of kinetic species
void computeBulk(std::vector< Real > &bulk_moles_old) const
Computes the value of bulk_moles_old for all basis species.
ModelGeochemicalDatabase & _mgd
The minimal geochemical database.
ConstraintMeaningEnum
Each basis species has one of the following constraints.
@ FREE_MOLES_MINERAL_SPECIES
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...
void closeSystem()
Changes a KG_SOLVENT_WATER constraint to MOLES_BULK_WATER (if there is such a constraint) and all FRE...
Real surfaceSorptionModifier(unsigned eqm_j) const
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,...
std::vector< Real > _kin_moles_old
old mole number of kinetic species
void setTemperature(Real temperature)
Sets the temperature to the given quantity.
void setModelGeochemicalDatabase(const ModelGeochemicalDatabase &mgd)
Copies a ModelGeochemicalDatabase into our _mgd structure.
Real getTemperature() const
std::vector< Real > _basis_activity
values of activity (for water, minerals and aqueous basis species) or fugacity (for gases)
Base class to compute activity coefficients for non-minerals and non-gases (since these species do no...
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 ...
virtual Real waterActivity() const =0
Computes and returns the activity of water.
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:
Calculators to compute ionic strength and stoichiometric ionic strength.
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 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.
Class to swap basis species with equilibrium species.
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,...
virtual const char * what() const
unsigned int get(unsigned int i) const
unsigned int size() const
std::vector< T > & get_values()
DenseMatrix sub_matrix(unsigned int row_id, unsigned int row_size, unsigned int col_id, unsigned int col_size) const
void resize(const unsigned int new_m, const unsigned int new_n)
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
constexpr Real GAS_CONSTANT
constexpr Real DIELECTRIC_CONSTANT_WATER
constexpr Real CELSIUS_TO_KELVIN
constexpr Real MOLES_PER_KG_WATER
constexpr Real PERMITTIVITY_FREE_SPACE
constexpr Real DENSITY_WATER
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.
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,...
Data structure to hold all relevant information from the database file.
std::vector< bool > eqm_species_mineral
eqm_species_mineral[i] = true iff the i^th equilibrium species is a mineral
DenseMatrix< Real > eqm_stoichiometry
eqm_stoichiometry(i, j) = stoichiometric coefficient for equilibrium species "i" in terms of the basi...
std::vector< Real > basis_species_molecular_weight
all quantities have a molecular weight (g)
DenseMatrix< Real > kin_stoichiometry
kin_stoichiometry(i, j) = stoichiometric coefficient for kinetic species "i" in terms of the basis sp...
std::vector< Real > basis_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0)
std::string redox_lhs
the name of the species on the left-hand side of the redox equations.
std::vector< bool > kin_species_mineral
kin_species_mineral[j] = true iff the j^th kinetic species is a mineral
std::vector< unsigned > surface_sorption_number
surface_sorption_number[j] = the index of the surface potential that should be used to modify the equ...
std::vector< bool > basis_species_transported
basis_species_transported[j] = true iff the j^th basis species is transported in reactive-transport s...
std::vector< std::string > kin_species_name
kin_species_name[j] = name of the j^th kinetic species
DenseMatrix< Real > redox_stoichiometry
redox_stoichiometry(i, j) = stoichiometric coefficients for i^th redox species that is in disequilibr...
DenseMatrix< Real > swap_to_original_basis
Swap matrix that allows expression in terms of the original basis.
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< bool > basis_species_mineral
basis_species_mineral[j] = true iff the j^th basis species is a mineral
std::vector< KineticRateDefinition > kin_rate
rates given to kinetic species.
DenseMatrix< Real > redox_log10K
redox_log10K(i, j) = log10(equilibrium constant) for i^th redox species at the j^th temperature point
DenseMatrix< Real > kin_log10K
kin_log10K(i, j) = log10(equilibrium constant for the i^th kinetic species at the j^th temperature po...
std::unordered_map< std::string, SurfaceComplexationInfo > surface_complexation_info
Holds info on surface complexation, if any, in the model.
std::vector< bool > surface_sorption_related
surface_sorption_related[j] = true iff the j^th equilibrium species is involved in surface sorption
std::unordered_map< std::string, unsigned > eqm_species_index
eqm_species_index[name] = index of the equilibrium species (secondary aqueous species,...
const GeochemicalDatabaseReader * original_database
a pointer to the original database used to build this ModelGeochemicalDatabase
std::vector< std::string > basis_species_name
basis_species_name[j] = name of the j^th basis species
std::unordered_map< std::string, unsigned > basis_species_index
basis_species_index[name] = index of the basis species, within all ModelGeochemicalDatabase internal ...
std::vector< std::string > surface_sorption_name
surface_sorption_name[k] = name of the mineral involved in surface sorption.
DenseMatrix< Real > eqm_log10K
eqm_log10K(i, j) = log10(equilibrium constant) for i^th equilibrium species at the j^th temperature p...
std::vector< bool > basis_species_gas
basis_species_gas[j] = true iff the j^th basis species is a gas
std::unordered_map< std::string, unsigned > kin_species_index
kin_species_index[name] = index of the kinetic species, within all ModelGeochemicalDatabase internal ...
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species
std::vector< Real > eqm_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0)
std::vector< bool > eqm_species_gas
eqm_species_gas[i] = true iff the i^th equilibrium species is a gas
std::vector< Real > kin_species_molecular_weight
all quantities have a molecular weight (g/mol)
std::vector< bool > eqm_species_transported
eqm_species_transported[i] = true iff the i^th eqm species is transported in reactive-transport sims