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)
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;
std::vector< bool > surface_sorption_related
surface_sorption_related[j] = true iff the j^th equilibrium species is involved in surface sorption ...
GeochemistrySpeciesSwapper(unsigned basis_size, Real stoi_tol)
DenseMatrix< Real > redox_stoichiometry
redox_stoichiometry(i, j) = stoichiometric coefficients for i^th redox species that is in disequilibr...
std::vector< Real > eqm_species_molecular_weight
all quantities have a molecular weight (g)
std::string redox_lhs
the name of the species on the left-hand side of the redox equations.
std::vector< bool > basis_species_transported
basis_species_transported[j] = true iff the j^th basis species is transported in reactive-transport s...
DenseVector< Real > _swap_sigma
used in SVD decomposition of swap matrix
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...
DenseMatrix< Real > _swap_VT
used in SVD decomposition of swap matrix
DenseMatrix< Real > _inv_swap_matrix
inverse of swap matrix
void mooseError(Args &&... args)
virtual void zero() override final
std::vector< bool > eqm_species_gas
eqm_species_gas[i] = true iff the i^th equilibrium species is a gas
DenseMatrix< Real > _swap_U
used in SVD decomposition of swap matrix
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
DenseMatrix< Real > kin_stoichiometry
kin_stoichiometry(i, j) = stoichiometric coefficient for kinetic species "i" in terms of the basis sp...
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
DenseMatrix< Real > redox_log10K
redox_log10K(i, j) = log10(equilibrium constant) for i^th redox species at the j^th temperature point...
DenseMatrix< Real > swap_to_original_basis
Swap matrix that allows expression in terms of the original basis.
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...
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
void scale_column(const unsigned int col, const Real factor)
std::vector< Real > basis_species_radius
all quantities have an ionic radius (Angstrom) for computing activity (mineral radius = 0...
DenseMatrix< Real > _true_swap_matrix
Before _swap_matrix.svd (a non-const method) is called, we copy _true_swap_matrix = _swap_matrix...
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...
void svd(DenseVector< Real > &sigma)
Real _stoi_tol
tolerance for matrix inversion and stoichiometric coefficients
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< Real > eqm_species_radius
all quantities have an ionic radius (Angstrom) for computing activity (mineral radius = 0...
DenseMatrix< Real > eqm_log10K
eqm_log10K(i, j) = log10(equilibrium constant) for i^th equilibrium species at the j^th temperature p...
void right_multiply_transpose(const DenseMatrix< Real > &A)
std::vector< Real > basis_species_molecular_weight
all quantities have a molecular weight (g)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< bool > eqm_species_transported
eqm_species_transported[i] = true iff the i^th eqm species is transported in reactive-transport sims ...
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...
DenseMatrix< Real > _swap_matrix
swap matrix
std::vector< Real > eqm_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however) ...
virtual void right_multiply(const DenseMatrixBase< Real > &M2) override final
std::vector< Real > basis_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0) ...
std::vector< unsigned > have_swapped_into_basis
Species that have been swapped into the basis.
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_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0) ...
Data structure to hold all relevant information from the database file.
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
std::vector< Real > basis_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however) ...
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...
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species
std::vector< std::string > basis_species_name
basis_species_name[j] = name of the j^th basis species
virtual void left_multiply(const DenseMatrixBase< Real > &M2) override final
std::vector< unsigned > have_swapped_out_of_basis
Species that have been swapped out of the basis.
std::vector< KineticRateDefinition > kin_rate
rates given to kinetic species.
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...