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

Generated by: LCOV version 1.14