Move read_multipole_data to C++

This commit is contained in:
Paul Romano 2019-01-24 14:33:15 -06:00
parent eb576a6fd2
commit 1690dc0af3
7 changed files with 76 additions and 107 deletions

View file

@ -324,7 +324,6 @@ add_library(libopenmc SHARED
src/mesh_header.F90
src/message_passing.F90
src/mgxs_interface.F90
src/multipole_header.F90
src/nuclide_header.F90
src/output.F90
src/particle_header.F90

View file

@ -4,6 +4,7 @@
#include "hdf5.h"
#include "xtensor/xtensor.hpp"
#include <array>
#include <complex>
#include <string>
#include <tuple>
@ -25,6 +26,9 @@ constexpr int FIT_S {0}; // Scattering
constexpr int FIT_A {1}; // Absorption
constexpr int FIT_F {2}; // Fission
// Multipole HDF5 file version
constexpr std::array<int, 2> WMP_VERSION {1, 1};
//========================================================================
// Windowed multipole data
//========================================================================
@ -68,6 +72,21 @@ public:
xt::xtensor<bool, 1> broaden_poly_; //!< Whether to broaden curvefit
};
//========================================================================
// Non-member functions
//========================================================================
//! Check to make sure WMP library data version matches
//!
//! \param[in] file HDF5 file object
void check_wmp_version(hid_t file);
//! \brief Checks for the existence of a multipole library in the directory and
//! loads it
//!
//! \param[in] i_nuclide Index in global nuclides array
void read_multipole_data(int i_nuclide);
} // namespace openmc
#endif // OPENMC_WMP_H

View file

@ -14,6 +14,7 @@
#include "openmc/string_utils.h"
#include "openmc/thermal.h"
#include "openmc/xml_interface.h"
#include "openmc/wmp.h"
#include "pugixml.hpp"
@ -160,7 +161,6 @@ void read_cross_sections_xml()
}
}
extern "C" void read_multipole_data(int i_nuclide);
extern "C" void nuclide_from_hdf5(hid_t group, const Nuclide* ptr,
const double* temps, int n, int n_nuclide);

View file

@ -1858,67 +1858,4 @@ contains
end subroutine normalize_ao
!===============================================================================
! READ_MULTIPOLE_DATA checks for the existence of a multipole library in the
! directory and loads it using multipole_read
!===============================================================================
subroutine read_multipole_data(i_table) bind(C)
integer(C_INT), value :: i_table ! index in nuclides/sab_tables
logical :: file_exists ! Does multipole library exist?
character(7) :: readable ! Is multipole library readable?
character(MAX_FILE_LEN) :: filename ! Path to multipole xs library
integer(HID_T) :: file_id
integer(HID_T) :: group_id
interface
subroutine nuclide_load_multipole(ptr, group) bind(C)
import C_PTR, HID_T
type(C_PTR), value :: ptr
integer(HID_T), value :: group
end subroutine
end interface
associate (nuc => nuclides(i_table))
! Look for WMP data in cross_sections.xml
if (library_present(LIBRARY_WMP, nuc % name)) then
filename = library_path(LIBRARY_WMP, nuc % name)
else
nuc % mp_present = .false.
return
end if
! Check if Multipole library exists and is readable
inquire(FILE=filename, EXIST=file_exists, READ=readable)
if (.not. file_exists) then
nuc % mp_present = .false.
return
elseif (readable(1:3) == 'NO') then
call fatal_error("Multipole library '" // trim(filename) // "' is not &
&readable! Change file permissions with chmod command.")
end if
! Display message
call write_message("Reading " // trim(nuc % name) // " WMP data from " &
// filename, 6)
! Open file and make sure version is sufficient
file_id = file_open(filename, 'r')
call check_wmp_version(file_id)
! Read nuclide data from HDF5
group_id = open_group(file_id, nuc % name)
nuc % mp_present = .true.
call nuclide_load_multipole(nuc % ptr, group_id)
call close_group(group_id)
! Close the file
call file_close(file_id)
end associate
end subroutine read_multipole_data
end module input_xml

View file

@ -1,37 +0,0 @@
module multipole_header
use constants
use hdf5_interface
use error, only: fatal_error
use string, only: to_str
implicit none
contains
!===============================================================================
! CHECK_WMP_VERSION checks for the right version of WMP data within HDF5
! files
!===============================================================================
subroutine check_wmp_version(file_id)
integer(HID_T), intent(in) :: file_id
integer, allocatable :: version(:)
if (attribute_exists(file_id, 'version')) then
call read_attribute(version, file_id, 'version')
if (version(1) /= WMP_VERSION(1)) then
call fatal_error("WMP data format uses version " // trim(to_str(&
version(1))) // "." // trim(to_str(version(2))) // " whereas &
&your installation of OpenMC expects version " // trim(to_str(&
WMP_VERSION(1))) // ".x data.")
end if
else
call fatal_error("WMP data does not indicate a version. Your &
&installation of OpenMC expects version " // trim(to_str(&
WMP_VERSION(1))) // ".x data.")
end if
end subroutine check_wmp_version
end module multipole_header

View file

@ -978,11 +978,6 @@ extern "C" double nuclide_fission_q_recov(Nuclide* nuc, double E)
return nuc->fission_q_recov_ ? (*nuc->fission_q_recov_)(E) : 0.0;
}
extern "C" void nuclide_load_multipole(Nuclide* nuc, hid_t group)
{
nuc->multipole_ = std::make_unique<WindowedMultipole>(group);
}
extern "C" void multipole_deriv_eval(Nuclide* nuc, double E, double sqrtkT,
double* sig_s, double* sig_a, double* sig_f)
{

View file

@ -1,13 +1,20 @@
#include "openmc/wmp.h"
#include "openmc/constants.h"
#include "openmc/cross_sections.h"
#include "openmc/hdf5_interface.h"
#include "openmc/math_functions.h"
#include "openmc/nuclide.h"
#include <cmath>
#include <sstream>
namespace openmc {
//========================================================================
// WindowedeMultipole implementation
//========================================================================
WindowedMultipole::WindowedMultipole(hid_t group)
{
// Get name of nuclide from group, removing leading '/'
@ -184,4 +191,53 @@ WindowedMultipole::evaluate_deriv(double E, double sqrtkT)
return std::make_tuple(sig_s, sig_a, sig_f);
}
//========================================================================
// Non-member functions
//========================================================================
void check_wmp_version(hid_t file)
{
if (attribute_exists(file, "version")) {
std::array<int, 2> version;
read_attribute(file, "version", version);
if (version[0] != WMP_VERSION[0]) {
std::stringstream msg;
msg << "WMP data format uses version " << version[0] << "." <<
version[1] << " whereas your installation of OpenMC expects version "
<< WMP_VERSION[0] << ".x data.";
fatal_error(msg);
}
} else {
fatal_error("WMP data does not indicate a version. Your installation of "
"OpenMC expects version " + std::to_string(WMP_VERSION[0]) + ".x data.");
}
}
void read_multipole_data(int i_nuclide)
{
// Look for WMP data in cross_sections.xml
const auto& nuc {data::nuclides[i_nuclide]};
auto it = data::library_map.find({Library::Type::wmp, nuc->name_});
// If no WMP library for this nuclide, just return
if (it == data::library_map.end()) return;
// Check if WMP library exists
int idx = it->second;
std::string& filename = data::libraries[idx].path_;
// Display message
write_message("Reading " + nuc->name_ + " WMP data from " + filename, 6);
// Open file and make sure version is sufficient
hid_t file = file_open(filename, 'r');
check_wmp_version(file);
// Read nuclide data from HDF5
hid_t group = open_group(file, nuc->name_.c_str());
nuc->multipole_ = std::make_unique<WindowedMultipole>(group);
close_group(group);
file_close(file);
}
} // namespace openmc