Loading...
Searching...
No Matches
checkpoint.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * The native interpolation record on disk: `<prefix>.save/interpolation.q3ip`.
5 *
6 * An NSCF run with a `control.interpolation` block writes one; `q3_utility
7 * interpolate` reads it back and evaluates the model without the engine, which
8 * is the point of saving it at all.
9 *
10 * This file owns the ENVELOPE only -- the magic number, the format version,
11 * the method's name, the lattice and the Fermi level -- and dispatches the
12 * method's own payload to a file beside it. A second interpolation method adds
13 * a payload file and one case in each direction here.
14 *
15 * The version gate is load-bearing: a field added to a payload without bumping
16 * it decodes as garbage far from the mistake, which is exactly how a stale
17 * record once failed inside a consumer with a bare "Error: vector".
18 */
19
20#include <cstdint>
21#include <fstream>
22#include <stdexcept>
23#include <string>
24
29
30namespace q3 {
31
32namespace internal::interpolation_checkpoint {
33
34constexpr uint32_t magic = 0x50493351; // "Q3IP"
35constexpr uint32_t version = 2; // 2: trial-orbital centres in the Wannier payload
36
37} // namespace internal::interpolation_checkpoint
38
40 const std::string& file_path) {
41 namespace stream_io = internal::interpolation_stream;
42 namespace constants = internal::interpolation_checkpoint;
43 if (record.method.empty()) {
44 throw std::invalid_argument(
45 "interpolation record: the record names no method; nothing to write.");
46 }
47 std::ofstream stream(file_path, std::ios::binary);
48 if (!stream) {
49 throw std::runtime_error("interpolation record: cannot open '" + file_path +
50 "' for writing.");
51 }
52 stream_io::write_scalar<uint32_t>(stream, constants::magic);
53 stream_io::write_scalar<uint32_t>(stream, constants::version);
54 stream_io::write_string(stream, record.method);
55 stream_io::write_matrix(stream, record.real_lattice_bohr);
56 stream_io::write_matrix(stream, record.reciprocal_lattice_inverse_bohr);
57 stream_io::write_scalar<double>(stream, record.fermi_energy_rydberg);
58 if (record.method == "wannier") {
60 } else {
61 throw std::invalid_argument("interpolation record: no serializer for method '" +
62 record.method + "'.");
63 }
64 if (!stream) {
65 throw std::runtime_error("interpolation record: writing '" + file_path + "' failed.");
66 }
67}
68
69[[nodiscard]] inline InterpolationRecord read_interpolation_record(const std::string& file_path) {
70 namespace stream_io = internal::interpolation_stream;
71 namespace constants = internal::interpolation_checkpoint;
72 std::ifstream stream(file_path, std::ios::binary);
73 if (!stream) {
74 throw std::runtime_error("interpolation record: cannot open '" + file_path + "'.");
75 }
76 if (stream_io::read_scalar<uint32_t>(stream) != constants::magic) {
77 throw std::runtime_error("interpolation record: '" + file_path +
78 "' is not an interpolation record (bad magic).");
79 }
80 const uint32_t version = stream_io::read_scalar<uint32_t>(stream);
81 if (version != constants::version) {
82 throw std::runtime_error("interpolation record: '" + file_path + "' has format version " +
83 std::to_string(version) + "; this build reads version " +
84 std::to_string(constants::version) + ".");
85 }
87 record.method = stream_io::read_string(stream);
88 record.real_lattice_bohr = stream_io::read_matrix(stream);
89 record.reciprocal_lattice_inverse_bohr = stream_io::read_matrix(stream);
90 record.fermi_energy_rydberg = stream_io::read_scalar<double>(stream);
91 if (record.method == "wannier") {
93 } else {
94 throw std::runtime_error("interpolation record: '" + file_path +
95 "' was built by unknown method '" + record.method + "'.");
96 }
97 return record;
98}
99
100} // namespace q3
WannierInputs read(std::istream &stream)
Definition payload.hpp:82
void write(std::ostream &stream, const WannierInputs &record)
Definition payload.hpp:42
void write_interpolation_record(const InterpolationRecord &record, const std::string &file_path)
constexpr const char * version
Definition version.hpp:26
InterpolationRecord read_interpolation_record(const std::string &file_path)
WannierInputs wannier
Payload for method == "wannier": interface matrices on the full k-grid.
Definition record.hpp:46
Matrix3x3 real_lattice_bohr
Rows a1, a2, a3, Cartesian, in bohr.
Definition record.hpp:34
std::string method
The method that built the payload: "wannier".
Definition record.hpp:31
Matrix3x3 reciprocal_lattice_inverse_bohr
Rows b1, b2, b3, Cartesian, in inverse bohr, with the 2 pi included.
Definition record.hpp:36