diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp index de6d45adaa8c46c7ad637ac92f0e7d2bf29ae164..eda8957dedad4d50459ba217404e26cbd5b9e82b 100644 --- a/Applications/ApplicationsLib/ProjectData.cpp +++ b/Applications/ApplicationsLib/ProjectData.cpp @@ -38,6 +38,10 @@ #include "ProcessLib/CreateJacobianAssembler.h" #include "ProcessLib/DeactivatedSubdomain.h" +// PhreeqcIO +#include "ChemistryLib/CreatePhreeqcIO.h" +#include "ProcessLib/ComponentTransport/ComponentTransportProcess.h" + // FileIO #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h" #include "MeshLib/IO/readMeshFromFile.h" @@ -338,6 +342,11 @@ ProjectData::ProjectData(BaseLib::ConfigTree const& project_config, //! \ogs_file_param{prj__nonlinear_solvers} parseNonlinearSolvers(project_config.getConfigSubtree("nonlinear_solvers")); + parseChemicalSystem( + //! \ogs_file_param{prj__chemical_system} + project_config.getConfigSubtreeOptional("chemical_system"), + output_directory); + //! \ogs_file_param{prj__time_loop} parseTimeLoop(project_config.getConfigSubtree("time_loop"), output_directory); @@ -923,8 +932,9 @@ void ProjectData::parseTimeLoop(BaseLib::ConfigTree const& config, { DBUG("Reading time loop configuration."); - _time_loop = ProcessLib::createTimeLoop( - config, output_directory, _processes, _nonlinear_solvers, _mesh_vec); + _time_loop = ProcessLib::createTimeLoop(config, output_directory, + _processes, _nonlinear_solvers, + _mesh_vec, _chemical_system); if (!_time_loop) { @@ -996,3 +1006,52 @@ void ProjectData::parseCurves( "The curve name is not unique."); } } + +void ProjectData::parseChemicalSystem( + boost::optional<BaseLib::ConfigTree> const& config, + std::string const& output_directory) +{ + if (!config) + return; + + INFO( + "Ready for initializing interface to a chemical solver for water " + "chemistry calculation."); + + auto const& process = _processes.begin()->second; + if (auto const* component_transport_process = dynamic_cast< + ProcessLib::ComponentTransport::ComponentTransportProcess const*>( + process.get())) + { + auto const chemical_solver = + //! \ogs_file_attr{prj__chemical_system__chemical_solver} + config->getConfigAttribute<std::string>("chemical_solver"); + + if (boost::iequals(chemical_solver, "Phreeqc")) + { + INFO( + "Configuring phreeqc interface for water chemistry " + "calculation."); + + auto const& process_id_to_component_name_map = + component_transport_process->getProcessIDToComponentNameMap(); + + _chemical_system = ChemistryLib::createPhreeqcIO( + _mesh_vec[0]->getNumberOfBaseNodes(), + process_id_to_component_name_map, config, output_directory); + } + else + { + OGS_FATAL( + "Unknown chemical solver. Please specify Phreeqc as the solver " + "for water chemistry calculation instead."); + } + } + else + { + OGS_FATAL( + "The specified type of the process to be solved is not component " + "transport process so that water chemistry calculation could not " + "be activated."); + } +} diff --git a/Applications/ApplicationsLib/ProjectData.h b/Applications/ApplicationsLib/ProjectData.h index b319c3341ff2c285030afd1bccaccea57e29c29e..a488bc280e9965d5d7710aebe2d28c037f2a872a 100644 --- a/Applications/ApplicationsLib/ProjectData.h +++ b/Applications/ApplicationsLib/ProjectData.h @@ -21,6 +21,7 @@ #include "MaterialLib/MPL/Medium.h" #include "MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h" +#include "ChemistryLib/PhreeqcIO.h" #include "ParameterLib/CoordinateSystem.h" #include "ParameterLib/Parameter.h" #include "ProcessLib/Process.h" @@ -112,6 +113,9 @@ private: void parseCurves(boost::optional<BaseLib::ConfigTree> const& config); + void parseChemicalSystem(boost::optional<BaseLib::ConfigTree> const& config, + const std::string& output_directory); + std::unique_ptr<MaterialPropertyLib::Medium> _medium; std::vector<std::unique_ptr<MeshLib::Mesh>> _mesh_vec; std::map<std::string, std::unique_ptr<ProcessLib::Process>> _processes; @@ -134,4 +138,6 @@ private: std::map<std::string, std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> _curves; + + std::unique_ptr<ChemistryLib::PhreeqcIO> _chemical_system; }; diff --git a/ProcessLib/CreateTimeLoop.cpp b/ProcessLib/CreateTimeLoop.cpp index 9a0de21c25335c649a53a6a9f3bd8f242d6edb09..71bbe024db3f7efd8e962efeec52cf03a5821b12 100644 --- a/ProcessLib/CreateTimeLoop.cpp +++ b/ProcessLib/CreateTimeLoop.cpp @@ -25,7 +25,8 @@ std::unique_ptr<TimeLoop> createTimeLoop( const std::map<std::string, std::unique_ptr<Process>>& processes, const std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>>& nonlinear_solvers, - std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes) + std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes, + std::unique_ptr<ChemistryLib::PhreeqcIO>& phreeqc_io) { auto const& coupling_config //! \ogs_file_param{prj__time_loop__global_process_coupling} @@ -93,6 +94,7 @@ std::unique_ptr<TimeLoop> createTimeLoop( return std::make_unique<TimeLoop>( std::move(output), std::move(per_process_data), max_coupling_iterations, - std::move(global_coupling_conv_criteria), start_time, end_time); + std::move(global_coupling_conv_criteria), std::move(phreeqc_io), + start_time, end_time); } } // namespace ProcessLib diff --git a/ProcessLib/CreateTimeLoop.h b/ProcessLib/CreateTimeLoop.h index 86f6d9d89316e045d4b6210da5114a0f5620c647..167e0e68ccbdff2b6f2759890989b7c46b5233cb 100644 --- a/ProcessLib/CreateTimeLoop.h +++ b/ProcessLib/CreateTimeLoop.h @@ -31,6 +31,11 @@ namespace NumLib class NonlinearSolverBase; } +namespace ChemistryLib +{ +class PhreeqcIO; +} + namespace ProcessLib { class TimeLoop; @@ -45,6 +50,7 @@ std::unique_ptr<TimeLoop> createTimeLoop( std::map<std::string, std::unique_ptr<Process>> const& processes, std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>> const& nonlinear_solvers, - std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes); + std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes, + std::unique_ptr<ChemistryLib::PhreeqcIO>& phreeqc_io); } // namespace ProcessLib diff --git a/ProcessLib/TimeLoop.cpp b/ProcessLib/TimeLoop.cpp index 116280db9a04926fb299ebefe9a9c07a7de39e48..efd338064c41049e84609ea894d55f7a48ca85da 100644 --- a/ProcessLib/TimeLoop.cpp +++ b/ProcessLib/TimeLoop.cpp @@ -13,9 +13,12 @@ #include "BaseLib/Error.h" #include "BaseLib/RunTime.h" +#include "ChemistryLib/CreatePhreeqcIO.h" #include "MathLib/LinAlg/LinAlg.h" #include "NumLib/ODESolver/ConvergenceCriterionPerComponent.h" #include "NumLib/ODESolver/TimeDiscretizedODESystem.h" +#include "ProcessLib/CreateProcessData.h" +#include "ProcessLib/Output/CreateOutput.h" #include "CoupledSolutionsForStaggeredScheme.h" #include "ProcessData.h" @@ -207,13 +210,15 @@ TimeLoop::TimeLoop(std::unique_ptr<Output>&& output, const int global_coupling_max_iterations, std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>>&& global_coupling_conv_crit, + std::unique_ptr<ChemistryLib::PhreeqcIO>&& chemical_system, const double start_time, const double end_time) : _output(std::move(output)), _per_process_data(std::move(per_process_data)), _start_time(start_time), _end_time(end_time), _global_coupling_max_iterations(global_coupling_max_iterations), - _global_coupling_conv_crit(std::move(global_coupling_conv_crit)) + _global_coupling_conv_crit(std::move(global_coupling_conv_crit)), + _chemical_system(std::move(chemical_system)) { } diff --git a/ProcessLib/TimeLoop.h b/ProcessLib/TimeLoop.h index 1aca083d9d4d028e538e078e0faad20aea92b6d3..3597dad777aa5fce738434303a4df8432b5a8d51 100644 --- a/ProcessLib/TimeLoop.h +++ b/ProcessLib/TimeLoop.h @@ -27,6 +27,11 @@ namespace NumLib class ConvergenceCriterion; } +namespace ChemistryLib +{ +class PhreeqcIO; +} + namespace ProcessLib { struct ProcessData; @@ -40,6 +45,7 @@ public: const int global_coupling_max_iterations, std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>>&& global_coupling_conv_crit, + std::unique_ptr<ChemistryLib::PhreeqcIO>&& chemical_system, const double start_time, const double end_time); bool loop(); @@ -124,6 +130,7 @@ private: std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>> _global_coupling_conv_crit; + std::unique_ptr<ChemistryLib::PhreeqcIO> _chemical_system; /** * Vector of solutions of the coupled processes. * Each vector element stores the references of the solution vectors