OGS
ChemistryLib::PhreeqcIOData::PhreeqcIO Class Referencefinal

Detailed Description

Definition at line 33 of file PhreeqcIO.h.

#include <PhreeqcIO.h>

Inheritance diagram for ChemistryLib::PhreeqcIOData::PhreeqcIO:
[legend]
Collaboration diagram for ChemistryLib::PhreeqcIOData::PhreeqcIO:
[legend]

Public Member Functions

 PhreeqcIO (MeshLib::Mesh const &mesh, GlobalLinearSolver &linear_solver, std::string const &project_file_name, std::string &&database, std::unique_ptr< ChemicalSystem > &&chemical_system, std::vector< ReactionRate > &&reaction_rates, std::unique_ptr< UserPunch > &&user_punch, std::unique_ptr< Output > &&output, std::unique_ptr< Dump > &&dump, Knobs &&knobs)
 
 ~PhreeqcIO ()
 
void initialize () override
 
void initializeChemicalSystemConcrete (std::vector< double > const &concentrations, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Medium const &medium, ParameterLib::SpatialPosition const &pos, double const t) override
 
void setChemicalSystemConcrete (std::vector< double > const &concentrations, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Medium const *medium, MaterialPropertyLib::VariableArray const &vars, ParameterLib::SpatialPosition const &pos, double const t, double const dt) override
 
void setAqueousSolutionsPrevFromDumpFile () override
 
void executeSpeciationCalculation (double const dt) override
 
double getConcentration (int const component_id, GlobalIndexType const chemical_system_id) const override
 
void updateVolumeFractionPostReaction (GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Medium const &medium, ParameterLib::SpatialPosition const &pos, double const porosity, double const t, double const dt) override
 
void updatePorosityPostReaction (GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Medium const &medium, double &porosity) override
 
void computeSecondaryVariable (std::size_t const ele_id, std::vector< GlobalIndexType > const &chemical_system_indices) override
 
std::vector< std::string > const getComponentList () const override
 
- Public Member Functions inherited from ChemistryLib::ChemicalSolverInterface
 ChemicalSolverInterface (MeshLib::Mesh const &mesh, GlobalLinearSolver &linear_solver_)
 
std::vector< std::size_t > const & getElementIDs ()
 
virtual Eigen::SparseMatrix< double > const * getStoichiometricMatrix () const
 
virtual double getKineticPrefactor (std::size_t reaction_id) const
 
virtual ~ChemicalSolverInterface ()=default
 

Public Attributes

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

Private Member Functions

void writeInputsToFile (double const dt)
 
void callPhreeqc () const
 
void readOutputsFromFile ()
 
PhreeqcIOoperator<< (double const dt)
 

Private Attributes

std::string const _database
 
std::unique_ptr< ChemicalSystem_chemical_system
 
std::vector< ReactionRate > const _reaction_rates
 
std::unique_ptr< UserPunch_user_punch
 
std::unique_ptr< Output > const _output
 
std::unique_ptr< Dump > const _dump
 
Knobs const _knobs
 
double _dt = std::numeric_limits<double>::quiet_NaN()
 
const int phreeqc_instance_id = 0
 
std::size_t _num_chemical_systems = -1
 

Friends

std::ostream & operator<< (std::ostream &os, PhreeqcIO const &phreeqc_io)
 
std::istream & operator>> (std::istream &in, PhreeqcIO &phreeqc_io)
 

Constructor & Destructor Documentation

◆ PhreeqcIO()

ChemistryLib::PhreeqcIOData::PhreeqcIO::PhreeqcIO ( MeshLib::Mesh const & mesh,
GlobalLinearSolver & linear_solver,
std::string const & project_file_name,
std::string && database,
std::unique_ptr< ChemicalSystem > && chemical_system,
std::vector< ReactionRate > && reaction_rates,
std::unique_ptr< UserPunch > && user_punch,
std::unique_ptr< Output > && output,
std::unique_ptr< Dump > && dump,
Knobs && knobs )

Definition at line 265 of file PhreeqcIO.cpp.

276 _phreeqc_input_file(specifyFileName(project_file_name, ".inp")),
277 _database(std::move(database)),
278 _chemical_system(std::move(chemical_system)),
279 _reaction_rates(std::move(reaction_rates)),
280 _user_punch(std::move(user_punch)),
281 _output(std::move(output)),
282 _dump(std::move(dump)),
283 _knobs(std::move(knobs))
284{
285 // initialize phreeqc instance
286 if (CreateIPhreeqc() != phreeqc_instance_id)
287 {
288 OGS_FATAL(
289 "Failed to initialize phreeqc instance, due to lack of memory.");
290 }
291
292 // load specified thermodynamic database
293 if (LoadDatabase(phreeqc_instance_id, _database.c_str()) != IPQ_OK)
294 {
295 OGS_FATAL(
296 "Failed in loading the specified thermodynamic database file: "
297 "{:s}.",
298 _database);
299 }
300
301 if (SetSelectedOutputFileOn(phreeqc_instance_id, 1) != IPQ_OK)
302 {
303 OGS_FATAL(
304 "Failed to fly the flag for the specified file {:s} where phreeqc "
305 "will write output.",
306 _output->basic_output_setups.output_file);
307 }
308
309 if (_dump)
310 {
311 // Chemical composition of the aqueous solution of last time step will
312 // be written into .dmp file once the second function argument is set to
313 // one.
314 SetDumpFileOn(phreeqc_instance_id, 1);
315 }
316}
#define OGS_FATAL(...)
Definition Error.h:26
ChemicalSolverInterface(MeshLib::Mesh const &mesh, GlobalLinearSolver &linear_solver_)
std::unique_ptr< ChemicalSystem > _chemical_system
Definition PhreeqcIO.h:111
std::vector< ReactionRate > const _reaction_rates
Definition PhreeqcIO.h:112
std::unique_ptr< UserPunch > _user_punch
Definition PhreeqcIO.h:113
std::unique_ptr< Dump > const _dump
Definition PhreeqcIO.h:115
std::unique_ptr< Output > const _output
Definition PhreeqcIO.h:114
std::string specifyFileName(std::string const &project_file_name, std::string const &file_extension)
Definition Output.cpp:23

References _database, _dump, _output, OGS_FATAL, and phreeqc_instance_id.

◆ ~PhreeqcIO()

ChemistryLib::PhreeqcIOData::PhreeqcIO::~PhreeqcIO ( )

Definition at line 318 of file PhreeqcIO.cpp.

319{
320 DestroyIPhreeqc(phreeqc_instance_id);
321}

References phreeqc_instance_id.

Member Function Documentation

◆ callPhreeqc()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::callPhreeqc ( ) const
private

Definition at line 639 of file PhreeqcIO.cpp.

640{
641 INFO("Phreeqc: Executing chemical calculation.");
642 if (RunFile(phreeqc_instance_id, _phreeqc_input_file.c_str()) != IPQ_OK)
643 {
644 OutputErrorString(phreeqc_instance_id);
645 OGS_FATAL(
646 "Failed in performing speciation calculation with the generated "
647 "phreeqc input file '{:s}'.",
649 }
650}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35

References _phreeqc_input_file, INFO(), OGS_FATAL, and phreeqc_instance_id.

Referenced by executeSpeciationCalculation().

◆ computeSecondaryVariable()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::computeSecondaryVariable ( std::size_t const ele_id,
std::vector< GlobalIndexType > const & chemical_system_indices )
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 907 of file PhreeqcIO.cpp.

910{
911 for (auto const& kinetic_reactant : _chemical_system->kinetic_reactants)
912 {
913 (*kinetic_reactant.mesh_prop_molality)[ele_id] =
914 averageReactantMolality(kinetic_reactant, chemical_system_indices);
915 }
916
917 for (auto const& equilibrium_reactant :
918 _chemical_system->equilibrium_reactants)
919 {
920 (*equilibrium_reactant.mesh_prop_molality)[ele_id] =
921 averageReactantMolality(equilibrium_reactant,
922 chemical_system_indices);
923 }
924}
static double averageReactantMolality(Reactant const &reactant, std::vector< GlobalIndexType > const &chemical_system_indices)

References _chemical_system.

◆ executeSpeciationCalculation()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::executeSpeciationCalculation ( double const dt)
overridevirtual

◆ getComponentList()

std::vector< std::string > const ChemistryLib::PhreeqcIOData::PhreeqcIO::getComponentList ( ) const
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 857 of file PhreeqcIO.cpp.

858{
859 std::vector<std::string> component_names;
860 auto const& components = _chemical_system->aqueous_solution->components;
861 std::transform(components.begin(), components.end(),
862 std::back_inserter(component_names),
863 [](auto const& c) { return c.name; });
864
865 component_names.push_back("H");
866
867 return component_names;
868}

References _chemical_system.

◆ getConcentration()

double ChemistryLib::PhreeqcIOData::PhreeqcIO::getConcentration ( int const component_id,
GlobalIndexType const chemical_system_id ) const
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 412 of file PhreeqcIO.cpp.

414{
415 auto const& aqueous_solution = *_chemical_system->aqueous_solution;
416 auto& components = aqueous_solution.components;
417 auto const& pH = *aqueous_solution.pH;
418
419 if (component_id < static_cast<int>(components.size()))
420 {
422 *components[component_id].amount);
423
424 return components[component_id].amount->get(chemical_system_id);
425 }
426
427 // pH
428 MathLib::LinAlg::setLocalAccessibleVector(*aqueous_solution.pH);
429
430 return pH.get(chemical_system_id);
431}
void setLocalAccessibleVector(PETScVector const &x)
Definition LinAlg.cpp:27

References _chemical_system, ChemistryLib::PhreeqcIOData::pH, and MathLib::LinAlg::setLocalAccessibleVector().

◆ initialize()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::initialize ( )
overridevirtual

◆ initializeChemicalSystemConcrete()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::initializeChemicalSystemConcrete ( std::vector< double > const & concentrations,
GlobalIndexType const & chemical_system_id,
MaterialPropertyLib::Medium const & medium,
ParameterLib::SpatialPosition const & pos,
double const t )
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 335 of file PhreeqcIO.cpp.

341{
342 setAqueousSolution(concentrations, chemical_system_id,
343 *_chemical_system->aqueous_solution);
344
345 auto const& solid_phase = medium.phase("Solid");
346 auto const& liquid_phase = medium.phase("AqueousLiquid");
347
348 for (auto& kinetic_reactant : _chemical_system->kinetic_reactants)
349 {
350 initializeReactantMolality(kinetic_reactant, chemical_system_id,
351 solid_phase, liquid_phase, medium, pos, t);
352 }
353
354 for (auto& equilibrium_reactant : _chemical_system->equilibrium_reactants)
355 {
356 initializeReactantMolality(equilibrium_reactant, chemical_system_id,
357 solid_phase, liquid_phase, medium, pos, t);
358 }
359
360 for (auto& exchanger : _chemical_system->exchangers)
361 {
362 initializeSiteMolality(exchanger, chemical_system_id, solid_phase, pos,
363 t);
364 }
365
366 for (auto& surface_site : _chemical_system->surface)
367 {
368 if (auto const surface_site_ptr =
369 std::get_if<MoleBasedSurfaceSite>(&surface_site))
370 {
371 initializeSiteMolality(*surface_site_ptr, chemical_system_id,
372 solid_phase, pos, t);
373 }
374 }
375}
void initializeSiteMolality(Site &site, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Phase const &solid_phase, ParameterLib::SpatialPosition const &pos, double const t)
void initializeReactantMolality(Reactant &reactant, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Phase const &solid_phase, MaterialPropertyLib::Phase const &liquid_phase, MaterialPropertyLib::Medium const &medium, ParameterLib::SpatialPosition const &pos, double const t)
Definition PhreeqcIO.cpp:86
void setAqueousSolution(std::vector< double > const &concentrations, GlobalIndexType const &chemical_system_id, AqueousSolution &aqueous_solution)
Definition PhreeqcIO.cpp:62

References _chemical_system, and MaterialPropertyLib::Medium::phase().

◆ operator<<()

PhreeqcIO & ChemistryLib::PhreeqcIOData::PhreeqcIO::operator<< ( double const dt)
inlineprivate

Definition at line 104 of file PhreeqcIO.h.

105 {
106 _dt = dt;
107 return *this;
108 }

References _dt.

◆ readOutputsFromFile()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::readOutputsFromFile ( )
private

Definition at line 652 of file PhreeqcIO.cpp.

653{
654 auto const& basic_output_setups = _output->basic_output_setups;
655 auto const& phreeqc_result_file = basic_output_setups.output_file;
656 DBUG("Reading phreeqc results from file '{:s}'.", phreeqc_result_file);
657 std::ifstream in(phreeqc_result_file);
658
659 if (!in)
660 {
661 OGS_FATAL("Could not open phreeqc result file '{:s}'.",
662 phreeqc_result_file);
663 }
664
665 in >> *this;
666
667 if (!in)
668 {
669 OGS_FATAL("Error when reading phreeqc result file '{:s}'",
670 phreeqc_result_file);
671 }
672
673 in.close();
674}
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30

References _output, DBUG(), and OGS_FATAL.

Referenced by executeSpeciationCalculation().

◆ setAqueousSolutionsPrevFromDumpFile()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::setAqueousSolutionsPrevFromDumpFile ( )
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 433 of file PhreeqcIO.cpp.

434{
435 if (!_dump)
436 {
437 return;
438 }
439
440 auto const& dump_file = _dump->dump_file;
441 std::ifstream in(dump_file);
442 if (!in)
443 {
444 // return if phreeqc dump file doesn't exist. Normally, this happens in
445 // the first time step.
446 return;
447 }
448
449 _dump->readDumpFile(in, _num_chemical_systems);
450
451 if (!in)
452 {
453 OGS_FATAL("Error when reading phreeqc dump file '{:s}'", dump_file);
454 }
455
456 in.close();
457}

References _dump, _num_chemical_systems, and OGS_FATAL.

◆ setChemicalSystemConcrete()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::setChemicalSystemConcrete ( std::vector< double > const & concentrations,
GlobalIndexType const & chemical_system_id,
MaterialPropertyLib::Medium const * medium,
MaterialPropertyLib::VariableArray const & vars,
ParameterLib::SpatialPosition const & pos,
double const t,
double const dt )
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 377 of file PhreeqcIO.cpp.

383{
384 setAqueousSolution(concentrations, chemical_system_id,
385 *_chemical_system->aqueous_solution);
386
387 auto const& solid_phase = medium->phase("Solid");
388 auto const& liquid_phase = medium->phase("AqueousLiquid");
389
390 for (auto& kinetic_reactant : _chemical_system->kinetic_reactants)
391 {
392 setReactantMolality(kinetic_reactant, chemical_system_id, solid_phase,
393 liquid_phase, vars, pos, t, dt);
394 }
395
396 for (auto& equilibrium_reactant : _chemical_system->equilibrium_reactants)
397 {
398 setReactantMolality(equilibrium_reactant, chemical_system_id,
399 solid_phase, liquid_phase, vars, pos, t, dt);
400 }
401}
void setReactantMolality(Reactant &reactant, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Phase const &solid_phase, MaterialPropertyLib::Phase const &liquid_phase, MaterialPropertyLib::VariableArray const &vars, ParameterLib::SpatialPosition const &pos, double const t, double const dt)

References _chemical_system, and MaterialPropertyLib::Medium::phase().

◆ updatePorosityPostReaction()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::updatePorosityPostReaction ( GlobalIndexType const & chemical_system_id,
MaterialPropertyLib::Medium const & medium,
double & porosity )
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 889 of file PhreeqcIO.cpp.

893{
894 for (auto& kinetic_reactant : _chemical_system->kinetic_reactants)
895 {
896 setPorosityPostReaction(kinetic_reactant, chemical_system_id, medium,
897 porosity);
898 }
899
900 for (auto& equilibrium_reactant : _chemical_system->equilibrium_reactants)
901 {
902 setPorosityPostReaction(equilibrium_reactant, chemical_system_id,
903 medium, porosity);
904 }
905}
void setPorosityPostReaction(Reactant &reactant, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Medium const &medium, double &porosity)

References _chemical_system.

◆ updateVolumeFractionPostReaction()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::updateVolumeFractionPostReaction ( GlobalIndexType const & chemical_system_id,
MaterialPropertyLib::Medium const & medium,
ParameterLib::SpatialPosition const & pos,
double const porosity,
double const t,
double const dt )
overridevirtual

Reimplemented from ChemistryLib::ChemicalSolverInterface.

Definition at line 870 of file PhreeqcIO.cpp.

875{
876 for (auto& kinetic_reactant : _chemical_system->kinetic_reactants)
877 {
878 updateReactantVolumeFraction(kinetic_reactant, chemical_system_id,
879 medium, pos, porosity, t, dt);
880 }
881
882 for (auto& equilibrium_reactant : _chemical_system->equilibrium_reactants)
883 {
884 updateReactantVolumeFraction(equilibrium_reactant, chemical_system_id,
885 medium, pos, porosity, t, dt);
886 }
887}
void updateReactantVolumeFraction(Reactant &reactant, GlobalIndexType const &chemical_system_id, MaterialPropertyLib::Medium const &medium, ParameterLib::SpatialPosition const &pos, double const porosity, double const t, double const dt)

References _chemical_system.

◆ writeInputsToFile()

void ChemistryLib::PhreeqcIOData::PhreeqcIO::writeInputsToFile ( double const dt)
private

Definition at line 459 of file PhreeqcIO.cpp.

460{
461 DBUG("Writing phreeqc inputs into file '{:s}'.", _phreeqc_input_file);
462 std::ofstream out(_phreeqc_input_file, std::ofstream::out);
463
464 if (!out)
465 {
466 OGS_FATAL("Could not open file '{:s}' for writing phreeqc inputs.",
468 }
469
470 out << std::scientific
471 << std::setprecision(std::numeric_limits<double>::max_digits10);
472 out << (*this << dt);
473
474 if (!out)
475 {
476 OGS_FATAL("Failed in generating phreeqc input file '{:s}'.",
478 }
479
480 out.close();
481}

References _phreeqc_input_file, DBUG(), and OGS_FATAL.

Referenced by executeSpeciationCalculation().

Friends And Related Symbol Documentation

◆ operator<<

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

Definition at line 483 of file PhreeqcIO.cpp.

484{
485 bool const fixing_pe =
486 phreeqc_io._chemical_system->aqueous_solution->fixing_pe;
487 if (fixing_pe)
488 {
489 os << "PHASES\n"
490 << "Fix_pe\n"
491 << "e- = e-\n"
492 << "log_k 0.0\n\n";
493 }
494
495 os << phreeqc_io._knobs << "\n";
496
497 os << *phreeqc_io._output << "\n";
498
499 auto const& user_punch = phreeqc_io._user_punch;
500 if (user_punch)
501 {
502 os << *user_punch << "\n";
503 }
504
505 auto const& reaction_rates = phreeqc_io._reaction_rates;
506 if (!reaction_rates.empty())
507 {
508 os << "RATES\n";
509 os << reaction_rates << "\n";
510 }
511
512 for (std::size_t chemical_system_id = 0;
513 chemical_system_id < phreeqc_io._num_chemical_systems;
514 ++chemical_system_id)
515 {
516 os << "SOLUTION " << chemical_system_id + 1 << "\n";
517 phreeqc_io._chemical_system->aqueous_solution->print(
518 os, chemical_system_id);
519
520 auto const& dump = phreeqc_io._dump;
521 if (dump)
522 {
523 auto const& aqueous_solutions_prev = dump->aqueous_solutions_prev;
524 if (!aqueous_solutions_prev.empty())
525 {
526 os << aqueous_solutions_prev[chemical_system_id] << "\n\n";
527 }
528 }
529
530 os << "USE solution none\n";
531 os << "END\n\n";
532
533 os << "USE solution " << chemical_system_id + 1 << "\n\n";
534
535 auto const& equilibrium_reactants =
536 phreeqc_io._chemical_system->equilibrium_reactants;
537 if (!equilibrium_reactants.empty() || fixing_pe)
538 {
539 os << "EQUILIBRIUM_PHASES " << chemical_system_id + 1 << "\n";
540 for (auto const& equilibrium_reactant : equilibrium_reactants)
541 {
542 equilibrium_reactant.print(os, chemical_system_id);
543 }
544 fixing_pe
545 ? os << "Fix_pe "
546 << -phreeqc_io._chemical_system->aqueous_solution->pe0
547 << " O2(g)\n\n"
548 : os << "\n";
549 }
550
551 auto const& kinetic_reactants =
552 phreeqc_io._chemical_system->kinetic_reactants;
553 if (!kinetic_reactants.empty())
554 {
555 os << "KINETICS " << chemical_system_id + 1 << "\n";
556 for (auto const& kinetic_reactant : kinetic_reactants)
557 {
558 kinetic_reactant.print(os, chemical_system_id);
559 }
560 os << "-steps " << phreeqc_io._dt << "\n\n";
561 }
562
563 auto const& surface = phreeqc_io._chemical_system->surface;
564 if (!surface.empty())
565 {
566 os << "SURFACE " << chemical_system_id + 1 << "\n";
567 std::size_t aqueous_solution_id =
568 dump->aqueous_solutions_prev.empty()
569 ? chemical_system_id + 1
570 : phreeqc_io._num_chemical_systems + chemical_system_id + 1;
571 os << "-equilibrate with solution " << aqueous_solution_id << "\n";
572
573 // print unit
574 if (std::holds_alternative<DensityBasedSurfaceSite>(
575 surface.front()))
576 {
577 os << "-sites_units density\n";
578 }
579 else
580 {
581 os << "-sites_units absolute\n";
582 }
583
584 for (auto const& surface_site : surface)
585 {
586 std::visit(
587 overloaded{[&os](DensityBasedSurfaceSite const& s)
588 {
589 os << s.name << " " << s.site_density << " "
590 << s.specific_surface_area << " "
591 << s.mass << "\n";
592 },
593 [&os, chemical_system_id](
594 MoleBasedSurfaceSite const& s) {
595 os << s.name << " "
596 << (*s.molality)[chemical_system_id]
597 << "\n";
598 }},
599 surface_site);
600 }
601
602 // overlook the effect of the buildup of charges onto the surface
603 if (std::holds_alternative<MoleBasedSurfaceSite>(surface.front()))
604 {
605 os << "-no_edl\n";
606 }
607
608 os << "SAVE solution " << chemical_system_id + 1 << "\n";
609 }
610
611 auto const& exchangers = phreeqc_io._chemical_system->exchangers;
612 if (!exchangers.empty())
613 {
614 os << "EXCHANGE " << chemical_system_id + 1 << "\n";
615 std::size_t const aqueous_solution_id =
616 dump->aqueous_solutions_prev.empty()
617 ? chemical_system_id + 1
618 : phreeqc_io._num_chemical_systems + chemical_system_id + 1;
619 os << "-equilibrate with solution " << aqueous_solution_id << "\n";
620 for (auto const& exchanger : exchangers)
621 {
622 exchanger.print(os, chemical_system_id);
623 }
624 os << "SAVE solution " << chemical_system_id + 1 << "\n";
625 }
626
627 os << "END\n\n";
628 }
629
630 auto const& dump = phreeqc_io._dump;
631 if (dump)
632 {
633 dump->print(os, phreeqc_io._num_chemical_systems);
634 }
635
636 return os;
637}

◆ operator>>

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

Definition at line 676 of file PhreeqcIO.cpp.

677{
678 // Skip the headline
679 in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
680
681 std::string line;
682 auto const& output = *phreeqc_io._output;
683 auto const& dropped_item_ids = output.dropped_item_ids;
684
685 auto const& surface = phreeqc_io._chemical_system->surface;
686 auto const& exchangers = phreeqc_io._chemical_system->exchangers;
687
688 int const num_skipped_lines =
689 1 + (!surface.empty() ? 1 : 0) + (!exchangers.empty() ? 1 : 0);
690
691 auto& equilibrium_reactants =
692 phreeqc_io._chemical_system->equilibrium_reactants;
693 auto& kinetic_reactants = phreeqc_io._chemical_system->kinetic_reactants;
694
695 for (std::size_t chemical_system_id = 0;
696 chemical_system_id < phreeqc_io._num_chemical_systems;
697 ++chemical_system_id)
698 {
699 // Skip equilibrium calculation result of initial solution
700 for (int i = 0; i < num_skipped_lines; ++i)
701 {
702 in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
703 }
704
705 // Get calculation result of the solution after the reaction
706 if (!std::getline(in, line))
707 {
708 OGS_FATAL(
709 "Error when reading calculation result of Solution {:d} "
710 "after the reaction.",
711 chemical_system_id);
712 }
713
714 std::vector<double> accepted_items;
715 std::vector<std::string> items;
716 boost::trim_if(line, boost::is_any_of("\t "));
717 boost::algorithm::split(items, line, boost::is_any_of("\t "),
718 boost::token_compress_on);
719 for (int item_id = 0; item_id < static_cast<int>(items.size());
720 ++item_id)
721 {
722 if (std::find(dropped_item_ids.begin(), dropped_item_ids.end(),
723 item_id) == dropped_item_ids.end())
724 {
725 double value;
726 try
727 {
728 value = std::stod(items[item_id]);
729 }
730 catch (const std::invalid_argument& e)
731 {
732 OGS_FATAL(
733 "Invalid argument. Could not convert string '{:s}' to "
734 "double for chemical system {:d}, column {:d}. "
735 "Exception '{:s}' was thrown.",
736 items[item_id], chemical_system_id + 1, item_id,
737 e.what());
738 }
739 catch (const std::out_of_range& e)
740 {
741 OGS_FATAL(
742 "Out of range error. Could not convert string "
743 "'{:s}' to double for chemical system {:d}, column "
744 "{:d}. Exception '{:s}' was thrown.",
745 items[item_id], chemical_system_id + 1, item_id,
746 e.what());
747 }
748 accepted_items.push_back(value);
749 }
750 }
751 assert(accepted_items.size() == output.accepted_items.size());
752
753 auto& aqueous_solution = phreeqc_io._chemical_system->aqueous_solution;
754 auto& components = aqueous_solution->components;
755 auto& user_punch = phreeqc_io._user_punch;
756
757 GlobalIndexType const offset = aqueous_solution->pH->getRangeBegin();
758 GlobalIndexType const global_index = offset + chemical_system_id;
759
760 for (int item_id = 0; item_id < static_cast<int>(accepted_items.size());
761 ++item_id)
762 {
763 auto const& accepted_item = output.accepted_items[item_id];
764 auto const& item_name = accepted_item.name;
765
766 auto compare_by_name = [&item_name](auto const& item)
767 { return item.name == item_name; };
768
769 switch (accepted_item.item_type)
770 {
771 case ItemType::pH:
772 {
773 // Update pH value
775 *aqueous_solution->pH);
776 aqueous_solution->pH->set(
777 global_index, std::pow(10, -accepted_items[item_id]));
778 break;
779 }
780 case ItemType::pe:
781 {
782 // Update pe value
783 (*aqueous_solution->pe)[chemical_system_id] =
784 accepted_items[item_id];
785 break;
786 }
788 {
789 // Update component concentrations
790 auto const& component = BaseLib::findElementOrError(
791 components, compare_by_name,
792 [&]() {
793 OGS_FATAL("Could not find component '{:s}'.",
794 item_name);
795 });
797 *component.amount);
798 component.amount->set(global_index,
799 accepted_items[item_id]);
800 break;
801 }
803 {
804 // Update amounts of equilibrium reactant
805 auto const& equilibrium_reactant =
807 equilibrium_reactants, compare_by_name,
808 [&]()
809 {
810 OGS_FATAL(
811 "Could not find equilibrium reactant "
812 "'{:s}'",
813 item_name);
814 });
815 (*equilibrium_reactant.molality)[chemical_system_id] =
816 accepted_items[item_id];
817 break;
818 }
820 {
821 // Update amounts of kinetic reactants
822 auto const& kinetic_reactant = BaseLib::findElementOrError(
823 kinetic_reactants, compare_by_name,
824 [&]() {
825 OGS_FATAL("Could not find kinetic reactant '{:s}'.",
826 item_name);
827 });
828 (*kinetic_reactant.molality)[chemical_system_id] =
829 accepted_items[item_id];
830 break;
831 }
833 {
834 assert(user_punch);
835 auto const& secondary_variables =
836 user_punch->secondary_variables;
837 // Update values of secondary variables
838 auto const& secondary_variable =
840 secondary_variables, compare_by_name,
841 [&]() {
842 OGS_FATAL(
843 "Could not find secondary variable '{:s}'.",
844 item_name);
845 });
846 (*secondary_variable.value)[chemical_system_id] =
847 accepted_items[item_id];
848 break;
849 }
850 }
851 }
852 }
853
854 return in;
855}
GlobalMatrix::IndexType GlobalIndexType
ranges::range_reference_t< Range > findElementOrError(Range &range, std::predicate< ranges::range_reference_t< Range > > auto &&predicate, std::invocable auto error_callback)
Definition Algorithm.h:81

Member Data Documentation

◆ _chemical_system

◆ _database

std::string const ChemistryLib::PhreeqcIOData::PhreeqcIO::_database
private

Definition at line 110 of file PhreeqcIO.h.

Referenced by PhreeqcIO().

◆ _dt

double ChemistryLib::PhreeqcIOData::PhreeqcIO::_dt = std::numeric_limits<double>::quiet_NaN()
private

Definition at line 117 of file PhreeqcIO.h.

Referenced by operator<<().

◆ _dump

std::unique_ptr<Dump> const ChemistryLib::PhreeqcIOData::PhreeqcIO::_dump
private

Definition at line 115 of file PhreeqcIO.h.

Referenced by PhreeqcIO(), and setAqueousSolutionsPrevFromDumpFile().

◆ _knobs

Knobs const ChemistryLib::PhreeqcIOData::PhreeqcIO::_knobs
private

Definition at line 116 of file PhreeqcIO.h.

◆ _num_chemical_systems

std::size_t ChemistryLib::PhreeqcIOData::PhreeqcIO::_num_chemical_systems = -1
private

Definition at line 119 of file PhreeqcIO.h.

Referenced by initialize(), and setAqueousSolutionsPrevFromDumpFile().

◆ _output

std::unique_ptr<Output> const ChemistryLib::PhreeqcIOData::PhreeqcIO::_output
private

Definition at line 114 of file PhreeqcIO.h.

Referenced by PhreeqcIO(), and readOutputsFromFile().

◆ _phreeqc_input_file

std::string const ChemistryLib::PhreeqcIOData::PhreeqcIO::_phreeqc_input_file

Definition at line 95 of file PhreeqcIO.h.

Referenced by callPhreeqc(), and writeInputsToFile().

◆ _reaction_rates

std::vector<ReactionRate> const ChemistryLib::PhreeqcIOData::PhreeqcIO::_reaction_rates
private

Definition at line 112 of file PhreeqcIO.h.

◆ _user_punch

std::unique_ptr<UserPunch> ChemistryLib::PhreeqcIOData::PhreeqcIO::_user_punch
private

Definition at line 113 of file PhreeqcIO.h.

Referenced by initialize().

◆ phreeqc_instance_id

const int ChemistryLib::PhreeqcIOData::PhreeqcIO::phreeqc_instance_id = 0
private

Definition at line 118 of file PhreeqcIO.h.

Referenced by PhreeqcIO(), ~PhreeqcIO(), and callPhreeqc().


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