Merge branch 'ml/add_ignore_list_to_runner' into 'poet'

feat: add support for ignoring specified cells in simulation run

See merge request naaice/iphreeqc!23
This commit is contained in:
Max Lübke 2024-12-04 10:08:14 +01:00
commit bdaea707ab
3 changed files with 62 additions and 0 deletions

View File

@ -50,6 +50,18 @@ public:
void run(std::vector<std::vector<double>> &simulationInOut,
const double time_step);
/**
* @brief Runs the simulation with the given input and output data.
*
* @param simulationInOut A reference to a 2D vector containing the simulation
* input and output data.
* @param time_step The time step for the simulation.
* @param to_ignore A vector of indices specifying which elements to ignore
* during the simulation.
*/
void run(std::vector<std::vector<double>> &simulationInOut,
const double time_step, const std::vector<std::size_t> &to_ignore);
/**
* @brief Returns the number of engines currently stored.
*

View File

@ -1,9 +1,11 @@
#include "PhreeqcEngine.hpp"
#include "PhreeqcMatrix.hpp"
#include "PhreeqcRunner.hpp"
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <memory>
#include <set>
#include <vector>
PhreeqcRunner::PhreeqcRunner(const PhreeqcMatrix &matrix) {
@ -50,6 +52,32 @@ void PhreeqcRunner::run(std::vector<std::vector<double>> &simulationInOut,
this->_engineStorage.at(pqc_id)->runCell(this->_buffer, time_step);
// Copy the buffer back to the output while ignoring the first element and
// NaNs
copy_from_buffer(this->_buffer, simulationInOut[i]);
}
}
void PhreeqcRunner::run(std::vector<std::vector<double>> &simulationInOut,
const double time_step,
const std::vector<std::size_t> &to_ignore) {
const std::set<std::size_t> to_ignore_set(to_ignore.begin(), to_ignore.end());
for (std::size_t i = 0; i < simulationInOut.size(); i++) {
if (to_ignore_set.find(i) != to_ignore_set.end()) {
continue;
}
const auto &current_inout = simulationInOut[i];
const auto pqc_id = static_cast<int>(current_inout[0]);
this->_buffer.clear();
// Copy the input to the buffer while ignoring the first element and NaNs
copy_to_buffer(this->_buffer, current_inout);
this->_engineStorage.at(pqc_id)->runCell(this->_buffer, time_step);
// Copy the buffer back to the output while ignoring the first element and
// NaNs
copy_from_buffer(this->_buffer, simulationInOut[i]);

View File

@ -72,4 +72,26 @@ POET_TEST(PhreeqcRunnerUnknownID) {
simulationInOut[0][0] = 1000;
EXPECT_THROW(runner.run(simulationInOut, 100), std::out_of_range);
}
POET_TEST(PhreeqcRunnerSimulationWithIgnoredCells) {
PhreeqcMatrix pqc_mat(test_database, test_script);
const auto subsetted_pqc_mat = pqc_mat.subset({2, 3});
PhreeqcRunner runner(subsetted_pqc_mat);
const auto stl_mat = subsetted_pqc_mat.get();
const auto matrix_values = stl_mat.values;
const auto num_columns = stl_mat.names.size();
std::vector<double> second_line(matrix_values.begin() + num_columns,
matrix_values.end());
std::vector<std::vector<double>> simulationInOut;
simulationInOut.push_back(second_line);
EXPECT_NO_THROW(runner.run(simulationInOut, 10000, {0}));
for (std::size_t i = 0; i < num_columns; ++i) {
EXPECT_DOUBLE_EQ(simulationInOut[0][i], second_line[i]);
}
}