# Single-shot DFT+DMFT

After having set up the hdf5 archive, we can now proceed to our first DFT+DMFT calculation. It consists of initialization steps, and the actual DMFT self-consistency loop, With the code snippets below you can build your own script and target it to your needs. Little examples on mixing and on restarting from a previous calculation at the end of this page should also demonstrate how simple you can modify your own DMFT script. A full working calculation for SrVO3 is discussed in the next section.

## Initialization of the calculation

Before doing the actual calculation, we have to initialize all needed objects.
The first thing is the `SumkDFT`

class.
It contains all basic routines that are necessary to perform a summation in k-space
to get the local quantities used in DMFT. It is initialized by:

```
from triqs_dft_tools.sumk_dft import *
SK = SumkDFT(hdf_file = filename + '.h5')
```

## Setting up the impurity solver

The next step is to setup an impurity solver. There are different solvers available within the TRIQS framework. E.g. for SrVO3, we will use the hybridization expansion CTHYB solver. Later on, we will see also the example of the Hubbard-I solver. They all have in common, that they are called by an uniform command:

```
S.solve(params)
```

where *params* are the solver parameters and depend on the actual
solver. Setting up the CTHYB solver for SrVO3 is
discussed on the next page. Here, let us now perform the DMFT
loop using the methods of **DFTTools**, assuming that we have already
set up a working solver instance.

## Doing the DMFT loop

Having initialized the `Sumk class`

and the solver, we can proceed with the actual DMFT part of the calculation.
We set up the loop over DMFT iterations and the self-consistency condition:

```
n_loops = 15
for iteration_number in range(n_loops) : # start the DMFT loop
SK.set_Sigma([ S.Sigma ]) # Put self energy to the SumK class
chemical_potential = SK.calc_mu() # calculate the chemical potential for the given density
S.G_iw << SK.extract_G_loc()[0] # extract the local Green function
S.G0_iw << inverse(S.Sigma_iw + inverse(S.G_iw)) # finally get G0, the input for the solver
S.solve(h_int=h_int, **p) # now solve the impurity problem
dm = S.G_iw.density() # Density matrix of the impurity problem
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=1) # Set the double counting term
SK.save(['chemical_potential','dc_imp','dc_energ']) # Save data in the hdf5 archive
```

These steps are enough for a basic DMFT Loop.
After the self-consistency steps, which lead to a new \(G^0(i\omega)\),
the impurity solver is called. Different to model calculations, we have to do a few
more steps after this, because of the double-counting correction. We first
calculate the density of the impurity problem. Then, the routine `calc_dc`

takes as parameters this density matrix, the Coulomb interaction, Hund’s rule
coupling, and the type of double-counting that should be used. Possible values
for *use_dc_formula* are:

0: Full-localised limit (FLL)

1: DC formula as given in K. Held, Adv. Phys. 56, 829 (2007).

2: Around-mean-field (AMF)

At the end of the calculation, we can save the Green function and self energy into a file:

```
from h5 import HDFArchive
import triqs.utility.mpi as mpi
if mpi.is_master_node():
ar = HDFArchive("YourDFTDMFTcalculation.h5",'w')
ar["G"] = S.G_iw
ar["Sigma"] = S.Sigma_iw
```

These are the essential steps necessary for a one-shot DFT+DMFT calculation.
For a detailed description of the `SumkDFT`

routines, see the reference manual. To perform full charge self-consistent calculations, there
are some more things to consider, which we will see later on.

## Restarting a calculation

Often only a few DMFT iterations are performed first, and thus, it is desirable to carry out further iterations, e.g. to improve on the convergence. With a little modification at the initialization stage (before the DMFT loop) it is possible to detect if previous runs are present, or if the calculation should start from scratch:

```
previous_runs = 0
previous_present = False
if mpi.is_master_node():
with HDFArchive(dft_filename+'.h5','a') as f:
if 'dmft_output' in f:
ar = f['dmft_output']
if 'iterations' in ar:
previous_present = True
previous_runs = ar['iterations']
else:
f.create_group('dmft_output')
previous_runs = mpi.bcast(previous_runs)
previous_present = mpi.bcast(previous_present)
```

You can see from this code snippet, that removing the subgroup *dmft_results* from the
hdf file has the effect of reseting the calculation to the starting point. If there are previous
runs stored in the hdf5 archive, we can now load the self energy, the chemical potential and
double counting values of the last iteration:

```
if previous_present:
if mpi.is_master_node():
with HDFArchive(dft_filename+'.h5','r') as ar:
S.Sigma_iw << ar['dmft_output']['Sigma_iw']
S.Sigma_iw << mpi.bcast(S.Sigma_iw)
chemical_potential,dc_imp,dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
SK.set_mu(chemical_potential)
SK.set_dc(dc_imp,dc_energ)
```

The data is loaded only on the master node, and therefore we broadcast it to the slave nodes.
Be careful when storing the *iteration_number* as we also have to add the previous
iteration count:

```
ar['dmft_output']['iterations'] = iteration_number + previous_runs
```

## Mixing

In some cases a mixing of two consecutive self energies (or alternatively two hybridization functions) can be necessary in order to ensure convergence:

```
mix = 0.8 # mixing factor
if (iteration_number>1 or previous_present):
if mpi.is_master_node():
with HDFArchive(dft_filename+'.h5','r') as ar:
mpi.report("Mixing Sigma and G with factor %s"%mix)
S.Sigma_iw << mix * S.Sigma_iw + (1.0-mix) * ar['dmft_output']['Sigma_iw']
S.G_iw << mix * S.G_iw + (1.0-mix) * ar['dmft_output']['G_iw']
S.G_iw << mpi.bcast(S.G_iw)
S.Sigma_iw << mpi.bcast(S.Sigma_iw)
```

In this little piece of code, which should be placed after calling the solver, two consecutive
self energies are linearly mixed with the factor *mix*. Of course, it is possible
to implement more advanced mixing schemes (e.g. Broyden’s methods), however, in most cases
simple linear mixing or even no mixing is sufficient for a reasonably fast convergence.