16 #include "libmesh/elem.h" 17 #include "libmesh/parallel_algebra.h" 18 #include "libmesh/parallel_sync.h" 19 #include "libmesh/enum_point_locator_type.h" 20 #include "libmesh/mesh_tools.h" 25 const std::vector<std::shared_ptr<Ray>> & rays,
26 std::vector<std::shared_ptr<Ray>> & local_rays,
27 const bool do_exchange)
32 _do_exchange(do_exchange),
34 _parallel_study(*_study.parallelStudy()),
36 _local_rays(local_rays),
60 std::unordered_map<processor_id_type, std::vector<std::shared_ptr<Ray>>> rays_to_send;
66 for (
auto & ray :
_rays)
68 rays_to_send[pid].push_back(ray);
75 for (
auto & ray : rays)
81 Parallel::push_parallel_packed_range(
comm(), rays_to_send, &
_parallel_study, claim_functor);
99 claimPoint(ray->currentPoint(),
getID(ray), (*_point_locator)(ray->currentPoint()));
113 const bool smallest =
id % 2 == 0;
116 const Elem * extremum_elem = elem;
123 for (
const auto & neighbor : neighbors)
125 mooseAssert(neighbor->active(),
"Inactive neighbor");
127 if ((smallest && neighbor->id() < extremum_elem->
id()) ||
128 (!smallest && neighbor->id() > extremum_elem->
id()))
129 if (neighbor->contains_point(point))
130 extremum_elem = neighbor;
136 mooseAssert(extremum_elem->
active(),
"Inactive element");
137 return extremum_elem;
148 mooseAssert(elem->
active(),
"Inactive element");
153 if (!(!ray->invalidCurrentIncomingSide() &&
154 _study.
elemSide(*elem, ray->currentIncomingSide()).contains_point(ray->currentPoint()) &&
160 starting_incoming_side = s;
164 ray->setStart(ray->currentPoint(), elem, starting_incoming_side);
184 const auto bbox = MeshTools::create_local_bounding_box(
_mesh.
getMesh());
187 std::vector<std::pair<Point, Point>> bb_points = {
static_cast<std::pair<Point, Point>
>(bbox)};
195 pid_bbox.
scale(0.01);
206 for (
const auto & elem :
_mesh.
getMesh().active_element_ptr_range())
209 for (
unsigned int v = 0;
v < elem->n_vertices(); ++
v)
211 const auto & node = elem->node_ptr(
v);
212 for (
const auto & neighbor_id : node_to_elem_map.at(node->id()))
214 if (neighbor_id == elem->id())
218 if (std::count(fill.begin(), fill.end(), neighbor) == 0)
219 fill.emplace_back(neighbor);
234 std::map<RayID, char> local_map;
235 auto add_to_local_map =
236 [
this, &local_map](
const std::vector<std::shared_ptr<Ray>> & rays,
const bool claimed_rays)
238 for (
const auto & ray : rays)
240 const auto id =
getID(ray);
243 auto emplace_pair = local_map.emplace(
id, claimed_rays);
246 if (!emplace_pair.second && claimed_rays)
248 mooseAssert(!emplace_pair.first->second,
249 "Ray was claimed more than once on a single processor");
250 emplace_pair.first->second =
true;
256 add_to_local_map(
_rays,
false);
260 std::map<processor_id_type, std::vector<std::pair<RayID, char>>> send_info;
261 if (local_map.size())
262 send_info.emplace(std::piecewise_construct,
263 std::forward_as_tuple(0),
264 std::forward_as_tuple(local_map.begin(), local_map.end()));
267 std::map<RayID, std::vector<std::pair<processor_id_type, char>>> global_map;
271 const std::vector<std::pair<RayID, char>> & id_claimed_pairs)
273 for (
const auto & id_claimed_pair : id_claimed_pairs)
274 global_map[id_claimed_pair.first].emplace_back(pid, id_claimed_pair.second);
278 Parallel::push_parallel_vector_data(
comm(), send_info, receive_functor);
282 for (
const auto & id_pairs_pair : global_map)
284 const RayID id = id_pairs_pair.first;
285 const std::vector<std::pair<processor_id_type, char>> & pid_claimed_pairs =
286 id_pairs_pair.second;
288 std::vector<processor_id_type> claimed_pids;
289 for (
const auto & pid_claimed_pair : pid_claimed_pairs)
290 if (pid_claimed_pair.second)
291 claimed_pids.push_back(pid_claimed_pair.first);
293 if (claimed_pids.size() == 0)
295 mooseAssert(claimed_pids.size() == 1,
"Ray was claimed on multiple processors");
static const unsigned short invalid_side
Identifier for an invalid side index.
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
bool _needs_init
Whether or not an init is needed (bounding boxes, neighbors)
unsigned long int RayID
Type for a Ray's ID.
virtual Elem * elemPtr(const dof_id_type i)
bool contains_point(const Point &) const
IntRange< unsigned short > side_index_range() const
ClaimRays(RayTracingStudy &study, const std::vector< std::shared_ptr< Ray >> &rays, std::vector< std::shared_ptr< Ray >> &local_rays, const bool do_exchange)
Constructor.
void verifyClaiming()
Verifies that the claiming process succeeded.
const Parallel::Communicator & comm() const
virtual void postClaimRay(std::shared_ptr< Ray > &ray, const Elem *elem)
Entry point for acting on a Ray after it is claimed.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
ParallelStudy< std::shared_ptr< Ray >, Ray > & _parallel_study
The ParallelStudy, used as the context for communicating rays.
virtual void postClaim()
Entry point after claim()
const processor_id_type _pid
This processor ID.
void buildPointNeighbors()
Build the map of elements to all of their point neighbors.
const std::vector< std::shared_ptr< Ray > > & _rays
The Rays that need to be searched to possibly claimed.
virtual Elem * queryElemPtr(const dof_id_type i)
processor_id_type size() const
uint8_t processor_id_type
bool verifyRays() const
Whether or not to verify if Rays have valid information before being traced.
std::vector< libMesh::BoundingBox > _inflated_bboxes
The inflated bounding boxes for all processors.
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
MooseMesh & _mesh
The mesh.
std::vector< std::shared_ptr< Ray > > & _local_rays
The local Rays that are claimed.
RayTracingStudy & _study
The RayTracingStudy.
virtual RayID getID(const std::shared_ptr< Ray > &ray) const
Gets an ID associated with the Ray for claiming purposes.
void buildBoundingBoxes()
Builds the bounding boxes (_inflated_bboxes).
void claim()
Claim the Rays.
void possiblyClaim(const std::shared_ptr< Ray > &obj)
Possibly claim a Ray.
const bool _do_exchange
Whether or not the Rays need to be initially exchanged.
virtual void preClaim()
Entry point before claim()
virtual void meshChanged() override
Call on mesh changes to reinit the necessary data structures.
static const std::string v
std::unordered_map< dof_id_type, std::vector< const Elem * > > _elem_point_neighbors
Map of point neighbors for each element.
const libMesh::Elem & elemSide(const libMesh::Elem &elem, const unsigned int s, const THREAD_ID tid=0)
Get an element's side pointer without excessive memory allocation.
const libMesh::BoundingBox & inflatedBoundingBox(const processor_id_type pid) const
Get the inflated bounding box for rank .
void mooseError(Args &&... args) const
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
The point locator.
void scale(const Real factor)
processor_id_type processor_id() const
bool sideIsIncoming(const Elem *const elem, const unsigned short side, const Point &direction, const THREAD_ID tid)
Whether or not side is incoming on element elem in direction direction.
const Elem * claimPoint(const Point &point, const RayID id, const Elem *elem)
Try to claim a spatial point.
const std::map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
virtual void prePossiblyClaimRay(const std::shared_ptr< Ray > &)
Entry point before possibly claiming a Ray.
virtual void init()
Initialize the object.
Base class for Ray tracing studies that will generate Rays and then propagate all of them to terminat...