25 #include "libmesh/enum_to_string.h" 26 #include "libmesh/mesh_tools.h" 27 #include "libmesh/parallel_sync.h" 28 #include "libmesh/remote_elem.h" 40 params.addRangeCheckedParam<
Real>(
"ray_distance",
41 std::numeric_limits<Real>::max(),
43 "The maximum distance all Rays can travel");
45 params.addParam<
bool>(
46 "tolerate_failure",
false,
"Whether or not to tolerate a ray tracing failure");
48 MooseEnum work_buffers(
"lifo circular",
"circular");
49 params.addParam<
MooseEnum>(
"work_buffer_type", work_buffers,
"The work buffer type to use");
51 params.addParam<
bool>(
52 "ray_kernel_coverage_check",
true,
"Whether or not to perform coverage checks on RayKernels");
53 params.addParam<
bool>(
"warn_non_planar",
55 "Whether or not to produce a warning if any element faces are non-planar.");
57 params.addParam<
bool>(
58 "always_cache_traces",
60 "Whether or not to cache the Ray traces on every execution, primarily for use in output. " 61 "Warning: this can get expensive very quick with a large number of rays!");
62 params.addParam<
bool>(
"data_on_cache_traces",
64 "Whether or not to also cache the Ray's data when caching its traces");
65 params.addParam<
bool>(
"aux_data_on_cache_traces",
67 "Whether or not to also cache the Ray's aux data when caching its traces");
68 params.addParam<
bool>(
69 "segments_on_cache_traces",
71 "Whether or not to cache individual segments when trace caching is enabled. If false, we " 72 "will instead cache a segment for each part of the trace where the direction is the same. " 73 "This minimizes the number of segments requied to represent the Ray's path, but removes the " 74 "ability to show Ray field data on each segment through an element.");
76 params.addParam<
bool>(
"use_internal_sidesets",
78 "Whether or not to use internal sidesets for RayBCs in ray tracing");
80 params.addParam<
bool>(
"warn_subdomain_hmax",
82 "Whether or not to warn if the approximated hmax (constant on subdomain) " 83 "varies significantly for an element");
85 params.addParam<
bool>(
88 "Whether or not to verify the generated Rays. This includes checking their " 89 "starting information and the uniqueness of Rays before and after execution. This is also " 90 "used by derived studies for more specific verification.");
91 params.addParam<
bool>(
"verify_trace_intersections",
93 "Whether or not to verify the trace intersections in devel and dbg modes. " 94 "Trace intersections are not verified regardless of this parameter in " 95 "optimized modes (opt, oprof).");
97 params.addParam<
bool>(
"allow_other_flags_with_prekernels",
99 "Whether or not to allow the list of execution flags to have PRE_KERNELS " 100 "mixed with other flags. If this parameter is not set then if PRE_KERNELS " 101 "is provided it must be the only execution flag.");
106 params.addParamNamesToGroup(
107 "always_cache_traces data_on_cache_traces aux_data_on_cache_traces segments_on_cache_traces",
109 params.addParamNamesToGroup(
"warn_non_planar warn_subdomain_hmax",
"Tracing Warnings");
110 params.addParamNamesToGroup(
"ray_kernel_coverage_check verify_rays verify_trace_intersections",
111 "Checks and verifications");
114 params.addPrivateParam<
bool>(
"_use_ray_registration",
true);
116 params.addPrivateParam<
bool>(
"_bank_rays_on_completion",
true);
118 params.addPrivateParam<
bool>(
"_ray_dependent_subdomain_setup",
true);
121 params.addRelationshipManager(
"ElementPointNeighborLayers",
125 { rm_params.
set<
unsigned short>(
"layers") = 1; });
132 _mesh(_fe_problem.
mesh()),
136 _ray_kernel_coverage_check(getParam<bool>(
"ray_kernel_coverage_check")),
137 _warn_non_planar(getParam<bool>(
"warn_non_planar")),
138 _use_ray_registration(getParam<bool>(
"_use_ray_registration")),
139 _use_internal_sidesets(getParam<bool>(
"use_internal_sidesets")),
140 _tolerate_failure(getParam<bool>(
"tolerate_failure")),
141 _bank_rays_on_completion(getParam<bool>(
"_bank_rays_on_completion")),
142 _ray_dependent_subdomain_setup(getParam<bool>(
"_ray_dependent_subdomain_setup")),
144 _always_cache_traces(getParam<bool>(
"always_cache_traces")),
145 _data_on_cache_traces(getParam<bool>(
"data_on_cache_traces")),
146 _aux_data_on_cache_traces(getParam<bool>(
"aux_data_on_cache_traces")),
147 _segments_on_cache_traces(getParam<bool>(
"segments_on_cache_traces")),
148 _ray_max_distance(getParam<
Real>(
"ray_distance")),
149 _verify_rays(getParam<bool>(
"verify_rays")),
151 _verify_trace_intersections(getParam<bool>(
"verify_trace_intersections")),
157 declareRestartableData<
std::unordered_map<
std::string,
RayID>>(
"registered_ray_map")),
158 _reverse_registered_ray_map(
159 declareRestartableData<
std::vector<
std::string>>(
"reverse_registered_ray_map")),
165 _has_non_planar_sides(true),
166 _has_same_level_active_elems(sameLevelActiveElems()),
169 _domain_max_length(1.01 * (_b_box.
max() - _b_box.
min()).
norm()),
170 _total_volume(computeTotalVolume()),
184 _local_trace_ray_results(
TraceRay::FAILED_TRACES + 1, 0),
186 _called_initial_setup(false),
188 _elem_index_helper(_mesh.
getMesh(),
name() +
"_elem_index")
206 if (!getParam<bool>(
"allow_other_flags_with_prekernels") &&
_execute_enum.
size() > 1)
208 "PRE_KERNELS cannot be mixed with any other execution flag.\nThat is, you cannot " 210 "mix RayKernels that contribute to the Jacobian/residual with those that do not.");
213 mooseError(
"Execution on residual and Jacobian evaluation (execute_on = PRE_KERNELS)\n",
214 "is not supported for an eigenvalue solve.");
256 std::vector<RayKernelBase *> ray_kernels;
258 for (
const auto & rkb : ray_kernels)
260 mooseError(
"This study has RayKernel objects that contribute to residuals and Jacobians.",
261 "\nIn this case, the study must use the execute_on = PRE_KERNELS");
272 mooseAssert(
_num_cached[tid] == 0,
"Cached residuals/Jacobians not empty");
275 rto->residualSetup();
282 mooseAssert(
_num_cached[tid] == 0,
"Cached residuals/Jacobians not empty");
285 rto->jacobianSetup();
292 rto->timestepSetup();
306 trace_ray->meshChanged();
321 std::vector<RayKernelBase *> ray_kernels;
324 std::set<SubdomainID> ray_kernel_blocks;
325 for (
const auto & rk : ray_kernels)
326 ray_kernel_blocks.insert(rk->blockIDs().begin(), rk->blockIDs().end());
328 std::set<SubdomainID> missing;
331 ray_kernel_blocks.begin(),
332 ray_kernel_blocks.end(),
333 std::inserter(missing, missing.begin()));
337 std::ostringstream error;
338 error <<
"Subdomains { ";
339 std::copy(missing.begin(), missing.end(), std::ostream_iterator<SubdomainID>(error,
" "));
340 error <<
"} do not have RayKernels defined!";
350 std::vector<RayTracingObject *> ray_tracing_objects;
362 for (
const auto & rto : rtos)
363 for (
const auto & dep_name : rto->getRequestedItems())
366 for (
const auto & rto_search : rtos)
367 if (rto_search->name() == dep_name)
374 rto->paramError(
"depends_on",
376 rto->parameters().get<std::string>(
"_moose_base"),
393 Utility::enum_to_string(elem->type()),
394 " is not supported in ray tracing with adaptivity");
398 Utility::enum_to_string(elem->type()),
399 " is not supported in ray tracing");
426 Elem * elem = bnd_elem->_elem;
427 const unsigned int side = bnd_elem->_side;
428 const auto bnd_id = bnd_elem->_bnd_id;
436 std::vector<RayBoundaryConditionBase *> result;
442 mooseError(
"RayBCs exist on internal sidesets that are not bounded by a different",
443 "\nsubdomain on each side.",
444 "\n\nIn order to use RayBCs on internal sidesets, said sidesets must have",
445 "\na different subdomain on each side.");
456 entry.resize(elem->
n_sides(), std::vector<BoundaryID>());
459 entry[side].push_back(bnd_id);
463 mooseError(
"RayBCs are defined on internal sidesets, but the study is not set to use ",
464 "internal sidesets during tracing.",
465 "\n\nSet the parameter use_internal_sidesets = true to enable this capability.");
486 entry.resize(elem->n_sides(), 0);
488 for (
const auto s : elem->side_index_range())
490 const auto & side =
elemSide(*elem, s);
491 if (side.n_vertices() < 4)
494 if (!side.has_affine_map())
502 "Ray tracing on non-planar faces is an approximation and may fail.\n\n",
503 "Use at your own risk! You can disable this warning by setting the\n",
504 "parameter 'warn_non_planar' to false.");
524 entry = std::max(entry, elem->hmax());
530 if (getParam<bool>(
"warn_subdomain_hmax"))
532 const auto warn_prefix =
type() +
" '" +
name() +
"': ";
533 const auto warn_suffix =
534 "\n\nRay tracing uses an approximate element size for each subdomain to scale the\n" 535 "tolerances used in computing ray intersections. This warning suggests that the\n" 536 "approximate element size is not a good approximation. This is likely due to poor\n" 537 "element aspect ratios.\n\n" 538 "This warning is only output for the first element affected.\n" 539 "To disable this warning, set warn_subdomain_hmax = false.\n";
543 const auto hmin = elem->hmin();
544 const auto hmax = elem->hmax();
547 const auto hmax_rel = hmax / max_hmax;
548 if (hmax_rel < 1.e-2 || hmax_rel > 1.e2)
550 "Element hmax varies significantly from subdomain hmax.\n",
552 "First element affected:\n",
555 const auto h_rel = max_hmax / hmin;
558 "Element hmin varies significantly from subdomain hmax.\n",
560 "First element affected:\n",
574 entry.resize(num_rays);
583 std::vector<std::string> all_ray_names;
586 all_ray_names.push_back(pair.first);
588 for (
auto & rto : rtos)
591 const auto & ray_names = rto->parameters().get<std::vector<std::string>>(
"rays");
593 const auto tid = rto->parameters().get<
THREAD_ID>(
"_tid");
597 for (
const auto & ray_name : (ray_names.empty() ? all_ray_names : ray_names))
602 "rays",
"Supplied ray '", ray_name,
"' is not a registered Ray in ",
typeAndName());
603 registration[id].insert(rto);
610 for (
const auto & rto : rtos)
611 if (rto->parameters().get<std::vector<std::string>>(
"rays").size())
614 "Rays cannot be supplied when the study does not require Ray registration.\n\n",
616 " does not require Ray registration.");
623 std::set<std::string> vars_to_be_zeroed;
624 std::vector<RayKernelBase *> ray_kernels;
626 for (
auto & rk : ray_kernels)
633 std::vector<std::string> vars_to_be_zeroed_vec(vars_to_be_zeroed.begin(),
634 vars_to_be_zeroed.end());
648 std::set<MooseVariableFEBase *> needed_moose_vars;
649 std::unordered_set<unsigned int> needed_mat_props;
655 rkb->subdomainSetup();
657 const auto & mv_deps = rkb->getMooseVariableDependencies();
658 needed_moose_vars.insert(mv_deps.begin(), mv_deps.end());
660 const auto & mp_deps = rkb->getMatPropDependencies();
661 needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
665 for (
auto & var : needed_moose_vars)
666 if (var->kind() == Moose::VarKindType::VAR_AUXILIARY)
689 if (rk->needSegmentReinit())
699 std::vector<Point> points;
700 std::vector<Real> weights;
713 std::vector<Point> & points,
714 std::vector<Real> & weights)
const 719 const Point diff = end - start;
720 const Point sum = end + start;
743 "Values should only be cached when computing Jacobian/residual");
752 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
763 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
773 TIME_SECTION(
"executeStudy", 2,
"Executing Study");
801 rto->preExecuteStudy();
818 auto generation_start_time = std::chrono::steady_clock::now();
820 TIME_SECTION(
"generateRays", 2,
"Generating Rays");
824 _generation_time = std::chrono::steady_clock::now() - generation_start_time;
833 "after generateRays()");
838 "after generateRays()");
844 TIME_SECTION(
"propagateRays", 2,
"Propagating Rays");
846 const auto propagation_start_time = std::chrono::steady_clock::now();
860 "after tracing completed");
868 "after tracing completed");
899 type(),
" '",
name(),
"': ", failures,
" ray tracing failures were tolerated.\n");
909 std::size_t num_entries = 0;
927 "Should not have cached values without Jacobian/residual computation");
950 rto->postExecuteStudy();
977 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
980 mooseError(
"Cannot register Ray ", (aux ?
"aux " :
""),
"data after initialSetup()");
983 const auto find = map.find(
name);
984 if (find != map.end())
988 if (other_map.find(
name) != other_map.end())
989 mooseError(
"Cannot register Ray aux data with name ",
992 (aux ?
"(non-aux)" :
"aux"),
993 " data already exists with said name.");
996 map.emplace(
name, map.size());
1000 vector.push_back(
name);
1002 return map.size() - 1;
1005 std::vector<RayDataIndex>
1008 std::vector<RayDataIndex> indices(names.size());
1009 for (std::size_t i = 0; i < names.size(); ++i)
1017 const bool graceful)
const 1019 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1022 const auto find = map.find(
name);
1023 if (find != map.end())
1024 return find->second;
1030 if (other_map.find(
name) != other_map.end())
1033 "' was not found.\n\n",
1035 (aux ?
"non-aux" :
"aux"),
1036 " data with said name was found.\n",
1037 "Did you mean to use ",
1038 (aux ?
"getRayDataIndex()/getRayDataIndices()?" 1039 :
"getRayAuxDataIndex()/getRayAuxDataIndices()"),
1042 mooseError(
"Unknown Ray ", (aux ?
"aux " :
""),
"data with name ",
name);
1045 std::vector<RayDataIndex>
1048 const bool graceful)
const 1050 std::vector<RayDataIndex> indices(names.size());
1051 for (std::size_t i = 0; i < names.size(); ++i)
1059 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1062 mooseError(
"Unknown Ray ", aux ?
"aux " :
"",
"data with index ", index);
1072 std::vector<RayDataIndex>
1084 std::vector<RayDataIndex>
1086 const bool graceful )
const 1103 std::vector<RayDataIndex>
1111 const bool graceful )
const 1116 std::vector<RayDataIndex>
1118 const bool graceful )
const 1132 std::vector<RayKernelBase *> result;
1134 return result.size();
1145 mooseError(
"Should not call getRayKernels() before initialSetup()");
1150 .condition<AttribSystem>(
"RayKernel")
1173 std::vector<RayKernelBase *> rkbs;
1181 for (
auto rkb : rkbs)
1182 if (ray_id_rtos.count(rkb))
1183 result.push_back(rkb);
1197 mooseError(
"Should not call getRayBCs() before initialSetup()");
1202 .condition<AttribSystem>(
"RayBoundaryCondition")
1212 const std::vector<TraceRayBndElement> & bnd_elems,
1219 if (bnd_elems.size() == 1)
1220 getRayBCs(result, bnd_elems[0].bnd_id, tid);
1223 std::vector<BoundaryID> bnd_ids(bnd_elems.size());
1224 for (MooseIndex(bnd_elems.size()) i = 0; i < bnd_elems.size(); ++i)
1225 bnd_ids[i] = bnd_elems[i].bnd_id;
1233 std::vector<RayBoundaryConditionBase *> rbcs;
1234 if (bnd_elems.size() == 1)
1235 getRayBCs(rbcs, bnd_elems[0].bnd_id, tid);
1238 std::vector<BoundaryID> bnd_ids(bnd_elems.size());
1239 for (MooseIndex(bnd_elems.size()) i = 0; i < bnd_elems.size(); ++i)
1240 bnd_ids[i] = bnd_elems[i].bnd_id;
1250 for (
auto rbc : rbcs)
1251 if (ray_id_rtos.count(rbc))
1252 result.push_back(rbc);
1256 std::vector<RayTracingObject *>
1259 std::vector<RayTracingObject *> result;
1264 const std::vector<std::shared_ptr<Ray>> &
1268 mooseError(
"The Ray bank is not available because the private parameter " 1269 "'_bank_rays_on_completion' is set to false.");
1271 mooseError(
"Cannot get the Ray bank during generation or propagation.");
1276 std::shared_ptr<Ray>
1281 std::shared_ptr<Ray> ray;
1282 for (
const std::shared_ptr<Ray> & possible_ray :
rayBank())
1283 if (possible_ray->id() == ray_id)
1290 unsigned int have_ray = ray ? 1 : 0;
1293 mooseError(
"Could not find a Ray with the ID ", ray_id,
" in the Ray banks.");
1296 mooseAssert(have_ray == 1,
"Multiple rays with the same ID were found in the Ray banks");
1304 const bool aux)
const 1309 Real value = ray ? (aux ? ray->auxData(index) : ray->data(index)) : 0;
1329 libmesh_parallel_only(
comm());
1331 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1334 mooseError(
"Cannot use registerRay() with Ray registration disabled");
1338 libmesh_parallel_only(
comm());
1353 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1356 mooseError(
"Should not use registeredRayID() with Ray registration disabled");
1360 return search->second;
1365 mooseError(
"Attempted to obtain ID of registered Ray ",
1367 ", but a Ray with said name is not registered.");
1373 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1376 mooseError(
"Should not use registeredRayName() with Ray registration disabled");
1381 mooseError(
"Attempted to obtain name of registered Ray with ID ",
1383 ", but a Ray with said ID is not registered.");
1391 volume += elem->volume();
1396 const std::vector<std::vector<BoundaryID>> &
1402 "Internal sideset map not initialized");
1420 const std::vector<std::shared_ptr<Ray>>::const_iterator end,
1422 const std::string & error_suffix)
const 1427 std::set<RayID> local_rays;
1428 for (
const std::shared_ptr<Ray> & ray :
as_range(begin, end))
1430 mooseAssert(ray,
"Null ray");
1434 if (!local_rays.insert(ray->id()).second)
1436 for (
const std::shared_ptr<Ray> & other_ray :
as_range(begin, end))
1437 if (ray.get() != other_ray.get() && ray->id() == other_ray->id())
1444 "\n\nOffending Ray information:\n\n",
1447 other_ray->getInfo());
1455 std::map<processor_id_type, std::vector<RayID>> send_ids;
1456 if (local_rays.size())
1457 send_ids.emplace(std::piecewise_construct,
1458 std::forward_as_tuple(0),
1459 std::forward_as_tuple(local_rays.begin(), local_rays.end()));
1463 std::map<RayID, processor_id_type> global_map;
1466 const auto check_ids =
1467 [
this, &global_map, &error_suffix](
processor_id_type pid,
const std::vector<RayID> & ids)
1469 for (
const RayID id : ids)
1471 const auto emplace_pair = global_map.emplace(
id, pid);
1474 if (!emplace_pair.second)
1477 " exists on ranks ",
1478 emplace_pair.first->second,
1486 Parallel::push_parallel_vector_data(
_communicator, send_ids, check_ids);
1492 const std::vector<std::shared_ptr<Ray>>::const_iterator end,
1493 const std::string & error_suffix)
1495 std::set<const Ray *> rays;
1496 for (
const std::shared_ptr<Ray> & ray :
as_range(begin, end))
1497 if (!rays.insert(ray.get()).second)
1498 mooseError(
"Multiple shared_ptrs were found that point to the same Ray ",
1500 "\n\nOffending Ray:\n",
1508 mooseAssert(ray,
"Null ray");
1509 mooseAssert(ray->shouldContinue(),
"Ray is not continuing");
1519 for (
const std::shared_ptr<Ray> & ray : rays)
1521 mooseAssert(ray,
"Null ray");
1522 mooseAssert(ray->shouldContinue(),
"Ray is not continuing");
1534 mooseAssert(ray,
"Null ray");
1544 mooseError(
"Can only reserve in Ray buffer during generateRays()");
1552 std::unordered_map<std::pair<const Elem *, unsigned short>,
Point> & cache =
1556 const auto elem_side_pair = std::make_pair(elem, side);
1557 const auto search = cache.find(elem_side_pair);
1560 if (search == cache.end())
1564 cache.emplace(elem_side_pair, normal);
1569 return search->second;
1575 unsigned int min_level = std::numeric_limits<unsigned int>::max();
1576 unsigned int max_level = std::numeric_limits<unsigned int>::min();
1580 const auto level = elem->
level();
1581 min_level = std::min(level, min_level);
1582 max_level = std::max(level, max_level);
1588 return min_level == max_level;
1596 mooseError(
"Subdomain ", subdomain_id,
" not found in subdomain hmax map");
1597 return find->second;
1603 Real bbox_volume = 1;
1613 libmesh_parallel_only(
comm());
1615 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1618 "Cannot be reset during generation or propagation");
1639 libmesh_parallel_only(
comm());
1641 Threads::spin_mutex::scoped_lock lock(
_spin_mutex);
1644 "Cannot be reset during generation or propagation");
1657 const unsigned short side,
1658 const Point & direction,
1662 const auto dot = normal * direction;
1666 std::shared_ptr<Ray>
1681 std::shared_ptr<Ray>
1695 std::shared_ptr<Ray>
1699 libmesh_parallel_only(
comm());
1711 std::shared_ptr<Ray>
1730 std::shared_ptr<Ray>
1738 std::shared_ptr<Ray>
bool hasRayKernels(const THREAD_ID tid)
Whether or not there are currently any active RayKernel objects.
bool currentlyGenerating() const
Whether or not the study is generating.
void getRayKernels(std::vector< RayKernelBase *> &result, SubdomainID id, THREAD_ID tid)
Fills the active RayKernels associated with this study and a block into result.
void internalSidesetSetup()
Does the setup for internal sidesets.
RayDataIndex registerRayData(const std::string &name)
Register a value to be filled in the data on a Ray with a given name.
RayData getBankedRayDataInternal(const RayID ray_id, const RayDataIndex index, const bool aux) const
Internal method for getting the value (replicated across all processors) in a Ray's data or aux data ...
virtual void postOnSegment(const THREAD_ID tid, const std::shared_ptr< Ray > &ray)
Called at the end of a Ray segment.
const bool _tolerate_failure
Whether or not to tolerate a Ray Tracing failure.
Real totalVolume() const
Get the current total volume of the domain.
void traceableMeshChecks()
Check for if all of the element types in the mesh are supported by ray tracing.
virtual void onCompleteRay(const std::shared_ptr< Ray > &ray)
Entry point for acting on a ray when it is completed (shouldContinue() == false)
libMesh::ConstElemRange * getActiveLocalElementRange()
const std::string & getRayDataNameInternal(const RayDataIndex index, const bool aux) const
Internal method for getting the name of Ray data or Ray aux data.
const std::vector< std::shared_ptr< Ray > > & rayBank() const
Get the Ray bank.
static const RayDataIndex INVALID_RAY_DATA_INDEX
Invalid index into a Ray's data.
std::vector< std::vector< std::set< const RayTracingObject * > > > _threaded_ray_object_registration
Threaded storage for all of the RayTracingObjects associated with a single Ray.
std::vector< std::string > & _reverse_registered_ray_map
Map from registered Ray ID to name.
unsigned long long int _total_intersections
Total number of Ray/element intersections.
RayID registerRay(const std::string &name)
Registers a Ray with a given name.
unsigned long long int _ending_intersections
Total number of Ray/element intersections for Rays that finished on this processor.
unsigned int _max_trajectory_changes
Max number of trajectory changes for a single Ray.
unsigned long int RayID
Type for a Ray's ID.
void verifyUniqueRayIDs(const std::vector< std::shared_ptr< Ray >>::const_iterator begin, const std::vector< std::shared_ptr< Ray >>::const_iterator end, const bool global, const std::string &error_suffix) const
Verifies that the Rays in the given range have unique Ray IDs.
bool _has_same_level_active_elems
Whether or not the mesh has active elements of the same level.
auto norm() const -> decltype(std::norm(Real()))
bool sameLevelActiveElems() const
Determine whether or not the mesh currently has active elements that are all the same level...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
virtual void initialSetup() override
void moveRayToBufferDuringTrace(std::shared_ptr< Ray > &ray, const THREAD_ID tid, const AcquireMoveDuringTraceKey &)
INTERNAL method for moving a Ray into the buffer during tracing.
RayDataIndex registerRayAuxData(const std::string &name)
Register a value to be filled in the aux data on a Ray with a given name.
Class that is used as a parameter to the public constructors/reset methods.
MooseMesh & _mesh
The Mesh.
T & getMesh(MooseMesh &mesh)
function to cast mesh
Attribute for the RayTracingStudy a RayTracingObject is associated with.
static InputParameters validParams()
virtual void prepare(const Elem *elem, const THREAD_ID tid) override
NumericVector< Number > & solution()
std::vector< std::vector< TraceData > > _threaded_cached_traces
The threaded storage for cached traces.
const bool _use_internal_sidesets
Whether or not to use the internal sidesets in ray tracing.
Data structure that stores information for output of a partial trace of a Ray on a processor...
std::shared_ptr< Ray > acquireRay()
User APIs for constructing Rays within the RayTracingStudy.
std::size_t rayAuxDataSize() const
The registered size of values in the Ray aux data.
std::unordered_map< SubdomainID, Real > _subdomain_hmax
The cached hmax for all elements in a subdomain.
libMesh::dof_id_type maxIndex() const
Gets the maximum index generated using this object.
libMesh::BoundingBox _loose_b_box
Loose nodal bounding box for the domain.
const std::set< BoundaryID > & getInternalSidesets() const
Gets the internal sidesets (that have RayBCs) within the local domain.
std::vector< std::vector< unsigned short > > _non_planar_sides
Non planar side data, which is for quick checking if an elem side is non-planar We use unsigned short...
RayData getBankedRayData(const RayID ray_id, const RayDataIndex index) const
Gets the data value for a banked ray with a given ID.
Base object for the RayKernel syntax.
void initialize(const libMesh::SimpleRange< libMesh::MeshBase::element_iterator > elems)
Initializes the indices in a contiguous manner for the given element range.
Real _ending_distance
Total distance traveled by Rays that end on this processor.
virtual void reinitSegment(const Elem *elem, const Point &start, const Point &end, const Real length, THREAD_ID tid)
Reinitialize objects for a Ray segment for ray tracing.
const std::string & name() const override
unsigned int size() const
RayDataIndex registerRayDataInternal(const std::string &name, const bool aux)
Internal method for registering Ray data or Ray aux data with a name.
const std::vector< RayKernelBase * > & currentRayKernels(THREAD_ID tid) const
Gets the current RayKernels for a thread, which are set in segmentSubdomainSetup() ...
const Parallel::Communicator & comm() const
Key that is used for restricting access to moveRayToBufferDuringTrace() and acquireRayDuringTrace().
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
std::shared_ptr< Ray > acquireReplicatedRay()
Acquire a Ray from the pool of Rays within generateRays() in a replicated fashion.
std::shared_ptr< Ray > acquireRayDuringTrace(const THREAD_ID tid, const AcquireMoveDuringTraceKey &)
INTERNAL methods for acquiring a Ray during a trace in RayKernels and RayBCs.
const Parallel::Communicator & _communicator
std::shared_ptr< Ray > acquireRegisteredRay(const std::string &name)
Acquires a Ray with a given name within generateRays().
void clearActiveMaterialProperties(const THREAD_ID tid)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
RayID _replicated_next_ray_id
Storage for the next available replicated RayID, obtained via generateReplicatedRayID() ...
std::set< BoundaryID > _internal_sidesets
The BoundaryIDs on the local mesh that have internal RayBCs.
virtual RayID generateUniqueRayID(const THREAD_ID tid)
Generates a unique RayID to be used for a Ray.
std::vector< std::vector< RayKernelBase * > > _threaded_current_ray_kernels
The current RayKernel objects for each thread.
virtual const std::string & name() const
void mooseWarning(Args &&... args) const
auto max(const L &left, const R &right)
std::vector< TraceData > _cached_traces
Storage for the cached traces.
RayDataIndex getRayAuxDataIndex(const std::string &name, const bool graceful=false) const
Gets the index associated with a registered value in the Ray aux data.
std::vector< std::shared_ptr< TraceRay > > _threaded_trace_ray
The TraceRay objects for each thread (they do the physical tracing)
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num) override
Real subdomainHmax(const SubdomainID subdomain_id) const
Get the cached hmax for all elements in a subdomain.
std::vector< RayID > _threaded_next_ray_id
Storage for the next available unique RayID, obtained via generateUniqueRayID()
bool isRectangularDomain() const
Whether or not the domain is rectangular (if it is prefectly encompassed by its bounding box) ...
std::vector< std::string > _ray_aux_data_names
The names for each Ray aux data entry.
virtual void setActiveElementalMooseVariables(const std::set< MooseVariableFEBase * > &moose_vars, const THREAD_ID tid) override
Threads::spin_mutex _spin_mutex
Spin mutex object for locks.
uint8_t processor_id_type
std::shared_ptr< Ray > getBankedRay(const RayID ray_id) const
Gets the Ray with the ID ray_id from the Ray bank.
unsigned long long int _total_processor_crossings
Total number of processor crossings.
processor_id_type n_processors() const
void nonPlanarSideSetup()
Sets up the caching of whether or not each element side is non-planar, which is stored in _non_planar...
bool verifyRays() const
Whether or not to verify if Rays have valid information before being traced.
unsigned int RayDataIndex
Type for the index into the data and aux data on a Ray.
void coverageChecks()
Perform coverage checks (coverage of RayMaterials and RayKernels, if enabled)
void resetReplicatedRayIDs()
Resets the generation of unique replicated RayIDs accessed via generateReplicatedRayID().
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const bool _bank_rays_on_completion
Whether or not to bank rays on completion.
void min(const T &r, T &o, Request &req) const
unsigned int _ending_max_intersections
Max number of intersections for Rays that finished on this processor.
TheWarehouse & theWarehouse() const
virtual void postExecuteStudy()
Entry point after study execution.
MooseVariableFE< Real > & variable()
Gets the variable this AuxRayKernel contributes to.
unsigned int _max_processor_crossings
Max number of processor crossings for all Rays.
const std::unique_ptr< ParallelRayStudy > _parallel_ray_study
The study that used is to actually execute (trace) the Rays.
virtual unsigned int dimension() const
std::vector< RayTracingObject * > getRayTracingObjects()
Gets all of the currently active RayTracingObjects.
virtual void residualSetup() override
static InputParameters validParams()
const Point & min() const
const bool & currentlyComputingResidual() const
boundary_id_type BoundaryID
std::vector< TheWarehouse::QueryCache< AttribSubdomains > > _threaded_cache_ray_kernel
Threaded cached subdomain query for RayKernelBase objects pertaining to this study.
virtual void execute() override
Executes the study (generates and propagates Rays)
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
unsigned int _max_intersections
Max number of intersections for a single Ray.
unsigned int _ending_max_trajectory_changes
Max number of trajectory changes for Rays that finished on this processor.
unsigned int _ending_max_processor_crossings
Max number of total processor crossings for Rays that finished on this processor. ...
const std::string & getRayDataName(const RayDataIndex index) const
Gets the name associated with a registered value in the Ray data.
void reserveRayBuffer(const std::size_t size)
Reserve size entires in the Ray buffer.
void zeroAuxVariables()
Zero the AuxVariables that the registered AuxRayKernels contribute to.
std::vector< std::unique_ptr< libMesh::FEBase > > _threaded_fe_face
Face FE used for computing face normals for each thread.
const std::string & type() const
void dependencyChecks()
Perform checks to see if the listed dependencies in the RayTracingObjects exist.
static InputParameters validParams()
const std::string & getRayAuxDataName(const RayDataIndex index) const
Gets the name associated with a registered value in the Ray aux data.
virtual void cacheResidual(const THREAD_ID tid) override
Basic datastructure for a ray that will traverse the mesh.
std::chrono::steady_clock::time_point _execution_start_time
Timing.
std::vector< TheWarehouse::QueryCache< AttribBoundaries > > _threaded_cache_ray_bc
Threaded cached boundary query for RayBC objects pertaining to this study.
virtual void jacobianSetup() override
std::string typeAndName() const
void paramError(const std::string ¶m, Args... args) const
bool isValueSet(const std::string &value) const
unsigned int number() const
std::string stringify(const T &t)
virtual void preExecuteStudy()
Entry point before study execution.
std::unordered_map< std::string, RayDataIndex > _ray_aux_data_map
The map from Ray aux data names to index.
AuxiliarySystem & getAuxiliarySystem()
const bool _warn_non_planar
Whether not to warn if non-planar faces are found.
libMesh::BoundingBox _b_box
Nodal bounding box for the domain.
virtual void meshChanged() override
libMesh::dof_id_type getIndex(const libMesh::Elem *elem) const
Get the index associated with the element elem.
virtual void setCurrentSubdomainID(const Elem *elem, const THREAD_ID tid) override
virtual void generateRays()=0
Subclasses should override this to determine how to generate Rays.
RayID generateReplicatedRayID()
Generates a Ray ID that is replicated across all processors.
const ExecFlagEnum & _execute_enum
RayDataIndex getRayDataIndexInternal(const std::string &name, const bool aux, const bool graceful) const
Internal method for getting the index of Ray data or Ray aux data.
void verifyDependenciesExist(const std::vector< RayTracingObject *> &rtos)
Verifies that the dependencies exist for a set of RayTracingObjects.
unsigned long long int _ending_processor_crossings
Total number of processor crossings for Rays that finished on this processor.
ElemIndexHelper _elem_index_helper
Helper for defining a local contiguous index for each element.
RayTracingStudy(const InputParameters ¶meters)
virtual unsigned int n_sides() const=0
std::vector< std::unordered_map< std::pair< const Elem *, unsigned short >, Point > > _threaded_cached_normals
Threaded cache for side normals that have been computed already during tracing.
TraceData & initThreadedCachedTrace(const std::shared_ptr< Ray > &ray, THREAD_ID tid)
Initialize a Ray in the threaded cached trace map to be filled with segments.
virtual const SystemBase & getSystemBase(const unsigned int sys_num) const
const Elem * neighbor_ptr(unsigned int i) const
virtual const Point & getSideNormal(const Elem *elem, const unsigned short side, const THREAD_ID tid)
Get the outward normal for a given element side.
const SubdomainID ANY_BLOCK_ID
unsigned int level() const
std::vector< RayDataIndex > getRayAuxDataIndices(const std::vector< std::string > &names, const bool graceful=false) const
Gets the indices associated with registered values in the Ray aux data.
std::unordered_map< std::string, RayDataIndex > _ray_data_map
The map from Ray data names to index.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< RayDataIndex > getRayDataIndices(const std::vector< std::string > &names, const bool graceful=false) const
Gets the indices associated with registered values in the Ray data.
bool currentlyPropagating() const
Whether or not the study is propagating (tracing Rays)
subdomain_id_type subdomain_id() const
bool _has_non_planar_sides
Whether or not the local mesh has elements with non-planar sides.
virtual void subdomainSetup(SubdomainID subdomain, const THREAD_ID tid)
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.
void max(const T &r, T &o, Request &req) const
void reinitMaterials(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true)
FEProblemBase & _fe_problem
void getRayBCs(std::vector< RayBoundaryConditionBase *> &result, BoundaryID id, THREAD_ID tid)
Fills the active RayBCs associated with this study and a boundary into result.
std::vector< std::size_t > _num_cached
Number of currently cached objects for Jacobian/residual for each thread.
std::chrono::steady_clock::duration _propagation_time
virtual void segmentSubdomainSetup(const SubdomainID subdomain, const THREAD_ID tid, const RayID ray_id)
Setup for on subdomain change or subdomain AND ray change during ray tracing.
RayData getBankedRayAuxData(const RayID ray_id, const RayDataIndex index) const
Gets the data value for a banked ray with a given ID.
bool _called_initial_setup
Whether or not we've called initial setup - used to stop from late registration.
void verifyUniqueRays(const std::vector< std::shared_ptr< Ray >>::const_iterator begin, const std::vector< std::shared_ptr< Ray >>::const_iterator end, const std::string &error_suffix)
Verifies that the Rays in the given range are unique.
std::vector< RayDataIndex > getRayDataIndicesInternal(const std::vector< std::string > &names, const bool aux, const bool graceful) const
Internal method for getting the indicies of Ray data or Ray aux data.
void mooseError(Args &&... args) const
Real _total_distance
Total distance traveled by all Rays.
const processor_id_type _pid
The rank of this processor (this actually takes time to lookup - so just do it once) ...
std::unordered_map< std::string, RayID > & _registered_ray_map
Map from registered Ray name to ID.
std::vector< std::string > _ray_data_names
The names for each Ray data entry.
float RayData
Type for a Ray's data.
const std::string & registeredRayName(const RayID ray_id) const
Gets the name of a registered ray.
void moveRayToBuffer(std::shared_ptr< Ray > &ray)
Moves a ray to the buffer to be traced during generateRays().
const ExecFlagType EXEC_PRE_KERNELS
RayID registeredRayID(const std::string &name, const bool graceful=false) const
Gets the ID of a registered ray.
virtual void buildSegmentQuadrature(const Point &start, const Point &end, const Real length, std::vector< Point > &points, std::vector< Real > &weights) const
Builds quadrature points for a given segment using the _segment_qrule.
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement *> * getBoundaryElementRange()
const bool _use_ray_registration
Whether or not to use Ray registration.
virtual bool hasActiveElementalMooseVariables(const THREAD_ID tid) const
const bool _ray_kernel_coverage_check
Whether or not to perform coverage checks on RayKernels.
void localElemIndexSetup()
Sets up the _elem_index_helper, which is used for obtaining a contiguous index for all elements that ...
const bool & currentlyComputingJacobian() const
std::vector< std::shared_ptr< Ray > > _ray_bank
Cumulative Ray bank - stored only when _bank_rays_on_completion.
const Point & max() const
std::vector< unsigned long long int > _local_trace_ray_results
Cumulative results on this processor from the threaded TraceRay objects.
std::chrono::steady_clock::duration _generation_time
void registeredRaySetup()
Sets up the maps from Ray to associated RayTracingObjects if _use_ray_registration.
void scale(const Real factor)
void moveRaysToBuffer(std::vector< std::shared_ptr< Ray >> &rays)
Moves rays to the buffer to be traced during generateRays().
void executeStudy()
Method for executing the study so that it can be called out of the standard UO execute() ...
void prepareMaterials(const std::unordered_set< unsigned int > &consumer_needed_mat_props, const SubdomainID blk_id, const THREAD_ID tid)
Adaptivity & adaptivity()
bool hasActiveMaterialProperties(const THREAD_ID tid) const
virtual void cacheJacobian(const THREAD_ID tid) override
auto min(const L &left, const R &right)
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid) override
std::shared_ptr< Ray > acquireUnsizedRay()
Acquire a Ray from the pool of Rays within generateRays(), without resizing the data (sizes the data ...
RayDataIndex getRayDataIndex(const std::string &name, const bool graceful=false) const
Gets the index associated with a registered value in the Ray data.
void resetUniqueRayIDs()
Resets the generation of unique RayIDs via generateUniqueRayID() to the beginning of the range...
virtual void addCachedResidual(const THREAD_ID tid) override
std::chrono::steady_clock::duration _execution_time
virtual void zeroVariables(std::vector< std::string > &vars_to_be_zeroed)
virtual void clearActiveElementalMooseVariables(const THREAD_ID tid) override
std::vector< std::unique_ptr< libMesh::QBase > > _threaded_q_face
Face quadrature used for computing face normals for each thread.
std::shared_ptr< Ray > acquireCopiedRay(const Ray &ray)
Acquires a Ray that that is copied from another Ray within generateRays().
Traces Rays through the mesh on a single processor.
std::vector< std::vector< std::vector< BoundaryID > > > _internal_sidesets_map
Internal sideset data, if internal sidesets exist (indexed with getLocalElemIndex()) ...
void subdomainHMaxSetup()
Caches the hmax for all elements in each subdomain.
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.
static const RayID INVALID_RAY_ID
Invalid Ray ID.
std::unique_ptr< libMesh::QBase > _segment_qrule
Quadrature rule for laying points across a 1D ray segment.
bool hasInternalSidesets() const
Whether or not the local mesh has internal sidesets that have RayBCs on them.
std::size_t rayDataSize() const
The registered size of values in the Ray data.
virtual void timestepSetup() override
const std::set< SubdomainID > & meshSubdomains() const
virtual void addCachedJacobian(const THREAD_ID tid) override
virtual bool shouldCacheTrace(const std::shared_ptr< Ray > &) const
Virtual that allows for selection in if a Ray should be cached or not (only used when _cache_traces)...
const RemoteElem * remote_elem
Real computeTotalVolume()
Helper function for computing the total domain volume.