mirror of
https://github.com/triqs/dft_tools
synced 2024-12-23 04:43:42 +01:00
Merge branch 'merge_vasp2dmft' into unstable
This commit is contained in:
commit
b647762349
@ -18,6 +18,6 @@ add_custom_target(doc_sphinx ALL DEPENDS ${sphinx_top} ${CMAKE_CURRENT_BINARY_DI
|
||||
# ---------------------------------
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ COMPONENT documentation DESTINATION share/doc/triqs_dft_tools
|
||||
FILES_MATCHING
|
||||
REGEX "\\.(html|pdf|png|gif|jpg|js|xsl|css|py|txt|inv|bib)$"
|
||||
REGEX "\\.(html|pdf|png|gif|jpg|js|xsl|css|py|txt|inv|bib|cfg)$"
|
||||
PATTERN "_*"
|
||||
)
|
||||
|
@ -14,7 +14,11 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.autosummary',
|
||||
'numpydoc']
|
||||
'nbsphinx',
|
||||
'numpydoc',
|
||||
'sphinx.ext.githubpages',
|
||||
'IPython.sphinxext.ipython_console_highlighting'
|
||||
]
|
||||
|
||||
source_suffix = '.rst'
|
||||
|
||||
|
@ -1,50 +1,67 @@
|
||||
.. _convVASP:
|
||||
|
||||
|
||||
===================
|
||||
Interface with VASP
|
||||
===================
|
||||
|
||||
.. warning::
|
||||
The VASP interface is in the alpha-version and the VASP part of it is not
|
||||
yet publicly released. The documentation may, thus, be subject to changes
|
||||
before the final release.
|
||||
The VASP interface relies on new options introduced since version 5.4.x In
|
||||
particular, a new INCAR-option `LOCPROJ
|
||||
<https://cms.mpi.univie.ac.at/wiki/index.php/LOCPROJ>`_, the new `LORBIT` modes
|
||||
13 and 14 have been added, and the new `ICHARG` mode 5 for charge
|
||||
self-consistent DFT+DMFT calculations have been added.
|
||||
|
||||
*Limitations of the alpha-version:*
|
||||
The VASP interface methodologically builds on the so called projection on
|
||||
localized orbitals (PLO) scheme, where the resulting KS states from DFT are
|
||||
projected on localized orbitals, which defines a basis for setting up a
|
||||
Hubbard-like model Hamiltonian. Resulting in lattice object stored in `SumkDFT`.
|
||||
The implementation is presented in `M. Schüler et al. 2018 J. Phys.: Condens.
|
||||
Matter 30 475901 <https://doi.org/10.1088/1361-648X/aae80a>`_.
|
||||
|
||||
* The interface works correctly only if the k-point symmetries
|
||||
are turned off during the VASP run (ISYM=-1).
|
||||
The interface consists of two parts, :ref:`PLOVASP<refPLOVASP>`, a collection of
|
||||
python classes and functions converting the raw VASP output to proper projector
|
||||
functions, and the python based :ref:`VaspConverter<refVASPconverter>`, which
|
||||
creates a h5 archive from the :ref:`PLOVASP<refPLOVASP>` output readable by
|
||||
`SumkDFT`. Therefore, the conversion consist always of two steps.
|
||||
|
||||
* Generation of projectors for k-point lines (option `Lines` in KPOINTS)
|
||||
needed for Bloch spectral function calculations is not possible at the moment.
|
||||
Here, we will present a guide how the interface `can` be used to create input for a DMFT calculation, using SrVO3 as an example. Full examples can be found in the :ref:`tutorial section of DFTTools<tutorials>`.
|
||||
|
||||
* The interface currently supports only collinear-magnetism calculation
|
||||
(this implis no spin-orbit coupling) and
|
||||
spin-polarized projectors have not been tested.
|
||||
Limitations of the interface
|
||||
============================
|
||||
|
||||
A detailed description of the VASP converter tool PLOVasp can be found
|
||||
in the :ref:`PLOVasp User's Guide <plovasp>`. Here, a quick-start guide is presented.
|
||||
* The interface works correctly only if the k-point symmetries
|
||||
are turned off during the VASP run (ISYM=-1).
|
||||
* Generation of projectors for k-point lines (option `Lines` in KPOINTS)
|
||||
needed for Bloch spectral function calculations is not possible at the moment.
|
||||
* The interface currently supports only collinear-magnetism calculation
|
||||
(this implies no spin-orbit coupling) and spin-polarized projectors have not
|
||||
been tested.
|
||||
* The converter needs the correct Fermi energy from VASP, which is read from
|
||||
the LOCPROJ file. However, VASP by default does not output this information.
|
||||
Please see `Remarks on the VASP version`_.
|
||||
|
||||
The VASP interface relies on new options introduced since version
|
||||
5.4.x. In particular, a new INCAR-option `LOCPROJ`
|
||||
and new `LORBIT` modes 13 and 14 have been added.
|
||||
VASP: generating raw projectors
|
||||
===============================
|
||||
|
||||
Option `LOCPROJ` selects a set of localized projectors that will
|
||||
be written to file `LOCPROJ` after a successful VASP run.
|
||||
A projector set is specified by site indices,
|
||||
labels of the target local states, and projector type:
|
||||
The VASP **INCAR** option `LOCPROJ` selects a set of localized projectors that
|
||||
will be written to the file **LOCPROJ** after a successful VASP run. A projector set is specified by site indices, labels of the target local states, and projector type:
|
||||
|
||||
| `LOCPROJ = <sites> : <shells> : <projector type>`
|
||||
|
||||
where `<sites>` represents a list of site indices separated by spaces,
|
||||
with the indices corresponding to the site position in the POSCAR file;
|
||||
`<shells>` specifies local states (see below);
|
||||
`<projector type>` chooses a particular type of the local basis function.
|
||||
The recommended projector type is `Pr 2`. The formalism for this type
|
||||
of projectors is presented in
|
||||
`M. Schüler et al. 2018 J. Phys.: Condens. Matter 30 475901 <https://doi.org/10.1088/1361-648X/aae80a>`_.
|
||||
where `<sites>` represents a list of site indices separated by spaces, with the
|
||||
indices corresponding to the site position in the **POSCAR** file; `<shells>`
|
||||
specifies local states (see below); `<projector type>` chooses a particular type
|
||||
of the local basis function. The recommended projector type is `Pr 2`. This will
|
||||
perform a projection of the Kohn-Sham states onto the VASP PAW projector
|
||||
functions. The number specified behind `Pr` is selecting a specific PAW channel,
|
||||
see the `VASP wiki page <https://cms.mpi.univie.ac.at/wiki/index.php/LOCPROJ>`_
|
||||
for more information. The formalism for this type of projectors is presented in
|
||||
`M. Schüler et al. 2018 J. Phys.: Condens. Matter 30 475901
|
||||
<https://doi.org/10.1088/1361-648X/aae80a>`_. For further details on the
|
||||
`LOCPROJ` flag also have a look in the `VASP wiki
|
||||
<https://cms.mpi.univie.ac.at/wiki/index.php/LOCPROJ>`_.
|
||||
|
||||
The allowed labels of the local states defined in terms of cubic
|
||||
harmonics are:
|
||||
harmonics are (mind the order):
|
||||
|
||||
* Entire shells: `s`, `p`, `d`, `f`
|
||||
|
||||
@ -55,16 +72,25 @@ harmonics are:
|
||||
* `f`-states: `fy(3x2-y2)`, `fxyz`, `fyz2`, `fz3`,
|
||||
`fxz2`, `fz(x2-y2)`, `fx(x2-3y2)`.
|
||||
|
||||
For projector type `Pr 2`, one should also set `LORBIT = 14` in the INCAR file
|
||||
and provide parameters `EMIN`, `EMAX`, defining, in this case, an
|
||||
energy range (energy window) corresponding to the valence states.
|
||||
Note that, as in the case
|
||||
of a DOS calculation, the position of the valence states depends on the
|
||||
Fermi level, which can usually be found at the end of the OUTCAR file.
|
||||
For projector type `Pr`, one should ideally also set `LORBIT = 14` in the
|
||||
INCAR file and provide parameters `EMIN`, `EMAX`, defining, in this case, an
|
||||
energy range (energy window) corresponding to the valence states. Note that,
|
||||
as in the case of a DOS calculation, the position of the valence states
|
||||
depends on the Fermi level, which can usually be found at the end of the
|
||||
OUTCAR file. Setting `LORBIT=14` will perform an automatic optimization of
|
||||
the PAW projector channel as described in `M. Schüler et al. 2018 J. Phys.:
|
||||
Condens. Matter 30 475901 <https://doi.org/10.1088/1361-648X/aae80a>`_, by
|
||||
using a linear combination of the PAW channels, to maximize the overlap in
|
||||
the chosen energy window between the projector and the Kohn-Sham state.
|
||||
Therefore, setting `LORBIT=14` will let VASP ignore the channel specified
|
||||
after `Pr`. This optimization is only performed for the projector type `Pr`,
|
||||
not for `Ps` and obviously not for `Hy`. We recommend to specify the PAW
|
||||
channel anyway, in case one forgets to set `LORBIT=14`.
|
||||
|
||||
For example, in case of SrVO3 one may first want to perform a self-consistent
|
||||
calculation, then set `ICHARGE = 1` and add the following additional
|
||||
lines into INCAR (provided that V is the second ion in POSCAR):
|
||||
In case of SrVO3 one may first want to perform a self-consistent
|
||||
calculation to know the Fermi level and the rough position of the target states.
|
||||
In the next step one sets `ICHARG = 1` and adds the following additional lines
|
||||
into INCAR (provided that V is the second ion in POSCAR):
|
||||
|
||||
| `EMIN = 3.0`
|
||||
| `EMAX = 8.0`
|
||||
@ -72,73 +98,320 @@ lines into INCAR (provided that V is the second ion in POSCAR):
|
||||
| `LOCPROJ = 2 : d : Pr 2`
|
||||
|
||||
The energy range does not have to be precise. Important is that it has a large
|
||||
overlap with valence bands and no overlap with semi-core or high unoccupied states.
|
||||
overlap with valence bands and no overlap with semi-core or high unoccupied
|
||||
states. This **INCAR** will calculate and write-out projections for all five d-orbitals.
|
||||
|
||||
|
||||
VASP input-output
|
||||
-----------------
|
||||
|
||||
The calculated projections :math:`\langle \chi_L | \Psi_\mu \rangle` are written
|
||||
into files **PROJCAR** and **LOCPROJ**. The difference between these two files
|
||||
is that **LOCPROJ** contains raw matrices without any reference to
|
||||
sites/orbitals, while **PROJCAR** is more detailed. In particular, the
|
||||
information that can be obtained for each projector from **PROJCAR** is the
|
||||
following:
|
||||
|
||||
* site (and species) index
|
||||
* for each `k`-point and band: a set of complex numbers for labeled orbitals
|
||||
|
||||
At the same time, **LOCPROJ** contains the total number of projectors (as well
|
||||
as the number of `k`-points, bands, and spin channels) in the first line, which
|
||||
can be used to allocate the arrays before parsing.
|
||||
|
||||
Conversion for the DMFT self-consistency cycle
|
||||
----------------------------------------------
|
||||
==============================================
|
||||
|
||||
The projectors generated by VASP require certain post-processing before
|
||||
they can be used for DMFT calculations. The most important step is to normalize
|
||||
The projectors generated by VASP require certain post-processing before they can
|
||||
be used for DMFT calculations. The most important step is to (ortho-)normalize
|
||||
them within an energy window that selects band states relevant for the impurity
|
||||
problem. Note that this energy window is different from the one described above
|
||||
and it must be chosen independently of the energy
|
||||
range given by `EMIN, EMAX` in INCAR.
|
||||
problem. This will create proper Wannier functions of the initial projections
|
||||
produced by VASP. Note that this energy window is different from the one
|
||||
described above and it must be chosen independently of the energy range given by
|
||||
`EMIN, EMAX` in the **INCAR** VASP input file. This part is done in `PLOVASP`.
|
||||
|
||||
Post-processing of `LOCPROJ` data is generally done as follows:
|
||||
|
||||
#. Prepare an input file `<name>.cfg` (e.g., `plo.cfg`) that describes the definition
|
||||
of your impurity problem (more details below).
|
||||
PLOVASP: converting VASP output
|
||||
--------------------------------
|
||||
|
||||
#. Extract the value of the Fermi level from OUTCAR and paste it at the end of
|
||||
the first line of LOCPROJ.
|
||||
:ref:`PLOVASP<refPLOVASP>` is a collection of python functions and classes, post-processing the raw VASP `LOCPROJ` output creating proper projector functions.
|
||||
|
||||
#. Run :program:`plovasp` with the input file as an argument, e.g.:
|
||||
The following VASP files are used by PLOVASP:
|
||||
* PROJCAR, LOCPROJ: raw projectors generated by VASP-PLO interface
|
||||
* EIGENVAL: Kohn-Sham eigenvalues as well as `k`-points with weights and Fermi weights
|
||||
* IBZKPT: `k`-point data (:math:`\Gamma`)
|
||||
* POSCAR: crystal structure data
|
||||
|
||||
| `plovasp plo.cfg`
|
||||
To run `PLOVASP`, one first prepares an input file `<name>.cfg` (default name `plo.cfg`) that describes the definition of the correlated subspace. For SrVO3 this input file would look like this:
|
||||
|
||||
This requires that the TRIQS paths are set correctly (see Installation
|
||||
of TRIQS).
|
||||
.. literalinclude:: ../tutorials/svo_vasp/plo.cfg
|
||||
|
||||
If everything goes right one gets files `<name>.ctrl` and `<name>.pg1`.
|
||||
These files are needed for the converter that will be invoked in your
|
||||
DMFT script.
|
||||
In the [section] general, the `DOSMESH` defines an energy window and number of
|
||||
data points, which lets the converter calculate the density of states of the
|
||||
created projector functions in a given energy window. Each projector shell is
|
||||
defined by a section `[Shell 1]` where the number can be arbitrary and used only
|
||||
for user convenience. Several parameters are required
|
||||
|
||||
The format of input file `<name>.cfg` is described in details in
|
||||
the :ref:`User's Guide <plovasp>`. Here we just consider a simple example for the case
|
||||
of SrVO3:
|
||||
|
||||
.. literalinclude:: images_scripts/srvo3.cfg
|
||||
|
||||
A projector shell is defined by a section `[Shell 1]` where the number
|
||||
can be arbitrary and used only for user convenience. Several
|
||||
parameters are required
|
||||
|
||||
- **IONS**: list of site indices which must be a subset of indices
|
||||
given earlier in `LOCPROJ`.
|
||||
- **IONS**: list of site indices which must be a subset of indices given earlier
|
||||
in the VASP INCAR `LOCPROJ` flag. Note: If projections are performed for
|
||||
multiple sites one can specify symmetry equivalent sites with brackets: `[2
|
||||
3]`. Here the projector are generated for ions 2 and 3, but they will be
|
||||
marked as symmetry equivalent later in 'SumkDFT'.
|
||||
- **LSHELL**: :math:`l`-quantum number of the projector shell; the corresponding
|
||||
orbitals must be present in `LOCPROJ`.
|
||||
- **EWINDOW**: energy window in which the projectors are normalized;
|
||||
note that the energies are defined with respect to the Fermi level.
|
||||
|
||||
Option **TRANSFORM** is optional but here, it is specified to extract
|
||||
only three :math:`t_{2g}` orbitals out of five `d` orbitals given by
|
||||
:math:`l = 2`.
|
||||
The Option **TRANSFORM** is optional here, and it is specified to extract
|
||||
only the three :math:`t_{2g}` orbitals out of the five `d` orbitals given by
|
||||
:math:`l = 2`. A detailed explanation of all input parameters can be found
|
||||
further below `PLOVASP detailed guide`_.
|
||||
|
||||
The conversion to a h5-file is performed in the same way as for Wien2TRIQS::
|
||||
Next, the converter is executed. This can be done by calling :program:`PLOVASP` directly in the command line with the input file as an argument, e.g.:
|
||||
| `plovasp plo.cfg`
|
||||
|
||||
or embedded in a python script as::
|
||||
|
||||
import triqs_dft_tools.converters.plovasp.converter as plo_converter
|
||||
# Generate and store PLOs
|
||||
plo_converter.generate_and_output_as_text('plo.cfg', vasp_dir='./')
|
||||
|
||||
This will create the xml files `vasp.ctrl` and `vasp.pg1` containing the orthonormalized projector functions readable by the :ref:`VaspConverter<refVASPconverter>`. Moreover, `PLOVASP` will output important information of the orthonormalization process, such as the density matrix of the correlated shell and the local Hamiltonian.
|
||||
|
||||
Running the VASP converter
|
||||
-------------------------------------
|
||||
|
||||
The actual conversion to a h5-file is performed with the orthonormalized projector functions readable by the :ref:`VaspConverter<refVASPconverter>` in the same fashion as with the other `DFTTools` converters::
|
||||
|
||||
from triqs_dft_tools.converters.vasp_converter import *
|
||||
Converter = VaspConverter(filename = filename)
|
||||
Converter = VaspConverter(filename = 'vasp')
|
||||
Converter.convert_dft_input()
|
||||
|
||||
As usual, the resulting h5-file can then be used with the SumkDFT class.
|
||||
As usual, the resulting h5-file can then be used with the SumkDFT class::
|
||||
sk = SumkDFTTools(hdf_file='vasp.h5')
|
||||
|
||||
Note that the automatic detection of the correct block structure might
|
||||
fail for VASP inputs.
|
||||
This can be circumvented by setting a bigger value of the threshold in
|
||||
:class:`SumkDFT <dft.sumk_dft.SumkDFT>`, e.g.::
|
||||
Note that the automatic detection of the correct block structure might fail for
|
||||
VASP inputs. This can be circumvented by setting a bigger value of the threshold
|
||||
in :class:`SumkDFT <dft.sumk_dft.SumkDFT>`, e.g.::
|
||||
|
||||
SK.analyse_block_structure(threshold = 1e-4)
|
||||
|
||||
However, do this only after a careful study of the density matrix and
|
||||
the projected DOS in the localized basis.
|
||||
However, this should only be done after a careful study of the density matrix and the projected DOS in the localized basis. For the complete process for SrVO3 see the tutorial for the VASP interface `here <../tutorials/svo_vasp/svo_notebook.html>`_.
|
||||
|
||||
PLOVASP detailed guide
|
||||
======================
|
||||
|
||||
The general purpose of the PLOVASP tool is to transform raw, non-normalized
|
||||
projectors generated by VASP into normalized projectors corresponding to
|
||||
user-defined projected localized orbitals (PLO). To enhance the performance
|
||||
parsing the raw VASP output files, the parser is implemented in plain C. The
|
||||
idea is that the python part of the parser first reads the first line of
|
||||
**LOCPROJ** and then calls the C-routine with necessary parameters to parse
|
||||
**PROJCAR**. The resulting PLOs can then be used for DFT+DMFT calculations with
|
||||
or without charge self-consistency. PLOVASP also provides some utilities for
|
||||
basic analysis of the generated projectors, such as outputting density matrices,
|
||||
local Hamiltonians, and projected density of states.
|
||||
|
||||
PLOs are determined by the energy window in which the raw projectors are
|
||||
normalized. This allows to define either atomic-like strongly localized Wannier
|
||||
functions (large energy window) or extended Wannier functions focusing on
|
||||
selected low-energy states (small energy window).
|
||||
|
||||
In PLOVASP, all projectors sharing the same energy window are combined into a
|
||||
`projector group`. This allows one in principal to define several groups with
|
||||
different energy windows for the same set of raw projectors. Note: multiple groups are not yet implemented.
|
||||
|
||||
A set of projectors defined on sites related to each other either by symmetry
|
||||
or by an atomic sort, along with a set of :math:`l`, :math:`m` quantum numbers,
|
||||
forms a `projector shell`. There could be several projectors shells in a
|
||||
projector group, implying that they will be normalized within the same energy
|
||||
window.
|
||||
|
||||
Projector shells and groups are specified by a user-defined input file whose
|
||||
format is described below. Additionally, each shell can be marked correlated or non-correlated, to tell `SumkDFT` whether or not these should be treated in the DMFT impurity problem.
|
||||
|
||||
Input file format
|
||||
-----------------
|
||||
|
||||
The input file is written in the standard config-file format.
|
||||
Parameters (or 'options') are grouped into sections specified as
|
||||
`[Section name]`. All parameters must be defined inside some section.
|
||||
|
||||
A PLOVASP input file can contain three types of sections:
|
||||
|
||||
#. **[General]**: includes parameters that are independent
|
||||
of a particular projector set, such as the Fermi level, additional
|
||||
output (e.g. the density of states), etc.
|
||||
#. **[Group <Ng>]**: describes projector groups, i.e. a set of
|
||||
projectors sharing the same energy window and normalization type.
|
||||
At the moment, DFTtools support only one projector group, therefore
|
||||
there should be no more than one projector group.
|
||||
#. **[Shell <Ns>]**: contains parameters of a projector shell labelled
|
||||
with `<Ns>`. If there is only one group section and one shell section,
|
||||
the group section can be omitted but in this case, the group required
|
||||
parameters must be provided inside the shell section.
|
||||
|
||||
Section [General]
|
||||
"""""""""""""""""
|
||||
|
||||
The entire section is optional and it contains four parameters:
|
||||
|
||||
* **BASENAME** (string): provides a base name for output files.
|
||||
Default filenames are :file:`vasp.*`.
|
||||
* **DOSMESH** ([float float] integer): if this parameter is given,
|
||||
the projected density of states for each projected orbital will be
|
||||
evaluated and stored to files :file:`pdos_<s>_<n>.dat`, where `s` is the
|
||||
shell index and `n` the ion index. The energy mesh is defined by three
|
||||
numbers: `EMIN` `EMAX` `NPOINTS`. The first two
|
||||
can be omitted in which case they are taken to be equal to the projector
|
||||
energy window. **Important note**: at the moment this option works
|
||||
only if the tetrahedron integration method (`ISMEAR = -4` or `-5`)
|
||||
is used in VASP to produce `LOCPROJ`.
|
||||
* **EFERMI** (float): provides the Fermi level. This value overrides
|
||||
the one extracted from VASP output files.
|
||||
* **HK** (True/False): If True, the projectors are applied the the Kohn-Sham
|
||||
eigenvalues which results in a Hamitlonian H(k) in orbital basis. The H(k)
|
||||
is written for each group to a file :file:`Basename.hk<Ng>`. It is recommended
|
||||
to also set `COMPLEMENT = True` (see below). Default is False.
|
||||
|
||||
There are no required parameters in this section.
|
||||
|
||||
Section [Shell]
|
||||
"""""""""""""""
|
||||
|
||||
This section specifies a projector shell. Each `[Shell]` section must be
|
||||
labeled by an index, e.g. `[Shell 1]`. These indices can then be referenced
|
||||
in a `[Group]` section.
|
||||
|
||||
In each `[Shell]` section two parameters are required:
|
||||
|
||||
* **IONS** (list of integer): indices of sites included in the shell.
|
||||
The sites can be given either by a list of integers `IONS = 5 6 7 8`
|
||||
or by a range `IONS = 5..8`. The site indices must be compatible with
|
||||
the POSCAR file.
|
||||
* **LSHELL** (integer): :math:`l` quantum number of the desired local states.
|
||||
|
||||
It is important that a given combination of site indices and local states
|
||||
given by `LSHELL` must be present in the LOCPROJ file.
|
||||
|
||||
There are additional optional parameters that allow one to transform
|
||||
the local states:
|
||||
|
||||
* **CORR** (True/False): Determines if shell is correlated or not. At least one
|
||||
shell has to be correlated. Default is True.
|
||||
* **SORT** (integer): Overrides the default detection of ion sorts by supplying
|
||||
an integer. Default is `None`, for which the default behavior is retained.
|
||||
* **TRANSFORM** (matrix): local transformation matrix applied to all states
|
||||
in the projector shell. The matrix is defined by a (multiline) block
|
||||
of floats, with each line corresponding to a row. The number of columns
|
||||
must be equal to :math:`2 l + 1`, with :math:`l` given by `LSHELL`. Only real matrices
|
||||
are allowed. This parameter can be useful to select certain subset of
|
||||
orbitals or perform a simple global rotation.
|
||||
* **TRANSFILE** (string): name of the file containing transformation
|
||||
matrices for each site. This option allows for a full-fledged functionality
|
||||
when it comes to local state transformations. The format of this file
|
||||
is described :ref:`below <transformation_file>`.
|
||||
|
||||
Section [Group]
|
||||
"""""""""""""""
|
||||
|
||||
Each defined projector shell must be part of a projector group. In the current
|
||||
implementation of DFTtools only a single group (labelled by any integer, e.g. `[Group 1]`)
|
||||
is supported. This implies that all projector shells
|
||||
must be included in this group.
|
||||
|
||||
Required parameters for any group are the following:
|
||||
|
||||
* **SHELLS** (list of integers): indices of projector shells included in the group.
|
||||
All defined shells must be grouped.
|
||||
* **EWINDOW** (float float): the energy window specified by two floats: bottom
|
||||
and top. All projectors in the current group are going to be normalized within
|
||||
this window. *Note*: This option must be specified inside the `[Shell]` section
|
||||
if only one shell is defined and the `[Group]` section is omitted.
|
||||
|
||||
Optional group parameters:
|
||||
|
||||
* **NORMALIZE** (True/False): specifies whether projectors in the group are
|
||||
to be normalized. The default value is **True**.
|
||||
* **NORMION** (True/False): specifies whether projectors are normalized on
|
||||
a per-site (per-ion) basis. That is, if `NORMION = True`, the orthogonality
|
||||
condition will be enforced on each site separately but the Wannier functions
|
||||
on different sites will not be orthogonal. If `NORMION = False`, the Wannier functions
|
||||
on different sites included in the group will be orthogonal to each other. The default value is **True**
|
||||
* **BANDS** (int int): the energy window specified by two ints: band index of
|
||||
lowest band and band index of highest band. Using this overrides the selection
|
||||
in `EWINDOW`.
|
||||
* **COMPLEMENT** (True/False). If True, the orthogonal complement is calculated
|
||||
resulting in unitary (quadratic) projectors, i.e., the same number of orbitals
|
||||
as bands. It is required to have an equal number of bands in the energy window
|
||||
at each k-point. Default is False.
|
||||
|
||||
|
||||
.. _transformation_file:
|
||||
|
||||
File of transformation matrices
|
||||
"""""""""""""""""""""""""""""""
|
||||
|
||||
.. warning::
|
||||
The description below applies only to collinear cases (i.e., without spin-orbit
|
||||
coupling). In this case, the matrices are spin-independent.
|
||||
|
||||
The file specified by option `TRANSFILE` contains transformation matrices
|
||||
for each ion. Each line must contain a series of floats whose number is either equal to
|
||||
the number of orbitals :math:`N_{orb}` (in this case the transformation matrices
|
||||
are assumed to be real) or to :math:`2 N_{orb}` (for the complex transformation matrices).
|
||||
The total number of lines :math:`N` must be a multiple of the number of ions :math:`N_{ion}`
|
||||
and the ratio :math:`N / N_{ion}`, then, gives the dimension of the transformed
|
||||
orbital space. The lines with floats can be separated by any number of empty or
|
||||
comment lines (starting from `#`), which are ignored.
|
||||
|
||||
A very simple example is a transformation matrix that selects the :math:`t_{2g}` manifold.
|
||||
For two correlated sites, one can define the file as follows:
|
||||
::
|
||||
|
||||
# Site 1
|
||||
1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
||||
0.0 0.0 0.0 1.0 0.0
|
||||
|
||||
# Site 2
|
||||
1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
||||
0.0 0.0 0.0 1.0 0.0
|
||||
|
||||
Remarks on the VASP version
|
||||
===============================
|
||||
|
||||
In the current version of the interface the Fermi energy is extracted from the
|
||||
`LOCPROJ` file. The file should contain the Fermi energy in the header. One can
|
||||
either copy the Fermi energy manually there after a successful VASP run, or
|
||||
modify the VASP source code slightly, by replacing the following line in
|
||||
`locproj.F` (around line 695):
|
||||
::
|
||||
WRITE(99,'(4I6," # of spin, # of k-points, # of bands, # of proj" )') NS,NK,NB,NF
|
||||
|
||||
with:
|
||||
::
|
||||
WRITE(99,'(4I6,F12.7," # of spin, # of k-points, # of bands, # of proj, Efermi" )') W%WDES%NCDIJ,NK,NB,NF,EFERMI
|
||||
|
||||
Another critical point for CSC calculations is the function call of
|
||||
`LPRJ_LDApU` in VASP. This function is not needed, and was left there for debug
|
||||
purposes, but is called every iteration. Removing the call to this function in `electron.F` in line 644 speeds up the calculation significantly in the `ICHARG=5` mode. Moreover, this prevents VASP from generating the `GAMMA` file, which should ideally only be done by the DMFT code after a successful DMFT step, and then be read by VASP.
|
||||
|
||||
|
||||
Furthermore, there is a bug in `fileio.F` around line 1710 where VASP tries to
|
||||
print "reading the density matrix from Gamma". This should be done only by the
|
||||
master node, and VASP gets stuck sometimes. Adding a
|
||||
::
|
||||
IF (IO%IU0>=0) THEN
|
||||
...
|
||||
ENDIF
|
||||
statement resolves this issue. A similar problem occurs, when VASP writes the
|
||||
`OSZICAR` file and a buffer is stuck. Adding a `flush` to the buffer in
|
||||
`electron.F` around line 580 after
|
||||
::
|
||||
CALL STOP_TIMING("G",IO%IU6,"DOS")
|
||||
flush(17)
|
||||
print *, ' '
|
||||
|
||||
resolves this issue. Otherwise the OSZICAR file is not written properly.
|
||||
|
@ -13,7 +13,7 @@ as a light-weight general-purpose interface. In the following, we will describe
|
||||
conversion tools.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 3
|
||||
|
||||
conv_wien2k
|
||||
conv_vasp
|
||||
|
@ -124,28 +124,66 @@ example how such a self-consistent calculation is performed from scratch.
|
||||
VASP + PLOVasp
|
||||
--------------
|
||||
|
||||
.. warning::
|
||||
This is a preliminary documentation valid for the alpha-version of the interface.
|
||||
Modifications to the implementation might be introduced before the final release.
|
||||
Unlike Wien2k implementation the charge self-consistent DMFT cycle in the
|
||||
framework of PLOVasp interface is controlled by an external script. Because of
|
||||
the specific way the DFT self-consistency is implemented in VASP the latter has
|
||||
to run parallel to the DMFT script, with the synchronisation being ensured by a
|
||||
lock file.
|
||||
|
||||
Unlike Wien2k implementation the charge self-consistent DMFT cycle
|
||||
in the framework of PLOVasp interface is controlled by an external script.
|
||||
Because of the specific way the DFT self-consistency is implemented in VASP
|
||||
the latter has to run parallel to the DMFT script, with the synchronisation being
|
||||
ensured by a lock file. PLOVasp interface provides a shell-script :program:`vasp_dmft.sh`
|
||||
which takes care of the process management. The user must, however, specify a path
|
||||
to VASP code and provide the DMFT Python-script.
|
||||
Once VASP reaches the point where the projectors are generated
|
||||
it creates a lock file `vasp.lock` and waits until the lock file is
|
||||
removed. The shell script, in turn, waits for the VASP process and once
|
||||
the lock file is created it starts a DMFT iteration. The DMFT iteration
|
||||
must finish by generating a Kohn-Sham (KS) density matrix (file `GAMMA`)
|
||||
and removing the lock file. The VASP process then reads in `GAMMA`
|
||||
and proceeds with the next iteration. PLOVasp interface provides a shell-script :program:`vasp_dmft` (in the triqs bin directory):
|
||||
::
|
||||
vasp_dmft [-n <number of cores>] -i <number of iterations> -j <number of VASP iterations with fixed charge density> [-v <VASP version>] [-p <path to VASP directory>] [<dmft_script.py>]
|
||||
|
||||
If the number of cores is not specified it is set to 1 by default.
|
||||
Set the number of times the dmft solver is called with -i <number of iterations>
|
||||
|
||||
Set the number of VASP iteration with a fixed charge density update
|
||||
inbetween the dmft runs with -j <number of VASP iterations with fixed charge density>
|
||||
|
||||
Set the version of VASP by -v standard(default)/no_gamma_write to
|
||||
specify if VASP writes the GAMMA file or not.
|
||||
|
||||
If the path to VASP directory is not specified it must be provided by a
|
||||
variable VASP_DIR.
|
||||
|
||||
<dmft_script.py> must provide an importable function 'dmft_cycle()'
|
||||
which is invoked once per DFT+DMFT iteration. If the script name is
|
||||
omitted the default name 'csc_dmft.py' is used.
|
||||
|
||||
which takes care of the process management. The user must, however, specify a path to VASP code and provide the DMFT Python-script. See for an example :ref:`NiO CSC tutorial<nio_csc>`.
|
||||
|
||||
The user-provided script is almost the same as for Wien2k charge self-consistent
|
||||
calculations with the main difference that its functionality (apart from
|
||||
the lines importing other modules) should be placed inside a function `dmft_cycle()`
|
||||
which will be called every DMFT cycle. Another difference is the way
|
||||
function `calc_density_correction()` works.
|
||||
calculations with the main difference that its functionality (apart from the
|
||||
lines importing other modules) should be placed inside a function `dmft_cycle()`
|
||||
which will be called every DMFT cycle.
|
||||
|
||||
VASP has a special INCAR `ICHARG=5` mode, that has to be switched on to make VASP wait for the `vasp.lock` file, and read the updated charge density after each step. One should add the following lines to the `INCAR` file::
|
||||
|
||||
ICHARG = 5
|
||||
NELM = 1000
|
||||
NELMIN = 1000
|
||||
|
||||
Technically, VASP runs with `ICHARG=5` in a SCF mode, and adding the DMFT
|
||||
changes to the DFT density in each step, so that the full DFT+DMFT charge
|
||||
density is constructed in every step. This is only done in VASP because only the
|
||||
changes to the DFT density are read by VASP not the full DFT+DMFT density.
|
||||
Moreover, one should always start with a converged `WAVECAR` file, or make sure,
|
||||
that the KS states are well converged before the first projectors are created!
|
||||
To understand the difference please make sure to read `ISTART flag VASP wiki
|
||||
<https://www.vasp.at/wiki/index.php/ISTART>`_. Furthermore, the flags `NELM` and
|
||||
`NELMIN` ensure that VASP does not terminate after the default number of
|
||||
iterations of 60.
|
||||
|
||||
Other DFT codes
|
||||
---------------
|
||||
|
||||
The extension to other DFT codes is straight forward. As described
|
||||
The extension to other DFT codes is straightforward. As described
|
||||
here, one needs to implement the correlated density matrix to be used
|
||||
for the calculation of the charge density. This implementation will of
|
||||
course depend on the DFT package, and might be easy to do or a quite
|
||||
|
@ -1,167 +0,0 @@
|
||||
.. _plovasp:
|
||||
|
||||
PLOVasp
|
||||
=======
|
||||
|
||||
The general purpose of the PLOVasp tool is to transform raw, non-normalized
|
||||
projectors generated by VASP into normalized projectors corresponding to
|
||||
user-defined projected localized orbitals (PLO). The PLOs can then be used for
|
||||
DFT+DMFT calculations with or without charge self-consistency. PLOVasp also
|
||||
provides some utilities for basic analysis of the generated projectors, such as
|
||||
outputting density matrices, local Hamiltonians, and projected density of
|
||||
states.
|
||||
|
||||
PLOs are determined by the energy window in which the raw projectors are
|
||||
normalized. This allows to define either atomic-like strongly localized Wannier
|
||||
functions (large energy window) or extended Wannier functions focusing on
|
||||
selected low-energy states (small energy window).
|
||||
|
||||
In PLOVasp, all projectors sharing the same energy window are combined into a
|
||||
`projector group`. Technically, this allows one to define several groups with
|
||||
different energy windows for the same set of raw projectors. Note, however,
|
||||
that DFTtools does not support projector groups at the moment but this feature
|
||||
might appear in future releases.
|
||||
|
||||
A set of projectors defined on sites related to each other either by symmetry
|
||||
or by an atomic sort, along with a set of :math:`l`, :math:`m` quantum numbers,
|
||||
forms a `projector shell`. There could be several projectors shells in a
|
||||
projector group, implying that they will be normalized within the same energy
|
||||
window.
|
||||
|
||||
Projector shells and groups are specified by a user-defined input file whose
|
||||
format is described below.
|
||||
|
||||
Input file format
|
||||
-----------------
|
||||
|
||||
The input file is written in the standard config-file format.
|
||||
Parameters (or 'options') are grouped into sections specified as
|
||||
`[Section name]`. All parameters must be defined inside some section.
|
||||
|
||||
A PLOVasp input file can contain three types of sections:
|
||||
|
||||
#. **[General]**: includes parameters that are independent
|
||||
of a particular projector set, such as the Fermi level, additional
|
||||
output (e.g. the density of states), etc.
|
||||
#. **[Group <Ng>]**: describes projector groups, i.e. a set of
|
||||
projectors sharing the same energy window and normalization type.
|
||||
At the moment, DFTtools support only one projector group, therefore
|
||||
there should be no more than one projector group.
|
||||
#. **[Shell <Ns>]**: contains parameters of a projector shell labelled
|
||||
with `<Ns>`. If there is only one group section and one shell section,
|
||||
the group section can be omitted but in this case, the group required
|
||||
parameters must be provided inside the shell section.
|
||||
|
||||
Section [General]
|
||||
"""""""""""""""""
|
||||
|
||||
The entire section is optional and it contains three parameters:
|
||||
|
||||
* **BASENAME** (string): provides a base name for output files.
|
||||
Default filenames are :file:`vasp.*`.
|
||||
* **DOSMESH** ([float float] integer): if this parameter is given,
|
||||
the projected density of states for each projected orbital will be
|
||||
evaluated and stored to files :file:`pdos_<n>.dat`, where `n` is the
|
||||
orbital index. The energy
|
||||
mesh is defined by three numbers: `EMIN` `EMAX` `NPOINTS`. The first two
|
||||
can be omitted in which case they are taken to be equal to the projector
|
||||
energy window. **Important note**: at the moment this option works
|
||||
only if the tetrahedron integration method (`ISMEAR = -4` or `-5`)
|
||||
is used in VASP to produce `LOCPROJ`.
|
||||
* **EFERMI** (float): provides the Fermi level. This value overrides
|
||||
the one extracted from VASP output files.
|
||||
|
||||
There are no required parameters in this section.
|
||||
|
||||
Section [Shell]
|
||||
"""""""""""""""
|
||||
|
||||
This section specifies a projector shell. Each `[Shell]` section must be
|
||||
labeled by an index, e.g. `[Shell 1]`. These indices can then be referenced
|
||||
in a `[Group]` section.
|
||||
|
||||
In each `[Shell]` section two parameters are required:
|
||||
|
||||
* **IONS** (list of integer): indices of sites included in the shell.
|
||||
The sites can be given either by a list of integers `IONS = 5 6 7 8`
|
||||
or by a range `IONS = 5..8`. The site indices must be compatible with
|
||||
the POSCAR file.
|
||||
* **LSHELL** (integer): :math:`l` quantum number of the desired local states.
|
||||
|
||||
It is important that a given combination of site indices and local states
|
||||
given by `LSHELL` must be present in the LOCPROJ file.
|
||||
|
||||
There are additional optional parameters that allow one to transform
|
||||
the local states:
|
||||
|
||||
* **TRANSFORM** (matrix): local transformation matrix applied to all states
|
||||
in the projector shell. The matrix is defined by a (multiline) block
|
||||
of floats, with each line corresponding to a row. The number of columns
|
||||
must be equal to :math:`2 l + 1`, with :math:`l` given by `LSHELL`. Only real matrices
|
||||
are allowed. This parameter can be useful to select certain subset of
|
||||
orbitals or perform a simple global rotation.
|
||||
* **TRANSFILE** (string): name of the file containing transformation
|
||||
matrices for each site. This option allows for a full-fledged functionality
|
||||
when it comes to local state transformations. The format of this file
|
||||
is described :ref:`below <transformation_file>`.
|
||||
|
||||
Section [Group]
|
||||
"""""""""""""""
|
||||
|
||||
Each defined projector shell must be part of a projector group. In the current
|
||||
implementation of DFTtools only a single group (labelled by any integer, e.g. `[Group 1]`)
|
||||
is supported. This implies that all projector shells
|
||||
must be included in this group.
|
||||
|
||||
Required parameters for any group are the following:
|
||||
|
||||
* **SHELLS** (list of integers): indices of projector shells included in the group.
|
||||
All defined shells must be grouped.
|
||||
* **EWINDOW** (float float): the energy window specified by two floats: bottom
|
||||
and top. All projectors in the current group are going to be normalized within
|
||||
this window. *Note*: This option must be specified inside the `[Shell]` section
|
||||
if only one shell is defined and the `[Group]` section is omitted.
|
||||
|
||||
Optional group parameters:
|
||||
|
||||
* **NORMALIZE** (True/False): specifies whether projectors in the group are
|
||||
to be normalized. The default value is **True**.
|
||||
* **NORMION** (True/False): specifies whether projectors are normalized on
|
||||
a per-site (per-ion) basis. That is, if `NORMION = True`, the orthogonality
|
||||
condition will be enforced on each site separately but the Wannier functions
|
||||
on different sites will not be orthogonal. If `NORMION = False`, the Wannier functions
|
||||
on different sites included in the group will be orthogonal to each other.
|
||||
|
||||
|
||||
.. _transformation_file:
|
||||
|
||||
File of transformation matrices
|
||||
"""""""""""""""""""""""""""""""
|
||||
|
||||
.. warning::
|
||||
The description below applies only to collinear cases (i.e., without spin-orbit
|
||||
coupling). In this case, the matrices are spin-independent.
|
||||
|
||||
The file specified by option `TRANSFILE` contains transformation matrices
|
||||
for each ion. Each line must contain a series of floats whose number is either equal to
|
||||
the number of orbitals :math:`N_{orb}` (in this case the transformation matrices
|
||||
are assumed to be real) or to :math:`2 N_{orb}` (for the complex transformation matrices).
|
||||
The total number of lines :math:`N` must be a multiple of the number of ions :math:`N_{ion}`
|
||||
and the ratio :math:`N / N_{ion}`, then, gives the dimension of the transformed
|
||||
orbital space. The lines with floats can be separated by any number of empty or
|
||||
comment lines (starting from `#`), which are ignored.
|
||||
|
||||
A very simple example is a transformation matrix that selects the :math:`t_{2g}` manifold.
|
||||
For two correlated sites, one can define the file as follows:
|
||||
::
|
||||
|
||||
# Site 1
|
||||
1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
||||
0.0 0.0 0.0 1.0 0.0
|
||||
|
||||
# Site 2
|
||||
1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
||||
0.0 0.0 0.0 1.0 0.0
|
||||
|
@ -22,6 +22,42 @@ Wannier90 Converter
|
||||
:members:
|
||||
:special-members:
|
||||
|
||||
PLOVASP
|
||||
----------
|
||||
.. _refPLOVASP:
|
||||
|
||||
PLOVASP reference, the classes / functions are sorted the way the converter uses them.
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.converter
|
||||
:members: generate_and_output_as_text
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.inpconf
|
||||
:members: ConfigParameters
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.vaspio
|
||||
:members: VaspData, Plocar, Poscar, Kpoints, Eigenval, Doscar, read_symmcar
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.elstruct
|
||||
:members: ElectronicStructure
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.plotools
|
||||
:members:
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.proj_shell
|
||||
:members:
|
||||
|
||||
.. automodule:: triqs_dft_tools.converters.plovasp.proj_group
|
||||
:members:
|
||||
|
||||
|
||||
VASP Converter
|
||||
-------------------
|
||||
.. _refVASPconverter:
|
||||
.. autoclass:: triqs_dft_tools.converters.vasp_converter.VaspConverter
|
||||
:members:
|
||||
:special-members:
|
||||
|
||||
|
||||
Converter Tools
|
||||
---------------
|
||||
.. autoclass:: triqs_dft_tools.converters.converter_tools.ConverterTools
|
||||
|
@ -23,3 +23,22 @@ Full charge self consistency with Wien2k: :math:`\gamma`-Ce
|
||||
|
||||
tutorials/ce-gamma-fscs_wien2k
|
||||
|
||||
VASP interface examples
|
||||
-----------------------
|
||||
|
||||
Simple Converter example: SrVO3
|
||||
"""""""""""""""""""""""""""""""
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
tutorials/svo_vasp/svo_notebook
|
||||
|
||||
Complex example: NiO
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
tutorials/nio_csc
|
||||
|
18
doc/tutorials/images_scripts/INCAR
Normal file
18
doc/tutorials/images_scripts/INCAR
Normal file
@ -0,0 +1,18 @@
|
||||
System = NiO
|
||||
|
||||
ISMEAR = -5
|
||||
|
||||
# the energy window to optimize projector channels
|
||||
EMIN = -3
|
||||
EMAX = 7
|
||||
|
||||
NBANDS = 16
|
||||
LMAXMIX = 6
|
||||
|
||||
# switch off all symmetries
|
||||
ISYM = -1
|
||||
|
||||
# project to Ni d and O p states
|
||||
LORBIT = 14
|
||||
LOCPROJ = 1 : d : Pr 1
|
||||
LOCPROJ = 2 : p : Pr 1
|
7
doc/tutorials/images_scripts/INCAR.rst
Normal file
7
doc/tutorials/images_scripts/INCAR.rst
Normal file
@ -0,0 +1,7 @@
|
||||
.. _INCAR:
|
||||
|
||||
INCAR
|
||||
-----------
|
||||
|
||||
.. literalinclude:: INCAR
|
||||
:language: bash
|
4
doc/tutorials/images_scripts/KPOINTS
Normal file
4
doc/tutorials/images_scripts/KPOINTS
Normal file
@ -0,0 +1,4 @@
|
||||
Automatically generated mesh
|
||||
0
|
||||
Gamma
|
||||
6 6 6
|
7
doc/tutorials/images_scripts/KPOINTS.rst
Normal file
7
doc/tutorials/images_scripts/KPOINTS.rst
Normal file
@ -0,0 +1,7 @@
|
||||
.. _KPOINTS:
|
||||
|
||||
KPOINTS
|
||||
-----------
|
||||
|
||||
.. literalinclude:: KPOINTS
|
||||
:language: bash
|
90
doc/tutorials/images_scripts/NiO_local_lattice_GF.py
Normal file
90
doc/tutorials/images_scripts/NiO_local_lattice_GF.py
Normal file
@ -0,0 +1,90 @@
|
||||
from itertools import *
|
||||
import numpy as np
|
||||
import pytriqs.utility.mpi as mpi
|
||||
from pytriqs.archive import *
|
||||
from pytriqs.gf import *
|
||||
from triqs_dft_tools.sumk_dft import *
|
||||
from triqs_dft_tools.sumk_dft_tools import *
|
||||
from pytriqs.operators.util.hamiltonians import *
|
||||
from pytriqs.operators.util.U_matrix import *
|
||||
from triqs_cthyb import *
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore", category=FutureWarning)
|
||||
|
||||
filename = 'nio'
|
||||
SK = SumkDFT(hdf_file = filename+'.h5', use_dft_blocks = False)
|
||||
|
||||
beta = 5.0
|
||||
|
||||
# We analyze the block structure of the Hamiltonian
|
||||
Sigma = SK.block_structure.create_gf(beta=beta)
|
||||
|
||||
SK.put_Sigma([Sigma])
|
||||
G = SK.extract_G_loc()
|
||||
SK.analyse_block_structure_from_gf(G, threshold = 1e-3)
|
||||
|
||||
|
||||
# Setup CTQMC Solver
|
||||
n_orb = SK.corr_shells[0]['dim']
|
||||
spin_names = ['up','down']
|
||||
orb_names = [i for i in range(0,n_orb)]
|
||||
|
||||
|
||||
# Print some information on the master node
|
||||
iteration_offset = 0
|
||||
Sigma_iw = 0
|
||||
if mpi.is_master_node():
|
||||
ar = HDFArchive(filename+'.h5','a')
|
||||
if not 'DMFT_results' in ar: ar.create_group('DMFT_results')
|
||||
if not 'Iterations' in ar['DMFT_results']: ar['DMFT_results'].create_group('Iterations')
|
||||
if 'iteration_count' in ar['DMFT_results']:
|
||||
iteration_offset = ar['DMFT_results']['iteration_count']+1
|
||||
print('offset',iteration_offset)
|
||||
Sigma_iw = ar['DMFT_results']['Iterations']['Sigma_it'+str(iteration_offset-1)]
|
||||
SK.dc_imp = ar['DMFT_results']['Iterations']['dc_imp'+str(iteration_offset-1)]
|
||||
SK.dc_energ = ar['DMFT_results']['Iterations']['dc_energ'+str(iteration_offset-1)]
|
||||
SK.chemical_potential = ar['DMFT_results']['Iterations']['chemical_potential'+str(iteration_offset-1)].real
|
||||
|
||||
iteration_offset = mpi.bcast(iteration_offset)
|
||||
Sigma_iw = mpi.bcast(Sigma_iw)
|
||||
SK.dc_imp = mpi.bcast(SK.dc_imp)
|
||||
SK.dc_energ = mpi.bcast(SK.dc_energ)
|
||||
SK.chemical_potential = mpi.bcast(SK.chemical_potential)
|
||||
|
||||
|
||||
SK.put_Sigma(Sigma_imp = [Sigma_iw])
|
||||
|
||||
ikarray = numpy.array(range(SK.n_k))
|
||||
|
||||
# set up the orbitally resolved local lattice greens function:
|
||||
n_orbs = SK.proj_mat_csc.shape[2]
|
||||
spn = SK.spin_block_names[SK.SO]
|
||||
mesh = Sigma_iw.mesh
|
||||
block_structure = [range(n_orbs) for sp in spn]
|
||||
gf_struct = [(spn[isp], block_structure[isp])
|
||||
for isp in range(SK.n_spin_blocks[SK.SO])]
|
||||
block_ind_list = [block for block, inner in gf_struct]
|
||||
glist = lambda: [GfImFreq(indices=inner, mesh=mesh)
|
||||
for block, inner in gf_struct]
|
||||
|
||||
G_latt_orb = BlockGf(name_list=block_ind_list,
|
||||
block_list=glist(), make_copies=False)
|
||||
G_latt_orb.zero()
|
||||
|
||||
for ik in mpi.slice_array(ikarray):
|
||||
G_latt_KS = SK.lattice_gf(ik=ik, beta=beta)
|
||||
G_latt_KS *= SK.bz_weights[ik]
|
||||
for bname, gf in G_latt_orb:
|
||||
add_g_ik = gf.copy()
|
||||
add_g_ik.zero()
|
||||
add_g_ik << SK.downfold(ik, 0, bname, G_latt_KS[bname], gf, shells='csc', ir=None)
|
||||
gf << gf + add_g_ik
|
||||
|
||||
G_latt_orb << mpi.all_reduce(
|
||||
mpi.world, G_latt_orb, lambda x, y: x + y)
|
||||
|
||||
mpi.barrier()
|
||||
|
||||
if mpi.is_master_node():
|
||||
ar['DMFT_results']['Iterations']['G_latt_orb_it'+str(iteration_offset-1)] = G_latt_orb
|
||||
if mpi.is_master_node(): del ar
|
9
doc/tutorials/images_scripts/NiO_local_lattice_GF.py.rst
Normal file
9
doc/tutorials/images_scripts/NiO_local_lattice_GF.py.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. _NiO_local_lattice_GF.py:
|
||||
|
||||
NiO_local_lattice_GF.py
|
||||
-----------
|
||||
|
||||
Download :download:`NiO_local_lattice_GF.py <./NiO_local_lattice_GF.py>`.
|
||||
|
||||
.. literalinclude:: NiO_local_lattice_GF.py
|
||||
:language: python
|
10
doc/tutorials/images_scripts/POSCAR
Normal file
10
doc/tutorials/images_scripts/POSCAR
Normal file
@ -0,0 +1,10 @@
|
||||
NiO
|
||||
4.17 #taken from 9x9x9 with sigma=0.2 ismear=2
|
||||
+0.0000000000 +0.5000000000 +0.5000000000
|
||||
+0.5000000000 +0.0000000000 +0.5000000000
|
||||
+0.5000000000 +0.5000000000 +0.0000000000
|
||||
Ni O
|
||||
1 1
|
||||
Direct
|
||||
+0.0000000000 +0.0000000000 +0.0000000000
|
||||
+0.5000000000 +0.5000000000 +0.5000000000
|
7
doc/tutorials/images_scripts/POSCAR.rst
Normal file
7
doc/tutorials/images_scripts/POSCAR.rst
Normal file
@ -0,0 +1,7 @@
|
||||
.. _POSCAR:
|
||||
|
||||
POSCAR
|
||||
-----------
|
||||
|
||||
.. literalinclude:: POSCAR
|
||||
:language: bash
|
3
doc/tutorials/images_scripts/converter.py
Normal file
3
doc/tutorials/images_scripts/converter.py
Normal file
@ -0,0 +1,3 @@
|
||||
from triqs_dft_tools.converters.vasp_converter import *
|
||||
Converter = VaspConverter(filename = 'nio')
|
||||
Converter.convert_dft_input()
|
10
doc/tutorials/images_scripts/converter.py.rst
Normal file
10
doc/tutorials/images_scripts/converter.py.rst
Normal file
@ -0,0 +1,10 @@
|
||||
.. _converter.py:
|
||||
|
||||
converter.py
|
||||
-------------------
|
||||
|
||||
Download :download:`converter.py <./converter.py>`.
|
||||
|
||||
|
||||
.. literalinclude:: converter.py
|
||||
:language: python
|
51
doc/tutorials/images_scripts/maxent.py
Normal file
51
doc/tutorials/images_scripts/maxent.py
Normal file
@ -0,0 +1,51 @@
|
||||
from pytriqs.gf import *
|
||||
from pytriqs.archive import *
|
||||
from triqs_maxent import *
|
||||
|
||||
filename = 'nio'
|
||||
|
||||
ar = HDFArchive(filename+'.h5','a')
|
||||
if 'iteration_count' in ar['DMFT_results']:
|
||||
iteration_offset = ar['DMFT_results']['iteration_count']+1
|
||||
G_latt = ar['DMFT_results']['Iterations']['G_latt_orb_it'+str(iteration_offset-1)]
|
||||
|
||||
|
||||
tm = TauMaxEnt(cost_function='bryan', probability='normal')
|
||||
|
||||
print(G_latt['up'][0,0])
|
||||
t2g_orbs = [0,1,3]
|
||||
eg_orbs = [2,4]
|
||||
op_orbs = [5,6,7]
|
||||
|
||||
orbs = [t2g_orbs, eg_orbs, op_orbs]
|
||||
#orbs = [t2g_orbs]
|
||||
|
||||
for orb in orbs:
|
||||
|
||||
print '\n'+str(orb[0])+'\n'
|
||||
|
||||
gf = 0*G_latt['up'][0,0]
|
||||
for iO in orb:
|
||||
gf = gf + G_latt['up'][iO,iO]
|
||||
tm.set_G_iw(gf)
|
||||
tm.omega =LinearOmegaMesh(omega_min=-20, omega_max=20, n_points=201)
|
||||
tm.alpha_mesh = LogAlphaMesh(alpha_min=0.01, alpha_max=20000, n_points=60)
|
||||
|
||||
tm.set_error(1.e-3)
|
||||
result=tm.run()
|
||||
result.get_A_out('LineFitAnalyzer')
|
||||
|
||||
if 'iteration_count' in ar['DMFT_results']:
|
||||
iteration_offset = ar['DMFT_results']['iteration_count']+1
|
||||
for oo in orb:
|
||||
ar['DMFT_results']['Iterations']['G_latt_orb_w_o'+str(oo)+'_it'+str(iteration_offset-1)] = result.analyzer_results['LineFitAnalyzer']['A_out']
|
||||
ar['DMFT_results']['Iterations']['w_it'+str(iteration_offset-1)] = result.omega
|
||||
|
||||
|
||||
# you may be interested in the details of the line analyzer:
|
||||
# from pytriqs.plot.mpl_interface import oplot
|
||||
#plt.figure(2)
|
||||
#result.analyzer_results['LineFitAnalyzer'].plot_linefit()
|
||||
#plt.savefig('ana'+str(orb[0])+'.pdf',fmt='pdf')
|
||||
|
||||
del ar
|
9
doc/tutorials/images_scripts/maxent.py.rst
Normal file
9
doc/tutorials/images_scripts/maxent.py.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. _maxent.py:
|
||||
|
||||
maxent.py
|
||||
-----------
|
||||
|
||||
Download :download:`maxent.py <./maxent.py>`.
|
||||
|
||||
.. literalinclude:: maxent.py
|
||||
:language: python
|
167
doc/tutorials/images_scripts/nio.py
Normal file
167
doc/tutorials/images_scripts/nio.py
Normal file
@ -0,0 +1,167 @@
|
||||
from itertools import *
|
||||
import numpy as np
|
||||
import pytriqs.utility.mpi as mpi
|
||||
from pytriqs.archive import *
|
||||
from pytriqs.gf import *
|
||||
import sys, pytriqs.version as triqs_version
|
||||
from triqs_dft_tools.sumk_dft import *
|
||||
from triqs_dft_tools.sumk_dft_tools import *
|
||||
from pytriqs.operators.util.hamiltonians import *
|
||||
from pytriqs.operators.util.U_matrix import *
|
||||
from triqs_cthyb import *
|
||||
import triqs_cthyb.version as cthyb_version
|
||||
import triqs_dft_tools.version as dft_tools_version
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore", category=FutureWarning)
|
||||
|
||||
filename = 'nio'
|
||||
|
||||
SK = SumkDFT(hdf_file = filename+'.h5', use_dft_blocks = False)
|
||||
|
||||
beta = 5.0
|
||||
|
||||
Sigma = SK.block_structure.create_gf(beta=beta)
|
||||
SK.put_Sigma([Sigma])
|
||||
G = SK.extract_G_loc()
|
||||
SK.analyse_block_structure_from_gf(G, threshold = 1e-3)
|
||||
for i_sh in range(len(SK.deg_shells)):
|
||||
num_block_deg_orbs = len(SK.deg_shells[i_sh])
|
||||
mpi.report('found {0:d} blocks of degenerate orbitals in shell {1:d}'.format(num_block_deg_orbs, i_sh))
|
||||
for iblock in range(num_block_deg_orbs):
|
||||
mpi.report('block {0:d} consists of orbitals:'.format(iblock))
|
||||
for keys in SK.deg_shells[i_sh][iblock].keys():
|
||||
mpi.report(' '+keys)
|
||||
|
||||
# Setup CTQMC Solver
|
||||
|
||||
n_orb = SK.corr_shells[0]['dim']
|
||||
spin_names = ['up','down']
|
||||
orb_names = [i for i in range(0,n_orb)]
|
||||
|
||||
#gf_struct = set_operator_structure(spin_names, orb_names, orb_hyb)
|
||||
gf_struct = SK.gf_struct_solver[0]
|
||||
mpi.report('Sumk to Solver: %s'%SK.sumk_to_solver)
|
||||
mpi.report('GF struct sumk: %s'%SK.gf_struct_sumk)
|
||||
mpi.report('GF struct solver: %s'%SK.gf_struct_solver)
|
||||
|
||||
S = Solver(beta=beta, gf_struct=gf_struct)
|
||||
|
||||
# Construct the Hamiltonian and save it in Hamiltonian_store.txt
|
||||
H = Operator()
|
||||
U = 8.0
|
||||
J = 1.0
|
||||
|
||||
|
||||
U_sph = U_matrix(l=2, U_int=U, J_hund=J)
|
||||
U_cubic = transform_U_matrix(U_sph, spherical_to_cubic(l=2, convention=''))
|
||||
Umat, Upmat = reduce_4index_to_2index(U_cubic)
|
||||
|
||||
H = h_int_density(spin_names, orb_names, map_operator_structure=SK.sumk_to_solver[0], U=Umat, Uprime=Upmat)
|
||||
|
||||
# Print some information on the master node
|
||||
mpi.report('Greens function structure is: %s '%gf_struct)
|
||||
mpi.report('U Matrix set to:\n%s'%Umat)
|
||||
mpi.report('Up Matrix set to:\n%s'%Upmat)
|
||||
|
||||
# Parameters for the CTQMC Solver
|
||||
p = {}
|
||||
p["max_time"] = -1
|
||||
p["random_name"] = ""
|
||||
p["random_seed"] = 123 * mpi.rank + 567
|
||||
p["length_cycle"] = 100
|
||||
p["n_warmup_cycles"] = 20000
|
||||
p["n_cycles"] = 200000
|
||||
p["fit_max_moment"] = 4
|
||||
p["fit_min_n"] = 30
|
||||
p["fit_max_n"] = 50
|
||||
p["perform_tail_fit"] = True
|
||||
|
||||
# Double Counting: 0 FLL, 1 Held, 2 AMF
|
||||
DC_type = 0
|
||||
DC_value = 59.0
|
||||
|
||||
# Prepare hdf file and and check for previous iterations
|
||||
n_iterations = 10
|
||||
|
||||
iteration_offset = 0
|
||||
if mpi.is_master_node():
|
||||
ar = HDFArchive(filename+'.h5','a')
|
||||
if not 'DMFT_results' in ar: ar.create_group('DMFT_results')
|
||||
if not 'Iterations' in ar['DMFT_results']: ar['DMFT_results'].create_group('Iterations')
|
||||
if not 'DMFT_input' in ar: ar.create_group('DMFT_input')
|
||||
if not 'Iterations' in ar['DMFT_input']: ar['DMFT_input'].create_group('Iterations')
|
||||
if not 'code_versions' in ar['DMFT_input']: ar['DMFT_input'].create_group('code_versio\
|
||||
ns')
|
||||
ar['DMFT_input']['code_versions']["triqs_version"] = triqs_version.version
|
||||
ar['DMFT_input']['code_versions']["triqs_git"] = triqs_version.git_hash
|
||||
ar['DMFT_input']['code_versions']["cthyb_version"] = cthyb_version.version
|
||||
ar['DMFT_input']['code_versions']["cthyb_git"] = cthyb_version.cthyb_hash
|
||||
ar['DMFT_input']['code_versions']["dft_tools_version"] = dft_tools_version.version
|
||||
ar['DMFT_input']['code_versions']["dft_tools_version"] = dft_tools_version.dft_tools_hash
|
||||
if 'iteration_count' in ar['DMFT_results']:
|
||||
iteration_offset = ar['DMFT_results']['iteration_count']+1
|
||||
S.Sigma_iw = ar['DMFT_results']['Iterations']['Sigma_it'+str(iteration_offset-1)]
|
||||
SK.dc_imp = ar['DMFT_results']['Iterations']['dc_imp'+str(iteration_offset-1)]
|
||||
SK.dc_energ = ar['DMFT_results']['Iterations']['dc_energ'+str(iteration_offset-1)]
|
||||
SK.chemical_potential = ar['DMFT_results']['Iterations']['chemical_potential'+str(iteration_offset-1)].real
|
||||
ar['DMFT_input']["dmft_script_it"+str(iteration_offset)] = open(sys.argv[0]).read()
|
||||
iteration_offset = mpi.bcast(iteration_offset)
|
||||
S.Sigma_iw = mpi.bcast(S.Sigma_iw)
|
||||
SK.dc_imp = mpi.bcast(SK.dc_imp)
|
||||
SK.dc_energ = mpi.bcast(SK.dc_energ)
|
||||
SK.chemical_potential = mpi.bcast(SK.chemical_potential)
|
||||
|
||||
# Calc the first G0
|
||||
SK.symm_deg_gf(S.Sigma_iw,orb=0)
|
||||
SK.put_Sigma(Sigma_imp = [S.Sigma_iw])
|
||||
SK.calc_mu(precision=0.01)
|
||||
S.G_iw << SK.extract_G_loc()[0]
|
||||
SK.symm_deg_gf(S.G_iw, orb=0)
|
||||
|
||||
#Init the DC term and the self-energy if no previous iteration was found
|
||||
if iteration_offset == 0:
|
||||
dm = S.G_iw.density()
|
||||
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
|
||||
S.Sigma_iw << SK.dc_imp[0]['up'][0,0]
|
||||
|
||||
mpi.report('%s DMFT cycles requested. Starting with iteration %s.'%(n_iterations,iteration_offset))
|
||||
|
||||
# The infamous DMFT self consistency cycle
|
||||
for it in range(iteration_offset, iteration_offset + n_iterations):
|
||||
|
||||
mpi.report('Doing iteration: %s'%it)
|
||||
|
||||
# Get G0
|
||||
S.G0_iw << inverse(S.Sigma_iw + inverse(S.G_iw))
|
||||
# Solve the impurity problem
|
||||
S.solve(h_int = H, **p)
|
||||
if mpi.is_master_node():
|
||||
ar['DMFT_input']['Iterations']['solver_dict_it'+str(it)] = p
|
||||
ar['DMFT_results']['Iterations']['Gimp_it'+str(it)] = S.G_iw
|
||||
ar['DMFT_results']['Iterations']['Gtau_it'+str(it)] = S.G_tau
|
||||
ar['DMFT_results']['Iterations']['Sigma_uns_it'+str(it)] = S.Sigma_iw
|
||||
# Calculate double counting
|
||||
dm = S.G_iw.density()
|
||||
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
|
||||
# Get new G
|
||||
SK.symm_deg_gf(S.Sigma_iw,orb=0)
|
||||
SK.put_Sigma(Sigma_imp=[S.Sigma_iw])
|
||||
SK.calc_mu(precision=0.01)
|
||||
S.G_iw << SK.extract_G_loc()[0]
|
||||
|
||||
# print densities
|
||||
for sig,gf in S.G_iw:
|
||||
mpi.report("Orbital %s density: %.6f"%(sig,dm[sig][0,0]))
|
||||
mpi.report('Total charge of Gloc : %.6f'%S.G_iw.total_density())
|
||||
|
||||
if mpi.is_master_node():
|
||||
ar['DMFT_results']['iteration_count'] = it
|
||||
ar['DMFT_results']['Iterations']['Sigma_it'+str(it)] = S.Sigma_iw
|
||||
ar['DMFT_results']['Iterations']['Gloc_it'+str(it)] = S.G_iw
|
||||
ar['DMFT_results']['Iterations']['G0loc_it'+str(it)] = S.G0_iw
|
||||
ar['DMFT_results']['Iterations']['dc_imp'+str(it)] = SK.dc_imp
|
||||
ar['DMFT_results']['Iterations']['dc_energ'+str(it)] = SK.dc_energ
|
||||
ar['DMFT_results']['Iterations']['chemical_potential'+str(it)] = SK.chemical_potential
|
||||
|
||||
if mpi.is_master_node(): del ar
|
9
doc/tutorials/images_scripts/nio.py.rst
Normal file
9
doc/tutorials/images_scripts/nio.py.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. _nio.py:
|
||||
|
||||
nio.py
|
||||
-----------
|
||||
|
||||
Download :download:`nio.py <./nio.py>`.
|
||||
|
||||
.. literalinclude:: nio.py
|
||||
:language: python
|
BIN
doc/tutorials/images_scripts/nio_Aw.png
Normal file
BIN
doc/tutorials/images_scripts/nio_Aw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
201
doc/tutorials/images_scripts/nio_csc.py
Normal file
201
doc/tutorials/images_scripts/nio_csc.py
Normal file
@ -0,0 +1,201 @@
|
||||
from itertools import *
|
||||
import numpy as np
|
||||
import pytriqs.utility.mpi as mpi
|
||||
from pytriqs.archive import *
|
||||
from pytriqs.gf import *
|
||||
import sys, pytriqs.version as triqs_version
|
||||
from triqs_dft_tools.sumk_dft import *
|
||||
from triqs_dft_tools.sumk_dft_tools import *
|
||||
from pytriqs.operators.util.hamiltonians import *
|
||||
from pytriqs.operators.util.U_matrix import *
|
||||
from triqs_cthyb import *
|
||||
import triqs_cthyb.version as cthyb_version
|
||||
import triqs_dft_tools.version as dft_tools_version
|
||||
from triqs_dft_tools.converters.vasp_converter import *
|
||||
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore", category=FutureWarning)
|
||||
|
||||
|
||||
def dmft_cycle():
|
||||
filename = 'nio'
|
||||
|
||||
Converter = VaspConverter(filename=filename)
|
||||
Converter.convert_dft_input()
|
||||
|
||||
SK = SumkDFT(hdf_file = filename+'.h5', use_dft_blocks = False)
|
||||
|
||||
beta = 5.0
|
||||
|
||||
Sigma = SK.block_structure.create_gf(beta=beta)
|
||||
SK.put_Sigma([Sigma])
|
||||
G = SK.extract_G_loc()
|
||||
SK.analyse_block_structure_from_gf(G, threshold = 1e-2)
|
||||
for i_sh in range(len(SK.deg_shells)):
|
||||
num_block_deg_orbs = len(SK.deg_shells[i_sh])
|
||||
mpi.report('found {0:d} blocks of degenerate orbitals in shell {1:d}'.format(num_block_deg_orbs, i_sh))
|
||||
for iblock in range(num_block_deg_orbs):
|
||||
mpi.report('block {0:d} consists of orbitals:'.format(iblock))
|
||||
for keys in SK.deg_shells[i_sh][iblock].keys():
|
||||
mpi.report(' '+keys)
|
||||
|
||||
# Setup CTQMC Solver
|
||||
|
||||
n_orb = SK.corr_shells[0]['dim']
|
||||
spin_names = ['up','down']
|
||||
orb_names = [i for i in range(0,n_orb)]
|
||||
|
||||
#gf_struct = set_operator_structure(spin_names, orb_names, orb_hyb)
|
||||
gf_struct = SK.gf_struct_solver[0]
|
||||
mpi.report('Sumk to Solver: %s'%SK.sumk_to_solver)
|
||||
mpi.report('GF struct sumk: %s'%SK.gf_struct_sumk)
|
||||
mpi.report('GF struct solver: %s'%SK.gf_struct_solver)
|
||||
|
||||
S = Solver(beta=beta, gf_struct=gf_struct)
|
||||
|
||||
# Construct the Hamiltonian and save it in Hamiltonian_store.txt
|
||||
H = Operator()
|
||||
U = 8.0
|
||||
J = 1.0
|
||||
|
||||
|
||||
U_sph = U_matrix(l=2, U_int=U, J_hund=J)
|
||||
U_cubic = transform_U_matrix(U_sph, spherical_to_cubic(l=2, convention=''))
|
||||
Umat, Upmat = reduce_4index_to_2index(U_cubic)
|
||||
|
||||
H = h_int_density(spin_names, orb_names, map_operator_structure=SK.sumk_to_solver[0], U=Umat, Uprime=Upmat)
|
||||
|
||||
# Print some information on the master node
|
||||
mpi.report('Greens function structure is: %s '%gf_struct)
|
||||
mpi.report('U Matrix set to:\n%s'%Umat)
|
||||
mpi.report('Up Matrix set to:\n%s'%Upmat)
|
||||
|
||||
# Parameters for the CTQMC Solver
|
||||
p = {}
|
||||
p["max_time"] = -1
|
||||
p["random_name"] = ""
|
||||
p["random_seed"] = 123 * mpi.rank + 567
|
||||
p["length_cycle"] = 100
|
||||
p["n_warmup_cycles"] = 2000
|
||||
p["n_cycles"] = 20000
|
||||
p["fit_max_moment"] = 4
|
||||
p["fit_min_n"] = 30
|
||||
p["fit_max_n"] = 50
|
||||
p["perform_tail_fit"] = True
|
||||
|
||||
# Double Counting: 0 FLL, 1 Held, 2 AMF
|
||||
DC_type = 0
|
||||
DC_value = 59.0
|
||||
|
||||
# Prepare hdf file and and check for previous iterations
|
||||
n_iterations = 1
|
||||
|
||||
iteration_offset = 0
|
||||
if mpi.is_master_node():
|
||||
ar = HDFArchive(filename+'.h5','a')
|
||||
if not 'DMFT_results' in ar: ar.create_group('DMFT_results')
|
||||
if not 'Iterations' in ar['DMFT_results']: ar['DMFT_results'].create_group('Iterations')
|
||||
if not 'DMFT_input' in ar: ar.create_group('DMFT_input')
|
||||
if not 'Iterations' in ar['DMFT_input']: ar['DMFT_input'].create_group('Iterations')
|
||||
if not 'code_versions' in ar['DMFT_input']: ar['DMFT_input'].create_group('code_versio\
|
||||
ns')
|
||||
ar['DMFT_input']['code_versions']["triqs_version"] = triqs_version.version
|
||||
ar['DMFT_input']['code_versions']["triqs_git"] = triqs_version.git_hash
|
||||
ar['DMFT_input']['code_versions']["cthyb_version"] = cthyb_version.version
|
||||
ar['DMFT_input']['code_versions']["cthyb_git"] = cthyb_version.cthyb_hash
|
||||
ar['DMFT_input']['code_versions']["dft_tools_version"] = dft_tools_version.version
|
||||
ar['DMFT_input']['code_versions']["dft_tools_git"] = dft_tools_version.dft_tools_hash
|
||||
if 'iteration_count' in ar['DMFT_results']:
|
||||
iteration_offset = ar['DMFT_results']['iteration_count']+1
|
||||
S.Sigma_iw = ar['DMFT_results']['Iterations']['Sigma_it'+str(iteration_offset-1)]
|
||||
SK.dc_imp = ar['DMFT_results']['Iterations']['dc_imp'+str(iteration_offset-1)]
|
||||
SK.dc_energ = ar['DMFT_results']['Iterations']['dc_energ'+str(iteration_offset-1)]
|
||||
SK.chemical_potential = ar['DMFT_results']['Iterations']['chemical_potential'+str(iteration_offset-1)].real
|
||||
ar['DMFT_input']["dmft_script_it"+str(iteration_offset)] = open(sys.argv[0]).read()
|
||||
iteration_offset = mpi.bcast(iteration_offset)
|
||||
S.Sigma_iw = mpi.bcast(S.Sigma_iw)
|
||||
SK.dc_imp = mpi.bcast(SK.dc_imp)
|
||||
SK.dc_energ = mpi.bcast(SK.dc_energ)
|
||||
SK.chemical_potential = mpi.bcast(SK.chemical_potential)
|
||||
|
||||
# Calc the first G0
|
||||
SK.symm_deg_gf(S.Sigma_iw,orb=0)
|
||||
SK.put_Sigma(Sigma_imp = [S.Sigma_iw])
|
||||
SK.calc_mu(precision=0.01)
|
||||
S.G_iw << SK.extract_G_loc()[0]
|
||||
SK.symm_deg_gf(S.G_iw, orb=0)
|
||||
|
||||
#Init the DC term and the self-energy if no previous iteration was found
|
||||
if iteration_offset == 0:
|
||||
dm = S.G_iw.density()
|
||||
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
|
||||
S.Sigma_iw << SK.dc_imp[0]['up'][0,0]
|
||||
|
||||
mpi.report('%s DMFT cycles requested. Starting with iteration %s.'%(n_iterations,iteration_offset))
|
||||
|
||||
|
||||
|
||||
# The infamous DMFT self consistency cycle
|
||||
for it in range(iteration_offset, iteration_offset + n_iterations):
|
||||
mpi.report('Doing iteration: %s'%it)
|
||||
|
||||
# Get G0
|
||||
S.G0_iw << inverse(S.Sigma_iw + inverse(S.G_iw))
|
||||
# Solve the impurity problem
|
||||
S.solve(h_int = H, **p)
|
||||
if mpi.is_master_node():
|
||||
ar['DMFT_input']['Iterations']['solver_dict_it'+str(it)] = p
|
||||
ar['DMFT_results']['Iterations']['Gimp_it'+str(it)] = S.G_iw
|
||||
ar['DMFT_results']['Iterations']['Gtau_it'+str(it)] = S.G_tau
|
||||
ar['DMFT_results']['Iterations']['Sigma_uns_it'+str(it)] = S.Sigma_iw
|
||||
# Calculate double counting
|
||||
dm = S.G_iw.density()
|
||||
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
|
||||
# Get new G
|
||||
SK.symm_deg_gf(S.Sigma_iw,orb=0)
|
||||
SK.put_Sigma(Sigma_imp=[S.Sigma_iw])
|
||||
SK.calc_mu(precision=0.01)
|
||||
S.G_iw << SK.extract_G_loc()[0]
|
||||
|
||||
# print densities
|
||||
for sig,gf in S.G_iw:
|
||||
mpi.report("Orbital %s density: %.6f"%(sig,dm[sig][0,0]))
|
||||
mpi.report('Total charge of Gloc : %.6f'%S.G_iw.total_density())
|
||||
|
||||
if mpi.is_master_node():
|
||||
ar['DMFT_results']['iteration_count'] = it
|
||||
ar['DMFT_results']['Iterations']['Sigma_it'+str(it)] = S.Sigma_iw
|
||||
ar['DMFT_results']['Iterations']['Gloc_it'+str(it)] = S.G_iw
|
||||
ar['DMFT_results']['Iterations']['G0loc_it'+str(it)] = S.G0_iw
|
||||
ar['DMFT_results']['Iterations']['dc_imp'+str(it)] = SK.dc_imp
|
||||
ar['DMFT_results']['Iterations']['dc_energ'+str(it)] = SK.dc_energ
|
||||
ar['DMFT_results']['Iterations']['chemical_potential'+str(it)] = SK.chemical_potential
|
||||
|
||||
|
||||
|
||||
|
||||
if mpi.is_master_node():
|
||||
print 'calculating mu...'
|
||||
SK.chemical_potential = SK.calc_mu( precision = 0.000001 )
|
||||
|
||||
if mpi.is_master_node():
|
||||
print 'calculating GAMMA'
|
||||
SK.calc_density_correction(dm_type='vasp')
|
||||
|
||||
if mpi.is_master_node():
|
||||
print 'calculating energy corrections'
|
||||
|
||||
correnerg = 0.5 * (S.G_iw * S.Sigma_iw).total_density()
|
||||
|
||||
dm = S.G_iw.density() # compute the density matrix of the impurity problem
|
||||
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
|
||||
dc_energ = SK.dc_energ[0]
|
||||
|
||||
if mpi.is_master_node():
|
||||
ar['DMFT_results']['Iterations']['corr_energy_it'+str(it)] = correnerg
|
||||
ar['DMFT_results']['Iterations']['dc_energy_it'+str(it)] = dc_energ
|
||||
|
||||
if mpi.is_master_node(): del ar
|
||||
|
||||
return correnerg, dc_energ
|
9
doc/tutorials/images_scripts/nio_csc.py.rst
Normal file
9
doc/tutorials/images_scripts/nio_csc.py.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. _nio_csc.py:
|
||||
|
||||
nio_csc.py
|
||||
-------------
|
||||
|
||||
Download :download:`nio_csc.py <./nio_csc.py>`.
|
||||
|
||||
.. literalinclude:: nio_csc.py
|
||||
:language: python
|
28
doc/tutorials/images_scripts/plo.cfg
Normal file
28
doc/tutorials/images_scripts/plo.cfg
Normal file
@ -0,0 +1,28 @@
|
||||
[General]
|
||||
BASENAME = nio
|
||||
DOSMESH = -21 55 400
|
||||
|
||||
[Group 1]
|
||||
SHELLS = 1 2
|
||||
EWINDOW = -9 2
|
||||
NORMION = False
|
||||
NORMALIZE = True
|
||||
BANDS = 2 10
|
||||
|
||||
[Shell 1] # Ni d shell
|
||||
LSHELL = 2
|
||||
IONS = 1
|
||||
CORR = True
|
||||
TRANSFORM = 1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
||||
0.0 0.0 1.0 0.0 0.0
|
||||
0.0 0.0 0.0 1.0 0.0
|
||||
0.0 0.0 0.0 0.0 1.0
|
||||
|
||||
[Shell 2] # O p shell
|
||||
LSHELL = 1
|
||||
IONS = 2
|
||||
CORR = False
|
||||
TRANSFORM = 1.0 0.0 0.0
|
||||
0.0 1.0 0.0
|
||||
0.0 0.0 1.0
|
9
doc/tutorials/images_scripts/plo.cfg.rst
Normal file
9
doc/tutorials/images_scripts/plo.cfg.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. _plo.cfg:
|
||||
|
||||
plo.cfg
|
||||
-----------
|
||||
|
||||
Download :download:`plo.cfg<./plo.cfg>`.
|
||||
|
||||
.. literalinclude:: plo.cfg
|
||||
:language: bash
|
102
doc/tutorials/nio_csc.rst
Normal file
102
doc/tutorials/nio_csc.rst
Normal file
@ -0,0 +1,102 @@
|
||||
.. _nio_csc:
|
||||
|
||||
DFT and projections
|
||||
==================================================
|
||||
|
||||
We will perform DFT+DMFT calcluations for the charge-transfer insulator NiO. We start from scratch and provide all necessary input files to do the calculations: First for doing a single-shot calculation.
|
||||
.. (and then for charge-selfconsistency).
|
||||
|
||||
VASP setup
|
||||
-------------------------------
|
||||
We start by running a simple VASP calculation to converge the charge density initially.
|
||||
Use the :ref:`INCAR`, :ref:`POSCAR`, and :ref:`KPOINTS` provided and use your
|
||||
own :file:`POTCAR` file.
|
||||
|
||||
Let us take a look in the :file:`INCAR`, where we have to specify local orbitals as basis
|
||||
for our many-body calculation.
|
||||
|
||||
.. literalinclude:: images_scripts/INCAR
|
||||
|
||||
`LORBIT = 14` takes care of optimizing the projectors in the energy window defined
|
||||
by `EMIN` and `EMAX`. We switch off all symmetries with `ISYM=-1` since symmetries
|
||||
are not implemented in the later DMFT scripts. Finally, we select the relevant orbitals
|
||||
for atom 1 (Ni, d-orbitals) and 2 (O, p-orbitals) by the two `LOCPROJ` lines.
|
||||
For details refer to the VASP wiki on the `LOCPROJ <https://cms.mpi.univi
|
||||
e.ac.at/wiki/index.php/LOCPROJ>`_ flag. The projectors are stored in the file `LOCPROJ`.
|
||||
|
||||
|
||||
PLOVASP
|
||||
------------------------------
|
||||
Next, we postprocess the projectors, which VASP stored in the file `LOCPROJ`.
|
||||
We do this by invoking :program:`plovasp plo.cfg` which is configured by an input file, e.g., named :ref:`plo.cfg`.
|
||||
|
||||
.. literalinclude:: images_scripts/plo.cfg
|
||||
|
||||
Here, in `[General]` we set the basename and the grid for calculating the density of
|
||||
states. In `[Group 1]` we define a group of two shells which are orthonormalized with
|
||||
respect to states in an energy window from `-9` to `2` for all ions simultanously
|
||||
(`NORMION = False`). We define the two shells, which correspond to the Ni d states
|
||||
and the O p states. Only the Ni shell is treated as correlated (`CORR = True`), i.e.,
|
||||
is supplemented with a Coulomb interaction later in the DMFT calculation.
|
||||
|
||||
Converting to hdf5 file
|
||||
-------------------------------
|
||||
We gather the output generated by :program:`plovasp` into a hdf5 archive which :program:`dft_tools` is able to read. We do this by running :program:`python converter.py` on the script :ref:`converter.py`:
|
||||
|
||||
.. literalinclude:: images_scripts/converter.py
|
||||
|
||||
Now we are all set to perform a dmft calculation.
|
||||
|
||||
DMFT
|
||||
==================================================
|
||||
|
||||
dmft script
|
||||
------------------------------
|
||||
|
||||
Since the python script for performing the dmft loop pretty much resembles that presented in the tutorial on :ref:`SrVO3 <srvo3>`, we will not go into detail here but simply provide the script :ref:`nio.py`. Following Kunes et al. in `PRB 75 165115 (2007) <https://journals.aps.org/prb/abstract/10.1103/PhysRevB.75.165115>`_ we use :math:`U=8` and :math:`J=1`. We select :math:`\beta=5` instead of :math:`\beta=10` to ease the problem slightly. For simplicity we fix the double-counting potential to :math:`\mu_{DC}=59` eV by::
|
||||
|
||||
DC_value = 59.0
|
||||
SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_value=DC_value)
|
||||
|
||||
For sensible results run this script in parallel on at least 20 cores. As a quick check of the results, we can compare the orbital occupation from the paper cited above (:math:`n_{eg} = 0.54` and :math:`n_{t2g}=1.0`) and those from the cthyb output (check lines `Orbital up_0 density:` for a t2g and `Orbital up_2 density:` for an eg orbital). They should coincide well.
|
||||
|
||||
|
||||
Local lattice Green's function for all projected orbitals
|
||||
---------------------------------------------------------
|
||||
We calculate the local lattice Green's function - now also for the uncorrelated orbitals, i.e., the O p states, for what we use the script :ref:`NiO_local_lattice_GF.py`. The result is saved in the h5 file as `G_latt_orb_it<n_it>`, where `<n_it>` is the number of the last DMFT iteration.
|
||||
|
||||
Spectral function on real axis: MaxEnt
|
||||
--------------------------------------
|
||||
To compare to results from literature we make use of the `maxent triqs application <https://triqs.github.io/maxent/master/>`_ and calculate the spectral function on real axis. Use this script to perform a crude but quick calculation: :ref:`maxent.py` using a linear real axis and a line-fit analyzer to determine the optimal :math:`\alpha`. The output is saved in the h5 file in `DMFT_results/Iterations/G_latt_orb_w_o<n_o>_it<n_it>`, where `<n_o>` is the number of the orbital and `n_it` is again the number of the last iteration. The real axis information is stored in `DMFT_results/Iterations/w_it<n_it>`.
|
||||
|
||||
|
||||
.. image:: images_scripts/nio_Aw.png
|
||||
:width: 400
|
||||
:align: center
|
||||
|
||||
Charge self-consistent DMFT
|
||||
==================================================
|
||||
|
||||
|
||||
In this part we will perform charge self-consistent DMFT calculations. To do so we have to adapt the VASP `INCAR` such that :program:`VASP` reads the updated charge density after each step. We add the lines::
|
||||
|
||||
ICHARG = 5
|
||||
NELM = 1000
|
||||
NELMIN = 1000
|
||||
IMIX=0
|
||||
|
||||
which makes VASP wait after each step of its iterative diagonalization until the file vasp.lock is created. It then reads the update of the charge density in the file `GAMMA`. It is terminated by an external script after a desired amount of steps, such that we deactivate all automatic stoping criterion by setting the number of steps to a very high number.
|
||||
|
||||
We take the respective converged DFT and DMFT calculations from before as a starting point. I.e., we copy the `CHGCAR` and `nio.h5` together with the other :program:`VASP` input files and :file:`plo.cfg` in a new directory. We use a script called :program:`vasp_dmft` to invoke :program:`VASP` in the background and start the DMFT calculation together with :program:`plovasp` and the converter. This script assumes that the dmft sript contains a function `dmft_cycle()` and also the conversion from text files to the h5 file. Additionally we have to add a few lines to calculate the density correction and calculate the correlation energy. We adapt the script straightforardly (for a working example see :ref:`nio_csc.py`). The most important new lines are::
|
||||
|
||||
SK.chemical_potential = SK.calc_mu( precision = 0.000001 )
|
||||
SK.calc_density_correction(dm_type='vasp')
|
||||
correnerg = 0.5 * (S.G_iw * S.Sigma_iw).total_density()
|
||||
|
||||
where the chemical potential is determined to a greater precision than before, the correction to the dft density matrix is calculated and output to the file :file:`GAMMA`. The correlation energy is calculated via Migdal-Galitzki formula. We also slightly increase the tolerance for the detection of blocks since the DFT calculation now includes some QMC noise.
|
||||
|
||||
To help convergence, we keep the density (i.e., the GAMMA file) fixed for a few DFT iterations. We do so since VASP uses an iterative diagonalization.
|
||||
|
||||
We can start the whole machinery by excecuting::
|
||||
|
||||
vasp_dmft -n <n_procs> -i <n_iters> -j <n_iters_dft> -p <vasp_exec> nio_csc.py
|
23
doc/tutorials/svo_vasp/INCAR
Normal file
23
doc/tutorials/svo_vasp/INCAR
Normal file
@ -0,0 +1,23 @@
|
||||
SYSTEM = SrVO3
|
||||
NCORE = 4
|
||||
LMAXMIX=6
|
||||
EDIFF = 1.E-10
|
||||
|
||||
# DOS energy window
|
||||
NEDOS = 2001
|
||||
|
||||
! switch off symmetries
|
||||
ISYM=-1
|
||||
|
||||
# Smearing procedure
|
||||
ISMEAR = -5
|
||||
|
||||
# the energy window to optimize projector channels
|
||||
EMIN = 3.9
|
||||
EMAX = 7.1
|
||||
|
||||
# use the PAW channel optimization
|
||||
LORBIT=14
|
||||
|
||||
# project to V d
|
||||
LOCPROJ = 2 : d : Pr
|
6
doc/tutorials/svo_vasp/KPOINTS
Normal file
6
doc/tutorials/svo_vasp/KPOINTS
Normal file
@ -0,0 +1,6 @@
|
||||
Automatic Mesh
|
||||
0
|
||||
Gamma
|
||||
9 9 9
|
||||
0 0 0
|
||||
|
13
doc/tutorials/svo_vasp/POSCAR
Normal file
13
doc/tutorials/svo_vasp/POSCAR
Normal file
@ -0,0 +1,13 @@
|
||||
SrVO3
|
||||
1.0
|
||||
3.8420900000 0.0000000000 0.0000000000
|
||||
0.0000000000 3.8420900000 0.0000000000
|
||||
0.0000000000 0.0000000000 3.8420900000
|
||||
Sr V O
|
||||
1 1 3
|
||||
Direct
|
||||
0.000000000 0.000000000 0.000000000
|
||||
0.500000000 0.500000000 0.500000000
|
||||
0.500000000 0.500000000 0.000000000
|
||||
0.000000000 0.500000000 0.500000000
|
||||
0.500000000 0.000000000 0.500000000
|
@ -1,7 +1,10 @@
|
||||
[General]
|
||||
DOSMESH = -3.0 3.0 2001
|
||||
|
||||
[Shell 1]
|
||||
LSHELL = 2
|
||||
IONS = 2
|
||||
EWINDOW = -1.45 1.8
|
||||
EWINDOW = -1.4 2.0
|
||||
|
||||
TRANSFORM = 1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
1248
doc/tutorials/svo_vasp/svo_dos.svg
Normal file
1248
doc/tutorials/svo_vasp/svo_dos.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 56 KiB |
357
doc/tutorials/svo_vasp/svo_notebook.ipynb
Normal file
357
doc/tutorials/svo_vasp/svo_notebook.ipynb
Normal file
@ -0,0 +1,357 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"nbsphinx": "hidden"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import matplotlib\n",
|
||||
"matplotlib.use(\"Pdf\")\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"%matplotlib inline\n",
|
||||
"%config InlineBackend.figure_format = 'svg'\n",
|
||||
"\n",
|
||||
"# set matplotlib parameters\n",
|
||||
"params = {'backend': 'ps',\n",
|
||||
" 'axes.labelsize': 13,\n",
|
||||
" 'font.size': 13,\n",
|
||||
" 'legend.fontsize': 13,\n",
|
||||
" 'xtick.labelsize': 13,\n",
|
||||
" 'ytick.labelsize': 13,\n",
|
||||
" 'text.usetex': False,\n",
|
||||
" 'text.latex.preamble': \"\\\\usepackage{mathpazo}, \\\\usepackage{amsmath}\",\n",
|
||||
" 'font.family': 'sans-serif',\n",
|
||||
" 'font.sans-serif': ['Computer Modern Sans serif']}\n",
|
||||
"plt.rcParams.update(params)\n",
|
||||
"\n",
|
||||
"import warnings \n",
|
||||
"warnings.filterwarnings(\"ignore\") #ignore some matplotlib warnings\n",
|
||||
"\n",
|
||||
"# numpy\n",
|
||||
"import numpy as np"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In this basic example we will perform a VASP calculation for SrVO$_3$, build PLOs for the Vanadium t$_{2g}$ orbitals, and load them as SumK object, which can be then used to perform a DMFT calculation.\n",
|
||||
"\n",
|
||||
"## VASP setup\n",
|
||||
"\n",
|
||||
"First we setup the VASP [INCAR link](INCAR) file by specifing the LOCPROJ, EMIN, EMAX and LORBIT flags:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```\n",
|
||||
"SYSTEM = SrVO3\n",
|
||||
"NCORE = 4\n",
|
||||
"LMAXMIX=6\n",
|
||||
"EDIFF = 1.E-10\n",
|
||||
"\n",
|
||||
"# DOS energy window\n",
|
||||
"NEDOS = 2001\n",
|
||||
"\n",
|
||||
"! switch off symmetries\n",
|
||||
"ISYM=-1\n",
|
||||
"\n",
|
||||
"# Smearing procedure\n",
|
||||
"ISMEAR = -5\n",
|
||||
"\n",
|
||||
"# the energy window to optimize projector channels\n",
|
||||
"EMIN = 3.9\n",
|
||||
"EMAX = 7.1\n",
|
||||
"\n",
|
||||
"# use the PAW channel optimization\n",
|
||||
"LORBIT=14\n",
|
||||
"\n",
|
||||
"# project to V d\n",
|
||||
"LOCPROJ = 2 : d : Pr\n",
|
||||
"```\n",
|
||||
"Moreover we prepare a [KPOINTS link](KPOINTS), [POSCAR link](POSCAR), and a POTCAR file. For the POTCAR file please use the VASP provided PBE pseudopotentials: `Sr_sv`, `V`, and `O`. \n",
|
||||
"\n",
|
||||
"Now VASP is executed, which should converge in roughly 27 iterations. Afterwards you should find the files LOCPROJ and PROJCAR in you directory. \n",
|
||||
"\n",
|
||||
"## PLOVASP\n",
|
||||
"\n",
|
||||
"First import the PLOVASP module of DFTTools:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Starting run with 1 MPI rank(s) at : 2019-12-05 16:12:52.689539\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# import plovasp converter\n",
|
||||
"import triqs_dft_tools.converters.plovasp.converter as plo_converter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next, create a configuration file for plovasp [plo.cfg link](plo.cfg):\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"[General]\n",
|
||||
"DOSMESH = -3.0 3.0 2001\n",
|
||||
"\n",
|
||||
"[Shell 1]\n",
|
||||
"LSHELL = 2\n",
|
||||
"IONS = 2\n",
|
||||
"EWINDOW = -1.4 2.0\n",
|
||||
"\n",
|
||||
"TRANSFORM = 1.0 0.0 0.0 0.0 0.0\n",
|
||||
" 0.0 1.0 0.0 0.0 0.0\n",
|
||||
" 0.0 0.0 0.0 1.0 0.0\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"where the energy window of the t$_{2g}$ bands is specified by `EWINDOW` and the `TRANSFORM` flag picks the correct three orbitals out of the five Vanadium $d$ orbitals [see the guide for the ordering of orbitals](../../guide/conv_vasp.html). Before running PLOVASP, make sure that the Fermi energy is written in the first line of the `LOCPROJ` file, or copy it there (see the VASP [interface guide](../../guide/conv_vasp.html) for more information). The first line should look like\n",
|
||||
"```\n",
|
||||
"1 729 21 5 5.3834262 # of spin, # of k-points, # of bands, # of proj, Efermi\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Now run PLOVASP:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Read parameters:\n",
|
||||
"0 -> {'m': 0, 'l': 2, 'isite': 2, 'label': 'dxy'}\n",
|
||||
"1 -> {'m': 1, 'l': 2, 'isite': 2, 'label': 'dyz'}\n",
|
||||
"2 -> {'m': 2, 'l': 2, 'isite': 2, 'label': 'dz2'}\n",
|
||||
"3 -> {'m': 3, 'l': 2, 'isite': 2, 'label': 'dxz'}\n",
|
||||
"4 -> {'m': 4, 'l': 2, 'isite': 2, 'label': 'dx2-y2'}\n",
|
||||
" Found POSCAR, title line: SrVO3\n",
|
||||
" Total number of ions: 5\n",
|
||||
" Number of types: 3\n",
|
||||
" Number of ions for each type: [1, 1, 3]\n",
|
||||
"\n",
|
||||
" Total number of k-points: 729\n",
|
||||
" Total number of tetrahedra: 4374\n",
|
||||
"eigvals from LOCPROJ\n",
|
||||
"\n",
|
||||
" Unorthonormalized density matrices and overlaps:\n",
|
||||
" Spin: 1\n",
|
||||
" Site: 2\n",
|
||||
" Density matrix Overlap\n",
|
||||
" 0.5875772 0.0015679 -0.0003707 0.0015674 0.0000000 0.9294791 -0.0000080 -0.0000078 -0.0000080 -0.0000001\n",
|
||||
" 0.0015679 0.5876177 -0.0001854 -0.0016078 0.0003240 -0.0000080 0.9294790 -0.0000042 0.0000080 0.0000070\n",
|
||||
" -0.0003707 -0.0001854 0.5815486 -0.0001854 -0.0000000 -0.0000078 -0.0000042 0.9715751 -0.0000038 0.0000003\n",
|
||||
" 0.0015674 -0.0016078 -0.0001854 0.5876172 -0.0003240 -0.0000080 0.0000080 -0.0000038 0.9294791 -0.0000066\n",
|
||||
" 0.0000000 0.0003240 -0.0000000 -0.0003240 0.5815487 -0.0000001 0.0000070 0.0000003 -0.0000066 0.9715748\n",
|
||||
"\n",
|
||||
" Generating 1 shell...\n",
|
||||
"\n",
|
||||
" Shell : 1\n",
|
||||
" Orbital l : 2\n",
|
||||
" Number of ions: 1\n",
|
||||
" Dimension : 3\n",
|
||||
" Correlated : True\n",
|
||||
" Ion sort : [1]\n",
|
||||
"Density matrix:\n",
|
||||
" Shell 1\n",
|
||||
" Site 1\n",
|
||||
" 0.3332630 0.0021719 0.0021714\n",
|
||||
" 0.0021719 0.3333128 -0.0022211\n",
|
||||
" 0.0021714 -0.0022211 0.3333123\n",
|
||||
" trace: 0.9998880790966638\n",
|
||||
"\n",
|
||||
" Impurity density: 0.9998880790966638\n",
|
||||
"\n",
|
||||
"Overlap:\n",
|
||||
" Site 1\n",
|
||||
"[[ 1. -0. 0.]\n",
|
||||
" [-0. 1. 0.]\n",
|
||||
" [ 0. 0. 1.]]\n",
|
||||
"\n",
|
||||
"Local Hamiltonian:\n",
|
||||
" Shell 1\n",
|
||||
" Site 1\n",
|
||||
" 0.5633806 0.0007563 0.0007563\n",
|
||||
" 0.0007563 0.5633801 -0.0007559\n",
|
||||
" 0.0007563 -0.0007559 0.5633801\n",
|
||||
"\n",
|
||||
"Evaluating DOS...\n",
|
||||
" Shell 1\n",
|
||||
" Total number of states: [[[7.33737319 7.48285647 7.28002405]]]\n",
|
||||
" Storing ctrl-file...\n",
|
||||
" Storing PLO-group file 'vasp.pg1'...\n",
|
||||
" Density within window: 0.9999741659673522\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Generate and store PLOs\n",
|
||||
"plo_converter.generate_and_output_as_text('plo.cfg', vasp_dir='./')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"PLOVASP created one shell with three orbitals, which are equally filled by 1/3, one electron in total. Additionally we calculated the density of states. Both in VASP and PLOVASP. The later stores the data in the file pdos_x.dat, which can be simply plotted with [matplotlib](https://matplotlib.org/). The result should look similar to:\n",
|
||||
"\n",
|
||||
"![](svo_dos.svg)\n",
|
||||
"\n",
|
||||
"Here the gray area highlights the energy window for the PLOs. The total DOS of VASP (blue) coincides with the PLO DOS in the window, as we re-orthonormalized the projector functions in the given window, picking up also Oxygen weight. This setting is closed to the result of maximally localized Wannier functions created with [wannier90](http://www.wannier.org/) without running the actual minimization of the spread. Note, for a proper comparison one can use the hydrogen projector in VASP by using the the line `LOCPROJ= 2 : d : Hy`, instead of `Pr`. \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"## Converting to hdf5 file\n",
|
||||
"\n",
|
||||
"Finally we can run the VASP converter to create a h5 file:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Reading input from vasp.ctrl...\n",
|
||||
"{\n",
|
||||
" \"ngroups\": 1,\n",
|
||||
" \"nk\": 729,\n",
|
||||
" \"ns\": 1,\n",
|
||||
" \"nc_flag\": 0\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
" No. of inequivalent shells: 1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# import VASPconverter\n",
|
||||
"from triqs_dft_tools.converters.vasp_converter import *\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# create Converter\n",
|
||||
"Converter = VaspConverter(filename = 'vasp')\n",
|
||||
"# run the converter\n",
|
||||
"Converter.convert_dft_input()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The resulting h5 file `vasp.h5` can now be loaded as sumk object via:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# SumK\n",
|
||||
"from triqs_dft_tools.sumk_dft_tools import SumkDFTTools\n",
|
||||
"\n",
|
||||
"SK = SumkDFTTools(hdf_file='vasp.h5', use_dft_blocks = False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here one should carefully determine the block structure manually. This is important to find degenerate orbitals and spin-channels:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"found 1 blocks of degenerate orbitals in shell 0\n",
|
||||
"block 0 consists of orbitals:\n",
|
||||
" up_2\n",
|
||||
" up_0\n",
|
||||
" up_1\n",
|
||||
" down_2\n",
|
||||
" down_1\n",
|
||||
" down_0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"Sigma = SK.block_structure.create_gf(beta=40)\n",
|
||||
"SK.put_Sigma([Sigma])\n",
|
||||
"G = SK.extract_G_loc()\n",
|
||||
"SK.analyse_block_structure_from_gf(G, threshold = 1e-3)\n",
|
||||
"for i_sh in range(len(SK.deg_shells)):\n",
|
||||
" num_block_deg_orbs = len(SK.deg_shells[i_sh])\n",
|
||||
" mpi.report('found {0:d} blocks of degenerate orbitals in shell {1:d}'.format(num_block_deg_orbs, i_sh))\n",
|
||||
" for iblock in range(num_block_deg_orbs):\n",
|
||||
" mpi.report('block {0:d} consists of orbitals:'.format(iblock))\n",
|
||||
" for keys in SK.deg_shells[i_sh][iblock].keys():\n",
|
||||
" mpi.report(' '+keys)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This minimal example extracts the block structure by calculating once the local Green's functions and then finds degenerate orbitals with a certain threshold in `Gloc`. Afterwards the result is reported, where 1 block is found with size 6 (3x2 orbitals for spin), where a all 6 orbitals are marked as degenerate. This is indeed correct in cubic SrVO$_3$, as all 3 t$_{2g}$ orbitals are degenerate. Note: for a magnetic calculation one has to break the symmetry between up and down at this point manually. Moreover, one can reduce the threshold for example to `1e-5` and finds that then the degeneracy of the 3 t$_{2g}$ orbitals is not found anymore, resulting in only two degenerate blocks for spin up and down, each with size 3x3.\n",
|
||||
"\n",
|
||||
"Afterwards the exact same DMFT script as in the [Wien2k tutorial](../srvo3.html) can be used. For a more elaborate example including charge self-consistency take a look at the [VASP NiO example](../nio_csc.html)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 2",
|
||||
"language": "python",
|
||||
"name": "python2"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.15+"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/plotools.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/plotools.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/plotools"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/plotools"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
2
doc/vasp/build/.gitignore
vendored
2
doc/vasp/build/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!/.gitignore
|
@ -1,19 +0,0 @@
|
||||
[General]
|
||||
EFERMI = -0.6
|
||||
|
||||
[Group 1]
|
||||
SHELLS = 1 2
|
||||
EWINDOW = -7.6 2.7
|
||||
|
||||
[Shell 1]
|
||||
# Ni shell
|
||||
IONS = 5 6 7 8
|
||||
LSHELL = 2
|
||||
TRANSFORM =
|
||||
0.0 0.0 0.0 0.0 1.0
|
||||
0.0 0.0 1.0 0.0 0.0
|
||||
|
||||
[Shell 2]
|
||||
# Oxygen shell
|
||||
IONS = 9..20
|
||||
LSHELL = 1
|
@ -1,43 +0,0 @@
|
||||
.. highlight:: python
|
||||
|
||||
#######################
|
||||
Charge self-consistency
|
||||
#######################
|
||||
|
||||
Introduction
|
||||
************
|
||||
|
||||
Running a DFT+DMFT calculation in the charge self-consistent mode
|
||||
requires additional process management whereby the control is given
|
||||
to the VASP and to the TRIQS code in an alternating manner.
|
||||
It is implemented by a lock system. A VASP process is launched in
|
||||
the background and a self-consistency (SC) script in the foreground.
|
||||
Once VASP reaches the point where the projectors are generated
|
||||
it creates a lock file `vasp.lock` and waits until the lock file is
|
||||
removed. The SC script, in turn, waits for the VASP process and once
|
||||
the lock file is created it starts a DMFT iteration. The DMFT iteration
|
||||
must finish by generating a Kohn-Sham (KS) density matrix (file `GAMMA`)
|
||||
and removing the lock file. The VASP process then reads in `GAMMA`
|
||||
and proceeds with the next iteration.
|
||||
|
||||
The DMFT iteration is performed using a user-defined script.
|
||||
However, the control part is maintained by two universal scripts:
|
||||
`sc_dmft.sh` and `sc_dmft.py`.
|
||||
|
||||
The first script, `sc_dmft.sh`, launches the VASP process
|
||||
in the background mode, takes its pid, and launches `sc_dmft.py`
|
||||
in the foreground mode.
|
||||
Both processes are run within an MPI environment with an appropriate
|
||||
number of MPI nodes.
|
||||
|
||||
The second script, `sc_dmft.py`, is responsible for the charge self-consitency
|
||||
logic described in the first paragraph. It also combines the total
|
||||
energy contributions coming from the DFT and DMFT parts.
|
||||
The script imports a user-defined DMFT script `dmft_cycle.py` which
|
||||
must produce KS density-matrix file `GAMMA` for the next DFT iteration
|
||||
and also must return the correlation (including the double counting) energy
|
||||
of the impurity model as well as a correlation correction to the
|
||||
DFT band energy (resulting from the difference between the bare
|
||||
and DMFT density matrices).
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
Code Structure
|
||||
##############
|
||||
|
||||
.. toctree::
|
||||
|
||||
vaspio
|
||||
plotools
|
||||
converter
|
||||
charge_selfcons
|
||||
|
||||
The program consists of three main parts:
|
||||
* :doc:`Import of data from VASP files </vaspio>`
|
||||
* Processing of projectors according to an input config-file
|
||||
* Conversion of the DFT data to TRIQS h5-file
|
||||
|
||||
Import of data from VASP files is implemented in `vaspio.py`. The data
|
||||
is read from VASP files and then stored in objects in raw format
|
||||
(i.e. practically no processing is done at this stage).
|
||||
These objects are then combined into a dictionary which can be easily
|
||||
passed to other routines.
|
||||
|
||||
The basic workflow is prescribed as follows:
|
||||
* raw data is read from VASP files and passed to the main part
|
||||
* in the main part the input config-file is read and the projectors are selected and process accordingly
|
||||
* the processed data is stored into output text-files
|
||||
* when the TRIQS-converter is requested the data is read from text-files and written into a h5-file in an appropriate format
|
@ -1,244 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# plotools documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue Feb 3 20:25:36 2015.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('../../../python/vasp'))
|
||||
sys.path.insert(0, os.path.abspath('../../../c'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.pngmath', 'sphinx.ext.mathjax']
|
||||
mathjax_path = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'PLOVasp'
|
||||
copyright = u'2015, Oleg E. Peil'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'plotoolsdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'plotools.tex', u'plotools Documentation',
|
||||
u'Oleg E. Peil', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'plotools', u'plotools Documentation',
|
||||
[u'Oleg E. Peil'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'plotools', u'plotools Documentation',
|
||||
u'Oleg E. Peil', 'plotools', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
@ -1,124 +0,0 @@
|
||||
Input Config-file
|
||||
=================
|
||||
|
||||
A config-file describes subsets of PLOs that are to be generated.
|
||||
The PLOs are defined in terms of `shells` determined uniquely by an orbital
|
||||
number `l` and a set of ions (nomrmally, of the same sort).
|
||||
The shells are further combined into `groups` such that PLO in each group
|
||||
are orthogonalized together. This, for instance, allows to create a group of several
|
||||
mutually orthogonal subsets of PLOs.
|
||||
A group is characterized by a single projection energy window.
|
||||
|
||||
A config-file contains three types of sections:
|
||||
|
||||
- **[General]** : providing information applicable to all projected shells
|
||||
(e.g. Fermi level)
|
||||
- **[Shell <Ns>]** : each section like this describes a PLO shell, with the index
|
||||
`Ns` used for referencing
|
||||
- **[Group <tag>]** : describes shell groups
|
||||
|
||||
The format requirements are relatively flexible. A config-file must contain
|
||||
at least one `[Shell]` section. If there is only one shell defined, it is possible
|
||||
to specify the energy window by providing parameters `EMIN`, `EMAX` (see below)
|
||||
right in this section, in which case a group
|
||||
will be created automatically and the `[Group]` section can be omitted.
|
||||
If, nevertheless, a group referencing the single shell is explicitly given
|
||||
the energy window parameters provided in the `[Group]` have higher priority
|
||||
and in case of conflict with `[Shell]` section a warning is issued.
|
||||
|
||||
An example of a config-file:
|
||||
|
||||
.. literalinclude:: adv_example.cfg
|
||||
|
||||
Here two shells, one corresponding to `d` states on ions 5-8, another to `p`
|
||||
states of ions 9-20, are created. They form a single group that, by default, will be
|
||||
orthogonalized within a window `[-7.6, 2.7]` eV. Also Fermi level is explicitly
|
||||
specified, which might be necessary sometimes, e.g., for non-self-consistent calcuation
|
||||
of the band structure.
|
||||
|
||||
Below, the sections and their parameters are described.
|
||||
All parameter names are case-insensitive.
|
||||
|
||||
Section [General]
|
||||
-----------------
|
||||
|
||||
**Required parameters:**
|
||||
|
||||
In principle, there are unconditionally required parameters in this section.
|
||||
However, if VASP data file do not contain a meaningful value of the Fermi level
|
||||
it must be given here using parameter *EFERMI*. Note that if this parameter
|
||||
is given it will override a value that might have been read from VASP files.
|
||||
|
||||
**Optional parameters:**
|
||||
- *BASENAME* (string): a basename for output files. The filenames will be
|
||||
of the form '<basename>.*'.
|
||||
- *DOSMESH* (float, float, int): if this parameter is provided the projected
|
||||
DOS for each projected shell will be generated, with the energy mesh parameters
|
||||
given by the energy range (two floats) and the number of points (int). It is also
|
||||
possible to omit the energy range, in which case it will be set to the energy window
|
||||
of the corresponding projector group.
|
||||
|
||||
Section [Shell <Ns>]
|
||||
--------------------
|
||||
|
||||
Defines a projected shell with an integer index `<Ns>`. Ideally, the indices should
|
||||
run uniformly starting from 1. However, since they are used only to reference
|
||||
shells in group sections, their values are not important. One should only
|
||||
make sure that there are no sections with the same name, in which case one
|
||||
of them will be ignored by config parser.
|
||||
|
||||
**Required parameters:**
|
||||
|
||||
- *IONS* ([int]): provides a list of ions. The list can be either given
|
||||
by a explicit enumeration of ion indices or by a range `N1..N2` (ions `N1` and `N2`
|
||||
will be included).
|
||||
- *LSHELL* (int): orbital number `l` of the shell (`l = 0,1,2,3` for `s,p,d,f`, respectively).
|
||||
|
||||
|
||||
**Optional parameters:**
|
||||
|
||||
- *TRANSFORM* (matrix of floats): transformation matrices
|
||||
(real or complex) that are applied to projectors before orthogonalization.
|
||||
The number of columns `Nc` must be consistent with the number of orbitals
|
||||
(`Nc = 2l+1` for real matrices and `Nc = 2(2l+1)` for complex ones).
|
||||
The dimension of the resulting orbital subspace is determined by the number of rows.
|
||||
- *TRANSFILE* (str): file containing transformation matrices for individual ions.
|
||||
The file must contain rows of floats. Empty lines and lines starting with '#' are ignored.
|
||||
The data is interpreted as follows:
|
||||
|
||||
* The number of rows is divided by the number of ions to give the number
|
||||
of rows per ion, `Nr`.
|
||||
* The number of columns is divided by `Nm = 2 * l + 1` to give `nsize`.
|
||||
There are, then, three options:
|
||||
|
||||
#. if `nc_flag = 0`, i.e. a calculation is collinear (no spin-orbit coupling),
|
||||
and `nsize = 1` the matrices are considered to be real;
|
||||
#. if `nc_flag = 0` and `nsize = 2` the matrices are considered to be complex;
|
||||
#. if `nc_flag = 1`, i.e. a calculation is non-collinear, it is expected
|
||||
that `nsize = 4`, and the matrices are considered to be complex and
|
||||
spin-dependent.
|
||||
|
||||
* The subspace dimension is determined simply as `Ndim = Nr / nsize`.
|
||||
|
||||
In all cases when a division is performed the result must be integer. Otherwise,
|
||||
the matrices are considered to be inconsistent.
|
||||
- *EWINDOW* (float, float): energy window. Should be given only if no excplicit groups
|
||||
is specified. Otherwise, the values are overriden by group parameters.
|
||||
|
||||
|
||||
Section [Group <tag>]
|
||||
---------------------
|
||||
|
||||
Defines a group of shells. Note that the group tag can be any string without whitespaces.
|
||||
It will be used to tag intermediate output files.
|
||||
|
||||
**Required parameters:**
|
||||
|
||||
- *SHELLS* ([int]): indices refering to shells forming the group.
|
||||
- *EWINDOW* (float, float): the bottom and top of the energy window with respect to the Fermi level.
|
||||
|
||||
**Optional parameters:**
|
||||
- NORMALIZE (True/False): if True, orthogonalizetion is performed (default behavior).
|
||||
- *NORMION* (True/False): if True, orthogonalization is performed on each site
|
||||
separately; if False, all projectors of the group are orthogonalized together.
|
||||
|
@ -1,4 +0,0 @@
|
||||
TRIQS Converter
|
||||
###############
|
||||
|
||||
The converter provides an interface between a DFT code and TRIQS solvers.
|
@ -1,12 +0,0 @@
|
||||
[General]
|
||||
|
||||
[PLO Group 1]
|
||||
|
||||
IONS = 5 6 7 8
|
||||
EMIN = -0.6
|
||||
EMAX = 2.7
|
||||
LSHELL = 2
|
||||
RTRANSFORM =
|
||||
0.0 0.0 0.0 0.0 1.0
|
||||
0.0 0.0 1.0 0.0 0.0
|
||||
|
@ -1,27 +0,0 @@
|
||||
.. plotools documentation master file, created by
|
||||
sphinx-quickstart on Tue Feb 3 20:25:36 2015.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to PLOVasp's documentation!
|
||||
====================================
|
||||
|
||||
PLOVasp documentation.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
users_guide
|
||||
code_struct
|
||||
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
@ -1,64 +0,0 @@
|
||||
|
||||
Processing tools for PLOs generated by VASP.
|
||||
|
||||
The main purpose of this set of tools is to process raw data
|
||||
generated by VASP and to convert data to the TRIQS format. The raw data
|
||||
is read from files:
|
||||
POSCAR (atomic positions)
|
||||
EIGVAL (eignevalues)
|
||||
PLOCAR (non-orthogonalized PLOs and Fermi-weights)
|
||||
IBZKPT (k-points and tetrahedra)
|
||||
|
||||
An appropriate set of orthogonalized projectors is defined by
|
||||
parameters defined in the config file (config-like syntax).
|
||||
The config-file allows to define several groups of projectors.
|
||||
|
||||
|
||||
Structure of PLOtools:
|
||||
|
||||
vaspio.py: reading of VASP-generated files
|
||||
|
||||
|
||||
|
||||
vaspio.py:
|
||||
All VASP data are represented by objects which contain data read
|
||||
from corresponding files. These objects will subsequently be used to
|
||||
handle the data and convert it into a more functional internal representation.
|
||||
|
||||
|
||||
Functions
|
||||
|
||||
read_lines(filename): generator yielding lines from a file <filename>
|
||||
|
||||
Classes:
|
||||
Plocar: raw PLO data from PLOCAR file;
|
||||
the data itself is read using an auxiliary C-routine 'read_plocar'
|
||||
|
||||
Poscar: structure data from POSCAR file
|
||||
|
||||
Kpoints: k-point data from IBZKPT file
|
||||
note that k-point data is also contained in EIGENVAL file;
|
||||
the two k-point sets will be checked for consistency.
|
||||
|
||||
Eigenval: Kohn-Sham eigenvalues as well as k-points with weights
|
||||
|
||||
Symmcar: symmetry operations stored by VASP into SYMMCAR file
|
||||
|
||||
|
||||
ploortho.py (or projectors.py)
|
||||
Set of routines for processing projectors. The functionality includes:
|
||||
-- selecting a proper subset of non-orthogonalized projectors from the raw VASP input
|
||||
-- transforming and orthogonalizing projectors
|
||||
-- calculating DFT density matrix and local Hamiltonian
|
||||
|
||||
General design:
|
||||
Input data: conf_pars (output of 'parse_input()'), VASP file descriptors (Eigenval, Plocar, etc.)
|
||||
|
||||
* A projector for a given k-point is described by class 'Projector'
|
||||
PLOs project on a set or orbitals and a set of ions.
|
||||
|
||||
* Projector set is a container of 'Projector' objects.
|
||||
Out of optimization purposes the projectors are stored in a multi-dimensional
|
||||
array. A view in terms of Projector objects is, however, possible.
|
||||
|
||||
|
@ -1,191 +0,0 @@
|
||||
.. highlight:: python
|
||||
|
||||
#########
|
||||
PLO tools
|
||||
#########
|
||||
|
||||
Introduction
|
||||
************
|
||||
|
||||
This set of tools is intended for processing of raw projectors read
|
||||
from VASP. One of the main tasks is to generate an orthonormalized subset
|
||||
of PLOs constructed according to the :doc:`config-file </config>`.
|
||||
|
||||
To produce the final output the following steps are undertaken:
|
||||
|
||||
* Parse input config-file
|
||||
|
||||
* Input raw VASP data
|
||||
|
||||
* Convert the raw VASP data into an internal representaion and check it for consistency.
|
||||
|
||||
* Generate a set of projector shells according to the parameters of the config-file
|
||||
|
||||
* Create a set of projector groups
|
||||
|
||||
* Perform necessary group operations (such as :ref:`orthogonalization<ortho>`) on the constituing shells
|
||||
|
||||
* Calculate and output some useful quantities (bare density matrix, DOS, etc.)
|
||||
|
||||
|
||||
Initial Processing
|
||||
******************
|
||||
|
||||
The raw data from VASP files is initially read in simple objects (containers).
|
||||
Then these objects are combined in an another object containing all necessary
|
||||
electronic structure data. At this stage simple consistency checks are performed:
|
||||
|
||||
* the basic dimensions, such as the number of bands, number of `k`-points, etc.,
|
||||
are consistent for all data
|
||||
|
||||
* the `k`-point mesh are read both the IBZKPT and EIGENVAL and it is worth checking
|
||||
that both sets are coinciding
|
||||
|
||||
* in case tetrahedron data is read from IBZKPT, the tetrahedron volume must be related
|
||||
to the total volume of the unit cell as derived from POSCAR
|
||||
|
||||
All electronic structure from VASP is stored in a class ElectronicStructure:
|
||||
|
||||
.. autoclass:: triqs_dft_tools.converters.plovasp.elstruct.ElectronicStructure
|
||||
:members:
|
||||
|
||||
|
||||
Consistency with parameters
|
||||
|
||||
* parameters in the config-file should pass trivial checks such as that the ion
|
||||
list does not contain non-existing ions (boundary check for ion indices)
|
||||
|
||||
.. function:: check_vasp_data_consistency(conf_pars, vasp_data)
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- *conf_pars* (dict) : dictionary of input parameters from conf-file
|
||||
- *vasp_data* (dict) : dictionary containing all VASP data
|
||||
|
||||
**Returns**:
|
||||
|
||||
*None*
|
||||
|
||||
**Raises**:
|
||||
|
||||
A meaningful exception indicating an inconsistency in the input data
|
||||
|
||||
|
||||
Selecting projector subsets
|
||||
===========================
|
||||
|
||||
The first step of PLO processing is to select subsets of projectors
|
||||
corresponding to PLO groups. Each group contains a set of shells.
|
||||
Each projector shell is represented by an object 'ProjectorShell'
|
||||
that contains an array of projectors and information on the shell itself
|
||||
(orbital number, ions, etc.). 'ProjectorShell's are contained in
|
||||
both a list of shells (according to the original list as read
|
||||
from config-file) and in a 'ProjectorGroup' object, the latter
|
||||
also providing information about the energy window.
|
||||
`[In fact, shell container can be a simple dictionary.]`
|
||||
|
||||
Order of operations:
|
||||
|
||||
- transform projectors (all bands) in each shell
|
||||
- select transformed shell projectors for a given group within the window
|
||||
- orthogonalize if necessary projectors within a group by performing
|
||||
the following operations for each k-point:
|
||||
* combine all projector shells into a single array
|
||||
* orthogonalize the array
|
||||
* distribute back the arrays assuming that the order is preserved
|
||||
|
||||
|
||||
.. autoclass:: triqs_dft_tools.converters.plovasp.proj_shell.ProjectorShell
|
||||
:members:
|
||||
|
||||
|
||||
The class is using a helper function `select_bands()` for selecting a subset of bands.
|
||||
|
||||
.. function:: select_bands(eigvals, emin, emax)
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- *eigvals* (numpy.array) : array of eigenvalues
|
||||
- *emin*, *emax* (float) : energy window
|
||||
|
||||
**Returns**:
|
||||
|
||||
*ib_win*, *nb_min*, *nb_max* (numpy.array[int], int, int) :
|
||||
lowest and highest indices of the selected bands
|
||||
|
||||
|
||||
.. _ortho:
|
||||
|
||||
Orthogonalization
|
||||
-----------------
|
||||
|
||||
At the second stage the selected projectors are orthogonalized (orthonormalized).
|
||||
Orthogonalization can be performed in different ways if projection is made
|
||||
on several ions or if several correlated shells per ion are considered.
|
||||
In the case of several correlated ions per unit cell (and one correlated shell per ion)
|
||||
at least two options can be considered:
|
||||
|
||||
#. Projectors are normalized for each ion separetely. In this case, corresponding
|
||||
Wannier functions for different ions are generally not orthogonal.
|
||||
|
||||
#. Projectors are normalized for all ions in the unit cell simultaneously. This
|
||||
ensures that the Wannier functions for different ions are mutually orthogonal.
|
||||
|
||||
The way the normalization of a PLO group is done is controlled by two group parameters:
|
||||
|
||||
- *NORMALIZE* (True/False) : indicates whether the PLO group is normalized (True by default)
|
||||
- *NORMION* (True/False) : indicates whether the PLO group is normalized on a per-ion basis
|
||||
(False by default)
|
||||
|
||||
|
||||
Storing generated projectors
|
||||
****************************
|
||||
|
||||
After the PLOs are generated they are stored to text files which can be subsequently
|
||||
converted to TRIQS h5-files (using the converter). The general format of the file
|
||||
is a JSON-header containing all necessary parameters followed by a set of arrays.
|
||||
There is always one (control) file containing general information (`k`-kpoints, lattice vectors etc.)
|
||||
and `at least` one file containing correlated groups (one file for each group).
|
||||
|
||||
Control file format
|
||||
===================
|
||||
|
||||
Filename '<namebase>.ctrl'. Contains the data shared between all shells.
|
||||
The JSON-header consists of the following elements:
|
||||
|
||||
* *nk*: number of `k`-points
|
||||
|
||||
* *ns*: number of spin channels
|
||||
|
||||
* *nc_flag*: collinear/noncollinear case (False/True)
|
||||
|
||||
* *ng*: number of projector groups
|
||||
|
||||
* Symmetry information (list of symmetry operations)
|
||||
|
||||
* *efermi*: Fermi level (optional)
|
||||
|
||||
* Lattice information
|
||||
|
||||
Projector-group file format
|
||||
===========================
|
||||
|
||||
Projector-group files have names '<namebase>.plog<Ng>'.
|
||||
They essentially contain serialized objects of class 'ProjectorGroup'.
|
||||
The JSON-header has, thus, the following elements:
|
||||
|
||||
* *shells*: list of shells
|
||||
|
||||
* each shell is a dictionary:
|
||||
|
||||
- *lshell*: orbital number `l`
|
||||
|
||||
- *nion*: number of ions
|
||||
|
||||
- *ndim*: number of orbitals/ion
|
||||
|
||||
- *nbmax*: maxmimum number of bands (needed for array allocations)
|
||||
|
||||
* *emin*, *emax*: energy window
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
User's Guide
|
||||
############
|
||||
|
||||
.. toctree::
|
||||
config
|
||||
|
||||
PLOVasp is a set of tools for performing DFT+DMFT calculations within
|
||||
the fromalism of projected localized orbitals (PLO) using
|
||||
VASP in combination with the TRIQS package.
|
||||
It relies on projectors implemented in VASP >= 5.4.1 and generated with
|
||||
the option LOCPROJ in INCAR. The main goal of PLOVasp is to use these raw
|
||||
projectors generated by VASP to produce PLOs and to convert them to the standard
|
||||
format of DFTTools, which allows a user to use the same DMFT scripts
|
||||
as for Wien2TRIQS interface, with only the converter class being replaced.
|
||||
|
||||
Currently PLOVasp supports only one-shot DFT+DMFT calculations, with
|
||||
the full charge self-consistency being in the process of implementation.
|
||||
|
||||
PLOVasp package consists of two main parts:
|
||||
* A set of tools for processing VASP-generated projectors
|
||||
* A converter class VaspConverter that prepares an HDF5 file for DFTTools
|
||||
|
||||
A typical one-shot DFT+DMFT calculation is generally performed as follows:
|
||||
* Run VASP with LOCPROJ option to generate raw projectors
|
||||
* Write an input file and run PLOVasp to produce data required by DFTTools
|
||||
* Run a DMFT script based on DFTTools with VaspConverter class used as a converter
|
||||
|
||||
The format of the input file is described in section :doc:`Input Config-file <config>`.
|
||||
|
@ -1,39 +0,0 @@
|
||||
.. _vaspio:
|
||||
|
||||
VASP input-output
|
||||
#################
|
||||
|
||||
The following VASP files are used by PLOtools:
|
||||
* PROJCAR, LOCPROJ: raw projectors generated by VASP-PLO interface (VASP version >= 5.4.1)
|
||||
* EIGENVAL: Kohn-Sham eigenvalues as well as `k`-points with weights and Fermi weights
|
||||
* IBZKPT: `k`-point data (:math:`\Gamma`)
|
||||
* POSCAR: crystal structure data
|
||||
|
||||
Starting from version 5.4.1 VASP now supports an official output of various types of
|
||||
projectors that are requested in INCAR by specifying a set of sites, orbitals and types
|
||||
of projectors. The calculated projectors are output into files **PROJCAR** and **LOCPROJ**.
|
||||
The difference between these two files is that **LOCPROJ** contains raw matrices without
|
||||
any reference to sites/orbitals, while **PROJCAR** is more detailed on that.
|
||||
In particular, the information that can be obtained for each projector from **PROJCAR** is the following:
|
||||
|
||||
* site (and species) index
|
||||
* for each `k`-point and band: a set of complex numbers for labeled orbitals
|
||||
|
||||
At the same time, **LOCPROJ** contains the total number of projectors (as well as the
|
||||
number of `k`-points, bands, and spin channels) in the first line,
|
||||
which can be used to allocate the arrays before parsing.
|
||||
|
||||
To enhance the performance of the parser, it is implemented in plain C. The idea is
|
||||
that the python part of the parser first reads the first line of **LOCPROJ** and
|
||||
then calls the C-routine with necessary parameters to parse **PROJCAR**.
|
||||
|
||||
The projectors are read in and stored in class `Plocar`. Two major data structures are stored:
|
||||
|
||||
* complex array `plo = nd.array((nproj, nspin, nk, nband))`
|
||||
* list of projector descriptors `proj_params` containing the information on
|
||||
the character of projectors
|
||||
|
||||
When a ProjectorShell is initialized it copies a subset of projectors corresponding
|
||||
to selected sites/orbitals. This can be done by looping all shell sites/orbitals and
|
||||
searching for the corresponding projector using the descriptor list `proj_params`.
|
||||
|
@ -24,14 +24,16 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.main
|
||||
=========
|
||||
plovasp.converter
|
||||
=================
|
||||
|
||||
Main script of PLOVasp.
|
||||
PLOVASP is a tool to transform raw, non-normalized
|
||||
projectors generated by VASP into normalized projectors
|
||||
corresponding to user-defined projected localized orbitals (PLO).
|
||||
|
||||
Runs routines in proper order to generate and store PLOs.
|
||||
|
||||
Usage: python main.py <conf-file> [<path-to-vasp-calcultaion>]
|
||||
Usage: python converter.py <conf-file> [<path-to-vasp-calculation>]
|
||||
"""
|
||||
import sys
|
||||
import vaspio
|
||||
@ -85,4 +87,3 @@ def main():
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.elstruct
|
||||
=============
|
||||
plovasp.elstruct
|
||||
================
|
||||
|
||||
Internal representation of VASP electronic structure data.
|
||||
"""
|
||||
@ -105,7 +105,7 @@ class ElectronicStructure:
|
||||
print "eigvals from LOCPROJ"
|
||||
self.eigvals = vasp_data.plocar.eigs
|
||||
self.ferw = vasp_data.plocar.ferw.transpose((2, 0, 1))
|
||||
self.efermi = vasp_data.plocar.efermi
|
||||
self.efermi = vasp_data.doscar.efermi
|
||||
|
||||
# For later use it is more convenient to use a different order of indices
|
||||
# [see ProjectorGroup.orthogonalization()]
|
||||
@ -123,6 +123,21 @@ class ElectronicStructure:
|
||||
# Concatenate coordinates grouped by type into one array
|
||||
self.structure['qcoords'] = np.vstack(vasp_data.poscar.q_types)
|
||||
self.structure['type_of_ion'] = vasp_data.poscar.type_of_ion
|
||||
|
||||
a = []
|
||||
for ia in range(3):
|
||||
a.append( vasp_data.poscar.a_brav[:,ia])
|
||||
vol = np.dot(a[0],np.cross(a[1],a[2]))
|
||||
b1 = 2.0*np.pi*np.cross(a[1],a[2])/vol
|
||||
b2 = 2.0*np.pi*np.cross(a[2],a[0])/vol
|
||||
b3 = 2.0*np.pi*np.cross(a[0],a[1])/vol
|
||||
b = [b1,b2,b3]
|
||||
self.kmesh['kpoints_cart'] = 0.0 * self.kmesh['kpoints']
|
||||
|
||||
for ik in range(self.nktot):
|
||||
for ii in range(3):
|
||||
self.kmesh['kpoints_cart'][ik] += self.kmesh['kpoints'][ik,ii]*b[ii]
|
||||
|
||||
# FIXME: This can be removed if ion coordinates are stored in a continuous array
|
||||
## Construct a map to access coordinates by index
|
||||
# self.structure['ion_index'] = []
|
||||
@ -159,8 +174,9 @@ class ElectronicStructure:
|
||||
# ov_min = np.minimum(ov, ov_min)
|
||||
|
||||
# Output only the site-diagonal parts of the matrices
|
||||
print
|
||||
print " Unorthonormalized density matrices and overlaps:"
|
||||
for ispin in xrange(ns):
|
||||
print
|
||||
print " Spin:", ispin + 1
|
||||
for io, ion in enumerate(ions):
|
||||
print " Site:", ion
|
||||
@ -173,11 +189,9 @@ class ElectronicStructure:
|
||||
dm[iorb, iorb2] = den_mat[ispin, ind, ind2]
|
||||
ov[iorb, iorb2] = overlap[ispin, ind, ind2]
|
||||
|
||||
print " Density matrix" + (12*norb - 12)*" " + "Overlap"
|
||||
print " Density matrix" + (12*norb - 12 + 2)*" " + "Overlap"
|
||||
for drow, dov in zip(dm, ov):
|
||||
out = ''.join(map("{0:12.7f}".format, drow))
|
||||
out += " "
|
||||
out += ''.join(map("{0:12.7f}".format, dov))
|
||||
print out
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
!INCAR
|
||||
!POSCAR
|
||||
!POTCAR
|
||||
!KPOINTS
|
||||
!plo.cfg
|
||||
!*.sh
|
||||
!*.py
|
@ -1,49 +0,0 @@
|
||||
ADDGRID = TRUE
|
||||
AMIX = 0.1
|
||||
AMIN = 0.01
|
||||
BMIX = 0.0001
|
||||
#IMIX = 1
|
||||
#MIXFIRST = True
|
||||
ALGO = NORMAL
|
||||
EDIFF = 0.00001
|
||||
EDIFFG = -0.002
|
||||
EMAX = 13.0
|
||||
EMIN = -2.0
|
||||
ENCUT = 600
|
||||
ENAUG = 1100
|
||||
IBRION = -1
|
||||
ICHARG = 5
|
||||
ISIF = 4
|
||||
ISMEAR = 2
|
||||
ISPIN = 2
|
||||
ISYM = -1
|
||||
LASPH = TRUE
|
||||
LCHARG = TRUE
|
||||
LDAU = True
|
||||
LDAUJ = 0
|
||||
LDAUL = 3
|
||||
LDAUTYPE = 2
|
||||
LDAUU = 0.0
|
||||
LDAUPRINT = 2
|
||||
LMAXMIX = 6
|
||||
LORBIT = 13
|
||||
LREAL = False
|
||||
ROPT = 1e-3 1e-3 1e-3
|
||||
LWAVE = TRUE
|
||||
MAGMOM = 1.1
|
||||
#NBANDS = 16
|
||||
NEDOS = 501
|
||||
NELM = 100
|
||||
NELMDL = -7
|
||||
NELMIN = 1
|
||||
NPAR = 4
|
||||
NSIM = 1
|
||||
NSW = 0
|
||||
POTIM = 0.4
|
||||
PREC = Accurate
|
||||
SIGMA = 0.1
|
||||
SMASS = 0.5
|
||||
SYMPREC = 1.0e-6
|
||||
|
||||
# Projectors
|
||||
LOCPROJ = 1 : f : Pr 1
|
@ -1,4 +0,0 @@
|
||||
Automatic kpoint scheme
|
||||
0
|
||||
Gamma
|
||||
4 4 4
|
@ -1,9 +0,0 @@
|
||||
gamma-Ce
|
||||
1.0
|
||||
2.5790000000000000 2.5790000000000000 0.0000000000000000
|
||||
0.0000000000000000 2.5790000000000000 2.5790000000000000
|
||||
2.5790000000000000 0.0000000000000000 2.5790000000000000
|
||||
Ce
|
||||
1
|
||||
Direct
|
||||
0.0 0.0 0.0
|
File diff suppressed because it is too large
Load Diff
@ -1,252 +0,0 @@
|
||||
from math import sqrt
|
||||
from scipy.misc import factorial as fact
|
||||
from itertools import product
|
||||
import numpy as np
|
||||
|
||||
# The interaction matrix in desired basis
|
||||
# U^{spherical}_{m1 m2 m3 m4} = \sum_{k=0}^{2l} F_k angular_matrix_element(l, k, m1, m2, m3, m4)
|
||||
def U_matrix(l, radial_integrals=None, U_int=None, J_hund=None, basis="spherical", T=None):
|
||||
"""Calculate U matrix being given either radial_integrals or U_int and J_hund.
|
||||
l = angular momentum of shell being treated (l=2 for d shell, l=3 for f shell)
|
||||
radial_integrals = [F0,F2,F4,..] (default None)
|
||||
U_int, J_hund = values to use to compute radial_integrals (default None),
|
||||
basis = "spherical", "cubic", or "other",
|
||||
T = transformation matrix from spherical to desired basis, if basis='other' (default None)"""
|
||||
|
||||
# Check all necessary information is present and consistent
|
||||
if radial_integrals is None and (U_int is None and J_hund is None):
|
||||
raise ValueError("U_matrix: provide either the radial_integrals or U_int and J_hund.")
|
||||
if radial_integrals is None and (U_int is not None and J_hund is not None):
|
||||
radial_integrals = U_J_to_radial_integrals(l, U_int, J_hund)
|
||||
if radial_integrals is not None and (U_int is not None and J_hund is not None):
|
||||
if len(radial_integrals)-1 != l:
|
||||
raise ValueError("U_matrix: inconsistency in l and number of radial_integrals provided.")
|
||||
if (radial_integrals - U_J_to_radial_integrals(l, U_int, J_hund)).any() != 0.0:
|
||||
print "Warning: U_matrix: radial_integrals provided do not match U_int and J_hund. Using radial_integrals to calculate spherical U_matrix."
|
||||
|
||||
# Full interaction matrix
|
||||
# Basis of spherical harmonics Y_{-2}, Y_{-1}, Y_{0}, Y_{1}, Y_{2}
|
||||
# U^{spherical}_{m1 m2 m3 m4} = \sum_{k=0}^{2l} F_k angular_matrix_element(l, k, m1, m2, m3, m4)
|
||||
U_matrix = np.zeros((2*l+1,2*l+1,2*l+1,2*l+1),dtype=float)
|
||||
|
||||
m_range = range(-l,l+1)
|
||||
for n, F in enumerate(radial_integrals):
|
||||
k = 2*n
|
||||
for m1, m2, m3, m4 in product(m_range,m_range,m_range,m_range):
|
||||
U_matrix[m1+l,m2+l,m3+l,m4+l] += F * angular_matrix_element(l,k,m1,m2,m3,m4)
|
||||
|
||||
# Transform from spherical basis if needed
|
||||
if basis == "cubic": T = spherical_to_cubic(l)
|
||||
if basis == "other" and T is None:
|
||||
raise ValueError("U_matrix: provide T for other bases.")
|
||||
if T is not None: U_matrix = transform_U_matrix(U_matrix, T)
|
||||
|
||||
return U_matrix
|
||||
|
||||
# Convert full 4-index U matrix to 2-index density-density form
|
||||
def reduce_4index_to_2index(U_4index):
|
||||
"""Reduces the four-index matrix to two-index matrices."""
|
||||
|
||||
size = len(U_4index) # 2l+1
|
||||
U = np.zeros((size,size),dtype=float) # matrix for same spin
|
||||
Uprime = np.zeros((size,size),dtype=float) # matrix for opposite spin
|
||||
|
||||
m_range = range(size)
|
||||
for m,mp in product(m_range,m_range):
|
||||
U[m,mp] = U_4index[m,mp,m,mp].real - U_4index[m,mp,mp,m].real
|
||||
Uprime[m,mp] = U_4index[m,mp,m,mp].real
|
||||
|
||||
return U, Uprime
|
||||
|
||||
# Construct the 2-index matrices for the density-density form
|
||||
def U_matrix_kanamori(n_orb, U_int, J_hund):
|
||||
"""Calculate the Kanamori U and Uprime matrices."""
|
||||
|
||||
U = np.zeros((n_orb,n_orb),dtype=float) # matrix for same spin
|
||||
Uprime = np.zeros((n_orb,n_orb),dtype=float) # matrix for opposite spin
|
||||
|
||||
m_range = range(n_orb)
|
||||
for m,mp in product(m_range,m_range):
|
||||
if m == mp:
|
||||
Uprime[m,mp] = U_int
|
||||
else:
|
||||
U[m,mp] = U_int - 3.0*J_hund
|
||||
Uprime[m,mp] = U_int - 2.0*J_hund
|
||||
|
||||
return U, Uprime
|
||||
|
||||
# Get t2g or eg components
|
||||
def t2g_submatrix(U, convention=''):
|
||||
"""Return only the t2g part of the full d-manifold two- or four-index U matrix."""
|
||||
if convention == 'wien2k':
|
||||
return subarray(U, len(U.shape)*[(2,3,4)])
|
||||
else:
|
||||
return subarray(U, len(U.shape)*[(0,1,3)])
|
||||
|
||||
def eg_submatrix(U, convention=''):
|
||||
"""Return only the eg part of the full d-manifold two- or four-index U matrix."""
|
||||
if convention == 'wien2k':
|
||||
return subarray(U, len(U.shape)*[(0,1)])
|
||||
else:
|
||||
return subarray(U, len(U.shape)*[(2,4)])
|
||||
|
||||
# Transform the interaction matrix into another basis
|
||||
def transform_U_matrix(U_matrix, T):
|
||||
"""Transform the interaction matrix into another basis by applying matrix T."""
|
||||
return np.einsum("ij,kl,jlmo,mn,op",np.conj(T),np.conj(T),U_matrix,np.transpose(T),np.transpose(T))
|
||||
|
||||
# Rotation matrices: complex harmonics to cubic harmonics
|
||||
# Complex harmonics basis: ..., Y_{-2}, Y_{-1}, Y_{0}, Y_{1}, Y_{2}, ...
|
||||
def spherical_to_cubic(l, convention=''):
|
||||
"""Returns the spherical harmonics to cubic harmonics rotation matrix."""
|
||||
size = 2*l+1
|
||||
T = np.zeros((size,size),dtype=complex)
|
||||
if convention != 'wien2k' and l == 2:
|
||||
raise ValueError("spherical_to_cubic: standard convention not implemented for l=1")
|
||||
if l == 0:
|
||||
cubic_names = ("s")
|
||||
elif l == 1:
|
||||
cubic_names = ("x","y","z")
|
||||
T[0,0] = 1.0/sqrt(2); T[0,2] = -1.0/sqrt(2)
|
||||
T[1,0] = 1j/sqrt(2); T[1,2] = 1j/sqrt(2)
|
||||
T[2,1] = 1.0
|
||||
elif l == 2:
|
||||
if convention == 'wien2k':
|
||||
cubic_names = ("z^2","x^2-y^2","xy","yz","xz")
|
||||
T[0,2] = 1.0
|
||||
T[1,0] = 1.0/sqrt(2); T[1,4] = 1.0/sqrt(2)
|
||||
T[2,0] = -1j/sqrt(2); T[2,4] = 1j/sqrt(2)
|
||||
T[3,1] = 1j/sqrt(2); T[3,3] = -1j/sqrt(2)
|
||||
T[4,1] = 1.0/sqrt(2); T[4,3] = 1.0/sqrt(2)
|
||||
else:
|
||||
cubic_names = ("xy","yz","z^2","xz","x^2-y^2")
|
||||
T[0,0] = 1j/sqrt(2); T[0,4] = -1j/sqrt(2)
|
||||
T[1,1] = 1j/sqrt(2); T[1,3] = 1j/sqrt(2)
|
||||
T[2,2] = 1.0
|
||||
T[3,1] = 1.0/sqrt(2); T[3,3] = -1.0/sqrt(2)
|
||||
T[4,0] = 1.0/sqrt(2); T[4,4] = 1.0/sqrt(2)
|
||||
elif l == 3:
|
||||
if convention == 'wien2k':
|
||||
cubic_names = ("x(x^2-3y^2)","z(x^2-y^2)","xz^2","z^3","yz^2","xyz","y(3x^2-y^2)")
|
||||
T[0,0] = 1.0/sqrt(2); T[0,6] = -1.0/sqrt(2)
|
||||
T[1,1] = 1.0/sqrt(2); T[1,5] = 1.0/sqrt(2)
|
||||
T[2,2] = 1.0/sqrt(2); T[2,4] = -1.0/sqrt(2)
|
||||
T[3,5] = 1.0
|
||||
T[4,2] = 1j/sqrt(2); T[4,4] = 1j/sqrt(2)
|
||||
T[5,1] = 1j/sqrt(2); T[5,5] = -1j/sqrt(2)
|
||||
T[6,0] = 1j/sqrt(2); T[6,6] = 1j/sqrt(2)
|
||||
else:
|
||||
cubic_names = ("y(3x^2-y^2)","xyz","yz^2","z^3","xz^2","z(x^2-y^2)","x(x^2-3y^2)")
|
||||
# Verified with the matrix generated in VASP
|
||||
T[0,0] = 1j/sqrt(2); T[0,6] = 1j/sqrt(2)
|
||||
T[1,1] = 1j/sqrt(2); T[1,5] = -1j/sqrt(2)
|
||||
T[2,2] = 1j/sqrt(2); T[2,4] = 1j/sqrt(2)
|
||||
T[3,3] = 1.0
|
||||
T[4,2] = 1.0/sqrt(2); T[4,4] = -1.0/sqrt(2)
|
||||
T[5,1] = 1.0/sqrt(2); T[5,5] = 1.0/sqrt(2)
|
||||
T[6,0] = 1.0/sqrt(2); T[6,6] = -1.0/sqrt(2)
|
||||
else: raise ValueError("spherical_to_cubic: implemented only for l=0,1,2,3")
|
||||
|
||||
return T
|
||||
|
||||
# Names of cubic harmonics
|
||||
def cubic_names(l):
|
||||
if l == 0 or l == 's':
|
||||
return ("s")
|
||||
elif l == 1 or l == 'p':
|
||||
return ("x","y","z")
|
||||
elif l == 2 or l == 'd':
|
||||
return ("xy","yz","z^2","xz","x^2-y^2")
|
||||
elif l == 't2g':
|
||||
return ("xy","yz","xz")
|
||||
elif l == 'eg':
|
||||
return ("z^2","x^2-y^2")
|
||||
elif l == 3 or l == 'f':
|
||||
return ("x(x^2-3y^2)","z(x^2-y^2)","xz^2","z^3","yz^2","xyz","y(3x^2-y^2)")
|
||||
else: raise ValueError("cubic_names: implemented only for l=0,1,2,3")
|
||||
|
||||
# Convert U,J -> radial integrals F_k
|
||||
def U_J_to_radial_integrals(l, U_int, J_hund):
|
||||
"""Determines the radial integrals F_k from U_int and J_hund."""
|
||||
|
||||
F = np.zeros((l+1),dtype=float)
|
||||
if l == 2:
|
||||
F[0] = U_int
|
||||
F[1] = J_hund * 14.0 / (1.0 + 0.63)
|
||||
F[2] = 0.630 * F[1]
|
||||
elif l == 3:
|
||||
F[0] = U_int
|
||||
F[1] = 6435.0 * J_hund / (286.0 + 195.0 * 451.0 / 675.0 + 250.0 * 1001.0 / 2025.0)
|
||||
F[2] = 451.0 * F[1] / 675.0
|
||||
F[3] = 1001.0 * F[1] / 2025.0
|
||||
else: raise ValueError("U_J_to_radial_integrals: implemented only for l=2,3")
|
||||
|
||||
return F
|
||||
|
||||
# Convert radial integrals F_k -> U,J
|
||||
def radial_integrals_to_U_J(l, F):
|
||||
"""Determines U_int and J_hund from the radial integrals."""
|
||||
|
||||
if l == 2:
|
||||
U_int = F[0]
|
||||
J_hund = F[1] * (1.0 + 0.63) / 14.0
|
||||
elif l == 3:
|
||||
U_int = F[0]
|
||||
J_hund = F[1] * (286.0 + 195.0 * 451.0 / 675.0 + 250.0 * 1001.0 / 2025.0) / 6435.0
|
||||
else: raise ValueError("radial_integrals_to_U_J: implemented only for l=2,3")
|
||||
|
||||
return U_int,J_hund
|
||||
|
||||
# Angular matrix elements of particle-particle interaction
|
||||
# (2l+1)^2 ((l 0) (k 0) (l 0))^2 \sum_{q=-k}^{k} (-1)^{m1+m2+q} ((l -m1) (k q) (l m3)) ((l -m2) (k -q) (l m4))
|
||||
def angular_matrix_element(l, k, m1, m2, m3, m4):
|
||||
result = 0
|
||||
for q in range(-k,k+1):
|
||||
result += three_j_symbol((l,-m1),(k,q),(l,m3))*three_j_symbol((l,-m2),(k,-q),(l,m4))*(-1.0 if (m1+q+m2) % 2 else 1.0)
|
||||
result *= (2*l+1)**2 * (three_j_symbol((l,0),(k,0),(l,0))**2)
|
||||
return result
|
||||
|
||||
# Wigner 3-j symbols
|
||||
# ((j1 m1) (j2 m2) (j3 m3))
|
||||
def three_j_symbol(jm1, jm2, jm3):
|
||||
j1, m1 = jm1
|
||||
j2, m2 = jm2
|
||||
j3, m3 = jm3
|
||||
|
||||
if (m1+m2+m3 != 0 or
|
||||
m1 < -j1 or m1 > j1 or
|
||||
m2 < -j2 or m2 > j2 or
|
||||
m3 < -j3 or m3 > j3 or
|
||||
j3 > j1 + j2 or
|
||||
j3 < abs(j1-j2)):
|
||||
return .0
|
||||
|
||||
result = -1.0 if (j1-j2-m3) % 2 else 1.0
|
||||
result *= sqrt(fact(j1+j2-j3)*fact(j1-j2+j3)*fact(-j1+j2+j3)/fact(j1+j2+j3+1))
|
||||
result *= sqrt(fact(j1-m1)*fact(j1+m1)*fact(j2-m2)*fact(j2+m2)*fact(j3-m3)*fact(j3+m3))
|
||||
|
||||
t_min = max(j2-j3-m1,j1-j3+m2,0)
|
||||
t_max = min(j1-m1,j2+m2,j1+j2-j3)
|
||||
|
||||
t_sum = 0
|
||||
for t in range(t_min,t_max+1):
|
||||
t_sum += (-1.0 if t % 2 else 1.0)/(fact(t)*fact(j3-j2+m1+t)*fact(j3-j1-m2+t)*fact(j1+j2-j3-t)*fact(j1-m1-t)*fact(j2+m2-t))
|
||||
|
||||
result *= t_sum
|
||||
return result
|
||||
|
||||
# Clebsch-Gordan coefficients
|
||||
# < j1 m1 j2 m2 | j3 m3 > = (-1)^{j1-j2+m3} \sqrt{2j3+1} ((j1 m1) (j2 m2) (j3 -m3))
|
||||
def clebsch_gordan(jm1, jm2, jm3):
|
||||
norm = sqrt(2*jm3[0]+1)*(-1 if jm1[0]-jm2[0]+jm3[1] % 2 else 1)
|
||||
return norm*three_j_symbol(jm1,jm2,(jm3[0],-jm3[1]))
|
||||
|
||||
# Create subarray containing columns in idxlist
|
||||
# e.g. idxlist = [(0),(2,3),(0,1,2,3)] gives
|
||||
# column 0 for 1st dim,
|
||||
# columns 2 and 3 for 2nd dim,
|
||||
# columns 0,1,2 and 3 for 3rd dim.
|
||||
def subarray(a,idxlist,n=None) :
|
||||
if n is None: n = len(a.shape)-1
|
||||
sa = a[tuple(slice(x) for x in a.shape[:n]) + (idxlist[n],)]
|
||||
return subarray(sa,idxlist, n-1) if n > 0 else sa
|
@ -1,335 +0,0 @@
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||
#
|
||||
# Copyright (C) 2011 by M. Ferrero, O. Parcollet
|
||||
#
|
||||
# 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 types import *
|
||||
#from triqs_dft_tools.U_matrix import *
|
||||
from U_matrix import *
|
||||
from pytriqs.gf import *
|
||||
#from hubbard_I import gf_hi_fullu, sigma_atomic_fullu
|
||||
import pytriqs.utility.mpi as mpi
|
||||
from itertools import izip
|
||||
import numpy
|
||||
import copy
|
||||
|
||||
class Solver:
|
||||
"""
|
||||
Hartree-Fock Solver
|
||||
"""
|
||||
|
||||
# initialisation:
|
||||
def __init__(self, beta, l, n_msb=1025, use_spin_orbit=False, Nmoments=5, dudarev=False):
|
||||
|
||||
self.name = "Hartree-Fock"
|
||||
self.beta = beta
|
||||
self.l = l
|
||||
self.Nmsb = n_msb
|
||||
self.UseSpinOrbit = use_spin_orbit
|
||||
self.Converged = False
|
||||
self.Nspin = 2
|
||||
self.Nmoments=Nmoments
|
||||
|
||||
self.dudarev = dudarev
|
||||
|
||||
assert use_spin_orbit == False, "Spin-orbit is not implemented"
|
||||
|
||||
self.Nlm = 2*l+1
|
||||
if (use_spin_orbit):
|
||||
# no blocks!
|
||||
self.gf_struct = [ ('ud', range(2*self.Nlm)) ]
|
||||
else:
|
||||
# up/down blocks:
|
||||
self.gf_struct = [ ('up', range(self.Nlm)), ('down', range(self.Nlm)) ]
|
||||
|
||||
# construct Greens functions:
|
||||
self.a_list = [a for a,al in self.gf_struct]
|
||||
glist = lambda : [ GfImFreq(indices = al, beta = self.beta, n_points = self.Nmsb) for a,al in self.gf_struct]
|
||||
self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False)
|
||||
self.G_Old = self.G.copy()
|
||||
self.G0 = self.G.copy()
|
||||
self.Sigma = self.G.copy()
|
||||
self.Sigma_Old = self.G.copy()
|
||||
|
||||
|
||||
|
||||
def solve(self, U_int, J_hund, T=None, verbosity=0, Iteration_Number=1, Test_Convergence=0.0001):
|
||||
"""Calculation of the impurity Greens function using Hubbard-I"""
|
||||
|
||||
if self.Converged :
|
||||
mpi.report("Solver %(name)s has already converged: SKIPPING"%self.__dict__)
|
||||
return
|
||||
|
||||
if mpi.is_master_node():
|
||||
self.verbosity = verbosity
|
||||
else:
|
||||
self.verbosity = 0
|
||||
|
||||
#self.Nmoments = 5
|
||||
|
||||
ur,ujmn,umn=self.__set_umatrix(U=U_int,J=J_hund,T=T)
|
||||
|
||||
|
||||
M = [x for x in self.G.mesh]
|
||||
self.zmsb = numpy.array([x for x in M],numpy.complex_)
|
||||
|
||||
# # for the tails:
|
||||
# tailtempl={}
|
||||
# for sig,g in self.G:
|
||||
# tailtempl[sig] = copy.deepcopy(g.tail)
|
||||
# for i in range(9): tailtempl[sig][i] *= 0.0
|
||||
|
||||
# self.__save_eal('eal.dat',Iteration_Number)
|
||||
|
||||
# mpi.report( "Starting Fortran solver %(name)s"%self.__dict__)
|
||||
|
||||
self.Sigma_Old <<= self.Sigma
|
||||
self.G_Old <<= self.G
|
||||
|
||||
# # call the fortran solver:
|
||||
# temp = 1.0/self.beta
|
||||
# gf,tail,self.atocc,self.atmag = gf_hi_fullu(e0f=self.ealmat, ur=ur, umn=umn, ujmn=ujmn,
|
||||
# zmsb=self.zmsb, nmom=self.Nmoments, ns=self.Nspin, temp=temp, verbosity = self.verbosity)
|
||||
|
||||
#self.sig = sigma_atomic_fullu(gf=self.gf,e0f=self.eal,zmsb=self.zmsb,ns=self.Nspin,nlm=self.Nlm)
|
||||
def print_matrix(m):
|
||||
for row in m:
|
||||
print ''.join(map("{0:12.7f}".format, row))
|
||||
|
||||
|
||||
# Hartree-Fock solver
|
||||
self.Sigma.zero()
|
||||
dm = self.G.density()
|
||||
if mpi.is_master_node():
|
||||
# print
|
||||
# print " Reduced U-matrix:"
|
||||
# print " U:"
|
||||
# print_matrix(ujmn)
|
||||
# print " Up:"
|
||||
# print_matrix(umn)
|
||||
#
|
||||
## sig_test = {bl: numpy.zeros((self.Nlm, self.Nlm)) for bl in dm}
|
||||
# sig_test = {}
|
||||
# sig_test['up'] = numpy.dot(umn, dm['up'].real) + numpy.dot(ujmn, dm['down'].real)
|
||||
# sig_test['down'] = numpy.dot(umn, dm['down'].real) + numpy.dot(ujmn, dm['up'].real)
|
||||
# print " Sigma test:"
|
||||
# print_matrix(sig_test['up'])
|
||||
print
|
||||
print " Density matrix (up):"
|
||||
print_matrix(dm['up'])
|
||||
print
|
||||
print " Density matrix (down):"
|
||||
print_matrix(dm['down'])
|
||||
|
||||
if self.dudarev:
|
||||
Ueff = U_int - J_hund
|
||||
corr_energy = 0.0
|
||||
dft_dc = 0.0
|
||||
for bl1 in dm:
|
||||
# (U - J) * (1/2 - n)
|
||||
self.Sigma[bl1] << Ueff * (0.5 * numpy.identity(self.Nlm) - dm[bl1])
|
||||
# 1/2 (U - J) * \sum_{\sig} [\sum_{m} n_{m,m \sig} - \sum_{m1,m2} n_{m1,m2 \sig} n_{m2,m1 \sig}]
|
||||
corr_energy += 0.5 * Ueff * (dm[bl1].trace() - (dm[bl1]*dm[bl1].conj()).sum()).real
|
||||
# V[n] * n^{\dagger}
|
||||
dft_dc += (self.Sigma[bl1](0) * dm[bl1].conj()).sum().real
|
||||
|
||||
else:
|
||||
# !!!!!
|
||||
# !!!!! Mind the order of indices in the 4-index matrix!
|
||||
# !!!!!
|
||||
for il1 in xrange(self.Nlm):
|
||||
for il2 in xrange(self.Nlm):
|
||||
for il3 in xrange(self.Nlm):
|
||||
for il4 in xrange(self.Nlm):
|
||||
for bl1 in dm:
|
||||
for bl2 in dm:
|
||||
self.Sigma[bl1][il1, il2] += ur[il1, il3, il2, il4] * dm[bl2][il3, il4]
|
||||
if bl1 == bl2:
|
||||
self.Sigma[bl1][il1, il2] -= ur[il1, il3, il4, il2] * dm[bl1][il3, il4]
|
||||
|
||||
if mpi.is_master_node() and self.verbosity > 0:
|
||||
print
|
||||
print " Sigma (up):"
|
||||
print_matrix(self.Sigma['up'](0).real)
|
||||
print
|
||||
print " Sigma (down):"
|
||||
print_matrix(self.Sigma['down'](0).real)
|
||||
# if (self.verbosity==0):
|
||||
# # No fortran output, so give basic results here
|
||||
# mpi.report("Atomic occupancy in Hubbard I Solver : %s"%self.atocc)
|
||||
# mpi.report("Atomic magn. mom. in Hubbard I Solver : %s"%self.atmag)
|
||||
|
||||
# transfer the data to the GF class:
|
||||
if (self.UseSpinOrbit):
|
||||
nlmtot = self.Nlm*2 # only one block in this case!
|
||||
else:
|
||||
nlmtot = self.Nlm
|
||||
|
||||
# M={}
|
||||
# isp=-1
|
||||
# for a,al in self.gf_struct:
|
||||
# isp+=1
|
||||
# M[a] = numpy.array(gf[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot,:]).transpose(2,0,1).copy()
|
||||
# for i in range(min(self.Nmoments,8)):
|
||||
# tailtempl[a][i+1] = tail[i][isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot]
|
||||
#
|
||||
# #glist = lambda : [ GfImFreq(indices = al, beta = self.beta, n_points = self.Nmsb, data =M[a], tail =self.tailtempl[a])
|
||||
# # for a,al in self.gf_struct]
|
||||
# glist = lambda : [ GfImFreq(indices = al, beta = self.beta, n_points = self.Nmsb) for a,al in self.gf_struct]
|
||||
# self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False)
|
||||
#
|
||||
# self.__copy_Gf(self.G,M,tailtempl)
|
||||
#
|
||||
# # Self energy:
|
||||
# self.G0 <<= iOmega_n
|
||||
#
|
||||
# M = [ self.ealmat[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot] for isp in range((2*self.Nlm)/nlmtot) ]
|
||||
# self.G0 -= M
|
||||
# self.Sigma <<= self.G0 - inverse(self.G)
|
||||
#
|
||||
# # invert G0
|
||||
# self.G0.invert()
|
||||
|
||||
def test_distance(G1,G2, dist) :
|
||||
def f(G1,G2) :
|
||||
#print abs(G1.data - G2.data)
|
||||
dS = max(abs(G1.data - G2.data).flatten())
|
||||
aS = max(abs(G1.data).flatten())
|
||||
if mpi.is_master_node():
|
||||
print " Distances:", dS, " vs ", aS * dist
|
||||
return dS <= aS*dist
|
||||
return reduce(lambda x,y : x and y, [f(g1,g2) for (i1,g1),(i2,g2) in izip(G1,G2)])
|
||||
|
||||
mpi.report("\nChecking Sigma for convergence...\nUsing tolerance %s"%Test_Convergence)
|
||||
self.Converged = test_distance(self.Sigma,self.Sigma_Old,Test_Convergence)
|
||||
|
||||
if self.Converged :
|
||||
mpi.report("Solver HAS CONVERGED")
|
||||
else :
|
||||
mpi.report("Solver has not yet converged")
|
||||
|
||||
return corr_energy, dft_dc
|
||||
|
||||
|
||||
def GF_realomega(self, ommin, ommax, N_om, U_int, J_hund, T=None, verbosity=0, broadening=0.01):
|
||||
"""Calculates the GF and spectral function on the real axis."""
|
||||
|
||||
delta_om = (ommax-ommin)/(1.0*(N_om-1))
|
||||
|
||||
omega = numpy.zeros([N_om],numpy.complex_)
|
||||
|
||||
ur,umn,ujmn=self.__set_umatrix(U=U_int,J=J_hund,T=T)
|
||||
|
||||
for i in range(N_om):
|
||||
omega[i] = ommin + delta_om * i + 1j * broadening
|
||||
|
||||
tailtempl={}
|
||||
for sig,g in self.G:
|
||||
tailtempl[sig] = copy.deepcopy(g.tail)
|
||||
for i in range(9): tailtempl[sig][i] *= 0.0
|
||||
|
||||
temp = 1.0/self.beta
|
||||
gf,tail,self.atocc,self.atmag = gf_hi_fullu(e0f=self.ealmat, ur=ur, umn=umn, ujmn=ujmn,
|
||||
zmsb=omega, nmom=self.Nmoments, ns=self.Nspin, temp=temp, verbosity = verbosity)
|
||||
|
||||
# transfer the data to the GF class:
|
||||
if (self.UseSpinOrbit):
|
||||
nlmtot = self.Nlm*2 # only one block in this case!
|
||||
else:
|
||||
nlmtot = self.Nlm
|
||||
|
||||
M={}
|
||||
isp=-1
|
||||
for a,al in self.gf_struct:
|
||||
isp+=1
|
||||
M[a] = numpy.array(gf[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot,:]).transpose(2,0,1).copy()
|
||||
for i in range(min(self.Nmoments,8)):
|
||||
tailtempl[a][i+1] = tail[i][isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot]
|
||||
|
||||
#glist = lambda : [ GfReFreq(indices = al, window = (ommin, ommax), n_points = N_om, data = M[a], tail = self.tailtempl[a])
|
||||
# for a,al in self.gf_struct] # Indices for the upfolded G
|
||||
glist = lambda : [ GfReFreq(indices = al, window = (ommin, ommax), n_points = N_om) for a,al in self.gf_struct]
|
||||
self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False)
|
||||
|
||||
self.__copy_Gf(self.G,M,tailtempl)
|
||||
|
||||
# Self energy:
|
||||
self.G0 = self.G.copy()
|
||||
self.Sigma = self.G.copy()
|
||||
self.G0 <<= Omega + 1j*broadening
|
||||
|
||||
M = [ self.ealmat[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot] for isp in range((2*self.Nlm)/nlmtot) ]
|
||||
self.G0 -= M
|
||||
self.Sigma <<= self.G0 - inverse(self.G)
|
||||
self.Sigma.note='ReFreq' # This is important for the put_Sigma routine!!!
|
||||
|
||||
#sigmamat = sigma_atomic_fullu(gf=gf,e0f=self.ealmat,zmsb=omega,nlm=self.Nlm,ns=self.Nspin)
|
||||
|
||||
#return omega,gf,sigmamat
|
||||
|
||||
|
||||
def __save_eal(self,Filename,it):
|
||||
f=open(Filename,'a')
|
||||
f.write('\neff. atomic levels, Iteration %s\n'%it)
|
||||
for i in range(self.Nlm*self.Nspin):
|
||||
for j in range(self.Nlm*self.Nspin):
|
||||
f.write("%10.6f %10.6f "%(self.ealmat[i,j].real,self.ealmat[i,j].imag))
|
||||
f.write("\n")
|
||||
f.close()
|
||||
|
||||
def __copy_Gf(self,G,data,tail):
|
||||
""" Copies data and tail to Gf object GF """
|
||||
for s,g in G:
|
||||
g.data[:,:,:]=data[s][:,:,:]
|
||||
for imom in range(1,min(self.Nmoments,8)):
|
||||
g.tail.data[1+imom,:,:]=tail[s][imom]
|
||||
|
||||
|
||||
def set_atomic_levels(self,eal):
|
||||
""" Helps to set correctly the variables for the atomic levels from a dictionary."""
|
||||
|
||||
assert (type(eal)==DictType), "Give a dictionary to set_atomic_levels!"
|
||||
|
||||
cnt = 0
|
||||
self.ealmat[:,:] *= 0.0
|
||||
|
||||
for ind in eal:
|
||||
self.Eff_Atomic_Levels[ind] = copy.deepcopy(eal[ind])
|
||||
|
||||
if self.UseSpinOrbit:
|
||||
for ii in range(self.Nlm*2):
|
||||
for jj in range(self.Nlm*2):
|
||||
self.ealmat[ii,jj] = self.Eff_Atomic_Levels[ind][ii,jj]
|
||||
else:
|
||||
for ii in range(self.Nlm):
|
||||
for jj in range(self.Nlm):
|
||||
self.ealmat[cnt*self.Nlm + ii,cnt*self.Nlm + jj] = self.Eff_Atomic_Levels[ind][ii,jj]
|
||||
|
||||
cnt += 1
|
||||
|
||||
|
||||
def __set_umatrix(self,U,J,T=None):
|
||||
# U matrix:
|
||||
# l = (Nlm-1)/2
|
||||
# If T is specified, it is used to transform the Basis set
|
||||
Umat = U_matrix(l=self.l, U_int=U, J_hund=J, basis='cubic', T=T)
|
||||
U, Up = reduce_4index_to_2index(Umat)
|
||||
|
||||
return Umat, U, Up
|
@ -1,15 +0,0 @@
|
||||
[General]
|
||||
#EFERMI =
|
||||
#BASENAME = plo_vasp
|
||||
#DOSMESH = -5.0 10.0 4001
|
||||
|
||||
[Group 1]
|
||||
SHELLS = 1
|
||||
NORMALIZE = False
|
||||
EWINDOW = -41.45 41.8
|
||||
|
||||
[Shell 1]
|
||||
LSHELL = 3
|
||||
IONS = 1
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
PYTHONPATH=$HOME/Codes/triqs/triqs1.2/applications/dft_tools/dev_src/python:$HOME/Codes/triqs/triqs1.2/applications/dft_tools/dev_src/c:$PYTHONPATH pytriqs $@
|
@ -1,2 +0,0 @@
|
||||
PLOVASP_PATH=$HOME/Codes/triqs/triqs1.2/applications/dft_tools/dev_src
|
||||
PYTHONPATH=$PLOVASP_PATH/python:$PLOVASP_PATH/c:$PYTHONPATH pytriqs $PLOVASP_PATH/python/converters/plovasp/main.py $@
|
@ -1,164 +0,0 @@
|
||||
|
||||
import os
|
||||
import errno
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
import pytriqs.utility.mpi as mpi
|
||||
import converters.plovasp.main as plovasp
|
||||
from test_ham_hf import dmft_cycle
|
||||
|
||||
debug = True
|
||||
#
|
||||
# Helper functions
|
||||
#
|
||||
def sigint_handler(signal, frame):
|
||||
raise SystemExit(1)
|
||||
|
||||
def is_vasp_lock_present():
|
||||
return os.path.isfile('./vasp.lock')
|
||||
|
||||
def is_vasp_running(vasp_pid):
|
||||
"""
|
||||
Tests if VASP initial process is still alive.
|
||||
"""
|
||||
pid_exists = False
|
||||
if mpi.is_master_node():
|
||||
try:
|
||||
os.kill(vasp_pid, 0)
|
||||
except OSError, e:
|
||||
pid_exists = e.errno == errno.EPERM
|
||||
else:
|
||||
pid_exists = True
|
||||
|
||||
pid_exists = mpi.bcast(pid_exists)
|
||||
return pid_exists
|
||||
|
||||
def get_dft_energy():
|
||||
"""
|
||||
Reads energy from the last line of OSZICAR.
|
||||
"""
|
||||
with open('OSZICAR', 'r') as f:
|
||||
nextline = f.readline()
|
||||
while nextline.strip():
|
||||
line = nextline
|
||||
nextline = f.readline()
|
||||
# print "OSZICAR: ", line[:-1]
|
||||
|
||||
try:
|
||||
dft_energy = float(line.split()[2])
|
||||
except ValueError:
|
||||
print "Cannot read energy from OSZICAR, setting it to zero"
|
||||
dft_energy = 0.0
|
||||
|
||||
return dft_energy
|
||||
|
||||
class bcolors:
|
||||
MAGENTA = '\033[95m'
|
||||
BLUE = '\033[94m'
|
||||
GREEN = '\033[92m'
|
||||
YELLOW = '\033[93m'
|
||||
RED = '\033[91m'
|
||||
ENDC = '\033[0m'
|
||||
#
|
||||
# Main self-consistent cycle
|
||||
#
|
||||
def run_all(vasp_pid):
|
||||
"""
|
||||
"""
|
||||
mpi.report(" Waiting for VASP lock to appear...")
|
||||
while not is_vasp_lock_present():
|
||||
time.sleep(1)
|
||||
|
||||
vasp_running = True
|
||||
|
||||
while vasp_running:
|
||||
if debug: print bcolors.RED + "rank %s"%(mpi.rank) + bcolors.ENDC
|
||||
mpi.report(" Waiting for VASP lock to disappear...")
|
||||
mpi.barrier()
|
||||
while is_vasp_lock_present():
|
||||
time.sleep(1)
|
||||
# if debug: print bcolors.YELLOW + " waiting: rank %s"%(mpi.rank) + bcolors.ENDC
|
||||
if not is_vasp_running(vasp_pid):
|
||||
mpi.report(" VASP stopped")
|
||||
vasp_running = False
|
||||
break
|
||||
|
||||
if debug: print bcolors.MAGENTA + "rank %s"%(mpi.rank) + bcolors.ENDC
|
||||
err = 0
|
||||
exc = None
|
||||
try:
|
||||
if debug: print bcolors.BLUE + "plovasp: rank %s"%(mpi.rank) + bcolors.ENDC
|
||||
if mpi.is_master_node():
|
||||
plovasp.generate_and_output_as_text('plo.cfg', vasp_dir='./')
|
||||
# Read energy from OSZICAR
|
||||
dft_energy = get_dft_energy()
|
||||
except Exception, exc:
|
||||
err = 1
|
||||
|
||||
err = mpi.bcast(err)
|
||||
if err:
|
||||
if mpi.is_master_node():
|
||||
raise exc
|
||||
else:
|
||||
raise SystemExit(1)
|
||||
|
||||
mpi.barrier()
|
||||
|
||||
try:
|
||||
if debug: print bcolors.GREEN + "rank %s"%(mpi.rank) + bcolors.ENDC
|
||||
corr_energy, dft_dc = dmft_cycle()
|
||||
except:
|
||||
if mpi.is_master_node():
|
||||
print " master forwarding the exception..."
|
||||
raise
|
||||
else:
|
||||
print " rank %i exiting..."%(mpi.rank)
|
||||
raise SystemExit(1)
|
||||
mpi.barrier()
|
||||
|
||||
if mpi.is_master_node():
|
||||
total_energy = dft_energy + corr_energy - dft_dc
|
||||
print
|
||||
print "="*80
|
||||
print " Total energy: ", total_energy
|
||||
print " DFT energy: ", dft_energy
|
||||
print " Corr. energy: ", corr_energy
|
||||
print " DFT DC: ", dft_dc
|
||||
print "="*80
|
||||
print
|
||||
|
||||
if mpi.is_master_node() and vasp_running:
|
||||
open('./vasp.lock', 'a').close()
|
||||
|
||||
if mpi.is_master_node():
|
||||
total_energy = dft_energy + corr_energy - dft_dc
|
||||
with open('TOTENERGY', 'w') as f:
|
||||
f.write(" Total energy: %s\n"%(total_energy))
|
||||
f.write(" DFT energy: %s\n"%(dft_energy))
|
||||
f.write(" Corr. energy: %s\n"%(corr_energy))
|
||||
f.write(" DFT DC: %s\n"%(dft_dc))
|
||||
f.write(" Energy correction: %s\n"%(corr_energy - dft_dc))
|
||||
|
||||
mpi.report("***Done")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
vasp_pid = int(sys.argv[1])
|
||||
except (ValueError, KeyError):
|
||||
if mpi.is_master_node():
|
||||
print "VASP process pid must be provided as the first argument"
|
||||
raise
|
||||
# if len(sys.argv) > 1:
|
||||
# vasp_path = sys.argv[1]
|
||||
# else:
|
||||
# try:
|
||||
# vasp_path = os.environ['VASP_DIR']
|
||||
# except KeyError:
|
||||
# if mpi.is_master_node():
|
||||
# print "Path to VASP must be specified either as an argument of in VASP_DIR"
|
||||
# raise
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
|
||||
run_all(vasp_pid)
|
@ -1,9 +0,0 @@
|
||||
#/bin/bash
|
||||
|
||||
NPROC=8
|
||||
|
||||
rm -f vasp.lock
|
||||
stdbuf -o 0 mpirun -np $NPROC ~/Codes/vasp/build_20151202/vasp.5.4.2/build/std/vasp &
|
||||
|
||||
mpirun -np $NPROC ./run_build.sh sc_dmft.py $(jobs -p) || kill %1
|
||||
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash -l
|
||||
#
|
||||
#SBATCH --job-name="JOBNAME"
|
||||
#SBATCH --time=36:00:00
|
||||
##SBATCH --nodes=8
|
||||
#SBATCH --ntasks=8
|
||||
#SBATCH --partition=qmac
|
||||
##SBATCH --mem-per-cpu=1024
|
||||
#SBATCH --output=job.%j.o
|
||||
#SBATCH --error=job.%j.e
|
||||
|
||||
#======START=====
|
||||
# source $HOME/.profile
|
||||
# export KMP_AFFINITY=none
|
||||
|
||||
# module load slurm
|
||||
source /cm/shared/apps/intel/composer_xe/composer_xe_2015.0.090/mkl/bin/mklvars.sh intel64
|
||||
# module switch PrgEnv-gnu PrgEnv-intel
|
||||
# module load intel/14.0.2.144
|
||||
#module load intel/mkl/64/11.2/2015.0.090
|
||||
|
||||
export OMP_NUM_THREADS=1
|
||||
|
||||
VASP_DIR=$HOME/Codes/vasp/build_20151202/vasp.5.4.2/build/std
|
||||
#mpirun -np $SLURM_NTASKS $VASP_DIR/vasp
|
||||
./sc_dmft.sh
|
||||
|
||||
|
@ -1,437 +0,0 @@
|
||||
#from triqs_dft_tools.sumk_dft import *
|
||||
from sumk_dft import *
|
||||
#from triqs_dft_tools.converters.wien2k_converter import *
|
||||
from converters.vasp_converter import *
|
||||
#from pytriqs.applications.impurity_solvers.hubbard_I.hubbard_solver import Solver
|
||||
from hf_solver import Solver
|
||||
import shutil
|
||||
|
||||
class TestSumkDFT(SumkDFT):
|
||||
# calculate and save occupancy matrix in the Bloch basis for VASP charge denity recalculation
|
||||
def calc_density_correction(self, filename='GAMMA', dm_type='wien2k'):
|
||||
r"""
|
||||
Calculates the charge density correction and stores it into a file.
|
||||
|
||||
The charge density correction is needed for charge-self-consistent DFT+DMFT calculations.
|
||||
It represents a density matrix of the interacting system defined in Bloch basis
|
||||
and it is calculated from the sum over Matsubara frequecies of the full GF,
|
||||
|
||||
..math:: N_{\nu\nu'}(k) = \sum_{i\omega_{n}} G_{\nu\nu'}(k, i\omega_{n})
|
||||
|
||||
The density matrix for every `k`-point is stored into a file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : string
|
||||
Name of the file to store the charge density correction.
|
||||
|
||||
Returns
|
||||
-------
|
||||
(deltaN, dens) : tuple
|
||||
Returns a tuple containing the density matrix `deltaN` and
|
||||
the corresponing total charge `dens`.
|
||||
|
||||
"""
|
||||
assert type(filename) == StringType, "calc_density_correction: filename has to be a string!"
|
||||
assert dm_type in ('vasp', 'wien2k'), "'type' must be either 'vasp' or 'wienk'"
|
||||
|
||||
ntoi = self.spin_names_to_ind[self.SO]
|
||||
spn = self.spin_block_names[self.SO]
|
||||
dens = {sp: 0.0 for sp in spn}
|
||||
|
||||
# Fetch Fermi weights and energy window band indices
|
||||
if dm_type == 'vasp':
|
||||
fermi_weights = 0
|
||||
band_window = 0
|
||||
if mpi.is_master_node():
|
||||
with HDFArchive(self.hdf_file,'r') as ar:
|
||||
fermi_weights = ar['dft_misc_input']['dft_fermi_weights']
|
||||
band_window = ar['dft_misc_input']['band_window']
|
||||
fermi_weights = mpi.bcast(fermi_weights)
|
||||
band_window = mpi.bcast(band_window)
|
||||
|
||||
# Convert Fermi weights to a density matrix
|
||||
dens_mat_dft = {}
|
||||
for sp in spn:
|
||||
dens_mat_dft[sp] = [fermi_weights[ik, ntoi[sp], :].astype(numpy.complex_) for ik in xrange(self.n_k)]
|
||||
|
||||
# Set up deltaN:
|
||||
deltaN = {}
|
||||
for sp in spn:
|
||||
deltaN[sp] = [numpy.zeros([self.n_orbitals[ik,ntoi[sp]],self.n_orbitals[ik,ntoi[sp]]], numpy.complex_) for ik in range(self.n_k)]
|
||||
|
||||
ikarray = numpy.array(range(self.n_k))
|
||||
for ik in mpi.slice_array(ikarray):
|
||||
G_latt_iw = self.lattice_gf(ik = ik, mu = self.chemical_potential, iw_or_w = "iw")
|
||||
for bname,gf in G_latt_iw:
|
||||
deltaN[bname][ik][:, :] = G_latt_iw[bname].density()
|
||||
dens[bname] += self.bz_weights[ik] * G_latt_iw[bname].total_density()
|
||||
if dm_type == 'vasp':
|
||||
# In 'vasp'-mode subtract the DFT density matrix
|
||||
diag_inds = numpy.diag_indices(self.n_orbitals[ik, ntoi[bname]])
|
||||
deltaN[bname][ik][diag_inds] -= dens_mat_dft[bname][ik]
|
||||
dens[bname] -= self.bz_weights[ik] * dens_mat_dft[bname][ik].sum().real
|
||||
|
||||
# mpi reduce:
|
||||
for bname in deltaN:
|
||||
for ik in range(self.n_k):
|
||||
deltaN[bname][ik] = mpi.all_reduce(mpi.world, deltaN[bname][ik], lambda x,y : x+y)
|
||||
dens[bname] = mpi.all_reduce(mpi.world, dens[bname], lambda x,y : x+y)
|
||||
mpi.barrier()
|
||||
|
||||
# now save to file:
|
||||
if dm_type == 'wien2k':
|
||||
if mpi.is_master_node():
|
||||
if self.SP == 0:
|
||||
f = open(filename,'w')
|
||||
else:
|
||||
f = open(filename+'up','w')
|
||||
f1 = open(filename+'dn','w')
|
||||
# write chemical potential (in Rydberg):
|
||||
f.write("%.14f\n"%(self.chemical_potential/self.energy_unit))
|
||||
if self.SP != 0: f1.write("%.14f\n"%(self.chemical_potential/self.energy_unit))
|
||||
# write beta in rydberg-1
|
||||
f.write("%.14f\n"%(G_latt_iw.mesh.beta*self.energy_unit))
|
||||
if self.SP != 0: f1.write("%.14f\n"%(G_latt_iw.mesh.beta*self.energy_unit))
|
||||
|
||||
if self.SP == 0: # no spin-polarization
|
||||
|
||||
for ik in range(self.n_k):
|
||||
f.write("%s\n"%self.n_orbitals[ik,0])
|
||||
for inu in range(self.n_orbitals[ik,0]):
|
||||
for imu in range(self.n_orbitals[ik,0]):
|
||||
valre = (deltaN['up'][ik][inu,imu].real + deltaN['down'][ik][inu,imu].real) / 2.0
|
||||
valim = (deltaN['up'][ik][inu,imu].imag + deltaN['down'][ik][inu,imu].imag) / 2.0
|
||||
f.write("%.14f %.14f "%(valre,valim))
|
||||
f.write("\n")
|
||||
f.write("\n")
|
||||
f.close()
|
||||
|
||||
elif self.SP == 1: # with spin-polarization
|
||||
|
||||
# dict of filename: (spin index, block_name)
|
||||
if self.SO == 0: to_write = {f: (0, 'up'), f1: (1, 'down')}
|
||||
if self.SO == 1: to_write = {f: (0, 'ud'), f1: (0, 'ud')}
|
||||
for fout in to_write.iterkeys():
|
||||
isp, sp = to_write[fout]
|
||||
for ik in range(self.n_k):
|
||||
fout.write("%s\n"%self.n_orbitals[ik,isp])
|
||||
for inu in range(self.n_orbitals[ik,isp]):
|
||||
for imu in range(self.n_orbitals[ik,isp]):
|
||||
fout.write("%.14f %.14f "%(deltaN[sp][ik][inu,imu].real,deltaN[sp][ik][inu,imu].imag))
|
||||
fout.write("\n")
|
||||
fout.write("\n")
|
||||
fout.close()
|
||||
elif dm_type == 'vasp':
|
||||
# assert self.SP == 0, "Spin-polarized density matrix is not implemented"
|
||||
|
||||
if mpi.is_master_node():
|
||||
with open(filename, 'w') as f:
|
||||
f.write(" %i -1 ! Number of k-points, default number of bands\n"%(self.n_k))
|
||||
for sp in spn:
|
||||
for ik in xrange(self.n_k):
|
||||
ib1 = band_window[0][ik, 0]
|
||||
ib2 = band_window[0][ik, 1]
|
||||
f.write(" %i %i %i\n"%(ik + 1, ib1, ib2))
|
||||
for inu in xrange(self.n_orbitals[ik, 0]):
|
||||
for imu in xrange(self.n_orbitals[ik, 0]):
|
||||
if self.SP == 0:
|
||||
valre = (deltaN['up'][ik][inu, imu].real + deltaN['down'][ik][inu, imu].real) / 2.0
|
||||
valim = (deltaN['up'][ik][inu, imu].imag + deltaN['down'][ik][inu, imu].imag) / 2.0
|
||||
else:
|
||||
valre = deltaN[sp][ik][inu, imu].real
|
||||
valim = deltaN[sp][ik][inu, imu].imag
|
||||
|
||||
f.write(" %.14f %.14f"%(valre, valim))
|
||||
f.write("\n")
|
||||
else:
|
||||
raise NotImplementedError("Unknown density matrix type: '%s'"%(dm_type))
|
||||
|
||||
return deltaN, dens
|
||||
|
||||
def calc_hamiltonian_correction(self, filename='GAMMA'):
|
||||
r"""
|
||||
Calculates the charge density correction and stores it into a file.
|
||||
|
||||
The charge density correction is needed for charge-self-consistent DFT+DMFT calculations.
|
||||
It represents a density matrix of the interacting system defined in Bloch basis
|
||||
and it is calculated from the sum over Matsubara frequecies of the full GF,
|
||||
|
||||
..math:: N_{\nu\nu'}(k) = \sum_{i\omega_{n}} G_{\nu\nu'}(k, i\omega_{n})
|
||||
|
||||
The density matrix for every `k`-point is stored into a file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : string
|
||||
Name of the file to store the charge density correction.
|
||||
|
||||
Returns
|
||||
-------
|
||||
(deltaN, dens) : tuple
|
||||
Returns a tuple containing the density matrix `deltaN` and
|
||||
the corresponing total charge `dens`.
|
||||
|
||||
"""
|
||||
assert type(filename) == StringType, "calc_density_correction: filename has to be a string!"
|
||||
|
||||
ntoi = self.spin_names_to_ind[self.SO]
|
||||
spn = self.spin_block_names[self.SO]
|
||||
dens = {sp: 0.0 for sp in spn}
|
||||
|
||||
# Fetch Fermi weights and energy window band indices
|
||||
fermi_weights = 0
|
||||
band_window = 0
|
||||
if mpi.is_master_node():
|
||||
with HDFArchive(self.hdf_file,'r') as ar:
|
||||
fermi_weights = ar['dft_misc_input']['dft_fermi_weights']
|
||||
band_window = ar['dft_misc_input']['band_window']
|
||||
fermi_weights = mpi.bcast(fermi_weights)
|
||||
band_window = mpi.bcast(band_window)
|
||||
|
||||
# Set up deltaH:
|
||||
deltaH = {}
|
||||
for sp in spn:
|
||||
deltaH[sp] = [numpy.zeros([self.n_orbitals[ik,ntoi[sp]],self.n_orbitals[ik,ntoi[sp]]], numpy.complex_) for ik in range(self.n_k)]
|
||||
|
||||
ikarray = numpy.array(range(self.n_k))
|
||||
for ik in mpi.slice_array(ikarray):
|
||||
sigma_minus_dc = [s.copy() for s in self.Sigma_imp_iw]
|
||||
sigma_minus_dc = self.add_dc('iw')
|
||||
|
||||
beta = self.Sigma_imp_iw[0].mesh.beta # override beta if Sigma_iw is present
|
||||
n_iw = len(self.Sigma_imp_iw[0].mesh)
|
||||
|
||||
block_structure = [ range(self.n_orbitals[ik,ntoi[sp]]) for sp in spn ]
|
||||
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]
|
||||
glist = lambda : [ GfImFreq(indices=inner,beta=beta,n_points=n_iw) for block,inner in gf_struct]
|
||||
G_latt = BlockGf(name_list = block_ind_list, block_list = glist(), make_copies = False)
|
||||
G_latt.zero()
|
||||
|
||||
for icrsh in range(self.n_corr_shells):
|
||||
for bname, gf in G_latt:
|
||||
gf += self.upfold(ik,icrsh,bname,sigma_minus_dc[icrsh][bname],gf)
|
||||
|
||||
for sp in spn:
|
||||
deltaH[sp][ik][:, :] = G_latt[sp](0) # Any Matsubara frequency will do
|
||||
# G_latt_iw = self.lattice_gf(ik = ik, mu = self.chemical_potential, iw_or_w = "iw")
|
||||
# for bname,gf in G_latt_iw:
|
||||
# deltaN[bname][ik][:, :] = G_latt_iw[bname].density()
|
||||
# dens[bname] += self.bz_weights[ik] * G_latt_iw[bname].total_density()
|
||||
# if dm_type == 'vasp':
|
||||
## In 'vasp'-mode subtract the DFT density matrix
|
||||
# diag_inds = numpy.diag_indices(self.n_orbitals[ik, ntoi[bname]])
|
||||
# deltaN[bname][ik][diag_inds] -= dens_mat_dft[bname][ik]
|
||||
# dens[bname] -= self.bz_weights[ik] * dens_mat_dft[bname][ik].sum().real
|
||||
|
||||
# mpi reduce:
|
||||
for bname in deltaH:
|
||||
for ik in range(self.n_k):
|
||||
deltaH[bname][ik] = mpi.all_reduce(mpi.world, deltaH[bname][ik], lambda x,y : x+y)
|
||||
mpi.barrier()
|
||||
|
||||
# now save to file:
|
||||
if mpi.is_master_node():
|
||||
with open(filename, 'w') as f:
|
||||
f.write("H %i -1 ! Number of k-points, default number of bands\n"%(self.n_k))
|
||||
for sp in spn:
|
||||
for ik in xrange(self.n_k):
|
||||
ib1 = band_window[0][ik, 0]
|
||||
ib2 = band_window[0][ik, 1]
|
||||
f.write(" %i %i %i\n"%(ik + 1, ib1, ib2))
|
||||
for inu in xrange(self.n_orbitals[ik, 0]):
|
||||
for imu in xrange(self.n_orbitals[ik, 0]):
|
||||
if self.SP == 0:
|
||||
valre = (deltaH['up'][ik][inu, imu].real + deltaH['down'][ik][inu, imu].real) / 2.0
|
||||
valim = (deltaH['up'][ik][inu, imu].imag + deltaH['down'][ik][inu, imu].imag) / 2.0
|
||||
else:
|
||||
valre = deltaH[sp][ik][inu, imu].real
|
||||
valim = deltaH[sp][ik][inu, imu].imag
|
||||
|
||||
f.write(" %.14f %.14f"%(valre, valim))
|
||||
f.write("\n")
|
||||
return deltaH
|
||||
|
||||
def dmft_cycle():
|
||||
lda_filename = 'vasp'
|
||||
beta = 400
|
||||
U_int = 4.00
|
||||
J_hund = 0.70
|
||||
Loops = 1 # Number of DMFT sc-loops
|
||||
Mix = 1.0 # Mixing factor in QMC
|
||||
DC_type = 0 # 0...FLL, 1...Held, 2... AMF, 3...Lichtenstein
|
||||
DC_Mix = 1.0 # 1.0 ... all from imp; 0.0 ... all from Gloc
|
||||
useBlocs = False # use bloc structure from LDA input
|
||||
useMatrix = True # use the U matrix calculated from Slater coefficients instead of (U+2J, U, U-J)
|
||||
chemical_potential_init=-0.0 # initial chemical potential
|
||||
|
||||
use_dudarev = True
|
||||
|
||||
HDFfilename = lda_filename+'.h5'
|
||||
|
||||
# Convert DMFT input:
|
||||
# Can be commented after the first run
|
||||
Converter = VaspConverter(filename=lda_filename)
|
||||
Converter.convert_dft_input()
|
||||
|
||||
#check if there are previous runs:
|
||||
previous_runs = 0
|
||||
previous_present = False
|
||||
|
||||
if mpi.is_master_node():
|
||||
with HDFArchive(HDFfilename,'a') as ar:
|
||||
if 'iterations' in ar:
|
||||
previous_present = True
|
||||
previous_runs = ar['iterations']
|
||||
else:
|
||||
previous_runs = 0
|
||||
previous_present = False
|
||||
|
||||
mpi.barrier()
|
||||
previous_runs = mpi.bcast(previous_runs)
|
||||
previous_present = mpi.bcast(previous_present)
|
||||
|
||||
# Init the SumK class
|
||||
#SK=SumkDFT(hdf_file=lda_filename+'.h5',use_dft_blocks=False)
|
||||
SK=TestSumkDFT(hdf_file=lda_filename+'.h5',use_dft_blocks=False)
|
||||
|
||||
Norb = SK.corr_shells[0]['dim']
|
||||
l = SK.corr_shells[0]['l']
|
||||
|
||||
# Init the Hubbard-I solver:
|
||||
S = Solver(beta = beta, l = l, dudarev=use_dudarev)
|
||||
|
||||
# DEBUG
|
||||
#SK.put_Sigma(Sigma_imp=[S.Sigma])
|
||||
#dH = SK.calc_hamiltonian_correction(filename='GAMMA')
|
||||
# END DEBUG
|
||||
|
||||
chemical_potential=chemical_potential_init
|
||||
# load previous data: old self-energy, chemical potential, DC correction
|
||||
if (previous_present):
|
||||
mpi.report("Using stored data for initialisation")
|
||||
if (mpi.is_master_node()):
|
||||
with HDFArchive(HDFfilename,'a') as ar:
|
||||
S.Sigma <<= ar['SigmaF']
|
||||
things_to_load=['chemical_potential','dc_imp']
|
||||
old_data=SK.load(things_to_load)
|
||||
chemical_potential=old_data[0]
|
||||
SK.dc_imp=old_data[1]
|
||||
S.Sigma = mpi.bcast(S.Sigma)
|
||||
chemical_potential=mpi.bcast(chemical_potential)
|
||||
SK.dc_imp=mpi.bcast(SK.dc_imp)
|
||||
|
||||
|
||||
# DMFT loop:
|
||||
for Iteration_Number in range(1,Loops+1):
|
||||
|
||||
itn = Iteration_Number + previous_runs
|
||||
|
||||
# put Sigma into the SumK class:
|
||||
S.Sigma.zero() # !!!!
|
||||
SK.put_Sigma(Sigma_imp = [ S.Sigma ])
|
||||
|
||||
# Compute the SumK, possibly fixing mu by dichotomy
|
||||
if SK.density_required and (Iteration_Number > 1):
|
||||
chemical_potential = SK.calc_mu( precision = 0.001 )
|
||||
else:
|
||||
mpi.report("No adjustment of chemical potential\nTotal density = %.3f"%SK.total_density(mu=chemical_potential))
|
||||
|
||||
# Density:
|
||||
S.G <<= SK.extract_G_loc()[0]
|
||||
mpi.report("Total charge of Gloc : %.6f"%S.G.total_density())
|
||||
|
||||
# calculated DC at the first run to have reasonable initial non-interacting atomic level positions
|
||||
if ((Iteration_Number==1)and(previous_present==False)):
|
||||
if use_dudarev:
|
||||
dc_value_init = 0.0
|
||||
else:
|
||||
dc_value_init=U_int/2.0
|
||||
dm=S.G.density()
|
||||
SK.calc_dc( dm, U_interact = U_int, J_hund = J_hund, orb = 0, use_dc_formula = DC_type, use_dc_value=dc_value_init)
|
||||
|
||||
# calculate non-interacting atomic level positions:
|
||||
# eal = SK.eff_atomic_levels()[0]
|
||||
# S.set_atomic_levels( eal = eal )
|
||||
|
||||
# solve it:
|
||||
corr_energy, dft_dc = S.solve(U_int = U_int, J_hund = J_hund, verbosity = 1)
|
||||
|
||||
# Now mix Sigma and G:
|
||||
if ((itn>1)or(previous_present)):
|
||||
if (mpi.is_master_node()and (Mix<1.0)):
|
||||
with HDFArchive(HDFfilename,'r') as ar:
|
||||
mpi.report("Mixing Sigma and G with factor %s"%Mix)
|
||||
if ('SigmaF' in ar):
|
||||
S.Sigma <<= Mix * S.Sigma + (1.0-Mix) * ar['SigmaF']
|
||||
if ('GF' in ar):
|
||||
S.G <<= Mix * S.G + (1.0-Mix) * ar['GF']
|
||||
S.G = mpi.bcast(S.G)
|
||||
S.Sigma = mpi.bcast(S.Sigma)
|
||||
|
||||
# after the Solver has finished, set new double counting:
|
||||
# dm = S.G.density()
|
||||
# if not use_dudarev:
|
||||
# SK.calc_dc( dm, U_interact = U_int, J_hund = J_hund, orb = 0, use_dc_formula = DC_type )
|
||||
|
||||
# correlation energy calculations:
|
||||
correnerg = 0.5 * (S.G * S.Sigma).total_density()
|
||||
mpi.report("Corr. energy = %s"%correnerg)
|
||||
|
||||
# store the impurity self-energy, GF as well as correlation energy in h5
|
||||
if (mpi.is_master_node()):
|
||||
with HDFArchive(HDFfilename,'a') as ar:
|
||||
ar['iterations'] = itn
|
||||
ar['chemical_cotential%s'%itn] = chemical_potential
|
||||
ar['SigmaF'] = S.Sigma
|
||||
ar['GF'] = S.G
|
||||
ar['correnerg%s'%itn] = correnerg
|
||||
ar['DCenerg%s'%itn] = SK.dc_energ
|
||||
|
||||
#Save essential SumkDFT data:
|
||||
things_to_save=['chemical_potential','dc_energ','dc_imp']
|
||||
SK.save(things_to_save)
|
||||
|
||||
# print out occupancy matrix of Ce 4f
|
||||
# mpi.report("Orbital densities of impurity Green function:")
|
||||
# for s in dm:
|
||||
# mpi.report("Block %s: "%s)
|
||||
# for ii in range(len(dm[s])):
|
||||
# str = ''
|
||||
# for jj in range(len(dm[s])):
|
||||
# if (dm[s][ii,jj].real>0):
|
||||
# str += " %.4f"%(dm[s][ii,jj].real)
|
||||
# else:
|
||||
# str += " %.4f"%(dm[s][ii,jj].real)
|
||||
# mpi.report(str)
|
||||
mpi.report("Total charge of impurity problem : %.6f"%S.G.total_density())
|
||||
|
||||
|
||||
# find exact chemical potential
|
||||
#if (SK.density_required):
|
||||
# SK.chemical_potential = SK.calc_mu( precision = 0.000001 )
|
||||
# SK.chemical_potential = SK.calc_mu( precision = 0.01 )
|
||||
|
||||
#dN, d = SK.calc_density_correction(filename='GAMMA', dm_type='vasp')
|
||||
#mpi.report("Trace of Density Matrix: %s"%d)
|
||||
mpi.report("Storing Hamiltonian correction GAMMA...")
|
||||
SK.put_Sigma(Sigma_imp=[S.Sigma])
|
||||
dH = SK.calc_hamiltonian_correction(filename='GAMMA')
|
||||
# shutil.copyfile('GAMMA', 'it%i.GAMMA'%(itn))
|
||||
|
||||
# store correlation energy contribution to be read by Wien2ki and then included to DFT+DMFT total energy
|
||||
if (mpi.is_master_node()):
|
||||
with HDFArchive(HDFfilename) as ar:
|
||||
itn = ar['iterations']
|
||||
correnerg = ar['correnerg%s'%itn]
|
||||
DCenerg = ar['DCenerg%s'%itn]
|
||||
correnerg -= DCenerg[0]
|
||||
f=open(lda_filename+'.qdmft','a')
|
||||
f.write("%.16f\n"%correnerg)
|
||||
f.close()
|
||||
|
||||
return corr_energy, dft_dc
|
||||
|
||||
if __name__ == '__main__':
|
||||
dmft_cycle()
|
@ -1,11 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
!INCAR
|
||||
!POSCAR
|
||||
!POTCAR
|
||||
!KPOINTS
|
||||
!plo.cfg
|
||||
!run_plovasp.sh
|
||||
!conv_example.py
|
||||
!rotations
|
||||
!rot_dz2_dx2
|
@ -1,39 +0,0 @@
|
||||
ADDGRID = TRUE
|
||||
ALGO = NORMAL
|
||||
EDIFF = 0.00001
|
||||
EDIFFG = -0.01
|
||||
EMAX = 13.0
|
||||
EMIN = -3.0
|
||||
ENCUT = 500
|
||||
IBRION = -1
|
||||
ICHARG = 11
|
||||
ISIF = 2
|
||||
ISMEAR = -5
|
||||
ISPIN = 1
|
||||
ISYM = -1
|
||||
LASPH = FALSE
|
||||
LCHARG = TRUE
|
||||
LDAU = FALSE
|
||||
LDAUJ = 0 0 0 0 0
|
||||
LDAUL = 0 2 0 0 0
|
||||
LDAUTYPE = 2
|
||||
LDAUU = 0 6.2 0 0 0
|
||||
LMAXMIX = 6
|
||||
LORBIT = 0
|
||||
LREAL = Auto
|
||||
ROPT = 1e-3 1e-3 1e-3
|
||||
LWAVE = FALSE
|
||||
NEDOS = 1001
|
||||
NELM = 100
|
||||
NELMDL = -9
|
||||
NELMIN = 5
|
||||
NPAR = 4
|
||||
NSIM = 1
|
||||
NSW = 0
|
||||
POTIM = 0.1
|
||||
PREC = Accurate
|
||||
SIGMA = 0.05
|
||||
SMASS = 0.5
|
||||
SYMPREC = 1.0e-12
|
||||
|
||||
LOCPROJ = 5 6 7 8 : d : Hy
|
@ -1,4 +0,0 @@
|
||||
Automatic kpoint scheme
|
||||
0
|
||||
Gamma
|
||||
5 5 3
|
@ -1,28 +0,0 @@
|
||||
LuNiO3, exp. low-T
|
||||
1.0
|
||||
5.1234998703 0.0000000000 0.0000000000
|
||||
0.0000000000 5.5089001656 0.0000000000
|
||||
-0.0166880521 0.0000000000 7.3551808822
|
||||
Lu Ni O
|
||||
4 4 12
|
||||
Direct
|
||||
0.977199972 0.077000000 0.252999991
|
||||
0.022800028 0.922999978 0.746999979
|
||||
0.522800028 0.577000022 0.247000009
|
||||
0.477199972 0.423000008 0.753000021
|
||||
0.500000000 0.000000000 0.000000000
|
||||
0.000000000 0.500000000 0.500000000
|
||||
0.500000000 0.000000000 0.500000000
|
||||
0.000000000 0.500000000 0.000000000
|
||||
0.110100001 0.462700009 0.244100004
|
||||
0.889899969 0.537299991 0.755900025
|
||||
0.389899999 0.962700009 0.255899996
|
||||
0.610100031 0.037299991 0.744099975
|
||||
0.693300009 0.313699991 0.053900000
|
||||
0.306699991 0.686300039 0.946099997
|
||||
0.806699991 0.813699961 0.446099997
|
||||
0.193300009 0.186300009 0.553900003
|
||||
0.185100004 0.201600000 0.943799973
|
||||
0.814899981 0.798399985 0.056200027
|
||||
0.314899981 0.701600015 0.556200027
|
||||
0.685100019 0.298399985 0.443799973
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
||||
[General]
|
||||
DOSMESH = 401
|
||||
|
||||
[Shell 1]
|
||||
EWINDOW = -8.6 2.7
|
||||
#EWINDOW = -0.6 2.7
|
||||
LSHELL = 2
|
||||
IONS = 5..8
|
||||
NORMION = True
|
||||
TRANSFILE = rotations
|
||||
#TRANSFILE = rot_dz2_dx2
|
||||
NORMALIZE = True
|
@ -1,18 +0,0 @@
|
||||
# Rotations to the local frames
|
||||
|
||||
# Atom 1, Euler angles: 44.57639968 16.85783381 -11.27701880
|
||||
0.02793493813 -0.09400347991 0.87385177595 -0.47142545676 0.06726141074
|
||||
-0.87830274777 -0.28356545426 0.00107688253 0.06072810673 0.38011294872
|
||||
|
||||
# Atom 2, Euler angles: 47.67919913 16.85783423 11.27702026
|
||||
-0.02793494291 0.09400349403 0.87385176987 -0.47142546468 0.06726141256
|
||||
-0.84565748799 -0.27808790765 -0.00680142052 -0.08187952499 -0.44808482755
|
||||
|
||||
# Atom 3, Euler angles:-133.92682764 17.32502138 165.73386489
|
||||
0.03668336697 0.12133769713 0.86698007031 0.47720500874 0.06747170631
|
||||
-0.85519672598 0.29102955535 -0.00287628125 -0.06301365234 0.42421853379
|
||||
|
||||
# Atom 4, Euler angles:-135.60182669 17.32502172 -165.73386378
|
||||
-0.03668337098 -0.12133770845 0.86698006522 0.47720501465 0.06747170748
|
||||
-0.84809293709 0.29001625337 0.00161325481 0.06758002057 -0.43824568573
|
||||
|
@ -1,30 +0,0 @@
|
||||
# Rotations to the local frames
|
||||
|
||||
# Atom 1, Euler angles: 44.57639968 16.85783381 -11.27701880
|
||||
0.38045444863 0.05847209742 0.07282374934 0.27130935338 0.87916060116
|
||||
-0.26548421431 0.78270891327 0.33738843326 0.43922773606 -0.10066245585
|
||||
0.02793493813 -0.09400347991 0.87385177595 -0.47142545676 0.06726141074
|
||||
0.11214484811 -0.54286439359 0.34241445738 0.71241867354 -0.26064104853
|
||||
-0.87830274777 -0.28356545426 0.00107688253 0.06072810673 0.38011294872
|
||||
|
||||
# Atom 2, Euler angles: 47.67919913 16.85783423 11.27702026
|
||||
-0.44835779602 -0.08059449489 0.07251344244 0.26569233153 0.84653954413
|
||||
-0.10160916307 0.51163832768 0.35542791179 0.72915358208 -0.26440093208
|
||||
-0.02793494291 0.09400349403 0.87385176987 -0.47142546468 0.06726141256
|
||||
0.26969226294 -0.80346823694 0.32365046757 0.41084840677 -0.09032628101
|
||||
-0.84565748799 -0.27808790765 -0.00680142052 -0.08187952499 -0.44808482755
|
||||
|
||||
# Atom 3, Euler angles:-133.92682764 17.32502138 165.73386489
|
||||
0.42474364412 -0.05919623743 0.07674521204 -0.27806951500 0.85608186496
|
||||
0.27929719729 0.78784591591 -0.35463192502 0.41101628718 0.08120158747
|
||||
0.03668336697 0.12133769713 0.86698007031 0.47720500874 0.06747170631
|
||||
-0.09422739956 -0.52571244938 -0.34158989281 0.72252862625 0.27571062205
|
||||
-0.85519672598 0.29102955535 -0.00287628125 -0.06301365234 0.42421853379
|
||||
|
||||
# Atom 4, Euler angles:-135.60182669 17.32502172 -165.73386378
|
||||
-0.43875616246 0.06397634469 0.07678214913 -0.27699516110 0.84898659561
|
||||
0.09192658044 0.51921347838 -0.34449569877 0.72588538389 0.27636930122
|
||||
-0.03668337098 -0.12133770845 0.86698006522 0.47720501465 0.06747170748
|
||||
-0.28006291089 -0.79214400488 -0.35180986204 0.40505852046 0.07893071297
|
||||
-0.84809293709 0.29001625337 0.00161325481 0.06758002057 -0.43824568573
|
||||
|
@ -1,2 +0,0 @@
|
||||
PLOVASP_PATH=/path/to/triqs1.2/applications/dft_tools/src
|
||||
PYTHONPATH=$PLOVASP_PATH/python:$PLOVASP_PATH/c:$PYTHONPATH pytriqs $PLOVASP_PATH/python/converters/plovasp/main.py $@
|
@ -1,7 +0,0 @@
|
||||
*
|
||||
!example.cfg
|
||||
!INCAR
|
||||
!KPOINTS
|
||||
!POSCAR
|
||||
!POTCAR
|
||||
!conv_example.py
|
@ -1,42 +0,0 @@
|
||||
ADDGRID = TRUE
|
||||
ALGO = NORMAL
|
||||
EDIFF = 0.00001
|
||||
EDIFFG = -0.002
|
||||
EMAX = 13.0
|
||||
EMIN = -2.0
|
||||
ENCUT = 550
|
||||
ENAUG = 1100
|
||||
IBRION = -1
|
||||
ICHARG = 11
|
||||
ISIF = 4
|
||||
ISMEAR = -5
|
||||
ISPIN = 1
|
||||
ISYM = -1
|
||||
LASPH = TRUE
|
||||
LCHARG = TRUE
|
||||
LDAU = False
|
||||
LDAUJ = 0 1.0 0 0 0
|
||||
LDAUL = -1 2 -1
|
||||
LDAUTYPE = 1
|
||||
LDAUU = 0 5.0 0 0 0
|
||||
LDAUPRINT = 1
|
||||
LMAXMIX = 6
|
||||
LORBIT = 0
|
||||
LREAL = False
|
||||
ROPT = 1e-3 1e-3 1e-3
|
||||
LWAVE = FALSE
|
||||
NBANDS = 16
|
||||
NEDOS = 501
|
||||
NELM = 100
|
||||
NELMDL = -7
|
||||
NELMIN = 7
|
||||
NPAR = 4
|
||||
NSIM = 8
|
||||
NSW = 0
|
||||
POTIM = 0.4
|
||||
PREC = Accurate
|
||||
SIGMA = 0.1
|
||||
SMASS = 0.5
|
||||
SYMPREC = 1.0e-6
|
||||
|
||||
LOCPROJ = 1 : d : Hy
|
@ -1,4 +0,0 @@
|
||||
Automatic kpoint scheme
|
||||
0
|
||||
Gamma
|
||||
2 2 2
|
@ -1,10 +0,0 @@
|
||||
V SF test
|
||||
2.9878
|
||||
-0.5 0.5 0.5
|
||||
0.5 -0.5 0.5
|
||||
0.5 0.5 -0.5
|
||||
V
|
||||
1
|
||||
Direct
|
||||
0.0 0.0 0.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
||||
|
||||
from vasp_converter import VaspConverter
|
||||
|
||||
if __name__ == '__main__':
|
||||
conv = VaspConverter('vasp')
|
||||
conv.convert_dft_input()
|
||||
|
@ -1,7 +0,0 @@
|
||||
|
||||
[Shell 1]
|
||||
LSHELL = 2
|
||||
IONS = 1
|
||||
EWINDOW = -15.0 5.0
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
!INCAR
|
||||
!POSCAR
|
||||
!POTCAR
|
||||
!KPOINTS
|
||||
!plo.cfg
|
||||
!run_plovasp.sh
|
||||
!conv_example.py
|
@ -1,43 +0,0 @@
|
||||
ADDGRID = TRUE
|
||||
ALGO = NORMAL
|
||||
EDIFF = 0.00001
|
||||
EDIFFG = -0.002
|
||||
EMAX = 13.0
|
||||
EMIN = -2.0
|
||||
ENCUT = 550
|
||||
ENAUG = 1100
|
||||
IBRION = -1
|
||||
ICHARG = 11
|
||||
ISIF = 4
|
||||
ISMEAR = -5
|
||||
ISPIN = 1
|
||||
ISYM = -1
|
||||
LASPH = TRUE
|
||||
LCHARG = TRUE
|
||||
LDAU = False
|
||||
LDAUJ = 0 1.0 0 0 0
|
||||
LDAUL = -1 2 -1
|
||||
LDAUTYPE = 1
|
||||
LDAUU = 0 5.0 0 0 0
|
||||
LDAUPRINT = 1
|
||||
LMAXMIX = 6
|
||||
LORBIT = 0
|
||||
LREAL = False
|
||||
ROPT = 1e-3 1e-3 1e-3
|
||||
LWAVE = FALSE
|
||||
NBANDS = 32
|
||||
NEDOS = 501
|
||||
NELM = 100
|
||||
NELMDL = -7
|
||||
NELMIN = 7
|
||||
NPAR = 1
|
||||
NSIM = 8
|
||||
NSW = 0
|
||||
POTIM = 0.4
|
||||
PREC = Accurate
|
||||
SIGMA = 0.1
|
||||
SMASS = 0.5
|
||||
SYMPREC = 1.0e-6
|
||||
|
||||
# Projectors
|
||||
LOCPROJ = 2 : d : Hy
|
@ -1,4 +0,0 @@
|
||||
Automatic kpoint scheme
|
||||
0
|
||||
Gamma
|
||||
3 3 3
|
@ -1,13 +0,0 @@
|
||||
SrVO3
|
||||
3.841
|
||||
1.0000000000000000 0.0000000000000000 0.0000000000000000
|
||||
0.0000000000000000 1.0000000000000000 0.0000000000000000
|
||||
0.0000000000000000 0.0000000000000000 1.0000000000000000
|
||||
Sr V O
|
||||
1 1 3
|
||||
Direct
|
||||
0.5 0.5 0.5
|
||||
0.0 0.0 0.0
|
||||
0.5 0.0 0.0
|
||||
0.0 0.5 0.0
|
||||
0.0 0.0 0.5
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
|
||||
import numpy as np
|
||||
from pytriqs.gf import *
|
||||
#from sumk_dft import SumkDFT
|
||||
from sumk_dft_tools import SumkDFTTools
|
||||
from converters.vasp_converter import VaspConverter
|
||||
|
||||
np.set_printoptions(suppress=True)
|
||||
|
||||
def density_matrix_and_overlap(sk):
|
||||
glist = [GfImFreq(indices=inds,beta=1000.0) for bl, inds in sk.gf_struct_sumk[0]]
|
||||
sigma = BlockGf(name_list=[bl for bl, inds in sk.gf_struct_sumk[0]], block_list=glist)
|
||||
sigma.zero()
|
||||
sk.put_Sigma(Sigma_imp=[sigma])
|
||||
|
||||
print "Overlap matrix:"
|
||||
dm_blocks = sk.check_projectors()
|
||||
print dm_blocks[0].real
|
||||
|
||||
sk.calc_mu(precision=0.001)
|
||||
|
||||
print
|
||||
print "Denisty matrix:"
|
||||
dm_blocks = sk.density_matrix(method='using_gf', beta=1000.0)
|
||||
ntot = 0.0
|
||||
for bl in dm_blocks[0]:
|
||||
print
|
||||
print bl
|
||||
print dm_blocks[0][bl].real
|
||||
ntot += dm_blocks[0][bl].real.trace()
|
||||
|
||||
print
|
||||
print " Impurity density:", ntot
|
||||
|
||||
def density_of_states(sk):
|
||||
glist = [GfReFreq(indices=inds, window=(-10.0, 10.0), n_points=2000) for bl, inds in sk.gf_struct_sumk[0]]
|
||||
sigma = BlockGf(name_list=[bl for bl, inds in sk.gf_struct_sumk[0]], block_list=glist)
|
||||
sigma.zero()
|
||||
sk.put_Sigma(Sigma_imp=[sigma])
|
||||
|
||||
print " Evaluating DOS..."
|
||||
sk.dos_wannier_basis(broadening=0.03, with_dc=False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
conv = VaspConverter('vasp')
|
||||
conv.convert_dft_input()
|
||||
|
||||
sk = SumkDFTTools(hdf_file='vasp.h5')
|
||||
|
||||
density_matrix_and_overlap(sk)
|
||||
# density_of_states(sk)
|
@ -1,16 +0,0 @@
|
||||
[General]
|
||||
DOSMESH = -3.0 5.0 4001
|
||||
|
||||
[Group 1]
|
||||
SHELLS = 1
|
||||
NORMALIZE = True
|
||||
EWINDOW = -1.45 1.8
|
||||
|
||||
[Shell 1]
|
||||
LSHELL = 2
|
||||
IONS = 2
|
||||
|
||||
TRANSFORM = 1.0 0.0 0.0 0.0 0.0
|
||||
0.0 1.0 0.0 0.0 0.0
|
||||
0.0 0.0 0.0 1.0 0.0
|
||||
|
@ -1,2 +0,0 @@
|
||||
PLOVASP_PATH=/path/to/triqs1.2/applications/dft_tools/src
|
||||
PYTHONPATH=$PLOVASP_PATH/python:$PLOVASP_PATH/c:$PYTHONPATH pytriqs $PLOVASP_PATH/python/converters/plovasp/main.py $@
|
@ -1,42 +0,0 @@
|
||||
ADDGRID = TRUE
|
||||
ALGO = NORMAL
|
||||
EDIFF = 0.00001
|
||||
EDIFFG = -0.002
|
||||
EMAX = 13.0
|
||||
EMIN = -2.0
|
||||
ENCUT = 550
|
||||
ENAUG = 1100
|
||||
IBRION = -1
|
||||
ICHARG = 11
|
||||
ISIF = 4
|
||||
ISMEAR = -5
|
||||
ISPIN = 1
|
||||
ISYM = -1
|
||||
LASPH = TRUE
|
||||
LCHARG = TRUE
|
||||
LDAU = False
|
||||
LDAUJ = 0 1.0 0 0 0
|
||||
LDAUL = -1 2 -1
|
||||
LDAUTYPE = 1
|
||||
LDAUU = 0 5.0 0 0 0
|
||||
LDAUPRINT = 1
|
||||
LMAXMIX = 6
|
||||
LORBIT = 0
|
||||
LREAL = False
|
||||
ROPT = 1e-3 1e-3 1e-3
|
||||
LWAVE = FALSE
|
||||
NBANDS = 32
|
||||
NEDOS = 501
|
||||
NELM = 100
|
||||
NELMDL = -7
|
||||
NELMIN = 7
|
||||
NPAR = 4
|
||||
NSIM = 8
|
||||
NSW = 0
|
||||
POTIM = 0.4
|
||||
PREC = Accurate
|
||||
SIGMA = 0.1
|
||||
SMASS = 0.5
|
||||
SYMPREC = 1.0e-6
|
||||
|
||||
LOCPROJ = 1 2 : d : Hy
|
@ -1,4 +0,0 @@
|
||||
Automatic kpoint scheme
|
||||
0
|
||||
Gamma
|
||||
2 2 2
|
@ -1,11 +0,0 @@
|
||||
V SF test
|
||||
2.9878
|
||||
1.0 0.0 0.0
|
||||
0.0 1.0 0.0
|
||||
0.0 0.0 1.0
|
||||
V
|
||||
2
|
||||
Direct
|
||||
0.0 0.0 0.0
|
||||
0.5 0.5 0.5
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
||||
|
||||
[Shell 1]
|
||||
LSHELL = 2
|
||||
IONS = 1
|
||||
EWINDOW = -15.0 5.0
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.inpconfig
|
||||
==============
|
||||
plovasp.inpconfig
|
||||
=================
|
||||
|
||||
Module for parsing and checking an input config-file.
|
||||
"""
|
||||
@ -84,7 +84,9 @@ class ConfigParameters:
|
||||
|
||||
self.sh_optional = {
|
||||
'transform': ('tmatrix', lambda s: self.parse_string_tmatrix(s, real=True)),
|
||||
'transfile': ('tmatrices', self.parse_file_tmatrix)}
|
||||
'transfile': ('tmatrices', self.parse_file_tmatrix),
|
||||
'sort': ('ion_sort', self.parse_string_int,None),
|
||||
'corr': ('corr', self.parse_string_logical, True)}
|
||||
|
||||
self.gr_required = {
|
||||
'shells': ('shells', lambda s: map(int, s.split())),
|
||||
@ -92,12 +94,16 @@ class ConfigParameters:
|
||||
|
||||
self.gr_optional = {
|
||||
'normalize' : ('normalize', self.parse_string_logical, True),
|
||||
'normion' : ('normion', self.parse_string_logical, True)}
|
||||
'normion' : ('normion', self.parse_string_logical, True),
|
||||
'complement' : ('complement', self.parse_string_logical, False),
|
||||
'bands': ('bands', self.parse_band_window)}
|
||||
|
||||
|
||||
self.gen_optional = {
|
||||
'basename' : ('basename', str, 'vasp'),
|
||||
'efermi' : ('efermi', float),
|
||||
'dosmesh': ('dosmesh', self.parse_string_dosmesh)}
|
||||
'dosmesh': ('dosmesh', self.parse_string_dosmesh),
|
||||
'hk': ('hk', self.parse_string_logical, False)}
|
||||
|
||||
#
|
||||
# Special parsers
|
||||
@ -190,6 +196,18 @@ class ConfigParameters:
|
||||
assert first_char in 'tf', "Logical parameters should be given by either 'True' or 'False'"
|
||||
return first_char == 't'
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# parse_string_int()
|
||||
#
|
||||
################################################################################
|
||||
def parse_string_int(self, par_str):
|
||||
"""
|
||||
int parameters
|
||||
"""
|
||||
return int(par_str)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# parse_energy_window()
|
||||
@ -205,6 +223,21 @@ class ConfigParameters:
|
||||
assert ftmp[0] < ftmp[1], "The first float in EWINDOW must be smaller than the second one"
|
||||
return tuple(ftmp)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# parse_band_window()
|
||||
#
|
||||
################################################################################
|
||||
def parse_band_window(self, par_str):
|
||||
"""
|
||||
Band window is given by two ints, with the first one being smaller
|
||||
than the second one.
|
||||
"""
|
||||
ftmp = map(int, par_str.split())
|
||||
assert len(ftmp) == 2, "BANDS must be specified by exactly two ints"
|
||||
assert ftmp[0] < ftmp[1], "The first int in BANDS must be smaller than the second one"
|
||||
return tuple(ftmp)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# parse_string_tmatrix()
|
||||
@ -461,12 +494,11 @@ class ConfigParameters:
|
||||
################################################################################
|
||||
def groups_shells_consistency(self):
|
||||
"""
|
||||
Ensures consistency between groups and shells.
|
||||
In particular:
|
||||
- if no groups are explicitly defined and only shell is defined create
|
||||
a group automatically
|
||||
- check the existance of all shells referenced in the groups
|
||||
- check that all shells are referenced in the groups
|
||||
Ensures consistency between groups and shells. In particular:
|
||||
- if no groups are explicitly defined and only shell is defined create a group automatically
|
||||
- check the existance of all shells referenced in the groups
|
||||
- check that all shells are referenced in the groups
|
||||
|
||||
"""
|
||||
# Special case: no groups is defined
|
||||
if self.ngroups == 0:
|
||||
@ -627,4 +659,3 @@ if __name__ == '__main__':
|
||||
doscar = vaspio.Doscar()
|
||||
doscar.from_file(vasp_dir)
|
||||
# pars = parse_input(filename)
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.plotools
|
||||
=============
|
||||
plovasp.plotools
|
||||
================
|
||||
|
||||
Set of routines for processing and outputting PLOs.
|
||||
|
||||
@ -33,11 +33,31 @@ r"""
|
||||
the consistency of the input data, generation of projected localized
|
||||
orbitals (PLOs) out of raw VASP projectors, and outputting data
|
||||
required by DFTTools.
|
||||
|
||||
The first step of PLO processing is to select subsets of projectors
|
||||
corresponding to PLO groups. Each group contains a set of shells. Each
|
||||
projector shell is represented by an object 'ProjectorShell' that contains
|
||||
an array of projectors and information on the shell itself (orbital number,
|
||||
ions, etc.). 'ProjectorShell's are contained in both a list of shells
|
||||
(according to the original list as read from config-file) and in a
|
||||
'ProjectorGroup' object, the latter also providing information about the
|
||||
energy window.
|
||||
|
||||
Order of operations:
|
||||
- transform projectors (all bands) in each shell
|
||||
- select transformed shell projectors for a given group within the window
|
||||
- orthogonalize if necessary projectors within a group by performing
|
||||
the following operations for each k-point:
|
||||
* combine all projector shells into a single array
|
||||
* orthogonalize the array
|
||||
* distribute back the arrays assuming that the order is preserved
|
||||
|
||||
"""
|
||||
import itertools as it
|
||||
import numpy as np
|
||||
from proj_group import ProjectorGroup
|
||||
from proj_shell import ProjectorShell
|
||||
from proj_shell import ComplementShell
|
||||
|
||||
np.set_printoptions(suppress=True)
|
||||
|
||||
@ -81,6 +101,7 @@ def check_data_consistency(pars, el_struct):
|
||||
errmsg = "Projector for isite = %s, l = %s does not match PROJCAR"%(ion + 1, lshell)
|
||||
raise Exception(errmsg)
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# generate_plo()
|
||||
@ -105,7 +126,8 @@ def generate_plo(conf_pars, el_struct):
|
||||
|
||||
# eigvals(nktot, nband, ispin) are defined with respect to the Fermi level
|
||||
eigvals = el_struct.eigvals - efermi
|
||||
|
||||
# check if at least one shell is correlated
|
||||
assert np.any([shell['corr'] for shell in conf_pars.shells]), 'at least one shell has be CORR = True'
|
||||
nshell = len(conf_pars.shells)
|
||||
print
|
||||
print " Generating %i shell%s..."%(nshell, '' if nshell == 1 else 's')
|
||||
@ -117,39 +139,59 @@ def generate_plo(conf_pars, el_struct):
|
||||
print " Orbital l : %i"%(pshell.lorb)
|
||||
print " Number of ions: %i"%(pshell.nion)
|
||||
print " Dimension : %i"%(pshell.ndim)
|
||||
print " Correlated : %r"%(pshell.corr)
|
||||
print " Ion sort : %r"%(pshell.ion_sort)
|
||||
pshells.append(pshell)
|
||||
|
||||
|
||||
pgroups = []
|
||||
for gr_par in conf_pars.groups:
|
||||
pgroup = ProjectorGroup(gr_par, pshells, eigvals)
|
||||
pgroup.orthogonalize()
|
||||
if pgroup.complement:
|
||||
pgroup.calc_complement(eigvals)
|
||||
if conf_pars.general['hk']:
|
||||
pgroup.calc_hk(eigvals)
|
||||
#testout = 'hk.out.h5'
|
||||
#from pytriqs.archive import HDFArchive
|
||||
#with HDFArchive(testout, 'w') as h5test:
|
||||
# h5test['hk'] = pgroup.hk
|
||||
# DEBUG output
|
||||
print "Density matrix:"
|
||||
dm_all, ov_all = pshells[pgroup.ishells[0]].density_matrix(el_struct)
|
||||
nimp = 0.0
|
||||
spin_fac = 2 if dm_all.shape[0] == 1 else 1
|
||||
for io in xrange(dm_all.shape[1]):
|
||||
print " Site %i"%(io + 1)
|
||||
dm = spin_fac * dm_all[:, io, : ,:].sum(0)
|
||||
for row in dm:
|
||||
print ''.join(map("{0:12.7f}".format, row))
|
||||
ndm = dm.trace()
|
||||
nimp += ndm
|
||||
print " trace: ", ndm
|
||||
ov_all = []
|
||||
for ish in pgroup.ishells:
|
||||
if not isinstance(pshells[pgroup.ishells[ish]],ComplementShell):
|
||||
print " Shell %i"%(ish + 1)
|
||||
dm_all, ov_all_ = pshells[ish].density_matrix(el_struct)
|
||||
ov_all.append(ov_all_[0])
|
||||
spin_fac = 2 if dm_all.shape[0] == 1 else 1
|
||||
for io in xrange(dm_all.shape[1]):
|
||||
print " Site %i"%(io + 1)
|
||||
dm = spin_fac * dm_all[:, io, : ,:].sum(0)
|
||||
for row in dm:
|
||||
print ''.join(map("{0:14.7f}".format, row))
|
||||
ndm = dm.trace()
|
||||
if pshells[ish].corr:
|
||||
nimp += ndm
|
||||
print " trace: ", ndm
|
||||
print
|
||||
print " Impurity density:", nimp
|
||||
print
|
||||
print "Overlap:"
|
||||
for io, ov in enumerate(ov_all[0]):
|
||||
for io, ov in enumerate(ov_all):
|
||||
print " Site %i"%(io + 1)
|
||||
print ov
|
||||
print ov[0,...]
|
||||
print
|
||||
print "Local Hamiltonian:"
|
||||
loc_ham = pshells[pgroup.ishells[0]].local_hamiltonian(el_struct)
|
||||
for io in xrange(loc_ham.shape[1]):
|
||||
print " Site %i"%(io + 1)
|
||||
for row in loc_ham[:, io, :, :].sum(0):
|
||||
print ''.join(map("{0:12.7f}".format, row))
|
||||
for ish in pgroup.ishells:
|
||||
if not isinstance(pshells[pgroup.ishells[ish]],ComplementShell):
|
||||
print " Shell %i"%(ish + 1)
|
||||
loc_ham = pshells[pgroup.ishells[ish]].local_hamiltonian(el_struct)
|
||||
for io in xrange(loc_ham.shape[1]):
|
||||
print " Site %i"%(io + 1)
|
||||
for row in loc_ham[:, io, :, :].sum(0):
|
||||
print ''.join(map("{0:14.7f}".format, row))
|
||||
# END DEBUG output
|
||||
if 'dosmesh' in conf_pars.general:
|
||||
print
|
||||
@ -164,12 +206,15 @@ def generate_plo(conf_pars, el_struct):
|
||||
n_points = mesh_pars['n_points']
|
||||
|
||||
emesh = np.linspace(dos_emin, dos_emax, n_points)
|
||||
dos = pshells[pgroup.ishells[0]].density_of_states(el_struct, emesh)
|
||||
de = emesh[1] - emesh[0]
|
||||
ntot = (dos[1:,...] + dos[:-1,...]).sum(0) / 2 * de
|
||||
print " Total number of states:", ntot
|
||||
for io in xrange(dos.shape[2]):
|
||||
np.savetxt('pdos_%i.dat'%(io), np.vstack((emesh.T, dos[:, 0, io, :].T)).T)
|
||||
for ish in pgroup.ishells:
|
||||
if not isinstance(pshells[pgroup.ishells[ish]],ComplementShell) or True:
|
||||
print " Shell %i"%(ish + 1)
|
||||
dos = pshells[pgroup.ishells[ish]].density_of_states(el_struct, emesh)
|
||||
de = emesh[1] - emesh[0]
|
||||
ntot = (dos[1:,...] + dos[:-1,...]).sum(0) / 2 * de
|
||||
print " Total number of states:", ntot
|
||||
for io in xrange(dos.shape[2]):
|
||||
np.savetxt('pdos_%i_%i.dat'%(ish,io), np.vstack((emesh.T, dos[:, 0, io, :].T)).T)
|
||||
|
||||
pgroups.append(pgroup)
|
||||
|
||||
@ -183,9 +228,12 @@ def generate_plo(conf_pars, el_struct):
|
||||
def output_as_text(pars, el_struct, pshells, pgroups):
|
||||
"""
|
||||
Output all information necessary for the converter as text files.
|
||||
|
||||
"""
|
||||
ctrl_output(pars, el_struct, len(pgroups))
|
||||
plo_output(pars, el_struct, pshells, pgroups)
|
||||
if pars.general['hk']:
|
||||
hk_output(pars, el_struct, pgroups)
|
||||
|
||||
|
||||
# TODO: k-points with weights should be stored once and for all
|
||||
@ -232,6 +280,27 @@ def kpoints_output(basename, el_struct):
|
||||
def ctrl_output(conf_pars, el_struct, ng):
|
||||
"""
|
||||
Outputs a ctrl-file.
|
||||
|
||||
Control file format
|
||||
""""""""""""""""""""""""""""""
|
||||
|
||||
Filename '<namebase>.ctrl'. Contains the data shared between all shells.
|
||||
The JSON-header consists of the following elements:
|
||||
|
||||
* *nk*: number of `k`-points
|
||||
|
||||
* *ns*: number of spin channels
|
||||
|
||||
* *nc_flag*: collinear/noncollinear case (False/True)
|
||||
|
||||
* *ng*: number of projector groups
|
||||
|
||||
* Symmetry information (list of symmetry operations)
|
||||
|
||||
* *efermi*: Fermi level (optional)
|
||||
|
||||
* Lattice information
|
||||
|
||||
"""
|
||||
ctrl_fname = conf_pars.general['basename'] + '.ctrl'
|
||||
head_dict = {}
|
||||
@ -259,6 +328,13 @@ def ctrl_output(conf_pars, el_struct, ng):
|
||||
tmp1 = "".join(map("{0:15.10f}".format, kp))
|
||||
out = tmp1 + "{0:16.10f}".format(el_struct.kmesh['kweights'][ik])
|
||||
f.write(out + "\n")
|
||||
f.write("# k-points and weights cartesian\n")
|
||||
labels = ['kx', 'ky', 'kz']
|
||||
out = "".join(map(lambda s: s.center(15), labels))
|
||||
f.write("#" + out + "\n")
|
||||
for ik, kp in enumerate(el_struct.kmesh['kpoints_cart']):
|
||||
out = "".join(map("{0:15.10f}".format, kp))
|
||||
f.write(out + "\n")
|
||||
|
||||
|
||||
################################################################################
|
||||
@ -276,31 +352,31 @@ def plo_output(conf_pars, el_struct, pshells, pgroups):
|
||||
Each group is stored in a '<basename>.plog<Ng>' file. The format is the
|
||||
following:
|
||||
|
||||
# Energy window: emin, emax
|
||||
ib_min, ib_max
|
||||
nelect
|
||||
# Eigenvalues
|
||||
isp, ik1, kx, ky, kz, kweight
|
||||
ib1, ib2
|
||||
eig1
|
||||
eig2
|
||||
...
|
||||
eigN
|
||||
ik2, kx, ky, kz, kweight
|
||||
...
|
||||
| # Energy window: emin, emax
|
||||
| ib_min, ib_max
|
||||
| nelect
|
||||
| # Eigenvalues
|
||||
| isp, ik1, kx, ky, kz, kweight
|
||||
| ib1, ib2
|
||||
| eig1
|
||||
| eig2
|
||||
| ...
|
||||
| eigN
|
||||
| ik2, kx, ky, kz, kweight
|
||||
| ...
|
||||
|
||||
# Projected shells
|
||||
Nshells
|
||||
# Shells: <shell indices>
|
||||
# Shell <1>
|
||||
Shell 1
|
||||
ndim
|
||||
# complex arrays: plo(ns, nion, ndim, nb)
|
||||
...
|
||||
# Shells: <shell indices>
|
||||
# Shell <2>
|
||||
Shell 2
|
||||
...
|
||||
| # Projected shells
|
||||
| Nshells
|
||||
| # Shells: <shell indices>
|
||||
| # Shell <1>
|
||||
| Shell 1
|
||||
| ndim
|
||||
| # complex arrays: plo(ns, nion, ndim, nb)
|
||||
| ...
|
||||
| # Shells: <shell indices>
|
||||
| # Shell <2>
|
||||
| Shell 2
|
||||
| ...
|
||||
|
||||
"""
|
||||
for ig, pgroup in enumerate(pgroups):
|
||||
@ -308,9 +384,14 @@ def plo_output(conf_pars, el_struct, pshells, pgroups):
|
||||
print " Storing PLO-group file '%s'..."%(plo_fname)
|
||||
head_dict = {}
|
||||
|
||||
head_dict['ewindow'] = (pgroup.emin, pgroup.emax)
|
||||
|
||||
head_dict['nb_max'] = pgroup.nb_max
|
||||
|
||||
if 'bands' in conf_pars.groups[ig]:
|
||||
head_dict['bandwindow'] = (pgroup.ib_min, pgroup.ib_max)
|
||||
else:
|
||||
head_dict['ewindow'] = (pgroup.emin, pgroup.emax)
|
||||
|
||||
# Number of electrons within the window
|
||||
head_dict['nelect'] = pgroup.nelect_window(el_struct)
|
||||
print " Density within window:", head_dict['nelect']
|
||||
@ -322,6 +403,7 @@ def plo_output(conf_pars, el_struct, pshells, pgroups):
|
||||
sh_dict['shell_index'] = ish
|
||||
sh_dict['lorb'] = shell.lorb
|
||||
sh_dict['ndim'] = shell.ndim
|
||||
sh_dict['corr'] = shell.corr
|
||||
# Convert ion indices from the internal representation (starting from 0)
|
||||
# to conventional VASP representation (starting from 1)
|
||||
ion_output = [io + 1 for io in shell.ion_list]
|
||||
@ -342,7 +424,11 @@ def plo_output(conf_pars, el_struct, pshells, pgroups):
|
||||
f.write("#END OF HEADER\n")
|
||||
|
||||
# Eigenvalues within the window
|
||||
f.write("# Eigenvalues within the energy window: %s, %s\n"%(pgroup.emin, pgroup.emax))
|
||||
if 'bands' in conf_pars.groups[ig]:
|
||||
f.write("# Eigenvalues within the band window: %s, %s\n"%(pgroup.ib_min+1, pgroup.ib_max+1))
|
||||
else:
|
||||
f.write("# Eigenvalues within the energy window: %s, %s\n"%(pgroup.emin, pgroup.emax))
|
||||
|
||||
nk, nband, ns_band = el_struct.eigvals.shape
|
||||
for isp in xrange(ns_band):
|
||||
f.write("# is = %i\n"%(isp + 1))
|
||||
@ -376,4 +462,79 @@ def plo_output(conf_pars, el_struct, pshells, pgroups):
|
||||
f.write("{0:16.10f}{1:16.10f}\n".format(p.real, p.imag))
|
||||
f.write("\n")
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# plo_output
|
||||
#
|
||||
################################################################################
|
||||
def hk_output(conf_pars, el_struct, pgroups):
|
||||
"""
|
||||
Outputs HK into text file.
|
||||
|
||||
Filename is defined by <basename> that is passed from config-file.
|
||||
|
||||
The Hk for each groups is stored in a '<basename>.hk<Ng>' file. The format is
|
||||
similar as defined in the Hk dft_tools format, but does not store info
|
||||
about correlated shells and irreps
|
||||
|
||||
nk # number of k-points
|
||||
n_el # electron density
|
||||
n_sh # number of total atomic shells
|
||||
at sort l dim # atom, sort, l, dim
|
||||
at sort l dim # atom, sort, l, dim
|
||||
|
||||
After these header lines, the file has to contain the Hamiltonian matrix
|
||||
in orbital space. The standard convention is that you give for each k-point
|
||||
first the matrix of the real part, then the matrix of the imaginary part,
|
||||
and then move on to the next k-point.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
for ig, pgroup in enumerate(pgroups):
|
||||
|
||||
hk_fname = conf_pars.general['basename'] + '.hk%i'%(ig + 1)
|
||||
print " Storing HK-group file '%s'..."%(hk_fname)
|
||||
|
||||
head_shells = []
|
||||
for ish in pgroup.ishells:
|
||||
|
||||
shell = pgroup.shells[ish]
|
||||
|
||||
ion_output = [io + 1 for io in shell.ion_list]
|
||||
|
||||
for iion in ion_output:
|
||||
sh_dict = {}
|
||||
sh_dict['shell_index'] = ish
|
||||
sh_dict['lorb'] = shell.lorb
|
||||
sh_dict['ndim'] = shell.ndim
|
||||
# Convert ion indices from the internal representation (starting from 0)
|
||||
# to conventional VASP representation (starting from 1)
|
||||
|
||||
# Derive sorts from equivalence classes
|
||||
sh_dict['ion_list'] = ion_output
|
||||
sh_dict['ion_sort'] = shell.ion_sort
|
||||
|
||||
|
||||
head_shells.append(sh_dict)
|
||||
|
||||
with open(hk_fname, 'wt') as f:
|
||||
# Eigenvalues within the window
|
||||
nk, nband, ns_band = el_struct.eigvals.shape
|
||||
f.write('%i # number of kpoints\n'%nk)
|
||||
f.write('{0:0.4f} # electron density\n'.format(pgroup.nelect_window(el_struct)))
|
||||
f.write('%i # number of shells\n'%len(head_shells))
|
||||
for head in head_shells:
|
||||
f.write('%i %i %i %i # atom sort l dim\n'%(head['ion_list'][0],head['ion_sort'][0],head['lorb'],head['ndim']))
|
||||
|
||||
norbs = pgroup.hk.shape[2]
|
||||
for isp in xrange(ns_band):
|
||||
for ik in xrange(nk):
|
||||
for io in xrange(norbs):
|
||||
for iop in xrange(norbs):
|
||||
f.write(" {0:14.10f}".format(pgroup.hk[isp,ik,io,iop].real))
|
||||
f.write("\n")
|
||||
for io in xrange(norbs):
|
||||
for iop in xrange(norbs):
|
||||
f.write(" {0:14.10f}".format(pgroup.hk[isp,ik,io,iop].imag))
|
||||
f.write("\n")
|
||||
|
@ -24,13 +24,13 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.proj_group
|
||||
===============
|
||||
plovasp.proj_group
|
||||
==================
|
||||
|
||||
Storage and manipulation of projector groups.
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
from proj_shell import ComplementShell
|
||||
np.set_printoptions(suppress=True)
|
||||
|
||||
################################################################################
|
||||
@ -48,10 +48,9 @@ class ProjectorGroup:
|
||||
the parameters from the config-file (passed in `pars`).
|
||||
|
||||
Parameters:
|
||||
|
||||
- gr_pars (dict) : group parameters from the config-file
|
||||
- shells ([ProjectorShell]) : array of ProjectorShell objects
|
||||
- eigvals (numpy.array) : array of KS eigenvalues
|
||||
- gr_pars (dict) : group parameters from the config-file
|
||||
- shells ([ProjectorShell]) : array of ProjectorShell objects
|
||||
- eigvals (numpy.array) : array of KS eigenvalues
|
||||
|
||||
"""
|
||||
def __init__(self, gr_pars, shells, eigvals):
|
||||
@ -62,16 +61,38 @@ class ProjectorGroup:
|
||||
self.ishells = gr_pars['shells']
|
||||
self.ortho = gr_pars['normalize']
|
||||
self.normion = gr_pars['normion']
|
||||
self.complement = gr_pars['complement']
|
||||
|
||||
self.shells = shells
|
||||
|
||||
# Determine the minimum and maximum band numbers
|
||||
ib_win, ib_min, ib_max = self.select_bands(eigvals)
|
||||
if 'bands' in gr_pars:
|
||||
nk, nband, ns_band = eigvals.shape
|
||||
ib_win = np.zeros((nk, ns_band, 2), dtype=np.int32)
|
||||
ib_win[:,:,0] = gr_pars['bands'][0]-1
|
||||
ib_win[:,:,1] = gr_pars['bands'][1]-1
|
||||
ib_min = gr_pars['bands'][0] - 1
|
||||
ib_max = gr_pars['bands'][1] - 1
|
||||
|
||||
else:
|
||||
ib_win, ib_min, ib_max = self.select_bands(eigvals)
|
||||
self.ib_win = ib_win
|
||||
self.ib_min = ib_min
|
||||
self.ib_max = ib_max
|
||||
self.nb_max = ib_max - ib_min + 1
|
||||
|
||||
|
||||
|
||||
if self.complement:
|
||||
n_bands = self.ib_win[:,:,1] - self.ib_win[:,:,0]+1
|
||||
n_orbs = sum([x.ndim for x in self.shells])
|
||||
assert np.all( n_bands == n_bands[0,0] ), "At each band the same number of bands has to be selected for calculating the complement (to end up with an equal number of orbitals at each k-point)."
|
||||
if n_orbs == n_bands[0,0]:
|
||||
self.complement = False
|
||||
print "\nWARNING: The total number of orbitals in this group is "
|
||||
print "equal to the number of bands. Setting COMPLEMENT to FALSE!\n"
|
||||
|
||||
|
||||
# Select projectors within the energy window
|
||||
for ish in self.ishells:
|
||||
shell = self.shells[ish]
|
||||
@ -156,6 +177,130 @@ class ProjectorGroup:
|
||||
shell = self.shells[ish]
|
||||
shell.proj_win[ion, isp, ik, :nlm, :nb] = p_orth[i1:i2, :nb]
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# calc_hk
|
||||
#
|
||||
################################################################################
|
||||
def calc_hk(self, eigvals):
|
||||
"""
|
||||
Calculate H(k) for a group by applying the projectors P
|
||||
to the eigenvalues eps.
|
||||
|
||||
H_ij(k) = sum_l P*_il eps_l P_lj
|
||||
|
||||
"""
|
||||
|
||||
# here we abuse the get_block_matrix_map(), however, it only works
|
||||
# if self.normion is false
|
||||
temp = self.normion
|
||||
self.normion = False
|
||||
block_maps, ndim = self.get_block_matrix_map()
|
||||
self.normion = temp
|
||||
|
||||
_, ns, nk, _, _ = self.shells[0].proj_win.shape
|
||||
|
||||
self.hk = np.zeros((ns,nk,ndim,ndim), dtype=np.complex128)
|
||||
# Note that 'ns' and 'nk' are the same for all shells
|
||||
for isp in xrange(ns):
|
||||
for ik in xrange(nk):
|
||||
bmin = self.ib_win[ik, isp, 0]
|
||||
bmax = self.ib_win[ik, isp, 1]+1
|
||||
|
||||
nb = bmax - bmin
|
||||
p_mat = np.zeros((ndim, nb), dtype=np.complex128)
|
||||
#print(bmin,bmax,nb)
|
||||
# Combine all projectors of the group to one block projector
|
||||
for bl_map in block_maps:
|
||||
p_mat[:, :] = 0.0j # !!! Clean-up from the last k-point and block!
|
||||
for ibl, block in enumerate(bl_map):
|
||||
i1, i2 = block['bmat_range']
|
||||
ish, ion = block['shell_ion']
|
||||
nlm = i2 - i1 + 1
|
||||
shell = self.shells[ish]
|
||||
p_mat[i1:i2, :nb] = shell.proj_win[ion, isp, ik, :nlm, :nb]
|
||||
|
||||
self.hk[isp,ik,:,:] = np.dot(p_mat*eigvals[ik,bmin:bmax,isp],
|
||||
p_mat.transpose().conjugate())
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# complement
|
||||
#
|
||||
################################################################################
|
||||
def calc_complement(self,eigvals):
|
||||
"""
|
||||
Calculate the complement for a group of projectors.
|
||||
|
||||
This leads to quadtratic projectors P = <l|n> by using a Gram-Schmidt.
|
||||
|
||||
The projector on the orthogonal complement of the existing projectors
|
||||
|l> is P^u = 1 - sum_l |l><l|
|
||||
We get candidates for complement projectors by applying P^u to a Bloch
|
||||
state |n>: |l*> = P^u |n>. For numerical stability we select that Bloch
|
||||
state which leads to the |l*> with the largest norm (that corresponds to
|
||||
that Bloch state with the smallest overlap with the space spanned by |l>)
|
||||
We normalize |l*> and add it to |l>. We do so untill we have as many
|
||||
|l> states as we have |n> states.
|
||||
|
||||
"""
|
||||
|
||||
print '\nCalculating complement\n'
|
||||
|
||||
block_maps, ndim = self.get_block_matrix_map()
|
||||
_, ns, nk, _, _ = self.shells[0].proj_win.shape
|
||||
p_mat = np.zeros((ndim, self.nb_max), dtype=np.complex128)
|
||||
p_full = np.zeros((1,ns,nk,self.nb_max, self.nb_max), dtype=np.complex128)
|
||||
|
||||
# Note that 'ns' and 'nk' are the same for all shells
|
||||
|
||||
|
||||
for isp in xrange(ns):
|
||||
for ik in xrange(nk):
|
||||
bmin = self.ib_win[ik, isp, 0]
|
||||
bmax = self.ib_win[ik, isp, 1]+1
|
||||
|
||||
nb = bmax - bmin
|
||||
# Combine all projectors of the group to one block projector
|
||||
for bl_map in block_maps:
|
||||
p_mat[:, :] = 0.0j # !!! Clean-up from the last k-point and block!
|
||||
for ibl, block in enumerate(bl_map):
|
||||
i1, i2 = block['bmat_range']
|
||||
ish, ion = block['shell_ion']
|
||||
nlm = i2 - i1 + 1
|
||||
shell = self.shells[ish]
|
||||
p_mat[i1:i2, :nb] = shell.proj_win[ion, isp, ik, :nlm, :nb]
|
||||
orbs_done = 1*ndim
|
||||
p_full[0,isp,ik,:ndim,:] = p_mat
|
||||
while orbs_done < self.nb_max:
|
||||
#We calculate the overlap of all bloch states: sum_l <n|l><l|m>
|
||||
overlap = np.dot(p_full[0,isp,ik,:orbs_done,:].transpose().conjugate(),p_full[0,isp,ik,:orbs_done,:])
|
||||
# work is the projector onto the orthogonal complment <n| ( 1 - sum_l |l><l| ) |m>
|
||||
work = np.eye(self.nb_max) - overlap
|
||||
# calculate the norm of the projected bloch function
|
||||
norm = np.sqrt(np.sum(work*work.transpose(),axis=1))
|
||||
# select the bloch function leading to the largest norm
|
||||
max_ind = np.argmax(norm)
|
||||
# normalize and put it to the projectors
|
||||
p_full[0,isp,ik,orbs_done,:] = work[:,max_ind].conjugate()/norm[max_ind]
|
||||
|
||||
orbs_done += 1
|
||||
|
||||
sh_pars = {}
|
||||
sh_pars['lshell'] = -1
|
||||
sh_pars['ions'] = {'nion':1,'ion_list':[[1]]}
|
||||
sh_pars['user_index'] = 'complement'
|
||||
sh_pars['corr'] = False
|
||||
sh_pars['ib_min'] = bmin
|
||||
sh_pars['ib_max'] = bmax
|
||||
sh_pars['ib_win'] = self.ib_win
|
||||
|
||||
self.shells.append(ComplementShell(sh_pars,p_full[:,:,:,ndim:,:],False))
|
||||
self.ishells.append(self.ishells[-1]+1)
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# gen_block_matrix_map
|
||||
@ -299,7 +444,8 @@ class ProjectorGroup:
|
||||
Returns
|
||||
-------
|
||||
|
||||
ib_win, nb_min, nb_max :
|
||||
ib_win, nb_min, nb_max : lowest and highest indices of the selected bands
|
||||
|
||||
"""
|
||||
# Sanity check
|
||||
if self.emin > eigvals.max() or self.emax < eigvals.min():
|
||||
@ -335,5 +481,3 @@ class ProjectorGroup:
|
||||
ib_max = max(ib_max, ib2)
|
||||
|
||||
return ib_win, ib_min, ib_max
|
||||
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.proj_shell
|
||||
===============
|
||||
plovasp.proj_shell
|
||||
==================
|
||||
|
||||
Storage and manipulation on projector shells.
|
||||
"""
|
||||
@ -72,6 +72,8 @@ class ProjectorShell:
|
||||
self.lorb = sh_pars['lshell']
|
||||
self.ions = sh_pars['ions']
|
||||
self.user_index = sh_pars['user_index']
|
||||
self.corr = sh_pars['corr']
|
||||
self.ion_sort = [sh_pars['ion_sort']]
|
||||
self.nc_flag = nc_flag
|
||||
# try:
|
||||
# self.tmatrix = sh_pars['tmatrix']
|
||||
@ -84,12 +86,14 @@ class ProjectorShell:
|
||||
self.nion = self.ions['nion']
|
||||
# Extract ion list and equivalence classes (ion sorts)
|
||||
self.ion_list = sorted(it.chain(*self.ions['ion_list']))
|
||||
self.ion_sort = []
|
||||
for ion in self.ion_list:
|
||||
for icl, eq_cl in enumerate(self.ions['ion_list']):
|
||||
if ion in eq_cl:
|
||||
self.ion_sort.append(icl + 1) # Enumerate classes starting from 1
|
||||
break
|
||||
|
||||
if self.ion_sort[0] is None:
|
||||
self.ion_sort = []
|
||||
for ion in self.ion_list:
|
||||
for icl, eq_cl in enumerate(self.ions['ion_list']):
|
||||
if ion in eq_cl:
|
||||
self.ion_sort.append(icl + 1) # Enumerate classes starting from 1
|
||||
break
|
||||
|
||||
self.ndim = self.extract_tmatrices(sh_pars)
|
||||
|
||||
@ -449,5 +453,60 @@ class ProjectorShell:
|
||||
|
||||
return dos
|
||||
|
||||
################################################################################
|
||||
################################################################################
|
||||
#
|
||||
# class ProjectorShell
|
||||
#
|
||||
################################################################################
|
||||
################################################################################
|
||||
class ComplementShell(ProjectorShell):
|
||||
"""
|
||||
Container of projectors related to a complement shell.
|
||||
|
||||
|
||||
Parameters:
|
||||
|
||||
- sh_pars (dict) : shell parameters from the config-file
|
||||
- proj_compl (numpy.array) : array of complement projectors
|
||||
|
||||
"""
|
||||
def __init__(self, sh_pars, proj_compl, nc_flag):
|
||||
self.lorb = sh_pars['lshell']
|
||||
self.ions = sh_pars['ions']
|
||||
self.user_index = sh_pars['user_index']
|
||||
self.corr = sh_pars['corr']
|
||||
self.nc_flag = nc_flag
|
||||
|
||||
self.ib_min = sh_pars['ib_min']
|
||||
self.ib_max = sh_pars['ib_max']
|
||||
self.ib_win = sh_pars['ib_win']
|
||||
|
||||
|
||||
#self.lm1 = self.lorb**2
|
||||
#self.lm2 = (self.lorb+1)**2
|
||||
|
||||
self.nion = self.ions['nion']
|
||||
# Extract ion list and equivalence classes (ion sorts)
|
||||
self.ion_list = sorted(it.chain(*self.ions['ion_list']))
|
||||
self.ion_sort = []
|
||||
for ion in self.ion_list:
|
||||
for icl, eq_cl in enumerate(self.ions['ion_list']):
|
||||
if ion in eq_cl:
|
||||
self.ion_sort.append(icl + 1) # Enumerate classes starting from 1
|
||||
break
|
||||
|
||||
self.ndim = proj_compl.shape[3]
|
||||
self.proj_win = proj_compl
|
||||
|
||||
def extract_tmatrices(self, sh_pars):
|
||||
raise Exception('not implemented')
|
||||
|
||||
def local_hamiltonian(self, el_struct, site_diag=True, spin_diag=True):
|
||||
raise Exception('not implemented')
|
||||
|
||||
def density_matrix(self, el_struct, site_diag=True, spin_diag=True):
|
||||
raise Exception('not implemented')
|
||||
|
||||
#def density_of_states(self, el_struct, emesh):
|
||||
# raise Exception('not implemented')
|
||||
|
@ -32,6 +32,7 @@ import signal
|
||||
import sys
|
||||
import pytriqs.utility.mpi as mpi
|
||||
import converter
|
||||
from shutil import copyfile
|
||||
|
||||
xch = sys.excepthook
|
||||
def excepthook(typ, value, traceback):
|
||||
@ -40,7 +41,7 @@ def excepthook(typ, value, traceback):
|
||||
mpi.MPI.COMM_WORLD.Abort(1)
|
||||
sys.excepthook = excepthook
|
||||
|
||||
debug = True
|
||||
debug = False
|
||||
#
|
||||
# Helper functions
|
||||
#
|
||||
@ -99,7 +100,7 @@ class bcolors:
|
||||
#
|
||||
# Main self-consistent cycle
|
||||
#
|
||||
def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter):
|
||||
def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter, n_iter_dft, vasp_version):
|
||||
"""
|
||||
"""
|
||||
mpi.report(" Waiting for VASP lock to appear...")
|
||||
@ -120,15 +121,9 @@ def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter):
|
||||
mpi.report(" VASP stopped")
|
||||
vasp_running = False
|
||||
break
|
||||
|
||||
# Tell VASP to stop if the maximum number of iterations is reached
|
||||
iter += 1
|
||||
if iter == n_iter:
|
||||
if mpi.is_master_node():
|
||||
print "\n Maximum number of iterations reached."
|
||||
print " Aborting VASP iterations...\n"
|
||||
f_stop = open('STOPCAR', 'wt')
|
||||
f_stop.write("LABORT = .TRUE.\n")
|
||||
f_stop.close()
|
||||
|
||||
|
||||
if debug: print bcolors.MAGENTA + "rank %s"%(mpi.rank) + bcolors.ENDC
|
||||
err = 0
|
||||
@ -155,9 +150,37 @@ def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter):
|
||||
print "="*80
|
||||
print
|
||||
|
||||
if mpi.is_master_node() and vasp_running:
|
||||
open('./vasp.lock', 'a').close()
|
||||
# check if we should do additional VASP calculations
|
||||
# in the standard VASP version, VASP writes out GAMMA itself
|
||||
# so that if we want to keep GAMMA fixed we have to copy it to
|
||||
# GAMMA_recent and copy it back after VASP has completed an iteration
|
||||
# if we are using a hacked Version of VASP where the write out is
|
||||
# disabled we can skip this step.
|
||||
# the hack consists of removing the call of LPRJ_LDApU in VASP src file
|
||||
# electron.F around line 644
|
||||
iter_dft = 0
|
||||
|
||||
if vasp_version == 'standard':
|
||||
copyfile(src='GAMMA',dst='GAMMA_recent')
|
||||
while iter_dft < n_iter_dft:
|
||||
if mpi.is_master_node():
|
||||
open('./vasp.lock', 'a').close()
|
||||
while is_vasp_lock_present():
|
||||
time.sleep(1)
|
||||
if not is_vasp_running(vasp_pid):
|
||||
mpi.report(" VASP stopped")
|
||||
vasp_running = False
|
||||
break
|
||||
iter_dft += 1
|
||||
if vasp_version == 'standard':
|
||||
copyfile(src='GAMMA_recent',dst='GAMMA')
|
||||
iter += 1
|
||||
if iter == n_iter:
|
||||
print "\n Maximum number of iterations reached."
|
||||
print " Aborting VASP iterations...\n"
|
||||
f_stop = open('STOPCAR', 'wt')
|
||||
f_stop.write("LABORT = .TRUE.\n")
|
||||
f_stop.close()
|
||||
if mpi.is_master_node():
|
||||
total_energy = dft_energy + corr_energy - dft_dc
|
||||
with open('TOTENERGY', 'w') as f:
|
||||
@ -170,7 +193,9 @@ def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter):
|
||||
mpi.report("***Done")
|
||||
|
||||
def main():
|
||||
|
||||
import importlib
|
||||
|
||||
try:
|
||||
vasp_pid = int(sys.argv[1])
|
||||
except (ValueError, KeyError):
|
||||
@ -186,18 +211,33 @@ def main():
|
||||
raise
|
||||
|
||||
try:
|
||||
dmft_script = re.sub("\.py$", "", sys.argv[3])
|
||||
n_iter_dft = int(sys.argv[3])
|
||||
except (ValueError, KeyError):
|
||||
if mpi.is_master_node():
|
||||
print "ERROR: Number of VASP iterations with fixed charge density must be provided as the third argument"
|
||||
raise
|
||||
|
||||
try:
|
||||
dmft_script = re.sub("\.py$", "", sys.argv[4])
|
||||
except:
|
||||
if mpi.is_master_node():
|
||||
print "ERROR: User-defined DMFT script must be provided as the third argument"
|
||||
print "ERROR: User-defined DMFT script must be provided as the fourth argument"
|
||||
raise
|
||||
|
||||
# Optional parameter: config-file name
|
||||
try:
|
||||
cfg_file = sys.argv[4]
|
||||
cfg_file = sys.argv[5]
|
||||
except KeyError:
|
||||
cfg_file = 'plo.cfg'
|
||||
|
||||
try:
|
||||
vasp_version = sys.argv[6]
|
||||
except KeyError:
|
||||
vasp_version = 'standard'
|
||||
|
||||
if vasp_version != 'standard' and vasp_version != 'no_gamma_write':
|
||||
raise Exception('vasp_version has to be standard or no_gamma_write')
|
||||
|
||||
# if len(sys.argv) > 1:
|
||||
# vasp_path = sys.argv[1]
|
||||
# else:
|
||||
@ -211,7 +251,7 @@ def main():
|
||||
|
||||
dmft_mod = importlib.import_module(dmft_script)
|
||||
|
||||
run_all(vasp_pid, dmft_mod.dmft_cycle, cfg_file, n_iter)
|
||||
run_all(vasp_pid, dmft_mod.dmft_cycle, cfg_file, n_iter, n_iter_dft, vasp_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -24,8 +24,8 @@
|
||||
#
|
||||
################################################################################
|
||||
r"""
|
||||
vasp.vaspio
|
||||
===========
|
||||
plovasp.vaspio
|
||||
==============
|
||||
|
||||
Input of required VASP data.
|
||||
|
||||
@ -88,8 +88,12 @@ class VaspData:
|
||||
self.doscar.from_file(vasp_dir)
|
||||
except (IOError, StopIteration):
|
||||
if efermi_required:
|
||||
# raise Exception("Efermi cannot be read from DOSCAR")
|
||||
pass
|
||||
print "!!! WARNING !!!: Error reading from Efermi from DOSCAR, trying LOCPROJ"
|
||||
try:
|
||||
self.plocar.efermi
|
||||
self.doscar.efermi = self.plocar.efermi
|
||||
except NameError:
|
||||
raise Exception("Efermi cannot be read from DOSCAR or LOCPROJ")
|
||||
else:
|
||||
# TODO: This a hack. Find out a way to determine ncdij without DOSCAR
|
||||
print "!!! WARNING !!!: Error reading from DOSCAR, taking Efermi from config"
|
||||
@ -103,16 +107,18 @@ class VaspData:
|
||||
################################################################################
|
||||
################################################################################
|
||||
class Plocar:
|
||||
r"""
|
||||
"""
|
||||
Class containing raw PLO data from VASP.
|
||||
|
||||
Properties
|
||||
----------
|
||||
Properties:
|
||||
- *plo* (numpy.array((nion, ns, nk, nb, nlmmax))) : raw projectors
|
||||
- *params* (dict) : parameters read from PLOCAR
|
||||
- *ferw* (array(nion, ns, nk, nb)) : Fermi weights from VASP
|
||||
|
||||
- *plo* (numpy.array((nion, ns, nk, nb, nlmmax))) : raw projectors
|
||||
- *params* (dict) : parameters read from PLOCAR
|
||||
- *ferw* (array(nion, ns, nk, nb)) : Fermi weights from VASP
|
||||
"""
|
||||
def __init__(self):
|
||||
self.plo = None
|
||||
self.proj_params = None
|
||||
|
||||
def from_file(self, vasp_dir='./', plocar_filename='PLOCAR'):
|
||||
r"""
|
||||
@ -240,7 +246,10 @@ class Plocar:
|
||||
self.nspin = 1 if self.ncdij == 1 else 2
|
||||
self.nspin_band = 2 if self.ncdij == 2 else 1
|
||||
|
||||
self.efermi = float(sline[4])
|
||||
try:
|
||||
self.efermi = float(sline[4])
|
||||
except:
|
||||
print "!!! WARNING !!!: Error reading E-Fermi from LOCPROJ, trying DOSCAR"
|
||||
|
||||
plo = np.zeros((nproj, self.nspin, nk, self.nband), dtype=np.complex128)
|
||||
proj_params = [{} for i in xrange(nproj)]
|
||||
@ -323,14 +332,12 @@ class Poscar:
|
||||
"""
|
||||
Class containing POSCAR data from VASP.
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
nq (int) : total number of ions
|
||||
ntypes ([int]) : number of ion types
|
||||
nions (int) : a list of number of ions of each type
|
||||
a_brav (numpy.array((3, 3), dtype=float)) : lattice vectors
|
||||
q_types ([numpy.array((nions, 3), dtype=float)]) : a list of
|
||||
Properties:
|
||||
- nq (int) : total number of ions
|
||||
- ntypes ([int]) : number of ion types
|
||||
- nions (int) : a list of number of ions of each type
|
||||
- a_brav (numpy.array((3, 3), dtype=float)) : lattice vectors
|
||||
- q_types ([numpy.array((nions, 3), dtype=float)]) : a list of
|
||||
arrays each containing fractional coordinates of ions of a given type
|
||||
"""
|
||||
def __init__(self):
|
||||
@ -350,7 +357,7 @@ class Poscar:
|
||||
"""
|
||||
# Convenince local function
|
||||
def readline_remove_comments():
|
||||
return f.next().split('!')[0].strip()
|
||||
return f.next().split('!')[0].split('#')[0].strip()
|
||||
|
||||
# Add a slash to the path name if necessary
|
||||
if vasp_dir[-1] != '/':
|
||||
@ -443,16 +450,18 @@ class Kpoints:
|
||||
"""
|
||||
Class describing k-points and optionally tetrahedra.
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
- nktot (int) : total number of k-points in the IBZ
|
||||
- kpts (numpy.array((nktot, 3), dtype=float)) : k-point vectors (fractional coordinates)
|
||||
- ntet (int) : total number of k-point tetrahedra
|
||||
- itet (numpy.array((ntet, 5), dtype=float) : array of tetrahedra
|
||||
- volt (float) : volume of a tetrahedron (the k-grid is assumed to
|
||||
be uniform)
|
||||
Properties:
|
||||
- nktot (int) : total number of k-points in the IBZ
|
||||
- kpts (numpy.array((nktot, 3), dtype=float)) : k-point vectors (fractional coordinates)
|
||||
- ntet (int) : total number of k-point tetrahedra
|
||||
- itet (numpy.array((ntet, 5), dtype=float) : array of tetrahedra
|
||||
- volt (float) : volume of a tetrahedron (the k-grid is assumed to
|
||||
be uniform)
|
||||
"""
|
||||
def __init__(self):
|
||||
self.kpts = None
|
||||
self.nktot = None
|
||||
self.kwghts = None
|
||||
#
|
||||
# Reads IBZKPT file
|
||||
#
|
||||
@ -610,6 +619,10 @@ class Doscar:
|
||||
"""
|
||||
Class containing some data from DOSCAR
|
||||
"""
|
||||
def __init__(self):
|
||||
self.ncdij = None
|
||||
self.efermi = None
|
||||
|
||||
def from_file(self, vasp_dir='./', dos_filename='DOSCAR'):
|
||||
"""
|
||||
Reads only E_Fermi from DOSCAR.
|
||||
@ -705,5 +718,3 @@ def read_symmcar(vasp_dir, symm_filename='SYMMCAR'):
|
||||
data.update({ 'nrot': nrot, 'ntrans': ntrans,
|
||||
'lmax': lmax, 'nion': nion,
|
||||
'sym_rots': rot_mats, 'perm_map': rot_map })
|
||||
|
||||
|
||||
|
@ -43,9 +43,36 @@ class VaspConverter(ConverterTools):
|
||||
dft_subgrp = 'dft_input', symmcorr_subgrp = 'dft_symmcorr_input',
|
||||
parproj_subgrp='dft_parproj_input', symmpar_subgrp='dft_symmpar_input',
|
||||
bands_subgrp = 'dft_bands_input', misc_subgrp = 'dft_misc_input',
|
||||
transp_subgrp = 'dft_transp_input', repacking = False):
|
||||
transp_subgrp = 'dft_transp_input', repacking = False,
|
||||
proj_or_hk='proj'):
|
||||
"""
|
||||
Init of the class. Variable filename gives the root of all filenames, e.g. case.ctqmcout, case.h5, and so on.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : string
|
||||
Base name of DFT 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.
|
||||
parproj_subgrp : string, optional
|
||||
Name of subgroup storing partial projector data.
|
||||
symmpar_subgrp : string, optional
|
||||
Name of subgroup storing partial-projector symmetry data.
|
||||
bands_subgrp : string, optional
|
||||
Name of subgroup storing band data.
|
||||
misc_subgrp : string, optional
|
||||
Name of subgroup storing miscellaneous DFT data.
|
||||
transp_subgrp : string, optional
|
||||
Name of subgroup storing transport data.
|
||||
repacking : boolean, optional
|
||||
Does the hdf5 archive need to be repacked to save space?
|
||||
proj_or_hk : string, optional
|
||||
Select scheme to convert between KS bands and localized orbitals.
|
||||
|
||||
"""
|
||||
|
||||
assert type(filename)==StringType, "Please provide the DFT files' base name as a string."
|
||||
@ -61,15 +88,22 @@ class VaspConverter(ConverterTools):
|
||||
self.bands_subgrp = bands_subgrp
|
||||
self.misc_subgrp = misc_subgrp
|
||||
self.transp_subgrp = transp_subgrp
|
||||
assert (proj_or_hk == 'proj') or (proj_or_hk == 'hk'), "proj_or_hk has to be 'proj' of 'hk'"
|
||||
self.proj_or_hk = proj_or_hk
|
||||
|
||||
# Checks if h5 file is there and repacks it if wanted:
|
||||
if (os.path.exists(self.hdf_file) and repacking):
|
||||
ConverterTools.repack(self)
|
||||
|
||||
|
||||
# this is to test pull request
|
||||
def read_data(self, fh):
|
||||
"""
|
||||
Generator for reading plain data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fh : file object
|
||||
file object which is read in.
|
||||
"""
|
||||
for line in fh:
|
||||
line_ = line.strip()
|
||||
@ -82,6 +116,11 @@ class VaspConverter(ConverterTools):
|
||||
def read_header_and_data(self, filename):
|
||||
"""
|
||||
Opens a file and returns a JSON-header and the generator for the plain data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : string
|
||||
file name of the file to read.
|
||||
"""
|
||||
fh = open(filename, 'rt')
|
||||
header = ""
|
||||
@ -121,12 +160,16 @@ class VaspConverter(ConverterTools):
|
||||
SO = ctrl_head['nc_flag']
|
||||
|
||||
kpts = numpy.zeros((n_k, 3))
|
||||
kpts_cart = numpy.zeros((n_k, 3))
|
||||
bz_weights = numpy.zeros(n_k)
|
||||
try:
|
||||
for ik in xrange(n_k):
|
||||
kx, ky, kz = rf.next(), rf.next(), rf.next()
|
||||
kpts[ik, :] = kx, ky, kz
|
||||
bz_weights[ik] = rf.next()
|
||||
for ik in xrange(n_k):
|
||||
kx, ky, kz = rf.next(), rf.next(), rf.next()
|
||||
kpts_cart[ik, :] = kx, ky, kz
|
||||
except StopIteration:
|
||||
raise "VaspConverter: error reading %s"%self.ctrl_file
|
||||
|
||||
@ -148,17 +191,23 @@ class VaspConverter(ConverterTools):
|
||||
jheader, rf = self.read_header_and_data(gr_file)
|
||||
gr_head = json.loads(jheader)
|
||||
|
||||
e_win = gr_head['ewindow']
|
||||
|
||||
nb_max = gr_head['nb_max']
|
||||
p_shells = gr_head['shells']
|
||||
density_required = gr_head['nelect']
|
||||
charge_below = 0.0 # This is not defined in VASP interface
|
||||
|
||||
# Note that in the DftTools convention each site gives a separate correlated shell!
|
||||
n_shells = sum([len(sh['ion_list']) for sh in p_shells])
|
||||
n_corr_shells = sum([len(sh['ion_list']) for sh in p_shells])
|
||||
|
||||
shells = []
|
||||
corr_shells = []
|
||||
shion_to_corr_shell = [[] for ish in xrange(len(p_shells))]
|
||||
shion_to_shell = [[] for ish in xrange(len(p_shells))]
|
||||
cr_shion_to_shell = [[] for ish in xrange(len(p_shells))]
|
||||
shorbs_to_globalorbs = [[] for ish in xrange(len(p_shells))]
|
||||
last_dimension = 0
|
||||
crshorbs_to_globalorbs = []
|
||||
icsh = 0
|
||||
for ish, sh in enumerate(p_shells):
|
||||
ion_list = sh['ion_list']
|
||||
@ -168,16 +217,25 @@ class VaspConverter(ConverterTools):
|
||||
# We set all sites inequivalent
|
||||
pars['sort'] = sh['ion_sort'][i]
|
||||
pars['l'] = sh['lorb']
|
||||
#pars['corr'] = sh['corr']
|
||||
pars['dim'] = sh['ndim']
|
||||
#pars['ion_list'] = sh['ion_list']
|
||||
pars['SO'] = SO
|
||||
# TODO: check what 'irep' entry does (it seems to be very specific to dmftproj)
|
||||
pars['irep'] = 0
|
||||
corr_shells.append(pars)
|
||||
shion_to_corr_shell[ish].append(i)
|
||||
shells.append(pars)
|
||||
shion_to_shell[ish].append(ish)
|
||||
shorbs_to_globalorbs[ish].append([last_dimension,
|
||||
last_dimension+sh['ndim']])
|
||||
last_dimension = last_dimension+sh['ndim']
|
||||
if sh['corr']:
|
||||
corr_shells.append(pars)
|
||||
|
||||
|
||||
# TODO: generalize this to the case of multiple shell groups
|
||||
n_shells = n_corr_shells # No non-correlated shells at the moment
|
||||
shells = corr_shells
|
||||
n_corr_shells = len(corr_shells)
|
||||
|
||||
n_orbs = sum([sh['dim'] for sh in shells])
|
||||
|
||||
# FIXME: atomic sorts in Wien2K are not the same as in VASP.
|
||||
# A symmetry analysis from OUTCAR or symmetry file should be used
|
||||
@ -217,6 +275,7 @@ class VaspConverter(ConverterTools):
|
||||
band_window = [numpy.zeros((n_k, 2), dtype=int) for isp in xrange(n_spin_blocs)]
|
||||
n_orbitals = numpy.zeros([n_k, n_spin_blocs], numpy.int)
|
||||
|
||||
|
||||
for isp in xrange(n_spin_blocs):
|
||||
for ik in xrange(n_k):
|
||||
ib1, ib2 = int(rf.next()), int(rf.next())
|
||||
@ -227,10 +286,33 @@ class VaspConverter(ConverterTools):
|
||||
hopping[ik, isp, ib, ib] = rf.next()
|
||||
f_weights[ik, isp, ib] = rf.next()
|
||||
|
||||
if self.proj_or_hk == 'hk':
|
||||
hopping = numpy.zeros([n_k, n_spin_blocs, n_orbs, n_orbs], numpy.complex_)
|
||||
# skip header lines
|
||||
hk_file = self.basename + '.hk%i'%(ig + 1)
|
||||
f_hk = open(hk_file, 'rt')
|
||||
# skip the header (1 line for n_kpoints, n_electrons, n_shells)
|
||||
# and one line per shell
|
||||
count = 0
|
||||
while count < 3 + n_shells:
|
||||
f_hk.readline()
|
||||
count += 1
|
||||
rf_hk = self.read_data(f_hk)
|
||||
for isp in xrange(n_spin_blocs):
|
||||
for ik in xrange(n_k):
|
||||
n_orbitals[ik, isp] = n_orbs
|
||||
for ib in xrange(n_orbs):
|
||||
for jb in xrange(n_orbs):
|
||||
hopping[ik, isp, ib, jb] = rf_hk.next()
|
||||
for ib in xrange(n_orbs):
|
||||
for jb in xrange(n_orbs):
|
||||
hopping[ik, isp, ib, jb] += 1j*rf_hk.next()
|
||||
rf_hk.close()
|
||||
|
||||
# Projectors
|
||||
# print n_orbitals
|
||||
# print [crsh['dim'] for crsh in corr_shells]
|
||||
proj_mat = numpy.zeros([n_k, n_spin_blocs, n_corr_shells, max([crsh['dim'] for crsh in corr_shells]), numpy.max(n_orbitals)], numpy.complex_)
|
||||
proj_mat_csc = numpy.zeros([n_k, n_spin_blocs, sum([sh['dim'] for sh in shells]), numpy.max(n_orbitals)], numpy.complex_)
|
||||
|
||||
# TODO: implement reading from more than one projector group
|
||||
# In 'dmftproj' each ion represents a separate correlated shell.
|
||||
@ -249,14 +331,37 @@ class VaspConverter(ConverterTools):
|
||||
for isp in xrange(n_spin_blocs):
|
||||
for ik in xrange(n_k):
|
||||
for ion in xrange(len(sh['ion_list'])):
|
||||
icsh = shion_to_corr_shell[ish][ion]
|
||||
for ilm in xrange(sh['ndim']):
|
||||
for ilm in xrange(shorbs_to_globalorbs[ish][ion][0],shorbs_to_globalorbs[ish][ion][1]):
|
||||
for ib in xrange(n_orbitals[ik, isp]):
|
||||
# This is to avoid confusion with the order of arguments
|
||||
pr = rf.next()
|
||||
pi = rf.next()
|
||||
proj_mat[ik, isp, icsh, ilm, ib] = complex(pr, pi)
|
||||
proj_mat_csc[ik, isp, ilm, ib] = complex(pr, pi)
|
||||
|
||||
# now save only projectors with flag 'corr' to proj_mat
|
||||
proj_mat = numpy.zeros([n_k, n_spin_blocs, n_corr_shells, max([crsh['dim'] for crsh in corr_shells]), numpy.max(n_orbitals)], numpy.complex_)
|
||||
if self.proj_or_hk == 'proj':
|
||||
for ish, sh in enumerate(p_shells):
|
||||
if sh['corr']:
|
||||
for isp in xrange(n_spin_blocs):
|
||||
for ik in xrange(n_k):
|
||||
for ion in xrange(len(sh['ion_list'])):
|
||||
icsh = shion_to_shell[ish][ion]
|
||||
for iclm,ilm in enumerate(xrange(shorbs_to_globalorbs[ish][ion][0],shorbs_to_globalorbs[ish][ion][1])):
|
||||
for ib in xrange(n_orbitals[ik, isp]):
|
||||
proj_mat[ik,isp,icsh,iclm,ib] = proj_mat_csc[ik,isp,ilm,ib]
|
||||
elif self.proj_or_hk == 'hk':
|
||||
|
||||
for ish, sh in enumerate(p_shells):
|
||||
if sh['corr']:
|
||||
for ion in xrange(len(sh['ion_list'])):
|
||||
icsh = shion_to_shell[ish][ion]
|
||||
for isp in xrange(n_spin_blocs):
|
||||
for ik in xrange(n_k):
|
||||
for iclm,ilm in enumerate(xrange(shorbs_to_globalorbs[ish][ion][0],shorbs_to_globalorbs[ish][ion][1])):
|
||||
proj_mat[ik,isp,icsh,iclm,ilm] = 1.0
|
||||
|
||||
#corr_shell.pop('ion_list')
|
||||
things_to_set = ['n_shells','shells','n_corr_shells','corr_shells','n_spin_blocs','n_orbitals','n_k','SO','SP','energy_unit']
|
||||
for it in things_to_set:
|
||||
# print "%s:"%(it), locals()[it]
|
||||
@ -268,6 +373,8 @@ class VaspConverter(ConverterTools):
|
||||
rf.close()
|
||||
|
||||
|
||||
proj_or_hk = self.proj_or_hk
|
||||
|
||||
# Save it to the HDF:
|
||||
with HDFArchive(self.hdf_file,'a') as ar:
|
||||
if not (self.dft_subgrp in ar): ar.create_group(self.dft_subgrp)
|
||||
@ -275,7 +382,9 @@ class VaspConverter(ConverterTools):
|
||||
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']
|
||||
'n_inequiv_shells', 'corr_to_inequiv', 'inequiv_to_corr','proj_or_hk','kpts','kpts_cart']
|
||||
if self.proj_or_hk == 'hk' or True:
|
||||
things_to_save.append('proj_mat_csc')
|
||||
for it in things_to_save: ar[self.dft_subgrp][it] = locals()[it]
|
||||
|
||||
# Store Fermi weights to 'dft_misc_input'
|
||||
@ -296,6 +405,24 @@ class VaspConverter(ConverterTools):
|
||||
Reads input for the band window from bandwin_file, which is case.oubwin,
|
||||
structure from struct_file, which is case.struct,
|
||||
symmetries from outputs_file, which is case.outputs.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
bandwin_file : string
|
||||
filename of .oubwin/up/dn file.
|
||||
struct_file : string
|
||||
filename of .struct file.
|
||||
outputs_file : string
|
||||
filename of .outputs file.
|
||||
misc_subgrp : string
|
||||
name of the subgroup in which to save
|
||||
SO : boolean
|
||||
spin-orbit switch
|
||||
SP : int
|
||||
spin
|
||||
n_k : int
|
||||
number of k-points
|
||||
|
||||
"""
|
||||
|
||||
if not (mpi.is_master_node()): return
|
||||
@ -390,6 +517,15 @@ class VaspConverter(ConverterTools):
|
||||
def convert_symmetry_input(self, ctrl_head, orbits, symm_subgrp):
|
||||
"""
|
||||
Reads input for the symmetrisations from symm_file, which is case.sympar or case.symqmc.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctrl_head : dict
|
||||
dictionary of header of .ctrl file
|
||||
orbits : list of shells
|
||||
contains all shells
|
||||
symm_subgrp : name of symmetry group in h5 archive
|
||||
|
||||
"""
|
||||
|
||||
# In VASP interface the symmetries are read directly from *.ctrl file
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user