From 2343d27bd235f39aa7dcf3ddd20a503b1be1eb34 Mon Sep 17 00:00:00 2001 From: GuySten Date: Sun, 15 Mar 2026 20:02:41 +0200 Subject: [PATCH] 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 5b632bbce5..52aba848a1 100644 --- a/include/openmc/particle_data.h +++ b/include/openmc/particle_data.h @@ -484,7 +484,7 @@ private: * 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 62e86b0d90..1b4ebdb96b 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 @@ public: // 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 @@ private: 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 3d848e3a3a..3287d00198 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