mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 13:15:39 -04:00
Move Cell.distribcell_index to C++
This commit is contained in:
parent
43c554583a
commit
ef8bf2b820
8 changed files with 114 additions and 109 deletions
|
|
@ -4,7 +4,6 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "constants.h"
|
||||
#include "error.h"
|
||||
#include "geometry.h"
|
||||
#include "hdf5_interface.h"
|
||||
|
|
@ -617,6 +616,8 @@ extern "C" {
|
|||
|
||||
int32_t cell_n_instances(Cell* c) {return c->n_instances;}
|
||||
|
||||
int cell_distribcell_index(Cell* c) {return c->distribcell_index;}
|
||||
|
||||
int cell_material_size(Cell* c) {return c->material.size();}
|
||||
|
||||
//TODO: off-by-one
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "constants.h"
|
||||
#include "hdf5.h"
|
||||
#include "pugixml.hpp"
|
||||
|
||||
|
|
@ -64,6 +65,9 @@ public:
|
|||
int32_t fill; //!< Universe # filling this cell
|
||||
int32_t n_instances{0}; //!< Number of instances of this cell
|
||||
|
||||
//! \brief Index corresponding to this cell in distribcell arrays
|
||||
int distribcell_index{C_NONE};
|
||||
|
||||
//! \brief Material(s) within this cell.
|
||||
//!
|
||||
//! May be multiple materials for distribcell.
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ contains
|
|||
! Distributed instances of this cell have different
|
||||
! materials/temperatures. Determine which instance this is for
|
||||
! assigning the matching material/temperature.
|
||||
distribcell_index = c % distribcell_index
|
||||
distribcell_index = c % distribcell_index()
|
||||
offset = 0
|
||||
do k = 1, p % n_coord
|
||||
if (cells(p % coord(k) % cell) % type() == FILL_UNIVERSE) then
|
||||
|
|
|
|||
|
|
@ -153,17 +153,90 @@ find_root_universe()
|
|||
//==============================================================================
|
||||
|
||||
void
|
||||
allocate_offset_tables(int n_maps)
|
||||
prepare_distribcell(int32_t* filter_cell_list, int n)
|
||||
{
|
||||
// Read the list of cells contained in distribcell filters from Fortran.
|
||||
std::unordered_set<int32_t> distribcells;
|
||||
for (int i = 0; i < n; i++) {
|
||||
distribcells.insert(filter_cell_list[i]);
|
||||
}
|
||||
|
||||
// Find all cells with distributed materials or temperatures. Make sure that
|
||||
// the number of materials/temperatures matches the number of cell instances.
|
||||
for (int i = 0; i < global_cells.size(); i++) {
|
||||
Cell& c {*global_cells[i]};
|
||||
|
||||
if (c.material.size() > 1) {
|
||||
if (c.material.size() != c.n_instances) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Cell " << c.id << " was specified with "
|
||||
<< c.material.size() << " materials but has " << c.n_instances
|
||||
<< " distributed instances. The number of materials must equal "
|
||||
"one or the number of instances.";
|
||||
fatal_error(err_msg);
|
||||
}
|
||||
distribcells.insert(i);
|
||||
}
|
||||
|
||||
if (c.sqrtkT.size() > 1) {
|
||||
if (c.sqrtkT.size() != c.n_instances) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Cell " << c.id << " was specified with "
|
||||
<< c.sqrtkT.size() << " temperatures but has " << c.n_instances
|
||||
<< " distributed instances. The number of temperatures must equal "
|
||||
"one or the number of instances.";
|
||||
fatal_error(err_msg);
|
||||
}
|
||||
distribcells.insert(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Search through universes for distributed cells and assign each one a
|
||||
// unique distribcell array index.
|
||||
//TODO: off-by-one
|
||||
int distribcell_index = 1;
|
||||
std::vector<int32_t> target_univ_ids;
|
||||
for (Universe* u : global_universes) {
|
||||
for (auto cell_indx : u->cells) {
|
||||
if (distribcells.find(cell_indx) != distribcells.end()) {
|
||||
global_cells[cell_indx]->distribcell_index = distribcell_index;
|
||||
target_univ_ids.push_back(u->id);
|
||||
++distribcell_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the cell and lattice offset tables.
|
||||
int n_maps = target_univ_ids.size();
|
||||
for (Cell* c : global_cells) {
|
||||
if (c->type != FILL_MATERIAL) {
|
||||
c->offset.resize(n_maps, C_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
for (Lattice* lat : lattices_c) {
|
||||
lat->allocate_offset_table(n_maps);
|
||||
}
|
||||
|
||||
// Fill the cell and lattice offset tables.
|
||||
for (int map = 0; map < target_univ_ids.size(); map++) {
|
||||
auto target_univ_id = target_univ_ids[map];
|
||||
for (Universe* univ : global_universes) {
|
||||
int32_t offset {0}; // TODO: is this a bug? It matches F90 implementation.
|
||||
for (int32_t cell_indx : univ->cells) {
|
||||
Cell& c = *global_cells[cell_indx];
|
||||
|
||||
if (c.type == FILL_UNIVERSE) {
|
||||
c.offset[map] = offset;
|
||||
int32_t search_univ = c.fill;
|
||||
offset += count_universe_instances(search_univ, target_univ_id);
|
||||
|
||||
} else if (c.type == FILL_LATTICE) {
|
||||
Lattice& lat = *lattices_c[c.fill];
|
||||
offset = lat.fill_offset_table(offset, target_univ_id, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -221,29 +294,6 @@ count_universe_instances(int32_t search_univ, int32_t target_univ_id)
|
|||
|
||||
//==============================================================================
|
||||
|
||||
void
|
||||
fill_offset_tables(int32_t target_univ_id, int map)
|
||||
{
|
||||
for (Universe* univ : global_universes) {
|
||||
int32_t offset {0}; // TODO: is this a bug? It matches F90 implementation.
|
||||
for (int32_t cell_indx : univ->cells) {
|
||||
Cell& c = *global_cells[cell_indx];
|
||||
|
||||
if (c.type == FILL_UNIVERSE) {
|
||||
c.offset[map] = offset;
|
||||
int32_t search_univ = c.fill;
|
||||
offset += count_universe_instances(search_univ, target_univ_id);
|
||||
|
||||
} else if (c.type == FILL_LATTICE) {
|
||||
Lattice& lat = *lattices_c[c.fill];
|
||||
offset = lat.fill_offset_table(offset, target_univ_id, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
std::string
|
||||
distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset,
|
||||
const Universe& search_univ, int32_t offset)
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ extern "C" void assign_temperatures();
|
|||
extern "C" int32_t find_root_universe();
|
||||
|
||||
//==============================================================================
|
||||
//! Allocate storage in Lattice and Cell objects for distribcell offset tables.
|
||||
//! Populate all data structures needed for distribcells.
|
||||
//==============================================================================
|
||||
|
||||
extern "C" void allocate_offset_tables(int n_maps);
|
||||
extern "C" void prepare_distribcell(int32_t* filter_cell_list, int n);
|
||||
|
||||
//==============================================================================
|
||||
//! Recursively search through the geometry and count cell instances.
|
||||
|
|
@ -59,15 +59,6 @@ extern "C" void count_cell_instances(int32_t univ_indx);
|
|||
extern "C" int
|
||||
count_universe_instances(int32_t search_univ, int32_t target_univ_id);
|
||||
|
||||
//==============================================================================
|
||||
//! Populate Cell and Lattice distribcell offset tables.
|
||||
//! @param target_univ_id The ID of the universe to be counted.
|
||||
//! @param map The index of the distribcell map that defines the offsets for the
|
||||
//! target universe.
|
||||
//==============================================================================
|
||||
|
||||
extern "C" void fill_offset_tables(int32_t target_univ_id, int map);
|
||||
|
||||
//==============================================================================
|
||||
//! Find the length necessary for a string to contain a distribcell path.
|
||||
//! @param target_cell The index of the Cell in the global Cell array.
|
||||
|
|
|
|||
|
|
@ -60,6 +60,13 @@ module geometry_header
|
|||
integer(C_INT32_T) :: n_instances
|
||||
end function cell_n_instances_c
|
||||
|
||||
function cell_distribcell_index_c(cell_ptr) &
|
||||
bind(C, name='cell_distribcell_index') result(distribcell_index)
|
||||
import C_PTR, C_INT
|
||||
type(C_PTR), intent(in), value :: cell_ptr
|
||||
integer(C_INT) :: distribcell_index
|
||||
end function cell_distribcell_index_c
|
||||
|
||||
function cell_material_size_c(cell_ptr) bind(C, name='cell_material_size') &
|
||||
result(n)
|
||||
import C_PTR, C_INT
|
||||
|
|
@ -266,8 +273,6 @@ module geometry_header
|
|||
|
||||
integer, allocatable :: region(:) ! Definition of spatial region as
|
||||
! Boolean expression of half-spaces
|
||||
integer :: distribcell_index ! Index corresponding to this cell in
|
||||
! distribcell arrays
|
||||
|
||||
! Rotation matrix and translation vector
|
||||
real(8), allocatable :: translation(:)
|
||||
|
|
@ -282,6 +287,7 @@ module geometry_header
|
|||
procedure :: universe => cell_universe
|
||||
procedure :: fill => cell_fill
|
||||
procedure :: n_instances => cell_n_instances
|
||||
procedure :: distribcell_index => cell_distribcell_index
|
||||
procedure :: material_size => cell_material_size
|
||||
procedure :: material => cell_material
|
||||
procedure :: sqrtkT_size => cell_sqrtkT_size
|
||||
|
|
@ -414,6 +420,12 @@ contains
|
|||
n_instances = cell_n_instances_c(this % ptr)
|
||||
end function cell_n_instances
|
||||
|
||||
function cell_distribcell_index(this) result(distribcell_index)
|
||||
class(Cell), intent(in) :: this
|
||||
integer(C_INT) :: distribcell_index
|
||||
distribcell_index = cell_distribcell_index_c(this % ptr)
|
||||
end function cell_distribcell_index
|
||||
|
||||
function cell_material_size(this) result(n)
|
||||
class(Cell), intent(in) :: this
|
||||
integer(C_INT) :: n
|
||||
|
|
|
|||
|
|
@ -51,25 +51,21 @@ module input_xml
|
|||
subroutine adjust_indices() bind(C)
|
||||
end subroutine adjust_indices
|
||||
|
||||
subroutine allocate_offset_tables(n_maps) bind(C)
|
||||
import C_INT
|
||||
integer(C_INT), intent(in), value :: n_maps
|
||||
end subroutine allocate_offset_tables
|
||||
|
||||
subroutine assign_temperatures() bind(C)
|
||||
end subroutine assign_temperatures
|
||||
|
||||
subroutine fill_offset_tables(target_univ_id, map) bind(C)
|
||||
import C_INT32_T, C_INT
|
||||
integer(C_INT32_T), intent(in), value :: target_univ_id
|
||||
integer(C_INT), intent(in), value :: map
|
||||
end subroutine fill_offset_tables
|
||||
|
||||
subroutine count_cell_instances(univ_indx) bind(C)
|
||||
import C_INT32_T
|
||||
integer(C_INT32_T), intent(in), value :: univ_indx
|
||||
end subroutine count_cell_instances
|
||||
|
||||
subroutine prepare_distribcell_c(cell_list, n) &
|
||||
bind(C, name="prepare_distribcell")
|
||||
import C_INT32_T, C_INT
|
||||
integer(C_INT), intent(in), value :: n
|
||||
integer(C_INT32_T), intent(in) :: cell_list(n)
|
||||
end subroutine prepare_distribcell_c
|
||||
|
||||
subroutine read_surfaces(node_ptr) bind(C)
|
||||
import C_PTR
|
||||
type(C_PTR) :: node_ptr
|
||||
|
|
@ -1007,7 +1003,7 @@ contains
|
|||
subroutine read_geometry_xml()
|
||||
|
||||
integer :: i, j, k
|
||||
integer :: n, n_mats, n_rlats, n_hlats
|
||||
integer :: n, n_rlats, n_hlats
|
||||
integer :: id
|
||||
integer :: univ_id
|
||||
integer :: n_cells_in_univ
|
||||
|
|
@ -1015,7 +1011,6 @@ contains
|
|||
logical :: file_exists
|
||||
logical :: boundary_exists
|
||||
character(MAX_LINE_LEN) :: filename
|
||||
character(MAX_WORD_LEN), allocatable :: sarray(:)
|
||||
character(:), allocatable :: region_spec
|
||||
type(Cell), pointer :: c
|
||||
class(Lattice), pointer :: lat
|
||||
|
|
@ -1100,9 +1095,6 @@ contains
|
|||
|
||||
c % ptr = cell_pointer(i - 1)
|
||||
|
||||
! Initialize distribcell instances and distribcell index
|
||||
c % distribcell_index = NONE
|
||||
|
||||
! Get pointer to i-th cell node
|
||||
node_cell = node_cell_list(i)
|
||||
|
||||
|
|
@ -3821,9 +3813,9 @@ contains
|
|||
|
||||
subroutine prepare_distribcell()
|
||||
|
||||
integer :: i, j, k
|
||||
integer :: i, j
|
||||
type(SetInt) :: cell_list ! distribcells to track
|
||||
type(ListInt) :: univ_list ! universes containing distribcells
|
||||
integer(C_INT32_T), allocatable :: cell_list_c(:)
|
||||
|
||||
! Find all cells listed in a distribcell filter.
|
||||
do i = 1, n_tallies
|
||||
|
|
@ -3835,56 +3827,11 @@ contains
|
|||
end do
|
||||
end do
|
||||
|
||||
! Find all cells with multiple (distributed) materials or temperatures.
|
||||
do i = 1, n_cells
|
||||
if (cells(i) % material_size() > 1 .or. cells(i) % sqrtkT_size() > 1) then
|
||||
call cell_list % add(i)
|
||||
end if
|
||||
end do
|
||||
|
||||
! Make sure the number of distributed materials and temperatures matches the
|
||||
! number of respective cell instances.
|
||||
do i = 1, n_cells
|
||||
associate (c => cells(i))
|
||||
if (c % material_size() > 1) then
|
||||
if (c % material_size() /= c % n_instances()) then
|
||||
call fatal_error("Cell " // trim(to_str(c % id())) // " was &
|
||||
&specified with " // trim(to_str(c % material_size())) &
|
||||
// " materials but has " // trim(to_str(c % n_instances())) &
|
||||
// " distributed instances. The number of materials must &
|
||||
&equal one or the number of instances.")
|
||||
end if
|
||||
end if
|
||||
if (c % sqrtkT_size() > 1) then
|
||||
if (c % sqrtkT_size() /= c % n_instances()) then
|
||||
call fatal_error("Cell " // trim(to_str(c % id())) // " was &
|
||||
&specified with " // trim(to_str(c % sqrtkT_size())) &
|
||||
// " temperatures but has " // trim(to_str(c % n_instances()))&
|
||||
// " distributed instances. The number of temperatures must &
|
||||
&equal one or the number of instances.")
|
||||
end if
|
||||
end if
|
||||
end associate
|
||||
end do
|
||||
|
||||
! Search through universes for distributed cells and assign each one a
|
||||
! unique distribcell array index.
|
||||
k = 1
|
||||
do i = 1, n_universes
|
||||
do j = 1, size(universes(i) % cells)
|
||||
if (cell_list % contains(universes(i) % cells(j))) then
|
||||
cells(universes(i) % cells(j)) % distribcell_index = k
|
||||
call univ_list % append(universes(i) % id)
|
||||
k = k + 1
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
|
||||
! Allocate and fill cell and lattice offset tables.
|
||||
call allocate_offset_tables(univ_list % size())
|
||||
do i = 1, univ_list % size()
|
||||
call fill_offset_tables(univ_list % get_item(i), i-1)
|
||||
allocate(cell_list_c(cell_list % size()))
|
||||
do i = 1, cell_list % size()
|
||||
cell_list_c(i) = cell_list % get_item(i) - 1
|
||||
end do
|
||||
call prepare_distribcell_c(cell_list_c, cell_list % size())
|
||||
|
||||
end subroutine prepare_distribcell
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ contains
|
|||
|
||||
integer :: distribcell_index, offset, i
|
||||
|
||||
distribcell_index = cells(this % cell) % distribcell_index
|
||||
distribcell_index = cells(this % cell) % distribcell_index()
|
||||
offset = 0
|
||||
do i = 1, p % n_coord
|
||||
if (cells(p % coord(i) % cell) % type() == FILL_UNIVERSE) then
|
||||
|
|
@ -154,7 +154,7 @@ contains
|
|||
end interface
|
||||
|
||||
! Get the distribcell index for this cell
|
||||
map = cells(i_cell) % distribcell_index
|
||||
map = cells(i_cell) % distribcell_index()
|
||||
|
||||
path_len = distribcell_path_len(i_cell-1, map-1, target_offset, &
|
||||
root_universe-1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue