LCOV - code coverage report
Current view: top level - src/restart - DataIO.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 186 319 58.3 %
Date: 2026-05-29 20:35:17 Functions: 23 57 40.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    44045095 : dataStore(std::ostream & stream, Real & v, void * /*context*/)
      30             : {
      31    44045095 :   stream.write((char *)&v, sizeof(v));
      32    44045095 : }
      33             : 
      34             : template <>
      35             : void
      36    30383245 : dataStore(std::ostream & stream, std::string & v, void * /*context*/)
      37             : {
      38             :   // Write the size of the string
      39    30383245 :   unsigned int size = v.size();
      40    30383245 :   stream.write((char *)&size, sizeof(size));
      41             : 
      42             :   // Write the string (Do not store the null byte)
      43    30383245 :   stream.write(v.c_str(), sizeof(char) * size);
      44    30383245 : }
      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    10444740 : dataStore(std::ostream & stream, bool & v, void * /*context*/)
      65             : {
      66    10444740 :   stream.write((char *)&v, sizeof(v));
      67    10444740 : }
      68             : 
      69             : template <>
      70             : void
      71       92791 : dataStore(std::ostream & stream, FEType & v, void * context)
      72             : {
      73       92791 :   auto order = v.order.get_order();
      74       92791 :   dataStore(stream, order, context);
      75             : 
      76       92791 :   auto family = v.family;
      77       92791 :   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       92791 :   auto p_refinement = v.p_refinement;
      91       92791 :   dataStore(stream, p_refinement, context);
      92       92791 : }
      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       62991 : dataStore(std::ostream & stream, const Elem *& e, void * context)
     145             : {
     146             :   // TODO: Write out the unique ID of this elem
     147       62991 :   dof_id_type id = libMesh::DofObject::invalid_id;
     148             : 
     149       62991 :   if (e)
     150             :   {
     151       62991 :     id = e->id();
     152       62991 :     if (id == libMesh::DofObject::invalid_id)
     153           0 :       mooseError("Can't output Elems with invalid ids!");
     154             :   }
     155             : 
     156       62991 :   storeHelper(stream, id, context);
     157       62991 : }
     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       50841 : dataStore(std::ostream & stream, std::stringstream & s, void * /* context */)
     213             : {
     214       50841 :   const std::string & s_str = s.str();
     215             : 
     216       50841 :   size_t s_size = s_str.size();
     217       50841 :   stream.write((char *)&s_size, sizeof(s_size));
     218             : 
     219       50841 :   stream.write(s_str.c_str(), sizeof(char) * (s_str.size()));
     220       50841 : }
     221             : 
     222             : template <typename T>
     223             : void
     224           0 : dataStore(std::ostream & stream, TensorValue<T> & v, void * context)
     225             : {
     226           0 :   for (const auto i : make_range(Moose::dim))
     227           0 :     for (const auto j : make_range(Moose::dim))
     228             :     {
     229           0 :       T r = v(i, j);
     230           0 :       dataStore(stream, r, context);
     231             :     }
     232           0 : }
     233             : 
     234             : template void dataStore(std::ostream & stream, TensorValue<Real> & v, void * context);
     235             : template void dataStore(std::ostream & stream, TensorValue<ADReal> & v, void * context);
     236             : 
     237             : template <typename T>
     238             : void
     239          48 : dataStore(std::ostream & stream, DenseMatrix<T> & v, void * context)
     240             : {
     241          48 :   unsigned int m = v.m();
     242          48 :   unsigned int n = v.n();
     243          48 :   stream.write((char *)&m, sizeof(m));
     244          48 :   stream.write((char *)&n, sizeof(n));
     245         144 :   for (unsigned int i = 0; i < m; i++)
     246         384 :     for (unsigned int j = 0; j < n; j++)
     247             :     {
     248         288 :       T r = v(i, j);
     249         288 :       dataStore(stream, r, context);
     250             :     }
     251          48 : }
     252             : 
     253             : template void dataStore(std::ostream & stream, DenseMatrix<Real> & v, void * context);
     254             : template void dataStore(std::ostream & stream, DenseMatrix<ADReal> & v, void * context);
     255             : 
     256             : template <typename T>
     257             : void
     258      103585 : dataStore(std::ostream & stream, VectorValue<T> & v, void * context)
     259             : {
     260             :   // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
     261             :   // won't work.
     262      414340 :   for (const auto i : make_range(Moose::dim))
     263             :   {
     264      310755 :     T r = v(i);
     265      310755 :     dataStore(stream, r, context);
     266             :   }
     267      103585 : }
     268             : 
     269             : template void dataStore(std::ostream & stream, VectorValue<Real> & v, void * context);
     270             : template void dataStore(std::ostream & stream, VectorValue<ADReal> & v, void * context);
     271             : 
     272             : void
     273       53971 : dataStore(std::ostream & stream, Point & p, void * context)
     274             : {
     275      215884 :   for (const auto i : make_range(Moose::dim))
     276             :   {
     277      161913 :     Real r = p(i);
     278      161913 :     dataStore(stream, r, context);
     279             :   }
     280       53971 : }
     281             : 
     282             : template <>
     283             : void
     284          48 : dataStore(std::ostream & stream, libMesh::Parameters & p, void * context)
     285             : {
     286             :   // First store the size of the map
     287          48 :   unsigned int size = p.n_parameters();
     288          48 :   stream.write((char *)&size, sizeof(size));
     289             : 
     290          48 :   auto it = p.begin();
     291          48 :   auto end = p.end();
     292             : 
     293         192 :   for (; it != end; ++it)
     294             :   {
     295         144 :     auto & key = const_cast<std::string &>(it->first);
     296         144 :     auto type = it->second->type();
     297             : 
     298         144 :     storeHelper(stream, key, context);
     299         144 :     storeHelper(stream, type, context);
     300             : 
     301             : #define storescalar(ptype)                                                                         \
     302             :   else if (it->second->type() == demangle(typeid(ptype).name())) storeHelper(                      \
     303             :       stream,                                                                                      \
     304             :       (dynamic_cast<libMesh::Parameters::Parameter<ptype> *>(MooseUtils::get(it->second)))->get(), \
     305             :       context)
     306             : 
     307             :     if (false)
     308             :       ;
     309         144 :     storescalar(Real);
     310          96 :     storescalar(short);
     311          96 :     storescalar(int);
     312          48 :     storescalar(long);
     313          48 :     storescalar(unsigned short);
     314          48 :     storescalar(unsigned int);
     315           0 :     storescalar(unsigned long);
     316             : 
     317             : #undef storescalar
     318         144 :   }
     319          48 : }
     320             : 
     321             : template <>
     322             : void
     323      163568 : dataStore(std::ostream & stream,
     324             :           std::unique_ptr<libMesh::NumericVector<Number>> & v,
     325             :           void * context)
     326             : {
     327             :   // Classes may declare unique pointers to vectors as restartable data and never actually create
     328             :   // vector instances. This happens for example in the `TimeIntegrator` class where subvector
     329             :   // instances are only created if multiple time integrators are present
     330      163568 :   bool have_vector = v.get();
     331      163568 :   dataStore(stream, have_vector, context);
     332      163568 :   if (!have_vector)
     333      163558 :     return;
     334             : 
     335             :   mooseAssert(context, "Needs a context of the communicator");
     336          10 :   const auto & comm = *static_cast<const libMesh::Parallel::Communicator *>(context);
     337             :   mooseAssert(&comm == &v->comm(), "Inconsistent communicator");
     338             : 
     339          10 :   if (v->type() == GHOSTED)
     340           0 :     mooseError("Cannot store ghosted numeric vectors");
     341             : 
     342             :   // Store the communicator size for sanity checking later
     343          10 :   unsigned int comm_size = comm.size();
     344          10 :   dataStore(stream, comm_size, nullptr);
     345             : 
     346             :   // Store the solver package so that we know what vector type to construct
     347             :   libMesh::SolverPackage solver_package;
     348          10 :   if (dynamic_cast<libMesh::PetscVector<Number> *>(v.get()))
     349          10 :     solver_package = PETSC_SOLVERS;
     350             :   else
     351           0 :     mooseError("Can only store unique_ptrs of PetscVectors");
     352          10 :   int solver_package_int = solver_package;
     353          10 :   dataStore(stream, solver_package_int, nullptr);
     354             : 
     355             :   // Store the sizes
     356          10 :   dof_id_type size = v->size();
     357          10 :   dataStore(stream, size, nullptr);
     358          10 :   dof_id_type local_size = v->local_size();
     359          10 :   dataStore(stream, local_size, nullptr);
     360             : 
     361             :   // Store the vector itself
     362          10 :   dataStore(stream, *v, nullptr);
     363             : }
     364             : 
     365             : // global load functions
     366             : 
     367             : template <>
     368             : void
     369    14158213 : dataLoad(std::istream & stream, Real & v, void * /*context*/)
     370             : {
     371    14158213 :   stream.read((char *)&v, sizeof(v));
     372    14158213 : }
     373             : 
     374             : template <>
     375             : void
     376     8216747 : dataLoad(std::istream & stream, std::string & v, void * /*context*/)
     377             : {
     378             :   // Read the size of the string
     379     8216747 :   unsigned int size = 0;
     380     8216747 :   stream.read((char *)&size, sizeof(size));
     381             : 
     382             :   // Resize the string data
     383     8216747 :   v.resize(size);
     384             : 
     385             :   // Read the string
     386     8216747 :   stream.read(&v[0], sizeof(char) * size);
     387     8216747 : }
     388             : 
     389             : template <>
     390             : void
     391           0 : dataLoad(std::istream & stream, VariableName & v, void * context)
     392             : {
     393           0 :   auto & name = static_cast<std::string &>(v);
     394           0 :   dataLoad(stream, name, context);
     395           0 : }
     396             : 
     397             : template <>
     398             : void
     399           0 : dataLoad(std::istream & stream, UserObjectName & v, void * context)
     400             : {
     401           0 :   auto & name = static_cast<std::string &>(v);
     402           0 :   dataLoad(stream, name, context);
     403           0 : }
     404             : 
     405             : template <>
     406             : void
     407     3054229 : dataLoad(std::istream & stream, bool & v, void * /*context*/)
     408             : {
     409     3054229 :   stream.read((char *)&v, sizeof(v));
     410     3054229 : }
     411             : 
     412             : template <>
     413             : void
     414       28229 : dataLoad(std::istream & stream, FEType & v, void * context)
     415             : {
     416       28229 :   int order = 0;
     417       28229 :   dataLoad(stream, order, context);
     418       28229 :   v.order = order;
     419             : 
     420       28229 :   dataLoad(stream, v.family, context);
     421             : 
     422             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     423             :   int radial_order = 0;
     424             :   dataLoad(stream, radial_order, context);
     425             :   v.radial_order = radial_order;
     426             : 
     427             :   dataLoad(stream, v.radial_family, context);
     428             :   dataLoad(stream, v.inf_map, context);
     429             : #endif
     430             : 
     431       28229 :   dataLoad(stream, v.p_refinement, context);
     432       28229 : }
     433             : 
     434             : template <>
     435             : void
     436           0 : dataLoad(std::istream & stream, std::vector<bool> & v, void * context)
     437             : {
     438           0 :   for (bool b : v)
     439           0 :     dataLoad(stream, b, context);
     440           0 : }
     441             : 
     442             : template <>
     443             : void
     444           0 : dataLoad(std::istream & stream, ADReal & dn, void * context)
     445             : {
     446           0 :   dataLoad(stream, dn.value(), context);
     447             : 
     448           0 :   if (ADReal::do_derivatives)
     449             :   {
     450           0 :     auto & derivatives = dn.derivatives();
     451           0 :     std::size_t size = 0;
     452           0 :     stream.read((char *)&size, sizeof(size));
     453           0 :     derivatives.resize(size);
     454             : 
     455           0 :     for (MooseIndex(derivatives) i = 0; i < derivatives.size(); ++i)
     456             :     {
     457           0 :       dataLoad(stream, derivatives.raw_index(i), context);
     458           0 :       dataLoad(stream, derivatives.raw_at(i), context);
     459             :     }
     460             :   }
     461           0 : }
     462             : 
     463             : template <>
     464             : void
     465       15206 : dataLoad(std::istream & stream, const Elem *& e, void * context)
     466             : {
     467       15206 :   if (!context)
     468           0 :     mooseError("Can only load Elem objects using a MooseMesh context!");
     469             : 
     470       15206 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     471             : 
     472             :   // TODO: Write out the unique ID of this element
     473       15206 :   dof_id_type id = libMesh::DofObject::invalid_id;
     474             : 
     475       15206 :   loadHelper(stream, id, context);
     476             : 
     477       15206 :   if (id != libMesh::DofObject::invalid_id)
     478       15206 :     e = mesh->elemPtr(id);
     479             :   else
     480           0 :     e = NULL;
     481       15206 : }
     482             : 
     483             : template <>
     484             : void
     485         545 : dataLoad(std::istream & stream, const Node *& n, void * context)
     486             : {
     487         545 :   if (!context)
     488           0 :     mooseError("Can only load Node objects using a MooseMesh context!");
     489             : 
     490         545 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     491             : 
     492             :   // TODO: Write out the unique ID of this nodeent
     493         545 :   dof_id_type id = libMesh::DofObject::invalid_id;
     494             : 
     495         545 :   loadHelper(stream, id, context);
     496             : 
     497         545 :   if (id != libMesh::DofObject::invalid_id)
     498         545 :     n = mesh->nodePtr(id);
     499             :   else
     500           0 :     n = NULL;
     501         545 : }
     502             : 
     503             : template <>
     504             : void
     505           0 : dataLoad(std::istream & stream, Elem *& e, void * context)
     506             : {
     507           0 :   if (!context)
     508           0 :     mooseError("Can only load Elem objects using a MooseMesh context!");
     509             : 
     510           0 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     511             : 
     512             :   // TODO: Write out the unique ID of this element
     513           0 :   dof_id_type id = libMesh::DofObject::invalid_id;
     514             : 
     515           0 :   loadHelper(stream, id, context);
     516             : 
     517           0 :   if (id != libMesh::DofObject::invalid_id)
     518           0 :     e = mesh->elemPtr(id);
     519             :   else
     520           0 :     e = NULL;
     521           0 : }
     522             : 
     523             : template <>
     524             : void
     525           0 : dataLoad(std::istream & stream, Node *& n, void * context)
     526             : {
     527           0 :   if (!context)
     528           0 :     mooseError("Can only load Node objects using a MooseMesh context!");
     529             : 
     530           0 :   MooseMesh * mesh = static_cast<MooseMesh *>(context);
     531             : 
     532             :   // TODO: Write out the unique ID of this nodeent
     533           0 :   dof_id_type id = libMesh::DofObject::invalid_id;
     534             : 
     535           0 :   loadHelper(stream, id, context);
     536             : 
     537           0 :   if (id != libMesh::DofObject::invalid_id)
     538           0 :     n = mesh->nodePtr(id);
     539             :   else
     540           0 :     n = NULL;
     541           0 : }
     542             : 
     543             : template <>
     544             : void
     545       16513 : dataLoad(std::istream & stream, std::stringstream & s, void * /* context */)
     546             : {
     547       16513 :   size_t s_size = 0;
     548       16513 :   stream.read((char *)&s_size, sizeof(s_size));
     549             : 
     550       16513 :   std::unique_ptr<char[]> s_s = std::make_unique<char[]>(s_size);
     551       16513 :   stream.read(s_s.get(), s_size);
     552             : 
     553             :   // Clear the stringstream before loading new data into it.
     554       16513 :   s.str(std::string());
     555       16513 :   s.write(s_s.get(), s_size);
     556       16513 : }
     557             : 
     558             : template <typename T>
     559             : void
     560           0 : dataLoad(std::istream & stream, TensorValue<T> & v, void * context)
     561             : {
     562             :   // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
     563             :   // won't work.
     564           0 :   for (const auto i : make_range(Moose::dim))
     565           0 :     for (const auto j : make_range(Moose::dim))
     566             :     {
     567           0 :       T r = 0;
     568           0 :       dataLoad(stream, r, context);
     569           0 :       v(i, j) = r;
     570             :     }
     571           0 : }
     572             : 
     573             : template void dataLoad(std::istream & stream, TensorValue<Real> & v, void * context);
     574             : template void dataLoad(std::istream & stream, TensorValue<ADReal> & v, void * context);
     575             : 
     576             : template <typename T>
     577             : void
     578          68 : dataLoad(std::istream & stream, DenseMatrix<T> & v, void * context)
     579             : {
     580          68 :   unsigned int m = 0, n = 0;
     581          68 :   stream.read((char *)&m, sizeof(m));
     582          68 :   stream.read((char *)&n, sizeof(n));
     583          68 :   v.resize(m, n);
     584         204 :   for (unsigned int i = 0; i < m; i++)
     585         544 :     for (unsigned int j = 0; j < n; j++)
     586             :     {
     587         408 :       T r = 0;
     588         408 :       dataLoad(stream, r, context);
     589         408 :       v(i, j) = r;
     590             :     }
     591          68 : }
     592             : 
     593             : template void dataLoad(std::istream & stream, DenseMatrix<Real> & v, void * context);
     594             : template void dataLoad(std::istream & stream, DenseMatrix<ADReal> & v, void * context);
     595             : 
     596             : template <typename T>
     597             : void
     598       12699 : dataLoad(std::istream & stream, VectorValue<T> & v, void * context)
     599             : {
     600             :   // Obviously if someone loads data with different LIBMESH_DIM than was used for saving them, it
     601             :   // won't work.
     602       50796 :   for (const auto i : make_range(Moose::dim))
     603             :   {
     604       38097 :     T r = 0;
     605       38097 :     dataLoad(stream, r, context);
     606       38097 :     v(i) = r;
     607             :   }
     608       12699 : }
     609             : 
     610             : template void dataLoad(std::istream & stream, VectorValue<Real> & v, void * context);
     611             : template void dataLoad(std::istream & stream, VectorValue<ADReal> & v, void * context);
     612             : 
     613             : void
     614           0 : dataLoad(std::istream & stream, Point & p, void * context)
     615             : {
     616           0 :   for (const auto i : make_range(Moose::dim))
     617             :   {
     618           0 :     Real r = 0;
     619           0 :     dataLoad(stream, r, context);
     620           0 :     p(i) = r;
     621             :   }
     622           0 : }
     623             : 
     624             : template <>
     625             : void
     626          68 : dataLoad(std::istream & stream, libMesh::Parameters & p, void * context)
     627             : {
     628          68 :   p.clear();
     629             : 
     630             :   // First read the size of the map
     631          68 :   unsigned int size = 0;
     632          68 :   stream.read((char *)&size, sizeof(size));
     633             : 
     634         272 :   for (unsigned int i = 0; i < size; i++)
     635             :   {
     636         204 :     std::string key, type;
     637         204 :     loadHelper(stream, key, context);
     638         204 :     loadHelper(stream, type, context);
     639             : 
     640             : #define loadscalar(ptype)                                                                          \
     641             :   else if (type == demangle(typeid(ptype).name())) do                                              \
     642             :   {                                                                                                \
     643             :     ptype & value = p.set<ptype>(key);                                                             \
     644             :     loadHelper(stream, value, context);                                                            \
     645             :   }                                                                                                \
     646             :   while (0)
     647             : 
     648             :     if (false)
     649             :       ;
     650         204 :     loadscalar(Real);
     651         136 :     loadscalar(short);
     652         136 :     loadscalar(int);
     653          68 :     loadscalar(long);
     654          68 :     loadscalar(unsigned short);
     655          68 :     loadscalar(unsigned int);
     656           0 :     loadscalar(unsigned long);
     657             : 
     658             : #undef loadscalar
     659         204 :   }
     660          68 : }
     661             : 
     662             : template <>
     663             : void
     664       44728 : dataLoad(std::istream & stream, std::unique_ptr<libMesh::NumericVector<Number>> & v, void * context)
     665             : {
     666             :   bool have_vector;
     667       44728 :   dataLoad(stream, have_vector, context);
     668             : 
     669       44728 :   if (!have_vector)
     670       44720 :     return;
     671             : 
     672             :   mooseAssert(context, "Needs a context of the communicator");
     673           8 :   const auto & comm = *static_cast<const libMesh::Parallel::Communicator *>(context);
     674           8 :   if (v)
     675             :     mooseAssert(&comm == &v->comm(), "Inconsistent communicator");
     676             : 
     677             :   // Load the communicator size for consistency checks
     678             :   unsigned int comm_size;
     679           8 :   dataLoad(stream, comm_size, nullptr);
     680             :   mooseAssert(comm.size() == comm_size, "Inconsistent communicator size");
     681             : 
     682             :   // Load the solver package to build the vector
     683             :   int solver_package_int;
     684           8 :   dataLoad(stream, solver_package_int, nullptr);
     685           8 :   libMesh::SolverPackage solver_package = static_cast<libMesh::SolverPackage>(solver_package_int);
     686             : 
     687             :   // Load the sizes
     688             :   dof_id_type size, local_size;
     689           8 :   dataLoad(stream, size, nullptr);
     690           8 :   dataLoad(stream, local_size, nullptr);
     691             : 
     692             :   // Construct the vector given the type, only if we need to. v could be non-null here
     693             :   // if we're advancing back and loading a backup
     694           8 :   if (!v)
     695             :   {
     696           6 :     v = NumericVector<Number>::build(comm, solver_package);
     697           6 :     v->init(size, local_size);
     698             :   }
     699             :   else
     700             :     mooseAssert(v->type() != GHOSTED, "Cannot be ghosted");
     701             : 
     702             :   // Make sure that the sizes are consistent; this will happen if we're calling this
     703             :   // on a vector that has already been loaded previously
     704             :   mooseAssert(v->size() == size, "Inconsistent size");
     705             :   mooseAssert(v->local_size() == local_size, "Inconsistent local size");
     706             : 
     707             :   // Now that we have an initialized vector, fill the entries
     708           8 :   dataLoad(stream, *v, nullptr);
     709             : }
     710             : 
     711             : template <>
     712             : void
     713           0 : dataLoad(std::istream & stream, Vec & v, void * context)
     714             : {
     715             :   PetscInt local_size;
     716           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetLocalSize(v, &local_size));
     717             :   PetscScalar * array;
     718           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetArray(v, &array));
     719           0 :   for (PetscInt i = 0; i < local_size; i++)
     720           0 :     dataLoad(stream, array[i], context);
     721             : 
     722           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecRestoreArray(v, &array));
     723           0 : }
     724             : 
     725             : template <>
     726             : void
     727           0 : dataStore(std::ostream & stream, Vec & v, void * context)
     728             : {
     729             :   PetscInt local_size;
     730           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetLocalSize(v, &local_size));
     731             :   PetscScalar * array;
     732           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecGetArray(v, &array));
     733           0 :   for (PetscInt i = 0; i < local_size; i++)
     734           0 :     dataStore(stream, array[i], context);
     735             : 
     736           0 :   LibmeshPetscCallA(PETSC_COMM_WORLD, VecRestoreArray(v, &array));
     737           0 : }

Generated by: LCOV version 1.14