19 const FileName filename,
20 const bool reexpress_free_electron,
21 const bool use_piecewise_interpolation,
22 const bool remove_all_extrapolated_secondary_species)
28 if (reexpress_free_electron)
31 if (use_piecewise_interpolation &&
_root[
"Header"].contains(
"logk model"))
32 _root[
"Header"][
"logk model"] =
"piecewise-linear";
34 if (remove_all_extrapolated_secondary_species)
64 if (!
_root.contains(
"free electron") || !
_root[
"free electron"].contains(
"e-") ||
65 !
_root[
"free electron"][
"e-"][
"species"].contains(
"O2(g)"))
67 if (!
_root.contains(
"basis species") || !
_root[
"basis species"].contains(
"O2(aq)"))
69 if (!
_root.contains(
"gas species") || !
_root[
"gas species"].contains(
"O2(g)") ||
70 !
_root[
"gas species"][
"O2(g)"][
"species"].contains(
"O2(aq)") ||
71 (
_root[
"gas species"][
"O2(g)"][
"species"].size() != 1))
75 const std::string stoi_o2g =
76 nlohmann::to_string(
_root[
"free electron"][
"e-"][
"species"][
"O2(g)"]);
77 _root[
"free electron"][
"e-"][
"species"].erase(
"O2(g)");
78 _root[
"free electron"][
"e-"][
"species"][
"O2(aq)"] = stoi_o2g;
82 if (!
_root[
"Header"].contains(
"temperatures"))
84 for (
unsigned i = 0; i <
_root[
"Header"][
"temperatures"].size(); ++i)
88 const Real newk = logk_e + stoi * logk_o2;
89 _root[
"free electron"][
"e-"][
"logk"][i] = std::to_string(newk);
96 if (
_root.contains(
"secondary species"))
98 std::set<std::string>
remove;
99 for (
const auto & item :
_root[
"secondary species"].items())
100 if (item.value().contains(
"note"))
101 remove.insert(item.key());
103 for (
const auto &
name :
remove)
111 return _root[
"Header"][
"activity model"];
117 return _root[
"Header"][
"fugacity model"];
123 return _root[
"Header"][
"logk model"];
129 if (
_root[
"Header"].contains(
"temperatures"))
131 auto temperatures =
_root[
"Header"][
"temperatures"];
133 for (
unsigned int i = 0; i < temperatures.size(); ++i)
138 const std::vector<Real> &
148 if (
_root[
"Header"].contains(
"pressures"))
150 auto pressures =
_root[
"Header"][
"pressures"];
152 for (
unsigned int i = 0; i < pressures.size(); ++i)
164 if (
_root[
"Header"].contains(
"adh"))
166 std::vector<Real> adhvals(
_root[
"Header"][
"adh"].size());
167 for (
unsigned int i = 0; i <
_root[
"Header"][
"adh"].size(); ++i)
172 if (
_root[
"Header"].contains(
"bdh"))
174 std::vector<Real> bdhvals(
_root[
"Header"][
"bdh"].size());
175 for (
unsigned int i = 0; i <
_root[
"Header"][
"bdh"].size(); ++i)
180 if (
_root[
"Header"].contains(
"bdot"))
182 std::vector<Real> bdotvals(
_root[
"Header"][
"bdot"].size());
183 for (
unsigned int i = 0; i <
_root[
"Header"][
"bdot"].size(); ++i)
194 mooseError(
"Attempted to get Debye-Huckel activity parameters but the activity model is ",
199 std::map<std::string, GeochemistryElements>
202 if (
_root.contains(
"elements"))
204 for (
auto & el :
_root[
"elements"].items())
206 _elements[el.key()].name = el.value()[
"name"];
207 _elements[el.key()].molecular_weight =
getReal(el.value()[
"molecular weight"]);
214 std::map<std::string, GeochemistryBasisSpecies>
218 for (
const auto & species : names)
219 if (
_root[
"basis species"].contains(species))
223 auto basis_species =
_root[
"basis species"][species];
229 std::map<std::string, Real> elements;
230 for (
auto & el : basis_species[
"elements"].items())
231 elements[el.key()] =
getReal(el.value());
243 std::map<std::string, GeochemistryEquilibriumSpecies>
247 for (
const auto & species : names)
248 if (
_root[
"secondary species"].contains(species) or
_root[
"free electron"].contains(species))
252 auto sec_species =
_root[
"secondary species"].contains(species)
253 ?
_root[
"secondary species"][species]
254 :
_root[
"free electron"][species];
260 std::vector<Real> eq_const(sec_species[
"logk"].size());
261 for (
unsigned int i = 0; i < sec_species[
"logk"].size(); ++i)
262 eq_const[i] =
getReal(sec_species[
"logk"][i]);
266 std::map<std::string, Real> basis_species;
267 for (
auto & bs : sec_species[
"species"].items())
268 basis_species[bs.key()] =
getReal(bs.value());
280 std::map<std::string, GeochemistryMineralSpecies>
284 for (
const auto & species : names)
285 if (
_root[
"mineral species"].contains(species))
289 auto mineral_species =
_root[
"mineral species"][species];
294 std::vector<Real> eq_const(mineral_species[
"logk"].size());
295 for (
unsigned int i = 0; i < mineral_species[
"logk"].size(); ++i)
296 eq_const[i] =
getReal(mineral_species[
"logk"][i]);
300 std::map<std::string, Real> basis_species;
301 for (
auto & bs : mineral_species[
"species"].items())
302 basis_species[bs.key()] =
getReal(bs.value());
307 std::map<std::string, Real> species_and_sorbing_density;
309 if (
_root[
"sorbing minerals"].contains(species))
311 auto sorbing_mineral =
_root[
"sorbing minerals"][species];
314 for (
auto & site : sorbing_mineral[
"sorbing sites"].items())
315 species_and_sorbing_density[site.key()] =
getReal(site.value());
327 std::map<std::string, GeochemistryGasSpecies>
331 for (
const auto & species : names)
332 if (
_root[
"gas species"].contains(species))
336 auto gas_species =
_root[
"gas species"][species];
340 std::vector<Real> eq_const(gas_species[
"logk"].size());
341 for (
unsigned int i = 0; i < gas_species[
"logk"].size(); ++i)
342 eq_const[i] =
getReal(gas_species[
"logk"][i]);
346 std::map<std::string, Real> basis_species;
347 for (
auto & bs : gas_species[
"species"].items())
348 basis_species[bs.key()] =
getReal(bs.value());
353 if (gas_species.contains(
"chi"))
355 std::vector<Real> chi(gas_species[
"chi"].size());
356 for (
unsigned int i = 0; i < gas_species[
"chi"].size(); ++i)
357 chi[i] =
getReal(gas_species[
"chi"][i]);
362 if (gas_species.contains(
"Pcrit"))
365 if (gas_species.contains(
"Tcrit"))
368 if (gas_species.contains(
"omega"))
379 std::map<std::string, GeochemistryRedoxSpecies>
383 for (
const auto & species : names)
384 if (
_root[
"redox couples"].contains(species))
388 auto redox_species =
_root[
"redox couples"][species];
394 std::vector<Real> eq_const(redox_species[
"logk"].size());
395 for (
unsigned int i = 0; i < redox_species[
"logk"].size(); ++i)
396 eq_const[i] =
getReal(redox_species[
"logk"][i]);
400 std::map<std::string, Real> basis_species;
401 for (
auto & bs : redox_species[
"species"].items())
402 basis_species[bs.key()] =
getReal(bs.value());
414 std::map<std::string, GeochemistryOxideSpecies>
418 for (
auto & species : names)
419 if (
_root[
"oxides"].contains(species))
423 auto oxide_species =
_root[
"oxides"][species];
427 std::map<std::string, Real> basis_species;
428 for (
auto & bs : oxide_species[
"species"].items())
429 basis_species[bs.key()] =
getReal(bs.value());
441 std::map<std::string, GeochemistrySurfaceSpecies>
445 for (
const auto & species : names)
446 if (
_root[
"surface species"].contains(species))
450 auto surface_species =
_root[
"surface species"][species];
457 std::map<std::string, Real> basis_species;
458 for (
auto & bs : surface_species[
"species"].items())
459 basis_species[bs.key()] =
getReal(bs.value());
474 if (
_root[
"Header"].contains(
"neutral species"))
476 auto neutral_species =
_root[
"Header"][
"neutral species"];
477 for (
auto & ns : neutral_species.items())
479 std::vector<std::vector<Real>> coeffs;
481 for (
auto & nsac : ns.value().items())
483 if (nsac.key() ==
"note")
485 std::vector<Real> coeffvec(nsac.value().size());
487 for (
unsigned int i = 0; i < coeffvec.size(); ++i)
488 coeffvec[i] =
getReal(nsac.value()[i]);
490 coeffs.push_back(coeffvec);
495 coeffs.resize(4, {});
504 const std::map<std::string, GeochemistryNeutralSpeciesActivity> &
507 if (!
_root[
"Header"].contains(
"neutral species"))
508 mooseError(
"No neutral species activity coefficients in database");
512 std::vector<std::string>
515 std::vector<std::map<std::string, Real>> basis_species(names.size());
517 for (
unsigned int i = 0; i < names.size(); ++i)
519 auto species = names[i];
521 if (
_root[
"secondary species"].contains(species))
523 auto sec_species =
_root[
"secondary species"][species];
526 std::map<std::string, Real> this_basis_species;
527 for (
auto & bs : sec_species[
"species"].items())
528 this_basis_species[bs.key()] =
getReal(bs.value());
530 basis_species[i] = this_basis_species;
541 std::vector<std::string>
544 std::vector<std::map<std::string, Real>> basis_species(names.size());
546 for (
unsigned int i = 0; i < names.size(); ++i)
548 const auto species = names[i];
550 if (
_root[
"mineral species"].contains(species))
552 auto min_species =
_root[
"mineral species"][species];
555 std::map<std::string, Real> this_basis_species;
556 for (
auto & bs : min_species[
"species"].items())
557 this_basis_species[bs.key()] =
getReal(bs.value());
559 basis_species[i] = this_basis_species;
570 std::vector<std::string>
573 std::vector<std::map<std::string, Real>> basis_species(names.size());
575 for (
unsigned int i = 0; i < names.size(); ++i)
577 const auto species = names[i];
579 if (
_root[
"gas species"].contains(species))
581 auto gas_species =
_root[
"gas species"][species];
584 std::map<std::string, Real> this_basis_species;
585 for (
auto & bs : gas_species[
"species"].items())
586 this_basis_species[bs.key()] =
getReal(bs.value());
588 basis_species[i] = this_basis_species;
599 std::vector<std::string>
602 std::vector<std::map<std::string, Real>> basis_species(names.size());
604 for (
unsigned int i = 0; i < names.size(); ++i)
606 const auto species = names[i];
608 if (
_root[
"redox couples"].contains(species))
610 auto redox_species =
_root[
"redox couples"][species];
613 std::map<std::string, Real> this_basis_species;
614 for (
auto & bs : redox_species[
"species"].items())
615 this_basis_species[bs.key()] =
getReal(bs.value());
617 basis_species[i] = this_basis_species;
628 std::vector<std::string>
631 std::vector<std::map<std::string, Real>> basis_species(names.size());
633 for (
unsigned int i = 0; i < names.size(); ++i)
635 const auto species = names[i];
637 if (
_root[
"oxides"].contains(species))
639 auto oxide_species =
_root[
"oxides"][species];
642 std::map<std::string, Real> this_basis_species;
643 for (
auto & bs : oxide_species[
"species"].items())
644 this_basis_species[bs.key()] =
getReal(bs.value());
646 basis_species[i] = this_basis_species;
657 std::vector<std::string>
659 const std::vector<std::string> & names,
660 const std::vector<std::map<std::string, Real>> & basis_species)
const 662 std::vector<std::string> reactions;
664 for (
unsigned int i = 0; i < names.size(); ++i)
667 for (
auto & bs : basis_species[i])
671 if (bs.second == -1.0)
678 if (bs.second == 1.0)
689 reactions.push_back(names[i] +
" =" +
reaction);
695 std::vector<std::string>
698 std::vector<std::string> names;
699 if (
_root.contains(
"mineral species"))
700 for (
auto & item :
_root[
"mineral species"].items())
701 names.push_back(item.key());
705 std::vector<std::string>
708 std::vector<std::string> names;
709 if (
_root.contains(
"secondary species"))
710 for (
auto & item :
_root[
"secondary species"].items())
711 names.push_back(item.key());
713 if (
_root.contains(
"free electron"))
714 for (
const auto & nm :
_root[
"free electron"].items())
715 names.push_back(nm.key());
719 std::vector<std::string>
722 std::vector<std::string> names;
723 if (
_root.contains(
"redox couples"))
724 for (
const auto & item :
_root[
"redox couples"].items())
725 names.push_back(item.key());
729 std::vector<std::string>
732 std::vector<std::string> names;
733 if (
_root.contains(
"surface species"))
734 for (
const auto & item :
_root[
"surface species"].items())
735 names.push_back(item.key());
748 return _root[
"basis species"].contains(
name);
754 return _root[
"redox couples"].contains(
name);
760 return _root[
"sorbing minerals"].contains(
name);
766 return _root[
"secondary species"].contains(
name) ||
_root[
"free electron"].contains(
name);
772 return _root[
"gas species"].contains(
name);
778 return _root[
"mineral species"].contains(
name);
790 return _root[
"surface species"].contains(
name);
797 for (
auto & item :
_root.items())
800 std::ostringstream
os;
801 os << item.value()[
name].dump(4);
808 return name +
":\n" + output;
814 if (node.is_string())
815 return MooseUtils::convert<Real>(node);
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::vector< Real > getPressures()
Get the pressure points that the equilibrium constant is defined at.
std::string getActivityModel() const
Get the activity model type.
Data structure for basis (primary) species.
std::map< std::string, Real > basis_species
void validate()
Validate the thermodynamic database.
const GeochemistryDebyeHuckel & getDebyeHuckel() const
Get the Debye-Huckel activity coefficients.
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::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.
void validate(const FileName filename, const nlohmann::json &db)
Validate the thermodynamic database.
std::map< std::string, GeochemistryRedoxSpecies > _redox_species
Redox species (couples) data read from the database.
Data structure for redox species.
Data structure for oxide species.
std::vector< std::string > redoxReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all redox reactions.
const FileName & filename() const
Filename of database.
std::string getLogKModel() const
Get the equilibrium constant model type.
std::vector< Real > equilibrium_const
nlohmann::json _root
JSON data.
Data structure for sorbing surface species.
std::vector< Real > equilibrium_const
std::string getFugacityModel() const
Get the fugacity model type.
std::basic_ostream< charT, traits > * os
std::map< std::string, GeochemistryGasSpecies > _gas_species
Gas species data read from the database.
std::map< std::string, Real > basis_species
std::string getSpeciesData(const std::string name) const
String representation of JSON species object contents.
bool isSorbingMineral(const std::string &name) const
returns True iff name is the name of a sorbing mineral
std::map< std::string, GeochemistryNeutralSpeciesActivity > _neutral_species_activity
Neutral species activity coefficients.
std::vector< std::string > mineralSpeciesNames() const
Returns a list of all the names of the "mineral species" in the database.
Data structure for Debye-Huckel activity coefficients.
const FileName _filename
Database filename.
bool isOxideSpecies(const std::string &name) const
const std::vector< Real > & getTemperatures() const
Get the temperature points that the equilibrium constant is defined at.
GeochemistryDebyeHuckel _debye_huckel
Debye-Huckel activity coefficients.
std::vector< std::string > surfaceSpeciesNames() const
Returns a list of all the names of the "surface species" in the database.
Data structure for mineral species.
const GeochemicalDatabaseReader db("database/moose_testdb.json", true, true, false)
std::map< std::string, GeochemistryMineralSpecies > _mineral_species
Mineral species data read from the database.
std::map< std::string, Real > basis_species
void removeExtrapolatedSecondarySpecies()
After parsing the database file, remove any secondary species that have extrapolated equilibrium cons...
GeochemicalDatabaseReader(const FileName filename, const bool reexpress_free_electron=true, const bool use_piecewise_interpolation=false, const bool remove_all_extrapolated_secondary_species=false)
Parse the file.
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true, bool check_for_git_lfs_pointer=true)
Data structure for neutral species activity coefficients.
std::map< std::string, GeochemistryBasisSpecies > getBasisSpecies(const std::vector< std::string > &names)
Get the basis (primary) species information.
void setDebyeHuckel()
Copy the Debye-Huckel parameters (if any) found in the database into _debye_huckel.
std::map< std::string, GeochemistryOxideSpecies > _oxide_species
Oxide species data read from the database.
Class for validating MOOSE geochemical database.
void read(const FileName filename)
Parse the thermodynamic database.
std::string stringify(const T &t)
bool isGasSpecies(const std::string &name) const
static Real getReal(const nlohmann::json &node)
void setTemperatures()
Copy the temperature points (if any) found in the database into _temperature_points.
void reexpressFreeElectron()
Sometimes the free electron's equilibrium reaction is defined in terms of O2(g) which is not a basis ...
std::vector< Real > _temperature_points
Temperature points in database.
std::map< std::string, GeochemistryElements > getElements()
Get all the elements.
std::map< std::string, Real > basis_species
std::vector< std::string > equilibriumReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all aqueous equilibrium reactions.
std::map< std::string, GeochemistryEquilibriumSpecies > _equilibrium_species
Secondary equilibrium species and free electron data read from the database.
std::vector< Real > equilibrium_const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::map< std::string, Real > sorption_sites
bool isSecondarySpecies(const std::string &name) const
Returns true if name is a "secondary species" or "free electron" in the database. ...
Data structure for secondary equilibrium species.
std::map< std::string, GeochemistrySurfaceSpecies > _surface_species
Surface sorbing species data read from the database.
bool isSurfaceSpecies(const std::string &name) const
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< std::string > oxideReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all oxide reactions.
std::map< std::string, Real > basis_species
std::map< std::string, GeochemistryOxideSpecies > getOxideSpecies(const std::vector< std::string > &names)
Get the oxide species information.
bool isMineralSpecies(const std::string &name) const
std::map< std::string, Real > elements
const std::map< std::string, GeochemistryNeutralSpeciesActivity > & getNeutralSpeciesActivity() const
Get the neutral species activity coefficients.
std::map< std::string, GeochemistryBasisSpecies > _basis_species
Basis species data read from the database.
std::vector< Real > equilibrium_const
std::map< std::string, Real > basis_species
std::map< std::string, GeochemistryRedoxSpecies > getRedoxSpecies(const std::vector< std::string > &names)
Get the redox species (couples) information.
std::vector< Real > _pressure_points
Pressure points in database.
std::vector< std::string > printReactions(const std::vector< std::string > &names, const std::vector< std::map< std::string, Real >> &basis_species) const
Generates a formatted vector of strings representing all reactions.
void setNeutralSpeciesActivity()
Copy the Debye-Huckel parameters for computing neutral species activity (if any) found in the databas...
std::vector< std::string > gasReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all gas reactions.
std::map< std::string, GeochemistryElements > _elements
Elements and their molecular weight read from the database.
bool isRedoxSpecies(const std::string &name) const
std::vector< std::string > mineralReactions(const std::vector< std::string > &names) const
Generates a formatted vector of strings representing all mineral reactions.
bool isBasisSpecies(const std::string &name) const
Checks if species is of given type.