16 const std::vector<Real> & promoting_monod_indices,
17 const std::vector<Real> & promoting_half_saturation,
19 const std::vector<std::string> & basis_species_name,
20 const std::vector<bool> & basis_species_gas,
21 const std::vector<Real> & basis_molality,
22 const std::vector<Real> & basis_activity,
23 const std::vector<bool> & basis_activity_known,
24 const std::vector<std::string> & eqm_species_name,
25 const std::vector<bool> & eqm_species_gas,
26 const std::vector<Real> & eqm_molality,
27 const std::vector<Real> & eqm_activity,
30 Real kin_species_molecular_weight,
32 Real log10_activity_product,
38 std::vector<Real> & drate_dmol)
40 const unsigned num_basis = basis_species_name.size();
41 const unsigned num_eqm = eqm_species_name.size();
43 if (num_basis + num_eqm != promoting_indices.size())
44 mooseError(
"kinetic_rate: promoting_indices incorrectly sized ", promoting_indices.size());
45 if (num_basis + num_eqm != promoting_monod_indices.size())
46 mooseError(
"kinetic_rate: promoting_monod_indices incorrectly sized ",
47 promoting_monod_indices.size());
48 if (num_basis + num_eqm != promoting_half_saturation.size())
49 mooseError(
"kinetic_rate: promoting_half_saturation incorrectly sized ",
50 promoting_half_saturation.size());
51 if (!(num_basis == basis_species_gas.size() && num_basis == basis_molality.size() &&
52 num_basis == basis_activity.size() && num_basis == basis_activity_known.size() &&
53 num_basis == drate_dmol.size()))
54 mooseError(
"kinetic_rate: incorrectly sized basis-species vectors ",
57 basis_species_gas.size(),
59 basis_molality.size(),
61 basis_activity.size(),
63 basis_activity_known.size(),
66 if (!(num_eqm == eqm_species_gas.size() && num_eqm == eqm_molality.size() &&
67 num_eqm == eqm_activity.size()))
68 mooseError(
"kinetic_rate: incorrectly sized equilibrium-species vectors ",
71 eqm_species_gas.size(),
76 if (!(eqm_stoichiometry.
m() == num_eqm && eqm_stoichiometry.
n() == num_basis))
77 mooseError(
"kinetic_rate: incorrectly sized eqm stoichiometry matrix ",
78 eqm_stoichiometry.
m(),
80 eqm_stoichiometry.
n());
81 if (!(kin_stoichiometry.
m() > kin && kin_stoichiometry.
n() == num_basis))
82 mooseError(
"kinetic_rate: incorrectly sized kinetic stoichiometry matrix ",
83 kin_stoichiometry.
m(),
85 kin_stoichiometry.
n());
90 rate *= kin_moles * kin_species_molecular_weight;
92 const Real kin_molality = kin_moles / basis_molality[0];
93 const Real dkin_molality_dkin_moles = 1.0 / basis_molality[0];
94 const Real dkin_molality_dnw = -kin_molality / basis_molality[0];
104 for (
unsigned i = 0; i < num_basis; ++i)
106 if (promoting_indices[i] == 0.0)
108 if (basis_species_gas[i] || basis_species_name[i] ==
"H+" || basis_species_name[i] ==
"OH-")
109 rate *=
std::pow(basis_activity[i], promoting_indices[i]);
111 rate *=
std::pow(basis_molality[i], promoting_indices[i]);
113 for (
unsigned j = 0;
j < num_eqm; ++
j)
115 const unsigned index = num_basis +
j;
116 if (promoting_indices[index] == 0.0)
118 if (eqm_species_gas[
j] || eqm_species_name[
j] ==
"H+" || eqm_species_name[
j] ==
"OH-")
119 rate *=
std::pow(eqm_activity[
j], promoting_indices[index]);
121 rate *=
std::pow(eqm_molality[
j], promoting_indices[index]);
125 for (
unsigned i = 0; i < num_basis; ++i)
127 if (promoting_monod_indices[i] == 0.0)
129 if (basis_species_gas[i] || basis_species_name[i] ==
"H+" || basis_species_name[i] ==
"OH-")
131 std::pow(promoting_half_saturation[i], promoting_indices[i]),
132 promoting_monod_indices[i]);
135 std::pow(promoting_half_saturation[i], promoting_indices[i]),
136 promoting_monod_indices[i]);
138 for (
unsigned j = 0;
j < num_eqm; ++
j)
140 const unsigned index = num_basis +
j;
141 if (promoting_monod_indices[index] == 0.0)
143 if (eqm_species_gas[
j] || eqm_species_name[
j] ==
"H+" || eqm_species_name[
j] ==
"OH-")
145 std::pow(promoting_half_saturation[index], promoting_indices[index]),
146 promoting_monod_indices[index]);
149 std::pow(promoting_half_saturation[index], promoting_indices[index]),
150 promoting_monod_indices[index]);
163 const Real ap_over_k =
std::pow(10.0, log10_activity_product - log10K_bio);
189 rate *= (description.
eta == 0.0)
191 : ((theta_term == 1.0) ? 0.0 :
std::pow(std::abs(1.0 - theta_term), description.
eta));
193 for (
unsigned i = 0; i < num_basis; ++i)
199 drate_dkin += rate / kin_moles;
204 drate_dkin += d_by_dkin_molality * dkin_molality_dkin_moles;
205 drate_dmol[0] += d_by_dkin_molality * dkin_molality_dnw;
209 const Real d_by_dkin_molality =
214 drate_dkin += d_by_dkin_molality * dkin_molality_dkin_moles;
215 drate_dmol[0] += d_by_dkin_molality * dkin_molality_dnw;
223 for (
unsigned i = 0; i < num_basis; ++i)
225 if (promoting_indices[i] == 0.0)
227 else if (basis_species_gas[i])
230 drate_dmol[i] += promoting_indices[i] * rate / basis_molality[i];
232 for (
unsigned j = 0;
j < num_eqm; ++
j)
235 const unsigned index = num_basis +
j;
236 if (promoting_indices[index] == 0.0)
238 for (
unsigned i = 1; i < num_basis; ++i)
239 if (!(basis_species_gas[i] || eqm_stoichiometry(
j, i) == 0.0))
241 promoting_indices[index] * rate * eqm_stoichiometry(
j, i) / basis_molality[i];
249 for (
unsigned i = 0; i < num_basis; ++i)
251 if (promoting_indices[i] == 0.0 || promoting_monod_indices[i] == 0.0)
253 else if (basis_species_gas[i])
255 else if (basis_species_name[i] ==
"H+" || basis_species_name[i] ==
"OH-")
256 drate_dmol[i] -= promoting_monod_indices[i] * promoting_indices[i] *
257 std::pow(basis_activity[i], promoting_indices[i]) * rate /
259 (
std::pow(basis_activity[i], promoting_indices[i]) +
260 std::pow(promoting_half_saturation[i], promoting_indices[i]));
262 drate_dmol[i] -= promoting_monod_indices[i] * promoting_indices[i] *
263 std::pow(basis_molality[i], promoting_indices[i] - 1) * rate /
264 (
std::pow(basis_molality[i], promoting_indices[i]) +
265 std::pow(promoting_half_saturation[i], promoting_indices[i]));
267 for (
unsigned j = 0;
j < num_eqm; ++
j)
269 const unsigned index = num_basis +
j;
270 if (promoting_indices[index] == 0.0 || promoting_monod_indices[index] == 0.0)
272 for (
unsigned i = 1; i < num_basis; ++i)
274 if (basis_species_gas[i] || eqm_stoichiometry(
j, i) == 0.0)
276 else if (eqm_species_gas[
j] || eqm_species_name[
j] ==
"H+" || eqm_species_name[
j] ==
"OH-")
277 drate_dmol[i] -= promoting_monod_indices[index] * promoting_indices[index] *
278 std::pow(eqm_activity[
j], promoting_indices[index]) * rate *
279 eqm_stoichiometry(
j, i) /
280 (
std::pow(eqm_activity[
j], promoting_indices[index]) +
281 std::pow(promoting_half_saturation[index], promoting_indices[index])) /
284 drate_dmol[i] -= promoting_monod_indices[index] * promoting_indices[index] *
285 std::pow(eqm_molality[
j], promoting_indices[index]) * rate *
286 eqm_stoichiometry(
j, i) /
287 (
std::pow(eqm_molality[
j], promoting_indices[index]) +
288 std::pow(promoting_half_saturation[index], promoting_indices[index])) /
293 Real deriv_ap_term = 0.0;
294 if (theta_term != 1.0)
296 description.
eta * rate / std::abs(1 - theta_term) * (-description.
theta) * theta_term;
299 if (description.
eta > 1)
301 else if (description.
eta == 1.0)
303 else if (description.
eta == 0.0)
306 deriv_ap_term = std::numeric_limits<Real>::max();
308 if (theta_term > 1.0)
309 deriv_ap_term = -deriv_ap_term;
310 for (
unsigned i = 1; i < num_basis; ++i)
311 if (!(basis_species_gas[i] || kin_stoichiometry(kin, i) == 0.0 || deriv_ap_term == 0.0))
312 drate_dmol[i] += deriv_ap_term * kin_stoichiometry(kin, i) / basis_molality[i];
constexpr Real CELSIUS_TO_KELVIN
void mooseError(Args &&... args)
Real kinetic_half_saturation
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.
DirectionChoiceEnum direction
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
constexpr Real GAS_CONSTANT
Holds a user-specified description of a kinetic rate.
Real intrinsic_rate_constant
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
Provides a parametric description of a general kinetic rate.
MooseUnits pow(const MooseUnits &, int)