Loading...
Searching...
No Matches
spread_minimization_settings.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * SpreadMinimizationSettings — the budget and the tolerances of the spread
5 * minimisation (SpreadMinimizer), each with the measurement that set it.
6 */
7
9
10namespace q3 {
11
12struct [[nodiscard]] SpreadMinimizationSettings {
13 /// Relative change in Omega_D + Omega_OD that counts as converged.
14 Real convergence_tolerance = 1.0e-10;
15 int maximum_iterations = 3000;
16 /// Iterations the relative change must stay below the tolerance for.
17 int convergence_window = 3;
18 /// Halvings of the trial step before a stationary point is declared.
19 int maximum_step_reductions = 30;
20 /// What a trial step is multiplied by each time it fails to lower Omega.
21 Real step_reduction_factor = 0.5;
22 /**
23 * What the step is multiplied by after every success, without a ceiling.
24 * Without this the first hard k-point permanently halves the step for the
25 * whole run, and a minimisation that started well finishes at a crawl.
26 * Backtracking already refuses anything that overshoots, so a cap only
27 * slows the recovery from one bad direction -- capping this at the natural
28 * scale, and separately resetting it there on every conjugate-gradient
29 * restart, were both tried and both cost copper its convergence: it
30 * reaches the same Omega_OD of 4.772 either way, but spends the entire
31 * iteration budget getting there instead of a hundred iterations.
32 */
33 Real step_growth_factor = 1.2;
34 /**
35 * A gradient this small a fraction of where it started ends the run early.
36 * It is a shortcut, not the convergence test: the gradient carries the
37 * b-weights, which scale as 1/b^2 and so with the cell, and its size at a
38 * genuine minimum varies by orders of magnitude between systems -- measured
39 * here, a toy chain at Omega_OD = 7e-7, its exact minimum, still shows 3e-4,
40 * while copper at its own minimum never falls to a thousandth of where it
41 * began. What the run is judged by is whether it can still lower Omega; the
42 * gradient is reported beside the answer as the diagnostic it is.
43 */
44 Real relative_gradient_tolerance = 1.0e-3;
45 /**
46 * Conjugate-gradient restarts. Steepest descent on this functional creeps:
47 * a three-function chain on eight k-points takes five hundred iterations to
48 * do what conjugation does in a few dozen, and on a real system the crawl
49 * is the difference between converging and exhausting the budget. The
50 * search direction is conjugated against the previous one and reset every
51 * `restart_interval` iterations, because the manifold is curved and a
52 * direction carried too far along it stops being conjugate to anything.
53 */
54 int restart_interval = 20;
55};
56
57} // namespace q3
double Real