Ejemplo n.º 1
0
def make_calc(beta=2.0, h_field=0.0):
    
    # ------------------------------------------------------------------
    # -- Hubbard atom with two bath sites, Hamiltonian

    p = ParameterCollection(
        beta = beta,
        h_field = h_field,
        U = 5.0,
        ntau = 40,
        niw = 15,
        )

    p.mu = 0.5*p.U
    
    # ------------------------------------------------------------------

    print('--> Solving SIAM with parameters')
    print(p)
    
    # ------------------------------------------------------------------

    up, do = 'up', 'dn'
    docc = c_dag(up,0) * c(up,0) * c_dag(do,0) * c(do,0)
    mA = c_dag(up,0) * c(up,0) - c_dag(do,0) * c(do,0)
    nA = c_dag(up,0) * c(up,0) + c_dag(do,0) * c(do,0)

    p.H = -p.mu * nA + p.U * docc + p.h_field * mA
    
    # ------------------------------------------------------------------

    fundamental_operators = [c(up,0), c(do,0)]
    
    ed = TriqsExactDiagonalization(p.H, fundamental_operators, p.beta)

    g_tau = GfImTime(beta=beta, statistic='Fermion', n_points=40, indices=[0])
    g_iw = GfImFreq(beta=beta, statistic='Fermion', n_points=10, indices=[0])

    p.G_tau = BlockGf(name_list=[up,do], block_list=[g_tau]*2, make_copies=True)
    p.G_iw = BlockGf(name_list=[up,do], block_list=[g_iw]*2, make_copies=True)
    
    ed.set_g2_tau(p.G_tau[up], c(up,0), c_dag(up,0))
    ed.set_g2_tau(p.G_tau[do], c(do,0), c_dag(do,0))

    ed.set_g2_iwn(p.G_iw[up], c(up,0), c_dag(up,0))
    ed.set_g2_iwn(p.G_iw[do], c(do,0), c_dag(do,0))

    p.magnetization = ed.get_expectation_value(0.5 * mA)
    p.magnetization2 = ed.get_expectation_value(0.25 * mA * mA)
    
    # ------------------------------------------------------------------
    # -- Store to hdf5
    
    filename = 'data_pyed_h_field_%4.4f.h5' % h_field
    with HDFArchive(filename,'w') as res:
        res['p'] = p
Ejemplo n.º 2
0
def legendre_filter(G_tau, order=100, G_l_cut=1e-19):
    """ Filter binned imaginary time Green's function
    using a Legendre filter of given order and coefficient threshold. 
    
    Parameters
    ----------

    G_tau : TRIQS imaginary time Block Green's function

    order : int
        Legendre expansion order in the filter

    G_l_cut : float
        Legendre coefficient cut-off 

    Returns
    -------

    G_l : TRIQS Legendre Block Green's function
        Fitted Green's function on a Legendre mesh

    """
    l_g_l = []

    for b, g in G_tau:

        g_l = fit_legendre(g, order=order)
        g_l.data[:] *= (np.abs(g_l.data) > G_l_cut)
        enforce_discontinuity(g_l, np.array([[1.]]))
        l_g_l.append(g_l)

    G_l = BlockGf(name_list=list(G_tau.indices), block_list=l_g_l)
    return G_l
Ejemplo n.º 3
0
def get_test_impurity_model(norb=2, ntau=1000, beta=10.0):
    """ Function that generates a random impurity model for testing """

    from triqs.operators import c, c_dag, Operator, dagger

    from pyed.OperatorUtils import fundamental_operators_from_gf_struct
    from pyed.OperatorUtils import symmetrize_quartic_tensor
    from pyed.OperatorUtils import get_quadratic_operator
    from pyed.OperatorUtils import operator_from_quartic_tensor

    orb_idxs = list(np.arange(norb))
    #print "orb_idxs ", orb_idxs
    spin_idxs = ['up', 'do']
    gf_struct = [[spin_idx, orb_idxs] for spin_idx in spin_idxs]
    #print "gf_struct", gf_struct

    # -- Random Hamiltonian

    fundamental_operators = fundamental_operators_from_gf_struct(gf_struct)
    #print "fundamental_operators ", fundamental_operators

    N = len(fundamental_operators)
    t_OO = np.random.random((N, N)) + 1.j * np.random.random((N, N))
    t_OO = 0.5 * (t_OO + np.conj(t_OO.T))

    #print "N", N
    #print "t_OO", t_OO.shape

    #print 't_OO.real =\n', t_OO.real
    #print 't_OO.imag =\n', t_OO.imag

    U_OOOO = np.random.random((N, N, N, N)) + 1.j * np.random.random(
        (N, N, N, N))
    U_OOOO = symmetrize_quartic_tensor(U_OOOO, conjugation=True)

    #print 'gf_struct =', gf_struct
    #print 'fundamental_operators = ', fundamental_operators


    H_loc = get_quadratic_operator(t_OO, fundamental_operators) + \
        operator_from_quartic_tensor(U_OOOO, fundamental_operators)

    #print 'H_loc =', H_loc
    #print "H_loc.type", H_loc.type()

    from triqs.gf import MeshImTime, BlockGf

    mesh = MeshImTime(beta, 'Fermion', ntau)
    Delta_tau = BlockGf(mesh=mesh, gf_struct=gf_struct)

    #print "mesh", mesh
    #print "Delta_tau", Delta_tau

    for block_name, delta_tau in Delta_tau:
        delta_tau.data[:] = -0.5

    return gf_struct, Delta_tau, H_loc
Ejemplo n.º 4
0
def w2dyn_ndarray_to_triqs_BlockGF_iw_beta_niw(giw, n_iw, beta, gf_struct):
    """ Convert a W2Dynamics ndarray format with indices [wosos] or [wff]
    where t is time, o is orbital, s is spin index, f is flavour
    to a block Triqs Matsubara response function 

    Takes: 
    giw  : Green function as numpy array
    beta : inverse temperature
    niw : number of Matsubaras
    gf_struct: desired block structure of triqs GF

    Returns: 
    BlockGF : triqs block Green function the response function data

    Author: Hugo U. R. Strand (2019) """

    ### check number of Matsubaras is correct and as last dimension
    ### the variable n_iw has only positive Matsubaras, the objects
    ### have both negative and positive
    n_iw_check = giw.shape[-1] / 2
    assert n_iw_check == n_iw

    ### check if giw is 3 or 5 dimensional, and make it 3 dimensional
    if len(giw.shape) == 5:
        norbs = giw.shape[0]
        nspin = giw.shape[1]
        nflavour = norbs * nspin
        giw = giw.reshape(nflavour, nflavour, 2 * n_iw)
    elif len(giw.shape) == 3:
        nflavour = giw.shape[0]
    else:
        raise Exception(
            "giw array must be 3 or 5 dimensional with iw as last dimension!")

    ### generate triqs Green function with same dimension than
    ### the input; this may not be a good idea if worm is used
    ### since then the output can have another structure...
    from triqs.gf import MeshImFreq, BlockGf
    iw_mesh = MeshImFreq(beta, 'Fermion', n_iw)
    G_iw = BlockGf(mesh=iw_mesh, gf_struct=gf_struct)

    ### read out blocks from full w2dyn matrices
    offset = 0
    for name, g_iw in G_iw:

        size1 = G_iw[name].data.shape[-1]
        size2 = G_iw[name].data.shape[-2]
        assert (size1 == size2)
        size_block = size1
        giw_block = giw[offset:offset + size_block,
                        offset:offset + size_block, :]
        g_iw.data[:] = giw_block.transpose(2, 0, 1)

        offset += size_block

    return G_iw
Ejemplo n.º 5
0
    def __init__(self,
                 beta,
                 gf_struct,
                 n_iw=1025,
                 n_tau=10001,
                 n_l=30,
                 delta_interface=False,
                 complex=False):
        """Constructor setting up response function parameters

        Arguments:
        beta : inverse temperature
        gf_struct : Triqs Green's function block structure
        n_iw : number of Matsubara frequencies
        n_tau : number of imaginary time points
        """

        self.constr_params = {
            "beta": beta,
            "gf_struct": gf_struct,
            "n_iw": n_iw,
            "n_tau": n_tau,
            "n_l": n_l,
            "delta_interface": delta_interface
        }

        self.beta = beta
        self.gf_struct = gf_struct
        self.n_iw = n_iw
        self.n_tau = n_tau
        self.n_l = n_l
        self.delta_interface = delta_interface
        self.complex = complex

        self.tau_mesh = MeshImTime(beta, 'Fermion', n_tau)
        self.iw_mesh = MeshImFreq(beta, 'Fermion', n_iw)

        if self.delta_interface:
            self.Delta_tau = BlockGf(mesh=self.tau_mesh,
                                     gf_struct=self.gf_struct)
        else:
            self.G0_iw = BlockGf(mesh=self.iw_mesh, gf_struct=gf_struct)
Ejemplo n.º 6
0
    def test_sumk_discrete(self):
        tbl_w90 = TB_from_wannier90(seed='wannier_TB_test',
                                    path='./',
                                    extend_to_spin=False)

        SK = SumkDiscreteFromLattice(lattice=tbl_w90, n_points=10)
        Sigma_proto = GfImFreq(
            mesh=MeshImFreq(beta=40, S='Fermion', n_max=1025),
            target_shape=[tbl_w90.n_orbitals, tbl_w90.n_orbitals])
        Sigma_iw = BlockGf(name_list=['up', 'down'],
                           block_list=[Sigma_proto, Sigma_proto],
                           make_copies=True)

        # Sumk only accepts Sigma of MeshImFreq
        Gloc = SK(Sigma=Sigma_iw, mu=12.3461)
        # check if density is close to 1, not to strict since nkpts is relatively small
        assert abs(Gloc.total_density().real - 1.0) < 1e-2
Ejemplo n.º 7
0
def extract_deltaiw_and_tij_from_G0(G0_iw, gf_struct):

    iw_mesh = G0_iw.mesh
    Delta_iw = BlockGf(mesh=iw_mesh, gf_struct=gf_struct)
    H_loc_block = []

    for block, g0_iw in G0_iw:

        tail, err = g0_iw.fit_hermitian_tail()
        #print "---------------"
        #print "tail", tail
        H_loc = tail[2]
        #print "---------------"
        #print "H_loc", H_loc
        Delta_iw[block] << iOmega_n - H_loc - inverse(g0_iw)

        H_loc_block.append(H_loc)

    return Delta_iw, H_loc_block
h_bath = sum(c_dag_bath_vec[s] * h_bath_mat * c_bath_vec[s]
             for s in spin_names)[0, 0]
h_coup = sum(c_dag_vec[s] * V_mat * c_bath_vec[s] +
             c_dag_bath_vec[s] * V_mat.transpose() * c_vec[s]
             for s in spin_names)[0, 0]  # FIXME Adjoint

# ==== Total impurity hamiltonian ====
h_imp = h_loc + h_coup + h_bath

# ==== Green function structure ====
gf_struct = [[s, orb_names] for s in spin_names]

# ==== Hybridization Function ====
n_iw = int(10 * beta)
iw_mesh = MeshImFreq(beta, 'Fermion', n_iw)
Delta = BlockGf(mesh=iw_mesh, gf_struct=gf_struct)
# FIXME Delta['up'] << V_mat.transpose() * inverse(iOmega_n - h_bath_mat) * V_mat
for bl, iw in product(spin_names, iw_mesh):
    Delta[bl][iw] = V_mat * inv(iw.value * eye(len(orb_bath_names)) -
                                h_bath_mat) * V_mat.transpose()

# ==== Non-Interacting Impurity Green function  ====
G0_iw = Delta.copy()
G0_iw['up'] << inverse(
    iOmega_n - h_0_mat - Delta['up'])  # FIXME Should work for BlockGf
G0_iw['dn'] << inverse(iOmega_n - h_0_mat - Delta['dn'])

# ==== Construct the CTHYB solver using the G0_iw Interface ====
constr_params = {
    'beta': beta,
    'gf_struct': gf_struct,
Ejemplo n.º 9
0
def w2dyn_ndarray_to_triqs_BlockGF_tau_beta_ntau(gtau_osost, beta, gf_struct):
    """ Convert a DistributedSample of data in W2Dynamics
    ndarray format with indices [osost]
    where t is time, o is orbital, s is spin index
    to a spin-block Triqs imaginary time response function 

    Takes: 
    gtau : Green function as DistributedSample
    beta : inverse temperature
    ntau : number of tau points (including tau=0 and beta) 

    Returns: 
    BlockGF : triqs block Green function the response function data

    Author: Hugo U. R. Strand (2019) """

    gtau = gtau_osost.mean()
    gtau_err = gtau_osost.stderr()

    n_tau = gtau.shape[-1]
    assert n_tau % 2 == 0, "Need an even number of tau points to downsample to Triqs tau mesh"

    # -- Average over interior bins to simulate Triqs bin structure
    # -- with half-width edge bins.

    def average_interior_bins(gtau):

        gtau_0 = gtau[..., 0]
        gtau_beta = gtau[..., -1]
        gtau_mid = gtau[..., 1:-1]
        gtau_mid = 0.5 * (gtau_mid[..., ::2] + gtau_mid[..., 1::2])

        shape = list(gtau_mid.shape)
        shape[-1] += 2

        gtau = np.zeros(shape, dtype=complex)
        gtau[..., 0] = gtau_0
        gtau[..., -1] = gtau_beta
        gtau[..., 1:-1] = gtau_mid

        return gtau

    gtau = average_interior_bins(gtau)
    gtau_err = average_interior_bins(gtau_err)

    ### Reshape to rank 3

    assert (len(gtau.shape) == 5)

    norbs, nspin, _, _, n_tau = gtau.shape
    shape = (norbs * nspin, norbs * nspin, n_tau)
    gtau, gtau_err = gtau.reshape(shape), gtau_err.reshape(shape)

    ### generate triqs Green function with same dimension than
    ### the input; this may not be a good idea if worm is used
    ### since then the output can have another structure...
    from triqs.gf import MeshImTime, BlockGf

    tau_mesh = MeshImTime(beta, 'Fermion', n_tau)

    G_tau_data = BlockGf(mesh=tau_mesh, gf_struct=gf_struct)
    G_tau_error = BlockGf(mesh=tau_mesh, gf_struct=gf_struct)

    gtau = exchange_fastest_running_index_ffw(gtau)

    ### read out blocks from full w2dyn matrices
    offset = 0
    for name, _ in G_tau_data:

        size1, size2 = G_tau_data[name].target_shape
        assert (size1 == size2)
        size_block = size1

        gtau_block = gtau[offset:offset + size_block,
                          offset:offset + size_block, :]
        gtau_err_block = gtau_err[offset:offset + size_block,
                                  offset:offset + size_block, :]

        G_tau_data[name].data[:] = -gtau_block.transpose(2, 0, 1)
        G_tau_error[name].data[:] = -gtau_err_block.transpose(2, 0, 1)

        offset += size_block

    return G_tau_data, G_tau_error
Ejemplo n.º 10
0
    def solve(self, **params_kw):
        """Solve impurity model 

        Arguments:
        n_cycles : number of Monte Carlo cycles
        n_warmup_cycles : number of warmub Monte Carlo cycles
        length_cycle : number of proposed moves per cycle
        h_int : interaction Hamiltonian as a quartic triqs operator
        h_0 : quadratic part of the local Hamiltonian
              (only required if delta_interface=true has been specified during construction)
        """

        n_cycles = params_kw.pop(
            "n_cycles")  ### what does the True or False mean?
        n_warmup_cycles = params_kw.pop("n_warmup_cycles", 5000)  ### default
        max_time = params_kw.pop("max_time", -1)
        worm = params_kw.pop("worm", False)
        percentageworminsert = params_kw.pop("PercentageWormInsert", 0.00)
        percentagewormreplace = params_kw.pop("PercentageWormReplace", 0.00)

        length_cycle = params_kw.pop("length_cycle", 50)
        h_int = params_kw.pop("h_int")
        self.last_solve_params = {
            "n_cycles": n_cycles,
            "n_warmup_cycles": n_warmup_cycles,
            "length_cycle": length_cycle,
            "h_int": h_int
        }

        if self.delta_interface:
            h_0 = params_kw.pop("h_0")
            self.last_solve_params["h_0"] = h_0

        random_seed = params_kw.pop("random_seed", 1)
        move_double = params_kw.pop("move_double", True)
        measure_G_l = params_kw.pop("measure_G_l", True)
        measure_pert_order = params_kw.pop("measure_pert_order", False)
        statesampling = params_kw.pop("statesampling", False)
        flavourchange_moves = params_kw.pop("flavourchange_moves", False)
        move_global_prob = params_kw.pop("flavomove_global_prob", 0.005)

        if isinstance(self.gf_struct, dict):
            print(
                "WARNING: gf_struct should be a list of pairs [ [str,[int,...]], ...], not a dict"
            )
            self.gf_struct = [[k, v] for k, v in self.gf_struct.items()]

        ### Andi: the definition in the U-Matrix in w2dyn is
        ### 1/2 \sum_{ijkl} U_{ijkl} cdag_i cdag_j c_l c_k
        ###                                         !   !
        ### a factor of 2 is needed to compensate the 1/2, and a minus for
        ### exchange of the annihilators; is this correct for any two particle interaction term?

        U_ijkl = dict_to_matrix(extract_U_dict4(h_int), self.gf_struct)

        ### Make sure that the spin index is the fastest running variable
        norb = U_ijkl.shape[0] // 2
        U_ijkl = U_ijkl.reshape(2, norb, 2, norb, 2, norb, 2, norb)
        U_ijkl = U_ijkl.transpose(1, 0, 3, 2, 5, 4, 7, 6)
        U_ijkl = U_ijkl.reshape(norb * 2, norb * 2, norb * 2, norb * 2)

        if self.delta_interface:
            t_ij_matrix = dict_to_matrix(extract_h_dict(h_0), self.gf_struct)
        else:
            Delta_iw, t_ij_lst = extract_deltaiw_and_tij_from_G0(
                self.G0_iw, self.gf_struct)

            self.Delta_tau = BlockGf(mesh=self.tau_mesh,
                                     gf_struct=self.gf_struct)
            self.Delta_tau << Fourier(Delta_iw)

            assert len(t_ij_lst) in set([1, 2, 4]), \
                  "For now t_ij_lst must not contain more than 4 blocks; generalize it!"
            t_ij_matrix = block_diag(*t_ij_lst)

        # in w2dyn Delta is a hole propagator
        for bl, Delta_bl in self.Delta_tau:
            Delta_bl.data[:] = -Delta_bl.data[::-1, ...]

        t_ij_matrix *= -1  # W2Dynamics sign convention

        ### transform t_ij from (f,f) to (o,s,o,s) format

        norb = int(t_ij_matrix.shape[0] / 2)
        t_ij_matrix = t_ij_matrix.reshape(2, norb, 2, norb)
        t_osos_tensor = t_ij_matrix.transpose(1, 0, 3, 2)

        ftau, _, __ = triqs_gf_to_w2dyn_ndarray_g_tosos_beta_ntau(
            self.Delta_tau)

        ### now comes w2dyn!
        # Make a temporary files with input parameters

        Parameters_in = """#asdf
[General]
[Atoms]
[[1]]
Nd = %i
Hamiltonian = Kanamori
[QMC]
TaudiffMax = -1.0""" % norb

        cfg_file = tempfile.NamedTemporaryFile(delete=False, mode="w")
        cfg_file.write(Parameters_in)
        cfg_file.close()

        ### read w2dyn parameter file; later we will replace this by a
        ### converter of triqs-parameters to w2dyn-parameters

        key_value_args = {}
        cfg = config.get_cfg(cfg_file.name, key_value_args, err=sys.stderr)

        ### check if Delta_tau is diagonal matrix, and set w2dyn parameter
        ### offdiag accordingly
        max_blocksize = 0
        for name, d in self.Delta_tau:

            blocksize = d.data.shape[-1]
            #print "blocksize", blocksize
            if blocksize > max_blocksize:
                max_blocksize = blocksize

        if max_blocksize == 1:
            cfg["QMC"]["offdiag"] = 0
        else:
            cfg["QMC"]["offdiag"] = 1

        ### complex worms are not yet existing
        if self.complex and worm:
            print('complex and worm together not yet implemented')
            exit()

        if self.complex:
            cfg["QMC"]["complex"] = 1
            cfg["QMC"]["use_phase"] = 1

            ### check if offdiag is set; complex makes no sense without offdiag
            assert cfg["QMC"]["offdiag"] != 0, \
                  "Complex does not make sense for diagonal Delta_tau!"

        if move_double:
            cfg["QMC"]["Percentage4OperatorMove"] = 0.005
        else:
            cfg["QMC"]["Percentage4OperatorMove"] = 0

        cfg["QMC"]["PercentageGlobalMove"] = move_global_prob

        if flavourchange_moves:
            cfg["QMC"]["flavourchange_moves"] = 1
        else:
            cfg["QMC"]["flavourchange_moves"] = 0

        os.remove(cfg_file.name)  # remove temp file with input parameters

        ### I now write the triqs parameters into the cfg file;
        ### we may later do this with dictionaries
        ### in a more sophisticated way

        cfg["General"]["beta"] = self.beta
        cfg["QMC"]["Niw"] = self.n_iw
        cfg["QMC"][
            "Ntau"] = self.n_tau * 2  # use double resolution bins & down sample to Triqs l8r
        if measure_G_l:
            cfg["QMC"]["NLegMax"] = self.n_l
            cfg["QMC"]["NLegOrder"] = self.n_l
        else:
            cfg["QMC"]["NLegMax"] = 1
            cfg["QMC"]["NLegOrder"] = 1

        cfg["QMC"]["Nwarmups"] = length_cycle * n_warmup_cycles
        cfg["QMC"]["Nmeas"] = n_cycles
        cfg["QMC"]["measurement_time"] = max_time
        cfg["QMC"]["Ncorr"] = length_cycle

        if statesampling:
            cfg["QMC"]["statesampling"] = 1
        else:
            cfg["QMC"]["statesampling"] = 0

        if worm:
            cfg["QMC"]["WormMeasGiw"] = 1
            cfg["QMC"]["WormMeasGtau"] = 1
            cfg["QMC"]["WormSearchEta"] = 1

            ### set worm parameters to some default values if not set by user
            if percentageworminsert != 0.0:
                cfg["QMC"]["PercentageWormInsert"] = percentageworminsert
            else:
                cfg["QMC"]["PercentageWormInsert"] = 0.2
            if percentagewormreplace != 0.0:
                cfg["QMC"]["PercentageWormReplace"] = percentagewormreplace
            else:
                cfg["QMC"]["PercentageWormReplace"] = 0.2

        if mpi.rank == 0:
            print(' ')
            print('specifications for w2dyn:')
            print('cfg["QMC"]["offdiag"] ', cfg["QMC"]["offdiag"])
            print('cfg["QMC"]["Percentage4OperatorMove"] ',
                  cfg["QMC"]["Percentage4OperatorMove"])
            print('cfg["QMC"]["flavourchange_moves"] ',
                  cfg["QMC"]["flavourchange_moves"])
            print('cfg["QMC"]["statesampling"] ', cfg["QMC"]["statesampling"])

        ### initialize the solver; it needs the config-string
        Nseed = random_seed + mpi.rank
        use_mpi = False
        mpi_comm = mpi.world
        solver = impurity.CtHybSolver(cfg, Nseed, 0, 0, 0, False, mpi_comm)

        ### generate dummy input that we don't necessarily need
        niw = 2 * cfg["QMC"]["Niw"]
        g0inviw = np.zeros(shape=(2 * self.n_iw, norb, 2, norb, 2))
        fiw = np.zeros(shape=(2 * self.n_iw, norb, 2, norb, 2))
        fmom = np.zeros(shape=(2, norb, 2, norb, 2))
        symmetry_moves = ()
        paramag = False
        atom = config.atomlist_from_cfg(cfg, norb)[0]

        ### if calculation not complex, the solver must have only
        ### real arrays as input
        if self.complex:
            muimp = t_osos_tensor
        else:
            g0inviw = np.real(g0inviw)
            fiw = np.real(fiw)
            fmom = np.real(fmom)
            ftau = np.real(ftau)
            muimp = np.real(t_osos_tensor)
            U_ijkl = np.real(U_ijkl)

        ### here the properties of the impurity will be defined
        imp_problem = impurity.ImpurityProblem(self.beta, g0inviw, fiw, fmom,
                                               ftau, muimp, atom.dd_int, None,
                                               None, symmetry_moves, paramag)

        print("\n" + "." * 40)

        ### hardcode the set of conserved quantities to number of electrons
        ### and activate the automatic minimalisation procedure of blocks
        ### ( QN "All" does this)
        #print "imp_problem.interaction.quantum_numbers ",  imp_problem.interaction.quantum_numbers
        imp_problem.interaction.quantum_numbers = ("Nt", "All")
        #imp_problem.interaction.quantum_numbers = ( "Nt", "Szt", "Qzt" )
        #imp_problem.interaction.quantum_numbers = ( "Nt", "Szt" )
        #imp_problem.interaction.quantum_numbers = ( "Nt" )

        ### feed impurity problem into solver
        solver.set_problem(imp_problem)

        ### solve impurity problem
        mccfgcontainer = []
        iter_no = 1
        if self.complex:
            solver.set_problem(imp_problem)
            solver.umatrix = U_ijkl
            result = solver.solve(mccfgcontainer)
            gtau = result.other["gtau-full"]
        else:
            if not worm:
                solver.set_problem(imp_problem)
                solver.umatrix = U_ijkl
                result = solver.solve(iter_no, mccfgcontainer)
                gtau = result.other["gtau-full"]
            else:

                gtau = np.zeros(shape=(1, norb, 2, norb, 2, 2 * self.n_tau))

                from auxiliaries.compoundIndex import index2component_general

                components = []

                for comp_ind in range(1, (2 * norb)**2 + 1):

                    tmp = index2component_general(norb, 2, int(comp_ind))

                    ### check if ftau is nonzero

                    bands = tmp[1]
                    spins = tmp[2]

                    b1 = bands[0]
                    b2 = bands[1]
                    s1 = spins[0]
                    s2 = spins[1]

                    all_zeros = not np.any(ftau[:, b1, s1, b2, s2] > 1e-5)

                    if not all_zeros:
                        components = np.append(components, comp_ind)

                if mpi.rank == 0:
                    print('worm components to measure: ', components)

                ### divide either max_time Nmeas among the nonzero components
                if max_time <= 0:
                    cfg["QMC"]["Nmeas"] = int(cfg["QMC"]["Nmeas"] /
                                              float(len(components)))
                else:
                    cfg["QMC"]["measurement_time"] = int(
                        float(max_time) / float(len(components)))

                for comp_ind in components:

                    if mpi.rank == 0:
                        print('--> comp_ind', comp_ind)

                    solver.set_problem(imp_problem)
                    solver.umatrix = U_ijkl
                    result_aux, result = solver.solve_component(
                        1, 2, comp_ind, mccfgcontainer)

                    for i in list(result.other.keys()):

                        if "gtau-worm" in i:
                            gtau_name = i

                    tmp = index2component_general(norb, 2, int(comp_ind))

                    ### check if ftau is nonzero

                    bands = tmp[1]
                    spins = tmp[2]

                    b1 = bands[0]
                    b2 = bands[1]
                    s1 = spins[0]
                    s2 = spins[1]

                    # Remove axis 0 from local samples by averaging, so
                    # no data remains unused even if there is more than
                    # one local sample (should not happen)
                    gtau[0, b1, s1, b2,
                         s2, :] = np.mean(result.other[gtau_name].local,
                                          axis=0)
                gtau = stat.DistributedSample(gtau, mpi_comm, ntotal=mpi.size)

        if cfg["QMC"]["offdiag"] == 0 and worm == 0:

            def bs_diagflat(bs_array):
                """Return an array with a shape extended compared to
                that of the argument by doubling the first two axes and
                fill it such that the returned array is diagonal with
                respect to both pairs (axes 1 and 3 and axes 2 and 4).
                """
                shape_bsonly = bs_array.shape[0:2]
                bsbs_shape = shape_bsonly + bs_array.shape
                bsbs_array = np.zeros(bsbs_shape, dtype=bs_array.dtype)
                for b in range(bs_array.shape[0]):
                    for s in range(bs_array.shape[1]):
                        bsbs_array[b, s, b, s, ...] = bs_array[b, s, ...]
                return bsbs_array

            gtau = result.other["gtau"].apply(bs_diagflat)

        ### here comes the function for conversion w2dyn --> triqs
        self.G_tau, self.G_tau_error = w2dyn_ndarray_to_triqs_BlockGF_tau_beta_ntau(
            gtau, self.beta, self.gf_struct)

        self.G_iw = BlockGf(mesh=self.iw_mesh, gf_struct=self.gf_struct)

        ### I will use the FFT from triqs here...
        for name, g in self.G_tau:
            bl_size = g.target_shape[0]
            known_moments = np.zeros((4, bl_size, bl_size), dtype=np.complex)
            for i in range(bl_size):
                known_moments[1, i, i] = 1

            self.G_iw[name].set_from_fourier(g, known_moments)

        ### add perturbation order as observable
        #print 'measure_pert_order ', measure_pert_order
        if measure_pert_order:
            hist = result.other["hist"]
            #print 'hist.shape', hist.shape

        ### GF in Legendre expansion
        if measure_G_l:
            Gl = result.other["gleg-full"]
Ejemplo n.º 11
0
import numpy as np

### generate a test-impurity
ntau = 1000
niw = 2000
beta = 20.0
norb = 5

### generate block structure
spin_names = ['up', 'dn']
orb_names = [i for i in range(norb)]
gf_struct = [[s, orb_names] for s in spin_names]

### generate hybridisation function
iw_mesh = MeshImFreq(beta, 'Fermion', niw)
Delta_iw = BlockGf(mesh=iw_mesh, gf_struct=gf_struct)

### generate random values for hybridisation function
for block, delta_iw in Delta_iw:

    ### generate random hermitian bath energies
    s = (norb, norb)
    eps = 5.0 * (np.random.random(s) - 0.5) + 3.j * (np.random.random(s) - 0.5)
    eps = eps + np.conjugate(eps.T)

    delta_block = inverse(iOmega_n - eps)
    delta_iw << delta_block

    ### multiply everything (element-wise) with hermitian matrix
    ### since Delta(iw) does not have high frequency tail of 1
    randmat = 5.0 * (np.random.random(s) - 0.5) + 3.j * (np.random.random(s) -