From 201ca7fcb3cfe59409d8495e2f30910893cdac44 Mon Sep 17 00:00:00 2001 From: zoeprieto Date: Tue, 10 Sep 2024 14:52:28 -0500 Subject: [PATCH] option to split source particle list per batch --- include/openmc/settings.h | 17 ++++++------ openmc/settings.py | 29 ++++++++++++++------ src/settings.cpp | 25 +++++++++++------ src/simulation.cpp | 58 +++++++++++++++++++++++++++------------ 4 files changed, 86 insertions(+), 43 deletions(-) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 10ef8b0cd89..2dbe9e8d4db 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -60,7 +60,8 @@ extern bool source_mcpl_write; //!< write source in mcpl files? extern bool surf_source_write; //!< write surface source file? extern bool surf_mcpl_write; //!< write surface mcpl file? extern bool surf_source_read; //!< read surface source file? -extern bool info_surface_source; //!< write surface source message? +extern bool info_surface_source; //!< print surface source info? +extern bool split_file_per_batch; //!< create surface source file per batch? extern bool survival_biasing; //!< use survival biasing? extern bool temperature_multipole; //!< use multipole data? extern "C" bool trigger_on; //!< tally triggers enabled? @@ -134,12 +135,12 @@ extern int max_history_splits; //!< maximum number of particle splits for weight windows extern int64_t max_surface_particles; //!< maximum number of particles to be //!< banked on surfaces per process -extern int64_t max_files; //!< maximum number of particle files to be - //!< created -extern int64_t ssw_cell_id; //!< Cell id for the surface source - //!< write setting -extern SSWCellType ssw_cell_type; //!< Type of option for the cell - //!< argument of surface source write +extern int64_t n_surf_source_files; //!< number of surfaces source files to be + //!< created for the n last batches +extern int64_t ssw_cell_id; //!< Cell id for the surface source + //!< write setting +extern SSWCellType ssw_cell_type; //!< Type of option for the cell + //!< argument of surface source write extern TemperatureMethod temperature_method; //!< method for choosing temperatures extern double @@ -174,4 +175,4 @@ void free_memory_settings(); } // namespace openmc -#endif // OPENMC_SETTINGS_H +#endif // OPENMC_SETTINGS_H \ No newline at end of file diff --git a/openmc/settings.py b/openmc/settings.py index 54a9882c7ae..f5821fff2f0 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -207,8 +207,10 @@ class Settings: banked (int) :max_particles: Maximum number of particles to be banked on surfaces per process (int) - :max_files: Maximum number of particles list files (int) - :info_surface_source: write message with surface source info (bool) + :split_file_per_batch: create surface source file per batch (bool) + :n_surf_source_files: Number of surfaces source files to be created + for the n last batches (int) + :info_surface_source: print number of particle saved in surface source file (bool) :mcpl: Output in the form of an MCPL-file (bool) :cell: Cell ID used to determine if particles crossing identified surfaces are to be banked. Particles coming from or going to this @@ -716,7 +718,8 @@ def surf_source_write(self, surf_source_write: dict): cv.check_value( "surface source writing key", key, - ("surface_ids", "max_particles", "max_files", "info_surface_source", "mcpl", "cell", "cellfrom", "cellto"), + ("surface_ids", "max_particles", "split_file_per_batch", "n_surf_source_files", "info_surface_source", + "mcpl", "cell", "cellfrom", "cellto"), ) if key == "surface_ids": cv.check_type( @@ -726,12 +729,14 @@ def surf_source_write(self, surf_source_write: dict): cv.check_greater_than("surface id for source banking", surf_id, 0) elif key == "mcpl": cv.check_type("write to an MCPL-format file", value, bool) + elif key == "split_file_per_batch": + cv.check_type("create surface source file per batch", value, bool) elif key == "info_surface_source": cv.check_type("write message with surface source info", value, bool) - elif key in ("max_particles", "max_files", "cell", "cellfrom", "cellto"): + elif key in ("max_particles", "n_surf_source_files", "cell", "cellfrom", "cellto"): name = { "max_particles": "maximum particle banks on surfaces per process", - "max_files": "maximum source particle list files.", + "n_surf_source_files": "number of surfaces source files.", "cell": "Cell ID for source banking (from or to)", "cellfrom": "Cell ID for source banking (from only)", "cellto": "Cell ID for source banking (to only)", @@ -1248,10 +1253,13 @@ def _create_surf_source_write_subelement(self, root): if "mcpl" in self._surf_source_write: subelement = ET.SubElement(element, "mcpl") subelement.text = str(self._surf_source_write["mcpl"]).lower() + if "split_file_per_batch" in self._surf_source_write: + subelement = ET.SubElement(element, "split_file_per_batch") + subelement.text = str(self._surf_source_write["split_file_per_batch"]).lower() if "info_surface_source" in self._surf_source_write: subelement = ET.SubElement(element, "info_surface_source") subelement.text = str(self._surf_source_write["info_surface_source"]).lower() - for key in ("max_particles", "max_files", "cell", "cellfrom", "cellto"): + for key in ("max_particles", "n_surf_source_files", "cell", "cellfrom", "cellto"): if key in self._surf_source_write: subelement = ET.SubElement(element, key) subelement.text = str(self._surf_source_write[key]) @@ -1650,16 +1658,19 @@ def _surf_source_write_from_xml_element(self, root): elem = root.find('surf_source_write') if elem is None: return - for key in ('surface_ids', 'max_particles', 'max_files', 'info_surface_source', 'mcpl', 'cell', 'cellto', 'cellfrom'): + for key in ('surface_ids', 'max_particles', 'split_file_per_batch', 'n_surf_source_files', 'info_surface_source', + 'mcpl', 'cell', 'cellto', 'cellfrom'): value = get_text(elem, key) if value is not None: if key == 'surface_ids': value = [int(x) for x in value.split()] elif key == 'mcpl': value = value in ('true', '1') + elif key == 'split_file_per_batch': + value = value in ('true', '1') elif key == 'info_surface_source': value = value in ('true', '1') - elif key in ('max_particles', 'max_files', 'cell', 'cellfrom', 'cellto'): + elif key in ('max_particles', 'n_surf_source_files', 'cell', 'cellfrom', 'cellto'): value = int(value) self.surf_source_write[key] = value @@ -2098,4 +2109,4 @@ def from_xml(cls, path: PathLike = 'settings.xml'): tree = ET.parse(path, parser=parser) root = tree.getroot() meshes = _read_meshes(root) - return cls.from_xml_element(root, meshes) + return cls.from_xml_element(root, meshes) \ No newline at end of file diff --git a/src/settings.cpp b/src/settings.cpp index 2cf5efdfdec..65e62bcd48b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -79,6 +79,7 @@ bool weight_window_checkpoint_surface {false}; bool weight_window_checkpoint_collision {true}; bool write_all_tracks {false}; bool write_initial_source {false}; +bool split_file_per_batch {false}; bool info_surface_source {false}; std::string path_cross_sections; @@ -120,7 +121,7 @@ std::unordered_set sourcepoint_batch; std::unordered_set statepoint_batch; std::unordered_set source_write_surf_id; int64_t max_surface_particles; -int64_t max_files {1}; +int64_t n_surf_source_files {1}; int64_t ssw_cell_id {C_NONE}; SSWCellType ssw_cell_type {SSWCellType::None}; TemperatureMethod temperature_method {TemperatureMethod::NEAREST}; @@ -796,18 +797,26 @@ void read_settings_xml(pugi::xml_node root) } // Get maximum number of files per batch to be created - if (check_for_node(node_ssw, "max_files")) { - max_files = std::stoll(get_node_value(node_ssw, "max_files")); + if (check_for_node(node_ssw, "n_surf_source_files")) { + n_surf_source_files = + std::stoll(get_node_value(node_ssw, "n_surf_source_files")); // Make sure you have enough batchs - if (max_files > (n_batches - n_inactive)) { - fatal_error("The maximum number of particle files must to be higher " - "than the number of active simulated batchs."); + if (n_surf_source_files > (n_batches - n_inactive)) { + fatal_error("The number of surface source files must to be lower " + "than the number of active simulated batches."); } } + // Check if we want create surface source file per batch + if (check_for_node(node_ssw, "split_file_per_batch")) { + split_file_per_batch = + get_node_value_bool(node_ssw, "split_file_per_batch"); + } + // Check if we want to write info about surface source if (check_for_node(node_ssw, "info_surface_source")) { - info_surface_source = get_node_value_bool(node_ssw, "info_surface_source"); + info_surface_source = + get_node_value_bool(node_ssw, "info_surface_source"); } if (check_for_node(node_ssw, "mcpl")) { @@ -1151,4 +1160,4 @@ extern "C" int openmc_get_n_batches(int* n_batches, bool get_max_batches) return 0; } -} // namespace openmc +} // namespace openmc \ No newline at end of file diff --git a/src/simulation.cpp b/src/simulation.cpp index 1b233a93a0c..4d46cff1613 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -346,8 +346,10 @@ void initialize_batch() // Increment current batch ++simulation::current_batch; - simulation::surf_source_bank.clear(); - simulation::surf_source_bank.reserve(settings::max_surface_particles); + if(settings::split_file_per_batch){ + simulation::surf_source_bank.clear(); + simulation::surf_source_bank.reserve(settings::max_surface_particles); + } if (settings::run_mode == RunMode::FIXED_SOURCE) { if (settings::solver_type == SolverType::RANDOM_RAY && @@ -467,22 +469,42 @@ void finalize_batch() } // Write out surface source if requested. - if (settings::surf_source_write && - simulation::current_batch > (settings::n_batches - settings::max_files) && - simulation::current_batch > (settings::n_inactive)) { - auto filename = settings::path_output + "surface_source_batch_" + - std::to_string(simulation::current_batch); - auto surf_work_index = - mpi::calculate_parallel_index_vector(simulation::surf_source_bank.size()); - gsl::span surfbankspan(simulation::surf_source_bank.begin(), - simulation::surf_source_bank.size()); - if (settings::surf_mcpl_write) { - write_mcpl_source_point(filename.c_str(), surfbankspan, surf_work_index); - } else { - write_source_point(filename.c_str(), surfbankspan, surf_work_index); + if (settings::surf_source_write) { + if (simulation::current_batch == settings::n_batches && + settings::split_file_per_batch == false) { + auto filename = settings::path_output + "surface_source"; + auto surf_work_index = mpi::calculate_parallel_index_vector( + simulation::surf_source_bank.size()); + gsl::span surfbankspan(simulation::surf_source_bank.begin(), + simulation::surf_source_bank.size()); + if (settings::surf_mcpl_write) { + write_mcpl_source_point( + filename.c_str(), surfbankspan, surf_work_index); + } else { + write_source_point(filename.c_str(), surfbankspan, surf_work_index); + } } - if (settings::info_surface_source){ - write_message("Info surface source crossing {}/{}", simulation::surf_source_bank.size(), settings::n_particles); + else if (settings::split_file_per_batch && + simulation::current_batch > + (settings::n_batches - settings::n_surf_source_files)) + { + auto filename = settings::path_output + "surface_source_batch_" + + std::to_string(simulation::current_batch); + auto surf_work_index = mpi::calculate_parallel_index_vector( + simulation::surf_source_bank.size()); + gsl::span surfbankspan(simulation::surf_source_bank.begin(), + simulation::surf_source_bank.size()); + if (settings::surf_mcpl_write) { + write_mcpl_source_point( + filename.c_str(), surfbankspan, surf_work_index); + } else { + write_source_point(filename.c_str(), surfbankspan, surf_work_index); + } + if (settings::info_surface_source) { + write_message( + "Number of particles saved in the surface source file {}/{}", + simulation::surf_source_bank.size(), settings::n_particles); + } } } } @@ -848,4 +870,4 @@ void transport_event_based() } } -} // namespace openmc +} // namespace openmc \ No newline at end of file