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 (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)
 
std::vector< GlobalVector * > getIntPtProcessSolutions () const override
 
void updateNodalProcessSolutions (std::vector< GlobalVector * > const &process_solutions, std::size_t const node_id)
 
- Public Member Functions inherited from ChemistryLib::ChemicalSolverInterface
 ChemicalSolverInterface (GlobalLinearSolver &linear_solver_)
 
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 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)
 
bool isHydrogen (char const *element) const
 
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
 
GlobalLinearSolverlinear_solver
 

Constructor & Destructor Documentation

◆ PhreeqcKernel()

ChemistryLib::PhreeqcKernelData::PhreeqcKernel::PhreeqcKernel ( 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.

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

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 259 of file PhreeqcKernel.cpp.

260 {
261  std::size_t const num_chemical_systems = process_solutions[0]->size();
262  for (std::size_t chemical_system_id = 0;
263  chemical_system_id < num_chemical_systems;
264  ++chemical_system_id)
265  {
266  Rxn_new_solution.insert(chemical_system_id);
267  new_solution = 1;
268  use.Set_n_solution_user(chemical_system_id);
269 
270  if (!Rxn_pp_assemblage_map.empty())
271  {
272  Rxn_new_pp_assemblage.insert(chemical_system_id);
273  use.Set_pp_assemblage_in(true);
274  use.Set_n_pp_assemblage_user(chemical_system_id);
275  }
276 
277  if (!Rxn_kinetics_map.empty())
278  {
279  use.Set_kinetics_in(true);
280  use.Set_n_kinetics_user(chemical_system_id);
281  }
282 
283  initial_solutions(false);
284 
285  reactions();
286 
287  updateNodalProcessSolutions(process_solutions, chemical_system_id);
288 
289  reset(chemical_system_id);
290  }
291 }
void updateNodalProcessSolutions(std::vector< GlobalVector * > const &process_solutions, std::size_t const node_id)
void reset(std::size_t const chemical_system_id)

References reset(), and updateNodalProcessSolutions().

Referenced by executeSpeciationCalculation().

◆ configureOutputSettings()

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

Definition at line 72 of file PhreeqcKernel.h.

72 { pr.all = false; }

Referenced by PhreeqcKernel().

◆ executeSpeciationCalculation()

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

Implements ChemistryLib::ChemicalSolverInterface.

Definition at line 175 of file PhreeqcKernel.cpp.

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

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

◆ getIntPtProcessSolutions()

std::vector<GlobalVector*> ChemistryLib::PhreeqcKernelData::PhreeqcKernel::getIntPtProcessSolutions ( ) const
inlineoverridevirtual

Implements ChemistryLib::ChemicalSolverInterface.

Definition at line 51 of file PhreeqcKernel.h.

52  {
53  return {};
54  }

◆ getOrCreateInitialAqueousSolution()

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

Definition at line 237 of file PhreeqcKernel.cpp.

239 {
240  if (!aqueous_solution.Get_initial_data())
241  {
242  aqueous_solution.Set_initial_data(_initial_aqueous_solution.get());
243  aqueous_solution.Set_new_def(true);
244  }
245 
246  return aqueous_solution.Get_initial_data();
247 }

References _initial_aqueous_solution.

Referenced by setAqueousSolutions().

◆ initializePhreeqcGeneralSettings()

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

Definition at line 61 of file PhreeqcKernel.h.

61 { do_initialize(); }

Referenced by PhreeqcKernel().

◆ isHydrogen()

bool ChemistryLib::PhreeqcKernelData::PhreeqcKernel::isHydrogen ( char const *  element) const
inlineprivate

Definition at line 77 of file PhreeqcKernel.h.

78  {
79  return strcmp(element, "H") == 0;
80  }

Referenced by setAqueousSolutions(), and updateNodalProcessSolutions().

◆ loadDatabase()

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

Definition at line 132 of file PhreeqcKernel.cpp.

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

References OGS_FATAL.

Referenced by PhreeqcKernel().

◆ reinitializeRates()

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

Definition at line 144 of file PhreeqcKernel.cpp.

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

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 293 of file PhreeqcKernel.cpp.

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

References _aqueous_solution.

Referenced by callPhreeqc().

◆ setAqueousSolutions()

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

Definition at line 186 of file PhreeqcKernel.cpp.

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

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

Referenced by executeSpeciationCalculation().

◆ setConvergenceTolerance()

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

Definition at line 70 of file PhreeqcKernel.h.

70 { convergence_tolerance = 1e-12; }

Referenced by PhreeqcKernel().

◆ setTimeStepSize()

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

Definition at line 249 of file PhreeqcKernel.cpp.

250 {
251  // Loop over rxn kinetics map
252  for (auto& map_pair : Rxn_kinetics_map)
253  {
254  auto& kinetics = map_pair.second;
255  kinetics.Get_steps().push_back(dt);
256  }
257 }

Referenced by executeSpeciationCalculation().

◆ tidyEquilibriumReactants()

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

Definition at line 111 of file PhreeqcKernel.cpp.

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

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 329 of file PhreeqcKernel.cpp.

332 {
333  for (auto const& map_pair : _process_id_to_master_map)
334  {
335  auto const transport_process_id = map_pair.first;
336  auto const& master_species = map_pair.second;
337 
338  auto& transport_process_solution =
339  process_solutions[transport_process_id];
340 
341  auto const& element_name = master_species->elt->name;
342  if (isHydrogen(element_name))
343  {
344  // Update hydrogen concentration by pH value.
345  auto const hydrogen_concentration = std::pow(10, s_hplus->la);
346  transport_process_solution->set(node_id, hydrogen_concentration);
347  }
348  else
349  {
350  // Update solutions of component transport processes.
351  auto const concentration =
352  master_species->primary
353  ? master_species->total_primary / mass_water_aq_x
354  : master_species->total / mass_water_aq_x;
355  transport_process_solution->set(node_id, concentration);
356  }
357  }
358 }

References _process_id_to_master_map, MaterialPropertyLib::concentration, and isHydrogen().

Referenced by callPhreeqc().

Member Data Documentation

◆ _aqueous_solution

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

Definition at line 88 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 87 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 86 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 89 of file PhreeqcKernel.h.

Referenced by reinitializeRates().


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