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 : }
|