diff --git a/include/openmc/photon.h b/include/openmc/photon.h index 3f36decdb3..8ed1431d0c 100644 --- a/include/openmc/photon.h +++ b/include/openmc/photon.h @@ -22,16 +22,35 @@ public: int Z_; //! Atomic number }; +//============================================================================== +//! Cached microscopic photon cross sections for a particular element at the +//! current energy +//============================================================================== + +struct ElementMicroXS { + int index_grid; //!< index on element energy grid + double last_E {0.0}; //!< last evaluated energy in [eV] + double interp_factor; //!< interpolation factor on energy grid + double total; //!< microscopic total photon xs + double coherent; //!< microscopic coherent xs + double incoherent; //!< microscopic incoherent xs + double photoelectric; //!< microscopic photoelectric xs + double pair_production; //!< microscopic pair production xs +}; + //============================================================================== // Global variables //============================================================================== namespace data { - extern std::vector elements; - } // namespace data +namespace simulation { +extern ElementMicroXS* micro_photon_xs; +#pragma omp threadprivate(micro_photon_xs) +} // namespace simulation + } // namespace openmc #endif // OPENMC_PHOTON_H diff --git a/src/nuclide.cpp b/src/nuclide.cpp index 030185f1b4..075e6f55b2 100644 --- a/src/nuclide.cpp +++ b/src/nuclide.cpp @@ -5,6 +5,7 @@ #include "openmc/error.h" #include "openmc/hdf5_interface.h" #include "openmc/message_passing.h" +#include "openmc/photon.h" #include "openmc/random_lcg.h" #include "openmc/search.h" #include "openmc/settings.h" @@ -935,12 +936,14 @@ extern "C" bool multipole_in_range(Nuclide* nuc, double E) extern "C" void nuclides_clear() { data::nuclides.clear(); } extern "C" NuclideMicroXS* micro_xs_ptr(); +extern "C" ElementMicroXS* micro_photon_xs_ptr(); void set_micro_xs() { #pragma omp parallel { simulation::micro_xs = micro_xs_ptr(); + simulation::micro_photon_xs = micro_photon_xs_ptr(); } } diff --git a/src/photon.cpp b/src/photon.cpp index b36f29a5c3..a13d287bf1 100644 --- a/src/photon.cpp +++ b/src/photon.cpp @@ -9,11 +9,13 @@ namespace openmc { //============================================================================== namespace data { - std::vector elements; - } // namespace data +namespace simulation { +ElementMicroXS* micro_photon_xs; +} // namespace simulation + //============================================================================== // PhotonInteraction implementation //============================================================================== diff --git a/src/photon_header.F90 b/src/photon_header.F90 index 9da958a6f4..4be73831d0 100644 --- a/src/photon_header.F90 +++ b/src/photon_header.F90 @@ -1,5 +1,7 @@ module photon_header + use, intrinsic :: ISO_C_BINDING + use algorithm, only: binary_search use constants use dict_header, only: DictIntInt, DictCharInt @@ -92,18 +94,18 @@ module photon_header ! particular element at the current energy !=============================================================================== - type ElementMicroXS - integer :: index_grid ! index on element energy grid - real(8) :: last_E = ZERO ! last evaluated energy - real(8) :: interp_factor ! interpolation factor on energy grid - real(8) :: total ! microscropic total photon xs - real(8) :: coherent ! microscopic coherent xs - real(8) :: incoherent ! microscopic incoherent xs - real(8) :: photoelectric ! microscopic photoelectric xs - real(8) :: pair_production ! microscopic pair production xs + type, bind(C) :: ElementMicroXS + integer(C_INT) :: index_grid ! index on element energy grid + real(C_DOUBLE) :: last_E = ZERO ! last evaluated energy + real(C_DOUBLE) :: interp_factor ! interpolation factor on energy grid + real(C_DOUBLE) :: total ! microscropic total photon xs + real(C_DOUBLE) :: coherent ! microscopic coherent xs + real(C_DOUBLE) :: incoherent ! microscopic incoherent xs + real(C_DOUBLE) :: photoelectric ! microscopic photoelectric xs + real(C_DOUBLE) :: pair_production ! microscopic pair production xs end type ElementMicroXS - type(ElementMicroXS), allocatable :: micro_photon_xs(:) ! Cache for each element + type(ElementMicroXS), allocatable, target :: micro_photon_xs(:) ! Cache for each element !$omp threadprivate(micro_photon_xs) contains @@ -517,4 +519,13 @@ contains if (allocated(ttb)) deallocate(ttb) end subroutine free_memory_photon + function micro_photon_xs_ptr() result(ptr) bind(C) + type(C_PTR) :: ptr + if (size(micro_photon_xs) > 0) then + ptr = C_LOC(micro_photon_xs(1)) + else + ptr = C_NULL_PTR + end if + end function + end module photon_header