From 5109bd0de1222f3096f9f511b194c35e25a69696 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sat, 5 Oct 2019 02:13:12 -0500 Subject: [PATCH] Adding error trigger attribute to volume calc. --- include/openmc/volume_calc.h | 4 ++-- src/volume_calc.cpp | 32 +++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/openmc/volume_calc.h b/include/openmc/volume_calc.h index b5e8477424..2a8273f9bf 100644 --- a/include/openmc/volume_calc.h +++ b/include/openmc/volume_calc.h @@ -88,8 +88,8 @@ public: // Data members int domain_type_; //!< Type of domain (cell, material, etc.) - int n_samples_; //!< Number of samples to use - int seed_offset_; + size_t n_samples_; //!< Number of samples to use + double error_trigger_ {-1.0}; //!< Error below which the calculation will stop Position lower_left_; //!< Lower-left position of bounding box Position upper_right_; //!< Upper-right position of bounding box std::vector domain_ids_; //!< IDs of domains to find volumes of diff --git a/src/volume_calc.cpp b/src/volume_calc.cpp index 40b5f08dde..a57305db93 100644 --- a/src/volume_calc.cpp +++ b/src/volume_calc.cpp @@ -59,7 +59,23 @@ VolumeCalculation::VolumeCalculation(pugi::xml_node node) domain_ids_ = get_node_array(node, "domain_ids"); lower_left_ = get_node_array(node, "lower_left"); upper_right_ = get_node_array(node, "upper_right"); - n_samples_ = std::stoi(get_node_value(node, "samples")); + std::stringstream size_t_stream(get_node_value(node, "samples")); + size_t_stream >> n_samples_; + if (size_t_stream.fail()) { + std::stringstream msg; + msg << "Could not read number of samples (" + << size_t_stream.str() << ")\n"; + fatal_error(msg); + } + + if (check_for_node(node, "error_trigger")) { + error_trigger_ = std::stod(get_node_value(node, "error_trigger")); + if (error_trigger_ <= 0.0) { + std::stringstream msg; + msg << "Invalid error trigger " << error_trigger_ << " provided for a volume calculation."; + fatal_error(msg); + } + } // Ensure there are no duplicates by copying elements to a set and then // comparing the length with the original vector @@ -74,8 +90,10 @@ VolumeCalculation::VolumeCalculation(pugi::xml_node node) std::vector VolumeCalculation::execute() const { std::vector results = _execute(); + + if (error_trigger_ <= 0.0) { return results; } + size_t offset = n_samples_; - double error_limit = 1E-05; double max_err; while (true) { @@ -84,7 +102,7 @@ std::vector VolumeCalculation::execute() const { for (const auto& result : results) { max_err = std::max(max_err, result.volume[1]); } // exit once we're below our error limit - if (max_err <= error_limit) { break; } + if (max_err <= error_trigger_) { break; } std::vector tmp = _execute(offset); offset += n_samples_; @@ -104,9 +122,9 @@ std::vector VolumeCalculation::_execute(size_t seed_o std::vector> master_hits(n); // Number of hits for each material in each domain // Divide work over MPI processes - int min_samples = n_samples_ / mpi::n_procs; - int remainder = n_samples_ % mpi::n_procs; - int i_start, i_end; + size_t min_samples = n_samples_ / mpi::n_procs; + size_t remainder = n_samples_ % mpi::n_procs; + size_t i_start, i_end; if (mpi::rank < remainder) { i_start = (min_samples + 1)*mpi::rank; i_end = i_start + min_samples + 1; @@ -126,7 +144,7 @@ std::vector VolumeCalculation::_execute(size_t seed_o // Sample locations and count hits #pragma omp for - for (int i = i_start; i < i_end; i++) { + for (size_t i = i_start; i < i_end; i++) { set_particle_seed(seed_offset + i); p.n_coord_ = 1;