77 std::ofstream stream = open(file_path);
80 require_overlaps_present(record);
82 stream <<
"Written by Q3\n";
83 stream <<
" " << record.
number_of_bands <<
" " << number_of_kpoints <<
" "
84 << number_of_directions <<
"\n";
86 std::vector<KPoint> kpoints = build_kpoints(record);
87 for (
int kpoint_index = 0; kpoint_index < number_of_kpoints; kpoint_index++) {
88 for (
int direction_index = 0; direction_index < number_of_directions;
100 const std::vector<Complex>& block =
102 for (
const Complex& value : block) {
103 write_complex(stream, value);
110 std::ofstream stream = open(file_path);
113 throw std::invalid_argument(
114 "Wannier90FormatWriter::write_projections: the record holds no projections");
117 stream <<
"Written by Q3\n";
118 stream <<
" " << record.
number_of_bands <<
" " << number_of_kpoints <<
" "
121 for (
int kpoint_index = 0; kpoint_index < number_of_kpoints; kpoint_index++) {
125 for (
int band_index = 0; band_index < record.
number_of_bands; band_index++) {
126 stream <<
" " << band_index + 1 <<
" " << orbital_index + 1 <<
" "
129 block[
static_cast<std::size_t
>(orbital_index) * record.
number_of_bands +
131 write_complex(stream, value);
139 throw std::invalid_argument(
140 "Wannier90FormatWriter::write_eigenvalues: the record holds no eigenvalues");
142 std::ofstream stream = open(file_path);
143 for (
int kpoint_index = 0; kpoint_index < record.
number_of_kpoints(); kpoint_index++) {
146 throw std::invalid_argument(
"Wannier90FormatWriter::write_eigenvalues: k-point " +
147 std::to_string(kpoint_index) +
" carries " +
148 std::to_string(row.size()) +
149 " eigenvalues, fewer than number_of_bands = " +
152 for (
int band_index = 0; band_index < record.
number_of_bands; band_index++) {
153 stream <<
" " << band_index + 1 <<
" " << kpoint_index + 1 <<
" " << std::scientific
164 std::ofstream stream = open(file_path);
168 stream <<
"File written by Q3\n\n";
169 stream <<
"calc_only_A : F\n\n";
171 write_lattice_block(stream,
"real_lattice", real_lattice);
172 write_lattice_block(stream,
"recip_lattice", reciprocal_lattice);
174 stream <<
"begin kpoints\n";
175 stream <<
" " << number_of_kpoints <<
"\n";
177 stream <<
" " << std::fixed << std::setprecision(12) << kpoint.x <<
" " << kpoint.y
178 <<
" " << kpoint.z <<
"\n";
180 stream <<
"end kpoints\n\n";
182 std::vector<KPoint> kpoints = build_kpoints(record);
183 stream <<
"begin nnkpts\n";
184 stream <<
" " << number_of_directions <<
"\n";
185 for (
int kpoint_index = 0; kpoint_index < number_of_kpoints; kpoint_index++) {
186 for (
int direction_index = 0; direction_index < number_of_directions;
199 stream <<
"end nnkpts\n";
203 static std::ofstream open(
const std::string& file_path) {
204 std::ofstream stream(file_path);
206 throw std::runtime_error(
"Wannier90FormatWriter: cannot write " + file_path);
211 static void write_complex(std::ofstream& stream,
const Complex& value) {
212 stream <<
" " << std::scientific << std::setprecision(12) << value.real() <<
" "
213 << value.imag() <<
"\n";
217 write_lattice_block(std::ofstream& stream,
const std::string& name,
const Matrix3x3& lattice) {
218 stream <<
"begin " << name <<
"\n";
219 for (
int row = 0; row < 3; row++) {
220 stream <<
" " << std::fixed << std::setprecision(12) << lattice[row].x <<
" "
221 << lattice[row].y <<
" " << lattice[row].z <<
"\n";
223 stream <<
"end " << name <<
"\n\n";
231 static std::vector<KPoint> build_kpoints(
const WannierInputs& record) {
232 std::vector<KPoint> kpoints(record.kpoint_coordinates.size());
233 for (std::size_t index = 0; index < record.kpoint_coordinates.size(); index++) {
234 kpoints[index].coordinates = record.kpoint_coordinates[index];
235 kpoints[index].weight = 0.0;
240 static void require_overlaps_present(
const WannierInputs& record) {
241 if (
static_cast<int>(record.overlap_matrices.size()) != record.number_of_kpoints()) {
242 throw std::invalid_argument(
243 "Wannier90FormatWriter::write_overlaps: the record holds no overlaps");
245 for (
const std::vector<std::vector<Complex>>& per_kpoint : record.overlap_matrices) {
246 if (per_kpoint.size() != record.neighbor_directions.size()) {
247 throw std::invalid_argument(
248 "Wannier90FormatWriter::write_overlaps: a k-point carries a different number "
249 "of neighbour blocks than there are neighbour directions");
static ResolvedKPointNeighbor resolve_neighbor(int starting_kpoint_index, const IntegerVector3D &grid_step, const std::array< int, 3 > &grid_dimensions, const std::vector< KPoint > &physical_kpoints)
std::complex< double > Complex
3×3 matrix stored row-major: row i = mat[i]
IntegerVector3D periodic_image_shift
int neighbor_kpoint_index