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
parent 1a644baaba
commit 9cb2aba57a
4 changed files with 213 additions and 202 deletions

View File

@ -13,7 +13,7 @@
#include <string>
#include <vector>
class IPhreeqcModule : public IPhreeqc {
class IPhreeqcPOET : public IPhreeqc {
public:
std::vector<double>
get_essential_values(std::size_t cell_number,
@ -23,13 +23,12 @@ public:
const std::vector<std::string> &order,
std::vector<double> &values);
IPhreeqcModule(const std::string &database, const std::string &input_script,
const std::vector<int> &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<std::string> getInitNames() const {
@ -55,7 +54,7 @@ private:
std::vector<std::vector<double>> initial_concentrations;
std::vector<int> solution_ids;
void parseInitValues(const std::vector<int> &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<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,
essential_names &names, std::vector<double> &values);

View File

@ -38,9 +38,9 @@ createConcVector(const std::vector<std::string> &conc_names,
return conc_vec;
}
void IPhreeqcModule::valuesFromModule(const std::string &module_name,
int cell_number, essential_names &names,
std::vector<double> &values) {
void IPhreeqcPOET::valuesFromModule(const std::string &module_name,
int cell_number, essential_names &names,
std::vector<double> &values) {
std::size_t dest_module_i = 0;
std::vector<double> 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<IPhreeqc::SolutionMapping> &unresolved,
// std::map<int, std::pair<essential_names, std::vector<double>>>
// &mapped_values) {
void IPhreeqcPOET::resolveSolutionUseKW(
const std::vector<IPhreeqc::SolutionMapping> &unresolved,
std::map<int, std::pair<essential_names, std::vector<double>>>
&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<double> 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<double> 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<int> &ids) {
void IPhreeqcPOET::parseInitValues() {
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]));
}
// const auto unresolved_modules = this->getSolutionMapping();
// resolveSolutionUseKW(unresolved_modules, init_values);
const auto unresolved_modules = this->getSolutionMapping();
resolveSolutionUseKW(unresolved_modules, init_values);
std::vector<int> 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<int> &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<double>
IPhreeqcModule::get_essential_values(std::size_t cell_number,
const std::vector<std::string> &order) {
IPhreeqcPOET::get_essential_values(std::size_t cell_number,
const std::vector<std::string> &order) {
std::vector<double> 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<std::string> &order,
std::vector<double> &values) {
void IPhreeqcPOET::set_essential_values(std::size_t cell_number,
const std::vector<std::string> &order,
std::vector<double> &values) {
auto dump_it = values.begin();

View File

@ -1,201 +1,162 @@
#include <memory> // auto_ptr
#include <map>
#include <string.h>
#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 <map>
#include <memory> // auto_ptr
#include <string.h>
#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<size_t, IPhreeqc*> IPhreeqc::Instances;
std::map<size_t, IPhreeqc *> 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<std::ostringstream>;
this->WarningReporter = new CErrorReporter<std::ostringstream>;
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<std::ostringstream>;
this->WarningReporter = new CErrorReporter<std::ostringstream>;
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<size_t, IPhreeqc*>::value_type instance(this->Index, this);
/*std::pair<std::map<size_t, IPhreeqc*>::iterator, bool> pr = */IPhreeqc::Instances.insert(instance);
mutex_unlock(&map_lock);
mutex_lock(&map_lock);
this->Index = IPhreeqc::InstancesIndex++;
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);
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<int, CSelectedOutput *>::iterator sit =
this->SelectedOutputMap.begin();
for (; sit != this->SelectedOutputMap.end(); ++sit) {
delete (*sit).second;
}
this->SelectedOutputMap.clear();
mutex_lock(&map_lock);
std::map<size_t, IPhreeqc*>::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<size_t, IPhreeqc *>::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<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)
{
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();
}

View File

@ -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<SolutionMapping> 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<SolutionMapping> use_solutions;
};
#endif // INC_IPHREEQC_HPP