https://mooseframework.inl.gov
Loading...
Searching...
No Matches
RestartableDataWriter.C
Go to the documentation of this file.
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
11
12#include "DataIO.h"
13#include "RestartableDataMap.h"
14
15#include <fstream>
16#include <system_error>
17
22
23RestartableDataWriter::RestartableDataWriter(MooseApp & app, std::vector<RestartableDataMap> & data)
24 : RestartableDataIO(app, data)
25{
26}
27
28void
29RestartableDataWriter::write(std::ostream & header_stream, std::ostream & data_stream)
30{
31 // Set everything as not stored
32 for (const auto tid : make_range(dataSize()))
33 for (auto & value : currentData(tid))
34 value.setNotStored({});
35
36 // Header
37 char id[] = {'R', 'D'};
38 header_stream.write(id, 2);
39
40 // File version
41 auto file_version = CURRENT_BACKUP_FILE_VERSION;
42 dataStore(header_stream, file_version, nullptr);
43
44 // Type hash for basic hash
45 std::size_t compare_hash_code = typeid(COMPARE_HASH_CODE_TYPE).hash_code();
46 dataStore(header_stream, compare_hash_code, nullptr);
47
48 // Number of procs
49 auto n_procs = n_processors();
50 dataStore(header_stream, n_procs, nullptr);
51
52 // Number of data
53 auto num_data = dataSize();
54 dataStore(header_stream, num_data, nullptr);
55
56 // Size of data for each thread
57 for (const auto tid : make_range(dataSize()))
58 {
59 std::size_t n_data = currentData(tid).size();
60 dataStore(header_stream, n_data, nullptr);
61 }
62
63 // Write out the RestartableData header, and store the actual data separately
64 for (const auto tid : make_range(dataSize()))
65 for (auto & data : currentData(tid))
66 {
67 // Store the data
68 const std::size_t data_start_position = static_cast<std::size_t>(data_stream.tellp());
69 data.store(data_stream);
70 std::size_t data_size = static_cast<std::size_t>(data_stream.tellp()) - data_start_position;
71
72 // Store name, size, type hash, and type in the header
73 mooseAssert(data.name().size(), "Empty name");
74 std::string name = data.name();
75 std::string type = data.typeId().name();
76 std::size_t type_hash_code = data.typeId().hash_code();
77 bool has_context = data.hasContext();
78 dataStore(header_stream, name, nullptr);
79 dataStore(header_stream, data_size, nullptr);
80 dataStore(header_stream, type_hash_code, nullptr);
81 dataStore(header_stream, type, nullptr);
82 dataStore(header_stream, has_context, nullptr);
83 }
84}
85
86std::vector<std::filesystem::path>
87RestartableDataWriter::write(const std::filesystem::path & folder_base)
88{
89 const auto header_file = restartableHeaderFile(folder_base);
90 const auto data_file = restartableDataFile(folder_base);
91
92 // Make the folder if it doesn't exist
93 const auto dir = header_file.parent_path();
94 mooseAssert(dir == data_file.parent_path(), "Inconsistent directories");
95 if (!std::filesystem::exists(dir))
96 {
97 std::error_code err;
98 if (!std::filesystem::create_directory(dir, err))
99 mooseError("Unable to create restart directory\n",
100 std::filesystem::absolute(dir),
101 "\n\n",
102 err.message());
103 }
104
105 // We want to keep track of the paths that we create so that we can
106 // return them for file management later (primarily removing old checkpoints)
107 std::vector<std::filesystem::path> paths;
108
109 // Helper for opening a stream for use
110 auto open = [&paths](const std::filesystem::path & filename)
111 {
112 std::ofstream stream;
113 stream.open(filename.c_str(), std::ios::out | std::ios::binary);
114 if (!stream.is_open())
116 "Unable to open restart file ", std::filesystem::absolute(filename), " for writing");
117 paths.push_back(filename);
118 return stream;
119 };
120
121 // Open and write
122 auto header_stream = open(header_file);
123 auto data_stream = open(data_file);
124 write(header_stream, data_stream);
125
126 // Update the folder's modified time to now for consistency
127 // (this used in checking for the latest checkpoint)
128 const auto data_write_time = std::filesystem::last_write_time(header_file);
129 std::filesystem::last_write_time(dir, data_write_time);
130
131 return paths;
132}
void dataStore(std::ostream &stream, LineSegment &l, void *context)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
for(PetscInt i=0;i< nvars;++i)
Base class for MOOSE-based applications.
Definition MooseApp.h:110
Class for doing restart.
static const std::string & restartableDataFile()
static const std::string & restartableHeaderFile()
RestartableDataMap & currentData(const THREAD_ID tid)
std::size_t dataSize() const
Storage for restartable data that is ordered based on insertion order.
void write(std::ostream &header_stream, std::ostream &data_stream)
Writes the restartable data to header stream header_stream and data stream data_stream.
RestartableDataWriter(MooseApp &app, RestartableDataMap &data)
std::string name(const ElemQuality q)
IntRange< T > make_range(T beg, T end)