mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Move cross section caches to C++
This commit is contained in:
parent
34be2851b4
commit
16b2a657d6
11 changed files with 39 additions and 281 deletions
|
|
@ -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
|
||||
|
|
|
|||
14
src/api.F90
14
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()
|
||||
|
|
|
|||
|
|
@ -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<Library::Type>(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<Library::Type>(type);
|
||||
LibraryKey key {lib_type, name};
|
||||
return data::library_map.find(key) != data::library_map.end();
|
||||
}
|
||||
|
||||
} // namespace openmc
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -774,31 +774,7 @@ std::pair<double, double> 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<int>(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});
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue