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 "atomicSpecies.h"
|
||||
|
||||
namespace serif::atomic {
|
||||
namespace fourdst::atomic {
|
||||
struct Species {
|
||||
std::string m_name; //< Name of the species
|
||||
std::string m_el; //< Element symbol
|
||||
@@ -101,9 +101,9 @@ namespace serif::atomic {
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<serif::atomic::Species> {
|
||||
size_t operator()(const serif::atomic::Species& s) const noexcept {
|
||||
struct hash<fourdst::atomic::Species> {
|
||||
size_t operator()(const fourdst::atomic::Species& s) const noexcept {
|
||||
return std::hash<std::string>()(s.m_name);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
} // namespace std
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#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 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);
|
||||
|
||||
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')
|
||||
|
||||
subdir('mfem')
|
||||
subdir('yaml-cpp')
|
||||
subdir('quill')
|
||||
subdir('boost')
|
||||
subdir('opatIO')
|
||||
subdir('mpi')
|
||||
subdir('hypre')
|
||||
subdir('pybind')
|
||||
subdir('fourdst')
|
||||
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 = [
|
||||
probe_dep,
|
||||
quill_dep,
|
||||
species_weight_dep,
|
||||
const_dep,
|
||||
config_dep,
|
||||
log_dep
|
||||
]
|
||||
|
||||
# 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
|
||||
install_headers(composition_headers, subdir : 'SERiF/composition')
|
||||
install_headers(composition_headers, subdir : 'libcomposition/composition')
|
||||
|
||||
@@ -33,13 +33,13 @@
|
||||
#include "atomicSpecies.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) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -56,11 +56,11 @@ namespace serif::composition {
|
||||
if (m_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.");
|
||||
}
|
||||
m_symbol = symbol;
|
||||
m_isotope = serif::atomic::species.at(symbol);
|
||||
m_isotope = fourdst::atomic::species.at(symbol);
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace serif::composition {
|
||||
return m_relAbundance;
|
||||
}
|
||||
|
||||
serif::atomic::Species CompositionEntry::isotope() const {
|
||||
fourdst::atomic::Species CompositionEntry::isotope() const {
|
||||
return m_isotope;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ namespace serif::composition {
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -652,7 +652,7 @@ namespace serif::composition {
|
||||
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
|
||||
if (!m_finalized) {
|
||||
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||
@@ -696,4 +696,4 @@ namespace serif::composition {
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace serif::composition
|
||||
} // namespace fourdst::composition
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "probe.h"
|
||||
#include "config.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "atomicSpecies.h"
|
||||
|
||||
namespace serif::composition {
|
||||
namespace fourdst::composition {
|
||||
struct CanonicalComposition {
|
||||
double X = 0.0; ///< Mass fraction of Hydrogen.
|
||||
double Y = 0.0; ///< Mass fraction of Helium.
|
||||
@@ -63,7 +63,7 @@ namespace serif::composition {
|
||||
*/
|
||||
struct CompositionEntry {
|
||||
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.
|
||||
|
||||
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.
|
||||
* @return The isotope of the species.
|
||||
*/
|
||||
serif::atomic::Species isotope() const;
|
||||
fourdst::atomic::Species isotope() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the mode of the composition entry.
|
||||
@@ -215,8 +215,8 @@ namespace serif::composition {
|
||||
*/
|
||||
class Composition {
|
||||
private:
|
||||
serif::config::Config& m_config = serif::config::Config::getInstance();
|
||||
serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance();
|
||||
fourdst::config::Config& m_config = fourdst::config::Config::getInstance();
|
||||
fourdst::logging::LogManager& m_logManager = fourdst::logging::LogManager::getInstance();
|
||||
quill::Logger* m_logger = m_logManager.getLogger("log");
|
||||
|
||||
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 contains(const serif::atomic::Species& isotope) const;
|
||||
bool contains(const fourdst::atomic::Species& isotope) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the composition mode.
|
||||
@@ -508,4 +508,4 @@ namespace serif::composition {
|
||||
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.
|
||||
*/
|
||||
TEST_F(compositionTest, isotopeMasses) {
|
||||
EXPECT_NO_THROW(serif::atomic::species.at("H-1"));
|
||||
EXPECT_DOUBLE_EQ(serif::atomic::species.at("H-1").mass(), 1.007825031898);
|
||||
EXPECT_DOUBLE_EQ(serif::atomic::species.at("He-3").mass(), 3.0160293219700001);
|
||||
EXPECT_DOUBLE_EQ(serif::atomic::species.at("He-4").mass(),4.0026032541300003);
|
||||
EXPECT_NO_THROW(fourdst::atomic::species.at("H-1"));
|
||||
EXPECT_DOUBLE_EQ(fourdst::atomic::species.at("H-1").mass(), 1.007825031898);
|
||||
EXPECT_DOUBLE_EQ(fourdst::atomic::species.at("He-3").mass(), 3.0160293219700001);
|
||||
EXPECT_DOUBLE_EQ(fourdst::atomic::species.at("He-4").mass(),4.0026032541300003);
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, constructor) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
EXPECT_NO_THROW(serif::composition::Composition comp);
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
EXPECT_NO_THROW(fourdst::composition::Composition comp);
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, registerSymbol) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::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);
|
||||
@@ -46,8 +46,8 @@ TEST_F(compositionTest, registerSymbol) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, setGetComposition) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
|
||||
@@ -72,8 +72,8 @@ TEST_F(compositionTest, setGetComposition) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, setGetNumberFraction) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1", false);
|
||||
comp.registerSymbol("He-4", false);
|
||||
|
||||
@@ -89,8 +89,8 @@ TEST_F(compositionTest, setGetNumberFraction) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, subset) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
comp.setMassFraction("H-1", 0.6);
|
||||
@@ -98,14 +98,14 @@ TEST_F(compositionTest, subset) {
|
||||
EXPECT_NO_THROW(comp.finalize());
|
||||
|
||||
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_DOUBLE_EQ(subsetComp.getMassFraction("H-1"), 1.0);
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, finalizeWithNormalization) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
comp.setMassFraction("H-1", 0.3);
|
||||
@@ -116,8 +116,8 @@ TEST_F(compositionTest, finalizeWithNormalization) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, finalizeWithoutNormalization) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
comp.setMassFraction("H-1", 0.5);
|
||||
@@ -128,8 +128,8 @@ TEST_F(compositionTest, finalizeWithoutNormalization) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, getComposition) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
comp.setMassFraction("H-1", 0.6);
|
||||
@@ -143,8 +143,8 @@ TEST_F(compositionTest, getComposition) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, setCompositionMode) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
comp.setMassFraction("H-1", 0.6);
|
||||
@@ -165,8 +165,8 @@ TEST_F(compositionTest, setCompositionMode) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, hasSymbol) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::composition::Composition comp;
|
||||
comp.registerSymbol("H-1");
|
||||
comp.registerSymbol("He-4");
|
||||
comp.setMassFraction("H-1", 0.6);
|
||||
@@ -180,28 +180,28 @@ TEST_F(compositionTest, hasSymbol) {
|
||||
}
|
||||
|
||||
TEST_F(compositionTest, mix) {
|
||||
serif::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
serif::composition::Composition comp1;
|
||||
fourdst::config::Config::getInstance().loadConfig(EXAMPLE_FILENAME);
|
||||
fourdst::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());
|
||||
|
||||
serif::composition::Composition comp2;
|
||||
fourdst::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());
|
||||
|
||||
serif::composition::Composition mixedComp = comp1 + comp2;
|
||||
fourdst::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);
|
||||
|
||||
serif::composition::Composition mixedComp2 = comp1.mix(comp2, 0.25);
|
||||
fourdst::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);
|
||||
}
|
||||
}
|
||||
|
||||
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