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