LCOV - code coverage report
Current view: top level - src/restart - DataIO.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33416 (b10b36) with base 9fbd27 Lines: 215 348 61.8 %
Date: 2026-07-23 16:15:30 Functions: 25 59 42.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             : #include "DenseMatrix.h"
      11             : #include "DataIO.h"
      12             : #include "MooseMesh.h"
      13             : #include "FEProblemBase.h"
      14             : #include "NonlinearSystemBase.h"
      15             : 
      16             : #include "libmesh/vector_value.h"
      17             : #include "libmesh/tensor_value.h"
      18             : #include "libmesh/fe_type.h"
      19             : 
      20             : #include "libmesh/elem.h"
      21             : #include "libmesh/petsc_vector.h"
      22             : #include "libmesh/enum_solver_package.h"
      23             : #include "libmesh/petsc_solver_exception.h"
      24             : 
      25             : using namespace libMesh;
      26             : 
      27             : template <>
      28             : void
      29    44130699 : dataStore(std::ostream & stream, Real & v, void * /*context*/)
      30             : {
      31    44130699 :   stream.write((char *)&v, sizeof(v));
      32    44130699 : }
      33             : 
      34             : template <>
      35             : void
      36    30951959 : dataStore(std::ostream & stream, std::string & v, void * /*context*/)
      37             : {
      38             :   // Write the size of the string
      39    30951959 :   unsigned int size = v.size();
      40    30951959 :   stream.write((char *)&size, sizeof(size));
      41             : 
      42             :   // Write the string (Do not store the null byte)
      43    30951959 :   stream.write(v.c_str(), sizeof(char) * size);
      44    30951959 : }
      45             : 
      46             : template <>
      47             : void
      48           0 : dataStore(std::ostream & stream, VariableName & v, void * context)
      49             : {
      50           0 :   auto & name = static_cast<std::string &>(v);
      51           0 :   dataStore(stream, name, context);
      52           0 : }
      53             : 
      54             : template <>
      55             : void
      56           0 : dataStore(std::ostream & stream, UserObjectName & v, void * context)
      57             : {
      58           0 :   auto & name = static_cast<std::string &>(v);
      59           0 :   dataStore(stream, name, context);
      60           0 : }
      61             : 
      62             : template <>
      63             : void
      64    10646063 : dataStore(std::ostream & stream, bool & v, void * /*context*/)
      65             : {
      66    10646063 :   stream.write((char *)&v, sizeof(v));
      67    10646063 : }
      68             : 
      69             : template <>
      70             : void
      71       93991 : dataStore(std::ostream & stream, FEType & v, void * context)
      72             : {
      73       93991 :   auto order = v.order.get_order();
      74       93991 :   dataStore(stream, order, context);
      75             : 
      76       93991 :   auto family = v.family;
      77       93991 :   dataStore(stream, family, context);
      78             : 
      79             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
      80             :   auto radial_order = v.radial_order.get_order();
      81             :   dataStore(stream, radial_order, context);
      82             : 
      83             :   auto radial_family = v.radial_family;
      84             :   dataStore(stream, radial_family, context);
      85             : 
      86             :   auto inf_map = v.inf_map;
      87             :   dataStore(stream, inf_map, context);
      88             : #endif
      89             : 
      90       93991 :   auto p_refinement = v.p_refinement;
      91       93991 :   dataStore(stream, p_refinement, context);
      92       93991 : }
      93             : 
      94             : template <>
      95             : void
      96           0 : dataStore(std::ostream & stream, std::vector<bool> & v, void * context)
      97             : {
      98           0 :   for (bool b : v)
      99           0 :     dataStore(stream, b, context);
     100           0 : }
     101             : 
     102             : template <>
     103             : void
     104           0 : dataStore(std::ostream & stream, RankTwoTensor & rtt, void * context)
     105             : {
     106           0 :   dataStore(stream, rtt._coords, context);
     107           0 : }
     108             : 
     109             : template <>
     110             : void
     111           0 : dataStore(std::ostream & stream, RankThreeTensor & rtht, void * context)
     112             : {
     113           0 :   dataStore(stream, rtht._vals, context);
     114           0 : }
     115             : 
     116             : template <>
     117             : void
     118           0 : dataStore(std::ostream & stream, RankFourTensor & rft, void * context)
     119             : {
     120           0 :   dataStore(stream, rft._vals, context);
     121           0 : }
     122             : 
     123             : template <>
     124             : void
     125           0 : dataStore(std::ostream & stream, ADReal & dn, void * context)
     126             : {
     127           0 :   dataStore(stream, dn.value(), context);
     128             : 
     129           0 :   if (ADReal::do_derivatives)
     130             :   {
     131           0 :     auto & derivatives = dn.derivatives();
     132           0 :     std::size_t size = derivatives.size();
     133           0 :     dataStore(stream, size, context);
     134           0 :     for (MooseIndex(size) i = 0; i < size; ++i)
     135             :     {
     136           0 :       dataStore(stream, derivatives.raw_index(i), context);
     137           0 :       dataStore(stream, derivatives.raw_at(i), context);
     138             :     }
     139             :   }
     140           0 : }
     141             : 
     142             : template <>
     143             : void
     144       62997 : dataStore(std::ostream & stream, const Elem *& e, void * context)
     145             : {
     146             :   // TODO: Write out the unique ID of this elem
     147       62997 :   dof_id_type id = libMesh::DofObject::invalid_id;
     148             : 
     149       62997 :   if (e)
     150             :   {
     151       62997 :     id = e->id();
     152       62997 :     if (id == libMesh::DofObject::invalid_id)
     153           0 :       mooseError("Can't output Elems with invalid ids!");
     154             :   }
     155             : 
     156       62997 :   storeHelper(stream, id, context);
     157       62997 : }
     158             : 
     159             : template <>
     160             : void
     161        4181 : dataStore(std::ostream & stream, const Node *& n, void * context)
     162             : {
     163             :   // TODO: Write out the unique ID of this node
     164        4181 :   dof_id_type id = libMesh::DofObject::invalid_id;
     165             : 
     166        4181 :   if (n)
     167             :   {
     168        4181 :     id = n->id();
     169        4181 :     if (id == libMesh::DofObject::invalid_id)
     170           0 :       mooseError("Can't output Nodes with invalid ids!");
     171             :   }
     172             : 
     173        4181 :   storeHelper(stream, id, context);
     174        4181 : }
     175             : 
     176             : template <>
     177             : void
     178           0 : dataStore(std::ostream & stream, Elem *& e, void * context)
     179             : {
     180             :   // TODO: Write out the unique ID of this elem
     181           0 :   dof_id_type id = libMesh::DofObject::invalid_id;
     182             : 
     183           0 :   if (e)
     184             :   {
     185           0 :     id = e->id();
     186           0 :     if (id == libMesh::DofObject::invalid_id)
     187           0 :       mooseError("Can't output Elems with invalid ids!");
     188             :   }
     189             : 
     190           0 :   storeHelper(stream, id, context);
     191           0 : }
     192             : 
     193             : template <>
     194             : void
     195           0 : dataStore(std::ostream & stream, Node *& n, void * context)
     196             : {
     197             :   // TODO: Write out the unique ID of this node
     198           0 :   dof_id_type id = libMesh::DofObject::invalid_id;
     199             : 
     200           0 :   if (n)
     201             :   {
     202           0 :     id = n->id();
     203           0 :     if (id == libMesh::DofObject::invalid_id)
     204           0 :       mooseError("Can't output Nodes with invalid ids!");
     205             :   }
     206             : 
     207           0 :   storeHelper(stream, id, context);
     208           0 : }
     209             : 
     210             : template <>
     211             : void
     212       51205 : dataStore(std::ostream & stream, std::stringstream & s, void * /* context */)
     213             : {
     214       51205 :   const std::string & s_str = s.str();
     215             : 
     216       51205 :   size_t s_size = s_str.size();
     217       51205 :   stream.write((char *)&s_size, sizeof(s_size));
     218             : 
     219       51205 :   stream.write(s_str.c_str(), sizeof(char) * (s_str.size()));
     220       51205 : }
     221             : 
     222             : #ifdef MOOSE_LIBTORCH_ENABLED
     223             : template <>
     224             : void
     225           2 : dataStore(std::ostream & stream, torch::Tensor & t, void * context)
     226             : {
     227           2 :   const auto tensor = LibtorchUtils::toCPUContiguous(t);
     228             :   mooseAssert(tensor.scalar_type() == at::kDouble,
     229             :               "Restart storage currently supports only double tensors.");
     230             : 
     231           2 :   auto rank = cast_int<unsigned int>(tensor.dim());
     232           2 :   dataStore(stream, rank, nullptr);
     233           7 :   for (unsigned int dim = 0; dim < rank; ++dim)
     234             :   {
     235           5 :     auto size = cast_int<unsigned int>(tensor.sizes()[dim]);
     236           5 :     dataStore(stream, size, nullptr);
     237             :   }
     238             : 
     239           2 :   const auto flattened = tensor.reshape({tensor.numel()});
     240           2 :   const auto t_accessor = flattened.accessor<Real, 1>();
     241           8 :   for (int64_t i = 0; i < flattened.numel(); ++i)
     242             :   {
     243           6 :     Real r = t_accessor[i];
     244           6 :     dataStore(stream, r, context);
     245             :   }
     246           2 : }
     247             : #endif
     248             : 
     249             : template <typename T>
     250             : void
     251           0 : dataStore(std::ostream & stream, TensorValue<T> & v, void * context)
     252             : {
     253           0 :   for (const auto i : make_range(Moose::dim))
     254           0 :     for (const auto j : make_range(Moose::dim))
     255             :     {
     256           0 :       T r = v(i, j);
     257           0 :       dataStore(stream, r, context);
     258             :     }
     259           0 : }
     260             : 
     261             : template void dataStore(std::ostream & stream, TensorValue<Real> & v, void * context);
     262             : template void dataStore(std::ostream & stream, TensorValue<ADReal> & v, void * context);
     263             : 
     264             : template <typename T>
     265             : void
     266          48 : dataStore(std::ostream & stream, DenseMatrix<T> & v, void * context)
     267             : {
     268          48 :   unsigned int m = v.m();
     269          48 :   unsigned int n = v.n();
     270          48 :   stream.write((char *)&m, sizeof(m));
     271          48 :   stream.write((char *)&n, sizeof(n));
     272         144 :   for (unsigned int i = 0; i < m; i++)
     273         384 :     for (unsigned int j = 0; j < n; j++)
     274             :     {
     275         288 :       T r = v(i, j);
     276         288 :       dataStore(stream, r, context);
     277             :     }
     278          48 : }
     279             : 
     280             : template void dataStore(std::ostream & stream, DenseMatrix<Real> & v, void * context);
     281             : template void dataStore(std::ostream & stream, DenseMatrix<ADReal> & v, void * context);
     282             : 
     283             : template <typename T>
     284             : void
     285      103603 : dataStore(std::ostream & stream, VectorValue<T> & v, void * context)
     286             : {
     287             :   // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
     288             :   // won't work.
     289      414412 :   for (const auto i : make_range(Moose::dim))
     290             :   {
     291      310809 :     T r = v(i);
     292      310809 :     dataStore(stream, r, context);
     293             :   }
     294      103603 : }
     295             : 
     296             : template void dataStore(std::ostream & stream, VectorValue<Real> & v, void * context);
     297             : template void dataStore(std::ostream & stream, VectorValue<ADReal> & v, void * context);
     298             : 
     299             : void
     300       53986 : dataStore(std::ostream & stream, Point & p, void * context)
     301             : {
     302      215944 :   for (const auto i : make_range(Moose::dim))
     303             :   {
     304      161958 :     Real r = p(i);
     305      161958 :     dataStore(stream, r, context);
     306             :   }
     307       53986 : }
     308             : 
     309             : template <>
     310             : void
     311          48 : dataStore(std::ostream & stream, libMesh::Parameters & p, void * context)
     312             : {
     313             :   // First store the size of the map
     314          48 :   unsigned int size = p.n_parameters();
     315          48 :   stream.write((char *)&size, sizeof(size));
     316             : 
     317          48 :   auto it = p.begin();
     318          48 :   auto end = p.end();
     319             : 
     320         192 :   for (; it != end; ++it)
     321             :   {
     322         144 :     auto & key = const_cast<std::string &>(it->first);
     323         144 :     auto type = it->second->type();
     324             : 
     325         144 :     storeHelper(stream, key, context);
     326         144 :     storeHelper(stream, type, context);
     327             : 
     328             : #define storescalar(ptype)                                                                         \
     329             :   else if (it->second->type() == demangle(typeid(ptype).name())) storeHelper(                      \
     330             :       stream,                                                                                      \
     331             :       (dynamic_cast<libMesh::Parameters::Parameter<ptype> *>(MooseUtils::get(it->second)))->get(), \
     332             :       context)
     333             : 
     334             :     if (false)
     335             :       ;
     336         144 :     storescalar(Real);
     337          96 :     storescalar(short);
     338          96 :     storescalar(int);
     339          48 :     storescalar(long);
     340          48 :     storescalar(unsigned short);
     341          48 :     storescalar(unsigned int);
     342           0 :     storescalar(unsigned long);
     343             : 
     344             : #undef storescalar
     345         144 :   }
     346          48 : }
     347             : 
     348             : template <>
     349             : void
     350      167428 : dataStore(std::ostream & stream,
     351             :           std::unique_ptr<libMesh::NumericVector<Number>> & v,
     352             :           void * context)
     353             : {
     354             :   // Classes may declare unique pointers to vectors as restartable data and never actually create
     355             :   // vector instances. This happens for example in the `TimeIntegrator` class where subvector
     356             :   // instances are only created if multiple time integrators are present
     357      167428 :   bool have_vector = v.get();
     358      167428 :   dataStore(stream, have_vector, context);
     359      167428 :   if (!have_vector)
     360      167418 :     return;
     361             : 
     362             :   mooseAssert(context, "Needs a context of the communicator");
     363          10 :   const auto & comm = *static_cast<const libMesh::Parallel::Communicator *>(context);
     364             :   mooseAssert(&comm == &v->comm(), "Inconsistent communicator");
     365             : 
     366          10 :   if (v->type() == GHOSTED)
     367           0 :     mooseError("Cannot store ghosted numeric vectors");
     368             : 
     369             :   // Store the communicator size for sanity checking later
     370          10 :   unsigned int comm_size = comm.size();
     371          10 :   dataStore(stream, comm_size, nullptr);
     372             : 
     373             :   // Store the solver package so that we know what vector type to construct
     374             :   libMesh::SolverPackage solver_package;
     375          10 :   if (dynamic_cast<libMesh::PetscVector<Number> *>(v.get()))
     376          10 :     solver_package = PETSC_SOLVERS;
     377             :   else
     378           0 :     mooseError("Can only store unique_ptrs of PetscVectors");
     379          10 :   int solver_package_int = solver_package;
     380          10 :   dataStore(stream, solver_package_int, nullptr);
     381             : 
     382             :   // Store the sizes
     383          10 :   dof_id_type size = v->size();
     384          10 :   dataStore(stream, size, nullptr);
     385          10 :   dof_id_type local_size = v->local_size();
     386          10 :   dataStore(stream, local_size, nullptr);
     387             : 
     388             :   // Store the vector itself
     389          10 :   dataStore(stream, *v, nullptr);
     390             : }
     391             : 
     392             : // global load functions
     393             : 
     394             : template <>
     395             : void
     396    13931617 : dataLoad(std::istream & stream, Real & v, void * /*context*/)
     397             : {
     398    13931617 :   stream.read((char *)&v, sizeof(v));
     399    13931617 : }
     400             : 
     401             : template <>
     402             : void
     403     8054562 : dataLoad(std::istream & stream, std::string & v, void * /*context*/)
     404             : {
     405             :   // Read the size of the string
     406     8054562 :   unsigned int size = 0;
     407     8054562 :   stream.read((char *)&size, sizeof(size));
     408             : 
     409             :   // Resize the string data
     410     8054562 :   v.resize(size);
     411             : 
     412             :   // Read the string
     413     8054562 :   stream.read(&v[0], sizeof(char) * size);
     414     8054562 : }
     415             : 
     416             : template <>
     417             : void
     418           0 : dataLoad(std::istream & stream, VariableName & v, void * context)
     419             : {
     420           0 :   auto & name = static_cast<std::string &>(v);
     421           0 :   dataLoad(stream, name, context);
     422           0 : }
     423             : 
     424             : template <>
     425             : void
     426           0 : dataLoad(std::istream & stream, UserObjectName & v, void * context)
     427             : {
     428           0 :   auto & name = static_cast<std::string &>(v);
     429           0 :   dataLoad(stream, name, context);
     430           0 : }
     431             : 
     432             : template <>
     433             : void
     434     2991998 : dataLoad(std::istream & stream, bool & v, void * /*context*/)
     435             : {
     436     2991998 :   stream.read((char *)&v, sizeof(v));
     437     2991998 : }
     438             : 
     439             : template <>
     440             : void
     441       27604 : dataLoad(std::istream & stream, FEType & v, void * context)
     442             : {
     443       27604 :   int order = 0;
     444       27604 :   dataLoad(stream, order, context);
     445       27604 :   v.order = order;
     446             : 
     447       27604 :   dataLoad(stream, v.family, context);
     448             : 
     449             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     450             :   int radial_order = 0;
     451             :   dataLoad(stream, radial_order, context);
     452             :   v.radial_order = radial_order;
     453             : 
     454             :   dataLoad(stream, v.radial_family, context);
     455             :   dataLoad(stream, v.inf_map, context);
     456             : #endif
     457             : 
     458       27604 :   dataLoad(stream, v.p_refinement, context);
     459       27604 : }
     460             : 
     461             : template <>
     462             : void
     463           0 : dataLoad(std::istream & stream, std::vector<bool> & v, void * context)
     464             : {
     465           0 :   for (bool b : v)
     466           0 :     dataLoad(stream, b, context);
     467           0 : }
     468             : 
     469             : template <>
     470             : void
     471           0 : dataLoad(std::istream & stream, ADReal & dn, void * context)
     472             : {
     473           0 :   dataLoad(stream, dn.value(), context);
     474             : 
     475           0 :   if (ADReal::do_derivatives)
     476             :   {
     477           0 :     auto & derivatives = dn.derivatives();
     478           0 :     std::size_t size = 0;
     479           0 :     stream.read((char *)&size, sizeof(size));
     480           0 :     derivatives.resize(size);
     481             : 
     482           0 :     for (MooseIndex(derivatives) i = 0; i < derivatives.size(); ++i)
     483             :     {
     484           0 :       dataLoad(stream, derivatives.raw_index(i), context);
     485           0 :       dataLoad(stream, derivatives.raw_at(i), context);
     486             :     }
     487             :   }
     488           0 : }
     489             : 
     490             : template <>
     491             : void
     492       15212 : dataLoad(std::istream & stream, const Elem *& e, void * context)
     493             : {
     494       15212 :   if (!context)
     495           0 :     mooseError("Can only load Elem objects using a MooseMesh context!");
     496             : 
     497       15212 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     498             : 
     499             :   // TODO: Write out the unique ID of this element
     500       15212 :   dof_id_type id = libMesh::DofObject::invalid_id;
     501             : 
     502       15212 :   loadHelper(stream, id, context);
     503             : 
     504       15212 :   if (id != libMesh::DofObject::invalid_id)
     505       15212 :     e = mesh->elemPtr(id);
     506             :   else
     507           0 :     e = NULL;
     508       15212 : }
     509             : 
     510             : template <>
     511             : void
     512         545 : dataLoad(std::istream & stream, const Node *& n, void * context)
     513             : {
     514         545 :   if (!context)
     515           0 :     mooseError("Can only load Node objects using a MooseMesh context!");
     516             : 
     517         545 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     518             : 
     519             :   // TODO: Write out the unique ID of this nodeent
     520         545 :   dof_id_type id = libMesh::DofObject::invalid_id;
     521             : 
     522         545 :   loadHelper(stream, id, context);
     523             : 
     524         545 :   if (id != libMesh::DofObject::invalid_id)
     525         545 :     n = mesh->nodePtr(id);
     526             :   else
     527           0 :     n = NULL;
     528         545 : }
     529             : 
     530             : template <>
     531             : void
     532           0 : dataLoad(std::istream & stream, Elem *& e, void * context)
     533             : {
     534           0 :   if (!context)
     535           0 :     mooseError("Can only load Elem objects using a MooseMesh context!");
     536             : 
     537           0 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     538             : 
     539             :   // TODO: Write out the unique ID of this element
     540           0 :   dof_id_type id = libMesh::DofObject::invalid_id;
     541             : 
     542           0 :   loadHelper(stream, id, context);
     543             : 
     544           0 :   if (id != libMesh::DofObject::invalid_id)
     545           0 :     e = mesh->elemPtr(id);
     546             :   else
     547           0 :     e = NULL;
     548           0 : }
     549             : 
     550             : template <>
     551             : void
     552           0 : dataLoad(std::istream & stream, Node *& n, void * context)
     553             : {
     554           0 :   if (!context)
     555           0 :     mooseError("Can only load Node objects using a MooseMesh context!");
     556             : 
     557           0 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     558             : 
     559             :   // TODO: Write out the unique ID of this nodeent
     560           0 :   dof_id_type id = libMesh::DofObject::invalid_id;
     561             : 
     562           0 :   loadHelper(stream, id, context);
     563             : 
     564           0 :   if (id != libMesh::DofObject::invalid_id)
     565           0 :     n = mesh->nodePtr(id);
     566             :   else
     567           0 :     n = NULL;
     568           0 : }
     569             : 
     570             : template <>
     571             : void
     572       16529 : dataLoad(std::istream & stream, std::stringstream & s, void * /* context */)
     573             : {
     574       16529 :   size_t s_size = 0;
     575       16529 :   stream.read((char *)&s_size, sizeof(s_size));
     576             : 
     577       16529 :   std::unique_ptr<char[]> s_s = std::make_unique<char[]>(s_size);
     578       16529 :   stream.read(s_s.get(), s_size);
     579             : 
     580             :   // Clear the stringstream before loading new data into it.
     581       16529 :   s.str(std::string());
     582       16529 :   s.write(s_s.get(), s_size);
     583       16529 : }
     584             : 
     585             : #ifdef MOOSE_LIBTORCH_ENABLED
     586             : template <>
     587             : void
     588           2 : dataLoad(std::istream & stream, torch::Tensor & t, void * context)
     589             : {
     590           2 :   unsigned int rank = 0;
     591           2 :   dataLoad(stream, rank, nullptr);
     592             : 
     593           2 :   std::vector<int64_t> sizes(rank);
     594           7 :   for (unsigned int dim = 0; dim < rank; ++dim)
     595             :   {
     596           5 :     unsigned int size = 0;
     597           5 :     dataLoad(stream, size, nullptr);
     598           5 :     sizes[dim] = size;
     599             :   }
     600             : 
     601           2 :   t = torch::empty(sizes, at::kDouble);
     602           2 :   auto flattened = t.reshape({t.numel()});
     603           2 :   auto t_accessor = flattened.accessor<Real, 1>();
     604           8 :   for (int64_t i = 0; i < flattened.numel(); ++i)
     605             :   {
     606           6 :     Real r = 0;
     607           6 :     dataLoad(stream, r, context);
     608           6 :     t_accessor[i] = r;
     609             :   }
     610           2 : }
     611             : #endif
     612             : 
     613             : template <typename T>
     614             : void
     615           0 : dataLoad(std::istream & stream, TensorValue<T> & v, void * context)
     616             : {
     617             :   // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
     618             :   // won't work.
     619           0 :   for (const auto i : make_range(Moose::dim))
     620           0 :     for (const auto j : make_range(Moose::dim))
     621             :     {
     622           0 :       T r = 0;
     623           0 :       dataLoad(stream, r, context);
     624           0 :       v(i, j) = r;
     625             :     }
     626           0 : }
     627             : 
     628             : template void dataLoad(std::istream & stream, TensorValue<Real> & v, void * context);
     629             : template void dataLoad(std::istream & stream, TensorValue<ADReal> & v, void * context);
     630             : 
     631             : template <typename T>
     632             : void
     633          68 : dataLoad(std::istream & stream, DenseMatrix<T> & v, void * context)
     634             : {
     635          68 :   unsigned int m = 0, n = 0;
     636          68 :   stream.read((char *)&m, sizeof(m));
     637          68 :   stream.read((char *)&n, sizeof(n));
     638          68 :   v.resize(m, n);
     639         204 :   for (unsigned int i = 0; i < m; i++)
     640         544 :     for (unsigned int j = 0; j < n; j++)
     641             :     {
     642         408 :       T r = 0;
     643         408 :       dataLoad(stream, r, context);
     644         408 :       v(i, j) = r;
     645             :     }
     646          68 : }
     647             : 
     648             : template void dataLoad(std::istream & stream, DenseMatrix<Real> & v, void * context);
     649             : template void dataLoad(std::istream & stream, DenseMatrix<ADReal> & v, void * context);
     650             : 
     651             : template <typename T>
     652             : void
     653       12717 : dataLoad(std::istream & stream, VectorValue<T> & v, void * context)
     654             : {
     655             :   // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
     656             :   // won't work.
     657       50868 :   for (const auto i : make_range(Moose::dim))
     658             :   {
     659       38151 :     T r = 0;
     660       38151 :     dataLoad(stream, r, context);
     661       38151 :     v(i) = r;
     662             :   }
     663       12717 : }
     664             : 
     665             : template void dataLoad(std::istream & stream, VectorValue<Real> & v, void * context);
     666             : template void dataLoad(std::istream & stream, VectorValue<ADReal> & v, void * context);
     667             : 
     668             : void
     669           0 : dataLoad(std::istream & stream, Point & p, void * context)
     670             : {
     671           0 :   for (const auto i : make_range(Moose::dim))
     672             :   {
     673           0 :     Real r = 0;
     674           0 :     dataLoad(stream, r, context);
     675           0 :     p(i) = r;
     676             :   }
     677           0 : }
     678             : 
     679             : template <>
     680             : void
     681          68 : dataLoad(std::istream & stream, libMesh::Parameters & p, void * context)
     682             : {
     683          68 :   p.clear();
     684             : 
     685             :   // First read the size of the map
     686          68 :   unsigned int size = 0;
     687          68 :   stream.read((char *)&size, sizeof(size));
     688             : 
     689         272 :   for (unsigned int i = 0; i < size; i++)
     690             :   {
     691         204 :     std::string key, type;
     692         204 :     loadHelper(stream, key, context);
     693         204 :     loadHelper(stream, type, context);
     694             : 
     695             : #define loadscalar(ptype)                                                                          \
     696             :   else if (type == demangle(typeid(ptype).name())) do                                              \
     697             :   {                                                                                                \
     698             :     ptype & value = p.set<ptype>(key);                                                             \
     699             :     loadHelper(stream, value, context);                                                            \
     700             :   }                                                                                                \
     701             :   while (0)
     702             : 
     703             :     if (false)
     704             :       ;
     705         204 :     loadscalar(Real);
     706         136 :     loadscalar(short);
     707         136 :     loadscalar(int);
     708          68 :     loadscalar(long);
     709          68 :     loadscalar(unsigned short);
     710          68 :     loadscalar(unsigned int);
     711           0 :     loadscalar(unsigned long);
     712             : 
     713             : #undef loadscalar
     714         204 :   }
     715          68 : }
     716             : 
     717             : template <>
     718             : void
     719       44268 : dataLoad(std::istream & stream, std::unique_ptr<libMesh::NumericVector<Number>> & v, void * context)
     720             : {
     721             :   bool have_vector;
     722       44268 :   dataLoad(stream, have_vector, context);
     723             : 
     724       44268 :   if (!have_vector)
     725       44260 :     return;
     726             : 
     727             :   mooseAssert(context, "Needs a context of the communicator");
     728           8 :   const auto & comm = *static_cast<const libMesh::Parallel::Communicator *>(context);
     729           8 :   if (v)
     730             :     mooseAssert(&comm == &v->comm(), "Inconsistent communicator");
     731             : 
     732             :   // Load the communicator size for consistency checks
     733             :   unsigned int comm_size;
     734           8 :   dataLoad(stream, comm_size, nullptr);
     735             :   mooseAssert(comm.size() == comm_size, "Inconsistent communicator size");
     736             : 
     737             :   // Load the solver package to build the vector
     738             :   int solver_package_int;
     739           8 :   dataLoad(stream, solver_package_int, nullptr);
     740           8 :   libMesh::SolverPackage solver_package = static_cast<libMesh::SolverPackage>(solver_package_int);
     741             : 
     742             :   // Load the sizes
     743             :   dof_id_type size, local_size;
     744           8 :   dataLoad(stream, size, nullptr);
     745           8 :   dataLoad(stream, local_size, nullptr);
     746             : 
     747             :   // Construct the vector given the type, only if we need to. v could be non-null here
     748             :   // if we're advancing back and loading a backup
     749           8 :   if (!v)
     750             :   {
     751           6 :     v = NumericVector<Number>::build(comm, solver_package);
     752           6 :     v->init(size, local_size);
     753             :   }
     754             :   else
     755             :     mooseAssert(v->type() != GHOSTED, "Cannot be ghosted");
     756             : 
     757             :   // Make sure that the sizes are consistent; this will happen if we're calling this
     758             :   // on a vector that has already been loaded previously
     759             :   mooseAssert(v->size() == size, "Inconsistent size");
     760             :   mooseAssert(v->local_size() == local_size, "Inconsistent local size");
     761             : 
     762             :   // Now that we have an initialized vector, fill the entries
     763           8 :   dataLoad(stream, *v, nullptr);
     764             : }
     765             : 
     766             : template <>
     767             : void
     768           0 : dataLoad(std::istream & stream, Vec & v, void * context)
     769             : {
     770             :   PetscInt local_size;
     771           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetLocalSize(v, &local_size));
     772             :   PetscScalar * array;
     773           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetArray(v, &array));
     774           0 :   for (PetscInt i = 0; i < local_size; i++)
     775           0 :     dataLoad(stream, array[i], context);
     776             : 
     777           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecRestoreArray(v, &array));
     778           0 : }
     779             : 
     780             : template <>
     781             : void
     782           0 : dataStore(std::ostream & stream, Vec & v, void * context)
     783             : {
     784             :   PetscInt local_size;
     785           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetLocalSize(v, &local_size));
     786             :   PetscScalar * array;
     787           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetArray(v, &array));
     788           0 :   for (PetscInt i = 0; i < local_size; i++)
     789           0 :     dataStore(stream, array[i], context);
     790             : 
     791           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecRestoreArray(v, &array));
     792           0 : }

Generated by: LCOV version 1.14