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