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.