From 37ccb46a8ccd277237a0286a546c0d1b1c134693 Mon Sep 17 00:00:00 2001 From: hschnait Date: Wed, 29 Apr 2020 16:13:06 +0200 Subject: [PATCH] Add convert_operator method to block_structure + Tests --- python/block_structure.py | 44 ++++++++++++++++++++++++++++++++++++ test/basis_transformation.py | 29 ++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/python/block_structure.py b/python/block_structure.py index 4b40a69a..86147109 100644 --- a/python/block_structure.py +++ b/python/block_structure.py @@ -769,6 +769,50 @@ class BlockStructure(object): "block " + block + \ " has wrong indices (shell {})".format(ish) + def convert_operator(self, O, ish=0): + """ Converts a second-quantization operator from sumk structure + to solver structure. + + Parameters + ---------- + O : pytriqs.operators.Operator + Operator in sumk structure + + ish : int + shell index on which the operator acts + """ + + from pytriqs.operators import Operator, c, c_dag + + T = self.transformation[ish] + sk2s = self.sumk_to_solver[ish] + + O_out = Operator(0) + + for monomial in O: + coefficient = monomial[-1] + new_monomial = Operator(1) + #if coefficient > 1e-10: + for single_operator in monomial[0]: + new_single_operator = Operator(0) + daggered = single_operator[0] + + blockname = single_operator[1][0] + i = single_operator[1][1] + for j in range(len(T[blockname])): + if sk2s[(blockname, j)] != (None, None): + if daggered: + new_single_operator += (T[blockname][j,i] * c_dag(*sk2s[(blockname, j)])) + else: + new_single_operator += (T[blockname][j,i].conjugate() * c(*sk2s[(blockname, j)])) + + new_monomial *= new_single_operator + + O_out += new_monomial * coefficient + return O_out + + + def convert_gf(self, G, G_struct=None, ish_from=0, ish_to=None, show_warnings=True, G_out=None, space_from='solver', space_to='solver', ish=None, **kwargs): """ Convert BlockGf from its structure to this structure. diff --git a/test/basis_transformation.py b/test/basis_transformation.py index dd0ddd46..05586a2d 100644 --- a/test/basis_transformation.py +++ b/test/basis_transformation.py @@ -68,3 +68,32 @@ dm = SK.density_matrix(method='using_point_integration') for dmi in dm: for e in dmi: assert is_diagonal_matrix(np.dot(np.dot(t_solver_dm[0][e], dmi[e].conj().T),t_solver_dm[0][e].conj().T)) + + +# Test convert_operator +SK = SumkDFT(hdf_file = 'SrVO3.h5', use_dft_blocks=True) +BS = SK.block_structure +from pytriqs.operators.util import h_int_slater, U_matrix, t2g_submatrix, transform_U_matrix + + +U3x3 = t2g_submatrix(U_matrix(2, U_int=2, J_hund=0.2, basis='spheric')) + +BS.transformation = [{'up':np.eye(3), 'down': np.eye(3)}] +H0 = h_int_slater(spin_names=['up','down'], orb_names=range(3), U_matrix=U3x3, off_diag=False) +H1 = h_int_slater(spin_names=['up','down'], orb_names=range(3), U_matrix=U3x3, off_diag=True) +assert( H0 == BS.convert_operator(H1) ) + +# Trafo Matrix switching index 1 & 2 +BS.transformation = [{'up':np.array([[1,0,0],[0,0,1],[0,1,0]]), 'down': np.array([[1,0,0],[0,0,1],[0,1,0]])}] +H2 = BS.convert_operator(h_int_slater(spin_names=['up','down'], orb_names=[0,2,1], U_matrix=U3x3, off_diag=True)) +assert( H0 == H2 ) + +BS.transformation = [{'up':np.array([[1,0,0],[0,1/np.sqrt(2),1/np.sqrt(2)],[0,1/np.sqrt(2),-1/np.sqrt(2)]]), 'down': np.array([[1,0,0],[0,1/np.sqrt(2),1/np.sqrt(2)],[0,1/np.sqrt(2),-1/np.sqrt(2)]])}] +H3 = BS.convert_operator(h_int_slater(spin_names=['up','down'], orb_names=[0,1,2], U_matrix=U3x3, off_diag=True)) +for op in H3: + for c_op in op[0]: + assert(BS.gf_struct_solver_dict[0][c_op[1][0]][c_op[1][1]] is not None) # This crashes with a key error if the operator structure is not the solver structure + +U_trafod = transform_U_matrix(U3x3, BS.transformation[0]['up'].conjugate()) # The notorious .conjugate() +H4 = h_int_slater(spin_names=['up','down'], orb_names=range(3), U_matrix=U_trafod, map_operator_structure=BS.sumk_to_solver[0]) +assert( H4 == H3 ) # check that convert_operator does the same as transform_U_matrix