OGS
ChemistryLib::PhreeqcKernelData::PhreeqcKernel Class Referencefinal

Detailed Description

Definition at line 32 of file PhreeqcKernel.h.

#include <PhreeqcKernel.h>

Inheritance diagram for ChemistryLib::PhreeqcKernelData::PhreeqcKernel:
[legend]
Collaboration diagram for ChemistryLib::PhreeqcKernelData::PhreeqcKernel:
[legend]

Public Member Functions

 PhreeqcKernel (MeshLib::Mesh const &mesh, GlobalLinearSolver &linear_solver, std::size_t const num_chemical_systems, std::vector< std::pair< int, std::string > > const &process_id_to_component_name_map, std::string const &database, AqueousSolution aqueous_solution, std::unique_ptr< EquilibriumReactants > &&equilibrium_reactants, std::unique_ptr< Kinetics > &&kinetic_reactants, std::vector< ReactionRate > &&reaction_rates)
 
void executeSpeciationCalculation (double const dt) override
 
void setAqueousSolutions (std::vector< GlobalVector * > const &process_solutions)
 
void callPhreeqc (std::vector< GlobalVector * > &process_solutions)
 
void updateNodalProcessSolutions (std::vector< GlobalVector * > const &process_solutions, std::size_t const node_id)
 
- Public Member Functions inherited from ChemistryLib::ChemicalSolverInterface
 ChemicalSolverInterface (MeshLib::Mesh const &mesh, GlobalLinearSolver &linear_solver_)
 
std::vector< std::size_t > const & getElementIDs ()
 
virtual void initialize ()
 
virtual void initializeChemicalSystemConcrete (std::vector< double > const &, GlobalIndexType const &, MaterialPropertyLib::Medium const &, ParameterLib::SpatialPosition const &, double const)
 
virtual void setChemicalSystemConcrete (std::vector< double > const &, GlobalIndexType const &, MaterialPropertyLib::Medium const *, MaterialPropertyLib::VariableArray const &, ParameterLib::SpatialPosition const &, double const, double const)
 
virtual void setAqueousSolutionsPrevFromDumpFile ()
 
virtual double getConcentration (int const, GlobalIndexType const) const
 
virtual std::vector< std::string > const getComponentList () const
 
virtual Eigen::SparseMatrix< double > const * getStoichiometricMatrix () const
 
virtual double getKineticPrefactor (std::size_t reaction_id) const
 
virtual void updateVolumeFractionPostReaction (GlobalIndexType const &, MaterialPropertyLib::Medium const &, ParameterLib::SpatialPosition const &, double const, double const, double const)
 
virtual void updatePorosityPostReaction (GlobalIndexType const &, MaterialPropertyLib::Medium const &, double &)
 
virtual void computeSecondaryVariable (std::size_t const, std::vector< GlobalIndexType > const &)
 
virtual ~ChemicalSolverInterface ()=default
 

Private Member Functions

void initializePhreeqcGeneralSettings ()
 
void tidyEquilibriumReactants (EquilibriumReactants const &equilibrium_reactants)
 
void loadDatabase (std::string const &database)
 
void reinitializeRates ()
 
void setConvergenceTolerance ()
 
void configureOutputSettings ()
 
cxxISolution * getOrCreateInitialAqueousSolution (cxxSolution &aqueous_solution)
 
void setTimeStepSize (double const dt)
 
void reset (std::size_t const chemical_system_id)
 

Private Attributes

std::map< int, struct master * > _process_id_to_master_map
 
std::unique_ptr< cxxISolution const > _initial_aqueous_solution
 
std::unique_ptr< cxxSolution const > _aqueous_solution
 
std::vector< ReactionRate > const _reaction_rates
 

Additional Inherited Members

- Public Attributes inherited from ChemistryLib::ChemicalSolverInterface
std::vector< GlobalIndexTypechemical_system_index_map
 
MeshLib::Mesh const & _mesh
 
GlobalLinearSolverlinear_solver
 

Constructor & Destructor Documentation

◆ PhreeqcKernel()

ChemistryLib::PhreeqcKernelData::PhreeqcKernel::PhreeqcKernel ( MeshLib::Mesh const & mesh,
GlobalLinearSolver & linear_solver,
std::size_t const num_chemical_systems,
std::vector< std::pair< int, std::string > > const & process_id_to_component_name_map,
std::string const & database,
AqueousSolution aqueous_solution,
std::unique_ptr< EquilibriumReactants > && equilibrium_reactants,
std::unique_ptr< Kinetics > && kinetic_reactants,
std::vector< ReactionRate > && reaction_rates )

Definition at line 26 of file PhreeqcKernel.cpp.

38 _initial_aqueous_solution(aqueous_solution.getInitialAqueousSolution()),
39 _aqueous_solution(aqueous_solution.castToBaseClassNoninitialized()),
40 _reaction_rates(std::move(reaction_rates))
41{
43
44 loadDatabase(database);
45
46 // solution
47 for (std::size_t chemical_system_id = 0;
48 chemical_system_id < num_chemical_systems;
49 ++chemical_system_id)
50 {
51 aqueous_solution.setChemicalSystemID(chemical_system_id);
52 Rxn_solution_map.emplace(chemical_system_id,
53 *aqueous_solution.castToBaseClass());
54 }
55 use.Set_solution_in(true);
56
57 // equilibrium reactants
58 if (equilibrium_reactants)
59 {
60 tidyEquilibriumReactants(*equilibrium_reactants);
61
62 for (std::size_t chemical_system_id = 0;
63 chemical_system_id < num_chemical_systems;
64 ++chemical_system_id)
65 {
66 equilibrium_reactants->setChemicalSystemID(chemical_system_id);
67 Rxn_pp_assemblage_map.emplace(
68 chemical_system_id, *equilibrium_reactants->castToBaseClass());
69 }
70 // explicitly release and delete equilibrium_reactants
71 equilibrium_reactants.reset(nullptr);
72
73 use.Set_pp_assemblage_in(true);
74 }
75
76 // kinetic reactants
77 if (kinetic_reactants)
78 {
79 for (std::size_t chemical_system_id = 0;
80 chemical_system_id < num_chemical_systems;
81 ++chemical_system_id)
82 {
83 kinetic_reactants->setChemicalSystemID(chemical_system_id);
84 Rxn_kinetics_map.emplace(chemical_system_id,
85 *kinetic_reactants->castToBaseClass());
86 }
87 // explicitly release and delete kinetic_reactants
88 kinetic_reactants.reset(nullptr);
89
90 use.Set_kinetics_in(true);
91 }
92
93 // rates
95
97
99
100 for (auto const& map_pair : process_id_to_component_name_map)
101 {
102 auto const transport_process_id = map_pair.first;
103 auto const& transport_process_variable = map_pair.second;
104
105 auto master_species =
106 master_bsearch(transport_process_variable.c_str());
107
108 _process_id_to_master_map[transport_process_id] = master_species;
109 }
110}
ChemicalSolverInterface(MeshLib::Mesh const &mesh, GlobalLinearSolver &linear_solver_)
std::vector< ReactionRate > const _reaction_rates
std::map< int, struct master * > _process_id_to_master_map
void tidyEquilibriumReactants(EquilibriumReactants const &equilibrium_reactants)
void loadDatabase(std::string const &database)
std::unique_ptr< cxxSolution const > _aqueous_solution
std::unique_ptr< cxxISolution const > _initial_aqueous_solution

References _process_id_to_master_map, ChemistryLib::PhreeqcKernelData::AqueousSolution::castToBaseClass(), configureOutputSettings(), initializePhreeqcGeneralSettings(), loadDatabase(), reinitializeRates(), ChemistryLib::PhreeqcKernelData::AqueousSolution::setChemicalSystemID(), setConvergenceTolerance(), and tidyEquilibriumReactants().

Member Function Documentation

◆ callPhreeqc()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::callPhreeqc ( std::vector< GlobalVector * > & process_solutions)

Definition at line 264 of file PhreeqcKernel.cpp.

265{
266 if (process_solutions.empty())
267 {
268 OGS_FATAL("About to access an empty process solutions vector.");
269 }
270 std::size_t const num_chemical_systems = process_solutions[0]->size();
271 for (std::size_t chemical_system_id = 0;
272 chemical_system_id < num_chemical_systems;
273 ++chemical_system_id)
274 {
275 Rxn_new_solution.insert(chemical_system_id);
276 new_solution = 1;
277 use.Set_n_solution_user(chemical_system_id);
278
279 if (!Rxn_pp_assemblage_map.empty())
280 {
281 Rxn_new_pp_assemblage.insert(chemical_system_id);
282 use.Set_pp_assemblage_in(true);
283 use.Set_n_pp_assemblage_user(chemical_system_id);
284 }
285
286 if (!Rxn_kinetics_map.empty())
287 {
288 use.Set_kinetics_in(true);
289 use.Set_n_kinetics_user(chemical_system_id);
290 }
291
292 initial_solutions(false);
293
294 reactions();
295
296 updateNodalProcessSolutions(process_solutions, chemical_system_id);
297
298 reset(chemical_system_id);
299 }
300}
#define OGS_FATAL(...)
Definition Error.h:26
void updateNodalProcessSolutions(std::vector< GlobalVector * > const &process_solutions, std::size_t const node_id)
void reset(std::size_t const chemical_system_id)

References OGS_FATAL, reset(), and updateNodalProcessSolutions().

Referenced by executeSpeciationCalculation().

◆ configureOutputSettings()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::configureOutputSettings ( )
inlineprivate

Definition at line 67 of file PhreeqcKernel.h.

67{ pr.all = false; }

Referenced by PhreeqcKernel().

◆ executeSpeciationCalculation()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::executeSpeciationCalculation ( double const dt)
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 174 of file PhreeqcKernel.cpp.

175{
176 std::vector<GlobalVector*> process_solutions;
177
178 setAqueousSolutions(process_solutions);
179
180 setTimeStepSize(dt);
181
182 callPhreeqc(process_solutions);
183}
void setAqueousSolutions(std::vector< GlobalVector * > const &process_solutions)
void callPhreeqc(std::vector< GlobalVector * > &process_solutions)

References callPhreeqc(), setAqueousSolutions(), and setTimeStepSize().

◆ getOrCreateInitialAqueousSolution()

cxxISolution * ChemistryLib::PhreeqcKernelData::PhreeqcKernel::getOrCreateInitialAqueousSolution ( cxxSolution & aqueous_solution)
private

Definition at line 242 of file PhreeqcKernel.cpp.

244{
245 if (!aqueous_solution.Get_initial_data())
246 {
247 aqueous_solution.Set_initial_data(_initial_aqueous_solution.get());
248 aqueous_solution.Set_new_def(true);
249 }
250
251 return aqueous_solution.Get_initial_data();
252}

References _initial_aqueous_solution.

Referenced by setAqueousSolutions().

◆ initializePhreeqcGeneralSettings()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::initializePhreeqcGeneralSettings ( )
inlineprivate

Definition at line 56 of file PhreeqcKernel.h.

56{ do_initialize(); }

Referenced by PhreeqcKernel().

◆ loadDatabase()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::loadDatabase ( std::string const & database)
private

Definition at line 133 of file PhreeqcKernel.cpp.

134{
135 std::ifstream in(database);
136 if (!in)
137 {
138 OGS_FATAL("Unable to open database file '{:s}'.", database);
139 }
140 assert(phrq_io->get_istream() == nullptr);
141 phrq_io->push_istream(&in, false);
142 read_database();
143}

References OGS_FATAL.

Referenced by PhreeqcKernel().

◆ reinitializeRates()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::reinitializeRates ( )
private

Definition at line 145 of file PhreeqcKernel.cpp.

146{
147 std::vector<struct rate> rates(_reaction_rates.size());
148 int rate_id = 0;
149 for (auto const& reaction_rate : _reaction_rates)
150 {
151 rates[rate_id].name = reaction_rate.kinetic_reactant.data();
152
153 // Commands' strings are freed by Phreeqc dtor.
154 rates[rate_id].commands = static_cast<char*>(
155 malloc(sizeof(char) * reaction_rate.commands().size() + 1));
156 if (rates[rate_id].commands == nullptr)
157 {
158 OGS_FATAL("Could not allocate memory for rate[{:d}] commands.",
159 rate_id);
160 }
161 reaction_rate.commands().copy(rates[rate_id].commands,
162 std::string::npos);
163 rates[rate_id].commands[reaction_rate.commands().size()] = '\0';
164
165 rates[rate_id].new_def = 1;
166 rates[rate_id].linebase = nullptr;
167 rates[rate_id].varbase = nullptr;
168 rates[rate_id].loopbase = nullptr;
169
170 ++rate_id;
171 };
172}

References _reaction_rates, and OGS_FATAL.

Referenced by PhreeqcKernel().

◆ reset()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::reset ( std::size_t const chemical_system_id)
private

Definition at line 302 of file PhreeqcKernel.cpp.

303{
304 // Clean up
305 Rxn_new_solution.clear();
306
307 // Solution
308 {
309 Rxn_solution_map[chemical_system_id] = *_aqueous_solution;
310 Rxn_solution_map[chemical_system_id].Set_n_user_both(
311 chemical_system_id);
312 Rxn_solution_map[chemical_system_id].Set_pe(-s_eminus->la);
313 }
314
315 // Equilibrium reactants
316 if (!Rxn_pp_assemblage_map.empty())
317 {
318 Rxn_new_pp_assemblage.clear();
319 for (int j = 0; j < count_unknowns; j++)
320 {
321 if (x == nullptr || x[j]->type != PP)
322 continue;
323
324 auto& phase_components = Rxn_pp_assemblage_map[chemical_system_id]
325 .Get_pp_assemblage_comps();
326 phase_components[x[j]->pp_assemblage_comp_name].Set_moles(
327 x[j]->moles);
328 }
329 }
330
331 // Kinetics
332 if (!Rxn_kinetics_map.empty())
333 {
334 Rxn_kinetics_map[chemical_system_id].Get_steps().clear();
335 }
336}

References _aqueous_solution.

Referenced by callPhreeqc().

◆ setAqueousSolutions()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::setAqueousSolutions ( std::vector< GlobalVector * > const & process_solutions)

Definition at line 190 of file PhreeqcKernel.cpp.

192{
193 assert(!process_solutions.empty());
194 // Loop over chemical systems
195 std::size_t const num_chemical_systems = process_solutions[0]->size();
196 for (std::size_t chemical_system_id = 0;
197 chemical_system_id < num_chemical_systems;
198 ++chemical_system_id)
199 {
200 auto& aqueous_solution = Rxn_solution_map[chemical_system_id];
201
202 auto initial_aqueous_solution =
203 getOrCreateInitialAqueousSolution(aqueous_solution);
204
205 auto& components = initial_aqueous_solution->Get_comps();
206 // Loop over transport process id map to retrieve component
207 // concentrations from process solutions
208 for (auto const& map_pair : _process_id_to_master_map)
209 {
210 auto const transport_process_id = map_pair.first;
211 auto const& master_species = map_pair.second;
212
213 auto& transport_process_solution =
214 process_solutions[transport_process_id];
215
216 char const* const element_name = master_species->elt->name;
217 auto const concentration =
218 transport_process_solution->get(chemical_system_id);
219 if (isHydrogen(element_name))
220 {
221 // Set pH value by hydrogen concentration.
222 double const pH = -std::log10(concentration);
223 aqueous_solution.Set_ph(pH);
224
225 {
226 auto hydrogen = components.find("H(1)");
227 if (hydrogen != components.end())
228 {
229 hydrogen->second.Set_input_conc(pH);
230 }
231 }
232 }
233 else
234 {
235 // Set component concentrations.
236 components[element_name].Set_input_conc(concentration);
237 }
238 }
239 }
240}
cxxISolution * getOrCreateInitialAqueousSolution(cxxSolution &aqueous_solution)
static bool isHydrogen(std::string_view const element)
@ concentration
used to specify decay rate of a substance.

References _process_id_to_master_map, getOrCreateInitialAqueousSolution(), ChemistryLib::PhreeqcKernelData::isHydrogen(), and ChemistryLib::pH.

Referenced by executeSpeciationCalculation().

◆ setConvergenceTolerance()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::setConvergenceTolerance ( )
inlineprivate

Definition at line 65 of file PhreeqcKernel.h.

65{ convergence_tolerance = 1e-12; }

Referenced by PhreeqcKernel().

◆ setTimeStepSize()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::setTimeStepSize ( double const dt)
private

Definition at line 254 of file PhreeqcKernel.cpp.

255{
256 // Loop over rxn kinetics map
257 for (auto& map_pair : Rxn_kinetics_map)
258 {
259 auto& kinetics = map_pair.second;
260 kinetics.Get_steps().push_back(dt);
261 }
262}

Referenced by executeSpeciationCalculation().

◆ tidyEquilibriumReactants()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::tidyEquilibriumReactants ( EquilibriumReactants const & equilibrium_reactants)
private

Definition at line 112 of file PhreeqcKernel.cpp.

114{
115 // extract a part of function body from int
116 // Phreeqc::tidy_pp_assemblage(void)
117 count_elts = 0;
118 double coef = 1.0;
119 for (auto const& phase_component :
120 equilibrium_reactants.getPhaseComponents())
121 {
122 int phase_id;
123 struct phase* phase_component_ptr =
124 phase_bsearch(phase_component.first.c_str(), &phase_id, FALSE);
125 add_elt_list(phase_component_ptr->next_elt, coef);
126 }
127
128 cxxNameDouble nd = elt_list_NameDouble();
129 const_cast<cxxPPassemblage*>(equilibrium_reactants.castToBaseClass())
130 ->Set_eltList(nd);
131}

References ChemistryLib::PhreeqcKernelData::EquilibriumReactants::castToBaseClass(), and ChemistryLib::PhreeqcKernelData::EquilibriumReactants::getPhaseComponents().

Referenced by PhreeqcKernel().

◆ updateNodalProcessSolutions()

void ChemistryLib::PhreeqcKernelData::PhreeqcKernel::updateNodalProcessSolutions ( std::vector< GlobalVector * > const & process_solutions,
std::size_t const node_id )

Definition at line 338 of file PhreeqcKernel.cpp.

341{
342 for (auto const& map_pair : _process_id_to_master_map)
343 {
344 auto const transport_process_id = map_pair.first;
345 auto const& master_species = map_pair.second;
346
347 auto& transport_process_solution =
348 process_solutions[transport_process_id];
349
350 char const* const element_name = master_species->elt->name;
351 if (isHydrogen(element_name))
352 {
353 // Update hydrogen concentration by pH value.
354 auto const hydrogen_concentration = std::pow(10, s_hplus->la);
355 transport_process_solution->set(node_id, hydrogen_concentration);
356 }
357 else
358 {
359 // Update solutions of component transport processes.
360 auto const concentration =
361 master_species->primary
362 ? master_species->total_primary / mass_water_aq_x
363 : master_species->total / mass_water_aq_x;
364 transport_process_solution->set(node_id, concentration);
365 }
366 }
367}

References _process_id_to_master_map, and ChemistryLib::PhreeqcKernelData::isHydrogen().

Referenced by callPhreeqc().

Member Data Documentation

◆ _aqueous_solution

std::unique_ptr<cxxSolution const> ChemistryLib::PhreeqcKernelData::PhreeqcKernel::_aqueous_solution
private

Definition at line 78 of file PhreeqcKernel.h.

Referenced by reset().

◆ _initial_aqueous_solution

std::unique_ptr<cxxISolution const> ChemistryLib::PhreeqcKernelData::PhreeqcKernel::_initial_aqueous_solution
private

Definition at line 77 of file PhreeqcKernel.h.

Referenced by getOrCreateInitialAqueousSolution().

◆ _process_id_to_master_map

std::map<int, struct master*> ChemistryLib::PhreeqcKernelData::PhreeqcKernel::_process_id_to_master_map
private

Definition at line 76 of file PhreeqcKernel.h.

Referenced by PhreeqcKernel(), setAqueousSolutions(), and updateNodalProcessSolutions().

◆ _reaction_rates

std::vector<ReactionRate> const ChemistryLib::PhreeqcKernelData::PhreeqcKernel::_reaction_rates
private

Definition at line 79 of file PhreeqcKernel.h.

Referenced by reinitializeRates().


The documentation for this class was generated from the following files: