mirror of
https://github.com/triqs/dft_tools
synced 2024-07-17 08:30:35 +02:00
77 lines
3.3 KiB
ReStructuredText
77 lines
3.3 KiB
ReStructuredText
.. _basisrotation:
|
|
|
|
Numerical Treatment of the Sign-Problem: Basis Rotations
|
|
=======
|
|
|
|
When performing calculations with off-diagonal terms in the hybridisation function or in the local Hamiltonian, one is
|
|
often limited by the fermionic sign-problem slowing down the QMC calculations significantly. This can occur for instance if the crystal shows locally rotated or distorted cages, or when spin-orbit coupling is included. The examples for this are included in the :ref:`tutorials` of this documentation.
|
|
|
|
However, as the fermonic sign in the QMC calculation is no
|
|
physical observable, one can try to improve the calculation by rotating
|
|
to another basis. While this basis can in principle be chosen arbitrarily,
|
|
two choices which have shown good results; name the basis sets that diagonalize the local Hamiltonian or the local density matrix of the
|
|
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 method 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 often switching back and forth between the unrotated basis (Sumk-Space) and the rotated basis that is used by the QMC Solver. However, this need not be done manually each time. Instead,
|
|
once the block_structure.transformation property is set as shown above, this is
|
|
done automatically, meaning that :class:`SumkDFT`'s :meth:`extract_G_loc`
|
|
and :meth:`put_Sigma` are doing the transformations by default::
|
|
|
|
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())
|