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