LCOV - code coverage report
Current view: top level - include/restart - DataIO.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 237 300 79.0 %
Date: 2026-05-29 20:35:17 Functions: 335 985 34.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14