www.mooseframework.org
DataIO.h
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #ifndef DATAIO_H
16 #define DATAIO_H
17 
18 // MOOSE includes
19 #include "MooseTypes.h"
20 #include "HashMap.h"
21 #include "MooseError.h"
22 #include "Backup.h"
23 
24 #include "libmesh/vector_value.h"
25 #include "libmesh/tensor_value.h"
26 #include "libmesh/parallel.h"
27 #ifdef LIBMESH_HAVE_CXX11_TYPE_TRAITS
28 #include <type_traits>
29 #endif
30 
31 // C++ includes
32 #include <string>
33 #include <vector>
34 #include <list>
35 #include <iostream>
36 #include <map>
37 #include <unordered_map>
38 
39 // Forward declarations
40 class ColumnMajorMatrix;
41 namespace libMesh
42 {
43 template <typename T>
44 class NumericVector;
45 template <typename T>
47 template <typename T>
48 class DenseVector;
49 class Elem;
50 }
51 
55 template <typename P>
56 inline void storeHelper(std::ostream & stream, P & data, void * context);
57 
61 template <typename P>
62 inline void storeHelper(std::ostream & stream, std::vector<P> & data, void * context);
63 
67 template <typename P>
68 inline void storeHelper(std::ostream & stream, std::shared_ptr<P> & data, void * context);
69 
73 template <typename P>
74 inline void storeHelper(std::ostream & stream, std::unique_ptr<P> & data, void * context);
75 
79 template <typename P>
80 inline void storeHelper(std::ostream & stream, std::set<P> & data, void * context);
81 
85 template <typename P, typename Q>
86 inline void storeHelper(std::ostream & stream, std::map<P, Q> & data, void * context);
87 
91 template <typename P, typename Q>
92 inline void storeHelper(std::ostream & stream, std::unordered_map<P, Q> & data, void * context);
93 
97 template <typename P, typename Q>
98 inline void storeHelper(std::ostream & stream, HashMap<P, Q> & data, void * context);
99 
103 template <typename P>
104 inline void loadHelper(std::istream & stream, P & data, void * context);
105 
109 template <typename P>
110 inline void loadHelper(std::istream & stream, std::vector<P> & data, void * context);
111 
115 template <typename P>
116 inline void loadHelper(std::istream & stream, std::shared_ptr<P> & data, void * context);
117 
121 template <typename P>
122 inline void loadHelper(std::istream & stream, std::unique_ptr<P> & data, void * context);
123 
127 template <typename P>
128 inline void loadHelper(std::istream & stream, std::set<P> & data, void * context);
129 
133 template <typename P, typename Q>
134 inline void loadHelper(std::istream & stream, std::map<P, Q> & data, void * context);
135 
139 template <typename P, typename Q>
140 inline void loadHelper(std::istream & stream, std::unordered_map<P, Q> & data, void * context);
141 
145 template <typename P, typename Q>
146 inline void loadHelper(std::istream & stream, HashMap<P, Q> & data, void * context);
147 
148 template <typename T>
149 inline void dataStore(std::ostream & stream, T & v, void * /*context*/);
150 
151 // global store functions
152 
153 template <typename T>
154 inline void
155 dataStore(std::ostream & stream, T & v, void * /*context*/)
156 {
157 #ifdef LIBMESH_HAVE_CXX11_TYPE_TRAITS
158  static_assert(std::is_polymorphic<T>::value == false,
159  "Cannot serialize a class that has virtual "
160  "members!\nWrite a custom dataStore() "
161  "template specialization!\n\n");
162  static_assert(std::is_trivially_copyable<T>::value || std::is_same<T, Point>::value,
163  "Cannot serialize a class that is not trivially copyable!\nWrite a custom "
164  "dataStore() template specialization!\n\n");
165 #endif
166 
167  // Moose::out<<"Generic dataStore"<<std::endl;
168  stream.write((char *)&v, sizeof(v));
169 }
170 
171 template <typename T>
172 inline void
173 dataStore(std::ostream & /*stream*/, T *& /*v*/, void * /*context*/)
174 {
175  mooseError("Attempting to store a raw pointer type: \"",
176  demangle(typeid(T).name()),
177  " *\" as restartable data!\nWrite a custom dataStore() template specialization!\n\n");
178 }
179 
180 template <typename T, typename U>
181 inline void
182 dataStore(std::ostream & stream, std::pair<T, U> & p, void * context)
183 {
184  storeHelper(stream, p.first, context);
185  storeHelper(stream, p.second, context);
186 }
187 
188 template <typename T>
189 inline void
190 dataStore(std::ostream & stream, std::vector<T> & v, void * context)
191 {
192  // First store the size of the vector
193  unsigned int size = v.size();
194  stream.write((char *)&size, sizeof(size));
195 
196  for (unsigned int i = 0; i < size; i++)
197  storeHelper(stream, v[i], context);
198 }
199 
200 template <typename T>
201 inline void
202 dataStore(std::ostream & stream, std::shared_ptr<T> & v, void * context)
203 {
204  T * tmp = v.get();
205 
206  storeHelper(stream, tmp, context);
207 }
208 
209 template <typename T>
210 inline void
211 dataStore(std::ostream & stream, std::unique_ptr<T> & v, void * context)
212 {
213  T * tmp = v.get();
214 
215  storeHelper(stream, tmp, context);
216 }
217 
218 template <typename T>
219 inline void
220 dataStore(std::ostream & stream, std::set<T> & s, void * context)
221 {
222  // First store the size of the set
223  unsigned int size = s.size();
224  stream.write((char *)&size, sizeof(size));
225 
226  typename std::set<T>::iterator it = s.begin();
227  typename std::set<T>::iterator end = s.end();
228 
229  for (; it != end; ++it)
230  {
231  T & x = const_cast<T &>(*it);
232  storeHelper(stream, x, context);
233  }
234 }
235 
236 template <typename T>
237 inline void
238 dataStore(std::ostream & stream, std::list<T> & l, void * context)
239 {
240  // First store the size of the set
241  unsigned int size = l.size();
242  stream.write((char *)&size, sizeof(size));
243 
244  typename std::list<T>::iterator it = l.begin();
245  typename std::list<T>::iterator end = l.end();
246 
247  for (; it != end; ++it)
248  {
249  T & x = const_cast<T &>(*it);
250  storeHelper(stream, x, context);
251  }
252 }
253 
254 template <typename T, typename U>
255 inline void
256 dataStore(std::ostream & stream, std::map<T, U> & m, void * context)
257 {
258  // First store the size of the map
259  unsigned int size = m.size();
260  stream.write((char *)&size, sizeof(size));
261 
262  typename std::map<T, U>::iterator it = m.begin();
263  typename std::map<T, U>::iterator end = m.end();
264 
265  for (; it != end; ++it)
266  {
267  T & key = const_cast<T &>(it->first);
268 
269  storeHelper(stream, key, context);
270 
271  storeHelper(stream, it->second, context);
272  }
273 }
274 
275 template <typename T, typename U>
276 inline void
277 dataStore(std::ostream & stream, std::unordered_map<T, U> & m, void * context)
278 {
279  // First store the size of the map
280  unsigned int size = m.size();
281  stream.write((char *)&size, sizeof(size));
282 
283  typename std::unordered_map<T, U>::iterator it = m.begin();
284  typename std::unordered_map<T, U>::iterator end = m.end();
285 
286  for (; it != end; ++it)
287  {
288  T & key = const_cast<T &>(it->first);
289 
290  storeHelper(stream, key, context);
291 
292  storeHelper(stream, it->second, context);
293  }
294 }
295 
296 template <typename T, typename U>
297 inline void
298 dataStore(std::ostream & stream, HashMap<T, U> & m, void * context)
299 {
300  // First store the size of the map
301  unsigned int size = m.size();
302  stream.write((char *)&size, sizeof(size));
303 
304  typename HashMap<T, U>::iterator it = m.begin();
305  typename HashMap<T, U>::iterator end = m.end();
306 
307  for (; it != end; ++it)
308  {
309  T & key = const_cast<T &>(it->first);
310 
311  storeHelper(stream, key, context);
312 
313  storeHelper(stream, it->second, context);
314  }
315 }
316 
317 // Specializations (defined in .C)
318 template <>
319 void dataStore(std::ostream & stream, Real & v, void * /*context*/);
320 template <>
321 void dataStore(std::ostream & stream, std::string & v, void * /*context*/);
322 template <>
323 void dataStore(std::ostream & stream, NumericVector<Real> & v, void * /*context*/);
324 template <>
325 void dataStore(std::ostream & stream, DenseVector<Real> & v, void * /*context*/);
326 template <>
327 void dataStore(std::ostream & stream, DenseMatrix<Real> & v, void * /*context*/);
328 template <>
329 void dataStore(std::ostream & stream, ColumnMajorMatrix & v, void * /*context*/);
330 template <>
331 void dataStore(std::ostream & stream, RealTensorValue & v, void * /*context*/);
332 template <>
333 void dataStore(std::ostream & stream, RealVectorValue & v, void * /*context*/);
334 template <>
335 void dataStore(std::ostream & stream, const Elem *& e, void * context);
336 template <>
337 void dataStore(std::ostream & stream, const Node *& n, void * context);
338 template <>
339 void dataStore(std::ostream & stream, Elem *& e, void * context);
340 template <>
341 void dataStore(std::ostream & stream, Node *& n, void * context);
342 template <>
343 void dataStore(std::ostream & stream, std::stringstream & s, void * context);
344 template <>
345 void dataStore(std::ostream & stream, std::stringstream *& s, void * context);
346 
347 // global load functions
348 
349 template <typename T>
350 inline void
351 dataLoad(std::istream & stream, T & v, void * /*context*/)
352 {
353  stream.read((char *)&v, sizeof(v));
354 }
355 
356 template <typename T>
357 void
358 dataLoad(std::istream & /*stream*/, T *& /*v*/, void * /*context*/)
359 {
360  mooseError("Attempting to load a raw pointer type: \"",
361  demangle(typeid(T).name()),
362  " *\" as restartable data!\nWrite a custom dataLoad() template specialization!\n\n");
363 }
364 
365 template <typename T, typename U>
366 inline void
367 dataLoad(std::istream & stream, std::pair<T, U> & p, void * context)
368 {
369  loadHelper(stream, p.first, context);
370  loadHelper(stream, p.second, context);
371 }
372 
373 template <typename T>
374 inline void
375 dataLoad(std::istream & stream, std::vector<T> & v, void * context)
376 {
377  // First read the size of the vector
378  unsigned int size = 0;
379  stream.read((char *)&size, sizeof(size));
380 
381  v.resize(size);
382 
383  for (unsigned int i = 0; i < size; i++)
384  loadHelper(stream, v[i], context);
385 }
386 
387 template <typename T>
388 inline void
389 dataLoad(std::istream & stream, std::shared_ptr<T> & v, void * context)
390 {
391  T * tmp = v.get();
392 
393  loadHelper(stream, tmp, context);
394 }
395 
396 template <typename T>
397 inline void
398 dataLoad(std::istream & stream, std::unique_ptr<T> & v, void * context)
399 {
400  T * tmp = v.get();
401 
402  loadHelper(stream, tmp, context);
403 }
404 
405 template <typename T>
406 inline void
407 dataLoad(std::istream & stream, std::set<T> & s, void * context)
408 {
409  // First read the size of the set
410  unsigned int size = 0;
411  stream.read((char *)&size, sizeof(size));
412 
413  for (unsigned int i = 0; i < size; i++)
414  {
415  T data;
416  loadHelper(stream, data, context);
417  s.insert(std::move(data));
418  }
419 }
420 
421 template <typename T>
422 inline void
423 dataLoad(std::istream & stream, std::list<T> & l, void * context)
424 {
425  // First read the size of the set
426  unsigned int size = 0;
427  stream.read((char *)&size, sizeof(size));
428 
429  for (unsigned int i = 0; i < size; i++)
430  {
431  T data;
432  loadHelper(stream, data, context);
433  l.push_back(std::move(data));
434  }
435 }
436 
437 template <typename T, typename U>
438 inline void
439 dataLoad(std::istream & stream, std::map<T, U> & m, void * context)
440 {
441  m.clear();
442 
443  // First read the size of the map
444  unsigned int size = 0;
445  stream.read((char *)&size, sizeof(size));
446 
447  for (unsigned int i = 0; i < size; i++)
448  {
449  T key;
450  loadHelper(stream, key, context);
451 
452  U & value = m[key];
453  loadHelper(stream, value, context);
454  }
455 }
456 
457 template <typename T, typename U>
458 inline void
459 dataLoad(std::istream & stream, std::unordered_map<T, U> & m, void * context)
460 {
461  m.clear();
462 
463  // First read the size of the map
464  unsigned int size = 0;
465  stream.read((char *)&size, sizeof(size));
466 
467  for (unsigned int i = 0; i < size; i++)
468  {
469  T key;
470  loadHelper(stream, key, context);
471 
472  U & value = m[key];
473  loadHelper(stream, value, context);
474  }
475 }
476 
477 template <typename T, typename U>
478 inline void
479 dataLoad(std::istream & stream, HashMap<T, U> & m, void * context)
480 {
481  // First read the size of the map
482  unsigned int size = 0;
483  stream.read((char *)&size, sizeof(size));
484 
485  for (unsigned int i = 0; i < size; i++)
486  {
487  T key;
488  loadHelper(stream, key, context);
489 
490  U & value = m[key];
491  loadHelper(stream, value, context);
492  }
493 }
494 
495 // Specializations (defined in .C)
496 template <>
497 void dataLoad(std::istream & stream, Real & v, void * /*context*/);
498 template <>
499 void dataLoad(std::istream & stream, std::string & v, void * /*context*/);
500 template <>
501 void dataLoad(std::istream & stream, NumericVector<Real> & v, void * /*context*/);
502 template <>
503 void dataLoad(std::istream & stream, DenseVector<Real> & v, void * /*context*/);
504 template <>
505 void dataLoad(std::istream & stream, DenseMatrix<Real> & v, void * /*context*/);
506 template <>
507 void dataLoad(std::istream & stream, ColumnMajorMatrix & v, void * /*context*/);
508 template <>
509 void dataLoad(std::istream & stream, RealTensorValue & v, void * /*context*/);
510 template <>
511 void dataLoad(std::istream & stream, RealVectorValue & v, void * /*context*/);
512 template <>
513 void dataLoad(std::istream & stream, const Elem *& e, void * context);
514 template <>
515 void dataLoad(std::istream & stream, const Node *& e, void * context);
516 template <>
517 void dataLoad(std::istream & stream, Elem *& e, void * context);
518 template <>
519 void dataLoad(std::istream & stream, Node *& e, void * context);
520 template <>
521 void dataLoad(std::istream & stream, std::stringstream & s, void * context);
522 template <>
523 void dataLoad(std::istream & stream, std::stringstream *& s, void * context);
524 
525 // Scalar Helper Function
526 template <typename P>
527 inline void
528 storeHelper(std::ostream & stream, P & data, void * context)
529 {
530  dataStore(stream, data, context);
531 }
532 
533 // Vector Helper Function
534 template <typename P>
535 inline void
536 storeHelper(std::ostream & stream, std::vector<P> & data, void * context)
537 {
538  dataStore(stream, data, context);
539 }
540 
541 // std::shared_ptr Helper Function
542 template <typename P>
543 inline void
544 storeHelper(std::ostream & stream, std::shared_ptr<P> & data, void * context)
545 {
546  dataStore(stream, data, context);
547 }
548 
549 // std::unique Helper Function
550 template <typename P>
551 inline void
552 storeHelper(std::ostream & stream, std::unique_ptr<P> & data, void * context)
553 {
554  dataStore(stream, data, context);
555 }
556 
557 // Set Helper Function
558 template <typename P>
559 inline void
560 storeHelper(std::ostream & stream, std::set<P> & data, void * context)
561 {
562  dataStore(stream, data, context);
563 }
564 
565 // Map Helper Function
566 template <typename P, typename Q>
567 inline void
568 storeHelper(std::ostream & stream, std::map<P, Q> & data, void * context)
569 {
570  dataStore(stream, data, context);
571 }
572 
573 // Unordered_map Helper Function
574 template <typename P, typename Q>
575 inline void
576 storeHelper(std::ostream & stream, std::unordered_map<P, Q> & data, void * context)
577 {
578  dataStore(stream, data, context);
579 }
580 
581 // HashMap Helper Function
582 template <typename P, typename Q>
583 inline void
584 storeHelper(std::ostream & stream, HashMap<P, Q> & data, void * context)
585 {
586  dataStore(stream, data, context);
587 }
588 
589 // Scalar Helper Function
590 template <typename P>
591 inline void
592 loadHelper(std::istream & stream, P & data, void * context)
593 {
594  dataLoad(stream, data, context);
595 }
596 
597 // Vector Helper Function
598 template <typename P>
599 inline void
600 loadHelper(std::istream & stream, std::vector<P> & data, void * context)
601 {
602  dataLoad(stream, data, context);
603 }
604 
605 // std::shared_ptr Helper Function
606 template <typename P>
607 inline void
608 loadHelper(std::istream & stream, std::shared_ptr<P> & data, void * context)
609 {
610  dataLoad(stream, data, context);
611 }
612 
613 // Unique Pointer Helper Function
614 template <typename P>
615 inline void
616 loadHelper(std::istream & stream, std::unique_ptr<P> & data, void * context)
617 {
618  dataLoad(stream, data, context);
619 }
620 
621 // Set Helper Function
622 template <typename P>
623 inline void
624 loadHelper(std::istream & stream, std::set<P> & data, void * context)
625 {
626  dataLoad(stream, data, context);
627 }
628 
629 // Map Helper Function
630 template <typename P, typename Q>
631 inline void
632 loadHelper(std::istream & stream, std::map<P, Q> & data, void * context)
633 {
634  dataLoad(stream, data, context);
635 }
636 
637 // Unordered_map Helper Function
638 template <typename P, typename Q>
639 inline void
640 loadHelper(std::istream & stream, std::unordered_map<P, Q> & data, void * context)
641 {
642  dataLoad(stream, data, context);
643 }
644 
645 // HashMap Helper Function
646 template <typename P, typename Q>
647 inline void
648 loadHelper(std::istream & stream, HashMap<P, Q> & data, void * context)
649 {
650  dataLoad(stream, data, context);
651 }
652 
653 // Specializations for Backup type
654 template <>
655 inline void
656 dataStore(std::ostream & stream, Backup *& backup, void * context)
657 {
658  dataStore(stream, backup->_system_data, context);
659 
660  for (unsigned int i = 0; i < backup->_restartable_data.size(); i++)
661  dataStore(stream, backup->_restartable_data[i], context);
662 }
663 
664 template <>
665 inline void
666 dataLoad(std::istream & stream, Backup *& backup, void * context)
667 {
668  dataLoad(stream, backup->_system_data, context);
669 
670  for (unsigned int i = 0; i < backup->_restartable_data.size(); i++)
671  dataLoad(stream, backup->_restartable_data[i], context);
672 }
673 
680 namespace libMesh
681 {
682 namespace Parallel
683 {
684 template <typename T>
685 class Packing<std::basic_string<T>>
686 {
687 public:
688  static const unsigned int size_bytes = 4;
689 
690  typedef T buffer_type;
691 
692  static unsigned int get_string_len(typename std::vector<T>::const_iterator in)
693  {
694  unsigned int string_len = reinterpret_cast<const unsigned char &>(in[size_bytes - 1]);
695  for (signed int i = size_bytes - 2; i >= 0; --i)
696  {
697  string_len *= 256;
698  string_len += reinterpret_cast<const unsigned char &>(in[i]);
699  }
700  return string_len;
701  }
702 
703  static unsigned int packed_size(typename std::vector<T>::const_iterator in)
704  {
705  return get_string_len(in) + size_bytes;
706  }
707 
708  static unsigned int packable_size(const std::basic_string<T> & s, const void *)
709  {
710  return s.size() + size_bytes;
711  }
712 
713  template <typename Iter>
714  static void pack(const std::basic_string<T> & b, Iter data_out, const void *)
715  {
716  unsigned int string_len = b.size();
717  for (unsigned int i = 0; i != size_bytes; ++i)
718  {
719  *data_out++ = (string_len % 256);
720  string_len /= 256;
721  }
722 
723  std::copy(b.begin(), b.end(), data_out);
724  }
725 
726  static std::basic_string<T> unpack(typename std::vector<T>::const_iterator in, void *)
727  {
728  unsigned int string_len = get_string_len(in);
729 
730  std::ostringstream oss;
731  for (unsigned int i = 0; i < string_len; ++i)
732  oss << reinterpret_cast<const unsigned char &>(in[i + size_bytes]);
733 
734  in += size_bytes + string_len;
735 
736  return oss.str();
737  }
738 };
739 
740 } // namespace Parallel
741 
742 } // namespace libMesh
743 
744 #endif /* DATAIO_H */
VectorValue< Real > RealVectorValue
Definition: Assembly.h:40
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts...
Definition: HashMap.h:24
static std::basic_string< T > unpack(typename std::vector< T >::const_iterator in, void *)
Definition: DataIO.h:726
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
static unsigned int packable_size(const std::basic_string< T > &s, const void *)
Definition: DataIO.h:708
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
static PetscErrorCode Vec x
This class defines a Tensor that can change its shape.
std::stringstream _system_data
Definition: Backup.h:32
void storeHelper(std::ostream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:528
PetscInt m
static unsigned int packed_size(typename std::vector< T >::const_iterator in)
Definition: DataIO.h:703
std::vector< std::stringstream * > _restartable_data
Definition: Backup.h:34
void dataStore(std::ostream &stream, T &v, void *)
Definition: DataIO.h:155
static void pack(const std::basic_string< T > &b, Iter data_out, const void *)
Definition: DataIO.h:714
Helper class to hold streams for Backup and Restore operations.
Definition: Backup.h:25
PetscInt n
static unsigned int get_string_len(typename std::vector< T >::const_iterator in)
Definition: DataIO.h:692
void dataLoad(std::istream &stream, T &v, void *)
Definition: DataIO.h:351
TensorValue< Real > RealTensorValue
Definition: Assembly.h:45
void loadHelper(std::istream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:592