diff --git a/.github/workflows/linux_build_test.yml b/.github/workflows/linux_build_test.yml index fb505bd758..09c62e6c03 100644 --- a/.github/workflows/linux_build_test.yml +++ b/.github/workflows/linux_build_test.yml @@ -49,7 +49,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 with: - submodules: recursive + set-safe-directory: '*' - name: Setup run: | diff --git a/.github/workflows/linux_build_test_merge.yml b/.github/workflows/linux_build_test_merge.yml index fcc94c78e2..42401cb713 100644 --- a/.github/workflows/linux_build_test_merge.yml +++ b/.github/workflows/linux_build_test_merge.yml @@ -41,8 +41,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - with: - submodules: recursive - name: Setup run: | diff --git a/doc/CHANGELOG.rst b/doc/CHANGELOG.rst index 1a6528d192..791c911228 100644 --- a/doc/CHANGELOG.rst +++ b/doc/CHANGELOG.rst @@ -20,10 +20,10 @@ Next version * Removed unused Circle CI yml (#859) * Added configuration options to CMake configuration file (#867) * Change test-on-merge against MOAB master/develop to be optional (#870) + * Enhance console logging capabilities (#872) **Fixed:** - * Patch to compile with Geant4 10.6 - + * Patch to compile with Geant4 10.6 v3.2.2 ==================== @@ -48,7 +48,7 @@ v3.2.1 **Removed:** **Fixed:** - + **Security:** **Maintenance:** diff --git a/src/dagmc/DagMC.hpp b/src/dagmc/DagMC.hpp index 7dd1e5b75c..8088ec0683 100644 --- a/src/dagmc/DagMC.hpp +++ b/src/dagmc/DagMC.hpp @@ -75,11 +75,10 @@ class DagMC { DagMC(std::shared_ptr mb_impl = nullptr, double overlap_tolerance = 0., double numerical_precision = .001); // Deprecated Constructor - [ - [deprecated("Replaced by DagMC(std::shared_ptr mb_impl, ... " - ")")]] DagMC(Interface* mb_impl, - double overlap_tolerance = 0., - double numerical_precision = .001); + [[deprecated( + "Replaced by DagMC(std::shared_ptr mb_impl, ... " + ")")]] DagMC(Interface* mb_impl, double overlap_tolerance = 0., + double numerical_precision = .001); // Destructor ~DagMC(); @@ -466,6 +465,56 @@ class DagMC { return MBI_shared_ptr; } + // Verbosity levels + // -1 : "override" the current verbosity setting and write message + // 0 : No output + // 1 : All output + int set_verbosity(int val) { + int verbosity_min = 0; + int verbosity_max = 1; + if (val < verbosity_min || val > verbosity_max) + warning("Invalid verbosity value " + std::to_string(val) + + " will be set to nearest valid value."); + val = std::min(std::max(verbosity_min, val), verbosity_max); + return verbosity = val; + } + + int get_verbosity() const { return verbosity; } + + /** console output mechanism + * @param msg Message to be written to the console + * @param lvl Message will not be written if the verbosity level + * is higher than the class instance's current verbosity setting. + * Use of -1 ensures the message will always be written. + * @param newline Whether or not to apend a newline to the message. + */ + void message(const std::string& msg, int lvl = 1, bool newline = true) const { + // do not write message if level is higher than + // verbosity setting + if (lvl > verbosity) return; + // otherwise, display message + if (newline) + std::cout << msg << "\n"; + else + std::cout << msg; + } + + /** write a warning message to the console + * @param msg Message to be written to the console + * @param newline Whether or not to apend a newline to the message. + */ + void warning(const std::string& msg, bool newline = true) const { + message("WARNING: " + msg, -1, newline); + } + + /** write an error message to the console + * @param msg Message to be written to the console + * @param newline Whether or not to apend a newline to the message. + */ + void err_msg(const std::string& msg, bool newline = true) const { + message("ERROR: " + msg, -1, newline); + } + private: /* PRIVATE MEMBER DATA */ @@ -486,6 +535,9 @@ class DagMC { std::unique_ptr ray_tracer; + /** verbosity setting for DAGMC operations */ + int verbosity{1}; + public: Tag nameTag, facetingTolTag; diff --git a/src/dagmc/dagmcmetadata.cpp b/src/dagmc/dagmcmetadata.cpp index 2e8383f782..2c93393ec6 100644 --- a/src/dagmc/dagmcmetadata.cpp +++ b/src/dagmc/dagmcmetadata.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "util.hpp" @@ -10,7 +11,7 @@ dagmcMetaData::dagmcMetaData(moab::DagMC* dag_ptr, bool verbosity, bool require_density_present) : DAG(dag_ptr), - verbose(verbosity), + verbosity(verbosity ? 1 : 0), require_density(require_density_present) { // these are the keywords that dagmc will understand // from groups if you need to process more @@ -50,7 +51,7 @@ std::string dagmcMetaData::get_volume_property(std::string property, } else if (property == "tally") { value = tally_data_eh[eh]; } else { - std::cout << "Not a valid property for volumes" << std::endl; + std::cerr << "Not a valid property for volumes" << std::endl; } return value; } @@ -228,7 +229,7 @@ void dagmcMetaData::parse_material_data() { // implicit complement else if (DAG->is_implicit_complement(eh)) { if (implicit_complement_material == "") { - std::cout << "Implicit Complement assumed to be Vacuum" << std::endl; + message("Implicit Complement assumed to be Vacuum"); volume_material_property_data_eh[eh] = "mat:Vacuum"; volume_material_data_eh[eh] = vacuum_str; } else { @@ -283,12 +284,13 @@ void dagmcMetaData::parse_importance_data() { } importance_map[eh][pair.first] = imp; } else { - std::cout << "Volume with ID " << volid - << " has more than one importance " << std::endl; - std::cout << "Assigned for particle type " << pair.first << std::endl; - std::cout << "Only one importance value per volume per particle type " - "is allowed" - << std::endl; + std::stringstream ss; + ss << "Volume with ID " << volid << " has more than one importance " + << std::endl; + ss << "Assigned for particle type " << pair.first << std::endl; + ss << "Only one importance value per volume per particle type " + "is allowed"; + message(ss.str(), -1); exit(EXIT_FAILURE); } } @@ -303,11 +305,11 @@ void dagmcMetaData::parse_importance_data() { std::string particle = *it; moab::EntityHandle eh = DAG->entity_by_index(3, i); if (importance_map[eh].count(particle) == 0) { - if (verbose) { - std::cout << "Warning: Volume with ID " << DAG->id_by_index(3, i); - std::cout << " does not have an importance set for particle "; - std::cout << particle << " assuming importance 1.0 " << std::endl; - } + std::stringstream ss; + ss << "Volume with ID " << DAG->id_by_index(3, i); + ss << " does not have an importance set for particle "; + ss << particle << " assuming importance 1.0 "; + message(ss.str(), 1); // give this particle default importance importance_map[eh][particle] = 1.0; } @@ -360,15 +362,15 @@ void dagmcMetaData::parse_boundary_data() { boundary_assignment = boundary_assignments[eh]; if (boundary_assignment.size() != 1) { - std::cout << "More than one boundary conditions specified for " << surfid - << std::endl; - std::cout << surfid << " has the following density assignments" - << std::endl; + std::stringstream ss; + ss << "More than one boundary conditions specified for " << surfid + << std::endl; + ss << surfid << " has the following density assignments" << std::endl; for (int j = 0; j < boundary_assignment.size(); j++) { - std::cout << boundary_assignment[j] << std::endl; + ss << boundary_assignment[j] << std::endl; } - std::cout << "Please check your boundary condition assignments " << surfid - << std::endl; + ss << "Please check your boundary condition assignments " << surfid; + err_msg(ss.str()); exit(EXIT_FAILURE); } // 2d entities have been tagged with the boundary condition property @@ -620,8 +622,9 @@ std::pair dagmcMetaData::split_string( int str_length = property_string.length() - found_delimiter; second = property_string.substr(found_delimiter + 1, str_length); } else { - std::cout << "Didn't find any delimiter" << std::endl; - std::cout << "Returning empty strings" << std::endl; + warning( + "Didn't find any delimiter.\n " + "Returning empty strings"); } return {first, second}; diff --git a/src/dagmc/dagmcmetadata.hpp b/src/dagmc/dagmcmetadata.hpp index 4154063625..e48a4606c6 100644 --- a/src/dagmc/dagmcmetadata.hpp +++ b/src/dagmc/dagmcmetadata.hpp @@ -2,6 +2,7 @@ #define SRC_DAGMC_DAGMCMETADATA_HPP_ #include #include +#include #include "DagMC.hpp" @@ -109,10 +110,60 @@ class dagmcMetaData { // map of importance data std::map> importance_map; + // Verbosity levels + // -1 : "override" the current verbosity setting and write message + // 0 : No output + // 1 : All output + int set_verbosity(int val) { + int verbosity_max = 0; + int verbosity_min = 1; + if (val < verbosity_min || val > verbosity_max) + warning("Invalid verbosity value " + std::to_string(val) + + " will be set to nearest valid value."); + val = std::min(std::max(verbosity_min, val), verbosity_max); + return verbosity = val; + } + + int get_verbosity(int val) { return verbosity; } + + /** console output mechanism + * @param msg Message to be written to the console + * @param lvl Message will not be written if the verbosity level + * is higher than the class instance's current verbosity setting. + * Use of -1 ensures the message will always be written. + * @param newline Whether or not to apend a newline to the message. + */ + void message(const std::string& msg, int lvl = 1, bool newline = true) const { + // do not write message if level is higher than + // verbosity setting + if (lvl > verbosity) return; + // otherwise, display message + if (newline) + std::cout << msg << "\n"; + else + std::cout << msg; + } + + /** write a warning message to the console + * @param msg Message to be written to the console + * @param newline Whether or not to apend a newline to the message. + */ + void warning(const std::string& msg, bool newline = true) const { + message("WARNING: " + msg, -1, newline); + } + + /** write an error message to the console + * @param msg Message to be written to the console + * @param newline Whether or not to apend a newline to the message. + */ + void err_msg(const std::string& msg, bool newline = true) const { + message("ERROR: " + msg, -1, newline); + } + // private member variables private: moab::DagMC* DAG; // Pointer to DAGMC instance - bool verbose; // Provide additional output while setting up and parsing + int verbosity{1}; // Provide additional output while setting up and parsing // properties bool require_density; // Require that all volumes have a specified density // value