Configuration#
Run parameters are specified through a YAML configuration file. You can either create a new file or modify the
default one, dga_config.yaml, which is shipped with the repository. Its default entries are chosen to be
sensible for typical use cases, so whenever a parameter is unclear the default can usually be kept; the only
exceptions are the input file paths, which always have to be set explicitly.
Individual settings within a section, or even whole sections, may be omitted, in which case DGAmore falls back to
the predefined defaults listed below alongside the variable type the code expects. The order of the sections in the
file does not matter for parsing; the sections are discussed here in the order in which they appear in the default
dga_config.yaml.
Matsubara frequencies#
The first section governs the frequency box sizes used throughout the calculation.
box_sizes:
niw_core: -1 # int
niv_core: -1 # int
niv_shell: 0 # int
The “core” region defines the frequency box on which the Bethe-Salpeter and Schwinger-Dyson equations are solved
explicitly, while the “shell” region sets the size of the asymptotic tails used for the vertex reconstruction
through the U-range method. Here niw_core is the number of positive bosonic Matsubara frequencies and
niv_core the number of positive fermionic ones, so that the objects carry 2 * niw_core + 1 bosonic and
2 * niv_core fermionic frequencies in total. Setting either core size to -1 instructs the code to take the
full number of positive frequencies available from the DMFT calculation; if a smaller box is requested, the DMFT
vertices are cut down to the specified size.
Lattice and symmetries#
The next section describes the Hamiltonian and the lattice symmetries of the system.
lattice:
symmetries: "auto" # str | list[str]
type: "from_wannier90" # str
hr_input: "/path/to/file" # str | list[float]
interaction_type: "one_band_from_dmft" # str
interaction_input: "" # str
nk: [ 16, 16, 1 ] # list[int]
# nq: [ 16, 16, 1 ] # list[int]
The symmetries field controls how the irreducible Brillouin zone is built. Entering auto enables the
automatic symmetry discovery, which probes a large number of combined momentum and orbital transformations,
constructs the irreducible zone together with its map onto the full zone, and always yields the smallest possible
number of irreducible momenta; it is the preferred choice. Alternatively, one of the predefined symmetry sets, such
as two_dimensional_square or three_dimensional_cubic, can be supplied, or a list of individual symmetries
can be passed explicitly. The supported single operations are x-inv, y-inv and z-inv (inverting the
respective momentum component), x-y-sym, x-z-sym and y-z-sym (exchanging two components), and
x-y-inv (inverting both in-plane components at once). Passing
[ "x-inv", "y-inv", "z-inv", "x-y-sym", "x-z-sym", "y-z-sym" ] is, for instance, equivalent to
three_dimensional_cubic. The predefined and individual operations always act on the primitive reciprocal
lattice axes, so they map the grids incorrectly when not every calculated orbital shares the requested symmetry, or
when the primitive reciprocal lattice vectors are not orthogonal; the automatic discovery is free of both
limitations because it inspects the Hamiltonian directly.
The type field selects the form in which the kinetic part of the Hamiltonian is provided. With
from_wannier90 the hr_input field points to a real-space Hamiltonian file holding the hopping elements,
whereas from_wannierHK expects a file giving the Hamiltonian directly in momentum space. The third option,
t_tp_tpp, is available for single-band input only and reads a list of three floating-point values for the
nearest, next-nearest and third-nearest neighbour hoppings from hr_input, for example [1.0, -0.25, 0.12].
Because DGAmore supports multi-orbital calculations with non-local interactions, an interaction type and input must
be specified as well. With one_band_from_dmft a single-band calculation is assumed and the local interaction
strength is read from the DMFT input, while kanamori_from_dmft takes the interaction values from DMFT and builds
the Kanamori interaction tensor; in both cases interaction_input is ignored. Choosing custom instead lets
the code read the interaction from the file referenced in interaction_input, which is structured like a
real-space Hamiltonian file but with four orbital indices instead of two and may also encode non-local
interactions.
Finally, nk and nq set the sizes of the momentum grid for the one-particle quantities and for the
ladder, respectively. The nq field may be left unset, in which case nk is reused for the q-grid. Note that
the Eliashberg equation can only be solved when the two grids have the same size.
Self-consistency#
This section controls the self-consistency cycle.
self_consistency:
max_iter: 20 # int
epsilon: 1e-4 # float
mixing: 0.2 # float
mixing_strategy: "linear" # str
mixing_history_length: 3 # int
previous_sc_path: "" # str
use_interpolated_sigma: False # bool
use_lambda_correction: False # bool
restrict_chi_phys: False # bool
The max_iter field puts an upper limit on the number of iterations; if the self-energy has not converged by
then, the loop stops and the program exits. The non-local self-energy is written to the output folder for every
iteration. Convergence itself is judged by epsilon through the relative residual of the Schwinger-Dyson iteration: the
norm of the change in the self-energy between consecutive iterations, divided by the norm of the previous one, taken
over the full momentum grid, all orbital combinations and the positive fermionic frequencies of the core box. The cycle is
considered converged once this residual drops below epsilon; in addition, the chemical potential is required to
change by less than a small temperature-dependent threshold between iterations.
The mixing parameter is a floating-point number between zero and one that sets the weight of the new
self-energy in the update. The accompanying mixing_strategy selects between linear, pulay and
anderson mixing; the latter two build a prediction from the previous mixing_history_length self-energies and
fall back to linear mixing while fewer iterations than the history length are available. The previous_sc_path
field points to the folder of an earlier, possibly unconverged, self-consistency run: the code then resumes from
its last iterations and continues converging, applying Pulay or Anderson mixing right away if enough previous
iterations are available. Enabling use_interpolated_sigma makes the cycle start from the interpolated
self-energy of the previous run, with the interpolation itself configured in the
self-energy interpolation section.
Setting use_lambda_correction to True applies the lambda correction throughout the entire self-consistency
cycle for single-band data, which can help stabilise convergence or reveal how a lambda-corrected cycle changes the
results. The correction scheme is taken from the type field of the
lambda correction section, and perform_lambda_correction is enabled automatically for
every iteration. Lastly, restrict_chi_phys clamps the inverse physical susceptibilities to
positive values, replacing any negative value by a small positive one. This sometimes stabilises early iterations
but generally yields unphysical results, so once the self-energy converges with this option enabled and iterations
remain, the option is switched off automatically and the cycle continues until convergence is reached again or
max_iter is hit.
Lambda correction#
DGAmore implements two lambda-correction schemes, both restricted to the single-band case.
lambda_correction:
perform_lambda_correction: False # bool
type: "spch" # str
When perform_lambda_correction is True, the code applies the correction selected in type: spch
corrects both the density and the magnetic susceptibility, whereas sp corrects only the magnetic one.
DMFT input#
This section specifies the DMFT result files and the structure of the vertex.
dmft_input:
type: "w2dyn" # str
input_path: "./" # str
fname_1p: "1p-data.hdf5" # str
fname_2p: "g4iw_sym.hdf5" # str
do_sym_v_vp: True # bool
symmetrize_orbitals: [] # list[int] | list[list[int]]
n_ineq: 1 # int
ineq_ordering: [ 1 ] # list[int]
Currently only w2dynamics output is supported, though support for further DMFT solvers is planned. The result files
are expected in the folder given by input_path, with fname_1p and fname_2p naming the one- and
two-particle results. Because the two-particle Green’s function is symmetric under the exchange of its two fermionic
frequencies, this symmetrisation is enforced explicitly when do_sym_v_vp is True.
The symmetrize_orbitals field allows the local DMFT quantities, namely the self-energy and the one- and
two-particle Green’s functions, to be symmetrised over orbitals, which is well defined because these quantities are
purely local. For the three orbitals of a material such as \(\mathrm{SrVO}_3\), entering [1, 2, 3]
symmetrises all three with respect to one another. Subsets and multiple subsets are equally possible: for a
four-orbital case in which orbitals one and three as well as orbitals two and four are locally equivalent, one
enters [[1, 3], [2, 4]].
The last two settings were introduced for multi-layered materials such as \(\mathrm{La}_3\mathrm{Ni}_2\mathrm{O}_7\).
There the DGA calculation uses a four-orbital model, while at the DMFT level the symmetry of the system lets one
treat pairs of orbitals as equivalent atoms, producing two-orbital DMFT quantities that must be mapped back onto the
full four-band orbital-diagonal space. The n_ineq field gives the number of inequivalent atoms treated in DMFT
(one for \(\mathrm{La}_3\mathrm{Ni}_2\mathrm{O}_7\)), and ineq_ordering specifies how these are distributed
across the orbital-diagonal entries of the Hamiltonian; setting it to [1, 1] correctly populates the four-orbital
space by repeating the first atom’s data. The entries may be ordered arbitrarily or repeated to suit different
layered geometries, as long as the total number of orbitals they represent matches the number of bands in the
Hamiltonian input.
Eliashberg equation#
Superconducting properties are obtained by solving the linearised Eliashberg equation, configured here.
eliashberg:
perform_eliashberg: False # bool
save_pairing_vertex: False # bool
save_fq: False # bool
construct_fq_cheap: False # bool
n_eig: 4 # int
epsilon: 1e-6 # float
symmetry: "random" # str
include_local_part: True # bool
subfolder_name: "Eliashberg" # str
The equation is solved only when perform_eliashberg is True. Enabling save_pairing_vertex or save_fq
writes the pairing vertex or the full ladder vertex on the irreducible Brillouin zone to the output folder. Since
assembling the full ladder vertex is very memory-intensive, construct_fq_cheap offers a variant that builds it
on a reduced fermionic frequency box and needs only a quarter of the memory; this slightly changes the eigenvalues
and gap functions but remains qualitatively reliable, as verified across many test cases, and is recommended only
for datasets that push the memory limits.
The equation is solved with a Lanczos algorithm based on the ARPACK routines, retrieving the n_eig largest
eigenvalues and the corresponding gap functions to an accuracy of epsilon. The symmetry field sets the
starting vector of the iteration: entering "d-wave", for example, begins from a gap function with d-wave
symmetry, but "random" is sufficient most of the time. The pairing vertex includes local reducible diagrams by default,
which can be skipped by setting include_local_part to False; this is only advisable when s-wave symmetry is
not expected, as these diagrams become relevant in that case. Finally, the results are written to a subfolder named
according to subfolder_name.
Self-energy interpolation#
When a low-temperature parameter set is hard to converge, a common strategy is to bootstrap the solution from a converged result at a higher temperature, interpolating the self-energy to the target temperature and frequency grid before entering the self-consistency cycle.
self_energy_interpolation:
do_interpolation: False # bool
target_beta: 1.0 # float
target_niv: 10 # int
The interpolation runs when do_interpolation is True. It applies a linear inter- or extrapolation for the
lowest frequencies and a PCHIP interpolation for the remaining ones. The resulting self-energy, now at the new
inverse temperature target_beta and the new number of positive fermionic frequencies target_niv, is written
to the output folder for each iteration.
Output#
This section collects further output settings.
output:
output_path: "" # str
do_plotting: True # bool
plotting_subfolder_name: "Plots" # str
When output_path is empty, the results are written to a subfolder created next to the DMFT input files;
otherwise they go to the folder it names. If do_plotting is enabled, a few quantities such as the self-energy
and the Green’s function are plotted with matplotlib into the subfolder named by plotting_subfolder_name.
Analytic continuation#
The code integrates support for continuing Green’s functions from the Matsubara axis to the real-frequency axis
through the ana_cont package.
ana_cont:
do_spectrum_dga: False # bool
do_spectrum_dmft: False # bool
w_count: 1001 # int
plot_spectrum: True # bool
k_path: [ [0.0, 0.0, 0.0, "Gamma"], [0.0, 0.5, 0.0, "X"] ] # list[tuple]
energy_window: [ -2, 3 ] # list[float]
The flags do_spectrum_dga and do_spectrum_dmft toggle the continuation of the DGA and DMFT
Green’s functions, respectively. The procedure yields the spectral function over a symmetric interval of w_count
real-frequency points. When plot_spectrum is enabled, the spectral function is plotted along the path given in
k_path, a list of tuples whose first three elements are the coordinates of a high-symmetry point in the
primitive reciprocal lattice and whose fourth element is its label (the example above is truncated relative to the
default path). The energy_window parameter sets the bounds of the frequency axis in the resulting spectral
plots.
Memory efficiency#
For very large parameter sets memory becomes the main bottleneck, owing to the vectorised nature of the implemented equations. This section therefore exposes more memory-efficient algorithms for five of the heaviest steps.
memory:
save_memory_for_chi0q: False # bool
save_memory_for_chiq_aux: False # bool
save_memory_for_sde: False # bool
save_memory_for_fq: False # bool
save_memory_for_lanczos: False # bool
These switches control, in turn, the construction of the bare bubble susceptibility, of the auxiliary
susceptibility entering the Schwinger-Dyson equation, of the Schwinger-Dyson equation itself, of the full ladder
vertices for the Eliashberg equation, and of the Lanczos algorithm. Enabling any of them increases the runtime
substantially because of the additional Python-level looping and MPI communication. Under the hood, the bubble and the
Schwinger-Dyson steps use fast Fourier transforms when their switches are left at False; this gives by far the
largest speed-up while barely affecting the memory footprint, so it can be kept at the default in almost all cases.
The largest memory savings come from the auxiliary-susceptibility and full-ladder-vertex switches, which shrink
those objects considerably, whereas the Lanczos switch matters only for extremely large parameter sets and can
usually stay disabled.
In practice these switches rarely need to be set by hand. Before the heavy part of a run begins, DGAmore inspects the memory available on every node together with an analytic estimate of the peak memory each of the five steps consumes, accounting for how the momentum points are distributed across the MPI ranks that share a node. Whenever the default, faster variant of a step would not fit, the corresponding switch is turned on automatically. The estimate is evaluated as a node total: it sums, over all ranks placed on a node, the data that each rank keeps resident throughout the calculation plus the transient peak of the step in question, and requires the result to stay below ninety percent of that node’s available memory. Because the switches act process-wide, the most constrained node decides whether a given switch is enabled.
A switch that is explicitly set to True in the configuration is always honoured: the automatic detection can
only enable additional switches, never turn off one that was requested. Conversely, if even the most memory-frugal
variant of a required step does not fit on some node, the run stops immediately with a MemoryError that
recommends using more nodes, fewer ranks per node, or a smaller frequency box or momentum grid, rather than failing
unpredictably partway through.