From 16b2a657d6eb94418e9014eb1f49de7ecba80885 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 19 Feb 2019 22:43:28 -0600 Subject: [PATCH] Move cross section caches to C++ --- CMakeLists.txt | 3 -- src/api.F90 | 14 +++-- src/cross_sections.cpp | 17 ------ src/input_xml.F90 | 12 ----- src/nuclide.cpp | 14 ----- src/nuclide_header.F90 | 108 --------------------------------------- src/particle_restart.cpp | 16 ++++-- src/photon.cpp | 26 +--------- src/photon_header.F90 | 53 ------------------- src/simulation.F90 | 39 -------------- src/simulation.cpp | 18 +++++-- 11 files changed, 39 insertions(+), 281 deletions(-) delete mode 100644 src/nuclide_header.F90 delete mode 100644 src/photon_header.F90 delete mode 100644 src/simulation.F90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ab7cdb04..59d630e56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -316,14 +316,11 @@ add_library(libopenmc SHARED src/material_header.F90 src/message_passing.F90 src/mgxs_interface.F90 - src/nuclide_header.F90 src/particle_header.F90 - src/photon_header.F90 src/pugixml/pugixml_f.F90 src/relaxng src/settings.F90 src/simulation_header.F90 - src/simulation.F90 src/state_point.F90 src/stl_vector.F90 src/string.F90 diff --git a/src/api.F90 b/src/api.F90 index cb3856861..eca8d5b28 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -60,8 +60,6 @@ contains use bank_header use material_header - use nuclide_header - use photon_header use settings use simulation_header use tally_filter_header @@ -95,8 +93,17 @@ contains subroutine free_memory_geometry() bind(C) end subroutine + subroutine free_memory_photon() bind(C) + end subroutine + subroutine sab_clear() bind(C) end subroutine + + subroutine library_clear() bind(C) + end subroutine + + subroutine nuclides_clear() bind(C) + end subroutine end interface call free_memory_geometry() @@ -104,10 +111,11 @@ contains call free_memory_material() call free_memory_volume() call free_memory_simulation() - call free_memory_nuclide() call free_memory_photon() call free_memory_settings() call sab_clear() + call library_clear() + call nuclides_clear() call free_memory_source() call free_memory_mesh() call free_memory_tally() diff --git a/src/cross_sections.cpp b/src/cross_sections.cpp index 150eb51cb..9a57ff19b 100644 --- a/src/cross_sections.cpp +++ b/src/cross_sections.cpp @@ -427,21 +427,4 @@ extern "C" void library_clear() { data::library_map.clear(); } -extern "C" const char* library_path(int type, const char* name) { - auto lib_type = static_cast(type); - LibraryKey key {lib_type, name}; - if (data::library_map.find(key) == data::library_map.end()) { - return nullptr; - } else { - auto idx = data::library_map[key]; - return data::libraries[idx].path_.c_str(); - } -} - -extern "C" bool library_present(int type, const char* name) { - auto lib_type = static_cast(type); - LibraryKey key {lib_type, name}; - return data::library_map.find(key) != data::library_map.end(); -} - } // namespace openmc diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 8da108e35..0e7668f7e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -11,8 +11,6 @@ module input_xml use material_header use message_passing use mgxs_interface - use nuclide_header - use photon_header use settings use stl_vector, only: VectorInt, VectorReal, VectorChar use string, only: to_lower, to_str, str_to_int, & @@ -54,13 +52,6 @@ contains type(XMLDocument) :: doc type(XMLNode) :: root - interface - function elements_size() bind(C) result(n) - import C_INT - integer(C_INT) :: n - end function - end interface - ! Display output message call write_message("Reading materials XML file...", 5) @@ -89,9 +80,6 @@ contains root = doc % document_element() call read_materials(root % ptr) - ! Set total number of nuclides and elements - n_elements = elements_size() - ! Close materials XML file call doc % clear() diff --git a/src/nuclide.cpp b/src/nuclide.cpp index 9b9a9ef31..8a8d61abf 100644 --- a/src/nuclide.cpp +++ b/src/nuclide.cpp @@ -967,8 +967,6 @@ set_particle_energy_bounds(int particle, double E_min, double E_max) data::energy_max[particle] = E_max; } -extern "C" int nuclides_size() { return data::nuclide_map.size(); } - extern "C" bool multipole_in_range(const Nuclide* nuc, double E) { return nuc->multipole_ && E >= nuc->multipole_->E_min_&& @@ -981,16 +979,4 @@ extern "C" void nuclides_clear() data::nuclide_map.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(); - } -} - } // namespace openmc diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 deleted file mode 100644 index f7fdff531..000000000 --- a/src/nuclide_header.F90 +++ /dev/null @@ -1,108 +0,0 @@ -module nuclide_header - - use, intrinsic :: ISO_FORTRAN_ENV - use, intrinsic :: ISO_C_BINDING - - use constants - - implicit none - -!=============================================================================== -! NUCLIDEMICROXS contains cached microscopic cross sections for a particular -! nuclide at the current energy -!=============================================================================== - - ! Arbitrary value to indicate invalid cache state for elastic scattering - ! (NuclideMicroXS % elastic) - real(8), parameter :: CACHE_INVALID = -1 - - type, bind(C) :: NuclideMicroXS - ! Microscopic cross sections in barns - real(C_DOUBLE) :: total - real(C_DOUBLE) :: absorption ! absorption (disappearance) - real(C_DOUBLE) :: fission ! fission - real(C_DOUBLE) :: nu_fission ! neutron production from fission - - real(C_DOUBLE) :: elastic ! If sab_frac is not 1 or 0, then this value is - ! averaged over bound and non-bound nuclei - real(C_DOUBLE) :: thermal ! Bound thermal elastic & inelastic scattering - real(C_DOUBLE) :: thermal_elastic ! Bound thermal elastic scattering - real(C_DOUBLE) :: photon_prod ! microscopic photon production xs - - ! Cross sections for depletion reactions (note that these are not stored in - ! macroscopic cache) - real(C_DOUBLE) :: reaction(6) - - ! Indicies and factors needed to compute cross sections from the data tables - integer(C_INT) :: index_grid ! Index on nuclide energy grid - integer(C_INT) :: index_temp ! Temperature index for nuclide - real(C_DOUBLE) :: interp_factor ! Interpolation factor on nuc. energy grid - integer(C_INT) :: index_sab = NONE ! Index in sab_tables - integer(C_INT) :: index_temp_sab ! Temperature index for sab_tables - real(C_DOUBLE) :: sab_frac ! Fraction of atoms affected by S(a,b) - logical(C_BOOL) :: use_ptable ! In URR range with probability tables? - - ! Energy and temperature last used to evaluate these cross sections. If - ! these values have changed, then the cross sections must be re-evaluated. - real(C_DOUBLE) :: last_E = ZERO ! Last evaluated energy - real(C_DOUBLE) :: last_sqrtkT = ZERO ! Last temperature in sqrt(Boltzmann - ! constant * temperature (eV)) - end type NuclideMicroXS - -!=============================================================================== -! MATERIALMACROXS contains cached macroscopic cross sections for the material a -! particle is traveling through -!=============================================================================== - - type, bind(C) :: MaterialMacroXS - real(C_DOUBLE) :: total ! macroscopic total xs - real(C_DOUBLE) :: absorption ! macroscopic absorption xs - real(C_DOUBLE) :: fission ! macroscopic fission xs - real(C_DOUBLE) :: nu_fission ! macroscopic production xs - real(C_DOUBLE) :: photon_prod ! macroscopic photon production xs - - ! Photon cross sections - real(C_DOUBLE) :: coherent ! macroscopic coherent xs - real(C_DOUBLE) :: incoherent ! macroscopic incoherent xs - real(C_DOUBLE) :: photoelectric ! macroscopic photoelectric xs - real(C_DOUBLE) :: pair_production ! macroscopic pair production xs - end type MaterialMacroXS - - ! Cross section caches - type(NuclideMicroXS), allocatable, target :: micro_xs(:) ! Cache for each nuclide -!$omp threadprivate(micro_xs) - - interface - function nuclides_size() bind(C) result(n) - import C_INT - integer(C_INT) :: n - end function - end interface - -contains - - function micro_xs_ptr() result(ptr) bind(C) - type(C_PTR) :: ptr - ptr = C_LOC(micro_xs(1)) - end function - - -!=============================================================================== -! FREE_MEMORY_NUCLIDE deallocates global arrays defined in this module -!=============================================================================== - - subroutine free_memory_nuclide() - interface - subroutine library_clear() bind(C) - end subroutine - - subroutine nuclides_clear() bind(C) - end subroutine - end interface - - call nuclides_clear() - call library_clear() - - end subroutine free_memory_nuclide - -end module nuclide_header diff --git a/src/particle_restart.cpp b/src/particle_restart.cpp index 89781bb6c..19dd50d77 100644 --- a/src/particle_restart.cpp +++ b/src/particle_restart.cpp @@ -6,6 +6,7 @@ #include "openmc/nuclide.h" #include "openmc/output.h" #include "openmc/particle.h" +#include "openmc/photon.h" #include "openmc/random_lcg.h" #include "openmc/settings.h" #include "openmc/simulation.h" @@ -71,8 +72,12 @@ void run_particle_restart() // Set verbosity high settings::verbosity = 10; - simulation_init_f(); - set_micro_xs(); + // Create cross section caches + #pragma omp parallel + { + simulation::micro_xs = new NuclideMicroXS[data::nuclides.size()]; + simulation::micro_photon_xs = new ElementMicroXS[data::elements.size()]; + } // Initialize the particle to be tracked Particle p; @@ -103,7 +108,12 @@ void run_particle_restart() // Write output if particle made it print_particle(&p); - simulation_finalize_f(); + // Clear cross section caches + #pragma omp parallel + { + delete[] simulation::micro_xs; + delete[] simulation::micro_photon_xs; + } } } // namespace openmc diff --git a/src/photon.cpp b/src/photon.cpp index 0dff1d47f..d3fa9f465 100644 --- a/src/photon.cpp +++ b/src/photon.cpp @@ -774,31 +774,7 @@ std::pair klein_nishina(double alpha) // Fortran compatibility //============================================================================== -extern "C" void photon_from_hdf5(hid_t group) -{ - data::elements.emplace_back(group, data::elements.size()); - - // Determine if minimum/maximum energy for this element is greater/less than - // the previous - const auto& element {data::elements.back()}; - if (element.energy_.size() >= 1) { - int photon = static_cast(ParticleType::photon); - int n = element.energy_.size(); - data::energy_min[photon] = std::max(data::energy_min[photon], - std::exp(element.energy_(1))); - data::energy_max[photon] = std::min(data::energy_max[photon], - std::exp(element.energy_(n - 1))); - } -} - -extern "C" int elements_size() { return data::element_map.size(); } - -extern "C" void photon_calculate_xs(int i_element, double E) -{ - data::elements[i_element - 1].calculate_xs(E); -} - -extern "C" void free_memory_photon_c() +extern "C" void free_memory_photon() { data::elements.clear(); data::compton_profile_pz.resize({0}); diff --git a/src/photon_header.F90 b/src/photon_header.F90 deleted file mode 100644 index f5d9aad66..000000000 --- a/src/photon_header.F90 +++ /dev/null @@ -1,53 +0,0 @@ -module photon_header - - use, intrinsic :: ISO_C_BINDING - - use constants - - integer :: n_elements ! Number of photon cross section tables - -!=============================================================================== -! ELEMENTMICROXS contains cached microscopic photon cross sections for a -! particular element at the current energy -!=============================================================================== - - 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, target :: micro_photon_xs(:) ! Cache for each element -!$omp threadprivate(micro_photon_xs) - -contains - -!=============================================================================== -! FREE_MEMORY_PHOTON deallocates/resets global variables in this module -!=============================================================================== - - subroutine free_memory_photon() - interface - subroutine free_memory_photon_c() bind(C) - end subroutine - end interface - - ! Deallocate photon cross section data - n_elements = 0 - 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 diff --git a/src/simulation.F90 b/src/simulation.F90 deleted file mode 100644 index 2a521807d..000000000 --- a/src/simulation.F90 +++ /dev/null @@ -1,39 +0,0 @@ -module simulation - - use, intrinsic :: ISO_C_BINDING - - use nuclide_header, only: micro_xs, nuclides_size - use photon_header, only: micro_photon_xs, n_elements - - implicit none - private - -contains - -!=============================================================================== -! INITIALIZE_SIMULATION -!=============================================================================== - - subroutine simulation_init_f() bind(C) - -!$omp parallel - ! Allocate array for microscopic cross section cache - allocate(micro_xs(nuclides_size())) - allocate(micro_photon_xs(n_elements)) -!$omp end parallel - - end subroutine - -!=============================================================================== -! FINALIZE_SIMULATION calculates tally statistics, writes tallies, and displays -! execution time and results -!=============================================================================== - - subroutine simulation_finalize_f() bind(C) - ! Free up simulation-specific memory -!$omp parallel - deallocate(micro_xs, micro_photon_xs) -!$omp end parallel - end subroutine - -end module simulation diff --git a/src/simulation.cpp b/src/simulation.cpp index 096ea87ff..89bd93421 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -10,6 +10,7 @@ #include "openmc/nuclide.h" #include "openmc/output.h" #include "openmc/particle.h" +#include "openmc/photon.h" #include "openmc/random_lcg.h" #include "openmc/settings.h" #include "openmc/source.h" @@ -84,9 +85,12 @@ int openmc_simulation_init() mat->init_nuclide_index(); } - // Call Fortran initialization - simulation_init_f(); - set_micro_xs(); + // Create cross section caches + #pragma omp parallel + { + simulation::micro_xs = new NuclideMicroXS[data::nuclides.size()]; + simulation::micro_photon_xs = new ElementMicroXS[data::elements.size()]; + } // Reset global variables -- this is done before loading state point (as that // will potentially populate k_generation and entropy) @@ -135,7 +139,13 @@ int openmc_simulation_finalize() for (auto& mat : model::materials) { mat->mat_nuclide_index_.clear(); } - simulation_finalize_f(); + + // Clear cross section caches + #pragma omp parallel + { + delete[] simulation::micro_xs; + delete[] simulation::micro_photon_xs; + } // Increment total number of generations simulation::total_gen += simulation::current_batch*settings::gen_per_batch;