diff --git a/poet/CMakeLists.txt b/poet/CMakeLists.txt index 19e315c5..ca26809e 100644 --- a/poet/CMakeLists.txt +++ b/poet/CMakeLists.txt @@ -61,5 +61,8 @@ if (BUILD_TESTING AND STANDALONE_BUILD) gtest_discover_tests(poet_test) endif() -add_executable(golemrunner test/testGolemRunner.cpp) -target_link_libraries(golemrunner IPhreeqcPOET) \ No newline at end of file +add_executable(testGolemRunner test/testGolemRunner.cpp) +target_link_libraries(testGolemRunner IPhreeqcPOET) + +add_executable(testGetters test/testGetters.cpp) +target_link_libraries(testGetters IPhreeqcPOET) diff --git a/poet/include/PhreeqcMatrix.hpp b/poet/include/PhreeqcMatrix.hpp index 567aba6e..26583157 100644 --- a/poet/include/PhreeqcMatrix.hpp +++ b/poet/include/PhreeqcMatrix.hpp @@ -313,6 +313,48 @@ public: */ bool withRedox() const { return _m_with_redox; } + // MDL + /** + * @brief Returns all column names of the Matrix pertaining to KINETICS + * + * This function returns a string vector. + * + * @return std::vector Whole vector of names. Empty if no KINETICS + * is defined + */ + std::vector getMatrixKinetics() const; + + /** + * @brief Returns all column names of the Matrix pertaining to EQUILIBRIUM + * + * This function returns a string vector. + * + * @return std::vector Whole vector of names. Empty if no EQUILIBRIUM + * is defined + */ + std::vector getMatrixEquilibrium() const; + + + /* + + @brief Returns all column names of the Matrix pertaining to + quantities that must be transported + + @return std::vector vector of names + + */ + std::vector getMatrixMustTransport() const; + + /* + + @brief Returns all column names of the Matrix pertaining to + quantities that must NOT be transported but have to be included in + the output + + @return std::vector vector of names + */ + std::vector getMatrixOutOnly() const; + private: std::map> _m_map; std::map> _m_internal_names; @@ -330,4 +372,4 @@ private: bool _m_with_h0_o0; bool _m_with_redox; -}; \ No newline at end of file +}; diff --git a/poet/src/PhreeqcMatrix/Access.cpp b/poet/src/PhreeqcMatrix/Access.cpp index ad78cc67..b98eda45 100644 --- a/poet/src/PhreeqcMatrix/Access.cpp +++ b/poet/src/PhreeqcMatrix/Access.cpp @@ -240,3 +240,99 @@ double PhreeqcMatrix::operator()(int cell_id, const std::string &name) const { return it->value; } + + +// MDL +std::vector PhreeqcMatrix::getMatrixKinetics() const { + std::vector names; + + auto n = this->getIds().size(); + for (auto i = 0; igetKineticsNames(i); + for (auto nam : pqc_kinnames ) { + for (auto mat_name : this->get().names){ + if (mat_name.starts_with(nam)) { + names.push_back(mat_name); + } + } + } + } + std::sort(names.begin(), names.end()); + std::vector::iterator it; + it = std::unique(names.begin(), names.end()); + names.resize(std::distance(names.begin(),it) ); + return names; +} + + +std::vector PhreeqcMatrix::getMatrixEquilibrium() const { + + std::vector names; + std::vector mat_names = this->get().names; + auto n = this->getIds().size(); + for (auto i = 0; igetEquilibriumNames(i); + for (auto nam : pqc_eqnames ) { + for (auto mat_name : mat_names){ + if (mat_name.starts_with(nam)) { + if (std::find(names.begin(), names.end(), mat_name) == names.end()) { + names.push_back(mat_name); + } + } + } + } + } + // std::sort(names.begin(), names.end()); + // std::vector::iterator it; + // it = std::unique(names.begin(), names.end()); + // names.resize(std::distance(names.begin(),it) ); + return names; +} + +std::vector PhreeqcMatrix::getMatrixMustTransport() const { + std::vector names; + + const std::vector to_remove = { + "tc", "patm", "SolVol", "pH", "pe" + }; + + // sols contains all solutes; we must remove { tc, patm, SolVol, pH, pe } + auto sols = this->getSolutionNames(); + for (auto name : sols) { + if (std::find(to_remove.begin(), to_remove.end(), name) == to_remove.end()) { + names.push_back(name); + } + } + + return names; +} + +std::vector PhreeqcMatrix::getMatrixOutOnly() const { + // MDL we must append here selected_output / user_punch + std::vector defaultnames = { + "tc", "patm", "SolVol", "pH", "pe" + }; + std::vector ret; + for (auto nm : defaultnames) { + ret.push_back(nm); + } + return ret; +} + +// std::vector PhreeqcMatrix::getTransported() const { +// std::vector names; + +// const auto &first_element = _m_map.begin()->second; + +// for (const auto &element : _m_map.begin()->second) { +// // assuming the element vector always starts with the solution components +// if (element.type != PhreeqcComponent::SOLUTION) { +// break; +// } + +// names.push_back(element.name); +// } + +// return names; +// } + diff --git a/poet/test/testGetters.cpp b/poet/test/testGetters.cpp new file mode 100644 index 00000000..5eaaaf49 --- /dev/null +++ b/poet/test/testGetters.cpp @@ -0,0 +1,103 @@ +// Time-stamp: "Last modified 2025-07-28 19:54:57 delucia" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PhreeqcMatrix.hpp" +#include "PhreeqcEngine.hpp" +#include "PhreeqcRunner.hpp" + + +std::string readFile(const std::string &path) { + std::string string_rpath(PATH_MAX, '\0'); + + if (realpath(path.c_str(), string_rpath.data()) == nullptr) { + throw std::runtime_error(":: Failed to resolve the realpath to file " + path); + } + + std::ifstream file(string_rpath); + + if (!file.is_open()) { + throw std::runtime_error(":: Failed to open file: " + path); + } + + std::stringstream buffer; + buffer << file.rdbuf(); + + return buffer.str(); +} + +// pretty print a vector, standard implementation from stackoverflow +template +std::ostream & operator<<(std::ostream & os, std::vector vec) +{ + os << "{ "; + std::copy(vec.begin(), vec.end(), std::ostream_iterator(os, ", ")); + os << " }"; + return os; +} + + +int main(int argc, char *argv[]) { + + if (argc < 3) { + std::cout << "::" << argv[0] << ": two args needed, script and database\n"; + return 1; + } + + + ////// INITIALISATION + // read Script and Database and put it in a std::string + auto script = readFile(argv[1]); + auto db = readFile(argv[2]); + + // Create the matrix directly from database and init script + std::cout << ":: Creating a PhreeqcMatrix with valence states and H(0)/O(0) \n"; + PhreeqcMatrix pqc_mat1(db, script, true, true); + + // How many different SOLUTIONS ("CELLS") are defined in the script? + const auto ids = pqc_mat1.getIds(); + + int n = ids.size(); + + std::cout << ":: Found " << n << " distinct PHREEQC problems \n"; + std::cout << ids << "\n"; + + std::cout << ":: getSolutionsNames(): the common solutes across all problems: \n"; + const auto solutes1 = pqc_mat1.getSolutionNames(); + std::cout << solutes1 << "\n"; + + // auto expmat = pqc_mat1.get(); + auto allvars = pqc_mat1.get().names; + std::cout << ":: pqc_mat1.get().names: \n"; + std::cout << allvars << "\n"; + + auto MatNamesKin = pqc_mat1.getMatrixKinetics(); + std::cout << ":: pqc_mat1.getMatrixKinetics(): \n"; + std::cout << MatNamesKin << "\n"; + + auto MatNamesEqui = pqc_mat1.getMatrixEquilibrium(); + std::cout << ":: pqc_mat1.getMatrixEquilibrium(): \n"; + std::cout << MatNamesEqui << "\n"; + + auto transported = pqc_mat1.getMatrixMustTransport(); + std::cout << ":: pqc_mat1.getMatrixMustTransport(): \n"; + std::cout << transported << "\n"; + + auto outonly = pqc_mat1.getMatrixOutOnly(); + std::cout << ":: pqc_mat1.getMatrixOutOnly(): \n"; + std::cout << outonly << "\n"; + return 0; +} + +// Oneliner for rz-vm278 relative to iphreeqc/poet/test!! + +// g++ testGolemRunner.cpp -o testG -Wall -I../../poet/include -I../../src -I../../src/phreeqcpp -I../../src/phreeqcpp/common -I../../src/phreeqcpp/PhreeqcKeywords -lIPhreeqc -lIPhreeqcPOET -L../../bbuild/ -L../../bbuild/poet