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 10797437 : 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 10797437 : const ConstructRayKey &)
28 10797437 : : _id(id),
29 10797437 : _current_point(RayTracingCommon::invalid_point),
30 10797437 : _direction(RayTracingCommon::invalid_point),
31 10797437 : _current_elem(nullptr),
32 10797437 : _current_incoming_side(RayTracingCommon::invalid_side),
33 10797437 : _end_set(false),
34 10797437 : _max_distance(std::numeric_limits<Real>::max()),
35 10797437 : _data(data_size, 0),
36 10797437 : _aux_data(aux_data_size, 0),
37 10797437 : _study(*study)
38 : {
39 10797437 : resetCountersInternal();
40 10797437 : }
41 :
42 : void
43 1202596 : 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 1202596 : _id = id;
51 1202596 : _data.resize(data_size, 0);
52 1202596 : _aux_data.resize(aux_data_size, 0);
53 :
54 1202596 : if (reset)
55 : {
56 11815 : resetCountersInternal();
57 11815 : _current_point = RayTracingCommon::invalid_point;
58 11815 : _direction = RayTracingCommon::invalid_point;
59 11815 : _current_elem = nullptr;
60 11815 : _current_incoming_side = RayTracingCommon::invalid_side;
61 11815 : _end_set = false;
62 11815 : _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 1202596 : }
69 :
70 3980340 : Ray::Ray(const Ray * const other, const ConstructRayKey & key)
71 3980340 : : Ray(&other->_study,
72 3980340 : other->_id,
73 : other->_data.size(),
74 : other->_aux_data.size(),
75 : /* reset = */ true,
76 3980340 : key)
77 : {
78 3980340 : other->errorIfTracing("Cannot copy Ray");
79 :
80 3980340 : if (!other->invalidCurrentPoint())
81 3980340 : setStart(other->_current_point, other->_current_elem, other->_current_incoming_side);
82 :
83 3980340 : if (other->_end_set)
84 2680594 : setStartingEndPoint(other->endPoint());
85 : else
86 : {
87 1299746 : if (!other->invalidDirection())
88 1299746 : setStartingDirection(other->_direction);
89 1299746 : if (other->maxDistanceSet())
90 28 : _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 3980340 : }
96 :
97 : void
98 55287 : Ray::reset(const Ray * const other, const ConstructRayKey &)
99 : {
100 55287 : other->errorIfTracing("Cannot copy Ray");
101 : mooseAssert(&other->_study == &_study, "Cannot copy Ray from different study");
102 :
103 55287 : clearStartingInfoInternal();
104 55287 : resetCountersInternal();
105 :
106 55287 : _id = other->_id;
107 :
108 55287 : if (!other->invalidCurrentPoint())
109 55287 : setStart(other->_current_point, other->_current_elem, other->_current_incoming_side);
110 :
111 55287 : if (other->_end_set)
112 29718 : setStartingEndPoint(other->endPoint());
113 : else
114 : {
115 25569 : if (!other->invalidDirection())
116 25569 : setStartingDirection(other->_direction);
117 25569 : if (other->maxDistanceSet())
118 8 : _max_distance = other->_max_distance;
119 : }
120 :
121 55287 : _data = other->_data;
122 55287 : _aux_data = other->_aux_data;
123 55287 : }
124 :
125 : bool
126 78900 : Ray::equalityHelper(const Ray & other, const bool equal) const
127 : {
128 78900 : if (this == &other)
129 : return equal;
130 :
131 74820 : if (_id != other._id)
132 4080 : return !equal;
133 70740 : if (invalidCurrentPoint() != other.invalidCurrentPoint() ||
134 66660 : !_current_point.absolute_fuzzy_equals(other._current_point))
135 4080 : return !equal;
136 66660 : if (invalidDirection() != other.invalidDirection() ||
137 62580 : !_direction.absolute_fuzzy_equals(other._direction))
138 4080 : return !equal;
139 62580 : if (_current_elem != other._current_elem)
140 4080 : return !equal;
141 58500 : if (_current_incoming_side != other._current_incoming_side)
142 4080 : return !equal;
143 54420 : if (_end_set != other._end_set)
144 4080 : return !equal;
145 50340 : if (_processor_crossings != other._processor_crossings)
146 4080 : return !equal;
147 46260 : if (_intersections != other._intersections)
148 4080 : return !equal;
149 42180 : if (_trajectory_changes != other._trajectory_changes)
150 4080 : return !equal;
151 38100 : if (_trajectory_changed != other._trajectory_changed)
152 4080 : return !equal;
153 34020 : if (!MooseUtils::absoluteFuzzyEqual(_distance, other._distance))
154 4080 : return !equal;
155 29940 : if (!MooseUtils::absoluteFuzzyEqual(_max_distance, other._max_distance))
156 4080 : return !equal;
157 25860 : if (_should_continue != other._should_continue)
158 4080 : return !equal;
159 21780 : if (_data.size() != other._data.size())
160 4080 : return !equal;
161 30724 : for (std::size_t i = 0; i < _data.size(); ++i)
162 17104 : if (!MooseUtils::absoluteFuzzyEqual(_data[i], other._data[i]))
163 4080 : return !equal;
164 13620 : if (_aux_data.size() != other._aux_data.size())
165 4080 : return !equal;
166 13804 : for (std::size_t i = 0; i < _aux_data.size(); ++i)
167 8344 : if (!MooseUtils::absoluteFuzzyEqual(_aux_data[i], other._aux_data[i]))
168 4080 : return !equal;
169 5460 : if (&_study != &other._study)
170 4080 : return !equal;
171 :
172 : return equal;
173 : }
174 :
175 : bool
176 1752 : Ray::atEnd() const
177 : {
178 1752 : 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 1750 : return MooseUtils::absoluteFuzzyEqual(_distance, _max_distance);
183 : }
184 :
185 : Point
186 2712062 : Ray::endPoint() const
187 : {
188 2712062 : 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 2712060 : return _current_point + (_max_distance - _distance) * _direction;
193 : }
194 :
195 : void
196 4063 : Ray::changeDirection(const Point & direction, const ChangeDirectionKey)
197 : {
198 4063 : 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 4061 : _direction = direction.unit();
202 4061 : _trajectory_changed = true;
203 4061 : }
204 :
205 : void
206 652 : Ray::changeStartDirection(const Point & start,
207 : const Point & direction,
208 : const ChangeStartDirectionKey)
209 : {
210 652 : 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 650 : _current_point = start;
214 650 : _direction = direction.unit();
215 650 : _trajectory_changed = true;
216 650 : }
217 :
218 : void
219 8142918 : Ray::setStart(const Point & starting_point,
220 : const Elem * starting_elem /* = nullptr */,
221 : const unsigned short starting_incoming_side /* = RayTracingCommon::invalid_side */)
222 : {
223 : mooseAssert(starting_point != RayTracingCommon::invalid_point, "Invalid point");
224 8142918 : errorIfTracing("Cannot use Ray::setStart()");
225 8142918 : if (!invalidCurrentPoint() && !_current_point.absolute_fuzzy_equals(starting_point))
226 2 : errorWhenInitializing("Starting point was already set via Ray::setStart() and is being changed."
227 : "\n\nYou may only call Ray::setStart() after it has been called once to"
228 : "\nchange the starting element and starting incoming side."
229 : "\n\nYou may also clear the starting info via Ray::clearStartingInfo().");
230 :
231 8142916 : _current_point = starting_point;
232 8142916 : _current_elem = starting_elem;
233 8142916 : _current_incoming_side = starting_incoming_side;
234 :
235 8142916 : if (_study.verifyRays())
236 : {
237 8142916 : if (!_study.looseBoundingBox().contains_point(starting_point))
238 2 : errorWhenInitializing("Mesh does not contain starting point.");
239 8142914 : if (starting_elem)
240 : {
241 : mooseAssert(_study.meshBase().query_elem_ptr(starting_elem->id()) == starting_elem,
242 : "Element is not owned by the mesh");
243 : if (!starting_elem->active())
244 2 : errorWhenInitializing("Starting element is not active.");
245 : }
246 :
247 : bool non_planar_start = false;
248 :
249 8142912 : if (!invalidCurrentIncomingSide())
250 : {
251 2338054 : if (!starting_elem)
252 2 : errorWhenInitializing("Starting incoming side is set but starting element is not set.");
253 2338052 : if (starting_elem->n_sides() < starting_incoming_side)
254 2 : errorWhenInitializing("Starting incoming side is not valid for its starting element.");
255 :
256 2338050 : non_planar_start = _study.sideIsNonPlanar(starting_elem, starting_incoming_side);
257 4676100 : if (!non_planar_start &&
258 4676100 : !starting_elem->build_side_ptr(starting_incoming_side)->contains_point(starting_point))
259 2 : errorWhenInitializing("Starting incoming side does not contain the starting point.");
260 : }
261 :
262 8142906 : if (starting_elem && !non_planar_start && !starting_elem->contains_point(starting_point))
263 2 : errorWhenInitializing("Starting element does not contain the starting point.");
264 : }
265 8142904 : }
266 :
267 : void
268 8092452 : Ray::setStartingDirection(const Point & starting_direction)
269 : {
270 8092452 : errorIfTracing("Cannot use Ray::setStartingDirection()");
271 8092452 : if (invalidCurrentPoint())
272 2 : errorWhenInitializing("Cannot use Ray::setStartingDirection() before Ray::setStart().");
273 8092450 : if (!invalidDirection())
274 2 : errorWhenInitializing(
275 : "Cannot change a Ray's starting direction using Ray::setStartingDirection()"
276 : "\nafter it has already been set."
277 : "\n\nYou must first clear the starting info using Ray::clearStartingInfo().");
278 8092448 : if (starting_direction.absolute_fuzzy_equals(Point(0, 0, 0)))
279 2 : errorWhenInitializing("Starting direction in Ray::setStartingDirection() is the zero vector.");
280 :
281 8092446 : _direction = starting_direction.unit();
282 8092446 : }
283 :
284 : void
285 5385145 : Ray::setStartingEndPoint(const Point & starting_end_point)
286 : {
287 5385145 : errorIfTracing("Cannot use Ray::setStartingEndPoint()");
288 5385145 : if (invalidCurrentPoint())
289 2 : errorWhenInitializing("Cannot use Ray::setStartingEndPoint() before Ray::setStart().");
290 5385143 : if (_current_point.absolute_fuzzy_equals(starting_end_point))
291 2 : errorWhenInitializing("End point is equal to the start point in Ray::setStartingEndPoint().");
292 5385141 : if (!invalidDirection())
293 2 : errorWhenInitializing("Cannot use Ray::setStartingEndPoint() after Ray::setStartingDirection()."
294 : "\n\nClear the starting information with Ray::clearStartingInfo().");
295 5385139 : if (maxDistanceSet())
296 2 : errorWhenInitializing(
297 : "Cannot use Ray::setStartingEndPoint() after Ray::setStartingMaxDistance().");
298 :
299 5385137 : if (_study.verifyRays() && !_study.looseBoundingBox().contains_point(starting_end_point))
300 2 : errorWhenInitializing("End point is not within the mesh for Ray::setStartingEndPoint().");
301 :
302 5385135 : Point difference = starting_end_point;
303 : difference -= _current_point;
304 5385135 : setStartingMaxDistance(difference.norm());
305 5385135 : setStartingDirection(difference);
306 5385135 : _end_set = true;
307 5385135 : }
308 :
309 : void
310 5386179 : Ray::setStartingMaxDistance(const Real starting_max_distance)
311 : {
312 5386179 : errorIfTracing("Cannot use Ray::setStartingMaxDistance()");
313 5386179 : if (invalidCurrentPoint())
314 2 : errorWhenInitializing("Cannot use Ray::setStartingMaxDistance() before Ray::setStart().");
315 5386177 : if (starting_max_distance <= 0)
316 2 : errorWhenInitializing("Starting max distance is <= 0 in Ray::setStartingMaxDistance().");
317 5386175 : if (_end_set)
318 2 : errorWhenInitializing(
319 : "Cannot use Ray::setStartingMaxDistance() after Ray::setStartingEndPoint().");
320 :
321 5386173 : _max_distance = starting_max_distance;
322 5386173 : }
323 :
324 : void
325 1581 : Ray::setStationary()
326 : {
327 1581 : errorIfTracing("Cannot use Ray::setStationary()");
328 1581 : if (invalidCurrentPoint())
329 2 : errorWhenInitializing("Cannot use Ray::setStationary() before Ray::setStart()");
330 1579 : if (_end_set)
331 2 : errorWhenInitializing("Cannot use Ray::setStationary() after Ray::setStartingEndPoint()");
332 1577 : if (!invalidDirection())
333 2 : errorWhenInitializing("Cannot use Ray::setStationary() with Ray::setStartingDirection()");
334 1575 : _max_distance = 0;
335 : mooseAssert(stationary(), "Stationary not set");
336 1575 : }
337 :
338 : void
339 93312 : Ray::invalidateStartingElem()
340 : {
341 186624 : errorIfTracing("Cannot use Ray::invalidateStartingElem()");
342 : invalidateCurrentElem();
343 93312 : }
344 :
345 : void
346 93312 : Ray::invalidateStartingIncomingSide()
347 : {
348 186624 : errorIfTracing("Cannot use Ray::invalidateStartingIncomingSide()");
349 : invalidateCurrentIncomingSide();
350 93312 : }
351 :
352 : void
353 956 : Ray::clearStartingInfo()
354 : {
355 956 : errorIfTracing("Cannot use Ray::clearStartingInfo()");
356 954 : clearStartingInfoInternal();
357 954 : }
358 :
359 : void
360 56241 : Ray::clearStartingInfoInternal()
361 : {
362 : invalidateCurrentPoint();
363 : invalidateCurrentElem();
364 : invalidateCurrentIncomingSide();
365 : invalidateDirection();
366 : invalidateMaxDistance();
367 56241 : _end_set = false;
368 56241 : }
369 :
370 : void
371 31231482 : Ray::errorIfTracing(const std::string & reason) const
372 : {
373 : if (hasTraced())
374 2 : mooseError(reason, " after it has started tracing\n\n", getInfo());
375 31231480 : }
376 :
377 : void
378 42 : Ray::errorWhenInitializing(const std::string & reason) const
379 : {
380 42 : mooseError("While initializing starting information for a Ray:\n\n", reason, "\n\n", getInfo());
381 : }
382 :
383 : void
384 956 : Ray::resetCounters()
385 : {
386 956 : if (!_study.currentlyGenerating())
387 2 : mooseError("Ray::resetCounters() can only be used during generateRays()\n\n", getInfo());
388 954 : resetCountersInternal();
389 954 : }
390 :
391 : void
392 10865493 : Ray::resetCountersInternal()
393 : {
394 10865493 : _processor_crossings = 0;
395 10865493 : _intersections = 0;
396 10865493 : _trajectory_changes = 0;
397 10865493 : _distance = 0;
398 10865493 : _trajectory_changed = false;
399 10865493 : _should_continue = true;
400 10865493 : }
401 :
402 : std::vector<RayData> &
403 4008202 : Ray::data()
404 : {
405 : mooseAssert(_data.size() == 0 || _data.size() == _study.rayDataSize(),
406 : "Ray data size of " + std::to_string(_data.size()) +
407 : " is not zero or the size required by the study of " +
408 : std::to_string(_study.rayDataSize()));
409 4008202 : _data.resize(_study.rayDataSize());
410 4008202 : return _data;
411 : }
412 :
413 : const std::vector<RayData> &
414 185349 : Ray::data() const
415 : {
416 : mooseAssert(_data.size() == 0 || _data.size() == _study.rayDataSize(),
417 : "Ray data size is not zero or the size required by study");
418 185349 : _data.resize(_study.rayDataSize());
419 185349 : return _data;
420 : }
421 :
422 : RayData &
423 1433389 : Ray::data(const std::size_t i)
424 : {
425 : mooseAssert(_study.rayDataSize() > i, "Accessing Ray data out of range");
426 1433389 : return data()[i];
427 : }
428 :
429 : const RayData &
430 177912 : Ray::data(const std::size_t i) const
431 : {
432 : mooseAssert(_study.rayDataSize() > i, "Accessing Ray data out of range");
433 177912 : return data()[i];
434 : }
435 :
436 : std::vector<RayData> &
437 3141024 : Ray::auxData()
438 : {
439 : mooseAssert(_aux_data.size() == 0 || _aux_data.size() == _study.rayAuxDataSize(),
440 : "Ray data size is not zero or the size required by study");
441 3141024 : _aux_data.resize(_study.rayAuxDataSize());
442 3141024 : return _aux_data;
443 : }
444 :
445 : const std::vector<RayData> &
446 2160069 : Ray::auxData() const
447 : {
448 : mooseAssert(_aux_data.size() == 0 || _aux_data.size() == _study.rayAuxDataSize(),
449 : "Ray data size is not zero or the size required by study");
450 2160069 : _aux_data.resize(_study.rayAuxDataSize());
451 2160069 : return _aux_data;
452 : }
453 :
454 : RayData &
455 566437 : Ray::auxData(const std::size_t i)
456 : {
457 : mooseAssert(_study.rayAuxDataSize() > i, "Accessing Ray data out of range");
458 566437 : return auxData()[i];
459 : }
460 :
461 : const RayData &
462 2152632 : Ray::auxData(const std::size_t i) const
463 : {
464 : mooseAssert(_study.rayAuxDataSize() > i, "Accessing Ray data out of range");
465 2152632 : return auxData()[i];
466 : }
467 :
468 : std::string
469 3765 : Ray::getInfo() const
470 : {
471 3765 : std::ostringstream oss;
472 :
473 3765 : oss << "Ray information with " << _study.type() << " '" << _study.name() << "' on pid "
474 3765 : << _study.comm().rank() << "\n";
475 7530 : oss << " this = " << this << "\n";
476 7530 : oss << " id() = " << id() << "\n";
477 3765 : if (_study.useRayRegistration() && !invalidID())
478 74 : oss << " _study.registeredRayName(id()) = " << _study.registeredRayName(id()) << "\n";
479 3765 : oss << " currentPoint() = ";
480 3765 : if (invalidCurrentPoint())
481 12 : oss << "invalid point\n";
482 : else
483 3753 : oss << currentPoint() << "\n";
484 3765 : oss << " direction() = ";
485 3765 : if (invalidDirection())
486 36 : oss << "invalid point\n";
487 : else
488 3729 : oss << direction() << "\n";
489 3765 : oss << " currentIncomingSide() = ";
490 3765 : if (invalidCurrentIncomingSide())
491 272 : oss << "invalid side\n";
492 : else
493 3493 : oss << currentIncomingSide() << "\n";
494 5782 : oss << " endSet() = " << (endSet() ? "true" : "false") << "\n";
495 3765 : if (endSet())
496 : {
497 3496 : oss << " endPoint() = " << endPoint() << "\n";
498 1762 : oss << " atEnd() = " << (atEnd() ? "true" : "false") << "\n";
499 : }
500 7530 : oss << " distance() = " << distance() << "\n";
501 7530 : oss << " maxDistance() = " << maxDistance() << "\n";
502 3765 : if (currentElem())
503 : {
504 7490 : oss << " currentElem()->id() = " << currentElem()->id() << "\n";
505 7490 : oss << " currentElem()->processor_id() = " << currentElem()->processor_id() << "\n";
506 : }
507 : else
508 20 : oss << " currentElem()->id() = invalid\n";
509 7530 : oss << " processorCrossings() = " << processorCrossings() << "\n";
510 7530 : oss << " intersections() = " << intersections() << "\n";
511 7530 : oss << " trajectoryChanges() = " << trajectoryChanges() << "\n";
512 7447 : oss << " shouldContinue() = " << (shouldContinue() ? "true" : "false") << "\n";
513 7526 : oss << " trajectoryChanged() = " << (trajectoryChanged() ? "true" : "false") << "\n";
514 3765 : oss << " data() = ";
515 7437 : for (std::size_t i = 0; i < data().size(); ++i)
516 7344 : oss << "\n '" << _study.getRayDataName(i) << "' = " << data(i);
517 3765 : oss << "\n";
518 3765 : oss << " auxData() = ";
519 7437 : for (std::size_t i = 0; i < auxData().size(); ++i)
520 7344 : oss << "\n '" << _study.getRayAuxDataName(i) << "' = " << auxData(i);
521 3765 : oss << "\n";
522 :
523 3765 : return oss.str();
524 3765 : }
525 :
526 : namespace libMesh
527 : {
528 : namespace Parallel
529 : {
530 :
531 : unsigned int
532 3811054 : Packing<std::shared_ptr<Ray>>::size(const std::size_t data_size, const std::size_t aux_data_size)
533 : {
534 : // Current incoming side, end_set, processor crossings, intersections, trajectory
535 : // changes (packed into as few buffer_type as possible: 5 values stored as 2 Reals)
536 : constexpr unsigned int mixed_size = RayTracingPackingUtils::
537 : mixedPackSize<buffer_type, unsigned short, bool, unsigned int, unsigned int, unsigned int>();
538 : mooseAssert(mixed_size == 2, "Mixed size should be 2");
539 :
540 : // First value: size of data, size of aux data, id, current point (3 values), direction (3
541 : // values), current element, distance, max distance
542 : // Second value: mixed size (see above)
543 : auto size = 12 + mixed_size;
544 :
545 : #ifdef SINGLE_PRECISION_RAY
546 : if (data_size)
547 : size += RayTracingPackingUtils::reinterpretCopySize<RayData, buffer_type>(data_size);
548 : if (aux_data_size)
549 : size += RayTracingPackingUtils::reinterpretCopySize<RayData, buffer_type>(aux_data_size);
550 : #else
551 3811054 : size += data_size + aux_data_size;
552 : #endif
553 :
554 3811054 : return size;
555 : }
556 :
557 : unsigned int
558 1275174 : Packing<std::shared_ptr<Ray>>::packed_size(typename std::vector<buffer_type>::const_iterator in)
559 : {
560 1275174 : const std::size_t data_size = static_cast<std::size_t>(*in++);
561 1275174 : const std::size_t aux_data_size = static_cast<std::size_t>(*in);
562 :
563 1275174 : return size(data_size, aux_data_size);
564 : }
565 :
566 : unsigned int
567 2535880 : Packing<std::shared_ptr<Ray>>::packable_size(const std::shared_ptr<Ray> & ray, const void *)
568 : {
569 2535880 : return size(ray->data().size(), ray->auxData().size());
570 : }
571 :
572 : template <>
573 : std::shared_ptr<Ray>
574 1275174 : Packing<std::shared_ptr<Ray>>::unpack(std::vector<buffer_type>::const_iterator in,
575 : ParallelStudy<std::shared_ptr<Ray>, Ray> * study)
576 : {
577 : mooseAssert(dynamic_cast<ParallelRayStudy *>(study), "Not a ParallelRayStudy");
578 : RayTracingStudy & ray_tracing_study = static_cast<ParallelRayStudy *>(study)->rayTracingStudy();
579 :
580 : // Grab the data size
581 1275174 : const std::size_t data_size = static_cast<std::size_t>(*in++);
582 1275174 : const std::size_t aux_data_size = static_cast<std::size_t>(*in++);
583 :
584 : // ID
585 : RayID id;
586 1275174 : RayTracingPackingUtils::unpack(*in++, id);
587 :
588 : std::shared_ptr<Ray> ray =
589 : ray_tracing_study.acquireRayInternal(id,
590 : data_size,
591 : aux_data_size,
592 : /* reset = */ false,
593 1275174 : RayTracingStudy::AcquireRayInternalKey());
594 :
595 : // Current Point
596 1275174 : ray->_current_point(0) = *in++;
597 1275174 : ray->_current_point(1) = *in++;
598 1275174 : ray->_current_point(2) = *in++;
599 :
600 : // Direction
601 1275174 : ray->_direction(0) = *in++;
602 1275174 : ray->_direction(1) = *in++;
603 1275174 : ray->_direction(2) = *in++;
604 :
605 : // Current Element
606 1275174 : RayTracingPackingUtils::unpack(ray->_current_elem, *in++, &ray_tracing_study.meshBase());
607 :
608 : // Current incoming size, end set, processor crossings, intersections, trajectory changes
609 : // (unpacked from as few buffer_type as possible - 5 values from 2 Reals)
610 1275174 : RayTracingPackingUtils::mixedUnpack<buffer_type>(in,
611 1275174 : ray->_current_incoming_side,
612 1275174 : ray->_end_set,
613 1275174 : ray->_processor_crossings,
614 1275174 : ray->_intersections,
615 1275174 : ray->_trajectory_changes);
616 :
617 : // Distance
618 1275174 : ray->_distance = *in++;
619 :
620 : // Max distance
621 1275174 : ray->_max_distance = *in++;
622 :
623 : #ifdef SINGLE_PRECISION_RAY
624 : RayTracingPackingUtils::reinterpretUnpackCopy<buffer_type>(ray->_data, in);
625 : RayTracingPackingUtils::reinterpretUnpackCopy<buffer_type>(ray->_aux_data, in);
626 : #else
627 : // Copy out data
628 : RayTracingPackingUtils::unpackCopy(ray->_data, in);
629 : RayTracingPackingUtils::unpackCopy(ray->_aux_data, in);
630 : #endif
631 :
632 1275174 : ray->_should_continue = true;
633 1275174 : ray->_trajectory_changed = false;
634 :
635 1275174 : return ray;
636 : }
637 :
638 : template <>
639 : void
640 1275174 : Packing<std::shared_ptr<Ray>>::pack(const std::shared_ptr<Ray> & ray,
641 : std::back_insert_iterator<std::vector<buffer_type>> data_out,
642 : const ParallelStudy<std::shared_ptr<Ray>, Ray> * study)
643 : {
644 : mooseAssert(dynamic_cast<const ParallelRayStudy *>(study), "Not a ParallelRayStudy");
645 : const RayTracingStudy & ray_tracing_study =
646 : static_cast<const ParallelRayStudy *>(study)->rayTracingStudy();
647 : mooseAssert(&ray->study() == &ray_tracing_study, "Packing Ray for different study");
648 :
649 : // Storing the data size first makes it easy to verify and reserve space
650 1275174 : data_out = static_cast<buffer_type>(ray->_data.size());
651 1275174 : data_out = static_cast<buffer_type>(ray->_aux_data.size());
652 :
653 : // ID
654 1275174 : data_out = RayTracingPackingUtils::pack<buffer_type>(ray->id());
655 :
656 : // Current Point
657 : data_out = ray->_current_point(0);
658 : data_out = ray->_current_point(1);
659 : data_out = ray->_current_point(2);
660 :
661 : // Direction
662 : data_out = ray->_direction(0);
663 : data_out = ray->_direction(1);
664 : data_out = ray->_direction(2);
665 :
666 : // Current element
667 : data_out =
668 2534500 : RayTracingPackingUtils::pack<buffer_type>(ray->_current_elem, &ray_tracing_study.meshBase());
669 :
670 : // Current incoming size, end set, processor crossings, intersections, trajectory changes
671 : // (packed into as few buffer_type as possible - 5 values into 2 Reals
672 1275174 : RayTracingPackingUtils::mixedPack<buffer_type>(data_out,
673 1275174 : ray->_current_incoming_side,
674 1275174 : ray->_end_set,
675 1275174 : ray->_processor_crossings,
676 1275174 : ray->_intersections,
677 1275174 : ray->_trajectory_changes);
678 :
679 : // Distance
680 1275174 : data_out = ray->_distance;
681 : // Max distance
682 1275174 : data_out = ray->_max_distance;
683 :
684 : // Copy out data
685 : #ifdef SINGLE_PRECISION_RAY
686 : RayTracingPackingUtils::reinterpretPackCopy<buffer_type>(ray->_data, data_out);
687 : RayTracingPackingUtils::reinterpretPackCopy<buffer_type>(ray->_aux_data, data_out);
688 : #else
689 : std::copy(ray->_data.begin(), ray->_data.end(), data_out);
690 : std::copy(ray->_aux_data.begin(), ray->_aux_data.end(), data_out);
691 : #endif
692 1275174 : }
693 :
694 : } // namespace Parallel
695 :
696 : } // namespace libMesh
697 :
698 : void
699 2650416 : dataStore(std::ostream & stream, std::shared_ptr<Ray> & ray, void * context)
700 : {
701 : mooseAssert(ray, "Null ray");
702 : mooseAssert(context, "Missing RayTracingStudy context");
703 : mooseAssert(static_cast<RayTracingStudy *>(context) == &ray->study(), "Different study");
704 :
705 2650416 : storeHelper(stream, ray->_id, context);
706 2650416 : storeHelper(stream, ray->_current_point, context);
707 2650416 : storeHelper(stream, ray->_direction, context);
708 5300394 : auto current_elem_id = ray->currentElem() ? ray->currentElem()->id() : DofObject::invalid_id;
709 : storeHelper(stream, current_elem_id, context);
710 2650416 : storeHelper(stream, ray->_current_incoming_side, context);
711 2650416 : storeHelper(stream, ray->_end_set, context);
712 2650416 : storeHelper(stream, ray->_processor_crossings, context);
713 2650416 : storeHelper(stream, ray->_intersections, context);
714 2650416 : storeHelper(stream, ray->_trajectory_changes, context);
715 2650416 : storeHelper(stream, ray->_trajectory_changed, context);
716 2650416 : storeHelper(stream, ray->_distance, context);
717 2650416 : storeHelper(stream, ray->_max_distance, context);
718 2650416 : storeHelper(stream, ray->_should_continue, context);
719 2650416 : storeHelper(stream, ray->_data, context);
720 2650416 : storeHelper(stream, ray->_aux_data, context);
721 2650416 : }
722 :
723 : void
724 2650323 : dataLoad(std::istream & stream, std::shared_ptr<Ray> & ray, void * context)
725 : {
726 : mooseAssert(context, "Missing RayTracingStudy context");
727 : RayTracingStudy * study = static_cast<RayTracingStudy *>(context);
728 :
729 : RayID id;
730 : loadHelper(stream, id, context);
731 2650323 : ray = study->acquireRayInternal(id,
732 : /* data_size = */ 0,
733 : /* aux_data_size = */ 0,
734 : /* reset = */ true,
735 2650323 : RayTracingStudy::AcquireRayInternalKey());
736 :
737 2650323 : loadHelper(stream, ray->_current_point, context);
738 2650323 : loadHelper(stream, ray->_direction, context);
739 : dof_id_type current_elem_id;
740 : loadHelper(stream, current_elem_id, context);
741 2650323 : ray->_current_elem = study->meshBase().query_elem_ptr(current_elem_id);
742 2650323 : loadHelper(stream, ray->_current_incoming_side, context);
743 2650323 : loadHelper(stream, ray->_end_set, context);
744 2650323 : loadHelper(stream, ray->_processor_crossings, context);
745 2650323 : loadHelper(stream, ray->_intersections, context);
746 2650323 : loadHelper(stream, ray->_trajectory_changes, context);
747 2650323 : loadHelper(stream, ray->_trajectory_changed, context);
748 2650323 : loadHelper(stream, ray->_distance, context);
749 2650323 : loadHelper(stream, ray->_max_distance, context);
750 2650323 : loadHelper(stream, ray->_should_continue, context);
751 2650323 : loadHelper(stream, ray->_data, context);
752 2650323 : loadHelper(stream, ray->_aux_data, context);
753 :
754 : if (ray->hasTraced())
755 : mooseAssert(!study->currentlyGenerating() && !study->currentlyPropagating(),
756 : "Cannot not load a Ray that has already traced during generation or propagation; "
757 : "reset the Ray first");
758 2650323 : }
|