OGS
ChemistryLib::PhreeqcIOData Namespace Reference

Namespaces

namespace  anonymous_namespace{PhreeqcIO.cpp}

Classes

struct  AqueousSolution
class  BasicOutputSetups
 Controls which built-in PHREEQC columns appear in the output file. More...
struct  ChemicalSystem
 Complete description of one local reactive system passed to PHREEQC. More...
struct  ClampingStats
struct  Component
struct  DensityBasedSurfaceSite
struct  Dump
struct  EquilibriumReactant
struct  ExchangeSite
struct  KineticReactant
struct  Knobs
struct  MoleBasedSurfaceSite
struct  Output
 Specification of which PHREEQC output columns are imported into OpenGeoSys. More...
struct  OutputItem
 One PHREEQC output column that OpenGeoSys will keep. More...
class  PhreeqcInstancePool
class  PhreeqcIO
 Drives the chemistry step in the operator-split reactive transport loop. More...
struct  ReactionRate
struct  SecondaryVariable
struct  UserPunch

Enumerations

enum class  ItemType {
  pH , pe , Component , EquilibriumReactant ,
  KineticReactant , SecondaryVariable
}
 Category used to interpret a PHREEQC output column. More...

Functions

std::string specifyFileName (std::string const &project_file_name, std::string const &file_extension)
std::ostream & operator<< (std::ostream &os, PhreeqcIO const &phreeqc_io)
std::istream & operator>> (std::istream &in, PhreeqcIO &phreeqc_io)
ClampingStats setAqueousSolution (std::vector< double > const &concentrations, std::size_t const chemical_system_id, AqueousSolution &aqueous_solution, double const warning_threshold)
std::unique_ptr< AqueousSolutioncreateAqueousSolution (BaseLib::ConfigTree const &config, MeshLib::Mesh &mesh)
std::unique_ptr< ChemicalSystemcreateChemicalSystem (BaseLib::ConfigTree const &config, MeshLib::Mesh &mesh)
std::vector< EquilibriumReactantcreateEquilibriumReactants (std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
std::vector< ExchangeSitecreateExchange (std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
std::vector< KineticReactantcreateKineticReactants (std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
Knobs createKnobs (BaseLib::ConfigTree const &config)
std::unique_ptr< OutputcreateOutput (ChemicalSystem const &chemical_system, std::unique_ptr< UserPunch > const &user_punch, bool const use_high_precision, std::string const &project_file_name)
std::vector< ComponentcreateSolutionComponents (BaseLib::ConfigTree const &config)
std::vector< std::variant< DensityBasedSurfaceSite, MoleBasedSurfaceSite > > createSurface (std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
std::unique_ptr< UserPunchcreateUserPunch (std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh const &mesh)
std::ostream & operator<< (std::ostream &os, Knobs const &knobs)
std::ostream & operator<< (std::ostream &os, BasicOutputSetups const &basic_output_setups)
std::ostream & operator<< (std::ostream &os, Output const &output)
std::ostream & operator<< (std::ostream &os, ReactionRate const &reaction_rate)
std::ostream & operator<< (std::ostream &os, UserPunch const &user_punch)

Enumeration Type Documentation

◆ ItemType

Category used to interpret a PHREEQC output column.

Distinguishes pH / pe, total component amounts, equilibrium-phase amounts, kinetic-phase amounts, and user-defined secondary variables.

Enumerator
pH 
pe 
Component 
EquilibriumReactant 
KineticReactant 
SecondaryVariable 

Definition at line 71 of file ChemistryLib/PhreeqcIOData/Output.h.

Function Documentation

◆ createAqueousSolution()

std::unique_ptr< AqueousSolution > ChemistryLib::PhreeqcIOData::createAqueousSolution ( BaseLib::ConfigTree const & config,
MeshLib::Mesh & mesh )
Input File Parameter
prj__chemical_system__solution__fixing_pe
Input File Parameter
prj__chemical_system__solution__temperature
Input File Parameter
prj__chemical_system__solution__pressure
Input File Parameter
prj__chemical_system__solution__pe

Definition at line 17 of file PhreeqcIOData/CreateAqueousSolution.cpp.

19{
21 auto const fixing_pe = config.getConfigAttribute<bool>("fixing_pe", false);
22
24 auto const temperature = config.getConfigParameter<double>("temperature");
25
27 auto const pressure = config.getConfigParameter<double>("pressure");
28
30 auto const pe0 = config.getConfigParameter<double>("pe");
31
34
35 auto components = createSolutionComponents(config);
36
37 auto charge_balance = createChargeBalance(config);
38
39 return std::make_unique<AqueousSolution>(fixing_pe, temperature, pressure,
40 pe, pe0, std::move(components),
41 charge_balance);
42}
std::vector< Component > createSolutionComponents(BaseLib::ConfigTree const &config)
ChargeBalance createChargeBalance(BaseLib::ConfigTree const &config)
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)

References ChemistryLib::createChargeBalance(), createSolutionComponents(), BaseLib::ConfigTree::getConfigAttribute(), BaseLib::ConfigTree::getConfigParameter(), MeshLib::getOrCreateMeshProperty(), MeshLib::IntegrationPoint, and pe.

Referenced by createChemicalSystem().

◆ createChemicalSystem()

std::unique_ptr< ChemicalSystem > ChemistryLib::PhreeqcIOData::createChemicalSystem ( BaseLib::ConfigTree const & config,
MeshLib::Mesh & mesh )
Input File Parameter
prj__chemical_system__solution
Input File Parameter
prj__chemical_system__kinetic_reactants
Input File Parameter
prj__chemical_system__equilibrium_reactants
Input File Parameter
prj__chemical_system__exchangers
Input File Parameter
prj__chemical_system__surface

Definition at line 22 of file CreateChemicalSystem.cpp.

24{
25 // solution
26 auto aqueous_solution = createAqueousSolution(
28 config.getConfigSubtree("solution"), mesh);
29
30 // kinetic reactants
31 auto kinetic_reactants = createKineticReactants(
33 config.getConfigSubtreeOptional("kinetic_reactants"), mesh);
34
35 // equilibrium reactants
36 auto equilibrium_reactants = createEquilibriumReactants(
38 config.getConfigSubtreeOptional("equilibrium_reactants"), mesh);
39
40 // exchangers
41 auto exchangers = createExchange(
43 config.getConfigSubtreeOptional("exchangers"), mesh);
44
45 // surface
46 auto surface = createSurface(
48 config.getConfigSubtreeOptional("surface"), mesh);
49
50 return std::make_unique<ChemicalSystem>(std::move(aqueous_solution),
51 std::move(kinetic_reactants),
52 std::move(equilibrium_reactants),
53 std::move(exchangers),
54 std::move(surface));
55}
std::vector< std::variant< DensityBasedSurfaceSite, MoleBasedSurfaceSite > > createSurface(std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
std::unique_ptr< AqueousSolution > createAqueousSolution(BaseLib::ConfigTree const &config, MeshLib::Mesh &mesh)
std::vector< ExchangeSite > createExchange(std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
std::vector< EquilibriumReactant > createEquilibriumReactants(std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)
std::vector< KineticReactant > createKineticReactants(std::optional< BaseLib::ConfigTree > const &config, MeshLib::Mesh &mesh)

References createAqueousSolution(), createEquilibriumReactants(), createExchange(), createKineticReactants(), createSurface(), BaseLib::ConfigTree::getConfigSubtree(), and BaseLib::ConfigTree::getConfigSubtreeOptional().

◆ createEquilibriumReactants()

std::vector< EquilibriumReactant > ChemistryLib::PhreeqcIOData::createEquilibriumReactants ( std::optional< BaseLib::ConfigTree > const & config,
MeshLib::Mesh & mesh )
Input File Parameter
prj__chemical_system__equilibrium_reactants__phase_component
Input File Parameter
prj__chemical_system__equilibrium_reactants__phase_component__name
Input File Parameter
prj__chemical_system__equilibrium_reactants__phase_component__saturation_index
Input File Parameter
prj__chemical_system__equilibrium_reactants__phase_component__reaction_irreversibility

Definition at line 17 of file PhreeqcIOData/CreateEquilibriumReactants.cpp.

19{
20 if (!config)
21 {
22 return {};
23 }
24
25 std::vector<EquilibriumReactant> equilibrium_reactants;
26 for (
27 auto const& equilibrium_reactant_config :
29 config->getConfigSubtreeList("phase_component"))
30 {
31 auto name =
33 equilibrium_reactant_config.getConfigParameter<std::string>("name");
34
35 double const saturation_index =
37 equilibrium_reactant_config.getConfigParameter<double>(
38 "saturation_index");
39
40 auto reaction_irreversibility =
42 equilibrium_reactant_config.getConfigParameter<std::string>(
43 "reaction_irreversibility", "");
44
45 if (!reaction_irreversibility.empty() &&
46 (reaction_irreversibility != "dissolve_only" &&
47 reaction_irreversibility != "precipitate_only"))
48 {
50 "{:s}: reaction direction only allows `dissolve_only` or "
51 "`precipitate_only`",
52 name);
53 }
54
57
59 mesh, name + "_prev", MeshLib::MeshItemType::IntegrationPoint, 1);
60
62 mesh, "phi_" + name, MeshLib::MeshItemType::IntegrationPoint, 1);
63
64 auto volume_fraction_prev = MeshLib::getOrCreateMeshProperty<double>(
65 mesh,
66 "phi_" + name + "_prev",
68 1);
69
70 auto mesh_prop_molality = MeshLib::getOrCreateMeshProperty<double>(
71 mesh, name + "_avg", MeshLib::MeshItemType::Cell, 1);
72 mesh_prop_molality->resize(mesh.getNumberOfElements());
73
74 equilibrium_reactants.emplace_back(std::move(name),
75 molality,
76 molality_prev,
77 volume_fraction,
78 volume_fraction_prev,
79 mesh_prop_molality,
80 saturation_index,
81 std::move(reaction_irreversibility));
82 }
83
84 return equilibrium_reactants;
85}
#define OGS_FATAL(...)
Definition Error.h:10
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:89

References MeshLib::Cell, MeshLib::Mesh::getNumberOfElements(), MeshLib::getOrCreateMeshProperty(), MeshLib::IntegrationPoint, and OGS_FATAL.

Referenced by createChemicalSystem().

◆ createExchange()

std::vector< ExchangeSite > ChemistryLib::PhreeqcIOData::createExchange ( std::optional< BaseLib::ConfigTree > const & config,
MeshLib::Mesh & mesh )
Input File Parameter
prj__chemical_system__exchangers__exchange_site
Input File Parameter
prj__chemical_system__exchangers__exchange_site__ion_exchanging_species

Definition at line 15 of file CreateExchange.cpp.

17{
18 if (!config)
19 {
20 return {};
21 }
22
23 std::vector<ExchangeSite> exchangers;
24 for (auto const& site_config :
26 config->getConfigSubtreeList("exchange_site"))
27 {
29 auto name = site_config.getConfigParameter<std::string>(
30 "ion_exchanging_species");
31
32 auto const molality = MeshLib::getOrCreateMeshProperty<double>(
34
35 exchangers.emplace_back(std::move(name), molality);
36 }
37
38 return exchangers;
39}

References MeshLib::getOrCreateMeshProperty(), and MeshLib::IntegrationPoint.

Referenced by createChemicalSystem().

◆ createKineticReactants()

std::vector< KineticReactant > ChemistryLib::PhreeqcIOData::createKineticReactants ( std::optional< BaseLib::ConfigTree > const & config,
MeshLib::Mesh & mesh )
Input File Parameter
prj__chemical_system__kinetic_reactants__kinetic_reactant
Input File Parameter
prj__chemical_system__kinetic_reactants__kinetic_reactant__name
Input File Parameter
prj__chemical_system__kinetic_reactants__kinetic_reactant__chemical_formula
Input File Parameter
prj__chemical_system__kinetic_reactants__kinetic_reactant__parameters
Input File Parameter
prj__chemical_system__kinetic_reactants__kinetic_reactant__fix_amount

Definition at line 17 of file PhreeqcIOData/CreateKineticReactant.cpp.

19{
20 if (!config)
21 {
22 return {};
23 }
24
25 std::vector<KineticReactant> kinetic_reactants;
26 for (
27 auto const& reactant_config :
29 config->getConfigSubtreeList("kinetic_reactant"))
30 {
32 auto name = reactant_config.getConfigParameter<std::string>("name");
33
34 auto chemical_formula =
36 reactant_config.getConfigParameter<std::string>("chemical_formula",
37 "");
38
39 auto parameters =
41 reactant_config.getConfigParameter<std::vector<double>>(
42 "parameters", {});
43
44 bool const fix_amount =
46 reactant_config.getConfigParameter<bool>("fix_amount", false);
47
50
52 mesh, name + "_prev", MeshLib::MeshItemType::IntegrationPoint, 1);
53
55 mesh, "phi_" + name, MeshLib::MeshItemType::IntegrationPoint, 1);
56
57 auto volume_fraction_prev = MeshLib::getOrCreateMeshProperty<double>(
58 mesh,
59 "phi_" + name + "_prev",
61 1);
62
63 auto mesh_prop_molality = MeshLib::getOrCreateMeshProperty<double>(
64 mesh, name + "_avg", MeshLib::MeshItemType::Cell, 1);
65 assert(mesh_prop_molality->size() == mesh.getNumberOfElements());
66
67 kinetic_reactants.emplace_back(std::move(name),
68 std::move(chemical_formula),
69 molality,
70 molality_prev,
71 volume_fraction,
72 volume_fraction_prev,
73 mesh_prop_molality,
74 std::move(parameters),
75 fix_amount);
76 }
77
78 return kinetic_reactants;
79}

References MeshLib::Cell, MeshLib::Mesh::getNumberOfElements(), MeshLib::getOrCreateMeshProperty(), and MeshLib::IntegrationPoint.

Referenced by createChemicalSystem().

◆ createKnobs()

Knobs ChemistryLib::PhreeqcIOData::createKnobs ( BaseLib::ConfigTree const & config)
Input File Parameter
prj__chemical_system__knobs__max_iter
Input File Parameter
prj__chemical_system__knobs__relative_convergence_tolerance
Input File Parameter
prj__chemical_system__knobs__tolerance
Input File Parameter
prj__chemical_system__knobs__step_size
Input File Parameter
prj__chemical_system__knobs__scaling

Definition at line 13 of file CreateKnobs.cpp.

14{
15 auto const max_iterations =
17 config.getConfigParameter<int>("max_iter");
18
19 auto const relative_convergence_tolerance =
21 config.getConfigParameter<double>("relative_convergence_tolerance");
22
23 auto const tolerance =
25 config.getConfigParameter<double>("tolerance");
26
27 auto const step_size =
29 config.getConfigParameter<int>("step_size");
30
31 auto const scaling =
33 config.getConfigParameter<bool>("scaling");
34
35 return {max_iterations, relative_convergence_tolerance, tolerance,
36 step_size, scaling};
37}

References BaseLib::ConfigTree::getConfigParameter().

◆ createOutput()

std::unique_ptr< Output > ChemistryLib::PhreeqcIOData::createOutput ( ChemicalSystem const & chemical_system,
std::unique_ptr< UserPunch > const & user_punch,
bool const use_high_precision,
std::string const & project_file_name )

Definition at line 18 of file ChemistryLib/PhreeqcIOData/CreateOutput.cpp.

23{
24 auto const& components = chemical_system.aqueous_solution->components;
25 auto const& equilibrium_reactants = chemical_system.equilibrium_reactants;
26 auto const& kinetic_reactants = chemical_system.kinetic_reactants;
27 // Mark which phreeqc output items will be held.
28 std::vector<OutputItem> accepted_items{{"pH", ItemType::pH},
29 {"pe", ItemType::pe}};
30
31 auto accepted_item = [](auto const& item)
32 { return OutputItem(item.name, item.item_type); };
33 std::transform(components.begin(), components.end(),
34 std::back_inserter(accepted_items), accepted_item);
35 std::transform(equilibrium_reactants.begin(), equilibrium_reactants.end(),
36 std::back_inserter(accepted_items), accepted_item);
37 for (auto const& kinetic_reactant : kinetic_reactants)
38 {
39 if (kinetic_reactant.fix_amount)
40 {
41 continue;
42 }
43 accepted_items.emplace_back(kinetic_reactant.name,
44 kinetic_reactant.item_type);
45 }
46
47 if (user_punch)
48 {
49 auto const& secondary_variables = user_punch->secondary_variables;
50 accepted_items.reserve(accepted_items.size() +
51 secondary_variables.size());
52 std::transform(secondary_variables.begin(), secondary_variables.end(),
53 std::back_inserter(accepted_items), accepted_item);
54 }
55
56 // Record ids of which phreeqc output items will be dropped.
57 BasicOutputSetups basic_output_setups(project_file_name,
58 use_high_precision);
59 auto const num_dropped_basic_items =
60 basic_output_setups.getNumberOfDroppedItems();
61 std::vector<int> dropped_item_ids(num_dropped_basic_items);
62 std::iota(dropped_item_ids.begin(), dropped_item_ids.end(), 0);
63
64 auto const num_dvalue_equilibrium_reactants = equilibrium_reactants.size();
65 auto const num_dvalue_kinetic_reactants = kinetic_reactants.size();
66 int const num_dvalue_items =
67 num_dvalue_equilibrium_reactants + num_dvalue_kinetic_reactants;
68
69 auto const num_basic_items =
70 basic_output_setups.getNumberOfItemsInDisplay();
71 auto const num_components = components.size();
72 auto dvalue_item_id = num_basic_items + num_components + 1;
73 for (int i = 0; i < num_dvalue_items; ++i)
74 {
75 dropped_item_ids.push_back(dvalue_item_id);
76 dvalue_item_id += 2;
77 }
78
79 return std::make_unique<Output>(std::move(basic_output_setups),
80 std::move(accepted_items),
81 std::move(dropped_item_ids));
82}
Controls which built-in PHREEQC columns appear in the output file.
One PHREEQC output column that OpenGeoSys will keep.

References ChemistryLib::PhreeqcIOData::ChemicalSystem::aqueous_solution, ChemistryLib::PhreeqcIOData::ChemicalSystem::equilibrium_reactants, ChemistryLib::PhreeqcIOData::BasicOutputSetups::getNumberOfDroppedItems(), ChemistryLib::PhreeqcIOData::BasicOutputSetups::getNumberOfItemsInDisplay(), ChemistryLib::PhreeqcIOData::ChemicalSystem::kinetic_reactants, pe, and pH.

◆ createSolutionComponents()

std::vector< Component > ChemistryLib::PhreeqcIOData::createSolutionComponents ( BaseLib::ConfigTree const & config)
Input File Parameter
prj__chemical_system__solution__components
Input File Parameter
prj__chemical_system__solution__components__component
Input File Parameter
prj__chemical_system__solution__components__component__chemical_formula

Definition at line 13 of file CreateSolutionComponent.cpp.

15{
16 std::vector<Component> components;
18 auto components_config = config.getConfigSubtree("components");
19
20 for (
21 auto const& component_config :
23 components_config.getConfigSubtreeList("component"))
24 {
25 auto const component_name = component_config.getValue<std::string>();
26 auto const chemical_formula =
28 component_config.getConfigAttribute<std::string>("chemical_formula",
29 "");
30 components.emplace_back(component_name, chemical_formula);
31 }
32
33 return components;
34}

References BaseLib::ConfigTree::getConfigSubtree().

Referenced by createAqueousSolution().

◆ createSurface()

std::vector< std::variant< DensityBasedSurfaceSite, MoleBasedSurfaceSite > > ChemistryLib::PhreeqcIOData::createSurface ( std::optional< BaseLib::ConfigTree > const & config,
MeshLib::Mesh & mesh )
Input File Parameter
prj__chemical_system__surface__site_unit
Input File Parameter
prj__chemical_system__surface__site
Input File Parameter
prj__chemical_system__surface__site__name
Input File Parameter
prj__chemical_system__surface__site__site_density
Input File Parameter
prj__chemical_system__surface__site__specific_surface_area
Input File Parameter
prj__chemical_system__surface__site__mass
Input File Parameter
prj__chemical_system__surface__site
Input File Parameter
prj__chemical_system__surface__site__name

Definition at line 16 of file CreateSurface.cpp.

18{
19 if (!config)
20 {
21 return {};
22 }
23
24 std::vector<std::variant<DensityBasedSurfaceSite, MoleBasedSurfaceSite>>
25 surface;
26
27 auto const surface_site_unit =
29 config->getConfigAttribute<std::string>("site_unit", "mole");
30
31 if (surface_site_unit == "density")
32 {
33 for (auto const& site_config :
35 config->getConfigSubtreeList("site"))
36 {
38 auto name = site_config.getConfigParameter<std::string>("name");
39
40 auto const site_density =
42 site_config.getConfigParameter<double>("site_density");
43
44 auto const specific_surface_area =
46 site_config.getConfigParameter<double>("specific_surface_area");
47
48 auto const mass =
50 site_config.getConfigParameter<double>("mass");
51
52 surface.emplace_back(DensityBasedSurfaceSite(
53 std::move(name), site_density, specific_surface_area, mass));
54 }
55
56 return surface;
57 }
58
59 if (surface_site_unit == "mole")
60 {
61 for (auto const& site_config :
63 config->getConfigSubtreeList("site"))
64 {
66 auto name = site_config.getConfigParameter<std::string>("name");
67
70
71 surface.emplace_back(
72 MoleBasedSurfaceSite(std::move(name), molality));
73 }
74
75 return surface;
76 }
77
78 OGS_FATAL("Surface site unit should be either of 'density' or 'mole'.");
79}

References MeshLib::getOrCreateMeshProperty(), MeshLib::IntegrationPoint, and OGS_FATAL.

Referenced by createChemicalSystem().

◆ createUserPunch()

std::unique_ptr< UserPunch > ChemistryLib::PhreeqcIOData::createUserPunch ( std::optional< BaseLib::ConfigTree > const & config,
MeshLib::Mesh const & mesh )
Input File Parameter
prj__chemical_system__user_punch__headline
Input File Parameter
prj__chemical_system__user_punch__statement

Definition at line 15 of file CreateUserPunch.cpp.

17{
18 if (!config)
19 {
20 return nullptr;
21 }
22
23 std::vector<SecondaryVariable> secondary_variables;
24 for (auto const& variable_name :
26 config->getConfigParameter<std::vector<std::string>>("headline"))
27 {
29 const_cast<MeshLib::Mesh&>(mesh),
30 variable_name,
32 1);
33 std::fill(std::begin(*value),
34 std::end(*value),
35 std::numeric_limits<double>::quiet_NaN());
36
37 secondary_variables.emplace_back(variable_name, value);
38 }
39
40 std::vector<std::string> statements;
41 for (auto const& statement :
43 config->getConfigParameterList<std::string>("statement"))
44 {
45 statements.emplace_back(statement);
46 }
47
48 return std::make_unique<UserPunch>(std::move(secondary_variables),
49 std::move(statements));
50}

References MeshLib::getOrCreateMeshProperty(), and MeshLib::IntegrationPoint.

◆ operator<<() [1/6]

std::ostream & ChemistryLib::PhreeqcIOData::operator<< ( std::ostream & os,
BasicOutputSetups const & basic_output_setups )

Definition at line 39 of file ChemistryLib/PhreeqcIOData/Output.cpp.

41{
42 os << "SELECTED_OUTPUT"
43 << "\n";
44 os << "-file " << basic_output_setups.output_file << "\n";
45 os << "-high_precision " << std::boolalpha
46 << basic_output_setups.use_high_precision << "\n";
47 os << "-simulation " << std::boolalpha
49 os << "-state " << std::boolalpha << BasicOutputSetups::display_state
50 << "\n";
51 os << "-distance " << std::boolalpha << BasicOutputSetups::display_distance
52 << "\n";
53 os << "-time " << std::boolalpha << BasicOutputSetups::display_current_time
54 << "\n";
55 os << "-step " << std::boolalpha << BasicOutputSetups::display_time_step
56 << "\n";
57
58 return os;
59}

◆ operator<<() [2/6]

std::ostream & ChemistryLib::PhreeqcIOData::operator<< ( std::ostream & os,
Knobs const & knobs )

Definition at line 12 of file Knobs.cpp.

13{
14 os << "KNOBS"
15 << "\n";
16 os << "-iterations " << knobs.max_iterations << "\n";
17 os << "-convergence_tolerance " << knobs.relative_convergence_tolerance
18 << "\n";
19 os << "-tolerance " << knobs.tolerance << "\n";
20 os << "-step_size " << knobs.step_size << "\n";
21 os << "-diagonal_scale " << knobs.scaling << "\n";
22
23 return os;
24}

◆ operator<<() [3/6]

std::ostream & ChemistryLib::PhreeqcIOData::operator<< ( std::ostream & os,
Output const & output )

Definition at line 61 of file ChemistryLib/PhreeqcIOData/Output.cpp.

62{
63 os << output.basic_output_setups;
64
65 auto const component_items =
66 output.getOutputItemsByItemType(ItemType::Component);
67 os << "-totals";
68 for (auto const& component_item : component_items)
69 {
70 os << " " << component_item.name;
71 }
72 os << "\n";
73
74 auto const equilibrium_phase_items =
75 output.getOutputItemsByItemType(ItemType::EquilibriumReactant);
76 if (!equilibrium_phase_items.empty())
77 {
78 os << "-equilibrium_phases";
79 for (auto const& equilibrium_phase_item : equilibrium_phase_items)
80 {
81 os << " " << equilibrium_phase_item.name;
82 }
83 os << "\n";
84 }
85
86 auto const kinetic_reactant_items =
87 output.getOutputItemsByItemType(ItemType::KineticReactant);
88 if (!kinetic_reactant_items.empty())
89 {
90 os << "-kinetic_reactants";
91 for (auto const& kinetic_reactant_item : kinetic_reactant_items)
92 {
93 os << " " << kinetic_reactant_item.name;
94 }
95 os << "\n";
96 }
97
98 return os;
99}

◆ operator<<() [4/6]

std::ostream & ChemistryLib::PhreeqcIOData::operator<< ( std::ostream & os,
PhreeqcIO const & phreeqc_io )

Definition at line 780 of file PhreeqcIO.cpp.

781{
782 phreeqc_io.writeInputHeader(os);
783
784 for (std::size_t chemical_system_id = 0;
785 chemical_system_id < phreeqc_io._num_chemical_systems;
786 ++chemical_system_id)
787 {
788 std::size_t const solution_id = chemical_system_id + 1;
789 std::size_t const prev_solution_id =
790 phreeqc_io._num_chemical_systems + chemical_system_id + 1;
791 phreeqc_io.writeSystemBlock(os, chemical_system_id, solution_id,
792 prev_solution_id, phreeqc_io._dt);
793 }
794
795 if (phreeqc_io._dump)
796 {
797 phreeqc_io._dump->print(os, phreeqc_io._num_chemical_systems);
798 }
799
800 return os;
801}

◆ operator<<() [5/6]

std::ostream & ChemistryLib::PhreeqcIOData::operator<< ( std::ostream & os,
ReactionRate const & reaction_rate )

Definition at line 12 of file PhreeqcIOData/ReactionRate.cpp.

13{
14 os << reaction_rate.kinetic_reactant << "\n";
15 os << "-start"
16 << "\n";
17 int line_number = 1;
18 for (auto const& expression_statement : reaction_rate.expression_statements)
19 {
20 os << line_number << " " << expression_statement << "\n";
21 ++line_number;
22 }
23 os << "-end"
24 << "\n";
25
26 return os;
27}

◆ operator<<() [6/6]

std::ostream & ChemistryLib::PhreeqcIOData::operator<< ( std::ostream & os,
UserPunch const & user_punch )

Definition at line 20 of file UserPunch.cpp.

21{
22 os << "USER_PUNCH"
23 << "\n";
24 os << "-headings ";
25 auto const& secondary_variables = user_punch.secondary_variables;
26 for (auto const& secondary_variable : secondary_variables)
27 {
28 os << secondary_variable.name << " ";
29 }
30 os << "\n";
31
32 os << "-start"
33 << "\n";
34 int line_number = 1;
35 for (auto const& statement : user_punch.statements)
36 {
37 os << line_number << " " << statement << "\n";
38 ++line_number;
39 }
40 os << "-end"
41 << "\n";
42
43 return os;
44}

◆ operator>>()

std::istream & ChemistryLib::PhreeqcIOData::operator>> ( std::istream & in,
PhreeqcIO & phreeqc_io )

Definition at line 930 of file PhreeqcIO.cpp.

931{
932 // Skip the headline
933 in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
934
935 std::string line;
936
937 auto const& surface = phreeqc_io._chemical_system->surface;
938 auto const& exchangers = phreeqc_io._chemical_system->exchangers;
939
940 int const num_skipped_lines =
941 1 + (!surface.empty() ? 1 : 0) + (!exchangers.empty() ? 1 : 0);
942
943 for (std::size_t chemical_system_id = 0;
944 chemical_system_id < phreeqc_io._num_chemical_systems;
945 ++chemical_system_id)
946 {
947 for (int i = 0; i < num_skipped_lines; ++i)
948 {
949 in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
950 }
951
952 if (!std::getline(in, line))
953 {
954 OGS_FATAL(
955 "Error when reading calculation result of Solution {:d} "
956 "after the reaction.",
957 chemical_system_id);
958 }
959
960 phreeqc_io.updateSystemFromOutputLine(line, chemical_system_id);
961 }
962
963 return in;
964}
void updateSystemFromOutputLine(std::string_view line, std::size_t chemical_system_id)
std::unique_ptr< ChemicalSystem > _chemical_system
Definition PhreeqcIO.h:246

◆ setAqueousSolution()

ClampingStats ChemistryLib::PhreeqcIOData::setAqueousSolution ( std::vector< double > const & concentrations,
std::size_t chemical_system_id,
AqueousSolution & aqueous_solution,
double warning_threshold )

Writes concentrations into aqueous_solution for the given chemical_system_id and returns the clamping statistics.

Negative component concentrations are clamped to zero: values in \([\text{warning\_threshold}, 0)\) are treated as floating-point noise (e.g. from MPI partitioning or non-monotone advection/diffusion schemes) and clamped silently, whereas values below warning_threshold (which is negative) are clamped and counted as "severe" in the returned ClampingStats. The caller is responsible for reporting these (e.g. as an aggregated warning across all chemical systems). The last entry of concentrations is the H+ activity \(10^{-\text{pH}}\) for the pH "component".

Definition at line 55 of file PhreeqcIOData/AqueousSolution.cpp.

59{
60 ClampingStats stats;
61 auto& components = aqueous_solution.components;
62 for (unsigned component_id = 0; component_id < components.size();
63 ++component_id)
64 {
65 components[component_id].amount[chemical_system_id] =
66 stats.clamp(concentrations[component_id], warning_threshold,
67 components[component_id].name);
68 }
69 // clamp() collects value-level counters; the per-cell counters are this
70 // one cell's contribution to the run-level accumulator.
71 stats.n_cells = stats.n_values > 0 ? 1 : 0;
72 stats.n_severe_cells = stats.n_severe_values > 0 ? 1 : 0;
73
74 // The transport process carries the H+ activity 10^-pH as the last entry
75 // of the concentrations vector for the pH "component". Unlike component
76 // concentrations it is not clamped: PHREEQC assumes 1 kg of water, and
77 // water autoprotolysis always yields some H+, so a non-positive H+ activity
78 // is physically impossible. Clamping it to zero would make
79 // pH = -log10(activity) NaN/inf, so a non-positive value here signals a
80 // transport-side bug rather than floating-point noise.
81 double const h_plus_activity = concentrations.back();
82 if (h_plus_activity <= 0.0)
83 {
85 "H+ activity (10^-pH) at chemical system {:d} is {:g} <= 0, which "
86 "is physically impossible (PHREEQC's 1 kg-water assumption "
87 "guarantees a positive H+ activity).",
88 chemical_system_id, h_plus_activity);
89 }
90 aqueous_solution.H_plus_activity[chemical_system_id] = h_plus_activity;
91 return stats;
92}
std::vector< double > H_plus_activity
H+ activity 10^-pH, per chemical_system_id.
std::size_t n_severe_values
total severe values clamped
std::size_t n_severe_cells
cells with a severe clamp
double clamp(double c, double warning_threshold, std::string_view name)
std::size_t n_values
total values clamped
std::size_t n_cells
cells with any clamping

References ChemistryLib::PhreeqcIOData::ClampingStats::clamp(), ChemistryLib::PhreeqcIOData::AqueousSolution::components, ChemistryLib::PhreeqcIOData::AqueousSolution::H_plus_activity, ChemistryLib::PhreeqcIOData::ClampingStats::n_cells, ChemistryLib::PhreeqcIOData::ClampingStats::n_severe_cells, ChemistryLib::PhreeqcIOData::ClampingStats::n_severe_values, ChemistryLib::PhreeqcIOData::ClampingStats::n_values, and OGS_FATAL.

Referenced by ChemistryLib::PhreeqcIOData::PhreeqcIO::initializeChemicalSystemConcrete(), and ChemistryLib::PhreeqcIOData::PhreeqcIO::setChemicalSystemConcrete().

◆ specifyFileName()

std::string ChemistryLib::PhreeqcIOData::specifyFileName ( std::string const & project_file_name,
std::string const & file_extension )
extern

Definition at line 18 of file ChemistryLib/PhreeqcIOData/Output.cpp.

20{
21#ifdef USE_PETSC
22 int mpi_rank;
23
24 MPI_Comm_rank(BaseLib::MPI::OGS_COMM_WORLD, &mpi_rank);
25 return project_file_name + "_phreeqc_pid_" + std::to_string(mpi_rank) +
26 file_extension;
27#endif
28
29 return project_file_name + "_phreeqc" + file_extension;
30}
MPI_Comm OGS_COMM_WORLD
Definition MPI.cpp:9

References BaseLib::MPI::OGS_COMM_WORLD.

Referenced by ChemistryLib::PhreeqcIOData::BasicOutputSetups::BasicOutputSetups(), ChemistryLib::PhreeqcIOData::Dump::Dump(), and ChemistryLib::PhreeqcIOData::PhreeqcIO::PhreeqcIO().