LCOV - code coverage report
Current view: top level - include/restart - DataIO.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 218 278 78.4 %
Date: 2025-07-17 01:28:37 Functions: 318 903 35.2 %
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             : 
      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

Generated by: LCOV version 1.14