Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #include "Ray.h"
11 :
12 : // Local includes
13 : #include "ParallelRayStudy.h"
14 : #include "RayTracingStudy.h"
15 : #include "RayTracingPackingUtils.h"
16 :
17 : // MOOSE includes
18 : #include "DataIO.h"
19 :
20 : using namespace libMesh;
21 :
22 6314081 : Ray::Ray(RayTracingStudy * study,
23 : const RayID id,
24 : const std::size_t data_size,
25 : const std::size_t aux_data_size,
26 : const bool /* reset */,
27 6314081 : const ConstructRayKey &)
28 6314081 : : _id(id),
29 6314081 : _current_point(RayTracingCommon::invalid_point),
30 6314081 : _direction(RayTracingCommon::invalid_point),
31 6314081 : _current_elem(nullptr),
32 6314081 : _current_incoming_side(RayTracingCommon::invalid_side),
33 6314081 : _end_set(false),
34 6314081 : _max_distance(std::numeric_limits<Real>::max()),
35 6314081 : _data(data_size, 0),
36 6314081 : _aux_data(aux_data_size, 0),
37 6314081 : _study(*study)
38 : {
39 6314081 : resetCountersInternal();
40 6314081 : }
41 :
42 : void
43 492585 : Ray::reset(RayTracingStudy * libmesh_dbg_var(study),
44 : const RayID id,
45 : const std::size_t data_size,
46 : const std::size_t aux_data_size,
47 : const bool reset,
48 : const ConstructRayKey &)
49 : {
50 492585 : _id = id;
51 492585 : _data.resize(data_size, 0);
52 492585 : _aux_data.resize(aux_data_size, 0);
53 :
54 492585 : if (reset)
55 : {
56 4973 : resetCountersInternal();
57 4973 : _current_point = RayTracingCommon::invalid_point;
58 4973 : _direction = RayTracingCommon::invalid_point;
59 4973 : _current_elem = nullptr;
60 4973 : _current_incoming_side = RayTracingCommon::invalid_side;
61 4973 : _end_set = false;
62 4973 : _max_distance = std::numeric_limits<Real>::max();
63 : std::fill(_data.begin(), _data.end(), 0);
64 : std::fill(_aux_data.begin(), _aux_data.end(), 0);
65 : }
66 :
67 : mooseAssert(study == &_study, "Resetting Ray from different study");
68 492585 : }
69 :
70 2658269 : Ray::Ray(const Ray * const other, const ConstructRayKey & key)
71 2658269 : : Ray(&other->_study,
72 2658269 : other->_id,
73 : other->_data.size(),
74 : other->_aux_data.size(),
75 : /* reset = */ true,
76 2658269 : key)
77 : {
78 2658269 : other->errorIfTracing("Cannot copy Ray");
79 :
80 2658269 : if (!other->invalidCurrentPoint())
81 2658269 : setStart(other->_current_point, other->_current_elem, other->_current_incoming_side);
82 :
83 2658269 : if (other->_end_set)
84 1786074 : setStartingEndPoint(other->endPoint());
85 : else
86 : {
87 872195 : if (!other->invalidDirection())
88 872195 : setStartingDirection(other->_direction);
89 872195 : if (other->maxDistanceSet())
90 30 : _max_distance = other->_max_distance;
91 : }
92 :
93 : std::copy(other->_data.begin(), other->_data.end(), _data.begin());
94 : std::copy(other->_aux_data.begin(), other->_aux_data.end(), _aux_data.begin());
95 2658269 : }
96 :
97 : void
98 40154 : Ray::reset(const Ray * const other, const ConstructRayKey &)
99 : {
100 40154 : other->errorIfTracing("Cannot copy Ray");
101 : mooseAssert(&other->_study == &_study, "Cannot copy Ray from different study");
102 :
103 40154 : clearStartingInfoInternal();
104 40154 : resetCountersInternal();
105 :
106 40154 : _id = other->_id;
107 :
108 40154 : if (!other->invalidCurrentPoint())
109 40154 : setStart(other->_current_point, other->_current_elem, other->_current_incoming_side);
110 :
111 40154 : if (other->_end_set)
112 22276 : setStartingEndPoint(other->endPoint());
113 : else
114 : {
115 17878 : if (!other->invalidDirection())
116 17878 : setStartingDirection(other->_direction);
117 17878 : if (other->maxDistanceSet())
118 6 : _max_distance = other->_max_distance;
119 : }
120 :
121 40154 : _data = other->_data;
122 40154 : _aux_data = other->_aux_data;
123 40154 : }
124 :
125 : bool
126 62698 : Ray::equalityHelper(const Ray & other, const bool equal) const
127 : {
128 62698 : if (this == &other)
129 : return equal;
130 :
131 59434 : if (_id != other._id)
132 3264 : return !equal;
133 56170 : if (invalidCurrentPoint() != other.invalidCurrentPoint() ||
134 52906 : !_current_point.absolute_fuzzy_equals(other._current_point))
135 3264 : return !equal;
136 52906 : if (invalidDirection() != other.invalidDirection() ||
137 49642 : !_direction.absolute_fuzzy_equals(other._direction))
138 3264 : return !equal;
139 49642 : if (_current_elem != other._current_elem)
140 3264 : return !equal;
141 46378 : if (_current_incoming_side != other._current_incoming_side)
142 3264 : return !equal;
143 43114 : if (_trajectory_changed != other._trajectory_changed)
144 3264 : return !equal;
145 39850 : if (_end_set != other._end_set)
146 3264 : return !equal;
147 36586 : if (_should_continue != other._should_continue)
148 3264 : return !equal;
149 33322 : if (_processor_crossings != other._processor_crossings)
150 3264 : return !equal;
151 30058 : if (_intersections != other._intersections)
152 3264 : return !equal;
153 26794 : if (_trajectory_changes != other._trajectory_changes)
154 3264 : return !equal;
155 23530 : if (!MooseUtils::absoluteFuzzyEqual(_distance, other._distance))
156 3264 : return !equal;
157 20266 : if (!MooseUtils::absoluteFuzzyEqual(_max_distance, other._max_distance))
158 3264 : return !equal;
159 17002 : if (_data.size() != other._data.size())
160 3264 : return !equal;
161 23854 : for (std::size_t i = 0; i < _data.size(); ++i)
162 13380 : if (!MooseUtils::absoluteFuzzyEqual(_data[i], other._data[i]))
163 3264 : return !equal;
164 10474 : if (_aux_data.size() != other._aux_data.size())
165 3264 : return !equal;
166 10558 : for (std::size_t i = 0; i < _aux_data.size(); ++i)
167 6612 : if (!MooseUtils::absoluteFuzzyEqual(_aux_data[i], other._aux_data[i]))
168 3264 : return !equal;
169 3946 : if (&_study != &other._study)
170 3264 : return !equal;
171 :
172 : return equal;
173 : }
174 :
175 : bool
176 1176 : Ray::atEnd() const
177 : {
178 1176 : if (!_end_set)
179 2 : mooseError("Cannot use Ray::atEnd() for a Ray that does not have an end set\n\n", getInfo());
180 : mooseAssert(_distance <= _max_distance + TOLERANCE * TOLERANCE, "Distance past max distance");
181 :
182 1174 : return MooseUtils::absoluteFuzzyEqual(_distance, _max_distance);
183 : }
184 :
185 : Point
186 1809524 : Ray::endPoint() const
187 : {
188 1809524 : if (!_end_set)
189 2 : mooseError("Cannot use Ray::endPoint() for a Ray that does not have an end set\n\n", getInfo());
190 : mooseAssert(_distance <= _max_distance + TOLERANCE * TOLERANCE, "Distance past max distance");
191 :
192 1809522 : return _current_point + (_max_distance - _distance) * _direction;
193 : }
194 :
195 : void
196 2692 : Ray::changeDirection(const Point & direction, const ChangeDirectionKey)
197 : {
198 2692 : if (direction.absolute_fuzzy_equals(Point(0, 0, 0)))
199 2 : mooseError("Cannot set zero vector direction for a Ray\n\n", getInfo());
200 :
201 2690 : _direction = direction.unit();
202 2690 : _trajectory_changed = true;
203 2690 : }
204 :
205 : void
206 436 : Ray::changeStartDirection(const Point & start,
207 : const Point & direction,
208 : const ChangeStartDirectionKey)
209 : {
210 436 : if (direction.absolute_fuzzy_equals(Point(0, 0, 0)))
211 2 : mooseError("Cannot set zero vector direction for a Ray\n\n", getInfo());
212 :
213 434 : _current_point = start;
214 434 : _direction = direction.unit();
215 434 : _trajectory_changed = true;
216 434 : }
217 :
218 : void
219 31686 : Ray::changePointElemSide(const Point & point,
220 : const Elem & elem,
221 : const unsigned int side,
222 : const ChangePointElemSideKey)
223 : {
224 : mooseAssert(!_trajectory_changed, "Should not have already changed");
225 :
226 31686 : _current_point = point;
227 31686 : _current_elem = &elem;
228 31686 : _current_incoming_side = side;
229 31686 : _trajectory_changed = true;
230 31686 : }
231 :
232 : void
233 5443265 : Ray::setStart(const Point & starting_point,
234 : const Elem * starting_elem /* = nullptr */,
235 : const unsigned short starting_incoming_side /* = RayTracingCommon::invalid_side */)
236 : {
237 : mooseAssert(starting_point != RayTracingCommon::invalid_point, "Invalid point");
238 5443265 : errorIfTracing("Cannot use Ray::setStart()");
239 5443265 : if (!invalidCurrentPoint() && !_current_point.absolute_fuzzy_equals(starting_point))
240 2 : errorWhenInitializing("Starting point was already set via Ray::setStart() and is being changed."
241 : "\n\nYou may only call Ray::setStart() after it has been called once to"
242 : "\nchange the starting element and starting incoming side."
243 : "\n\nYou may also clear the starting info via Ray::clearStartingInfo().");
244 :
245 5443263 : _current_point = starting_point;
246 5443263 : _current_elem = starting_elem;
247 5443263 : _current_incoming_side = starting_incoming_side;
248 :
249 5443263 : if (_study.verifyRays())
250 : {
251 5443263 : if (!_study.looseBoundingBox().contains_point(starting_point))
252 2 : errorWhenInitializing("Mesh does not contain starting point.");
253 5443261 : if (starting_elem)
254 : {
255 : mooseAssert(_study.meshBase().query_elem_ptr(starting_elem->id()) == starting_elem,
256 : "Element is not owned by the mesh");
257 : if (!starting_elem->active())
258 2 : errorWhenInitializing("Starting element is not active.");
259 : }
260 :
261 : bool non_planar_start = false;
262 :
263 5443259 : if (!invalidCurrentIncomingSide())
264 : {
265 1572245 : if (!starting_elem)
266 2 : errorWhenInitializing("Starting incoming side is set but starting element is not set.");
267 1572243 : if (starting_elem->n_sides() < starting_incoming_side)
268 2 : errorWhenInitializing("Starting incoming side is not valid for its starting element.");
269 :
270 1572241 : non_planar_start = _study.sideIsNonPlanar(starting_elem, starting_incoming_side);
271 3144482 : if (!non_planar_start &&
272 3144482 : !starting_elem->build_side_ptr(starting_incoming_side)->contains_point(starting_point))
273 2 : errorWhenInitializing("Starting incoming side does not contain the starting point.");
274 : }
275 :
276 5443253 : if (starting_elem && !non_planar_start && !starting_elem->contains_point(starting_point))
277 2 : errorWhenInitializing("Starting element does not contain the starting point.");
278 : }
279 5443251 : }
280 :
281 : void
282 5409557 : Ray::setStartingDirection(const Point & starting_direction)
283 : {
284 5409557 : errorIfTracing("Cannot use Ray::setStartingDirection()");
285 5409557 : if (invalidCurrentPoint())
286 2 : errorWhenInitializing("Cannot use Ray::setStartingDirection() before Ray::setStart().");
287 5409555 : if (!invalidDirection())
288 2 : errorWhenInitializing(
289 : "Cannot change a Ray's starting direction using Ray::setStartingDirection()"
290 : "\nafter it has already been set."
291 : "\n\nYou must first clear the starting info using Ray::clearStartingInfo().");
292 5409553 : if (starting_direction.absolute_fuzzy_equals(Point(0, 0, 0)))
293 2 : errorWhenInitializing("Starting direction in Ray::setStartingDirection() is the zero vector.");
294 :
295 5409551 : _direction = starting_direction.unit();
296 5409551 : }
297 :
298 : void
299 3591957 : Ray::setStartingEndPoint(const Point & starting_end_point)
300 : {
301 3591957 : errorIfTracing("Cannot use Ray::setStartingEndPoint()");
302 3591957 : if (invalidCurrentPoint())
303 2 : errorWhenInitializing("Cannot use Ray::setStartingEndPoint() before Ray::setStart().");
304 3591955 : if (_current_point.absolute_fuzzy_equals(starting_end_point))
305 2 : errorWhenInitializing("End point is equal to the start point in Ray::setStartingEndPoint().");
306 3591953 : if (!invalidDirection())
307 2 : errorWhenInitializing("Cannot use Ray::setStartingEndPoint() after Ray::setStartingDirection()."
308 : "\n\nClear the starting information with Ray::clearStartingInfo().");
309 3591951 : if (maxDistanceSet())
310 2 : errorWhenInitializing(
311 : "Cannot use Ray::setStartingEndPoint() after Ray::setStartingMaxDistance().");
312 :
313 3591949 : if (_study.verifyRays() && !_study.looseBoundingBox().contains_point(starting_end_point))
314 2 : errorWhenInitializing("End point is not within the mesh for Ray::setStartingEndPoint().");
315 :
316 3591947 : Point difference = starting_end_point;
317 : difference -= _current_point;
318 3591947 : setStartingMaxDistance(difference.norm());
319 3591947 : setStartingDirection(difference);
320 3591947 : _end_set = true;
321 3591947 : }
322 :
323 : void
324 3592691 : Ray::setStartingMaxDistance(const Real starting_max_distance)
325 : {
326 3592691 : errorIfTracing("Cannot use Ray::setStartingMaxDistance()");
327 3592691 : if (invalidCurrentPoint())
328 2 : errorWhenInitializing("Cannot use Ray::setStartingMaxDistance() before Ray::setStart().");
329 3592689 : if (starting_max_distance <= 0)
330 2 : errorWhenInitializing("Starting max distance is <= 0 in Ray::setStartingMaxDistance().");
331 3592687 : if (_end_set)
332 2 : errorWhenInitializing(
333 : "Cannot use Ray::setStartingMaxDistance() after Ray::setStartingEndPoint().");
334 :
335 3592685 : _max_distance = starting_max_distance;
336 3592685 : }
337 :
338 : void
339 1056 : Ray::setStationary()
340 : {
341 1056 : errorIfTracing("Cannot use Ray::setStationary()");
342 1056 : if (invalidCurrentPoint())
343 2 : errorWhenInitializing("Cannot use Ray::setStationary() before Ray::setStart()");
344 1054 : if (_end_set)
345 2 : errorWhenInitializing("Cannot use Ray::setStationary() after Ray::setStartingEndPoint()");
346 1052 : if (!invalidDirection())
347 2 : errorWhenInitializing("Cannot use Ray::setStationary() with Ray::setStartingDirection()");
348 1050 : _max_distance = 0;
349 : mooseAssert(stationary(), "Stationary not set");
350 1050 : }
351 :
352 : void
353 62208 : Ray::invalidateStartingElem()
354 : {
355 124416 : errorIfTracing("Cannot use Ray::invalidateStartingElem()");
356 : invalidateCurrentElem();
357 62208 : }
358 :
359 : void
360 62208 : Ray::invalidateStartingIncomingSide()
361 : {
362 124416 : errorIfTracing("Cannot use Ray::invalidateStartingIncomingSide()");
363 : invalidateCurrentIncomingSide();
364 62208 : }
365 :
366 : void
367 668 : Ray::clearStartingInfo()
368 : {
369 668 : errorIfTracing("Cannot use Ray::clearStartingInfo()");
370 666 : clearStartingInfoInternal();
371 666 : }
372 :
373 : void
374 40820 : Ray::clearStartingInfoInternal()
375 : {
376 : invalidateCurrentPoint();
377 : invalidateCurrentElem();
378 : invalidateCurrentIncomingSide();
379 : invalidateDirection();
380 : invalidateMaxDistance();
381 40820 : _end_set = false;
382 40820 : }
383 :
384 : void
385 20862033 : Ray::errorIfTracing(const std::string & reason) const
386 : {
387 : if (hasTraced())
388 2 : mooseError(reason, " after it has started tracing\n\n", getInfo());
389 20862031 : }
390 :
391 : void
392 42 : Ray::errorWhenInitializing(const std::string & reason) const
393 : {
394 42 : mooseError("While initializing starting information for a Ray:\n\n", reason, "\n\n", getInfo());
395 : }
396 :
397 : void
398 668 : Ray::resetCounters()
399 : {
400 668 : if (!_study.currentlyGenerating())
401 2 : mooseError("Ray::resetCounters() can only be used during generateRays()\n\n", getInfo());
402 666 : resetCountersInternal();
403 666 : }
404 :
405 : void
406 6359874 : Ray::resetCountersInternal()
407 : {
408 6359874 : _processor_crossings = 0;
409 6359874 : _intersections = 0;
410 6359874 : _trajectory_changes = 0;
411 6359874 : _distance = 0;
412 6359874 : _trajectory_changed = false;
413 6359874 : _should_continue = true;
414 6359874 : }
415 :
416 : std::vector<RayData> &
417 2025052 : Ray::data()
418 : {
419 : mooseAssert(_data.size() == 0 || _data.size() == _study.rayDataSize(),
420 : "Ray data size of " + std::to_string(_data.size()) +
421 : " is not zero or the size required by the study of " +
422 : std::to_string(_study.rayDataSize()));
423 2025052 : _data.resize(_study.rayDataSize());
424 2025052 : return _data;
425 : }
426 :
427 : const std::vector<RayData> &
428 126236 : Ray::data() const
429 : {
430 : mooseAssert(_data.size() == 0 || _data.size() == _study.rayDataSize(),
431 : "Ray data size is not zero or the size required by study");
432 126236 : _data.resize(_study.rayDataSize());
433 126236 : return _data;
434 : }
435 :
436 : RayData &
437 962030 : Ray::data(const std::size_t i)
438 : {
439 : mooseAssert(_study.rayDataSize() > i, "Accessing Ray data out of range");
440 962030 : return data()[i];
441 : }
442 :
443 : const RayData &
444 121248 : Ray::data(const std::size_t i) const
445 : {
446 : mooseAssert(_study.rayDataSize() > i, "Accessing Ray data out of range");
447 121248 : return data()[i];
448 : }
449 :
450 : std::vector<RayData> &
451 1442656 : Ray::auxData()
452 : {
453 : mooseAssert(_aux_data.size() == 0 || _aux_data.size() == _study.rayAuxDataSize(),
454 : "Ray data size is not zero or the size required by study");
455 1442656 : _aux_data.resize(_study.rayAuxDataSize());
456 1442656 : return _aux_data;
457 : }
458 :
459 : const std::vector<RayData> &
460 1461636 : Ray::auxData() const
461 : {
462 : mooseAssert(_aux_data.size() == 0 || _aux_data.size() == _study.rayAuxDataSize(),
463 : "Ray data size is not zero or the size required by study");
464 1461636 : _aux_data.resize(_study.rayAuxDataSize());
465 1461636 : return _aux_data;
466 : }
467 :
468 : RayData &
469 379782 : Ray::auxData(const std::size_t i)
470 : {
471 : mooseAssert(_study.rayAuxDataSize() > i, "Accessing Ray data out of range");
472 379782 : return auxData()[i];
473 : }
474 :
475 : const RayData &
476 1456648 : Ray::auxData(const std::size_t i) const
477 : {
478 : mooseAssert(_study.rayAuxDataSize() > i, "Accessing Ray data out of range");
479 1456648 : return auxData()[i];
480 : }
481 :
482 : std::string
483 2540 : Ray::getInfo() const
484 : {
485 2540 : std::ostringstream oss;
486 :
487 2540 : oss << "Ray information with " << _study.type() << " '" << _study.name() << "' on pid "
488 2540 : << _study.comm().rank() << "\n";
489 5080 : oss << " this = " << this << "\n";
490 5080 : oss << " id() = " << id() << "\n";
491 2540 : if (_study.useRayRegistration() && !invalidID())
492 72 : oss << " _study.registeredRayName(id()) = " << _study.registeredRayName(id()) << "\n";
493 2540 : oss << " currentPoint() = ";
494 2540 : if (invalidCurrentPoint())
495 12 : oss << "invalid point\n";
496 : else
497 2528 : oss << currentPoint() << "\n";
498 2540 : oss << " direction() = ";
499 2540 : if (invalidDirection())
500 36 : oss << "invalid point\n";
501 : else
502 2504 : oss << direction() << "\n";
503 2540 : oss << " currentIncomingSide() = ";
504 2540 : if (invalidCurrentIncomingSide())
505 200 : oss << "invalid side\n";
506 : else
507 2340 : oss << currentIncomingSide() << "\n";
508 3908 : oss << " endSet() = " << (endSet() ? "true" : "false") << "\n";
509 2540 : if (endSet())
510 : {
511 2344 : oss << " endPoint() = " << endPoint() << "\n";
512 1186 : oss << " atEnd() = " << (atEnd() ? "true" : "false") << "\n";
513 : }
514 5080 : oss << " distance() = " << distance() << "\n";
515 5080 : oss << " maxDistance() = " << maxDistance() << "\n";
516 2540 : if (currentElem())
517 : {
518 5040 : oss << " currentElem()->id() = " << currentElem()->id() << "\n";
519 5040 : oss << " currentElem()->processor_id() = " << currentElem()->processor_id() << "\n";
520 : }
521 : else
522 20 : oss << " currentElem()->id() = invalid\n";
523 5080 : oss << " processorCrossings() = " << processorCrossings() << "\n";
524 5080 : oss << " intersections() = " << intersections() << "\n";
525 5080 : oss << " trajectoryChanges() = " << trajectoryChanges() << "\n";
526 4998 : oss << " shouldContinue() = " << (shouldContinue() ? "true" : "false") << "\n";
527 5076 : oss << " trajectoryChanged() = " << (trajectoryChanged() ? "true" : "false") << "\n";
528 2540 : oss << " data() = ";
529 4988 : for (std::size_t i = 0; i < data().size(); ++i)
530 4896 : oss << "\n '" << _study.getRayDataName(i) << "' = " << data(i);
531 2540 : oss << "\n";
532 2540 : oss << " auxData() = ";
533 4988 : for (std::size_t i = 0; i < auxData().size(); ++i)
534 4896 : oss << "\n '" << _study.getRayAuxDataName(i) << "' = " << auxData(i);
535 2540 : oss << "\n";
536 :
537 2540 : return oss.str();
538 2540 : }
539 :
540 : namespace libMesh
541 : {
542 : namespace Parallel
543 : {
544 :
545 : unsigned int
546 1551285 : Packing<std::shared_ptr<Ray>>::size(const std::size_t data_size, const std::size_t aux_data_size)
547 : {
548 : // Current incoming side, end_set, processor crossings, intersections, trajectory
549 : // changes (packed into as few buffer_type as possible: 5 values stored as 2 Reals)
550 : constexpr unsigned int mixed_size = RayTracingPackingUtils::
551 : mixedPackSize<buffer_type, unsigned short, bool, unsigned int, unsigned int, unsigned int>();
552 : mooseAssert(mixed_size == 2, "Mixed size should be 2");
553 :
554 : // First value: size of data, size of aux data, id, current point (3 values), direction (3
555 : // values), current element, distance, max distance
556 : // Second value: mixed size (see above)
557 : auto size = 12 + mixed_size;
558 :
559 : #ifdef SINGLE_PRECISION_RAY
560 : if (data_size)
561 : size += RayTracingPackingUtils::reinterpretCopySize<RayData, buffer_type>(data_size);
562 : if (aux_data_size)
563 : size += RayTracingPackingUtils::reinterpretCopySize<RayData, buffer_type>(aux_data_size);
564 : #else
565 1551285 : size += data_size + aux_data_size;
566 : #endif
567 :
568 1551285 : return size;
569 : }
570 :
571 : unsigned int
572 519125 : Packing<std::shared_ptr<Ray>>::packed_size(typename std::vector<buffer_type>::const_iterator in)
573 : {
574 519125 : const std::size_t data_size = static_cast<std::size_t>(*in++);
575 519125 : const std::size_t aux_data_size = static_cast<std::size_t>(*in);
576 :
577 519125 : return size(data_size, aux_data_size);
578 : }
579 :
580 : unsigned int
581 1032160 : Packing<std::shared_ptr<Ray>>::packable_size(const std::shared_ptr<Ray> & ray, const void *)
582 : {
583 1032160 : return size(ray->data().size(), ray->auxData().size());
584 : }
585 :
586 : template <>
587 : std::shared_ptr<Ray>
588 519125 : Packing<std::shared_ptr<Ray>>::unpack(std::vector<buffer_type>::const_iterator in,
589 : ParallelStudy<std::shared_ptr<Ray>, Ray> * study)
590 : {
591 : mooseAssert(dynamic_cast<ParallelRayStudy *>(study), "Not a ParallelRayStudy");
592 : RayTracingStudy & ray_tracing_study = static_cast<ParallelRayStudy *>(study)->rayTracingStudy();
593 :
594 : // Grab the data size
595 519125 : const std::size_t data_size = static_cast<std::size_t>(*in++);
596 519125 : const std::size_t aux_data_size = static_cast<std::size_t>(*in++);
597 :
598 : // ID
599 : RayID id;
600 519125 : RayTracingPackingUtils::unpack(*in++, id);
601 :
602 : std::shared_ptr<Ray> ray =
603 : ray_tracing_study.acquireRayInternal(id,
604 : data_size,
605 : aux_data_size,
606 : /* reset = */ false,
607 519125 : RayTracingStudy::AcquireRayInternalKey());
608 :
609 : // Current Point
610 519125 : ray->_current_point(0) = *in++;
611 519125 : ray->_current_point(1) = *in++;
612 519125 : ray->_current_point(2) = *in++;
613 :
614 : // Direction
615 519125 : ray->_direction(0) = *in++;
616 519125 : ray->_direction(1) = *in++;
617 519125 : ray->_direction(2) = *in++;
618 :
619 : // Current Element
620 519125 : RayTracingPackingUtils::unpack(ray->_current_elem, *in++, &ray_tracing_study.meshBase());
621 :
622 : // Current incoming size, end set, processor crossings, intersections, trajectory changes
623 : // (unpacked from as few buffer_type as possible - 5 values from 2 Reals)
624 519125 : RayTracingPackingUtils::mixedUnpack<buffer_type>(in,
625 519125 : ray->_current_incoming_side,
626 519125 : ray->_end_set,
627 519125 : ray->_processor_crossings,
628 519125 : ray->_intersections,
629 519125 : ray->_trajectory_changes);
630 :
631 : // Distance
632 519125 : ray->_distance = *in++;
633 :
634 : // Max distance
635 519125 : ray->_max_distance = *in++;
636 :
637 : #ifdef SINGLE_PRECISION_RAY
638 : RayTracingPackingUtils::reinterpretUnpackCopy<buffer_type>(ray->_data, in);
639 : RayTracingPackingUtils::reinterpretUnpackCopy<buffer_type>(ray->_aux_data, in);
640 : #else
641 : // Copy out data
642 : RayTracingPackingUtils::unpackCopy(ray->_data, in);
643 : RayTracingPackingUtils::unpackCopy(ray->_aux_data, in);
644 : #endif
645 :
646 519125 : ray->_should_continue = true;
647 519125 : ray->_trajectory_changed = false;
648 :
649 519125 : return ray;
650 : }
651 :
652 : template <>
653 : void
654 519125 : Packing<std::shared_ptr<Ray>>::pack(const std::shared_ptr<Ray> & ray,
655 : std::back_insert_iterator<std::vector<buffer_type>> data_out,
656 : const ParallelStudy<std::shared_ptr<Ray>, Ray> * study)
657 : {
658 : mooseAssert(dynamic_cast<const ParallelRayStudy *>(study), "Not a ParallelRayStudy");
659 : const RayTracingStudy & ray_tracing_study =
660 : static_cast<const ParallelRayStudy *>(study)->rayTracingStudy();
661 : mooseAssert(&ray->study() == &ray_tracing_study, "Packing Ray for different study");
662 :
663 : // Storing the data size first makes it easy to verify and reserve space
664 519125 : data_out = static_cast<buffer_type>(ray->_data.size());
665 519125 : data_out = static_cast<buffer_type>(ray->_aux_data.size());
666 :
667 : // ID
668 519125 : data_out = RayTracingPackingUtils::pack<buffer_type>(ray->id());
669 :
670 : // Current Point
671 : data_out = ray->_current_point(0);
672 : data_out = ray->_current_point(1);
673 : data_out = ray->_current_point(2);
674 :
675 : // Direction
676 : data_out = ray->_direction(0);
677 : data_out = ray->_direction(1);
678 : data_out = ray->_direction(2);
679 :
680 : // Current element
681 : data_out =
682 1031478 : RayTracingPackingUtils::pack<buffer_type>(ray->_current_elem, &ray_tracing_study.meshBase());
683 :
684 : // Current incoming size, end set, processor crossings, intersections, trajectory changes
685 : // (packed into as few buffer_type as possible - 5 values into 2 Reals
686 519125 : RayTracingPackingUtils::mixedPack<buffer_type>(data_out,
687 519125 : ray->_current_incoming_side,
688 519125 : ray->_end_set,
689 519125 : ray->_processor_crossings,
690 519125 : ray->_intersections,
691 519125 : ray->_trajectory_changes);
692 :
693 : // Distance
694 519125 : data_out = ray->_distance;
695 : // Max distance
696 519125 : data_out = ray->_max_distance;
697 :
698 : // Copy out data
699 : #ifdef SINGLE_PRECISION_RAY
700 : RayTracingPackingUtils::reinterpretPackCopy<buffer_type>(ray->_data, data_out);
701 : RayTracingPackingUtils::reinterpretPackCopy<buffer_type>(ray->_aux_data, data_out);
702 : #else
703 : std::copy(ray->_data.begin(), ray->_data.end(), data_out);
704 : std::copy(ray->_aux_data.begin(), ray->_aux_data.end(), data_out);
705 : #endif
706 519125 : }
707 :
708 : } // namespace Parallel
709 :
710 : } // namespace libMesh
711 :
712 : void
713 888386 : dataStore(std::ostream & stream, std::shared_ptr<Ray> & ray, void * context)
714 : {
715 : mooseAssert(ray, "Null ray");
716 : mooseAssert(context, "Missing RayTracingStudy context");
717 : mooseAssert(static_cast<RayTracingStudy *>(context) == &ray->study(), "Different study");
718 :
719 888386 : storeHelper(stream, ray->_id, context);
720 888386 : storeHelper(stream, ray->_current_point, context);
721 888386 : storeHelper(stream, ray->_direction, context);
722 1776768 : auto current_elem_id = ray->currentElem() ? ray->currentElem()->id() : DofObject::invalid_id;
723 : storeHelper(stream, current_elem_id, context);
724 888386 : storeHelper(stream, ray->_current_incoming_side, context);
725 888386 : storeHelper(stream, ray->_trajectory_changed, context);
726 888386 : storeHelper(stream, ray->_end_set, context);
727 888386 : storeHelper(stream, ray->_should_continue, context);
728 888386 : storeHelper(stream, ray->_processor_crossings, context);
729 888386 : storeHelper(stream, ray->_intersections, context);
730 888386 : storeHelper(stream, ray->_trajectory_changes, context);
731 888386 : storeHelper(stream, ray->_distance, context);
732 888386 : storeHelper(stream, ray->_max_distance, context);
733 888386 : storeHelper(stream, ray->_data, context);
734 888386 : storeHelper(stream, ray->_aux_data, context);
735 888386 : }
736 :
737 : void
738 888348 : dataLoad(std::istream & stream, std::shared_ptr<Ray> & ray, void * context)
739 : {
740 : mooseAssert(context, "Missing RayTracingStudy context");
741 : RayTracingStudy * study = static_cast<RayTracingStudy *>(context);
742 :
743 : RayID id;
744 : loadHelper(stream, id, context);
745 888348 : ray = study->acquireRayInternal(id,
746 : /* data_size = */ 0,
747 : /* aux_data_size = */ 0,
748 : /* reset = */ true,
749 888348 : RayTracingStudy::AcquireRayInternalKey());
750 :
751 888348 : loadHelper(stream, ray->_current_point, context);
752 888348 : loadHelper(stream, ray->_direction, context);
753 : dof_id_type current_elem_id;
754 : loadHelper(stream, current_elem_id, context);
755 888348 : ray->_current_elem = study->meshBase().query_elem_ptr(current_elem_id);
756 888348 : loadHelper(stream, ray->_current_incoming_side, context);
757 888348 : loadHelper(stream, ray->_trajectory_changed, context);
758 888348 : loadHelper(stream, ray->_end_set, context);
759 888348 : loadHelper(stream, ray->_should_continue, context);
760 888348 : loadHelper(stream, ray->_processor_crossings, context);
761 888348 : loadHelper(stream, ray->_intersections, context);
762 888348 : loadHelper(stream, ray->_trajectory_changes, context);
763 888348 : loadHelper(stream, ray->_distance, context);
764 888348 : loadHelper(stream, ray->_max_distance, context);
765 888348 : loadHelper(stream, ray->_data, context);
766 888348 : loadHelper(stream, ray->_aux_data, context);
767 :
768 : if (ray->hasTraced())
769 : mooseAssert(!study->currentlyGenerating() && !study->currentlyPropagating(),
770 : "Cannot not load a Ray that has already traced during generation or propagation; "
771 : "reset the Ray first");
772 888348 : }
|