def create_gf(self, ish=0, gf_function=GfImFreq, **kwargs): """ Create a zero BlockGf having the gf_struct_solver structure. When using GfImFreq as gf_function, typically you have to supply beta as keyword argument. Parameters ---------- ish : int shell index gf_function : constructor function used to construct the Gf objects constituting the individual blocks; default: GfImFreq **kwargs : options passed on to the Gf constructor for the individual blocks """ names = self.gf_struct_solver[ish].keys() blocks = [] for n in names: G = gf_function(indices=self.gf_struct_solver[ish][n], **kwargs) blocks.append(G) G = BlockGf(name_list=names, block_list=blocks) return G
def Transform_SymmetryBasis_to_RealSpace(self, IN, OUT=None): """ IN : in symmetry cluster indices. Returns OUT to real space""" OUT = OUT if OUT else BlockGf(G) for sig, B in OUT: for i in range(4): for j in range(4): B[(i + 1, 1), (j + 1, 1)] = sum_list([ self.P[i, k] * self.Pinv[k, j] * IN[ind + sig] for k, ind in enumerate(['00-', '10-', '01-', '11-']) ]) return OUT
def symm_to_real(self, gf_in, gf_out=None): """ gf_in : in symmetry cluster indices. Returns gf_out to real space""" gf_out = gf_out if gf_out else BlockGf(G) for sig, B in gf_out: for i in range(4): for j in range(4): B[i, j] = sum_list([ self.P[i, k] * self.Pinv[k, j] * gf_in[ind + sig] for k, ind in enumerate(['+1-', '-1-', '+i-', '-i-']) ]) return gf_out
def real_to_symm(self, gf_in, gf_out=None): """ gf_in[i,j] in real space --> gf_out into the symmetry basis""" gf_out = gf_out if gf_out else BlockGf(G) for sig, B in gf_in: for k, ind in enumerate(['+1-', '-1-', '+i-', '-i-']): gf_out[ind + sig] = sum_list([ sum_list([ B[i, j] * self.P[j, k] * self.Pinv[k, i] for j in range(4) ]) for i in range(4) ]) return gf_out
def __init__(self, archive, beta, n_iw, sigma_c_iw, dmu, blocks, blockstates, mix, *args, **kwargs): sigma_iw = sigma_c_iw super(DMFTObjects, self).__init__(archive) self.g_iw = BlockGf(name_block_generator = [(s, GfImFreq(indices = blockstates, beta = beta, n_points = n_iw, name = '$G_{c'+s+'}$')) for s in blocks], name = '$G_c$') self.sigma_iw = BlockGf(name_block_generator = [(s, GfImFreq(indices = blockstates, beta = beta, n_points = n_iw)) for s in blocks], name = '$\Sigma_c$') self.g_0_iw = BlockGf(name_block_generator = [(s, GfImFreq(indices = blockstates, beta = beta, n_points = n_iw)) for s in blocks], name = '$\\mathcal{G}$') if sigma_iw: self.sigma_iw << sigma_iw elif self.next_loop() > 0: self.sigma_iw = self.load('sigma_c_iw') else: self.sigma_iw.zero() if dmu or type(dmu) == int: self.dmu = dmu elif self.next_loop() > 0: self.dmu = self.load('dmu') else: self.dmu = 0 if self.next_loop() > 0: self.mixing = MixUpdate(self.load('sigma_c_iw'), self.load('dmu'), mix) else: self.mixing = MixUpdate(self.sigma_iw, self.dmu, mix)
def Transform_RealSpace_to_SymmetryBasis(self, IN, OUT=None): """ IN[i,j] in real space --> OUT into the symmetry basis""" OUT = OUT if OUT else BlockGf(G) for sig, B in IN: for k, ind in enumerate(['00-', '10-', '01-', '11-']): OUT[ind + sig] = sum_list([ sum_list([ B[(i + 1, 1), (j + 1, 1)] * self.P[j, k] * self.Pinv[k, i] for j in range(4) ]) for i in range(4) ]) return OUT
############################################################################### # High temperature seeds # ---------------------- hot_beta = np.round(1 / np.arange(1 / 25, .2, 1.44e-3), 3) gfsiw = [] wnli = [] for beta in hot_beta: freq = 2 * int(beta * 3) wnh = gf.matsubara_freq(beta, freq, 1 - freq) wnli.append(wnh) print(beta) gfsiw.append(hilbert_trans(1j * wnh, w, differential_weight(w), Aw, 0)) plt.plot(wnh, gfsiw[-1].imag, 'o:') plt.plot(wnh, gfsiw[-1].real, 'o:') # triqs blocks gfarr = GfImFreq(indices=[0], beta=beta, n_points=int(beta * 3)) G_iw = BlockGf(name_list=['asym_dw', 'asym_up', 'sym_dw', 'sym_up'], block_list=(gfarr, gfarr, gfarr, gfarr), make_copies=True) dlat.gf_sym_2_triqs_blockgf(gfsiw[-1], G_iw, u_int, tp) with HDFArchive('DIMER_PM_met_B{}_tp0.3.h5'.format(beta), 'a') as dest: dest['/U{}/it000/G_iw'.format(u_int)] = G_iw # block_names = ['sym_up', 'sym_dw', 'asym_up', 'asym_dw'] # gref = np.squeeze([G_iw[name].data for name in block_names]) # plt.plot(wnh, gref.T.real) # plt.plot(wnh, gref.T.imag)
class DMFTObjects(ArchiveConnected): """ Initializes the objects that converge during the DMFT cycles """ def __init__(self, archive, beta, n_iw, sigma_c_iw, dmu, blocks, blockstates, mix, *args, **kwargs): sigma_iw = sigma_c_iw super(DMFTObjects, self).__init__(archive) self.g_iw = BlockGf(name_block_generator = [(s, GfImFreq(indices = blockstates, beta = beta, n_points = n_iw, name = '$G_{c'+s+'}$')) for s in blocks], name = '$G_c$') self.sigma_iw = BlockGf(name_block_generator = [(s, GfImFreq(indices = blockstates, beta = beta, n_points = n_iw)) for s in blocks], name = '$\Sigma_c$') self.g_0_iw = BlockGf(name_block_generator = [(s, GfImFreq(indices = blockstates, beta = beta, n_points = n_iw)) for s in blocks], name = '$\\mathcal{G}$') if sigma_iw: self.sigma_iw << sigma_iw elif self.next_loop() > 0: self.sigma_iw = self.load('sigma_c_iw') else: self.sigma_iw.zero() if dmu or type(dmu) == int: self.dmu = dmu elif self.next_loop() > 0: self.dmu = self.load('dmu') else: self.dmu = 0 if self.next_loop() > 0: self.mixing = MixUpdate(self.load('sigma_c_iw'), self.load('dmu'), mix) else: self.mixing = MixUpdate(self.sigma_iw, self.dmu, mix) def paramagnetic(self): """makes g, sigma and g0 paramagnetic by averaging""" for g in [self.g_iw, self.sigma_iw, self. g_0_iw]: g << impose_paramagnetism(g) def afm(self): """makes g, sigma and g0 paramagnetic by averaging""" for g in [self.g_iw, self.sigma_iw, self. g_0_iw]: g << impose_afm(g) def site_symmetric(self, site_symmetries): """makes g, sigma and g0 site symmetric by averaging according to site_symmetries""" for g in [self.g_iw, self.sigma_iw, self. g_0_iw]: g << impose_site_symmetries(g, site_symmetries) def mix(self): self.sigma_iw, self.dmu = self.mixing(self.sigma_iw, self.dmu) def find_dmu(self, scheme_obj, cluster_density, dmu_lim, dmu_step_lim, nambu, verbosity, *args, **kwargs): if cluster_density: dens = lambda dmu : scheme_obj.g_local(self.sigma_iw, dmu, pretransf = False).total_density() dmu_old = self.dmu self.dmu, density0 = dichotomy(function = dens, x_init = self.dmu, y_value = cluster_density, precision_on_y = 0.001, delta_x = 0.5, max_loops = 1000, x_name = 'dmu', y_name = 'cluster_density', verbosity = verbosity) if self.dmu == None: dmu = dmu_old if dmu_lim: if dmu > dmu_lim: self.dmu = dmu_lim elif dmu < -dmu_lim: self.dmu = -dmu_lim if dmu_step_lim: if self.dmu - dmu_old > dmu_step_lim: self.dmu = dmu_old + dmu_step_lim elif self.dmu - dmu_old < -dmu_step_lim: self.dmu = dmu_old - dmu_step_lim def make_g_0_iw_with_delta_tau_real(self, n_tau = 10000): delta_iw = delta(self.g_0_iw) delta_tau = self.get_delta_tau() for s, b in delta_tau: for n, tau in enumerate(b.mesh): b.data[n,:,:] = b.data[n,:,:].real # Tail consistency is maintained anyways #for i in range(len(b.tail.data)): # orbs = range(len(b.tail.data[i,:,:])) # for j, k in product(orbs, orbs): # b.tail.data[i,j,k] = b.tail.data[i,j,k].real delta_iw_new = self.g_0_iw.copy() for s, b in delta_iw_new: b.set_from_fourier(delta_tau[s]) g_0_inv = self.g_0_iw.copy() g_0_inv << inverse(self.g_0_iw) g_0_inv << g_0_inv + delta_iw - delta_iw_new self.g_0_iw << inverse(g_0_inv) def get_delta_tau(self, n_tau = 10000): delta_tau = BlockGf(name_list = [ind for ind in self.g_0_iw.indices], block_list = [GfImTime(beta = self.g_0_iw.beta, indices = [ind for ind in block.indices]) for blockname, block in self.g_0_iw], make_copies = False) for s in self.g_0_iw.indices: delta_tau[s].set_from_inverse_fourier(delta(self.g_0_iw[s])) return delta_tau def get_g_iw(self): return self.g_iw def set_g_iw(self, g): self.g_iw << g def get_sigma_iw(self): return self.sigma_iw def set_sigma_iw(self, g): self.sigma_iw << g def get_g_0_iw(self): return self.g_0_iw def set_g_0_iw(self, g): self.g_0_iw << g def get_dmu(self): return self.dmu def set_dmu(self, mu): self.dmu = mu def get_mixing(self): return self.mixing def get_dmft_objs(self): return self.g_0_iw, self.g_iw, self.sigma_iw, self.dmu def set_dmft_objs(self, g0, g, sigma, dmu = False): """sets G0, G and Sigma""" self.g_0_iw << g0 self.g_iw << g self.sigma_iw << sigma if dmu: self.dmu = dmu
(-1, 0) : [[ t]], # where n=Number_Orbitals (0, 1) : [[ t]], (0, -1) : [[ t]], (1, 1) : [[ tp]], (-1, -1): [[ tp]], (1, -1) : [[ tp]], (-1, 1) : [[ tp]]} L = TBLattice ( units = [(1, 0, 0) , (0, 1, 0) ], hopping = hop) SL = TBSuperLattice(tb_lattice =L, super_lattice_units = [ (2, 0), (0, 2) ]) # SumK function that will perform the sum over the BZ SK = SumkDiscreteFromLattice (lattice = SL, n_points = 8, method = "Riemann") # Defines G and Sigma with a block structure compatible with the SumK function G= BlockGf( name_block_generator = [ (s, GfImFreq(indices = SK.GFBlocIndices, mesh = S.G.mesh)) for s in ['up', 'down'] ], make_copies = False) Sigma = G.copy() # Init Sigma for n, B in S.Sigma : B <<= 2.0 S.symm_to_real(gf_in = S.Sigma, gf_out = Sigma) # Embedding # Computes sum over BZ and returns density dens = (SK(mu = Chemical_potential, Sigma = Sigma, field = None , result = G).total_density()/4) mpi.report("Total density = %.3f"%dens) S.real_to_symm(gf_in = G, gf_out = S.G) # Extraction S.G0 = inverse(S.Sigma + inverse(S.G)) # Finally get S.G0 # Solve the impurity problem
(1, 1): [[tp]], (-1, -1): [[tp]], (1, -1): [[tp]], (-1, 1): [[tp]] } L = TBLattice(units=[(1, 0, 0), (0, 1, 0)], hopping=hop) SL = TBSuperLattice(tb_lattice=L, super_lattice_units=[(2, 0), (0, 2)]) # SumK function that will perform the sum over the BZ SK = SumkDiscreteFromLattice(lattice=SL, n_points=8, method="Riemann") # Defines G and Sigma with a block structure compatible with the SumK function G = BlockGf(name_block_generator=[(s, GfImFreq(indices=SK.GFBlocIndices, mesh=S.G.mesh)) for s in ['up', 'down']], make_copies=False) Sigma = G.copy() # Init Sigma for n, B in S.Sigma: B <<= 2.0 S.symm_to_real(gf_in=S.Sigma, gf_out=Sigma) # Embedding # Computes sum over BZ and returns density dens = (SK(mu=Chemical_potential, Sigma=Sigma, field=None, result=G).total_density() / 4) mpi.report("Total density = %.3f" % dens)