def S_op(component, spin_names, orb_names, off_diag=None, map_operator_structure=None): r""" Create a component of the spin vector operator. .. math:: \hat S_{x,y,z} = \frac{1}{2}\sum_{i\sigma\sigma'} a^\dagger_{i\sigma} \mathbf{\tau}^{x,y,z}_{\sigma\sigma'} a_{i\sigma'}, \quad\hat S_\pm = \hat S_x \pm i \hat S_y. Parameters ---------- component : string Component to be created, one of 'x', 'y', 'z', '+', or '-'. *Warning*: y-component is not supported at the moment! spin_names : list of strings Names of the spins, e.g. ['up','down']. orb_names : list of strings or int Names of the orbitals, e.g. [0,1,2] or ['t2g','eg']. off_diag : boolean Do we have (orbital) off-diagonal elements? If yes, the operators and blocks are denoted by ('spin', 'orbital'), otherwise by ('spin_orbital',0). map_operator_structure : dict Mapping of names of GF blocks names from one convention to another, e.g. {('up', 0): ('up_0', 0), ('down', 0): ('down_0',0)}. If provided, the operators and blocks are denoted by the mapping of ``('spin', 'orbital')``. Returns ------- S : Operator The component of the spin vector operator. """ # FIXME assert component != 'y', "We cannot construct operators with complex coefficients at the moment. Sorry for that!" mkind = get_mkind(off_diag, map_operator_structure) pm = pauli_matrix[component] S = Operator() spin_range = range(len(spin_names)) for n1, n2 in product(spin_range, spin_range): for on in orb_names: S += 0.5 * c_dag(*mkind(spin_names[n1], on)) * pm[n1, n2] * c( *mkind(spin_names[n2], on)) return S
def S_op(component, spin_names, orb_names, off_diag = None, map_operator_structure = None): r""" Create a component of the spin vector operator. .. math:: \hat S_{x,y,z} = \frac{1}{2}\sum_{i\sigma\sigma'} a^\dagger_{i\sigma} \mathbf{\tau}^{x,y,z}_{\sigma\sigma'} a_{i\sigma'}, \quad\hat S_\pm = \hat S_x \pm i \hat S_y. Parameters ---------- component : string Component to be created, one of 'x', 'y', 'z', '+', or '-'. *Warning*: y-component is not supported at the moment! spin_names : list of strings Names of the spins, e.g. ['up','down']. orb_names : list of strings or int Names of the orbitals, e.g. [0,1,2] or ['t2g','eg']. off_diag : boolean Do we have (orbital) off-diagonal elements? If yes, the operators and blocks are denoted by ('spin', 'orbital'), otherwise by ('spin_orbital',0). map_operator_structure : dict Mapping of names of GF blocks names from one convention to another, e.g. {('up', 0): ('up_0', 0), ('down', 0): ('down_0',0)}. If provided, the operators and blocks are denoted by the mapping of ``('spin', 'orbital')``. Returns ------- S : Operator The component of the spin vector operator. """ # FIXME assert component != 'y', "We cannot construct operators with complex coefficients at the moment. Sorry for that!" mkind = get_mkind(off_diag,map_operator_structure) pm = pauli_matrix[component] S = Operator() spin_range = range(len(spin_names)) for n1, n2 in product(spin_range,spin_range): for on in orb_names: S += 0.5 * c_dag(*mkind(spin_names[n1],on)) * pm[n1,n2] * c(*mkind(spin_names[n2],on)) return S
def L_op(component, spin_names, orb_names, off_diag=None, map_operator_structure=None, basis='spherical', T=None): r""" Create a component of the orbital momentum vector operator. .. math:: \hat L_{z,+,-} &= \sum_{ii'\sigma} a^\dagger_{i\sigma} L^{z,+,-}_{ii'} a_{i'\sigma},\\ \hat L_x &= \frac{1}{2}(\hat L_+ + \hat L_-),\ \hat L_y = \frac{1}{2i}(\hat L_+ - \hat L_-),\\ L^z_{ii'} &= i\delta_{i,i'}, \ L^+_{ii'} = \delta_{i,i'+1}\sqrt{l(l+1)-i'(i'+1)}, \ L^+_{ii'} = \delta_{i,i'-1}\sqrt{l(l+1)-i'(i'-1)}. Parameters ---------- component : string Component to be created, one of 'x', 'y', 'z', '+', or '-'. *Warning*: y-component is not supported at the moment! spin_names : list of strings Names of the spins, e.g. ['up','down']. orb_names : list of strings or int Names of the orbitals, e.g. [0,1,2] or ['t2g','eg']. off_diag : boolean Do we have (orbital) off-diagonal elements? If yes, the operators and blocks are denoted by ('spin', 'orbital'), otherwise by ('spin_orbital',0). map_operator_structure : dict Mapping of names of GF blocks names from one convention to another, e.g. {('up', 0): ('up_0', 0), ('down', 0): ('down_0',0)}. If provided, the operators and blocks are denoted by the mapping of ``('spin', 'orbital')``. basis : string, optional The basis in which the interaction matrix should be computed. Takes the values - 'spherical': spherical harmonics, - 'cubic': cubic harmonics (valid only for the integer orbital momenta, i.e. for odd sizes of orb_names), - 'other': other basis type as given by the transformation matrix T. T : real/complex numpy array, optional Transformation matrix for basis change. Must be provided if basis='other'. Returns ------- L : Operator The component of the orbital momentum vector operator. """ # FIXME assert component != 'y', "We cannot construct operators with complex coefficients at the moment. Sorry for that!" l = (len(orb_names) - 1) / 2.0 L_melem_dict = { 'z': lambda m, mp: m if np.isclose(m, mp) else 0, '+': lambda m, mp: np.sqrt(l * (l + 1) - mp * (mp + 1)) if np.isclose(m, mp + 1) else 0, '-': lambda m, mp: np.sqrt(l * (l + 1) - mp * (mp - 1)) if np.isclose(m, mp - 1) else 0, 'x': lambda m, mp: 0.5 * (L_melem_dict['+'](m, mp) + L_melem_dict['-'] (m, mp)), 'y': lambda m, mp: -0.5j * (L_melem_dict['+'](m, mp) - L_melem_dict['-'] (m, mp)) } L_melem = L_melem_dict[component] orb_range = range(int(2 * l + 1)) L_matrix = np.array([[L_melem(o1 - l, o2 - l) for o2 in orb_range] for o1 in orb_range]) # Transform from spherical basis if needed if basis == "cubic": if not np.isclose(np.mod(l, 1), 0): raise ValueError( "L_op: cubic basis is only defined for the integer orbital momenta." ) T = spherical_to_cubic(l) if basis == "other" and T is None: raise ValueError("L_op: provide T for other bases.") if T is not None: L_matrix = np.einsum("ij,jk,kl", np.conj(T), L_matrix, np.transpose(T)) mkind = get_mkind(off_diag, map_operator_structure) L = Operator() for sn in spin_names: for o1, o2 in product(orb_range, orb_range): L += c_dag(*mkind(sn, orb_names[o1])) * L_matrix[o1, o2] * c( *mkind(sn, orb_names[o2])) return L
def ls_op(spin_names, orb_names, off_diag=None, map_operator_structure=None, basis='spherical', T=None): """one-body spin-orbit coupling operator""" spin_range = range(len(spin_names)) l = (len(orb_names) - 1) / 2.0 orb_range = range(int(2 * l + 1)) pauli_matrix = { 'x': np.array([[0, 1], [1, 0]]), 'y': np.array([[0, -1j], [1j, 0]]), 'z': np.array([[1, 0], [0, -1]]), '+': np.array([[0, 2], [0, 0]]), '-': np.array([[0, 0], [2, 0]]) } L_melem_dict = { 'z': lambda m, mp: m if np.isclose(m, mp) else 0, '+': lambda m, mp: np.sqrt(l * (l + 1) - mp * (mp + 1)) if np.isclose(m, mp + 1) else 0, '-': lambda m, mp: np.sqrt(l * (l + 1) - mp * (mp - 1)) if np.isclose(m, mp - 1) else 0, 'x': lambda m, mp: 0.5 * (L_melem_dict['+'](m, mp) + L_melem_dict['-'] (m, mp)), 'y': lambda m, mp: -0.5j * (L_melem_dict['+'](m, mp) - L_melem_dict['-'] (m, mp)) } # define S matrix S_matrix = {} for component in ['z', '+', '-']: pm = pauli_matrix[component] S_matrix[component] = np.array( [[0.5 * pm[n1, n2] for n2 in spin_range] for n1 in spin_range]) # define L matrix L_matrix = {} for component in ['z', '+', '-']: L_melem = L_melem_dict[component] L_matrix[component] = np.array( [[L_melem(o1 - l, o2 - l) for o2 in orb_range] for o1 in orb_range]) # Transform from spherical basis if needed if basis == "cubic": if not np.isclose(np.mod(l, 1), 0): raise ValueError( "L_op: cubic basis is only defined for the integer orbital momenta." ) T = spherical_to_cubic(l) if basis == "other" and T is None: raise ValueError("L_op: provide T for other bases.") if T is not None: L_matrix = np.einsum("ij,jk,kl", np.conj(T), L_matrix, np.transpose(T)) # LS_matrix[n1,n2,o1,o2] = sum_x S_matrix[x][n1,n2] * L_matrix[x][o1,o2] LS_matrix = np.einsum("ij,kl", S_matrix['z'], L_matrix['z'])\ + np.einsum("ij,kl", S_matrix['+'], L_matrix['-']) * 0.5\ + np.einsum("ij,kl", S_matrix['-'], L_matrix['+']) * 0.5 mkind = get_mkind(off_diag, map_operator_structure) ls = Operator() for n1, n2 in product(spin_range, spin_range): for o1, o2 in product(orb_range, orb_range): ls += c_dag(*mkind(spin_names[n1], orb_names[o1])) * LS_matrix[ n1, n2, o1, o2] * c(*mkind(spin_names[n2], orb_names[o2])) return ls
def L_op(component, spin_names, orb_names, off_diag = None, map_operator_structure = None, basis='spherical', T=None): r""" Create a component of the orbital momentum vector operator. .. math:: \hat L_{z,+,-} &= \sum_{ii'\sigma} a^\dagger_{i\sigma} L^{z,+,-}_{ii'} a_{i'\sigma},\\ \hat L_x &= \frac{1}{2}(\hat L_+ + \hat L_-),\ \hat L_y = \frac{1}{2i}(\hat L_+ - \hat L_-),\\ L^z_{ii'} &= i\delta_{i,i'}, \ L^+_{ii'} = \delta_{i,i'+1}\sqrt{l(l+1)-i'(i'+1)}, \ L^+_{ii'} = \delta_{i,i'-1}\sqrt{l(l+1)-i'(i'-1)}. Parameters ---------- component : string Component to be created, one of 'x', 'y', 'z', '+', or '-'. spin_names : list of strings Names of the spins, e.g. ['up','down']. orb_names : list of strings or int Names of the orbitals, e.g. [0,1,2] or ['t2g','eg']. off_diag : boolean Do we have (orbital) off-diagonal elements? If yes, the operators and blocks are denoted by ('spin', 'orbital'), otherwise by ('spin_orbital',0). map_operator_structure : dict Mapping of names of GF blocks names from one convention to another, e.g. {('up', 0): ('up_0', 0), ('down', 0): ('down_0',0)}. If provided, the operators and blocks are denoted by the mapping of ``('spin', 'orbital')``. basis : string, optional The basis in which the interaction matrix should be computed. Takes the values - 'spherical': spherical harmonics, - 'cubic': cubic harmonics (valid only for the integer orbital momenta, i.e. for odd sizes of orb_names), - 'other': other basis type as given by the transformation matrix T. T : real/complex numpy array, optional Transformation matrix for basis change. Must be provided if basis='other'. Returns ------- L : Operator The component of the orbital momentum vector operator. """ l = (len(orb_names)-1)/2.0 L_melem_dict = {'z' : lambda m,mp: m if np.isclose(m,mp) else 0, '+' : lambda m,mp: np.sqrt(l*(l+1)-mp*(mp+1)) if np.isclose(m,mp+1) else 0, '-' : lambda m,mp: np.sqrt(l*(l+1)-mp*(mp-1)) if np.isclose(m,mp-1) else 0, 'x' : lambda m,mp: 0.5*(L_melem_dict['+'](m,mp) + L_melem_dict['-'](m,mp)), 'y' : lambda m,mp: -0.5j*(L_melem_dict['+'](m,mp) - L_melem_dict['-'](m,mp))} L_melem = L_melem_dict[component] orb_range = range(int(2*l+1)) L_matrix = np.array([[L_melem(o1-l,o2-l) for o2 in orb_range] for o1 in orb_range]) # Transform from spherical basis if needed if basis == "cubic": if not np.isclose(np.mod(l,1),0): raise ValueError("L_op: cubic basis is only defined for the integer orbital momenta.") T = spherical_to_cubic(int(l)) if basis == "other" and T is None: raise ValueError("L_op: provide T for other bases.") if T is not None: L_matrix = np.einsum("ij,jk,kl",np.conj(T),L_matrix,np.transpose(T)) mkind = get_mkind(off_diag,map_operator_structure) L = Operator() for sn in spin_names: for o1, o2 in product(orb_range,orb_range): L += c_dag(*mkind(sn,orb_names[o1])) * L_matrix[o1,o2] * c(*mkind(sn,orb_names[o2])) return L
from pytriqs.archive import * from pytriqs.applications.impurity_solvers.cthyb import AtomicProblem f = HDFArchive('dca_beta20_np975_histogram.out.h5','r') h_diag = f['h_diag-0'] fc = HDFArchive('check.h5','w') fc['h_diag-0'] = h_diag A = PostProcess(f['density_matrix-0'],f['h_loc-0']) CHEC = HDFArchive('densmat.h5','w') CHEC['density_matrix'] = f['density_matrix-0'] c_dag_0_up = ( c_dag("00-up",0) + c_dag("10-up",0) + c_dag("01-up",0) + c_dag("11-up",0))/2 c_dag_1_up = ( c_dag("00-up",0) - c_dag("10-up",0) + c_dag("01-up",0) - c_dag("11-up",0))/2 c_dag_2_up = ( c_dag("00-up",0) - c_dag("10-up",0) - c_dag("01-up",0) + c_dag("11-up",0))/2 c_dag_3_up = ( c_dag("00-up",0) + c_dag("10-up",0) - c_dag("01-up",0) - c_dag("11-up",0))/2 c_dag_0_down = ( c_dag("00-down",0) + c_dag("10-down",0) + c_dag("01-down",0) + c_dag("11-down",0))/2 c_dag_1_down = ( c_dag("00-down",0) - c_dag("10-down",0) + c_dag("01-down",0) - c_dag("11-down",0))/2 c_dag_2_down = ( c_dag("00-down",0) - c_dag("10-down",0) - c_dag("01-down",0) + c_dag("11-down",0))/2 c_dag_3_down = ( c_dag("00-down",0) + c_dag("10-down",0) - c_dag("01-down",0) - c_dag("11-down",0))/2 ops_0hole = [ (c_dag_0_up*c_dag_3_down-c_dag_0_down*c_dag_3_up)*(c_dag_1_up*c_dag_2_down-c_dag_1_down*c_dag_2_up)/2, (c_dag_0_up*c_dag_1_down-c_dag_0_down*c_dag_1_up)*(c_dag_2_up*c_dag_3_down-c_dag_2_down*c_dag_3_up)/2 ] ops_1hole = [
from pytriqs.operators.operators import Operator, c, c_dag, n, dagger from pytriqs.archive import * from pytriqs.applications.impurity_solvers.cthyb import AtomicProblem f = HDFArchive('dca_beta20_np975_histogram.out.h5', 'r') h_diag = f['h_diag-0'] fc = HDFArchive('check.h5', 'w') fc['h_diag-0'] = h_diag A = PostProcess(f['density_matrix-0'], f['h_loc-0']) CHEC = HDFArchive('densmat.h5', 'w') CHEC['density_matrix'] = f['density_matrix-0'] c_dag_0_up = (c_dag("00-up", 0) + c_dag("10-up", 0) + c_dag("01-up", 0) + c_dag("11-up", 0)) / 2 c_dag_1_up = (c_dag("00-up", 0) - c_dag("10-up", 0) + c_dag("01-up", 0) - c_dag("11-up", 0)) / 2 c_dag_2_up = (c_dag("00-up", 0) - c_dag("10-up", 0) - c_dag("01-up", 0) + c_dag("11-up", 0)) / 2 c_dag_3_up = (c_dag("00-up", 0) + c_dag("10-up", 0) - c_dag("01-up", 0) - c_dag("11-up", 0)) / 2 c_dag_0_down = (c_dag("00-down", 0) + c_dag("10-down", 0) + c_dag("01-down", 0) + c_dag("11-down", 0)) / 2 c_dag_1_down = (c_dag("00-down", 0) - c_dag("10-down", 0) + c_dag("01-down", 0) - c_dag("11-down", 0)) / 2 c_dag_2_down = (c_dag("00-down", 0) - c_dag("10-down", 0) - c_dag("01-down", 0) + c_dag("11-down", 0)) / 2 c_dag_3_down = (c_dag("00-down", 0) + c_dag("10-down", 0) -