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
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
 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)
Пример #6
0
 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
Пример #7
0
###############################################################################
# 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)
Пример #8
0
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
Пример #9
0
        (-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
Пример #10
0
    (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)