14 const std::vector<std::string> & basis_species,
15 const std::vector<std::string> & minerals,
16 const std::vector<std::string> & gases,
17 const std::vector<std::string> & kinetic_minerals,
18 const std::vector<std::string> & kinetic_redox,
19 const std::vector<std::string> & kinetic_surface_species,
20 const std::string & redox_ox,
21 const std::string & redox_e)
29 _kinetic_mineral_index(),
30 _kinetic_mineral_info(),
31 _kinetic_redox_index(),
32 _kinetic_redox_info(),
33 _kinetic_surface_index(),
34 _kinetic_surface_info(),
75 catch (
const std::out_of_range &)
85 std::vector<std::string>
90 names[name_ind.second] = name_ind.first;
98 for (
const auto &
name : basis_species)
100 if (ind == 0 and
name !=
"H2O")
101 mooseError(
"First member of basis species list must be H2O");
103 mooseError(
name,
" exists more than once in the basis species list");
119 mooseError(
name +
" does not exist in the basis species or redox species in " +
128 if (minerals.size() == 1 && minerals[0] ==
"*")
130 for (
const auto &
name : minerals)
144 for (
const auto &
name : gases)
159 for (
const auto &
name : kinetic_minerals)
162 mooseError(
name +
" exists more than once in the kinetic_minerals list");
164 mooseError(
name +
" exists in both the minerals and kinetic_minerals lists");
175 for (
const auto &
name : kinetic_redox)
178 mooseError(
name +
" exists more than once in the kinetic_redox list");
180 mooseError(
name +
" exists in both the basis_species and kinetic_redox lists");
189 const std::vector<std::string> & kinetic_surface_species)
192 for (
const auto &
name : kinetic_surface_species)
195 mooseError(
name +
" exists more than once in the kinetic_surface_species list");
216 bool all_species_in_basis_or_sec =
true;
220 all_species_in_basis_or_sec =
false;
223 if (all_species_in_basis_or_sec)
248 bool all_species_in_basis_or_sec =
true;
252 all_species_in_basis_or_sec =
false;
255 if (all_species_in_basis_or_sec)
272 bool all_species_in_basis_or_sec =
true;
276 all_species_in_basis_or_sec =
false;
279 if (all_species_in_basis_or_sec)
302 if (!(minerals.size() == 1 && minerals[0] ==
"*"))
309 bool known_basis_only =
true;
310 for (
const auto & basis_stoi : name_ms.second.basis_species)
315 known_basis_only =
false;
319 if (known_basis_only)
346 std::vector<Real> & redox_e_log10K)
350 redox_e_stoichiometry.assign(num_basis, 0.0);
351 redox_e_log10K.assign(numT, 0.0);
356 for (
unsigned i = 0; i < numT; ++i)
360 const Real stoi_coeff = react.second;
364 redox_e_stoichiometry[col] += react.second;
371 for (
unsigned i = 0; i < numT; ++i)
373 for (
unsigned col = 0; col < num_basis; ++col)
382 const std::vector<GeochemistryMineralSpecies> & mineral_info)
const 384 for (
const auto & mineral : mineral_info)
386 for (
const auto & element : mineral.basis_species)
388 mooseError(
"The reaction for " + mineral.name +
" depends on " + element.first +
389 " which is not reducable to a set of basis species");
390 for (
const auto & element : mineral.sorption_sites)
392 mooseError(
"The sorbing sites for " + mineral.name +
" include " + element.first +
393 " which is not in the basis_species list");
401 for (
const auto & element : gas.basis_species)
403 mooseError(
"The reaction for " + gas.name +
" depends on " + element.first +
404 " which is not reducable to a set of basis species");
411 for (
const auto & element : kr.basis_species)
413 mooseError(
"The reaction for " + kr.name +
" depends on " + element.first +
414 " which is not reducable to a set of basis species");
421 for (
const auto & element : kr.basis_species)
423 mooseError(
"The reaction for " + kr.name +
" depends on " + element.first +
424 " which is not reducable to a set of basis species");
467 species.molecular_weight;
480 es.
name = species.name;
484 overlap.push_back(es);
489 es.
name = species.name;
493 overlap.push_back(es);
498 for (
const auto & species : overlap)
528 std::vector<Real>(num_rows, 0.0);
534 std::vector<Real>(num_rows, 0.0);
540 for (
const auto & species : overlap)
542 species.molecular_weight;
548 species.molecular_volume;
552 if (species.surface_area != 0.0)
560 if (species.surface_area != 0.0)
577 for (
const auto & species : overlap)
580 for (
unsigned i = 0; i < num_temperatures; ++i)
582 for (
const auto & react : species.basis_species)
584 const Real stoi_coeff = react.second;
595 for (
unsigned i = 0; i < num_temperatures; ++i)
597 for (
unsigned col = 0; col < num_cols; ++col)
601 mooseError(
"Species " + species.name +
" includes " + react.first +
602 ", which cannot be expressed in terms of the basis. Previous checks must be " 610 std::vector<Real> redox_e_stoichiometry(num_cols, 0.0);
611 std::vector<Real> redox_e_log10K(num_temperatures, 0.0);
612 std::vector<Real> redox_stoi;
613 std::vector<Real> redox_log10K;
618 redox_stoi.insert(redox_stoi.end(), redox_e_stoichiometry.begin(), redox_e_stoichiometry.end());
619 redox_log10K.insert(redox_log10K.end(), redox_e_log10K.begin(), redox_e_log10K.end());
624 const Real beta = redox_e_stoichiometry[o2_index];
634 std::vector<Real> stoi(num_cols, 0.0);
635 bool only_involves_basis_species =
true;
642 only_involves_basis_species =
false;
646 if (!only_involves_basis_species)
652 stoi[bs.second] = -1.0;
659 for (
unsigned basis_i = 0; basis_i < num_cols; ++basis_i)
660 stoi[basis_i] *= -beta /
alpha;
662 for (
unsigned basis_i = 0; basis_i < num_cols; ++basis_i)
663 stoi[basis_i] += redox_e_stoichiometry[basis_i];
665 redox_stoi.insert(redox_stoi.end(), stoi.begin(), stoi.end());
668 for (
unsigned temp = 0; temp < num_temperatures; ++temp)
670 redox_e_log10K[temp]);
675 const unsigned num_redox = redox_stoi.size() / num_cols;
677 for (
unsigned red = 0; red < num_redox; ++red)
678 for (
unsigned basis_i = 0; basis_i < num_cols; ++basis_i)
681 for (
unsigned red = 0; red < num_redox; ++red)
682 for (
unsigned temp = 0; temp < num_temperatures; ++temp)
691 ms.
name = species.name;
696 overlap_kin.push_back(ms);
701 ms.
name = species.name;
707 ms.
equilibrium_const.push_back(species.log10K + species.dlog10KdT * (temp - T0));
708 overlap_kin.push_back(ms);
710 const unsigned num_kin = overlap_kin.size();
714 for (
const auto & species : overlap_kin)
745 for (
const auto & species : overlap_kin)
747 species.molecular_weight;
751 for (
const auto & species : overlap_kin)
753 species.molecular_volume;
760 for (
const auto & species : overlap_kin)
763 for (
unsigned i = 0; i < num_temperatures; ++i)
765 for (
const auto & react : species.basis_species)
767 const Real stoi_coeff = react.second;
778 for (
unsigned i = 0; i < num_temperatures; ++i)
780 for (
unsigned col = 0; col < num_cols; ++col)
784 mooseError(
"Kinetic species " + species.name +
" includes " + react.first +
785 ", which cannot be expressed in terms of the basis. Previous checks must be " 791 std::vector<std::string> all_sorbing_sites;
793 for (
const auto & name_frac : name_info.second.sorption_sites)
794 if (std::find(all_sorbing_sites.begin(), all_sorbing_sites.end(), name_frac.first) !=
795 all_sorbing_sites.end())
797 "The sorbing site ", name_frac.first,
" appears in more than one sorbing mineral");
799 all_sorbing_sites.push_back(name_frac.first);
804 for (
const auto & name_info :
807 for (
const auto & name_frac :
808 name_info.second.sorption_sites)
813 bool mineral_involved_in_eqm =
false;
814 for (
const auto & name_frac :
815 name_info.second.sorption_sites)
818 for (
unsigned j = 0;
j < num_rows; ++
j)
821 mineral_involved_in_eqm =
true;
825 if (!mineral_involved_in_eqm)
830 for (
const auto & name_frac :
831 name_info.second.sorption_sites)
834 for (
unsigned j = 0;
j < num_rows; ++
j)
838 mooseError(
"It is an error for any equilibrium species (such as ",
840 ") to have a reaction involving more than one sorbing site");
860 mooseError(
"Cannot prescribe a kinetic rate to species ",
862 " since it is not a kinetic species");
869 std::vector<Real> promoting_ind(num_basis + num_eqm, 0.0);
870 std::vector<Real> promoting_m_ind(num_basis + num_eqm, 0.0);
871 std::vector<Real> promoting_k(num_basis + num_eqm, 0.0);
872 for (
unsigned i = 0; i < num_pro; ++i)
882 "Promoting species ", promoting_species,
" must be a basis or a secondary species");
887 unsigned progeny_num = 0;
893 mooseError(
"Progeny ", description.
progeny,
" must be a basis or a secondary species");
std::vector< bool > surface_sorption_related
surface_sorption_related[j] = true iff the j^th equilibrium species is involved in surface sorption ...
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...
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::map< std::string, GeochemistrySurfaceSpecies > getSurfaceSpecies(const std::vector< std::string > &names)
Get the surface sorbing species information.
std::map< std::string, GeochemistryEquilibriumSpecies > getEquilibriumSpecies(const std::vector< std::string > &names)
Get the secondary equilibrium species information.
std::string redox_lhs
the name of the species on the left-hand side of the redox equations.
void buildGases(const std::vector< std::string > &gases)
using the gas list, this method builds _gas_index and _gas_info
std::vector< bool > kin_species_mineral
kin_species_mineral[j] = true iff the j^th kinetic species is a mineral
A single rate expression for the kinetic species with index kinetic_species_index.
std::vector< bool > basis_species_transported
basis_species_transported[j] = true iff the j^th basis species is transported in reactive-transport s...
Data structure for basis (primary) species.
unsigned getIndexOfOriginalBasisSpecies(const std::string &name) const
std::vector< Real > kin_species_charge
all kinetic quantities have a charge (mineral charge = 0)
std::vector< std::string > surface_sorption_name
surface_sorption_name[k] = name of the mineral involved in surface sorption.
std::map< std::string, Real > basis_species
void buildKineticMinerals(const std::vector< std::string > &kinetic_minerals)
using the kinetic_minerals list, this method builds _kinetic_mineral_index and _kinetic_mineral_info ...
void buildKineticRedox(const std::vector< std::string > &kinetic_redox)
using the kinetic_redox list, this method builds _kinetic_redox_index and _kinetic_redox_info ...
void mooseError(Args &&... args)
Data structure for mineral species.
std::vector< std::string > redoxCoupleNames() const
Returns a list of all the names of the "redox couples" in the database.
std::vector< bool > eqm_species_gas
eqm_species_gas[i] = true iff the i^th equilibrium species is a gas
std::map< std::string, GeochemistryMineralSpecies > getMineralSpecies(const std::vector< std::string > &names)
Get the mineral species information.
std::map< std::string, GeochemistryGasSpecies > getGasSpecies(const std::vector< std::string > &names)
Get the gas species information.
std::unordered_map< std::string, unsigned > _basis_index
given a species name, return its index in the corresponding "info" std::vector
std::vector< GeochemistryBasisSpecies > _basis_info
a vector of all relevant species
std::unordered_map< std::string, unsigned > basis_species_index
basis_species_index[name] = index of the basis species, within all ModelGeochemicalDatabase internal ...
std::unordered_map< std::string, unsigned > _mineral_index
given a species name, return its index in the corresponding "info" std::vector
void createModel()
Fully populate the ModelGeochemicalDatabase.
DenseMatrix< Real > kin_stoichiometry
kin_stoichiometry(i, j) = stoichiometric coefficient for kinetic species "i" in terms of the basis sp...
Data structure for redox species.
std::vector< Real > kin_species_molecular_weight
all quantities have a molecular weight (g/mol)
void buildAllMinerals(const std::vector< std::string > &minerals)
If minerals = {"*"} then populate _mineral_index and _mineral_info with all relevant minerals This is...
std::vector< Real > kin_species_molecular_volume
all quantities have a molecular volume (cm^3/mol) (only nonzero for minerals, however) ...
const FileName & filename() const
Filename of database.
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
void checkKineticSurfaceSpecies() const
Check that all kinetic surface species in the _kinetic_surface_species list have reactions that invol...
std::vector< Real > equilibrium_const
DenseMatrix< Real > redox_log10K
redox_log10K(i, j) = log10(equilibrium constant) for i^th redox species at the j^th temperature point...
std::vector< GeochemistryMineralSpecies > _mineral_info
a vector of all relevant species
Data structure for sorbing surface species.
std::vector< Real > equilibrium_const
std::vector< GeochemistrySurfaceSpecies > _kinetic_surface_info
a vector of all relevant species
std::vector< Real > promoting_half_saturation
std::map< std::string, Real > basis_species
ModelGeochemicalDatabase _model
The important datastructure built by this class.
std::unordered_map< std::string, unsigned > kin_species_index
kin_species_index[name] = index of the kinetic species, within all ModelGeochemicalDatabase internal ...
void checkGases() const
Check that all gases in the "gases" list have reactions that involve only the basis_species or second...
void buildBasis(const std::vector< std::string > &basis_species)
using the basis_species list, this method builds _basis_index and _basis_info
DenseMatrix< Real > eqm_stoichiometry
eqm_stoichiometry(i, j) = stoichiometric coefficient for equilibrium species "i" in terms of the basi...
std::vector< std::string > mineralSpeciesNames() const
Returns a list of all the names of the "mineral species" in the database.
const std::vector< Real > & getTemperatures() const
Get the temperature points that the equilibrium constant is defined at.
std::vector< std::string > surfaceSpeciesNames() const
Returns a list of all the names of the "surface species" in the database.
std::vector< Real > basis_species_radius
all quantities have an ionic radius (Angstrom) for computing activity (mineral radius = 0...
Data structure for mineral species.
const GeochemicalDatabaseReader db("database/moose_testdb.json", true, true, false)
void buildRedoxeInfo(std::vector< Real > &redox_e_stoichiometry, std::vector< Real > &redox_e_log10K)
Extract the stoichiometry and log10K for the _redox_e species.
PertinentGeochemicalSystem(const GeochemicalDatabaseReader &db, const std::vector< std::string > &basis_species, const std::vector< std::string > &minerals, const std::vector< std::string > &gases, const std::vector< std::string > &kinetic_minerals, const std::vector< std::string > &kinetic_redox, const std::vector< std::string > &kinetic_surface_species, const std::string &redox_ox, const std::string &redox_e)
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 ModelGeochemicalDatabase & modelGeochemicalDatabase() const
Return a reference to the ModelGeochemicalDatabase structure.
void checkKineticRedox() const
Check that all kinetic redox species in the _kinetic_redox list have reactions that involve only the ...
void addKineticRate(const KineticRateUserDescription &description)
Adds a rate description for kinetic_species.
std::unordered_map< std::string, unsigned > _kinetic_redox_index
given a species name, return its index in the corresponding "info" std::vector
void buildSecondarySpecies()
Extract all relevant "redox couples" and "secondary species" and "surface species" from the database...
std::map< std::string, Real > sorption_sites
std::map< std::string, GeochemistryBasisSpecies > getBasisSpecies(const std::vector< std::string > &names)
Get the basis (primary) species information.
std::unordered_map< std::string, unsigned > _secondary_index
given a species name, return its index in the corresponding "info" std::vector
std::unordered_map< std::string, unsigned > _kinetic_surface_index
given a species name, return its index in the corresponding "info" std::vector
std::vector< GeochemistryMineralSpecies > _kinetic_mineral_info
a vector of all relevant species
std::unordered_map< std::string, std::vector< Real > > gas_chi
Holds info on gas fugacity "chi" parameters.
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 > kin_species_transported
kin_species_transported[j] = true iff the j^th kinetic species is transported in reactive-transport s...
std::vector< Real > eqm_species_radius
all quantities have an ionic radius (Angstrom) for computing activity (mineral radius = 0...
void buildKineticSurface(const std::vector< std::string > &kinetic_surface)
using the kinetic_surface list, this method builds _kinetic_surface_index and _kinetic_surface_info ...
DenseMatrix< Real > eqm_log10K
eqm_log10K(i, j) = log10(equilibrium constant) for i^th equilibrium species at the j^th temperature p...
std::vector< GeochemistryRedoxSpecies > _kinetic_redox_info
a vector of all relevant species
void checkMinerals(const std::vector< GeochemistryMineralSpecies > &mineral_info) const
Check that all minerals in mineral_info have reactions that involve only the basis_species or seconda...
std::vector< Real > basis_species_molecular_weight
all quantities have a molecular weight (g)
std::map< std::string, Real > basis_species
std::vector< Real > equilibrium_const
std::vector< GeochemistryGasSpecies > _gas_info
a vector of all relevant species
Data structure designed to hold information related to sorption via surface complexation.
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 ...
static const std::string alpha
Data structure for secondary equilibrium species.
std::vector< std::string > secondarySpeciesNames() const
Returns a list of all the names of the "secondary species" and "free electron" in the database...
std::vector< Real > eqm_species_molecular_volume
all quantities have a molecular volume (cm^3) (only nonzero for minerals, however) ...
std::vector< std::string > originalBasisNames() const
std::vector< Real > basis_species_charge
all quantities have a charge (mineral charge = 0, gas charge = 0, oxide charge = 0) ...
Holds a user-specified description of a kinetic rate.
void resize(const unsigned int new_m, const unsigned int new_n)
GeochemicalDatabaseReader _db
The database.
std::vector< bool > basis_species_gas
basis_species_gas[j] = true iff the j^th basis species is a gas
std::map< std::string, Real > basis_species
std::vector< Real > promoting_indices
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) ...
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.
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) ...
std::vector< GeochemistryEquilibriumSpecies > _secondary_info
a vector of all relevant species
std::map< std::string, GeochemistryRedoxSpecies > getRedoxSpecies(const std::vector< std::string > &names)
Get the redox species (couples) information.
std::string kinetic_species_name
std::vector< Real > promoting_monod_indices
const std::string _redox_e
The name of the free electron involved in redox reactions.
std::unordered_map< std::string, unsigned > _gas_index
given a species name, return its index in the corresponding "info" std::vector
std::vector< std::string > promoting_species
const std::string _redox_ox
The name of the oxygen in all disequilibrium-redox equations, eg O2(aq), which must be a basis specie...
std::unordered_map< std::string, SurfaceComplexationInfo > surface_complexation_info
Holds info on surface complexation, if any, in the model.
std::unordered_map< std::string, unsigned > _kinetic_mineral_index
given a species name, return its index in the corresponding "info" std::vector
std::vector< std::string > eqm_species_name
eqm_species_name[i] = name of the i^th eqm species
for(PetscInt i=0;i< nvars;++i)
void buildMinerals(const std::vector< std::string > &minerals)
using the minerals list, this method builds _mineral_index and _mineral_info, unless minerals = {"*"}...
std::vector< std::string > basis_species_name
basis_species_name[j] = name of the j^th basis species
Class for reading geochemical reactions from a MOOSE geochemical database.
bool isRedoxSpecies(const std::string &name) const
std::vector< KineticRateDefinition > kin_rate
rates given to kinetic species.
bool isBasisSpecies(const std::string &name) const
Checks if species is of given type.