build(libcomposition): brought working build system into libcomposition
This commit is contained in:
91
.gitignore
vendored
Normal file
91
.gitignore
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
*.env
|
||||||
|
*.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
ENV.bak/
|
||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# C and C++ (using Meson)
|
||||||
|
build/
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.d
|
||||||
|
*.dSYM/
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.obj
|
||||||
|
*.dll
|
||||||
|
*.lib
|
||||||
|
*.pdb
|
||||||
|
*.exp
|
||||||
|
*.log
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Fortran
|
||||||
|
*.mod
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Doxygen
|
||||||
|
html/
|
||||||
|
latex/
|
||||||
|
xml/
|
||||||
|
man/
|
||||||
|
rtf/
|
||||||
|
tags
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
*.swp
|
||||||
|
*._DS_Store
|
||||||
|
*.DS_Store
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
*.cache
|
||||||
|
*.private
|
||||||
|
*.private/
|
||||||
|
|
||||||
|
subprojects/mfem/
|
||||||
|
subprojects/tetgen/
|
||||||
|
subprojects/yaml-cpp/
|
||||||
|
subprojects/quill/
|
||||||
|
subprojects/googletest-*/
|
||||||
|
subprojects/opat-core/
|
||||||
|
subprojects/pybind11*/
|
||||||
|
subprojects/packagecache/
|
||||||
|
subprojects/hypre/
|
||||||
|
subprojects/qhull/
|
||||||
|
subprojects/cppad/
|
||||||
|
subprojects/libconfig/
|
||||||
|
subprojects/libconstants/
|
||||||
|
subprojects/liblogging/
|
||||||
|
|
||||||
|
qhull.wrap
|
||||||
|
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
*.log
|
||||||
|
mpi-install-log.txt
|
||||||
|
|
||||||
|
output/
|
||||||
|
|
||||||
|
.boost_installed
|
||||||
|
4DSSE_logs/
|
||||||
|
.last_build_flags
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
scratch/
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "atomicSpecies.h"
|
#include "atomicSpecies.h"
|
||||||
|
|
||||||
namespace serif::atomic {
|
namespace fourdst::atomic {
|
||||||
struct Species {
|
struct Species {
|
||||||
std::string m_name; //< Name of the species
|
std::string m_name; //< Name of the species
|
||||||
std::string m_el; //< Element symbol
|
std::string m_el; //< Element symbol
|
||||||
@@ -101,9 +101,9 @@ namespace serif::atomic {
|
|||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template<>
|
template<>
|
||||||
struct hash<serif::atomic::Species> {
|
struct hash<fourdst::atomic::Species> {
|
||||||
size_t operator()(const serif::atomic::Species& s) const noexcept {
|
size_t operator()(const fourdst::atomic::Species& s) const noexcept {
|
||||||
return std::hash<std::string>()(s.m_name);
|
return std::hash<std::string>()(s.m_name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "atomicSpecies.h"
|
#include "atomicSpecies.h"
|
||||||
|
|
||||||
namespace serif::atomic {
|
namespace fourdst::atomic {
|
||||||
static const Species n_1("n-1", "n", 1, 1, 0, 1, 0.0, "B-", 782.347, 1.0086649159, 0.00047);
|
static const Species n_1("n-1", "n", 1, 1, 0, 1, 0.0, "B-", 782.347, 1.0086649159, 0.00047);
|
||||||
static const Species H_1("H-1", "H", -1, 0, 1, 1, 0.0, "B-", std::numeric_limits<double>::quiet_NaN(), 1.007825031898, 1.4e-05);
|
static const Species H_1("H-1", "H", -1, 0, 1, 1, 0.0, "B-", std::numeric_limits<double>::quiet_NaN(), 1.007825031898, 1.4e-05);
|
||||||
static const Species H_2("H-2", "H", 0, 1, 1, 2, 1112.2831, "B-", std::numeric_limits<double>::quiet_NaN(), 2.014101777844, 1.5e-05);
|
static const Species H_2("H-2", "H", 0, 1, 1, 2, 1112.2831, "B-", std::numeric_limits<double>::quiet_NaN(), 2.014101777844, 1.5e-05);
|
||||||
|
|||||||
1
assets/static/meson.build
Normal file
1
assets/static/meson.build
Normal file
@@ -0,0 +1 @@
|
|||||||
|
subdir('atomic')
|
||||||
2
build-config/fourdst/libconfig/meson.build
Normal file
2
build-config/fourdst/libconfig/meson.build
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
config_p = subproject('libconfig')
|
||||||
|
config_dep = config_p.get_variable('config_dep')
|
||||||
2
build-config/fourdst/libconstants/meson.build
Normal file
2
build-config/fourdst/libconstants/meson.build
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
const_p = subproject('libconstants')
|
||||||
|
const_dep = const_p.get_variable('const_dep')
|
||||||
6
build-config/fourdst/liblogging/meson.build
Normal file
6
build-config/fourdst/liblogging/meson.build
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
logging_p = subproject('liblogging')
|
||||||
|
|
||||||
|
logging_dep = logging_p.get_variable('logging_dep')
|
||||||
|
quill_dep = logging_p.get_variable('quill_dep')
|
||||||
|
|
||||||
|
log_dep = [logging_dep, quill_dep]
|
||||||
3
build-config/fourdst/meson.build
Normal file
3
build-config/fourdst/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
subdir('libconstants')
|
||||||
|
subdir('liblogging')
|
||||||
|
subdir('libconfig')
|
||||||
@@ -1,24 +1,5 @@
|
|||||||
cmake = import('cmake')
|
cmake = import('cmake')
|
||||||
|
|
||||||
subdir('mfem')
|
subdir('fourdst')
|
||||||
subdir('yaml-cpp')
|
|
||||||
subdir('quill')
|
|
||||||
subdir('boost')
|
|
||||||
subdir('opatIO')
|
|
||||||
subdir('mpi')
|
|
||||||
subdir('hypre')
|
|
||||||
subdir('pybind')
|
|
||||||
subdir('cppad')
|
subdir('cppad')
|
||||||
|
|
||||||
# Set the config file error handling options
|
|
||||||
configErr = get_option('config_error_handling')
|
|
||||||
|
|
||||||
# build up any -D flags we need
|
|
||||||
commonCppArgs = []
|
|
||||||
if configErr == 'warn'
|
|
||||||
commonCppArgs += ['-DCONFIG_WARN']
|
|
||||||
elif configErr == 'harsh'
|
|
||||||
commonCppArgs += ['-DCONFIG_HARSH']
|
|
||||||
endif
|
|
||||||
|
|
||||||
add_project_arguments(commonCppArgs, language: 'cpp')
|
|
||||||
|
|||||||
42
meson.build
Normal file
42
meson.build
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# ***********************************************************************
|
||||||
|
#
|
||||||
|
# Copyright (C) 2025 -- The 4D-STAR Collaboration
|
||||||
|
# File Author: Emily Boudreaux
|
||||||
|
# Last Modified: June 21, 2025
|
||||||
|
#
|
||||||
|
# libcomposition is free software; you can use it and/or modify
|
||||||
|
# it under the terms and restrictions the GNU General Library Public
|
||||||
|
# License version 3 (GPLv3) as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# libcomposition is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the GNU Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public License
|
||||||
|
# along with this software; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# *********************************************************************** #
|
||||||
|
project('libcomposition', 'cpp', version: 'v1.0.0', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0')
|
||||||
|
|
||||||
|
# Add default visibility for all C++ targets
|
||||||
|
add_project_arguments('-fvisibility=default', language: 'cpp')
|
||||||
|
|
||||||
|
cpp = meson.get_compiler('cpp')
|
||||||
|
subdir('build-config')
|
||||||
|
subdir('assets/static')
|
||||||
|
subdir('src')
|
||||||
|
subdir('tests')
|
||||||
|
|
||||||
|
pkg = import('pkgconfig')
|
||||||
|
pkg.generate(
|
||||||
|
name: 'libcomposition',
|
||||||
|
description: 'Composition module for SERiF and related projects',
|
||||||
|
version: meson.project_version(),
|
||||||
|
libraries: [libcomposition],
|
||||||
|
subdirs: ['libcomposition'],
|
||||||
|
filebase: 'libcomposition',
|
||||||
|
install_dir: join_paths(get_option('libdir'), 'pkgconfig')
|
||||||
|
)
|
||||||
|
|
||||||
23
readme.md
Normal file
23
readme.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# libcomposition
|
||||||
|
|
||||||
|
libcomposition is the chemistry tracking tool used by SERiF and related products.
|
||||||
|
|
||||||
|
This has been broken out of the main serif project to allow for more modularity
|
||||||
|
|
||||||
|
## Building
|
||||||
|
In order to build libconstants you need `meson>=1.5.0`. This can be installed with `pip`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install "meson>=1.5.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then from the root libcomposition directory it is as simple as
|
||||||
|
|
||||||
|
```bash
|
||||||
|
meson setup build --buildtype=release
|
||||||
|
meson compile -C build
|
||||||
|
meson test -C build
|
||||||
|
```
|
||||||
|
|
||||||
|
this will auto generate a pkg-config file for you so that linking other libraries to libcomposition is easy.
|
||||||
|
|
||||||
@@ -8,10 +8,10 @@ composition_headers = files(
|
|||||||
)
|
)
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
probe_dep,
|
|
||||||
quill_dep,
|
|
||||||
species_weight_dep,
|
species_weight_dep,
|
||||||
const_dep,
|
const_dep,
|
||||||
|
config_dep,
|
||||||
|
log_dep
|
||||||
]
|
]
|
||||||
|
|
||||||
# Define the libcomposition library so it can be linked against by other parts of the build system
|
# Define the libcomposition library so it can be linked against by other parts of the build system
|
||||||
@@ -30,4 +30,4 @@ composition_dep = declare_dependency(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Make headers accessible
|
# Make headers accessible
|
||||||
install_headers(composition_headers, subdir : 'SERiF/composition')
|
install_headers(composition_headers, subdir : 'libcomposition/composition')
|
||||||
|
|||||||
@@ -33,13 +33,13 @@
|
|||||||
#include "atomicSpecies.h"
|
#include "atomicSpecies.h"
|
||||||
#include "species.h"
|
#include "species.h"
|
||||||
|
|
||||||
namespace serif::composition {
|
namespace fourdst::composition {
|
||||||
|
|
||||||
CompositionEntry::CompositionEntry() : m_symbol("H-1"), m_isotope(serif::atomic::species.at("H-1")),
|
CompositionEntry::CompositionEntry() : m_symbol("H-1"), m_isotope(fourdst::atomic::species.at("H-1")),
|
||||||
m_initialized(false) {
|
m_initialized(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositionEntry::CompositionEntry(const std::string& symbol, const bool massFracMode) : m_symbol(symbol), m_isotope(serif::atomic::species.at(symbol)), m_massFracMode(massFracMode) {
|
CompositionEntry::CompositionEntry(const std::string& symbol, const bool massFracMode) : m_symbol(symbol), m_isotope(fourdst::atomic::species.at(symbol)), m_massFracMode(massFracMode) {
|
||||||
setSpecies(symbol);
|
setSpecies(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,11 +56,11 @@ namespace serif::composition {
|
|||||||
if (m_initialized) {
|
if (m_initialized) {
|
||||||
throw std::runtime_error("Composition entry is already initialized.");
|
throw std::runtime_error("Composition entry is already initialized.");
|
||||||
}
|
}
|
||||||
if (serif::atomic::species.count(symbol) == 0) {
|
if (fourdst::atomic::species.count(symbol) == 0) {
|
||||||
throw std::runtime_error("Invalid symbol.");
|
throw std::runtime_error("Invalid symbol.");
|
||||||
}
|
}
|
||||||
m_symbol = symbol;
|
m_symbol = symbol;
|
||||||
m_isotope = serif::atomic::species.at(symbol);
|
m_isotope = fourdst::atomic::species.at(symbol);
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ namespace serif::composition {
|
|||||||
return m_relAbundance;
|
return m_relAbundance;
|
||||||
}
|
}
|
||||||
|
|
||||||
serif::atomic::Species CompositionEntry::isotope() const {
|
fourdst::atomic::Species CompositionEntry::isotope() const {
|
||||||
return m_isotope;
|
return m_isotope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ namespace serif::composition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::isValidSymbol(const std::string& symbol) {
|
bool Composition::isValidSymbol(const std::string& symbol) {
|
||||||
return serif::atomic::species.contains(symbol);
|
return fourdst::atomic::species.contains(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
double Composition::setMassFraction(const std::string& symbol, const double& mass_fraction) {
|
double Composition::setMassFraction(const std::string& symbol, const double& mass_fraction) {
|
||||||
@@ -652,7 +652,7 @@ namespace serif::composition {
|
|||||||
return m_compositions.count(symbol) > 0;
|
return m_compositions.count(symbol) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::contains(const serif::atomic::Species &isotope) const {
|
bool Composition::contains(const fourdst::atomic::Species &isotope) const {
|
||||||
// Check if the isotope's symbol is in the composition
|
// Check if the isotope's symbol is in the composition
|
||||||
if (!m_finalized) {
|
if (!m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||||
@@ -696,4 +696,4 @@ namespace serif::composition {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace serif::composition
|
} // namespace fourdst::composition
|
||||||
|
|||||||
@@ -27,12 +27,12 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "probe.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#include "atomicSpecies.h"
|
#include "atomicSpecies.h"
|
||||||
|
|
||||||
namespace serif::composition {
|
namespace fourdst::composition {
|
||||||
struct CanonicalComposition {
|
struct CanonicalComposition {
|
||||||
double X = 0.0; ///< Mass fraction of Hydrogen.
|
double X = 0.0; ///< Mass fraction of Hydrogen.
|
||||||
double Y = 0.0; ///< Mass fraction of Helium.
|
double Y = 0.0; ///< Mass fraction of Helium.
|
||||||
@@ -63,7 +63,7 @@ namespace serif::composition {
|
|||||||
*/
|
*/
|
||||||
struct CompositionEntry {
|
struct CompositionEntry {
|
||||||
std::string m_symbol; ///< The chemical symbol of the species.
|
std::string m_symbol; ///< The chemical symbol of the species.
|
||||||
serif::atomic::Species m_isotope; ///< The isotope of the species.
|
fourdst::atomic::Species m_isotope; ///< The isotope of the species.
|
||||||
bool m_massFracMode = true; ///< The mode of the composition entry. True if mass fraction, false if number fraction.
|
bool m_massFracMode = true; ///< The mode of the composition entry. True if mass fraction, false if number fraction.
|
||||||
|
|
||||||
double m_massFraction = 0.0; ///< The mass fraction of the species.
|
double m_massFraction = 0.0; ///< The mass fraction of the species.
|
||||||
@@ -142,7 +142,7 @@ namespace serif::composition {
|
|||||||
* @brief Gets the isotope of the species.
|
* @brief Gets the isotope of the species.
|
||||||
* @return The isotope of the species.
|
* @return The isotope of the species.
|
||||||
*/
|
*/
|
||||||
serif::atomic::Species isotope() const;
|
fourdst::atomic::Species isotope() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the mode of the composition entry.
|
* @brief Gets the mode of the composition entry.
|
||||||
@@ -215,8 +215,8 @@ namespace serif::composition {
|
|||||||
*/
|
*/
|
||||||
class Composition {
|
class Composition {
|
||||||
private:
|
private:
|
||||||
serif::config::Config& m_config = serif::config::Config::getInstance();
|
fourdst::config::Config& m_config = fourdst::config::Config::getInstance();
|
||||||
serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance();
|
fourdst::logging::LogManager& m_logManager = fourdst::logging::LogManager::getInstance();
|
||||||
quill::Logger* m_logger = m_logManager.getLogger("log");
|
quill::Logger* m_logger = m_logManager.getLogger("log");
|
||||||
|
|
||||||
bool m_finalized = false; ///< True if the composition is finalized.
|
bool m_finalized = false; ///< True if the composition is finalized.
|
||||||
@@ -473,7 +473,7 @@ namespace serif::composition {
|
|||||||
*/
|
*/
|
||||||
bool hasSymbol(const std::string& symbol) const;
|
bool hasSymbol(const std::string& symbol) const;
|
||||||
|
|
||||||
bool contains(const serif::atomic::Species& isotope) const;
|
bool contains(const fourdst::atomic::Species& isotope) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the composition mode.
|
* @brief Sets the composition mode.
|
||||||
@@ -508,4 +508,4 @@ namespace serif::composition {
|
|||||||
Composition operator+(const Composition& other) const;
|
Composition operator+(const Composition& other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
}; // namespace serif::composition
|
}; // namespace fourdst::composition
|
||||||
|
|||||||
1
src/meson.build
Normal file
1
src/meson.build
Normal file
@@ -0,0 +1 @@
|
|||||||
|
subdir('composition')
|
||||||
7
subprojects/libconfig.wrap
Normal file
7
subprojects/libconfig.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-git]
|
||||||
|
url = https://github.com/4D-STAR/libconfig.git
|
||||||
|
revision = v1.0.0
|
||||||
|
depth = 1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
libconfig = config_dep
|
||||||
7
subprojects/libconstants.wrap
Normal file
7
subprojects/libconstants.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-git]
|
||||||
|
url = https://github.com/4D-STAR/libconstants.git
|
||||||
|
revision = v1.1
|
||||||
|
depth = 1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
libconstants = const_dep
|
||||||
7
subprojects/liblogging.wrap
Normal file
7
subprojects/liblogging.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-git]
|
||||||
|
url = https://github.com/4D-STAR/liblogging.git
|
||||||
|
revision = v1.0.1
|
||||||
|
depth = 1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
liblogging = logging_dep
|
||||||
2
subprojects/quill.wrap
Normal file
2
subprojects/quill.wrap
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[wrap-redirect]
|
||||||
|
filename = liblogging/subprojects/quill.wrap
|
||||||
2
subprojects/yaml-cpp.wrap
Normal file
2
subprojects/yaml-cpp.wrap
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[wrap-redirect]
|
||||||
|
filename = libconfig/subprojects/yaml-cpp.wrap
|
||||||
@@ -19,20 +19,20 @@ class compositionTest : public ::testing::Test {};
|
|||||||
* @brief Test the constructor of the composition class.
|
* @brief Test the constructor of the composition class.
|
||||||
*/
|
*/
|
||||||
TEST_F(compositionTest, isotopeMasses) {
|
TEST_F(compositionTest, isotopeMasses) {
|
||||||
EXPECT_NO_THROW(serif::atomic::species.at("H-1"));
|
EXPECT_NO_THROW(fourdst::atomic::species.at("H-1"));
|
||||||
EXPECT_DOUBLE_EQ(serif::atomic::species.at("H-1").mass(), 1.007825031898);
|
EXPECT_DOUBLE_EQ(fourdst::atomic::species.at("H-1").mass(), 1.007825031898);
|
||||||
EXPECT_DOUBLE_EQ(serif::atomic::species.at("He-3").mass(), 3.0160293219700001);
|
EXPECT_DOUBLE_EQ(fourdst::atomic::species.at("He-3").mass(), 3.0160293219700001);
|
||||||
EXPECT_DOUBLE_EQ(serif::atomic::species.at("He-4").mass(),4.0026032541300003);
|
EXPECT_DOUBLE_EQ(fourdst::atomic::species.at("He-4").mass(),4.0026032541300003);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, constructor) {
|
TEST_F(compositionTest, constructor) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
EXPECT_NO_THROW(serif::composition::Composition comp);
|
EXPECT_NO_THROW(fourdst::composition::Composition comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, registerSymbol) {
|
TEST_F(compositionTest, registerSymbol) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
EXPECT_NO_THROW(comp.registerSymbol("H-1"));
|
EXPECT_NO_THROW(comp.registerSymbol("H-1"));
|
||||||
EXPECT_NO_THROW(comp.registerSymbol("He-4"));
|
EXPECT_NO_THROW(comp.registerSymbol("He-4"));
|
||||||
EXPECT_THROW(comp.registerSymbol("H-19"), std::runtime_error);
|
EXPECT_THROW(comp.registerSymbol("H-19"), std::runtime_error);
|
||||||
@@ -46,8 +46,8 @@ TEST_F(compositionTest, registerSymbol) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, setGetComposition) {
|
TEST_F(compositionTest, setGetComposition) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
|
|
||||||
@@ -72,8 +72,8 @@ TEST_F(compositionTest, setGetComposition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, setGetNumberFraction) {
|
TEST_F(compositionTest, setGetNumberFraction) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1", false);
|
comp.registerSymbol("H-1", false);
|
||||||
comp.registerSymbol("He-4", false);
|
comp.registerSymbol("He-4", false);
|
||||||
|
|
||||||
@@ -89,8 +89,8 @@ TEST_F(compositionTest, setGetNumberFraction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, subset) {
|
TEST_F(compositionTest, subset) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
comp.setMassFraction("H-1", 0.6);
|
comp.setMassFraction("H-1", 0.6);
|
||||||
@@ -98,14 +98,14 @@ TEST_F(compositionTest, subset) {
|
|||||||
EXPECT_NO_THROW(comp.finalize());
|
EXPECT_NO_THROW(comp.finalize());
|
||||||
|
|
||||||
std::vector<std::string> symbols = {"H-1"};
|
std::vector<std::string> symbols = {"H-1"};
|
||||||
serif::composition::Composition subsetComp = comp.subset(symbols, "norm");
|
fourdst::composition::Composition subsetComp = comp.subset(symbols, "norm");
|
||||||
EXPECT_TRUE(subsetComp.finalize());
|
EXPECT_TRUE(subsetComp.finalize());
|
||||||
EXPECT_DOUBLE_EQ(subsetComp.getMassFraction("H-1"), 1.0);
|
EXPECT_DOUBLE_EQ(subsetComp.getMassFraction("H-1"), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, finalizeWithNormalization) {
|
TEST_F(compositionTest, finalizeWithNormalization) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
comp.setMassFraction("H-1", 0.3);
|
comp.setMassFraction("H-1", 0.3);
|
||||||
@@ -116,8 +116,8 @@ TEST_F(compositionTest, finalizeWithNormalization) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, finalizeWithoutNormalization) {
|
TEST_F(compositionTest, finalizeWithoutNormalization) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
comp.setMassFraction("H-1", 0.5);
|
comp.setMassFraction("H-1", 0.5);
|
||||||
@@ -128,8 +128,8 @@ TEST_F(compositionTest, finalizeWithoutNormalization) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, getComposition) {
|
TEST_F(compositionTest, getComposition) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
comp.setMassFraction("H-1", 0.6);
|
comp.setMassFraction("H-1", 0.6);
|
||||||
@@ -143,8 +143,8 @@ TEST_F(compositionTest, getComposition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, setCompositionMode) {
|
TEST_F(compositionTest, setCompositionMode) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
comp.setMassFraction("H-1", 0.6);
|
comp.setMassFraction("H-1", 0.6);
|
||||||
@@ -165,8 +165,8 @@ TEST_F(compositionTest, setCompositionMode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, hasSymbol) {
|
TEST_F(compositionTest, hasSymbol) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp;
|
fourdst::composition::Composition comp;
|
||||||
comp.registerSymbol("H-1");
|
comp.registerSymbol("H-1");
|
||||||
comp.registerSymbol("He-4");
|
comp.registerSymbol("He-4");
|
||||||
comp.setMassFraction("H-1", 0.6);
|
comp.setMassFraction("H-1", 0.6);
|
||||||
@@ -180,28 +180,28 @@ TEST_F(compositionTest, hasSymbol) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(compositionTest, mix) {
|
TEST_F(compositionTest, mix) {
|
||||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||||
serif::composition::Composition comp1;
|
fourdst::composition::Composition comp1;
|
||||||
comp1.registerSymbol("H-1");
|
comp1.registerSymbol("H-1");
|
||||||
comp1.registerSymbol("He-4");
|
comp1.registerSymbol("He-4");
|
||||||
comp1.setMassFraction("H-1", 0.6);
|
comp1.setMassFraction("H-1", 0.6);
|
||||||
comp1.setMassFraction("He-4", 0.4);
|
comp1.setMassFraction("He-4", 0.4);
|
||||||
EXPECT_NO_THROW(comp1.finalize());
|
EXPECT_NO_THROW(comp1.finalize());
|
||||||
|
|
||||||
serif::composition::Composition comp2;
|
fourdst::composition::Composition comp2;
|
||||||
comp2.registerSymbol("H-1");
|
comp2.registerSymbol("H-1");
|
||||||
comp2.registerSymbol("He-4");
|
comp2.registerSymbol("He-4");
|
||||||
comp2.setMassFraction("H-1", 0.4);
|
comp2.setMassFraction("H-1", 0.4);
|
||||||
comp2.setMassFraction("He-4", 0.6);
|
comp2.setMassFraction("He-4", 0.6);
|
||||||
EXPECT_NO_THROW(comp2.finalize());
|
EXPECT_NO_THROW(comp2.finalize());
|
||||||
|
|
||||||
serif::composition::Composition mixedComp = comp1 + comp2;
|
fourdst::composition::Composition mixedComp = comp1 + comp2;
|
||||||
EXPECT_TRUE(mixedComp.finalize());
|
EXPECT_TRUE(mixedComp.finalize());
|
||||||
EXPECT_DOUBLE_EQ(mixedComp.getMassFraction("H-1"), 0.5);
|
EXPECT_DOUBLE_EQ(mixedComp.getMassFraction("H-1"), 0.5);
|
||||||
EXPECT_DOUBLE_EQ(mixedComp.getMassFraction("He-4"), 0.5);
|
EXPECT_DOUBLE_EQ(mixedComp.getMassFraction("He-4"), 0.5);
|
||||||
|
|
||||||
serif::composition::Composition mixedComp2 = comp1.mix(comp2, 0.25);
|
fourdst::composition::Composition mixedComp2 = comp1.mix(comp2, 0.25);
|
||||||
EXPECT_TRUE(mixedComp2.finalize());
|
EXPECT_TRUE(mixedComp2.finalize());
|
||||||
EXPECT_DOUBLE_EQ(mixedComp2.getMassFraction("H-1"), 0.45);
|
EXPECT_DOUBLE_EQ(mixedComp2.getMassFraction("H-1"), 0.45);
|
||||||
EXPECT_DOUBLE_EQ(mixedComp2.getMassFraction("He-4"), 0.55);
|
EXPECT_DOUBLE_EQ(mixedComp2.getMassFraction("He-4"), 0.55);
|
||||||
}
|
}
|
||||||
|
|||||||
7
tests/meson.build
Normal file
7
tests/meson.build
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Google Test dependency
|
||||||
|
gtest_dep = dependency('gtest', main: true, required : true)
|
||||||
|
gtest_main = dependency('gtest_main', required: true)
|
||||||
|
gtest_nomain_dep = dependency('gtest', main: false, required : true)
|
||||||
|
|
||||||
|
# Subdirectories for unit and integration tests
|
||||||
|
subdir('composition')
|
||||||
151
utils/atomic/convertWeightsToHeader.py
Normal file
151
utils/atomic/convertWeightsToHeader.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
# Define fixed-width column specifications based on the format:
|
||||||
|
# a1 (width 1), i3 (width 3), i5 (width 5), i5 (width 5), i5 (width 5),
|
||||||
|
# 1x (skip 1), a3 (width 3), a4 (width 4), 1x (skip 1),
|
||||||
|
# f14.6 (width 14), f12.6 (width 12), f13.5 (width 13),
|
||||||
|
# 1x (skip 1), f10.5 (width 10), 1x (skip 1),
|
||||||
|
# a2 (width 2), f13.5 (width 13), f11.5 (width 11),
|
||||||
|
# 1x (skip 1), i3 (width 3), 1x (skip 1),
|
||||||
|
# f13.6 (width 13), f12.6 (width 12)
|
||||||
|
# Compute cumulative positions (0-indexed):
|
||||||
|
colSpecs = [
|
||||||
|
(0, 1), # control
|
||||||
|
(1, 4), # NZ
|
||||||
|
(4, 9), # N
|
||||||
|
(9, 14), # Z
|
||||||
|
(14, 19), # A
|
||||||
|
# skip 1 char at position 19; next field starts at 20
|
||||||
|
(20, 23), # el
|
||||||
|
(23, 27), # o
|
||||||
|
# skip 1 char at position 27; next field starts at 28
|
||||||
|
(28, 42), # massExcess (f14.6)
|
||||||
|
(42, 54), # massExcessUnc (f12.6)
|
||||||
|
(54, 67), # bindingEnergy (f13.5)
|
||||||
|
# skip 1 char at position 67; next field starts at 68
|
||||||
|
(68, 78), # bindingEnergyUnc (f10.5)
|
||||||
|
# skip 1 char at position 78; next field starts at 79
|
||||||
|
(79, 81), # betaCode (a2)
|
||||||
|
(81, 94), # betaDecayEnergy (f13.5)
|
||||||
|
(94, 105), # betaDecayEnergyUnc (f11.5)
|
||||||
|
# skip 1 char at position 105; next field starts at 106
|
||||||
|
(106, 109),# atomicMassInt (i3)
|
||||||
|
# skip 1 char at position 109; next field starts at 110
|
||||||
|
(110, 123),# atomicMassFrac (f13.6)
|
||||||
|
(123, 135) # atomicMassUnc (f12.6)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Define column names (using camelCase for variables)
|
||||||
|
columnNames = [
|
||||||
|
"control",
|
||||||
|
"nz",
|
||||||
|
"n",
|
||||||
|
"z",
|
||||||
|
"a",
|
||||||
|
"el",
|
||||||
|
"o",
|
||||||
|
"massExcess",
|
||||||
|
"massExcessUnc",
|
||||||
|
"bindingEnergy",
|
||||||
|
"bindingEnergyUnc",
|
||||||
|
"betaCode",
|
||||||
|
"betaDecayEnergy",
|
||||||
|
"betaDecayEnergyUnc",
|
||||||
|
"atomicMassInt",
|
||||||
|
"atomicMassFrac",
|
||||||
|
"atomicMassUnc"
|
||||||
|
]
|
||||||
|
|
||||||
|
def combine_atomic_mass(row):
|
||||||
|
"""
|
||||||
|
Combine the integer and fractional parts of the atomic mass.
|
||||||
|
For example, if atomicMassInt is '1' and atomicMassFrac is '008664.91590',
|
||||||
|
this function returns float('1008664.91590').
|
||||||
|
"""
|
||||||
|
intPart = str(row["atomicMassInt"]).strip()
|
||||||
|
fracPart = str(row["atomicMassFrac"]).strip()
|
||||||
|
try:
|
||||||
|
combined = int(intPart) + float(fracPart)/1e6
|
||||||
|
return combined
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def mkInstanceName(row):
|
||||||
|
"""
|
||||||
|
Make a c++ instance name from the element and atomic number.
|
||||||
|
"""
|
||||||
|
speciesName = f"{row['el'].strip()}-{row['a']}"
|
||||||
|
return speciesName.replace("-", "_")
|
||||||
|
|
||||||
|
def formatSpecies(row):
|
||||||
|
"""
|
||||||
|
Format c++ instantiation of Species struct from row data.
|
||||||
|
"""
|
||||||
|
name = f"{row['el'].strip()}-{row['a']}"
|
||||||
|
instanceName = name.replace("-", "_")
|
||||||
|
nz = int(row['nz'])
|
||||||
|
n = int(row['n'])
|
||||||
|
z = int(row['z'])
|
||||||
|
a = int(row['a'])
|
||||||
|
bindingEnergy = float(row['bindingEnergy'])
|
||||||
|
atomicMass = float(row['atomicMass'])
|
||||||
|
atomicMassUnc = float(row['atomicMassUnc'])
|
||||||
|
NaN = "std::numeric_limits<double>::quiet_NaN()"
|
||||||
|
try:
|
||||||
|
betaDecayEnergy = float(row['betaDecayEnergy'].replace("#", "").replace("*", ""))
|
||||||
|
except ValueError:
|
||||||
|
betaDecayEnergy = NaN
|
||||||
|
instantiation = f"static const Species {instanceName}(\"{name}\", \"{row['el']}\", {nz}, {n}, {z}, {a}, {bindingEnergy}, \"{row['betaCode']}\", {betaDecayEnergy}, {atomicMass}, {atomicMassUnc});"
|
||||||
|
return instantiation, instanceName
|
||||||
|
|
||||||
|
def formatSpeciesDefines(row):
|
||||||
|
instanceName = f"SERIF_SPECIES_{formatSpecies(row)[1]}"
|
||||||
|
define = f"""#ifndef {instanceName.upper()}
|
||||||
|
#define {instanceName.upper()}
|
||||||
|
#endif // {instanceName.upper()}"""
|
||||||
|
return define
|
||||||
|
|
||||||
|
def formatHeader(dataFrame):
|
||||||
|
"""
|
||||||
|
Format c++ header file from DataFrame.
|
||||||
|
"""
|
||||||
|
header = f"""#pragma once
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string_view>
|
||||||
|
#include <string>
|
||||||
|
#include "atomicSpecies.h"
|
||||||
|
|
||||||
|
namespace fourdst::atomic {{
|
||||||
|
{'\n '.join([formatSpecies(row)[0] for index, row in dataFrame.iterrows()])}
|
||||||
|
static const std::unordered_map<std::string, Species> species = {{
|
||||||
|
{'\n '.join([f'{{"{row["el"].strip()}-{row["a"]}", {mkInstanceName(row)}}},' for index, row in dataFrame.iterrows()])}
|
||||||
|
}};
|
||||||
|
}}; // namespace fourdst::atomic
|
||||||
|
|
||||||
|
{'\n'.join([formatSpeciesDefines(row) for index, row in dataFrame.iterrows()])}
|
||||||
|
"""
|
||||||
|
return header
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
parser = argparse.ArgumentParser(description="Convert mass data to c++ header file.")
|
||||||
|
parser.add_argument("input", help="Input file path.")
|
||||||
|
parser.add_argument("-o", "--output", help="Output file path.", default="../../assets/static/atomic/include/species.h")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if not os.path.exists(args.input):
|
||||||
|
raise FileNotFoundError(f"File not found: {args.input}")
|
||||||
|
|
||||||
|
# Read the file (adjust the skiprows value if your header differs)
|
||||||
|
dataFrame = pd.read_fwf(args.input, colspecs=colSpecs, names=columnNames, skiprows=36)
|
||||||
|
|
||||||
|
# Combine the two atomic mass fields into one float column
|
||||||
|
dataFrame["atomicMass"] = dataFrame.apply(combine_atomic_mass, axis=1)
|
||||||
|
dataFrame.drop(columns=["atomicMassInt", "atomicMassFrac"], inplace=True)
|
||||||
|
|
||||||
|
# Format the header
|
||||||
|
header = formatHeader(dataFrame)
|
||||||
|
with open(args.output, "w") as f:
|
||||||
|
f.write(header)
|
||||||
13
utils/atomic/readme.md
Normal file
13
utils/atomic/readme.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Information
|
||||||
|
Simple python utility for turning the file assets/atomic/weights.dat into a c++ header which can be included to provide easy access to all atomic weights inside 4DSSE
|
||||||
|
|
||||||
|
## Requirments
|
||||||
|
In order to use this utility you will need
|
||||||
|
|
||||||
|
- Python
|
||||||
|
- Pandas
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```bash
|
||||||
|
python convertWeightsToHeader.py <path/to/weights.dat> -o atomicWeights.h
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user