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

Generated by: LCOV version 1.14