Merge branch '1-set-knobs-from-original-input-script-for-engines' into 'poet'

Resolve "Set knobs from original input script for Engines"

Closes #1

See merge request naaice/iphreeqc!19
This commit is contained in:
Max Lübke 2024-12-03 09:10:13 +01:00
commit 90a2432f03
8 changed files with 221 additions and 5 deletions

View File

@ -1,6 +1,7 @@
set(POET_SOURCE_FILES
src/Engine.cpp
src/Runner.cpp
src/Knobs.cpp
#Wrappers
src/Wrapper/EquilibriumWrapper.cpp
src/Wrapper/EquilibriumCompWrapper.cpp
@ -35,6 +36,7 @@ if (BUILD_TESTING AND STANDALONE_BUILD)
test/testPhreeqcEngine.cpp
test/testPhreeqcMatrix.cpp
test/testPhreeqcRunner.cpp
test/testPhreeqcKnobs.cpp
test/utils.cpp
)

View File

@ -0,0 +1,89 @@
#pragma once
#include "Phreeqc.h"
#include <cstdint>
/**
* @brief A struct to hold the parameters for PhreeqcKnobs.
*
* @note See more information on the parameters in the [Phreeqc
* manual](https://wwwbrr.cr.usgs.gov/projects/GWC_coupled/phreeqc/html/final-46.html)
*/
struct PhreeqcKnobsParams {
//
std::uint32_t iterations;
double convergence_tolerance;
double tolerance;
double step_size;
double pe_step_size;
bool diagonal_scale;
};
/**
* @class PhreeqcKnobs
* @brief A class to manage and manipulate knobs (parameters) for a Phreeqc
* instance.
*
* This class provides functionalities to read and write knobs (parameters) for
* a given Phreeqc instance. It also allows getting and setting the parameters
* through accessor and mutator methods.
*
* @note The class supports default copy and move constructors and assignment
* operators.
*
* @param pqc_instance A pointer to a Phreeqc instance.
*/
class PhreeqcKnobs {
public:
/**
* @brief Constructs a PhreeqcKnobs object from an exisiting phreeqc instance
*
* @param pqc_instance A pointer to an instance of the Phreeqc class.
*/
PhreeqcKnobs(Phreeqc *pqc_instance);
PhreeqcKnobs(const PhreeqcKnobs &) = default;
PhreeqcKnobs(PhreeqcKnobs &&) = default;
PhreeqcKnobs &operator=(const PhreeqcKnobs &) = default;
PhreeqcKnobs &operator=(PhreeqcKnobs &&) = default;
/**
* @brief Reads and store the configuration knobs from the given Phreeqc
* instance in the object.
*
* @param pqc_instance A pointer to the Phreeqc instance for which the knobs
* are to be read.
*/
void readKnobs(Phreeqc *pqc_instance);
/**
* @brief Writes the current state of the knobs to the given Phreeqc
* instance.
*
* @param pqc_instance A pointer to the Phreeqc instance whose knobs are to be
* written.
*/
void writeKnobs(Phreeqc *pqc_instance) const;
/**
* @brief Retrieves the current PhreeqcKnobs parameters.
*
* @return PhreeqcKnobsParams The current parameters of the PhreeqcKnobs.
*/
PhreeqcKnobsParams getParams() const { return _params; }
/**
* @brief Sets the parameters for PhreeqcKnobs.
*
* This function assigns the provided PhreeqcKnobsParams object to the
* internal _params member variable, updating the configuration of the
* PhreeqcKnobs instance.
*
* @param params The PhreeqcKnobsParams object containing the new parameters
* to be set.
*/
void setParams(const PhreeqcKnobsParams &params) { _params = params; }
private:
PhreeqcKnobsParams _params;
};

View File

@ -1,7 +1,5 @@
#pragma once
#include <array>
#include <cstddef>
#include <map>
#include <memory>
#include <set>
@ -9,7 +7,7 @@
#include <vector>
#include "IPhreeqc.hpp"
#include "global_structures.h"
#include "PhreeqcKnobs.hpp"
/**
* @brief Class for storing information from Phreeqc
@ -276,6 +274,16 @@ public:
*/
bool checkIfExists(int cell_id) const;
/**
* @brief Retrieves the current PhreeqcKnobs settings.
*
* This function returns a copy of the PhreeqcKnobs object that contains
* the current configuration settings for the Phreeqc instance.
*
* @return PhreeqcKnobs The current configuration settings.
*/
PhreeqcKnobs getKnobs() const { return *_m_knobs; }
private:
std::map<int, std::vector<element>> _m_map;
std::map<int, std::vector<base_names>> _m_internal_names;
@ -287,5 +295,7 @@ private:
void remove_NaNs();
std::shared_ptr<IPhreeqc> _m_pqc;
std::shared_ptr<PhreeqcKnobs> _m_knobs;
std::string _m_database;
};

View File

@ -10,6 +10,7 @@
#include <string>
#include <vector>
#include "PhreeqcKnobs.hpp"
#include "PhreeqcMatrix.hpp"
#include "Wrapper/EquilibriumWrapper.hpp"
#include "Wrapper/ExchangeWrapper.hpp"
@ -87,6 +88,8 @@ PhreeqcEngine::Impl::Impl(const PhreeqcMatrix &pqc_mat, const int cell_id) {
this->LoadDatabaseString(pqc_mat.getDatabase().c_str());
pqc_mat.getKnobs().writeKnobs(this->PhreeqcPtr);
const std::string pqc_string =
replaceRawKeywordID(pqc_mat.getDumpStringsPQI(cell_id));

24
poet/src/Knobs.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "PhreeqcKnobs.hpp"
PhreeqcKnobs::PhreeqcKnobs(Phreeqc *pqc_instance) {
this->readKnobs(pqc_instance);
}
void PhreeqcKnobs::readKnobs(Phreeqc *pqc_instance) {
this->_params.iterations = pqc_instance->itmax;
this->_params.convergence_tolerance = pqc_instance->convergence_tolerance;
this->_params.tolerance = pqc_instance->ineq_tol;
this->_params.step_size = pqc_instance->step_size;
this->_params.pe_step_size = pqc_instance->pe_step_size;
this->_params.diagonal_scale =
static_cast<bool>(pqc_instance->diagonal_scale);
}
void PhreeqcKnobs::writeKnobs(Phreeqc *pqc_instance) const {
pqc_instance->itmax = this->_params.iterations;
pqc_instance->convergence_tolerance = this->_params.convergence_tolerance;
pqc_instance->ineq_tol = this->_params.tolerance;
pqc_instance->step_size = this->_params.step_size;
pqc_instance->pe_step_size = this->_params.pe_step_size;
pqc_instance->diagonal_scale = this->_params.diagonal_scale;
}

View File

@ -1,9 +1,11 @@
#include "IPhreeqc.hpp"
#include "PhreeqcKnobs.hpp"
#include "PhreeqcMatrix.hpp"
#include <Phreeqc.h>
#include <Solution.h>
#include <cmath>
#include <memory>
#include <string>
PhreeqcMatrix::PhreeqcMatrix(const std::string &database,
@ -14,6 +16,9 @@ PhreeqcMatrix::PhreeqcMatrix(const std::string &database,
this->_m_pqc->LoadDatabaseString(database.c_str());
this->_m_pqc->RunString(input_script.c_str());
this->_m_knobs =
std::make_shared<PhreeqcKnobs>(this->_m_pqc.get()->GetPhreeqcPtr());
this->initialize();
}

View File

@ -0,0 +1,84 @@
#include <gtest/gtest.h>
#include <testInput.hpp>
#include "IPhreeqc.hpp"
#include "PhreeqcKnobs.hpp"
#include "utils.hpp"
const std::string barite_db = readFile(barite_test::database);
const std::string barite_script = readFile(barite_test::script);
const std::string knob_input = R"(
KNOBS
-iterations 120
-convergence_tolerance 1e-12
-tolerance 1e-16
-step_size 200
-pe_step_size 20
-diagonal_scale true
END
)";
POET_TEST(PhreeqcKnobsDefaultParams) {
IPhreeqc pqc;
pqc.LoadDatabaseString(barite_db.c_str());
pqc.RunString(barite_script.c_str());
PhreeqcKnobs knobs(pqc.GetPhreeqcPtr());
const PhreeqcKnobsParams params = knobs.getParams();
EXPECT_EQ(params.iterations, 100);
EXPECT_DOUBLE_EQ(params.convergence_tolerance, 1e-8);
EXPECT_DOUBLE_EQ(params.tolerance, 1e-15);
EXPECT_DOUBLE_EQ(params.step_size, 100);
EXPECT_DOUBLE_EQ(params.pe_step_size, 10);
EXPECT_FALSE(params.diagonal_scale);
}
inline void compare_params(const PhreeqcKnobsParams &params) {
EXPECT_EQ(params.iterations, 120);
EXPECT_DOUBLE_EQ(params.convergence_tolerance, 1e-12);
EXPECT_DOUBLE_EQ(params.tolerance, 1e-16);
EXPECT_DOUBLE_EQ(params.step_size, 200);
EXPECT_DOUBLE_EQ(params.pe_step_size, 20);
EXPECT_TRUE(params.diagonal_scale);
}
POET_TEST(PhreeqcKnobsSetFromScript) {
IPhreeqc pqc;
pqc.LoadDatabaseString(barite_db.c_str());
pqc.RunString(knob_input.c_str());
pqc.RunString(barite_script.c_str());
PhreeqcKnobs knobs(pqc.GetPhreeqcPtr());
const PhreeqcKnobsParams params = knobs.getParams();
compare_params(params);
}
POET_TEST(PhreeqcKnobsSetFromClass) {
IPhreeqc pqc;
pqc.LoadDatabaseString(barite_db.c_str());
pqc.RunString(knob_input.c_str());
pqc.RunString(barite_script.c_str());
PhreeqcKnobs knobs(pqc.GetPhreeqcPtr());
IPhreeqc new_instance;
new_instance.LoadDatabaseString(barite_db.c_str());
new_instance.RunString(barite_script.c_str());
knobs.writeKnobs(new_instance.GetPhreeqcPtr());
PhreeqcKnobs new_knobs(new_instance.GetPhreeqcPtr());
const PhreeqcKnobsParams params = new_knobs.getParams();
compare_params(params);
}

View File

@ -1851,8 +1851,7 @@ protected:
friend class IPhreeqcMMS;
friend class IPhreeqcPhast;
friend class PhreeqcRM;
friend class PhreeqcInit;
friend class PhreeqcEngine;
friend class PhreeqcKnobs;
std::vector<int> keycount; // used to mark keywords that have been read