From 4b09b97ce4a1f33adb7be4ea7cb57453a18e72f7 Mon Sep 17 00:00:00 2001 From: aichhorn Date: Thu, 30 Apr 2020 12:47:03 +0200 Subject: [PATCH] Included block_structure.convert_operator() in doc and non-SOC tutorial --- doc/guide/BasisRotation.rst | 18 +++++++++++++----- .../images_scripts/Sr2MgOsO6_noSOC.py | 14 +++++--------- doc/tutorials/sr2mgoso6_nosoc.rst | 13 +++++++------ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/doc/guide/BasisRotation.rst b/doc/guide/BasisRotation.rst index 88108f1e..b0df7fc4 100644 --- a/doc/guide/BasisRotation.rst +++ b/doc/guide/BasisRotation.rst @@ -67,8 +67,16 @@ done automatically, meaning that :class:`SumkDFT`'s :meth:`extract_G_loc`, :meth S.G_iw << SK.extract_G_loc()[0] .. warning:: - Before doing the DMFT self-consistency loop, 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()) + Before doing the DMFT self-consistency loop, one must not forget to also transform the + interaction Hamiltonian to the diagonal basis! + This can be also be done with a method of the :class:`BlockStructure` class, + namely the :meth:`convert_operator` method. Having set up a Hamiltonian in the *sumk* structure, it can easily + be transformed to the *solver* structure (including rotations of basis, picking of orbitals, + making matrices diagonal, etc) by:: + + H_solver = SK.block_structure.convert_operator(H_sumk) + + We refer to the tutorials on how to set up the Hamiltonian H_sumk in selected cases. + Note that this transformation might generally lead to complex values in the + interaction Hamiltonian. Unless you know better and can make everything real, + you should take care of using the correct version of the TRIQS CTQMC solver. \ No newline at end of file diff --git a/doc/tutorials/images_scripts/Sr2MgOsO6_noSOC.py b/doc/tutorials/images_scripts/Sr2MgOsO6_noSOC.py index 232c087d..8740b061 100644 --- a/doc/tutorials/images_scripts/Sr2MgOsO6_noSOC.py +++ b/doc/tutorials/images_scripts/Sr2MgOsO6_noSOC.py @@ -23,22 +23,18 @@ SK.calculate_diagonalization_matrix(prop_to_be_diagonal='eal',calc_in_solver_blo # Now we pick the orbitals: # BE CAREFUL: THIS NEEDS TO BE DONE PROPERLY # AND IS DIFFERENT FORM CASE TO CASE! -indices_to_pick_sumk = [1,3,4] SK.block_structure.pick_gf_struct_solver([{'up_1': [0],'up_2': [0],'up_3': [0],'down_1': [0],'down_2': [0],'down_3': [0]}]) ########################### -# Now we set up the U matrix, first in cubic (Wien2k) convention: +# Now we set up the U matrix, first in cubic Wien2k convention: U = 2.0 J = 0.2 U_mat = U_matrix(l=2,U_int=U,J_hund=J,basis='other', T=SK.T[0].conjugate()) -# Now we transform the U Matrix: -U_trans = transform_U_matrix(U_mat, SK.block_structure.transformation[0]['up'].conjugate()) -# pick out the relevant orbitals: -U_red = subarray(U_trans,len(U_trans.shape)*[indices_to_pick_sumk]) - -# Finally, set up the Hamiltonian: -h_int = h_int_slater(['up','down'], indices_to_pick_sumk, U_red, map_operator_structure=SK.block_structure.sumk_to_solver[0], off_diag=False, complex=False) +# Now we set up the Hamiltonian: +h_sumk = h_int_slater(['up','down'], range(5), U_mat, off_diag=True) +# And now we rotate into solver space: +h_int = SK.block_structure.convert_operator(h_sumk) # Solver Init: beta = 40.0 diff --git a/doc/tutorials/sr2mgoso6_nosoc.rst b/doc/tutorials/sr2mgoso6_nosoc.rst index 6902fef0..534e5cd2 100644 --- a/doc/tutorials/sr2mgoso6_nosoc.rst +++ b/doc/tutorials/sr2mgoso6_nosoc.rst @@ -130,12 +130,13 @@ We now set up the interaction Hamiltonian. Since we want to rotate the interacti J = 0.2 U_mat = U_matrix(l=2,U_int=U,J_hund=J,basis='other', T=SK.T[0].conjugate()) -In the last line we use the Wien2k convention to write the U matrix in the cubic harmonics. Next, we want to rotate it, and pick out only the relevant :math:`t_{2g}` orbitals. At this step we need to give the indices of the wanted orbitals in the *sumk* basis:: +In the last line we use the Wien2k convention to write the U matrix in the cubic harmonics. Next, we want to set up a Hamiltonian and rotate it into the *solver* basis:: - U_trans = transform_U_matrix(U_mat, SK.block_structure.transformation[0]['up'].conjugate()) - indices_to_pick_sumk = [1,3,4] # these are the relevant indices in the sumk basis - U_red = subarray(U_trans,len(U_trans.shape)*[indices_to_pick_sumk]) - h_int = h_int_slater(['up','down'], indices_to_pick_sumk, U_red, map_operator_structure=SK.block_structure.sumk_to_solver[0], off_diag=False, complex=False) + h_sumk = h_int_slater(['up','down'], range(5), U_mat, off_diag=True) + h_int = SK.block_structure.convert_operator(h_sumk) + h_int = h_int.real + +Note that we needed to set up the interaction matrix for the full set of five *d* orbitals. The :meth:`convert_operator` method then takes care of rotating and picking the relevant orbitals. In the last line above we made the Hamiltonian real, since we know it this case that there are only real numbers in the interaction Hamiltonian. Note that this is not generally the case! Now we have the interaction Hamiltonian for the solver, which we set up next:: @@ -201,7 +202,7 @@ The DMFT loop itself looks very much the same as in :ref:`SrVO3`:: # Save stuff into the user_data group of hdf5 archive in case of rerun: SK.save(['chemical_potential','dc_imp','dc_energ']) -The only difference to the other example is in the initialisation of the real part of the self energy. We cannot just take an element of the *dc_imp* array, since this array is stored in the *sumk* structure. Therefore, we first need to transform this matrix into *solver* space, and then take the appropriate matrix element. After the first iteration (here done with 24e6 MC sweeps), you should get self energies like this: +The only difference to the other example is in the initialisation of the real part of the self energy. We cannot just take an element of the *dc_imp* array, since this array is stored in the *sumk* structure. Therefore, we first need to transform this matrix into *solver* space, and then take the appropriate matrix element. After the first iteration (here done with 24e6 MC sweeps and using the real version of the CTMQC solver), you should get self energies like this: .. image:: images_scripts/Sr2MgOsO6_noSOC_Sigmas.png :width: 600