From 2343d27bd235f39aa7dcf3ddd20a503b1be1eb34 Mon Sep 17 00:00:00 2001 From: GuySten Date: Sun, 15 Mar 2026 20:02:41 +0200 Subject: [PATCH 1/2] implement ParticleRay class --- include/openmc/particle_data.h | 2 +- include/openmc/ray.h | 19 ++++++++++++-- src/ray.cpp | 47 ++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/include/openmc/particle_data.h b/include/openmc/particle_data.h index 5b632bbce53..52aba848a10 100644 --- a/include/openmc/particle_data.h +++ b/include/openmc/particle_data.h @@ -484,7 +484,7 @@ class GeometryState { * Algorithms.” Annals of Nuclear Energy 113 (March 2018): 506–18. * https://doi.org/10.1016/j.anucene.2017.11.032. */ -class ParticleData : public GeometryState { +class ParticleData : virtual public GeometryState { private: //========================================================================== // Data members -- see public: below for descriptions diff --git a/include/openmc/ray.h b/include/openmc/ray.h index 62e86b0d90f..1b4ebdb96b4 100644 --- a/include/openmc/ray.h +++ b/include/openmc/ray.h @@ -1,14 +1,14 @@ #ifndef OPENMC_RAY_H #define OPENMC_RAY_H -#include "openmc/particle_data.h" +#include "openmc/particle.h" #include "openmc/position.h" namespace openmc { // Base class that implements ray tracing logic, not necessarily through // defined regions of the geometry but also outside of it. -class Ray : public GeometryState { +class Ray : virtual public GeometryState { public: // Initialize from location and direction @@ -32,6 +32,8 @@ class Ray : public GeometryState { // Sets the dist_ variable void compute_distance(); + virtual void update_distance(); + protected: // Records how far the ray has traveled double traversal_distance_ {0.0}; @@ -46,5 +48,18 @@ class Ray : public GeometryState { unsigned event_counter_ {0}; }; +class ParticleRay : public Ray, public Particle { + +public: + // Sets the dist_ variable + void update_distance() override; + +protected: + // Records how much time passed during travel + double time_distance_ {0.0}; + // Records how much mean free paths the ray traveled + double mfp_distance_ {0.0}; +}; + } // namespace openmc #endif // OPENMC_RAY_H diff --git a/src/ray.cpp b/src/ray.cpp index 3d848e3a3a7..3287d001986 100644 --- a/src/ray.cpp +++ b/src/ray.cpp @@ -2,6 +2,8 @@ #include "openmc/error.h" #include "openmc/geometry.h" +#include "openmc/material.h" +#include "openmc/mgxs_interface.h" #include "openmc/settings.h" namespace openmc { @@ -136,8 +138,8 @@ void Ray::trace() cross_lattice(*this, boundary(), settings::verbosity >= 10); } - // Record how far the ray has traveled - traversal_distance_ += boundary().distance(); + update_distance(); + inside_cell = neighbor_list_find_cell(*this, settings::verbosity >= 10); // Call the specialized logic for this type of ray. Note that we do not @@ -165,4 +167,45 @@ void Ray::trace() } } +void Ray::update_distance() +{ + // Record how far the ray has traveled + traversal_distance_ += boundary().distance(); +} + +void ParticleRay::update_distance() +{ + Ray::update_distance(); + + time_distance_ += speed() * boundary().distance(); + + // Calculate microscopic and macroscopic cross sections + if (material() != MATERIAL_VOID) { + if (settings::run_CE) { + if (material() != material_last() || sqrtkT() != sqrtkT_last() || + density_mult() != density_mult_last()) { + // If the material is the same as the last material and the + // temperature hasn't changed, we don't need to lookup cross + // sections again. + model::materials[material()]->calculate_xs(*this); + } + } else { + // Get the MG data; unlike the CE case above, we have to re-calculate + // cross sections for every collision since the cross sections may + // be angle-dependent + data::mg.macro_xs_[material()].calculate_xs(*this); + + // Update the particle's group while we know we are multi-group + g_last() = g(); + } + } else { + macro_xs().total = 0.0; + macro_xs().absorption = 0.0; + macro_xs().fission = 0.0; + macro_xs().nu_fission = 0.0; + } + + mfp_distance_ += macro_xs().total * boundary().distance(); +} + } // namespace openmc From c19ba54698cf0bce039705b0c7d2f768f2e68019 Mon Sep 17 00:00:00 2001 From: GuySten Date: Mon, 16 Mar 2026 15:12:57 +0200 Subject: [PATCH 2/2] update --- include/openmc/ray.h | 18 +++++++++++++++--- src/ray.cpp | 6 ++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/openmc/ray.h b/include/openmc/ray.h index 1b4ebdb96b4..d4eed886850 100644 --- a/include/openmc/ray.h +++ b/include/openmc/ray.h @@ -51,14 +51,26 @@ class Ray : virtual public GeometryState { class ParticleRay : public Ray, public Particle { public: + ParticleRay( + Position r, Direction u, ParticleType type_, double time_, double E_) + : Ray(r, u) + { + type() = type_; + time() = time_; + E() = E_; + } + + void on_intersection() override; + // Sets the dist_ variable void update_distance() override; + const double& traversal_distance() const { return traversal_distance_; } + const double& traversal_mfp() const { return traversal_mfp_; } + protected: - // Records how much time passed during travel - double time_distance_ {0.0}; // Records how much mean free paths the ray traveled - double mfp_distance_ {0.0}; + double traversal_mfp_ {0.0}; }; } // namespace openmc diff --git a/src/ray.cpp b/src/ray.cpp index 3287d001986..f0667ff5e16 100644 --- a/src/ray.cpp +++ b/src/ray.cpp @@ -173,11 +173,13 @@ void Ray::update_distance() traversal_distance_ += boundary().distance(); } +void ParticleRay::on_intersection() {} + void ParticleRay::update_distance() { Ray::update_distance(); - time_distance_ += speed() * boundary().distance(); + time() += boundary().distance() / speed(); // Calculate microscopic and macroscopic cross sections if (material() != MATERIAL_VOID) { @@ -205,7 +207,7 @@ void ParticleRay::update_distance() macro_xs().nu_fission = 0.0; } - mfp_distance_ += macro_xs().total * boundary().distance(); + traversal_mfp_ += macro_xs().total * boundary().distance(); } } // namespace openmc