From 32bd64c157210891da916f23a130503e5951b6d3 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Mon, 24 Nov 2025 16:09:01 -0500 Subject: [PATCH 01/10] Add local adjoint source --- .../openmc/random_ray/flat_source_domain.h | 5 +- .../openmc/random_ray/random_ray_simulation.h | 7 +- openmc/settings.py | 8 ++ src/random_ray/flat_source_domain.cpp | 17 ++- src/random_ray/random_ray_simulation.cpp | 128 +++++++++++------- src/settings.cpp | 11 +- src/source.cpp | 2 + 7 files changed, 119 insertions(+), 59 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 9fdd5587508..3d167d0b148 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -39,9 +39,10 @@ class FlatSourceDomain { void random_ray_tally(); virtual void accumulate_iteration_flux(); void output_to_vtk() const; - void convert_external_sources(); + void convert_external_sources(bool use_adjoint_sources); void count_external_source_regions(); - void set_adjoint_sources(const vector& forward_flux); + void set_global_adjoint_sources(const vector& forward_flux); + void set_local_adjoint_sources(); void flux_swap(); virtual double evaluate_flux_at_point(Position r, int64_t sr, int g) const; double compute_fixed_source_normalization_factor() const; diff --git a/include/openmc/random_ray/random_ray_simulation.h b/include/openmc/random_ray/random_ray_simulation.h index b94e7401b3e..637098eadd0 100644 --- a/include/openmc/random_ray/random_ray_simulation.h +++ b/include/openmc/random_ray/random_ray_simulation.h @@ -21,7 +21,12 @@ class RandomRaySimulation { // Methods void compute_segment_correction_factors(); void apply_fixed_sources_and_mesh_domains(); - void prepare_fixed_sources_adjoint(vector& forward_flux, + void prepare_global_fixed_sources_adjoint(vector& forward_flux, + SourceRegionContainer& forward_source_regions, + SourceRegionContainer& forward_base_source_regions, + std::unordered_map& + forward_source_region_map); + void prepare_local_fixed_sources_adjoint( SourceRegionContainer& forward_source_regions, SourceRegionContainer& forward_base_source_regions, std::unordered_map& diff --git a/openmc/settings.py b/openmc/settings.py index a2bf51a51e5..4a254a44695 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -198,6 +198,9 @@ class Settings: stabilization, which may be desirable as stronger diagonal stabilization also tends to dampen the convergence rate of the solver, thus requiring more iterations to converge. + :adjoint_source: + Source object used to define localized adjoint source/detector response + function. .. versionadded:: 0.15.0 resonance_scattering : dict @@ -1192,6 +1195,8 @@ def random_ray(self, random_ray: dict): cv.check_type('diagonal stabilization rho', value, Real) cv.check_greater_than('diagonal stabilization rho', value, 0.0, True) + elif key == 'adjoint_source': + cv.check_type('adjoint source', value, SourceBase) else: raise ValueError(f'Unable to set random ray to "{key}" which is ' 'unsupported by OpenMC') @@ -1656,6 +1661,9 @@ def _create_random_ray_subelement(self, root, mesh_memo=None): if mesh_memo is not None and mesh.id not in mesh_memo: root.append(mesh.to_xml_element()) mesh_memo.add(mesh.id) + elif key == 'adjoint_source' and isinstance(value, SourceBase): + adj_source_element = value.to_xml_element() + element.append(adj_source_element) else: subelement = ET.SubElement(element, key) subelement.text = str(value) diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 8ab30abf207..c6bbb94678a 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -1019,13 +1019,17 @@ void FlatSourceDomain::count_external_source_regions() } } -void FlatSourceDomain::convert_external_sources() +void FlatSourceDomain::convert_external_sources(bool use_adjoint_sources) { + // Determine whether forward or (local) adjoint sources are desired + const auto& sources = use_adjoint_sources ? + model::adjoint_sources : model::external_sources; + // Loop over external sources - for (int es = 0; es < model::external_sources.size(); es++) { + for (int es = 0; es < sources.size(); es++) { // Extract source information - Source* s = model::external_sources[es].get(); + Source* s = sources[es].get(); IndependentSource* is = dynamic_cast(s); Discrete* energy = dynamic_cast(is->energy()); const std::unordered_set& domain_ids = is->domain_ids(); @@ -1180,7 +1184,7 @@ void FlatSourceDomain::flatten_xs() } } -void FlatSourceDomain::set_adjoint_sources(const vector& forward_flux) +void FlatSourceDomain::set_global_adjoint_sources(const vector& forward_flux) { // Set the external source to 1/forward_flux. If the forward flux is negative // or zero, set the adjoint source to zero, as this is likely a very small @@ -1218,6 +1222,11 @@ void FlatSourceDomain::set_adjoint_sources(const vector& forward_flux) } } +void FlatSourceDomain::set_local_adjoint_sources() +{ + // Set the external source to user-specified adjoint sources. + convert_external_sources(true); + void FlatSourceDomain::transpose_scattering_matrix() { // Transpose the inner two dimensions for each material diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index b831efcd99a..7d5e73a350a 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -28,69 +28,75 @@ void openmc_run_random_ray() // Run forward simulation ////////////////////////////////////////////////////////// - // Check if adjoint calculation is needed. If it is, we will run the forward - // calculation first and then the adjoint calculation later. + // Check if adjoint calculation is needed, and if local adjoint source(s) + // are present. If an adjoint calculation is needed and no sources are + // specified, we will run a forward calculation first to calculate adjoint + // sources for global variance reduction, then perform an adjoint + // calculation later. bool adjoint_needed = FlatSourceDomain::adjoint_; + bool global_adjoint = model::adjoint_sources.empty(); - // Configure the domain for forward simulation - FlatSourceDomain::adjoint_ = false; + // If we're going to do an adjoint simulation with global adjoint sources + // afterwards, report that this is the initial forward flux solve. + if (!adjoint_needed || global_adjoint) { + // Configure the domain for forward simulation + FlatSourceDomain::adjoint_ = false; - // If we're going to do an adjoint simulation afterwards, report that this is - // the initial forward flux solve. - if (adjoint_needed && mpi::master) - header("FORWARD FLUX SOLVE", 3); + if (mpi::master) + header("FORWARD FLUX SOLVE", 3); - // Initialize OpenMC general data structures - openmc_simulation_init(); + // Initialize OpenMC general data structures + openmc_simulation_init(); - // Validate that inputs meet requirements for random ray mode - if (mpi::master) - validate_random_ray_inputs(); + // Validate that inputs meet requirements for random ray mode + if (mpi::master) + validate_random_ray_inputs(); - // Declare forward flux so that it can be saved for later adjoint simulation - vector forward_flux; - SourceRegionContainer forward_source_regions; - SourceRegionContainer forward_base_source_regions; - std::unordered_map - forward_source_region_map; + // Declare forward flux so that it can be saved for later adjoint simulation + vector forward_flux; + SourceRegionContainer forward_source_regions; + SourceRegionContainer forward_base_source_regions; + std::unordered_map + forward_source_region_map; - { - // Initialize Random Ray Simulation Object - RandomRaySimulation sim; + { + // Initialize Random Ray Simulation Object + RandomRaySimulation sim; - // Initialize fixed sources, if present - sim.apply_fixed_sources_and_mesh_domains(); + // Initialize fixed sources, if present + sim.apply_fixed_sources_and_mesh_domains(); - // Begin main simulation timer - simulation::time_total.start(); + // Begin main simulation timer + simulation::time_total.start(); - // Execute random ray simulation - sim.simulate(); + // Execute random ray simulation + sim.simulate(); - // End main simulation timer - simulation::time_total.stop(); + // End main simulation timer + simulation::time_total.stop(); - // Normalize and save the final forward flux - sim.domain()->serialize_final_fluxes(forward_flux); + // Normalize and save the final forward flux + sim.domain()->serialize_final_fluxes(forward_flux); - double source_normalization_factor = - sim.domain()->compute_fixed_source_normalization_factor() / - (settings::n_batches - settings::n_inactive); + double source_normalization_factor = + sim.domain()->compute_fixed_source_normalization_factor() / + (settings::n_batches - settings::n_inactive); #pragma omp parallel for - for (uint64_t i = 0; i < forward_flux.size(); i++) { - forward_flux[i] *= source_normalization_factor; - } + for (uint64_t i = 0; i < forward_flux.size(); i++) { + forward_flux[i] *= source_normalization_factor; + } - forward_source_regions = sim.domain()->source_regions_; - forward_source_region_map = sim.domain()->source_region_map_; - forward_base_source_regions = sim.domain()->base_source_regions_; + forward_source_regions = sim.domain()->source_regions_; + forward_source_region_map = sim.domain()->source_region_map_; + forward_base_source_regions = sim.domain()->base_source_regions_; - // Finalize OpenMC - openmc_simulation_finalize(); + // Finalize OpenMC + openmc_simulation_finalize(); - // Output all simulation results - sim.output_simulation_results(); + // Output all simulation results + sim.output_simulation_results(); + } } ////////////////////////////////////////////////////////// @@ -113,9 +119,14 @@ void openmc_run_random_ray() RandomRaySimulation adjoint_sim; // Initialize adjoint fixed sources, if present - adjoint_sim.prepare_fixed_sources_adjoint(forward_flux, - forward_source_regions, forward_base_source_regions, - forward_source_region_map); + if (global_adjoint) { + adjoint_sim.prepare_global_fixed_sources_adjoint(forward_flux, + forward_source_regions, forward_base_source_regions, + forward_source_region_map); + } else { + adjoint_sim.prepare_local_fixed_sources_adjoint(forward_source_regions, + forward_base_source_regions,forward_source_region_map); + } // Transpose scattering matrix adjoint_sim.domain()->transpose_scattering_matrix(); @@ -412,7 +423,7 @@ void RandomRaySimulation::apply_fixed_sources_and_mesh_domains() } } -void RandomRaySimulation::prepare_fixed_sources_adjoint( +void RandomRaySimulation::prepare_global_fixed_sources_adjoint( vector& forward_flux, SourceRegionContainer& forward_source_regions, SourceRegionContainer& forward_base_source_regions, std::unordered_map& @@ -425,7 +436,24 @@ void RandomRaySimulation::prepare_fixed_sources_adjoint( domain_->base_source_regions_ = forward_base_source_regions; domain_->source_regions_.adjoint_reset(); } - domain_->set_adjoint_sources(forward_flux); + domain_->set_global_adjoint_sources(forward_flux); + } +} + +void RandomRaySimulation::prepare_local_fixed_sources_adjoint( + SourceRegionContainer& forward_source_regions, + SourceRegionContainer& forward_base_source_regions, + std::unordered_map& + forward_source_region_map) +{ + if (settings::run_mode == RunMode::FIXED_SOURCE) { + if (RandomRay::mesh_subdivision_enabled_) { + domain_->source_regions_ = forward_source_regions; + domain_->source_region_map_ = forward_source_region_map; + domain_->base_source_regions_ = forward_base_source_regions; + domain_->source_regions_.adjoint_reset(); + } + domain_->set_local_adjoint_sources(); } } diff --git a/src/settings.cpp b/src/settings.cpp index 53fcdec38b3..bdd838c3791 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -266,8 +266,9 @@ void get_run_parameters(pugi::xml_node node_base) } else { fatal_error("Specify random ray inactive distance in settings XML"); } - if (check_for_node(random_ray_node, "source")) { - xml_node source_node = random_ray_node.child("source"); + if (check_for_node(random_ray_node, "ray_source")) { + xml_node ray_source_node = random_ray_node.child("ray_source"); + xml_node source_node = ray_source_node.child("source"); // Get point to list of elements and make sure there is at least // one RandomRay::ray_source_ = Source::create(source_node); @@ -354,6 +355,12 @@ void get_run_parameters(pugi::xml_node node_base) "between 0 and 1"); } } + + for (pugi::xml_node adj_source_node : random_ray_node.children("adjoint_source")) { + // Find any local adjoint sources + xml_node source_node = adj_source_node.child("source"); + model::adjoint_sources.push_back(Source::create(source_node)); + } } } diff --git a/src/source.cpp b/src/source.cpp index c1b4ce260a3..ab4f22730ed 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -45,6 +45,8 @@ namespace model { vector> external_sources; +vector> adjoint_sources; + DiscreteIndex external_sources_probability; } // namespace model From b1c39a64a1aabb231a53fe02ace3d01377157925 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Wed, 7 Jan 2026 12:45:27 -0500 Subject: [PATCH 02/10] local adjoint init --- include/openmc/source.h | 1 + openmc/settings.py | 16 ++++++++++++---- src/random_ray/flat_source_domain.cpp | 1 + src/random_ray/random_ray_simulation.cpp | 16 ++++++++-------- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 6733eaeffca..95289637d3c 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -35,6 +35,7 @@ class Source; namespace model { extern vector> external_sources; +extern vector> adjoint_sources; // Probability distribution for selecting external sources extern DiscreteIndex external_sources_probability; diff --git a/openmc/settings.py b/openmc/settings.py index 4a254a44695..e2a4a7075ec 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1647,8 +1647,9 @@ def _create_random_ray_subelement(self, root, mesh_memo=None): element = ET.SubElement(root, "random_ray") for key, value in self._random_ray.items(): if key == 'ray_source' and isinstance(value, SourceBase): + subelement = ET.SubElement(element, 'ray_source') source_element = value.to_xml_element() - element.append(source_element) + subelement.append(source_element) elif key == 'source_region_meshes': subelement = ET.SubElement(element, 'source_region_meshes') for mesh, domains in value: @@ -1662,8 +1663,9 @@ def _create_random_ray_subelement(self, root, mesh_memo=None): root.append(mesh.to_xml_element()) mesh_memo.add(mesh.id) elif key == 'adjoint_source' and isinstance(value, SourceBase): + subelement = ET.SubElement(element, 'adjoint_source') adj_source_element = value.to_xml_element() - element.append(adj_source_element) + subelement.append(adj_source_element) else: subelement = ET.SubElement(element, key) subelement.text = str(value) @@ -2043,8 +2045,9 @@ def _random_ray_from_xml_element(self, root): for child in elem: if child.tag in ('distance_inactive', 'distance_active', 'diagonal_stabilization_rho'): self.random_ray[child.tag] = float(child.text) - elif child.tag == 'source': - source = SourceBase.from_xml_element(child) + elif child.tag == 'ray_source': + source_element = child.find('source') + source = SourceBase.from_xml_element(source_element) self.random_ray['ray_source'] = source elif child.tag == 'volume_estimator': self.random_ray['volume_estimator'] = child.text @@ -2058,6 +2061,11 @@ def _random_ray_from_xml_element(self, root): self.random_ray['adjoint'] = ( child.text in ('true', '1') ) + elif child.tag == 'adjoint_source': + for subelem in child.findall('source'): + src = SourceBase.from_xml_element(subelem) + # add newly constructed source object to the list + self.random_ray['adjoint_source'].append(src) elif child.tag == 'sample_method': self.random_ray['sample_method'] = child.text elif child.tag == 'source_region_meshes': diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index c6bbb94678a..4c7015ea8f9 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -1226,6 +1226,7 @@ void FlatSourceDomain::set_local_adjoint_sources() { // Set the external source to user-specified adjoint sources. convert_external_sources(true); +} void FlatSourceDomain::transpose_scattering_matrix() { diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 7d5e73a350a..e69cd21aa42 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -36,6 +36,13 @@ void openmc_run_random_ray() bool adjoint_needed = FlatSourceDomain::adjoint_; bool global_adjoint = model::adjoint_sources.empty(); + // Declare forward flux so that it can be saved for either simulation + vector forward_flux; + SourceRegionContainer forward_source_regions; + SourceRegionContainer forward_base_source_regions; + std::unordered_map + forward_source_region_map; + // If we're going to do an adjoint simulation with global adjoint sources // afterwards, report that this is the initial forward flux solve. if (!adjoint_needed || global_adjoint) { @@ -52,13 +59,6 @@ void openmc_run_random_ray() if (mpi::master) validate_random_ray_inputs(); - // Declare forward flux so that it can be saved for later adjoint simulation - vector forward_flux; - SourceRegionContainer forward_source_regions; - SourceRegionContainer forward_base_source_regions; - std::unordered_map - forward_source_region_map; - { // Initialize Random Ray Simulation Object RandomRaySimulation sim; @@ -418,7 +418,7 @@ void RandomRaySimulation::apply_fixed_sources_and_mesh_domains() domain_->apply_meshes(); if (settings::run_mode == RunMode::FIXED_SOURCE) { // Transfer external source user inputs onto random ray source regions - domain_->convert_external_sources(); + domain_->convert_external_sources(false); domain_->count_external_source_regions(); } } From 30cd00208c01b73ae345d47233c8ba1ed98ae3b2 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Fri, 9 Jan 2026 13:52:54 -0500 Subject: [PATCH 03/10] Added forward-weighted adjoint sources from @jtramm --- include/openmc/constants.h | 5 + .../openmc/random_ray/flat_source_domain.h | 50 +++--- include/openmc/weight_windows.h | 3 +- openmc/weight_windows.py | 8 +- src/random_ray/flat_source_domain.cpp | 163 ++++++++++++++++-- src/weight_windows.cpp | 7 + 6 files changed, 191 insertions(+), 45 deletions(-) diff --git a/include/openmc/constants.h b/include/openmc/constants.h index 2a7ce199046..16b9cdc86a8 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -63,6 +63,11 @@ constexpr int MAX_SAMPLE {100000}; // source region in the random ray solver constexpr double MIN_HITS_PER_BATCH {1.5}; +// The minimum flux value to be considered non-zero when computing adjoint +// sources. Positive values below this cutoff will be treated as zero, so as to +// prevent extremely large adjoint source terms from being generated. +constexpr double ZERO_FLUX_CUTOFF {1e-22}; + // ============================================================================ // MATH AND PHYSICAL CONSTANTS diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 3d167d0b148..d344c7f9efa 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -27,21 +27,22 @@ class FlatSourceDomain { //---------------------------------------------------------------------------- // Methods - virtual void update_neutron_source(double k_eff); - double compute_k_eff(double k_eff_old) const; + virtual void update_single_neutron_source(SourceRegionHandle& srh); + virtual void update_all_neutron_sources(); + void compute_k_eff(); virtual void normalize_scalar_flux_and_volumes( double total_active_distance_per_iteration); int64_t add_source_to_scalar_flux(); virtual void batch_reset(); - void convert_source_regions_to_tallies(); + void convert_source_regions_to_tallies(int64_t start_sr_id); void reset_tally_volumes(); void random_ray_tally(); virtual void accumulate_iteration_flux(); void output_to_vtk() const; void convert_external_sources(bool use_adjoint_sources); void count_external_source_regions(); - void set_global_adjoint_sources(const vector& forward_flux); + void set_fw_adjoint_sources(const vector& forward_flux); void set_local_adjoint_sources(); void flux_swap(); virtual double evaluate_flux_at_point(Position r, int64_t sr, int g) const; @@ -55,9 +56,8 @@ class FlatSourceDomain { bool is_target_void); void apply_mesh_to_cell_and_children(int32_t i_cell, int32_t mesh_idx, int32_t target_material_id, bool is_target_void); - void prepare_base_source_regions(); SourceRegionHandle get_subdivided_source_region_handle( - int64_t sr, int mesh_bin, Position r, double dist, Direction u); + SourceRegionKey sr_key, Position r, Direction u); void finalize_discovered_source_regions(); void apply_transport_stabilization(); int64_t n_source_regions() const @@ -68,11 +68,16 @@ class FlatSourceDomain { { return source_regions_.n_source_regions() * negroups_; } + int64_t lookup_base_source_region_idx(const GeometryState& p) const; + SourceRegionKey lookup_source_region_key(const GeometryState& p) const; + int64_t lookup_mesh_bin(int64_t sr, Position r) const; + int lookup_mesh_idx(int64_t sr) const; //---------------------------------------------------------------------------- // Static Data members static bool volume_normalized_flux_tallies_; static bool adjoint_; // If the user wants outputs based on the adjoint flux + static bool cadis_; static double diagonal_stabilization_rho_; // Adjusts strength of diagonal stabilization // for transport corrected MGXS data @@ -87,6 +92,7 @@ class FlatSourceDomain { //---------------------------------------------------------------------------- // Public Data members + double k_eff_ {1.0}; // Eigenvalue bool mapped_all_tallies_ {false}; // If all source regions have been visited int64_t n_external_source_regions_ {0}; // Total number of source regions with @@ -111,14 +117,6 @@ class FlatSourceDomain { // The abstract container holding all source region-specific data SourceRegionContainer source_regions_; - // Base source region container. When source region subdivision via mesh - // is in use, this container holds the original (non-subdivided) material - // filled cell instance source regions. These are useful as they can be - // initialized with external source and mesh domain information ahead of time. - // Then, dynamically discovered source regions can be initialized by cloning - // their base region. - SourceRegionContainer base_source_regions_; - // Parallel hash map holding all source regions discovered during // a single iteration. This is a threadsafe data structure that is cleaned // out after each iteration and stored in the "source_regions_" container. @@ -135,8 +133,17 @@ class FlatSourceDomain { // Map that relates a SourceRegionKey to the external source index. This map // is used to check if there are any point sources within a subdivided source // region at the time it is discovered. - std::unordered_map - point_source_map_; + std::unordered_map, SourceRegionKey::HashFunctor> + external_point_source_map_; + + // Map that relates a base source region index to the external source index. + // This map is used to check if there are any volumetric sources within a + // subdivided source region at the time it is discovered. + std::unordered_map> external_volumetric_source_map_; + + // Map that relates a base source region index to a mesh index. This map + // is used to check which subdivision mesh is present in a source region. + std::unordered_map mesh_map_; // If transport corrected MGXS data is being used, there may be negative // in-group scattering cross sections that can result in instability in MOC @@ -148,12 +155,11 @@ class FlatSourceDomain { //---------------------------------------------------------------------------- // Methods void apply_external_source_to_source_region( - Discrete* discrete, double strength_factor, SourceRegionHandle& srh); - void apply_external_source_to_cell_instances(int32_t i_cell, - Discrete* discrete, double strength_factor, int target_material_id, - const vector& instances); - void apply_external_source_to_cell_and_children(int32_t i_cell, - Discrete* discrete, double strength_factor, int32_t target_material_id); + int src_idx, SourceRegionHandle& srh); + void apply_external_source_to_cell_instances(int32_t i_cell, int src_idx, + int target_material_id, const vector& instances); + void apply_external_source_to_cell_and_children( + int32_t i_cell, int src_idx, int32_t target_material_id); virtual void set_flux_to_flux_plus_source(int64_t sr, double volume, int g); void set_flux_to_source(int64_t sr, int g); virtual void set_flux_to_old_flux(int64_t sr, int g); diff --git a/include/openmc/weight_windows.h b/include/openmc/weight_windows.h index 6f2ef07079f..6939e8ac60a 100644 --- a/include/openmc/weight_windows.h +++ b/include/openmc/weight_windows.h @@ -17,7 +17,7 @@ namespace openmc { -enum class WeightWindowUpdateMethod { MAGIC, FW_CADIS }; +enum class WeightWindowUpdateMethod { MAGIC, FW_CADIS, CADIS }; //============================================================================== // Constants @@ -71,6 +71,7 @@ struct WeightWindow { { lower_weight *= factor; upper_weight *= factor; + survival_weight *= factor; } }; diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index d52b81925aa..d7425d5c4e5 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -670,7 +670,7 @@ class WeightWindowGenerator: maximum and minimum energy for the data available at runtime. particle_type : {'neutron', 'photon'} Particle type the weight windows apply to - method : {'magic', 'fw_cadis'} + method : {'magic', 'fw_cadis', 'cadis'} The weight window generation methodology applied during an update. max_realizations : int The upper limit for number of tally realizations when generating weight @@ -775,7 +775,7 @@ def method(self) -> str: @method.setter def method(self, m: str): cv.check_type('generation method', m, str) - cv.check_value('generation method', m, ('magic', 'fw_cadis')) + cv.check_value('generation method', m, ('magic', 'fw_cadis', 'cadis')) self._method = m if self._update_parameters is not None: try: @@ -808,7 +808,7 @@ def update_parameters(self) -> dict: return self._update_parameters def _check_update_parameters(self, params: dict): - if self.method == 'magic' or self.method == 'fw_cadis': + if self.method == 'magic' or self.method == 'fw_cadis' or self.method == 'cadis': check_params = self._MAGIC_PARAMS for key, val in params.items(): @@ -851,7 +851,7 @@ def _sanitize_update_parameters(cls, method: str, update_parameters: dict): update_parameters : dict The update parameters as-read from the XML node (keys: str, values: str) """ - if method == 'magic' or method == 'fw_cadis': + if method == 'magic' or method == 'fw_cadis' or method == 'cadis': check_params = cls._MAGIC_PARAMS for param, param_type in check_params.items(): diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 4c7015ea8f9..5678f70ee6b 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -30,6 +30,7 @@ RandomRayVolumeEstimator FlatSourceDomain::volume_estimator_ { RandomRayVolumeEstimator::HYBRID}; bool FlatSourceDomain::volume_normalized_flux_tallies_ {false}; bool FlatSourceDomain::adjoint_ {false}; +bool FlatSourceDomain::cadis_ {false}; double FlatSourceDomain::diagonal_stabilization_rho_ {1.0}; std::unordered_map>> FlatSourceDomain::mesh_domain_map_; @@ -1184,42 +1185,168 @@ void FlatSourceDomain::flatten_xs() } } -void FlatSourceDomain::set_global_adjoint_sources(const vector& forward_flux) +void FlatSourceDomain::set_fw_adjoint_sources(const vector& forward_flux) { - // Set the external source to 1/forward_flux. If the forward flux is negative - // or zero, set the adjoint source to zero, as this is likely a very small - // source region that we don't need to bother trying to vector particles - // towards. Flux negativity in random ray is not related to the flux being - // small in magnitude, but rather due to the source region being physically - // small in volume and thus having a noisy flux estimate. + // Set the adjoint external source to 1/forward_flux. If the forward flux is + // negative, zero, or extremely close to zero, set the adjoint source to zero, + // as this is likely a very small source region that we don't need to bother + // trying to vector particles towards. In the case of flux "being extremely + // close to zero", we define this as being a fixed fraction of the maximum + // forward flux, below which we assume the flux would be physically + // undetectable. + + // First, find the maximum forward flux value + double max_flux = 0.0; +#pragma omp parallel for reduction(max : max_flux) + for (int64_t se = 0; se < n_source_elements(); se++) { + double flux = source_regions_.scalar_flux_final(se); + if (flux > max_flux) { + max_flux = flux; + } + } + + // Then, compute the adjoint source for each source region #pragma omp parallel for for (int64_t sr = 0; sr < n_source_regions(); sr++) { for (int g = 0; g < negroups_; g++) { - double flux = forward_flux[sr * negroups_ + g]; - if (flux <= 0.0) { + double flux = source_regions_.scalar_flux_final(sr, g); + if (flux <= ZERO_FLUX_CUTOFF * max_flux) { source_regions_.external_source(sr, g) = 0.0; } else { source_regions_.external_source(sr, g) = 1.0 / flux; + if (!std::isfinite(source_regions_.external_source(sr, g))) { + // If the flux is NaN or Inf, set the adjoint source to zero + source_regions_.external_source(sr, g) = 0.0; + } } if (flux > 0.0) { source_regions_.external_source_present(sr) = 1; } + source_regions_.scalar_flux_final(sr, g) = 0.0; } } - // Divide the fixed source term by sigma t (to save time when applying each - // iteration) + // "Small" source regions in OpenMC are defined as those that are hit by + // MIN_HITS_PER_BATCH rays or fewer each batch. These regions typically have + // very small volumes combined with a low aspect ratio, and are often + // generated when applying a source region mesh that clips the edge of a + // curved surface. As perhaps only a few rays will visit these regions over + // the entire forward simulation, the forward flux estimates are extremely + // noisy and unreliable. In some cases, the noise may make the forward fluxes + // extremely low, leading to unphysically large adjoint source terms, + // resulting in weight windows that aggressively try to drive particles + // towards these regions. To fix this, we simply filter out any "small" source + // regions from consideration. If a source region is "small", we + // set its adjoint source to zero. This adds negligible bias to the adjoint + // flux solution, as the true total adjoint source contribution from small + // regions is likely to be negligible. + if (!cadis_) { #pragma omp parallel for - for (int64_t sr = 0; sr < n_source_regions(); sr++) { - int material = source_regions_.material(sr); - if (material == MATERIAL_VOID) { - continue; + for (int64_t sr = 0; sr < n_source_regions(); sr++) { + if (source_regions_.is_small(sr)) { + for (int g = 0; g < negroups_; g++) { + source_regions_.external_source(sr, g) = 0.0; + } + source_regions_.external_source_present(sr) = 0; + } } - for (int g = 0; g < negroups_; g++) { - double sigma_t = sigma_t_[material * negroups_ + g]; - source_regions_.external_source(sr, g) /= sigma_t; + + // Divide the fixed source term by sigma t (to save time when applying each + // iteration) +#pragma omp parallel for + for (int64_t sr = 0; sr < n_source_regions(); sr++) { + int material = source_regions_.material(sr); + if (material == MATERIAL_VOID) { + continue; + } + for (int g = 0; g < negroups_; g++) { + double sigma_t = sigma_t_[material * negroups_ + g]; + source_regions_.external_source(sr, g) /= sigma_t; + if (!std::isfinite(source_regions_.external_source(sr, g))) { + // If the flux is NaN or Inf, set the adjoint source to zero + source_regions_.external_source(sr, g) = 0.0; + } + } } } + + if (cadis_) { +// Only external sources that have a non-mesh type tally task should remain +// non-zero. Everything else gets zero'd out. +#pragma omp parallel for + for (int64_t sr = 0; sr < n_source_regions(); sr++) { + + // If there is already no external source, don't need to do anything + if (source_regions_.external_source_present(sr) == 0) { + continue; + } + + // If there is an adjoint source term here, then we need to check it. + + // We will track if ANY group has a valid CADIS source term + bool has_any_sources = false; + + // Now, loop over groups + for (int g = 0; g < negroups_; g++) { + + // If there are no tally tasks associated with this source element + // then it is not a CADIS source, so we continue to the next group + if (source_regions_.tally_task(sr, g).empty()) { + source_regions_.external_source(sr, g) = 0.0; + continue; + } + + // If there are tally tasks, we can through them and check if + // any of them have a non-mesh filter type. + + // We track if ANY of the tasks have a non-mesh filter + bool has_non_mesh_filter = false; + + // Now we loop through + for (const auto& task : source_regions_.tally_task(sr, g)) { + Tally& tally {*model::tallies[task.tally_idx]}; + auto filter_types = tally.filter_types(); + + // For each tally, we loop through the filter types array. + // If any of them have a CADIS-compatible filter type, + // then this source element is a valid CADIS source + for (const auto& filter_type : filter_types) { + if (filter_type == FilterType::CELL || + filter_type == FilterType::CELL_INSTANCE || + filter_type == FilterType::DISTRIBCELL || + filter_type == FilterType::UNIVERSE || + filter_type == FilterType::MATERIAL) { + has_non_mesh_filter = true; + break; + } + } + } + + // If ANY of the tasks has a non-mesh filter type, + // Then we keep the source term and set that this + // source region has a valid CADIS source term. + // Otherwise, we zero out the source term. + if (has_non_mesh_filter) { + has_any_sources = true; + // print external source term + fmt::print("External source term for source region {} group {}: {}\n", + sr, g, source_regions_.external_source(sr, g)); + } else { + source_regions_.external_source(sr, g) = 0.0; + } + } // End loop over groups + + // If there were any valid CADIS source terms for any + // of the groups, then the SR as a whole counts as a source + if (has_any_sources) { + source_regions_.external_source_present(sr) = 1; + } else { + source_regions_.external_source_present(sr) = 0; + } + } // End loop over source regions + } // End CADIS logic +} + } void FlatSourceDomain::set_local_adjoint_sources() diff --git a/src/weight_windows.cpp b/src/weight_windows.cpp index 0efa5a6aeee..1022ee71b2f 100644 --- a/src/weight_windows.cpp +++ b/src/weight_windows.cpp @@ -806,6 +806,13 @@ WeightWindowsGenerator::WeightWindowsGenerator(pugi::xml_node node) fatal_error("FW-CADIS can only be run in random ray solver mode."); } FlatSourceDomain::adjoint_ = true; + } else if (method_string == "cadis") { + method_ = WeightWindowUpdateMethod::CADIS; + if (settings::solver_type != SolverType::RANDOM_RAY) { + fatal_error("CADIS can only be run in random ray solver mode."); + } + FlatSourceDomain::adjoint_ = true; + FlatSourceDomain::cadis_ = true; } else { fatal_error(fmt::format( "Unknown weight window update method '{}' specified", method_string)); From 767fa791df5d667543e20431c0c1243e112b22d1 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Thu, 15 Jan 2026 12:38:42 -0500 Subject: [PATCH 04/10] Use single simulation for fwd/adjoint transport --- .../openmc/random_ray/random_ray_simulation.h | 2 +- src/random_ray/random_ray_simulation.cpp | 129 +++++++++--------- 2 files changed, 68 insertions(+), 63 deletions(-) diff --git a/include/openmc/random_ray/random_ray_simulation.h b/include/openmc/random_ray/random_ray_simulation.h index 832a8436085..c783f8ce5f8 100644 --- a/include/openmc/random_ray/random_ray_simulation.h +++ b/include/openmc/random_ray/random_ray_simulation.h @@ -21,7 +21,7 @@ class RandomRaySimulation { // Methods void compute_segment_correction_factors(); void apply_fixed_sources_and_mesh_domains(); - void prepare_global_fixed_sources_adjoint(); + void prepare_fw_fixed_sources_adjoint(); void prepare_local_fixed_sources_adjoint(); void simulate(); void output_simulation_results() const; diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 6b70785cd14..d45c9aeca02 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -34,57 +34,60 @@ void openmc_run_random_ray() // sources for global variance reduction, then perform an adjoint // calculation later. bool adjoint_needed = FlatSourceDomain::adjoint_; - bool global_adjoint = model::adjoint_sources.empty(); + bool fw_adjoint = model::adjoint_sources.empty() && adjoint_needed; - // If we're going to do an adjoint simulation with global adjoint sources - // afterwards, report that this is the initial forward flux solve. - if (!adjoint_needed || global_adjoint) { + // If we're going to do an adjoint simulation with forward-weighted adjoint + // sources afterwards, report that this is the initial forward flux solve. + if (!adjoint_needed || fw_adjoint) { // Configure the domain for forward simulation FlatSourceDomain::adjoint_ = false; - if (mpi::master) + if (adjoint_needed && mpi::master) header("FORWARD FLUX SOLVE", 3); + } else { + // Configure domain for adjoint simulation (later) + FlatSourceDomain::adjoint_ = true; + } - // Initialize OpenMC general data structures - openmc_simulation_init(); + // Initialize OpenMC general data structures + openmc_simulation_init(); - // Validate that inputs meet requirements for random ray mode - if (mpi::master) - validate_random_ray_inputs(); + // Validate that inputs meet requirements for random ray mode + if (mpi::master) + validate_random_ray_inputs(); - { - // Initialize Random Ray Simulation Object - RandomRaySimulation sim; + // Initialize Random Ray Simulation Object + RandomRaySimulation sim; - // Initialize fixed sources, if present - sim.apply_fixed_sources_and_mesh_domains(); + if (!adjoint_needed || fw_adjoint) { + // Initialize fixed sources, if present + sim.apply_fixed_sources_and_mesh_domains(); - // Begin main simulation timer - simulation::time_total.start(); + // Begin main simulation timer + simulation::time_total.start(); - // Execute random ray simulation - sim.simulate(); + // Execute random ray simulation + sim.simulate(); - // End main simulation timer - simulation::time_total.stop(); + // End main simulation timer + simulation::time_total.stop(); - // Normalize and save the final forward flux - double source_normalization_factor = - sim.domain()->compute_fixed_source_normalization_factor() / - (settings::n_batches - settings::n_inactive); + // Normalize and save the final forward flux + double source_normalization_factor = + sim.domain()->compute_fixed_source_normalization_factor() / + (settings::n_batches - settings::n_inactive); #pragma omp parallel for - for (uint64_t se = 0; se < sim.domain()->n_source_elements(); se++) { - sim.domain()->source_regions_.scalar_flux_final(se) *= - source_normalization_factor; - } + for (uint64_t se = 0; se < sim.domain()->n_source_elements(); se++) { + sim.domain()->source_regions_.scalar_flux_final(se) *= + source_normalization_factor; + } - // Finalize OpenMC - openmc_simulation_finalize(); + // Finalize OpenMC + openmc_simulation_finalize(); - // Output all simulation results - sim.output_simulation_results(); - } + // Output all simulation results + sim.output_simulation_results(); } ////////////////////////////////////////////////////////// @@ -97,44 +100,45 @@ void openmc_run_random_ray() reset_timers(); - // Configure the domain for adjoint simulation - FlatSourceDomain::adjoint_ = true; - if (mpi::master) header("ADJOINT FLUX SOLVE", 3); - // Initialize OpenMC general data structures - openmc_simulation_init(); + if (fw_adjoint) { + // Forward simulation has already been run; + // Configure the domain for adjoint simulation and + // re-initialize OpenMC general data structures + FlatSourceDomain::adjoint_ = true; - sim.domain()->k_eff_ = 1.0; + openmc_simulation_init(); - // Initialize adjoint fixed sources, if present - if (global_adjoint) { - sim.prepare_global_fixed_sources_adjoint(); - } else { - sim.prepare_local_fixed_sources_adjoint(); - } + sim.prepare_fw_fixed_sources_adjoint(); + } else { + // Initialize adjoint fixed sources + sim.prepare_local_fixed_sources_adjoint(); + } + + sim.domain()->k_eff_ = 1.0; // Transpose scattering matrix - sim.domain()->transpose_scattering_matrix(); + sim.domain()->transpose_scattering_matrix(); - // Swap nu_sigma_f and chi - sim.domain()->nu_sigma_f_.swap(sim.domain()->chi_); + // Swap nu_sigma_f and chi + sim.domain()->nu_sigma_f_.swap(sim.domain()->chi_); - // Begin main simulation timer - simulation::time_total.start(); + // Begin main simulation timer + simulation::time_total.start(); - // Execute random ray simulation - sim.simulate(); + // Execute random ray simulation + sim.simulate(); - // End main simulation timer - simulation::time_total.stop(); + // End main simulation timer + simulation::time_total.stop(); - // Finalize OpenMC - openmc_simulation_finalize(); - - // Output all simulation results - sim.output_simulation_results(); + // Finalize OpenMC + openmc_simulation_finalize(); + + // Output all simulation results + sim.output_simulation_results(); } } @@ -408,11 +412,12 @@ void RandomRaySimulation::apply_fixed_sources_and_mesh_domains() } } -void RandomRaySimulation::prepare_global_fixed_sources_adjoint() +void RandomRaySimulation::prepare_fw_fixed_sources_adjoint() { + // Prepare adjoint fixed sources using forward flux domain_->source_regions_.adjoint_reset(); if (settings::run_mode == RunMode::FIXED_SOURCE) { - domain_->set_global_adjoint_sources(); + domain_->set_fw_adjoint_sources(); } } From f3e49f26639b9d4bea315a5c8017f927b58b2161 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Thu, 15 Jan 2026 13:35:32 -0500 Subject: [PATCH 05/10] Clean up updated adjoint source setting --- include/openmc/random_ray/flat_source_domain.h | 2 +- src/random_ray/flat_source_domain.cpp | 2 -- src/random_ray/random_ray_simulation.cpp | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 5894a062b33..e5dae3a41ac 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -42,7 +42,7 @@ class FlatSourceDomain { void output_to_vtk() const; void convert_external_sources(bool use_adjoint_sources); void count_external_source_regions(); - void set_fw_adjoint_sources(const vector& forward_flux); + void set_fw_adjoint_sources(); void set_local_adjoint_sources(); void flux_swap(); virtual double evaluate_flux_at_point(Position r, int64_t sr, int g) const; diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 7f0efdaf592..094172e1f7c 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -1342,8 +1342,6 @@ void FlatSourceDomain::set_fw_adjoint_sources() } // End CADIS logic } -} - void FlatSourceDomain::set_local_adjoint_sources() { // Set the external source to user-specified adjoint sources. diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index d45c9aeca02..c4c64b533d2 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -139,7 +139,6 @@ void openmc_run_random_ray() // Output all simulation results sim.output_simulation_results(); - } } // Enforces restrictions on inputs in random ray mode. While there are From 97f8133c4b1339f9a2aba575102c6b237cce8ca0 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Fri, 16 Jan 2026 08:58:43 -0500 Subject: [PATCH 06/10] add cadis as option on WWG --- openmc/weight_windows.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index d6efbbb89d8..4c42c863563 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -515,7 +515,7 @@ class WeightWindowGenerator: energies in [eV] for a single bin particle_type : {'neutron', 'photon'} Particle type the weight windows apply to - method : {'magic', 'fw_cadis'} + method : {'magic', 'fw_cadis', 'cadis'} The weight window generation methodology applied during an update. max_realizations : int The upper limit for number of tally realizations when generating weight @@ -528,7 +528,7 @@ class WeightWindowGenerator: Whether or not to apply weight windows on the fly. """ - _MAGIC_PARAMS = {'value': str, 'threshold': float, 'ratio': float} + _WWG_PARAMS = {'value': str, 'threshold': float, 'ratio': float} def __init__( self, @@ -635,13 +635,13 @@ def update_parameters(self) -> dict: def _check_update_parameters(self, params: dict): if self.method == 'magic' or self.method == 'fw_cadis' or self.method == 'cadis': - check_params = self._MAGIC_PARAMS + check_params = self._WWG_PARAMS for key, val in params.items(): if key not in check_params: raise ValueError(f'Invalid param "{key}" for {self.method} ' 'weight window generation') - cv.check_type(f'weight window generation param: "{key}"', val, self._MAGIC_PARAMS[key]) + cv.check_type(f'weight window generation param: "{key}"', val, self._WWG_PARAMS[key]) @update_parameters.setter def update_parameters(self, params: dict): @@ -678,7 +678,7 @@ def _sanitize_update_parameters(cls, method: str, update_parameters: dict): The update parameters as-read from the XML node (keys: str, values: str) """ if method == 'magic' or method == 'fw_cadis' or method == 'cadis': - check_params = cls._MAGIC_PARAMS + check_params = cls._WWG_PARAMS for param, param_type in check_params.items(): if param in update_parameters: From 001f176f9de05dfc935671acdd273d9d24f49c74 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Mon, 26 Jan 2026 22:25:28 -0500 Subject: [PATCH 07/10] CADIS WWG UI with model.tallies linking --- openmc/model/model.py | 35 ++++++++++++++++++++++++++++ openmc/weight_windows.py | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/openmc/model/model.py b/openmc/model/model.py index 6e4c1c5856d..486aabbc981 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -265,6 +265,37 @@ def add_kinetics_parameters_tallies(self, num_groups: int | None = None): denom_tally = openmc.Tally(name='IFP denominator') denom_tally.scores = ['ifp-denominator'] self.tallies.append(denom_tally) + + # TODO: This should also be incorporated into lower-level calls in + # settings.py, but it requires information about the tallies currently + # on the active Model + def _assign_cadis_tally_IDs(self): + # Verify that all tallies assigned as targets on WeightWindowGenerators + # exist within model.tallies. If this is the case, convert the .targets + # attribute of each WeightWindowGenerator to a sequence of tally IDs. + if len(self.settings.weight_window_generators) == 0: + return + + for wwg in self.settings.weight_window_generators: + # Only proceeds if the "targets" attribute is an openmc.Tallies, + # which means it hasn't been checked against model.tallies. + if isinstance(wwg.targets, openmc.Tallies): + id_vec = [] + for tal in wwg.targets: + # check against model tallies + id_next = None + for reference_tal in self.tallies: + if tal == reference_tal: + id_next = reference_tal.id + break + + if id_next == None: + raise RuntimeError( + f'CADIS target tally {tal.id} not found on model.tallies!') + else: + id_vec.append(id_next) + + wwg.targets = id_vec @classmethod def from_xml( @@ -576,6 +607,7 @@ def export_to_xml(self, directory: PathLike = '.', remove_surfs: bool = False, if not d.is_dir(): d.mkdir(parents=True, exist_ok=True) + self._assign_cadis_tally_IDs() self.settings.export_to_xml(d) self.geometry.export_to_xml(d, remove_surfs=remove_surfs) @@ -634,6 +666,9 @@ def export_to_model_xml(self, path: PathLike = 'model.xml', remove_surfs: bool = "set the Geometry.merge_surfaces attribute instead.") self.geometry.merge_surfaces = True + # Link CADIS WeightWindowGenerator target tallies, if present + self._assign_cadis_tally_IDs() + # provide a memo to track which meshes have been written mesh_memo = set() settings_element = self.settings.to_xml_element(mesh_memo) diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index 4c42c863563..d7c14f2c7bd 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -12,6 +12,7 @@ import openmc from openmc.filter import _PARTICLES from openmc.mesh import MeshBase, RectilinearMesh, CylindricalMesh, SphericalMesh, UnstructuredMesh +from openmc.tally import Tallies import openmc.checkvalue as cv from openmc.checkvalue import PathLike from ._xml import get_elem_list, get_text, clean_indentation @@ -498,6 +499,8 @@ class WeightWindowGenerator: Particle type the weight windows apply to method : {'magic', 'fw_cadis', 'cadis'} The weight window generation methodology applied during an update. + targets : :class:`openmc.Tallies` + Target tallies for local variance reduction via CADIS. max_realizations : int The upper limit for number of tally realizations when generating weight windows. @@ -517,6 +520,8 @@ class WeightWindowGenerator: Particle type the weight windows apply to method : {'magic', 'fw_cadis', 'cadis'} The weight window generation methodology applied during an update. + targets : :class:`openmc.Tallies` + Target tallies for local variance reduction via CADIS. max_realizations : int The upper limit for number of tally realizations when generating weight windows. @@ -536,6 +541,7 @@ def __init__( energy_bounds: Sequence[float] | None = None, particle_type: str = 'neutron', method: str = 'magic', + targets: openmc.Tallies | list[int] | None = None, max_realizations: int = 1, update_interval: int = 1, on_the_fly: bool = True @@ -548,6 +554,7 @@ def __init__( self.energy_bounds = energy_bounds self.particle_type = particle_type self.method = method + self.targets = targets self.max_realizations = max_realizations self.update_interval = update_interval self.on_the_fly = on_the_fly @@ -608,6 +615,26 @@ def method(self, m: str): self._check_update_parameters() except (TypeError, KeyError): warnings.warn(f'Update parameters are invalid for the "{m}" method.') + + @property + def targets(self) -> openmc.Tallies: + return self._targets + + @targets.setter + def targets(self, t): + if t is None: + self._targets = t + else: + cv.check_type('CADIS target tallies', t, [openmc.Tallies, list]) + cv.check_greater_than('CADIS target tallies', len(t), 0) + if isinstance(t, list): + for tally_id in t: + if not isinstance(tally_id, int): + raise TypeError( + "Tally IDs passed to WeightWindowGenerator " \ + "must be of type int") + + self._targets = t @property def max_realizations(self) -> int: @@ -704,6 +731,20 @@ def to_xml_element(self): otf_elem.text = str(self.on_the_fly).lower() method_elem = ET.SubElement(element, 'method') method_elem.text = self.method + if self.targets is not None: + if self.method != 'cadis': + raise ValueError( + "CADIS update method is required in order to use " \ + "target tallies for WeightWindowGenerator.") + elif isinstance(self.targets, openmc.Tallies): + raise RuntimeError( + "CADIS target tallies must be checked to ensure they are" \ + "present on model.tallies. Use model.export_to_xml() or " \ + "model.export_to_model_xml() to link CADIS target tallies.") + else: + targets_elem = ET.SubElement(element, 'targets') + targets_elem.text = ' '.join(str(tally_id) for tally_id in self.targets) + if self.update_parameters is not None: self._update_parameters_subelement(element) @@ -740,6 +781,14 @@ def from_xml_element(cls, elem: ET.Element, meshes: dict) -> Self: wwg.update_interval = int(get_text(elem, 'update_interval')) wwg.on_the_fly = bool(get_text(elem, 'on_the_fly')) wwg.method = get_text(elem, 'method') + targets_elem = elem.find('targets') + if targets_elem is not None: + if wwg.method != 'cadis': + raise ValueError( + "CADIS update method is required in order to use " \ + "target tallies for WeightWindowGenerator.") + else: + wwg.targets = get_elem_list(elem, "targets") if elem.find('update_parameters') is not None: update_parameters = {} From 5e273549ff26442fe3578340012a9cdd0814c9d4 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Mon, 26 Jan 2026 22:28:01 -0500 Subject: [PATCH 08/10] fix possible typo in WWG.from_xml_element() --- openmc/weight_windows.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index d7c14f2c7bd..2e541f393d0 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -772,7 +772,7 @@ def from_xml_element(cls, elem: ET.Element, meshes: dict) -> Self: mesh_id = int(get_text(elem, 'mesh')) mesh = meshes[mesh_id] - energy_bounds = get_elem_list(elem, "energy_bounds, float") + energy_bounds = get_elem_list(elem, "energy_bounds", float) particle_type = get_text(elem, 'particle_type') wwg = cls(mesh, energy_bounds, particle_type) From eea6be300faa89ea119ca985e2b44f4d51d7b6be Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Thu, 29 Jan 2026 22:32:28 -0500 Subject: [PATCH 09/10] cpp UI --- .../openmc/random_ray/flat_source_domain.h | 2 ++ include/openmc/weight_windows.h | 3 +++ src/random_ray/flat_source_domain.cpp | 27 ++++++++++++++----- src/random_ray/random_ray_simulation.cpp | 4 +-- src/settings.cpp | 22 +++++++++++---- src/weight_windows.cpp | 11 +++++++- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index e5dae3a41ac..cfe2be2a7a0 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -86,6 +86,8 @@ class FlatSourceDomain { static std::unordered_map>> mesh_domain_map_; + static std::vector cadis_targets_; + //---------------------------------------------------------------------------- // Static data members static RandomRayVolumeEstimator volume_estimator_; diff --git a/include/openmc/weight_windows.h b/include/openmc/weight_windows.h index 6939e8ac60a..c21200440fd 100644 --- a/include/openmc/weight_windows.h +++ b/include/openmc/weight_windows.h @@ -235,6 +235,9 @@ class WeightWindowsGenerator { double threshold_ {1.0}; // targets_; }; //! Finalize variance reduction objects after all inputs have been read diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 094172e1f7c..fb9996625fb 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -1292,14 +1292,23 @@ void FlatSourceDomain::set_fw_adjoint_sources() } // If there are tally tasks, we can through them and check if - // any of them have a non-mesh filter type. + // any of them are CADIS targets and have a non-mesh filter type. - // We track if ANY of the tasks have a non-mesh filter - bool has_non_mesh_filter = false; + // We track if ANY of the tasks are CADIS target tallies + bool cadis_target_region = false; // Now we loop through for (const auto& task : source_regions_.tally_task(sr, g)) { Tally& tally {*model::tallies[task.tally_idx]}; + const auto t_id = tally.id(); + + // Skip non-target tallies + if (std::find(cadis_targets_.begin(), + cadis_targets_.end(), + t_id) == cadis_targets_.end()) { + continue; + } + auto filter_types = tally.filter_types(); // For each tally, we loop through the filter types array. @@ -1311,17 +1320,23 @@ void FlatSourceDomain::set_fw_adjoint_sources() filter_type == FilterType::DISTRIBCELL || filter_type == FilterType::UNIVERSE || filter_type == FilterType::MATERIAL) { - has_non_mesh_filter = true; + cadis_target_region = true; break; } } + // If a target tally doesn't have any compatible filters, error + if (!cadis_target_region) { + fatal_error("CADIS target tally with ID " + + std::to_string(t_id) + " does not have any " + "CADIS-compatible filters."); + } } - // If ANY of the tasks has a non-mesh filter type, + // If ANY of the tasks is a CADIS target, // Then we keep the source term and set that this // source region has a valid CADIS source term. // Otherwise, we zero out the source term. - if (has_non_mesh_filter) { + if (cadis_target_region) { has_any_sources = true; // print external source term fmt::print("External source term for source region {} group {}: {}\n", diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index c4c64b533d2..f38e5e9065c 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -353,8 +353,8 @@ void validate_random_ray_inputs() warning( "Linear sources may result in negative fluxes in small source regions " "generated by mesh subdivision. Negative sources may result in low " - "quality FW-CADIS weight windows. We recommend you use flat source mode " - "when generating weight windows with an overlaid mesh tally."); + "quality (FW-)CADIS weight windows. We recommend you use flat source " + "mode when generating weight windows with an overlaid mesh tally."); } } diff --git a/src/settings.cpp b/src/settings.cpp index 192d67bb4bd..d8fca66df81 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -364,11 +364,13 @@ void get_run_parameters(pugi::xml_node node_base) "between 0 and 1"); } } - - for (pugi::xml_node adj_source_node : random_ray_node.children("adjoint_source")) { - // Find any local adjoint sources - xml_node source_node = adj_source_node.child("source"); - model::adjoint_sources.push_back(Source::create(source_node)); + if (check_for_node(random_ray_node, "adjoint_source")) { + for (pugi::xml_node adj_source_node : + random_ray_node.children("adjoint_source")) { + // Find any local adjoint sources + xml_node source_node = adj_source_node.child("source"); + model::adjoint_sources.push_back(Source::create(source_node)); + } } } } @@ -1256,6 +1258,16 @@ void read_settings_xml(pugi::xml_node root) break; } } + // If any weight window generators have CADIS target tallies, user-defined + // adjoint sources cannot be used at the same time. + if (!model::adjoint_sources.empty()) { + for (const auto& wwg : variance_reduction::weight_windows_generators) { + if (!wwg->targets_.empty()) { + fatal_error("Cannot use both user-defined adjoint sources and CADIS " + "target tallies at the same time."); + } + } + } } // Set up weight window checkpoints diff --git a/src/weight_windows.cpp b/src/weight_windows.cpp index 42dfccbbdb9..f60de4c56d5 100644 --- a/src/weight_windows.cpp +++ b/src/weight_windows.cpp @@ -698,7 +698,7 @@ void WeightWindows::update_weights(const Tally* tally, const std::string& value, } } } else { - // For FW-CADIS, weight windows are inversely proportional to the adjoint + // For (FW-)CADIS, weight windows are inversely proportional to the adjoint // fluxes. We normalize the weight windows across all energy groups. #pragma omp parallel for collapse(2) schedule(static) for (int e = 0; e < e_bins; e++) { @@ -883,6 +883,15 @@ WeightWindowsGenerator::WeightWindowsGenerator(pugi::xml_node node) } FlatSourceDomain::adjoint_ = true; FlatSourceDomain::cadis_ = true; + if (check_for_node(node,"targets")) { + targets_ = get_node_array(node, "targets"); + FlatSourceDomain::cadis_targets_.insert( + std::end(FlatSourceDomain::cadis_targets_), std::begin(targets_), + std::end(targets_)); + } else { + fatal_error("CADIS method requires target tallies be specified to " + "WeightWindowGenerator."); + } } else { fatal_error(fmt::format( "Unknown weight window update method '{}' specified", method_string)); From 291fb210f13fea75b0f4ec682d7be1b743aba999 Mon Sep 17 00:00:00 2001 From: j-fletcher Date: Fri, 30 Jan 2026 00:26:50 -0500 Subject: [PATCH 10/10] regression tests and import bugfixes --- openmc/tallies.py | 91 +++++++++++-------- openmc/weight_windows.py | 2 +- src/random_ray/flat_source_domain.cpp | 1 + .../inputs_true.dat | 12 ++- .../random_ray_adjoint_k_eff/inputs_true.dat | 12 ++- .../random_ray_adjoint_k_eff/results_true.dat | 4 +- .../infinite_medium/inputs_true.dat | 12 ++- .../material_wise/inputs_true.dat | 12 ++- .../stochastic_slab/inputs_true.dat | 12 ++- .../infinite_medium/model/inputs_true.dat | 12 ++- .../infinite_medium/user/inputs_true.dat | 12 ++- .../stochastic_slab/model/inputs_true.dat | 12 ++- .../stochastic_slab/user/inputs_true.dat | 14 +-- .../inputs_true.dat | 12 ++- .../random_ray_entropy/settings.xml | 12 ++- .../cell/inputs_true.dat | 12 ++- .../material/inputs_true.dat | 12 ++- .../universe/inputs_true.dat | 12 ++- .../linear/inputs_true.dat | 12 ++- .../linear_xy/inputs_true.dat | 12 ++- .../flat/inputs_true.dat | 12 ++- .../linear/inputs_true.dat | 12 ++- .../False/inputs_true.dat | 12 ++- .../True/inputs_true.dat | 12 ++- .../flat/inputs_true.dat | 12 ++- .../linear_xy/inputs_true.dat | 12 ++- .../random_ray_halton_samples/inputs_true.dat | 12 ++- .../results_true.dat | 6 +- .../random_ray_k_eff/inputs_true.dat | 12 ++- .../random_ray_k_eff/results_true.dat | 6 +- .../random_ray_k_eff_mesh/inputs_true.dat | 12 ++- .../random_ray_k_eff_mesh/results_true.dat | 2 +- .../random_ray_linear/linear/inputs_true.dat | 12 ++- .../linear_xy/inputs_true.dat | 12 ++- .../linear_xy/results_true.dat | 2 +- .../random_ray_low_density/inputs_true.dat | 12 ++- .../inputs_true.dat | 12 ++- .../random_ray_void/flat/inputs_true.dat | 12 ++- .../random_ray_void/linear/inputs_true.dat | 12 ++- .../hybrid/inputs_true.dat | 12 ++- .../naive/inputs_true.dat | 12 ++- .../simulation_averaged/inputs_true.dat | 12 ++- .../hybrid/inputs_true.dat | 12 ++- .../naive/inputs_true.dat | 12 ++- .../simulation_averaged/inputs_true.dat | 12 ++- .../weightwindows_fw_cadis/inputs_true.dat | 12 ++- .../flat/inputs_true.dat | 12 ++- .../linear/inputs_true.dat | 12 ++- 48 files changed, 347 insertions(+), 249 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 7b1ef021987..d74670fc9df 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -16,6 +16,23 @@ import openmc import openmc.checkvalue as cv +from openmc.filter import ( + Filter, + DistribcellFilter, + EnergyFunctionFilter, + DelayedGroupFilter, + FilterMeta, + MeshFilter, + MeshBornFilter, +) +from openmc.arithmetic import ( + CrossFilter, + AggregateFilter, + CrossScore, + AggregateScore, + CrossNuclide, + AggregateNuclide, +) from ._sparse_compat import lil_array from ._xml import clean_indentation, get_elem_list, get_text from .mixin import IDManagerMixin @@ -31,9 +48,9 @@ # The following indicate acceptable types when setting Tally.scores, # Tally.nuclides, and Tally.filters -_SCORE_CLASSES = (str, openmc.CrossScore, openmc.AggregateScore) -_NUCLIDE_CLASSES = (str, openmc.CrossNuclide, openmc.AggregateNuclide) -_FILTER_CLASSES = (openmc.Filter, openmc.CrossFilter, openmc.AggregateFilter) +_SCORE_CLASSES = (str, CrossScore, AggregateScore) +_NUCLIDE_CLASSES = (str, CrossNuclide, AggregateNuclide) +_FILTER_CLASSES = (Filter, CrossFilter, AggregateFilter) # Valid types of estimators ESTIMATOR_TYPES = {'tracklength', 'collision', 'analog'} @@ -394,7 +411,7 @@ def _read_results(self): self._num_realizations = int(group['n_realizations'][()]) for filt in self.filters: - if isinstance(filt, openmc.DistribcellFilter): + if isinstance(filt, DistribcellFilter): filter_group = f[f'tallies/filters/filter {filt.id}'] filt._num_bins = int(filter_group['n_bins'][()]) @@ -1062,8 +1079,8 @@ def _can_merge_filters(self, other): return False # Return False if only one tally has a delayed group filter - tally1_dg = self.contains_filter(openmc.DelayedGroupFilter) - tally2_dg = other.contains_filter(openmc.DelayedGroupFilter) + tally1_dg = self.contains_filter(DelayedGroupFilter) + tally2_dg = other.contains_filter(DelayedGroupFilter) if tally1_dg != tally2_dg: return False @@ -1575,7 +1592,7 @@ def find_filter(self, filter_type): # Also check to see if the desired filter is wrapped up in an # aggregate - elif isinstance(test_filter, openmc.AggregateFilter): + elif isinstance(test_filter, AggregateFilter): if isinstance(test_filter.aggregate_filter, filter_type): return test_filter @@ -1677,7 +1694,7 @@ def get_filter_indices(self, filters=[], filter_bins=[]): """ - cv.check_type('filters', filters, Iterable, openmc.FilterMeta) + cv.check_type('filters', filters, Iterable, FilterMeta) cv.check_type('filter_bins', filter_bins, Iterable, tuple) # If user did not specify any specific Filters, use them all @@ -1760,7 +1777,7 @@ def get_score_indices(self, scores): """ for score in scores: - if not isinstance(score, (str, openmc.CrossScore)): + if not isinstance(score, (str, CrossScore)): msg = f'Unable to get score indices for score "{score}" in ' \ f'ID="{self.id}" since it is not a string or CrossScore ' \ 'Tally' @@ -1957,9 +1974,9 @@ def get_pandas_dataframe(self, filters=True, nuclides=True, scores=True, column_name = 'score' for score in self.scores: - if isinstance(score, (str, openmc.CrossScore)): + if isinstance(score, (str, CrossScore)): scores.append(str(score)) - elif isinstance(score, openmc.AggregateScore): + elif isinstance(score, AggregateScore): scores.append(score.name) column_name = f'{score.aggregate_op}(score)' @@ -2059,7 +2076,7 @@ def get_reshaped_data(self, value='mean', expand_dims=False): for i, f in enumerate(self.filters): if expand_dims: # Mesh filter indices are backwards so we need to flip them - if type(f) in {openmc.MeshFilter, openmc.MeshBornFilter}: + if type(f) in {MeshFilter, MeshBornFilter}: fshape = f.shape[::-1] new_shape += fshape idx0, idx1 = i, i + len(fshape) - 1 @@ -2246,7 +2263,7 @@ def hybrid_product(self, other, binary_op, filter_product=None, else: all_filters = [self_copy.filters, other_copy.filters] for self_filter, other_filter in product(*all_filters): - new_filter = openmc.CrossFilter(self_filter, other_filter, + new_filter = CrossFilter(self_filter, other_filter, binary_op) new_tally.filters.append(new_filter) @@ -2257,7 +2274,7 @@ def hybrid_product(self, other, binary_op, filter_product=None, else: all_nuclides = [self_copy.nuclides, other_copy.nuclides] for self_nuclide, other_nuclide in product(*all_nuclides): - new_nuclide = openmc.CrossNuclide(self_nuclide, other_nuclide, + new_nuclide = CrossNuclide(self_nuclide, other_nuclide, binary_op) new_tally.nuclides.append(new_nuclide) @@ -2268,9 +2285,9 @@ def cross_score(score1, score2, binary_op): if score1 == score2: return score1 else: - return openmc.CrossScore(score1, score2, binary_op) + return CrossScore(score1, score2, binary_op) else: - return openmc.CrossScore(score1, score2, binary_op) + return CrossScore(score1, score2, binary_op) # Add scores to the new tally if score_product == 'entrywise': @@ -2479,16 +2496,16 @@ def _swap_filters(self, filter1, filter2): # Construct lists of tuples for the bins in each of the two filters filters = [type(filter1), type(filter2)] - if isinstance(filter1, openmc.DistribcellFilter): + if isinstance(filter1, DistribcellFilter): filter1_bins = [b for b in range(filter1.num_bins)] - elif isinstance(filter1, openmc.EnergyFunctionFilter): + elif isinstance(filter1, EnergyFunctionFilter): filter1_bins = [None] else: filter1_bins = filter1.bins - if isinstance(filter2, openmc.DistribcellFilter): + if isinstance(filter2, DistribcellFilter): filter2_bins = [b for b in range(filter2.num_bins)] - elif isinstance(filter2, openmc.EnergyFunctionFilter): + elif isinstance(filter2, EnergyFunctionFilter): filter2_bins = [None] else: filter2_bins = filter2.bins @@ -2621,11 +2638,11 @@ def _swap_scores(self, score1, score2): raise ValueError(msg) # Check that the scores are valid - if not isinstance(score1, (str, openmc.CrossScore)): + if not isinstance(score1, (str, CrossScore)): msg = 'Unable to swap score1 "{}" in Tally ID="{}" since it is ' \ 'not a string or CrossScore'.format(score1, self.id) raise ValueError(msg) - elif not isinstance(score2, (str, openmc.CrossScore)): + elif not isinstance(score2, (str, CrossScore)): msg = 'Unable to swap score2 "{}" in Tally ID="{}" since it is ' \ 'not a string or CrossScore'.format(score2, self.id) raise ValueError(msg) @@ -3269,7 +3286,7 @@ def get_slice(self, scores=[], filters=[], filter_bins=[], nuclides=[], new_filter.bins = [f.bins[i] for i in bin_indices] # Set number of bins manually for mesh/distribcell filters - if filter_type is openmc.DistribcellFilter: + if filter_type is DistribcellFilter: new_filter._num_bins = f._num_bins # Replace existing filter with new one @@ -3335,16 +3352,16 @@ def summation(self, scores=[], filter_type=None, std_dev = self.get_reshaped_data(value='std_dev') # Sum across any filter bins specified by the user - if isinstance(filter_type, openmc.FilterMeta): + if isinstance(filter_type, FilterMeta): find_filter = self.find_filter(filter_type) # If user did not specify filter bins, sum across all bins if len(filter_bins) == 0: bin_indices = np.arange(find_filter.num_bins) - if isinstance(find_filter, openmc.DistribcellFilter): + if isinstance(find_filter, DistribcellFilter): filter_bins = np.arange(find_filter.num_bins) - elif isinstance(find_filter, openmc.EnergyFunctionFilter): + elif isinstance(find_filter, EnergyFunctionFilter): filter_bins = [None] else: filter_bins = find_filter.bins @@ -3373,7 +3390,7 @@ def summation(self, scores=[], filter_type=None, # Add AggregateFilter to the tally sum if not remove_filter: - filter_sum = openmc.AggregateFilter(self_filter, + filter_sum = AggregateFilter(self_filter, [tuple(filter_bins)], 'sum') tally_sum.filters.append(filter_sum) @@ -3396,7 +3413,7 @@ def summation(self, scores=[], filter_type=None, std_dev = np.sqrt(std_dev) # Add AggregateNuclide to the tally sum - nuclide_sum = openmc.AggregateNuclide(nuclides, 'sum') + nuclide_sum = AggregateNuclide(nuclides, 'sum') tally_sum.nuclides.append(nuclide_sum) # Add a copy of this tally's nuclides to the tally sum @@ -3414,7 +3431,7 @@ def summation(self, scores=[], filter_type=None, std_dev = np.sqrt(std_dev) # Add AggregateScore to the tally sum - score_sum = openmc.AggregateScore(scores, 'sum') + score_sum = AggregateScore(scores, 'sum') tally_sum.scores.append(score_sum) # Add a copy of this tally's scores to the tally sum @@ -3487,16 +3504,16 @@ def average(self, scores=[], filter_type=None, std_dev = self.get_reshaped_data(value='std_dev') # Average across any filter bins specified by the user - if isinstance(filter_type, openmc.FilterMeta): + if isinstance(filter_type, FilterMeta): find_filter = self.find_filter(filter_type) # If user did not specify filter bins, average across all bins if len(filter_bins) == 0: bin_indices = np.arange(find_filter.num_bins) - if isinstance(find_filter, openmc.DistribcellFilter): + if isinstance(find_filter, DistribcellFilter): filter_bins = np.arange(find_filter.num_bins) - elif isinstance(find_filter, openmc.EnergyFunctionFilter): + elif isinstance(find_filter, EnergyFunctionFilter): filter_bins = [None] else: filter_bins = find_filter.bins @@ -3526,7 +3543,7 @@ def average(self, scores=[], filter_type=None, # Add AggregateFilter to the tally avg if not remove_filter: - filter_sum = openmc.AggregateFilter(self_filter, + filter_sum = AggregateFilter(self_filter, [tuple(filter_bins)], 'avg') tally_avg.filters.append(filter_sum) @@ -3550,7 +3567,7 @@ def average(self, scores=[], filter_type=None, std_dev = np.sqrt(std_dev) # Add AggregateNuclide to the tally avg - nuclide_avg = openmc.AggregateNuclide(nuclides, 'avg') + nuclide_avg = AggregateNuclide(nuclides, 'avg') tally_avg.nuclides.append(nuclide_avg) # Add a copy of this tally's nuclides to the tally avg @@ -3569,7 +3586,7 @@ def average(self, scores=[], filter_type=None, std_dev = np.sqrt(std_dev) # Add AggregateScore to the tally avg - score_sum = openmc.AggregateScore(scores, 'avg') + score_sum = AggregateScore(scores, 'avg') tally_avg.scores.append(score_sum) # Add a copy of this tally's scores to the tally avg @@ -3759,7 +3776,7 @@ def _create_mesh_subelements(self, root_element, memo=None): already_written = memo if memo else set() for tally in self: for f in tally.filters: - if isinstance(f, openmc.MeshFilter): + if isinstance(f, MeshFilter): if f.mesh.id in already_written: continue if len(f.mesh.name) > 0: @@ -3854,7 +3871,7 @@ def from_xml_element(cls, elem, meshes=None): # Read filter elements filters = {} for e in elem.findall('filter'): - filter = openmc.Filter.from_xml_element(e, meshes=meshes) + filter = Filter.from_xml_element(e, meshes=meshes) filters[filter.id] = filter # Read derivative elements diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index 2e541f393d0..221fa718217 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -12,7 +12,7 @@ import openmc from openmc.filter import _PARTICLES from openmc.mesh import MeshBase, RectilinearMesh, CylindricalMesh, SphericalMesh, UnstructuredMesh -from openmc.tally import Tallies +from openmc.tallies import Tallies import openmc.checkvalue as cv from openmc.checkvalue import PathLike from ._xml import get_elem_list, get_text, clean_indentation diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index fb9996625fb..799cbfac77c 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -34,6 +34,7 @@ bool FlatSourceDomain::cadis_ {false}; double FlatSourceDomain::diagonal_stabilization_rho_ {1.0}; std::unordered_map>> FlatSourceDomain::mesh_domain_map_; +std::vector FlatSourceDomain::cadis_targets_; FlatSourceDomain::FlatSourceDomain() : negroups_(data::mg.num_energy_groups_) { diff --git a/tests/regression_tests/random_ray_adjoint_fixed_source/inputs_true.dat b/tests/regression_tests/random_ray_adjoint_fixed_source/inputs_true.dat index 0adfc548848..94e2709768f 100644 --- a/tests/regression_tests/random_ray_adjoint_fixed_source/inputs_true.dat +++ b/tests/regression_tests/random_ray_adjoint_fixed_source/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true true naive diff --git a/tests/regression_tests/random_ray_adjoint_k_eff/inputs_true.dat b/tests/regression_tests/random_ray_adjoint_k_eff/inputs_true.dat index 073348c41e7..755afd6c439 100644 --- a/tests/regression_tests/random_ray_adjoint_k_eff/inputs_true.dat +++ b/tests/regression_tests/random_ray_adjoint_k_eff/inputs_true.dat @@ -80,11 +80,13 @@ 100.0 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + true true diff --git a/tests/regression_tests/random_ray_adjoint_k_eff/results_true.dat b/tests/regression_tests/random_ray_adjoint_k_eff/results_true.dat index dfef53cd2f9..429067b2212 100644 --- a/tests/regression_tests/random_ray_adjoint_k_eff/results_true.dat +++ b/tests/regression_tests/random_ray_adjoint_k_eff/results_true.dat @@ -79,7 +79,7 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -9.248400E-01 +9.248399E-01 1.710699E-01 0.000000E+00 0.000000E+00 @@ -148,7 +148,7 @@ tally 1: 9.272977E-01 1.721077E-01 3.161443E-02 -2.000179E-04 +2.000180E-04 2.002789E-07 8.027290E-15 8.778794E-01 diff --git a/tests/regression_tests/random_ray_auto_convert/infinite_medium/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert/infinite_medium/inputs_true.dat index 464c89a5df9..86d5ec4abd5 100644 --- a/tests/regression_tests/random_ray_auto_convert/infinite_medium/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert/infinite_medium/inputs_true.dat @@ -41,11 +41,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_auto_convert/material_wise/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert/material_wise/inputs_true.dat index 464c89a5df9..86d5ec4abd5 100644 --- a/tests/regression_tests/random_ray_auto_convert/material_wise/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert/material_wise/inputs_true.dat @@ -41,11 +41,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_auto_convert/stochastic_slab/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert/stochastic_slab/inputs_true.dat index 464c89a5df9..86d5ec4abd5 100644 --- a/tests/regression_tests/random_ray_auto_convert/stochastic_slab/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert/stochastic_slab/inputs_true.dat @@ -41,11 +41,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/model/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/model/inputs_true.dat index 80a166c6786..15981f7fa5f 100644 --- a/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/model/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/model/inputs_true.dat @@ -38,11 +38,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/user/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/user/inputs_true.dat index 464c89a5df9..86d5ec4abd5 100644 --- a/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/user/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert_source_energy/infinite_medium/user/inputs_true.dat @@ -41,11 +41,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/model/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/model/inputs_true.dat index 80a166c6786..15981f7fa5f 100644 --- a/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/model/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/model/inputs_true.dat @@ -38,11 +38,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/user/inputs_true.dat b/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/user/inputs_true.dat index 464c89a5df9..2314266563c 100644 --- a/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/user/inputs_true.dat +++ b/tests/regression_tests/random_ray_auto_convert_source_energy/stochastic_slab/user/inputs_true.dat @@ -40,12 +40,14 @@ multi-group - - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_diagonal_stabilization/inputs_true.dat b/tests/regression_tests/random_ray_diagonal_stabilization/inputs_true.dat index 47325ebd7d5..11100e88e12 100644 --- a/tests/regression_tests/random_ray_diagonal_stabilization/inputs_true.dat +++ b/tests/regression_tests/random_ray_diagonal_stabilization/inputs_true.dat @@ -41,11 +41,13 @@ multi-group - - - -0.63 -0.63 -1.0 0.63 0.63 1.0 - - + + + + -0.63 -0.63 -1.0 0.63 0.63 1.0 + + + 30.0 150.0 diff --git a/tests/regression_tests/random_ray_entropy/settings.xml b/tests/regression_tests/random_ray_entropy/settings.xml index 81deaa7751d..0d830417b62 100644 --- a/tests/regression_tests/random_ray_entropy/settings.xml +++ b/tests/regression_tests/random_ray_entropy/settings.xml @@ -6,11 +6,13 @@ 5 multi-group - - - 0.0 0.0 0.0 100.0 100.0 100.0 - - + + + + 0.0 0.0 0.0 100.0 100.0 100.0 + + + 40.0 400.0 diff --git a/tests/regression_tests/random_ray_fixed_source_domain/cell/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/cell/inputs_true.dat index 9f1987f3acc..d650bbaf95c 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/cell/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_domain/cell/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_fixed_source_domain/material/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/material/inputs_true.dat index b4f57dbfa8a..98a51add1f3 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/material/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_domain/material/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_fixed_source_domain/universe/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/universe/inputs_true.dat index ab91f74e50d..20deba664bd 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/universe/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_domain/universe/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_fixed_source_linear/linear/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_linear/linear/inputs_true.dat index 220fa7db643..2268d82c391 100644 --- a/tests/regression_tests/random_ray_fixed_source_linear/linear/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_linear/linear/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true linear diff --git a/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/inputs_true.dat index f8c4430852f..fe95baa7bb5 100644 --- a/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true linear_xy diff --git a/tests/regression_tests/random_ray_fixed_source_mesh/flat/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_mesh/flat/inputs_true.dat index c84e544fcc4..a5632ece960 100644 --- a/tests/regression_tests/random_ray_fixed_source_mesh/flat/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_mesh/flat/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_fixed_source_mesh/linear/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_mesh/linear/inputs_true.dat index 05c4846e6b4..9d22603c63c 100644 --- a/tests/regression_tests/random_ray_fixed_source_mesh/linear/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_mesh/linear/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/False/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_normalization/False/inputs_true.dat index 0c870e10067..de941f10fbb 100644 --- a/tests/regression_tests/random_ray_fixed_source_normalization/False/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_normalization/False/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + false diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/True/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_normalization/True/inputs_true.dat index ab91f74e50d..20deba664bd 100644 --- a/tests/regression_tests/random_ray_fixed_source_normalization/True/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_normalization/True/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_fixed_source_subcritical/flat/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_subcritical/flat/inputs_true.dat index 0c05a71df32..943468a1095 100644 --- a/tests/regression_tests/random_ray_fixed_source_subcritical/flat/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_subcritical/flat/inputs_true.dat @@ -110,11 +110,13 @@ 40.0 40.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + false flat diff --git a/tests/regression_tests/random_ray_fixed_source_subcritical/linear_xy/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_subcritical/linear_xy/inputs_true.dat index a67495bf169..650953c4b06 100644 --- a/tests/regression_tests/random_ray_fixed_source_subcritical/linear_xy/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_subcritical/linear_xy/inputs_true.dat @@ -110,11 +110,13 @@ 40.0 40.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + false linear_xy diff --git a/tests/regression_tests/random_ray_halton_samples/inputs_true.dat b/tests/regression_tests/random_ray_halton_samples/inputs_true.dat index 36d5f6f2276..1b86d2daeea 100644 --- a/tests/regression_tests/random_ray_halton_samples/inputs_true.dat +++ b/tests/regression_tests/random_ray_halton_samples/inputs_true.dat @@ -80,11 +80,13 @@ 100.0 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + true halton diff --git a/tests/regression_tests/random_ray_halton_samples/results_true.dat b/tests/regression_tests/random_ray_halton_samples/results_true.dat index 256f8a744a3..5f39ebaeb19 100644 --- a/tests/regression_tests/random_ray_halton_samples/results_true.dat +++ b/tests/regression_tests/random_ray_halton_samples/results_true.dat @@ -24,7 +24,7 @@ tally 1: 1.707007E-02 5.933921E-05 4.154514E-02 -3.514889E-04 +3.514888E-04 1.513147E+00 4.652938E-01 1.810962E-02 @@ -34,7 +34,7 @@ tally 1: 4.347893E+00 3.798064E+00 6.851785E-03 -9.430195E-06 +9.430194E-06 1.695426E-02 5.773923E-05 2.809071E+00 @@ -152,7 +152,7 @@ tally 1: 4.036663E-02 3.323832E-04 1.516801E+00 -4.675245E-01 +4.675244E-01 1.752096E-02 6.241641E-05 4.264304E-02 diff --git a/tests/regression_tests/random_ray_k_eff/inputs_true.dat b/tests/regression_tests/random_ray_k_eff/inputs_true.dat index 545bd1d4578..72b783344fd 100644 --- a/tests/regression_tests/random_ray_k_eff/inputs_true.dat +++ b/tests/regression_tests/random_ray_k_eff/inputs_true.dat @@ -80,11 +80,13 @@ 100.0 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + true diff --git a/tests/regression_tests/random_ray_k_eff/results_true.dat b/tests/regression_tests/random_ray_k_eff/results_true.dat index ace18df8cce..4e0c31988d7 100644 --- a/tests/regression_tests/random_ray_k_eff/results_true.dat +++ b/tests/regression_tests/random_ray_k_eff/results_true.dat @@ -1,5 +1,5 @@ k-combined: -8.400321E-01 8.023357E-03 +8.400321E-01 8.023358E-03 tally 1: 1.075769E+00 2.317354E-01 @@ -28,7 +28,7 @@ tally 1: 1.509054E+00 4.629325E-01 1.749679E-02 -6.226587E-05 +6.226588E-05 4.258421E-02 3.688336E-04 4.322054E+00 @@ -131,7 +131,7 @@ tally 1: 2.304093E-01 4.053505E-01 3.291277E-02 -9.865420E-01 +9.865421E-01 1.949549E-01 6.047420E-01 7.327008E-02 diff --git a/tests/regression_tests/random_ray_k_eff_mesh/inputs_true.dat b/tests/regression_tests/random_ray_k_eff_mesh/inputs_true.dat index 98badea18d8..f6e9c8e3e71 100644 --- a/tests/regression_tests/random_ray_k_eff_mesh/inputs_true.dat +++ b/tests/regression_tests/random_ray_k_eff_mesh/inputs_true.dat @@ -80,11 +80,13 @@ 100.0 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + true diff --git a/tests/regression_tests/random_ray_k_eff_mesh/results_true.dat b/tests/regression_tests/random_ray_k_eff_mesh/results_true.dat index 2ae8fad85fb..2976d169b63 100644 --- a/tests/regression_tests/random_ray_k_eff_mesh/results_true.dat +++ b/tests/regression_tests/random_ray_k_eff_mesh/results_true.dat @@ -1,5 +1,5 @@ k-combined: -8.379203E-01 8.057199E-03 +8.379203E-01 8.057198E-03 tally 1: 1.073897E+00 2.309328E-01 diff --git a/tests/regression_tests/random_ray_linear/linear/inputs_true.dat b/tests/regression_tests/random_ray_linear/linear/inputs_true.dat index a43a66e71c7..269d9892ebf 100644 --- a/tests/regression_tests/random_ray_linear/linear/inputs_true.dat +++ b/tests/regression_tests/random_ray_linear/linear/inputs_true.dat @@ -80,11 +80,13 @@ 100.0 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + true linear diff --git a/tests/regression_tests/random_ray_linear/linear_xy/inputs_true.dat b/tests/regression_tests/random_ray_linear/linear_xy/inputs_true.dat index 7f76f2fd1c1..217e9551614 100644 --- a/tests/regression_tests/random_ray_linear/linear_xy/inputs_true.dat +++ b/tests/regression_tests/random_ray_linear/linear_xy/inputs_true.dat @@ -80,11 +80,13 @@ 100.0 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - + + + + -1.26 -1.26 -1 1.26 1.26 1 + + + true linear_xy diff --git a/tests/regression_tests/random_ray_linear/linear_xy/results_true.dat b/tests/regression_tests/random_ray_linear/linear_xy/results_true.dat index 052608b4254..e00538f64c6 100644 --- a/tests/regression_tests/random_ray_linear/linear_xy/results_true.dat +++ b/tests/regression_tests/random_ray_linear/linear_xy/results_true.dat @@ -90,7 +90,7 @@ tally 1: 1.746692E+00 1.536860E-01 4.251098E+00 -9.103405E-01 +9.103406E-01 3.651202E+00 6.682179E-01 5.431675E-01 diff --git a/tests/regression_tests/random_ray_low_density/inputs_true.dat b/tests/regression_tests/random_ray_low_density/inputs_true.dat index ab91f74e50d..20deba664bd 100644 --- a/tests/regression_tests/random_ray_low_density/inputs_true.dat +++ b/tests/regression_tests/random_ray_low_density/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_point_source_locator/inputs_true.dat b/tests/regression_tests/random_ray_point_source_locator/inputs_true.dat index 088f803bfa8..b4bd263f5ac 100644 --- a/tests/regression_tests/random_ray_point_source_locator/inputs_true.dat +++ b/tests/regression_tests/random_ray_point_source_locator/inputs_true.dat @@ -206,11 +206,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/random_ray_void/flat/inputs_true.dat b/tests/regression_tests/random_ray_void/flat/inputs_true.dat index aa28e7b68bf..66390c76661 100644 --- a/tests/regression_tests/random_ray_void/flat/inputs_true.dat +++ b/tests/regression_tests/random_ray_void/flat/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true flat diff --git a/tests/regression_tests/random_ray_void/linear/inputs_true.dat b/tests/regression_tests/random_ray_void/linear/inputs_true.dat index e4b2f22fa27..45228a03955 100644 --- a/tests/regression_tests/random_ray_void/linear/inputs_true.dat +++ b/tests/regression_tests/random_ray_void/linear/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true linear diff --git a/tests/regression_tests/random_ray_volume_estimator/hybrid/inputs_true.dat b/tests/regression_tests/random_ray_volume_estimator/hybrid/inputs_true.dat index 8e8a8ed9b81..4d1af46b121 100644 --- a/tests/regression_tests/random_ray_volume_estimator/hybrid/inputs_true.dat +++ b/tests/regression_tests/random_ray_volume_estimator/hybrid/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true hybrid diff --git a/tests/regression_tests/random_ray_volume_estimator/naive/inputs_true.dat b/tests/regression_tests/random_ray_volume_estimator/naive/inputs_true.dat index 1e25b97da66..a268d55d04a 100644 --- a/tests/regression_tests/random_ray_volume_estimator/naive/inputs_true.dat +++ b/tests/regression_tests/random_ray_volume_estimator/naive/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true naive diff --git a/tests/regression_tests/random_ray_volume_estimator/simulation_averaged/inputs_true.dat b/tests/regression_tests/random_ray_volume_estimator/simulation_averaged/inputs_true.dat index 78c16269763..777ccaea510 100644 --- a/tests/regression_tests/random_ray_volume_estimator/simulation_averaged/inputs_true.dat +++ b/tests/regression_tests/random_ray_volume_estimator/simulation_averaged/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true simulation_averaged diff --git a/tests/regression_tests/random_ray_volume_estimator_linear/hybrid/inputs_true.dat b/tests/regression_tests/random_ray_volume_estimator_linear/hybrid/inputs_true.dat index 47a8a718249..dd11567f69d 100644 --- a/tests/regression_tests/random_ray_volume_estimator_linear/hybrid/inputs_true.dat +++ b/tests/regression_tests/random_ray_volume_estimator_linear/hybrid/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true linear hybrid diff --git a/tests/regression_tests/random_ray_volume_estimator_linear/naive/inputs_true.dat b/tests/regression_tests/random_ray_volume_estimator_linear/naive/inputs_true.dat index 80a9ada4d5b..6933fba435e 100644 --- a/tests/regression_tests/random_ray_volume_estimator_linear/naive/inputs_true.dat +++ b/tests/regression_tests/random_ray_volume_estimator_linear/naive/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true linear naive diff --git a/tests/regression_tests/random_ray_volume_estimator_linear/simulation_averaged/inputs_true.dat b/tests/regression_tests/random_ray_volume_estimator_linear/simulation_averaged/inputs_true.dat index 4f032a62a82..3ccab1d21b7 100644 --- a/tests/regression_tests/random_ray_volume_estimator_linear/simulation_averaged/inputs_true.dat +++ b/tests/regression_tests/random_ray_volume_estimator_linear/simulation_averaged/inputs_true.dat @@ -207,11 +207,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true linear simulation_averaged diff --git a/tests/regression_tests/weightwindows_fw_cadis/inputs_true.dat b/tests/regression_tests/weightwindows_fw_cadis/inputs_true.dat index 5fa6505ddf4..6bdabfbee31 100644 --- a/tests/regression_tests/weightwindows_fw_cadis/inputs_true.dat +++ b/tests/regression_tests/weightwindows_fw_cadis/inputs_true.dat @@ -222,11 +222,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true naive diff --git a/tests/regression_tests/weightwindows_fw_cadis_mesh/flat/inputs_true.dat b/tests/regression_tests/weightwindows_fw_cadis_mesh/flat/inputs_true.dat index ceb89e6e34c..a0d84257a8d 100644 --- a/tests/regression_tests/weightwindows_fw_cadis_mesh/flat/inputs_true.dat +++ b/tests/regression_tests/weightwindows_fw_cadis_mesh/flat/inputs_true.dat @@ -222,11 +222,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true diff --git a/tests/regression_tests/weightwindows_fw_cadis_mesh/linear/inputs_true.dat b/tests/regression_tests/weightwindows_fw_cadis_mesh/linear/inputs_true.dat index c7691e950c4..62f8478586b 100644 --- a/tests/regression_tests/weightwindows_fw_cadis_mesh/linear/inputs_true.dat +++ b/tests/regression_tests/weightwindows_fw_cadis_mesh/linear/inputs_true.dat @@ -222,11 +222,13 @@ 500.0 100.0 - - - 0.0 0.0 0.0 30.0 30.0 30.0 - - + + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + true