51 results_.calculation =
"interpolation";
52 results_.provenance = std::move(provenance);
53 results_.properties.fermi_energy =
54 generated::FermiEnergy{generated::FermiEnergyNameEnum::FERMI_ENERGY,
55 generated::FermiEnergyUnitsEnum::RY,
56 fermi_energy_rydberg};
66 const std::string& record_path,
68 results_.construction.method = method;
69 results_.construction.description = interpolator.
description();
70 results_.construction.record = record_path;
72 for (
const auto& [name, value] : interpolator.
diagnostics()) {
74 results_.construction.total_bloch_sum_weight = value;
77 if (!results_.construction.diagnostics) {
78 results_.construction.diagnostics.emplace();
80 (*results_.construction.diagnostics)[name] = value;
94 results_.construction.spread = spread_block(construction.
spread);
96 results_.construction.disentanglement =
99 results_.quality = quality_block(quality, construction.
spread);
108 generated::EigenvaluesAtKpoints block;
109 block.name = generated::EigenvaluesAtKpointsNameEnum::EIGENVALUES_AT_KPOINTS;
110 block.units = generated::EigenvaluesAtKpointsUnitsEnum::RY;
115 generated::EigenvaluesAtKpointsBandEnergies channel;
116 channel.energies = std::vector<double>(at_kpoint.begin(), at_kpoint.end());
117 generated::EigenvaluesAtKpointsEigenvaluesAtKPoint entry;
118 if (kpoint_index < kpoints.size()) {
119 const Vector3D& kpoint = kpoints[kpoint_index];
120 entry.kpoint = std::vector<double>{kpoint.
x, kpoint.
y, kpoint.
z};
122 entry.eigenvalues = std::vector{channel};
123 block.values.push_back(std::move(entry));
125 results_.properties.eigenvalues_at_kpoints = std::move(block);
130 generated::DensityOfStates block;
131 block.name = generated::DensityOfStatesNameEnum::DENSITY_OF_STATES;
132 block.x_axis.label = generated::DensityOfStatesXAxisLabelEnum::ENERGY;
133 block.x_axis.units = generated::DensityOfStatesXAxisUnitsEnum::RY;
134 block.y_axis.label = generated::DensityOfStatesYAxisLabelEnum::DENSITY_OF_STATES;
135 block.y_axis.units = generated::DensityOfStatesYAxisUnitsEnum::STATES_UNITCELL;
136 block.x_data_array = std::vector<nlohmann::json>(density.
energies_rydberg.begin(),
139 results_.properties.density_of_states = std::move(block);
142 [[nodiscard]]
const generated::InterpolationResults&
results()
const {
146 [[nodiscard]] nlohmann::json
json()
const {
150 void write(
const std::string& path)
const {
156 [[nodiscard]]
static std::vector<std::vector<double>>
157 triplets(
const std::vector<Vector3D>& vectors) {
158 std::vector<std::vector<double>> rows;
159 rows.reserve(vectors.size());
160 for (
const Vector3D& vector : vectors) {
161 rows.push_back({vector.x, vector.y, vector.z});
167 [[nodiscard]]
static std::vector<std::int64_t> indices(
const std::vector<int>& values) {
168 return std::vector<std::int64_t>(values.begin(), values.end());
172 [[nodiscard]]
static generated::InterpolationResultsSpread
173 spread_block(
const SpreadReport& report) {
174 generated::InterpolationResultsSpread block;
175 block.gauge_invariant_bohr_squared = report.gauge_invariant_bohr_squared;
176 block.localized = report.localized;
177 if (report.evaluated) {
178 block.total_bohr_squared = report.total_bohr_squared;
179 block.guiding_centers =
180 report.guided_by_trial_orbitals ?
"trial orbitals" :
"projection gauge";
181 block.trial_orbital_centers_bohr = triplets(report.trial_orbital_centers_bohr);
182 block.initial_minimizable_bohr_squared = report.initial_minimizable_bohr_squared;
183 block.centers_bohr = triplets(report.centers_bohr);
184 block.spreads_bohr_squared = report.spreads_bohr_squared;
186 if (report.localized) {
187 block.localization_iterations = report.localization_iterations;
188 block.localization_converged = report.localization_converged;
189 block.localization_gradient_norm = report.localization_gradient_norm;
201 [[nodiscard]]
static generated::InterpolationResultsDisentanglement
202 disentanglement_block(
const DisentanglementReport& report) {
203 const BandClassificationSummary& verdict = report.classification;
204 generated::InterpolationResultsDisentanglement block;
205 block.metallic = verdict.metallic;
206 block.bands_crossing_fermi = verdict.number_of_bands_crossing_fermi;
207 block.frozen_window_above_fermi_ev =
209 block.frozen_window_automatic = verdict.frozen_window_automatic;
210 for (
const BandExcludedFromFreeze& band : verdict.bands_excluded_from_freeze) {
211 generated::InterpolationResultsExcludedBand excluded;
212 excluded.band = band.band_index + 1;
213 excluded.kpoints = band.number_of_kpoints;
214 block.bands_excluded_from_freeze.push_back(excluded);
219 [[nodiscard]]
static generated::InterpolationResultsHamiltonianDecay
220 hamiltonian_decay_block(
const HamiltonianDecay& decay) {
221 generated::InterpolationResultsHamiltonianDecay block;
222 block.outermost_shell_distance_bohr = decay.outermost_shell_distance;
223 block.outermost_shell_size = decay.outermost_shell_size;
224 block.outermost_shell_maximum_ry = decay.outermost_shell_maximum;
225 block.largest_hopping_ry = decay.largest_hopping;
226 block.ratio = decay.ratio;
231 [[nodiscard]]
static generated::InterpolationResultsQuality
232 quality_block(
const WannierQualityReport& report,
const SpreadReport& spread) {
233 generated::InterpolationResultsQuality block;
234 if (!report.spreads_bohr_squared.empty()) {
235 generated::InterpolationResultsQualitySpread statistics;
236 statistics.median_bohr_squared = report.spread_median_bohr_squared;
237 statistics.variance_bohr_squared = report.spread_variance_bohr_squared;
238 statistics.maximum_bohr_squared = report.spread_maximum_bohr_squared;
239 statistics.outliers = indices(report.spread_outliers);
240 statistics.above_ten_angstrom_squared =
241 indices(report.spreads_above_ten_angstrom_squared);
242 block.spread = statistics;
244 if (!report.nearest_atom_distance_bohr.empty()) {
245 generated::InterpolationResultsQualityCenters centers;
246 centers.nearest_atom_distance_bohr = report.nearest_atom_distance_bohr;
247 centers.nearest_bond_midpoint_distance_bohr =
248 report.nearest_bond_midpoint_distance_bohr;
249 centers.shortest_bond_bohr = report.shortest_bond_bohr;
250 block.centers = centers;
252 block.hamiltonian_decay = hamiltonian_decay_block(report.decay);
253 if (spread.localized) {
254 block.localization_converged = spread.localization_converged;
259 generated::InterpolationResults results_;