Example #1
0
    def __init__(self, e_k, beta, H_int=None, gf_struct=None,
                 mu0=0., mu_max=10, mu_min=-10.):

        if mpi.is_master_node():
            print(self.logo())

        gf_struct = fix_gf_struct_type(gf_struct)
        
        self.mu = mu0
        self.beta = beta
        self.mu_max = mu_max
        self.mu_min = mu_min
        
        self.e_k = e_k.copy()
        self.e_k_MF = e_k.copy()
        self.n_k = len(self.e_k.mesh)

        self.target_shape = self.e_k.target_shape

        self.shape_ab = self.e_k.target_shape
        self.shape_abcd = list(self.shape_ab) * 2

        self.norb = self.target_shape[0]
        self.triu_idxs = np.triu_indices(self.norb, k=1)

        if mpi.is_master_node():
            print('beta =', self.beta)
            print('mu =', self.mu)
            print('bands =', self.norb)
            print('n_k =', len(self.e_k.mesh))
            print('H_int =', H_int)
            print()

        if gf_struct is None:
            assert( H_int is None ), \
                'Error: gf_struct = None, but H_int is not None'

        if H_int is not None:
            assert( gf_struct is not None ), \
                'Error: H_int = None, but gf_struct is not None'

            fundamental_operators = fundamental_operators_from_gf_struct(gf_struct)

            if mpi.is_master_node():
                print('gf_struct =', gf_struct)
                print('fundamental_operators =', fundamental_operators)
                print()

            assert( is_operator_composed_of_only_fundamental_operators(
                H_int, fundamental_operators) ), \
                'Error: H_int is incompatible with gf_struct and its fundamental_operators'
            
            self.U_abcd = get_rpa_tensor(H_int, fundamental_operators)

        else:
            self.U_abcd = np.zeros(self.shape_abcd)
Example #2
0
def dmft_step(Delta_in):
  global itern
  itern += 1
  if verbose:
    print("Iteration %i min_iter=%i max_iter=%i\n" % (itern, min_iter, max_iter))
  Delta_in_fixed = fix_hyb_function(Delta_in, Delta_min)
  S.Delta_w << Delta_in_fixed

  S.solve(**sp) # Solve the impurity model
  global Gself, Gloc, Gloc_prev
  Gself = calc_G(Delta_in_fixed, S.Sigma_w, mu) # impurity GF ("self-energy-trick" improved)
  Gloc, Delta = self_consistency(S.Sigma_w)     # apply the DMFT self-consistency equation

  diff_loc_imp = gf_diff(Gself, Gloc)            # difference between impurity and local lattice GF
  diff_prev = gf_diff(Gloc, Gloc_prev)           # difference between two consecutively computed local latice GFs
  Gloc_prev = Gloc.copy()
  occupancy = calc_occupancy(Delta, S.Sigma_w, mu)
  diff_occupancy = abs(occupancy-occupancy_goal) # this difference is used as the measure of deviation

  stats = OrderedDict([("itern", itern), ("mu", mu), ("diff_loc_imp", diff_loc_imp), ("diff_prev", diff_prev),
                       ("diff_occupancy", diff_occupancy), ("occupancy", occupancy)])
  for i in observables:
    stats[i] = S.expv[i]
  header_string = fmt_str_header(len(stats)).format(*[i for i in stats.keys()])
  stats_string  = fmt_str(len(stats)).format(*[i for i in stats.values()])
  if mpi.is_master_node():
    if itern == 1: stats_file.write(header_string)
    stats_file.write(stats_string)
  if verbose: print("stats: %sstats: %s" % (header_string, stats_string))

  if store_steps:
    os.mkdir(str(itern)) # one subdirectory per iteration
    save_BlockGf(str(itern)+"/Delta", Delta_in_fixed)
    save_BlockGf(str(itern)+"/Sigma", S.Sigma_w) # self-energy
    save_BlockGf(str(itern)+"/G", Gloc)          # local lattice Green's function
    save_BlockA(str(itern)+"/A", Gloc)           # spectral function of local lattice GF
    store_result(str(itern)+"/"+solution_filename, S)

  if mpi.is_master_node():
    store_result(checkpoint_filename, S) # for checkpoint/restart functionality

  # Check for convergence. The only way to exit the DMFT loop is by generating exceptions.
  if (diff_loc_imp   < eps_loc_imp   and
      diff_prev      < eps_prev      and
      diff_occupancy < eps_occupancy and
      itern >= min_iter):
    raise Converged(stats_string)
  if (itern == max_iter):
    raise FailedToConverge(stats_string)

  if occup_method == "adjust":
    Gloc, Delta = adjust_mu(Delta, S.Sigma_w) # here we update mu to get closer to target occupancy

  return Delta
Example #3
0
 def __init__(self, param, dmft_param):
     self.param = param
     self.dmft_param = dmft_param
     self.occupancy_goal = param["occupancy"]
     self.T = param["T"]
     self.observables = []  # List of expectation values to compute
     self.cp = {}  # Dictinary with creator parameters
     self.sp = {
         "T": self.T,
         "model_parameters": {}
     }  # Dictionary with solver parameters
     self.mp = {}  # Dictionary with model parameters
     self.nrgp = {
     }  # Dictionary with low-level NRG Parameters (optional tweaks)
     # Open file with basic information (convergence criteria, occupancy, expectation values of operators) for monitoring the iteration process
     if mpi.is_master_node():
         self.stats_file = open(self.stats_filename, "w",
                                buffering=1)  # line buffered
     # Initialize a function ht0 for calculating the Hilbert transform of the DOS
     if (param["dos"] == "Bethe"):
         self.ht1 = lambda z: 2 * (
             z - 1j * np.sign(z.imag) * np.sqrt(1 - z**2)
         )  # Analytical expression for Hilbert transform of Bethe lattice DOS
         self.ht0 = lambda z: self.ht1(z / param["Bethe_unit"])
     else:
         table = np.loadtxt(param["dos"])
         self.dosA = Gf(mesh=MeshReFreqPts(table[:, 0]), target_shape=[])
         for i, w in enumerate(self.dosA.mesh):
             self.dosA[w] = np.array([[table[i, 1]]])
         self.ht0 = lambda z: hilbert_transform_refreq(self.dosA, z)
Example #4
0
File: bse.py Project: TRIQS/tprf
def solve_lattice_bse_e_k_sigma_w(mu,
                                  e_k,
                                  sigma_w,
                                  gamma_wnn,
                                  tail_corr_nwf=-1):

    kmesh = e_k.mesh
    fmesh_huge = sigma_w.mesh
    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_sigma = len(fmesh_huge) // 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_sigma     =', nwf_sigma))
        print(('nwf_chi0_tail =', tail_corr_nwf))
        print()

    # -- Lattice BSE calc with built in trace using g_wk
    from triqs_tprf.lattice import chiq_sum_nu_from_e_k_sigma_w_and_gamma_PH

    chi_kw = chiq_sum_nu_from_e_k_sigma_w_and_gamma_PH(
        mu, e_k, sigma_w, gamma_wnn, tail_corr_nwf=tail_corr_nwf)

    return chi_kw
Example #5
0
def main(input_file, output_file):
    """
    Solve the impurity problem.
    """

    import time
    t_start = time.time()

    with HDFArchive(os.path.abspath(input_file), 'r') as h:
        rot = h['rot'] if 'rot' in h else None
        beta = h['beta']
        gf_struct = h['gf_struct']
        # convert a dict to a list of pairs [ (str,[int,...]), ...]
        gf_struct = [(k, list(v)) for k, v in gf_struct.items()]
        u_mat = h['u_mat']
        n_iw = h['n_iw']
        G0_iw = h['G0_iw']
        params = h['params']

    if rot is not None:
        raise RuntimeError("TRIQS/HubbardI interface does not support basis rotation!")

    h_int = make_h_int(u_mat, gf_struct)

    # Create a working horse
    S = Solver(beta, gf_struct, n_iw)
    S.G0_iw << G0_iw

    for k in params:
        # e.g. numpy.bool_ to bool
        params[k] = convert_to_built_in_scalar_type(params[k])

    S.solve(h_int=h_int, **params)

    # Retrieve results from the working horse
    Sigma_iw = S.Sigma_iw.copy()
    G_iw = S.G_iw.copy()

    if mpi.is_master_node():
        with HDFArchive(os.path.abspath(output_file), 'w') as h:
            h['Sigma_iw'] = Sigma_iw
            h['Gimp_iw'] = G_iw

    t_end = time.time()
    if mpi.is_master_node():
        print('TRIQS/hubbardI ran for {} seconds.'.format(t_end-t_start))
Example #6
0
    def test_mpi(self):

        a = Toto(0)

        if mpi.is_master_node():
            a = Toto(1)
            mpi.bcast(a)

        self.assertEqual(a, Toto(1))
Example #7
0
class test_SIAM(unittest.TestCase):

    # Construct Parameters
    cp = {}
    cp["model"] = "SIAM"
    cp["symtype"] = "QS"
    cp["mesh_max"] = 1.0
    cp["mesh_min"] = 1e-3
    cp["mesh_ratio"] = 1.1

    # Set up the Solver
    S = Solver(**cp)

    # Solve Parameters
    sp = {}
    sp["T"] = 1e-3
    sp["Lambda"] = 4.0
    sp["Nz"] = 4
    sp["Tmin"] = 1e-4
    sp["keep"] = 50
    sp["keepenergy"] = 6.0

    # Model Parameters
    mp = {}
    mp["U1"] = 0.5
    mp["eps1"] = -0.24
    sp["model_parameters"] = mp

    # Low-level NRG Parameters
    np = {}
    np["bins"] = 50
    S.set_nrg_params(**np)

    # # Initialize hybridization function
    S.Delta_w['imp'] << 0.1 * SemiCircular(1.0)

    # Solve the impurity model
    S.solve(**sp)

    if mpi.is_master_node():
      # Store the Result
      fnout = "MPI_SIAM_QS_np%i.out.h5" % mpi.size
      with HDFArchive(fnout, 'w') as arch:
        arch["A_w"] = S.A_w
        arch["G_w"] = S.G_w
        arch["F_w"] = S.F_w
        arch["Sigma_w"] = S.Sigma_w

      # Compare against reference result
      fnref = "MPI_SIAM_QS.ref.h5" # the same for all cases!
      h5diff(fnout, fnref)
Example #8
0
def is_vasp_running(vasp_pid):
    """
    Tests if VASP initial process is still alive.
    """
    pid_exists = False
    if mpi.is_master_node():
        try:
            os.kill(vasp_pid, 0)
        except OSError as e:
            pid_exists = e.errno == errno.EPERM
        else:
            pid_exists = True

    pid_exists = mpi.bcast(pid_exists)
    return pid_exists
class test_SIAM(unittest.TestCase):

    # Construct Parameters
    cp = {}
    cp["model"] = "SIAM"
    cp["symtype"] = "QS"
    cp["mesh_max"] = 1.0
    cp["mesh_min"] = 1e-3
    cp["mesh_ratio"] = 1.1

    # Set up the Solver
    S = Solver(**cp)

    # Solve Parameters
    sp = {}
    sp["T"] = 1e-3
    sp["Lambda"] = 4.0
    sp["Nz"] = 2
    sp["Tmin"] = 1e-4
    sp["keep"] = 50
    sp["keepenergy"] = 6.0

    # Model Parameters
    mp = {}
    mp["U1"] = 0.5
    mp["eps1"] = -0.24
    sp["model_parameters"] = mp

    # Low-level NRG Parameters
    np = {}
    np["bins"] = 50
    S.set_nrg_params(**np)

    # # Initialize hybridization function
    S.Delta_w['imp'] << 0.1 * SemiCircular(1.0)

    # Solve the impurity model
    S.solve(**sp)

    if mpi.is_master_node(): HDFArchive('Solver.h5', 'w')['S'] = S

    # Rerun the Solver and Compare
    S_old = HDFArchive('Solver.h5', 'r')['S']
    S_old.solve(**S_old.last_solve_params)
    assert_block_gfs_are_close(S_old.G_w, S.G_w, 1e-12)
Example #10
0
    def repack(self):
        """
        Calls the h5repack routine in order to reduce the file size of the hdf5 archive.

        Note
        ----
        Should only be used before the first invokation of HDFArchive in the program, 
        otherwise the hdf5 linking will be broken.

        """

        import subprocess

        if not (mpi.is_master_node()):
            return
        mpi.report("Repacking the file %s" % self.hdf_file)

        retcode = subprocess.call(
            ["h5repack", "-i%s" % self.hdf_file, "-otemphgfrt.h5"])
        if retcode != 0:
            mpi.report("h5repack failed!")
        else:
            subprocess.call(["mv", "-f", "temphgfrt.h5", "%s" % self.hdf_file])
Example #11
0
def is_vasp_lock_present():
    res_bool = False
    if mpi.is_master_node():
        res_bool = os.path.isfile('./vasp.lock')
    res_bool = mpi.bcast(res_bool)
    return res_bool
Example #12
0
def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter, n_iter_dft, vasp_version):
    """
    """
    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

        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()

        # check if we should do additional VASP calculations
        # in the standard VASP version, VASP writes out GAMMA itself
        # so that if we want to keep GAMMA fixed we have to copy it to
        # GAMMA_recent and copy it back after VASP has completed an iteration
        # if we are using a hacked Version of VASP where the write out is
        # disabled we can skip this step.
        # the hack consists of removing the call of LPRJ_LDApU in VASP src file
        # electron.F around line 644
        iter_dft = 0

        if vasp_version == 'standard':
            copyfile(src='GAMMA', dst='GAMMA_recent')
        while iter_dft < n_iter_dft:
            if mpi.is_master_node():
                open('./vasp.lock', 'a').close()
            while is_vasp_lock_present():
                time.sleep(1)
                if not is_vasp_running(vasp_pid):
                    mpi.report("  VASP stopped")
                    vasp_running = False
                    break
            iter_dft += 1
            if vasp_version == 'standard':
                copyfile(src='GAMMA_recent', dst='GAMMA')
        iter += 1
        if iter == n_iter:
            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 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")
Example #13
0
def main():

    import importlib

    try:
        vasp_pid = int(sys.argv[1])
    except (ValueError, KeyError):
        if mpi.is_master_node():
            print(
                "ERROR: VASP process pid must be provided as the first argument"
            )
        raise

    try:
        n_iter = int(sys.argv[2])
    except (ValueError, KeyError):
        if mpi.is_master_node():
            print(
                "ERROR: Number of iterations must be provided as the second argument"
            )
        raise

    try:
        n_iter_dft = int(sys.argv[3])
    except (ValueError, KeyError):
        if mpi.is_master_node():
            print(
                "ERROR: Number of VASP iterations with fixed charge density must be provided as the third argument"
            )
        raise

    try:
        dmft_script = re.sub("\.py$", "", sys.argv[4])
    except:
        if mpi.is_master_node():
            print(
                "ERROR: User-defined DMFT script must be provided as the fourth argument"
            )
        raise

# Optional parameter: config-file name
    try:
        cfg_file = sys.argv[5]
    except KeyError:
        cfg_file = 'plo.cfg'

    try:
        vasp_version = sys.argv[6]
    except KeyError:
        vasp_version = 'standard'

    if vasp_version != 'standard' and vasp_version != 'no_gamma_write':
        raise Exception('vasp_version has to be standard or no_gamma_write')


#    if len(sys.argv) > 1:
#        vasp_path = sys.argv[1]
#    else:
#        try:
#            vasp_path = os.environ['VASP_DIR']
#        except KeyError:
#            if mpi.is_master_node():
#                print "Path to VASP must be specified either as an argument of in VASP_DIR"
#            raise
    signal.signal(signal.SIGINT, sigint_handler)

    dmft_mod = importlib.import_module(dmft_script)

    run_all(vasp_pid, dmft_mod.dmft_cycle, cfg_file, n_iter, n_iter_dft,
            vasp_version)
Example #14
0
p["n_warmup_cycles"] = 100000
p["n_cycles"] = 1000000
p["perform_tail_fit"] = True
p["fit_max_moment"] = 4
p["fit_min_n"] = 30
p["fit_max_n"] = 60

# If conversion step was not done, we could do it here. Uncomment the lines it you want to do this.
#from triqs_dft_tools.converters.wien2k import *
#Converter = Wien2kConverter(filename=dft_filename, repacking=True)
#Converter.convert_dft_input()
#mpi.barrier()

previous_runs = 0
previous_present = False
if mpi.is_master_node():
    with HDFArchive(dft_filename + '.h5', 'a') as f:
        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')
previous_runs = mpi.bcast(previous_runs)
previous_present = mpi.bcast(previous_present)

SK = SumkDFT(hdf_file=dft_filename + '.h5',
             use_dft_blocks=use_blocks,
             h_field=h_field)
Example #15
0
    def convert_dft_input(self,
                          first_real_part_matrix=True,
                          only_upper_triangle=False,
                          weights_in_file=False):
        """
        Reads the appropriate files and stores the data for the dft_subgrp in the hdf5 archive. 

        Parameters
        ----------
        first_real_part_matrix : boolean, optional
                                 Should all the real components for given k be read in first, followed by the imaginary parts?
        only_upper_triangle : boolean, optional
                              Should only the upper triangular part of H(k) be read in? 
        weights_in_file : boolean, optional
                          Are the k-point weights to be read in?

        """

        # Read and write only on the master node
        if not (mpi.is_master_node()):
            return
        mpi.report("Reading input from %s..." % self.dft_file)

        # R is a generator : each R.Next() will return the next number in the
        # file
        R = ConverterTools.read_fortran_file(self, self.dft_file,
                                             self.fortran_to_replace)
        try:
            # the energy conversion factor is 1.0, we assume eV in files
            energy_unit = 1.0
            # read the number of k points
            n_k = int(next(R))
            k_dep_projection = 0
            SP = 0  # no spin-polarision
            SO = 0  # no spin-orbit
            # total charge below energy window is set to 0
            charge_below = 0.0
            # density required, for setting the chemical potential
            density_required = next(R)
            symm_op = 0  # No symmetry groups for the k-sum

            # the information on the non-correlated shells is needed for
            # defining dimension of matrices:
            # number of shells considered in the Wanniers
            n_shells = int(next(R))
            # corresponds to index R in formulas
            # now read the information about the shells (atom, sort, l, dim):
            shell_entries = ['atom', 'sort', 'l', 'dim']
            shells = [{name: int(val)
                       for name, val in zip(shell_entries, R)}
                      for ish in range(n_shells)]

            # number of corr. shells (e.g. Fe d, Ce f) in the unit cell,
            n_corr_shells = int(next(R))
            # corresponds to index R in formulas
            # now read the information about the shells (atom, sort, l, dim, SO
            # flag, irep):
            corr_shell_entries = ['atom', 'sort', 'l', 'dim', 'SO', 'irep']
            corr_shells = [{
                name: int(val)
                for name, val in zip(corr_shell_entries, R)
            } for icrsh in range(n_corr_shells)]

            # determine the number of inequivalent correlated shells and maps,
            # needed for further reading
            [n_inequiv_shells, corr_to_inequiv, inequiv_to_corr
             ] = ConverterTools.det_shell_equivalence(self, corr_shells)

            use_rotations = 0
            rot_mat = [
                numpy.identity(corr_shells[icrsh]['dim'], numpy.complex_)
                for icrsh in range(n_corr_shells)
            ]
            rot_mat_time_inv = [0 for i in range(n_corr_shells)]

            # Representative representations are read from file
            n_reps = [1 for i in range(n_inequiv_shells)]
            dim_reps = [0 for i in range(n_inequiv_shells)]
            T = []
            for ish in range(n_inequiv_shells):
                # number of representatives ("subsets"), e.g. t2g and eg
                n_reps[ish] = int(next(R))
                dim_reps[ish] = [int(next(R)) for i in range(n_reps[ish])
                                 ]  # dimensions of the subsets

                # The transformation matrix:
                # is of dimension 2l+1, it is taken to be standard d (as in
                # Wien2k)
                ll = 2 * corr_shells[inequiv_to_corr[ish]]['l'] + 1
                lmax = ll * (corr_shells[inequiv_to_corr[ish]]['SO'] + 1)
                T.append(numpy.zeros([lmax, lmax], numpy.complex_))

                T[ish] = numpy.array(
                    [[0.0, 0.0, 1.0, 0.0, 0.0],
                     [1.0 / sqrt(2.0), 0.0, 0.0, 0.0, 1.0 / sqrt(2.0)],
                     [-1.0 / sqrt(2.0), 0.0, 0.0, 0.0, 1.0 / sqrt(2.0)],
                     [0.0, 1.0 / sqrt(2.0), 0.0, -1.0 / sqrt(2.0), 0.0],
                     [0.0, 1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0), 0.0]])

            # Spin blocks to be read:
            # number of spins to read for Norbs and Ham, NOT Projectors
            n_spin_blocs = SP + 1 - SO

            # define the number of n_orbitals for all k points: it is the
            # number of total bands and independent of k!
            n_orbitals = numpy.ones([n_k, n_spin_blocs], numpy.int) * sum(
                [sh['dim'] for sh in shells])

            # Initialise the projectors:
            proj_mat = numpy.zeros([
                n_k, n_spin_blocs, n_corr_shells,
                max([crsh['dim'] for crsh in corr_shells]),
                numpy.max(n_orbitals)
            ], numpy.complex_)

            # Read the projectors from the file:
            for ik in range(n_k):
                for icrsh in range(n_corr_shells):
                    for isp in range(n_spin_blocs):

                        # calculate the offset:
                        offset = 0
                        n_orb = 0
                        for ish in range(n_shells):
                            if (n_orb == 0):
                                if (shells[ish]['atom']
                                        == corr_shells[icrsh]['atom']) and (
                                            shells[ish]['sort']
                                            == corr_shells[icrsh]['sort']):
                                    n_orb = corr_shells[icrsh]['dim']
                                else:
                                    offset += shells[ish]['dim']

                        proj_mat[ik, isp, icrsh, 0:n_orb,
                                 offset:offset + n_orb] = numpy.identity(n_orb)

            # now define the arrays for weights and hopping ...
            # w(k_index),  default normalisation
            bz_weights = numpy.ones([n_k], numpy.float_) / float(n_k)
            hopping = numpy.zeros([
                n_k, n_spin_blocs,
                numpy.max(n_orbitals),
                numpy.max(n_orbitals)
            ], numpy.complex_)

            if (weights_in_file):
                # weights in the file
                for ik in range(n_k):
                    bz_weights[ik] = next(R)

            # if the sum over spins is in the weights, take it out again!!
            sm = sum(bz_weights)
            bz_weights[:] /= sm

            # Grab the H
            for isp in range(n_spin_blocs):
                for ik in range(n_k):
                    n_orb = n_orbitals[ik, isp]

                    # first read all real components for given k, then read
                    # imaginary parts
                    if (first_real_part_matrix):

                        for i in range(n_orb):
                            if (only_upper_triangle):
                                istart = i
                            else:
                                istart = 0
                            for j in range(istart, n_orb):
                                hopping[ik, isp, i, j] = next(R)

                        for i in range(n_orb):
                            if (only_upper_triangle):
                                istart = i
                            else:
                                istart = 0
                            for j in range(istart, n_orb):
                                hopping[ik, isp, i, j] += next(R) * 1j
                                if ((only_upper_triangle) and (i != j)):
                                    hopping[ik, isp, j,
                                            i] = hopping[ik, isp, i,
                                                         j].conjugate()

                    else:  # read (real,im) tuple

                        for i in range(n_orb):
                            if (only_upper_triangle):
                                istart = i
                            else:
                                istart = 0
                            for j in range(istart, n_orb):
                                hopping[ik, isp, i, j] = next(R)
                                hopping[ik, isp, i, j] += next(R) * 1j

                                if ((only_upper_triangle) and (i != j)):
                                    hopping[ik, isp, j,
                                            i] = hopping[ik, isp, i,
                                                         j].conjugate()
            # keep some things that we need for reading parproj:
            things_to_set = [
                'n_shells', 'shells', 'n_corr_shells', 'corr_shells',
                'n_spin_blocs', 'n_orbitals', 'n_k', 'SO', 'SP', 'energy_unit'
            ]
            for it in things_to_set:
                setattr(self, it, locals()[it])
        except StopIteration:  # a more explicit error if the file is corrupted.
            raise "HK Converter : reading file dft_file failed!"

        R.close()

        # Save to the HDF5:
        with HDFArchive(self.hdf_file, 'a') as ar:
            if not (self.dft_subgrp in ar):
                ar.create_group(self.dft_subgrp)
            things_to_save = [
                'energy_unit', 'n_k', 'k_dep_projection', 'SP', 'SO',
                'charge_below', 'density_required', 'symm_op', 'n_shells',
                'shells', 'n_corr_shells', 'corr_shells', 'use_rotations',
                'rot_mat', 'rot_mat_time_inv', 'n_reps', 'dim_reps', 'T',
                'n_orbitals', 'proj_mat', 'bz_weights', 'hopping',
                'n_inequiv_shells', 'corr_to_inequiv', 'inequiv_to_corr'
            ]
            for it in things_to_save:
                ar[self.dft_subgrp][it] = locals()[it]
Example #16
0
File: bse.py Project: TRIQS/tprf
def solve_lattice_bse(g_wk, gamma_wnn):
    r""" Compute the generalized lattice susceptibility 
    :math:`\chi_{\bar{a}b\bar{c}d}(\mathbf{k}, \omega_n)` using the Bethe-Salpeter 
    equation (BSE).

    Parameters
    ----------

    g_wk : Gf,
           Single-particle Green's function :math:`G_{a\bar{b}}(i\nu_n, \mathbf{k})`.
    gamma_wnn : Gf,
                Local particle-hole vertex function 
                :math:`\Gamma_{a\bar{b}c\bar{d}}(i\omega_n, i\nu_n, i\nu_n')`.

    Returns
    -------
    chi_kw : Gf,
             Generalized lattice susceptibility 
             :math:`\chi_{\bar{a}b\bar{c}d}(\mathbf{k}, i\omega_n)`.

    chi0_kw : Gf,
              Generalized bare lattice susceptibility 
              :math:`\chi^0_{\bar{a}b\bar{c}d}(\mathbf{k}, i\omega_n)`.
    """

    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()

    mpi.report('--> chi0_wk_tail_corr')
    chi0_wk_tail_corr = imtime_bubble_chi0_wk(g_wk, nw=nw)

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

    chi0_wnk = get_chi0_wnk(g_wk, nw=nw, nwf=nwf)

    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
Example #17
0
def is_master_node():
    if is_mpi_loaded():
        import triqs.utility.mpi as mpi
        return mpi.is_master_node()
    else:
        return True
Example #18
0
beta = 100.0

# We analyze the block structure of the Hamiltonian
Sigma = SK_tools.block_structure.create_gf(beta=beta)

SK_tools.put_Sigma([Sigma])
G = SK_tools.extract_G_loc()
SK_tools.analyse_block_structure_from_gf(G, threshold = 1e-2)
gf_struct = SK_tools.gf_struct_solver[0]

S = Solver(beta=beta, gf_struct=gf_struct)

# non-interacting chemical potential
chemical_potential0 = 0.0

if mpi.is_master_node():
    ar = HDFArchive(filename+'.h5','a')
    if 'iteration_count' in ar['DMFT_results']:
        previous_present = True
        iteration_offset = ar['DMFT_results']['iteration_count']+1
        print('reading iteration'+str(iteration_offset))
        SK_tools.dc_imp = ar['DMFT_results']['Iterations']['dc_imp'+str(iteration_offset-1)]
        S.Sigma_w = ar['DMFT_results']['Iterations']['Sigma_w_it'+str(iteration_offset-1)]
        dc_energ = ar['DMFT_results']['Iterations']['dc_energ'+str(iteration_offset-1)]
        SK_tools.chemical_potential = ar['DMFT_results']['Iterations']['chemical_potential'+str(iteration_offset-1)].real
        chemical_potential0 = ar['DMFT_results']['Iterations']['chemical_potential0'].real

mpi.barrier()
S.Sigma_w << mpi.bcast(S.Sigma_w)
SK_tools.chemical_potential = mpi.bcast(SK_tools.chemical_potential)
chemical_potential0 = mpi.bcast(chemical_potential0)
Example #19
0
def run_test(t1, filename):
    dptkeys = [
        'verbosity', 'calculate_sigma', 'calculate_sigma1', 'calculate_sigma2'
    ]

    parms = {
        # Solver parameters
        'n_iw': 100,
        # Physical parameters
        'U': 0.5,
        't1': t1,
        'beta': 10,
        # DMFT loop control parameters
        'calculate_sigma': True,
        'calculate_sigma1': True,
        'calculate_sigma2': True,
        'measure_G2_iw_ph': True,
        "measure_G2_n_bosonic": 10,
        "measure_G2_n_fermionic": 10,
        "verbosity": 4,
    }

    parms["N_x"] = 2
    parms["N_y"] = 1
    parms["N_z"] = 1
    parms["ksi_delta"] = 1.0

    # Chemical potential depends on the definition of H(k) that is used
    parms['chemical_potential_bare'] = 0.
    parms['chemical_potential'] = parms['U'] / 2. + parms[
        'chemical_potential_bare']

    n_orbs = 1  # Number of orbitals
    off_diag = True
    spin_names = ['up', 'dn']  # Outer (non-hybridizing) blocks
    orb_names = ['%s' % i for i in range(n_orbs)]  # Orbital indices
    gf_struct = op.set_operator_structure(spin_names,
                                          orb_names,
                                          off_diag=off_diag)

    if haspomerol:
        #####
        #
        # Reference: 4 site cluster, calculate only G, not G2
        #
        #####
        def calc_reference():

            ref_orbs = [
                '%s' % i for i in range(n_orbs * parms['N_x'] * parms['N_y'])
            ]
            ref_gf_struct = op.set_operator_structure(spin_names,
                                                      ref_orbs,
                                                      off_diag=off_diag)
            ref_index_converter = {(sn, o): ("loc", int(o),
                                             "down" if sn == "dn" else "up")
                                   for sn, o in product(spin_names, ref_orbs)}
            #print ref_index_converter,ref_orbs
            ref_ed = PomerolED(ref_index_converter, verbose=True)
            ref_N = sum(
                ops.n(sn, o) for sn, o in product(spin_names, ref_orbs))
            #  2 3
            #  0 1
            ref_H = (parms["U"] * (ops.n('up', '0') * ops.n('dn', '0') +
                                   ops.n('up', '1') * ops.n('dn', '1')) -
                     2. * parms['t1'] *
                     (ops.c_dag('up', '0') * ops.c('up', '1') +
                      ops.c_dag('up', '1') * ops.c('up', '0') +
                      ops.c_dag('dn', '0') * ops.c('dn', '1') +
                      ops.c_dag('dn', '1') * ops.c('dn', '0')) -
                     parms['chemical_potential'] * ref_N)
            # Run the solver
            ref_ed.diagonalize(ref_H)
            # Compute G(i\omega)
            ref_G_iw = ref_ed.G_iw(ref_gf_struct, parms['beta'], parms['n_iw'])
            return ref_G_iw

        ref_G_iw = calc_reference()
        ref = ref_G_iw[ref_spin]

        g2_blocks = set([("up", "up"), ("up", "dn"), ("dn", "up"),
                         ("dn", "dn")])
        index_converter = {(sn, o):
                           ("loc", int(o), "down" if sn == "dn" else "up")
                           for sn, o in product(spin_names, orb_names)}

        # 1 Bath degree of freedom
        # Level of the bath sites
        epsilon = [
            -parms['chemical_potential_bare'],
        ]
        index_converter.update({
            ("B%i_%s" % (k, sn), 0):
            ("bath" + str(k), 0, "down" if sn == "dn" else "up")
            for k, sn in product(range(len(epsilon)), spin_names)
        })

        # Make PomerolED solver object
        ed = PomerolED(index_converter, verbose=True)
        N = sum(ops.n(sn, o) for sn, o in product(spin_names, orb_names))
        H_loc = (parms["U"] * (ops.n('up', '0') * ops.n('dn', '0')) -
                 parms['chemical_potential'] * N)

        # Bath Hamiltonian: levels
        H_bath = sum(eps * ops.n("B%i_%s" % (k, sn), 0)
                     for sn, (k,
                              eps) in product(spin_names, enumerate(epsilon)))

        # Hybridization Hamiltonian
        # Bath-impurity hybridization
        V = [
            -2 * bath_prefactor * t1,
        ]
        H_hyb = ops.Operator()
        for k, v in enumerate(V):
            H_hyb += sum(
                v * ops.c_dag("B%i_%s" % (k, sn), 0) * ops.c(sn, '0') +
                np.conj(v) * ops.c_dag(sn, '0') * ops.c("B%i_%s" % (k, sn), 0)
                for sn in spin_names)

        # Obtain bath sites from Delta and create H_ED
        H_ED = H_loc + H_bath + H_hyb

        # Run the solver
        ed.diagonalize(H_ED)
        # Compute G(i\omega)
        G_iw = ed.G_iw(gf_struct, parms['beta'], parms['n_iw'])

        if parms["measure_G2_iw_ph"]:
            common_g2_params = {
                'gf_struct': gf_struct,
                'beta': parms['beta'],
                'blocks': g2_blocks,
                'n_iw': parms['measure_G2_n_bosonic']
            }
            G2_iw = ed.G2_iw_inu_inup(channel="PH",
                                      block_order="AABB",
                                      n_inu=parms['measure_G2_n_fermionic'],
                                      **common_g2_params)

        if mpi.is_master_node():
            with ar.HDFArchive(filename, 'w') as arch:
                arch["parms"] = parms
                arch["G_iw"] = G_iw
                arch["G2_iw"] = G2_iw
                arch["ref"] = ref
    else:  # haspomerol is False
        with ar.HDFArchive(filename, 'r') as arch:
            ref = arch['ref']
            G_iw = arch['G_iw']
            G2_iw = arch['G2_iw']

    BL = lattice.BravaisLattice(units=[
        (1, 0, 0),
    ])  #linear lattice
    kmesh = gf.MeshBrillouinZone(lattice.BrillouinZone(BL), parms["N_x"])
    Hk_blocks = [gf.Gf(indices=orb_names, mesh=kmesh) for spin in spin_names]
    Hk = gf.BlockGf(name_list=spin_names, block_list=Hk_blocks)

    def Hk_f(k):
        return -2 * parms['t1'] * (np.cos(k[0])) * np.eye(1)

    for spin, _ in Hk:
        for k in Hk.mesh:
            Hk[spin][k] = Hk_f(k.value)

    # Construct the DF2 program
    X = dualfermion.Dpt(beta=parms['beta'],
                        gf_struct=gf_struct,
                        Hk=Hk,
                        n_iw=parms['n_iw'],
                        n_iw2=parms["measure_G2_n_fermionic"],
                        n_iW=parms["measure_G2_n_bosonic"])

    for name, g0 in X.Delta:
        X.Delta[name] << gf.inverse(
            gf.iOmega_n +
            parms['chemical_potential_bare']) * bath_prefactor**2 * 4 * t1**2

    X.G2_iw << G2_iw

    # Run the dual perturbation theory
    X.gimp << G_iw  # Load G from impurity solver
    dpt_parms = {key: parms[key] for key in parms if key in dptkeys}
    X.run(**dpt_parms)
Example #20
0
        for o1 in orb_names:
            if h_loc_0_offidag:
                for o2 in orb_names:
                    Hloc_0 += atomic_levels[spin][o1, o2] * (
                        c_dag(spin, o1) * c(spin, o2) +
                        c_dag(spin, o2) * c(spin, o1))
            else:
                o2 = o1
                Hloc_0 += atomic_levels[spin][o1, o2] * (
                    c_dag(spin, o1) * c(spin, o2) +
                    c_dag(spin, o2) * c(spin, o1))

    Hloc_0 += (-mu) * N

# store data obtained
if store_h5 and mpi.is_master_node():
    with HDFArchive(store_h5_file, 'a') as ar:
        ar['block_structure'] = sum_k.block_structure
        ar['mu'] = sum_k.chemical_potential
        # ar['Gloc'] = Gloc
        ar['Hloc_0'] = Hloc_0

# construct interaction matrix
if not 'Hint' in locals():
    if h_int_type == 'slater':
        mpi.report('setting up slater Hamiltonian')
        Umat_full = U_matrix(l=2, U_int=U, J_hund=J, basis='cubic')

        # rotate to den mat diag basis
        Umat_full_rotated = transform_U_matrix(Umat_full, sum_k.rot_mat[0].T)
Example #21
0
def main(input_file, output_file):
    """
    Solve the impurity problem.
    """

    import time
    t_start = time.time()

    with HDFArchive(os.path.abspath(input_file), 'r') as h:
        rot = h['rot'] if 'rot' in h else None
        beta = h['beta']
        gf_struct = h['gf_struct']
        # convert a dict to a list of pairs [ (str,[int,...]), ...]
        gf_struct = [(k, list(v)) for k, v in gf_struct.items()]
        u_mat = h['u_mat']
        n_iw = h['n_iw']
        G0_iw = h['G0_iw']
        params = h['params']

    use_spin_orbit = len(gf_struct) == 1

    # Rotate basis
    u_mat_rot = u_mat.copy()
    G0_iw_rot = G0_iw.copy()
    if not rot is None:
        u_mat_rot = rotate_basis(rot,
                                 use_spin_orbit,
                                 u_mat_rot,
                                 Gfs=[G0_iw_rot],
                                 direction='forward')
    h_int = make_h_int(u_mat_rot, gf_struct)

    # Create a working horse
    S = TRIQSCTHYBSolver(beta, gf_struct, n_iw)
    S.G0_iw << G0_iw_rot

    if 'random_seed' in params:
        raise RuntimeError("Do not set random_seed for triqs/cthyb manually")

    params['random_seed'] = 34788 + 928374 * mpi.rank + params[
        'random_seed_offset']
    del params['random_seed_offset']

    for k in params:
        # e.g. numpy.bool_ to bool
        params[k] = convert_to_built_in_scalar_type(params[k])

    S.solve(h_int=h_int, **params)

    # Retrieve results from the working horse
    Sigma_iw = S.Sigma_iw.copy()
    G_iw = S.G_iw.copy()

    if not rot is None:
        Gfs = [Sigma_iw, G_iw]
        rotate_basis(rot,
                     use_spin_orbit,
                     u_matrix=None,
                     Gfs=Gfs,
                     direction='backward')

    if mpi.is_master_node():
        with HDFArchive(os.path.abspath(output_file), 'w') as h:
            h['Sigma_iw'] = Sigma_iw
            h['Gimp_iw'] = G_iw

    t_end = time.time()
    if mpi.is_master_node():
        print('TRIQS/cthyb ran for {} seconds.'.format(t_end - t_start))
Example #22
0
def dmft_cycle():
    filename = 'nio'
    
    Converter = VaspConverter(filename=filename)
    Converter.convert_dft_input()
    
    SK = SumkDFT(hdf_file = filename+'.h5', use_dft_blocks = False)
    
    beta = 5.0 
     
    Sigma = SK.block_structure.create_gf(beta=beta)
    SK.put_Sigma([Sigma])
    G = SK.extract_G_loc()
    SK.analyse_block_structure_from_gf(G, threshold = 1e-2)
    for i_sh in range(len(SK.deg_shells)):
        num_block_deg_orbs = len(SK.deg_shells[i_sh])
        mpi.report('found {0:d} blocks of degenerate orbitals in shell {1:d}'.format(num_block_deg_orbs, i_sh))
        for iblock in range(num_block_deg_orbs):
            mpi.report('block {0:d} consists of orbitals:'.format(iblock))
            for keys in list(SK.deg_shells[i_sh][iblock].keys()):
                mpi.report('  '+keys)
    
    # Setup CTQMC Solver
    
    n_orb = SK.corr_shells[0]['dim']
    spin_names = ['up','down']
    orb_names = [i for i in range(0,n_orb)]
    
    #gf_struct = set_operator_structure(spin_names, orb_names, orb_hyb)
    gf_struct = SK.gf_struct_solver[0]
    mpi.report('Sumk to Solver: %s'%SK.sumk_to_solver)
    mpi.report('GF struct sumk: %s'%SK.gf_struct_sumk)
    mpi.report('GF struct solver: %s'%SK.gf_struct_solver)
    
    S = Solver(beta=beta, gf_struct=gf_struct)
    
    # Construct the Hamiltonian and save it in Hamiltonian_store.txt
    H = Operator() 
    U = 8.0
    J = 1.0
    
    
    U_sph = U_matrix(l=2, U_int=U, J_hund=J)
    U_cubic = transform_U_matrix(U_sph, spherical_to_cubic(l=2, convention=''))
    Umat, Upmat = reduce_4index_to_2index(U_cubic)
    
    H = h_int_density(spin_names, orb_names, map_operator_structure=SK.sumk_to_solver[0], U=Umat, Uprime=Upmat)
    
    # Print some information on the master node
    mpi.report('Greens function structure is: %s '%gf_struct)
    mpi.report('U Matrix set to:\n%s'%Umat)
    mpi.report('Up Matrix set to:\n%s'%Upmat)
    
    # Parameters for the CTQMC Solver
    p = {}
    p["max_time"] = -1
    p["random_name"] = ""
    p["random_seed"] = 123 * mpi.rank + 567
    p["length_cycle"] = 100
    p["n_warmup_cycles"] = 2000
    p["n_cycles"] = 20000
    p["fit_max_moment"] = 4
    p["fit_min_n"] = 30
    p["fit_max_n"] = 50
    p["perform_tail_fit"] = True
    
    # Double Counting: 0 FLL, 1 Held, 2 AMF
    DC_type = 0
    DC_value = 59.0
    
    # Prepare hdf file and and check for previous iterations
    n_iterations = 1
    
    iteration_offset = 0
    if mpi.is_master_node():
        ar = HDFArchive(filename+'.h5','a')
        if not 'DMFT_results' in ar: ar.create_group('DMFT_results')
        if not 'Iterations' in ar['DMFT_results']: ar['DMFT_results'].create_group('Iterations')
        if not 'DMFT_input' in ar: ar.create_group('DMFT_input')
        if not 'Iterations' in ar['DMFT_input']: ar['DMFT_input'].create_group('Iterations')
        if not 'code_versions' in ar['DMFT_input']: ar['DMFT_input'].create_group('code_versio\
    ns')
        ar['DMFT_input']['code_versions']["triqs_version"] = triqs_version.version
        ar['DMFT_input']['code_versions']["triqs_git"] = triqs_version.git_hash
        ar['DMFT_input']['code_versions']["cthyb_version"] = cthyb_version.version
        ar['DMFT_input']['code_versions']["cthyb_git"] = cthyb_version.triqs_cthyb_hash
        ar['DMFT_input']['code_versions']["dft_tools_version"] = dft_tools_version.version
        ar['DMFT_input']['code_versions']["dft_tools_git"] = dft_tools_version.triqs_dft_tools_hash
        if 'iteration_count' in ar['DMFT_results']:
            iteration_offset = ar['DMFT_results']['iteration_count']+1
            S.Sigma_iw = ar['DMFT_results']['Iterations']['Sigma_it'+str(iteration_offset-1)]
            SK.dc_imp = ar['DMFT_results']['Iterations']['dc_imp'+str(iteration_offset-1)]
            SK.dc_energ = ar['DMFT_results']['Iterations']['dc_energ'+str(iteration_offset-1)]
            SK.chemical_potential = ar['DMFT_results']['Iterations']['chemical_potential'+str(iteration_offset-1)].real
        ar['DMFT_input']["dmft_script_it"+str(iteration_offset)] = open(sys.argv[0]).read()
    iteration_offset = mpi.bcast(iteration_offset)
    S.Sigma_iw = mpi.bcast(S.Sigma_iw)
    SK.dc_imp = mpi.bcast(SK.dc_imp)
    SK.dc_energ = mpi.bcast(SK.dc_energ)
    SK.chemical_potential = mpi.bcast(SK.chemical_potential)
    
    # Calc the first G0
    SK.symm_deg_gf(S.Sigma_iw, ish=0)
    SK.put_Sigma(Sigma_imp = [S.Sigma_iw])
    SK.calc_mu(precision=0.01)
    S.G_iw << SK.extract_G_loc()[0]
    SK.symm_deg_gf(S.G_iw, ish=0)
    
    #Init the DC term and the self-energy if no previous iteration was found
    if iteration_offset == 0:
        dm = S.G_iw.density()
        SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
        S.Sigma_iw << SK.dc_imp[0]['up'][0,0]
    
    mpi.report('%s DMFT cycles requested. Starting with iteration %s.'%(n_iterations,iteration_offset))
    
    
    
    # The infamous DMFT self consistency cycle
    for it in range(iteration_offset, iteration_offset + n_iterations):
        mpi.report('Doing iteration: %s'%it)
        
        # Get G0
        S.G0_iw << inverse(S.Sigma_iw + inverse(S.G_iw))
        # Solve the impurity problem
        S.solve(h_int = H, **p)
        if mpi.is_master_node(): 
            ar['DMFT_input']['Iterations']['solver_dict_it'+str(it)] = p
            ar['DMFT_results']['Iterations']['Gimp_it'+str(it)] = S.G_iw
            ar['DMFT_results']['Iterations']['Gtau_it'+str(it)] = S.G_tau
            ar['DMFT_results']['Iterations']['Sigma_uns_it'+str(it)] = S.Sigma_iw
        # Calculate double counting
        dm = S.G_iw.density()
        SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
        # Get new G
        SK.symm_deg_gf(S.Sigma_iw, ish=0)
        SK.put_Sigma(Sigma_imp=[S.Sigma_iw])
        SK.calc_mu(precision=0.01)
        S.G_iw << SK.extract_G_loc()[0]
        
        # print densities
        for sig,gf in S.G_iw:
            mpi.report("Orbital %s density: %.6f"%(sig,dm[sig][0,0]))
        mpi.report('Total charge of Gloc : %.6f'%S.G_iw.total_density())
    
        if mpi.is_master_node(): 
            ar['DMFT_results']['iteration_count'] = it
            ar['DMFT_results']['Iterations']['Sigma_it'+str(it)] = S.Sigma_iw
            ar['DMFT_results']['Iterations']['Gloc_it'+str(it)] = S.G_iw
            ar['DMFT_results']['Iterations']['G0loc_it'+str(it)] = S.G0_iw
            ar['DMFT_results']['Iterations']['dc_imp'+str(it)] = SK.dc_imp
            ar['DMFT_results']['Iterations']['dc_energ'+str(it)] = SK.dc_energ
            ar['DMFT_results']['Iterations']['chemical_potential'+str(it)] = SK.chemical_potential
    
    
    
    
    if mpi.is_master_node():
        print('calculating mu...')
    SK.chemical_potential = SK.calc_mu( precision = 0.000001 )
    
    if mpi.is_master_node():
        print('calculating GAMMA')
    SK.calc_density_correction(dm_type='vasp')
    
    if mpi.is_master_node():
        print('calculating energy corrections')
    
    correnerg = 0.5 * (S.G_iw * S.Sigma_iw).total_density()
    
    dm = S.G_iw.density() # compute the density matrix of the impurity problem
    SK.calc_dc(dm, U_interact=U, J_hund=J, orb=0, use_dc_formula=DC_type,use_dc_value=DC_value)
    dc_energ = SK.dc_energ[0]
    
    if mpi.is_master_node(): 
        ar['DMFT_results']['Iterations']['corr_energy_it'+str(it)] = correnerg
        ar['DMFT_results']['Iterations']['dc_energy_it'+str(it)] = dc_energ
    
    if mpi.is_master_node(): del ar
        
    return correnerg, dc_energ
Example #23
0
Delta_min = 1e-5          # minimal value for the hybridisation function; if too large, it produces incorrect spectral distribution,
                          # if too small, it leads to discretization problems (1e-5 is usually a good and rather safe choice)
normalize_to_one = True   # scaling of the spectral function (relevant in the case of block structure and/or matrix structure of GF)
solution_filename = "solution.h5"
checkpoint_filename = "checkpoint.h5"

# Additional quantities of interest
observables = ["n_d", "n_d^2"]
if B is not None:
  observables.extend(["SZd"])
if "Holstein" in model:
  observables.extend(["nph", "displ", "displ^2"])

# Run-time global variables
itern = 0                                          # iteration counter
verbose = verbose and mpi.is_master_node()         # output is only produced by the master node
store_steps = store_steps and mpi.is_master_node() # output is only produced by the master node
symtype = ("QS" if B is None else "QSZ")

# Set up the Solver
S = Solver(model=model, symtype=symtype, mesh_max=mesh_max, mesh_min=mesh_min, mesh_ratio=mesh_ratio)
S.set_verbosity(verbose_nrg)

newG = lambda : S.G_w.copy()                             # Creates a BlockGf object of appropriate structure
nr_blocks = lambda bgf : len([bl for bl in bgf.indices]) # Returns the number of blocks in a BlockGf object
block_size = lambda bl : len(S.G_w[bl].indices[0])       # Matrix size of Green's functions in block 'bl'
identity = lambda bl : np.identity(block_size(bl))       # Returns the identity matrix in block 'bl'

# Solve Parameters
sp = { "T": T, "Lambda": 2.0, "Nz": 4, "Tmin": 1e-5, "keep": 10000, "keepenergy": 10.0 }
Example #24
0
def _main_mpi(model_hdf5_file, input_file, output_file):
    """

    Launch SumkDFT and compute chemical potential, local Green's function and density matrix
    This function depends on MPI through DFTTools.
    Do not call this from non-MPI module directly.

    """

    import triqs.utility.mpi as mpi

    # read HDF5 file on the master node
    if mpi.is_master_node():
        with HDFArchive(input_file, 'r') as h:
            params = h['params']
            keys = list(params.keys())
    else:
        params = {}
        keys = []
    assert isinstance(params, dict)

    # broadcast parameters
    keys = mpi.bcast(keys)
    for key in keys:
        if not mpi.is_master_node():
            params[key] = None
        params[key] = mpi.bcast(params[key])

    beta = params['beta']
    with_dc = params['with_dc']

    results = {}

    def add_potential(_sigma, _pot):
        sigma_plus_pot = _sigma.copy()
        for sp, sigma in sigma_plus_pot:
            sigma += _pot[sp]
        return sigma_plus_pot

    def setup_sk(sk, iwn_or_w_or_none):
        if iwn_or_w_or_none == 'iwn':
            assert len(params['Sigma_iw_sh']) == len(params['potential'])
            Sigma_iw_sh_plus_pot = [
                add_potential(sigma, pot) for sigma, pot in zip(
                    params['Sigma_iw_sh'], params['potential'])
            ]
            sk.set_Sigma(Sigma_iw_sh_plus_pot)
        elif iwn_or_w_or_none == 'w':
            # sk.set_Sigma([params['Sigma_w_sh'][ish] for ish in range(sk.n_inequiv_shells)])
            Sigma_w_sh = [
                params['Sigma_w_sh'][ish] for ish in range(sk.n_inequiv_shells)
            ]
            Sigma_w_sh_plus_pot = [
                add_potential(sigma, pot)
                for sigma, pot in zip(Sigma_w_sh, params['potential'])
            ]
            sk.set_Sigma(Sigma_w_sh_plus_pot)
        elif iwn_or_w_or_none == "none":
            pass
        else:
            raise RuntimeError("Invalid iwn_or_w")

        if params['with_dc']:
            sk.set_dc(params['dc_imp'], params['dc_energ'])
        sk.set_mu(params['mu'])

    if params['calc_mode'] == 'Gloc':
        from triqs_dft_tools import SumkDFT
        sk = SumkDFT(hdf_file=model_hdf5_file,
                     use_dft_blocks=False,
                     h_field=0.0)
        setup_sk(sk, 'iwn')
        if params['adjust_mu']:
            # find the chemical potential for given density
            sk.calc_mu(params['prec_mu'])
            results['mu'] = float(sk.chemical_potential)

        # Local Green's function and Density matrix
        results['Gloc_iw_sh'] = sk.extract_G_loc(with_dc=with_dc)
        dm = sk.density_matrix(beta=beta)
        for ish in range(len(dm)):
            for b in list(dm[ish].keys()):
                dm[ish][b] = numpy.conj(dm[ish][b])
        results['dm_sh'] = dm

    elif params['calc_mode'] == 'dos':
        # Compute dos
        from .sumkdft_post import SumkDFTDCorePost
        sk = SumkDFTDCorePost(hdf_file=model_hdf5_file,
                              use_dft_blocks=False,
                              h_field=0.0)
        setup_sk(sk, 'w')
        results['dos'], results['dosproj'], results['dosproj_orb'] = \
            sk.dos_wannier_basis(broadening=params['broadening'],
                             mesh=params['mesh'],
                             with_Sigma=True, with_dc=with_dc, save_to_file=False)

    elif params['calc_mode'] == 'spaghettis':
        # A(k, omega)
        from .sumkdft_post import SumkDFTDCorePost
        sk = SumkDFTDCorePost(hdf_file=model_hdf5_file,
                              use_dft_blocks=False,
                              h_field=0.0,
                              bands_data=params['bands_data'])
        setup_sk(sk, 'w')
        results['akw'] = sk.spaghettis(broadening=params['broadening'],
                                       plot_range=None,
                                       ishell=None,
                                       save_to_file=None)

    elif params['calc_mode'] == 'momentum_distribution':
        # n(k)
        from .sumkdft_post import SumkDFTDCorePost
        sk = SumkDFTDCorePost(hdf_file=model_hdf5_file,
                              use_dft_blocks=False,
                              h_field=0.0)
        setup_sk(sk, 'iwn')
        results['den'] = \
            sk.calc_momentum_distribution(mu=params["mu"], beta=beta, with_Sigma=True, with_dc=True)

    elif params['calc_mode'] == 'bse':
        # chi0
        from dft_tools.sumk_dft_chi import SumkDFTChi
        # save div data (overwrite if data exist)
        if mpi.is_master_node():
            with HDFArchive(model_hdf5_file, 'a') as ar:
                if 'dft_input_chi' in ar:
                    del ar['dft_input_chi']
                ar.create_group('dft_input_chi')
                ar['dft_input_chi']['div'] = numpy.array(params['div'])
        # check if IBZ and FBZ data are saved separately
        dft_data_fbz = 'dft_input'
        if mpi.is_master_node():
            with HDFArchive(model_hdf5_file, 'r') as ar:
                if 'dft_input_fbz' in ar:
                    dft_data_fbz = 'dft_input_fbz'
        dft_data_fbz = mpi.bcast(dft_data_fbz)
        sk = SumkDFTChi(hdf_file=model_hdf5_file,
                        use_dft_blocks=False,
                        h_field=0.0,
                        dft_data_fbz=dft_data_fbz)
        setup_sk(sk, 'iwn')

        temp_file = None
        if params['use_temp_file']:
            temp_file = 'G_k_iw_temp.h5'

        sk.save_X0q_for_bse(list_wb=params['list_wb'],
                            n_wf_cutoff=params['n_wf_G2'],
                            qpoints_saved=params['X0q_qpoints_saved'],
                            h5_file=params['bse_h5_out_file'],
                            temp_file=temp_file,
                            nonlocal_order_parameter=False)
    else:
        raise RuntimeError("Unknown calc_mode: " + str(params['calc_mode']))

    if mpi.is_master_node():
        with HDFArchive(output_file, 'w') as h:
            for k, v in list(results.items()):
                h[k] = v
Example #25
0
def plot(filename):

    if mpi.is_master_node():
        with ar.HDFArchive(filename, 'r') as arch:
            parms = arch["parms"]
            t1 = parms['t1']
            gimp = arch["G_iw"][ref_spin]
            ref = arch["ref"]
        sigma_k = HDFArchive("sigma_k.h5", 'r')['sigma_k'][ref_spin]
        G_k = HDFArchive("G_k.h5", 'r')['G_k'][ref_spin]

        inv = np.linalg.inv

        # Calculate lattice self-energy
        for ki, k in enumerate(sigma_k.mesh[1]):
            selfenergylist = []
            ref_list = []
            simp_list = []

            kx = k.value[0]
            tk = -2 * t1 * (np.cos(kx))

            def factor(ii):
                return np.exp(1j * kx * ii)

            for wn in sigma_k.mesh[0]:
                wval = wn.value.imag
                if wval < 0: continue
                S = sigma_k[(wn, k)] + parms['chemical_potential']

                invG0k = wn.value + parms['chemical_potential'] - tk
                #S = invG0k-1./G_k[(wn,k)]

                selfenergylist.append([
                    wval,
                ] + list(S.flatten()))

                # Reference data, convert from 2x2 matrix to complex number with correct k
                ref_G = np.sum(
                    factor(ii) * ref[(wn)][0, ii] for ii in range(2))
                ref_S = invG0k - 1. / ref_G
                ref_list.append([
                    wval,
                ] + list(ref_S.flatten()))
                #ref_list.append( [wval,]+list(ref_G.flatten()) )

                # calculate impurity self-energy as well, from runfile['G_iw']
                g = gimp[(wn)]

                # This was done using TODO check factors Delta
                invg0 = wn.value + parms[
                    'chemical_potential'] - bath_prefactor**2 * 4 * t1**2 / (
                        wn.value + parms['chemical_potential_bare'])
                Simp = invg0 - 1. / g
                simp_list.append([
                    wval,
                ] + list(Simp.flatten()))

            s = np.array(selfenergylist)
            r = np.array(ref_list)
            s2 = np.array(simp_list)
            for column in range(1, 2):
                assert np.max(np.abs(s[:5, column] - r[:5, column])) < 1e-4
Example #26
0
def imtime_bubble_chi0_wk(g_wk, nw=1, save_memory=False):
    ncores = multiprocessing.cpu_count()

    wmesh, kmesh = g_wk.mesh.components

    norb = g_wk.target_shape[0]
    beta = wmesh.beta
    nw_g = len(wmesh)
    nk = len(kmesh)

    ntau = 2 * nw_g

    # -- Memory Approximation

    ng_tr = ntau * np.prod(nk) * norb**2  # storing G(tau, r)
    ng_wr = nw_g * np.prod(nk) * norb**2  # storing G(w, r)
    ng_t = ntau * norb**2  # storing G(tau)

    nchi_tr = ntau * np.prod(nk) * norb**4  # storing \chi(tau, r)
    nchi_wr = nw * np.prod(nk) * norb**4  # storing \chi(w, r)
    nchi_t = ntau * norb**4  # storing \chi(tau)
    nchi_w = nw * norb**4  # storing \chi(w)
    nchi_r = np.prod(nk) * norb**4  # storing \chi(r)

    if nw == 1:
        ntot_case_1 = ng_tr + ng_wr
        ntot_case_2 = ng_tr + nchi_wr + ncores * (nchi_t + 2 * ng_t)
        ntot_case_3 = 4 * nchi_wr

        ntot = max(ntot_case_1, ntot_case_2, ntot_case_3)

    else:
        ntot_case_1 = ng_tr + nchi_tr + ncores * (nchi_t + 2 * ng_t)
        ntot_case_2 = nchi_tr + nchi_wr + ncores * (nchi_w + nchi_t)

        ntot = max(ntot_case_1, ntot_case_2)

    nbytes = ntot * np.complex128().nbytes
    ngb = nbytes / 1024.**3

    if mpi.is_master_node():
        print(tprf_banner(), "\n")
        print('beta  =', beta)
        print('nk    =', nk)
        print('nw    =', nw_g)
        print('norb  =', norb)
        print()
        print('Approx. Memory Utilization: %2.2f GB\n' % ngb)

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

    mpi.report('--> fourier_wr_to_tr')
    g_tr = fourier_wr_to_tr(g_wr)
    del g_wr

    if nw == 1:
        mpi.report('--> chi0_w0r_from_grt_PH (bubble in tau & r)')
        chi0_wr = chi0_w0r_from_grt_PH(g_tr)
        del g_tr
    else:
        if not save_memory:
            mpi.report('--> chi0_tr_from_grt_PH (bubble in tau & r)')
            chi0_tr = chi0_tr_from_grt_PH(g_tr)
            del g_tr

            mpi.report('--> chi_wr_from_chi_tr')
            chi0_wr = chi_wr_from_chi_tr(chi0_tr, nw=nw)
            del chi0_tr
        elif save_memory:
            chi0_wr = chi0_wr_from_grt_PH(g_tr, nw=nw)

    mpi.report('--> chi_wk_from_chi_wr (r->k)')
    chi0_wk = chi_wk_from_chi_wr(chi0_wr)
    del chi0_wr

    return chi0_wk
Example #27
0
    def dmft_step(self, Delta_in):
        self.itern += 1
        if verbose():
            print("\nIteration %i min_iter=%i max_iter=%i" %
                  (self.itern, self.dmft_param["min_iter"],
                   self.dmft_param["max_iter"]))
        Delta_in_fixed = fix_hyb_function(Delta_in,
                                          self.dmft_param["Delta_min"])
        self.S.Delta_w << Delta_in_fixed

        t0 = timeit.default_timer()
        self.S.solve(**self.sp)  # Solve the impurity model
        t1 = timeit.default_timer()
        dt = int(t1 - t0)
        solver_time = '{:02}:{:02}:{:02}'.format(dt // 3600, dt % 3600 // 60,
                                                 dt % 60)  # hh:mm:ss format

        self.Gself = calc_G(
            Delta_in_fixed, self.S.Sigma_w,
            self.mu)  # impurity GF ("self-energy-trick" improved)
        Gloc_prev = self.Gloc.copy(
        )  # store copy of previous Gloc for checking convergence
        self.Gloc, self.Delta = self_consistency(
            self.S.Sigma_w, self.mu,
            self.ht)  # apply the DMFT self-consistency equation
        self.occupancy = calc_occupancy(
            self.Delta, self.S.Sigma_w, self.mu,
            self.T)  # occupancy calculated from the local lattice GF

        diff_loc_imp = gf_diff(
            self.Gself,
            self.Gloc)  # difference between impurity and local lattice GF
        diff_prev = gf_diff(
            self.Gloc, Gloc_prev
        )  # difference between two consecutively computed local latice GFs
        diff_occupancy = abs(
            self.occupancy - self.occupancy_goal
        )  # this difference is used as the measure of deviation

        stats = OrderedDict([("itern", self.itern), ("time", solver_time),
                             ("mu", self.mu), ("diff_loc_imp", diff_loc_imp),
                             ("diff_prev", diff_prev),
                             ("diff_occupancy", diff_occupancy),
                             ("occupancy", self.occupancy)])
        for i in self.observables:
            stats[i] = self.S.expv[i]
        header_string = fmt_str_header(
            len(stats)).format(*[i for i in stats.keys()])
        stats_string = fmt_str(len(stats)).format(*[i for i in stats.values()])
        if mpi.is_master_node():
            if self.itern == 1:
                print(header_string, file=self.stats_file)
            print(stats_string, file=self.stats_file)
        if verbose():
            print(header_string)
            print(stats_string)

        if self.dmft_param["store_steps"] and mpi.is_master_node():
            os.mkdir(str(self.itern))  # one subdirectory per iteration
            save_BlockGf(str(self.itern) + "/Delta", Delta_in_fixed)
            save_BlockGf(str(self.itern) + "/Sigma",
                         self.S.Sigma_w)  # self-energy
            save_BlockGf(str(self.itern) + "/G",
                         self.Gloc)  # local lattice Green's function
            save_BlockA(str(self.itern) + "/A",
                        self.Gloc)  # spectral function of local lattice GF
            self.store_result(str(self.itern) + "/" + self.solution_filename)

        if mpi.is_master_node():
            self.store_result(self.checkpoint_filename
                              )  # for checkpoint/restart functionality

        # Check for convergence
        if (diff_loc_imp < self.dmft_param["eps_loc_imp"]
                and diff_prev < self.dmft_param["eps_prev"]
                and diff_occupancy < self.dmft_param["eps_occupancy"]):
            self.okn += 1
        else:
            self.okn = 0

        # The only way to exit the DMFT loop is by generating exceptions.
        if (self.okn >= self.dmft_param.get("conv_iter", 1)
                and self.itern >= self.dmft_param["min_iter"]):
            if mpi.is_master_node():
                self.store_result(self.solution_filename
                                  )  # full converged results as an HDF5 file
                try:
                    os.remove(self.checkpoint_filename
                              )  # checkpoint file is no longer needed
                except OSError:
                    pass
                if self.converged_flag_file:
                    touch(self.converged_flag_file
                          )  # signal convergence through a file
            raise Converged("%s\n%s" % (header_string, stats_string))
        if (self.itern == self.dmft_param["max_iter"]):
            raise FailedToConverge("%s\n%s" % (header_string, stats_string))
        if self.stop_flag_file and os.path.isfile(self.stop_flag_file):
            raise ForcedStop()

        if self.dmft_param["occup_method"] == "adjust":
            self.Gloc, self.Delta, new_mu = self.adjust_mu(
                self.Delta, self.S.Sigma_w,
                self.mu)  # here we update mu to get closer to target occupancy
            self.set_mu(new_mu)

        return self.Delta
Example #28
0
File: bse.py Project: TRIQS/tprf
def solve_lattice_bse_at_specific_w(g_wk, gamma_wnn, nw_index):
    r""" Compute the generalized lattice susceptibility 
    :math:`\chi_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, \mathbf{k})` using the Bethe-Salpeter 
    equation (BSE) for a specific :math:`i\omega_{n=\mathrm{nw\_index}}`.


    Parameters
    ----------

    g_wk : Gf,
           Single-particle Green's function :math:`G_{a\bar{b}}(i\nu_n, \mathbf{k})`.
    gamma_wnn : Gf,
                Local particle-hole vertex function 
                :math:`\Gamma_{a\bar{b}c\bar{d}}(i\omega_n, i\nu_n, i\nu_n')`.
    nw_index : int,
               The bosonic Matsubara frequency index :math:`i\omega_{n=\mathrm{nw\_index}}`
               at which the BSE is solved.

    Returns
    -------
    chi_k : Gf,
            Generalized lattice susceptibility 
            :math:`\chi_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, \mathbf{k})`.

    chi0_k : Gf,
             Generalized bare lattice susceptibility 
             :math:`\chi^0_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, \mathbf{k})`.
    """

    # Only use \Gamma at the specific \omega
    gamma_nn = gamma_wnn[Idx(nw_index), :, :]
    # Keep fake bosonic mesh for usability with other functions
    gamma_wnn = add_fake_bosonic_mesh(gamma_nn)

    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)
    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 at specific \omega.\n'
        )
        print('nk    =', nk)
        print('nw_index    =', nw_index)
        print('nwf   =', nwf)
        print('nwf_g =', nwf_g)
        print()

    mpi.report('--> chi0_wk_tail_corr')
    # Calculate chi0_wk up to the specific \omega
    chi0_wk_tail_corr = imtime_bubble_chi0_wk(g_wk,
                                              nw=np.abs(nw_index) + 1,
                                              save_memory=True)
    # Only use specific \omega, but put back on fake bosonic mesh
    chi0_k_tail_corr = chi0_wk_tail_corr[Idx(nw_index), :]
    chi0_wk_tail_corr = add_fake_bosonic_mesh(chi0_k_tail_corr,
                                              beta=bmesh.beta)

    chi0_nk = get_chi0_nk_at_specific_w(g_wk, nw_index=nw_index, nwf=nwf)
    # Keep fake bosonic mesh for usability with other functions
    chi0_wnk = add_fake_bosonic_mesh(chi0_nk)

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

    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.')

    chi_k = chi_kw[:, Idx(0)]
    del chi_kw

    chi0_k = chi0_kw[:, Idx(0)]
    del chi0_kw

    return chi_k, chi0_k
S = Solver(**constr_params)

# --------- Initialize G0_iw ----------
S.G0_iw << G0_iw

# --------- Solve! ----------
solve_params = {
    'h_int': h_int,
    'n_warmup_cycles': 100,
    'n_cycles': 1000,
    'length_cycle': 100
}
S.solve(**solve_params)

# -------- Save in archive ---------
if mpi.is_master_node():
    with HDFArchive("2orb_Discrete_Bath.out.h5", 'w') as results:
        results["G_iw"] = S.G_iw
        results["G_tau"] = S.G_tau

from triqs.utility.h5diff import h5diff
if args.libcxx:
    h5diff("2orb_Discrete_Bath.libcxx.ref.h5",
           "2orb_Discrete_Bath.out.h5",
           precision=1.e-5)
elif args.gccver_ge11:
    h5diff("2orb_Discrete_Bath.gccver_ge11.ref.h5",
           "2orb_Discrete_Bath.out.h5",
           precision=1.e-5)
else:
    h5diff("2orb_Discrete_Bath.ref.h5",
Example #30
0
def verbose():
    return be_verbose and mpi.is_master_node()