From eb576a6fd2814a160c3e082001dffc5639f856b2 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 24 Jan 2019 08:02:40 -0600 Subject: [PATCH] Move remaining functions in mgxs_data.F90 --- CMakeLists.txt | 1 - include/openmc/mgxs_interface.h | 12 ++--- src/initialize.cpp | 1 - src/mgxs_data.F90 | 95 --------------------------------- src/mgxs_interface.F90 | 14 ----- src/mgxs_interface.cpp | 81 ++++++++++++++++++---------- 6 files changed, 57 insertions(+), 147 deletions(-) delete mode 100644 src/mgxs_data.F90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 272a0cca2..9884e7d50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,7 +323,6 @@ add_library(libopenmc SHARED src/math.F90 src/mesh_header.F90 src/message_passing.F90 - src/mgxs_data.F90 src/mgxs_interface.F90 src/multipole_header.F90 src/nuclide_header.F90 diff --git a/include/openmc/mgxs_interface.h b/include/openmc/mgxs_interface.h index 41cc63c1e..a6c9e19c1 100644 --- a/include/openmc/mgxs_interface.h +++ b/include/openmc/mgxs_interface.h @@ -33,17 +33,13 @@ extern std::vector rev_energy_bins; void read_mgxs(); -extern "C" void -add_mgxs_c(hid_t file_id, const std::string& name, +void +add_mgxs(hid_t file_id, const std::string& name, const std::vector& temperature); -extern "C" bool -query_fissionable_c(int n_nuclides, const int i_nuclides[]); +void create_macro_xs(); -extern "C" void -create_macro_xs_c(const char* mat_name, int n_nuclides, const int i_nuclides[], - int n_temps, const double temps[], const double atom_densities[], - double tolerance, int& method); +std::vector> get_mat_kTs(); extern "C" void read_mg_cross_sections_header_c(hid_t file_id); diff --git a/src/initialize.cpp b/src/initialize.cpp index 9f879509a..36abfa718 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -29,7 +29,6 @@ #include "openmc/timer.h" // data/functions from Fortran side -extern "C" void create_macro_xs(); extern "C" void normalize_ao(); extern "C" void print_usage(); extern "C" void print_version(); diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 deleted file mode 100644 index 05e5571fa..000000000 --- a/src/mgxs_data.F90 +++ /dev/null @@ -1,95 +0,0 @@ -module mgxs_data - - use, intrinsic :: ISO_C_BINDING - - use constants - use algorithm, only: find - use dict_header, only: DictCharInt - use error, only: fatal_error, write_message - use geometry_header, only: cells - use hdf5_interface - use material_header, only: Material, materials, n_materials - use mgxs_interface - use nuclide_header, only: n_nuclides - use set_header, only: SetChar - use settings - use stl_vector, only: VectorReal, VectorChar - use string, only: to_lower - implicit none - -contains - -!=============================================================================== -! CREATE_MACRO_XS generates the macroscopic xs from the microscopic input data -!=============================================================================== - - subroutine create_macro_xs() bind(C) - integer :: i_mat ! index in materials array - type(Material), pointer :: mat ! current material - type(VectorReal), allocatable :: kTs(:) - character(MAX_WORD_LEN) :: name ! name of material - - ! Get temperatures to read for each material - call get_mat_kTs(kTs) - - ! Force all nuclides in a material to be the same representation. - ! Therefore type(nuclides(mat % nuclide(1)) % obj) dictates type(macroxs). - ! At the same time, we will find the scattering type, as that will dictate - ! how we allocate the scatter object within macroxs.allocate(macro_xs(n_materials)) - do i_mat = 1, n_materials - - ! Get the material - mat => materials(i_mat) - - name = trim(mat % name) // C_NULL_CHAR - - call create_macro_xs_c(name, mat % n_nuclides, mat % nuclide, & - kTs(i_mat) % size(), kTs(i_mat) % data, mat % atom_density, & - temperature_tolerance, temperature_method) - end do - - end subroutine create_macro_xs - -!=============================================================================== -! GET_MAT_kTs returns a list of temperatures (in eV) that each -! material appears at in the model. -!=============================================================================== - - subroutine get_mat_kTs(kTs) - - type(VectorReal), allocatable, intent(out) :: kTs(:) - integer :: i, j ! Cell and material index - integer :: i_material ! Index in materials array - real(8) :: kT ! temperature in eV - - allocate(kTs(size(materials))) - - do i = 1, size(cells) - ! Skip non-material cells - if (cells(i) % fill() /= C_NONE) cycle - - do j = 1, cells(i) % material_size() - - ! Skip void materials - if (cells(i) % material(j) == MATERIAL_VOID) cycle - - ! Get temperature of cell (rounding to nearest integer) - if (cells(i) % sqrtkT_size() > 1) then - kT = cells(i) % sqrtkT(j-1)**2 - else - kT = cells(i) % sqrtkT(0)**2 - end if - - i_material = cells(i) % material(j) - - ! Add temperature if it hasn't already been added - if (find(kTs(i_material), kT) == -1) then - call kTs(i_material) % push_back(kT) - end if - - end do - end do - - end subroutine get_mat_kTs - -end module mgxs_data diff --git a/src/mgxs_interface.F90 b/src/mgxs_interface.F90 index b09c6a55c..88b3c20e0 100644 --- a/src/mgxs_interface.F90 +++ b/src/mgxs_interface.F90 @@ -7,20 +7,6 @@ module mgxs_interface implicit none interface - subroutine create_macro_xs_c(name, n_nuclides, i_nuclides, n_temps, temps, & - atom_densities, tolerance, method) bind(C) - use ISO_C_BINDING - implicit none - character(kind=C_CHAR),intent(in) :: name(*) - integer(C_INT), value, intent(in) :: n_nuclides - integer(C_INT), intent(in) :: i_nuclides(1:n_nuclides) - integer(C_INT), value, intent(in) :: n_temps - real(C_DOUBLE), intent(in) :: temps(1:n_temps) - real(C_DOUBLE), intent(in) :: atom_densities(1:n_nuclides) - real(C_DOUBLE), value, intent(in) :: tolerance - integer(C_INT), intent(inout) :: method - end subroutine create_macro_xs_c - subroutine calculate_xs_c(i_mat, gin, sqrtkT, uvw, total_xs, abs_xs, & nu_fiss_xs) bind(C) use ISO_C_BINDING diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 88e62ed86..df08a6bb1 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -3,7 +3,9 @@ #include #include +#include "openmc/cell.h" #include "openmc/cross_sections.h" +#include "openmc/container_util.h" #include "openmc/error.h" #include "openmc/file_utils.h" #include "openmc/geometry_aux.h" @@ -84,7 +86,7 @@ void read_mgxs() std::string& name = nuclide_names[i_nuc]; if (already_read.find(name) == already_read.end()) { - add_mgxs_c(file_id, name, nuc_temps[i_nuc]); + add_mgxs(file_id, name, nuc_temps[i_nuc]); already_read.insert(name); } @@ -97,8 +99,10 @@ void read_mgxs() file_close(file_id); } +//============================================================================== + void -add_mgxs_c(hid_t file_id, const std::string& name, +add_mgxs(hid_t file_id, const std::string& name, const std::vector& temperature) { write_message("Loading " + std::string(name) + " data...", 6); @@ -118,43 +122,64 @@ add_mgxs_c(hid_t file_id, const std::string& name, //============================================================================== -bool -query_fissionable_c(int n_nuclides, const int i_nuclides[]) +void create_macro_xs() { - bool result = false; - for (int n = 0; n < n_nuclides; n++) { - if (data::nuclides_MG[i_nuclides[n] - 1].fissionable) result = true; + // Get temperatures to read for each material + auto kTs = get_mat_kTs(); + + // Force all nuclides in a material to be the same representation. + // Therefore type(nuclides[mat->nuclide_[0]]) dictates type(macroxs). + // At the same time, we will find the scattering type, as that will dictate + // how we allocate the scatter object within macroxs. + for (int i = 0; i < model::materials.size(); ++i) { + if (kTs[i].size() > 0) { + // Convert atom_densities to a vector + Material* mat = model::materials[i]; + std::vector atom_densities(mat->atom_density_.begin(), + mat->atom_density_.end()); + + // Build array of pointers to nuclides_MG's Mgxs objects needed for this + // material + std::vector mgxs_ptr; + for (int i_nuclide : mat->nuclide_) { + mgxs_ptr.push_back(&data::nuclides_MG[i_nuclide]); + } + + data::macro_xs.emplace_back(mat->name_, kTs[i], mgxs_ptr, atom_densities); + } else { + // Preserve the ordering of materials by including a blank entry + data::macro_xs.emplace_back(); + } } - return result; } //============================================================================== -void -create_macro_xs_c(const char* mat_name, int n_nuclides, const int i_nuclides[], - int n_temps, const double temps[], const double atom_densities[], - double tolerance, int& method) +std::vector> get_mat_kTs() { - if (n_temps > 0) { - // // Convert temps to a vector - std::vector temperature(temps, temps + n_temps); + std::vector> kTs(model::materials.size()); - // Convert atom_densities to a vector - std::vector atom_densities_vec(atom_densities, - atom_densities + n_nuclides); + for (const auto& cell : model::cells) { + // Skip non-material cells + if (cell->fill_ != C_NONE) continue; - // Build array of pointers to nuclides_MG's Mgxs objects needed for this - // material - std::vector mgxs_ptr(n_nuclides); - for (int n = 0; n < n_nuclides; n++) { - mgxs_ptr[n] = &data::nuclides_MG[i_nuclides[n] - 1]; + for (int j = 0; j < cell->material_.size(); ++j) { + // Skip void materials + int i_material = cell->material_[j]; + if (i_material == MATERIAL_VOID) continue; + + // Get temperature of cell (rounding to nearest integer) + double sqrtkT = cell->sqrtkT_.size() == 1 ? + cell->sqrtkT_[j] : cell->sqrtkT_[0]; + double kT = sqrtkT * sqrtkT; + + // Add temperature if it hasn't already been added + if (!contains(kTs[i_material], kT)) { + kTs[i_material].push_back(kT); + } } - - data::macro_xs.emplace_back(mat_name, temperature, mgxs_ptr, atom_densities_vec); - } else { - // Preserve the ordering of materials by including a blank entry - data::macro_xs.emplace_back(); } + return kTs; } //==============================================================================