From 64ae9949263aa9e9944b795b4397d1a3d0fe5719 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 14 Aug 2018 16:22:40 -0400 Subject: [PATCH 01/43] Add check_cell_overlap to C++ --- CMakeLists.txt | 1 + src/cell.cpp | 5 +++++ src/geometry.F90 | 14 ++++++++++++- src/geometry.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ src/geometry.h | 5 +++++ src/output.F90 | 9 +++++++++ 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/geometry.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c94f4df5fd..673a714926 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -386,6 +386,7 @@ add_library(libopenmc SHARED src/cell.cpp src/initialize.cpp src/finalize.cpp + src/geometry.cpp src/geometry_aux.cpp src/hdf5_interface.cpp src/lattice.cpp diff --git a/src/cell.cpp b/src/cell.cpp index acf1473bb8..2bcea24f6f 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -7,8 +7,10 @@ #include "constants.h" #include "error.h" +#include "geometry.h" #include "hdf5_interface.h" #include "lattice.h" +#include "settings.h" #include "surface.h" #include "xml_interface.h" @@ -460,6 +462,9 @@ read_cells(pugi::xml_node *node) global_universes[it->second]->cells.push_back(i); } } + + // Allocate the cell overlap count if necessary. + if (openmc_check_overlaps) overlap_check_count.resize(n_cells, 0); } //============================================================================== diff --git a/src/geometry.F90 b/src/geometry.F90 index 5bf0012a38..aa2689e35f 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -31,7 +31,14 @@ module geometry integer(C_INT32_T), intent(in), value :: search_univ integer(C_INT32_T), intent(in), value :: target_univ_id integer(C_INT) :: count - end function + end function count_universe_instances + + function check_cell_overlap_c(p) bind(C, name="check_cell_overlap") & + result(is_overlapping) + import Particle, C_BOOL + type(Particle), intent(in) :: p + logical(C_BOOL) :: is_overlapping + end function check_cell_overlap_c end interface contains @@ -60,6 +67,9 @@ contains integer :: index_cell ! index in cells array type(Cell), pointer :: c ! pointer to cell type(Universe), pointer :: univ ! universe to search in + logical :: overlap_c + + overlap_c = check_cell_overlap_c(p) ! loop through each coordinate level n_coord = p % n_coord @@ -76,6 +86,7 @@ contains if (cell_contains(c, p)) then ! the particle should only be contained in one cell per level if (index_cell /= p % coord(j) % cell) then + if (.not. overlap_c) call fatal_error("Cell overlap disagreement") call fatal_error("Overlapping cells detected: " & &// trim(to_str(cells(index_cell) % id())) // ", " & &// trim(to_str(cells(p % coord(j) % cell) % id())) & @@ -88,6 +99,7 @@ contains end do end do + if (overlap_c) call fatal_error("Cell overlap disagreement") end subroutine check_cell_overlap diff --git a/src/geometry.cpp b/src/geometry.cpp new file mode 100644 index 0000000000..3c38e67164 --- /dev/null +++ b/src/geometry.cpp @@ -0,0 +1,52 @@ +#include "geometry.h" + +#include + +#include "cell.h" +#include "error.h" +#include "particle.h" + +//TODO: remove this include +#include + + +namespace openmc { + +std::vector overlap_check_count; + +extern "C" bool +check_cell_overlap(Particle* p) { + int n_coord = p->n_coord; + + // loop through each coordinate level + for (int j = 0; j < n_coord; j++) { + //p->n_coord = j + 1; + Universe& univ {*global_universes[p->coord[j].universe - 1]}; + int n = univ.cells.size(); + + // loop through each cell on this level + for (int i = 0; i < n; i++) { + int index_cell = univ.cells[i]; + Cell& c {*global_cells[index_cell]}; + + if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { + //TODO: off-by-one indexing + if (index_cell != p->coord[j].cell - 1) { + std::stringstream err_msg; + err_msg << "Overlapping cells detected: " << c.id << ", " + << global_cells[p->coord[j].cell-1]->id << " on universe " + << univ.id; + fatal_error(err_msg); + } + ++overlap_check_count[index_cell]; + } + } + } + + return false; +} + +extern "C" int64_t get_overlap_check_count(int i) +{return overlap_check_count[i];} + +} // namespace openmc diff --git a/src/geometry.h b/src/geometry.h index 09e7eda8eb..7d345b102e 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -1,10 +1,15 @@ #ifndef OPENMC_GEOMETRY_H #define OPENMC_GEOMETRY_H +#include +#include + namespace openmc { extern "C" int openmc_root_universe; +extern std::vector overlap_check_count; + } // namespace openmc #endif // OPENMC_GEOMETRY_H diff --git a/src/output.F90 b/src/output.F90 index 49dc380a9c..760a305036 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -628,6 +628,14 @@ contains subroutine print_overlap_check + interface + function get_overlap_check_count(index_cell) result(count) bind(C) + import C_INT, C_INT64_T + integer(C_INT), intent(in), value :: index_cell + integer(C_INT64_T) :: count + end function get_overlap_check_count + end interface + integer :: i, j integer :: num_sparse = 0 @@ -638,6 +646,7 @@ contains do i = 1, n_cells write(ou,101) cells(i) % id(), overlap_check_cnt(i) + write(ou,101) cells(i) % id(), get_overlap_check_count(i-1) if (overlap_check_cnt(i) < 10) num_sparse = num_sparse + 1 end do write(ou,*) From 5d9cb16dff15dce7e43cfeb984d13ad758f6589e Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 14 Aug 2018 19:04:05 -0400 Subject: [PATCH 02/43] Move all cell overlap code to C++ --- CMakeLists.txt | 1 + src/geometry.F90 | 60 ++----------------------------------- src/geometry.cpp | 3 -- src/output.F90 | 45 ---------------------------- src/output.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++ src/output.h | 26 ++++++++++++++++ src/settings.h | 3 +- src/simulation.F90 | 16 +++++----- 8 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 src/output.cpp create mode 100644 src/output.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 673a714926..7543a541d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -394,6 +394,7 @@ add_library(libopenmc SHARED src/message_passing.cpp src/mgxs.cpp src/mgxs_interface.cpp + src/output.cpp src/particle.cpp src/plot.cpp src/position.cpp diff --git a/src/geometry.F90 b/src/geometry.F90 index aa2689e35f..5d715e98b4 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -33,12 +33,10 @@ module geometry integer(C_INT) :: count end function count_universe_instances - function check_cell_overlap_c(p) bind(C, name="check_cell_overlap") & - result(is_overlapping) - import Particle, C_BOOL + subroutine check_cell_overlap(p) bind(C) + import Particle type(Particle), intent(in) :: p - logical(C_BOOL) :: is_overlapping - end function check_cell_overlap_c + end subroutine check_cell_overlap end interface contains @@ -51,58 +49,6 @@ contains p%coord(p%n_coord)%uvw, p%surface) end function cell_contains -!=============================================================================== -! CHECK_CELL_OVERLAP checks for overlapping cells at the current particle's -! position using cell_contains and the LocalCoord's built up by find_cell -!=============================================================================== - - subroutine check_cell_overlap(p) - - type(Particle), intent(inout) :: p - - integer :: i ! cell loop index on a level - integer :: j ! coordinate level index - integer :: n_coord ! saved number of coordinate levels - integer :: n ! number of cells to search on a level - integer :: index_cell ! index in cells array - type(Cell), pointer :: c ! pointer to cell - type(Universe), pointer :: univ ! universe to search in - logical :: overlap_c - - overlap_c = check_cell_overlap_c(p) - - ! loop through each coordinate level - n_coord = p % n_coord - do j = 1, n_coord - p % n_coord = j - univ => universes(p % coord(j) % universe) - n = size(univ % cells) - - ! loop through each cell on this level - do i = 1, n - index_cell = univ % cells(i) - c => cells(index_cell) - - if (cell_contains(c, p)) then - ! the particle should only be contained in one cell per level - if (index_cell /= p % coord(j) % cell) then - if (.not. overlap_c) call fatal_error("Cell overlap disagreement") - call fatal_error("Overlapping cells detected: " & - &// trim(to_str(cells(index_cell) % id())) // ", " & - &// trim(to_str(cells(p % coord(j) % cell) % id())) & - &// " on universe " // trim(to_str(univ % id))) - end if - - overlap_check_cnt(index_cell) = overlap_check_cnt(index_cell) + 1 - - end if - - end do - end do - if (overlap_c) call fatal_error("Cell overlap disagreement") - - end subroutine check_cell_overlap - !=============================================================================== ! FIND_CELL determines what cell a source particle is in within a particular ! universe. If the base universe is passed, the particle should be found as long diff --git a/src/geometry.cpp b/src/geometry.cpp index 3c38e67164..7c0dd28bc2 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -46,7 +46,4 @@ check_cell_overlap(Particle* p) { return false; } -extern "C" int64_t get_overlap_check_count(int i) -{return overlap_check_count[i];} - } // namespace openmc diff --git a/src/output.F90 b/src/output.F90 index 760a305036..62b3ee0829 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -622,51 +622,6 @@ contains end subroutine print_results -!=============================================================================== -! PRINT_OVERLAP_DEBUG displays information regarding overlap checking results -!=============================================================================== - - subroutine print_overlap_check - - interface - function get_overlap_check_count(index_cell) result(count) bind(C) - import C_INT, C_INT64_T - integer(C_INT), intent(in), value :: index_cell - integer(C_INT64_T) :: count - end function get_overlap_check_count - end interface - - integer :: i, j - integer :: num_sparse = 0 - - ! display header block for geometry debugging section - call header("Cell Overlap Check Summary", 1) - - write(ou,100) 'Cell ID','No. Overlap Checks' - - do i = 1, n_cells - write(ou,101) cells(i) % id(), overlap_check_cnt(i) - write(ou,101) cells(i) % id(), get_overlap_check_count(i-1) - if (overlap_check_cnt(i) < 10) num_sparse = num_sparse + 1 - end do - write(ou,*) - write(ou,'(1X,A)') 'There were ' // trim(to_str(num_sparse)) // & - ' cells with less than 10 overlap checks' - j = 0 - do i = 1, n_cells - if (overlap_check_cnt(i) < 10) then - j = j + 1 - write(ou,'(1X,A8)', advance='no') trim(to_str(cells(i) % id())) - if (modulo(j,8) == 0) write(ou,*) - end if - end do - write(ou,*) - -100 format (1X,A,T15,A) -101 format (1X,I8,T15,I12) - - end subroutine print_overlap_check - !=============================================================================== ! WRITE_TALLIES creates an output file and writes out the mean values of all ! tallies and their standard deviations diff --git a/src/output.cpp b/src/output.cpp new file mode 100644 index 0000000000..9c1c85a9e6 --- /dev/null +++ b/src/output.cpp @@ -0,0 +1,75 @@ +#include "output.h" + +#include // for std::transform +#include // for strlen +#include // for setw +#include +#include + +#include "cell.h" +#include "geometry.h" +#include "message_passing.h" +#include "openmc.h" +#include "settings.h" + + +namespace openmc { + +void +header(const char* msg, int level) { + // Determine how many times to repeat the '=' character. + int n_prefix = (63 - strlen(msg)) / 2; + int n_suffix = n_prefix; + if ((strlen(msg) % 2) == 0) ++n_suffix; + + // Convert to uppercase. + std::string upper(msg); + std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper); + + // Add ===> <=== markers. + std::stringstream out; + out << ' '; + for (int i = 0; i < n_prefix; i++) out << '='; + out << "> " << upper << " <"; + for (int i = 0; i < n_suffix; i++) out << '='; + + // Print header based on verbosity level. + if (openmc_verbosity >= level) { + std::cout << out.str() << std::endl << std::endl; + } +} + +//============================================================================== + +extern "C" void +print_overlap_check() { +#ifdef OPENMC_MPI + std::vector temp(overlap_check_count); + int err = MPI_Reduce(temp.data(), overlap_check_count.data(), + overlap_check_count.size(), MPI_LONG, MPI_SUM, 0, + mpi::intracomm); +#endif + + if (openmc_master) { + header("cell overlap check summary", 1); + std::cout << " Cell ID No. Overlap Checks" << std::endl; + + std::vector sparse_cell_ids; + for (int i = 0; i < n_cells; i++) { + std::cout << " " << std::setw(8) << global_cells[i]->id << std::setw(17) + << overlap_check_count[i] << std::endl;; + if (overlap_check_count[i] < 10) { + sparse_cell_ids.push_back(global_cells[i]->id); + } + } + + std::cout << std::endl << " There were " << sparse_cell_ids.size() + << " cells with less than 10 overlap checks" << std::endl; + for (auto id : sparse_cell_ids) { + std::cout << " " << id; + } + std::cout << std::endl; + } +} + +} // namespace openmc diff --git a/src/output.h b/src/output.h new file mode 100644 index 0000000000..cabd39edeb --- /dev/null +++ b/src/output.h @@ -0,0 +1,26 @@ +//! \file output.h +//! Functions for ASCII output. + +#ifndef OPENMC_OUTPUT_H +#define OPENMC_OUTPUT_H + + +namespace openmc { + +//============================================================================== +//! Display a header block. +//! +//! \param msg The main text of the header +//! \param level The lowest verbosity level at which this header is printed +//============================================================================== + +void header(const char* msg, int level); + +//============================================================================== +//! Display information regarding cell overlap checking. +//============================================================================== + +extern "C" void print_overlap_check(); + +} // namespace openmc +#endif // OPENMC_OUTPUT_H diff --git a/src/settings.h b/src/settings.h index c203aafde7..2bdd3bb5b5 100644 --- a/src/settings.h +++ b/src/settings.h @@ -19,6 +19,7 @@ extern "C" bool openmc_check_overlaps; extern "C" bool openmc_particle_restart_run; extern "C" bool openmc_restart_run; extern "C" bool openmc_write_all_tracks; +extern "C" int openmc_verbosity; // Defined in .cpp // TODO: Make strings instead of char* once Fortran is gone @@ -40,4 +41,4 @@ extern "C" void read_settings(pugi::xml_node* root); } // namespace openmc -#endif // OPENMC_SETTINGS_H \ No newline at end of file +#endif // OPENMC_SETTINGS_H diff --git a/src/simulation.F90 b/src/simulation.F90 index 00d558d140..5c0118530c 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -24,7 +24,7 @@ module simulation use nuclide_header, only: micro_xs, n_nuclides use output, only: header, print_columns, & print_batch_keff, print_generation, print_runtime, & - print_results, print_overlap_check, write_tallies + print_results, write_tallies use particle_header use photon_header, only: micro_photon_xs, n_elements use random_lcg, only: set_particle_seed @@ -498,7 +498,6 @@ contains integer :: n ! size of arrays integer :: mpi_err ! MPI error code integer :: count_per_filter ! number of result values for one filter bin - integer(8) :: temp real(8) :: tempr(3) ! temporary array for communication #ifdef OPENMC_MPIF08 type(MPI_Datatype) :: result_block @@ -507,6 +506,11 @@ contains #endif #endif + interface + subroutine print_overlap_check() bind(C) + end subroutine print_overlap_check + end interface + err = 0 ! Skip if simulation was never run @@ -559,12 +563,6 @@ contains k_col_abs = tempr(1) k_col_tra = tempr(2) k_abs_tra = tempr(3) - - if (check_overlaps) then - call MPI_REDUCE(overlap_check_cnt, temp, n_cells, MPI_INTEGER8, & - MPI_SUM, 0, mpi_intracomm, mpi_err) - overlap_check_cnt = temp - end if #endif ! Write tally results to tallies.out @@ -576,8 +574,8 @@ contains if (master) then if (verbosity >= 6) call print_runtime() if (verbosity >= 4) call print_results() - if (check_overlaps) call print_overlap_check() end if + if (check_overlaps) call print_overlap_check() ! Reset flags need_depletion_rx = .false. From 1b3bbba41e30dc92a58aafefc06e41a47409b5bf Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 15 Aug 2018 11:49:17 -0400 Subject: [PATCH 03/43] Start implementing C++ find_cell --- src/geometry.F90 | 62 ++++++++------------------------------- src/geometry.cpp | 59 +++++++++++++++++++++++++++++++++++-- src/geometry.h | 1 + src/input_xml.F90 | 5 ---- src/settings.h | 4 ++- src/simulation_header.F90 | 6 +--- 6 files changed, 74 insertions(+), 63 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index 5d715e98b4..4a033c323f 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -37,6 +37,15 @@ module geometry import Particle type(Particle), intent(in) :: p end subroutine check_cell_overlap + + function find_cell_c(p, n_search_cells, search_cells) & + bind(C, name="find_cell") result(found) + import Particle, C_INT, C_BOOL + type(Particle), intent(in) :: p + integer(C_INT), intent(in), value :: n_search_cells + integer(C_INT), intent(in), optional :: search_cells(n_search_cells) + logical(C_BOOL) :: found + end function find_cell_c end interface contains @@ -60,64 +69,19 @@ contains type(Particle), intent(inout) :: p logical, intent(inout) :: found integer, optional :: search_cells(:) - integer :: i ! index over cells integer :: j, k ! coordinate level index integer :: offset ! instance # of a distributed cell integer :: distribcell_index integer :: i_xyz(3) ! indices in lattice - integer :: n ! number of cells to search integer :: i_cell ! index in cells array - integer :: i_universe ! index in universes array - logical :: use_search_cells ! use cells provided as argument - do j = p % n_coord + 1, MAX_COORD - call reset_coord(p % coord(j)) - end do - j = p % n_coord - - ! Determine universe (if not yet set, use root universe) - i_universe = p % coord(j) % universe - if (i_universe == C_NONE) then - p % coord(j) % universe = root_universe - i_universe = root_universe - end if - - ! set size of list to search if (present(search_cells)) then - use_search_cells = .true. - n = size(search_cells) + found = find_cell_c(p, size(search_cells), search_cells-1) else - use_search_cells = .false. - n = size(universes(i_universe) % cells) + found = find_cell_c(p, 0) end if - - found = .false. - CELL_LOOP: do i = 1, n - ! select cells based on whether we are searching a universe or a provided - ! list of cells (this would be for lists of neighbor cells) - if (use_search_cells) then - i_cell = search_cells(i) - ! check to make sure search cell is in same universe - if (cells(i_cell) % universe() /= i_universe) cycle - else - i_cell = universes(i_universe) % cells(i) - end if - - ! Move on to the next cell if the particle is not inside this cell - if (cell_contains(cells(i_cell), p)) then - ! Set cell on this level - p % coord(j) % cell = i_cell - - ! Show cell information on trace - if (verbosity >= 10 .or. trace) then - call write_message(" Entering cell " // trim(to_str(& - cells(i_cell) % id()))) - end if - - found = .true. - exit - end if - end do CELL_LOOP + j = p % n_coord + i_cell = p % coord(j) % cell if (found) then associate(c => cells(i_cell)) diff --git a/src/geometry.cpp b/src/geometry.cpp index 7c0dd28bc2..4c31fe85d0 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -3,8 +3,10 @@ #include #include "cell.h" +#include "constants.h" #include "error.h" #include "particle.h" +#include "settings.h" //TODO: remove this include #include @@ -20,14 +22,13 @@ check_cell_overlap(Particle* p) { // loop through each coordinate level for (int j = 0; j < n_coord; j++) { - //p->n_coord = j + 1; - Universe& univ {*global_universes[p->coord[j].universe - 1]}; + Universe& univ = *global_universes[p->coord[j].universe - 1]; int n = univ.cells.size(); // loop through each cell on this level for (int i = 0; i < n; i++) { int index_cell = univ.cells[i]; - Cell& c {*global_cells[index_cell]}; + Cell& c = *global_cells[index_cell]; if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { //TODO: off-by-one indexing @@ -46,4 +47,56 @@ check_cell_overlap(Particle* p) { return false; } +//============================================================================== + +extern "C" bool +find_cell(Particle* p, int n_search_cells, int* search_cells) { + for (int i = p->n_coord; i < MAX_COORD; i++) { + p->coord[i].reset(); + } + + // Determine universe (if not yet set, use root universe) + int i_universe = p->coord[p->n_coord-1].universe; + if (i_universe == C_NONE) { + p->coord[p->n_coord-1].universe = openmc_root_universe; + i_universe = openmc_root_universe; + } + //TODO: off-by-one indexing + --i_universe; + + // If not given a set of search cells, search all cells in the uninverse. + if (n_search_cells == 0) { + search_cells = global_universes[i_universe]->cells.data(); + n_search_cells = global_universes[i_universe]->cells.size(); + } + + // Find which cell of this universe the particle is in. + bool found = false; + for (int i = 0; i < n_search_cells; i++) { + int32_t i_cell = search_cells[i]; + + // Make sure the search cell is in the same universe + //TODO: off-by-one indexing + if (global_cells[i_cell]->universe - 1 != i_universe) continue; + + Position r {p->coord[p->n_coord-1].xyz}; + Direction u {p->coord[p->n_coord-1].uvw}; + int32_t surf = p->surface; + if (global_cells[i_cell]->contains(r, u, surf)) { + //TODO: off-by-one indexing + p->coord[p->n_coord-1].cell = i_cell + 1; + + if (openmc_verbosity >= 10 || openmc_trace) { + std::stringstream msg; + msg << " Entering cell " << global_cells[i_cell]->id; + write_message(msg, 1); + } + found = true; + break; + } + } + + return found; +} + } // namespace openmc diff --git a/src/geometry.h b/src/geometry.h index 7d345b102e..e02a17b983 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -8,6 +8,7 @@ namespace openmc { extern "C" int openmc_root_universe; +//TODO: free this memory extern std::vector overlap_check_count; } // namespace openmc diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e81bb92f7b..e4302478fe 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1086,11 +1086,6 @@ contains ! Allocate cells array allocate(cells(n_cells)) - if (check_overlaps) then - allocate(overlap_check_cnt(n_cells)) - overlap_check_cnt = 0 - end if - n_universes = 0 do i = 1, n_cells c => cells(i) diff --git a/src/settings.h b/src/settings.h index 2bdd3bb5b5..ff6b1cf3b7 100644 --- a/src/settings.h +++ b/src/settings.h @@ -18,8 +18,10 @@ namespace openmc { extern "C" bool openmc_check_overlaps; extern "C" bool openmc_particle_restart_run; extern "C" bool openmc_restart_run; -extern "C" bool openmc_write_all_tracks; +extern "C" bool openmc_trace; extern "C" int openmc_verbosity; +extern "C" bool openmc_write_all_tracks; +#pragma omp threadprivate(openmc_trace) // Defined in .cpp // TODO: Make strings instead of char* once Fortran is gone diff --git a/src/simulation_header.F90 b/src/simulation_header.F90 index 60bed6425a..3405694028 100644 --- a/src/simulation_header.F90 +++ b/src/simulation_header.F90 @@ -67,10 +67,7 @@ module simulation_header integer :: restart_batch - ! Flag for enabling cell overlap checking during transport - integer(8), allocatable :: overlap_check_cnt(:) - - logical :: trace + logical(C_BOOL), bind(C, name='openmc_trace') :: trace !$omp threadprivate(trace, thread_id, current_work) @@ -90,7 +87,6 @@ contains !=============================================================================== subroutine free_memory_simulation() - if (allocated(overlap_check_cnt)) deallocate(overlap_check_cnt) if (allocated(entropy_p)) deallocate(entropy_p) if (allocated(source_frac)) deallocate(source_frac) if (allocated(work_index)) deallocate(work_index) From 3b8d1ffb4b21a0b64a9577f9dcd81e86303695c0 Mon Sep 17 00:00:00 2001 From: jingang Date: Wed, 15 Aug 2018 22:08:12 -0400 Subject: [PATCH 04/43] update for new wmp library v1.0 - python api and docs --- docs/source/io_formats/data_wmp.rst | 60 +--- docs/source/methods/cross_sections.rst | 5 +- openmc/data/__init__.py | 2 +- openmc/data/multipole.py | 364 +++++++------------------ 4 files changed, 111 insertions(+), 320 deletions(-) diff --git a/docs/source/io_formats/data_wmp.rst b/docs/source/io_formats/data_wmp.rst index 6174e85ff7..25916c5229 100644 --- a/docs/source/io_formats/data_wmp.rst +++ b/docs/source/io_formats/data_wmp.rst @@ -5,7 +5,7 @@ Windowed Multipole Library Format ================================= **/version** (*char[]*) - The format version of the file. The current version is "v0.2" + The format version of the file. The current version is "v1.0" **/nuclide/** - **broaden_poly** (*int[]*) @@ -23,55 +23,25 @@ Windowed Multipole Library Format \text{data}[:,i] = [\text{pole},~\text{residue}_1,~\text{residue}_2, ~\ldots] - The residues are in the order: total, competitive if present, - absorption, fission. Complex numbers are stored by forming a type with - ":math:`r`" and ":math:`i`" identifiers, similar to how `h5py`_ does it. - - **end_E** (*double*) + The residues are in the order: scattering, absorption, fission. Complex + numbers are stored by forming a type with ":math:`r`" and ":math:`i`" + identifiers, similar to how `h5py`_ does it. + - **E_max** (*double*) Highest energy the windowed multipole part of the library is valid for. - - **formalism** (*int*) - The formalism of the underlying data. Uses the `ENDF-6`_ format - formalism numbers. - - .. table:: Table of supported formalisms. - - +-------------+------------------+ - | Formalism | Formalism number | - +=============+==================+ - | MLBW | 2 | - +-------------+------------------+ - | Reich-Moore | 3 | - +-------------+------------------+ - - - **l_value** (*int[]*) - The index for a corresponding pole. Equivalent to the :math:`l` quantum - number of the resonance the pole comes from :math:`+1`. - - **pseudo_K0RS** (*double[]*) - :math:`l` dependent value of - - .. math:: - \sqrt{\frac{2 m_n}{\hbar}}\frac{AWR}{AWR + 1} r_{s,l} - - Where :math:`m_n` is mass of neutron, :math:`AWR` is the atomic weight - ratio of the target to the neutron, and :math:`r_{s,l}` is the - scattering radius for a given :math:`l`. + - **E_min** (*double*) + Lowest energy the windowed multipole part of the library is valid for. - **spacing** (*double*) .. math:: - \frac{\sqrt{E_{max}}- \sqrt{E_{min}}}{n_w} + \frac{\sqrt{E_{max}} - \sqrt{E_{min}}}{n_w} - Where :math:`E_{max}` is the maximum energy the windows go up to. This - is not equivalent to the maximum energy for which the windowed multipole - data is valid for. It is slightly higher to ensure an integer number of - windows. :math:`E_{min}` is the minimum energy and equivalent to - ``start_E``, and :math:`n_w` is the number of windows, given by - ``windows``. + Where :math:`E_{max}` is the maximum energy the windows go up to. + :math:`E_{min}` is the minimum energy, and :math:`n_w` is the number of + windows, given by ``windows``. - **sqrtAWR** (*double*) Square root of the atomic weight ratio. - - **start_E** (*double*) - Lowest energy the windowed multipole part of the library is valid for. - - **w_start** (*int[]*) - The pole to start from for each window. - - **w_end** (*int[]*) - The pole to end at for each window. + - **windows** (*int[][]*) + The poles to start from and end at for each window. windows[i, 0] and + windows[i, 1] are, respectively, the indexes (1-based) of the first and + last pole in window i. .. _h5py: http://docs.h5py.org/en/latest/ -.. _ENDF-6: https://www.oecd-nea.org/dbdata/data/manual-endf/endf102.pdf diff --git a/docs/source/methods/cross_sections.rst b/docs/source/methods/cross_sections.rst index 9f677bac43..4940275d3a 100644 --- a/docs/source/methods/cross_sections.rst +++ b/docs/source/methods/cross_sections.rst @@ -90,7 +90,7 @@ Assuming free-gas thermal motion, cross sections in the multipole form can be analytically Doppler broadened to give the form: .. math:: - \sigma(E, T) = \frac{1}{2 E \sqrt{\xi}} \sum_j \text{Re} \left[i r_j + \sigma(E, T) = \frac{1}{2 E \sqrt{\xi}} \sum_j \text{Re} \left[r_j \sqrt{\pi} W_i(z) - \frac{r_j}{\sqrt{\pi}} C \left(\frac{p_j}{\sqrt{\xi}}, \frac{u}{2 \sqrt{\xi}}\right)\right] .. math:: @@ -141,7 +141,7 @@ scattering does not occur in the resolved resonance region. This is usually, but not always the case. Future library versions may eliminate this issue. The data format used by OpenMC to represent windowed multipole data is specified -in :ref:`io_data_wmp`. +in :ref:`io_data_wmp` with a publicly available `WMP library`_. .. _temperature_treatment: @@ -270,6 +270,7 @@ or even isotropic scattering. https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-14-24530.pdf .. _Hwang: http://www.ans.org/pubs/journals/nse/a_16381 .. _Josey: http://dx.doi.org/10.1016/j.jcp.2015.08.013 +.. _WMP Library: https://github.com/mit-crpg/WMP_Library .. _MCNP: http://mcnp.lanl.gov .. _Serpent: http://montecarlo.vtt.fi .. _NJOY: http://t2.lanl.gov/codes.shtml diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py index 390a67c9b9..dec11cd3a9 100644 --- a/openmc/data/__init__.py +++ b/openmc/data/__init__.py @@ -4,7 +4,7 @@ HDF5_VERSION_MINOR = 0 HDF5_VERSION = (HDF5_VERSION_MAJOR, HDF5_VERSION_MINOR) # Version of WMP nuclear data format -WMP_VERSION = 'v0.2' +WMP_VERSION = 'v1.0' from .data import * diff --git a/openmc/data/multipole.py b/openmc/data/multipole.py index f7a78d9532..c6e4f123c9 100644 --- a/openmc/data/multipole.py +++ b/openmc/data/multipole.py @@ -10,26 +10,16 @@ import openmc.checkvalue as cv from openmc.mixin import EqualityMixin -# Formalisms -_FORM_MLBW = 2 -_FORM_RM = 3 - # Constants that determine which value to access _MP_EA = 0 # Pole -# Reich-Moore indices -_RM_RT = 1 # Residue total -_RM_RA = 2 # Residue absorption -_RM_RF = 3 # Residue fission - -# Multi-level Breit Wigner indices -_MLBW_RT = 1 # Residue total -_MLBW_RX = 2 # Residue competitive -_MLBW_RA = 3 # Residue absorption -_MLBW_RF = 4 # Residue fission +# Residue indices +_MP_RS = 1 # Residue scattering +_MP_RA = 2 # Residue absorption +_MP_RF = 3 # Residue fission # Polynomial fit indices -_FIT_T = 0 # Total +_FIT_S = 0 # Scattering _FIT_A = 1 # Absorption _FIT_F = 2 # Fission @@ -143,98 +133,61 @@ class WindowedMultipole(EqualityMixin): Parameters ---------- - formalism : {'MLBW', 'RM'} - The R-matrix formalism used to reconstruct resonances. Either 'MLBW' - for multi-level Breit Wigner or 'RM' for Reich-Moore. Attributes ---------- - num_l : Integral - Number of possible l quantum states for this nuclide. fit_order : Integral Order of the windowed curvefit. fissionable : bool Whether or not the target nuclide has fission data. - formalism : {'MLBW', 'RM'} - The R-matrix formalism used to reconstruct resonances. Either 'MLBW' - for multi-level Breit Wigner or 'RM' for Reich-Moore. spacing : Real The width of each window in sqrt(E)-space. For example, the frst window - will end at (sqrt(start_E) + spacing)**2 and the second window at - (sqrt(start_E) + 2*spacing)**2. + will end at (sqrt(E_min) + spacing)**2 and the second window at + (sqrt(E_min) + 2*spacing)**2. sqrtAWR : Real Square root of the atomic weight ratio of the target nuclide. - start_E : Real + E_min : Real Lowest energy in eV the library is valid for. - end_E : Real + E_max : Real Highest energy in eV the library is valid for. data : np.ndarray A 2D array of complex poles and residues. data[i, 0] gives the energy at which pole i is located. data[i, 1:] gives the residues associated - with the i-th pole. There are 3 residues for Reich-Moore data, one each - for the total, absorption, and fission channels. Multi-level - Breit Wigner data has an additional residue for the competitive channel. - pseudo_k0RS : np.ndarray - A 1D array of Real values. There is one value for each valid l - quantum number. The values are equal to - sqrt(2 m / hbar) * AWR / (AWR + 1) * r - where m is the neutron mass, AWR is the atomic weight ratio, and r - is the l-dependent scattering radius. - l_value : np.ndarray - A 1D array of Integral values equal to the l quantum number for each - pole + 1. - w_start : np.ndarray - A 1D array of Integral values. w_start[i] - 1 is the index of the first - pole in window i. - w_end : np.ndarray - A 1D array of Integral values. w_end[i] - 1 is the index of the last - pole in window i. + with the i-th pole. There are 3 residues, one each for the scattering, + absorption, and fission channels. + windows : np.ndarray + A 2D array of Integral values. windows[i, 0] - 1 is the index of the + first pole in window i. windows[i, 1] - 1 is the index of the last pole + in window i. broaden_poly : np.ndarray A 1D array of boolean values indicating whether or not the polynomial curvefit in that window should be Doppler broadened. curvefit : np.ndarray A 3D array of Real curvefit polynomial coefficients. curvefit[i, 0, :] - gives coefficients for the total cross section in window i. + gives coefficients for the scattering cross section in window i. curvefit[i, 1, :] gives absorption coefficients and curvefit[i, 2, :] gives fission coefficients. The polynomial terms are increasing powers of sqrt(E) starting with 1/E e.g: a/E + b/sqrt(E) + c + d sqrt(E) + ... """ - def __init__(self, formalism): - self._num_l = None - self.formalism = formalism + def __init__(self): self.spacing = None self.sqrtAWR = None - self.start_E = None - self.end_E = None + self.E_min = None + self.E_max = None self.data = None - self.pseudo_k0RS = None - self.l_value = None - self.w_start = None - self.w_end = None + self.windows = None self.broaden_poly = None self.curvefit = None - @property - def num_l(self): - return self._num_l - @property def fit_order(self): return self.curvefit.shape[1] - 1 @property def fissionable(self): - if self.formalism == 'RM': - return self.data.shape[1] == 4 - else: - # Assume self.formalism == 'MLBW' - return self.data.shape[1] == 5 - - @property - def formalism(self): - return self._formalism + return self.data.shape[1] == 4 @property def spacing(self): @@ -245,32 +198,24 @@ class WindowedMultipole(EqualityMixin): return self._sqrtAWR @property - def start_E(self): - return self._start_E + def E_min(self): + return self._E_min @property - def end_E(self): - return self._end_E + def E_max(self): + return self._E_max @property def data(self): return self._data - @property - def pseudo_k0RS(self): - return self._pseudo_k0RS - @property def l_value(self): return self._l_value @property - def w_start(self): - return self._w_start - - @property - def w_end(self): - return self._w_end + def windows(self): + return self._windows @property def broaden_poly(self): @@ -280,116 +225,64 @@ class WindowedMultipole(EqualityMixin): def curvefit(self): return self._curvefit - @formalism.setter - def formalism(self, formalism): - cv.check_type('formalism', formalism, str) - cv.check_value('formalism', formalism, ('MLBW', 'RM')) - self._formalism = formalism - @spacing.setter def spacing(self, spacing): if spacing is not None: - cv.check_type('spacing', spacing, Real) - cv.check_greater_than('spacing', spacing, 0.0, equality=False) + check_type('spacing', spacing, Real) + check_greater_than('spacing', spacing, 0.0, equality=False) self._spacing = spacing @sqrtAWR.setter def sqrtAWR(self, sqrtAWR): if sqrtAWR is not None: - cv.check_type('sqrtAWR', sqrtAWR, Real) - cv.check_greater_than('sqrtAWR', sqrtAWR, 0.0, equality=False) + check_type('sqrtAWR', sqrtAWR, Real) + check_greater_than('sqrtAWR', sqrtAWR, 0.0, equality=False) self._sqrtAWR = sqrtAWR - @start_E.setter - def start_E(self, start_E): - if start_E is not None: - cv.check_type('start_E', start_E, Real) - cv.check_greater_than('start_E', start_E, 0.0, equality=True) - self._start_E = start_E + @E_min.setter + def E_min(self, E_min): + if E_min is not None: + check_type('E_min', E_min, Real) + check_greater_than('E_min', E_min, 0.0, equality=True) + self._E_min = E_min - @end_E.setter - def end_E(self, end_E): - if end_E is not None: - cv.check_type('end_E', end_E, Real) - cv.check_greater_than('end_E', end_E, 0.0, equality=False) - self._end_E = end_E + @E_max.setter + def E_max(self, E_max): + if E_max is not None: + check_type('E_max', E_max, Real) + check_greater_than('E_max', E_max, 0.0, equality=False) + self._E_max = E_max @data.setter def data(self, data): if data is not None: - cv.check_type('data', data, np.ndarray) + check_type('data', data, np.ndarray) if len(data.shape) != 2: raise ValueError('Multipole data arrays must be 2D') - if self.formalism == 'RM': - if data.shape[1] not in (3, 4): - raise ValueError('For the Reich-Moore formalism, ' - 'data.shape[1] must be 3 or 4. One value for the pole.' - ' One each for the total and absorption residues. ' - 'Possibly one more for a fission residue.') - else: - # Assume self.formalism == 'MLBW' - if data.shape[1] not in (4, 5): - raise ValueError('For the Multi-level Breit-Wigner ' - 'formalism, data.shape[1] must be 4 or 5. One value ' - 'for the pole. One each for the total, competitive, ' - 'and absorption residues. Possibly one more for a ' - 'fission residue.') + if data.shape[1] not in (3, 4): + raise ValueError( + 'data.shape[1] must be 3 or 4. One value for the pole.' + ' One each for the scattering and absorption residues. ' + 'Possibly one more for a fission residue.') if not np.issubdtype(data.dtype, complex): raise TypeError('Multipole data arrays must be complex dtype') self._data = data - @pseudo_k0RS.setter - def pseudo_k0RS(self, pseudo_k0RS): - if pseudo_k0RS is not None: - cv.check_type('pseudo_k0RS', pseudo_k0RS, np.ndarray) - if len(pseudo_k0RS.shape) != 1: - raise ValueError('Multipole pseudo_k0RS arrays must be 1D') - if not np.issubdtype(pseudo_k0RS.dtype, float): - raise TypeError('Multipole data arrays must be float dtype') - self._pseudo_k0RS = pseudo_k0RS - - @l_value.setter - def l_value(self, l_value): - if l_value is not None: - cv.check_type('l_value', l_value, np.ndarray) - if len(l_value.shape) != 1: - raise ValueError('Multipole l_value arrays must be 1D') - if not np.issubdtype(l_value.dtype, int): - raise TypeError('Multipole l_value arrays must be integer' + @windows.setter + def windows(self, windows): + if windows is not None: + check_type('windows', windows, np.ndarray) + if len(windows.shape) != 2: + raise ValueError('Multipole windows arrays must be 2D') + if not np.issubdtype(windows.dtype, int): + raise TypeError('Multipole windows arrays must be integer' ' dtype') - - self._num_l = len(np.unique(l_value)) - - else: - self._num_l = None - - self._l_value = l_value - - @w_start.setter - def w_start(self, w_start): - if w_start is not None: - cv.check_type('w_start', w_start, np.ndarray) - if len(w_start.shape) != 1: - raise ValueError('Multipole w_start arrays must be 1D') - if not np.issubdtype(w_start.dtype, int): - raise TypeError('Multipole w_start arrays must be integer' - ' dtype') - self._w_start = w_start - - @w_end.setter - def w_end(self, w_end): - if w_end is not None: - cv.check_type('w_end', w_end, np.ndarray) - if len(w_end.shape) != 1: - raise ValueError('Multipole w_end arrays must be 1D') - if not np.issubdtype(w_end.dtype, int): - raise TypeError('Multipole w_end arrays must be integer dtype') - self._w_end = w_end + self._windows = windows @broaden_poly.setter def broaden_poly(self, broaden_poly): if broaden_poly is not None: - cv.check_type('broaden_poly', broaden_poly, np.ndarray) + check_type('broaden_poly', broaden_poly, np.ndarray) if len(broaden_poly.shape) != 1: raise ValueError('Multipole broaden_poly arrays must be 1D') if not np.issubdtype(broaden_poly.dtype, bool): @@ -400,10 +293,10 @@ class WindowedMultipole(EqualityMixin): @curvefit.setter def curvefit(self, curvefit): if curvefit is not None: - cv.check_type('curvefit', curvefit, np.ndarray) + check_type('curvefit', curvefit, np.ndarray) if len(curvefit.shape) != 3: raise ValueError('Multipole curvefit arrays must be 3D') - if curvefit.shape[2] not in (2, 3): # sig_t, sig_a (maybe sig_f) + if curvefit.shape[2] not in (2, 3): # sig_s, sig_a (maybe sig_f) raise ValueError('The third dimension of multipole curvefit' ' arrays must have a length of 2 or 3') if not np.issubdtype(curvefit.dtype, float): @@ -443,19 +336,14 @@ class WindowedMultipole(EqualityMixin): 'Python API expects version ' + WMP_VERSION) group = h5file['nuclide'] - # Read scalars. + out = cls() - if group['formalism'].value == _FORM_MLBW: - out = cls('MLBW') - elif group['formalism'].value == _FORM_RM: - out = cls('RM') - else: - raise ValueError('Unrecognized/Unsupported R-matrix formalism') + # Read scalars. out.spacing = group['spacing'].value out.sqrtAWR = group['sqrtAWR'].value - out.start_E = group['start_E'].value - out.end_E = group['end_E'].value + out.E_min = group['E_min'].value + out.E_max = group['E_max'].value # Read arrays. @@ -463,27 +351,15 @@ class WindowedMultipole(EqualityMixin): out.data = group['data'].value - out.l_value = group['l_value'].value - if out.l_value.shape[0] != out.data.shape[0]: - raise ValueError(err.format('l_value', 'data')) - - out.pseudo_k0RS = group['pseudo_K0RS'].value - if out.pseudo_k0RS.shape[0] != out.num_l: - raise ValueError(err.format('pseudo_k0RS', 'l_value')) - - out.w_start = group['w_start'].value - - out.w_end = group['w_end'].value - if out.w_end.shape[0] != out.w_start.shape[0]: - raise ValueError(err.format('w_end', 'w_start')) + out.windows = group['windows'].value out.broaden_poly = group['broaden_poly'].value.astype(np.bool) - if out.broaden_poly.shape[0] != out.w_start.shape[0]: - raise ValueError(err.format('broaden_poly', 'w_start')) + if out.broaden_poly.shape[0] != out.windows.shape[0]: + raise ValueError(err.format('broaden_poly', 'windows')) out.curvefit = group['curvefit'].value - if out.curvefit.shape[0] != out.w_start.shape[0]: - raise ValueError(err.format('curvefit', 'w_start')) + if out.curvefit.shape[0] != out.windows.shape[0]: + raise ValueError(err.format('curvefit', 'windows')) # _broaden_wmp_polynomials assumes the curve fit has at least 3 terms. if out.fit_order < 2: @@ -493,7 +369,7 @@ class WindowedMultipole(EqualityMixin): return out def _evaluate(self, E, T): - """Compute total, absorption, and fission cross sections. + """Compute scattering, absorption, and fission cross sections. Parameters ---------- @@ -510,8 +386,8 @@ class WindowedMultipole(EqualityMixin): """ - if E < self.start_E: return (0, 0, 0) - if E > self.end_E: return (0, 0, 0) + if E < self.E_min: return (0, 0, 0) + if E > self.E_max: return (0, 0, 0) # ====================================================================== # Bookkeeping @@ -525,34 +401,12 @@ class WindowedMultipole(EqualityMixin): # the 1-based vs. 0-based indexing. Similarly startw needs to be # decreased by 1. endw does not need to be decreased because # range(startw, endw) does not include endw. - i_window = int(np.floor((sqrtE - sqrt(self.start_E)) / self.spacing)) - startw = self.w_start[i_window] - 1 - endw = self.w_end[i_window] - - # Fill in factors. Because of the unique interference dips in scatering - # resonances, the total cross section has a special "factor" that does - # not appear in the absorption and fission equations. - if startw <= endw: - twophi = np.zeros(self.num_l, dtype=np.float) - sig_t_factor = np.zeros(self.num_l, dtype=np.cfloat) - - for iL in range(self.num_l): - twophi[iL] = self.pseudo_k0RS[iL] * sqrtE - if iL == 1: - twophi[iL] = twophi[iL] - np.arctan(twophi[iL]) - elif iL == 2: - arg = 3.0 * twophi[iL] / (3.0 - twophi[iL]**2) - twophi[iL] = twophi[iL] - np.arctan(arg) - elif iL == 3: - arg = (twophi[iL] * (15.0 - twophi[iL]**2) - / (15.0 - 6.0 * twophi[iL]**2)) - twophi[iL] = twophi[iL] - np.arctan(arg) - - twophi = 2.0 * twophi - sig_t_factor = np.cos(twophi) - 1j*np.sin(twophi) + i_window = int(np.floor((sqrtE - sqrt(self.E_min)) / self.spacing)) + startw = self.windows[i_window, 0] - 1 + endw = self.windows[i_window, 1] # Initialize the ouptut cross sections. - sig_t = 0.0 + sig_s = 0.0 sig_a = 0.0 sig_f = 0.0 @@ -565,7 +419,7 @@ class WindowedMultipole(EqualityMixin): broadened_polynomials = _broaden_wmp_polynomials(E, dopp, self.fit_order + 1) for i_poly in range(self.fit_order+1): - sig_t += (self.curvefit[i_window, i_poly, _FIT_T] + sig_s += (self.curvefit[i_window, i_poly, _FIT_S] * broadened_polynomials[i_poly]) sig_a += (self.curvefit[i_window, i_poly, _FIT_A] * broadened_polynomials[i_poly]) @@ -575,7 +429,7 @@ class WindowedMultipole(EqualityMixin): else: temp = invE for i_poly in range(self.fit_order+1): - sig_t += self.curvefit[i_window, i_poly, _FIT_T] * temp + sig_s += self.curvefit[i_window, i_poly, _FIT_S] * temp sig_a += self.curvefit[i_window, i_poly, _FIT_A] * temp if self.fissionable: sig_f += self.curvefit[i_window, i_poly, _FIT_F] * temp @@ -589,22 +443,10 @@ class WindowedMultipole(EqualityMixin): for i_pole in range(startw, endw): psi_chi = -1j / (self.data[i_pole, _MP_EA] - sqrtE) c_temp = psi_chi / E - if self.formalism == 'MLBW': - sig_t += ((self.data[i_pole, _MLBW_RT] * c_temp * - sig_t_factor[self.l_value[i_pole]-1]).real - + (self.data[i_pole, _MLBW_RX] * c_temp).real) - sig_a += (self.data[i_pole, _MLBW_RA] * c_temp).real - if self.fissionable: - sig_f += (self.data[i_pole, _MLBW_RF] * c_temp).real - elif self.formalism == 'RM': - sig_t += (self.data[i_pole, _RM_RT] * c_temp * - sig_t_factor[self.l_value[i_pole]-1]).real - sig_a += (self.data[i_pole, _RM_RA] * c_temp).real - if self.fissionable: - sig_f += (self.data[i_pole, _RM_RF] * c_temp).real - else: - raise ValueError('Unrecognized/Unsupported R-matrix' - ' formalism') + sig_s += (self.data[i_pole, _MP_RS] * c_temp).real + sig_a += (self.data[i_pole, _MP_RA] * c_temp).real + if self.fissionable: + sig_f += (self.data[i_pole, _MP_RF] * c_temp).real else: # At temperature, use Faddeeva function-based form. @@ -612,27 +454,15 @@ class WindowedMultipole(EqualityMixin): for i_pole in range(startw, endw): Z = (sqrtE - self.data[i_pole, _MP_EA]) * dopp w_val = _faddeeva(Z) * dopp * invE * sqrt(pi) - if self.formalism == 'MLBW': - sig_t += ((self.data[i_pole, _MLBW_RT] * - sig_t_factor[self.l_value[i_pole]-1] + - self.data[i_pole, _MLBW_RX]) * w_val).real - sig_a += (self.data[i_pole, _MLBW_RA] * w_val).real - if self.fissionable: - sig_f += (self.data[i_pole, _MLBW_RF] * w_val).real - elif self.formalism == 'RM': - sig_t += (self.data[i_pole, _RM_RT] * w_val * - sig_t_factor[self.l_value[i_pole]-1]).real - sig_a += (self.data[i_pole, _RM_RA] * w_val).real - if self.fissionable: - sig_f += (self.data[i_pole, _RM_RF] * w_val).real - else: - raise ValueError('Unrecognized/Unsupported R-matrix' - ' formalism') + sig_s += (self.data[i_pole, _MP_RS] * w_val).real + sig_a += (self.data[i_pole, _MP_RA] * w_val).real + if self.fissionable: + sig_f += (self.data[i_pole, _MP_RF] * w_val).real - return sig_t, sig_a, sig_f + return sig_s, sig_a, sig_f def __call__(self, E, T): - """Compute total, absorption, and fission cross sections. + """Compute scattering, absorption, and fission cross sections. Parameters ---------- @@ -674,24 +504,14 @@ class WindowedMultipole(EqualityMixin): g = f.create_group('nuclide') # Write scalars. - if self.formalism == 'MLBW': - g.create_dataset('formalism', - data=np.array(_FORM_MLBW, dtype=np.int32)) - else: - # Assume RM. - g.create_dataset('formalism', - data=np.array(_FORM_RM, dtype=np.int32)) g.create_dataset('spacing', data=np.array(self.spacing)) g.create_dataset('sqrtAWR', data=np.array(self.sqrtAWR)) - g.create_dataset('start_E', data=np.array(self.start_E)) - g.create_dataset('end_E', data=np.array(self.end_E)) + g.create_dataset('E_min', data=np.array(self.E_min)) + g.create_dataset('E_max', data=np.array(self.E_max)) # Write arrays. g.create_dataset('data', data=self.data) - g.create_dataset('l_value', data=self.l_value) - g.create_dataset('pseudo_K0RS', data=self.pseudo_k0RS) - g.create_dataset('w_start', data=self.w_start) - g.create_dataset('w_end', data=self.w_end) + g.create_dataset('windows', data=self.windows) g.create_dataset('broaden_poly', data=self.broaden_poly.astype(np.int8)) g.create_dataset('curvefit', data=self.curvefit) From 60a88b9cab49d63e71e9ee6ba6b06f0905d6ae9b Mon Sep 17 00:00:00 2001 From: jingang Date: Thu, 16 Aug 2018 00:12:18 -0400 Subject: [PATCH 05/43] update for new wmp library v1.0 - openmc code --- src/constants.F90 | 2 +- src/multipole_header.F90 | 106 +++++++++------------------ src/nuclide_header.F90 | 151 +++++++++------------------------------ src/physics.F90 | 4 +- src/tallies/tally.F90 | 136 +++++++++++++++++------------------ 5 files changed, 140 insertions(+), 259 deletions(-) diff --git a/src/constants.F90 b/src/constants.F90 index ab85b277a6..a3118f84da 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -25,7 +25,7 @@ module constants integer, parameter :: VERSION_VOLUME(2) = [1, 0] integer, parameter :: VERSION_VOXEL(2) = [1, 0] integer, parameter :: VERSION_MGXS_LIBRARY(2) = [1, 0] - character(10), parameter :: VERSION_MULTIPOLE = "v0.2" + character(10), parameter :: VERSION_MULTIPOLE = "v1.0" ! ============================================================================ ! ADJUSTABLE PARAMETERS diff --git a/src/multipole_header.F90 b/src/multipole_header.F90 index f2d0c91062..05eb62e1aa 100644 --- a/src/multipole_header.F90 +++ b/src/multipole_header.F90 @@ -10,27 +10,16 @@ module multipole_header !======================================================================== ! Multipole related constants - ! Formalisms - integer, parameter :: FORM_MLBW = 2, & - FORM_RM = 3, & - FORM_RML = 7 - ! Constants that determine which value to access integer, parameter :: MP_EA = 1 ! Pole - ! Reich-Moore indices - integer, parameter :: RM_RT = 2, & ! Residue total - RM_RA = 3, & ! Residue absorption - RM_RF = 4 ! Residue fission - - ! Multi-level Breit Wigner indices - integer, parameter :: MLBW_RT = 2, & ! Residue total - MLBW_RX = 3, & ! Residue compettitive - MLBW_RA = 4, & ! Residue absorption - MLBW_RF = 5 ! Residue fission + ! Residue indices + integer, parameter :: MP_RS = 2, & ! Residue scattering + MP_RA = 3, & ! Residue absorption + MP_RF = 4 ! Residue fission ! Polynomial fit indices - integer, parameter :: FIT_T = 1, & ! Total + integer, parameter :: FIT_S = 1, & ! Scattering FIT_A = 2, & ! Absorption FIT_F = 3 ! Fission @@ -46,33 +35,22 @@ module multipole_header ! Isotope Properties logical :: fissionable ! Is this isotope fissionable? - integer, allocatable :: l_value(:) ! The l index of the pole - integer :: num_l ! Number of unique l values - real(8), allocatable :: pseudo_k0RS(:) ! The value (sqrt(2*mass neutron - ! /reduced planck constant) - ! * AWR/(AWR + 1) - ! * scattering radius for - ! each l complex(8), allocatable :: data(:,:) ! Poles and residues real(8) :: sqrtAWR ! Square root of the atomic ! weight ratio - integer :: formalism ! R-matrix formalism !========================================================================= ! Windows integer :: fit_order ! Order of the fit. 1 linear, ! 2 quadratic, etc. - real(8) :: start_E ! Start energy for the windows - real(8) :: end_E ! End energy for the windows + real(8) :: E_min ! Start energy for the windows + real(8) :: E_max ! End energy for the windows real(8) :: spacing ! The actual spacing in sqrt(E) ! space. - ! spacing = sqrt(multipole_w % endE - multipole_w % startE) - ! / multipole_w % windows - integer, allocatable :: w_start(:) ! Contains the index of the pole at - ! the start of the window - integer, allocatable :: w_end(:) ! Contains the index of the pole at - ! the end of the window + integer, allocatable :: windows(:, :) ! Contains the indexes of the poles + ! at the start and end of the + ! window real(8), allocatable :: curvefit(:,:,:) ! Contains the fitting function. ! (reaction type, coeff index, ! window index) @@ -96,7 +74,7 @@ contains character(len=*), intent(in) :: filename character(len=10) :: version - integer :: i, n_poles, n_residue_types, n_windows + integer :: i, n_poles, n_residues, n_windows integer(HSIZE_T) :: dims_1d(1), dims_2d(2), dims_3d(3) integer(HID_T) :: file_id integer(HID_T) :: group_id @@ -114,65 +92,49 @@ contains // trim(filename) // " uses version " // trim(version) // ".") ! Read scalar values. - call read_dataset(this % formalism, group_id, "formalism") call read_dataset(this % spacing, group_id, "spacing") call read_dataset(this % sqrtAWR, group_id, "sqrtAWR") - call read_dataset(this % start_E, group_id, "start_E") - call read_dataset(this % end_E, group_id, "end_E") + call read_dataset(this % E_min, group_id, "E_min") + call read_dataset(this % E_max, group_id, "E_max") ! Read the "data" array. Use its shape to figure out the number of poles ! and residue types in this data. dset = open_dataset(group_id, "data") call get_shape(dset, dims_2d) - n_residue_types = int(dims_2d(1), 4) - 1 + n_residues = int(dims_2d(1), 4) - 1 n_poles = int(dims_2d(2), 4) - allocate(this % data(n_residue_types+1, n_poles)) - call read_dataset(this % data, dset) + allocate(this % data(n_residues+1, n_poles)) + if (n_poles > 0) call read_dataset(this % data, dset) call close_dataset(dset) ! Check to see if this data includes fission residues. - if (this % formalism == FORM_RM) then - this % fissionable = (n_residue_types == 3) - else - ! Assume FORM_MLBW. - this % fissionable = (n_residue_types == 4) - end if + this % fissionable = (n_residues == 3) - ! Read the "l_value" array. - allocate(this % l_value(n_poles)) - call read_dataset(this % l_value, group_id, "l_value") - - ! Figure out the number of unique l values in the l_value array. - do i = 1, n_poles - if (.not. l_val_dict % has(this % l_value(i))) then - call l_val_dict % set(this % l_value(i), 0) - end if - end do - this % num_l = l_val_dict % size() - call l_val_dict % clear() - - ! Read the "pseudo_K0RS" array. - allocate(this % pseudo_k0RS(this % num_l)) - call read_dataset(this % pseudo_k0RS, group_id, "pseudo_K0RS") - - ! Read the "w_start" array and use its shape to figure out the number of + ! Read the "windows" array and use its shape to figure out the number of ! windows. - dset = open_dataset(group_id, "w_start") - call get_shape(dset, dims_1d) - n_windows = int(dims_1d(1), 4) - allocate(this % w_start(n_windows)) - call read_dataset(this % w_start, dset) + dset = open_dataset(group_id, "windows") + call get_shape(dset, dims_2d) + n_windows = int(dims_2d(2), 4) + allocate(this % windows(dims_2d(1), n_windows)) + call read_dataset(this % windows, dset) call close_dataset(dset) - ! Read the "w_end" and "broaden_poly" arrays. - allocate(this % w_end(n_windows)) - call read_dataset(this % w_end, group_id, "w_end") + ! Read the "broaden_poly" arrays. + dset = open_dataset(group_id, "broaden_poly") + call get_shape(dset, dims_1d) + if (dims_1d(1) /= n_windows) call fatal_error("broaden_poly array shape is& + ¬ consistent with the windows array shape in multipole library"& + // trim(filename) // ".") allocate(this % broaden_poly(n_windows)) - call read_dataset(this % broaden_poly, group_id, "broaden_poly") + call read_dataset(this % broaden_poly, dset) + call close_dataset(dset) ! Read the "curvefit" array. dset = open_dataset(group_id, "curvefit") call get_shape(dset, dims_3d) + if (dims_3d(3) /= n_windows) call fatal_error("curvefit array shape is not& + &consistent with the windows array shape in multipole library"& + // trim(filename) // ".") allocate(this % curvefit(dims_3d(1), dims_3d(2), dims_3d(3))) call read_dataset(this % curvefit, dset) call close_dataset(dset) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 8cd225bc98..a2e47fa434 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -12,11 +12,9 @@ module nuclide_header use hdf5_interface use math, only: faddeeva, w_derivative, & broaden_wmp_polynomials - use multipole_header, only: FORM_RM, FORM_MLBW, MP_EA, RM_RT, RM_RA, & - RM_RF, MLBW_RT, MLBW_RX, MLBW_RA, MLBW_RF, & - FIT_T, FIT_A, FIT_F, MultipoleArray + use multipole_header, only: MP_EA, MP_RS, MP_RA, MP_RF, & + FIT_S, FIT_A, FIT_F, MultipoleArray use message_passing - use multipole_header, only: MultipoleArray use random_lcg, only: prn, future_prn, prn_set_stream use reaction_header, only: Reaction use sab_header, only: SAlphaBeta, sab_tables @@ -849,7 +847,7 @@ contains integer :: threshold ! threshold energy index real(8) :: f ! interp factor on nuclide energy grid real(8) :: kT ! temperature in eV - real(8) :: sig_t, sig_a, sig_f ! Intermediate multipole variables + real(8) :: sig_s, sig_a, sig_f ! Intermediate multipole variables ! Initialize cached cross sections to zero micro_xs % elastic = CACHE_INVALID @@ -859,8 +857,8 @@ contains ! Check to see if there is multipole data present at this energy use_mp = .false. if (this % mp_present) then - if (E >= this % multipole % start_E .and. & - E <= this % multipole % end_E) then + if (E >= this % multipole % E_min .and. & + E <= this % multipole % E_max) then use_mp = .true. end if end if @@ -868,9 +866,10 @@ contains ! Evaluate multipole or interpolate if (use_mp) then ! Call multipole kernel - call multipole_eval(this % multipole, E, sqrtkT, sig_t, sig_a, sig_f) + call multipole_eval(this % multipole, E, sqrtkT, sig_s, sig_a, sig_f) - micro_xs % total = sig_t + micro_xs % total = sig_s + sig_a + micro_xs % elastic = sig_s micro_xs % absorption = sig_a micro_xs % fission = sig_f @@ -1076,9 +1075,6 @@ contains micro_xs % elastic = (ONE - f) * rx % xs(i_temp, i_grid) + & f * rx % xs(i_temp, i_grid + 1) end associate - else - ! For multipole, elastic is total - absorption - micro_xs % elastic = micro_xs % total - micro_xs % absorption end if end subroutine nuclide_calculate_elastic_xs @@ -1130,7 +1126,7 @@ contains ! sections in the resolved resonance regions !=============================================================================== - subroutine multipole_eval(multipole, E, sqrtkT, sig_t, sig_a, sig_f) + subroutine multipole_eval(multipole, E, sqrtkT, sig_s, sig_a, sig_f) type(MultipoleArray), intent(in) :: multipole ! The windowed multipole ! object to process. real(8), intent(in) :: E ! The energy at which to @@ -1138,7 +1134,7 @@ contains real(8), intent(in) :: sqrtkT ! The temperature in the form ! sqrt(kT), at which ! to evaluate the XS. - real(8), intent(out) :: sig_t ! Total cross section + real(8), intent(out) :: sig_s ! Scattering cross section real(8), intent(out) :: sig_a ! Absorption cross section real(8), intent(out) :: sig_f ! Fission cross section complex(8) :: psi_chi ! The value of the psi-chi function for the @@ -1146,7 +1142,6 @@ contains complex(8) :: c_temp ! complex temporary variable complex(8) :: w_val ! The faddeeva function evaluated at Z complex(8) :: Z ! sqrt(atomic weight ratio / kT) * (sqrt(E) - pole) - complex(8) :: sig_t_factor(multipole % num_l) real(8) :: broadened_polynomials(multipole % fit_order + 1) real(8) :: sqrtE ! sqrt(E), eV real(8) :: invE ! 1/E, eV @@ -1166,18 +1161,13 @@ contains invE = ONE / E ! Locate us. - i_window = floor((sqrtE - sqrt(multipole % start_E)) / multipole % spacing & + i_window = floor((sqrtE - sqrt(multipole % E_min)) / multipole % spacing & + ONE) - startw = multipole % w_start(i_window) - endw = multipole % w_end(i_window) - - ! Fill in factors. - if (startw <= endw) then - call compute_sig_t_factor(multipole, sqrtE, sig_t_factor) - end if + startw = multipole % windows(1, i_window) + endw = multipole % windows(2, i_window) ! Initialize the ouptut cross sections. - sig_t = ZERO + sig_s = ZERO sig_a = ZERO sig_f = ZERO @@ -1190,7 +1180,7 @@ contains call broaden_wmp_polynomials(E, dopp, multipole % fit_order + 1, & broadened_polynomials) do i_poly = 1, multipole % fit_order+1 - sig_t = sig_t + multipole % curvefit(FIT_T, i_poly, i_window) & + sig_s = sig_s + multipole % curvefit(FIT_S, i_poly, i_window) & * broadened_polynomials(i_poly) sig_a = sig_a + multipole % curvefit(FIT_A, i_poly, i_window) & * broadened_polynomials(i_poly) @@ -1202,7 +1192,7 @@ contains else ! Evaluate as if it were a polynomial temp = invE do i_poly = 1, multipole % fit_order+1 - sig_t = sig_t + multipole % curvefit(FIT_T, i_poly, i_window) * temp + sig_s = sig_s + multipole % curvefit(FIT_S, i_poly, i_window) * temp sig_a = sig_a + multipole % curvefit(FIT_A, i_poly, i_window) * temp if (multipole % fissionable) then sig_f = sig_f + multipole % curvefit(FIT_F, i_poly, i_window) * temp @@ -1219,21 +1209,10 @@ contains do i_pole = startw, endw psi_chi = -ONEI / (multipole % data(MP_EA, i_pole) - sqrtE) c_temp = psi_chi / E - if (multipole % formalism == FORM_MLBW) then - sig_t = sig_t + real(multipole % data(MLBW_RT, i_pole) * c_temp * & - sig_t_factor(multipole % l_value(i_pole))) & - + real(multipole % data(MLBW_RX, i_pole) * c_temp) - sig_a = sig_a + real(multipole % data(MLBW_RA, i_pole) * c_temp) - if (multipole % fissionable) then - sig_f = sig_f + real(multipole % data(MLBW_RF, i_pole) * c_temp) - end if - else if (multipole % formalism == FORM_RM) then - sig_t = sig_t + real(multipole % data(RM_RT, i_pole) * c_temp * & - sig_t_factor(multipole % l_value(i_pole))) - sig_a = sig_a + real(multipole % data(RM_RA, i_pole) * c_temp) - if (multipole % fissionable) then - sig_f = sig_f + real(multipole % data(RM_RF, i_pole) * c_temp) - end if + sig_s = sig_s + real(multipole % data(MP_RS, i_pole) * c_temp) + sig_a = sig_a + real(multipole % data(MP_RA, i_pole) * c_temp) + if (multipole % fissionable) then + sig_f = sig_f + real(multipole % data(MP_RF, i_pole) * c_temp) end if end do else @@ -1243,21 +1222,10 @@ contains do i_pole = startw, endw Z = (sqrtE - multipole % data(MP_EA, i_pole)) * dopp w_val = faddeeva(Z) * dopp * invE * SQRT_PI - if (multipole % formalism == FORM_MLBW) then - sig_t = sig_t + real((multipole % data(MLBW_RT, i_pole) * & - sig_t_factor(multipole % l_value(i_pole)) + & - multipole % data(MLBW_RX, i_pole)) * w_val) - sig_a = sig_a + real(multipole % data(MLBW_RA, i_pole) * w_val) - if (multipole % fissionable) then - sig_f = sig_f + real(multipole % data(MLBW_RF, i_pole) * w_val) - end if - else if (multipole % formalism == FORM_RM) then - sig_t = sig_t + real(multipole % data(RM_RT, i_pole) * w_val * & - sig_t_factor(multipole % l_value(i_pole))) - sig_a = sig_a + real(multipole % data(RM_RA, i_pole) * w_val) - if (multipole % fissionable) then - sig_f = sig_f + real(multipole % data(RM_RF, i_pole) * w_val) - end if + sig_s = sig_s + real(multipole % data(MP_RS, i_pole) * w_val) + sig_a = sig_a + real(multipole % data(MP_RA, i_pole) * w_val) + if (multipole % fissionable) then + sig_f = sig_f + real(multipole % data(MP_RF, i_pole) * w_val) end if end do end if @@ -1270,7 +1238,7 @@ contains ! temperature. !=============================================================================== - subroutine multipole_deriv_eval(multipole, E, sqrtkT, sig_t, sig_a, sig_f) + subroutine multipole_deriv_eval(multipole, E, sqrtkT, sig_s, sig_a, sig_f) type(MultipoleArray), intent(in) :: multipole ! The windowed multipole ! object to process. real(8), intent(in) :: E ! The energy at which to @@ -1278,12 +1246,11 @@ contains real(8), intent(in) :: sqrtkT ! The temperature in the form ! sqrt(kT), at which to ! evaluate the XS. - real(8), intent(out) :: sig_t ! Total cross section + real(8), intent(out) :: sig_s ! Scattering cross section real(8), intent(out) :: sig_a ! Absorption cross section real(8), intent(out) :: sig_f ! Fission cross section complex(8) :: w_val ! The faddeeva function evaluated at Z complex(8) :: Z ! sqrt(atomic weight ratio / kT) * (sqrt(E) - pole) - complex(8) :: sig_t_factor(multipole % num_l) real(8) :: sqrtE ! sqrt(E), eV real(8) :: invE ! 1/E, eV real(8) :: dopp ! sqrt(atomic weight ratio / kT) @@ -1305,18 +1272,13 @@ contains &derivatives are not implemented for 0 Kelvin cross sections.") ! Locate us - i_window = floor((sqrtE - sqrt(multipole % start_E)) / multipole % spacing & + i_window = floor((sqrtE - sqrt(multipole % E_min)) / multipole % spacing & + ONE) - startw = multipole % w_start(i_window) - endw = multipole % w_end(i_window) - - ! Fill in factors. - if (startw <= endw) then - call compute_sig_t_factor(multipole, sqrtE, sig_t_factor) - end if + startw = multipole % windows(1, i_window) + endw = multipole % windows(2, i_window) ! Initialize the ouptut cross sections. - sig_t = ZERO + sig_s = ZERO sig_a = ZERO sig_f = ZERO @@ -1333,61 +1295,18 @@ contains do i_pole = startw, endw Z = (sqrtE - multipole % data(MP_EA, i_pole)) * dopp w_val = -invE * SQRT_PI * HALF * w_derivative(Z, 2) - if (multipole % formalism == FORM_MLBW) then - sig_t = sig_t + real((multipole % data(MLBW_RT, i_pole) * & - sig_t_factor(multipole%l_value(i_pole)) + & - multipole % data(MLBW_RX, i_pole)) * w_val) - sig_a = sig_a + real(multipole % data(MLBW_RA, i_pole) * w_val) - if (multipole % fissionable) then - sig_f = sig_f + real(multipole % data(MLBW_RF, i_pole) * w_val) - end if - else if (multipole % formalism == FORM_RM) then - sig_t = sig_t + real(multipole % data(RM_RT, i_pole) * w_val * & - sig_t_factor(multipole % l_value(i_pole))) - sig_a = sig_a + real(multipole % data(RM_RA, i_pole) * w_val) - if (multipole % fissionable) then - sig_f = sig_f + real(multipole % data(RM_RF, i_pole) * w_val) - end if + sig_s = sig_s + real(multipole % data(MP_RS, i_pole) * w_val) + sig_a = sig_a + real(multipole % data(MP_RA, i_pole) * w_val) + if (multipole % fissionable) then + sig_f = sig_f + real(multipole % data(MP_RF, i_pole) * w_val) end if end do - sig_t = -HALF*multipole % sqrtAWR / sqrt(K_BOLTZMANN) * T**(-1.5) * sig_t + sig_s = -HALF*multipole % sqrtAWR / sqrt(K_BOLTZMANN) * T**(-1.5) * sig_s sig_a = -HALF*multipole % sqrtAWR / sqrt(K_BOLTZMANN) * T**(-1.5) * sig_a sig_f = -HALF*multipole % sqrtAWR / sqrt(K_BOLTZMANN) * T**(-1.5) * sig_f end if end subroutine multipole_deriv_eval -!=============================================================================== -! COMPUTE_SIG_T_FACTOR calculates the sig_t_factor, a factor inside of the sig_t -! equation not present in the sig_a and sig_f equations. -!=============================================================================== - - subroutine compute_sig_t_factor(multipole, sqrtE, sig_t_factor) - type(MultipoleArray), intent(in) :: multipole - real(8), intent(in) :: sqrtE - complex(8), intent(out) :: sig_t_factor(multipole % num_l) - - integer :: iL - real(8) :: twophi(multipole % num_l) - real(8) :: arg - - do iL = 1, multipole % num_l - twophi(iL) = multipole % pseudo_k0RS(iL) * sqrtE - if (iL == 2) then - twophi(iL) = twophi(iL) - atan(twophi(iL)) - else if (iL == 3) then - arg = 3.0_8 * twophi(iL) / (3.0_8 - twophi(iL)**2) - twophi(iL) = twophi(iL) - atan(arg) - else if (iL == 4) then - arg = twophi(iL) * (15.0_8 - twophi(iL)**2) & - / (15.0_8 - 6.0_8 * twophi(iL)**2) - twophi(iL) = twophi(iL) - atan(arg) - end if - end do - - twophi = 2.0_8 * twophi - sig_t_factor = cmplx(cos(twophi), -sin(twophi), KIND=8) - end subroutine compute_sig_t_factor - !=============================================================================== ! 0K_ELASTIC_XS determines the microscopic 0K elastic cross section ! for a given nuclide at the trial relative energy used in resonance scattering diff --git a/src/physics.F90 b/src/physics.F90 index d5f6302a82..fa75fa0ed9 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -526,8 +526,8 @@ contains ! Check to see if we are in a windowed multipole range. WMP only supports ! the first fission reaction. if (nuc % mp_present) then - if (E >= nuc % multipole % start_E .and. & - E <= nuc % multipole % end_E) then + if (E >= nuc % multipole % E_min .and. & + E <= nuc % multipole % E_max) then i_reaction = nuc % index_fission(1) return end if diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 2c660ce87b..2365ec46f2 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -3009,7 +3009,7 @@ contains integer :: l logical :: scoring_diff_nuclide real(8) :: flux_deriv - real(8) :: dsig_t, dsig_a, dsig_f, cum_dsig + real(8) :: dsig_s, dsig_a, dsig_f, cum_dsig if (score == ZERO) return @@ -3250,17 +3250,18 @@ contains if (mat % nuclide(l) == p % event_nuclide) exit end do - dsig_t = ZERO + dsig_s = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & - + dsig_t * mat % atom_density(l) / material_xs % total) + + (dsig_s + dsig_a) * mat % atom_density(l) & + / material_xs % total) end associate else score = score * flux_deriv @@ -3276,18 +3277,17 @@ contains if (mat % nuclide(l) == p % event_nuclide) exit end do - dsig_t = ZERO + dsig_s = ZERO dsig_a = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate - score = score * (flux_deriv + (dsig_t - dsig_a) & - * mat % atom_density(l) / & + score = score * (flux_deriv + dsig_s * mat % atom_density(l) / & (material_xs % total - material_xs % absorption)) end associate else @@ -3306,10 +3306,10 @@ contains dsig_a = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv + dsig_a * mat % atom_density(l) & @@ -3331,10 +3331,10 @@ contains dsig_f = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & @@ -3356,10 +3356,10 @@ contains dsig_f = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & @@ -3392,12 +3392,13 @@ contains do l = 1, mat % n_nuclides associate (nuc => nuclides(mat % nuclide(l))) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E .and. & + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max .and. & micro_xs(mat % nuclide(l)) % total > ZERO) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) - cum_dsig = cum_dsig + dsig_t * mat % atom_density(l) + p % sqrtkT, dsig_s, dsig_a, dsig_f) + cum_dsig = cum_dsig + (dsig_s + dsig_a) & + * mat % atom_density(l) end if end associate end do @@ -3406,17 +3407,17 @@ contains + cum_dsig / material_xs % total) else if (materials(p % material) % id == deriv % diff_material & .and. material_xs % total > ZERO) then - dsig_t = ZERO + dsig_s = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & - + dsig_t / micro_xs(i_nuclide) % total) + + (dsig_s + dsig_a) / micro_xs(i_nuclide) % total) else score = score * flux_deriv end if @@ -3430,14 +3431,13 @@ contains do l = 1, mat % n_nuclides associate (nuc => nuclides(mat % nuclide(l))) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E .and. & + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max .and. & (micro_xs(mat % nuclide(l)) % total & - micro_xs(mat % nuclide(l)) % absorption) > ZERO) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) - cum_dsig = cum_dsig & - + (dsig_t - dsig_a) * mat % atom_density(l) + p % sqrtkT, dsig_s, dsig_a, dsig_f) + cum_dsig = cum_dsig + dsig_s * mat % atom_density(l) end if end associate end do @@ -3447,17 +3447,17 @@ contains else if ( materials(p % material) % id == deriv % diff_material & .and. (material_xs % total - material_xs % absorption) > ZERO)& then - dsig_t = ZERO + dsig_s = ZERO dsig_a = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate - score = score * (flux_deriv + (dsig_t - dsig_a) & + score = score * (flux_deriv + dsig_s & / (micro_xs(i_nuclide) % total & - micro_xs(i_nuclide) % absorption)) else @@ -3473,11 +3473,11 @@ contains do l = 1, mat % n_nuclides associate (nuc => nuclides(mat % nuclide(l))) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E .and. & + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max .and. & micro_xs(mat % nuclide(l)) % absorption > ZERO) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) cum_dsig = cum_dsig + dsig_a * mat % atom_density(l) end if end associate @@ -3490,10 +3490,10 @@ contains dsig_a = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & @@ -3511,11 +3511,11 @@ contains do l = 1, mat % n_nuclides associate (nuc => nuclides(mat % nuclide(l))) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E .and. & + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max .and. & micro_xs(mat % nuclide(l)) % fission > ZERO) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) cum_dsig = cum_dsig + dsig_f * mat % atom_density(l) end if end associate @@ -3528,10 +3528,10 @@ contains dsig_f = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & @@ -3549,11 +3549,11 @@ contains do l = 1, mat % n_nuclides associate (nuc => nuclides(mat % nuclide(l))) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E .and. & + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max .and. & micro_xs(mat % nuclide(l)) % nu_fission > ZERO) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) cum_dsig = cum_dsig + dsig_f * mat % atom_density(l) & * micro_xs(mat % nuclide(l)) % nu_fission & / micro_xs(mat % nuclide(l)) % fission @@ -3568,10 +3568,10 @@ contains dsig_f = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) end if end associate score = score * (flux_deriv & @@ -3603,7 +3603,7 @@ contains real(8), intent(in) :: distance ! Neutron flight distance integer :: i, l - real(8) :: dsig_t, dsig_a, dsig_f + real(8) :: dsig_s, dsig_a, dsig_f ! A void material cannot be perturbed so it will not affect flux derivatives if (p % material == MATERIAL_VOID) return @@ -3640,15 +3640,15 @@ contains do l=1, mat % n_nuclides associate (nuc => nuclides(mat % nuclide(l))) if (nuc % mp_present .and. & - p % E >= nuc % multipole % start_E .and. & - p % E <= nuc % multipole % end_E) then + p % E >= nuc % multipole % E_min .and. & + p % E <= nuc % multipole % E_max) then ! phi is proportional to e^(-Sigma_tot * dist) ! (1 / phi) * (d_phi / d_T) = - (d_Sigma_tot / d_T) * dist ! (1 / phi) * (d_phi / d_T) = - N (d_sigma_tot / d_T) * dist call multipole_deriv_eval(nuc % multipole, p % E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) + p % sqrtkT, dsig_s, dsig_a, dsig_f) deriv % flux_deriv = deriv % flux_deriv & - - distance * dsig_t * mat % atom_density(l) + - distance * (dsig_s + dsig_a) * mat % atom_density(l) end if end associate end do @@ -3679,7 +3679,7 @@ contains type(Particle), intent(in) :: p integer :: i, j, l - real(8) :: dsig_t, dsig_a, dsig_f + real(8) :: dsig_s, dsig_a, dsig_f ! A void material cannot be perturbed so it will not affect flux derivatives if (p % material == MATERIAL_VOID) return @@ -3727,14 +3727,14 @@ contains associate (nuc => nuclides(mat % nuclide(l))) if (mat % nuclide(l) == p % event_nuclide .and. & nuc % mp_present .and. & - p % last_E >= nuc % multipole % start_E .and. & - p % last_E <= nuc % multipole % end_E) then + p % last_E >= nuc % multipole % E_min .and. & + p % last_E <= nuc % multipole % E_max) then ! phi is proportional to Sigma_s ! (1 / phi) * (d_phi / d_T) = (d_Sigma_s / d_T) / Sigma_s ! (1 / phi) * (d_phi / d_T) = (d_sigma_s / d_T) / sigma_s call multipole_deriv_eval(nuc % multipole, p % last_E, & - p % sqrtkT, dsig_t, dsig_a, dsig_f) - deriv % flux_deriv = deriv % flux_deriv + (dsig_t - dsig_a)& + p % sqrtkT, dsig_s, dsig_a, dsig_f) + deriv % flux_deriv = deriv % flux_deriv + (dsig_s + dsig_a)& / (micro_xs(mat % nuclide(l)) % total & - micro_xs(mat % nuclide(l)) % absorption) ! Note that this is an approximation! The real scattering From 26c54e5483203ba8df9245791b674828300372ba Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 8 May 2017 09:24:40 -0500 Subject: [PATCH 06/43] Add Material.from_xml_element and Materials.from_xml classmethods --- openmc/material.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/openmc/material.py b/openmc/material.py index dac2fe14af..c8d4c9fd09 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -907,6 +907,58 @@ class Material(IDManagerMixin): return element + @classmethod + def from_xml_element(cls, elem): + """Generate material from an XML element + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + XML element + + Returns + ------- + openmc.Material + Material generated from XML element + + """ + mat_id = int(elem.get('id')) + mat = cls(mat_id) + mat.name = elem.get('name') + mat.temperature = elem.get('temperature') + mat.depletable = bool(elem.get('depletable')) + + # Get each nuclide + for nuclide in elem.findall('nuclide'): + name = nuclide.attrib['name'] + if 'ao' in nuclide.attrib: + mat.add_nuclide(name, float(nuclide.attrib['ao'])) + elif 'wo' in nuclide.attrib: + mat.add_nuclide(name, float(nuclide.attrib['wo']), 'wo') + + # Get each element + for element in elem.findall('element'): + name = element.attrib['name'] + if 'ao' in element.attrib: + mat.add_element(name, float(element.attrib['ao'])) + elif 'wo' in element.attrib: + mat.add_element(name, float(element.attrib['wo']), 'wo') + + # Get each S(a,b) table + for sab in elem.findall('sab'): + mat.add_s_alpha_beta(sab.get('name')) + + # Get total material density + density = elem.find('density') + units = density.get('units') + if units == 'sum': + mat.set_density(units) + else: + value = float(density.get('value')) + mat.set_density(units, value) + + return mat + class Materials(cv.CheckedList): """Collection of Materials used for an OpenMC simulation. @@ -1031,3 +1083,35 @@ class Materials(cv.CheckedList): # Write the XML Tree to the materials.xml file tree = ET.ElementTree(root_element) tree.write(path, xml_declaration=True, encoding='utf-8') + + @classmethod + def from_xml(cls, path='materials.xml'): + """Generate materials collection from XML file + + Parameters + ---------- + path : str, optional + Path to materials XML file + + Returns + ------- + openmc.Materials + Materials collection + + """ + tree = ET.parse(path) + root = tree.getroot() + + materials = cls() + for material in root.findall('material'): + materials.append(Material.from_xml_element(material)) + + xs = tree.find('cross_sections') + if xs is not None: + materials.cross_sections = xs.text + + mpl = tree.find('multipole_library') + if mpl is not None: + materials.multipole_library = mpl.text + + return materials From b9ade1e7581ea99f5469614047089cd79d7f9db8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 10 Aug 2018 11:46:14 -0500 Subject: [PATCH 07/43] Fix input for lattice_hex test --- .../regression_tests/lattice_hex/geometry.xml | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/regression_tests/lattice_hex/geometry.xml b/tests/regression_tests/lattice_hex/geometry.xml index cfe39849cb..fa6a18ee16 100644 --- a/tests/regression_tests/lattice_hex/geometry.xml +++ b/tests/regression_tests/lattice_hex/geometry.xml @@ -7,42 +7,42 @@ - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - + + + + + - - - + + + - + From f42a75a9e14c9898ed8b5f15aa5f6f4c66aa789a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 10 Aug 2018 11:46:51 -0500 Subject: [PATCH 08/43] Add Geometry.from_xml() capability --- openmc/geometry.py | 189 ++++++++++++++++++++++++++++++++++++++++++++- openmc/material.py | 11 ++- openmc/surface.py | 130 ++++++++++++++++++------------- 3 files changed, 273 insertions(+), 57 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 1ee93dfd6d..471de202b5 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -1,8 +1,10 @@ -from collections import OrderedDict +from collections import OrderedDict, defaultdict from collections.abc import Iterable from copy import deepcopy from xml.etree import ElementTree as ET +import numpy as np + import openmc from openmc.clean_xml import clean_xml_indentation from openmc.checkvalue import check_type @@ -98,6 +100,191 @@ class Geometry(object): tree = ET.ElementTree(root_element) tree.write(path, xml_declaration=True, encoding='utf-8') + @classmethod + def from_xml(cls, path='geometry.xml', materials=None): + """Generate geometry from XML file + + Parameters + ---------- + path : str, optional + Path to geometry XML file + materials : openmc.Materials or None + Materials used to assign to cells. If None, an attempt is made to + generate it from the materials.xml file. + + Returns + ------- + openmc.Geometry + Geometry object + + """ + # Helper function to get value from an attribute/element + def get(elem, name, default=None): + if name in elem.attrib: + return elem.get(name, default) + else: + child = elem.find(name) + return child.text if child is not None else default + + # Helper function for keeping a cache of Universe instances + universes = {} + def get_universe(univ_id): + if univ_id not in universes: + univ = openmc.Universe(univ_id) + universes[univ_id] = univ + return universes[univ_id] + + tree = ET.parse(path) + root = tree.getroot() + + # Get surfaces + surfaces = {} + periodic = {} + for surface in root.findall('surface'): + s = openmc.Surface.from_xml_element(surface) + surfaces[s.id] = s + + # Check for periodic surface + other_id = get(surface, 'periodic_surface_id') + if other_id is not None: + periodic[s.id] = int(other_id) + + # Apply periodic surfaces + for s1, s2 in periodic.items(): + surfaces[s1].periodic_surface = surfaces[s2] + + # Dictionary that maps each universe to a list of cells/lattices that + # contain it (needed to determine which universe is the root) + child_of = defaultdict(list) + + for elem in root.findall('lattice'): + lat_id = int(get(elem, 'id')) + name = get(elem, 'name') + lat = openmc.RectLattice(lat_id, name) + lat.lower_left = [float(i) for i in get(elem, 'lower_left').split()] + lat.pitch = [float(i) for i in get(elem, 'pitch').split()] + outer = get(elem, 'outer') + if outer is not None: + lat.outer = get_universe(int(outer)) + universes[lat_id] = lat + + # Get array of universes + dimension = get(elem, 'dimension').split() + shape = np.array(dimension, dtype=int)[::-1] + uarray = np.array([get_universe(int(i)) for i in + get(elem, 'universes').split()]) + for u in uarray: + child_of[u].append(lat) + uarray.shape = shape + lat.universes = uarray + + for elem in root.findall('hex_lattice'): + lat_id = int(get(elem, 'id')) + name = get(elem, 'name') + lat = openmc.HexLattice(lat_id, name) + lat.center = [float(i) for i in get(elem, 'center').split()] + lat.pitch = [float(i) for i in get(elem, 'pitch').split()] + outer = get(elem, 'outer') + if outer is not None: + lat.outer = get_universe(int(outer)) + universes[lat_id] = lat + + # Get nested lists of universes + lat._num_rings = n_rings = int(get(elem, 'n_rings')) + lat._num_axial = n_axial = int(get(elem, 'n_axial', 1)) + + # Create empty nested lists for one axial level + univs = [[None for _ in range(max(6*(n_rings - 1 - r), 1))] + for r in range(n_rings)] + if n_axial > 1: + univs = [deepcopy(univs) for i in range(n_axial)] + + # Get flat array of universes numbers + uarray = np.array([get_universe(int(i)) for i in + get(elem, 'universes').split()]) + for u in uarray: + child_of[u].append(lat) + + # Fill nested lists + j = 0 + for z in range(n_axial): + # Get list for a single axial level + axial_level = univs[z] if n_axial > 1 else univs + + # Start iterating from top + x, alpha = 0, n_rings - 1 + while True: + # Set entry in list based on (x,alpha,z) coordinates + _, i_ring, i_within = lat.get_universe_index((x, alpha, z)) + axial_level[i_ring][i_within] = uarray[j] + + # Move to the right + x += 2 + alpha -= 1 + if not lat.is_valid_index((x, alpha, z)): + # Move down in y direction + alpha += x - 1 + x = 1 - x + if not lat.is_valid_index((x, alpha, z)): + # Move to the right + x += 2 + alpha -= 1 + if not lat.is_valid_index((x, alpha, z)): + # Reached the bottom + break + j += 1 + lat.universes = univs + + # Create dictionary to easily look up materials + if materials is None: + materials = openmc.Materials.from_xml() + mats = {str(m.id): m for m in materials} + mats['void'] = None + + for elem in root.findall('cell'): + cell_id = int(get(elem, 'id')) + name = get(elem, 'name') + c = openmc.Cell(cell_id, name) + + # Assign material/distributed materials or fill + mat_text = get(elem, 'material') + if mat_text is not None: + mat_ids = mat_text.split() + if len(mat_ids) > 1: + c.fill = [mats[i] for i in mat_ids] + else: + c.fill = mats[mat_ids[0]] + else: + fill_id = int(get(elem, 'fill')) + c.fill = get_universe(fill_id) + child_of[c.fill].append(c) + + # Assign region + region = get(elem, 'region') + if region is not None: + c.region = openmc.Region.from_expression(region, surfaces) + + # Check for other attributes + t = get(elem, 'temperature') + if t is not None: + c.temperature = float(t) + for key in ('temperature', 'rotation', 'translation'): + value = get(elem, key) + if value is not None: + setattr(c, key, [float(x) for x in value.split()]) + + # Add this cell to appropriate universe + univ_id = int(get(elem, 'universe', 0)) + get_universe(univ_id).add_cell(c) + + # Determine which universe is the root by finding one which is not a + # child of any other object + for u in universes.values(): + if not child_of[u]: + return cls(u) + else: + raise ValueError('Error determining root universe.') + def find(self, point): """Find cells/universes/lattices which contain a given point diff --git a/openmc/material.py b/openmc/material.py index c8d4c9fd09..3d54da31be 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -946,7 +946,8 @@ class Material(IDManagerMixin): # Get each S(a,b) table for sab in elem.findall('sab'): - mat.add_s_alpha_beta(sab.get('name')) + fraction = float(sab.get('fraction', 1.0)) + mat.add_s_alpha_beta(sab.get('name'), fraction) # Get total material density density = elem.find('density') @@ -957,6 +958,11 @@ class Material(IDManagerMixin): value = float(density.get('value')) mat.set_density(units, value) + # Check for isotropic scattering nuclides + isotropic = elem.find('isotropic') + if isotropic is not None: + mat.isotropic = isotropic.text.split() + return mat @@ -1102,14 +1108,15 @@ class Materials(cv.CheckedList): tree = ET.parse(path) root = tree.getroot() + # Generate each material materials = cls() for material in root.findall('material'): materials.append(Material.from_xml_element(material)) + # Check for cross sections settings xs = tree.find('cross_sections') if xs is not None: materials.cross_sections = xs.text - mpl = tree.find('multipole_library') if mpl is not None: materials.multipole_library = mpl.text diff --git a/openmc/surface.py b/openmc/surface.py index ad5053e370..826ac5cc8d 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -59,7 +59,6 @@ class Surface(IDManagerMixin): def __init__(self, surface_id=None, boundary_type='transmission', name=''): self.id = surface_id self.name = name - self._type = '' self.boundary_type = boundary_type # A dictionary of the quadratic surface coefficients @@ -67,10 +66,6 @@ class Surface(IDManagerMixin): # Value - coefficient value self._coefficients = {} - # An ordered list of the coefficient names to export to XML in the - # proper order - self._coeff_keys = [] - def __neg__(self): return Halfspace(self, '-') @@ -203,6 +198,49 @@ class Surface(IDManagerMixin): return element + @staticmethod + def from_xml_element(elem): + """Generate surface from an XML element + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + XML element + + Returns + ------- + openmc.Surface + Instance of a surface subclass + + """ + + # Determine appropriate class + surf_type = elem.get('type') + surface_classes = { + 'plane': Plane, + 'x-plane': XPlane, + 'y-plane': YPlane, + 'z-plane': ZPlane, + 'x-cylinder': XCylinder, + 'y-cylinder': YCylinder, + 'z-cylinder': ZCylinder, + 'sphere': Sphere, + 'x-cone': XCone, + 'y-cone': YCone, + 'z-cone': ZCone, + 'quadric': Quadric, + } + cls = surface_classes[surf_type] + + # Determine ID, boundary type, coefficients + kwargs = {} + kwargs['surface_id'] = int(elem.get('id')) + kwargs['boundary_type'] = elem.get('boundary', 'transmission') + coeffs = [float(x) for x in elem.get('coeffs').split()] + kwargs.update(dict(zip(cls._coeff_keys, coeffs))) + + return cls(**kwargs) + @staticmethod def from_hdf5(group): """Create surface from HDF5 group @@ -324,12 +362,12 @@ class Plane(Surface): """ + _type = 'plane' + _coeff_keys = ('A', 'B', 'C', 'D') + def __init__(self, surface_id=None, boundary_type='transmission', A=1., B=0., C=0., D=0., name=''): super().__init__(surface_id, boundary_type, name=name) - - self._type = 'plane' - self._coeff_keys = ['A', 'B', 'C', 'D'] self._periodic_surface = None self.a = A self.b = B @@ -458,12 +496,12 @@ class XPlane(Plane): """ + _type = 'x-plane' + _coeff_keys = ('x0',) + def __init__(self, surface_id=None, boundary_type='transmission', x0=0., name=''): super().__init__(surface_id, boundary_type, name=name) - - self._type = 'x-plane' - self._coeff_keys = ['x0'] self.x0 = x0 @property @@ -563,13 +601,13 @@ class YPlane(Plane): """ + _type = 'y-plane' + _coeff_keys = ('y0',) + def __init__(self, surface_id=None, boundary_type='transmission', y0=0., name=''): # Initialize YPlane class attributes super().__init__(surface_id, boundary_type, name=name) - - self._type = 'y-plane' - self._coeff_keys = ['y0'] self.y0 = y0 @property @@ -669,13 +707,13 @@ class ZPlane(Plane): """ + _type = 'z-plane' + _coeff_keys = ('z0',) + def __init__(self, surface_id=None, boundary_type='transmission', z0=0., name=''): # Initialize ZPlane class attributes super().__init__(surface_id, boundary_type, name=name) - - self._type = 'z-plane' - self._coeff_keys = ['z0'] self.z0 = z0 @property @@ -774,8 +812,6 @@ class Cylinder(Surface, metaclass=ABCMeta): def __init__(self, surface_id=None, boundary_type='transmission', R=1., name=''): super().__init__(surface_id, boundary_type, name=name) - - self._coeff_keys = ['R'] self.r = R @property @@ -831,12 +867,12 @@ class XCylinder(Cylinder): """ + _type = 'x-cylinder' + _coeff_keys = ('y0', 'z0', 'R') + def __init__(self, surface_id=None, boundary_type='transmission', y0=0., z0=0., R=1., name=''): super().__init__(surface_id, boundary_type, R, name=name) - - self._type = 'x-cylinder' - self._coeff_keys = ['y0', 'z0', 'R'] self.y0 = y0 self.z0 = z0 @@ -953,12 +989,12 @@ class YCylinder(Cylinder): """ + _type = 'y-cylinder' + _coeff_keys = ('x0', 'z0', 'R') + def __init__(self, surface_id=None, boundary_type='transmission', x0=0., z0=0., R=1., name=''): super().__init__(surface_id, boundary_type, R, name=name) - - self._type = 'y-cylinder' - self._coeff_keys = ['x0', 'z0', 'R'] self.x0 = x0 self.z0 = z0 @@ -1075,12 +1111,12 @@ class ZCylinder(Cylinder): """ + _type = 'z-cylinder' + _coeff_keys = ('x0', 'y0', 'R') + def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., R=1., name=''): super().__init__(surface_id, boundary_type, R, name=name) - - self._type = 'z-cylinder' - self._coeff_keys = ['x0', 'y0', 'R'] self.x0 = x0 self.y0 = y0 @@ -1201,12 +1237,12 @@ class Sphere(Surface): """ + _type = 'sphere' + _coeff_keys = ('x0', 'y0', 'z0', 'R') + def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R=1., name=''): super().__init__(surface_id, boundary_type, name=name) - - self._type = 'sphere' - self._coeff_keys = ['x0', 'y0', 'z0', 'R'] self.x0 = x0 self.y0 = y0 self.z0 = z0 @@ -1348,11 +1384,12 @@ class Cone(Surface, metaclass=ABCMeta): Type of the surface """ + + _coeff_keys = ('x0', 'y0', 'z0', 'R2') + def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R2=1., name=''): super().__init__(surface_id, boundary_type, name=name) - - self._coeff_keys = ['x0', 'y0', 'z0', 'R2'] self.x0 = x0 self.y0 = y0 self.z0 = z0 @@ -1443,12 +1480,7 @@ class XCone(Cone): """ - def __init__(self, surface_id=None, boundary_type='transmission', - x0=0., y0=0., z0=0., R2=1., name=''): - super().__init__(surface_id, boundary_type, x0, y0, - z0, R2, name=name) - - self._type = 'x-cone' + _type = 'x-cone' def evaluate(self, point): """Evaluate the surface equation at a given point. @@ -1519,12 +1551,7 @@ class YCone(Cone): """ - def __init__(self, surface_id=None, boundary_type='transmission', - x0=0., y0=0., z0=0., R2=1., name=''): - super().__init__(surface_id, boundary_type, x0, y0, z0, - R2, name=name) - - self._type = 'y-cone' + _type = 'y-cone' def evaluate(self, point): """Evaluate the surface equation at a given point. @@ -1595,12 +1622,7 @@ class ZCone(Cone): """ - def __init__(self, surface_id=None, boundary_type='transmission', - x0=0., y0=0., z0=0., R2=1., name=''): - super().__init__(surface_id, boundary_type, x0, y0, z0, - R2, name=name) - - self._type = 'z-cone' + _type = 'z-cone' def evaluate(self, point): """Evaluate the surface equation at a given point. @@ -1659,13 +1681,13 @@ class Quadric(Surface): """ + _type = 'quadric' + _coeff_keys = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k') + def __init__(self, surface_id=None, boundary_type='transmission', a=0., b=0., c=0., d=0., e=0., f=0., g=0., h=0., j=0., k=0., name=''): super().__init__(surface_id, boundary_type, name=name) - - self._type = 'quadric' - self._coeff_keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k'] self.a = a self.b = b self.c = c From c5632794de1d029ad758c3041bf978adf0820596 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 17 Aug 2018 10:35:24 -0500 Subject: [PATCH 09/43] Add tests for from_xml methods --- openmc/material.py | 8 ----- tests/unit_tests/conftest.py | 51 +++++++++++++++++++++++++++++++ tests/unit_tests/test_geometry.py | 11 +++++++ tests/unit_tests/test_material.py | 34 +++++++++++++++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/openmc/material.py b/openmc/material.py index 3d54da31be..d19a5f4b99 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -936,14 +936,6 @@ class Material(IDManagerMixin): elif 'wo' in nuclide.attrib: mat.add_nuclide(name, float(nuclide.attrib['wo']), 'wo') - # Get each element - for element in elem.findall('element'): - name = element.attrib['name'] - if 'ao' in element.attrib: - mat.add_element(name, float(element.attrib['ao'])) - elif 'wo' in element.attrib: - mat.add_element(name, float(element.attrib['wo']), 'wo') - # Get each S(a,b) table for sab in elem.findall('sab'): fraction = float(sab.get('fraction', 1.0)) diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index 1434eaf3b4..94fa6abc76 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -60,3 +60,54 @@ def cell_with_lattice(): return ([inside_cyl, outside_cyl, main_cell], [m_inside[0], m_inside[1], m_inside[3], m_outside], univ, lattice) + +@pytest.fixture +def mixed_lattice_model(uo2, water): + cyl = openmc.ZCylinder(R=0.4) + c1 = openmc.Cell(fill=uo2, region=-cyl) + c1.temperature = 600.0 + c2 = openmc.Cell(fill=water, region=+cyl) + pin = openmc.Universe(cells=[c1, c2]) + + empty = openmc.Cell() + empty_univ = openmc.Universe(cells=[empty]) + + hex_lattice = openmc.HexLattice() + hex_lattice.center = (0.0, 0.0) + hex_lattice.pitch = (1.2, 10.0) + outer_ring = [pin]*6 + inner_ring = [empty_univ] + axial_level = [outer_ring, inner_ring] + hex_lattice.universes = [axial_level]*3 + hex_lattice.outer = empty_univ + + cell_hex = openmc.Cell(fill=hex_lattice) + u = openmc.Universe(cells=[cell_hex]) + rotated_cell_hex = openmc.Cell(fill=u) + rotated_cell_hex.rotation = (0., 0., 30.) + ur = openmc.Universe(cells=[rotated_cell_hex]) + + d = 6.0 + rect_lattice = openmc.RectLattice() + rect_lattice.lower_left = (-d, -d) + rect_lattice.pitch = (d, d) + rect_lattice.outer = empty_univ + rect_lattice.universes = [ + [ur, empty_univ], + [empty_univ, u] + ] + + xmin = openmc.XPlane(x0=-d, boundary_type='periodic') + xmax = openmc.XPlane(x0=d, boundary_type='periodic') + xmin.periodic_surface = xmax + ymin = openmc.YPlane(y0=-d, boundary_type='periodic') + ymax = openmc.YPlane(y0=d, boundary_type='periodic') + main_cell = openmc.Cell(fill=rect_lattice, + region=+xmin & -xmax & +ymin & -ymax) + + # Create geometry and use unique material in each fuel cell + geometry = openmc.Geometry([main_cell]) + geometry.determine_paths() + c1.fill = [water.clone() for i in range(c1.num_instances)] + + return openmc.model.Model(geometry) diff --git a/tests/unit_tests/test_geometry.py b/tests/unit_tests/test_geometry.py index 93d2fa6341..b5d6076bb3 100644 --- a/tests/unit_tests/test_geometry.py +++ b/tests/unit_tests/test_geometry.py @@ -244,3 +244,14 @@ def test_determine_paths(cell_with_lattice): for i in range(4): assert geom.get_instances(cells[0].paths[i]) == i assert geom.get_instances(mats[-1].paths[i]) == i + +def test_from_xml(run_in_tmpdir, mixed_lattice_model): + # Export model + mixed_lattice_model.export_to_xml() + + # Import geometry + geom = openmc.Geometry.from_xml() + assert isinstance(geom, openmc.Geometry) + ll, ur = geom.bounding_box + assert ll == pytest.approx((-6.0, -6.0, -np.inf)) + assert ur == pytest.approx((6.0, 6.0, np.inf)) diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index b7b745408d..7cedd8deef 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -182,3 +182,37 @@ def test_borated_water(): # Test the density override m = openmc.model.borated_water(975, 566.5, 15.51, density=0.9) assert m.density == pytest.approx(0.9, 1e-3) + + +def test_from_xml(run_in_tmpdir): + # Create a materials.xml file + m1 = openmc.Material(1, 'water') + m1.add_nuclide('H1', 1.0) + m1.add_nuclide('O16', 2.0) + m1.add_s_alpha_beta('c_H_in_H2O') + m1.set_density('g/cm3', 0.9) + m1.isotropic = ['H1'] + m2 = openmc.Material(2, 'zirc') + m2.add_nuclide('Zr90', 1.0, 'wo') + m2.set_density('kg/m3', 10.0) + m3 = openmc.Material(3) + m3.add_nuclide('N14', 0.02) + + mats = openmc.Materials([m1, m2, m3]) + mats.cross_sections = 'fake_path.xml' + mats.multipole_library = 'fake_multipole/' + mats.export_to_xml() + + # Regenerate materials from XML + mats = openmc.Materials.from_xml() + assert len(mats) == 3 + m1 = mats[0] + assert m1.id == 1 + assert m1.name == 'water' + assert m1.nuclides == [('H1', 1.0, 'ao'), ('O16', 2.0, 'ao')] + assert m1.isotropic == ['H1'] + m2 = mats[1] + assert m2.nuclides == [('Zr90', 1.0, 'wo')] + assert m2.density == 10.0 + assert m2.density_units == 'kg/m3' + assert mats[2].density_units == 'sum' From 63032ba40a7029d2476c8dd02c81f77d3b143b28 Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 17 Aug 2018 14:22:25 -0400 Subject: [PATCH 10/43] update mutipole tests --- openmc/data/multipole.py | 28 +++++----- .../multipole/results_true.dat | 54 +++++++++---------- tests/unit_tests/test_data_multipole.py | 50 +++++++---------- 3 files changed, 57 insertions(+), 75 deletions(-) diff --git a/openmc/data/multipole.py b/openmc/data/multipole.py index c6e4f123c9..04e6dc20b6 100644 --- a/openmc/data/multipole.py +++ b/openmc/data/multipole.py @@ -209,10 +209,6 @@ class WindowedMultipole(EqualityMixin): def data(self): return self._data - @property - def l_value(self): - return self._l_value - @property def windows(self): return self._windows @@ -228,35 +224,35 @@ class WindowedMultipole(EqualityMixin): @spacing.setter def spacing(self, spacing): if spacing is not None: - check_type('spacing', spacing, Real) - check_greater_than('spacing', spacing, 0.0, equality=False) + cv.check_type('spacing', spacing, Real) + cv.check_greater_than('spacing', spacing, 0.0, equality=False) self._spacing = spacing @sqrtAWR.setter def sqrtAWR(self, sqrtAWR): if sqrtAWR is not None: - check_type('sqrtAWR', sqrtAWR, Real) - check_greater_than('sqrtAWR', sqrtAWR, 0.0, equality=False) + cv.check_type('sqrtAWR', sqrtAWR, Real) + cv.check_greater_than('sqrtAWR', sqrtAWR, 0.0, equality=False) self._sqrtAWR = sqrtAWR @E_min.setter def E_min(self, E_min): if E_min is not None: - check_type('E_min', E_min, Real) - check_greater_than('E_min', E_min, 0.0, equality=True) + cv.check_type('E_min', E_min, Real) + cv.check_greater_than('E_min', E_min, 0.0, equality=True) self._E_min = E_min @E_max.setter def E_max(self, E_max): if E_max is not None: - check_type('E_max', E_max, Real) - check_greater_than('E_max', E_max, 0.0, equality=False) + cv.check_type('E_max', E_max, Real) + cv.check_greater_than('E_max', E_max, 0.0, equality=False) self._E_max = E_max @data.setter def data(self, data): if data is not None: - check_type('data', data, np.ndarray) + cv.check_type('data', data, np.ndarray) if len(data.shape) != 2: raise ValueError('Multipole data arrays must be 2D') if data.shape[1] not in (3, 4): @@ -271,7 +267,7 @@ class WindowedMultipole(EqualityMixin): @windows.setter def windows(self, windows): if windows is not None: - check_type('windows', windows, np.ndarray) + cv.check_type('windows', windows, np.ndarray) if len(windows.shape) != 2: raise ValueError('Multipole windows arrays must be 2D') if not np.issubdtype(windows.dtype, int): @@ -282,7 +278,7 @@ class WindowedMultipole(EqualityMixin): @broaden_poly.setter def broaden_poly(self, broaden_poly): if broaden_poly is not None: - check_type('broaden_poly', broaden_poly, np.ndarray) + cv.check_type('broaden_poly', broaden_poly, np.ndarray) if len(broaden_poly.shape) != 1: raise ValueError('Multipole broaden_poly arrays must be 1D') if not np.issubdtype(broaden_poly.dtype, bool): @@ -293,7 +289,7 @@ class WindowedMultipole(EqualityMixin): @curvefit.setter def curvefit(self, curvefit): if curvefit is not None: - check_type('curvefit', curvefit, np.ndarray) + cv.check_type('curvefit', curvefit, np.ndarray) if len(curvefit.shape) != 3: raise ValueError('Multipole curvefit arrays must be 3D') if curvefit.shape[2] not in (2, 3): # sig_s, sig_a (maybe sig_f) diff --git a/tests/regression_tests/multipole/results_true.dat b/tests/regression_tests/multipole/results_true.dat index 19c34229ff..890e47efd9 100644 --- a/tests/regression_tests/multipole/results_true.dat +++ b/tests/regression_tests/multipole/results_true.dat @@ -1,36 +1,36 @@ k-combined: -1.363786E+00 1.103929E-02 +1.342579E+00 1.221176E-02 tally 1: -3.960375E+00 -3.138356E+00 -2.875799E+00 -1.655329E+00 -5.521904E-01 -6.105083E-02 -4.617974E-01 -4.274130E-02 +3.839794E+00 +2.951721E+00 +2.785273E+00 +1.554128E+00 +5.349716E-01 +5.732174E-02 +4.499834E-01 +4.055011E-02 0.000000E+00 0.000000E+00 -2.254165E+01 -1.016444E+02 +2.258507E+01 +1.020294E+02 0.000000E+00 0.000000E+00 -6.839351E-04 -9.359599E-08 -2.251829E+01 -1.014341E+02 -4.903575E-05 -1.199780E-09 -3.595002E+02 -2.586079E+04 -2.875799E+00 -1.655329E+00 -2.174747E+00 -9.465589E-01 -3.543564E+02 -2.512619E+04 -4.903575E-05 -1.199780E-09 +6.862242E-04 +9.421377E-08 +2.256396E+01 +1.018388E+02 +1.146136E-04 +3.296980E-09 +3.624627E+02 +2.628739E+04 +2.785273E+00 +1.554128E+00 +2.176478E+00 +9.480405E-01 +3.574110E+02 +2.555993E+04 +1.146136E-04 +3.296980E-09 Cell ID = 11 Name = diff --git a/tests/unit_tests/test_data_multipole.py b/tests/unit_tests/test_data_multipole.py index a1cc5bc02c..4683dcd3af 100644 --- a/tests/unit_tests/test_data_multipole.py +++ b/tests/unit_tests/test_data_multipole.py @@ -3,8 +3,6 @@ import os import numpy as np import pytest import openmc.data - - pytestmark = pytest.mark.skipif( 'OPENMC_MULTIPOLE_LIBRARY' not in os.environ, reason='OPENMC_MULTIPOLE_LIBRARY environment variable must be set') @@ -18,44 +16,32 @@ def u235(): @pytest.fixture(scope='module') -def u234(): +def b10(): directory = os.environ['OPENMC_MULTIPOLE_LIBRARY'] - filename = os.path.join(directory, '092234.h5') + filename = os.path.join(directory, '005010.h5') return openmc.data.WindowedMultipole.from_hdf5(filename) -@pytest.fixture(scope='module') -def fe56(): - directory = os.environ['OPENMC_MULTIPOLE_LIBRARY'] - filename = os.path.join(directory, '026056.h5') - return openmc.data.WindowedMultipole.from_hdf5(filename) - - -def test_evaluate_rm(u235): - """Make sure a Reich-Moore multipole object can be called.""" +def test_evaluate(u235): + """Test the cross section evaluation of a library.""" energies = [1e-3, 1.0, 10.0, 50.] - total, absorption, fission = u235(energies, 0.0) - assert total[1] == pytest.approx(90.64895383) - total, absorption, fission = u235(energies, 300.0) - assert total[1] == pytest.approx(91.12534964) + scattering, absorption, fission = u235(energies, 0.0) + assert (scattering[1], absorption[1], fission[1]) == \ + pytest.approx((13.09, 77.56, 67.36), rel=1e-3) + scattering, absorption, fission = u235(energies, 300.0) + assert (scattering[2], absorption[2], fission[2]) == \ + pytest.approx((11.24, 21.26, 15.50), rel=1e-3) -def test_evaluate_mlbw(u234): - """Make sure a Multi-Level Breit-Wigner multipole object can be called.""" - energies = [1e-3, 1.0, 10.0, 50.] - total, absorption, fission = u234(energies, 0.0) - assert total[3] == pytest.approx(15.02827953) - total, absorption, fission = u234(energies, 300.0) - assert total[3] == pytest.approx(15.08269143) - - -def test_high_l(fe56): - """Test a nuclide (Fe56) with a high l-value (4).""" +def test_evaluate_none_poles(b10): + """Test a library with no poles, i.e., purely polynomials.""" energies = [1e-3, 1.0, 10.0, 1e3, 1e5] - total, absorption, fission = fe56(energies, 0.0) - assert total[0] == pytest.approx(25.072619556789267) - total, absorption, fission = fe56(energies, 300.0) - assert total[0] == pytest.approx(27.85535792368082) + scattering, absorption, fission = b10(energies, 0.0) + assert (scattering[0], absorption[0], fission[0]) == \ + pytest.approx((2.201, 19330., 0.), rel=1e-3) + scattering, absorption, fission = b10(energies, 300.0) + assert (scattering[-1], absorption[-1], fission[-1]) == \ + pytest.approx((2.878, 1.982, 0.), rel=1e-3) def test_export_to_hdf5(tmpdir, u235): From e4de659b12e428269b5ce194f15ad428525c4d1c Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 17 Aug 2018 14:42:14 -0400 Subject: [PATCH 11/43] update travis ci scripts to use latest library --- .travis.yml | 3 ++- tools/ci/travis-before-script.sh | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f61fa1db0b..50ef636412 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ cache: directories: - $HOME/nndc_hdf5 - $HOME/endf-b-vii.1 + - $HOME/WMP_Library env: global: - FC=gfortran @@ -25,7 +26,7 @@ env: - OMP_NUM_THREADS=2 - OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml - OPENMC_ENDF_DATA=$HOME/endf-b-vii.1 - - OPENMC_MULTIPOLE_LIBRARY=$HOME/multipole_lib + - OPENMC_MULTIPOLE_LIBRARY=$HOME/WMP_Library/WMP_Library - PATH=$PATH:$HOME/NJOY2016/build - DISPLAY=:99.0 matrix: diff --git a/tools/ci/travis-before-script.sh b/tools/ci/travis-before-script.sh index bbb34358b9..ca7cf75e2c 100755 --- a/tools/ci/travis-before-script.sh +++ b/tools/ci/travis-before-script.sh @@ -17,5 +17,6 @@ if [[ ! -d $ENDF/neutrons || ! -d $ENDF/photoat || ! -d $ENDF/atomic_relax ]]; t fi # Download multipole library -git clone --branch=master git://github.com/smharper/windowed_multipole_library.git wmp_lib -tar -C $HOME -xzvf wmp_lib/multipole_lib.tar.gz +if [[ ! -d $HOME/WMP_Library ]]; then + git lfs clone https://github.com/mit-crpg/WMP_Library.git +fi From 8a20f3cc0ace1ca00aebc7967c926b3cab1d0215 Mon Sep 17 00:00:00 2001 From: liangjg Date: Fri, 17 Aug 2018 16:05:34 -0400 Subject: [PATCH 12/43] check if git-lfs installed in travis --- .travis.yml | 2 +- .../diff_tally/results_true.dat | 220 +++++++++--------- tools/ci/travis-before-script.sh | 11 +- 3 files changed, 120 insertions(+), 113 deletions(-) diff --git a/.travis.yml b/.travis.yml index 50ef636412..ae2ceafa12 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ env: - OMP_NUM_THREADS=2 - OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml - OPENMC_ENDF_DATA=$HOME/endf-b-vii.1 - - OPENMC_MULTIPOLE_LIBRARY=$HOME/WMP_Library/WMP_Library + - OPENMC_MULTIPOLE_LIBRARY=$HOME/WMP_Library - PATH=$PATH:$HOME/NJOY2016/build - DISPLAY=:99.0 matrix: diff --git a/tests/regression_tests/diff_tally/results_true.dat b/tests/regression_tests/diff_tally/results_true.dat index 29c906f2e8..165459e7d2 100644 --- a/tests/regression_tests/diff_tally/results_true.dat +++ b/tests/regression_tests/diff_tally/results_true.dat @@ -1,27 +1,27 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. -3,,density,flux,-4.5951022e+00,4.0201889e-01 -3,,density,flux,-9.9630192e+00,1.8897688e+00 -1,,density,flux,-4.2074596e-01,6.8569557e-02 -1,,density,flux,-2.8861314e-01,1.0032157e-01 -1,O16,nuclide_density,flux,-1.7146771e+01,1.8740496e+01 -1,O16,nuclide_density,flux,-1.4411733e+01,1.5986415e+01 -1,U235,nuclide_density,flux,-3.1082590e+03,3.5930199e+02 -1,U235,nuclide_density,flux,-2.5816702e+03,2.4275334e+02 -1,,temperature,flux,-2.2847162e-06,3.5489476e-04 -1,,temperature,flux,-8.5566667e-05,4.3023777e-04 -3,,density,total,-1.5582276e+00,2.8496759e-01 -3,,density,absorption,1.5711173e-01,1.7341244e-01 -3,,density,scatter,-1.7153393e+00,1.9431809e-01 -3,,density,fission,2.0152323e-01,7.4786095e-02 -3,,density,nu-fission,4.8687131e-01,1.8265878e-01 -3,,density,total,2.2943608e-01,8.6539576e-02 -3,,density,absorption,2.4646330e-01,8.6186628e-02 -3,,density,scatter,-1.7027217e-02,3.1732345e-03 -3,,density,fission,2.1668870e-01,7.5183313e-02 -3,,density,nu-fission,5.2774399e-01,1.8320780e-01 -3,,density,total,1.3300225e+01,4.2626034e+00 -3,,density,absorption,2.3903751e-01,8.9355264e-02 -3,,density,scatter,1.3061188e+01,4.1751261e+00 +3,,density,flux,-4.7291290e+00,8.8503902e-01 +3,,density,flux,-1.0533184e+01,3.0256001e+00 +1,,density,flux,-4.9634223e-01,1.3190338e-01 +1,,density,flux,-4.7458622e-01,5.6426916e-02 +1,O16,nuclide_density,flux,-1.4897399e+01,1.3583122e+01 +1,O16,nuclide_density,flux,-2.2389753e+01,1.5574833e+01 +1,U235,nuclide_density,flux,-2.8858701e+03,4.7033287e+02 +1,U235,nuclide_density,flux,-2.4203468e+03,3.2197255e+02 +1,,temperature,flux,1.6417230e-04,4.7576853e-04 +1,,temperature,flux,7.5575279e-05,8.0740029e-04 +3,,density,total,-1.5555916e+00,5.3353204e-01 +3,,density,absorption,1.4925823e-01,2.3501173e-01 +3,,density,scatter,-1.7048498e+00,3.3363896e-01 +3,,density,fission,1.3210039e-01,1.6377610e-01 +3,,density,nu-fission,3.1732288e-01,3.9893191e-01 +3,,density,total,1.4744448e-01,2.0435075e-01 +3,,density,absorption,1.6665433e-01,1.9696442e-01 +3,,density,scatter,-1.9209851e-02,7.8974770e-03 +3,,density,fission,1.4878594e-01,1.6616312e-01 +3,,density,nu-fission,3.6225815e-01,4.0486140e-01 +3,,density,total,1.2662462e+01,6.2596594e+00 +3,,density,absorption,2.2864288e-01,1.3031728e-01 +3,,density,scatter,1.2433820e+01,6.1294912e+00 3,,density,fission,0.0000000e+00,0.0000000e+00 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 3,,density,total,0.0000000e+00,0.0000000e+00 @@ -29,19 +29,19 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 3,,density,scatter,0.0000000e+00,0.0000000e+00 3,,density,fission,0.0000000e+00,0.0000000e+00 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,density,total,3.3373495e-01,4.6827421e-02 -1,,density,absorption,6.7487092e-04,6.5232977e-03 -1,,density,scatter,3.3306008e-01,4.0307583e-02 -1,,density,fission,-1.8402784e-03,4.2206212e-03 -1,,density,nu-fission,-3.8312038e-03,1.0337874e-02 -1,,density,total,-2.4831544e-04,5.5020059e-03 -1,,density,absorption,-4.0311629e-03,5.0266899e-03 -1,,density,scatter,3.7828475e-03,4.8043964e-04 -1,,density,fission,-3.6379968e-03,4.1821819e-03 -1,,density,nu-fission,-8.8266852e-03,1.0193373e-02 -1,,density,total,-3.6848185e-01,1.9314902e-01 -1,,density,absorption,-7.3640407e-03,4.0184508e-03 -1,,density,scatter,-3.6111780e-01,1.8936612e-01 +1,,density,total,2.9404312e-01,7.0116815e-02 +1,,density,absorption,-1.1851195e-03,1.6943078e-03 +1,,density,scatter,2.9522824e-01,6.8519873e-02 +1,,density,fission,-4.4865588e-03,2.3660449e-03 +1,,density,nu-fission,-1.0266898e-02,5.7956130e-03 +1,,density,total,-3.6990351e-03,3.5138725e-03 +1,,density,absorption,-7.0064347e-03,2.7205092e-03 +1,,density,scatter,3.3073996e-03,7.9802045e-04 +1,,density,fission,-6.3630708e-03,2.3832611e-03 +1,,density,nu-fission,-1.5466339e-02,5.8086647e-03 +1,,density,total,-5.5743331e-01,6.1625011e-02 +1,,density,absorption,-9.1430498e-03,4.0831822e-03 +1,,density,scatter,-5.4829026e-01,5.7756112e-02 1,,density,fission,0.0000000e+00,0.0000000e+00 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,,density,total,0.0000000e+00,0.0000000e+00 @@ -49,19 +49,19 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,density,scatter,0.0000000e+00,0.0000000e+00 1,,density,fission,0.0000000e+00,0.0000000e+00 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 -1,O16,nuclide_density,total,3.9050701e+01,8.5131265e+00 -1,O16,nuclide_density,absorption,-7.7573286e-01,7.1182570e-01 -1,O16,nuclide_density,scatter,3.9826434e+01,7.8536529e+00 -1,O16,nuclide_density,fission,-4.2193390e-01,6.0091792e-01 -1,O16,nuclide_density,nu-fission,-1.0411912e+00,1.4662352e+00 -1,O16,nuclide_density,total,-5.8976625e-01,7.9559349e-01 -1,O16,nuclide_density,absorption,-5.0047331e-01,7.1666177e-01 -1,O16,nuclide_density,scatter,-8.9292946e-02,8.9937898e-02 -1,O16,nuclide_density,fission,-3.6634959e-01,6.1270658e-01 -1,O16,nuclide_density,nu-fission,-8.9338374e-01,1.4932014e+00 -1,O16,nuclide_density,total,-3.3511352e+00,2.2365725e+01 -1,O16,nuclide_density,absorption,1.5473875e-01,4.3692662e-01 -1,O16,nuclide_density,scatter,-3.5058740e+00,2.1928948e+01 +1,O16,nuclide_density,total,3.9360816e+01,6.1390337e+00 +1,O16,nuclide_density,absorption,-6.8169613e-01,4.5302455e-01 +1,O16,nuclide_density,scatter,4.0042512e+01,6.4069240e+00 +1,O16,nuclide_density,fission,-6.1275244e-01,2.5764187e-01 +1,O16,nuclide_density,nu-fission,-1.5090099e+00,6.3048791e-01 +1,O16,nuclide_density,total,-7.5872288e-01,3.4843447e-01 +1,O16,nuclide_density,absorption,-6.7382098e-01,3.1002267e-01 +1,O16,nuclide_density,scatter,-8.4901894e-02,6.5286818e-02 +1,O16,nuclide_density,fission,-5.5597011e-01,2.7085418e-01 +1,O16,nuclide_density,nu-fission,-1.3555055e+00,6.6014209e-01 +1,O16,nuclide_density,total,-1.5539605e+01,2.3345398e+01 +1,O16,nuclide_density,absorption,-8.5880168e-02,5.0677339e-01 +1,O16,nuclide_density,scatter,-1.5453725e+01,2.2838892e+01 1,O16,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,total,0.0000000e+00,0.0000000e+00 @@ -69,19 +69,19 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,O16,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 -1,U235,nuclide_density,total,-9.1643805e+02,1.8814046e+02 -1,U235,nuclide_density,absorption,1.8114000e+02,4.6345847e+01 -1,U235,nuclide_density,scatter,-1.0975781e+03,1.4310981e+02 -1,U235,nuclide_density,fission,2.8765342e+02,2.2586319e+01 -1,U235,nuclide_density,nu-fission,7.0175585e+02,5.5024716e+01 -1,U235,nuclide_density,total,4.6786282e+02,2.8271731e+01 -1,U235,nuclide_density,absorption,3.6134508e+02,2.8453765e+01 -1,U235,nuclide_density,scatter,1.0651774e+02,1.3120589e+00 -1,U235,nuclide_density,fission,2.8859249e+02,2.2522591e+01 -1,U235,nuclide_density,nu-fission,7.0430623e+02,5.4858487e+01 -1,U235,nuclide_density,total,-5.0586963e+03,6.7151365e+02 -1,U235,nuclide_density,absorption,-1.2315731e+02,1.8905184e+01 -1,U235,nuclide_density,scatter,-4.9355390e+03,6.5260939e+02 +1,U235,nuclide_density,total,-7.9766848e+02,2.3476486e+02 +1,U235,nuclide_density,absorption,2.2136536e+02,5.7727802e+01 +1,U235,nuclide_density,scatter,-1.0190338e+03,1.7827380e+02 +1,U235,nuclide_density,fission,3.0782358e+02,2.4835876e+01 +1,U235,nuclide_density,nu-fission,7.5106928e+02,6.0668638e+01 +1,U235,nuclide_density,total,4.9643664e+02,3.6425359e+01 +1,U235,nuclide_density,absorption,3.8860811e+02,3.5290173e+01 +1,U235,nuclide_density,scatter,1.0782853e+02,1.9206965e+00 +1,U235,nuclide_density,fission,3.0827647e+02,2.4266512e+01 +1,U235,nuclide_density,nu-fission,7.5228268e+02,5.9109738e+01 +1,U235,nuclide_density,total,-4.7231732e+03,7.5353357e+02 +1,U235,nuclide_density,absorption,-1.1580370e+02,1.8531790e+01 +1,U235,nuclide_density,scatter,-4.6073695e+03,7.3502263e+02 1,U235,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,total,0.0000000e+00,0.0000000e+00 @@ -89,19 +89,19 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,U235,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,temperature,total,8.6368265e-05,1.7363899e-04 -1,,temperature,absorption,1.9220262e-05,3.4988977e-05 -1,,temperature,scatter,6.7148003e-05,1.4635162e-04 -1,,temperature,fission,-5.2927287e-06,1.2158338e-05 -1,,temperature,nu-fission,-1.2897086e-05,2.9622912e-05 -1,,temperature,total,-4.2009323e-06,1.8263855e-05 -1,,temperature,absorption,-4.3037914e-06,1.6219907e-05 -1,,temperature,scatter,1.0285902e-07,2.0676492e-06 -1,,temperature,fission,-5.2953783e-06,1.2158786e-05 -1,,temperature,nu-fission,-1.2903531e-05,2.9624000e-05 -1,,temperature,total,-1.1160261e-04,6.1705782e-04 -1,,temperature,absorption,-2.0394397e-06,8.4055062e-06 -1,,temperature,scatter,-1.0956317e-04,6.0869070e-04 +1,,temperature,total,3.1189559e-04,2.4271722e-04 +1,,temperature,absorption,1.6665424e-04,8.8838735e-05 +1,,temperature,scatter,1.4524136e-04,1.9136840e-04 +1,,temperature,fission,2.3953827e-05,2.1283894e-05 +1,,temperature,nu-fission,5.8367285e-05,5.1859176e-05 +1,,temperature,total,-7.8880798e-03,5.1962157e-03 +1,,temperature,absorption,3.1100192e-05,2.7372999e-05 +1,,temperature,scatter,1.2500314e-06,2.6699016e-06 +1,,temperature,fission,2.3952417e-05,2.1283903e-05 +1,,temperature,nu-fission,5.8363840e-05,5.1859165e-05 +1,,temperature,total,2.9848900e-04,1.1934160e-03 +1,,temperature,absorption,9.5075952e-06,1.8452256e-05 +1,,temperature,scatter,2.8898141e-04,1.1750098e-03 1,,temperature,fission,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 1,,temperature,total,0.0000000e+00,0.0000000e+00 @@ -109,68 +109,68 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,,temperature,scatter,0.0000000e+00,0.0000000e+00 1,,temperature,fission,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 -3,,density,absorption,1.3594219e-01,1.0122046e-01 -3,,density,absorption,2.8656499e-01,3.7923985e-02 -1,,density,absorption,-2.2106085e-03,9.8387075e-03 -1,,density,absorption,-3.3239716e-03,8.7768141e-03 -1,O16,nuclide_density,absorption,-1.2640173e+00,9.1596515e-01 -1,O16,nuclide_density,absorption,1.3146714e-01,9.9380272e-01 -1,U235,nuclide_density,absorption,1.5677452e+02,8.1085465e+01 -1,U235,nuclide_density,absorption,-1.4334804e+02,3.2100956e+01 -1,,temperature,absorption,-8.9633351e-06,3.5750907e-05 -1,,temperature,absorption,7.0140498e-07,1.1694324e-05 +3,,density,absorption,3.1512672e-02,2.4627803e-01 +3,,density,absorption,1.1452915e-01,1.5733776e-01 +1,,density,absorption,-1.4010827e-03,5.7414887e-03 +1,,density,absorption,-8.9116087e-03,7.6054344e-03 +1,O16,nuclide_density,absorption,-1.0238428e+00,3.5596763e-01 +1,O16,nuclide_density,absorption,-5.4386638e-01,6.3275232e-01 +1,U235,nuclide_density,absorption,1.9740455e+02,1.1770740e+02 +1,U235,nuclide_density,absorption,-1.3873202e+02,3.0030411e+01 +1,,temperature,absorption,1.6299319e-04,1.0720491e-04 +1,,temperature,absorption,-2.9480687e-05,1.9529799e-05 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 -3,,density,scatter,4.7213241e-01,1.6556808e-01 +3,,density,scatter,2.5895299e-01,3.3093831e-01 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 -3,,density,scatter,3.4067110e-02,2.1267271e-02 -3,,density,nu-fission,4.1265284e-01,1.3891654e-01 -3,,density,scatter,-2.1663022e+00,3.2444877e-01 -3,,density,nu-fission,4.4524898e-01,1.4098968e-01 -3,,density,scatter,-2.1357153e-02,1.7423446e-02 +3,,density,scatter,2.4380993e-02,2.4380993e-02 +3,,density,nu-fission,1.3982705e-01,4.0427820e-01 +3,,density,scatter,-1.8460573e+00,1.6126524e-01 +3,,density,nu-fission,1.7650022e-01,4.0560218e-01 +3,,density,scatter,3.9711501e-02,4.4405692e-02 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 -3,,density,scatter,8.6343785e+00,2.9292930e+00 +3,,density,scatter,7.8960553e+00,4.4763896e+00 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 3,,density,scatter,0.0000000e+00,0.0000000e+00 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 -3,,density,scatter,4.3792818e+00,1.9915652e+00 +3,,density,scatter,4.6518780e+00,1.6862698e+00 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 3,,density,scatter,0.0000000e+00,0.0000000e+00 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,density,scatter,-5.0479210e-03,9.5688761e-03 +1,,density,scatter,-1.4155379e-02,7.8989014e-03 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,density,scatter,4.4418327e-04,7.8121620e-04 -1,,density,nu-fission,-1.9240114e-02,1.4935352e-02 -1,,density,scatter,3.4099348e-01,2.8182893e-02 -1,,density,nu-fission,-2.4226858e-02,1.4481188e-02 -1,,density,scatter,1.1073847e-03,2.7478584e-04 +1,,density,scatter,1.0449664e-03,5.7043392e-04 +1,,density,nu-fission,-1.3723982e-02,1.5246898e-02 +1,,density,scatter,3.0959958e-01,5.7651589e-02 +1,,density,nu-fission,-1.9529210e-02,1.4804175e-02 +1,,density,scatter,5.1063052e-04,1.7748731e-03 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,density,scatter,-2.7695506e-01,1.3529978e-01 +1,,density,scatter,-3.4116700e-01,1.4433252e-01 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,,density,scatter,0.0000000e+00,0.0000000e+00 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,density,scatter,-8.8202815e-02,7.8863942e-02 +1,,density,scatter,-2.0735470e-01,8.6865144e-02 1,,density,nu-fission,0.0000000e+00,0.0000000e+00 1,,density,scatter,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 -1,O16,nuclide_density,scatter,1.1279170e-01,6.9836765e-02 -1,O16,nuclide_density,nu-fission,-1.6695105e+00,1.6777445e+00 -1,O16,nuclide_density,scatter,-1.0671543e-01,1.9127943e-01 +1,O16,nuclide_density,scatter,1.4017611e-01,9.5507870e-02 +1,O16,nuclide_density,nu-fission,-8.8199870e-01,1.6570982e+00 +1,O16,nuclide_density,scatter,-1.5442745e-01,1.3136597e-01 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,O16,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 -1,U235,nuclide_density,scatter,6.3235790e+00,3.9733167e+00 -1,U235,nuclide_density,nu-fission,6.2368225e+02,1.0172850e+02 -1,U235,nuclide_density,scatter,3.2601903e+01,6.2672072e+00 +1,U235,nuclide_density,scatter,8.1567193e+00,5.7077716e+00 +1,U235,nuclide_density,nu-fission,7.1482113e+02,1.4806072e+02 +1,U235,nuclide_density,scatter,5.2848809e+01,1.3486619e+01 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 -1,,temperature,scatter,-2.0884127e-06,1.6684645e-06 -1,,temperature,nu-fission,-1.5670247e-05,4.5939944e-05 -1,,temperature,scatter,3.9749436e-06,3.9749436e-06 +1,,temperature,scatter,-2.9687644e-07,2.8614575e-07 +1,,temperature,nu-fission,6.9612785e-05,8.2246105e-05 +1,,temperature,scatter,5.9452821e-09,8.7655524e-09 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 1,,temperature,scatter,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 diff --git a/tools/ci/travis-before-script.sh b/tools/ci/travis-before-script.sh index ca7cf75e2c..f66add5276 100755 --- a/tools/ci/travis-before-script.sh +++ b/tools/ci/travis-before-script.sh @@ -17,6 +17,13 @@ if [[ ! -d $ENDF/neutrons || ! -d $ENDF/photoat || ! -d $ENDF/atomic_relax ]]; t fi # Download multipole library -if [[ ! -d $HOME/WMP_Library ]]; then - git lfs clone https://github.com/mit-crpg/WMP_Library.git +if [[ ! -e $HOME/WMP_Library/092235.h5 ]]; then + if [[ $(command -v git-lfs) ]]; then + echo "Downloading WMP Library ..." + git clone https://github.com/mit-crpg/WMP_Library.git wmp_repo + mv wmp_repo/WMP_Library $HOME + else + echo "git lfs not found" + unset OPENMC_MULTIPOLE_LIBRARY + fi fi From 968cd22e29a535883280a90b0f5e445b727a7d73 Mon Sep 17 00:00:00 2001 From: liangjg Date: Sat, 18 Aug 2018 21:25:06 -0400 Subject: [PATCH 13/43] fixed np.dtype warnings --- openmc/data/multipole.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openmc/data/multipole.py b/openmc/data/multipole.py index 04e6dc20b6..a0d90ac019 100644 --- a/openmc/data/multipole.py +++ b/openmc/data/multipole.py @@ -260,7 +260,7 @@ class WindowedMultipole(EqualityMixin): 'data.shape[1] must be 3 or 4. One value for the pole.' ' One each for the scattering and absorption residues. ' 'Possibly one more for a fission residue.') - if not np.issubdtype(data.dtype, complex): + if not np.issubdtype(data.dtype, np.complexfloating): raise TypeError('Multipole data arrays must be complex dtype') self._data = data @@ -270,7 +270,7 @@ class WindowedMultipole(EqualityMixin): cv.check_type('windows', windows, np.ndarray) if len(windows.shape) != 2: raise ValueError('Multipole windows arrays must be 2D') - if not np.issubdtype(windows.dtype, int): + if not np.issubdtype(windows.dtype, np.integer): raise TypeError('Multipole windows arrays must be integer' ' dtype') self._windows = windows @@ -281,7 +281,7 @@ class WindowedMultipole(EqualityMixin): cv.check_type('broaden_poly', broaden_poly, np.ndarray) if len(broaden_poly.shape) != 1: raise ValueError('Multipole broaden_poly arrays must be 1D') - if not np.issubdtype(broaden_poly.dtype, bool): + if not np.issubdtype(broaden_poly.dtype, np.bool_): raise TypeError('Multipole broaden_poly arrays must be boolean' ' dtype') self._broaden_poly = broaden_poly @@ -295,7 +295,7 @@ class WindowedMultipole(EqualityMixin): if curvefit.shape[2] not in (2, 3): # sig_s, sig_a (maybe sig_f) raise ValueError('The third dimension of multipole curvefit' ' arrays must have a length of 2 or 3') - if not np.issubdtype(curvefit.dtype, float): + if not np.issubdtype(curvefit.dtype, np.floating): raise TypeError('Multipole curvefit arrays must be float dtype') self._curvefit = curvefit From 43c554583a7606c50d6f5623fca41c649daa9b4a Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 19 Aug 2018 14:57:28 -0400 Subject: [PATCH 14/43] Move cell temperatures to C++ --- openmc/capi/cell.py | 2 +- src/api.F90 | 1 - src/cell.cpp | 63 ++++++++++++++++++ src/cell.h | 8 ++- src/geometry.F90 | 8 +-- src/geometry_aux.cpp | 31 +++++++++ src/geometry_aux.h | 6 ++ src/geometry_header.F90 | 140 ++++++++++------------------------------ src/input_xml.F90 | 87 +++---------------------- src/material.cpp | 4 ++ src/material.h | 5 ++ src/mgxs_data.F90 | 6 +- src/settings.F90 | 2 +- src/settings.h | 1 + src/summary.F90 | 7 +- 15 files changed, 171 insertions(+), 200 deletions(-) diff --git a/openmc/capi/cell.py b/openmc/capi/cell.py index 4b994ac168..1a4c8996f0 100644 --- a/openmc/capi/cell.py +++ b/openmc/capi/cell.py @@ -141,7 +141,7 @@ class Cell(_FortranObjectWithID): Which instance of the cell """ - _dll.openmc_cell_set_temperature(self._index, T, instance) + _dll.openmc_cell_set_temperature(self._index, T, c_int32(instance)) class _CellMapping(Mapping): diff --git a/src/api.F90 b/src/api.F90 index fd97338967..c8bea6583f 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -38,7 +38,6 @@ module openmc_api public :: openmc_cell_filter_get_bins public :: openmc_cell_get_id public :: openmc_cell_set_id - public :: openmc_cell_set_temperature public :: openmc_energy_filter_get_bins public :: openmc_energy_filter_set_bins public :: openmc_extend_filters diff --git a/src/cell.cpp b/src/cell.cpp index 457d4050ba..da5998b90f 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -259,6 +259,36 @@ Cell::Cell(pugi::xml_node cell_node) } } + // Read the temperature element which may be distributed like materials. + if (check_for_node(cell_node, "temperature")) { + sqrtkT = get_node_array(cell_node, "temperature"); + sqrtkT.shrink_to_fit(); + + // Make sure this is a material-filled cell. + if (material.size() == 0) { + std::stringstream err_msg; + err_msg << "Cell " << id << " was specified with a temperature but " + "no material. Temperature specification is only valid for cells " + "filled with a material."; + fatal_error(err_msg); + } + + // Make sure all temperatures are non-negative. + for (auto T : sqrtkT) { + if (T < 0) { + std::stringstream err_msg; + err_msg << "Cell " << id + << " was specified with a negative temperature"; + fatal_error(err_msg); + } + } + + // Convert to sqrt(k*T). + for (auto& T : sqrtkT) { + T = std::sqrt(K_BOLTZMANN * T); + } + } + // Read the region specification. std::string region_spec; if (check_for_node(cell_node, "region")) { @@ -539,6 +569,35 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n, return 0; } +//TODO: make sure data is loaded for this temperature +extern "C" int +openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) +{ + if (index >= 1 && index <= global_cells.size()) { + //TODO: off-by-one + Cell& c {*global_cells[index - 1]}; + + if (instance) { + if (*instance >= 0 && *instance < c.sqrtkT.size()) { + c.sqrtkT[*instance] = std::sqrt(K_BOLTZMANN * T); + } else { + strcpy(openmc_err_msg, "Distribcell instance is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } + } else { + for (auto& T_ : c.sqrtkT) { + T_ = std::sqrt(K_BOLTZMANN * T); + } + } + + } else { + strcpy(openmc_err_msg, "Index in cells array is out of bounds."); + return OPENMC_E_OUT_OF_BOUNDS; + } + + return 0; +} + //============================================================================== // Fortran compatibility functions //============================================================================== @@ -568,6 +627,10 @@ extern "C" { return mat + 1; } + int cell_sqrtkT_size(Cell* c) {return c->sqrtkT.size();} + + double cell_sqrtkT(Cell* c, int i) {return c->sqrtkT[i];} + bool cell_simple(Cell* c) {return c->simple;} bool cell_contains(Cell* c, double xyz[3], double uvw[3], int32_t on_surface) diff --git a/src/cell.h b/src/cell.h index 0b42a656c3..42b34ae401 100644 --- a/src/cell.h +++ b/src/cell.h @@ -66,9 +66,15 @@ public: //! \brief Material(s) within this cell. //! - //! May be multiple materials for distribcell. C_NONE signifies a universe. + //! May be multiple materials for distribcell. std::vector material; + //! \brief Temperature(s) within this cell. + //! + //! The stored values are actually sqrt(k_Boltzmann * T) for each temperature + //! T. The units are sqrt(eV). + std::vector sqrtkT; + //! Definition of spatial region as Boolean expression of half-spaces std::vector region; //! Reverse Polish notation for region expression diff --git a/src/geometry.F90 b/src/geometry.F90 index e1e8dc7a18..60c4948bb7 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -94,7 +94,7 @@ contains p % last_sqrtkT = p % sqrtkT ! Get distributed offset - if (c % material_size() > 1 .or. size(c % sqrtkT) > 1) then + if (c % material_size() > 1 .or. c % sqrtkT_size() > 1) then ! Distributed instances of this cell have different ! materials/temperatures. Determine which instance this is for ! assigning the matching material/temperature. @@ -133,10 +133,10 @@ contains end if ! Save the temperature - if (size(c % sqrtkT) > 1) then - p % sqrtkT = c % sqrtkT(offset + 1) + if (c % sqrtkT_size() > 1) then + p % sqrtkT = c % sqrtkT(offset) else - p % sqrtkT = c % sqrtkT(1) + p % sqrtkT = c % sqrtkT(0) end if elseif (c % type() == FILL_UNIVERSE) then CELL_TYPE diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 2b795d607f..93c08fbe13 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -10,6 +10,7 @@ #include "geometry.h" #include "lattice.h" #include "material.h" +#include "settings.h" namespace openmc { @@ -78,6 +79,36 @@ adjust_indices() //============================================================================== +void +assign_temperatures() +{ + for (Cell* c : global_cells) { + // Ignore non-material cells and cells with defined temperature. + if (c->material.size() == 0) continue; + if (c->sqrtkT.size() > 0) continue; + + c->sqrtkT.reserve(c->material.size()); + for (auto i_mat : c->material) { + if (i_mat == MATERIAL_VOID) { + // Set void region to 0K. + c->sqrtkT.push_back(0); + + } else { + if (global_materials[i_mat]->temperature >= 0) { + // This material has a default temperature; use that value. + auto T = global_materials[i_mat]->temperature; + c->sqrtkT.push_back(std::sqrt(K_BOLTZMANN * T)); + } else { + // Use the global default temperature. + c->sqrtkT.push_back(std::sqrt(K_BOLTZMANN * temperature_default)); + } + } + } + } +} + +//============================================================================== + int32_t find_root_universe() { diff --git a/src/geometry_aux.h b/src/geometry_aux.h index fb5940d1c9..fdc6a16b71 100644 --- a/src/geometry_aux.h +++ b/src/geometry_aux.h @@ -15,6 +15,12 @@ namespace openmc { extern "C" void adjust_indices(); +//============================================================================== +//! Assign defaults to cells with undefined temperatures. +//============================================================================== + +extern "C" void assign_temperatures(); + //============================================================================== //! Figure out which Universe is the root universe. //! diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 7714601a42..f7f533bd79 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -75,6 +75,21 @@ module geometry_header integer(C_INT32_T) :: mat end function cell_material_c + function cell_sqrtkT_size_c(cell_ptr) bind(C, name='cell_sqrtkT_size') & + result(n) + import C_PTR, C_INT + type(C_PTR), intent(in), value :: cell_ptr + integer(C_INT) :: n + end function cell_sqrtkT_size_c + + function cell_sqrtkT_c(cell_ptr, i) bind(C, name='cell_sqrtkT') & + result(sqrtkT) + import C_PTR, C_INT, C_DOUBLE + type(C_PTR), intent(in), value :: cell_ptr + integer(C_INT), intent(in), value :: i + real(C_DOUBLE) :: sqrtkT + end function cell_sqrtkT_c + function cell_simple_c(cell_ptr) bind(C, name='cell_simple') result(simple) import C_PTR, C_BOOL type(C_PTR), intent(in), value :: cell_ptr @@ -253,9 +268,6 @@ module geometry_header ! Boolean expression of half-spaces integer :: distribcell_index ! Index corresponding to this cell in ! distribcell arrays - real(8), allocatable :: sqrtkT(:) ! Square root of k_Boltzmann * - ! temperature in eV. Multiple for - ! distribcell ! Rotation matrix and translation vector real(8), allocatable :: translation(:) @@ -272,6 +284,8 @@ module geometry_header procedure :: n_instances => cell_n_instances procedure :: material_size => cell_material_size procedure :: material => cell_material + procedure :: sqrtkT_size => cell_sqrtkT_size + procedure :: sqrtkT => cell_sqrtkT procedure :: simple => cell_simple procedure :: distance => cell_distance procedure :: offset => cell_offset @@ -413,6 +427,19 @@ contains mat = cell_material_c(this % ptr, i) end function cell_material + function cell_sqrtkT_size(this) result(n) + class(Cell), intent(in) :: this + integer :: n + n = cell_sqrtkT_size_c(this % ptr) + end function cell_sqrtkT_size + + function cell_sqrtkT(this, i) result(sqrtkT) + class(Cell), intent(in) :: this + integer, intent(in) :: i + real(C_DOUBLE) :: sqrtkT + sqrtkT = cell_sqrtkT_c(this % ptr, i) + end function cell_sqrtkT + function cell_simple(this) result(simple) class(Cell), intent(in) :: this logical(C_BOOL) :: simple @@ -470,10 +497,10 @@ contains if (cells(i) % material(j) == MATERIAL_VOID) cycle ! Get temperature of cell (rounding to nearest integer) - if (size(cells(i) % sqrtkT) > 1) then - temperature = cells(i) % sqrtkT(j)**2 / K_BOLTZMANN + if (cells(i) % sqrtkT_size() > 1) then + temperature = cells(i) % sqrtkT(j-1)**2 / K_BOLTZMANN else - temperature = cells(i) % sqrtkT(1)**2 / K_BOLTZMANN + temperature = cells(i) % sqrtkT(0)**2 / K_BOLTZMANN end if i_material = cells(i) % material(j) @@ -626,105 +653,4 @@ contains end if end function openmc_cell_set_id - - function openmc_cell_set_temperature(index, T, instance) result(err) bind(C) - ! Set the temperature of a cell - integer(C_INT32_T), value, intent(in) :: index ! index in cells - real(C_DOUBLE), value, intent(in) :: T ! temperature - integer(C_INT32_T), optional, intent(in) :: instance ! cell instance - - integer(C_INT) :: err ! error code - integer :: j ! looping variable - integer :: n ! number of cell instances - integer :: material_index ! material index in materials array - integer :: num_nuclides ! num nuclides in material - integer :: nuclide_index ! index of nuclide in nuclides array - real(8) :: min_temp ! min common-denominator avail temp - real(8) :: max_temp ! max common-denominator avail temp - real(8) :: temp ! actual temp we'll assign - logical :: outside_low ! lower than available data - logical :: outside_high ! higher than available data - - outside_low = .false. - outside_high = .false. - - err = E_UNASSIGNED - - if (index >= 1 .and. index <= size(cells)) then - - ! error if the cell is filled with another universe - if (cells(index) % fill() /= C_NONE) then - err = E_GEOMETRY - call set_errmsg("Cannot set temperature on a cell filled & - &with a universe.") - else - ! find which material is associated with this cell (material_index - ! is the index into the materials array) - if (present(instance)) then - material_index = cells(index) % material(instance + 1) - else - material_index = cells(index) % material(1) - end if - - ! number of nuclides associated with this material - num_nuclides = size(materials(material_index) % nuclide) - - min_temp = ZERO - max_temp = INFINITY - - do j = 1, num_nuclides - nuclide_index = materials(material_index) % nuclide(j) - min_temp = max(min_temp, minval(nuclides(nuclide_index) % kTs)) - max_temp = min(max_temp, maxval(nuclides(nuclide_index) % kTs)) - end do - - ! adjust the temperature to be within bounds if necessary - if (K_BOLTZMANN * T < min_temp) then - outside_low = .true. - temp = min_temp / K_BOLTZMANN - else if (K_BOLTZMANN * T > max_temp) then - outside_high = .true. - temp = max_temp / K_BOLTZMANN - else - temp = T - end if - - associate (c => cells(index)) - if (allocated(c % sqrtkT)) then - n = size(c % sqrtkT) - if (present(instance) .and. n > 1) then - if (instance >= 0 .and. instance < n) then - c % sqrtkT(instance + 1) = sqrt(K_BOLTZMANN * temp) - err = 0 - end if - else - c % sqrtkT(:) = sqrt(K_BOLTZMANN * temp) - err = 0 - end if - end if - end associate - - ! Assign error codes for outside of temperature bounds provided the - ! temperature was changed correctly. This needs to be done after - ! changing the temperature based on the logical structure above. - if (err == 0) then - if (outside_low) then - err = E_WARNING - call set_errmsg("Nuclear data has not been loaded beyond lower & - &bound of T=" // trim(to_str(T)) // " K.") - else if (outside_high) then - err = E_WARNING - call set_errmsg("Nuclear data has not been loaded beyond upper & - &bound of T=" // trim(to_str(T)) // " K.") - end if - end if - - end if - - else - err = E_OUT_OF_BOUNDS - call set_errmsg("Index in cells array is out of bounds.") - end if - end function openmc_cell_set_temperature - end module geometry_header diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 3a1c2fac27..6c26da0b04 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -56,6 +56,9 @@ module input_xml 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 @@ -178,7 +181,7 @@ contains call neighbor_lists() ! Assign temperatures to cells that don't have temperatures already assigned - call assign_temperatures(material_temps) + call assign_temperatures() ! Determine desired txemperatures for each nuclide and S(a,b) table call get_temperatures(nuc_temps, sab_temps) @@ -1203,40 +1206,6 @@ contains call get_node_array(node_cell, "translation", c % translation) end if - ! Read cell temperatures. If the temperature is not specified, set it to - ! a negative number for now. During initialization we'll replace - ! negatives with the temperature from the material data. - if (check_for_node(node_cell, "temperature")) then - n = node_word_count(node_cell, "temperature") - if (n > 0) then - ! Make sure this is a "normal" cell. - if (c % fill() /= C_NONE) call fatal_error("Cell " & - // trim(to_str(c % id())) // " was specified with a temperature & - &but no material. Temperature specification is only valid for & - &cells filled with a material.") - - ! Copy in temperatures - allocate(c % sqrtkT(n)) - call get_node_array(node_cell, "temperature", c % sqrtkT) - - ! Make sure all temperatues are positive - do j = 1, size(c % sqrtkT) - if (c % sqrtkT(j) < ZERO) call fatal_error("Cell " & - // trim(to_str(c % id())) // " was specified with a negative & - &temperature. All cell temperatures must be non-negative.") - end do - - ! Convert to sqrt(kT) - c % sqrtkT(:) = sqrt(K_BOLTZMANN * c % sqrtkT(:)) - else - allocate(c % sqrtkT(1)) - c % sqrtkT(1) = -1.0 - end if - else - allocate(c % sqrtkT(1)) - c % sqrtkT = -1.0 - end if - ! Add cell to dictionary call cell_dict % set(c % id(), i) @@ -3796,46 +3765,6 @@ contains end subroutine read_ce_cross_sections -!=============================================================================== -! ASSIGN_TEMPERATURES If any cells have undefined temperatures, try to find -! their temperatures from material or global default temperatures -!=============================================================================== - - subroutine assign_temperatures(material_temps) - real(8), intent(in) :: material_temps(:) - - integer :: i, j - integer :: i_material - - do i = 1, n_cells - ! Ignore non-normal cells and cells with defined temperature. - if (cells(i) % fill() /= C_NONE) cycle - if (cells(i) % sqrtkT(1) >= ZERO) cycle - - ! Set the number of temperatures equal to the number of materials. - deallocate(cells(i) % sqrtkT) - allocate(cells(i) % sqrtkT(cells(i) % material_size())) - - ! Check each of the cell materials for temperature data. - do j = 1, cells(i) % material_size() - ! Arbitrarily set void regions to 0K. - if (cells(i) % material(j) == MATERIAL_VOID) then - cells(i) % sqrtkT(j) = ZERO - cycle - end if - - ! Use material default or global default temperature - i_material = cells(i) % material(j) - if (material_temps(i_material) >= ZERO) then - cells(i) % sqrtkT(j) = sqrt(K_BOLTZMANN * & - material_temps(i_material)) - else - cells(i) % sqrtkT(j) = sqrt(K_BOLTZMANN * temperature_default) - end if - end do - end do - end subroutine assign_temperatures - !=============================================================================== ! READ_MULTIPOLE_DATA checks for the existence of a multipole library in the ! directory and loads it using multipole_read @@ -3908,7 +3837,7 @@ contains ! Find all cells with multiple (distributed) materials or temperatures. do i = 1, n_cells - if (cells(i) % material_size() > 1 .or. size(cells(i) % sqrtkT) > 1) then + if (cells(i) % material_size() > 1 .or. cells(i) % sqrtkT_size() > 1) then call cell_list % add(i) end if end do @@ -3926,10 +3855,10 @@ contains &equal one or the number of instances.") end if end if - if (size(c % sqrtkT) > 1) then - if (size(c % sqrtkT) /= c % n_instances()) then + 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(size(c % sqrtkT))) & + &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.") diff --git a/src/material.cpp b/src/material.cpp index c9ef47f074..f98a2c40a3 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -27,6 +27,10 @@ Material::Material(pugi::xml_node material_node) } else { fatal_error("Must specify id of material in materials XML file."); } + + if (check_for_node(material_node, "temperature")) { + temperature = std::stod(get_node_value(material_node, "temperature")); + } } //============================================================================== diff --git a/src/material.h b/src/material.h index 0a9a099a44..3ccaf1e0b3 100644 --- a/src/material.h +++ b/src/material.h @@ -26,6 +26,11 @@ class Material public: int32_t id; //!< Unique ID + //! \brief Default temperature for cells containing this material. + //! + //! A negative value indicates no default temperature was specified. + double temperature {-1}; + Material() {}; explicit Material(pugi::xml_node material_node); diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index b95c3a877a..03a0e9402f 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -160,10 +160,10 @@ contains if (cells(i) % material(j) == MATERIAL_VOID) cycle ! Get temperature of cell (rounding to nearest integer) - if (size(cells(i) % sqrtkT) > 1) then - kT = cells(i) % sqrtkT(j)**2 + if (cells(i) % sqrtkT_size() > 1) then + kT = cells(i) % sqrtkT(j-1)**2 else - kT = cells(i) % sqrtkT(1)**2 + kT = cells(i) % sqrtkT(0)**2 end if i_material = cells(i) % material(j) diff --git a/src/settings.F90 b/src/settings.F90 index 972eba1d58..cb0a556220 100644 --- a/src/settings.F90 +++ b/src/settings.F90 @@ -21,7 +21,7 @@ module settings integer(C_INT) :: temperature_method = TEMPERATURE_NEAREST logical :: temperature_multipole = .false. real(C_DOUBLE) :: temperature_tolerance = 10.0_8 - real(8) :: temperature_default = 293.6_8 + real(C_DOUBLE), bind(C) :: temperature_default = 293.6_8 real(8) :: temperature_range(2) = [ZERO, ZERO] integer :: n_log_bins ! number of bins for logarithmic grid diff --git a/src/settings.h b/src/settings.h index ff6b1cf3b7..5c7bf2c840 100644 --- a/src/settings.h +++ b/src/settings.h @@ -21,6 +21,7 @@ extern "C" bool openmc_restart_run; extern "C" bool openmc_trace; extern "C" int openmc_verbosity; extern "C" bool openmc_write_all_tracks; +extern "C" double temperature_default; #pragma omp threadprivate(openmc_trace) // Defined in .cpp diff --git a/src/summary.F90 b/src/summary.F90 index 13bc426637..6c311e9821 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -218,9 +218,10 @@ contains deallocate(cell_materials) end if - allocate(cell_temperatures(size(c % sqrtkT))) - cell_temperatures(:) = c % sqrtkT(:) - cell_temperatures(:) = cell_temperatures(:)**2 / K_BOLTZMANN + allocate(cell_temperatures(c % sqrtkT_size())) + do j = 1, c % sqrtkT_size() + cell_temperatures(j) = c % sqrtkT(j-1)**2 / K_BOLTZMANN + end do call write_dataset(cell_group, "temperature", cell_temperatures) deallocate(cell_temperatures) From ef8bf2b8204df6f2cf76861ce9d924f64346b2fa Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 19 Aug 2018 18:39:28 -0400 Subject: [PATCH 15/43] Move Cell.distribcell_index to C++ --- src/cell.cpp | 3 +- src/cell.h | 4 + src/geometry.F90 | 2 +- src/geometry_aux.cpp | 100 +++++++++++++++++------ src/geometry_aux.h | 13 +-- src/geometry_header.F90 | 16 +++- src/input_xml.F90 | 81 ++++-------------- src/tallies/tally_filter_distribcell.F90 | 4 +- 8 files changed, 114 insertions(+), 109 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index da5998b90f..a68ab9d0b4 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -4,7 +4,6 @@ #include #include -#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 diff --git a/src/cell.h b/src/cell.h index 42b34ae401..8b7c3a78b1 100644 --- a/src/cell.h +++ b/src/cell.h @@ -7,6 +7,7 @@ #include #include +#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. diff --git a/src/geometry.F90 b/src/geometry.F90 index 60c4948bb7..f717810bb1 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -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 diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 93c08fbe13..6d7d5badb5 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -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 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 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) diff --git a/src/geometry_aux.h b/src/geometry_aux.h index fdc6a16b71..e3fd034c69 100644 --- a/src/geometry_aux.h +++ b/src/geometry_aux.h @@ -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. diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index f7f533bd79..272966b338 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -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 diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 6c26da0b04..7d8a8393df 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -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 diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index c9564083da..9ef282126e 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -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) From c7115e5b106b5eaf6b8032e3fafb3aa1f3f20520 Mon Sep 17 00:00:00 2001 From: liangjg Date: Sat, 18 Aug 2018 21:44:54 -0400 Subject: [PATCH 16/43] fix bugs in test --- src/tallies/tally.F90 | 6 +-- .../diff_tally/results_true.dat | 38 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 2365ec46f2..78a714032d 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -3251,6 +3251,7 @@ contains end do dsig_s = ZERO + dsig_a = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & p % last_E >= nuc % multipole % E_min .and. & @@ -3278,7 +3279,6 @@ contains end do dsig_s = ZERO - dsig_a = ZERO associate (nuc => nuclides(p % event_nuclide)) if (nuc % mp_present .and. & p % last_E >= nuc % multipole % E_min .and. & @@ -3408,6 +3408,7 @@ contains else if (materials(p % material) % id == deriv % diff_material & .and. material_xs % total > ZERO) then dsig_s = ZERO + dsig_a = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & p % last_E >= nuc % multipole % E_min .and. & @@ -3448,7 +3449,6 @@ contains .and. (material_xs % total - material_xs % absorption) > ZERO)& then dsig_s = ZERO - dsig_a = ZERO associate (nuc => nuclides(i_nuclide)) if (nuc % mp_present .and. & p % last_E >= nuc % multipole % E_min .and. & @@ -3734,7 +3734,7 @@ contains ! (1 / phi) * (d_phi / d_T) = (d_sigma_s / d_T) / sigma_s call multipole_deriv_eval(nuc % multipole, p % last_E, & p % sqrtkT, dsig_s, dsig_a, dsig_f) - deriv % flux_deriv = deriv % flux_deriv + (dsig_s + dsig_a)& + deriv % flux_deriv = deriv % flux_deriv + dsig_s& / (micro_xs(mat % nuclide(l)) % total & - micro_xs(mat % nuclide(l)) % absorption) ! Note that this is an approximation! The real scattering diff --git a/tests/regression_tests/diff_tally/results_true.dat b/tests/regression_tests/diff_tally/results_true.dat index 165459e7d2..e3cff4ca0d 100644 --- a/tests/regression_tests/diff_tally/results_true.dat +++ b/tests/regression_tests/diff_tally/results_true.dat @@ -7,8 +7,8 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,O16,nuclide_density,flux,-2.2389753e+01,1.5574833e+01 1,U235,nuclide_density,flux,-2.8858701e+03,4.7033287e+02 1,U235,nuclide_density,flux,-2.4203468e+03,3.2197255e+02 -1,,temperature,flux,1.6417230e-04,4.7576853e-04 -1,,temperature,flux,7.5575279e-05,8.0740029e-04 +1,,temperature,flux,-1.1195282e-04,3.5426553e-04 +1,,temperature,flux,-4.4294257e-04,5.4687257e-04 3,,density,total,-1.5555916e+00,5.3353204e-01 3,,density,absorption,1.4925823e-01,2.3501173e-01 3,,density,scatter,-1.7048498e+00,3.3363896e-01 @@ -89,19 +89,19 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,U235,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 -1,,temperature,total,3.1189559e-04,2.4271722e-04 -1,,temperature,absorption,1.6665424e-04,8.8838735e-05 -1,,temperature,scatter,1.4524136e-04,1.9136840e-04 -1,,temperature,fission,2.3953827e-05,2.1283894e-05 -1,,temperature,nu-fission,5.8367285e-05,5.1859176e-05 -1,,temperature,total,-7.8880798e-03,5.1962157e-03 -1,,temperature,absorption,3.1100192e-05,2.7372999e-05 -1,,temperature,scatter,1.2500314e-06,2.6699016e-06 -1,,temperature,fission,2.3952417e-05,2.1283903e-05 -1,,temperature,nu-fission,5.8363840e-05,5.1859165e-05 -1,,temperature,total,2.9848900e-04,1.1934160e-03 -1,,temperature,absorption,9.5075952e-06,1.8452256e-05 -1,,temperature,scatter,2.8898141e-04,1.1750098e-03 +1,,temperature,total,5.7228698e-05,1.7465295e-04 +1,,temperature,absorption,2.9495471e-05,3.1637786e-05 +1,,temperature,scatter,2.7733227e-05,1.4323068e-04 +1,,temperature,fission,-5.6710689e-06,1.2800905e-05 +1,,temperature,nu-fission,-1.3819116e-05,3.1189136e-05 +1,,temperature,total,-5.8315815e-06,1.8705738e-05 +1,,temperature,absorption,-5.3204426e-06,1.6688104e-05 +1,,temperature,scatter,-5.1113883e-07,2.0213875e-06 +1,,temperature,fission,-5.6723577e-06,1.2800214e-05 +1,,temperature,nu-fission,-1.3822264e-05,3.1187458e-05 +1,,temperature,total,-5.5283703e-04,7.6408422e-04 +1,,temperature,absorption,-6.2179157e-06,1.0365194e-05 +1,,temperature,scatter,-5.4661911e-04,7.5373133e-04 1,,temperature,fission,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 1,,temperature,total,0.0000000e+00,0.0000000e+00 @@ -117,8 +117,8 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,O16,nuclide_density,absorption,-5.4386638e-01,6.3275232e-01 1,U235,nuclide_density,absorption,1.9740455e+02,1.1770740e+02 1,U235,nuclide_density,absorption,-1.3873202e+02,3.0030411e+01 -1,,temperature,absorption,1.6299319e-04,1.0720491e-04 -1,,temperature,absorption,-2.9480687e-05,1.9529799e-05 +1,,temperature,absorption,5.0340072e-06,2.9911538e-05 +1,,temperature,absorption,-3.7625680e-05,2.4883845e-05 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 3,,density,scatter,2.5895299e-01,3.3093831e-01 3,,density,nu-fission,0.0000000e+00,0.0000000e+00 @@ -168,8 +168,8 @@ d_material,d_nuclide,d_variable,score,mean,std. dev. 1,U235,nuclide_density,nu-fission,0.0000000e+00,0.0000000e+00 1,U235,nuclide_density,scatter,0.0000000e+00,0.0000000e+00 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 -1,,temperature,scatter,-2.9687644e-07,2.8614575e-07 -1,,temperature,nu-fission,6.9612785e-05,8.2246105e-05 +1,,temperature,scatter,-2.9956385e-07,2.8883252e-07 +1,,temperature,nu-fission,-2.1023382e-05,4.9883940e-05 1,,temperature,scatter,5.9452821e-09,8.7655524e-09 1,,temperature,nu-fission,0.0000000e+00,0.0000000e+00 1,,temperature,scatter,0.0000000e+00,0.0000000e+00 From 22c393610fbea85ab33e0f3b9022a636b6840561 Mon Sep 17 00:00:00 2001 From: liangjg Date: Mon, 20 Aug 2018 11:18:33 -0400 Subject: [PATCH 17/43] download wmp library from a release link instead of using git-lfs --- scripts/openmc-get-multipole-data | 13 ++++--------- tools/ci/travis-before-script.sh | 10 ++-------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/scripts/openmc-get-multipole-data b/scripts/openmc-get-multipole-data index ea25396488..c8a2d1e9b9 100755 --- a/scripts/openmc-get-multipole-data +++ b/scripts/openmc-get-multipole-data @@ -29,9 +29,9 @@ parser.add_argument('-b', '--batch', action='store_true', args = parser.parse_args() -baseUrl = 'https://github.com/smharper/windowed_multipole_library/blob/master/' -files = ['multipole_lib.tar.gz?raw=true'] -checksums = ['3985aea96f7162a9419c7ed8352e6abb'] +baseUrl = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.0/' +files = ['WMP_Library_v1.0.tar.gz'] +checksums = ['22cb675734cfccb278dffd40dcfbf26a'] block_size = 16384 # ============================================================================== @@ -101,12 +101,7 @@ for f in files: # Extract files with tarfile.open(fname, 'r') as tgz: print('Extracting {0}...'.format(fname)) - tgz.extractall(path='wmp/') - -# Move data files down one level -for filename in glob.glob('wmp/multipole_lib/*'): - shutil.move(filename, 'wmp/') -os.rmdir('wmp/multipole_lib') + tgz.extractall(path='') # ============================================================================== # PROMPT USER TO DELETE .TAR.GZ FILES diff --git a/tools/ci/travis-before-script.sh b/tools/ci/travis-before-script.sh index f66add5276..6d44521a6e 100755 --- a/tools/ci/travis-before-script.sh +++ b/tools/ci/travis-before-script.sh @@ -18,12 +18,6 @@ fi # Download multipole library if [[ ! -e $HOME/WMP_Library/092235.h5 ]]; then - if [[ $(command -v git-lfs) ]]; then - echo "Downloading WMP Library ..." - git clone https://github.com/mit-crpg/WMP_Library.git wmp_repo - mv wmp_repo/WMP_Library $HOME - else - echo "git lfs not found" - unset OPENMC_MULTIPOLE_LIBRARY - fi + wget https://github.com/mit-crpg/WMP_Library/releases/download/v1.0/WMP_Library_v1.0.tar.gz + tar -C $HOME -xzvf WMP_Library_v1.0.tar.gz fi From cb5db790d776fe6fb96c29c0d73b32aabe5c76ad Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 20 Aug 2018 12:24:08 -0400 Subject: [PATCH 18/43] Move FILL_MATERIAL chunk of find_cell to C++ --- src/geometry.F90 | 60 ++--------------------------------------------- src/geometry.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++--- src/geometry.h | 17 +++++++++++++- 3 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index f717810bb1..29e03bbb5f 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -69,9 +69,7 @@ contains type(Particle), intent(inout) :: p logical, intent(inout) :: found integer, optional :: search_cells(:) - integer :: j, k ! coordinate level index - integer :: offset ! instance # of a distributed cell - integer :: distribcell_index + integer :: j ! coordinate level index integer :: i_xyz(3) ! indices in lattice integer :: i_cell ! index in cells array @@ -85,61 +83,7 @@ contains if (found) then associate(c => cells(i_cell)) - CELL_TYPE: if (c % type() == FILL_MATERIAL) then - ! ====================================================================== - ! AT LOWEST UNIVERSE, TERMINATE SEARCH - - ! Save previous material and temperature - p % last_material = p % material - p % last_sqrtkT = p % sqrtkT - - ! Get distributed offset - if (c % material_size() > 1 .or. c % sqrtkT_size() > 1) then - ! 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() - offset = 0 - do k = 1, p % n_coord - if (cells(p % coord(k) % cell) % type() == FILL_UNIVERSE) then - offset = offset + cells(p % coord(k) % cell) & - % offset(distribcell_index-1) - elseif (cells(p % coord(k) % cell) % type() == FILL_LATTICE) then - if (lattices(p % coord(k + 1) % lattice) % obj & - % are_valid_indices([& - p % coord(k + 1) % lattice_x, & - p % coord(k + 1) % lattice_y, & - p % coord(k + 1) % lattice_z])) then - offset = offset + lattices(p % coord(k + 1) % lattice) % obj & - % offset(distribcell_index - 1, & - [p % coord(k + 1) % lattice_x, & - p % coord(k + 1) % lattice_y, & - p % coord(k + 1) % lattice_z]) - end if - end if - end do - - ! Keep track of which instance of the cell the particle is in - p % cell_instance = offset + 1 - else - p % cell_instance = 1 - end if - - ! Save the material - if (c % material_size() > 1) then - p % material = c % material(offset + 1) - else - p % material = c % material(1) - end if - - ! Save the temperature - if (c % sqrtkT_size() > 1) then - p % sqrtkT = c % sqrtkT(offset) - else - p % sqrtkT = c % sqrtkT(0) - end if - - elseif (c % type() == FILL_UNIVERSE) then CELL_TYPE + CELL_TYPE: if (c % type() == FILL_UNIVERSE) then ! ====================================================================== ! CELL CONTAINS LOWER UNIVERSE, RECURSIVELY FIND CELL diff --git a/src/geometry.cpp b/src/geometry.cpp index 4c31fe85d0..7131a45135 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -5,7 +5,7 @@ #include "cell.h" #include "constants.h" #include "error.h" -#include "particle.h" +#include "lattice.h" #include "settings.h" //TODO: remove this include @@ -16,6 +16,8 @@ namespace openmc { std::vector overlap_check_count; +//============================================================================== + extern "C" bool check_cell_overlap(Particle* p) { int n_coord = p->n_coord; @@ -72,10 +74,11 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { // Find which cell of this universe the particle is in. bool found = false; + int32_t i_cell; for (int i = 0; i < n_search_cells; i++) { - int32_t i_cell = search_cells[i]; + i_cell = search_cells[i]; - // Make sure the search cell is in the same universe + // Make sure the search cell is in the same universe. //TODO: off-by-one indexing if (global_cells[i_cell]->universe - 1 != i_universe) continue; @@ -96,6 +99,58 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { } } + if (found) { + Cell& c {*global_cells[i_cell]}; + if (c.type == FILL_MATERIAL) { + // Find the distribcell instance number. + if (c.material.size() > 1 || c.sqrtkT.size() > 1) { + //===================================================================== + //! Found a material cell which means this is the lowest coord level. + + //TODO: off-by-one indexing + int distribcell_index = c.distribcell_index - 1; + int offset = 0; + for (int i = 0; i < p->n_coord; i++) { + Cell& c_i {*global_cells[p->coord[i].cell-1]}; + if (c_i.type == FILL_UNIVERSE) { + offset += c_i.offset[distribcell_index]; + } else if (c_i.type == FILL_LATTICE) { + Lattice& lat {*lattices_c[p->coord[i+1].lattice-1]}; + int i_xyz[3] {p->coord[i+1].lattice_x, + p->coord[i+1].lattice_y, + p->coord[i+1].lattice_z}; + if (lat.are_valid_indices(i_xyz)) { + offset += lat.offset(distribcell_index, i_xyz); + } + } + } + p->cell_instance = offset + 1; + } else { + p->cell_instance = 1; + } + + // Set the material and temperature. + p->last_material = p->material; + int32_t mat; + if (c.material.size() > 1) { + mat = c.material[p->cell_instance-1]; + } else { + mat = c.material[0]; + } + if (mat == MATERIAL_VOID) { + p->material = MATERIAL_VOID; + } else { + p->material = mat + 1; + } + p->last_sqrtkT = p->sqrtkT; + if (c.sqrtkT.size() > 1) { + p->sqrtkT = c.sqrtkT[p->cell_instance-1]; + } else { + p->sqrtkT = c.sqrtkT[0]; + } + } + } + return found; } diff --git a/src/geometry.h b/src/geometry.h index e02a17b983..b73ae314c4 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -4,13 +4,28 @@ #include #include +#include "particle.h" + namespace openmc { extern "C" int openmc_root_universe; -//TODO: free this memory extern std::vector overlap_check_count; +//============================================================================== +//! Check for overlapping cells at the particle's position. +//============================================================================== + +extern "C" bool +check_cell_overlap(Particle* p); + +//============================================================================== +//! Locate the particle in the geometry tree and set its geometry data fields. +//============================================================================== + +extern "C" bool +find_cell(Particle* p, int n_search_cells, int* search_cells); + } // namespace openmc #endif // OPENMC_GEOMETRY_H From 2ed0fceb7d4eb919e8b40b870727225c69a02ea4 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 20 Aug 2018 14:31:31 -0400 Subject: [PATCH 19/43] Make translation and rotation tests more thorough --- tests/regression_tests/rotation/geometry.xml | 10 +++++----- tests/regression_tests/rotation/materials.xml | 7 ++++++- tests/regression_tests/rotation/results_true.dat | 2 +- tests/regression_tests/translation/geometry.xml | 10 +++++----- tests/regression_tests/translation/materials.xml | 7 ++++++- tests/regression_tests/translation/results_true.dat | 2 +- 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/tests/regression_tests/rotation/geometry.xml b/tests/regression_tests/rotation/geometry.xml index 2226178771..f324617065 100644 --- a/tests/regression_tests/rotation/geometry.xml +++ b/tests/regression_tests/rotation/geometry.xml @@ -1,11 +1,11 @@ - - - + + - - + + + diff --git a/tests/regression_tests/rotation/materials.xml b/tests/regression_tests/rotation/materials.xml index 2472a74717..160c9c6789 100644 --- a/tests/regression_tests/rotation/materials.xml +++ b/tests/regression_tests/rotation/materials.xml @@ -2,8 +2,13 @@ - + + + + + + diff --git a/tests/regression_tests/rotation/results_true.dat b/tests/regression_tests/rotation/results_true.dat index 5cb3925a62..7598a4a478 100644 --- a/tests/regression_tests/rotation/results_true.dat +++ b/tests/regression_tests/rotation/results_true.dat @@ -1,2 +1,2 @@ k-combined: -2.943619E-01 3.309646E-03 +4.240695E-01 8.013236E-03 diff --git a/tests/regression_tests/translation/geometry.xml b/tests/regression_tests/translation/geometry.xml index e2cdf23916..6c6343865a 100644 --- a/tests/regression_tests/translation/geometry.xml +++ b/tests/regression_tests/translation/geometry.xml @@ -1,11 +1,11 @@ - - - + + - - + + + diff --git a/tests/regression_tests/translation/materials.xml b/tests/regression_tests/translation/materials.xml index 2472a74717..160c9c6789 100644 --- a/tests/regression_tests/translation/materials.xml +++ b/tests/regression_tests/translation/materials.xml @@ -2,8 +2,13 @@ - + + + + + + diff --git a/tests/regression_tests/translation/results_true.dat b/tests/regression_tests/translation/results_true.dat index 5cb3925a62..a503110345 100644 --- a/tests/regression_tests/translation/results_true.dat +++ b/tests/regression_tests/translation/results_true.dat @@ -1,2 +1,2 @@ k-combined: -2.943619E-01 3.309646E-03 +4.101355E-01 1.577552E-02 From cddf39b201eb152f89a3ebed536fd36ba1797c39 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 20 Aug 2018 19:52:07 -0400 Subject: [PATCH 20/43] Move FILL_UNIVERSE chunk of find_cell to C++ --- src/cell.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++ src/cell.h | 10 +++++++ src/geometry.F90 | 22 --------------- src/geometry.cpp | 48 ++++++++++++++++++++++++++++++-- src/input_xml.F90 | 22 --------------- src/position.h | 19 ++++++++++++- src/summary.F90 | 11 -------- 7 files changed, 144 insertions(+), 59 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index a68ab9d0b4..9786a89fc6 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -317,6 +317,65 @@ Cell::Cell(pugi::xml_node cell_node) break; } } + + // Read the translation vector. + if (check_for_node(cell_node, "translation")) { + if (fill == C_NONE) { + std::stringstream err_msg; + err_msg << "Cannot apply a translation to cell " << id + << " because it is not filled with another universe"; + fatal_error(err_msg); + } + + auto xyz {get_node_array(cell_node, "translation")}; + if (xyz.size() != 3) { + std::stringstream err_msg; + err_msg << "Non-3D translation vector applied to cell " << id; + fatal_error(err_msg); + } + translation = xyz; + } + + // Read the rotation transform. + if (check_for_node(cell_node, "rotation")) { + if (fill == C_NONE) { + std::stringstream err_msg; + err_msg << "Cannot apply a rotation to cell " << id + << " because it is not filled with another universe"; + fatal_error(err_msg); + } + + auto rot {get_node_array(cell_node, "rotation")}; + if (rot.size() != 3) { + std::stringstream err_msg; + err_msg << "Non-3D rotation vector applied to cell " << id; + fatal_error(err_msg); + } + + // Store the rotation angles. + rotation.reserve(12); + rotation.push_back(rot[0]); + rotation.push_back(rot[1]); + rotation.push_back(rot[2]); + + // Compute and store the rotation matrix. + auto phi = -rot[0] * PI / 180.0; + auto theta = -rot[1] * PI / 180.0; + auto psi = -rot[2] * PI / 180.0; + rotation.push_back(std::cos(theta) * std::cos(psi)); + rotation.push_back(-std::cos(phi) * std::sin(psi) + + std::sin(phi) * std::sin(theta) * std::cos(psi)); + rotation.push_back(std::sin(phi) * std::sin(psi) + + std::cos(phi) * std::sin(theta) * std::cos(psi)); + rotation.push_back(std::cos(theta) * std::sin(psi)); + rotation.push_back(std::cos(phi) * std::cos(psi) + + std::sin(phi) * std::sin(theta) * std::sin(psi)); + rotation.push_back(-std::sin(phi) * std::cos(psi) + + std::cos(phi) * std::sin(theta) * std::sin(psi)); + rotation.push_back(-std::sin(theta)); + rotation.push_back(std::sin(phi) * std::cos(theta)); + rotation.push_back(std::cos(phi) * std::cos(theta)); + } } //============================================================================== @@ -393,6 +452,18 @@ Cell::to_hdf5(hid_t cell_group) const } write_string(cell_group, "region", region_spec.str(), false); } + + if (type == FILL_UNIVERSE) { + write_dataset(cell_group, "fill_type", "universe"); + write_dataset(cell_group, "fill", global_universes[fill]->id); + if (translation != 0) { + write_dataset(cell_group, "translation", translation); + } + if (!rotation.empty()) { + std::array rot {rotation[0], rotation[1], rotation[2]}; + write_dataset(cell_group, "rotation", rot); + } + } } //============================================================================== diff --git a/src/cell.h b/src/cell.h index 8b7c3a78b1..4f3a8978f9 100644 --- a/src/cell.h +++ b/src/cell.h @@ -85,6 +85,16 @@ public: std::vector rpn; bool simple; //!< Does the region contain only intersections? + Position translation {0, 0, 0}; //!< Translation vector for filled universe + + //! \brief Rotational tranfsormation of the filled universe. + // + //! The vector is empty if there is no rotation. Otherwise, the first three + //! values are the rotation angles respectively about the x-, y-, and z-, axes + //! in degrees. The next 9 values give the rotation matrix in row-major + //! order. + std::vector rotation; + std::vector offset; //!< Distribcell offset table Cell() {}; diff --git a/src/geometry.F90 b/src/geometry.F90 index 29e03bbb5f..817da18ded 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -84,30 +84,8 @@ contains if (found) then associate(c => cells(i_cell)) CELL_TYPE: if (c % type() == FILL_UNIVERSE) then - ! ====================================================================== - ! CELL CONTAINS LOWER UNIVERSE, RECURSIVELY FIND CELL - - ! Store lower level coordinates - p % coord(j + 1) % xyz = p % coord(j) % xyz - p % coord(j + 1) % uvw = p % coord(j) % uvw - - ! Move particle to next level and set universe j = j + 1 p % n_coord = j - p % coord(j) % universe = c % fill() + 1 - - ! Apply translation - if (allocated(c % translation)) then - p % coord(j) % xyz = p % coord(j) % xyz - c % translation - end if - - ! Apply rotation - if (allocated(c % rotation_matrix)) then - p % coord(j) % xyz = matmul(c % rotation_matrix, p % coord(j) % xyz) - p % coord(j) % uvw = matmul(c % rotation_matrix, p % coord(j) % uvw) - p % coord(j) % rotated = .true. - end if - call find_cell(p, found) j = p % n_coord diff --git a/src/geometry.cpp b/src/geometry.cpp index 7131a45135..695afe0be3 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -102,11 +102,11 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { if (found) { Cell& c {*global_cells[i_cell]}; if (c.type == FILL_MATERIAL) { + //======================================================================= + //! Found a material cell which means this is the lowest coord level. + // Find the distribcell instance number. if (c.material.size() > 1 || c.sqrtkT.size() > 1) { - //===================================================================== - //! Found a material cell which means this is the lowest coord level. - //TODO: off-by-one indexing int distribcell_index = c.distribcell_index - 1; int offset = 0; @@ -148,6 +148,48 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { } else { p->sqrtkT = c.sqrtkT[0]; } + + } else if (c.type == FILL_UNIVERSE) { + //======================================================================== + //! Found a lower universe, update this coord level then search the next. + + // Add another coordinate level. + //++p->n_coord; + p->coord[p->n_coord].universe = c.fill + 1; + + // Set the position and direction. + for (int i = 0; i < 3; i++) { + p->coord[p->n_coord].xyz[i] = p->coord[p->n_coord-1].xyz[i]; + p->coord[p->n_coord].uvw[i] = p->coord[p->n_coord-1].uvw[i]; + } + + // Apply translation. + p->coord[p->n_coord].xyz[0] -= c.translation.x; + p->coord[p->n_coord].xyz[1] -= c.translation.y; + p->coord[p->n_coord].xyz[2] -= c.translation.z; + + // Apply rotation. + if (!c.rotation.empty()) { + auto x = p->coord[p->n_coord].xyz[0]; + auto y = p->coord[p->n_coord].xyz[1]; + auto z = p->coord[p->n_coord].xyz[2]; + p->coord[p->n_coord].xyz[0] = x*c.rotation[3] + y*c.rotation[4] + + z*c.rotation[5]; + p->coord[p->n_coord].xyz[1] = x*c.rotation[6] + y*c.rotation[7] + + z*c.rotation[8]; + p->coord[p->n_coord].xyz[2] = x*c.rotation[9] + y*c.rotation[10] + + z*c.rotation[11]; + auto u = p->coord[p->n_coord].uvw[0]; + auto v = p->coord[p->n_coord].uvw[1]; + auto w = p->coord[p->n_coord].uvw[2]; + p->coord[p->n_coord].uvw[0] = u*c.rotation[3] + v*c.rotation[4] + + w*c.rotation[5]; + p->coord[p->n_coord].uvw[1] = u*c.rotation[6] + v*c.rotation[7] + + w*c.rotation[8]; + p->coord[p->n_coord].uvw[2] = u*c.rotation[9] + v*c.rotation[10] + + w*c.rotation[11]; + p->coord[p->n_coord].rotated = true; + } } } diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 7d8a8393df..27b8be9467 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1176,28 +1176,6 @@ contains cos(phi)*cos(theta) /), (/ 3,3 /)) end if - ! Translation vector - if (check_for_node(node_cell, "translation")) then - ! Translations can only be applied to cells that are being filled with - ! another universe - if (c % fill() == C_NONE) then - call fatal_error("Cannot apply a translation to cell " & - // trim(to_str(c % id())) // " because it is not filled with & - &another universe") - end if - - ! Read number of translation parameters - n = node_word_count(node_cell, "translation") - if (n /= 3) then - call fatal_error("Incorrect number of translation parameters on & - &cell " // to_str(c % id())) - end if - - ! Copy translation vector - allocate(c % translation(3)) - call get_node_array(node_cell, "translation", c % translation) - end if - ! Add cell to dictionary call cell_dict % set(c % id(), i) diff --git a/src/position.h b/src/position.h index 808e0bcf67..62af3a1224 100644 --- a/src/position.h +++ b/src/position.h @@ -1,6 +1,8 @@ #ifndef OPENMC_POSITION_H #define OPENMC_POSITION_H +#include + namespace openmc { //============================================================================== @@ -12,6 +14,7 @@ struct Position { Position() = default; Position(double x_, double y_, double z_) : x{x_}, y{y_}, z{z_} { }; Position(const double xyz[]) : x{xyz[0]}, y{xyz[1]}, z{xyz[2]} { }; + Position(const std::vector xyz) : x{xyz[0]}, y{xyz[1]}, z{xyz[2]} { }; // Unary operators Position& operator+=(Position); @@ -63,6 +66,20 @@ inline Position operator*(Position a, Position b) { return a *= b; } inline Position operator*(Position a, double b) { return a *= b; } inline Position operator*(double a, Position b) { return b *= a; } +inline bool operator==(Position a, Position b) +{return a.x == b.x && a.y == b.y && a.z == b.z;} +inline bool operator==(Position a, double b) +{return a.x == b && a.y == b && a.z == b;} +inline bool operator==(double a, Position b) +{return a == b.x && a == b.y && a == b.z;} + +inline bool operator!=(Position a, Position b) +{return a.x != b.x || a.y != b.y || a.z != b.z;} +inline bool operator!=(Position a, double b) +{return a.x != b || a.y != b || a.z != b;} +inline bool operator!=(double a, Position b) +{return a != b.x || a != b.y || a != b.z;} + //============================================================================== //! Type representing a vector direction in Cartesian coordinates //============================================================================== @@ -71,4 +88,4 @@ using Direction = Position; } // namespace openmc -#endif // OPENMC_POSITION_H \ No newline at end of file +#endif // OPENMC_POSITION_H diff --git a/src/summary.F90 b/src/summary.F90 index 6c311e9821..e2cc5f786d 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -225,17 +225,6 @@ contains call write_dataset(cell_group, "temperature", cell_temperatures) deallocate(cell_temperatures) - case (FILL_UNIVERSE) - call write_dataset(cell_group, "fill_type", "universe") - call write_dataset(cell_group, "fill", universes(c%fill()+1)%id) - - if (allocated(c%translation)) then - call write_dataset(cell_group, "translation", c%translation) - end if - if (allocated(c%rotation)) then - call write_dataset(cell_group, "rotation", c%rotation) - end if - case (FILL_LATTICE) call write_dataset(cell_group, "fill_type", "lattice") ! Do not access the 'lattices' array with 'c % fill() + 1' directly; it From 918735732a7acf9f9453555ea4dcafe2f8f5d0d4 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 20 Aug 2018 20:39:55 -0400 Subject: [PATCH 21/43] Move FILL_LATTICE chunk of find_cell to C++ --- src/geometry.F90 | 63 ----------------------------------------- src/geometry.cpp | 57 +++++++++++++++++++++++++++++++++---- src/geometry_header.F90 | 15 ---------- src/lattice.cpp | 2 -- src/lattice.h | 21 ++++++++++++++ 5 files changed, 73 insertions(+), 85 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index 817da18ded..dcaabb9dda 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -65,78 +65,15 @@ contains !=============================================================================== recursive subroutine find_cell(p, found, search_cells) - type(Particle), intent(inout) :: p logical, intent(inout) :: found integer, optional :: search_cells(:) - integer :: j ! coordinate level index - integer :: i_xyz(3) ! indices in lattice - integer :: i_cell ! index in cells array if (present(search_cells)) then found = find_cell_c(p, size(search_cells), search_cells-1) else found = find_cell_c(p, 0) end if - j = p % n_coord - i_cell = p % coord(j) % cell - - if (found) then - associate(c => cells(i_cell)) - CELL_TYPE: if (c % type() == FILL_UNIVERSE) then - j = j + 1 - p % n_coord = j - call find_cell(p, found) - j = p % n_coord - - elseif (c % type() == FILL_LATTICE) then CELL_TYPE - ! ====================================================================== - ! CELL CONTAINS LATTICE, RECURSIVELY FIND CELL - - associate (lat => lattices(c % fill() + 1) % obj) - ! Determine lattice indices - i_xyz = lat % get_indices(p % coord(j) % xyz + TINY_BIT * p % coord(j) % uvw) - - ! Store lower level coordinates - p % coord(j + 1) % xyz = lat % get_local_xyz(p % coord(j) % xyz, i_xyz) - p % coord(j + 1) % uvw = p % coord(j) % uvw - - ! set particle lattice indices - p % coord(j + 1) % lattice = c % fill() + 1 - p % coord(j + 1) % lattice_x = i_xyz(1) - p % coord(j + 1) % lattice_y = i_xyz(2) - p % coord(j + 1) % lattice_z = i_xyz(3) - - ! Set the next lowest coordinate level. - if (lat % are_valid_indices(i_xyz)) then - ! Particle is inside the lattice. - p % coord(j + 1) % universe = & - lat % get([i_xyz(1), i_xyz(2), i_xyz(3)]) + 1 - - else - ! Particle is outside the lattice. - if (lat % outer() == NO_OUTER_UNIVERSE) then - call warning("Particle " // trim(to_str(p %id)) & - // " is outside lattice " // trim(to_str(lat % id())) & - // " but the lattice has no defined outer universe.") - found = .false. - return - else - p % coord(j + 1) % universe = lat % outer() + 1 - end if - end if - end associate - - ! Move particle to next level and search for the lower cells. - j = j + 1 - p % n_coord = j - - call find_cell(p, found) - j = p % n_coord - - end if CELL_TYPE - end associate - end if end subroutine find_cell diff --git a/src/geometry.cpp b/src/geometry.cpp index 695afe0be3..e400a2245d 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -8,9 +8,6 @@ #include "lattice.h" #include "settings.h" -//TODO: remove this include -#include - namespace openmc { @@ -153,8 +150,7 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { //======================================================================== //! Found a lower universe, update this coord level then search the next. - // Add another coordinate level. - //++p->n_coord; + // Set the lower coordinate level universe. p->coord[p->n_coord].universe = c.fill + 1; // Set the position and direction. @@ -190,6 +186,57 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { + w*c.rotation[11]; p->coord[p->n_coord].rotated = true; } + + // Update the coordinate level and recurse. + ++p->n_coord; + find_cell(p, 0, nullptr); + + } else if (c.type == FILL_LATTICE) { + //======================================================================== + //! Found a lower lattice, update this coord level then search the next. + + Lattice& lat {*lattices_c[c.fill]}; + + // Determine lattice indices. + Position r {p->coord[p->n_coord-1].xyz}; + Direction u {p->coord[p->n_coord-1].uvw}; + r += TINY_BIT * u; + auto i_xyz = lat.get_indices(r); + + // Store lower level coordinates. + r = lat.get_local_position(p->coord[p->n_coord-1].xyz, i_xyz); + p->coord[p->n_coord].xyz[0] = r.x; + p->coord[p->n_coord].xyz[1] = r.y; + p->coord[p->n_coord].xyz[2] = r.z; + p->coord[p->n_coord].uvw[0] = u.x; + p->coord[p->n_coord].uvw[1] = u.y; + p->coord[p->n_coord].uvw[2] = u.z; + + // Set lattice indices. + p->coord[p->n_coord].lattice = c.fill + 1; + p->coord[p->n_coord].lattice_x = i_xyz[0]; + p->coord[p->n_coord].lattice_y = i_xyz[1]; + p->coord[p->n_coord].lattice_z = i_xyz[2]; + + // Set the lower coordinate level universe. + if (lat.are_valid_indices(i_xyz)) { + p->coord[p->n_coord].universe = lat[i_xyz] + 1; + } else { + if (lat.outer != NO_OUTER_UNIVERSE) { + p->coord[p->n_coord].universe = lat.outer + 1; + } else { + std::stringstream err_msg; + err_msg << "Particle " << p->id << " is outside lattice " + << lat.id << " but the lattice has no defined outer " + "universe."; + warning(err_msg); + found = false; + } + } + + // Update the coordinate level and recurse. + ++p->n_coord; + find_cell(p, 0, nullptr); } } diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 272966b338..23700d8291 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -191,13 +191,6 @@ module geometry_header integer(C_INT32_T) :: offset end function lattice_offset_c - function lattice_outer_c(lat_ptr) bind(C, name='lattice_outer') & - result(outer) - import C_PTR, C_INT32_T - type(C_PTR), intent(in), value :: lat_ptr - integer(C_INT32_T) :: outer - end function lattice_outer_c - function lattice_universe_c(lat_ptr, i_xyz) & bind(C, name='lattice_universe') result(univ) import C_PTR, C_INT32_t, C_INT @@ -238,7 +231,6 @@ module geometry_header procedure :: get_indices => lattice_get_indices procedure :: get_local_xyz => lattice_get_local_xyz procedure :: offset => lattice_offset - procedure :: outer => lattice_outer procedure :: to_hdf5 => lattice_to_hdf5 end type Lattice @@ -275,7 +267,6 @@ module geometry_header ! Boolean expression of half-spaces ! Rotation matrix and translation vector - real(8), allocatable :: translation(:) real(8), allocatable :: rotation(:) real(8), allocatable :: rotation_matrix(:,:) @@ -370,12 +361,6 @@ contains offset = lattice_offset_c(this % ptr, map, i_xyz) end function lattice_offset - function lattice_outer(this) result(outer) - class(Lattice), intent(in) :: this - integer(C_INT32_T) :: outer - outer = lattice_outer_c(this % ptr) - end function lattice_outer - subroutine lattice_to_hdf5(this, group) class(Lattice), intent(in) :: this integer(HID_T), intent(in) :: group diff --git a/src/lattice.cpp b/src/lattice.cpp index e2871d9e1a..8797d0fbac 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -923,8 +923,6 @@ extern "C" { int32_t lattice_offset(Lattice *lat, int map, const int i_xyz[3]) {return lat->offset(map, i_xyz);} - int32_t lattice_outer(Lattice *lat) {return lat->outer;} - void lattice_to_hdf5(Lattice *lat, hid_t group) {lat->to_hdf5(group);} int32_t lattice_universe(Lattice *lat, const int i_xyz[3]) diff --git a/src/lattice.h b/src/lattice.h index 94d7b43878..df7c699d8c 100644 --- a/src/lattice.h +++ b/src/lattice.h @@ -54,6 +54,13 @@ public: virtual int32_t& operator[](const int i_xyz[3]) = 0; + int32_t& + operator[](std::array i_xyz) + { + int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; + return operator[](i_xyz_); + } + virtual LatticeIter begin(); LatticeIter end(); @@ -76,6 +83,13 @@ public: //! otherwise. virtual bool are_valid_indices(const int i_xyz[3]) const = 0; + bool + are_valid_indices(std::array i_xyz) const + { + int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; + return are_valid_indices(i_xyz_); + } + //! \brief Find the next lattice surface crossing //! \param r A 3D Cartesian coordinate. //! \param u A 3D Cartesian direction. @@ -98,6 +112,13 @@ public: virtual Position get_local_position(Position r, const int i_xyz[3]) const = 0; + Position + get_local_position(Position r, std::array i_xyz) const + { + int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; + return get_local_position(r, i_xyz_); + } + //! \brief Check flattened lattice index. //! \param indx The index for a lattice tile. //! \return true if the given index fit within the lattice bounds. False From c98142dd239c249330356793c93c09af5dccec76 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 20 Aug 2018 22:45:28 -0400 Subject: [PATCH 22/43] Move cross_lattice to C++ --- src/geometry.F90 | 82 +++++------------------------------------------- src/geometry.cpp | 64 ++++++++++++++++++++++++++++++++++++- src/geometry.h | 11 +++++-- src/particle.h | 10 +++++- 4 files changed, 89 insertions(+), 78 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index dcaabb9dda..09f7066bef 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -41,11 +41,18 @@ module geometry function find_cell_c(p, n_search_cells, search_cells) & bind(C, name="find_cell") result(found) import Particle, C_INT, C_BOOL - type(Particle), intent(in) :: p + type(Particle), intent(inout) :: p integer(C_INT), intent(in), value :: n_search_cells integer(C_INT), intent(in), optional :: search_cells(n_search_cells) logical(C_BOOL) :: found end function find_cell_c + + subroutine cross_lattice(p, lattice_translation) & + bind(C, name="cross_lattice") + import Particle, C_INT + type(Particle), intent(inout) :: p + integer(C_INT), intent(in) :: lattice_translation(3) + end subroutine cross_lattice end interface contains @@ -77,79 +84,6 @@ contains end subroutine find_cell -!=============================================================================== -! CROSS_LATTICE moves a particle into a new lattice element -!=============================================================================== - - subroutine cross_lattice(p, lattice_translation) - - type(Particle), intent(inout) :: p - integer, intent(in) :: lattice_translation(3) - integer :: j - integer :: i_xyz(3) ! indices in lattice - logical :: found ! particle found in cell? - class(Lattice), pointer :: lat - - j = p % n_coord - lat => lattices(p % coord(j) % lattice) % obj - - if (verbosity >= 10 .or. trace) then - call write_message(" Crossing lattice " // trim(to_str(lat % id())) & - &// ". Current position (" // trim(to_str(p % coord(j) % lattice_x)) & - &// "," // trim(to_str(p % coord(j) % lattice_y)) // "," & - &// trim(to_str(p % coord(j) % lattice_z)) // ")") - end if - - ! Set the lattice indices. - p % coord(j) % lattice_x = p % coord(j) % lattice_x + lattice_translation(1) - p % coord(j) % lattice_y = p % coord(j) % lattice_y + lattice_translation(2) - p % coord(j) % lattice_z = p % coord(j) % lattice_z + lattice_translation(3) - i_xyz(1) = p % coord(j) % lattice_x - i_xyz(2) = p % coord(j) % lattice_y - i_xyz(3) = p % coord(j) % lattice_z - - ! Set the new coordinate position. - p % coord(j) % xyz = lat % get_local_xyz(p % coord(j - 1) % xyz, i_xyz) - - OUTSIDE_LAT: if (.not. lat % are_valid_indices(i_xyz)) then - ! The particle is outside the lattice. Search for it from base coord - p % n_coord = 1 - call find_cell(p, found) - if (.not. found) then - if (p % alive) then ! Particle may have been killed in find_cell - call particle_mark_as_lost(p, "Could not locate particle " & - // trim(to_str(p % id)) // " after crossing a lattice boundary.") - return - end if - end if - - else OUTSIDE_LAT - - ! Find cell in next lattice element - p % coord(j) % universe = & - lat % get([i_xyz(1), i_xyz(2), i_xyz(3)]) + 1 - - call find_cell(p, found) - if (.not. found) then - ! In some circumstances, a particle crossing the corner of a cell may - ! not be able to be found in the next universe. In this scenario we cut - ! off all lower-level coordinates and search from universe zero - - ! Remove lower coordinates - p % n_coord = 1 - - ! Search for particle - call find_cell(p, found) - if (.not. found) then - call particle_mark_as_lost(p, "Could not locate particle " // & - trim(to_str(p % id)) // " after crossing a lattice boundary.") - return - end if - end if - end if OUTSIDE_LAT - - end subroutine cross_lattice - !=============================================================================== ! DISTANCE_TO_BOUNDARY calculates the distance to the nearest boundary for a ! particle 'p' traveling in a certain direction. For a cell in a subuniverse diff --git a/src/geometry.cpp b/src/geometry.cpp index e400a2245d..85cefb7e2d 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -1,5 +1,6 @@ #include "geometry.h" +#include #include #include "cell.h" @@ -230,7 +231,7 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { << lat.id << " but the lattice has no defined outer " "universe."; warning(err_msg); - found = false; + return false; } } @@ -243,4 +244,65 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { return found; } +//============================================================================== + +extern "C" void +cross_lattice(Particle* p, int lattice_translation[3]) +{ + Lattice& lat {*lattices_c[p->coord[p->n_coord-1].lattice-1]}; + + if (openmc_verbosity >= 10 || openmc_trace) { + std::stringstream msg; + msg << " Crossing lattice " << lat.id << ". Current position (" + << p->coord[p->n_coord-1].lattice_x << "," + << p->coord[p->n_coord-1].lattice_y << "," + << p->coord[p->n_coord-1].lattice_z << ")"; + write_message(msg, 1); + } + + // Set the lattice indices. + p->coord[p->n_coord-1].lattice_x += lattice_translation[0]; + p->coord[p->n_coord-1].lattice_y += lattice_translation[1]; + p->coord[p->n_coord-1].lattice_z += lattice_translation[2]; + std::array i_xyz {p->coord[p->n_coord-1].lattice_x, + p->coord[p->n_coord-1].lattice_y, + p->coord[p->n_coord-1].lattice_z}; + + // Set the new coordinate position. + auto r = lat.get_local_position(p->coord[p->n_coord-2].xyz, i_xyz); + p->coord[p->n_coord-1].xyz[0] = r.x; + p->coord[p->n_coord-1].xyz[1] = r.y; + p->coord[p->n_coord-1].xyz[2] = r.z; + + if (!lat.are_valid_indices(i_xyz)) { + // The particle is outside the lattice. Search for it from the base coords. + p->n_coord = 1; + bool found = find_cell(p, 0, nullptr); + if (!found && p->alive) { + std::stringstream err_msg; + err_msg << "Could not locate particle " << p->id + << " after crossing a lattice boundary"; + p->mark_as_lost(err_msg); + } + + } else { + // Find cell in next lattice element. + p->coord[p->n_coord-1].universe = lat[i_xyz] + 1; + bool found = find_cell(p, 0, nullptr); + + if (!found) { + // A particle crossing the corner of a lattice tile may not be found. In + // this case, search for it from the base coords. + p->n_coord = 1; + bool found = find_cell(p, 0, nullptr); + if (!found && p->alive) { + std::stringstream err_msg; + err_msg << "Could not locate particle " << p->id + << " after crossing a lattice boundary"; + p->mark_as_lost(err_msg); + } + } + } +} + } // namespace openmc diff --git a/src/geometry.h b/src/geometry.h index b73ae314c4..47162c73e1 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -13,19 +13,26 @@ extern "C" int openmc_root_universe; extern std::vector overlap_check_count; //============================================================================== -//! Check for overlapping cells at the particle's position. +//! Check for overlapping cells at a particle's position. //============================================================================== extern "C" bool check_cell_overlap(Particle* p); //============================================================================== -//! Locate the particle in the geometry tree and set its geometry data fields. +//! Locate a particle in the geometry tree and set its geometry data fields. //============================================================================== extern "C" bool find_cell(Particle* p, int n_search_cells, int* search_cells); +//============================================================================== +//! Move a particle into a new lattice tile. +//============================================================================== + +extern "C" void +cross_lattice(Particle* p, int lattice_translation[3]); + } // namespace openmc #endif // OPENMC_GEOMETRY_H diff --git a/src/particle.h b/src/particle.h index b533971710..e03af3d69b 100644 --- a/src/particle.h +++ b/src/particle.h @@ -4,8 +4,10 @@ //! \file particle.h //! \brief Particle type -#include #include +#include +#include +#include #include "openmc.h" @@ -152,6 +154,12 @@ extern "C" { //! \param message A warning message to display void mark_as_lost(const char* message); + void mark_as_lost(const std::string& message) + {mark_as_lost(message.c_str());} + + void mark_as_lost(const std::stringstream& message) + {mark_as_lost(message.str());} + //! create a particle restart HDF5 file void write_restart(); }; From bc1c1e491628741fb8457d5a1ecc69d9c259b541 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 20 Aug 2018 23:42:51 -0400 Subject: [PATCH 23/43] Move neighbor lists to C++ --- src/cell.cpp | 18 -------- src/cell.h | 7 ++++ src/geometry.F90 | 92 +++++------------------------------------ src/geometry.cpp | 27 ++++++++---- src/geometry.h | 2 +- src/geometry_aux.cpp | 28 +++++++++++++ src/geometry_aux.h | 6 +++ src/geometry_header.F90 | 6 --- src/input_xml.F90 | 44 +------------------- src/string.F90 | 92 ----------------------------------------- src/surface.h | 5 ++- src/surface_header.F90 | 3 -- src/tracking.F90 | 17 +------- 13 files changed, 79 insertions(+), 268 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index 9786a89fc6..c22813ea71 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -17,17 +17,6 @@ namespace openmc { -//============================================================================== -// Constants -//============================================================================== - -// TODO: Convert to enum -constexpr int32_t OP_LEFT_PAREN {std::numeric_limits::max()}; -constexpr int32_t OP_RIGHT_PAREN {std::numeric_limits::max() - 1}; -constexpr int32_t OP_COMPLEMENT {std::numeric_limits::max() - 2}; -constexpr int32_t OP_INTERSECTION {std::numeric_limits::max() - 3}; -constexpr int32_t OP_UNION {std::numeric_limits::max() - 4}; - //============================================================================== // Global variables //============================================================================== @@ -705,13 +694,6 @@ extern "C" { bool cell_simple(Cell* c) {return c->simple;} - bool cell_contains(Cell* c, double xyz[3], double uvw[3], int32_t on_surface) - { - Position r {xyz}; - Direction u {uvw}; - return c->contains(r, u, on_surface); - } - void cell_distance(Cell* c, double xyz[3], double uvw[3], int32_t on_surface, double* min_dist, int32_t* i_surf) { diff --git a/src/cell.h b/src/cell.h index 4f3a8978f9..a10c407f0b 100644 --- a/src/cell.h +++ b/src/cell.h @@ -25,6 +25,13 @@ extern "C" int FILL_MATERIAL; extern "C" int FILL_UNIVERSE; extern "C" int FILL_LATTICE; +// TODO: Convert to enum +constexpr int32_t OP_LEFT_PAREN {std::numeric_limits::max()}; +constexpr int32_t OP_RIGHT_PAREN {std::numeric_limits::max() - 1}; +constexpr int32_t OP_COMPLEMENT {std::numeric_limits::max() - 2}; +constexpr int32_t OP_INTERSECTION {std::numeric_limits::max() - 3}; +constexpr int32_t OP_UNION {std::numeric_limits::max() - 4}; + //============================================================================== // Global variables //============================================================================== diff --git a/src/geometry.F90 b/src/geometry.F90 index 09f7066bef..dcd44360be 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -15,16 +15,6 @@ module geometry implicit none interface - function cell_contains_c(cell_ptr, xyz, uvw, on_surface) & - bind(C, name="cell_contains") result(in_cell) - import C_PTR, C_DOUBLE, C_INT32_T, C_BOOL - type(C_PTR), intent(in), value :: cell_ptr - real(C_DOUBLE), intent(in) :: xyz(3) - real(C_DOUBLE), intent(in) :: uvw(3) - integer(C_INT32_T), intent(in), value :: on_surface - logical(C_BOOL) :: in_cell - end function cell_contains_c - function count_universe_instances(search_univ, target_univ_id) bind(C) & result(count) import C_INT32_T, C_INT @@ -38,12 +28,11 @@ module geometry type(Particle), intent(in) :: p end subroutine check_cell_overlap - function find_cell_c(p, n_search_cells, search_cells) & + function find_cell_c(p, search_surf) & bind(C, name="find_cell") result(found) import Particle, C_INT, C_BOOL type(Particle), intent(inout) :: p - integer(C_INT), intent(in), value :: n_search_cells - integer(C_INT), intent(in), optional :: search_cells(n_search_cells) + integer(C_INT), intent(in), value :: search_surf logical(C_BOOL) :: found end function find_cell_c @@ -53,31 +42,26 @@ module geometry type(Particle), intent(inout) :: p integer(C_INT), intent(in) :: lattice_translation(3) end subroutine cross_lattice + + subroutine neighbor_lists() bind(C) + end subroutine neighbor_lists end interface contains - function cell_contains(c, p) result(in_cell) - type(Cell), intent(in) :: c - type(Particle), intent(in) :: p - logical :: in_cell - in_cell = cell_contains_c(c%ptr, p%coord(p%n_coord)%xyz, & - p%coord(p%n_coord)%uvw, p%surface) - end function cell_contains - !=============================================================================== ! FIND_CELL determines what cell a source particle is in within a particular ! universe. If the base universe is passed, the particle should be found as long ! as it's within the geometry !=============================================================================== - recursive subroutine find_cell(p, found, search_cells) - type(Particle), intent(inout) :: p - logical, intent(inout) :: found - integer, optional :: search_cells(:) + subroutine find_cell(p, found, search_surf) + type(Particle), intent(inout) :: p + logical, intent(inout) :: found + integer, optional, intent(in) :: search_surf - if (present(search_cells)) then - found = find_cell_c(p, size(search_cells), search_cells-1) + if (present(search_surf)) then + found = find_cell_c(p, search_surf) else found = find_cell_c(p, 0) end if @@ -201,58 +185,4 @@ contains end subroutine distance_to_boundary -!=============================================================================== -! NEIGHBOR_LISTS builds a list of neighboring cells to each surface to speed up -! searches when a cell boundary is crossed. -!=============================================================================== - - subroutine neighbor_lists() - - integer :: i ! index in cells/surfaces array - integer :: j ! index in region specification - integer :: k ! surface half-space spec - integer :: n ! size of vector - type(VectorInt), allocatable :: neighbor_pos(:) - type(VectorInt), allocatable :: neighbor_neg(:) - - call write_message("Building neighboring cells lists for each surface...", & - 6) - - allocate(neighbor_pos(n_surfaces)) - allocate(neighbor_neg(n_surfaces)) - - do i = 1, n_cells - do j = 1, size(cells(i)%region) - ! Get token from region specification and skip any tokens that - ! correspond to operators rather than regions - k = cells(i)%region(j) - if (abs(k) >= OP_UNION) cycle - - ! Add this cell ID to neighbor list for k-th surface - if (k > 0) then - call neighbor_pos(abs(k))%push_back(i) - else - call neighbor_neg(abs(k))%push_back(i) - end if - end do - end do - - do i = 1, n_surfaces - ! Copy positive neighbors to Surface instance - n = neighbor_pos(i)%size() - if (n > 0) then - allocate(surfaces(i)%neighbor_pos(n)) - surfaces(i)%neighbor_pos(:) = neighbor_pos(i)%data(1:n) - end if - - ! Copy negative neighbors to Surface instance - n = neighbor_neg(i)%size() - if (n > 0) then - allocate(surfaces(i)%neighbor_neg(n)) - surfaces(i)%neighbor_neg(:) = neighbor_neg(i)%data(1:n) - end if - end do - - end subroutine neighbor_lists - end module geometry diff --git a/src/geometry.cpp b/src/geometry.cpp index 85cefb7e2d..87bf0abfda 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -8,6 +8,7 @@ #include "error.h" #include "lattice.h" #include "settings.h" +#include "surface.h" namespace openmc { @@ -50,7 +51,7 @@ check_cell_overlap(Particle* p) { //============================================================================== extern "C" bool -find_cell(Particle* p, int n_search_cells, int* search_cells) { +find_cell(Particle* p, int search_surf) { for (int i = p->n_coord; i < MAX_COORD; i++) { p->coord[i].reset(); } @@ -64,8 +65,18 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { //TODO: off-by-one indexing --i_universe; - // If not given a set of search cells, search all cells in the uninverse. - if (n_search_cells == 0) { + // If a surface was indicated, only search cells from the neighbor list of + // that surface. + int* search_cells; + int n_search_cells; + if (search_surf > 0) { + search_cells = global_surfaces[search_surf-1]->neighbor_pos.data(); + n_search_cells = global_surfaces[search_surf-1]->neighbor_pos.size(); + } else if (search_surf < 0) { + search_cells = global_surfaces[-search_surf-1]->neighbor_neg.data(); + n_search_cells = global_surfaces[-search_surf-1]->neighbor_neg.size(); + } else { + // No surface was indicated, search all cells in the universe. search_cells = global_universes[i_universe]->cells.data(); n_search_cells = global_universes[i_universe]->cells.size(); } @@ -190,7 +201,7 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { // Update the coordinate level and recurse. ++p->n_coord; - find_cell(p, 0, nullptr); + find_cell(p, 0); } else if (c.type == FILL_LATTICE) { //======================================================================== @@ -237,7 +248,7 @@ find_cell(Particle* p, int n_search_cells, int* search_cells) { // Update the coordinate level and recurse. ++p->n_coord; - find_cell(p, 0, nullptr); + find_cell(p, 0); } } @@ -277,7 +288,7 @@ cross_lattice(Particle* p, int lattice_translation[3]) if (!lat.are_valid_indices(i_xyz)) { // The particle is outside the lattice. Search for it from the base coords. p->n_coord = 1; - bool found = find_cell(p, 0, nullptr); + bool found = find_cell(p, 0); if (!found && p->alive) { std::stringstream err_msg; err_msg << "Could not locate particle " << p->id @@ -288,13 +299,13 @@ cross_lattice(Particle* p, int lattice_translation[3]) } else { // Find cell in next lattice element. p->coord[p->n_coord-1].universe = lat[i_xyz] + 1; - bool found = find_cell(p, 0, nullptr); + bool found = find_cell(p, 0); if (!found) { // A particle crossing the corner of a lattice tile may not be found. In // this case, search for it from the base coords. p->n_coord = 1; - bool found = find_cell(p, 0, nullptr); + bool found = find_cell(p, 0); if (!found && p->alive) { std::stringstream err_msg; err_msg << "Could not locate particle " << p->id diff --git a/src/geometry.h b/src/geometry.h index 47162c73e1..9a13ae2209 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -24,7 +24,7 @@ check_cell_overlap(Particle* p); //============================================================================== extern "C" bool -find_cell(Particle* p, int n_search_cells, int* search_cells); +find_cell(Particle* p, int search_surf); //============================================================================== //! Move a particle into a new lattice tile. diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 6d7d5badb5..6ca3b6d3b3 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -11,6 +11,7 @@ #include "lattice.h" #include "material.h" #include "settings.h" +#include "surface.h" namespace openmc { @@ -152,6 +153,33 @@ find_root_universe() //============================================================================== +void +neighbor_lists() +{ + write_message("Building neighboring cells lists for each surface...", 6); + + for (int i = 0; i < global_cells.size(); i++) { + for (auto token : global_cells[i]->region) { + // Skip operator tokens. + if (std::abs(token) >= OP_UNION) continue; + + // This token is a surface index. Add the cell to the surface's list. + if (token > 0) { + global_surfaces[std::abs(token)-1]->neighbor_pos.push_back(i); + } else { + global_surfaces[std::abs(token)-1]->neighbor_neg.push_back(i); + } + } + } + + for (Surface* surf : global_surfaces) { + surf->neighbor_pos.shrink_to_fit(); + surf->neighbor_neg.shrink_to_fit(); + } +} + +//============================================================================== + void prepare_distribcell(int32_t* filter_cell_list, int n) { diff --git a/src/geometry_aux.h b/src/geometry_aux.h index e3fd034c69..3511a84bee 100644 --- a/src/geometry_aux.h +++ b/src/geometry_aux.h @@ -31,6 +31,12 @@ extern "C" void assign_temperatures(); extern "C" int32_t find_root_universe(); +//!============================================================================= +//! Build a list of neighboring cells to each surface to speed up tracking. +//!============================================================================= + +extern "C" void neighbor_lists(); + //============================================================================== //! Populate all data structures needed for distribcells. //============================================================================== diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 23700d8291..0223a63ff8 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -212,9 +212,6 @@ module geometry_header type Universe integer :: id ! Unique ID integer, allocatable :: cells(:) ! List of cells within - real(8) :: x0 ! Translation in x-coordinate - real(8) :: y0 ! Translation in y-coordinate - real(8) :: z0 ! Translation in z-coordinate end type Universe !=============================================================================== @@ -263,9 +260,6 @@ module geometry_header type Cell type(C_PTR) :: ptr - integer, allocatable :: region(:) ! Definition of spatial region as - ! Boolean expression of half-spaces - ! Rotation matrix and translation vector real(8), allocatable :: rotation(:) real(8), allocatable :: rotation_matrix(:,:) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 27b8be9467..bea0ed6379 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -31,7 +31,7 @@ module input_xml use source_header use stl_vector, only: VectorInt, VectorReal, VectorChar use string, only: to_lower, to_str, str_to_int, str_to_real, & - starts_with, ends_with, tokenize, split_string, & + starts_with, ends_with, split_string, & zero_padded, to_c_string use summary, only: write_summary use tally @@ -1002,16 +1002,14 @@ contains subroutine read_geometry_xml() - integer :: i, j, k + integer :: i, j integer :: n, n_rlats, n_hlats - integer :: id integer :: univ_id integer :: n_cells_in_univ real(8) :: phi, theta, psi logical :: file_exists logical :: boundary_exists character(MAX_LINE_LEN) :: filename - character(:), allocatable :: region_spec type(Cell), pointer :: c class(Lattice), pointer :: lat type(XMLDocument) :: doc @@ -1021,7 +1019,6 @@ contains type(XMLNode), allocatable :: node_cell_list(:) type(XMLNode), allocatable :: node_rlat_list(:) type(XMLNode), allocatable :: node_hlat_list(:) - type(VectorInt) :: tokens type(VectorInt) :: univ_ids ! List of all universe IDs type(DictIntInt) :: cells_in_univ_dict ! Used to count how many cells each ! universe contains @@ -1104,43 +1101,6 @@ contains // to_str(c % id())) end if - ! Check for region specification (also under deprecated name surfaces) - if (check_for_node(node_cell, "surfaces")) then - call warning("The use of 'surfaces' is deprecated and will be & - &disallowed in a future release. Use 'region' instead. The & - &openmc-update-inputs utility can be used to automatically & - &update geometry.xml files.") - region_spec = node_value_string(node_cell, "surfaces") - call get_node_value(node_cell, "surfaces", region_spec) - elseif (check_for_node(node_cell, "region")) then - region_spec = node_value_string(node_cell, "region") - else - region_spec = '' - end if - - if (len_trim(region_spec) > 0) then - ! Create surfaces array from string - call tokenize(region_spec, tokens) - - ! Convert user IDs to surface indices - do j = 1, tokens % size() - id = tokens % data(j) - if (id < OP_UNION) then - if (surface_dict % has(abs(id))) then - k = surface_dict % get(abs(id)) - tokens % data(j) = sign(k, id) - end if - end if - end do - - ! Copy region spec and RPN form to cell arrays - allocate(c % region(tokens%size())) - c % region(:) = tokens%data(1:tokens%size()) - - call tokens%clear() - end if - if (.not. allocated(c%region)) allocate(c%region(0)) - ! Rotation matrix if (check_for_node(node_cell, "rotation")) then ! Rotations can only be applied to cells that are being filled with diff --git a/src/string.F90 b/src/string.F90 index 71d9d6e966..90b51d7aa0 100644 --- a/src/string.F90 +++ b/src/string.F90 @@ -64,98 +64,6 @@ contains end subroutine split_string -!=============================================================================== -! TOKENIZE takes a string that includes logical expressions for a list of -! bounding surfaces in a cell and splits it into separate tokens. The characters -! (, ), |, and ~ count as separate tokens since they represent operators. -!=============================================================================== - - subroutine tokenize(string, tokens) - character(*), intent(in) :: string - type(VectorInt), intent(inout) :: tokens - - integer :: i ! current index - integer :: i_start ! starting index of word - integer :: token - character(len=len_trim(string)) :: string_ - - ! Remove leading blanks - string_ = adjustl(string) - - i_start = 0 - i = 1 - do while (i <= len_trim(string_)) - ! Check for special characters - if (index('()|~ ', string_(i:i)) > 0) then - ! If the special character appears immediately after a non-operator, - ! create a token with the surface half-space - if (i_start > 0) then - call tokens%push_back(int(str_to_int(& - string_(i_start:i - 1)), 4)) - end if - - select case (string_(i:i)) - case ('(') - call tokens%push_back(OP_LEFT_PAREN) - case (')') - if (tokens%size() > 0) then - token = tokens%data(tokens%size()) - if (token >= OP_UNION .and. token < OP_RIGHT_PAREN) then - call fatal_error("Right parentheses cannot follow an operator in & - ®ion specification: " // trim(string)) - end if - end if - call tokens%push_back(OP_RIGHT_PAREN) - case ('|') - if (tokens%size() > 0) then - token = tokens%data(tokens%size()) - if (.not. (token < OP_UNION .or. token == OP_RIGHT_PAREN)) then - call fatal_error("Union cannot follow an operator in region & - &specification: " // trim(string)) - end if - end if - call tokens%push_back(OP_UNION) - case ('~') - call tokens%push_back(OP_COMPLEMENT) - case (' ') - ! Find next non-space character - do while (string_(i+1:i+1) == ' ') - i = i + 1 - end do - - ! If previous token is a halfspace or right parenthesis and next token - ! is not a left parenthese or union operator, that implies that the - ! whitespace is to be interpreted as an intersection operator - if (i_start > 0 .or. tokens%data(tokens%size()) == OP_RIGHT_PAREN) then - if (index(')|', string_(i+1:i+1)) == 0) then - call tokens%push_back(OP_INTERSECTION) - end if - end if - end select - - i_start = 0 - else - ! Check for invalid characters - if (index('-+0123456789', string_(i:i)) == 0) then - call fatal_error("Invalid character '" // string_(i:i) // "' in & - ®ion specification.") - end if - - ! If we haven't yet reached the start of a word, start a new word - if (i_start == 0) i_start = i - end if - - i = i + 1 - end do - - ! If we've reached the end and we're still in a word, create a token from it - ! and add it to the list - if (i_start > 0) then - call tokens%push_back(int(str_to_int(& - string_(i_start:len_trim(string_))), 4)) - end if - end subroutine tokenize - !=============================================================================== ! CONCATENATE takes an array of words and concatenates them together in one ! string with a single space between words diff --git a/src/surface.h b/src/surface.h index 746db5c3b5..c9d8648d8d 100644 --- a/src/surface.h +++ b/src/surface.h @@ -58,11 +58,12 @@ class Surface { public: int id; //!< Unique ID - //int neighbor_pos[], //!< List of cells on positive side - // neighbor_neg[]; //!< List of cells on negative side int bc; //!< Boundary condition std::string name; //!< User-defined name + std::vector neighbor_pos; //!< List of cells on positive side + std::vector neighbor_neg; //!< List of cells on negative side + explicit Surface(pugi::xml_node surf_node); virtual ~Surface() {} diff --git a/src/surface_header.F90 b/src/surface_header.F90 index 4a5834ec2c..401ac90aae 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -84,9 +84,6 @@ module surface_header !=============================================================================== type :: Surface - integer, allocatable :: & - neighbor_pos(:), & ! List of cells on positive side - neighbor_neg(:) ! List of cells on negative side type(C_PTR) :: ptr contains diff --git a/src/tracking.F90 b/src/tracking.F90 index dd0c26b433..e9568fe54a 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -467,21 +467,8 @@ contains ! ========================================================================== ! SEARCH NEIGHBOR LISTS FOR NEXT CELL - if (p % surface > 0 .and. allocated(surf%neighbor_pos)) then - ! If coming from negative side of surface, search all the neighboring - ! cells on the positive side - - call find_cell(p, found, surf%neighbor_pos) - if (found) return - - elseif (p % surface < 0 .and. allocated(surf%neighbor_neg)) then - ! If coming from positive side of surface, search all the neighboring - ! cells on the negative side - - call find_cell(p, found, surf%neighbor_neg) - if (found) return - - end if + call find_cell(p, found, p % surface) + if (found) return ! ========================================================================== ! COULDN'T FIND PARTICLE IN NEIGHBORING CELLS, SEARCH ALL CELLS From 909c43b1e4e67e8d6841fb87b583558792b5da29 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 21 Aug 2018 06:25:32 -0500 Subject: [PATCH 24/43] Look for materials.xml in same directory as geometry.xml for from_xml --- openmc/geometry.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 471de202b5..8227b10536 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -1,6 +1,7 @@ from collections import OrderedDict, defaultdict from collections.abc import Iterable from copy import deepcopy +from pathlib import Path from xml.etree import ElementTree as ET import numpy as np @@ -237,7 +238,8 @@ class Geometry(object): # Create dictionary to easily look up materials if materials is None: - materials = openmc.Materials.from_xml() + filename = Path(path).parent / 'materials.xml' + materials = openmc.Materials.from_xml(str(filename)) mats = {str(m.id): m for m in materials} mats['void'] = None From e8b99c0a389c136f1548f7fcaa7e9fcba928fa09 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 21 Aug 2018 06:33:32 -0500 Subject: [PATCH 25/43] Make sure lattice outer universe is added to child_of --- openmc/geometry.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openmc/geometry.py b/openmc/geometry.py index 8227b10536..3a2c18311b 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -167,6 +167,7 @@ class Geometry(object): outer = get(elem, 'outer') if outer is not None: lat.outer = get_universe(int(outer)) + child_of[lat.outer].append(lat) universes[lat_id] = lat # Get array of universes @@ -188,6 +189,7 @@ class Geometry(object): outer = get(elem, 'outer') if outer is not None: lat.outer = get_universe(int(outer)) + child_of[lat.outer].append(lat) universes[lat_id] = lat # Get nested lists of universes From fbf7713a335def236e6a51a74adf2ddd837825f7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 21 Aug 2018 07:47:29 -0500 Subject: [PATCH 26/43] Split up Geometry.from_xml, rename clean_xml -> _xml --- openmc/_xml.py | 51 +++++++++++++++ openmc/cell.py | 59 +++++++++++++++++ openmc/clean_xml.py | 26 -------- openmc/cmfd.py | 4 +- openmc/data/library.py | 4 +- openmc/deplete/chain.py | 4 +- openmc/geometry.py | 138 ++++++---------------------------------- openmc/lattice.py | 109 +++++++++++++++++++++++++++++++ openmc/material.py | 4 +- openmc/plots.py | 4 +- openmc/settings.py | 4 +- openmc/tallies.py | 4 +- 12 files changed, 254 insertions(+), 157 deletions(-) create mode 100644 openmc/_xml.py delete mode 100644 openmc/clean_xml.py diff --git a/openmc/_xml.py b/openmc/_xml.py new file mode 100644 index 0000000000..9c6c219e2f --- /dev/null +++ b/openmc/_xml.py @@ -0,0 +1,51 @@ +def clean_indentation(element, level=0, spaces_per_level=2): + """ + copy and paste from http://effbot.org/zone/elementent-lib.htm#prettyprint + it basically walks your tree and adds spaces and newlines so the tree is + printed in a nice way + """ + + i = "\n" + level*spaces_per_level*" " + + if len(element): + + if not element.text or not element.text.strip(): + element.text = i + spaces_per_level*" " + + if not element.tail or not element.tail.strip(): + element.tail = i + + for sub_element in element: + clean_indentation(sub_element, level+1, spaces_per_level) + + if not sub_element.tail or not sub_element.tail.strip(): + sub_element.tail = i + + else: + if level and (not element.tail or not element.tail.strip()): + element.tail = i + + +def get_text(elem, name, default=None): + """Retrieve text of an attribute or subelement. + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + Element from which to search + name : str + Name of attribute/subelement + default : object + A defult value to return if matching attribute/subelement exists + + Returns + ------- + str + Text of attribute or subelement + + """ + if name in elem.attrib: + return elem.get(name, default) + else: + child = elem.find(name) + return child.text if child is not None else default diff --git a/openmc/cell.py b/openmc/cell.py index cbfd74b21b..492bdeeb68 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -13,6 +13,7 @@ import openmc import openmc.checkvalue as cv from openmc.surface import Halfspace from openmc.region import Region, Intersection, Complement +from openmc._xml import get_text from .mixin import IDManagerMixin @@ -522,3 +523,61 @@ class Cell(IDManagerMixin): element.set("rotation", ' '.join(map(str, self.rotation))) return element + + @classmethod + def from_xml_element(cls, elem, surfaces, materials, get_universe): + """Generate cell from XML element + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + `` element + surfaces : dict + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + materials : dict + Dictionary mapping material IDs to :class:`openmc.Material` + instances (defined in :math:`openmc.Geometry.from_xml`) + get_universe : function + Function returning universe (defined in + :meth:`openmc.Geometry.from_xml`) + + Returns + ------- + Cell + Cell instance + + """ + cell_id = int(get_text(elem, 'id')) + name = get_text(elem, 'name') + c = cls(cell_id, name) + + # Assign material/distributed materials or fill + mat_text = get_text(elem, 'material') + if mat_text is not None: + mat_ids = mat_text.split() + if len(mat_ids) > 1: + c.fill = [materials[i] for i in mat_ids] + else: + c.fill = materials[mat_ids[0]] + else: + fill_id = int(get_text(elem, 'fill')) + c.fill = get_universe(fill_id) + + # Assign region + region = get_text(elem, 'region') + if region is not None: + c.region = Region.from_expression(region, surfaces) + + # Check for other attributes + t = get_text(elem, 'temperature') + if t is not None: + c.temperature = float(t) + for key in ('temperature', 'rotation', 'translation'): + value = get_text(elem, key) + if value is not None: + setattr(c, key, [float(x) for x in value.split()]) + + # Add this cell to appropriate universe + univ_id = int(get_text(elem, 'universe', 0)) + get_universe(univ_id).add_cell(c) + return c diff --git a/openmc/clean_xml.py b/openmc/clean_xml.py deleted file mode 100644 index d1002070b3..0000000000 --- a/openmc/clean_xml.py +++ /dev/null @@ -1,26 +0,0 @@ -def clean_xml_indentation(element, level=0, spaces_per_level=2): - """ - copy and paste from http://effbot.org/zone/elementent-lib.htm#prettyprint - it basically walks your tree and adds spaces and newlines so the tree is - printed in a nice way - """ - - i = "\n" + level*spaces_per_level*" " - - if len(element): - - if not element.text or not element.text.strip(): - element.text = i + spaces_per_level*" " - - if not element.tail or not element.tail.strip(): - element.tail = i - - for sub_element in element: - clean_xml_indentation(sub_element, level+1, spaces_per_level) - - if not sub_element.tail or not sub_element.tail.strip(): - sub_element.tail = i - - else: - if level and (not element.tail or not element.tail.strip()): - element.tail = i diff --git a/openmc/cmfd.py b/openmc/cmfd.py index 5444334b20..c156cd00a3 100644 --- a/openmc/cmfd.py +++ b/openmc/cmfd.py @@ -15,7 +15,7 @@ from numbers import Real, Integral from xml.etree import ElementTree as ET import sys -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation from openmc.checkvalue import (check_type, check_length, check_value, check_greater_than, check_less_than) @@ -512,7 +512,7 @@ class CMFD(object): self._create_write_matrices_subelement() # Clean the indentation in the file to be user-readable - clean_xml_indentation(self._cmfd_file) + clean_indentation(self._cmfd_file) # Write the XML Tree to the cmfd.xml file tree = ET.ElementTree(self._cmfd_file) diff --git a/openmc/data/library.py b/openmc/data/library.py index 58e5e4e16a..8d821e49fd 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -4,7 +4,7 @@ import xml.etree.ElementTree as ET import h5py from openmc.mixin import EqualityMixin -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation from openmc.checkvalue import check_type @@ -95,7 +95,7 @@ class DataLibrary(EqualityMixin): lib_element.set('type', library['type']) # Clean the indentation to be user-readable - clean_xml_indentation(root) + clean_indentation(root) # Write XML file tree = ET.ElementTree(root) diff --git a/openmc/deplete/chain.py b/openmc/deplete/chain.py index 1826ca9ca0..4635d99d15 100644 --- a/openmc/deplete/chain.py +++ b/openmc/deplete/chain.py @@ -23,7 +23,7 @@ except ImportError: import scipy.sparse as sp import openmc.data -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation from .nuclide import Nuclide, DecayTuple, ReactionTuple @@ -356,7 +356,7 @@ class Chain(object): if _have_lxml: tree.write(str(filename), encoding='utf-8', pretty_print=True) else: - clean_xml_indentation(root_elem) + clean_indentation(root_elem) tree.write(str(filename), encoding='utf-8') def form_matrix(self, rates): diff --git a/openmc/geometry.py b/openmc/geometry.py index 3a2c18311b..4cbc60c249 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -7,7 +7,7 @@ from xml.etree import ElementTree as ET import numpy as np import openmc -from openmc.clean_xml import clean_xml_indentation +import openmc._xml as xml from openmc.checkvalue import check_type @@ -95,7 +95,7 @@ class Geometry(object): x.tag, int(x.get('id')))) # Clean the indentation in the file to be user-readable - clean_xml_indentation(root_element) + xml.clean_indentation(root_element) # Write the XML Tree to the geometry.xml file tree = ET.ElementTree(root_element) @@ -119,14 +119,6 @@ class Geometry(object): Geometry object """ - # Helper function to get value from an attribute/element - def get(elem, name, default=None): - if name in elem.attrib: - return elem.get(name, default) - else: - child = elem.find(name) - return child.text if child is not None else default - # Helper function for keeping a cache of Universe instances universes = {} def get_universe(univ_id): @@ -146,7 +138,7 @@ class Geometry(object): surfaces[s.id] = s # Check for periodic surface - other_id = get(surface, 'periodic_surface_id') + other_id = xml.get_text(surface, 'periodic_surface_id') if other_id is not None: periodic[s.id] = int(other_id) @@ -159,84 +151,27 @@ class Geometry(object): child_of = defaultdict(list) for elem in root.findall('lattice'): - lat_id = int(get(elem, 'id')) - name = get(elem, 'name') - lat = openmc.RectLattice(lat_id, name) - lat.lower_left = [float(i) for i in get(elem, 'lower_left').split()] - lat.pitch = [float(i) for i in get(elem, 'pitch').split()] - outer = get(elem, 'outer') - if outer is not None: - lat.outer = get_universe(int(outer)) + lat = openmc.RectLattice.from_xml_element(elem, get_universe) + universes[lat.id] = lat + if lat.outer is not None: child_of[lat.outer].append(lat) - universes[lat_id] = lat - - # Get array of universes - dimension = get(elem, 'dimension').split() - shape = np.array(dimension, dtype=int)[::-1] - uarray = np.array([get_universe(int(i)) for i in - get(elem, 'universes').split()]) - for u in uarray: + for u in lat.universes.ravel(): child_of[u].append(lat) - uarray.shape = shape - lat.universes = uarray for elem in root.findall('hex_lattice'): - lat_id = int(get(elem, 'id')) - name = get(elem, 'name') - lat = openmc.HexLattice(lat_id, name) - lat.center = [float(i) for i in get(elem, 'center').split()] - lat.pitch = [float(i) for i in get(elem, 'pitch').split()] - outer = get(elem, 'outer') - if outer is not None: - lat.outer = get_universe(int(outer)) + lat = openmc.HexLattice.from_xml_element(elem, get_universe) + universes[lat.id] = lat + if lat.outer is not None: child_of[lat.outer].append(lat) - universes[lat_id] = lat - - # Get nested lists of universes - lat._num_rings = n_rings = int(get(elem, 'n_rings')) - lat._num_axial = n_axial = int(get(elem, 'n_axial', 1)) - - # Create empty nested lists for one axial level - univs = [[None for _ in range(max(6*(n_rings - 1 - r), 1))] - for r in range(n_rings)] - if n_axial > 1: - univs = [deepcopy(univs) for i in range(n_axial)] - - # Get flat array of universes numbers - uarray = np.array([get_universe(int(i)) for i in - get(elem, 'universes').split()]) - for u in uarray: - child_of[u].append(lat) - - # Fill nested lists - j = 0 - for z in range(n_axial): - # Get list for a single axial level - axial_level = univs[z] if n_axial > 1 else univs - - # Start iterating from top - x, alpha = 0, n_rings - 1 - while True: - # Set entry in list based on (x,alpha,z) coordinates - _, i_ring, i_within = lat.get_universe_index((x, alpha, z)) - axial_level[i_ring][i_within] = uarray[j] - - # Move to the right - x += 2 - alpha -= 1 - if not lat.is_valid_index((x, alpha, z)): - # Move down in y direction - alpha += x - 1 - x = 1 - x - if not lat.is_valid_index((x, alpha, z)): - # Move to the right - x += 2 - alpha -= 1 - if not lat.is_valid_index((x, alpha, z)): - # Reached the bottom - break - j += 1 - lat.universes = univs + if lat.ndim == 2: + for ring in lat.universes: + for u in ring: + child_of[u].append(lat) + else: + for axial_slice in lat.universes: + for ring in axial_slice: + for u in ring: + child_of[u].append(lat) # Create dictionary to easily look up materials if materials is None: @@ -246,41 +181,10 @@ class Geometry(object): mats['void'] = None for elem in root.findall('cell'): - cell_id = int(get(elem, 'id')) - name = get(elem, 'name') - c = openmc.Cell(cell_id, name) - - # Assign material/distributed materials or fill - mat_text = get(elem, 'material') - if mat_text is not None: - mat_ids = mat_text.split() - if len(mat_ids) > 1: - c.fill = [mats[i] for i in mat_ids] - else: - c.fill = mats[mat_ids[0]] - else: - fill_id = int(get(elem, 'fill')) - c.fill = get_universe(fill_id) + c = openmc.Cell.from_xml_element(elem, surfaces, mats, get_universe) + if c.fill_type in ('universe', 'lattice'): child_of[c.fill].append(c) - # Assign region - region = get(elem, 'region') - if region is not None: - c.region = openmc.Region.from_expression(region, surfaces) - - # Check for other attributes - t = get(elem, 'temperature') - if t is not None: - c.temperature = float(t) - for key in ('temperature', 'rotation', 'translation'): - value = get(elem, key) - if value is not None: - setattr(c, key, [float(x) for x in value.split()]) - - # Add this cell to appropriate universe - univ_id = int(get(elem, 'universe', 0)) - get_universe(univ_id).add_cell(c) - # Determine which universe is the root by finding one which is not a # child of any other object for u in universes.values(): diff --git a/openmc/lattice.py b/openmc/lattice.py index ef33247fca..8bf4e47571 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -10,6 +10,7 @@ import numpy as np import openmc.checkvalue as cv import openmc +from openmc._xml import get_text from openmc.mixin import IDManagerMixin @@ -768,6 +769,42 @@ class RectLattice(Lattice): # Append the XML subelement for this Lattice to the XML element xml_element.append(lattice_subelement) + @classmethod + def from_xml_element(cls, elem, get_universe): + """Generate rectangular lattice from XML element + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + `` element + get_universe : function + Function returning universe (defined in + :meth:`openmc.Geometry.from_xml`) + + Returns + ------- + RectLattice + Rectangular lattice + + """ + lat_id = int(get_text(elem, 'id')) + name = get_text(elem, 'name') + lat = cls(lat_id, name) + lat.lower_left = [float(i) for i in get_text(elem, 'lower_left').split()] + lat.pitch = [float(i) for i in get_text(elem, 'pitch').split()] + outer = get_text(elem, 'outer') + if outer is not None: + lat.outer = get_universe(int(outer)) + + # Get array of universes + dimension = get_text(elem, 'dimension').split() + shape = np.array(dimension, dtype=int)[::-1] + uarray = np.array([get_universe(int(i)) for i in + get_text(elem, 'universes').split()]) + uarray.shape = shape + lat.universes = uarray + return lat + class HexLattice(Lattice): r"""A lattice consisting of hexagonal prisms. @@ -1207,6 +1244,78 @@ class HexLattice(Lattice): # Append the XML subelement for this Lattice to the XML element xml_element.append(lattice_subelement) + @classmethod + def from_xml_element(cls, elem, get_universe): + """Generate hexagonal lattice from XML element + + Parameters + ---------- + elem : xml.etree.ElementTree.Element + `` element + get_universe : function + Function returning universe (defined in + :meth:`openmc.Geometry.from_xml`) + + Returns + ------- + HexLattice + Hexagonal lattice + + """ + lat_id = int(get_text(elem, 'id')) + name = get_text(elem, 'name') + lat = cls(lat_id, name) + lat.center = [float(i) for i in get_text(elem, 'center').split()] + lat.pitch = [float(i) for i in get_text(elem, 'pitch').split()] + outer = get_text(elem, 'outer') + if outer is not None: + lat.outer = get_universe(int(outer)) + + # Get nested lists of universes + lat._num_rings = n_rings = int(get_text(elem, 'n_rings')) + lat._num_axial = n_axial = int(get_text(elem, 'n_axial', 1)) + + # Create empty nested lists for one axial level + univs = [[None for _ in range(max(6*(n_rings - 1 - r), 1))] + for r in range(n_rings)] + if n_axial > 1: + univs = [deepcopy(univs) for i in range(n_axial)] + + # Get flat array of universes numbers + uarray = np.array([get_universe(int(i)) for i in + get_text(elem, 'universes').split()]) + + # Fill nested lists + j = 0 + for z in range(n_axial): + # Get list for a single axial level + axial_level = univs[z] if n_axial > 1 else univs + + # Start iterating from top + x, alpha = 0, n_rings - 1 + while True: + # Set entry in list based on (x,alpha,z) coordinates + _, i_ring, i_within = lat.get_universe_index((x, alpha, z)) + axial_level[i_ring][i_within] = uarray[j] + + # Move to the right + x += 2 + alpha -= 1 + if not lat.is_valid_index((x, alpha, z)): + # Move down in y direction + alpha += x - 1 + x = 1 - x + if not lat.is_valid_index((x, alpha, z)): + # Move to the right + x += 2 + alpha -= 1 + if not lat.is_valid_index((x, alpha, z)): + # Reached the bottom + break + j += 1 + lat.universes = univs + return lat + def _repr_axial_slice(self, universes): """Return string representation for the given 2D group of universes. diff --git a/openmc/material.py b/openmc/material.py index d19a5f4b99..4ba4f03063 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -9,7 +9,7 @@ import numpy as np import openmc import openmc.data import openmc.checkvalue as cv -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation from .mixin import IDManagerMixin @@ -1076,7 +1076,7 @@ class Materials(cv.CheckedList): self._create_material_subelements(root_element) # Clean the indentation in the file to be user-readable - clean_xml_indentation(root_element) + clean_indentation(root_element) # Write the XML Tree to the materials.xml file tree = ET.ElementTree(root_element) diff --git a/openmc/plots.py b/openmc/plots.py index 8eff78b1d9..f99392def9 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -9,7 +9,7 @@ import numpy as np import openmc import openmc.checkvalue as cv -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation from openmc.mixin import IDManagerMixin @@ -816,7 +816,7 @@ class Plots(cv.CheckedList): self._create_plot_subelements() # Clean the indentation in the file to be user-readable - clean_xml_indentation(self._plots_file) + clean_indentation(self._plots_file) # Write the XML Tree to the plots.xml file tree = ET.ElementTree(self._plots_file) diff --git a/openmc/settings.py b/openmc/settings.py index 7629ea9afc..efe41b2a1b 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -6,7 +6,7 @@ import sys import numpy as np -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation import openmc.checkvalue as cv from openmc import VolumeCalculation, Source, Mesh @@ -994,7 +994,7 @@ class Settings(object): self._create_log_grid_bins_subelement(root_element) # Clean the indentation in the file to be user-readable - clean_xml_indentation(root_element) + clean_indentation(root_element) # Write the XML Tree to the settings.xml file tree = ET.ElementTree(root_element) diff --git a/openmc/tallies.py b/openmc/tallies.py index 74f3429034..1e4b142fe1 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -15,7 +15,7 @@ import h5py import openmc import openmc.checkvalue as cv -from openmc.clean_xml import clean_xml_indentation +from openmc._xml import clean_indentation from .mixin import IDManagerMixin @@ -3187,7 +3187,7 @@ class Tallies(cv.CheckedList): self._create_derivative_subelements(root_element) # Clean the indentation in the file to be user-readable - clean_xml_indentation(root_element) + clean_indentation(root_element) # Write the XML Tree to the tallies.xml file tree = ET.ElementTree(root_element) From 8bb17a481ea02cde00f657109c74e526195f4252 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 21 Aug 2018 11:02:14 -0400 Subject: [PATCH 27/43] Move distance_to_boundary to C++ --- src/cell.cpp | 12 ---- src/geometry.F90 | 127 ++++------------------------------------ src/geometry.cpp | 99 +++++++++++++++++++++++++++++++ src/geometry.h | 8 +++ src/geometry_header.F90 | 57 ------------------ src/lattice.cpp | 16 ++--- src/lattice.h | 12 ++++ 7 files changed, 133 insertions(+), 198 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index c22813ea71..a3a5d9fde4 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -692,18 +692,6 @@ extern "C" { double cell_sqrtkT(Cell* c, int i) {return c->sqrtkT[i];} - bool cell_simple(Cell* c) {return c->simple;} - - void cell_distance(Cell* c, double xyz[3], double uvw[3], int32_t on_surface, - double* min_dist, int32_t* i_surf) - { - Position r {xyz}; - Direction u {uvw}; - std::pair out = c->distance(r, u, on_surface); - *min_dist = out.first; - *i_surf = out.second; - } - int32_t cell_offset(Cell* c, int map) {return c->offset[map];} void cell_to_hdf5(Cell* c, hid_t group) {c->to_hdf5(group);} diff --git a/src/geometry.F90 b/src/geometry.F90 index dcd44360be..b5dee81fa2 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -43,6 +43,16 @@ module geometry integer(C_INT), intent(in) :: lattice_translation(3) end subroutine cross_lattice + subroutine distance_to_boundary(p, dist, surface_crossed, & + lattice_translation, next_level) bind(C) + import Particle, C_DOUBLE, C_INT + type(Particle), intent(inout) :: p + real(C_DOUBLE), intent(out) :: dist + integer(C_INT), intent(out) :: surface_crossed + integer(C_INT), intent(out) :: lattice_translation(3) + integer(C_INT), intent(out) :: next_level + end subroutine distance_to_boundary + subroutine neighbor_lists() bind(C) end subroutine neighbor_lists end interface @@ -68,121 +78,4 @@ contains end subroutine find_cell -!=============================================================================== -! DISTANCE_TO_BOUNDARY calculates the distance to the nearest boundary for a -! particle 'p' traveling in a certain direction. For a cell in a subuniverse -! that has a parent cell, also include the surfaces of the edge of the universe. -!=============================================================================== - - subroutine distance_to_boundary(p, dist, surface_crossed, lattice_translation, & - next_level) - type(Particle), intent(inout) :: p - real(8), intent(out) :: dist - integer, intent(out) :: surface_crossed - integer, intent(out) :: lattice_translation(3) - integer, intent(out) :: next_level - - integer :: j - integer :: i_xyz(3) ! lattice indices - integer :: level_surf_cross ! surface crossed on current level - integer :: level_lat_trans(3) ! lattice translation on current level - real(8) :: xyz_t(3) ! local particle coordinates - real(8) :: d_lat ! distance to lattice boundary - real(8) :: d_surf ! distance to surface - real(8) :: xyz_cross(3) ! coordinates at projected surface crossing - real(8) :: surf_uvw(3) ! surface normal direction - type(Cell), pointer :: c - class(Lattice), pointer :: lat - - ! inialize distance to infinity (huge) - dist = INFINITY - d_lat = INFINITY - d_surf = INFINITY - lattice_translation(:) = [0, 0, 0] - - next_level = 0 - - ! Loop over each universe level - LEVEL_LOOP: do j = 1, p % n_coord - - ! get pointer to cell on this level - c => cells(p % coord(j) % cell) - - ! ======================================================================= - ! FIND MINIMUM DISTANCE TO SURFACE IN THIS CELL - - call c % distance(p % coord(j) % xyz, p % coord(j) % uvw, p % surface, & - d_surf, level_surf_cross) - - ! ======================================================================= - ! FIND MINIMUM DISTANCE TO LATTICE SURFACES - - LAT_COORD: if (p % coord(j) % lattice /= NONE) then - lat => lattices(p % coord(j) % lattice) % obj - - i_xyz(1) = p % coord(j) % lattice_x - i_xyz(2) = p % coord(j) % lattice_y - i_xyz(3) = p % coord(j) % lattice_z - - LAT_TYPE: select type(lat) - - type is (RectLattice) - call lat % distance(p % coord(j) % xyz, p % coord(j) % uvw, & - i_xyz, d_lat, level_lat_trans) - - type is (HexLattice) LAT_TYPE - xyz_t(1) = p % coord(j-1) % xyz(1) - xyz_t(2) = p % coord(j-1) % xyz(2) - xyz_t(3) = p % coord(j) % xyz(3) - call lat % distance(xyz_t, p % coord(j) % uvw, & - i_xyz, d_lat, level_lat_trans) - end select LAT_TYPE - - if (d_lat < ZERO) then - call particle_mark_as_lost(p, "Particle " // trim(to_str(p % id)) & - //" had a negative distance to a lattice boundary. d = " & - //trim(to_str(d_lat))) - end if - end if LAT_COORD - - ! If the boundary on this lattice level is coincident with a boundary on - ! a higher level then we need to make sure that the higher level boundary - ! is selected. This logic must include consideration of floating point - ! precision. - if (d_surf < d_lat) then - if ((dist - d_surf)/dist >= FP_REL_PRECISION) then - dist = d_surf - - ! If the cell is not simple, it is possible that both the negative and - ! positive half-space were given in the region specification. Thus, we - ! have to explicitly check which half-space the particle would be - ! traveling into if the surface is crossed - if (.not. c % simple()) then - xyz_cross(:) = p % coord(j) % xyz + d_surf*p % coord(j) % uvw - call surfaces(abs(level_surf_cross)) % normal(xyz_cross, surf_uvw) - if (dot_product(p % coord(j) % uvw, surf_uvw) > ZERO) then - surface_crossed = abs(level_surf_cross) - else - surface_crossed = -abs(level_surf_cross) - end if - else - surface_crossed = level_surf_cross - end if - - lattice_translation(:) = [0, 0, 0] - next_level = j - end if - else - if ((dist - d_lat)/dist >= FP_REL_PRECISION) then - dist = d_lat - surface_crossed = NONE - lattice_translation(:) = level_lat_trans - next_level = j - end if - end if - - end do LEVEL_LOOP - - end subroutine distance_to_boundary - end module geometry diff --git a/src/geometry.cpp b/src/geometry.cpp index 87bf0abfda..e7cbdd8046 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -15,6 +15,8 @@ namespace openmc { std::vector overlap_check_count; +constexpr int F90_NONE {0}; //TODO: replace usage of this with C_NONE + //============================================================================== extern "C" bool @@ -316,4 +318,101 @@ cross_lattice(Particle* p, int lattice_translation[3]) } } +//============================================================================== + +extern "C" void +distance_to_boundary(Particle* p, double* dist, int* surface_crossed, + int lattice_translation[3], int* next_level) +{ + *dist = INFINITY; + double d_lat = INFINITY; + double d_surf = INFINITY; + lattice_translation[0] = 0; + lattice_translation[1] = 0; + lattice_translation[2] = 0; + int32_t level_surf_cross; + std::array level_lat_trans; + + // Loop over each coordinate level. + for (int i = 0; i < p->n_coord; i++) { + Position r {p->coord[i].xyz}; + Direction u {p->coord[i].uvw}; + Cell& c {*global_cells[p->coord[i].cell-1]}; + + // Find the oncoming surface in this cell and the distance to it. + auto surface_distance = c.distance(r, u, p->surface); + d_surf = surface_distance.first; + level_surf_cross = surface_distance.second; + + // Find the distance to the next lattice tile crossing. + if (p->coord[i].lattice != F90_NONE) { + Lattice& lat {*lattices_c[p->coord[i].lattice-1]}; + std::array i_xyz {p->coord[i].lattice_x, p->coord[i].lattice_y, + p->coord[i].lattice_z}; + //TODO: refactor so both lattice use the same position argument (which + //also means the lat.type attribute can be removed) + std::pair> lattice_distance; + switch (lat.type) { + case LatticeType::rect: + lattice_distance = lat.distance(r, u, i_xyz); + break; + case LatticeType::hex: + Position r_hex {p->coord[i-1].xyz[0], p->coord[i-1].xyz[1], + p->coord[i].xyz[2]}; + lattice_distance = lat.distance(r_hex, u, i_xyz); + break; + } + d_lat = lattice_distance.first; + level_lat_trans = lattice_distance.second; + + if (d_lat < 0) { + std::stringstream err_msg; + err_msg << "Particle " << p->id + << " had a negative distance to a lattice boundary"; + p->mark_as_lost(err_msg); + } + } + + // If the boundary on this coordinate level is coincident with a boundary on + // a higher level then we need to make sure that the higher level boundary + // is selected. This logic must consider floating point precision. + if (d_surf < d_lat) { + if (*dist == INFINITY || ((*dist) - d_surf)/(*dist) >= FP_REL_PRECISION) { + *dist = d_surf; + + // If the cell is not simple, it is possible that both the negative and + // positive half-space were given in the region specification. Thus, we + // have to explicitly check which half-space the particle would be + // traveling into if the surface is crossed + if (c.simple) { + *surface_crossed = level_surf_cross; + } else { + Position r_hit = r + d_surf * u; + Surface& surf {*global_surfaces[std::abs(level_surf_cross)-1]}; + Direction norm = surf.normal(r_hit); + if (u.dot(norm) > 0) { + *surface_crossed = std::abs(level_surf_cross); + } else { + *surface_crossed = -std::abs(level_surf_cross); + } + } + + lattice_translation[0] = 0; + lattice_translation[1] = 0; + lattice_translation[2] = 0; + *next_level = i + 1; + } + } else { + if (*dist == INFINITY || ((*dist) - d_lat)/(*dist) >= FP_REL_PRECISION) { + *dist = d_lat; + *surface_crossed = F90_NONE; + lattice_translation[0] = level_lat_trans[0]; + lattice_translation[1] = level_lat_trans[1]; + lattice_translation[2] = level_lat_trans[2]; + *next_level = i + 1; + } + } + } +} + } // namespace openmc diff --git a/src/geometry.h b/src/geometry.h index 9a13ae2209..742818579b 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -33,6 +33,14 @@ find_cell(Particle* p, int search_surf); extern "C" void cross_lattice(Particle* p, int lattice_translation[3]); +//============================================================================== +//! Find the next boundary a particle will intersect. +//============================================================================== + +extern "C" void +distance_to_boundary(Particle* p, double* dist, int* surface_crossed, + int lattice_translation[3], int* next_level); + } // namespace openmc #endif // OPENMC_GEOMETRY_H diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 0223a63ff8..504534d302 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -97,23 +97,6 @@ module geometry_header real(C_DOUBLE) :: sqrtkT end function cell_sqrtkT_c - function cell_simple_c(cell_ptr) bind(C, name='cell_simple') result(simple) - import C_PTR, C_BOOL - type(C_PTR), intent(in), value :: cell_ptr - logical(C_BOOL) :: simple - end function cell_simple_c - - subroutine cell_distance_c(cell_ptr, xyz, uvw, on_surface, min_dist, & - i_surf) bind(C, name="cell_distance") - import C_PTR, C_INT32_T, C_DOUBLE - type(C_PTR), intent(in), value :: cell_ptr - real(C_DOUBLE), intent(in) :: xyz(3) - real(C_DOUBLE), intent(in) :: uvw(3) - integer(C_INT32_T), intent(in), value :: on_surface - real(C_DOUBLE), intent(out) :: min_dist - integer(C_INT32_T), intent(out) :: i_surf - end subroutine cell_distance_c - function cell_offset_c(cell_ptr, map) bind(C, name="cell_offset") & result(offset) import C_PTR, C_INT, C_INT32_T @@ -148,17 +131,6 @@ module geometry_header logical(C_BOOL) :: is_valid end function lattice_are_valid_indices_c - subroutine lattice_distance_c(lat_ptr, xyz, uvw, i_xyz, d, lattice_trans) & - bind(C, name='lattice_distance') - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), intent(in), value :: lat_ptr - real(C_DOUBLE), intent(in) :: xyz(3) - real(C_DOUBLE), intent(in) :: uvw(3) - integer(C_INT), intent(in) :: i_xyz(3) - real(C_DOUBLE), intent(out) :: d - integer(C_INT), intent(out) :: lattice_trans(3) - end subroutine lattice_distance_c - subroutine lattice_get_indices_c(lat_ptr, xyz, i_xyz) & bind(C, name='lattice_get_indices') import C_PTR, C_INT, C_DOUBLE @@ -223,7 +195,6 @@ module geometry_header contains procedure :: id => lattice_id procedure :: are_valid_indices => lattice_are_valid_indices - procedure :: distance => lattice_distance procedure :: get => lattice_get procedure :: get_indices => lattice_get_indices procedure :: get_local_xyz => lattice_get_local_xyz @@ -277,8 +248,6 @@ module geometry_header procedure :: material => cell_material procedure :: sqrtkT_size => cell_sqrtkT_size procedure :: sqrtkT => cell_sqrtkT - procedure :: simple => cell_simple - procedure :: distance => cell_distance procedure :: offset => cell_offset procedure :: to_hdf5 => cell_to_hdf5 @@ -314,16 +283,6 @@ contains is_valid = lattice_are_valid_indices_c(this % ptr, i_xyz) end function lattice_are_valid_indices - subroutine lattice_distance(this, xyz, uvw, i_xyz, d, lattice_trans) - class(Lattice), intent(in) :: this - real(C_DOUBLE), intent(in) :: xyz(3) - real(C_DOUBLE), intent(in) :: uvw(3) - integer(C_INT), intent(in) :: i_xyz(3) - real(C_DOUBLE), intent(out) :: d - integer(C_INT), intent(out) :: lattice_trans(3) - call lattice_distance_c(this % ptr, xyz, uvw, i_xyz, d, lattice_trans) - end subroutine lattice_distance - function lattice_get(this, i_xyz) result(univ) class(Lattice), intent(in) :: this integer(C_INT), intent(in) :: i_xyz(3) @@ -431,22 +390,6 @@ contains sqrtkT = cell_sqrtkT_c(this % ptr, i) end function cell_sqrtkT - function cell_simple(this) result(simple) - class(Cell), intent(in) :: this - logical(C_BOOL) :: simple - simple = cell_simple_c(this % ptr) - end function cell_simple - - subroutine cell_distance(this, xyz, uvw, on_surface, min_dist, i_surf) - class(Cell), intent(in) :: this - real(C_DOUBLE), intent(in) :: xyz(3) - real(C_DOUBLE), intent(in) :: uvw(3) - integer(C_INT32_T), intent(in) :: on_surface - real(C_DOUBLE), intent(out) :: min_dist - integer(C_INT32_T), intent(out) :: i_surf - call cell_distance_c(this % ptr, xyz, uvw, on_surface, min_dist, i_surf) - end subroutine cell_distance - function cell_offset(this, map) result(offset) class(Cell), intent(in) :: this integer(C_INT), intent(in) :: map diff --git a/src/lattice.cpp b/src/lattice.cpp index 8797d0fbac..46f88e3519 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -137,6 +137,8 @@ Lattice::to_hdf5(hid_t lattices_group) const RectLattice::RectLattice(pugi::xml_node lat_node) : Lattice {lat_node} { + type = LatticeType::rect; + // Read the number of lattice cells in each dimension. std::string dimension_str {get_node_value(lat_node, "dimension")}; std::vector dimension_words {split(dimension_str)}; @@ -399,6 +401,8 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const HexLattice::HexLattice(pugi::xml_node lat_node) : Lattice {lat_node} { + type = LatticeType::hex; + // Read the number of lattice cells in each dimension. n_rings = std::stoi(get_node_value(lat_node, "n_rings")); if (check_for_node(lat_node, "n_axial")) { @@ -889,18 +893,6 @@ extern "C" { bool lattice_are_valid_indices(Lattice *lat, const int i_xyz[3]) {return lat->are_valid_indices(i_xyz);} - void lattice_distance(Lattice *lat, const double xyz[3], const double uvw[3], - const int i_xyz[3], double *d, int lattice_trans[3]) - { - Position r {xyz}; - Direction u {uvw}; - std::pair> ld {lat->distance(r, u, i_xyz)}; - *d = ld.first; - lattice_trans[0] = ld.second[0]; - lattice_trans[1] = ld.second[1]; - lattice_trans[2] = ld.second[2]; - } - void lattice_get_indices(Lattice *lat, const double xyz[3], int i_xyz[3]) { Position r {xyz}; diff --git a/src/lattice.h b/src/lattice.h index df7c699d8c..758acfa829 100644 --- a/src/lattice.h +++ b/src/lattice.h @@ -22,6 +22,10 @@ namespace openmc { constexpr int32_t NO_OUTER_UNIVERSE{-1}; +enum class LatticeType { + rect, hex +}; + //============================================================================== // Global variables //============================================================================== @@ -44,6 +48,7 @@ class Lattice public: int32_t id; //!< Universe ID number std::string name; //!< User-defined name + LatticeType type; std::vector universes; //!< Universes filling each lattice tile int32_t outer {NO_OUTER_UNIVERSE}; //!< Universe tiled outside the lattice std::vector offsets; //!< Distribcell offset table @@ -100,6 +105,13 @@ public: distance(Position r, Direction u, const int i_xyz[3]) const = 0; + std::pair> + distance(Position r, Direction u, std::array i_xyz) const + { + int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; + return distance(r, u, i_xyz_); + } + //! \brief Find the lattice tile indices for a given point. //! \param r A 3D Cartesian coordinate. //! \return An array containing the indices of a lattice tile. From 041e3e7cbb5bf74ebb60d319cbc5a9f07111b3bd Mon Sep 17 00:00:00 2001 From: Zhuoran Han Date: Thu, 23 Aug 2018 11:01:37 -0500 Subject: [PATCH 28/43] Check hash value for equality --- openmc/filter_expansion.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openmc/filter_expansion.py b/openmc/filter_expansion.py index 7debebd6b9..67a9117a9a 100644 --- a/openmc/filter_expansion.py +++ b/openmc/filter_expansion.py @@ -19,7 +19,7 @@ class ExpansionFilter(Filter): if type(self) is not type(other): return False else: - return self.bins == other.bins + return hash(self) == hash(other) @property def order(self): @@ -390,6 +390,9 @@ class ZernikeFilter(ExpansionFilter): def __hash__(self): string = type(self).__name__ + '\n' string += '{: <16}=\t{}\n'.format('\tOrder', self.order) + string += '{: <16}=\t{}\n'.format('\tX', self.x) + string += '{: <16}=\t{}\n'.format('\tY', self.y) + string += '{: <16}=\t{}\n'.format('\tR', self.r) return hash(string) def __repr__(self): From 0cf903cc67af4267a8216535fc2fa6a61f4341a1 Mon Sep 17 00:00:00 2001 From: liangjg Date: Thu, 23 Aug 2018 09:10:21 -0700 Subject: [PATCH 29/43] update nuclear-data.ipynb --- examples/jupyter/nuclear-data.ipynb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/jupyter/nuclear-data.ipynb b/examples/jupyter/nuclear-data.ipynb index 7087681a04..726de6f3e2 100644 --- a/examples/jupyter/nuclear-data.ipynb +++ b/examples/jupyter/nuclear-data.ipynb @@ -1466,7 +1466,7 @@ }, "outputs": [], "source": [ - "url = 'https://anl.box.com/shared/static/ulhcoohm12gduwdalknmf8dpnepzkxj0.h5'\n", + "url = 'https://github.com/mit-crpg/WMP_Library/releases/download/v1.0/092238.h5'\n", "filename, headers = urllib.request.urlretrieve(url, '092238.h5')" ] }, @@ -1485,7 +1485,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The `WindowedMultipole` object can be called with energy and temperature values. Calling the object gives a tuple of 3 cross sections: total, radiative capture, and fission." + "The `WindowedMultipole` object can be called with energy and temperature values. Calling the object gives a tuple of 3 cross sections: elastic scattering, radiative capture, and fission." ] }, { @@ -1498,9 +1498,7 @@ { "data": { "text/plain": [ - "(array(9.638243132516015),\n", - " array(0.5053244245010787),\n", - " array(2.931753364280356e-06))" + "(array(9.13284265), array(0.50530278), array(2.9316765e-06))" ] }, "execution_count": 43, From be075618d995d1b2cbd643cba5c7e7f4e85b23e6 Mon Sep 17 00:00:00 2001 From: Zhuoran Han Date: Thu, 23 Aug 2018 11:50:12 -0500 Subject: [PATCH 30/43] Fix code style --- openmc/filter_expansion.py | 8 ++++---- openmc/polynomial.py | 10 +++++++--- tests/unit_tests/test_polynomials.py | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/openmc/filter_expansion.py b/openmc/filter_expansion.py index 67a9117a9a..59457b6857 100644 --- a/openmc/filter_expansion.py +++ b/openmc/filter_expansion.py @@ -325,8 +325,8 @@ class ZernikeFilter(ExpansionFilter): This filter allows scores to be multiplied by Zernike polynomials of the particle's position normalized to a given unit circle, up to a - user-specified order. The standard Zernike polynomials follow the definition by - Born and Wolf, *Principles of Optics* and are defined as + user-specified order. The standard Zernike polynomials follow the + definition by Born and Wolf, *Principles of Optics* and are defined as .. math:: Z_n^m(\rho, \theta) = R_n^m(\rho) \cos (m\theta), \quad m > 0 @@ -342,7 +342,7 @@ class ZernikeFilter(ExpansionFilter): \frac{n+m}{2} - k)! (\frac{n-m}{2} - k)!} \rho^{n-2k}. With this definition, the integral of :math:`(Z_n^m)^2` over the unit disk - is :math:`\frac{\epsilon_m\pi}{2n+2}` for each polynomial where + is :math:`\frac{\epsilon_m\pi}{2n+2}` for each polynomial where :math:`\epsilon_m` is 2 if :math:`m` equals 0 and 1 otherwise. Specifying a filter with order N tallies moments for all :math:`n` from 0 @@ -488,7 +488,7 @@ class ZernikeRadialFilter(ZernikeFilter): is :math:`\frac{\pi}{n+1}`. If there is only radial dependency, the polynomials are integrated over - the azimuthal angles. The only terms left are :math:`Z_n^{0}(\rho, \theta) + the azimuthal angles. The only terms left are :math:`Z_n^{0}(\rho, \theta) = R_n^{0}(\rho)`. Note that :math:`n` could only be even orders. Therefore, for a radial Zernike polynomials up to order of :math:`n`, there are :math:`\frac{n}{2} + 1` terms in total. The indexing is from the diff --git a/openmc/polynomial.py b/openmc/polynomial.py index b120659976..3552819f6b 100644 --- a/openmc/polynomial.py +++ b/openmc/polynomial.py @@ -1,9 +1,10 @@ import numpy as np import openmc import openmc.capi as capi +from collections import Iterable -def legendre_from_expcoef(coef, domain= (-1,1)): +def legendre_from_expcoef(coef, domain=(-1, 1)): """Return a Legendre series object based on expansion coefficients. Given a list of coefficients from FET tally and a array of down, return @@ -73,5 +74,8 @@ class ZernikeRadial(Polynomial): return self._order def __call__(self, r): - zn_rad = capi.calc_zn_rad(self.order, r) - return np.sum(self._norm_coef * zn_rad) + if isinstance(r, Iterable): + return [np.sum(self._norm_coef * capi.calc_zn_rad(self.order, r_i)) + for r_i in r] + else: + return np.sum(self._norm_coef * capi.calc_zn_rad(self.order, r)) diff --git a/tests/unit_tests/test_polynomials.py b/tests/unit_tests/test_polynomials.py index 52c30bb000..82b400b3b8 100644 --- a/tests/unit_tests/test_polynomials.py +++ b/tests/unit_tests/test_polynomials.py @@ -27,3 +27,21 @@ def test_zernike_radial(): test_vals = zn_rad(rho) assert ref_vals == test_vals + + rho = [0.2, 0.5] + # Reference solution from running the Fortran implementation + raw_zn1 = np.array([ + 1.00000000e+00, -9.20000000e-01, 7.69600000e-01, + -5.66720000e-01, 3.35219200e-01, -1.01747000e-01]) + raw_zn2 = np.array([ + 1.00000000e+00, -5.00000000e-01, -1.25000000e-01, + 4.37500000e-01, -2.89062500e-01, -8.98437500e-02]) + + ref_vals = [np.sum(norm_coeff * raw_zn1), np.sum(norm_coeff * raw_zn2)] + + test_vals = zn_rad(rho) + + print(ref_vals) + print(test_vals) + + assert np.allclose(ref_vals, test_vals) From 57674ce33b4bb5c3c597a5567d4be624e0d04793 Mon Sep 17 00:00:00 2001 From: Zhuoran Han Date: Thu, 23 Aug 2018 12:12:04 -0500 Subject: [PATCH 31/43] Delete leftovers --- tests/unit_tests/test_polynomials.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/unit_tests/test_polynomials.py b/tests/unit_tests/test_polynomials.py index 82b400b3b8..f6ac2711fd 100644 --- a/tests/unit_tests/test_polynomials.py +++ b/tests/unit_tests/test_polynomials.py @@ -41,7 +41,4 @@ def test_zernike_radial(): test_vals = zn_rad(rho) - print(ref_vals) - print(test_vals) - assert np.allclose(ref_vals, test_vals) From d4a6e8d827afe5b110747702e7808b296439f2c6 Mon Sep 17 00:00:00 2001 From: Zhuoran Han Date: Thu, 23 Aug 2018 15:33:19 -0500 Subject: [PATCH 32/43] Update --- openmc/polynomial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/polynomial.py b/openmc/polynomial.py index 3552819f6b..8bcb74f68a 100644 --- a/openmc/polynomial.py +++ b/openmc/polynomial.py @@ -1,7 +1,7 @@ import numpy as np import openmc import openmc.capi as capi -from collections import Iterable +from collections.abc import Iterable def legendre_from_expcoef(coef, domain=(-1, 1)): From 7b3185306628509baec37b061fd24c20970caab6 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 21 Aug 2018 12:10:01 -0400 Subject: [PATCH 33/43] Remove Universe type from Fortran --- src/cell.cpp | 27 ++++++++++++++++++++++ src/cell.h | 5 +++- src/geometry_header.F90 | 17 +++++--------- src/hdf5_interface.h | 13 +++++++++++ src/input_xml.F90 | 24 +------------------ src/output.F90 | 5 ++-- src/summary.F90 | 33 ++++++++------------------- src/tallies/tally_filter_universe.F90 | 4 ++-- src/volume_calc.F90 | 4 ++-- 9 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index a3a5d9fde4..e6dbb348dd 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -182,6 +182,28 @@ generate_rpn(int32_t cell_id, std::vector infix) return rpn; } +//============================================================================== +// Universe implementation +//============================================================================== + +void +Universe::to_hdf5(hid_t universes_group) const +{ + // Create a group for this universe. + std::stringstream group_name; + group_name << "universe " << id; + auto group = create_group(universes_group, group_name); + + // Write the contained cells. + if (cells.size() > 0) { + std::vector cell_ids; + for (auto i_cell : cells) cell_ids.push_back(global_cells[i_cell]->id); + write_dataset(group, "cells", cell_ids); + } + + close_group(group); +} + //============================================================================== // Cell implementation //============================================================================== @@ -704,6 +726,11 @@ extern "C" { } n_cells = global_cells.size(); } + + int32_t universe_id(int i_univ) {return global_universes[i_univ]->id;} + + void universes_to_hdf5(hid_t universes_group) + {for (Universe* u : global_universes) u->to_hdf5(universes_group);} } diff --git a/src/cell.h b/src/cell.h index a10c407f0b..72b09f7a82 100644 --- a/src/cell.h +++ b/src/cell.h @@ -55,7 +55,10 @@ class Universe public: int32_t id; //!< Unique ID std::vector cells; //!< Cells within this universe - //double x0, y0, z0; //!< Translation coordinates. + + //! \brief Write universe information to an HDF5 group. + //! \param group_id An HDF5 group id. + void to_hdf5(hid_t group_id) const; }; //============================================================================== diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 504534d302..df59e34101 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -16,6 +16,12 @@ module geometry_header implicit none interface + function universe_id(universe_ind) bind(C) result(id) + import C_INT, C_INT32_T + integer(C_INT), intent(in), value :: universe_ind + integer(C_INT32_T) :: id + end function universe_id + function cell_pointer(cell_ind) bind(C) result(ptr) import C_PTR, C_INT32_T integer(C_INT32_T), intent(in), value :: cell_ind @@ -177,15 +183,6 @@ module geometry_header end subroutine extend_cells_c end interface -!=============================================================================== -! UNIVERSE defines a geometry that fills all phase space -!=============================================================================== - - type Universe - integer :: id ! Unique ID - integer, allocatable :: cells(:) ! List of cells within - end type Universe - !=============================================================================== ! LATTICE abstract type for ordered array of universes. !=============================================================================== @@ -260,7 +257,6 @@ module geometry_header integer(C_INT32_T), bind(C) :: n_universes ! # of universes type(Cell), allocatable, target :: cells(:) - type(Universe), allocatable, target :: universes(:) type(LatticeContainer), allocatable, target :: lattices(:) ! Dictionaries which map user IDs to indices in the global arrays @@ -483,7 +479,6 @@ contains n_universes = 0 if (allocated(cells)) deallocate(cells) - if (allocated(universes)) deallocate(universes) if (allocated(lattices)) deallocate(lattices) call cell_dict % clear() diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index 65a9e2c995..e749a8e1b9 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -36,7 +36,13 @@ bool using_mpio_device(hid_t obj_id); //============================================================================== hid_t create_group(hid_t parent_id, const std::string& name); + +inline hid_t create_group(hid_t parent_id, const std::stringstream& name) +{return create_group(parent_id, name.str());} + + hid_t file_open(const std::string& filename, char mode, bool parallel=false); + void write_string(hid_t group_id, const char* name, const std::string& buffer, bool indep); @@ -314,6 +320,13 @@ write_dataset(hid_t obj_id, const char* name, const std::array& buffer) write_dataset(obj_id, 1, dims, name, H5TypeMap::type_id, buffer.data(), false); } +template inline void +write_dataset(hid_t obj_id, const char* name, const std::vector& buffer) +{ + hsize_t dims[] {buffer.size()}; + write_dataset(obj_id, 1, dims, name, H5TypeMap::type_id, buffer.data(), false); +} + inline void write_dataset(hid_t obj_id, const char* name, Position r) { diff --git a/src/input_xml.F90 b/src/input_xml.F90 index bea0ed6379..e938a456b9 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1002,7 +1002,7 @@ contains subroutine read_geometry_xml() - integer :: i, j + integer :: i integer :: n, n_rlats, n_hlats integer :: univ_id integer :: n_cells_in_univ @@ -1205,30 +1205,8 @@ contains ! SETUP UNIVERSES ! Allocate universes, universe cell arrays, and assign base universe - allocate(universes(n_universes)) - do i = 1, n_universes - associate (u => universes(i)) - u % id = univ_ids % data(i) - - ! Allocate cell list - n_cells_in_univ = cells_in_univ_dict % get(u % id) - allocate(u % cells(n_cells_in_univ)) - u % cells(:) = 0 - end associate - end do root_universe = find_root_universe() + 1 - do i = 1, n_cells - ! Get index in universes array - j = universe_dict % get(cells(i) % universe()) - - ! Set the first zero entry in the universe cells array to the index in the - ! global cells array - associate (u => universes(j)) - u % cells(find(u % cells, 0)) = i - end associate - end do - ! Clear dictionary call cells_in_univ_dict%clear() diff --git a/src/output.F90 b/src/output.F90 index 62b3ee0829..78614269d6 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -211,7 +211,6 @@ contains integer :: i ! index for coordinate levels type(Cell), pointer :: c - type(Universe), pointer :: u class(Lattice), pointer :: l ! display type of particle @@ -239,8 +238,8 @@ contains ! Print universe for this level if (p % coord(i) % universe /= NONE) then - u => universes(p % coord(i) % universe) - write(ou,*) ' Universe = ' // trim(to_str(u % id)) + write(ou,*) ' Universe = ' & + // trim(to_str(universe_id(p % coord(i) % universe-1))) end if ! Print information on lattice diff --git a/src/summary.F90 b/src/summary.F90 index e2cc5f786d..e7823a6aa8 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -163,16 +163,22 @@ contains integer :: i, j, cell_fill integer, allocatable :: cell_materials(:) - integer, allocatable :: cell_ids(:) real(8), allocatable :: cell_temperatures(:) integer(HID_T) :: geom_group integer(HID_T) :: cells_group, cell_group integer(HID_T) :: surfaces_group - integer(HID_T) :: universes_group, univ_group + integer(HID_T) :: universes_group integer(HID_T) :: lattices_group type(Cell), pointer :: c class(Lattice), pointer :: lat + interface + subroutine universes_to_hdf5(universes_group) bind(C) + import HID_T + integer(HID_T), intent(in), value :: universes_group + end subroutine universes_to_hdf5 + end interface + ! Use H5LT interface to write number of geometry objects geom_group = create_group(file_id, "geometry") call write_attribute(geom_group, "n_cells", n_cells) @@ -254,29 +260,8 @@ contains ! ========================================================================== ! WRITE INFORMATION ON UNIVERSES - ! Create universes group (nothing directly written here) then close universes_group = create_group(geom_group, "universes") - - ! Write information on each universe - UNIVERSE_LOOP: do i = 1, n_universes - associate (u => universes(i)) - univ_group = create_group(universes_group, "universe " // & - trim(to_str(u%id))) - - ! Write list of cells in this universe - if (size(u % cells) > 0) then - allocate(cell_ids(size(u % cells))) - do j = 1, size(u % cells) - cell_ids(j) = cells(u % cells(j)) % id() - end do - call write_dataset(univ_group, "cells", cell_ids) - deallocate(cell_ids) - end if - - call close_group(univ_group) - end associate - end do UNIVERSE_LOOP - + call universes_to_hdf5(universes_group) call close_group(universes_group) ! ========================================================================== diff --git a/src/tallies/tally_filter_universe.F90 b/src/tallies/tally_filter_universe.F90 index 0dc5aefe14..2bfc382080 100644 --- a/src/tallies/tally_filter_universe.F90 +++ b/src/tallies/tally_filter_universe.F90 @@ -78,7 +78,7 @@ contains allocate(universe_ids(size(this % universes))) do i = 1, size(this % universes) - universe_ids(i) = universes(this % universes(i)) % id + universe_ids(i) = universe_id(this % universes(i)-1) end do call write_dataset(filter_group, "bins", universe_ids) end subroutine to_statepoint_universe @@ -112,7 +112,7 @@ contains integer, intent(in) :: bin character(MAX_LINE_LEN) :: label - label = "Universe " // to_str(universes(this % universes(bin)) % id) + label = "Universe " // to_str(universe_id(this % universes(bin)-1)) end function text_label_universe end module tally_filter_universe diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index e0c3e88594..93774f98c9 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -9,7 +9,7 @@ module volume_calc use constants use error, only: write_message use geometry, only: find_cell - use geometry_header, only: universes, cells + use geometry_header, only: cells, universe_id use hdf5_interface, only: file_open, file_close, write_attribute, & create_group, close_group, write_dataset, HID_T use output, only: header, time_stamp @@ -216,7 +216,7 @@ contains elseif (this % domain_type == FILTER_UNIVERSE) then do level = 1, p % n_coord do i_domain = 1, size(this % domain_id) - if (universes(p % coord(level) % universe) % id == & + if (universe_id(p % coord(level) % universe - 1) == & this % domain_id(i_domain)) then i_material = p % material call check_hit(i_domain, i_material, indices, hits, n_mat) From f467d52ce73fba5856b49066db7618358b0abe48 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 24 Aug 2018 16:04:05 -0400 Subject: [PATCH 34/43] Make sure init is called in C-API unit test --- tests/unit_tests/test_capi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index 2c3f95b4c7..9d3bc106d2 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -49,7 +49,7 @@ def capi_init(pincell_model): @pytest.fixture(scope='module') -def capi_simulation_init(pincell_model): +def capi_simulation_init(capi_init): openmc.capi.simulation_init() yield From 3be4e09e8e26cfee0b4b80d993a4132b8a461913 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 24 Aug 2018 17:14:11 -0400 Subject: [PATCH 35/43] Use 0-based indexing for universes --- src/cell.cpp | 3 +-- src/geometry.cpp | 15 ++++++--------- src/geometry_aux.cpp | 3 +-- src/input_xml.F90 | 8 ++++---- src/output.F90 | 2 +- src/tallies/tally_filter_distribcell.F90 | 4 ++-- src/tallies/tally_filter_universe.F90 | 2 +- src/volume_calc.F90 | 2 +- 8 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index e6dbb348dd..30df8da55e 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -439,8 +439,7 @@ Cell::to_hdf5(hid_t cell_group) const write_string(cell_group, "name", name, false); } - //TODO: Fix the off-by-one indexing. - write_dataset(cell_group, "universe", global_universes[universe-1]->id); + write_dataset(cell_group, "universe", global_universes[universe]->id); // Write the region specification. if (!region.empty()) { diff --git a/src/geometry.cpp b/src/geometry.cpp index e7cbdd8046..c7c9a4199a 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -25,7 +25,7 @@ check_cell_overlap(Particle* p) { // loop through each coordinate level for (int j = 0; j < n_coord; j++) { - Universe& univ = *global_universes[p->coord[j].universe - 1]; + Universe& univ = *global_universes[p->coord[j].universe]; int n = univ.cells.size(); // loop through each cell on this level @@ -64,8 +64,6 @@ find_cell(Particle* p, int search_surf) { p->coord[p->n_coord-1].universe = openmc_root_universe; i_universe = openmc_root_universe; } - //TODO: off-by-one indexing - --i_universe; // If a surface was indicated, only search cells from the neighbor list of // that surface. @@ -90,8 +88,7 @@ find_cell(Particle* p, int search_surf) { i_cell = search_cells[i]; // Make sure the search cell is in the same universe. - //TODO: off-by-one indexing - if (global_cells[i_cell]->universe - 1 != i_universe) continue; + if (global_cells[i_cell]->universe != i_universe) continue; Position r {p->coord[p->n_coord-1].xyz}; Direction u {p->coord[p->n_coord-1].uvw}; @@ -165,7 +162,7 @@ find_cell(Particle* p, int search_surf) { //! Found a lower universe, update this coord level then search the next. // Set the lower coordinate level universe. - p->coord[p->n_coord].universe = c.fill + 1; + p->coord[p->n_coord].universe = c.fill; // Set the position and direction. for (int i = 0; i < 3; i++) { @@ -234,10 +231,10 @@ find_cell(Particle* p, int search_surf) { // Set the lower coordinate level universe. if (lat.are_valid_indices(i_xyz)) { - p->coord[p->n_coord].universe = lat[i_xyz] + 1; + p->coord[p->n_coord].universe = lat[i_xyz]; } else { if (lat.outer != NO_OUTER_UNIVERSE) { - p->coord[p->n_coord].universe = lat.outer + 1; + p->coord[p->n_coord].universe = lat.outer; } else { std::stringstream err_msg; err_msg << "Particle " << p->id << " is outside lattice " @@ -300,7 +297,7 @@ cross_lattice(Particle* p, int lattice_translation[3]) } else { // Find cell in next lattice element. - p->coord[p->n_coord-1].universe = lat[i_xyz] + 1; + p->coord[p->n_coord-1].universe = lat[i_xyz]; bool found = find_cell(p, 0); if (!found) { diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 6ca3b6d3b3..6fd5021fa4 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -62,8 +62,7 @@ adjust_indices() for (Cell* c : global_cells) { auto search = universe_map.find(c->universe); if (search != universe_map.end()) { - //TODO: Remove this off-by-one indexing. - c->universe = search->second + 1; + c->universe = search->second; } else { std::stringstream err_msg; err_msg << "Could not find universe " << c->universe diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e938a456b9..1a9a234f58 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -170,7 +170,7 @@ contains ! Perform some final operations to set up the geometry call adjust_indices() - call count_cell_instances(root_universe-1) + call count_cell_instances(root_universe) ! After reading input and basic geometry setup is complete, build lists of ! neighboring cells for efficient tracking @@ -185,7 +185,7 @@ contains ! Check to make sure there are not too many nested coordinate levels in the ! geometry since the coordinate list is statically allocated for performance ! reasons - if (maximum_levels(root_universe - 1) > MAX_COORD) then + if (maximum_levels(root_universe) > MAX_COORD) then call fatal_error("Too many nested coordinate levels in the geometry. & &Try increasing the maximum number of coordinate levels by & &providing the CMake -Dmaxcoord= option.") @@ -1146,7 +1146,7 @@ contains if (.not. cells_in_univ_dict % has(univ_id)) then n_universes = n_universes + 1 n_cells_in_univ = 1 - call universe_dict % set(univ_id, n_universes) + call universe_dict % set(univ_id, n_universes - 1) call univ_ids % push_back(univ_id) else n_cells_in_univ = 1 + cells_in_univ_dict % get(univ_id) @@ -1205,7 +1205,7 @@ contains ! SETUP UNIVERSES ! Allocate universes, universe cell arrays, and assign base universe - root_universe = find_root_universe() + 1 + root_universe = find_root_universe() ! Clear dictionary call cells_in_univ_dict%clear() diff --git a/src/output.F90 b/src/output.F90 index 78614269d6..e45968ffc5 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -239,7 +239,7 @@ contains ! Print universe for this level if (p % coord(i) % universe /= NONE) then write(ou,*) ' Universe = ' & - // trim(to_str(universe_id(p % coord(i) % universe-1))) + // trim(to_str(universe_id(p % coord(i) % universe))) end if ! Print information on lattice diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index 9ef282126e..f59d155ea4 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -157,9 +157,9 @@ contains map = cells(i_cell) % distribcell_index() path_len = distribcell_path_len(i_cell-1, map-1, target_offset, & - root_universe-1) + root_universe) allocate(path_c(path_len)) - call distribcell_path(i_cell-1, map-1, target_offset, root_universe-1, & + call distribcell_path(i_cell-1, map-1, target_offset, root_universe, & path_c) do i = 1, min(path_len, MAX_LINE_LEN) if (path_c(i) == C_NULL_CHAR) exit diff --git a/src/tallies/tally_filter_universe.F90 b/src/tallies/tally_filter_universe.F90 index 2bfc382080..39c1449b3d 100644 --- a/src/tallies/tally_filter_universe.F90 +++ b/src/tallies/tally_filter_universe.F90 @@ -112,7 +112,7 @@ contains integer, intent(in) :: bin character(MAX_LINE_LEN) :: label - label = "Universe " // to_str(universe_id(this % universes(bin)-1)) + label = "Universe " // to_str(universe_id(this % universes(bin))) end function text_label_universe end module tally_filter_universe diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index 93774f98c9..c291f1ff75 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -216,7 +216,7 @@ contains elseif (this % domain_type == FILTER_UNIVERSE) then do level = 1, p % n_coord do i_domain = 1, size(this % domain_id) - if (universe_id(p % coord(level) % universe - 1) == & + if (universe_id(p % coord(level) % universe) == & this % domain_id(i_domain)) then i_material = p % material call check_hit(i_domain, i_material, indices, hits, n_mat) From 92f9c09a816501b1fa623781c206028fccda44a6 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 24 Aug 2018 17:56:49 -0400 Subject: [PATCH 36/43] Use 0-based indexing for cells in LocalCoord --- src/api.F90 | 2 +- src/geometry.cpp | 12 +++++------- src/output.F90 | 4 ++-- src/particle.cpp | 6 +++--- src/plot.F90 | 6 +++--- src/tallies/tally_filter_cell.F90 | 2 +- src/tallies/tally_filter_cellborn.F90 | 2 +- src/tallies/tally_filter_cellfrom.F90 | 2 +- src/tallies/tally_filter_distribcell.F90 | 8 ++++---- src/tracking.F90 | 8 ++++---- src/volume_calc.F90 | 2 +- 11 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/api.F90 b/src/api.F90 index c8bea6583f..72acec064c 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -206,7 +206,7 @@ contains if (found) then if (rtype == 1) then - id = cells(p % coord(p % n_coord) % cell) % id() + id = cells(p % coord(p % n_coord) % cell + 1) % id() elseif (rtype == 2) then if (p % material == MATERIAL_VOID) then id = 0 diff --git a/src/geometry.cpp b/src/geometry.cpp index c7c9a4199a..9aac3f3143 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -34,11 +34,10 @@ check_cell_overlap(Particle* p) { Cell& c = *global_cells[index_cell]; if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { - //TODO: off-by-one indexing - if (index_cell != p->coord[j].cell - 1) { + if (index_cell != p->coord[j].cell) { std::stringstream err_msg; err_msg << "Overlapping cells detected: " << c.id << ", " - << global_cells[p->coord[j].cell-1]->id << " on universe " + << global_cells[p->coord[j].cell]->id << " on universe " << univ.id; fatal_error(err_msg); } @@ -94,8 +93,7 @@ find_cell(Particle* p, int search_surf) { Direction u {p->coord[p->n_coord-1].uvw}; int32_t surf = p->surface; if (global_cells[i_cell]->contains(r, u, surf)) { - //TODO: off-by-one indexing - p->coord[p->n_coord-1].cell = i_cell + 1; + p->coord[p->n_coord-1].cell = i_cell; if (openmc_verbosity >= 10 || openmc_trace) { std::stringstream msg; @@ -119,7 +117,7 @@ find_cell(Particle* p, int search_surf) { int distribcell_index = c.distribcell_index - 1; int offset = 0; for (int i = 0; i < p->n_coord; i++) { - Cell& c_i {*global_cells[p->coord[i].cell-1]}; + Cell& c_i {*global_cells[p->coord[i].cell]}; if (c_i.type == FILL_UNIVERSE) { offset += c_i.offset[distribcell_index]; } else if (c_i.type == FILL_LATTICE) { @@ -334,7 +332,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, for (int i = 0; i < p->n_coord; i++) { Position r {p->coord[i].xyz}; Direction u {p->coord[i].uvw}; - Cell& c {*global_cells[p->coord[i].cell-1]}; + Cell& c {*global_cells[p->coord[i].cell]}; // Find the oncoming surface in this cell and the distance to it. auto surface_distance = c.distance(r, u, p->surface); diff --git a/src/output.F90 b/src/output.F90 index e45968ffc5..0f23c67bd8 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -231,8 +231,8 @@ contains write(ou,*) ' Level ' // trim(to_str(i - 1)) ! Print cell for this level - if (p % coord(i) % cell /= NONE) then - c => cells(p % coord(i) % cell) + if (p % coord(i) % cell /= C_NONE) then + c => cells(p % coord(i) % cell + 1) write(ou,*) ' Cell = ' // trim(to_str(c % id())) end if diff --git a/src/particle.cpp b/src/particle.cpp index e46d06c011..5dbfb2483c 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -19,8 +19,8 @@ namespace openmc { void LocalCoord::reset() { - cell = 0; - universe = 0; + cell = C_NONE; + universe = C_NONE; lattice = 0; lattice_x = 0; lattice_y = 0; @@ -67,7 +67,7 @@ Particle::initialize() // clear attributes surface = 0; - cell_born = 0; + cell_born = C_NONE; material = 0; last_material = 0; last_sqrtkT = 0; diff --git a/src/plot.F90 b/src/plot.F90 index 2fd898206c..517c27fa17 100644 --- a/src/plot.F90 +++ b/src/plot.F90 @@ -84,7 +84,7 @@ contains else if (pl % color_by == PLOT_COLOR_MATS) then ! Assign color based on material - associate (c => cells(p % coord(j) % cell)) + associate (c => cells(p % coord(j) % cell + 1)) if (c % type() == FILL_UNIVERSE) then ! If we stopped on a middle universe level, treat as if not found rgb = pl % not_found % rgb @@ -100,8 +100,8 @@ contains end associate else if (pl % color_by == PLOT_COLOR_CELLS) then ! Assign color based on cell - rgb = pl % colors(p % coord(j) % cell) % rgb - id = cells(p % coord(j) % cell) % id() + rgb = pl % colors(p % coord(j) % cell + 1) % rgb + id = cells(p % coord(j) % cell + 1) % id() else rgb = 0 id = -1 diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index be37467073..a394ed122b 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -59,7 +59,7 @@ contains ! Iterate over coordinate levels to see with cells match do i = 1, p % n_coord - val = this % map % get(p % coord(i) % cell) + val = this % map % get(p % coord(i) % cell + 1) if (val /= EMPTY) then call match % bins % push_back(val) call match % weights % push_back(ONE) diff --git a/src/tallies/tally_filter_cellborn.F90 b/src/tallies/tally_filter_cellborn.F90 index a373c2d4e1..37bf042020 100644 --- a/src/tallies/tally_filter_cellborn.F90 +++ b/src/tallies/tally_filter_cellborn.F90 @@ -55,7 +55,7 @@ contains integer :: val - val = this % map % get(p % cell_born) + val = this % map % get(p % cell_born + 1) if (val /= EMPTY) then call match % bins % push_back(val) call match % weights % push_back(ONE) diff --git a/src/tallies/tally_filter_cellfrom.F90 b/src/tallies/tally_filter_cellfrom.F90 index 83a3179d26..a99aa68832 100644 --- a/src/tallies/tally_filter_cellfrom.F90 +++ b/src/tallies/tally_filter_cellfrom.F90 @@ -42,7 +42,7 @@ contains ! Starting one coordinate level deeper, find the next bin. do i = 1, p % last_n_coord - val = this % map % get(p % last_cell(i)) + val = this % map % get(p % last_cell(i) + 1) if (val /= EMPTY) then call match % bins % push_back(val) call match % weights % push_back(ONE) diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index f59d155ea4..48b223a439 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -57,10 +57,10 @@ contains 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 - offset = offset + cells(p % coord(i) % cell) & + if (cells(p % coord(i) % cell + 1) % type() == FILL_UNIVERSE) then + offset = offset + cells(p % coord(i) % cell + 1) & % offset(distribcell_index-1) - elseif (cells(p % coord(i) % cell) % type() == FILL_LATTICE) then + elseif (cells(p % coord(i) % cell + 1) % type() == FILL_LATTICE) then if (lattices(p % coord(i + 1) % lattice) % obj & % are_valid_indices([& p % coord(i + 1) % lattice_x, & @@ -73,7 +73,7 @@ contains p % coord(i + 1) % lattice_z]) end if end if - if (this % cell == p % coord(i) % cell) then + if (this % cell == p % coord(i) % cell + 1) then call match % bins % push_back(offset + 1) call match % weights % push_back(ONE) return diff --git a/src/tracking.F90 b/src/tracking.F90 index e9568fe54a..d93ac9ab97 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -91,7 +91,7 @@ contains ! If the cell hasn't been determined based on the particle's location, ! initiate a search for the current cell. This generally happens at the ! beginning of the history and again for any secondary particles - if (p % coord(p % n_coord) % cell == NONE) then + if (p % coord(p % n_coord) % cell == C_NONE) then call find_cell(p, found_cell) if (.not. found_cell) then call particle_mark_as_lost(p, "Could not find the cell containing" & @@ -100,7 +100,7 @@ contains end if ! set birth cell attribute - if (p % cell_born == NONE) p % cell_born = p % coord(p % n_coord) % cell + if (p % cell_born == C_NONE) p % cell_born = p % coord(p % n_coord) % cell end if ! Write particle track. @@ -183,7 +183,7 @@ contains end do p % last_n_coord = p % n_coord - p % coord(p % n_coord) % cell = NONE + p % coord(p % n_coord) % cell = C_NONE if (any(lattice_translation /= 0)) then ! Particle crosses lattice boundary p % surface = ERROR_INT @@ -251,7 +251,7 @@ contains do j = 1, p % n_coord - 1 if (p % coord(j + 1) % rotated) then ! If next level is rotated, apply rotation matrix - p % coord(j + 1) % uvw = matmul(cells(p % coord(j) % cell) % & + p % coord(j + 1) % uvw = matmul(cells(p % coord(j) % cell + 1) % & rotation_matrix, p % coord(j) % uvw) else ! Otherwise, copy this level's direction diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index c291f1ff75..f7ded73611 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -205,7 +205,7 @@ contains elseif (this % domain_type == FILTER_CELL) THEN do level = 1, p % n_coord do i_domain = 1, size(this % domain_id) - if (cells(p % coord(level) % cell) % id() & + if (cells(p % coord(level) % cell + 1) % id() & == this % domain_id(i_domain)) then i_material = p % material call check_hit(i_domain, i_material, indices, hits, n_mat) From 243eae1244971bafd8926faac7491afda693b7ef Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 24 Aug 2018 19:06:04 -0400 Subject: [PATCH 37/43] Move all summary.h5 geometry writing to C++ --- CMakeLists.txt | 1 + src/cell.cpp | 51 +++++++++++++--- src/hdf5_interface.cpp | 2 + src/hdf5_interface.h | 2 +- src/summary.F90 | 132 +++-------------------------------------- src/summary.cpp | 36 +++++++++++ 6 files changed, 89 insertions(+), 135 deletions(-) create mode 100644 src/summary.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a449e74849..d69a7c7f77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -420,6 +420,7 @@ add_library(libopenmc SHARED src/simulation.cpp src/state_point.cpp src/string_functions.cpp + src/summary.cpp src/surface.cpp src/xml_interface.cpp src/xsdata.cpp) diff --git a/src/cell.cpp b/src/cell.cpp index 30df8da55e..c6f7b3ab9e 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -433,13 +433,18 @@ Cell::distance(Position r, Direction u, int32_t on_surface) const //============================================================================== void -Cell::to_hdf5(hid_t cell_group) const +Cell::to_hdf5(hid_t cells_group) const { + // Create a group for this cell. + std::stringstream group_name; + group_name << "cell " << id; + auto group = create_group(cells_group, group_name); + if (!name.empty()) { - write_string(cell_group, "name", name, false); + write_string(group, "name", name, false); } - write_dataset(cell_group, "universe", global_universes[universe]->id); + write_dataset(group, "universe", global_universes[universe]->id); // Write the region specification. if (!region.empty()) { @@ -460,20 +465,48 @@ Cell::to_hdf5(hid_t cell_group) const << copysign(global_surfaces[abs(token)-1]->id, token); } } - write_string(cell_group, "region", region_spec.str(), false); + write_string(group, "region", region_spec.str(), false); } - if (type == FILL_UNIVERSE) { - write_dataset(cell_group, "fill_type", "universe"); - write_dataset(cell_group, "fill", global_universes[fill]->id); + // Write fill information. + if (type == FILL_MATERIAL) { + write_dataset(group, "fill_type", "material"); + std::vector mat_ids; + for (auto i_mat : material) { + if (i_mat != MATERIAL_VOID) { + mat_ids.push_back(global_materials[i_mat]->id); + } else { + mat_ids.push_back(MATERIAL_VOID); + } + } + if (mat_ids.size() == 1) { + write_dataset(group, "material", mat_ids[0]); + } else { + write_dataset(group, "material", mat_ids); + } + + std::vector temps; + for (auto sqrtkT_val : sqrtkT) + temps.push_back(sqrtkT_val * sqrtkT_val / K_BOLTZMANN); + write_dataset(group, "temperature", temps); + + } else if (type == FILL_UNIVERSE) { + write_dataset(group, "fill_type", "universe"); + write_dataset(group, "fill", global_universes[fill]->id); if (translation != 0) { - write_dataset(cell_group, "translation", translation); + write_dataset(group, "translation", translation); } if (!rotation.empty()) { std::array rot {rotation[0], rotation[1], rotation[2]}; - write_dataset(cell_group, "rotation", rot); + write_dataset(group, "rotation", rot); } + + } else if (type == FILL_LATTICE) { + write_dataset(group, "fill_type", "lattice"); + write_dataset(group, "lattice", lattices_c[fill]->id); } + + close_group(group); } //============================================================================== diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index 5d6926479c..643859620b 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -899,6 +899,8 @@ using_mpio_device(hid_t obj_id) template<> const hid_t H5TypeMap::type_id = H5T_NATIVE_INT; template<> +const hid_t H5TypeMap::type_id = H5T_NATIVE_ULONG; +template<> const hid_t H5TypeMap::type_id = H5T_NATIVE_INT64; template<> const hid_t H5TypeMap::type_id = H5T_NATIVE_DOUBLE; diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index e749a8e1b9..8eccaa016f 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -281,7 +281,7 @@ void read_dataset(hid_t obj_id, const char* name, xt::xarray& arr, bool indep template inline void write_attribute(hid_t obj_id, const char* name, T buffer) { - write_attr(obj_id, name, 0, nullptr, H5TypeMap::type_id, &buffer); + write_attr(obj_id, 0, nullptr, name, H5TypeMap::type_id, &buffer); } inline void diff --git a/src/summary.F90 b/src/summary.F90 index e7823a6aa8..9d3b7bc8fe 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -29,6 +29,13 @@ contains subroutine write_summary() + interface + subroutine write_geometry(file_id) bind(C) + import HID_T + integer(HID_T), intent(in), value :: file_id + end subroutine write_geometry + end interface + integer(HID_T) :: file_id ! Display output message @@ -154,131 +161,6 @@ contains end subroutine write_nuclides -!=============================================================================== -! WRITE_GEOMETRY -!=============================================================================== - - subroutine write_geometry(file_id) - integer(HID_T), intent(in) :: file_id - - integer :: i, j, cell_fill - integer, allocatable :: cell_materials(:) - real(8), allocatable :: cell_temperatures(:) - integer(HID_T) :: geom_group - integer(HID_T) :: cells_group, cell_group - integer(HID_T) :: surfaces_group - integer(HID_T) :: universes_group - integer(HID_T) :: lattices_group - type(Cell), pointer :: c - class(Lattice), pointer :: lat - - interface - subroutine universes_to_hdf5(universes_group) bind(C) - import HID_T - integer(HID_T), intent(in), value :: universes_group - end subroutine universes_to_hdf5 - end interface - - ! Use H5LT interface to write number of geometry objects - geom_group = create_group(file_id, "geometry") - call write_attribute(geom_group, "n_cells", n_cells) - call write_attribute(geom_group, "n_surfaces", n_surfaces) - call write_attribute(geom_group, "n_universes", n_universes) - call write_attribute(geom_group, "n_lattices", size(lattices)) - - ! ========================================================================== - ! WRITE INFORMATION ON CELLS - - ! Create a cell group (nothing directly written in this group) then close - cells_group = create_group(geom_group, "cells") - - ! Write information on each cell - CELL_LOOP: do i = 1, n_cells - c => cells(i) - cell_group = create_group(cells_group, "cell " // trim(to_str(c%id()))) - - call c % to_hdf5(cell_group) - - ! Write information on what fills this cell - select case (c%type()) - case (FILL_MATERIAL) - call write_dataset(cell_group, "fill_type", "material") - - if (c % material_size() == 1) then - if (c % material(1) == MATERIAL_VOID) then - call write_dataset(cell_group, "material", MATERIAL_VOID) - else - call write_dataset(cell_group, "material", & - materials(c % material(1)) % id()) - end if - else - allocate(cell_materials(c % material_size())) - do j = 1, c % material_size() - if (c % material(j) == MATERIAL_VOID) then - cell_materials(j) = MATERIAL_VOID - else - cell_materials(j) = materials(c % material(j)) % id() - end if - end do - call write_dataset(cell_group, "material", cell_materials) - deallocate(cell_materials) - end if - - allocate(cell_temperatures(c % sqrtkT_size())) - do j = 1, c % sqrtkT_size() - cell_temperatures(j) = c % sqrtkT(j-1)**2 / K_BOLTZMANN - end do - call write_dataset(cell_group, "temperature", cell_temperatures) - deallocate(cell_temperatures) - - case (FILL_LATTICE) - call write_dataset(cell_group, "fill_type", "lattice") - ! Do not access the 'lattices' array with 'c % fill() + 1' directly; it - ! causes a segfault in GCC 7.3.0 - cell_fill = c % fill() + 1 - call write_dataset(cell_group, "lattice", lattices(cell_fill)%obj%id()) - end select - - call close_group(cell_group) - end do CELL_LOOP - - call close_group(cells_group) - - ! ========================================================================== - ! WRITE INFORMATION ON SURFACES - - ! Create surfaces group - surfaces_group = create_group(geom_group, "surfaces") - - ! Write information on each surface - SURFACE_LOOP: do i = 1, n_surfaces - call surfaces(i) % to_hdf5(surfaces_group) - end do SURFACE_LOOP - - call close_group(surfaces_group) - - ! ========================================================================== - ! WRITE INFORMATION ON UNIVERSES - - universes_group = create_group(geom_group, "universes") - call universes_to_hdf5(universes_group) - call close_group(universes_group) - - ! ========================================================================== - ! WRITE INFORMATION ON LATTICES - - lattices_group = create_group(geom_group, "lattices") - - do i = 1, size(lattices) - lat => lattices(i)%obj - call lat % to_hdf5(lattices_group) - end do - - call close_group(lattices_group) - call close_group(geom_group) - - end subroutine write_geometry - !=============================================================================== ! WRITE_MATERIALS !=============================================================================== diff --git a/src/summary.cpp b/src/summary.cpp new file mode 100644 index 0000000000..a7344e7b4d --- /dev/null +++ b/src/summary.cpp @@ -0,0 +1,36 @@ +#include "cell.h" +#include "hdf5_interface.h" +#include "lattice.h" +#include "surface.h" + + +namespace openmc { + +extern "C" void +write_geometry(hid_t file_id) { + auto geom_group = create_group(file_id, "geometry"); + write_attribute(geom_group, "n_cells", global_cells.size()); + write_attribute(geom_group, "n_surfaces", global_surfaces.size()); + write_attribute(geom_group, "n_universes", global_universes.size()); + write_attribute(geom_group, "n_lattices", lattices_c.size()); + + auto cells_group = create_group(geom_group, "cells"); + for (Cell* c : global_cells) c->to_hdf5(cells_group); + close_group(cells_group); + + auto surfaces_group = create_group(geom_group, "surfaces"); + for (Surface* surf : global_surfaces) surf->to_hdf5(surfaces_group); + close_group(surfaces_group); + + auto universes_group = create_group(geom_group, "universes"); + for (Universe* u : global_universes) u->to_hdf5(universes_group); + close_group(universes_group); + + auto lattices_group = create_group(geom_group, "lattices"); + for (Lattice* lat : lattices_c) lat->to_hdf5(lattices_group); + close_group(lattices_group); + + close_group(geom_group); +} + +} // namespace openmc From fe790e2c726b794a97f8d7b8044e1b5098aa8729 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 24 Aug 2018 19:48:10 -0400 Subject: [PATCH 38/43] Cleanup --- src/cell.cpp | 2 - src/geometry_header.F90 | 103 +---------------------- src/input_xml.F90 | 12 +-- src/lattice.cpp | 54 ++++-------- src/lattice.h | 43 +++------- src/output.F90 | 2 +- src/surface.cpp | 11 --- src/surface_header.F90 | 32 ------- src/tallies/tally_filter_distribcell.F90 | 5 +- 9 files changed, 35 insertions(+), 229 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index c6f7b3ab9e..83516eba67 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -748,8 +748,6 @@ extern "C" { int32_t cell_offset(Cell* c, int map) {return c->offset[map];} - void cell_to_hdf5(Cell* c, hid_t group) {c->to_hdf5(group);} - void extend_cells_c(int32_t n) { global_cells.reserve(global_cells.size() + n); diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index df59e34101..b58b5415ba 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -111,12 +111,6 @@ module geometry_header integer(C_INT32_T) :: offset end function cell_offset_c - subroutine cell_to_hdf5_c(cell_ptr, group) bind(C, name='cell_to_hdf5') - import HID_T, C_PTR - type(C_PTR), intent(in), value :: cell_ptr - integer(HID_T), intent(in), value :: group - end subroutine cell_to_hdf5_c - function lattice_pointer(lat_ind) bind(C) result(ptr) import C_PTR, C_INT32_T integer(C_INT32_T), intent(in), value :: lat_ind @@ -137,29 +131,6 @@ module geometry_header logical(C_BOOL) :: is_valid end function lattice_are_valid_indices_c - subroutine lattice_get_indices_c(lat_ptr, xyz, i_xyz) & - bind(C, name='lattice_get_indices') - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), intent(in), value :: lat_ptr - real(C_DOUBLE), intent(in) :: xyz(3) - integer(C_INT), intent(out) :: i_xyz(3) - end subroutine lattice_get_indices_c - - subroutine lattice_get_local_xyz_c(lat_ptr, global_xyz, i_xyz, local_xyz) & - bind(C, name='lattice_get_local_xyz') - import C_PTR, C_INT, C_DOUBLE - type(C_PTR), intent(in), value :: lat_ptr - real(C_DOUBLE), intent(in) :: global_xyz(3) - integer(C_INT), intent(in) :: i_xyz(3) - real(C_DOUBLE), intent(out) :: local_xyz(3) - end subroutine lattice_get_local_xyz_c - - subroutine lattice_to_hdf5_c(lat_ptr, group) bind(C, name='lattice_to_hdf5') - import HID_T, C_PTR - type(C_PTR), intent(in), value :: lat_ptr - integer(HID_T), intent(in), value :: group - end subroutine lattice_to_hdf5_c - function lattice_offset_c(lat_ptr, map, i_xyz) & bind(C, name='lattice_offset') result(offset) import C_PTR, C_INT, C_INT32_T @@ -169,14 +140,6 @@ module geometry_header integer(C_INT32_T) :: offset end function lattice_offset_c - function lattice_universe_c(lat_ptr, i_xyz) & - bind(C, name='lattice_universe') result(univ) - import C_PTR, C_INT32_t, C_INT - type(C_PTR), intent(in), value :: lat_ptr - integer(C_INT), intent(in) :: i_xyz(3) - integer(C_INT32_T) :: univ - end function lattice_universe_c - subroutine extend_cells_c(n) bind(C) import C_INT32_t integer(C_INT32_T), intent(in), value :: n @@ -187,40 +150,14 @@ module geometry_header ! LATTICE abstract type for ordered array of universes. !=============================================================================== - type, abstract :: Lattice + type :: Lattice type(C_PTR) :: ptr contains procedure :: id => lattice_id procedure :: are_valid_indices => lattice_are_valid_indices - procedure :: get => lattice_get - procedure :: get_indices => lattice_get_indices - procedure :: get_local_xyz => lattice_get_local_xyz procedure :: offset => lattice_offset - procedure :: to_hdf5 => lattice_to_hdf5 end type Lattice -!=============================================================================== -! RECTLATTICE extends LATTICE for rectilinear arrays. -!=============================================================================== - - type, extends(Lattice) :: RectLattice - end type RectLattice - -!=============================================================================== -! HEXLATTICE extends LATTICE for hexagonal (sometimes called triangular) arrays. -!=============================================================================== - - type, extends(Lattice) :: HexLattice - end type HexLattice - -!=============================================================================== -! LATTICECONTAINER pointer array for storing lattices -!=============================================================================== - - type LatticeContainer - class(Lattice), allocatable :: obj - end type LatticeContainer - !=============================================================================== ! CELL defines a closed volume by its bounding surfaces !=============================================================================== @@ -246,7 +183,6 @@ module geometry_header procedure :: sqrtkT_size => cell_sqrtkT_size procedure :: sqrtkT => cell_sqrtkT procedure :: offset => cell_offset - procedure :: to_hdf5 => cell_to_hdf5 end type Cell @@ -257,7 +193,7 @@ module geometry_header integer(C_INT32_T), bind(C) :: n_universes ! # of universes type(Cell), allocatable, target :: cells(:) - type(LatticeContainer), allocatable, target :: lattices(:) + type(Lattice), allocatable, target :: lattices(:) ! Dictionaries which map user IDs to indices in the global arrays type(DictIntInt) :: cell_dict @@ -279,29 +215,6 @@ contains is_valid = lattice_are_valid_indices_c(this % ptr, i_xyz) end function lattice_are_valid_indices - function lattice_get(this, i_xyz) result(univ) - class(Lattice), intent(in) :: this - integer(C_INT), intent(in) :: i_xyz(3) - integer(C_INT32_T) :: univ - univ = lattice_universe_c(this % ptr, i_xyz) - end function lattice_get - - function lattice_get_indices(this, xyz) result(i_xyz) - class(Lattice), intent(in) :: this - real(C_DOUBLE), intent(in) :: xyz(3) - integer(C_INT) :: i_xyz(3) - call lattice_get_indices_c(this % ptr, xyz, i_xyz) - end function lattice_get_indices - - function lattice_get_local_xyz(this, global_xyz, i_xyz) & - result(local_xyz) - class(Lattice), intent(in) :: this - real(C_DOUBLE), intent(in) :: global_xyz(3) - integer(C_INT), intent(in) :: i_xyz(3) - real(C_DOUBLE) :: local_xyz(3) - call lattice_get_local_xyz_c(this % ptr, global_xyz, i_xyz, local_xyz) - end function lattice_get_local_xyz - function lattice_offset(this, map, i_xyz) result(offset) class(Lattice), intent(in) :: this integer(C_INT), intent(in) :: map @@ -310,12 +223,6 @@ contains offset = lattice_offset_c(this % ptr, map, i_xyz) end function lattice_offset - subroutine lattice_to_hdf5(this, group) - class(Lattice), intent(in) :: this - integer(HID_T), intent(in) :: group - call lattice_to_hdf5_c(this % ptr, group) - end subroutine lattice_to_hdf5 - !=============================================================================== function cell_id(this) result(id) @@ -393,12 +300,6 @@ contains offset = cell_offset_c(this % ptr, map) end function cell_offset - subroutine cell_to_hdf5(this, group) - class(Cell), intent(in) :: this - integer(HID_T), intent(in) :: group - call cell_to_hdf5_c(this % ptr, group) - end subroutine cell_to_hdf5 - !=============================================================================== ! GET_TEMPERATURES returns a list of temperatures that each nuclide/S(a,b) table ! appears at in the model. Later, this list is used to determine the actual diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 1a9a234f58..cbdc54fec9 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1170,11 +1170,8 @@ contains allocate(lattices(n_rlats + n_hlats)) RECT_LATTICES: do i = 1, n_rlats - allocate(RectLattice::lattices(i) % obj) - lat => lattices(i) % obj + lat => lattices(i) lat % ptr = lattice_pointer(i - 1) - select type(lat) - type is (RectLattice) ! Get pointer to i-th lattice node_lat = node_rlat_list(i) @@ -1182,15 +1179,11 @@ contains ! Add lattice to dictionary call lattice_dict % set(lat % id(), i) - end select end do RECT_LATTICES HEX_LATTICES: do i = 1, n_hlats - allocate(HexLattice::lattices(n_rlats + i) % obj) - lat => lattices(n_rlats + i) % obj + lat => lattices(n_rlats + i) lat % ptr = lattice_pointer(n_rlats + i - 1) - select type (lat) - type is (HexLattice) ! Get pointer to i-th lattice node_lat = node_hlat_list(i) @@ -1198,7 +1191,6 @@ contains ! Add lattice to dictionary call lattice_dict % set(lat % id(), n_rlats + i) - end select end do HEX_LATTICES ! ========================================================================== diff --git a/src/lattice.cpp b/src/lattice.cpp index 46f88e3519..241c4dedcf 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -206,7 +206,7 @@ RectLattice::RectLattice(pugi::xml_node lat_node) //============================================================================== int32_t& -RectLattice::operator[](const int i_xyz[3]) +RectLattice::operator[](std::array i_xyz) { int indx = nx*ny*i_xyz[2] + nx*i_xyz[1] + i_xyz[0]; return universes[indx]; @@ -225,7 +225,8 @@ RectLattice::are_valid_indices(const int i_xyz[3]) const //============================================================================== std::pair> -RectLattice::distance(Position r, Direction u, const int i_xyz[3]) const +RectLattice::distance(Position r, Direction u, const std::array& i_xyz) +const { // Get short aliases to the coordinates. double x = r.x; @@ -299,7 +300,8 @@ RectLattice::get_indices(Position r) const //============================================================================== Position -RectLattice::get_local_position(Position r, const int i_xyz[3]) const +RectLattice::get_local_position(Position r, const std::array i_xyz) +const { r.x -= (lower_left.x + (i_xyz[0] + 0.5)*pitch.x); r.y -= (lower_left.y + (i_xyz[1] + 0.5)*pitch.y); @@ -549,7 +551,7 @@ HexLattice::HexLattice(pugi::xml_node lat_node) //============================================================================== int32_t& -HexLattice::operator[](const int i_xyz[3]) +HexLattice::operator[](std::array i_xyz) { int indx = (2*n_rings-1)*(2*n_rings-1) * i_xyz[2] + (2*n_rings-1) * i_xyz[1] @@ -580,7 +582,8 @@ HexLattice::are_valid_indices(const int i_xyz[3]) const //============================================================================== std::pair> -HexLattice::distance(Position r, Direction u, const int i_xyz[3]) const +HexLattice::distance(Position r, Direction u, const std::array& i_xyz) +const { // Compute the direction on the hexagonal basis. double beta_dir = u.x * std::sqrt(3.0) / 2.0 + u.y / 2.0; @@ -598,10 +601,10 @@ HexLattice::distance(Position r, Direction u, const int i_xyz[3]) const double edge = -copysign(0.5*pitch[0], beta_dir); // Oncoming edge Position r_t; if (beta_dir > 0) { - const int i_xyz_t[3] {i_xyz[0]+1, i_xyz[1], i_xyz[2]}; + const std::array i_xyz_t {i_xyz[0]+1, i_xyz[1], i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); } else { - const int i_xyz_t[3] {i_xyz[0]-1, i_xyz[1], i_xyz[2]}; + const std::array i_xyz_t {i_xyz[0]-1, i_xyz[1], i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); } double beta = r_t.x * std::sqrt(3.0) / 2.0 + r_t.y / 2.0; @@ -617,10 +620,10 @@ HexLattice::distance(Position r, Direction u, const int i_xyz[3]) const // Lower-right and upper-left sides. edge = -copysign(0.5*pitch[0], gamma_dir); if (gamma_dir > 0) { - const int i_xyz_t[3] {i_xyz[0]+1, i_xyz[1]-1, i_xyz[2]}; + const std::array i_xyz_t {i_xyz[0]+1, i_xyz[1]-1, i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); } else { - const int i_xyz_t[3] {i_xyz[0]-1, i_xyz[1]+1, i_xyz[2]}; + const std::array i_xyz_t {i_xyz[0]-1, i_xyz[1]+1, i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); } double gamma = r_t.x * std::sqrt(3.0) / 2.0 - r_t.y / 2.0; @@ -639,10 +642,10 @@ HexLattice::distance(Position r, Direction u, const int i_xyz[3]) const // Upper and lower sides. edge = -copysign(0.5*pitch[0], u.y); if (u.y > 0) { - const int i_xyz_t[3] {i_xyz[0], i_xyz[1]+1, i_xyz[2]}; + const std::array i_xyz_t {i_xyz[0], i_xyz[1]+1, i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); } else { - const int i_xyz_t[3] {i_xyz[0], i_xyz[1]-1, i_xyz[2]}; + const std::array i_xyz_t {i_xyz[0], i_xyz[1]-1, i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); } if ((std::abs(r_t.y - edge) > FP_PRECISION) && u.y != 0) { @@ -719,7 +722,7 @@ HexLattice::get_indices(Position r) const double d_min {INFTY}; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { - int i_xyz[3] {out[0] + j, out[1] + i, 0}; + const std::array i_xyz {out[0] + j, out[1] + i, 0}; Position r_t = get_local_position(r, i_xyz); double d = r_t.x*r_t.x + r_t.y*r_t.y; if (d < d_min) { @@ -747,7 +750,8 @@ HexLattice::get_indices(Position r) const //============================================================================== Position -HexLattice::get_local_position(Position r, const int i_xyz[3]) const +HexLattice::get_local_position(Position r, const std::array i_xyz) +const { // x_l = x_g - (center + pitch_x*cos(30)*index_x) r.x -= (center.x + std::sqrt(3.0)/2.0 * (i_xyz[0] - n_rings + 1) * pitch[0]); @@ -893,32 +897,8 @@ extern "C" { bool lattice_are_valid_indices(Lattice *lat, const int i_xyz[3]) {return lat->are_valid_indices(i_xyz);} - void lattice_get_indices(Lattice *lat, const double xyz[3], int i_xyz[3]) - { - Position r {xyz}; - std::array inds = lat->get_indices(r); - i_xyz[0] = inds[0]; - i_xyz[1] = inds[1]; - i_xyz[2] = inds[2]; - } - - void lattice_get_local_xyz(Lattice *lat, const double global_xyz[3], - const int i_xyz[3], double local_xyz[3]) - { - Position global {global_xyz}; - Position local = lat->get_local_position(global, i_xyz); - local_xyz[0] = local.x; - local_xyz[1] = local.y; - local_xyz[2] = local.z; - } - int32_t lattice_offset(Lattice *lat, int map, const int i_xyz[3]) {return lat->offset(map, i_xyz);} - - void lattice_to_hdf5(Lattice *lat, hid_t group) {lat->to_hdf5(group);} - - int32_t lattice_universe(Lattice *lat, const int i_xyz[3]) - {return (*lat)[i_xyz];} } } // namespace openmc diff --git a/src/lattice.h b/src/lattice.h index 758acfa829..163b86e851 100644 --- a/src/lattice.h +++ b/src/lattice.h @@ -57,14 +57,7 @@ public: virtual ~Lattice() {} - virtual int32_t& operator[](const int i_xyz[3]) = 0; - - int32_t& - operator[](std::array i_xyz) - { - int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; - return operator[](i_xyz_); - } + virtual int32_t& operator[](std::array i_xyz) = 0; virtual LatticeIter begin(); LatticeIter end(); @@ -98,20 +91,13 @@ public: //! \brief Find the next lattice surface crossing //! \param r A 3D Cartesian coordinate. //! \param u A 3D Cartesian direction. - //! \param i_xyz[3] The indices for a lattice tile. + //! \param i_xyz The indices for a lattice tile. //! \return The distance to the next crossing and an array indicating how the //! lattice indices would change after crossing that boundary. virtual std::pair> - distance(Position r, Direction u, const int i_xyz[3]) const + distance(Position r, Direction u, const std::array& i_xyz) const = 0; - std::pair> - distance(Position r, Direction u, std::array i_xyz) const - { - int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; - return distance(r, u, i_xyz_); - } - //! \brief Find the lattice tile indices for a given point. //! \param r A 3D Cartesian coordinate. //! \return An array containing the indices of a lattice tile. @@ -119,17 +105,10 @@ public: //! \brief Get coordinates local to a lattice tile. //! \param r A 3D Cartesian coordinate. - //! \param i_xyz[3] The indices for a lattice tile. + //! \param i_xyz The indices for a lattice tile. //! \return Local 3D Cartesian coordinates. virtual Position - get_local_position(Position r, const int i_xyz[3]) const = 0; - - Position - get_local_position(Position r, std::array i_xyz) const - { - int i_xyz_[3] {i_xyz[0], i_xyz[1], i_xyz[2]}; - return get_local_position(r, i_xyz_); - } + get_local_position(Position r, const std::array i_xyz) const = 0; //! \brief Check flattened lattice index. //! \param indx The index for a lattice tile. @@ -223,17 +202,17 @@ class RectLattice : public Lattice public: explicit RectLattice(pugi::xml_node lat_node); - int32_t& operator[](const int i_xyz[3]); + int32_t& operator[](std::array i_xyz); bool are_valid_indices(const int i_xyz[3]) const; std::pair> - distance(Position r, Direction u, const int i_xyz[3]) const; + distance(Position r, Direction u, const std::array& i_xyz) const; std::array get_indices(Position r) const; Position - get_local_position(Position r, const int i_xyz[3]) const; + get_local_position(Position r, const std::array i_xyz) const; int32_t& offset(int map, const int i_xyz[3]); @@ -259,7 +238,7 @@ class HexLattice : public Lattice public: explicit HexLattice(pugi::xml_node lat_node); - int32_t& operator[](const int i_xyz[3]); + int32_t& operator[](std::array i_xyz); LatticeIter begin(); @@ -268,12 +247,12 @@ public: bool are_valid_indices(const int i_xyz[3]) const; std::pair> - distance(Position r, Direction u, const int i_xyz[3]) const; + distance(Position r, Direction u, const std::array& i_xyz) const; std::array get_indices(Position r) const; Position - get_local_position(Position r, const int i_xyz[3]) const; + get_local_position(Position r, const std::array i_xyz) const; bool is_valid_index(int indx) const; diff --git a/src/output.F90 b/src/output.F90 index 0f23c67bd8..a4d7341542 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -244,7 +244,7 @@ contains ! Print information on lattice if (p % coord(i) % lattice /= NONE) then - l => lattices(p % coord(i) % lattice) % obj + l => lattices(p % coord(i) % lattice) write(ou,*) ' Lattice = ' // trim(to_str(l % id())) write(ou,*) ' Lattice position = (' // trim(to_str(& p % coord(i) % lattice_x)) // ',' // trim(to_str(& diff --git a/src/surface.cpp b/src/surface.cpp index 421c43d485..5ae3900357 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -1228,17 +1228,6 @@ extern "C" { uvw[2] = u.z; } - void surface_normal(Surface* surf, double xyz[3], double uvw[3]) - { - Position r {xyz}; - Direction u = surf->normal(r); - uvw[0] = u.x; - uvw[1] = u.y; - uvw[2] = u.z; - } - - void surface_to_hdf5(Surface* surf, hid_t group) {surf->to_hdf5(group);} - int surface_i_periodic(PeriodicSurface* surf) {return surf->i_periodic;} bool diff --git a/src/surface_header.F90 b/src/surface_header.F90 index 401ac90aae..9d7e114613 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -38,23 +38,6 @@ module surface_header real(C_DOUBLE), intent(inout) :: uvw(3); end subroutine surface_reflect_c - pure subroutine surface_normal_c(surf_ptr, xyz, uvw) & - bind(C, name='surface_normal') - use ISO_C_BINDING - implicit none - type(C_PTR), intent(in), value :: surf_ptr - real(C_DOUBLE), intent(in) :: xyz(3); - real(C_DOUBLE), intent(out) :: uvw(3); - end subroutine surface_normal_c - - subroutine surface_to_hdf5_c(surf_ptr, group) & - bind(C, name='surface_to_hdf5') - import C_PTR, HID_T - implicit none - type(C_PTR), intent(in), value :: surf_ptr - integer(HID_T), intent(in), value :: group - end subroutine surface_to_hdf5_c - pure function surface_i_periodic_c(surf_ptr) & bind(C, name="surface_i_periodic") result(i_periodic) use ISO_C_BINDING @@ -91,8 +74,6 @@ module surface_header procedure :: id => surface_id procedure :: bc => surface_bc procedure :: reflect => surface_reflect - procedure :: normal => surface_normal - procedure :: to_hdf5 => surface_to_hdf5 procedure :: i_periodic => surface_i_periodic procedure :: periodic_translate => surface_periodic @@ -126,19 +107,6 @@ contains call surface_reflect_c(this % ptr, xyz, uvw) end subroutine surface_reflect - pure subroutine surface_normal(this, xyz, uvw) - class(Surface), intent(in) :: this - real(C_DOUBLE), intent(in) :: xyz(3); - real(C_DOUBLE), intent(out) :: uvw(3); - call surface_normal_c(this % ptr, xyz, uvw) - end subroutine surface_normal - - subroutine surface_to_hdf5(this, group) - class(Surface), intent(in) :: this - integer(HID_T), intent(in) :: group - call surface_to_hdf5_c(this % ptr, group) - end subroutine surface_to_hdf5 - pure function surface_i_periodic(this) result(i_periodic) class(Surface), intent(in) :: this integer(C_INT) :: i_periodic diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index 48b223a439..ae4e09023d 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -61,12 +61,11 @@ contains offset = offset + cells(p % coord(i) % cell + 1) & % offset(distribcell_index-1) elseif (cells(p % coord(i) % cell + 1) % type() == FILL_LATTICE) then - if (lattices(p % coord(i + 1) % lattice) % obj & - % are_valid_indices([& + if (lattices(p % coord(i + 1) % lattice) % are_valid_indices([& p % coord(i + 1) % lattice_x, & p % coord(i + 1) % lattice_y, & p % coord(i + 1) % lattice_z])) then - offset = offset + lattices(p % coord(i + 1) % lattice) % obj & + offset = offset + lattices(p % coord(i + 1) % lattice) & % offset(distribcell_index - 1, & [p % coord(i + 1) % lattice_x, & p % coord(i + 1) % lattice_y, & From de38aa5a63d01d664dc53098b1f628d08c2c0530 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 27 Aug 2018 17:07:22 -0400 Subject: [PATCH 39/43] Address #1061 comments --- docs/source/io_formats/geometry.rst | 2 +- include/openmc/cell.h | 2 +- include/openmc/geometry.h | 16 ++++++++++++- include/openmc/position.h | 8 ------- include/openmc/settings.h | 2 -- include/openmc/simulation.h | 3 ++- openmc/cell.py | 2 +- src/cell.cpp | 2 +- src/geometry.cpp | 37 +++++++++++++---------------- src/output.cpp | 12 +++++----- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/source/io_formats/geometry.rst b/docs/source/io_formats/geometry.rst index 16ce8e6553..94511842dc 100644 --- a/docs/source/io_formats/geometry.rst +++ b/docs/source/io_formats/geometry.rst @@ -201,7 +201,7 @@ Each ```` element can have the following attributes or sub-elements: .. math:: - \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\theta \sin\psi + + \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\phi \sin\psi + \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi + \cos\phi \sin\theta \cos\psi \\ \cos\theta \sin\psi & \cos\phi \cos\psi + \sin\phi \sin\theta \sin\psi & -\sin\phi \cos\psi + \cos\phi \sin\theta \sin\psi \\ diff --git a/include/openmc/cell.h b/include/openmc/cell.h index c9227c7d6b..0334740256 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -7,10 +7,10 @@ #include #include -#include "constants.h" #include "hdf5.h" #include "pugixml.hpp" +#include "openmc/constants.h" #include "openmc/position.h" diff --git a/include/openmc/geometry.h b/include/openmc/geometry.h index 742818579b..f045209ee8 100644 --- a/include/openmc/geometry.h +++ b/include/openmc/geometry.h @@ -4,10 +4,15 @@ #include #include -#include "particle.h" +#include "openmc/particle.h" + namespace openmc { +//============================================================================== +// Global variables +//============================================================================== + extern "C" int openmc_root_universe; extern std::vector overlap_check_count; @@ -21,6 +26,15 @@ check_cell_overlap(Particle* p); //============================================================================== //! Locate a particle in the geometry tree and set its geometry data fields. +//! +//! \param p A particle to be located. This function will populate the +//! geometry-dependent data fields of the particle. +//! \param search_surf A surface that the particle is expected to be on. This +//! value should be the signed, 1-based index of a surface. If positive, the +//! cells on the positive half-space of the surface will be searched. If +//! negative, the negative half-space will be searched. +//! \return True if the particle's location could be found and ascribed to a +//! valid geometry coordinate stack. //============================================================================== extern "C" bool diff --git a/include/openmc/position.h b/include/openmc/position.h index 62af3a1224..97ab6f0e66 100644 --- a/include/openmc/position.h +++ b/include/openmc/position.h @@ -68,17 +68,9 @@ inline Position operator*(double a, Position b) { return b *= a; } inline bool operator==(Position a, Position b) {return a.x == b.x && a.y == b.y && a.z == b.z;} -inline bool operator==(Position a, double b) -{return a.x == b && a.y == b && a.z == b;} -inline bool operator==(double a, Position b) -{return a == b.x && a == b.y && a == b.z;} inline bool operator!=(Position a, Position b) {return a.x != b.x || a.y != b.y || a.z != b.z;} -inline bool operator!=(Position a, double b) -{return a.x != b || a.y != b || a.z != b;} -inline bool operator!=(double a, Position b) -{return a != b.x || a != b.y || a != b.z;} //============================================================================== //! Type representing a vector direction in Cartesian coordinates diff --git a/include/openmc/settings.h b/include/openmc/settings.h index d3b964ac27..66c6b53c07 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -19,11 +19,9 @@ namespace openmc { extern "C" bool openmc_check_overlaps; extern "C" bool openmc_particle_restart_run; extern "C" bool openmc_restart_run; -extern "C" bool openmc_trace; extern "C" int openmc_verbosity; extern "C" bool openmc_write_all_tracks; extern "C" double temperature_default; -#pragma omp threadprivate(openmc_trace) // Defined in .cpp // TODO: Make strings instead of char* once Fortran is gone diff --git a/include/openmc/simulation.h b/include/openmc/simulation.h index 14bb56f27b..b3239be689 100644 --- a/include/openmc/simulation.h +++ b/include/openmc/simulation.h @@ -7,7 +7,8 @@ extern "C" int openmc_current_batch; extern "C" int openmc_current_gen; extern "C" int64_t openmc_current_work; extern "C" int openmc_n_lost_particles; +extern "C" bool openmc_trace; -#pragma omp threadprivate(openmc_current_work) +#pragma omp threadprivate(openmc_current_work, openmc_trace) #endif // OPENMC_SIMULATION_H diff --git a/openmc/cell.py b/openmc/cell.py index 492bdeeb68..8503deffa1 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -57,7 +57,7 @@ class Cell(IDManagerMixin): .. math:: - \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\theta \sin\psi + \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\phi \sin\psi + \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi + \cos\phi \sin\theta \cos\psi \\ \cos\theta \sin\psi & \cos\phi \cos\psi + \sin\phi \sin\theta \sin\psi & -\sin\phi \cos\psi + \cos\phi diff --git a/src/cell.cpp b/src/cell.cpp index ed82da15bb..956fff6e9f 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -494,7 +494,7 @@ Cell::to_hdf5(hid_t cells_group) const } else if (type == FILL_UNIVERSE) { write_dataset(group, "fill_type", "universe"); write_dataset(group, "fill", global_universes[fill]->id); - if (translation != 0) { + if (translation != Position(0, 0, 0)) { write_dataset(group, "translation", translation); } if (!rotation.empty()) { diff --git a/src/geometry.cpp b/src/geometry.cpp index d9b9642f52..6815260972 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -7,7 +7,7 @@ #include "openmc/constants.h" #include "openmc/error.h" #include "openmc/lattice.h" -#include "openmc/settings.h" +#include "openmc/simulation.h" #include "openmc/surface.h" @@ -23,16 +23,14 @@ extern "C" bool check_cell_overlap(Particle* p) { int n_coord = p->n_coord; - // loop through each coordinate level + // Loop through each coordinate level for (int j = 0; j < n_coord; j++) { Universe& univ = *global_universes[p->coord[j].universe]; int n = univ.cells.size(); - // loop through each cell on this level - for (int i = 0; i < n; i++) { - int index_cell = univ.cells[i]; + // Loop through each cell on this level + for (auto index_cell : univ.cells) { Cell& c = *global_cells[index_cell]; - if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { if (index_cell != p->coord[j].cell) { std::stringstream err_msg; @@ -65,26 +63,23 @@ find_cell(Particle* p, int search_surf) { } // If a surface was indicated, only search cells from the neighbor list of - // that surface. - int* search_cells; - int n_search_cells; + // that surface. The surface index is signed, and the sign signifies whether + // the positive or negative side of the surface should be searched. + const std::vector* search_cells; if (search_surf > 0) { - search_cells = global_surfaces[search_surf-1]->neighbor_pos.data(); - n_search_cells = global_surfaces[search_surf-1]->neighbor_pos.size(); + search_cells = &global_surfaces[search_surf-1]->neighbor_pos; } else if (search_surf < 0) { - search_cells = global_surfaces[-search_surf-1]->neighbor_neg.data(); - n_search_cells = global_surfaces[-search_surf-1]->neighbor_neg.size(); + search_cells = &global_surfaces[-search_surf-1]->neighbor_neg; } else { // No surface was indicated, search all cells in the universe. - search_cells = global_universes[i_universe]->cells.data(); - n_search_cells = global_universes[i_universe]->cells.size(); + search_cells = &global_universes[i_universe]->cells; } // Find which cell of this universe the particle is in. bool found = false; int32_t i_cell; - for (int i = 0; i < n_search_cells; i++) { - i_cell = search_cells[i]; + for (int i = 0; i < search_cells->size(); i++) { + i_cell = (*search_cells)[i]; // Make sure the search cell is in the same universe. if (global_cells[i_cell]->universe != i_universe) continue; @@ -155,6 +150,8 @@ find_cell(Particle* p, int search_surf) { p->sqrtkT = c.sqrtkT[0]; } + return true; + } else if (c.type == FILL_UNIVERSE) { //======================================================================== //! Found a lower universe, update this coord level then search the next. @@ -198,7 +195,7 @@ find_cell(Particle* p, int search_surf) { // Update the coordinate level and recurse. ++p->n_coord; - find_cell(p, 0); + return find_cell(p, 0); } else if (c.type == FILL_LATTICE) { //======================================================================== @@ -245,11 +242,9 @@ find_cell(Particle* p, int search_surf) { // Update the coordinate level and recurse. ++p->n_coord; - find_cell(p, 0); + return find_cell(p, 0); } } - - return found; } //============================================================================== diff --git a/src/output.cpp b/src/output.cpp index 89b4c85577..b8530dd3bc 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -46,29 +46,29 @@ print_overlap_check() { #ifdef OPENMC_MPI std::vector temp(overlap_check_count); int err = MPI_Reduce(temp.data(), overlap_check_count.data(), - overlap_check_count.size(), MPI_LONG, MPI_SUM, 0, + overlap_check_count.size(), MPI_INT64_T, MPI_SUM, 0, mpi::intracomm); #endif if (openmc_master) { header("cell overlap check summary", 1); - std::cout << " Cell ID No. Overlap Checks" << std::endl; + std::cout << " Cell ID No. Overlap Checks\n"; std::vector sparse_cell_ids; for (int i = 0; i < n_cells; i++) { std::cout << " " << std::setw(8) << global_cells[i]->id << std::setw(17) - << overlap_check_count[i] << std::endl;; + << overlap_check_count[i] << "\n"; if (overlap_check_count[i] < 10) { sparse_cell_ids.push_back(global_cells[i]->id); } } - std::cout << std::endl << " There were " << sparse_cell_ids.size() - << " cells with less than 10 overlap checks" << std::endl; + std::cout << "\n There were " << sparse_cell_ids.size() + << " cells with less than 10 overlap checks\n"; for (auto id : sparse_cell_ids) { std::cout << " " << id; } - std::cout << std::endl; + std::cout << "\n"; } } From 260bf843e85e3cb3d8c4f90ea84771c9004dcaaf Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 27 Aug 2018 18:45:02 -0400 Subject: [PATCH 40/43] Add trailing underscores to class attributes --- include/openmc/cell.h | 34 ++-- include/openmc/lattice.h | 72 ++++----- include/openmc/surface.h | 40 +++-- src/cell.cpp | 218 +++++++++++++------------- src/geometry.cpp | 98 ++++++------ src/geometry_aux.cpp | 176 ++++++++++----------- src/lattice.cpp | 328 +++++++++++++++++++-------------------- src/output.cpp | 4 +- src/surface.cpp | 258 +++++++++++++++--------------- 9 files changed, 612 insertions(+), 616 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 0334740256..fddfb1adb5 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -53,8 +53,8 @@ extern std::unordered_map universe_map; class Universe { public: - int32_t id; //!< Unique ID - std::vector cells; //!< Cells within this universe + int32_t id_; //!< Unique ID + std::vector cells_; //!< Cells within this universe //! \brief Write universe information to an HDF5 group. //! \param group_id An HDF5 group id. @@ -68,34 +68,34 @@ public: class Cell { public: - int32_t id; //!< Unique ID - std::string name; //!< User-defined name - int type; //!< Material, universe, or lattice - int32_t universe; //!< Universe # this cell is in - int32_t fill; //!< Universe # filling this cell - int32_t n_instances{0}; //!< Number of instances of this cell + int32_t id_; //!< Unique ID + std::string name_; //!< User-defined name + int type_; //!< Material, universe, or lattice + int32_t universe_; //!< Universe # this cell is in + 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}; + int distribcell_index_{C_NONE}; //! \brief Material(s) within this cell. //! //! May be multiple materials for distribcell. - std::vector material; + std::vector material_; //! \brief Temperature(s) within this cell. //! //! The stored values are actually sqrt(k_Boltzmann * T) for each temperature //! T. The units are sqrt(eV). - std::vector sqrtkT; + std::vector sqrtkT_; //! Definition of spatial region as Boolean expression of half-spaces - std::vector region; + std::vector region_; //! Reverse Polish notation for region expression - std::vector rpn; - bool simple; //!< Does the region contain only intersections? + std::vector rpn_; + bool simple_; //!< Does the region contain only intersections? - Position translation {0, 0, 0}; //!< Translation vector for filled universe + Position translation_ {0, 0, 0}; //!< Translation vector for filled universe //! \brief Rotational tranfsormation of the filled universe. // @@ -103,9 +103,9 @@ public: //! values are the rotation angles respectively about the x-, y-, and z-, axes //! in degrees. The next 9 values give the rotation matrix in row-major //! order. - std::vector rotation; + std::vector rotation_; - std::vector offset; //!< Distribcell offset table + std::vector offset_; //!< Distribcell offset table Cell() {}; diff --git a/include/openmc/lattice.h b/include/openmc/lattice.h index 04381d2189..10f6b46179 100644 --- a/include/openmc/lattice.h +++ b/include/openmc/lattice.h @@ -46,12 +46,12 @@ class ReverseLatticeIter; class Lattice { public: - int32_t id; //!< Universe ID number - std::string name; //!< User-defined name - LatticeType type; - std::vector universes; //!< Universes filling each lattice tile - int32_t outer {NO_OUTER_UNIVERSE}; //!< Universe tiled outside the lattice - std::vector offsets; //!< Distribcell offset table + int32_t id_; //!< Universe ID number + std::string name_; //!< User-defined name + LatticeType type_; + std::vector universes_; //!< Universes filling each lattice tile + int32_t outer_ {NO_OUTER_UNIVERSE}; //!< Universe tiled outside the lattice + std::vector offsets_; //!< Distribcell offset table explicit Lattice(pugi::xml_node lat_node); @@ -70,7 +70,7 @@ public: //! Allocate offset table for distribcell. void allocate_offset_table(int n_maps) - {offsets.resize(n_maps * universes.size(), C_NONE);} + {offsets_.resize(n_maps * universes_.size(), C_NONE);} //! Populate the distribcell offset tables. int32_t fill_offset_table(int32_t offset, int32_t target_univ_id, int map); @@ -115,7 +115,7 @@ public: //! \return true if the given index fit within the lattice bounds. False //! otherwise. virtual bool is_valid_index(int indx) const - {return (indx >= 0) && (indx < universes.size());} + {return (indx >= 0) && (indx < universes_.size());} //! \brief Get the distribcell offset for a lattice tile. //! \param The map index for the target cell. @@ -134,7 +134,7 @@ public: void to_hdf5(hid_t group_id) const; protected: - bool is_3d; //!< Has divisions along the z-axis? + bool is_3d_; //!< Has divisions along the z-axis? virtual void to_hdf5_inner(hid_t group_id) const = 0; }; @@ -146,31 +146,31 @@ protected: class LatticeIter { public: - int indx; //!< An index to a Lattice universes or offsets array. + int indx_; //!< An index to a Lattice universes or offsets array. - LatticeIter(Lattice &lat_, int indx_) - : lat(lat_), - indx(indx_) + LatticeIter(Lattice &lat, int indx) + : lat_(lat), + indx_(indx) {} - bool operator==(const LatticeIter &rhs) {return (indx == rhs.indx);} + bool operator==(const LatticeIter &rhs) {return (indx_ == rhs.indx_);} bool operator!=(const LatticeIter &rhs) {return !(*this == rhs);} - int32_t& operator*() {return lat.universes[indx];} + int32_t& operator*() {return lat_.universes_[indx_];} LatticeIter& operator++() { - while (indx < lat.universes.size()) { - ++indx; - if (lat.is_valid_index(indx)) return *this; + while (indx_ < lat_.universes_.size()) { + ++indx_; + if (lat_.is_valid_index(indx_)) return *this; } - indx = lat.universes.size(); + indx_ = lat_.universes_.size(); return *this; } protected: - Lattice ⪫ + Lattice& lat_; }; //============================================================================== @@ -180,17 +180,17 @@ protected: class ReverseLatticeIter : public LatticeIter { public: - ReverseLatticeIter(Lattice &lat_, int indx_) - : LatticeIter {lat_, indx_} + ReverseLatticeIter(Lattice &lat, int indx) + : LatticeIter {lat, indx} {} ReverseLatticeIter& operator++() { - while (indx > -1) { - --indx; - if (lat.is_valid_index(indx)) return *this; + while (indx_ > -1) { + --indx_; + if (lat_.is_valid_index(indx_)) return *this; } - indx = -1; + indx_ = -1; return *this; } }; @@ -221,14 +221,14 @@ public: void to_hdf5_inner(hid_t group_id) const; private: - std::array n_cells; //!< Number of cells along each axis - Position lower_left; //!< Global lower-left corner of the lattice - Position pitch; //!< Lattice tile width along each axis + std::array n_cells_; //!< Number of cells along each axis + Position lower_left_; //!< Global lower-left corner of the lattice + Position pitch_; //!< Lattice tile width along each axis // Convenience aliases - int &nx {n_cells[0]}; - int &ny {n_cells[1]}; - int &nz {n_cells[2]}; + int &nx {n_cells_[0]}; + int &ny {n_cells_[1]}; + int &nz {n_cells_[2]}; }; //============================================================================== @@ -263,10 +263,10 @@ public: void to_hdf5_inner(hid_t group_id) const; private: - int n_rings; //!< Number of radial tile positions - int n_axial; //!< Number of axial tile positions - Position center; //!< Global center of lattice - std::array pitch; //!< Lattice tile width and height + int n_rings_; //!< Number of radial tile positions + int n_axial_; //!< Number of axial tile positions + Position center_; //!< Global center of lattice + std::array pitch_; //!< Lattice tile width and height }; } // namespace openmc diff --git a/include/openmc/surface.h b/include/openmc/surface.h index df149b4a2f..16f75b907b 100644 --- a/include/openmc/surface.h +++ b/include/openmc/surface.h @@ -57,12 +57,12 @@ struct BoundingBox class Surface { public: - int id; //!< Unique ID - int bc; //!< Boundary condition - std::string name; //!< User-defined name + int id_; //!< Unique ID + int bc_; //!< Boundary condition + std::string name_; //!< User-defined name - std::vector neighbor_pos; //!< List of cells on positive side - std::vector neighbor_neg; //!< List of cells on negative side + std::vector neighbor_pos_; //!< List of cells on positive side + std::vector neighbor_neg_; //!< List of cells on negative side explicit Surface(pugi::xml_node surf_node); @@ -121,7 +121,7 @@ protected: class PeriodicSurface : public Surface { public: - int i_periodic{C_NONE}; //!< Index of corresponding periodic surface + int i_periodic_{C_NONE}; //!< Index of corresponding periodic surface explicit PeriodicSurface(pugi::xml_node surf_node); @@ -148,7 +148,7 @@ public: class SurfaceXPlane : public PeriodicSurface { - double x0; + double x0_; public: explicit SurfaceXPlane(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -168,7 +168,7 @@ public: class SurfaceYPlane : public PeriodicSurface { - double y0; + double y0_; public: explicit SurfaceYPlane(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -188,7 +188,7 @@ public: class SurfaceZPlane : public PeriodicSurface { - double z0; + double z0_; public: explicit SurfaceZPlane(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -208,7 +208,7 @@ public: class SurfacePlane : public PeriodicSurface { - double A, B, C, D; + double A_, B_, C_, D_; public: explicit SurfacePlane(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -229,7 +229,7 @@ public: class SurfaceXCylinder : public Surface { - double y0, z0, radius; + double y0_, z0_, radius_; public: explicit SurfaceXCylinder(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -247,7 +247,7 @@ public: class SurfaceYCylinder : public Surface { - double x0, z0, radius; + double x0_, z0_, radius_; public: explicit SurfaceYCylinder(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -265,7 +265,7 @@ public: class SurfaceZCylinder : public Surface { - double x0, y0, radius; + double x0_, y0_, radius_; public: explicit SurfaceZCylinder(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -283,7 +283,7 @@ public: class SurfaceSphere : public Surface { - double x0, y0, z0, radius; + double x0_, y0_, z0_, radius_; public: explicit SurfaceSphere(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -301,7 +301,7 @@ public: class SurfaceXCone : public Surface { - double x0, y0, z0, radius_sq; + double x0_, y0_, z0_, radius_sq_; public: explicit SurfaceXCone(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -319,7 +319,7 @@ public: class SurfaceYCone : public Surface { - double x0, y0, z0, radius_sq; + double x0_, y0_, z0_, radius_sq_; public: explicit SurfaceYCone(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -337,7 +337,7 @@ public: class SurfaceZCone : public Surface { - double x0, y0, z0, radius_sq; + double x0_, y0_, z0_, radius_sq_; public: explicit SurfaceZCone(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -355,7 +355,7 @@ public: class SurfaceQuadric : public Surface { // Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 - double A, B, C, D, E, F, G, H, J, K; + double A_, B_, C_, D_, E_, F_, G_, H_, J_, K_; public: explicit SurfaceQuadric(pugi::xml_node surf_node); double evaluate(Position r) const; @@ -374,10 +374,6 @@ extern "C" { int surface_bc(Surface* surf); bool surface_sense(Surface* surf, double xyz[3], double uvw[3]); void surface_reflect(Surface* surf, double xyz[3], double uvw[3]); - double surface_distance(Surface* surf, double xyz[3], double uvw[3], - bool coincident); - void surface_normal(Surface* surf, double xyz[3], double uvw[3]); - void surface_to_hdf5(Surface* surf, hid_t group); int surface_i_periodic(PeriodicSurface* surf); bool surface_periodic(PeriodicSurface* surf, PeriodicSurface* other, double xyz[3], double uvw[3]); diff --git a/src/cell.cpp b/src/cell.cpp index 956fff6e9f..c6b39f314d 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -192,13 +192,13 @@ Universe::to_hdf5(hid_t universes_group) const { // Create a group for this universe. std::stringstream group_name; - group_name << "universe " << id; + group_name << "universe " << id_; auto group = create_group(universes_group, group_name); // Write the contained cells. - if (cells.size() > 0) { + if (cells_.size() > 0) { std::vector cell_ids; - for (auto i_cell : cells) cell_ids.push_back(global_cells[i_cell]->id); + for (auto i_cell : cells_) cell_ids.push_back(global_cells[i_cell]->id_); write_dataset(group, "cells", cell_ids); } @@ -212,19 +212,19 @@ Universe::to_hdf5(hid_t universes_group) const Cell::Cell(pugi::xml_node cell_node) { if (check_for_node(cell_node, "id")) { - id = std::stoi(get_node_value(cell_node, "id")); + id_ = std::stoi(get_node_value(cell_node, "id")); } else { fatal_error("Must specify id of cell in geometry XML file."); } if (check_for_node(cell_node, "name")) { - name = get_node_value(cell_node, "name"); + name_ = get_node_value(cell_node, "name"); } if (check_for_node(cell_node, "universe")) { - universe = std::stoi(get_node_value(cell_node, "universe")); + universe_ = std::stoi(get_node_value(cell_node, "universe")); } else { - universe = 0; + universe_ = 0; } // Make sure that either material or fill was specified, but not both. @@ -232,20 +232,20 @@ Cell::Cell(pugi::xml_node cell_node) bool material_present = check_for_node(cell_node, "material"); if (!(fill_present || material_present)) { std::stringstream err_msg; - err_msg << "Neither material nor fill was specified for cell " << id; + err_msg << "Neither material nor fill was specified for cell " << id_; fatal_error(err_msg); } if (fill_present && material_present) { std::stringstream err_msg; - err_msg << "Cell " << id << " has both a material and a fill specified; " + err_msg << "Cell " << id_ << " has both a material and a fill specified; " << "only one can be specified per cell"; fatal_error(err_msg); } if (fill_present) { - fill = std::stoi(get_node_value(cell_node, "fill")); + fill_ = std::stoi(get_node_value(cell_node, "fill")); } else { - fill = C_NONE; + fill_ = C_NONE; } // Read the material element. There can be zero materials (filled with a @@ -255,47 +255,47 @@ Cell::Cell(pugi::xml_node cell_node) std::vector mats {get_node_array(cell_node, "material", true)}; if (mats.size() > 0) { - material.reserve(mats.size()); + material_.reserve(mats.size()); for (std::string mat : mats) { if (mat.compare("void") == 0) { - material.push_back(MATERIAL_VOID); + material_.push_back(MATERIAL_VOID); } else { - material.push_back(std::stoi(mat)); + material_.push_back(std::stoi(mat)); } } } else { std::stringstream err_msg; - err_msg << "An empty material element was specified for cell " << id; + err_msg << "An empty material element was specified for cell " << id_; fatal_error(err_msg); } } // Read the temperature element which may be distributed like materials. if (check_for_node(cell_node, "temperature")) { - sqrtkT = get_node_array(cell_node, "temperature"); - sqrtkT.shrink_to_fit(); + sqrtkT_ = get_node_array(cell_node, "temperature"); + sqrtkT_.shrink_to_fit(); // Make sure this is a material-filled cell. - if (material.size() == 0) { + if (material_.size() == 0) { std::stringstream err_msg; - err_msg << "Cell " << id << " was specified with a temperature but " + err_msg << "Cell " << id_ << " was specified with a temperature but " "no material. Temperature specification is only valid for cells " "filled with a material."; fatal_error(err_msg); } // Make sure all temperatures are non-negative. - for (auto T : sqrtkT) { + for (auto T : sqrtkT_) { if (T < 0) { std::stringstream err_msg; - err_msg << "Cell " << id + err_msg << "Cell " << id_ << " was specified with a negative temperature"; fatal_error(err_msg); } } // Convert to sqrt(k*T). - for (auto& T : sqrtkT) { + for (auto& T : sqrtkT_) { T = std::sqrt(K_BOLTZMANN * T); } } @@ -307,34 +307,34 @@ Cell::Cell(pugi::xml_node cell_node) } // Get a tokenized representation of the region specification. - region = tokenize(region_spec); - region.shrink_to_fit(); + region_ = tokenize(region_spec); + region_.shrink_to_fit(); // Convert user IDs to surface indices. - for (auto &r : region) { + for (auto& r : region_) { if (r < OP_UNION) { r = copysign(surface_map[abs(r)] + 1, r); } } // Convert the infix region spec to RPN. - rpn = generate_rpn(id, region); - rpn.shrink_to_fit(); + rpn_ = generate_rpn(id_, region_); + rpn_.shrink_to_fit(); // Check if this is a simple cell. - simple = true; - for (int32_t token : rpn) { + simple_ = true; + for (int32_t token : rpn_) { if ((token == OP_COMPLEMENT) || (token == OP_UNION)) { - simple = false; + simple_ = false; break; } } // Read the translation vector. if (check_for_node(cell_node, "translation")) { - if (fill == C_NONE) { + if (fill_ == C_NONE) { std::stringstream err_msg; - err_msg << "Cannot apply a translation to cell " << id + err_msg << "Cannot apply a translation to cell " << id_ << " because it is not filled with another universe"; fatal_error(err_msg); } @@ -342,17 +342,17 @@ Cell::Cell(pugi::xml_node cell_node) auto xyz {get_node_array(cell_node, "translation")}; if (xyz.size() != 3) { std::stringstream err_msg; - err_msg << "Non-3D translation vector applied to cell " << id; + err_msg << "Non-3D translation vector applied to cell " << id_; fatal_error(err_msg); } - translation = xyz; + translation_ = xyz; } // Read the rotation transform. if (check_for_node(cell_node, "rotation")) { - if (fill == C_NONE) { + if (fill_ == C_NONE) { std::stringstream err_msg; - err_msg << "Cannot apply a rotation to cell " << id + err_msg << "Cannot apply a rotation to cell " << id_ << " because it is not filled with another universe"; fatal_error(err_msg); } @@ -360,33 +360,33 @@ Cell::Cell(pugi::xml_node cell_node) auto rot {get_node_array(cell_node, "rotation")}; if (rot.size() != 3) { std::stringstream err_msg; - err_msg << "Non-3D rotation vector applied to cell " << id; + err_msg << "Non-3D rotation vector applied to cell " << id_; fatal_error(err_msg); } // Store the rotation angles. - rotation.reserve(12); - rotation.push_back(rot[0]); - rotation.push_back(rot[1]); - rotation.push_back(rot[2]); + rotation_.reserve(12); + rotation_.push_back(rot[0]); + rotation_.push_back(rot[1]); + rotation_.push_back(rot[2]); // Compute and store the rotation matrix. auto phi = -rot[0] * PI / 180.0; auto theta = -rot[1] * PI / 180.0; auto psi = -rot[2] * PI / 180.0; - rotation.push_back(std::cos(theta) * std::cos(psi)); - rotation.push_back(-std::cos(phi) * std::sin(psi) - + std::sin(phi) * std::sin(theta) * std::cos(psi)); - rotation.push_back(std::sin(phi) * std::sin(psi) - + std::cos(phi) * std::sin(theta) * std::cos(psi)); - rotation.push_back(std::cos(theta) * std::sin(psi)); - rotation.push_back(std::cos(phi) * std::cos(psi) - + std::sin(phi) * std::sin(theta) * std::sin(psi)); - rotation.push_back(-std::sin(phi) * std::cos(psi) - + std::cos(phi) * std::sin(theta) * std::sin(psi)); - rotation.push_back(-std::sin(theta)); - rotation.push_back(std::sin(phi) * std::cos(theta)); - rotation.push_back(std::cos(phi) * std::cos(theta)); + rotation_.push_back(std::cos(theta) * std::cos(psi)); + rotation_.push_back(-std::cos(phi) * std::sin(psi) + + std::sin(phi) * std::sin(theta) * std::cos(psi)); + rotation_.push_back(std::sin(phi) * std::sin(psi) + + std::cos(phi) * std::sin(theta) * std::cos(psi)); + rotation_.push_back(std::cos(theta) * std::sin(psi)); + rotation_.push_back(std::cos(phi) * std::cos(psi) + + std::sin(phi) * std::sin(theta) * std::sin(psi)); + rotation_.push_back(-std::sin(phi) * std::cos(psi) + + std::cos(phi) * std::sin(theta) * std::sin(psi)); + rotation_.push_back(-std::sin(theta)); + rotation_.push_back(std::sin(phi) * std::cos(theta)); + rotation_.push_back(std::cos(phi) * std::cos(theta)); } } @@ -395,7 +395,7 @@ Cell::Cell(pugi::xml_node cell_node) bool Cell::contains(Position r, Direction u, int32_t on_surface) const { - if (simple) { + if (simple_) { return contains_simple(r, u, on_surface); } else { return contains_complex(r, u, on_surface); @@ -410,7 +410,7 @@ Cell::distance(Position r, Direction u, int32_t on_surface) const double min_dist {INFTY}; int32_t i_surf {std::numeric_limits::max()}; - for (int32_t token : rpn) { + for (int32_t token : rpn_) { // Ignore this token if it corresponds to an operator rather than a region. if (token >= OP_UNION) continue; @@ -438,19 +438,19 @@ Cell::to_hdf5(hid_t cells_group) const { // Create a group for this cell. std::stringstream group_name; - group_name << "cell " << id; + group_name << "cell " << id_; auto group = create_group(cells_group, group_name); - if (!name.empty()) { - write_string(group, "name", name, false); + if (!name_.empty()) { + write_string(group, "name", name_, false); } - write_dataset(group, "universe", global_universes[universe]->id); + write_dataset(group, "universe", global_universes[universe_]->id_); // Write the region specification. - if (!region.empty()) { + if (!region_.empty()) { std::stringstream region_spec {}; - for (int32_t token : region) { + for (int32_t token : region_) { if (token == OP_LEFT_PAREN) { region_spec << " ("; } else if (token == OP_RIGHT_PAREN) { @@ -463,17 +463,17 @@ Cell::to_hdf5(hid_t cells_group) const } else { // Note the off-by-one indexing region_spec << " " - << copysign(global_surfaces[abs(token)-1]->id, token); + << copysign(global_surfaces[abs(token)-1]->id_, token); } } write_string(group, "region", region_spec.str(), false); } // Write fill information. - if (type == FILL_MATERIAL) { + if (type_ == FILL_MATERIAL) { write_dataset(group, "fill_type", "material"); std::vector mat_ids; - for (auto i_mat : material) { + for (auto i_mat : material_) { if (i_mat != MATERIAL_VOID) { mat_ids.push_back(global_materials[i_mat]->id); } else { @@ -487,24 +487,24 @@ Cell::to_hdf5(hid_t cells_group) const } std::vector temps; - for (auto sqrtkT_val : sqrtkT) + for (auto sqrtkT_val : sqrtkT_) temps.push_back(sqrtkT_val * sqrtkT_val / K_BOLTZMANN); write_dataset(group, "temperature", temps); - } else if (type == FILL_UNIVERSE) { + } else if (type_ == FILL_UNIVERSE) { write_dataset(group, "fill_type", "universe"); - write_dataset(group, "fill", global_universes[fill]->id); - if (translation != Position(0, 0, 0)) { - write_dataset(group, "translation", translation); + write_dataset(group, "fill", global_universes[fill_]->id_); + if (translation_ != Position(0, 0, 0)) { + write_dataset(group, "translation", translation_); } - if (!rotation.empty()) { - std::array rot {rotation[0], rotation[1], rotation[2]}; + if (!rotation_.empty()) { + std::array rot {rotation_[0], rotation_[1], rotation_[2]}; write_dataset(group, "rotation", rot); } - } else if (type == FILL_LATTICE) { + } else if (type_ == FILL_LATTICE) { write_dataset(group, "fill_type", "lattice"); - write_dataset(group, "lattice", lattices_c[fill]->id); + write_dataset(group, "lattice", lattices_c[fill_]->id_); } close_group(group); @@ -515,7 +515,7 @@ Cell::to_hdf5(hid_t cells_group) const bool Cell::contains_simple(Position r, Direction u, int32_t on_surface) const { - for (int32_t token : rpn) { + for (int32_t token : rpn_) { if (token < OP_UNION) { // If the token is not an operator, evaluate the sense of particle with // respect to the surface and see if the token matches the sense. If the @@ -541,10 +541,10 @@ Cell::contains_complex(Position r, Direction u, int32_t on_surface) const { // Make a stack of booleans. We don't know how big it needs to be, but we do // know that rpn.size() is an upper-bound. - bool stack[rpn.size()]; + bool stack[rpn_.size()]; int i_stack = -1; - for (int32_t token : rpn) { + for (int32_t token : rpn_) { // If the token is a binary operator (intersection/union), apply it to // the last two items on the stack. If the token is a unary operator // (complement), apply it to the last item on the stack. @@ -606,15 +606,15 @@ read_cells(pugi::xml_node* node) // Populate the Universe vector and map. for (int i = 0; i < global_cells.size(); i++) { - int32_t uid = global_cells[i]->universe; + int32_t uid = global_cells[i]->universe_; auto it = universe_map.find(uid); if (it == universe_map.end()) { global_universes.push_back(new Universe()); - global_universes.back()->id = uid; - global_universes.back()->cells.push_back(i); + global_universes.back()->id_ = uid; + global_universes.back()->cells_.push_back(i); universe_map[uid] = global_universes.size() - 1; } else { - global_universes[it->second]->cells.push_back(i); + global_universes[it->second]->cells_.push_back(i); } } global_universes.shrink_to_fit(); @@ -633,12 +633,12 @@ openmc_cell_get_fill(int32_t index, int* type, int32_t** indices, int32_t* n) if (index >= 1 && index <= global_cells.size()) { //TODO: off-by-one Cell& c {*global_cells[index - 1]}; - *type = c.type; - if (c.type == FILL_MATERIAL) { - *indices = c.material.data(); - *n = c.material.size(); + *type = c.type_; + if (c.type_ == FILL_MATERIAL) { + *indices = c.material_.data(); + *n = c.material_.size(); } else { - *indices = &c.fill; + *indices = &c.fill_; *n = 1; } } else { @@ -656,25 +656,25 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n, //TODO: off-by-one Cell& c {*global_cells[index - 1]}; if (type == FILL_MATERIAL) { - c.type = FILL_MATERIAL; - c.material.clear(); + c.type_ = FILL_MATERIAL; + c.material_.clear(); for (int i = 0; i < n; i++) { int i_mat = indices[i]; if (i_mat == MATERIAL_VOID) { - c.material.push_back(MATERIAL_VOID); + c.material_.push_back(MATERIAL_VOID); } else if (i_mat >= 1 && i_mat <= global_materials.size()) { //TODO: off-by-one - c.material.push_back(i_mat - 1); + c.material_.push_back(i_mat - 1); } else { set_errmsg("Index in materials array is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } } - c.material.shrink_to_fit(); + c.material_.shrink_to_fit(); } else if (type == FILL_UNIVERSE) { - c.type = FILL_UNIVERSE; + c.type_ = FILL_UNIVERSE; } else { - c.type = FILL_LATTICE; + c.type_ = FILL_LATTICE; } } else { set_errmsg("Index in cells array is out of bounds."); @@ -692,14 +692,14 @@ openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) Cell& c {*global_cells[index - 1]}; if (instance) { - if (*instance >= 0 && *instance < c.sqrtkT.size()) { - c.sqrtkT[*instance] = std::sqrt(K_BOLTZMANN * T); + if (*instance >= 0 && *instance < c.sqrtkT_.size()) { + c.sqrtkT_[*instance] = std::sqrt(K_BOLTZMANN * T); } else { strcpy(openmc_err_msg, "Distribcell instance is out of bounds."); return OPENMC_E_OUT_OF_BOUNDS; } } else { - for (auto& T_ : c.sqrtkT) { + for (auto& T_ : c.sqrtkT_) { T_ = std::sqrt(K_BOLTZMANN * T); } } @@ -719,35 +719,35 @@ openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) extern "C" { Cell* cell_pointer(int32_t cell_ind) {return global_cells[cell_ind];} - int32_t cell_id(Cell* c) {return c->id;} + int32_t cell_id(Cell* c) {return c->id_;} - void cell_set_id(Cell* c, int32_t id) {c->id = id;} + void cell_set_id(Cell* c, int32_t id) {c->id_ = id;} - int cell_type(Cell* c) {return c->type;} + int cell_type(Cell* c) {return c->type_;} - int32_t cell_universe(Cell* c) {return c->universe;} + int32_t cell_universe(Cell* c) {return c->universe_;} - int32_t cell_fill(Cell* c) {return c->fill;} + int32_t cell_fill(Cell* c) {return c->fill_;} - int32_t cell_n_instances(Cell* c) {return c->n_instances;} + int32_t cell_n_instances(Cell* c) {return c->n_instances_;} - int cell_distribcell_index(Cell* c) {return c->distribcell_index;} + int cell_distribcell_index(Cell* c) {return c->distribcell_index_;} - int cell_material_size(Cell* c) {return c->material.size();} + int cell_material_size(Cell* c) {return c->material_.size();} //TODO: off-by-one int32_t cell_material(Cell* c, int i) { - int32_t mat = c->material[i-1]; + int32_t mat = c->material_[i-1]; if (mat == MATERIAL_VOID) return MATERIAL_VOID; return mat + 1; } - int cell_sqrtkT_size(Cell* c) {return c->sqrtkT.size();} + int cell_sqrtkT_size(Cell* c) {return c->sqrtkT_.size();} - double cell_sqrtkT(Cell* c, int i) {return c->sqrtkT[i];} + double cell_sqrtkT(Cell* c, int i) {return c->sqrtkT_[i];} - int32_t cell_offset(Cell* c, int map) {return c->offset[map];} + int32_t cell_offset(Cell* c, int map) {return c->offset_[map];} void extend_cells_c(int32_t n) { @@ -758,7 +758,7 @@ extern "C" { n_cells = global_cells.size(); } - int32_t universe_id(int i_univ) {return global_universes[i_univ]->id;} + int32_t universe_id(int i_univ) {return global_universes[i_univ]->id_;} void universes_to_hdf5(hid_t universes_group) {for (Universe* u : global_universes) u->to_hdf5(universes_group);} diff --git a/src/geometry.cpp b/src/geometry.cpp index 6815260972..1999738d51 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -26,17 +26,17 @@ check_cell_overlap(Particle* p) { // Loop through each coordinate level for (int j = 0; j < n_coord; j++) { Universe& univ = *global_universes[p->coord[j].universe]; - int n = univ.cells.size(); + int n = univ.cells_.size(); // Loop through each cell on this level - for (auto index_cell : univ.cells) { + for (auto index_cell : univ.cells_) { Cell& c = *global_cells[index_cell]; if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { if (index_cell != p->coord[j].cell) { std::stringstream err_msg; - err_msg << "Overlapping cells detected: " << c.id << ", " - << global_cells[p->coord[j].cell]->id << " on universe " - << univ.id; + err_msg << "Overlapping cells detected: " << c.id_ << ", " + << global_cells[p->coord[j].cell]->id_ << " on universe " + << univ.id_; fatal_error(err_msg); } ++overlap_check_count[index_cell]; @@ -67,12 +67,12 @@ find_cell(Particle* p, int search_surf) { // the positive or negative side of the surface should be searched. const std::vector* search_cells; if (search_surf > 0) { - search_cells = &global_surfaces[search_surf-1]->neighbor_pos; + search_cells = &global_surfaces[search_surf-1]->neighbor_pos_; } else if (search_surf < 0) { - search_cells = &global_surfaces[-search_surf-1]->neighbor_neg; + search_cells = &global_surfaces[-search_surf-1]->neighbor_neg_; } else { // No surface was indicated, search all cells in the universe. - search_cells = &global_universes[i_universe]->cells; + search_cells = &global_universes[i_universe]->cells_; } // Find which cell of this universe the particle is in. @@ -82,7 +82,7 @@ find_cell(Particle* p, int search_surf) { i_cell = (*search_cells)[i]; // Make sure the search cell is in the same universe. - if (global_cells[i_cell]->universe != i_universe) continue; + if (global_cells[i_cell]->universe_ != i_universe) continue; Position r {p->coord[p->n_coord-1].xyz}; Direction u {p->coord[p->n_coord-1].uvw}; @@ -92,7 +92,7 @@ find_cell(Particle* p, int search_surf) { if (openmc_verbosity >= 10 || openmc_trace) { std::stringstream msg; - msg << " Entering cell " << global_cells[i_cell]->id; + msg << " Entering cell " << global_cells[i_cell]->id_; write_message(msg, 1); } found = true; @@ -102,20 +102,20 @@ find_cell(Particle* p, int search_surf) { if (found) { Cell& c {*global_cells[i_cell]}; - if (c.type == FILL_MATERIAL) { + if (c.type_ == FILL_MATERIAL) { //======================================================================= //! Found a material cell which means this is the lowest coord level. // Find the distribcell instance number. - if (c.material.size() > 1 || c.sqrtkT.size() > 1) { + if (c.material_.size() > 1 || c.sqrtkT_.size() > 1) { //TODO: off-by-one indexing - int distribcell_index = c.distribcell_index - 1; + int distribcell_index = c.distribcell_index_ - 1; int offset = 0; for (int i = 0; i < p->n_coord; i++) { Cell& c_i {*global_cells[p->coord[i].cell]}; - if (c_i.type == FILL_UNIVERSE) { - offset += c_i.offset[distribcell_index]; - } else if (c_i.type == FILL_LATTICE) { + if (c_i.type_ == FILL_UNIVERSE) { + offset += c_i.offset_[distribcell_index]; + } else if (c_i.type_ == FILL_LATTICE) { Lattice& lat {*lattices_c[p->coord[i+1].lattice-1]}; int i_xyz[3] {p->coord[i+1].lattice_x, p->coord[i+1].lattice_y, @@ -133,10 +133,10 @@ find_cell(Particle* p, int search_surf) { // Set the material and temperature. p->last_material = p->material; int32_t mat; - if (c.material.size() > 1) { - mat = c.material[p->cell_instance-1]; + if (c.material_.size() > 1) { + mat = c.material_[p->cell_instance-1]; } else { - mat = c.material[0]; + mat = c.material_[0]; } if (mat == MATERIAL_VOID) { p->material = MATERIAL_VOID; @@ -144,20 +144,20 @@ find_cell(Particle* p, int search_surf) { p->material = mat + 1; } p->last_sqrtkT = p->sqrtkT; - if (c.sqrtkT.size() > 1) { - p->sqrtkT = c.sqrtkT[p->cell_instance-1]; + if (c.sqrtkT_.size() > 1) { + p->sqrtkT = c.sqrtkT_[p->cell_instance-1]; } else { - p->sqrtkT = c.sqrtkT[0]; + p->sqrtkT = c.sqrtkT_[0]; } return true; - } else if (c.type == FILL_UNIVERSE) { + } else if (c.type_ == FILL_UNIVERSE) { //======================================================================== //! Found a lower universe, update this coord level then search the next. // Set the lower coordinate level universe. - p->coord[p->n_coord].universe = c.fill; + p->coord[p->n_coord].universe = c.fill_; // Set the position and direction. for (int i = 0; i < 3; i++) { @@ -166,30 +166,30 @@ find_cell(Particle* p, int search_surf) { } // Apply translation. - p->coord[p->n_coord].xyz[0] -= c.translation.x; - p->coord[p->n_coord].xyz[1] -= c.translation.y; - p->coord[p->n_coord].xyz[2] -= c.translation.z; + p->coord[p->n_coord].xyz[0] -= c.translation_.x; + p->coord[p->n_coord].xyz[1] -= c.translation_.y; + p->coord[p->n_coord].xyz[2] -= c.translation_.z; // Apply rotation. - if (!c.rotation.empty()) { + if (!c.rotation_.empty()) { auto x = p->coord[p->n_coord].xyz[0]; auto y = p->coord[p->n_coord].xyz[1]; auto z = p->coord[p->n_coord].xyz[2]; - p->coord[p->n_coord].xyz[0] = x*c.rotation[3] + y*c.rotation[4] - + z*c.rotation[5]; - p->coord[p->n_coord].xyz[1] = x*c.rotation[6] + y*c.rotation[7] - + z*c.rotation[8]; - p->coord[p->n_coord].xyz[2] = x*c.rotation[9] + y*c.rotation[10] - + z*c.rotation[11]; + p->coord[p->n_coord].xyz[0] = x*c.rotation_[3] + y*c.rotation_[4] + + z*c.rotation_[5]; + p->coord[p->n_coord].xyz[1] = x*c.rotation_[6] + y*c.rotation_[7] + + z*c.rotation_[8]; + p->coord[p->n_coord].xyz[2] = x*c.rotation_[9] + y*c.rotation_[10] + + z*c.rotation_[11]; auto u = p->coord[p->n_coord].uvw[0]; auto v = p->coord[p->n_coord].uvw[1]; auto w = p->coord[p->n_coord].uvw[2]; - p->coord[p->n_coord].uvw[0] = u*c.rotation[3] + v*c.rotation[4] - + w*c.rotation[5]; - p->coord[p->n_coord].uvw[1] = u*c.rotation[6] + v*c.rotation[7] - + w*c.rotation[8]; - p->coord[p->n_coord].uvw[2] = u*c.rotation[9] + v*c.rotation[10] - + w*c.rotation[11]; + p->coord[p->n_coord].uvw[0] = u*c.rotation_[3] + v*c.rotation_[4] + + w*c.rotation_[5]; + p->coord[p->n_coord].uvw[1] = u*c.rotation_[6] + v*c.rotation_[7] + + w*c.rotation_[8]; + p->coord[p->n_coord].uvw[2] = u*c.rotation_[9] + v*c.rotation_[10] + + w*c.rotation_[11]; p->coord[p->n_coord].rotated = true; } @@ -197,11 +197,11 @@ find_cell(Particle* p, int search_surf) { ++p->n_coord; return find_cell(p, 0); - } else if (c.type == FILL_LATTICE) { + } else if (c.type_ == FILL_LATTICE) { //======================================================================== //! Found a lower lattice, update this coord level then search the next. - Lattice& lat {*lattices_c[c.fill]}; + Lattice& lat {*lattices_c[c.fill_]}; // Determine lattice indices. Position r {p->coord[p->n_coord-1].xyz}; @@ -219,7 +219,7 @@ find_cell(Particle* p, int search_surf) { p->coord[p->n_coord].uvw[2] = u.z; // Set lattice indices. - p->coord[p->n_coord].lattice = c.fill + 1; + p->coord[p->n_coord].lattice = c.fill_ + 1; p->coord[p->n_coord].lattice_x = i_xyz[0]; p->coord[p->n_coord].lattice_y = i_xyz[1]; p->coord[p->n_coord].lattice_z = i_xyz[2]; @@ -228,12 +228,12 @@ find_cell(Particle* p, int search_surf) { if (lat.are_valid_indices(i_xyz)) { p->coord[p->n_coord].universe = lat[i_xyz]; } else { - if (lat.outer != NO_OUTER_UNIVERSE) { - p->coord[p->n_coord].universe = lat.outer; + if (lat.outer_ != NO_OUTER_UNIVERSE) { + p->coord[p->n_coord].universe = lat.outer_; } else { std::stringstream err_msg; err_msg << "Particle " << p->id << " is outside lattice " - << lat.id << " but the lattice has no defined outer " + << lat.id_ << " but the lattice has no defined outer " "universe."; warning(err_msg); return false; @@ -256,7 +256,7 @@ cross_lattice(Particle* p, int lattice_translation[3]) if (openmc_verbosity >= 10 || openmc_trace) { std::stringstream msg; - msg << " Crossing lattice " << lat.id << ". Current position (" + msg << " Crossing lattice " << lat.id_ << ". Current position (" << p->coord[p->n_coord-1].lattice_x << "," << p->coord[p->n_coord-1].lattice_y << "," << p->coord[p->n_coord-1].lattice_z << ")"; @@ -342,7 +342,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, //TODO: refactor so both lattice use the same position argument (which //also means the lat.type attribute can be removed) std::pair> lattice_distance; - switch (lat.type) { + switch (lat.type_) { case LatticeType::rect: lattice_distance = lat.distance(r, u, i_xyz); break; @@ -374,7 +374,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, // positive half-space were given in the region specification. Thus, we // have to explicitly check which half-space the particle would be // traveling into if the surface is crossed - if (c.simple) { + if (c.simple_) { *surface_crossed = level_surf_cross; } else { Position r_hit = r + d_surf * u; diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index c55baf4b0b..768b2dd4ec 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -23,25 +23,25 @@ adjust_indices() { // Adjust material/fill idices. for (Cell* c : global_cells) { - if (c->fill != C_NONE) { - int32_t id = c->fill; + if (c->fill_ != C_NONE) { + int32_t id = c->fill_; auto search_univ = universe_map.find(id); auto search_lat = lattice_map.find(id); if (search_univ != universe_map.end()) { - c->type = FILL_UNIVERSE; - c->fill = search_univ->second; + c->type_ = FILL_UNIVERSE; + c->fill_ = search_univ->second; } else if (search_lat != lattice_map.end()) { - c->type = FILL_LATTICE; - c->fill = search_lat->second; + c->type_ = FILL_LATTICE; + c->fill_ = search_lat->second; } else { std::stringstream err_msg; - err_msg << "Specified fill " << id << " on cell " << c->id + err_msg << "Specified fill " << id << " on cell " << c->id_ << " is neither a universe nor a lattice."; fatal_error(err_msg); } } else { - c->type = FILL_MATERIAL; - for (auto it = c->material.begin(); it != c->material.end(); it++) { + c->type_ = FILL_MATERIAL; + for (auto it = c->material_.begin(); it != c->material_.end(); it++) { int32_t mid = *it; if (mid != MATERIAL_VOID) { auto search = material_map.find(mid); @@ -50,7 +50,7 @@ adjust_indices() } else { std::stringstream err_msg; err_msg << "Could not find material " << mid - << " specified on cell " << c->id; + << " specified on cell " << c->id_; fatal_error(err_msg); } } @@ -60,13 +60,13 @@ adjust_indices() // Change cell.universe values from IDs to indices. for (Cell* c : global_cells) { - auto search = universe_map.find(c->universe); + auto search = universe_map.find(c->universe_); if (search != universe_map.end()) { - c->universe = search->second; + c->universe_ = search->second; } else { std::stringstream err_msg; - err_msg << "Could not find universe " << c->universe - << " specified on cell " << c->id; + err_msg << "Could not find universe " << c->universe_ + << " specified on cell " << c->id_; fatal_error(err_msg); } } @@ -84,23 +84,23 @@ assign_temperatures() { for (Cell* c : global_cells) { // Ignore non-material cells and cells with defined temperature. - if (c->material.size() == 0) continue; - if (c->sqrtkT.size() > 0) continue; + if (c->material_.size() == 0) continue; + if (c->sqrtkT_.size() > 0) continue; - c->sqrtkT.reserve(c->material.size()); - for (auto i_mat : c->material) { + c->sqrtkT_.reserve(c->material_.size()); + for (auto i_mat : c->material_) { if (i_mat == MATERIAL_VOID) { // Set void region to 0K. - c->sqrtkT.push_back(0); + c->sqrtkT_.push_back(0); } else { if (global_materials[i_mat]->temperature_ >= 0) { // This material has a default temperature; use that value. auto T = global_materials[i_mat]->temperature_; - c->sqrtkT.push_back(std::sqrt(K_BOLTZMANN * T)); + c->sqrtkT_.push_back(std::sqrt(K_BOLTZMANN * T)); } else { // Use the global default temperature. - c->sqrtkT.push_back(std::sqrt(K_BOLTZMANN * temperature_default)); + c->sqrtkT_.push_back(std::sqrt(K_BOLTZMANN * temperature_default)); } } } @@ -115,7 +115,7 @@ find_root_universe() // Find all the universes listed as a cell fill. std::unordered_set fill_univ_ids; for (Cell* c : global_cells) { - fill_univ_ids.insert(c->fill); + fill_univ_ids.insert(c->fill_); } // Find all the universes contained in a lattice. @@ -123,8 +123,8 @@ find_root_universe() for (auto it = lat->begin(); it != lat->end(); ++it) { fill_univ_ids.insert(*it); } - if (lat->outer != NO_OUTER_UNIVERSE) { - fill_univ_ids.insert(lat->outer); + if (lat->outer_ != NO_OUTER_UNIVERSE) { + fill_univ_ids.insert(lat->outer_); } } @@ -132,7 +132,7 @@ find_root_universe() bool root_found {false}; int32_t root_univ; for (int32_t i = 0; i < global_universes.size(); i++) { - auto search = fill_univ_ids.find(global_universes[i]->id); + auto search = fill_univ_ids.find(global_universes[i]->id_); if (search == fill_univ_ids.end()) { if (root_found) { fatal_error("Two or more universes are not used as fill universes, so " @@ -158,22 +158,22 @@ neighbor_lists() write_message("Building neighboring cells lists for each surface...", 6); for (int i = 0; i < global_cells.size(); i++) { - for (auto token : global_cells[i]->region) { + for (auto token : global_cells[i]->region_) { // Skip operator tokens. if (std::abs(token) >= OP_UNION) continue; // This token is a surface index. Add the cell to the surface's list. if (token > 0) { - global_surfaces[std::abs(token)-1]->neighbor_pos.push_back(i); + global_surfaces[std::abs(token)-1]->neighbor_pos_.push_back(i); } else { - global_surfaces[std::abs(token)-1]->neighbor_neg.push_back(i); + global_surfaces[std::abs(token)-1]->neighbor_neg_.push_back(i); } } } for (Surface* surf : global_surfaces) { - surf->neighbor_pos.shrink_to_fit(); - surf->neighbor_neg.shrink_to_fit(); + surf->neighbor_pos_.shrink_to_fit(); + surf->neighbor_neg_.shrink_to_fit(); } } @@ -193,11 +193,11 @@ prepare_distribcell(int32_t* filter_cell_list, int n) 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) { + 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 + 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); @@ -205,13 +205,13 @@ prepare_distribcell(int32_t* filter_cell_list, int n) distribcells.insert(i); } - if (c.sqrtkT.size() > 1) { - if (c.sqrtkT.size() != c.n_instances) { + 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."; + 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); @@ -224,10 +224,10 @@ prepare_distribcell(int32_t* filter_cell_list, int n) int distribcell_index = 1; std::vector target_univ_ids; for (Universe* u : global_universes) { - for (auto cell_indx : u->cells) { + 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); + global_cells[cell_indx]->distribcell_index_ = distribcell_index; + target_univ_ids.push_back(u->id_); ++distribcell_index; } } @@ -236,8 +236,8 @@ prepare_distribcell(int32_t* filter_cell_list, int n) // 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); + if (c->type_ != FILL_MATERIAL) { + c->offset_.resize(n_maps, C_NONE); } } for (Lattice* lat : lattices_c) { @@ -249,16 +249,16 @@ prepare_distribcell(int32_t* filter_cell_list, int n) 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) { + 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; + 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]; + } else if (c.type_ == FILL_LATTICE) { + Lattice& lat = *lattices_c[c.fill_]; offset = lat.fill_offset_table(offset, target_univ_id, map); } } @@ -271,17 +271,17 @@ prepare_distribcell(int32_t* filter_cell_list, int n) void count_cell_instances(int32_t univ_indx) { - for (int32_t cell_indx : global_universes[univ_indx]->cells) { + for (int32_t cell_indx : global_universes[univ_indx]->cells_) { Cell& c = *global_cells[cell_indx]; - ++c.n_instances; + ++c.n_instances_; - if (c.type == FILL_UNIVERSE) { + if (c.type_ == FILL_UNIVERSE) { // This cell contains another universe. Recurse into that universe. - count_cell_instances(c.fill); + count_cell_instances(c.fill_); - } else if (c.type == FILL_LATTICE) { + } else if (c.type_ == FILL_LATTICE) { // This cell contains a lattice. Recurse into the lattice universes. - Lattice& lat = *lattices_c[c.fill]; + Lattice& lat = *lattices_c[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { count_cell_instances(*it); } @@ -295,20 +295,20 @@ int count_universe_instances(int32_t search_univ, int32_t target_univ_id) { // If this is the target, it can't contain itself. - if (global_universes[search_univ]->id == target_univ_id) { + if (global_universes[search_univ]->id_ == target_univ_id) { return 1; } int count {0}; - for (int32_t cell_indx : global_universes[search_univ]->cells) { + for (int32_t cell_indx : global_universes[search_univ]->cells_) { Cell& c = *global_cells[cell_indx]; - if (c.type == FILL_UNIVERSE) { - int32_t next_univ = c.fill; + if (c.type_ == FILL_UNIVERSE) { + int32_t next_univ = c.fill_; count += count_universe_instances(next_univ, target_univ_id); - } else if (c.type == FILL_LATTICE) { - Lattice& lat = *lattices_c[c.fill]; + } else if (c.type_ == FILL_LATTICE) { + Lattice& lat = *lattices_c[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { int32_t next_univ = *it; count += count_universe_instances(next_univ, target_univ_id); @@ -327,14 +327,14 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, { std::stringstream path; - path << "u" << search_univ.id << "->"; + path << "u" << search_univ.id_ << "->"; // Check to see if this universe directly contains the target cell. If so, // write to the path and return. - for (int32_t cell_indx : search_univ.cells) { + for (int32_t cell_indx : search_univ.cells_) { if ((cell_indx == target_cell) && (offset == target_offset)) { Cell& c = *global_cells[cell_indx]; - path << "c" << c.id; + path << "c" << c.id_; return path.str(); } } @@ -343,19 +343,19 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, // cell or lattice cell in this universe. Find which cell contains the // target. std::vector::const_reverse_iterator cell_it - {search_univ.cells.crbegin()}; - for (; cell_it != search_univ.cells.crend(); ++cell_it) { + {search_univ.cells_.crbegin()}; + for (; cell_it != search_univ.cells_.crend(); ++cell_it) { Cell& c = *global_cells[*cell_it]; // Material cells don't contain other cells so ignore them. - if (c.type != FILL_MATERIAL) { + if (c.type_ != FILL_MATERIAL) { int32_t temp_offset; - if (c.type == FILL_UNIVERSE) { - temp_offset = offset + c.offset[map]; + if (c.type_ == FILL_UNIVERSE) { + temp_offset = offset + c.offset_[map]; } else { - Lattice& lat = *lattices_c[c.fill]; - int32_t indx = lat.universes.size()*map + lat.begin().indx; - temp_offset = offset + lat.offsets[indx]; + Lattice& lat = *lattices_c[c.fill_]; + int32_t indx = lat.universes_.size()*map + lat.begin().indx_; + temp_offset = offset + lat.offsets_[indx]; } // The desired cell is the first cell that gives an offset smaller or @@ -366,24 +366,24 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, // Add the cell to the path string. Cell& c = *global_cells[*cell_it]; - path << "c" << c.id << "->"; + path << "c" << c.id_ << "->"; - if (c.type == FILL_UNIVERSE) { + if (c.type_ == FILL_UNIVERSE) { // Recurse into the fill cell. - offset += c.offset[map]; + offset += c.offset_[map]; path << distribcell_path_inner(target_cell, map, target_offset, - *global_universes[c.fill], offset); + *global_universes[c.fill_], offset); return path.str(); } else { // Recurse into the lattice cell. - Lattice& lat = *lattices_c[c.fill]; - path << "l" << lat.id; + Lattice& lat = *lattices_c[c.fill_]; + path << "l" << lat.id_; for (ReverseLatticeIter it = lat.rbegin(); it != lat.rend(); ++it) { - int32_t indx = lat.universes.size()*map + it.indx; - int32_t temp_offset = offset + lat.offsets[indx]; + int32_t indx = lat.universes_.size()*map + it.indx_; + int32_t temp_offset = offset + lat.offsets_[indx]; if (temp_offset <= target_offset) { offset = temp_offset; - path << "(" << lat.index_to_string(it.indx) << ")->"; + path << "(" << lat.index_to_string(it.indx_) << ")->"; path << distribcell_path_inner(target_cell, map, target_offset, *global_universes[*it], offset); return path.str(); @@ -424,13 +424,13 @@ maximum_levels(int32_t univ) { int levels_below {0}; - for (int32_t cell_indx : global_universes[univ]->cells) { + for (int32_t cell_indx : global_universes[univ]->cells_) { Cell& c = *global_cells[cell_indx]; - if (c.type == FILL_UNIVERSE) { - int32_t next_univ = c.fill; + if (c.type_ == FILL_UNIVERSE) { + int32_t next_univ = c.fill_; levels_below = std::max(levels_below, maximum_levels(next_univ)); - } else if (c.type == FILL_LATTICE) { - Lattice& lat = *lattices_c[c.fill]; + } else if (c.type_ == FILL_LATTICE) { + Lattice& lat = *lattices_c[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { int32_t next_univ = *it; levels_below = std::max(levels_below, maximum_levels(next_univ)); diff --git a/src/lattice.cpp b/src/lattice.cpp index 36b0cea61c..0975082eb7 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -29,17 +29,17 @@ std::unordered_map lattice_map; Lattice::Lattice(pugi::xml_node lat_node) { if (check_for_node(lat_node, "id")) { - id = std::stoi(get_node_value(lat_node, "id")); + id_ = std::stoi(get_node_value(lat_node, "id")); } else { fatal_error("Must specify id of lattice in geometry XML file."); } if (check_for_node(lat_node, "name")) { - name = get_node_value(lat_node, "name"); + name_ = get_node_value(lat_node, "name"); } if (check_for_node(lat_node, "outer")) { - outer = std::stoi(get_node_value(lat_node, "outer")); + outer_ = std::stoi(get_node_value(lat_node, "outer")); } } @@ -49,10 +49,10 @@ LatticeIter Lattice::begin() {return LatticeIter(*this, 0);} LatticeIter Lattice::end() -{return LatticeIter(*this, universes.size());} +{return LatticeIter(*this, universes_.size());} ReverseLatticeIter Lattice::rbegin() -{return ReverseLatticeIter(*this, universes.size()-1);} +{return ReverseLatticeIter(*this, universes_.size()-1);} ReverseLatticeIter Lattice::rend() {return ReverseLatticeIter(*this, -1);} @@ -71,20 +71,20 @@ Lattice::adjust_indices() } else { std::stringstream err_msg; err_msg << "Invalid universe number " << uid << " specified on " - "lattice " << id; + "lattice " << id_; fatal_error(err_msg); } } // Adjust the index for the outer universe. - if (outer != NO_OUTER_UNIVERSE) { - auto search = universe_map.find(outer); + if (outer_ != NO_OUTER_UNIVERSE) { + auto search = universe_map.find(outer_); if (search != universe_map.end()) { - outer = search->second; + outer_ = search->second; } else { std::stringstream err_msg; - err_msg << "Invalid universe number " << outer << " specified on " - "lattice " << id; + err_msg << "Invalid universe number " << outer_ << " specified on " + "lattice " << id_; fatal_error(err_msg); } } @@ -96,7 +96,7 @@ int32_t Lattice::fill_offset_table(int32_t offset, int32_t target_univ_id, int map) { for (LatticeIter it = begin(); it != end(); ++it) { - offsets[map * universes.size() + it.indx] = offset; + offsets_[map * universes_.size() + it.indx_] = offset; offset += count_universe_instances(*it, target_univ_id); } return offset; @@ -109,19 +109,19 @@ Lattice::to_hdf5(hid_t lattices_group) const { // Make a group for the lattice. std::string group_name {"lattice "}; - group_name += std::to_string(id); + group_name += std::to_string(id_); hid_t lat_group = create_group(lattices_group, group_name); // Write the name and outer universe. - if (!name.empty()) { - write_string(lat_group, "name", name, false); + if (!name_.empty()) { + write_string(lat_group, "name", name_, false); } - if (outer != NO_OUTER_UNIVERSE) { - int32_t outer_id = global_universes[outer]->id; + if (outer_ != NO_OUTER_UNIVERSE) { + int32_t outer_id = global_universes[outer_]->id_; write_dataset(lat_group, "outer", outer_id); } else { - write_dataset(lat_group, "outer", outer); + write_dataset(lat_group, "outer", outer_); } // Call subclass-overriden function to fill in other details. @@ -137,21 +137,21 @@ Lattice::to_hdf5(hid_t lattices_group) const RectLattice::RectLattice(pugi::xml_node lat_node) : Lattice {lat_node} { - type = LatticeType::rect; + type_ = LatticeType::rect; // Read the number of lattice cells in each dimension. std::string dimension_str {get_node_value(lat_node, "dimension")}; std::vector dimension_words {split(dimension_str)}; if (dimension_words.size() == 2) { - n_cells[0] = std::stoi(dimension_words[0]); - n_cells[1] = std::stoi(dimension_words[1]); - n_cells[2] = 1; - is_3d = false; + n_cells_[0] = std::stoi(dimension_words[0]); + n_cells_[1] = std::stoi(dimension_words[1]); + n_cells_[2] = 1; + is_3d_ = false; } else if (dimension_words.size() == 3) { - n_cells[0] = std::stoi(dimension_words[0]); - n_cells[1] = std::stoi(dimension_words[1]); - n_cells[2] = std::stoi(dimension_words[2]); - is_3d = true; + n_cells_[0] = std::stoi(dimension_words[0]); + n_cells_[1] = std::stoi(dimension_words[1]); + n_cells_[2] = std::stoi(dimension_words[2]); + is_3d_ = true; } else { fatal_error("Rectangular lattice must be two or three dimensions."); } @@ -163,9 +163,9 @@ RectLattice::RectLattice(pugi::xml_node lat_node) fatal_error("Number of entries on must be the same as the " "number of entries on ."); } - lower_left[0] = stod(ll_words[0]); - lower_left[1] = stod(ll_words[1]); - if (is_3d) {lower_left[2] = stod(ll_words[2]);} + lower_left_[0] = stod(ll_words[0]); + lower_left_[1] = stod(ll_words[1]); + if (is_3d_) {lower_left_[2] = stod(ll_words[2]);} // Read the lattice pitches. std::string pitch_str {get_node_value(lat_node, "pitch")}; @@ -174,9 +174,9 @@ RectLattice::RectLattice(pugi::xml_node lat_node) fatal_error("Number of entries on must be the same as the " "number of entries on ."); } - pitch[0] = stod(pitch_words[0]); - pitch[1] = stod(pitch_words[1]); - if (is_3d) {pitch[2] = stod(pitch_words[2]);} + pitch_[0] = stod(pitch_words[0]); + pitch_[1] = stod(pitch_words[1]); + if (is_3d_) {pitch_[2] = stod(pitch_words[2]);} // Read the universes and make sure the correct number was specified. std::string univ_str {get_node_value(lat_node, "universes")}; @@ -191,13 +191,13 @@ RectLattice::RectLattice(pugi::xml_node lat_node) } // Parse the universes. - universes.resize(nx*ny*nz, C_NONE); + universes_.resize(nx*ny*nz, C_NONE); for (int iz = 0; iz < nz; iz++) { for (int iy = ny-1; iy > -1; iy--) { for (int ix = 0; ix < nx; ix++) { int indx1 = nx*ny*iz + nx*(ny-iy-1) + ix; int indx2 = nx*ny*iz + nx*iy + ix; - universes[indx1] = std::stoi(univ_words[indx2]); + universes_[indx1] = std::stoi(univ_words[indx2]); } } } @@ -209,7 +209,7 @@ int32_t& RectLattice::operator[](std::array i_xyz) { int indx = nx*ny*i_xyz[2] + nx*i_xyz[1] + i_xyz[0]; - return universes[indx]; + return universes_[indx]; } //============================================================================== @@ -217,9 +217,9 @@ RectLattice::operator[](std::array i_xyz) bool RectLattice::are_valid_indices(const int i_xyz[3]) const { - return ( (i_xyz[0] >= 0) && (i_xyz[0] < n_cells[0]) - && (i_xyz[1] >= 0) && (i_xyz[1] < n_cells[1]) - && (i_xyz[2] >= 0) && (i_xyz[2] < n_cells[2])); + return ( (i_xyz[0] >= 0) && (i_xyz[0] < n_cells_[0]) + && (i_xyz[1] >= 0) && (i_xyz[1] < n_cells_[1]) + && (i_xyz[2] >= 0) && (i_xyz[2] < n_cells_[2])); } //============================================================================== @@ -234,8 +234,8 @@ const double z = r.z; // Determine the oncoming edge. - double x0 {copysign(0.5 * pitch[0], u.x)}; - double y0 {copysign(0.5 * pitch[1], u.y)}; + double x0 {copysign(0.5 * pitch_[0], u.x)}; + double y0 {copysign(0.5 * pitch_[1], u.y)}; // Left and right sides double d {INFTY}; @@ -263,8 +263,8 @@ const } // Top and bottom sides - if (is_3d) { - double z0 {copysign(0.5 * pitch[2], u.z)}; + if (is_3d_) { + double z0 {copysign(0.5 * pitch_[2], u.z)}; if ((std::abs(z - z0) > FP_PRECISION) && u.z != 0) { double this_d = (z0 - z) / u.z; if (this_d < d) { @@ -286,11 +286,11 @@ const std::array RectLattice::get_indices(Position r) const { - int ix {static_cast(std::ceil((r.x - lower_left.x) / pitch.x))-1}; - int iy {static_cast(std::ceil((r.y - lower_left.y) / pitch.y))-1}; + int ix {static_cast(std::ceil((r.x - lower_left_.x) / pitch_.x))-1}; + int iy {static_cast(std::ceil((r.y - lower_left_.y) / pitch_.y))-1}; int iz; - if (is_3d) { - iz = static_cast(std::ceil((r.z - lower_left.z) / pitch.z))-1; + if (is_3d_) { + iz = static_cast(std::ceil((r.z - lower_left_.z) / pitch_.z))-1; } else { iz = 0; } @@ -303,10 +303,10 @@ Position RectLattice::get_local_position(Position r, const std::array i_xyz) const { - r.x -= (lower_left.x + (i_xyz[0] + 0.5)*pitch.x); - r.y -= (lower_left.y + (i_xyz[1] + 0.5)*pitch.y); - if (is_3d) { - r.z -= (lower_left.z + (i_xyz[2] + 0.5)*pitch.z); + r.x -= (lower_left_.x + (i_xyz[0] + 0.5)*pitch_.x); + r.y -= (lower_left_.y + (i_xyz[1] + 0.5)*pitch_.y); + if (is_3d_) { + r.z -= (lower_left_.z + (i_xyz[2] + 0.5)*pitch_.z); } return r; } @@ -316,7 +316,7 @@ const int32_t& RectLattice::offset(int map, const int i_xyz[3]) { - return offsets[nx*ny*nz*map + nx*ny*i_xyz[2] + nx*i_xyz[1] + i_xyz[0]]; + return offsets_[nx*ny*nz*map + nx*ny*i_xyz[2] + nx*i_xyz[1] + i_xyz[0]]; } //============================================================================== @@ -330,7 +330,7 @@ RectLattice::index_to_string(int indx) const std::string out {std::to_string(ix)}; out += ','; out += std::to_string(iy); - if (is_3d) { + if (is_3d_) { out += ','; out += std::to_string(iz); } @@ -344,25 +344,25 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const { // Write basic lattice information. write_string(lat_group, "type", "rectangular", false); - if (is_3d) { - write_dataset(lat_group, "pitch", pitch); - write_dataset(lat_group, "lower_left", lower_left); - write_dataset(lat_group, "dimension", n_cells); + if (is_3d_) { + write_dataset(lat_group, "pitch", pitch_); + write_dataset(lat_group, "lower_left", lower_left_); + write_dataset(lat_group, "dimension", n_cells_); } else { - std::array pitch_short {{pitch[0], pitch[1]}}; + std::array pitch_short {{pitch_[0], pitch_[1]}}; write_dataset(lat_group, "pitch", pitch_short); - std::array ll_short {{lower_left[0], lower_left[1]}}; + std::array ll_short {{lower_left_[0], lower_left_[1]}}; write_dataset(lat_group, "lower_left", ll_short); - std::array nc_short {{n_cells[0], n_cells[1]}}; + std::array nc_short {{n_cells_[0], n_cells_[1]}}; write_dataset(lat_group, "dimension", nc_short); } // Write the universe ids. The convention here is to switch the ordering on // the y-axis to match the way universes are input in a text file. - if (is_3d) { - hsize_t nx {static_cast(n_cells[0])}; - hsize_t ny {static_cast(n_cells[1])}; - hsize_t nz {static_cast(n_cells[2])}; + if (is_3d_) { + hsize_t nx {static_cast(n_cells_[0])}; + hsize_t ny {static_cast(n_cells_[1])}; + hsize_t nz {static_cast(n_cells_[2])}; int out[nx*ny*nz]; for (int m = 0; m < nz; m++) { @@ -370,7 +370,7 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const for (int j = 0; j < nx; j++) { int indx1 = nx*ny*m + nx*k + j; int indx2 = nx*ny*m + nx*(ny-k-1) + j; - out[indx2] = global_universes[universes[indx1]]->id; + out[indx2] = global_universes[universes_[indx1]]->id_; } } } @@ -379,15 +379,15 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const write_int(lat_group, 3, dims, "universes", out, false); } else { - hsize_t nx {static_cast(n_cells[0])}; - hsize_t ny {static_cast(n_cells[1])}; + hsize_t nx {static_cast(n_cells_[0])}; + hsize_t ny {static_cast(n_cells_[1])}; int out[nx*ny]; for (int k = 0; k < ny; k++) { for (int j = 0; j < nx; j++) { int indx1 = nx*k + j; int indx2 = nx*(ny-k-1) + j; - out[indx2] = global_universes[universes[indx1]]->id; + out[indx2] = global_universes[universes_[indx1]]->id_; } } @@ -403,54 +403,54 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const HexLattice::HexLattice(pugi::xml_node lat_node) : Lattice {lat_node} { - type = LatticeType::hex; + type_ = LatticeType::hex; // Read the number of lattice cells in each dimension. - n_rings = std::stoi(get_node_value(lat_node, "n_rings")); + n_rings_ = std::stoi(get_node_value(lat_node, "n_rings")); if (check_for_node(lat_node, "n_axial")) { - n_axial = std::stoi(get_node_value(lat_node, "n_axial")); - is_3d = true; + n_axial_ = std::stoi(get_node_value(lat_node, "n_axial")); + is_3d_ = true; } else { - n_axial = 1; - is_3d = false; + n_axial_ = 1; + is_3d_ = false; } // Read the lattice center. std::string center_str {get_node_value(lat_node, "center")}; std::vector center_words {split(center_str)}; - if (is_3d && (center_words.size() != 3)) { + if (is_3d_ && (center_words.size() != 3)) { fatal_error("A hexagonal lattice with must have
" "specified by 3 numbers."); - } else if (!is_3d && center_words.size() != 2) { + } else if (!is_3d_ && center_words.size() != 2) { fatal_error("A hexagonal lattice without must have
" "specified by 2 numbers."); } - center[0] = stod(center_words[0]); - center[1] = stod(center_words[1]); - if (is_3d) {center[2] = stod(center_words[2]);} + center_[0] = stod(center_words[0]); + center_[1] = stod(center_words[1]); + if (is_3d_) {center_[2] = stod(center_words[2]);} // Read the lattice pitches. std::string pitch_str {get_node_value(lat_node, "pitch")}; std::vector pitch_words {split(pitch_str)}; - if (is_3d && (pitch_words.size() != 2)) { + if (is_3d_ && (pitch_words.size() != 2)) { fatal_error("A hexagonal lattice with must have " "specified by 2 numbers."); - } else if (!is_3d && (pitch_words.size() != 1)) { + } else if (!is_3d_ && (pitch_words.size() != 1)) { fatal_error("A hexagonal lattice without must have " "specified by 1 number."); } - pitch[0] = stod(pitch_words[0]); - if (is_3d) {pitch[1] = stod(pitch_words[1]);} + pitch_[0] = stod(pitch_words[0]); + if (is_3d_) {pitch_[1] = stod(pitch_words[1]);} // Read the universes and make sure the correct number was specified. - int n_univ = (3*n_rings*n_rings - 3*n_rings + 1) * n_axial; + int n_univ = (3*n_rings_*n_rings_ - 3*n_rings_ + 1) * n_axial_; std::string univ_str {get_node_value(lat_node, "universes")}; std::vector univ_words {split(univ_str)}; if (univ_words.size() != n_univ) { std::stringstream err_msg; err_msg << "Expected " << n_univ - << " universes for a hexagonal lattice with " << n_rings - << " rings and " << n_axial << " axial levels" << " but " + << " universes for a hexagonal lattice with " << n_rings_ + << " rings and " << n_axial_ << " axial levels" << " but " << univ_words.size() << " were specified."; fatal_error(err_msg); } @@ -464,25 +464,25 @@ HexLattice::HexLattice(pugi::xml_node lat_node) // in a manner that matches the input order. Note that i_x = 0, i_a = 0 // corresponds to the center of the hexagonal lattice. - universes.resize((2*n_rings-1) * (2*n_rings-1) * n_axial, C_NONE); + universes_.resize((2*n_rings_-1) * (2*n_rings_-1) * n_axial_, C_NONE); int input_index = 0; - for (int m = 0; m < n_axial; m++) { + for (int m = 0; m < n_axial_; m++) { // Initialize lattice indecies. int i_x = 1; - int i_a = n_rings - 1; + int i_a = n_rings_ - 1; // Map upper triangular region of hexagonal lattice which is found in the // first n_rings-1 rows of the input. - for (int k = 0; k < n_rings-1; k++) { + for (int k = 0; k < n_rings_-1; k++) { // Walk the index to lower-left neighbor of last row start. i_x -= 1; // Iterate over the input columns. for (int j = 0; j < k+1; j++) { - int indx = (2*n_rings-1)*(2*n_rings-1) * m - + (2*n_rings-1) * (i_a+n_rings-1) - + (i_x+n_rings-1); - universes[indx] = std::stoi(univ_words[input_index]); + int indx = (2*n_rings_-1)*(2*n_rings_-1) * m + + (2*n_rings_-1) * (i_a+n_rings_-1) + + (i_x+n_rings_-1); + universes_[indx] = std::stoi(univ_words[input_index]); input_index++; // Walk the index to the right neighbor (which is not adjacent). i_x += 2; @@ -496,7 +496,7 @@ HexLattice::HexLattice(pugi::xml_node lat_node) // Map the middle square region of the hexagonal lattice which is found in // the next 2*n_rings-1 rows of the input. - for (int k = 0; k < 2*n_rings-1; k++) { + for (int k = 0; k < 2*n_rings_-1; k++) { if ((k % 2) == 0) { // Walk the index to the lower-left neighbor of the last row start. i_x -= 1; @@ -507,11 +507,11 @@ HexLattice::HexLattice(pugi::xml_node lat_node) } // Iterate over the input columns. - for (int j = 0; j < n_rings - (k % 2); j++) { - int indx = (2*n_rings-1)*(2*n_rings-1) * m - + (2*n_rings-1) * (i_a+n_rings-1) - + (i_x+n_rings-1); - universes[indx] = std::stoi(univ_words[input_index]); + for (int j = 0; j < n_rings_ - (k % 2); j++) { + int indx = (2*n_rings_-1)*(2*n_rings_-1) * m + + (2*n_rings_-1) * (i_a+n_rings_-1) + + (i_x+n_rings_-1); + universes_[indx] = std::stoi(univ_words[input_index]); input_index++; // Walk the index to the right neighbor (which is not adjacent). i_x += 2; @@ -519,22 +519,22 @@ HexLattice::HexLattice(pugi::xml_node lat_node) } // Return the lattice index to the start of the current row. - i_x -= 2*(n_rings - (k % 2)); - i_a += n_rings - (k % 2); + i_x -= 2*(n_rings_ - (k % 2)); + i_a += n_rings_ - (k % 2); } // Map the lower triangular region of the hexagonal lattice. - for (int k = 0; k < n_rings-1; k++) { + for (int k = 0; k < n_rings_-1; k++) { // Walk the index to the lower-right neighbor of the last row start. i_x += 1; i_a -= 1; // Iterate over the input columns. - for (int j = 0; j < n_rings-k-1; j++) { - int indx = (2*n_rings-1)*(2*n_rings-1) * m - + (2*n_rings-1) * (i_a+n_rings-1) - + (i_x+n_rings-1); - universes[indx] = std::stoi(univ_words[input_index]); + for (int j = 0; j < n_rings_-k-1; j++) { + int indx = (2*n_rings_-1)*(2*n_rings_-1) * m + + (2*n_rings_-1) * (i_a+n_rings_-1) + + (i_x+n_rings_-1); + universes_[indx] = std::stoi(univ_words[input_index]); input_index++; // Walk the index to the right neighbor (which is not adjacent). i_x += 2; @@ -542,8 +542,8 @@ HexLattice::HexLattice(pugi::xml_node lat_node) } // Return lattice index to start of current row. - i_x -= 2*(n_rings - k - 1); - i_a += n_rings - k - 1; + i_x -= 2*(n_rings_ - k - 1); + i_a += n_rings_ - k - 1; } } } @@ -553,19 +553,19 @@ HexLattice::HexLattice(pugi::xml_node lat_node) int32_t& HexLattice::operator[](std::array i_xyz) { - int indx = (2*n_rings-1)*(2*n_rings-1) * i_xyz[2] - + (2*n_rings-1) * i_xyz[1] + int indx = (2*n_rings_-1)*(2*n_rings_-1) * i_xyz[2] + + (2*n_rings_-1) * i_xyz[1] + i_xyz[0]; - return universes[indx]; + return universes_[indx]; } //============================================================================== LatticeIter HexLattice::begin() -{return LatticeIter(*this, n_rings-1);} +{return LatticeIter(*this, n_rings_-1);} ReverseLatticeIter HexLattice::rbegin() -{return ReverseLatticeIter(*this, universes.size()-n_rings);} +{return ReverseLatticeIter(*this, universes_.size()-n_rings_);} //============================================================================== @@ -573,10 +573,10 @@ bool HexLattice::are_valid_indices(const int i_xyz[3]) const { return ((i_xyz[0] >= 0) && (i_xyz[1] >= 0) && (i_xyz[2] >= 0) - && (i_xyz[0] < 2*n_rings-1) && (i_xyz[1] < 2*n_rings-1) - && (i_xyz[0] + i_xyz[1] > n_rings-2) - && (i_xyz[0] + i_xyz[1] < 3*n_rings-2) - && (i_xyz[2] < n_axial)); + && (i_xyz[0] < 2*n_rings_-1) && (i_xyz[1] < 2*n_rings_-1) + && (i_xyz[0] + i_xyz[1] > n_rings_-2) + && (i_xyz[0] + i_xyz[1] < 3*n_rings_-2) + && (i_xyz[2] < n_axial_)); } //============================================================================== @@ -598,7 +598,7 @@ const // Upper-right and lower-left sides. double d {INFTY}; std::array lattice_trans; - double edge = -copysign(0.5*pitch[0], beta_dir); // Oncoming edge + double edge = -copysign(0.5*pitch_[0], beta_dir); // Oncoming edge Position r_t; if (beta_dir > 0) { const std::array i_xyz_t {i_xyz[0]+1, i_xyz[1], i_xyz[2]}; @@ -618,7 +618,7 @@ const } // Lower-right and upper-left sides. - edge = -copysign(0.5*pitch[0], gamma_dir); + edge = -copysign(0.5*pitch_[0], gamma_dir); if (gamma_dir > 0) { const std::array i_xyz_t {i_xyz[0]+1, i_xyz[1]-1, i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); @@ -640,7 +640,7 @@ const } // Upper and lower sides. - edge = -copysign(0.5*pitch[0], u.y); + edge = -copysign(0.5*pitch_[0], u.y); if (u.y > 0) { const std::array i_xyz_t {i_xyz[0], i_xyz[1]+1, i_xyz[2]}; r_t = get_local_position(r, i_xyz_t); @@ -661,9 +661,9 @@ const } // Top and bottom sides - if (is_3d) { + if (is_3d_) { double z = r.z; - double z0 {copysign(0.5 * pitch[1], u.z)}; + double z0 {copysign(0.5 * pitch_[1], u.z)}; if ((std::abs(z - z0) > FP_PRECISION) && u.z != 0) { double this_d = (z0 - z) / u.z; if (this_d < d) { @@ -687,13 +687,13 @@ std::array HexLattice::get_indices(Position r) const { // Offset the xyz by the lattice center. - Position r_o {r.x - center.x, r.y - center.y, r.z}; - if (is_3d) {r_o.z -= center.z;} + Position r_o {r.x - center_.x, r.y - center_.y, r.z}; + if (is_3d_) {r_o.z -= center_.z;} // Index the z direction. std::array out; - if (is_3d) { - out[2] = static_cast(std::ceil(r_o.z / pitch[1] + 0.5 * n_axial))-1; + if (is_3d_) { + out[2] = static_cast(std::ceil(r_o.z / pitch_[1] + 0.5 * n_axial_))-1; } else { out[2] = 0; } @@ -702,13 +702,13 @@ HexLattice::get_indices(Position r) const // find the index of the global coordinates to within 4 cells. double alpha = r_o.y - r_o.x / std::sqrt(3.0); out[0] = static_cast(std::floor(r_o.x - / (0.5*std::sqrt(3.0) * pitch[0]))); - out[1] = static_cast(std::floor(alpha / pitch[0])); + / (0.5*std::sqrt(3.0) * pitch_[0]))); + out[1] = static_cast(std::floor(alpha / pitch_[0])); // Add offset to indices (the center cell is (i_x, i_alpha) = (0, 0) but // the array is offset so that the indices never go below 0). - out[0] += n_rings-1; - out[1] += n_rings-1; + out[0] += n_rings_-1; + out[1] += n_rings_-1; // Calculate the (squared) distance between the particle and the centers of // the four possible cells. Regular hexagonal tiles form a Voronoi @@ -754,12 +754,12 @@ HexLattice::get_local_position(Position r, const std::array i_xyz) const { // x_l = x_g - (center + pitch_x*cos(30)*index_x) - r.x -= (center.x + std::sqrt(3.0)/2.0 * (i_xyz[0] - n_rings + 1) * pitch[0]); + r.x -= center_.x + std::sqrt(3.0)/2.0 * (i_xyz[0] - n_rings_ + 1) * pitch_[0]; // y_l = y_g - (center + pitch_x*index_x + pitch_y*sin(30)*index_y) - r.y -= (center.y + (i_xyz[1] - n_rings + 1) * pitch[0] - + (i_xyz[0] - n_rings + 1) * pitch[0] / 2.0); - if (is_3d) { - r.z -= center.z - (0.5 * n_axial - i_xyz[2] - 0.5) * pitch[1]; + r.y -= (center_.y + (i_xyz[1] - n_rings_ + 1) * pitch_[0] + + (i_xyz[0] - n_rings_ + 1) * pitch_[0] / 2.0); + if (is_3d_) { + r.z -= center_.z - (0.5 * n_axial_ - i_xyz[2] - 0.5) * pitch_[1]; } return r; @@ -770,9 +770,9 @@ const bool HexLattice::is_valid_index(int indx) const { - int nx {2*n_rings - 1}; - int ny {2*n_rings - 1}; - int nz {n_axial}; + int nx {2*n_rings_ - 1}; + int ny {2*n_rings_ - 1}; + int nz {n_axial_}; int iz = indx / (nx * ny); int iy = (indx - nx*ny*iz) / nx; int ix = indx - nx*ny*iz - nx*iy; @@ -785,10 +785,10 @@ HexLattice::is_valid_index(int indx) const int32_t& HexLattice::offset(int map, const int i_xyz[3]) { - int nx {2*n_rings - 1}; - int ny {2*n_rings - 1}; - int nz {n_axial}; - return offsets[nx*ny*nz*map + nx*ny*i_xyz[2] + nx*i_xyz[1] + i_xyz[0]]; + int nx {2*n_rings_ - 1}; + int ny {2*n_rings_ - 1}; + int nz {n_axial_}; + return offsets_[nx*ny*nz*map + nx*ny*i_xyz[2] + nx*i_xyz[1] + i_xyz[0]]; } //============================================================================== @@ -796,15 +796,15 @@ HexLattice::offset(int map, const int i_xyz[3]) std::string HexLattice::index_to_string(int indx) const { - int nx {2*n_rings - 1}; - int ny {2*n_rings - 1}; + int nx {2*n_rings_ - 1}; + int ny {2*n_rings_ - 1}; int iz {indx / (nx * ny)}; int iy {(indx - nx * ny * iz) / nx}; int ix {indx - nx * ny * iz - nx * iy}; - std::string out {std::to_string(ix - n_rings + 1)}; + std::string out {std::to_string(ix - n_rings_ + 1)}; out += ','; - out += std::to_string(iy - n_rings + 1); - if (is_3d) { + out += std::to_string(iy - n_rings_ + 1); + if (is_3d_) { out += ','; out += std::to_string(iz); } @@ -818,36 +818,36 @@ HexLattice::to_hdf5_inner(hid_t lat_group) const { // Write basic lattice information. write_string(lat_group, "type", "hexagonal", false); - write_dataset(lat_group, "n_rings", n_rings); - write_dataset(lat_group, "n_axial", n_axial); - if (is_3d) { - write_dataset(lat_group, "pitch", pitch); - write_dataset(lat_group, "center", center); + write_dataset(lat_group, "n_rings", n_rings_); + write_dataset(lat_group, "n_axial", n_axial_); + if (is_3d_) { + write_dataset(lat_group, "pitch", pitch_); + write_dataset(lat_group, "center", center_); } else { - std::array pitch_short {{pitch[0]}}; + std::array pitch_short {{pitch_[0]}}; write_dataset(lat_group, "pitch", pitch_short); - std::array center_short {{center[0], center[1]}}; + std::array center_short {{center_[0], center_[1]}}; write_dataset(lat_group, "center", center_short); } // Write the universe ids. - hsize_t nx {static_cast(2*n_rings - 1)}; - hsize_t ny {static_cast(2*n_rings - 1)}; - hsize_t nz {static_cast(n_axial)}; + hsize_t nx {static_cast(2*n_rings_ - 1)}; + hsize_t ny {static_cast(2*n_rings_ - 1)}; + hsize_t nz {static_cast(n_axial_)}; int out[nx*ny*nz]; for (int m = 0; m < nz; m++) { for (int k = 0; k < ny; k++) { for (int j = 0; j < nx; j++) { int indx = nx*ny*m + nx*k + j; - if (j + k < n_rings - 1) { + if (j + k < n_rings_ - 1) { // This array position is never used; put a -1 to indicate this. out[indx] = -1; - } else if (j + k > 3*n_rings - 3) { + } else if (j + k > 3*n_rings_ - 3) { // This array position is never used; put a -1 to indicate this. out[indx] = -1; } else { - out[indx] = global_universes[universes[indx]]->id; + out[indx] = global_universes[universes_[indx]]->id_; } } } @@ -873,7 +873,7 @@ read_lattices(pugi::xml_node *node) // Fill the lattice map. for (int i_lat = 0; i_lat < lattices_c.size(); i_lat++) { - int id = lattices_c[i_lat]->id; + int id = lattices_c[i_lat]->id_; auto in_map = lattice_map.find(id); if (in_map == lattice_map.end()) { lattice_map[id] = i_lat; @@ -892,7 +892,7 @@ read_lattices(pugi::xml_node *node) extern "C" { Lattice* lattice_pointer(int lat_ind) {return lattices_c[lat_ind];} - int32_t lattice_id(Lattice *lat) {return lat->id;} + int32_t lattice_id(Lattice *lat) {return lat->id_;} bool lattice_are_valid_indices(Lattice *lat, const int i_xyz[3]) {return lat->are_valid_indices(i_xyz);} diff --git a/src/output.cpp b/src/output.cpp index b8530dd3bc..2d7b76753b 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -56,10 +56,10 @@ print_overlap_check() { std::vector sparse_cell_ids; for (int i = 0; i < n_cells; i++) { - std::cout << " " << std::setw(8) << global_cells[i]->id << std::setw(17) + std::cout << " " << std::setw(8) << global_cells[i]->id_ << std::setw(17) << overlap_check_count[i] << "\n"; if (overlap_check_count[i] < 10) { - sparse_cell_ids.push_back(global_cells[i]->id); + sparse_cell_ids.push_back(global_cells[i]->id_); } } diff --git a/src/surface.cpp b/src/surface.cpp index 4de0bd0f98..54ff511dc4 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -141,38 +141,38 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, Surface::Surface(pugi::xml_node surf_node) { if (check_for_node(surf_node, "id")) { - id = std::stoi(get_node_value(surf_node, "id")); + id_ = std::stoi(get_node_value(surf_node, "id")); } else { fatal_error("Must specify id of surface in geometry XML file."); } if (check_for_node(surf_node, "name")) { - name = get_node_value(surf_node, "name", false); + name_ = get_node_value(surf_node, "name", false); } if (check_for_node(surf_node, "boundary")) { std::string surf_bc = get_node_value(surf_node, "boundary", true, true); if (surf_bc == "transmission" || surf_bc == "transmit" ||surf_bc.empty()) { - bc = BC_TRANSMIT; + bc_ = BC_TRANSMIT; } else if (surf_bc == "vacuum") { - bc = BC_VACUUM; + bc_ = BC_VACUUM; } else if (surf_bc == "reflective" || surf_bc == "reflect" || surf_bc == "reflecting") { - bc = BC_REFLECT; + bc_ = BC_REFLECT; } else if (surf_bc == "periodic") { - bc = BC_PERIODIC; + bc_ = BC_PERIODIC; } else { std::stringstream err_msg; err_msg << "Unknown boundary condition \"" << surf_bc - << "\" specified on surface " << id; + << "\" specified on surface " << id_; fatal_error(err_msg); } } else { - bc = BC_TRANSMIT; + bc_ = BC_TRANSMIT; } } @@ -211,11 +211,11 @@ void Surface::to_hdf5(hid_t group_id) const { std::string group_name {"surface "}; - group_name += std::to_string(id); + group_name += std::to_string(id_); hid_t surf_group = create_group(group_id, group_name); - switch(bc) { + switch(bc_) { case BC_TRANSMIT : write_string(surf_group, "boundary_type", "transmission", false); break; @@ -230,8 +230,8 @@ Surface::to_hdf5(hid_t group_id) const break; } - if (!name.empty()) { - write_string(surf_group, "name", name, false); + if (!name_.empty()) { + write_string(surf_group, "name", name_, false); } to_hdf5_inner(surf_group); @@ -247,7 +247,7 @@ PeriodicSurface::PeriodicSurface(pugi::xml_node surf_node) : Surface {surf_node} { if (check_for_node(surf_node, "periodic_surface_id")) { - i_periodic = std::stoi(get_node_value(surf_node, "periodic_surface_id")); + i_periodic_ = std::stoi(get_node_value(surf_node, "periodic_surface_id")); } } @@ -273,17 +273,17 @@ axis_aligned_plane_distance(Position r, Direction u, bool coincident, double off SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, id, x0); + read_coeffs(surf_node, id_, x0_); } double SurfaceXPlane::evaluate(Position r) const { - return r.x - x0; + return r.x - x0_; } double SurfaceXPlane::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_plane_distance<0>(r, u, coincident, x0); + return axis_aligned_plane_distance<0>(r, u, coincident, x0_); } Direction SurfaceXPlane::normal(Position r) const @@ -294,7 +294,7 @@ Direction SurfaceXPlane::normal(Position r) const void SurfaceXPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-plane", false); - std::array coeffs {{x0}}; + std::array coeffs {{x0_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -303,15 +303,15 @@ bool SurfaceXPlane::periodic_translate(const PeriodicSurface* other, { Direction other_n = other->normal(r); if (other_n.x == 1 and other_n.y == 0 and other_n.z == 0) { - r.x = x0; + r.x = x0_; return false; } else { // Assume the partner is an YPlane (the only supported partner). Use the - // evaluate function to find y0, then adjust position/Direction for rotational - // symmetry. - double y0 = -other->evaluate({0., 0., 0.}); - r.y = r.x - x0 + y0; - r.x = x0; + // evaluate function to find y0, then adjust position/Direction for + // rotational symmetry. + double y0_ = -other->evaluate({0., 0., 0.}); + r.y = r.x - x0_ + y0_; + r.x = x0_; double ux = u.x; u.x = -u.y; @@ -324,7 +324,7 @@ bool SurfaceXPlane::periodic_translate(const PeriodicSurface* other, BoundingBox SurfaceXPlane::bounding_box() const { - return {x0, x0, -INFTY, INFTY, -INFTY, INFTY}; + return {x0_, x0_, -INFTY, INFTY, -INFTY, INFTY}; } //============================================================================== @@ -334,17 +334,17 @@ SurfaceXPlane::bounding_box() const SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, id, y0); + read_coeffs(surf_node, id_, y0_); } double SurfaceYPlane::evaluate(Position r) const { - return r.y - y0; + return r.y - y0_; } double SurfaceYPlane::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_plane_distance<1>(r, u, coincident, y0); + return axis_aligned_plane_distance<1>(r, u, coincident, y0_); } Direction SurfaceYPlane::normal(Position r) const @@ -355,7 +355,7 @@ Direction SurfaceYPlane::normal(Position r) const void SurfaceYPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-plane", false); - std::array coeffs {{y0}}; + std::array coeffs {{y0_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -365,15 +365,15 @@ bool SurfaceYPlane::periodic_translate(const PeriodicSurface *other, Direction other_n = other->normal(r); if (other_n.x == 0 and other_n.y == 1 and other_n.z == 0) { // The periodic partner is also aligned along y. Just change the y coord. - r.y = y0; + r.y = y0_; return false; } else { // Assume the partner is an XPlane (the only supported partner). Use the // evaluate function to find x0, then adjust position/Direction for rotational // symmetry. - double x0 = -other->evaluate({0., 0., 0.}); - r.x = r.y - y0 + x0; - r.y = y0; + double x0_ = -other->evaluate({0., 0., 0.}); + r.x = r.y - y0_ + x0_; + r.y = y0_; double ux = u.x; u.x = u.y; @@ -386,7 +386,7 @@ bool SurfaceYPlane::periodic_translate(const PeriodicSurface *other, BoundingBox SurfaceYPlane::bounding_box() const { - return {-INFTY, INFTY, y0, y0, -INFTY, INFTY}; + return {-INFTY, INFTY, y0_, y0_, -INFTY, INFTY}; } //============================================================================== @@ -396,17 +396,17 @@ SurfaceYPlane::bounding_box() const SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, id, z0); + read_coeffs(surf_node, id_, z0_); } double SurfaceZPlane::evaluate(Position r) const { - return r.z - z0; + return r.z - z0_; } double SurfaceZPlane::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_plane_distance<2>(r, u, coincident, z0); + return axis_aligned_plane_distance<2>(r, u, coincident, z0_); } Direction SurfaceZPlane::normal(Position r) const @@ -417,7 +417,7 @@ Direction SurfaceZPlane::normal(Position r) const void SurfaceZPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-plane", false); - std::array coeffs {{z0}}; + std::array coeffs {{z0_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -425,14 +425,14 @@ bool SurfaceZPlane::periodic_translate(const PeriodicSurface* other, Position& r, Direction& u) const { // Assume the other plane is aligned along z. Just change the z coord. - r.z = z0; + r.z = z0_; return false; } BoundingBox SurfaceZPlane::bounding_box() const { - return {-INFTY, INFTY, -INFTY, INFTY, z0, z0}; + return {-INFTY, INFTY, -INFTY, INFTY, z0_, z0_}; } //============================================================================== @@ -442,20 +442,20 @@ SurfaceZPlane::bounding_box() const SurfacePlane::SurfacePlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, id, A, B, C, D); + read_coeffs(surf_node, id_, A_, B_, C_, D_); } double SurfacePlane::evaluate(Position r) const { - return A*r.x + B*r.y + C*r.z - D; + return A_*r.x + B_*r.y + C_*r.z - D_; } double SurfacePlane::distance(Position r, Direction u, bool coincident) const { - const double f = A*r.x + B*r.y + C*r.z - D; - const double projection = A*u.x + B*u.y + C*u.z; + const double f = A_*r.x + B_*r.y + C_*r.z - D_; + const double projection = A_*u.x + B_*u.y + C_*u.z; if (coincident or std::abs(f) < FP_COINCIDENT or projection == 0.0) { return INFTY; } else { @@ -468,13 +468,13 @@ SurfacePlane::distance(Position r, Direction u, bool coincident) const Direction SurfacePlane::normal(Position r) const { - return {A, B, C}; + return {A_, B_, C_}; } void SurfacePlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "plane", false); - std::array coeffs {{A, B, C, D}}; + std::array coeffs {{A_, B_, C_, D_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -484,12 +484,12 @@ bool SurfacePlane::periodic_translate(const PeriodicSurface* other, Position& r, // This function assumes the other plane shares this plane's normal direction. // Determine the distance to intersection. - double d = evaluate(r) / (A*A + B*B + C*C); + double d = evaluate(r) / (A_*A_ + B_*B_ + C_*C_); // Move the particle that distance along the normal vector. - r.x -= d * A; - r.y -= d * B; - r.z -= d * C; + r.x -= d * A_; + r.y -= d * B_; + r.z -= d * C_; return false; } @@ -582,30 +582,30 @@ axis_aligned_cylinder_normal(Position r, double offset1, double offset2) SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, y0, z0, radius); + read_coeffs(surf_node, id_, y0_, z0_, radius_); } double SurfaceXCylinder::evaluate(Position r) const { - return axis_aligned_cylinder_evaluate<1, 2>(r, y0, z0, radius); + return axis_aligned_cylinder_evaluate<1, 2>(r, y0_, z0_, radius_); } double SurfaceXCylinder::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_cylinder_distance<0, 1, 2>(r, u, coincident, y0, z0, - radius); + return axis_aligned_cylinder_distance<0, 1, 2>(r, u, coincident, y0_, z0_, + radius_); } Direction SurfaceXCylinder::normal(Position r) const { - return axis_aligned_cylinder_normal<0, 1, 2>(r, y0, z0); + return axis_aligned_cylinder_normal<0, 1, 2>(r, y0_, z0_); } void SurfaceXCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-cylinder", false); - std::array coeffs {{y0, z0, radius}}; + std::array coeffs {{y0_, z0_, radius_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -616,29 +616,29 @@ void SurfaceXCylinder::to_hdf5_inner(hid_t group_id) const SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, x0, z0, radius); + read_coeffs(surf_node, id_, x0_, z0_, radius_); } double SurfaceYCylinder::evaluate(Position r) const { - return axis_aligned_cylinder_evaluate<0, 2>(r, x0, z0, radius); + return axis_aligned_cylinder_evaluate<0, 2>(r, x0_, z0_, radius_); } double SurfaceYCylinder::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_cylinder_distance<1, 0, 2>(r, u, coincident, x0, z0, - radius); + return axis_aligned_cylinder_distance<1, 0, 2>(r, u, coincident, x0_, z0_, + radius_); } Direction SurfaceYCylinder::normal(Position r) const { - return axis_aligned_cylinder_normal<1, 0, 2>(r, x0, z0); + return axis_aligned_cylinder_normal<1, 0, 2>(r, x0_, z0_); } void SurfaceYCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-cylinder", false); - std::array coeffs {{x0, z0, radius}}; + std::array coeffs {{x0_, z0_, radius_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -649,29 +649,29 @@ void SurfaceYCylinder::to_hdf5_inner(hid_t group_id) const SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, x0, y0, radius); + read_coeffs(surf_node, id_, x0_, y0_, radius_); } double SurfaceZCylinder::evaluate(Position r) const { - return axis_aligned_cylinder_evaluate<0, 1>(r, x0, y0, radius); + return axis_aligned_cylinder_evaluate<0, 1>(r, x0_, y0_, radius_); } double SurfaceZCylinder::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_cylinder_distance<2, 0, 1>(r, u, coincident, x0, y0, - radius); + return axis_aligned_cylinder_distance<2, 0, 1>(r, u, coincident, x0_, y0_, + radius_); } Direction SurfaceZCylinder::normal(Position r) const { - return axis_aligned_cylinder_normal<2, 0, 1>(r, x0, y0); + return axis_aligned_cylinder_normal<2, 0, 1>(r, x0_, y0_); } void SurfaceZCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-cylinder", false); - std::array coeffs {{x0, y0, radius}}; + std::array coeffs {{x0_, y0_, radius_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -682,24 +682,24 @@ void SurfaceZCylinder::to_hdf5_inner(hid_t group_id) const SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, x0, y0, z0, radius); + read_coeffs(surf_node, id_, x0_, y0_, z0_, radius_); } double SurfaceSphere::evaluate(Position r) const { - const double x = r.x - x0; - const double y = r.y - y0; - const double z = r.z - z0; - return x*x + y*y + z*z - radius*radius; + const double x = r.x - x0_; + const double y = r.y - y0_; + const double z = r.z - z0_; + return x*x + y*y + z*z - radius_*radius_; } double SurfaceSphere::distance(Position r, Direction u, bool coincident) const { - const double x = r.x - x0; - const double y = r.y - y0; - const double z = r.z - z0; + const double x = r.x - x0_; + const double y = r.y - y0_; + const double z = r.z - z0_; const double k = x*u.x + y*u.y + z*u.z; - const double c = x*x + y*y + z*z - radius*radius; + const double c = x*x + y*y + z*z - radius_*radius_; const double quad = k*k - c; if (quad < 0.0) { @@ -733,13 +733,13 @@ double SurfaceSphere::distance(Position r, Direction u, bool coincident) const Direction SurfaceSphere::normal(Position r) const { - return {2.0*(r.x - x0), 2.0*(r.y - y0), 2.0*(r.z - z0)}; + return {2.0*(r.x - x0_), 2.0*(r.y - y0_), 2.0*(r.z - z0_)}; } void SurfaceSphere::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "sphere", false); - std::array coeffs {{x0, y0, z0, radius}}; + std::array coeffs {{x0_, y0_, z0_, radius_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -835,29 +835,29 @@ axis_aligned_cone_normal(Position r, double offset1, double offset2, SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, x0, y0, z0, radius_sq); + read_coeffs(surf_node, id_, x0_, y0_, z0_, radius_sq_); } double SurfaceXCone::evaluate(Position r) const { - return axis_aligned_cone_evaluate<0, 1, 2>(r, x0, y0, z0, radius_sq); + return axis_aligned_cone_evaluate<0, 1, 2>(r, x0_, y0_, z0_, radius_sq_); } double SurfaceXCone::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_cone_distance<0, 1, 2>(r, u, coincident, x0, y0, z0, - radius_sq); + return axis_aligned_cone_distance<0, 1, 2>(r, u, coincident, x0_, y0_, z0_, + radius_sq_); } Direction SurfaceXCone::normal(Position r) const { - return axis_aligned_cone_normal<0, 1, 2>(r, x0, y0, z0, radius_sq); + return axis_aligned_cone_normal<0, 1, 2>(r, x0_, y0_, z0_, radius_sq_); } void SurfaceXCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-cone", false); - std::array coeffs {{x0, y0, z0, radius_sq}}; + std::array coeffs {{x0_, y0_, z0_, radius_sq_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -868,29 +868,29 @@ void SurfaceXCone::to_hdf5_inner(hid_t group_id) const SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, x0, y0, z0, radius_sq); + read_coeffs(surf_node, id_, x0_, y0_, z0_, radius_sq_); } double SurfaceYCone::evaluate(Position r) const { - return axis_aligned_cone_evaluate<1, 0, 2>(r, y0, x0, z0, radius_sq); + return axis_aligned_cone_evaluate<1, 0, 2>(r, y0_, x0_, z0_, radius_sq_); } double SurfaceYCone::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_cone_distance<1, 0, 2>(r, u, coincident, y0, x0, z0, - radius_sq); + return axis_aligned_cone_distance<1, 0, 2>(r, u, coincident, y0_, x0_, z0_, + radius_sq_); } Direction SurfaceYCone::normal(Position r) const { - return axis_aligned_cone_normal<1, 0, 2>(r, y0, x0, z0, radius_sq); + return axis_aligned_cone_normal<1, 0, 2>(r, y0_, x0_, z0_, radius_sq_); } void SurfaceYCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-cone", false); - std::array coeffs {{x0, y0, z0, radius_sq}}; + std::array coeffs {{x0_, y0_, z0_, radius_sq_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -901,29 +901,29 @@ void SurfaceYCone::to_hdf5_inner(hid_t group_id) const SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, x0, y0, z0, radius_sq); + read_coeffs(surf_node, id_, x0_, y0_, z0_, radius_sq_); } double SurfaceZCone::evaluate(Position r) const { - return axis_aligned_cone_evaluate<2, 0, 1>(r, z0, x0, y0, radius_sq); + return axis_aligned_cone_evaluate<2, 0, 1>(r, z0_, x0_, y0_, radius_sq_); } double SurfaceZCone::distance(Position r, Direction u, bool coincident) const { - return axis_aligned_cone_distance<2, 0, 1>(r, u, coincident, z0, x0, y0, - radius_sq); + return axis_aligned_cone_distance<2, 0, 1>(r, u, coincident, z0_, x0_, y0_, + radius_sq_); } Direction SurfaceZCone::normal(Position r) const { - return axis_aligned_cone_normal<2, 0, 1>(r, z0, x0, y0, radius_sq); + return axis_aligned_cone_normal<2, 0, 1>(r, z0_, x0_, y0_, radius_sq_); } void SurfaceZCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-cone", false); - std::array coeffs {{x0, y0, z0, radius_sq}}; + std::array coeffs {{x0_, y0_, z0_, radius_sq_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -934,7 +934,7 @@ void SurfaceZCone::to_hdf5_inner(hid_t group_id) const SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, id, A, B, C, D, E, F, G, H, J, K); + read_coeffs(surf_node, id_, A_, B_, C_, D_, E_, F_, G_, H_, J_, K_); } double @@ -943,9 +943,9 @@ SurfaceQuadric::evaluate(Position r) const const double x = r.x; const double y = r.y; const double z = r.z; - return x*(A*x + D*y + G) + - y*(B*y + E*z + H) + - z*(C*z + F*x + J) + K; + return x*(A_*x + D_*y + G_) + + y*(B_*y + E_*z + H_) + + z*(C_*z + F_*x + J_) + K_; } double @@ -958,11 +958,11 @@ SurfaceQuadric::distance(Position r, Direction ang, bool coincident) const const double &v = ang.y; const double &w = ang.z; - const double a = A*u*u + B*v*v + C*w*w + D*u*v + E*v*w + F*u*w; - const double k = (A*u*x + B*v*y + C*w*z + 0.5*(D*(u*y + v*x) + - E*(v*z + w*y) + F*(w*x + u*z) + G*u + H*v + J*w)); - const double c = A*x*x + B*y*y + C*z*z + D*x*y + E*y*z + F*x*z + G*x + H*y - + J*z + K; + const double a = A_*u*u + B_*v*v + C_*w*w + D_*u*v + E_*v*w + F_*u*w; + const double k = A_*u*x + B_*v*y + C_*w*z + 0.5*(D_*(u*y + v*x) + + E_*(v*z + w*y) + F_*(w*x + u*z) + G_*u + H_*v + J_*w); + const double c = A_*x*x + B_*y*y + C_*z*z + D_*x*y + E_*y*z + F_*x*z + G_*x + + H_*y + J_*z + K_; double quad = k*k - a*c; double d; @@ -1008,15 +1008,15 @@ SurfaceQuadric::normal(Position r) const const double &x = r.x; const double &y = r.y; const double &z = r.z; - return {2.0*A*x + D*y + F*z + G, - 2.0*B*y + D*x + E*z + H, - 2.0*C*z + E*y + F*x + J}; + return {2.0*A_*x + D_*y + F_*z + G_, + 2.0*B_*y + D_*x + E_*z + H_, + 2.0*C_*z + E_*y + F_*x + J_}; } void SurfaceQuadric::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "quadric", false); - std::array coeffs {{A, B, C, D, E, F, G, H, J, K}}; + std::array coeffs {{A_, B_, C_, D_, E_, F_, G_, H_, J_, K_}}; write_dataset(group_id, "coefficients", coeffs); } @@ -1086,7 +1086,7 @@ read_surfaces(pugi::xml_node* node) // Fill the surface map. for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - int id = global_surfaces[i_surf]->id; + int id = global_surfaces[i_surf]->id_; auto in_map = surface_map.find(id); if (in_map == surface_map.end()) { surface_map[id] = i_surf; @@ -1102,7 +1102,7 @@ read_surfaces(pugi::xml_node* node) zmin {INFTY}, zmax {-INFTY}; int i_xmin, i_xmax, i_ymin, i_ymax, i_zmin, i_zmax; for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - if (global_surfaces[i_surf]->bc == BC_PERIODIC) { + if (global_surfaces[i_surf]->bc_ == BC_PERIODIC) { // Downcast to the PeriodicSurface type. Surface* surf_base = global_surfaces[i_surf]; PeriodicSurface* surf = dynamic_cast(surf_base); @@ -1111,7 +1111,7 @@ read_surfaces(pugi::xml_node* node) if (!surf) { std::stringstream err_msg; err_msg << "Periodic boundary condition not supported for surface " - << surf_base->id + << surf_base->id_ << ". Periodic BCs are only supported for planar surfaces."; fatal_error(err_msg); } @@ -1147,7 +1147,7 @@ read_surfaces(pugi::xml_node* node) // Set i_periodic for periodic BC surfaces. for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - if (global_surfaces[i_surf]->bc == BC_PERIODIC) { + if (global_surfaces[i_surf]->bc_ == BC_PERIODIC) { // Downcast to the PeriodicSurface type. Surface* surf_base = global_surfaces[i_surf]; PeriodicSurface* surf = dynamic_cast(surf_base); @@ -1158,48 +1158,48 @@ read_surfaces(pugi::xml_node* node) if (!surf_p) { // This is not a SurfacePlane. - if (surf->i_periodic == C_NONE) { + if (surf->i_periodic_ == C_NONE) { // The user did not specify the matching periodic surface. See if we // can find the partnered surface from the bounding box information. if (i_surf == i_xmin) { - surf->i_periodic = i_xmax; + surf->i_periodic_ = i_xmax; } else if (i_surf == i_xmax) { - surf->i_periodic = i_xmin; + surf->i_periodic_ = i_xmin; } else if (i_surf == i_ymin) { - surf->i_periodic = i_ymax; + surf->i_periodic_ = i_ymax; } else if (i_surf == i_ymax) { - surf->i_periodic = i_ymin; + surf->i_periodic_ = i_ymin; } else if (i_surf == i_zmin) { - surf->i_periodic = i_zmax; + surf->i_periodic_ = i_zmax; } else if (i_surf == i_zmax) { - surf->i_periodic = i_zmin; + surf->i_periodic_ = i_zmin; } else { fatal_error("Periodic boundary condition applied to interior " "surface"); } } else { // Convert the surface id to an index. - surf->i_periodic = surface_map[surf->i_periodic]; + surf->i_periodic_ = surface_map[surf->i_periodic_]; } } else { // This is a SurfacePlane. We won't try to find it's partner if the // user didn't specify one. - if (surf->i_periodic == C_NONE) { + if (surf->i_periodic_ == C_NONE) { std::stringstream err_msg; err_msg << "No matching periodic surface specified for periodic " - "boundary condition on surface " << surf->id; + "boundary condition on surface " << surf->id_; fatal_error(err_msg); } else { // Convert the surface id to an index. - surf->i_periodic = surface_map[surf->i_periodic]; + surf->i_periodic_ = surface_map[surf->i_periodic_]; } } // Make sure the opposite surface is also periodic. - if (global_surfaces[surf->i_periodic]->bc != BC_PERIODIC) { + if (global_surfaces[surf->i_periodic_]->bc_ != BC_PERIODIC) { std::stringstream err_msg; err_msg << "Could not find matching surface for periodic boundary " - "condition on surface " << surf->id; + "condition on surface " << surf->id_; fatal_error(err_msg); } } @@ -1213,9 +1213,9 @@ read_surfaces(pugi::xml_node* node) extern "C" { Surface* surface_pointer(int surf_ind) {return global_surfaces[surf_ind];} - int surface_id(Surface* surf) {return surf->id;} + int surface_id(Surface* surf) {return surf->id_;} - int surface_bc(Surface* surf) {return surf->bc;} + int surface_bc(Surface* surf) {return surf->bc_;} void surface_reflect(Surface* surf, double xyz[3], double uvw[3]) { @@ -1228,7 +1228,7 @@ extern "C" { uvw[2] = u.z; } - int surface_i_periodic(PeriodicSurface* surf) {return surf->i_periodic;} + int surface_i_periodic(PeriodicSurface* surf) {return surf->i_periodic_;} bool surface_periodic(PeriodicSurface* surf, PeriodicSurface* other, double xyz[3], From 0e348e338b9b17f804c081fd5dd19cc5f2dda030 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 27 Aug 2018 19:06:01 -0400 Subject: [PATCH 41/43] Remove global_ prefix from global geometry vectors --- include/openmc/cell.h | 4 +- include/openmc/lattice.h | 2 +- include/openmc/material.h | 2 +- include/openmc/surface.h | 2 +- src/cell.cpp | 68 +++++++++++++-------------- src/geometry.cpp | 34 +++++++------- src/geometry_aux.cpp | 98 +++++++++++++++++++-------------------- src/lattice.cpp | 20 ++++---- src/material.cpp | 28 +++++------ src/output.cpp | 4 +- src/summary.cpp | 16 +++---- src/surface.cpp | 46 +++++++++--------- 12 files changed, 162 insertions(+), 162 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index fddfb1adb5..fa5134b60f 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -39,11 +39,11 @@ constexpr int32_t OP_UNION {std::numeric_limits::max() - 4}; extern "C" int32_t n_cells; class Cell; -extern std::vector global_cells; +extern std::vector cells; extern std::unordered_map cell_map; class Universe; -extern std::vector global_universes; +extern std::vector universes; extern std::unordered_map universe_map; //============================================================================== diff --git a/include/openmc/lattice.h b/include/openmc/lattice.h index 10f6b46179..cacb87abea 100644 --- a/include/openmc/lattice.h +++ b/include/openmc/lattice.h @@ -31,7 +31,7 @@ enum class LatticeType { //============================================================================== class Lattice; -extern std::vector lattices_c; +extern std::vector lattices; extern std::unordered_map lattice_map; diff --git a/include/openmc/material.h b/include/openmc/material.h index 9390ef5980..1af6f85976 100644 --- a/include/openmc/material.h +++ b/include/openmc/material.h @@ -14,7 +14,7 @@ namespace openmc { //============================================================================== class Material; -extern std::vector global_materials; +extern std::vector materials; extern std::unordered_map material_map; //============================================================================== diff --git a/include/openmc/surface.h b/include/openmc/surface.h index 16f75b907b..23d5d15438 100644 --- a/include/openmc/surface.h +++ b/include/openmc/surface.h @@ -32,7 +32,7 @@ extern "C" const int BC_PERIODIC; extern "C" int32_t n_surfaces; class Surface; -extern std::vector global_surfaces; +extern std::vector surfaces; extern std::map surface_map; diff --git a/src/cell.cpp b/src/cell.cpp index c6b39f314d..c0eaa3ebfb 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -24,10 +24,10 @@ namespace openmc { int32_t n_cells {0}; -std::vector global_cells; +std::vector cells; std::unordered_map cell_map; -std::vector global_universes; +std::vector universes; std::unordered_map universe_map; //============================================================================== @@ -198,7 +198,7 @@ Universe::to_hdf5(hid_t universes_group) const // Write the contained cells. if (cells_.size() > 0) { std::vector cell_ids; - for (auto i_cell : cells_) cell_ids.push_back(global_cells[i_cell]->id_); + for (auto i_cell : cells_) cell_ids.push_back(cells[i_cell]->id_); write_dataset(group, "cells", cell_ids); } @@ -417,7 +417,7 @@ Cell::distance(Position r, Direction u, int32_t on_surface) const // Calculate the distance to this surface. // Note the off-by-one indexing bool coincident {token == on_surface}; - double d {global_surfaces[abs(token)-1]->distance(r, u, coincident)}; + double d {surfaces[abs(token)-1]->distance(r, u, coincident)}; // Check if this distance is the new minimum. if (d < min_dist) { @@ -445,7 +445,7 @@ Cell::to_hdf5(hid_t cells_group) const write_string(group, "name", name_, false); } - write_dataset(group, "universe", global_universes[universe_]->id_); + write_dataset(group, "universe", universes[universe_]->id_); // Write the region specification. if (!region_.empty()) { @@ -463,7 +463,7 @@ Cell::to_hdf5(hid_t cells_group) const } else { // Note the off-by-one indexing region_spec << " " - << copysign(global_surfaces[abs(token)-1]->id_, token); + << copysign(surfaces[abs(token)-1]->id_, token); } } write_string(group, "region", region_spec.str(), false); @@ -475,7 +475,7 @@ Cell::to_hdf5(hid_t cells_group) const std::vector mat_ids; for (auto i_mat : material_) { if (i_mat != MATERIAL_VOID) { - mat_ids.push_back(global_materials[i_mat]->id); + mat_ids.push_back(materials[i_mat]->id); } else { mat_ids.push_back(MATERIAL_VOID); } @@ -493,7 +493,7 @@ Cell::to_hdf5(hid_t cells_group) const } else if (type_ == FILL_UNIVERSE) { write_dataset(group, "fill_type", "universe"); - write_dataset(group, "fill", global_universes[fill_]->id_); + write_dataset(group, "fill", universes[fill_]->id_); if (translation_ != Position(0, 0, 0)) { write_dataset(group, "translation", translation_); } @@ -504,7 +504,7 @@ Cell::to_hdf5(hid_t cells_group) const } else if (type_ == FILL_LATTICE) { write_dataset(group, "fill_type", "lattice"); - write_dataset(group, "lattice", lattices_c[fill_]->id_); + write_dataset(group, "lattice", lattices[fill_]->id_); } close_group(group); @@ -526,7 +526,7 @@ Cell::contains_simple(Position r, Direction u, int32_t on_surface) const return false; } else { // Note the off-by-one indexing - bool sense = global_surfaces[abs(token)-1]->sense(r, u); + bool sense = surfaces[abs(token)-1]->sense(r, u); if (sense != (token > 0)) {return false;} } } @@ -568,7 +568,7 @@ Cell::contains_complex(Position r, Direction u, int32_t on_surface) const stack[i_stack] = false; } else { // Note the off-by-one indexing - bool sense = global_surfaces[abs(token)-1]->sense(r, u); + bool sense = surfaces[abs(token)-1]->sense(r, u); stack[i_stack] = (sense == (token > 0)); } } @@ -599,25 +599,25 @@ read_cells(pugi::xml_node* node) } // Loop over XML cell elements and populate the array. - global_cells.reserve(n_cells); + cells.reserve(n_cells); for (pugi::xml_node cell_node: node->children("cell")) { - global_cells.push_back(new Cell(cell_node)); + cells.push_back(new Cell(cell_node)); } // Populate the Universe vector and map. - for (int i = 0; i < global_cells.size(); i++) { - int32_t uid = global_cells[i]->universe_; + for (int i = 0; i < cells.size(); i++) { + int32_t uid = cells[i]->universe_; auto it = universe_map.find(uid); if (it == universe_map.end()) { - global_universes.push_back(new Universe()); - global_universes.back()->id_ = uid; - global_universes.back()->cells_.push_back(i); - universe_map[uid] = global_universes.size() - 1; + universes.push_back(new Universe()); + universes.back()->id_ = uid; + universes.back()->cells_.push_back(i); + universe_map[uid] = universes.size() - 1; } else { - global_universes[it->second]->cells_.push_back(i); + universes[it->second]->cells_.push_back(i); } } - global_universes.shrink_to_fit(); + universes.shrink_to_fit(); // Allocate the cell overlap count if necessary. if (openmc_check_overlaps) overlap_check_count.resize(n_cells, 0); @@ -630,9 +630,9 @@ read_cells(pugi::xml_node* node) extern "C" int openmc_cell_get_fill(int32_t index, int* type, int32_t** indices, int32_t* n) { - if (index >= 1 && index <= global_cells.size()) { + if (index >= 1 && index <= cells.size()) { //TODO: off-by-one - Cell& c {*global_cells[index - 1]}; + Cell& c {*cells[index - 1]}; *type = c.type_; if (c.type_ == FILL_MATERIAL) { *indices = c.material_.data(); @@ -652,9 +652,9 @@ extern "C" int openmc_cell_set_fill(int32_t index, int type, int32_t n, const int32_t* indices) { - if (index >= 1 && index <= global_cells.size()) { + if (index >= 1 && index <= cells.size()) { //TODO: off-by-one - Cell& c {*global_cells[index - 1]}; + Cell& c {*cells[index - 1]}; if (type == FILL_MATERIAL) { c.type_ = FILL_MATERIAL; c.material_.clear(); @@ -662,7 +662,7 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n, int i_mat = indices[i]; if (i_mat == MATERIAL_VOID) { c.material_.push_back(MATERIAL_VOID); - } else if (i_mat >= 1 && i_mat <= global_materials.size()) { + } else if (i_mat >= 1 && i_mat <= materials.size()) { //TODO: off-by-one c.material_.push_back(i_mat - 1); } else { @@ -687,9 +687,9 @@ openmc_cell_set_fill(int32_t index, int type, int32_t n, extern "C" int openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) { - if (index >= 1 && index <= global_cells.size()) { + if (index >= 1 && index <= cells.size()) { //TODO: off-by-one - Cell& c {*global_cells[index - 1]}; + Cell& c {*cells[index - 1]}; if (instance) { if (*instance >= 0 && *instance < c.sqrtkT_.size()) { @@ -717,7 +717,7 @@ openmc_cell_set_temperature(int32_t index, double T, const int32_t* instance) //============================================================================== extern "C" { - Cell* cell_pointer(int32_t cell_ind) {return global_cells[cell_ind];} + Cell* cell_pointer(int32_t cell_ind) {return cells[cell_ind];} int32_t cell_id(Cell* c) {return c->id_;} @@ -751,17 +751,17 @@ extern "C" { void extend_cells_c(int32_t n) { - global_cells.reserve(global_cells.size() + n); + cells.reserve(cells.size() + n); for (int32_t i = 0; i < n; i++) { - global_cells.push_back(new Cell()); + cells.push_back(new Cell()); } - n_cells = global_cells.size(); + n_cells = cells.size(); } - int32_t universe_id(int i_univ) {return global_universes[i_univ]->id_;} + int32_t universe_id(int i_univ) {return universes[i_univ]->id_;} void universes_to_hdf5(hid_t universes_group) - {for (Universe* u : global_universes) u->to_hdf5(universes_group);} + {for (Universe* u : universes) u->to_hdf5(universes_group);} } diff --git a/src/geometry.cpp b/src/geometry.cpp index 1999738d51..22e3cbfe34 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -25,17 +25,17 @@ check_cell_overlap(Particle* p) { // Loop through each coordinate level for (int j = 0; j < n_coord; j++) { - Universe& univ = *global_universes[p->coord[j].universe]; + Universe& univ = *universes[p->coord[j].universe]; int n = univ.cells_.size(); // Loop through each cell on this level for (auto index_cell : univ.cells_) { - Cell& c = *global_cells[index_cell]; + Cell& c = *cells[index_cell]; if (c.contains(p->coord[j].xyz, p->coord[j].uvw, p->surface)) { if (index_cell != p->coord[j].cell) { std::stringstream err_msg; err_msg << "Overlapping cells detected: " << c.id_ << ", " - << global_cells[p->coord[j].cell]->id_ << " on universe " + << cells[p->coord[j].cell]->id_ << " on universe " << univ.id_; fatal_error(err_msg); } @@ -67,12 +67,12 @@ find_cell(Particle* p, int search_surf) { // the positive or negative side of the surface should be searched. const std::vector* search_cells; if (search_surf > 0) { - search_cells = &global_surfaces[search_surf-1]->neighbor_pos_; + search_cells = &surfaces[search_surf-1]->neighbor_pos_; } else if (search_surf < 0) { - search_cells = &global_surfaces[-search_surf-1]->neighbor_neg_; + search_cells = &surfaces[-search_surf-1]->neighbor_neg_; } else { // No surface was indicated, search all cells in the universe. - search_cells = &global_universes[i_universe]->cells_; + search_cells = &universes[i_universe]->cells_; } // Find which cell of this universe the particle is in. @@ -82,17 +82,17 @@ find_cell(Particle* p, int search_surf) { i_cell = (*search_cells)[i]; // Make sure the search cell is in the same universe. - if (global_cells[i_cell]->universe_ != i_universe) continue; + if (cells[i_cell]->universe_ != i_universe) continue; Position r {p->coord[p->n_coord-1].xyz}; Direction u {p->coord[p->n_coord-1].uvw}; int32_t surf = p->surface; - if (global_cells[i_cell]->contains(r, u, surf)) { + if (cells[i_cell]->contains(r, u, surf)) { p->coord[p->n_coord-1].cell = i_cell; if (openmc_verbosity >= 10 || openmc_trace) { std::stringstream msg; - msg << " Entering cell " << global_cells[i_cell]->id_; + msg << " Entering cell " << cells[i_cell]->id_; write_message(msg, 1); } found = true; @@ -101,7 +101,7 @@ find_cell(Particle* p, int search_surf) { } if (found) { - Cell& c {*global_cells[i_cell]}; + Cell& c {*cells[i_cell]}; if (c.type_ == FILL_MATERIAL) { //======================================================================= //! Found a material cell which means this is the lowest coord level. @@ -112,11 +112,11 @@ find_cell(Particle* p, int search_surf) { int distribcell_index = c.distribcell_index_ - 1; int offset = 0; for (int i = 0; i < p->n_coord; i++) { - Cell& c_i {*global_cells[p->coord[i].cell]}; + Cell& c_i {*cells[p->coord[i].cell]}; if (c_i.type_ == FILL_UNIVERSE) { offset += c_i.offset_[distribcell_index]; } else if (c_i.type_ == FILL_LATTICE) { - Lattice& lat {*lattices_c[p->coord[i+1].lattice-1]}; + Lattice& lat {*lattices[p->coord[i+1].lattice-1]}; int i_xyz[3] {p->coord[i+1].lattice_x, p->coord[i+1].lattice_y, p->coord[i+1].lattice_z}; @@ -201,7 +201,7 @@ find_cell(Particle* p, int search_surf) { //======================================================================== //! Found a lower lattice, update this coord level then search the next. - Lattice& lat {*lattices_c[c.fill_]}; + Lattice& lat {*lattices[c.fill_]}; // Determine lattice indices. Position r {p->coord[p->n_coord-1].xyz}; @@ -252,7 +252,7 @@ find_cell(Particle* p, int search_surf) { extern "C" void cross_lattice(Particle* p, int lattice_translation[3]) { - Lattice& lat {*lattices_c[p->coord[p->n_coord-1].lattice-1]}; + Lattice& lat {*lattices[p->coord[p->n_coord-1].lattice-1]}; if (openmc_verbosity >= 10 || openmc_trace) { std::stringstream msg; @@ -327,7 +327,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, for (int i = 0; i < p->n_coord; i++) { Position r {p->coord[i].xyz}; Direction u {p->coord[i].uvw}; - Cell& c {*global_cells[p->coord[i].cell]}; + Cell& c {*cells[p->coord[i].cell]}; // Find the oncoming surface in this cell and the distance to it. auto surface_distance = c.distance(r, u, p->surface); @@ -336,7 +336,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, // Find the distance to the next lattice tile crossing. if (p->coord[i].lattice != F90_NONE) { - Lattice& lat {*lattices_c[p->coord[i].lattice-1]}; + Lattice& lat {*lattices[p->coord[i].lattice-1]}; std::array i_xyz {p->coord[i].lattice_x, p->coord[i].lattice_y, p->coord[i].lattice_z}; //TODO: refactor so both lattice use the same position argument (which @@ -378,7 +378,7 @@ distance_to_boundary(Particle* p, double* dist, int* surface_crossed, *surface_crossed = level_surf_cross; } else { Position r_hit = r + d_surf * u; - Surface& surf {*global_surfaces[std::abs(level_surf_cross)-1]}; + Surface& surf {*surfaces[std::abs(level_surf_cross)-1]}; Direction norm = surf.normal(r_hit); if (u.dot(norm) > 0) { *surface_crossed = std::abs(level_surf_cross); diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 768b2dd4ec..9c1d17b4d6 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -22,7 +22,7 @@ void adjust_indices() { // Adjust material/fill idices. - for (Cell* c : global_cells) { + for (Cell* c : cells) { if (c->fill_ != C_NONE) { int32_t id = c->fill_; auto search_univ = universe_map.find(id); @@ -59,7 +59,7 @@ adjust_indices() } // Change cell.universe values from IDs to indices. - for (Cell* c : global_cells) { + for (Cell* c : cells) { auto search = universe_map.find(c->universe_); if (search != universe_map.end()) { c->universe_ = search->second; @@ -72,7 +72,7 @@ adjust_indices() } // Change all lattice universe values from IDs to indices. - for (Lattice* l : lattices_c) { + for (Lattice* l : lattices) { l->adjust_indices(); } } @@ -82,7 +82,7 @@ adjust_indices() void assign_temperatures() { - for (Cell* c : global_cells) { + for (Cell* c : cells) { // Ignore non-material cells and cells with defined temperature. if (c->material_.size() == 0) continue; if (c->sqrtkT_.size() > 0) continue; @@ -94,9 +94,9 @@ assign_temperatures() c->sqrtkT_.push_back(0); } else { - if (global_materials[i_mat]->temperature_ >= 0) { + if (materials[i_mat]->temperature_ >= 0) { // This material has a default temperature; use that value. - auto T = global_materials[i_mat]->temperature_; + auto T = materials[i_mat]->temperature_; c->sqrtkT_.push_back(std::sqrt(K_BOLTZMANN * T)); } else { // Use the global default temperature. @@ -114,12 +114,12 @@ find_root_universe() { // Find all the universes listed as a cell fill. std::unordered_set fill_univ_ids; - for (Cell* c : global_cells) { + for (Cell* c : cells) { fill_univ_ids.insert(c->fill_); } // Find all the universes contained in a lattice. - for (Lattice* lat : lattices_c) { + for (Lattice* lat : lattices) { for (auto it = lat->begin(); it != lat->end(); ++it) { fill_univ_ids.insert(*it); } @@ -131,8 +131,8 @@ find_root_universe() // Figure out which universe is not in the set. This is the root universe. bool root_found {false}; int32_t root_univ; - for (int32_t i = 0; i < global_universes.size(); i++) { - auto search = fill_univ_ids.find(global_universes[i]->id_); + for (int32_t i = 0; i < universes.size(); i++) { + auto search = fill_univ_ids.find(universes[i]->id_); if (search == fill_univ_ids.end()) { if (root_found) { fatal_error("Two or more universes are not used as fill universes, so " @@ -157,21 +157,21 @@ neighbor_lists() { write_message("Building neighboring cells lists for each surface...", 6); - for (int i = 0; i < global_cells.size(); i++) { - for (auto token : global_cells[i]->region_) { + for (int i = 0; i < cells.size(); i++) { + for (auto token : cells[i]->region_) { // Skip operator tokens. if (std::abs(token) >= OP_UNION) continue; // This token is a surface index. Add the cell to the surface's list. if (token > 0) { - global_surfaces[std::abs(token)-1]->neighbor_pos_.push_back(i); + surfaces[std::abs(token)-1]->neighbor_pos_.push_back(i); } else { - global_surfaces[std::abs(token)-1]->neighbor_neg_.push_back(i); + surfaces[std::abs(token)-1]->neighbor_neg_.push_back(i); } } } - for (Surface* surf : global_surfaces) { + for (Surface* surf : surfaces) { surf->neighbor_pos_.shrink_to_fit(); surf->neighbor_neg_.shrink_to_fit(); } @@ -190,8 +190,8 @@ prepare_distribcell(int32_t* filter_cell_list, int n) // 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]}; + for (int i = 0; i < cells.size(); i++) { + Cell& c {*cells[i]}; if (c.material_.size() > 1) { if (c.material_.size() != c.n_instances_) { @@ -223,10 +223,10 @@ prepare_distribcell(int32_t* filter_cell_list, int n) //TODO: off-by-one int distribcell_index = 1; std::vector target_univ_ids; - for (Universe* u : global_universes) { + for (Universe* u : universes) { for (auto cell_indx : u->cells_) { if (distribcells.find(cell_indx) != distribcells.end()) { - global_cells[cell_indx]->distribcell_index_ = distribcell_index; + cells[cell_indx]->distribcell_index_ = distribcell_index; target_univ_ids.push_back(u->id_); ++distribcell_index; } @@ -235,22 +235,22 @@ prepare_distribcell(int32_t* filter_cell_list, int n) // Allocate the cell and lattice offset tables. int n_maps = target_univ_ids.size(); - for (Cell* c : global_cells) { + for (Cell* c : cells) { if (c->type_ != FILL_MATERIAL) { c->offset_.resize(n_maps, C_NONE); } } - for (Lattice* lat : lattices_c) { + for (Lattice* lat : lattices) { 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) { + for (Universe* univ : 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]; + Cell& c = *cells[cell_indx]; if (c.type_ == FILL_UNIVERSE) { c.offset_[map] = offset; @@ -258,7 +258,7 @@ prepare_distribcell(int32_t* filter_cell_list, int n) offset += count_universe_instances(search_univ, target_univ_id); } else if (c.type_ == FILL_LATTICE) { - Lattice& lat = *lattices_c[c.fill_]; + Lattice& lat = *lattices[c.fill_]; offset = lat.fill_offset_table(offset, target_univ_id, map); } } @@ -271,8 +271,8 @@ prepare_distribcell(int32_t* filter_cell_list, int n) void count_cell_instances(int32_t univ_indx) { - for (int32_t cell_indx : global_universes[univ_indx]->cells_) { - Cell& c = *global_cells[cell_indx]; + for (int32_t cell_indx : universes[univ_indx]->cells_) { + Cell& c = *cells[cell_indx]; ++c.n_instances_; if (c.type_ == FILL_UNIVERSE) { @@ -281,7 +281,7 @@ count_cell_instances(int32_t univ_indx) } else if (c.type_ == FILL_LATTICE) { // This cell contains a lattice. Recurse into the lattice universes. - Lattice& lat = *lattices_c[c.fill_]; + Lattice& lat = *lattices[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { count_cell_instances(*it); } @@ -295,20 +295,20 @@ int count_universe_instances(int32_t search_univ, int32_t target_univ_id) { // If this is the target, it can't contain itself. - if (global_universes[search_univ]->id_ == target_univ_id) { + if (universes[search_univ]->id_ == target_univ_id) { return 1; } int count {0}; - for (int32_t cell_indx : global_universes[search_univ]->cells_) { - Cell& c = *global_cells[cell_indx]; + for (int32_t cell_indx : universes[search_univ]->cells_) { + Cell& c = *cells[cell_indx]; if (c.type_ == FILL_UNIVERSE) { int32_t next_univ = c.fill_; count += count_universe_instances(next_univ, target_univ_id); } else if (c.type_ == FILL_LATTICE) { - Lattice& lat = *lattices_c[c.fill_]; + Lattice& lat = *lattices[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { int32_t next_univ = *it; count += count_universe_instances(next_univ, target_univ_id); @@ -333,7 +333,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, // write to the path and return. for (int32_t cell_indx : search_univ.cells_) { if ((cell_indx == target_cell) && (offset == target_offset)) { - Cell& c = *global_cells[cell_indx]; + Cell& c = *cells[cell_indx]; path << "c" << c.id_; return path.str(); } @@ -345,7 +345,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, std::vector::const_reverse_iterator cell_it {search_univ.cells_.crbegin()}; for (; cell_it != search_univ.cells_.crend(); ++cell_it) { - Cell& c = *global_cells[*cell_it]; + Cell& c = *cells[*cell_it]; // Material cells don't contain other cells so ignore them. if (c.type_ != FILL_MATERIAL) { @@ -353,7 +353,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, if (c.type_ == FILL_UNIVERSE) { temp_offset = offset + c.offset_[map]; } else { - Lattice& lat = *lattices_c[c.fill_]; + Lattice& lat = *lattices[c.fill_]; int32_t indx = lat.universes_.size()*map + lat.begin().indx_; temp_offset = offset + lat.offsets_[indx]; } @@ -365,18 +365,18 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, } // Add the cell to the path string. - Cell& c = *global_cells[*cell_it]; + Cell& c = *cells[*cell_it]; path << "c" << c.id_ << "->"; if (c.type_ == FILL_UNIVERSE) { // Recurse into the fill cell. offset += c.offset_[map]; path << distribcell_path_inner(target_cell, map, target_offset, - *global_universes[c.fill_], offset); + *universes[c.fill_], offset); return path.str(); } else { // Recurse into the lattice cell. - Lattice& lat = *lattices_c[c.fill_]; + Lattice& lat = *lattices[c.fill_]; path << "l" << lat.id_; for (ReverseLatticeIter it = lat.rbegin(); it != lat.rend(); ++it) { int32_t indx = lat.universes_.size()*map + it.indx_; @@ -385,7 +385,7 @@ distribcell_path_inner(int32_t target_cell, int32_t map, int32_t target_offset, offset = temp_offset; path << "(" << lat.index_to_string(it.indx_) << ")->"; path << distribcell_path_inner(target_cell, map, target_offset, - *global_universes[*it], offset); + *universes[*it], offset); return path.str(); } } @@ -398,7 +398,7 @@ int distribcell_path_len(int32_t target_cell, int32_t map, int32_t target_offset, int32_t root_univ) { - Universe& root = *global_universes[root_univ]; + Universe& root = *universes[root_univ]; std::string path_ {distribcell_path_inner(target_cell, map, target_offset, root, 0)}; return path_.size() + 1; @@ -410,7 +410,7 @@ void distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset, int32_t root_univ, char* path) { - Universe& root = *global_universes[root_univ]; + Universe& root = *universes[root_univ]; std::string path_ {distribcell_path_inner(target_cell, map, target_offset, root, 0)}; path_.copy(path, path_.size()); @@ -424,13 +424,13 @@ maximum_levels(int32_t univ) { int levels_below {0}; - for (int32_t cell_indx : global_universes[univ]->cells_) { - Cell& c = *global_cells[cell_indx]; + for (int32_t cell_indx : universes[univ]->cells_) { + Cell& c = *cells[cell_indx]; if (c.type_ == FILL_UNIVERSE) { int32_t next_univ = c.fill_; levels_below = std::max(levels_below, maximum_levels(next_univ)); } else if (c.type_ == FILL_LATTICE) { - Lattice& lat = *lattices_c[c.fill_]; + Lattice& lat = *lattices[c.fill_]; for (auto it = lat.begin(); it != lat.end(); ++it) { int32_t next_univ = *it; levels_below = std::max(levels_below, maximum_levels(next_univ)); @@ -447,17 +447,17 @@ maximum_levels(int32_t univ) void free_memory_geometry_c() { - for (Cell* c : global_cells) {delete c;} - global_cells.clear(); + for (Cell* c : cells) {delete c;} + cells.clear(); cell_map.clear(); n_cells = 0; - for (Universe* u : global_universes) {delete u;} - global_universes.clear(); + for (Universe* u : universes) {delete u;} + universes.clear(); universe_map.clear(); - for (Lattice* lat : lattices_c) {delete lat;} - lattices_c.clear(); + for (Lattice* lat : lattices) {delete lat;} + lattices.clear(); lattice_map.clear(); overlap_check_count.clear(); diff --git a/src/lattice.cpp b/src/lattice.cpp index 0975082eb7..21f4768506 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -18,7 +18,7 @@ namespace openmc { // Global variables //============================================================================== -std::vector lattices_c; +std::vector lattices; std::unordered_map lattice_map; @@ -118,7 +118,7 @@ Lattice::to_hdf5(hid_t lattices_group) const } if (outer_ != NO_OUTER_UNIVERSE) { - int32_t outer_id = global_universes[outer_]->id_; + int32_t outer_id = universes[outer_]->id_; write_dataset(lat_group, "outer", outer_id); } else { write_dataset(lat_group, "outer", outer_); @@ -370,7 +370,7 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const for (int j = 0; j < nx; j++) { int indx1 = nx*ny*m + nx*k + j; int indx2 = nx*ny*m + nx*(ny-k-1) + j; - out[indx2] = global_universes[universes_[indx1]]->id_; + out[indx2] = universes[universes_[indx1]]->id_; } } } @@ -387,7 +387,7 @@ RectLattice::to_hdf5_inner(hid_t lat_group) const for (int j = 0; j < nx; j++) { int indx1 = nx*k + j; int indx2 = nx*(ny-k-1) + j; - out[indx2] = global_universes[universes_[indx1]]->id_; + out[indx2] = universes[universes_[indx1]]->id_; } } @@ -847,7 +847,7 @@ HexLattice::to_hdf5_inner(hid_t lat_group) const // This array position is never used; put a -1 to indicate this. out[indx] = -1; } else { - out[indx] = global_universes[universes_[indx]]->id_; + out[indx] = universes[universes_[indx]]->id_; } } } @@ -865,15 +865,15 @@ extern "C" void read_lattices(pugi::xml_node *node) { for (pugi::xml_node lat_node : node->children("lattice")) { - lattices_c.push_back(new RectLattice(lat_node)); + lattices.push_back(new RectLattice(lat_node)); } for (pugi::xml_node lat_node : node->children("hex_lattice")) { - lattices_c.push_back(new HexLattice(lat_node)); + lattices.push_back(new HexLattice(lat_node)); } // Fill the lattice map. - for (int i_lat = 0; i_lat < lattices_c.size(); i_lat++) { - int id = lattices_c[i_lat]->id_; + for (int i_lat = 0; i_lat < lattices.size(); i_lat++) { + int id = lattices[i_lat]->id_; auto in_map = lattice_map.find(id); if (in_map == lattice_map.end()) { lattice_map[id] = i_lat; @@ -890,7 +890,7 @@ read_lattices(pugi::xml_node *node) //============================================================================== extern "C" { - Lattice* lattice_pointer(int lat_ind) {return lattices_c[lat_ind];} + Lattice* lattice_pointer(int lat_ind) {return lattices[lat_ind];} int32_t lattice_id(Lattice *lat) {return lat->id_;} diff --git a/src/material.cpp b/src/material.cpp index 8a74299c4e..1a0c2d2078 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -13,7 +13,7 @@ namespace openmc { // Global variables //============================================================================== -std::vector global_materials; +std::vector materials; std::unordered_map material_map; //============================================================================== @@ -46,13 +46,13 @@ read_materials(pugi::xml_node* node) { // Loop over XML material elements and populate the array. for (pugi::xml_node material_node : node->children("material")) { - global_materials.push_back(new Material(material_node)); + materials.push_back(new Material(material_node)); } - global_materials.shrink_to_fit(); + materials.shrink_to_fit(); // Populate the material map. - for (int i = 0; i < global_materials.size(); i++) { - int32_t mid = global_materials[i]->id; + for (int i = 0; i < materials.size(); i++) { + int32_t mid = materials[i]->id; auto search = material_map.find(mid); if (search == material_map.end()) { material_map[mid] = i; @@ -71,8 +71,8 @@ read_materials(pugi::xml_node* node) extern "C" int openmc_material_get_volume(int32_t index, double* volume) { - if (index >= 1 && index <= global_materials.size()) { - Material* m = global_materials[index - 1]; + if (index >= 1 && index <= materials.size()) { + Material* m = materials[index - 1]; if (m->volume_ >= 0.0) { *volume = m->volume_; return 0; @@ -91,8 +91,8 @@ openmc_material_get_volume(int32_t index, double* volume) extern "C" int openmc_material_set_volume(int32_t index, double volume) { - if (index >= 1 && index <= global_materials.size()) { - Material* m = global_materials[index - 1]; + if (index >= 1 && index <= materials.size()) { + Material* m = materials[index - 1]; if (volume >= 0.0) { m->volume_ = volume; return 0; @@ -111,7 +111,7 @@ openmc_material_set_volume(int32_t index, double volume) //============================================================================== extern "C" { - Material* material_pointer(int32_t indx) {return global_materials[indx];} + Material* material_pointer(int32_t indx) {return materials[indx];} int32_t material_id(Material* mat) {return mat->id;} @@ -124,16 +124,16 @@ extern "C" { void extend_materials_c(int32_t n) { - global_materials.reserve(global_materials.size() + n); + materials.reserve(materials.size() + n); for (int32_t i = 0; i < n; i++) { - global_materials.push_back(new Material()); + materials.push_back(new Material()); } } void free_memory_material_c() { - for (Material *mat : global_materials) {delete mat;} - global_materials.clear(); + for (Material *mat : materials) {delete mat;} + materials.clear(); material_map.clear(); } } diff --git a/src/output.cpp b/src/output.cpp index 2d7b76753b..7964a33c88 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -56,10 +56,10 @@ print_overlap_check() { std::vector sparse_cell_ids; for (int i = 0; i < n_cells; i++) { - std::cout << " " << std::setw(8) << global_cells[i]->id_ << std::setw(17) + std::cout << " " << std::setw(8) << cells[i]->id_ << std::setw(17) << overlap_check_count[i] << "\n"; if (overlap_check_count[i] < 10) { - sparse_cell_ids.push_back(global_cells[i]->id_); + sparse_cell_ids.push_back(cells[i]->id_); } } diff --git a/src/summary.cpp b/src/summary.cpp index a14d6c441e..d103e78b9c 100644 --- a/src/summary.cpp +++ b/src/summary.cpp @@ -9,25 +9,25 @@ namespace openmc { extern "C" void write_geometry(hid_t file_id) { auto geom_group = create_group(file_id, "geometry"); - write_attribute(geom_group, "n_cells", global_cells.size()); - write_attribute(geom_group, "n_surfaces", global_surfaces.size()); - write_attribute(geom_group, "n_universes", global_universes.size()); - write_attribute(geom_group, "n_lattices", lattices_c.size()); + write_attribute(geom_group, "n_cells", cells.size()); + write_attribute(geom_group, "n_surfaces", surfaces.size()); + write_attribute(geom_group, "n_universes", universes.size()); + write_attribute(geom_group, "n_lattices", lattices.size()); auto cells_group = create_group(geom_group, "cells"); - for (Cell* c : global_cells) c->to_hdf5(cells_group); + for (Cell* c : cells) c->to_hdf5(cells_group); close_group(cells_group); auto surfaces_group = create_group(geom_group, "surfaces"); - for (Surface* surf : global_surfaces) surf->to_hdf5(surfaces_group); + for (Surface* surf : surfaces) surf->to_hdf5(surfaces_group); close_group(surfaces_group); auto universes_group = create_group(geom_group, "universes"); - for (Universe* u : global_universes) u->to_hdf5(universes_group); + for (Universe* u : universes) u->to_hdf5(universes_group); close_group(universes_group); auto lattices_group = create_group(geom_group, "lattices"); - for (Lattice* lat : lattices_c) lat->to_hdf5(lattices_group); + for (Lattice* lat : lattices) lat->to_hdf5(lattices_group); close_group(lattices_group); close_group(geom_group); diff --git a/src/surface.cpp b/src/surface.cpp index 54ff511dc4..d7f523ed64 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -27,7 +27,7 @@ extern "C" const int BC_PERIODIC {3}; int32_t n_surfaces; -std::vector global_surfaces; +std::vector surfaces; std::map surface_map; @@ -1032,7 +1032,7 @@ read_surfaces(pugi::xml_node* node) } // Loop over XML surface elements and populate the array. - global_surfaces.reserve(n_surfaces); + surfaces.reserve(n_surfaces); { pugi::xml_node surf_node; int i_surf; @@ -1041,40 +1041,40 @@ read_surfaces(pugi::xml_node* node) std::string surf_type = get_node_value(surf_node, "type", true, true); if (surf_type == "x-plane") { - global_surfaces.push_back(new SurfaceXPlane(surf_node)); + surfaces.push_back(new SurfaceXPlane(surf_node)); } else if (surf_type == "y-plane") { - global_surfaces.push_back(new SurfaceYPlane(surf_node)); + surfaces.push_back(new SurfaceYPlane(surf_node)); } else if (surf_type == "z-plane") { - global_surfaces.push_back(new SurfaceZPlane(surf_node)); + surfaces.push_back(new SurfaceZPlane(surf_node)); } else if (surf_type == "plane") { - global_surfaces.push_back(new SurfacePlane(surf_node)); + surfaces.push_back(new SurfacePlane(surf_node)); } else if (surf_type == "x-cylinder") { - global_surfaces.push_back(new SurfaceXCylinder(surf_node)); + surfaces.push_back(new SurfaceXCylinder(surf_node)); } else if (surf_type == "y-cylinder") { - global_surfaces.push_back(new SurfaceYCylinder(surf_node)); + surfaces.push_back(new SurfaceYCylinder(surf_node)); } else if (surf_type == "z-cylinder") { - global_surfaces.push_back(new SurfaceZCylinder(surf_node)); + surfaces.push_back(new SurfaceZCylinder(surf_node)); } else if (surf_type == "sphere") { - global_surfaces.push_back(new SurfaceSphere(surf_node)); + surfaces.push_back(new SurfaceSphere(surf_node)); } else if (surf_type == "x-cone") { - global_surfaces.push_back(new SurfaceXCone(surf_node)); + surfaces.push_back(new SurfaceXCone(surf_node)); } else if (surf_type == "y-cone") { - global_surfaces.push_back(new SurfaceYCone(surf_node)); + surfaces.push_back(new SurfaceYCone(surf_node)); } else if (surf_type == "z-cone") { - global_surfaces.push_back(new SurfaceZCone(surf_node)); + surfaces.push_back(new SurfaceZCone(surf_node)); } else if (surf_type == "quadric") { - global_surfaces.push_back(new SurfaceQuadric(surf_node)); + surfaces.push_back(new SurfaceQuadric(surf_node)); } else { std::stringstream err_msg; @@ -1086,7 +1086,7 @@ read_surfaces(pugi::xml_node* node) // Fill the surface map. for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - int id = global_surfaces[i_surf]->id_; + int id = surfaces[i_surf]->id_; auto in_map = surface_map.find(id); if (in_map == surface_map.end()) { surface_map[id] = i_surf; @@ -1102,9 +1102,9 @@ read_surfaces(pugi::xml_node* node) zmin {INFTY}, zmax {-INFTY}; int i_xmin, i_xmax, i_ymin, i_ymax, i_zmin, i_zmax; for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - if (global_surfaces[i_surf]->bc_ == BC_PERIODIC) { + if (surfaces[i_surf]->bc_ == BC_PERIODIC) { // Downcast to the PeriodicSurface type. - Surface* surf_base = global_surfaces[i_surf]; + Surface* surf_base = surfaces[i_surf]; PeriodicSurface* surf = dynamic_cast(surf_base); // Make sure this surface inherits from PeriodicSurface. @@ -1147,9 +1147,9 @@ read_surfaces(pugi::xml_node* node) // Set i_periodic for periodic BC surfaces. for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { - if (global_surfaces[i_surf]->bc_ == BC_PERIODIC) { + if (surfaces[i_surf]->bc_ == BC_PERIODIC) { // Downcast to the PeriodicSurface type. - Surface* surf_base = global_surfaces[i_surf]; + Surface* surf_base = surfaces[i_surf]; PeriodicSurface* surf = dynamic_cast(surf_base); // Also try downcasting to the SurfacePlane type (which must be handled @@ -1196,7 +1196,7 @@ read_surfaces(pugi::xml_node* node) } // Make sure the opposite surface is also periodic. - if (global_surfaces[surf->i_periodic_]->bc_ != BC_PERIODIC) { + if (surfaces[surf->i_periodic_]->bc_ != BC_PERIODIC) { std::stringstream err_msg; err_msg << "Could not find matching surface for periodic boundary " "condition on surface " << surf->id_; @@ -1211,7 +1211,7 @@ read_surfaces(pugi::xml_node* node) //============================================================================== extern "C" { - Surface* surface_pointer(int surf_ind) {return global_surfaces[surf_ind];} + Surface* surface_pointer(int surf_ind) {return surfaces[surf_ind];} int surface_id(Surface* surf) {return surf->id_;} @@ -1251,8 +1251,8 @@ extern "C" { void free_memory_surfaces_c() { - for (Surface* surf : global_surfaces) {delete surf;} - global_surfaces.clear(); + for (Surface* surf : surfaces) {delete surf;} + surfaces.clear(); n_surfaces = 0; surface_map.clear(); } From fe24b640af82244b5af8c37e0cc093386dc65859 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 27 Aug 2018 19:31:42 -0400 Subject: [PATCH 42/43] Use 0-based indexing for distribcell --- src/geometry.cpp | 14 ++++++-------- src/geometry_aux.cpp | 3 +-- src/tallies/tally_filter_distribcell.F90 | 8 ++++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/geometry.cpp b/src/geometry.cpp index 22e3cbfe34..2c83e38366 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -108,33 +108,31 @@ find_cell(Particle* p, int search_surf) { // Find the distribcell instance number. if (c.material_.size() > 1 || c.sqrtkT_.size() > 1) { - //TODO: off-by-one indexing - int distribcell_index = c.distribcell_index_ - 1; int offset = 0; for (int i = 0; i < p->n_coord; i++) { Cell& c_i {*cells[p->coord[i].cell]}; if (c_i.type_ == FILL_UNIVERSE) { - offset += c_i.offset_[distribcell_index]; + offset += c_i.offset_[c.distribcell_index_]; } else if (c_i.type_ == FILL_LATTICE) { Lattice& lat {*lattices[p->coord[i+1].lattice-1]}; int i_xyz[3] {p->coord[i+1].lattice_x, p->coord[i+1].lattice_y, p->coord[i+1].lattice_z}; if (lat.are_valid_indices(i_xyz)) { - offset += lat.offset(distribcell_index, i_xyz); + offset += lat.offset(c.distribcell_index_, i_xyz); } } } - p->cell_instance = offset + 1; + p->cell_instance = offset; } else { - p->cell_instance = 1; + p->cell_instance = 0; } // Set the material and temperature. p->last_material = p->material; int32_t mat; if (c.material_.size() > 1) { - mat = c.material_[p->cell_instance-1]; + mat = c.material_[p->cell_instance]; } else { mat = c.material_[0]; } @@ -145,7 +143,7 @@ find_cell(Particle* p, int search_surf) { } p->last_sqrtkT = p->sqrtkT; if (c.sqrtkT_.size() > 1) { - p->sqrtkT = c.sqrtkT_[p->cell_instance-1]; + p->sqrtkT = c.sqrtkT_[p->cell_instance]; } else { p->sqrtkT = c.sqrtkT_[0]; } diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 9c1d17b4d6..a304790125 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -220,8 +220,7 @@ prepare_distribcell(int32_t* filter_cell_list, int n) // Search through universes for distributed cells and assign each one a // unique distribcell array index. - //TODO: off-by-one - int distribcell_index = 1; + int distribcell_index = 0; std::vector target_univ_ids; for (Universe* u : universes) { for (auto cell_indx : u->cells_) { diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index ae4e09023d..f35ffc3ec4 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -59,14 +59,14 @@ contains do i = 1, p % n_coord if (cells(p % coord(i) % cell + 1) % type() == FILL_UNIVERSE) then offset = offset + cells(p % coord(i) % cell + 1) & - % offset(distribcell_index-1) + % offset(distribcell_index) elseif (cells(p % coord(i) % cell + 1) % type() == FILL_LATTICE) then if (lattices(p % coord(i + 1) % lattice) % are_valid_indices([& p % coord(i + 1) % lattice_x, & p % coord(i + 1) % lattice_y, & p % coord(i + 1) % lattice_z])) then offset = offset + lattices(p % coord(i + 1) % lattice) & - % offset(distribcell_index - 1, & + % offset(distribcell_index, & [p % coord(i + 1) % lattice_x, & p % coord(i + 1) % lattice_y, & p % coord(i + 1) % lattice_z]) @@ -155,10 +155,10 @@ contains ! Get the distribcell index for this cell map = cells(i_cell) % distribcell_index() - path_len = distribcell_path_len(i_cell-1, map-1, target_offset, & + path_len = distribcell_path_len(i_cell-1, map, target_offset, & root_universe) allocate(path_c(path_len)) - call distribcell_path(i_cell-1, map-1, target_offset, root_universe, & + call distribcell_path(i_cell-1, map, target_offset, root_universe, & path_c) do i = 1, min(path_len, MAX_LINE_LEN) if (path_c(i) == C_NULL_CHAR) exit From 1de49c76e0250d32bf1ea349eab67b330f232e8e Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 27 Aug 2018 20:09:48 -0400 Subject: [PATCH 43/43] Fix distribcell index bug --- src/api.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api.F90 b/src/api.F90 index f089555bce..0fa537e528 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -207,7 +207,7 @@ contains if (found) then index = p % coord(p % n_coord) % cell + 1 - instance = p % cell_instance - 1 + instance = p % cell_instance err = 0 else err = E_GEOMETRY