18namespace fs = std::filesystem;
25 explicit Impl(
const fs::path &path) :
file(path.string(), h5pp::FileAccess::REPLACE) {}
31 fs::path temporary_checkpoint_path(
const fs::path &path)
33 const auto stamp = std::chrono::high_resolution_clock::now().time_since_epoch().count();
34 return path.parent_path() / fmt::format(
".{}.{}.tmp", path.filename().string(), stamp);
37 std::string resource_destination(
const std::string &logical)
41 const size_t start = logical.find_first_not_of(
'/');
42 if (start == std::string::npos || logical ==
".")
43 return "/resources/tree";
44 return "/resources/tree/" + logical.substr(start);
48 std::pair<std::vector<T>, std::vector<long>> pack_ragged(
const std::vector<std::vector<T>> &rows)
50 std::pair<std::vector<T>, std::vector<long>> packed;
51 packed.second.reserve(rows.size() + 1);
52 packed.second.push_back(0);
53 for (
const auto &row : rows)
55 packed.first.insert(packed.first.end(), row.begin(), row.end());
56 packed.second.push_back(packed.first.size());
61 Eigen::MatrixXi pack_padded(
const std::vector<std::vector<int>> &rows)
64 for (
const auto &row : rows)
65 width = std::max(width, int(row.size()));
66 Eigen::MatrixXi packed = Eigen::MatrixXi::Constant(rows.size(), width, -1);
67 for (
int i = 0; i < rows.size(); ++i)
68 for (
int j = 0; j < rows[i].size(); ++j)
69 packed(i, j) = rows[i][j];
75 : path_(fs::absolute(
path).lexically_normal()), temporary_path_(temporary_checkpoint_path(path_))
79 fs::create_directories(
path_.parent_path());
82 write_long(
"/checkpoint/metadata/schema_version", metadata.schema_version);
83 write_string(
"/checkpoint/metadata/formulation", metadata.formulation);
84 write_long(
"/checkpoint/metadata/step", metadata.step);
85 write_double(
"/checkpoint/metadata/time", metadata.time);
87 write_long(
"/checkpoint/metadata/remaining_steps", metadata.remaining_steps);
88 write_long(
"/checkpoint/metadata/output_index", metadata.output_index);
97 std::error_code error;
149 write_vector(group +
"/higher_order_weights", packed.first);
155 const auto cell_faces = pack_ragged(data.
cell_faces);
163 std::transform(data.
cell_is_hex.begin(), data.
cell_is_hex.end(), is_hex.begin(), [](
const bool value) { return int(value); });
175 impl_->file.deleteLink(
"/resources/root");
177 const auto *hdf5 =
dynamic_cast<const HDF5IO *
>(&resources);
178 for (
const std::string &canonical : manifest)
180 const std::string destination = resource_destination(canonical);
182 if (
impl_->file.linkExists(destination))
184 if (!resources.
exists(canonical))
190 impl_->file.copyLinkFromFile(destination, hdf5->file_path(), hdf5->resolve(canonical));
195 impl_->file.createGroup(destination);
198 auto input = resources.
open(canonical,
true);
199 const std::vector<unsigned char> contents{
200 std::istreambuf_iterator<char>(*input), std::istreambuf_iterator<char>()};
212 std::error_code error;
217 error = std::error_code(GetLastError(), std::system_category());
227 :
path_(fs::absolute(path).lexically_normal()), io_(std::make_unique<
HDF5IO>(
path_))
229 const auto require = [&](
const std::string &key) {
230 if (!
io_->exists(key))
233 for (
const std::string &key : {
234 "/config",
"/checkpoint/metadata/schema_version",
"/checkpoint/metadata/formulation",
235 "/checkpoint/metadata/step",
"/checkpoint/metadata/time",
"/checkpoint/metadata/dt",
236 "/checkpoint/metadata/remaining_steps",
"/checkpoint/metadata/output_index",
237 "/checkpoint/meshes/active",
"/checkpoint/state",
"/resources/root"})
240 path_,
io_->read_string(
"/resources/root"),
path_.parent_path(),
"/resources/tree");
241 config_ = json::parse(
io_->read_string(
"/config"));
251 "Unsupported checkpoint schema {} in {}; expected {}.",
std::vector< Eigen::VectorXi > faces
const std::filesystem::path & path() const
CheckpointMetadata metadata_
std::filesystem::path path_
std::unique_ptr< mesh::Mesh > read_mesh(const std::string &path, bool non_conforming=false) const
CheckpointReader(const std::filesystem::path &path)
long read_long(const std::string &path) const
double read_double(const std::string &path) const
Eigen::MatrixXd read_matrix(const std::string &path) const
std::unique_ptr< const ResourceIO > resources_
std::unique_ptr< const HDF5IO > io_
Eigen::MatrixXi read_int_matrix(const std::string &path) const
std::vector< int > read_int_vector(const std::string &path) const
std::string read_string(const std::string &path) const
std::vector< double > read_vector(const std::string &path) const
std::vector< long > read_long_vector(const std::string &path) const
Impl(const fs::path &path)
std::unique_ptr< Impl > impl_
void write_matrix(const std::string &path, const Eigen::MatrixXd &value)
std::filesystem::path path_
void write_attribute(const std::string &path, const std::string &name, long value)
void write_double(const std::string &path, double value)
std::filesystem::path temporary_path_
void write_int_matrix(const std::string &path, const Eigen::MatrixXi &value)
void write_mesh(const std::string &group, const mesh::Mesh &mesh)
void write_bytes(const std::string &path, const std::vector< unsigned char > &value)
void write_long_vector(const std::string &path, const std::vector< long > &value)
CheckpointWriter(const std::filesystem::path &path, const json &config, const CheckpointMetadata &metadata)
void write_string(const std::string &path, const std::string &value)
void write_long(const std::string &path, long value)
void embed_resources(const ResourceIO &resources)
void write_int_vector(const std::string &path, const std::vector< int > &value)
void write_vector(const std::string &path, const std::vector< double > &value)
HDF5 logical paths always use POSIX separators and roots.
Read-only interface to a hierarchical collection of simulation resources.
std::vector< std::string > accessed_resources() const
A snapshot of canonical paths consumed so far, including solver setup.
virtual std::string canonical_path(const std::string &path) const =0
Absolute resource identity, independent of the active reader root.
virtual std::string describe(const std::string &path) const =0
virtual bool exists(const std::string &path) const =0
virtual std::unique_ptr< std::istream > open(const std::string &path, bool binary) const =0
virtual bool is_group(const std::string &path) const =0
Format-independent input used to construct a runtime Mesh.
bool has_polyhedral_topology() const
Eigen::MatrixXd higher_order_nodes
std::vector< std::vector< int > > higher_order_connectivity
std::vector< int > node_ids
std::vector< int > geometry_ids
std::vector< std::vector< int > > boundary_elements
std::vector< std::vector< int > > faces
Optional topology for arbitrary polyhedral cells.
std::vector< int > body_ids
bool elements_are_ordered
Whether each element row carries a format-defined local vertex order.
std::vector< int > boundary_ids
Eigen::MatrixXd cell_kernel_points
std::vector< std::vector< int > > cell_faces
std::vector< std::vector< int > > cell_face_orientations
std::vector< std::vector< double > > higher_order_weights
std::vector< bool > cell_is_hex
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
MeshData to_mesh_data() const
Capture the complete runtime mesh in the canonical, format-independent representation.
The only non-legacy decoder from a logical resource path to mesh data.
std::unique_ptr< Mesh > load_fem(const std::string &path, bool non_conforming=false) const
constexpr long CHECKPOINT_SCHEMA_VERSION
constexpr long MESH_SCHEMA_VERSION
The canonical typed mesh schema shared by HDF5 bundles and checkpoints.
void log_and_throw_error(const std::string &msg)