Docker Tutorial: Runing eDMFT in Docker
This tutorial is useful to try the software without installing it
locally, or to crosscheck the local installation. It only requires
python with matplotlib (for plotting) and docker-desktop. The image
name is haulek/edmft.
MnO example, using latest scripts
Step 1: Install and Start Docker Desktop
First, install Docker Desktop locally and start the application. Once
Docker Desktop is running, use the search menu to look for the image
by entering:
haulek/edmft or edmft
After finding the image, click on Pull to download it. This
action will fetch the required image to execute eDMFT in Docker.
Step 2: Create a Directory for Output Files
Next, create an empty directory, we will call it
examples
, somewhere on your local
drive. This directory will store files generated during the Docker
run. Since graphical output is not included in this Docker, we will
plot results using Python on local machine (outside Docker).
We will copy all relevant Python
plotting scripts into this local directory to ensure accessibility
outside Docker.
Step 3: Start an Interactive Docker Session
Once the image is downloaded and the "examples" directory is created,
start an interactive Docker session by running the following command:
docker run -it -v ./examples:/root/examples edmft /bin/bash
Here is what each part of the command does:
-it
: Starts an interactive session.
-v ./examples:/root/examples
: Maps the local examples directory to /root/examples in the Docker container.
edmft
: Specifies the Docker image.
/bin/bash
: Opens a bash shell.
The session will start an interactive shell. In this shell, navigate
to the examples directory by executing:
cd ~/examples/
From this point onward, all commands to be executed inside the Docker
container will be shown in blue text.
Step 4: Copy Necessary Files
Copy the crystallographic information for the two examples to the current directory by running:
cp -r /app/examples/* .
This copies two examples, MnO and CrSb, as well as useful plotting
scripts to the current directory (~/examples)
Verify that all necessary files are present by running:
ll
The output should display:
drwxr-xr-x 3 root root 96 Dec 22 21:29 CrSb
drwxr-xr-x 3 root root 96 Dec 22 21:29 MnO
-rwxr-xr-x 1 root root 4426 Dec 22 21:29 plt_akplot.py
-rwxr-xr-x 1 root root 8477 Dec 22 21:29 plt_dos.py
-rwxr-xr-x 1 root root 10296 Dec 22 21:29 plt_gs.py
-rwxr-xr-x 1 root root 1586 Dec 22 21:29 plt_info.py
-rwxr-xr-x 1 root root 5402 Dec 22 21:29 plt_makplot.py
-rwxr-xr-x 1 root root 4128 Dec 22 21:29 plt_spaght.py
If you navigate to the same directory on your native computer shell,
you should see the same files. For the two examples, we only have
structure files in the directory, namely, MnO.cif and CrSb.mcif . The
first is the standard crystallographic file for non-magnetic and the
latter for magnetic material.
Step 5: Initialize the Calculation
We start with the MnO example. MnO is a charge transfer insulator in a
high-spin state with localized electrons. The Mn-d electrons will be
treated dynamically in the calculation. For this tutorial, we will set
the Coulomb interaction parameter U to 10 eV and the exchange
parameter J to 1 eV. These values are typical for transition metal oxides. They can be computed by
constrained-DMFT with supercell eDMFT calculation.
To initialize the calculation, execute the following command:
cd MnO
cif2indmf.py -U 10 -J 1 -T 100 -d 'exactd' -F 10 -f -w MnO.cif
This command converts the crystallographic MnO.cif file to a format
compatible with Wien2k (e.g., MnO.struct) and prepares all necessary
DMFT input files.
the Options are
- -U 10 -J 1: Specifies the Coulomb (Hubard and Hunds) interaction.
- -T 100: Sets the temperature to 100 K.
- -d 'exactd': Uses exact double-counting with dielectric screening, suitable for insulators like MnO.
- -F 10: Limits the calculation to a maximum of 10 self-consistent steps.
- -f: Prevents updates to the Fermi level during iterations.
- -w: Generates a momentum path for band and spectrum plotting (MnO.klist_band).
Additional Notes on Calculation Choices:
- Exact Double-Counting 'exactd' is used.
In most calculations, we use 'exacty' or 'exact' (a combination of 'exactd'
and 'exacty'). When computing exact double-counting, we construct
screened Coulomb repulsion in real space, often using a mix of
Yukawa and dielectric screening. Since MnO has a large charge gap,
the screening is predominantly dielectric, making exactd the most
appropriate choice.
- Convergence: The calculation stops when the change in impurity
occupancy between successive steps is less than 5e-4. This threshold
can be challenging to achieve on a laptop with limited processors, due
to Monte Carlo noise. The -F 10 option restricts the calculation to 10
impurity steps for quicker convergence.
Many DFT iterations are performed at each impurity update.
For more accuracy, this option
can be omitted to allow additional iterations.
- Chemical Potential Fixation (-f): The -f option disables Fermi
level updates at each iteration. While this speeds up convergence for
insulators like MnO, it requires verification of charge neutrality by
ensuring that the self-consistent charge density matches the valence
electron count. For charge neutrality, monitor the :DRHO entry in the
MnO.scf file. Note that the -f option should not be used for metals
and should only be applied to insulators after confirming charge
neutrality.
After these steps we should have the following files in MnO directory:
-rw-r--r-- 1 root root 4207 Dec 22 21:29 MnO.cif
-rw-r--r-- 1 root root 3812 Dec 22 21:41 MnO.struct
-rw-r--r-- 1 root root 23862 Dec 22 21:41 MnO.klist_band
-rw-r--r-- 1 root root 575 Dec 22 21:41 MnO.indmf
-rw-r--r-- 1 root root 1603 Dec 22 21:41 MnO.indmfl
-rw-r--r-- 1 root root 122 Dec 22 21:41 MnO.indmfi
-rw-r--r-- 1 root root 1942 Dec 22 21:41 params.dat
-rw-r--r-- 1 root root 79144 Dec 22 21:41 cif2struct.log
Step 6: Initialize and run DFT
Initialize the DFT calculation by running:
init_lapw
Perform the DFT self-consistent calculation:
run_lapw
This step should complete in a few minutes.
Step 7: Analyzing DFT results
To solve the Kohn-Sham problem along the high-symmetry path in the first Brillouin zone, execute:
x lapw1 -band
Next, navigate to the MnO directory on your local shell (outside Docker) and plot the resulting band structure:
../plt_spaght.py MnO.output1 -y-8:8
The plot will show the band structure, like that:
The plot should look like:
Note that black color commands should be executed outside docker, and
blue inside docker shell.
The plot shows that we have 5 bands crossing the Fermi level, which
have majority Mn:3d character. The oxygen:2p bands are found between -8eV
to -4eV, and Mn:4s state starts just above the Fermi level and is the
wide green conduction band.
Step 8: Initialize DMFT run
To initialize the DMFT calculation after the DFT run, execute the
following commands inside the Docker shell:
init_proj.py -a
szero.py
- init_proj.py: Calculates the radial dependence of the Mn:3d
orbitals and stores that info in projectorw.dat. This will be used
as a projector in the eDMFT calculation.
- szero.py: Creates a blank self-energy file for DMFT.
Step 9: Running and Monitoring the eDMFT Calculation
Configure parallel execution by writing the command for parallel
execution into
mpi_prefix.dat:
echo "mpirun -n 8 " > mpi_prefix.dat
Here, adjust 8 to match the number of threads your laptop supports.
Start the self-consistent eDMFT calculation:
run_dmft.py
This step may take several minutes per iteration. Monitor progress using the output files or plotting scripts.
The first impurity step is done when we see the following output:
STOP LAPW0 END
STOP LAPW1 END
STOP DMFT1 END
STOP IMPURITY_0
STOP DMFT2 END
STOP CORE END
STOP MIXER END
:ENERGY convergence: 1.0
:CHARGE convergence: 1.0
:EF convergence: 0
:NIMP convergence: 1
:NIMP difference : 1
Here is a schematic plot of the calculation. Note that we first
proceed on the right side down to impurity (lapw0,lapw1,dmft1,impurity)
and than we go multiple times through the gray loop (around 10-times) to
converge charge density (dmft2,core,mixer,lapw0,lapw1,dmft2,...). Once
charge is converged, we go through the large loop and update impurity self-energy.
While the code is running (and after the first step is finished) we
can start plotting the progress of the calculation.
To display convergence of impurity/lattice occupancy, and total
energy, we can run (outside Docker in MnO directory):
../plt_info.py
The top plot shows all DFT and DMFT steps and the Mn:5d charge as
found from impurity occupancy (nimp) and from integrating charge within muffin-tin sphere
in solid (nlat). The second plot shows the same two quantities, but
only on converged DFT charge (and each DMFT self-energy). Namely,
after impurity self-energy is recomputed, we converge DFT charge on
current self-energy. The bottom plot show the total energy and total
free energy of the system and its changes through iterations. It
should look like:
We can also monitor how similar are impurity Greens function and
lattice Greens function. We can do that by executing
../plt_gs.py -x:5 -a 6
This plots up to 5eV frequency range, and displays last 6 impurity
Greens function. When the calculation is converged, the last impurity
Greens function should coincide with the lattice computed Greens
function. Towards the end, the plot should look like:
We see that at the beginning the current
lattice Greens function and impurity Greens function do not coincide,
but they get closer with each iteration (subject to MC noise).
To plot the last step only, we execute:
../plt_gs.py -x:5
and if the line and dots coincide, we reached self-consistency.
The convergence is not perfect since we use only 10 steps and only 8
processors for MC calculation. But it is good enough that we can
proceed with real axis calculation.
Since we fixed the chemical potential, we need to check that the
system is charge neutral. This is achieved by
grep ':DRHO' MnO.scf
The numbers should be much smaller than unity. A unit of charge here
correspond to doping of 1 electron.
We can also monitor other files during calculation. For example:
- info.iterate : contains convergence information,
impurity/lattice occupation, total energy and free energy, etc
- MnO.dayfile: execution order and charge convergence
- dmft_info.out: information about all steps, input and output parameters
- imp.0/nohup_imp.out.000: current impurity status
- :log : summary of executions
- MnO.outputdmf1 : output from dmft1 step
- MnO.outputdmf2 : output from dmft2 step
Step 10: Real Axis Calculation and Spectral Plotting
The calculation was performed on imaginary axis, and now we want to
perform analytic continuation to the real axis, and display density of
states and the spectral function. To do that, we execute inside Docker
shell:
to_real_axis.py -y-6:6
Here -y-6:6 means that the spectral function will have frequency range
from -6eV to 6eV.
This scripts execute several steps. First the maximum entropy method
is run (inside maxent subdirectory), and than one DFT+eDMFT iteration is
performed on the real axis (inside onreal subdirectory).
We obtained density of states, the green's function on the real
axis, and the momentum resolved spectral function. To display them we execute outside the docker:
cd onreal
../../plt_gs.py -x-12:12
../../plt_dos.py -x-12:12
../../plt_akplot.py
The plot of the Greens function (plt_gs.py) should produce a plot like that:
We see a clear gap of the order of 2.5eV at the Fermi level. The first
valence excitation is from eg state, which strongly hybridizes with
the oxygen below the Fermi level. The first conduction state is of t2g
origin. Interestingly, our large Coulomb repulsion of 10eV is not
clearly seen in our plot. This is because it is screened by the
oxygen:p bands and Mn:4s state, so that the Hubbard bands appear much
closer than they would in a corresponding Hubbard model.
The density of states displays all states, including oxygen, and we
can see that less than 50% of the first excitation in the valence
state is of Mn:eg character, and the rest is of oxygen:2p
character. Since majority of the states just below the Fermi level are
of oxygen character, this material is characterized as charge-transfer
insulator, according to Zaanen-Sawatzky-Allen classification. The
upper Hubbard band is majority of Mn:3d character, even though there
is approximately 40% of charge that is not Mn:3d. Some is Mn:4s, and some
interstitial charge.
Finally, the spectral density plot (plt_akplot.py) displays the
momentum resolved spectra, which has some similarity with the DFT bands,
displayed earlier, but there are vast differences. The oxygen:p
bands, which were mostly below -4eV, are still somewhat similar,
although they move closet to EF (-3eV because of reduced level
repulsion), and became broad due to hybridization with Mn:3d. The
mixture of oxygen and Mn:3d is so-called Zhang-Rice singlet, which is
the first occupied state (between -2eV and EF), which is all that is
left from Mn:3d bands in DFT. The unoccupied Mn:4s
band is not changed much, but all the Mn:3d disappeared to
above 4eV, and is just a broad diffusive spectra, comprising the Hubbard band.
CrSb example
Step 1: Initialize CrSb
Navigate to CrSb example directory:
cd ~/examples/CrSb
Currently we only have CrSb.mcif file, which describes its crystal
structure and magnetic configuration. It can be displayed (for
example) by VESTA, which should show:
CrSb is altermagnetic (not AFM but AM) compound that crystalizes in hexagonal space
group (194) with magnetic space group P63'/m'm'c (194.268)
More information about this material can be found at
Bilbao server.
We initialize the calculation by
cif2indmf.py -m -F 10 -w CrSb.mcif
the Options are
- -m: We want to initialize magnetic eDMFT calculation with magnetic
configuration from CrSb.mcif file
- -F 10: Limits the calculation to a maximum of 10 self-consistent steps.
- -w: Generates a momentum path for band and spectrum plotting (MnO.klist_band).
We should have the following files now:
-rw-r--r-- 1 root root 3158 Dec 22 21:29 CrSb.mcif
-rw-r--r-- 1 root root 1898 Dec 22 22:22 CrSb.struct
-rw-r--r-- 1 root root 23783 Dec 22 22:22 CrSb.klist_band
-rw-r--r-- 1 root root 1046 Dec 22 22:22 CrSb.indmf
-rw-r--r-- 1 root root 3052 Dec 22 22:22 CrSb.indmfl
-rw-r--r-- 1 root root 3052 Dec 22 22:22 CrSb.indmfldn
-rw-r--r-- 1 root root 378 Dec 22 22:22 CrSb.indmfi
-rw-r--r-- 1 root root 1942 Dec 22 22:22 params.dat
-rw-r--r-- 1 root root 37869 Dec 22 22:22 cif2struct.log
Step 2: Initialize and run DFT
Initialize the DFT calculation:
init_lapw
Perform the DFT (non-magnetic) self-consistent calculation:
run_lapw
This step should complete in a few minutes.
Next we check the DFT band structure by executing
x lapw1 -band
Next, navigate to the CrSb directory on your local shell (outside
Docker) and plot the resulting DFT band structure:
../plt_spaght.py CrSb.output1 -y-6:6
The plot should look like:
Step 3: Initialize and run eDMFT
Next we need compute quasi-atomi orbital on current DFT charge
density, which is achieved by
init_proj.py -a
The blank self-energy is obtained by
szero.py -m
Here we added additional flag "-m", which adds some initial exchange
splitting to the self-energy. This should push the calculation towards
magnetic solution.
We also prepare parallel execution by
echo "mpirun -n 8 " > mpi_prefix.dat
and finally run eDMFT by
run_dmft.py
This should take approximately 40 minutes to complete 10 eDMFT steps. The
metallic systems are typically slower because the perturbation order
is larger. Indeed, we can check that average perturbation order in
hybridization expansion Monte Carlo is 290 and maximum is 450 (check "imp.0/histogram.dat").
We can monitor the convergence with (on native shell inside CrSb directory)
../plt_info.py
which should give
And as before, we can plot current Greens function by
../plt_gs.py -x:5
and should show
Notice that you can click on the legend to hide or replot each
curve. These plots have so-called dynamic legend.
Step 4: Plot results of eDMFT on real axis
Analytic continuation and plotting spectra can be achieved by one
command:
to_real_axis.py -y-6:6
Once this finishes, one can plot the green's function, density of
states and the spectral function. First navigate to
"onreal directory" on your native shell, and than execute
../../plt_gs.py -x-6:6
../../plt_dos.py -x-6:6
../../plt_akplot.py
which should give:
Since this is magnetic calculation the two different spin directions
do not necessary have the same spectra. In conventional AFM the
Kramers degeneracy is protected, but in altermagnets it is lifted at
least in part of momentum space. For CrSb, this is indeed the case on
xz plane, which is here achieved with the path from M to A:
../../plt_makplot.py
In most of the path the red and blue spectra coincide (Kramers
degeneracy for spin-up and spin-down). In the path from M to A the
degeneracy is lifted:
Notice that the first Brillouine zone has this form: