From 9effa478c8dc46837df42f98f916666d20cad2b3 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 24 Jun 2024 15:29:44 -0500 Subject: [PATCH 01/61] added inheriting LinearSourceDomain class --- CMakeLists.txt | 1 + .../openmc/random_ray/flat_source_domain.h | 17 +-- .../openmc/random_ray/linear_source_domain.h | 61 +++++++++++ src/random_ray/linear_source_domain.cpp | 103 ++++++++++++++++++ 4 files changed, 174 insertions(+), 8 deletions(-) create mode 100644 include/openmc/random_ray/linear_source_domain.h create mode 100644 src/random_ray/linear_source_domain.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cbeaa0241b..eb62e4ba5cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -380,6 +380,7 @@ list(APPEND libopenmc_SOURCES src/random_ray/random_ray_simulation.cpp src/random_ray/random_ray.cpp src/random_ray/flat_source_domain.cpp + src/random_ray/linear_source_domain.cpp src/reaction.cpp src/reaction_product.cpp src/scattdata.cpp diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index badbb25fc2c..6ac488840a1 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -89,23 +89,24 @@ struct TallyTask { class FlatSourceDomain { public: //---------------------------------------------------------------------------- - // Constructors + // Constructors and Destructors FlatSourceDomain(); + virtual ~FlatSourceDomain() = default; //---------------------------------------------------------------------------- // Methods - void update_neutron_source(double k_eff); - double compute_k_eff(double k_eff_old) const; - void normalize_scalar_flux_and_volumes( + virtual void update_neutron_source(double k_eff); + virtual double compute_k_eff(double k_eff_old) const; + virtual void normalize_scalar_flux_and_volumes( double total_active_distance_per_iteration); - int64_t add_source_to_scalar_flux(); - void batch_reset(); + virtual int64_t add_source_to_scalar_flux(); + virtual void batch_reset(); void convert_source_regions_to_tallies(); void reset_tally_volumes(); void random_ray_tally(); void accumulate_iteration_flux(); void output_to_vtk() const; - void all_reduce_replicated_source_regions(); + virtual void all_reduce_replicated_source_regions(); void convert_external_sources(); void count_external_source_regions(); @@ -136,7 +137,7 @@ class FlatSourceDomain { vector source_; vector external_source_; -private: +protected: //---------------------------------------------------------------------------- // Methods void apply_external_source_to_source_region( diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h new file mode 100644 index 00000000000..197806469a7 --- /dev/null +++ b/include/openmc/random_ray/linear_source_domain.h @@ -0,0 +1,61 @@ +#ifndef OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H +#define OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H + +#include "openmc/random_ray/flat_source_domain.h" + +#include "openmc/openmp_interface.h" +#include "openmc/position.h" +#include "openmc/source.h" + +namespace openmc { + + /* + * The LinearSourceDomain class encompasses data and methods for storing + * scalar flux and source region for all flat source regions in a + * random ray simulation domain. + */ + +class LinearSourceDomain : public FlatSourceDomain { +public: + //---------------------------------------------------------------------------- + // Constructors + LinearSourceDomain(); + + //---------------------------------------------------------------------------- + // Methods + void update_neutron_source(double k_eff) override; + double compute_k_eff(double k_eff_old) const override; + void normalize_scalar_flux_and_volumes( + double total_active_distance_per_iteration) override; + int64_t add_source_to_scalar_flux() override; + void batch_reset() override; + void convert_source_regions_to_tallies(); + void reset_tally_volumes(); + void random_ray_tally(); + void accumulate_iteration_flux(); + void output_to_vtk() const; + void all_reduce_replicated_source_regions() override; + void convert_external_sources(); + void count_external_source_regions(); + + //---------------------------------------------------------------------------- + // Public Data members + + // ... + +private: + //---------------------------------------------------------------------------- + // Methods + + // ... + + //---------------------------------------------------------------------------- + // Private data members + + // ... + +}; // class LinearSourceDomain + +} // namespace openmc + +#endif // OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H \ No newline at end of file diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp new file mode 100644 index 00000000000..edfb4678524 --- /dev/null +++ b/src/random_ray/linear_source_domain.cpp @@ -0,0 +1,103 @@ +#include "openmc/random_ray/linear_source_domain.h" + +#include "openmc/cell.h" +#include "openmc/geometry.h" +#include "openmc/material.h" +#include "openmc/message_passing.h" +#include "openmc/mgxs_interface.h" +#include "openmc/output.h" +#include "openmc/plot.h" +#include "openmc/random_ray/random_ray.h" +#include "openmc/simulation.h" +#include "openmc/tallies/filter.h" +#include "openmc/tallies/tally.h" +#include "openmc/tallies/tally_scoring.h" +#include "openmc/timer.h" + +#include + +namespace openmc { + +//============================================================================== +// LinearSourceDomain implementation +//============================================================================== + +LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() +{ + // The base class constructor is already called, so just need to initialize + // the extra linear source members below + // ... +} + +void LinearSourceDomain::batch_reset() +{ + // We will first call the base class method as it needs to reset these + // variables as well + FlatSourceDomain::batch_reset(); + // And then we add in the stuff specific to the linear source class as well + // ... +} + +void LinearSourceDomain::accumulate_iteration_flux() +{ + // Fully reimplement this function for linear source + // ... +} + +void LinearSourceDomain::update_neutron_source(double k_eff) +{ + // Fully reimplement this function for linear source + // ... +} + +void LinearSourceDomain::normalize_scalar_flux_and_volumes( + double total_active_distance_per_iteration) + { + // Fully reimplement this function for linear source + // ... + } + + int64_t LinearSourceDomain::add_source_to_scalar_flux() +{ + int64_t n_hits = 0; + // Fully reimplement this function for linear source + // ... + return n_hits; +} + +double LinearSourceDomain::compute_k_eff(double k_eff_old) const +{ + // Fully reimplement this function for linear source + // ... + return 1.0; +} + +//void LinearSourceDomain::random_ray_tally() +//{ + // Can we just use the base class method? (Do we need this method at all?) + // ... +//} + +void LinearSourceDomain::all_reduce_replicated_source_regions() +{ + // We will first call the base class method as it needs to reduce these + // variables as well + FlatSourceDomain::all_reduce_replicated_source_regions(); + // Then we add in the stuff specific to the linear source class + // ... +} + +//oid LinearSourceDomain::output_to_vtk() const +//{ + // Can we just use the base class method? (Do we need this method at all?) + // ... +//} + +//void LinearSourceDomain::apply_external_source_to_source_region( +// Discrete* discrete, double strength_factor, int64_t source_region) +//{ + // Can we just use the base class method? (Do we need this method at all?) + // ... +//} + +} // namespace openmc \ No newline at end of file From f9692a73b18088e2ff0cae9890d0e542a1a242b5 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 24 Jun 2024 16:23:46 -0500 Subject: [PATCH 02/61] finished linear source dummy implementation and class hierarchy --- include/openmc/constants.h | 2 + include/openmc/random_ray/random_ray.h | 4 ++ .../openmc/random_ray/random_ray_simulation.h | 3 +- openmc/settings.py | 11 +++++ src/random_ray/random_ray.cpp | 24 +++++++++- src/random_ray/random_ray_simulation.cpp | 47 ++++++++++++------- src/settings.cpp | 11 +++++ 7 files changed, 82 insertions(+), 20 deletions(-) diff --git a/include/openmc/constants.h b/include/openmc/constants.h index 1c683e5f50c..340dcc09956 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -342,6 +342,8 @@ enum class RunMode { enum class SolverType { MONTE_CARLO, RANDOM_RAY }; +enum class RandomRaySourceShape { FLAT, LINEAR }; + //============================================================================== // Geometry Constants diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 5ee64574ec1..7c353e608b5 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -25,6 +25,9 @@ class RandomRay : public Particle { // Methods void event_advance_ray(); void attenuate_flux(double distance, bool is_active); + void attenuate_flux_flat_source(double distance, bool is_active); + void attenuate_flux_linear_source(double distance, bool is_active); + void initialize_ray(uint64_t ray_id, FlatSourceDomain* domain); uint64_t transport_history_based_single_ray(); @@ -33,6 +36,7 @@ class RandomRay : public Particle { static double distance_inactive_; // Inactive (dead zone) ray length static double distance_active_; // Active ray length static unique_ptr ray_source_; // Starting source for ray sampling + static RandomRaySourceShape source_shape_; // Flag for linear source //---------------------------------------------------------------------------- // Public data members diff --git a/include/openmc/random_ray/random_ray_simulation.h b/include/openmc/random_ray/random_ray_simulation.h index b439574bfca..c1d47821d7a 100644 --- a/include/openmc/random_ray/random_ray_simulation.h +++ b/include/openmc/random_ray/random_ray_simulation.h @@ -2,6 +2,7 @@ #define OPENMC_RANDOM_RAY_SIMULATION_H #include "openmc/random_ray/flat_source_domain.h" +#include "openmc/random_ray/linear_source_domain.h" namespace openmc { @@ -31,7 +32,7 @@ class RandomRaySimulation { // Data members private: // Contains all flat source region data - FlatSourceDomain domain_; + unique_ptr domain_; // Random ray eigenvalue double k_eff_ {1.0}; diff --git a/openmc/settings.py b/openmc/settings.py index fae6f638364..debb18fb3d4 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -157,6 +157,9 @@ class Settings: :ray_source: Starting ray distribution (must be uniform in space and angle) as specified by a :class:`openmc.SourceBase` object. + :source_shape: + Assumed shape of the source distribution within each source + region. Options are 'flat' (default) or 'linear'. .. versionadded:: 0.15.0 resonance_scattering : dict @@ -1084,6 +1087,9 @@ def random_ray(self, random_ray: dict): random_ray[key], 0.0, True) elif key == 'ray_source': cv.check_type('random ray source', random_ray[key], SourceBase) + elif key == 'source_shape': + cv.check_value('source shape', random_ray[key], + ('flat', 'linear')) else: raise ValueError(f'Unable to set random ray to "{key}" which is ' 'unsupported by OpenMC') @@ -1877,6 +1883,11 @@ def _random_ray_from_xml_element(self, root): elif child.tag == 'source': source = SourceBase.from_xml_element(child) self.random_ray['ray_source'] = source + elif child.tag == 'source_shape': + source = SourceBase.from_xml_element(child) + self.random_ray['ray_source'] = source + elif child.tag == 'source_shape': + self.random_ray['source_shape'] = child.text def to_xml_element(self, mesh_memo=None): """Create a 'settings' element to be written to an XML file. diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 63d728cce8b..018acfc3ee8 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -1,5 +1,6 @@ #include "openmc/random_ray/random_ray.h" +#include "openmc/constants.h" #include "openmc/geometry.h" #include "openmc/message_passing.h" #include "openmc/mgxs_interface.h" @@ -68,6 +69,7 @@ float cjosey_exponential(float tau) double RandomRay::distance_inactive_; double RandomRay::distance_active_; unique_ptr RandomRay::ray_source_; +RandomRaySourceShape RandomRay::source_shape_ {RandomRaySourceShape::FLAT}; RandomRay::RandomRay() : angular_flux_(data::mg.num_energy_groups_), @@ -152,6 +154,20 @@ void RandomRay::event_advance_ray() } } +void RandomRay::attenuate_flux(double distance, bool is_active) +{ + switch (source_shape_) { + case RandomRaySourceShape::FLAT: + attenuate_flux_flat_source(distance, is_active); + break; + case RandomRaySourceShape::LINEAR: + attenuate_flux_linear_source(distance, is_active); + break; + default: + fatal_error("Unknown source shape for random ray transport."); + } +} + // This function forms the inner loop of the random ray transport process. // It is responsible for several tasks. Based on the incoming angular flux // of the ray and the source term in the region, the outgoing angular flux @@ -165,7 +181,7 @@ void RandomRay::event_advance_ray() // than use of many atomic operations corresponding to each energy group // individually (at least on CPU). Several other bookkeeping tasks are also // performed when inside the lock. -void RandomRay::attenuate_flux(double distance, bool is_active) +void RandomRay::attenuate_flux_flat_source(double distance, bool is_active) { // The number of geometric intersections is counted for reporting purposes n_event()++; @@ -236,6 +252,12 @@ void RandomRay::attenuate_flux(double distance, bool is_active) } } +void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) +{ + // Reimplement for linear source + // ... +} + void RandomRay::initialize_ray(uint64_t ray_id, FlatSourceDomain* domain) { domain_ = domain; diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 17866c30208..e2bbe41d89f 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -241,14 +241,25 @@ RandomRaySimulation::RandomRaySimulation() // Random ray mode does not have an inner loop over generations within a // batch, so set the current gen to 1 simulation::current_gen = 1; + + switch (RandomRay::source_shape_) { + case RandomRaySourceShape::FLAT: + domain_ = make_unique(); + break; + case RandomRaySourceShape::LINEAR: + domain_ = make_unique(); + break; + default: + fatal_error("Unknown random ray source shape"); + } } void RandomRaySimulation::simulate() { if (settings::run_mode == RunMode::FIXED_SOURCE) { // Transfer external source user inputs onto random ray source regions - domain_.convert_external_sources(); - domain_.count_external_source_regions(); + domain_->convert_external_sources(); + domain_->count_external_source_regions(); } // Random ray power iteration loop @@ -262,11 +273,11 @@ void RandomRaySimulation::simulate() simulation::total_weight = 1.0; // Update source term (scattering + fission) - domain_.update_neutron_source(k_eff_); + domain_->update_neutron_source(k_eff_); // Reset scalar fluxes, iteration volume tallies, and region hit flags to // zero - domain_.batch_reset(); + domain_->batch_reset(); // Start timer for transport simulation::time_transport.start(); @@ -275,7 +286,7 @@ void RandomRaySimulation::simulate() #pragma omp parallel for schedule(dynamic) \ reduction(+ : total_geometric_intersections_) for (int i = 0; i < simulation::work_per_rank; i++) { - RandomRay ray(i, &domain_); + RandomRay ray(i, domain_.get()); total_geometric_intersections_ += ray.transport_history_based_single_ray(); } @@ -283,18 +294,18 @@ void RandomRaySimulation::simulate() simulation::time_transport.stop(); // If using multiple MPI ranks, perform all reduce on all transport results - domain_.all_reduce_replicated_source_regions(); + domain_->all_reduce_replicated_source_regions(); // Normalize scalar flux and update volumes - domain_.normalize_scalar_flux_and_volumes( + domain_->normalize_scalar_flux_and_volumes( settings::n_particles * RandomRay::distance_active_); // Add source to scalar flux, compute number of FSR hits - int64_t n_hits = domain_.add_source_to_scalar_flux(); + int64_t n_hits = domain_->add_source_to_scalar_flux(); if (settings::run_mode == RunMode::EIGENVALUE) { // Compute random ray k-eff - k_eff_ = domain_.compute_k_eff(k_eff_); + k_eff_ = domain_->compute_k_eff(k_eff_); // Store random ray k-eff into OpenMC's native k-eff variable global_tally_tracklength = k_eff_; @@ -304,19 +315,19 @@ void RandomRaySimulation::simulate() if (simulation::current_batch > settings::n_inactive && mpi::master) { // Generate mapping between source regions and tallies - if (!domain_.mapped_all_tallies_) { - domain_.convert_source_regions_to_tallies(); + if (!domain_->mapped_all_tallies_) { + domain_->convert_source_regions_to_tallies(); } // Use above mapping to contribute FSR flux data to appropriate tallies - domain_.random_ray_tally(); + domain_->random_ray_tally(); // Add this iteration's scalar flux estimate to final accumulated estimate - domain_.accumulate_iteration_flux(); + domain_->accumulate_iteration_flux(); } // Set phi_old = phi_new - domain_.scalar_flux_old_.swap(domain_.scalar_flux_new_); + domain_->scalar_flux_old_.swap(domain_->scalar_flux_new_); // Check for any obvious insabilities/nans/infs instability_check(n_hits, k_eff_, avg_miss_rate_); @@ -347,9 +358,9 @@ void RandomRaySimulation::output_simulation_results() const if (mpi::master) { print_results_random_ray(total_geometric_intersections_, avg_miss_rate_ / settings::n_batches, negroups_, - domain_.n_source_regions_, domain_.n_external_source_regions_); + domain_->n_source_regions_, domain_->n_external_source_regions_); if (model::plots.size() > 0) { - domain_.output_to_vtk(); + domain_->output_to_vtk(); } } } @@ -359,8 +370,8 @@ void RandomRaySimulation::output_simulation_results() const void RandomRaySimulation::instability_check( int64_t n_hits, double k_eff, double& avg_miss_rate) const { - double percent_missed = ((domain_.n_source_regions_ - n_hits) / - static_cast(domain_.n_source_regions_)) * + double percent_missed = ((domain_->n_source_regions_ - n_hits) / + static_cast(domain_->n_source_regions_)) * 100.0; avg_miss_rate += percent_missed; diff --git a/src/settings.cpp b/src/settings.cpp index 6c3226b04a6..308a9176fd2 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -269,6 +269,17 @@ void get_run_parameters(pugi::xml_node node_base) } else { fatal_error("Specify random ray source in settings XML"); } + if (check_for_node(random_ray_node, "source_shape")) { + std::string temp_str = + get_node_value(random_ray_node, "source_shape", true, true); + if (temp_str == "flat") { + RandomRay::source_shape_ = RandomRaySourceShape::FLAT; + } else if (temp_str == "linear") { + RandomRay::source_shape_ = RandomRaySourceShape::LINEAR; + } else { + fatal_error("Unrecognized source shape: " + temp_str); + } + } } } From d554c18c0694001c66cbdc02c150d51e3ecfa92c Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 25 Jun 2024 14:31:40 +0100 Subject: [PATCH 03/61] added in linear sources, need to fix flux swap in RR simulation --- .../openmc/random_ray/flat_source_domain.h | 4 +- .../openmc/random_ray/linear_source_domain.h | 20 +- include/openmc/random_ray/random_ray.h | 5 + .../openmc/random_ray/random_ray_simulation.h | 1 + src/random_ray/linear_source_domain.cpp | 297 +++++++++++++++--- src/random_ray/random_ray.cpp | 279 +++++++++++++++- src/random_ray/random_ray_simulation.cpp | 7 + 7 files changed, 556 insertions(+), 57 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 6ac488840a1..3707e9887e8 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -96,7 +96,7 @@ class FlatSourceDomain { //---------------------------------------------------------------------------- // Methods virtual void update_neutron_source(double k_eff); - virtual double compute_k_eff(double k_eff_old) const; + double compute_k_eff(double k_eff_old) const; virtual void normalize_scalar_flux_and_volumes( double total_active_distance_per_iteration); virtual int64_t add_source_to_scalar_flux(); @@ -106,7 +106,7 @@ class FlatSourceDomain { void random_ray_tally(); void accumulate_iteration_flux(); void output_to_vtk() const; - virtual void all_reduce_replicated_source_regions(); + void all_reduce_replicated_source_regions(); void convert_external_sources(); void count_external_source_regions(); diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 197806469a7..03c68578f7e 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -9,7 +9,7 @@ namespace openmc { - /* +/* * The LinearSourceDomain class encompasses data and methods for storing * scalar flux and source region for all flat source regions in a * random ray simulation domain. @@ -24,7 +24,7 @@ class LinearSourceDomain : public FlatSourceDomain { //---------------------------------------------------------------------------- // Methods void update_neutron_source(double k_eff) override; - double compute_k_eff(double k_eff_old) const override; + double compute_k_eff(double k_eff_old) const; // override void normalize_scalar_flux_and_volumes( double total_active_distance_per_iteration) override; int64_t add_source_to_scalar_flux() override; @@ -34,14 +34,26 @@ class LinearSourceDomain : public FlatSourceDomain { void random_ray_tally(); void accumulate_iteration_flux(); void output_to_vtk() const; - void all_reduce_replicated_source_regions() override; + void all_reduce_replicated_source_regions(); //override void convert_external_sources(); void count_external_source_regions(); //---------------------------------------------------------------------------- // Public Data members - // ... + vector flux_x_new_; + vector flux_x_old_; + vector source_x_; + vector flux_y_new_; + vector flux_y_old_; + vector source_y_; + vector flux_z_new_; + vector flux_z_old_; + vector source_z_; + vector centroid_; + vector centroid_t_; + vector mom_matrix_; + vector mom_matrix_t_; private: //---------------------------------------------------------------------------- diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 7c353e608b5..ecb320e6722 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -46,6 +46,11 @@ class RandomRay : public Particle { //---------------------------------------------------------------------------- // Private data members vector delta_psi_; + vector delta_x_; + vector delta_y_; + vector delta_z_; + vector mat_score_; + int negroups_; FlatSourceDomain* domain_ {nullptr}; // pointer to domain that has flat source // data needed for ray transport diff --git a/include/openmc/random_ray/random_ray_simulation.h b/include/openmc/random_ray/random_ray_simulation.h index c1d47821d7a..2452b962ae1 100644 --- a/include/openmc/random_ray/random_ray_simulation.h +++ b/include/openmc/random_ray/random_ray_simulation.h @@ -33,6 +33,7 @@ class RandomRaySimulation { private: // Contains all flat source region data unique_ptr domain_; + //unique_ptr domain_ls_; // Random ray eigenvalue double k_eff_ {1.0}; diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index edfb4678524..1a31e453cb4 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -24,80 +24,281 @@ namespace openmc { LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() { - // The base class constructor is already called, so just need to initialize - // the extra linear source members below - // ... + flux_x_new_.assign(n_source_elements_, 0.0); + flux_x_old_.assign(n_source_elements_, 0.0); + source_x_.assign(n_source_elements_, 0.0); + flux_y_new_.assign(n_source_elements_, 0.0); + flux_y_old_.assign(n_source_elements_, 0.0); + source_y_.assign(n_source_elements_, 0.0); + flux_z_new_.assign(n_source_elements_, 0.0); + flux_z_old_.assign(n_source_elements_, 0.0); + source_z_.assign(n_source_elements_, 0.0); + + centroid_.assign(n_source_regions_ * 3, nan("")); + centroid_t_.assign(n_source_regions_ * 3, 0.0); + mom_matrix_.assign(n_source_regions_ * 6, 0.0); + mom_matrix_t_.assign(n_source_regions_ * 6, 0.0); } void LinearSourceDomain::batch_reset() { - // We will first call the base class method as it needs to reset these - // variables as well FlatSourceDomain::batch_reset(); - // And then we add in the stuff specific to the linear source class as well - // ... + parallel_fill(flux_x_new_, 0.0f); + parallel_fill(flux_y_new_, 0.0f); + parallel_fill(flux_z_new_, 0.0f); } -void LinearSourceDomain::accumulate_iteration_flux() +// void LinearSourceDomain::accumulate_iteration_flux() +// { +// // Fully reimplement this function for linear source +// // ... +// } + +// Calculate source gradients by inverting the moment matrix +void moment_matrix_inversion(const std::vector& mom_matrix_, int sr, double& invM1, double& invM2, + double& invM3, double& invM4, double& invM5, double& invM6) { - // Fully reimplement this function for linear source - // ... + int64_t midx = sr * 6; + double det = mom_matrix_[midx + 0] * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]) - + mom_matrix_[midx + 3] * mom_matrix_[midx + 2] * mom_matrix_[midx + 2] - + mom_matrix_[midx + 5] * mom_matrix_[midx + 1] * mom_matrix_[midx + 1] + + 2 * mom_matrix_[midx + 1] * mom_matrix_[midx + 2] * mom_matrix_[midx + 4]; + if ( abs(det) > 0.0 ) { //1E-10 + double one_det = 1.0 / det; + invM1 = one_det * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]); + invM2 = one_det * (mom_matrix_[midx + 2] * mom_matrix_[midx + 4] - mom_matrix_[midx + 1] * mom_matrix_[midx + 5]); + invM3 = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 4] - mom_matrix_[midx + 3] * mom_matrix_[midx + 2]); + invM4 = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 5] - mom_matrix_[midx + 2] * mom_matrix_[midx + 2]); + invM5 = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 2] - mom_matrix_[midx + 0] * mom_matrix_[midx + 4]); + invM6 = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 3] - mom_matrix_[midx + 1] * mom_matrix_[midx + 1]); + } else { + invM1 = 0.0; + invM2 = 0.0; + invM3 = 0.0; + invM4 = 0.0; + invM5 = 0.0; + invM6 = 0.0; + det = 1.0; + } + } void LinearSourceDomain::update_neutron_source(double k_eff) { - // Fully reimplement this function for linear source - // ... +std::cout << "new" << std::endl; +simulation::time_update_src.start(); + + double inverse_k_eff = 1.0 / k_eff; + + // Temperature and angle indices, if using multiple temperature + // data sets and/or anisotropic data sets. + // TODO: Currently assumes we are only using single temp/single + // angle data. + const int t = 0; + const int a = 0; + //double det; + + #pragma omp parallel for + for (int sr = 0; sr < n_source_regions_; sr++) { + int material = material_[sr]; + double invM1, invM2, invM3, invM4, invM5, invM6; + moment_matrix_inversion(mom_matrix_, sr, invM1, invM2, invM3, invM4, invM5, invM6); + + for (int e_out = 0; e_out < negroups_; e_out++) { + float sigma_t = data::mg.macro_xs_[material].get_xs( + MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); + + float scatter_source = 0.0f; + float fission_source = 0.0f; + float x_scatter = 0.0f; + float y_scatter = 0.0f; + float z_scatter = 0.0f; + float x_fission = 0.0f; + float y_fission = 0.0f; + float z_fission = 0.0f; + + for (int e_in = 0; e_in < negroups_; e_in++) { + float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; + float flux_x = flux_x_old_[sr * negroups_ + e_in]; + float flux_y = flux_y_old_[sr * negroups_ + e_in]; + float flux_z = flux_z_old_[sr * negroups_ + e_in]; + float sigma_s = data::mg.macro_xs_[material].get_xs( + MgxsType::NU_SCATTER, e_in, &e_out, nullptr, nullptr, t, a); + float nu_sigma_f = data::mg.macro_xs_[material].get_xs( + MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); + float chi = data::mg.macro_xs_[material].get_xs( + MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); + scatter_source += sigma_s * scalar_flux; + fission_source += nu_sigma_f * scalar_flux * chi; + // Calculate scattering source for higher order scattering + x_scatter += sigma_s * flux_x ; + y_scatter += sigma_s * flux_y ; + z_scatter += sigma_s * flux_z; + x_fission += nu_sigma_f * flux_x * chi; + y_fission += nu_sigma_f * flux_y * chi; + z_fission += nu_sigma_f * flux_z * chi; + } + + fission_source *= inverse_k_eff; + float new_isotropic_source = (scatter_source + fission_source) / sigma_t; + source_[sr * negroups_ + e_out] = new_isotropic_source; + + if (simulation::current_batch > 2) { + + x_fission *= inverse_k_eff; + y_fission *= inverse_k_eff; + z_fission *= inverse_k_eff; + + float x_source = (x_scatter + x_fission) / sigma_t; + float y_source = (y_scatter + y_fission) / sigma_t; + float z_source = (z_scatter + z_fission) / sigma_t; + + float new_source_x = invM1 * x_source + invM2 * y_source + invM3 * z_source; + float new_source_y = invM2 * x_source + invM4 * y_source + invM5 * z_source; + float new_source_z = invM3 * x_source + invM5 * y_source + invM6 * z_source; + source_x_[sr * negroups_ + e_out] = new_source_x; + source_y_[sr * negroups_ + e_out] = new_source_y; + source_z_[sr * negroups_ + e_out] = new_source_z; + + } + } + } + + simulation::time_update_src.stop(); } void LinearSourceDomain::normalize_scalar_flux_and_volumes( double total_active_distance_per_iteration) - { - // Fully reimplement this function for linear source - // ... +{ + float normalization_factor = 1.0 / total_active_distance_per_iteration; + double volume_normalization_factor = + 1.0 / (total_active_distance_per_iteration * simulation::current_batch); + +// Normalize flux to total distance travelled by all rays this iteration +#pragma omp parallel for + for (int64_t e = 0; e < scalar_flux_new_.size(); e++) { + scalar_flux_new_[e] *= normalization_factor; + flux_x_new_[e] *= normalization_factor; + flux_y_new_[e] *= normalization_factor; + flux_z_new_[e] *= normalization_factor; } - int64_t LinearSourceDomain::add_source_to_scalar_flux() -{ - int64_t n_hits = 0; - // Fully reimplement this function for linear source - // ... - return n_hits; +// Accumulate cell-wise ray length tallies collected this iteration, then +// update the simulation-averaged cell-wise volume estimates +#pragma omp parallel for + for (int64_t sr = 0; sr < n_source_regions_; sr++) { + volume_t_[sr] += volume_[sr]; + volume_[sr] = volume_t_[sr] * volume_normalization_factor; + } } -double LinearSourceDomain::compute_k_eff(double k_eff_old) const + +int64_t LinearSourceDomain::add_source_to_scalar_flux() { - // Fully reimplement this function for linear source - // ... - return 1.0; -} + int64_t n_hits = 0; -//void LinearSourceDomain::random_ray_tally() -//{ - // Can we just use the base class method? (Do we need this method at all?) - // ... -//} + // Temperature and angle indices, if using multiple temperature + // data sets and/or anisotropic data sets. + // TODO: Currently assumes we are only using single temp/single + // angle data. + const int t = 0; + const int a = 0; -void LinearSourceDomain::all_reduce_replicated_source_regions() -{ - // We will first call the base class method as it needs to reduce these - // variables as well - FlatSourceDomain::all_reduce_replicated_source_regions(); - // Then we add in the stuff specific to the linear source class - // ... +#pragma omp parallel for reduction(+ : n_hits) + for (int sr = 0; sr < n_source_regions_; sr++) { + + double volume = volume_[sr]; + double volume_tracks = volume_t_[sr]; + double invvol = 1.0f / volume_tracks; + int material = material_[sr]; + int64_t didx = sr * 3; + int64_t midx = sr * 6; + + // Check if this cell was hit this iteration + int was_cell_hit = was_hit_[sr]; + if (was_cell_hit) { + n_hits++; + } + + for (int g = 0; g < negroups_; g++) { + int64_t idx = (sr * negroups_) + g; + // There are three scenarios we need to consider: + if (was_cell_hit) { + // 1. If the FSR was hit this iteration, then the new flux is equal to + // the flat source from the previous iteration plus the contributions + // from rays passing through the source region (computed during the + // transport sweep) + scalar_flux_new_[idx] /= volume; + scalar_flux_new_[idx] += source_[idx]; + flux_x_new_[idx] /= volume ; + flux_y_new_[idx] /= volume ; + flux_z_new_[idx] /= volume ; + for (int i = 0; i < 3; i++) { // Update centroids + centroid_[didx + i] = centroid_t_[didx + i] * invvol; + } + for (int i = 0; i < 6; i++) { // Update spatial moments + mom_matrix_[midx + i] = mom_matrix_t_[midx + i] * invvol; + } + } else if (volume > 0.0) { + // 2. If the FSR was not hit this iteration, but has been hit some + // previous iteration, then we simply set the new scalar flux to be + // equal to the contribution from the flat source alone. + scalar_flux_new_[idx] = source_[idx]; + flux_x_new_[idx] /= volume ; + flux_y_new_[idx] /= volume ; + flux_z_new_[idx] /= volume ; + for (int i = 0; i < 3; i++) { // Update centroids + centroid_[didx + i] = centroid_t_[didx + i] * invvol; + } + for (int i = 0; i < 6; i++) { // Update spatial moments + mom_matrix_[midx + i] = mom_matrix_t_[midx + i] * invvol; + } + } else { + // If the FSR was not hit this iteration, and it has never been hit in + // any iteration (i.e., volume is zero), then we want to set this to 0 + // to avoid dividing anything by a zero volume. + scalar_flux_new_[idx] = 0.0f; + flux_x_new_[idx] = 0.0f ; + flux_y_new_[idx] = 0.0f ; + flux_z_new_[idx] = 0.0f ; + } + } + } + + return n_hits; } -//oid LinearSourceDomain::output_to_vtk() const -//{ - // Can we just use the base class method? (Do we need this method at all?) - // ... -//} +// double LinearSourceDomain::compute_k_eff(double k_eff_old) const +// { +// FlatSourceDomain::compute_k_eff(k_eff_old); +// } + +// void LinearSourceDomain::random_ray_tally() +// { +// // Can we just use the base class method? (Do we need this method at all?) +// // ... +// } + +// void LinearSourceDomain::all_reduce_replicated_source_regions() +// { +// // We will first call the base class method as it needs to reduce these +// // variables as well +// FlatSourceDomain::all_reduce_replicated_source_regions(); +// // Then we add in the stuff specific to the linear source class +// // ... +// } + +// void LinearSourceDomain::output_to_vtk() const +// { +// // Can we just use the base class method? (Do we need this method at all?) +// // ... +// } -//void LinearSourceDomain::apply_external_source_to_source_region( +// void LinearSourceDomain::apply_external_source_to_source_region( // Discrete* discrete, double strength_factor, int64_t source_region) -//{ - // Can we just use the base class method? (Do we need this method at all?) - // ... -//} +// { +// Can we just use the base class method? (Do we need this method at all?) +// ... +// } } // namespace openmc \ No newline at end of file diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 018acfc3ee8..63aac48766d 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -5,6 +5,7 @@ #include "openmc/message_passing.h" #include "openmc/mgxs_interface.h" #include "openmc/random_ray/flat_source_domain.h" +#include "openmc/random_ray/linear_source_domain.h" #include "openmc/search.h" #include "openmc/settings.h" #include "openmc/simulation.h" @@ -58,6 +59,91 @@ float cjosey_exponential(float tau) num = num * x + c1n; num = num * x; + return num / den; +} +// Computes y = 1/x-(1-exp(-x))/x**2 using a 5/6th order rational approximation. +// OpenMoC https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 + +float exponentialG(float tau) +{ + // Numerator coefficients in rational approximation for 1/x - (1 - exp(-x)) / x^2 + constexpr float d0n = 0.5f; + constexpr float d1n = 0.176558112351595f; + constexpr float d2n = 0.04041584305811143f; + constexpr float d3n = 0.006178333902037397f; + constexpr float d4n = 0.0006429894635552992f; + constexpr float d5n = 0.00006064409107557148f; + + // Denominator coefficients in rational approximation for 1/x - (1 - exp(-x)) / x^2 + constexpr float d0d = 1.0f; + constexpr float d1d = 0.6864462055546078f; + constexpr float d2d = 0.2263358514260129f; + constexpr float d3d = 0.04721469893686252f; + constexpr float d4d = 0.006883236664917246f; + constexpr float d5d = 0.0007036272419147752f; + constexpr float d6d = 0.00006064409107557148f; + + float x = tau; + + float num = d5n; + num = num * x + d4n; + num = num * x + d3n; + num = num * x + d2n; + num = num * x + d1n; + num = num * x + d0n; + + float den = d6d; + den = den * x + d5d; + den = den * x + d4d; + den = den * x + d3d; + den = den * x + d2d; + den = den * x + d1d; + den = den * x + d0d; + + + return num / den; +} + +// Computes G2 : y = 2/3 - (1 + 2/x) * (1/x + 0.5 - (1 + 1/x) * (1-exp(-x)) / x) +// using a 5/5th order rational approximation, +// FROM: OpenMoC https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 + + +float exponentialG2(float tau) +{ + + // Coefficients for numerator in rational approximation + constexpr float g1n = -0.08335775885589858f; + constexpr float g2n = -0.003603942303847604f; + constexpr float g3n = 0.0037673183263550827f; + constexpr float g4n = 0.00001124183494990467f; + constexpr float g5n = 0.00016837426505799449f; + + // Coefficients for denominator in rational approximation + constexpr float g1d = 0.7454048371823628f; + constexpr float g2d = 0.23794300531408347f; + constexpr float g3d = 0.05367250964303789f; + constexpr float g4d = 0.006125197988351906f; + constexpr float g5d = 0.0010102514456857377f; + + float x = tau; + + float num = g5n; + num = num * x + g4n; + num = num * x + g3n; + num = num * x + g2n; + num = num * x + g1n; + num = num * x; + + float den = g5d; + den = den * x + g4d; + den = den * x + g3d; + den = den * x + g2d; + den = den * x + g1d; + den = den * x + 1.0f; + + + return num / den; } @@ -74,7 +160,17 @@ RandomRaySourceShape RandomRay::source_shape_ {RandomRaySourceShape::FLAT}; RandomRay::RandomRay() : angular_flux_(data::mg.num_energy_groups_), delta_psi_(data::mg.num_energy_groups_), - negroups_(data::mg.num_energy_groups_) + negroups_(data::mg.num_energy_groups_), + delta_x_(data::mg.num_energy_groups_), + delta_y_(data::mg.num_energy_groups_), + delta_z_(data::mg.num_energy_groups_), + mat_score_(6) + // prev_angular_flux_(data::mg.num_energy_groups_), + // flat_source_(data::mg.num_energy_groups_), + // dir_source_(data::mg.num_energy_groups_), + // exp_gn_(data::mg.num_energy_groups_), + // exp_f1_(data::mg.num_energy_groups_), + // tau_(data::mg.num_energy_groups_), {} RandomRay::RandomRay(uint64_t ray_id, FlatSourceDomain* domain) : RandomRay() @@ -254,8 +350,185 @@ void RandomRay::attenuate_flux_flat_source(double distance, bool is_active) void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) { - // Reimplement for linear source - // ... + + LinearSourceDomain* domain = static_cast(domain_); + // The number of geometric intersections is counted for reporting purposes + n_event()++; + + // Determine source region index etc. + int i_cell = lowest_coord().cell; + + // The source region is the spatial region index + int64_t source_region = + domain_->source_region_offsets_[i_cell] + cell_instance(); + + // The source element is the energy-specific region index + int64_t source_element = source_region * negroups_; + int64_t midx = source_region * 6 ; + int64_t didx = source_region * 3 ; + int material = this->material(); + + // Temperature and angle indices, if using multiple temperature + // data sets and/or anisotropic data sets. + // TODO: Currently assumes we are only using single temp/single + // angle data. + const int t = 0; + const int a = 0; + + Position centroid_pos(domain->centroid_[didx + 0], + domain->centroid_[didx + 1], + domain->centroid_[didx + 2]); + Position midpoint = r() + u() * (distance / 2.0); + Position rm_local; + Position r0_local; + //if (simulation::current_batch > 2) { + if (centroid_pos[0] == centroid_pos[0]) { + rm_local = midpoint - centroid_pos; + r0_local = r() - centroid_pos; + } else{ + r0_local = -u() * 0.5 * distance; + } + // linear source terms + // for (int g = 0; g < negroups_; g++) { + // flat_source_[g] = rm_local[0] * domain->source_x_[source_element + g]; + // flat_source_[g] = flat_source_[g] + rm_local[1] * domain->source_y_[source_element + g]; + // flat_source_[g] = flat_source_[g] + rm_local[2] * domain->source_z_[source_element + g]; + // flat_source_[g] = flat_source_[g] + domain->source_[source_element + g]; + // dir_source_[g] = u()[0] * domain->source_x_[source_element + g]; + // dir_source_[g] = dir_source_[g] + u()[1] * domain->source_y_[source_element + g]; //u()[1] + // dir_source_[g] = dir_source_[g] + u()[2] * domain->source_z_[source_element + g]; + + // prev_angular_flux_[g] = angular_flux_[g]; + // } + +//everything in one loop, wastes LS comp calculation that might not be needed (dead length) +//less arrays to store + + // MOC incoming flux attenuation + source contribution/attenuation equation + for (int g = 0; g < negroups_; g++) { + float sigma_t = data::mg.macro_xs_[material].get_xs( + MgxsType::TOTAL, g, NULL, NULL, NULL, t, a); + float tau = sigma_t * distance; + float flat_source = rm_local[0] * domain->source_x_[source_element + g] + + rm_local[1] * domain->source_y_[source_element + g] + rm_local[2] * + domain->source_z_[source_element + g] + domain_->source_[source_element + g]; + float dir_source = u()[0] * domain->source_x_[source_element + g] + + u()[1] * domain->source_y_[source_element + g] + + u()[2] * domain->source_z_[source_element + g]; + + if (tau < 1E-8f) { + tau = 0.0f; + } + float gn = exponentialG(tau); + float f1 = 1.0f - tau * gn; + float f2 = (2.0f * gn - f1) * distance * distance; + float new_delta_psi = + (angular_flux_[g] - flat_source) * f1 * distance + - 0.5 * dir_source * f2; + delta_psi_[g] = new_delta_psi; + // prev_angular_flux_[g] = angular_flux_[g]; + float h1 = f1 - gn; + float g1 = 0.5f - h1; + float g2 = exponentialG2(tau); + g1 = g1 * flat_source * distance; + g2 = g2 * dir_source * distance * distance * 0.5f; + h1 = h1 * angular_flux_[g] * distance; + h1 = (g1 + g2 + h1) * distance; + float new_flat_source = flat_source * distance + new_delta_psi; + flat_source = new_flat_source; + float new_delta_x = r0_local[0] * flat_source + u()[0] * h1; + delta_x_[g] = new_delta_x; + float new_delta_y = r0_local[1] * flat_source + u()[1] * h1; + delta_y_[g] = new_delta_y; + float new_delta_z = r0_local[2] * flat_source + u()[2] * h1; + delta_z_[g] = new_delta_y; + angular_flux_[g] -= new_delta_psi * sigma_t; + } + // for (int g = 0; g < negroups_; g++) { + // float sigma_t = data::mg.macro_xs_[material].get_xs( + // MgxsType::TOTAL, g, NULL, NULL, NULL, t, a); + // float tau = sigma_t * distance; + // if (tau < 1E-8f) { + // tau = 0.0f; + // } + // tau_[g] = tau; + // exp_gn_[g] = exponentialG(tau); + // exp_f1_[g] = 1.0f - tau * exp_gn_[g]; + // float f2 = (2.0f * exp_gn_[g] - exp_f1_[g]) * distance * distance; + // float new_delta_psi = + // (angular_flux_[g] - flat_source_[g]) * exp_f1_[g] * distance + // - 0.5 * dir_source_[g] * f2; + // delta_psi_[g] = new_delta_psi; + // angular_flux_[g] -= new_delta_psi * sigma_t; + // } + + // If ray is in the active phase (not in dead zone), make contributions to + // source region bookkeeping + if (is_active) { + double distance2_12 = distance * distance / 12.0; + mat_score_[0] = distance * (rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12); + mat_score_[1] = distance * (rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12); + mat_score_[2] = distance * (rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12); + mat_score_[3] = distance * (rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12); + mat_score_[4] = distance * (rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12); + mat_score_[5] = distance * (rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12); + + // for (int g = 0; g < negroups_; g++) { + // float h1 = exp_f1_[g] - exp_gn_[g]; + // float g1 = 0.5f - h1; + // float g2 = exponentialG2(tau_[g]); + // g1 = g1 * flat_source_[g] * distance; + // g2 = g2 * dir_source_[g] * distance * distance * 0.5f; + // float new_h1 = h1 * prev_angular_flux_[g] * distance; + // h1 = new_h1; + // h1 = (g1 + g2 + h1) * distance; + // float new_flat_source = flat_source_[g] * distance + delta_psi_[g]; + // flat_source_[g] = new_flat_source; + // float new_delta_x = r0_local[0] * flat_source_[g] + u()[0] * h1; + // delta_x_[g] = new_delta_x; + // float new_delta_y = r0_local[1] * flat_source_[g] + u()[1] * h1; + // delta_y_[g] = new_delta_y; + // float new_delta_z = r0_local[2] * flat_source_[g] + u()[2] * h1; + // delta_z_[g] = new_delta_y; + // } + + // Aquire lock for source region + domain_->lock_[source_region].lock(); + // Accumulate delta psi into new estimate of source region flux for + // this iteration + for (int g = 0; g < negroups_; g++) { + domain_->scalar_flux_new_[source_element + g] += delta_psi_[g]; + domain->flux_x_new_[source_element + g] += delta_x_[g]; + domain->flux_y_new_[source_element + g] += delta_y_[g]; + domain->flux_z_new_[source_element + g] += delta_z_[g]; + } + for (int i = 0; i < 6; i++) { + domain->mom_matrix_t_[midx + i] += mat_score_[i]; + } + for (int i = 0; i < 3; i++) { + domain->centroid_t_[didx + i] += midpoint[i] * distance ; + } + + // If the source region hasn't been hit yet this iteration, + // indicate that it now has + if (domain_->was_hit_[source_region] == 0) { + domain_->was_hit_[source_region] = 1; + } + + // Accomulate volume (ray distance) into this iteration's estimate + // of the source region's volume + domain_->volume_[source_region] += distance; + + // Tally valid position inside the source region (e.g., midpoint of + // the ray) if not done already + if (!domain_->position_recorded_[source_region]) { + domain_->position_[source_region] = midpoint; + domain_->position_recorded_[source_region] = 1; + } + + // Release lock + domain_->lock_[source_region].unlock(); + } } void RandomRay::initialize_ray(uint64_t ray_id, FlatSourceDomain* domain) diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index e2bbe41d89f..9047c09ed3d 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -13,6 +13,8 @@ #include "openmc/tallies/tally.h" #include "openmc/tallies/tally_scoring.h" #include "openmc/timer.h" +#include "openmc/random_ray/flat_source_domain.h" +#include "openmc/random_ray/linear_source_domain.h" namespace openmc { @@ -327,7 +329,12 @@ void RandomRaySimulation::simulate() } // Set phi_old = phi_new + + //LinearSourceDomain* domain = static_cast(domain_); domain_->scalar_flux_old_.swap(domain_->scalar_flux_new_); + domain_->flux_x_old_.swap(domain_->flux_x_new_); + domain_->flux_y_old_.swap(domain_->flux_y_new_); + domain_->flux_z_old_.swap(domain_->flux_z_new_); // Check for any obvious insabilities/nans/infs instability_check(n_hits, k_eff_, avg_miss_rate_); From cc905125255329effec93d3cd86ea36f8db98499 Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 25 Jun 2024 14:39:34 +0100 Subject: [PATCH 04/61] added method for flux swap --- include/openmc/random_ray/flat_source_domain.h | 1 + include/openmc/random_ray/linear_source_domain.h | 1 + include/openmc/random_ray/random_ray_simulation.h | 1 - src/random_ray/flat_source_domain.cpp | 4 ++++ src/random_ray/linear_source_domain.cpp | 9 +++++++++ src/random_ray/random_ray_simulation.cpp | 7 +------ 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 3707e9887e8..85fb8b845bc 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -109,6 +109,7 @@ class FlatSourceDomain { void all_reduce_replicated_source_regions(); void convert_external_sources(); void count_external_source_regions(); + virtual void flux_swap(); //---------------------------------------------------------------------------- // Public Data members diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 03c68578f7e..f245d15907d 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -37,6 +37,7 @@ class LinearSourceDomain : public FlatSourceDomain { void all_reduce_replicated_source_regions(); //override void convert_external_sources(); void count_external_source_regions(); + void flux_swap() override; //---------------------------------------------------------------------------- // Public Data members diff --git a/include/openmc/random_ray/random_ray_simulation.h b/include/openmc/random_ray/random_ray_simulation.h index 2452b962ae1..c1d47821d7a 100644 --- a/include/openmc/random_ray/random_ray_simulation.h +++ b/include/openmc/random_ray/random_ray_simulation.h @@ -33,7 +33,6 @@ class RandomRaySimulation { private: // Contains all flat source region data unique_ptr domain_; - //unique_ptr domain_ls_; // Random ray eigenvalue double k_eff_ {1.0}; diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 7f5d76943e5..8e4926956f7 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -928,5 +928,9 @@ void FlatSourceDomain::convert_external_sources() } } } +void FlatSourceDomain::flux_swap() +{ +scalar_flux_old_.swap(scalar_flux_new_); +} } // namespace openmc diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 1a31e453cb4..8c9ab3e6cb0 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -301,4 +301,13 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // ... // } +void LinearSourceDomain::flux_swap() +{ + FlatSourceDomain::flux_swap(); + flux_x_old_.swap(flux_x_new_); + flux_y_old_.swap(flux_y_new_); + flux_z_old_.swap(flux_z_new_); +} + + } // namespace openmc \ No newline at end of file diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 9047c09ed3d..02e9b30d2f6 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -329,12 +329,7 @@ void RandomRaySimulation::simulate() } // Set phi_old = phi_new - - //LinearSourceDomain* domain = static_cast(domain_); - domain_->scalar_flux_old_.swap(domain_->scalar_flux_new_); - domain_->flux_x_old_.swap(domain_->flux_x_new_); - domain_->flux_y_old_.swap(domain_->flux_y_new_); - domain_->flux_z_old_.swap(domain_->flux_z_new_); + domain_->flux_swap(); // Check for any obvious insabilities/nans/infs instability_check(n_hits, k_eff_, avg_miss_rate_); From 50a9cb99a0d9f7208eb013caaf071c99a9a61a98 Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 25 Jun 2024 14:57:35 +0100 Subject: [PATCH 05/61] removed prints/include --- src/random_ray/linear_source_domain.cpp | 1 - src/random_ray/random_ray_simulation.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 8c9ab3e6cb0..2fa0daa87ef 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -85,7 +85,6 @@ void moment_matrix_inversion(const std::vector& mom_matrix_, int sr, dou void LinearSourceDomain::update_neutron_source(double k_eff) { -std::cout << "new" << std::endl; simulation::time_update_src.start(); double inverse_k_eff = 1.0 / k_eff; diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 02e9b30d2f6..20d20f1580d 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -14,7 +14,6 @@ #include "openmc/tallies/tally_scoring.h" #include "openmc/timer.h" #include "openmc/random_ray/flat_source_domain.h" -#include "openmc/random_ray/linear_source_domain.h" namespace openmc { From a09fa9713494379768622c94d0c08010e44b9a72 Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 25 Jun 2024 17:13:43 +0100 Subject: [PATCH 06/61] added external source to source, for fixed source calculations --- src/random_ray/linear_source_domain.cpp | 38 ++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 2fa0daa87ef..42579d91e19 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -108,7 +108,6 @@ simulation::time_update_src.start(); MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); float scatter_source = 0.0f; - float fission_source = 0.0f; float x_scatter = 0.0f; float y_scatter = 0.0f; float z_scatter = 0.0f; @@ -128,7 +127,6 @@ simulation::time_update_src.start(); float chi = data::mg.macro_xs_[material].get_xs( MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); scatter_source += sigma_s * scalar_flux; - fission_source += nu_sigma_f * scalar_flux * chi; // Calculate scattering source for higher order scattering x_scatter += sigma_s * flux_x ; y_scatter += sigma_s * flux_y ; @@ -138,8 +136,9 @@ simulation::time_update_src.start(); z_fission += nu_sigma_f * flux_z * chi; } - fission_source *= inverse_k_eff; - float new_isotropic_source = (scatter_source + fission_source) / sigma_t; + + // fission_source *= inverse_k_eff; + float new_isotropic_source = (scatter_source) / sigma_t; source_[sr * negroups_ + e_out] = new_isotropic_source; if (simulation::current_batch > 2) { @@ -163,6 +162,37 @@ simulation::time_update_src.start(); } } + if (settings::run_mode == RunMode::EIGENVALUE) { + #pragma omp parallel for + for (int sr = 0; sr < n_source_regions_; sr++) { + int material = material_[sr]; + + for (int e_out = 0; e_out < negroups_; e_out++) { + float sigma_t = data::mg.macro_xs_[material].get_xs( + MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); + float fission_source = 0.0f; + + for (int e_in = 0; e_in < negroups_; e_in++) { + float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; + float nu_sigma_f = data::mg.macro_xs_[material].get_xs( + MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); + float chi = data::mg.macro_xs_[material].get_xs( + MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); + fission_source += nu_sigma_f * scalar_flux * chi; + } + source_[sr * negroups_ + e_out] += + fission_source * inverse_k_eff / sigma_t; + } + } + } + else { + // Add external source if in fixed source mode + #pragma omp parallel for + for (int se = 0; se < n_source_elements_; se++) { + source_[se] += external_source_[se]; + } + } + simulation::time_update_src.stop(); } From 74d913d18fd1b8b725ac9703d6f7164a29f9739a Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 25 Jun 2024 23:01:23 +0100 Subject: [PATCH 07/61] added LS method section --- docs/source/methods/random_ray.rst | 140 ++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index 427ba11489f..8b769d44fa0 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -218,8 +218,7 @@ Following the multigroup discretization, another assumption made is that a large and complex problem can be broken up into small constant cross section regions, and that these regions have group dependent, flat, isotropic sources (fission and scattering), :math:`Q_g`. Anisotropic as well as higher order sources are -also possible with MOC-based methods but are not used yet in OpenMC for -simplicity. With these key assumptions, the multigroup MOC form of the neutron +also possible with MOC-based methods. With these key assumptions, the multigroup MOC form of the neutron transport equation can be written as in Equation :eq:`moc_final`. .. math:: @@ -287,7 +286,7 @@ final expression for the average angular flux for a ray crossing a region as: .. math:: :label: average_psi_final - \overline{\psi}_{r,i,g} = \frac{Q_{i,g}}{\Sigma_{t,i,g}} + \frac{\Delta \psi_{r,g}}{\ell_r \Sigma_{t,i,g}} + \overline{\psi}_{r,i,g} = \frac{Q_{i,g}}{\Sigma_{t,i,g}} + \frac{\Delta \psi_{r,g}}{\ell_r \Sigma_{t,i,g}}. ~~~~~~~~~~~ Random Rays @@ -756,6 +755,137 @@ to OpenMC, but for now this restriction needs to be respected. .. _usersguide_fixed_source_methods: +-------------------------- +Random Ray Linear Sources +-------------------------- +Instead of making the flat source approximation, that was used in the previous section, a Linear Source (LS) approximation can be used. Different LS approximations +have been developed, the OpenMC implementation follows the scheme described by `Ferrer `_. The LS source along a characterstic is given by: + +.. math:: + :label: linear_source + + Q_{r,i,g}(s) = \bar{Q}_{r,i,g} + \hat{Q}_{r,i,g}(s-\ell_{r}/2), + +where the source, :math:`Q_{i,g,r}(s)`, varies linearly along the track and :math:`\bar{Q}_{i,g,r}` and :math:`\hat{Q}_{i,g,r}` are track specific source terms we will define shortly. +Integrating the source, following :eq:`moc_final`, leads to + +.. math:: + :label: lsr_attenuation + + \psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{i, g, r}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) + F_{1}\left(\tau_{i,g}\right)+\frac{\hat{Q}_{i, g, r}^{g}}{2\left(\Sigma_{\mathrm{t}, i,g}\right)^{2}} F_{2}\left(\tau_{i,g}\right), + +where for simplicity we have introduced :math:`\tau_{i,g}` and the expoential terms :math:`F1` and :math:`F2`, given by: + +.. math:: + :label: tau + + \tau_{i,g} = \Sigma_{\mathrm{t,i,g}} \ell_{r} + +.. math:: + :label: f1 + + F_1(\tau) = 1 - e^{-\tau}, + +and + +.. math:: + :label: f2 + + F_{2}\left(\tau\right) = 2\left[\tau-F_{1}\left(\tau\right)\right]-\tau F_{1}\left(\tau\right). + + +To solve for the track specific terms we start by defining a local reference frame. If we now refer to :math:`\mathbf{r}` +as our global coordinate and introduce the source region specific coordinate :math:`\mathbf{u}` such that, + +.. math:: + :label: local_coord + + \mathbf{u}_{r} = \mathbf{r}-\mathbf{r}_{\mathrm{c}}, + +where :math:`\mathbf{r}_{\mathrm{c}}` is the centroid of the source region of interest and in turn +:math:`\mathbf{u}_{r,\mathrm{c}}` and :math:`\mathbf{u}_{r,0}` are the local centroid and entry positions of a ray. +The computation of the local and global centroids are described further by `Gunow `_. + +Using the local position the source in a source region is given by: + +.. math:: + :label: region_source + + \tilde{Q}(\boldsymbol{x}) ={Q}_{i,g}+ \boldsymbol{\vec{Q}}_{i,g} \cdot \mathbf{u}_{r}\;\mathrm{,} + +This definition allows us to solve for our characteric source terms resulting in: + +.. math:: + :label: source_term_1 + + \bar{Q}_{r, i, g} = Q_{i,g} + \left[\mathbf{u}_{r,\mathrm{c}} \cdot \boldsymbol{\vec{Q}}_{i,g}\right], + +.. math:: + :label: source_term_2 + + \hat{Q}_{r, i, g} = \left[\boldsymbol{\Omega} \cdot \boldsymbol{\vec{Q}}_{i,g}\right]\;\mathrm{.} + +The next step is to solve for the LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}`. +A relationship between the LS source vector and the source moments, :math:`\boldsymbol{\vec{q}}_{i,g}` +can be derived, `4 `_, `5 `_: + +.. math:: + :label: m_equation + + \boldsymbol{\vec{q}}_{i,g} = \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{,} + +The LS source vector can be solved for by the inversion of the M matrix, a geometrical quantity specific to the particular +source region REF, if the source moments can be solved for. Fortunately, the source moments are also defined by the definiton +of the source: + +.. math:: + :label: source_moments + + q_{v, i, g}= \frac{\chi_{i,g}}{k_{eff}} \sum_{g^{\prime}=1}^{G} \bar{\nu} + \Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G} + \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z) + +where we have introduced the scalar flux moments :math:`\hat{\phi}`. +Finally, the scalar flux moments can be solved for by taking the integral definition, resulting in: + +.. math:: + :label: scalar_moments + + \hat{\phi}_{v,i,g}^{simulation} = \frac{\sum\limits_{r=1}^{N_i} + \ell_{r} \left[\Omega_{v} \hat{\psi}_{r,i,g} + u_{r,v,0} \bar{\psi}_{r,i,g}\right]} + {\Sigma_{t,i,g} \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B}} + \quad \forall v \in(x, y, z), + + +where the average angular flux is given by Equation :eq:`average_psi_final`, +and the angular flux spatial moments :math:`\hat{\psi}_{r,i,g}` by: + +.. math:: + :label: angular_moments + + \hat{\psi}_{r, i, g} = \frac{\ell_{r}\psi^{in}_{r,g}}{2} + + \left(\frac{\bar{Q}_{r,i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) + \frac{G_{1}\left(\tau_{i,g}\right)}{\Sigma_{\mathrm{t}, i, g}} + \frac{\ell_{r}\hat{Q}_{r,i,g}} + {2\left(\Sigma_{\mathrm{t}, i, g}\right)^{2}}G_{2}\left(\tau_{i,g}\right)\;\mathrm{,} + + +The new exponentials introduced, again for simplicity, are simply: + + +.. math:: + :label: G1 + + G_{1}(\tau) = 1+\frac{\tau}{2}-\left(1+\frac{1}{\tau}\right) F_{1}(\tau), + +.. math:: + :label: G2 + + G_{2}(\tau) = \frac{2}{3} \tau-\left(1+\frac{2}{\tau}\right) G_{1}(\tau) + + + + ------------ Fixed Source ------------ @@ -832,6 +962,8 @@ in random ray particle transport are: .. _Tramm-2018: https://dspace.mit.edu/handle/1721.1/119038 .. _Tramm-2020: https://doi.org/10.1051/EPJCONF/202124703021 .. _Cosgrove-2023: https://doi.org/10.1080/00295639.2023.2270618 +.. _Ferrer-2016: https://doi.org/10.13182/NSE15-6 +.. _Gunow-2018: https://dspace.mit.edu/handle/1721.1/119030 .. only:: html @@ -840,3 +972,5 @@ in random ray particle transport are: .. [Askew-1972] Askew, “A Characteristics Formulation of the Neutron Transport Equation in Complicated Geometries.” Technical Report AAEW-M 1108, UK Atomic Energy Establishment (1972). + + From 9eb39065d5435cf39dd06ea535a1cae84ed9675c Mon Sep 17 00:00:00 2001 From: RufusN Date: Wed, 26 Jun 2024 00:30:51 +0100 Subject: [PATCH 08/61] updates to method, edits to bias section and start of usersguide LS section --- docs/source/methods/random_ray.rst | 43 +++++++++++++-------------- docs/source/usersguide/random_ray.rst | 8 +++++ 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index 8b769d44fa0..b4d979eb08c 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -755,10 +755,10 @@ to OpenMC, but for now this restriction needs to be respected. .. _usersguide_fixed_source_methods: --------------------------- -Random Ray Linear Sources --------------------------- -Instead of making the flat source approximation, that was used in the previous section, a Linear Source (LS) approximation can be used. Different LS approximations +--------------- +Linear Sources +--------------- +Instead of making a flat source approximation, as in the previous section, a Linear Source (LS) approximation can be used. Different LS approximations have been developed, the OpenMC implementation follows the scheme described by `Ferrer `_. The LS source along a characterstic is given by: .. math:: @@ -766,8 +766,8 @@ have been developed, the OpenMC implementation follows the scheme described by ` Q_{r,i,g}(s) = \bar{Q}_{r,i,g} + \hat{Q}_{r,i,g}(s-\ell_{r}/2), -where the source, :math:`Q_{i,g,r}(s)`, varies linearly along the track and :math:`\bar{Q}_{i,g,r}` and :math:`\hat{Q}_{i,g,r}` are track specific source terms we will define shortly. -Integrating the source, following :eq:`moc_final`, leads to +where the source, :math:`Q_{i,g,r}(s)`, varies linearly along the track and :math:`\bar{Q}_{i,g,r}` and :math:`\hat{Q}_{i,g,r}` are track specific source terms to define shortly. +Integrating the source, as done in Equation :eq:`moc_final`, leads to .. math:: :label: lsr_attenuation @@ -775,7 +775,7 @@ Integrating the source, following :eq:`moc_final`, leads to \psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{i, g, r}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) F_{1}\left(\tau_{i,g}\right)+\frac{\hat{Q}_{i, g, r}^{g}}{2\left(\Sigma_{\mathrm{t}, i,g}\right)^{2}} F_{2}\left(\tau_{i,g}\right), -where for simplicity we have introduced :math:`\tau_{i,g}` and the expoential terms :math:`F1` and :math:`F2`, given by: +where for simplicity the term :math:`\tau_{i,g}` and the expoentials :math:`F1` and :math:`F2` are introduced, given by: .. math:: :label: tau @@ -795,15 +795,15 @@ and F_{2}\left(\tau\right) = 2\left[\tau-F_{1}\left(\tau\right)\right]-\tau F_{1}\left(\tau\right). -To solve for the track specific terms we start by defining a local reference frame. If we now refer to :math:`\mathbf{r}` -as our global coordinate and introduce the source region specific coordinate :math:`\mathbf{u}` such that, +To solve for the track specific source terms in Equation :eq:`linear_source` we first define a local reference frame. If we now refer to :math:`\mathbf{r}` +as the global coordinate and introduce the source region specific coordinate :math:`\mathbf{u}` such that, .. math:: :label: local_coord \mathbf{u}_{r} = \mathbf{r}-\mathbf{r}_{\mathrm{c}}, -where :math:`\mathbf{r}_{\mathrm{c}}` is the centroid of the source region of interest and in turn +where :math:`\mathbf{r}_{\mathrm{c}}` is the centroid of the source region of interest. In turn :math:`\mathbf{u}_{r,\mathrm{c}}` and :math:`\mathbf{u}_{r,0}` are the local centroid and entry positions of a ray. The computation of the local and global centroids are described further by `Gunow `_. @@ -833,7 +833,7 @@ can be derived, `4 `_, `5 `_: .. math:: :label: m_equation - \boldsymbol{\vec{q}}_{i,g} = \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{,} + \boldsymbol{\vec{q}}_{i,g} = \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} The LS source vector can be solved for by the inversion of the M matrix, a geometrical quantity specific to the particular source region REF, if the source moments can be solved for. Fortunately, the source moments are also defined by the definiton @@ -842,20 +842,21 @@ of the source: .. math:: :label: source_moments - q_{v, i, g}= \frac{\chi_{i,g}}{k_{eff}} \sum_{g^{\prime}=1}^{G} \bar{\nu} + q_{v, i, g}= \frac{\chi_{i,g}}{k_{eff}} \sum_{g^{\prime}=1}^{G} \nu \Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G} - \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z) + \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z)\;\mathrm{,} where we have introduced the scalar flux moments :math:`\hat{\phi}`. -Finally, the scalar flux moments can be solved for by taking the integral definition, resulting in: +The scalar flux moments can be solved for by taking the `integral definition `_ of a spatial moment, allowing us +to derive a "simulation averaged" estimator for the scalar moment, as in Equation :eq:`phi_sim`, .. math:: - :label: scalar_moments + :label: scalar_moments_sim \hat{\phi}_{v,i,g}^{simulation} = \frac{\sum\limits_{r=1}^{N_i} \ell_{r} \left[\Omega_{v} \hat{\psi}_{r,i,g} + u_{r,v,0} \bar{\psi}_{r,i,g}\right]} {\Sigma_{t,i,g} \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B}} - \quad \forall v \in(x, y, z), + \quad \forall v \in(x, y, z)\;\mathrm{,} where the average angular flux is given by Equation :eq:`average_psi_final`, @@ -884,8 +885,6 @@ The new exponentials introduced, again for simplicity, are simply: G_{2}(\tau) = \frac{2}{3} \tau-\left(1+\frac{2}{\tau}\right) G_{1}(\tau) - - ------------ Fixed Source ------------ @@ -932,13 +931,13 @@ in random ray particle transport are: areas typically have solutions that are highly effective at mitigating bias, error stemming from multigroup energy discretization is much harder to remedy. - - **Flat Source Approximation:**. In OpenMC, a "flat" (0th order) source - approximation is made, wherein the scattering and fission sources within a + - **Source Approximation:**. In OpenMC, a "flat" (0th order) source + approximation is often made, wherein the scattering and fission sources within a cell are assumed to be spatially uniform. As the source in reality is a continuous function, this leads to bias, although the bias can be reduced to acceptable levels if the flat source regions are sufficiently small. - The bias can also be mitigated by assuming a higher-order source (e.g., - linear or quadratic), although OpenMC does not yet have this capability. + The bias can also be mitigated by assuming a higher-order source such as the + linear source approximation currently implemented into OpenMC. In practical terms, this source of bias can become very large if cells are large (with dimensions beyond that of a typical particle mean free path), but the subdivision of cells can often reduce this bias to trivial levels. diff --git a/docs/source/usersguide/random_ray.rst b/docs/source/usersguide/random_ray.rst index 61f0746500c..270e33c0b50 100644 --- a/docs/source/usersguide/random_ray.rst +++ b/docs/source/usersguide/random_ray.rst @@ -415,6 +415,14 @@ in the `OpenMC Jupyter notebook collection separate materials can be defined each with a separate multigroup dataset corresponding to a given temperature. +--------------- +Linear Sources +--------------- +Linear Sources (LS), are supported with the eigenvalue and fixed source random ray solvers. +LS can be toggled on with:: + + settings.random_ray['source_shape'] = 'linear' + --------------------------------- Fixed Source and Eigenvalue Modes --------------------------------- From ead9a4adf3e59211ff4dcecee43f25a74d409392 Mon Sep 17 00:00:00 2001 From: RufusN Date: Wed, 26 Jun 2024 00:39:49 +0100 Subject: [PATCH 09/61] added to usersguide --- docs/source/usersguide/random_ray.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/usersguide/random_ray.rst b/docs/source/usersguide/random_ray.rst index 270e33c0b50..de55a1d89ba 100644 --- a/docs/source/usersguide/random_ray.rst +++ b/docs/source/usersguide/random_ray.rst @@ -423,6 +423,9 @@ LS can be toggled on with:: settings.random_ray['source_shape'] = 'linear' +LS enables the use of coarser discretisations and lower ray populations, offsetting +the increased computation. + --------------------------------- Fixed Source and Eigenvalue Modes --------------------------------- From ab0e899218d8c7d2ff29f8000ef51a7fa523488f Mon Sep 17 00:00:00 2001 From: RufusN Date: Wed, 26 Jun 2024 12:51:06 +0100 Subject: [PATCH 10/61] further edits --- docs/source/methods/random_ray.rst | 34 +++++++++++++++++---------- docs/source/usersguide/random_ray.rst | 2 +- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index b4d979eb08c..a3b15aa7c3d 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -753,27 +753,25 @@ behavior if a single simulation cell is able to score to multiple filter mesh cells. In the future, the capability to fully support mesh tallies may be added to OpenMC, but for now this restriction needs to be respected. -.. _usersguide_fixed_source_methods: - --------------- Linear Sources --------------- Instead of making a flat source approximation, as in the previous section, a Linear Source (LS) approximation can be used. Different LS approximations -have been developed, the OpenMC implementation follows the scheme described by `Ferrer `_. The LS source along a characterstic is given by: +have been developed, the OpenMC implementation follows the MOC LS scheme described by `Ferrer `_. The LS source along a characterstic is given by: .. math:: :label: linear_source - Q_{r,i,g}(s) = \bar{Q}_{r,i,g} + \hat{Q}_{r,i,g}(s-\ell_{r}/2), + Q_{i,g}(s) = \bar{Q}_{r,i,g} + \hat{Q}_{r,i,g}(s-\ell_{r}/2), -where the source, :math:`Q_{i,g,r}(s)`, varies linearly along the track and :math:`\bar{Q}_{i,g,r}` and :math:`\hat{Q}_{i,g,r}` are track specific source terms to define shortly. +where the source, :math:`Q_{i,g}(s)`, varies linearly along the track and :math:`\bar{Q}_{r,i,g}` and :math:`\hat{Q}_{r,i,g}` are track specific source terms to define shortly. Integrating the source, as done in Equation :eq:`moc_final`, leads to .. math:: :label: lsr_attenuation - \psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{i, g, r}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) - F_{1}\left(\tau_{i,g}\right)+\frac{\hat{Q}_{i, g, r}^{g}}{2\left(\Sigma_{\mathrm{t}, i,g}\right)^{2}} F_{2}\left(\tau_{i,g}\right), + \psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{r, i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) + F_{1}\left(\tau_{i,g}\right)+\frac{\hat{Q}_{r, i, g}^{g}}{2\left(\Sigma_{\mathrm{t}, i,g}\right)^{2}} F_{2}\left(\tau_{i,g}\right), where for simplicity the term :math:`\tau_{i,g}` and the expoentials :math:`F1` and :math:`F2` are introduced, given by: @@ -807,7 +805,7 @@ where :math:`\mathbf{r}_{\mathrm{c}}` is the centroid of the source region of in :math:`\mathbf{u}_{r,\mathrm{c}}` and :math:`\mathbf{u}_{r,0}` are the local centroid and entry positions of a ray. The computation of the local and global centroids are described further by `Gunow `_. -Using the local position the source in a source region is given by: +Using the local position, the source in a source region is given by: .. math:: :label: region_source @@ -824,8 +822,9 @@ This definition allows us to solve for our characteric source terms resulting in .. math:: :label: source_term_2 - \hat{Q}_{r, i, g} = \left[\boldsymbol{\Omega} \cdot \boldsymbol{\vec{Q}}_{i,g}\right]\;\mathrm{.} - + \hat{Q}_{r, i, g} = \left[\boldsymbol{\Omega} \cdot \boldsymbol{\vec{Q}}_{i,g}\right]\;\mathrm{,} + +:math:`\boldsymbol{\Omega}` being the direction vector of the ray. The next step is to solve for the LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}`. A relationship between the LS source vector and the source moments, :math:`\boldsymbol{\vec{q}}_{i,g}` can be derived, `4 `_, `5 `_: @@ -836,7 +835,7 @@ can be derived, `4 `_, `5 `_: \boldsymbol{\vec{q}}_{i,g} = \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} The LS source vector can be solved for by the inversion of the M matrix, a geometrical quantity specific to the particular -source region REF, if the source moments can be solved for. Fortunately, the source moments are also defined by the definiton +`source region `_, provided that the source moments can be calculated. Fortunately, the source moments are also defined by the definiton of the source: .. math:: @@ -846,6 +845,13 @@ of the source: \Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G} \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z)\;\mathrm{,} +(John:Alternatively the below can be used with some edits---- ) + +.. math:: + :label: source_moments_update + + q^{n}(v,i) = \frac{\chi}{k^{n-1}_{eff}} \nu \Sigma_f(i, g) \hat{\phi}^{n-1}_{v, i}(g) + \sum\limits^{G}_{g\prime} \Sigma_{s}({i,g,g^{\prime}}) \hat{\phi}^{n-1}_{v, i}({g^{\prime}}) + where we have introduced the scalar flux moments :math:`\hat{\phi}`. The scalar flux moments can be solved for by taking the `integral definition `_ of a spatial moment, allowing us to derive a "simulation averaged" estimator for the scalar moment, as in Equation :eq:`phi_sim`, @@ -868,7 +874,7 @@ and the angular flux spatial moments :math:`\hat{\psi}_{r,i,g}` by: \hat{\psi}_{r, i, g} = \frac{\ell_{r}\psi^{in}_{r,g}}{2} + \left(\frac{\bar{Q}_{r,i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) \frac{G_{1}\left(\tau_{i,g}\right)}{\Sigma_{\mathrm{t}, i, g}} + \frac{\ell_{r}\hat{Q}_{r,i,g}} - {2\left(\Sigma_{\mathrm{t}, i, g}\right)^{2}}G_{2}\left(\tau_{i,g}\right)\;\mathrm{,} + {2\left(\Sigma_{\mathrm{t}, i, g}\right)^{2}}G_{2}\left(\tau_{i,g}\right)\;\mathrm{.} The new exponentials introduced, again for simplicity, are simply: @@ -884,6 +890,10 @@ The new exponentials introduced, again for simplicity, are simply: G_{2}(\tau) = \frac{2}{3} \tau-\left(1+\frac{2}{\tau}\right) G_{1}(\tau) +The contents of this section, alongside the equations for the flat source and scalar flux, Equations :eq:`source_update` and :eq:`phi_sim` respectively, +completes the set of equations for LS. + +.. _usersguide_fixed_source_methods: ------------ Fixed Source diff --git a/docs/source/usersguide/random_ray.rst b/docs/source/usersguide/random_ray.rst index de55a1d89ba..68d730450dd 100644 --- a/docs/source/usersguide/random_ray.rst +++ b/docs/source/usersguide/random_ray.rst @@ -424,7 +424,7 @@ LS can be toggled on with:: settings.random_ray['source_shape'] = 'linear' LS enables the use of coarser discretisations and lower ray populations, offsetting -the increased computation. +the increased computation per ray. --------------------------------- Fixed Source and Eigenvalue Modes From 82cc0a77fc0b03458d1693111eb4ddfa6475eb2f Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 11:07:15 -0500 Subject: [PATCH 11/61] moved 2x2 lattice to examples. --- openmc/examples.py | 233 ++++++++++++++++++ .../regression_tests/random_ray_basic/test.py | 223 +---------------- 2 files changed, 239 insertions(+), 217 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index fc94b8b528e..0a96ee89581 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -644,3 +644,236 @@ def slab_mg(num_regions=1, mat_names=None, mgxslib_name='2g.h5'): model.xs_data = macros return model + +def random_ray_lattice_mgxs(): + """Creates a seven group cross section data library + + Returns + ------- + mgxs : openmc.MGXSLibrary + A seven group cross section data library + + """ + # Instantiate the energy group data + group_edges = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] + groups = openmc.mgxs.EnergyGroups(group_edges) + + # Instantiate the 7-group (C5G7) cross section data + uo2_xsdata = openmc.XSdata('UO2', groups) + uo2_xsdata.order = 0 + uo2_xsdata.set_total( + [0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, + 0.5644058]) + uo2_xsdata.set_absorption([8.0248e-03, 3.7174e-03, 2.6769e-02, 9.6236e-02, + 3.0020e-02, 1.1126e-01, 2.8278e-01]) + scatter_matrix = np.array( + [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) + scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) + uo2_xsdata.set_scatter_matrix(scatter_matrix) + uo2_xsdata.set_fission([7.21206e-03, 8.19301e-04, 6.45320e-03, + 1.85648e-02, 1.78084e-02, 8.30348e-02, + 2.16004e-01]) + uo2_xsdata.set_nu_fission([2.005998e-02, 2.027303e-03, 1.570599e-02, + 4.518301e-02, 4.334208e-02, 2.020901e-01, + 5.257105e-01]) + uo2_xsdata.set_chi([5.8791e-01, 4.1176e-01, 3.3906e-04, 1.1761e-07, 0.0000e+00, + 0.0000e+00, 0.0000e+00]) + + h2o_xsdata = openmc.XSdata('LWTR', groups) + h2o_xsdata.order = 0 + h2o_xsdata.set_total([0.15920605, 0.412969593, 0.59030986, 0.58435, + 0.718, 1.2544497, 2.650379]) + h2o_xsdata.set_absorption([6.0105e-04, 1.5793e-05, 3.3716e-04, + 1.9406e-03, 5.7416e-03, 1.5001e-02, + 3.7239e-02]) + scatter_matrix = np.array( + [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], + [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], + [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], + [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], + [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) + scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) + h2o_xsdata.set_scatter_matrix(scatter_matrix) + + mg_cross_sections = openmc.MGXSLibrary(groups) + mg_cross_sections.add_xsdatas([uo2_xsdata, h2o_xsdata]) + + return mg_cross_sections + +def random_ray_lattice(): + """Create a 2x2 PWR pincell asymmetrical lattic eexample. + + This model is a 2x2 reflective lattice of fuel pins with one of the lattice + locations have just moderator instead of a fuel pin. It uses 7 group + cross section data + + Returns + ------- + model : openmc.model.Model + A PWR pin-cell model + + """ + model = openmc.model.Model() + + ############################################################################### + # Create materials for the problem + + # Instantiate some Materials and register the appropriate macroscopic data + uo2 = openmc.Material(name='UO2 fuel') + uo2.set_density('macro', 1.0) + uo2.add_macroscopic('UO2') + + water = openmc.Material(name='Water') + water.set_density('macro', 1.0) + water.add_macroscopic('LWTR') + + # Instantiate a Materials collection and export to XML + materials = openmc.Materials([uo2, water]) + materials.cross_sections = "mgxs.h5" + + ############################################################################### + # Define problem geometry + + ######################################## + # Define an unbounded pincell universe + + pitch = 1.26 + + # Create a surface for the fuel outer radius + fuel_or = openmc.ZCylinder(r=0.54, name='Fuel OR') + inner_ring_a = openmc.ZCylinder(r=0.33, name='inner ring a') + inner_ring_b = openmc.ZCylinder(r=0.45, name='inner ring b') + outer_ring_a = openmc.ZCylinder(r=0.60, name='outer ring a') + outer_ring_b = openmc.ZCylinder(r=0.69, name='outer ring b') + + # Instantiate Cells + fuel_a = openmc.Cell(fill=uo2, region=-inner_ring_a, name='fuel inner a') + fuel_b = openmc.Cell(fill=uo2, region=+inner_ring_a & -inner_ring_b, name='fuel inner b') + fuel_c = openmc.Cell(fill=uo2, region=+inner_ring_b & -fuel_or, name='fuel inner c') + moderator_a = openmc.Cell(fill=water, region=+fuel_or & -outer_ring_a, name='moderator inner a') + moderator_b = openmc.Cell(fill=water, region=+outer_ring_a & -outer_ring_b, name='moderator outer b') + moderator_c = openmc.Cell(fill=water, region=+outer_ring_b, name='moderator outer c') + + # Create pincell universe + pincell_base = openmc.Universe() + + # Register Cells with Universe + pincell_base.add_cells([fuel_a, fuel_b, fuel_c, moderator_a, moderator_b, moderator_c]) + + # Create planes for azimuthal sectors + azimuthal_planes = [] + for i in range(8): + angle = 2 * i * openmc.pi / 8 + normal_vector = (-openmc.sin(angle), openmc.cos(angle), 0) + azimuthal_planes.append(openmc.Plane(a=normal_vector[0], b=normal_vector[1], c=normal_vector[2], d=0)) + + # Create a cell for each azimuthal sector + azimuthal_cells = [] + for i in range(8): + azimuthal_cell = openmc.Cell(name=f'azimuthal_cell_{i}') + azimuthal_cell.fill = pincell_base + azimuthal_cell.region = +azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] + azimuthal_cells.append(azimuthal_cell) + + # Create a geometry with the azimuthal universes + pincell = openmc.Universe(cells=azimuthal_cells) + + ######################################## + # Define a moderator lattice universe + + moderator_infinite = openmc.Cell(fill=water, name='moderator infinite') + mu = openmc.Universe() + mu.add_cells([moderator_infinite]) + + lattice = openmc.RectLattice() + lattice.lower_left = [-pitch/2.0, -pitch/2.0] + lattice.pitch = [pitch/10.0, pitch/10.0] + lattice.universes = np.full((10, 10), mu) + + mod_lattice_cell = openmc.Cell(fill=lattice) + + mod_lattice_uni = openmc.Universe() + + mod_lattice_uni.add_cells([mod_lattice_cell]) + + ######################################## + # Define 2x2 outer lattice + lattice2x2 = openmc.RectLattice() + lattice2x2.lower_left = (-pitch, -pitch) + lattice2x2.pitch = (pitch, pitch) + lattice2x2.universes = [ + [pincell, pincell], + [pincell, mod_lattice_uni] + ] + + ######################################## + # Define cell containing lattice and other stuff + box = openmc.model.RectangularPrism(pitch*2, pitch*2, boundary_type='reflective') + + assembly = openmc.Cell(fill=lattice2x2, region=-box, name='assembly') + + # Create a geometry with the top-level cell + geometry = openmc.Geometry([assembly]) + + ############################################################################### + # Define problem settings + + # Instantiate a Settings object, set all runtime parameters, and export to XML + settings = openmc.Settings() + settings.energy_mode = "multi-group" + settings.batches = 10 + settings.inactive = 5 + settings.particles = 100 + + # Create an initial uniform spatial source distribution over fissionable zones + lower_left = (-pitch, -pitch, -1) + upper_right = (pitch, pitch, 1) + uniform_dist = openmc.stats.Box(lower_left, upper_right) + rr_source = openmc.IndependentSource(space=uniform_dist) + + settings.random_ray['distance_active'] = 100.0 + settings.random_ray['distance_inactive'] = 20.0 + settings.random_ray['ray_source'] = rr_source + + ############################################################################### + # Define tallies + + # Create a mesh that will be used for tallying + mesh = openmc.RegularMesh() + mesh.dimension = (2, 2) + mesh.lower_left = (-pitch, -pitch) + mesh.upper_right = (pitch, pitch) + + # Create a mesh filter that can be used in a tally + mesh_filter = openmc.MeshFilter(mesh) + + # Create an energy group filter as well + group_edges = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] + energy_filter = openmc.EnergyFilter(group_edges) + + # Now use the mesh filter in a tally and indicate what scores are desired + tally = openmc.Tally(name="Mesh tally") + tally.filters = [mesh_filter, energy_filter] + tally.scores = ['flux', 'fission', 'nu-fission'] + tally.estimator = 'analog' + + # Instantiate a Tallies collection and export to XML + tallies = openmc.Tallies([tally]) + + ############################################################################### + # Exporting to OpenMC model + ############################################################################### + + model.geometry = geometry + model.materials = materials + model.settings = settings + model.tallies = tallies + return model \ No newline at end of file diff --git a/tests/regression_tests/random_ray_basic/test.py b/tests/regression_tests/random_ray_basic/test.py index 1727a63716c..5c14e99fcd2 100644 --- a/tests/regression_tests/random_ray_basic/test.py +++ b/tests/regression_tests/random_ray_basic/test.py @@ -2,10 +2,10 @@ import numpy as np import openmc +from openmc.examples import random_ray_lattice_mgxs, random_ray_lattice from tests.testing_harness import TolerantPyAPITestHarness - class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() @@ -13,220 +13,9 @@ def _cleanup(self): if os.path.exists(f): os.remove(f) - -def random_ray_model() -> openmc.Model: - ############################################################################### - # Create multigroup data - - # Instantiate the energy group data - group_edges = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] - groups = openmc.mgxs.EnergyGroups(group_edges) - - # Instantiate the 7-group (C5G7) cross section data - uo2_xsdata = openmc.XSdata('UO2', groups) - uo2_xsdata.order = 0 - uo2_xsdata.set_total( - [0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, - 0.5644058]) - uo2_xsdata.set_absorption([8.0248e-03, 3.7174e-03, 2.6769e-02, 9.6236e-02, - 3.0020e-02, 1.1126e-01, 2.8278e-01]) - scatter_matrix = np.array( - [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) - scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) - uo2_xsdata.set_scatter_matrix(scatter_matrix) - uo2_xsdata.set_fission([7.21206e-03, 8.19301e-04, 6.45320e-03, - 1.85648e-02, 1.78084e-02, 8.30348e-02, - 2.16004e-01]) - uo2_xsdata.set_nu_fission([2.005998e-02, 2.027303e-03, 1.570599e-02, - 4.518301e-02, 4.334208e-02, 2.020901e-01, - 5.257105e-01]) - uo2_xsdata.set_chi([5.8791e-01, 4.1176e-01, 3.3906e-04, 1.1761e-07, 0.0000e+00, - 0.0000e+00, 0.0000e+00]) - - h2o_xsdata = openmc.XSdata('LWTR', groups) - h2o_xsdata.order = 0 - h2o_xsdata.set_total([0.15920605, 0.412969593, 0.59030986, 0.58435, - 0.718, 1.2544497, 2.650379]) - h2o_xsdata.set_absorption([6.0105e-04, 1.5793e-05, 3.3716e-04, - 1.9406e-03, 5.7416e-03, 1.5001e-02, - 3.7239e-02]) - scatter_matrix = np.array( - [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], - [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], - [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], - [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], - [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) - scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) - h2o_xsdata.set_scatter_matrix(scatter_matrix) - - mg_cross_sections = openmc.MGXSLibrary(groups) - mg_cross_sections.add_xsdatas([uo2_xsdata, h2o_xsdata]) - mg_cross_sections.export_to_hdf5() - - ############################################################################### - # Create materials for the problem - - # Instantiate some Materials and register the appropriate macroscopic data - uo2 = openmc.Material(name='UO2 fuel') - uo2.set_density('macro', 1.0) - uo2.add_macroscopic('UO2') - - water = openmc.Material(name='Water') - water.set_density('macro', 1.0) - water.add_macroscopic('LWTR') - - # Instantiate a Materials collection and export to XML - materials = openmc.Materials([uo2, water]) - materials.cross_sections = "mgxs.h5" - - ############################################################################### - # Define problem geometry - - ######################################## - # Define an unbounded pincell universe - - pitch = 1.26 - - # Create a surface for the fuel outer radius - fuel_or = openmc.ZCylinder(r=0.54, name='Fuel OR') - inner_ring_a = openmc.ZCylinder(r=0.33, name='inner ring a') - inner_ring_b = openmc.ZCylinder(r=0.45, name='inner ring b') - outer_ring_a = openmc.ZCylinder(r=0.60, name='outer ring a') - outer_ring_b = openmc.ZCylinder(r=0.69, name='outer ring b') - - # Instantiate Cells - fuel_a = openmc.Cell(fill=uo2, region=-inner_ring_a, name='fuel inner a') - fuel_b = openmc.Cell(fill=uo2, region=+inner_ring_a & -inner_ring_b, name='fuel inner b') - fuel_c = openmc.Cell(fill=uo2, region=+inner_ring_b & -fuel_or, name='fuel inner c') - moderator_a = openmc.Cell(fill=water, region=+fuel_or & -outer_ring_a, name='moderator inner a') - moderator_b = openmc.Cell(fill=water, region=+outer_ring_a & -outer_ring_b, name='moderator outer b') - moderator_c = openmc.Cell(fill=water, region=+outer_ring_b, name='moderator outer c') - - # Create pincell universe - pincell_base = openmc.Universe() - - # Register Cells with Universe - pincell_base.add_cells([fuel_a, fuel_b, fuel_c, moderator_a, moderator_b, moderator_c]) - - # Create planes for azimuthal sectors - azimuthal_planes = [] - for i in range(8): - angle = 2 * i * openmc.pi / 8 - normal_vector = (-openmc.sin(angle), openmc.cos(angle), 0) - azimuthal_planes.append(openmc.Plane(a=normal_vector[0], b=normal_vector[1], c=normal_vector[2], d=0)) - - # Create a cell for each azimuthal sector - azimuthal_cells = [] - for i in range(8): - azimuthal_cell = openmc.Cell(name=f'azimuthal_cell_{i}') - azimuthal_cell.fill = pincell_base - azimuthal_cell.region = +azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] - azimuthal_cells.append(azimuthal_cell) - - # Create a geometry with the azimuthal universes - pincell = openmc.Universe(cells=azimuthal_cells) - - ######################################## - # Define a moderator lattice universe - - moderator_infinite = openmc.Cell(fill=water, name='moderator infinite') - mu = openmc.Universe() - mu.add_cells([moderator_infinite]) - - lattice = openmc.RectLattice() - lattice.lower_left = [-pitch/2.0, -pitch/2.0] - lattice.pitch = [pitch/10.0, pitch/10.0] - lattice.universes = np.full((10, 10), mu) - - mod_lattice_cell = openmc.Cell(fill=lattice) - - mod_lattice_uni = openmc.Universe() - - mod_lattice_uni.add_cells([mod_lattice_cell]) - - ######################################## - # Define 2x2 outer lattice - lattice2x2 = openmc.RectLattice() - lattice2x2.lower_left = (-pitch, -pitch) - lattice2x2.pitch = (pitch, pitch) - lattice2x2.universes = [ - [pincell, pincell], - [pincell, mod_lattice_uni] - ] - - ######################################## - # Define cell containing lattice and other stuff - box = openmc.model.RectangularPrism(pitch*2, pitch*2, boundary_type='reflective') - - assembly = openmc.Cell(fill=lattice2x2, region=-box, name='assembly') - - # Create a geometry with the top-level cell - geometry = openmc.Geometry([assembly]) - - ############################################################################### - # Define problem settings - - # Instantiate a Settings object, set all runtime parameters, and export to XML - settings = openmc.Settings() - settings.energy_mode = "multi-group" - settings.batches = 10 - settings.inactive = 5 - settings.particles = 100 - - # Create an initial uniform spatial source distribution over fissionable zones - lower_left = (-pitch, -pitch, -1) - upper_right = (pitch, pitch, 1) - uniform_dist = openmc.stats.Box(lower_left, upper_right) - rr_source = openmc.IndependentSource(space=uniform_dist) - - settings.random_ray['distance_active'] = 100.0 - settings.random_ray['distance_inactive'] = 20.0 - settings.random_ray['ray_source'] = rr_source - - ############################################################################### - # Define tallies - - # Create a mesh that will be used for tallying - mesh = openmc.RegularMesh() - mesh.dimension = (2, 2) - mesh.lower_left = (-pitch, -pitch) - mesh.upper_right = (pitch, pitch) - - # Create a mesh filter that can be used in a tally - mesh_filter = openmc.MeshFilter(mesh) - - # Create an energy group filter as well - energy_filter = openmc.EnergyFilter(group_edges) - - # Now use the mesh filter in a tally and indicate what scores are desired - tally = openmc.Tally(name="Mesh tally") - tally.filters = [mesh_filter, energy_filter] - tally.scores = ['flux', 'fission', 'nu-fission'] - tally.estimator = 'analog' - - # Instantiate a Tallies collection and export to XML - tallies = openmc.Tallies([tally]) - - ############################################################################### - # Exporting to OpenMC model - ############################################################################### - - model = openmc.Model() - model.geometry = geometry - model.materials = materials - model.settings = settings - model.tallies = tallies - return model - - def test_random_ray_basic(): - harness = MGXSTestHarness('statepoint.10.h5', random_ray_model()) - harness.main() + mgxs = random_ray_lattice_mgxs() + mgxs.export_to_hdf5('mgxs.h5') + model = random_ray_lattice() + harness = MGXSTestHarness('statepoint.10.h5', model) + harness.main() \ No newline at end of file From 486031698d44db8c36c4ae01efe7ae2dd8f12f95 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 11:21:38 -0500 Subject: [PATCH 12/61] simplified vacuum test --- .../random_ray_vacuum/test.py | 230 +----------------- 1 file changed, 13 insertions(+), 217 deletions(-) diff --git a/tests/regression_tests/random_ray_vacuum/test.py b/tests/regression_tests/random_ray_vacuum/test.py index e9ca2252144..341c2005d49 100644 --- a/tests/regression_tests/random_ray_vacuum/test.py +++ b/tests/regression_tests/random_ray_vacuum/test.py @@ -2,10 +2,10 @@ import numpy as np import openmc +from openmc.examples import random_ray_lattice_mgxs, random_ray_lattice from tests.testing_harness import TolerantPyAPITestHarness - class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() @@ -13,223 +13,19 @@ def _cleanup(self): if os.path.exists(f): os.remove(f) - -def random_ray_model() -> openmc.Model: - ############################################################################### - # Create multigroup data - - # Instantiate the energy group data - group_edges = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] - groups = openmc.mgxs.EnergyGroups(group_edges) - - # Instantiate the 7-group (C5G7) cross section data - uo2_xsdata = openmc.XSdata('UO2', groups) - uo2_xsdata.order = 0 - uo2_xsdata.set_total( - [0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, - 0.5644058]) - uo2_xsdata.set_absorption([8.0248e-03, 3.7174e-03, 2.6769e-02, 9.6236e-02, - 3.0020e-02, 1.1126e-01, 2.8278e-01]) - scatter_matrix = np.array( - [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) - scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) - uo2_xsdata.set_scatter_matrix(scatter_matrix) - uo2_xsdata.set_fission([7.21206e-03, 8.19301e-04, 6.45320e-03, - 1.85648e-02, 1.78084e-02, 8.30348e-02, - 2.16004e-01]) - uo2_xsdata.set_nu_fission([2.005998e-02, 2.027303e-03, 1.570599e-02, - 4.518301e-02, 4.334208e-02, 2.020901e-01, - 5.257105e-01]) - uo2_xsdata.set_chi([5.8791e-01, 4.1176e-01, 3.3906e-04, 1.1761e-07, 0.0000e+00, - 0.0000e+00, 0.0000e+00]) - - h2o_xsdata = openmc.XSdata('LWTR', groups) - h2o_xsdata.order = 0 - h2o_xsdata.set_total([0.15920605, 0.412969593, 0.59030986, 0.58435, - 0.718, 1.2544497, 2.650379]) - h2o_xsdata.set_absorption([6.0105e-04, 1.5793e-05, 3.3716e-04, - 1.9406e-03, 5.7416e-03, 1.5001e-02, - 3.7239e-02]) - scatter_matrix = np.array( - [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], - [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], - [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], - [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], - [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) - scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) - h2o_xsdata.set_scatter_matrix(scatter_matrix) - - mg_cross_sections = openmc.MGXSLibrary(groups) - mg_cross_sections.add_xsdatas([uo2_xsdata, h2o_xsdata]) - mg_cross_sections.export_to_hdf5() - - ############################################################################### - # Create materials for the problem - - # Instantiate some Materials and register the appropriate Macroscopic objects - uo2 = openmc.Material(name='UO2 fuel') - uo2.set_density('macro', 1.0) - uo2.add_macroscopic('UO2') - - water = openmc.Material(name='Water') - water.set_density('macro', 1.0) - water.add_macroscopic('LWTR') - - # Instantiate a Materials collection and export to XML - materials = openmc.Materials([uo2, water]) - materials.cross_sections = "mgxs.h5" - - ############################################################################### - # Define problem geometry - - ######################################## - # Define an unbounded pincell universe - +def test_random_ray_vacuum(): + mgxs = random_ray_lattice_mgxs() + mgxs.export_to_hdf5('mgxs.h5') + model = random_ray_lattice() pitch = 1.26 + geometry = model.geometry - # Create a surface for the fuel outer radius - fuel_or = openmc.ZCylinder(r=0.54, name='Fuel OR') - inner_ring_a = openmc.ZCylinder(r=0.33, name='inner ring a') - inner_ring_b = openmc.ZCylinder(r=0.45, name='inner ring b') - outer_ring_a = openmc.ZCylinder(r=0.60, name='outer ring a') - outer_ring_b = openmc.ZCylinder(r=0.69, name='outer ring b') - - # Instantiate Cells - fuel_a = openmc.Cell(fill=uo2, region=-inner_ring_a, name='fuel inner a') - fuel_b = openmc.Cell(fill=uo2, region=+inner_ring_a & -inner_ring_b, name='fuel inner b') - fuel_c = openmc.Cell(fill=uo2, region=+inner_ring_b & -fuel_or, name='fuel inner c') - moderator_a = openmc.Cell(fill=water, region=+fuel_or & -outer_ring_a, name='moderator inner a') - moderator_b = openmc.Cell(fill=water, region=+outer_ring_a & -outer_ring_b, name='moderator outer b') - moderator_c = openmc.Cell(fill=water, region=+outer_ring_b, name='moderator outer c') - - # Create pincell universe - pincell_base = openmc.Universe() - - # Register Cells with Universe - pincell_base.add_cells([fuel_a, fuel_b, fuel_c, moderator_a, moderator_b, moderator_c]) - - # Create planes for azimuthal sectors - azimuthal_planes = [] - for i in range(8): - angle = 2 * i * openmc.pi / 8 - normal_vector = (-openmc.sin(angle), openmc.cos(angle), 0) - azimuthal_planes.append(openmc.Plane(a=normal_vector[0], b=normal_vector[1], c=normal_vector[2], d=0)) - - # Create a cell for each azimuthal sector - azimuthal_cells = [] - for i in range(8): - azimuthal_cell = openmc.Cell(name=f'azimuthal_cell_{i}') - azimuthal_cell.fill = pincell_base - azimuthal_cell.region = +azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] - azimuthal_cells.append(azimuthal_cell) - - # Create a geometry with the azimuthal universes - pincell = openmc.Universe(cells=azimuthal_cells) - - ######################################## - # Define a moderator lattice universe - - moderator_infinite = openmc.Cell(fill=water, name='moderator infinite') - mu = openmc.Universe() - mu.add_cells([moderator_infinite]) - - lattice = openmc.RectLattice() - lattice.lower_left = [-pitch/2.0, -pitch/2.0] - lattice.pitch = [pitch/10.0, pitch/10.0] - lattice.universes = np.full((10, 10), mu) - - mod_lattice_cell = openmc.Cell(fill=lattice) - - mod_lattice_uni = openmc.Universe() - - mod_lattice_uni.add_cells([mod_lattice_cell]) - - ######################################## - # Define 2x2 outer lattice - lattice2x2 = openmc.RectLattice() - lattice2x2.lower_left = [-pitch, -pitch] - lattice2x2.pitch = [pitch, pitch] - lattice2x2.universes = [ - [pincell, pincell], - [pincell, mod_lattice_uni] - ] - - ######################################## - # Define cell containing lattice and other stuff - box = openmc.model.RectangularPrism(pitch*2, pitch*2, boundary_type='vacuum') - - assembly = openmc.Cell(fill=lattice2x2, region=-box, name='assembly') - - root = openmc.Universe(name='root universe') - root.add_cell(assembly) + # Convert reflective surfaces to vacuum + surfaces = geometry.get_all_surfaces() + for key, surface in surfaces.items(): + if surface.boundary_type == 'reflective': + surface.boundary_type = 'vacuum' # Create a geometry with the two cells and export to XML - geometry = openmc.Geometry(root) - - ############################################################################### - # Define problem settings - - # Instantiate a Settings object, set all runtime parameters, and export to XML - settings = openmc.Settings() - settings.energy_mode = "multi-group" - settings.batches = 10 - settings.inactive = 5 - settings.particles = 100 - - # Create an initial uniform spatial source distribution over fissionable zones - lower_left = (-pitch, -pitch, -1) - upper_right = (pitch, pitch, 1) - uniform_dist = openmc.stats.Box(lower_left, upper_right) - rr_source = openmc.IndependentSource(space=uniform_dist) - - settings.random_ray['distance_active'] = 100.0 - settings.random_ray['distance_inactive'] = 20.0 - settings.random_ray['ray_source'] = rr_source - - ############################################################################### - # Define tallies - - # Create a mesh that will be used for tallying - mesh = openmc.RegularMesh() - mesh.dimension = (2, 2) - mesh.lower_left = (-pitch, -pitch) - mesh.upper_right = (pitch, pitch) - - # Create a mesh filter that can be used in a tally - mesh_filter = openmc.MeshFilter(mesh) - - # Create an energy group filter as well - energy_filter = openmc.EnergyFilter(group_edges) - - # Now use the mesh filter in a tally and indicate what scores are desired - tally = openmc.Tally(name="Mesh tally") - tally.filters = [mesh_filter, energy_filter] - tally.scores = ['flux', 'fission', 'nu-fission'] - tally.estimator = 'analog' - - # Instantiate a Tallies collection and export to XML - tallies = openmc.Tallies([tally]) - - ############################################################################### - # Exporting to OpenMC model - ############################################################################### - - model = openmc.Model() - model.geometry = geometry - model.materials = materials - model.settings = settings - model.tallies = tallies - return model - - -def test_random_ray_vacuum(): - harness = MGXSTestHarness('statepoint.10.h5', random_ray_model()) - harness.main() + harness = MGXSTestHarness('statepoint.10.h5', model) + harness.main() \ No newline at end of file From 904e42067985e03c4980d28260d7cfb0f2f6087c Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 13:08:59 -0500 Subject: [PATCH 13/61] changed fixed source test to cube, and added cube to examples --- openmc/examples.py | 249 +++++++++++-- .../regression_tests/random_ray_basic/test.py | 4 +- .../cell/inputs_true.dat | 309 +++++++++------- .../cell/results_true.dat | 50 +-- .../material/inputs_true.dat | 307 ++++++++------- .../material/results_true.dat | 50 +-- .../random_ray_fixed_source/test.py | 350 ++---------------- .../universe/inputs_true.dat | 307 ++++++++------- .../universe/results_true.dat | 50 +-- .../random_ray_vacuum/test.py | 8 +- 10 files changed, 801 insertions(+), 883 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index 0a96ee89581..cd2abc7f275 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -645,15 +645,24 @@ def slab_mg(num_regions=1, mat_names=None, mgxslib_name='2g.h5'): return model -def random_ray_lattice_mgxs(): - """Creates a seven group cross section data library +def random_ray_lattice(): + """Create a 2x2 PWR pincell asymmetrical lattic eexample. + + This model is a 2x2 reflective lattice of fuel pins with one of the lattice + locations have just moderator instead of a fuel pin. It uses 7 group + cross section data Returns ------- - mgxs : openmc.MGXSLibrary - A seven group cross section data library + model : openmc.model.Model + A PWR pin-cell model """ + model = openmc.model.Model() + + ############################################################################### + # Create MGXS data for the problem + # Instantiate the energy group data group_edges = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] groups = openmc.mgxs.EnergyGroups(group_edges) @@ -705,23 +714,7 @@ def random_ray_lattice_mgxs(): mg_cross_sections = openmc.MGXSLibrary(groups) mg_cross_sections.add_xsdatas([uo2_xsdata, h2o_xsdata]) - - return mg_cross_sections - -def random_ray_lattice(): - """Create a 2x2 PWR pincell asymmetrical lattic eexample. - - This model is a 2x2 reflective lattice of fuel pins with one of the lattice - locations have just moderator instead of a fuel pin. It uses 7 group - cross section data - - Returns - ------- - model : openmc.model.Model - A PWR pin-cell model - - """ - model = openmc.model.Model() + mg_cross_sections.export_to_hdf5('mgxs.h5') ############################################################################### # Create materials for the problem @@ -876,4 +869,218 @@ def random_ray_lattice(): model.materials = materials model.settings = settings model.tallies = tallies + return model + +def random_ray_three_region_cube(): + """Create a 2x2 PWR pincell asymmetrical lattic eexample. + + This model is a 2x2 reflective lattice of fuel pins with one of the lattice + locations have just moderator instead of a fuel pin. It uses 7 group + cross section data + + Returns + ------- + model : openmc.model.Model + A PWR pin-cell model + + """ + + model = openmc.model.Model() + + ############################################################################### + # Helper function creates a 3 region cube with different fills in each region + def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): + cube = [[[0 for _ in range(N)] for _ in range(N)] for _ in range(N)] + for i in range(N): + for j in range(N): + for k in range(N): + if i < n_1 and j >= (N-n_1) and k < n_1: + cube[i][j][k] = fill_1 + elif i < n_2 and j >= (N-n_2) and k < n_2: + cube[i][j][k] = fill_2 + else: + cube[i][j][k] = fill_3 + return cube + + ############################################################################### + # Create multigroup data + + # Instantiate the energy group data + ebins = [1e-5, 20.0e6] + groups = openmc.mgxs.EnergyGroups(group_edges=ebins) + + void_sigma_a = 4.0e-6 + void_sigma_s = 3.0e-4 + void_mat_data = openmc.XSdata('void', groups) + void_mat_data.order = 0 + void_mat_data.set_total([void_sigma_a + void_sigma_s]) + void_mat_data.set_absorption([void_sigma_a]) + void_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[void_sigma_s]]]),0,3)) + + absorber_sigma_a = 0.75 + absorber_sigma_s = 0.25 + absorber_mat_data = openmc.XSdata('absorber', groups) + absorber_mat_data.order = 0 + absorber_mat_data.set_total([absorber_sigma_a + absorber_sigma_s]) + absorber_mat_data.set_absorption([absorber_sigma_a]) + absorber_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[absorber_sigma_s]]]),0,3)) + + multiplier = 0.1 + source_sigma_a = void_sigma_a * multiplier + source_sigma_s = void_sigma_s * multiplier + source_mat_data = openmc.XSdata('source', groups) + source_mat_data.order = 0 + print(source_sigma_a + source_sigma_s) + source_mat_data.set_total([source_sigma_a + source_sigma_s]) + source_mat_data.set_absorption([source_sigma_a]) + source_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[source_sigma_s]]]),0,3)) + + mg_cross_sections_file = openmc.MGXSLibrary(groups) + mg_cross_sections_file.add_xsdatas([source_mat_data, void_mat_data, absorber_mat_data]) + mg_cross_sections_file.export_to_hdf5() + + ############################################################################### + # Create materials for the problem + + # Instantiate some Macroscopic Data + source_data = openmc.Macroscopic('source') + void_data = openmc.Macroscopic('void') + absorber_data = openmc.Macroscopic('absorber') + + # Instantiate some Materials and register the appropriate Macroscopic objects + source_mat = openmc.Material(name='source') + source_mat.set_density('macro', 1.0) + source_mat.add_macroscopic(source_data) + + void_mat = openmc.Material(name='void') + void_mat.set_density('macro', 1.0) + void_mat.add_macroscopic(void_data) + + absorber_mat = openmc.Material(name='absorber') + absorber_mat.set_density('macro', 1.0) + absorber_mat.add_macroscopic(absorber_data) + + # Instantiate a Materials collection and export to XML + materials_file = openmc.Materials([source_mat, void_mat, absorber_mat]) + materials_file.cross_sections = "mgxs.h5" + + ############################################################################### + # Define problem geometry + + source_cell = openmc.Cell(fill=source_mat, name='infinite source region') + void_cell = openmc.Cell(fill=void_mat, name='infinite void region') + absorber_cell = openmc.Cell(fill=absorber_mat, name='infinite absorber region') + + source_universe = openmc.Universe(name = 'source universe') + source_universe.add_cells([source_cell]) + + void_universe = openmc.Universe() + void_universe.add_cells([void_cell]) + + absorber_universe = openmc.Universe() + absorber_universe.add_cells([absorber_cell]) + + absorber_width = 30.0 + n_base = 6 + + # This variable can be increased above 1 to refine the FSR mesh resolution further + refinement_level = 2 + + n = n_base * refinement_level + pitch = absorber_width / n + + pattern = fill_cube(n, 1*refinement_level, 5*refinement_level, source_universe, void_universe, absorber_universe) + + lattice = openmc.RectLattice() + lattice.lower_left = [0.0, 0.0, 0.0] + lattice.pitch = [pitch, pitch, pitch] + lattice.universes = pattern + #print(lattice) + + lattice_cell = openmc.Cell(fill=lattice) + + lattice_uni = openmc.Universe() + lattice_uni.add_cells([lattice_cell]) + + x_low = openmc.XPlane(x0=0.0,boundary_type='reflective') + x_high = openmc.XPlane(x0=absorber_width,boundary_type='vacuum') + + y_low = openmc.YPlane(y0=0.0,boundary_type='reflective') + y_high = openmc.YPlane(y0=absorber_width,boundary_type='vacuum') + + z_low = openmc.ZPlane(z0=0.0,boundary_type='reflective') + z_high = openmc.ZPlane(z0=absorber_width,boundary_type='vacuum') + + full_domain = openmc.Cell(fill=lattice_uni, region=+x_low & -x_high & +y_low & -y_high & +z_low & -z_high, name='full domain') + + root = openmc.Universe(name='root universe') + root.add_cell(full_domain) + + # Create a geometry with the two cells and export to XML + geometry = openmc.Geometry(root) + + ############################################################################### + # Define problem settings + + # Instantiate a Settings object, set all runtime parameters, and export to XML + settings = openmc.Settings() + settings.energy_mode = "multi-group" + settings.inactive = 5 + settings.batches = 10 + settings.particles = 90 + settings.run_mode = 'fixed source' + + # Create an initial uniform spatial source for ray integration + lower_left_ray = [0.0, 0.0, 0.0] + upper_right_ray = [absorber_width, absorber_width, absorber_width] + uniform_dist_ray = openmc.stats.Box(lower_left_ray, upper_right_ray, only_fissionable=False) + rr_source = openmc.IndependentSource(space=uniform_dist_ray) + + settings.random_ray['distance_active'] = 500.0 + settings.random_ray['distance_inactive'] = 100.0 + settings.random_ray['ray_source'] = rr_source + + # Create the neutron source in the bottom right of the moderator + strengths = [1.0] # Good - fast group appears largest (besides most thermal) + midpoints = [100.0] + energy_distribution = openmc.stats.Discrete(x=midpoints,p=strengths) + + source = openmc.IndependentSource(energy=energy_distribution, constraints={'domains':[source_universe]}, strength=3.14) + + settings.source = [source] + + ############################################################################### + # Define tallies + + estimator = 'tracklength' + + absorber_filter = openmc.MaterialFilter(absorber_mat) + absorber_tally = openmc.Tally(name="Absorber Tally") + absorber_tally.filters = [absorber_filter] + absorber_tally.scores = ['flux'] + absorber_tally.estimator = estimator + + void_filter = openmc.MaterialFilter(void_mat) + void_tally = openmc.Tally(name="Void Tally") + void_tally.filters = [void_filter] + void_tally.scores = ['flux'] + void_tally.estimator = estimator + + source_filter = openmc.MaterialFilter(source_mat) + source_tally = openmc.Tally(name="Source Tally") + source_tally.filters = [source_filter] + source_tally.scores = ['flux'] + source_tally.estimator = estimator + + # Instantiate a Tallies collection and export to XML + tallies = openmc.Tallies([source_tally, void_tally, absorber_tally]) + + ############################################################################### + # Assmble Model + + model.geometry = geometry + model.materials = materials_file + model.settings = settings + model.tallies = tallies + return model \ No newline at end of file diff --git a/tests/regression_tests/random_ray_basic/test.py b/tests/regression_tests/random_ray_basic/test.py index 5c14e99fcd2..9b9b1a55a6a 100644 --- a/tests/regression_tests/random_ray_basic/test.py +++ b/tests/regression_tests/random_ray_basic/test.py @@ -2,7 +2,7 @@ import numpy as np import openmc -from openmc.examples import random_ray_lattice_mgxs, random_ray_lattice +from openmc.examples import random_ray_lattice from tests.testing_harness import TolerantPyAPITestHarness @@ -14,8 +14,6 @@ def _cleanup(self): os.remove(f) def test_random_ray_basic(): - mgxs = random_ray_lattice_mgxs() - mgxs.export_to_hdf5('mgxs.h5') model = random_ray_lattice() harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() \ No newline at end of file diff --git a/tests/regression_tests/random_ray_fixed_source/cell/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source/cell/inputs_true.dat index 99e67745a26..df2ac9537cc 100644 --- a/tests/regression_tests/random_ray_fixed_source/cell/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source/cell/inputs_true.dat @@ -10,195 +10,234 @@ - + - + - - - - - - + + + - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 -1 1 -1 1 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 -1 1 -1 1 - - - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 - -2 2 -2 2 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 -2 2 -2 2 - - - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 - -3 3 -3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -3 3 -3 3 - - - 10.0 10.0 10.0 - 6 10 6 - 0.0 0.0 0.0 - -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -8 8 8 8 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -7 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 - + - + - + fixed source - 1000 + 90 10 5 - + 100.0 1.0 cell - 4 + 1 multi-group - 400.0 + 500.0 100.0 - 0.0 0.0 0.0 60.0 100.0 60.0 + 0.0 0.0 0.0 30.0 30.0 30.0 - - 1 10 1 - 0.0 0.0 0.0 - 10.0 100.0 10.0 - - - 6 1 1 - 0.0 50.0 0.0 - 60.0 60.0 10.0 - - - 6 1 1 - 0.0 90.0 30.0 - 60.0 100.0 40.0 - - + 1 - + 2 - + 3 - - 1 + + 3 flux - analog + tracklength - + 2 flux - analog + tracklength - - 3 + + 1 flux - analog + tracklength diff --git a/tests/regression_tests/random_ray_fixed_source/cell/results_true.dat b/tests/regression_tests/random_ray_fixed_source/cell/results_true.dat index df923ab236a..714ad44a084 100644 --- a/tests/regression_tests/random_ray_fixed_source/cell/results_true.dat +++ b/tests/regression_tests/random_ray_fixed_source/cell/results_true.dat @@ -1,47 +1,9 @@ tally 1: -3.751048E+01 -2.841797E+02 -9.930788E+00 -1.988180E+01 -3.781121E+00 -3.005165E+00 -2.383139E+00 -1.232560E+00 -1.561884E+00 -6.440577E-01 -1.089787E+00 -3.724896E-01 -6.608456E-01 -1.285592E-01 -2.372611E-01 -1.601299E-02 -7.814803E-02 -1.765829E-03 -2.862108E-02 -2.460129E-04 +-6.614591E+04 +1.283943E+09 tally 2: -1.089787E+00 -3.724896E-01 -3.767926E-01 -3.724399E-02 -8.614121E-02 -1.526889E-03 -3.610725E-02 -2.629885E-04 -1.466261E-02 -4.536997E-05 -4.653106E-03 -4.381672E-06 +3.415331E+00 +2.396684E+00 tally 3: -1.617918E-03 -6.317049E-07 -1.161473E-03 -2.789553E-07 -1.198879E-03 -3.189531E-07 -1.031737E-03 -2.207381E-07 -5.466329E-04 -6.166808E-08 -2.146062E-04 -9.937520E-09 +2.277429E-01 +1.050297E-02 diff --git a/tests/regression_tests/random_ray_fixed_source/material/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source/material/inputs_true.dat index 7fde0c419b5..7ac54688e88 100644 --- a/tests/regression_tests/random_ray_fixed_source/material/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source/material/inputs_true.dat @@ -10,137 +10,191 @@ - + - + - - - - - - + + + - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 -1 1 -1 1 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 -1 1 -1 1 - - - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 - -2 2 -2 2 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 -2 2 -2 2 - - - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 - -3 3 -3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -3 3 -3 3 - - - 10.0 10.0 10.0 - 6 10 6 - 0.0 0.0 0.0 - -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -8 8 8 8 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -7 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 - + - + - + fixed source - 1000 + 90 10 5 - + 100.0 1.0 @@ -151,54 +205,39 @@ multi-group - 400.0 + 500.0 100.0 - 0.0 0.0 0.0 60.0 100.0 60.0 + 0.0 0.0 0.0 30.0 30.0 30.0 - - 1 10 1 - 0.0 0.0 0.0 - 10.0 100.0 10.0 - - - 6 1 1 - 0.0 50.0 0.0 - 60.0 60.0 10.0 - - - 6 1 1 - 0.0 90.0 30.0 - 60.0 100.0 40.0 - - + 1 - + 2 - + 3 - - 1 + + 3 flux - analog + tracklength - + 2 flux - analog + tracklength - - 3 + + 1 flux - analog + tracklength diff --git a/tests/regression_tests/random_ray_fixed_source/material/results_true.dat b/tests/regression_tests/random_ray_fixed_source/material/results_true.dat index e3d52890919..714ad44a084 100644 --- a/tests/regression_tests/random_ray_fixed_source/material/results_true.dat +++ b/tests/regression_tests/random_ray_fixed_source/material/results_true.dat @@ -1,47 +1,9 @@ tally 1: -3.751047E+01 -2.841797E+02 -9.930788E+00 -1.988181E+01 -3.781121E+00 -3.005165E+00 -2.383139E+00 -1.232560E+00 -1.561884E+00 -6.440577E-01 -1.089787E+00 -3.724896E-01 -6.608456E-01 -1.285592E-01 -2.372611E-01 -1.601299E-02 -7.814803E-02 -1.765829E-03 -2.862108E-02 -2.460129E-04 +-6.614591E+04 +1.283943E+09 tally 2: -1.089787E+00 -3.724896E-01 -3.767925E-01 -3.724398E-02 -8.614120E-02 -1.526889E-03 -3.610725E-02 -2.629885E-04 -1.466261E-02 -4.536997E-05 -4.653106E-03 -4.381672E-06 +3.415331E+00 +2.396684E+00 tally 3: -1.617918E-03 -6.317049E-07 -1.161473E-03 -2.789553E-07 -1.198879E-03 -3.189531E-07 -1.031737E-03 -2.207381E-07 -5.466329E-04 -6.166809E-08 -2.146062E-04 -9.937520E-09 +2.277429E-01 +1.050297E-02 diff --git a/tests/regression_tests/random_ray_fixed_source/test.py b/tests/regression_tests/random_ray_fixed_source/test.py index 41a6c35bb03..cc07a4e4092 100644 --- a/tests/regression_tests/random_ray_fixed_source/test.py +++ b/tests/regression_tests/random_ray_fixed_source/test.py @@ -3,24 +3,11 @@ import numpy as np import openmc from openmc.utility_funcs import change_directory +from openmc.examples import random_ray_three_region_cube import pytest from tests.testing_harness import TolerantPyAPITestHarness -def fill_3d_list(n, val): - """ - Generates a 3D list of dimensions nxnxn filled with copies of val. - - Parameters: - n (int): The dimension of the 3D list. - val (any): The value to fill the 3D list with. - - Returns: - list: A 3D list of dimensions nxnxn filled with val. - """ - return [[[val for _ in range(n)] for _ in range(n)] for _ in range(n)] - - class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() @@ -28,312 +15,39 @@ def _cleanup(self): if os.path.exists(f): os.remove(f) -def create_random_ray_model(domain_type): - openmc.reset_auto_ids() - ############################################################################### - # Create multigroup data - - # Instantiate the energy group data - ebins = [1e-5, 20.0e6] - groups = openmc.mgxs.EnergyGroups(group_edges=ebins) - - # High scattering ratio means system is all scattering - # Low means fully absorbing - scattering_ratio = 0.5 - - source_total_xs = 0.1 - source_mat_data = openmc.XSdata('source', groups) - source_mat_data.order = 0 - source_mat_data.set_total([source_total_xs]) - source_mat_data.set_absorption([source_total_xs * (1.0 - scattering_ratio)]) - source_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[source_total_xs * scattering_ratio]]]),0,3)) - - void_total_xs = 1.0e-4 - void_mat_data = openmc.XSdata('void', groups) - void_mat_data.order = 0 - void_mat_data.set_total([void_total_xs]) - void_mat_data.set_absorption([void_total_xs * (1.0 - scattering_ratio)]) - void_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[void_total_xs * scattering_ratio]]]),0,3)) - - shield_total_xs = 0.1 - shield_mat_data = openmc.XSdata('shield', groups) - shield_mat_data.order = 0 - shield_mat_data.set_total([shield_total_xs]) - shield_mat_data.set_absorption([shield_total_xs * (1.0 - scattering_ratio)]) - shield_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[shield_total_xs * scattering_ratio]]]),0,3)) - - mg_cross_sections_file = openmc.MGXSLibrary(groups) - mg_cross_sections_file.add_xsdatas([source_mat_data, void_mat_data, shield_mat_data]) - mg_cross_sections_file.export_to_hdf5() - - ############################################################################### - # Create materials for the problem - - # Instantiate some Macroscopic Data - source_data = openmc.Macroscopic('source') - void_data = openmc.Macroscopic('void') - shield_data = openmc.Macroscopic('shield') - - # Instantiate some Materials and register the appropriate Macroscopic objects - source_mat = openmc.Material(name='source') - source_mat.set_density('macro', 1.0) - source_mat.add_macroscopic(source_data) - - void_mat = openmc.Material(name='void') - void_mat.set_density('macro', 1.0) - void_mat.add_macroscopic(void_data) - - shield_mat = openmc.Material(name='shield') - shield_mat.set_density('macro', 1.0) - shield_mat.add_macroscopic(shield_data) - - # Instantiate a Materials collection and export to XML - materials_file = openmc.Materials([source_mat, void_mat, shield_mat]) - materials_file.cross_sections = "mgxs.h5" - - ############################################################################### - # Define problem geometry - - source_cell = openmc.Cell(fill=source_mat, name='infinite source region') - void_cell = openmc.Cell(fill=void_mat, name='infinite void region') - shield_cell = openmc.Cell(fill=shield_mat, name='infinite shield region') - - sub = openmc.Universe() - sub.add_cells([source_cell]) - - vub = openmc.Universe() - vub.add_cells([void_cell]) - - aub = openmc.Universe() - aub.add_cells([shield_cell]) - - # n controls the dimension of subdivision within each outer lattice element - # E.g., n = 10 results in 1cm cubic FSRs - n = 2 - delta = 10.0 / n - ll = [-5.0, -5.0, -5.0] - pitch = [delta, delta, delta] - - source_lattice = openmc.RectLattice() - source_lattice.lower_left = ll - source_lattice.pitch = pitch - source_lattice.universes = fill_3d_list(n, sub) - - void_lattice = openmc.RectLattice() - void_lattice.lower_left = ll - void_lattice.pitch = pitch - void_lattice.universes = fill_3d_list(n, vub) - - shield_lattice = openmc.RectLattice() - shield_lattice.lower_left = ll - shield_lattice.pitch = pitch - shield_lattice.universes = fill_3d_list(n, aub) - - source_lattice_cell = openmc.Cell(fill=source_lattice, name='source lattice cell') - su = openmc.Universe() - su.add_cells([source_lattice_cell]) - - void_lattice_cell = openmc.Cell(fill=void_lattice, name='void lattice cell') - vu = openmc.Universe() - vu.add_cells([void_lattice_cell]) - - shield_lattice_cell = openmc.Cell(fill=shield_lattice, name='shield lattice cell') - au = openmc.Universe() - au.add_cells([shield_lattice_cell]) - - z_base = [ - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [vu, vu, vu, vu, au, au], - [vu, au, au, au, au, au], - [vu, au, au, au, au, au], - [vu, au, au, au, au, au], - [vu, au, au, au, au, au], - [su, au, au, au, au, au] - ] - - z_col = [ - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, vu, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au] - ] - - z_high = [ - [au, au, au, vu, au, au], - [au, au, au, vu, au, au], - [au, au, au, vu, au, au], - [au, au, au, vu, au, au], - [au, au, au, vu, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au] - ] - - z_cap = [ - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au], - [au, au, au, au, au, au] - ] - - dogleg_pattern = [ - z_base, - z_col, - z_col, - z_high, - z_cap, - z_cap - ] - - x = 60.0 - x_dim = 6 - - y = 100.0 - y_dim = 10 - - z = 60.0 - z_dim = 6 - - lattice = openmc.RectLattice() - lattice.lower_left = [0.0, 0.0, 0.0] - lattice.pitch = [x/x_dim, y/y_dim, z/z_dim] - lattice.universes = dogleg_pattern - - lattice_cell = openmc.Cell(fill=lattice, name='dogleg lattice cell') - - lattice_uni = openmc.Universe() - lattice_uni.add_cells([lattice_cell]) - - x_low = openmc.XPlane(x0=0.0,boundary_type='reflective') - x_high = openmc.XPlane(x0=x,boundary_type='vacuum') - - y_low = openmc.YPlane(y0=0.0,boundary_type='reflective') - y_high = openmc.YPlane(y0=y,boundary_type='vacuum') - - z_low = openmc.ZPlane(z0=0.0,boundary_type='reflective') - z_high = openmc.ZPlane(z0=z,boundary_type='vacuum') - - full_domain = openmc.Cell(fill=lattice_uni, region=+x_low & -x_high & +y_low & -y_high & +z_low & -z_high, name='full domain') - - root = openmc.Universe(name='root universe') - root.add_cell(full_domain) - - # Create a geometry with the two cells and export to XML - geometry = openmc.Geometry(root) - - ############################################################################### - # Define problem settings - - # Instantiate a Settings object, set all runtime parameters, and export to XML - settings = openmc.Settings() - settings.energy_mode = "multi-group" - settings.batches = 10 - settings.inactive = 5 - settings.particles = 1000 - settings.run_mode = 'fixed source' - - settings.random_ray['distance_active'] = 400.0 - settings.random_ray['distance_inactive'] = 100.0 - - # Create an initial uniform spatial source for ray integration - lower_left = (0.0, 0.0, 0.0) - upper_right = (x, y, z) - uniform_dist = openmc.stats.Box(lower_left, upper_right) - settings.random_ray['ray_source']= openmc.IndependentSource(space=uniform_dist) - - # Create the neutron source in the bottom right of the moderator - strengths = [1.0] - midpoints = [100.0] - energy_distribution = openmc.stats.Discrete(x=midpoints,p=strengths) - if domain_type == 'cell': - domain = source_lattice_cell - elif domain_type == 'material': - domain = source_mat - elif domain_type == 'universe': - domain = sub - source = openmc.IndependentSource( - energy=energy_distribution, - constraints={'domains': [domain]} - ) - settings.source = [source] - - ############################################################################### - # Define tallies - - estimator = 'analog' - - # Case 3A - mesh_3A = openmc.RegularMesh() - mesh_3A.dimension = (1, y_dim, 1) - mesh_3A.lower_left = (0.0, 0.0, 0.0) - mesh_3A.upper_right = (10.0, y, 10.0) - mesh_filter_3A = openmc.MeshFilter(mesh_3A) - - tally_3A = openmc.Tally(name="Case 3A") - tally_3A.filters = [mesh_filter_3A] - tally_3A.scores = ['flux'] - tally_3A.estimator = estimator - - # Case 3B - mesh_3B = openmc.RegularMesh() - mesh_3B.dimension = (x_dim, 1, 1) - mesh_3B.lower_left = (0.0, 50.0, 0.0) - mesh_3B.upper_right = (x, 60.0, 10.0) - mesh_filter_3B = openmc.MeshFilter(mesh_3B) - - tally_3B = openmc.Tally(name="Case 3B") - tally_3B.filters = [mesh_filter_3B] - tally_3B.scores = ['flux'] - tally_3B.estimator = estimator - - # Case 3C - mesh_3C = openmc.RegularMesh() - mesh_3C.dimension = (x_dim, 1, 1) - mesh_3C.lower_left = (0.0, 90.0, 30.0) - mesh_3C.upper_right = (x, 100.0, 40.0) - mesh_filter_3C = openmc.MeshFilter(mesh_3C) - - tally_3C = openmc.Tally(name="Case 3C") - tally_3C.filters = [mesh_filter_3C] - tally_3C.scores = ['flux'] - tally_3C.estimator = estimator - - # Instantiate a Tallies collection and export to XML - tallies = openmc.Tallies([tally_3A, tally_3B, tally_3C]) - - ############################################################################### - # Assmble Model - - model = openmc.model.Model() - model.geometry = geometry - model.materials = materials_file - model.settings = settings - model.xs_data = mg_cross_sections_file - model.tallies = tallies - - return model - @pytest.mark.parametrize("domain_type", ["cell", "material", "universe"]) def test_random_ray_fixed_source(domain_type): with change_directory(domain_type): - model = create_random_ray_model(domain_type) + openmc.reset_auto_ids() + model = random_ray_three_region_cube() + source = model.settings.source[0] + constraints = source.constraints + print(constraints) + + if domain_type == 'cell': + # Convert reflective surfaces to vacuum + cells = model.geometry.get_all_cells() + for key, cell in cells.items(): + print(cell.name) + if cell.name == 'infinite source region': + constraints['domain_type'] = 'cell' + constraints['domain_ids'] = [cell.id] + elif domain_type == 'material': + # Convert reflective surfaces to vacuum + materials = model.materials + for material in materials: + if material.name == 'source': + constraints['domain_type'] = 'material' + constraints['domain_ids'] = [material.id] + elif domain_type == 'universe': + universes = model.geometry.get_all_universes() + for key, universe in universes.items(): + if universe.name == 'source universe': + constraints['domain_type'] = 'universe' + constraints['domain_ids'] = [universe.id] + + print(constraints) + harness = MGXSTestHarness('statepoint.10.h5', model) - harness.main() + harness.main() \ No newline at end of file diff --git a/tests/regression_tests/random_ray_fixed_source/universe/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source/universe/inputs_true.dat index 349917fee72..3dd0900d2bf 100644 --- a/tests/regression_tests/random_ray_fixed_source/universe/inputs_true.dat +++ b/tests/regression_tests/random_ray_fixed_source/universe/inputs_true.dat @@ -10,137 +10,191 @@ - + - + - - - - - - + + + - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 -1 1 -1 1 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 -1 1 -1 1 - - - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 - -2 2 -2 2 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 -2 2 -2 2 - - - 5.0 5.0 5.0 - 2 2 2 - -5.0 -5.0 -5.0 - -3 3 -3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -3 3 -3 3 - - - 10.0 10.0 10.0 - 6 10 6 - 0.0 0.0 0.0 - -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -8 8 8 8 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -8 9 9 9 9 9 -7 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 8 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 -9 9 9 9 9 9 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 - + - + - + fixed source - 1000 + 90 10 5 - + 100.0 1.0 @@ -151,54 +205,39 @@ multi-group - 400.0 + 500.0 100.0 - 0.0 0.0 0.0 60.0 100.0 60.0 + 0.0 0.0 0.0 30.0 30.0 30.0 - - 1 10 1 - 0.0 0.0 0.0 - 10.0 100.0 10.0 - - - 6 1 1 - 0.0 50.0 0.0 - 60.0 60.0 10.0 - - - 6 1 1 - 0.0 90.0 30.0 - 60.0 100.0 40.0 - - + 1 - + 2 - + 3 - - 1 + + 3 flux - analog + tracklength - + 2 flux - analog + tracklength - - 3 + + 1 flux - analog + tracklength diff --git a/tests/regression_tests/random_ray_fixed_source/universe/results_true.dat b/tests/regression_tests/random_ray_fixed_source/universe/results_true.dat index 36d24e939af..714ad44a084 100644 --- a/tests/regression_tests/random_ray_fixed_source/universe/results_true.dat +++ b/tests/regression_tests/random_ray_fixed_source/universe/results_true.dat @@ -1,47 +1,9 @@ tally 1: -3.751047E+01 -2.841797E+02 -9.930788E+00 -1.988180E+01 -3.781121E+00 -3.005165E+00 -2.383139E+00 -1.232560E+00 -1.561884E+00 -6.440577E-01 -1.089787E+00 -3.724896E-01 -6.608456E-01 -1.285592E-01 -2.372611E-01 -1.601299E-02 -7.814803E-02 -1.765829E-03 -2.862107E-02 -2.460129E-04 +-6.614591E+04 +1.283943E+09 tally 2: -1.089787E+00 -3.724896E-01 -3.767926E-01 -3.724399E-02 -8.614120E-02 -1.526889E-03 -3.610725E-02 -2.629885E-04 -1.466261E-02 -4.536997E-05 -4.653106E-03 -4.381672E-06 +3.415331E+00 +2.396684E+00 tally 3: -1.617918E-03 -6.317049E-07 -1.161473E-03 -2.789553E-07 -1.198879E-03 -3.189531E-07 -1.031737E-03 -2.207381E-07 -5.466329E-04 -6.166808E-08 -2.146062E-04 -9.937520E-09 +2.277429E-01 +1.050297E-02 diff --git a/tests/regression_tests/random_ray_vacuum/test.py b/tests/regression_tests/random_ray_vacuum/test.py index 341c2005d49..e195c378f20 100644 --- a/tests/regression_tests/random_ray_vacuum/test.py +++ b/tests/regression_tests/random_ray_vacuum/test.py @@ -2,7 +2,7 @@ import numpy as np import openmc -from openmc.examples import random_ray_lattice_mgxs, random_ray_lattice +from openmc.examples import random_ray_lattice from tests.testing_harness import TolerantPyAPITestHarness @@ -14,14 +14,10 @@ def _cleanup(self): os.remove(f) def test_random_ray_vacuum(): - mgxs = random_ray_lattice_mgxs() - mgxs.export_to_hdf5('mgxs.h5') model = random_ray_lattice() - pitch = 1.26 - geometry = model.geometry # Convert reflective surfaces to vacuum - surfaces = geometry.get_all_surfaces() + surfaces = model.geometry.get_all_surfaces() for key, surface in surfaces.items(): if surface.boundary_type == 'reflective': surface.boundary_type = 'vacuum' From 55919729acc709e6a6b8edbb8890895060b336c1 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 13:11:41 -0500 Subject: [PATCH 14/61] changed random ray test names --- .../__init__.py | 0 .../cell/inputs_true.dat | 0 .../cell/results_true.dat | 0 .../material/inputs_true.dat | 0 .../material/results_true.dat | 0 .../test.py | 0 .../universe/inputs_true.dat | 0 .../universe/results_true.dat | 0 .../{random_ray_fixed_source => random_ray_k_eff}/__init__.py | 0 .../{random_ray_basic => random_ray_k_eff}/inputs_true.dat | 0 .../{random_ray_basic => random_ray_k_eff}/results_true.dat | 0 .../{random_ray_basic => random_ray_k_eff}/test.py | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename tests/regression_tests/{random_ray_basic => random_ray_fixed_source_domain}/__init__.py (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/cell/inputs_true.dat (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/cell/results_true.dat (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/material/inputs_true.dat (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/material/results_true.dat (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/test.py (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/universe/inputs_true.dat (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_fixed_source_domain}/universe/results_true.dat (100%) rename tests/regression_tests/{random_ray_fixed_source => random_ray_k_eff}/__init__.py (100%) rename tests/regression_tests/{random_ray_basic => random_ray_k_eff}/inputs_true.dat (100%) rename tests/regression_tests/{random_ray_basic => random_ray_k_eff}/results_true.dat (100%) rename tests/regression_tests/{random_ray_basic => random_ray_k_eff}/test.py (100%) diff --git a/tests/regression_tests/random_ray_basic/__init__.py b/tests/regression_tests/random_ray_fixed_source_domain/__init__.py similarity index 100% rename from tests/regression_tests/random_ray_basic/__init__.py rename to tests/regression_tests/random_ray_fixed_source_domain/__init__.py diff --git a/tests/regression_tests/random_ray_fixed_source/cell/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/cell/inputs_true.dat similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/cell/inputs_true.dat rename to tests/regression_tests/random_ray_fixed_source_domain/cell/inputs_true.dat diff --git a/tests/regression_tests/random_ray_fixed_source/cell/results_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/cell/results_true.dat similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/cell/results_true.dat rename to tests/regression_tests/random_ray_fixed_source_domain/cell/results_true.dat diff --git a/tests/regression_tests/random_ray_fixed_source/material/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/material/inputs_true.dat similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/material/inputs_true.dat rename to tests/regression_tests/random_ray_fixed_source_domain/material/inputs_true.dat diff --git a/tests/regression_tests/random_ray_fixed_source/material/results_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/material/results_true.dat similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/material/results_true.dat rename to tests/regression_tests/random_ray_fixed_source_domain/material/results_true.dat diff --git a/tests/regression_tests/random_ray_fixed_source/test.py b/tests/regression_tests/random_ray_fixed_source_domain/test.py similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/test.py rename to tests/regression_tests/random_ray_fixed_source_domain/test.py diff --git a/tests/regression_tests/random_ray_fixed_source/universe/inputs_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/universe/inputs_true.dat similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/universe/inputs_true.dat rename to tests/regression_tests/random_ray_fixed_source_domain/universe/inputs_true.dat diff --git a/tests/regression_tests/random_ray_fixed_source/universe/results_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/universe/results_true.dat similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/universe/results_true.dat rename to tests/regression_tests/random_ray_fixed_source_domain/universe/results_true.dat diff --git a/tests/regression_tests/random_ray_fixed_source/__init__.py b/tests/regression_tests/random_ray_k_eff/__init__.py similarity index 100% rename from tests/regression_tests/random_ray_fixed_source/__init__.py rename to tests/regression_tests/random_ray_k_eff/__init__.py diff --git a/tests/regression_tests/random_ray_basic/inputs_true.dat b/tests/regression_tests/random_ray_k_eff/inputs_true.dat similarity index 100% rename from tests/regression_tests/random_ray_basic/inputs_true.dat rename to tests/regression_tests/random_ray_k_eff/inputs_true.dat diff --git a/tests/regression_tests/random_ray_basic/results_true.dat b/tests/regression_tests/random_ray_k_eff/results_true.dat similarity index 100% rename from tests/regression_tests/random_ray_basic/results_true.dat rename to tests/regression_tests/random_ray_k_eff/results_true.dat diff --git a/tests/regression_tests/random_ray_basic/test.py b/tests/regression_tests/random_ray_k_eff/test.py similarity index 100% rename from tests/regression_tests/random_ray_basic/test.py rename to tests/regression_tests/random_ray_k_eff/test.py From b35b7ecaf9c97265b4ccea6697d429cd7e241ea2 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 13:19:16 -0500 Subject: [PATCH 15/61] cleanup of cube example --- openmc/examples.py | 14 +++++++------- .../random_ray_fixed_source_domain/test.py | 11 ++++------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index cd2abc7f275..73d1d2ded51 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -872,16 +872,18 @@ def random_ray_lattice(): return model def random_ray_three_region_cube(): - """Create a 2x2 PWR pincell asymmetrical lattic eexample. + """Create a three region cube model. - This model is a 2x2 reflective lattice of fuel pins with one of the lattice - locations have just moderator instead of a fuel pin. It uses 7 group - cross section data + This is a simple monoenergetic problem of a cube with three concentric cubic + regions. The innermost region is near void (with Sigma_t around 10^-5) and + contains an external isotropic source term, the middle region is void (with + Sigma_t around 10^-4), and the outer region of the cube is an absorber + (with Sigma_t around 1). Returns ------- model : openmc.model.Model - A PWR pin-cell model + A three region cube model """ @@ -930,7 +932,6 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): source_sigma_s = void_sigma_s * multiplier source_mat_data = openmc.XSdata('source', groups) source_mat_data.order = 0 - print(source_sigma_a + source_sigma_s) source_mat_data.set_total([source_sigma_a + source_sigma_s]) source_mat_data.set_absorption([source_sigma_a]) source_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[source_sigma_s]]]),0,3)) @@ -995,7 +996,6 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): lattice.lower_left = [0.0, 0.0, 0.0] lattice.pitch = [pitch, pitch, pitch] lattice.universes = pattern - #print(lattice) lattice_cell = openmc.Cell(fill=lattice) diff --git a/tests/regression_tests/random_ray_fixed_source_domain/test.py b/tests/regression_tests/random_ray_fixed_source_domain/test.py index cc07a4e4092..13a93f39334 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/test.py +++ b/tests/regression_tests/random_ray_fixed_source_domain/test.py @@ -20,12 +20,13 @@ def test_random_ray_fixed_source(domain_type): with change_directory(domain_type): openmc.reset_auto_ids() model = random_ray_three_region_cube() + + # Based on the parameter, we need to adjust + # the particle source constraints source = model.settings.source[0] constraints = source.constraints - print(constraints) - + if domain_type == 'cell': - # Convert reflective surfaces to vacuum cells = model.geometry.get_all_cells() for key, cell in cells.items(): print(cell.name) @@ -33,7 +34,6 @@ def test_random_ray_fixed_source(domain_type): constraints['domain_type'] = 'cell' constraints['domain_ids'] = [cell.id] elif domain_type == 'material': - # Convert reflective surfaces to vacuum materials = model.materials for material in materials: if material.name == 'source': @@ -45,9 +45,6 @@ def test_random_ray_fixed_source(domain_type): if universe.name == 'source universe': constraints['domain_type'] = 'universe' constraints['domain_ids'] = [universe.id] - - print(constraints) - harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() \ No newline at end of file From 23a8102fbeaea3564bc7e499d054f0a392b030ab Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 13:47:44 -0500 Subject: [PATCH 16/61] reduced comment block width --- openmc/examples.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index 73d1d2ded51..43ebfb25a1a 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -660,7 +660,7 @@ def random_ray_lattice(): """ model = openmc.model.Model() - ############################################################################### + ########################################################################### # Create MGXS data for the problem # Instantiate the energy group data @@ -716,7 +716,7 @@ def random_ray_lattice(): mg_cross_sections.add_xsdatas([uo2_xsdata, h2o_xsdata]) mg_cross_sections.export_to_hdf5('mgxs.h5') - ############################################################################### + ########################################################################### # Create materials for the problem # Instantiate some Materials and register the appropriate macroscopic data @@ -732,7 +732,7 @@ def random_ray_lattice(): materials = openmc.Materials([uo2, water]) materials.cross_sections = "mgxs.h5" - ############################################################################### + ########################################################################### # Define problem geometry ######################################## @@ -816,7 +816,7 @@ def random_ray_lattice(): # Create a geometry with the top-level cell geometry = openmc.Geometry([assembly]) - ############################################################################### + ########################################################################### # Define problem settings # Instantiate a Settings object, set all runtime parameters, and export to XML @@ -836,7 +836,7 @@ def random_ray_lattice(): settings.random_ray['distance_inactive'] = 20.0 settings.random_ray['ray_source'] = rr_source - ############################################################################### + ########################################################################### # Define tallies # Create a mesh that will be used for tallying @@ -861,9 +861,9 @@ def random_ray_lattice(): # Instantiate a Tallies collection and export to XML tallies = openmc.Tallies([tally]) - ############################################################################### + ########################################################################### # Exporting to OpenMC model - ############################################################################### + ########################################################################### model.geometry = geometry model.materials = materials @@ -889,7 +889,7 @@ def random_ray_three_region_cube(): model = openmc.model.Model() - ############################################################################### + ########################################################################### # Helper function creates a 3 region cube with different fills in each region def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): cube = [[[0 for _ in range(N)] for _ in range(N)] for _ in range(N)] @@ -904,7 +904,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): cube[i][j][k] = fill_3 return cube - ############################################################################### + ########################################################################### # Create multigroup data # Instantiate the energy group data @@ -940,7 +940,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): mg_cross_sections_file.add_xsdatas([source_mat_data, void_mat_data, absorber_mat_data]) mg_cross_sections_file.export_to_hdf5() - ############################################################################### + ########################################################################### # Create materials for the problem # Instantiate some Macroscopic Data @@ -965,7 +965,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): materials_file = openmc.Materials([source_mat, void_mat, absorber_mat]) materials_file.cross_sections = "mgxs.h5" - ############################################################################### + ########################################################################### # Define problem geometry source_cell = openmc.Cell(fill=source_mat, name='infinite source region') @@ -1019,7 +1019,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): # Create a geometry with the two cells and export to XML geometry = openmc.Geometry(root) - ############################################################################### + ########################################################################### # Define problem settings # Instantiate a Settings object, set all runtime parameters, and export to XML @@ -1049,7 +1049,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): settings.source = [source] - ############################################################################### + ########################################################################### # Define tallies estimator = 'tracklength' @@ -1075,7 +1075,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): # Instantiate a Tallies collection and export to XML tallies = openmc.Tallies([source_tally, void_tally, absorber_tally]) - ############################################################################### + ########################################################################### # Assmble Model model.geometry = geometry From 28bf71bb33aa335e0e58781b012761d42feb84b1 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 13:52:03 -0500 Subject: [PATCH 17/61] formatted examples.py with autopep8 --- openmc/examples.py | 140 +++++++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 50 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index 43ebfb25a1a..22bdd60b845 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -77,7 +77,8 @@ def pwr_pin_cell(): model.settings.inactive = 5 model.settings.particles = 100 model.settings.source = openmc.IndependentSource( - space=openmc.stats.Box([-pitch/2, -pitch/2, -1], [pitch/2, pitch/2, 1]), + space=openmc.stats.Box([-pitch/2, -pitch/2, -1], + [pitch/2, pitch/2, 1]), constraints={'fissionable': True} ) @@ -166,7 +167,8 @@ def pwr_core(): lower_rad_ref.add_nuclide('Cr52', 0.145407678031, 'wo') lower_rad_ref.add_s_alpha_beta('c_H_in_H2O') - upper_rad_ref = openmc.Material(7, name='Upper radial reflector / Top plate region') + upper_rad_ref = openmc.Material( + 7, name='Upper radial reflector / Top plate region') upper_rad_ref.set_density('g/cm3', 4.28) upper_rad_ref.add_nuclide('H1', 0.0086117, 'wo') upper_rad_ref.add_nuclide('O16', 0.0683369, 'wo') @@ -313,13 +315,15 @@ def pwr_core(): 11, 11, 11, 11, 11, 13, 13, 14, 14, 14]) # Define fuel lattices. - l100 = openmc.RectLattice(name='Fuel assembly (lower half)', lattice_id=100) + l100 = openmc.RectLattice( + name='Fuel assembly (lower half)', lattice_id=100) l100.lower_left = (-10.71, -10.71) l100.pitch = (1.26, 1.26) l100.universes = np.tile(fuel_cold, (17, 17)) l100.universes[tube_x, tube_y] = tube_cold - l101 = openmc.RectLattice(name='Fuel assembly (upper half)', lattice_id=101) + l101 = openmc.RectLattice( + name='Fuel assembly (upper half)', lattice_id=101) l101.lower_left = (-10.71, -10.71) l101.pitch = (1.26, 1.26) l101.universes = np.tile(fuel_hot, (17, 17)) @@ -405,10 +409,14 @@ def pwr_core(): c6 = openmc.Cell(cell_id=6, fill=top_fa, region=-s5 & +s36 & -s37) c7 = openmc.Cell(cell_id=7, fill=top_nozzle, region=-s5 & +s37 & -s38) c8 = openmc.Cell(cell_id=8, fill=upper_rad_ref, region=-s7 & +s38 & -s39) - c9 = openmc.Cell(cell_id=9, fill=bot_nozzle, region=+s6 & -s7 & +s32 & -s38) - c10 = openmc.Cell(cell_id=10, fill=rpv_steel, region=+s7 & -s8 & +s31 & -s39) - c11 = openmc.Cell(cell_id=11, fill=lower_rad_ref, region=+s5 & -s6 & +s32 & -s34) - c12 = openmc.Cell(cell_id=12, fill=upper_rad_ref, region=+s5 & -s6 & +s36 & -s38) + c9 = openmc.Cell(cell_id=9, fill=bot_nozzle, + region=+s6 & -s7 & +s32 & -s38) + c10 = openmc.Cell(cell_id=10, fill=rpv_steel, + region=+s7 & -s8 & +s31 & -s39) + c11 = openmc.Cell(cell_id=11, fill=lower_rad_ref, + region=+s5 & -s6 & +s32 & -s34) + c12 = openmc.Cell(cell_id=12, fill=upper_rad_ref, + region=+s5 & -s6 & +s36 & -s38) root.add_cells((c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)) # Assign root universe to geometry @@ -489,10 +497,10 @@ def pwr_assembly(): fuel_pin_universe = openmc.Universe(name='Fuel Pin') fuel_cell = openmc.Cell(name='fuel', fill=fuel, region=-fuel_or) clad_cell = openmc.Cell(name='clad', fill=clad, region=+fuel_or & -clad_or) - hot_water_cell = openmc.Cell(name='hot water', fill=hot_water, region=+clad_or) + hot_water_cell = openmc.Cell( + name='hot water', fill=hot_water, region=+clad_or) fuel_pin_universe.add_cells([fuel_cell, clad_cell, hot_water_cell]) - # Create a control rod guide tube universe guide_tube_universe = openmc.Universe(name='Guide Tube') gt_inner_cell = openmc.Cell(name='guide tube inner water', fill=hot_water, @@ -530,7 +538,8 @@ def pwr_assembly(): model.settings.inactive = 5 model.settings.particles = 100 model.settings.source = openmc.IndependentSource( - space=openmc.stats.Box([-pitch/2, -pitch/2, -1], [pitch/2, pitch/2, 1]), + space=openmc.stats.Box([-pitch/2, -pitch/2, -1], + [pitch/2, pitch/2, 1]), constraints={'fissionable': True} ) @@ -645,6 +654,7 @@ def slab_mg(num_regions=1, mat_names=None, mgxslib_name='2g.h5'): return model + def random_ray_lattice(): """Create a 2x2 PWR pincell asymmetrical lattic eexample. @@ -677,11 +687,16 @@ def random_ray_lattice(): 3.0020e-02, 1.1126e-01, 2.8278e-01]) scatter_matrix = np.array( [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], + [0.0000000, 0.3244560, 0.0016314, 0.0000000, + 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.4509400, 0.0026792, + 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.4525650, + 0.0055664, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0001253, + 0.2714010, 0.0102550, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, + 0.0012968, 0.2658020, 0.0168090], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) uo2_xsdata.set_scatter_matrix(scatter_matrix) @@ -703,11 +718,16 @@ def random_ray_lattice(): 3.7239e-02]) scatter_matrix = np.array( [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], - [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], - [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], - [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], - [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], + [0.0000000, 0.2823340, 0.1299400, 0.0006234, + 0.0000480, 0.0000074, 0.0000010], + [0.0000000, 0.0000000, 0.3452560, 0.2245700, + 0.0169990, 0.0026443, 0.0005034], + [0.0000000, 0.0000000, 0.0000000, 0.0910284, + 0.4155100, 0.0637320, 0.0121390], + [0.0000000, 0.0000000, 0.0000000, 0.0000714, + 0.1391380, 0.5118200, 0.0612290], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, + 0.0022157, 0.6999130, 0.5373200], [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) scatter_matrix = np.rollaxis(scatter_matrix, 0, 3) h2o_xsdata.set_scatter_matrix(scatter_matrix) @@ -749,31 +769,39 @@ def random_ray_lattice(): # Instantiate Cells fuel_a = openmc.Cell(fill=uo2, region=-inner_ring_a, name='fuel inner a') - fuel_b = openmc.Cell(fill=uo2, region=+inner_ring_a & -inner_ring_b, name='fuel inner b') - fuel_c = openmc.Cell(fill=uo2, region=+inner_ring_b & -fuel_or, name='fuel inner c') - moderator_a = openmc.Cell(fill=water, region=+fuel_or & -outer_ring_a, name='moderator inner a') - moderator_b = openmc.Cell(fill=water, region=+outer_ring_a & -outer_ring_b, name='moderator outer b') - moderator_c = openmc.Cell(fill=water, region=+outer_ring_b, name='moderator outer c') + fuel_b = openmc.Cell(fill=uo2, region=+inner_ring_a & - + inner_ring_b, name='fuel inner b') + fuel_c = openmc.Cell(fill=uo2, region=+inner_ring_b & - + fuel_or, name='fuel inner c') + moderator_a = openmc.Cell( + fill=water, region=+fuel_or & -outer_ring_a, name='moderator inner a') + moderator_b = openmc.Cell( + fill=water, region=+outer_ring_a & -outer_ring_b, name='moderator outer b') + moderator_c = openmc.Cell( + fill=water, region=+outer_ring_b, name='moderator outer c') # Create pincell universe pincell_base = openmc.Universe() # Register Cells with Universe - pincell_base.add_cells([fuel_a, fuel_b, fuel_c, moderator_a, moderator_b, moderator_c]) + pincell_base.add_cells( + [fuel_a, fuel_b, fuel_c, moderator_a, moderator_b, moderator_c]) # Create planes for azimuthal sectors azimuthal_planes = [] for i in range(8): angle = 2 * i * openmc.pi / 8 normal_vector = (-openmc.sin(angle), openmc.cos(angle), 0) - azimuthal_planes.append(openmc.Plane(a=normal_vector[0], b=normal_vector[1], c=normal_vector[2], d=0)) + azimuthal_planes.append(openmc.Plane( + a=normal_vector[0], b=normal_vector[1], c=normal_vector[2], d=0)) # Create a cell for each azimuthal sector azimuthal_cells = [] for i in range(8): azimuthal_cell = openmc.Cell(name=f'azimuthal_cell_{i}') azimuthal_cell.fill = pincell_base - azimuthal_cell.region = +azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] + azimuthal_cell.region = + \ + azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] azimuthal_cells.append(azimuthal_cell) # Create a geometry with the azimuthal universes @@ -809,7 +837,8 @@ def random_ray_lattice(): ######################################## # Define cell containing lattice and other stuff - box = openmc.model.RectangularPrism(pitch*2, pitch*2, boundary_type='reflective') + box = openmc.model.RectangularPrism( + pitch*2, pitch*2, boundary_type='reflective') assembly = openmc.Cell(fill=lattice2x2, region=-box, name='assembly') @@ -871,6 +900,7 @@ def random_ray_lattice(): model.tallies = tallies return model + def random_ray_three_region_cube(): """Create a three region cube model. @@ -917,7 +947,8 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): void_mat_data.order = 0 void_mat_data.set_total([void_sigma_a + void_sigma_s]) void_mat_data.set_absorption([void_sigma_a]) - void_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[void_sigma_s]]]),0,3)) + void_mat_data.set_scatter_matrix( + np.rollaxis(np.array([[[void_sigma_s]]]), 0, 3)) absorber_sigma_a = 0.75 absorber_sigma_s = 0.25 @@ -925,7 +956,8 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): absorber_mat_data.order = 0 absorber_mat_data.set_total([absorber_sigma_a + absorber_sigma_s]) absorber_mat_data.set_absorption([absorber_sigma_a]) - absorber_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[absorber_sigma_s]]]),0,3)) + absorber_mat_data.set_scatter_matrix( + np.rollaxis(np.array([[[absorber_sigma_s]]]), 0, 3)) multiplier = 0.1 source_sigma_a = void_sigma_a * multiplier @@ -934,10 +966,12 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): source_mat_data.order = 0 source_mat_data.set_total([source_sigma_a + source_sigma_s]) source_mat_data.set_absorption([source_sigma_a]) - source_mat_data.set_scatter_matrix(np.rollaxis(np.array([[[source_sigma_s]]]),0,3)) + source_mat_data.set_scatter_matrix( + np.rollaxis(np.array([[[source_sigma_s]]]), 0, 3)) mg_cross_sections_file = openmc.MGXSLibrary(groups) - mg_cross_sections_file.add_xsdatas([source_mat_data, void_mat_data, absorber_mat_data]) + mg_cross_sections_file.add_xsdatas( + [source_mat_data, void_mat_data, absorber_mat_data]) mg_cross_sections_file.export_to_hdf5() ########################################################################### @@ -945,7 +979,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): # Instantiate some Macroscopic Data source_data = openmc.Macroscopic('source') - void_data = openmc.Macroscopic('void') + void_data = openmc.Macroscopic('void') absorber_data = openmc.Macroscopic('absorber') # Instantiate some Materials and register the appropriate Macroscopic objects @@ -970,9 +1004,10 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): source_cell = openmc.Cell(fill=source_mat, name='infinite source region') void_cell = openmc.Cell(fill=void_mat, name='infinite void region') - absorber_cell = openmc.Cell(fill=absorber_mat, name='infinite absorber region') + absorber_cell = openmc.Cell( + fill=absorber_mat, name='infinite absorber region') - source_universe = openmc.Universe(name = 'source universe') + source_universe = openmc.Universe(name='source universe') source_universe.add_cells([source_cell]) void_universe = openmc.Universe() @@ -990,7 +1025,8 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): n = n_base * refinement_level pitch = absorber_width / n - pattern = fill_cube(n, 1*refinement_level, 5*refinement_level, source_universe, void_universe, absorber_universe) + pattern = fill_cube(n, 1*refinement_level, 5*refinement_level, + source_universe, void_universe, absorber_universe) lattice = openmc.RectLattice() lattice.lower_left = [0.0, 0.0, 0.0] @@ -1002,16 +1038,17 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): lattice_uni = openmc.Universe() lattice_uni.add_cells([lattice_cell]) - x_low = openmc.XPlane(x0=0.0,boundary_type='reflective') - x_high = openmc.XPlane(x0=absorber_width,boundary_type='vacuum') + x_low = openmc.XPlane(x0=0.0, boundary_type='reflective') + x_high = openmc.XPlane(x0=absorber_width, boundary_type='vacuum') - y_low = openmc.YPlane(y0=0.0,boundary_type='reflective') - y_high = openmc.YPlane(y0=absorber_width,boundary_type='vacuum') + y_low = openmc.YPlane(y0=0.0, boundary_type='reflective') + y_high = openmc.YPlane(y0=absorber_width, boundary_type='vacuum') - z_low = openmc.ZPlane(z0=0.0,boundary_type='reflective') - z_high = openmc.ZPlane(z0=absorber_width,boundary_type='vacuum') + z_low = openmc.ZPlane(z0=0.0, boundary_type='reflective') + z_high = openmc.ZPlane(z0=absorber_width, boundary_type='vacuum') - full_domain = openmc.Cell(fill=lattice_uni, region=+x_low & -x_high & +y_low & -y_high & +z_low & -z_high, name='full domain') + full_domain = openmc.Cell(fill=lattice_uni, region=+x_low & - + x_high & +y_low & -y_high & +z_low & -z_high, name='full domain') root = openmc.Universe(name='root universe') root.add_cell(full_domain) @@ -1033,7 +1070,8 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): # Create an initial uniform spatial source for ray integration lower_left_ray = [0.0, 0.0, 0.0] upper_right_ray = [absorber_width, absorber_width, absorber_width] - uniform_dist_ray = openmc.stats.Box(lower_left_ray, upper_right_ray, only_fissionable=False) + uniform_dist_ray = openmc.stats.Box( + lower_left_ray, upper_right_ray, only_fissionable=False) rr_source = openmc.IndependentSource(space=uniform_dist_ray) settings.random_ray['distance_active'] = 500.0 @@ -1041,11 +1079,13 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): settings.random_ray['ray_source'] = rr_source # Create the neutron source in the bottom right of the moderator - strengths = [1.0] # Good - fast group appears largest (besides most thermal) + # Good - fast group appears largest (besides most thermal) + strengths = [1.0] midpoints = [100.0] - energy_distribution = openmc.stats.Discrete(x=midpoints,p=strengths) + energy_distribution = openmc.stats.Discrete(x=midpoints, p=strengths) - source = openmc.IndependentSource(energy=energy_distribution, constraints={'domains':[source_universe]}, strength=3.14) + source = openmc.IndependentSource(energy=energy_distribution, constraints={ + 'domains': [source_universe]}, strength=3.14) settings.source = [source] @@ -1083,4 +1123,4 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): model.settings = settings model.tallies = tallies - return model \ No newline at end of file + return model From 6348358e106ede25fd2dda109f03f0d225f17b6b Mon Sep 17 00:00:00 2001 From: John Tramm Date: Wed, 26 Jun 2024 13:55:33 -0500 Subject: [PATCH 18/61] removed vacuum tests --- .../random_ray_vacuum/__init__.py | 0 .../random_ray_vacuum/inputs_true.dat | 108 ----------- .../random_ray_vacuum/results_true.dat | 171 ------------------ .../random_ray_vacuum/test.py | 27 --- 4 files changed, 306 deletions(-) delete mode 100644 tests/regression_tests/random_ray_vacuum/__init__.py delete mode 100644 tests/regression_tests/random_ray_vacuum/inputs_true.dat delete mode 100644 tests/regression_tests/random_ray_vacuum/results_true.dat delete mode 100644 tests/regression_tests/random_ray_vacuum/test.py diff --git a/tests/regression_tests/random_ray_vacuum/__init__.py b/tests/regression_tests/random_ray_vacuum/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/regression_tests/random_ray_vacuum/inputs_true.dat b/tests/regression_tests/random_ray_vacuum/inputs_true.dat deleted file mode 100644 index 4ef10942005..00000000000 --- a/tests/regression_tests/random_ray_vacuum/inputs_true.dat +++ /dev/null @@ -1,108 +0,0 @@ - - - - mgxs.h5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0.126 0.126 - 10 10 - -0.63 -0.63 - -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 -3 3 3 3 3 3 3 3 3 3 - - - 1.26 1.26 - 2 2 - -1.26 -1.26 - -2 2 -2 5 - - - - - - - - - - - - - - - - - - - - - eigenvalue - 100 - 10 - 5 - multi-group - - 100.0 - 20.0 - - - -1.26 -1.26 -1 1.26 1.26 1 - - - - - - - 2 2 - -1.26 -1.26 - 1.26 1.26 - - - 1 - - - 1e-05 0.0635 10.0 100.0 1000.0 500000.0 1000000.0 20000000.0 - - - 1 2 - flux fission nu-fission - analog - - - diff --git a/tests/regression_tests/random_ray_vacuum/results_true.dat b/tests/regression_tests/random_ray_vacuum/results_true.dat deleted file mode 100644 index c25999aad5a..00000000000 --- a/tests/regression_tests/random_ray_vacuum/results_true.dat +++ /dev/null @@ -1,171 +0,0 @@ -k-combined: -1.010455E-01 1.585558E-02 -tally 1: -7.466984E-01 -1.245920E-01 -2.771079E-01 -1.714504E-02 -6.744252E-01 -1.015566E-01 -1.634870E-01 -6.288701E-03 -2.405120E-02 -1.362874E-04 -5.853580E-02 -8.072823E-04 -1.641162E-02 -6.568765E-05 -5.223801E-04 -6.753516E-08 -1.271369E-03 -4.000365E-07 -3.014736E-02 -1.922973E-04 -9.765325E-04 -2.043645E-07 -2.376685E-03 -1.210529E-06 -1.562379E-01 -4.906526E-03 -1.746664E-03 -6.141658E-07 -4.251084E-03 -3.638028E-06 -1.826385E+00 -6.678141E-01 -3.095716E-03 -1.920117E-06 -7.660132E-03 -1.175650E-05 -2.013809E+00 -8.136726E-01 -3.015545E-02 -1.832201E-04 -8.387586E-02 -1.417475E-03 -1.573069E+00 -5.388374E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.867849E-01 -1.864798E-02 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.136372E-02 -1.035499E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -3.973323E-02 -3.229766E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.779974E-01 -6.350613E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.036886E+00 -2.151147E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -1.109991E+00 -2.468005E-01 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -5.813217E-01 -7.704274E-02 -2.160141E-01 -1.062660E-02 -5.257350E-01 -6.294540E-02 -1.358032E-01 -4.462239E-03 -2.030839E-02 -1.002755E-04 -4.942655E-02 -5.939703E-04 -1.612888E-02 -6.604109E-05 -5.274425E-04 -7.250333E-08 -1.283689E-03 -4.294649E-07 -2.985723E-02 -1.925418E-04 -9.868482E-04 -2.142916E-07 -2.401791E-03 -1.269331E-06 -1.590678E-01 -5.110940E-03 -1.800903E-03 -6.566490E-07 -4.383091E-03 -3.889678E-06 -1.928611E+00 -7.475889E-01 -3.310101E-03 -2.209547E-06 -8.190613E-03 -1.352862E-05 -2.172777E+00 -9.544513E-01 -3.334566E-02 -2.267149E-04 -9.274926E-02 -1.753971E-03 -7.566911E-01 -1.278105E-01 -2.881892E-01 -1.854375E-02 -7.013949E-01 -1.098417E-01 -1.662732E-01 -6.495387E-03 -2.515274E-02 -1.488430E-04 -6.121675E-02 -8.816538E-04 -1.682747E-02 -6.933017E-05 -5.514441E-04 -7.567901E-08 -1.342104E-03 -4.482757E-07 -3.068773E-02 -1.997062E-04 -1.021094E-03 -2.240938E-07 -2.485139E-03 -1.327393E-06 -1.578722E-01 -5.013656E-03 -1.812622E-03 -6.620083E-07 -4.411613E-03 -3.921424E-06 -1.922798E+00 -7.400474E-01 -3.401690E-03 -2.320513E-06 -8.417243E-03 -1.420805E-05 -2.178318E+00 -9.546106E-01 -3.451316E-02 -2.421994E-04 -9.599661E-02 -1.873766E-03 diff --git a/tests/regression_tests/random_ray_vacuum/test.py b/tests/regression_tests/random_ray_vacuum/test.py deleted file mode 100644 index e195c378f20..00000000000 --- a/tests/regression_tests/random_ray_vacuum/test.py +++ /dev/null @@ -1,27 +0,0 @@ -import os - -import numpy as np -import openmc -from openmc.examples import random_ray_lattice - -from tests.testing_harness import TolerantPyAPITestHarness - -class MGXSTestHarness(TolerantPyAPITestHarness): - def _cleanup(self): - super()._cleanup() - f = 'mgxs.h5' - if os.path.exists(f): - os.remove(f) - -def test_random_ray_vacuum(): - model = random_ray_lattice() - - # Convert reflective surfaces to vacuum - surfaces = model.geometry.get_all_surfaces() - for key, surface in surfaces.items(): - if surface.boundary_type == 'reflective': - surface.boundary_type = 'vacuum' - - # Create a geometry with the two cells and export to XML - harness = MGXSTestHarness('statepoint.10.h5', model) - harness.main() \ No newline at end of file From 1931213ed490ba1eb275877ff0f190f159ffa783 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Thu, 27 Jun 2024 09:58:34 -0500 Subject: [PATCH 19/61] working on moment matrix object --- src/random_ray/linear_source_domain.cpp | 34 ++++++++++--------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 42579d91e19..83dcf2a120a 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -55,32 +55,25 @@ void LinearSourceDomain::batch_reset() // } // Calculate source gradients by inverting the moment matrix -void moment_matrix_inversion(const std::vector& mom_matrix_, int sr, double& invM1, double& invM2, - double& invM3, double& invM4, double& invM5, double& invM6) +std::array moment_matrix_inversion(const std::vector& mom_matrix_, int sr) { int64_t midx = sr * 6; + std::array invM; double det = mom_matrix_[midx + 0] * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]) - mom_matrix_[midx + 3] * mom_matrix_[midx + 2] * mom_matrix_[midx + 2] - mom_matrix_[midx + 5] * mom_matrix_[midx + 1] * mom_matrix_[midx + 1] + 2 * mom_matrix_[midx + 1] * mom_matrix_[midx + 2] * mom_matrix_[midx + 4]; if ( abs(det) > 0.0 ) { //1E-10 double one_det = 1.0 / det; - invM1 = one_det * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]); - invM2 = one_det * (mom_matrix_[midx + 2] * mom_matrix_[midx + 4] - mom_matrix_[midx + 1] * mom_matrix_[midx + 5]); - invM3 = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 4] - mom_matrix_[midx + 3] * mom_matrix_[midx + 2]); - invM4 = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 5] - mom_matrix_[midx + 2] * mom_matrix_[midx + 2]); - invM5 = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 2] - mom_matrix_[midx + 0] * mom_matrix_[midx + 4]); - invM6 = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 3] - mom_matrix_[midx + 1] * mom_matrix_[midx + 1]); + invM[0] = one_det * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]); + invM[1] = one_det * (mom_matrix_[midx + 2] * mom_matrix_[midx + 4] - mom_matrix_[midx + 1] * mom_matrix_[midx + 5]); + invM[2] = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 4] - mom_matrix_[midx + 3] * mom_matrix_[midx + 2]); + invM[3] = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 5] - mom_matrix_[midx + 2] * mom_matrix_[midx + 2]); + invM[4] = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 2] - mom_matrix_[midx + 0] * mom_matrix_[midx + 4]); + invM[5] = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 3] - mom_matrix_[midx + 1] * mom_matrix_[midx + 1]); } else { - invM1 = 0.0; - invM2 = 0.0; - invM3 = 0.0; - invM4 = 0.0; - invM5 = 0.0; - invM6 = 0.0; - det = 1.0; + invM = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; } - } void LinearSourceDomain::update_neutron_source(double k_eff) @@ -100,8 +93,7 @@ simulation::time_update_src.start(); #pragma omp parallel for for (int sr = 0; sr < n_source_regions_; sr++) { int material = material_[sr]; - double invM1, invM2, invM3, invM4, invM5, invM6; - moment_matrix_inversion(mom_matrix_, sr, invM1, invM2, invM3, invM4, invM5, invM6); + std::array invM = moment_matrix_inversion(mom_matrix_, sr); for (int e_out = 0; e_out < negroups_; e_out++) { float sigma_t = data::mg.macro_xs_[material].get_xs( @@ -151,9 +143,9 @@ simulation::time_update_src.start(); float y_source = (y_scatter + y_fission) / sigma_t; float z_source = (z_scatter + z_fission) / sigma_t; - float new_source_x = invM1 * x_source + invM2 * y_source + invM3 * z_source; - float new_source_y = invM2 * x_source + invM4 * y_source + invM5 * z_source; - float new_source_z = invM3 * x_source + invM5 * y_source + invM6 * z_source; + float new_source_x = invM[0] * x_source + invM[1] * y_source + invM[2] * z_source; + float new_source_y = invM[1] * x_source + invM[3] * y_source + invM[4] * z_source; + float new_source_z = invM[2] * x_source + invM[4] * y_source + invM[5] * z_source; source_x_[sr * negroups_ + e_out] = new_source_x; source_y_[sr * negroups_ + e_out] = new_source_y; source_z_[sr * negroups_ + e_out] = new_source_z; From f190a0a9d3ea43480fc1417d73b4f7368d4af4d3 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Thu, 27 Jun 2024 16:32:09 -0500 Subject: [PATCH 20/61] made symmetric matrix class to handle moments operations --- CMakeLists.txt | 1 + .../openmc/random_ray/linear_source_domain.h | 5 +- include/openmc/random_ray/symmetric_matrix.h | 59 ++++ src/random_ray/linear_source_domain.cpp | 272 ++++++++---------- src/random_ray/random_ray.cpp | 19 +- src/random_ray/symmetric_matrix.cpp | 59 ++++ 6 files changed, 255 insertions(+), 160 deletions(-) create mode 100644 include/openmc/random_ray/symmetric_matrix.h create mode 100644 src/random_ray/symmetric_matrix.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eb62e4ba5cb..03298640493 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -381,6 +381,7 @@ list(APPEND libopenmc_SOURCES src/random_ray/random_ray.cpp src/random_ray/flat_source_domain.cpp src/random_ray/linear_source_domain.cpp + src/random_ray/symmetric_matrix.cpp src/reaction.cpp src/reaction_product.cpp src/scattdata.cpp diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index f245d15907d..000ca93da56 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -2,6 +2,7 @@ #define OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H #include "openmc/random_ray/flat_source_domain.h" +#include "openmc/random_ray/symmetric_matrix.h" #include "openmc/openmp_interface.h" #include "openmc/position.h" @@ -53,8 +54,8 @@ class LinearSourceDomain : public FlatSourceDomain { vector source_z_; vector centroid_; vector centroid_t_; - vector mom_matrix_; - vector mom_matrix_t_; + vector mom_matrix_; + vector mom_matrix_t_; private: //---------------------------------------------------------------------------- diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h new file mode 100644 index 00000000000..e128b43831c --- /dev/null +++ b/include/openmc/random_ray/symmetric_matrix.h @@ -0,0 +1,59 @@ +#ifndef OPENMC_SYMMETRIC_MATRIX_H +#define OPENMC_SYMMETRIC_MATRIX_H + +namespace openmc { + +// The SymmetricMatrix class is a sparese representation a 3x3 symmetric +// matrix, with elements labeled as follows: +// +// | a b c | +// | b d e | +// | c e f | +// +class SymmetricMatrix { +public: + //---------------------------------------------------------------------------- + // Public data members + double a; + double b; + double c; + double d; + double e; + double f; + + //---------------------------------------------------------------------------- + // Constructors + SymmetricMatrix() = default; + SymmetricMatrix(double a, double b, double c, double d, double e, double f) + : a(a), b(b), c(c), d(d), e(e), f(f) + {} + + //---------------------------------------------------------------------------- + // Methods + SymmetricMatrix inverse() const; + double determinant() const; + void set_to_zero() { a = b = c = d = e = f = 0; } + void scale(double x) + { + a *= x; + b *= x; + c *= x; + d *= x; + e *= x; + f *= x; + } + SymmetricMatrix& operator+=(const SymmetricMatrix& rhs) + { + a += rhs.a; + b += rhs.b; + c += rhs.c; + d += rhs.d; + e += rhs.e; + f += rhs.f; + return *this; + } +}; + +} // namespace openmc + +#endif // OPENMC_SYMMETRIC_MATRIX_H \ No newline at end of file diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 83dcf2a120a..56f8324b6bd 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -24,61 +24,37 @@ namespace openmc { LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() { - flux_x_new_.assign(n_source_elements_, 0.0); - flux_x_old_.assign(n_source_elements_, 0.0); - source_x_.assign(n_source_elements_, 0.0); - flux_y_new_.assign(n_source_elements_, 0.0); - flux_y_old_.assign(n_source_elements_, 0.0); - source_y_.assign(n_source_elements_, 0.0); - flux_z_new_.assign(n_source_elements_, 0.0); - flux_z_old_.assign(n_source_elements_, 0.0); - source_z_.assign(n_source_elements_, 0.0); - - centroid_.assign(n_source_regions_ * 3, nan("")); - centroid_t_.assign(n_source_regions_ * 3, 0.0); - mom_matrix_.assign(n_source_regions_ * 6, 0.0); - mom_matrix_t_.assign(n_source_regions_ * 6, 0.0); + flux_x_new_.assign(n_source_elements_, 0.0); + flux_x_old_.assign(n_source_elements_, 0.0); + source_x_.assign(n_source_elements_, 0.0); + flux_y_new_.assign(n_source_elements_, 0.0); + flux_y_old_.assign(n_source_elements_, 0.0); + source_y_.assign(n_source_elements_, 0.0); + flux_z_new_.assign(n_source_elements_, 0.0); + flux_z_old_.assign(n_source_elements_, 0.0); + source_z_.assign(n_source_elements_, 0.0); + + centroid_.assign(n_source_regions_ * 3, nan("")); + centroid_t_.assign(n_source_regions_ * 3, 0.0); + mom_matrix_.resize(n_source_regions_); + for( auto& m : mom_matrix_ ) + m.set_to_zero(); + mom_matrix_t_.resize(n_source_regions_); + for( auto& m : mom_matrix_t_ ) + m.set_to_zero(); } void LinearSourceDomain::batch_reset() { - FlatSourceDomain::batch_reset(); - parallel_fill(flux_x_new_, 0.0f); - parallel_fill(flux_y_new_, 0.0f); - parallel_fill(flux_z_new_, 0.0f); -} - -// void LinearSourceDomain::accumulate_iteration_flux() -// { -// // Fully reimplement this function for linear source -// // ... -// } - -// Calculate source gradients by inverting the moment matrix -std::array moment_matrix_inversion(const std::vector& mom_matrix_, int sr) -{ - int64_t midx = sr * 6; - std::array invM; - double det = mom_matrix_[midx + 0] * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]) - - mom_matrix_[midx + 3] * mom_matrix_[midx + 2] * mom_matrix_[midx + 2] - - mom_matrix_[midx + 5] * mom_matrix_[midx + 1] * mom_matrix_[midx + 1] + - 2 * mom_matrix_[midx + 1] * mom_matrix_[midx + 2] * mom_matrix_[midx + 4]; - if ( abs(det) > 0.0 ) { //1E-10 - double one_det = 1.0 / det; - invM[0] = one_det * (mom_matrix_[midx + 3] * mom_matrix_[midx + 5] - mom_matrix_[midx + 4] * mom_matrix_[midx + 4]); - invM[1] = one_det * (mom_matrix_[midx + 2] * mom_matrix_[midx + 4] - mom_matrix_[midx + 1] * mom_matrix_[midx + 5]); - invM[2] = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 4] - mom_matrix_[midx + 3] * mom_matrix_[midx + 2]); - invM[3] = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 5] - mom_matrix_[midx + 2] * mom_matrix_[midx + 2]); - invM[4] = one_det * (mom_matrix_[midx + 1] * mom_matrix_[midx + 2] - mom_matrix_[midx + 0] * mom_matrix_[midx + 4]); - invM[5] = one_det * (mom_matrix_[midx + 0] * mom_matrix_[midx + 3] - mom_matrix_[midx + 1] * mom_matrix_[midx + 1]); - } else { - invM = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - } + FlatSourceDomain::batch_reset(); + parallel_fill(flux_x_new_, 0.0f); + parallel_fill(flux_y_new_, 0.0f); + parallel_fill(flux_z_new_, 0.0f); } void LinearSourceDomain::update_neutron_source(double k_eff) { -simulation::time_update_src.start(); + simulation::time_update_src.start(); double inverse_k_eff = 1.0 / k_eff; @@ -88,103 +64,103 @@ simulation::time_update_src.start(); // angle data. const int t = 0; const int a = 0; - //double det; +// double det; +#pragma omp parallel for + for (int sr = 0; sr < n_source_regions_; sr++) { - #pragma omp parallel for + int material = material_[sr]; + SymmetricMatrix invM = mom_matrix_[sr].inverse(); + + for (int e_out = 0; e_out < negroups_; e_out++) { + float sigma_t = data::mg.macro_xs_[material].get_xs( + MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); + + float scatter_source = 0.0f; + float x_scatter = 0.0f; + float y_scatter = 0.0f; + float z_scatter = 0.0f; + float x_fission = 0.0f; + float y_fission = 0.0f; + float z_fission = 0.0f; + + for (int e_in = 0; e_in < negroups_; e_in++) { + float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; + float flux_x = flux_x_old_[sr * negroups_ + e_in]; + float flux_y = flux_y_old_[sr * negroups_ + e_in]; + float flux_z = flux_z_old_[sr * negroups_ + e_in]; + float sigma_s = data::mg.macro_xs_[material].get_xs( + MgxsType::NU_SCATTER, e_in, &e_out, nullptr, nullptr, t, a); + float nu_sigma_f = data::mg.macro_xs_[material].get_xs( + MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); + float chi = data::mg.macro_xs_[material].get_xs( + MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); + scatter_source += sigma_s * scalar_flux; + // Calculate scattering source for higher order scattering + x_scatter += sigma_s * flux_x; + y_scatter += sigma_s * flux_y; + z_scatter += sigma_s * flux_z; + x_fission += nu_sigma_f * flux_x * chi; + y_fission += nu_sigma_f * flux_y * chi; + z_fission += nu_sigma_f * flux_z * chi; + } + + // fission_source *= inverse_k_eff; + float new_isotropic_source = (scatter_source) / sigma_t; + source_[sr * negroups_ + e_out] = new_isotropic_source; + + if (simulation::current_batch > 2) { + + x_fission *= inverse_k_eff; + y_fission *= inverse_k_eff; + z_fission *= inverse_k_eff; + + float x_source = (x_scatter + x_fission) / sigma_t; + float y_source = (y_scatter + y_fission) / sigma_t; + float z_source = (z_scatter + z_fission) / sigma_t; + + float new_source_x = + invM.a * x_source + invM.b * y_source + invM.c * z_source; + float new_source_y = + invM.b * x_source + invM.d * y_source + invM.e * z_source; + float new_source_z = + invM.c * x_source + invM.e * y_source + invM.f * z_source; + source_x_[sr * negroups_ + e_out] = new_source_x; + source_y_[sr * negroups_ + e_out] = new_source_y; + source_z_[sr * negroups_ + e_out] = new_source_z; + } + } + } + + if (settings::run_mode == RunMode::EIGENVALUE) { +#pragma omp parallel for for (int sr = 0; sr < n_source_regions_; sr++) { int material = material_[sr]; - std::array invM = moment_matrix_inversion(mom_matrix_, sr); - + for (int e_out = 0; e_out < negroups_; e_out++) { float sigma_t = data::mg.macro_xs_[material].get_xs( MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); - - float scatter_source = 0.0f; - float x_scatter = 0.0f; - float y_scatter = 0.0f; - float z_scatter = 0.0f; - float x_fission = 0.0f; - float y_fission = 0.0f; - float z_fission = 0.0f; + float fission_source = 0.0f; for (int e_in = 0; e_in < negroups_; e_in++) { float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; - float flux_x = flux_x_old_[sr * negroups_ + e_in]; - float flux_y = flux_y_old_[sr * negroups_ + e_in]; - float flux_z = flux_z_old_[sr * negroups_ + e_in]; - float sigma_s = data::mg.macro_xs_[material].get_xs( - MgxsType::NU_SCATTER, e_in, &e_out, nullptr, nullptr, t, a); float nu_sigma_f = data::mg.macro_xs_[material].get_xs( MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); float chi = data::mg.macro_xs_[material].get_xs( MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); - scatter_source += sigma_s * scalar_flux; - // Calculate scattering source for higher order scattering - x_scatter += sigma_s * flux_x ; - y_scatter += sigma_s * flux_y ; - z_scatter += sigma_s * flux_z; - x_fission += nu_sigma_f * flux_x * chi; - y_fission += nu_sigma_f * flux_y * chi; - z_fission += nu_sigma_f * flux_z * chi; + fission_source += nu_sigma_f * scalar_flux * chi; } - - - // fission_source *= inverse_k_eff; - float new_isotropic_source = (scatter_source) / sigma_t; - source_[sr * negroups_ + e_out] = new_isotropic_source; - - if (simulation::current_batch > 2) { - - x_fission *= inverse_k_eff; - y_fission *= inverse_k_eff; - z_fission *= inverse_k_eff; - - float x_source = (x_scatter + x_fission) / sigma_t; - float y_source = (y_scatter + y_fission) / sigma_t; - float z_source = (z_scatter + z_fission) / sigma_t; - - float new_source_x = invM[0] * x_source + invM[1] * y_source + invM[2] * z_source; - float new_source_y = invM[1] * x_source + invM[3] * y_source + invM[4] * z_source; - float new_source_z = invM[2] * x_source + invM[4] * y_source + invM[5] * z_source; - source_x_[sr * negroups_ + e_out] = new_source_x; - source_y_[sr * negroups_ + e_out] = new_source_y; - source_z_[sr * negroups_ + e_out] = new_source_z; - - } + source_[sr * negroups_ + e_out] += + fission_source * inverse_k_eff / sigma_t; } + } + } else { +// Add external source if in fixed source mode +#pragma omp parallel for + for (int se = 0; se < n_source_elements_; se++) { + source_[se] += external_source_[se]; + } } - if (settings::run_mode == RunMode::EIGENVALUE) { - #pragma omp parallel for - for (int sr = 0; sr < n_source_regions_; sr++) { - int material = material_[sr]; - - for (int e_out = 0; e_out < negroups_; e_out++) { - float sigma_t = data::mg.macro_xs_[material].get_xs( - MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); - float fission_source = 0.0f; - - for (int e_in = 0; e_in < negroups_; e_in++) { - float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; - float nu_sigma_f = data::mg.macro_xs_[material].get_xs( - MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); - float chi = data::mg.macro_xs_[material].get_xs( - MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); - fission_source += nu_sigma_f * scalar_flux * chi; - } - source_[sr * negroups_ + e_out] += - fission_source * inverse_k_eff / sigma_t; - } - } - } - else { - // Add external source if in fixed source mode - #pragma omp parallel for - for (int se = 0; se < n_source_elements_; se++) { - source_[se] += external_source_[se]; - } - } - simulation::time_update_src.stop(); } @@ -213,7 +189,6 @@ void LinearSourceDomain::normalize_scalar_flux_and_volumes( } } - int64_t LinearSourceDomain::add_source_to_scalar_flux() { int64_t n_hits = 0; @@ -232,8 +207,8 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() double volume_tracks = volume_t_[sr]; double invvol = 1.0f / volume_tracks; int material = material_[sr]; - int64_t didx = sr * 3; - int64_t midx = sr * 6; + int64_t didx = sr * 3; + int64_t midx = sr * 6; // Check if this cell was hit this iteration int was_cell_hit = was_hit_[sr]; @@ -251,37 +226,35 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // transport sweep) scalar_flux_new_[idx] /= volume; scalar_flux_new_[idx] += source_[idx]; - flux_x_new_[idx] /= volume ; - flux_y_new_[idx] /= volume ; - flux_z_new_[idx] /= volume ; + flux_x_new_[idx] /= volume; + flux_y_new_[idx] /= volume; + flux_z_new_[idx] /= volume; for (int i = 0; i < 3; i++) { // Update centroids centroid_[didx + i] = centroid_t_[didx + i] * invvol; } - for (int i = 0; i < 6; i++) { // Update spatial moments - mom_matrix_[midx + i] = mom_matrix_t_[midx + i] * invvol; - } + mom_matrix_[sr] = mom_matrix_t_[sr]; + mom_matrix_[sr].scale(invvol); } else if (volume > 0.0) { // 2. If the FSR was not hit this iteration, but has been hit some // previous iteration, then we simply set the new scalar flux to be // equal to the contribution from the flat source alone. scalar_flux_new_[idx] = source_[idx]; - flux_x_new_[idx] /= volume ; - flux_y_new_[idx] /= volume ; - flux_z_new_[idx] /= volume ; + flux_x_new_[idx] /= volume; + flux_y_new_[idx] /= volume; + flux_z_new_[idx] /= volume; for (int i = 0; i < 3; i++) { // Update centroids - centroid_[didx + i] = centroid_t_[didx + i] * invvol; - } - for (int i = 0; i < 6; i++) { // Update spatial moments - mom_matrix_[midx + i] = mom_matrix_t_[midx + i] * invvol; + centroid_[didx + i] = centroid_t_[didx + i] * invvol; } + mom_matrix_[sr] = mom_matrix_t_[sr]; + mom_matrix_[sr].scale(invvol); } else { // If the FSR was not hit this iteration, and it has never been hit in // any iteration (i.e., volume is zero), then we want to set this to 0 // to avoid dividing anything by a zero volume. scalar_flux_new_[idx] = 0.0f; - flux_x_new_[idx] = 0.0f ; - flux_y_new_[idx] = 0.0f ; - flux_z_new_[idx] = 0.0f ; + flux_x_new_[idx] = 0.0f; + flux_y_new_[idx] = 0.0f; + flux_z_new_[idx] = 0.0f; } } } @@ -296,7 +269,8 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // void LinearSourceDomain::random_ray_tally() // { -// // Can we just use the base class method? (Do we need this method at all?) +// // Can we just use the base class method? (Do we need this method at +// all?) // // ... // } @@ -311,7 +285,8 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // void LinearSourceDomain::output_to_vtk() const // { -// // Can we just use the base class method? (Do we need this method at all?) +// // Can we just use the base class method? (Do we need this method at +// all?) // // ... // } @@ -330,5 +305,4 @@ void LinearSourceDomain::flux_swap() flux_z_old_.swap(flux_z_new_); } - } // namespace openmc \ No newline at end of file diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 63aac48766d..bd3be5c0046 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -464,14 +464,15 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // If ray is in the active phase (not in dead zone), make contributions to // source region bookkeeping + SymmetricMatrix mat_score; if (is_active) { double distance2_12 = distance * distance / 12.0; - mat_score_[0] = distance * (rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12); - mat_score_[1] = distance * (rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12); - mat_score_[2] = distance * (rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12); - mat_score_[3] = distance * (rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12); - mat_score_[4] = distance * (rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12); - mat_score_[5] = distance * (rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12); + mat_score.a = distance * (rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12); + mat_score.b = distance * (rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12); + mat_score.c = distance * (rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12); + mat_score.d = distance * (rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12); + mat_score.e = distance * (rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12); + mat_score.f = distance * (rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12); // for (int g = 0; g < negroups_; g++) { // float h1 = exp_f1_[g] - exp_gn_[g]; @@ -502,9 +503,9 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) domain->flux_y_new_[source_element + g] += delta_y_[g]; domain->flux_z_new_[source_element + g] += delta_z_[g]; } - for (int i = 0; i < 6; i++) { - domain->mom_matrix_t_[midx + i] += mat_score_[i]; - } + + domain->mom_matrix_t_[source_region] += mat_score; + for (int i = 0; i < 3; i++) { domain->centroid_t_[didx + i] += midpoint[i] * distance ; } diff --git a/src/random_ray/symmetric_matrix.cpp b/src/random_ray/symmetric_matrix.cpp new file mode 100644 index 00000000000..f0b149fd2e2 --- /dev/null +++ b/src/random_ray/symmetric_matrix.cpp @@ -0,0 +1,59 @@ +#include "openmc/random_ray/symmetric_matrix.h" + +#include + +namespace openmc { + +//============================================================================== +// UpperTriangular implementation +//============================================================================== + +// Inters the following 3x3 smmetric matrix labeled as: +// +// | a b c | +// | b d e | +// | c e f | +// +// We first check the determinant to ensure it is non-zero +// before proceeding with the inversion. If the determinant +// is zero, we return a matrix of zeros. +// Inversion is calculated by computing the adjoint matrix +// first, and then the inverse can be computed as: +// A^-1 = 1/det(A) * adj(A) +SymmetricMatrix SymmetricMatrix::inverse() const +{ + SymmetricMatrix inv; + + // Check if the determinant is zero + double det = determinant(); + if (det < std::abs(1.0e-10)) { + inv.set_to_zero(); + return inv; + } + + // Compute the adjoint matrix + inv.a = d*f - e*e; + inv.b = c*e - b*f; + inv.c = b*e - c*d; + inv.d = a*f - c*c; + inv.e = b*c - a*e; + inv.f = a*d - b*b; + + // A^-1 = 1/det(A) * adj(A) + inv.scale(1.0 / det); + + return inv; +} + +// Computes the determinant of a 3x3 symmetric +// matrix, with elements labeled as follows: +// +// | a b c | +// | b d e | +// | c e f | +double SymmetricMatrix::determinant() const +{ + return a * (d*f - e*e) - b * (b*f - c*e) + c * (b*e - c*d); +} + +} // namespace openmc \ No newline at end of file From fdb82b284a49590376a5832fec93ce1d9f0e315b Mon Sep 17 00:00:00 2001 From: John Tramm Date: Thu, 27 Jun 2024 22:46:30 -0500 Subject: [PATCH 21/61] using scale --- src/random_ray/random_ray.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index bd3be5c0046..a71eff834ac 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -464,15 +464,17 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // If ray is in the active phase (not in dead zone), make contributions to // source region bookkeeping - SymmetricMatrix mat_score; if (is_active) { + SymmetricMatrix mat_score; double distance2_12 = distance * distance / 12.0; - mat_score.a = distance * (rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12); - mat_score.b = distance * (rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12); - mat_score.c = distance * (rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12); - mat_score.d = distance * (rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12); - mat_score.e = distance * (rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12); - mat_score.f = distance * (rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12); + mat_score.a = rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12; + mat_score.b = rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12; + mat_score.c = rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12; + mat_score.d = rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12; + mat_score.e = rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12; + mat_score.f = rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12; + + mat_score.scale(distance); // for (int g = 0; g < negroups_; g++) { // float h1 = exp_f1_[g] - exp_gn_[g]; @@ -505,7 +507,7 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) } domain->mom_matrix_t_[source_region] += mat_score; - + for (int i = 0; i < 3; i++) { domain->centroid_t_[didx + i] += midpoint[i] * distance ; } From 41a00a84dc0be9b088b1ae206a4eb42f84211de0 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 28 Jun 2024 15:26:28 -0500 Subject: [PATCH 22/61] partial progress --- .../openmc/random_ray/flat_source_domain.h | 4 +- .../openmc/random_ray/linear_source_domain.h | 8 +- include/openmc/random_ray/random_ray.h | 4 +- include/openmc/random_ray/symmetric_matrix.h | 4 + src/random_ray/flat_source_domain.cpp | 20 +++-- src/random_ray/linear_source_domain.cpp | 61 +++++++++++++- src/random_ray/random_ray.cpp | 18 ++-- src/random_ray/symmetric_matrix.cpp | 82 ++++++++++++++----- 8 files changed, 161 insertions(+), 40 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 85fb8b845bc..d7a1f6ea032 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -104,12 +104,14 @@ class FlatSourceDomain { void convert_source_regions_to_tallies(); void reset_tally_volumes(); void random_ray_tally(); - void accumulate_iteration_flux(); + virtual void accumulate_iteration_flux(); void output_to_vtk() const; void all_reduce_replicated_source_regions(); void convert_external_sources(); void count_external_source_regions(); virtual void flux_swap(); + virtual double evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const; + //---------------------------------------------------------------------------- // Public Data members diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 000ca93da56..ab641d9b9bf 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -33,23 +33,29 @@ class LinearSourceDomain : public FlatSourceDomain { void convert_source_regions_to_tallies(); void reset_tally_volumes(); void random_ray_tally(); - void accumulate_iteration_flux(); + void accumulate_iteration_flux() override; void output_to_vtk() const; void all_reduce_replicated_source_regions(); //override void convert_external_sources(); void count_external_source_regions(); void flux_swap() override; + double evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const override; + //---------------------------------------------------------------------------- // Public Data members vector flux_x_new_; vector flux_x_old_; + vector flux_x_t_; + vector source_x_; vector flux_y_new_; + vector flux_y_t_; vector flux_y_old_; vector source_y_; vector flux_z_new_; + vector flux_z_t_; vector flux_z_old_; vector source_z_; vector centroid_; diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index ecb320e6722..52c4367bf8e 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -24,9 +24,9 @@ class RandomRay : public Particle { //---------------------------------------------------------------------------- // Methods void event_advance_ray(); - void attenuate_flux(double distance, bool is_active); + void attenuate_flux(double distance, bool is_active, double distance_to_boundary); void attenuate_flux_flat_source(double distance, bool is_active); - void attenuate_flux_linear_source(double distance, bool is_active); + void attenuate_flux_linear_source(double distance, bool is_active, double distance_to_boundary); void initialize_ray(uint64_t ray_id, FlatSourceDomain* domain); uint64_t transport_history_based_single_ray(); diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h index e128b43831c..c503c417fcd 100644 --- a/include/openmc/random_ray/symmetric_matrix.h +++ b/include/openmc/random_ray/symmetric_matrix.h @@ -1,6 +1,8 @@ #ifndef OPENMC_SYMMETRIC_MATRIX_H #define OPENMC_SYMMETRIC_MATRIX_H +#include + namespace openmc { // The SymmetricMatrix class is a sparese representation a 3x3 symmetric @@ -52,6 +54,8 @@ class SymmetricMatrix { f += rhs.f; return *this; } + + std::array solve(const std::array& y) const; }; } // namespace openmc diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 8e4926956f7..850271a7167 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -657,6 +657,11 @@ void FlatSourceDomain::all_reduce_replicated_source_regions() #endif } +double FlatSourceDomain::evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const +{ + return scalar_flux_final_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); +} + // Outputs all basic material, FSR ID, multigroup flux, and // fission source data to .vtk file that can be directly // loaded and displayed by Paraview. Note that .vtk binary @@ -717,6 +722,7 @@ void FlatSourceDomain::output_to_vtk() const // Relate voxel spatial locations to random ray source regions vector voxel_indices(Nx * Ny * Nz); + vector voxel_positions(Nx * Ny * Nz); #pragma omp parallel for collapse(3) for (int z = 0; z < Nz; z++) { @@ -733,6 +739,7 @@ void FlatSourceDomain::output_to_vtk() const int64_t source_region_idx = source_region_offsets_[i_cell] + p.cell_instance(); voxel_indices[z * Ny * Nx + y * Nx + x] = source_region_idx; + voxel_positions[z * Ny * Nx + y * Nx + x] = sample; } } } @@ -754,10 +761,10 @@ void FlatSourceDomain::output_to_vtk() const for (int g = 0; g < negroups_; g++) { std::fprintf(plot, "SCALARS flux_group_%d float\n", g); std::fprintf(plot, "LOOKUP_TABLE default\n"); - for (int fsr : voxel_indices) { + for (int i = 0; i < Nx * Ny * Nz; i++) { + int64_t fsr = voxel_indices[i]; int64_t source_element = fsr * negroups_ + g; - float flux = scalar_flux_final_[source_element]; - flux /= (settings::n_batches - settings::n_inactive); + float flux = evaluate_flux_at_point(voxel_positions[i], fsr, g); flux = convert_to_big_endian(flux); std::fwrite(&flux, sizeof(float), 1, plot); } @@ -784,13 +791,14 @@ void FlatSourceDomain::output_to_vtk() const // Plot fission source std::fprintf(plot, "SCALARS total_fission_source float\n"); std::fprintf(plot, "LOOKUP_TABLE default\n"); - for (int fsr : voxel_indices) { + for (int i = 0; i < Nx * Ny * Nz; i++) { + int64_t fsr = voxel_indices[i]; + float total_fission = 0.0; int mat = material_[fsr]; for (int g = 0; g < negroups_; g++) { int64_t source_element = fsr * negroups_ + g; - float flux = scalar_flux_final_[source_element]; - flux /= (settings::n_batches - settings::n_inactive); + float flux = evaluate_flux_at_point(voxel_positions[i], fsr, g); float Sigma_f = data::mg.macro_xs_[mat].get_xs( MgxsType::FISSION, g, nullptr, nullptr, nullptr, 0, 0); total_fission += Sigma_f * flux; diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 56f8324b6bd..69c3588144b 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -26,12 +26,18 @@ LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() { flux_x_new_.assign(n_source_elements_, 0.0); flux_x_old_.assign(n_source_elements_, 0.0); + flux_x_t_.assign(n_source_elements_, 0.0); + source_x_.assign(n_source_elements_, 0.0); flux_y_new_.assign(n_source_elements_, 0.0); flux_y_old_.assign(n_source_elements_, 0.0); + flux_y_t_.assign(n_source_elements_, 0.0); + source_y_.assign(n_source_elements_, 0.0); flux_z_new_.assign(n_source_elements_, 0.0); flux_z_old_.assign(n_source_elements_, 0.0); + flux_z_t_.assign(n_source_elements_, 0.0); + source_z_.assign(n_source_elements_, 0.0); centroid_.assign(n_source_regions_ * 3, nan("")); @@ -69,7 +75,7 @@ void LinearSourceDomain::update_neutron_source(double k_eff) for (int sr = 0; sr < n_source_regions_; sr++) { int material = material_[sr]; - SymmetricMatrix invM = mom_matrix_[sr].inverse(); + //SymmetricMatrix invM = mom_matrix_[sr].inverse(); for (int e_out = 0; e_out < negroups_; e_out++) { float sigma_t = data::mg.macro_xs_[material].get_xs( @@ -118,6 +124,9 @@ void LinearSourceDomain::update_neutron_source(double k_eff) float y_source = (y_scatter + y_fission) / sigma_t; float z_source = (z_scatter + z_fission) / sigma_t; + // Using Inverse + + /* float new_source_x = invM.a * x_source + invM.b * y_source + invM.c * z_source; float new_source_y = @@ -127,6 +136,13 @@ void LinearSourceDomain::update_neutron_source(double k_eff) source_x_[sr * negroups_ + e_out] = new_source_x; source_y_[sr * negroups_ + e_out] = new_source_y; source_z_[sr * negroups_ + e_out] = new_source_z; + */ + + std::array source_vec = mom_matrix_[sr].solve({x_source, y_source, z_source}); + source_x_[sr * negroups_ + e_out] = source_vec[0]; + source_y_[sr * negroups_ + e_out] = source_vec[1]; + source_z_[sr * negroups_ + e_out] = source_vec[2]; + } } } @@ -305,4 +321,47 @@ void LinearSourceDomain::flux_swap() flux_z_old_.swap(flux_z_new_); } +void LinearSourceDomain::accumulate_iteration_flux() +{ + // Accumulate scalar flux + FlatSourceDomain::accumulate_iteration_flux(); + + // Accumulate scalar flux moments +#pragma omp parallel for + for (int64_t se = 0; se < n_source_elements_; se++) { + flux_x_t_[se] += flux_x_new_[se]; + flux_y_t_[se] += flux_y_new_[se]; + flux_z_t_[se] += flux_z_new_[se]; + } +} + +double LinearSourceDomain::evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const +{ + float phi_flat = FlatSourceDomain::evaluate_flux_at_point(r, sr, g); + + Position centroid(centroid_[sr * 3], centroid_[sr * 3 + 1], centroid_[sr * 3 + 2]); + Position local_r = r - centroid; + + float phi_x = flux_x_t_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); + float phi_y = flux_y_t_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); + float phi_z = flux_z_t_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); + + // This gets sort of the right order of magnitude, but is not correct + //phi_x *= volume_[sr] * simulation_volume_; + //phi_y *= volume_[sr] * simulation_volume_; + //phi_z *= volume_[sr] * simulation_volume_; + + std::array phi_solved = mom_matrix_[sr].solve({phi_x, phi_y, phi_z}); + + if( sr == 1337 && g == 6) + { + //printf("phi_flat: %.3le phi_x: %.3le phi_y: %.3le phi_z: %.3le total_phi: %.3le x: %.3le y: %.3le z: %.3le\n", + // phi_flat, phi_x, phi_y, phi_z, phi_flat + phi_solved[0] * local_r.x + phi_solved[1] * local_r.y + phi_solved[2] * local_r.z, + // phi_solved[0] * local_r.x, phi_solved[1] * local_r.y, phi_solved[2] * local_r.z); + } + + //return phi_flat + phi_x * local_r.x + phi_y * local_r.y + phi_z * local_r.z; + return phi_flat + phi_solved[0] * local_r.x + phi_solved[1] * local_r.y + phi_solved[2] * local_r.z; +} + } // namespace openmc \ No newline at end of file diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index a71eff834ac..5e2ebdee38a 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -205,6 +205,8 @@ void RandomRay::event_advance_ray() return; } + double distance_to_boundary = distance; + if (is_active_) { // If the ray is in the active length, need to check if it has // reached its maximum termination distance. If so, reduce @@ -216,7 +218,7 @@ void RandomRay::event_advance_ray() } distance_travelled_ += distance; - attenuate_flux(distance, true); + attenuate_flux(distance, true, distance_to_boundary); } else { // If the ray is still in the dead zone, need to check if it // has entered the active phase. If so, split into two segments (one @@ -226,7 +228,7 @@ void RandomRay::event_advance_ray() if (distance_travelled_ + distance >= distance_inactive_) { is_active_ = true; double distance_dead = distance_inactive_ - distance_travelled_; - attenuate_flux(distance_dead, false); + attenuate_flux(distance_dead, false, distance_to_boundary); double distance_alive = distance - distance_dead; @@ -236,11 +238,11 @@ void RandomRay::event_advance_ray() wgt() = 0.0; } - attenuate_flux(distance_alive, true); + attenuate_flux(distance_alive, true, distance_to_boundary); distance_travelled_ = distance_alive; } else { distance_travelled_ += distance; - attenuate_flux(distance, false); + attenuate_flux(distance, false, distance_to_boundary); } } @@ -250,7 +252,7 @@ void RandomRay::event_advance_ray() } } -void RandomRay::attenuate_flux(double distance, bool is_active) +void RandomRay::attenuate_flux(double distance, bool is_active, double distance_to_boundary) { switch (source_shape_) { case RandomRaySourceShape::FLAT: @@ -348,9 +350,8 @@ void RandomRay::attenuate_flux_flat_source(double distance, bool is_active) } } -void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) +void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, double distance_to_boundary) { - LinearSourceDomain* domain = static_cast(domain_); // The number of geometric intersections is counted for reporting purposes n_event()++; @@ -441,7 +442,8 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) float new_delta_y = r0_local[1] * flat_source + u()[1] * h1; delta_y_[g] = new_delta_y; float new_delta_z = r0_local[2] * flat_source + u()[2] * h1; - delta_z_[g] = new_delta_y; + new_delta_z = 0.0f; + delta_z_[g] = new_delta_z; angular_flux_[g] -= new_delta_psi * sigma_t; } // for (int g = 0; g < negroups_; g++) { diff --git a/src/random_ray/symmetric_matrix.cpp b/src/random_ray/symmetric_matrix.cpp index f0b149fd2e2..5913222378b 100644 --- a/src/random_ray/symmetric_matrix.cpp +++ b/src/random_ray/symmetric_matrix.cpp @@ -1,6 +1,7 @@ #include "openmc/random_ray/symmetric_matrix.h" +#include "openmc/error.h" -#include +#include namespace openmc { @@ -13,7 +14,7 @@ namespace openmc { // | a b c | // | b d e | // | c e f | -// +// // We first check the determinant to ensure it is non-zero // before proceeding with the inversion. If the determinant // is zero, we return a matrix of zeros. @@ -22,27 +23,28 @@ namespace openmc { // A^-1 = 1/det(A) * adj(A) SymmetricMatrix SymmetricMatrix::inverse() const { - SymmetricMatrix inv; - - // Check if the determinant is zero - double det = determinant(); - if (det < std::abs(1.0e-10)) { - inv.set_to_zero(); - return inv; - } + SymmetricMatrix inv; - // Compute the adjoint matrix - inv.a = d*f - e*e; - inv.b = c*e - b*f; - inv.c = b*e - c*d; - inv.d = a*f - c*c; - inv.e = b*c - a*e; - inv.f = a*d - b*b; + // Check if the determinant is zero + double det = determinant(); + if (det < std::abs(1.0e-10)) { + inv.set_to_zero(); + fatal_error("Matrix is singular and cannot be inverted."); + return inv; + } - // A^-1 = 1/det(A) * adj(A) - inv.scale(1.0 / det); + // Compute the adjoint matrix + inv.a = d * f - e * e; + inv.b = c * e - b * f; + inv.c = b * e - c * d; + inv.d = a * f - c * c; + inv.e = b * c - a * e; + inv.f = a * d - b * b; - return inv; + // A^-1 = 1/det(A) * adj(A) + inv.scale(1.0 / det); + + return inv; } // Computes the determinant of a 3x3 symmetric @@ -53,7 +55,45 @@ SymmetricMatrix SymmetricMatrix::inverse() const // | c e f | double SymmetricMatrix::determinant() const { - return a * (d*f - e*e) - b * (b*f - c*e) + c * (b*e - c*d); + return a * (d * f - e * e) - b * (b * f - c * e) + c * (b * e - c * d); +} + +std::array SymmetricMatrix::solve(const std::array& y) const +{ +// Check for positive definiteness and calculate Cholesky decomposition + if (a <= 1e-10) { + fatal_error("Matrix is not positive definite (element 'a' non-positive)."); + } + + double L11 = std::sqrt(a); + double L21 = b / L11; // Using matrix element 'b' directly + double L31 = c / L11; + + double tmp = d - L21 * L21; + if (tmp <= 1e-10) { + fatal_error("Matrix is not positive definite at second diagonal element."); + } + double L22 = std::sqrt(tmp); + + double L32 = (e - L21 * L31) / L22; + + tmp = f - L31 * L31 - L32 * L32; + if (tmp <= 1e-10) { + fatal_error("Matrix is not positive definite at third diagonal element."); + } + double L33 = std::sqrt(tmp); + + // Solving Ly = y (forward substitution) + double y1 = y[0] / L11; + double y2 = (y[1] - L21 * y1) / L22; + double y3 = (y[2] - L31 * y1 - L32 * y2) / L33; + + // Solving L^T x = y (backward substitution) + double x3 = y3 / L33; + double x2 = (y2 - L32 * x3) / L22; + double x1 = (y1 - L21 * x2 - L31 * x3) / L11; + + return {x1, x2, x3}; } } // namespace openmc \ No newline at end of file From 7743154c9d5629f46111ddb131c31ba3da1898ae Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 28 Jun 2024 21:19:39 -0500 Subject: [PATCH 23/61] partial progress on refactor --- .../openmc/random_ray/linear_source_domain.h | 21 +- include/openmc/random_ray/symmetric_matrix.h | 25 ++ src/random_ray/linear_source_domain.cpp | 219 ++++-------------- src/random_ray/random_ray.cpp | 2 +- src/random_ray/symmetric_matrix.cpp | 2 +- 5 files changed, 75 insertions(+), 194 deletions(-) diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index ab641d9b9bf..ea48cf8267f 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -45,21 +45,12 @@ class LinearSourceDomain : public FlatSourceDomain { //---------------------------------------------------------------------------- // Public Data members - vector flux_x_new_; - vector flux_x_old_; - vector flux_x_t_; - - vector source_x_; - vector flux_y_new_; - vector flux_y_t_; - vector flux_y_old_; - vector source_y_; - vector flux_z_new_; - vector flux_z_t_; - vector flux_z_old_; - vector source_z_; - vector centroid_; - vector centroid_t_; + vector source_moments_; + vector flux_moments_old_; + vector flux_moments_new_; + vector flux_moments_t_; + vector centroid_; + vector centroid_t_; vector mom_matrix_; vector mom_matrix_t_; diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h index c503c417fcd..5917e576bca 100644 --- a/include/openmc/random_ray/symmetric_matrix.h +++ b/include/openmc/random_ray/symmetric_matrix.h @@ -44,6 +44,18 @@ class SymmetricMatrix { e *= x; f *= x; } + + SymmetricMatrix& operator*= (double x) + { + a *= x; + b *= x; + c *= x; + d *= x; + e *= x; + f *= x; + return *this; + } + SymmetricMatrix& operator+=(const SymmetricMatrix& rhs) { a += rhs.a; @@ -55,7 +67,20 @@ class SymmetricMatrix { return *this; } + Position operator*(const Position& rhs) const + { + return {a * rhs.x + b * rhs.y + c * rhs.z, + b * rhs.x + d * rhs.y + e * rhs.z, + c * rhs.x + e * rhs.y + f * rhs.z}; + } + std::array solve(const std::array& y) const; + Position solve( const Position& y) const + { + std::array y_array = {y.x, y.y, y.z}; + std::array x_array = solve(y_array); + return {x_array[0], x_array[1], x_array[2]}; + } }; } // namespace openmc diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 69c3588144b..3ed9556844e 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -24,38 +24,24 @@ namespace openmc { LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() { - flux_x_new_.assign(n_source_elements_, 0.0); - flux_x_old_.assign(n_source_elements_, 0.0); - flux_x_t_.assign(n_source_elements_, 0.0); - - source_x_.assign(n_source_elements_, 0.0); - flux_y_new_.assign(n_source_elements_, 0.0); - flux_y_old_.assign(n_source_elements_, 0.0); - flux_y_t_.assign(n_source_elements_, 0.0); - - source_y_.assign(n_source_elements_, 0.0); - flux_z_new_.assign(n_source_elements_, 0.0); - flux_z_old_.assign(n_source_elements_, 0.0); - flux_z_t_.assign(n_source_elements_, 0.0); - - source_z_.assign(n_source_elements_, 0.0); - - centroid_.assign(n_source_regions_ * 3, nan("")); - centroid_t_.assign(n_source_regions_ * 3, 0.0); - mom_matrix_.resize(n_source_regions_); - for( auto& m : mom_matrix_ ) - m.set_to_zero(); - mom_matrix_t_.resize(n_source_regions_); - for( auto& m : mom_matrix_t_ ) - m.set_to_zero(); + flux_moments_old_.assign(n_source_elements_, {0.0, 0.0, 0.0}); + flux_moments_new_.assign(n_source_elements_, {0.0, 0.0, 0.0}); + flux_moments_t_.assign(n_source_elements_, {0.0, 0.0, 0.0}); + source_moments_.assign(n_source_elements_, {0.0, 0.0, 0.0}); + + centroid_.assign(n_source_regions_, {nan(""), nan(""), nan("")}); + centroid_t_.assign(n_source_regions_, {0.0, 0.0, 0.0}); + mom_matrix_.assign(n_source_regions_, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); + mom_matrix_t_.assign(n_source_regions_, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); } void LinearSourceDomain::batch_reset() { FlatSourceDomain::batch_reset(); - parallel_fill(flux_x_new_, 0.0f); - parallel_fill(flux_y_new_, 0.0f); - parallel_fill(flux_z_new_, 0.0f); + #pragma omp parallel for + for (auto& m : flux_moments_new_) { + m = {0.0, 0.0, 0.0}; + } } void LinearSourceDomain::update_neutron_source(double k_eff) @@ -75,101 +61,42 @@ void LinearSourceDomain::update_neutron_source(double k_eff) for (int sr = 0; sr < n_source_regions_; sr++) { int material = material_[sr]; - //SymmetricMatrix invM = mom_matrix_[sr].inverse(); + SymmetricMatrix invM = mom_matrix_[sr].inverse(); for (int e_out = 0; e_out < negroups_; e_out++) { float sigma_t = data::mg.macro_xs_[material].get_xs( MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); - float scatter_source = 0.0f; - float x_scatter = 0.0f; - float y_scatter = 0.0f; - float z_scatter = 0.0f; - float x_fission = 0.0f; - float y_fission = 0.0f; - float z_fission = 0.0f; + float scatter_flat= 0.0f; + float fission_flat = 0.0f; + Position scatter_linear = {0.0, 0.0, 0.0}; + Position fission_linear = {0.0, 0.0, 0.0}; for (int e_in = 0; e_in < negroups_; e_in++) { - float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; - float flux_x = flux_x_old_[sr * negroups_ + e_in]; - float flux_y = flux_y_old_[sr * negroups_ + e_in]; - float flux_z = flux_z_old_[sr * negroups_ + e_in]; + float flux_flat = scalar_flux_old_[sr * negroups_ + e_in]; + Position flux_linear = flux_moments_old_[sr * negroups_ + e_in]; float sigma_s = data::mg.macro_xs_[material].get_xs( MgxsType::NU_SCATTER, e_in, &e_out, nullptr, nullptr, t, a); float nu_sigma_f = data::mg.macro_xs_[material].get_xs( MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); float chi = data::mg.macro_xs_[material].get_xs( MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); - scatter_source += sigma_s * scalar_flux; + scatter_flat += sigma_s * flux_flat; + fission_flat += nu_sigma_f * flux_flat * chi; // Calculate scattering source for higher order scattering - x_scatter += sigma_s * flux_x; - y_scatter += sigma_s * flux_y; - z_scatter += sigma_s * flux_z; - x_fission += nu_sigma_f * flux_x * chi; - y_fission += nu_sigma_f * flux_y * chi; - z_fission += nu_sigma_f * flux_z * chi; + scatter_linear += sigma_s * flux_flat; + fission_linear += nu_sigma_f * flux_linear * chi; } - // fission_source *= inverse_k_eff; - float new_isotropic_source = (scatter_source) / sigma_t; - source_[sr * negroups_ + e_out] = new_isotropic_source; + source_[sr * negroups_ + e_out] = (scatter_flat + fission_flat * inverse_k_eff) / sigma_t; if (simulation::current_batch > 2) { - - x_fission *= inverse_k_eff; - y_fission *= inverse_k_eff; - z_fission *= inverse_k_eff; - - float x_source = (x_scatter + x_fission) / sigma_t; - float y_source = (y_scatter + y_fission) / sigma_t; - float z_source = (z_scatter + z_fission) / sigma_t; - - // Using Inverse - - /* - float new_source_x = - invM.a * x_source + invM.b * y_source + invM.c * z_source; - float new_source_y = - invM.b * x_source + invM.d * y_source + invM.e * z_source; - float new_source_z = - invM.c * x_source + invM.e * y_source + invM.f * z_source; - source_x_[sr * negroups_ + e_out] = new_source_x; - source_y_[sr * negroups_ + e_out] = new_source_y; - source_z_[sr * negroups_ + e_out] = new_source_z; - */ - - std::array source_vec = mom_matrix_[sr].solve({x_source, y_source, z_source}); - source_x_[sr * negroups_ + e_out] = source_vec[0]; - source_y_[sr * negroups_ + e_out] = source_vec[1]; - source_z_[sr * negroups_ + e_out] = source_vec[2]; - + source_moments_[sr * negroups_ + e_out] = invM * ((scatter_linear + fission_linear * inverse_k_eff) / sigma_t); } } } - if (settings::run_mode == RunMode::EIGENVALUE) { -#pragma omp parallel for - for (int sr = 0; sr < n_source_regions_; sr++) { - int material = material_[sr]; - - for (int e_out = 0; e_out < negroups_; e_out++) { - float sigma_t = data::mg.macro_xs_[material].get_xs( - MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); - float fission_source = 0.0f; - - for (int e_in = 0; e_in < negroups_; e_in++) { - float scalar_flux = scalar_flux_old_[sr * negroups_ + e_in]; - float nu_sigma_f = data::mg.macro_xs_[material].get_xs( - MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); - float chi = data::mg.macro_xs_[material].get_xs( - MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); - fission_source += nu_sigma_f * scalar_flux * chi; - } - source_[sr * negroups_ + e_out] += - fission_source * inverse_k_eff / sigma_t; - } - } - } else { + if (settings::run_mode == RunMode::FIXED_SOURCE) { // Add external source if in fixed source mode #pragma omp parallel for for (int se = 0; se < n_source_elements_; se++) { @@ -191,9 +118,7 @@ void LinearSourceDomain::normalize_scalar_flux_and_volumes( #pragma omp parallel for for (int64_t e = 0; e < scalar_flux_new_.size(); e++) { scalar_flux_new_[e] *= normalization_factor; - flux_x_new_[e] *= normalization_factor; - flux_y_new_[e] *= normalization_factor; - flux_z_new_[e] *= normalization_factor; + flux_moments_new_[e] *= normalization_factor; } // Accumulate cell-wise ray length tallies collected this iteration, then @@ -230,6 +155,9 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() int was_cell_hit = was_hit_[sr]; if (was_cell_hit) { n_hits++; + centroid_[sr] *= invvol; + mom_matrix_[sr] = mom_matrix_t_[sr]; + mom_matrix_[sr] *= invvol; } for (int g = 0; g < negroups_; g++) { @@ -242,35 +170,19 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // transport sweep) scalar_flux_new_[idx] /= volume; scalar_flux_new_[idx] += source_[idx]; - flux_x_new_[idx] /= volume; - flux_y_new_[idx] /= volume; - flux_z_new_[idx] /= volume; - for (int i = 0; i < 3; i++) { // Update centroids - centroid_[didx + i] = centroid_t_[didx + i] * invvol; - } - mom_matrix_[sr] = mom_matrix_t_[sr]; - mom_matrix_[sr].scale(invvol); + flux_moments_new_[idx] *= (1.0/volume); } else if (volume > 0.0) { // 2. If the FSR was not hit this iteration, but has been hit some // previous iteration, then we simply set the new scalar flux to be // equal to the contribution from the flat source alone. scalar_flux_new_[idx] = source_[idx]; - flux_x_new_[idx] /= volume; - flux_y_new_[idx] /= volume; - flux_z_new_[idx] /= volume; - for (int i = 0; i < 3; i++) { // Update centroids - centroid_[didx + i] = centroid_t_[didx + i] * invvol; - } - mom_matrix_[sr] = mom_matrix_t_[sr]; - mom_matrix_[sr].scale(invvol); + flux_moments_new_[idx] *= (1.0/volume); } else { // If the FSR was not hit this iteration, and it has never been hit in // any iteration (i.e., volume is zero), then we want to set this to 0 // to avoid dividing anything by a zero volume. scalar_flux_new_[idx] = 0.0f; - flux_x_new_[idx] = 0.0f; - flux_y_new_[idx] = 0.0f; - flux_z_new_[idx] = 0.0f; + flux_moments_new_[idx] *= 0.0f; } } } @@ -278,49 +190,13 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() return n_hits; } -// double LinearSourceDomain::compute_k_eff(double k_eff_old) const -// { -// FlatSourceDomain::compute_k_eff(k_eff_old); -// } - -// void LinearSourceDomain::random_ray_tally() -// { -// // Can we just use the base class method? (Do we need this method at -// all?) -// // ... -// } - -// void LinearSourceDomain::all_reduce_replicated_source_regions() -// { -// // We will first call the base class method as it needs to reduce these -// // variables as well -// FlatSourceDomain::all_reduce_replicated_source_regions(); -// // Then we add in the stuff specific to the linear source class -// // ... -// } - -// void LinearSourceDomain::output_to_vtk() const -// { -// // Can we just use the base class method? (Do we need this method at -// all?) -// // ... -// } - -// void LinearSourceDomain::apply_external_source_to_source_region( -// Discrete* discrete, double strength_factor, int64_t source_region) -// { -// Can we just use the base class method? (Do we need this method at all?) -// ... -// } - void LinearSourceDomain::flux_swap() { FlatSourceDomain::flux_swap(); - flux_x_old_.swap(flux_x_new_); - flux_y_old_.swap(flux_y_new_); - flux_z_old_.swap(flux_z_new_); + flux_moments_old_.swap(flux_moments_new_); } + void LinearSourceDomain::accumulate_iteration_flux() { // Accumulate scalar flux @@ -329,9 +205,7 @@ void LinearSourceDomain::accumulate_iteration_flux() // Accumulate scalar flux moments #pragma omp parallel for for (int64_t se = 0; se < n_source_elements_; se++) { - flux_x_t_[se] += flux_x_new_[se]; - flux_y_t_[se] += flux_y_new_[se]; - flux_z_t_[se] += flux_z_new_[se]; + flux_moments_t_[se] += flux_moments_new_[se]; } } @@ -339,19 +213,10 @@ double LinearSourceDomain::evaluate_flux_at_point(const Position r, const int64_ { float phi_flat = FlatSourceDomain::evaluate_flux_at_point(r, sr, g); - Position centroid(centroid_[sr * 3], centroid_[sr * 3 + 1], centroid_[sr * 3 + 2]); - Position local_r = r - centroid; - - float phi_x = flux_x_t_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); - float phi_y = flux_y_t_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); - float phi_z = flux_z_t_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); - - // This gets sort of the right order of magnitude, but is not correct - //phi_x *= volume_[sr] * simulation_volume_; - //phi_y *= volume_[sr] * simulation_volume_; - //phi_z *= volume_[sr] * simulation_volume_; - - std::array phi_solved = mom_matrix_[sr].solve({phi_x, phi_y, phi_z}); + Position local_r = r - centroid_[sr]; + Position phi_linear = flux_moments_t_[sr * negroups_ + g]; + phi_linear *= 1.0 / (settings::n_batches - settings::n_inactive); + Position phi_solved = mom_matrix_[sr].solve(phi_linear); if( sr == 1337 && g == 6) { @@ -361,7 +226,7 @@ double LinearSourceDomain::evaluate_flux_at_point(const Position r, const int64_ } //return phi_flat + phi_x * local_r.x + phi_y * local_r.y + phi_z * local_r.z; - return phi_flat + phi_solved[0] * local_r.x + phi_solved[1] * local_r.y + phi_solved[2] * local_r.z; + return phi_flat + phi_solved.dot(local_r); } } // namespace openmc \ No newline at end of file diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 5e2ebdee38a..3101a47aec3 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -259,7 +259,7 @@ void RandomRay::attenuate_flux(double distance, bool is_active, double distance_ attenuate_flux_flat_source(distance, is_active); break; case RandomRaySourceShape::LINEAR: - attenuate_flux_linear_source(distance, is_active); + attenuate_flux_linear_source(distance, is_active, distance_to_boundary); break; default: fatal_error("Unknown source shape for random ray transport."); diff --git a/src/random_ray/symmetric_matrix.cpp b/src/random_ray/symmetric_matrix.cpp index 5913222378b..657268cb8c0 100644 --- a/src/random_ray/symmetric_matrix.cpp +++ b/src/random_ray/symmetric_matrix.cpp @@ -29,7 +29,7 @@ SymmetricMatrix SymmetricMatrix::inverse() const double det = determinant(); if (det < std::abs(1.0e-10)) { inv.set_to_zero(); - fatal_error("Matrix is singular and cannot be inverted."); + //fatal_error("Matrix is singular and cannot be inverted."); return inv; } From cdd20fafaa6d33b5de0a51ffb24c0bc0f1111473 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 28 Jun 2024 23:43:28 -0500 Subject: [PATCH 24/61] finished refactor to Position --- include/openmc/random_ray/random_ray.h | 5 +- include/openmc/random_ray/symmetric_matrix.h | 2 + src/random_ray/random_ray.cpp | 101 +++---------------- 3 files changed, 17 insertions(+), 91 deletions(-) diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 52c4367bf8e..5be9654c6a4 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -46,10 +46,7 @@ class RandomRay : public Particle { //---------------------------------------------------------------------------- // Private data members vector delta_psi_; - vector delta_x_; - vector delta_y_; - vector delta_z_; - vector mat_score_; + vector delta_moments_; int negroups_; FlatSourceDomain* domain_ {nullptr}; // pointer to domain that has flat source diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h index 5917e576bca..397bffeed71 100644 --- a/include/openmc/random_ray/symmetric_matrix.h +++ b/include/openmc/random_ray/symmetric_matrix.h @@ -3,6 +3,8 @@ #include +#include "openmc/position.h" + namespace openmc { // The SymmetricMatrix class is a sparese representation a 3x3 symmetric diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 3101a47aec3..64eb5491ed5 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -161,16 +161,7 @@ RandomRay::RandomRay() : angular_flux_(data::mg.num_energy_groups_), delta_psi_(data::mg.num_energy_groups_), negroups_(data::mg.num_energy_groups_), - delta_x_(data::mg.num_energy_groups_), - delta_y_(data::mg.num_energy_groups_), - delta_z_(data::mg.num_energy_groups_), - mat_score_(6) - // prev_angular_flux_(data::mg.num_energy_groups_), - // flat_source_(data::mg.num_energy_groups_), - // dir_source_(data::mg.num_energy_groups_), - // exp_gn_(data::mg.num_energy_groups_), - // exp_f1_(data::mg.num_energy_groups_), - // tau_(data::mg.num_energy_groups_), + delta_moments_(data::mg.num_energy_groups_) {} RandomRay::RandomRay(uint64_t ray_id, FlatSourceDomain* domain) : RandomRay() @@ -375,10 +366,8 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do // angle data. const int t = 0; const int a = 0; - - Position centroid_pos(domain->centroid_[didx + 0], - domain->centroid_[didx + 1], - domain->centroid_[didx + 2]); + + Position& centroid_pos = domain->centroid_[source_region]; Position midpoint = r() + u() * (distance / 2.0); Position rm_local; Position r0_local; @@ -389,33 +378,15 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do } else{ r0_local = -u() * 0.5 * distance; } - // linear source terms - // for (int g = 0; g < negroups_; g++) { - // flat_source_[g] = rm_local[0] * domain->source_x_[source_element + g]; - // flat_source_[g] = flat_source_[g] + rm_local[1] * domain->source_y_[source_element + g]; - // flat_source_[g] = flat_source_[g] + rm_local[2] * domain->source_z_[source_element + g]; - // flat_source_[g] = flat_source_[g] + domain->source_[source_element + g]; - // dir_source_[g] = u()[0] * domain->source_x_[source_element + g]; - // dir_source_[g] = dir_source_[g] + u()[1] * domain->source_y_[source_element + g]; //u()[1] - // dir_source_[g] = dir_source_[g] + u()[2] * domain->source_z_[source_element + g]; - - // prev_angular_flux_[g] = angular_flux_[g]; - // } - -//everything in one loop, wastes LS comp calculation that might not be needed (dead length) -//less arrays to store + // MOC incoming flux attenuation + source contribution/attenuation equation for (int g = 0; g < negroups_; g++) { float sigma_t = data::mg.macro_xs_[material].get_xs( MgxsType::TOTAL, g, NULL, NULL, NULL, t, a); float tau = sigma_t * distance; - float flat_source = rm_local[0] * domain->source_x_[source_element + g] + - rm_local[1] * domain->source_y_[source_element + g] + rm_local[2] * - domain->source_z_[source_element + g] + domain_->source_[source_element + g]; - float dir_source = u()[0] * domain->source_x_[source_element + g] + - u()[1] * domain->source_y_[source_element + g] + - u()[2] * domain->source_z_[source_element + g]; + float flat_source = domain_->source_[source_element + g] + rm_local.dot(domain->source_moments_[source_element + g]); + float dir_source = u().dot(domain->source_moments_[source_element + g]); if (tau < 1E-8f) { tau = 0.0f; @@ -435,34 +406,13 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do g2 = g2 * dir_source * distance * distance * 0.5f; h1 = h1 * angular_flux_[g] * distance; h1 = (g1 + g2 + h1) * distance; - float new_flat_source = flat_source * distance + new_delta_psi; - flat_source = new_flat_source; - float new_delta_x = r0_local[0] * flat_source + u()[0] * h1; - delta_x_[g] = new_delta_x; - float new_delta_y = r0_local[1] * flat_source + u()[1] * h1; - delta_y_[g] = new_delta_y; - float new_delta_z = r0_local[2] * flat_source + u()[2] * h1; - new_delta_z = 0.0f; - delta_z_[g] = new_delta_z; + flat_source = flat_source * distance + new_delta_psi; + delta_moments_[g] = r0_local * flat_source + u() * h1; + + delta_moments_[g].z = 0.0f; + angular_flux_[g] -= new_delta_psi * sigma_t; } - // for (int g = 0; g < negroups_; g++) { - // float sigma_t = data::mg.macro_xs_[material].get_xs( - // MgxsType::TOTAL, g, NULL, NULL, NULL, t, a); - // float tau = sigma_t * distance; - // if (tau < 1E-8f) { - // tau = 0.0f; - // } - // tau_[g] = tau; - // exp_gn_[g] = exponentialG(tau); - // exp_f1_[g] = 1.0f - tau * exp_gn_[g]; - // float f2 = (2.0f * exp_gn_[g] - exp_f1_[g]) * distance * distance; - // float new_delta_psi = - // (angular_flux_[g] - flat_source_[g]) * exp_f1_[g] * distance - // - 0.5 * dir_source_[g] * f2; - // delta_psi_[g] = new_delta_psi; - // angular_flux_[g] -= new_delta_psi * sigma_t; - // } // If ray is in the active phase (not in dead zone), make contributions to // source region bookkeeping @@ -478,41 +428,18 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do mat_score.scale(distance); - // for (int g = 0; g < negroups_; g++) { - // float h1 = exp_f1_[g] - exp_gn_[g]; - // float g1 = 0.5f - h1; - // float g2 = exponentialG2(tau_[g]); - // g1 = g1 * flat_source_[g] * distance; - // g2 = g2 * dir_source_[g] * distance * distance * 0.5f; - // float new_h1 = h1 * prev_angular_flux_[g] * distance; - // h1 = new_h1; - // h1 = (g1 + g2 + h1) * distance; - // float new_flat_source = flat_source_[g] * distance + delta_psi_[g]; - // flat_source_[g] = new_flat_source; - // float new_delta_x = r0_local[0] * flat_source_[g] + u()[0] * h1; - // delta_x_[g] = new_delta_x; - // float new_delta_y = r0_local[1] * flat_source_[g] + u()[1] * h1; - // delta_y_[g] = new_delta_y; - // float new_delta_z = r0_local[2] * flat_source_[g] + u()[2] * h1; - // delta_z_[g] = new_delta_y; - // } - // Aquire lock for source region domain_->lock_[source_region].lock(); + // Accumulate delta psi into new estimate of source region flux for // this iteration for (int g = 0; g < negroups_; g++) { domain_->scalar_flux_new_[source_element + g] += delta_psi_[g]; - domain->flux_x_new_[source_element + g] += delta_x_[g]; - domain->flux_y_new_[source_element + g] += delta_y_[g]; - domain->flux_z_new_[source_element + g] += delta_z_[g]; + domain->flux_moments_new_[source_element + g] += delta_moments_[g]; } domain->mom_matrix_t_[source_region] += mat_score; - - for (int i = 0; i < 3; i++) { - domain->centroid_t_[didx + i] += midpoint[i] * distance ; - } + domain->centroid_t_[source_region] += midpoint * distance; // If the source region hasn't been hit yet this iteration, // indicate that it now has From cf1e272dfbeb73a3683c28d82ed37e40b72d0048 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Sat, 29 Jun 2024 14:51:17 -0500 Subject: [PATCH 25/61] fixed bug with flat vs linear scatter source update --- src/random_ray/linear_source_domain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 3ed9556844e..2bdafb681b4 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -84,7 +84,7 @@ void LinearSourceDomain::update_neutron_source(double k_eff) scatter_flat += sigma_s * flux_flat; fission_flat += nu_sigma_f * flux_flat * chi; // Calculate scattering source for higher order scattering - scatter_linear += sigma_s * flux_flat; + scatter_linear += sigma_s * flux_linear; fission_linear += nu_sigma_f * flux_linear * chi; } From 96b678ee73c507f5ae2cd6d9f6e3b578965639d7 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Sat, 29 Jun 2024 15:23:19 -0500 Subject: [PATCH 26/61] fixed bug with flat vs linear scatter source update --- src/random_ray/random_ray.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 64eb5491ed5..6eeb6c035af 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -419,12 +419,12 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do if (is_active) { SymmetricMatrix mat_score; double distance2_12 = distance * distance / 12.0; - mat_score.a = rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12; - mat_score.b = rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12; - mat_score.c = rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12; - mat_score.d = rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12; - mat_score.e = rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12; - mat_score.f = rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12; + mat_score.a = rm_local[0] * rm_local[0] * u()[0] * u()[0] * distance2_12; + mat_score.b = rm_local[0] * rm_local[1] * u()[0] * u()[1] * distance2_12; + mat_score.c = rm_local[0] * rm_local[2] * u()[0] * u()[2] * distance2_12; + mat_score.d = rm_local[1] * rm_local[1] * u()[1] * u()[1] * distance2_12; + mat_score.e = rm_local[1] * rm_local[2] * u()[1] * u()[2] * distance2_12; + mat_score.f = rm_local[2] * rm_local[2] * u()[2] * u()[2] * distance2_12; mat_score.scale(distance); From 03448539edd31e9edac5a277184924c061b53720 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Sat, 29 Jun 2024 15:28:45 -0500 Subject: [PATCH 27/61] progress on refactor --- src/random_ray/random_ray.cpp | 12 ++++++------ src/random_ray/symmetric_matrix.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 6eeb6c035af..64eb5491ed5 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -419,12 +419,12 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do if (is_active) { SymmetricMatrix mat_score; double distance2_12 = distance * distance / 12.0; - mat_score.a = rm_local[0] * rm_local[0] * u()[0] * u()[0] * distance2_12; - mat_score.b = rm_local[0] * rm_local[1] * u()[0] * u()[1] * distance2_12; - mat_score.c = rm_local[0] * rm_local[2] * u()[0] * u()[2] * distance2_12; - mat_score.d = rm_local[1] * rm_local[1] * u()[1] * u()[1] * distance2_12; - mat_score.e = rm_local[1] * rm_local[2] * u()[1] * u()[2] * distance2_12; - mat_score.f = rm_local[2] * rm_local[2] * u()[2] * u()[2] * distance2_12; + mat_score.a = rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12; + mat_score.b = rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12; + mat_score.c = rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12; + mat_score.d = rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12; + mat_score.e = rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12; + mat_score.f = rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12; mat_score.scale(distance); diff --git a/src/random_ray/symmetric_matrix.cpp b/src/random_ray/symmetric_matrix.cpp index 657268cb8c0..dd8c0559ab4 100644 --- a/src/random_ray/symmetric_matrix.cpp +++ b/src/random_ray/symmetric_matrix.cpp @@ -96,4 +96,31 @@ std::array SymmetricMatrix::solve(const std::array& y) con return {x1, x2, x3}; } +void compute_moments_matrix(const Position& m, const Position& u, const double& distance) +{ + constexpr double one_over_twelve = 1.0 / 12.0; + double distance2_12 = distance * distance * one_over_twelve; + mat_score.a = m[0] * m[0] + u[0] * u[0] * distance2_12; + mat_score.b = m[0] * m[1] + u[0] * u[1] * distance2_12; + mat_score.c = m[0] * m[2] + u[0] * u[2] * distance2_12; + mat_score.d = m[1] * m[1] + u[1] * u[1] * distance2_12; + mat_score.e = m[1] * m[2] + u[1] * u[2] * distance2_12; + mat_score.f = m[2] * m[2] + u[2] * u[2] * distance2_12; + + mat_score.scale(distance); + + a = +} +{ + double distance2_12 = distance * distance / 12.0; + mat_score.a = rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12; + mat_score.b = rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12; + mat_score.c = rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12; + mat_score.d = rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12; + mat_score.e = rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12; + mat_score.f = rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12; + + mat_score.scale(distance); +} + } // namespace openmc \ No newline at end of file From dbb460d473dbd08cd469e65b22b0889a5d0f63ef Mon Sep 17 00:00:00 2001 From: John Tramm Date: Sat, 29 Jun 2024 21:17:38 -0500 Subject: [PATCH 28/61] progress on refactor --- include/openmc/random_ray/symmetric_matrix.h | 2 + src/random_ray/random_ray.cpp | 89 +++++++------- src/random_ray/symmetric_matrix.cpp | 117 +++++++++---------- 3 files changed, 106 insertions(+), 102 deletions(-) diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h index 397bffeed71..c8481ac8fa8 100644 --- a/include/openmc/random_ray/symmetric_matrix.h +++ b/include/openmc/random_ray/symmetric_matrix.h @@ -83,6 +83,8 @@ class SymmetricMatrix { std::array x_array = solve(y_array); return {x_array[0], x_array[1], x_array[2]}; } + + void compute_spatial_moments_matrix(const Position& r, const Direction& u, const double& distance); }; } // namespace openmc diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 64eb5491ed5..b4320db3969 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -61,12 +61,14 @@ float cjosey_exponential(float tau) return num / den; } -// Computes y = 1/x-(1-exp(-x))/x**2 using a 5/6th order rational approximation. -// OpenMoC https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 +// Computes y = 1/x-(1-exp(-x))/x**2 using a 5/6th order rational +// approximation. OpenMoC +// https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 float exponentialG(float tau) { - // Numerator coefficients in rational approximation for 1/x - (1 - exp(-x)) / x^2 + // Numerator coefficients in rational approximation for 1/x - (1 - exp(-x)) / + // x^2 constexpr float d0n = 0.5f; constexpr float d1n = 0.176558112351595f; constexpr float d2n = 0.04041584305811143f; @@ -74,7 +76,8 @@ float exponentialG(float tau) constexpr float d4n = 0.0006429894635552992f; constexpr float d5n = 0.00006064409107557148f; - // Denominator coefficients in rational approximation for 1/x - (1 - exp(-x)) / x^2 + // Denominator coefficients in rational approximation for 1/x - (1 - exp(-x)) + // / x^2 constexpr float d0d = 1.0f; constexpr float d1d = 0.6864462055546078f; constexpr float d2d = 0.2263358514260129f; @@ -85,7 +88,7 @@ float exponentialG(float tau) float x = tau; - float num = d5n; + float num = d5n; num = num * x + d4n; num = num * x + d3n; num = num * x + d2n; @@ -100,14 +103,12 @@ float exponentialG(float tau) den = den * x + d1d; den = den * x + d0d; - return num / den; } -// Computes G2 : y = 2/3 - (1 + 2/x) * (1/x + 0.5 - (1 + 1/x) * (1-exp(-x)) / x) -// using a 5/5th order rational approximation, -// FROM: OpenMoC https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 - +// Computes G2 : y = 2/3 - (1 + 2/x) * (1/x + 0.5 - (1 + 1/x) * (1-exp(-x)) / +// x) using a 5/5th order rational approximation, FROM: OpenMoC +// https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 float exponentialG2(float tau) { @@ -126,7 +127,7 @@ float exponentialG2(float tau) constexpr float g4d = 0.006125197988351906f; constexpr float g5d = 0.0010102514456857377f; - float x = tau; + float x = tau; float num = g5n; num = num * x + g4n; @@ -142,8 +143,6 @@ float exponentialG2(float tau) den = den * x + g1d; den = den * x + 1.0f; - - return num / den; } @@ -243,7 +242,8 @@ void RandomRay::event_advance_ray() } } -void RandomRay::attenuate_flux(double distance, bool is_active, double distance_to_boundary) +void RandomRay::attenuate_flux( + double distance, bool is_active, double distance_to_boundary) { switch (source_shape_) { case RandomRaySourceShape::FLAT: @@ -341,7 +341,8 @@ void RandomRay::attenuate_flux_flat_source(double distance, bool is_active) } } -void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, double distance_to_boundary) +void RandomRay::attenuate_flux_linear_source( + double distance, bool is_active, double distance_to_boundary) { LinearSourceDomain* domain = static_cast(domain_); // The number of geometric intersections is counted for reporting purposes @@ -356,8 +357,8 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do // The source element is the energy-specific region index int64_t source_element = source_region * negroups_; - int64_t midx = source_region * 6 ; - int64_t didx = source_region * 3 ; + int64_t midx = source_region * 6; + int64_t didx = source_region * 3; int material = this->material(); // Temperature and angle indices, if using multiple temperature @@ -365,38 +366,38 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do // TODO: Currently assumes we are only using single temp/single // angle data. const int t = 0; - const int a = 0; - - Position& centroid_pos = domain->centroid_[source_region]; + const int a = 0; + + Position& centroid_pos = domain->centroid_[source_region]; Position midpoint = r() + u() * (distance / 2.0); Position rm_local; Position r0_local; - //if (simulation::current_batch > 2) { + // if (simulation::current_batch > 2) { if (centroid_pos[0] == centroid_pos[0]) { - rm_local = midpoint - centroid_pos; + rm_local = midpoint - centroid_pos; r0_local = r() - centroid_pos; - } else{ + } else { r0_local = -u() * 0.5 * distance; } - // MOC incoming flux attenuation + source contribution/attenuation equation for (int g = 0; g < negroups_; g++) { float sigma_t = data::mg.macro_xs_[material].get_xs( MgxsType::TOTAL, g, NULL, NULL, NULL, t, a); float tau = sigma_t * distance; - float flat_source = domain_->source_[source_element + g] + rm_local.dot(domain->source_moments_[source_element + g]); + float flat_source = + domain_->source_[source_element + g] + + rm_local.dot(domain->source_moments_[source_element + g]); float dir_source = u().dot(domain->source_moments_[source_element + g]); if (tau < 1E-8f) { tau = 0.0f; } - float gn = exponentialG(tau); + float gn = exponentialG(tau); float f1 = 1.0f - tau * gn; float f2 = (2.0f * gn - f1) * distance * distance; float new_delta_psi = - (angular_flux_[g] - flat_source) * f1 * distance - - 0.5 * dir_source * f2; + (angular_flux_[g] - flat_source) * f1 * distance - 0.5 * dir_source * f2; delta_psi_[g] = new_delta_psi; // prev_angular_flux_[g] = angular_flux_[g]; float h1 = f1 - gn; @@ -410,22 +411,19 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do delta_moments_[g] = r0_local * flat_source + u() * h1; delta_moments_[g].z = 0.0f; - + angular_flux_[g] -= new_delta_psi * sigma_t; } // If ray is in the active phase (not in dead zone), make contributions to // source region bookkeeping if (is_active) { + // Compute an estimate of the spatial moments matric for the source + // region based on this ray's crossing. SymmetricMatrix mat_score; - double distance2_12 = distance * distance / 12.0; - mat_score.a = rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12; - mat_score.b = rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12; - mat_score.c = rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12; - mat_score.d = rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12; - mat_score.e = rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12; - mat_score.f = rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12; + mat_score.compute_spatial_moments_matrix(rm_local, u(), distance); + // Scale the moment matrix by the length of the ray segment mat_score.scale(distance); // Aquire lock for source region @@ -435,11 +433,22 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do // this iteration for (int g = 0; g < negroups_; g++) { domain_->scalar_flux_new_[source_element + g] += delta_psi_[g]; - domain->flux_moments_new_[source_element + g] += delta_moments_[g]; + domain->flux_moments_new_[source_element + g] += delta_moments_[g]; } - domain->mom_matrix_t_[source_region] += mat_score; + // Accumulate the volume (ray segment distance), + // centroid, and spatial momement estimates into the running totals + // for the iteration for this source region. These three parameters + // form the 0th order (volume), 1st order (centroid), and 2nd order + // (spatial moments matrix) spatial moments of the source region. + // The centroid and spatial momements estimates are scaled + // by the ray segment length. + domain_->volume_[source_region] += distance; domain->centroid_t_[source_region] += midpoint * distance; + domain->mom_matrix_t_[source_region] += mat_score; + + // Accomulate volume (ray distance) into this iteration's estimate + // of the source region's volume // If the source region hasn't been hit yet this iteration, // indicate that it now has @@ -447,10 +456,6 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active, do domain_->was_hit_[source_region] = 1; } - // Accomulate volume (ray distance) into this iteration's estimate - // of the source region's volume - domain_->volume_[source_region] += distance; - // Tally valid position inside the source region (e.g., midpoint of // the ray) if not done already if (!domain_->position_recorded_[source_region]) { diff --git a/src/random_ray/symmetric_matrix.cpp b/src/random_ray/symmetric_matrix.cpp index dd8c0559ab4..79d15190a17 100644 --- a/src/random_ray/symmetric_matrix.cpp +++ b/src/random_ray/symmetric_matrix.cpp @@ -29,7 +29,7 @@ SymmetricMatrix SymmetricMatrix::inverse() const double det = determinant(); if (det < std::abs(1.0e-10)) { inv.set_to_zero(); - //fatal_error("Matrix is singular and cannot be inverted."); + // fatal_error("Matrix is singular and cannot be inverted."); return inv; } @@ -58,69 +58,66 @@ double SymmetricMatrix::determinant() const return a * (d * f - e * e) - b * (b * f - c * e) + c * (b * e - c * d); } -std::array SymmetricMatrix::solve(const std::array& y) const +std::array SymmetricMatrix::solve( + const std::array& y) const { -// Check for positive definiteness and calculate Cholesky decomposition - if (a <= 1e-10) { - fatal_error("Matrix is not positive definite (element 'a' non-positive)."); - } - - double L11 = std::sqrt(a); - double L21 = b / L11; // Using matrix element 'b' directly - double L31 = c / L11; - - double tmp = d - L21 * L21; - if (tmp <= 1e-10) { - fatal_error("Matrix is not positive definite at second diagonal element."); - } - double L22 = std::sqrt(tmp); - - double L32 = (e - L21 * L31) / L22; - - tmp = f - L31 * L31 - L32 * L32; - if (tmp <= 1e-10) { - fatal_error("Matrix is not positive definite at third diagonal element."); - } - double L33 = std::sqrt(tmp); - - // Solving Ly = y (forward substitution) - double y1 = y[0] / L11; - double y2 = (y[1] - L21 * y1) / L22; - double y3 = (y[2] - L31 * y1 - L32 * y2) / L33; - - // Solving L^T x = y (backward substitution) - double x3 = y3 / L33; - double x2 = (y2 - L32 * x3) / L22; - double x1 = (y1 - L21 * x2 - L31 * x3) / L11; - - return {x1, x2, x3}; -} + // Check for positive definiteness and calculate Cholesky decomposition + if (a <= 1e-10) { + fatal_error("Matrix is not positive definite (element 'a' non-positive)."); + } -void compute_moments_matrix(const Position& m, const Position& u, const double& distance) -{ - constexpr double one_over_twelve = 1.0 / 12.0; - double distance2_12 = distance * distance * one_over_twelve; - mat_score.a = m[0] * m[0] + u[0] * u[0] * distance2_12; - mat_score.b = m[0] * m[1] + u[0] * u[1] * distance2_12; - mat_score.c = m[0] * m[2] + u[0] * u[2] * distance2_12; - mat_score.d = m[1] * m[1] + u[1] * u[1] * distance2_12; - mat_score.e = m[1] * m[2] + u[1] * u[2] * distance2_12; - mat_score.f = m[2] * m[2] + u[2] * u[2] * distance2_12; - - mat_score.scale(distance); - - a = + double L11 = std::sqrt(a); + double L21 = b / L11; // Using matrix element 'b' directly + double L31 = c / L11; + + double tmp = d - L21 * L21; + if (tmp <= 1e-10) { + fatal_error("Matrix is not positive definite at second diagonal element."); + } + double L22 = std::sqrt(tmp); + + double L32 = (e - L21 * L31) / L22; + + tmp = f - L31 * L31 - L32 * L32; + if (tmp <= 1e-10) { + fatal_error("Matrix is not positive definite at third diagonal element."); + } + double L33 = std::sqrt(tmp); + + // Solving Ly = y (forward substitution) + double y1 = y[0] / L11; + double y2 = (y[1] - L21 * y1) / L22; + double y3 = (y[2] - L31 * y1 - L32 * y2) / L33; + + // Solving L^T x = y (backward substitution) + double x3 = y3 / L33; + double x2 = (y2 - L32 * x3) / L22; + double x1 = (y1 - L21 * x2 - L31 * x3) / L11; + + return {x1, x2, x3}; } + +// Compute a 3x3 spatial moment matrix based on a single ray crossing. +// The matrix is symmetric, and is defined as: +// +// | a b c | +// | b d e | +// | c e f | +// +// The estimate of the obect's spatial moments matrix is computed based on the +// midpoint of the ray's crossing, the direction of the ray, and the distance +// the ray traveled through the 3D object. +void SymmetricMatrix::compute_spatial_moments_matrix( + const Position& r, const Direction& u, const double& distance) { - double distance2_12 = distance * distance / 12.0; - mat_score.a = rm_local[0] * rm_local[0] + u()[0] * u()[0] * distance2_12; - mat_score.b = rm_local[0] * rm_local[1] + u()[0] * u()[1] * distance2_12; - mat_score.c = rm_local[0] * rm_local[2] + u()[0] * u()[2] * distance2_12; - mat_score.d = rm_local[1] * rm_local[1] + u()[1] * u()[1] * distance2_12; - mat_score.e = rm_local[1] * rm_local[2] + u()[1] * u()[2] * distance2_12; - mat_score.f = rm_local[2] * rm_local[2] + u()[2] * u()[2] * distance2_12; - - mat_score.scale(distance); + constexpr double one_over_twelve = 1.0 / 12.0; + const double distance2_12 = distance * distance * one_over_twelve; + a = r[0] * r[0] + u[0] * u[0] * distance2_12; + b = r[0] * r[1] + u[0] * u[1] * distance2_12; + c = r[0] * r[2] + u[0] * u[2] * distance2_12; + d = r[1] * r[1] + u[1] * u[1] * distance2_12; + e = r[1] * r[2] + u[1] * u[2] * distance2_12; + f = r[2] * r[2] + u[2] * u[2] * distance2_12; } } // namespace openmc \ No newline at end of file From 2da90ac087434571f37e9aad5c0b2e701427a06d Mon Sep 17 00:00:00 2001 From: John Tramm Date: Sat, 29 Jun 2024 21:31:32 -0500 Subject: [PATCH 29/61] refactoring mostly done --- src/random_ray/linear_source_domain.cpp | 47 +++++++++++++++---------- src/random_ray/random_ray.cpp | 7 ++-- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 2bdafb681b4..028fe6c3f28 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -38,7 +38,7 @@ LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() void LinearSourceDomain::batch_reset() { FlatSourceDomain::batch_reset(); - #pragma omp parallel for +#pragma omp parallel for for (auto& m : flux_moments_new_) { m = {0.0, 0.0, 0.0}; } @@ -67,37 +67,45 @@ void LinearSourceDomain::update_neutron_source(double k_eff) float sigma_t = data::mg.macro_xs_[material].get_xs( MgxsType::TOTAL, e_out, nullptr, nullptr, nullptr, t, a); - float scatter_flat= 0.0f; + float scatter_flat = 0.0f; float fission_flat = 0.0f; Position scatter_linear = {0.0, 0.0, 0.0}; Position fission_linear = {0.0, 0.0, 0.0}; for (int e_in = 0; e_in < negroups_; e_in++) { + // Handles for the flat and linear components of the flux float flux_flat = scalar_flux_old_[sr * negroups_ + e_in]; Position flux_linear = flux_moments_old_[sr * negroups_ + e_in]; + + // Handles for cross sections float sigma_s = data::mg.macro_xs_[material].get_xs( MgxsType::NU_SCATTER, e_in, &e_out, nullptr, nullptr, t, a); float nu_sigma_f = data::mg.macro_xs_[material].get_xs( MgxsType::NU_FISSION, e_in, nullptr, nullptr, nullptr, t, a); float chi = data::mg.macro_xs_[material].get_xs( MgxsType::CHI_PROMPT, e_in, &e_out, nullptr, nullptr, t, a); + + // Compute source terms for flat and linear components of the flux scatter_flat += sigma_s * flux_flat; fission_flat += nu_sigma_f * flux_flat * chi; - // Calculate scattering source for higher order scattering scatter_linear += sigma_s * flux_linear; fission_linear += nu_sigma_f * flux_linear * chi; } - source_[sr * negroups_ + e_out] = (scatter_flat + fission_flat * inverse_k_eff) / sigma_t; + // Compute the flat source term + source_[sr * negroups_ + e_out] = + (scatter_flat + fission_flat * inverse_k_eff) / sigma_t; + // Compute the linear source terms if (simulation::current_batch > 2) { - source_moments_[sr * negroups_ + e_out] = invM * ((scatter_linear + fission_linear * inverse_k_eff) / sigma_t); + source_moments_[sr * negroups_ + e_out] = + invM * ((scatter_linear + fission_linear * inverse_k_eff) / sigma_t); } } } if (settings::run_mode == RunMode::FIXED_SOURCE) { -// Add external source if in fixed source mode +// Add external source to flat source term if in fixed source mode #pragma omp parallel for for (int se = 0; se < n_source_elements_; se++) { source_[se] += external_source_[se]; @@ -146,7 +154,7 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() double volume = volume_[sr]; double volume_tracks = volume_t_[sr]; - double invvol = 1.0f / volume_tracks; + double invvol = 1.0 / volume_tracks; int material = material_[sr]; int64_t didx = sr * 3; int64_t midx = sr * 6; @@ -170,13 +178,13 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // transport sweep) scalar_flux_new_[idx] /= volume; scalar_flux_new_[idx] += source_[idx]; - flux_moments_new_[idx] *= (1.0/volume); + flux_moments_new_[idx] *= (1.0 / volume); } else if (volume > 0.0) { // 2. If the FSR was not hit this iteration, but has been hit some // previous iteration, then we simply set the new scalar flux to be // equal to the contribution from the flat source alone. scalar_flux_new_[idx] = source_[idx]; - flux_moments_new_[idx] *= (1.0/volume); + flux_moments_new_[idx] *= (1.0 / volume); } else { // If the FSR was not hit this iteration, and it has never been hit in // any iteration (i.e., volume is zero), then we want to set this to 0 @@ -196,7 +204,6 @@ void LinearSourceDomain::flux_swap() flux_moments_old_.swap(flux_moments_new_); } - void LinearSourceDomain::accumulate_iteration_flux() { // Accumulate scalar flux @@ -209,7 +216,8 @@ void LinearSourceDomain::accumulate_iteration_flux() } } -double LinearSourceDomain::evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const +double LinearSourceDomain::evaluate_flux_at_point( + const Position r, const int64_t sr, const int g) const { float phi_flat = FlatSourceDomain::evaluate_flux_at_point(r, sr, g); @@ -217,15 +225,18 @@ double LinearSourceDomain::evaluate_flux_at_point(const Position r, const int64_ Position phi_linear = flux_moments_t_[sr * negroups_ + g]; phi_linear *= 1.0 / (settings::n_batches - settings::n_inactive); Position phi_solved = mom_matrix_[sr].solve(phi_linear); - - if( sr == 1337 && g == 6) - { - //printf("phi_flat: %.3le phi_x: %.3le phi_y: %.3le phi_z: %.3le total_phi: %.3le x: %.3le y: %.3le z: %.3le\n", - // phi_flat, phi_x, phi_y, phi_z, phi_flat + phi_solved[0] * local_r.x + phi_solved[1] * local_r.y + phi_solved[2] * local_r.z, - // phi_solved[0] * local_r.x, phi_solved[1] * local_r.y, phi_solved[2] * local_r.z); + + if (sr == 1337 && g == 6) { + // printf("phi_flat: %.3le phi_x: %.3le phi_y: %.3le phi_z: %.3le total_phi: + // %.3le x: %.3le y: %.3le z: %.3le\n", + // phi_flat, phi_x, phi_y, phi_z, phi_flat + phi_solved[0] * + // local_r.x + phi_solved[1] * local_r.y + phi_solved[2] * local_r.z, + // phi_solved[0] * local_r.x, phi_solved[1] * local_r.y, + // phi_solved[2] * local_r.z); } - //return phi_flat + phi_x * local_r.x + phi_y * local_r.y + phi_z * local_r.z; + // return phi_flat + phi_x * local_r.x + phi_y * local_r.y + phi_z * + // local_r.z; return phi_flat + phi_solved.dot(local_r); } diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index b4320db3969..2710b6f6b37 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -357,8 +357,6 @@ void RandomRay::attenuate_flux_linear_source( // The source element is the energy-specific region index int64_t source_element = source_region * negroups_; - int64_t midx = source_region * 6; - int64_t didx = source_region * 3; int material = this->material(); // Temperature and angle indices, if using multiple temperature @@ -372,11 +370,13 @@ void RandomRay::attenuate_flux_linear_source( Position midpoint = r() + u() * (distance / 2.0); Position rm_local; Position r0_local; + // if (simulation::current_batch > 2) { if (centroid_pos[0] == centroid_pos[0]) { rm_local = midpoint - centroid_pos; r0_local = r() - centroid_pos; } else { + rm_local = {0.0, 0.0, 0.0}; r0_local = -u() * 0.5 * distance; } @@ -447,9 +447,6 @@ void RandomRay::attenuate_flux_linear_source( domain->centroid_t_[source_region] += midpoint * distance; domain->mom_matrix_t_[source_region] += mat_score; - // Accomulate volume (ray distance) into this iteration's estimate - // of the source region's volume - // If the source region hasn't been hit yet this iteration, // indicate that it now has if (domain_->was_hit_[source_region] == 0) { From 56d9da834adab4fa41b768988ffa7fb0b6a6f6d3 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Sat, 29 Jun 2024 21:35:43 -0500 Subject: [PATCH 30/61] fixed bug with always zero centroid --- src/random_ray/linear_source_domain.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 028fe6c3f28..7bbc6735316 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -156,13 +156,12 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() double volume_tracks = volume_t_[sr]; double invvol = 1.0 / volume_tracks; int material = material_[sr]; - int64_t didx = sr * 3; - int64_t midx = sr * 6; // Check if this cell was hit this iteration int was_cell_hit = was_hit_[sr]; if (was_cell_hit) { n_hits++; + centroid_[sr] = centroid_t_[sr]; centroid_[sr] *= invvol; mom_matrix_[sr] = mom_matrix_t_[sr]; mom_matrix_[sr] *= invvol; From 07ad8089fb4f3a80188cc29c7ea8f2b9ae948e1c Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 09:33:44 -0500 Subject: [PATCH 31/61] going to add 2D option to LS --- include/openmc/constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openmc/constants.h b/include/openmc/constants.h index 340dcc09956..c76d6e9326c 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -342,7 +342,7 @@ enum class RunMode { enum class SolverType { MONTE_CARLO, RANDOM_RAY }; -enum class RandomRaySourceShape { FLAT, LINEAR }; +enum class RandomRaySourceShape { FLAT, LINEAR, LINEAR_2D }; //============================================================================== // Geometry Constants From 566462d4c8279f1c4663a16ea4f98080cfb3d864 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 10:17:22 -0500 Subject: [PATCH 32/61] testing with centroid corrected estimators, not useful --- include/openmc/random_ray/random_ray.h | 4 ++-- src/random_ray/linear_source_domain.cpp | 1 - src/random_ray/random_ray.cpp | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 5be9654c6a4..00201e54b50 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -24,9 +24,9 @@ class RandomRay : public Particle { //---------------------------------------------------------------------------- // Methods void event_advance_ray(); - void attenuate_flux(double distance, bool is_active, double distance_to_boundary); + void attenuate_flux(double distance, bool is_active); void attenuate_flux_flat_source(double distance, bool is_active); - void attenuate_flux_linear_source(double distance, bool is_active, double distance_to_boundary); + void attenuate_flux_linear_source(double distance, bool is_active); void initialize_ray(uint64_t ray_id, FlatSourceDomain* domain); uint64_t transport_history_based_single_ray(); diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 7bbc6735316..18d91214dd8 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -183,7 +183,6 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // previous iteration, then we simply set the new scalar flux to be // equal to the contribution from the flat source alone. scalar_flux_new_[idx] = source_[idx]; - flux_moments_new_[idx] *= (1.0 / volume); } else { // If the FSR was not hit this iteration, and it has never been hit in // any iteration (i.e., volume is zero), then we want to set this to 0 diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 2710b6f6b37..b6bc7e7fe34 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -208,7 +208,7 @@ void RandomRay::event_advance_ray() } distance_travelled_ += distance; - attenuate_flux(distance, true, distance_to_boundary); + attenuate_flux(distance, true); } else { // If the ray is still in the dead zone, need to check if it // has entered the active phase. If so, split into two segments (one @@ -218,7 +218,7 @@ void RandomRay::event_advance_ray() if (distance_travelled_ + distance >= distance_inactive_) { is_active_ = true; double distance_dead = distance_inactive_ - distance_travelled_; - attenuate_flux(distance_dead, false, distance_to_boundary); + attenuate_flux(distance_dead, false); double distance_alive = distance - distance_dead; @@ -228,11 +228,11 @@ void RandomRay::event_advance_ray() wgt() = 0.0; } - attenuate_flux(distance_alive, true, distance_to_boundary); + attenuate_flux(distance_alive, true); distance_travelled_ = distance_alive; } else { distance_travelled_ += distance; - attenuate_flux(distance, false, distance_to_boundary); + attenuate_flux(distance, false); } } @@ -243,14 +243,14 @@ void RandomRay::event_advance_ray() } void RandomRay::attenuate_flux( - double distance, bool is_active, double distance_to_boundary) + double distance, bool is_active) { switch (source_shape_) { case RandomRaySourceShape::FLAT: attenuate_flux_flat_source(distance, is_active); break; case RandomRaySourceShape::LINEAR: - attenuate_flux_linear_source(distance, is_active, distance_to_boundary); + attenuate_flux_linear_source(distance, is_active); break; default: fatal_error("Unknown source shape for random ray transport."); @@ -341,8 +341,7 @@ void RandomRay::attenuate_flux_flat_source(double distance, bool is_active) } } -void RandomRay::attenuate_flux_linear_source( - double distance, bool is_active, double distance_to_boundary) +void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) { LinearSourceDomain* domain = static_cast(domain_); // The number of geometric intersections is counted for reporting purposes @@ -399,7 +398,6 @@ void RandomRay::attenuate_flux_linear_source( float new_delta_psi = (angular_flux_[g] - flat_source) * f1 * distance - 0.5 * dir_source * f2; delta_psi_[g] = new_delta_psi; - // prev_angular_flux_[g] = angular_flux_[g]; float h1 = f1 - gn; float g1 = 0.5f - h1; float g2 = exponentialG2(tau); @@ -410,6 +408,10 @@ void RandomRay::attenuate_flux_linear_source( flat_source = flat_source * distance + new_delta_psi; delta_moments_[g] = r0_local * flat_source + u() * h1; + // In 2D, the z-moment is going to blow up, because r_0_local in z + // is going to be huge (i.e., the ray's starting point is going + // to be very far from the centroid given that the cell is infinite + // in length. delta_moments_[g].z = 0.0f; angular_flux_[g] -= new_delta_psi * sigma_t; @@ -423,9 +425,6 @@ void RandomRay::attenuate_flux_linear_source( SymmetricMatrix mat_score; mat_score.compute_spatial_moments_matrix(rm_local, u(), distance); - // Scale the moment matrix by the length of the ray segment - mat_score.scale(distance); - // Aquire lock for source region domain_->lock_[source_region].lock(); @@ -445,6 +444,7 @@ void RandomRay::attenuate_flux_linear_source( // by the ray segment length. domain_->volume_[source_region] += distance; domain->centroid_t_[source_region] += midpoint * distance; + mat_score.scale(distance); domain->mom_matrix_t_[source_region] += mat_score; // If the source region hasn't been hit yet this iteration, From 72066e33b8c05195a4c0d226e5b2098b45270db4 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 10:34:35 -0500 Subject: [PATCH 33/61] enabled volume normalized tallies on new example problems for testing --- openmc/examples.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openmc/examples.py b/openmc/examples.py index 22bdd60b845..d841ba4d243 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -864,6 +864,7 @@ def random_ray_lattice(): settings.random_ray['distance_active'] = 100.0 settings.random_ray['distance_inactive'] = 20.0 settings.random_ray['ray_source'] = rr_source + settings.random_ray['volume_normalized_flux_tallies'] = True ########################################################################### # Define tallies @@ -1077,6 +1078,7 @@ def fill_cube(N, n_1, n_2, fill_1, fill_2, fill_3): settings.random_ray['distance_active'] = 500.0 settings.random_ray['distance_inactive'] = 100.0 settings.random_ray['ray_source'] = rr_source + settings.random_ray['volume_normalized_flux_tallies'] = True # Create the neutron source in the bottom right of the moderator # Good - fast group appears largest (besides most thermal) From 31b9b67f79824198ea0954dc0b58fca46f5649cc Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 10:38:48 -0500 Subject: [PATCH 34/61] enabled tally normalization by default in fixed source domain example problem --- .../cell/inputs_true.dat | 1 + .../cell/results_true.dat | 12 ++++++------ .../material/inputs_true.dat | 1 + .../material/results_true.dat | 12 ++++++------ .../universe/inputs_true.dat | 1 + .../universe/results_true.dat | 12 ++++++------ 6 files changed, 21 insertions(+), 18 deletions(-) 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 df2ac9537cc..d6ca8918cd0 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 @@ -212,6 +212,7 @@ 0.0 0.0 0.0 30.0 30.0 30.0 + True diff --git a/tests/regression_tests/random_ray_fixed_source_domain/cell/results_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/cell/results_true.dat index 714ad44a084..5f297586075 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/cell/results_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_domain/cell/results_true.dat @@ -1,9 +1,9 @@ tally 1: --6.614591E+04 -1.283943E+09 +-5.745886E+02 +9.758367E+04 tally 2: -3.415331E+00 -2.396684E+00 +2.971927E-02 +1.827222E-04 tally 3: -2.277429E-01 -1.050297E-02 +1.978393E-03 +7.951531E-07 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 7ac54688e88..7fae491aea4 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 @@ -212,6 +212,7 @@ 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/results_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/material/results_true.dat index 714ad44a084..5f297586075 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/material/results_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_domain/material/results_true.dat @@ -1,9 +1,9 @@ tally 1: --6.614591E+04 -1.283943E+09 +-5.745886E+02 +9.758367E+04 tally 2: -3.415331E+00 -2.396684E+00 +2.971927E-02 +1.827222E-04 tally 3: -2.277429E-01 -1.050297E-02 +1.978393E-03 +7.951531E-07 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 3dd0900d2bf..75d84efe978 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 @@ -212,6 +212,7 @@ 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/results_true.dat b/tests/regression_tests/random_ray_fixed_source_domain/universe/results_true.dat index 714ad44a084..5f297586075 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/universe/results_true.dat +++ b/tests/regression_tests/random_ray_fixed_source_domain/universe/results_true.dat @@ -1,9 +1,9 @@ tally 1: --6.614591E+04 -1.283943E+09 +-5.745886E+02 +9.758367E+04 tally 2: -3.415331E+00 -2.396684E+00 +2.971927E-02 +1.827222E-04 tally 3: -2.277429E-01 -1.050297E-02 +1.978393E-03 +7.951531E-07 From efc8f67a04b49cb994d6946f76364ef9f2cca573 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 10:46:57 -0500 Subject: [PATCH 35/61] added test specifically on volume normalization --- .../False/inputs_true.dat | 244 ++++++++++++++++++ .../False/results_true.dat | 9 + .../True/inputs_true.dat | 244 ++++++++++++++++++ .../True/results_true.dat | 9 + .../__init__.py | 0 .../test.py | 30 +++ 6 files changed, 536 insertions(+) create mode 100644 tests/regression_tests/random_ray_fixed_source_normalization/False/inputs_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_normalization/False/results_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_normalization/True/inputs_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_normalization/True/results_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_normalization/__init__.py create mode 100644 tests/regression_tests/random_ray_fixed_source_normalization/test.py 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 new file mode 100644 index 00000000000..559cff0f0df --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_normalization/False/inputs_true.dat @@ -0,0 +1,244 @@ + + + + mgxs.h5 + + + + + + + + + + + + + + + + + + + + + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + + + + + + + + + + fixed source + 90 + 10 + 5 + + + 100.0 1.0 + + + universe + 1 + + + multi-group + + 500.0 + 100.0 + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + False + + + + + 1 + + + 2 + + + 3 + + + 3 + flux + tracklength + + + 2 + flux + tracklength + + + 1 + flux + tracklength + + + diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/False/results_true.dat b/tests/regression_tests/random_ray_fixed_source_normalization/False/results_true.dat new file mode 100644 index 00000000000..dbe778df9bf --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_normalization/False/results_true.dat @@ -0,0 +1,9 @@ +tally 1: +-6.614590E+04 +1.283943E+09 +tally 2: +4.612657E+02 +4.402080E+04 +tally 3: +2.248302E+01 +1.026884E+02 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 new file mode 100644 index 00000000000..75d84efe978 --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_normalization/True/inputs_true.dat @@ -0,0 +1,244 @@ + + + + mgxs.h5 + + + + + + + + + + + + + + + + + + + + + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + + + + + + + + + + fixed source + 90 + 10 + 5 + + + 100.0 1.0 + + + universe + 1 + + + multi-group + + 500.0 + 100.0 + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + True + + + + + 1 + + + 2 + + + 3 + + + 3 + flux + tracklength + + + 2 + flux + tracklength + + + 1 + flux + tracklength + + + diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/True/results_true.dat b/tests/regression_tests/random_ray_fixed_source_normalization/True/results_true.dat new file mode 100644 index 00000000000..5f297586075 --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_normalization/True/results_true.dat @@ -0,0 +1,9 @@ +tally 1: +-5.745886E+02 +9.758367E+04 +tally 2: +2.971927E-02 +1.827222E-04 +tally 3: +1.978393E-03 +7.951531E-07 diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/__init__.py b/tests/regression_tests/random_ray_fixed_source_normalization/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/test.py b/tests/regression_tests/random_ray_fixed_source_normalization/test.py new file mode 100644 index 00000000000..6279e7e0744 --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_normalization/test.py @@ -0,0 +1,30 @@ +import os + +import numpy as np +import openmc +from openmc.utility_funcs import change_directory +from openmc.examples import random_ray_three_region_cube +import pytest + +from tests.testing_harness import TolerantPyAPITestHarness + +class MGXSTestHarness(TolerantPyAPITestHarness): + def _cleanup(self): + super()._cleanup() + f = 'mgxs.h5' + if os.path.exists(f): + os.remove(f) + +@pytest.mark.parametrize("normalize", ["True", "False"]) +def test_random_ray_fixed_source(normalize): + with change_directory(normalize): + openmc.reset_auto_ids() + model = random_ray_three_region_cube() + + if normalize == "True" : + model.settings.random_ray['volume_normalized_flux_tallies'] = True + else: + model.settings.random_ray['volume_normalized_flux_tallies'] = False + + harness = MGXSTestHarness('statepoint.10.h5', model) + harness.main() From bf696fabb7ba7226b258e549da4c0e0849b285c5 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 13:54:01 -0500 Subject: [PATCH 36/61] refactored Position to MomentArray --- include/openmc/constants.h | 2 +- .../openmc/random_ray/flat_source_domain.h | 2 +- .../openmc/random_ray/linear_source_domain.h | 8 +- include/openmc/random_ray/random_ray.h | 3 +- include/openmc/random_ray/symmetric_matrix.h | 3 + openmc/settings.py | 4 +- src/random_ray/linear_source_domain.cpp | 23 ++-- src/random_ray/random_ray.cpp | 101 +++++++++++------- src/random_ray/random_ray_simulation.cpp | 1 + src/settings.cpp | 2 + 10 files changed, 87 insertions(+), 62 deletions(-) diff --git a/include/openmc/constants.h b/include/openmc/constants.h index c76d6e9326c..e502506c91e 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -342,7 +342,7 @@ enum class RunMode { enum class SolverType { MONTE_CARLO, RANDOM_RAY }; -enum class RandomRaySourceShape { FLAT, LINEAR, LINEAR_2D }; +enum class RandomRaySourceShape { FLAT, LINEAR, LINEAR_XY }; //============================================================================== // Geometry Constants diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index d7a1f6ea032..b53e5eca5d1 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -130,6 +130,7 @@ class FlatSourceDomain { vector lock_; vector was_hit_; vector volume_; + vector volume_t_; vector position_recorded_; vector position_; @@ -173,7 +174,6 @@ class FlatSourceDomain { // 1D arrays representing values for all source regions vector material_; - vector volume_t_; // 2D arrays stored in 1D representing values for all source regions x energy // groups diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index ea48cf8267f..5e6b8816b4b 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -45,10 +45,10 @@ class LinearSourceDomain : public FlatSourceDomain { //---------------------------------------------------------------------------- // Public Data members - vector source_moments_; - vector flux_moments_old_; - vector flux_moments_new_; - vector flux_moments_t_; + vector source_moments_; + vector flux_moments_old_; + vector flux_moments_new_; + vector flux_moments_t_; vector centroid_; vector centroid_t_; vector mom_matrix_; diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 00201e54b50..3cd5e3a9080 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -4,6 +4,7 @@ #include "openmc/memory.h" #include "openmc/particle.h" #include "openmc/random_ray/flat_source_domain.h" +#include "openmc/random_ray/symmetric_matrix.h" #include "openmc/source.h" namespace openmc { @@ -46,7 +47,7 @@ class RandomRay : public Particle { //---------------------------------------------------------------------------- // Private data members vector delta_psi_; - vector delta_moments_; + vector delta_moments_; int negroups_; FlatSourceDomain* domain_ {nullptr}; // pointer to domain that has flat source diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h index c8481ac8fa8..0da88e8db03 100644 --- a/include/openmc/random_ray/symmetric_matrix.h +++ b/include/openmc/random_ray/symmetric_matrix.h @@ -7,6 +7,9 @@ namespace openmc { +// We make a typedef for the MomentArray type, which is a 3D vector of doubles. +using MomentArray = Position; + // The SymmetricMatrix class is a sparese representation a 3x3 symmetric // matrix, with elements labeled as follows: // diff --git a/openmc/settings.py b/openmc/settings.py index debb18fb3d4..8a6537e05d9 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -159,7 +159,7 @@ class Settings: specified by a :class:`openmc.SourceBase` object. :source_shape: Assumed shape of the source distribution within each source - region. Options are 'flat' (default) or 'linear'. + region. Options are 'flat' (default), 'linear', or 'linear_xy'. .. versionadded:: 0.15.0 resonance_scattering : dict @@ -1089,7 +1089,7 @@ def random_ray(self, random_ray: dict): cv.check_type('random ray source', random_ray[key], SourceBase) elif key == 'source_shape': cv.check_value('source shape', random_ray[key], - ('flat', 'linear')) + ('flat', 'linear', 'linear_xy')) else: raise ValueError(f'Unable to set random ray to "{key}" which is ' 'unsupported by OpenMC') diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 18d91214dd8..0f790c082da 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -69,13 +69,13 @@ void LinearSourceDomain::update_neutron_source(double k_eff) float scatter_flat = 0.0f; float fission_flat = 0.0f; - Position scatter_linear = {0.0, 0.0, 0.0}; - Position fission_linear = {0.0, 0.0, 0.0}; + MomentArray scatter_linear = {0.0, 0.0, 0.0}; + MomentArray fission_linear = {0.0, 0.0, 0.0}; for (int e_in = 0; e_in < negroups_; e_in++) { // Handles for the flat and linear components of the flux float flux_flat = scalar_flux_old_[sr * negroups_ + e_in]; - Position flux_linear = flux_moments_old_[sr * negroups_ + e_in]; + MomentArray flux_linear = flux_moments_old_[sr * negroups_ + e_in]; // Handles for cross sections float sigma_s = data::mg.macro_xs_[material].get_xs( @@ -220,21 +220,10 @@ double LinearSourceDomain::evaluate_flux_at_point( float phi_flat = FlatSourceDomain::evaluate_flux_at_point(r, sr, g); Position local_r = r - centroid_[sr]; - Position phi_linear = flux_moments_t_[sr * negroups_ + g]; + MomentArray phi_linear = flux_moments_t_[sr * negroups_ + g]; phi_linear *= 1.0 / (settings::n_batches - settings::n_inactive); - Position phi_solved = mom_matrix_[sr].solve(phi_linear); - - if (sr == 1337 && g == 6) { - // printf("phi_flat: %.3le phi_x: %.3le phi_y: %.3le phi_z: %.3le total_phi: - // %.3le x: %.3le y: %.3le z: %.3le\n", - // phi_flat, phi_x, phi_y, phi_z, phi_flat + phi_solved[0] * - // local_r.x + phi_solved[1] * local_r.y + phi_solved[2] * local_r.z, - // phi_solved[0] * local_r.x, phi_solved[1] * local_r.y, - // phi_solved[2] * local_r.z); - } - - // return phi_flat + phi_x * local_r.x + phi_y * local_r.y + phi_z * - // local_r.z; + MomentArray phi_solved = mom_matrix_[sr].solve(phi_linear); + return phi_flat + phi_solved.dot(local_r); } diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index b6bc7e7fe34..9f296e05aed 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -159,9 +159,13 @@ RandomRaySourceShape RandomRay::source_shape_ {RandomRaySourceShape::FLAT}; RandomRay::RandomRay() : angular_flux_(data::mg.num_energy_groups_), delta_psi_(data::mg.num_energy_groups_), - negroups_(data::mg.num_energy_groups_), - delta_moments_(data::mg.num_energy_groups_) -{} + negroups_(data::mg.num_energy_groups_) +{ + if (source_shape_ == RandomRaySourceShape::LINEAR || + source_shape_ == RandomRaySourceShape::LINEAR_XY) { + delta_moments_.resize(negroups_); + } +} RandomRay::RandomRay(uint64_t ray_id, FlatSourceDomain* domain) : RandomRay() { @@ -242,14 +246,14 @@ void RandomRay::event_advance_ray() } } -void RandomRay::attenuate_flux( - double distance, bool is_active) +void RandomRay::attenuate_flux(double distance, bool is_active) { switch (source_shape_) { case RandomRaySourceShape::FLAT: attenuate_flux_flat_source(distance, is_active); break; case RandomRaySourceShape::LINEAR: + case RandomRaySourceShape::LINEAR_XY: attenuate_flux_linear_source(distance, is_active); break; default: @@ -343,7 +347,13 @@ void RandomRay::attenuate_flux_flat_source(double distance, bool is_active) void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) { - LinearSourceDomain* domain = static_cast(domain_); + // Cast domain to LinearSourceDomain + LinearSourceDomain* domain = dynamic_cast(domain_); + if (!domain) { + fatal_error("RandomRay::attenuate_flux_linear_source() called with " + "non-LinearSourceDomain domain."); + } + // The number of geometric intersections is counted for reporting purposes n_event()++; @@ -365,62 +375,84 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) const int t = 0; const int a = 0; - Position& centroid_pos = domain->centroid_[source_region]; + Position& centroid = domain->centroid_[source_region]; Position midpoint = r() + u() * (distance / 2.0); + + // Determine the local position of the midpoint and the ray origin + // relative to the source region's centroid Position rm_local; Position r0_local; - // if (simulation::current_batch > 2) { - if (centroid_pos[0] == centroid_pos[0]) { - rm_local = midpoint - centroid_pos; - r0_local = r() - centroid_pos; + // In the first few iterations of the simulation, the source region + // may not yet have had any ray crossings, in which case there will + // be no estimate of its centroid. We detect this by checking if it has + // any accumulated volume. If its volume is zero, just use the midpoint + // of the ray as the region's centroid. + if (domain->volume_t_[source_region]) { + rm_local = midpoint - centroid; + r0_local = r() - centroid; } else { rm_local = {0.0, 0.0, 0.0}; r0_local = -u() * 0.5 * distance; } - // MOC incoming flux attenuation + source contribution/attenuation equation + // Linear Source MOC incoming flux attenuation + source + // contribution/attenuation equation for (int g = 0; g < negroups_; g++) { + + // Compute tau, the optical thickness of the ray segment float sigma_t = data::mg.macro_xs_[material].get_xs( MgxsType::TOTAL, g, NULL, NULL, NULL, t, a); float tau = sigma_t * distance; + + // If tau is very small, set it to zero to avoid numerical issues. + // The following computations will still work with tau = 0. + if (tau < 1.0e-8f) { + tau = 0.0f; + } + + // Compute the linear source angular flux attenuation and source + // contribution quantities float flat_source = domain_->source_[source_element + g] + rm_local.dot(domain->source_moments_[source_element + g]); - float dir_source = u().dot(domain->source_moments_[source_element + g]); + float linear_source = u().dot(domain->source_moments_[source_element + g]); - if (tau < 1E-8f) { - tau = 0.0f; - } float gn = exponentialG(tau); float f1 = 1.0f - tau * gn; float f2 = (2.0f * gn - f1) * distance * distance; - float new_delta_psi = - (angular_flux_[g] - flat_source) * f1 * distance - 0.5 * dir_source * f2; - delta_psi_[g] = new_delta_psi; + float new_delta_psi = (angular_flux_[g] - flat_source) * f1 * distance - + 0.5 * linear_source * f2; + float h1 = f1 - gn; float g1 = 0.5f - h1; float g2 = exponentialG2(tau); g1 = g1 * flat_source * distance; - g2 = g2 * dir_source * distance * distance * 0.5f; + g2 = g2 * linear_source * distance * distance * 0.5f; h1 = h1 * angular_flux_[g] * distance; h1 = (g1 + g2 + h1) * distance; flat_source = flat_source * distance + new_delta_psi; - delta_moments_[g] = r0_local * flat_source + u() * h1; - // In 2D, the z-moment is going to blow up, because r_0_local in z - // is going to be huge (i.e., the ray's starting point is going - // to be very far from the centroid given that the cell is infinite - // in length. - delta_moments_[g].z = 0.0f; + // Store contributions for this group into arrays, so that they can + // be accumulated into the source region's estimates inside of the locked + // region. + delta_psi_[g] = new_delta_psi; + delta_moments_[g] = r0_local * flat_source + u() * h1; + // Update the angular flux for this group angular_flux_[g] -= new_delta_psi * sigma_t; + + // If 2D mode is enabled, the z-component of the flux moments is forced + // to zero + if (source_shape_ == RandomRaySourceShape::LINEAR_XY) { + delta_moments_[g].z = 0.0; + } } // If ray is in the active phase (not in dead zone), make contributions to // source region bookkeeping if (is_active) { - // Compute an estimate of the spatial moments matric for the source + // Compute an estimate of the spatial moments matrix for the source // region based on this ray's crossing. SymmetricMatrix mat_score; mat_score.compute_spatial_moments_matrix(rm_local, u(), distance); @@ -428,20 +460,17 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // Aquire lock for source region domain_->lock_[source_region].lock(); - // Accumulate delta psi into new estimate of source region flux for - // this iteration + // Accumulate deltas into the new estimate of source region flux for this + // iteration for (int g = 0; g < negroups_; g++) { domain_->scalar_flux_new_[source_element + g] += delta_psi_[g]; domain->flux_moments_new_[source_element + g] += delta_moments_[g]; } - // Accumulate the volume (ray segment distance), - // centroid, and spatial momement estimates into the running totals - // for the iteration for this source region. These three parameters - // form the 0th order (volume), 1st order (centroid), and 2nd order - // (spatial moments matrix) spatial moments of the source region. - // The centroid and spatial momements estimates are scaled - // by the ray segment length. + // Accumulate the volume (ray segment distance), centroid, and spatial + // momement estimates into the running totals for the iteration for this + // source region. The centroid and spatial momements estimates are scaled by + // the ray segment length as part of length averaging of the estimates. domain_->volume_[source_region] += distance; domain->centroid_t_[source_region] += midpoint * distance; mat_score.scale(distance); diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 20d20f1580d..3c34718316d 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -248,6 +248,7 @@ RandomRaySimulation::RandomRaySimulation() domain_ = make_unique(); break; case RandomRaySourceShape::LINEAR: + case RandomRaySourceShape::LINEAR_XY: domain_ = make_unique(); break; default: diff --git a/src/settings.cpp b/src/settings.cpp index 308a9176fd2..4d95b2008c7 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -276,6 +276,8 @@ void get_run_parameters(pugi::xml_node node_base) RandomRay::source_shape_ = RandomRaySourceShape::FLAT; } else if (temp_str == "linear") { RandomRay::source_shape_ = RandomRaySourceShape::LINEAR; + } else if (temp_str == "linear_xy") { + RandomRay::source_shape_ = RandomRaySourceShape::LINEAR_XY; } else { fatal_error("Unrecognized source shape: " + temp_str); } From 87f31d22c91695f88fe620dd0fe54717bf8708e9 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 1 Jul 2024 15:07:26 -0500 Subject: [PATCH 37/61] refactor to MomentMatrix from SymmetricMatrix --- CMakeLists.txt | 2 +- .../openmc/random_ray/linear_source_domain.h | 6 +- include/openmc/random_ray/moment_matrix.h | 92 ++++++++++++++++++ include/openmc/random_ray/random_ray.h | 2 +- include/openmc/random_ray/symmetric_matrix.h | 95 ------------------- src/random_ray/linear_source_domain.cpp | 4 +- ...symmetric_matrix.cpp => moment_matrix.cpp} | 16 ++-- src/random_ray/random_ray.cpp | 4 +- 8 files changed, 108 insertions(+), 113 deletions(-) create mode 100644 include/openmc/random_ray/moment_matrix.h delete mode 100644 include/openmc/random_ray/symmetric_matrix.h rename src/random_ray/{symmetric_matrix.cpp => moment_matrix.cpp} (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03298640493..0f4cc1b527b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -381,7 +381,7 @@ list(APPEND libopenmc_SOURCES src/random_ray/random_ray.cpp src/random_ray/flat_source_domain.cpp src/random_ray/linear_source_domain.cpp - src/random_ray/symmetric_matrix.cpp + src/random_ray/moment_matrix.cpp src/reaction.cpp src/reaction_product.cpp src/scattdata.cpp diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 5e6b8816b4b..1d18f69004c 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -2,7 +2,7 @@ #define OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H #include "openmc/random_ray/flat_source_domain.h" -#include "openmc/random_ray/symmetric_matrix.h" +#include "openmc/random_ray/moment_matrix.h" #include "openmc/openmp_interface.h" #include "openmc/position.h" @@ -51,8 +51,8 @@ class LinearSourceDomain : public FlatSourceDomain { vector flux_moments_t_; vector centroid_; vector centroid_t_; - vector mom_matrix_; - vector mom_matrix_t_; + vector mom_matrix_; + vector mom_matrix_t_; private: //---------------------------------------------------------------------------- diff --git a/include/openmc/random_ray/moment_matrix.h b/include/openmc/random_ray/moment_matrix.h new file mode 100644 index 00000000000..47e4d75dd1b --- /dev/null +++ b/include/openmc/random_ray/moment_matrix.h @@ -0,0 +1,92 @@ +#ifndef OPENMC_MOMENT_MATRIX_H +#define OPENMC_MOMENT_MATRIX_H + +#include + +#include "openmc/position.h" + +namespace openmc { + +// The MomentArray class is a 3-element array representing the x, y, and z +// moments. It is defined as an alias for the Position class to allow for +// dot products and other operations with Position and Direction objects. +// TODO: This class could in theory have 32-bit instead of 64-bit FP values. +using MomentArray = Position; + +// The MomentMatrix class is a sparese representation a 3x3 symmetric +// matrix, with elements labeled as follows: +// +// | a b c | +// | b d e | +// | c e f | +// +// This class uses FP64 values as objects will be accumulated to over many +// iterations. +class MomentMatrix { +public: + //---------------------------------------------------------------------------- + // Public data members + double a; + double b; + double c; + double d; + double e; + double f; + + //---------------------------------------------------------------------------- + // Constructors + MomentMatrix() = default; + MomentMatrix(double a, double b, double c, double d, double e, double f) + : a {a}, b {b}, c {c}, d {d}, e {e}, f {f} + {} + + //---------------------------------------------------------------------------- + // Methods + MomentMatrix inverse() const; + double determinant() const; + void set_to_zero() { a = b = c = d = e = f = 0; } + + inline MomentMatrix& operator*=(double x) + { + a *= x; + b *= x; + c *= x; + d *= x; + e *= x; + f *= x; + return *this; + } + + inline MomentMatrix operator*(double x) const + { + MomentMatrix m_copy = *this; + m_copy *= x; + return m_copy; + } + + inline MomentMatrix& operator+=(const MomentMatrix& rhs) + { + a += rhs.a; + b += rhs.b; + c += rhs.c; + d += rhs.d; + e += rhs.e; + f += rhs.f; + return *this; + } + + MomentArray operator*(const MomentArray& rhs) const + { + return {a * rhs.x + b * rhs.y + c * rhs.z, + b * rhs.x + d * rhs.y + e * rhs.z, c * rhs.x + e * rhs.y + f * rhs.z}; + } + + MomentArray solve(const MomentArray& y) const; + + void compute_spatial_moments_matrix( + const Position& r, const Direction& u, const double& distance); +}; + +} // namespace openmc + +#endif // OPENMC_MOMENT_MATRIX_H \ No newline at end of file diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 3cd5e3a9080..e3b8f117c3c 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -4,7 +4,7 @@ #include "openmc/memory.h" #include "openmc/particle.h" #include "openmc/random_ray/flat_source_domain.h" -#include "openmc/random_ray/symmetric_matrix.h" +#include "openmc/random_ray/moment_matrix.h" #include "openmc/source.h" namespace openmc { diff --git a/include/openmc/random_ray/symmetric_matrix.h b/include/openmc/random_ray/symmetric_matrix.h deleted file mode 100644 index 0da88e8db03..00000000000 --- a/include/openmc/random_ray/symmetric_matrix.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef OPENMC_SYMMETRIC_MATRIX_H -#define OPENMC_SYMMETRIC_MATRIX_H - -#include - -#include "openmc/position.h" - -namespace openmc { - -// We make a typedef for the MomentArray type, which is a 3D vector of doubles. -using MomentArray = Position; - -// The SymmetricMatrix class is a sparese representation a 3x3 symmetric -// matrix, with elements labeled as follows: -// -// | a b c | -// | b d e | -// | c e f | -// -class SymmetricMatrix { -public: - //---------------------------------------------------------------------------- - // Public data members - double a; - double b; - double c; - double d; - double e; - double f; - - //---------------------------------------------------------------------------- - // Constructors - SymmetricMatrix() = default; - SymmetricMatrix(double a, double b, double c, double d, double e, double f) - : a(a), b(b), c(c), d(d), e(e), f(f) - {} - - //---------------------------------------------------------------------------- - // Methods - SymmetricMatrix inverse() const; - double determinant() const; - void set_to_zero() { a = b = c = d = e = f = 0; } - void scale(double x) - { - a *= x; - b *= x; - c *= x; - d *= x; - e *= x; - f *= x; - } - - SymmetricMatrix& operator*= (double x) - { - a *= x; - b *= x; - c *= x; - d *= x; - e *= x; - f *= x; - return *this; - } - - SymmetricMatrix& operator+=(const SymmetricMatrix& rhs) - { - a += rhs.a; - b += rhs.b; - c += rhs.c; - d += rhs.d; - e += rhs.e; - f += rhs.f; - return *this; - } - - Position operator*(const Position& rhs) const - { - return {a * rhs.x + b * rhs.y + c * rhs.z, - b * rhs.x + d * rhs.y + e * rhs.z, - c * rhs.x + e * rhs.y + f * rhs.z}; - } - - std::array solve(const std::array& y) const; - Position solve( const Position& y) const - { - std::array y_array = {y.x, y.y, y.z}; - std::array x_array = solve(y_array); - return {x_array[0], x_array[1], x_array[2]}; - } - - void compute_spatial_moments_matrix(const Position& r, const Direction& u, const double& distance); -}; - -} // namespace openmc - -#endif // OPENMC_SYMMETRIC_MATRIX_H \ No newline at end of file diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 0f790c082da..9137a6fc781 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -61,7 +61,7 @@ void LinearSourceDomain::update_neutron_source(double k_eff) for (int sr = 0; sr < n_source_regions_; sr++) { int material = material_[sr]; - SymmetricMatrix invM = mom_matrix_[sr].inverse(); + MomentMatrix invM = mom_matrix_[sr].inverse(); for (int e_out = 0; e_out < negroups_; e_out++) { float sigma_t = data::mg.macro_xs_[material].get_xs( @@ -223,7 +223,7 @@ double LinearSourceDomain::evaluate_flux_at_point( MomentArray phi_linear = flux_moments_t_[sr * negroups_ + g]; phi_linear *= 1.0 / (settings::n_batches - settings::n_inactive); MomentArray phi_solved = mom_matrix_[sr].solve(phi_linear); - + return phi_flat + phi_solved.dot(local_r); } diff --git a/src/random_ray/symmetric_matrix.cpp b/src/random_ray/moment_matrix.cpp similarity index 88% rename from src/random_ray/symmetric_matrix.cpp rename to src/random_ray/moment_matrix.cpp index 79d15190a17..be1ddb8f3aa 100644 --- a/src/random_ray/symmetric_matrix.cpp +++ b/src/random_ray/moment_matrix.cpp @@ -1,5 +1,5 @@ -#include "openmc/random_ray/symmetric_matrix.h" #include "openmc/error.h" +#include "openmc/random_ray/moment_matrix.h" #include @@ -21,15 +21,14 @@ namespace openmc { // Inversion is calculated by computing the adjoint matrix // first, and then the inverse can be computed as: // A^-1 = 1/det(A) * adj(A) -SymmetricMatrix SymmetricMatrix::inverse() const +MomentMatrix MomentMatrix::inverse() const { - SymmetricMatrix inv; + MomentMatrix inv; // Check if the determinant is zero double det = determinant(); if (det < std::abs(1.0e-10)) { inv.set_to_zero(); - // fatal_error("Matrix is singular and cannot be inverted."); return inv; } @@ -42,7 +41,7 @@ SymmetricMatrix SymmetricMatrix::inverse() const inv.f = a * d - b * b; // A^-1 = 1/det(A) * adj(A) - inv.scale(1.0 / det); + inv *= 1.0 / det; return inv; } @@ -53,13 +52,12 @@ SymmetricMatrix SymmetricMatrix::inverse() const // | a b c | // | b d e | // | c e f | -double SymmetricMatrix::determinant() const +double MomentMatrix::determinant() const { return a * (d * f - e * e) - b * (b * f - c * e) + c * (b * e - c * d); } -std::array SymmetricMatrix::solve( - const std::array& y) const +MomentArray MomentMatrix::solve(const MomentArray& y) const { // Check for positive definiteness and calculate Cholesky decomposition if (a <= 1e-10) { @@ -107,7 +105,7 @@ std::array SymmetricMatrix::solve( // The estimate of the obect's spatial moments matrix is computed based on the // midpoint of the ray's crossing, the direction of the ray, and the distance // the ray traveled through the 3D object. -void SymmetricMatrix::compute_spatial_moments_matrix( +void MomentMatrix::compute_spatial_moments_matrix( const Position& r, const Direction& u, const double& distance) { constexpr double one_over_twelve = 1.0 / 12.0; diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 9f296e05aed..7109f2d01a9 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -454,7 +454,7 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) if (is_active) { // Compute an estimate of the spatial moments matrix for the source // region based on this ray's crossing. - SymmetricMatrix mat_score; + MomentMatrix mat_score; mat_score.compute_spatial_moments_matrix(rm_local, u(), distance); // Aquire lock for source region @@ -473,7 +473,7 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // the ray segment length as part of length averaging of the estimates. domain_->volume_[source_region] += distance; domain->centroid_t_[source_region] += midpoint * distance; - mat_score.scale(distance); + mat_score *= distance; domain->mom_matrix_t_[source_region] += mat_score; // If the source region hasn't been hit yet this iteration, From 0fd8997246c20ed98db9bd927f370a935ec5c651 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 08:42:23 -0500 Subject: [PATCH 38/61] removed matrix linear solve, as the inverse works well enough --- include/openmc/random_ray/moment_matrix.h | 10 +++--- src/random_ray/linear_source_domain.cpp | 6 ++-- src/random_ray/moment_matrix.cpp | 38 ----------------------- 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/include/openmc/random_ray/moment_matrix.h b/include/openmc/random_ray/moment_matrix.h index 47e4d75dd1b..a0a98c1f8c8 100644 --- a/include/openmc/random_ray/moment_matrix.h +++ b/include/openmc/random_ray/moment_matrix.h @@ -44,7 +44,10 @@ class MomentMatrix { // Methods MomentMatrix inverse() const; double determinant() const; - void set_to_zero() { a = b = c = d = e = f = 0; } + void compute_spatial_moments_matrix( + const Position& r, const Direction& u, const double& distance); + + inline void set_to_zero() { a = b = c = d = e = f = 0; } inline MomentMatrix& operator*=(double x) { @@ -80,11 +83,6 @@ class MomentMatrix { return {a * rhs.x + b * rhs.y + c * rhs.z, b * rhs.x + d * rhs.y + e * rhs.z, c * rhs.x + e * rhs.y + f * rhs.z}; } - - MomentArray solve(const MomentArray& y) const; - - void compute_spatial_moments_matrix( - const Position& r, const Direction& u, const double& distance); }; } // namespace openmc diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 9137a6fc781..42eac5b37da 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -188,7 +188,7 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() // any iteration (i.e., volume is zero), then we want to set this to 0 // to avoid dividing anything by a zero volume. scalar_flux_new_[idx] = 0.0f; - flux_moments_new_[idx] *= 0.0f; + flux_moments_new_[idx] *= 0.0; } } } @@ -222,8 +222,10 @@ double LinearSourceDomain::evaluate_flux_at_point( Position local_r = r - centroid_[sr]; MomentArray phi_linear = flux_moments_t_[sr * negroups_ + g]; phi_linear *= 1.0 / (settings::n_batches - settings::n_inactive); - MomentArray phi_solved = mom_matrix_[sr].solve(phi_linear); + MomentMatrix invM = mom_matrix_[sr].inverse(); + MomentArray phi_solved = invM * phi_linear; + return phi_flat + phi_solved.dot(local_r); } diff --git a/src/random_ray/moment_matrix.cpp b/src/random_ray/moment_matrix.cpp index be1ddb8f3aa..fc724e42a72 100644 --- a/src/random_ray/moment_matrix.cpp +++ b/src/random_ray/moment_matrix.cpp @@ -57,44 +57,6 @@ double MomentMatrix::determinant() const return a * (d * f - e * e) - b * (b * f - c * e) + c * (b * e - c * d); } -MomentArray MomentMatrix::solve(const MomentArray& y) const -{ - // Check for positive definiteness and calculate Cholesky decomposition - if (a <= 1e-10) { - fatal_error("Matrix is not positive definite (element 'a' non-positive)."); - } - - double L11 = std::sqrt(a); - double L21 = b / L11; // Using matrix element 'b' directly - double L31 = c / L11; - - double tmp = d - L21 * L21; - if (tmp <= 1e-10) { - fatal_error("Matrix is not positive definite at second diagonal element."); - } - double L22 = std::sqrt(tmp); - - double L32 = (e - L21 * L31) / L22; - - tmp = f - L31 * L31 - L32 * L32; - if (tmp <= 1e-10) { - fatal_error("Matrix is not positive definite at third diagonal element."); - } - double L33 = std::sqrt(tmp); - - // Solving Ly = y (forward substitution) - double y1 = y[0] / L11; - double y2 = (y[1] - L21 * y1) / L22; - double y3 = (y[2] - L31 * y1 - L32 * y2) / L33; - - // Solving L^T x = y (backward substitution) - double x3 = y3 / L33; - double x2 = (y2 - L32 * x3) / L22; - double x1 = (y1 - L21 * x2 - L31 * x3) / L11; - - return {x1, x2, x3}; -} - // Compute a 3x3 spatial moment matrix based on a single ray crossing. // The matrix is symmetric, and is defined as: // From 16af8610cddb9bde43b557a2a649fee31e0be525 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 08:47:22 -0500 Subject: [PATCH 39/61] added comment --- src/random_ray/moment_matrix.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/random_ray/moment_matrix.cpp b/src/random_ray/moment_matrix.cpp index fc724e42a72..18c48181078 100644 --- a/src/random_ray/moment_matrix.cpp +++ b/src/random_ray/moment_matrix.cpp @@ -28,6 +28,9 @@ MomentMatrix MomentMatrix::inverse() const // Check if the determinant is zero double det = determinant(); if (det < std::abs(1.0e-10)) { + // Set the inverse to zero. In effect, this will + // result in all the linear terms of the source becoming + // zero, leaving just the flat source. inv.set_to_zero(); return inv; } From 82a8243d980acd12aa349414ecfee62138bac464 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 08:49:48 -0500 Subject: [PATCH 40/61] updated doc string of new model --- openmc/examples.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index d841ba4d243..1fedecac2cf 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -659,13 +659,13 @@ def random_ray_lattice(): """Create a 2x2 PWR pincell asymmetrical lattic eexample. This model is a 2x2 reflective lattice of fuel pins with one of the lattice - locations have just moderator instead of a fuel pin. It uses 7 group - cross section data + locations having just moderator instead of a fuel pin. It uses 7 group + cross section data. Returns ------- model : openmc.model.Model - A PWR pin-cell model + A PWR 2x2 lattice model """ model = openmc.model.Model() From 45f5071df885b842209a0d497bab221a92ed8d99 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 10:00:19 -0500 Subject: [PATCH 41/61] added tests for linear source --- .../__init__.py | 0 .../linear/inputs_true.dat | 245 ++++++++++++++++++ .../linear/results_true.dat | 9 + .../linear_xy/inputs_true.dat | 245 ++++++++++++++++++ .../linear_xy/results_true.dat | 9 + .../random_ray_fixed_source_linear/test.py | 25 ++ .../random_ray_linear/__init__.py | 0 .../random_ray_linear/linear/inputs_true.dat | 110 ++++++++ .../random_ray_linear/linear/results_true.dat | 171 ++++++++++++ .../linear_xy/inputs_true.dat | 110 ++++++++ .../linear_xy/results_true.dat | 171 ++++++++++++ .../random_ray_linear/test.py | 25 ++ 12 files changed, 1120 insertions(+) create mode 100644 tests/regression_tests/random_ray_fixed_source_linear/__init__.py create mode 100644 tests/regression_tests/random_ray_fixed_source_linear/linear/inputs_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_linear/linear/results_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_linear/linear_xy/inputs_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_linear/linear_xy/results_true.dat create mode 100644 tests/regression_tests/random_ray_fixed_source_linear/test.py create mode 100644 tests/regression_tests/random_ray_linear/__init__.py create mode 100644 tests/regression_tests/random_ray_linear/linear/inputs_true.dat create mode 100644 tests/regression_tests/random_ray_linear/linear/results_true.dat create mode 100644 tests/regression_tests/random_ray_linear/linear_xy/inputs_true.dat create mode 100644 tests/regression_tests/random_ray_linear/linear_xy/results_true.dat create mode 100644 tests/regression_tests/random_ray_linear/test.py diff --git a/tests/regression_tests/random_ray_fixed_source_linear/__init__.py b/tests/regression_tests/random_ray_fixed_source_linear/__init__.py new file mode 100644 index 00000000000..e69de29bb2d 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 new file mode 100644 index 00000000000..e2972c5f20a --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_linear/linear/inputs_true.dat @@ -0,0 +1,245 @@ + + + + mgxs.h5 + + + + + + + + + + + + + + + + + + + + + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + + + + + + + + + + fixed source + 90 + 10 + 5 + + + 100.0 1.0 + + + universe + 1 + + + multi-group + + 500.0 + 100.0 + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + True + linear + + + + + 1 + + + 2 + + + 3 + + + 3 + flux + tracklength + + + 2 + flux + tracklength + + + 1 + flux + tracklength + + + diff --git a/tests/regression_tests/random_ray_fixed_source_linear/linear/results_true.dat b/tests/regression_tests/random_ray_fixed_source_linear/linear/results_true.dat new file mode 100644 index 00000000000..7fb01a0ea11 --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_linear/linear/results_true.dat @@ -0,0 +1,9 @@ +tally 1: +-5.745718E+02 +9.757661E+04 +tally 2: +3.074428E-02 +1.952251E-04 +tally 3: +1.980876E-03 +7.970502E-07 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 new file mode 100644 index 00000000000..5b958d65cdb --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/inputs_true.dat @@ -0,0 +1,245 @@ + + + + mgxs.h5 + + + + + + + + + + + + + + + + + + + + + 2.5 2.5 2.5 + 12 12 12 + 0.0 0.0 0.0 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 +1 1 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 +2 2 2 2 2 2 2 2 2 2 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 3 3 + + + + + + + + + + fixed source + 90 + 10 + 5 + + + 100.0 1.0 + + + universe + 1 + + + multi-group + + 500.0 + 100.0 + + + 0.0 0.0 0.0 30.0 30.0 30.0 + + + True + linear_xy + + + + + 1 + + + 2 + + + 3 + + + 3 + flux + tracklength + + + 2 + flux + tracklength + + + 1 + flux + tracklength + + + diff --git a/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/results_true.dat b/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/results_true.dat new file mode 100644 index 00000000000..22b39edcfd8 --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_linear/linear_xy/results_true.dat @@ -0,0 +1,9 @@ +tally 1: +-5.745810E+02 +9.758220E+04 +tally 2: +3.022777E-02 +1.884091E-04 +tally 3: +1.980651E-03 +7.968779E-07 diff --git a/tests/regression_tests/random_ray_fixed_source_linear/test.py b/tests/regression_tests/random_ray_fixed_source_linear/test.py new file mode 100644 index 00000000000..9455049e95a --- /dev/null +++ b/tests/regression_tests/random_ray_fixed_source_linear/test.py @@ -0,0 +1,25 @@ +import os + +import numpy as np +import openmc +from openmc.utility_funcs import change_directory +from openmc.examples import random_ray_three_region_cube +import pytest + +from tests.testing_harness import TolerantPyAPITestHarness + +class MGXSTestHarness(TolerantPyAPITestHarness): + def _cleanup(self): + super()._cleanup() + f = 'mgxs.h5' + if os.path.exists(f): + os.remove(f) + +@pytest.mark.parametrize("shape", ["linear", "linear_xy"]) +def test_random_ray_fixed_source_linear(shape): + with change_directory(shape): + openmc.reset_auto_ids() + model = random_ray_three_region_cube() + model.settings.random_ray['source_shape'] = shape + harness = MGXSTestHarness('statepoint.10.h5', model) + harness.main() diff --git a/tests/regression_tests/random_ray_linear/__init__.py b/tests/regression_tests/random_ray_linear/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/regression_tests/random_ray_linear/linear/inputs_true.dat b/tests/regression_tests/random_ray_linear/linear/inputs_true.dat new file mode 100644 index 00000000000..c580be3d19e --- /dev/null +++ b/tests/regression_tests/random_ray_linear/linear/inputs_true.dat @@ -0,0 +1,110 @@ + + + + mgxs.h5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.126 0.126 + 10 10 + -0.63 -0.63 + +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 + + + 1.26 1.26 + 2 2 + -1.26 -1.26 + +2 2 +2 5 + + + + + + + + + + + + + + + + + + + + + eigenvalue + 100 + 10 + 5 + multi-group + + 100.0 + 20.0 + + + -1.26 -1.26 -1 1.26 1.26 1 + + + True + linear + + + + + 2 2 + -1.26 -1.26 + 1.26 1.26 + + + 1 + + + 1e-05 0.0635 10.0 100.0 1000.0 500000.0 1000000.0 20000000.0 + + + 1 2 + flux fission nu-fission + analog + + + diff --git a/tests/regression_tests/random_ray_linear/linear/results_true.dat b/tests/regression_tests/random_ray_linear/linear/results_true.dat new file mode 100644 index 00000000000..a3e24dc75d8 --- /dev/null +++ b/tests/regression_tests/random_ray_linear/linear/results_true.dat @@ -0,0 +1,171 @@ +k-combined: +8.273022E-01 1.347623E-02 +tally 1: +5.004109E+00 +5.022655E+00 +1.844047E+00 +6.833376E-01 +4.488042E+00 +4.047669E+00 +2.824818E+00 +1.599927E+00 +4.182704E-01 +3.509796E-02 +1.017987E+00 +2.078987E-01 +1.676761E+00 +5.682729E-01 +5.385624E-02 +5.857594E-04 +1.310753E-01 +3.469677E-03 +2.353602E+00 +1.127695E+00 +7.721312E-02 +1.212202E-03 +1.879213E-01 +7.180339E-03 +7.082957E+00 +1.019023E+01 +8.203580E-02 +1.366996E-03 +1.996612E-01 +8.097436E-03 +2.034293E+01 +8.321967E+01 +3.099116E-02 +1.933713E-04 +7.668546E-02 +1.183975E-03 +1.311478E+01 +3.442575E+01 +1.778200E-01 +6.347187E-03 +4.945973E-01 +4.910476E-02 +7.576546E+00 +1.148094E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.386885E+00 +2.295318E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.823720E+00 +6.769694E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.703042E+00 +1.494228E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +7.465612E+00 +1.132769E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.820337E+01 +6.657534E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.127686E+01 +2.549122E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.561053E+00 +4.169936E+00 +1.674166E+00 +5.624648E-01 +4.074585E+00 +3.331694E+00 +2.723008E+00 +1.487311E+00 +4.059013E-01 +3.307772E-02 +9.878827E-01 +1.959320E-01 +1.663524E+00 +5.584734E-01 +5.399658E-02 +5.877094E-04 +1.314169E-01 +3.481227E-03 +2.310994E+00 +1.086435E+00 +7.627297E-02 +1.181877E-03 +1.856331E-01 +7.000707E-03 +7.100201E+00 +1.023633E+01 +8.285591E-02 +1.393520E-03 +2.016572E-01 +8.254554E-03 +2.119292E+01 +9.022917E+01 +3.281214E-02 +2.163583E-04 +8.119135E-02 +1.324719E-03 +1.380975E+01 +3.815787E+01 +1.919186E-01 +7.384267E-03 +5.338118E-01 +5.712809E-02 +5.024478E+00 +5.056216E+00 +1.888826E+00 +7.148091E-01 +4.597025E+00 +4.234087E+00 +2.839930E+00 +1.616473E+00 +4.294394E-01 +3.697612E-02 +1.045170E+00 +2.190237E-01 +1.688196E+00 +5.765397E-01 +5.539650E-02 +6.200086E-04 +1.348240E-01 +3.672547E-03 +2.361633E+00 +1.136540E+00 +7.901052E-02 +1.270359E-03 +1.922958E-01 +7.524822E-03 +7.100780E+00 +1.024481E+01 +8.389610E-02 +1.429594E-03 +2.041888E-01 +8.468240E-03 +2.049187E+01 +8.438141E+01 +3.195576E-02 +2.052140E-04 +7.907229E-02 +1.256485E-03 +1.327412E+01 +3.524466E+01 +1.850084E-01 +6.847675E-03 +5.145915E-01 +5.297677E-02 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 new file mode 100644 index 00000000000..5c4076de70f --- /dev/null +++ b/tests/regression_tests/random_ray_linear/linear_xy/inputs_true.dat @@ -0,0 +1,110 @@ + + + + mgxs.h5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.126 0.126 + 10 10 + -0.63 -0.63 + +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 +3 3 3 3 3 3 3 3 3 3 + + + 1.26 1.26 + 2 2 + -1.26 -1.26 + +2 2 +2 5 + + + + + + + + + + + + + + + + + + + + + eigenvalue + 100 + 10 + 5 + multi-group + + 100.0 + 20.0 + + + -1.26 -1.26 -1 1.26 1.26 1 + + + True + linear_xy + + + + + 2 2 + -1.26 -1.26 + 1.26 1.26 + + + 1 + + + 1e-05 0.0635 10.0 100.0 1000.0 500000.0 1000000.0 20000000.0 + + + 1 2 + flux fission nu-fission + analog + + + 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 new file mode 100644 index 00000000000..f79b3fa787f --- /dev/null +++ b/tests/regression_tests/random_ray_linear/linear_xy/results_true.dat @@ -0,0 +1,171 @@ +k-combined: +8.368882E-01 8.107070E-03 +tally 1: +5.072700E+00 +5.152684E+00 +1.876680E+00 +7.051697E-01 +4.567463E+00 +4.176989E+00 +2.858196E+00 +1.636775E+00 +4.239946E-01 +3.601884E-02 +1.031918E+00 +2.133534E-01 +1.692006E+00 +5.789664E-01 +5.442292E-02 +5.988675E-04 +1.324545E-01 +3.547321E-03 +2.371801E+00 +1.146513E+00 +7.804414E-02 +1.241074E-03 +1.899438E-01 +7.351359E-03 +7.134037E+00 +1.034554E+01 +8.269855E-02 +1.390936E-03 +2.012742E-01 +8.239245E-03 +2.043174E+01 +8.386878E+01 +3.098171E-02 +1.929186E-04 +7.666208E-02 +1.181203E-03 +1.312800E+01 +3.447362E+01 +1.763141E-01 +6.217438E-03 +4.904088E-01 +4.810096E-02 +7.608165E+00 +1.157716E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +3.392187E+00 +2.302667E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.821339E+00 +6.737984E-01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +2.695742E+00 +1.483104E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +7.457904E+00 +1.129343E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.824331E+01 +6.687165E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.138096E+01 +2.591161E+01 +0.000000E+00 +0.000000E+00 +0.000000E+00 +0.000000E+00 +4.582534E+00 +4.206969E+00 +1.707129E+00 +5.837143E-01 +4.154811E+00 +3.457563E+00 +2.727459E+00 +1.491183E+00 +4.100516E-01 +3.371280E-02 +9.979836E-01 +1.996938E-01 +1.660765E+00 +5.570066E-01 +5.425719E-02 +5.941503E-04 +1.320511E-01 +3.519379E-03 +2.306630E+00 +1.083425E+00 +7.695103E-02 +1.205473E-03 +1.872834E-01 +7.140475E-03 +7.077631E+00 +1.018246E+01 +8.321109E-02 +1.408010E-03 +2.025216E-01 +8.340388E-03 +2.094896E+01 +8.817186E+01 +3.233088E-02 +2.099749E-04 +8.000050E-02 +1.285635E-03 +1.356905E+01 +3.683229E+01 +1.859858E-01 +6.921278E-03 +5.173102E-01 +5.354619E-02 +5.056029E+00 +5.118575E+00 +1.910007E+00 +7.308066E-01 +4.648575E+00 +4.328846E+00 +2.856363E+00 +1.634636E+00 +4.328679E-01 +3.755784E-02 +1.053514E+00 +2.224694E-01 +1.692444E+00 +5.793158E-01 +5.559366E-02 +6.243434E-04 +1.353038E-01 +3.698224E-03 +2.368251E+00 +1.142832E+00 +7.949453E-02 +1.285913E-03 +1.934738E-01 +7.616955E-03 +7.118354E+00 +1.029753E+01 +8.426801E-02 +1.442436E-03 +2.050940E-01 +8.544309E-03 +2.046889E+01 +8.419814E+01 +3.182500E-02 +2.035334E-04 +7.874874E-02 +1.246195E-03 +1.326056E+01 +3.517079E+01 +1.833225E-01 +6.723237E-03 +5.099023E-01 +5.201406E-02 diff --git a/tests/regression_tests/random_ray_linear/test.py b/tests/regression_tests/random_ray_linear/test.py new file mode 100644 index 00000000000..769214f26fc --- /dev/null +++ b/tests/regression_tests/random_ray_linear/test.py @@ -0,0 +1,25 @@ +import os + +import numpy as np +import openmc +from openmc.examples import random_ray_lattice +from openmc.utility_funcs import change_directory +import pytest + +from tests.testing_harness import TolerantPyAPITestHarness + +class MGXSTestHarness(TolerantPyAPITestHarness): + def _cleanup(self): + super()._cleanup() + f = 'mgxs.h5' + if os.path.exists(f): + os.remove(f) + +@pytest.mark.parametrize("shape", ["linear", "linear_xy"]) +def test_random_ray_source(shape): + with change_directory(shape): + openmc.reset_auto_ids() + model = random_ray_lattice() + model.settings.random_ray['source_shape'] = shape + harness = MGXSTestHarness('statepoint.10.h5', model) + harness.main() From ab1766538b706014d2cc3ff3925b86e5830c40b0 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 10:38:05 -0500 Subject: [PATCH 42/61] edits on docs --- docs/source/methods/random_ray.rst | 60 ++++++++++++++---------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index 9f50cc3f50d..bb7321ff8b0 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -758,6 +758,18 @@ behavior if a single simulation cell is able to score to multiple filter mesh cells. In the future, the capability to fully support mesh tallies may be added to OpenMC, but for now this restriction needs to be respected. +Flux tallies are handled slightly differently than in Monte Carlo. By default, +in MC, flux tallies are reported in units of tracklength (cm), so must be +manually normalized by volume by the user to produce an estimate of flux in +units of cm\ :sup:`-2`\. Alternatively, MC flux tallies can be normalized via a +separated volume calculation process as discussed in the :ref:`Volume +Calculation Section`. In random ray, as the volumes are +computed on-the-fly as part of the transport process, the flux tallies can +easily be reported either in units of flux (cm\ :sup:`-2`\) or tracklength (cm). +By default, the unnormalized flux values (units of cm) will be reported. If the +user wishes to received volume normalized flux tallies, then an option for this +is available, as described in the :ref:`User Guide`. + -------------- Linear Sources -------------- @@ -765,7 +777,7 @@ Linear Sources Instead of making a flat source approximation, as in the previous section, a Linear Source (LS) approximation can be used. Different LS approximations have been developed, the OpenMC implementation follows the MOC LS scheme described by -`Ferrer `_. The LS source along a characterstic is given by: +`Ferrer `_. The LS source along a characterstic is given by: .. math:: :label: linear_source @@ -817,7 +829,7 @@ the global coordinate and introduce the source region specific coordinate where :math:`\mathbf{r}_{\mathrm{c}}` is the centroid of the source region of interest. In turn :math:`\mathbf{u}_{r,\mathrm{c}}` and :math:`\mathbf{u}_{r,0}` are the local centroid and entry positions of a ray. The computation of the -local and global centroids are described further by `Gunow `_. +local and global centroids are described further by `Gunow `_. Using the local position, the source in a source region is given by: @@ -841,17 +853,20 @@ This definition allows us to solve for our characteric source terms resulting in :math:`\boldsymbol{\Omega}` being the direction vector of the ray. The next step is to solve for the LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}`. A relationship between the LS source vector and the source moments, -:math:`\boldsymbol{\vec{q}}_{i,g}` can be derived, `4 `_, `5 -`_: +:math:`\boldsymbol{\vec{q}}_{i,g}` can be derived, as in `Ferrer +`_ and `Gunow `_: .. math:: :label: m_equation - \boldsymbol{\vec{q}}_{i,g} = \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} + \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} = \boldsymbol{\vec{q}}_{i,g} -The LS source vector can be solved for by the inversion of the M matrix, a -geometrical quantity specific to the particular `source region `_, -provided that the source moments can be calculated. Fortunately, the source +The LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}` can be obtained via a +linear solve of :eq:`m_equation`, or by the direct inversion of the spatial +momemnts matrix :math:`M_i`, a :math:`3\times3` symmetric matrix that is defined +by purely geometrical aspects specific to the particular `source region +`_ :math:`i`. However, to accomplish this, we must first know the +source moments :math:`\boldsymbol{\vec{q}}_{i,g}`. Fortunately, the source moments are also defined by the definiton of the source: .. math:: @@ -861,17 +876,11 @@ moments are also defined by the definiton of the source: \Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G} \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z)\;\mathrm{,} -(John:Alternatively the below can be used with some edits---- ) - -.. math:: - :label: source_moments_update - - q^{n}(v,i) = \frac{\chi}{k^{n-1}_{eff}} \nu \Sigma_f(i, g) \hat{\phi}^{n-1}_{v, i}(g) + \sum\limits^{G}_{g\prime} \Sigma_{s}({i,g,g^{\prime}}) \hat{\phi}^{n-1}_{v, i}({g^{\prime}}) - -where we have introduced the scalar flux moments :math:`\hat{\phi}`. The scalar -flux moments can be solved for by taking the `integral definition `_ -of a spatial moment, allowing us to derive a "simulation averaged" estimator for -the scalar moment, as in Equation :eq:`phi_sim`, +where :math:`v` indicates the direction vector component, and we have introduced +the scalar flux moments :math:`\hat{\phi}`. The scalar flux moments can be +solved for by taking the `integral definition `_ of a spatial +moment, allowing us to derive a "simulation averaged" estimator for the scalar +moment, as in Equation :eq:`phi_sim`, .. math:: :label: scalar_moments_sim @@ -896,7 +905,6 @@ the angular flux spatial moments :math:`\hat{\psi}_{r,i,g}` by: The new exponentials introduced, again for simplicity, are simply: - .. math:: :label: G1 @@ -911,18 +919,6 @@ The contents of this section, alongside the equations for the flat source and scalar flux, Equations :eq:`source_update` and :eq:`phi_sim` respectively, completes the set of equations for LS. -Flux tallies are handled slightly differently than in Monte Carlo. By default, -in MC, flux tallies are reported in units of tracklength (cm), so must be -manually normalized by volume by the user to produce an estimate of flux in -units of cm\ :sup:`-2`\. Alternatively, MC flux tallies can be normalized via a -separated volume calculation process as discussed in the :ref:`Volume -Calculation Section`. In random ray, as the volumes are -computed on-the-fly as part of the transport process, the flux tallies can -easily be reported either in units of flux (cm\ :sup:`-2`\) or tracklength (cm). -By default, the unnormalized flux values (units of cm) will be reported. If the -user wishes to received volume normalized flux tallies, then an option for this -is available, as described in the :ref:`User Guide`. - .. _methods-shannon-entropy-random-ray: ----------------------------- From 35cb4b291c6c25d6ca5911c28b97a041109c0a34 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 10:46:08 -0500 Subject: [PATCH 43/61] edits on docs --- docs/source/methods/random_ray.rst | 35 ++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index bb7321ff8b0..139520bd0b3 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -859,15 +859,32 @@ relationship between the LS source vector and the source moments, .. math:: :label: m_equation - \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} = \boldsymbol{\vec{q}}_{i,g} - -The LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}` can be obtained via a -linear solve of :eq:`m_equation`, or by the direct inversion of the spatial -momemnts matrix :math:`M_i`, a :math:`3\times3` symmetric matrix that is defined -by purely geometrical aspects specific to the particular `source region -`_ :math:`i`. However, to accomplish this, we must first know the -source moments :math:`\boldsymbol{\vec{q}}_{i,g}`. Fortunately, the source -moments are also defined by the definiton of the source: + \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} = \boldsymbol{\vec{q}}_{i,g} . + +The spatial moments matrix :math:`M_i` in region :math:`i` represents the +spatial distribution of the 3D object composing the source region. This matrix +is independent of the material of the source region, fluxes, and any transport +effects -- it is a purely geometric quantity. It is a symmetric :math:`3\times3` +matrix. While :math:`M_i` is not known apriori to the simulation, similar to the +source region volume, it can be computed "on-the-fly" as a byproduct of the +random ray integration process. Each time a ray randomly crosses the region +within its active length, an estimate of the spatial moments matrix can be +computed by using the midpoint of the ray as an estimate of the centroid, and +the distance and direction of the ray can be used to inform the other spatial +moments within the matrix. As this information is purely geometric, the +stochastic estimate of the centroid and spatial moments matrix can be +accumulated and improved over the entire duration of the simulation, approaching +their true quantities. + +With an estimate of the spatial moments matrix :math:`M_i` resulting from the +ray tracing process naturally, the LS source vector +:math:`\boldsymbol{\vec{Q}}_{i,g}` can be obtained via a linear solve of +:eq:`m_equation`, or by the direct inversion of the spatial momemnts matrix +:math:`M_i`, a :math:`3\times3` symmetric matrix that is defined by purely +geometrical aspects specific to the particular `source region `_ +:math:`i`. However, to accomplish this, we must first know the source moments +:math:`\boldsymbol{\vec{q}}_{i,g}`. Fortunately, the source moments are also +defined by the definiton of the source: .. math:: :label: source_moments From 11dba822ffbabc2e4479d100dae5be78cafebe1c Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 11:02:08 -0500 Subject: [PATCH 44/61] adding more to docs --- docs/source/methods/random_ray.rst | 4 ++-- docs/source/usersguide/random_ray.rst | 29 +++++++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index 139520bd0b3..aa8de629940 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -873,8 +873,8 @@ computed by using the midpoint of the ray as an estimate of the centroid, and the distance and direction of the ray can be used to inform the other spatial moments within the matrix. As this information is purely geometric, the stochastic estimate of the centroid and spatial moments matrix can be -accumulated and improved over the entire duration of the simulation, approaching -their true quantities. +accumulated and improved over the entire duration of the simulation, converging +towards their true quantities. With an estimate of the spatial moments matrix :math:`M_i` resulting from the ray tracing process naturally, the LS source vector diff --git a/docs/source/usersguide/random_ray.rst b/docs/source/usersguide/random_ray.rst index 5d61b7ccca3..8477274d5de 100644 --- a/docs/source/usersguide/random_ray.rst +++ b/docs/source/usersguide/random_ray.rst @@ -447,16 +447,33 @@ in the `OpenMC Jupyter notebook collection separate materials can be defined each with a separate multigroup dataset corresponding to a given temperature. ---------------- +-------------- Linear Sources ---------------- -Linear Sources (LS), are supported with the eigenvalue and fixed source random ray solvers. -LS can be toggled on with:: +-------------- + +Linear Sources (LS), are supported with the eigenvalue and fixed source random +ray solvers. General 3D LS can be toggled by setting the ``source_shape`` field +in the :attr:`openmc.Settings.random_ray` dictionary to ``'linear'`` as:: settings.random_ray['source_shape'] = 'linear' -LS enables the use of coarser discretisations and lower ray populations, offsetting -the increased computation per ray. +LS enables the use of coarser mesh discretisations and lower ray populations, +offsetting the increased computation per ray. + +While OpenMC has no specific mode for 2D simulations, such simulations can be +performed implicitly by leaving one of the dimensions of the geometry unbounded +or by imposing reflective boundary conditions with no variation in between them +in that dimension. When 3D linear sources are used in a 2D random ray +simulation, the extremely long (or potentially infinite) spatial dimension along +one of the axes can cause the linear source to become noisy, leading to +potentially large increases in variance. To mitigate this, the user can force +the z-terms of the linear source to zero by setting the ``source_shape`` field +as:: + + settings.random_ray['source_shape'] = 'linear_xy' + +which will greatly improve the quality of the linear source term in 2D +simulations. --------------------------------- Fixed Source and Eigenvalue Modes From 551e386fe1b374b2d2659ff2d403c3d7ebed9b66 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Tue, 2 Jul 2024 11:21:50 -0500 Subject: [PATCH 45/61] removed nan inits --- src/random_ray/linear_source_domain.cpp | 2 +- src/random_ray/random_ray.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 42eac5b37da..032401d7448 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -29,7 +29,7 @@ LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() flux_moments_t_.assign(n_source_elements_, {0.0, 0.0, 0.0}); source_moments_.assign(n_source_elements_, {0.0, 0.0, 0.0}); - centroid_.assign(n_source_regions_, {nan(""), nan(""), nan("")}); + centroid_.assign(n_source_regions_, {0.0, 0.0, 0.0}); centroid_t_.assign(n_source_regions_, {0.0, 0.0, 0.0}); mom_matrix_.assign(n_source_regions_, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); mom_matrix_t_.assign(n_source_regions_, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 7109f2d01a9..ebf16372dc6 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -453,9 +453,10 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // source region bookkeeping if (is_active) { // Compute an estimate of the spatial moments matrix for the source - // region based on this ray's crossing. - MomentMatrix mat_score; - mat_score.compute_spatial_moments_matrix(rm_local, u(), distance); + // region based on parameters from this ray's crossing + MomentMatrix moment_matrix_estimate; + moment_matrix_estimate.compute_spatial_moments_matrix( + rm_local, u(), distance); // Aquire lock for source region domain_->lock_[source_region].lock(); @@ -473,8 +474,8 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // the ray segment length as part of length averaging of the estimates. domain_->volume_[source_region] += distance; domain->centroid_t_[source_region] += midpoint * distance; - mat_score *= distance; - domain->mom_matrix_t_[source_region] += mat_score; + moment_matrix_estimate *= distance; + domain->mom_matrix_t_[source_region] += moment_matrix_estimate; // If the source region hasn't been hit yet this iteration, // indicate that it now has From 11acd0a15035c0353afba9c356ae9f1e9356fc6d Mon Sep 17 00:00:00 2001 From: John Tramm Date: Thu, 4 Jul 2024 12:58:47 -0500 Subject: [PATCH 46/61] ran clang format --- include/openmc/random_ray/linear_source_domain.h | 8 ++++---- include/openmc/random_ray/random_ray.h | 2 +- src/random_ray/flat_source_domain.cpp | 12 +++++++----- src/random_ray/linear_source_domain.cpp | 2 +- src/random_ray/moment_matrix.cpp | 4 ++-- src/random_ray/random_ray_simulation.cpp | 2 +- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 1d18f69004c..c88f0d998db 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -35,12 +35,12 @@ class LinearSourceDomain : public FlatSourceDomain { void random_ray_tally(); void accumulate_iteration_flux() override; void output_to_vtk() const; - void all_reduce_replicated_source_regions(); //override + void all_reduce_replicated_source_regions(); // override void convert_external_sources(); void count_external_source_regions(); void flux_swap() override; - double evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const override; - + double evaluate_flux_at_point( + const Position r, const int64_t sr, const int g) const override; //---------------------------------------------------------------------------- // Public Data members @@ -62,7 +62,7 @@ class LinearSourceDomain : public FlatSourceDomain { //---------------------------------------------------------------------------- // Private data members - + // ... }; // class LinearSourceDomain diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index e3b8f117c3c..44d3c2c33e1 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -48,7 +48,7 @@ class RandomRay : public Particle { // Private data members vector delta_psi_; vector delta_moments_; - + int negroups_; FlatSourceDomain* domain_ {nullptr}; // pointer to domain that has flat source // data needed for ray transport diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index 56c4776dba4..d1b347544ca 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -751,9 +751,11 @@ void FlatSourceDomain::all_reduce_replicated_source_regions() #endif } -double FlatSourceDomain::evaluate_flux_at_point(const Position r, const int64_t sr, const int g) const +double FlatSourceDomain::evaluate_flux_at_point( + const Position r, const int64_t sr, const int g) const { - return scalar_flux_final_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); + return scalar_flux_final_[sr * negroups_ + g] / + (settings::n_batches - settings::n_inactive); } // Outputs all basic material, FSR ID, multigroup flux, and @@ -888,8 +890,8 @@ void FlatSourceDomain::output_to_vtk() const // Plot fission source std::fprintf(plot, "SCALARS total_fission_source float\n"); std::fprintf(plot, "LOOKUP_TABLE default\n"); - for (int i = 0; i < Nx * Ny * Nz; i++) { - int64_t fsr = voxel_indices[i]; + for (int i = 0; i < Nx * Ny * Nz; i++) { + int64_t fsr = voxel_indices[i]; float total_fission = 0.0; int mat = material_[fsr]; @@ -1035,7 +1037,7 @@ void FlatSourceDomain::convert_external_sources() } void FlatSourceDomain::flux_swap() { -scalar_flux_old_.swap(scalar_flux_new_); + scalar_flux_old_.swap(scalar_flux_new_); } } // namespace openmc diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 032401d7448..abb6de76746 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -225,7 +225,7 @@ double LinearSourceDomain::evaluate_flux_at_point( MomentMatrix invM = mom_matrix_[sr].inverse(); MomentArray phi_solved = invM * phi_linear; - + return phi_flat + phi_solved.dot(local_r); } diff --git a/src/random_ray/moment_matrix.cpp b/src/random_ray/moment_matrix.cpp index 18c48181078..1e631afb857 100644 --- a/src/random_ray/moment_matrix.cpp +++ b/src/random_ray/moment_matrix.cpp @@ -1,5 +1,5 @@ -#include "openmc/error.h" #include "openmc/random_ray/moment_matrix.h" +#include "openmc/error.h" #include @@ -30,7 +30,7 @@ MomentMatrix MomentMatrix::inverse() const if (det < std::abs(1.0e-10)) { // Set the inverse to zero. In effect, this will // result in all the linear terms of the source becoming - // zero, leaving just the flat source. + // zero, leaving just the flat source. inv.set_to_zero(); return inv; } diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 3c34718316d..39a0b46b858 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -6,6 +6,7 @@ #include "openmc/mgxs_interface.h" #include "openmc/output.h" #include "openmc/plot.h" +#include "openmc/random_ray/flat_source_domain.h" #include "openmc/random_ray/random_ray.h" #include "openmc/simulation.h" #include "openmc/source.h" @@ -13,7 +14,6 @@ #include "openmc/tallies/tally.h" #include "openmc/tallies/tally_scoring.h" #include "openmc/timer.h" -#include "openmc/random_ray/flat_source_domain.h" namespace openmc { From ebf7971345def41b0fe4bd7677734275bbb71085 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Thu, 4 Jul 2024 18:10:57 +0000 Subject: [PATCH 47/61] ran llvm 15 format --- include/openmc/random_ray/random_ray.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/openmc/random_ray/random_ray.h b/include/openmc/random_ray/random_ray.h index 44d3c2c33e1..913a9af4a75 100644 --- a/include/openmc/random_ray/random_ray.h +++ b/include/openmc/random_ray/random_ray.h @@ -34,9 +34,9 @@ class RandomRay : public Particle { //---------------------------------------------------------------------------- // Static data members - static double distance_inactive_; // Inactive (dead zone) ray length - static double distance_active_; // Active ray length - static unique_ptr ray_source_; // Starting source for ray sampling + static double distance_inactive_; // Inactive (dead zone) ray length + static double distance_active_; // Active ray length + static unique_ptr ray_source_; // Starting source for ray sampling static RandomRaySourceShape source_shape_; // Flag for linear source //---------------------------------------------------------------------------- From f19a0a3c6020e75edc403e68df510d802e19d33e Mon Sep 17 00:00:00 2001 From: RufusN Date: Sat, 6 Jul 2024 12:58:39 +0100 Subject: [PATCH 48/61] test MPI fix --- include/openmc/random_ray/flat_source_domain.h | 2 +- include/openmc/random_ray/linear_source_domain.h | 4 ++-- src/random_ray/linear_source_domain.cpp | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index 2a17a0b6763..a246d601a2d 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -106,7 +106,7 @@ class FlatSourceDomain { void random_ray_tally(); virtual void accumulate_iteration_flux(); void output_to_vtk() const; - void all_reduce_replicated_source_regions(); + virtual void all_reduce_replicated_source_regions(); void convert_external_sources(); void count_external_source_regions(); virtual void flux_swap(); diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index c88f0d998db..a3d80b994be 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -25,7 +25,7 @@ class LinearSourceDomain : public FlatSourceDomain { //---------------------------------------------------------------------------- // Methods void update_neutron_source(double k_eff) override; - double compute_k_eff(double k_eff_old) const; // override + double compute_k_eff(double k_eff_old) const; void normalize_scalar_flux_and_volumes( double total_active_distance_per_iteration) override; int64_t add_source_to_scalar_flux() override; @@ -35,7 +35,7 @@ class LinearSourceDomain : public FlatSourceDomain { void random_ray_tally(); void accumulate_iteration_flux() override; void output_to_vtk() const; - void all_reduce_replicated_source_regions(); // override + void all_reduce_replicated_source_regions() override; void convert_external_sources(); void count_external_source_regions(); void flux_swap() override; diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index abb6de76746..d488f0b0ce2 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -214,6 +214,17 @@ void LinearSourceDomain::accumulate_iteration_flux() } } +void LinearSourceDomain::all_reduce_replicated_source_regions() +{ +#ifdef OPENMC_MPI + FlatSourceDomain::all_reduce_replicated_source_regions(); + simulation::time_bank_sendrecv.start(); + MPI_Allreduce(MPI_IN_PLACE, flux_moments_new_.data(), n_source_elements_, + MPI_FLOAT, MPI_SUM, mpi::intracomm); + simulation::time_bank_sendrecv.stop(); +#endif +} + double LinearSourceDomain::evaluate_flux_at_point( const Position r, const int64_t sr, const int g) const { From b3c1c71ffeabbf8d0e9335801a956deb28d96ccd Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 8 Jul 2024 22:36:39 -0500 Subject: [PATCH 49/61] fix for MPI domain replication for LS --- .../openmc/random_ray/linear_source_domain.h | 1 + src/random_ray/linear_source_domain.cpp | 32 ++++++++++++++++--- src/random_ray/random_ray.cpp | 4 +-- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index a3d80b994be..555e1da73b1 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -50,6 +50,7 @@ class LinearSourceDomain : public FlatSourceDomain { vector flux_moments_new_; vector flux_moments_t_; vector centroid_; + vector centroid_iteration_; vector centroid_t_; vector mom_matrix_; vector mom_matrix_t_; diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index d488f0b0ce2..4a43daedd02 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -30,6 +30,7 @@ LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() source_moments_.assign(n_source_elements_, {0.0, 0.0, 0.0}); centroid_.assign(n_source_regions_, {0.0, 0.0, 0.0}); + centroid_iteration_.assign(n_source_regions_, {0.0, 0.0, 0.0}); centroid_t_.assign(n_source_regions_, {0.0, 0.0, 0.0}); mom_matrix_.assign(n_source_regions_, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); mom_matrix_t_.assign(n_source_regions_, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); @@ -39,8 +40,13 @@ void LinearSourceDomain::batch_reset() { FlatSourceDomain::batch_reset(); #pragma omp parallel for - for (auto& m : flux_moments_new_) { - m = {0.0, 0.0, 0.0}; + for (int64_t se = 0; se < n_source_elements_; se++) { + flux_moments_t_[se] = {0.0, 0.0, 0.0}; + } +#pragma omp parallel for + for (int64_t sr = 0; sr < n_source_regions_; sr++) { + centroid_iteration_[sr] = {0.0, 0.0, 0.0}; + mom_matrix_[sr] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; } } @@ -133,6 +139,8 @@ void LinearSourceDomain::normalize_scalar_flux_and_volumes( // update the simulation-averaged cell-wise volume estimates #pragma omp parallel for for (int64_t sr = 0; sr < n_source_regions_; sr++) { + centroid_t_[sr] += centroid_iteration_[sr]; + mom_matrix_t_[sr] += mom_matrix_[sr]; volume_t_[sr] += volume_[sr]; volume_[sr] = volume_t_[sr] * volume_normalization_factor; } @@ -219,8 +227,24 @@ void LinearSourceDomain::all_reduce_replicated_source_regions() #ifdef OPENMC_MPI FlatSourceDomain::all_reduce_replicated_source_regions(); simulation::time_bank_sendrecv.start(); - MPI_Allreduce(MPI_IN_PLACE, flux_moments_new_.data(), n_source_elements_, - MPI_FLOAT, MPI_SUM, mpi::intracomm); + + // We are going to assume we can safely cast Position, MomentArray, + // and MomentMatrix to contiguous arrays of doubles for the MPI + // allreduce operation. If a new FP32 MomentArray type is introduced, + // then there will likely be padding, in which case this function + // will need to become more complex. + if (sizeof(MomentArray) != 3 * sizeof(double) || + sizeof(MomentMatrix) != 6 * sizeof(double)) { + fatal_error("Unexpected buffer padding in linear source domain reduction."); + } + + MPI_Allreduce(MPI_IN_PLACE, static_cast(flux_moments_new_.data()), + n_source_elements_ * 3, MPI_DOUBLE, MPI_SUM, mpi::intracomm); + MPI_Allreduce(MPI_IN_PLACE, static_cast(mom_matrix_.data()), + n_source_regions_ * 6, MPI_DOUBLE, MPI_SUM, mpi::intracomm); + MPI_Allreduce(MPI_IN_PLACE, static_cast(centroid_iteration_.data()), + n_source_regions_ * 3, MPI_DOUBLE, MPI_SUM, mpi::intracomm); + simulation::time_bank_sendrecv.stop(); #endif } diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index ebf16372dc6..1b8b0a509ab 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -473,9 +473,9 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) // source region. The centroid and spatial momements estimates are scaled by // the ray segment length as part of length averaging of the estimates. domain_->volume_[source_region] += distance; - domain->centroid_t_[source_region] += midpoint * distance; + domain->centroid_iteration_[source_region] += midpoint * distance; moment_matrix_estimate *= distance; - domain->mom_matrix_t_[source_region] += moment_matrix_estimate; + domain->mom_matrix_[source_region] += moment_matrix_estimate; // If the source region hasn't been hit yet this iteration, // indicate that it now has From 72f94d0c9475ad27e59ed40b632f60eb9c4380f4 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 8 Jul 2024 22:59:13 -0500 Subject: [PATCH 50/61] update mom_matrix and centroids even if missed --- src/random_ray/linear_source_domain.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 4a43daedd02..3822ab341ef 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -142,7 +142,12 @@ void LinearSourceDomain::normalize_scalar_flux_and_volumes( centroid_t_[sr] += centroid_iteration_[sr]; mom_matrix_t_[sr] += mom_matrix_[sr]; volume_t_[sr] += volume_[sr]; + double invvol = 1.0 / volume_t_[sr]; volume_[sr] = volume_t_[sr] * volume_normalization_factor; + centroid_[sr] = centroid_t_[sr]; + centroid_[sr] *= invvol; + mom_matrix_[sr] = mom_matrix_t_[sr]; + mom_matrix_[sr] *= invvol; } } @@ -161,18 +166,12 @@ int64_t LinearSourceDomain::add_source_to_scalar_flux() for (int sr = 0; sr < n_source_regions_; sr++) { double volume = volume_[sr]; - double volume_tracks = volume_t_[sr]; - double invvol = 1.0 / volume_tracks; int material = material_[sr]; // Check if this cell was hit this iteration int was_cell_hit = was_hit_[sr]; if (was_cell_hit) { n_hits++; - centroid_[sr] = centroid_t_[sr]; - centroid_[sr] *= invvol; - mom_matrix_[sr] = mom_matrix_t_[sr]; - mom_matrix_[sr] *= invvol; } for (int g = 0; g < negroups_; g++) { From 61bce364855f18684e4c310082661f89f941281f Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 8 Jul 2024 23:15:49 -0500 Subject: [PATCH 51/61] ensure no nans if missed --- src/random_ray/linear_source_domain.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 3822ab341ef..2d7651f5c8e 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -142,12 +142,14 @@ void LinearSourceDomain::normalize_scalar_flux_and_volumes( centroid_t_[sr] += centroid_iteration_[sr]; mom_matrix_t_[sr] += mom_matrix_[sr]; volume_t_[sr] += volume_[sr]; - double invvol = 1.0 / volume_t_[sr]; volume_[sr] = volume_t_[sr] * volume_normalization_factor; - centroid_[sr] = centroid_t_[sr]; - centroid_[sr] *= invvol; - mom_matrix_[sr] = mom_matrix_t_[sr]; - mom_matrix_[sr] *= invvol; + if (volume_t_[sr] > 0.0) { + double inv_volume = 1.0 / volume_t_[sr]; + centroid_[sr] = centroid_t_[sr]; + centroid_[sr] *= inv_volume; + mom_matrix_[sr] = mom_matrix_t_[sr]; + mom_matrix_[sr] *= inv_volume; + } } } From bd4999ec52b1b8ad0a2ae02fbf044895297bfb7c Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 8 Jul 2024 23:23:27 -0500 Subject: [PATCH 52/61] Fixed wrong array reset --- src/random_ray/linear_source_domain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 2d7651f5c8e..466a5fb5ca8 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -41,7 +41,7 @@ void LinearSourceDomain::batch_reset() FlatSourceDomain::batch_reset(); #pragma omp parallel for for (int64_t se = 0; se < n_source_elements_; se++) { - flux_moments_t_[se] = {0.0, 0.0, 0.0}; + flux_moments_new_[se] = {0.0, 0.0, 0.0}; } #pragma omp parallel for for (int64_t sr = 0; sr < n_source_regions_; sr++) { From 6ed90895191f5b96dd37f5277507c216f6500d7e Mon Sep 17 00:00:00 2001 From: John Tramm Date: Mon, 8 Jul 2024 23:30:11 -0500 Subject: [PATCH 53/61] updated strings, and added MPI control to printouts --- src/random_ray/linear_source_domain.cpp | 7 +++--- src/random_ray/random_ray_simulation.cpp | 29 +++++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 466a5fb5ca8..f98664461da 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -231,9 +231,10 @@ void LinearSourceDomain::all_reduce_replicated_source_regions() // We are going to assume we can safely cast Position, MomentArray, // and MomentMatrix to contiguous arrays of doubles for the MPI - // allreduce operation. If a new FP32 MomentArray type is introduced, - // then there will likely be padding, in which case this function - // will need to become more complex. + // allreduce operation. This is a safe assumption as typically + // compilers will at most pad to 8 byte boundaries. If a new FP32 MomentArray + // type is introduced, then there will likely be padding, in which case this + // function will need to become more complex. if (sizeof(MomentArray) != 3 * sizeof(double) || sizeof(MomentMatrix) != 6 * sizeof(double)) { fatal_error("Unexpected buffer padding in linear source domain reduction."); diff --git a/src/random_ray/random_ray_simulation.cpp b/src/random_ray/random_ray_simulation.cpp index 39a0b46b858..4bc77645bcd 100644 --- a/src/random_ray/random_ray_simulation.cpp +++ b/src/random_ray/random_ray_simulation.cpp @@ -377,20 +377,23 @@ void RandomRaySimulation::instability_check( 100.0; avg_miss_rate += percent_missed; - if (percent_missed > 10.0) { - warning(fmt::format( - "Very high FSR miss rate detected ({:.3f}%). Instability may occur. " - "Increase ray density by adding more rays and/or active distance.", - percent_missed)); - } else if (percent_missed > 0.01) { - warning(fmt::format("Elevated FSR miss rate detected ({:.3f}%). Increasing " - "ray density by adding more rays and/or active " - "distance may improve simulation efficiency.", - percent_missed)); - } + if (mpi::master) { + if (percent_missed > 10.0) { + warning(fmt::format( + "Very high FSR miss rate detected ({:.3f}%). Instability may occur. " + "Increase ray density by adding more rays and/or active distance.", + percent_missed)); + } else if (percent_missed > 0.01) { + warning( + fmt::format("Elevated FSR miss rate detected ({:.3f}%). Increasing " + "ray density by adding more rays and/or active " + "distance may improve simulation efficiency.", + percent_missed)); + } - if (k_eff > 10.0 || k_eff < 0.01 || !(std::isfinite(k_eff))) { - fatal_error("Instability detected"); + if (k_eff > 10.0 || k_eff < 0.01 || !(std::isfinite(k_eff))) { + fatal_error("Instability detected"); + } } } From 1e40537420dc1b9d1e09a1e9dfd304d138f293ea Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 9 Jul 2024 22:01:41 +0100 Subject: [PATCH 54/61] renamed variables, added comments --- .../openmc/random_ray/linear_source_domain.h | 2 +- src/random_ray/linear_source_domain.cpp | 6 +++-- src/random_ray/random_ray.cpp | 23 ++++++++++--------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 555e1da73b1..b8909fb9a5d 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -45,7 +45,7 @@ class LinearSourceDomain : public FlatSourceDomain { //---------------------------------------------------------------------------- // Public Data members - vector source_moments_; + vector source_gradients_; vector flux_moments_old_; vector flux_moments_new_; vector flux_moments_t_; diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index f98664461da..460cf7db751 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -24,10 +24,12 @@ namespace openmc { LinearSourceDomain::LinearSourceDomain() : FlatSourceDomain() { + // First order spatial moment of the scalar flux flux_moments_old_.assign(n_source_elements_, {0.0, 0.0, 0.0}); flux_moments_new_.assign(n_source_elements_, {0.0, 0.0, 0.0}); flux_moments_t_.assign(n_source_elements_, {0.0, 0.0, 0.0}); - source_moments_.assign(n_source_elements_, {0.0, 0.0, 0.0}); + // Source gradients given by M inverse multiplied by source moments + source_gradients_.assign(n_source_elements_, {0.0, 0.0, 0.0}); centroid_.assign(n_source_regions_, {0.0, 0.0, 0.0}); centroid_iteration_.assign(n_source_regions_, {0.0, 0.0, 0.0}); @@ -104,7 +106,7 @@ void LinearSourceDomain::update_neutron_source(double k_eff) // Compute the linear source terms if (simulation::current_batch > 2) { - source_moments_[sr * negroups_ + e_out] = + source_gradients_[sr * negroups_ + e_out] = invM * ((scatter_linear + fission_linear * inverse_k_eff) / sigma_t); } } diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 1b8b0a509ab..8be15e5bbc9 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -411,33 +411,34 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) tau = 0.0f; } - // Compute the linear source angular flux attenuation and source - // contribution quantities - float flat_source = + // Compute linear source terms, spatial and directional (dir), + // calculated from the source gradients dot product with local centroid + // and direction, respectively. + float spatial_source = domain_->source_[source_element + g] + - rm_local.dot(domain->source_moments_[source_element + g]); - float linear_source = u().dot(domain->source_moments_[source_element + g]); + rm_local.dot(domain->source_gradients_[source_element + g]); + float dir_source = u().dot(domain->source_gradients_[source_element + g]); float gn = exponentialG(tau); float f1 = 1.0f - tau * gn; float f2 = (2.0f * gn - f1) * distance * distance; - float new_delta_psi = (angular_flux_[g] - flat_source) * f1 * distance - - 0.5 * linear_source * f2; + float new_delta_psi = (angular_flux_[g] - spatial_source) * f1 * distance - + 0.5 * dir_source * f2; float h1 = f1 - gn; float g1 = 0.5f - h1; float g2 = exponentialG2(tau); - g1 = g1 * flat_source * distance; - g2 = g2 * linear_source * distance * distance * 0.5f; + g1 = g1 * spatial_source * distance; + g2 = g2 * dir_source * distance * distance * 0.5f; h1 = h1 * angular_flux_[g] * distance; h1 = (g1 + g2 + h1) * distance; - flat_source = flat_source * distance + new_delta_psi; + spatial_source = spatial_source * distance + new_delta_psi; // Store contributions for this group into arrays, so that they can // be accumulated into the source region's estimates inside of the locked // region. delta_psi_[g] = new_delta_psi; - delta_moments_[g] = r0_local * flat_source + u() * h1; + delta_moments_[g] = r0_local * spatial_source + u() * h1; // Update the angular flux for this group angular_flux_[g] -= new_delta_psi * sigma_t; From d86984bbcdf2eea5cc77a419de4dd061a86834f1 Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 9 Jul 2024 22:08:42 +0100 Subject: [PATCH 55/61] Introduced distance_2 for repeated distance squared calculations --- src/random_ray/random_ray.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 8be15e5bbc9..eec566160f8 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -395,6 +395,7 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) rm_local = {0.0, 0.0, 0.0}; r0_local = -u() * 0.5 * distance; } + double distance_2 = distance * distance; // Linear Source MOC incoming flux attenuation + source // contribution/attenuation equation @@ -421,17 +422,17 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) float gn = exponentialG(tau); float f1 = 1.0f - tau * gn; - float f2 = (2.0f * gn - f1) * distance * distance; + float f2 = (2.0f * gn - f1) * distance_2; float new_delta_psi = (angular_flux_[g] - spatial_source) * f1 * distance - 0.5 * dir_source * f2; float h1 = f1 - gn; float g1 = 0.5f - h1; float g2 = exponentialG2(tau); - g1 = g1 * spatial_source * distance; - g2 = g2 * dir_source * distance * distance * 0.5f; - h1 = h1 * angular_flux_[g] * distance; - h1 = (g1 + g2 + h1) * distance; + g1 = g1 * spatial_source; + g2 = g2 * dir_source * distance * 0.5f; + h1 = h1 * angular_flux_[g]; + h1 = (g1 + g2 + h1) * distance_2; spatial_source = spatial_source * distance + new_delta_psi; // Store contributions for this group into arrays, so that they can From 097026326e5629aee1b6ec16caf3d35daff7b4fa Mon Sep 17 00:00:00 2001 From: RufusN Date: Tue, 9 Jul 2024 23:14:42 +0100 Subject: [PATCH 56/61] ran clang format --- src/random_ray/random_ray.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index eec566160f8..4fae5fcde64 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -413,8 +413,8 @@ void RandomRay::attenuate_flux_linear_source(double distance, bool is_active) } // Compute linear source terms, spatial and directional (dir), - // calculated from the source gradients dot product with local centroid - // and direction, respectively. + // calculated from the source gradients dot product with local centroid + // and direction, respectively. float spatial_source = domain_->source_[source_element + g] + rm_local.dot(domain->source_gradients_[source_element + g]); From b46dd16ecdfe0544023306df5d8009ff1c66f665 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 12 Jul 2024 09:34:17 -0500 Subject: [PATCH 57/61] adjusted formatting of python test files to match develop --- tests/regression_tests/random_ray_fixed_source_domain/test.py | 3 +++ tests/regression_tests/random_ray_fixed_source_linear/test.py | 2 ++ .../random_ray_fixed_source_normalization/test.py | 1 + tests/regression_tests/random_ray_k_eff/test.py | 1 + 4 files changed, 7 insertions(+) diff --git a/tests/regression_tests/random_ray_fixed_source_domain/test.py b/tests/regression_tests/random_ray_fixed_source_domain/test.py index ae3eb4cb1cf..5885a92009a 100644 --- a/tests/regression_tests/random_ray_fixed_source_domain/test.py +++ b/tests/regression_tests/random_ray_fixed_source_domain/test.py @@ -7,6 +7,7 @@ from tests.testing_harness import TolerantPyAPITestHarness + class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() @@ -14,6 +15,7 @@ def _cleanup(self): if os.path.exists(f): os.remove(f) + @pytest.mark.parametrize("domain_type", ["cell", "material", "universe"]) def test_random_ray_fixed_source(domain_type): with change_directory(domain_type): @@ -24,6 +26,7 @@ def test_random_ray_fixed_source(domain_type): # the particle source constraints source = model.settings.source[0] constraints = source.constraints + if domain_type == 'cell': cells = model.geometry.get_all_cells() for key, cell in cells.items(): diff --git a/tests/regression_tests/random_ray_fixed_source_linear/test.py b/tests/regression_tests/random_ray_fixed_source_linear/test.py index 9455049e95a..25335dea602 100644 --- a/tests/regression_tests/random_ray_fixed_source_linear/test.py +++ b/tests/regression_tests/random_ray_fixed_source_linear/test.py @@ -8,6 +8,7 @@ from tests.testing_harness import TolerantPyAPITestHarness + class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() @@ -15,6 +16,7 @@ def _cleanup(self): if os.path.exists(f): os.remove(f) + @pytest.mark.parametrize("shape", ["linear", "linear_xy"]) def test_random_ray_fixed_source_linear(shape): with change_directory(shape): diff --git a/tests/regression_tests/random_ray_fixed_source_normalization/test.py b/tests/regression_tests/random_ray_fixed_source_normalization/test.py index 45b1ac9b9e6..3fa4ba2a63f 100644 --- a/tests/regression_tests/random_ray_fixed_source_normalization/test.py +++ b/tests/regression_tests/random_ray_fixed_source_normalization/test.py @@ -7,6 +7,7 @@ from tests.testing_harness import TolerantPyAPITestHarness + class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() diff --git a/tests/regression_tests/random_ray_k_eff/test.py b/tests/regression_tests/random_ray_k_eff/test.py index 7466a2f11b3..8dd0dd9155c 100644 --- a/tests/regression_tests/random_ray_k_eff/test.py +++ b/tests/regression_tests/random_ray_k_eff/test.py @@ -4,6 +4,7 @@ from tests.testing_harness import TolerantPyAPITestHarness + class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() From c613d2b0ef52d8e7b38805a06c65d757311f462a Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 12 Jul 2024 09:44:43 -0500 Subject: [PATCH 58/61] formatting of docs --- docs/source/methods/random_ray.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index aa8de629940..e4347ed11a9 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -218,8 +218,9 @@ Following the multigroup discretization, another assumption made is that a large and complex problem can be broken up into small constant cross section regions, and that these regions have group dependent, flat, isotropic sources (fission and scattering), :math:`Q_g`. Anisotropic as well as higher order sources are -also possible with MOC-based methods. With these key assumptions, the multigroup MOC form of the neutron -transport equation can be written as in Equation :eq:`moc_final`. +also possible with MOC-based methods. With these key assumptions, the multigroup +MOC form of the neutron transport equation can be written as in Equation +:eq:`moc_final`. .. math:: :label: moc_final From 91fae90f2827476f62bee656769a59d877d205bd Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 12 Jul 2024 12:04:35 -0500 Subject: [PATCH 59/61] fix period in docs, and added OpenMOC license for G1 and G2 functions --- docs/source/methods/random_ray.rst | 2 +- src/random_ray/random_ray.cpp | 42 +++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index e4347ed11a9..74a47d0a860 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -860,7 +860,7 @@ relationship between the LS source vector and the source moments, .. math:: :label: m_equation - \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g}\;\mathrm{.} = \boldsymbol{\vec{q}}_{i,g} . + \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g} = \boldsymbol{\vec{q}}_{i,g} \;\mathrm{.} The spatial moments matrix :math:`M_i` in region :math:`i` represents the spatial distribution of the 3D object composing the source region. This matrix diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index 4fae5fcde64..e547a7693bd 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -61,10 +61,37 @@ float cjosey_exponential(float tau) return num / den; } -// Computes y = 1/x-(1-exp(-x))/x**2 using a 5/6th order rational -// approximation. OpenMoC -// https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 +// The below two functions (exponentialG and exponentialG2) were developed +// by Colin Josey. The implementation of these functions is closely based +// on the OpenMOC versions of these functions. The OpenMOC license is given +// below: + +// Copyright (C) 2012-2023 Massachusetts Institute of Technology and OpenMOC +// contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// Computes y = 1/x-(1-exp(-x))/x**2 using a 5/6th order rational +// approximation. It is accurate to 2e-7 over [0, 1e5]. Developed by Colin +// Josey using Remez's algorithm, with original implementation in OpenMOC at: +// https://github.com/mit-crpg/OpenMOC/blob/develop/src/exponentials.h float exponentialG(float tau) { // Numerator coefficients in rational approximation for 1/x - (1 - exp(-x)) / @@ -106,10 +133,11 @@ float exponentialG(float tau) return num / den; } -// Computes G2 : y = 2/3 - (1 + 2/x) * (1/x + 0.5 - (1 + 1/x) * (1-exp(-x)) / -// x) using a 5/5th order rational approximation, FROM: OpenMoC -// https://github.com/mit-crpg/OpenMOC/blob/7c8c9460c1c95f68dae102a402a39afa233a0b8c/src/exponentials.h#L9 - +// Computes G2 : y = 2/3 - (1 + 2/x) * (1/x + 0.5 - (1 + 1/x) * (1-exp(-x)) / +// x) using a 5/5th order rational approximation. It is accurate to 1e-6 over +// [0, 1e6]. Developed by Colin Josey using Remez's algorithm, with original +// implementation in OpenMOC at: +// https://github.com/mit-crpg/OpenMOC/blob/develop/src/exponentials.h float exponentialG2(float tau) { From 49815e27cda1ffe643a7fc5c2d3faaceececcff3 Mon Sep 17 00:00:00 2001 From: John Tramm Date: Fri, 12 Jul 2024 13:17:54 -0500 Subject: [PATCH 60/61] review fix items from @jtramm review --- include/openmc/random_ray/linear_source_domain.h | 13 +------------ src/random_ray/linear_source_domain.cpp | 2 +- src/random_ray/moment_matrix.cpp | 12 +++++------- src/random_ray/random_ray.cpp | 2 -- tests/regression_tests/random_ray_linear/test.py | 1 + 5 files changed, 8 insertions(+), 22 deletions(-) diff --git a/include/openmc/random_ray/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index b8909fb9a5d..83289c9fe18 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -12,7 +12,7 @@ namespace openmc { /* * The LinearSourceDomain class encompasses data and methods for storing - * scalar flux and source region for all flat source regions in a + * scalar flux and source region for all linear source regions in a * random ray simulation domain. */ @@ -55,17 +55,6 @@ class LinearSourceDomain : public FlatSourceDomain { vector mom_matrix_; vector mom_matrix_t_; -private: - //---------------------------------------------------------------------------- - // Methods - - // ... - - //---------------------------------------------------------------------------- - // Private data members - - // ... - }; // class LinearSourceDomain } // namespace openmc diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 460cf7db751..09c4cd1bb11 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -64,7 +64,7 @@ void LinearSourceDomain::update_neutron_source(double k_eff) // angle data. const int t = 0; const int a = 0; -// double det; + #pragma omp parallel for for (int sr = 0; sr < n_source_regions_; sr++) { diff --git a/src/random_ray/moment_matrix.cpp b/src/random_ray/moment_matrix.cpp index 1e631afb857..0324a14943b 100644 --- a/src/random_ray/moment_matrix.cpp +++ b/src/random_ray/moment_matrix.cpp @@ -9,18 +9,16 @@ namespace openmc { // UpperTriangular implementation //============================================================================== -// Inters the following 3x3 smmetric matrix labeled as: +// Inverts a 3x3 smmetric matrix labeled as: // // | a b c | // | b d e | // | c e f | // -// We first check the determinant to ensure it is non-zero -// before proceeding with the inversion. If the determinant -// is zero, we return a matrix of zeros. -// Inversion is calculated by computing the adjoint matrix -// first, and then the inverse can be computed as: -// A^-1 = 1/det(A) * adj(A) +// We first check the determinant to ensure it is non-zero before proceeding +// with the inversion. If the determinant is zero, we return a matrix of zeros. +// Inversion is calculated by computing the adjoint matrix first, and then the +// inverse can be computed as: A^-1 = 1/det(A) * adj(A) MomentMatrix MomentMatrix::inverse() const { MomentMatrix inv; diff --git a/src/random_ray/random_ray.cpp b/src/random_ray/random_ray.cpp index e547a7693bd..a5bf6ec1060 100644 --- a/src/random_ray/random_ray.cpp +++ b/src/random_ray/random_ray.cpp @@ -227,8 +227,6 @@ void RandomRay::event_advance_ray() return; } - double distance_to_boundary = distance; - if (is_active_) { // If the ray is in the active length, need to check if it has // reached its maximum termination distance. If so, reduce diff --git a/tests/regression_tests/random_ray_linear/test.py b/tests/regression_tests/random_ray_linear/test.py index 445e3ad3f07..10262789deb 100644 --- a/tests/regression_tests/random_ray_linear/test.py +++ b/tests/regression_tests/random_ray_linear/test.py @@ -7,6 +7,7 @@ from tests.testing_harness import TolerantPyAPITestHarness + class MGXSTestHarness(TolerantPyAPITestHarness): def _cleanup(self): super()._cleanup() From 06f2eef2d45f8afe47ba212d16f02826599b842e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 16 Jul 2024 16:09:08 -0500 Subject: [PATCH 61/61] Typo and style fixes --- docs/source/methods/random_ray.rst | 76 +++++++++---------- docs/source/usersguide/random_ray.rst | 4 +- .../openmc/random_ray/flat_source_domain.h | 3 +- .../openmc/random_ray/linear_source_domain.h | 5 +- include/openmc/random_ray/moment_matrix.h | 8 +- src/random_ray/flat_source_domain.cpp | 2 +- src/random_ray/linear_source_domain.cpp | 6 +- 7 files changed, 48 insertions(+), 56 deletions(-) diff --git a/docs/source/methods/random_ray.rst b/docs/source/methods/random_ray.rst index 74a47d0a860..9f8eb84d80e 100644 --- a/docs/source/methods/random_ray.rst +++ b/docs/source/methods/random_ray.rst @@ -777,8 +777,8 @@ Linear Sources Instead of making a flat source approximation, as in the previous section, a Linear Source (LS) approximation can be used. Different LS approximations have -been developed, the OpenMC implementation follows the MOC LS scheme described by -`Ferrer `_. The LS source along a characterstic is given by: +been developed; the OpenMC implementation follows the MOC LS scheme described by +`Ferrer `_. The LS source along a characteristic is given by: .. math:: :label: linear_source @@ -788,16 +788,16 @@ been developed, the OpenMC implementation follows the MOC LS scheme described by where the source, :math:`Q_{i,g}(s)`, varies linearly along the track and :math:`\bar{Q}_{r,i,g}` and :math:`\hat{Q}_{r,i,g}` are track specific source terms to define shortly. Integrating the source, as done in Equation -:eq:`moc_final`, leads to +:eq:`moc_final`, leads to .. math:: :label: lsr_attenuation - \psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{r, i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) + \psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{r, i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) F_{1}\left(\tau_{i,g}\right)+\frac{\hat{Q}_{r, i, g}^{g}}{2\left(\Sigma_{\mathrm{t}, i,g}\right)^{2}} F_{2}\left(\tau_{i,g}\right), -where for simplicity the term :math:`\tau_{i,g}` and the expoentials :math:`F1` -and :math:`F2` are introduced, given by: +where for simplicity the term :math:`\tau_{i,g}` and the expoentials :math:`F_1` +and :math:`F_2` are introduced, given by: .. math:: :label: tau @@ -837,20 +837,20 @@ Using the local position, the source in a source region is given by: .. math:: :label: region_source - \tilde{Q}(\boldsymbol{x}) ={Q}_{i,g}+ \boldsymbol{\vec{Q}}_{i,g} \cdot \mathbf{u}_{r}\;\mathrm{,} + \tilde{Q}(\boldsymbol{x}) ={Q}_{i,g}+ \boldsymbol{\vec{Q}}_{i,g} \cdot \mathbf{u}_{r}\;\mathrm{,} -This definition allows us to solve for our characteric source terms resulting in: +This definition allows us to solve for our characteric source terms resulting in: .. math:: :label: source_term_1 - \bar{Q}_{r, i, g} = Q_{i,g} + \left[\mathbf{u}_{r,\mathrm{c}} \cdot \boldsymbol{\vec{Q}}_{i,g}\right], + \bar{Q}_{r, i, g} = Q_{i,g} + \left[\mathbf{u}_{r,\mathrm{c}} \cdot \boldsymbol{\vec{Q}}_{i,g}\right], .. math:: :label: source_term_2 \hat{Q}_{r, i, g} = \left[\boldsymbol{\Omega} \cdot \boldsymbol{\vec{Q}}_{i,g}\right]\;\mathrm{,} - + :math:`\boldsymbol{\Omega}` being the direction vector of the ray. The next step is to solve for the LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}`. A relationship between the LS source vector and the source moments, @@ -863,42 +863,40 @@ relationship between the LS source vector and the source moments, \mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g} = \boldsymbol{\vec{q}}_{i,g} \;\mathrm{.} The spatial moments matrix :math:`M_i` in region :math:`i` represents the -spatial distribution of the 3D object composing the source region. This matrix -is independent of the material of the source region, fluxes, and any transport -effects -- it is a purely geometric quantity. It is a symmetric :math:`3\times3` -matrix. While :math:`M_i` is not known apriori to the simulation, similar to the -source region volume, it can be computed "on-the-fly" as a byproduct of the -random ray integration process. Each time a ray randomly crosses the region -within its active length, an estimate of the spatial moments matrix can be -computed by using the midpoint of the ray as an estimate of the centroid, and -the distance and direction of the ray can be used to inform the other spatial -moments within the matrix. As this information is purely geometric, the -stochastic estimate of the centroid and spatial moments matrix can be -accumulated and improved over the entire duration of the simulation, converging -towards their true quantities. +spatial distribution of the 3D object composing the `source region +`_. This matrix is independent of the material of the source +region, fluxes, and any transport effects -- it is a purely geometric quantity. +It is a symmetric :math:`3\times3` matrix. While :math:`M_i` is not known +apriori to the simulation, similar to the source region volume, it can be +computed "on-the-fly" as a byproduct of the random ray integration process. Each +time a ray randomly crosses the region within its active length, an estimate of +the spatial moments matrix can be computed by using the midpoint of the ray as +an estimate of the centroid, and the distance and direction of the ray can be +used to inform the other spatial moments within the matrix. As this information +is purely geometric, the stochastic estimate of the centroid and spatial moments +matrix can be accumulated and improved over the entire duration of the +simulation, converging towards their true quantities. With an estimate of the spatial moments matrix :math:`M_i` resulting from the ray tracing process naturally, the LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}` can be obtained via a linear solve of -:eq:`m_equation`, or by the direct inversion of the spatial momemnts matrix -:math:`M_i`, a :math:`3\times3` symmetric matrix that is defined by purely -geometrical aspects specific to the particular `source region `_ -:math:`i`. However, to accomplish this, we must first know the source moments +:eq:`m_equation`, or by the direct inversion of :math:`M_i`. However, to +accomplish this, we must first know the source moments :math:`\boldsymbol{\vec{q}}_{i,g}`. Fortunately, the source moments are also -defined by the definiton of the source: +defined by the definition of the source: .. math:: :label: source_moments - q_{v, i, g}= \frac{\chi_{i,g}}{k_{eff}} \sum_{g^{\prime}=1}^{G} \nu - \Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G} - \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z)\;\mathrm{,} + q_{v, i, g}= \frac{\chi_{i,g}}{k_{eff}} \sum_{g^{\prime}=1}^{G} \nu + \Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G} + \Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z)\;\mathrm{,} where :math:`v` indicates the direction vector component, and we have introduced the scalar flux moments :math:`\hat{\phi}`. The scalar flux moments can be solved for by taking the `integral definition `_ of a spatial moment, allowing us to derive a "simulation averaged" estimator for the scalar -moment, as in Equation :eq:`phi_sim`, +moment, as in Equation :eq:`phi_sim`, .. math:: :label: scalar_moments_sim @@ -906,7 +904,7 @@ moment, as in Equation :eq:`phi_sim`, \hat{\phi}_{v,i,g}^{simulation} = \frac{\sum\limits_{r=1}^{N_i} \ell_{r} \left[\Omega_{v} \hat{\psi}_{r,i,g} + u_{r,v,0} \bar{\psi}_{r,i,g}\right]} {\Sigma_{t,i,g} \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B}} - \quad \forall v \in(x, y, z)\;\mathrm{,} + \quad \forall v \in(x, y, z)\;\mathrm{,} where the average angular flux is given by Equation :eq:`average_psi_final`, and @@ -915,8 +913,8 @@ the angular flux spatial moments :math:`\hat{\psi}_{r,i,g}` by: .. math:: :label: angular_moments - \hat{\psi}_{r, i, g} = \frac{\ell_{r}\psi^{in}_{r,g}}{2} + - \left(\frac{\bar{Q}_{r,i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) + \hat{\psi}_{r, i, g} = \frac{\ell_{r}\psi^{in}_{r,g}}{2} + + \left(\frac{\bar{Q}_{r,i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right) \frac{G_{1}\left(\tau_{i,g}\right)}{\Sigma_{\mathrm{t}, i, g}} + \frac{\ell_{r}\hat{Q}_{r,i,g}} {2\left(\Sigma_{\mathrm{t}, i, g}\right)^{2}}G_{2}\left(\tau_{i,g}\right)\;\mathrm{.} @@ -935,7 +933,7 @@ The new exponentials introduced, again for simplicity, are simply: The contents of this section, alongside the equations for the flat source and scalar flux, Equations :eq:`source_update` and :eq:`phi_sim` respectively, -completes the set of equations for LS. +completes the set of equations for LS. .. _methods-shannon-entropy-random-ray: @@ -955,7 +953,7 @@ sources is adjusted such that: :label: fraction-source-random-ray S_i = \frac{\text{Fission source in FSR $i \times$ Volume of FSR - $i$}}{\text{Total fission source}} = \frac{Q_{i} V_{i}}{\sum_{i=1}^{i=N} + $i$}}{\text{Total fission source}} = \frac{Q_{i} V_{i}}{\sum_{i=1}^{i=N} Q_{i} V_{i}} The Shannon entropy is then computed normally as @@ -1023,7 +1021,7 @@ in random ray particle transport are: cell are assumed to be spatially uniform. As the source in reality is a continuous function, this leads to bias, although the bias can be reduced to acceptable levels if the flat source regions are sufficiently small. - The bias can also be mitigated by assuming a higher-order source such as the + The bias can also be mitigated by assuming a higher-order source such as the linear source approximation currently implemented into OpenMC. In practical terms, this source of bias can become very large if cells are large (with dimensions beyond that of a typical particle mean free path), @@ -1058,5 +1056,3 @@ in random ray particle transport are: .. [Askew-1972] Askew, “A Characteristics Formulation of the Neutron Transport Equation in Complicated Geometries.” Technical Report AAEW-M 1108, UK Atomic Energy Establishment (1972). - - diff --git a/docs/source/usersguide/random_ray.rst b/docs/source/usersguide/random_ray.rst index 8477274d5de..117d5e23fb5 100644 --- a/docs/source/usersguide/random_ray.rst +++ b/docs/source/usersguide/random_ray.rst @@ -455,9 +455,9 @@ Linear Sources (LS), are supported with the eigenvalue and fixed source random ray solvers. General 3D LS can be toggled by setting the ``source_shape`` field in the :attr:`openmc.Settings.random_ray` dictionary to ``'linear'`` as:: - settings.random_ray['source_shape'] = 'linear' + settings.random_ray['source_shape'] = 'linear' -LS enables the use of coarser mesh discretisations and lower ray populations, +LS enables the use of coarser mesh discretizations and lower ray populations, offsetting the increased computation per ray. While OpenMC has no specific mode for 2D simulations, such simulations can be diff --git a/include/openmc/random_ray/flat_source_domain.h b/include/openmc/random_ray/flat_source_domain.h index a246d601a2d..33c5661dcd4 100644 --- a/include/openmc/random_ray/flat_source_domain.h +++ b/include/openmc/random_ray/flat_source_domain.h @@ -110,8 +110,7 @@ class FlatSourceDomain { void convert_external_sources(); void count_external_source_regions(); virtual void flux_swap(); - virtual double evaluate_flux_at_point( - const Position r, const int64_t sr, const int g) const; + 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/linear_source_domain.h b/include/openmc/random_ray/linear_source_domain.h index 83289c9fe18..5010ffddd6f 100644 --- a/include/openmc/random_ray/linear_source_domain.h +++ b/include/openmc/random_ray/linear_source_domain.h @@ -39,8 +39,7 @@ class LinearSourceDomain : public FlatSourceDomain { void convert_external_sources(); void count_external_source_regions(); void flux_swap() override; - double evaluate_flux_at_point( - const Position r, const int64_t sr, const int g) const override; + double evaluate_flux_at_point(Position r, int64_t sr, int g) const override; //---------------------------------------------------------------------------- // Public Data members @@ -59,4 +58,4 @@ class LinearSourceDomain : public FlatSourceDomain { } // namespace openmc -#endif // OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H \ No newline at end of file +#endif // OPENMC_RANDOM_RAY_LINEAR_SOURCE_DOMAIN_H diff --git a/include/openmc/random_ray/moment_matrix.h b/include/openmc/random_ray/moment_matrix.h index a0a98c1f8c8..c95bb2c1286 100644 --- a/include/openmc/random_ray/moment_matrix.h +++ b/include/openmc/random_ray/moment_matrix.h @@ -9,18 +9,18 @@ namespace openmc { // The MomentArray class is a 3-element array representing the x, y, and z // moments. It is defined as an alias for the Position class to allow for -// dot products and other operations with Position and Direction objects. +// dot products and other operations with Position objects. // TODO: This class could in theory have 32-bit instead of 64-bit FP values. using MomentArray = Position; -// The MomentMatrix class is a sparese representation a 3x3 symmetric +// The MomentMatrix class is a sparse representation a 3x3 symmetric // matrix, with elements labeled as follows: // // | a b c | // | b d e | // | c e f | // -// This class uses FP64 values as objects will be accumulated to over many +// This class uses FP64 values as objects that are accumulated to over many // iterations. class MomentMatrix { public: @@ -87,4 +87,4 @@ class MomentMatrix { } // namespace openmc -#endif // OPENMC_MOMENT_MATRIX_H \ No newline at end of file +#endif // OPENMC_MOMENT_MATRIX_H diff --git a/src/random_ray/flat_source_domain.cpp b/src/random_ray/flat_source_domain.cpp index d1b347544ca..8b6cda93f2a 100644 --- a/src/random_ray/flat_source_domain.cpp +++ b/src/random_ray/flat_source_domain.cpp @@ -752,7 +752,7 @@ void FlatSourceDomain::all_reduce_replicated_source_regions() } double FlatSourceDomain::evaluate_flux_at_point( - const Position r, const int64_t sr, const int g) const + Position r, int64_t sr, int g) const { return scalar_flux_final_[sr * negroups_ + g] / (settings::n_batches - settings::n_inactive); diff --git a/src/random_ray/linear_source_domain.cpp b/src/random_ray/linear_source_domain.cpp index 09c4cd1bb11..1603ec24a4e 100644 --- a/src/random_ray/linear_source_domain.cpp +++ b/src/random_ray/linear_source_domain.cpp @@ -14,8 +14,6 @@ #include "openmc/tallies/tally_scoring.h" #include "openmc/timer.h" -#include - namespace openmc { //============================================================================== @@ -254,7 +252,7 @@ void LinearSourceDomain::all_reduce_replicated_source_regions() } double LinearSourceDomain::evaluate_flux_at_point( - const Position r, const int64_t sr, const int g) const + Position r, int64_t sr, int g) const { float phi_flat = FlatSourceDomain::evaluate_flux_at_point(r, sr, g); @@ -268,4 +266,4 @@ double LinearSourceDomain::evaluate_flux_at_point( return phi_flat + phi_solved.dot(local_r); } -} // namespace openmc \ No newline at end of file +} // namespace openmc