From 9cb2aba57a91198f07940102b083d00fe9ffe51c Mon Sep 17 00:00:00 2001 From: Max Luebke Date: Sat, 9 Mar 2024 23:51:15 +0100 Subject: [PATCH] Add SolutionMapping struct and related methods to IPhreeqc and IPhreeqcPOET classes --- poet/include/IPhreeqcPOET.hpp | 14 +- poet/src/IPhreeqcPOET.cpp | 75 ++++---- src/IPhreeqc.cpp | 312 +++++++++++++++++----------------- src/IPhreeqc.hpp | 14 +- 4 files changed, 213 insertions(+), 202 deletions(-) diff --git a/poet/include/IPhreeqcPOET.hpp b/poet/include/IPhreeqcPOET.hpp index eefdf215..0d278647 100644 --- a/poet/include/IPhreeqcPOET.hpp +++ b/poet/include/IPhreeqcPOET.hpp @@ -13,7 +13,7 @@ #include #include -class IPhreeqcModule : public IPhreeqc { +class IPhreeqcPOET : public IPhreeqc { public: std::vector get_essential_values(std::size_t cell_number, @@ -23,13 +23,12 @@ public: const std::vector &order, std::vector &values); - IPhreeqcModule(const std::string &database, const std::string &input_script, - const std::vector &ids) + IPhreeqcPOET(const std::string &database, const std::string &input_script) : IPhreeqc() { this->LoadDatabase(database.c_str()); this->RunFile(input_script.c_str()); - this->parseInitValues(ids); + this->parseInitValues(); } std::vector getInitNames() const { @@ -55,7 +54,7 @@ private: std::vector> initial_concentrations; std::vector solution_ids; - void parseInitValues(const std::vector &ids); + void parseInitValues(); essential_names dump_essential_names(std::size_t cell_number); @@ -80,6 +79,11 @@ private: return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_surface_map(), n); } + void resolveSolutionUseKW( + const std::vector &unresolved, + std::map>> + &mapped_values); + void valuesFromModule(const std::string &module_name, int cell_number, essential_names &names, std::vector &values); diff --git a/poet/src/IPhreeqcPOET.cpp b/poet/src/IPhreeqcPOET.cpp index 6137f05d..131848eb 100644 --- a/poet/src/IPhreeqcPOET.cpp +++ b/poet/src/IPhreeqcPOET.cpp @@ -38,9 +38,9 @@ createConcVector(const std::vector &conc_names, return conc_vec; } -void IPhreeqcModule::valuesFromModule(const std::string &module_name, - int cell_number, essential_names &names, - std::vector &values) { +void IPhreeqcPOET::valuesFromModule(const std::string &module_name, + int cell_number, essential_names &names, + std::vector &values) { std::size_t dest_module_i = 0; std::vector to_insert; if (module_name == "exchange") { // 1 @@ -65,33 +65,32 @@ void IPhreeqcModule::valuesFromModule(const std::string &module_name, values.insert(values.begin() + offset, to_insert.begin(), to_insert.end()); } -// void IPhreeqcModule::resolveSolutionUseKW( -// const std::vector &unresolved, -// std::map>> -// &mapped_values) { +void IPhreeqcPOET::resolveSolutionUseKW( + const std::vector &unresolved, + std::map>> + &mapped_values) { -// for (const auto &input : unresolved) { -// if (mapped_values.find(input.module_n) != mapped_values.end()) { -// continue; -// } + for (const auto &input : unresolved) { + if (mapped_values.find(input.module_n) != mapped_values.end()) { + continue; + } -// essential_names new_conc_names; -// new_conc_names[0] = mapped_values[input.sol_n].first[0]; + essential_names new_conc_names; + new_conc_names[0] = mapped_values[input.sol_n].first[0]; -// const auto &curr_sol_vec = mapped_values[input.sol_n].second; -// std::vector new_conc_values( -// curr_sol_vec.begin(), curr_sol_vec.begin() + -// new_conc_names[0].size()); + const auto &curr_sol_vec = mapped_values[input.sol_n].second; + std::vector new_conc_values( + curr_sol_vec.begin(), curr_sol_vec.begin() + new_conc_names[0].size()); -// valuesFromModule(input.module_name, input.module_n, new_conc_names, -// new_conc_values); + valuesFromModule(input.module_name, input.module_n, new_conc_names, + new_conc_values); -// mapped_values[input.module_n] = -// std::make_pair(new_conc_names, new_conc_values); -// } -// } + mapped_values[input.module_n] = + std::make_pair(new_conc_names, new_conc_values); + } +} -void IPhreeqcModule::parseInitValues(const std::vector &ids) { +void IPhreeqcPOET::parseInitValues() { std::map>> init_values; @@ -107,20 +106,20 @@ void IPhreeqcModule::parseInitValues(const std::vector &ids) { curr_conc_names, this->get_essential_values(id, curr_conc_names[0])); } - // const auto unresolved_modules = this->getSolutionMapping(); - // resolveSolutionUseKW(unresolved_modules, init_values); + const auto unresolved_modules = this->getSolutionMapping(); + resolveSolutionUseKW(unresolved_modules, init_values); std::vector ids_to_erase; // loop over found initial values and erase those that are not in the ids for (const auto &[id, values] : init_values) { // find key in vector of ids - auto it = std::find(ids.begin(), ids.end(), id); + // auto it = std::find(ids.begin(), ids.end(), id); - if (it == ids.end()) { - ids_to_erase.push_back(id); - continue; - } + // if (it == ids.end()) { + // ids_to_erase.push_back(id); + // continue; + // } // create a union of all known concentration names for (std::size_t i = 0; i < 5; i++) { @@ -185,8 +184,8 @@ void IPhreeqcModule::parseInitValues(const std::vector &ids) { // } } -IPhreeqcModule::essential_names -IPhreeqcModule::dump_essential_names(std::size_t cell_number) { +IPhreeqcPOET::essential_names +IPhreeqcPOET::dump_essential_names(std::size_t cell_number) { essential_names eNames; @@ -224,8 +223,8 @@ IPhreeqcModule::dump_essential_names(std::size_t cell_number) { } std::vector -IPhreeqcModule::get_essential_values(std::size_t cell_number, - const std::vector &order) { +IPhreeqcPOET::get_essential_values(std::size_t cell_number, + const std::vector &order) { std::vector essentials; // Solutions @@ -271,9 +270,9 @@ IPhreeqcModule::get_essential_values(std::size_t cell_number, return essentials; } -void IPhreeqcModule::set_essential_values(std::size_t cell_number, - const std::vector &order, - std::vector &values) { +void IPhreeqcPOET::set_essential_values(std::size_t cell_number, + const std::vector &order, + std::vector &values) { auto dump_it = values.begin(); diff --git a/src/IPhreeqc.cpp b/src/IPhreeqc.cpp index 11f57a0a..f244839c 100644 --- a/src/IPhreeqc.cpp +++ b/src/IPhreeqc.cpp @@ -1,201 +1,162 @@ -#include // auto_ptr -#include -#include -#include "IPhreeqc.hpp" // IPhreeqc -#include "Phreeqc.h" // Phreeqc -#include "thread.h" +#include "IPhreeqc.hpp" // IPhreeqc +#include "Phreeqc.h" // Phreeqc #include "Version.h" +#include "thread.h" +#include +#include // auto_ptr +#include -#include "Debug.h" // ASSERT -#include "ErrorReporter.hxx" // CErrorReporter -#include "CSelectedOutput.hxx" // CSelectedOutput -#include "SelectedOutput.h" // SelectedOutput -#include "dumper.h" // dumper +#include "CSelectedOutput.hxx" // CSelectedOutput +#include "Debug.h" // ASSERT +#include "ErrorReporter.hxx" // CErrorReporter +#include "SelectedOutput.h" // SelectedOutput +#include "dumper.h" // dumper // statics -std::map IPhreeqc::Instances; +std::map IPhreeqc::Instances; size_t IPhreeqc::InstancesIndex = 0; std::string IPhreeqc::Version(VERSION_STRING); static const char empty[] = ""; - IPhreeqc::IPhreeqc(void) -: DatabaseLoaded(false) -, ClearAccumulated(false) -, UpdateComponents(true) -, OutputFileOn(false) -, LogFileOn(false) -, ErrorFileOn(false) -, DumpOn(false) -, DumpStringOn(false) -, OutputStringOn(false) -, LogStringOn(false) -, ErrorStringOn(true) -, ErrorReporter(0) -, WarningStringOn(true) -, WarningReporter(0) -, CurrentSelectedOutputUserNumber(1) -, PhreeqcPtr(0) -, input_file(0) -, database_file(0) -{ - this->ErrorReporter = new CErrorReporter; - this->WarningReporter = new CErrorReporter; - this->PhreeqcPtr = new Phreeqc(this); + : DatabaseLoaded(false), ClearAccumulated(false), UpdateComponents(true), + OutputFileOn(false), LogFileOn(false), ErrorFileOn(false), DumpOn(false), + DumpStringOn(false), OutputStringOn(false), LogStringOn(false), + ErrorStringOn(true), ErrorReporter(0), WarningStringOn(true), + WarningReporter(0), CurrentSelectedOutputUserNumber(1), PhreeqcPtr(0), + input_file(0), database_file(0) { + this->ErrorReporter = new CErrorReporter; + this->WarningReporter = new CErrorReporter; + this->PhreeqcPtr = new Phreeqc(this); - ASSERT(this->PhreeqcPtr->phast == 0); - this->UnLoadDatabase(); + ASSERT(this->PhreeqcPtr->phast == 0); + this->UnLoadDatabase(); - mutex_lock(&map_lock); - this->Index = IPhreeqc::InstancesIndex++; - std::map::value_type instance(this->Index, this); - /*std::pair::iterator, bool> pr = */IPhreeqc::Instances.insert(instance); - mutex_unlock(&map_lock); + mutex_lock(&map_lock); + this->Index = IPhreeqc::InstancesIndex++; + std::map::value_type instance(this->Index, this); + /*std::pair::iterator, bool> pr = */ IPhreeqc:: + Instances.insert(instance); + mutex_unlock(&map_lock); - this->SelectedOutputStringOn[1] = false; + this->SelectedOutputStringOn[1] = false; - this->SelectedOutputFileOnMap[1] = false; - this->SelectedOutputFileNameMap[1] = this->sel_file_name(1); - - this->OutputFileName = create_file_name("phreeqc", "out"); - this->ErrorFileName = create_file_name("phreeqc", "err"); - this->LogFileName = create_file_name("phreeqc", "log"); + this->SelectedOutputFileOnMap[1] = false; + this->SelectedOutputFileNameMap[1] = this->sel_file_name(1); - this->DumpFileName = create_file_name("dump", "out"); - this->PhreeqcPtr->dump_info.Set_file_name(this->DumpFileName); + this->OutputFileName = create_file_name("phreeqc", "out"); + this->ErrorFileName = create_file_name("phreeqc", "err"); + this->LogFileName = create_file_name("phreeqc", "log"); + + this->DumpFileName = create_file_name("dump", "out"); + this->PhreeqcPtr->dump_info.Set_file_name(this->DumpFileName); } -IPhreeqc::~IPhreeqc(void) -{ +IPhreeqc::~IPhreeqc(void) { #if !defined(NDEBUG) - this->OutputFileOn = false; + this->OutputFileOn = false; #endif - delete this->PhreeqcPtr; - delete this->WarningReporter; - delete this->ErrorReporter; + delete this->PhreeqcPtr; + delete this->WarningReporter; + delete this->ErrorReporter; - std::map< int, CSelectedOutput* >::iterator sit = this->SelectedOutputMap.begin(); - for (; sit != this->SelectedOutputMap.end(); ++sit) - { - delete (*sit).second; - } - this->SelectedOutputMap.clear(); + std::map::iterator sit = + this->SelectedOutputMap.begin(); + for (; sit != this->SelectedOutputMap.end(); ++sit) { + delete (*sit).second; + } + this->SelectedOutputMap.clear(); - mutex_lock(&map_lock); - std::map::iterator it = IPhreeqc::Instances.find(this->Index); - if (it != IPhreeqc::Instances.end()) - { - IPhreeqc::Instances.erase(it); - } - mutex_unlock(&map_lock); + mutex_lock(&map_lock); + std::map::iterator it = + IPhreeqc::Instances.find(this->Index); + if (it != IPhreeqc::Instances.end()) { + IPhreeqc::Instances.erase(it); + } + mutex_unlock(&map_lock); } -VRESULT IPhreeqc::AccumulateLine(const char *line) -{ - try - { - if (this->ClearAccumulated) - { - this->ClearAccumulatedLines(); - this->ClearAccumulated = false; - } +VRESULT IPhreeqc::AccumulateLine(const char *line) { + try { + if (this->ClearAccumulated) { + this->ClearAccumulatedLines(); + this->ClearAccumulated = false; + } - this->ErrorReporter->Clear(); - this->WarningReporter->Clear(); - this->StringInput.append(line); - this->StringInput.append("\n"); - return VR_OK; - } - catch (...) - { - this->AddError("AccumulateLine: An unhandled exception occured.\n"); - throw; - } - return VR_OUTOFMEMORY; + this->ErrorReporter->Clear(); + this->WarningReporter->Clear(); + this->StringInput.append(line); + this->StringInput.append("\n"); + return VR_OK; + } catch (...) { + this->AddError("AccumulateLine: An unhandled exception occured.\n"); + throw; + } + return VR_OUTOFMEMORY; } -size_t IPhreeqc::AddError(const char* str) -{ - return this->ErrorReporter->AddError(str); +size_t IPhreeqc::AddError(const char *str) { + return this->ErrorReporter->AddError(str); } -size_t IPhreeqc::AddWarning(const char* str) -{ - return this->WarningReporter->AddError(str); +size_t IPhreeqc::AddWarning(const char *str) { + return this->WarningReporter->AddError(str); } -void IPhreeqc::ClearAccumulatedLines(void) -{ - this->StringInput.erase(); +void IPhreeqc::ClearAccumulatedLines(void) { this->StringInput.erase(); } + +const std::string &IPhreeqc::GetAccumulatedLines(void) { + return this->StringInput; } -const std::string& IPhreeqc::GetAccumulatedLines(void) -{ - return this->StringInput; +const char *IPhreeqc::GetComponent(int n) { + static const char empty[] = ""; + this->ListComponents(); + if (n < 0 || n >= (int)this->Components.size()) { + return empty; + } + std::list::iterator it = this->Components.begin(); + for (int i = 0; i < n; ++i) { + ++it; + } + return (*it).c_str(); } -const char* IPhreeqc::GetComponent(int n) -{ - static const char empty[] = ""; - this->ListComponents(); - if (n < 0 || n >= (int)this->Components.size()) - { - return empty; - } - std::list< std::string >::iterator it = this->Components.begin(); - for(int i = 0; i < n; ++i) - { - ++it; - } - return (*it).c_str(); +size_t IPhreeqc::GetComponentCount(void) { + this->ListComponents(); + return this->Components.size(); } -size_t IPhreeqc::GetComponentCount(void) -{ - this->ListComponents(); - return this->Components.size(); +int IPhreeqc::GetCurrentSelectedOutputUserNumber(void) const { + return this->CurrentSelectedOutputUserNumber; } -int IPhreeqc::GetCurrentSelectedOutputUserNumber(void)const -{ - return this->CurrentSelectedOutputUserNumber; +const char *IPhreeqc::GetDumpFileName(void) const { + return this->DumpFileName.c_str(); } -const char* IPhreeqc::GetDumpFileName(void)const -{ - return this->DumpFileName.c_str(); +bool IPhreeqc::GetDumpFileOn(void) const { return this->DumpOn; } + +const char *IPhreeqc::GetDumpString(void) const { + static const char err_msg[] = "GetDumpString: DumpStringOn not set.\n"; + if (!this->DumpStringOn) { + return err_msg; + } + return this->DumpString.c_str(); } -bool IPhreeqc::GetDumpFileOn(void)const -{ - return this->DumpOn; +const char *IPhreeqc::GetDumpStringLine(int n) { + static const char empty[] = ""; + if (n < 0 || n >= this->GetDumpStringLineCount()) { + return empty; + } + return this->DumpLines[n].c_str(); } -const char* IPhreeqc::GetDumpString(void)const -{ - static const char err_msg[] = "GetDumpString: DumpStringOn not set.\n"; - if (!this->DumpStringOn) - { - return err_msg; - } - return this->DumpString.c_str(); -} - -const char* IPhreeqc::GetDumpStringLine(int n) -{ - static const char empty[] = ""; - if (n < 0 || n >= this->GetDumpStringLineCount()) - { - return empty; - } - return this->DumpLines[n].c_str(); -} - -int IPhreeqc::GetDumpStringLineCount(void)const -{ - return (int)this->DumpLines.size(); +int IPhreeqc::GetDumpStringLineCount(void) const { + return (int)this->DumpLines.size(); } bool IPhreeqc::GetDumpStringOn(void)const @@ -1393,13 +1354,47 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL /* * Calculate distribution for exchangers */ - if (this->PhreeqcPtr->new_exchange) - this->PhreeqcPtr->initial_exchangers(TRUE); + if (this->PhreeqcPtr->new_exchange) { + if (this->PhreeqcPtr->use.Get_solution_in()) { + for (const auto &n_user : + this->PhreeqcPtr->Rxn_new_exchange) { + this->use_solutions.push_back( + {.module_n = n_user, + .module_name = "exchange", + .sol_n = + this->PhreeqcPtr->use.Get_n_solution_user()}); + } + } + this->PhreeqcPtr->initial_exchangers(TRUE); + } /* * Calculate distribution for surfaces */ - if (this->PhreeqcPtr->new_surface) - this->PhreeqcPtr->initial_surfaces(TRUE); + if (this->PhreeqcPtr->new_surface) { + if (this->PhreeqcPtr->use.Get_solution_in()) { + for (const auto &n_user : + this->PhreeqcPtr->Rxn_new_surface) { + this->use_solutions.push_back( + {.module_n = n_user, + .module_name = "surface", + .sol_n = + this->PhreeqcPtr->use.Get_n_solution_user()}); + } + } + + this->PhreeqcPtr->initial_surfaces(TRUE); + } + + if (this->PhreeqcPtr->new_kinetics) { + if (this->PhreeqcPtr->use.Get_solution_in()) { + this->use_solutions.push_back( + {.module_n = + this->PhreeqcPtr->use.Get_n_kinetics_user(), + .module_name = "kinetics", + .sol_n = this->PhreeqcPtr->use.Get_n_solution_user()}); + } + } + /* * Calculate initial gas composition */ @@ -1880,5 +1875,6 @@ std::string IPhreeqc::create_file_name(const char *prefix, const char *suffix) { std::ostringstream oss; oss << prefix << "." << this->Index << "." << suffix; - return oss.str(); + + return oss.str(); } diff --git a/src/IPhreeqc.hpp b/src/IPhreeqc.hpp index c79957b5..29ea18f1 100644 --- a/src/IPhreeqc.hpp +++ b/src/IPhreeqc.hpp @@ -913,6 +913,12 @@ protected: bool get_sel_out_string_on(int n)const; + struct SolutionMapping { + int module_n; + std::string module_name; + int sol_n; + }; + protected: #if defined(_MSC_VER) /* disable warning C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' */ @@ -990,6 +996,10 @@ protected: std::map< int, std::string > SelectedOutputStringMap; std::map< int, std::vector< std::string > > SelectedOutputLinesMap; + std::vector getSolutionMapping() const { + return this->use_solutions; + }; + protected: Phreeqc* PhreeqcPtr; FILE *input_file; @@ -1021,7 +1031,9 @@ private: /** * operator= not supported */ - IPhreeqc& operator=(const IPhreeqc&); + IPhreeqc &operator=(const IPhreeqc &); + + std::vector use_solutions; }; #endif // INC_IPHREEQC_HPP