diff --git a/include/openmc/particle.h b/include/openmc/particle.h index ee59d73014..2917b45e4a 100644 --- a/include/openmc/particle.h +++ b/include/openmc/particle.h @@ -34,9 +34,6 @@ namespace openmc { // use to store the bins for delayed group tallies. constexpr int MAX_DELAYED_GROUPS {8}; -// Maximum number of lost particles, relative to the total number of particles -constexpr double REL_MAX_LOST_PARTICLES {1.0e-6}; - constexpr double CACHE_INVALID {-1.0}; //============================================================================== diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 1dcdea3cc7..3407eadf4b 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -63,11 +63,12 @@ extern std::string path_source; extern std::string path_sourcepoint; //!< path to a source file extern "C" std::string path_statepoint; //!< path to a statepoint file -extern "C" int32_t n_batches; //!< number of (inactive+active) batches -extern "C" int32_t n_inactive; //!< number of inactive batches -extern "C" int32_t n_max_lost_particles; //!< maximum number of lost particles -extern "C" int32_t gen_per_batch; //!< number of generations per batch -extern "C" int64_t n_particles; //!< number of particles per generation +extern "C" int32_t n_batches; //!< number of (inactive+active) batches +extern "C" int32_t n_inactive; //!< number of inactive batches +extern "C" int32_t n_max_lost_particles; //!< maximum number of lost particles +extern double relative_max_lost_particles; //!< maximum number of lost particles, relative to the total number of particles +extern "C" int32_t gen_per_batch; //!< number of generations per batch +extern "C" int64_t n_particles; //!< number of particles per generation extern int64_t max_particles_in_flight; //!< Max num. event-based particles in flight diff --git a/openmc/lib/settings.py b/openmc/lib/settings.py index a25ccb962f..8345e00881 100644 --- a/openmc/lib/settings.py +++ b/openmc/lib/settings.py @@ -23,6 +23,7 @@ class _Settings(object): generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch') inactive = _DLLGlobal(c_int32, 'n_inactive') max_lost_particles = _DLLGlobal(c_int32, 'n_max_lost_particles') + rel_max_lost_particles = _DLLGlobal(c_double, 'relative_max_lost_particles') particles = _DLLGlobal(c_int64, 'n_particles') restart_run = _DLLGlobal(c_bool, 'restart_run') run_CE = _DLLGlobal(c_bool, 'run_CE') diff --git a/openmc/settings.py b/openmc/settings.py index 79e7719a3d..794c97b618 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -60,6 +60,8 @@ class Settings(object): Number of generations per batch max_lost_particles : int Maximum number of lost particles + rel_max_lost_particles : int + Maximum number of lost particles, relative to the total number of particles inactive : int Number of inactive batches keff_trigger : dict @@ -179,6 +181,7 @@ class Settings(object): self._generations_per_batch = None self._inactive = None self._max_lost_particles = None + self._rel_max_lost_particles = None self._particles = None self._keff_trigger = None @@ -261,6 +264,10 @@ class Settings(object): def max_lost_particles(self): return self._max_lost_particles + @property + def rel_max_lost_particles(self): + return self._rel_max_lost_particles + @property def particles(self): return self._particles @@ -430,6 +437,13 @@ class Settings(object): cv.check_greater_than('max_lost_particles', max_lost_particles, 0) self._max_lost_particles = max_lost_particles + @rel_max_lost_particles.setter + def rel_max_lost_particles(self, rel_max_lost_particles): + cv.check_type('rel_max_lost_particles', rel_max_lost_particles, Real) + cv.check_greater_than('rel_max_lost_particles', rel_max_lost_particles, 0) + cv.check_less_than('rel_max_lost_particles', rel_max_lost_particles, 1) + self._rel_max_lost_particles = rel_max_lost_particles + @particles.setter def particles(self, particles): cv.check_type('particles', particles, Integral) @@ -779,7 +793,12 @@ class Settings(object): def _create_max_lost_particles_subelement(self, root): if self._max_lost_particles is not None: element = ET.SubElement(root, "max_lost_particles") - element.text = str(self._max_lost_particles) + element.text = str(self._max_lost_particles) + + def _create_rel_max_lost_particles_subelement(self, root): + if self._rel_max_lost_particles is not None: + element = ET.SubElement(root, "rel_max_lost_particles") + element.text = str(self._rel_max_lost_particles) def _create_particles_subelement(self, root): if self._particles is not None: @@ -1028,6 +1047,7 @@ class Settings(object): self._batches_from_xml_element(elem) self._inactive_from_xml_element(elem) self._max_lost_particles_from_xml_element(elem) + self._rel_max_lost_particles_from_xml_element(elem) self._generations_per_batch_from_xml_element(elem) def _run_mode_from_xml_element(self, root): @@ -1053,7 +1073,12 @@ class Settings(object): def _max_lost_particles_from_xml_element(self, root): text = get_text(root, 'max_lost_particles') if text is not None: - self.max_lost_particles = int(text) + self.max_lost_particles = int(text) + + def _rel_max_lost_particles_from_xml_element(self, root): + text = get_text(root, 'rel_max_lost_particles') + if text is not None: + self.rel_max_lost_particles = float(text) def _generations_per_batch_from_xml_element(self, root): text = get_text(root, 'generations_per_batch') @@ -1295,6 +1320,7 @@ class Settings(object): self._create_batches_subelement(root_element) self._create_inactive_subelement(root_element) self._create_max_lost_particles_subelement(root_element) + self._create_rel_max_lost_particles_subelement(root_element) self._create_generations_per_batch_subelement(root_element) self._create_keff_trigger_subelement(root_element) self._create_source_subelement(root_element) @@ -1366,6 +1392,7 @@ class Settings(object): settings._batches_from_xml_element(root) settings._inactive_from_xml_element(root) settings._max_lost_particles_from_xml_element(root) + settings._rel_max_lost_particles_from_xml_element(root) settings._generations_per_batch_from_xml_element(root) settings._keff_trigger_from_xml_element(root) settings._source_from_xml_element(root) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 051195ec96..0d78bf68dc 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -79,6 +79,8 @@ class StatePoint(object): Number of inactive batches n_max_lost_particles : int Number of max lost particles + relative_max_lost_particles : float + Number of max lost particles, relative to the total number of particles n_particles : int Number of particles per generation n_realizations : int @@ -316,7 +318,11 @@ class StatePoint(object): @property def n_max_lost_particles(self): - return self._f['n_max_lost_particles'][()] + return self._f['n_max_lost_particles'][()] + + @property + def relative_max_lost_particles(self): + return self._f['relative_max_lost_particles'][()] @property def n_particles(self): diff --git a/src/particle.cpp b/src/particle.cpp index 8e66222048..79e6625771 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -164,8 +164,6 @@ Particle::event_calculate_xs() if (cell_born_ == C_NONE) cell_born_ = coord_[n_coord_ - 1].cell; } - std::cout << "settings::n_max_lost_particles " << settings::n_max_lost_particles << std::endl; - // Write particle track. if (write_track_) write_particle_track(*this); @@ -630,12 +628,10 @@ Particle::mark_as_lost(const char* message) auto n = simulation::current_batch * settings::gen_per_batch * simulation::work_per_rank; - std::cout << simulation::n_lost_particles << "HELLLOOOOOOOOOOOO MS DOUBTFIRE" << std::endl; - // Abort the simulation if the maximum number of lost particles has been // reached if (simulation::n_lost_particles >= settings::n_max_lost_particles && - simulation::n_lost_particles >= REL_MAX_LOST_PARTICLES*n) { + simulation::n_lost_particles >= settings::relative_max_lost_particles*n) { fatal_error("Maximum number of lost particles has been reached."); } } diff --git a/src/settings.cpp b/src/settings.cpp index 41a55501c2..d72e5f17f7 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -80,6 +80,7 @@ std::string path_statepoint; int32_t n_batches; int32_t n_inactive {0}; int32_t n_max_lost_particles {10}; +double relative_max_lost_particles {1.0e-6}; int32_t gen_per_batch {1}; int64_t n_particles {-1}; @@ -149,6 +150,11 @@ void get_run_parameters(pugi::xml_node node_base) n_max_lost_particles = std::stoi(get_node_value(node_base, "max_lost_particles")); } + // Get relative number of lost particles + if (check_for_node(node_base, "rel_max_lost_particles")) { + relative_max_lost_particles = std::stod(get_node_value(node_base, "rel_max_lost_particles")); + } + // Get number of inactive batches if (run_mode == RunMode::EIGENVALUE) { if (check_for_node(node_base, "inactive")) { @@ -358,7 +364,9 @@ void read_settings_xml() fatal_error("Number of particles must be greater than zero."); } else if (n_max_lost_particles <= 0) { fatal_error("Number of max lost particles must be greater than zero."); - } + } else if (relative_max_lost_particles <= 0.0 || relative_max_lost_particles >= 1.0) { + fatal_error("Relative max lost particles must be between zero and one."); + } } // Copy random number seed if specified