Page MenuHomec4science

database_reader.cpp
No OneTemporary

File Metadata

Created
Sat, Jun 1, 02:17

database_reader.cpp

#include "catch.hpp"
#include "database/reader_common.hpp"
#include "database/yaml_reader.hpp"
#include <string>
#include <istream>
#include <sstream>
#include "str_database.hpp"
using namespace specmicp;
using namespace specmicp::database;
#include "utils/timer.hpp"
#include <iostream>
TEST_CASE("Database reader - help function")
{
SECTION("Equation Parsing")
{
std::map<std::string, specmicp::scalar_t> compo;
std::string eq = "A, 2 B, -C, -3D, SDF, - 3 de, - X";
specmicp::database::parse_equation(eq, compo);
CHECK(compo["A"] == 1);
CHECK(compo["B"] == 2);
CHECK(compo["C"] == -1);
CHECK(compo["D"] == -3);
CHECK(compo["SDF"] == 1);
CHECK(compo["de"] == -3);
CHECK(compo["X"] == -1);
}
SECTION("Charge parsing")
{
CHECK(specmicp::database::charge_from_label("neutral") == 0);
CHECK(specmicp::database::charge_from_label("neutral[]") == 0);
CHECK(specmicp::database::charge_from_label("charge[+]") == 1);
CHECK(specmicp::database::charge_from_label("charge[-]") == -1);
CHECK(specmicp::database::charge_from_label("charge[2]") == 2);
CHECK(specmicp::database::charge_from_label("charge[2-]") == -2);
CHECK(specmicp::database::charge_from_label("charge[2+]") == +2);
CHECK(specmicp::database::charge_from_label("charge[-3]") == -3);
CHECK(specmicp::database::charge_from_label("charge[+1]") == +1);
CHECK_THROWS_AS(specmicp::database::charge_from_label("charge[+3"), specmicp::database::db_invalid_syntax);
CHECK_THROWS_AS(specmicp::database::charge_from_label("charge[ddd]"), specmicp::database::db_invalid_syntax);
}
}
TEST_CASE("Element parser")
{
SECTION("Add to element map")
{
element_map map1 = {{"A", 1.0}, {"B", 1.0}};
element_map map2 = {{"B", 1.0}, {"C", 3.0}};
add_to_element_map(map1, map2, 1.0);
CHECK(map1["A"] == 1.0);
CHECK(map1["B"] == 2.0);
CHECK(map1["C"] == 3.0);
}
SECTION("Add to element map")
{
element_map map1 = {{"A", 1.0}, {"B", 1.0}};
element_map map2 = {{"B", 1.0}, {"C", 3.0}};
add_to_element_map(map1, map2, 2.0);
CHECK(map1["A"] == 1.0);
CHECK(map1["B"] == 3.0);
CHECK(map1["C"] == 6.0);
}
SECTION("Element parser")
{
element_map element_compo;
std::string label = "CCaFe2Al3O2.5H8.165";
element_composition_from_label(label, element_compo);
CHECK(element_compo["C"] == 1.0);
CHECK(element_compo["Ca"] == 1.0);
CHECK(element_compo["Fe"] == 2.0);
CHECK(element_compo["Al"] == 3.0);
CHECK(element_compo["O"] == 2.5);
CHECK(element_compo["H"] == 8.165);
}
SECTION("Parenthesis")
{
element_map element_compo;
std::string label = "Al(OH)4";
element_composition_from_label(label, element_compo);
CHECK(element_compo["Al"] == 1.0);
CHECK(element_compo["O"] == 4.0);
CHECK(element_compo["H"] == 4.0);
}
SECTION("Parenthesis 2")
{
std::map<std::string, scalar_t> element_compo;
std::string label = "Al(OH)4(H2O)2";
element_composition_from_label(label, element_compo);
CHECK(element_compo["Al"] == 1.0);
CHECK(element_compo["O"] == 6.0);
CHECK(element_compo["H"] == 8.0);
}
SECTION("semi-colon")
{
std::map<std::string, scalar_t> element_compo;
std::string label = "CaSO3:0.5H2O";
element_composition_from_label(label, element_compo);
CHECK(element_compo["Ca"] == 1.0);
CHECK(element_compo["S"] == 1.0);
CHECK(element_compo["O"] == 3.5);
CHECK(element_compo["H"] == 1.0);
}
SECTION("qualifier")
{
std::vector<std::string> list_label {"CO2(g)", "CO2(aq)"};
for (auto& it: list_label)
{
element_map compo;
element_composition_from_label(it, compo);
CHECK(compo["C"] == 1.0);
CHECK(compo["O"] == 2.0);
}
}
}
TEST_CASE("Database reader") {
SECTION("Good database") {
Timer timer;
std::istringstream input(good_test_database);
DataReaderYaml reader(input);
RawDatabasePtr data = reader.get_database();
timer.stop();
std::cout << "Reading database : " << timer.elapsed_time()*1000 << " ms (Ref 0.20ms)" << std::endl;
CHECK(data->aqueous.is_valid());
CHECK(data->components.is_valid());
CHECK(data->minerals.is_valid());
CHECK(data->minerals_kinetic.is_valid());
CHECK(data->gas.is_valid());
CHECK(data->is_valid());
size_t hash = data->get_hash();
// component
// =========
CHECK(data->nb_component() == 5);
CHECK(data->components.get_id("C1[-]") == 2);
CHECK(data->components.get_label(0) == "H2O");
CHECK(data->components.charge(1) == -1);
CHECK(data->a_debye_component(2) == 1.0);
CHECK(data->b_debye_component(3) == 0.4);
// aqueous
// =======
CHECK(data->nb_aqueous() == 3);
CHECK(data->aqueous.get_id("A2") == -1);
// normal
// ------
CHECK(data->nu_aqueous(0, 0) == 0.0);
CHECK(data->nu_aqueous(0, 1) == 0.0);
CHECK(data->nu_aqueous(0, 2) == 1.0);
CHECK(data->nu_aqueous(0, 3) == 1.0);
CHECK(data->nu_aqueous(0, 4) == 0.0);
CHECK(data->logk_aqueous(0) == -2.0);
// canonicalization
// ----------------
CHECK(data->nu_aqueous(1, 0) == 0.0);
CHECK(data->nu_aqueous(1, 1) == 0.0);
CHECK(data->nu_aqueous(1, 2) == 1.0);
CHECK(data->nu_aqueous(1, 3) == 2.0);
CHECK(data->nu_aqueous(1, 4) == 0.0);
CHECK(data->logk_aqueous(1) == -4);
// aqueous parameters
// ------------------
CHECK(data->charge_aqueous(0) == 0);
CHECK(data->charge_aqueous(1) == +1);
CHECK(data->a_debye_aqueous(1) == 1.0);
CHECK(data->b_debye_aqueous(1) == 0.4);
// Minerals
// ========
CHECK(data->nb_mineral() == 2);
CHECK(data->minerals.get_label(0) == "M1");
CHECK(data->minerals.get_label(1) == "M2");
CHECK(data->nu_mineral(0, 0) == 0.0);
CHECK(data->nu_mineral(0, 1) == 0.0);
CHECK(data->nu_mineral(0, 2) == 1.0);
CHECK(data->nu_mineral(0, 3) == 1.0);
CHECK(data->nu_mineral(0, 4) == 0.0);
CHECK(data->logk_mineral(0) == -7);
CHECK(data->molar_volume_mineral(0) == 1e-6*10.0);
CHECK(data->molar_mass_mineral(0, units::MassUnit::gram) == 5.0);
CHECK(data->nu_mineral(1, 0) == 0.0);
CHECK(data->nu_mineral(1, 1) == 0.0);
CHECK(data->nu_mineral(1, 2) == 2.0);
CHECK(data->nu_mineral(1, 3) == 2.0);
CHECK(data->nu_mineral(1, 4) == 1.0);
CHECK(data->logk_mineral(1) == -6+data->logk_aqueous(1)+data->logk_aqueous(2));
CHECK(data->unsafe_molar_volume_mineral(1) < 0);
CHECK_THROWS(data->molar_volume_mineral(1));
// Kinetic Minerals
// ================
CHECK(data->nb_mineral_kinetic() == 1);
CHECK(data->minerals_kinetic.get_label(0) == "MK1");
CHECK(data->nu_mineral_kinetic(0, 0) == 0.0);
CHECK(data->nu_mineral_kinetic(0, 1) == 0.0);
CHECK(data->nu_mineral_kinetic(0, 2) == 1.0);
CHECK(data->nu_mineral_kinetic(0, 3) == 1.0);
CHECK(data->nu_mineral_kinetic(0, 4) == 2.0);
CHECK(data->logk_mineral_kinetic(0) == -9);
CHECK(data->molar_volume_mineral_kinetic(0) == 1e-6*30.0);
CHECK(data->molar_mass_mineral_kinetic(0, units::MassUnit::gram) == 13.0);
// Gas
// ======
CHECK(data->nb_gas() == 1);
CHECK(data->gas.get_label(0) == "G1");
CHECK(data->nu_gas(0, 0) == 0.0);
CHECK(data->nu_gas(0, 1) == 0.0);
CHECK(data->nu_gas(0, 2) == 0.0);
CHECK(data->nu_gas(0, 3) == 0.0);
CHECK(data->nu_gas(0, 4) == 1.0);
CHECK(data->logk_gas(0) == 3.0);
// sorbed
// ======
CHECK(data->nb_sorbed() == 1);
CHECK(data->sorbed.get_label(0) == "S1");
CHECK(data->nu_sorbed(0, 0) == 0.0);
CHECK(data->nu_sorbed(0, 1) == 0.0);
CHECK(data->nu_sorbed(0, 2) == 0.0);
CHECK(data->nu_sorbed(0, 3) == 0.0);
CHECK(data->nu_sorbed(0, 4) == 1.0);
CHECK(data->logk_sorbed(0) == -6);
// Compounds
// =========
CHECK(data->nb_compounds() == 1);
CHECK(data->get_label_compound(0) == "Comp1");
CHECK(data->nu_compound(0, 0) == 2.0);
CHECK(data->nu_compound(0, 1) == 0.0);
CHECK(data->nu_compound(0, 2) == 0.0);
CHECK(data->nu_compound(0, 3) == 0.0);
CHECK(data->nu_compound(0, 4) == 1.0);
// Elements
// =========
CHECK(data->get_id_component_from_element("plop") == -1);
CHECK(data->get_id_component_from_element("C1") != -1);
CHECK(data->get_label_component_from_element("C1") == "C1[-]");
CHECK(data->get_label_component_from_element("C3") == "C3");
//
data->freeze_db();
CHECK(data->get_hash() == hash);
CHECK(data->is_valid());
}
}

Event Timeline