refactor(serif): refactored entire codebase into serif and sub namespaces

This commit is contained in:
2025-06-11 14:49:11 -04:00
parent f0e1840c91
commit 6e4ff1ece9
56 changed files with 747 additions and 2041 deletions

View File

@@ -30,7 +30,7 @@
#include "atomicSpecies.h"
using namespace composition;
namespace serif::composition {
CompositionEntry::CompositionEntry() : m_symbol("H-1"), m_isotope(chemSpecies::species.at("H-1")), m_initialized(false) {}
@@ -547,10 +547,24 @@ Composition Composition::operator+(const Composition& other) const {
return mix(other, 0.5);
}
std::ostream& composition::operator<<(std::ostream& os, const Composition& composition) {
std::ostream& operator<<(std::ostream& os, const GlobalComposition& comp) {
os << "Global Composition: \n";
os << "\tSpecific Number Density: " << comp.specificNumberDensity << "\n";
os << "\tMean Particle Mass: " << comp.meanParticleMass << "\n";
return os;
}
std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry) {
os << "<" << entry.m_symbol << " : m_frac = " << entry.mass_fraction() << ">";
return os;
}
std::ostream& operator<<(std::ostream& os, const Composition& composition) {
os << "Composition: \n";
for (const auto& [symbol, entry] : composition.m_compositions) {
os << entry << "\n";
}
return os;
}
} // namespace serif::composition

View File

@@ -33,7 +33,7 @@
#include "atomicSpecies.h"
namespace composition{
namespace serif::composition {
/**
* @brief Represents the global composition of a system. This tends to be used after finalize and is primarily for internal use.
*/
@@ -42,12 +42,7 @@ namespace composition{
double meanParticleMass; ///< The mean particle mass of the composition (\sum_{i} \frac{n_i}{m_i}. where n_i is the number fraction of the ith species and m_i is the mass of the ith species).
// Overload the output stream operator for GlobalComposition
friend std::ostream& operator<<(std::ostream& os, const GlobalComposition& comp) {
os << "Global Composition: \n";
os << "\tSpecific Number Density: " << comp.specificNumberDensity << "\n";
os << "\tMean Particle Mass: " << comp.meanParticleMass << "\n";
return os;
}
friend std::ostream& operator<<(std::ostream& os, const GlobalComposition& comp);
};
/**
@@ -174,10 +169,7 @@ namespace composition{
* @param entry The CompositionEntry to output.
* @return The output stream.
*/
friend std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry) {
os << "<" << entry.m_symbol << " : m_frac = " << entry.mass_fraction() << ">";
return os;
}
friend std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry);
};
/**
@@ -210,8 +202,8 @@ namespace composition{
*/
class Composition {
private:
Config& m_config = Config::getInstance();
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
serif::config::Config& m_config = serif::config::Config::getInstance();
serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance();
quill::Logger* m_logger = m_logManager.getLogger("log");
bool m_finalized = false; ///< True if the composition is finalized.
@@ -471,6 +463,6 @@ namespace composition{
Composition operator+(const Composition& other) const;
};
};
}; // namespace serif::composition
#endif // COMPOSITION_H

View File

@@ -29,6 +29,9 @@
#include "config.h"
namespace serif {
namespace config {
Config::Config() {}
Config::~Config() {}
@@ -103,3 +106,6 @@ std::vector<std::string> Config::keys() const {
recurse_keys(node, keyList);
return keyList;
}
} // namespace config
} // namespace serif

View File

@@ -34,7 +34,11 @@
#include "yaml-cpp/yaml.h"
// -- Forward Def of Resource manager to let it act as a friend of Config --
class ResourceManager;
namespace serif { namespace resource { class ResourceManager; } } // Forward declaration
class configTestPrivateAccessor; // Forward declaration for test utility
namespace serif {
namespace config {
/**
* @class Config
@@ -230,9 +234,12 @@ public:
}
// Setup gTest class as a friend
friend class configTestPrivateAccessor;
friend class ::configTestPrivateAccessor; // Friend declaration for global test accessor
// -- Resource Manager is a friend of config so it can create a seperate instance
friend class ResourceManager;
friend class serif::resource::ResourceManager; // Adjusted friend declaration
};
} // namespace config
} // namespace serif
#endif

View File

@@ -1,124 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <set>
#include "const.h"
#include "embedded_constants.h" // Generated at build time by meson
Constants::Constants() {
loaded_ = initialize();
}
bool Constants::initialize() {
return load();
}
Constant Constants::get(const std::string& name) const {
auto it = constants_.find(name);
if (it != constants_.end()) {
return it->second;
} else {
throw std::out_of_range("Constant '" + name + "' not found.");
}
}
Constant Constants::operator[](const std::string& name) const {
return this->get(name);
}
bool Constants::has(const std::string& name) const {
return constants_.find(name) != constants_.end();
}
std::set<std::string> Constants::keys() const {
std::set<std::string> keys;
for (const auto& pair : constants_) {
keys.insert(pair.first);
}
return keys;
}
std::string Constants::trim(const std::string& str) {
size_t first = str.find_first_not_of(" \t");
if (first == std::string::npos) return "";
size_t last = str.find_last_not_of(" \t");
return str.substr(first, last - first + 1);
}
bool Constants::load() {
std::istringstream fileStream(embeddedConstants);
std::string line;
bool data_section = false;
int line_count = 0;
while (std::getline(fileStream, line)) {
line_count++;
// Detect start of data section (double divider line)
if (!data_section) {
if (line.find("Symbol") != std::string::npos) { // Find header row
std::getline(fileStream, line); // Skip dashed divider
std::getline(fileStream, line); // Skip second dashed divider
data_section = true;
}
continue;
}
// Ensure the line is long enough to contain all fields
if (line.length() < 125) continue;
// Define exact column widths from Python script
int start = 0;
const std::string symbol = trim(line.substr(start, col_widths_[0])); start += col_widths_[0];
const std::string name = trim(line.substr(start, col_widths_[1])); start += col_widths_[1];
const std::string valueStr = line.substr(start, col_widths_[2]); start += col_widths_[2];
const std::string unit = trim(line.substr(start, col_widths_[3])); start += col_widths_[3]; // Only trim the unit
const std::string uncertaintyStr = line.substr(start, col_widths_[4]); start += col_widths_[4];
const std::string reference = trim(line.substr(start, col_widths_[5])); // Only trim reference
// Convert numerical fields safely
double value = 0.0, uncertainty = 0.0;
try {
value = std::stod(valueStr);
} catch (...) {
std::cerr << "Warning: Invalid value in line " << line_count << ": " << valueStr << std::endl;
}
try {
uncertainty = std::stod(uncertaintyStr);
} catch (...) {
std::cerr << "Warning: Invalid uncertainty in line " << line_count << ": " << uncertaintyStr << std::endl;
}
// Store in map
constants_.emplace(symbol, Constant{name, value, uncertainty, unit, reference});
}
loaded_ = true;
return true;
}

View File

@@ -0,0 +1,126 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <set>
#include "const.h"
#include "embedded_constants.h" // Generated at build time by meson
namespace serif::constant {
Constants::Constants() {
loaded_ = initialize();
}
bool Constants::initialize() {
return load();
}
Constant Constants::get(const std::string& name) const {
auto it = constants_.find(name);
if (it != constants_.end()) {
return it->second;
} else {
throw std::out_of_range("Constant '" + name + "' not found.");
}
}
Constant Constants::operator[](const std::string& name) const {
return this->get(name);
}
bool Constants::has(const std::string& name) const {
return constants_.find(name) != constants_.end();
}
std::set<std::string> Constants::keys() const {
std::set<std::string> keys;
for (const auto& pair : constants_) {
keys.insert(pair.first);
}
return keys;
}
std::string Constants::trim(const std::string& str) {
size_t first = str.find_first_not_of(" \t");
if (first == std::string::npos) return "";
size_t last = str.find_last_not_of(" \t");
return str.substr(first, last - first + 1);
}
bool Constants::load() {
std::istringstream fileStream(embeddedConstants);
std::string line;
bool data_section = false;
int line_count = 0;
while (std::getline(fileStream, line)) {
line_count++;
// Detect start of data section (double divider line)
if (!data_section) {
if (line.find("Symbol") != std::string::npos) { // Find header row
std::getline(fileStream, line); // Skip dashed divider
std::getline(fileStream, line); // Skip second dashed divider
data_section = true;
}
continue;
}
// Ensure the line is long enough to contain all fields
if (line.length() < 125) continue;
// Define exact column widths from Python script
int start = 0;
const std::string symbol = trim(line.substr(start, col_widths_[0])); start += col_widths_[0];
const std::string name = trim(line.substr(start, col_widths_[1])); start += col_widths_[1];
const std::string valueStr = line.substr(start, col_widths_[2]); start += col_widths_[2];
const std::string unit = trim(line.substr(start, col_widths_[3])); start += col_widths_[3]; // Only trim the unit
const std::string uncertaintyStr = line.substr(start, col_widths_[4]); start += col_widths_[4];
const std::string reference = trim(line.substr(start, col_widths_[5])); // Only trim reference
// Convert numerical fields safely
double value = 0.0, uncertainty = 0.0;
try {
value = std::stod(valueStr);
} catch (...) {
std::cerr << "Warning: Invalid value in line " << line_count << ": " << valueStr << std::endl;
}
try {
uncertainty = std::stod(uncertaintyStr);
} catch (...) {
std::cerr << "Warning: Invalid uncertainty in line " << line_count << ": " << uncertaintyStr << std::endl;
}
// Store in map
constants_.emplace(symbol, Constant{name, value, uncertainty, unit, reference});
}
loaded_ = true;
return true;
}
}

View File

@@ -18,9 +18,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// *********************************************************************** */
#ifndef CONST_H
#define CONST_H
#pragma once
#include <string>
#include <fstream>
#include <iostream>
@@ -28,6 +26,7 @@
#include <set>
#include <map>
namespace serif::constant {
/**
* @brief Structure to hold a constant's details.
*/
@@ -140,4 +139,5 @@ public:
};
#endif
} // namespace serif::const

View File

@@ -1,22 +0,0 @@
# Define the library
dobj_sources = files(
'private/Metadata.cpp',
'private/DObject.cpp',
'private/LockableDObject.cpp'
)
dobj_headers = files(
'public/Metadata.h',
'public/DObject.h',
'public/LockableDObject.h'
)
# Define the libdobj library so it can be linked against by other parts of the build system
libdobj = library('dobj',
dobj_sources,
include_directories: include_directories('public'),
cpp_args: ['-fvisibility=default'],
install : true)
# Make headers accessible
install_headers(dobj_headers, subdir : '4DSSE/dobj')

View File

@@ -1,239 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#include "DObject.h"
#include <iostream>
#include <stdexcept>
/**
* @file DObject.cpp
* @brief Implementation of the DObject class.
*
* Provides the implementation for a universal data container with plugin support.
*/
// Default constructor
DObject::DObject() : data_(std::monostate()), debugEnabled_(false) {
// The data is initialized to an empty state using std::monostate (a variant placeholder).
}
/**
* @brief Constructor to initialize a DObject with data.
*/
DObject::DObject(const DataType& data)
: data_(data), debugEnabled_(false) {}
/**
* @brief Retrieves the data stored in the DObject.
*/
const DObject::DataType& DObject::getData() const noexcept {
return data_;
}
/**
* @brief Sets the data for the DObject.
*/
void DObject::setData(const DataType& data) {
data_ = data;
}
/**
* @brief Enables or disables debugging and tracing for the DObject.
*/
void DObject::setDebugging(bool enableDebug) {
debugEnabled_ = enableDebug;
}
/**
* @brief Checks if debugging is enabled for the DObject.
*/
bool DObject::isDebuggingEnabled() const noexcept {
return debugEnabled_;
}
/**
* @breif Sets an error code and returns the old one
*/
int DObject::setErrorCode(int code) noexcept {
int oldCode = errorCode_;
errorCode_ = code;
return oldCode;
}
int DObject::getErrorCode() const noexcept {
return errorCode_;
}
/**
* @brief Registers a plugin with the DObject.
*/
void DObject::registerPlugin(const std::string& id, Plugin plugin) {
if (plugins_.find(id) != plugins_.end()) {
throw std::runtime_error("Plugin with ID '" + id + "' already exists.");
}
plugins_[id] = std::move(plugin);
}
/**
* @brief Unregisters a plugin by its identifier.
*/
void DObject::unregisterPlugin(const std::string& id) {
if (plugins_.erase(id) == 0) {
throw std::runtime_error("Plugin with ID '" + id + "' not found.");
}
}
/**
* @brief Executes a plugin by its identifier.
*/
void DObject::runPlugin(const std::string& id) {
auto it = plugins_.find(id);
if (it == plugins_.end()) {
throw std::runtime_error("Plugin with ID '" + id + "' not found.");
}
it->second(*this); // Invoke the plugin, passing this DObject as a reference.
}
/**
* @brief Executes all registered plugins in the registry.
*/
void DObject::runAllPlugins() {
for (auto& [id, plugin] : plugins_) {
plugin(*this); // Invoke each plugin, passing this DObject as a reference.
}
}
/**
* @brief Provides a human-readable summary of the DObject.
*/
std::ostream& operator<<(std::ostream& os, const DObject& obj) {
os << "DObject Summary:\n";
os << " Debugging Enabled: " << (obj.debugEnabled_ ? "Yes" : "No") << "\n";
os << " Data: ";
std::visit([&os](const auto& value) {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, std::monostate>) {
os << "EMPTY";
} else if constexpr (std::is_same_v<T, int>) {
os << value;
} else if constexpr (std::is_same_v<T, float>) {
os << value;
} else if constexpr (std::is_same_v<T, double>) {
os << value;
} else if constexpr (std::is_same_v<T, std::string>) {
os << value;
} else if constexpr (std::is_same_v<T, std::vector<int>>) {
os << "[";
for (const auto& elem : value) {
os << elem << ", ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<float>>) {
os << "[";
for (const auto& elem : value) {
os << elem << ", ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<double>>) {
os << "[";
for (const auto& elem : value) {
os << elem << ", ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<std::vector<int>>>) {
os << "\n[";
for (const auto& row : value) {
os << "[";
for (const auto& elem : row) {
os << elem << ", ";
}
os << "], ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<std::vector<float>>>) {
os << "\n[";
for (const auto& row : value) {
os << "[";
for (const auto& elem : row) {
os << elem << ", ";
}
os << "], ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<std::vector<double>>>) {
os << "\n[";
for (const auto& row : value) {
os << "[";
for (const auto& elem : row) {
os << elem << ", ";
}
os << "], ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<std::vector<std::vector<int>>>>) {
os << "\n[";
for (const auto& plane : value) {
os << "[";
for (const auto& row : plane) {
os << "[";
for (const auto& elem : row) {
os << elem << ", ";
}
os << "], ";
}
os << "], ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<std::vector<std::vector<float>>>>) {
os << "\n[";
for (const auto& plane : value) {
os << "[";
for (const auto& row : plane) {
os << "[";
for (const auto& elem : row) {
os << elem << ", ";
}
os << "], ";
}
os << "], ";
}
os << "]";
} else if constexpr (std::is_same_v<T, std::vector<std::vector<std::vector<double>>>>) {
os << "\n[";
for (const auto& plane : value) {
os << "[";
for (const auto& row : plane) {
os << "[";
for (const auto& elem : row) {
os << elem << ", ";
}
os << "], ";
}
os << "], ";
}
os << "]";
} else {
os << "UNKNOWN";
}
}, obj.data_);
os << "\n Data Type: " << obj.dataTypeMap.at(obj.data_.index());
os << "\n Plugins Registered: " << obj.plugins_.size() << "\n";
return os;
}

View File

@@ -1,42 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#include "LockableDObject.h"
/**
* @brief Access the underlying DObject.
*/
DObject& LockableDObject::get() {
return object_;
}
/**
* @brief Locks the mutex to ensure thread-safe access.
*/
void LockableDObject::lock() {
mutex_.lock();
}
/**
* @brief Unlocks the mutex after thread-safe access.
*/
void LockableDObject::unlock() {
mutex_.unlock();
}

View File

@@ -1,158 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#include "Metadata.h"
/**
* @file Metadata.cpp
* @brief Implementation of the Metadata class used in the dobj module.
*
* Provides methods to manage metadata for data objects, including size, type,
* dimensions, and debugging flags.
*/
/**
* @brief Constructor to initialize Metadata with specific attributes.
*
* @param byteSize The total size of the data in bytes.
* @param dataType The type of the data (e.g., "float", "double").
* @param dimensions A vector representing the size of each dimension (e.g., {3, 4} for a 3x4 matrix).
* @param debugFlag Whether debugging information is enabled for this Metadata instance.
*/
Metadata::Metadata(std::size_t byteSize, std::string dataType, std::vector<std::size_t> dimensions, bool debugFlag)
: byteSize_(byteSize), dataType_(std::move(dataType)), dimensions_(std::move(dimensions)), debugFlag_(debugFlag) {}
/**
* @brief Gets the total size of the data in bytes.
*
* The size is often required for memory allocation and validation in numerical routines.
*
* @return The total byte size of the data.
*/
std::size_t Metadata::getByteSize() const noexcept {
return byteSize_;
}
/**
* @brief Sets the total size of the data in bytes.
*
* It's important to ensure this matches the actual data size in memory to prevent overflows
* or incorrect computations downstream.
*
* @param byteSize The total byte size to set.
*/
void Metadata::setByteSize(std::size_t byteSize) noexcept {
byteSize_ = byteSize;
}
/**
* @brief Gets the type of the data.
*
* The type (e.g., "float", "double") is critical for casting raw data or interfacing with libraries
* that require specific types.
*
* @return A string representing the data type.
*/
const std::string& Metadata::getDataType() const noexcept {
return dataType_;
}
/**
* @brief Sets the type of the data.
*
* When setting the data type, ensure it aligns with the underlying data representation.
* Mismatched types can lead to undefined behavior in numerical calculations.
*
* @param dataType A string representing the data type.
*/
void Metadata::setDataType(const std::string& dataType) {
dataType_ = dataType;
}
/**
* @brief Gets the dimensions of the data.
*
* Dimensions define the shape of the data (e.g., 2D arrays, 3D matrices). This is essential
* for ensuring that operations (e.g., matrix multiplication) are performed correctly.
*
* @return A vector representing the size of each dimension.
*/
const std::vector<std::size_t>& Metadata::getDimensions() const noexcept {
return dimensions_;
}
/**
* @brief Sets the dimensions of the data.
*
* When modifying dimensions, verify that they are consistent with the actual data representation.
*
* @param dimensions A vector representing the size of each dimension.
*/
void Metadata::setDimensions(const std::vector<std::size_t>& dimensions) {
dimensions_ = dimensions;
}
/**
* @brief Checks if debugging information is enabled.
*
* Debugging flags can be useful for tracking performance metrics or error provenance.
*
* @return True if debugging is enabled, false otherwise.
*/
bool Metadata::isDebugEnabled() const noexcept {
return debugFlag_;
}
/**
* @brief Sets the debugging flag.
*
* Enabling debugging can introduce performance overhead but provides valuable insights
* during development or testing.
*
* @param debugFlag Whether debugging is enabled.
*/
void Metadata::setDebugEnabled(bool debugFlag) noexcept {
debugFlag_ = debugFlag;
}
/**
* @brief Prints the metadata information for debugging purposes.
*
* This function provides a human-readable summary of the metadata. Useful for quick checks
* or logging during debugging sessions.
*
* @param os The output stream to print to.
* @param metadata The Metadata object to print.
* @return A reference to the output stream.
*/
std::ostream& operator<<(std::ostream& os, const Metadata& metadata) {
os << "Metadata Information:\n";
os << " Byte Size: " << metadata.byteSize_ << " bytes\n";
os << " Data Type: " << metadata.dataType_ << "\n";
os << " Dimensions: [";
for (size_t i = 0; i < metadata.dimensions_.size(); ++i) {
os << metadata.dimensions_[i];
if (i < metadata.dimensions_.size() - 1) os << ", ";
}
os << "]\n";
os << " Debug Enabled: " << (metadata.debugFlag_ ? "Yes" : "No") << "\n";
return os;
}

View File

@@ -1,257 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#ifndef DOBJECT_H
#define DOBJECT_H
#include <variant>
#include <memory>
#include <vector>
#include <string>
#include <mutex>
#include <map>
#include <functional>
/**
* @file DObject.h
* @brief Defines the DObject class, a universal data container for the project.
*
* The DObject class encapsulates arbitrary data and its associated metadata,
* providing a consistent interface for public-facing functions. It includes
* support for dynamically registered plugins.
*/
/**
* @class DObject
* @brief A universal data container class.
*
* The DObject class is designed to store arbitrary data alongside descriptive metadata.
* It supports plugin registration to allow extensible functionality.
*
* The general purpose of this is to simplify memory managment, function interfaces,
* and interoperability with other languages by wrapping all of that up inside of
* one location (DObject). There are still a limited number of types that DOBject can
* represent these include
* - bool
* - short int
* - int
* - long int
* - float
* - double
* - long double
* - std::string
* - std::monostate
* - std::vector<int>
* - std::vector<float>
* - std::vector<double>
* - std::vector<std::string>
* - std::vector<std::vector<int>>
* - std::vector<std::vector<float>>
* - std::vector<std::vector<double>>
* - std::vector<std::vector<std::vector<int>>>
* - std::vector<std::vector<std::vector<float>>>
* - std::vector<std::vector<std::vector<double>>
*
*
* If more types are needed, they can be added to the DataType variant.
*
* In general the usage of this might look like
* @code
* DObject obj;
* std::vector<int> data = {1, 2, 3, 4, 5};
* obj.setData(data);
* std::cout << "Data is " << obj << std::end;
* someFunction(&obj);
* @endcode
*
* All memory managment should be taken care of
* as all datatypes accepted by the varient are either primatives or
* include their own built in memory managment (i.e. this means that
* wherever possible vectors should be used in place of raw arrays).
*/
class DObject {
public:
/**
* @brief Supported data types for the DObject.
*
* This type alias uses `std::variant` to store different types of data,
* ensuring type safety and flexibility.
*/
using DataType = std::variant<
bool, short int, int, long int, float, double,
long double, std::string, std::monostate, std::vector<int>,
std::vector<float>, std::vector<double>, std::vector<std::string>,
std::vector<std::vector<int>>, std::vector<std::vector<float>>,
std::vector<std::vector<double>>,
std::vector<std::vector<std::vector<int>>>,
std::vector<std::vector<std::vector<float>>>,
std::vector<std::vector<std::vector<double>>>
>;
// Mapping of data types to their string representations
std::map<int, std::string> dataTypeMap = {
{0, "bool"}, {1, "short int"}, {2, "int"}, {3, "long int"}, {4, "float"},
{5, "double"}, {6, "long double"}, {7, "string"}, {8, "std::monostate"},
{9, "vector<int>"}, {10, "vector<float>"}, {11, "vector<double>"},
{12, "vector<string>"}, {13, "vector<vector<int>"},
{14, "vector<vector<float>"}, {15, "vector<vector<double>"},
{16, "vector<vector<vector<int>>"}, {17, "vector<vector<vector<float>>"},
{18, "vector<vector<vector<double>>"}
};
/**
* @brief Placeholder type for plugins.
*
* In the future, this will be replaced with a concrete interface.
*/
using Plugin = std::function<void(DObject&)>;
/**
* @brief Default constructor.
*
* Creates an empty DObject.
*/
DObject();
/**
* @brief Constructor to initialize a DObject with data.
*
* @param data The data to be stored in the DObject.
*/
DObject(const DataType& data);
/**
* @brief Retrieves the data stored in the DObject.
*
* Use the appropriate type (matching the stored data) with `std::get<T>()`.
*
* @return A constant reference to the stored data.
*/
const DataType& getData() const noexcept;
/**
* @brief Retrieves the data stored in the DObject as a typed object so that std::get<T>() is not needed.
*
* @return Data as type T
*/
template <typename T>
T getDataAs() const {
if (std::holds_alternative<T>(data_)) {
return std::get<T>(data_);
} else {
throw std::bad_variant_access();
}
}
/**
* @brief Sets the data for the DObject.
*
* Updates the stored data and optionally updates metadata.
*
* @param data The new data to store in the DObject.
*/
void setData(const DataType& data);
/**
* @brief Enables or disables debugging and tracing for the DObject.
*
* When debugging is enabled, the DObject tracks creation and modification history.
*
* @param enableDebug True to enable debugging, false to disable it.
*/
void setDebugging(bool enableDebug);
/**
* @brief Checks if debugging is enabled for the DObject.
*
* @return True if debugging is enabled, false otherwise.
*/
bool isDebuggingEnabled() const noexcept;
/**
* @breif Set error code tracked by the DOBject
*
* @return The previous error code
*/
int setErrorCode(int code) noexcept;
/**
* @brief Get the error code tracked by the DObject
*
* @return The error code
*/
int getErrorCode() const noexcept;
/**
* @brief Registers a plugin with the DObject.
*
* Plugins are stored in a registry and can add custom functionality to the DObject.
*
* @param id A unique identifier for the plugin.
* @param plugin The plugin function to register.
*/
void registerPlugin(const std::string& id, Plugin plugin);
/**
* @brief Unregisters a plugin by its identifier.
*
* Removes the plugin from the registry if it exists.
*
* @param id The unique identifier of the plugin to unregister.
*/
void unregisterPlugin(const std::string& id);
/**
* @brief Executes a plugin by its identifier.
*
* Invokes the registered plugin function. If the plugin is not found, no action is taken.
*
* @param id The unique identifier of the plugin to execute.
*/
void runPlugin(const std::string& id);
/**
* @brief Executes all registered plugins in the registry.
*
* Iterates through all plugins and invokes them on the current DObject.
*/
void runAllPlugins();
/**
* @brief Provides a human-readable summary of the DObject.
*
* Useful for quick inspection or logging during debugging sessions.
*
* @param os The output stream to write to.
* @param obj The DObject to summarize.
* @return A reference to the output stream.
*/
friend std::ostream& operator<<(std::ostream& os, const DObject& obj);
private:
DataType data_; ///< The main data stored in the DObject.
bool debugEnabled_ = false; ///< Indicates whether debugging is enabled.
int errorCode_ = 0; ///< Error code tracked by the DObject.
std::map<std::string, Plugin> plugins_; ///< Registry for dynamically registered plugins.
};
#endif // DOBJECT_H

View File

@@ -1,67 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#ifndef LOCKABLE_DOBJECT_H
#define LOCKABLE_DOBJECT_H
#include "DObject.h"
#include <mutex>
/**
* @file LockableDObject.h
* @brief A lightweight wrapper for DObject that adds locking capabilities.
*
* This class allows safe concurrent access to a DObject by providing
* locking and unlocking methods.
*/
/**
* @class LockableDObject
* @brief Wrapper for DObject with thread-safe access.
*/
class LockableDObject {
public:
/**
* @brief Default constructor.
*/
LockableDObject() = default;
/**
* @brief Access the underlying DObject.
* @return A reference to the wrapped DObject.
*/
DObject& get();
/**
* @brief Locks the mutex to ensure thread-safe access.
*/
void lock();
/**
* @brief Unlocks the mutex after thread-safe access.
*/
void unlock();
private:
DObject object_; ///< The underlying DObject instance.
std::mutex mutex_; ///< Mutex for thread-safe access.
};
#endif // LOCKABLE_DOBJECT_H

View File

@@ -1,132 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#ifndef METADATA_H
#define METADATA_H
#if defined(__APPLE__) || defined(__linux__)
#define EXPORT_SYMBOL __attribute__((visibility("default")))
#else
#define EXPORT_SYMBOL
#endif
#include <string>
#include <vector>
#include <cstddef>
#include <iostream>
/**
* @file Metadata.h
* @brief Public interface for the Metadata class used in the dobj module.
*
* The Metadata class provides descriptive information about the data encapsulated
* within a dobj, including size, type, dimensions, and debugging flags.
*/
/**
* @class Metadata
* @brief Represents metadata information for data objects in the dobj module.
*
* The Metadata class encapsulates details such as data size, type, dimensions,
* and optional debugging flags. It is designed to provide descriptive attributes
* in a lightweight and efficient manner.
*/
class EXPORT_SYMBOL Metadata {
public:
/**
* @brief Default constructor for Metadata.
*/
Metadata() = default;
/**
* @brief Constructor to initialize Metadata with specific attributes.
*
* @param byteSize The total size of the data in bytes.
* @param dataType The type of the data (e.g., "float", "double").
* @param dimensions A vector representing the size of each dimension (e.g., {3, 4} for a 3x4 matrix).
* @param debugFlag Whether debugging information is enabled for this Metadata instance.
*/
Metadata(std::size_t byteSize, std::string dataType, std::vector<std::size_t> dimensions, bool debugFlag = false);
/**
* @brief Gets the total size of the data in bytes.
* @return The total byte size of the data.
*/
[[nodiscard]] std::size_t getByteSize() const noexcept;
/**
* @brief Sets the total size of the data in bytes.
* @param byteSize The total byte size to set.
*/
void setByteSize(std::size_t byteSize) noexcept;
/**
* @brief Gets the type of the data.
* @return A string representing the data type.
*/
[[nodiscard]] const std::string& getDataType() const noexcept;
/**
* @brief Sets the type of the data.
* @param dataType A string representing the data type.
*/
void setDataType(const std::string& dataType);
/**
* @brief Gets the dimensions of the data.
* @return A vector representing the size of each dimension.
*/
[[nodiscard]] const std::vector<std::size_t>& getDimensions() const noexcept;
/**
* @brief Sets the dimensions of the data.
* @param dimensions A vector representing the size of each dimension.
*/
void setDimensions(const std::vector<std::size_t>& dimensions);
/**
* @brief Checks if debugging information is enabled.
* @return True if debugging is enabled, false otherwise.
*/
[[nodiscard]] bool isDebugEnabled() const noexcept;
/**
* @brief Sets the debugging flag.
* @param debugFlag Whether debugging is enabled.
*/
void setDebugEnabled(bool debugFlag) noexcept;
/**
* @brief Prints the metadata information for debugging purposes.
*
* @param os The output stream to print to.
* @param metadata The Metadata object to print.
* @return A reference to the output stream.
*/
friend std::ostream& operator<<(std::ostream& os, const Metadata& metadata);
private:
int byteSize_ = 0; ///< Total size of the data in bytes.
std::string dataType_; ///< Type of the data (e.g., "float", "double").
std::vector<std::size_t> dimensions_; ///< Dimensions of the data (e.g., {3, 4} for a 3x4 matrix).
bool debugFlag_ = false; ///< Indicates whether debugging is enabled.
};
#endif // METADATA_H

View File

@@ -24,6 +24,9 @@
#include "helm.h"
#include "debug.h"
#include <string>
namespace serif::eos {
EosIO::EosIO(const std::string filename) : m_filename(filename) {
load();
}
@@ -49,8 +52,8 @@ void EosIO::load() {
void EosIO::loadHelm() {
// Load the HELM table from the file
auto helmTabptr = helmholtz::read_helm_table(m_filename);
auto helmTabptr = serif::eos::helmholtz::read_helm_table(m_filename);
m_table = std::move(helmTabptr);
m_loaded = true;
}
}

View File

@@ -43,6 +43,8 @@
using namespace std;
// interpolating polynomila function definitions
namespace serif::eos::helmholtz {
double** heap_allocate_contiguous_2D_memory(int rows, int cols) {
double **array = new double*[rows];
array[0] = new double[rows * cols];
@@ -58,8 +60,6 @@ void heap_deallocate_contiguous_2D_memory(double **array) {
delete[] array[0];
delete[] array;
}
// interpolating polynomila function definitions
namespace helmholtz {
double psi0(double z) { return z*z*z * (z * (-6.0 * z + 15.0) - 10.0) + 1.0; }
double dpsi0(double z) { return z*z * ( z * (-30.0 * z + 60.0) - 30.0); }
@@ -123,14 +123,14 @@ namespace helmholtz {
// this function reads in the HELM table and stores in the above arrays
std::unique_ptr<HELMTable> read_helm_table(const std::string filename) {
Config& config = Config::getInstance();
serif::config::Config& config = serif::config::Config::getInstance();
std::string logFile = config.get<std::string>("EOS:Helm:LogFile", "log");
Probe::LogManager& logManager = Probe::LogManager::getInstance();
serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance();
quill::Logger* logger = logManager.getLogger(logFile);
LOG_INFO(logger, "read_helm_table : Reading HELM table from file {}", filename);
// Make a unique pointer to the HELMTable
std::unique_ptr<HELMTable> table = std::make_unique<HELMTable>();
std::unique_ptr<serif::eos::helmholtz::HELMTable> table = std::make_unique<serif::eos::helmholtz::HELMTable>();
string data;
int i, j;
@@ -233,13 +233,13 @@ namespace helmholtz {
ion, radiation, electron-positron and Coulomb interaction
and returns the calculated quantities in the input
***/
EOS get_helm_EOS(EOSInput &q, const HELMTable &table) {
Config& config = Config::getInstance();
serif::eos::helmholtz::EOS get_helm_EOS(serif::eos::helmholtz::EOSInput &q, const serif::eos::helmholtz::HELMTable &table) {
serif::config::Config& config = serif::config::Config::getInstance();
std::string logFile = config.get<std::string>("EOS:Helm:LogFile", "log");
Probe::LogManager& logManager = Probe::LogManager::getInstance();
serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance();
quill::Logger* logger = logManager.getLogger(logFile);
Constants& constants = Constants::getInstance();
serif::constant::Constants& constants = serif::constant::Constants::getInstance();
const double pi = std::numbers::pi;
const double amu = constants.get("u").value;
const double h = constants.get("h").value;
@@ -822,7 +822,7 @@ namespace helmholtz {
double csound = clight * sqrt(gamma1/z);
// package in q:
EOS eos;
serif::eos::helmholtz::EOS eos;
eos.ptot = ptot; eos.etot = etot; eos.stot = stot;
eos.pgas = pgas; eos.egas = egas; eos.sgas = sgas;
eos.prad = prad; eos.erad = erad; eos.srad = srad;

View File

@@ -18,18 +18,18 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// *********************************************************************** */
#ifndef EOSIO_H
#define EOSIO_H
#pragma once
#include <string>
#include <variant>
#include <memory>
// EOS table format includes
#include "helm.h"
namespace serif::eos {
// EOS table format includes
using EOSTable = std::variant<
std::unique_ptr<helmholtz::HELMTable>
std::unique_ptr<serif::eos::helmholtz::HELMTable>
>;
/**
@@ -86,5 +86,4 @@ public:
*/
EOSTable& getTable();
};
#endif // EOSIO_H
}

View File

@@ -22,11 +22,8 @@
// helmholtz.f90, which implements the Helmholtz Free Energy EOS described
// by Timmes & Swesty (2000) doi:10.1086/313304 -- Aaron Dotter 2025
#ifndef HELM_H
#define HELM_H
#pragma once
#define IMAX 541
#define JMAX 201
#include <array>
#include <iostream>
@@ -37,6 +34,9 @@
#include "debug.h"
namespace serif::eos::helmholtz {
constexpr int IMAX = 541;
constexpr int JMAX = 201;
/**
* @brief 2D array template alias.
* @tparam T Type of the array elements.
@@ -50,8 +50,6 @@ double** heap_allocate_contiguous_2D_memory(int rows, int cols);
void heap_deallocate_contiguous_2D_memory(double **array);
namespace helmholtz
{
const double tlo = 3.0, thi = 13.0;
const double dlo = -12.0, dhi = 15.0;
const double tstp = (thi - tlo) / (JMAX - 1), tstpi = 1 / tstp;
@@ -497,4 +495,3 @@ namespace helmholtz
}
#endif // HELM_H

View File

@@ -26,7 +26,7 @@
#include "meshIO.h"
namespace serif::mesh {
MeshIO::MeshIO(const std::string &mesh_file, double scale_factor)
{
mesh_file_ = mesh_file;
@@ -79,3 +79,4 @@ bool MeshIO::IsLoaded() const
mfem::Mesh &MeshIO::GetMesh() const noexcept {
return *m_mesh;
}
}

View File

@@ -23,6 +23,7 @@
#include "mfem.hpp"
#include <string>
namespace serif::mesh {
/**
* @brief Class for handling mesh input/output operations.
*/
@@ -64,3 +65,4 @@ public:
*/
[[nodiscard]] bool IsLoaded() const;
};
}

View File

@@ -7,10 +7,9 @@ subdir('types')
subdir('misc')
subdir('config')
subdir('probe')
subdir('dobj')
# Physically Informed Libraries
subdir('const')
subdir('constants')
subdir('composition')
# Asset Libraries
@@ -22,4 +21,4 @@ subdir('resource')
# Physics Libraries
subdir('network')
subdir('poly')
subdir('polytrope')

View File

@@ -30,6 +30,7 @@
* BREAKPOINT(); // Triggers a breakpoint in the debugger
* @endcode
*/
#pragma once
#ifdef __GNUC__ // GCC and Clang
/**

View File

@@ -18,9 +18,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// *********************************************************************** */
#ifndef WARNING_CONTROL_H
#define WARNING_CONTROL_H
#pragma once
#if defined(__GNUC__) || defined(__clang__)
#define DEPRECATION_WARNING_OFF _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
@@ -32,5 +30,3 @@
#define DEPRECATION_WARNING_OFF
#define DEPRECATION_WARNING_ON
#endif
#endif // WARNING_CONTROL_H

View File

@@ -72,7 +72,7 @@ The coefficients to the fit are from reaclib.jinaweb.org .
*/
namespace nnApprox8{
namespace serif::network::approx8{
// using namespace std;
using namespace boost::numeric::odeint;
@@ -245,7 +245,7 @@ namespace nnApprox8{
// a Jacobian matrix for implicit solvers
void Jacobian::operator() ( const vector_type &y, matrix_type &J, double /* t */, vector_type &dfdt ) {
Constants& constants = Constants::getInstance();
serif::constant::Constants& constants = serif::constant::Constants::getInstance();
const double avo = constants.get("N_a").value;
const double clight = constants.get("c").value;
// EOS
@@ -350,7 +350,7 @@ namespace nnApprox8{
}
void ODE::operator() ( const vector_type &y, vector_type &dydt, double /* t */) {
Constants& constants = Constants::getInstance();
serif::constant::Constants& constants = serif::constant::Constants::getInstance();
const double avo = constants.get("N_a").value;
const double clight = constants.get("c").value;
@@ -444,7 +444,7 @@ namespace nnApprox8{
dydt[Net::iener] = -enuc*avo*clight*clight;
}
nuclearNetwork::NetOut Approx8Network::evaluate(const nuclearNetwork::NetIn &netIn) {
NetOut Approx8Network::evaluate(const NetIn &netIn) {
m_y = convert_netIn(netIn);
m_tmax = netIn.tmax;
m_dt0 = netIn.dt0;
@@ -488,7 +488,7 @@ namespace nnApprox8{
m_y[i] /= ysum;
}
nuclearNetwork::NetOut netOut;
NetOut netOut;
std::vector<double> outComposition;
outComposition.reserve(Net::nvar);
@@ -506,7 +506,7 @@ namespace nnApprox8{
m_stiff = stiff;
}
vector_type Approx8Network::convert_netIn(const nuclearNetwork::NetIn &netIn) {
vector_type Approx8Network::convert_netIn(const NetIn &netIn) {
if (netIn.composition.size() != Net::niso) {
LOG_ERROR(m_logger, "Error: composition size mismatch in convert_netIn");
throw std::runtime_error("Error: composition size mismatch in convert_netIn");

View File

@@ -22,13 +22,13 @@
#include "probe.h"
#include "quill/LogMacros.h"
namespace nuclearNetwork {
namespace serif::network {
Network::Network() :
m_config(Config::getInstance()),
m_logManager(Probe::LogManager::getInstance()),
m_config(serif::config::Config::getInstance()),
m_logManager(serif::probe::LogManager::getInstance()),
m_logger(m_logManager.getLogger("log")) {
}
nuclearNetwork::NetOut nuclearNetwork::Network::evaluate(const NetIn &netIn) {
NetOut Network::evaluate(const NetIn &netIn) {
// You can throw an exception here or log a warning if it should never be used.
LOG_ERROR(m_logger, "nuclearNetwork::Network::evaluate() is not implemented");
throw std::runtime_error("nuclearNetwork::Network::evaluate() is not implemented");

View File

@@ -53,7 +53,7 @@ typedef boost::numeric::ublas::matrix< double > matrix_type;
*/
typedef std::array<double,7> vec7;
namespace nnApprox8{
namespace serif::network::approx8{
using namespace boost::numeric::odeint;
@@ -294,14 +294,14 @@ namespace nnApprox8{
* @class Approx8Network
* @brief Class for the Approx8 nuclear reaction network.
*/
class Approx8Network : public nuclearNetwork::Network {
class Approx8Network : public Network {
public:
/**
* @brief Evaluates the nuclear network.
* @param netIn Input parameters for the network.
* @return Output results from the network.
*/
virtual nuclearNetwork::NetOut evaluate(const nuclearNetwork::NetIn &netIn);
virtual NetOut evaluate(const NetIn &netIn);
/**
* @brief Sets whether the solver should use a stiff method.
@@ -325,7 +325,7 @@ namespace nnApprox8{
* @param netIn Input parameters for the network.
* @return Internal state vector.
*/
vector_type convert_netIn(const nuclearNetwork::NetIn &netIn);
vector_type convert_netIn(const NetIn &netIn);
};
} // namespace nnApprox8

View File

@@ -26,7 +26,7 @@
#include "config.h"
#include "quill/Logger.h"
namespace nuclearNetwork {
namespace serif::network {
/**
* @struct NetIn
@@ -102,8 +102,8 @@ namespace nuclearNetwork {
virtual NetOut evaluate(const NetIn &netIn);
protected:
Config& m_config; ///< Configuration instance
Probe::LogManager& m_logManager; ///< Log manager instance
serif::config::Config& m_config; ///< Configuration instance
serif::probe::LogManager& m_logManager; ///< Log manager instance
quill::Logger* m_logger; ///< Logger instance
};

View File

@@ -1,43 +0,0 @@
/* ***********************************************************************
//
// Copyright (C) 2025 -- The 4D-STAR Collaboration
// File Author: Emily Boudreaux
// Last Modified: March 17, 2025
//
// 4DSSE 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.
//
// 4DSSE 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
//
// *********************************************************************** */
#ifndef OPAC_H
#define OPAC_H
#include <string>
#include <map>
#include "DObject.h"
/**
* @breif initlaize the opacity module
* @param args: a hash map of all arguments needed to intialize opac
* @return error code in a DObject
**/
DObject initlaize_opac(const std::map<std::string, DObject>& args);
/**
* @breif opacity given a temperature, density, and composition
* @param args: a hash map of all arguments needed to calculate opac
* @return error code in a DObject
**/
DObject
#endif

View File

@@ -22,6 +22,8 @@
#include "polyCoeff.h"
namespace serif {
namespace polytrope {
namespace polycoeff{
double nonlinearSourceCoeff(const mfem::Vector &x)
{
@@ -57,4 +59,6 @@ namespace polycoeff{
return surfaceFlux;
}
}
} // namespace polycoeff
} // namespace polytrope
} // namespace serif

View File

@@ -23,6 +23,8 @@
#include "mfem.hpp"
#include <cmath>
namespace serif {
namespace polytrope {
namespace polycoeff
{
/**
@@ -63,4 +65,6 @@ namespace polycoeff
constexpr static double coeff[51] = {-8.164634353536671e-01, 8.651804355981230e-01, -6.391939109867470e-01, 4.882118355278944e-01, -3.898475553686603e-01, 3.102560043891329e-01, -2.365565113144737e-01, 1.639832755778444e-01, -9.645271947133248e-02, 4.450140636696046e-02, -1.460885194751961e-02, 2.816293786806504e-03, -8.178583546493117e-05, -8.584494556484958e-05, 8.476252127593868e-06, 2.923593421315422e-06, -2.206768214995963e-07, -1.203227957690371e-07, -3.381181730985542e-09, 4.022824706790907e-09, 7.041049107708875e-10, -3.562885681170365e-11, -3.281525407784209e-11, -5.031807464141896e-12, 2.034136401832885e-13, 2.361284283178230e-13, 4.602774507763180e-14, 1.809170850970874e-15, -1.333813332262995e-15, -4.045891156434286e-16, -5.197949512114809e-17, 2.222220713310119e-18, 2.625223897130583e-18, 6.226001466529447e-19, 6.571419077089260e-20, -6.672159423054950e-21, -4.476242224056620e-21, -9.790792477821165e-22, -9.222211318122281e-23, 1.427942034536028e-23, 7.759197090219954e-24, 1.546886518887300e-24, 9.585471984274525e-26, -4.005276449706623e-26, -1.459299762834743e-26, -1.870491354620814e-27, 2.271573838802745e-28, 1.360979028415734e-28, 1.102172718357361e-29, -6.919347646474293e-30, 4.875282352118995e-31};
};
} // namespace polyCoeff
} // namespace polycoeff
} // namespace polytrope
} // namespace serif

View File

@@ -39,6 +39,8 @@
#include "utilities.h"
#include "quill/LogMacros.h"
namespace serif {
namespace polytrope {
namespace laneEmden {
@@ -68,12 +70,12 @@ namespace laneEmden {
}
return acc;
}
}
} // namespace laneEmden
PolySolver::PolySolver(mfem::Mesh& mesh, const double n, const double order)
: m_config(Config::getInstance()),
m_logManager(Probe::LogManager::getInstance()),
: m_config(serif::config::Config::getInstance()), // Updated
m_logManager(serif::probe::LogManager::getInstance()),
m_logger(m_logManager.getLogger("log")),
m_polytropicIndex(n),
m_feOrder(order),
@@ -100,10 +102,10 @@ mfem::Mesh& PolySolver::prepareMesh(const double n) {
if (n > 4.99 || n < 0.0) {
throw std::runtime_error("The polytropic index n must be less than 5.0 and greater than 0.0. Currently it is " + std::to_string(n));
}
const ResourceManager& rm = ResourceManager::getInstance();
const Resource& genericResource = rm.getResource("mesh:polySphere");
const auto &meshIO = std::get<std::unique_ptr<MeshIO>>(genericResource);
meshIO->LinearRescale(polycoeff::x1(n));
const serif::resource::ResourceManager& rm = serif::resource::ResourceManager::getInstance();
const serif::resource::types::Resource& genericResource = rm.getResource("mesh:polySphere");
const auto &meshIO = std::get<std::unique_ptr<serif::mesh::MeshIO>>(genericResource);
meshIO->LinearRescale(polycoeff::x1(n)); // Assumes polycoeff is now serif::polytrope::polycoeff
return meshIO->GetMesh();
}
@@ -162,7 +164,7 @@ std::unique_ptr<formBundle> PolySolver::buildIndividualForms(const mfem::Array<i
forms->Q->AddDomainIntegrator(new mfem::MixedVectorGradientIntegrator()); // Q ∫ψ^φ·∇N^θ dV
forms->D->AddDomainIntegrator(new mfem::VectorFEMassIntegrator()); // D ∫ψ^φ·N^φ dV
forms->S->AddDomainIntegrator(new mfem::DiffusionIntegrator()); // S ∫∇ψ^θ·∇N^θ dV
forms->f->AddDomainIntegrator(new polyMFEMUtils::NonlinearPowerIntegrator(m_polytropicIndex));
forms->f->AddDomainIntegrator(new polyMFEMUtils::NonlinearPowerIntegrator(m_polytropicIndex)); // Assumes polyMFEMUtils is now serif::polytrope::polyMFEMUtils
// --- Assemble and Finalize the forms ---
assembleAndFinalizeForm(forms->M);
@@ -225,7 +227,7 @@ void PolySolver::solve() const {
saveAndViewSolution(solution);
}
SSE::MFEMArrayPairSet PolySolver::getEssentialTrueDof() const {
serif::types::MFEMArrayPairSet PolySolver::getEssentialTrueDof() const {
mfem::Array<int> theta_ess_tdof_list;
mfem::Array<int> phi_ess_tdof_list;
@@ -248,7 +250,7 @@ SSE::MFEMArrayPairSet PolySolver::getEssentialTrueDof() const {
thetaSurfaceVals.SetSize(theta_ess_tdof_list.Size());
thetaSurfaceVals = 0.0;
phiSurfaceVals.SetSize(phi_ess_tdof_list.Size());
phiSurfaceVals = polycoeff::thetaSurfaceFlux(m_polytropicIndex);
phiSurfaceVals = polycoeff::thetaSurfaceFlux(m_polytropicIndex); // Assumes polycoeff is now serif::polytrope::polycoeff
// combine the essential dofs with the center dofs
theta_ess_tdof_list.Append(thetaCenterDofs);
@@ -257,9 +259,9 @@ SSE::MFEMArrayPairSet PolySolver::getEssentialTrueDof() const {
// phi_ess_tdof_list.Append(phiCenterDofs);
// phiSurfaceVals.Append(phiCenterVals);
SSE::MFEMArrayPair thetaPair = std::make_pair(theta_ess_tdof_list, thetaSurfaceVals);
SSE::MFEMArrayPair phiPair = std::make_pair(phi_ess_tdof_list, phiSurfaceVals);
SSE::MFEMArrayPairSet pairSet = std::make_pair(thetaPair, phiPair);
serif::types::MFEMArrayPair thetaPair = std::make_pair(theta_ess_tdof_list, thetaSurfaceVals);
serif::types::MFEMArrayPair phiPair = std::make_pair(phi_ess_tdof_list, phiSurfaceVals);
serif::types::MFEMArrayPairSet pairSet = std::make_pair(thetaPair, phiPair);
return pairSet;
}
@@ -344,7 +346,7 @@ void PolySolver::setInitialGuess() const {
xh /= r; // Normalize the vector
y.SetSize(m_mesh.SpaceDimension());
y = xh;
y *= polycoeff::thetaSurfaceFlux(m_polytropicIndex);
y *= polycoeff::thetaSurfaceFlux(m_polytropicIndex); // Assumes polycoeff is now serif::polytrope::polycoeff
}
);
// We want to apply specific boundary conditions to the surface
@@ -377,8 +379,8 @@ void PolySolver::setInitialGuess() const {
}
if (m_config.get<bool>("Poly:Solver:ViewInitialGuess", false)) {
Probe::glVisView(*m_theta, m_mesh, "θ init");
Probe::glVisView(*m_phi, m_mesh, "φ init");
serif::probe::glVisView(*m_theta, m_mesh, "θ init");
serif::probe::glVisView(*m_phi, m_mesh, "φ init");
}
std::cout << "HERE" << std::endl;
@@ -390,8 +392,8 @@ void PolySolver::saveAndViewSolution(const mfem::BlockVector& state_vector) cons
mfem::Vector& x_phi = x_block.GetBlock(1);
if (m_config.get<bool>("Poly:Output:View", false)) {
Probe::glVisView(x_theta, *m_feTheta, "θ Solution");
Probe::glVisView(x_phi, *m_fePhi, "ɸ Solution");
serif::probe::glVisView(x_theta, *m_feTheta, "θ Solution");
serif::probe::glVisView(x_phi, *m_fePhi, "ɸ Solution");
}
// --- Extract the Solution ---
@@ -405,26 +407,27 @@ void PolySolver::saveAndViewSolution(const mfem::BlockVector& state_vector) cons
const std::vector rayDirection = {rayCoLatitude, rayLongitude};
Probe::getRaySolution(x_theta, *m_feTheta, rayDirection, raySamples, solutionPath);
serif::probe::getRaySolution(x_theta, *m_feTheta, rayDirection, raySamples, solutionPath);
// Probe::getRaySolution(x_phi, *m_fePhi, rayDirection, raySamples, derivSolPath);
}
}
void PolySolver::setOperatorEssentialTrueDofs() const {
const SSE::MFEMArrayPairSet ess_tdof_pair_set = getEssentialTrueDof();
const serif::types::MFEMArrayPairSet ess_tdof_pair_set = getEssentialTrueDof();
m_polytropOperator->set_essential_true_dofs(ess_tdof_pair_set);
}
void PolySolver::LoadSolverUserParams(double &newtonRelTol, double &newtonAbsTol, int &newtonMaxIter, int &newtonPrintLevel, double &gmresRelTol, double &gmresAbsTol, int &gmresMaxIter, int &gmresPrintLevel) const {
newtonRelTol = m_config.get<double>("Poly:Solver:Newton:RelTol", 1e-7);
newtonAbsTol = m_config.get<double>("Poly:Solver:Newton:AbsTol", 1e-7);
newtonMaxIter = m_config.get<int>("Poly:Solver:Newton:MaxIter", 200);
newtonPrintLevel = m_config.get<int>("Poly:Solver:Newton:PrintLevel", 1);
void PolySolver::LoadSolverUserParams(double &newtonRelTol, double &newtonAbsTol, int &newtonMaxIter, int &newtonPrintLevel,
double &gmresRelTol, double &gmresAbsTol, int &gmresMaxIter, int &gmresPrintLevel) const {
newtonRelTol = m_config.get<double>("Poly:Solver:Newton:RelTol", 1.e-4);
newtonAbsTol = m_config.get<double>("Poly:Solver:Newton:AbsTol", 1.e-6);
newtonMaxIter = m_config.get<int>("Poly:Solver:Newton:MaxIter", 10);
newtonPrintLevel = m_config.get<int>("Poly:Solver:Newton:PrintLevel", 3);
gmresRelTol = m_config.get<double>("Poly:Solver:GMRES:RelTol", 1e-10);
gmresAbsTol = m_config.get<double>("Poly:Solver:GMRES:AbsTol", 1e-12);
gmresMaxIter = m_config.get<int>("Poly:Solver:GMRES:MaxIter", 2000);
gmresPrintLevel = m_config.get<int>("Poly:Solver:GMRES:PrintLevel", 0);
gmresRelTol = m_config.get<double>("Poly:Solver:GMRES:RelTol", 1.e-12);
gmresAbsTol = m_config.get<double>("Poly:Solver:GMRES:AbsTol", 1.e-12);
gmresMaxIter = m_config.get<int>("Poly:Solver:GMRES:MaxIter", 200);
gmresPrintLevel = m_config.get<int>("Poly:Solver:GMRES:PrintLevel", -1);
LOG_DEBUG(m_logger, "Newton Solver (relTol: {:0.2E}, absTol: {:0.2E}, maxIter: {}, printLevel: {})", newtonRelTol, newtonAbsTol, newtonMaxIter, newtonPrintLevel);
LOG_DEBUG(m_logger, "GMRES Solver (relTol: {:0.2E}, absTol: {:0.2E}, maxIter: {}, printLevel: {})", gmresRelTol, gmresAbsTol, gmresMaxIter, gmresPrintLevel);
@@ -432,7 +435,7 @@ void PolySolver::LoadSolverUserParams(double &newtonRelTol, double &newtonAbsTol
void PolySolver::GetDofCoordinates(const mfem::FiniteElementSpace &fes, const std::string& filename) {
mfem::Mesh *mesh = fes.GetMesh();
double r = Probe::getMeshRadius(*mesh);
double r = serif::probe::getMeshRadius(*mesh);
std::ofstream outputFile(filename, std::ios::out | std::ios::trunc);
outputFile << "dof,R,r,x,y,z" << '\n';
@@ -493,3 +496,6 @@ solverBundle PolySolver::setupNewtonSolver() const {
return solver;
}
} // namespace polytrope
} // namespace serif

View File

@@ -32,6 +32,9 @@
#include "probe.h"
#include "quill/Logger.h"
namespace serif {
namespace polytrope {
/**
* @brief Namespace for Lane-Emden equation related utility functions.
*
@@ -98,7 +101,7 @@ namespace laneEmden {
* @endcode
*/
double thetaSeriesExpansion(const double xi, const double n, const int order);
}
} // namespace laneEmden
/**
* @brief Structure to manage the lifetime of MFEM solver objects.
@@ -272,8 +275,8 @@ public: // Public methods
private: // Private Attributes
// --- Configuration and Logging ---
Config& m_config; ///< Reference to the global configuration manager instance.
Probe::LogManager& m_logManager; ///< Reference to the global log manager instance.
serif::config::Config& m_config; ///< Reference to the global configuration manager instance.
serif::probe::LogManager& m_logManager; ///< Reference to the global log manager instance.
quill::Logger* m_logger; ///< Pointer to the specific logger instance for this class.
// --- Physical and Discretization Parameters ---
@@ -437,7 +440,7 @@ private: // Private methods
* 4. Potentially \f$\boldsymbol{\phi} = \mathbf{0}\f$ at the center (though the current implementation in `polySolver.cpp`
* seems to set components of \f$\boldsymbol{\phi}\f$ to zero at DOFs associated with the center element(s)).
*
* @return An `SSE::MFEMArrayPairSet` containing two pairs:
* @return An `serif::types::MFEMArrayPairSet` containing two pairs:
* - The first pair is for \f$\theta\f$: (`mfem::Array<int>` of essential TDOF indices, `mfem::Array<double>` of corresponding values).
* - The second pair is for \f$\boldsymbol{\phi}\f$: (`mfem::Array<int>` of essential TDOF indices, `mfem::Array<double>` of corresponding values).
*
@@ -450,7 +453,7 @@ private: // Private methods
* @pre `m_mesh`, `m_feTheta`, `m_fePhi` must be initialized. `m_polytropicIndex` must be set.
* @throw `mfem::ErrorException` (via `MFEM_ABORT`) if `findCenterElement()` fails to locate the center vertex.
*/
SSE::MFEMArrayPairSet getEssentialTrueDof() const;
serif::types::MFEMArrayPairSet getEssentialTrueDof() const;
/**
* @brief Finds the degrees of freedom (DOFs) associated with the geometric center (origin) of the mesh.
@@ -608,3 +611,5 @@ private: // Private methods
};
} // namespace polytrope
} // namespace serif

View File

@@ -25,10 +25,13 @@
#include "config.h"
#include <string>
namespace serif {
namespace polytrope {
namespace polyMFEMUtils {
NonlinearPowerIntegrator::NonlinearPowerIntegrator(const double n) :
m_polytropicIndex(n),
m_epsilon(Config::getInstance().get<double>("Poly:Solver:Epsilon", 1.0e-8)) {
m_epsilon(serif::config::Config::getInstance().get<double>("Poly:Solver:Epsilon", 1.0e-8)) {
if (m_polytropicIndex < 0.0) {
throw std::invalid_argument("Polytropic index must be non-negative.");
}
@@ -139,3 +142,5 @@ namespace polyMFEMUtils {
}
} // namespace polyMFEMUtils
} // namespace polytrope
} // namespace serif

View File

@@ -26,6 +26,10 @@
#include "mfem_smout.h"
#include <memory>
#include "config.h"
namespace serif {
namespace polytrope {
// --- SchurCompliment Class Implementation ---
// SchurCompliment: Constructors
@@ -34,8 +38,8 @@ SchurCompliment::SchurCompliment(
const mfem::SparseMatrix &DOp,
const mfem::SparseMatrix &MOp,
const mfem::Solver &GradInvOp ) :
mfem::Operator(DOp.Height(), DOp.Width())
{
mfem::Operator(DOp.Height(), DOp.Width()) {
// Initialize sizes
SetOperator(QOp, DOp, MOp, GradInvOp);
m_nPhi = m_DOp->Height();
m_nTheta = m_MOp->Height();
@@ -127,10 +131,8 @@ void GMRESInverter::Mult(const mfem::Vector &x, mfem::Vector &y) const {
// --- PolytropeOperator Class Implementation ---
// PolytropeOperator: Constructor
PolytropeOperator::PolytropeOperator(
std::unique_ptr<mfem::MixedBilinearForm> M,
std::unique_ptr<mfem::MixedBilinearForm> Q,
std::unique_ptr<mfem::BilinearForm> D,
@@ -138,6 +140,7 @@ PolytropeOperator::PolytropeOperator(
std::unique_ptr<mfem::NonlinearForm> f,
const mfem::Array<int> &blockOffsets) :
// TODO: Need to update this so that the size is that of the reduced system operator
mfem::Operator(blockOffsets.Last()), // Initialize the base class with the total size of the block offset vector
m_blockOffsets(blockOffsets),
m_jacobian(nullptr) {
@@ -281,7 +284,7 @@ void PolytropeOperator::finalize(const mfem::Vector &initTheta) {
}
// PolytropeOperator: Essential True DOF Management
void PolytropeOperator::set_essential_true_dofs(const SSE::MFEMArrayPair& theta_ess_tdofs, const SSE::MFEMArrayPair& phi_ess_tdofs) {
void PolytropeOperator::set_essential_true_dofs(const serif::types::MFEMArrayPair& theta_ess_tdofs, const serif::types::MFEMArrayPair& phi_ess_tdofs) {
m_isFinalized = false;
m_theta_ess_tdofs = theta_ess_tdofs;
m_phi_ess_tdofs = phi_ess_tdofs;
@@ -293,11 +296,11 @@ void PolytropeOperator::set_essential_true_dofs(const SSE::MFEMArrayPair& theta_
}
}
void PolytropeOperator::set_essential_true_dofs(const SSE::MFEMArrayPairSet& ess_tdof_pair_set) {
void PolytropeOperator::set_essential_true_dofs(const serif::types::MFEMArrayPairSet& ess_tdof_pair_set) {
set_essential_true_dofs(ess_tdof_pair_set.first, ess_tdof_pair_set.second);
}
SSE::MFEMArrayPairSet PolytropeOperator::get_essential_true_dofs() const {
serif::types::MFEMArrayPairSet PolytropeOperator::get_essential_true_dofs() const {
return std::make_pair(m_theta_ess_tdofs, m_phi_ess_tdofs);
}
@@ -485,3 +488,6 @@ void PolytropeOperator::update_preconditioner(const mfem::Operator &grad) const
update_inverse_nonlinear_jacobian(grad);
update_inverse_schur_compliment();
}
} // namespace polytrope
} // namespace serif

View File

@@ -31,7 +31,8 @@
* @brief A collection of utilities for working with MFEM and solving the lane-emden equation.
*/
namespace serif {
namespace polytrope {
/**
* @namespace polyMFEMUtils
* @brief A namespace for utilities for working with MFEM and solving the lane-emden equation.
@@ -69,8 +70,8 @@ namespace polyMFEMUtils {
*/
virtual void AssembleElementGrad (const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override;
private:
Config& m_config = Config::getInstance();
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
serif::config::Config& m_config = serif::config::Config::getInstance();
serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance();
quill::Logger* m_logger = m_logManager.getLogger("log");
double m_polytropicIndex;
double m_epsilon;
@@ -102,3 +103,5 @@ namespace polyMFEMUtils {
} // namespace polyMFEMUtils
} // namespace polytrope
} // namespace serif

View File

@@ -26,6 +26,9 @@
#include "probe.h"
namespace serif {
namespace polytrope {
/**
* @brief Represents the Schur complement operator used in the solution process.
*
@@ -40,7 +43,12 @@ public:
* @param MOp The M matrix operator.
* @param GradInvOp The inverse of the gradient operator.
*/
SchurCompliment(const mfem::SparseMatrix &QOp, const mfem::SparseMatrix &DOp, const mfem::SparseMatrix &MOp, const mfem::Solver &GradInvOp);
SchurCompliment(
const mfem::SparseMatrix &QOp,
const mfem::SparseMatrix &DOp,
const mfem::SparseMatrix &MOp,
const mfem::Solver &GradInvOp
);
/**
* @brief Constructs a SchurCompliment operator without the inverse gradient initially.
@@ -49,7 +57,11 @@ public:
* @param DOp The D matrix operator.
* @param MOp The M matrix operator.
*/
SchurCompliment(const mfem::SparseMatrix &QOp, const mfem::SparseMatrix &DOp, const mfem::SparseMatrix &MOp);
SchurCompliment(
const mfem::SparseMatrix &QOp,
const mfem::SparseMatrix &DOp,
const mfem::SparseMatrix &MOp
);
/**
* @brief Destructor.
@@ -200,14 +212,14 @@ public:
* @param theta_ess_tdofs Pair of arrays: (indices of essential DOFs for θ, values at these DOFs).
* @param phi_ess_tdofs Pair of arrays: (indices of essential DOFs for φ, values at these DOFs).
*/
void set_essential_true_dofs(const SSE::MFEMArrayPair& theta_ess_tdofs, const SSE::MFEMArrayPair& phi_ess_tdofs);
void set_essential_true_dofs(const serif::types::MFEMArrayPair& theta_ess_tdofs, const serif::types::MFEMArrayPair& phi_ess_tdofs);
/**
* @brief Sets the essential true degrees of freedom using a pair of pairs.
* Marks the operator as not finalized.
* @param ess_tdof_pair_set A pair containing the essential TDOF pairs for theta and phi.
*/
void set_essential_true_dofs(const SSE::MFEMArrayPairSet& ess_tdof_pair_set);
void set_essential_true_dofs(const serif::types::MFEMArrayPairSet& ess_tdof_pair_set);
/**
@@ -264,7 +276,7 @@ public:
* @brief Gets the currently set essential true degrees of freedom.
* @return A pair containing the essential TDOF pairs for theta and phi.
*/
SSE::MFEMArrayPairSet get_essential_true_dofs() const;
serif::types::MFEMArrayPairSet get_essential_true_dofs() const;
/**
* @brief Gets the block offsets for the full (unreduced) system.
@@ -280,7 +292,7 @@ public:
private:
// --- Logging ---
Probe::LogManager& m_logManager = Probe::LogManager::getInstance(); ///< Reference to the global log manager.
serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance(); ///< Reference to the global log manager.
quill::Logger* m_logger = m_logManager.getLogger("log"); ///< Pointer to the specific logger instance.
// --- Input Bilinear/Nonlinear Forms (owned) ---
@@ -323,8 +335,8 @@ private:
mfem::Array<int> m_reducedBlockOffsets; ///< Block offsets for the reduced system (free DOFs).
// --- Essential Boundary Conditions ---
SSE::MFEMArrayPair m_theta_ess_tdofs; ///< Essential true DOFs for θ (indices and values).
SSE::MFEMArrayPair m_phi_ess_tdofs; ///< Essential true DOFs for φ (indices and values).
serif::types::MFEMArrayPair m_theta_ess_tdofs; ///< Essential true DOFs for θ (indices and values).
serif::types::MFEMArrayPair m_phi_ess_tdofs; ///< Essential true DOFs for φ (indices and values).
// --- Jacobian and Preconditioner Components (owned, mutable) ---
std::unique_ptr<mfem::ScaledOperator> m_negQ_mat; ///< Scaled operator for -Q_reduced.
@@ -382,3 +394,6 @@ private:
*/
void update_preconditioner(const mfem::Operator &grad) const;
};
} // namespace polytrope
} // namespace serif

View File

@@ -42,7 +42,7 @@
#include "warning_control.h"
namespace Probe {
namespace serif::probe {
void pause() {
std::cout << "Execution paused. Please press enter to continue..."
@@ -56,7 +56,7 @@ void wait(int seconds) {
void glVisView(mfem::GridFunction& u, mfem::Mesh& mesh,
const std::string& windowTitle, const std::string& keyset) {
Config& config = Config::getInstance();
serif::config::Config& config = serif::config::Config::getInstance();
quill::Logger* logger = LogManager::getInstance().getLogger("log");
if (config.get<bool>("Probe:GLVis:Visualization", true)) {
std::string usedKeyset;
@@ -108,8 +108,8 @@ double getMeshRadius(mfem::Mesh& mesh) {
std::pair<std::vector<double>, std::vector<double>> getRaySolution(mfem::GridFunction& u, mfem::Mesh& mesh,
const std::vector<double>& rayDirection,
int numSamples, std::string filename) {
Config& config = Config::getInstance();
Probe::LogManager& logManager = Probe::LogManager::getInstance();
serif::config::Config& config = serif::config::Config::getInstance();
serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance();
quill::Logger* logger = logManager.getLogger("log");
LOG_INFO(logger, "Getting ray solution...");
// Check if the directory to write to exists
@@ -204,7 +204,7 @@ std::pair<std::vector<double>, std::vector<double>> getRaySolution(mfem::Vector
}
LogManager::LogManager() {
Config& config = Config::getInstance();
serif::config::Config& config = serif::config::Config::getInstance();
quill::Backend::start();
auto CLILogger = quill::Frontend::create_or_get_logger(
"root",

View File

@@ -32,7 +32,7 @@
/**
* @brief The Probe namespace contains utility functions for debugging and logging.
*/
namespace Probe {
namespace serif::probe {
/**
* @brief Pause the execution and wait for user input.
*/

View File

@@ -34,6 +34,7 @@
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
namespace serif::resource {
ResourceManager::ResourceManager() {
const std::string defaultDataDir = TOSTRING(DATA_DIR);
m_dataDir = m_config.get<std::string>("Data:Dir", defaultDataDir);
@@ -43,7 +44,7 @@ ResourceManager::ResourceManager() {
const std::filesystem::path indexFile(indexFilePath);
m_resourceConfig.loadConfig(indexFile.string());
for (const auto key : m_resourceConfig.keys() ) {
for (const auto& key : m_resourceConfig.keys() ) {
load(key);
}
}
@@ -54,7 +55,7 @@ std::vector<std::string> ResourceManager::getAvaliableResources() const {
return resources;
}
const Resource& ResourceManager::getResource(const std::string &name) const {
const serif::resource::types::Resource& ResourceManager::getResource(const std::string &name) const {
if (const auto it = m_resources.find(name); it != m_resources.end()) {
return it->second;
}
@@ -79,9 +80,10 @@ bool ResourceManager::load(const std::string& name) {
LOG_INFO(m_logger, "Resource already loaded: {}", name);
return true;
}
Resource resource = createResource(name, resourcePath);
serif::resource::types::Resource resource = serif::resource::types::createResource(name, resourcePath);
m_resources[name] = std::move(resource);
// -- Check if the resource is already in the map
return true;
}
}

View File

@@ -27,6 +27,7 @@
#include "debug.h"
namespace serif::resource::types {
std::string getFirstSegment(const std::string& input) {
size_t pos = input.find(':');
if (pos == std::string::npos) {
@@ -45,10 +46,10 @@ Resource createResource(const std::string& type, const std::string& path) {
std::make_unique<opat::OPAT>(opat::readOPAT(p)));
}},
{"mesh", [](const std::string& p) { return Resource(
std::make_unique<MeshIO>(p));
std::make_unique<serif::mesh::MeshIO>(p));
}},
{"eos", [](const std::string& p) { return Resource(
std::make_unique<EosIO>(p));
std::make_unique<serif::eos::EosIO>(p));
}}
// Add more mappings as needed
};
@@ -59,3 +60,4 @@ Resource createResource(const std::string& type, const std::string& path) {
throw std::invalid_argument("Unknown resource type: " + type);
}
}
}

View File

@@ -18,8 +18,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// *********************************************************************** */
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#pragma once
#include <vector>
#include <string>
@@ -38,6 +37,7 @@
* The ResourceManager class is responsible for loading, storing, and providing access to resources.
* It follows the Singleton design pattern to ensure only one instance of the manager exists.
*/
namespace serif::resource {
class ResourceManager {
private:
/**
@@ -55,13 +55,13 @@ private:
*/
ResourceManager& operator=(const ResourceManager&) = delete;
Config& m_config = Config::getInstance();
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
serif::config::Config& m_config = serif::config::Config::getInstance();
serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance();
quill::Logger* m_logger = m_logManager.getLogger("log");
Config m_resourceConfig;
serif::config::Config m_resourceConfig;
std::string m_dataDir;
std::unordered_map<std::string, Resource> m_resources;
std::unordered_map<std::string, types::Resource> m_resources;
/**
* @brief Loads a resource by name.
@@ -104,7 +104,7 @@ public:
* const Resource& resource = manager.getResource("exampleResource");
* @endcode
*/
const Resource& getResource(const std::string &name) const;
const types::Resource& getResource(const std::string &name) const;
/**
* @brief Loads a resource by name.
@@ -131,5 +131,4 @@ public:
*/
std::unordered_map<std::string, bool> loadAllResources();
};
#endif // RESOURCE_MANAGER_H
}

View File

@@ -18,8 +18,6 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// *********************************************************************** */
#ifndef RESOURCE_MANAGER_TYPES_H
#define RESOURCE_MANAGER_TYPES_H
#include <memory>
#include <variant>
@@ -29,6 +27,7 @@
#include "meshIO.h"
#include "eosIO.h"
namespace serif::resource::types {
/**
* @file resourceManagerTypes.h
* @brief Defines types and functions for managing resources.
@@ -51,8 +50,8 @@
*/
using Resource = std::variant<
std::unique_ptr<opat::OPAT>,
std::unique_ptr<MeshIO>,
std::unique_ptr<EosIO>>;
std::unique_ptr<serif::mesh::MeshIO>,
std::unique_ptr<serif::eos::EosIO>>;
/**
* @brief Extracts the first segment of a given string.
@@ -87,5 +86,4 @@ std::string getFirstSegment(const std::string& input);
* @endcode
*/
Resource createResource(const std::string& type, const std::string& path);
#endif // RESOURCE_MANAGER_TYPES_H
}

View File

@@ -23,8 +23,7 @@
#include <utility>
#include "mfem.hpp"
// TODO : Need a better namespace name for these types
namespace SSE {
namespace serif::types {
typedef std::pair<mfem::Array<int>, mfem::Array<double>> MFEMArrayPair;
typedef std::pair<MFEMArrayPair, MFEMArrayPair> MFEMArrayPairSet;
}

View File

@@ -1,86 +0,0 @@
#include <gtest/gtest.h>
#include "DObject.h"
#include "Metadata.h"
/**
* @file DObjectTest.cpp
* @brief Unit tests for the DObject class.
*/
/**
* @brief Test suite for the DObject class.
*/
class DObjectTest : public ::testing::Test {
protected:
DObject defaultObject;
DObject initializedObject;
void SetUp() override {
// Create a DObject with initial data and metadata
DObject initializedObject(std::vector<float>{1.0f, 2.0f, 3.0f, 4.0f});
}
};
/**
* @test Verify default constructor initializes correctly.
*/
TEST_F(DObjectTest, DefaultConstructor) {
EXPECT_NO_THROW(DObject());
EXPECT_NO_THROW(auto data = defaultObject.getData());
EXPECT_FALSE(defaultObject.isDebuggingEnabled());
}
/**
* @test Verify constructor initializes with provided data and metadata.
*/
TEST_F(DObjectTest, ParameterizedConstructor) {
DObject obj(std::vector<int>{1, 2, 3});
EXPECT_NO_THROW(obj.getData());
EXPECT_EQ(std::get<std::vector<int>>(obj.getData()), std::vector<int>({1, 2, 3}));
}
/**
* @test Verify getter and setter for data.
*/
TEST_F(DObjectTest, DataSetterGetter) {
std::vector<double> newData = {3.14, 2.71, 1.61};
EXPECT_NO_THROW(defaultObject.setData(newData));
EXPECT_EQ(std::get<std::vector<double>>(defaultObject.getData()), newData);
}
/**
* @test Verify enabling and disabling debugging.
*/
TEST_F(DObjectTest, DebuggingFlag) {
EXPECT_FALSE(defaultObject.isDebuggingEnabled());
defaultObject.setDebugging(true);
EXPECT_TRUE(defaultObject.isDebuggingEnabled());
defaultObject.setDebugging(false);
EXPECT_FALSE(defaultObject.isDebuggingEnabled());
}
TEST_F(DObjectTest, ErrorCodeSetteGetter) {
int prevCode;
prevCode = defaultObject.setErrorCode(1);
EXPECT_EQ(prevCode, 0);
prevCode = defaultObject.setErrorCode(2);
EXPECT_EQ(prevCode, 1);
int getCode;
getCode = defaultObject.getErrorCode();
EXPECT_EQ(getCode, 2);
}
/**
* @test Basic Integration Test
*/
TEST_F(DObjectTest, IntegrationTest) {
float data = 55.86868;
DObject obj;
obj.setData(data);
float newData;
newData = std::get<float>(obj.getData());
EXPECT_EQ(data, newData);
}

View File

@@ -1,89 +0,0 @@
#include <gtest/gtest.h>
#include "LockableDObject.h"
#include <thread>
#include <vector>
/**
* @file LockableDObjectTest.cpp
* @brief Unit tests for the LockableDObject class.
*/
/**
* @brief Test suite for the LockableDObject class.
*/
class LockableDObjectTest : public ::testing::Test {
protected:
LockableDObject lockableObject;
void SetUp() override {
// Initialize the LockableDObject for tests
DObject& obj = lockableObject.get();
obj.setData(42); // Set initial data
}
};
/**
* @test Verify the default construction of LockableDObject.
*/
TEST_F(LockableDObjectTest, DefaultConstruction) {
EXPECT_NO_THROW(LockableDObject obj);
}
/**
* @test Verify access to the underlying DObject.
*/
TEST_F(LockableDObjectTest, AccessDObject) {
DObject& obj = lockableObject.get();
EXPECT_EQ(std::get<int>(obj.getData()), 42); // Ensure the data is accessible
}
/**
* @test Verify locking and unlocking.
*/
TEST_F(LockableDObjectTest, LockAndUnlock) {
EXPECT_NO_THROW(lockableObject.lock());
EXPECT_NO_THROW(lockableObject.unlock());
}
/**
* @test Verify thread safety with multiple threads.
*/
TEST_F(LockableDObjectTest, ThreadSafety) {
const int numThreads = 10;
std::vector<std::thread> threads;
std::atomic<int> successCount{0};
// Each thread tries to update the data
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back([this, i, &successCount]() {
lockableObject.lock();
DObject& obj = lockableObject.get();
obj.setData(i);
if (std::get<int>(obj.getData()) == i) {
successCount++;
}
lockableObject.unlock();
});
}
for (auto& t : threads) {
t.join();
}
EXPECT_EQ(successCount, numThreads);
}
/**
* @test Verify that the DObject remains consistent when accessed via LockableDObject.
*/
TEST_F(LockableDObjectTest, ConsistentState) {
lockableObject.lock();
DObject& obj = lockableObject.get();
obj.setData(100);
EXPECT_EQ(std::get<int>(obj.getData()), 100);
lockableObject.unlock();
lockableObject.lock();
EXPECT_EQ(std::get<int>(lockableObject.get().getData()), 100);
lockableObject.unlock();
}

View File

@@ -1,162 +0,0 @@
#include <gtest/gtest.h>
#include <thread>
#include "Metadata.h"
/**
* @file MetadataTest.cpp
* @brief Unit tests and integration tests for the Metadata class.
*/
/**
* @brief Test suite for the Metadata class.
*/
class MetadataTest : public ::testing::Test {
protected:
void SetUp() override {
// Common setup for tests (if needed)
}
void TearDown() override {
// Clean up after tests (if needed)
}
};
/**
* @test Verify default constructor initializes correctly.
*/
TEST_F(MetadataTest, DefaultConstructor) {
Metadata metadata;
int expectedByteSize = 0;
EXPECT_EQ(metadata.getByteSize(), expectedByteSize);
EXPECT_EQ(metadata.getDataType(), "");
EXPECT_TRUE(metadata.getDimensions().empty());
EXPECT_FALSE(metadata.isDebugEnabled());
}
/**
* @test Verify parameterized constructor initializes correctly.
*/
TEST_F(MetadataTest, ParameterizedConstructor) {
std::vector<std::size_t> dimensions = {3, 4, 5};
Metadata metadata(120, "float", dimensions, true);
int expectedByteSize = 120;
EXPECT_EQ(metadata.getByteSize(), expectedByteSize);
EXPECT_EQ(metadata.getDataType(), "float");
EXPECT_EQ(metadata.getDimensions(), dimensions);
EXPECT_TRUE(metadata.isDebugEnabled());
}
/**
* @test Verify setters and getters for byte size.
*/
TEST_F(MetadataTest, ByteSizeSetterGetter) {
Metadata metadata;
metadata.setByteSize(256);
EXPECT_EQ(metadata.getByteSize(), 256);
}
/**
* @test Verify setters and getters for data type.
*/
TEST_F(MetadataTest, DataTypeSetterGetter) {
Metadata metadata;
metadata.setDataType("double");
EXPECT_EQ(metadata.getDataType(), "double");
}
/**
* @test Verify setters and getters for dimensions.
*/
TEST_F(MetadataTest, DimensionsSetterGetter) {
Metadata metadata;
std::vector<std::size_t> dimensions = {2, 2, 2};
metadata.setDimensions(dimensions);
EXPECT_EQ(metadata.getDimensions(), dimensions);
}
/**
* @test Verify setters and getters for debug flag.
*/
TEST_F(MetadataTest, DebugFlagSetterGetter) {
Metadata metadata;
metadata.setDebugEnabled(true);
EXPECT_TRUE(metadata.isDebugEnabled());
metadata.setDebugEnabled(false);
EXPECT_FALSE(metadata.isDebugEnabled());
}
/**
* @test Verify metadata output with operator<<.
*/
TEST_F(MetadataTest, MetadataOutputOperator) {
Metadata metadata(64, "int", {8, 8}, true);
std::ostringstream oss;
oss << metadata;
std::string expectedOutput = "Metadata Information:\n"
" Byte Size: 64 bytes\n"
" Data Type: int\n"
" Dimensions: [8, 8]\n"
" Debug Enabled: Yes\n";
EXPECT_EQ(oss.str(), expectedOutput);
}
/**
* @test Integration test: Validate metadata behavior in a multi-step scenario.
*/
TEST_F(MetadataTest, IntegrationScenario) {
Metadata metadata;
// Step 1: Initialize metadata with some values
metadata.setByteSize(128);
metadata.setDataType("float");
metadata.setDimensions({4, 4, 2});
metadata.setDebugEnabled(true);
EXPECT_EQ(metadata.getByteSize(), 128);
EXPECT_EQ(metadata.getDataType(), "float");
EXPECT_EQ(metadata.getDimensions(), (std::vector<std::size_t>{4, 4, 2}));
EXPECT_TRUE(metadata.isDebugEnabled());
// Step 2: Simulate a metadata update
metadata.setByteSize(256);
metadata.setDataType("double");
metadata.setDimensions({8, 8});
metadata.setDebugEnabled(false);
EXPECT_EQ(metadata.getByteSize(), 256);
EXPECT_EQ(metadata.getDataType(), "double");
EXPECT_EQ(metadata.getDimensions(), (std::vector<std::size_t>{8, 8}));
EXPECT_FALSE(metadata.isDebugEnabled());
}
/**
* @test Integration test: Handling edge cases for metadata.
*/
TEST_F(MetadataTest, EdgeCaseHandling) {
Metadata metadata;
// Case 1: Empty dimensions
metadata.setDimensions({});
EXPECT_TRUE(metadata.getDimensions().empty());
// Case 2: Large byte size
metadata.setByteSize(static_cast<std::size_t>(-1));
EXPECT_EQ(metadata.getByteSize(), static_cast<std::size_t>(-1));
// Case 3: Empty data type
metadata.setDataType("");
EXPECT_EQ(metadata.getDataType(), "");
}

View File

@@ -1,24 +0,0 @@
# Test files for dobj
test_sources = [
'MetadataTest.cpp',
'DObjectTest.cpp',
'LockableDObjectTest.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, gtest_main],
include_directories: include_directories('../../src/dobj/public'),
link_with: libdobj, # 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)
endforeach

View File

@@ -1,9 +0,0 @@
test_file = 'testDObject.cpp'
exe_name = test_file.split('.')[0]
executable(
exe_name,
test_file,
include_directories: include_directories('../../src/dobj/public'),
link_with: libdobj, # Link the dobj library
install_rpath: '@loader_path/../../src' # Ensure runtime library path resolves correctly
)

View File

@@ -1,31 +0,0 @@
#include<iostream>
#include "DObject.h"
DObject testFunction(DObject &obj);
int main(){
float data = 55.86868;
DObject obj;
obj.setData(data);
float newData;
newData = std::get<float>(obj.getData());
std::cout << "Data: " << newData << std::endl;
std::cout << "Calling test function" << std::endl;
DObject newObj = testFunction(obj);
std::cout << newObj << std::endl;
return 0;
}
// Test function which takes a DObject as an argument and
// returns new DObject with an vector of 10 elements identical to the input DObject
// This should use std::varient and auto to do some degree of type inference
DObject testFunction(DObject &obj){
float data = obj.getDataAs<float>();
std::cout << "Data: " << data << std::endl;
std::vector<std::vector<float>> newData(3, std::vector<float>(3, data));
DObject newObj(newData);
std::cout << obj << std::endl;
return newObj;
}