Page MenuHomec4science

equilibrium_stagger.cpp
No OneTemporary

File Metadata

Created
Fri, May 24, 07:11

equilibrium_stagger.cpp

#include "catch.hpp"
#include "database/database.hpp"
#include "database/data_container.hpp"
#include "dfpm/meshes/generic_mesh1d.hpp"
#include "reactmicp/systems/unsaturated/equilibrium_constraints.hpp"
#include "reactmicp/systems/unsaturated/equilibrium_stagger.hpp"
#include "reactmicp/systems/unsaturated/variables_interface.hpp"
#include "reactmicp/solver/staggers_base/stagger_structs.hpp"
#include "reactmicp/systems/unsaturated/variables.hpp"
#include "specmicp/adimensional/adimensional_system_solver.hpp"
#include "specmicp/adimensional/adimensional_system_solver_structs.hpp"
#include "specmicp/adimensional/adimensional_system_solution_extractor.hpp"
#include "specmicp/problem_solver/formulation.hpp"
#include "specmicp/problem_solver/dissolver.hpp"
#include "utils/log.hpp"
#include <iostream>
using namespace specmicp;
using namespace specmicp::reactmicp;
using namespace specmicp::reactmicp::systems::unsaturated;
static specmicp::database::RawDatabasePtr get_database()
{
static database::RawDatabasePtr raw_data {nullptr};
if (raw_data == nullptr)
{
specmicp::database::Database thedatabase(TEST_CEMDATA_PATH);
thedatabase.keep_only_components(
{"H2O", "H[+]", "Ca[2+]", "Si(OH)4", "HCO3[-]"}
);
std::map<std::string, std::string> swap = {{"HCO3[-]", "CO2"},};
thedatabase.swap_components(swap);
raw_data = thedatabase.get_database();
raw_data->freeze_db();
}
return raw_data;
}
static AdimensionalSystemSolution
get_init_solution(database::RawDatabasePtr the_database)
{
Formulation formulation;
formulation.set_mass_solution(500);
formulation.add_mineral("C2S", 1000.0);
formulation.add_mineral("C3S", 4000.0);
formulation.add_aqueous_species("CO2", 20);
Dissolver dissolver(the_database);
Vector tot_conc = dissolver.dissolve(formulation, false);
AdimensionalSystemConstraints constraints;
constraints.total_concentrations = tot_conc;
AdimensionalSystemSolver adim_solver(the_database, constraints);
adim_solver.get_options().solver_options.set_tolerance(1e-14);
Vector x;
adim_solver.initialise_variables(x, 0.8, -3);
micpsolver::MiCPPerformance perf = adim_solver.solve(x);
specmicp_assert(perf.return_code > micpsolver::MiCPSolverReturnCode::Success);
return adim_solver.get_raw_solution(x);
}
TEST_CASE("EquilibriumConstraints", "[Equilibrium],[Constraints]") {
init_logger(&std::cout, logger::Warning);
SECTION("Initialisation") {
EquilibriumConstraints constraints(10);
auto id_0 = constraints.new_constraints();
CHECK(id_0 == 0);
AdimensionalSystemConstraints& constraint = constraints[id_0];
constraint.set_charge_keeper(2);
AdimensionalSystemConstraints new_constraint;
new_constraint.set_charge_keeper(3);
auto id_1 = constraints.add_constraints(new_constraint);
CHECK(id_1 == 1);
CHECK(constraints[id_1].charge_keeper == new_constraint.charge_keeper);
constraints.set_constraints(id_0, {0, 1, 2, 3, 4});
constraints.set_constraints(id_1, {5, 6, 7, 8});
CHECK(constraints.get_constraints(0).charge_keeper == 2);
CHECK(constraints.get_constraints(1).charge_keeper == 2);
CHECK(constraints.get_constraints(2).charge_keeper == 2);
CHECK(constraints.get_constraints(3).charge_keeper == 2);
CHECK(constraints.get_constraints(4).charge_keeper == 2);
CHECK(constraints.get_constraints(5).charge_keeper == 3);
CHECK(constraints.get_constraints(6).charge_keeper == 3);
CHECK(constraints.get_constraints(7).charge_keeper == 3);
CHECK(constraints.get_constraints(8).charge_keeper == 3);
std::cout << "This error is ok : ";
CHECK_THROWS(constraints.get_constraints(9));
std::vector<std::size_t> id_constraints(10, 1);
id_constraints[0] = 0;
constraints.set_constraints(id_constraints);
CHECK(constraints.get_constraints(0).charge_keeper == 2);
CHECK(constraints.get_constraints(1).charge_keeper == 3);
CHECK(constraints.get_constraints(2).charge_keeper == 3);
CHECK(constraints.get_constraints(3).charge_keeper == 3);
CHECK(constraints.get_constraints(4).charge_keeper == 3);
CHECK(constraints.get_constraints(5).charge_keeper == 3);
CHECK(constraints.get_constraints(6).charge_keeper == 3);
CHECK(constraints.get_constraints(7).charge_keeper == 3);
CHECK(constraints.get_constraints(8).charge_keeper == 3);
CHECK(constraints.get_constraints(9).charge_keeper == 3);
id_constraints[5] = 2;
std::cout << "This error is ok : ";
CHECK_THROWS(constraints.set_constraints(id_constraints));
}
}
TEST_CASE("Equilibrium stagger", "[Equilibrium],[Stagger]") {
init_logger(&std::cout, logger::Warning);
index_t nb_nodes {10};
scalar_t dx {1.0};
scalar_t cross_section {5.0};
mesh::Mesh1DPtr the_mesh = mesh::uniform_mesh1d({dx, nb_nodes, cross_section});
database::RawDatabasePtr raw_data = get_database();
std::shared_ptr<EquilibriumConstraints> constraints = equilibrium_constraints(the_mesh);
constraints->set_constraint_for_all(constraints->new_constraints());
constraints->get_options().solver_options.set_tolerance(1e-14);
index_t id_co2 = raw_data->get_id_component_from_element("C");
VariablesInterface interface(the_mesh, raw_data, {id_co2});
units::UnitsSet units_set;
AdimensionalSystemSolution solution = get_init_solution(raw_data);
AdimensionalSystemSolutionExtractor extr(solution, raw_data, units_set);
scalar_t rho_l = extr.density_water();
interface.set_porosity(extr.porosity());
scalar_t init_saturation = extr.saturation_water();
interface.set_liquid_saturation(init_saturation);
scalar_t init_water_aqconc = rho_l*extr.total_aqueous_concentration(0);
interface.set_water_aqueous_concentration(init_water_aqconc);
scalar_t init_water_solidconc = extr.total_solid_concentration(0);
interface.set_solid_concentration(0, init_water_solidconc);
for (index_t comp: raw_data->range_aqueous_component())
{
interface.set_aqueous_concentration(comp,
rho_l*extr.total_aqueous_concentration(comp));
interface.set_solid_concentration(comp,
extr.total_solid_concentration(comp));
}
// pv co2
UnsaturatedVariablesPtr vars = interface.get_variables();
scalar_t pv_co2 = extr.fugacity_gas(vars->get_id_gas(id_co2)
)*vars->get_total_pressure();
std::cout << "pv co2 : " << pv_co2 << " tot pressure : " << vars->get_total_pressure() << std::endl;
interface.set_partial_pressure(id_co2, pv_co2);
scalar_t init_co2_aqconc = rho_l*extr.total_aqueous_concentration(id_co2);
scalar_t init_co2_solidconc = extr.total_solid_concentration(id_co2);
for (index_t node: the_mesh->range_nodes())
{
vars->set_adim_solution(node, solution);
}
SECTION("Initialisation") {
EquilibriumStagger stagger(vars, constraints);
// Check that nothing has changed after we solved an already solved problem
stagger.initialize(vars);
stagger.initialize_timestep(1.0, vars);
solver::StaggerReturnCode retcode = stagger.restart_timestep(vars);
CHECK(retcode > solver::StaggerReturnCode::NotConvergedYet);
for (index_t node: the_mesh->range_nodes()) {
CHECK(interface.get_liquid_saturation()(node) == init_saturation);
CHECK(interface.get_water_aqueous_concentration()(node)/init_water_aqconc
== Approx(1.0).epsilon(1e-14));
CHECK(interface.get_solid_concentration(0)(node) / init_water_solidconc
== Approx(1.0).epsilon(1e-14));
CHECK(interface.get_aqueous_concentration(id_co2)(node)/init_co2_aqconc
== Approx(1.0).epsilon(1e-14));
CHECK(interface.get_solid_concentration(id_co2)(node) / init_co2_solidconc
== Approx(1.0).epsilon(1e-14));
CHECK(interface.get_partial_pressure(id_co2)(node) == Approx(pv_co2).epsilon(1e-12));
}
}
}

Event Timeline