Exemple #1
0
  def lattice(data, funcG, funcW, n): #the only option - we need Gkw and Wqnu for self energy in the next iteration
    #data.get_Gkw(funcG) #gets Gkw from G0 and Sigma
    def func(var, data):
      mu = var[0]
      dt = data[0]
      #print "func call! mu: ", mu, " n: ",dt.ns['up']
      n= data[1] 
      dt.mus['up'] = mu
      dt.mus['down'] = dt.mus['up']
      dt.get_Gkw_direct(funcG) #gets Gkw from w, mu, epsilon and Sigma and X
      dt.get_G_loc() #gets G_loc from Gkw
      dt.get_n_from_G_loc()     
      #print "funcvalue: ",-abs(n - dt.ns['up'])  
      return 1.0-abs(n - dt.ns['up'])  
    if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
    varbest, funcvalue, iterations = amoeba(var=[data.mus['up']],
                                              scale=[0.01],
                                              func=func, 
                                              data = [data, n],
                                              itmax=30,
                                              ftolerance=1e-2,
                                              xtolerance=1e-2)
    if mpi.is_master_node():
      print "mu best: ", varbest
      print "-abs(diff n - data.n): ", funcvalue
      print "iterations used: ", iterations

    data.get_Gtildekw() #gets Gkw-G_loc

    data.get_Wqnu_from_func(funcW) #gets Wqnu from P and J 
    data.get_W_loc() #gets W_loc from Wqnu
    data.get_Wtildeqnu() #gets Wqnu-W_loc, 
Exemple #2
0
        def HT(res):
            # First compute the eps_hat array
            eps_hat = epsilon_hat(self.dos.eps) if epsilon_hat else numpy.array( [ x* numpy.identity (N1) for x in self.dos.eps] )
            assert eps_hat.shape[0] == self.dos.eps.shape[0], "epsilon_hat function behaves incorrectly"
            assert eps_hat.shape[1] == eps_hat.shape[2], "epsilon_hat function behaves incorrectly (result not a square matrix)"
            assert N1 == eps_hat.shape[1], "Size of Sigma and of epsilon_hat mismatch"

            res.zero()

            # Perform the sum over eps[i]
            tmp, tmp2 = res.copy(), res.copy()
            tmp << iOmega_n + mu + eta * 1j
            if not(Sigma_fnt):
                tmp -= Sigma
            if field != None: tmp -= field

            # I slice all the arrays on the node. Cf reduce operation below.
            for d, e_h, e in  itertools.izip (*[mpi.slice_array(A) for A in [self.rho_for_sum, eps_hat, self.dos.eps]]):
                tmp2.copy_from(tmp)
                tmp2 -= e_h
                if Sigma_fnt: tmp2 -= Sigma(e)
                tmp2.invert()
                tmp2 *= d
                res += tmp2
            # sum the res GF of all nodes and returns the results on all nodes...
            # Cf Boost.mpi.python, collective communicator for documentation.
            # The point is that res is pickable, hence can be transmitted between nodes without further code...
            res << mpi.all_reduce(mpi.world, res, lambda x, y: x+y)
            mpi.barrier()
Exemple #3
0
 def __init__(self, archive, *args, **kwargs):
     self.archive = archive
     if not os.path.exists(archive) and mpi.is_master_node():
         archive = HDFArchive(archive, 'w')
         archive.create_group('results')
         archive['results']['n_dmft_loops'] = 0
         del archive
     mpi.barrier()
Exemple #4
0
def calc_bandcorr_man(general_parameters, SK, E_kin_dft):
    """
    Calculates the correlated kinetic energy from DMFT for target states
    and then determines the band correction energy

    Parameters
    ----------
    general_parameters : dict
        general parameters as a dict

    SK : SumK Object instances

    E_kin_dft: float
        kinetic energy from DFT


    __Returns:__
    E_bandcorr: float
        band energy correction E_kin_dmft - E_kin_dft

    """
    E_kin_dmft = 0.0 + 0.0j
    E_kin = 0.0 + 0.0j
    H_ks = SK.hopping
    num_kpts = SK.n_k

    # kinetic energy from dmft lattice Greens functions
    ikarray = np.array(range(SK.n_k))
    for ik in mpi.slice_array(ikarray):
        nb = int(SK.n_orbitals[ik])
        # calculate lattice greens function
        G_iw_lat = SK.lattice_gf(ik,
                                 beta=general_parameters['beta'],
                                 with_Sigma=True,
                                 with_dc=True).copy()
        # calculate G(beta) via the function density, which is the same as fourier trafo G(w) and taking G(b)
        G_iw_lat_beta = G_iw_lat.density()
        # Doing the formula
        E_kin += np.trace(
            np.dot(
                H_ks[ik, 0, :nb, :nb], G_iw_lat_beta['up'][:, :])) + np.trace(
                    np.dot(H_ks[ik, 0, :nb, :nb], G_iw_lat_beta['down'][:, :]))
    E_kin = float(E_kin.real)

    # collect data and put into E_kin_dmft
    E_kin_dmft = mpi.all_reduce(mpi.world, E_kin, lambda x, y: x + y)
    mpi.barrier()
    # E_kin should be divided by the number of k-points
    E_kin_dmft = E_kin_dmft / num_kpts

    if mpi.is_master_node():
        print 'Kinetic energy contribution dmft part: ' + str(E_kin_dmft)

    E_bandcorr = E_kin_dmft - E_kin_dft

    return E_bandcorr
Exemple #5
0
 def extract_Gloc(mu):
     ret = Gloc.copy()
     ret.zero()
     Gk = ret.copy()
     mu_mat = np.zeros((8, 8))
     for i in range(4):
         mu_mat[i, i] = mu
         mu_mat[i + 4, i + 4] = -mu
     nk = Hk_nambu.shape[0]
     ikarray = np.array(range(nk))
     for ik in mpi.slice_array(ikarray):
         Gk['nambu'] << inverse(iOmega_n - Hk_nambu[ik] + mu_mat -
                                Sigma_orig['nambu'])
         ret['nambu'] += Gk['nambu']
     mpi.barrier()
     ret['nambu'] << mpi.all_reduce(mpi.world, ret['nambu'],
                                    lambda x, y: x + y) / nk
     return ret
Exemple #6
0
    def density_gf(self,beta):
        """Calculates the density without setting up Gloc. It is useful for Hubbard I, and very fast.""" 

        dens_mat = [ {} for icrsh in xrange(self.n_corr_shells)]
        for icrsh in xrange(self.n_corr_shells):
            for bl in self.block_names[self.corr_shells[icrsh][4]]:
                dens_mat[icrsh][bl] = numpy.zeros([self.corr_shells[icrsh][3],self.corr_shells[icrsh][3]], numpy.complex_)

        ikarray=numpy.array(range(self.n_k))

        for ik in mpi.slice_array(ikarray):
            
            Gupf = self.lattice_gf_matsubara(ik=ik, beta=beta, mu=self.chemical_potential)
            Gupf *= self.bz_weights[ik]
            dm = Gupf.density()
            MMat = [dm[bl] for bl in self.block_names[self.SO]]
            
            for icrsh in range(self.n_corr_shells):
                for ibn,bn in enumerate(self.block_names[self.corr_shells[icrsh][4]]):
                    isp = self.names_to_ind[self.corr_shells[icrsh][4]][bn]
                    dim = self.corr_shells[icrsh][3]
                    n_orb = self.n_orbitals[ik,isp]
                    #print ik, bn, isp
                    dens_mat[icrsh][bn] += numpy.dot( numpy.dot(self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb],MMat[ibn]),
                                                      self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb].transpose().conjugate() )

        # get data from nodes:
        for icrsh in range(self.n_corr_shells):
            for sig in dens_mat[icrsh]:
                dens_mat[icrsh][sig] = mpi.all_reduce(mpi.world,dens_mat[icrsh][sig],lambda x,y : x+y)
        mpi.barrier()


        if (self.symm_op!=0): dens_mat = self.Symm_corr.symmetrize(dens_mat)

        # Rotate to local coordinate system:
        if (self.use_rotations):
            for icrsh in xrange(self.n_corr_shells):
                for bn in dens_mat[icrsh]:
                    if (self.rot_mat_time_inv[icrsh]==1): dens_mat[icrsh][bn] = dens_mat[icrsh][bn].conjugate()
                    dens_mat[icrsh][bn] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),dens_mat[icrsh][bn]) , 
                                                    self.rot_mat[icrsh] )

        return dens_mat
        def HT(res):
            # First compute the eps_hat array
            eps_hat = epsilon_hat(
                self.dos.eps) if epsilon_hat else numpy.array(
                    [x * numpy.identity(Sigma.N1) for x in self.dos.eps])
            assert eps_hat.shape[0] == self.dos.eps.shape[
                0], "epsilon_hat function behaves incorrectly"
            assert eps_hat.shape[1] == eps_hat.shape[
                2], "epsilon_hat function behaves incorrectly (result not a square matrix)"
            assert Sigma.N1 == eps_hat.shape[
                1], "Size of Sigma and of epsilon_hat mismatch"

            res.zero()
            Sigma_fnt = callable(Sigma)
            if Sigma_fnt:
                assert len(
                    inspect.getargspec(Sigma)[0]
                ) == 1, "Sigma function is not of the correct type. See Documentation"

            # Perform the sum over eps[i]
            tmp, tmp2 = res.copy(), res.copy()
            tmp <<= iOmega_n + mu + eta * 1j
            if not (Sigma_fnt):
                tmp -= Sigma
            if field != None: tmp -= field

            # I slice all the arrays on the node. Cf reduce operation below.
            for d, e_h, e in itertools.izip(*[
                    mpi.slice_array(A)
                    for A in [self.rho_for_sum, eps_hat, self.dos.eps]
            ]):
                tmp2.copy_from(tmp)
                tmp2 -= e_h
                if Sigma_fnt: tmp2 -= Sigma(e)
                tmp2.invert()
                tmp2 *= d
                res += tmp2
            # sum the res GF of all nodes and returns the results on all nodes...
            # Cf Boost.mpi.python, collective communicator for documentation.
            # The point is that res is pickable, hence can be transmitted between nodes without further code...
            res <<= mpi.all_reduce(mpi.world, res, lambda x, y: x + y)
            mpi.barrier()
Exemple #8
0
 def total_density(self, mu):
     """
     Calculates the total charge for the energy window for a given mu. Since in general n_orbitals depends on k, 
     the calculation is done in the following order:
     G_aa'(k,iw) -> n(k) = Tr G_aa'(k,iw) -> sum_k n_k 
     
     mu: chemical potential
     
     The calculation is done in the global coordinate system, if distinction is made between local/global!
     """
     
     dens = 0.0
     ikarray=numpy.array(range(self.n_k))
     
     for ik in mpi.slice_array(ikarray):
     
         S = self.lattice_gf_matsubara(ik=ik,mu=mu) 
         dens += self.bz_weights[ik] * S.total_density()
             
     # collect data from mpi:
     dens = mpi.all_reduce(mpi.world,dens,lambda x,y : x+y)
     mpi.barrier()
             
     return dens
Exemple #9
0
def get_chi0_wnk(g_wk, nw=1, nwf=None):
    r""" Compute the generalized lattice bubble susceptibility 
    :math:`\chi^{(0)}_{abcd}(\omega, \nu, \mathbf{k})` from the single-particle
    Green's function :math:`G_{ab}(\omega, \mathbf{k})`.

    Parameters
    ----------

    g_wk : Single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`.
    nw : Number of bosonic freqiencies in :math:`\chi`.
    nwf : Number of fermionic freqiencies in :math:`\chi`.    

    Returns
    -------

    chi0_wnk : Generalized lattice bubble susceptibility
               :math:`\chi^{(0)}_{abcd}(\omega, \nu, \mathbf{k})`
    """

    fmesh = g_wk.mesh.components[0]
    kmesh = g_wk.mesh.components[1]

    if nwf is None:
        nwf = len(fmesh) / 2

    mpi.barrier()
    mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 0, 0)][0, 0]))
    n = np.sum(g_wk.data) / len(kmesh)
    mpi.report('n ' + str(n))
    mpi.barrier()

    mpi.report('--> g_wr from g_wk')
    g_wr = fourier_wk_to_wr(g_wk)

    mpi.barrier()
    mpi.report('g_wr ' + str(g_wr[Idx(2), Idx(0, 0, 0)][0, 0]))
    n_r = np.sum(g_wr.data, axis=0)[0]
    mpi.report('n_r=0 ' + str(n_r[0, 0]))
    mpi.barrier()

    mpi.report('--> chi0_wnr from g_wr')
    chi0_wnr = chi0r_from_gr_PH(nw=nw, nn=nwf, g_nr=g_wr)

    #mpi.report('--> chi0_wnr from g_wr (nompi)')
    #chi0_wnr_nompi = chi0r_from_gr_PH_nompi(nw=nw, nn=nwf, g_wr=g_wr)

    del g_wr

    #abs_diff = np.abs(chi0_wnr.data - chi0_wnr_nompi.data)
    #mpi.report('shape = ' + str(abs_diff.shape))
    #idx = np.argmax(abs_diff)
    #mpi.report('argmax = ' + str(idx))
    #diff = np.max(abs_diff)
    #mpi.report('diff = %6.6f' % diff)
    #del chi0_wnr
    #chi0_wnr = chi0_wnr_nompi

    #exit()

    mpi.barrier()
    mpi.report('chi0_wnr ' +
               str(chi0_wnr[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    chi0_r0 = np.sum(chi0_wnr[:, :, Idx(0, 0, 0)].data)
    mpi.report('chi0_r0 ' + str(chi0_r0))
    mpi.barrier()

    mpi.report('--> chi0_wnk from chi0_wnr')
    chi0_wnk = chi0q_from_chi0r(chi0_wnr)

    del chi0_wnr

    mpi.barrier()
    mpi.report('chi0_wnk ' +
               str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    chi0 = np.sum(chi0_wnk.data) / len(kmesh)
    mpi.report('chi0 = ' + str(chi0))
    mpi.barrier()

    #if mpi.is_master_node():
    if False:
        from triqs_tprf.ParameterCollection import ParameterCollection
        p = ParameterCollection()
        p.g_wk = g_wk
        p.g_wr = g_wr
        p.chi0_wnr = chi0_wnr
        p.chi0_wnk = chi0_wnk

        print '--> Writing debug info for BSE'
        with HDFArchive('data_debug_bse.h5', 'w') as arch:
            arch['p'] = p

    mpi.barrier()

    return chi0_wnk
Exemple #10
0
  def lattice(data, frozen_boson, n, ph_symmetry, accepted_mu_range=[-2.0,2.0]):
    def get_n(dt):
      dt.get_Gkw_direct() #gets Gkw from w, mu, epsilon and Sigma and X
      dt.get_Fkw_direct() #gets Fkw from w, mu, epsilon and Sigma and X
      dt.get_G_loc() #gets G_loc from Gkw
      dt.get_n_from_G_loc()     

    if mpi.is_master_node(): print "supercond_hubbard: lattice"

    if (n is None) or ((n==0.5) and ph_symmetry):
      if n==0.5: #otherwise - nothing to be done
        data.mus['up'] = 0
        if 'down' in data.fermionic_struct.keys(): data.mus['down'] = data.mus['up']  
        get_n(data)
    else:
      def func(var, data):
        mu = var[0]
        dt = data[0]
        #print "func call! mu: ", mu, " n: ",dt.ns['up']
        n= data[1] 
        dt.mus['up'] = mu
        if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus['up']
        get_n(dt)        #print "funcvalue: ",-abs(n - dt.ns['up'])  

        val = 1.0-abs(n - dt.ns['up'])  
        if mpi.is_master_node(): print "amoeba func call: val = ",val
        if val != val: return -1e+6
        else: return val
      if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()

      if mpi.is_master_node(): print "about to do mu search:"

      guesses = [data.mus['up'], 0.0, -0.1, -0.3, -0.4, -0.5, -0.7, 0.3, 0.5, 0.7]
      found = False  
      for l in range(len(guesses)):
        varbest, funcvalue, iterations = amoeba(var=[guesses[l]],
                                              scale=[0.01],
                                              func=func, 
                                              data = [data, n],
                                              itmax=30,
                                              ftolerance=1e-2,
                                              xtolerance=1e-2,
                                              known_max = 1.0,
                                              known_max_accr = 5e-5)
        if (varbest[0]>accepted_mu_range[0] and varbest[0]<accepted_mu_range[1]) and (abs(funcvalue-1.0)<1e-2): #change the bounds for large doping
          found = True 
          func(varbest, [data, n])
          break 
        if l+1 == len(guesses):
          if mpi.is_master_node(): print "mu search FAILED: doing a scan..."

          mu_grid = numpy.linspace(-1.0,0.3,50)
          func_values = [func(var=[mu], data=[data,n]) for mu in mu_grid]
          if mpi.is_master_node(): 
            print "func_values: "
            for i in range(len(mu_grid)):
              print "mu: ",mu_grid[i], " 1-abs(n-n): ", func_values[i]
          mui_max = numpy.argmax(func_values)
          if mpi.is_master_node(): print "using mu: ", mu_grid[mui_max]
          data.mus['up'] = mu_grid[mui_max]
          if 'down' in data.fermionic_struct.keys(): data.mus['down'] = data.mus['up']
          get_n(data)

             
      if mpi.is_master_node() and found:
        print "guesses tried: ", l  
        print "mu best: ", varbest
        print "1-abs(diff n - data.n): ", funcvalue
        print "iterations used: ", iterations

    data.get_Gtildekw() #gets Gkw-G_loc

    if not frozen_boson: 
      data.get_Wqnu_from_func(func =  dict.fromkeys(data.bosonic_struct.keys(), dyson.scalar.W_from_P_and_J)) #gets Wqnu from P and J 
      data.get_W_loc() #gets W_loc from Wqnu, used in local bubbles
      data.get_Wtildeqnu()
Exemple #11
0
def get_G_w_from_A_w(A_w,
                     w_points,
                     np_interp_A=None,
                     np_omega=2000,
                     w_min=-10,
                     w_max=10,
                     broadening_factor=1.0):
    r""" Use Kramers-Kronig to determine the retarded Green function :math:`G(\omega)`

    This calculates :math:`G(\omega)` from the spectral function :math:`A(\omega)`.
    A numerical broadening of :math:`bf * i\Delta\omega`
    is used, with the adjustable broadening factor bf (default is 1).
    This function normalizes :math:`A(\omega)`.
    Use mpi to save time.

    Parameters
    ----------
    A_w : array
        Real-frequency spectral function.
    w_points : array
        Real-frequency grid points.
    np_interp_A : int
        Number of grid points A_w should be interpolated on before
        G_w is calculated. The interpolation is performed on a linear
        grid with np_interp_A points from min(w_points) to max(w_points).
    np_omega : int
        Number of equidistant grid points of the output Green function.
    w_min : float
        Start point of output Green function.
    w_max : float
        End point of output Green function.
    broadening_factor : float
        Factor multiplying the broadening :math:`i\Delta\omega`

    Returns
    -------
    G_w : GfReFreq
        TRIQS retarded Green function.
    """

    shape_A = np.shape(A_w)

    if len(shape_A) == 1:
        indices = [0]
        matrix_valued = False
    elif (len(shape_A) == 3) and (shape_A[0] == shape_A[1]):
        indices = range(0, shape_A[0])
        matrix_valued = True
    else:
        raise Exception('A_w has wrong shape, must be n x n x n_w')

    if w_min > w_max:
        raise Exception('w_min must be smaller than w_max')

    if np_interp_A:
        w_points_interp = np.linspace(np.min(w_points),
                                      np.max(w_points), np_interp_A)
        if matrix_valued:
            for i in range(shape_A[0]):
                for j in range(shape_A[1]):
                    A_w[i, j, :] = np.interp(w_points_interp,
                                             w_points, A_w[i, j, :])
        else:
            A_w = np.interp(w_points_interp, w_points, A_w)
        w_points = w_points_interp

    G_w = GfReFreq(indices=indices, window=(w_min, w_max), n_points=np_omega)
    G_w.zero()

    iw_points = np.array(range(len(w_points)))

    for iw in mpi.slice_array(iw_points):
        domega = (w_points[min(len(w_points) - 1, iw + 1)] -
                  w_points[max(0, iw - 1)]) * 0.5
        if matrix_valued:
            for i in range(shape_A[0]):
                for j in range(shape_A[1]):
                    G_w[i, j] << G_w[i, j] + A_w[i, j, iw] * \
                        inverse(Omega - w_points[iw] + 1j * domega * broadening_factor) * domega
        else:
            G_w << G_w + A_w[iw] * \
                inverse(Omega - w_points[iw] + 1j * domega * broadening_factor) * domega

    G_w << mpi.all_reduce(mpi.world, G_w, lambda x, y: x + y)
    mpi.barrier()

    return G_w
Exemple #12
0
def solve_lattice_bse(g_wk, gamma_wnn, tail_corr_nwf=None):

    fmesh_g = g_wk.mesh.components[0]
    kmesh = g_wk.mesh.components[1]

    bmesh = gamma_wnn.mesh.components[0]
    fmesh = gamma_wnn.mesh.components[1]

    nk = len(kmesh)
    nw = (len(bmesh) + 1) / 2
    nwf = len(fmesh) / 2
    nwf_g = len(fmesh_g) / 2

    if mpi.is_master_node():
        print tprf_banner(), "\n"
        print 'Lattcie BSE with local vertex approximation.\n'
        print 'nk    =', nk
        print 'nw    =', nw
        print 'nwf   =', nwf
        print 'nwf_g =', nwf_g
        print 'tail_corr_nwf =', tail_corr_nwf
        print

    if tail_corr_nwf is None:
        tail_corr_nwf = nwf

    mpi.report('--> chi0_wnk_tail_corr')
    chi0_wnk_tail_corr = get_chi0_wnk(g_wk, nw=nw, nwf=tail_corr_nwf)

    mpi.report('--> trace chi0_wnk_tail_corr (WARNING! NO TAIL FIT. FIXME!)')
    chi0_wk_tail_corr = chi0q_sum_nu_tail_corr_PH(chi0_wnk_tail_corr)
    #chi0_wk_tail_corr = chi0q_sum_nu(chi0_wnk_tail_corr)

    mpi.barrier()
    mpi.report('B1 ' +
               str(chi0_wk_tail_corr[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    mpi.report('--> chi0_wnk_tail_corr to chi0_wnk')
    if tail_corr_nwf != nwf:
        mpi.report('--> fixed_fermionic_window_python_wnk')
        chi0_wnk = fixed_fermionic_window_python_wnk(chi0_wnk_tail_corr,
                                                     nwf=nwf)
    else:
        chi0_wnk = chi0_wnk_tail_corr.copy()

    del chi0_wnk_tail_corr

    mpi.barrier()
    mpi.report('C ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    mpi.report('--> trace chi0_wnk')
    chi0_wk = chi0q_sum_nu(chi0_wnk)

    mpi.barrier()
    mpi.report('D ' + str(chi0_wk[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    dchi_wk = chi0_wk_tail_corr - chi0_wk

    chi0_kw = Gf(mesh=MeshProduct(kmesh, bmesh),
                 target_shape=chi0_wk_tail_corr.target_shape)
    chi0_kw.data[:] = chi0_wk_tail_corr.data.swapaxes(0, 1)

    del chi0_wk
    del chi0_wk_tail_corr

    assert (chi0_wnk.mesh.components[0] == bmesh)
    assert (chi0_wnk.mesh.components[1] == fmesh)
    assert (chi0_wnk.mesh.components[2] == kmesh)

    # -- Lattice BSE calc with built in trace
    mpi.report('--> chi_kw from BSE')
    #mpi.report('DEBUG BSE INACTIVE'*72)
    chi_kw = chiq_sum_nu_from_chi0q_and_gamma_PH(chi0_wnk, gamma_wnn)
    #chi_kw = chi0_kw.copy()

    mpi.barrier()
    mpi.report('--> chi_kw from BSE (done)')

    del chi0_wnk

    mpi.report('--> chi_kw tail corrected (using chi0_wnk)')
    for k in kmesh:
        chi_kw[
            k, :] += dchi_wk[:,
                             k]  # -- account for high freq of chi_0 (better than nothing)

    del dchi_wk

    mpi.report('--> solve_lattice_bse, done.')

    return chi_kw, chi0_kw
Exemple #13
0
def afm_heisenberg_calculation(T, Js, dispersion,
                               n_loops_max=50, rules = [[0, 0.65], [10, 0.3], [15, 0.65]],
                               n_cycles=100000, max_time=10*60):
  if mpi.is_master_node(): print "WELCOME TO AFM HEISENBERG!"
 
  bosonic_struct = {'z': [0], '+-': [0]}
  fermionic_struct = {'up': [0], 'down': [0]}

  beta = 1.0/T 
  n_iw = 200
  n_tau = int(n_iw*pi)

  #init solver
  solver = Solver( beta = beta,
                   gf_struct = fermionic_struct, 
                   n_tau_k = n_tau,
                   n_tau_g = 10000,
                   n_tau_delta = 10000,
                   n_tau_nn = 4*n_tau,
                   n_w_b_nn = n_iw,
                   n_w = n_iw )

  #init data, assign the solver to it
  dt = bosonic_data( n_iw = n_iw, 
                     n_q = 256, 
                     beta = beta, 
                     solver = solver,
                     bosonic_struct = bosonic_struct,
                     fermionic_struct = fermionic_struct,
                     archive_name="so_far_nothing_you_shouldnt_see_this_file")
  
  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = dt.P_imp_iw,
                            accuracy=3e-5, 
                            struct=bosonic_struct, 
                            archive_name=dt.archive_name ) ]


  mixers = [ mixer( mixed_quantity = dt.P_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf ),
             mixer( mixed_quantity = dt.mus,
                    rules=rules,
                    func=mixer.mix_dictionary )  ]

  err = 0
  for J in Js:
    dt.archive_name="edmft.heis_afm.J%s.T%s.out.h5"%(J,T)
    convergers[0].archive_name = dt.archive_name

    if not (dispersion is None): #this is optional since we're using semi-analytical summation and evaluate chi_loc directly from P
      dt.fill_in_qs()
      dt.fill_in_Jq( dict.fromkeys(['z','+-'], partial(dispersion, J=J)) )
      if mpi.is_master_node():
        dt.dump_non_interacting()

    preset = edmft_heisenberg_afm(J)
    #init the dmft_loop 
    dmft = dmft_loop(  cautionary       = preset.cautionary, 
                       lattice          = preset.lattice,
                       pre_impurity     = preset.pre_impurity, 
                       impurity         = partial( impurity_cthyb, no_fermionic_bath=True, n_cycles=n_cycles, max_time=max_time ), 
                       post_impurity    = preset.post_impurity,
                       selfenergy       = preset.selfenergy, 
                       convergers       = convergers,
                       mixers           = mixers,
                       after_it_is_done = preset.after_it_is_done  )

    if J == Js[0]: #do this only once!
      dt.mus = {'up': 0.1, 'down': -0.1}
      safe_and_stupid_scalar_P_imp(safe_value = -preset.cautionary.safe_value['z']*0.95, P_imp=dt.P_imp_iw['z'])
      safe_and_stupid_scalar_P_imp(safe_value = -preset.cautionary.safe_value['+-']*0.95, P_imp=dt.P_imp_iw['+-'])

    mpi.barrier()
    #run dmft!-------------
    err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=5, print_non_loc=False)
  return err
Exemple #14
0
def csc_flow_control(general_parameters, solver_parameters):
    """
    function to run the csc cycle. It writes and removes the vasp.lock file to
    start and stop Vasp, run the converter, run the dmft cycle and abort the job
    if all iterations are finished.

    Parameters
    ----------
    general_parameters : dict
        general parameters as a dict
    solver_parameters : dict
        solver parameters as a dict

    __Returns:__
    nothing

    """
    mpi.report("  Waiting for VASP lock to appear...")
    while not toolset.is_vasp_lock_present():
        time.sleep(1)

    # if GAMMA file already exists, load it by doing an extra DFT iteration
    if os.path.exists('GAMMA'):
        iter= -8
    else:
        iter = 0

    iter_dmft = 0
    start_dft = timer()
    while iter_dmft < general_parameters['n_iter_dmft']:

        mpi.report("  Waiting for VASP lock to disappear...")
        mpi.barrier()
        #waiting for vasp to finish
        while toolset.is_vasp_lock_present():
            time.sleep(1)

        # check if we should do a dmft iteration now
        iter += 1
        if (iter-1) % general_parameters['n_iter_dft'] != 0 or iter < 0:
            if mpi.is_master_node():
                open('./vasp.lock', 'a').close()
            continue

        # run the converter
        if mpi.is_master_node():
            end_dft = timer()

            # check for plo file for projectors
            if not os.path.exists(general_parameters['plo_cfg']):
                mpi.report('*** Input PLO config file not found! I was looking for '+str(general_parameters['plo_cfg'])+' ***')
                mpi.MPI.COMM_WORLD.Abort(1)

            # run plo converter
            plo_converter.generate_and_output_as_text(general_parameters['plo_cfg'], vasp_dir='./')


            # # create h5 archive or build updated H(k)

            Converter = VaspConverter(filename=general_parameters['seedname'])

            # convert now h5 archive now
            Converter.convert_dft_input()

            # if wanted store eigenvalues in h5 archive
            if general_parameters['store_dft_eigenvals']:
                toolset.store_dft_eigvals(config_file = general_parameters['plo_cfg'],
                                  path_to_h5 = general_parameters['seedname']+'.h5',
                                  iteration = iter_dmft+1)

        mpi.barrier()

        if mpi.is_master_node():
            print
            print "="*80
            print 'DFT cycle took %10.4f seconds'%(end_dft-start_dft)
            print "calling dmft_cycle"
            print "DMFT iteration", iter_dmft+1,"/", general_parameters['n_iter_dmft']
            print "="*80
            print

        # if first iteration the h5 archive and observables need to be prepared
        if iter_dmft == 0:
            observables = dict()
            if mpi.is_master_node():
                # basic H5 archive checks and setup
                h5_archive = HDFArchive(general_parameters['seedname']+'.h5','a')
                if not 'DMFT_results' in h5_archive:
                    h5_archive.create_group('DMFT_results')
                if not 'last_iter' in h5_archive['DMFT_results']:
                    h5_archive['DMFT_results'].create_group('last_iter')
                if not 'DMFT_input' in h5_archive:
                    h5_archive.create_group('DMFT_input')

                # prepare observable dicts and files, which is stored on the master node

                observables = prep_observables(general_parameters, h5_archive)
            observables = mpi.bcast(observables)

        if mpi.is_master_node():
            start_dmft = timer()

        ############################################################
        # run the dmft_cycle
        observables = dmft_cycle(general_parameters, solver_parameters, observables)
        ############################################################

        if iter_dmft == 0:
            iter_dmft += general_parameters['n_iter_dmft_first']
        else:
            iter_dmft += general_parameters['n_iter_dmft_per']

        if mpi.is_master_node():
            end_dmft = timer()
            print
            print "="*80
            print 'DMFT cycle took %10.4f seconds'%(end_dmft-start_dmft)
            print "running VASP now"
            print "="*80
            print
        #######

        # remove the lock file and Vasp will be unleashed
        if mpi.is_master_node():
            open('./vasp.lock', 'a').close()

        # start the timer again for the dft loop
        if mpi.is_master_node():
            start_dft = timer()

    # stop if the maximum number of dmft iterations is reached
    if mpi.is_master_node():
        print "\n  Maximum number of iterations reached."
        print "  Aborting VASP iterations...\n"
        f_stop = open('STOPCAR', 'wt')
        f_stop.write("LABORT = .TRUE.\n")
        f_stop.close()
        mpi.MPI.COMM_WORLD.Abort(1)
Exemple #15
0
    def dos_wannier_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True):
        """
        Calculates the density of states in the basis of the Wannier functions.

        Parameters
        ----------
        mu : double, optional
             Chemical potential, overrides the one stored in the hdf5 archive.
        broadening : double, optional
                     Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used.
        mesh : real frequency MeshType, optional
               Omega mesh for the real-frequency Green's function. Given as parameter to lattice_gf.
        with_Sigma : boolean, optional
                     If True, the self energy is used for the calculation. If false, the DOS is calculated without self energy.
        with_dc : boolean, optional
                  If True the double counting correction is used.
        save_to_file : boolean, optional
                       If True, text files with the calculated data will be created.

        Returns
        -------
        DOS : Dict of numpy arrays
              Contains the full density of states.
        DOSproj :  Dict of numpy arrays
                   DOS projected to atoms.
        DOSproj_orb : Dict of numpy arrays
                      DOS projected to atoms and resolved into orbital contributions.
        """

        if (mesh is None) and (not with_Sigma):
            raise ValueError, "lattice_gf: Give the mesh=(om_min,om_max,n_points) for the lattice GfReFreq."
        if mesh is None:
            om_mesh = [x.real for x in self.Sigma_imp_w[0].mesh]
            om_min = om_mesh[0]
            om_max = om_mesh[-1]
            n_om = len(om_mesh)
            mesh = (om_min, om_max, n_om)
        else:
            om_min, om_max, n_om = mesh
            om_mesh = numpy.linspace(om_min, om_max, n_om)

        G_loc = []
        for icrsh in range(self.n_corr_shells):
            spn = self.spin_block_names[self.corr_shells[icrsh]['SO']]
            glist = [GfReFreq(indices=inner, window=(om_min, om_max), n_points=n_om)
                     for block, inner in self.gf_struct_sumk[icrsh]]
            G_loc.append(
                BlockGf(name_list=spn, block_list=glist, make_copies=False))
        for icrsh in range(self.n_corr_shells):
            G_loc[icrsh].zero()

        DOS = {sp: numpy.zeros([n_om], numpy.float_)
               for sp in self.spin_block_names[self.SO]}
        DOSproj = [{} for ish in range(self.n_inequiv_shells)]
        DOSproj_orb = [{} for ish in range(self.n_inequiv_shells)]
        for ish in range(self.n_inequiv_shells):
            for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]]['SO']]:
                dim = self.corr_shells[self.inequiv_to_corr[ish]]['dim']
                DOSproj[ish][sp] = numpy.zeros([n_om], numpy.float_)
                DOSproj_orb[ish][sp] = numpy.zeros(
                    [n_om, dim, dim], numpy.float_)

        ikarray = numpy.array(range(self.n_k))
        for ik in mpi.slice_array(ikarray):

            G_latt_w = self.lattice_gf(
                ik=ik, mu=mu, iw_or_w="w", broadening=broadening, mesh=mesh, with_Sigma=with_Sigma, with_dc=with_dc)
            G_latt_w *= self.bz_weights[ik]

            # Non-projected DOS
            for iom in range(n_om):
                for bname, gf in G_latt_w:
                    DOS[bname][iom] -= gf.data[iom, :, :].imag.trace() / \
                        numpy.pi

            # Projected DOS:
            for icrsh in range(self.n_corr_shells):
                tmp = G_loc[icrsh].copy()
                for bname, gf in tmp:
                    tmp[bname] << self.downfold(ik, icrsh, bname, G_latt_w[
                                                bname], gf)  # downfolding G
                G_loc[icrsh] += tmp

        # Collect data from mpi:
        for bname in DOS:
            DOS[bname] = mpi.all_reduce(
                mpi.world, DOS[bname], lambda x, y: x + y)
        for icrsh in range(self.n_corr_shells):
            G_loc[icrsh] << mpi.all_reduce(
                mpi.world, G_loc[icrsh], lambda x, y: x + y)
        mpi.barrier()

        # Symmetrize and rotate to local coord. system if needed:
        if self.symm_op != 0:
            G_loc = self.symmcorr.symmetrize(G_loc)
        if self.use_rotations:
            for icrsh in range(self.n_corr_shells):
                for bname, gf in G_loc[icrsh]:
                    G_loc[icrsh][bname] << self.rotloc(
                        icrsh, gf, direction='toLocal')

        # G_loc can now also be used to look at orbitally-resolved quantities
        for ish in range(self.n_inequiv_shells):
            for bname, gf in G_loc[self.inequiv_to_corr[ish]]:  # loop over spins
                for iom in range(n_om):
                    DOSproj[ish][bname][iom] -= gf.data[iom,
                                                        :, :].imag.trace() / numpy.pi
                DOSproj_orb[ish][bname][
                    :, :, :] -= gf.data[:, :, :].imag / numpy.pi

        # Write to files
        if save_to_file and mpi.is_master_node():
            for sp in self.spin_block_names[self.SO]:
                f = open('DOS_wann_%s.dat' % sp, 'w')
                for iom in range(n_om):
                    f.write("%s    %s\n" % (om_mesh[iom], DOS[sp][iom]))
                f.close()

                # Partial
                for ish in range(self.n_inequiv_shells):
                    f = open('DOS_wann_%s_proj%s.dat' % (sp, ish), 'w')
                    for iom in range(n_om):
                        f.write("%s    %s\n" %
                                (om_mesh[iom], DOSproj[ish][sp][iom]))
                    f.close()

                    # Orbitally-resolved
                    for i in range(self.corr_shells[self.inequiv_to_corr[ish]]['dim']):
                        for j in range(i, self.corr_shells[self.inequiv_to_corr[ish]]['dim']):
                            f = open('DOS_wann_' + sp + '_proj' + str(ish) +
                                     '_' + str(i) + '_' + str(j) + '.dat', 'w')
                            for iom in range(n_om):
                                f.write("%s    %s\n" % (
                                    om_mesh[iom], DOSproj_orb[ish][sp][iom, i, j]))
                            f.close()

        return DOS, DOSproj, DOSproj_orb
Exemple #16
0
    def partial_charges(self, beta=40, mu=None, with_Sigma=True, with_dc=True):
        """
        Calculates the orbitally-resolved density matrix for all the orbitals considered in the input, consistent with
        the definition of Wien2k. Hence, (possibly non-orthonormal) projectors have to be provided in the partial projectors subgroup of
        the hdf5 archive.

        Parameters
        ----------

        with_Sigma : boolean, optional
                     If True, the self energy is used for the calculation. If false, partial charges are calculated without self-energy correction.
        beta : double, optional
               In case the self-energy correction is not used, the inverse temperature where the calculation should be done has to be given here.
        mu : double, optional
             Chemical potential, overrides the one stored in the hdf5 archive.
        with_dc : boolean, optional
                  If True the double counting correction is used.

        Returns
        -------
        dens_mat : list of numpy array
                   A list of density matrices projected to all shells provided in the input.
        """

        things_to_read = ['dens_mat_below', 'n_parproj',
                          'proj_mat_all', 'rot_mat_all', 'rot_mat_all_time_inv']
        value_read = self.read_input_from_hdf(
            subgrp=self.parproj_data, things_to_read=things_to_read)
        if not value_read:
            return value_read
        if self.symm_op:
            self.symmpar = Symmetry(self.hdf_file, subgroup=self.symmpar_data)

        spn = self.spin_block_names[self.SO]
        ntoi = self.spin_names_to_ind[self.SO]
        # Density matrix in the window
        self.dens_mat_window = [[numpy.zeros([self.shells[ish]['dim'], self.shells[ish]['dim']], numpy.complex_)
                                 for ish in range(self.n_shells)]
                                for isp in range(len(spn))]
        # Set up G_loc
        gf_struct_parproj = [[(sp, range(self.shells[ish]['dim'])) for sp in spn]
                             for ish in range(self.n_shells)]
        if with_Sigma:
            G_loc = [BlockGf(name_block_generator=[(block, GfImFreq(indices=inner, mesh=self.Sigma_imp_iw[0].mesh))
                                                   for block, inner in gf_struct_parproj[ish]], make_copies=False)
                     for ish in range(self.n_shells)]
            beta = self.Sigma_imp_iw[0].mesh.beta
        else:
            G_loc = [BlockGf(name_block_generator=[(block, GfImFreq(indices=inner, beta=beta))
                                                   for block, inner in gf_struct_parproj[ish]], make_copies=False)
                     for ish in range(self.n_shells)]
        for ish in range(self.n_shells):
            G_loc[ish].zero()

        ikarray = numpy.array(range(self.n_k))
        for ik in mpi.slice_array(ikarray):

            G_latt_iw = self.lattice_gf(
                ik=ik, mu=mu, iw_or_w="iw", beta=beta, with_Sigma=with_Sigma, with_dc=with_dc)
            G_latt_iw *= self.bz_weights[ik]
            for ish in range(self.n_shells):
                tmp = G_loc[ish].copy()
                for ir in range(self.n_parproj[ish]):
                    for bname, gf in tmp:
                        tmp[bname] << self.downfold(ik, ish, bname, G_latt_iw[
                                                    bname], gf, shells='all', ir=ir)
                    G_loc[ish] += tmp

        # Collect data from mpi:
        for ish in range(self.n_shells):
            G_loc[ish] << mpi.all_reduce(
                mpi.world, G_loc[ish], lambda x, y: x + y)
        mpi.barrier()

        # Symmetrize and rotate to local coord. system if needed:
        if self.symm_op != 0:
            G_loc = self.symmpar.symmetrize(G_loc)
        if self.use_rotations:
            for ish in range(self.n_shells):
                for bname, gf in G_loc[ish]:
                    G_loc[ish][bname] << self.rotloc(
                        ish, gf, direction='toLocal', shells='all')

        for ish in range(self.n_shells):
            isp = 0
            for bname, gf in G_loc[ish]:
                self.dens_mat_window[isp][ish] = G_loc[ish].density()[bname]
                isp += 1

        # Add density matrices to get the total:
        dens_mat = [[self.dens_mat_below[ntoi[spn[isp]]][ish] + self.dens_mat_window[isp][ish]
                     for ish in range(self.n_shells)]
                    for isp in range(len(spn))]

        return dens_mat
Exemple #17
0
    def spaghettis(self, broadening=None, plot_shift=0.0, plot_range=None, ishell=None, mu=None, save_to_file='Akw_'):
        """
        Calculates the correlated band structure using a real-frequency self energy.

        Parameters
        ----------
        mu : double, optional
             Chemical potential, overrides the one stored in the hdf5 archive.
        broadening : double, optional
                     Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used.
        plot_shift : double, optional
                     Offset for each A(k,w) for stacked plotting of spectra.
        plot_range : list of double, optional
                     Sets the energy window for plotting to (plot_range[0],plot_range[1]). If not provided, the energy mesh of the self energy is used.
        ishell : integer, optional
                 Contains the index of the shell on which the spectral function is projected. If ishell=None, the total spectrum without projection is calculated.
        save_to_file : string, optional
                       Filename where the spectra are stored.

        Returns
        -------
        Akw : Dict of numpy arrays
              Data as it is also written to the files.
        """

        assert hasattr(
            self, "Sigma_imp_w"), "spaghettis: Set Sigma_imp_w first."
        things_to_read = ['n_k', 'n_orbitals', 'proj_mat',
                          'hopping', 'n_parproj', 'proj_mat_all']
        value_read = self.read_input_from_hdf(
            subgrp=self.bands_data, things_to_read=things_to_read)
        if not value_read:
            return value_read
        things_to_read = ['rot_mat_all', 'rot_mat_all_time_inv']
        value_read = self.read_input_from_hdf(
            subgrp=self.parproj_data, things_to_read=things_to_read)
        if not value_read:
            return value_read

        if mu is None:
            mu = self.chemical_potential
        spn = self.spin_block_names[self.SO]
        mesh = [x.real for x in self.Sigma_imp_w[0].mesh]
        n_om = len(mesh)

        if plot_range is None:
            om_minplot = mesh[0] - 0.001
            om_maxplot = mesh[n_om - 1] + 0.001
        else:
            om_minplot = plot_range[0]
            om_maxplot = plot_range[1]

        if ishell is None:
            Akw = {sp: numpy.zeros([self.n_k, n_om], numpy.float_)
                   for sp in spn}
        else:
            Akw = {sp: numpy.zeros(
                [self.shells[ishell]['dim'], self.n_k, n_om], numpy.float_) for sp in spn}

        if not ishell is None:
            gf_struct_parproj = [
                (sp, range(self.shells[ishell]['dim'])) for sp in spn]
            G_loc = BlockGf(name_block_generator=[(block, GfReFreq(indices=inner, mesh=self.Sigma_imp_w[0].mesh))
                                                  for block, inner in gf_struct_parproj], make_copies=False)
            G_loc.zero()

        ikarray = numpy.array(range(self.n_k))
        for ik in mpi.slice_array(ikarray):

            G_latt_w = self.lattice_gf(
                ik=ik, mu=mu, iw_or_w="w", broadening=broadening)

            if ishell is None:
                # Non-projected A(k,w)
                for iom in range(n_om):
                    if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                        for bname, gf in G_latt_w:
                            Akw[bname][ik, iom] += gf.data[iom, :,
                                                           :].imag.trace() / (-1.0 * numpy.pi)
                        # shift Akw for plotting stacked k-resolved eps(k)
                        # curves
                        Akw[bname][ik, iom] += ik * plot_shift

            else:  # ishell not None
                # Projected A(k,w):
                G_loc.zero()
                tmp = G_loc.copy()
                for ir in range(self.n_parproj[ishell]):
                    for bname, gf in tmp:
                        tmp[bname] << self.downfold(ik, ishell, bname, G_latt_w[
                                                    bname], gf, shells='all', ir=ir)
                    G_loc += tmp

                # Rotate to local frame
                if self.use_rotations:
                    for bname, gf in G_loc:
                        G_loc[bname] << self.rotloc(
                            ishell, gf, direction='toLocal', shells='all')

                for iom in range(n_om):
                    if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                        for ish in range(self.shells[ishell]['dim']):
                            for sp in spn:
                                Akw[sp][ish, ik, iom] = G_loc[sp].data[
                                    iom, ish, ish].imag / (-1.0 * numpy.pi)

        # Collect data from mpi
        for sp in spn:
            Akw[sp] = mpi.all_reduce(mpi.world, Akw[sp], lambda x, y: x + y)
        mpi.barrier()

        if save_to_file and mpi.is_master_node():
            if ishell is None:
                for sp in spn:  # loop over GF blocs:
                    # Open file for storage:
                    f = open(save_to_file + sp + '.dat', 'w')
                    for ik in range(self.n_k):
                        for iom in range(n_om):
                            if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                                if plot_shift > 0.0001:
                                    f.write('%s      %s\n' %
                                            (mesh[iom], Akw[sp][ik, iom]))
                                else:
                                    f.write('%s     %s      %s\n' %
                                            (ik, mesh[iom], Akw[sp][ik, iom]))
                        f.write('\n')
                    f.close()

            else:  # ishell is not None
                for sp in spn:
                    for ish in range(self.shells[ishell]['dim']):
                        # Open file for storage:
                        f = open(save_to_file + str(ishell) + '_' +
                                 sp + '_proj' + str(ish) + '.dat', 'w')
                        for ik in range(self.n_k):
                            for iom in range(n_om):
                                if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                                    if plot_shift > 0.0001:
                                        f.write('%s      %s\n' % (
                                            mesh[iom], Akw[sp][ish, ik, iom]))
                                    else:
                                        f.write('%s     %s      %s\n' % (
                                            ik, mesh[iom], Akw[sp][ish, ik, iom]))
                            f.write('\n')
                        f.close()

        return Akw
Exemple #18
0
    def constr_Sigma_real_axis(self, filename, hdf=True, hdf_dataset='SigmaReFreq',n_om=0,orb=0, tol_mesh=1e-6):
        """Uses Data from files to construct Sigma (or GF)  on the real axis."""

        if not hdf:
            # read sigma from text files
            #first get the mesh out of one of the files:
            if (len(self.gf_struct_solver[orb][0][1])==1):
                Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'.dat'
            else:
                Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'/'+str(self.gf_struct_solver[orb][0][1][0])+'_'+str(self.gf_struct_solver[orb][0][1][0])+'.dat'

            R = read_fortran_file(Fname)
            mesh = numpy.zeros([n_om],numpy.float_)
            try:
                for i in xrange(n_om):
                    mesh[i] = R.next()
                    sk = R.next()
                    sk = R.next()

            except StopIteration : # a more explicit error if the file is corrupted.
                raise "SumkLDA.read_Sigma_ME : reading mesh failed!"
            R.close()

            # check whether the mesh is uniform
            bin = (mesh[n_om-1]-mesh[0])/(n_om-1)
            for i in xrange(n_om):
                assert abs(i*bin+mesh[0]-mesh[i]) < tol_mesh, 'constr_Sigma_ME: real-axis mesh is non-uniform!'

            # construct Sigma
            a_list = [a for a,al in self.gf_struct_solver[orb]]
            glist = lambda : [ GfReFreq(indices = al, window=(mesh[0],mesh[n_om-1]),n_points=n_om) for a,al in self.gf_struct_solver[orb]]
            SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)

            #read Sigma
        
            for i,g in SigmaME:
                mesh=[w for w in g.mesh]
                for iL in g.indices:
                    for iR in g.indices:
                        if (len(g.indices) == 1):
                            Fname = filename+'_%s'%(i)+'.dat'
                        else:
                            Fname = 'SigmaME_'+'%s'%(i)+'_%s'%(iL)+'_%s'%(iR)+'.dat'
                        R = read_fortran_file(Fname)
                        try:
                            for iom in xrange(n_om):
                                sk = R.next()
                                rsig = R.next()
                                isig = R.next()
                                g.data[iom,iL,iR]=rsig+1j*isig
                        except StopIteration : # a more explicit error if the file is corrupted.
                            raise "SumkLDA.read_Sigma_ME : reading Sigma from file failed!"
                        R.close()


        else:

            # read sigma from hdf
            omega_min=0.0
            omega_max=0.0
            n_om=0
            if (mpi.is_master_node()):
                ar = HDFArchive(filename)
                SigmaME = ar[hdf_dataset]
                del ar
                # we need some parameters to construct Sigma on other nodes
                omega_min=SigmaME.mesh.omega_min
                omega_max=SigmaME.mesh.omega_max
                n_om=len(SigmaME.mesh)
            omega_min=mpi.bcast(omega_min)
            omega_max=mpi.bcast(omega_max)
            n_om=mpi.bcast(n_om)
            mpi.barrier()
            # construct Sigma on other nodes
            if (not mpi.is_master_node()):
                a_list = [a for a,al in self.gf_struct_solver[orb]]
                glist = lambda : [ GfReFreq(indices = al, window=(omega_min,omega_max),n_points=n_om) for a,al in self.gf_struct_solver[orb]]
                SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
            # pass SigmaME to other nodes
            SigmaME = mpi.bcast(SigmaME)
            mpi.barrier()

        SigmaME.note='ReFreq'

        return SigmaME
def supercond_trilex_tUVJ_calculation( 
                            Ts = [0.12,0.08,0.04,0.02,0.01], 
                            ns=[0.0, 0.2, 0.4, 0.6, 0.8], 
                            ts=[0.25], t_dispersion = epsilonk_square,
                            Us = [1.0,2.0,3.0,4.0], 
                            Vs = [0.2, 0.5, 1.0, 1.5], V_dispersion = Jq_square,
                            Js = [0], J_dispersion = Jq_square,
                            hs = [0],  
                            refresh_X = False,
                            n_ks = [40], 
                            w_cutoff = 20.0,
                            n_loops_min = 10, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]],
                            use_cthyb=True, n_cycles=100000, max_time=10*60, accuracy = 1e-4,
                            initial_guess_archive_name = '', suffix=''):
  if mpi.is_master_node(): print "WELCOME TO supercond trilex tUVJ calculation!"

  bosonic_struct = {'0': [0], '1': [0]}    
  if len(Js)==1 and Js[0] == 0:
    del bosonic_struct['1']
  if len(Vs)==1 and Vs[0] == 0.0:
    del bosonic_struct['0']

  fermionic_struct = {'up': [0], 'down': [0]}

  beta = 1.0/Ts[0] 
  
  n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0)
  if mpi.is_master_node():
    print "PM HUBBARD GW: n_iw: ",n_iw
  n_tau = int(n_iw*pi)

  n_q = n_ks[0]
  n_k = n_q

  #init solver
  if use_cthyb:
    solver = Solver( beta = beta,
                     gf_struct = fermionic_struct, 
                     n_tau_k = n_tau,
                     n_tau_g = 10000,
                     n_tau_delta = 10000,
                     n_tau_nn = 4*n_tau,
                     n_w_b_nn = n_iw,
                     n_w = n_iw )
  else: 
    print "no solver, quitting..."
    quit()
    

  #init data, assign the solver to it
  dt = supercond_trilex_data( 
                       n_iw = n_iw, 
                       n_iw_f = n_iw/2, 
                       n_iw_b = n_iw/2,  
                       n_k = n_k,
                       n_q = n_q, 
                       beta = beta, 
                       solver = solver,
                       bosonic_struct = bosonic_struct,
                       fermionic_struct = fermionic_struct,
                       archive_name="so_far_nothing_you_shouldnt_see_this_file" )

  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = lambda: dt.P_loc_iw,
                            accuracy=accuracy, 
                            struct=bosonic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_P_loc' ),
                 converger( monitored_quantity = lambda: dt.G_loc_iw,
                            accuracy=accuracy, 
                            struct=fermionic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_G_loc'     ) ]

  #initial guess
  ps = itertools.product(n_ks,ts,ns,Us,Vs,Js,Ts,hs)

  counter = 0
  old_nk = n_k
  old_beta = beta

  for p in ps:    
    #name stuff to avoid confusion   
    nk = p[0]
    t = p[1]
    n = p[2]
    U = p[3]
    V = p[4]
    J = p[5]
    T = p[6] 
    beta = 1.0/T
    h = p[7]

    if nk!=old_nk:
      dt.change_ks(IBZ.k_grid(nk))
      old_nk = nk

    if beta!=old_beta:
      n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0)
      n_tau = int(n_iw*pi)
      dt.change_beta(beta, n_iw)

      if trilex:
        dt.solver = Solver( beta = beta,
                     gf_struct = fermionic_struct, 
                     n_tau_k = n_tau,
                     n_tau_g = 10000,
                     n_tau_delta = 10000,
                     n_tau_nn = 4*n_tau,
                     n_w_b_nn = n_iw,
                     n_w = n_iw )
      old_beta = beta


    filename = "result"
    if len(n_ks)>1: filename += ".nk%s"%nk
    if len(ts)>1: filename += ".t%s"%t
    if len(ns)>1: filename += ".n%s"%n   
    if len(Us)>1: filename += ".U%s"%U
    if len(Vs)>1: filename += ".V%s"%V
    if len(Js)>1: filename += ".J%s"%J
    if len(Ts)>1: filename += ".T%s"%T
    if len(hs)>1: filename += ".h%s"%h
    filename += ".h5"
    dt.archive_name = filename

    for conv in convergers:
      conv.archive_name = dt.archive_name

    vks = {'0': lambda kx,ky: V_dispersion(kx,ky,J=V), '1': lambda kx,ky:  J_dispersion(kx,ky,J=J)}
    
    dt.fill_in_Jq( vks )  
    dt.fill_in_epsilonk(dict.fromkeys(fermionic_struct.keys(), partial(t_dispersion, t=t)))

    preset = supercond_trilex_tUVJ(n = n, U = U, bosonic_struct = bosonic_struct)

    n_w_f=dt.n_iw_f
    n_w_b=dt.n_iw_b
    if use_cthyb:
      impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, 
                                         trilex=True, n_w_f=n_w_f, n_w_b=n_w_b,
                                         n_cycles=n_cycles, max_time=max_time )
      dt.dump_solver = solvers.cthyb.dump
    else: quit()      

    mixers = [ mixer( mixed_quantity = dt.P_loc_iw,
                      rules=rules,
                      func=mixer.mix_gf ),
               mixer( mixed_quantity = dt.Sigma_loc_iw,
                      rules=rules,
                      func=mixer.mix_gf)  ]

    #init the dmft_loop 
    dmft = dmft_loop(  cautionary       = preset.cautionary, 
                       lattice          = preset.lattice,
                       pre_impurity     = preset.pre_impurity, 
                       impurity         = impurity, 
                       post_impurity    = preset.post_impurity,
                       selfenergy       = preset.selfenergy, 
                       convergers       = convergers,
                       mixers           = mixers,
                       after_it_is_done = preset.after_it_is_done )

    #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) )  
    if (T==Ts[0]): #do this only once!         
      dt.mus['up'] = dt.mus['down'] = U/2.0
      dt.ns['up'] = dt.ns['down'] = n #such that in the first iteration mu is not adjusted
      dt.P_imp_iw << 0.0    
      dt.Sigma_imp_iw << U/2.0  #making sure that in the first iteration the impurity problem is half-filled. if not solving impurity problem, not needed
      for U in fermionic_struct.keys(): dt.Sigmakw[U].fill(0)
      for U in fermionic_struct.keys(): dt.Xkw[U].fill(0)
    
    if refresh_X:
      for kxi in range(dt.n_k):
        for kyi in range(dt.n_k):
          for wi in range(dt.nw):
            for U in fermionic_struct.keys():
              dt.Xkw[U][wi, kxi, kyi] += X_dwave(dt.ks[kxi],dt.ks[kyi], 1.0)

    if h!=0:
      for kxi in range(dt.n_k):
        for kyi in range(dt.n_k):
          for wi in range(dt.nw):
            for U in fermionic_struct.keys():
              dt.hsck[U][kxi, kyi] = X_dwave(dt.ks[kxi],dt.ks[kyi], h)
   
    mpi.barrier()
    #run dmft!-------------
    err = dmft.run( dt,
                    n_loops_max=n_loops_max, n_loops_min=n_loops_min,
                    print_three_leg=1, print_non_local=1,
                    skip_self_energy_on_first_iteration=True,
                    last_iteration_err_is_allowed = 18 )
    if (err==2): break
    counter += 1
  return err
def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter):
    """
    """
    mpi.report("  Waiting for VASP lock to appear...")
    while not is_vasp_lock_present():
        time.sleep(1)

    vasp_running = True

    iter = 0
    while vasp_running:
        if debug: print bcolors.RED + "rank %s" % (mpi.rank) + bcolors.ENDC
        mpi.report("  Waiting for VASP lock to disappear...")
        mpi.barrier()
        while is_vasp_lock_present():
            time.sleep(1)
            #            if debug: print bcolors.YELLOW + " waiting: rank %s"%(mpi.rank) + bcolors.ENDC
            if not is_vasp_running(vasp_pid):
                mpi.report("  VASP stopped")
                vasp_running = False
                break


# Tell VASP to stop if the maximum number of iterations is reached
        iter += 1
        if iter == n_iter:
            if mpi.is_master_node():
                print "\n  Maximum number of iterations reached."
                print "  Aborting VASP iterations...\n"
                f_stop = open('STOPCAR', 'wt')
                f_stop.write("LABORT = .TRUE.\n")
                f_stop.close()

        if debug: print bcolors.MAGENTA + "rank %s" % (mpi.rank) + bcolors.ENDC
        err = 0
        exc = None
        if debug:
            print bcolors.BLUE + "plovasp: rank %s" % (mpi.rank) + bcolors.ENDC
        if mpi.is_master_node():
            converter.generate_and_output_as_text(cfg_file, vasp_dir='./')
            # Read energy from OSZICAR
            dft_energy = get_dft_energy()
        mpi.barrier()

        if debug: print bcolors.GREEN + "rank %s" % (mpi.rank) + bcolors.ENDC
        corr_energy, dft_dc = dmft_cycle()
        mpi.barrier()

        if mpi.is_master_node():
            total_energy = dft_energy + corr_energy - dft_dc
            print
            print "=" * 80
            print "  Total energy: ", total_energy
            print "  DFT energy: ", dft_energy
            print "  Corr. energy: ", corr_energy
            print "  DFT DC: ", dft_dc
            print "=" * 80
            print

        if mpi.is_master_node() and vasp_running:
            open('./vasp.lock', 'a').close()

    if mpi.is_master_node():
        total_energy = dft_energy + corr_energy - dft_dc
        with open('TOTENERGY', 'w') as f:
            f.write("  Total energy: %s\n" % (total_energy))
            f.write("  DFT energy: %s\n" % (dft_energy))
            f.write("  Corr. energy: %s\n" % (corr_energy))
            f.write("  DFT DC: %s\n" % (dft_dc))
            f.write("  Energy correction: %s\n" % (corr_energy - dft_dc))

    mpi.report("***Done")
Exemple #21
0
    def spaghettis(self, broadening=None, plot_shift=0.0, plot_range=None, ishell=None, mu=None, save_to_file='Akw_'):
        """
        Calculates the correlated band structure using a real-frequency self energy.

        Parameters
        ----------
        mu : double, optional
             Chemical potential, overrides the one stored in the hdf5 archive.
        broadening : double, optional
                     Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used.
        plot_shift : double, optional
                     Offset for each A(k,w) for stacked plotting of spectra.
        plot_range : list of double, optional
                     Sets the energy window for plotting to (plot_range[0],plot_range[1]). If not provided, the energy mesh of the self energy is used.
        ishell : integer, optional
                 Contains the index of the shell on which the spectral function is projected. If ishell=None, the total spectrum without projection is calculated.
        save_to_file : string, optional
                       Filename where the spectra are stored.

        Returns
        -------
        Akw : Dict of numpy arrays
              Data as it is also written to the files.
        """

        assert hasattr(
            self, "Sigma_imp_w"), "spaghettis: Set Sigma_imp_w first."
        things_to_read = ['n_k', 'n_orbitals', 'proj_mat',
                          'hopping', 'n_parproj', 'proj_mat_all']
        value_read = self.read_input_from_hdf(
            subgrp=self.bands_data, things_to_read=things_to_read)
        if not value_read:
            return value_read
        if ishell is not None:
            things_to_read = ['rot_mat_all', 'rot_mat_all_time_inv']
            value_read = self.read_input_from_hdf(
                subgrp=self.parproj_data, things_to_read=things_to_read)
            if not value_read:
                return value_read

        if mu is None:
            mu = self.chemical_potential
        spn = self.spin_block_names[self.SO]
        mesh = [x.real for x in self.Sigma_imp_w[0].mesh]
        n_om = len(mesh)

        if plot_range is None:
            om_minplot = mesh[0] - 0.001
            om_maxplot = mesh[n_om - 1] + 0.001
        else:
            om_minplot = plot_range[0]
            om_maxplot = plot_range[1]

        if ishell is None:
            Akw = {sp: numpy.zeros([self.n_k, n_om], numpy.float_)
                   for sp in spn}
        else:
            Akw = {sp: numpy.zeros(
                [self.shells[ishell]['dim'], self.n_k, n_om], numpy.float_) for sp in spn}

        if not ishell is None:
            gf_struct_parproj = [
                (sp, range(self.shells[ishell]['dim'])) for sp in spn]
            G_loc = BlockGf(name_block_generator=[(block, GfReFreq(indices=inner, mesh=self.Sigma_imp_w[0].mesh))
                                                  for block, inner in gf_struct_parproj], make_copies=False)
            G_loc.zero()

        ikarray = numpy.array(range(self.n_k))
        for ik in mpi.slice_array(ikarray):

            G_latt_w = self.lattice_gf(
                ik=ik, mu=mu, iw_or_w="w", broadening=broadening)

            if ishell is None:
                # Non-projected A(k,w)
                for iom in range(n_om):
                    if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                        for bname, gf in G_latt_w:
                            Akw[bname][ik, iom] += gf.data[iom, :,
                                                           :].imag.trace() / (-1.0 * numpy.pi)
                        # shift Akw for plotting stacked k-resolved eps(k)
                        # curves
                        Akw[bname][ik, iom] += ik * plot_shift

            else:  # ishell not None
                # Projected A(k,w):
                G_loc.zero()
                tmp = G_loc.copy()
                for ir in range(self.n_parproj[ishell]):
                    for bname, gf in tmp:
                        tmp[bname] << self.downfold(ik, ishell, bname, G_latt_w[
                                                    bname], gf, shells='all', ir=ir)
                    G_loc += tmp

                # Rotate to local frame
                if self.use_rotations:
                    for bname, gf in G_loc:
                        G_loc[bname] << self.rotloc(
                            ishell, gf, direction='toLocal', shells='all')

                for iom in range(n_om):
                    if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                        for ish in range(self.shells[ishell]['dim']):
                            for sp in spn:
                                Akw[sp][ish, ik, iom] = G_loc[sp].data[
                                    iom, ish, ish].imag / (-1.0 * numpy.pi)

        # Collect data from mpi
        for sp in spn:
            Akw[sp] = mpi.all_reduce(mpi.world, Akw[sp], lambda x, y: x + y)
        mpi.barrier()

        if save_to_file and mpi.is_master_node():
            if ishell is None:
                for sp in spn:  # loop over GF blocs:
                    # Open file for storage:
                    f = open(save_to_file + sp + '.dat', 'w')
                    for ik in range(self.n_k):
                        for iom in range(n_om):
                            if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                                if plot_shift > 0.0001:
                                    f.write('%s      %s\n' %
                                            (mesh[iom], Akw[sp][ik, iom]))
                                else:
                                    f.write('%s     %s      %s\n' %
                                            (ik, mesh[iom], Akw[sp][ik, iom]))
                        f.write('\n')
                    f.close()

            else:  # ishell is not None
                for sp in spn:
                    for ish in range(self.shells[ishell]['dim']):
                        # Open file for storage:
                        f = open(save_to_file + str(ishell) + '_' +
                                 sp + '_proj' + str(ish) + '.dat', 'w')
                        for ik in range(self.n_k):
                            for iom in range(n_om):
                                if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot):
                                    if plot_shift > 0.0001:
                                        f.write('%s      %s\n' % (
                                            mesh[iom], Akw[sp][ish, ik, iom]))
                                    else:
                                        f.write('%s     %s      %s\n' % (
                                            ik, mesh[iom], Akw[sp][ish, ik, iom]))
                            f.write('\n')
                        f.close()

        return Akw
Exemple #22
0
def pm_hubbard_calculation( T, Us, mutildes, dispersion, #necessary to partially evaluate dispersion!!! the calculation does not need to know about t
                            rules = [[0, 0.5], [3, 0.0], [10, 0.65]], n_loops_max=25, 
                            n_cycles=20000, max_time=10*60): 

  if mpi.is_master_node(): print "WELCOME TO PM HUBBARD!"
                                                                                 
  fermionic_struct = {'up': [0], 'down': [0]}

  beta = 1.0/T 
  n_iw = 200
  n_tau = int(n_iw*pi)
  n_k = 32

  #init solver
  solver = Solver( beta = beta,
                   gf_struct = fermionic_struct, 
                   n_tau_k = n_tau,
                   n_tau_g = 10000,
                   n_tau_delta = 10000,
                   n_tau_nn = 4*n_tau,
                   n_w_b_nn = n_iw,
                   n_w = n_iw )
  #init data, assign the solver to it
  dt = fermionic_data( n_iw = n_iw, 
                       n_k = n_k, 
                       beta = beta, 
                       solver = solver,
                       bosonic_struct = {},
                       fermionic_struct = fermionic_struct,
                       archive_name="nothing_yet_if_you_see_this_file_something_went wrong" )

  dt.fill_in_ks()
  dt.fill_in_epsilonk(dict.fromkeys(['up','down'], dispersion) )

  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = dt.Sigma_imp_iw,
                            accuracy=3e-3, 
                            struct=fermionic_struct, 
                            archive_name=dt.archive_name ) ]

  mixers = [ mixer( mixed_quantity = dt.Sigma_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf ) ]

  mpi.barrier()
  #run dmft!-------------

  err = 0
  for U in Us:
    for mutilde in mutildes:
      dt.mus['up'] = dt.mus['down'] = mutilde + U/2.0 #necessary input! by default 0
      dt.archive_name = "dmft.hubb_pm.U%s.mutilde%s.T%s.h5"%(U,mutilde,T) 
      convergers[0].archive_name = dt.archive_name

      if mpi.is_master_node():
        dt.dump_non_interacting()  

      preset = dmft_hubbard_pm(U)

      #init the dmft_loop 
      dmft = dmft_loop(  cautionary       = None, 
                         lattice          = preset.lattice,
                         pre_impurity     = preset.pre_impurity, 
                         impurity         = partial( impurity_cthyb, no_fermionic_bath=False, n_cycles=n_cycles, max_time=max_time ), 
                         post_impurity    = preset.post_impurity,
                         selfenergy       = preset.selfenergy, 
                         convergers       = convergers,
                         mixers           = mixers,
                         after_it_is_done = preset.after_it_is_done  )

      if U==Us[0]:
        dt.Sigma_imp_iw << mutilde+U/2.0 #initial guess only at the beginning, continues from the previous solution

      err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=5)
  return err #number of failed calculations
Exemple #23
0
    def dos_wannier_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True):
        """
        Calculates the density of states in the basis of the Wannier functions.

        Parameters
        ----------
        mu : double, optional
             Chemical potential, overrides the one stored in the hdf5 archive.
        broadening : double, optional
                     Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used.
        mesh : real frequency MeshType, optional
               Omega mesh for the real-frequency Green's function. Given as parameter to lattice_gf.
        with_Sigma : boolean, optional
                     If True, the self energy is used for the calculation. If false, the DOS is calculated without self energy.
        with_dc : boolean, optional
                  If True the double counting correction is used.
        save_to_file : boolean, optional
                       If True, text files with the calculated data will be created.

        Returns
        -------
        DOS : Dict of numpy arrays
              Contains the full density of states.
        DOSproj :  Dict of numpy arrays
                   DOS projected to atoms.
        DOSproj_orb : Dict of numpy arrays
                      DOS projected to atoms and resolved into orbital contributions.
        """

        if (mesh is None) and (not with_Sigma):
            raise ValueError, "lattice_gf: Give the mesh=(om_min,om_max,n_points) for the lattice GfReFreq."
        if mesh is None:
            om_mesh = [x.real for x in self.Sigma_imp_w[0].mesh]
            om_min = om_mesh[0]
            om_max = om_mesh[-1]
            n_om = len(om_mesh)
            mesh = (om_min, om_max, n_om)
        else:
            om_min, om_max, n_om = mesh
            om_mesh = numpy.linspace(om_min, om_max, n_om)

        G_loc = []
        for icrsh in range(self.n_corr_shells):
            spn = self.spin_block_names[self.corr_shells[icrsh]['SO']]
            glist = [GfReFreq(indices=inner, window=(om_min, om_max), n_points=n_om)
                     for block, inner in self.gf_struct_sumk[icrsh]]
            G_loc.append(
                BlockGf(name_list=spn, block_list=glist, make_copies=False))
        for icrsh in range(self.n_corr_shells):
            G_loc[icrsh].zero()

        DOS = {sp: numpy.zeros([n_om], numpy.float_)
               for sp in self.spin_block_names[self.SO]}
        DOSproj = [{} for ish in range(self.n_inequiv_shells)]
        DOSproj_orb = [{} for ish in range(self.n_inequiv_shells)]
        for ish in range(self.n_inequiv_shells):
            for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]]['SO']]:
                dim = self.corr_shells[self.inequiv_to_corr[ish]]['dim']
                DOSproj[ish][sp] = numpy.zeros([n_om], numpy.float_)
                DOSproj_orb[ish][sp] = numpy.zeros(
                    [n_om, dim, dim], numpy.complex_)

        ikarray = numpy.array(range(self.n_k))
        for ik in mpi.slice_array(ikarray):

            G_latt_w = self.lattice_gf(
                ik=ik, mu=mu, iw_or_w="w", broadening=broadening, mesh=mesh, with_Sigma=with_Sigma, with_dc=with_dc)
            G_latt_w *= self.bz_weights[ik]

            # Non-projected DOS
            for iom in range(n_om):
                for bname, gf in G_latt_w:
                    DOS[bname][iom] -= gf.data[iom, :, :].imag.trace() / \
                        numpy.pi

            # Projected DOS:
            for icrsh in range(self.n_corr_shells):
                tmp = G_loc[icrsh].copy()
                for bname, gf in tmp:
                    tmp[bname] << self.downfold(ik, icrsh, bname, G_latt_w[
                                                bname], gf)  # downfolding G
                G_loc[icrsh] += tmp

        # Collect data from mpi:
        for bname in DOS:
            DOS[bname] = mpi.all_reduce(
                mpi.world, DOS[bname], lambda x, y: x + y)
        for icrsh in range(self.n_corr_shells):
            G_loc[icrsh] << mpi.all_reduce(
                mpi.world, G_loc[icrsh], lambda x, y: x + y)
        mpi.barrier()

        # Symmetrize and rotate to local coord. system if needed:
        if self.symm_op != 0:
            G_loc = self.symmcorr.symmetrize(G_loc)
        if self.use_rotations:
            for icrsh in range(self.n_corr_shells):
                for bname, gf in G_loc[icrsh]:
                    G_loc[icrsh][bname] << self.rotloc(
                        icrsh, gf, direction='toLocal')

        # G_loc can now also be used to look at orbitally-resolved quantities
        for ish in range(self.n_inequiv_shells):
            for bname, gf in G_loc[self.inequiv_to_corr[ish]]:  # loop over spins
                for iom in range(n_om):
                    DOSproj[ish][bname][iom] -= gf.data[iom,
                                                        :, :].imag.trace() / numpy.pi
                DOSproj_orb[ish][bname][
                    :, :, :] += (1.0j*(gf-gf.conjugate().transpose())/2.0/numpy.pi).data[:,:,:]

        # Write to files
        if save_to_file and mpi.is_master_node():
            for sp in self.spin_block_names[self.SO]:
                f = open('DOS_wann_%s.dat' % sp, 'w')
                for iom in range(n_om):
                    f.write("%s    %s\n" % (om_mesh[iom], DOS[sp][iom]))
                f.close()

                # Partial
                for ish in range(self.n_inequiv_shells):
                    f = open('DOS_wann_%s_proj%s.dat' % (sp, ish), 'w')
                    for iom in range(n_om):
                        f.write("%s    %s\n" %
                                (om_mesh[iom], DOSproj[ish][sp][iom]))
                    f.close()

                    # Orbitally-resolved
                    for i in range(self.corr_shells[self.inequiv_to_corr[ish]]['dim']):
                        for j in range(i, self.corr_shells[self.inequiv_to_corr[ish]]['dim']):
                            f = open('DOS_wann_' + sp + '_proj' + str(ish) +
                                     '_' + str(i) + '_' + str(j) + '.dat', 'w')
                            for iom in range(n_om):
                                f.write("%s    %s    %s\n" % (
                                    om_mesh[iom], DOSproj_orb[ish][sp][iom, i, j].real,DOSproj_orb[ish][sp][iom, i, j].imag))
                            f.close()

        return DOS, DOSproj, DOSproj_orb
Exemple #24
0
delta_mix = 1.0                  # Mixing factor of Delta as input for the AIM
dc_type = 0                      # DC type: 0 FLL, 1 Held, 2 AMF
use_blocks = True                # use bloc structure from DFT input
prec_mu = 0.0001
h_field = 0.0

# Solver parameters
p = {}
p["max_time"] = -1
p["length_cycle"] = 50
p["n_warmup_cycles"] = 50
p["n_cycles"] = 5000

Converter = Wien2kConverter(filename=dft_filename, repacking=True)
Converter.convert_dft_input()
mpi.barrier()

previous_runs = 0
previous_present = False
if mpi.is_master_node():
    f = HDFArchive(dft_filename+'.h5','a')
    if 'dmft_output' in f:
        ar = f['dmft_output']
        if 'iterations' in ar:
            previous_present = True
            previous_runs = ar['iterations']
    else:
        f.create_group('dmft_output')
    del f
previous_runs    = mpi.bcast(previous_runs)
previous_present = mpi.bcast(previous_present)
Exemple #25
0
    def partial_charges(self, beta=40, mu=None, with_Sigma=True, with_dc=True):
        """
        Calculates the orbitally-resolved density matrix for all the orbitals considered in the input, consistent with
        the definition of Wien2k. Hence, (possibly non-orthonormal) projectors have to be provided in the partial projectors subgroup of
        the hdf5 archive.

        Parameters
        ----------

        with_Sigma : boolean, optional
                     If True, the self energy is used for the calculation. If false, partial charges are calculated without self-energy correction.
        beta : double, optional
               In case the self-energy correction is not used, the inverse temperature where the calculation should be done has to be given here.
        mu : double, optional
             Chemical potential, overrides the one stored in the hdf5 archive.
        with_dc : boolean, optional
                  If True the double counting correction is used.

        Returns
        -------
        dens_mat : list of numpy array
                   A list of density matrices projected to all shells provided in the input.
        """

        things_to_read = ['dens_mat_below', 'n_parproj',
                          'proj_mat_all', 'rot_mat_all', 'rot_mat_all_time_inv']
        value_read = self.read_input_from_hdf(
            subgrp=self.parproj_data, things_to_read=things_to_read)
        if not value_read:
            return value_read
        if self.symm_op:
            self.symmpar = Symmetry(self.hdf_file, subgroup=self.symmpar_data)

        spn = self.spin_block_names[self.SO]
        ntoi = self.spin_names_to_ind[self.SO]
        # Density matrix in the window
        self.dens_mat_window = [[numpy.zeros([self.shells[ish]['dim'], self.shells[ish]['dim']], numpy.complex_)
                                 for ish in range(self.n_shells)]
                                for isp in range(len(spn))]
        # Set up G_loc
        gf_struct_parproj = [[(sp, range(self.shells[ish]['dim'])) for sp in spn]
                             for ish in range(self.n_shells)]
        if with_Sigma:
            G_loc = [BlockGf(name_block_generator=[(block, GfImFreq(indices=inner, mesh=self.Sigma_imp_iw[0].mesh))
                                                   for block, inner in gf_struct_parproj[ish]], make_copies=False)
                     for ish in range(self.n_shells)]
            beta = self.Sigma_imp_iw[0].mesh.beta
        else:
            G_loc = [BlockGf(name_block_generator=[(block, GfImFreq(indices=inner, beta=beta))
                                                   for block, inner in gf_struct_parproj[ish]], make_copies=False)
                     for ish in range(self.n_shells)]
        for ish in range(self.n_shells):
            G_loc[ish].zero()

        ikarray = numpy.array(range(self.n_k))
        for ik in mpi.slice_array(ikarray):

            G_latt_iw = self.lattice_gf(
                ik=ik, mu=mu, iw_or_w="iw", beta=beta, with_Sigma=with_Sigma, with_dc=with_dc)
            G_latt_iw *= self.bz_weights[ik]
            for ish in range(self.n_shells):
                tmp = G_loc[ish].copy()
                for ir in range(self.n_parproj[ish]):
                    for bname, gf in tmp:
                        tmp[bname] << self.downfold(ik, ish, bname, G_latt_iw[
                                                    bname], gf, shells='all', ir=ir)
                    G_loc[ish] += tmp

        # Collect data from mpi:
        for ish in range(self.n_shells):
            G_loc[ish] << mpi.all_reduce(
                mpi.world, G_loc[ish], lambda x, y: x + y)
        mpi.barrier()

        # Symmetrize and rotate to local coord. system if needed:
        if self.symm_op != 0:
            G_loc = self.symmpar.symmetrize(G_loc)
        if self.use_rotations:
            for ish in range(self.n_shells):
                for bname, gf in G_loc[ish]:
                    G_loc[ish][bname] << self.rotloc(
                        ish, gf, direction='toLocal', shells='all')

        for ish in range(self.n_shells):
            isp = 0
            for bname, gf in G_loc[ish]:
                self.dens_mat_window[isp][ish] = G_loc[ish].density()[bname]
                isp += 1

        # Add density matrices to get the total:
        dens_mat = [[self.dens_mat_below[ntoi[spn[isp]]][ish] + self.dens_mat_window[isp][ish]
                     for ish in range(self.n_shells)]
                    for isp in range(len(spn))]

        return dens_mat
def pm_tUV_trilex_calculation( T, 
                               mutildes=[0.0], 
                               ns = [0.5, 0.53, 0.55, 0.57], fixed_n = False,
                               ts=[0.25], t_dispersion = epsilonk_square, ph_symmetry = True,
                               Us = [1.0], alpha=2.0/3.0, ising = False,    
                               Vs = [0.0], V_dispersion = Jq_square,       
                               nk = 24,                
                               n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]],
                               trilex = True,
                               use_cthyb=True, n_cycles=100000, max_time=10*60,
                               initial_guess_archive_name = '', suffix=''):
  if mpi.is_master_node(): print "WELCOME TO PM tUV trilex calculation!"

  bosonic_struct = {'0': [0], '1': [0]}    
  if not ising:
    if alpha==2.0/3.0:
      del bosonic_struct['1']
    if alpha==1.0/3.0:
      del bosonic_struct['0']
  else:
    if alpha==1.0:
      del vks['1']
    if alpha==0.0:
      del vks['0']

  fermionic_struct = {'up': [0], 'down': [0]}

  beta = 1.0/T 
  
  n_iw = int(((30.0*beta)/math.pi-1.0)/2.0)
  if mpi.is_master_node():
    print "PM HUBBARD GW: n_iw: ",n_iw
  n_tau = int(n_iw*pi)

  n_q = nk
  n_k = n_q

  #init solver

  solver = Solver(   beta = beta,
                     gf_struct = fermionic_struct, 
                     n_tau_k = n_tau,
                     n_tau_g = 10000,
                     n_tau_delta = 10000,
                     n_tau_nn = 4*n_tau,
                     n_w_b_nn = n_iw,
                     n_w = n_iw )

  #init data, assign the solver to it
  dt = GW_data(     n_iw = n_iw,
                    n_k = n_k,
                    n_q = n_q, 
                    beta = beta, 
                    solver = solver,
                    bosonic_struct = bosonic_struct,
                    fermionic_struct = fermionic_struct,
                    archive_name="so_far_nothing_you_shouldnt_see_this_file" )

  if trilex:
    dt.__class__ = trilex_data
    dt.promote( n_iw_f = n_iw/2, 
                n_iw_b  = n_iw/2 ) 

  if not trilex:
    dt.get_Sigmakw = partial(dt.get_Sigmakw, imtime = True)
    dt.get_Pqnu = partial(dt.get_Pqnu, imtime = True)
    #dt.get_Sigma_loc_from_local_bubble = partial(dt.get_Sigma_loc_from_local_bubble, imtime = True)
    #dt.get_P_loc_from_local_bubble = partial(dt.get_P_loc_from_local_bubble, imtime = True)
  
  if ising:
    dt.get_Sigmakw = partial(dt.get_Sigmakw, ising_decoupling = True )

  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = lambda: dt.P_imp_iw,
                            accuracy=1e-4, 
                            struct=bosonic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_P_imp' ),
                 converger( monitored_quantity = lambda: dt.G_imp_iw,
                            accuracy=1e-4, 
                            struct=fermionic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_G_imp'     ) ]

  mixers = [ mixer( mixed_quantity = dt.P_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf ),
             mixer( mixed_quantity = dt.Sigma_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf)  ]

  monitors = [ monitor( monitored_quantity = lambda: dt.ns['up'], 
                          h5key = 'n_vs_it', 
                          archive_name = dt.archive_name),
               monitor( monitored_quantity = lambda: dt.mus['up'], 
                          h5key = 'mu_vs_it', 
                          archive_name = dt.archive_name) ]

  err = 0
  #initial guess
  if fixed_n:
    ps = itertools.product(ns,ts,Us,Vs)
  else:
    ps = itertools.product(mutildes,ts,Us,Vs)

  counter = 0
  for p in ps:    
    #name stuff to avoid confusion   
    if fixed_n:
      n = p[0]
      mutilde = None
    else:
      mutilde = p[0]
      n = None
    t = p[1]
    U = p[2]
    V = p[3]

    filename = "result"
    if len(mutildes)>1 and not fixed_n: filename += ".mutilde%s"%mutilde
    if len(ns)>1 and fixed_n: filename += ".n%s"%n
    if len(ts)>1: filename += ".t%s"%t
    if len(Us)>1: filename += ".U%s"%U
    if len(Vs)>1: filename += ".V%s"%V
    filename += ".h5"
    dt.archive_name = filename

    for conv in convergers:
      conv.archive_name = dt.archive_name

    if not ising:
      Uch = (3.0*alpha-1.0)*U
      Usp = (alpha-2.0/3.0)*U
    else:
      Uch = alpha*U
      Usp = (alpha-1.0)*U

    vks = {'0': lambda kx,ky: Uch + V_dispersion(kx,ky,J=V), '1': lambda kx,ky: Usp}
    if not ising:
      if alpha==2.0/3.0:
        del vks['1']
      if alpha==1.0/3.0:
        del vks['0']
    else:
      if alpha==1.0:
        del vks['1']
      if alpha==0.0:
        del vks['0']
    
    dt.fill_in_Jq( vks )  
    dt.fill_in_epsilonk(dict.fromkeys(['up','down'], partial(t_dispersion, t=t)))


    if trilex: 
      preset = trilex_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct, ising = ising, n=n, ph_symmetry=ph_symmetry)
    else:      
      preset = GW_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct, ising = ising, n=n, ph_symmetry=ph_symmetry)


    #preset.cautionary.get_safe_values(dt.Jq, dt.bosonic_struct, n_q, n_q)
    if mpi.is_master_node():
      print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," mutilde= ",mutilde
      #print "cautionary safe values: ",preset.cautionary.safe_value  
    
    
    impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, 
                                           trilex=trilex, n_w_f=dt.n_iw_f if trilex else 2, n_w_b=dt.n_iw_b if trilex else 2,
                                           n_cycles=n_cycles, max_time=max_time )
    dt.dump_solver = solvers.cthyb.dump

    #init the dmft_loop 
    dmft = dmft_loop(  cautionary       = preset.cautionary, 
                       lattice          = preset.lattice,
                       pre_impurity     = preset.pre_impurity, 
                       impurity         = impurity, 
                       post_impurity    = partial( preset.post_impurity ),
                       selfenergy       = preset.selfenergy, 
                       convergers       = convergers,
                       mixers           = mixers,
                       after_it_is_done = preset.after_it_is_done )

    #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) )  
    if counter==0: #do this only once!   
      if mutilde is None:
        mu = n*U     
      else:
        mu = mutilde+U/2.0      
      dt.mus['up'] = dt.mus['down'] = mu
      dt.P_imp_iw << 0.0
      #for A in bosonic_struct.keys():
      #  if preset.cautionary.safe_value[A] < 0.0:
      #    safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value[A]*0.95, P_imp=dt.P_imp_iw[A])
      dt.Sigma_imp_iw << mu #making sure that in the first iteration Delta is close to half-filled

    
    if initial_guess_archive_name!='':
      dt.load_initial_guess_from_file(initial_guess_archive_name, suffix)
      #dt.load_initial_guess_from_file("/home/jvucicev/TRIQS/run/sc_scripts/Archive_Vdecoupling/edmft.mutilde0.0.t0.25.U3.0.V2.0.J0.0.T0.01.h5")
   
    mpi.barrier()
    #run dmft!-------------
    err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_non_local=True)
    counter += 1
  return err
Exemple #27
0
    h = Histogram(0, 10)
    h << x

else:
    h, h_ref = None, None
    
h = mpi.bcast(h)
h_ref = mpi.bcast(h_ref)

for rank in xrange(mpi.size):
    if rank == mpi.rank:

        print '-'*72
        print 'rank =', mpi.rank
        print 'h =\n', h
        print 'h_ref =\n', h_ref

        # -- Compare h and h_ref
        pts = np.array([ int(h.mesh_point(idx)) for idx in xrange(len(h))])

        for pt, val in zip(pts, h.data):
            val = int(val)
            #print pt, val
            if val > 0:
                assert( val == h_ref[pt] )
            else:
                assert( not h_ref.has_key(pt) )
        
    mpi.barrier()

Exemple #28
0
    def extract_G_loc(self, mu=None, with_Sigma = True):
        """ 
        extracts the local downfolded Green function at the chemical potential of the class.
        At the end, the local G is rotated from the gloabl coordinate system to the local system.
        if with_Sigma = False: Sigma is not included => non-interacting local GF
        """

        if (mu is None): mu = self.chemical_potential
            
        Gloc = [ self.Sigma_imp[icrsh].copy() for icrsh in xrange(self.n_corr_shells) ]   # this list will be returned  
        for icrsh in xrange(self.n_corr_shells): Gloc[icrsh].zero()                # initialize to zero
        beta = Gloc[0].mesh.beta
        
        ikarray=numpy.array(range(self.n_k))
        
        for ik in mpi.slice_array(ikarray):
            
            S = self.lattice_gf_matsubara(ik=ik,mu=mu,with_Sigma = with_Sigma, beta = beta) 
            S *= self.bz_weights[ik]

                
            for icrsh in xrange(self.n_corr_shells):
                tmp = Gloc[icrsh].copy()                  # init temporary storage
                for sig,gf in tmp: tmp[sig] <<= self.downfold(ik,icrsh,sig,S[sig],gf)
                Gloc[icrsh] += tmp

        #collect data from mpi:
        for icrsh in xrange(self.n_corr_shells):
            Gloc[icrsh] <<= mpi.all_reduce(mpi.world,Gloc[icrsh],lambda x,y : x+y)
        mpi.barrier()

  
        # Gloc[:] is now the sum over k projected to the local orbitals.
        # here comes the symmetrisation, if needed:   
        if (self.symm_op!=0): Gloc = self.Symm_corr.symmetrize(Gloc)
        
        # Gloc is rotated to the local coordinate system:
        if (self.use_rotations):
            for icrsh in xrange(self.n_corr_shells):
                for sig,gf in Gloc[icrsh]: Gloc[icrsh][sig] <<= self.rotloc(icrsh,gf,direction='toLocal')

        # transform to CTQMC blocks:
        Glocret = [ BlockGf( name_block_generator = [ (a,GfImFreq(indices = al, mesh = Gloc[0].mesh)) for a,al in self.gf_struct_solver[i] ],
                        make_copies = False) for i in xrange(self.n_inequiv_corr_shells)  ]
        for ish in xrange(self.n_inequiv_corr_shells):

            # setting up the index map:
            map_ind={}
            cnt = {}
            for blname in self.map[ish]:
                cnt[blname] = 0
    
            for a,al in self.gf_struct_solver[ish]:
                blname = self.map_inv[ish][a]
                map_ind[a] = range(len(al))
                for i in al:
                    map_ind[a][i] = cnt[blname]
                    cnt[blname]+=1
            
            
            for ibl in range(len(self.gf_struct_solver[ish])):
                for i in range(len(self.gf_struct_solver[ish][ibl][1])):
                    for j in range(len(self.gf_struct_solver[ish][ibl][1])):
                        bl   = self.gf_struct_solver[ish][ibl][0]
                        ind1 = self.gf_struct_solver[ish][ibl][1][i]
                        ind2 = self.gf_struct_solver[ish][ibl][1][j]
                        ind1_imp = map_ind[bl][ind1]
                        ind2_imp = map_ind[bl][ind2]
                        Glocret[ish][bl][ind1,ind2] <<= Gloc[self.invshellmap[ish]][self.map_inv[ish][bl]][ind1_imp,ind2_imp]


        # return only the inequivalent shells:
        return Glocret
Exemple #29
0
    def partial_charges(self, beta=40):
        """Calculates the orbitally-resolved density matrix for all the orbitals considered in the input.
           The theta-projectors are used, hence case.parproj data is necessary"""

        #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all']
        #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data,thingstoread=thingstoread)
        retval = self.read_par_proj_input_from_hdf()
        if not retval: return retval
        if self.symm_op:
            self.Symm_par = Symmetry(self.hdf_file,
                                     subgroup=self.symm_par_data)

        # Density matrix in the window
        bln = self.block_names[self.SO]
        ntoi = self.names_to_ind[self.SO]
        self.dens_mat_window = [[
            numpy.zeros([self.shells[ish][3], self.shells[ish][3]],
                        numpy.complex_) for ish in range(self.n_shells)
        ] for isp in range(len(bln))]  # init the density matrix

        mu = self.chemical_potential
        GFStruct_proj = [[(al, range(self.shells[i][3])) for al in bln]
                         for i in xrange(self.n_shells)]
        if hasattr(self, "Sigma_imp"):
            Gproj = [
                BlockGf(name_block_generator=[
                    (a, GfImFreq(indices=al, mesh=self.Sigma_imp[0].mesh))
                    for a, al in GFStruct_proj[ish]
                ],
                        make_copies=False) for ish in xrange(self.n_shells)
            ]
            beta = self.Sigma_imp[0].mesh.beta
        else:
            Gproj = [
                BlockGf(name_block_generator=[(a,
                                               GfImFreq(indices=al, beta=beta))
                                              for a, al in GFStruct_proj[ish]],
                        make_copies=False) for ish in xrange(self.n_shells)
            ]

        for ish in xrange(self.n_shells):
            Gproj[ish].zero()

        ikarray = numpy.array(range(self.n_k))
        #print mpi.rank, mpi.slice_array(ikarray)
        #print "K-Sum starts on node",mpi.rank," at ",datetime.now()

        for ik in mpi.slice_array(ikarray):
            #print mpi.rank, ik, datetime.now()
            S = self.lattice_gf_matsubara(ik=ik, mu=mu, beta=beta)
            S *= self.bz_weights[ik]

            for ish in xrange(self.n_shells):
                tmp = Gproj[ish].copy()
                for ir in xrange(self.n_parproj[ish]):
                    for sig, gf in tmp:
                        tmp[sig] <<= self.downfold_pc(ik, ir, ish, sig, S[sig],
                                                      gf)
                    Gproj[ish] += tmp

        #print "K-Sum done on node",mpi.rank," at ",datetime.now()
        #collect data from mpi:
        for ish in xrange(self.n_shells):
            Gproj[ish] <<= mpi.all_reduce(mpi.world, Gproj[ish],
                                          lambda x, y: x + y)
        mpi.barrier()

        #print "Data collected on node",mpi.rank," at ",datetime.now()

        # Symmetrisation:
        if (self.symm_op != 0): Gproj = self.Symm_par.symmetrize(Gproj)
        #print "Symmetrisation done on node",mpi.rank," at ",datetime.now()

        for ish in xrange(self.n_shells):

            # Rotation to local:
            if (self.use_rotations):
                for sig, gf in Gproj[ish]:
                    Gproj[ish][sig] <<= self.rotloc_all(ish,
                                                        gf,
                                                        direction='toLocal')

            isp = 0
            for sig, gf in Gproj[ish]:  #dmg.append(Gproj[ish].density()[sig])
                self.dens_mat_window[isp][ish] = Gproj[ish].density()[sig]
                isp += 1

        # add Density matrices to get the total:
        dens_mat = [[
            self.dens_mat_below[ntoi[bln[isp]]][ish] +
            self.dens_mat_window[isp][ish] for ish in range(self.n_shells)
        ] for isp in range(len(bln))]

        return dens_mat
def cellular_calculation(
        Lx=2,
        Ly=1,
        periodized=False,
        triangular=False,
        Us=[1.0],
        Ts=[0.125],
        ns=[0.5],
        fixed_n=True,
        mutildes=[0.0],
        dispersion=lambda kx, ky: matrix_dispersion(2, -0.25, 0.0, kx, ky),
        ph_symmetry=False,
        dispersion_automatic=True,
        scalar_dispersion=lambda kx, ky: epsilonk_square(kx, ky, -0.25),
        n_ks=[24],
        n_k_automatic=False,
        n_k_rules=[[0.06, 32], [0.03, 48], [0.005, 64], [0.00, 96]],
        w_cutoff=20.0,
        min_its=5,
        max_its=25,
        mix_Sigma=False,
        rules=[[0, 0.5], [6, 0.2], [12, 0.65]],
        do_dmft_first=False,
        use_cthyb=False,
        alpha=0.5,
        delta=0.1,
        n_cycles=100000,
        max_time_rules=[[1, 5 * 60], [2, 20 * 60], [4, 80 * 60], [8, 200 * 60],
                        [16, 400 * 60]],
        time_rules_automatic=False,
        exponent=0.7,
        overall_prefactor=1.0,
        no_timing=False,
        accuracy=1e-4,
        solver_data_package=None,
        print_current=1,
        insulating_initial=False,
        initial_guess_archive_name='',
        suffix='',
        start_from_Gweiss=False):

    if mpi.is_master_node():
        print "WELCOME TO cellular calculation!"
        if n_k_automatic: print "n_k automatic!!!"
    if len(n_ks) == 0 and n_k_automatic: n_ks = [0]

    if use_cthyb:
        solver_class = solvers.cthyb
    else:
        solver_class = solvers.ctint

    fermionic_struct = {'up': [0]}

    Nc = Lx * Ly
    impurity_struct = {'%sx%s' % (Lx, Ly): range(Nc)}

    if not time_rules_automatic:
        max_times = {}
        for C in impurity_struct:
            for r in max_time_rules:
                if r[0] <= len(impurity_struct[C]):
                    max_times[C] = r[1]
        if mpi.is_master_node(): print "max_times from rules: ", max_times

    beta = 1.0 / Ts[0]

    n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0)
    if mpi.is_master_node():
        print "PM HUBBARD GW: n_iw: ", n_iw

    if not n_k_automatic:
        n_k = n_ks[0]
        print "n_k = ", n_k
    else:
        n_k = n_k_from_rules(Ts[0], n_k_rules)
        #if mpi.is_master_node(): print "n_k automatic!!!"

    dt = cellular_data(
        n_iw=n_iw,
        n_k=n_k,
        beta=beta,
        impurity_struct=impurity_struct,
        fermionic_struct=fermionic_struct,
        archive_name="so_far_nothing_you_shouldnt_see_this_file")

    if fixed_n:
        ps = itertools.product(n_ks, ns, Us, Ts)
    else:
        ps = itertools.product(n_ks, mutildes, Us, Ts)

    counter = 0
    old_nk = n_k
    old_beta = beta

    for p in ps:
        #name stuff to avoid confusion
        nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules))
        if fixed_n:
            n = p[1]
        else:
            mutilde = p[1]
            n = None
        U = p[2]
        T = p[3]
        beta = 1.0 / T

        if nk != old_nk and (not n_k_automatic):
            dt.change_ks(IBZ.k_grid(nk))

        if beta != old_beta:
            n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0)
            if n_k_automatic:
                nk = n_k_from_rules(T, n_k_rules)
                if nk != old_nk:
                    dt.change_ks(IBZ.k_grid(nk))
            dt.change_beta(beta, n_iw)

        old_beta = beta
        old_nk = nk

        filename = "result"
        if len(n_ks) > 1 and (not n_k_automatic):
            filename += ".nk%s" % nk
        if len(ns) > 1 and fixed_n:
            filename += ".n%s" % n
        if len(mutildes) > 1 and not fixed_n:
            filename += ".mutilde%s" % mutilde
        if len(Us) > 1: filename += ".U%s" % U
        if len(Ts) > 1: filename += ".T%.4f" % T
        filename += ".h5"
        dt.archive_name = filename

        if mpi.is_master_node():
            if fixed_n:
                print "Working: U: %s T %s n: %s n_k: %s n_iw: %s" % (U, n, T,
                                                                      nk, n_iw)
            else:
                print "Working: U: %s T %s mutilde: %s n_k: %s n_iw: %s" % (
                    U, mutilde, T, nk, n_iw)

        if mpi.is_master_node():
            print "about to fill dispersion. ph-symmetry: ", ph_symmetry
        for key in dt.fermionic_struct.keys():
            for kxi in range(dt.n_k):
                for kyi in range(dt.n_k):
                    dt.epsilonijk[key][:, :, kxi, kyi] = dispersion(
                        dt.ks[kxi], dt.ks[kyi])

        if not triangular:
            prepare_cellular(dt, Lx, Ly, solver_class, periodized)
            identical_pairs = {
                dt.impurity_struct.keys()[0]: get_identical_pair_sets(Lx, Ly)
            }
        else:
            prepare_cellular_triangular(dt, Lx, Ly, solver_class, periodized)
            identical_pairs = {
                dt.impurity_struct.keys()[0]:
                triangular_identical_pair_sets(Lx, Ly)
            }

        solver_class.initialize_solvers(dt, solver_data_package)

        max_times = {}

        if no_timing:
            for C in dt.impurity_struct.keys():
                max_times[C] = -1
            if mpi.is_master_node():
                print "no_timing! solvers will run until they perform all the mc steps", max_times

        if time_rules_automatic and (not no_timing):
            for C in dt.impurity_struct.keys():
                Nc = len(dt.impurity_struct[C])
                pref = ((dt.beta / 8.0) * U * Nc)**exponent  #**1.2
                print C
                print "Nc: ", Nc,
                print "U: ", U,
                print "beta: ", dt.beta,
                print "pref: ", pref
                max_times[C] = int(overall_prefactor * pref * 5 * 60)
            if mpi.is_master_node(): print "max times automatic: ", max_times

        actions = [
            generic_action(
                name="lattice",
                main=lambda data: [
                    data.get_Sigmaijkw(),
                    nested_mains.lattice(data,
                                         n=n,
                                         ph_symmetry=ph_symmetry,
                                         accepted_mu_range=[-2.0, 2.0])
                ],
                mixers=[],
                cautionaries=[],
                allowed_errors=[],
                printout=lambda data, it: ([
                    data.dump_general(quantities=
                                      ['Sigmaijkw', 'Gijkw', 'G_ij_iw'],
                                      suffix='-current'),
                    data.dump_scalar(suffix='-current')
                ] if ((it + 1) % print_current == 0) else None)),
            generic_action(
                name="pre_impurity",
                main=lambda data: nested_mains.pre_impurity(data),
                mixers=[],
                cautionaries=[],
                allowed_errors=[],
                printout=lambda data, it:
                (data.dump_general(quantities=['Gweiss_iw'], suffix='-current')
                 if ((it + 1) % print_current == 0) else None)),
            generic_action(
                name="impurity",
                main=(lambda data: nested_mains.impurity(
                    data,
                    U,
                    symmetrize_quantities=True,
                    alpha=alpha,
                    delta=delta,
                    n_cycles=n_cycles,
                    max_times=max_times,
                    solver_data_package=solver_data_package)) if
                (not use_cthyb) else (lambda data: nested_mains.impurity_cthyb(
                    data,
                    U,
                    symmetrize_quantities=True,
                    n_cycles=n_cycles,
                    max_times=max_times,
                    solver_data_package=solver_data_package)),
                mixers=[],
                cautionaries=[
                    lambda data, it: local_nan_cautionary(data,
                                                          data.impurity_struct,
                                                          Qs=['Sigma_imp_iw'],
                                                          raise_exception=True
                                                          ),
                    lambda data, it: symmetrize_cluster_impurity(
                        data.Sigma_imp_iw, identical_pairs)
                ],
                allowed_errors=[1],
                printout=lambda data, it: ([
                    data.dump_general(quantities=['Sigma_imp_iw', 'G_imp_iw'],
                                      suffix='-current'),
                    data.dump_solvers(suffix='-current')
                ] if ((it + 1) % print_current == 0) else None))
        ]

        monitors = [
            monitor(monitored_quantity=lambda: dt.ns['up'],
                    h5key='n_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.mus['up'],
                    h5key='mu_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.err,
                    h5key='err_vs_it',
                    archive_name=dt.archive_name)
        ]  #,
        #                 monitor( monitored_quantity = lambda: actions[3].errs[0],
        #                          h5key = 'sign_err_vs_it',
        #                          archive_name = dt.archive_name) ]

        convergers = [
            converger(monitored_quantity=lambda: dt.G_ij_iw,
                      accuracy=accuracy,
                      struct=impurity_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_G_loc')
        ]

        convergers.append(
            converger(monitored_quantity=lambda: dt.G_imp_iw,
                      accuracy=accuracy,
                      struct=impurity_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_G_imp'))

        dmft = generic_loop(name="cellular DMFT",
                            actions=actions,
                            convergers=convergers,
                            monitors=monitors)

        if (counter == 0):  #do the initial guess only once!
            if initial_guess_archive_name != '':
                if start_from_Gweiss:
                    dt.mus['up'] = U / 2.0
                    A = HDFArchive(initial_guess_archive_name, "r")
                    dt.Gweiss_iw << A['Gweiss_iw%s' % suffix]
                    del A
                    dt.dump_general(quantities=['Gweiss_iw'],
                                    suffix='-initial')
                else:
                    if mpi.is_master_node():
                        print "constructing dt from initial guess in a file: ", initial_guess_archive_name, "suffix: ", suffix
                    old_epsilonk = dt.epsilonk
                    dt.construct_from_file(initial_guess_archive_name, suffix)
                    if dt.beta != beta:
                        dt.change_beta(beta, n_iw)
                    if dt.n_k != nk:
                        dt.change_ks(IBZ.k_grid(nk))
                    if mpi.is_master_node():
                        print "putting back the old Jq and epsilonk"
                    dt.epsilonk = old_epsilonk
            else:
                if not fixed_n:
                    dt.mus['up'] = U / 2.0 + mutilde
                else:
                    dt.mus['up'] = U / 2.0
                if 'down' in dt.fermionic_struct.keys():
                    dt.mus['down'] = dt.mus[
                        'up']  #this is not necessary at the moment, but may become
                for C in dt.impurity_struct.keys():
                    for l in dt.impurity_struct[
                            C]:  #just the local components (but on each site!)
                        dt.Sigma_imp_iw[C].data[:, l, l] = U / 2.0 - int(
                            insulating_initial) * 1j / numpy.array(dt.ws)
                for key in fermionic_struct.keys():
                    for l in range(dt.Nc):
                        numpy.transpose(
                            dt.Sigmaijkw[key])[:, :, l, l, :] = U / 2.0 - int(
                                insulating_initial) * 1j / numpy.array(dt.ws)
                dt.dump_general(quantities=['Sigmaijkw', 'Sigma_imp_iw'],
                                suffix='-initial')

        if (counter == 0) and do_dmft_first:
            assert False, "not implemented"

        #run cellular!-------------

        if mix_Sigma:
            actions[3].mixers.append(
                mixer(mixed_quantity=lambda: dt.Sigmaijkw,
                      rules=rules,
                      func=mixer.mix_matrix_lattice_gf,
                      initialize=True))

        dt.dump_parameters()
        dt.dump_non_interacting()

        err = dmft.run(dt,
                       max_its=max_its,
                       min_its=min_its,
                       max_it_err_is_allowed=7,
                       print_final=True,
                       print_current=1,
                       start_from_action_index=(2 if start_from_Gweiss else 0))
        if mpi.is_master_node():
            print "periodizing result..."
            print "filling scalar dispersion..."
            for key in dt.fermionic_struct.keys():
                for kxi in range(dt.n_k):
                    for kyi in range(dt.n_k):
                        dt.epsilonk[key][kxi, kyi] = scalar_dispersion(
                            dt.ks[kxi], dt.ks[kyi])
            dt.dump_general(['epsilonk'], suffix='')
            dt.periodize_cumul()
            dt.dump_general(['Gkw', 'Sigmakw', 'gkw', 'gijw', 'g_imp_iw'],
                            suffix='-periodized_cumul')
            dt.periodize_selfenergy()
            dt.dump_general(['Gkw', 'Sigmakw', 'Sigmaijw'],
                            suffix='-periodized_selfenergy')
            cmd = 'mv %s %s' % (filename, filename.replace(
                "result", "cellular"))
            print cmd
            os.system(cmd)

        if (err == 2):
            print "Cautionary error!!! exiting..."
            solver_data_package['construct|run|exit'] = 2
            if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
                solver_data_package = mpi.bcast(solver_data_package)
            break

        if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
        counter += 1
    if not (solver_data_package is None):
        solver_data_package['construct|run|exit'] = 2
    if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
        solver_data_package = mpi.bcast(solver_data_package)
    return dt, monitors, convergers
def supercond_hubbard_calculation( Ts = [0.12,0.08,0.04,0.02,0.01], 
                            mutildes=[0.0, 0.2, 0.4, 0.6, 0.8],
                            ns = [0.5,0.53,0.55,0.57,0.6], fixed_n = False,   
                            ts=[0.25], t_dispersion = epsilonk_square, ph_symmetry = True,
                            Us = [1.0,2.0,3.0,4.0], alpha=2.0/3.0, ising = False,
                            hs = [0],  
                            frozen_boson = False, 
                            refresh_X = True, strength = 5.0, max_it = 10,
                            n_ks = [24], n_k_automatic = False, n_k_rules = [[0.06, 32],[0.03, 48],[0.005, 64],[0.00, 96]],
                            w_cutoff = 20.0,
                            n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], mix_Sigma = True,
                            trilex = False, edmft = False, local_bubble_for_charge_P = False,charge_boson_GW_style = False, imtime = True, use_optimized = True, N_cores = 1, 
                            do_dmft_first = True, do_normal = True, do_eigenvalue = False, do_superconducting = False, initial_X_prefactor = 2.0,
                            use_cthyb=True, n_cycles=100000, max_time=10*60, accuracy = 1e-4, supercond_accr = 1e-8, solver_data_package = None,
                            print_local_frequency=5, print_non_local_frequency = 5, total_debug=False,
                            initial_guess_archive_name = '', suffix='', clean_up_polarization = True):
  if mpi.is_master_node():
     print "WELCOME TO supercond hubbard calculation!"
     if n_k_automatic: print "n_k automatic!!!"
  if len(n_ks)==0 and n_k_automatic: n_ks=[0]

  loc_from_imp = trilex or edmft    

  bosonic_struct = {'0': [0], '1': [0]}    
  if not ising:
    if alpha==2.0/3.0:
      del bosonic_struct['1']
    if alpha==1.0/3.0:
      del bosonic_struct['0']
  else:
    if alpha==1.0:
      del vks['1']
    if alpha==0.0:
      del vks['0']

  fermionic_struct = {'up': [0], 'down': [0]}
  if not loc_from_imp:
    del fermionic_struct['down']
  beta = 1.0/Ts[0] 
  
  n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0)
  if mpi.is_master_node():
    print "PM HUBBARD GW: n_iw: ",n_iw
  n_tau = int(n_iw*pi)


  if not n_k_automatic:
    n_q = n_ks[0]
    n_k = n_q
  else:
    n_k = n_q = n_k_from_rules(Ts[0], n_k_rules)
    if mpi.is_master_node(): print "n_k automatic!!!"

  #init solver
  if use_cthyb and loc_from_imp:
    if solver_data_package is None: solver_data_package = {}
    solver_data_package['solver'] = 'cthyb'
    solver_data_package['constructor_parameters']={}
    solver_data_package['constructor_parameters']['beta'] = beta
    solver_data_package['constructor_parameters']['gf_struct'] = fermionic_struct
    solver_data_package['constructor_parameters']['n_tau_k'] = n_tau
    solver_data_package['constructor_parameters']['n_tau_g'] = 10000
    solver_data_package['constructor_parameters']['n_tau_delta'] = 10000
    solver_data_package['constructor_parameters']['n_tau_nn'] = 4*n_tau
    solver_data_package['constructor_parameters']['n_w_b_nn'] = n_iw
    solver_data_package['constructor_parameters']['n_w'] = n_iw
    solver_data_package['construct|run|exit'] = 0

    if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package)
     
    solver = Solver( **solver_data_package['constructor_parameters'] )
  else:
    solver = None


  assert not( imtime and trilex ), "imtime bubbles inapplicable in trilex"
  #init data, assign the solver to it
  dt = supercond_data( n_iw = n_iw, 
                       ntau = (None if (imtime) else 3 ), #no need to waste memory on tau-dependent quantities unless we're going to use them (None means ntau=n_iw*5)
                       n_k = n_k,
                       n_q = n_q, 
                       beta = beta, 
                       solver = solver,
                       bosonic_struct = bosonic_struct,
                       fermionic_struct = fermionic_struct,
                       archive_name="so_far_nothing_you_shouldnt_see_this_file" )
  if trilex or (edmft and local_bubble_for_charge_P and not charge_boson_GW_style): #if emdft, nothing to add
    dt.__class__=supercond_trilex_data
    dt.promote(dt.n_iw/2, dt.n_iw/2)

  if use_optimized:
    dt.patch_optimized()

  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = lambda: dt.P_loc_iw,
                            accuracy=accuracy, 
                            struct=bosonic_struct, 
                            archive_name="not_yet_you_shouldnt_see_this_file",
                            h5key = 'diffs_P_loc' ),
                 converger( monitored_quantity = lambda: dt.G_loc_iw,
                            accuracy=accuracy, 
                            struct=fermionic_struct, 
                            archive_name="not_yet_you_shouldnt_see_this_file",
                            h5key = 'diffs_G_loc'     ) ]

  #initial guess
  
  #assert not(trilex and fixed_n), "trilex doesn't yet work"

  if fixed_n:
    ps = itertools.product(n_ks,ts,ns,Us,Ts,hs)
  else:
    ps = itertools.product(n_ks,ts,mutildes,Us,Ts,hs)

  counter = 0
  old_nk = n_k
  old_beta = beta

  old_get_Xkw = None
  #-------------------------------------------------------------------------------------------------------------------------------#
  for p in ps:    
    #name stuff to avoid confusion   
    t = p[1]
    if fixed_n:
      n = p[2]
    else:
      mutilde = p[2]
      n = None
    U = p[3]
    T = p[4] 
    beta = 1.0/T
    h = p[5]

    nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules) )

    if nk!=old_nk and (not n_k_automatic):
      dt.change_ks(IBZ.k_grid(nk))
      old_nk = nk

    if beta!=old_beta:
      n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0)
      n_tau = int(n_iw*pi)

      if n_k_automatic:
        nk = n_k_from_rules(T, n_k_rules)
        if nk != old_nk: 
          dt.change_ks(IBZ.k_grid(nk))
          old_nk = nk

      dt.change_beta(beta, n_iw)

      if loc_from_imp:
        if solver_data_package is None: solver_data_package = {}
        solver_data_package['constructor_parameters']={}
        solver_data_package['constructor_parameters']['beta'] = beta
        solver_data_package['constructor_parameters']['gf_struct'] = fermionic_struct
        solver_data_package['constructor_parameters']['n_tau_k'] = n_tau
        solver_data_package['constructor_parameters']['n_tau_g'] = 10000
        solver_data_package['constructor_parameters']['n_tau_delta'] = 10000
        solver_data_package['constructor_parameters']['n_tau_nn'] = 4*n_tau
        solver_data_package['constructor_parameters']['n_w_b_nn'] = n_iw
        solver_data_package['constructor_parameters']['n_w'] = n_iw
        solver_data_package['construct|run|exit'] = 0

        if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package)
        dt.solver = Solver( **solver_data_package['constructor_parameters'] )
      old_beta = beta

    filename = "result"
    if len(n_ks)>1 and (not n_k_automatic):
      filename += ".nk%s"%nk
    if len(ts)>1: filename += ".t%s"%t
    if len(ns)>1 and fixed_n: 
      filename += ".n%s"%n
    if len(mutildes)>1 and not fixed_n:
      filename += ".mutilde%s"%mutilde      
    if len(Us)>1: filename += ".U%s"%U
    if len(Ts)>1: filename += ".T%.4f"%T
    if len(hs)>1: filename += ".h%s"%h
    filename += ".h5"
    dt.archive_name = filename
    for conv in convergers:
      conv.archive_name = dt.archive_name

    if not ising:
      Uch = (3.0*alpha-1.0)*U
      Usp = (alpha-2.0/3.0)*U
    else:
      Uch = alpha*U
      Usp = (alpha-1.0)*U

    vks = {'0': lambda kx,ky: Uch, '1': lambda kx,ky: Usp}
    if not ising:
      if alpha==2.0/3.0:
        del vks['1']
      if alpha==1.0/3.0:
        del vks['0']
    else:
      if alpha==1.0:
        del vks['1']
      if alpha==0.0:
        del vks['0']
    
    dt.fill_in_Jq( vks )  
    dt.fill_in_epsilonk(dict.fromkeys(fermionic_struct.keys(), partial(t_dispersion, t=t)))

    #assert not(use_optimized and trilex), "don't have optimized freq summation from trilex"
    if trilex and charge_boson_GW_style:
      dt.Lambda_wrapper = lambda A,wi,nui: ( (dt.__class__.Lambda_wrapper(dt,A,wi,nui)) if (A=='1') else 1.0 )

    Lam = ( dt.Lambda_wrapper if trilex else ( lambda A, wi, nui: 1.0 )  )
    if (not use_optimized) or (not imtime): #automatically if trilex because imtime = False is asserted
      dt.get_Sigmakw = lambda: dt.__class__.get_Sigmakw(dt, ising_decoupling = ising, imtime = imtime, Lambda = Lam)
      dt.get_Xkw = lambda: dt.__class__.get_Xkw(dt, ising_decoupling = ising, imtime = imtime, Lambda = Lam) 
      dt.get_Pqnu = lambda: dt.__class__.get_Pqnu(dt, imtime = imtime, Lambda = Lam) 
    else:
      dt.get_Sigmakw =  lambda: GW_data.optimized_get_Sigmakw(dt, ising_decoupling = ising, N_cores=N_cores)
      dt.get_Xkw =  lambda: supercond_data.optimized_get_Xkw(dt, ising_decoupling = ising, N_cores=N_cores) 
      dt.get_Pqnu =  lambda: supercond_data.optimized_get_Pqnu(dt, N_cores=N_cores) 



    dt.get_Sigma_loc_from_local_bubble = lambda: GW_data.get_Sigma_loc_from_local_bubble(dt, ising_decoupling = ising, imtime = imtime, Lambda = Lam)   
    if  local_bubble_for_charge_P:
      dt.get_P_loc_from_local_bubble = lambda: GW_data.get_P_loc_from_local_bubble(dt, imtime = False, Lambda = dt.Lambda_wrapper)
    if charge_boson_GW_style:
      dt.get_P_loc_from_local_bubble = lambda: GW_data.get_P_loc_from_local_bubble(dt, imtime = imtime, Lambda = lambda A,wi,nui: 1.0)

    dt.optimized_get_P_imp = lambda: GW_data.optimized_get_P_imp(dt, use_caution=not local_bubble_for_charge_P and not charge_boson_GW_style, prefactor=0.99, 
                                                                     use_local_bubble_for_charge = local_bubble_for_charge_P or charge_boson_GW_style )
    #dt.optimized_get_P_imp = lambda: GW_data.optimized_get_P_imp(dt, use_caution=False, prefactor=0.99, use_local_bubble_for_charge = local_bubble_for_charge_P)
    if not loc_from_imp:
      dt.get_P_loc_from_local_bubble = lambda: dt.__class__.get_P_loc_from_local_bubble(dt, imtime = imtime, Lambda = Lam)

    if ((h==0.0)or(h==0))and (not refresh_X):
      if mpi.is_master_node(): print "assigning GW_data.Pqnu because no h, no imposed X"
      old_get_Xkw = dt.get_Xkw #save the old one and put it back before returning data   
      old_get_Pqnu = dt.get_Pqnu
      dt.get_Xkw = lambda: None
      if (not use_optimized) or (not imtime):
        dt.get_Pqnu = lambda: GW_data.get_Pqnu(dt, imtime = imtime, Lambda = Lam) 
      else: 
        dt.get_Pqnu = lambda: GW_data.optimized_get_Pqnu(dt, N_cores=N_cores) 

    if trilex or (edmft and local_bubble_for_charge_P and not charge_boson_GW_style): 
      preset = supercond_trilex_hubbard(U=U, alpha=alpha, ising = ising, frozen_boson=(frozen_boson if (T!=Ts[0]) else False), refresh_X = refresh_X, n = n, ph_symmetry = ph_symmetry)
    elif edmft:
      preset = supercond_EDMFTGW_hubbard(U=U, alpha=alpha, ising = ising, frozen_boson=(frozen_boson if (T!=Ts[0]) else False), refresh_X = refresh_X, n = n, ph_symmetry = ph_symmetry)
    else:
      preset = supercond_hubbard(frozen_boson=(frozen_boson if (T!=Ts[0]) else False), refresh_X=refresh_X, n = n, ph_symmetry=ph_symmetry)

    if refresh_X:
      preset.cautionary.refresh_X = partial(preset.cautionary.refresh_X, strength=strength, max_it=max_it)

    if mpi.is_master_node():
      if fixed_n:
        print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," n= ",n
      else:
        print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," mutilde= ",mutilde
      #print "cautionary safe values: ",preset.cautionary.safe_value    

    if loc_from_imp:
      if trilex or (local_bubble_for_charge_P and not charge_boson_GW_style):
        n_w_f=dt.n_iw_f
        n_w_b=dt.n_iw_b
      else:
        n_w_f=4
        n_w_b=4

      if use_cthyb:
        impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, 
                                           trilex=trilex or (local_bubble_for_charge_P and not charge_boson_GW_style), n_w_f=n_w_f, n_w_b=n_w_b,
                                           n_cycles=n_cycles, max_time=max_time,
                                           solver_data_package = solver_data_package )
        dt.dump_solver = partial(solvers.cthyb.dump, solver = dt.solver, archive_name = dt.archive_name)
      else:
        impurity = partial( solvers.ctint.run, n_cycles=n_cycles)
        dt.dump_solver = partial(solvers.cthyb.dump, solver = dt.solver, archive_name = dt.archive_name)
    else:
      impurity = lambda data: None

    mixers = [mixer( mixed_quantity = lambda: dt.Pqnu,
                      rules=rules,
                      func=mixer.mix_lattice_gf ),
              mixer( mixed_quantity = lambda: dt.P_loc_iw,
                     rules=rules,
                     func=mixer.mix_block_gf ) ]
    if mix_Sigma:
      mixers.extend([mixer( mixed_quantity = lambda: dt.Sigmakw,
                     rules=rules,
                     func=mixer.mix_lattice_gf),
                     mixer( mixed_quantity = lambda: dt.Sigma_loc_iw,
                     rules=rules,
                     func=mixer.mix_block_gf)])

    monitors = [ monitor( monitored_quantity = lambda: dt.ns['up'], 
                          h5key = 'n_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.mus['up'], 
                          h5key = 'mu_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: numpy.amax(dt.Pqnu['1'][dt.m_to_nui(0),:,:]*Usp), 
                          h5key = 'maxPspUsp_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.err, 
                          h5key = 'err_vs_it', 
                          archive_name = dt.archive_name) ]

    if loc_from_imp:
      monitors.extend([ monitor( monitored_quantity = lambda: dt.P_imp_iw['0'].data[dt.m_to_nui(0),0,0], 
                                 h5key = 'Pimp_vs_it', 
                                 archive_name = dt.archive_name), 
                        monitor( monitored_quantity = lambda: dt.W_loc_iw['0'].data[dt.m_to_nui(0),0,0], 
                                 h5key = 'Wloc_vs_it', 
                                 archive_name = dt.archive_name),
                        monitor( monitored_quantity = lambda: dt.Uweiss_iw['0'].data[dt.m_to_nui(0),0,0], 
                                 h5key = 'Uweiss_vs_it', 
                                 archive_name = dt.archive_name),
                        monitor( monitored_quantity = lambda: dt.chi_imp_iw['0'].data[dt.m_to_nui(0),0,0], 
                                 h5key = 'chimp_vs_it',
                                archive_name = dt.archive_name) ])
      #mixers.extend([ mixer( mixed_quantity = lambda: dt.chi_imp_iw['0'],
      #                  rules=[[0,0.9]],
      #                  func=mixer.mix_gf) ] )
 
    #init the dmft_loop 
    dmft = dmft_loop(  cautionary       = preset.cautionary, 
                       lattice          = preset.lattice,
                       pre_impurity     = preset.pre_impurity, 
                       impurity         = impurity, 
                       post_impurity    = preset.post_impurity,
                       selfenergy       = preset.selfenergy, 
                       convergers       = convergers,
                       mixers           = mixers,
                       monitors		= monitors, 
                       after_it_is_done = preset.after_it_is_done )

    #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) )  
    #if (T==Ts[0]) and trilex: #do this only once!         
    #  dt.mus['up'] = dt.mus['down'] = mutilde+U/2.0
    #  dt.P_imp_iw << 0.0    
    #  dt.Sigma_imp_iw << U/2.0 + mutilde #making sure that in the first iteration the impurity problem is half-filled. if not solving impurity problem, not needed
    #  for U in fermionic_struct.keys(): dt.Sigmakw[U].fill(0)
    #  for U in fermionic_struct.keys(): dt.Xkw[U].fill(0)
    if (T==Ts[0]): #do the initial guess only once!         
      if initial_guess_archive_name!='':
        if mpi.is_master_node(): print "constructing dt from initial guess in a file: ",initial_guess_archive_name, "suffix: ",suffix
        old_Jq = dt.Jq #this thing is the parameter of the calculation, we don't want to load it from the initial guess file
        old_epsilonk = dt.epsilonk
        dt.construct_from_file(initial_guess_archive_name, suffix) 
        if dt.beta != beta:
          dt.change_beta(beta, n_iw)
        if dt.n_k != nk:
          dt.change_ks(IBZ.k_grid(nk))
        if mpi.is_master_node(): print "putting back the old Jq and epsilonk"
        dt.epsilonk = old_epsilonk
        dt.Jq = old_Jq 
        if clean_up_polarization:
          if mpi.is_master_node(): print "now emptying polarization to be sure"
          for A in dt.bosonic_struct.keys(): #empty the Polarization!!!!!!!!!!!!
            dt.Pqnu[A][:,:,:] = 0.0
            dt.P_loc_iw[A] << 0.0
            dt.chi_imp_iw[A] << 0.0
      else:
        if not fixed_n:  
          dt.mus['up'] = mutilde
        else:
  	  dt.mus['up'] = 0.0
        if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus['up']   #this is not necessary at the moment, but may become
        dt.P_imp_iw << 0.0    
        if loc_from_imp: #making sure that in the first iteration the impurity problem is half-filled. if not solving impurity problem, not needed
 	  dt.Sigma_loc_iw << U/2.0
        else:
	  dt.Sigma_loc_iw << 0.0  
        for U in fermionic_struct.keys(): dt.Sigmakw[U].fill(0)
        for U in fermionic_struct.keys(): dt.Xkw[U].fill(0)
      #note that below from here U is no longer U because of the above for loops     

    if not do_superconducting:
      for U in fermionic_struct.keys(): dt.Xkw[U].fill(0)
 
    if loc_from_imp and (T==Ts[0]) and do_dmft_first:
      #do one short run of dmft before starting emdft+gw
      if mpi.is_master_node(): print "================= 20 iterations of DMFT!!!! ================="
      Jqcopy = deepcopy(dt.Jq) #copy the old Jq
      for A in dt.bosonic_struct.keys():
        dt.Jq[A][:,:] = 0.0 #setting bare bosonic propagators to zero reduces the calculation to dmft.      

      #but we also don't want to do the calculation of Sigmakw and Pqnu 
      get_Sigmakw = dt.get_Sigmakw
      get_Pqnu = dt.get_Pqnu
      get_Xkw = dt.get_Xkw       
 
      def copy_Sigma_loc_to_Sigmakw():
        if mpi.is_master_node(): print ">>>>> just copying Sigma_loc to Sigma_kw" 
        for U in dt.fermionic_struct.keys():
          numpy.transpose(dt.Sigmakw[U])[:] = dt.Sigma_loc_iw[U].data[:,0,0]
     
      dt.get_Sigmakw = copy_Sigma_loc_to_Sigmakw
      dt.get_Pqnu = lambda: None
      dt.get_Xkw = lambda: None

      if trilex: #get rid of vertex related stuff
        get_chi3_imp = dt.get_chi3_imp
        get_chi3tilde_imp = dt.get_chi3tilde_imp
        get_Lambda_imp = dt.get_Lambda_imp

        dt.get_chi3_imp = lambda: None
        dt.get_chi3tilde_imp = lambda: None
        dt.get_Lambda_imp = lambda: None
        old_impurity = dmft.impurity
        dmft.impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, 
                                           trilex=False, n_w_f=n_w_f, n_w_b=n_w_b,
                                           n_cycles=n_cycles, max_time=( max_time if (not trilex) else (max_time/2)), 
                                           solver_data_package = solver_data_package )
      
      dmft.mixers = [] # no mixing
      dmft.cautionary = None # nothing to be cautious about 
       
      # DO THE CALC   
      dmft.run( dt, calculation_name = 'dmft', total_debug = total_debug,
                n_loops_max=20, 
                n_loops_min=15,
                print_local=1, print_impurity_input=1, print_three_leg=100000, print_non_local=10000, print_impurity_output=1,
                skip_self_energy_on_first_iteration=True,
                mix_after_selfenergy = True, 
                last_iteration_err_is_allowed = 100 )
      #move the result
      if mpi.is_master_node():
        cmd = 'mv %s %s'%(filename, filename.replace("result", "dmft")) 
        print cmd
        os.system(cmd)
      # put everything back to normal
      dmft.mixers = mixers
      dmft.cautionary = preset.cautionary

      dt.Jq = Jqcopy #put back the old Jq now for the actual calculation
      for A in dt.bosonic_struct.keys(): #empty the Polarization!!!!!!!!!!!!
        dt.Pqnu[A][:,:,:] = 0.0
        dt.P_loc_iw[A] << 0.0
        dt.chi_imp_iw[A] << 0.0
      dt.get_Sigmakw = get_Sigmakw 
      dt.get_Pqnu = get_Pqnu 
      dt.get_Xkw = get_Xkw       
      if trilex: #put back in the vertex related stuff
        dt.get_chi3_imp = get_chi3_imp
        dt.get_chi3tilde_imp = get_chi3tilde_imp
        dt.get_Lambda_imp = get_Lambda_imp
        dmft.impurity = old_impurity     

    if refresh_X:  
      preset.cautionary.reset()
      preset.cautionary.refresh_X(dt)

    if h!=0:
      for kxi in range(dt.n_k):
        for kyi in range(dt.n_k):
          for wi in range(dt.nw):
            for U in fermionic_struct.keys():
              dt.hsck[U][kxi, kyi] = X_dwave(dt.ks[kxi],dt.ks[kyi], h)
   
    if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
    #run dmft!-------------
    if do_normal and not (do_superconducting and T!=Ts[0]):
      err = dmft.run( dt,  calculation_name = 'normal', total_debug = total_debug,
                      n_loops_max=n_loops_max, 
                      n_loops_min=n_loops_min,
                      print_local=print_local_frequency, print_impurity_input=( 1 if loc_from_imp else 1000 ), print_three_leg=1, print_non_local=print_non_local_frequency,
                      skip_self_energy_on_first_iteration=True,
                      mix_after_selfenergy = True, 
                      last_iteration_err_is_allowed = n_loops_max+5 ) #n_loops_max/2 )
      if (err==2): 
        print "Cautionary error!!! exiting..."
        solver_data_package['construct|run|exit'] = 2
        if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package)
        break

    if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
    if do_eigenvalue:
      #get the leading eigenvalue and the corresponding eigenvector to be used as the initial guess for Xkw
      if imtime and use_optimized:
        dt.optimized_get_leading_eigenvalue(max_it = 60, accr = 5e-4, 
                                          ising_decoupling = ising, 
                                          N_cores = N_cores, symmetry = 'd')  #for now let's stick to plain d-wave
      else:
        dt.get_Xkw = lambda: supercond_data.get_Xkw( dt, imtime = False, 
                                            simple = False, 
                                            use_IBZ_symmetry = False,
                                            ising_decoupling=ising,
                                            su2_symmetry=True, wi_list = [], Lambda = dt.Lambda_wrapper)

        dt.get_leading_eigenvalue(max_it = 60, accr = 5e-4, 
                                          ising_decoupling = ising, symmetry = 'd')  #for now let's stick to plain d-wave
      if mpi.is_master_node():
        if dt.eig_ratio < 1.0:
          print ">>>>>>>>>>> eig_ratio<1.0... better luck next time"
        else: 
          print ">>>>>>>>>>> eig_ratio>=1.0!!"
        dt.dump_all(suffix='-final') 
        cmd = 'mv %s %s'%(filename, filename.replace("result", "result_normal")) 
        print cmd
        os.system(cmd)

    if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
    if do_superconducting and (dt.eig_ratio >= 1.0):          
      if mpi.is_master_node(): print "--------------------------------- will now do superconducting calculation!!! ------------------------------"
      # start from a small gap
      for U in dt.fermionic_struct.keys():
        dt.Xkw[U] *= initial_X_prefactor

      #put back in the supercond functions for Sigma and P 
      dt.get_Xkw = old_get_Xkw
      dt.get_Pqnu = old_get_Pqnu 

      monitors.extend( [ monitor( monitored_quantity = lambda: dt.Xkw['up'][dt.nw/2,0,dt.n_k/2].real, 
                          h5key = 'Xkw_vs_it', 
                          archive_name = dt.archive_name),
                         monitor( monitored_quantity = lambda: numpy.amax(dt.Fkw['up'][:,:,:].real), 
                          h5key = 'Fkw_vs_it', 
                          archive_name = dt.archive_name) ]   )

      for conv in convergers:
        conv.accuracy = supercond_accr
      #run the calculation again
      err = dmft.run( dt, calculation_name = 'supercond', total_debug = total_debug,
                    n_loops_max=100, 
                    n_loops_min=25,
                    print_local=print_local_frequency, print_impurity_input=( 1 if loc_from_imp else 1000 ), print_three_leg=1, print_non_local=5,
                    skip_self_energy_on_first_iteration=True,
                    mix_after_selfenergy = True, 
                    last_iteration_err_is_allowed = n_loops_max+5 ) #n_loops_max/2 )

    elif do_superconducting:
      if mpi.is_master_node(): print "--------------------------------- no point in doing superconducting calculation: eig_ratio<1"
    counter += 1
  if not (old_get_Xkw is None):
    dt.get_Xkw  = old_get_Xkw #putting back the function for later use
  solver_data_package['construct|run|exit'] = 2
  if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package)
  return dt, monitors, convergers
def dca_calculation(dca_scheme,
                    ph_symmetry=False,
                    Us=[1.0],
                    Ts=[0.125],
                    ns=[0.5],
                    fixed_n=True,
                    mutildes=[0.0],
                    w_cutoff=20.0,
                    min_its=5,
                    max_its=25,
                    mix_Sigma=False,
                    rules=[[0, 0.5], [6, 0.2], [12, 0.65]],
                    do_dmft_first=False,
                    alpha=0.5,
                    delta=0.1,
                    automatic_alpha_and_delta=False,
                    n_cycles=10000000,
                    max_time_rules=[[1, 5 * 60], [2, 20 * 60], [4, 80 * 60],
                                    [8, 200 * 60], [16, 400 * 60]],
                    time_rules_automatic=False,
                    exponent=0.7,
                    overall_prefactor=1.0,
                    no_timing=False,
                    accuracy=1e-4,
                    solver_data_package=None,
                    print_current=1,
                    initial_guess_archive_name='',
                    suffix=''):

    if mpi.is_master_node():
        print "WELCOME TO dca calculation!"

    solver_class = solvers.ctint

    impurity_struct = dca_scheme.get_impurity_struct()
    fermionic_struct = dca_scheme.get_fermionic_struct()

    if mpi.is_master_node(): print "impurity_struct: ", impurity_struct
    if mpi.is_master_node(): print "fermionic_struct: ", fermionic_struct

    if not time_rules_automatic:
        max_times = {}
        for C in impurity_struct:
            for r in max_time_rules:
                if r[0] <= len(impurity_struct[C]):
                    max_times[C] = r[1]
        if mpi.is_master_node(): print "max_times from rules: ", max_times

    beta = 1.0 / Ts[0]

    n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0)
    if mpi.is_master_node():
        print "PM HUBBARD GW: n_iw: ", n_iw

    dt = dca_data(n_iw=n_iw,
                  beta=beta,
                  impurity_struct=impurity_struct,
                  fermionic_struct=fermionic_struct,
                  archive_name="so_far_nothing_you_shouldnt_see_this_file")

    if fixed_n:
        ps = itertools.product(ns, Us, Ts)
    else:
        ps = itertools.product(mutildes, Us, Ts)

    counter = 0
    old_beta = beta
    for p in ps:
        #name stuff to avoid confusion
        if fixed_n:
            n = p[0]
        else:
            mutilde = p[0]
            n = None
        U = p[1]
        T = p[2]
        beta = 1.0 / T

        if beta != old_beta:
            n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0)
            dt.change_beta(beta, n_iw)

        old_beta = beta

        filename = "result"
        if len(ns) > 1 and fixed_n:
            filename += ".n%s" % n
        if len(mutildes) > 1 and not fixed_n:
            filename += ".mutilde%s" % mutilde
        if len(Us) > 1: filename += ".U%s" % U
        if len(Ts) > 1: filename += ".T%.4f" % T
        filename += ".h5"
        dt.archive_name = filename

        if mpi.is_master_node():
            if fixed_n:
                print "Working: U: %s T %s n: %s " % (U, T, n)
            else:
                print "Working: U: %s T %s mutilde: %s " % (U, T, mutilde)

        prepare_dca(dt, dca_scheme, solver_class)

        solver_class.initialize_solvers(dt, solver_data_package)

        if no_timing:
            for C in dt.impurity_struct.keys():
                max_times[C] = -1
            if mpi.is_master_node():
                print "no_timing! solvers will run until they perform all the mc steps", max_times

        if time_rules_automatic and (not no_timing):
            max_times = {}
            for C in dt.impurity_struct.keys():
                Nc = len(dt.impurity_struct[C])
                pref = ((dt.beta / 8.0) * U * Nc)**exponent  #**1.2
                print C
                print "Nc: ", Nc,
                print "U: ", U,
                print "beta: ", dt.beta,
                print "pref: ", pref
                max_times[C] = int(overall_prefactor * pref * 5 * 60)
            if mpi.is_master_node(): print "max times automatic: ", max_times

        identical_pairs = dca_scheme.get_identical_pairs()
        if not (identical_pairs is None):
            print "identical pairs not known, there will be no symmetrization"
            identical_pairs = {'x': identical_pairs}

        actions = [
            generic_action(name="lattice",
                           main=lambda data: nested_mains.lattice(
                               data,
                               n=n,
                               ph_symmetry=ph_symmetry,
                               accepted_mu_range=[-2.0, 2.0]),
                           mixers=[],
                           cautionaries=[],
                           allowed_errors=[],
                           printout=lambda data, it: ([
                               data.dump_general(quantities=['GK_iw', 'GR_iw'],
                                                 suffix='-current'),
                               data.dump_scalar(suffix='-current')
                           ] if ((it + 1) % print_current == 0) else None)),
            generic_action(
                name="pre_impurity",
                main=lambda data: nested_mains.pre_impurity(data),
                mixers=[],
                cautionaries=[],
                allowed_errors=[],
                printout=lambda data, it: (data.dump_general(
                    quantities=['GweissK_iw', 'GweissR_iw', 'Gweiss_iw'],
                    suffix='-current') if (
                        (it + 1) % print_current == 0) else None)),
            generic_action(
                name="impurity",
                main=(lambda data: nested_mains.impurity(
                    data,
                    U,
                    symmetrize_quantities=True,
                    alpha=alpha,
                    delta=delta,
                    automatic_alpha_and_delta=automatic_alpha_and_delta,
                    n_cycles=n_cycles,
                    max_times=max_times,
                    solver_data_package=solver_data_package)),
                mixers=[],
                cautionaries=[
                    lambda data, it: local_nan_cautionary(data,
                                                          data.impurity_struct,
                                                          Qs=['Sigma_imp_iw'],
                                                          raise_exception=True
                                                          ), lambda data, it:
                    (symmetric_G_and_self_energy_on_impurity(
                        data.G_imp_iw, data.Sigma_imp_iw, data.solvers,
                        identical_pairs, identical_pairs)
                     if it >= 100 else symmetrize_cluster_impurity(
                         data.Sigma_imp_iw, identical_pairs))
                ],
                allowed_errors=[1],
                printout=lambda data, it: ([
                    data.dump_general(quantities=['Sigma_imp_iw', 'G_imp_iw'],
                                      suffix='-current'),
                    data.dump_solvers(suffix='-current')
                ] if ((it + 1) % print_current == 0) else None)),
            generic_action(
                name="selfenergy",
                main=lambda data: dca_mains.selfenergy(data),
                mixers=[],
                cautionaries=[],
                allowed_errors=[],
                printout=lambda data, it:
                (data.dump_general(quantities=['SigmaR_iw', 'SigmaK_iw'],
                                   suffix='-current')
                 if ((it + 1) % print_current == 0) else None))
        ]

        if mix_Sigma:
            actions[3].mixers.append(
                mixer(mixed_quantity=lambda: dt.SigmaK_iw,
                      rules=rules,
                      func=mixer.mix_block_gf,
                      initialize=True))

        monitors = [
            monitor(monitored_quantity=lambda: dt.ns['00'],
                    h5key='n_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.mus['00'],
                    h5key='mu_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.SigmaR_iw['00'].data[
                dt.nw / 2, 0, 0].imag,
                    h5key='ImSigma00_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.SigmaR_iw['00'].data[
                dt.nw / 2, 0, 0].real,
                    h5key='ReSigma00_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.GR_iw['00'].data[dt.nw / 2,
                                                                   0, 0].imag,
                    h5key='ImG00_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.GR_iw['00'].data[dt.nw / 2,
                                                                   0, 0].real,
                    h5key='ReG00_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.err,
                    h5key='err_vs_it',
                    archive_name=dt.archive_name)
        ]  #,
        #                 monitor( monitored_quantity = lambda: actions[3].errs[0],
        #                          h5key = 'sign_err_vs_it',
        #                          archive_name = dt.archive_name) ]

        convergers = [
            converger(monitored_quantity=lambda: dt.GR_iw,
                      accuracy=accuracy,
                      struct=fermionic_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_GR'),
            converger(monitored_quantity=lambda: dt.SigmaR_iw,
                      accuracy=accuracy,
                      struct=fermionic_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_SigmaR')
        ]

        dmft = generic_loop(name="DCA",
                            actions=actions,
                            convergers=convergers,
                            monitors=monitors)

        if (counter == 0):  #do the initial guess only once!
            if initial_guess_archive_name != '':
                if mpi.is_master_node():
                    print "constructing dt from initial guess in a file: ", initial_guess_archive_name, "suffix: ", suffix
                dt.construct_from_file(
                    initial_guess_archive_name,
                    suffix)  #make sure it is the right dca_scheme
                if dt.beta != beta:
                    dt.change_beta(beta, n_iw)
            else:
                if not fixed_n:
                    dt.set_mu(mutilde)
                else:
                    dt.set_mu(U / 2.0)
                for C in dt.impurity_struct.keys():
                    for l in dt.impurity_struct[
                            C]:  #just the local components (but on each site!)
                        dt.Sigma_imp_iw[C][l, l] << U / 2.0
                for K, sig in dt.SigmaK_iw:
                    sig[0, 0] << U / 2.0
            dt.dump_general(quantities=['SigmaK_iw', 'Sigma_imp_iw'],
                            suffix='-initial')

        if (counter == 0) and do_dmft_first:
            assert False, "not implemented"

        #run dca!-------------
        dt.dump_parameters()
        dt.dump_non_interacting()

        err = dmft.run(dt,
                       max_its=max_its,
                       min_its=min_its,
                       max_it_err_is_allowed=7,
                       print_final=True,
                       print_current=1)
        if mpi.is_master_node():
            cmd = 'mv %s %s' % (filename, filename.replace("result", "dca"))
            print cmd
            os.system(cmd)

        if (err == 2):
            print "Cautionary error!!! exiting..."
            solver_data_package['construct|run|exit'] = 2
            if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
                solver_data_package = mpi.bcast(solver_data_package)

            break

        if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
        counter += 1
    if not (solver_data_package is None):
        solver_data_package['construct|run|exit'] = 2
    if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
        solver_data_package = mpi.bcast(solver_data_package)

    return dt, monitors, convergers
    def dos_partial(self,broadening=0.01):
        """calculates the orbitally-resolved DOS"""

        assert hasattr(self,"Sigma_imp"), "Set Sigma First!!"

        #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all']
        #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data, thingstoread=thingstoread)
        retval = self.read_par_proj_input_from_hdf()
        if not retval: return retval
        if self.symm_op: self.Symm_par = Symmetry(self.hdf_file,subgroup=self.symm_par_data)

        mu = self.chemical_potential

        gf_struct_proj = [ [ (al, range(self.shells[i][3])) for al in self.block_names[self.SO] ]  for i in xrange(self.n_shells) ]
        Gproj = [BlockGf(name_block_generator = [ (a,GfReFreq(indices = al, mesh = self.Sigma_imp[0].mesh)) for a,al in gf_struct_proj[ish] ], make_copies = False ) 
                 for ish in xrange(self.n_shells)]
        for ish in range(self.n_shells): Gproj[ish].zero()

        Msh = [x for x in self.Sigma_imp[0].mesh]
        n_om = len(Msh)

        DOS = {}
        for bn in self.block_names[self.SO]:
            DOS[bn] = numpy.zeros([n_om],numpy.float_)

        DOSproj     = [ {} for ish in range(self.n_shells) ]
        DOSproj_orb = [ {} for ish in range(self.n_shells) ]
        for ish in range(self.n_shells):
            for bn in self.block_names[self.SO]:
                dl = self.shells[ish][3]
                DOSproj[ish][bn] = numpy.zeros([n_om],numpy.float_)
                DOSproj_orb[ish][bn] = numpy.zeros([n_om,dl,dl],numpy.float_)

        ikarray=numpy.array(range(self.n_k))

        for ik in mpi.slice_array(ikarray):

            S = self.lattice_gf_realfreq(ik=ik,mu=mu,broadening=broadening)
            S *= self.bz_weights[ik]

            # non-projected DOS
            for iom in range(n_om): 
                for sig,gf in S: DOS[sig][iom] += gf.data[iom,:,:].imag.trace()/(-3.1415926535)
               
            #projected DOS:
            for ish in xrange(self.n_shells):
                tmp = Gproj[ish].copy()
                for ir in xrange(self.n_parproj[ish]):
                    for sig,gf in tmp: tmp[sig] <<= self.downfold_pc(ik,ir,ish,sig,S[sig],gf)
                    Gproj[ish] += tmp
                   
        # collect data from mpi:
        for sig in DOS:
            DOS[sig] = mpi.all_reduce(mpi.world,DOS[sig],lambda x,y : x+y)
        for ish in xrange(self.n_shells):
            Gproj[ish] <<= mpi.all_reduce(mpi.world,Gproj[ish],lambda x,y : x+y)
        mpi.barrier()        
                  
        if (self.symm_op!=0): Gproj = self.Symm_par.symmetrize(Gproj)

        # rotation to local coord. system:
        if (self.use_rotations):
            for ish in xrange(self.n_shells):
                for sig,gf in Gproj[ish]: Gproj[ish][sig] <<= self.rotloc_all(ish,gf,direction='toLocal')
                
        for ish in range(self.n_shells):
            for sig,gf in Gproj[ish]:  
                for iom in range(n_om): DOSproj[ish][sig][iom] += gf.data[iom,:,:].imag.trace()/(-3.1415926535)
                DOSproj_orb[ish][sig][:,:,:] += gf.data[:,:,:].imag / (-3.1415926535)
	    

        if (mpi.is_master_node()):
            # output to files
            for bn in self.block_names[self.SO]:
                f=open('./DOScorr%s.dat'%bn, 'w')
                for i in range(n_om): f.write("%s    %s\n"%(Msh[i],DOS[bn][i]))
                f.close()    

                # partial
                for ish in range(self.n_shells):
                    f=open('DOScorr%s_proj%s.dat'%(bn,ish),'w')
                    for i in range(n_om): f.write("%s    %s\n"%(Msh[i],DOSproj[ish][bn][i]))
                    f.close()
 
                    for i in range(self.shells[ish][3]):
                        for j in range(i,self.shells[ish][3]):
                            Fname = './DOScorr'+bn+'_proj'+str(ish)+'_'+str(i)+'_'+str(j)+'.dat'
                            f=open(Fname,'w')
                            for iom in range(n_om): f.write("%s    %s\n"%(Msh[iom],DOSproj_orb[ish][bn][iom,i,j]))
                            f.close()
Exemple #34
0
    def dos_partial(self, broadening=0.01):
        """calculates the orbitally-resolved DOS"""

        assert hasattr(self, "Sigma_imp"), "Set Sigma First!!"

        #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all']
        #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data, thingstoread=thingstoread)
        retval = self.read_par_proj_input_from_hdf()
        if not retval: return retval
        if self.symm_op:
            self.Symm_par = Symmetry(self.hdf_file,
                                     subgroup=self.symm_par_data)

        mu = self.chemical_potential

        gf_struct_proj = [[(al, range(self.shells[i][3]))
                           for al in self.block_names[self.SO]]
                          for i in xrange(self.n_shells)]
        Gproj = [
            BlockGf(name_block_generator=[
                (a, GfReFreq(indices=al, mesh=self.Sigma_imp[0].mesh))
                for a, al in gf_struct_proj[ish]
            ],
                    make_copies=False) for ish in xrange(self.n_shells)
        ]
        for ish in range(self.n_shells):
            Gproj[ish].zero()

        Msh = [x for x in self.Sigma_imp[0].mesh]
        n_om = len(Msh)

        DOS = {}
        for bn in self.block_names[self.SO]:
            DOS[bn] = numpy.zeros([n_om], numpy.float_)

        DOSproj = [{} for ish in range(self.n_shells)]
        DOSproj_orb = [{} for ish in range(self.n_shells)]
        for ish in range(self.n_shells):
            for bn in self.block_names[self.SO]:
                dl = self.shells[ish][3]
                DOSproj[ish][bn] = numpy.zeros([n_om], numpy.float_)
                DOSproj_orb[ish][bn] = numpy.zeros([n_om, dl, dl],
                                                   numpy.float_)

        ikarray = numpy.array(range(self.n_k))

        for ik in mpi.slice_array(ikarray):

            S = self.lattice_gf_realfreq(ik=ik, mu=mu, broadening=broadening)
            S *= self.bz_weights[ik]

            # non-projected DOS
            for iom in range(n_om):
                for sig, gf in S:
                    DOS[sig][iom] += gf.data[iom, :, :].imag.trace() / (
                        -3.1415926535)

            #projected DOS:
            for ish in xrange(self.n_shells):
                tmp = Gproj[ish].copy()
                for ir in xrange(self.n_parproj[ish]):
                    for sig, gf in tmp:
                        tmp[sig] <<= self.downfold_pc(ik, ir, ish, sig, S[sig],
                                                      gf)
                    Gproj[ish] += tmp

        # collect data from mpi:
        for sig in DOS:
            DOS[sig] = mpi.all_reduce(mpi.world, DOS[sig], lambda x, y: x + y)
        for ish in xrange(self.n_shells):
            Gproj[ish] <<= mpi.all_reduce(mpi.world, Gproj[ish],
                                          lambda x, y: x + y)
        mpi.barrier()

        if (self.symm_op != 0): Gproj = self.Symm_par.symmetrize(Gproj)

        # rotation to local coord. system:
        if (self.use_rotations):
            for ish in xrange(self.n_shells):
                for sig, gf in Gproj[ish]:
                    Gproj[ish][sig] <<= self.rotloc_all(ish,
                                                        gf,
                                                        direction='toLocal')

        for ish in range(self.n_shells):
            for sig, gf in Gproj[ish]:
                for iom in range(n_om):
                    DOSproj[ish][sig][iom] += gf.data[
                        iom, :, :].imag.trace() / (-3.1415926535)
                DOSproj_orb[ish][sig][:, :, :] += gf.data[:, :, :].imag / (
                    -3.1415926535)

        if (mpi.is_master_node()):
            # output to files
            for bn in self.block_names[self.SO]:
                f = open('./DOScorr%s.dat' % bn, 'w')
                for i in range(n_om):
                    f.write("%s    %s\n" % (Msh[i], DOS[bn][i]))
                f.close()

                # partial
                for ish in range(self.n_shells):
                    f = open('DOScorr%s_proj%s.dat' % (bn, ish), 'w')
                    for i in range(n_om):
                        f.write("%s    %s\n" % (Msh[i], DOSproj[ish][bn][i]))
                    f.close()

                    for i in range(self.shells[ish][3]):
                        for j in range(i, self.shells[ish][3]):
                            Fname = './DOScorr' + bn + '_proj' + str(
                                ish) + '_' + str(i) + '_' + str(j) + '.dat'
                            f = open(Fname, 'w')
                            for iom in range(n_om):
                                f.write("%s    %s\n" %
                                        (Msh[iom], DOSproj_orb[ish][bn][iom, i,
                                                                        j]))
                            f.close()
    def partial_charges(self,beta=40):
        """Calculates the orbitally-resolved density matrix for all the orbitals considered in the input.
           The theta-projectors are used, hence case.parproj data is necessary"""
           

        #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all']
        #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data,thingstoread=thingstoread)
        retval = self.read_par_proj_input_from_hdf()
        if not retval: return retval
        if self.symm_op: self.Symm_par = Symmetry(self.hdf_file,subgroup=self.symm_par_data)
        
        # Density matrix in the window
        bln = self.block_names[self.SO]
        ntoi = self.names_to_ind[self.SO]
        self.dens_mat_window = [ [numpy.zeros([self.shells[ish][3],self.shells[ish][3]],numpy.complex_) for ish in range(self.n_shells)]   
                                 for isp in range(len(bln)) ]    # init the density matrix

        mu = self.chemical_potential
        GFStruct_proj = [ [ (al, range(self.shells[i][3])) for al in bln ]  for i in xrange(self.n_shells) ]
        if hasattr(self,"Sigma_imp"):
            Gproj = [BlockGf(name_block_generator = [ (a,GfImFreq(indices = al, mesh = self.Sigma_imp[0].mesh)) for a,al in GFStruct_proj[ish] ], make_copies = False)
                     for ish in xrange(self.n_shells)]
            beta = self.Sigma_imp[0].mesh.beta
        else:
            Gproj = [BlockGf(name_block_generator = [ (a,GfImFreq(indices = al, beta = beta)) for a,al in GFStruct_proj[ish] ], make_copies = False)
                     for ish in xrange(self.n_shells)]

        for ish in xrange(self.n_shells): Gproj[ish].zero()

        ikarray=numpy.array(range(self.n_k))
        #print mpi.rank, mpi.slice_array(ikarray)
        #print "K-Sum starts on node",mpi.rank," at ",datetime.now()
        
        for ik in mpi.slice_array(ikarray):
            #print mpi.rank, ik, datetime.now()
            S = self.lattice_gf_matsubara(ik=ik,mu=mu,beta=beta)
            S *= self.bz_weights[ik]

            for ish in xrange(self.n_shells):
                tmp = Gproj[ish].copy()
                for ir in xrange(self.n_parproj[ish]):
                    for sig,gf in tmp: tmp[sig] <<= self.downfold_pc(ik,ir,ish,sig,S[sig],gf)
                    Gproj[ish] += tmp
        
        #print "K-Sum done on node",mpi.rank," at ",datetime.now()
        #collect data from mpi:
        for ish in xrange(self.n_shells):
            Gproj[ish] <<= mpi.all_reduce(mpi.world,Gproj[ish],lambda x,y : x+y)
        mpi.barrier()

        #print "Data collected on node",mpi.rank," at ",datetime.now()

        # Symmetrisation:
        if (self.symm_op!=0): Gproj = self.Symm_par.symmetrize(Gproj)
        #print "Symmetrisation done on node",mpi.rank," at ",datetime.now()
        
        for ish in xrange(self.n_shells):

            # Rotation to local:
            if (self.use_rotations):
                for sig,gf in Gproj[ish]: Gproj[ish][sig] <<= self.rotloc_all(ish,gf,direction='toLocal')

            isp = 0
            for sig,gf in Gproj[ish]: #dmg.append(Gproj[ish].density()[sig])
                self.dens_mat_window[isp][ish] = Gproj[ish].density()[sig]
                isp+=1
       
        # add Density matrices to get the total:
        dens_mat = [ [ self.dens_mat_below[ntoi[bln[isp]]][ish]+self.dens_mat_window[isp][ish] for ish in range(self.n_shells)]
                     for isp in range(len(bln)) ]

        return dens_mat
def nested_calculation(clusters,
                       nested_struct_archive_name=None,
                       flexible_Gweiss=False,
                       sign=-1,
                       sign_up_to=2,
                       use_Gweiss_causal_cautionary=False,
                       use_G_proj=False,
                       mix_G_proj=False,
                       G_proj_mixing_rules=[[0, 0.0]],
                       Us=[1.0],
                       Ts=[0.125],
                       ns=[0.5],
                       fixed_n=True,
                       mutildes=[0.0],
                       dispersion=lambda kx, ky: epsilonk_square(kx, ky, 0.25),
                       ph_symmetry=True,
                       use_cumulant=False,
                       n_ks=[24],
                       n_k_automatic=False,
                       n_k_rules=[[0.06, 32], [0.03, 48], [0.005, 64],
                                  [0.00, 96]],
                       w_cutoff=20.0,
                       min_its=5,
                       max_its=25,
                       mix_Sigma=False,
                       rules=[[0, 0.5], [6, 0.2], [12, 0.65]],
                       do_dmft_first=False,
                       use_cthyb=False,
                       alpha=0.5,
                       delta=0.1,
                       automatic_alpha_and_delta=False,
                       n_cycles=10000000,
                       max_time_rules=[[1, 5 * 60], [2, 20 * 60], [4, 80 * 60],
                                       [8, 200 * 60], [16, 400 * 60]],
                       time_rules_automatic=False,
                       exponent=0.7,
                       overall_prefactor=1.0,
                       no_timing=False,
                       accuracy=1e-4,
                       solver_data_package=None,
                       print_current=1,
                       insulating_initial=False,
                       initial_guess_archive_name='',
                       suffix=''):

    if mpi.is_master_node():
        print "WELCOME TO %snested calculation!" % ("cumul_"
                                                    if use_cumulant else "")
        if n_k_automatic: print "n_k automatic!!!"
    if len(n_ks) == 0 and n_k_automatic: n_ks = [0]

    if use_cthyb:
        solver_class = solvers.cthyb
    else:
        solver_class = solvers.ctint

    fermionic_struct = {'up': [0]}

    if mpi.is_master_node(): print "nested structure: "
    if not (nested_struct_archive_name is None):
        try:
            nested_scheme = nested_struct.from_file(nested_struct_archive_name)
            if mpi.is_master_node():
                print "nested structure loaded from file", nested_struct_archive_name
        except:
            nested_scheme = nested_struct(clusters)
            nested_scheme.print_to_file(nested_struct_archive_name)
            if mpi.is_master_node():
                print "nested structure printed to file", nested_struct_archive_name
    else:
        nested_scheme = nested_struct(clusters)
    if mpi.is_master_node(): print nested_scheme.get_tex()

    impurity_struct = nested_scheme.get_impurity_struct()

    if not time_rules_automatic:
        max_times = {}
        for C in impurity_struct:
            for r in max_time_rules:
                if r[0] <= len(impurity_struct[C]):
                    max_times[C] = r[1]
        if mpi.is_master_node(): print "max_times from rules: ", max_times

    beta = 1.0 / Ts[0]

    n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0)
    if mpi.is_master_node():
        print "PM HUBBARD GW: n_iw: ", n_iw

    if not n_k_automatic:
        n_k = n_ks[0]
        print "n_k = ", n_k
    else:
        n_k = n_k_from_rules(Ts[0], n_k_rules)
        #if mpi.is_master_node(): print "n_k automatic!!!"

    dt = nested_data(n_iw=n_iw,
                     n_k=n_k,
                     beta=beta,
                     impurity_struct=impurity_struct,
                     fermionic_struct=fermionic_struct,
                     archive_name="so_far_nothing_you_shouldnt_see_this_file")
    if use_cumulant:
        dt.__class__ = cumul_nested_data
        dt.promote()

    if fixed_n:
        ps = itertools.product(n_ks, ns, Us, Ts)
    else:
        ps = itertools.product(n_ks, mutildes, Us, Ts)

    counter = 0
    old_nk = n_k
    old_beta = beta

    for p in ps:
        #name stuff to avoid confusion
        nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules))
        if fixed_n:
            n = p[1]
        else:
            mutilde = p[1]
            n = None
        U = p[2]
        T = p[3]
        beta = 1.0 / T

        if nk != old_nk and (not n_k_automatic):
            dt.change_ks(IBZ.k_grid(nk))

        if beta != old_beta:
            n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0)
            if n_k_automatic:
                nk = n_k_from_rules(T, n_k_rules)
                if nk != old_nk:
                    dt.change_ks(IBZ.k_grid(nk))
            dt.change_beta(beta, n_iw)

        old_beta = beta
        old_nk = nk
        nested_scheme.set_nk(nk)  #don't forget this part

        filename = "result"
        if len(n_ks) > 1 and (not n_k_automatic):
            filename += ".nk%s" % nk
        if len(ns) > 1 and fixed_n:
            filename += ".n%s" % n
        if len(mutildes) > 1 and not fixed_n:
            filename += ".mutilde%s" % mutilde
        if len(Us) > 1: filename += ".U%s" % U
        if len(Ts) > 1: filename += ".T%.4f" % T
        filename += ".h5"
        dt.archive_name = filename

        if mpi.is_master_node():
            if fixed_n:
                print "Working: U: %s T %s n: %s n_k: %s n_iw: %s" % (U, n, T,
                                                                      nk, n_iw)
            else:
                print "Working: U: %s T %s mutilde: %s n_k: %s n_iw: %s" % (
                    U, mutilde, T, nk, n_iw)

        if mpi.is_master_node():
            print "about to fill dispersion. ph-symmetry: ", ph_symmetry
        for key in dt.fermionic_struct.keys():
            for kxi in range(dt.n_k):
                for kyi in range(dt.n_k):
                    dt.epsilonk[key][kxi,
                                     kyi] = dispersion(dt.ks[kxi], dt.ks[kyi])

        if not use_cumulant:
            prepare = prepare_nested
        else:
            prepare = prepare_cumul_nested
        if flexible_Gweiss:
            prepare(dt, nested_scheme, solver_class, flexible_Gweiss, sign,
                    sign_up_to)
        else:
            prepare(dt, nested_scheme, solver_class, use_G_proj=use_G_proj)

        solver_class.initialize_solvers(dt, solver_data_package)

        max_times = {}

        if no_timing:
            for C in dt.impurity_struct.keys():
                max_times[C] = -1
            if mpi.is_master_node():
                print "no_timing! solvers will run until they perform all the mc steps", max_times

        if time_rules_automatic and (not no_timing):
            for C in dt.impurity_struct.keys():
                Nc = len(dt.impurity_struct[C])
                pref = ((dt.beta / 8.0) * U * Nc)**exponent  #**1.2
                print C
                print "Nc: ", Nc,
                print "U: ", U,
                print "beta: ", dt.beta,
                print "pref: ", pref
                max_times[C] = int(overall_prefactor * pref * 5 * 60)
            if mpi.is_master_node(): print "max times automatic: ", max_times

        identical_pairs_Sigma = nested_scheme.get_identical_pairs()
        identical_pairs_G = nested_scheme.get_identical_pairs_for_G()
        identical_pairs_G_ai = nested_scheme.get_identical_pairs_for_G(
            across_imps=True)

        actions = [
            generic_action(name="lattice",
                           main=lambda data: nested_mains.lattice(
                               data,
                               n=n,
                               ph_symmetry=ph_symmetry,
                               accepted_mu_range=[-2.0, 2.0]),
                           mixers=[],
                           cautionaries=[],
                           allowed_errors=[],
                           printout=lambda data, it: ([
                               data.dump_general(quantities=['Gkw', 'Gijw'] +
                                                 (['G_proj_iw']
                                                  if use_G_proj else []),
                                                 suffix='-current'),
                               data.dump_scalar(suffix='-current')
                           ] if ((it + 1) % print_current == 0) else None)),
            generic_action(
                name="pre_impurity",
                main=lambda data: nested_mains.pre_impurity(data),
                mixers=[],
                cautionaries=([
                    lambda data, it: ph_symmetric_Gweiss_causal_cautionary(
                        data, ntau=5000)
                ] if use_Gweiss_causal_cautionary else []),
                allowed_errors=([0] if use_Gweiss_causal_cautionary else []),
                printout=lambda data, it: (
                    (data.dump_general(quantities=[
                        'Gweiss_iw_unfit', 'Gweiss_iw', 'Delta_iw',
                        'Delta_iw_fit', 'Delta_tau', 'Delta_tau_fit'
                    ],
                                       suffix='-%s' % it))
                    if use_Gweiss_causal_cautionary else (data.dump_general(
                        quantities=['Gweiss_iw'], suffix='-current')))),
            generic_action(
                name="impurity",
                main=(lambda data: nested_mains.impurity(
                    data,
                    U,
                    symmetrize_quantities=True,
                    alpha=alpha,
                    delta=delta,
                    automatic_alpha_and_delta=automatic_alpha_and_delta,
                    n_cycles=n_cycles,
                    max_times=max_times,
                    solver_data_package=solver_data_package)) if
                (not use_cthyb) else (lambda data: nested_mains.impurity_cthyb(
                    data,
                    U,
                    symmetrize_quantities=True,
                    n_cycles=n_cycles,
                    max_times=max_times,
                    solver_data_package=solver_data_package)),
                mixers=[],
                cautionaries=[
                    lambda data, it: local_nan_cautionary(data,
                                                          data.impurity_struct,
                                                          Qs=['Sigma_imp_iw'],
                                                          raise_exception=True
                                                          ), lambda data, it:
                    (symmetric_G_and_self_energy_on_impurity(
                        data.G_imp_iw,
                        data.Sigma_imp_iw,
                        data.solvers,
                        identical_pairs_Sigma,
                        identical_pairs_G,
                        across_imps=True,
                        identical_pairs_G_ai=identical_pairs_G_ai)
                     if it >= 0 else symmetrize_cluster_impurity(
                         data.Sigma_imp_iw, identical_pairs_Sigma))
                ],
                allowed_errors=[1],
                printout=lambda data, it: ([
                    data.dump_general(quantities=['Sigma_imp_iw', 'G_imp_iw'],
                                      suffix='-current'),
                    data.dump_solvers(suffix='-current')
                ] if ((it + 1) % print_current == 0) else None)),
            generic_action(
                name="selfenergy",
                main=lambda data: nested_mains.selfenergy(data),
                mixers=[],
                cautionaries=[
                    lambda data, it: nonloc_sign_cautionary(data.Sigmakw['up'],
                                                            desired_sign=-1,
                                                            clip_off=False,
                                                            real_or_imag='imag'
                                                            )
                ],
                allowed_errors=[0],
                printout=lambda data, it:
                (data.dump_general(quantities=['Sigmakw', 'Sigmaijw'],
                                   suffix='-current')
                 if ((it + 1) % print_current == 0) else None))
        ]

        if use_cumulant:
            del actions[3]
            actions.append(
                generic_action(
                    name="cumulant",
                    main=lambda data: cumul_nested_mains.cumulant(data),
                    mixers=[],
                    cautionaries=[
                        lambda data, it: nonloc_sign_cautionary(
                            data.gkw['up'],
                            desired_sign=-1,
                            clip_off=False,
                            real_or_imag='imag')
                    ],
                    allowed_errors=[0],
                    printout=lambda data, it:
                    (data.dump_general(quantities=['gijw', 'gkw'],
                                       suffix='-current')
                     if ((it + 1) % print_current == 0) else None)))

        monitors = [
            monitor(monitored_quantity=lambda: dt.ns['up'],
                    h5key='n_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.mus['up'],
                    h5key='mu_vs_it',
                    archive_name=dt.archive_name),
            monitor(monitored_quantity=lambda: dt.err,
                    h5key='err_vs_it',
                    archive_name=dt.archive_name)
        ]  #,
        #                 monitor( monitored_quantity = lambda: actions[3].errs[0],
        #                          h5key = 'sign_err_vs_it',
        #                          archive_name = dt.archive_name) ]

        if use_cumulant:
            monitors += [
                monitor(monitored_quantity=lambda: dt.gijw['up'][dt.nw / 2, 0,
                                                                 0].imag,
                        h5key='Img_00_w0_vs_it',
                        archive_name=dt.archive_name),
                monitor(monitored_quantity=lambda: dt.gijw['up'][dt.nw / 2, 0,
                                                                 0].real,
                        h5key='Reg_00_iw0_vs_it',
                        archive_name=dt.archive_name),
                monitor(monitored_quantity=lambda: dt.gkw['up'][
                    dt.nw / 2, dt.n_k / 2, dt.n_k / 2].imag,
                        h5key='Img_pipi_iw0_vs_it',
                        archive_name=dt.archive_name),
                monitor(monitored_quantity=lambda: dt.gkw['up'][
                    dt.nw / 2, dt.n_k / 2, dt.n_k / 2].real,
                        h5key='Reg_pipi_iw0_vs_it',
                        archive_name=dt.archive_name)
            ]
        else:
            monitors += [
                monitor(monitored_quantity=lambda: dt.Sigma_loc_iw['up'].data[
                    dt.nw / 2, 0, 0].imag,
                        h5key='ImSigma_loc_iw0_vs_it',
                        archive_name=dt.archive_name),
                monitor(monitored_quantity=lambda: dt.Sigma_loc_iw['up'].data[
                    dt.nw / 2, 0, 0].real,
                        h5key='ReSigma_loc_iw0_vs_it',
                        archive_name=dt.archive_name),
                monitor(monitored_quantity=lambda: dt.Sigmakw['up'][
                    dt.nw / 2, dt.n_k / 2, dt.n_k / 2].imag,
                        h5key='ImSigmakw_pipi_vs_it',
                        archive_name=dt.archive_name),
                monitor(monitored_quantity=lambda: dt.Sigmakw['up'][
                    dt.nw / 2, dt.n_k / 2, dt.n_k / 2].real,
                        h5key='ReSigmakw_pipi_vs_it',
                        archive_name=dt.archive_name)
            ]

        convergers = [
            converger(monitored_quantity=lambda: dt.G_loc_iw,
                      accuracy=accuracy,
                      struct=fermionic_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_G_loc'),
            converger(monitored_quantity=lambda: dt.Sigma_loc_iw,
                      accuracy=accuracy,
                      struct=fermionic_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_Sigma_loc'),
            converger(monitored_quantity=lambda: dt.G_imp_iw,
                      accuracy=accuracy,
                      struct=impurity_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_G_imp'),
            converger(monitored_quantity=lambda: dt.Gweiss_iw,
                      accuracy=accuracy,
                      struct=impurity_struct,
                      archive_name=dt.archive_name,
                      h5key='diffs_Gweiss')
        ]
        max_dist = 3
        for i in range(max_dist + 1):
            for j in range(0, i + 1):
                convergers.append(
                    converger(monitored_quantity=lambda i=i, j=j: dt.Gijw['up']
                              [:, i, j],
                              accuracy=accuracy,
                              func=converger.check_numpy_array,
                              archive_name=dt.archive_name,
                              h5key='diffs_G_%s%s' % (i, j)))
        dmft = generic_loop(name="nested-cluster DMFT",
                            actions=actions,
                            convergers=convergers,
                            monitors=monitors)

        if (counter == 0):  #do the initial guess only once!
            if initial_guess_archive_name != '':
                if mpi.is_master_node():
                    print "constructing dt from initial guess in a file: ", initial_guess_archive_name, "suffix: ", suffix
                old_epsilonk = dt.epsilonk
                dt.construct_from_file(initial_guess_archive_name, suffix)
                if dt.beta != beta:
                    dt.change_beta(beta, n_iw)
                if dt.n_k != nk:
                    dt.change_ks(IBZ.k_grid(nk))
                if mpi.is_master_node():
                    print "putting back the old Jq and epsilonk"
                dt.epsilonk = old_epsilonk
            else:
                if not fixed_n:
                    dt.mus['up'] = mutilde
                else:
                    dt.mus['up'] = U / 2.0
                if 'down' in dt.fermionic_struct.keys():
                    dt.mus['down'] = dt.mus[
                        'up']  #this is not necessary at the moment, but may become
                for C in dt.impurity_struct.keys():
                    for l in dt.impurity_struct[
                            C]:  #just the local components (but on each site!)
                        dt.Sigma_imp_iw[C].data[:, l, l] = U / 2.0 - int(
                            insulating_initial) * 1j / numpy.array(dt.ws)
                if not use_cumulant:
                    for key in fermionic_struct.keys():
                        dt.Sigmakw[key][:, :, :] = U / 2.0
                        numpy.transpose(dt.Sigmakw[key])[:] -= int(
                            insulating_initial) * 1j / numpy.array(dt.ws)
                else:
                    for key in fermionic_struct.keys():
                        numpy.transpose(dt.gkw[key])[:] = numpy.array(
                            dt.iws[:])**(-1.0)
            if not use_cumulant:
                dt.dump_general(quantities=['Sigmakw', 'Sigma_imp_iw'],
                                suffix='-initial')
            else:
                dt.dump_general(quantities=['gkw'], suffix='-initial')

        if (counter == 0) and do_dmft_first:
            assert False, "this part of code needs to be adjusted"
            #do one short run of dmft before starting nested
            if mpi.is_master_node():
                print "================= 20 iterations of DMFT!!!! ================="
            #save the old stuff
            old_impurity_struct = dt.impurity_struct
            old_name = dmft.name
            #dmft_scheme
            dmft_scheme = nested_scheme([cluster(0, 0, 1, 1)])
            dmft_scheme.set_nk(dt.n_k)
            dt.impurity_struct = dmft_scheme.get_impurity_struct()
            prepare_nested(dt, dmft_scheme, solvers.ctint)
            dmft.name = "dmft"
            #run dmft
            dmft.run(dt,
                     max_its=20,
                     min_its=15,
                     max_it_err_is_allowed=7,
                     print_final=True,
                     print_current=10000)
            #move the result
            if mpi.is_master_node():
                cmd = 'mv %s %s' % (filename, filename.replace(
                    "result", "dmft"))
                print cmd
                os.system(cmd)
            #put everything back the way it was
            dmft.name = old_name
            dt.impurity_struct = old_impurity_struct
            prepare(dt, nested_scheme, solver_class)

        #run nested!-------------

        if mix_Sigma:
            actions[3].mixers.extend([
                mixer(mixed_quantity=lambda: (dt.Sigmakw if
                                              (not use_cumulant) else dt.gkw),
                      rules=rules,
                      func=mixer.mix_lattice_gf,
                      initialize=True)
            ])
            actions[2].mixers.extend([
                mixer(mixed_quantity=lambda: dt.Sigma_imp_iw,
                      rules=rules,
                      func=mixer.mix_block_gf,
                      initialize=True)
            ])

        if mix_G_proj:
            actions[0].mixers.append(
                mixer(mixed_quantity=lambda: dt.G_proj_iw,
                      rules=G_proj_mixing_rules,
                      func=mixer.mix_block_gf,
                      initialize=True))

        dt.dump_parameters()
        dt.dump_non_interacting()

        err = dmft.run(dt,
                       max_its=max_its,
                       min_its=min_its,
                       max_it_err_is_allowed=7,
                       print_final=True,
                       print_current=1)
        if mpi.is_master_node():
            if use_cumulant:
                print "calculating Sigma"
                dt.get_Sigmakw()
                dt.get_Sigma_loc()
                dt.dump_general(['Sigmakw', 'Sigma_loc_iw'], suffix='-final')
            cmd = 'mv %s %s' % (filename, filename.replace("result", "nested"))
            print cmd
            os.system(cmd)

        if (err == 2):
            print "Cautionary error!!! exiting..."
            solver_data_package['construct|run|exit'] = 2
            if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
                solver_data_package = mpi.bcast(solver_data_package)
            break

        if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
        counter += 1
    if not (solver_data_package is None):
        solver_data_package['construct|run|exit'] = 2
    if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
        solver_data_package = mpi.bcast(solver_data_package)
    return dt, monitors, convergers
Exemple #37
0
    def run_dmft_loops(self, n_dmft_loops = 1):
        """runs the DMFT calculation"""
        clp = p = CleanLoopParameters(self.get_parameters())
        report = Reporter(**clp)
        report('Parameters:', clp)
        scheme = Scheme(**clp)
        dmft = DMFTObjects(**clp)
        raw_dmft = DMFTObjects(**clp)
        g_0_c_iw, g_c_iw, sigma_c_iw, dmu = dmft.get_dmft_objs() # ref, ref, ref, value

        report('Initializing...')
        if clp['nambu']:
            transf = NambuTransformation(**clp)
            scheme.set_pretransf(transf.pretransformation(), transf.pretransformation_inverse())
            raw_transf = NambuTransformation(**clp)
        else:
            transf = ClustersiteTransformation(g_loc = scheme.g_local(sigma_c_iw, dmu), **clp)
            clp.update({'g_transf_struct': transf.get_g_struct()})
            raw_transf = ClustersiteTransformation(**clp)
        
        transf.set_hamiltonian(**clp)
        report('Transformation ready')
        report('New basis:', transf.get_g_struct())
        impurity = Solver(beta = clp['beta'], gf_struct = dict(transf.get_g_struct()), 
                          n_tau = clp['n_tau'], n_iw = clp['n_iw'], n_l = clp['n_legendre'])
        impurity.Delta_tau.name = '$\\tilde{\\Delta}_c$'
        rnames = random_generator_names_list()
        report('H = ', transf.hamiltonian)
        report('Impurity solver ready')
        report('')

        for loop_nr in range(self.next_loop(), self.next_loop() + n_dmft_loops):
            report('DMFT-loop nr. %s'%loop_nr)
            if mpi.is_master_node(): duration = time()

            report('Calculating dmu...')
            dmft.find_dmu(scheme, **clp)
            g_0_c_iw, g_c_iw, sigma_c_iw, dmu = dmft.get_dmft_objs()
            report('dmu = %s'%dmu)

            report('Calculating local Greenfunction...')
            g_c_iw << scheme.g_local(sigma_c_iw, dmu)
            g_c_iw << addExtField(g_c_iw, p['ext_field'])
            if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(g_c_iw, p['archive'][0:-3] + 'Gchecksym' + str(loop_nr) + '.pdf')
            report('Calculating Weiss-field...')
            g_0_c_iw << inverse(inverse(g_c_iw) + sigma_c_iw)

            dmft.make_g_0_iw_with_delta_tau_real()

            report('Changing basis...')
            transf.set_dmft_objs(*dmft.get_dmft_objs())
            if mpi.is_master_node() and p['verbosity'] > 1: 
                checktransf_plot(transf.get_g_iw(), p['archive'][0:-3] + 'Gchecktransf' + str(loop_nr) + '.pdf')
                checktransf_plot(g_0_c_iw, p['archive'][0:-3] + 'Gweisscheck' + str(loop_nr) + '.pdf')
                checksym_plot(inverse(transf.g_0_iw), p['archive'][0:-3] + 'invGweisscheckconst' + str(loop_nr) + '.pdf')
                #checksym_plot(inverse(transf.get_g_iw()), p['archive'][0:-3] + 'invGsymcheckconst' + str(loop_nr) + '.pdf')

            if not clp['random_name']: clp.update({'random_name': rnames[int((loop_nr + mpi.rank) % len(rnames))]}) # TODO move
            if not clp['random_seed']: clp.update({'random_seed': 862379 * mpi.rank + 12563 * self.next_loop()})
            impurity.G0_iw << transf.get_g_0_iw()
            report('Solving impurity problem...')
            mpi.barrier()
            impurity.solve(h_int = transf.get_hamiltonian(), **clp.get_cthyb_parameters())

            if mpi.is_master_node() and p['verbosity'] > 1:
                checksym_plot(inverse(impurity.G0_iw), p['archive'][0:-3] + 'invGweisscheckconstsolver' + str(loop_nr) + '.pdf')
            report('Postprocessing measurements...')
            if clp['measure_g_l']:
                for ind, g in transf.get_g_iw(): g  << LegendreToMatsubara(impurity.G_l[ind])
            else:
                for ind, g in transf.get_g_iw(): g.set_from_fourier(impurity.G_tau[ind])
            raw_transf.set_dmft_objs(transf.get_g_0_iw(),
                                     transf.get_g_iw(),
                                     inverse(transf.get_g_0_iw()) - inverse(transf.get_g_iw()))
            if clp['measure_g_tau'] and clp['fit_tail']:
                for ind, g in transf.get_g_iw():
                    for tind in transf.get_g_struct():
                        if tind[0] == ind: block_inds = tind[1]
                    fixed_moments = TailGf(len(block_inds), len(block_inds), 1, 1)
                    fixed_moments[1] = identity(len(block_inds))
                    g.fit_tail(fixed_moments, 3, clp['tail_start'], clp['n_iw'] - 1)
            if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(inverse(transf.get_g_iw()), p['archive'][0:-3] + 'invGsymcheckconstsolver' + str(loop_nr) + '.pdf')
            report('Backtransforming...')
            transf.set_sigma_iw(inverse(transf.get_g_0_iw()) - inverse(transf.get_g_iw()))
            dmft.set_dmft_objs(*transf.get_backtransformed_dmft_objs())
            dmft.set_dmu(dmu)
            raw_dmft.set_dmft_objs(*raw_transf.get_backtransformed_dmft_objs())
            raw_dmft.set_dmu(dmu)

            if clp['mix']: dmft.mix()
            if clp['impose_paramagnetism']: dmft.paramagnetic()
            if clp['impose_afm']: dmft.afm()
            if clp['site_symmetries']: dmft.site_symmetric(clp['site_symmetries'])
            density = scheme.apply_pretransf_inv(dmft.get_g_iw(), True).total_density()

            report('Saving results...')
            if mpi.is_master_node():
                a = HDFArchive(p['archive'], 'a')
                if not a.is_group('results'):
                    a.create_group('results')
                a_r = a['results']
                a_r.create_group(str(loop_nr))
                a_l = a_r[str(loop_nr)]
                a_l['g_c_iw'] = dmft.get_g_iw()
                a_l['g_c_iw_raw'] = raw_dmft.get_g_iw()
                a_l['g_transf_iw'] = transf.get_g_iw()
                a_l['g_transf_iw_raw'] = raw_transf.get_g_iw()
                a_l['sigma_c_iw'] = dmft.get_sigma_iw()
                a_l['sigma_c_iw_raw'] = raw_dmft.get_sigma_iw()
                a_l['sigma_transf_iw'] = transf.get_sigma_iw()
                a_l['sigma_transf_iw_raw'] = raw_transf.get_sigma_iw()
                a_l['g_0_c_iw'] = dmft.get_g_0_iw()
                a_l['g_0_c_iw_raw'] = raw_dmft.get_g_0_iw()
                a_l['g_0_transf_iw'] = transf.get_g_0_iw()
                a_l['g_0_transf_iw_raw'] = raw_transf.get_g_0_iw()
                a_l['dmu'] = dmft.get_dmu()
                a_l['density'] = density
                a_l['loop_time'] = {'seconds': time() - duration,
                                    'hours': (time() - duration)/3600., 
                                    'days': (time() - duration)/3600./24.}
                a_l['n_cpu'] = mpi.size
                a_l['cdmft_code_version'] = CDmft._version
                clp_dict = dict()
                clp_dict.update(clp)
                a_l['parameters'] = clp_dict
                a_l['triqs_code_version'] = version

                a_l['delta_transf_tau'] = impurity.Delta_tau
                if clp['measure_g_l']: a_l['g_transf_l'] = impurity.G_l
                if clp['measure_g_tau']: a_l['g_transf_tau'] = impurity.G_tau
                a_l['sign'] = impurity.average_sign
                if clp['measure_density_matrix']: a_l['density_matrix'] = impurity.density_matrix
                a_l['g_atomic_tau'] = impurity.atomic_gf
                a_l['h_loc_diagonalization'] = impurity.h_loc_diagonalization
                if a_r.is_data('n_dmft_loops'):
                    a_r['n_dmft_loops'] += 1
                else:
                    a_r['n_dmft_loops'] = 1
                del a_l, a_r, a
            report('Loop done')
            report('')
            mpi.barrier()
Exemple #38
0
def solve_lattice_bse(g_wk, gamma_wnn, tail_corr_nwf=None):
    r""" Compute the generalized lattice susceptibility 
    :math:`\chi_{abcd}(\omega, \mathbf{k})` using the Bethe-Salpeter 
    equation (BSE).

    Parameters
    ----------

    g_wk : Single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`.
    gamma_wnn : Local particle-hole vertex function 
                :math:`\Gamma_{abcd}(\omega, \nu, \nu')`
    tail_corr_nwf : Number of fermionic freqiencies to use in the 
                    tail correction of the sum over fermionic frequencies.

    Returns
    -------

    chi0_wk : Generalized lattice susceptibility
              :math:`\chi_{abcd}(\omega, \mathbf{k})`
    """

    fmesh_g = g_wk.mesh.components[0]
    kmesh = g_wk.mesh.components[1]

    bmesh = gamma_wnn.mesh.components[0]
    fmesh = gamma_wnn.mesh.components[1]

    nk = len(kmesh)
    nw = (len(bmesh) + 1) / 2
    nwf = len(fmesh) / 2
    nwf_g = len(fmesh_g) / 2

    if mpi.is_master_node():
        print tprf_banner(), "\n"
        print 'Lattcie BSE with local vertex approximation.\n'
        print 'nk    =', nk
        print 'nw    =', nw
        print 'nwf   =', nwf
        print 'nwf_g =', nwf_g
        print 'tail_corr_nwf =', tail_corr_nwf
        print

    if tail_corr_nwf is None:
        tail_corr_nwf = nwf

    mpi.report('--> chi0_wnk_tail_corr')
    chi0_wnk_tail_corr = get_chi0_wnk(g_wk, nw=nw, nwf=tail_corr_nwf)

    mpi.report('--> trace chi0_wnk_tail_corr (WARNING! NO TAIL FIT. FIXME!)')
    chi0_wk_tail_corr = chi0q_sum_nu_tail_corr_PH(chi0_wnk_tail_corr)
    #chi0_wk_tail_corr = chi0q_sum_nu(chi0_wnk_tail_corr)

    mpi.barrier()
    mpi.report('B1 ' +
               str(chi0_wk_tail_corr[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    mpi.report('--> chi0_wnk_tail_corr to chi0_wnk')
    if tail_corr_nwf != nwf:
        mpi.report('--> fixed_fermionic_window_python_wnk')
        chi0_wnk = fixed_fermionic_window_python_wnk(chi0_wnk_tail_corr,
                                                     nwf=nwf)
    else:
        chi0_wnk = chi0_wnk_tail_corr.copy()

    del chi0_wnk_tail_corr

    mpi.barrier()
    mpi.report('C ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    mpi.report('--> trace chi0_wnk')
    chi0_wk = chi0q_sum_nu(chi0_wnk)

    mpi.barrier()
    mpi.report('D ' + str(chi0_wk[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    dchi_wk = chi0_wk_tail_corr - chi0_wk

    chi0_kw = Gf(mesh=MeshProduct(kmesh, bmesh),
                 target_shape=chi0_wk_tail_corr.target_shape)
    chi0_kw.data[:] = chi0_wk_tail_corr.data.swapaxes(0, 1)

    del chi0_wk
    del chi0_wk_tail_corr

    assert (chi0_wnk.mesh.components[0] == bmesh)
    assert (chi0_wnk.mesh.components[1] == fmesh)
    assert (chi0_wnk.mesh.components[2] == kmesh)

    # -- Lattice BSE calc with built in trace
    mpi.report('--> chi_kw from BSE')
    #mpi.report('DEBUG BSE INACTIVE'*72)
    chi_kw = chiq_sum_nu_from_chi0q_and_gamma_PH(chi0_wnk, gamma_wnn)
    #chi_kw = chi0_kw.copy()

    mpi.barrier()
    mpi.report('--> chi_kw from BSE (done)')

    del chi0_wnk

    mpi.report('--> chi_kw tail corrected (using chi0_wnk)')
    for k in kmesh:
        chi_kw[
            k, :] += dchi_wk[:,
                             k]  # -- account for high freq of chi_0 (better than nothing)

    del dchi_wk

    mpi.report('--> solve_lattice_bse, done.')

    return chi_kw, chi0_kw
    def __call__ (self, Sigma, mu=0, eta=0, field=None, epsilon_hat=None, result=None, selected_blocks=()):
	"""
	- Computes:
	   result <- \[ \sum_k (\omega + \mu - field - t(k) - Sigma(k,\omega)) \]
           if result is None, it returns a new GF with the results.
           otherwise, result must be a GF, in which the calculation is done, and which is then returned.
           (this allows chain calculation: SK(mu = mu,Sigma = Sigma, result = G).total_density()
           which computes the sumK into G,  and returns the density of G.

        - Sigma can be a X, or a function k-> X or a function k,eps ->X where:
	    - k is expected to be a 1d-numpy array of size self.dim of float,
	      containing the k vector in the basis of the RBZ  (i.e.  -0.5< k_i <0.5)
            - eps is t(k)
	    - X is anything such that X[BlockName] can be added/subtracted to a GFBloc for BlockName in selected_blocks.
	      e.g. X can be a BlockGf(with at least the selected_blocks), or a dictionnary Blockname -> array
	      if the array has the same dimension as the GF blocks (for example to add a static Sigma).

        - field: Any k independant object to be added to the GF

        - epsilon_hat: a function of eps_k returning a matrix, the dimensions of Sigma

        - selected_blocks: The calculation is done with the SAME t(k) for all blocks. If this list is not None
	  only the blocks in this list are calculated.
	  e.g. G and Sigma have block indices 'up' and 'down'.
	       if selected_blocks ==None: 'up' and 'down' are calculated
	       if selected_blocks == ['up']: only 'up' is calculated. 'down' is 0.


        """

        assert selected_blocks == (), "selected_blocks not supported for now"
            #S = Sigma.view_selected_blocks(selected_blocks) if selected_blocks else Sigma
            #Gres = result if result else Sigma.copy()
            #G = Gres.view_selected_blocks(selected_blocks) if selected_blocks else Gres

        # check Sigma
        # case 1) Sigma is a BlockGf
        if isinstance(Sigma, BlockGf):
            model = Sigma
            Sigma_fnt = False
        # case 2) Sigma is a function returning a BlockGf
        else:
            assert callable(Sigma), "If Sigma is not a BlockGf it must be a function"
            Sigma_Nargs = len(inspect.getargspec(Sigma)[0])
            assert Sigma_Nargs <= 2, "Sigma must be a function of k or of k and epsilon"
            if Sigma_Nargs == 1:
                model = Sigma(self.bz_points[0])
            elif Sigma_Nargs == 2:
                model = Sigma(self.bz_points[0], self.hopping[0])
            Sigma_fnt = True

        G = result if result else model.copy()
        assert isinstance(G,BlockGf), "G must be a BlockGf"

        # check input
        assert self.orthogonal_basis, "Local_G: must be orthogonal. non ortho cases not checked."
        assert len(list(set([g.N1 for i,g in G]))) == 1
        assert self.bz_weights.shape[0] == self.n_kpts(), "Internal Error"
        no = list(set([g.N1 for i,g in G]))[0]

        # Initialize
        G.zero()
        tmp,tmp2 = G.copy(),G.copy()
        mupat = mu * numpy.identity(no, numpy.complex_)
        tmp << iOmega_n
        if field != None: tmp -= field
        if not Sigma_fnt: tmp -= Sigma  # substract Sigma once for all

        # Loop on k points...
        for w, k, eps_k in izip(*[mpi.slice_array(A) for A in [self.bz_weights, self.bz_points, self.hopping]]):

            eps_hat = epsilon_hat(eps_k) if epsilon_hat else eps_k
            tmp2 << tmp
            tmp2 -= tmp2.n_blocks * [eps_hat - mupat]

            if Sigma_fnt:
                if Sigma_Nargs == 1: tmp2 -= Sigma(k)
                elif Sigma_Nargs == 2: tmp2 -= Sigma(k,eps_k)

            tmp2.invert()
            tmp2 *= w
            G += tmp2

        G << mpi.all_reduce(mpi.world,G,lambda x,y: x+y)
        mpi.barrier()

        return G
Exemple #40
0
def run_all(vasp_pid):
    """
    """
    mpi.report("  Waiting for VASP lock to appear...")
    while not is_vasp_lock_present():
        time.sleep(1)

    vasp_running = True

    while vasp_running:
        if debug: print bcolors.RED + "rank %s"%(mpi.rank) + bcolors.ENDC
        mpi.report("  Waiting for VASP lock to disappear...")
        mpi.barrier()
        while is_vasp_lock_present():
            time.sleep(1)
#            if debug: print bcolors.YELLOW + " waiting: rank %s"%(mpi.rank) + bcolors.ENDC
            if not is_vasp_running(vasp_pid):
                mpi.report("  VASP stopped")
                vasp_running = False
                break

        if debug: print bcolors.MAGENTA + "rank %s"%(mpi.rank) + bcolors.ENDC
        err = 0
        exc = None
        try:
            if debug: print bcolors.BLUE + "plovasp: rank %s"%(mpi.rank) + bcolors.ENDC
            if mpi.is_master_node():
                plovasp.generate_and_output_as_text('plo.cfg', vasp_dir='./')
# Read energy from OSZICAR
                dft_energy = get_dft_energy()
        except Exception, exc:
            err = 1

        err = mpi.bcast(err)
        if err:
            if mpi.is_master_node():
                raise exc
            else:
                raise SystemExit(1)

        mpi.barrier()

        try:
            if debug: print bcolors.GREEN + "rank %s"%(mpi.rank) + bcolors.ENDC
            corr_energy, dft_dc = dmft_cycle()
        except:
            if mpi.is_master_node():
                print "  master forwarding the exception..."
                raise
            else:
                print "  rank %i exiting..."%(mpi.rank)
                raise SystemExit(1)
        mpi.barrier()

        if mpi.is_master_node():
            total_energy = dft_energy + corr_energy - dft_dc
            print
            print "="*80
            print "  Total energy: ", total_energy
            print "  DFT energy: ", dft_energy
            print "  Corr. energy: ", corr_energy
            print "  DFT DC: ", dft_dc
            print "="*80
            print

        if mpi.is_master_node() and vasp_running:
            open('./vasp.lock', 'a').close()
    def run(
            self,
            data,
            calculation_name='',
            total_debug=False,
            n_loops_max=100,
            n_loops_min=5,
            print_local=1,
            print_impurity_input=1,
            print_non_local=1,
            print_three_leg=1,
            print_impurity_output=1,
            skip_self_energy_on_first_iteration=False,  #1 every iteration, 2 every second, -2 never (except for final)
            mix_after_selfenergy=False,
            last_iteration_err_is_allowed=15):
        for mixer in (self.mixers + self.imp_mixers):
            mixer.get_initial()
        for conv in self.convergers:
            conv.reset()
        for monitor in self.monitors:
            monitor.reset()

        if not (self.cautionary is None):
            self.cautionary.reset()

        if mpi.is_master_node():
            data.dump_parameters(suffix='')
            data.dump_non_interacting(suffix='')

        converged = False
        failed = False
        for loop_index in range(n_loops_max):
            if mpi.is_master_node():
                print "---------------------------- loop_index: ", loop_index, "/", n_loops_max, "---------------------------------"
            times = []

            times.append((time(), "selfenergy"))

            if loop_index != 0 or not skip_self_energy_on_first_iteration:
                self.selfenergy(data=data)

            times.append((time(), "mixing 1"))

            if mix_after_selfenergy:
                for mixer in self.mixers:
                    mixer.mix(loop_index)

            times.append((time(), "cautionary"))

            if not (self.cautionary is None):
                data.err = self.cautionary.check_and_fix(data)
                if data.err and (loop_index > last_iteration_err_is_allowed):
                    failed = True

            times.append((time(), "lattice"))

            self.lattice(data=data)

            times.append((time(), "pre_impurity"))

            self.pre_impurity(data=data)

            times.append((time(), "dump_impurity_input"))

            if mpi.is_master_node() and ((loop_index + 1) %
                                         print_impurity_input == 0):
                data.dump_impurity_input(suffix='-%s' % loop_index)

            times.append((time(), "impurity"))

            if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
            self.impurity(data=data)
            if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
            times.append((time(), "dump_impurity_output and mix impurity"))

            if mpi.is_master_node():
                if (loop_index + 1) % print_local == 0:
                    data.dump_solver(suffix='-%s' % loop_index)

            for mixer in self.imp_mixers:
                mixer.mix(loop_index)

            times.append((time(), "post_impurity"))

            self.post_impurity(data=data)

            times.append((time(), "convergers"))

            c = True
            for conv in self.convergers:
                if not conv.check():
                    c = False
            converged = c  #here we are checking that all have converged, not that at least one has converged

            times.append((time(), "mixing 2"))

            if not converged and not mix_after_selfenergy:
                for mixer in self.mixers:
                    mixer.mix(loop_index)

            times.append((time(), "monitors"))

            for monitor in self.monitors:
                monitor.monitor()

            times.append((time(), "dumping"))

            if mpi.is_master_node():
                data.dump_errors(suffix='-%s' % loop_index)
                data.dump_scalar(suffix='-%s' % loop_index)
                if (loop_index + 1) % print_local == 0:
                    data.dump_local(suffix='-%s' % loop_index)
                if (loop_index + 1) % print_three_leg == 0:
                    data.dump_three_leg(suffix='-%s' % loop_index)
                if (loop_index + 1) % print_non_local == 0:
                    data.dump_non_local(suffix='-%s' % loop_index)
                A = HDFArchive(data.archive_name)
                A['max_index'] = loop_index
                del A
            if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()

            if (mpi.rank == 0
                    or mpi.rank == 1) and total_debug:  #total debug option
                archive_name = 'full_data'
                if calculation_name != '':
                    archive_name += '_%s' % calculation_name
                archive_name += '.rank%s' % (mpi.rank)
                print "about to dump all data in ", archive_name
                data.dump_all(suffix='-%s' % loop_index,
                              archive_name=archive_name)

            times.append((time(), ""))
            if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
            if mpi.is_master_node():
                self.print_timings(times)

            if (converged and loop_index > n_loops_min) or failed: break

        if not (self.after_it_is_done is None):
            self.after_it_is_done(
                data
            )  #notice that if we don't say data=data we can pass a method of data for after_it_is_done, such that here self=data

        if mpi.is_master_node():
            data.dump_all(suffix='-final')

        if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
        if converged:
            return 0
        else:
            if failed:
                return 2  #probably hitting AFM
            else:
                return 1  #maximum number of loops reached
Exemple #42
0
    def __call__ (self, Sigma, mu=0, eta=0, field=None, epsilon_hat=None, result=None, selected_blocks=()):
	"""
	- Computes:
	   result <- \[ \sum_k (\omega + \mu - field - t(k) - Sigma(k,\omega)) \]
           if result is None, it returns a new GF with the results.
           otherwise, result must be a GF, in which the calculation is done, and which is then returned.
           (this allows chain calculation: SK(mu = mu,Sigma = Sigma, result = G).total_density()
           which computes the sumK into G,  and returns the density of G.

        - Sigma can be a X, or a function k-> X or a function k,eps ->X where:
	    - k is expected to be a 1d-numpy array of size self.dim of float,
	      containing the k vector in the basis of the RBZ  (i.e.  -0.5< k_i <0.5)
            - eps is t(k)
	    - X is anything such that X[BlockName] can be added/subtracted to a GFBloc for BlockName in selected_blocks.
	      e.g. X can be a BlockGf(with at least the selected_blocks), or a dictionnary Blockname -> array
	      if the array has the same dimension as the GF blocks (for example to add a static Sigma).

        - field: Any k independant object to be added to the GF

        - epsilon_hat: a function of eps_k returning a matrix, the dimensions of Sigma

        - selected_blocks: The calculation is done with the SAME t(k) for all blocks. If this list is not None
	  only the blocks in this list are calculated.
	  e.g. G and Sigma have block indices 'up' and 'down'.
	       if selected_blocks ==None: 'up' and 'down' are calculated
	       if selected_blocks == ['up']: only 'up' is calculated. 'down' is 0.


        """

        assert selected_blocks == (), "selected_blocks not supported for now"
            #S = Sigma.view_selected_blocks(selected_blocks) if selected_blocks else Sigma
            #Gres = result if result else Sigma.copy()
            #G = Gres.view_selected_blocks(selected_blocks) if selected_blocks else Gres

        # check Sigma
        # case 1) Sigma is a BlockGf
        if isinstance(Sigma, BlockGf):
            model = Sigma
            Sigma_fnt = False
        # case 2) Sigma is a function returning a BlockGf
        else:
            assert callable(Sigma), "If Sigma is not a BlockGf it must be a function"
            Sigma_Nargs = len(inspect.getargspec(Sigma)[0])
            assert Sigma_Nargs <= 2, "Sigma must be a function of k or of k and epsilon"
            if Sigma_Nargs == 1:
                model = Sigma(self.bz_points[0])
            elif Sigma_Nargs == 2:
                model = Sigma(self.bz_points[0], self.hopping[0])
            Sigma_fnt = True

        G = result if result else model.copy()
        assert isinstance(G,BlockGf), "G must be a BlockGf"

        # check input
        assert self.orthogonal_basis, "Local_G: must be orthogonal. non ortho cases not checked."
        assert len(list(set([g.target_shape[0] for i,g in G]))) == 1
        assert self.bz_weights.shape[0] == self.n_kpts(), "Internal Error"
        no = list(set([g.target_shape[0] for i,g in G]))[0]

        # Initialize
        G.zero()
        tmp,tmp2 = G.copy(),G.copy()
        mupat = mu * numpy.identity(no, numpy.complex_)
        tmp << iOmega_n
        if field != None: tmp -= field
        if not Sigma_fnt: tmp -= Sigma  # substract Sigma once for all

        # Loop on k points...
        for w, k, eps_k in izip(*[mpi.slice_array(A) for A in [self.bz_weights, self.bz_points, self.hopping]]):

            eps_hat = epsilon_hat(eps_k) if epsilon_hat else eps_k
            tmp2 << tmp
            tmp2 -= tmp2.n_blocks * [eps_hat - mupat]

            if Sigma_fnt:
                if Sigma_Nargs == 1: tmp2 -= Sigma(k)
                elif Sigma_Nargs == 2: tmp2 -= Sigma(k,eps_k)

            tmp2.invert()
            tmp2 *= w
            G += tmp2

        G << mpi.all_reduce(mpi.world,G,lambda x,y: x+y)
        mpi.barrier()

        return G
        def run(data,
                no_fermionic_bath,
                symmetrize_quantities=True,
                trilex=False,
                n_w_f=2,
                n_w_b=2,
                n_cycles=20000,
                max_time=10 * 60,
                hartree_shift=0.0,
                solver_data_package=None):
            #------- run solver
            try:
                if solver_data_package is None:
                    solver_data_package = {}
                solver_data_package['solve_parameters'] = {}
                #solver_data_package['solve_parameters']['h_int'] = lambda: data.U_inf * n('up',0) * n('down',0)
                solver_data_package['solve_parameters']['U_inf'] = data.U_inf
                solver_data_package['solve_parameters']['hartree_shift'] = [
                    hartree_shift, hartree_shift
                ]
                solver_data_package['solve_parameters']['n_cycles'] = n_cycles
                solver_data_package['solve_parameters']['length_cycle'] = 1000
                solver_data_package['solve_parameters'][
                    'n_warmup_cycles'] = 1000
                solver_data_package['solve_parameters']['max_time'] = max_time
                solver_data_package['solve_parameters']['measure_nn'] = True
                solver_data_package['solve_parameters']['measure_nnw'] = True
                solver_data_package['solve_parameters'][
                    'measure_chipmt'] = True
                solver_data_package['solve_parameters']['measure_gt'] = False
                solver_data_package['solve_parameters']['measure_ft'] = False
                solver_data_package['solve_parameters'][
                    'measure_gw'] = not no_fermionic_bath
                solver_data_package['solve_parameters'][
                    'measure_fw'] = not no_fermionic_bath
                solver_data_package['solve_parameters']['measure_g2w'] = trilex
                solver_data_package['solve_parameters']['measure_f2w'] = False
                solver_data_package['solve_parameters']['measure_hist'] = True
                solver_data_package['solve_parameters'][
                    'measure_hist_composite'] = True
                solver_data_package['solve_parameters']['measure_nnt'] = False
                solver_data_package['solve_parameters'][
                    'move_group_into_spin_segment'] = not no_fermionic_bath
                solver_data_package['solve_parameters'][
                    'move_split_spin_segment'] = not no_fermionic_bath
                solver_data_package['solve_parameters'][
                    'move_swap_empty_lines'] = True
                solver_data_package['solve_parameters'][
                    'move_move'] = not no_fermionic_bath
                solver_data_package['solve_parameters'][
                    'move_insert_segment'] = not no_fermionic_bath
                solver_data_package['solve_parameters'][
                    'move_remove_segment'] = not no_fermionic_bath

                solver_data_package['solve_parameters']['n_w_f_vertex'] = n_w_f
                solver_data_package['solve_parameters']['n_w_b_vertex'] = n_w_b
                solver_data_package['solve_parameters'][
                    'keep_Jperp_negative'] = True
                print solver_data_package['solve_parameters']

                solver_data_package['G0_iw'] = data.solver.G0_iw
                solver_data_package['D0_iw'] = data.solver.D0_iw
                solver_data_package['Jperp_iw'] = data.solver.Jperp_iw

                solver_data_package['construct|run|exit'] = 1

                if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
                    solver_data_package = mpi.bcast(solver_data_package)
                print "about to run "
                #data.solver.solve( **(solver_data_package['solve_parameters'] + )
                data.solver.solve(
                    h_int=solver_data_package['solve_parameters']['U_inf'] *
                    n('up', 0) * n('down', 0),
                    hartree_shift=solver_data_package['solve_parameters']
                    ['hartree_shift'],
                    n_cycles=solver_data_package['solve_parameters']
                    ['n_cycles'],
                    length_cycle=solver_data_package['solve_parameters']
                    ['length_cycle'],
                    n_warmup_cycles=solver_data_package['solve_parameters']
                    ['n_warmup_cycles'],
                    max_time=solver_data_package['solve_parameters']
                    ['max_time'],
                    measure_nn=solver_data_package['solve_parameters']
                    ['measure_nn'],
                    measure_nnw=solver_data_package['solve_parameters']
                    ['measure_nnw'],
                    measure_chipmt=solver_data_package['solve_parameters']
                    ['measure_chipmt'],
                    measure_gt=solver_data_package['solve_parameters']
                    ['measure_gt'],
                    measure_ft=solver_data_package['solve_parameters']
                    ['measure_ft'],
                    measure_gw=solver_data_package['solve_parameters']
                    ['measure_gw'],
                    measure_fw=solver_data_package['solve_parameters']
                    ['measure_fw'],
                    measure_g2w=solver_data_package['solve_parameters']
                    ['measure_g2w'],
                    measure_f2w=solver_data_package['solve_parameters']
                    ['measure_f2w'],
                    measure_hist=solver_data_package['solve_parameters']
                    ['measure_hist'],
                    measure_hist_composite=solver_data_package[
                        'solve_parameters']['measure_hist_composite'],
                    measure_nnt=solver_data_package['solve_parameters']
                    ['measure_nnt'],
                    move_group_into_spin_segment=solver_data_package[
                        'solve_parameters']['move_group_into_spin_segment'],
                    move_split_spin_segment=solver_data_package[
                        'solve_parameters']['move_split_spin_segment'],
                    move_swap_empty_lines=solver_data_package[
                        'solve_parameters']['move_swap_empty_lines'],
                    move_move=solver_data_package['solve_parameters']
                    ['move_move'],
                    move_insert_segment=solver_data_package['solve_parameters']
                    ['move_insert_segment'],
                    move_remove_segment=solver_data_package['solve_parameters']
                    ['move_remove_segment'],
                    n_w_f_vertex=solver_data_package['solve_parameters']
                    ['n_w_f_vertex'],
                    n_w_b_vertex=solver_data_package['solve_parameters']
                    ['n_w_b_vertex'],
                    keep_Jperp_negative=solver_data_package['solve_parameters']
                    ['keep_Jperp_negative'])

                data.G_imp_iw << data.solver.G_iw

                get_Sigma_from_G_and_G0 = False
                for U in data.fermionic_struct.keys():
                    if numpy.any(numpy.isnan(
                            data.G_imp_iw[U].data[:, 0, 0])) or numpy.any(
                                numpy.isnan(data.solver.F_iw[U].data[:, 0,
                                                                     0])):
                        if numpy.any(
                                numpy.isnan(data.G_imp_iw[U].data[:, 0, 0])):
                            print "[Node", mpi.rank, "]", " nan in F_imp and G_imp!!! exiting to system..."
                            if mpi.is_master_node():
                                data.dump_all(archive_name="black_box_nan",
                                              suffix='')
                                cthyb.dump(data.solver,
                                           archive_name="black_box_nan",
                                           suffix='')
                            if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
                            solver_data_package['construct|run|exit'] = 2
                            if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1):
                                solver_data_package = mpi.bcast(
                                    solver_data_package)
                            quit()
                        else:
                            print "[Node", mpi.rank, "]", " nan in F but not in G!! will be calculating Sigma from G and G0"
                            get_Sigma_from_G_and_G0 = True

                if symmetrize_quantities:
                    symmetrize_blockgf(data.G_imp_iw, data.fermionic_struct)
                    symmetrize_blockgf(data.solver.F_iw, data.fermionic_struct)

                if not get_Sigma_from_G_and_G0:
                    extract_Sigma_from_F_and_G(
                        data.Sigma_imp_iw, data.solver.F_iw, data.G_imp_iw
                    )  #!!!! this thing fails when the S S boson is not SU(2) symmetric
                else:
                    extract_Sigma_from_G0_and_G(data.Sigma_imp_iw,
                                                data.solver.G0_iw,
                                                data.G_imp_iw)
                data.get_Sz(
                )  #moved these in impurity!!!!! maybe not the best idea
                data.get_chi_imp()

            except Exception as e:
                import traceback, os.path, sys
                top = traceback.extract_stack()[-1]
                if mpi.is_master_node():
                    data.dump_impurity_input('black_box', '')
                raise Exception(
                    '%s, %s, %s \t %s ' %
                    (type(e).__name__, os.path.basename(top[0]), top[1], e))
Exemple #44
0
def pm_tUVJ_calculation( T, mutildes=[0.0], 
                            ts=[0.25], t_dispersion = epsilonk_square,
                            Us = [1.0], decouple_U = False,
                            Vs = [0.2], V_dispersion = None, 
                            Js = [0.05], J_dispersion = None,                            
                            n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]],
                            use_cthyb=False, n_cycles=100000, max_time=10*60,
                            initial_guess_archive_name = '', suffix=''):
  if mpi.is_master_node(): print "WELCOME TO PM tUVJ!"

  bosonic_struct = {'0': [0], 'z': [0]}    
  fermionic_struct = {'up': [0], 'down': [0]}

  beta = 1.0/T 
  
  n_iw = int(((20.0*beta)/math.pi-1.0)/2.0)
  n_tau = int(n_iw*pi)
  if (V_dispersion is None) and (J_dispersion is None):
    n_q = 1
  else:
    n_q = 12

  n_k = n_q

  #init solver
  if use_cthyb:
    solver = Solver( beta = beta,
                     gf_struct = fermionic_struct, 
                     n_tau_k = n_tau,
                     n_tau_g = 10000,
                     n_tau_delta = 10000,
                     n_tau_nn = 4*n_tau,
                     n_w_b_nn = n_iw,
                     n_w = n_iw )
  else:
    solver = SolverCore( beta = beta, 
                gf_struct = fermionic_struct,

                n_iw = n_iw,  
                n_tau_g0  = 10001,

                n_tau_dynamical_interactions = n_iw*4,
                n_iw_dynamical_interactions = n_iw,

                n_tau_nnt = n_iw*2+1, 

                n_tau_g2t = 13,
                n_w_f_g2w = 6,
                n_w_b_g2w = 6,

                n_tau_M4t = 25,
                n_w_f_M4w = 12,
                n_w_b_M4w = 12
              )


  #init data, assign the solver to it
  dt = full_data( n_iw = n_iw, 
                  n_k = n_k,
                  n_q = n_q, 
                  beta = beta, 
                  solver = solver,
                  bosonic_struct = bosonic_struct,
                  fermionic_struct = fermionic_struct,
                  archive_name="so_far_nothing_you_shouldnt_see_this_file" )

  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = dt.P_imp_iw,
                            accuracy=1e-3, 
                            struct=bosonic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_P_imp' ),
                 converger( monitored_quantity = dt.G_imp_iw,
                            accuracy=1e-3, 
                            struct=fermionic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_G_imp'     ) ]

  mixers = [ mixer( mixed_quantity = dt.P_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf ),
             mixer( mixed_quantity = dt.Sigma_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf)  ]

  err = 0
  #initial guess
  
  ps = itertools.product(mutildes,ts,Us,Vs,Js)

  counter = 0
  for p in ps:    
    #name stuff to avoid confusion   
    mutilde = p[0]
    t = p[1]
    U = p[2]
    V = p[3] 
    J = p[4]
  
    dt.archive_name="edmft.mutilde%s.t%s.U%s.V%s.J%s.T%s.h5"%(mutilde,t,U,V,J,T)
    for conv in convergers:
      conv.archive_name = dt.archive_name

    convergers[0].struct = copy.deepcopy(bosonic_struct)
    if J==0.0: del convergers[0].struct['z'] #no need to monitor quantities that are not involved in the calculation
    if V==0.0: del convergers[0].struct['0']

    if not ((V_dispersion is None) and (J_dispersion is None)): #this is optional since we're using semi-analytical summation and evaluate chi_loc directly from P
      dt.fill_in_qs()
      if decouple_U:
        dt.fill_in_Jq( {'0': lambda kx,ky: V_dispersion(kx,ky,J=V)+U, 'z':  partial(J_dispersion, J=J)} )  
      else:
        dt.fill_in_Jq( {'0': partial(V_dispersion, J=V), 'z':  partial(J_dispersion, J=J)} )  

      dt.fill_in_ks()
      dt.fill_in_epsilonk(dict.fromkeys(['up','down'], partial(t_dispersion, t=t)))

      if mpi.is_master_node():
        dt.dump_non_interacting()

    preset = edmft_tUVJ_pm(mutilde=mutilde, U=U, V=V, J=J)
    preset.cautionary.get_safe_values(dt.Jq, dt.bosonic_struct, n_q, n_q)
    if mpi.is_master_node():
      print "U = ",U," V= ",V, "J= ",J," mutilde= ",mutilde
      print "cautionary safe values: ",preset.cautionary.safe_value  
    
    impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, n_cycles=n_cycles, max_time=max_time )
    dt.dump_solver = solvers.cthyb.dump
    if not use_cthyb:
      imp = partial( solvers.ctint.run, n_cycles=n_cycles)
      dt.dump_solver = solvers.ctint.dump

    #init the dmft_loop 
    dmft = dmft_loop(  cautionary       = preset.cautionary, 
                       lattice          = preset.lattice,
                       pre_impurity     = preset.pre_impurity, 
                       impurity         = impurity, 
                       post_impurity    = partial( preset.post_impurity ),
                       selfenergy       = preset.selfenergy, 
                       convergers       = convergers,
                       mixers           = mixers,
                       after_it_is_done = preset.after_it_is_done  )

    
    if counter==0: #do this only once!      
      dt.mus['up'] = dt.mus['down'] = mutilde+U/2.0
      #safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value['0']*0.8, P_imp=dt.P_imp_iw['0'])
      #safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value['z']*0.8, P_imp=dt.P_imp_iw['z'])
      dt.Sigma_imp_iw << U/2.0 #starting from half-filled hartree-fock self-energy
      dt.P_imp_iw << 0.0
    
    if initial_guess_archive_name!='':
      dt.load_initial_guess_from_file(initial_guess_archive_name, suffix)
      #dt.load_initial_guess_from_file("/home/jvucicev/TRIQS/run/sc_scripts/Archive_Vdecoupling/edmft.mutilde0.0.t0.25.U3.0.V2.0.J0.0.T0.01.h5")
   
    mpi.barrier()
    #run dmft!-------------
    err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_non_loc=False)
    counter += 1
  return err
    def run(self):
        """
        """
        mpi.barrier()
        if mpi.size==1 : # single machine. Avoid the fork
            while not(self.finished()):
                n = self.next()
                if n!=None : 
                    self.treate(self.the_function(n),0)
            return

        # Code for multiprocessor machines
        RequestList,pid = [],0   # the pid of the child on the master
        node_running,node_stopped= mpi.size*[False],mpi.size*[False]

        if mpi.rank==0 :
          while not(self.finished()) or pid or [n for n in node_running if n] != [] :
              # Treat the request which have self.finished
              def keep_request(r) :
                  #if not(mpi.test(r)) :  return True
                  #if r.message !=None : self.treate(*r.message)
                  #node_running[r.status.source] = False
                  T = r.test()
                  if T is None :  return True
                  value = T[0]
                  if value !=None : self.treate(*value)
                  node_running[T[1].source] = False
                  return False
              RequestList = filter(keep_request,RequestList)
              # send new calculation to the nodes or "stop" them
              for node in [ n for n in range(1,mpi.size) if not(node_running[n] or node_stopped[n]) ] :
                  #open('tmp','a').write("master : comm to node %d %s\n"%(node,self.finished()))
                  mpi.send(self.finished(),node)
                  if not(self.finished()) :
                      mpi.send(self.next(),node) # send the data for the computation
                      node_running[node] = True
                      RequestList.append(mpi.irecv(node)) #Post the receive
                  else :
                      node_stopped[node] = True

              # Look if the child process on the master has self.finished.
              if not(pid) or os.waitpid(pid,os.WNOHANG) :
                  if pid :
                      RR = cPickle.load(open("res_master",'r'))
                      if RR != None : self.treate(*RR)
                  if not(self.finished()) :
                      pid=os.fork();
                      currently_calculated_by_master = self.next()
                      if pid==0 :  # we are on the child
                          if currently_calculated_by_master :
                              res = self.the_function(currently_calculated_by_master)
                          else:
                              res = None
                          cPickle.dump((res,mpi.rank),open('res_master','w'))
                          os._exit(0) # Cf python doc. Used for child only.
                  else : pid=0
              if (pid): time.sleep(self.SleepTime) # so that most of the time is for the actual calculation on the master

        else : # not master
            while not(mpi.recv(0)) :  # master will first send a finished flag
                omega = mpi.recv(0)
                if omega ==None :
                    res = None
                else :
                    res = self.the_function(omega)
                mpi.send((res,mpi.rank),0)
                
        mpi.barrier()
Exemple #46
0
def pm_hubbard_GW_calculation( T, mutildes=[0.0], 
                            ts=[0.25], t_dispersion = epsilonk_square,
                            Us = [1.0], alpha=2.0/3.0, 
                            n_ks = [6, 36, 64],
                            n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]],
                            trilex = False,
                            use_cthyb=True, n_cycles=100000, max_time=10*60,
                            initial_guess_archive_name = '', suffix=''):
  if mpi.is_master_node(): print "WELCOME TO PM hubbard GW calculation!"

  bosonic_struct = {'0': [0], '1': [0]}    
  if alpha==2.0/3.0:
    del bosonic_struct['1']
  if alpha==1.0/3.0:
    del bosonic_struct['0']

  fermionic_struct = {'up': [0], 'down': [0]}

  beta = 1.0/T 
  
  n_iw = int(((20.0*beta)/math.pi-1.0)/2.0)
  if mpi.is_master_node():
    print "PM HUBBARD GW: n_iw: ",n_iw
  n_tau = int(n_iw*pi)

  n_q = n_ks[0]
  n_k = n_q

  #init solver
  if use_cthyb:
    solver = Solver( beta = beta,
                     gf_struct = fermionic_struct, 
                     n_tau_k = n_tau,
                     n_tau_g = 10000,
                     n_tau_delta = 10000,
                     n_tau_nn = 4*n_tau,
                     n_w_b_nn = n_iw,
                     n_w = n_iw )
  else:
    solver = SolverCore( beta = beta, 
                gf_struct = fermionic_struct,

                n_iw = n_iw,  
                n_tau_g0  = 10001,

                n_tau_dynamical_interactions = n_iw*4,
                n_iw_dynamical_interactions = n_iw,

                n_tau_nnt = n_iw*2+1, 

                n_tau_g2t = 13,
                n_w_f_g2w = 6,
                n_w_b_g2w = 6,

                n_tau_M4t = 25,
                n_w_f_M4w = 12,
                n_w_b_M4w = 12
              )


  #init data, assign the solver to it
  dt = GW_data( n_iw = n_iw, 
                  n_k = n_k,
                  n_q = n_q, 
                  beta = beta, 
                  solver = solver,
                  bosonic_struct = bosonic_struct,
                  fermionic_struct = fermionic_struct,
                  archive_name="so_far_nothing_you_shouldnt_see_this_file" )
  if trilex:
    dt.__class__=trilex_data
    dt.promote(dt.n_iw/2, dt.n_iw/2)

  #init convergence and cautionary measures
  convergers = [ converger( monitored_quantity = dt.P_imp_iw,
                            accuracy=1e-3, 
                            struct=bosonic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_P_imp' ),
                 converger( monitored_quantity = dt.G_imp_iw,
                            accuracy=1e-3, 
                            struct=fermionic_struct, 
                            archive_name=dt.archive_name,
                            h5key = 'diffs_G_imp'     ) ]

  mixers = [ mixer( mixed_quantity = dt.P_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf ),
             mixer( mixed_quantity = dt.Sigma_imp_iw,
                    rules=rules,
                    func=mixer.mix_gf)  ]

  err = 0
  #initial guess
  
  ps = itertools.product(mutildes,ts,Us,n_ks)

  counter = 0
  for p in ps:    
    #name stuff to avoid confusion   
    mutilde = p[0]
    t = p[1]
    U = p[2]
    nk = p[3]
    dt.change_ks(IBZ.k_grid(nk))

    if trilex:
      dt.archive_name="trilex.mutilde%s.t%s.U%s.alpha%s.T%s.nk%s.h5"%(mutilde,t,U,alpha,T,nk )
    else:
      dt.archive_name="GW.mutilde%s.t%s.U%s.alpha%s.T%s.nk%s.h5"%(mutilde,t,U,alpha,T,nk)
    for conv in convergers:
      conv.archive_name = dt.archive_name

    Uch = (3.0*alpha-1.0)*U
    Usp = (alpha-2.0/3.0)*U
    vks = {'0': lambda kx,ky: Uch, '1': lambda kx,ky: Usp}
    if alpha==2.0/3.0:
      del vks['1']
    if alpha==1.0/3.0:
      del vks['0']
    
    dt.fill_in_Jq( vks )  
    dt.fill_in_epsilonk(dict.fromkeys(['up','down'], partial(t_dispersion, t=t)))

    if trilex: 
      preset = trilex_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct)
    else:
      preset = GW_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct)

    if mpi.is_master_node():
      print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," mutilde= ",mutilde
      #print "cautionary safe values: ",preset.cautionary.safe_value    

    if trilex:
      n_w_f=dt.n_iw_f
      n_w_b=dt.n_iw_b
    else:
      n_w_f=2
      n_w_b=2

    impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, 
                                           trilex=trilex, n_w_f=n_w_f, n_w_b=n_w_b,
                                           n_cycles=n_cycles, max_time=max_time )
    dt.dump_solver = solvers.cthyb.dump
    if not use_cthyb:
      imp = partial( solvers.ctint.run, n_cycles=n_cycles)
      dt.dump_solver = solvers.ctint.dump

    #init the dmft_loop 
    dmft = dmft_loop(  cautionary       = preset.cautionary, 
                       lattice          = preset.lattice,
                       pre_impurity     = preset.pre_impurity, 
                       impurity         = impurity, 
                       post_impurity    = partial( preset.post_impurity ),
                       selfenergy       = preset.selfenergy, 
                       convergers       = convergers,
                       mixers           = mixers,
                       after_it_is_done = preset.after_it_is_done )

    #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) )  
    if counter==0: #do this only once!         
      dt.mus['up'] = dt.mus['down'] = mutilde+U/2.0
      dt.P_imp_iw << 0.0
      #for A in bosonic_struct.keys():
      #  if preset.cautionary.safe_value[A] < 0.0:
      #    safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value[A]*0.95, P_imp=dt.P_imp_iw[A])
      dt.Sigma_imp_iw << U/2.0 + mutilde #making sure that in the first iteration the impurity problem is half-filled

    
    if initial_guess_archive_name!='':
      dt.load_initial_guess_from_file(initial_guess_archive_name, suffix)
      #dt.load_initial_guess_from_file("/home/jvucicev/TRIQS/run/sc_scripts/Archive_Vdecoupling/edmft.mutilde0.0.t0.25.U3.0.V2.0.J0.0.T0.01.h5")
   
    mpi.barrier()
    #run dmft!-------------
    err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min,  print_three_leg=1, print_non_local=1 )
    counter += 1
  return err
Exemple #47
0
    def calc_density_correction(self,filename = 'dens_mat.dat'):
        """ Calculates the density correction in order to feed it back to the DFT calculations."""

        
        assert (type(filename)==StringType), "filename has to be a string!"

        ntoi = self.names_to_ind[self.SO]
        bln = self.block_names[self.SO]

        # Set up deltaN:
        deltaN = {}
        for ib in bln:
            deltaN[ib] = [ numpy.zeros( [self.n_orbitals[ik,ntoi[ib]],self.n_orbitals[ik,ntoi[ib]]], numpy.complex_) for ik in range(self.n_k)]

        ikarray=numpy.array(range(self.n_k))
        
        dens = {}
        for ib in bln:
            dens[ib] = 0.0
 
        for ik in mpi.slice_array(ikarray):
        
            S = self.lattice_gf_matsubara(ik=ik,mu=self.chemical_potential)
            for sig,g in S:
                deltaN[sig][ik] = S[sig].density()
                dens[sig] += self.bz_weights[ik] * S[sig].total_density()
            
                

        #put mpi Barrier:
        for sig in deltaN:
            for ik in range(self.n_k):
                deltaN[sig][ik] = mpi.all_reduce(mpi.world,deltaN[sig][ik],lambda x,y : x+y)
            dens[sig] = mpi.all_reduce(mpi.world,dens[sig],lambda x,y : x+y)
        mpi.barrier()

       
        # now save to file:
        if (mpi.is_master_node()):
            if (self.SP==0):
                f=open(filename,'w')
            else:
                f=open(filename+'up','w')
                f1=open(filename+'dn','w')
            # write chemical potential (in Rydberg):
            f.write("%.14f\n"%(self.chemical_potential/self.energy_unit))
            if (self.SP!=0): f1.write("%.14f\n"%(self.chemical_potential/self.energy_unit))
            # write beta in ryderg-1
            f.write("%.14f\n"%(S.mesh.beta*self.energy_unit))
            if (self.SP!=0): f1.write("%.14f\n"%(S.mesh.beta*self.energy_unit))
            if (self.SP==0):
                for ik in range(self.n_k):
                    f.write("%s\n"%self.n_orbitals[ik,0])
                    for inu in range(self.n_orbitals[ik,0]):
                        for imu in range(self.n_orbitals[ik,0]):
                            valre = (deltaN['up'][ik][inu,imu].real + deltaN['down'][ik][inu,imu].real) / 2.0
                            valim = (deltaN['up'][ik][inu,imu].imag + deltaN['down'][ik][inu,imu].imag) / 2.0
                            f.write("%.14f  %.14f "%(valre,valim))
                        f.write("\n")
                    f.write("\n")
                f.close()
            elif ((self.SP==1)and(self.SO==0)):
                for ik in range(self.n_k):
                    f.write("%s\n"%self.n_orbitals[ik,0])
                    for inu in range(self.n_orbitals[ik,0]):
                        for imu in range(self.n_orbitals[ik,0]):
                            f.write("%.14f  %.14f "%(deltaN['up'][ik][inu,imu].real,deltaN['up'][ik][inu,imu].imag))
                        f.write("\n")
                    f.write("\n")
                f.close()
                for ik in range(self.n_k):
                    f1.write("%s\n"%self.n_orbitals[ik,1])
                    for inu in range(self.n_orbitals[ik,1]):
                        for imu in range(self.n_orbitals[ik,1]):
                            f1.write("%.14f  %.14f "%(deltaN['down'][ik][inu,imu].real,deltaN['down'][ik][inu,imu].imag))
                        f1.write("\n")
                    f1.write("\n")
                f1.close()
            else:
                for ik in range(self.n_k):
                    f.write("%s\n"%self.n_orbitals[ik,0])
                    for inu in range(self.n_orbitals[ik,0]):
                        for imu in range(self.n_orbitals[ik,0]):
                            f.write("%.14f  %.14f "%(deltaN['ud'][ik][inu,imu].real,deltaN['ud'][ik][inu,imu].imag))
                        f.write("\n")
                    f.write("\n")
                f.close()
                for ik in range(self.n_k):
                    f1.write("%s\n"%self.n_orbitals[ik,0])
                    for inu in range(self.n_orbitals[ik,0]):
                        for imu in range(self.n_orbitals[ik,0]):
                            f1.write("%.14f  %.14f "%(deltaN['ud'][ik][inu,imu].real,deltaN['ud'][ik][inu,imu].imag))
                        f1.write("\n")
                    f1.write("\n")
                f1.close()
                                                            

        return deltaN, dens
Exemple #48
0
def get_chi0_wnk(g_wk, nw=1, nwf=None):

    fmesh = g_wk.mesh.components[0]
    kmesh = g_wk.mesh.components[1]

    if nwf is None:
        nwf = len(fmesh) / 2

    mpi.barrier()
    mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 1, 2)][0, 0]))
    n = np.sum(g_wk.data) / len(kmesh)
    mpi.report('n ' + str(n))
    mpi.barrier()

    mpi.report('--> g_wr from g_wk')
    g_wr = fourier_wk_to_wr(g_wk)

    mpi.barrier()
    mpi.report('g_wr ' + str(g_wr[Idx(2), Idx(0, 1, 2)][0, 0]))
    n_r = np.sum(g_wr.data, axis=0)[0]
    mpi.report('n_r=0 ' + str(n_r[0, 0]))
    mpi.barrier()

    mpi.report('--> chi0_wnr from g_wr')
    chi0_wnr = chi0r_from_gr_PH(nw=nw, nnu=nwf, gr=g_wr)

    #mpi.report('--> chi0_wnr from g_wr (nompi)')
    #chi0_wnr_nompi = chi0r_from_gr_PH_nompi(nw=nw, nnu=nwf, gr=g_wr)

    del g_wr

    #abs_diff = np.abs(chi0_wnr.data - chi0_wnr_nompi.data)
    #mpi.report('shape = ' + str(abs_diff.shape))
    #idx = np.argmax(abs_diff)
    #mpi.report('argmax = ' + str(idx))
    #diff = np.max(abs_diff)
    #mpi.report('diff = %6.6f' % diff)
    #del chi0_wnr
    #chi0_wnr = chi0_wnr_nompi

    #exit()

    mpi.barrier()
    mpi.report('chi0_wnr ' +
               str(chi0_wnr[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    chi0_r0 = np.sum(chi0_wnr[:, :, Idx(0, 0, 0)].data)
    mpi.report('chi0_r0 ' + str(chi0_r0))
    mpi.barrier()

    mpi.report('--> chi0_wnk from chi0_wnr')
    chi0_wnk = chi0q_from_chi0r(chi0_wnr)

    del chi0_wnr

    mpi.barrier()
    mpi.report('chi0_wnk ' +
               str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    chi0 = np.sum(chi0_wnk.data) / len(kmesh)
    mpi.report('chi0 = ' + str(chi0))
    mpi.barrier()

    #if mpi.is_master_node():
    if False:
        from triqs_tprf.ParameterCollection import ParameterCollection
        p = ParameterCollection()
        p.g_wk = g_wk
        p.g_wr = g_wr
        p.chi0_wnr = chi0_wnr
        p.chi0_wnk = chi0_wnk

        print '--> Writing debug info for BSE'
        with HDFArchive('data_debug_bse.h5', 'w') as arch:
            arch['p'] = p

    mpi.barrier()

    return chi0_wnk
Exemple #49
0
    def simple_point_dens_mat(self):


        ntoi = self.names_to_ind[self.SO]
        bln = self.block_names[self.SO]

        MMat = [numpy.zeros( [self.n_orbitals[0,ntoi[bl]],self.n_orbitals[0,ntoi[bl]]], numpy.complex_) for bl in bln] 

        dens_mat = [ {} for icrsh in xrange(self.n_corr_shells)]
        for icrsh in xrange(self.n_corr_shells):
            for bl in self.block_names[self.corr_shells[icrsh][4]]:
                dens_mat[icrsh][bl] = numpy.zeros([self.corr_shells[icrsh][3],self.corr_shells[icrsh][3]], numpy.complex_)

        ikarray=numpy.array(range(self.n_k))
          
        for ik in mpi.slice_array(ikarray):
            
            unchangedsize = all( [ self.n_orbitals[ik,ntoi[bln[ib]]]==len(MMat[ib]) 
                                   for ib in range(self.n_spin_blocks_gf[self.SO]) ] )
               
            if (not unchangedsize):
                MMat = [numpy.zeros( [self.n_orbitals[ik,ntoi[bl]],self.n_orbitals[ik,ntoi[bl]]], numpy.complex_) for bl in bln] 

            for ibl,bl in enumerate(bln):
                ind = ntoi[bl]
                for inu in range(self.n_orbitals[ik,ind]):
                    if ( (self.hopping[ik,ind,inu,inu]-self.h_field*(1-2*ibl)) < 0.0): 
                        MMat[ibl][inu,inu] = 1.0
                    else:
                        MMat[ibl][inu,inu] = 0.0 


            for icrsh in range(self.n_corr_shells):
                for ibn,bn in enumerate(self.block_names[self.corr_shells[icrsh][4]]):
                    isp = self.names_to_ind[self.corr_shells[icrsh][4]][bn]
                    dim = self.corr_shells[icrsh][3]
                    n_orb = self.n_orbitals[ik,isp]
                    
                    #print ik, bn, isp
                    dens_mat[icrsh][bn] += self.bz_weights[ik] * numpy.dot( numpy.dot(self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb],MMat[ibn]) , 
                                                                           self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb].transpose().conjugate() )

        # get data from nodes:
        for icrsh in range(self.n_corr_shells):
            for sig in dens_mat[icrsh]:
                dens_mat[icrsh][sig] = mpi.all_reduce(mpi.world,dens_mat[icrsh][sig],lambda x,y : x+y)
        mpi.barrier()

                    
        if (self.symm_op!=0): dens_mat = self.Symm_corr.symmetrize(dens_mat)

        # Rotate to local coordinate system:
        if (self.use_rotations):
            for icrsh in xrange(self.n_corr_shells):
                for bn in dens_mat[icrsh]:
                    if (self.rot_mat_time_inv[icrsh]==1): dens_mat[icrsh][bn] = dens_mat[icrsh][bn].conjugate()
                    dens_mat[icrsh][bn] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),dens_mat[icrsh][bn]) , 
                                                    self.rot_mat[icrsh])
                

        return dens_mat
Exemple #50
0
def nested_edmft_calculation( clusters, nested_struct_archive_name = None, flexible_Gweiss=False, sign=-1, sign_up_to=2, use_Gweiss_causal_cautionary = False,
                              freeze_Uweiss = False, no_lattice = False,
                              Us = [1.0], decoupling = 'ising', decoupling_alpha = 0.5,
                              Ts = [0.125], 
                              ns = [0.5], fixed_n = True,
                              mutildes = [0.0],
                              dispersion = lambda kx, ky: epsilonk_square(kx,ky, 0.25), ph_symmetry = True,                              
                              n_ks = [64], n_k_automatic = False, n_k_rules = [[0.06, 32],[0.03, 48],[0.005, 64],[0.00, 96]],
                              w_cutoff = 50.0,
                              min_its = 5, max_its=25, 
                              mix_GWlatt = False, rules = [[0, 0.5], [6, 0.2], [12, 0.65]],              
                              mix_Uweiss = False, Uweiss_mix_rules = [[0, 0.5], [6, 0.2], [12, 0.65]],                       
                              use_cthyb = False,
                              alpha = 0.5, delta = 0.1,  automatic_alpha_and_delta = False,
                              n_cycles=10000000, 
                              max_time_rules= [ [1, 5*60], [2, 20*60], [4, 80*60], [8, 200*60], [16,400*60] ], time_rules_automatic=False, exponent = 0.7, overall_prefactor=4.0, no_timing = False,
                              accuracy = 1e-4, 
                              solver_data_package = None,
                              print_current = 1,
                              insulating_initial = False,
                              Wilson_bath_initial = False,
                              bath_initial = False,
                              selfenergy_initial = False,  
                              initial_guess_archive_name = '', suffix=''):

  if mpi.is_master_node():
    print "WELCOME TO nested edmft calculation!"
    if n_k_automatic: print "n_k automatic!!!"
  if len(n_ks)==0 and n_k_automatic: n_ks=[0]

  if use_cthyb:
    assert False, "cthyb usage not implemented"
    solver_class = solvers.cthyb
  else:
    solver_class = solvers.ctint

  fermionic_struct = {'up': [0]}
  bosonic_struct = {'0': [0], '1': [0]}   
  if decoupling=='ising':
    if decoupling_alpha==1.0:
      del bosonic_struct['1']
    if decoupling_alpha==0.0:
      del bosonic_struct['0']
  elif decoupling=='heisenberg':
    if decoupling_alpha==2.0/3.0:
      del bosonic_struct['1']
    if decoupling_alpha==1.0/3.0:
      del bosonic_struct['0']


  if mpi.is_master_node(): print "nested structure: "
  if not (nested_struct_archive_name is None):
    try:
      nested_scheme = nested_struct.from_file(nested_struct_archive_name)
      if mpi.is_master_node(): print "nested structure loaded from file",nested_struct_archive_name 
    except:  
      nested_scheme = nested_struct(clusters)
      nested_scheme.print_to_file(nested_struct_archive_name) 
      if mpi.is_master_node(): print "nested structure printed to file",nested_struct_archive_name 
  else:
    nested_scheme = nested_struct(clusters)
  if mpi.is_master_node(): print nested_scheme.get_tex()

  impurity_struct = nested_scheme.get_impurity_struct()

  if not time_rules_automatic:
    max_times = {}
    for C in impurity_struct:
      for r in max_time_rules:
        if r[0]<=len(impurity_struct[C]):
          max_times[C] = r[1]
    if mpi.is_master_node(): print "max_times from rules: ",max_times


  beta = 1.0/Ts[0] 
  
  n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0)
  if mpi.is_master_node():
    print "PM HUBBARD GW: n_iw: ",n_iw

  if not n_k_automatic:
    n_k = n_ks[0]
    print "n_k = ", n_k
  else:
    n_k = n_k_from_rules(Ts[0], n_k_rules)
    #if mpi.is_master_node(): print "n_k automatic!!!"

  dt = nested_edmft_data(  n_iw = n_iw, 
                     n_k = n_k, 
                     beta = beta, 
                     impurity_struct = impurity_struct,
                     fermionic_struct = fermionic_struct,
                     bosonic_struct = bosonic_struct,
                     archive_name="so_far_nothing_you_shouldnt_see_this_file"  )

  if fixed_n:
    ps = itertools.product(n_ks,ns,Us,Ts)
  else:
    ps = itertools.product(n_ks,mutildes,Us,Ts)

  counter = 0
  old_nk = n_k
  old_beta = beta

  for p in ps:    
    #name stuff to avoid confusion   
    nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules) )
    if fixed_n:
      n = p[1]
    else:
      mutilde = p[1]
      n = None
    U = p[2]
    T = p[3] 
    beta = 1.0/T

    if nk!=old_nk and (not n_k_automatic):
      assert False, "changing n_k not implemented" 
      dt.change_ks(IBZ.k_grid(nk))

    if beta!=old_beta:
      assert False, "changing beta not implemented"
      n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0)
      if n_k_automatic:
        nk = n_k_from_rules(T, n_k_rules)
        if nk != old_nk: 
          dt.change_ks(IBZ.k_grid(nk))
      dt.change_beta(beta, n_iw)
 
    old_beta = beta
    old_nk = nk
    nested_scheme.set_nk(nk) #don't forget this part

    filename = "result"
    if len(n_ks)>1 and (not n_k_automatic):
      filename += ".nk%s"%nk
    if len(ns)>1 and fixed_n: 
      filename += ".n%s"%n
    if len(mutildes)>1 and not fixed_n:
      filename += ".mutilde%s"%mutilde      
    if len(Us)>1: filename += ".U%s"%U
    if len(Ts)>1: filename += ".T%.4f"%T
    filename += ".h5"
    dt.archive_name = filename

    if mpi.is_master_node():
      if fixed_n:
        print "Working: U: %s T %s n: %s n_k: %s n_iw: %s"%(U,n,T,nk,n_iw)
      else:
        print "Working: U: %s T %s mutilde: %s n_k: %s n_iw: %s"%(U,mutilde,T,nk,n_iw)

    if mpi.is_master_node():
      print "about to fill dispersion. ph-symmetry: ",ph_symmetry 
    for key in dt.fermionic_struct.keys():
      for kxi in range(dt.n_k):
        for kyi in range(dt.n_k):
          dt.epsilonk[key][kxi,kyi] = dispersion(dt.ks[kxi], dt.ks[kyi])
    if decoupling=='ising':
      for key in dt.bosonic_struct.keys():
        if key=='0': dt.Jq[key][:,:]=decoupling_alpha*U
        if key=='1': dt.Jq[key][:,:]=(decoupling_alpha-1)*U
    elif decoupling=='heisenberg': 
        if key=='0': dt.Jq[key][:,:]=(3.0*decoupling_alpha-1.0)*U
        if key=='1': dt.Jq[key][:,:]=(decoupling_alpha-2.0/3.0)*U
    else: assert False, "unknown decoupling scheme"

    prepare_nested_edmft( dt, nested_scheme, solver_class )

    solver_class.initialize_solvers( dt, solver_data_package, bosonic_measures=True )
 

    if no_timing:
      max_times = {}
      for C in dt.impurity_struct.keys():
        max_times[C] = -1
      if mpi.is_master_node(): print "no_timing! solvers will run until they perform all the mc steps",max_times        

    if time_rules_automatic and (not no_timing): 
      max_times = {}
      for C in dt.impurity_struct.keys():
        Nc = len(dt.impurity_struct[C])
        pref = ((dt.beta/8.0)*U*Nc)**exponent #**1.2
        print C
        print "Nc: ",Nc,
        print "U: ", U,  
        print "beta: ",dt.beta,
        print "pref: ",pref 
        max_times[C] = int(overall_prefactor*pref*5*60)
      if mpi.is_master_node(): print "max times automatic: ",max_times        

    identical_pairs_Sigma = nested_scheme.get_identical_pairs()
    identical_pairs_G = nested_scheme.get_identical_pairs_for_G()
    identical_pairs_G_ai = nested_scheme.get_identical_pairs_for_G(across_imps=True)
 
    def do_print(*args):
      for x in args: print x,
      print "" 

    used_Cs = []

    actions =[  generic_action(  name = "lattice",
                    main = ( (lambda data: nested_edmft_mains.lattice(data, n=n, ph_symmetry=ph_symmetry, accepted_mu_range=[-2.0,2.0]))
                             if (not no_lattice) else
                             (lambda data: [ data.copy_imp_to_latt(used_Cs[0]),
                                             do_print("just copying imp",used_Cs[0],"->latt, no_lattice! Gijw000:",data.Gijw['up'][0,0,0],
                                                      [ "Wijnu_"+A+ "000:"+str(data.Wijnu['0'][0,0,0]) for A in data.Wijnu.keys()] ) ]) #TODO generalize for any size cluster
                           ),
                           
                    mixers = [], cautionaries = [], allowed_errors = [],    
                    printout = lambda data, it: ( [data.dump_general( quantities = ['Gkw','Gijw','Wqnu','Wijnu'], suffix='-current' ), data.dump_scalar(suffix='-current')
                                                  ] if ((it+1) % print_current==0) else None 
                                                )
                              ),
                generic_action(  name = "pre_impurity",
                    main = lambda data: nested_edmft_mains.pre_impurity(data, freeze_Uweiss = freeze_Uweiss, Cs= used_Cs),                       
                    mixers = [], cautionaries = [], allowed_errors = [],        
                    printout = lambda data, it: ( data.dump_general( quantities = ['Gweiss_iw','Uweiss_iw','Uweiss_dyn_iw'], suffix='-current' ) )
                              ),
                generic_action(  name = "impurity",
                    main = (lambda data: nested_mains.impurity(data, U, symmetrize_quantities = True, alpha=alpha, delta=delta, automatic_alpha_and_delta = automatic_alpha_and_delta, 
                                                               n_cycles=n_cycles, max_times = max_times, solver_data_package = solver_data_package, bosonic_measures=not freeze_Uweiss, Cs= used_Cs ))
                           if (not use_cthyb) else
                           (lambda data: nested_mains.impurity_cthyb(data, U, symmetrize_quantities = True, n_cycles=n_cycles, max_times = max_times, solver_data_package = solver_data_package )),
                    mixers = [], cautionaries = [lambda data,it: local_nan_cautionary(data, data.impurity_struct, Qs = ['Sigma_imp_iw'], raise_exception = True),                                                 
                                                 lambda data,it: ( symmetric_G_and_self_energy_on_impurity(data.G_imp_iw, data.Sigma_imp_iw, data.solvers, 
                                                                                                           identical_pairs_Sigma, identical_pairs_G,
                                                                                                           across_imps=True, identical_pairs_G_ai=identical_pairs_G_ai  )
                                                                   if it>=10000 else  
                                                                   symmetrize_cluster_impurity(data.Sigma_imp_iw, identical_pairs_Sigma) )
                                                ], allowed_errors = [1],    
                    printout = lambda data, it: ( [ data.dump_general( quantities = ['Sigma_imp_iw','G_imp_iw'], suffix='-current' ),
                                                    data.dump_solvers(suffix='-current')
                                                  ] if ((it+1) % print_current==0) else None)  ),
                generic_action(  name = "post_impurity",
                    main = lambda data: nested_edmft_mains.post_impurity(data, identical_pairs = identical_pairs_Sigma, Cs= used_Cs),#, homogeneous_pairs = identical_pairs_G), 
                    mixers = [], cautionaries = [], allowed_errors = [],    
                    printout = lambda data, it: (data.dump_general( quantities = ['chi_imp_iw','P_imp_iw','W_imp_iw'], suffix='-current' ) if ((it+1) % print_current==0) else None) ),
                generic_action(  name = "selfenergy",
                    main = lambda data: nested_edmft_mains.selfenergy(data), 
                    mixers = [], cautionaries = [lambda data,it: nonloc_sign_cautionary(data.Sigmakw['up'], desired_sign = -1, clip_off = False, real_or_imag = 'imag')], allowed_errors = [0],    
                    printout = lambda data, it: (data.dump_general( quantities = ['Sigmakw','Sigmaijw','Sigma_loc_iw','Pqnu','Pijnu','P_loc_iw'], suffix='-current' ) if ((it+1) % print_current==0) else None) ) ]



    monitors = [ monitor( monitored_quantity = lambda: dt.ns['up'], 
                          h5key = 'n_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.mus['up'], 
                          h5key = 'mu_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.err, 
                          h5key = 'err_vs_it', 
                          archive_name = dt.archive_name) ]

    monitors+= [ monitor( monitored_quantity = lambda: dt.Sigma_loc_iw['up'].data[dt.nw/2,0,0].imag, 
                          h5key = 'ImSigma_loc_iw0_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.Sigma_loc_iw['up'].data[dt.nw/2,0,0].real, 
                          h5key = 'ReSigma_loc_iw0_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.Sigmakw['up'][dt.nw/2, dt.n_k/2, dt.n_k/2].imag, 
                          h5key = 'ImSigmakw_pipi_vs_it', 
                          archive_name = dt.archive_name),
                 monitor( monitored_quantity = lambda: dt.Sigmakw['up'][dt.nw/2, dt.n_k/2, dt.n_k/2].real, 
                          h5key = 'ReSigmakw_pipi_vs_it', 
                          archive_name = dt.archive_name)]

    
    convergers = [ converger( monitored_quantity = lambda: dt.G_loc_iw,
                            accuracy=accuracy, 
                            struct=fermionic_struct, 
                            archive_name= dt.archive_name,
                            h5key = 'diffs_G_loc' ),
                   converger( monitored_quantity = lambda: dt.W_loc_iw,
                            accuracy=accuracy, 
                            struct=bosonic_struct, 
                            archive_name= dt.archive_name,
                            h5key = 'diffs_W_loc' ),
                   converger( monitored_quantity = lambda: dt.P_loc_iw,
                            accuracy=accuracy, 
                            struct=bosonic_struct, 
                            archive_name= dt.archive_name,
                            h5key = 'diffs_P_loc' ),
                   converger( monitored_quantity = lambda: dt.Sigma_loc_iw,
                            accuracy=accuracy, 
                            struct=fermionic_struct, 
                            archive_name= dt.archive_name,
                            h5key = 'diffs_Sigma_loc') ]
    max_dist = 3
    for i in range(max_dist+1):
      for j in range(0,i+1):
        convergers.append( converger( monitored_quantity = lambda i=i, j=j: dt.Gijw['up'][:,i,j],
                                      accuracy=accuracy,
                                      func = converger.check_numpy_array,  
                                      archive_name= dt.archive_name,
                                      h5key = 'diffs_G_%s%s'%(i,j) ) )
    convergers.append( converger( monitored_quantity = lambda: dt.G_imp_iw,
                                  accuracy=accuracy, 
                                  struct=impurity_struct, 
                                  archive_name= dt.archive_name,
                                  h5key = 'diffs_G_imp' ) )
    convergers.append( converger( monitored_quantity = lambda: dt.Gweiss_iw,
                                  accuracy=accuracy, 
                                  struct=impurity_struct, 
                                  archive_name= dt.archive_name,
                                  h5key = 'diffs_Gweiss' ) )
    combo_imp_struct = {}   
    for CA,Uw in dt.Uweiss_iw:
      combo_imp_struct[CA] = impurity_struct[C]   
    convergers.append( converger( monitored_quantity = lambda: dt.Uweiss_iw,
                                  accuracy=accuracy, 
                                  struct=combo_imp_struct, 
                                  archive_name= dt.archive_name,
                                  h5key = 'diffs_Uweiss' ) )


    dmft = generic_loop(
                name = "nested-cluster EDMFT", 
                actions = actions,
                convergers = convergers,  
                monitors = monitors )

    start_from_action_index = 0

    if freeze_Uweiss:
      if mpi.is_master_node(): print "Uweiss frozen! Equivalent to nested DMFT calculation"

    if (counter==0): #do the initial guess only once!         
      if initial_guess_archive_name!='':
        if selfenergy_initial:
          start_from_action_index = 0
          if mpi.is_master_node(): print "Taking Sigma from initial guess in:",initial_guess_archive_name, "suffix: ",suffix
          HDFA = HDFArchive(initial_guess_archive_name,'r')                
          dt.Sigmakw = deepcopy(HDFA['Sigmakw%s'%suffix])
          dt.Sigma_imp_iw << HDFA['Sigma_imp_iw%s'%suffix]
          dt.mus = HDFA['mus%s'%suffix]
          del HDFA
          dt.dump_general( quantities = ['Sigmakw','Sigma_imp_iw'], suffix='-initial' )  
        elif bath_initial:
          start_from_action_index = 2
          if mpi.is_master_node(): print "Taking Gweiss from initial guess in:",initial_guess_archive_name, "suffix: ",suffix
          HDFA = HDFArchive(initial_guess_archive_name,'r')                
          input_blocks = [C for C,gw in HDFA['Gweiss_iw%s'%suffix]]  
          if set(input_blocks)!=set(impurity_struct.keys()): 
            used_Cs[:]=input_blocks[:]
            print "WARNING: input block structure does not correspond to the nested scheme block structure. Running only the impurities in the input block set."
          for C,gw in HDFA['Gweiss_iw%s'%suffix]: 
            dt.Gweiss_iw[C] << gw 
          dt.mus = HDFA['mus%s'%suffix]
          for C in impurity_struct.keys(): #in any case fill Uweiss for P_imp calculation not to crash
            for A in bosonic_struct:
              print "dt.Jq[",A,"][0,0]:",dt.Jq[A][0,0]
              dt.Uweiss_iw[C+'|'+A] << dt.Jq[A][0,0]
              dt.Uweiss_dyn_iw[C+'|'+A] << 0.0
          del HDFA
          dt.dump_general( quantities = ['Gweiss_iw','Uweiss_iw','Uweiss_dyn_iw'], suffix='-initial' )       
      else:
        if not fixed_n:  
          dt.mus['up'] = mutilde
        else:
          dt.mus['up'] = U/2.0
        if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus['up']   #this is not necessary at the moment, but may become         
        if Wilson_bath_initial:
          start_from_action_index = 2
          if impurity_struct.keys()!=["1x1"]: assert False, "Wilson initializer inapplicable!"
          for A in bosonic_struct:
            print "dt.Jq[",A,"][0,0]:",dt.Jq[A][0,0]
            dt.Uweiss_iw['1x1|'+A] << dt.Jq[A][0,0]
            dt.Uweiss_dyn_iw['1x1|'+A] << 0.0
          dt.Gweiss_iw['1x1'] << inverse(iOmega_n+U/2.0-Wilson(0.25))
          dt.dump_general( quantities = ['Gweiss_iw','Uweiss_iw','Uweiss_dyn_iw'], suffix='-initial' )  
        else: 
          for C in dt.impurity_struct.keys():
            for l in dt.impurity_struct[C]: #just the local components (but on each site!)         
              dt.Sigma_imp_iw[C].data[:,l,l] = U/2.0-int(insulating_initial)*1j/numpy.array(dt.ws)
            for A in bosonic_struct:
              CA = C+"|"+A
              dt.Uweiss_iw[CA] << dt.Jq[A][0,0]
              dt.Uweiss_dyn_iw[CA] << 0.0
              dt.P_imp_iw[CA] << 0.0
          for A in bosonic_struct:
            dt.Pqnu[A][:,:,:] = 0.0
            dt.P_loc_iw[A]<< 0.0
            dt.Pijnu[A][:,:,:]= 0.0        
          for key in fermionic_struct.keys(): 
            dt.Sigmakw[key][:,:,:] = U/2.0    
            numpy.transpose(dt.Sigmakw[key])[:] -= int(insulating_initial)*1j/numpy.array(dt.ws)
          dt.dump_general( quantities = ['Sigmakw','Sigma_imp_iw'], suffix='-initial' )  

 

    #run nested!-------------

    if mix_GWlatt:
      actions[0].mixers.extend([ mixer( mixed_quantity = lambda: dt.Gijw,
                                      rules=rules,
                                      func=mixer.mix_lattice_gf,
                                      initialize = True ) ])
      actions[0].mixers.extend([ mixer( mixed_quantity = lambda: dt.Wijnu,
                                      rules=rules,
                                      func=mixer.mix_lattice_gf,
                                      initialize = True ) ])
    if mix_Uweiss:
      print "mixing Uweiss, rules:", Uweiss_mix_rules
      actions[1].mixers.extend([ mixer( mixed_quantity = lambda: dt.Uweiss_iw,
                                      rules=Uweiss_mix_rules,
                                      func=mixer.mix_block_gf,
                                      initialize = True ) ])
      actions[1].mixers.extend([ mixer( mixed_quantity = lambda: dt.Uweiss_dyn_iw,
                                      rules=Uweiss_mix_rules,
                                      func=mixer.mix_block_gf,
                                      initialize = True ) ])


    dt.dump_parameters()
    dt.dump_non_interacting() 

    err = dmft.run( dt, 
              max_its=max_its, 
              min_its=min_its,
              max_it_err_is_allowed = 7,
              print_final=True, 
              print_current = 1,
              start_from_action_index = start_from_action_index  )
    if mpi.is_master_node():
      cmd = 'mv %s %s'%(filename, filename.replace("result", "nested_edmft")) 
      print cmd
      os.system(cmd)

    if (err==2): 
      print "Cautionary error!!! exiting..."
      solver_data_package['construct|run|exit'] = 2
      if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package)
      break

    if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
    counter += 1
  if not (solver_data_package is None): solver_data_package['construct|run|exit'] = 2
  if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package)
  return dt, monitors, convergers
  def run(self, data, calculation_name='', total_debug = False,
                n_loops_max=100, n_loops_min=5, 
                print_local=1, print_impurity_input=1, print_non_local=1, print_three_leg=1, print_impurity_output=1,
                skip_self_energy_on_first_iteration=False,  #1 every iteration, 2 every second, -2 never (except for final)
                mix_after_selfenergy = False, 
                last_iteration_err_is_allowed = 15 ):
    for mixer in (self.mixers + self.imp_mixers):
      mixer.get_initial()
    for conv in self.convergers:
      conv.reset()
    for monitor in self.monitors:
      monitor.reset()

    if not (self.cautionary is None):
      self.cautionary.reset() 

    if mpi.is_master_node():
        data.dump_parameters(suffix='')
        data.dump_non_interacting(suffix='')

    converged = False     
    failed = False
    for loop_index in range(n_loops_max):
      if mpi.is_master_node():
        print "---------------------------- loop_index: ",loop_index,"/",n_loops_max,"---------------------------------"
      times = []
     
      times.append((time(),"selfenergy"))

      if loop_index!=0 or not skip_self_energy_on_first_iteration: 
        self.selfenergy(data=data)

      times.append((time(),"mixing 1"))

      if mix_after_selfenergy:
        for mixer in self.mixers:
          mixer.mix(loop_index)

      times.append((time(),"cautionary"))

      if not (self.cautionary is None):
        data.err = self.cautionary.check_and_fix(data)        
        if data.err and (loop_index > last_iteration_err_is_allowed):
          failed = True

      times.append((time(),"lattice"))

      self.lattice(data=data)

      times.append((time(),"pre_impurity"))

      self.pre_impurity(data=data)

      times.append((time(),"dump_impurity_input"))

      if mpi.is_master_node() and ((loop_index + 1) % print_impurity_input==0):
        data.dump_impurity_input(suffix='-%s'%loop_index)    

      times.append((time(),"impurity"))

      if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
      self.impurity(data=data)
      if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
      times.append((time(),"dump_impurity_output and mix impurity"))

      if mpi.is_master_node():
        if (loop_index + 1) % print_local == 0: data.dump_solver(suffix='-%s'%loop_index)      

      for mixer in self.imp_mixers:
        mixer.mix(loop_index)

      times.append((time(),"post_impurity"))

      self.post_impurity(data=data)

      times.append((time(),"convergers"))

      c = True
      for conv in self.convergers:
        if not conv.check():
          c = False
      converged = c #here we are checking that all have converged, not that at least one has converged

      times.append((time(),"mixing 2"))

      if not converged and not mix_after_selfenergy:
        for mixer in self.mixers:
          mixer.mix(loop_index)

      times.append((time(),"monitors"))

      for monitor in self.monitors:
        monitor.monitor()

      times.append((time(),"dumping"))

      if mpi.is_master_node():
        data.dump_errors(suffix='-%s'%loop_index)
        data.dump_scalar(suffix='-%s'%loop_index)
        if (loop_index + 1) % print_local == 0: data.dump_local(suffix='-%s'%loop_index)
        if (loop_index + 1) % print_three_leg == 0: data.dump_three_leg(suffix='-%s'%loop_index)
        if (loop_index + 1) % print_non_local == 0: data.dump_non_local(suffix='-%s'%loop_index)          
        A = HDFArchive(data.archive_name)
        A['max_index'] = loop_index
        del A
      if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()

      if (mpi.rank==0 or mpi.rank==1) and total_debug: #total debug option
        archive_name = 'full_data'
        if calculation_name !='':
          archive_name += '_%s'%calculation_name
        archive_name += '.rank%s'%(mpi.rank) 
        print "about to dump all data in ",archive_name
        data.dump_all(suffix='-%s'%loop_index, archive_name=archive_name)

      times.append((time(),""))
      if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
      if mpi.is_master_node():
        self.print_timings(times)

      if (converged and loop_index>n_loops_min) or failed: break

    if not (self.after_it_is_done is None):
      self.after_it_is_done(data) #notice that if we don't say data=data we can pass a method of data for after_it_is_done, such that here self=data    

    if mpi.is_master_node():
      data.dump_all(suffix='-final') 

    if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier()
    if converged:
      return 0  
    else:
      if failed:
        return 2 #probably hitting AFM
      else:
        return 1 #maximum number of loops reached