From f7eeb074b9ba06abccbf5cc16ac3ae86360b35ff Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 6 Aug 2018 21:31:30 -0500 Subject: [PATCH] Address @smharper comments on #1035 --- CMakeLists.txt | 1 + src/hdf5_interface.h | 4 +-- src/initialize.cpp | 10 +------ src/input_xml.F90 | 8 +++++ src/particle.cpp | 4 +-- src/particle.h | 17 ++++++----- src/settings.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++ src/settings.h | 43 +++++++++++++++++++++++++++ src/string_utils.h | 19 ++++++++---- 9 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 src/settings.cpp create mode 100644 src/settings.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ac3b3c814..ea9bd5969 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -398,6 +398,7 @@ add_library(libopenmc SHARED src/pugixml/pugixml_c.cpp src/random_lcg.cpp src/scattdata.cpp + src/settings.cpp src/simulation.cpp src/state_point.cpp src/string_functions.cpp diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index 2face49ea..b0d2cc2c1 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -143,8 +143,8 @@ struct H5TypeMap { static const hid_t type_id; }; // Template functions used to provide simple interface to lower-level functions //============================================================================== -template -void write_attribute(hid_t obj_id, const char* name, T buffer) +template inline void +write_attribute(hid_t obj_id, const char* name, T buffer) { write_attr(obj_id, name, 0, nullptr, H5TypeMap::type_id, &buffer); } diff --git a/src/initialize.cpp b/src/initialize.cpp index 728f43695..62eeea409 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -10,25 +10,17 @@ #include "hdf5_interface.h" #include "message_passing.h" #include "openmc.h" +#include "settings.h" #ifdef _OPENMP #include "omp.h" #endif // data/functions from Fortran side -extern "C" bool openmc_check_overlaps; -extern "C" bool openmc_write_all_tracks; -extern "C" bool openmc_particle_restart_run; -extern "C" bool openmc_restart_run; extern "C" void print_usage(); extern "C" void print_version(); - // Paths to various files extern "C" { - char* openmc_path_input; - char* openmc_path_statepoint; - char* openmc_path_sourcepoint; - char* openmc_path_particle_restart; bool is_null(void* ptr) {return !ptr;} } diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e2feb6848..e81bb92f7 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -82,6 +82,11 @@ module input_xml type(C_PTR) :: node_ptr end subroutine read_lattices + subroutine read_settings(node_ptr) bind(C) + import C_PTR + type(C_PTR) :: node_ptr + end subroutine read_settings + function find_root_universe() bind(C) result(root) import C_INT32_T integer(C_INT32_T) :: root @@ -240,6 +245,9 @@ contains call doc % load_file(filename) root = doc % document_element() + ! Read settings from C++ side + call read_settings(root % ptr) + ! Verbosity if (check_for_node(root, "verbosity")) then call get_node_value(root, "verbosity", verbosity) diff --git a/src/particle.cpp b/src/particle.cpp index a7f91e0f3..74523eef2 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -7,6 +7,7 @@ #include "error.h" #include "hdf5_interface.h" #include "openmc.h" +#include "settings.h" #include "simulation.h" namespace openmc { @@ -146,9 +147,8 @@ Particle::write_restart() if (openmc_run_mode == RUN_MODE_PARTICLE) return; // Set up file name - // TODO: Add path_output when available on C++ side std::stringstream filename; - filename << "particle_" << openmc_current_batch << '_' << id << ".h5"; + filename << path_output << "particle_" << openmc_current_batch << '_' << id << ".h5"; #pragma omp critical (WriteParticleRestart) { diff --git a/src/particle.h b/src/particle.h index 81089f606..caa54d7de 100644 --- a/src/particle.h +++ b/src/particle.h @@ -1,6 +1,9 @@ #ifndef PARTICLE_H #define PARTICLE_H +//! @file particle.h +//! @brief Particle type + #include #include @@ -21,12 +24,12 @@ constexpr double REL_MAX_LOST_PARTICLES {1.0e-6}; extern "C" { struct LocalCoord { - int cell; - int universe; - int lattice; - int lattice_x; - int lattice_y; - int lattice_z; + int cell {-1}; + int universe {-1}; + int lattice {-1}; + int lattice_x {-1}; + int lattice_y {-1}; + int lattice_z {-1}; double xyz[3]; //!< particle position double uvw[3]; //!< particle direction bool rotated {false}; //!< Is the level rotated? @@ -95,7 +98,7 @@ extern "C" { double last_sqrtkT; //!< last temperature // Statistical data - int n_collision; //!< # of collisions + int n_collision; //!< number of collisions // Track output bool write_track {false}; diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 000000000..8ecc04a79 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,70 @@ +#include "settings.h" + +#include "error.h" +#include "openmc.h" +#include "string_utils.h" +#include "xml_interface.h" + +namespace openmc { + +//============================================================================== +// Global variables +//============================================================================== + +char* openmc_path_input; +char* openmc_path_statepoint; +char* openmc_path_sourcepoint; +char* openmc_path_particle_restart; +std::string path_cross_sections; +std::string path_multipole; +std::string path_output; +std::string path_source; + +//============================================================================== +// Functions +//============================================================================== + +void read_settings(pugi::xml_node* root) +{ + // Look for deprecated cross_sections.xml file in settings.xml + if (check_for_node(*root, "cross_sections")) { + warning("Setting cross_sections in settings.xml has been deprecated." + " The cross_sections are now set in materials.xml and the " + "cross_sections input to materials.xml and the OPENMC_CROSS_SECTIONS" + " environment variable will take precendent over setting " + "cross_sections in settings.xml."); + path_cross_sections = get_node_value(*root, "cross_sections"); + } + + // Look for deprecated windowed_multipole file in settings.xml + if (openmc_run_mode != RUN_MODE_PLOTTING) { + if (check_for_node(*root, "multipole_library")) { + warning("Setting multipole_library in settings.xml has been " + "deprecated. The multipole_library is now set in materials.xml and" + " the multipole_library input to materials.xml and the " + "OPENMC_MULTIPOLE_LIBRARY environment variable will take " + "precendent over setting multipole_library in settings.xml."); + path_multipole = get_node_value(*root, "multipole_library"); + } + if (!ends_with(path_multipole, "/")) { + path_multipole += "/"; + } + } + + // Check for output options + if (check_for_node(*root, "output")) { + + // Get pointer to output node + pugi::xml_node node_output = root->child("output"); + + // Set output directory if a path has been specified + if (check_for_node(node_output, "path")) { + path_output = get_node_value(node_output, "path"); + if (!ends_with(path_output, "/")) { + path_output += "/"; + } + } + } +} + +} // namespace openmc \ No newline at end of file diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 000000000..0fc272bcd --- /dev/null +++ b/src/settings.h @@ -0,0 +1,43 @@ +#ifndef OPENMC_SETTINGS_H +#define OPENMC_SETTINGS_H + +//! @file settings.h +//! @brief Settings for OpenMC + +#include + +#include "pugixml.hpp" + +namespace openmc { + +//============================================================================== +// Global variable declarations +//============================================================================== + +// Defined on Fortran side +extern "C" bool openmc_check_overlaps; +extern "C" bool openmc_particle_restart_run; +extern "C" bool openmc_restart_run; +extern "C" bool openmc_write_all_tracks; + +// Defined in .cpp +// TODO: Make strings instead of char* once Fortran is gone +extern "C" char* openmc_path_input; +extern "C" char* openmc_path_statepoint; +extern "C" char* openmc_path_sourcepoint; +extern "C" char* openmc_path_particle_restart; +extern std::string path_cross_sections; +extern std::string path_multipole; +extern std::string path_output; +extern std::string path_source; + +//============================================================================== +//! Read settings from XML file +//! @param[in] root XML node for +//============================================================================== + +extern "C" void read_settings(pugi::xml_node* root); + +} // namespace openmc + +#endif // OPENMC_SETTINGS_H \ No newline at end of file diff --git a/src/string_utils.h b/src/string_utils.h index e2cb773ab..d4d3b3173 100644 --- a/src/string_utils.h +++ b/src/string_utils.h @@ -1,14 +1,14 @@ -#ifndef STRING_UTILS_H -#define STRING_UTILS_H +#ifndef OPENMC_STRING_UTILS_H +#define OPNEMC_STRING_UTILS_H +#include #include #include - namespace openmc { -std::vector -split(const std::string &in) +inline std::vector +split(const std::string& in) { std::vector out; @@ -31,5 +31,12 @@ split(const std::string &in) return out; } +inline bool +ends_with(const std::string& value, const std::string& ending) +{ + if (ending.size() > value.size()) return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + } // namespace openmc -#endif // STRING_UTILS_H +#endif // OPENMC_STRING_UTILS_H