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 : #pragma once
11 :
12 : // MOOSE includes
13 : #include "ADReal.h"
14 : #include "MooseTypes.h"
15 : #include "HashMap.h"
16 : #include "MooseError.h"
17 : #include "RankTwoTensor.h"
18 : #include "RankThreeTensor.h"
19 : #include "RankFourTensor.h"
20 : #include "ColumnMajorMatrix.h"
21 : #include "UniqueStorage.h"
22 : #include "TwoVector.h"
23 :
24 : #include "libmesh/parallel.h"
25 : #include "libmesh/parameters.h"
26 : #include "libmesh/numeric_vector.h"
27 :
28 : #include "LibtorchUtils.h"
29 :
30 : #ifdef LIBMESH_HAVE_CXX11_TYPE_TRAITS
31 : #include <type_traits>
32 : #endif
33 :
34 : // C++ includes
35 : #include <string>
36 : #include <vector>
37 : #include <list>
38 : #include <iostream>
39 : #include <map>
40 : #include <unordered_map>
41 : #include <unordered_set>
42 : #include <memory>
43 : #include <optional>
44 :
45 : namespace libMesh
46 : {
47 : template <typename T>
48 : class DenseMatrix;
49 : template <typename T>
50 : class DenseVector;
51 : template <typename T>
52 : class VectorValue;
53 : template <typename T>
54 : class TensorValue;
55 : class Elem;
56 : class FEType;
57 : class Point;
58 : }
59 :
60 : #ifdef MOOSE_MFEM_ENABLED
61 : namespace Moose::MFEM
62 : {
63 : struct SolutionState
64 : {
65 : };
66 : }
67 : #endif
68 :
69 : /**
70 : * Scalar helper routine
71 : */
72 : template <typename P>
73 : inline void storeHelper(std::ostream & stream, P & data, void * context);
74 :
75 : /**
76 : * Vector helper routine
77 : */
78 : template <typename P>
79 : inline void storeHelper(std::ostream & stream, std::vector<P> & data, void * context);
80 :
81 : /**
82 : * Shared pointer helper routine
83 : */
84 : template <typename P>
85 : inline void storeHelper(std::ostream & stream, std::shared_ptr<P> & data, void * context);
86 :
87 : /**
88 : * Unique pointer helper routine
89 : */
90 : template <typename P>
91 : inline void storeHelper(std::ostream & stream, std::unique_ptr<P> & data, void * context);
92 :
93 : /**
94 : * Set helper routine
95 : */
96 : template <typename P>
97 : inline void storeHelper(std::ostream & stream, std::set<P> & data, void * context);
98 :
99 : /**
100 : * Map helper routine
101 : */
102 : template <typename P, typename Q>
103 : inline void storeHelper(std::ostream & stream, std::map<P, Q> & data, void * context);
104 :
105 : /**
106 : * Unordered_map helper routine
107 : */
108 : template <typename P, typename Q>
109 : inline void storeHelper(std::ostream & stream, std::unordered_map<P, Q> & data, void * context);
110 :
111 : /**
112 : * Optional helper routine
113 : */
114 : template <typename P>
115 : inline void storeHelper(std::ostream & stream, std::optional<P> & data, void * context);
116 :
117 : /**
118 : * HashMap helper routine
119 : */
120 : template <typename P, typename Q>
121 : inline void storeHelper(std::ostream & stream, HashMap<P, Q> & data, void * context);
122 :
123 : /**
124 : * UniqueStorage helper routine
125 : */
126 : template <typename T>
127 : inline void storeHelper(std::ostream & stream, UniqueStorage<T> & data, void * context);
128 :
129 : /**
130 : * Scalar helper routine
131 : */
132 : template <typename P>
133 : inline void loadHelper(std::istream & stream, P & data, void * context);
134 :
135 : /**
136 : * Vector helper routine
137 : */
138 : template <typename P>
139 : inline void loadHelper(std::istream & stream, std::vector<P> & data, void * context);
140 :
141 : /**
142 : * Shared Pointer helper routine
143 : */
144 : template <typename P>
145 : inline void loadHelper(std::istream & stream, std::shared_ptr<P> & data, void * context);
146 :
147 : /**
148 : * Unique Pointer helper routine
149 : */
150 : template <typename P>
151 : inline void loadHelper(std::istream & stream, std::unique_ptr<P> & data, void * context);
152 :
153 : /**
154 : * Set helper routine
155 : */
156 : template <typename P>
157 : inline void loadHelper(std::istream & stream, std::set<P> & data, void * context);
158 :
159 : /**
160 : * Map helper routine
161 : */
162 : template <typename P, typename Q>
163 : inline void loadHelper(std::istream & stream, std::map<P, Q> & data, void * context);
164 :
165 : /**
166 : * Unordered_map helper routine
167 : */
168 : template <typename P, typename Q>
169 : inline void loadHelper(std::istream & stream, std::unordered_map<P, Q> & data, void * context);
170 :
171 : /**
172 : * Optional helper routine
173 : */
174 : template <typename P>
175 : inline void loadHelper(std::istream & stream, std::optional<P> & data, void * context);
176 :
177 : /**
178 : * Hashmap helper routine
179 : */
180 : template <typename P, typename Q>
181 : inline void loadHelper(std::istream & stream, HashMap<P, Q> & data, void * context);
182 :
183 : /**
184 : * UniqueStorage helper routine
185 : */
186 : template <typename T>
187 : inline void loadHelper(std::istream & stream, UniqueStorage<T> & data, void * context);
188 :
189 : template <typename T>
190 : inline void dataStore(std::ostream & stream, T & v, void * /*context*/);
191 :
192 : // DO NOT MODIFY THE NEXT LINE - It is used by MOOSEDocs
193 : // *************** Global Store Declarations *****************
194 : template <typename T>
195 : inline void
196 62920613 : dataStore(std::ostream & stream, T & v, void * /*context*/)
197 : {
198 : #ifdef LIBMESH_HAVE_CXX11_TYPE_TRAITS
199 : static_assert(std::is_polymorphic<T>::value == false,
200 : "Cannot serialize a class that has virtual "
201 : "members!\nWrite a custom dataStore() "
202 : "template specialization!\n\n");
203 : static_assert(std::is_trivially_copyable<T>::value,
204 : "Cannot serialize a class that is not trivially copyable!\nWrite a custom "
205 : "dataStore() template specialization!\n\n");
206 : #endif
207 :
208 62920613 : stream.write((char *)&v, sizeof(v));
209 : mooseAssert(!stream.bad(), "Failed to store");
210 62920613 : }
211 :
212 : template <typename T>
213 : inline void
214 3 : dataStore(std::ostream & /*stream*/, T *& /*v*/, void * /*context*/)
215 : {
216 3 : mooseError("Attempting to store a raw pointer type: \"",
217 : libMesh::demangle(typeid(T).name()),
218 : " *\" as restartable data!\nWrite a custom dataStore() template specialization!\n\n");
219 : }
220 :
221 : void dataStore(std::ostream & stream, Point & p, void * context);
222 :
223 : template <typename T, typename U>
224 : inline void
225 1148829 : dataStore(std::ostream & stream, std::pair<T, U> & p, void * context)
226 : {
227 1148829 : storeHelper(stream, p.first, context);
228 1148829 : storeHelper(stream, p.second, context);
229 1148829 : }
230 :
231 : template <typename T>
232 : inline void
233 1532028 : dataStore(std::ostream & stream, std::vector<T> & v, void * context)
234 : {
235 : // First store the size of the vector
236 1532028 : unsigned int size = v.size();
237 1532028 : dataStore(stream, size, nullptr);
238 :
239 13501960 : for (unsigned int i = 0; i < size; i++)
240 11969932 : storeHelper(stream, v[i], context);
241 1532028 : }
242 :
243 : template <typename T>
244 : inline void
245 : dataStore(std::ostream & stream, std::shared_ptr<T> & v, void * context)
246 : {
247 : T * tmp = v.get();
248 :
249 : storeHelper(stream, tmp, context);
250 : }
251 :
252 : template <typename T>
253 : inline void
254 : dataStore(std::ostream & stream, std::unique_ptr<T> & v, void * context)
255 : {
256 : T * tmp = v.get();
257 :
258 : storeHelper(stream, tmp, context);
259 : }
260 :
261 : template <typename T>
262 : inline void
263 10941 : dataStore(std::ostream & stream, std::set<T> & s, void * context)
264 : {
265 : // First store the size of the set
266 10941 : unsigned int size = s.size();
267 10941 : dataStore(stream, size, nullptr);
268 :
269 10941 : typename std::set<T>::iterator it = s.begin();
270 10941 : typename std::set<T>::iterator end = s.end();
271 :
272 20308 : for (; it != end; ++it)
273 : {
274 9367 : T & x = const_cast<T &>(*it);
275 9367 : storeHelper(stream, x, context);
276 : }
277 10941 : }
278 :
279 : template <typename T>
280 : inline void
281 0 : dataStore(std::ostream & stream, std::list<T> & l, void * context)
282 : {
283 : // First store the size of the set
284 0 : unsigned int size = l.size();
285 0 : dataStore(stream, size, nullptr);
286 :
287 0 : typename std::list<T>::iterator it = l.begin();
288 0 : typename std::list<T>::iterator end = l.end();
289 :
290 0 : for (; it != end; ++it)
291 : {
292 0 : T & x = const_cast<T &>(*it);
293 0 : storeHelper(stream, x, context);
294 : }
295 0 : }
296 :
297 : template <typename T>
298 : inline void
299 46779 : dataStore(std::ostream & stream, std::deque<T> & l, void * context)
300 : {
301 : // First store the size of the container
302 46779 : unsigned int size = l.size();
303 46779 : dataStore(stream, size, nullptr);
304 :
305 46779 : typename std::deque<T>::iterator it = l.begin();
306 46779 : typename std::deque<T>::iterator end = l.end();
307 :
308 7325514 : for (; it != end; ++it)
309 : {
310 7278735 : T & x = const_cast<T &>(*it);
311 7278735 : storeHelper(stream, x, context);
312 : }
313 46779 : }
314 :
315 : template <typename T, typename U>
316 : inline void
317 2216918 : dataStore(std::ostream & stream, std::map<T, U> & m, void * context)
318 : {
319 : // First store the size of the map
320 2216918 : unsigned int size = m.size();
321 2216918 : dataStore(stream, size, nullptr);
322 :
323 2216918 : typename std::map<T, U>::iterator it = m.begin();
324 2216918 : typename std::map<T, U>::iterator end = m.end();
325 :
326 4977805 : for (; it != end; ++it)
327 : {
328 2760887 : T & key = const_cast<T &>(it->first);
329 :
330 2760887 : storeHelper(stream, key, context);
331 :
332 2760887 : storeHelper(stream, it->second, context);
333 : }
334 2216918 : }
335 :
336 : template <typename T, typename U>
337 : inline void
338 50 : dataStore(std::ostream & stream, std::unordered_map<T, U> & m, void * context)
339 : {
340 : // First store the size of the map
341 50 : unsigned int size = m.size();
342 50 : dataStore(stream, size, nullptr);
343 :
344 50 : typename std::unordered_map<T, U>::iterator it = m.begin();
345 50 : typename std::unordered_map<T, U>::iterator end = m.end();
346 :
347 100 : for (; it != end; ++it)
348 : {
349 50 : T & key = const_cast<T &>(it->first);
350 :
351 50 : storeHelper(stream, key, context);
352 :
353 50 : storeHelper(stream, it->second, context);
354 : }
355 50 : }
356 :
357 : template <typename T>
358 : inline void
359 83889 : dataStore(std::ostream & stream, std::unordered_set<T> & s, void * context)
360 : {
361 : // First store the size of the set
362 83889 : std::size_t size = s.size();
363 83889 : dataStore(stream, size, nullptr);
364 :
365 83893 : for (auto & element : s)
366 4 : dataStore(stream, element, context);
367 83889 : }
368 :
369 : template <typename T>
370 : inline void
371 8277 : dataStore(std::ostream & stream, std::optional<T> & m, void * context)
372 : {
373 8277 : bool has_value = m.has_value();
374 8277 : dataStore(stream, has_value, nullptr);
375 :
376 8277 : if (has_value)
377 8125 : storeHelper(stream, *m, context);
378 8277 : }
379 :
380 : template <typename T, typename U>
381 : inline void
382 : dataStore(std::ostream & stream, HashMap<T, U> & m, void * context)
383 : {
384 : // First store the size of the map
385 : unsigned int size = m.size();
386 : dataStore(stream, size, nullptr);
387 :
388 : typename HashMap<T, U>::iterator it = m.begin();
389 : typename HashMap<T, U>::iterator end = m.end();
390 :
391 : for (; it != end; ++it)
392 : {
393 : T & key = const_cast<T &>(it->first);
394 :
395 : storeHelper(stream, key, context);
396 :
397 : storeHelper(stream, it->second, context);
398 : }
399 : }
400 :
401 : template <typename T, int Rows, int Cols>
402 : void
403 2 : dataStore(std::ostream & stream, Eigen::Matrix<T, Rows, Cols> & v, void * context)
404 : {
405 2 : auto m = cast_int<unsigned int>(v.rows());
406 2 : dataStore(stream, m, context);
407 2 : auto n = cast_int<unsigned int>(v.cols());
408 2 : dataStore(stream, n, context);
409 9 : for (const auto i : make_range(m))
410 18 : for (const auto j : make_range(n))
411 : {
412 11 : auto & r = v(i, j);
413 11 : dataStore(stream, r, context);
414 : }
415 2 : }
416 :
417 : template <typename T>
418 : void
419 : dataStore(std::ostream & stream, GenericTwoVector<T> & v, void * context)
420 : {
421 : dataStore(stream, static_cast<Eigen::Matrix<T, 2, 1> &>(v), context);
422 : }
423 :
424 : // Specializations (defined in .C)
425 : template <>
426 : void dataStore(std::ostream & stream, Real & v, void * context);
427 : template <>
428 : void dataStore(std::ostream & stream, std::string & v, void * context);
429 : template <>
430 : void dataStore(std::ostream & stream, VariableName & v, void * context);
431 : template <>
432 : void dataStore(std::ostream & stream, UserObjectName & v, void * context);
433 : template <>
434 : void dataStore(std::ostream & stream, bool & v, void * context);
435 : template <>
436 : void dataStore(std::ostream & stream, libMesh::FEType & v, void * context);
437 : // Vectors of bools are special
438 : // https://en.wikipedia.org/w/index.php?title=Sequence_container_(C%2B%2B)&oldid=767869909#Specialization_for_bool
439 : template <>
440 : void dataStore(std::ostream & stream, std::vector<bool> & v, void * context);
441 : template <>
442 : void dataStore(std::ostream & stream, const Elem *& e, void * context);
443 : template <>
444 : void dataStore(std::ostream & stream, const Node *& n, void * context);
445 : template <>
446 : void dataStore(std::ostream & stream, Elem *& e, void * context);
447 : template <>
448 : void dataStore(std::ostream & stream, Node *& n, void * context);
449 : template <>
450 : void dataStore(std::ostream & stream, std::stringstream & s, void * context);
451 : template <>
452 : void dataStore(std::ostream & stream, ADReal & dn, void * context);
453 : #ifdef MOOSE_LIBTORCH_ENABLED
454 : template <>
455 : void dataStore(std::ostream & stream, torch::Tensor & t, void * context);
456 : #endif
457 : template <>
458 : void dataStore(std::ostream & stream, libMesh::Parameters & p, void * context);
459 : #ifdef MOOSE_MFEM_ENABLED
460 : template <>
461 : void dataStore(std::ostream & stream, Moose::MFEM::SolutionState & state, void * context);
462 : #endif
463 :
464 : /**
465 : * Stores an owned numeric vector.
466 : *
467 : * This should be used in lieu of the NumericVector<Number> & implementation
468 : * when the vector may not necessarily be initialized yet on the loading of
469 : * the data. It stores the partitioning (total and local number of entries).
470 : *
471 : * Requirements: the unique_ptr must exist (cannot be null), the vector
472 : * cannot be ghosted, and the provided context must be the Communicator.
473 : */
474 : template <>
475 : void dataStore(std::ostream & stream,
476 : std::unique_ptr<libMesh::NumericVector<libMesh::Number>> & v,
477 : void * context);
478 :
479 : template <std::size_t N>
480 : inline void
481 0 : dataStore(std::ostream & stream, std::array<ADReal, N> & dn, void * context)
482 : {
483 0 : for (std::size_t i = 0; i < N; ++i)
484 0 : dataStore(stream, dn[i], context);
485 0 : }
486 :
487 : template <std::size_t N>
488 : inline void
489 0 : dataStore(std::ostream & stream, ADReal (&dn)[N], void * context)
490 : {
491 0 : for (std::size_t i = 0; i < N; ++i)
492 0 : dataStore(stream, dn[i], context);
493 0 : }
494 :
495 : template <typename T>
496 : void
497 10 : dataStore(std::ostream & stream, libMesh::NumericVector<T> & v, void * context)
498 : {
499 10 : v.close();
500 :
501 10 : numeric_index_type size = v.local_size();
502 :
503 984 : for (numeric_index_type i = v.first_local_index(); i < v.first_local_index() + size; i++)
504 : {
505 974 : T r = v(i);
506 974 : dataStore(stream, r, context);
507 : }
508 10 : }
509 :
510 : template <>
511 : void dataStore(std::ostream & stream, Vec & v, void * context);
512 :
513 : template <typename T>
514 : void
515 48 : dataStore(std::ostream & stream, DenseVector<T> & v, void * context)
516 : {
517 48 : unsigned int m = v.size();
518 48 : dataStore(stream, m, nullptr);
519 192 : for (unsigned int i = 0; i < v.size(); i++)
520 : {
521 144 : T r = v(i);
522 144 : dataStore(stream, r, context);
523 : }
524 48 : }
525 :
526 : template <typename T>
527 : void dataStore(std::ostream & stream, libMesh::TensorValue<T> & v, void * context);
528 :
529 : template <typename T>
530 : void dataStore(std::ostream & stream, libMesh::DenseMatrix<T> & v, void * context);
531 :
532 : template <typename T>
533 : void dataStore(std::ostream & stream, libMesh::VectorValue<T> & v, void * context);
534 :
535 : template <typename T>
536 : void
537 0 : dataStore(std::ostream & stream, RankTwoTensorTempl<T> & rtt, void * context)
538 : {
539 0 : dataStore(stream, rtt._coords, context);
540 0 : }
541 :
542 : template <typename T>
543 : void
544 0 : dataStore(std::ostream & stream, RankThreeTensorTempl<T> & rtt, void * context)
545 : {
546 0 : dataStore(stream, rtt._vals, context);
547 0 : }
548 :
549 : template <typename T>
550 : void
551 0 : dataStore(std::ostream & stream, RankFourTensorTempl<T> & rft, void * context)
552 : {
553 0 : dataStore(stream, rft._vals, context);
554 0 : }
555 :
556 : template <typename T>
557 : void
558 0 : dataStore(std::ostream & stream, SymmetricRankTwoTensorTempl<T> & srtt, void * context)
559 : {
560 0 : dataStore(stream, srtt._vals, context);
561 0 : }
562 :
563 : template <typename T>
564 : void
565 0 : dataStore(std::ostream & stream, SymmetricRankFourTensorTempl<T> & srft, void * context)
566 : {
567 0 : dataStore(stream, srft._vals, context);
568 0 : }
569 :
570 : template <typename T>
571 : void
572 : dataStore(std::ostream & stream, ColumnMajorMatrixTempl<T> & cmm, void * context)
573 : {
574 : dataStore(stream, cmm._values, context);
575 : }
576 :
577 : // DO NOT MODIFY THE NEXT LINE - It is used by MOOSEDocs
578 : // *************** Global Load Declarations *****************
579 : template <typename T>
580 : inline void
581 18531621 : dataLoad(std::istream & stream, T & v, void * /*context*/)
582 : {
583 18531621 : stream.read((char *)&v, sizeof(v));
584 : mooseAssert(!stream.bad(), "Failed to load");
585 18531621 : }
586 :
587 : template <typename T>
588 : void
589 4 : dataLoad(std::istream & /*stream*/, T *& /*v*/, void * /*context*/)
590 : {
591 4 : mooseError("Attempting to load a raw pointer type: \"",
592 : libMesh::demangle(typeid(T).name()),
593 : " *\" as restartable data!\nWrite a custom dataLoad() template specialization!\n\n");
594 : }
595 :
596 : template <typename T, typename U>
597 : inline void
598 30604 : dataLoad(std::istream & stream, std::pair<T, U> & p, void * context)
599 : {
600 30604 : loadHelper(stream, p.first, context);
601 30604 : loadHelper(stream, p.second, context);
602 30604 : }
603 :
604 : template <typename T>
605 : inline void
606 410449 : dataLoad(std::istream & stream, std::vector<T> & v, void * context)
607 : {
608 : // First read the size of the vector
609 410449 : unsigned int size = 0;
610 410449 : dataLoad(stream, size, nullptr);
611 :
612 410449 : v.resize(size);
613 :
614 6231852 : for (unsigned int i = 0; i < size; i++)
615 5821403 : loadHelper(stream, v[i], context);
616 410449 : }
617 :
618 : template <typename T>
619 : inline void
620 : dataLoad(std::istream & stream, std::shared_ptr<T> & v, void * context)
621 : {
622 : T * tmp = v.get();
623 :
624 : loadHelper(stream, tmp, context);
625 : }
626 :
627 : template <typename T>
628 : inline void
629 : dataLoad(std::istream & stream, std::unique_ptr<T> & v, void * context)
630 : {
631 : T * tmp = v.get();
632 :
633 : loadHelper(stream, tmp, context);
634 : }
635 :
636 : template <typename T>
637 : inline void
638 7068 : dataLoad(std::istream & stream, std::set<T> & s, void * context)
639 : {
640 : // First read the size of the set
641 7068 : unsigned int size = 0;
642 7068 : dataLoad(stream, size, nullptr);
643 :
644 14432 : for (unsigned int i = 0; i < size; i++)
645 : {
646 7228 : T data;
647 7364 : loadHelper(stream, data, context);
648 7364 : s.insert(std::move(data));
649 : }
650 7068 : }
651 :
652 : template <typename T>
653 : inline void
654 0 : dataLoad(std::istream & stream, std::list<T> & l, void * context)
655 : {
656 : // First read the size of the set
657 0 : unsigned int size = 0;
658 0 : dataLoad(stream, size, nullptr);
659 :
660 0 : for (unsigned int i = 0; i < size; i++)
661 : {
662 0 : T data;
663 0 : loadHelper(stream, data, context);
664 0 : l.push_back(std::move(data));
665 : }
666 0 : }
667 :
668 : template <typename T>
669 : inline void
670 : dataLoad(std::istream & stream, std::deque<T> & l, void * context)
671 : {
672 : // First read the size of the container
673 : unsigned int size = 0;
674 : dataLoad(stream, size, nullptr);
675 :
676 : for (unsigned int i = 0; i < size; i++)
677 : {
678 : T data;
679 : loadHelper(stream, data, context);
680 : l.push_back(std::move(data));
681 : }
682 : }
683 :
684 : template <typename T, typename U>
685 : inline void
686 317592 : dataLoad(std::istream & stream, std::map<T, U> & m, void * context)
687 : {
688 317592 : m.clear();
689 :
690 : // First read the size of the map
691 317592 : unsigned int size = 0;
692 317592 : dataLoad(stream, size, nullptr);
693 :
694 691686 : for (unsigned int i = 0; i < size; i++)
695 : {
696 360533 : T key;
697 374094 : loadHelper(stream, key, context);
698 :
699 374094 : U & value = m[key];
700 374094 : loadHelper(stream, value, context);
701 : }
702 317592 : }
703 :
704 : template <typename T, typename U>
705 : inline void
706 10 : dataLoad(std::istream & stream, std::unordered_map<T, U> & m, void * context)
707 : {
708 10 : m.clear();
709 :
710 : // First read the size of the map
711 10 : unsigned int size = 0;
712 10 : dataLoad(stream, size, nullptr);
713 :
714 20 : for (unsigned int i = 0; i < size; i++)
715 : {
716 : T key;
717 10 : loadHelper(stream, key, context);
718 :
719 10 : U & value = m[key];
720 10 : loadHelper(stream, value, context);
721 : }
722 10 : }
723 :
724 : template <typename T>
725 : inline void
726 22174 : dataLoad(std::istream & stream, std::unordered_set<T> & s, void * context)
727 : {
728 22174 : s.clear();
729 :
730 : // First read the size of the set
731 22174 : std::size_t size = 0;
732 22174 : dataLoad(stream, size, nullptr);
733 22174 : s.reserve(size);
734 :
735 22176 : for (std::size_t i = 0; i < size; i++)
736 : {
737 : T element;
738 2 : dataLoad(stream, element, context);
739 2 : s.insert(element);
740 : }
741 22174 : }
742 :
743 : template <typename T>
744 : inline void
745 6987 : dataLoad(std::istream & stream, std::optional<T> & m, void * context)
746 : {
747 : bool has_value;
748 6987 : dataLoad(stream, has_value, nullptr);
749 :
750 6987 : if (has_value)
751 : {
752 6837 : m = T{};
753 6837 : loadHelper(stream, *m, context);
754 : }
755 : else
756 150 : m.reset();
757 13824 : }
758 :
759 : template <typename T, typename U>
760 : inline void
761 : dataLoad(std::istream & stream, HashMap<T, U> & m, void * context)
762 : {
763 : // First read the size of the map
764 : unsigned int size = 0;
765 : dataLoad(stream, size, nullptr);
766 :
767 : for (unsigned int i = 0; i < size; i++)
768 : {
769 : T key;
770 : loadHelper(stream, key, context);
771 :
772 : U & value = m[key];
773 : loadHelper(stream, value, context);
774 : }
775 : }
776 :
777 : template <typename T, int Rows, int Cols>
778 : void
779 2 : dataLoad(std::istream & stream, Eigen::Matrix<T, Rows, Cols> & v, void * context)
780 : {
781 2 : unsigned int m = 0;
782 2 : dataLoad(stream, m, context);
783 2 : unsigned int n = 0;
784 2 : dataLoad(stream, n, context);
785 2 : v.resize(m, n);
786 9 : for (const auto i : make_range(m))
787 18 : for (const auto j : make_range(n))
788 : {
789 11 : T r{};
790 11 : dataLoad(stream, r, context);
791 11 : v(i, j) = r;
792 : }
793 2 : }
794 :
795 : template <typename T>
796 : void
797 : dataLoad(std::istream & stream, GenericTwoVector<T> & v, void * context)
798 : {
799 : dataLoad(stream, static_cast<Eigen::Matrix<T, 2, 1> &>(v), context);
800 : }
801 :
802 : // Specializations (defined in .C)
803 : template <>
804 : void dataLoad(std::istream & stream, Real & v, void * /*context*/);
805 : template <>
806 : void dataLoad(std::istream & stream, std::string & v, void * /*context*/);
807 : template <>
808 : void dataLoad(std::istream & stream, VariableName & v, void * /*context*/);
809 : template <>
810 : void dataLoad(std::istream & stream, UserObjectName & v, void * /*context*/);
811 : template <>
812 : void dataLoad(std::istream & stream, bool & v, void * /*context*/);
813 : template <>
814 : void dataLoad(std::istream & stream, libMesh::FEType & v, void * /*context*/);
815 : // Vectors of bools are special
816 : // https://en.wikipedia.org/w/index.php?title=Sequence_container_(C%2B%2B)&oldid=767869909#Specialization_for_bool
817 : template <>
818 : void dataLoad(std::istream & stream, std::vector<bool> & v, void * /*context*/);
819 : template <>
820 : void dataLoad(std::istream & stream, const Elem *& e, void * context);
821 : template <>
822 : void dataLoad(std::istream & stream, const Node *& e, void * context);
823 : template <>
824 : void dataLoad(std::istream & stream, Elem *& e, void * context);
825 : template <>
826 : void dataLoad(std::istream & stream, Node *& e, void * context);
827 : template <>
828 : void dataLoad(std::istream & stream, std::stringstream & s, void * context);
829 : template <>
830 : void dataLoad(std::istream & stream, ADReal & dn, void * context);
831 : #ifdef MOOSE_LIBTORCH_ENABLED
832 : template <>
833 : void dataLoad(std::istream & stream, torch::Tensor & t, void * context);
834 : #endif
835 : template <>
836 : void dataLoad(std::istream & stream, libMesh::Parameters & p, void * context);
837 : #ifdef MOOSE_MFEM_ENABLED
838 : template <>
839 : void dataLoad(std::istream & stream, Moose::MFEM::SolutionState & state, void * context);
840 : #endif
841 : /**
842 : * Loads an owned numeric vector.
843 : *
844 : * This is used in lieu of the NumericVector<double> & implementation when
845 : * the vector may not necessarily be initialized yet on the loading of the data.
846 : *
847 : * If \p is not null, it must have the same global and local sizes that it
848 : * was stored with. In this case, the data is simply filled into the vector.
849 : *
850 : * If \p is null, it will be constructed with the type (currently just a
851 : * PetscVector) stored and initialized with the global and local sizes stored.
852 : * The data will then be filled after initialization.
853 : *
854 : * Requirements: the vector cannot be ghosted, the provided context must be
855 : * the Communicator, and if \p v is initialized, it must have the same global
856 : * and local sizes that the vector was stored with.
857 : */
858 : template <>
859 : void dataLoad(std::istream & stream,
860 : std::unique_ptr<libMesh::NumericVector<libMesh::Number>> & v,
861 : void * context);
862 :
863 : template <std::size_t N>
864 : inline void
865 0 : dataLoad(std::istream & stream, std::array<ADReal, N> & dn, void * context)
866 : {
867 0 : for (std::size_t i = 0; i < N; ++i)
868 0 : dataLoad(stream, dn[i], context);
869 0 : }
870 :
871 : template <std::size_t N>
872 : inline void
873 0 : dataLoad(std::istream & stream, ADReal (&dn)[N], void * context)
874 : {
875 0 : for (std::size_t i = 0; i < N; ++i)
876 0 : dataLoad(stream, dn[i], context);
877 0 : }
878 :
879 : template <typename T>
880 : void
881 8 : dataLoad(std::istream & stream, libMesh::NumericVector<T> & v, void * context)
882 : {
883 8 : numeric_index_type size = v.local_size();
884 504 : for (numeric_index_type i = v.first_local_index(); i < v.first_local_index() + size; i++)
885 : {
886 496 : T r = 0;
887 496 : dataLoad(stream, r, context);
888 496 : v.set(i, r);
889 : }
890 8 : v.close();
891 8 : }
892 :
893 : template <>
894 : void dataLoad(std::istream & stream, Vec & v, void * context);
895 :
896 : template <typename T>
897 : void
898 68 : dataLoad(std::istream & stream, DenseVector<T> & v, void * context)
899 : {
900 68 : unsigned int n = 0;
901 68 : dataLoad(stream, n, nullptr);
902 68 : v.resize(n);
903 272 : for (unsigned int i = 0; i < n; i++)
904 : {
905 204 : T r = 0;
906 204 : dataLoad(stream, r, context);
907 204 : v(i) = r;
908 : }
909 68 : }
910 :
911 : template <typename T>
912 : void dataLoad(std::istream & stream, libMesh::TensorValue<T> & v, void * context);
913 :
914 : template <typename T>
915 : void dataLoad(std::istream & stream, libMesh::DenseMatrix<T> & v, void * context);
916 :
917 : template <typename T>
918 : void dataLoad(std::istream & stream, libMesh::VectorValue<T> & v, void * context);
919 :
920 : template <typename T>
921 : void
922 0 : dataLoad(std::istream & stream, RankTwoTensorTempl<T> & rtt, void * context)
923 : {
924 0 : dataLoad(stream, rtt._coords, context);
925 0 : }
926 :
927 : template <typename T>
928 : void
929 0 : dataLoad(std::istream & stream, RankThreeTensorTempl<T> & rtt, void * context)
930 : {
931 0 : dataLoad(stream, rtt._vals, context);
932 0 : }
933 :
934 : template <typename T>
935 : void
936 0 : dataLoad(std::istream & stream, RankFourTensorTempl<T> & rft, void * context)
937 : {
938 0 : dataLoad(stream, rft._vals, context);
939 0 : }
940 :
941 : template <typename T>
942 : void
943 0 : dataLoad(std::istream & stream, SymmetricRankTwoTensorTempl<T> & rtt, void * context)
944 : {
945 0 : dataLoad(stream, rtt._vals, context);
946 0 : }
947 :
948 : template <typename T>
949 : void
950 0 : dataLoad(std::istream & stream, SymmetricRankFourTensorTempl<T> & rft, void * context)
951 : {
952 0 : dataLoad(stream, rft._vals, context);
953 0 : }
954 :
955 : template <typename T>
956 : void
957 : dataLoad(std::istream & stream, ColumnMajorMatrixTempl<T> & cmm, void * context)
958 : {
959 : dataLoad(stream, cmm._values, context);
960 : }
961 :
962 : // Scalar Helper Function
963 : template <typename P>
964 : inline void
965 26920735 : storeHelper(std::ostream & stream, P & data, void * context)
966 : {
967 26920735 : dataStore(stream, data, context);
968 26920732 : }
969 :
970 : // Vector Helper Function
971 : template <typename P>
972 : inline void
973 722449 : storeHelper(std::ostream & stream, std::vector<P> & data, void * context)
974 : {
975 722449 : dataStore(stream, data, context);
976 722449 : }
977 :
978 : // std::shared_ptr Helper Function
979 : template <typename P>
980 : inline void
981 1615088 : storeHelper(std::ostream & stream, std::shared_ptr<P> & data, void * context)
982 : {
983 1615088 : dataStore(stream, data, context);
984 1615088 : }
985 :
986 : // std::unique Helper Function
987 : template <typename P>
988 : inline void
989 171491 : storeHelper(std::ostream & stream, std::unique_ptr<P> & data, void * context)
990 : {
991 171491 : dataStore(stream, data, context);
992 171491 : }
993 :
994 : // Set Helper Function
995 : template <typename P>
996 : inline void
997 2792 : storeHelper(std::ostream & stream, std::set<P> & data, void * context)
998 : {
999 2792 : dataStore(stream, data, context);
1000 2792 : }
1001 :
1002 : // Map Helper Function
1003 : template <typename P, typename Q>
1004 : inline void
1005 1570036 : storeHelper(std::ostream & stream, std::map<P, Q> & data, void * context)
1006 : {
1007 1570036 : dataStore(stream, data, context);
1008 1570036 : }
1009 :
1010 : // Unordered_map Helper Function
1011 : template <typename P, typename Q>
1012 : inline void
1013 50 : storeHelper(std::ostream & stream, std::unordered_map<P, Q> & data, void * context)
1014 : {
1015 50 : dataStore(stream, data, context);
1016 50 : }
1017 :
1018 : // Optional Helper Function
1019 : template <typename P>
1020 : inline void
1021 8277 : storeHelper(std::ostream & stream, std::optional<P> & data, void * context)
1022 : {
1023 8277 : dataStore(stream, data, context);
1024 8277 : }
1025 :
1026 : // HashMap Helper Function
1027 : template <typename P, typename Q>
1028 : inline void
1029 : storeHelper(std::ostream & stream, HashMap<P, Q> & data, void * context)
1030 : {
1031 : dataStore(stream, data, context);
1032 : }
1033 :
1034 : /**
1035 : * UniqueStorage helper routine
1036 : *
1037 : * The data within the UniqueStorage object cannot be null. The helper
1038 : * for unique_ptr<T> is called to store the data.
1039 : */
1040 : template <typename T>
1041 : inline void
1042 2 : storeHelper(std::ostream & stream, UniqueStorage<T> & data, void * context)
1043 : {
1044 2 : std::size_t size = data.size();
1045 2 : dataStore(stream, size, nullptr);
1046 :
1047 8 : for (const auto i : index_range(data))
1048 : {
1049 : mooseAssert(data.hasValue(i), "Data doesn't have a value");
1050 6 : storeHelper(stream, data.pointerValue(i), context);
1051 : }
1052 2 : }
1053 :
1054 : // Scalar Helper Function
1055 : template <typename P>
1056 : inline void
1057 7279973 : loadHelper(std::istream & stream, P & data, void * context)
1058 : {
1059 7279973 : dataLoad(stream, data, context);
1060 7279948 : }
1061 :
1062 : // Vector Helper Function
1063 : template <typename P>
1064 : inline void
1065 162670 : loadHelper(std::istream & stream, std::vector<P> & data, void * context)
1066 : {
1067 162670 : dataLoad(stream, data, context);
1068 162670 : }
1069 :
1070 : // std::shared_ptr Helper Function
1071 : template <typename P>
1072 : inline void
1073 65072 : loadHelper(std::istream & stream, std::shared_ptr<P> & data, void * context)
1074 : {
1075 65072 : dataLoad(stream, data, context);
1076 65072 : }
1077 :
1078 : // Unique Pointer Helper Function
1079 : template <typename P>
1080 : inline void
1081 45513 : loadHelper(std::istream & stream, std::unique_ptr<P> & data, void * context)
1082 : {
1083 45513 : dataLoad(stream, data, context);
1084 45513 : }
1085 :
1086 : // Set Helper Function
1087 : template <typename P>
1088 : inline void
1089 187 : loadHelper(std::istream & stream, std::set<P> & data, void * context)
1090 : {
1091 187 : dataLoad(stream, data, context);
1092 187 : }
1093 :
1094 : // Map Helper Function
1095 : template <typename P, typename Q>
1096 : inline void
1097 138262 : loadHelper(std::istream & stream, std::map<P, Q> & data, void * context)
1098 : {
1099 138262 : dataLoad(stream, data, context);
1100 138262 : }
1101 :
1102 : // Unordered_map Helper Function
1103 : template <typename P, typename Q>
1104 : inline void
1105 10 : loadHelper(std::istream & stream, std::unordered_map<P, Q> & data, void * context)
1106 : {
1107 10 : dataLoad(stream, data, context);
1108 10 : }
1109 :
1110 : // Optional Helper Function
1111 : template <typename P>
1112 : inline void
1113 6987 : loadHelper(std::istream & stream, std::optional<P> & data, void * context)
1114 : {
1115 6987 : dataLoad(stream, data, context);
1116 6987 : }
1117 :
1118 : // HashMap Helper Function
1119 : template <typename P, typename Q>
1120 : inline void
1121 : loadHelper(std::istream & stream, HashMap<P, Q> & data, void * context)
1122 : {
1123 : dataLoad(stream, data, context);
1124 : }
1125 :
1126 : /**
1127 : * UniqueStorage Helper Function
1128 : *
1129 : * The unique_ptr<T> loader is called to load the data. That is,
1130 : * you will likely need a specialization of unique_ptr<T> that will
1131 : * appropriately construct and then fill the piece of data.
1132 : */
1133 : template <typename T>
1134 : inline void
1135 2 : loadHelper(std::istream & stream, UniqueStorage<T> & data, void * context)
1136 : {
1137 : std::size_t size;
1138 2 : dataLoad(stream, size, nullptr);
1139 2 : data.resize(size);
1140 :
1141 8 : for (const auto i : index_range(data))
1142 6 : loadHelper(stream, data.pointerValue(i), context);
1143 2 : }
1144 :
1145 : void dataLoad(std::istream & stream, Point & p, void * context);
1146 :
1147 : #ifndef TIMPI_HAVE_STRING_PACKING
1148 : /**
1149 : * The following methods are specializations for using the libMesh::Parallel::packed_range_*
1150 : * routines
1151 : * for std::strings. These are here because the dataLoad/dataStore routines create raw string
1152 : * buffers that can be communicated in a standard way using packed ranges.
1153 : */
1154 : namespace libMesh
1155 : {
1156 : namespace Parallel
1157 : {
1158 : template <typename T>
1159 : class Packing<std::basic_string<T>>
1160 : {
1161 : public:
1162 : static const unsigned int size_bytes = 4;
1163 :
1164 : typedef T buffer_type;
1165 :
1166 : static unsigned int get_string_len(typename std::vector<T>::const_iterator in)
1167 : {
1168 : unsigned int string_len = reinterpret_cast<const unsigned char &>(in[size_bytes - 1]);
1169 : for (signed int i = size_bytes - 2; i >= 0; --i)
1170 : {
1171 : string_len *= 256;
1172 : string_len += reinterpret_cast<const unsigned char &>(in[i]);
1173 : }
1174 : return string_len;
1175 : }
1176 :
1177 : static unsigned int packed_size(typename std::vector<T>::const_iterator in)
1178 : {
1179 : return get_string_len(in) + size_bytes;
1180 : }
1181 :
1182 : static unsigned int packable_size(const std::basic_string<T> & s, const void *)
1183 : {
1184 : return s.size() + size_bytes;
1185 : }
1186 :
1187 : template <typename Iter>
1188 : static void pack(const std::basic_string<T> & b, Iter data_out, const void *)
1189 : {
1190 : unsigned int string_len = b.size();
1191 : for (unsigned int i = 0; i != size_bytes; ++i)
1192 : {
1193 : *data_out++ = (string_len % 256);
1194 : string_len /= 256;
1195 : }
1196 :
1197 : std::copy(b.begin(), b.end(), data_out);
1198 : }
1199 :
1200 : static std::basic_string<T> unpack(typename std::vector<T>::const_iterator in, void *)
1201 : {
1202 : unsigned int string_len = get_string_len(in);
1203 :
1204 : std::ostringstream oss;
1205 : for (unsigned int i = 0; i < string_len; ++i)
1206 : oss << reinterpret_cast<const unsigned char &>(in[i + size_bytes]);
1207 :
1208 : in += size_bytes + string_len;
1209 :
1210 : return oss.str();
1211 : }
1212 : };
1213 :
1214 : } // namespace Parallel
1215 :
1216 : } // namespace libMesh
1217 :
1218 : #endif
|