mirror of
https://github.com/triqs/dft_tools
synced 2025-01-10 04:58:19 +01:00
77 lines
2.8 KiB
ReStructuredText
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())
|