13 : _stoi_tol(stoi_tol),
14 _swap_matrix(basis_size, basis_size),
15 _true_swap_matrix(basis_size, basis_size),
16 _inv_swap_matrix(basis_size, basis_size),
17 _swap_sigma(basis_size),
18 _swap_U(basis_size, basis_size),
19 _swap_VT(basis_size, basis_size)
25 const std::string & replace_this,
26 const std::string & with_this)
28 if (replace_this ==
"H2O")
29 mooseError(
"Cannot remove H2O from the basis");
31 mooseError(replace_this +
" is not in the basis, so cannot be removed from the basis");
33 mooseError(with_this +
" is not an equilibrium species, so cannot be "
34 "removed from the equilibrium species list");
41 unsigned basis_index_to_replace,
42 unsigned eqm_index_to_insert)
46 if (basis_index_to_replace == 0)
47 mooseError(
"Cannot remove H2O from the basis");
48 if (basis_index_to_replace >= num_cols)
49 mooseError(basis_index_to_replace,
" exceeds the number of basis species in the problem");
50 if (eqm_index_to_insert >= num_rows)
51 mooseError(eqm_index_to_insert,
" exceeds the number of equilibrium species in the problem");
54 "Equilibrium species ",
56 " is involved in surface sorption so cannot be swapped into the basis. If this is truly "
57 "necessary, code enhancements will need to be made including: recording whether basis "
58 "species are involved in surface sorption, including them in the surface-potential "
59 "calculations, and carefully swapping surface-potential-modified equilibrium constants");
66 unsigned basis_index_to_replace,
67 unsigned eqm_index_to_insert)
72 mooseError(
"GeochemistrySpeciesSwapper constructed with incorrect "
73 "basis_species size");
85 for (
unsigned i = 0; i < num_cols; ++i)
87 for (
unsigned i = 0; i < num_cols; ++i)
100 for (
unsigned i = 0; i < num_cols; ++i)
102 mooseException(
"Matrix is not invertible, which signals an invalid basis swap");
105 for (
unsigned i = 0; i < num_cols; ++i)
107 for (
unsigned i = 0; i < num_cols; ++i)
108 for (
unsigned j = 0; j < num_cols; ++j)
115 const std::string & replace_this,
116 const std::string & with_this)
128 unsigned basis_index_to_replace,
129 unsigned eqm_index_to_insert)
133 checkSwap(
mgd, basis_index_to_replace, eqm_index_to_insert);
136 alterMGD(
mgd, basis_index_to_replace, eqm_index_to_insert);
141 DenseVector<Real> & bulk_composition,
142 const std::string & replace_this,
143 const std::string & with_this)
152 DenseVector<Real> & bulk_composition,
153 unsigned basis_index_to_replace,
154 unsigned eqm_index_to_insert)
163 unsigned basis_index_to_replace,
164 unsigned eqm_index_to_insert)
172 const unsigned pro_ind_eqm =
173 num_cols + eqm_index_to_insert;
188 const bool redox_lhs_going_to_basis = (eqm_name ==
mgd.
redox_lhs);
190 !redox_lhs_going_to_basis,
191 "Should not be able to swap the redox LHS into the basis");
235 for (
unsigned i = 0; i < num_cols; ++i)
240 for (
unsigned i = 0; i < num_rows; ++i)
241 for (
unsigned j = 0; j < num_cols; ++j)
246 if (!redox_lhs_going_to_basis)
248 for (
unsigned red = 0; red < num_redox; ++red)
249 for (
unsigned j = 0; j < num_cols; ++j)
255 for (
unsigned i = 0; i < kin_rows; ++i)
256 for (
unsigned j = 0; j < num_cols; ++j)
261 for (
unsigned t = 0; t < num_temperatures; ++t)
263 const Real log10k_eqm_species =
mgd.
eqm_log10K(eqm_index_to_insert, t);
266 for (
unsigned row = 0; row < num_rows; ++row)
271 if (!redox_lhs_going_to_basis)
272 for (
unsigned red = 0; red < num_redox; ++red)
277 for (
unsigned kin = 0; kin < kin_rows; ++kin)
324 for (
unsigned r = 0; r < num_rate; ++r)
326 const Real promoting_index_of_original_basis =
327 mgd.
kin_rate[r].promoting_indices[basis_index_to_replace];
328 mgd.
kin_rate[r].promoting_indices[basis_index_to_replace] =
330 mgd.
kin_rate[r].promoting_indices[pro_ind_eqm] = promoting_index_of_original_basis;
331 const Real promoting_monod_index_of_original_basis =
332 mgd.
kin_rate[r].promoting_monod_indices[basis_index_to_replace];
333 mgd.
kin_rate[r].promoting_monod_indices[basis_index_to_replace] =
334 mgd.
kin_rate[r].promoting_monod_indices[pro_ind_eqm];
335 mgd.
kin_rate[r].promoting_monod_indices[pro_ind_eqm] = promoting_monod_index_of_original_basis;
336 const Real promoting_half_saturation_of_original_basis =
337 mgd.
kin_rate[r].promoting_half_saturation[basis_index_to_replace];
338 mgd.
kin_rate[r].promoting_half_saturation[basis_index_to_replace] =
339 mgd.
kin_rate[r].promoting_half_saturation[pro_ind_eqm];
340 mgd.
kin_rate[r].promoting_half_saturation[pro_ind_eqm] =
341 promoting_half_saturation_of_original_basis;
345 for (
unsigned r = 0; r < num_rate; ++r)
348 mgd.
kin_rate[r].progeny_index = basis_index_to_replace;
349 else if (
mgd.
kin_rate[r].progeny_index == basis_index_to_replace)
356 DenseVector<Real> & bulk_composition)
const
358 if (bulk_composition.size() != basis_size)
359 mooseError(
"GeochemistrySpeciesSwapper: bulk_composition has size ",
360 bulk_composition.size(),
361 " which differs from the basis size");
362 DenseVector<Real> result;
364 bulk_composition = result;
370 const std::vector<Real> & eqm_molality,
371 bool minerals_allowed,
373 bool sorption_allowed,
374 unsigned & best_eqm_species)
const
377 if (eqm_molality.size() != num_eqm)
380 " which is not equal to the number of equilibrium species ",
384 best_eqm_species = 0;
385 bool legitimate_swap_found =
false;
386 Real best_stoi = 0.0;
387 for (
unsigned j = 0; j < num_eqm; ++j)
398 if (stoi >= best_stoi)
401 best_eqm_species = j;
402 legitimate_swap_found =
true;
405 return legitimate_swap_found;
const ModelGeochemicalDatabase mgd
void mooseError(Args &&... args)
void alterMGD(ModelGeochemicalDatabase &mgd, unsigned basis_index_to_replace, unsigned eqm_index_to_insert)
Modify the ModelGeochemicalDatabase mgd to swap the indexed basis species and the indexed equilibrium...
void alterBulkComposition(unsigned basis_size, DenseVector< Real > &bulk_composition) const
Calculate the bulk composition in the new basis based on the bulk composition in the original basis.
void checkSwap(const 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.
DenseMatrix< Real > _swap_U
used in SVD decomposition of swap matrix
DenseMatrix< Real > _swap_matrix
swap matrix
DenseMatrix< Real > _swap_VT
used in SVD decomposition of swap matrix
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,...
Real _stoi_tol
tolerance for matrix inversion and stoichiometric coefficients
GeochemistrySpeciesSwapper(unsigned basis_size, Real stoi_tol)
bool findBestEqmSwap(unsigned basis_ind, const ModelGeochemicalDatabase &mgd, const std::vector< Real > &eqm_molality, bool minerals_allowed, bool gas_allowed, bool sorption_allowed, unsigned &best_eqm_species) const
For the the given basis index, find the equilibrium index that it should be swapped with.
DenseMatrix< Real > _true_swap_matrix
Before _swap_matrix.svd (a non-const method) is called, we copy _true_swap_matrix = _swap_matrix.
DenseVector< Real > _swap_sigma
used in SVD decomposition of swap matrix
DenseMatrix< Real > _inv_swap_matrix
inverse of swap matrix
void constructInverseMatrix(const ModelGeochemicalDatabase &mgd, unsigned basis_index_to_replace, unsigned eqm_index_to_insert)
Construct the swap matrix, and its inverse, that describes the swap between the indexed basis species...
void scale_column(const unsigned int col, const T factor)
void right_multiply_transpose(const DenseMatrix< T > &A)
void svd(DenseVector< Real > &sigma)
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
virtual void left_multiply(const DenseMatrixBase< T > &M2) override final
virtual void zero() override final
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
std::vector< Real > eqm_species_radius
all quantities have an ionic radius (Angstrom) for computing activity (mineral radius = 0,...
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_radius
all quantities have an ionic radius (Angstrom) for computing activity (mineral radius = 0,...
std::vector< Real > basis_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0)
std::vector< Real > eqm_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however)
std::string redox_lhs
the name of the species on the left-hand side of the redox equations.
std::vector< Real > eqm_species_molecular_weight
all quantities have a molecular weight (g)
std::vector< unsigned > have_swapped_into_basis
Species that have been swapped into the basis.
std::vector< bool > basis_species_transported
basis_species_transported[j] = true iff the j^th basis species is transported in reactive-transport s...
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< 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::vector< bool > surface_sorption_related
surface_sorption_related[j] = true iff the j^th equilibrium species is involved in surface sorption
std::vector< unsigned > have_swapped_out_of_basis
Species that have been swapped out of the basis.
std::vector< Real > basis_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however)
std::unordered_map< std::string, unsigned > eqm_species_index
eqm_species_index[name] = index of the equilibrium species (secondary aqueous species,...
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 ...
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::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< bool > eqm_species_transported
eqm_species_transported[i] = true iff the i^th eqm species is transported in reactive-transport sims