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