BREAKING CHANGE: Add wrappers for reactants to get/set values

This commit is contained in:
Max Luebke 2024-04-15 15:34:21 +00:00 committed by Max Lübke
parent 4ec8b7006c
commit 8bdbb7bf6b
38 changed files with 2160 additions and 1087 deletions

View File

@ -0,0 +1,38 @@
#pragma once
#include "PPassemblage.h"
#include "WrapperBase.hpp"
#include <memory>
class EquilibriumWrapper : public WrapperBase {
public:
EquilibriumWrapper(cxxPPassemblage *ppassemblage,
const std::vector<std::string> &ppassemblage_names);
void get(std::span<LDBLE> &data) const override;
void set(const std::span<LDBLE> &data) override;
static std::vector<std::string>
names(const cxxPPassemblage *ppassemblage,
std::vector<std::string> &ppassemblage_names);
private:
cxxPPassemblage *ppassemblage;
class EquilibriumCompWrapper : public WrapperBase {
public:
EquilibriumCompWrapper(cxxPPassemblageComp &comp);
void get(std::span<LDBLE> &data) const override;
void set(const std::span<LDBLE> &data) override;
static std::vector<std::string> names(const cxxPPassemblageComp &comp);
private:
cxxPPassemblageComp &comp;
};
std::vector<std::unique_ptr<EquilibriumCompWrapper>> equilibrium_comps;
};

View File

@ -0,0 +1,43 @@
#pragma once
#include "ExchComp.h"
#include "Exchange.h"
#include "WrapperBase.hpp"
#include "phrqtype.h"
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
#include <span>
class ExchangeWrapper : public WrapperBase {
public:
ExchangeWrapper(cxxExchange *exch, const std::vector<std::string> &exchanger);
void get(std::span<LDBLE> &exchange) const;
void set(const std::span<LDBLE> &exchange);
static std::vector<std::string>
names(cxxExchange *exchange, std::vector<std::string> &exchange_formulas);
private:
cxxExchange *exchange;
class ExchangeCompWrapper : public WrapperBase {
public:
ExchangeCompWrapper(cxxExchComp &comp);
void get(std::span<LDBLE> &exchange) const;
void set(const std::span<LDBLE> &exchange);
private:
cxxExchComp &exch_comp;
static constexpr std::size_t NUM_NOT_TOTALS = 5;
};
std::vector<std::unique_ptr<ExchangeCompWrapper>> exchange_comps;
};

View File

@ -1,192 +0,0 @@
#pragma once
#include <IPhreeqc.hpp>
#include <Exchange.h>
#include <PPassemblage.h>
#include <Phreeqc.h>
#include <Solution.h>
#include <Surface.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <cxxKinetics.h>
#include <iomanip>
#include <map>
#include <sstream>
#include <string>
#include <sys/types.h>
#include <utility>
#include <vector>
enum { POET_SOL = 0, POET_EXCH, POET_KIN, POET_EQUIL, POET_SURF };
class IPhreeqcPOET : public IPhreeqc {
public:
IPhreeqcPOET(const std::string &database, const std::string &input_script)
: IPhreeqc() {
this->LoadDatabaseString(database.c_str());
this->RunString(input_script.c_str());
this->parseInit();
}
IPhreeqcPOET(const std::string &database, const std::string &input_script,
const std::vector<std::string> &solutionInitVector,
std::uint32_t n_cells)
: IPhreeqc(), n_cells(n_cells), solutionInitVector(solutionInitVector) {
this->LoadDatabaseString(database.c_str());
this->RunString(input_script.c_str());
if (n_cells > 1) {
std::string copy_string =
"COPY cell 1 2-" + std::to_string(n_cells) + "\n";
this->RunString(copy_string.c_str());
}
}
void queueCell(std::vector<double> &values) {
if (this->queued_cell_pointer > this->n_cells) {
return;
}
setCell(this->queued_cell_pointer++, values);
}
void dequeueCells(std::vector<std::vector<double>> &values) {
if (this->queued_cell_pointer == 1) {
return;
}
for (std::size_t i = 1; i < this->queued_cell_pointer; i++) {
std::vector<double> cell_values;
getCell(i, cell_values);
values.push_back(cell_values);
}
this->queued_cell_pointer = 1;
}
void runQueuedCells(double time_step) {
if (this->queued_cell_pointer == 1) {
return;
}
run(1, this->queued_cell_pointer - 1, time_step);
}
void setCell(int cell_number, std::vector<double> &values) {
this->set_essential_values(cell_number, this->solutionInitVector, values);
}
void getCell(int cell_number, std::vector<double> &values) {
values = this->get_essential_values(cell_number, this->solutionInitVector);
}
void run(int start_cell, int end_cell, double time_step) {
std::stringstream time_ss;
time_ss << std::fixed << std::setprecision(20) << time_step;
const std::string runs_string =
"RUN_CELLS\n -cells " + std::to_string(start_cell) + "-" +
std::to_string(end_cell) + "\n -time_step " + time_ss.str();
this->RunString(runs_string.c_str());
}
struct PhreeqcMat {
std::vector<std::string> names;
std::vector<int> ids;
std::vector<std::vector<double>> values;
};
PhreeqcMat getPhreeqcMat();
std::map<int, std::string> raw_dumps() {
std::map<int, std::string> dumps;
this->SetDumpStringOn(true);
for (const auto &[sol_id, unused] : this->raw_initials) {
std::string call_string = "DUMP\n -cells " + std::to_string(sol_id);
this->RunString(call_string.c_str());
dumps[sol_id] = this->GetDumpString();
}
this->SetDumpStringOn(false);
return dumps;
}
using essential_names = std::array<std::vector<std::string>, 5>;
using ModulesArray = std::array<std::uint32_t, 5>;
ModulesArray getModuleSizes(const std::vector<int> &cell_ids);
std::vector<std::string> getSolutionNames(int cell_id) {
return this->raw_initials[cell_id].first[POET_SOL];
}
private:
// required only for simulation
essential_names initial_names;
std::uint32_t n_cells;
std::vector<std::string> solutionInitVector;
void parseInitValues();
void parseInit();
essential_names dump_essential_names(std::size_t cell_number);
cxxSolution *Get_solution(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_solution_map(), n);
}
cxxExchange *Get_exchange(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_exchange_map(), n);
}
cxxKinetics *Get_kinetic(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_kinetics_map(), n);
}
cxxPPassemblage *Get_equilibrium(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_pp_assemblage_map(),
n);
}
cxxSurface *Get_surface(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_surface_map(), n);
}
using RawMap = std::map<int, std::pair<essential_names, std::vector<double>>>;
essential_names union_raws(const RawMap &raws);
std::vector<std::vector<double>>
conc_from_essentials(const RawMap &raws, const essential_names &names);
// void valuesFromModule(const std::string &module_name, int cell_number,
// essential_names &names, std::vector<double> &values);
std::string subExchangeName(std::string name) {
for (const auto &species : this->PhreeqcPtr->Get_species_list()) {
const std::string &species_name = species.s->name;
// check if `name` is a prefix of `species_name`
if (species_name.compare(0, name.size(), name) == 0) {
return species_name;
}
}
return name;
};
std::vector<double>
get_essential_values(std::size_t cell_number,
const std::vector<std::string> &order);
void set_essential_values(std::size_t cell_number,
const std::vector<std::string> &order,
std::vector<double> &values);
RawMap raw_initials;
std::size_t queued_cell_pointer = 1;
};

View File

@ -0,0 +1,38 @@
#pragma once
#include "KineticsComp.h"
#include "WrapperBase.hpp"
#include "cxxKinetics.h"
#include <memory>
#include <vector>
class KineticWrapper : public WrapperBase {
public:
KineticWrapper(cxxKinetics *kinetics,
const std::vector<std::string> &kin_comps);
void get(std::span<LDBLE> &data) const override;
void set(const std::span<LDBLE> &data) override;
static std::vector<std::string> names(cxxKinetics *kinetics,
std::vector<std::string> &kin_comps);
private:
cxxKinetics *kinetics;
class KineticCompWrapper : public WrapperBase {
public:
KineticCompWrapper(cxxKineticsComp &comp);
void get(std::span<LDBLE> &data) const override;
void set(const std::span<LDBLE> &data) override;
static std::vector<std::string> names(const cxxKineticsComp &comp);
private:
cxxKineticsComp &kin_comp;
};
std::vector<std::unique_ptr<KineticCompWrapper>> kinetic_comps;
};

20
poet/include/POETInit.hpp Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <string>
#include <vector>
struct POETInitCell {
std::vector<std::string> solutions;
std::vector<std::string> solution_primaries;
std::vector<std::string> exchanger;
std::vector<std::string> kinetics;
std::vector<std::string> equilibrium;
std::vector<std::string> surface_comps;
std::vector<std::string> surface_charges;
};
struct POETConfig {
std::string database;
std::string input_script;
POETInitCell cell;
};

View File

@ -0,0 +1,96 @@
#pragma once
#include "EquilibriumWrapper.hpp"
#include "ExchangeWrapper.hpp"
#include "KineticWrapper.hpp"
#include "POETInit.hpp"
#include "SolutionWrapper.hpp"
#include "SurfaceWrapper.hpp"
#include <IPhreeqc.hpp>
#include <Exchange.h>
#include <PPassemblage.h>
#include <Phreeqc.h>
#include <Solution.h>
#include <Surface.h>
#include <cstddef>
#include <cxxKinetics.h>
#include <iomanip>
#include <iostream>
#include <memory>
#include <ostream>
#include <span>
#include <sstream>
#include <string>
#include <sys/types.h>
#include <vector>
class PhreeqcEngine : public IPhreeqc {
public:
PhreeqcEngine(const POETConfig &config) : IPhreeqc() {
this->LoadDatabaseString(config.database.c_str());
this->RunString(config.input_script.c_str());
this->init_wrappers(config.cell);
}
void runCell(std::vector<double> &cell_values, double time_step);
void run(int start_cell, int end_cell) {
const std::string runs_string = "RUN_CELLS\n -cells " +
std::to_string(start_cell) + "-" +
std::to_string(end_cell) + "\nEND\n";
this->RunString(runs_string.c_str());
}
void run(int start_cell, int end_cell, double time_step) {
std::stringstream time_ss;
time_ss << std::fixed << std::setprecision(20) << time_step;
const std::string runs_string =
"RUN_CELLS\n -cells " + std::to_string(start_cell) + "-" +
std::to_string(end_cell) + "\n -time_step " + time_ss.str() + "\nEND\n";
this->RunString(runs_string.c_str());
}
private:
void init_wrappers(const POETInitCell &cell);
cxxSolution *Get_solution(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_solution_map(), n);
}
cxxExchange *Get_exchange(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_exchange_map(), n);
}
cxxKinetics *Get_kinetic(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_kinetics_map(), n);
}
cxxPPassemblage *Get_equilibrium(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_pp_assemblage_map(),
n);
}
cxxSurface *Get_surface(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_surface_map(), n);
}
void get_essential_values(std::span<double> &data);
void set_essential_values(const std::span<double> &data);
std::unique_ptr<SolutionWrapper> solutionWrapperPtr;
std::unique_ptr<ExchangeWrapper> exchangeWrapperPtr;
std::unique_ptr<KineticWrapper> kineticsWrapperPtr;
std::unique_ptr<EquilibriumWrapper> equilibriumWrapperPtr;
std::unique_ptr<SurfaceWrapper> surfaceWrapperPtr;
bool has_exchange = false;
bool has_kinetics = false;
bool has_equilibrium = false;
bool has_surface = false;
};

View File

@ -0,0 +1,156 @@
#pragma once
#include <IPhreeqc.hpp>
#include <Phreeqc.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "Exchange.h"
#include "PPassemblage.h"
#include "Solution.h"
#include "Surface.h"
#include "cxxKinetics.h"
enum { POET_SOL = 0, POET_EXCH, POET_KIN, POET_EQUIL, POET_SURF };
class PhreeqcInit : public IPhreeqc {
public:
PhreeqcInit(const std::string &database, const std::string &input_script);
struct PhreeqcMat {
std::vector<std::string> names;
std::vector<int> ids;
std::vector<std::vector<double>> values;
};
PhreeqcMat getPhreeqcMat() const { return pqc_mat; };
std::map<int, std::string> raw_dumps();
using essential_names = std::array<std::vector<std::string>, 5>;
using ModulesArray = std::array<std::uint32_t, 5>;
ModulesArray getModuleSizes(const std::vector<int> &cell_ids);
std::vector<std::string> getSolutionPrimaries() {
return std::vector<std::string>(this->surface_primaries.begin(),
this->surface_primaries.end());
}
std::vector<std::string> getSolutionNames(int cell_id) {
return this->raw_initials[cell_id].first[POET_SOL];
}
std::vector<std::string> getExchanger(int id) {
if (this->exchanger.contains(id)) {
return this->exchanger[id];
}
return {};
}
std::vector<std::string> getKineticsNames(int id) {
if (this->kinetics.contains(id)) {
return this->kinetics[id];
}
return {};
}
std::vector<std::string> getEquilibriumNames(int id) {
if (this->equilibrium.contains(id)) {
return this->equilibrium[id];
}
return {};
}
std::vector<std::string> getSurfaceCompNames(int id) {
if (this->surface_comps.contains(id)) {
return this->surface_comps[id];
}
return {};
}
std::vector<std::string> getSurfaceChargeNames(int id) {
if (this->surface_charge.contains(id)) {
return this->surface_charge[id];
}
return {};
}
private:
// required only for simulation
essential_names initial_names;
void parseInitValues();
void parseInit();
std::vector<std::string> dump_solution_names(int cell_number);
void dump_reactant_names(int cell_number,
const std::vector<std::string> union_sol_names,
essential_names &names);
std::vector<std::string>
find_all_valence_states(const std::vector<std::string> &solution_names,
const std::size_t offset);
cxxSolution *Get_solution(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_solution_map(), n);
}
cxxExchange *Get_exchange(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_exchange_map(), n);
}
cxxKinetics *Get_kinetic(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_kinetics_map(), n);
}
cxxPPassemblage *Get_equilibrium(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_pp_assemblage_map(),
n);
}
cxxSurface *Get_surface(std::size_t n) {
return Utilities::Rxn_find(this->PhreeqcPtr->Get_Rxn_surface_map(), n);
}
PhreeqcMat pqc_mat;
PhreeqcMat buildPhreeqcMat();
std::map<int, std::vector<std::string>> exchanger;
std::map<int, std::vector<std::string>> kinetics;
std::map<int, std::vector<std::string>> equilibrium;
std::map<int, std::vector<std::string>> surface_comps;
std::map<int, std::vector<std::string>> surface_charge;
std::set<std::string> surface_primaries;
using RawMap = std::map<int, std::pair<essential_names, std::vector<double>>>;
essential_names union_raws(const RawMap &raws);
std::vector<std::vector<double>>
conc_from_essentials(const RawMap &raws, const essential_names &names);
// void valuesFromModule(const std::string &module_name, int cell_number,
// essential_names &names, std::vector<double> &values);
std::string subExchangeName(std::string name);
std::vector<double>
get_essential_values_init(std::size_t cell_number,
const std::vector<std::string> &order);
RawMap raw_initials;
};

View File

@ -0,0 +1,26 @@
#pragma once
#include "NameDouble.h"
#include "Solution.h"
#include "WrapperBase.hpp"
#include <cstddef>
#include <vector>
class SolutionWrapper : public WrapperBase {
public:
SolutionWrapper(cxxSolution *soln,
const std::vector<std::string> &solution_order);
void get(std::span<LDBLE> &data) const;
void set(const std::span<LDBLE> &data);
static std::vector<std::string>
names(cxxSolution *solution, std::vector<std::string> &solution_order);
private:
cxxSolution *solution;
const std::vector<std::string> solution_order;
static constexpr std::size_t NUM_ESSENTIALS = 3;
};

View File

@ -0,0 +1,71 @@
#pragma once
#include "Surface.h"
#include "SurfaceCharge.h"
#include "SurfaceComp.h"
#include "WrapperBase.hpp"
#include "phrqtype.h"
#include <cstddef>
#include <memory>
#include <set>
#include <span>
#include <string>
#include <vector>
class SurfaceWrapper : public WrapperBase {
public:
SurfaceWrapper(cxxSurface *surf,
const std::set<std::string> &solution_primaries,
const std::vector<std::string> &comp_formulas,
const std::vector<std::string> &charge_names);
void get(std::span<LDBLE> &surface) const override;
void set(const std::span<LDBLE> &surface) override;
static std::vector<std::string>
names(cxxSurface *surface, const std::set<std::string> &solution_primaries,
std::vector<std::string> &comp_formulas,
std::vector<std::string> &charge_names);
private:
cxxSurface *surface;
class SurfaceCompWrapper : public WrapperBase {
public:
SurfaceCompWrapper(cxxSurfaceComp &comp);
void get(std::span<LDBLE> &surface) const;
void set(const std::span<LDBLE> &surface);
static std::vector<std::string> names(cxxSurfaceComp &comp);
private:
cxxSurfaceComp &surface_comp;
static constexpr std::size_t NUM_NOT_TOTALS = 3;
std::vector<std::string> total_names;
};
class SurfaceChargeWrapper : public WrapperBase {
public:
SurfaceChargeWrapper(cxxSurfaceCharge &charge,
const std::set<std::string> &solution_primaries);
void get(std::span<LDBLE> &surface) const;
void set(const std::span<LDBLE> &surface);
static std::vector<std::string>
names(cxxSurfaceCharge *charge, const std::set<std::string> &primaries);
private:
cxxSurfaceCharge &surface_charge;
static constexpr std::size_t NUM_NOT_TOTALS = 5;
std::set<std::string> primaries;
};
std::vector<std::unique_ptr<SurfaceCompWrapper>> surface_comps;
std::vector<std::unique_ptr<SurfaceChargeWrapper>> surface_charges;
};

View File

@ -0,0 +1,18 @@
#pragma once
#include <phrqtype.h>
#include <span>
class WrapperBase {
public:
virtual ~WrapperBase() = default;
std::size_t size() const { return this->num_elements; };
virtual void get(std::span<LDBLE> &data) const = 0;
virtual void set(const std::span<LDBLE> &data) = 0;
protected:
std::size_t num_elements = 0;
};

220
poet/src/Engine.cpp Normal file
View File

@ -0,0 +1,220 @@
#include "PhreeqcEngine.hpp"
#include <cstddef>
#include <span>
void PhreeqcEngine::init_wrappers(const POETInitCell &cell) {
// TODO: Implement the rest of the wrappers. Currently supported: EXCHANGE
// Solutions
this->solutionWrapperPtr =
std::make_unique<SolutionWrapper>(this->Get_solution(1), cell.solutions);
if (this->Get_exchange(1) != nullptr) {
this->exchangeWrapperPtr = std::make_unique<ExchangeWrapper>(
this->Get_exchange(1), cell.exchanger);
this->has_exchange = true;
}
if (this->Get_kinetic(1) != nullptr) {
this->kineticsWrapperPtr =
std::make_unique<KineticWrapper>(this->Get_kinetic(1), cell.kinetics);
this->has_kinetics = true;
}
if (this->Get_equilibrium(1) != nullptr) {
this->equilibriumWrapperPtr = std::make_unique<EquilibriumWrapper>(
this->Get_equilibrium(1), cell.equilibrium);
this->has_equilibrium = true;
}
if (this->Get_surface(1) != nullptr) {
std::set<std::string> primaries(cell.solution_primaries.begin(),
cell.solution_primaries.end());
this->surfaceWrapperPtr = std::make_unique<SurfaceWrapper>(
this->Get_surface(1), primaries, cell.surface_comps,
cell.surface_charges);
this->has_surface = true;
}
}
void PhreeqcEngine::get_essential_values(std::span<double> &data) {
this->solutionWrapperPtr->get(data);
std::size_t offset = this->solutionWrapperPtr->size();
if (this->has_exchange) {
std::span<double> exch_span{
data.subspan(offset, this->exchangeWrapperPtr->size())};
this->exchangeWrapperPtr->get(exch_span);
offset += this->exchangeWrapperPtr->size();
}
if (this->has_kinetics) {
std::span<double> kin_span{
data.subspan(offset, this->kineticsWrapperPtr->size())};
this->kineticsWrapperPtr->get(kin_span);
offset += this->kineticsWrapperPtr->size();
}
if (this->has_equilibrium) {
std::span<double> equ_span{
data.subspan(offset, this->equilibriumWrapperPtr->size())};
this->equilibriumWrapperPtr->get(equ_span);
offset += this->equilibriumWrapperPtr->size();
}
if (this->has_surface) {
std::span<double> surf_span{
data.subspan(offset, this->surfaceWrapperPtr->size())};
this->surfaceWrapperPtr->get(surf_span);
}
// // Exchange
// if (this->Get_exchange(cell_number) != NULL) {
// std::vector<double> exch_values(this->exchangeWrapperPtr->size());
// std::span<double> exch_span{exch_values};
// this->exchangeWrapperPtr->get(exch_span);
// // this->Get_exchange(cell_number)->get_essential_values(exch_values);
// essentials.insert(essentials.end(), exch_values.begin(),
// exch_values.end());
// }
// // Kinetics
// if (this->Get_kinetic(cell_number) != NULL) {
// std::vector<double> kin_values;
// this->Get_kinetic(cell_number)->get_essential_values(kin_values);
// essentials.insert(essentials.end(), kin_values.begin(),
// kin_values.end());
// }
// // PPassemblage
// if (this->Get_equilibrium(cell_number) != NULL) {
// std::vector<double> equ_values;
// this->Get_equilibrium(cell_number)->get_essential_values(equ_values);
// essentials.insert(essentials.end(), equ_values.begin(),
// equ_values.end());
// }
// // Surface
// if (this->Get_surface(cell_number) != NULL) {
// std::vector<double> surf_values(this->surfaceWrapperPtr->size());
// std::span<double> surf_span{surf_values};
// this->surfaceWrapperPtr->get(surf_span);
// // this->Get_surface(cell_number)->get_essential_values(surf_values);
// essentials.insert(essentials.end(), surf_values.begin(),
// surf_values.end());
// }
// return essentials;
}
void PhreeqcEngine::set_essential_values(const std::span<double> &data) {
this->solutionWrapperPtr->set(data);
this->PhreeqcPtr->initial_solutions_poet(1);
std::size_t offset = this->solutionWrapperPtr->size();
if (this->has_exchange) {
std::span<double> exch_span{
data.subspan(offset, this->exchangeWrapperPtr->size())};
this->exchangeWrapperPtr->set(exch_span);
offset += this->exchangeWrapperPtr->size();
}
if (this->has_kinetics) {
std::span<double> kin_span{
data.subspan(offset, this->kineticsWrapperPtr->size())};
this->kineticsWrapperPtr->set(kin_span);
offset += this->kineticsWrapperPtr->size();
}
if (this->has_equilibrium) {
std::span<double> equ_span{
data.subspan(offset, this->equilibriumWrapperPtr->size())};
this->equilibriumWrapperPtr->set(equ_span);
offset += this->equilibriumWrapperPtr->size();
}
if (this->has_surface) {
std::span<double> surf_span{
data.subspan(offset, this->surfaceWrapperPtr->size())};
this->surfaceWrapperPtr->set(surf_span);
}
// // Solutions
// if (this->Get_solution(cell_number) != NULL) {
// this->Get_solution(cell_number)->set_essential_values(dump_it, order);
// this->PhreeqcPtr->initial_solutions_poet(cell_number);
// }
// // Exchange
// if (this->Get_exchange(cell_number) != NULL) {
// auto &exch_pointer = this->exchangeWrapperPtr;
// std::span<double> exch_span{dump_it, exch_pointer->size()};
// exch_pointer->set(exch_span);
// dump_it += exch_pointer->size();
// // this->Get_exchange(cell_number)->set_essential_values(dump_it);
// // this->PhreeqcPtr->Rxn_new_exchange.insert(cell_number);
// // this->Get_exchange(cell_number)->Set_new_def(true);
// // this->Get_exchange(cell_number)->Set_solution_equilibria(true);
// // this->Get_exchange(cell_number)->Set_n_solution(cell_number);
// // this->PhreeqcPtr->initial_exchangers(FALSE);
// }
// // Kinetics
// if (this->Get_kinetic(cell_number) != NULL) {
// this->Get_kinetic(cell_number)->set_essential_values(dump_it);
// }
// // PPassemblage
// if (this->Get_equilibrium(cell_number) != NULL) {
// this->Get_equilibrium(cell_number)->set_essential_values(dump_it);
// }
// // Surface
// if (this->Get_surface(cell_number) != NULL) {
// auto *tmp = this->Get_surface(cell_number);
// auto &surf_pointer = this->surfaceWrapperPtr;
// std::span<double> surf_span{dump_it, surf_pointer->size()};
// surf_pointer->set(surf_span);
// dump_it += surf_pointer->size();
// // this->PhreeqcPtr->Rxn_new_surface.insert(cell_number);
// // this->Get_surface(cell_number)->set_essential_values(dump_it);
// // this->PhreeqcPtr->Rxn_new_surface.insert(cell_number);
// // this->PhreeqcPtr->initial_surfaces(TRUE);
// }
}
void PhreeqcEngine::runCell(std::vector<double> &cell_values,
double time_step) {
// skip ID
std::span<double> cell_data{cell_values.begin() + 1, cell_values.end()};
this->set_essential_values(cell_data);
this->run(1, 1, time_step);
this->get_essential_values(cell_data);
}

View File

@ -0,0 +1,30 @@
#include "EquilibriumWrapper.hpp"
EquilibriumWrapper::EquilibriumCompWrapper::EquilibriumCompWrapper(
cxxPPassemblageComp &comp_)
: comp(comp_) {
this->num_elements = 2;
}
void EquilibriumWrapper::EquilibriumCompWrapper::get(
std::span<LDBLE> &data) const {
data[0] = this->comp.Get_moles();
data[1] = this->comp.Get_si();
}
void EquilibriumWrapper::EquilibriumCompWrapper::set(
const std::span<LDBLE> &data) {
this->comp.Set_moles(data[0]);
this->comp.Set_si(data[1]);
}
std::vector<std::string> EquilibriumWrapper::EquilibriumCompWrapper::names(
const cxxPPassemblageComp &comp) {
std::vector<std::string> names;
const std::string &comp_name = comp.Get_name();
names.push_back(comp_name);
names.push_back(comp_name + "_si");
return names;
}

View File

@ -0,0 +1,66 @@
#include "EquilibriumWrapper.hpp"
#include <algorithm>
#include <memory>
EquilibriumWrapper::EquilibriumWrapper(
cxxPPassemblage *ppassemblage,
const std::vector<std::string> &ppassemblage_names)
: ppassemblage(ppassemblage) {
for (const auto &ppassemblage_name : ppassemblage_names) {
auto it = std::find_if(
ppassemblage->Get_pp_assemblage_comps().begin(),
ppassemblage->Get_pp_assemblage_comps().end(),
[&](const auto &comp) { return comp.first == ppassemblage_name; });
if (it == ppassemblage->Get_pp_assemblage_comps().end()) {
throw std::runtime_error(
"Equilibrium component not found in Phreeqc variables");
}
equilibrium_comps.push_back(
std::make_unique<EquilibriumCompWrapper>(it->second));
num_elements += equilibrium_comps.back()->size();
}
}
void EquilibriumWrapper::get(std::span<LDBLE> &data) const {
std::size_t offset = 0;
for (const auto &comp : equilibrium_comps) {
std::span<LDBLE> comp_span = data.subspan(offset, comp->size());
comp->get(comp_span);
offset += comp->size();
}
}
void EquilibriumWrapper::set(const std::span<LDBLE> &data) {
std::size_t offset = 0;
for (const auto &comp : equilibrium_comps) {
std::span<LDBLE> comp_span = data.subspan(offset, comp->size());
comp->set(comp_span);
offset += comp->size();
}
}
std::vector<std::string>
EquilibriumWrapper::names(const cxxPPassemblage *ppassemblage,
std::vector<std::string> &ppassemblage_names) {
std::vector<std::string> names;
for (const auto &comp : ppassemblage->Get_pp_assemblage_comps()) {
std::vector<std::string> comp_names =
EquilibriumCompWrapper::names(comp.second);
names.insert(names.end(), comp_names.begin(), comp_names.end());
ppassemblage_names.push_back(comp.first);
}
return names;
}

View File

@ -0,0 +1,41 @@
#include "ExchangeWrapper.hpp"
ExchangeWrapper::ExchangeCompWrapper::ExchangeCompWrapper(cxxExchComp &comp)
: exch_comp(comp) {
const std::size_t totals_size = exch_comp.Get_totals().size() - 1;
this->num_elements = totals_size + NUM_NOT_TOTALS;
}
void ExchangeWrapper::ExchangeCompWrapper::get(
std::span<LDBLE> &exchange) const {
exchange[0] = exch_comp.Get_totals().find(exch_comp.Get_formula())->second;
exchange[1] = exch_comp.Get_charge_balance();
exchange[2] = exch_comp.Get_la();
exchange[3] = exch_comp.Get_phase_proportion();
exchange[4] = exch_comp.Get_formula_z();
for (const auto &[name, value] : exch_comp.Get_totals()) {
if (name != exch_comp.Get_formula()) {
exchange[NUM_NOT_TOTALS +
std::distance(exch_comp.Get_totals().begin(),
exch_comp.Get_totals().find(name))] = value;
}
}
}
void ExchangeWrapper::ExchangeCompWrapper::set(
const std::span<LDBLE> &exchange) {
exch_comp.Get_totals().find(exch_comp.Get_formula())->second = exchange[0];
exch_comp.Set_charge_balance(exchange[1]);
exch_comp.Set_la(exchange[2]);
exch_comp.Set_phase_proportion(exchange[3]);
exch_comp.Set_formula_z(exchange[4]);
for (auto &[name, value] : exch_comp.Get_totals()) {
if (name != exch_comp.Get_formula()) {
value = exchange[NUM_NOT_TOTALS +
std::distance(exch_comp.Get_totals().begin(),
exch_comp.Get_totals().find(name))];
}
}
}

View File

@ -0,0 +1,101 @@
#include "ExchangeWrapper.hpp"
ExchangeWrapper::ExchangeWrapper(cxxExchange *exch,
const std::vector<std::string> &exchanger)
: exchange(exch) {
for (const auto &comp_name : exchanger) {
auto it = std::find_if(exchange->Get_exchange_comps().begin(),
exchange->Get_exchange_comps().end(),
[&](const cxxExchComp &comp) {
return comp.Get_formula() == comp_name;
});
if (it == exchange->Get_exchange_comps().end()) {
throw std::runtime_error(
"Exchange component not found in Phreeqc variables");
}
exchange_comps.push_back(std::make_unique<ExchangeCompWrapper>(*it));
num_elements += exchange_comps.back()->size();
}
// const std::size_t defined_comps = exchange->Get_exchange_comps().size();
// auto header_it = remaining_field_header.begin();
// while (header_it != remaining_field_header.end() &&
// exchange_comps.size() < defined_comps) {
// const std::string formular = *header_it;
// auto it = std::find_if(exchange->Get_exchange_comps().begin(),
// exchange->Get_exchange_comps().end(),
// [&](const cxxExchComp &comp) {
// return comp.Get_formula() == formular;
// });
// if (it != exchange->Get_exchange_comps().end()) {
// const size_t i = this->exchange_comps.size();
// exchange_comps.push_back(std::make_unique<ExchangeCompWrapper>(*it));
// header_it += this->exchange_comps[i]->size();
// num_elements += this->exchange_comps[i]->size();
// continue;
// }
// header_it++;
// }
// if (exchange_comps.size() != defined_comps) {
// throw std::runtime_error(
// "Not all exchange components found in Phreeqc variables");
// }
}
void ExchangeWrapper::get(std::span<LDBLE> &exchange) const {
std::size_t offset = 0;
for (const auto &comp : exchange_comps) {
std::span<LDBLE> comp_span = exchange.subspan(offset, comp->size());
comp->get(comp_span);
offset += comp->size();
}
}
void ExchangeWrapper::set(const std::span<LDBLE> &exchange) {
std::size_t offset = 0;
for (const auto &comp : exchange_comps) {
std::span<LDBLE> comp_span = exchange.subspan(offset, comp->size());
comp->set(comp_span);
offset += comp->size();
}
}
std::vector<std::string>
ExchangeWrapper::names(cxxExchange *exchange,
std::vector<std::string> &exchange_formulas) {
std::vector<std::string> e_names;
for (const auto &comp : exchange->Get_exchange_comps()) {
const std::string &formular = comp.Get_formula();
exchange_formulas.push_back(formular);
e_names.push_back(formular);
e_names.push_back(formular + "_cb");
e_names.push_back(formular + "_la");
e_names.push_back(formular + "_phase_proportion");
e_names.push_back(formular + "_formular_z");
for (const auto &total : comp.Get_totals()) {
if (total.first == formular) {
continue;
}
e_names.push_back(total.first + formular);
}
}
return e_names;
}

View File

@ -1,4 +1,6 @@
#include <IPhreeqcPOET.hpp>
#include <PhreeqcInit.hpp>
#include "Solution.h"
#include <algorithm>
#include <cstddef>
@ -37,9 +39,19 @@ createConcVector(const std::vector<std::string> &conc_names,
return conc_vec;
}
void IPhreeqcPOET::parseInit() {
PhreeqcInit::PhreeqcInit(const std::string &database,
const std::string &input_script)
: IPhreeqc() {
this->LoadDatabaseString(database.c_str());
this->RunString(input_script.c_str());
std::map<int, std::pair<essential_names, std::vector<double>>> init_values;
this->parseInit();
pqc_mat = this->buildPhreeqcMat();
}
void PhreeqcInit::parseInit() {
std::map<int, essential_names> init_values;
for (const auto &[id, val] : this->PhreeqcPtr->Get_Rxn_solution_map()) {
// A key less than zero indicates an internal solution
@ -47,16 +59,50 @@ void IPhreeqcPOET::parseInit() {
continue;
}
const essential_names curr_conc_names = this->dump_essential_names(id);
essential_names curr_conc_names;
curr_conc_names[POET_SOL] = dump_solution_names(id);
init_values[id] = curr_conc_names;
// auto pair =
// std::make_pair(curr_conc_names,
// this->get_essential_values_init(id,
// curr_conc_names[0]));
// raw_initials[id] = pair;
}
std::vector<std::string> union_solution_names;
for (const auto &[id, val] : init_values) {
union_solution_names =
unionStringVectors(union_solution_names, val[POET_SOL]);
}
for (auto &[id, val] : init_values) {
dump_reactant_names(id, union_solution_names, val);
std::vector<std::string> solution_order(val[POET_SOL].begin() + 3,
val[POET_SOL].end());
auto pair = std::make_pair(
curr_conc_names, this->get_essential_values(id, curr_conc_names[0]));
val, this->get_essential_values_init(id, solution_order));
raw_initials[id] = pair;
}
}
IPhreeqcPOET::essential_names IPhreeqcPOET::union_raws(const RawMap &raws) {
IPhreeqcPOET::essential_names names;
std::string PhreeqcInit::subExchangeName(std::string name) {
for (const auto &species : this->PhreeqcPtr->Get_species_list()) {
const std::string &species_name = species.s->name;
// check if `name` is a prefix of `species_name`
if (species_name.compare(0, name.size(), name) == 0) {
return species_name;
}
}
return name;
};
PhreeqcInit::essential_names PhreeqcInit::union_raws(const RawMap &raws) {
PhreeqcInit::essential_names names;
for (const auto &[sol_id, val] : raws) {
for (std::size_t i = 0; i < names.size(); i++) {
names[i] = unionStringVectors(names[i], val.first[i]);
@ -71,8 +117,8 @@ IPhreeqcPOET::essential_names IPhreeqcPOET::union_raws(const RawMap &raws) {
}
std::vector<std::vector<double>>
IPhreeqcPOET::conc_from_essentials(const RawMap &raws,
const essential_names &names) {
PhreeqcInit::conc_from_essentials(const RawMap &raws,
const essential_names &names) {
std::vector<std::vector<double>> values;
for (const auto &[key, val] : raws) {
@ -94,10 +140,10 @@ IPhreeqcPOET::conc_from_essentials(const RawMap &raws,
return values;
}
IPhreeqcPOET::PhreeqcMat IPhreeqcPOET::getPhreeqcMat() {
PhreeqcInit::PhreeqcMat PhreeqcInit::buildPhreeqcMat() {
std::vector<std::vector<double>> values;
const IPhreeqcPOET::essential_names ess_names =
const PhreeqcInit::essential_names ess_names =
this->union_raws(this->raw_initials);
const std::vector<std::vector<double>> conc_values =
@ -117,8 +163,8 @@ IPhreeqcPOET::PhreeqcMat IPhreeqcPOET::getPhreeqcMat() {
return {.names = conc_names, .ids = ids, .values = conc_values};
}
IPhreeqcPOET::ModulesArray
IPhreeqcPOET::getModuleSizes(const std::vector<int> &cell_ids) {
PhreeqcInit::ModulesArray
PhreeqcInit::getModuleSizes(const std::vector<int> &cell_ids) {
ModulesArray module_sizes;
RawMap raws;
@ -126,7 +172,7 @@ IPhreeqcPOET::getModuleSizes(const std::vector<int> &cell_ids) {
raws[id] = this->raw_initials[id];
}
const IPhreeqcPOET::essential_names ess_names = this->union_raws(raws);
const PhreeqcInit::essential_names ess_names = this->union_raws(raws);
std::transform(ess_names.begin(), ess_names.end(), module_sizes.begin(),
[](const auto &mod) { return mod.size(); });

View File

@ -1,119 +0,0 @@
#include <IPhreeqcPOET.hpp>
IPhreeqcPOET::essential_names
IPhreeqcPOET::dump_essential_names(std::size_t cell_number) {
essential_names eNames;
// Solutions
if (this->Get_solution(cell_number) != NULL) {
std::vector<std::string> &eSolNames = eNames[POET_SOL];
this->Get_solution(cell_number)->dump_essential_names(eSolNames);
}
// Exchange
if (this->Get_exchange(cell_number) != NULL) {
std::vector<std::string> &eExchNames = eNames[POET_EXCH];
this->Get_exchange(cell_number)->dump_essential_names(eExchNames);
}
// Kinetics
if (this->Get_kinetic(cell_number) != NULL) {
std::vector<std::string> &eKinNames = eNames[POET_KIN];
this->Get_kinetic(cell_number)->dump_essential_names(eKinNames);
}
// PPassemblage
if (this->Get_equilibrium(cell_number) != NULL) {
std::vector<std::string> &eEquNames = eNames[POET_EQUIL];
this->Get_equilibrium(cell_number)->dump_essential_names(eEquNames);
}
// Surface
if (this->Get_surface(cell_number) != NULL) {
std::vector<std::string> &eSurfNames = eNames[POET_SURF];
this->Get_surface(cell_number)->dump_essential_names(eSurfNames);
}
return eNames;
}
std::vector<double>
IPhreeqcPOET::get_essential_values(std::size_t cell_number,
const std::vector<std::string> &order) {
std::vector<double> essentials;
// Solutions
if (this->Get_solution(cell_number) != NULL) {
std::vector<double> sol_values;
this->Get_solution(cell_number)->get_essential_values(sol_values, order);
essentials.insert(essentials.end(), sol_values.begin(), sol_values.end());
}
// Exchange
if (this->Get_exchange(cell_number) != NULL) {
std::vector<double> exch_values;
this->Get_exchange(cell_number)->get_essential_values(exch_values);
essentials.insert(essentials.end(), exch_values.begin(), exch_values.end());
}
// Kinetics
if (this->Get_kinetic(cell_number) != NULL) {
std::vector<double> kin_values;
this->Get_kinetic(cell_number)->get_essential_values(kin_values);
essentials.insert(essentials.end(), kin_values.begin(), kin_values.end());
}
// PPassemblage
if (this->Get_equilibrium(cell_number) != NULL) {
std::vector<double> equ_values;
this->Get_equilibrium(cell_number)->get_essential_values(equ_values);
essentials.insert(essentials.end(), equ_values.begin(), equ_values.end());
}
// Surface
if (this->Get_surface(cell_number) != NULL) {
std::vector<double> surf_values;
this->Get_surface(cell_number)->get_essential_values(surf_values);
essentials.insert(essentials.end(), surf_values.begin(), surf_values.end());
}
return essentials;
}
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();
// Solutions
if (this->Get_solution(cell_number) != NULL) {
this->Get_solution(cell_number)->set_essential_values(dump_it, order);
}
// Exchange
if (this->Get_exchange(cell_number) != NULL) {
this->Get_exchange(cell_number)->set_essential_values(dump_it);
}
// Kinetics
if (this->Get_kinetic(cell_number) != NULL) {
this->Get_kinetic(cell_number)->set_essential_values(dump_it);
}
// PPassemblage
if (this->Get_equilibrium(cell_number) != NULL) {
this->Get_equilibrium(cell_number)->set_essential_values(dump_it);
}
// Surface
if (this->Get_surface(cell_number) != NULL) {
this->Get_surface(cell_number)->set_essential_values(dump_it);
}
}

251
poet/src/InitGetSet.cpp Normal file
View File

@ -0,0 +1,251 @@
#include "EquilibriumWrapper.hpp"
#include "ExchangeWrapper.hpp"
#include "KineticWrapper.hpp"
#include "PhreeqcInit.hpp"
#include "SolutionWrapper.hpp"
#include "SurfaceWrapper.hpp"
#include "global_structures.h"
#include <cassert>
#include <cstddef>
#include <set>
#include <span>
#include <string>
#include <vector>
std::vector<std::string> PhreeqcInit::dump_solution_names(int cell_number) {
constexpr std::size_t SKIP_H_O_CB = 3;
std::vector<std::string> placeholder;
return find_all_valence_states(
SolutionWrapper::names(this->Get_solution(cell_number), placeholder),
SKIP_H_O_CB);
}
void PhreeqcInit::dump_reactant_names(
int cell_number, const std::vector<std::string> union_sol_names,
essential_names &names) {
// Exchange
if (this->Get_exchange(cell_number) != NULL) {
auto *exchange = this->Get_exchange(cell_number);
std::vector<std::string> exch_formulas;
names[POET_EXCH] = ExchangeWrapper::names(exchange, exch_formulas);
this->exchanger[cell_number] = exch_formulas;
}
// Kinetics
if (this->Get_kinetic(cell_number) != NULL) {
auto *kinetic = this->Get_kinetic(cell_number);
std::vector<std::string> kin_comps;
names[POET_KIN] = KineticWrapper::names(kinetic, kin_comps);
this->kinetics[cell_number] = kin_comps;
}
// PPassemblage
if (this->Get_equilibrium(cell_number) != NULL) {
auto *equilibrium = this->Get_equilibrium(cell_number);
std::vector<std::string> equ_names;
names[POET_EQUIL] = EquilibriumWrapper::names(equilibrium, equ_names);
this->equilibrium[cell_number] = equ_names;
}
// Surface
if (this->Get_surface(cell_number) != NULL) {
auto *surface = this->Get_surface(cell_number);
if (this->surface_primaries.empty()) {
for (std::size_t i = 3; i < union_sol_names.size(); i++) {
const auto master_primary = this->PhreeqcPtr->master_bsearch_primary(
union_sol_names[i].c_str());
if (master_primary != NULL) {
this->surface_primaries.insert(master_primary->elt->name);
}
}
}
std::vector<std::string> comp_formulas;
std::vector<std::string> charge_names;
names[POET_SURF] = SurfaceWrapper::names(surface, this->surface_primaries,
comp_formulas, charge_names);
this->surface_comps[cell_number] = comp_formulas;
this->surface_charge[cell_number] = charge_names;
}
}
std::vector<std::string> PhreeqcInit::find_all_valence_states(
const std::vector<std::string> &solution_names, const std::size_t offset) {
std::vector<std::string> solution_with_valences(
solution_names.begin(), solution_names.begin() + offset);
// to avoid duplicates store already evaluated master species
std::set<std::string> master_species_found;
for (std::size_t i = offset; i < solution_names.size(); i++) {
const auto master_primary =
this->PhreeqcPtr->master_bsearch_primary(solution_names[i].c_str());
assert(master_primary != NULL);
const std::string master_species(master_primary->elt->name);
// in case we already found valences for this master species we skip it
if (master_species_found.contains(master_species)) {
continue;
}
master_species_found.insert(master_species);
bool has_valences = false;
std::size_t inner_loop_j = 0;
std::size_t last_valence = inner_loop_j;
// we HAVE to assume master species are already sorted!
// loop over all known master species
for (inner_loop_j = 0; inner_loop_j < this->PhreeqcPtr->master.size();
inner_loop_j++) {
std::string curr_master_species(
this->PhreeqcPtr->master[inner_loop_j]->elt->name);
if (curr_master_species == master_species) {
last_valence = inner_loop_j;
while (last_valence < this->PhreeqcPtr->master.size() - 1) {
std::string next_master_species(
this->PhreeqcPtr->master[last_valence + 1]->elt->name);
// check if the next name starts with the current master species
if (next_master_species.compare(0, master_species.size(),
master_species) != 0) {
break;
}
// check if the next character is an opening parenthesis
if (next_master_species[master_species.size()] != '(') {
break;
}
// if this is all true we have a valence state
has_valences = true;
last_valence++;
}
break;
}
}
// in case we found valences we add them to the solution
if (has_valences) {
// skip the master species and only add the valences
for (std::size_t k = inner_loop_j + 1; k <= last_valence; k++) {
solution_with_valences.push_back(
this->PhreeqcPtr->master[k]->elt->name);
}
continue;
}
// otherwise we just add the master species without any valences
solution_with_valences.push_back(master_species);
}
return solution_with_valences;
}
std::vector<double>
PhreeqcInit::get_essential_values_init(std::size_t cell_number,
const std::vector<std::string> &order) {
std::vector<double> essentials;
// Solutions
if (this->Get_solution(cell_number) != NULL) {
SolutionWrapper solution(this->Get_solution(cell_number), order);
std::vector<double> sol_values(solution.size());
std::span<double> sol_span{sol_values};
solution.get(sol_span);
essentials.insert(essentials.end(), sol_values.begin(), sol_values.end());
}
// Exchange
if (this->Get_exchange(cell_number) != NULL) {
ExchangeWrapper exchange(this->Get_exchange(cell_number),
this->exchanger[cell_number]);
std::vector<double> exch_values(exchange.size());
std::span<double> exch_span{exch_values};
exchange.get(exch_span);
essentials.insert(essentials.end(), exch_values.begin(), exch_values.end());
}
// Kinetics
if (this->Get_kinetic(cell_number) != NULL) {
KineticWrapper kinetic(this->Get_kinetic(cell_number),
this->kinetics[cell_number]);
std::vector<double> kin_values(kinetic.size());
std::span<double> kin_span{kin_values};
kinetic.get(kin_span);
essentials.insert(essentials.end(), kin_values.begin(), kin_values.end());
}
// PPassemblage
if (this->Get_equilibrium(cell_number) != NULL) {
EquilibriumWrapper equilibrium(this->Get_equilibrium(cell_number),
this->equilibrium[cell_number]);
std::vector<double> equ_values(equilibrium.size());
std::span<double> equ_span{equ_values};
equilibrium.get(equ_span);
essentials.insert(essentials.end(), equ_values.begin(), equ_values.end());
}
// Surface
if (this->Get_surface(cell_number) != NULL) {
SurfaceWrapper surface(
this->Get_surface(cell_number), this->surface_primaries,
this->surface_comps[cell_number], this->surface_charge[cell_number]);
std::vector<double> surf_values(surface.size());
std::span<double> surf_span{surf_values};
surface.get(surf_span);
essentials.insert(essentials.end(), surf_values.begin(), surf_values.end());
}
return essentials;
}
std::map<int, std::string> PhreeqcInit::raw_dumps() {
std::map<int, std::string> dumps;
this->SetDumpStringOn(true);
for (const auto &[sol_id, unused] : this->raw_initials) {
std::string call_string =
"DUMP\n -cells " + std::to_string(sol_id) + "\nEND\n";
this->RunString(call_string.c_str());
dumps[sol_id] = this->GetDumpString();
}
this->SetDumpStringOn(false);
return dumps;
}

View File

@ -0,0 +1,40 @@
#include "KineticWrapper.hpp"
#include <cstddef>
#include <string>
#include <vector>
KineticWrapper::KineticCompWrapper::KineticCompWrapper(cxxKineticsComp &comp)
: kin_comp(comp) {
this->num_elements = kin_comp.Get_d_params().size() + 1;
}
void KineticWrapper::KineticCompWrapper::get(std::span<LDBLE> &data) const {
data[0] = this->kin_comp.Get_m();
std::size_t next_index = 1;
for (const auto &param : this->kin_comp.Get_d_params()) {
data[next_index++] = param;
}
}
void KineticWrapper::KineticCompWrapper::set(const std::span<LDBLE> &data) {
this->kin_comp.Set_m(data[0]);
std::size_t next_index = 1;
for (auto &param : this->kin_comp.Get_d_params()) {
param = data[next_index++];
}
}
std::vector<std::string>
KineticWrapper::KineticCompWrapper::names(const cxxKineticsComp &comp) {
std::vector<std::string> names;
const std::string &comp_name = comp.Get_rate_name();
names.push_back(comp_name);
for (std::size_t i = 0; i < comp.Get_d_params().size(); i++) {
names.push_back(comp_name + "_p" + std::to_string(i + 1));
}
return names;
}

View File

@ -0,0 +1,78 @@
#include "KineticWrapper.hpp"
#include <vector>
KineticWrapper::KineticWrapper(cxxKinetics *kinetics,
const std::vector<std::string> &kin_comps)
: kinetics(kinetics) {
for (const auto &kin_name : kin_comps) {
auto it = std::find_if(kinetics->Get_kinetics_comps().begin(),
kinetics->Get_kinetics_comps().end(),
[&](const cxxKineticsComp &comp) {
return comp.Get_rate_name() == kin_name;
});
if (it == kinetics->Get_kinetics_comps().end()) {
throw std::runtime_error(
"Kinetic component not found in Phreeqc variables");
}
kinetic_comps.push_back(std::make_unique<KineticCompWrapper>(*it));
num_elements += kinetic_comps.back()->size();
}
}
void KineticWrapper::get(std::span<LDBLE> &data) const {
std::size_t offset = 0;
for (const auto &comp : kinetic_comps) {
std::span<LDBLE> comp_span = data.subspan(offset, comp->size());
comp->get(comp_span);
offset += comp->size();
}
}
void KineticWrapper::set(const std::span<LDBLE> &data) {
std::size_t offset = 0;
for (const auto &comp : kinetic_comps) {
std::span<LDBLE> comp_span = data.subspan(offset, comp->size());
comp->set(comp_span);
offset += comp->size();
}
}
std::vector<std::string>
KineticWrapper::names(cxxKinetics *kinetics,
std::vector<std::string> &kin_comps) {
std::vector<std::string> names;
for (const auto &comp : kinetics->Get_kinetics_comps()) {
std::vector<std::string> comp_names = KineticCompWrapper::names(comp);
names.insert(names.end(), comp_names.begin(), comp_names.end());
kin_comps.push_back(comp.Get_rate_name());
}
for (const auto &kin_name : kin_comps) {
auto it = std::find_if(kinetics->Get_kinetics_comps().begin(),
kinetics->Get_kinetics_comps().end(),
[&](const cxxKineticsComp &comp) {
return comp.Get_rate_name() == kin_name;
});
if (it == kinetics->Get_kinetics_comps().end()) {
throw std::runtime_error(
"Kinetic component not found in Phreeqc variables");
}
names.push_back(it->Get_rate_name());
}
return names;
}

View File

@ -0,0 +1,63 @@
#include "SolutionWrapper.hpp"
#include "NameDouble.h"
#include <vector>
SolutionWrapper::SolutionWrapper(
cxxSolution *soln, const std::vector<std::string> &solution_order_)
: solution(soln), solution_order(solution_order_) {
this->num_elements = solution_order.size() + NUM_ESSENTIALS;
auto &totals = solution->Get_totals();
}
void SolutionWrapper::get(std::span<LDBLE> &data) const {
data[0] = solution->Get_total_h();
data[1] = solution->Get_total_o();
data[2] = solution->Get_cb();
std::size_t i = NUM_ESSENTIALS;
for (const auto &tot_name : solution_order) {
auto it = solution->Get_totals().find(tot_name);
if (it == solution->Get_totals().end()) {
data[i++] = 0.0;
continue;
}
data[i++] = it->second;
}
}
void SolutionWrapper::set(const std::span<LDBLE> &data) {
std::size_t i = NUM_ESSENTIALS;
cxxNameDouble new_totals;
for (const auto &tot_name : solution_order) {
const double value = data[i++];
if (value < 1E-25) {
continue;
}
new_totals[tot_name] = value;
}
this->solution->Update(data[0], data[1], data[2], new_totals);
}
std::vector<std::string>
SolutionWrapper::names(cxxSolution *solution,
std::vector<std::string> &solution_order) {
std::vector<std::string> names;
names.push_back("H");
names.push_back("O");
names.push_back("Charge");
for (const auto &[tot_name, value] : solution->Get_totals()) {
if (tot_name == "H(0)" || tot_name == "O(0)") {
continue;
}
solution_order.push_back(tot_name);
}
names.insert(names.end(), solution_order.begin(), solution_order.end());
return names;
}

View File

@ -0,0 +1,72 @@
#include "SurfaceWrapper.hpp"
SurfaceWrapper::SurfaceChargeWrapper::SurfaceChargeWrapper(
cxxSurfaceCharge &charge, const std::set<std::string> &solution_primaries)
: surface_charge(charge), primaries(solution_primaries) {
num_elements = NUM_NOT_TOTALS + solution_primaries.size();
}
void SurfaceWrapper::SurfaceChargeWrapper::get(
std::span<LDBLE> &surface) const {
surface[0] = this->surface_charge.Get_specific_area();
surface[1] = this->surface_charge.Get_grams();
surface[2] = this->surface_charge.Get_charge_balance();
surface[3] = this->surface_charge.Get_mass_water();
surface[4] = this->surface_charge.Get_la_psi();
const auto dl_map = this->surface_charge.Get_diffuse_layer_totals();
for (auto it = this->primaries.begin(); it != this->primaries.end(); it++) {
const std::size_t index =
NUM_NOT_TOTALS + std::distance(this->primaries.begin(), it);
const auto dl_it = dl_map.find(*it);
if (dl_it == dl_map.end()) {
surface[index] = 0;
continue;
}
surface[index] = dl_it->second;
}
}
void SurfaceWrapper::SurfaceChargeWrapper::set(
const std::span<LDBLE> &surface) {
this->surface_charge.Set_specific_area(surface[0]);
this->surface_charge.Set_grams(surface[1]);
this->surface_charge.Set_charge_balance(surface[2]);
this->surface_charge.Set_mass_water(surface[3]);
this->surface_charge.Set_la_psi(surface[4]);
auto &dl_map = this->surface_charge.Get_diffuse_layer_totals();
dl_map.clear();
for (auto it = this->primaries.begin(); it != this->primaries.end(); it++) {
const std::size_t index =
NUM_NOT_TOTALS + std::distance(this->primaries.begin(), it);
if (surface[index] == 0) {
continue;
}
dl_map[*it] = surface[index];
}
}
std::vector<std::string> SurfaceWrapper::SurfaceChargeWrapper::names(
cxxSurfaceCharge *charge, const std::set<std::string> &primaries) {
std::vector<std::string> names;
const std::string &charge_name = charge->Get_name();
names.push_back(charge_name + "_area");
names.push_back(charge_name + "_grams");
names.push_back(charge_name + "_cb");
names.push_back(charge_name + "_mw");
names.push_back(charge_name + "_la");
for (const auto &name : primaries) {
names.push_back(charge_name + "_tot_" + name);
}
return names;
}

View File

@ -0,0 +1,52 @@
#include "SurfaceWrapper.hpp"
SurfaceWrapper::SurfaceCompWrapper::SurfaceCompWrapper(cxxSurfaceComp &comp)
: surface_comp(comp) {
num_elements = NUM_NOT_TOTALS + comp.Get_totals().size();
for (const auto &[name, value] : comp.Get_totals()) {
total_names.push_back(name);
}
}
void SurfaceWrapper::SurfaceCompWrapper::get(std::span<LDBLE> &surface) const {
surface[0] = this->surface_comp.Get_moles();
surface[1] = this->surface_comp.Get_la();
surface[2] = this->surface_comp.Get_charge_balance();
const auto &totals = this->surface_comp.Get_totals();
for (std::size_t i = 0; i < this->total_names.size(); i++) {
surface[NUM_NOT_TOTALS + i] = totals.at(this->total_names[i]);
}
}
void SurfaceWrapper::SurfaceCompWrapper::set(const std::span<LDBLE> &surface) {
this->surface_comp.Set_moles(surface[0]);
this->surface_comp.Set_la(surface[1]);
this->surface_comp.Set_charge_balance(surface[2]);
auto &totals = this->surface_comp.Get_totals();
totals.clear();
for (std::size_t i = 0; i < this->total_names.size(); i++) {
const std::size_t index = NUM_NOT_TOTALS + i;
totals[this->total_names[i]] = surface[index];
}
}
std::vector<std::string>
SurfaceWrapper::SurfaceCompWrapper::names(cxxSurfaceComp &comp) {
std::vector<std::string> names;
const std::string &phase_name = comp.Get_formula();
names.push_back(phase_name + "_moles");
names.push_back(phase_name + "_la");
names.push_back(phase_name + "_cb");
for (const auto &tot : comp.Get_totals()) {
names.push_back(phase_name + "_" + tot.first);
}
return names;
}

View File

@ -0,0 +1,98 @@
#include "SurfaceWrapper.hpp"
#include "SurfaceComp.h"
SurfaceWrapper::SurfaceWrapper(cxxSurface *surf,
const std::set<std::string> &solution_primaries,
const std::vector<std::string> &comp_formulas,
const std::vector<std::string> &charge_names)
: surface(surf) {
for (const auto &comp_name : comp_formulas) {
auto it = std::find_if(surface->Get_surface_comps().begin(),
surface->Get_surface_comps().end(),
[&](const cxxSurfaceComp &comp) {
return comp.Get_formula() == comp_name;
});
if (it == surface->Get_surface_comps().end()) {
throw std::runtime_error(
"Surface component not found in Phreeqc variables");
}
surface_comps.push_back(std::make_unique<SurfaceCompWrapper>(*it));
num_elements += surface_comps.back()->size();
}
for (const auto &charge_name : charge_names) {
auto it = std::find_if(surface->Get_surface_charges().begin(),
surface->Get_surface_charges().end(),
[&](const cxxSurfaceCharge &charge) {
return charge.Get_name() == charge_name;
});
if (it == surface->Get_surface_charges().end()) {
throw std::runtime_error("Surface charge not found in Phreeqc variables");
}
surface_charges.push_back(
std::make_unique<SurfaceChargeWrapper>(*it, solution_primaries));
num_elements += surface_charges.back()->size();
}
}
void SurfaceWrapper::get(std::span<LDBLE> &surface) const {
std::size_t offset = 0;
for (const auto &comp : surface_comps) {
std::span<LDBLE> comp_span = surface.subspan(offset, comp->size());
comp->get(comp_span);
offset += comp->size();
}
for (const auto &charge : surface_charges) {
std::span<LDBLE> charge_span = surface.subspan(offset, charge->size());
charge->get(charge_span);
offset += charge->size();
}
}
void SurfaceWrapper::set(const std::span<LDBLE> &surface) {
std::size_t offset = 0;
for (const auto &comp : surface_comps) {
std::span<LDBLE> comp_span = surface.subspan(offset, comp->size());
comp->set(comp_span);
offset += comp->size();
}
for (const auto &charge : surface_charges) {
std::span<LDBLE> charge_span = surface.subspan(offset, charge->size());
charge->set(charge_span);
offset += charge->size();
}
}
std::vector<std::string>
SurfaceWrapper::names(cxxSurface *surface,
const std::set<std::string> &solution_primaries,
std::vector<std::string> &comp_formulas,
std::vector<std::string> &charge_names) {
std::vector<std::string> names;
for (auto &comp : surface->Get_surface_comps()) {
comp_formulas.push_back(comp.Get_formula());
const auto charge_names = SurfaceCompWrapper::names(comp);
names.insert(names.end(), charge_names.begin(), charge_names.end());
}
for (auto &charge : surface->Get_surface_charges()) {
charge_names.push_back(charge.Get_name());
const auto comp_names =
SurfaceChargeWrapper::names(&charge, solution_primaries);
names.insert(names.end(), comp_names.begin(), comp_names.end());
}
return names;
}

View File

@ -2,17 +2,18 @@
//
//////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger)
#pragma warning( \
disable : 4786) // disable truncation warning (Only used by debugger)
#endif
#include <iostream> // std::cout std::cerr
#include <cassert> // assert
#include <algorithm> // std::sort
#include <algorithm> // std::sort
#include <cassert> // assert
#include <iostream> // std::cout std::cerr
#include "Utils.h" // define first
#include "Exchange.h"
#include "Phreeqc.h"
#include "cxxMix.h"
#include "Exchange.h"
#include "phqalloc.h"
#if defined(PHREEQCI_GUI)
@ -28,493 +29,367 @@ static char THIS_FILE[] = __FILE__;
//////////////////////////////////////////////////////////////////////
cxxExchange::cxxExchange(PHRQ_io *io)
//
// default constructor for cxxExchange
//
: cxxNumKeyword(io)
{
new_def = false;
solution_equilibria = false;
n_solution = -999;
pitzer_exchange_gammas = true;
//
// default constructor for cxxExchange
//
: cxxNumKeyword(io) {
new_def = false;
solution_equilibria = false;
n_solution = -999;
pitzer_exchange_gammas = true;
}
cxxExchange::cxxExchange(const std::map < int, cxxExchange > &entities,
cxxMix & mix, int l_n_user, PHRQ_io *io):
cxxNumKeyword(io)
{
this->n_user = this->n_user_end = l_n_user;
this->pitzer_exchange_gammas = true;
this->new_def = false;
this->n_solution = -999;
this->solution_equilibria = false;
//
// Mix exchangers
//
const std::map < int, LDBLE >&mixcomps = mix.Get_mixComps();
std::map < int, LDBLE >::const_iterator it;
for (it = mixcomps.begin(); it != mixcomps.end(); it++)
{
if (entities.find(it->first) != entities.end())
{
const cxxExchange *entity_ptr =
&(entities.find(it->first)->second);
this->add(*entity_ptr, it->second);
this->pitzer_exchange_gammas = entity_ptr->pitzer_exchange_gammas;
}
}
}
cxxExchange::~cxxExchange()
{
}
bool
cxxExchange::Get_related_phases() const
{
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
if (this->exchange_comps[i].Get_phase_name().size() > 0)
{
return (true);
}
}
return (false);
}
bool
cxxExchange::Get_related_rate() const
{
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
if (this->exchange_comps[i].Get_rate_name().size() > 0)
{
return (true);
}
}
return (false);
}
void
cxxExchange::dump_xml(std::ostream & s_oss, unsigned int indent) const
{
unsigned int i;
s_oss.precision(DBL_DIG - 1);
std::string indent0(""), indent1(""), indent2("");
for (i = 0; i < indent; ++i)
indent0.append(Utilities::INDENT);
for (i = 0; i < indent + 1; ++i)
indent1.append(Utilities::INDENT);
for (i = 0; i < indent + 2; ++i)
indent2.append(Utilities::INDENT);
// Exchange element and attributes
s_oss << indent0;
s_oss << "<exchange " << "\n";
s_oss << indent1;
s_oss << "pitzer_exchange_gammas=\"" << this->
pitzer_exchange_gammas << "\"" << "\n";
// components
s_oss << indent1;
s_oss << "<component " << "\n";
for (size_t j = 0; j < this->exchange_comps.size(); j++)
{
this->exchange_comps[j].dump_xml(s_oss, indent + 2);
}
return;
}
void
cxxExchange::dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out) const
{
unsigned int i;
s_oss.precision(DBL_DIG - 1);
std::string indent0(""), indent1(""), indent2("");
for (i = 0; i < indent; ++i)
indent0.append(Utilities::INDENT);
for (i = 0; i < indent + 1; ++i)
indent1.append(Utilities::INDENT);
for (i = 0; i < indent + 2; ++i)
indent2.append(Utilities::INDENT);
// Exchange element and attributes
s_oss << indent0;
int n_user_local = (n_out != NULL) ? *n_out : this->n_user;
s_oss << "EXCHANGE_RAW " << n_user_local << " " << this->description << "\n";
s_oss << indent1 << "# EXCHANGE_MODIFY candidate identifiers #\n";
s_oss << indent1;
s_oss << "-exchange_gammas " << (this->pitzer_exchange_gammas ? 1 : 0) << "\n";
// exchComps
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
s_oss << indent1;
s_oss << "-component " << this->exchange_comps[i].Get_formula() << "\n";
this->exchange_comps[i].dump_raw(s_oss, indent + 2);
}
s_oss << indent1 << "# EXCHANGE_MODIFY candidates with new_def=true #\n";
s_oss << indent1;
s_oss << "-new_def " << 0 << "\n";
s_oss << indent1;
s_oss << "-solution_equilibria " << 0 << "\n";
s_oss << indent1;
s_oss << "-n_solution " << this->n_solution << "\n";
s_oss << indent1 << "# Exchange workspace variables #\n";
s_oss << indent1;
s_oss << "-totals" << "\n";
this->totals.dump_raw(s_oss, indent + 1);
return;
}
void cxxExchange::dump_essential_names(
std::vector<std::string> &e_names) const {
e_names.clear();
e_names.reserve(this->exchange_comps.size() *
this->exchange_comps.at(0).Get_totals().size());
for (const auto &comp : this->exchange_comps) {
const std::string formular = comp.Get_formula();
e_names.push_back(formular);
for (const auto &total : comp.Get_totals()) {
if (total.first == formular) {
continue;
}
e_names.push_back(total.first + formular);
cxxExchange::cxxExchange(const std::map<int, cxxExchange> &entities,
cxxMix &mix, int l_n_user, PHRQ_io *io)
: cxxNumKeyword(io) {
this->n_user = this->n_user_end = l_n_user;
this->pitzer_exchange_gammas = true;
this->new_def = false;
this->n_solution = -999;
this->solution_equilibria = false;
//
// Mix exchangers
//
const std::map<int, LDBLE> &mixcomps = mix.Get_mixComps();
std::map<int, LDBLE>::const_iterator it;
for (it = mixcomps.begin(); it != mixcomps.end(); it++) {
if (entities.find(it->first) != entities.end()) {
const cxxExchange *entity_ptr = &(entities.find(it->first)->second);
this->add(*entity_ptr, it->second);
this->pitzer_exchange_gammas = entity_ptr->pitzer_exchange_gammas;
}
}
}
void cxxExchange::get_essential_values(std::vector<LDBLE> &e_values) const {
e_values.clear();
e_values.reserve(this->exchange_comps.size() *
this->exchange_comps.at(0).Get_totals().size());
for (const auto &comp : this->exchange_comps) {
const std::string formular = comp.Get_formula();
e_values.push_back(comp.Get_totals().find(formular)->second);
for (const auto &total : comp.Get_totals()) {
if (total.first == formular) {
continue;
}
e_values.push_back(total.second);
cxxExchange::~cxxExchange() {}
bool cxxExchange::Get_related_phases() const {
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
if (this->exchange_comps[i].Get_phase_name().size() > 0) {
return (true);
}
}
return (false);
}
bool cxxExchange::Get_related_rate() const {
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
if (this->exchange_comps[i].Get_rate_name().size() > 0) {
return (true);
}
}
return (false);
}
void cxxExchange::dump_xml(std::ostream &s_oss, unsigned int indent) const {
unsigned int i;
s_oss.precision(DBL_DIG - 1);
std::string indent0(""), indent1(""), indent2("");
for (i = 0; i < indent; ++i)
indent0.append(Utilities::INDENT);
for (i = 0; i < indent + 1; ++i)
indent1.append(Utilities::INDENT);
for (i = 0; i < indent + 2; ++i)
indent2.append(Utilities::INDENT);
// Exchange element and attributes
s_oss << indent0;
s_oss << "<exchange "
<< "\n";
s_oss << indent1;
s_oss << "pitzer_exchange_gammas=\"" << this->pitzer_exchange_gammas << "\""
<< "\n";
// components
s_oss << indent1;
s_oss << "<component "
<< "\n";
for (size_t j = 0; j < this->exchange_comps.size(); j++) {
this->exchange_comps[j].dump_xml(s_oss, indent + 2);
}
return;
}
void cxxExchange::dump_raw(std::ostream &s_oss, unsigned int indent,
int *n_out) const {
unsigned int i;
s_oss.precision(DBL_DIG - 1);
std::string indent0(""), indent1(""), indent2("");
for (i = 0; i < indent; ++i)
indent0.append(Utilities::INDENT);
for (i = 0; i < indent + 1; ++i)
indent1.append(Utilities::INDENT);
for (i = 0; i < indent + 2; ++i)
indent2.append(Utilities::INDENT);
void cxxExchange::set_essential_values(std::vector<LDBLE>::iterator &it) {
for (auto &comp : this->exchange_comps) {
const std::string formular = comp.Get_formula();
auto formular_total = comp.Get_totals();
formular_total[formular] = *(it++);
for (auto &total : comp.Get_totals()) {
if (total.first == formular) {
continue;
}
total.second = *(it++);
}
// Exchange element and attributes
s_oss << indent0;
int n_user_local = (n_out != NULL) ? *n_out : this->n_user;
s_oss << "EXCHANGE_RAW " << n_user_local << " "
<< this->description << "\n";
s_oss << indent1 << "# EXCHANGE_MODIFY candidate identifiers #\n";
s_oss << indent1;
s_oss << "-exchange_gammas "
<< (this->pitzer_exchange_gammas ? 1 : 0) << "\n";
// exchComps
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
s_oss << indent1;
s_oss << "-component "
<< this->exchange_comps[i].Get_formula() << "\n";
this->exchange_comps[i].dump_raw(s_oss, indent + 2);
}
s_oss << indent1 << "# EXCHANGE_MODIFY candidates with new_def=true #\n";
s_oss << indent1;
s_oss << "-new_def " << 0 << "\n";
s_oss << indent1;
s_oss << "-solution_equilibria " << 0 << "\n";
s_oss << indent1;
s_oss << "-n_solution " << this->n_solution << "\n";
s_oss << indent1 << "# Exchange workspace variables #\n";
s_oss << indent1;
s_oss << "-totals"
<< "\n";
this->totals.dump_raw(s_oss, indent + 1);
return;
}
void
cxxExchange::read_raw(CParser & parser, bool check)
{
std::istream::pos_type ptr;
std::istream::pos_type next_char;
std::string token;
bool useLastLine(false);
void cxxExchange::read_raw(CParser &parser, bool check) {
std::istream::pos_type ptr;
std::istream::pos_type next_char;
std::string token;
bool useLastLine(false);
// Read exchange number and description
this->read_number_description(parser);
this->Set_new_def(false);
bool pitzer_exchange_gammas_defined(false);
// Read exchange number and description
this->read_number_description(parser);
this->Set_new_def(false);
for (;;)
{
int opt;
if (useLastLine == false)
{
opt = parser.get_option(vopts, next_char);
}
else
{
opt = parser.getOptionFromLastLine(vopts, next_char, true);
}
useLastLine = false;
switch (opt)
{
case CParser::OPT_EOF:
break;
case CParser::OPT_KEYWORD:
break;
case CParser::OPT_DEFAULT:
case CParser::OPT_ERROR:
opt = CParser::OPT_EOF;
parser.error_msg("Unknown input in EXCH_COMP_RAW keyword.",
PHRQ_io::OT_CONTINUE);
parser.error_msg(parser.line().c_str(), PHRQ_io::OT_CONTINUE);
break;
bool pitzer_exchange_gammas_defined(false);
case 0: // pitzer_exchange_gammas
case 2: // exchange_gammas
if (!(parser.get_iss() >> this->pitzer_exchange_gammas))
{
this->pitzer_exchange_gammas = false;
parser.incr_input_error();
parser.
error_msg
("Expected boolean value for pitzer_exchange_gammas.",
PHRQ_io::OT_CONTINUE);
}
pitzer_exchange_gammas_defined = true;
break;
case 1: // component
{
std::string str;
if (!(parser.get_iss() >> str))
{
parser.incr_input_error();
parser.error_msg("Expected string value for component name.",
PHRQ_io::OT_CONTINUE);
}
else
{
cxxExchComp temp_comp(this->io);
temp_comp.Set_formula(str.c_str());
cxxExchComp *comp_ptr = this->Find_comp(str);
if (comp_ptr)
{
temp_comp = *comp_ptr;
}
temp_comp.read_raw(parser, check);
if (comp_ptr)
{
for (size_t j = 0; j < this->exchange_comps.size(); j++)
{
if (Utilities::strcmp_nocase(this->exchange_comps[j].Get_formula().c_str(), str.c_str()) == 0)
{
this->exchange_comps[j] = temp_comp;
}
}
}
else
{
this->exchange_comps.push_back(temp_comp);
}
useLastLine = true;
}
}
break;
case 3: // new_def
if (!(parser.get_iss() >> this->new_def))
{
this->new_def = false;
parser.incr_input_error();
parser.
error_msg
("Expected boolean value for new_def.",
PHRQ_io::OT_CONTINUE);
}
break;
case 4: // solution_equilibria
if (!(parser.get_iss() >> this->solution_equilibria))
{
this->solution_equilibria = false;
parser.incr_input_error();
parser.
error_msg
("Expected boolean value for solution_equilibria.",
PHRQ_io::OT_CONTINUE);
}
break;
case 5: // n_solution
if (!(parser.get_iss() >> this->n_solution))
{
this->n_solution = -999;
parser.incr_input_error();
parser.
error_msg
("Expected integer value for n_solution.",
PHRQ_io::OT_CONTINUE);
}
break;
case 6: // totals
if (this->totals.read_raw(parser, next_char) !=
CParser::PARSER_OK)
{
parser.incr_input_error();
parser.
error_msg
("Expected element name and molality for Exchange totals.",
PHRQ_io::OT_CONTINUE);
}
break;
}
if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD)
break;
}
// members that must be defined
if (check)
{
if (pitzer_exchange_gammas_defined == false)
{
parser.incr_input_error();
parser.
error_msg
("Pitzer_exchange_gammsa not defined for EXCHANGE_RAW input.",
PHRQ_io::OT_CONTINUE);
}
}
this->Sort_comps();
for (;;) {
int opt;
if (useLastLine == false) {
opt = parser.get_option(vopts, next_char);
} else {
opt = parser.getOptionFromLastLine(vopts, next_char, true);
}
useLastLine = false;
switch (opt) {
case CParser::OPT_EOF:
break;
case CParser::OPT_KEYWORD:
break;
case CParser::OPT_DEFAULT:
case CParser::OPT_ERROR:
opt = CParser::OPT_EOF;
parser.error_msg("Unknown input in EXCH_COMP_RAW keyword.",
PHRQ_io::OT_CONTINUE);
parser.error_msg(parser.line().c_str(), PHRQ_io::OT_CONTINUE);
break;
case 0: // pitzer_exchange_gammas
case 2: // exchange_gammas
if (!(parser.get_iss() >> this->pitzer_exchange_gammas)) {
this->pitzer_exchange_gammas = false;
parser.incr_input_error();
parser.error_msg("Expected boolean value for pitzer_exchange_gammas.",
PHRQ_io::OT_CONTINUE);
}
pitzer_exchange_gammas_defined = true;
break;
case 1: // component
{
std::string str;
if (!(parser.get_iss() >> str)) {
parser.incr_input_error();
parser.error_msg("Expected string value for component name.",
PHRQ_io::OT_CONTINUE);
} else {
cxxExchComp temp_comp(this->io);
temp_comp.Set_formula(str.c_str());
cxxExchComp *comp_ptr = this->Find_comp(str);
if (comp_ptr) {
temp_comp = *comp_ptr;
}
temp_comp.read_raw(parser, check);
if (comp_ptr) {
for (size_t j = 0; j < this->exchange_comps.size(); j++) {
if (Utilities::strcmp_nocase(
this->exchange_comps[j].Get_formula().c_str(),
str.c_str()) == 0) {
this->exchange_comps[j] = temp_comp;
}
}
} else {
this->exchange_comps.push_back(temp_comp);
}
useLastLine = true;
}
} break;
case 3: // new_def
if (!(parser.get_iss() >> this->new_def)) {
this->new_def = false;
parser.incr_input_error();
parser.error_msg("Expected boolean value for new_def.",
PHRQ_io::OT_CONTINUE);
}
break;
case 4: // solution_equilibria
if (!(parser.get_iss() >> this->solution_equilibria)) {
this->solution_equilibria = false;
parser.incr_input_error();
parser.error_msg("Expected boolean value for solution_equilibria.",
PHRQ_io::OT_CONTINUE);
}
break;
case 5: // n_solution
if (!(parser.get_iss() >> this->n_solution)) {
this->n_solution = -999;
parser.incr_input_error();
parser.error_msg("Expected integer value for n_solution.",
PHRQ_io::OT_CONTINUE);
}
break;
case 6: // totals
if (this->totals.read_raw(parser, next_char) != CParser::PARSER_OK) {
parser.incr_input_error();
parser.error_msg(
"Expected element name and molality for Exchange totals.",
PHRQ_io::OT_CONTINUE);
}
break;
}
if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD)
break;
}
// members that must be defined
if (check) {
if (pitzer_exchange_gammas_defined == false) {
parser.incr_input_error();
parser.error_msg(
"Pitzer_exchange_gammsa not defined for EXCHANGE_RAW input.",
PHRQ_io::OT_CONTINUE);
}
}
this->Sort_comps();
}
void
cxxExchange::add(const cxxExchange & addee, LDBLE extensive)
//
// Add existing exchange to "this" exchange
//
void cxxExchange::add(const cxxExchange &addee, LDBLE extensive)
//
// Add existing exchange to "this" exchange
//
{
// exchComps
if (extensive == 0.0)
return;
for (size_t i = 0; i < addee.exchange_comps.size(); i++)
{
size_t j;
for (j = 0; j < this->Get_exchange_comps().size(); j++)
if (addee.exchange_comps[i].Get_formula() == this->exchange_comps[j].Get_formula())
{
this->exchange_comps[j].add(addee.exchange_comps[i], extensive);
break;
}
if (j == this->exchange_comps.size())
{
cxxExchComp exc = addee.exchange_comps[i];
exc.multiply(extensive);
this->exchange_comps.push_back(exc);
}
}
this->pitzer_exchange_gammas = addee.pitzer_exchange_gammas;
// exchComps
if (extensive == 0.0)
return;
for (size_t i = 0; i < addee.exchange_comps.size(); i++) {
size_t j;
for (j = 0; j < this->Get_exchange_comps().size(); j++)
if (addee.exchange_comps[i].Get_formula() ==
this->exchange_comps[j].Get_formula()) {
this->exchange_comps[j].add(addee.exchange_comps[i], extensive);
break;
}
if (j == this->exchange_comps.size()) {
cxxExchComp exc = addee.exchange_comps[i];
exc.multiply(extensive);
this->exchange_comps.push_back(exc);
}
}
this->pitzer_exchange_gammas = addee.pitzer_exchange_gammas;
}
void
cxxExchange::totalize()
{
this->totals.clear();
// component structures
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
this->totals.add_extensive(this->exchange_comps[i].Get_totals(), 1.0);
this->totals.add("Charge", this->exchange_comps[i].Get_charge_balance());
}
return;
void cxxExchange::totalize() {
this->totals.clear();
// component structures
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
this->totals.add_extensive(this->exchange_comps[i].Get_totals(), 1.0);
this->totals.add("Charge", this->exchange_comps[i].Get_charge_balance());
}
return;
}
bool
cxxExchange::Get_pitzer_exchange_gammas() const
{
return this->pitzer_exchange_gammas;
bool cxxExchange::Get_pitzer_exchange_gammas() const {
return this->pitzer_exchange_gammas;
}
void
cxxExchange::Set_pitzer_exchange_gammas(bool b)
{
this->pitzer_exchange_gammas = b;
void cxxExchange::Set_pitzer_exchange_gammas(bool b) {
this->pitzer_exchange_gammas = b;
}
const cxxNameDouble &
cxxExchange::Get_totals() const
{
return totals;
const cxxNameDouble &cxxExchange::Get_totals() const { return totals; }
cxxExchComp *cxxExchange::Find_comp(std::string s) {
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
cxxNameDouble nd(this->exchange_comps[i].Get_totals());
cxxNameDouble::iterator nd_it;
for (nd_it = nd.begin(); nd_it != nd.end(); nd_it++) {
if (nd_it->first == s) {
return (&(this->exchange_comps[i]));
}
}
}
return NULL;
}
cxxExchComp *cxxExchange::Find_comp(std::string s)
{
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
cxxNameDouble nd(this->exchange_comps[i].Get_totals());
cxxNameDouble::iterator nd_it;
for (nd_it = nd.begin(); nd_it != nd.end(); nd_it++)
{
if(nd_it->first == s)
{
return (&(this->exchange_comps[i]));
}
}
}
return NULL;
}
void cxxExchange::
Sort_comps(void)
{
// sort comps
{
std::map<std::string, cxxExchComp> comp_map;
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
comp_map[this->exchange_comps[i].Get_formula()] = this->exchange_comps[i];
}
this->exchange_comps.clear();
std::map<std::string, cxxExchComp>::iterator it;
for (it = comp_map.begin(); it != comp_map.end(); it++)
{
this->exchange_comps.push_back(it->second);
}
}
void cxxExchange::Sort_comps(void) {
// sort comps
{
std::map<std::string, cxxExchComp> comp_map;
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
comp_map[this->exchange_comps[i].Get_formula()] = this->exchange_comps[i];
}
this->exchange_comps.clear();
std::map<std::string, cxxExchComp>::iterator it;
for (it = comp_map.begin(); it != comp_map.end(); it++) {
this->exchange_comps.push_back(it->second);
}
}
}
/* ---------------------------------------------------------------------- */
void
cxxExchange::Serialize(Dictionary & dictionary, std::vector < int >&ints, std::vector < double >&doubles)
void cxxExchange::Serialize(Dictionary &dictionary, std::vector<int> &ints,
std::vector<double> &doubles)
/* ---------------------------------------------------------------------- */
{
ints.push_back(this->n_user);
ints.push_back((int) this->exchange_comps.size());
for (size_t i = 0; i < this->exchange_comps.size(); i++)
{
exchange_comps[i].Serialize(dictionary, ints, doubles);
}
ints.push_back(this->pitzer_exchange_gammas ? 1 : 0);
ints.push_back(this->new_def ? 1 : 0);
ints.push_back(this->solution_equilibria ? 1 : 0);
ints.push_back(this->n_solution);
this->totals.Serialize(dictionary, ints, doubles);
ints.push_back(this->n_user);
ints.push_back((int)this->exchange_comps.size());
for (size_t i = 0; i < this->exchange_comps.size(); i++) {
exchange_comps[i].Serialize(dictionary, ints, doubles);
}
ints.push_back(this->pitzer_exchange_gammas ? 1 : 0);
ints.push_back(this->new_def ? 1 : 0);
ints.push_back(this->solution_equilibria ? 1 : 0);
ints.push_back(this->n_solution);
this->totals.Serialize(dictionary, ints, doubles);
}
/* ---------------------------------------------------------------------- */
void
cxxExchange::Deserialize(Dictionary & dictionary, std::vector < int >&ints, std::vector < double >&doubles, int &ii, int &dd)
void cxxExchange::Deserialize(Dictionary &dictionary, std::vector<int> &ints,
std::vector<double> &doubles, int &ii, int &dd)
/* ---------------------------------------------------------------------- */
{
this->n_user = ints[ii++];
this->n_user_end = this->n_user;
this->description = " ";
int count = ints[ii++];
this->exchange_comps.clear();
for (int n = 0; n < count; n++)
{
cxxExchComp ec(this->io);
ec.Deserialize(dictionary, ints, doubles, ii, dd);
this->exchange_comps.push_back(ec);
}
this->pitzer_exchange_gammas = (ints[ii++] != 0);
this->new_def = (ints[ii++] != 0);
this->solution_equilibria = (ints[ii++] != 0);
this->n_solution = ints[ii++];
this->totals.Deserialize(dictionary, ints, doubles, ii, dd);
this->n_user = ints[ii++];
this->n_user_end = this->n_user;
this->description = " ";
int count = ints[ii++];
this->exchange_comps.clear();
for (int n = 0; n < count; n++) {
cxxExchComp ec(this->io);
ec.Deserialize(dictionary, ints, doubles, ii, dd);
this->exchange_comps.push_back(ec);
}
this->pitzer_exchange_gammas = (ints[ii++] != 0);
this->new_def = (ints[ii++] != 0);
this->solution_equilibria = (ints[ii++] != 0);
this->n_solution = ints[ii++];
this->totals.Deserialize(dictionary, ints, doubles, ii, dd);
}
const std::vector< std::string >::value_type temp_vopts[] = {
std::vector< std::string >::value_type("pitzer_exchange_gammas"), // 0
std::vector< std::string >::value_type("component"), // 1
std::vector< std::string >::value_type("exchange_gammas"), // 2
std::vector< std::string >::value_type("new_def"), // 3
std::vector< std::string >::value_type("solution_equilibria"), // 4
std::vector< std::string >::value_type("n_solution"), // 5
std::vector< std::string >::value_type("totals") // 6
};
const std::vector< std::string > cxxExchange::vopts(temp_vopts, temp_vopts + sizeof temp_vopts / sizeof temp_vopts[0]);
const std::vector<std::string>::value_type temp_vopts[] = {
std::vector<std::string>::value_type("pitzer_exchange_gammas"), // 0
std::vector<std::string>::value_type("component"), // 1
std::vector<std::string>::value_type("exchange_gammas"), // 2
std::vector<std::string>::value_type("new_def"), // 3
std::vector<std::string>::value_type("solution_equilibria"), // 4
std::vector<std::string>::value_type("n_solution"), // 5
std::vector<std::string>::value_type("totals") // 6
};
const std::vector<std::string>
cxxExchange::vopts(temp_vopts,
temp_vopts + sizeof temp_vopts / sizeof temp_vopts[0]);

View File

@ -20,11 +20,8 @@ public:
cxxMix & mx, int n_user, PHRQ_io *io=NULL);
~cxxExchange();
void dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out=NULL) const;
void dump_essential_names(std::vector<std::string> &e_names) const;
void get_essential_values(std::vector<LDBLE> &e_values) const;
void set_essential_values(std::vector<LDBLE>::iterator &it);
void dump_raw(std::ostream &s_oss, unsigned int indent,
int *n_out = NULL) const;
void read_raw(CParser & parser, bool check = true);

View File

@ -131,40 +131,6 @@ cxxPPassemblage::dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out)
this->assemblage_totals.dump_raw(s_oss, indent + 1);
}
void cxxPPassemblage::dump_essential_names(
std::vector<std::string> &e_names) const {
e_names.clear();
e_names.reserve(this->pp_assemblage_comps.size() * 2);
for (const auto &pp_comp : this->pp_assemblage_comps) {
e_names.push_back(pp_comp.first);
e_names.push_back(pp_comp.first + "_si");
}
return;
}
void cxxPPassemblage::get_essential_values(std::vector<LDBLE> &e_values) const {
e_values.clear();
e_values.reserve(this->pp_assemblage_comps.size() * 2);
for (const auto &pp_comp : this->pp_assemblage_comps) {
e_values.push_back(pp_comp.second.Get_moles());
e_values.push_back(pp_comp.second.Get_si());
}
return;
}
void cxxPPassemblage::set_essential_values(std::vector<LDBLE>::iterator &it) {
for (auto &pp_comp : this->pp_assemblage_comps) {
pp_comp.second.Set_moles(*(it++));
pp_comp.second.Set_si(*(it++));
}
return;
}
void
cxxPPassemblage::read_raw(CParser & parser, bool check)
{

View File

@ -23,10 +23,6 @@ class cxxPPassemblage:public cxxNumKeyword
void dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out=NULL) const;
void dump_essential_names(std::vector<std::string> &e_names) const;
void get_essential_values(std::vector<LDBLE> &e_values) const;
void set_essential_values(std::vector<LDBLE>::iterator &it);
void read_raw(CParser &parser, bool check = true);
const cxxNameDouble & Get_assemblage_totals() const

View File

@ -424,7 +424,10 @@ public:
int initial_exchangers(int print);
int initial_gas_phases(int print);
int initial_solutions(int print);
int step_save_exch(int n_user);
int initial_solutions_poet(int sol_id);
int step_save_exch(int n_user);
int step_save_surf(int n_user);
int initial_surfaces(int print);
int reactions(void);
@ -1830,8 +1833,10 @@ protected:
friend class IPhreeqcMMS;
friend class IPhreeqcPhast;
friend class PhreeqcRM;
friend class PhreeqcInit;
friend class PhreeqcEngine;
std::vector<int> keycount; // used to mark keywords that have been read
std::vector<int> keycount; // used to mark keywords that have been read
public:
static const class const_iso iso_defaults[];

View File

@ -367,70 +367,6 @@ cxxSolution::dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out) con
return;
}
void cxxSolution::dump_essential_names(
std::vector<std::string> &e_names) const {
e_names.clear();
e_names.reserve(this->totals.size() + 3);
// e_names.push_back("H20");
e_names.push_back("H");
e_names.push_back("O");
e_names.push_back("Charge");
for (const auto &total : this->totals) {
if ((total.first == "O(0)") || (total.first == "H(0)")) {
continue;
}
e_names.push_back(total.first);
}
return;
}
void cxxSolution::get_essential_values(
std::vector<LDBLE> &e_values, const std::vector<std::string> &order) const {
e_values.clear();
e_values.reserve(this->totals.size() + 4);
// e_values.push_back(mass_water);
e_values.push_back(total_h);
e_values.push_back(total_o);
e_values.push_back(cb);
for (int i = 3; i < order.size(); i++) {
const auto tot = totals.find(order[i]);
if (tot == totals.end()) {
e_values.push_back(0);
continue;
}
e_values.push_back((tot->second));
}
return;
}
void cxxSolution::set_essential_values(std::vector<LDBLE>::iterator &it,
const std::vector<std::string> &order) {
// skip first field of moles H2O
// it++;
double t_h = *(it++);
double t_o = *(it++);
double c_b = *(it++);
cxxNameDouble nd;
for (int i = 3; i < order.size(); i++) {
double curr_val = *(it++);
if (curr_val < 0) {
curr_val = 0;
}
nd.add(order[i].c_str(), curr_val);
}
this->Update(t_h, t_o, c_b, nd);
}
#ifdef USE_REVISED_READ_RAW
void
cxxSolution::read_raw(CParser & parser, bool check)
@ -1258,17 +1194,20 @@ cxxSolution::Update(LDBLE h_tot, LDBLE o_tot, LDBLE charge, const cxxNameDouble
this->cb = charge;
this->mass_water = o_tot / 55.5;
// Don`t bother to update activities?
this->Update(const_nd);
//this->totals = const_nd;
cxxNameDouble::iterator it;
for (it = this->totals.begin(); it != this->totals.end(); it++)
{
if (it->second < 1e-25)
{
it->second = 0.0;
}
}
// Don`t bother to update activities?
// this->Update(const_nd);
// UP: instead of updating, we just set the new totals ...
this->totals = const_nd;
// UP: ... and doesn't need another check for zero values
// cxxNameDouble::iterator it;
// for (it = this->totals.begin(); it != this->totals.end(); it++) {
// if (it->second < 1e-25) {
// it->second = 0.0;
// }
// }
}
void
cxxSolution::Update_activities(const cxxNameDouble &original_tot)

View File

@ -105,13 +105,6 @@ class cxxSolution:public cxxNumKeyword
void dump_xml(std::ostream & os, unsigned int indent = 0) const;
void dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out=NULL) const;
void dump_essential_names(std::vector<std::string> &e_names) const;
void get_essential_values(std::vector<LDBLE> &e_values,
const std::vector<std::string> &order) const;
void set_essential_values(std::vector<LDBLE>::iterator &it,
const std::vector<std::string> &order);
LDBLE Get_master_activity(char *string) const;
void Set_master_activity(char *string, LDBLE value);
LDBLE Get_total(const char *string) const;

View File

@ -178,105 +178,6 @@ cxxSurface::dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out) cons
return;
}
void cxxSurface::dump_essential_names(std::vector<std::string> &e_names) {
// this is just some reserve size, might be changed in the future
const int reserve_size =
surface_comps.size() * 4 + surface_charges.size() * 100;
e_names.clear();
e_names.reserve(reserve_size);
for (auto &comp : this->surface_comps) {
const std::string phase_name = comp.Get_formula();
e_names.push_back(phase_name + "_moles");
e_names.push_back(phase_name + "_la");
e_names.push_back(phase_name + "_cb");
for (const auto &tot : comp.Get_totals()) {
e_names.push_back(phase_name + "_" + tot.first);
}
}
for (auto &charge : this->surface_charges) {
const std::string component = charge.Get_name() + "_charge";
e_names.push_back(component + "_area");
e_names.push_back(component + "_grams");
e_names.push_back(component + "_cb");
e_names.push_back(component + "_mw");
e_names.push_back(component + "_la");
for (const auto &tot : charge.Get_diffuse_layer_totals()) {
e_names.push_back(component + "_tot_" + tot.first);
}
// for (const auto &dl_layer : charge.Get_dl_species_map()) {
// e_names.push_back(component + "_dls_" +
// std::to_string(dl_layer.first));
// }
}
}
void cxxSurface::get_essential_values(std::vector<LDBLE> &e_values) {
// this is just some reserve size, might be changed in the future
const int reserve_size =
surface_comps.size() * 4 + surface_charges.size() * 100;
e_values.clear();
e_values.reserve(reserve_size);
for (auto &comp : this->surface_comps) {
e_values.push_back(comp.Get_moles());
e_values.push_back(comp.Get_la());
e_values.push_back(comp.Get_charge_balance());
for (const auto &tot : comp.Get_totals()) {
e_values.push_back(tot.second);
}
}
for (auto &charge : this->surface_charges) {
e_values.push_back(charge.Get_specific_area());
e_values.push_back(charge.Get_grams());
e_values.push_back(charge.Get_charge_balance());
e_values.push_back(charge.Get_mass_water());
e_values.push_back(charge.Get_la_psi());
for (const auto &tot : charge.Get_diffuse_layer_totals()) {
e_values.push_back(tot.second);
}
// for (const auto &dl_layer : charge.Get_dl_species_map()) {
// e_values.push_back(dl_layer.second);
// }
}
}
void cxxSurface::set_essential_values(std::vector<LDBLE>::iterator &it) {
for (auto &comp : this->surface_comps) {
comp.Set_moles(*(it++));
comp.Set_la(*(it++));
comp.Set_charge_balance(*(it++));
for (auto &tot : comp.Get_totals()) {
tot.second = *(it++);
}
}
for (auto &charge : this->surface_charges) {
charge.Set_specific_area(*(it++));
charge.Set_grams(*(it++));
charge.Set_charge_balance(*(it++));
charge.Set_mass_water(*(it++));
charge.Set_la_psi(*(it++));
for (auto &tot : charge.Get_diffuse_layer_totals()) {
tot.second = *(it++);
}
charge.Get_dl_species_map().clear();
// for (auto &dl_layer : charge.Get_dl_species_map()) {
// dl_layer.second = *(it++);
// }
}
}
void
cxxSurface::read_raw(CParser & parser, bool check)
{

View File

@ -1,3 +1,4 @@
#include <set>
#if !defined(SURFACE_H_INCLUDED)
#define SURFACE_H_INCLUDED
@ -31,11 +32,6 @@ public:
//void dump_xml(std::ostream & os, unsigned int indent = 0) const;
void dump_raw(std::ostream & s_oss, unsigned int indent, int *n_out=NULL) const;
void dump_essential_names(std::vector<std::string> &e_names);
void get_essential_values(std::vector<LDBLE> &e_values);
void set_essential_values(std::vector<LDBLE>::iterator &it);
void read_raw(CParser & parser, bool check = true);
bool Get_related_phases(void) const;
bool Get_related_rate(void) const;

View File

@ -159,45 +159,6 @@ cxxKinetics::dump_raw(std::ostream & s_oss, unsigned int indent, int * n_out) co
return;
}
void cxxKinetics::dump_essential_names(
std::vector<std::string> &e_names) const {
e_names.clear();
e_names.reserve(this->kinetics_comps.size() * 2);
for (const auto &comp : this->kinetics_comps) {
const std::string name = comp.Get_rate_name();
e_names.push_back(name);
for (int i = 0; i < comp.Get_d_params().size(); i++) {
e_names.push_back(name + "_p" + std::to_string(i + 1));
}
}
}
void cxxKinetics::get_essential_values(std::vector<LDBLE> &e_values) const {
e_values.clear();
e_values.reserve(this->kinetics_comps.size() * 2);
for (const auto &comp : this->kinetics_comps) {
e_values.push_back(comp.Get_m());
for (const auto &param : comp.Get_d_params()) {
e_values.push_back(param);
}
}
return;
}
void cxxKinetics::set_essential_values(std::vector<LDBLE>::iterator &it) {
for (auto &comp : this->kinetics_comps) {
comp.Set_m(*(it++));
for (auto &param : comp.Get_d_params()) {
param = *(it++);
}
}
return;
}
void
cxxKinetics::read_raw(CParser & parser, bool check)
{

View File

@ -25,11 +25,6 @@ class cxxKinetics:public cxxNumKeyword
void dump_raw(std::ostream & s_oss, unsigned int indent, int * n_out=NULL) const;
void dump_essential_names(std::vector<std::string> &e_names) const;
void get_essential_values(std::vector<LDBLE> &e_values) const;
void set_essential_values(std::vector<LDBLE>::iterator &it);
void read_raw(CParser & parser, bool check = true);
std::vector < LDBLE > &Get_steps(void) {return steps;}

View File

@ -341,6 +341,107 @@ set_use(void)
*/
return (OK);
}
int Phreeqc::initial_solutions_poet(int sol_id)
/* ---------------------------------------------------------------------- */
{
/*
* Go through list of solutions, make initial solution calculations
* for any marked "new".
*/
int converge, converge1;
int last, n_user, print1;
char token[2 * MAX_LENGTH];
// state = INITIAL_SOLUTION;
set_use();
print1 = TRUE;
dl_type_x = cxxSurface::NO_DL;
// std::map<int, cxxSolution>::iterator it = Rxn_solution_map.begin();
// for ( ; it != Rxn_solution_map.end(); it++)
//{
// for (size_t nn = 0; nn < Rxn_new_solution.size(); nn++)
cxxSolution &solution_ref = Rxn_solution_map.find(sol_id)->second;
initial_solution_isotopes = FALSE;
// if (solution_ref.Get_new_def()) {
use.Set_solution_ptr(&solution_ref);
LDBLE d0 = solution_ref.Get_density();
// LDBLE d1 = 0;
bool diag = (diagonal_scale == TRUE) ? true : false;
int count_iterations = 0;
// std::string input_units = solution_ref.Get_initial_data()->Get_units();
// cxxISolution *initial_data_ptr = solution_ref.Get_initial_data();
density_iterations = 0;
// for (;;) {
prep();
k_temp(solution_ref.Get_tc(), solution_ref.Get_patm());
set(TRUE);
always_full_pitzer = FALSE;
diagonal_scale = TRUE;
converge = model();
if (converge == ERROR /*&& diagonal_scale == FALSE*/) {
diagonal_scale = TRUE;
always_full_pitzer = TRUE;
set(TRUE);
converge = model();
}
// density_iterations++;
// if (solution_ref.Get_initial_data()->Get_calc_density()) {
// solution_ref.Set_density(calc_dens());
// if (!equal(d0, solution_ref.Get_density(), 1e-8)) {
// initial_data_ptr->Set_units(input_units);
// d0 = solution_ref.Get_density();
// if (count_iterations++ < 20) {
// diag = (diagonal_scale == TRUE) ? true : false;
// continue;
// } else {
// error_msg(
// sformatf("%s %d.",
// "Density calculation failed for initial solution ",
// solution_ref.Get_n_user()),
// STOP);
// }
// }
// }
// break;
// }
diagonal_scale = (diag) ? TRUE : FALSE;
converge1 = check_residuals();
sum_species();
viscosity();
add_isotopes(solution_ref);
punch_all();
// print_all();
density_iterations = 0;
/* free_model_allocs(); */
// remove pr_in
for (size_t i = 0; i < count_unknowns; i++) {
if (x[i]->type == SOLUTION_PHASE_BOUNDARY)
x[i]->phase->pr_in = false;
}
if (converge == ERROR || converge1 == ERROR) {
error_msg(sformatf("%s %d.",
"Model failed to converge for initial solution ",
solution_ref.Get_n_user()),
STOP);
}
n_user = solution_ref.Get_n_user();
last = solution_ref.Get_n_user_end();
/* copy isotope data */
if (solution_ref.Get_isotopes().size() > 0) {
isotopes_x = solution_ref.Get_isotopes();
} else {
isotopes_x.clear();
}
xsolution_save(n_user);
Utilities::Rxn_copies(Rxn_solution_map, n_user, last);
// }
initial_solution_isotopes = FALSE;
return (OK);
}
/* ---------------------------------------------------------------------- */
int Phreeqc::
initial_solutions(int print)

View File

@ -5003,16 +5003,16 @@ surface_model(void)
*/
debug_diffuse_layer_save = debug_diffuse_layer;
debug_model_save = debug_model;
if (last_model.force_prep)
{
// if (last_model.force_prep)
// {
// same_model = FALSE;
// }
// else
// {
// same_model = check_same_model();
// }
same_model = FALSE;
}
else
{
same_model = check_same_model();
}
if (dl_type_x != cxxSurface::NO_DL && same_model == FALSE)
{
if (dl_type_x != cxxSurface::NO_DL && same_model == FALSE) {
s_diff_layer.clear();
for (i = 0; i < (int)s.size(); i++)
{

View File

@ -36,21 +36,11 @@ prep(void)
*/
cxxSolution *solution_ptr;
if (state >= REACTION)
{
same_model = check_same_model();
}
else
{
same_model = FALSE;
last_model.force_prep = true;
}
/*same_model = FALSE; */
/*
* Initialize s, master, and unknown pointers
*/
solution_ptr = use.Get_solution_ptr();
if (solution_ptr == NULL)
// UP: we force to reset the model
same_model = FALSE;
last_model.force_prep = true;
solution_ptr = use.Get_solution_ptr();
if (solution_ptr == NULL)
{
error_msg("Solution needed for calculation not found, stopping.",
STOP);
@ -87,12 +77,17 @@ prep(void)
* Allocate space for array
*/
my_array.resize((max_unknowns + 1) * max_unknowns);
delta.resize(max_unknowns);
residual.resize(max_unknowns);
for (int j = 0; j < max_unknowns; j++)
{
residual[j] = 0;
}
for (double &val : my_array) {
val = 0;
}
delta.resize(max_unknowns);
for (double &val : delta) {
val = 0;
}
residual.resize(max_unknowns);
for (int j = 0; j < max_unknowns; j++) {
residual[j] = 0;
}
/*
* Build lists to fill Jacobian array and species list