Merge branch 'main' into feature/pointwisePolytrope

This commit is contained in:
2025-03-26 11:38:07 -04:00
86 changed files with 15850 additions and 2170 deletions

View File

@@ -0,0 +1,206 @@
#include <gtest/gtest.h>
#include <stdexcept>
#include <string>
#include <algorithm>
#include "atomicSpecies.h"
#include "composition.h"
#include "config.h"
std::string EXAMPLE_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/config/example.yaml";
/**
* @brief Test suite for the composition class.
*/
class compositionTest : public ::testing::Test {};
/**
* @brief Test the constructor of the composition class.
*/
TEST_F(compositionTest, isotopeMasses) {
EXPECT_NO_THROW(chemSpecies::species.at("H-1"));
EXPECT_DOUBLE_EQ(chemSpecies::species.at("H-1").mass(), 1.007825031898);
EXPECT_DOUBLE_EQ(chemSpecies::species.at("He-3").mass(), 3.0160293219700001);
EXPECT_DOUBLE_EQ(chemSpecies::species.at("He-4").mass(),4.0026032541300003);
}
TEST_F(compositionTest, constructor) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
EXPECT_NO_THROW(composition::Composition comp);
}
TEST_F(compositionTest, registerSymbol) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
EXPECT_NO_THROW(comp.registerSymbol("H-1"));
EXPECT_NO_THROW(comp.registerSymbol("He-4"));
EXPECT_THROW(comp.registerSymbol("H-19"), std::runtime_error);
EXPECT_THROW(comp.registerSymbol("He-21"), std::runtime_error);
std::set<std::string> registeredSymbols = comp.getRegisteredSymbols();
EXPECT_TRUE(registeredSymbols.find("H-1") != registeredSymbols.end());
EXPECT_TRUE(registeredSymbols.find("He-4") != registeredSymbols.end());
EXPECT_TRUE(registeredSymbols.find("H-19") == registeredSymbols.end());
EXPECT_TRUE(registeredSymbols.find("He-21") == registeredSymbols.end());
}
TEST_F(compositionTest, setGetComposition) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
EXPECT_DOUBLE_EQ(comp.setMassFraction("H-1", 0.5), 0.0);
EXPECT_DOUBLE_EQ(comp.setMassFraction("He-4", 0.5), 0.0);
EXPECT_DOUBLE_EQ(comp.setMassFraction("H-1", 0.6), 0.5);
EXPECT_DOUBLE_EQ(comp.setMassFraction("He-4", 0.4), 0.5);
EXPECT_NO_THROW(comp.finalize());
EXPECT_DOUBLE_EQ(comp.getMassFraction("H-1"), 0.6);
EXPECT_THROW(comp.setMassFraction("He-3", 0.3), std::runtime_error);
EXPECT_NO_THROW(comp.setMassFraction({"H-1", "He-4"}, {0.5, 0.5}));
EXPECT_THROW(comp.getComposition("H-1"), std::runtime_error);
EXPECT_TRUE(comp.finalize());
EXPECT_DOUBLE_EQ(comp.getComposition("H-1").first.mass_fraction(), 0.5);
EXPECT_NO_THROW(comp.setMassFraction({"H-1", "He-4"}, {0.6, 0.6}));
EXPECT_FALSE(comp.finalize());
EXPECT_THROW(comp.getComposition("H-1"), std::runtime_error);
}
TEST_F(compositionTest, setGetNumberFraction) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1", false);
comp.registerSymbol("He-4", false);
EXPECT_DOUBLE_EQ(comp.setNumberFraction("H-1", 0.5), 0.0);
EXPECT_DOUBLE_EQ(comp.setNumberFraction("He-4", 0.5), 0.0);
EXPECT_DOUBLE_EQ(comp.setNumberFraction("H-1", 0.6), 0.5);
EXPECT_DOUBLE_EQ(comp.setNumberFraction("He-4", 0.4), 0.5);
EXPECT_NO_THROW(comp.finalize());
EXPECT_DOUBLE_EQ(comp.getNumberFraction("H-1"), 0.6);
EXPECT_THROW(comp.setNumberFraction("He-3", 0.3), std::runtime_error);
}
TEST_F(compositionTest, subset) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
comp.setMassFraction("H-1", 0.6);
comp.setMassFraction("He-4", 0.4);
EXPECT_NO_THROW(comp.finalize());
std::vector<std::string> symbols = {"H-1"};
composition::Composition subsetComp = comp.subset(symbols, "norm");
EXPECT_TRUE(subsetComp.finalize());
EXPECT_DOUBLE_EQ(subsetComp.getMassFraction("H-1"), 1.0);
}
TEST_F(compositionTest, finalizeWithNormalization) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
comp.setMassFraction("H-1", 0.3);
comp.setMassFraction("He-4", 0.3);
EXPECT_TRUE(comp.finalize(true));
EXPECT_DOUBLE_EQ(comp.getMassFraction("H-1"), 0.5);
EXPECT_DOUBLE_EQ(comp.getMassFraction("He-4"), 0.5);
}
TEST_F(compositionTest, finalizeWithoutNormalization) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
comp.setMassFraction("H-1", 0.5);
comp.setMassFraction("He-4", 0.5);
EXPECT_TRUE(comp.finalize(false));
EXPECT_DOUBLE_EQ(comp.getMassFraction("H-1"), 0.5);
EXPECT_DOUBLE_EQ(comp.getMassFraction("He-4"), 0.5);
}
TEST_F(compositionTest, getComposition) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
comp.setMassFraction("H-1", 0.6);
comp.setMassFraction("He-4", 0.4);
EXPECT_NO_THROW(comp.finalize());
auto compositionEntry = comp.getComposition("H-1");
EXPECT_DOUBLE_EQ(compositionEntry.first.mass_fraction(), 0.6);
EXPECT_DOUBLE_EQ(compositionEntry.second.meanParticleMass, 1.4382769310381101);
EXPECT_DOUBLE_EQ(compositionEntry.second.specificNumberDensity, 1.0/1.4382769310381101);
}
TEST_F(compositionTest, setCompositionMode) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
comp.setMassFraction("H-1", 0.6);
comp.setMassFraction("He-4", 0.4);
EXPECT_NO_THROW(comp.finalize());
EXPECT_DOUBLE_EQ(comp.getMassFraction("H-1"), 0.6);
EXPECT_DOUBLE_EQ(comp.getMassFraction("He-4"), 0.4);
EXPECT_NO_THROW(comp.setCompositionMode(false));
EXPECT_NO_THROW(comp.setNumberFraction("H-1", 0.9));
EXPECT_NO_THROW(comp.setNumberFraction("He-4", 0.1));
EXPECT_THROW(comp.setCompositionMode(true), std::runtime_error);
EXPECT_NO_THROW(comp.finalize());
EXPECT_NO_THROW(comp.setCompositionMode(true));
}
TEST_F(compositionTest, hasSymbol) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp;
comp.registerSymbol("H-1");
comp.registerSymbol("He-4");
comp.setMassFraction("H-1", 0.6);
comp.setMassFraction("He-4", 0.4);
EXPECT_NO_THROW(comp.finalize());
EXPECT_TRUE(comp.hasSymbol("H-1"));
EXPECT_TRUE(comp.hasSymbol("He-4"));
EXPECT_FALSE(comp.hasSymbol("H-2"));
EXPECT_FALSE(comp.hasSymbol("He-3"));
}
TEST_F(compositionTest, mix) {
Config::getInstance().loadConfig(EXAMPLE_FILENAME);
composition::Composition comp1;
comp1.registerSymbol("H-1");
comp1.registerSymbol("He-4");
comp1.setMassFraction("H-1", 0.6);
comp1.setMassFraction("He-4", 0.4);
EXPECT_NO_THROW(comp1.finalize());
composition::Composition comp2;
comp2.registerSymbol("H-1");
comp2.registerSymbol("He-4");
comp2.setMassFraction("H-1", 0.4);
comp2.setMassFraction("He-4", 0.6);
EXPECT_NO_THROW(comp2.finalize());
composition::Composition mixedComp = comp1 + comp2;
EXPECT_TRUE(mixedComp.finalize());
EXPECT_DOUBLE_EQ(mixedComp.getMassFraction("H-1"), 0.5);
EXPECT_DOUBLE_EQ(mixedComp.getMassFraction("He-4"), 0.5);
composition::Composition mixedComp2 = comp1.mix(comp2, 0.25);
EXPECT_TRUE(mixedComp2.finalize());
EXPECT_DOUBLE_EQ(mixedComp2.getMassFraction("H-1"), 0.45);
EXPECT_DOUBLE_EQ(mixedComp2.getMassFraction("He-4"), 0.55);
}

View File

@@ -1,10 +1,8 @@
# Test files for opatIO
# Test files for const
test_sources = [
'opatIOTest.cpp',
'compositionTest.cpp',
]
foreach test_file : test_sources
exe_name = test_file.split('.')[0]
message('Building test: ' + exe_name)
@@ -13,9 +11,7 @@ foreach test_file : test_sources
test_exe = executable(
exe_name,
test_file,
dependencies: [gtest_dep, picosha2_dep, gtest_main],
include_directories: include_directories('../../src/opatIO/public'),
link_with: libopatIO, # Link the dobj library
dependencies: [gtest_dep, species_weight_dep, gtest_main, composition_dep],
install_rpath: '@loader_path/../../src' # Ensure runtime library path resolves correctly
)

View File

@@ -0,0 +1,91 @@
#include "composition.h"
#include "config.h"
#include <string>
int main(int argv, char* argc[]) {
std::string pathToConfigFile;
if (argv == 2) {
pathToConfigFile = argc[1];
} else {
pathToConfigFile = "config.json";
}
Config::getInstance().loadConfig(pathToConfigFile);
composition::Composition comp;
std::vector<std::string> symbols = {"H-1", "He-4"};
comp.registerSymbol(symbols);
comp.setMassFraction("H-1", 0.7);
comp.setMassFraction("He-4", 0.3);
comp.finalize();
std::cout << "=== Mass Fraction Mode ===" << std::endl;
std::cout << "\tH-1 Mass Frac: " << comp.getMassFraction("H-1") << std::endl;
std::cout << "\tH-1 Number Frac: " << comp.getNumberFraction("H-1") << std::endl;
std::cout << "\tHe-4 Mass Frac: " << comp.getMassFraction("He-4") << std::endl;
std::cout << "\tHe-4 Number Frac: " << comp.getNumberFraction("He-4") << std::endl;
std::cout << "\tMass Frac Sum: " << comp.getMassFraction("H-1") + comp.getMassFraction("He-4") << std::endl;
std::cout << "\tNumber Frac Sum: " << comp.getNumberFraction("H-1") + comp.getNumberFraction("He-4") << std::endl;
composition::Composition comp2;
comp2.registerSymbol(symbols, false);
comp2.setNumberFraction("H-1", comp.getNumberFraction("H-1"));
comp2.setNumberFraction("He-4", comp.getNumberFraction("He-4"));
comp2.finalize();
std::cout << "=== Number Fraction Mode ===" << std::endl;
std::cout << "\tH-1 Mass Frac: " << comp2.getMassFraction("H-1") << std::endl;
std::cout << "\tH-1 Number Frac: " << comp2.getNumberFraction("H-1") << std::endl;
std::cout << "\tHe-4 Mass Frac: " << comp2.getMassFraction("He-4") << std::endl;
std::cout << "\tHe-4 Number Frac: " << comp2.getNumberFraction("He-4") << std::endl;
std::cout << "\tMass Frac Sum: " << comp2.getMassFraction("H-1") + comp2.getMassFraction("He-4") << std::endl;
std::cout << "\tNumber Frac Sum: " << comp2.getNumberFraction("H-1") + comp2.getNumberFraction("He-4") << std::endl;
std::vector<std::string> symbols3 = {
"H-1",
"He-3",
"He-4",
"Li-6",
"Li-7",
"O-16",
"C-12",
"Fe-56",
"Ne-20",
"N-14",
"Mg-24",
"Si-28",
"S-32",
"Ca-40",
};
std::vector<double> mass_fractions = {
0.71243,
1e-5,
0.27,
1e-11,
1e-9,
0.009,
0.003,
0.0014,
0.0015,
0.001,
0.0006,
0.0006,
0.0004,
0.00006
};
composition::Composition comp3(symbols3, mass_fractions, true);
std::cout << "=== Mass Fraction Mode ===" << std::endl;
double massFracSum = 0.0;
double numberFracSum = 0.0;
for (const auto& symbol : symbols3) {
std::cout << "\t" << symbol << " Mass Frac: " << comp3.getMassFraction(symbol) << std::endl;
std::cout << "\t" << symbol << " Number Frac: " << comp3.getNumberFraction(symbol) << std::endl;
massFracSum += comp3.getMassFraction(symbol);
numberFracSum += comp3.getNumberFraction(symbol);
}
std::cout << "\tMass Frac Sum: " << massFracSum << std::endl;
std::cout << "\tNumber Frac Sum: " << numberFracSum << std::endl;
return 0;
}

View File

@@ -0,0 +1,2 @@
Composition:
Tracked: "H-1"

View File

@@ -0,0 +1 @@
executable('composition_sandbox', 'comp.cpp', dependencies: [composition_dep, config_dep])

View File

@@ -1,11 +1,12 @@
#include <gtest/gtest.h>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <set>
#include <sstream>
#include "helm.h"
#include "resourceManager.h"
#include "config.h"
/**
* @file constTest.cpp
@@ -17,21 +18,20 @@
*/
class eosTest : public ::testing::Test {};
std::string HELM_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/assets/eos/helm_table.dat";
std::string TEST_CONFIG = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/testsConfig.yaml";
/**
* @test Verify default constructor initializes correctly.
*/
TEST_F(eosTest, constructor) {
using namespace helmholtz;
EXPECT_NO_THROW(HELMTable table = read_helm_table(HELM_FILENAME));
}
TEST_F(eosTest, read_helm_table) {
using namespace helmholtz;
HELMTable table = read_helm_table(HELM_FILENAME);
// Capture the << operator output as a string
Config::getInstance().loadConfig(TEST_CONFIG);
ResourceManager& rm = ResourceManager::getInstance();
auto& eos = std::get<std::unique_ptr<EosIO>>(rm.getResource("eos:helm"));
auto& table = eos->getTable();
auto& helmTable = *std::get<std::unique_ptr<helmholtz::HELMTable>>(table);
std::stringstream ss;
ss << table;
ss << helmTable;
EXPECT_EQ(ss.str(), "HELMTable Data:\n imax: 541, jmax: 201\n Temperature Range: [1000, 1e+13]\n Density Range: [1e-12, 1e+15]\n");
}
@@ -58,28 +58,31 @@ TEST_F(eosTest, get_helm_EOS) {
eos1.abar = 1.0/asum;
eos1.zbar = eos1.abar*zsum;
HELMTable table = read_helm_table(HELM_FILENAME);
EOS eos = get_helm_EOS(eos1, table);
// std::cout << eos << std::endl;
ResourceManager& rm = ResourceManager::getInstance();
auto& eos = std::get<std::unique_ptr<EosIO>>(rm.getResource("eos:helm"));
auto& table = eos->getTable();
auto& helmTable = *std::get<std::unique_ptr<helmholtz::HELMTable>>(table);
EOS helmEos = get_helm_EOS(eos1, helmTable);
const double absErr = 1e-12;
//Check composition info
EXPECT_DOUBLE_EQ( eos.ye, 8.75e-01);
EXPECT_NEAR( helmEos.ye, 8.75e-01, absErr);
//Check E, P, S and derivatives of each wrt Rho and T
EXPECT_DOUBLE_EQ( eos.etaele, 2.3043348231021554e+01);
EXPECT_DOUBLE_EQ( eos.etot, 1.1586558190936826e+17);
EXPECT_DOUBLE_EQ(eos.denerdd, 6.1893000468285858e+10);
EXPECT_DOUBLE_EQ(eos.denerdt, 1.2129708972542575e+08);
EXPECT_DOUBLE_EQ( eos.ptot, 6.9610135220017030e+22);
EXPECT_DOUBLE_EQ(eos.dpresdd, 1.0296440482849070e+17);
EXPECT_DOUBLE_EQ(eos.dpresdt, 7.7171347517311625e+13);
EXPECT_DOUBLE_EQ( eos.stot, 6.0647461970567346e+08);
EXPECT_DOUBLE_EQ(eos.dentrdd,-7.7171347517311645e+01);
EXPECT_DOUBLE_EQ(eos.dentrdt, 1.2129708972542577e+00);
EXPECT_NEAR( helmEos.etaele, 2.3043348231021554e+01, absErr);
EXPECT_NEAR( helmEos.etot, 1.1586558190936826e+17, 1e3);
EXPECT_NEAR(helmEos.denerdd, 6.1893000468285858e+10, 1e-2);
EXPECT_NEAR(helmEos.denerdt, 1.2129708972542575e+08, 1e-7);
EXPECT_NEAR( helmEos.ptot, 6.9610135220017030e+22, 1e10);
EXPECT_NEAR(helmEos.dpresdd, 1.0296440482849070e+17, 1e3);
EXPECT_NEAR(helmEos.dpresdt, 7.7171347517311625e+13, 1.0);
EXPECT_NEAR( helmEos.stot, 6.0647461970567346e+08, 1e-7);
EXPECT_NEAR(helmEos.dentrdd,-7.7171347517311645e+01, absErr);
EXPECT_NEAR(helmEos.dentrdt, 1.2129708972542577e+00, absErr);
const double abs_err = 1.0e-12;
// Maxwell relations, should always be zero
EXPECT_NEAR( eos.dse, 0, abs_err);
EXPECT_NEAR( eos.dpe, 0, abs_err);
EXPECT_NEAR( eos.dsp, 0, abs_err);
EXPECT_NEAR( helmEos.dse, 0, absErr);
EXPECT_NEAR( helmEos.dpe, 0, absErr);
EXPECT_NEAR( helmEos.dsp, 0, absErr);
}

View File

@@ -11,7 +11,7 @@ foreach test_file : test_sources
test_exe = executable(
exe_name,
test_file,
dependencies: [gtest_dep, eos_dep, gtest_main],
dependencies: [gtest_dep, eos_dep, gtest_main, resourceManager_dep, config_dep],
install_rpath: '@loader_path/../../src' # Ensure runtime library path resolves correctly
)

View File

@@ -1,10 +1,9 @@
#include <gtest/gtest.h>
#include "meshIO.h"
#include <iostream>
#include <string>
#include "mfem.hpp"
std::string EXAMPLE_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/src/resources/mesh/sphere.msh";
std::string EXAMPLE_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/assets/dynamic/mesh/sphere.msh";
double ComputeMeshVolume(mfem::Mesh &mesh)
{

View File

@@ -6,13 +6,17 @@ gtest_nomain_dep = dependency('gtest', main: false, required : true)
# Subdirectories for unit and integration tests
subdir('dobj')
subdir('const')
subdir('opatIO')
subdir('meshIO')
subdir('probe')
subdir('config')
subdir('eos')
subdir('resource')
subdir('network')
subdir('composition')
subdir('poly')
# Subdirectories for sandbox tests
subdir('dobj_sandbox')
subdir('opatIO_sandbox')
subdir('composition_sandbox')

View File

@@ -0,0 +1,50 @@
#include <gtest/gtest.h>
#include <string>
#include "approx8.h"
#include "config.h"
#include "network.h"
#include <vector>
std::string TEST_CONFIG = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/testsConfig.yaml";
class approx8Test : public ::testing::Test {};
/**
* @brief Test the constructor of the Config class.
*/
TEST_F(approx8Test, constructor) {
Config& config = Config::getInstance();
config.loadConfig(TEST_CONFIG);
EXPECT_NO_THROW(nnApprox8::Approx8Network());
}
TEST_F(approx8Test, setStiff) {
nnApprox8::Approx8Network network;
EXPECT_NO_THROW(network.setStiff(true));
EXPECT_TRUE(network.isStiff());
EXPECT_NO_THROW(network.setStiff(false));
EXPECT_FALSE(network.isStiff());
}
TEST_F(approx8Test, evaluate) {
nnApprox8::Approx8Network network;
nuclearNetwork::NetIn netIn;
std::vector<double> comp = {0.708, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4};
netIn.composition = comp;
netIn.temperature = 1e7;
netIn.density = 1e2;
netIn.energy = 0.0;
netIn.tmax = 3.15e17;
netIn.dt0 = 1e12;
nuclearNetwork::NetOut netOut;
EXPECT_NO_THROW(netOut = network.evaluate(netIn));
EXPECT_DOUBLE_EQ(netOut.composition[nnApprox8::Net::ih1], 0.50166260916650918);
EXPECT_DOUBLE_EQ(netOut.composition[nnApprox8::Net::ihe4],0.48172270591286032);
EXPECT_DOUBLE_EQ(netOut.energy, 1.6433049870528356e+18);
}

25
tests/network/meson.build Normal file
View File

@@ -0,0 +1,25 @@
# Test files for network
test_sources = [
'approx8Test.cpp',
]
foreach test_file : test_sources
exe_name = test_file.split('.')[0]
message('Building test: ' + exe_name)
# Create an executable target for each test
test_exe = executable(
exe_name,
test_file,
dependencies: [gtest_dep, network_dep, gtest_main],
include_directories: include_directories('../../src/network/public'),
link_with: libnetwork, # Link the dobj library
install_rpath: '@loader_path/../../src' # Ensure runtime library path resolves correctly
)
# Add the executable as a test
test(
exe_name,
test_exe,
env: ['MESON_SOURCE_ROOT=' + meson.project_source_root(), 'MESON_BUILD_ROOT=' + meson.project_build_root()])
endforeach

View File

@@ -1,133 +0,0 @@
#include <gtest/gtest.h>
#include "opatIO.h"
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <sstream>
#include <cstring>
#include "picosha2.h"
std::string EXAMPLE_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/opatIO/synthetic_tables.opat";
/**
* @file opatIOTest.cpp
* @brief Unit tests for the OpatIO class and associated structs.
*/
/**
* @brief Test suite for the const class.
*/
class opatIOTest : public ::testing::Test {};
/**
* @test Verify default constructor initializes correctly.
*/
TEST_F(opatIOTest, DefaultConstructor) {
EXPECT_NO_THROW(OpatIO());
}
/*
* @test Verify constructor initializes correctly with a file.
*/
TEST_F(opatIOTest, Constructor) {
OpatIO opatIO(EXAMPLE_FILENAME);
}
/**
* @test Verify the header is read correctly.
*/
TEST_F(opatIOTest, Header) {
OpatIO opatIO(EXAMPLE_FILENAME);
Header header = opatIO.getHeader();
EXPECT_EQ(header.version, 1);
EXPECT_EQ(header.numTables, 20);
EXPECT_EQ(header.headerSize, 256);
EXPECT_EQ(header.indexOffset, 416416);
EXPECT_EQ(std::string(header.creationDate), "Feb 17, 2025");
EXPECT_EQ(std::string(header.sourceInfo), "utils/opatio/utils/mkTestData.py");
EXPECT_EQ(std::string(header.comment), "Synthetic Opacity Tables");
EXPECT_EQ(header.numIndex, 2);
}
/**
* @test Verify the number of index values is correct. Also check the byte position and index vector
*/
TEST_F(opatIOTest, TableIndex) {
OpatIO opatIO(EXAMPLE_FILENAME);
std::vector<TableIndex> tableIndex = opatIO.getTableIndex();
EXPECT_EQ(tableIndex.size(), 20);
EXPECT_EQ(tableIndex[0].index.at(0), 0.1);
EXPECT_EQ(tableIndex[0].index.at(1), 0.001);
EXPECT_EQ(tableIndex[0].byteStart, 256);
EXPECT_EQ(tableIndex[0].byteEnd, 21064);
}
/**
* @test Verify the maxQDepth (for caching)
*/
TEST_F(opatIOTest, MaxQDepth) {
OpatIO opatIO(EXAMPLE_FILENAME);
EXPECT_EQ(opatIO.getMaxQDepth(), 20);
opatIO.setMaxQDepth(5);
EXPECT_EQ(opatIO.getMaxQDepth(), 5);
}
/**
* @test Verify the Unload function
*/
TEST_F(opatIOTest, Unload){
OpatIO opatIO(EXAMPLE_FILENAME);
EXPECT_NO_THROW(opatIO.unload());
EXPECT_FALSE(opatIO.isLoaded());
}
/**
* @test Verify the lookupTableID function
*/
TEST_F(opatIOTest, LookupTableID) {
OpatIO opatIO(EXAMPLE_FILENAME);
std::vector<double> index = {0.321053, 0.0116842};
EXPECT_EQ(opatIO.lookupTableID(index), 7);
}
/**
* @test Verify the GetTable function by checking the first 2x2 square of the table
*/
TEST_F(opatIOTest, GetTable) {
OpatIO opatIO(EXAMPLE_FILENAME);
std::vector<double> index = {0.1, 0.001};
OPATTable tab = opatIO.getTable(index);
EXPECT_EQ(tab.N_R, 50);
EXPECT_EQ(tab.N_T, 50);
EXPECT_DOUBLE_EQ(tab.logR[0], -8.0);
EXPECT_DOUBLE_EQ(tab.logT[0], 3.0);
EXPECT_DOUBLE_EQ(tab.logKappa[0][0], -0.50183952461055);
EXPECT_DOUBLE_EQ(tab.logKappa[0][1], 1.8028572256396647);
EXPECT_DOUBLE_EQ(tab.logKappa[1][0], 1.8783385110582342);
EXPECT_DOUBLE_EQ(tab.logKappa[1][1], 1.1005312934444582);
}
/**
* @test Verify the GetTable function by computing the checksum of the first table and
* comparing it to the stored checksum
*/
TEST_F(opatIOTest, Checksum) {
OpatIO opatIO(EXAMPLE_FILENAME);
std::vector<double> index = {0.1, 0.001};
TableIndex tableIndex = opatIO.getTableIndex(index);
std::vector<unsigned char> hash = opatIO.computeChecksum(index);
std::string hexRepr = picosha2::bytes_to_hex_string(hash);
std::vector<unsigned char> storedHashVec(tableIndex.sha256, tableIndex.sha256 + 32);
std::string storedHexRepr = picosha2::bytes_to_hex_string(storedHashVec);
EXPECT_EQ(hexRepr, storedHexRepr);
}
TEST_F(opatIOTest, ChecksumAll) {
OpatIO opatIO(EXAMPLE_FILENAME);
opatIO.setMaxQDepth(5);
EXPECT_TRUE(opatIO.validateAll());
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
executable('tryGS98', 'opacity.cpp', dependencies: [opatio_dep])

View File

@@ -0,0 +1,28 @@
#include <vector>
#include <iostream>
//#include <string>
#include "opatIO.h"
int main() {
std::string FILENAME = "GS98hz.opat";
OpatIO opatIO(FILENAME);
Header header = opatIO.getHeader();
std::cout << header.version << std::endl;
std::cout << header.comment << std::endl;
std::cout << header.numTables << std::endl;
std::vector<TableIndex> tableIndex = opatIO.getTableIndex();
//print out the X,Z pairs in the table
for (size_t i=0; i< tableIndex.size()-1; i++){
std::cout << "Table [" << i << "]: {" << tableIndex[i].index.at(0) << ", "
<< tableIndex[i].index.at(1) << "}" << std::endl;
}
//find the table index corresponding to X=0.1, Z=0.001
std::vector<double> index = {0.1, 0.001};
OPATTable tab = opatIO.getTable(index);
}

View File

@@ -16,5 +16,8 @@ foreach test_file : test_sources
)
# Add the executable as a test
test(exe_name, test_exe)
test(
exe_name,
test_exe,
env: ['MESON_SOURCE_ROOT=' + meson.project_source_root(), 'MESON_BUILD_ROOT=' + meson.project_build_root()])
endforeach

View File

@@ -7,9 +7,12 @@
#include <sstream>
#include <regex>
#include <source_location>
#include "config.h"
#include <chrono>
#include "quill/LogMacros.h"
std::string TEST_CONFIG = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/testsConfig.yaml";
std::string getLastLine(const std::string& filename) {
std::ifstream file(filename);
std::string line, lastLine;
@@ -38,6 +41,7 @@ std::string stripTimestamps(const std::string& logLine) {
class probeTest : public ::testing::Test {};
TEST_F(probeTest, DefaultConstructorTest) {
Config::getInstance().loadConfig(TEST_CONFIG);
EXPECT_NO_THROW(Probe::LogManager::getInstance());
}
@@ -50,20 +54,23 @@ TEST_F(probeTest, waitTest) {
}
TEST_F(probeTest, getLoggerTest) {
Config::getInstance().loadConfig(TEST_CONFIG);
Probe::LogManager& logManager = Probe::LogManager::getInstance();
std::string loggerName = "log";
quill::Logger* logger = logManager.getLogger(loggerName);
const std::string loggerName = "testLog";
const std::string filename = "test.log";
quill::Logger* logger = logManager.newFileLogger(filename, loggerName);
EXPECT_NE(logger, nullptr);
LOG_INFO(logger, "This is a test message");
// Wait for the log to be written by calling getLastLine until it is non empty
std::string lastLine;
while (lastLine.empty()) {
lastLine = getLastLine("4DSSE.log");
lastLine = getLastLine("test.log");
}
EXPECT_EQ(stripTimestamps(lastLine), "This is a test message");
}
TEST_F(probeTest, newFileLoggerTest) {
Config::getInstance().loadConfig(TEST_CONFIG);
Probe::LogManager& logManager = Probe::LogManager::getInstance();
const std::string loggerName = "newLog";
const std::string filename = "newLog.log";
@@ -79,10 +86,12 @@ TEST_F(probeTest, newFileLoggerTest) {
}
TEST_F(probeTest, getLoggerNames) {
Config::getInstance().loadConfig(TEST_CONFIG);
Probe::LogManager& logManager = Probe::LogManager::getInstance();
std::vector<std::string> loggerNames = logManager.getLoggerNames();
EXPECT_EQ(loggerNames.size(), 3);
EXPECT_EQ(loggerNames.size(), 4);
EXPECT_EQ(loggerNames.at(0), "log");
EXPECT_EQ(loggerNames.at(1), "newLog");
EXPECT_EQ(loggerNames.at(2), "stdout");
EXPECT_EQ(loggerNames.at(3), "testLog");
}

View File

@@ -0,0 +1,24 @@
# Test files for const
test_sources = [
'resourceManagerTest.cpp',
]
foreach test_file : test_sources
exe_name = test_file.split('.')[0]
message('Building test: ' + exe_name)
# Create an executable target for each test
test_exe = executable(
exe_name,
test_file,
dependencies: [gtest_dep, resourceManager_dep, gtest_main, macros_dep],
include_directories: include_directories('../../src/resource/public'),
install_rpath: '@loader_path/../../src' # Ensure runtime library path resolves correctly
)
# Add the executable as a test
test(
exe_name,
test_exe,
env: ['MESON_SOURCE_ROOT=' + meson.project_source_root(), 'MESON_BUILD_ROOT=' + meson.project_build_root()])
endforeach

View File

@@ -0,0 +1,61 @@
#include <gtest/gtest.h>
#include "resourceManager.h"
#include "config.h"
#include "eosIO.h"
#include "helm.h"
#include "resourceManagerTypes.h"
#include <string>
#include <stdexcept>
#include <vector>
#include <set>
#include "debug.h"
/**
* @file configTest.cpp
* @brief Unit tests for the resourceManager class.
*/
std::string TEST_CONFIG = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/testsConfig.yaml";
/**
* @brief Test suite for the resourceManager class.
*/
class resourceManagerTest : public ::testing::Test {};
/**
* @brief Test the constructor of the resourceManager class.
*/
TEST_F(resourceManagerTest, constructor) {
Config::getInstance().loadConfig(TEST_CONFIG);
EXPECT_NO_THROW(ResourceManager::getInstance());
}
TEST_F(resourceManagerTest, getAvaliableResources) {
Config::getInstance().loadConfig(TEST_CONFIG);
ResourceManager& rm = ResourceManager::getInstance();
std::vector<std::string> resources = rm.getAvaliableResources();
std::set<std::string> expected = {"eos:helm", "mesh:sphere"};
std::set<std::string> actual(resources.begin(), resources.end());
EXPECT_EQ(expected, actual);
}
TEST_F(resourceManagerTest, getResource) {
Config::getInstance().loadConfig(TEST_CONFIG);
ResourceManager& rm = ResourceManager::getInstance();
std::string name = "eos:helm";
const Resource &r = rm.getResource(name);
// BREAKPOINT();
const auto &eos = std::get<std::unique_ptr<EosIO>>(r);
EXPECT_EQ("helm", eos->getFormat());
EOSTable &table = eos->getTable();
// -- Extract the Helm table from the EOSTable
helmholtz::HELMTable &helmTable = *std::get<std::unique_ptr<helmholtz::HELMTable>>(table);
EXPECT_DOUBLE_EQ(helmTable.f[0][0], -1692098915534.8142);
EXPECT_THROW(rm.getResource("opac:GS98:high:doesNotExist"), std::runtime_error);
}