diff --git a/CMakeLists.txt b/CMakeLists.txt index 29d16bc080..10cfd5aa03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ else() #=============================================================================== if(libmesh) find_package(LIBMESH REQUIRED) - set(LIBMESH_LIBRARIES mesh_opt timpi_opt netcdf) + set(LIBMESH_LIBRARIES mesh_devel timpi_devel netcdf) set(LIBMESH_INCLUDE_DIRS "${LIBMESH}/../include/") link_directories(${LIBMESH}) endif() diff --git a/include/openmc/mesh.h b/include/openmc/mesh.h index fffe287a0a..da2fca2c87 100644 --- a/include/openmc/mesh.h +++ b/include/openmc/mesh.h @@ -575,7 +575,7 @@ private: private: std::unique_ptr m_; //!< pointer to the libmesh mesh instance - std::unique_ptr point_locator_; //!< point locator for the mesh + std::vector> point_locators_; //!< pointers to locators for each thread std::unique_ptr equation_systems_; //!< pointer to the equation systems of the mesh (for result output) std::map variable_map_; //!< mappint of variable names (scores) to their numbers on the mesh BoundingBox bbox_; //!< bounding box of the mesh diff --git a/src/initialize.cpp b/src/initialize.cpp index d5040976e2..f4874d9f23 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -55,10 +55,6 @@ int openmc_init(int argc, char* argv[], const void* intracomm) initialize_mpi(comm); #endif -#ifdef LIBMESH - settings::LMI = new libMesh::LibMeshInit(argc, argv); -#endif - // Parse command-line arguments int err = parse_command_line(argc, argv); @@ -76,6 +72,11 @@ int openmc_init(int argc, char* argv[], const void* intracomm) } #endif +#ifdef LIBMESH + settings::LMI = new libMesh::LibMeshInit(argc, argv, omp_get_max_threads()); +#endif + + // Initialize random number generator -- if the user specifies a seed, it // will be re-initialized later openmc::openmc_set_seed(DEFAULT_SEED); diff --git a/src/mesh.cpp b/src/mesh.cpp index 26d8f35529..a3b36e3de0 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -2069,9 +2069,13 @@ LibMesh::LibMesh(pugi::xml_node node) : UnstructuredMeshBase(node) { equation_systems_->add_system(eq_system_name_); // setup the point locator - m_->set_point_locator_close_to_point_tol(FP_COINCIDENT); - point_locator_ = m_->sub_point_locator(); - point_locator_->enable_out_of_mesh_mode(); + int n_threads = omp_get_max_threads(); + point_locators_ = std::vector>(n_threads); + for (int i = 0; i < n_threads; i++) { + point_locators_[i] = m_->sub_point_locator(); + point_locators_[i]->set_find_element_tol(FP_COINCIDENT); + point_locators_[i]->enable_out_of_mesh_mode(); + } // will need mesh neighbors to walk the mesh m_->find_neighbors(); @@ -2210,23 +2214,9 @@ LibMesh::get_bin(Position r) const // look-up a tet using the point locator libMesh::Point p(r.x, r.y, r.z); - auto e = (*point_locator_)(p); - // sometimes the tet isn't quite right, - // make sure this tet contains our point - // if not, check this tet's neighbors - libMesh::Point dir(rand(), rand(), rand()); - dir /= dir.norm(); - if (e && !inside_tet(p, dir, e)) { - bool found = false; - for (int i = 0; i < e->n_neighbors(); i++) { - if (e->neighbor_ptr(i) && inside_tet(p, dir, e->neighbor_ptr(i))) { - e = e->neighbor_ptr(i); - found = true; - break; - } - } - } + int thread = omp_get_thread_num(); + auto e = (*point_locators_[thread])(p); if (!e) { return -1; @@ -2361,7 +2351,8 @@ LibMesh::intersect_track(libMesh::Point start, double track_remaining = track_len; // attempt to locate a tet for the starting point - auto e = (*point_locator_)(start); + int thread = omp_get_thread_num(); + auto e = (*point_locators_[thread])(start); // the point_locator seems off sometimes, // ensure the point is actually in the tet @@ -2436,7 +2427,9 @@ LibMesh::intersect_track(libMesh::Point start, } auto orig_e = e; start += dir * TINY_BIT; // nudge particle forward - e = (*point_locator_)(start); + + int thread = omp_get_thread_num(); + e = (*point_locators_[thread])(start); if (!e) { if (!orig_e->on_boundary()) {