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