def N_op(spin_names, orb_names, off_diag = None, map_operator_structure = None): r""" Create an operator of the total number of particles. .. math:: \hat N = \sum_{i\sigma} a_{i\sigma}^\dagger a_{i\sigma}. Parameters ---------- 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 ------- N : Operator The total number of particles. """ mkind = get_mkind(off_diag,map_operator_structure) N = Operator() for sn, on in product(spin_names,orb_names): N += n(*mkind(sn,on)) return N
def run_kanamori(max_orbitals,orbital_mixing): for num_orbitals in range(2,max_orbitals+1): orb_names = range(num_orbitals) gf_struct = set_operator_structure(spin_names,orb_names,True) mkind = get_mkind(True,None) U = 1.0*(np.ones((num_orbitals,num_orbitals))-np.eye(num_orbitals)) Up = 2.0*np.ones((num_orbitals,num_orbitals)) J = 0.2 V = 0.3 h_k = V*np.ones((num_orbitals,num_orbitals)) if orbital_mixing else V*np.eye(num_orbitals) h_int = h_int_kanamori(spin_names,orb_names,U,Up,J,True) # Quantum numbers QN = [sum([n(*mkind("up",o)) for o in orb_names],Operator()), # N_up sum([n(*mkind("dn",o)) for o in orb_names],Operator())] # N_down if not orbital_mixing: # PS quantum number QN.append(Operator()) for i, o in enumerate(orb_names): dn = n(*mkind("up",o)) - n(*mkind("dn",o)) QN[2] += (2**i)*dn*dn eig_qn,time_qn = partition(h_int,h_k,gf_struct,QN) eig_ap,time_ap = partition(h_int,h_k,gf_struct) model = "Kanamori, %i orbitals"%num_orbitals if orbital_mixing: model += " (orbital mixing)" print_line(model,2**(2*num_orbitals),(len(eig_qn),time_qn),(len(eig_ap),time_ap))
def run_slater(L, is_cubic): for l in L: orb_names = range(2 * l + 1) num_orbitals = len(orb_names) gf_struct = set_operator_structure(spin_names, orb_names, True) mkind = get_mkind(True, None) F = [3.0 * (0.3**k) for k in range(l + 1)] U_mat = U_matrix(l, F, basis='cubic' if is_cubic else 'spherical') h_int = h_int_slater(spin_names, orb_names, U_mat, True) h_k = np.zeros((num_orbitals, num_orbitals)) # Quantum numbers QN = [ sum([n(*mkind("up", o)) for o in orb_names], Operator()), # N_up sum([n(*mkind("dn", o)) for o in orb_names], Operator()) ] # N_down eig_qn, time_qn = partition(h_int, h_k, gf_struct, QN) eig_ap, time_ap = partition(h_int, h_k, gf_struct) model = "Slater, %i orbitals" % num_orbitals model += (" (cubic basis)" if is_cubic else " (spherical basis)") print_line(model, 2**(2 * num_orbitals), (len(eig_qn), time_qn), (len(eig_ap), time_ap))
def N_op(spin_names, orb_names, off_diag=None, map_operator_structure=None): r""" Create an operator of the total number of particles. .. math:: \hat N = \sum_{i\sigma} a_{i\sigma}^\dagger a_{i\sigma}. Parameters ---------- 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 ------- N : Operator The total number of particles. """ mkind = get_mkind(off_diag, map_operator_structure) N = Operator() for sn, on in product(spin_names, orb_names): N += n(*mkind(sn, on)) return N
def __init__(self, beta, gf_struct, n_iw, spin_orbit=False, verbose=True): self.beta = beta self.gf_struct = gf_struct self.n_iw = n_iw self.spin_orbit = spin_orbit self.verbose = verbose if self.verbose and mpi.is_master_node(): print "\n*** Hubbard I solver using Pomerol library" print "*** gf_struct =", gf_struct print "*** n_iw =", n_iw # get spin_name and orb_names from gf_struct self.__analyze_gf_struct(gf_struct) if self.verbose and mpi.is_master_node(): print "*** spin_names =", self.spin_names print "*** orb_names =", self.orb_names # check spin_names for sn in self.spin_names: if not spin_orbit: assert sn in ('down', 'dn', 'up' ) # become either 'down' or 'up' if spin_orbit: assert sn in ('down', 'dn', 'ud') # all become 'down' # Conversion from TRIQS to Pomerol notation for operator indices # TRIQS: ('dn', '-2') --> Pomerol: ('atom', 0, 'down') # NOTE: When spin_orbit is true, only spin 'down' is used. mkind = get_mkind(True, None) index_converter = { mkind(sn, bn): ("atom", bi, "down" if sn == "dn" or sn == "ud" else sn) for sn, (bi, bn) in product(self.spin_names, enumerate(self.orb_names)) } self.__ed = PomerolED(index_converter, verbose, spin_orbit) # init G_iw glist = lambda: [ GfImFreq(indices=self.orb_names, beta=beta, n_points=n_iw) for block, inner in gf_struct.items() ] self.G_iw = BlockGf(name_list=self.spin_names, block_list=glist(), make_copies=False) self.G_iw.zero() self.G0_iw = self.G_iw.copy() self.Sigma_iw = self.G_iw.copy()
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 run_kanamori(max_orbitals, orbital_mixing): for num_orbitals in range(2, max_orbitals + 1): orb_names = range(num_orbitals) gf_struct = set_operator_structure(spin_names, orb_names, True) mkind = get_mkind(True, None) U = 1.0 * (np.ones( (num_orbitals, num_orbitals)) - np.eye(num_orbitals)) Up = 2.0 * np.ones((num_orbitals, num_orbitals)) J = 0.2 V = 0.3 h_k = V * np.ones( (num_orbitals, num_orbitals)) if orbital_mixing else V * np.eye(num_orbitals) h_int = h_int_kanamori(spin_names, orb_names, U, Up, J, True) # Quantum numbers QN = [ sum([n(*mkind("up", o)) for o in orb_names], Operator()), # N_up sum([n(*mkind("dn", o)) for o in orb_names], Operator()) ] # N_down if not orbital_mixing: # PS quantum number QN.append(Operator()) for i, o in enumerate(orb_names): dn = n(*mkind("up", o)) - n(*mkind("dn", o)) QN[2] += (2**i) * dn * dn eig_qn, time_qn = partition(h_int, h_k, gf_struct, QN) eig_ap, time_ap = partition(h_int, h_k, gf_struct) model = "Kanamori, %i orbitals" % num_orbitals if orbital_mixing: model += " (orbital mixing)" print_line(model, 2**(2 * num_orbitals), (len(eig_qn), time_qn), (len(eig_ap), time_ap))
def run_slater(L,is_cubic): for l in L: orb_names = range(2*l+1) num_orbitals = len(orb_names) gf_struct = set_operator_structure(spin_names,orb_names,True) mkind = get_mkind(True,None) F = [3.0*(0.3**k) for k in range(l+1)] U_mat = U_matrix(l,F,basis='cubic' if is_cubic else 'spherical') h_int = h_int_slater(spin_names,orb_names,U_mat,True) h_k = np.zeros((num_orbitals,num_orbitals)) # Quantum numbers QN = [sum([n(*mkind("up",o)) for o in orb_names],Operator()), # N_up sum([n(*mkind("dn",o)) for o in orb_names],Operator())] # N_down eig_qn,time_qn = partition(h_int,h_k,gf_struct,QN) eig_ap,time_ap = partition(h_int,h_k,gf_struct) model = "Slater, %i orbitals"%num_orbitals model += (" (cubic basis)" if is_cubic else " (spherical basis)") print_line(model,2**(2*num_orbitals),(len(eig_qn),time_qn),(len(eig_ap),time_ap))
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
tau.append(float(cols[0])) data.append([-float(c) for c in cols[1:]]) g_ref = GfImTime(indices=range(len(data[0])), beta=tau[-1], n_points=len(tau)) for nt, d in enumerate(data): for nc, val in enumerate(d): g_ref.data[nt, nc, nc] = val # Read the results arch = HDFArchive("5_plus_5.h5", 'r') use_interaction = arch['use_interaction'] spin_names = arch['spin_names'] orb_names = arch['orb_names'] delta_params = arch['delta_params'] mkind = get_mkind(False, None) # Calculate theoretical curves if not use_interaction: g_theor = GfImTime(indices=range(len(orb_names)), beta=beta, n_points=n_tau) for nc, cn in enumerate(orb_names): V = delta_params[cn]['V'] e = delta_params[cn]['e'] e1 = e - V e2 = e + V g_theor_w = GfImFreq(indices=[0], beta=beta) g_theor_w << 0.5 * inverse(iOmega_n - e1) + 0.5 * inverse(iOmega_n -
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
p = {} p["max_time"] = -1 p["random_name"] = "" p["random_seed"] = 123 * mpi.rank + 567 p["length_cycle"] = 50 p["n_warmup_cycles"] = 50000/10 p["n_cycles"] = 3200000/10 p["use_norm_as_weight"] = True p["measure_density_matrix"] = False results_file_name = "kanamori_offdiag." + ("qn." if use_qn else "") + "h5" mpi.report("Welcome to Kanamori (off-diagonal) benchmark.") gf_struct = set_operator_structure(spin_names,orb_names,True) mkind = get_mkind(True,None) # Hamiltonian H = h_int_kanamori(spin_names,orb_names, np.array([[0,U-3*J],[U-3*J,0]]), np.array([[U,U-2*J],[U-2*J,U]]), J,True) if use_qn: QN = [sum([n(*mkind("up",o)) for o in orb_names],Operator()), sum([n(*mkind("dn",o)) for o in orb_names],Operator())] for o in orb_names: dn = n(*mkind("up",o)) - n(*mkind("dn",o)) QN.append(dn*dn) p["partition_method"] = "quantum_numbers" p["quantum_numbers"] = QN
tau.append(float(cols[0])) data.append([-float(c) for c in cols[1:]]) g_ref = GfImTime(indices = range(len(data[0])), beta=tau[-1], n_points=len(tau)) for nt, d in enumerate(data): for nc, val in enumerate(d): g_ref.data[nt,nc,nc] = val # Read the results arch = HDFArchive("5_plus_5.h5",'r') use_interaction = arch['use_interaction'] spin_names = arch['spin_names'] orb_names = arch['orb_names'] delta_params = arch['delta_params'] mkind = get_mkind(False,None) # Calculate theoretical curves if not use_interaction: g_theor = GfImTime(indices = range(len(orb_names)), beta=beta, n_points=n_tau) for nc, cn in enumerate(orb_names): V = delta_params[cn]['V'] e = delta_params[cn]['e'] e1 = e - V e2 = e + V g_theor_w = GfImFreq(indices = [0], beta=beta) g_theor_w << 0.5*inverse(iOmega_n - e1) + 0.5*inverse(iOmega_n - e2) g_theor[nc,nc] << InverseFourier(g_theor_w)
def five_plus_five(use_interaction=True): results_file_name = "5_plus_5." + ("int." if use_interaction else "") + "h5" # Block structure of GF L = 2 # d-orbital spin_names = ("up", "dn") orb_names = cubic_names(L) # Input parameters beta = 40. mu = 26 U = 4.0 J = 0.7 F0 = U F2 = J * (14.0 / (1.0 + 0.63)) F4 = F2 * 0.63 # Dump the local Hamiltonian to a text file (set to None to disable dumping) H_dump = "H.txt" # Dump Delta parameters to a text file (set to None to disable dumping) Delta_dump = "Delta_params.txt" # Hybridization function parameters # Delta(\tau) is diagonal in the basis of cubic harmonics # Each component of Delta(\tau) is represented as a list of single-particle # terms parametrized by pairs (V_k,\epsilon_k). delta_params = { "xy": { 'V': 0.2, 'e': -0.2 }, "yz": { 'V': 0.2, 'e': -0.15 }, "z^2": { 'V': 0.2, 'e': -0.1 }, "xz": { 'V': 0.2, 'e': 0.05 }, "x^2-y^2": { 'V': 0.2, 'e': 0.4 } } atomic_levels = { ('up_xy', 0): -0.2, ('dn_xy', 0): -0.2, ('up_yz', 0): -0.15, ('dn_yz', 0): -0.15, ('up_z^2', 0): -0.1, ('dn_z^2', 0): -0.1, ('up_xz', 0): 0.05, ('dn_xz', 0): 0.05, ('up_x^2-y^2', 0): 0.4, ('dn_x^2-y^2', 0): 0.4 } n_iw = 1025 n_tau = 10001 p = {} p["max_time"] = -1 p["random_name"] = "" p["random_seed"] = 123 * mpi.rank + 567 p["length_cycle"] = 50 #p["n_warmup_cycles"] = 5000 p["n_warmup_cycles"] = 500 p["n_cycles"] = int(1.e1 / mpi.size) #p["n_cycles"] = int(5.e5 / mpi.size) #p["n_cycles"] = int(5.e6 / mpi.size) p["partition_method"] = "autopartition" p["measure_G_tau"] = True p["move_shift"] = True p["move_double"] = True p["measure_pert_order"] = False p["performance_analysis"] = False p["use_trace_estimator"] = False mpi.report("Welcome to 5+5 (5 orbitals + 5 bath sites) test.") gf_struct = set_operator_structure(spin_names, orb_names, False) mkind = get_mkind(False, None) H = Operator() if use_interaction: # Local Hamiltonian U_mat = U_matrix(L, [F0, F2, F4], basis='cubic') H += h_int_slater(spin_names, orb_names, U_mat, False, H_dump=H_dump) else: mu = 0. p["h_int"] = H # Quantum numbers (N_up and N_down) QN = [Operator(), Operator()] for cn in orb_names: for i, sn in enumerate(spin_names): QN[i] += n(*mkind(sn, cn)) if p["partition_method"] == "quantum_numbers": p["quantum_numbers"] = QN mpi.report("Constructing the solver...") # Construct the solver S = SolverCore(beta=beta, gf_struct=gf_struct, n_tau=n_tau, n_iw=n_iw) mpi.report("Preparing the hybridization function...") H_hyb = Operator() # Set hybridization function if Delta_dump: Delta_dump_file = open(Delta_dump, 'w') for sn, cn in product(spin_names, orb_names): bn, i = mkind(sn, cn) V = delta_params[cn]['V'] e = delta_params[cn]['e'] delta_w = Gf(mesh=MeshImFreq(beta, 'Fermion', n_iw), target_shape=[]) delta_w << (V**2) * inverse(iOmega_n - e) S.G0_iw[bn][i, i] << inverse(iOmega_n + mu - atomic_levels[(bn, i)] - delta_w) cnb = cn + '_b' # bath level a = sn + '_' + cn b = sn + '_' + cn + '_b' H_hyb += ( atomic_levels[(bn,i)] - mu ) * n(a, 0) + \ n(b,0) * e + V * ( c(a,0) * c_dag(b,0) + c(b,0) * c_dag(a,0) ) # Dump Delta parameters if Delta_dump: Delta_dump_file.write(bn + '\t') Delta_dump_file.write(str(V) + '\t') Delta_dump_file.write(str(e) + '\n') if mpi.is_master_node(): filename_ham = 'data_Ham%s.h5' % ('_int' if use_interaction else '') with HDFArchive(filename_ham, 'w') as arch: arch['H'] = H_hyb + H arch['gf_struct'] = gf_struct arch['beta'] = beta mpi.report("Running the simulation...") # Solve the problem S.solve(**p) # Save the results if mpi.is_master_node(): Results = HDFArchive(results_file_name, 'w') Results['G_tau'] = S.G_tau Results['G0_iw'] = S.G0_iw Results['use_interaction'] = use_interaction Results['delta_params'] = delta_params Results['spin_names'] = spin_names Results['orb_names'] = orb_names import __main__ Results.create_group("log") log = Results["log"] log["version"] = version.version log["triqs_hash"] = version.triqs_hash log["cthyb_hash"] = version.cthyb_hash log["script"] = inspect.getsource(__main__)
g2_n_wb = 5 # Number of fermionic Matsubara frequencies for G^2 calculations g2_n_wf = 10 ##################### # Input for Pomerol # ##################### spin_names = ("up", "dn") orb_names = range(-L, L + 1) # GF structure off_diag = True gf_struct = set_operator_structure(spin_names, orb_names, off_diag=off_diag) mkind = get_mkind(off_diag, None) # Conversion from TRIQS to Pomerol notation for operator indices index_converter = { mkind(sn, bn): ("atom", bi, "down" if sn == "dn" else "up") for sn, (bi, bn) in product(spin_names, enumerate(orb_names)) } if mpi.is_master_node(): print "Block structure of single-particle Green's functions:", gf_struct print "index_converter:", index_converter # Operators N = N_op(spin_names, orb_names, off_diag=off_diag) Sz = S_op('z', spin_names, orb_names, off_diag=off_diag) Lz = L_op('z', spin_names, orb_names, off_diag=off_diag, basis='spherical') Jz = Sz + Lz