Move cross section caches to C++

This commit is contained in:
Paul Romano 2019-02-19 22:43:28 -06:00
parent 34be2851b4
commit 16b2a657d6
11 changed files with 39 additions and 281 deletions

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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});

View file

@ -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

View file

@ -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

View file

@ -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;