3
0
mirror of https://github.com/triqs/dft_tools synced 2024-07-17 08:30:35 +02:00
dft_tools/doc/guide/BasisRotation.rst
2019-07-18 14:16:37 +02:00

77 lines
2.8 KiB
ReStructuredText

.. _plovasp:
Numerical Treatment of the Sign-Problem: Basis Rotations
=======
When performing calculations with off-diagonal complex hybridisation or local Hamiltonian, one is
often limited by the fermionic sign-problem. However, as the sign is no
physical observable, one can try to improve the calculation by rotating
to another basis.
While the choice of basis to perform the calculation in can be chosen
arbitrarily, two choices which have shown good results are the basis
which diagonalizes the local Hamiltonian or the density matrix of then
system.
The transformation matrix can be stored in the :class:`BlockStructure` and the
transformation is automatically performed when using :class:`SumkDFT`'s :meth:`extract_G_loc`
and :meth:`put_Sigma` (see below).
Finding the Transformation Matrix
-----------------
The :class:`TransBasis` class offers a simple mehod to calculate the transformation
matrices to a basis where either the local Hamiltonian or the density matrix
is diagonal::
from triqs_dft_tools.trans_basis import TransBasis
TB = TransBasis(SK)
TB.calculate_diagonalisation_matrix(prop_to_be_diagonal='eal', calc_in_solver_blocks = True)
SK.block_structure.transformation = [{'ud':TB.w}]
Transforming Green's functions manually
-----------------
One can transform Green's functions manually using the :meth:`convert_gf` method::
# Rotate a Green's function from solver-space to sumk-space
new_gf = block_structure.convert_gf(old_gf, space_from='solver', space_to='sumk')
Automatic transformation during the DMFT loop
-----------------
During a DMFT loop one is switching back and forth between Sumk-Space and Solver-Space
in each iteration. Once the block_structure.transformation property is set, this can be
done automatically::
for it in range(iteration_offset, iteration_offset + n_iterations):
# every GF is in solver space here
S.G0_iw << inverse(S.Sigma_iw + inverse(S.G_iw))
# solve the impurity in solver space -> hopefully better sign
S.solve(h_int = H, **p)
# calc_dc(..., transform = True) by default
SK.calc_dc(S.G_iw.density(), U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type)
# put_Sigma(..., transform_to_sumk_blocks = True) by default
SK.put_Sigma([S.Sigma_iw])
SK.calc_mu()
# extract_G_loc(..., transform_to_solver_blocks = True) by default
S.G_iw << SK.extract_G_loc()[0]
.. warning::
One must not forget to also transform the interaction Hamiltonian to the diagonal basis!
This can be done with the :meth:`transform_U_matrix` method. However, due to different
conventions in this method, one must pass the conjugated version of the transformation matrix::
U_trans = transform_U_matrix(U, SK.block_structure.transformation[0]['ud'].conjugate())