<commit_before>#include "openmc/geometry.h"

#include <array>

#include <fmt/core.h>
#include <fmt/ostream.h>

#include "openmc/cell.h"
#include "openmc/constants.h"
#include "openmc/error.h"
#include "openmc/lattice.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include "openmc/string_utils.h"
#include "openmc/surface.h"


namespace openmc {

//==============================================================================
// Global variables
//==============================================================================


namespace model {

int root_universe {-1};
int n_coord_levels;

std::vector<int64_t> overlap_check_count;

} // namespace model

//==============================================================================
// Non-member functions
//==============================================================================

bool check_cell_overlap(Particle& p, bool error)
{
  int n_coord = p.n_coord_;

  // Loop through each coordinate level
  for (int j = 0; j < n_coord; j++) {
    Universe& univ = *model::universes[p.coord_[j].universe];

    // Loop through each cell on this level
    for (auto index_cell : univ.cells_) {
      Cell& c = *model::cells[index_cell];
      if (c.contains(p.coord_[j].r, p.coord_[j].u, p.surface_)) {
        if (index_cell != p.coord_[j].cell) {
          if (error) {
            fatal_error(fmt::format(
              "Overlapping cells detected: {}, {} on universe {}",
              c.id_, model::cells[p.coord_[j].cell]->id_, univ.id_));
          }
          return true;
        }
        #pragma omp atomic
        ++model::overlap_check_count[index_cell];
      }
    }
  }

  return false;
}

//==============================================================================

bool
find_cell_inner(Particle& p, const NeighborList* neighbor_list)
{
  // Find which cell of this universe the particle is in.  Use the neighbor list
  // to shorten the search if one was provided.
  bool found = false;
  int32_t i_cell = C_NONE;
  if (neighbor_list) {
    for (auto it = neighbor_list->cbegin(); it != neighbor_list->cend(); ++it) {
      i_cell = *it;

      // Make sure the search cell is in the same universe.
      int i_universe = p.coord_[p.n_coord_-1].universe;
      if (model::cells[i_cell]->universe_ != i_universe) continue;

      // Check if this cell contains the particle.
      Position r {p.r_local()};
      Direction u {p.u_local()};
      auto surf = p.surface_;
      if (model::cells[i_cell]->contains(r, u, surf)) {
        p.coord_[p.n_coord_-1].cell = i_cell;
        found = true;
        break;
      }
    }
  }

  // Check successively lower coordinate levels until finding material fill
  for (;;++p.n_coord_) {
    // If neighbor lists did not find a cell, must do exhaustive search
    if (i_cell == C_NONE) {
      int i_universe = p.coord_[p.n_coord_-1].universe;
      const auto& univ {*model::universes[i_universe]};
      const auto& cells {
        !univ.partitioner_
        ? model::universes[i_universe]->cells_
        : univ.partitioner_->get_cells(p.r_local(), p.u_local())
      };

      for (auto it = cells.cbegin(); it != cells.cend(); it++) {
        i_cell = *it;
<commit_msg>make sure failed neighbor list searches trigger exhaustive searches<commit_after>#include "openmc/geometry.h"

#include <array>

#include <fmt/core.h>
#include <fmt/ostream.h>

#include "openmc/cell.h"
#include "openmc/constants.h"
#include "openmc/error.h"
#include "openmc/lattice.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include "openmc/string_utils.h"
#include "openmc/surface.h"


namespace openmc {

//==============================================================================
// Global variables
//==============================================================================


namespace model {

int root_universe {-1};
int n_coord_levels;

std::vector<int64_t> overlap_check_count;

} // namespace model

//==============================================================================
// Non-member functions
//==============================================================================

bool check_cell_overlap(Particle& p, bool error)
{
  int n_coord = p.n_coord_;

  // Loop through each coordinate level
  for (int j = 0; j < n_coord; j++) {
    Universe& univ = *model::universes[p.coord_[j].universe];

    // Loop through each cell on this level
    for (auto index_cell : univ.cells_) {
      Cell& c = *model::cells[index_cell];
      if (c.contains(p.coord_[j].r, p.coord_[j].u, p.surface_)) {
        if (index_cell != p.coord_[j].cell) {
          if (error) {
            fatal_error(fmt::format(
              "Overlapping cells detected: {}, {} on universe {}",
              c.id_, model::cells[p.coord_[j].cell]->id_, univ.id_));
          }
          return true;
        }
        #pragma omp atomic
        ++model::overlap_check_count[index_cell];
      }
    }
  }

  return false;
}

//==============================================================================

bool
find_cell_inner(Particle& p, const NeighborList* neighbor_list)
{
  // Find which cell of this universe the particle is in.  Use the neighbor list
  // to shorten the search if one was provided.
  bool found = false;
  int32_t i_cell = C_NONE;
  if (neighbor_list) {
    for (auto it = neighbor_list->cbegin(); it != neighbor_list->cend(); ++it) {
      i_cell = *it;

      // Make sure the search cell is in the same universe.
      int i_universe = p.coord_[p.n_coord_-1].universe;
      if (model::cells[i_cell]->universe_ != i_universe) continue;

      // Check if this cell contains the particle.
      Position r {p.r_local()};
      Direction u {p.u_local()};
      auto surf = p.surface_;
      if (model::cells[i_cell]->contains(r, u, surf)) {
        p.coord_[p.n_coord_-1].cell = i_cell;
        found = true;
        break;
      }
    }

    // If we're attempting a neighbor list search and fail, we
    // now know we should return false. This will trigger an
    // exhaustive search from neighbor_list_find_cell and make
    // the result from that be appended to the neighbor list.
    if (!found)
      return false;
  }

  // Check successively lower coordinate levels until finding material fill
  for (;;++p.n_coord_) {
    // If we did not attempt to use neighbor lists, i_cell is still C_NONE.  In
    // that case, we should now do an exhaustive search to find the right value
    // of i_cell.
    //
    // Alternatively, neighbor list searches could have succeeded, but we found
    // that the fill of the neighbor cell was another universe. As such, in the
    // code below this conditional, we set i_cell back to C_NONE to indicate
    // that.
    if (i_cell == C_NONE) {
      int i_universe = p.coord_[p.n_coord_-1].universe;
      const auto& univ {*model::universes[i_universe]};
      const auto& cells {
        !univ.partitioner_
        ? model::universes[i_universe]->cells_
        : univ.partitioner_->get_cells(p.r_local(), p.u_local())
      };

      for (auto it = cells.cbegin(); it != cells.cend(); it++) {
        i_cell = *it;

{'fraction_non_alphanumeric': 0.22738111937158087, 'fraction_numerical': 0.002524898302707252, 'mean_word_length': 3.138131166569936, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1019956', 'n_tokens_mistral': 2228, 'n_tokens_neox': 2135, 'n_words': 583}