Skip to content

Commit 8130075

Browse files
authored
Merge pull request #130 from Fuad-HH/functor_parameter_for_search_mesh
Generalized search_mesh that takes a functor to execute at element boundary or destination
2 parents f7d3b4a + 3d11b9c commit 8130075

File tree

1 file changed

+86
-8
lines changed

1 file changed

+86
-8
lines changed

src/pumipic_adjacency.tpp

+86-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef PUMIPIC_ADJACENCY_NEW_HPP
22
#define PUMIPIC_ADJACENCY_NEW_HPP
3-
3+
#include <Omega_h_array.hpp>
4+
#include <Omega_h_defines.hpp>
45
#include <Omega_h_macros.h>
56
#include <iostream>
67
#include "Omega_h_for.hpp"
@@ -423,16 +424,55 @@ namespace pumipic {
423424
printf("Min area is: %.15f, Planned tol is %.15f\n", min_area, tol);
424425
return tol;
425426
}
426-
427-
template <class ParticleType, typename Segment3d, typename SegmentInt>
428-
bool search_mesh(o::Mesh& mesh, ParticleStructure<ParticleType>* ptcls,
427+
428+
/**
429+
* @brief Particle tracing through mesh
430+
*
431+
* Starting at the initial position, the particles are traced through the mesh (both 2D and 3D)
432+
* until they are all marked "done" by the particle handler "func" at element boundary or destination.
433+
* It gives back the parent element ids for the new positions of the particles,
434+
* the exit face ids for the particles that leave the domain, and the last intersection point for
435+
* the particles.
436+
*
437+
* Note: Particle trajectories are considered as rays (not line segments).
438+
*
439+
*
440+
* @tparam ParticleType Particle type
441+
* @tparam Segment3d Segment type for particle position
442+
* @tparam SegmentInt Segment type for particle ids
443+
* @tparam Func Callable type object
444+
* @param mesh Omega_h mesh to search on
445+
* @param ptcls Particle structure
446+
* @param x_ps_orig Particle starting position
447+
* @param x_ps_tgt Particle target position
448+
* @param pids Particle ids
449+
* @param elem_ids Paricle parent element ids
450+
* @param requireIntersection True if intersection is required
451+
* @param inter_faces Exit faces for particles at domain boundary
452+
* @param inter_points Stores intersection points for particles at each face
453+
* @param looplimit Maximum number of iterations
454+
* @param debug True if debug information is printed
455+
* @param func Callable object to handle particles at element sides or destination
456+
* @return True if all particles are found at destination or left domain
457+
*/
458+
template <class ParticleType, typename Segment3d, typename SegmentInt, typename Func>
459+
bool trace_particle_through_mesh(o::Mesh& mesh, ParticleStructure<ParticleType>* ptcls,
429460
Segment3d x_ps_orig, Segment3d x_ps_tgt, SegmentInt pids,
430461
o::Write<o::LO>& elem_ids,
431462
bool requireIntersection,
432463
o::Write<o::LO>& inter_faces,
433464
o::Write<o::Real>& inter_points,
434465
int looplimit,
435-
int debug) {
466+
bool debug,
467+
Func& func) {
468+
static_assert(
469+
std::is_invocable_r_v<
470+
void, Func, o::Mesh &, ParticleStructure<ParticleType> *,
471+
o::Write<o::LO> &, o::Write<o::LO> &, o::Write<o::LO> &,
472+
o::Write<o::Real> &, o::Write<o::LO> &,
473+
Segment3d, Segment3d>,
474+
"Functional must accept <mesh> <ps> <elem_ids> <inter_faces> <lastExit> <inter_points> <ptcl_done> <x_ps_orig> <x_ps_tgt>\n");
475+
436476
//Initialize timer
437477
const auto btime = pumipic_prebarrier();
438478
Kokkos::Profiling::pushRegion("pumipic_search_mesh");
@@ -517,10 +557,9 @@ namespace pumipic {
517557
//Find intersection face
518558
find_exit_face(mesh, ptcls, x_ps_orig, x_ps_tgt, elem_ids, ptcl_done, elmArea, useBcc, lastExit, inter_points, tol);
519559
//Check if intersection face is exposed
520-
check_model_intersection(mesh, ptcls, x_ps_orig, x_ps_tgt, elem_ids, ptcl_done, lastExit, side_is_exposed,
521-
requireIntersection, inter_faces);
560+
func(mesh, ptcls, elem_ids, inter_faces, lastExit, inter_points, ptcl_done, x_ps_orig, x_ps_tgt);
522561

523-
//Move to next element
562+
// Move to next element
524563
set_new_element(mesh, ptcls, elem_ids, ptcl_done, lastExit);
525564

526565
//Check if all particles are found
@@ -572,5 +611,44 @@ namespace pumipic {
572611
Kokkos::Profiling::popRegion();
573612
return found;
574613
}
614+
615+
template <typename ParticleType, typename Segment3d>
616+
struct RemoveParticleOnGeometricModelExit {
617+
RemoveParticleOnGeometricModelExit(o::Mesh &mesh, bool requireIntersection)
618+
: requireIntersection_(requireIntersection) {
619+
side_is_exposed_ = mark_exposed_sides(&mesh);
620+
}
621+
622+
void operator()(o::Mesh& mesh, ParticleStructure<ParticleType>* ptcls,
623+
o::Write<o::LO>& elem_ids, o::Write<o::LO>& inter_faces,
624+
o::Write<o::LO>& lastExit, o::Write<o::Real>& inter_points,
625+
o::Write<o::LO>& ptcl_done,
626+
Segment3d x_ps_orig,
627+
Segment3d x_ps_tgt) const {
628+
// Check if intersection face is exposed
629+
check_model_intersection(mesh, ptcls, x_ps_orig, x_ps_tgt, elem_ids,
630+
ptcl_done, lastExit, side_is_exposed_,
631+
requireIntersection_, inter_faces);
632+
}
633+
634+
private:
635+
bool requireIntersection_;
636+
o::Bytes side_is_exposed_;
637+
};
638+
639+
template <class ParticleType, typename Segment3d, typename SegmentInt>
640+
bool search_mesh(o::Mesh& mesh, ParticleStructure<ParticleType>* ptcls,
641+
Segment3d x_ps_orig, Segment3d x_ps_tgt, SegmentInt pids,
642+
o::Write<o::LO>& elem_ids,
643+
bool requireIntersection,
644+
o::Write<o::LO>& inter_faces,
645+
o::Write<o::Real>& inter_points,
646+
int looplimit,
647+
int debug) {
648+
RemoveParticleOnGeometricModelExit<ParticleType, Segment3d> native_handler(mesh, requireIntersection);
649+
650+
return trace_particle_through_mesh(mesh, ptcls, x_ps_orig, x_ps_tgt, pids, elem_ids, requireIntersection,
651+
inter_faces, inter_points, looplimit, debug, native_handler);
652+
}
575653
}
576654
#endif

0 commit comments

Comments
 (0)