2013-08-07 16:40:18 +02:00
|
|
|
.. _advanced:
|
|
|
|
|
|
|
|
A more advanced example
|
|
|
|
=======================
|
|
|
|
|
|
|
|
Normally, one wants to adjust some more parameters in order to make the calculation more efficient. Here, we
|
|
|
|
will see a more advanced example, which is also suited for parallel execution.
|
|
|
|
First, we load the necessary modules::
|
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
from pytriqs.applications.dft.sumk_dft import *
|
2013-08-07 16:40:18 +02:00
|
|
|
from pytriqs.applications.dft.converters.wien2k_converter import *
|
|
|
|
from pytriqs.applications.dft.solver_multiband import *
|
|
|
|
from pytriqs.gf.local import *
|
|
|
|
from pytriqs.archive import *
|
|
|
|
|
|
|
|
Then we define some parameters::
|
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
dft_filename='srvo3'
|
2014-05-30 02:07:07 +02:00
|
|
|
U = 2.7
|
2013-08-07 16:40:18 +02:00
|
|
|
J = 0.65
|
|
|
|
beta = 40
|
2014-05-30 02:12:43 +02:00
|
|
|
loops = 10 # Number of DMFT sc-loops
|
2014-05-30 02:07:07 +02:00
|
|
|
mix = 0.8 # Mixing factor of Sigma after solution of the AIM
|
2013-08-07 16:40:18 +02:00
|
|
|
Delta_mix = 1.0 # Mixing factor of Delta as input for the AIM
|
|
|
|
dc_type = 1 # DC type: 0 FLL, 1 Held, 2 AMF
|
2014-11-18 11:30:26 +01:00
|
|
|
use_blocks = True # use bloc structure from DFT input
|
2014-05-30 02:07:07 +02:00
|
|
|
use_matrix = False # True: Slater parameters, False: Kanamori parameters U+2J, U, U-J
|
2013-08-07 16:40:18 +02:00
|
|
|
use_spinflip = False # use the full rotational invariant interaction?
|
|
|
|
prec_mu = 0.0001
|
2014-05-30 02:12:43 +02:00
|
|
|
qmc_cycles = 20000
|
2013-08-07 16:40:18 +02:00
|
|
|
length_cycle = 200
|
2014-05-30 02:12:43 +02:00
|
|
|
warming_iterations = 2000
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
Most of these parameters are self-explaining. The first, `dft_filename`, gives the filename of the input files.
|
2013-08-07 16:40:18 +02:00
|
|
|
The next step, as described in the previous section, is to convert the input files::
|
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
Converter = Wien2kConverter(filename=dft_filename, repacking=True)
|
2014-12-09 12:26:00 +01:00
|
|
|
Converter.convert_dft_input()
|
2013-08-07 16:40:18 +02:00
|
|
|
mpi.barrier()
|
|
|
|
|
|
|
|
The command ``mpi.barrier()`` ensures that all nodes wait until the conversion of the input is finished on the master
|
|
|
|
node. After the conversion, we can check in the hdf5 archive, if previous runs are present, or if we have to start
|
|
|
|
from scratch::
|
|
|
|
|
|
|
|
previous_runs = 0
|
|
|
|
previous_present = False
|
|
|
|
if mpi.is_master_node():
|
2014-11-18 11:30:26 +01:00
|
|
|
ar = HDFArchive(dft_filename+'.h5','a')
|
2013-08-07 16:40:18 +02:00
|
|
|
if 'iterations' in ar:
|
|
|
|
previous_present = True
|
|
|
|
previous_runs = ar['iterations']
|
|
|
|
del ar
|
|
|
|
previous_runs = mpi.bcast(previous_runs)
|
|
|
|
previous_present = mpi.bcast(previous_present)
|
|
|
|
# if previous runs are present, no need for recalculating the bloc structure:
|
|
|
|
calc_blocs = use_blocks and (not previous_present)
|
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
Now we can use all this information to initialise the :class:`SumkDFT` class::
|
2013-08-07 16:40:18 +02:00
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
SK=SumkDFT(hdf_file=dft_filename+'.h5',use_dft_blocks=calc_blocs)
|
2013-08-07 16:40:18 +02:00
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
If there was a previous run, we know already about the block structure, and therefore `UseDFTBlocs` is set to `False`.
|
2013-08-07 16:40:18 +02:00
|
|
|
The next step is to initialise the Solver::
|
|
|
|
|
2014-11-26 16:24:02 +01:00
|
|
|
Norb = SK.corr_shells[0]['dim']
|
|
|
|
l = SK.corr_shells[0]['l']
|
2014-01-21 16:49:04 +01:00
|
|
|
S = SolverMultiBand(beta=beta,n_orb=Norb,gf_struct=SK.gf_struct_solver[0],map=SK.map[0])
|
2013-08-07 16:40:18 +02:00
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
As we can see, many options of the solver are set by properties of the :class:`SumkDFT` class, so we don't have
|
2014-03-28 23:29:06 +01:00
|
|
|
to set them manually.
|
2013-08-07 16:40:18 +02:00
|
|
|
|
|
|
|
If there are previous runs stored in the hdf5 archive, we can now load the self energy
|
|
|
|
of the last iteration::
|
|
|
|
|
|
|
|
if (previous_present):
|
|
|
|
if (mpi.is_master_node()):
|
2014-11-18 11:30:26 +01:00
|
|
|
ar = HDFArchive(dft_filename+'.h5','a')
|
2014-10-28 16:19:28 +01:00
|
|
|
S.Sigma << ar['SigmaImFreq']
|
2013-08-07 16:40:18 +02:00
|
|
|
del ar
|
|
|
|
S.Sigma = mpi.bcast(S.Sigma)
|
|
|
|
|
|
|
|
The last command is the broadcasting of the self energy from the master node to the slave nodes.
|
|
|
|
Now we can go to the definition of the self-consistency step. It consists again of the basic steps discussed in the
|
|
|
|
previous section, with some additional refinement::
|
|
|
|
|
|
|
|
for iteration_number in range(1,loops+1) :
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
SK.symm_deg_gf(S.Sigma,orb=0) # symmetrise Sigma
|
|
|
|
SK.put_Sigma(Sigma_imp = [ S.Sigma ]) # put Sigma into the SumK class:
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2014-12-03 23:12:39 +01:00
|
|
|
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential
|
2014-10-28 16:19:28 +01:00
|
|
|
S.G << SK.extract_G_loc()[0] # calculation of the local Green function
|
2013-08-07 16:40:18 +02:00
|
|
|
mpi.report("Total charge of Gloc : %.6f"%S.G.total_density())
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
if ((iteration_number==1)and(previous_present==False)):
|
|
|
|
# Init the DC term and the real part of Sigma, if no previous run was found:
|
|
|
|
dm = S.G.density()
|
2014-12-03 23:12:39 +01:00
|
|
|
SK.calc_dc( dm, U_interact = U, J_hund = J, orb = 0, use_dc_formula = dc_type)
|
2014-10-28 16:19:28 +01:00
|
|
|
S.Sigma << SK.dc_imp[0]['up'][0,0]
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2014-10-28 16:19:28 +01:00
|
|
|
S.G0 << inverse(S.Sigma + inverse(S.G))
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
# Solve the impurity problem:
|
2014-05-30 02:07:07 +02:00
|
|
|
S.solve(U_interact=U,J_hund=J,use_spinflip=use_spinflip,use_matrix=use_matrix,
|
2014-09-22 19:21:10 +02:00
|
|
|
l=l,T=SK.T[0], dim_reps=SK.dim_reps[0], irep=2, n_cycles=qmc_cycles,
|
2014-05-30 02:07:07 +02:00
|
|
|
length_cycle=length_cycle,n_warmup_cycles=warming_iterations)
|
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
# solution done, do the post-processing:
|
|
|
|
mpi.report("Total charge of impurity problem : %.6f"%S.G.total_density())
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2014-10-28 16:19:28 +01:00
|
|
|
S.Sigma <<(inverse(S.G0)-inverse(S.G))
|
2014-05-30 02:07:07 +02:00
|
|
|
# Solve the impurity problem:
|
|
|
|
S.solve(U_interact=U,J_hund=J,use_spinflip=use_spinflip,use_matrix=use_matrix,
|
2014-09-22 19:21:10 +02:00
|
|
|
l=l,T=SK.T[0], dim_reps=SK.dim_reps[0], irep=2, n_cycles=qmc_cycles,
|
2014-05-30 02:07:07 +02:00
|
|
|
length_cycle=length_cycle,n_warmup_cycles=warming_iterations)
|
|
|
|
|
|
|
|
# solution done, do the post-processing:
|
|
|
|
mpi.report("Total charge of impurity problem : %.6f"%S.G.total_density())
|
|
|
|
|
2014-10-28 16:19:28 +01:00
|
|
|
S.Sigma <<(inverse(S.G0)-inverse(S.G))
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
# Now mix Sigma and G with factor Mix, if wanted:
|
2014-05-30 02:07:07 +02:00
|
|
|
if ((iteration_number>1) or (previous_present)):
|
2013-08-07 16:40:18 +02:00
|
|
|
if (mpi.is_master_node()):
|
2014-11-18 11:30:26 +01:00
|
|
|
ar = HDFArchive(dft_filename+'.h5','a')
|
2013-08-07 16:40:18 +02:00
|
|
|
mpi.report("Mixing Sigma and G with factor %s"%mix)
|
2014-10-28 16:19:28 +01:00
|
|
|
S.Sigma << mix * S.Sigma + (1.0-mix) * ar['Sigma']
|
|
|
|
S.G << mix * S.G + (1.0-mix) * ar['GF']
|
2013-08-07 16:40:18 +02:00
|
|
|
del ar
|
|
|
|
S.G = mpi.bcast(S.G)
|
|
|
|
S.Sigma = mpi.bcast(S.Sigma)
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
# Write the final Sigma and G to the hdf5 archive:
|
|
|
|
if (mpi.is_master_node()):
|
2014-11-18 11:30:26 +01:00
|
|
|
ar = HDFArchive(dft_filename+'.h5','a')
|
2014-05-30 02:07:07 +02:00
|
|
|
ar['iterations'] = previous_runs + iteration_number
|
|
|
|
ar['Sigma'] = S.Sigma
|
2013-08-07 16:40:18 +02:00
|
|
|
ar['GF'] = S.G
|
2014-05-30 02:07:07 +02:00
|
|
|
del ar
|
2014-06-02 11:07:50 +02:00
|
|
|
|
2013-08-07 16:40:18 +02:00
|
|
|
# Now set new double counting:
|
|
|
|
dm = S.G.density()
|
2014-12-03 23:12:39 +01:00
|
|
|
SK.calc_dc( dm, U_interact = U, J_hund = J, orb = 0, use_dc_formula = dc_type)
|
2014-05-30 02:07:07 +02:00
|
|
|
|
|
|
|
#Save stuff:
|
2014-11-19 16:54:13 +01:00
|
|
|
SK.save(['chemical_potential','dc_imp','dc_energ'])
|
2014-05-30 02:07:07 +02:00
|
|
|
|
2014-11-18 11:30:26 +01:00
|
|
|
This is all we need for the DFT+DMFT calculation. At the end, all results are stored in the hdf5 output file.
|
2013-08-07 16:40:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
|