mirror of
https://github.com/triqs/dft_tools
synced 2024-11-06 22:23:52 +01:00
Merge branch 'master' into vasp
Conflicts: CMakeLists.txt python/CMakeLists.txt python/converters/__init__.py test/CMakeLists.txt
This commit is contained in:
commit
f142db96fb
@ -14,14 +14,19 @@ enable_testing()
|
|||||||
# Load TRIQS, including all predefined variables from TRIQS installation
|
# Load TRIQS, including all predefined variables from TRIQS installation
|
||||||
find_package(TRIQS REQUIRED)
|
find_package(TRIQS REQUIRED)
|
||||||
|
|
||||||
if (NOT ${TRIQS_WITH_PYTHON_SUPPORT})
|
|
||||||
MESSAGE(FATAL_ERROR "dft_tools require Python support in TRIQS")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Check that versions are compatible
|
# Check that versions are compatible
|
||||||
if(NOT DFT_TOOLS_VERSION EQUAL TRIQS_VERSION)
|
if(NOT DFT_TOOLS_VERSION EQUAL TRIQS_VERSION)
|
||||||
message(FATAL_ERROR "The application version is not compatible with the TRIQS library (TRIQS library version: ${TRIQS_VERSION} while this application version: ${DFT_TOOLS_VERSION})")
|
message(FATAL_ERROR "The application version is not compatible with the TRIQS library (TRIQS library version: ${TRIQS_VERSION} while this application version: ${DFT_TOOLS_VERSION})")
|
||||||
endif()
|
endif()
|
||||||
|
if (NOT ${TRIQS_WITH_PYTHON_SUPPORT})
|
||||||
|
MESSAGE(FATAL_ERROR "dft_tools require Python support in TRIQS")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Get hash
|
||||||
|
triqs_get_git_hash(${CMAKE_SOURCE_DIR} "DFT_TOOLS")
|
||||||
|
if(${GIT_RESULT} EQUAL 0)
|
||||||
|
message(STATUS "Hash: ${DFT_TOOLS_GIT_HASH}")
|
||||||
|
endif(${GIT_RESULT} EQUAL 0)
|
||||||
|
|
||||||
# We want to be installed in the TRIQS tree
|
# We want to be installed in the TRIQS tree
|
||||||
set(CMAKE_INSTALL_PREFIX ${TRIQS_PATH})
|
set(CMAKE_INSTALL_PREFIX ${TRIQS_PATH})
|
||||||
|
8
cmake/sitecustomize.py
Normal file
8
cmake/sitecustomize.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
def application_pytriqs_import(name,*args,**kwargs):
|
||||||
|
if name.startswith('@package_name@'):
|
||||||
|
name = name[len('@package_name@')+1:]
|
||||||
|
return builtin_import(name,*args,**kwargs)
|
||||||
|
|
||||||
|
import __builtin__
|
||||||
|
__builtin__.__import__, builtin_import = application_pytriqs_import, __builtin__.__import__
|
||||||
|
|
@ -77,7 +77,7 @@ for iteration_number in range(1,loops+1):
|
|||||||
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
||||||
|
|
||||||
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma_iw ]) # put Sigma into the SumK class
|
SK.set_Sigma([ S.Sigma_iw ]) # set Sigma into the SumK class
|
||||||
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
||||||
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
||||||
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#
|
#
|
||||||
# TRIQS documentation build configuration file
|
# TRIQS documentation build configuration file
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "@TRIQS_SPHINXEXT_PATH@/numpydoc")
|
||||||
|
|
||||||
extensions = ['sphinx.ext.autodoc',
|
extensions = ['sphinx.ext.autodoc',
|
||||||
'sphinx.ext.mathjax',
|
'sphinx.ext.mathjax',
|
||||||
'sphinx.ext.intersphinx',
|
'sphinx.ext.intersphinx',
|
||||||
|
@ -3,13 +3,14 @@ Frequently-Asked Questions
|
|||||||
|
|
||||||
wien2k: FERMI ERROR when running `x lapw2 -almd -band`
|
wien2k: FERMI ERROR when running `x lapw2 -almd -band`
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
|
|
||||||
In some versions of Wien2k, there is a problem in running `x lapw2 -almd -band`.
|
In some versions of Wien2k, there is a problem in running `x lapw2 -almd -band`.
|
||||||
|
|
||||||
A hack solution is as follows:
|
A hack solution is as follows:
|
||||||
1) `x lapw1 -band`
|
1) `x lapw1 -band`
|
||||||
2) edit in2 file: replace 'TOT' with 'QTL', 'TETRA' with 'ROOT'
|
2) edit in2 file: replace 'TOT' with 'QTL', 'TETRA' with 'ROOT'
|
||||||
3) `x lapw2 -almd -band`
|
3) `x lapw2 -almd -band`
|
||||||
4) `dmftproj -band` (add the fermi energy to file, it can be found by running `grep :FER *.scf`)
|
4) `dmftproj -band` (add the Fermi energy to file, it can be found by running `grep :FER *.scf`)
|
||||||
|
|
||||||
How do I plot the output of `spaghettis`?
|
How do I plot the output of `spaghettis`?
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
@ -20,6 +21,20 @@ the parameters as desired.
|
|||||||
|
|
||||||
.. literalinclude:: plotting_spaghettis.py
|
.. literalinclude:: plotting_spaghettis.py
|
||||||
|
|
||||||
|
x optic does not write a case.pmat file
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
Make sure that you set line 6 to "ON" and put a "1" to the following line.
|
||||||
|
The "1" is undocumented in Wien2k, but needed to have `case.pmat` written.
|
||||||
|
However, we are working on reading directly the `case.mommat2` file.
|
||||||
|
|
||||||
|
No module named pytriqs.*** error when running a script
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
Make sure that have properly build, tested and installed TRIQS and DFTTools
|
||||||
|
using, make, make test and make install. Additionally, you should always
|
||||||
|
use pytriqs to call your scripts, e.g. pytriqs yourscript.py
|
||||||
|
|
||||||
Why is my calculation not working?
|
Why is my calculation not working?
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
|
@ -64,9 +64,9 @@ where:
|
|||||||
It is important that each data file has to contain three columns: the real frequency mesh, the real part and the imaginary part
|
It is important that each data file has to contain three columns: the real frequency mesh, the real part and the imaginary part
|
||||||
of the self energy - exactly in this order! The mesh should be the same for all files read in and non-uniform meshes are not supported.
|
of the self energy - exactly in this order! The mesh should be the same for all files read in and non-uniform meshes are not supported.
|
||||||
|
|
||||||
Finally, we put the self energy into the `SK` object::
|
Finally, we set the self energy into the `SK` object::
|
||||||
|
|
||||||
SK.put_Sigma(Sigma_imp = [SigmaReFreq])
|
SK.set_Sigma([SigmaReFreq])
|
||||||
|
|
||||||
and additionally set the chemical potential and the double counting correction from the DMFT calculation::
|
and additionally set the chemical potential and the double counting correction from the DMFT calculation::
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ the output is printed into the files
|
|||||||
* `DOS_wannier_(sp)_proj(i)_(m)_(n).dat`: As above, but printed as orbitally-resolved matrix in indices
|
* `DOS_wannier_(sp)_proj(i)_(m)_(n).dat`: As above, but printed as orbitally-resolved matrix in indices
|
||||||
`(m)` and `(n)`. For `d` orbitals, it gives the DOS separately for, e.g., :math:`d_{xy}`, :math:`d_{x^2-y^2}`, and so on,
|
`(m)` and `(n)`. For `d` orbitals, it gives the DOS separately for, e.g., :math:`d_{xy}`, :math:`d_{x^2-y^2}`, and so on,
|
||||||
|
|
||||||
otherwise, the ouptput is returned by the function for a further usage in :program:`python`.
|
otherwise, the output is returned by the function for a further usage in :program:`python`.
|
||||||
|
|
||||||
Partial charges
|
Partial charges
|
||||||
---------------
|
---------------
|
||||||
@ -104,7 +104,7 @@ Partial charges
|
|||||||
Since we can calculate the partial charges directly from the Matsubara Green's functions, we also do not need a
|
Since we can calculate the partial charges directly from the Matsubara Green's functions, we also do not need a
|
||||||
real frequency self energy for this purpose. The calculation is done by::
|
real frequency self energy for this purpose. The calculation is done by::
|
||||||
|
|
||||||
SK.put_Sigma(Sigma_imp = SigmaImFreq)
|
SK.set_Sigma(SigmaImFreq)
|
||||||
dm = SK.partial_charges(beta=40.0, with_Sigma=True, with_dc=True)
|
dm = SK.partial_charges(beta=40.0, with_Sigma=True, with_dc=True)
|
||||||
|
|
||||||
which calculates the partial charges using the self energy, double counting, and chemical potential as set in the
|
which calculates the partial charges using the self energy, double counting, and chemical potential as set in the
|
||||||
|
@ -15,7 +15,7 @@ Interface with Wien2k
|
|||||||
|
|
||||||
We assume that the user has obtained a self-consistent solution of the
|
We assume that the user has obtained a self-consistent solution of the
|
||||||
Kohn-Sham equations. We further have to require that the user is
|
Kohn-Sham equations. We further have to require that the user is
|
||||||
familiar with the main inout/output files of Wien2k, and how to run
|
familiar with the main in/output files of Wien2k, and how to run
|
||||||
the DFT code.
|
the DFT code.
|
||||||
|
|
||||||
Conversion for the DMFT self-consistency cycle
|
Conversion for the DMFT self-consistency cycle
|
||||||
@ -31,7 +31,7 @@ We note that any other flag for lapw2, such as -c or -so (for
|
|||||||
spin-orbit coupling) has to be added also to this line. This creates
|
spin-orbit coupling) has to be added also to this line. This creates
|
||||||
some files that we need for the Wannier orbital construction.
|
some files that we need for the Wannier orbital construction.
|
||||||
|
|
||||||
The orbital construction itself is done by the fortran program
|
The orbital construction itself is done by the Fortran program
|
||||||
:program:`dmftproj`. For an extensive manual to this program see
|
:program:`dmftproj`. For an extensive manual to this program see
|
||||||
:download:`TutorialDmftproj.pdf <images_scripts/TutorialDmftproj.pdf>`.
|
:download:`TutorialDmftproj.pdf <images_scripts/TutorialDmftproj.pdf>`.
|
||||||
Here we will only describe only the basic steps.
|
Here we will only describe only the basic steps.
|
||||||
@ -79,7 +79,7 @@ following 3 to 5 lines:
|
|||||||
|
|
||||||
These lines have to be repeated for each inequivalent atom.
|
These lines have to be repeated for each inequivalent atom.
|
||||||
|
|
||||||
The last line gives the energy window, relativ to the Fermi energy,
|
The last line gives the energy window, relative to the Fermi energy,
|
||||||
that is used for the projective Wannier functions. Note that, in
|
that is used for the projective Wannier functions. Note that, in
|
||||||
accordance with Wien2k, we give energies in Rydberg units!
|
accordance with Wien2k, we give energies in Rydberg units!
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ The lines of this header define
|
|||||||
2 3. Thiw would mean, 2 irreps (eg and t2g), of dimension 2 and 3,
|
2 3. Thiw would mean, 2 irreps (eg and t2g), of dimension 2 and 3,
|
||||||
resp.
|
resp.
|
||||||
|
|
||||||
After these header lines, the file has to contain the hamiltonian
|
After these header lines, the file has to contain the Hamiltonian
|
||||||
matrix in orbital space. The standard convention is that you give for
|
matrix in orbital space. The standard convention is that you give for
|
||||||
each
|
each
|
||||||
:math:`\mathbf{k}`-point first the matrix of the real part, then the
|
:math:`\mathbf{k}`-point first the matrix of the real part, then the
|
||||||
@ -227,6 +227,116 @@ with the
|
|||||||
For more options of this converter, have a look at the
|
For more options of this converter, have a look at the
|
||||||
:ref:`refconverters` section of the reference manual.
|
:ref:`refconverters` section of the reference manual.
|
||||||
|
|
||||||
|
|
||||||
|
Wannier90 Converter
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Using this converter it is possible to convert the output of
|
||||||
|
:program:`Wannier90` (http://wannier.org) calculations of
|
||||||
|
Maximally Localized Wannier Functions (MLWF) and create a HDF5 archive
|
||||||
|
suitable for one-shot DMFT calculations with the
|
||||||
|
:class:`SumkDFT <pytriqs.applications.dft.sumk_dft.SumkDFT>` class.
|
||||||
|
|
||||||
|
The user must supply two files in order to run the Wannier90 Converter:
|
||||||
|
|
||||||
|
#. The file :file:`seedname_hr.dat`, which contains the DFT Hamiltonian
|
||||||
|
in the MLWF basis calculated through :program:`wannier90` with ``hr_plot = true``
|
||||||
|
(please refer to the :program:`wannier90` documentation).
|
||||||
|
#. A file named :file:`seedname.inp`, which contains the required
|
||||||
|
information about the :math:`\mathbf{k}`-point mesh, the electron density,
|
||||||
|
the correlated shell structure, ... (see below).
|
||||||
|
|
||||||
|
Here and in the following, the keyword ``seedname`` should always be intended
|
||||||
|
as a placeholder for the actual prefix chosen by the user when creating the
|
||||||
|
input for :program:`wannier90`.
|
||||||
|
Once these two files are available, one can use the converter as follows::
|
||||||
|
|
||||||
|
from pytriqs.applications.dft.converters import Wannier90Converter
|
||||||
|
Converter = Wannier90Converter(seedname='seedname')
|
||||||
|
Converter.convert_dft_input()
|
||||||
|
|
||||||
|
The converter input :file:`seedname.inp` is a simple text file with
|
||||||
|
the following format:
|
||||||
|
|
||||||
|
.. literalinclude:: images_scripts/LaVO3_w90.inp
|
||||||
|
|
||||||
|
The example shows the input for the perovskite crystal of LaVO\ :sub:`3`
|
||||||
|
in the room-temperature `Pnma` symmetry. The unit cell contains four
|
||||||
|
symmetry-equivalent correlated sites (the V atoms) and the total number
|
||||||
|
of electrons per unit cell is 8 (see second line).
|
||||||
|
The first line specifies how to generate the :math:`\mathbf{k}`-point
|
||||||
|
mesh that will be used to obtain :math:`H(\mathbf{k})`
|
||||||
|
by Fourier transforming :math:`H(\mathbf{R})`.
|
||||||
|
Currently implemented options are:
|
||||||
|
|
||||||
|
* :math:`\Gamma`-centered uniform grid with dimensions
|
||||||
|
:math:`n_{k_x} \times n_{k_y} \times n_{k_z}`;
|
||||||
|
specify ``0`` followed by the three grid dimensions,
|
||||||
|
like in the example above
|
||||||
|
* :math:`\Gamma`-centered uniform grid with dimensions
|
||||||
|
automatically determined by the converter (from the number of
|
||||||
|
:math:`\mathbf{R}` vectors found in :file:`seedname_hr.dat`);
|
||||||
|
just specify ``-1``
|
||||||
|
|
||||||
|
Inside :file:`seedname.inp`, it is crucial to correctly specify the
|
||||||
|
correlated shell structure, which depends on the contents of the
|
||||||
|
:program:`wannier90` output :file:`seedname_hr.dat` and on the order
|
||||||
|
of the MLWFs contained in it.
|
||||||
|
|
||||||
|
The number of MLWFs must be equal to, or greater than the total number
|
||||||
|
of correlated orbitals (i.e., the sum of all ``dim`` in :file:`seedname.inp`).
|
||||||
|
If the converter finds fewer MLWFs inside :file:`seedname_hr.dat`, then it
|
||||||
|
stops with an error; if it finds more MLWFs, then it assumes that the
|
||||||
|
additional MLWFs correspond to uncorrelated orbitals (e.g., the O-\ `2p` shells).
|
||||||
|
When reading the hoppings :math:`\langle w_i | H(\mathbf{R}) | w_j \rangle`
|
||||||
|
(where :math:`w_i` is the :math:`i`-th MLWF), the converter also assumes that
|
||||||
|
the first indices correspond to the correlated shells (in our example,
|
||||||
|
the V-t\ :sub:`2g` shells). Therefore, the MLWFs corresponding to the
|
||||||
|
uncorrelated shells (if present) must be listed **after** those of the
|
||||||
|
correlated shells.
|
||||||
|
With the :program:`wannier90` code, this can be achieved this by listing the
|
||||||
|
projections for the uncorrelated shells after those for the correlated shells.
|
||||||
|
In our `Pnma`-LaVO\ :sub:`3` example, for instance, we could use::
|
||||||
|
|
||||||
|
Begin Projections
|
||||||
|
V:l=2,mr=2,3,5:z=0,0,1:x=-1,1,0
|
||||||
|
O:l=1:mr=1,2,3:z=0,0,1:x=-1,1,0
|
||||||
|
End Projections
|
||||||
|
|
||||||
|
where the ``x=-1,1,0`` option indicates that the V--O bonds in the octahedra are
|
||||||
|
rotated by (approximatively) 45 degrees with respect to the axes of the `Pbnm` cell.
|
||||||
|
|
||||||
|
The converter will analyse the matrix elements of the local hamiltonian
|
||||||
|
to find the symmetry matrices `rot_mat` needed for the global-to-local
|
||||||
|
transformation of the basis set for correlated orbitals
|
||||||
|
(see section :ref:`hdfstructure`).
|
||||||
|
The matrices are obtained by finding the unitary transformations that diagonalize
|
||||||
|
:math:`\langle w_i | H_I(\mathbf{R}=0,0,0) | w_j \rangle`, where :math:`I` runs
|
||||||
|
over the correlated shells and `i,j` belong to the same shell (more details elsewhere...).
|
||||||
|
If two correlated shells are defined as equivalent in :file:`seedname.inp`,
|
||||||
|
then the corresponding eigenvalues have to match within a threshold of 10\ :sup:`-5`,
|
||||||
|
otherwise the converter will produce an error/warning.
|
||||||
|
If this happens, please carefully check your data in :file:`seedname_hr.dat`.
|
||||||
|
This method might fail in non-trivial cases (i.e., more than one correlated
|
||||||
|
shell is present) when there are some degenerate eigenvalues:
|
||||||
|
so far tests have not shown any issue, but one must be careful in those cases
|
||||||
|
(the converter will print a warning message).
|
||||||
|
|
||||||
|
The current implementation of the Wannier90 Converter has some limitations:
|
||||||
|
|
||||||
|
* Since :program:`wannier90` does not make use of symmetries (symmetry-reduction
|
||||||
|
of the :math:`\mathbf{k}`-point grid is not possible), the converter always
|
||||||
|
sets ``symm_op=0`` (see the :ref:`hdfstructure` section).
|
||||||
|
* No charge self-consistency possible at the moment.
|
||||||
|
* Calculations with spin-orbit (``SO=1``) are not supported.
|
||||||
|
* The spin-polarized case (``SP=1``) is not yet tested.
|
||||||
|
* The post-processing routines in the module
|
||||||
|
:class:`SumkDFTTools <pytriqs.applications.dft.sumk_dft_tools.SumkDFTTools>`
|
||||||
|
were not tested with this converter.
|
||||||
|
* ``proj_mat_all`` are not used, so there are no projectors onto the
|
||||||
|
uncorrelated orbitals for now.
|
||||||
|
|
||||||
|
|
||||||
MPI issues
|
MPI issues
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ These steps are not necessary, but can help to reduce fluctuations in the total
|
|||||||
Now we calculate the modified charge density::
|
Now we calculate the modified charge density::
|
||||||
|
|
||||||
# find exact chemical potential
|
# find exact chemical potential
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma_iw ])
|
SK.set_Sigma([ S.Sigma_iw ])
|
||||||
chemical_potential = SK.calc_mu( precision = 0.000001 )
|
chemical_potential = SK.calc_mu( precision = 0.000001 )
|
||||||
dN, d = SK.calc_density_correction(filename = dft_filename+'.qdmft')
|
dN, d = SK.calc_density_correction(filename = dft_filename+'.qdmft')
|
||||||
SK.save(['chemical_potential','dc_imp','dc_energ'])
|
SK.save(['chemical_potential','dc_imp','dc_energ'])
|
||||||
@ -56,10 +56,10 @@ We need also the correlation energy, which we evaluate by the Migdal formula::
|
|||||||
correnerg = 0.5 * (S.G_iw * S.Sigma_iw).total_density()
|
correnerg = 0.5 * (S.G_iw * S.Sigma_iw).total_density()
|
||||||
|
|
||||||
Other ways of calculating the correlation energy are possible, for
|
Other ways of calculating the correlation energy are possible, for
|
||||||
instance a direct measurment of the expectation value of the
|
instance a direct measurement of the expectation value of the
|
||||||
interacting hamiltonian. However, the Migdal formula works always,
|
interacting Hamiltonian. However, the Migdal formula works always,
|
||||||
independent of the solver that is used to solve the impurity problem.
|
independent of the solver that is used to solve the impurity problem.
|
||||||
From this value, we substract the double counting energy::
|
From this value, we subtract the double counting energy::
|
||||||
|
|
||||||
correnerg -= SK.dc_energ[0]
|
correnerg -= SK.dc_energ[0]
|
||||||
|
|
||||||
@ -104,13 +104,13 @@ number of nodes to be used:
|
|||||||
|
|
||||||
In that case, you will run on 64 computing cores. As standard setting,
|
In that case, you will run on 64 computing cores. As standard setting,
|
||||||
we use `mpirun` as the proper MPI execution statement. If you happen
|
we use `mpirun` as the proper MPI execution statement. If you happen
|
||||||
to have a differnet, non-standard MPI setup, you have to give the
|
to have a different, non-standard MPI setup, you have to give the
|
||||||
proper MPI execution statement, in the `run_lapw` script (see the
|
proper MPI execution statement, in the `run_lapw` script (see the
|
||||||
corresponding :program:`Wien2k` documentation).
|
corresponding :program:`Wien2k` documentation).
|
||||||
|
|
||||||
In many cases it is advisable to start from a converged one-shot
|
In many cases it is advisable to start from a converged one-shot
|
||||||
calculation. For practical purposes, you keep the number of DMFT loops
|
calculation. For practical purposes, you keep the number of DMFT loops
|
||||||
within one DFT cycle low, or even to `loops=1`. If you encouter
|
within one DFT cycle low, or even to `loops=1`. If you encounter
|
||||||
unstable convergence, you have to adjust the parameters such as
|
unstable convergence, you have to adjust the parameters such as
|
||||||
the number of DMFT loops, or some mixing of the self energy to improve
|
the number of DMFT loops, or some mixing of the self energy to improve
|
||||||
the convergence.
|
the convergence.
|
||||||
|
@ -50,7 +50,7 @@ iterations and the self-consistency condition::
|
|||||||
n_loops = 5
|
n_loops = 5
|
||||||
for iteration_number in range(n_loops) : # start the DMFT loop
|
for iteration_number in range(n_loops) : # start the DMFT loop
|
||||||
|
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma ]) # Put self energy to the SumK class
|
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
|
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.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.G0_iw << inverse(S.Sigma_iw + inverse(S.G_iw)) # finally get G0, the input for the Solver
|
||||||
@ -107,7 +107,7 @@ execution. For the convenience of the user, we provide also two
|
|||||||
working python scripts in this documentation. One for a calculation
|
working python scripts in this documentation. One for a calculation
|
||||||
using Kanamori definitions (:download:`dft_dmft_cthyb.py
|
using Kanamori definitions (:download:`dft_dmft_cthyb.py
|
||||||
<images_scripts/dft_dmft_cthyb.py>`) and one with a
|
<images_scripts/dft_dmft_cthyb.py>`) and one with a
|
||||||
rotational-invariant Slater interaction hamiltonian (:download:`dft_dmft_cthyb_slater.py
|
rotational-invariant Slater interaction Hamiltonian (:download:`dft_dmft_cthyb_slater.py
|
||||||
<images_scripts/dft_dmft_cthyb.py>`). The user has to adapt these
|
<images_scripts/dft_dmft_cthyb.py>`). The user has to adapt these
|
||||||
scripts to his own needs.
|
scripts to his own needs.
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ Most of these parameters are self-explanatory. The first,
|
|||||||
details on the solver parameters, we refer the user to
|
details on the solver parameters, we refer the user to
|
||||||
the :ref:`CTHYB solver <triqscthyb:welcome>` documentation.
|
the :ref:`CTHYB solver <triqscthyb:welcome>` documentation.
|
||||||
|
|
||||||
We assume that the conversion to the hdf5 archive is alreadz done. We
|
We assume that the conversion to the hdf5 archive is already done. We
|
||||||
can check now in this archive, if previous runs are present, or if we have to start
|
can check now in this archive, if previous runs are present, or if we have to start
|
||||||
from scratch::
|
from scratch::
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ from scratch::
|
|||||||
previous_present = mpi.bcast(previous_present)
|
previous_present = mpi.bcast(previous_present)
|
||||||
|
|
||||||
|
|
||||||
You can see in this code snipet, that all results of this calculation
|
You can see in this code snippet, that all results of this calculation
|
||||||
will be stored in a separate subgroup in the hdf5 file, called
|
will be stored in a separate subgroup in the hdf5 file, called
|
||||||
`dmft_output`. Removing this subgroup allows you to reset your
|
`dmft_output`. Removing this subgroup allows you to reset your
|
||||||
calculation to the starting point easily.
|
calculation to the starting point easily.
|
||||||
@ -178,7 +178,7 @@ The next step is to initialise the :class:`Solver <pytriqs.applications.impurit
|
|||||||
of two steps
|
of two steps
|
||||||
|
|
||||||
#. Calculating the multi-band interaction matrix, and setting up the
|
#. Calculating the multi-band interaction matrix, and setting up the
|
||||||
interaction hamiltonian
|
interaction Hamiltonian
|
||||||
#. Setting up the solver class
|
#. Setting up the solver class
|
||||||
|
|
||||||
The first step is done using methods of
|
The first step is done using methods of
|
||||||
@ -199,13 +199,13 @@ other choices (Slater interaction matrix for instance), and other
|
|||||||
parameters, we refer to the reference manual
|
parameters, we refer to the reference manual
|
||||||
of the :ref:`TRIQS <triqslibs:welcome>` library.
|
of the :ref:`TRIQS <triqslibs:welcome>` library.
|
||||||
|
|
||||||
Next, we construct the hamiltonian and the solver::
|
Next, we construct the Hamiltonian and the solver::
|
||||||
|
|
||||||
h_int = h_int_density(spin_names, orb_names, map_operator_structure=SK.sumk_to_solver[0], U=Umat, Uprime=Upmat)
|
h_int = h_int_density(spin_names, orb_names, map_operator_structure=SK.sumk_to_solver[0], U=Umat, Uprime=Upmat)
|
||||||
S = Solver(beta=beta, gf_struct=gf_struct)
|
S = Solver(beta=beta, gf_struct=gf_struct)
|
||||||
|
|
||||||
As you see, we take only density-density interactions into
|
As you see, we take only density-density interactions into
|
||||||
account. Other choices for the hamiltonian are
|
account. Other choices for the Hamiltonian are
|
||||||
|
|
||||||
* h_int_kanamori
|
* h_int_kanamori
|
||||||
* h_int_slater
|
* h_int_slater
|
||||||
@ -239,7 +239,7 @@ refinements::
|
|||||||
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
||||||
|
|
||||||
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma_iw ]) # put Sigma into the SumK class
|
SK.set_Sigma([ S.Sigma_iw ]) # put Sigma into the SumK class
|
||||||
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
||||||
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
||||||
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
||||||
|
@ -73,7 +73,7 @@ This program produces the following files:
|
|||||||
|
|
||||||
* :file:`Ce-gamma.ctqmcout` and :file:`Ce-gamma.symqmc` containing projector operators and symmetry operations for orthonormalized Wannier orbitals, respectively.
|
* :file:`Ce-gamma.ctqmcout` and :file:`Ce-gamma.symqmc` containing projector operators and symmetry operations for orthonormalized Wannier orbitals, respectively.
|
||||||
* :file:`Ce-gamma.parproj` and :file:`Ce-gamma.sympar` containing projector operators and symmetry operations for uncorrelated states, respectively. These files are needed for projected density-of-states or spectral-function calculations.
|
* :file:`Ce-gamma.parproj` and :file:`Ce-gamma.sympar` containing projector operators and symmetry operations for uncorrelated states, respectively. These files are needed for projected density-of-states or spectral-function calculations.
|
||||||
* :file:`Ce-gamma.oubwin` needed for the charge desity recalculation in the case of fully self-consistent DFT+DMFT run (see below).
|
* :file:`Ce-gamma.oubwin` needed for the charge density recalculation in the case of fully self-consistent DFT+DMFT run (see below).
|
||||||
|
|
||||||
Now we have all necessary input from :program:`Wien2k` for running DMFT calculations.
|
Now we have all necessary input from :program:`Wien2k` for running DMFT calculations.
|
||||||
|
|
||||||
@ -101,9 +101,9 @@ The Hubbard-I initialization `Solver` has also optional parameters one may use:
|
|||||||
|
|
||||||
* `n_msb`: the number of Matsubara frequencies used. The default is `n_msb=1025`.
|
* `n_msb`: the number of Matsubara frequencies used. The default is `n_msb=1025`.
|
||||||
* `use_spin_orbit`: if set 'True' the solver is run with spin-orbit coupling included. To perform actual DFT+DMFT calculations with spin-orbit one should also run :program:`Wien2k` and :program:`dmftproj` in spin-polarized mode and with spin-orbit included. By default, `use_spin_orbit=False`.
|
* `use_spin_orbit`: if set 'True' the solver is run with spin-orbit coupling included. To perform actual DFT+DMFT calculations with spin-orbit one should also run :program:`Wien2k` and :program:`dmftproj` in spin-polarized mode and with spin-orbit included. By default, `use_spin_orbit=False`.
|
||||||
* `Nmoments`: the number of moments used to describe high-ferquency tails of the Hubbard-I Green's function and self-energy. By default `Nmoments = 5`
|
* `Nmoments`: the number of moments used to describe high-frequency tails of the Hubbard-I Green's function and self-energy. By default `Nmoments = 5`
|
||||||
|
|
||||||
The `Solver.solve(U_int, J_hund)` statement has two necessary parameters, the Hubbard U parameter `U_int` and Hund's rule coupling `J_hund`. Notice that the solver constructs the full 4-index `U`-matrix by default, and the `U_int` parameter is in fact the Slatter `F0` integral. Other optional parameters are:
|
The `Solver.solve(U_int, J_hund)` statement has two necessary parameters, the Hubbard U parameter `U_int` and Hund's rule coupling `J_hund`. Notice that the solver constructs the full 4-index `U`-matrix by default, and the `U_int` parameter is in fact the Slater `F0` integral. Other optional parameters are:
|
||||||
|
|
||||||
* `T`: matrix that transforms the interaction matrix from complex spherical harmonics to a symmetry adapted basis. By default, the complex spherical harmonics basis is used and `T=None`.
|
* `T`: matrix that transforms the interaction matrix from complex spherical harmonics to a symmetry adapted basis. By default, the complex spherical harmonics basis is used and `T=None`.
|
||||||
* `verbosity`: tunes output from the solver. If `verbosity=0` only basic information is printed, if `verbosity=1` the ground state atomic occupancy and its energy are printed, if `verbosity=2` additional information is printed for all occupancies that were diagonalized. By default, `verbosity=0`.
|
* `verbosity`: tunes output from the solver. If `verbosity=0` only basic information is printed, if `verbosity=1` the ground state atomic occupancy and its energy are printed, if `verbosity=2` additional information is printed for all occupancies that were diagonalized. By default, `verbosity=0`.
|
||||||
|
@ -2,7 +2,6 @@ from pytriqs.applications.dft.sumk_dft import *
|
|||||||
from pytriqs.applications.dft.converters.wien2k_converter import *
|
from pytriqs.applications.dft.converters.wien2k_converter import *
|
||||||
from pytriqs.applications.impurity_solvers.hubbard_I.hubbard_solver import Solver
|
from pytriqs.applications.impurity_solvers.hubbard_I.hubbard_solver import Solver
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
dft_filename = os.getcwd().rpartition('/')[2]
|
dft_filename = os.getcwd().rpartition('/')[2]
|
||||||
|
|
||||||
@ -10,14 +9,12 @@ beta = 40
|
|||||||
U_int = 6.00
|
U_int = 6.00
|
||||||
J_hund = 0.70
|
J_hund = 0.70
|
||||||
Loops = 5 # Number of DMFT sc-loops
|
Loops = 5 # Number of DMFT sc-loops
|
||||||
Mix = 0.7 # Mixing factor in QMC
|
mixing = 0.7 # Mixing factor
|
||||||
DC_type = 0 # 0...FLL, 1...Held, 2... AMF, 3...Lichtenstein
|
DC_type = 0 # 0...FLL, 1...Held, 2... AMF, 3...Lichtenstein
|
||||||
chemical_potential_init=0.0 # initial chemical potential
|
chemical_potential_init=0.0 # initial chemical potential
|
||||||
|
|
||||||
HDFfilename = dft_filename+'.h5'
|
|
||||||
|
|
||||||
# Convert DMFT input:
|
# Convert DMFT input:
|
||||||
Converter = Wien2kConverter(filename=filename)
|
Converter = Wien2kConverter(filename=dft_filename)
|
||||||
Converter.convert_dft_input()
|
Converter.convert_dft_input()
|
||||||
mpi.barrier()
|
mpi.barrier()
|
||||||
|
|
||||||
@ -25,7 +22,7 @@ mpi.barrier()
|
|||||||
previous_runs = 0
|
previous_runs = 0
|
||||||
previous_present = False
|
previous_present = False
|
||||||
if mpi.is_master_node():
|
if mpi.is_master_node():
|
||||||
f = HDFArchive(filename+'.h5','a')
|
f = HDFArchive(dft_filename+'.h5','a')
|
||||||
if 'dmft_output' in f:
|
if 'dmft_output' in f:
|
||||||
ar = f['dmft_output']
|
ar = f['dmft_output']
|
||||||
if 'iterations' in ar:
|
if 'iterations' in ar:
|
||||||
@ -53,11 +50,11 @@ if previous_present:
|
|||||||
ar = HDFArchive(dft_filename+'.h5','a')
|
ar = HDFArchive(dft_filename+'.h5','a')
|
||||||
S.Sigma << ar['dmft_output']['Sigma']
|
S.Sigma << ar['dmft_output']['Sigma']
|
||||||
del ar
|
del ar
|
||||||
chemical_potential,dc_imp,dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
|
SK.chemical_potential,SK.dc_imp,SK.dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
|
||||||
S.Sigma << mpi.bcast(S.Sigma)
|
S.Sigma << mpi.bcast(S.Sigma)
|
||||||
SK.set_mu(chemical_potential)
|
SK.chemical_potential = mpi.bcast(SK.chemical_potential)
|
||||||
SK.set_dc(dc_imp,dc_energ)
|
SK.dc_imp = mpi.bcast(SK.dc_imp)
|
||||||
|
SK.dc_energ = mpi.bcast(SK.dc_energ)
|
||||||
|
|
||||||
# DMFT loop:
|
# DMFT loop:
|
||||||
for iteration_number in range(1,Loops+1):
|
for iteration_number in range(1,Loops+1):
|
||||||
@ -65,7 +62,7 @@ for iteration_number in range(1,Loops+1):
|
|||||||
itn = iteration_number + previous_runs
|
itn = iteration_number + previous_runs
|
||||||
|
|
||||||
# put Sigma into the SumK class:
|
# put Sigma into the SumK class:
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma ])
|
SK.set_Sigma([ S.Sigma ])
|
||||||
|
|
||||||
# Compute the SumK, possibly fixing mu by dichotomy
|
# Compute the SumK, possibly fixing mu by dichotomy
|
||||||
chemical_potential = SK.calc_mu( precision = 0.000001 )
|
chemical_potential = SK.calc_mu( precision = 0.000001 )
|
||||||
@ -89,11 +86,11 @@ for iteration_number in range(1,Loops+1):
|
|||||||
|
|
||||||
# Now mix Sigma and G with factor Mix, if wanted:
|
# Now mix Sigma and G with factor Mix, if wanted:
|
||||||
if (iteration_number>1 or previous_present):
|
if (iteration_number>1 or previous_present):
|
||||||
if (mpi.is_master_node() and (sigma_mix<1.0)):
|
if (mpi.is_master_node() and (mixing<1.0)):
|
||||||
ar = HDFArchive(dft_filename+'.h5','a')
|
ar = HDFArchive(dft_filename+'.h5','a')
|
||||||
mpi.report("Mixing Sigma and G with factor %s"%sigma_mix)
|
mpi.report("Mixing Sigma and G with factor %s"%mixing)
|
||||||
S.Sigma << sigma_mix * S.Sigma + (1.0-sigma_mix) * ar['dmft_output']['Sigma']
|
S.Sigma << mixing * S.Sigma + (1.0-mixing) * ar['dmft_output']['Sigma']
|
||||||
S.G << sigma_mix * S.G + (1.0-sigma_mix) * ar['dmft_output']['G']
|
S.G << mixing * S.G + (1.0-mixing) * ar['dmft_output']['G']
|
||||||
del ar
|
del ar
|
||||||
S.G << mpi.bcast(S.G)
|
S.G << mpi.bcast(S.G)
|
||||||
S.Sigma << mpi.bcast(S.Sigma)
|
S.Sigma << mpi.bcast(S.Sigma)
|
||||||
@ -104,8 +101,8 @@ for iteration_number in range(1,Loops+1):
|
|||||||
SK.calc_dc( dm, U_interact = U_int, J_hund = J_hund, orb = 0, use_dc_formula = DC_type )
|
SK.calc_dc( dm, U_interact = U_int, J_hund = J_hund, orb = 0, use_dc_formula = DC_type )
|
||||||
|
|
||||||
# correlation energy calculations:
|
# correlation energy calculations:
|
||||||
correnerg = 0.5 * (S.G * S.Sigma).total_density()
|
SK.correnerg = 0.5 * (S.G * S.Sigma).total_density()
|
||||||
mpi.report("Corr. energy = %s"%correnerg)
|
mpi.report("Corr. energy = %s"%SK.correnerg)
|
||||||
|
|
||||||
# store the impurity self-energy, GF as well as correlation energy in h5
|
# store the impurity self-energy, GF as well as correlation energy in h5
|
||||||
if mpi.is_master_node():
|
if mpi.is_master_node():
|
||||||
@ -145,7 +142,7 @@ mpi.report("Trace of Density Matrix: %s"%d)
|
|||||||
|
|
||||||
# store correlation energy contribution to be read by Wien2ki and then included to DFT+DMFT total energy
|
# store correlation energy contribution to be read by Wien2ki and then included to DFT+DMFT total energy
|
||||||
if (mpi.is_master_node()):
|
if (mpi.is_master_node()):
|
||||||
correnerg -= DCenerg[0]
|
SK.correnerg -= SK.dc_energ[0]
|
||||||
f=open(dft_filename+'.qdmft','a')
|
f=open(dft_filename+'.qdmft','a')
|
||||||
f.write("%.16f\n"%correnerg)
|
f.write("%.16f\n"%SK.correnerg)
|
||||||
f.close()
|
f.close()
|
||||||
|
@ -14,23 +14,21 @@ ommax=6.0
|
|||||||
N_om=2001
|
N_om=2001
|
||||||
broadening = 0.02
|
broadening = 0.02
|
||||||
|
|
||||||
HDFfilename = dft_filename+'.h5'
|
|
||||||
|
|
||||||
# Convert DMFT input:
|
# Convert DMFT input:
|
||||||
Converter = Wien2kConverter(filename=dft_filename,repacking=True)
|
Converter = Wien2kConverter(filename=dft_filename,repacking=True)
|
||||||
Converter.convert_dft_input()
|
Converter.convert_dft_input()
|
||||||
Converter.convert_parproj_input()
|
Converter.convert_parproj_input()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Init the SumK class
|
# Init the SumK class
|
||||||
SK = SumkDFTTools(hdf_file=dft_filename+'.h5',use_dft_blocks=False)
|
SK = SumkDFTTools(hdf_file=dft_filename+'.h5',use_dft_blocks=False)
|
||||||
|
|
||||||
# load old chemical potential and DC
|
# load old chemical potential and DC
|
||||||
if mpi.is_master_node():
|
if mpi.is_master_node():
|
||||||
chemical_potential,dc_imp,dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
|
SK.chemical_potential,SK.dc_imp,SK.dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
|
||||||
SK.set_mu(chemical_potential)
|
|
||||||
SK.set_dc(dc_imp,dc_energ)
|
SK.chemical_potential = mpi.bcast(SK.chemical_potential)
|
||||||
|
SK.dc_imp = mpi.bcast(SK.dc_imp)
|
||||||
|
SK.dc_energ = mpi.bcast(SK.dc_energ)
|
||||||
|
|
||||||
if (mpi.is_master_node()):
|
if (mpi.is_master_node()):
|
||||||
print 'DC after reading SK: ',SK.dc_imp[0]
|
print 'DC after reading SK: ',SK.dc_imp[0]
|
||||||
@ -47,7 +45,7 @@ S.set_atomic_levels( eal = eal )
|
|||||||
|
|
||||||
# Run the solver to get GF and self-energy on the real axis
|
# Run the solver to get GF and self-energy on the real axis
|
||||||
S.GF_realomega(ommin=ommin, ommax = ommax, N_om=N_om,U_int=U_int,J_hund=J_hund)
|
S.GF_realomega(ommin=ommin, ommax = ommax, N_om=N_om,U_int=U_int,J_hund=J_hund)
|
||||||
SK.put_Sigma(Sigma_imp = [S.Sigma])
|
SK.set_Sigma([S.Sigma])
|
||||||
|
|
||||||
# compute DOS
|
# compute DOS
|
||||||
SK.dos_parproj_basis(broadening=broadening)
|
SK.dos_parproj_basis(broadening=broadening)
|
||||||
|
7
doc/guide/images_scripts/LaVO3_w90.inp
Normal file
7
doc/guide/images_scripts/LaVO3_w90.inp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
0 6 4 6
|
||||||
|
8.0
|
||||||
|
4
|
||||||
|
0 0 2 3 0 0
|
||||||
|
1 0 2 3 0 0
|
||||||
|
2 0 2 3 0 0
|
||||||
|
3 0 2 3 0 0
|
@ -82,7 +82,7 @@ for iteration_number in range(1,loops+1):
|
|||||||
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
||||||
|
|
||||||
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma_iw ]) # put Sigma into the SumK class
|
SK.set_Sigma([ S.Sigma_iw ]) # set Sigma into the SumK class
|
||||||
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
||||||
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
||||||
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
||||||
|
@ -83,7 +83,7 @@ for iteration_number in range(1,loops+1):
|
|||||||
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
if mpi.is_master_node(): print "Iteration = ", iteration_number
|
||||||
|
|
||||||
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
SK.symm_deg_gf(S.Sigma_iw,orb=0) # symmetrise Sigma
|
||||||
SK.put_Sigma(Sigma_imp = [ S.Sigma_iw ]) # put Sigma into the SumK class
|
SK.set_Sigma([ S.Sigma_iw ]) # set Sigma into the SumK class
|
||||||
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
chemical_potential = SK.calc_mu( precision = prec_mu ) # find the chemical potential for given density
|
||||||
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
S.G_iw << SK.extract_G_loc()[0] # calc the local Green function
|
||||||
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
mpi.report("Total charge of Gloc : %.6f"%S.G_iw.total_density())
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.. _Transport:
|
.. _Transport:
|
||||||
|
|
||||||
Transport calculations
|
Transport calculations test
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Formalism
|
Formalism
|
||||||
@ -65,7 +65,10 @@ The basics steps to calculate the matrix elements of the momentum operator with
|
|||||||
6) Run `x optic`.
|
6) Run `x optic`.
|
||||||
|
|
||||||
Additionally the input file :file:`case.inop` is required. A detail description on how to setup this file can be found in the Wien2k user guide [#userguide]_ on page 166.
|
Additionally the input file :file:`case.inop` is required. A detail description on how to setup this file can be found in the Wien2k user guide [#userguide]_ on page 166.
|
||||||
Here the energy window can be chosen according to the window used for :program:`dmftproj`. However, keep in mind that energies have to be specified in absolute values! Furthermore it is important to set line 6 to ON for printing the matrix elements to the :file:`.pmat` file.
|
The optics energy window should be chosen according to the window used for :program:`dmftproj`. Note that the current version of the transport code uses only the smaller
|
||||||
|
of those two windows. However, keep in mind that the optics energy window has to be specified in absolute values and NOT relative to the Fermi energy!
|
||||||
|
You can read off the Fermi energy from the :file:`case.scf2` file. Please do not set the optional parameter NBvalMAX in :file:`case.inop`.
|
||||||
|
Furthermore it is necessary to set line 6 to "ON" and put a "1" in the following line to enable the printing of the matrix elements to :file:`case.pmat`.
|
||||||
|
|
||||||
|
|
||||||
Using the transport code
|
Using the transport code
|
||||||
@ -86,7 +89,7 @@ reads the required data of the Wien2k output and stores it in the `dft_transp_in
|
|||||||
Additionally we need to read and set the self energy, the chemical potential and the double counting::
|
Additionally we need to read and set the self energy, the chemical potential and the double counting::
|
||||||
|
|
||||||
ar = HDFArchive('case.h5', 'a')
|
ar = HDFArchive('case.h5', 'a')
|
||||||
SK.put_Sigma(Sigma_imp = [ar['dmft_output']['Sigma_w']])
|
SK.set_Sigma([ar['dmft_output']['Sigma_w']])
|
||||||
chemical_potential,dc_imp,dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
|
chemical_potential,dc_imp,dc_energ = SK.load(['chemical_potential','dc_imp','dc_energ'])
|
||||||
SK.set_mu(chemical_potential)
|
SK.set_mu(chemical_potential)
|
||||||
SK.set_dc(dc_imp,dc_energ)
|
SK.set_dc(dc_imp,dc_energ)
|
||||||
|
@ -5,19 +5,25 @@ Converters
|
|||||||
|
|
||||||
Wien2k Converter
|
Wien2k Converter
|
||||||
----------------
|
----------------
|
||||||
.. autoclass:: pytriqs.applications.dft.converters.wien2k_converter.Wien2kConverter
|
.. autoclass:: dft.converters.wien2k_converter.Wien2kConverter
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
H(k) Converter
|
H(k) Converter
|
||||||
--------------
|
--------------
|
||||||
.. autoclass:: pytriqs.applications.dft.converters.hk_converter.HkConverter
|
.. autoclass:: dft.converters.hk_converter.HkConverter
|
||||||
|
:members:
|
||||||
|
:special-members:
|
||||||
|
|
||||||
|
Wannier90 Converter
|
||||||
|
--------------
|
||||||
|
.. autoclass:: dft.converters.wannier90_converter.Wannier90Converter
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
|
|
||||||
Converter Tools
|
Converter Tools
|
||||||
---------------
|
---------------
|
||||||
.. autoclass:: pytriqs.applications.dft.converters.converter_tools.ConverterTools
|
.. autoclass:: dft.converters.converter_tools.ConverterTools
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
|
@ -2,7 +2,7 @@ SumK DFT
|
|||||||
========
|
========
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: pytriqs.applications.dft.sumk_dft.SumkDFT
|
.. autoclass:: sumk_dft.SumkDFT
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
@ -2,7 +2,7 @@ SumK DFT Tools
|
|||||||
==============
|
==============
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: pytriqs.applications.dft.sumk_dft_tools.SumkDFTTools
|
.. autoclass:: sumk_dft_tools.SumkDFTTools
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Symmetry
|
Symmetry
|
||||||
========
|
========
|
||||||
|
|
||||||
.. autoclass:: pytriqs.applications.dft.Symmetry
|
.. autoclass:: Symmetry
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
TransBasis
|
TransBasis
|
||||||
==========
|
==========
|
||||||
|
|
||||||
.. autoclass:: pytriqs.applications.dft.trans_basis.TransBasis
|
.. autoclass:: trans_basis.TransBasis
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
# where will the python end up in triqs?
|
# where will the python end up in triqs?
|
||||||
set(python_destination applications/dft)
|
set(python_destination pytriqs/applications/dft)
|
||||||
|
|
||||||
|
# site_customize for build
|
||||||
|
set(package_name "pytriqs.applications")
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/cmake/sitecustomize.py ${CMAKE_CURRENT_BINARY_DIR}/sitecustomize.py @ONLY)
|
||||||
|
|
||||||
# make a local pytriqs copy
|
# make a local pytriqs copy
|
||||||
#triqs_prepare_local_pytriqs_merged_with_my_python(${python_destination})
|
|
||||||
triqs_prepare_local_pytriqs(${python_destination})
|
triqs_prepare_local_pytriqs(${python_destination})
|
||||||
|
|
||||||
# to be able to run from toplevel
|
# to be able to run from toplevel
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
from wien2k_converter import Wien2kConverter
|
from wien2k_converter import Wien2kConverter
|
||||||
from hk_converter import HkConverter
|
from hk_converter import HkConverter
|
||||||
from vasp_converter import VaspConverter
|
from vasp_converter import VaspConverter
|
||||||
|
from wannier90_converter import Wannier90Converter
|
||||||
|
|
||||||
__all__ =['Wien2kConverter','HkConverter','VaspConverter']
|
__all__ =['Wien2kConverter','HkConverter','Wannier90Converter','VaspConverter']
|
||||||
|
|
||||||
|
|
||||||
|
578
python/converters/wannier90_converter.py
Normal file
578
python/converters/wannier90_converter.py
Normal file
@ -0,0 +1,578 @@
|
|||||||
|
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 by M. Aichhorn, L. Pourovskii, V. Vildosola
|
||||||
|
#
|
||||||
|
# TRIQS is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
###
|
||||||
|
# Wannier90 to HDF5 converter for the SumkDFT class of dfttools/TRIQS;
|
||||||
|
#
|
||||||
|
# written by Gabriele Sclauzero (Materials Theory, ETH Zurich), Dec 2015 -- Jan 2016,
|
||||||
|
# under the supervision of Claude Ederer (Materials Theory).
|
||||||
|
# Partially based on previous work by K. Dymkovski and the DFT_tools/TRIQS team.
|
||||||
|
#
|
||||||
|
# Limitations of the current implementation:
|
||||||
|
# - the case with SO=1 is not considered at the moment
|
||||||
|
# - the T rotation matrices are not used in this implementation
|
||||||
|
# - projectors for uncorrelated shells (proj_mat_all) cannot be set
|
||||||
|
#
|
||||||
|
# Things to be improved/checked:
|
||||||
|
# - the case with SP=1 might work, but was never tested (do we need to define
|
||||||
|
# rot_mat_time_inv also if symm_op = 0?)
|
||||||
|
# - the calculation of rot_mat in find_rot_mat() relies on the eigenvalues of H(0);
|
||||||
|
# this might fail in presence of degenerate eigenvalues (now just prints warning)
|
||||||
|
# - the FFT is always done in serial mode (because all converters run serially);
|
||||||
|
# this can become very slow with a large number of R-vectors/k-points
|
||||||
|
# - make the code more MPI safe (error handling): if we run with more than one process
|
||||||
|
# and an error occurs on the masternode, the calculation does not abort
|
||||||
|
###
|
||||||
|
|
||||||
|
|
||||||
|
from types import *
|
||||||
|
import numpy
|
||||||
|
import math
|
||||||
|
from pytriqs.archive import *
|
||||||
|
from converter_tools import *
|
||||||
|
from itertools import product
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
|
class Wannier90Converter(ConverterTools):
|
||||||
|
"""
|
||||||
|
Conversion from Wannier90 output to an hdf5 file that can be used as input for the SumkDFT class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, seedname, hdf_filename=None, dft_subgrp='dft_input',
|
||||||
|
symmcorr_subgrp='dft_symmcorr_input', repacking=False):
|
||||||
|
"""
|
||||||
|
Initialise the class.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
seedname : string
|
||||||
|
Base name of Wannier90 files
|
||||||
|
hdf_filename : string, optional
|
||||||
|
Name of hdf5 archive to be created
|
||||||
|
dft_subgrp : string, optional
|
||||||
|
Name of subgroup storing necessary DFT data
|
||||||
|
symmcorr_subgrp : string, optional
|
||||||
|
Name of subgroup storing correlated-shell symmetry data
|
||||||
|
repacking : boolean, optional
|
||||||
|
Does the hdf5 archive need to be repacked to save space?
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._name = "Wannier90Converter"
|
||||||
|
assert type(seedname) == StringType, self._name + \
|
||||||
|
": Please provide the DFT files' base name as a string."
|
||||||
|
if hdf_filename is None:
|
||||||
|
hdf_filename = seedname + '.h5'
|
||||||
|
self.hdf_file = hdf_filename
|
||||||
|
# if the w90 output is seedname_hr.dat, the input file for the
|
||||||
|
# converter must be called seedname.inp
|
||||||
|
self.inp_file = seedname + '.inp'
|
||||||
|
self.w90_seed = seedname
|
||||||
|
self.dft_subgrp = dft_subgrp
|
||||||
|
self.symmcorr_subgrp = symmcorr_subgrp
|
||||||
|
self.fortran_to_replace = {'D': 'E'}
|
||||||
|
# threshold below which matrix elements from wannier90 should be considered equal
|
||||||
|
self._w90zero = 2.e-6
|
||||||
|
|
||||||
|
# Checks if h5 file is there and repacks it if wanted:
|
||||||
|
if (os.path.exists(self.hdf_file) and repacking):
|
||||||
|
ConverterTools.repack(self)
|
||||||
|
|
||||||
|
def convert_dft_input(self):
|
||||||
|
"""
|
||||||
|
Reads the appropriate files and stores the data for the
|
||||||
|
|
||||||
|
- dft_subgrp
|
||||||
|
- symmcorr_subgrp
|
||||||
|
|
||||||
|
in the hdf5 archive.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Read and write only on the master node
|
||||||
|
if not (mpi.is_master_node()):
|
||||||
|
return
|
||||||
|
mpi.report("Reading input from %s..." % self.inp_file)
|
||||||
|
|
||||||
|
# R is a generator : each R.Next() will return the next number in the file
|
||||||
|
R = ConverterTools.read_fortran_file(
|
||||||
|
self, self.inp_file, self.fortran_to_replace)
|
||||||
|
shell_entries = ['atom', 'sort', 'l', 'dim']
|
||||||
|
corr_shell_entries = ['atom', 'sort', 'l', 'dim', 'SO', 'irep']
|
||||||
|
# First, let's read the input file with the parameters needed for the conversion
|
||||||
|
try:
|
||||||
|
# read k - point mesh generation option
|
||||||
|
kmesh_mode = int(R.next())
|
||||||
|
if kmesh_mode >= 0:
|
||||||
|
# read k-point mesh size from input
|
||||||
|
nki = [int(R.next()) for idir in range(3)]
|
||||||
|
else:
|
||||||
|
# some default grid, if everything else fails...
|
||||||
|
nki = [8, 8, 8]
|
||||||
|
# read the total number of electrons per cell
|
||||||
|
density_required = float(R.next())
|
||||||
|
# we do not read shells, because we have no additional shells beyond correlated ones,
|
||||||
|
# and the data will be copied from corr_shells into shells (see below)
|
||||||
|
# number of corr. shells (e.g. Fe d, Ce f) in the unit cell,
|
||||||
|
n_corr_shells = int(R.next())
|
||||||
|
# now read the information about the correlated shells (atom, sort, l, dim, SO flag, irep):
|
||||||
|
corr_shells = [{name: int(val) for name, val in zip(
|
||||||
|
corr_shell_entries, R)} for icrsh in range(n_corr_shells)]
|
||||||
|
except StopIteration: # a more explicit error if the file is corrupted.
|
||||||
|
mpi.report(self._name + ": reading input file %s failed!" %
|
||||||
|
self.inp_file)
|
||||||
|
# close the input file
|
||||||
|
R.close()
|
||||||
|
|
||||||
|
# Set or derive some quantities
|
||||||
|
# Wannier90 does not use symmetries to reduce the k-points
|
||||||
|
# the following might change in future versions
|
||||||
|
symm_op = 0
|
||||||
|
# copy corr_shells into shells (see above)
|
||||||
|
n_shells = n_corr_shells
|
||||||
|
shells = []
|
||||||
|
for ish in range(n_shells):
|
||||||
|
shells.append({key: corr_shells[ish].get(
|
||||||
|
key, None) for key in shell_entries})
|
||||||
|
###
|
||||||
|
SP = 0 # NO spin-polarised calculations for now
|
||||||
|
SO = 0 # NO spin-orbit calculation for now
|
||||||
|
charge_below = 0 # total charge below energy window NOT used for now
|
||||||
|
energy_unit = 1.0 # should be understood as eV units
|
||||||
|
###
|
||||||
|
# this is more general
|
||||||
|
n_spin = SP + 1 - SO
|
||||||
|
dim_corr_shells = sum([sh['dim'] for sh in corr_shells])
|
||||||
|
mpi.report(
|
||||||
|
"Total number of WFs expected in the correlated shells: %d" % dim_corr_shells)
|
||||||
|
|
||||||
|
# determine the number of inequivalent correlated shells and maps, needed for further processing
|
||||||
|
n_inequiv_shells, corr_to_inequiv, inequiv_to_corr = ConverterTools.det_shell_equivalence(
|
||||||
|
self, corr_shells)
|
||||||
|
mpi.report("Number of inequivalent shells: %d" % n_inequiv_shells)
|
||||||
|
mpi.report("Shell representatives: " + format(inequiv_to_corr))
|
||||||
|
shells_map = [inequiv_to_corr[corr_to_inequiv[ish]]
|
||||||
|
for ish in range(n_corr_shells)]
|
||||||
|
mpi.report("Mapping: " + format(shells_map))
|
||||||
|
|
||||||
|
# build the k-point mesh, if its size was given on input (kmesh_mode >= 0),
|
||||||
|
# otherwise it is built according to the data in the hr file (see below)
|
||||||
|
if kmesh_mode >= 0:
|
||||||
|
n_k, k_mesh, bz_weights = self.kmesh_build(nki, kmesh_mode)
|
||||||
|
self.n_k = n_k
|
||||||
|
self.k_mesh = k_mesh
|
||||||
|
|
||||||
|
# not used in this version: reset to dummy values?
|
||||||
|
n_reps = [1 for i in range(n_inequiv_shells)]
|
||||||
|
dim_reps = [0 for i in range(n_inequiv_shells)]
|
||||||
|
T = []
|
||||||
|
for ish in range(n_inequiv_shells):
|
||||||
|
ll = 2 * corr_shells[inequiv_to_corr[ish]]['l'] + 1
|
||||||
|
lmax = ll * (corr_shells[inequiv_to_corr[ish]]['SO'] + 1)
|
||||||
|
T.append(numpy.zeros([lmax, lmax], numpy.complex_))
|
||||||
|
|
||||||
|
spin_w90name = ['_up', '_down']
|
||||||
|
hamr_full = []
|
||||||
|
|
||||||
|
# TODO: generalise to SP=1 (only partially done)
|
||||||
|
rot_mat_time_inv = [0 for i in range(n_corr_shells)]
|
||||||
|
|
||||||
|
# Second, let's read the file containing the Hamiltonian in WF basis produced by Wannier90
|
||||||
|
for isp in range(n_spin):
|
||||||
|
# begin loop on isp
|
||||||
|
|
||||||
|
# build filename according to wannier90 conventions
|
||||||
|
if SP == 1:
|
||||||
|
mpi.report(
|
||||||
|
"Reading information for spin component n. %d" % isp)
|
||||||
|
hr_file = self.w90_seed + spin_w90name[isp] + '_hr.dat'
|
||||||
|
else:
|
||||||
|
hr_file = self.w90_seed + '_hr.dat'
|
||||||
|
# now grab the data from the H(R) file
|
||||||
|
mpi.report(
|
||||||
|
"The Hamiltonian in MLWF basis is extracted from %s ..." % hr_file)
|
||||||
|
nr, rvec, rdeg, nw, hamr = self.read_wannier90hr(hr_file)
|
||||||
|
# number of R vectors, their indices, their degeneracy, number of WFs, H(R)
|
||||||
|
mpi.report("... done: %d R vectors, %d WFs found" % (nr, nw))
|
||||||
|
|
||||||
|
if isp == 0:
|
||||||
|
# set or check some quantities that must be the same for both spins
|
||||||
|
self.nrpt = nr
|
||||||
|
|
||||||
|
# k-point grid: (if not defined before)
|
||||||
|
if kmesh_mode == -1:
|
||||||
|
# the size of the k-point mesh is determined from the largest R vector
|
||||||
|
nki = [2 * rvec[:, idir].max() + 1 for idir in range(3)]
|
||||||
|
# it will be the same as in the win only when nki is odd, because of the
|
||||||
|
# wannier90 convention: if we have nki k-points along the i-th direction,
|
||||||
|
# then we should get 2*(nki/2)+nki%2 R points along that direction
|
||||||
|
n_k, k_mesh, bz_weights = self.kmesh_build(nki)
|
||||||
|
self.n_k = n_k
|
||||||
|
self.k_mesh = k_mesh
|
||||||
|
|
||||||
|
# set the R vectors and their degeneracy
|
||||||
|
self.rvec = rvec
|
||||||
|
self.rdeg = rdeg
|
||||||
|
|
||||||
|
self.nwfs = nw
|
||||||
|
# check that the total number of WFs makes sense
|
||||||
|
if self.nwfs < dim_corr_shells:
|
||||||
|
mpi.report("ERROR: number of WFs in the file smaller than number of correlated orbitals!")
|
||||||
|
elif self.nwfs > dim_corr_shells:
|
||||||
|
# NOTE: correlated shells must appear before uncorrelated ones inside the file
|
||||||
|
mpi.report("Number of WFs larger than correlated orbitals:\n" +
|
||||||
|
"WFs from %d to %d treated as uncorrelated" % (dim_corr_shells + 1, self.nwfs))
|
||||||
|
else:
|
||||||
|
mpi.report("Number of WFs equal to number of correlated orbitals")
|
||||||
|
|
||||||
|
# we assume spin up and spin down always have same total number of WFs
|
||||||
|
n_orbitals = numpy.ones(
|
||||||
|
[self.n_k, n_spin], numpy.int) * self.nwfs
|
||||||
|
|
||||||
|
else:
|
||||||
|
# consistency check between the _up and _down file contents
|
||||||
|
if nr != self.nrpt:
|
||||||
|
mpi.report("Different number of R vectors for spin-up/spin-down!")
|
||||||
|
if nw != self.nwfs:
|
||||||
|
mpi.report("Different number of WFs for spin-up/spin-down!")
|
||||||
|
|
||||||
|
hamr_full.append(hamr)
|
||||||
|
# FIXME: when do we actually need deepcopy()?
|
||||||
|
# hamr_full.append(deepcopy(hamr))
|
||||||
|
|
||||||
|
for ir in range(nr):
|
||||||
|
# checks if the Hamiltonian is real (it should, if wannierisation worked fine)
|
||||||
|
if numpy.abs((hamr[ir].imag.max()).max()) > self._w90zero:
|
||||||
|
mpi.report("H(R) has large complex components at R %d" % ir)
|
||||||
|
# copy the R=0 block corresponding to the correlated shells
|
||||||
|
# into another variable (needed later for finding rot_mat)
|
||||||
|
if rvec[ir, 0] == 0 and rvec[ir, 1] == 0 and rvec[ir, 2] == 0:
|
||||||
|
ham_corr0 = hamr[ir][0:dim_corr_shells, 0:dim_corr_shells]
|
||||||
|
|
||||||
|
# checks if ham0 is Hermitian
|
||||||
|
if not numpy.allclose(ham_corr0.transpose().conjugate(), ham_corr0, atol=self._w90zero, rtol=1.e-9):
|
||||||
|
raise ValueError("H(R=0) matrix is not Hermitian!")
|
||||||
|
|
||||||
|
# find rot_mat symmetries by diagonalising the on-site Hamiltonian of the first spin
|
||||||
|
if isp == 0:
|
||||||
|
use_rotations, rot_mat = self.find_rot_mat(n_corr_shells, corr_shells, shells_map, ham_corr0)
|
||||||
|
else:
|
||||||
|
# consistency check
|
||||||
|
use_rotations_, rot_mat_ = self.find_rot_mat(n_corr_shells, corr_shells, shells_map, ham_corr0)
|
||||||
|
if (use_rotations and not use_rotations_):
|
||||||
|
mpi.report("Rotations cannot be used for spin component n. %d" % isp)
|
||||||
|
for icrsh in range(n_corr_shells):
|
||||||
|
if not numpy.allclose(rot_mat_[icrsh], rot_mat[icrsh], atol=self._w90zero, rtol=1.e-15):
|
||||||
|
mpi.report("Rotations for spin component n. %d do not match!" % isp)
|
||||||
|
# end loop on isp
|
||||||
|
|
||||||
|
mpi.report("The k-point grid has dimensions: %d, %d, %d" % tuple(nki))
|
||||||
|
# if calculations are spin-polarized, then renormalize k-point weights
|
||||||
|
if SP == 1:
|
||||||
|
bz_weights = 0.5 * bz_weights
|
||||||
|
|
||||||
|
# Third, compute the hoppings in reciprocal space
|
||||||
|
hopping = numpy.zeros([self.n_k, n_spin, numpy.max(n_orbitals), numpy.max(n_orbitals)], numpy.complex_)
|
||||||
|
for isp in range(n_spin):
|
||||||
|
# make Fourier transform H(R) -> H(k) : it can be done one spin at a time
|
||||||
|
hamk = self.fourier_ham(self.nwfs, hamr_full[isp])
|
||||||
|
# copy the H(k) in the right place of hoppings... is there a better way to do this??
|
||||||
|
for ik in range(self.n_k):
|
||||||
|
#hopping[ik,isp,:,:] = deepcopy(hamk[ik][:,:])*energy_unit
|
||||||
|
hopping[ik, isp, :, :] = hamk[ik][:, :] * energy_unit
|
||||||
|
|
||||||
|
# Then, initialise the projectors
|
||||||
|
k_dep_projection = 0 # we always have the same number of WFs at each k-point
|
||||||
|
proj_mat = numpy.zeros([self.n_k, n_spin, n_corr_shells, max(
|
||||||
|
[crsh['dim'] for crsh in corr_shells]), numpy.max(n_orbitals)], numpy.complex_)
|
||||||
|
iorb = 0
|
||||||
|
# Projectors simply consist in identity matrix blocks selecting those MLWFs that
|
||||||
|
# correspond to the specific correlated shell indexed by icrsh.
|
||||||
|
# NOTE: we assume that the correlated orbitals appear at the beginning of the H(R)
|
||||||
|
# file and that the ordering of MLWFs matches the corr_shell info from the input.
|
||||||
|
for icrsh in range(n_corr_shells):
|
||||||
|
norb = corr_shells[icrsh]['dim']
|
||||||
|
proj_mat[:, :, icrsh, 0:norb, iorb:iorb +
|
||||||
|
norb] = numpy.identity(norb, numpy.complex_)
|
||||||
|
iorb += norb
|
||||||
|
|
||||||
|
# Finally, save all required data into the HDF archive:
|
||||||
|
ar = HDFArchive(self.hdf_file, 'a')
|
||||||
|
if not (self.dft_subgrp in ar):
|
||||||
|
ar.create_group(self.dft_subgrp)
|
||||||
|
# The subgroup containing the data. If it does not exist, it is created. If it exists, the data is overwritten!
|
||||||
|
things_to_save = ['energy_unit', 'n_k', 'k_dep_projection', 'SP', 'SO', 'charge_below', 'density_required',
|
||||||
|
'symm_op', 'n_shells', 'shells', 'n_corr_shells', 'corr_shells', 'use_rotations', 'rot_mat',
|
||||||
|
'rot_mat_time_inv', 'n_reps', 'dim_reps', 'T', 'n_orbitals', 'proj_mat', 'bz_weights', 'hopping',
|
||||||
|
'n_inequiv_shells', 'corr_to_inequiv', 'inequiv_to_corr']
|
||||||
|
for it in things_to_save:
|
||||||
|
ar[self.dft_subgrp][it] = locals()[it]
|
||||||
|
del ar
|
||||||
|
|
||||||
|
def read_wannier90hr(self, hr_filename="wannier_hr.dat"):
|
||||||
|
"""
|
||||||
|
Method for reading the seedname_hr.dat file produced by Wannier90 (http://wannier.org)
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
hr_filename : string
|
||||||
|
full name of the H(R) file produced by Wannier90 (usually seedname_hr.dat)
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
nrpt : integer
|
||||||
|
number of R vectors found in the file
|
||||||
|
rvec_idx : numpy.array of integers
|
||||||
|
Miller indices of the R vectors
|
||||||
|
rvec_deg : numpy.array of floats
|
||||||
|
weight of the R vectors
|
||||||
|
num_wf : integer
|
||||||
|
number of Wannier functions found
|
||||||
|
h_of_r : list of numpy.array
|
||||||
|
<w_i|H(R)|w_j> = Hamilonian matrix elements in the Wannier basis
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Read only from the master node
|
||||||
|
if not (mpi.is_master_node()):
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(hr_filename, "r") as hr_filedesc:
|
||||||
|
hr_data = hr_filedesc.readlines()
|
||||||
|
hr_filedesc.close()
|
||||||
|
except IOError:
|
||||||
|
mpi.report("The file %s could not be read!" % hr_filename)
|
||||||
|
|
||||||
|
mpi.report("Reading %s..." % hr_filename + hr_data[0])
|
||||||
|
|
||||||
|
try:
|
||||||
|
# reads number of Wannier functions per spin
|
||||||
|
num_wf = int(hr_data[1])
|
||||||
|
nrpt = int(hr_data[2])
|
||||||
|
except ValueError:
|
||||||
|
mpi.report("Could not read number of WFs or R vectors")
|
||||||
|
|
||||||
|
# allocate arrays to save the R vector indexes and degeneracies and the Hamiltonian
|
||||||
|
rvec_idx = numpy.zeros((nrpt, 3), dtype=int)
|
||||||
|
rvec_deg = numpy.zeros(nrpt, dtype=int)
|
||||||
|
h_of_r = [numpy.zeros((num_wf, num_wf), dtype=numpy.complex_)
|
||||||
|
for n in range(nrpt)]
|
||||||
|
|
||||||
|
# variable currpos points to the current line in the file
|
||||||
|
currpos = 2
|
||||||
|
try:
|
||||||
|
ir = 0
|
||||||
|
# read the degeneracy of the R vectors (needed for the Fourier transform)
|
||||||
|
while ir < nrpt:
|
||||||
|
currpos += 1
|
||||||
|
for x in hr_data[currpos].split():
|
||||||
|
if ir >= nrpt:
|
||||||
|
raise IndexError("wrong number of R vectors??")
|
||||||
|
rvec_deg[ir] = int(x)
|
||||||
|
ir += 1
|
||||||
|
# for each direct lattice vector R read the block of the
|
||||||
|
# Hamiltonian H(R)
|
||||||
|
for ir, jj, ii in product(range(nrpt), range(num_wf), range(num_wf)):
|
||||||
|
# advance one line, split the line into tokens
|
||||||
|
currpos += 1
|
||||||
|
cline = hr_data[currpos].split()
|
||||||
|
# check if the orbital indexes in the file make sense
|
||||||
|
if int(cline[3]) != ii + 1 or int(cline[4]) != jj + 1:
|
||||||
|
mpi.report(
|
||||||
|
"Inconsistent indices at %s%s of R n. %s" % (ii, jj, ir))
|
||||||
|
rcurr = numpy.array(
|
||||||
|
[int(cline[0]), int(cline[1]), int(cline[2])])
|
||||||
|
if ii == 0 and jj == 0:
|
||||||
|
rvec_idx[ir] = rcurr
|
||||||
|
rprec = rcurr
|
||||||
|
else:
|
||||||
|
# check if the vector indices are consistent
|
||||||
|
if not numpy.array_equal(rcurr, rprec):
|
||||||
|
mpi.report(
|
||||||
|
"Inconsistent indices for R vector n. %s" % ir)
|
||||||
|
|
||||||
|
# fill h_of_r with the matrix elements of the Hamiltonian
|
||||||
|
h_of_r[ir][ii, jj] = complex(float(cline[5]), float(cline[6]))
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
mpi.report("Wrong data or structure in file %s" % hr_filename)
|
||||||
|
|
||||||
|
# return the data into variables
|
||||||
|
return nrpt, rvec_idx, rvec_deg, num_wf, h_of_r
|
||||||
|
|
||||||
|
def find_rot_mat(self, n_sh, sh_lst, sh_map, ham0):
|
||||||
|
"""
|
||||||
|
Method for finding the matrices that bring from local to global coordinate systems
|
||||||
|
(and viceversa), based on the eigenvalues of H(R=0)
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
n_sh : integer
|
||||||
|
number of shells
|
||||||
|
sh_lst : list of shells-type dictionaries
|
||||||
|
contains the shells (could be correlated or not)
|
||||||
|
sh_map : list of integers
|
||||||
|
mapping between shells
|
||||||
|
ham0 : numpy.array of floats
|
||||||
|
local Hamiltonian matrix elements
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
istatus : integer
|
||||||
|
if 0, something failed in the construction of the matrices
|
||||||
|
rot_mat : list of numpy.array
|
||||||
|
rotation matrix for each of the shell
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# initialize the rotation matrices to identities
|
||||||
|
rot_mat = [numpy.identity(sh_lst[ish]['dim'], dtype=complex)
|
||||||
|
for ish in range(n_sh)]
|
||||||
|
istatus = 0
|
||||||
|
|
||||||
|
hs = ham0.shape
|
||||||
|
if hs[0] != hs[1] or hs[0] != sum([sh['dim'] for sh in sh_lst]):
|
||||||
|
mpi.report(
|
||||||
|
"find_rot_mat: wrong block structure of input Hamiltonian!")
|
||||||
|
istatus = 0
|
||||||
|
# this error will lead into troubles later... early return
|
||||||
|
return istatus, rot_mat
|
||||||
|
|
||||||
|
# TODO: better handling of degenerate eigenvalue case
|
||||||
|
eigval_lst = []
|
||||||
|
eigvec_lst = []
|
||||||
|
iwf = 0
|
||||||
|
# loop over shells
|
||||||
|
for ish in range(n_sh):
|
||||||
|
# nw = number of orbitals in this shell
|
||||||
|
nw = sh_lst[ish]["dim"]
|
||||||
|
# diagonalize the sub-block of H(0) corresponding to this shell
|
||||||
|
eigval, eigvec = numpy.linalg.eigh(
|
||||||
|
ham0[iwf:iwf + nw, iwf:iwf + nw])
|
||||||
|
# find the indices sorting the eigenvalues in ascending order
|
||||||
|
eigsrt = eigval[0:nw].argsort()
|
||||||
|
# order eigenvalues and eigenvectors and save in a list
|
||||||
|
eigval_lst.append(eigval[eigsrt])
|
||||||
|
eigvec_lst.append(eigvec[eigsrt])
|
||||||
|
iwf += nw
|
||||||
|
# TODO: better handling of degenerate eigenvalue case
|
||||||
|
if sh_map[ish] != ish: # issue warning only when there are equivalent shells
|
||||||
|
for i in range(nw):
|
||||||
|
for j in range(i + 1, nw):
|
||||||
|
if (abs(eigval[j] - eigval[i]) < self._w90zero):
|
||||||
|
mpi.report("WARNING: degenerate eigenvalue of H(0) detected for shell %d: " % (ish) +
|
||||||
|
"global-to-local transformation might not work!")
|
||||||
|
|
||||||
|
for ish in range(n_sh):
|
||||||
|
try:
|
||||||
|
# build rotation matrices by combining the unitary
|
||||||
|
# transformations that diagonalize H(0)
|
||||||
|
rot_mat[ish] = numpy.dot(eigvec_lst[ish], eigvec_lst[
|
||||||
|
sh_map[ish]].conjugate().transpose())
|
||||||
|
except ValueError:
|
||||||
|
mpi.report(
|
||||||
|
"Global-to-local rotation matrices cannot be constructed!")
|
||||||
|
|
||||||
|
istatus = 1
|
||||||
|
# check that eigenvalues are the same (within accuracy) for
|
||||||
|
# equivalent shells
|
||||||
|
if not numpy.allclose(eigval_lst[ish], eigval_lst[sh_map[ish]], atol=self._w90zero, rtol=1.e-15):
|
||||||
|
mpi.report(
|
||||||
|
"ERROR: eigenvalue mismatch between equivalent shells! %d" % ish)
|
||||||
|
eigval_diff = eigval_lst[ish] - eigval_lst[sh_map[ish]]
|
||||||
|
mpi.report("Eigenvalue difference: " + format(eigval_diff))
|
||||||
|
istatus = 0
|
||||||
|
|
||||||
|
# TODO: add additional consistency check on rot_mat matrices?
|
||||||
|
|
||||||
|
return istatus, rot_mat
|
||||||
|
|
||||||
|
def kmesh_build(self, msize=None, mmode=0):
|
||||||
|
"""
|
||||||
|
Method for the generation of the k-point mesh.
|
||||||
|
Right now it only supports the option for generating a full grid containing k=0,0,0.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
msize : list of 3 integers
|
||||||
|
the dimensions of the mesh
|
||||||
|
mmode : integer
|
||||||
|
mesh generation mode (right now, only full grid available)
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
nkpt : integer
|
||||||
|
total number of k-points in the mesh
|
||||||
|
k_mesh : numpy.array[nkpt,3] of floats
|
||||||
|
the coordinates of all k-points
|
||||||
|
wk : numpy.array[nkpt] of floats
|
||||||
|
the weight of each k-point
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if mmode != 0:
|
||||||
|
raise ValueError("Mesh generation mode not supported: %s" % mmode)
|
||||||
|
|
||||||
|
# a regular mesh including Gamma point
|
||||||
|
# total number of k-points
|
||||||
|
nkpt = msize[0] * msize[1] * msize[2]
|
||||||
|
kmesh = numpy.zeros((nkpt, 3), dtype=float)
|
||||||
|
ii = 0
|
||||||
|
for ix, iy, iz in product(range(msize[0]), range(msize[1]), range(msize[2])):
|
||||||
|
kmesh[ii, :] = [float(ix) / msize[0], float(iy) / msize[1], float(iz) / msize[2]]
|
||||||
|
ii += 1
|
||||||
|
# weight is equal for all k-points because wannier90 uses uniform grid on whole BZ
|
||||||
|
# (normalization is always 1 and takes into account spin degeneracy)
|
||||||
|
wk = numpy.ones([nkpt], dtype=float) / float(nkpt)
|
||||||
|
|
||||||
|
return nkpt, kmesh, wk
|
||||||
|
|
||||||
|
def fourier_ham(self, norb, h_of_r):
|
||||||
|
"""
|
||||||
|
Method for obtaining H(k) from H(R) via Fourier transform
|
||||||
|
The R vectors and k-point mesh are read from global module variables
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
norb : integer
|
||||||
|
number of orbitals
|
||||||
|
h_of_r : list of numpy.array[norb,norb]
|
||||||
|
Hamiltonian H(R) in Wannier basis
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
h_of_k : list of numpy.array[norb,norb]
|
||||||
|
transformed Hamiltonian H(k) in Wannier basis
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
twopi = 2 * numpy.pi
|
||||||
|
h_of_k = [numpy.zeros((norb, norb), dtype=numpy.complex_) for ik in range(self.n_k)]
|
||||||
|
ridx = numpy.array(range(self.nrpt))
|
||||||
|
for ik, ir in product(range(self.n_k), ridx):
|
||||||
|
rdotk = twopi * numpy.dot(self.k_mesh[ik], self.rvec[ir])
|
||||||
|
factor = (math.cos(rdotk) + 1j * math.sin(rdotk)) / float(self.rdeg[ir])
|
||||||
|
h_of_k[ik][:, :] += factor * h_of_r[ir][:, :]
|
||||||
|
|
||||||
|
return h_of_k
|
@ -448,7 +448,6 @@ class SumkDFT:
|
|||||||
broadening = 0.01
|
broadening = 0.01
|
||||||
else: # broadening = 2 * \Delta omega, where \Delta omega is the spacing of omega points
|
else: # broadening = 2 * \Delta omega, where \Delta omega is the spacing of omega points
|
||||||
broadening = 2.0 * ( (mesh[1]-mesh[0])/(mesh[2]-1) )
|
broadening = 2.0 * ( (mesh[1]-mesh[0])/(mesh[2]-1) )
|
||||||
n_iw = 1025 # Default number of Matsubara frequencies
|
|
||||||
|
|
||||||
# Are we including Sigma?
|
# Are we including Sigma?
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
@ -457,10 +456,16 @@ class SumkDFT:
|
|||||||
if with_dc: sigma_minus_dc = self.add_dc(iw_or_w)
|
if with_dc: sigma_minus_dc = self.add_dc(iw_or_w)
|
||||||
if iw_or_w == "iw":
|
if iw_or_w == "iw":
|
||||||
beta = Sigma_imp[0].mesh.beta # override beta if Sigma_iw is present
|
beta = Sigma_imp[0].mesh.beta # override beta if Sigma_iw is present
|
||||||
n_iw = len(Sigma_imp[0].mesh)
|
mesh = Sigma_imp[0].mesh
|
||||||
|
elif iw_or_w == "w":
|
||||||
|
mesh = Sigma_imp[0].mesh
|
||||||
else:
|
else:
|
||||||
if (iw_or_w == "w") and (mesh is None):
|
if iw_or_w == "iw":
|
||||||
raise ValueError, "lattice_gf: Give the mesh=(om_min,om_max,n_points) for the lattice GfReFreq."
|
if beta is None: raise ValueError, "lattice_gf: Give the beta for the lattice GfReFreq."
|
||||||
|
mesh = MeshImFreq(beta=beta, S='Fermion', n_max=1025) # Default number of Matsubara frequencies
|
||||||
|
elif iw_or_w == "w":
|
||||||
|
if mesh is None: raise ValueError, "lattice_gf: Give the mesh=(om_min,om_max,n_points) for the lattice GfReFreq."
|
||||||
|
mesh = MeshReFreq(mesh[0],mesh[1],mesh[2])
|
||||||
|
|
||||||
# Check if G_latt is present
|
# Check if G_latt is present
|
||||||
set_up_G_latt = False # Assume not
|
set_up_G_latt = False # Assume not
|
||||||
@ -479,12 +484,9 @@ class SumkDFT:
|
|||||||
gf_struct = [ (spn[isp], block_structure[isp]) for isp in range(self.n_spin_blocks[self.SO]) ]
|
gf_struct = [ (spn[isp], block_structure[isp]) for isp in range(self.n_spin_blocks[self.SO]) ]
|
||||||
block_ind_list = [block for block,inner in gf_struct]
|
block_ind_list = [block for block,inner in gf_struct]
|
||||||
if iw_or_w == "iw":
|
if iw_or_w == "iw":
|
||||||
glist = lambda : [ GfImFreq(indices=inner,beta=beta,n_points=n_iw) for block,inner in gf_struct]
|
glist = lambda : [ GfImFreq(indices=inner,mesh=mesh) for block,inner in gf_struct ]
|
||||||
elif iw_or_w == "w":
|
elif iw_or_w == "w":
|
||||||
if with_Sigma:
|
glist = lambda : [ GfReFreq(indices=inner,mesh=mesh) for block,inner in gf_struct ]
|
||||||
glist = lambda : [ GfReFreq(indices=inner,mesh=Sigma_imp[0].mesh) for block,inner in gf_struct]
|
|
||||||
else:
|
|
||||||
glist = lambda : [ GfReFreq(indices=inner,window=(mesh[0],mesh[1]),n_points=mesh[2]) for block,inner in gf_struct]
|
|
||||||
G_latt = BlockGf(name_list = block_ind_list, block_list = glist(), make_copies = False)
|
G_latt = BlockGf(name_list = block_ind_list, block_list = glist(), make_copies = False)
|
||||||
G_latt.zero()
|
G_latt.zero()
|
||||||
|
|
||||||
@ -510,6 +512,8 @@ class SumkDFT:
|
|||||||
|
|
||||||
return G_latt
|
return G_latt
|
||||||
|
|
||||||
|
def set_Sigma(self,Sigma_imp):
|
||||||
|
self.put_Sigma(Sigma_imp)
|
||||||
|
|
||||||
def put_Sigma(self, Sigma_imp):
|
def put_Sigma(self, Sigma_imp):
|
||||||
r"""
|
r"""
|
||||||
@ -557,7 +561,6 @@ class SumkDFT:
|
|||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for bname,gf in SK_Sigma_imp[icrsh]: gf << self.rotloc(icrsh,gf,direction='toGlobal')
|
for bname,gf in SK_Sigma_imp[icrsh]: gf << self.rotloc(icrsh,gf,direction='toGlobal')
|
||||||
|
|
||||||
|
|
||||||
def extract_G_loc(self, mu=None, with_Sigma=True, with_dc=True):
|
def extract_G_loc(self, mu=None, with_Sigma=True, with_dc=True):
|
||||||
r"""
|
r"""
|
||||||
Extracts the local downfolded Green function by the Brillouin-zone integration of the lattice Green's function.
|
Extracts the local downfolded Green function by the Brillouin-zone integration of the lattice Green's function.
|
||||||
|
@ -47,6 +47,7 @@ class SumkDFTTools(SumkDFT):
|
|||||||
misc_data=misc_data)
|
misc_data=misc_data)
|
||||||
|
|
||||||
|
|
||||||
|
# Uses .data of only GfReFreq objects.
|
||||||
def dos_wannier_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True):
|
def dos_wannier_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True):
|
||||||
"""
|
"""
|
||||||
Calculates the density of states in the basis of the Wannier functions.
|
Calculates the density of states in the basis of the Wannier functions.
|
||||||
@ -163,6 +164,7 @@ class SumkDFTTools(SumkDFT):
|
|||||||
return DOS, DOSproj, DOSproj_orb
|
return DOS, DOSproj, DOSproj_orb
|
||||||
|
|
||||||
|
|
||||||
|
# Uses .data of only GfReFreq objects.
|
||||||
def dos_parproj_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True):
|
def dos_parproj_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True):
|
||||||
"""
|
"""
|
||||||
Calculates the orbitally-resolved DOS.
|
Calculates the orbitally-resolved DOS.
|
||||||
@ -290,6 +292,7 @@ class SumkDFTTools(SumkDFT):
|
|||||||
return DOS, DOSproj, DOSproj_orb
|
return DOS, DOSproj, DOSproj_orb
|
||||||
|
|
||||||
|
|
||||||
|
# Uses .data of only GfReFreq objects.
|
||||||
def spaghettis(self,broadening=None,plot_shift=0.0,plot_range=None,ishell=None,mu=None,save_to_file='Akw_'):
|
def spaghettis(self,broadening=None,plot_shift=0.0,plot_range=None,ishell=None,mu=None,save_to_file='Akw_'):
|
||||||
"""
|
"""
|
||||||
Calculates the correlated band structure using a real-frequency self energy.
|
Calculates the correlated band structure using a real-frequency self energy.
|
||||||
@ -377,6 +380,11 @@ class SumkDFTTools(SumkDFT):
|
|||||||
for sp in spn:
|
for sp in spn:
|
||||||
Akw[sp][ish,ik,iom] = G_loc[sp].data[iom,ish,ish].imag/(-1.0*numpy.pi)
|
Akw[sp][ish,ik,iom] = G_loc[sp].data[iom,ish,ish].imag/(-1.0*numpy.pi)
|
||||||
|
|
||||||
|
# Collect data from mpi
|
||||||
|
for sp in spn:
|
||||||
|
Akw[sp] = mpi.all_reduce(mpi.world, Akw[sp], lambda x,y : x+y)
|
||||||
|
mpi.barrier()
|
||||||
|
|
||||||
if save_to_file and mpi.is_master_node():
|
if save_to_file and mpi.is_master_node():
|
||||||
if ishell is None:
|
if ishell is None:
|
||||||
for sp in spn: # loop over GF blocs:
|
for sp in spn: # loop over GF blocs:
|
||||||
@ -394,7 +402,7 @@ class SumkDFTTools(SumkDFT):
|
|||||||
else: # ishell is not None
|
else: # ishell is not None
|
||||||
for sp in spn:
|
for sp in spn:
|
||||||
for ish in range(self.shells[ishell]['dim']):
|
for ish in range(self.shells[ishell]['dim']):
|
||||||
f = open(save_to_file+sp+'_proj'+str(ish)+'.dat','w') # Open file for storage:
|
f = open(save_to_file+str(ishell)+'_'+sp+'_proj'+str(ish)+'.dat','w') # Open file for storage:
|
||||||
for ik in range(self.n_k):
|
for ik in range(self.n_k):
|
||||||
for iom in range(n_om):
|
for iom in range(n_om):
|
||||||
if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
|
if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
|
||||||
@ -565,6 +573,7 @@ class SumkDFTTools(SumkDFT):
|
|||||||
return vol_c, vol_p
|
return vol_c, vol_p
|
||||||
|
|
||||||
|
|
||||||
|
# Uses .data of only GfReFreq objects.
|
||||||
def transport_distribution(self, beta, directions=['xx'], energy_window=None, Om_mesh=[0.0], with_Sigma=False, n_om=None, broadening=0.0):
|
def transport_distribution(self, beta, directions=['xx'], energy_window=None, Om_mesh=[0.0], with_Sigma=False, n_om=None, broadening=0.0):
|
||||||
r"""
|
r"""
|
||||||
Calculates the transport distribution
|
Calculates the transport distribution
|
||||||
|
30
python/version.py.in
Normal file
30
python/version.py.in
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 by M. Aichhorn, L. Pourovskii, V. Vildosola
|
||||||
|
#
|
||||||
|
# TRIQS is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
version = "@DFT_TOOLS_VERSION@"
|
||||||
|
triqs_hash = "@TRIQS_GIT_HASH@"
|
||||||
|
cthyb_hash = "@CTHYB_GIT_HASH@"
|
||||||
|
|
||||||
|
def show_version():
|
||||||
|
print "\nYou are using the dft_tools version %s\n"%version
|
||||||
|
|
||||||
|
def show_git_hash():
|
||||||
|
print "\nYou are using the dft_tools git hash %s based on triqs git hash %s\n"%(cthyb_hash, triqs_hash)
|
@ -1,12 +1,18 @@
|
|||||||
# load triqs helper to set up tests
|
# load triqs helper to set up tests
|
||||||
find_package(TriqsTest)
|
find_package(TriqsTest)
|
||||||
|
|
||||||
FILE(COPY SrVO3.h5 SrVO3_Sigma.h5 SrVO3.pmat SrVO3.struct SrVO3.outputs SrVO3.oubwin SrVO3.ctqmcout SrVO3.symqmc SrVO3.sympar SrVO3.parproj hk_convert_hamiltonian.hk DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
# Copy h5 files to binary dir
|
||||||
#triqs_add_test_hdf(wien2k_convert " -p 1.e-6" )
|
FILE(GLOB all_h5_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h5)
|
||||||
#triqs_add_test_hdf(hk_convert " -p 1.e-6" )
|
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/${all_h5_files} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
#triqs_add_test_hdf(sumkdft_basic " -d 1.e-6" )
|
# Copy other files
|
||||||
#triqs_add_test_hdf(srvo3_Gloc " -d 1.e-6" )
|
FILE(COPY SrVO3.pmat SrVO3.struct SrVO3.outputs SrVO3.oubwin SrVO3.ctqmcout SrVO3.symqmc SrVO3.sympar SrVO3.parproj hk_convert_hamiltonian.hk LaVO3-Pnma_hr.dat LaVO3-Pnma.inp DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
#triqs_add_test_hdf(srvo3_transp " -d 1.e-6" )
|
|
||||||
#triqs_add_test_hdf(sigma_from_file " -d 1.e-6" )
|
triqs_add_python_test(wien2k_convert)
|
||||||
|
triqs_add_python_test(hk_convert)
|
||||||
|
triqs_add_python_test(w90_convert)
|
||||||
|
triqs_add_python_test(sumkdft_basic)
|
||||||
|
triqs_add_python_test(srvo3_Gloc)
|
||||||
|
triqs_add_python_test(srvo3_transp)
|
||||||
|
triqs_add_python_test(sigma_from_file)
|
||||||
|
|
||||||
add_subdirectory(plovasp)
|
add_subdirectory(plovasp)
|
||||||
|
7
test/LaVO3-Pnma.inp
Normal file
7
test/LaVO3-Pnma.inp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
0 3 2 3
|
||||||
|
8.0
|
||||||
|
4
|
||||||
|
0 0 2 3 0 0
|
||||||
|
1 0 2 3 0 0
|
||||||
|
2 0 2 3 0 0
|
||||||
|
3 0 2 3 0 0
|
3893
test/LaVO3-Pnma_hr.dat
Normal file
3893
test/LaVO3-Pnma_hr.dat
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,12 @@
|
|||||||
|
|
||||||
from pytriqs.applications.dft.converters import *
|
from pytriqs.applications.dft.converters import *
|
||||||
from pytriqs.archive import *
|
from pytriqs.archive import *
|
||||||
|
from pytriqs.utility.h5diff import h5diff
|
||||||
|
import pytriqs.utility.mpi as mpi
|
||||||
|
|
||||||
Converter = HkConverter(filename='hk_convert_hamiltonian.hk',hdf_filename='hk_convert.output.h5')
|
Converter = HkConverter(filename='hk_convert_hamiltonian.hk',hdf_filename='hk_convert.out.h5')
|
||||||
|
|
||||||
Converter.convert_dft_input()
|
Converter.convert_dft_input()
|
||||||
|
|
||||||
|
if mpi.is_master_node():
|
||||||
|
h5diff("hk_convert.out.h5","hk_convert.ref.h5")
|
||||||
|
@ -1,7 +1,29 @@
|
|||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 by M. Aichhorn, L. Pourovskii, V. Vildosola
|
||||||
|
#
|
||||||
|
# TRIQS is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
from pytriqs.archive import *
|
from pytriqs.archive import *
|
||||||
from pytriqs.gf.local import *
|
from pytriqs.gf.local import *
|
||||||
from pytriqs.gf.local.tools import *
|
from pytriqs.gf.local.tools import *
|
||||||
from pytriqs.applications.dft.sumk_dft_tools import *
|
from pytriqs.applications.dft.sumk_dft_tools import *
|
||||||
|
from pytriqs.utility.comparison_tests import *
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
# Read self energy from hdf file
|
# Read self energy from hdf file
|
||||||
@ -24,9 +46,9 @@ a_list = [a for a,al in SK.gf_struct_solver[0].iteritems()]
|
|||||||
g_list = [read_gf_from_txt([['Sigma_' + a + '.dat']], a) for a in a_list]
|
g_list = [read_gf_from_txt([['Sigma_' + a + '.dat']], a) for a in a_list]
|
||||||
Sigma_txt = BlockGf(name_list = a_list, block_list = g_list, make_copies=False)
|
Sigma_txt = BlockGf(name_list = a_list, block_list = g_list, make_copies=False)
|
||||||
|
|
||||||
SK.put_Sigma(Sigma_imp = [Sigma_txt])
|
SK.set_Sigma([Sigma_txt])
|
||||||
|
|
||||||
SK.hdf_file = 'sigma_from_file.output.h5'
|
SK.hdf_file = 'sigma_from_file.out.h5'
|
||||||
SK.save(['Sigma_imp_w'])
|
SK.save(['Sigma_imp_w'])
|
||||||
|
|
||||||
if ((Sigma_txt - Sigma_hdf).real < 1e-6) & ((Sigma_txt - Sigma_hdf).imag < 1e-6):
|
if ((Sigma_txt - Sigma_hdf).real < 1e-6) & ((Sigma_txt - Sigma_hdf).imag < 1e-6):
|
||||||
|
@ -24,6 +24,8 @@ from pytriqs.gf.local import *
|
|||||||
from pytriqs.applications.dft.sumk_dft import *
|
from pytriqs.applications.dft.sumk_dft import *
|
||||||
from pytriqs.applications.dft.converters.wien2k_converter import *
|
from pytriqs.applications.dft.converters.wien2k_converter import *
|
||||||
from pytriqs.operators.util import set_operator_structure
|
from pytriqs.operators.util import set_operator_structure
|
||||||
|
from pytriqs.utility.comparison_tests import *
|
||||||
|
from pytriqs.utility.h5diff import h5diff
|
||||||
|
|
||||||
# Basic input parameters
|
# Basic input parameters
|
||||||
beta = 40
|
beta = 40
|
||||||
@ -41,9 +43,12 @@ gf_struct = set_operator_structure(spin_names,orb_names,orb_hybridized)
|
|||||||
glist = [ GfImFreq(indices=inner,beta=beta) for block,inner in gf_struct.iteritems()]
|
glist = [ GfImFreq(indices=inner,beta=beta) for block,inner in gf_struct.iteritems()]
|
||||||
Sigma_iw = BlockGf(name_list = gf_struct.keys(), block_list = glist, make_copies = False)
|
Sigma_iw = BlockGf(name_list = gf_struct.keys(), block_list = glist, make_copies = False)
|
||||||
|
|
||||||
SK.put_Sigma([Sigma_iw])
|
SK.set_Sigma([Sigma_iw])
|
||||||
Gloc = SK.extract_G_loc()
|
Gloc = SK.extract_G_loc()
|
||||||
|
|
||||||
ar = HDFArchive('srvo3_Gloc.output.h5','w')
|
if mpi.is_master_node():
|
||||||
|
with HDFArchive('srvo3_Gloc.out.h5','w') as ar:
|
||||||
ar['Gloc'] = Gloc[0]
|
ar['Gloc'] = Gloc[0]
|
||||||
del ar
|
|
||||||
|
if mpi.is_master_node():
|
||||||
|
h5diff("srvo3_Gloc.out.h5","srvo3_Gloc.ref.h5")
|
||||||
|
@ -23,6 +23,8 @@ from numpy import *
|
|||||||
from pytriqs.applications.dft.converters.wien2k_converter import *
|
from pytriqs.applications.dft.converters.wien2k_converter import *
|
||||||
from pytriqs.applications.dft.sumk_dft import *
|
from pytriqs.applications.dft.sumk_dft import *
|
||||||
from pytriqs.applications.dft.sumk_dft_tools import *
|
from pytriqs.applications.dft.sumk_dft_tools import *
|
||||||
|
from pytriqs.utility.comparison_tests import *
|
||||||
|
from pytriqs.utility.h5diff import h5diff
|
||||||
|
|
||||||
beta = 40
|
beta = 40
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ SK = SumkDFTTools(hdf_file='SrVO3.h5', use_dft_blocks=True)
|
|||||||
|
|
||||||
ar = HDFArchive('SrVO3_Sigma.h5', 'a')
|
ar = HDFArchive('SrVO3_Sigma.h5', 'a')
|
||||||
Sigma = ar['dmft_transp_input']['Sigma_w']
|
Sigma = ar['dmft_transp_input']['Sigma_w']
|
||||||
SK.put_Sigma(Sigma_imp = [Sigma])
|
SK.set_Sigma([Sigma])
|
||||||
SK.chemical_potential = ar['dmft_transp_input']['chemical_potential']
|
SK.chemical_potential = ar['dmft_transp_input']['chemical_potential']
|
||||||
SK.dc_imp = ar['dmft_transp_input']['dc_imp']
|
SK.dc_imp = ar['dmft_transp_input']['dc_imp']
|
||||||
del ar
|
del ar
|
||||||
@ -43,6 +45,8 @@ SK.transport_distribution(directions=['xx'], broadening=0.0, energy_window=[-0.3
|
|||||||
#SK.save(['Gamma_w','Om_meshr','omega','directions'])
|
#SK.save(['Gamma_w','Om_meshr','omega','directions'])
|
||||||
#SK.load(['Gamma_w','Om_meshr','omega','directions'])
|
#SK.load(['Gamma_w','Om_meshr','omega','directions'])
|
||||||
SK.conductivity_and_seebeck(beta=beta)
|
SK.conductivity_and_seebeck(beta=beta)
|
||||||
SK.hdf_file = 'srvo3_transp.output.h5'
|
SK.hdf_file = 'srvo3_transp.out.h5'
|
||||||
SK.save(['seebeck','optic_cond'])
|
SK.save(['seebeck','optic_cond'])
|
||||||
|
|
||||||
|
if mpi.is_master_node():
|
||||||
|
h5diff("srvo3_transp.out.h5","srvo3_transp.ref.h5")
|
||||||
|
@ -22,14 +22,18 @@
|
|||||||
|
|
||||||
from pytriqs.archive import *
|
from pytriqs.archive import *
|
||||||
from pytriqs.applications.dft.sumk_dft_tools import SumkDFTTools
|
from pytriqs.applications.dft.sumk_dft_tools import SumkDFTTools
|
||||||
|
import pytriqs.utility.mpi as mpi
|
||||||
|
from pytriqs.utility.comparison_tests import *
|
||||||
|
from pytriqs.utility.h5diff import h5diff
|
||||||
|
|
||||||
SK = SumkDFTTools(hdf_file = 'SrVO3.h5')
|
SK = SumkDFTTools(hdf_file = 'SrVO3.h5')
|
||||||
|
|
||||||
dm = SK.density_matrix(method = 'using_gf', beta = 40)
|
dm = SK.density_matrix(method = 'using_gf', beta = 40)
|
||||||
dm_pc = SK.partial_charges(beta=40,with_Sigma=False,with_dc=False)
|
dm_pc = SK.partial_charges(beta=40,with_Sigma=False,with_dc=False)
|
||||||
|
|
||||||
ar = HDFArchive('sumkdft_basic.output.h5','w')
|
with HDFArchive('sumkdft_basic.out.h5','w') as ar:
|
||||||
ar['dm'] = dm
|
ar['dm'] = dm
|
||||||
ar['dm_pc'] = dm_pc
|
ar['dm_pc'] = dm_pc
|
||||||
del ar
|
|
||||||
|
if mpi.is_master_node():
|
||||||
|
h5diff('sumkdft_basic.out.h5','sumkdft_basic.ref.h5')
|
||||||
|
34
test/w90_convert.py
Normal file
34
test/w90_convert.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 by M. Aichhorn, L. Pourovskii, V. Vildosola
|
||||||
|
#
|
||||||
|
# TRIQS is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
from pytriqs.applications.dft.converters import *
|
||||||
|
from pytriqs.archive import *
|
||||||
|
from pytriqs.utility.h5diff import h5diff
|
||||||
|
import pytriqs.utility.mpi as mpi
|
||||||
|
|
||||||
|
Converter = Wannier90Converter(seedname='LaVO3-Pnma',hdf_filename='w90_convert.out.h5')
|
||||||
|
|
||||||
|
Converter.convert_dft_input()
|
||||||
|
|
||||||
|
if mpi.is_master_node():
|
||||||
|
h5diff("w90_convert.out.h5","w90_convert.ref.h5")
|
BIN
test/w90_convert.ref.h5
Normal file
BIN
test/w90_convert.ref.h5
Normal file
Binary file not shown.
@ -22,13 +22,15 @@
|
|||||||
|
|
||||||
from pytriqs.archive import *
|
from pytriqs.archive import *
|
||||||
from pytriqs.applications.dft.converters import Wien2kConverter
|
from pytriqs.applications.dft.converters import Wien2kConverter
|
||||||
|
from pytriqs.utility.comparison_tests import *
|
||||||
|
from pytriqs.utility.h5diff import h5diff
|
||||||
|
import pytriqs.utility.mpi as mpi
|
||||||
|
|
||||||
Converter = Wien2kConverter(filename='SrVO3')
|
Converter = Wien2kConverter(filename='SrVO3')
|
||||||
Converter.hdf_file = 'wien2k_convert.output.h5'
|
Converter.hdf_file = 'wien2k_convert.out.h5'
|
||||||
Converter.convert_dft_input()
|
Converter.convert_dft_input()
|
||||||
|
|
||||||
Converter.convert_parproj_input()
|
Converter.convert_parproj_input()
|
||||||
|
|
||||||
|
if mpi.is_master_node():
|
||||||
|
h5diff('wien2k_convert.out.h5','wien2k_convert.ref.h5')
|
||||||
|
Loading…
Reference in New Issue
Block a user