Add SolutionMapping struct and related methods to IPhreeqc and IPhreeqcPOET classes

This commit is contained in:
Max Luebke 2024-03-09 23:51:15 +01:00 committed by Max Lübke
parent 7a719708cf
commit c79f90a21d
4 changed files with 213 additions and 202 deletions

View File

@ -13,7 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
class IPhreeqcModule : public IPhreeqc { class IPhreeqcPOET : public IPhreeqc {
public: public:
std::vector<double> std::vector<double>
get_essential_values(std::size_t cell_number, get_essential_values(std::size_t cell_number,
@ -23,13 +23,12 @@ public:
const std::vector<std::string> &order, const std::vector<std::string> &order,
std::vector<double> &values); std::vector<double> &values);
IPhreeqcModule(const std::string &database, const std::string &input_script, IPhreeqcPOET(const std::string &database, const std::string &input_script)
const std::vector<int> &ids)
: IPhreeqc() { : IPhreeqc() {
this->LoadDatabase(database.c_str()); this->LoadDatabase(database.c_str());
this->RunFile(input_script.c_str()); this->RunFile(input_script.c_str());
this->parseInitValues(ids); this->parseInitValues();
} }
std::vector<std::string> getInitNames() const { std::vector<std::string> getInitNames() const {
@ -55,7 +54,7 @@ private:
std::vector<std::vector<double>> initial_concentrations; std::vector<std::vector<double>> initial_concentrations;
std::vector<int> solution_ids; std::vector<int> solution_ids;
void parseInitValues(const std::vector<int> &ids); void parseInitValues();
essential_names dump_essential_names(std::size_t cell_number); 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); return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_surface_map(), n);
} }
void resolveSolutionUseKW(
const std::vector<IPhreeqc::SolutionMapping> &unresolved,
std::map<int, std::pair<essential_names, std::vector<double>>>
&mapped_values);
void valuesFromModule(const std::string &module_name, int cell_number, void valuesFromModule(const std::string &module_name, int cell_number,
essential_names &names, std::vector<double> &values); essential_names &names, std::vector<double> &values);

View File

@ -38,9 +38,9 @@ createConcVector(const std::vector<std::string> &conc_names,
return conc_vec; return conc_vec;
} }
void IPhreeqcModule::valuesFromModule(const std::string &module_name, void IPhreeqcPOET::valuesFromModule(const std::string &module_name,
int cell_number, essential_names &names, int cell_number, essential_names &names,
std::vector<double> &values) { std::vector<double> &values) {
std::size_t dest_module_i = 0; std::size_t dest_module_i = 0;
std::vector<double> to_insert; std::vector<double> to_insert;
if (module_name == "exchange") { // 1 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()); values.insert(values.begin() + offset, to_insert.begin(), to_insert.end());
} }
// void IPhreeqcModule::resolveSolutionUseKW( void IPhreeqcPOET::resolveSolutionUseKW(
// const std::vector<IPhreeqc::SolutionMapping> &unresolved, const std::vector<IPhreeqc::SolutionMapping> &unresolved,
// std::map<int, std::pair<essential_names, std::vector<double>>> std::map<int, std::pair<essential_names, std::vector<double>>>
// &mapped_values) { &mapped_values) {
// for (const auto &input : unresolved) { for (const auto &input : unresolved) {
// if (mapped_values.find(input.module_n) != mapped_values.end()) { if (mapped_values.find(input.module_n) != mapped_values.end()) {
// continue; continue;
// } }
// essential_names new_conc_names; essential_names new_conc_names;
// new_conc_names[0] = mapped_values[input.sol_n].first[0]; new_conc_names[0] = mapped_values[input.sol_n].first[0];
// const auto &curr_sol_vec = mapped_values[input.sol_n].second; const auto &curr_sol_vec = mapped_values[input.sol_n].second;
// std::vector<double> new_conc_values( std::vector<double> new_conc_values(
// curr_sol_vec.begin(), curr_sol_vec.begin() + curr_sol_vec.begin(), curr_sol_vec.begin() + new_conc_names[0].size());
// new_conc_names[0].size());
// valuesFromModule(input.module_name, input.module_n, new_conc_names, valuesFromModule(input.module_name, input.module_n, new_conc_names,
// new_conc_values); new_conc_values);
// mapped_values[input.module_n] = mapped_values[input.module_n] =
// std::make_pair(new_conc_names, new_conc_values); std::make_pair(new_conc_names, new_conc_values);
// } }
// } }
void IPhreeqcModule::parseInitValues(const std::vector<int> &ids) { void IPhreeqcPOET::parseInitValues() {
std::map<int, std::pair<essential_names, std::vector<double>>> init_values; std::map<int, std::pair<essential_names, std::vector<double>>> init_values;
@ -107,20 +106,20 @@ void IPhreeqcModule::parseInitValues(const std::vector<int> &ids) {
curr_conc_names, this->get_essential_values(id, curr_conc_names[0])); curr_conc_names, this->get_essential_values(id, curr_conc_names[0]));
} }
// const auto unresolved_modules = this->getSolutionMapping(); const auto unresolved_modules = this->getSolutionMapping();
// resolveSolutionUseKW(unresolved_modules, init_values); resolveSolutionUseKW(unresolved_modules, init_values);
std::vector<int> ids_to_erase; std::vector<int> ids_to_erase;
// loop over found initial values and erase those that are not in the ids // loop over found initial values and erase those that are not in the ids
for (const auto &[id, values] : init_values) { for (const auto &[id, values] : init_values) {
// find key in vector of ids // 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()) { // if (it == ids.end()) {
ids_to_erase.push_back(id); // ids_to_erase.push_back(id);
continue; // continue;
} // }
// create a union of all known concentration names // create a union of all known concentration names
for (std::size_t i = 0; i < 5; i++) { for (std::size_t i = 0; i < 5; i++) {
@ -185,8 +184,8 @@ void IPhreeqcModule::parseInitValues(const std::vector<int> &ids) {
// } // }
} }
IPhreeqcModule::essential_names IPhreeqcPOET::essential_names
IPhreeqcModule::dump_essential_names(std::size_t cell_number) { IPhreeqcPOET::dump_essential_names(std::size_t cell_number) {
essential_names eNames; essential_names eNames;
@ -224,8 +223,8 @@ IPhreeqcModule::dump_essential_names(std::size_t cell_number) {
} }
std::vector<double> std::vector<double>
IPhreeqcModule::get_essential_values(std::size_t cell_number, IPhreeqcPOET::get_essential_values(std::size_t cell_number,
const std::vector<std::string> &order) { const std::vector<std::string> &order) {
std::vector<double> essentials; std::vector<double> essentials;
// Solutions // Solutions
@ -271,9 +270,9 @@ IPhreeqcModule::get_essential_values(std::size_t cell_number,
return essentials; return essentials;
} }
void IPhreeqcModule::set_essential_values(std::size_t cell_number, void IPhreeqcPOET::set_essential_values(std::size_t cell_number,
const std::vector<std::string> &order, const std::vector<std::string> &order,
std::vector<double> &values) { std::vector<double> &values) {
auto dump_it = values.begin(); auto dump_it = values.begin();

View File

@ -1,201 +1,162 @@
#include <memory> // auto_ptr #include "IPhreeqc.hpp" // IPhreeqc
#include <map> #include "Phreeqc.h" // Phreeqc
#include <string.h>
#include "IPhreeqc.hpp" // IPhreeqc
#include "Phreeqc.h" // Phreeqc
#include "thread.h"
#include "Version.h" #include "Version.h"
#include "thread.h"
#include <map>
#include <memory> // auto_ptr
#include <string.h>
#include "Debug.h" // ASSERT #include "CSelectedOutput.hxx" // CSelectedOutput
#include "ErrorReporter.hxx" // CErrorReporter #include "Debug.h" // ASSERT
#include "CSelectedOutput.hxx" // CSelectedOutput #include "ErrorReporter.hxx" // CErrorReporter
#include "SelectedOutput.h" // SelectedOutput #include "SelectedOutput.h" // SelectedOutput
#include "dumper.h" // dumper #include "dumper.h" // dumper
// statics // statics
std::map<size_t, IPhreeqc*> IPhreeqc::Instances; std::map<size_t, IPhreeqc *> IPhreeqc::Instances;
size_t IPhreeqc::InstancesIndex = 0; size_t IPhreeqc::InstancesIndex = 0;
std::string IPhreeqc::Version(VERSION_STRING); std::string IPhreeqc::Version(VERSION_STRING);
static const char empty[] = ""; static const char empty[] = "";
IPhreeqc::IPhreeqc(void) IPhreeqc::IPhreeqc(void)
: DatabaseLoaded(false) : DatabaseLoaded(false), ClearAccumulated(false), UpdateComponents(true),
, ClearAccumulated(false) OutputFileOn(false), LogFileOn(false), ErrorFileOn(false), DumpOn(false),
, UpdateComponents(true) DumpStringOn(false), OutputStringOn(false), LogStringOn(false),
, OutputFileOn(false) ErrorStringOn(true), ErrorReporter(0), WarningStringOn(true),
, LogFileOn(false) WarningReporter(0), CurrentSelectedOutputUserNumber(1), PhreeqcPtr(0),
, ErrorFileOn(false) input_file(0), database_file(0) {
, DumpOn(false) this->ErrorReporter = new CErrorReporter<std::ostringstream>;
, DumpStringOn(false) this->WarningReporter = new CErrorReporter<std::ostringstream>;
, OutputStringOn(false) this->PhreeqcPtr = new Phreeqc(this);
, LogStringOn(false)
, ErrorStringOn(true)
, ErrorReporter(0)
, WarningStringOn(true)
, WarningReporter(0)
, CurrentSelectedOutputUserNumber(1)
, PhreeqcPtr(0)
, input_file(0)
, database_file(0)
{
this->ErrorReporter = new CErrorReporter<std::ostringstream>;
this->WarningReporter = new CErrorReporter<std::ostringstream>;
this->PhreeqcPtr = new Phreeqc(this);
ASSERT(this->PhreeqcPtr->phast == 0); ASSERT(this->PhreeqcPtr->phast == 0);
this->UnLoadDatabase(); this->UnLoadDatabase();
mutex_lock(&map_lock); mutex_lock(&map_lock);
this->Index = IPhreeqc::InstancesIndex++; this->Index = IPhreeqc::InstancesIndex++;
std::map<size_t, IPhreeqc*>::value_type instance(this->Index, this); std::map<size_t, IPhreeqc *>::value_type instance(this->Index, this);
/*std::pair<std::map<size_t, IPhreeqc*>::iterator, bool> pr = */IPhreeqc::Instances.insert(instance); /*std::pair<std::map<size_t, IPhreeqc*>::iterator, bool> pr = */ IPhreeqc::
mutex_unlock(&map_lock); Instances.insert(instance);
mutex_unlock(&map_lock);
this->SelectedOutputStringOn[1] = false; this->SelectedOutputStringOn[1] = false;
this->SelectedOutputFileOnMap[1] = false; this->SelectedOutputFileOnMap[1] = false;
this->SelectedOutputFileNameMap[1] = this->sel_file_name(1); 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->DumpFileName = create_file_name("dump", "out"); this->OutputFileName = create_file_name("phreeqc", "out");
this->PhreeqcPtr->dump_info.Set_file_name(this->DumpFileName); 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) #if !defined(NDEBUG)
this->OutputFileOn = false; this->OutputFileOn = false;
#endif #endif
delete this->PhreeqcPtr; delete this->PhreeqcPtr;
delete this->WarningReporter; delete this->WarningReporter;
delete this->ErrorReporter; delete this->ErrorReporter;
std::map< int, CSelectedOutput* >::iterator sit = this->SelectedOutputMap.begin(); std::map<int, CSelectedOutput *>::iterator sit =
for (; sit != this->SelectedOutputMap.end(); ++sit) this->SelectedOutputMap.begin();
{ for (; sit != this->SelectedOutputMap.end(); ++sit) {
delete (*sit).second; delete (*sit).second;
} }
this->SelectedOutputMap.clear(); this->SelectedOutputMap.clear();
mutex_lock(&map_lock); mutex_lock(&map_lock);
std::map<size_t, IPhreeqc*>::iterator it = IPhreeqc::Instances.find(this->Index); std::map<size_t, IPhreeqc *>::iterator it =
if (it != IPhreeqc::Instances.end()) IPhreeqc::Instances.find(this->Index);
{ if (it != IPhreeqc::Instances.end()) {
IPhreeqc::Instances.erase(it); IPhreeqc::Instances.erase(it);
} }
mutex_unlock(&map_lock); mutex_unlock(&map_lock);
} }
VRESULT IPhreeqc::AccumulateLine(const char *line) VRESULT IPhreeqc::AccumulateLine(const char *line) {
{ try {
try if (this->ClearAccumulated) {
{ this->ClearAccumulatedLines();
if (this->ClearAccumulated) this->ClearAccumulated = false;
{ }
this->ClearAccumulatedLines();
this->ClearAccumulated = false;
}
this->ErrorReporter->Clear(); this->ErrorReporter->Clear();
this->WarningReporter->Clear(); this->WarningReporter->Clear();
this->StringInput.append(line); this->StringInput.append(line);
this->StringInput.append("\n"); this->StringInput.append("\n");
return VR_OK; return VR_OK;
} } catch (...) {
catch (...) this->AddError("AccumulateLine: An unhandled exception occured.\n");
{ throw;
this->AddError("AccumulateLine: An unhandled exception occured.\n"); }
throw; return VR_OUTOFMEMORY;
}
return VR_OUTOFMEMORY;
} }
size_t IPhreeqc::AddError(const char* str) size_t IPhreeqc::AddError(const char *str) {
{ return this->ErrorReporter->AddError(str);
return this->ErrorReporter->AddError(str);
} }
size_t IPhreeqc::AddWarning(const char* str) size_t IPhreeqc::AddWarning(const char *str) {
{ return this->WarningReporter->AddError(str);
return this->WarningReporter->AddError(str);
} }
void IPhreeqc::ClearAccumulatedLines(void) void IPhreeqc::ClearAccumulatedLines(void) { this->StringInput.erase(); }
{
this->StringInput.erase(); const std::string &IPhreeqc::GetAccumulatedLines(void) {
return this->StringInput;
} }
const std::string& IPhreeqc::GetAccumulatedLines(void) const char *IPhreeqc::GetComponent(int n) {
{ static const char empty[] = "";
return this->StringInput; 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();
} }
const char* IPhreeqc::GetComponent(int n) size_t IPhreeqc::GetComponentCount(void) {
{ this->ListComponents();
static const char empty[] = ""; return this->Components.size();
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) int IPhreeqc::GetCurrentSelectedOutputUserNumber(void) const {
{ return this->CurrentSelectedOutputUserNumber;
this->ListComponents();
return this->Components.size();
} }
int IPhreeqc::GetCurrentSelectedOutputUserNumber(void)const const char *IPhreeqc::GetDumpFileName(void) const {
{ return this->DumpFileName.c_str();
return this->CurrentSelectedOutputUserNumber;
} }
const char* IPhreeqc::GetDumpFileName(void)const bool IPhreeqc::GetDumpFileOn(void) const { return this->DumpOn; }
{
return this->DumpFileName.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();
} }
bool IPhreeqc::GetDumpFileOn(void)const const char *IPhreeqc::GetDumpStringLine(int n) {
{ static const char empty[] = "";
return this->DumpOn; if (n < 0 || n >= this->GetDumpStringLineCount()) {
return empty;
}
return this->DumpLines[n].c_str();
} }
const char* IPhreeqc::GetDumpString(void)const int IPhreeqc::GetDumpStringLineCount(void) const {
{ return (int)this->DumpLines.size();
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();
} }
bool IPhreeqc::GetDumpStringOn(void)const bool IPhreeqc::GetDumpStringOn(void)const
@ -1398,13 +1359,47 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
/* /*
* Calculate distribution for exchangers * Calculate distribution for exchangers
*/ */
if (this->PhreeqcPtr->new_exchange) if (this->PhreeqcPtr->new_exchange) {
this->PhreeqcPtr->initial_exchangers(TRUE); 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 * Calculate distribution for surfaces
*/ */
if (this->PhreeqcPtr->new_surface) if (this->PhreeqcPtr->new_surface) {
this->PhreeqcPtr->initial_surfaces(TRUE); 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 * Calculate initial gas composition
*/ */
@ -1885,5 +1880,6 @@ std::string IPhreeqc::create_file_name(const char *prefix, const char *suffix)
{ {
std::ostringstream oss; std::ostringstream oss;
oss << prefix << "." << this->Index << "." << suffix; oss << prefix << "." << this->Index << "." << suffix;
return oss.str();
return oss.str();
} }

View File

@ -913,6 +913,12 @@ protected:
bool get_sel_out_string_on(int n)const; bool get_sel_out_string_on(int n)const;
struct SolutionMapping {
int module_n;
std::string module_name;
int sol_n;
};
protected: protected:
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* disable warning C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' */ /* 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::string > SelectedOutputStringMap;
std::map< int, std::vector< std::string > > SelectedOutputLinesMap; std::map< int, std::vector< std::string > > SelectedOutputLinesMap;
std::vector<SolutionMapping> getSolutionMapping() const {
return this->use_solutions;
};
protected: protected:
Phreeqc* PhreeqcPtr; Phreeqc* PhreeqcPtr;
FILE *input_file; FILE *input_file;
@ -1021,7 +1031,9 @@ private:
/** /**
* operator= not supported * operator= not supported
*/ */
IPhreeqc& operator=(const IPhreeqc&); IPhreeqc &operator=(const IPhreeqc &);
std::vector<SolutionMapping> use_solutions;
}; };
#endif // INC_IPHREEQC_HPP #endif // INC_IPHREEQC_HPP