def lattice(data, funcG, funcW, n): #the only option - we need Gkw and Wqnu for self energy in the next iteration #data.get_Gkw(funcG) #gets Gkw from G0 and Sigma def func(var, data): mu = var[0] dt = data[0] #print "func call! mu: ", mu, " n: ",dt.ns['up'] n= data[1] dt.mus['up'] = mu dt.mus['down'] = dt.mus['up'] dt.get_Gkw_direct(funcG) #gets Gkw from w, mu, epsilon and Sigma and X dt.get_G_loc() #gets G_loc from Gkw dt.get_n_from_G_loc() #print "funcvalue: ",-abs(n - dt.ns['up']) return 1.0-abs(n - dt.ns['up']) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() varbest, funcvalue, iterations = amoeba(var=[data.mus['up']], scale=[0.01], func=func, data = [data, n], itmax=30, ftolerance=1e-2, xtolerance=1e-2) if mpi.is_master_node(): print "mu best: ", varbest print "-abs(diff n - data.n): ", funcvalue print "iterations used: ", iterations data.get_Gtildekw() #gets Gkw-G_loc data.get_Wqnu_from_func(funcW) #gets Wqnu from P and J data.get_W_loc() #gets W_loc from Wqnu data.get_Wtildeqnu() #gets Wqnu-W_loc,
def HT(res): # First compute the eps_hat array eps_hat = epsilon_hat(self.dos.eps) if epsilon_hat else numpy.array( [ x* numpy.identity (N1) for x in self.dos.eps] ) assert eps_hat.shape[0] == self.dos.eps.shape[0], "epsilon_hat function behaves incorrectly" assert eps_hat.shape[1] == eps_hat.shape[2], "epsilon_hat function behaves incorrectly (result not a square matrix)" assert N1 == eps_hat.shape[1], "Size of Sigma and of epsilon_hat mismatch" res.zero() # Perform the sum over eps[i] tmp, tmp2 = res.copy(), res.copy() tmp << iOmega_n + mu + eta * 1j if not(Sigma_fnt): tmp -= Sigma if field != None: tmp -= field # I slice all the arrays on the node. Cf reduce operation below. for d, e_h, e in itertools.izip (*[mpi.slice_array(A) for A in [self.rho_for_sum, eps_hat, self.dos.eps]]): tmp2.copy_from(tmp) tmp2 -= e_h if Sigma_fnt: tmp2 -= Sigma(e) tmp2.invert() tmp2 *= d res += tmp2 # sum the res GF of all nodes and returns the results on all nodes... # Cf Boost.mpi.python, collective communicator for documentation. # The point is that res is pickable, hence can be transmitted between nodes without further code... res << mpi.all_reduce(mpi.world, res, lambda x, y: x+y) mpi.barrier()
def __init__(self, archive, *args, **kwargs): self.archive = archive if not os.path.exists(archive) and mpi.is_master_node(): archive = HDFArchive(archive, 'w') archive.create_group('results') archive['results']['n_dmft_loops'] = 0 del archive mpi.barrier()
def calc_bandcorr_man(general_parameters, SK, E_kin_dft): """ Calculates the correlated kinetic energy from DMFT for target states and then determines the band correction energy Parameters ---------- general_parameters : dict general parameters as a dict SK : SumK Object instances E_kin_dft: float kinetic energy from DFT __Returns:__ E_bandcorr: float band energy correction E_kin_dmft - E_kin_dft """ E_kin_dmft = 0.0 + 0.0j E_kin = 0.0 + 0.0j H_ks = SK.hopping num_kpts = SK.n_k # kinetic energy from dmft lattice Greens functions ikarray = np.array(range(SK.n_k)) for ik in mpi.slice_array(ikarray): nb = int(SK.n_orbitals[ik]) # calculate lattice greens function G_iw_lat = SK.lattice_gf(ik, beta=general_parameters['beta'], with_Sigma=True, with_dc=True).copy() # calculate G(beta) via the function density, which is the same as fourier trafo G(w) and taking G(b) G_iw_lat_beta = G_iw_lat.density() # Doing the formula E_kin += np.trace( np.dot( H_ks[ik, 0, :nb, :nb], G_iw_lat_beta['up'][:, :])) + np.trace( np.dot(H_ks[ik, 0, :nb, :nb], G_iw_lat_beta['down'][:, :])) E_kin = float(E_kin.real) # collect data and put into E_kin_dmft E_kin_dmft = mpi.all_reduce(mpi.world, E_kin, lambda x, y: x + y) mpi.barrier() # E_kin should be divided by the number of k-points E_kin_dmft = E_kin_dmft / num_kpts if mpi.is_master_node(): print 'Kinetic energy contribution dmft part: ' + str(E_kin_dmft) E_bandcorr = E_kin_dmft - E_kin_dft return E_bandcorr
def extract_Gloc(mu): ret = Gloc.copy() ret.zero() Gk = ret.copy() mu_mat = np.zeros((8, 8)) for i in range(4): mu_mat[i, i] = mu mu_mat[i + 4, i + 4] = -mu nk = Hk_nambu.shape[0] ikarray = np.array(range(nk)) for ik in mpi.slice_array(ikarray): Gk['nambu'] << inverse(iOmega_n - Hk_nambu[ik] + mu_mat - Sigma_orig['nambu']) ret['nambu'] += Gk['nambu'] mpi.barrier() ret['nambu'] << mpi.all_reduce(mpi.world, ret['nambu'], lambda x, y: x + y) / nk return ret
def density_gf(self,beta): """Calculates the density without setting up Gloc. It is useful for Hubbard I, and very fast.""" dens_mat = [ {} for icrsh in xrange(self.n_corr_shells)] for icrsh in xrange(self.n_corr_shells): for bl in self.block_names[self.corr_shells[icrsh][4]]: dens_mat[icrsh][bl] = numpy.zeros([self.corr_shells[icrsh][3],self.corr_shells[icrsh][3]], numpy.complex_) ikarray=numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): Gupf = self.lattice_gf_matsubara(ik=ik, beta=beta, mu=self.chemical_potential) Gupf *= self.bz_weights[ik] dm = Gupf.density() MMat = [dm[bl] for bl in self.block_names[self.SO]] for icrsh in range(self.n_corr_shells): for ibn,bn in enumerate(self.block_names[self.corr_shells[icrsh][4]]): isp = self.names_to_ind[self.corr_shells[icrsh][4]][bn] dim = self.corr_shells[icrsh][3] n_orb = self.n_orbitals[ik,isp] #print ik, bn, isp dens_mat[icrsh][bn] += numpy.dot( numpy.dot(self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb],MMat[ibn]), self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb].transpose().conjugate() ) # get data from nodes: for icrsh in range(self.n_corr_shells): for sig in dens_mat[icrsh]: dens_mat[icrsh][sig] = mpi.all_reduce(mpi.world,dens_mat[icrsh][sig],lambda x,y : x+y) mpi.barrier() if (self.symm_op!=0): dens_mat = self.Symm_corr.symmetrize(dens_mat) # Rotate to local coordinate system: if (self.use_rotations): for icrsh in xrange(self.n_corr_shells): for bn in dens_mat[icrsh]: if (self.rot_mat_time_inv[icrsh]==1): dens_mat[icrsh][bn] = dens_mat[icrsh][bn].conjugate() dens_mat[icrsh][bn] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),dens_mat[icrsh][bn]) , self.rot_mat[icrsh] ) return dens_mat
def HT(res): # First compute the eps_hat array eps_hat = epsilon_hat( self.dos.eps) if epsilon_hat else numpy.array( [x * numpy.identity(Sigma.N1) for x in self.dos.eps]) assert eps_hat.shape[0] == self.dos.eps.shape[ 0], "epsilon_hat function behaves incorrectly" assert eps_hat.shape[1] == eps_hat.shape[ 2], "epsilon_hat function behaves incorrectly (result not a square matrix)" assert Sigma.N1 == eps_hat.shape[ 1], "Size of Sigma and of epsilon_hat mismatch" res.zero() Sigma_fnt = callable(Sigma) if Sigma_fnt: assert len( inspect.getargspec(Sigma)[0] ) == 1, "Sigma function is not of the correct type. See Documentation" # Perform the sum over eps[i] tmp, tmp2 = res.copy(), res.copy() tmp <<= iOmega_n + mu + eta * 1j if not (Sigma_fnt): tmp -= Sigma if field != None: tmp -= field # I slice all the arrays on the node. Cf reduce operation below. for d, e_h, e in itertools.izip(*[ mpi.slice_array(A) for A in [self.rho_for_sum, eps_hat, self.dos.eps] ]): tmp2.copy_from(tmp) tmp2 -= e_h if Sigma_fnt: tmp2 -= Sigma(e) tmp2.invert() tmp2 *= d res += tmp2 # sum the res GF of all nodes and returns the results on all nodes... # Cf Boost.mpi.python, collective communicator for documentation. # The point is that res is pickable, hence can be transmitted between nodes without further code... res <<= mpi.all_reduce(mpi.world, res, lambda x, y: x + y) mpi.barrier()
def total_density(self, mu): """ Calculates the total charge for the energy window for a given mu. Since in general n_orbitals depends on k, the calculation is done in the following order: G_aa'(k,iw) -> n(k) = Tr G_aa'(k,iw) -> sum_k n_k mu: chemical potential The calculation is done in the global coordinate system, if distinction is made between local/global! """ dens = 0.0 ikarray=numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): S = self.lattice_gf_matsubara(ik=ik,mu=mu) dens += self.bz_weights[ik] * S.total_density() # collect data from mpi: dens = mpi.all_reduce(mpi.world,dens,lambda x,y : x+y) mpi.barrier() return dens
def get_chi0_wnk(g_wk, nw=1, nwf=None): r""" Compute the generalized lattice bubble susceptibility :math:`\chi^{(0)}_{abcd}(\omega, \nu, \mathbf{k})` from the single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`. Parameters ---------- g_wk : Single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`. nw : Number of bosonic freqiencies in :math:`\chi`. nwf : Number of fermionic freqiencies in :math:`\chi`. Returns ------- chi0_wnk : Generalized lattice bubble susceptibility :math:`\chi^{(0)}_{abcd}(\omega, \nu, \mathbf{k})` """ fmesh = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] if nwf is None: nwf = len(fmesh) / 2 mpi.barrier() mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 0, 0)][0, 0])) n = np.sum(g_wk.data) / len(kmesh) mpi.report('n ' + str(n)) mpi.barrier() mpi.report('--> g_wr from g_wk') g_wr = fourier_wk_to_wr(g_wk) mpi.barrier() mpi.report('g_wr ' + str(g_wr[Idx(2), Idx(0, 0, 0)][0, 0])) n_r = np.sum(g_wr.data, axis=0)[0] mpi.report('n_r=0 ' + str(n_r[0, 0])) mpi.barrier() mpi.report('--> chi0_wnr from g_wr') chi0_wnr = chi0r_from_gr_PH(nw=nw, nn=nwf, g_nr=g_wr) #mpi.report('--> chi0_wnr from g_wr (nompi)') #chi0_wnr_nompi = chi0r_from_gr_PH_nompi(nw=nw, nn=nwf, g_wr=g_wr) del g_wr #abs_diff = np.abs(chi0_wnr.data - chi0_wnr_nompi.data) #mpi.report('shape = ' + str(abs_diff.shape)) #idx = np.argmax(abs_diff) #mpi.report('argmax = ' + str(idx)) #diff = np.max(abs_diff) #mpi.report('diff = %6.6f' % diff) #del chi0_wnr #chi0_wnr = chi0_wnr_nompi #exit() mpi.barrier() mpi.report('chi0_wnr ' + str(chi0_wnr[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0_r0 = np.sum(chi0_wnr[:, :, Idx(0, 0, 0)].data) mpi.report('chi0_r0 ' + str(chi0_r0)) mpi.barrier() mpi.report('--> chi0_wnk from chi0_wnr') chi0_wnk = chi0q_from_chi0r(chi0_wnr) del chi0_wnr mpi.barrier() mpi.report('chi0_wnk ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0 = np.sum(chi0_wnk.data) / len(kmesh) mpi.report('chi0 = ' + str(chi0)) mpi.barrier() #if mpi.is_master_node(): if False: from triqs_tprf.ParameterCollection import ParameterCollection p = ParameterCollection() p.g_wk = g_wk p.g_wr = g_wr p.chi0_wnr = chi0_wnr p.chi0_wnk = chi0_wnk print '--> Writing debug info for BSE' with HDFArchive('data_debug_bse.h5', 'w') as arch: arch['p'] = p mpi.barrier() return chi0_wnk
def lattice(data, frozen_boson, n, ph_symmetry, accepted_mu_range=[-2.0,2.0]): def get_n(dt): dt.get_Gkw_direct() #gets Gkw from w, mu, epsilon and Sigma and X dt.get_Fkw_direct() #gets Fkw from w, mu, epsilon and Sigma and X dt.get_G_loc() #gets G_loc from Gkw dt.get_n_from_G_loc() if mpi.is_master_node(): print "supercond_hubbard: lattice" if (n is None) or ((n==0.5) and ph_symmetry): if n==0.5: #otherwise - nothing to be done data.mus['up'] = 0 if 'down' in data.fermionic_struct.keys(): data.mus['down'] = data.mus['up'] get_n(data) else: def func(var, data): mu = var[0] dt = data[0] #print "func call! mu: ", mu, " n: ",dt.ns['up'] n= data[1] dt.mus['up'] = mu if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus['up'] get_n(dt) #print "funcvalue: ",-abs(n - dt.ns['up']) val = 1.0-abs(n - dt.ns['up']) if mpi.is_master_node(): print "amoeba func call: val = ",val if val != val: return -1e+6 else: return val if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if mpi.is_master_node(): print "about to do mu search:" guesses = [data.mus['up'], 0.0, -0.1, -0.3, -0.4, -0.5, -0.7, 0.3, 0.5, 0.7] found = False for l in range(len(guesses)): varbest, funcvalue, iterations = amoeba(var=[guesses[l]], scale=[0.01], func=func, data = [data, n], itmax=30, ftolerance=1e-2, xtolerance=1e-2, known_max = 1.0, known_max_accr = 5e-5) if (varbest[0]>accepted_mu_range[0] and varbest[0]<accepted_mu_range[1]) and (abs(funcvalue-1.0)<1e-2): #change the bounds for large doping found = True func(varbest, [data, n]) break if l+1 == len(guesses): if mpi.is_master_node(): print "mu search FAILED: doing a scan..." mu_grid = numpy.linspace(-1.0,0.3,50) func_values = [func(var=[mu], data=[data,n]) for mu in mu_grid] if mpi.is_master_node(): print "func_values: " for i in range(len(mu_grid)): print "mu: ",mu_grid[i], " 1-abs(n-n): ", func_values[i] mui_max = numpy.argmax(func_values) if mpi.is_master_node(): print "using mu: ", mu_grid[mui_max] data.mus['up'] = mu_grid[mui_max] if 'down' in data.fermionic_struct.keys(): data.mus['down'] = data.mus['up'] get_n(data) if mpi.is_master_node() and found: print "guesses tried: ", l print "mu best: ", varbest print "1-abs(diff n - data.n): ", funcvalue print "iterations used: ", iterations data.get_Gtildekw() #gets Gkw-G_loc if not frozen_boson: data.get_Wqnu_from_func(func = dict.fromkeys(data.bosonic_struct.keys(), dyson.scalar.W_from_P_and_J)) #gets Wqnu from P and J data.get_W_loc() #gets W_loc from Wqnu, used in local bubbles data.get_Wtildeqnu()
def get_G_w_from_A_w(A_w, w_points, np_interp_A=None, np_omega=2000, w_min=-10, w_max=10, broadening_factor=1.0): r""" Use Kramers-Kronig to determine the retarded Green function :math:`G(\omega)` This calculates :math:`G(\omega)` from the spectral function :math:`A(\omega)`. A numerical broadening of :math:`bf * i\Delta\omega` is used, with the adjustable broadening factor bf (default is 1). This function normalizes :math:`A(\omega)`. Use mpi to save time. Parameters ---------- A_w : array Real-frequency spectral function. w_points : array Real-frequency grid points. np_interp_A : int Number of grid points A_w should be interpolated on before G_w is calculated. The interpolation is performed on a linear grid with np_interp_A points from min(w_points) to max(w_points). np_omega : int Number of equidistant grid points of the output Green function. w_min : float Start point of output Green function. w_max : float End point of output Green function. broadening_factor : float Factor multiplying the broadening :math:`i\Delta\omega` Returns ------- G_w : GfReFreq TRIQS retarded Green function. """ shape_A = np.shape(A_w) if len(shape_A) == 1: indices = [0] matrix_valued = False elif (len(shape_A) == 3) and (shape_A[0] == shape_A[1]): indices = range(0, shape_A[0]) matrix_valued = True else: raise Exception('A_w has wrong shape, must be n x n x n_w') if w_min > w_max: raise Exception('w_min must be smaller than w_max') if np_interp_A: w_points_interp = np.linspace(np.min(w_points), np.max(w_points), np_interp_A) if matrix_valued: for i in range(shape_A[0]): for j in range(shape_A[1]): A_w[i, j, :] = np.interp(w_points_interp, w_points, A_w[i, j, :]) else: A_w = np.interp(w_points_interp, w_points, A_w) w_points = w_points_interp G_w = GfReFreq(indices=indices, window=(w_min, w_max), n_points=np_omega) G_w.zero() iw_points = np.array(range(len(w_points))) for iw in mpi.slice_array(iw_points): domega = (w_points[min(len(w_points) - 1, iw + 1)] - w_points[max(0, iw - 1)]) * 0.5 if matrix_valued: for i in range(shape_A[0]): for j in range(shape_A[1]): G_w[i, j] << G_w[i, j] + A_w[i, j, iw] * \ inverse(Omega - w_points[iw] + 1j * domega * broadening_factor) * domega else: G_w << G_w + A_w[iw] * \ inverse(Omega - w_points[iw] + 1j * domega * broadening_factor) * domega G_w << mpi.all_reduce(mpi.world, G_w, lambda x, y: x + y) mpi.barrier() return G_w
def solve_lattice_bse(g_wk, gamma_wnn, tail_corr_nwf=None): fmesh_g = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] bmesh = gamma_wnn.mesh.components[0] fmesh = gamma_wnn.mesh.components[1] nk = len(kmesh) nw = (len(bmesh) + 1) / 2 nwf = len(fmesh) / 2 nwf_g = len(fmesh_g) / 2 if mpi.is_master_node(): print tprf_banner(), "\n" print 'Lattcie BSE with local vertex approximation.\n' print 'nk =', nk print 'nw =', nw print 'nwf =', nwf print 'nwf_g =', nwf_g print 'tail_corr_nwf =', tail_corr_nwf print if tail_corr_nwf is None: tail_corr_nwf = nwf mpi.report('--> chi0_wnk_tail_corr') chi0_wnk_tail_corr = get_chi0_wnk(g_wk, nw=nw, nwf=tail_corr_nwf) mpi.report('--> trace chi0_wnk_tail_corr (WARNING! NO TAIL FIT. FIXME!)') chi0_wk_tail_corr = chi0q_sum_nu_tail_corr_PH(chi0_wnk_tail_corr) #chi0_wk_tail_corr = chi0q_sum_nu(chi0_wnk_tail_corr) mpi.barrier() mpi.report('B1 ' + str(chi0_wk_tail_corr[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) mpi.barrier() mpi.report('--> chi0_wnk_tail_corr to chi0_wnk') if tail_corr_nwf != nwf: mpi.report('--> fixed_fermionic_window_python_wnk') chi0_wnk = fixed_fermionic_window_python_wnk(chi0_wnk_tail_corr, nwf=nwf) else: chi0_wnk = chi0_wnk_tail_corr.copy() del chi0_wnk_tail_corr mpi.barrier() mpi.report('C ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) mpi.barrier() mpi.report('--> trace chi0_wnk') chi0_wk = chi0q_sum_nu(chi0_wnk) mpi.barrier() mpi.report('D ' + str(chi0_wk[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) mpi.barrier() dchi_wk = chi0_wk_tail_corr - chi0_wk chi0_kw = Gf(mesh=MeshProduct(kmesh, bmesh), target_shape=chi0_wk_tail_corr.target_shape) chi0_kw.data[:] = chi0_wk_tail_corr.data.swapaxes(0, 1) del chi0_wk del chi0_wk_tail_corr assert (chi0_wnk.mesh.components[0] == bmesh) assert (chi0_wnk.mesh.components[1] == fmesh) assert (chi0_wnk.mesh.components[2] == kmesh) # -- Lattice BSE calc with built in trace mpi.report('--> chi_kw from BSE') #mpi.report('DEBUG BSE INACTIVE'*72) chi_kw = chiq_sum_nu_from_chi0q_and_gamma_PH(chi0_wnk, gamma_wnn) #chi_kw = chi0_kw.copy() mpi.barrier() mpi.report('--> chi_kw from BSE (done)') del chi0_wnk mpi.report('--> chi_kw tail corrected (using chi0_wnk)') for k in kmesh: chi_kw[ k, :] += dchi_wk[:, k] # -- account for high freq of chi_0 (better than nothing) del dchi_wk mpi.report('--> solve_lattice_bse, done.') return chi_kw, chi0_kw
def afm_heisenberg_calculation(T, Js, dispersion, n_loops_max=50, rules = [[0, 0.65], [10, 0.3], [15, 0.65]], n_cycles=100000, max_time=10*60): if mpi.is_master_node(): print "WELCOME TO AFM HEISENBERG!" bosonic_struct = {'z': [0], '+-': [0]} fermionic_struct = {'up': [0], 'down': [0]} beta = 1.0/T n_iw = 200 n_tau = int(n_iw*pi) #init solver solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) #init data, assign the solver to it dt = bosonic_data( n_iw = n_iw, n_q = 256, beta = beta, solver = solver, bosonic_struct = bosonic_struct, fermionic_struct = fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file") #init convergence and cautionary measures convergers = [ converger( monitored_quantity = dt.P_imp_iw, accuracy=3e-5, struct=bosonic_struct, archive_name=dt.archive_name ) ] mixers = [ mixer( mixed_quantity = dt.P_imp_iw, rules=rules, func=mixer.mix_gf ), mixer( mixed_quantity = dt.mus, rules=rules, func=mixer.mix_dictionary ) ] err = 0 for J in Js: dt.archive_name="edmft.heis_afm.J%s.T%s.out.h5"%(J,T) convergers[0].archive_name = dt.archive_name if not (dispersion is None): #this is optional since we're using semi-analytical summation and evaluate chi_loc directly from P dt.fill_in_qs() dt.fill_in_Jq( dict.fromkeys(['z','+-'], partial(dispersion, J=J)) ) if mpi.is_master_node(): dt.dump_non_interacting() preset = edmft_heisenberg_afm(J) #init the dmft_loop dmft = dmft_loop( cautionary = preset.cautionary, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = partial( impurity_cthyb, no_fermionic_bath=True, n_cycles=n_cycles, max_time=max_time ), post_impurity = preset.post_impurity, selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, after_it_is_done = preset.after_it_is_done ) if J == Js[0]: #do this only once! dt.mus = {'up': 0.1, 'down': -0.1} safe_and_stupid_scalar_P_imp(safe_value = -preset.cautionary.safe_value['z']*0.95, P_imp=dt.P_imp_iw['z']) safe_and_stupid_scalar_P_imp(safe_value = -preset.cautionary.safe_value['+-']*0.95, P_imp=dt.P_imp_iw['+-']) mpi.barrier() #run dmft!------------- err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=5, print_non_loc=False) return err
def csc_flow_control(general_parameters, solver_parameters): """ function to run the csc cycle. It writes and removes the vasp.lock file to start and stop Vasp, run the converter, run the dmft cycle and abort the job if all iterations are finished. Parameters ---------- general_parameters : dict general parameters as a dict solver_parameters : dict solver parameters as a dict __Returns:__ nothing """ mpi.report(" Waiting for VASP lock to appear...") while not toolset.is_vasp_lock_present(): time.sleep(1) # if GAMMA file already exists, load it by doing an extra DFT iteration if os.path.exists('GAMMA'): iter= -8 else: iter = 0 iter_dmft = 0 start_dft = timer() while iter_dmft < general_parameters['n_iter_dmft']: mpi.report(" Waiting for VASP lock to disappear...") mpi.barrier() #waiting for vasp to finish while toolset.is_vasp_lock_present(): time.sleep(1) # check if we should do a dmft iteration now iter += 1 if (iter-1) % general_parameters['n_iter_dft'] != 0 or iter < 0: if mpi.is_master_node(): open('./vasp.lock', 'a').close() continue # run the converter if mpi.is_master_node(): end_dft = timer() # check for plo file for projectors if not os.path.exists(general_parameters['plo_cfg']): mpi.report('*** Input PLO config file not found! I was looking for '+str(general_parameters['plo_cfg'])+' ***') mpi.MPI.COMM_WORLD.Abort(1) # run plo converter plo_converter.generate_and_output_as_text(general_parameters['plo_cfg'], vasp_dir='./') # # create h5 archive or build updated H(k) Converter = VaspConverter(filename=general_parameters['seedname']) # convert now h5 archive now Converter.convert_dft_input() # if wanted store eigenvalues in h5 archive if general_parameters['store_dft_eigenvals']: toolset.store_dft_eigvals(config_file = general_parameters['plo_cfg'], path_to_h5 = general_parameters['seedname']+'.h5', iteration = iter_dmft+1) mpi.barrier() if mpi.is_master_node(): print print "="*80 print 'DFT cycle took %10.4f seconds'%(end_dft-start_dft) print "calling dmft_cycle" print "DMFT iteration", iter_dmft+1,"/", general_parameters['n_iter_dmft'] print "="*80 print # if first iteration the h5 archive and observables need to be prepared if iter_dmft == 0: observables = dict() if mpi.is_master_node(): # basic H5 archive checks and setup h5_archive = HDFArchive(general_parameters['seedname']+'.h5','a') if not 'DMFT_results' in h5_archive: h5_archive.create_group('DMFT_results') if not 'last_iter' in h5_archive['DMFT_results']: h5_archive['DMFT_results'].create_group('last_iter') if not 'DMFT_input' in h5_archive: h5_archive.create_group('DMFT_input') # prepare observable dicts and files, which is stored on the master node observables = prep_observables(general_parameters, h5_archive) observables = mpi.bcast(observables) if mpi.is_master_node(): start_dmft = timer() ############################################################ # run the dmft_cycle observables = dmft_cycle(general_parameters, solver_parameters, observables) ############################################################ if iter_dmft == 0: iter_dmft += general_parameters['n_iter_dmft_first'] else: iter_dmft += general_parameters['n_iter_dmft_per'] if mpi.is_master_node(): end_dmft = timer() print print "="*80 print 'DMFT cycle took %10.4f seconds'%(end_dmft-start_dmft) print "running VASP now" print "="*80 print ####### # remove the lock file and Vasp will be unleashed if mpi.is_master_node(): open('./vasp.lock', 'a').close() # start the timer again for the dft loop if mpi.is_master_node(): start_dft = timer() # stop if the maximum number of dmft iterations is reached if mpi.is_master_node(): print "\n Maximum number of iterations reached." print " Aborting VASP iterations...\n" f_stop = open('STOPCAR', 'wt') f_stop.write("LABORT = .TRUE.\n") f_stop.close() mpi.MPI.COMM_WORLD.Abort(1)
def dos_wannier_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True): """ Calculates the density of states in the basis of the Wannier functions. Parameters ---------- mu : double, optional Chemical potential, overrides the one stored in the hdf5 archive. broadening : double, optional Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used. mesh : real frequency MeshType, optional Omega mesh for the real-frequency Green's function. Given as parameter to lattice_gf. with_Sigma : boolean, optional If True, the self energy is used for the calculation. If false, the DOS is calculated without self energy. with_dc : boolean, optional If True the double counting correction is used. save_to_file : boolean, optional If True, text files with the calculated data will be created. Returns ------- DOS : Dict of numpy arrays Contains the full density of states. DOSproj : Dict of numpy arrays DOS projected to atoms. DOSproj_orb : Dict of numpy arrays DOS projected to atoms and resolved into orbital contributions. """ if (mesh is None) and (not with_Sigma): raise ValueError, "lattice_gf: Give the mesh=(om_min,om_max,n_points) for the lattice GfReFreq." if mesh is None: om_mesh = [x.real for x in self.Sigma_imp_w[0].mesh] om_min = om_mesh[0] om_max = om_mesh[-1] n_om = len(om_mesh) mesh = (om_min, om_max, n_om) else: om_min, om_max, n_om = mesh om_mesh = numpy.linspace(om_min, om_max, n_om) G_loc = [] for icrsh in range(self.n_corr_shells): spn = self.spin_block_names[self.corr_shells[icrsh]['SO']] glist = [GfReFreq(indices=inner, window=(om_min, om_max), n_points=n_om) for block, inner in self.gf_struct_sumk[icrsh]] G_loc.append( BlockGf(name_list=spn, block_list=glist, make_copies=False)) for icrsh in range(self.n_corr_shells): G_loc[icrsh].zero() DOS = {sp: numpy.zeros([n_om], numpy.float_) for sp in self.spin_block_names[self.SO]} DOSproj = [{} for ish in range(self.n_inequiv_shells)] DOSproj_orb = [{} for ish in range(self.n_inequiv_shells)] for ish in range(self.n_inequiv_shells): for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]]['SO']]: dim = self.corr_shells[self.inequiv_to_corr[ish]]['dim'] DOSproj[ish][sp] = numpy.zeros([n_om], numpy.float_) DOSproj_orb[ish][sp] = numpy.zeros( [n_om, dim, dim], numpy.float_) ikarray = numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): G_latt_w = self.lattice_gf( ik=ik, mu=mu, iw_or_w="w", broadening=broadening, mesh=mesh, with_Sigma=with_Sigma, with_dc=with_dc) G_latt_w *= self.bz_weights[ik] # Non-projected DOS for iom in range(n_om): for bname, gf in G_latt_w: DOS[bname][iom] -= gf.data[iom, :, :].imag.trace() / \ numpy.pi # Projected DOS: for icrsh in range(self.n_corr_shells): tmp = G_loc[icrsh].copy() for bname, gf in tmp: tmp[bname] << self.downfold(ik, icrsh, bname, G_latt_w[ bname], gf) # downfolding G G_loc[icrsh] += tmp # Collect data from mpi: for bname in DOS: DOS[bname] = mpi.all_reduce( mpi.world, DOS[bname], lambda x, y: x + y) for icrsh in range(self.n_corr_shells): G_loc[icrsh] << mpi.all_reduce( mpi.world, G_loc[icrsh], lambda x, y: x + y) mpi.barrier() # Symmetrize and rotate to local coord. system if needed: if self.symm_op != 0: G_loc = self.symmcorr.symmetrize(G_loc) if self.use_rotations: for icrsh in range(self.n_corr_shells): for bname, gf in G_loc[icrsh]: G_loc[icrsh][bname] << self.rotloc( icrsh, gf, direction='toLocal') # G_loc can now also be used to look at orbitally-resolved quantities for ish in range(self.n_inequiv_shells): for bname, gf in G_loc[self.inequiv_to_corr[ish]]: # loop over spins for iom in range(n_om): DOSproj[ish][bname][iom] -= gf.data[iom, :, :].imag.trace() / numpy.pi DOSproj_orb[ish][bname][ :, :, :] -= gf.data[:, :, :].imag / numpy.pi # Write to files if save_to_file and mpi.is_master_node(): for sp in self.spin_block_names[self.SO]: f = open('DOS_wann_%s.dat' % sp, 'w') for iom in range(n_om): f.write("%s %s\n" % (om_mesh[iom], DOS[sp][iom])) f.close() # Partial for ish in range(self.n_inequiv_shells): f = open('DOS_wann_%s_proj%s.dat' % (sp, ish), 'w') for iom in range(n_om): f.write("%s %s\n" % (om_mesh[iom], DOSproj[ish][sp][iom])) f.close() # Orbitally-resolved for i in range(self.corr_shells[self.inequiv_to_corr[ish]]['dim']): for j in range(i, self.corr_shells[self.inequiv_to_corr[ish]]['dim']): f = open('DOS_wann_' + sp + '_proj' + str(ish) + '_' + str(i) + '_' + str(j) + '.dat', 'w') for iom in range(n_om): f.write("%s %s\n" % ( om_mesh[iom], DOSproj_orb[ish][sp][iom, i, j])) f.close() return DOS, DOSproj, DOSproj_orb
def partial_charges(self, beta=40, mu=None, with_Sigma=True, with_dc=True): """ Calculates the orbitally-resolved density matrix for all the orbitals considered in the input, consistent with the definition of Wien2k. Hence, (possibly non-orthonormal) projectors have to be provided in the partial projectors subgroup of the hdf5 archive. Parameters ---------- with_Sigma : boolean, optional If True, the self energy is used for the calculation. If false, partial charges are calculated without self-energy correction. beta : double, optional In case the self-energy correction is not used, the inverse temperature where the calculation should be done has to be given here. mu : double, optional Chemical potential, overrides the one stored in the hdf5 archive. with_dc : boolean, optional If True the double counting correction is used. Returns ------- dens_mat : list of numpy array A list of density matrices projected to all shells provided in the input. """ things_to_read = ['dens_mat_below', 'n_parproj', 'proj_mat_all', 'rot_mat_all', 'rot_mat_all_time_inv'] value_read = self.read_input_from_hdf( subgrp=self.parproj_data, things_to_read=things_to_read) if not value_read: return value_read if self.symm_op: self.symmpar = Symmetry(self.hdf_file, subgroup=self.symmpar_data) spn = self.spin_block_names[self.SO] ntoi = self.spin_names_to_ind[self.SO] # Density matrix in the window self.dens_mat_window = [[numpy.zeros([self.shells[ish]['dim'], self.shells[ish]['dim']], numpy.complex_) for ish in range(self.n_shells)] for isp in range(len(spn))] # Set up G_loc gf_struct_parproj = [[(sp, range(self.shells[ish]['dim'])) for sp in spn] for ish in range(self.n_shells)] if with_Sigma: G_loc = [BlockGf(name_block_generator=[(block, GfImFreq(indices=inner, mesh=self.Sigma_imp_iw[0].mesh)) for block, inner in gf_struct_parproj[ish]], make_copies=False) for ish in range(self.n_shells)] beta = self.Sigma_imp_iw[0].mesh.beta else: G_loc = [BlockGf(name_block_generator=[(block, GfImFreq(indices=inner, beta=beta)) for block, inner in gf_struct_parproj[ish]], make_copies=False) for ish in range(self.n_shells)] for ish in range(self.n_shells): G_loc[ish].zero() ikarray = numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): G_latt_iw = self.lattice_gf( ik=ik, mu=mu, iw_or_w="iw", beta=beta, with_Sigma=with_Sigma, with_dc=with_dc) G_latt_iw *= self.bz_weights[ik] for ish in range(self.n_shells): tmp = G_loc[ish].copy() for ir in range(self.n_parproj[ish]): for bname, gf in tmp: tmp[bname] << self.downfold(ik, ish, bname, G_latt_iw[ bname], gf, shells='all', ir=ir) G_loc[ish] += tmp # Collect data from mpi: for ish in range(self.n_shells): G_loc[ish] << mpi.all_reduce( mpi.world, G_loc[ish], lambda x, y: x + y) mpi.barrier() # Symmetrize and rotate to local coord. system if needed: if self.symm_op != 0: G_loc = self.symmpar.symmetrize(G_loc) if self.use_rotations: for ish in range(self.n_shells): for bname, gf in G_loc[ish]: G_loc[ish][bname] << self.rotloc( ish, gf, direction='toLocal', shells='all') for ish in range(self.n_shells): isp = 0 for bname, gf in G_loc[ish]: self.dens_mat_window[isp][ish] = G_loc[ish].density()[bname] isp += 1 # Add density matrices to get the total: dens_mat = [[self.dens_mat_below[ntoi[spn[isp]]][ish] + self.dens_mat_window[isp][ish] for ish in range(self.n_shells)] for isp in range(len(spn))] return dens_mat
def spaghettis(self, broadening=None, plot_shift=0.0, plot_range=None, ishell=None, mu=None, save_to_file='Akw_'): """ Calculates the correlated band structure using a real-frequency self energy. Parameters ---------- mu : double, optional Chemical potential, overrides the one stored in the hdf5 archive. broadening : double, optional Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used. plot_shift : double, optional Offset for each A(k,w) for stacked plotting of spectra. plot_range : list of double, optional Sets the energy window for plotting to (plot_range[0],plot_range[1]). If not provided, the energy mesh of the self energy is used. ishell : integer, optional Contains the index of the shell on which the spectral function is projected. If ishell=None, the total spectrum without projection is calculated. save_to_file : string, optional Filename where the spectra are stored. Returns ------- Akw : Dict of numpy arrays Data as it is also written to the files. """ assert hasattr( self, "Sigma_imp_w"), "spaghettis: Set Sigma_imp_w first." things_to_read = ['n_k', 'n_orbitals', 'proj_mat', 'hopping', 'n_parproj', 'proj_mat_all'] value_read = self.read_input_from_hdf( subgrp=self.bands_data, things_to_read=things_to_read) if not value_read: return value_read things_to_read = ['rot_mat_all', 'rot_mat_all_time_inv'] value_read = self.read_input_from_hdf( subgrp=self.parproj_data, things_to_read=things_to_read) if not value_read: return value_read if mu is None: mu = self.chemical_potential spn = self.spin_block_names[self.SO] mesh = [x.real for x in self.Sigma_imp_w[0].mesh] n_om = len(mesh) if plot_range is None: om_minplot = mesh[0] - 0.001 om_maxplot = mesh[n_om - 1] + 0.001 else: om_minplot = plot_range[0] om_maxplot = plot_range[1] if ishell is None: Akw = {sp: numpy.zeros([self.n_k, n_om], numpy.float_) for sp in spn} else: Akw = {sp: numpy.zeros( [self.shells[ishell]['dim'], self.n_k, n_om], numpy.float_) for sp in spn} if not ishell is None: gf_struct_parproj = [ (sp, range(self.shells[ishell]['dim'])) for sp in spn] G_loc = BlockGf(name_block_generator=[(block, GfReFreq(indices=inner, mesh=self.Sigma_imp_w[0].mesh)) for block, inner in gf_struct_parproj], make_copies=False) G_loc.zero() ikarray = numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): G_latt_w = self.lattice_gf( ik=ik, mu=mu, iw_or_w="w", broadening=broadening) if ishell is None: # Non-projected A(k,w) for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): for bname, gf in G_latt_w: Akw[bname][ik, iom] += gf.data[iom, :, :].imag.trace() / (-1.0 * numpy.pi) # shift Akw for plotting stacked k-resolved eps(k) # curves Akw[bname][ik, iom] += ik * plot_shift else: # ishell not None # Projected A(k,w): G_loc.zero() tmp = G_loc.copy() for ir in range(self.n_parproj[ishell]): for bname, gf in tmp: tmp[bname] << self.downfold(ik, ishell, bname, G_latt_w[ bname], gf, shells='all', ir=ir) G_loc += tmp # Rotate to local frame if self.use_rotations: for bname, gf in G_loc: G_loc[bname] << self.rotloc( ishell, gf, direction='toLocal', shells='all') for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): for ish in range(self.shells[ishell]['dim']): for sp in spn: Akw[sp][ish, ik, iom] = G_loc[sp].data[ iom, ish, ish].imag / (-1.0 * numpy.pi) # Collect data from mpi for sp in spn: Akw[sp] = mpi.all_reduce(mpi.world, Akw[sp], lambda x, y: x + y) mpi.barrier() if save_to_file and mpi.is_master_node(): if ishell is None: for sp in spn: # loop over GF blocs: # Open file for storage: f = open(save_to_file + sp + '.dat', 'w') for ik in range(self.n_k): for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): if plot_shift > 0.0001: f.write('%s %s\n' % (mesh[iom], Akw[sp][ik, iom])) else: f.write('%s %s %s\n' % (ik, mesh[iom], Akw[sp][ik, iom])) f.write('\n') f.close() else: # ishell is not None for sp in spn: for ish in range(self.shells[ishell]['dim']): # Open file for storage: f = open(save_to_file + str(ishell) + '_' + sp + '_proj' + str(ish) + '.dat', 'w') for ik in range(self.n_k): for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): if plot_shift > 0.0001: f.write('%s %s\n' % ( mesh[iom], Akw[sp][ish, ik, iom])) else: f.write('%s %s %s\n' % ( ik, mesh[iom], Akw[sp][ish, ik, iom])) f.write('\n') f.close() return Akw
def constr_Sigma_real_axis(self, filename, hdf=True, hdf_dataset='SigmaReFreq',n_om=0,orb=0, tol_mesh=1e-6): """Uses Data from files to construct Sigma (or GF) on the real axis.""" if not hdf: # read sigma from text files #first get the mesh out of one of the files: if (len(self.gf_struct_solver[orb][0][1])==1): Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'.dat' else: Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'/'+str(self.gf_struct_solver[orb][0][1][0])+'_'+str(self.gf_struct_solver[orb][0][1][0])+'.dat' R = read_fortran_file(Fname) mesh = numpy.zeros([n_om],numpy.float_) try: for i in xrange(n_om): mesh[i] = R.next() sk = R.next() sk = R.next() except StopIteration : # a more explicit error if the file is corrupted. raise "SumkLDA.read_Sigma_ME : reading mesh failed!" R.close() # check whether the mesh is uniform bin = (mesh[n_om-1]-mesh[0])/(n_om-1) for i in xrange(n_om): assert abs(i*bin+mesh[0]-mesh[i]) < tol_mesh, 'constr_Sigma_ME: real-axis mesh is non-uniform!' # construct Sigma a_list = [a for a,al in self.gf_struct_solver[orb]] glist = lambda : [ GfReFreq(indices = al, window=(mesh[0],mesh[n_om-1]),n_points=n_om) for a,al in self.gf_struct_solver[orb]] SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False) #read Sigma for i,g in SigmaME: mesh=[w for w in g.mesh] for iL in g.indices: for iR in g.indices: if (len(g.indices) == 1): Fname = filename+'_%s'%(i)+'.dat' else: Fname = 'SigmaME_'+'%s'%(i)+'_%s'%(iL)+'_%s'%(iR)+'.dat' R = read_fortran_file(Fname) try: for iom in xrange(n_om): sk = R.next() rsig = R.next() isig = R.next() g.data[iom,iL,iR]=rsig+1j*isig except StopIteration : # a more explicit error if the file is corrupted. raise "SumkLDA.read_Sigma_ME : reading Sigma from file failed!" R.close() else: # read sigma from hdf omega_min=0.0 omega_max=0.0 n_om=0 if (mpi.is_master_node()): ar = HDFArchive(filename) SigmaME = ar[hdf_dataset] del ar # we need some parameters to construct Sigma on other nodes omega_min=SigmaME.mesh.omega_min omega_max=SigmaME.mesh.omega_max n_om=len(SigmaME.mesh) omega_min=mpi.bcast(omega_min) omega_max=mpi.bcast(omega_max) n_om=mpi.bcast(n_om) mpi.barrier() # construct Sigma on other nodes if (not mpi.is_master_node()): a_list = [a for a,al in self.gf_struct_solver[orb]] glist = lambda : [ GfReFreq(indices = al, window=(omega_min,omega_max),n_points=n_om) for a,al in self.gf_struct_solver[orb]] SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False) # pass SigmaME to other nodes SigmaME = mpi.bcast(SigmaME) mpi.barrier() SigmaME.note='ReFreq' return SigmaME
def supercond_trilex_tUVJ_calculation( Ts = [0.12,0.08,0.04,0.02,0.01], ns=[0.0, 0.2, 0.4, 0.6, 0.8], ts=[0.25], t_dispersion = epsilonk_square, Us = [1.0,2.0,3.0,4.0], Vs = [0.2, 0.5, 1.0, 1.5], V_dispersion = Jq_square, Js = [0], J_dispersion = Jq_square, hs = [0], refresh_X = False, n_ks = [40], w_cutoff = 20.0, n_loops_min = 10, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], use_cthyb=True, n_cycles=100000, max_time=10*60, accuracy = 1e-4, initial_guess_archive_name = '', suffix=''): if mpi.is_master_node(): print "WELCOME TO supercond trilex tUVJ calculation!" bosonic_struct = {'0': [0], '1': [0]} if len(Js)==1 and Js[0] == 0: del bosonic_struct['1'] if len(Vs)==1 and Vs[0] == 0.0: del bosonic_struct['0'] fermionic_struct = {'up': [0], 'down': [0]} beta = 1.0/Ts[0] n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ",n_iw n_tau = int(n_iw*pi) n_q = n_ks[0] n_k = n_q #init solver if use_cthyb: solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) else: print "no solver, quitting..." quit() #init data, assign the solver to it dt = supercond_trilex_data( n_iw = n_iw, n_iw_f = n_iw/2, n_iw_b = n_iw/2, n_k = n_k, n_q = n_q, beta = beta, solver = solver, bosonic_struct = bosonic_struct, fermionic_struct = fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file" ) #init convergence and cautionary measures convergers = [ converger( monitored_quantity = lambda: dt.P_loc_iw, accuracy=accuracy, struct=bosonic_struct, archive_name=dt.archive_name, h5key = 'diffs_P_loc' ), converger( monitored_quantity = lambda: dt.G_loc_iw, accuracy=accuracy, struct=fermionic_struct, archive_name=dt.archive_name, h5key = 'diffs_G_loc' ) ] #initial guess ps = itertools.product(n_ks,ts,ns,Us,Vs,Js,Ts,hs) counter = 0 old_nk = n_k old_beta = beta for p in ps: #name stuff to avoid confusion nk = p[0] t = p[1] n = p[2] U = p[3] V = p[4] J = p[5] T = p[6] beta = 1.0/T h = p[7] if nk!=old_nk: dt.change_ks(IBZ.k_grid(nk)) old_nk = nk if beta!=old_beta: n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0) n_tau = int(n_iw*pi) dt.change_beta(beta, n_iw) if trilex: dt.solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) old_beta = beta filename = "result" if len(n_ks)>1: filename += ".nk%s"%nk if len(ts)>1: filename += ".t%s"%t if len(ns)>1: filename += ".n%s"%n if len(Us)>1: filename += ".U%s"%U if len(Vs)>1: filename += ".V%s"%V if len(Js)>1: filename += ".J%s"%J if len(Ts)>1: filename += ".T%s"%T if len(hs)>1: filename += ".h%s"%h filename += ".h5" dt.archive_name = filename for conv in convergers: conv.archive_name = dt.archive_name vks = {'0': lambda kx,ky: V_dispersion(kx,ky,J=V), '1': lambda kx,ky: J_dispersion(kx,ky,J=J)} dt.fill_in_Jq( vks ) dt.fill_in_epsilonk(dict.fromkeys(fermionic_struct.keys(), partial(t_dispersion, t=t))) preset = supercond_trilex_tUVJ(n = n, U = U, bosonic_struct = bosonic_struct) n_w_f=dt.n_iw_f n_w_b=dt.n_iw_b if use_cthyb: impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, trilex=True, n_w_f=n_w_f, n_w_b=n_w_b, n_cycles=n_cycles, max_time=max_time ) dt.dump_solver = solvers.cthyb.dump else: quit() mixers = [ mixer( mixed_quantity = dt.P_loc_iw, rules=rules, func=mixer.mix_gf ), mixer( mixed_quantity = dt.Sigma_loc_iw, rules=rules, func=mixer.mix_gf) ] #init the dmft_loop dmft = dmft_loop( cautionary = preset.cautionary, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = impurity, post_impurity = preset.post_impurity, selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, after_it_is_done = preset.after_it_is_done ) #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) ) if (T==Ts[0]): #do this only once! dt.mus['up'] = dt.mus['down'] = U/2.0 dt.ns['up'] = dt.ns['down'] = n #such that in the first iteration mu is not adjusted dt.P_imp_iw << 0.0 dt.Sigma_imp_iw << U/2.0 #making sure that in the first iteration the impurity problem is half-filled. if not solving impurity problem, not needed for U in fermionic_struct.keys(): dt.Sigmakw[U].fill(0) for U in fermionic_struct.keys(): dt.Xkw[U].fill(0) if refresh_X: for kxi in range(dt.n_k): for kyi in range(dt.n_k): for wi in range(dt.nw): for U in fermionic_struct.keys(): dt.Xkw[U][wi, kxi, kyi] += X_dwave(dt.ks[kxi],dt.ks[kyi], 1.0) if h!=0: for kxi in range(dt.n_k): for kyi in range(dt.n_k): for wi in range(dt.nw): for U in fermionic_struct.keys(): dt.hsck[U][kxi, kyi] = X_dwave(dt.ks[kxi],dt.ks[kyi], h) mpi.barrier() #run dmft!------------- err = dmft.run( dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_three_leg=1, print_non_local=1, skip_self_energy_on_first_iteration=True, last_iteration_err_is_allowed = 18 ) if (err==2): break counter += 1 return err
def run_all(vasp_pid, dmft_cycle, cfg_file, n_iter): """ """ mpi.report(" Waiting for VASP lock to appear...") while not is_vasp_lock_present(): time.sleep(1) vasp_running = True iter = 0 while vasp_running: if debug: print bcolors.RED + "rank %s" % (mpi.rank) + bcolors.ENDC mpi.report(" Waiting for VASP lock to disappear...") mpi.barrier() while is_vasp_lock_present(): time.sleep(1) # if debug: print bcolors.YELLOW + " waiting: rank %s"%(mpi.rank) + bcolors.ENDC if not is_vasp_running(vasp_pid): mpi.report(" VASP stopped") vasp_running = False break # Tell VASP to stop if the maximum number of iterations is reached iter += 1 if iter == n_iter: if mpi.is_master_node(): print "\n Maximum number of iterations reached." print " Aborting VASP iterations...\n" f_stop = open('STOPCAR', 'wt') f_stop.write("LABORT = .TRUE.\n") f_stop.close() if debug: print bcolors.MAGENTA + "rank %s" % (mpi.rank) + bcolors.ENDC err = 0 exc = None if debug: print bcolors.BLUE + "plovasp: rank %s" % (mpi.rank) + bcolors.ENDC if mpi.is_master_node(): converter.generate_and_output_as_text(cfg_file, vasp_dir='./') # Read energy from OSZICAR dft_energy = get_dft_energy() mpi.barrier() if debug: print bcolors.GREEN + "rank %s" % (mpi.rank) + bcolors.ENDC corr_energy, dft_dc = dmft_cycle() mpi.barrier() if mpi.is_master_node(): total_energy = dft_energy + corr_energy - dft_dc print print "=" * 80 print " Total energy: ", total_energy print " DFT energy: ", dft_energy print " Corr. energy: ", corr_energy print " DFT DC: ", dft_dc print "=" * 80 print if mpi.is_master_node() and vasp_running: open('./vasp.lock', 'a').close() if mpi.is_master_node(): total_energy = dft_energy + corr_energy - dft_dc with open('TOTENERGY', 'w') as f: f.write(" Total energy: %s\n" % (total_energy)) f.write(" DFT energy: %s\n" % (dft_energy)) f.write(" Corr. energy: %s\n" % (corr_energy)) f.write(" DFT DC: %s\n" % (dft_dc)) f.write(" Energy correction: %s\n" % (corr_energy - dft_dc)) mpi.report("***Done")
def spaghettis(self, broadening=None, plot_shift=0.0, plot_range=None, ishell=None, mu=None, save_to_file='Akw_'): """ Calculates the correlated band structure using a real-frequency self energy. Parameters ---------- mu : double, optional Chemical potential, overrides the one stored in the hdf5 archive. broadening : double, optional Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used. plot_shift : double, optional Offset for each A(k,w) for stacked plotting of spectra. plot_range : list of double, optional Sets the energy window for plotting to (plot_range[0],plot_range[1]). If not provided, the energy mesh of the self energy is used. ishell : integer, optional Contains the index of the shell on which the spectral function is projected. If ishell=None, the total spectrum without projection is calculated. save_to_file : string, optional Filename where the spectra are stored. Returns ------- Akw : Dict of numpy arrays Data as it is also written to the files. """ assert hasattr( self, "Sigma_imp_w"), "spaghettis: Set Sigma_imp_w first." things_to_read = ['n_k', 'n_orbitals', 'proj_mat', 'hopping', 'n_parproj', 'proj_mat_all'] value_read = self.read_input_from_hdf( subgrp=self.bands_data, things_to_read=things_to_read) if not value_read: return value_read if ishell is not None: things_to_read = ['rot_mat_all', 'rot_mat_all_time_inv'] value_read = self.read_input_from_hdf( subgrp=self.parproj_data, things_to_read=things_to_read) if not value_read: return value_read if mu is None: mu = self.chemical_potential spn = self.spin_block_names[self.SO] mesh = [x.real for x in self.Sigma_imp_w[0].mesh] n_om = len(mesh) if plot_range is None: om_minplot = mesh[0] - 0.001 om_maxplot = mesh[n_om - 1] + 0.001 else: om_minplot = plot_range[0] om_maxplot = plot_range[1] if ishell is None: Akw = {sp: numpy.zeros([self.n_k, n_om], numpy.float_) for sp in spn} else: Akw = {sp: numpy.zeros( [self.shells[ishell]['dim'], self.n_k, n_om], numpy.float_) for sp in spn} if not ishell is None: gf_struct_parproj = [ (sp, range(self.shells[ishell]['dim'])) for sp in spn] G_loc = BlockGf(name_block_generator=[(block, GfReFreq(indices=inner, mesh=self.Sigma_imp_w[0].mesh)) for block, inner in gf_struct_parproj], make_copies=False) G_loc.zero() ikarray = numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): G_latt_w = self.lattice_gf( ik=ik, mu=mu, iw_or_w="w", broadening=broadening) if ishell is None: # Non-projected A(k,w) for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): for bname, gf in G_latt_w: Akw[bname][ik, iom] += gf.data[iom, :, :].imag.trace() / (-1.0 * numpy.pi) # shift Akw for plotting stacked k-resolved eps(k) # curves Akw[bname][ik, iom] += ik * plot_shift else: # ishell not None # Projected A(k,w): G_loc.zero() tmp = G_loc.copy() for ir in range(self.n_parproj[ishell]): for bname, gf in tmp: tmp[bname] << self.downfold(ik, ishell, bname, G_latt_w[ bname], gf, shells='all', ir=ir) G_loc += tmp # Rotate to local frame if self.use_rotations: for bname, gf in G_loc: G_loc[bname] << self.rotloc( ishell, gf, direction='toLocal', shells='all') for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): for ish in range(self.shells[ishell]['dim']): for sp in spn: Akw[sp][ish, ik, iom] = G_loc[sp].data[ iom, ish, ish].imag / (-1.0 * numpy.pi) # Collect data from mpi for sp in spn: Akw[sp] = mpi.all_reduce(mpi.world, Akw[sp], lambda x, y: x + y) mpi.barrier() if save_to_file and mpi.is_master_node(): if ishell is None: for sp in spn: # loop over GF blocs: # Open file for storage: f = open(save_to_file + sp + '.dat', 'w') for ik in range(self.n_k): for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): if plot_shift > 0.0001: f.write('%s %s\n' % (mesh[iom], Akw[sp][ik, iom])) else: f.write('%s %s %s\n' % (ik, mesh[iom], Akw[sp][ik, iom])) f.write('\n') f.close() else: # ishell is not None for sp in spn: for ish in range(self.shells[ishell]['dim']): # Open file for storage: f = open(save_to_file + str(ishell) + '_' + sp + '_proj' + str(ish) + '.dat', 'w') for ik in range(self.n_k): for iom in range(n_om): if (mesh[iom] > om_minplot) and (mesh[iom] < om_maxplot): if plot_shift > 0.0001: f.write('%s %s\n' % ( mesh[iom], Akw[sp][ish, ik, iom])) else: f.write('%s %s %s\n' % ( ik, mesh[iom], Akw[sp][ish, ik, iom])) f.write('\n') f.close() return Akw
def pm_hubbard_calculation( T, Us, mutildes, dispersion, #necessary to partially evaluate dispersion!!! the calculation does not need to know about t rules = [[0, 0.5], [3, 0.0], [10, 0.65]], n_loops_max=25, n_cycles=20000, max_time=10*60): if mpi.is_master_node(): print "WELCOME TO PM HUBBARD!" fermionic_struct = {'up': [0], 'down': [0]} beta = 1.0/T n_iw = 200 n_tau = int(n_iw*pi) n_k = 32 #init solver solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) #init data, assign the solver to it dt = fermionic_data( n_iw = n_iw, n_k = n_k, beta = beta, solver = solver, bosonic_struct = {}, fermionic_struct = fermionic_struct, archive_name="nothing_yet_if_you_see_this_file_something_went wrong" ) dt.fill_in_ks() dt.fill_in_epsilonk(dict.fromkeys(['up','down'], dispersion) ) #init convergence and cautionary measures convergers = [ converger( monitored_quantity = dt.Sigma_imp_iw, accuracy=3e-3, struct=fermionic_struct, archive_name=dt.archive_name ) ] mixers = [ mixer( mixed_quantity = dt.Sigma_imp_iw, rules=rules, func=mixer.mix_gf ) ] mpi.barrier() #run dmft!------------- err = 0 for U in Us: for mutilde in mutildes: dt.mus['up'] = dt.mus['down'] = mutilde + U/2.0 #necessary input! by default 0 dt.archive_name = "dmft.hubb_pm.U%s.mutilde%s.T%s.h5"%(U,mutilde,T) convergers[0].archive_name = dt.archive_name if mpi.is_master_node(): dt.dump_non_interacting() preset = dmft_hubbard_pm(U) #init the dmft_loop dmft = dmft_loop( cautionary = None, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = partial( impurity_cthyb, no_fermionic_bath=False, n_cycles=n_cycles, max_time=max_time ), post_impurity = preset.post_impurity, selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, after_it_is_done = preset.after_it_is_done ) if U==Us[0]: dt.Sigma_imp_iw << mutilde+U/2.0 #initial guess only at the beginning, continues from the previous solution err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=5) return err #number of failed calculations
def dos_wannier_basis(self, mu=None, broadening=None, mesh=None, with_Sigma=True, with_dc=True, save_to_file=True): """ Calculates the density of states in the basis of the Wannier functions. Parameters ---------- mu : double, optional Chemical potential, overrides the one stored in the hdf5 archive. broadening : double, optional Lorentzian broadening of the spectra. If not given, standard value of lattice_gf is used. mesh : real frequency MeshType, optional Omega mesh for the real-frequency Green's function. Given as parameter to lattice_gf. with_Sigma : boolean, optional If True, the self energy is used for the calculation. If false, the DOS is calculated without self energy. with_dc : boolean, optional If True the double counting correction is used. save_to_file : boolean, optional If True, text files with the calculated data will be created. Returns ------- DOS : Dict of numpy arrays Contains the full density of states. DOSproj : Dict of numpy arrays DOS projected to atoms. DOSproj_orb : Dict of numpy arrays DOS projected to atoms and resolved into orbital contributions. """ if (mesh is None) and (not with_Sigma): raise ValueError, "lattice_gf: Give the mesh=(om_min,om_max,n_points) for the lattice GfReFreq." if mesh is None: om_mesh = [x.real for x in self.Sigma_imp_w[0].mesh] om_min = om_mesh[0] om_max = om_mesh[-1] n_om = len(om_mesh) mesh = (om_min, om_max, n_om) else: om_min, om_max, n_om = mesh om_mesh = numpy.linspace(om_min, om_max, n_om) G_loc = [] for icrsh in range(self.n_corr_shells): spn = self.spin_block_names[self.corr_shells[icrsh]['SO']] glist = [GfReFreq(indices=inner, window=(om_min, om_max), n_points=n_om) for block, inner in self.gf_struct_sumk[icrsh]] G_loc.append( BlockGf(name_list=spn, block_list=glist, make_copies=False)) for icrsh in range(self.n_corr_shells): G_loc[icrsh].zero() DOS = {sp: numpy.zeros([n_om], numpy.float_) for sp in self.spin_block_names[self.SO]} DOSproj = [{} for ish in range(self.n_inequiv_shells)] DOSproj_orb = [{} for ish in range(self.n_inequiv_shells)] for ish in range(self.n_inequiv_shells): for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]]['SO']]: dim = self.corr_shells[self.inequiv_to_corr[ish]]['dim'] DOSproj[ish][sp] = numpy.zeros([n_om], numpy.float_) DOSproj_orb[ish][sp] = numpy.zeros( [n_om, dim, dim], numpy.complex_) ikarray = numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): G_latt_w = self.lattice_gf( ik=ik, mu=mu, iw_or_w="w", broadening=broadening, mesh=mesh, with_Sigma=with_Sigma, with_dc=with_dc) G_latt_w *= self.bz_weights[ik] # Non-projected DOS for iom in range(n_om): for bname, gf in G_latt_w: DOS[bname][iom] -= gf.data[iom, :, :].imag.trace() / \ numpy.pi # Projected DOS: for icrsh in range(self.n_corr_shells): tmp = G_loc[icrsh].copy() for bname, gf in tmp: tmp[bname] << self.downfold(ik, icrsh, bname, G_latt_w[ bname], gf) # downfolding G G_loc[icrsh] += tmp # Collect data from mpi: for bname in DOS: DOS[bname] = mpi.all_reduce( mpi.world, DOS[bname], lambda x, y: x + y) for icrsh in range(self.n_corr_shells): G_loc[icrsh] << mpi.all_reduce( mpi.world, G_loc[icrsh], lambda x, y: x + y) mpi.barrier() # Symmetrize and rotate to local coord. system if needed: if self.symm_op != 0: G_loc = self.symmcorr.symmetrize(G_loc) if self.use_rotations: for icrsh in range(self.n_corr_shells): for bname, gf in G_loc[icrsh]: G_loc[icrsh][bname] << self.rotloc( icrsh, gf, direction='toLocal') # G_loc can now also be used to look at orbitally-resolved quantities for ish in range(self.n_inequiv_shells): for bname, gf in G_loc[self.inequiv_to_corr[ish]]: # loop over spins for iom in range(n_om): DOSproj[ish][bname][iom] -= gf.data[iom, :, :].imag.trace() / numpy.pi DOSproj_orb[ish][bname][ :, :, :] += (1.0j*(gf-gf.conjugate().transpose())/2.0/numpy.pi).data[:,:,:] # Write to files if save_to_file and mpi.is_master_node(): for sp in self.spin_block_names[self.SO]: f = open('DOS_wann_%s.dat' % sp, 'w') for iom in range(n_om): f.write("%s %s\n" % (om_mesh[iom], DOS[sp][iom])) f.close() # Partial for ish in range(self.n_inequiv_shells): f = open('DOS_wann_%s_proj%s.dat' % (sp, ish), 'w') for iom in range(n_om): f.write("%s %s\n" % (om_mesh[iom], DOSproj[ish][sp][iom])) f.close() # Orbitally-resolved for i in range(self.corr_shells[self.inequiv_to_corr[ish]]['dim']): for j in range(i, self.corr_shells[self.inequiv_to_corr[ish]]['dim']): f = open('DOS_wann_' + sp + '_proj' + str(ish) + '_' + str(i) + '_' + str(j) + '.dat', 'w') for iom in range(n_om): f.write("%s %s %s\n" % ( om_mesh[iom], DOSproj_orb[ish][sp][iom, i, j].real,DOSproj_orb[ish][sp][iom, i, j].imag)) f.close() return DOS, DOSproj, DOSproj_orb
delta_mix = 1.0 # Mixing factor of Delta as input for the AIM dc_type = 0 # DC type: 0 FLL, 1 Held, 2 AMF use_blocks = True # use bloc structure from DFT input prec_mu = 0.0001 h_field = 0.0 # Solver parameters p = {} p["max_time"] = -1 p["length_cycle"] = 50 p["n_warmup_cycles"] = 50 p["n_cycles"] = 5000 Converter = Wien2kConverter(filename=dft_filename, repacking=True) Converter.convert_dft_input() mpi.barrier() previous_runs = 0 previous_present = False if mpi.is_master_node(): f = HDFArchive(dft_filename+'.h5','a') if 'dmft_output' in f: ar = f['dmft_output'] if 'iterations' in ar: previous_present = True previous_runs = ar['iterations'] else: f.create_group('dmft_output') del f previous_runs = mpi.bcast(previous_runs) previous_present = mpi.bcast(previous_present)
def pm_tUV_trilex_calculation( T, mutildes=[0.0], ns = [0.5, 0.53, 0.55, 0.57], fixed_n = False, ts=[0.25], t_dispersion = epsilonk_square, ph_symmetry = True, Us = [1.0], alpha=2.0/3.0, ising = False, Vs = [0.0], V_dispersion = Jq_square, nk = 24, n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], trilex = True, use_cthyb=True, n_cycles=100000, max_time=10*60, initial_guess_archive_name = '', suffix=''): if mpi.is_master_node(): print "WELCOME TO PM tUV trilex calculation!" bosonic_struct = {'0': [0], '1': [0]} if not ising: if alpha==2.0/3.0: del bosonic_struct['1'] if alpha==1.0/3.0: del bosonic_struct['0'] else: if alpha==1.0: del vks['1'] if alpha==0.0: del vks['0'] fermionic_struct = {'up': [0], 'down': [0]} beta = 1.0/T n_iw = int(((30.0*beta)/math.pi-1.0)/2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ",n_iw n_tau = int(n_iw*pi) n_q = nk n_k = n_q #init solver solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) #init data, assign the solver to it dt = GW_data( n_iw = n_iw, n_k = n_k, n_q = n_q, beta = beta, solver = solver, bosonic_struct = bosonic_struct, fermionic_struct = fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file" ) if trilex: dt.__class__ = trilex_data dt.promote( n_iw_f = n_iw/2, n_iw_b = n_iw/2 ) if not trilex: dt.get_Sigmakw = partial(dt.get_Sigmakw, imtime = True) dt.get_Pqnu = partial(dt.get_Pqnu, imtime = True) #dt.get_Sigma_loc_from_local_bubble = partial(dt.get_Sigma_loc_from_local_bubble, imtime = True) #dt.get_P_loc_from_local_bubble = partial(dt.get_P_loc_from_local_bubble, imtime = True) if ising: dt.get_Sigmakw = partial(dt.get_Sigmakw, ising_decoupling = True ) #init convergence and cautionary measures convergers = [ converger( monitored_quantity = lambda: dt.P_imp_iw, accuracy=1e-4, struct=bosonic_struct, archive_name=dt.archive_name, h5key = 'diffs_P_imp' ), converger( monitored_quantity = lambda: dt.G_imp_iw, accuracy=1e-4, struct=fermionic_struct, archive_name=dt.archive_name, h5key = 'diffs_G_imp' ) ] mixers = [ mixer( mixed_quantity = dt.P_imp_iw, rules=rules, func=mixer.mix_gf ), mixer( mixed_quantity = dt.Sigma_imp_iw, rules=rules, func=mixer.mix_gf) ] monitors = [ monitor( monitored_quantity = lambda: dt.ns['up'], h5key = 'n_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.mus['up'], h5key = 'mu_vs_it', archive_name = dt.archive_name) ] err = 0 #initial guess if fixed_n: ps = itertools.product(ns,ts,Us,Vs) else: ps = itertools.product(mutildes,ts,Us,Vs) counter = 0 for p in ps: #name stuff to avoid confusion if fixed_n: n = p[0] mutilde = None else: mutilde = p[0] n = None t = p[1] U = p[2] V = p[3] filename = "result" if len(mutildes)>1 and not fixed_n: filename += ".mutilde%s"%mutilde if len(ns)>1 and fixed_n: filename += ".n%s"%n if len(ts)>1: filename += ".t%s"%t if len(Us)>1: filename += ".U%s"%U if len(Vs)>1: filename += ".V%s"%V filename += ".h5" dt.archive_name = filename for conv in convergers: conv.archive_name = dt.archive_name if not ising: Uch = (3.0*alpha-1.0)*U Usp = (alpha-2.0/3.0)*U else: Uch = alpha*U Usp = (alpha-1.0)*U vks = {'0': lambda kx,ky: Uch + V_dispersion(kx,ky,J=V), '1': lambda kx,ky: Usp} if not ising: if alpha==2.0/3.0: del vks['1'] if alpha==1.0/3.0: del vks['0'] else: if alpha==1.0: del vks['1'] if alpha==0.0: del vks['0'] dt.fill_in_Jq( vks ) dt.fill_in_epsilonk(dict.fromkeys(['up','down'], partial(t_dispersion, t=t))) if trilex: preset = trilex_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct, ising = ising, n=n, ph_symmetry=ph_symmetry) else: preset = GW_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct, ising = ising, n=n, ph_symmetry=ph_symmetry) #preset.cautionary.get_safe_values(dt.Jq, dt.bosonic_struct, n_q, n_q) if mpi.is_master_node(): print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," mutilde= ",mutilde #print "cautionary safe values: ",preset.cautionary.safe_value impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, trilex=trilex, n_w_f=dt.n_iw_f if trilex else 2, n_w_b=dt.n_iw_b if trilex else 2, n_cycles=n_cycles, max_time=max_time ) dt.dump_solver = solvers.cthyb.dump #init the dmft_loop dmft = dmft_loop( cautionary = preset.cautionary, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = impurity, post_impurity = partial( preset.post_impurity ), selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, after_it_is_done = preset.after_it_is_done ) #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) ) if counter==0: #do this only once! if mutilde is None: mu = n*U else: mu = mutilde+U/2.0 dt.mus['up'] = dt.mus['down'] = mu dt.P_imp_iw << 0.0 #for A in bosonic_struct.keys(): # if preset.cautionary.safe_value[A] < 0.0: # safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value[A]*0.95, P_imp=dt.P_imp_iw[A]) dt.Sigma_imp_iw << mu #making sure that in the first iteration Delta is close to half-filled if initial_guess_archive_name!='': dt.load_initial_guess_from_file(initial_guess_archive_name, suffix) #dt.load_initial_guess_from_file("/home/jvucicev/TRIQS/run/sc_scripts/Archive_Vdecoupling/edmft.mutilde0.0.t0.25.U3.0.V2.0.J0.0.T0.01.h5") mpi.barrier() #run dmft!------------- err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_non_local=True) counter += 1 return err
h = Histogram(0, 10) h << x else: h, h_ref = None, None h = mpi.bcast(h) h_ref = mpi.bcast(h_ref) for rank in xrange(mpi.size): if rank == mpi.rank: print '-'*72 print 'rank =', mpi.rank print 'h =\n', h print 'h_ref =\n', h_ref # -- Compare h and h_ref pts = np.array([ int(h.mesh_point(idx)) for idx in xrange(len(h))]) for pt, val in zip(pts, h.data): val = int(val) #print pt, val if val > 0: assert( val == h_ref[pt] ) else: assert( not h_ref.has_key(pt) ) mpi.barrier()
def extract_G_loc(self, mu=None, with_Sigma = True): """ extracts the local downfolded Green function at the chemical potential of the class. At the end, the local G is rotated from the gloabl coordinate system to the local system. if with_Sigma = False: Sigma is not included => non-interacting local GF """ if (mu is None): mu = self.chemical_potential Gloc = [ self.Sigma_imp[icrsh].copy() for icrsh in xrange(self.n_corr_shells) ] # this list will be returned for icrsh in xrange(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero beta = Gloc[0].mesh.beta ikarray=numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): S = self.lattice_gf_matsubara(ik=ik,mu=mu,with_Sigma = with_Sigma, beta = beta) S *= self.bz_weights[ik] for icrsh in xrange(self.n_corr_shells): tmp = Gloc[icrsh].copy() # init temporary storage for sig,gf in tmp: tmp[sig] <<= self.downfold(ik,icrsh,sig,S[sig],gf) Gloc[icrsh] += tmp #collect data from mpi: for icrsh in xrange(self.n_corr_shells): Gloc[icrsh] <<= mpi.all_reduce(mpi.world,Gloc[icrsh],lambda x,y : x+y) mpi.barrier() # Gloc[:] is now the sum over k projected to the local orbitals. # here comes the symmetrisation, if needed: if (self.symm_op!=0): Gloc = self.Symm_corr.symmetrize(Gloc) # Gloc is rotated to the local coordinate system: if (self.use_rotations): for icrsh in xrange(self.n_corr_shells): for sig,gf in Gloc[icrsh]: Gloc[icrsh][sig] <<= self.rotloc(icrsh,gf,direction='toLocal') # transform to CTQMC blocks: Glocret = [ BlockGf( name_block_generator = [ (a,GfImFreq(indices = al, mesh = Gloc[0].mesh)) for a,al in self.gf_struct_solver[i] ], make_copies = False) for i in xrange(self.n_inequiv_corr_shells) ] for ish in xrange(self.n_inequiv_corr_shells): # setting up the index map: map_ind={} cnt = {} for blname in self.map[ish]: cnt[blname] = 0 for a,al in self.gf_struct_solver[ish]: blname = self.map_inv[ish][a] map_ind[a] = range(len(al)) for i in al: map_ind[a][i] = cnt[blname] cnt[blname]+=1 for ibl in range(len(self.gf_struct_solver[ish])): for i in range(len(self.gf_struct_solver[ish][ibl][1])): for j in range(len(self.gf_struct_solver[ish][ibl][1])): bl = self.gf_struct_solver[ish][ibl][0] ind1 = self.gf_struct_solver[ish][ibl][1][i] ind2 = self.gf_struct_solver[ish][ibl][1][j] ind1_imp = map_ind[bl][ind1] ind2_imp = map_ind[bl][ind2] Glocret[ish][bl][ind1,ind2] <<= Gloc[self.invshellmap[ish]][self.map_inv[ish][bl]][ind1_imp,ind2_imp] # return only the inequivalent shells: return Glocret
def partial_charges(self, beta=40): """Calculates the orbitally-resolved density matrix for all the orbitals considered in the input. The theta-projectors are used, hence case.parproj data is necessary""" #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all'] #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data,thingstoread=thingstoread) retval = self.read_par_proj_input_from_hdf() if not retval: return retval if self.symm_op: self.Symm_par = Symmetry(self.hdf_file, subgroup=self.symm_par_data) # Density matrix in the window bln = self.block_names[self.SO] ntoi = self.names_to_ind[self.SO] self.dens_mat_window = [[ numpy.zeros([self.shells[ish][3], self.shells[ish][3]], numpy.complex_) for ish in range(self.n_shells) ] for isp in range(len(bln))] # init the density matrix mu = self.chemical_potential GFStruct_proj = [[(al, range(self.shells[i][3])) for al in bln] for i in xrange(self.n_shells)] if hasattr(self, "Sigma_imp"): Gproj = [ BlockGf(name_block_generator=[ (a, GfImFreq(indices=al, mesh=self.Sigma_imp[0].mesh)) for a, al in GFStruct_proj[ish] ], make_copies=False) for ish in xrange(self.n_shells) ] beta = self.Sigma_imp[0].mesh.beta else: Gproj = [ BlockGf(name_block_generator=[(a, GfImFreq(indices=al, beta=beta)) for a, al in GFStruct_proj[ish]], make_copies=False) for ish in xrange(self.n_shells) ] for ish in xrange(self.n_shells): Gproj[ish].zero() ikarray = numpy.array(range(self.n_k)) #print mpi.rank, mpi.slice_array(ikarray) #print "K-Sum starts on node",mpi.rank," at ",datetime.now() for ik in mpi.slice_array(ikarray): #print mpi.rank, ik, datetime.now() S = self.lattice_gf_matsubara(ik=ik, mu=mu, beta=beta) S *= self.bz_weights[ik] for ish in xrange(self.n_shells): tmp = Gproj[ish].copy() for ir in xrange(self.n_parproj[ish]): for sig, gf in tmp: tmp[sig] <<= self.downfold_pc(ik, ir, ish, sig, S[sig], gf) Gproj[ish] += tmp #print "K-Sum done on node",mpi.rank," at ",datetime.now() #collect data from mpi: for ish in xrange(self.n_shells): Gproj[ish] <<= mpi.all_reduce(mpi.world, Gproj[ish], lambda x, y: x + y) mpi.barrier() #print "Data collected on node",mpi.rank," at ",datetime.now() # Symmetrisation: if (self.symm_op != 0): Gproj = self.Symm_par.symmetrize(Gproj) #print "Symmetrisation done on node",mpi.rank," at ",datetime.now() for ish in xrange(self.n_shells): # Rotation to local: if (self.use_rotations): for sig, gf in Gproj[ish]: Gproj[ish][sig] <<= self.rotloc_all(ish, gf, direction='toLocal') isp = 0 for sig, gf in Gproj[ish]: #dmg.append(Gproj[ish].density()[sig]) self.dens_mat_window[isp][ish] = Gproj[ish].density()[sig] isp += 1 # add Density matrices to get the total: dens_mat = [[ self.dens_mat_below[ntoi[bln[isp]]][ish] + self.dens_mat_window[isp][ish] for ish in range(self.n_shells) ] for isp in range(len(bln))] return dens_mat
def cellular_calculation( Lx=2, Ly=1, periodized=False, triangular=False, Us=[1.0], Ts=[0.125], ns=[0.5], fixed_n=True, mutildes=[0.0], dispersion=lambda kx, ky: matrix_dispersion(2, -0.25, 0.0, kx, ky), ph_symmetry=False, dispersion_automatic=True, scalar_dispersion=lambda kx, ky: epsilonk_square(kx, ky, -0.25), n_ks=[24], n_k_automatic=False, n_k_rules=[[0.06, 32], [0.03, 48], [0.005, 64], [0.00, 96]], w_cutoff=20.0, min_its=5, max_its=25, mix_Sigma=False, rules=[[0, 0.5], [6, 0.2], [12, 0.65]], do_dmft_first=False, use_cthyb=False, alpha=0.5, delta=0.1, n_cycles=100000, max_time_rules=[[1, 5 * 60], [2, 20 * 60], [4, 80 * 60], [8, 200 * 60], [16, 400 * 60]], time_rules_automatic=False, exponent=0.7, overall_prefactor=1.0, no_timing=False, accuracy=1e-4, solver_data_package=None, print_current=1, insulating_initial=False, initial_guess_archive_name='', suffix='', start_from_Gweiss=False): if mpi.is_master_node(): print "WELCOME TO cellular calculation!" if n_k_automatic: print "n_k automatic!!!" if len(n_ks) == 0 and n_k_automatic: n_ks = [0] if use_cthyb: solver_class = solvers.cthyb else: solver_class = solvers.ctint fermionic_struct = {'up': [0]} Nc = Lx * Ly impurity_struct = {'%sx%s' % (Lx, Ly): range(Nc)} if not time_rules_automatic: max_times = {} for C in impurity_struct: for r in max_time_rules: if r[0] <= len(impurity_struct[C]): max_times[C] = r[1] if mpi.is_master_node(): print "max_times from rules: ", max_times beta = 1.0 / Ts[0] n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ", n_iw if not n_k_automatic: n_k = n_ks[0] print "n_k = ", n_k else: n_k = n_k_from_rules(Ts[0], n_k_rules) #if mpi.is_master_node(): print "n_k automatic!!!" dt = cellular_data( n_iw=n_iw, n_k=n_k, beta=beta, impurity_struct=impurity_struct, fermionic_struct=fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file") if fixed_n: ps = itertools.product(n_ks, ns, Us, Ts) else: ps = itertools.product(n_ks, mutildes, Us, Ts) counter = 0 old_nk = n_k old_beta = beta for p in ps: #name stuff to avoid confusion nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules)) if fixed_n: n = p[1] else: mutilde = p[1] n = None U = p[2] T = p[3] beta = 1.0 / T if nk != old_nk and (not n_k_automatic): dt.change_ks(IBZ.k_grid(nk)) if beta != old_beta: n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0) if n_k_automatic: nk = n_k_from_rules(T, n_k_rules) if nk != old_nk: dt.change_ks(IBZ.k_grid(nk)) dt.change_beta(beta, n_iw) old_beta = beta old_nk = nk filename = "result" if len(n_ks) > 1 and (not n_k_automatic): filename += ".nk%s" % nk if len(ns) > 1 and fixed_n: filename += ".n%s" % n if len(mutildes) > 1 and not fixed_n: filename += ".mutilde%s" % mutilde if len(Us) > 1: filename += ".U%s" % U if len(Ts) > 1: filename += ".T%.4f" % T filename += ".h5" dt.archive_name = filename if mpi.is_master_node(): if fixed_n: print "Working: U: %s T %s n: %s n_k: %s n_iw: %s" % (U, n, T, nk, n_iw) else: print "Working: U: %s T %s mutilde: %s n_k: %s n_iw: %s" % ( U, mutilde, T, nk, n_iw) if mpi.is_master_node(): print "about to fill dispersion. ph-symmetry: ", ph_symmetry for key in dt.fermionic_struct.keys(): for kxi in range(dt.n_k): for kyi in range(dt.n_k): dt.epsilonijk[key][:, :, kxi, kyi] = dispersion( dt.ks[kxi], dt.ks[kyi]) if not triangular: prepare_cellular(dt, Lx, Ly, solver_class, periodized) identical_pairs = { dt.impurity_struct.keys()[0]: get_identical_pair_sets(Lx, Ly) } else: prepare_cellular_triangular(dt, Lx, Ly, solver_class, periodized) identical_pairs = { dt.impurity_struct.keys()[0]: triangular_identical_pair_sets(Lx, Ly) } solver_class.initialize_solvers(dt, solver_data_package) max_times = {} if no_timing: for C in dt.impurity_struct.keys(): max_times[C] = -1 if mpi.is_master_node(): print "no_timing! solvers will run until they perform all the mc steps", max_times if time_rules_automatic and (not no_timing): for C in dt.impurity_struct.keys(): Nc = len(dt.impurity_struct[C]) pref = ((dt.beta / 8.0) * U * Nc)**exponent #**1.2 print C print "Nc: ", Nc, print "U: ", U, print "beta: ", dt.beta, print "pref: ", pref max_times[C] = int(overall_prefactor * pref * 5 * 60) if mpi.is_master_node(): print "max times automatic: ", max_times actions = [ generic_action( name="lattice", main=lambda data: [ data.get_Sigmaijkw(), nested_mains.lattice(data, n=n, ph_symmetry=ph_symmetry, accepted_mu_range=[-2.0, 2.0]) ], mixers=[], cautionaries=[], allowed_errors=[], printout=lambda data, it: ([ data.dump_general(quantities= ['Sigmaijkw', 'Gijkw', 'G_ij_iw'], suffix='-current'), data.dump_scalar(suffix='-current') ] if ((it + 1) % print_current == 0) else None)), generic_action( name="pre_impurity", main=lambda data: nested_mains.pre_impurity(data), mixers=[], cautionaries=[], allowed_errors=[], printout=lambda data, it: (data.dump_general(quantities=['Gweiss_iw'], suffix='-current') if ((it + 1) % print_current == 0) else None)), generic_action( name="impurity", main=(lambda data: nested_mains.impurity( data, U, symmetrize_quantities=True, alpha=alpha, delta=delta, n_cycles=n_cycles, max_times=max_times, solver_data_package=solver_data_package)) if (not use_cthyb) else (lambda data: nested_mains.impurity_cthyb( data, U, symmetrize_quantities=True, n_cycles=n_cycles, max_times=max_times, solver_data_package=solver_data_package)), mixers=[], cautionaries=[ lambda data, it: local_nan_cautionary(data, data.impurity_struct, Qs=['Sigma_imp_iw'], raise_exception=True ), lambda data, it: symmetrize_cluster_impurity( data.Sigma_imp_iw, identical_pairs) ], allowed_errors=[1], printout=lambda data, it: ([ data.dump_general(quantities=['Sigma_imp_iw', 'G_imp_iw'], suffix='-current'), data.dump_solvers(suffix='-current') ] if ((it + 1) % print_current == 0) else None)) ] monitors = [ monitor(monitored_quantity=lambda: dt.ns['up'], h5key='n_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.mus['up'], h5key='mu_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.err, h5key='err_vs_it', archive_name=dt.archive_name) ] #, # monitor( monitored_quantity = lambda: actions[3].errs[0], # h5key = 'sign_err_vs_it', # archive_name = dt.archive_name) ] convergers = [ converger(monitored_quantity=lambda: dt.G_ij_iw, accuracy=accuracy, struct=impurity_struct, archive_name=dt.archive_name, h5key='diffs_G_loc') ] convergers.append( converger(monitored_quantity=lambda: dt.G_imp_iw, accuracy=accuracy, struct=impurity_struct, archive_name=dt.archive_name, h5key='diffs_G_imp')) dmft = generic_loop(name="cellular DMFT", actions=actions, convergers=convergers, monitors=monitors) if (counter == 0): #do the initial guess only once! if initial_guess_archive_name != '': if start_from_Gweiss: dt.mus['up'] = U / 2.0 A = HDFArchive(initial_guess_archive_name, "r") dt.Gweiss_iw << A['Gweiss_iw%s' % suffix] del A dt.dump_general(quantities=['Gweiss_iw'], suffix='-initial') else: if mpi.is_master_node(): print "constructing dt from initial guess in a file: ", initial_guess_archive_name, "suffix: ", suffix old_epsilonk = dt.epsilonk dt.construct_from_file(initial_guess_archive_name, suffix) if dt.beta != beta: dt.change_beta(beta, n_iw) if dt.n_k != nk: dt.change_ks(IBZ.k_grid(nk)) if mpi.is_master_node(): print "putting back the old Jq and epsilonk" dt.epsilonk = old_epsilonk else: if not fixed_n: dt.mus['up'] = U / 2.0 + mutilde else: dt.mus['up'] = U / 2.0 if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus[ 'up'] #this is not necessary at the moment, but may become for C in dt.impurity_struct.keys(): for l in dt.impurity_struct[ C]: #just the local components (but on each site!) dt.Sigma_imp_iw[C].data[:, l, l] = U / 2.0 - int( insulating_initial) * 1j / numpy.array(dt.ws) for key in fermionic_struct.keys(): for l in range(dt.Nc): numpy.transpose( dt.Sigmaijkw[key])[:, :, l, l, :] = U / 2.0 - int( insulating_initial) * 1j / numpy.array(dt.ws) dt.dump_general(quantities=['Sigmaijkw', 'Sigma_imp_iw'], suffix='-initial') if (counter == 0) and do_dmft_first: assert False, "not implemented" #run cellular!------------- if mix_Sigma: actions[3].mixers.append( mixer(mixed_quantity=lambda: dt.Sigmaijkw, rules=rules, func=mixer.mix_matrix_lattice_gf, initialize=True)) dt.dump_parameters() dt.dump_non_interacting() err = dmft.run(dt, max_its=max_its, min_its=min_its, max_it_err_is_allowed=7, print_final=True, print_current=1, start_from_action_index=(2 if start_from_Gweiss else 0)) if mpi.is_master_node(): print "periodizing result..." print "filling scalar dispersion..." for key in dt.fermionic_struct.keys(): for kxi in range(dt.n_k): for kyi in range(dt.n_k): dt.epsilonk[key][kxi, kyi] = scalar_dispersion( dt.ks[kxi], dt.ks[kyi]) dt.dump_general(['epsilonk'], suffix='') dt.periodize_cumul() dt.dump_general(['Gkw', 'Sigmakw', 'gkw', 'gijw', 'g_imp_iw'], suffix='-periodized_cumul') dt.periodize_selfenergy() dt.dump_general(['Gkw', 'Sigmakw', 'Sigmaijw'], suffix='-periodized_selfenergy') cmd = 'mv %s %s' % (filename, filename.replace( "result", "cellular")) print cmd os.system(cmd) if (err == 2): print "Cautionary error!!! exiting..." solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) break if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() counter += 1 if not (solver_data_package is None): solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) return dt, monitors, convergers
def supercond_hubbard_calculation( Ts = [0.12,0.08,0.04,0.02,0.01], mutildes=[0.0, 0.2, 0.4, 0.6, 0.8], ns = [0.5,0.53,0.55,0.57,0.6], fixed_n = False, ts=[0.25], t_dispersion = epsilonk_square, ph_symmetry = True, Us = [1.0,2.0,3.0,4.0], alpha=2.0/3.0, ising = False, hs = [0], frozen_boson = False, refresh_X = True, strength = 5.0, max_it = 10, n_ks = [24], n_k_automatic = False, n_k_rules = [[0.06, 32],[0.03, 48],[0.005, 64],[0.00, 96]], w_cutoff = 20.0, n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], mix_Sigma = True, trilex = False, edmft = False, local_bubble_for_charge_P = False,charge_boson_GW_style = False, imtime = True, use_optimized = True, N_cores = 1, do_dmft_first = True, do_normal = True, do_eigenvalue = False, do_superconducting = False, initial_X_prefactor = 2.0, use_cthyb=True, n_cycles=100000, max_time=10*60, accuracy = 1e-4, supercond_accr = 1e-8, solver_data_package = None, print_local_frequency=5, print_non_local_frequency = 5, total_debug=False, initial_guess_archive_name = '', suffix='', clean_up_polarization = True): if mpi.is_master_node(): print "WELCOME TO supercond hubbard calculation!" if n_k_automatic: print "n_k automatic!!!" if len(n_ks)==0 and n_k_automatic: n_ks=[0] loc_from_imp = trilex or edmft bosonic_struct = {'0': [0], '1': [0]} if not ising: if alpha==2.0/3.0: del bosonic_struct['1'] if alpha==1.0/3.0: del bosonic_struct['0'] else: if alpha==1.0: del vks['1'] if alpha==0.0: del vks['0'] fermionic_struct = {'up': [0], 'down': [0]} if not loc_from_imp: del fermionic_struct['down'] beta = 1.0/Ts[0] n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ",n_iw n_tau = int(n_iw*pi) if not n_k_automatic: n_q = n_ks[0] n_k = n_q else: n_k = n_q = n_k_from_rules(Ts[0], n_k_rules) if mpi.is_master_node(): print "n_k automatic!!!" #init solver if use_cthyb and loc_from_imp: if solver_data_package is None: solver_data_package = {} solver_data_package['solver'] = 'cthyb' solver_data_package['constructor_parameters']={} solver_data_package['constructor_parameters']['beta'] = beta solver_data_package['constructor_parameters']['gf_struct'] = fermionic_struct solver_data_package['constructor_parameters']['n_tau_k'] = n_tau solver_data_package['constructor_parameters']['n_tau_g'] = 10000 solver_data_package['constructor_parameters']['n_tau_delta'] = 10000 solver_data_package['constructor_parameters']['n_tau_nn'] = 4*n_tau solver_data_package['constructor_parameters']['n_w_b_nn'] = n_iw solver_data_package['constructor_parameters']['n_w'] = n_iw solver_data_package['construct|run|exit'] = 0 if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package) solver = Solver( **solver_data_package['constructor_parameters'] ) else: solver = None assert not( imtime and trilex ), "imtime bubbles inapplicable in trilex" #init data, assign the solver to it dt = supercond_data( n_iw = n_iw, ntau = (None if (imtime) else 3 ), #no need to waste memory on tau-dependent quantities unless we're going to use them (None means ntau=n_iw*5) n_k = n_k, n_q = n_q, beta = beta, solver = solver, bosonic_struct = bosonic_struct, fermionic_struct = fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file" ) if trilex or (edmft and local_bubble_for_charge_P and not charge_boson_GW_style): #if emdft, nothing to add dt.__class__=supercond_trilex_data dt.promote(dt.n_iw/2, dt.n_iw/2) if use_optimized: dt.patch_optimized() #init convergence and cautionary measures convergers = [ converger( monitored_quantity = lambda: dt.P_loc_iw, accuracy=accuracy, struct=bosonic_struct, archive_name="not_yet_you_shouldnt_see_this_file", h5key = 'diffs_P_loc' ), converger( monitored_quantity = lambda: dt.G_loc_iw, accuracy=accuracy, struct=fermionic_struct, archive_name="not_yet_you_shouldnt_see_this_file", h5key = 'diffs_G_loc' ) ] #initial guess #assert not(trilex and fixed_n), "trilex doesn't yet work" if fixed_n: ps = itertools.product(n_ks,ts,ns,Us,Ts,hs) else: ps = itertools.product(n_ks,ts,mutildes,Us,Ts,hs) counter = 0 old_nk = n_k old_beta = beta old_get_Xkw = None #-------------------------------------------------------------------------------------------------------------------------------# for p in ps: #name stuff to avoid confusion t = p[1] if fixed_n: n = p[2] else: mutilde = p[2] n = None U = p[3] T = p[4] beta = 1.0/T h = p[5] nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules) ) if nk!=old_nk and (not n_k_automatic): dt.change_ks(IBZ.k_grid(nk)) old_nk = nk if beta!=old_beta: n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0) n_tau = int(n_iw*pi) if n_k_automatic: nk = n_k_from_rules(T, n_k_rules) if nk != old_nk: dt.change_ks(IBZ.k_grid(nk)) old_nk = nk dt.change_beta(beta, n_iw) if loc_from_imp: if solver_data_package is None: solver_data_package = {} solver_data_package['constructor_parameters']={} solver_data_package['constructor_parameters']['beta'] = beta solver_data_package['constructor_parameters']['gf_struct'] = fermionic_struct solver_data_package['constructor_parameters']['n_tau_k'] = n_tau solver_data_package['constructor_parameters']['n_tau_g'] = 10000 solver_data_package['constructor_parameters']['n_tau_delta'] = 10000 solver_data_package['constructor_parameters']['n_tau_nn'] = 4*n_tau solver_data_package['constructor_parameters']['n_w_b_nn'] = n_iw solver_data_package['constructor_parameters']['n_w'] = n_iw solver_data_package['construct|run|exit'] = 0 if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package) dt.solver = Solver( **solver_data_package['constructor_parameters'] ) old_beta = beta filename = "result" if len(n_ks)>1 and (not n_k_automatic): filename += ".nk%s"%nk if len(ts)>1: filename += ".t%s"%t if len(ns)>1 and fixed_n: filename += ".n%s"%n if len(mutildes)>1 and not fixed_n: filename += ".mutilde%s"%mutilde if len(Us)>1: filename += ".U%s"%U if len(Ts)>1: filename += ".T%.4f"%T if len(hs)>1: filename += ".h%s"%h filename += ".h5" dt.archive_name = filename for conv in convergers: conv.archive_name = dt.archive_name if not ising: Uch = (3.0*alpha-1.0)*U Usp = (alpha-2.0/3.0)*U else: Uch = alpha*U Usp = (alpha-1.0)*U vks = {'0': lambda kx,ky: Uch, '1': lambda kx,ky: Usp} if not ising: if alpha==2.0/3.0: del vks['1'] if alpha==1.0/3.0: del vks['0'] else: if alpha==1.0: del vks['1'] if alpha==0.0: del vks['0'] dt.fill_in_Jq( vks ) dt.fill_in_epsilonk(dict.fromkeys(fermionic_struct.keys(), partial(t_dispersion, t=t))) #assert not(use_optimized and trilex), "don't have optimized freq summation from trilex" if trilex and charge_boson_GW_style: dt.Lambda_wrapper = lambda A,wi,nui: ( (dt.__class__.Lambda_wrapper(dt,A,wi,nui)) if (A=='1') else 1.0 ) Lam = ( dt.Lambda_wrapper if trilex else ( lambda A, wi, nui: 1.0 ) ) if (not use_optimized) or (not imtime): #automatically if trilex because imtime = False is asserted dt.get_Sigmakw = lambda: dt.__class__.get_Sigmakw(dt, ising_decoupling = ising, imtime = imtime, Lambda = Lam) dt.get_Xkw = lambda: dt.__class__.get_Xkw(dt, ising_decoupling = ising, imtime = imtime, Lambda = Lam) dt.get_Pqnu = lambda: dt.__class__.get_Pqnu(dt, imtime = imtime, Lambda = Lam) else: dt.get_Sigmakw = lambda: GW_data.optimized_get_Sigmakw(dt, ising_decoupling = ising, N_cores=N_cores) dt.get_Xkw = lambda: supercond_data.optimized_get_Xkw(dt, ising_decoupling = ising, N_cores=N_cores) dt.get_Pqnu = lambda: supercond_data.optimized_get_Pqnu(dt, N_cores=N_cores) dt.get_Sigma_loc_from_local_bubble = lambda: GW_data.get_Sigma_loc_from_local_bubble(dt, ising_decoupling = ising, imtime = imtime, Lambda = Lam) if local_bubble_for_charge_P: dt.get_P_loc_from_local_bubble = lambda: GW_data.get_P_loc_from_local_bubble(dt, imtime = False, Lambda = dt.Lambda_wrapper) if charge_boson_GW_style: dt.get_P_loc_from_local_bubble = lambda: GW_data.get_P_loc_from_local_bubble(dt, imtime = imtime, Lambda = lambda A,wi,nui: 1.0) dt.optimized_get_P_imp = lambda: GW_data.optimized_get_P_imp(dt, use_caution=not local_bubble_for_charge_P and not charge_boson_GW_style, prefactor=0.99, use_local_bubble_for_charge = local_bubble_for_charge_P or charge_boson_GW_style ) #dt.optimized_get_P_imp = lambda: GW_data.optimized_get_P_imp(dt, use_caution=False, prefactor=0.99, use_local_bubble_for_charge = local_bubble_for_charge_P) if not loc_from_imp: dt.get_P_loc_from_local_bubble = lambda: dt.__class__.get_P_loc_from_local_bubble(dt, imtime = imtime, Lambda = Lam) if ((h==0.0)or(h==0))and (not refresh_X): if mpi.is_master_node(): print "assigning GW_data.Pqnu because no h, no imposed X" old_get_Xkw = dt.get_Xkw #save the old one and put it back before returning data old_get_Pqnu = dt.get_Pqnu dt.get_Xkw = lambda: None if (not use_optimized) or (not imtime): dt.get_Pqnu = lambda: GW_data.get_Pqnu(dt, imtime = imtime, Lambda = Lam) else: dt.get_Pqnu = lambda: GW_data.optimized_get_Pqnu(dt, N_cores=N_cores) if trilex or (edmft and local_bubble_for_charge_P and not charge_boson_GW_style): preset = supercond_trilex_hubbard(U=U, alpha=alpha, ising = ising, frozen_boson=(frozen_boson if (T!=Ts[0]) else False), refresh_X = refresh_X, n = n, ph_symmetry = ph_symmetry) elif edmft: preset = supercond_EDMFTGW_hubbard(U=U, alpha=alpha, ising = ising, frozen_boson=(frozen_boson if (T!=Ts[0]) else False), refresh_X = refresh_X, n = n, ph_symmetry = ph_symmetry) else: preset = supercond_hubbard(frozen_boson=(frozen_boson if (T!=Ts[0]) else False), refresh_X=refresh_X, n = n, ph_symmetry=ph_symmetry) if refresh_X: preset.cautionary.refresh_X = partial(preset.cautionary.refresh_X, strength=strength, max_it=max_it) if mpi.is_master_node(): if fixed_n: print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," n= ",n else: print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," mutilde= ",mutilde #print "cautionary safe values: ",preset.cautionary.safe_value if loc_from_imp: if trilex or (local_bubble_for_charge_P and not charge_boson_GW_style): n_w_f=dt.n_iw_f n_w_b=dt.n_iw_b else: n_w_f=4 n_w_b=4 if use_cthyb: impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, trilex=trilex or (local_bubble_for_charge_P and not charge_boson_GW_style), n_w_f=n_w_f, n_w_b=n_w_b, n_cycles=n_cycles, max_time=max_time, solver_data_package = solver_data_package ) dt.dump_solver = partial(solvers.cthyb.dump, solver = dt.solver, archive_name = dt.archive_name) else: impurity = partial( solvers.ctint.run, n_cycles=n_cycles) dt.dump_solver = partial(solvers.cthyb.dump, solver = dt.solver, archive_name = dt.archive_name) else: impurity = lambda data: None mixers = [mixer( mixed_quantity = lambda: dt.Pqnu, rules=rules, func=mixer.mix_lattice_gf ), mixer( mixed_quantity = lambda: dt.P_loc_iw, rules=rules, func=mixer.mix_block_gf ) ] if mix_Sigma: mixers.extend([mixer( mixed_quantity = lambda: dt.Sigmakw, rules=rules, func=mixer.mix_lattice_gf), mixer( mixed_quantity = lambda: dt.Sigma_loc_iw, rules=rules, func=mixer.mix_block_gf)]) monitors = [ monitor( monitored_quantity = lambda: dt.ns['up'], h5key = 'n_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.mus['up'], h5key = 'mu_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: numpy.amax(dt.Pqnu['1'][dt.m_to_nui(0),:,:]*Usp), h5key = 'maxPspUsp_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.err, h5key = 'err_vs_it', archive_name = dt.archive_name) ] if loc_from_imp: monitors.extend([ monitor( monitored_quantity = lambda: dt.P_imp_iw['0'].data[dt.m_to_nui(0),0,0], h5key = 'Pimp_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.W_loc_iw['0'].data[dt.m_to_nui(0),0,0], h5key = 'Wloc_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.Uweiss_iw['0'].data[dt.m_to_nui(0),0,0], h5key = 'Uweiss_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.chi_imp_iw['0'].data[dt.m_to_nui(0),0,0], h5key = 'chimp_vs_it', archive_name = dt.archive_name) ]) #mixers.extend([ mixer( mixed_quantity = lambda: dt.chi_imp_iw['0'], # rules=[[0,0.9]], # func=mixer.mix_gf) ] ) #init the dmft_loop dmft = dmft_loop( cautionary = preset.cautionary, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = impurity, post_impurity = preset.post_impurity, selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, monitors = monitors, after_it_is_done = preset.after_it_is_done ) #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) ) #if (T==Ts[0]) and trilex: #do this only once! # dt.mus['up'] = dt.mus['down'] = mutilde+U/2.0 # dt.P_imp_iw << 0.0 # dt.Sigma_imp_iw << U/2.0 + mutilde #making sure that in the first iteration the impurity problem is half-filled. if not solving impurity problem, not needed # for U in fermionic_struct.keys(): dt.Sigmakw[U].fill(0) # for U in fermionic_struct.keys(): dt.Xkw[U].fill(0) if (T==Ts[0]): #do the initial guess only once! if initial_guess_archive_name!='': if mpi.is_master_node(): print "constructing dt from initial guess in a file: ",initial_guess_archive_name, "suffix: ",suffix old_Jq = dt.Jq #this thing is the parameter of the calculation, we don't want to load it from the initial guess file old_epsilonk = dt.epsilonk dt.construct_from_file(initial_guess_archive_name, suffix) if dt.beta != beta: dt.change_beta(beta, n_iw) if dt.n_k != nk: dt.change_ks(IBZ.k_grid(nk)) if mpi.is_master_node(): print "putting back the old Jq and epsilonk" dt.epsilonk = old_epsilonk dt.Jq = old_Jq if clean_up_polarization: if mpi.is_master_node(): print "now emptying polarization to be sure" for A in dt.bosonic_struct.keys(): #empty the Polarization!!!!!!!!!!!! dt.Pqnu[A][:,:,:] = 0.0 dt.P_loc_iw[A] << 0.0 dt.chi_imp_iw[A] << 0.0 else: if not fixed_n: dt.mus['up'] = mutilde else: dt.mus['up'] = 0.0 if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus['up'] #this is not necessary at the moment, but may become dt.P_imp_iw << 0.0 if loc_from_imp: #making sure that in the first iteration the impurity problem is half-filled. if not solving impurity problem, not needed dt.Sigma_loc_iw << U/2.0 else: dt.Sigma_loc_iw << 0.0 for U in fermionic_struct.keys(): dt.Sigmakw[U].fill(0) for U in fermionic_struct.keys(): dt.Xkw[U].fill(0) #note that below from here U is no longer U because of the above for loops if not do_superconducting: for U in fermionic_struct.keys(): dt.Xkw[U].fill(0) if loc_from_imp and (T==Ts[0]) and do_dmft_first: #do one short run of dmft before starting emdft+gw if mpi.is_master_node(): print "================= 20 iterations of DMFT!!!! =================" Jqcopy = deepcopy(dt.Jq) #copy the old Jq for A in dt.bosonic_struct.keys(): dt.Jq[A][:,:] = 0.0 #setting bare bosonic propagators to zero reduces the calculation to dmft. #but we also don't want to do the calculation of Sigmakw and Pqnu get_Sigmakw = dt.get_Sigmakw get_Pqnu = dt.get_Pqnu get_Xkw = dt.get_Xkw def copy_Sigma_loc_to_Sigmakw(): if mpi.is_master_node(): print ">>>>> just copying Sigma_loc to Sigma_kw" for U in dt.fermionic_struct.keys(): numpy.transpose(dt.Sigmakw[U])[:] = dt.Sigma_loc_iw[U].data[:,0,0] dt.get_Sigmakw = copy_Sigma_loc_to_Sigmakw dt.get_Pqnu = lambda: None dt.get_Xkw = lambda: None if trilex: #get rid of vertex related stuff get_chi3_imp = dt.get_chi3_imp get_chi3tilde_imp = dt.get_chi3tilde_imp get_Lambda_imp = dt.get_Lambda_imp dt.get_chi3_imp = lambda: None dt.get_chi3tilde_imp = lambda: None dt.get_Lambda_imp = lambda: None old_impurity = dmft.impurity dmft.impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, trilex=False, n_w_f=n_w_f, n_w_b=n_w_b, n_cycles=n_cycles, max_time=( max_time if (not trilex) else (max_time/2)), solver_data_package = solver_data_package ) dmft.mixers = [] # no mixing dmft.cautionary = None # nothing to be cautious about # DO THE CALC dmft.run( dt, calculation_name = 'dmft', total_debug = total_debug, n_loops_max=20, n_loops_min=15, print_local=1, print_impurity_input=1, print_three_leg=100000, print_non_local=10000, print_impurity_output=1, skip_self_energy_on_first_iteration=True, mix_after_selfenergy = True, last_iteration_err_is_allowed = 100 ) #move the result if mpi.is_master_node(): cmd = 'mv %s %s'%(filename, filename.replace("result", "dmft")) print cmd os.system(cmd) # put everything back to normal dmft.mixers = mixers dmft.cautionary = preset.cautionary dt.Jq = Jqcopy #put back the old Jq now for the actual calculation for A in dt.bosonic_struct.keys(): #empty the Polarization!!!!!!!!!!!! dt.Pqnu[A][:,:,:] = 0.0 dt.P_loc_iw[A] << 0.0 dt.chi_imp_iw[A] << 0.0 dt.get_Sigmakw = get_Sigmakw dt.get_Pqnu = get_Pqnu dt.get_Xkw = get_Xkw if trilex: #put back in the vertex related stuff dt.get_chi3_imp = get_chi3_imp dt.get_chi3tilde_imp = get_chi3tilde_imp dt.get_Lambda_imp = get_Lambda_imp dmft.impurity = old_impurity if refresh_X: preset.cautionary.reset() preset.cautionary.refresh_X(dt) if h!=0: for kxi in range(dt.n_k): for kyi in range(dt.n_k): for wi in range(dt.nw): for U in fermionic_struct.keys(): dt.hsck[U][kxi, kyi] = X_dwave(dt.ks[kxi],dt.ks[kyi], h) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() #run dmft!------------- if do_normal and not (do_superconducting and T!=Ts[0]): err = dmft.run( dt, calculation_name = 'normal', total_debug = total_debug, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_local=print_local_frequency, print_impurity_input=( 1 if loc_from_imp else 1000 ), print_three_leg=1, print_non_local=print_non_local_frequency, skip_self_energy_on_first_iteration=True, mix_after_selfenergy = True, last_iteration_err_is_allowed = n_loops_max+5 ) #n_loops_max/2 ) if (err==2): print "Cautionary error!!! exiting..." solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package) break if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if do_eigenvalue: #get the leading eigenvalue and the corresponding eigenvector to be used as the initial guess for Xkw if imtime and use_optimized: dt.optimized_get_leading_eigenvalue(max_it = 60, accr = 5e-4, ising_decoupling = ising, N_cores = N_cores, symmetry = 'd') #for now let's stick to plain d-wave else: dt.get_Xkw = lambda: supercond_data.get_Xkw( dt, imtime = False, simple = False, use_IBZ_symmetry = False, ising_decoupling=ising, su2_symmetry=True, wi_list = [], Lambda = dt.Lambda_wrapper) dt.get_leading_eigenvalue(max_it = 60, accr = 5e-4, ising_decoupling = ising, symmetry = 'd') #for now let's stick to plain d-wave if mpi.is_master_node(): if dt.eig_ratio < 1.0: print ">>>>>>>>>>> eig_ratio<1.0... better luck next time" else: print ">>>>>>>>>>> eig_ratio>=1.0!!" dt.dump_all(suffix='-final') cmd = 'mv %s %s'%(filename, filename.replace("result", "result_normal")) print cmd os.system(cmd) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if do_superconducting and (dt.eig_ratio >= 1.0): if mpi.is_master_node(): print "--------------------------------- will now do superconducting calculation!!! ------------------------------" # start from a small gap for U in dt.fermionic_struct.keys(): dt.Xkw[U] *= initial_X_prefactor #put back in the supercond functions for Sigma and P dt.get_Xkw = old_get_Xkw dt.get_Pqnu = old_get_Pqnu monitors.extend( [ monitor( monitored_quantity = lambda: dt.Xkw['up'][dt.nw/2,0,dt.n_k/2].real, h5key = 'Xkw_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: numpy.amax(dt.Fkw['up'][:,:,:].real), h5key = 'Fkw_vs_it', archive_name = dt.archive_name) ] ) for conv in convergers: conv.accuracy = supercond_accr #run the calculation again err = dmft.run( dt, calculation_name = 'supercond', total_debug = total_debug, n_loops_max=100, n_loops_min=25, print_local=print_local_frequency, print_impurity_input=( 1 if loc_from_imp else 1000 ), print_three_leg=1, print_non_local=5, skip_self_energy_on_first_iteration=True, mix_after_selfenergy = True, last_iteration_err_is_allowed = n_loops_max+5 ) #n_loops_max/2 ) elif do_superconducting: if mpi.is_master_node(): print "--------------------------------- no point in doing superconducting calculation: eig_ratio<1" counter += 1 if not (old_get_Xkw is None): dt.get_Xkw = old_get_Xkw #putting back the function for later use solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package) return dt, monitors, convergers
def dca_calculation(dca_scheme, ph_symmetry=False, Us=[1.0], Ts=[0.125], ns=[0.5], fixed_n=True, mutildes=[0.0], w_cutoff=20.0, min_its=5, max_its=25, mix_Sigma=False, rules=[[0, 0.5], [6, 0.2], [12, 0.65]], do_dmft_first=False, alpha=0.5, delta=0.1, automatic_alpha_and_delta=False, n_cycles=10000000, max_time_rules=[[1, 5 * 60], [2, 20 * 60], [4, 80 * 60], [8, 200 * 60], [16, 400 * 60]], time_rules_automatic=False, exponent=0.7, overall_prefactor=1.0, no_timing=False, accuracy=1e-4, solver_data_package=None, print_current=1, initial_guess_archive_name='', suffix=''): if mpi.is_master_node(): print "WELCOME TO dca calculation!" solver_class = solvers.ctint impurity_struct = dca_scheme.get_impurity_struct() fermionic_struct = dca_scheme.get_fermionic_struct() if mpi.is_master_node(): print "impurity_struct: ", impurity_struct if mpi.is_master_node(): print "fermionic_struct: ", fermionic_struct if not time_rules_automatic: max_times = {} for C in impurity_struct: for r in max_time_rules: if r[0] <= len(impurity_struct[C]): max_times[C] = r[1] if mpi.is_master_node(): print "max_times from rules: ", max_times beta = 1.0 / Ts[0] n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ", n_iw dt = dca_data(n_iw=n_iw, beta=beta, impurity_struct=impurity_struct, fermionic_struct=fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file") if fixed_n: ps = itertools.product(ns, Us, Ts) else: ps = itertools.product(mutildes, Us, Ts) counter = 0 old_beta = beta for p in ps: #name stuff to avoid confusion if fixed_n: n = p[0] else: mutilde = p[0] n = None U = p[1] T = p[2] beta = 1.0 / T if beta != old_beta: n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0) dt.change_beta(beta, n_iw) old_beta = beta filename = "result" if len(ns) > 1 and fixed_n: filename += ".n%s" % n if len(mutildes) > 1 and not fixed_n: filename += ".mutilde%s" % mutilde if len(Us) > 1: filename += ".U%s" % U if len(Ts) > 1: filename += ".T%.4f" % T filename += ".h5" dt.archive_name = filename if mpi.is_master_node(): if fixed_n: print "Working: U: %s T %s n: %s " % (U, T, n) else: print "Working: U: %s T %s mutilde: %s " % (U, T, mutilde) prepare_dca(dt, dca_scheme, solver_class) solver_class.initialize_solvers(dt, solver_data_package) if no_timing: for C in dt.impurity_struct.keys(): max_times[C] = -1 if mpi.is_master_node(): print "no_timing! solvers will run until they perform all the mc steps", max_times if time_rules_automatic and (not no_timing): max_times = {} for C in dt.impurity_struct.keys(): Nc = len(dt.impurity_struct[C]) pref = ((dt.beta / 8.0) * U * Nc)**exponent #**1.2 print C print "Nc: ", Nc, print "U: ", U, print "beta: ", dt.beta, print "pref: ", pref max_times[C] = int(overall_prefactor * pref * 5 * 60) if mpi.is_master_node(): print "max times automatic: ", max_times identical_pairs = dca_scheme.get_identical_pairs() if not (identical_pairs is None): print "identical pairs not known, there will be no symmetrization" identical_pairs = {'x': identical_pairs} actions = [ generic_action(name="lattice", main=lambda data: nested_mains.lattice( data, n=n, ph_symmetry=ph_symmetry, accepted_mu_range=[-2.0, 2.0]), mixers=[], cautionaries=[], allowed_errors=[], printout=lambda data, it: ([ data.dump_general(quantities=['GK_iw', 'GR_iw'], suffix='-current'), data.dump_scalar(suffix='-current') ] if ((it + 1) % print_current == 0) else None)), generic_action( name="pre_impurity", main=lambda data: nested_mains.pre_impurity(data), mixers=[], cautionaries=[], allowed_errors=[], printout=lambda data, it: (data.dump_general( quantities=['GweissK_iw', 'GweissR_iw', 'Gweiss_iw'], suffix='-current') if ( (it + 1) % print_current == 0) else None)), generic_action( name="impurity", main=(lambda data: nested_mains.impurity( data, U, symmetrize_quantities=True, alpha=alpha, delta=delta, automatic_alpha_and_delta=automatic_alpha_and_delta, n_cycles=n_cycles, max_times=max_times, solver_data_package=solver_data_package)), mixers=[], cautionaries=[ lambda data, it: local_nan_cautionary(data, data.impurity_struct, Qs=['Sigma_imp_iw'], raise_exception=True ), lambda data, it: (symmetric_G_and_self_energy_on_impurity( data.G_imp_iw, data.Sigma_imp_iw, data.solvers, identical_pairs, identical_pairs) if it >= 100 else symmetrize_cluster_impurity( data.Sigma_imp_iw, identical_pairs)) ], allowed_errors=[1], printout=lambda data, it: ([ data.dump_general(quantities=['Sigma_imp_iw', 'G_imp_iw'], suffix='-current'), data.dump_solvers(suffix='-current') ] if ((it + 1) % print_current == 0) else None)), generic_action( name="selfenergy", main=lambda data: dca_mains.selfenergy(data), mixers=[], cautionaries=[], allowed_errors=[], printout=lambda data, it: (data.dump_general(quantities=['SigmaR_iw', 'SigmaK_iw'], suffix='-current') if ((it + 1) % print_current == 0) else None)) ] if mix_Sigma: actions[3].mixers.append( mixer(mixed_quantity=lambda: dt.SigmaK_iw, rules=rules, func=mixer.mix_block_gf, initialize=True)) monitors = [ monitor(monitored_quantity=lambda: dt.ns['00'], h5key='n_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.mus['00'], h5key='mu_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.SigmaR_iw['00'].data[ dt.nw / 2, 0, 0].imag, h5key='ImSigma00_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.SigmaR_iw['00'].data[ dt.nw / 2, 0, 0].real, h5key='ReSigma00_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.GR_iw['00'].data[dt.nw / 2, 0, 0].imag, h5key='ImG00_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.GR_iw['00'].data[dt.nw / 2, 0, 0].real, h5key='ReG00_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.err, h5key='err_vs_it', archive_name=dt.archive_name) ] #, # monitor( monitored_quantity = lambda: actions[3].errs[0], # h5key = 'sign_err_vs_it', # archive_name = dt.archive_name) ] convergers = [ converger(monitored_quantity=lambda: dt.GR_iw, accuracy=accuracy, struct=fermionic_struct, archive_name=dt.archive_name, h5key='diffs_GR'), converger(monitored_quantity=lambda: dt.SigmaR_iw, accuracy=accuracy, struct=fermionic_struct, archive_name=dt.archive_name, h5key='diffs_SigmaR') ] dmft = generic_loop(name="DCA", actions=actions, convergers=convergers, monitors=monitors) if (counter == 0): #do the initial guess only once! if initial_guess_archive_name != '': if mpi.is_master_node(): print "constructing dt from initial guess in a file: ", initial_guess_archive_name, "suffix: ", suffix dt.construct_from_file( initial_guess_archive_name, suffix) #make sure it is the right dca_scheme if dt.beta != beta: dt.change_beta(beta, n_iw) else: if not fixed_n: dt.set_mu(mutilde) else: dt.set_mu(U / 2.0) for C in dt.impurity_struct.keys(): for l in dt.impurity_struct[ C]: #just the local components (but on each site!) dt.Sigma_imp_iw[C][l, l] << U / 2.0 for K, sig in dt.SigmaK_iw: sig[0, 0] << U / 2.0 dt.dump_general(quantities=['SigmaK_iw', 'Sigma_imp_iw'], suffix='-initial') if (counter == 0) and do_dmft_first: assert False, "not implemented" #run dca!------------- dt.dump_parameters() dt.dump_non_interacting() err = dmft.run(dt, max_its=max_its, min_its=min_its, max_it_err_is_allowed=7, print_final=True, print_current=1) if mpi.is_master_node(): cmd = 'mv %s %s' % (filename, filename.replace("result", "dca")) print cmd os.system(cmd) if (err == 2): print "Cautionary error!!! exiting..." solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) break if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() counter += 1 if not (solver_data_package is None): solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) return dt, monitors, convergers
def dos_partial(self,broadening=0.01): """calculates the orbitally-resolved DOS""" assert hasattr(self,"Sigma_imp"), "Set Sigma First!!" #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all'] #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data, thingstoread=thingstoread) retval = self.read_par_proj_input_from_hdf() if not retval: return retval if self.symm_op: self.Symm_par = Symmetry(self.hdf_file,subgroup=self.symm_par_data) mu = self.chemical_potential gf_struct_proj = [ [ (al, range(self.shells[i][3])) for al in self.block_names[self.SO] ] for i in xrange(self.n_shells) ] Gproj = [BlockGf(name_block_generator = [ (a,GfReFreq(indices = al, mesh = self.Sigma_imp[0].mesh)) for a,al in gf_struct_proj[ish] ], make_copies = False ) for ish in xrange(self.n_shells)] for ish in range(self.n_shells): Gproj[ish].zero() Msh = [x for x in self.Sigma_imp[0].mesh] n_om = len(Msh) DOS = {} for bn in self.block_names[self.SO]: DOS[bn] = numpy.zeros([n_om],numpy.float_) DOSproj = [ {} for ish in range(self.n_shells) ] DOSproj_orb = [ {} for ish in range(self.n_shells) ] for ish in range(self.n_shells): for bn in self.block_names[self.SO]: dl = self.shells[ish][3] DOSproj[ish][bn] = numpy.zeros([n_om],numpy.float_) DOSproj_orb[ish][bn] = numpy.zeros([n_om,dl,dl],numpy.float_) ikarray=numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): S = self.lattice_gf_realfreq(ik=ik,mu=mu,broadening=broadening) S *= self.bz_weights[ik] # non-projected DOS for iom in range(n_om): for sig,gf in S: DOS[sig][iom] += gf.data[iom,:,:].imag.trace()/(-3.1415926535) #projected DOS: for ish in xrange(self.n_shells): tmp = Gproj[ish].copy() for ir in xrange(self.n_parproj[ish]): for sig,gf in tmp: tmp[sig] <<= self.downfold_pc(ik,ir,ish,sig,S[sig],gf) Gproj[ish] += tmp # collect data from mpi: for sig in DOS: DOS[sig] = mpi.all_reduce(mpi.world,DOS[sig],lambda x,y : x+y) for ish in xrange(self.n_shells): Gproj[ish] <<= mpi.all_reduce(mpi.world,Gproj[ish],lambda x,y : x+y) mpi.barrier() if (self.symm_op!=0): Gproj = self.Symm_par.symmetrize(Gproj) # rotation to local coord. system: if (self.use_rotations): for ish in xrange(self.n_shells): for sig,gf in Gproj[ish]: Gproj[ish][sig] <<= self.rotloc_all(ish,gf,direction='toLocal') for ish in range(self.n_shells): for sig,gf in Gproj[ish]: for iom in range(n_om): DOSproj[ish][sig][iom] += gf.data[iom,:,:].imag.trace()/(-3.1415926535) DOSproj_orb[ish][sig][:,:,:] += gf.data[:,:,:].imag / (-3.1415926535) if (mpi.is_master_node()): # output to files for bn in self.block_names[self.SO]: f=open('./DOScorr%s.dat'%bn, 'w') for i in range(n_om): f.write("%s %s\n"%(Msh[i],DOS[bn][i])) f.close() # partial for ish in range(self.n_shells): f=open('DOScorr%s_proj%s.dat'%(bn,ish),'w') for i in range(n_om): f.write("%s %s\n"%(Msh[i],DOSproj[ish][bn][i])) f.close() for i in range(self.shells[ish][3]): for j in range(i,self.shells[ish][3]): Fname = './DOScorr'+bn+'_proj'+str(ish)+'_'+str(i)+'_'+str(j)+'.dat' f=open(Fname,'w') for iom in range(n_om): f.write("%s %s\n"%(Msh[iom],DOSproj_orb[ish][bn][iom,i,j])) f.close()
def dos_partial(self, broadening=0.01): """calculates the orbitally-resolved DOS""" assert hasattr(self, "Sigma_imp"), "Set Sigma First!!" #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all'] #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data, thingstoread=thingstoread) retval = self.read_par_proj_input_from_hdf() if not retval: return retval if self.symm_op: self.Symm_par = Symmetry(self.hdf_file, subgroup=self.symm_par_data) mu = self.chemical_potential gf_struct_proj = [[(al, range(self.shells[i][3])) for al in self.block_names[self.SO]] for i in xrange(self.n_shells)] Gproj = [ BlockGf(name_block_generator=[ (a, GfReFreq(indices=al, mesh=self.Sigma_imp[0].mesh)) for a, al in gf_struct_proj[ish] ], make_copies=False) for ish in xrange(self.n_shells) ] for ish in range(self.n_shells): Gproj[ish].zero() Msh = [x for x in self.Sigma_imp[0].mesh] n_om = len(Msh) DOS = {} for bn in self.block_names[self.SO]: DOS[bn] = numpy.zeros([n_om], numpy.float_) DOSproj = [{} for ish in range(self.n_shells)] DOSproj_orb = [{} for ish in range(self.n_shells)] for ish in range(self.n_shells): for bn in self.block_names[self.SO]: dl = self.shells[ish][3] DOSproj[ish][bn] = numpy.zeros([n_om], numpy.float_) DOSproj_orb[ish][bn] = numpy.zeros([n_om, dl, dl], numpy.float_) ikarray = numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): S = self.lattice_gf_realfreq(ik=ik, mu=mu, broadening=broadening) S *= self.bz_weights[ik] # non-projected DOS for iom in range(n_om): for sig, gf in S: DOS[sig][iom] += gf.data[iom, :, :].imag.trace() / ( -3.1415926535) #projected DOS: for ish in xrange(self.n_shells): tmp = Gproj[ish].copy() for ir in xrange(self.n_parproj[ish]): for sig, gf in tmp: tmp[sig] <<= self.downfold_pc(ik, ir, ish, sig, S[sig], gf) Gproj[ish] += tmp # collect data from mpi: for sig in DOS: DOS[sig] = mpi.all_reduce(mpi.world, DOS[sig], lambda x, y: x + y) for ish in xrange(self.n_shells): Gproj[ish] <<= mpi.all_reduce(mpi.world, Gproj[ish], lambda x, y: x + y) mpi.barrier() if (self.symm_op != 0): Gproj = self.Symm_par.symmetrize(Gproj) # rotation to local coord. system: if (self.use_rotations): for ish in xrange(self.n_shells): for sig, gf in Gproj[ish]: Gproj[ish][sig] <<= self.rotloc_all(ish, gf, direction='toLocal') for ish in range(self.n_shells): for sig, gf in Gproj[ish]: for iom in range(n_om): DOSproj[ish][sig][iom] += gf.data[ iom, :, :].imag.trace() / (-3.1415926535) DOSproj_orb[ish][sig][:, :, :] += gf.data[:, :, :].imag / ( -3.1415926535) if (mpi.is_master_node()): # output to files for bn in self.block_names[self.SO]: f = open('./DOScorr%s.dat' % bn, 'w') for i in range(n_om): f.write("%s %s\n" % (Msh[i], DOS[bn][i])) f.close() # partial for ish in range(self.n_shells): f = open('DOScorr%s_proj%s.dat' % (bn, ish), 'w') for i in range(n_om): f.write("%s %s\n" % (Msh[i], DOSproj[ish][bn][i])) f.close() for i in range(self.shells[ish][3]): for j in range(i, self.shells[ish][3]): Fname = './DOScorr' + bn + '_proj' + str( ish) + '_' + str(i) + '_' + str(j) + '.dat' f = open(Fname, 'w') for iom in range(n_om): f.write("%s %s\n" % (Msh[iom], DOSproj_orb[ish][bn][iom, i, j])) f.close()
def partial_charges(self,beta=40): """Calculates the orbitally-resolved density matrix for all the orbitals considered in the input. The theta-projectors are used, hence case.parproj data is necessary""" #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all'] #retval = self.read_input_from_HDF(SubGrp=self.par_proj_data,thingstoread=thingstoread) retval = self.read_par_proj_input_from_hdf() if not retval: return retval if self.symm_op: self.Symm_par = Symmetry(self.hdf_file,subgroup=self.symm_par_data) # Density matrix in the window bln = self.block_names[self.SO] ntoi = self.names_to_ind[self.SO] self.dens_mat_window = [ [numpy.zeros([self.shells[ish][3],self.shells[ish][3]],numpy.complex_) for ish in range(self.n_shells)] for isp in range(len(bln)) ] # init the density matrix mu = self.chemical_potential GFStruct_proj = [ [ (al, range(self.shells[i][3])) for al in bln ] for i in xrange(self.n_shells) ] if hasattr(self,"Sigma_imp"): Gproj = [BlockGf(name_block_generator = [ (a,GfImFreq(indices = al, mesh = self.Sigma_imp[0].mesh)) for a,al in GFStruct_proj[ish] ], make_copies = False) for ish in xrange(self.n_shells)] beta = self.Sigma_imp[0].mesh.beta else: Gproj = [BlockGf(name_block_generator = [ (a,GfImFreq(indices = al, beta = beta)) for a,al in GFStruct_proj[ish] ], make_copies = False) for ish in xrange(self.n_shells)] for ish in xrange(self.n_shells): Gproj[ish].zero() ikarray=numpy.array(range(self.n_k)) #print mpi.rank, mpi.slice_array(ikarray) #print "K-Sum starts on node",mpi.rank," at ",datetime.now() for ik in mpi.slice_array(ikarray): #print mpi.rank, ik, datetime.now() S = self.lattice_gf_matsubara(ik=ik,mu=mu,beta=beta) S *= self.bz_weights[ik] for ish in xrange(self.n_shells): tmp = Gproj[ish].copy() for ir in xrange(self.n_parproj[ish]): for sig,gf in tmp: tmp[sig] <<= self.downfold_pc(ik,ir,ish,sig,S[sig],gf) Gproj[ish] += tmp #print "K-Sum done on node",mpi.rank," at ",datetime.now() #collect data from mpi: for ish in xrange(self.n_shells): Gproj[ish] <<= mpi.all_reduce(mpi.world,Gproj[ish],lambda x,y : x+y) mpi.barrier() #print "Data collected on node",mpi.rank," at ",datetime.now() # Symmetrisation: if (self.symm_op!=0): Gproj = self.Symm_par.symmetrize(Gproj) #print "Symmetrisation done on node",mpi.rank," at ",datetime.now() for ish in xrange(self.n_shells): # Rotation to local: if (self.use_rotations): for sig,gf in Gproj[ish]: Gproj[ish][sig] <<= self.rotloc_all(ish,gf,direction='toLocal') isp = 0 for sig,gf in Gproj[ish]: #dmg.append(Gproj[ish].density()[sig]) self.dens_mat_window[isp][ish] = Gproj[ish].density()[sig] isp+=1 # add Density matrices to get the total: dens_mat = [ [ self.dens_mat_below[ntoi[bln[isp]]][ish]+self.dens_mat_window[isp][ish] for ish in range(self.n_shells)] for isp in range(len(bln)) ] return dens_mat
def nested_calculation(clusters, nested_struct_archive_name=None, flexible_Gweiss=False, sign=-1, sign_up_to=2, use_Gweiss_causal_cautionary=False, use_G_proj=False, mix_G_proj=False, G_proj_mixing_rules=[[0, 0.0]], Us=[1.0], Ts=[0.125], ns=[0.5], fixed_n=True, mutildes=[0.0], dispersion=lambda kx, ky: epsilonk_square(kx, ky, 0.25), ph_symmetry=True, use_cumulant=False, n_ks=[24], n_k_automatic=False, n_k_rules=[[0.06, 32], [0.03, 48], [0.005, 64], [0.00, 96]], w_cutoff=20.0, min_its=5, max_its=25, mix_Sigma=False, rules=[[0, 0.5], [6, 0.2], [12, 0.65]], do_dmft_first=False, use_cthyb=False, alpha=0.5, delta=0.1, automatic_alpha_and_delta=False, n_cycles=10000000, max_time_rules=[[1, 5 * 60], [2, 20 * 60], [4, 80 * 60], [8, 200 * 60], [16, 400 * 60]], time_rules_automatic=False, exponent=0.7, overall_prefactor=1.0, no_timing=False, accuracy=1e-4, solver_data_package=None, print_current=1, insulating_initial=False, initial_guess_archive_name='', suffix=''): if mpi.is_master_node(): print "WELCOME TO %snested calculation!" % ("cumul_" if use_cumulant else "") if n_k_automatic: print "n_k automatic!!!" if len(n_ks) == 0 and n_k_automatic: n_ks = [0] if use_cthyb: solver_class = solvers.cthyb else: solver_class = solvers.ctint fermionic_struct = {'up': [0]} if mpi.is_master_node(): print "nested structure: " if not (nested_struct_archive_name is None): try: nested_scheme = nested_struct.from_file(nested_struct_archive_name) if mpi.is_master_node(): print "nested structure loaded from file", nested_struct_archive_name except: nested_scheme = nested_struct(clusters) nested_scheme.print_to_file(nested_struct_archive_name) if mpi.is_master_node(): print "nested structure printed to file", nested_struct_archive_name else: nested_scheme = nested_struct(clusters) if mpi.is_master_node(): print nested_scheme.get_tex() impurity_struct = nested_scheme.get_impurity_struct() if not time_rules_automatic: max_times = {} for C in impurity_struct: for r in max_time_rules: if r[0] <= len(impurity_struct[C]): max_times[C] = r[1] if mpi.is_master_node(): print "max_times from rules: ", max_times beta = 1.0 / Ts[0] n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ", n_iw if not n_k_automatic: n_k = n_ks[0] print "n_k = ", n_k else: n_k = n_k_from_rules(Ts[0], n_k_rules) #if mpi.is_master_node(): print "n_k automatic!!!" dt = nested_data(n_iw=n_iw, n_k=n_k, beta=beta, impurity_struct=impurity_struct, fermionic_struct=fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file") if use_cumulant: dt.__class__ = cumul_nested_data dt.promote() if fixed_n: ps = itertools.product(n_ks, ns, Us, Ts) else: ps = itertools.product(n_ks, mutildes, Us, Ts) counter = 0 old_nk = n_k old_beta = beta for p in ps: #name stuff to avoid confusion nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules)) if fixed_n: n = p[1] else: mutilde = p[1] n = None U = p[2] T = p[3] beta = 1.0 / T if nk != old_nk and (not n_k_automatic): dt.change_ks(IBZ.k_grid(nk)) if beta != old_beta: n_iw = int(((w_cutoff * beta) / math.pi - 1.0) / 2.0) if n_k_automatic: nk = n_k_from_rules(T, n_k_rules) if nk != old_nk: dt.change_ks(IBZ.k_grid(nk)) dt.change_beta(beta, n_iw) old_beta = beta old_nk = nk nested_scheme.set_nk(nk) #don't forget this part filename = "result" if len(n_ks) > 1 and (not n_k_automatic): filename += ".nk%s" % nk if len(ns) > 1 and fixed_n: filename += ".n%s" % n if len(mutildes) > 1 and not fixed_n: filename += ".mutilde%s" % mutilde if len(Us) > 1: filename += ".U%s" % U if len(Ts) > 1: filename += ".T%.4f" % T filename += ".h5" dt.archive_name = filename if mpi.is_master_node(): if fixed_n: print "Working: U: %s T %s n: %s n_k: %s n_iw: %s" % (U, n, T, nk, n_iw) else: print "Working: U: %s T %s mutilde: %s n_k: %s n_iw: %s" % ( U, mutilde, T, nk, n_iw) if mpi.is_master_node(): print "about to fill dispersion. ph-symmetry: ", ph_symmetry for key in dt.fermionic_struct.keys(): for kxi in range(dt.n_k): for kyi in range(dt.n_k): dt.epsilonk[key][kxi, kyi] = dispersion(dt.ks[kxi], dt.ks[kyi]) if not use_cumulant: prepare = prepare_nested else: prepare = prepare_cumul_nested if flexible_Gweiss: prepare(dt, nested_scheme, solver_class, flexible_Gweiss, sign, sign_up_to) else: prepare(dt, nested_scheme, solver_class, use_G_proj=use_G_proj) solver_class.initialize_solvers(dt, solver_data_package) max_times = {} if no_timing: for C in dt.impurity_struct.keys(): max_times[C] = -1 if mpi.is_master_node(): print "no_timing! solvers will run until they perform all the mc steps", max_times if time_rules_automatic and (not no_timing): for C in dt.impurity_struct.keys(): Nc = len(dt.impurity_struct[C]) pref = ((dt.beta / 8.0) * U * Nc)**exponent #**1.2 print C print "Nc: ", Nc, print "U: ", U, print "beta: ", dt.beta, print "pref: ", pref max_times[C] = int(overall_prefactor * pref * 5 * 60) if mpi.is_master_node(): print "max times automatic: ", max_times identical_pairs_Sigma = nested_scheme.get_identical_pairs() identical_pairs_G = nested_scheme.get_identical_pairs_for_G() identical_pairs_G_ai = nested_scheme.get_identical_pairs_for_G( across_imps=True) actions = [ generic_action(name="lattice", main=lambda data: nested_mains.lattice( data, n=n, ph_symmetry=ph_symmetry, accepted_mu_range=[-2.0, 2.0]), mixers=[], cautionaries=[], allowed_errors=[], printout=lambda data, it: ([ data.dump_general(quantities=['Gkw', 'Gijw'] + (['G_proj_iw'] if use_G_proj else []), suffix='-current'), data.dump_scalar(suffix='-current') ] if ((it + 1) % print_current == 0) else None)), generic_action( name="pre_impurity", main=lambda data: nested_mains.pre_impurity(data), mixers=[], cautionaries=([ lambda data, it: ph_symmetric_Gweiss_causal_cautionary( data, ntau=5000) ] if use_Gweiss_causal_cautionary else []), allowed_errors=([0] if use_Gweiss_causal_cautionary else []), printout=lambda data, it: ( (data.dump_general(quantities=[ 'Gweiss_iw_unfit', 'Gweiss_iw', 'Delta_iw', 'Delta_iw_fit', 'Delta_tau', 'Delta_tau_fit' ], suffix='-%s' % it)) if use_Gweiss_causal_cautionary else (data.dump_general( quantities=['Gweiss_iw'], suffix='-current')))), generic_action( name="impurity", main=(lambda data: nested_mains.impurity( data, U, symmetrize_quantities=True, alpha=alpha, delta=delta, automatic_alpha_and_delta=automatic_alpha_and_delta, n_cycles=n_cycles, max_times=max_times, solver_data_package=solver_data_package)) if (not use_cthyb) else (lambda data: nested_mains.impurity_cthyb( data, U, symmetrize_quantities=True, n_cycles=n_cycles, max_times=max_times, solver_data_package=solver_data_package)), mixers=[], cautionaries=[ lambda data, it: local_nan_cautionary(data, data.impurity_struct, Qs=['Sigma_imp_iw'], raise_exception=True ), lambda data, it: (symmetric_G_and_self_energy_on_impurity( data.G_imp_iw, data.Sigma_imp_iw, data.solvers, identical_pairs_Sigma, identical_pairs_G, across_imps=True, identical_pairs_G_ai=identical_pairs_G_ai) if it >= 0 else symmetrize_cluster_impurity( data.Sigma_imp_iw, identical_pairs_Sigma)) ], allowed_errors=[1], printout=lambda data, it: ([ data.dump_general(quantities=['Sigma_imp_iw', 'G_imp_iw'], suffix='-current'), data.dump_solvers(suffix='-current') ] if ((it + 1) % print_current == 0) else None)), generic_action( name="selfenergy", main=lambda data: nested_mains.selfenergy(data), mixers=[], cautionaries=[ lambda data, it: nonloc_sign_cautionary(data.Sigmakw['up'], desired_sign=-1, clip_off=False, real_or_imag='imag' ) ], allowed_errors=[0], printout=lambda data, it: (data.dump_general(quantities=['Sigmakw', 'Sigmaijw'], suffix='-current') if ((it + 1) % print_current == 0) else None)) ] if use_cumulant: del actions[3] actions.append( generic_action( name="cumulant", main=lambda data: cumul_nested_mains.cumulant(data), mixers=[], cautionaries=[ lambda data, it: nonloc_sign_cautionary( data.gkw['up'], desired_sign=-1, clip_off=False, real_or_imag='imag') ], allowed_errors=[0], printout=lambda data, it: (data.dump_general(quantities=['gijw', 'gkw'], suffix='-current') if ((it + 1) % print_current == 0) else None))) monitors = [ monitor(monitored_quantity=lambda: dt.ns['up'], h5key='n_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.mus['up'], h5key='mu_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.err, h5key='err_vs_it', archive_name=dt.archive_name) ] #, # monitor( monitored_quantity = lambda: actions[3].errs[0], # h5key = 'sign_err_vs_it', # archive_name = dt.archive_name) ] if use_cumulant: monitors += [ monitor(monitored_quantity=lambda: dt.gijw['up'][dt.nw / 2, 0, 0].imag, h5key='Img_00_w0_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.gijw['up'][dt.nw / 2, 0, 0].real, h5key='Reg_00_iw0_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.gkw['up'][ dt.nw / 2, dt.n_k / 2, dt.n_k / 2].imag, h5key='Img_pipi_iw0_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.gkw['up'][ dt.nw / 2, dt.n_k / 2, dt.n_k / 2].real, h5key='Reg_pipi_iw0_vs_it', archive_name=dt.archive_name) ] else: monitors += [ monitor(monitored_quantity=lambda: dt.Sigma_loc_iw['up'].data[ dt.nw / 2, 0, 0].imag, h5key='ImSigma_loc_iw0_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.Sigma_loc_iw['up'].data[ dt.nw / 2, 0, 0].real, h5key='ReSigma_loc_iw0_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.Sigmakw['up'][ dt.nw / 2, dt.n_k / 2, dt.n_k / 2].imag, h5key='ImSigmakw_pipi_vs_it', archive_name=dt.archive_name), monitor(monitored_quantity=lambda: dt.Sigmakw['up'][ dt.nw / 2, dt.n_k / 2, dt.n_k / 2].real, h5key='ReSigmakw_pipi_vs_it', archive_name=dt.archive_name) ] convergers = [ converger(monitored_quantity=lambda: dt.G_loc_iw, accuracy=accuracy, struct=fermionic_struct, archive_name=dt.archive_name, h5key='diffs_G_loc'), converger(monitored_quantity=lambda: dt.Sigma_loc_iw, accuracy=accuracy, struct=fermionic_struct, archive_name=dt.archive_name, h5key='diffs_Sigma_loc'), converger(monitored_quantity=lambda: dt.G_imp_iw, accuracy=accuracy, struct=impurity_struct, archive_name=dt.archive_name, h5key='diffs_G_imp'), converger(monitored_quantity=lambda: dt.Gweiss_iw, accuracy=accuracy, struct=impurity_struct, archive_name=dt.archive_name, h5key='diffs_Gweiss') ] max_dist = 3 for i in range(max_dist + 1): for j in range(0, i + 1): convergers.append( converger(monitored_quantity=lambda i=i, j=j: dt.Gijw['up'] [:, i, j], accuracy=accuracy, func=converger.check_numpy_array, archive_name=dt.archive_name, h5key='diffs_G_%s%s' % (i, j))) dmft = generic_loop(name="nested-cluster DMFT", actions=actions, convergers=convergers, monitors=monitors) if (counter == 0): #do the initial guess only once! if initial_guess_archive_name != '': if mpi.is_master_node(): print "constructing dt from initial guess in a file: ", initial_guess_archive_name, "suffix: ", suffix old_epsilonk = dt.epsilonk dt.construct_from_file(initial_guess_archive_name, suffix) if dt.beta != beta: dt.change_beta(beta, n_iw) if dt.n_k != nk: dt.change_ks(IBZ.k_grid(nk)) if mpi.is_master_node(): print "putting back the old Jq and epsilonk" dt.epsilonk = old_epsilonk else: if not fixed_n: dt.mus['up'] = mutilde else: dt.mus['up'] = U / 2.0 if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus[ 'up'] #this is not necessary at the moment, but may become for C in dt.impurity_struct.keys(): for l in dt.impurity_struct[ C]: #just the local components (but on each site!) dt.Sigma_imp_iw[C].data[:, l, l] = U / 2.0 - int( insulating_initial) * 1j / numpy.array(dt.ws) if not use_cumulant: for key in fermionic_struct.keys(): dt.Sigmakw[key][:, :, :] = U / 2.0 numpy.transpose(dt.Sigmakw[key])[:] -= int( insulating_initial) * 1j / numpy.array(dt.ws) else: for key in fermionic_struct.keys(): numpy.transpose(dt.gkw[key])[:] = numpy.array( dt.iws[:])**(-1.0) if not use_cumulant: dt.dump_general(quantities=['Sigmakw', 'Sigma_imp_iw'], suffix='-initial') else: dt.dump_general(quantities=['gkw'], suffix='-initial') if (counter == 0) and do_dmft_first: assert False, "this part of code needs to be adjusted" #do one short run of dmft before starting nested if mpi.is_master_node(): print "================= 20 iterations of DMFT!!!! =================" #save the old stuff old_impurity_struct = dt.impurity_struct old_name = dmft.name #dmft_scheme dmft_scheme = nested_scheme([cluster(0, 0, 1, 1)]) dmft_scheme.set_nk(dt.n_k) dt.impurity_struct = dmft_scheme.get_impurity_struct() prepare_nested(dt, dmft_scheme, solvers.ctint) dmft.name = "dmft" #run dmft dmft.run(dt, max_its=20, min_its=15, max_it_err_is_allowed=7, print_final=True, print_current=10000) #move the result if mpi.is_master_node(): cmd = 'mv %s %s' % (filename, filename.replace( "result", "dmft")) print cmd os.system(cmd) #put everything back the way it was dmft.name = old_name dt.impurity_struct = old_impurity_struct prepare(dt, nested_scheme, solver_class) #run nested!------------- if mix_Sigma: actions[3].mixers.extend([ mixer(mixed_quantity=lambda: (dt.Sigmakw if (not use_cumulant) else dt.gkw), rules=rules, func=mixer.mix_lattice_gf, initialize=True) ]) actions[2].mixers.extend([ mixer(mixed_quantity=lambda: dt.Sigma_imp_iw, rules=rules, func=mixer.mix_block_gf, initialize=True) ]) if mix_G_proj: actions[0].mixers.append( mixer(mixed_quantity=lambda: dt.G_proj_iw, rules=G_proj_mixing_rules, func=mixer.mix_block_gf, initialize=True)) dt.dump_parameters() dt.dump_non_interacting() err = dmft.run(dt, max_its=max_its, min_its=min_its, max_it_err_is_allowed=7, print_final=True, print_current=1) if mpi.is_master_node(): if use_cumulant: print "calculating Sigma" dt.get_Sigmakw() dt.get_Sigma_loc() dt.dump_general(['Sigmakw', 'Sigma_loc_iw'], suffix='-final') cmd = 'mv %s %s' % (filename, filename.replace("result", "nested")) print cmd os.system(cmd) if (err == 2): print "Cautionary error!!! exiting..." solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) break if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() counter += 1 if not (solver_data_package is None): solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) return dt, monitors, convergers
def run_dmft_loops(self, n_dmft_loops = 1): """runs the DMFT calculation""" clp = p = CleanLoopParameters(self.get_parameters()) report = Reporter(**clp) report('Parameters:', clp) scheme = Scheme(**clp) dmft = DMFTObjects(**clp) raw_dmft = DMFTObjects(**clp) g_0_c_iw, g_c_iw, sigma_c_iw, dmu = dmft.get_dmft_objs() # ref, ref, ref, value report('Initializing...') if clp['nambu']: transf = NambuTransformation(**clp) scheme.set_pretransf(transf.pretransformation(), transf.pretransformation_inverse()) raw_transf = NambuTransformation(**clp) else: transf = ClustersiteTransformation(g_loc = scheme.g_local(sigma_c_iw, dmu), **clp) clp.update({'g_transf_struct': transf.get_g_struct()}) raw_transf = ClustersiteTransformation(**clp) transf.set_hamiltonian(**clp) report('Transformation ready') report('New basis:', transf.get_g_struct()) impurity = Solver(beta = clp['beta'], gf_struct = dict(transf.get_g_struct()), n_tau = clp['n_tau'], n_iw = clp['n_iw'], n_l = clp['n_legendre']) impurity.Delta_tau.name = '$\\tilde{\\Delta}_c$' rnames = random_generator_names_list() report('H = ', transf.hamiltonian) report('Impurity solver ready') report('') for loop_nr in range(self.next_loop(), self.next_loop() + n_dmft_loops): report('DMFT-loop nr. %s'%loop_nr) if mpi.is_master_node(): duration = time() report('Calculating dmu...') dmft.find_dmu(scheme, **clp) g_0_c_iw, g_c_iw, sigma_c_iw, dmu = dmft.get_dmft_objs() report('dmu = %s'%dmu) report('Calculating local Greenfunction...') g_c_iw << scheme.g_local(sigma_c_iw, dmu) g_c_iw << addExtField(g_c_iw, p['ext_field']) if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(g_c_iw, p['archive'][0:-3] + 'Gchecksym' + str(loop_nr) + '.pdf') report('Calculating Weiss-field...') g_0_c_iw << inverse(inverse(g_c_iw) + sigma_c_iw) dmft.make_g_0_iw_with_delta_tau_real() report('Changing basis...') transf.set_dmft_objs(*dmft.get_dmft_objs()) if mpi.is_master_node() and p['verbosity'] > 1: checktransf_plot(transf.get_g_iw(), p['archive'][0:-3] + 'Gchecktransf' + str(loop_nr) + '.pdf') checktransf_plot(g_0_c_iw, p['archive'][0:-3] + 'Gweisscheck' + str(loop_nr) + '.pdf') checksym_plot(inverse(transf.g_0_iw), p['archive'][0:-3] + 'invGweisscheckconst' + str(loop_nr) + '.pdf') #checksym_plot(inverse(transf.get_g_iw()), p['archive'][0:-3] + 'invGsymcheckconst' + str(loop_nr) + '.pdf') if not clp['random_name']: clp.update({'random_name': rnames[int((loop_nr + mpi.rank) % len(rnames))]}) # TODO move if not clp['random_seed']: clp.update({'random_seed': 862379 * mpi.rank + 12563 * self.next_loop()}) impurity.G0_iw << transf.get_g_0_iw() report('Solving impurity problem...') mpi.barrier() impurity.solve(h_int = transf.get_hamiltonian(), **clp.get_cthyb_parameters()) if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(inverse(impurity.G0_iw), p['archive'][0:-3] + 'invGweisscheckconstsolver' + str(loop_nr) + '.pdf') report('Postprocessing measurements...') if clp['measure_g_l']: for ind, g in transf.get_g_iw(): g << LegendreToMatsubara(impurity.G_l[ind]) else: for ind, g in transf.get_g_iw(): g.set_from_fourier(impurity.G_tau[ind]) raw_transf.set_dmft_objs(transf.get_g_0_iw(), transf.get_g_iw(), inverse(transf.get_g_0_iw()) - inverse(transf.get_g_iw())) if clp['measure_g_tau'] and clp['fit_tail']: for ind, g in transf.get_g_iw(): for tind in transf.get_g_struct(): if tind[0] == ind: block_inds = tind[1] fixed_moments = TailGf(len(block_inds), len(block_inds), 1, 1) fixed_moments[1] = identity(len(block_inds)) g.fit_tail(fixed_moments, 3, clp['tail_start'], clp['n_iw'] - 1) if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(inverse(transf.get_g_iw()), p['archive'][0:-3] + 'invGsymcheckconstsolver' + str(loop_nr) + '.pdf') report('Backtransforming...') transf.set_sigma_iw(inverse(transf.get_g_0_iw()) - inverse(transf.get_g_iw())) dmft.set_dmft_objs(*transf.get_backtransformed_dmft_objs()) dmft.set_dmu(dmu) raw_dmft.set_dmft_objs(*raw_transf.get_backtransformed_dmft_objs()) raw_dmft.set_dmu(dmu) if clp['mix']: dmft.mix() if clp['impose_paramagnetism']: dmft.paramagnetic() if clp['impose_afm']: dmft.afm() if clp['site_symmetries']: dmft.site_symmetric(clp['site_symmetries']) density = scheme.apply_pretransf_inv(dmft.get_g_iw(), True).total_density() report('Saving results...') if mpi.is_master_node(): a = HDFArchive(p['archive'], 'a') if not a.is_group('results'): a.create_group('results') a_r = a['results'] a_r.create_group(str(loop_nr)) a_l = a_r[str(loop_nr)] a_l['g_c_iw'] = dmft.get_g_iw() a_l['g_c_iw_raw'] = raw_dmft.get_g_iw() a_l['g_transf_iw'] = transf.get_g_iw() a_l['g_transf_iw_raw'] = raw_transf.get_g_iw() a_l['sigma_c_iw'] = dmft.get_sigma_iw() a_l['sigma_c_iw_raw'] = raw_dmft.get_sigma_iw() a_l['sigma_transf_iw'] = transf.get_sigma_iw() a_l['sigma_transf_iw_raw'] = raw_transf.get_sigma_iw() a_l['g_0_c_iw'] = dmft.get_g_0_iw() a_l['g_0_c_iw_raw'] = raw_dmft.get_g_0_iw() a_l['g_0_transf_iw'] = transf.get_g_0_iw() a_l['g_0_transf_iw_raw'] = raw_transf.get_g_0_iw() a_l['dmu'] = dmft.get_dmu() a_l['density'] = density a_l['loop_time'] = {'seconds': time() - duration, 'hours': (time() - duration)/3600., 'days': (time() - duration)/3600./24.} a_l['n_cpu'] = mpi.size a_l['cdmft_code_version'] = CDmft._version clp_dict = dict() clp_dict.update(clp) a_l['parameters'] = clp_dict a_l['triqs_code_version'] = version a_l['delta_transf_tau'] = impurity.Delta_tau if clp['measure_g_l']: a_l['g_transf_l'] = impurity.G_l if clp['measure_g_tau']: a_l['g_transf_tau'] = impurity.G_tau a_l['sign'] = impurity.average_sign if clp['measure_density_matrix']: a_l['density_matrix'] = impurity.density_matrix a_l['g_atomic_tau'] = impurity.atomic_gf a_l['h_loc_diagonalization'] = impurity.h_loc_diagonalization if a_r.is_data('n_dmft_loops'): a_r['n_dmft_loops'] += 1 else: a_r['n_dmft_loops'] = 1 del a_l, a_r, a report('Loop done') report('') mpi.barrier()
def solve_lattice_bse(g_wk, gamma_wnn, tail_corr_nwf=None): r""" Compute the generalized lattice susceptibility :math:`\chi_{abcd}(\omega, \mathbf{k})` using the Bethe-Salpeter equation (BSE). Parameters ---------- g_wk : Single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`. gamma_wnn : Local particle-hole vertex function :math:`\Gamma_{abcd}(\omega, \nu, \nu')` tail_corr_nwf : Number of fermionic freqiencies to use in the tail correction of the sum over fermionic frequencies. Returns ------- chi0_wk : Generalized lattice susceptibility :math:`\chi_{abcd}(\omega, \mathbf{k})` """ fmesh_g = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] bmesh = gamma_wnn.mesh.components[0] fmesh = gamma_wnn.mesh.components[1] nk = len(kmesh) nw = (len(bmesh) + 1) / 2 nwf = len(fmesh) / 2 nwf_g = len(fmesh_g) / 2 if mpi.is_master_node(): print tprf_banner(), "\n" print 'Lattcie BSE with local vertex approximation.\n' print 'nk =', nk print 'nw =', nw print 'nwf =', nwf print 'nwf_g =', nwf_g print 'tail_corr_nwf =', tail_corr_nwf print if tail_corr_nwf is None: tail_corr_nwf = nwf mpi.report('--> chi0_wnk_tail_corr') chi0_wnk_tail_corr = get_chi0_wnk(g_wk, nw=nw, nwf=tail_corr_nwf) mpi.report('--> trace chi0_wnk_tail_corr (WARNING! NO TAIL FIT. FIXME!)') chi0_wk_tail_corr = chi0q_sum_nu_tail_corr_PH(chi0_wnk_tail_corr) #chi0_wk_tail_corr = chi0q_sum_nu(chi0_wnk_tail_corr) mpi.barrier() mpi.report('B1 ' + str(chi0_wk_tail_corr[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) mpi.barrier() mpi.report('--> chi0_wnk_tail_corr to chi0_wnk') if tail_corr_nwf != nwf: mpi.report('--> fixed_fermionic_window_python_wnk') chi0_wnk = fixed_fermionic_window_python_wnk(chi0_wnk_tail_corr, nwf=nwf) else: chi0_wnk = chi0_wnk_tail_corr.copy() del chi0_wnk_tail_corr mpi.barrier() mpi.report('C ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) mpi.barrier() mpi.report('--> trace chi0_wnk') chi0_wk = chi0q_sum_nu(chi0_wnk) mpi.barrier() mpi.report('D ' + str(chi0_wk[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) mpi.barrier() dchi_wk = chi0_wk_tail_corr - chi0_wk chi0_kw = Gf(mesh=MeshProduct(kmesh, bmesh), target_shape=chi0_wk_tail_corr.target_shape) chi0_kw.data[:] = chi0_wk_tail_corr.data.swapaxes(0, 1) del chi0_wk del chi0_wk_tail_corr assert (chi0_wnk.mesh.components[0] == bmesh) assert (chi0_wnk.mesh.components[1] == fmesh) assert (chi0_wnk.mesh.components[2] == kmesh) # -- Lattice BSE calc with built in trace mpi.report('--> chi_kw from BSE') #mpi.report('DEBUG BSE INACTIVE'*72) chi_kw = chiq_sum_nu_from_chi0q_and_gamma_PH(chi0_wnk, gamma_wnn) #chi_kw = chi0_kw.copy() mpi.barrier() mpi.report('--> chi_kw from BSE (done)') del chi0_wnk mpi.report('--> chi_kw tail corrected (using chi0_wnk)') for k in kmesh: chi_kw[ k, :] += dchi_wk[:, k] # -- account for high freq of chi_0 (better than nothing) del dchi_wk mpi.report('--> solve_lattice_bse, done.') return chi_kw, chi0_kw
def __call__ (self, Sigma, mu=0, eta=0, field=None, epsilon_hat=None, result=None, selected_blocks=()): """ - Computes: result <- \[ \sum_k (\omega + \mu - field - t(k) - Sigma(k,\omega)) \] if result is None, it returns a new GF with the results. otherwise, result must be a GF, in which the calculation is done, and which is then returned. (this allows chain calculation: SK(mu = mu,Sigma = Sigma, result = G).total_density() which computes the sumK into G, and returns the density of G. - Sigma can be a X, or a function k-> X or a function k,eps ->X where: - k is expected to be a 1d-numpy array of size self.dim of float, containing the k vector in the basis of the RBZ (i.e. -0.5< k_i <0.5) - eps is t(k) - X is anything such that X[BlockName] can be added/subtracted to a GFBloc for BlockName in selected_blocks. e.g. X can be a BlockGf(with at least the selected_blocks), or a dictionnary Blockname -> array if the array has the same dimension as the GF blocks (for example to add a static Sigma). - field: Any k independant object to be added to the GF - epsilon_hat: a function of eps_k returning a matrix, the dimensions of Sigma - selected_blocks: The calculation is done with the SAME t(k) for all blocks. If this list is not None only the blocks in this list are calculated. e.g. G and Sigma have block indices 'up' and 'down'. if selected_blocks ==None: 'up' and 'down' are calculated if selected_blocks == ['up']: only 'up' is calculated. 'down' is 0. """ assert selected_blocks == (), "selected_blocks not supported for now" #S = Sigma.view_selected_blocks(selected_blocks) if selected_blocks else Sigma #Gres = result if result else Sigma.copy() #G = Gres.view_selected_blocks(selected_blocks) if selected_blocks else Gres # check Sigma # case 1) Sigma is a BlockGf if isinstance(Sigma, BlockGf): model = Sigma Sigma_fnt = False # case 2) Sigma is a function returning a BlockGf else: assert callable(Sigma), "If Sigma is not a BlockGf it must be a function" Sigma_Nargs = len(inspect.getargspec(Sigma)[0]) assert Sigma_Nargs <= 2, "Sigma must be a function of k or of k and epsilon" if Sigma_Nargs == 1: model = Sigma(self.bz_points[0]) elif Sigma_Nargs == 2: model = Sigma(self.bz_points[0], self.hopping[0]) Sigma_fnt = True G = result if result else model.copy() assert isinstance(G,BlockGf), "G must be a BlockGf" # check input assert self.orthogonal_basis, "Local_G: must be orthogonal. non ortho cases not checked." assert len(list(set([g.N1 for i,g in G]))) == 1 assert self.bz_weights.shape[0] == self.n_kpts(), "Internal Error" no = list(set([g.N1 for i,g in G]))[0] # Initialize G.zero() tmp,tmp2 = G.copy(),G.copy() mupat = mu * numpy.identity(no, numpy.complex_) tmp << iOmega_n if field != None: tmp -= field if not Sigma_fnt: tmp -= Sigma # substract Sigma once for all # Loop on k points... for w, k, eps_k in izip(*[mpi.slice_array(A) for A in [self.bz_weights, self.bz_points, self.hopping]]): eps_hat = epsilon_hat(eps_k) if epsilon_hat else eps_k tmp2 << tmp tmp2 -= tmp2.n_blocks * [eps_hat - mupat] if Sigma_fnt: if Sigma_Nargs == 1: tmp2 -= Sigma(k) elif Sigma_Nargs == 2: tmp2 -= Sigma(k,eps_k) tmp2.invert() tmp2 *= w G += tmp2 G << mpi.all_reduce(mpi.world,G,lambda x,y: x+y) mpi.barrier() return G
def run_all(vasp_pid): """ """ mpi.report(" Waiting for VASP lock to appear...") while not is_vasp_lock_present(): time.sleep(1) vasp_running = True while vasp_running: if debug: print bcolors.RED + "rank %s"%(mpi.rank) + bcolors.ENDC mpi.report(" Waiting for VASP lock to disappear...") mpi.barrier() while is_vasp_lock_present(): time.sleep(1) # if debug: print bcolors.YELLOW + " waiting: rank %s"%(mpi.rank) + bcolors.ENDC if not is_vasp_running(vasp_pid): mpi.report(" VASP stopped") vasp_running = False break if debug: print bcolors.MAGENTA + "rank %s"%(mpi.rank) + bcolors.ENDC err = 0 exc = None try: if debug: print bcolors.BLUE + "plovasp: rank %s"%(mpi.rank) + bcolors.ENDC if mpi.is_master_node(): plovasp.generate_and_output_as_text('plo.cfg', vasp_dir='./') # Read energy from OSZICAR dft_energy = get_dft_energy() except Exception, exc: err = 1 err = mpi.bcast(err) if err: if mpi.is_master_node(): raise exc else: raise SystemExit(1) mpi.barrier() try: if debug: print bcolors.GREEN + "rank %s"%(mpi.rank) + bcolors.ENDC corr_energy, dft_dc = dmft_cycle() except: if mpi.is_master_node(): print " master forwarding the exception..." raise else: print " rank %i exiting..."%(mpi.rank) raise SystemExit(1) mpi.barrier() if mpi.is_master_node(): total_energy = dft_energy + corr_energy - dft_dc print print "="*80 print " Total energy: ", total_energy print " DFT energy: ", dft_energy print " Corr. energy: ", corr_energy print " DFT DC: ", dft_dc print "="*80 print if mpi.is_master_node() and vasp_running: open('./vasp.lock', 'a').close()
def run( self, data, calculation_name='', total_debug=False, n_loops_max=100, n_loops_min=5, print_local=1, print_impurity_input=1, print_non_local=1, print_three_leg=1, print_impurity_output=1, skip_self_energy_on_first_iteration=False, #1 every iteration, 2 every second, -2 never (except for final) mix_after_selfenergy=False, last_iteration_err_is_allowed=15): for mixer in (self.mixers + self.imp_mixers): mixer.get_initial() for conv in self.convergers: conv.reset() for monitor in self.monitors: monitor.reset() if not (self.cautionary is None): self.cautionary.reset() if mpi.is_master_node(): data.dump_parameters(suffix='') data.dump_non_interacting(suffix='') converged = False failed = False for loop_index in range(n_loops_max): if mpi.is_master_node(): print "---------------------------- loop_index: ", loop_index, "/", n_loops_max, "---------------------------------" times = [] times.append((time(), "selfenergy")) if loop_index != 0 or not skip_self_energy_on_first_iteration: self.selfenergy(data=data) times.append((time(), "mixing 1")) if mix_after_selfenergy: for mixer in self.mixers: mixer.mix(loop_index) times.append((time(), "cautionary")) if not (self.cautionary is None): data.err = self.cautionary.check_and_fix(data) if data.err and (loop_index > last_iteration_err_is_allowed): failed = True times.append((time(), "lattice")) self.lattice(data=data) times.append((time(), "pre_impurity")) self.pre_impurity(data=data) times.append((time(), "dump_impurity_input")) if mpi.is_master_node() and ((loop_index + 1) % print_impurity_input == 0): data.dump_impurity_input(suffix='-%s' % loop_index) times.append((time(), "impurity")) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() self.impurity(data=data) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() times.append((time(), "dump_impurity_output and mix impurity")) if mpi.is_master_node(): if (loop_index + 1) % print_local == 0: data.dump_solver(suffix='-%s' % loop_index) for mixer in self.imp_mixers: mixer.mix(loop_index) times.append((time(), "post_impurity")) self.post_impurity(data=data) times.append((time(), "convergers")) c = True for conv in self.convergers: if not conv.check(): c = False converged = c #here we are checking that all have converged, not that at least one has converged times.append((time(), "mixing 2")) if not converged and not mix_after_selfenergy: for mixer in self.mixers: mixer.mix(loop_index) times.append((time(), "monitors")) for monitor in self.monitors: monitor.monitor() times.append((time(), "dumping")) if mpi.is_master_node(): data.dump_errors(suffix='-%s' % loop_index) data.dump_scalar(suffix='-%s' % loop_index) if (loop_index + 1) % print_local == 0: data.dump_local(suffix='-%s' % loop_index) if (loop_index + 1) % print_three_leg == 0: data.dump_three_leg(suffix='-%s' % loop_index) if (loop_index + 1) % print_non_local == 0: data.dump_non_local(suffix='-%s' % loop_index) A = HDFArchive(data.archive_name) A['max_index'] = loop_index del A if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if (mpi.rank == 0 or mpi.rank == 1) and total_debug: #total debug option archive_name = 'full_data' if calculation_name != '': archive_name += '_%s' % calculation_name archive_name += '.rank%s' % (mpi.rank) print "about to dump all data in ", archive_name data.dump_all(suffix='-%s' % loop_index, archive_name=archive_name) times.append((time(), "")) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if mpi.is_master_node(): self.print_timings(times) if (converged and loop_index > n_loops_min) or failed: break if not (self.after_it_is_done is None): self.after_it_is_done( data ) #notice that if we don't say data=data we can pass a method of data for after_it_is_done, such that here self=data if mpi.is_master_node(): data.dump_all(suffix='-final') if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if converged: return 0 else: if failed: return 2 #probably hitting AFM else: return 1 #maximum number of loops reached
def __call__ (self, Sigma, mu=0, eta=0, field=None, epsilon_hat=None, result=None, selected_blocks=()): """ - Computes: result <- \[ \sum_k (\omega + \mu - field - t(k) - Sigma(k,\omega)) \] if result is None, it returns a new GF with the results. otherwise, result must be a GF, in which the calculation is done, and which is then returned. (this allows chain calculation: SK(mu = mu,Sigma = Sigma, result = G).total_density() which computes the sumK into G, and returns the density of G. - Sigma can be a X, or a function k-> X or a function k,eps ->X where: - k is expected to be a 1d-numpy array of size self.dim of float, containing the k vector in the basis of the RBZ (i.e. -0.5< k_i <0.5) - eps is t(k) - X is anything such that X[BlockName] can be added/subtracted to a GFBloc for BlockName in selected_blocks. e.g. X can be a BlockGf(with at least the selected_blocks), or a dictionnary Blockname -> array if the array has the same dimension as the GF blocks (for example to add a static Sigma). - field: Any k independant object to be added to the GF - epsilon_hat: a function of eps_k returning a matrix, the dimensions of Sigma - selected_blocks: The calculation is done with the SAME t(k) for all blocks. If this list is not None only the blocks in this list are calculated. e.g. G and Sigma have block indices 'up' and 'down'. if selected_blocks ==None: 'up' and 'down' are calculated if selected_blocks == ['up']: only 'up' is calculated. 'down' is 0. """ assert selected_blocks == (), "selected_blocks not supported for now" #S = Sigma.view_selected_blocks(selected_blocks) if selected_blocks else Sigma #Gres = result if result else Sigma.copy() #G = Gres.view_selected_blocks(selected_blocks) if selected_blocks else Gres # check Sigma # case 1) Sigma is a BlockGf if isinstance(Sigma, BlockGf): model = Sigma Sigma_fnt = False # case 2) Sigma is a function returning a BlockGf else: assert callable(Sigma), "If Sigma is not a BlockGf it must be a function" Sigma_Nargs = len(inspect.getargspec(Sigma)[0]) assert Sigma_Nargs <= 2, "Sigma must be a function of k or of k and epsilon" if Sigma_Nargs == 1: model = Sigma(self.bz_points[0]) elif Sigma_Nargs == 2: model = Sigma(self.bz_points[0], self.hopping[0]) Sigma_fnt = True G = result if result else model.copy() assert isinstance(G,BlockGf), "G must be a BlockGf" # check input assert self.orthogonal_basis, "Local_G: must be orthogonal. non ortho cases not checked." assert len(list(set([g.target_shape[0] for i,g in G]))) == 1 assert self.bz_weights.shape[0] == self.n_kpts(), "Internal Error" no = list(set([g.target_shape[0] for i,g in G]))[0] # Initialize G.zero() tmp,tmp2 = G.copy(),G.copy() mupat = mu * numpy.identity(no, numpy.complex_) tmp << iOmega_n if field != None: tmp -= field if not Sigma_fnt: tmp -= Sigma # substract Sigma once for all # Loop on k points... for w, k, eps_k in izip(*[mpi.slice_array(A) for A in [self.bz_weights, self.bz_points, self.hopping]]): eps_hat = epsilon_hat(eps_k) if epsilon_hat else eps_k tmp2 << tmp tmp2 -= tmp2.n_blocks * [eps_hat - mupat] if Sigma_fnt: if Sigma_Nargs == 1: tmp2 -= Sigma(k) elif Sigma_Nargs == 2: tmp2 -= Sigma(k,eps_k) tmp2.invert() tmp2 *= w G += tmp2 G << mpi.all_reduce(mpi.world,G,lambda x,y: x+y) mpi.barrier() return G
def run(data, no_fermionic_bath, symmetrize_quantities=True, trilex=False, n_w_f=2, n_w_b=2, n_cycles=20000, max_time=10 * 60, hartree_shift=0.0, solver_data_package=None): #------- run solver try: if solver_data_package is None: solver_data_package = {} solver_data_package['solve_parameters'] = {} #solver_data_package['solve_parameters']['h_int'] = lambda: data.U_inf * n('up',0) * n('down',0) solver_data_package['solve_parameters']['U_inf'] = data.U_inf solver_data_package['solve_parameters']['hartree_shift'] = [ hartree_shift, hartree_shift ] solver_data_package['solve_parameters']['n_cycles'] = n_cycles solver_data_package['solve_parameters']['length_cycle'] = 1000 solver_data_package['solve_parameters'][ 'n_warmup_cycles'] = 1000 solver_data_package['solve_parameters']['max_time'] = max_time solver_data_package['solve_parameters']['measure_nn'] = True solver_data_package['solve_parameters']['measure_nnw'] = True solver_data_package['solve_parameters'][ 'measure_chipmt'] = True solver_data_package['solve_parameters']['measure_gt'] = False solver_data_package['solve_parameters']['measure_ft'] = False solver_data_package['solve_parameters'][ 'measure_gw'] = not no_fermionic_bath solver_data_package['solve_parameters'][ 'measure_fw'] = not no_fermionic_bath solver_data_package['solve_parameters']['measure_g2w'] = trilex solver_data_package['solve_parameters']['measure_f2w'] = False solver_data_package['solve_parameters']['measure_hist'] = True solver_data_package['solve_parameters'][ 'measure_hist_composite'] = True solver_data_package['solve_parameters']['measure_nnt'] = False solver_data_package['solve_parameters'][ 'move_group_into_spin_segment'] = not no_fermionic_bath solver_data_package['solve_parameters'][ 'move_split_spin_segment'] = not no_fermionic_bath solver_data_package['solve_parameters'][ 'move_swap_empty_lines'] = True solver_data_package['solve_parameters'][ 'move_move'] = not no_fermionic_bath solver_data_package['solve_parameters'][ 'move_insert_segment'] = not no_fermionic_bath solver_data_package['solve_parameters'][ 'move_remove_segment'] = not no_fermionic_bath solver_data_package['solve_parameters']['n_w_f_vertex'] = n_w_f solver_data_package['solve_parameters']['n_w_b_vertex'] = n_w_b solver_data_package['solve_parameters'][ 'keep_Jperp_negative'] = True print solver_data_package['solve_parameters'] solver_data_package['G0_iw'] = data.solver.G0_iw solver_data_package['D0_iw'] = data.solver.D0_iw solver_data_package['Jperp_iw'] = data.solver.Jperp_iw solver_data_package['construct|run|exit'] = 1 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast(solver_data_package) print "about to run " #data.solver.solve( **(solver_data_package['solve_parameters'] + ) data.solver.solve( h_int=solver_data_package['solve_parameters']['U_inf'] * n('up', 0) * n('down', 0), hartree_shift=solver_data_package['solve_parameters'] ['hartree_shift'], n_cycles=solver_data_package['solve_parameters'] ['n_cycles'], length_cycle=solver_data_package['solve_parameters'] ['length_cycle'], n_warmup_cycles=solver_data_package['solve_parameters'] ['n_warmup_cycles'], max_time=solver_data_package['solve_parameters'] ['max_time'], measure_nn=solver_data_package['solve_parameters'] ['measure_nn'], measure_nnw=solver_data_package['solve_parameters'] ['measure_nnw'], measure_chipmt=solver_data_package['solve_parameters'] ['measure_chipmt'], measure_gt=solver_data_package['solve_parameters'] ['measure_gt'], measure_ft=solver_data_package['solve_parameters'] ['measure_ft'], measure_gw=solver_data_package['solve_parameters'] ['measure_gw'], measure_fw=solver_data_package['solve_parameters'] ['measure_fw'], measure_g2w=solver_data_package['solve_parameters'] ['measure_g2w'], measure_f2w=solver_data_package['solve_parameters'] ['measure_f2w'], measure_hist=solver_data_package['solve_parameters'] ['measure_hist'], measure_hist_composite=solver_data_package[ 'solve_parameters']['measure_hist_composite'], measure_nnt=solver_data_package['solve_parameters'] ['measure_nnt'], move_group_into_spin_segment=solver_data_package[ 'solve_parameters']['move_group_into_spin_segment'], move_split_spin_segment=solver_data_package[ 'solve_parameters']['move_split_spin_segment'], move_swap_empty_lines=solver_data_package[ 'solve_parameters']['move_swap_empty_lines'], move_move=solver_data_package['solve_parameters'] ['move_move'], move_insert_segment=solver_data_package['solve_parameters'] ['move_insert_segment'], move_remove_segment=solver_data_package['solve_parameters'] ['move_remove_segment'], n_w_f_vertex=solver_data_package['solve_parameters'] ['n_w_f_vertex'], n_w_b_vertex=solver_data_package['solve_parameters'] ['n_w_b_vertex'], keep_Jperp_negative=solver_data_package['solve_parameters'] ['keep_Jperp_negative']) data.G_imp_iw << data.solver.G_iw get_Sigma_from_G_and_G0 = False for U in data.fermionic_struct.keys(): if numpy.any(numpy.isnan( data.G_imp_iw[U].data[:, 0, 0])) or numpy.any( numpy.isnan(data.solver.F_iw[U].data[:, 0, 0])): if numpy.any( numpy.isnan(data.G_imp_iw[U].data[:, 0, 0])): print "[Node", mpi.rank, "]", " nan in F_imp and G_imp!!! exiting to system..." if mpi.is_master_node(): data.dump_all(archive_name="black_box_nan", suffix='') cthyb.dump(data.solver, archive_name="black_box_nan", suffix='') if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size > 1): solver_data_package = mpi.bcast( solver_data_package) quit() else: print "[Node", mpi.rank, "]", " nan in F but not in G!! will be calculating Sigma from G and G0" get_Sigma_from_G_and_G0 = True if symmetrize_quantities: symmetrize_blockgf(data.G_imp_iw, data.fermionic_struct) symmetrize_blockgf(data.solver.F_iw, data.fermionic_struct) if not get_Sigma_from_G_and_G0: extract_Sigma_from_F_and_G( data.Sigma_imp_iw, data.solver.F_iw, data.G_imp_iw ) #!!!! this thing fails when the S S boson is not SU(2) symmetric else: extract_Sigma_from_G0_and_G(data.Sigma_imp_iw, data.solver.G0_iw, data.G_imp_iw) data.get_Sz( ) #moved these in impurity!!!!! maybe not the best idea data.get_chi_imp() except Exception as e: import traceback, os.path, sys top = traceback.extract_stack()[-1] if mpi.is_master_node(): data.dump_impurity_input('black_box', '') raise Exception( '%s, %s, %s \t %s ' % (type(e).__name__, os.path.basename(top[0]), top[1], e))
def pm_tUVJ_calculation( T, mutildes=[0.0], ts=[0.25], t_dispersion = epsilonk_square, Us = [1.0], decouple_U = False, Vs = [0.2], V_dispersion = None, Js = [0.05], J_dispersion = None, n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], use_cthyb=False, n_cycles=100000, max_time=10*60, initial_guess_archive_name = '', suffix=''): if mpi.is_master_node(): print "WELCOME TO PM tUVJ!" bosonic_struct = {'0': [0], 'z': [0]} fermionic_struct = {'up': [0], 'down': [0]} beta = 1.0/T n_iw = int(((20.0*beta)/math.pi-1.0)/2.0) n_tau = int(n_iw*pi) if (V_dispersion is None) and (J_dispersion is None): n_q = 1 else: n_q = 12 n_k = n_q #init solver if use_cthyb: solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) else: solver = SolverCore( beta = beta, gf_struct = fermionic_struct, n_iw = n_iw, n_tau_g0 = 10001, n_tau_dynamical_interactions = n_iw*4, n_iw_dynamical_interactions = n_iw, n_tau_nnt = n_iw*2+1, n_tau_g2t = 13, n_w_f_g2w = 6, n_w_b_g2w = 6, n_tau_M4t = 25, n_w_f_M4w = 12, n_w_b_M4w = 12 ) #init data, assign the solver to it dt = full_data( n_iw = n_iw, n_k = n_k, n_q = n_q, beta = beta, solver = solver, bosonic_struct = bosonic_struct, fermionic_struct = fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file" ) #init convergence and cautionary measures convergers = [ converger( monitored_quantity = dt.P_imp_iw, accuracy=1e-3, struct=bosonic_struct, archive_name=dt.archive_name, h5key = 'diffs_P_imp' ), converger( monitored_quantity = dt.G_imp_iw, accuracy=1e-3, struct=fermionic_struct, archive_name=dt.archive_name, h5key = 'diffs_G_imp' ) ] mixers = [ mixer( mixed_quantity = dt.P_imp_iw, rules=rules, func=mixer.mix_gf ), mixer( mixed_quantity = dt.Sigma_imp_iw, rules=rules, func=mixer.mix_gf) ] err = 0 #initial guess ps = itertools.product(mutildes,ts,Us,Vs,Js) counter = 0 for p in ps: #name stuff to avoid confusion mutilde = p[0] t = p[1] U = p[2] V = p[3] J = p[4] dt.archive_name="edmft.mutilde%s.t%s.U%s.V%s.J%s.T%s.h5"%(mutilde,t,U,V,J,T) for conv in convergers: conv.archive_name = dt.archive_name convergers[0].struct = copy.deepcopy(bosonic_struct) if J==0.0: del convergers[0].struct['z'] #no need to monitor quantities that are not involved in the calculation if V==0.0: del convergers[0].struct['0'] if not ((V_dispersion is None) and (J_dispersion is None)): #this is optional since we're using semi-analytical summation and evaluate chi_loc directly from P dt.fill_in_qs() if decouple_U: dt.fill_in_Jq( {'0': lambda kx,ky: V_dispersion(kx,ky,J=V)+U, 'z': partial(J_dispersion, J=J)} ) else: dt.fill_in_Jq( {'0': partial(V_dispersion, J=V), 'z': partial(J_dispersion, J=J)} ) dt.fill_in_ks() dt.fill_in_epsilonk(dict.fromkeys(['up','down'], partial(t_dispersion, t=t))) if mpi.is_master_node(): dt.dump_non_interacting() preset = edmft_tUVJ_pm(mutilde=mutilde, U=U, V=V, J=J) preset.cautionary.get_safe_values(dt.Jq, dt.bosonic_struct, n_q, n_q) if mpi.is_master_node(): print "U = ",U," V= ",V, "J= ",J," mutilde= ",mutilde print "cautionary safe values: ",preset.cautionary.safe_value impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, n_cycles=n_cycles, max_time=max_time ) dt.dump_solver = solvers.cthyb.dump if not use_cthyb: imp = partial( solvers.ctint.run, n_cycles=n_cycles) dt.dump_solver = solvers.ctint.dump #init the dmft_loop dmft = dmft_loop( cautionary = preset.cautionary, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = impurity, post_impurity = partial( preset.post_impurity ), selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, after_it_is_done = preset.after_it_is_done ) if counter==0: #do this only once! dt.mus['up'] = dt.mus['down'] = mutilde+U/2.0 #safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value['0']*0.8, P_imp=dt.P_imp_iw['0']) #safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value['z']*0.8, P_imp=dt.P_imp_iw['z']) dt.Sigma_imp_iw << U/2.0 #starting from half-filled hartree-fock self-energy dt.P_imp_iw << 0.0 if initial_guess_archive_name!='': dt.load_initial_guess_from_file(initial_guess_archive_name, suffix) #dt.load_initial_guess_from_file("/home/jvucicev/TRIQS/run/sc_scripts/Archive_Vdecoupling/edmft.mutilde0.0.t0.25.U3.0.V2.0.J0.0.T0.01.h5") mpi.barrier() #run dmft!------------- err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_non_loc=False) counter += 1 return err
def run(self): """ """ mpi.barrier() if mpi.size==1 : # single machine. Avoid the fork while not(self.finished()): n = self.next() if n!=None : self.treate(self.the_function(n),0) return # Code for multiprocessor machines RequestList,pid = [],0 # the pid of the child on the master node_running,node_stopped= mpi.size*[False],mpi.size*[False] if mpi.rank==0 : while not(self.finished()) or pid or [n for n in node_running if n] != [] : # Treat the request which have self.finished def keep_request(r) : #if not(mpi.test(r)) : return True #if r.message !=None : self.treate(*r.message) #node_running[r.status.source] = False T = r.test() if T is None : return True value = T[0] if value !=None : self.treate(*value) node_running[T[1].source] = False return False RequestList = filter(keep_request,RequestList) # send new calculation to the nodes or "stop" them for node in [ n for n in range(1,mpi.size) if not(node_running[n] or node_stopped[n]) ] : #open('tmp','a').write("master : comm to node %d %s\n"%(node,self.finished())) mpi.send(self.finished(),node) if not(self.finished()) : mpi.send(self.next(),node) # send the data for the computation node_running[node] = True RequestList.append(mpi.irecv(node)) #Post the receive else : node_stopped[node] = True # Look if the child process on the master has self.finished. if not(pid) or os.waitpid(pid,os.WNOHANG) : if pid : RR = cPickle.load(open("res_master",'r')) if RR != None : self.treate(*RR) if not(self.finished()) : pid=os.fork(); currently_calculated_by_master = self.next() if pid==0 : # we are on the child if currently_calculated_by_master : res = self.the_function(currently_calculated_by_master) else: res = None cPickle.dump((res,mpi.rank),open('res_master','w')) os._exit(0) # Cf python doc. Used for child only. else : pid=0 if (pid): time.sleep(self.SleepTime) # so that most of the time is for the actual calculation on the master else : # not master while not(mpi.recv(0)) : # master will first send a finished flag omega = mpi.recv(0) if omega ==None : res = None else : res = self.the_function(omega) mpi.send((res,mpi.rank),0) mpi.barrier()
def pm_hubbard_GW_calculation( T, mutildes=[0.0], ts=[0.25], t_dispersion = epsilonk_square, Us = [1.0], alpha=2.0/3.0, n_ks = [6, 36, 64], n_loops_min = 5, n_loops_max=25, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], trilex = False, use_cthyb=True, n_cycles=100000, max_time=10*60, initial_guess_archive_name = '', suffix=''): if mpi.is_master_node(): print "WELCOME TO PM hubbard GW calculation!" bosonic_struct = {'0': [0], '1': [0]} if alpha==2.0/3.0: del bosonic_struct['1'] if alpha==1.0/3.0: del bosonic_struct['0'] fermionic_struct = {'up': [0], 'down': [0]} beta = 1.0/T n_iw = int(((20.0*beta)/math.pi-1.0)/2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ",n_iw n_tau = int(n_iw*pi) n_q = n_ks[0] n_k = n_q #init solver if use_cthyb: solver = Solver( beta = beta, gf_struct = fermionic_struct, n_tau_k = n_tau, n_tau_g = 10000, n_tau_delta = 10000, n_tau_nn = 4*n_tau, n_w_b_nn = n_iw, n_w = n_iw ) else: solver = SolverCore( beta = beta, gf_struct = fermionic_struct, n_iw = n_iw, n_tau_g0 = 10001, n_tau_dynamical_interactions = n_iw*4, n_iw_dynamical_interactions = n_iw, n_tau_nnt = n_iw*2+1, n_tau_g2t = 13, n_w_f_g2w = 6, n_w_b_g2w = 6, n_tau_M4t = 25, n_w_f_M4w = 12, n_w_b_M4w = 12 ) #init data, assign the solver to it dt = GW_data( n_iw = n_iw, n_k = n_k, n_q = n_q, beta = beta, solver = solver, bosonic_struct = bosonic_struct, fermionic_struct = fermionic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file" ) if trilex: dt.__class__=trilex_data dt.promote(dt.n_iw/2, dt.n_iw/2) #init convergence and cautionary measures convergers = [ converger( monitored_quantity = dt.P_imp_iw, accuracy=1e-3, struct=bosonic_struct, archive_name=dt.archive_name, h5key = 'diffs_P_imp' ), converger( monitored_quantity = dt.G_imp_iw, accuracy=1e-3, struct=fermionic_struct, archive_name=dt.archive_name, h5key = 'diffs_G_imp' ) ] mixers = [ mixer( mixed_quantity = dt.P_imp_iw, rules=rules, func=mixer.mix_gf ), mixer( mixed_quantity = dt.Sigma_imp_iw, rules=rules, func=mixer.mix_gf) ] err = 0 #initial guess ps = itertools.product(mutildes,ts,Us,n_ks) counter = 0 for p in ps: #name stuff to avoid confusion mutilde = p[0] t = p[1] U = p[2] nk = p[3] dt.change_ks(IBZ.k_grid(nk)) if trilex: dt.archive_name="trilex.mutilde%s.t%s.U%s.alpha%s.T%s.nk%s.h5"%(mutilde,t,U,alpha,T,nk ) else: dt.archive_name="GW.mutilde%s.t%s.U%s.alpha%s.T%s.nk%s.h5"%(mutilde,t,U,alpha,T,nk) for conv in convergers: conv.archive_name = dt.archive_name Uch = (3.0*alpha-1.0)*U Usp = (alpha-2.0/3.0)*U vks = {'0': lambda kx,ky: Uch, '1': lambda kx,ky: Usp} if alpha==2.0/3.0: del vks['1'] if alpha==1.0/3.0: del vks['0'] dt.fill_in_Jq( vks ) dt.fill_in_epsilonk(dict.fromkeys(['up','down'], partial(t_dispersion, t=t))) if trilex: preset = trilex_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct) else: preset = GW_hubbard_pm(mutilde=mutilde, U=U, alpha=alpha, bosonic_struct=bosonic_struct) if mpi.is_master_node(): print "U = ",U," alpha= ",alpha, "Uch= ",Uch," Usp=",Usp," mutilde= ",mutilde #print "cautionary safe values: ",preset.cautionary.safe_value if trilex: n_w_f=dt.n_iw_f n_w_b=dt.n_iw_b else: n_w_f=2 n_w_b=2 impurity = partial( solvers.cthyb.run, no_fermionic_bath=False, trilex=trilex, n_w_f=n_w_f, n_w_b=n_w_b, n_cycles=n_cycles, max_time=max_time ) dt.dump_solver = solvers.cthyb.dump if not use_cthyb: imp = partial( solvers.ctint.run, n_cycles=n_cycles) dt.dump_solver = solvers.ctint.dump #init the dmft_loop dmft = dmft_loop( cautionary = preset.cautionary, lattice = preset.lattice, pre_impurity = preset.pre_impurity, impurity = impurity, post_impurity = partial( preset.post_impurity ), selfenergy = preset.selfenergy, convergers = convergers, mixers = mixers, after_it_is_done = preset.after_it_is_done ) #dt.get_G0kw( func = dict.fromkeys(['up', 'down'], dyson.scalar.G_from_w_mu_epsilon_and_Sigma) ) if counter==0: #do this only once! dt.mus['up'] = dt.mus['down'] = mutilde+U/2.0 dt.P_imp_iw << 0.0 #for A in bosonic_struct.keys(): # if preset.cautionary.safe_value[A] < 0.0: # safe_and_stupid_scalar_P_imp(safe_value = preset.cautionary.safe_value[A]*0.95, P_imp=dt.P_imp_iw[A]) dt.Sigma_imp_iw << U/2.0 + mutilde #making sure that in the first iteration the impurity problem is half-filled if initial_guess_archive_name!='': dt.load_initial_guess_from_file(initial_guess_archive_name, suffix) #dt.load_initial_guess_from_file("/home/jvucicev/TRIQS/run/sc_scripts/Archive_Vdecoupling/edmft.mutilde0.0.t0.25.U3.0.V2.0.J0.0.T0.01.h5") mpi.barrier() #run dmft!------------- err += dmft.run(dt, n_loops_max=n_loops_max, n_loops_min=n_loops_min, print_three_leg=1, print_non_local=1 ) counter += 1 return err
def calc_density_correction(self,filename = 'dens_mat.dat'): """ Calculates the density correction in order to feed it back to the DFT calculations.""" assert (type(filename)==StringType), "filename has to be a string!" ntoi = self.names_to_ind[self.SO] bln = self.block_names[self.SO] # Set up deltaN: deltaN = {} for ib in bln: deltaN[ib] = [ numpy.zeros( [self.n_orbitals[ik,ntoi[ib]],self.n_orbitals[ik,ntoi[ib]]], numpy.complex_) for ik in range(self.n_k)] ikarray=numpy.array(range(self.n_k)) dens = {} for ib in bln: dens[ib] = 0.0 for ik in mpi.slice_array(ikarray): S = self.lattice_gf_matsubara(ik=ik,mu=self.chemical_potential) for sig,g in S: deltaN[sig][ik] = S[sig].density() dens[sig] += self.bz_weights[ik] * S[sig].total_density() #put mpi Barrier: for sig in deltaN: for ik in range(self.n_k): deltaN[sig][ik] = mpi.all_reduce(mpi.world,deltaN[sig][ik],lambda x,y : x+y) dens[sig] = mpi.all_reduce(mpi.world,dens[sig],lambda x,y : x+y) mpi.barrier() # now save to file: if (mpi.is_master_node()): if (self.SP==0): f=open(filename,'w') else: f=open(filename+'up','w') f1=open(filename+'dn','w') # write chemical potential (in Rydberg): f.write("%.14f\n"%(self.chemical_potential/self.energy_unit)) if (self.SP!=0): f1.write("%.14f\n"%(self.chemical_potential/self.energy_unit)) # write beta in ryderg-1 f.write("%.14f\n"%(S.mesh.beta*self.energy_unit)) if (self.SP!=0): f1.write("%.14f\n"%(S.mesh.beta*self.energy_unit)) if (self.SP==0): for ik in range(self.n_k): f.write("%s\n"%self.n_orbitals[ik,0]) for inu in range(self.n_orbitals[ik,0]): for imu in range(self.n_orbitals[ik,0]): valre = (deltaN['up'][ik][inu,imu].real + deltaN['down'][ik][inu,imu].real) / 2.0 valim = (deltaN['up'][ik][inu,imu].imag + deltaN['down'][ik][inu,imu].imag) / 2.0 f.write("%.14f %.14f "%(valre,valim)) f.write("\n") f.write("\n") f.close() elif ((self.SP==1)and(self.SO==0)): for ik in range(self.n_k): f.write("%s\n"%self.n_orbitals[ik,0]) for inu in range(self.n_orbitals[ik,0]): for imu in range(self.n_orbitals[ik,0]): f.write("%.14f %.14f "%(deltaN['up'][ik][inu,imu].real,deltaN['up'][ik][inu,imu].imag)) f.write("\n") f.write("\n") f.close() for ik in range(self.n_k): f1.write("%s\n"%self.n_orbitals[ik,1]) for inu in range(self.n_orbitals[ik,1]): for imu in range(self.n_orbitals[ik,1]): f1.write("%.14f %.14f "%(deltaN['down'][ik][inu,imu].real,deltaN['down'][ik][inu,imu].imag)) f1.write("\n") f1.write("\n") f1.close() else: for ik in range(self.n_k): f.write("%s\n"%self.n_orbitals[ik,0]) for inu in range(self.n_orbitals[ik,0]): for imu in range(self.n_orbitals[ik,0]): f.write("%.14f %.14f "%(deltaN['ud'][ik][inu,imu].real,deltaN['ud'][ik][inu,imu].imag)) f.write("\n") f.write("\n") f.close() for ik in range(self.n_k): f1.write("%s\n"%self.n_orbitals[ik,0]) for inu in range(self.n_orbitals[ik,0]): for imu in range(self.n_orbitals[ik,0]): f1.write("%.14f %.14f "%(deltaN['ud'][ik][inu,imu].real,deltaN['ud'][ik][inu,imu].imag)) f1.write("\n") f1.write("\n") f1.close() return deltaN, dens
def get_chi0_wnk(g_wk, nw=1, nwf=None): fmesh = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] if nwf is None: nwf = len(fmesh) / 2 mpi.barrier() mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 1, 2)][0, 0])) n = np.sum(g_wk.data) / len(kmesh) mpi.report('n ' + str(n)) mpi.barrier() mpi.report('--> g_wr from g_wk') g_wr = fourier_wk_to_wr(g_wk) mpi.barrier() mpi.report('g_wr ' + str(g_wr[Idx(2), Idx(0, 1, 2)][0, 0])) n_r = np.sum(g_wr.data, axis=0)[0] mpi.report('n_r=0 ' + str(n_r[0, 0])) mpi.barrier() mpi.report('--> chi0_wnr from g_wr') chi0_wnr = chi0r_from_gr_PH(nw=nw, nnu=nwf, gr=g_wr) #mpi.report('--> chi0_wnr from g_wr (nompi)') #chi0_wnr_nompi = chi0r_from_gr_PH_nompi(nw=nw, nnu=nwf, gr=g_wr) del g_wr #abs_diff = np.abs(chi0_wnr.data - chi0_wnr_nompi.data) #mpi.report('shape = ' + str(abs_diff.shape)) #idx = np.argmax(abs_diff) #mpi.report('argmax = ' + str(idx)) #diff = np.max(abs_diff) #mpi.report('diff = %6.6f' % diff) #del chi0_wnr #chi0_wnr = chi0_wnr_nompi #exit() mpi.barrier() mpi.report('chi0_wnr ' + str(chi0_wnr[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0_r0 = np.sum(chi0_wnr[:, :, Idx(0, 0, 0)].data) mpi.report('chi0_r0 ' + str(chi0_r0)) mpi.barrier() mpi.report('--> chi0_wnk from chi0_wnr') chi0_wnk = chi0q_from_chi0r(chi0_wnr) del chi0_wnr mpi.barrier() mpi.report('chi0_wnk ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0 = np.sum(chi0_wnk.data) / len(kmesh) mpi.report('chi0 = ' + str(chi0)) mpi.barrier() #if mpi.is_master_node(): if False: from triqs_tprf.ParameterCollection import ParameterCollection p = ParameterCollection() p.g_wk = g_wk p.g_wr = g_wr p.chi0_wnr = chi0_wnr p.chi0_wnk = chi0_wnk print '--> Writing debug info for BSE' with HDFArchive('data_debug_bse.h5', 'w') as arch: arch['p'] = p mpi.barrier() return chi0_wnk
def simple_point_dens_mat(self): ntoi = self.names_to_ind[self.SO] bln = self.block_names[self.SO] MMat = [numpy.zeros( [self.n_orbitals[0,ntoi[bl]],self.n_orbitals[0,ntoi[bl]]], numpy.complex_) for bl in bln] dens_mat = [ {} for icrsh in xrange(self.n_corr_shells)] for icrsh in xrange(self.n_corr_shells): for bl in self.block_names[self.corr_shells[icrsh][4]]: dens_mat[icrsh][bl] = numpy.zeros([self.corr_shells[icrsh][3],self.corr_shells[icrsh][3]], numpy.complex_) ikarray=numpy.array(range(self.n_k)) for ik in mpi.slice_array(ikarray): unchangedsize = all( [ self.n_orbitals[ik,ntoi[bln[ib]]]==len(MMat[ib]) for ib in range(self.n_spin_blocks_gf[self.SO]) ] ) if (not unchangedsize): MMat = [numpy.zeros( [self.n_orbitals[ik,ntoi[bl]],self.n_orbitals[ik,ntoi[bl]]], numpy.complex_) for bl in bln] for ibl,bl in enumerate(bln): ind = ntoi[bl] for inu in range(self.n_orbitals[ik,ind]): if ( (self.hopping[ik,ind,inu,inu]-self.h_field*(1-2*ibl)) < 0.0): MMat[ibl][inu,inu] = 1.0 else: MMat[ibl][inu,inu] = 0.0 for icrsh in range(self.n_corr_shells): for ibn,bn in enumerate(self.block_names[self.corr_shells[icrsh][4]]): isp = self.names_to_ind[self.corr_shells[icrsh][4]][bn] dim = self.corr_shells[icrsh][3] n_orb = self.n_orbitals[ik,isp] #print ik, bn, isp dens_mat[icrsh][bn] += self.bz_weights[ik] * numpy.dot( numpy.dot(self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb],MMat[ibn]) , self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb].transpose().conjugate() ) # get data from nodes: for icrsh in range(self.n_corr_shells): for sig in dens_mat[icrsh]: dens_mat[icrsh][sig] = mpi.all_reduce(mpi.world,dens_mat[icrsh][sig],lambda x,y : x+y) mpi.barrier() if (self.symm_op!=0): dens_mat = self.Symm_corr.symmetrize(dens_mat) # Rotate to local coordinate system: if (self.use_rotations): for icrsh in xrange(self.n_corr_shells): for bn in dens_mat[icrsh]: if (self.rot_mat_time_inv[icrsh]==1): dens_mat[icrsh][bn] = dens_mat[icrsh][bn].conjugate() dens_mat[icrsh][bn] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),dens_mat[icrsh][bn]) , self.rot_mat[icrsh]) return dens_mat
def nested_edmft_calculation( clusters, nested_struct_archive_name = None, flexible_Gweiss=False, sign=-1, sign_up_to=2, use_Gweiss_causal_cautionary = False, freeze_Uweiss = False, no_lattice = False, Us = [1.0], decoupling = 'ising', decoupling_alpha = 0.5, Ts = [0.125], ns = [0.5], fixed_n = True, mutildes = [0.0], dispersion = lambda kx, ky: epsilonk_square(kx,ky, 0.25), ph_symmetry = True, n_ks = [64], n_k_automatic = False, n_k_rules = [[0.06, 32],[0.03, 48],[0.005, 64],[0.00, 96]], w_cutoff = 50.0, min_its = 5, max_its=25, mix_GWlatt = False, rules = [[0, 0.5], [6, 0.2], [12, 0.65]], mix_Uweiss = False, Uweiss_mix_rules = [[0, 0.5], [6, 0.2], [12, 0.65]], use_cthyb = False, alpha = 0.5, delta = 0.1, automatic_alpha_and_delta = False, n_cycles=10000000, max_time_rules= [ [1, 5*60], [2, 20*60], [4, 80*60], [8, 200*60], [16,400*60] ], time_rules_automatic=False, exponent = 0.7, overall_prefactor=4.0, no_timing = False, accuracy = 1e-4, solver_data_package = None, print_current = 1, insulating_initial = False, Wilson_bath_initial = False, bath_initial = False, selfenergy_initial = False, initial_guess_archive_name = '', suffix=''): if mpi.is_master_node(): print "WELCOME TO nested edmft calculation!" if n_k_automatic: print "n_k automatic!!!" if len(n_ks)==0 and n_k_automatic: n_ks=[0] if use_cthyb: assert False, "cthyb usage not implemented" solver_class = solvers.cthyb else: solver_class = solvers.ctint fermionic_struct = {'up': [0]} bosonic_struct = {'0': [0], '1': [0]} if decoupling=='ising': if decoupling_alpha==1.0: del bosonic_struct['1'] if decoupling_alpha==0.0: del bosonic_struct['0'] elif decoupling=='heisenberg': if decoupling_alpha==2.0/3.0: del bosonic_struct['1'] if decoupling_alpha==1.0/3.0: del bosonic_struct['0'] if mpi.is_master_node(): print "nested structure: " if not (nested_struct_archive_name is None): try: nested_scheme = nested_struct.from_file(nested_struct_archive_name) if mpi.is_master_node(): print "nested structure loaded from file",nested_struct_archive_name except: nested_scheme = nested_struct(clusters) nested_scheme.print_to_file(nested_struct_archive_name) if mpi.is_master_node(): print "nested structure printed to file",nested_struct_archive_name else: nested_scheme = nested_struct(clusters) if mpi.is_master_node(): print nested_scheme.get_tex() impurity_struct = nested_scheme.get_impurity_struct() if not time_rules_automatic: max_times = {} for C in impurity_struct: for r in max_time_rules: if r[0]<=len(impurity_struct[C]): max_times[C] = r[1] if mpi.is_master_node(): print "max_times from rules: ",max_times beta = 1.0/Ts[0] n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0) if mpi.is_master_node(): print "PM HUBBARD GW: n_iw: ",n_iw if not n_k_automatic: n_k = n_ks[0] print "n_k = ", n_k else: n_k = n_k_from_rules(Ts[0], n_k_rules) #if mpi.is_master_node(): print "n_k automatic!!!" dt = nested_edmft_data( n_iw = n_iw, n_k = n_k, beta = beta, impurity_struct = impurity_struct, fermionic_struct = fermionic_struct, bosonic_struct = bosonic_struct, archive_name="so_far_nothing_you_shouldnt_see_this_file" ) if fixed_n: ps = itertools.product(n_ks,ns,Us,Ts) else: ps = itertools.product(n_ks,mutildes,Us,Ts) counter = 0 old_nk = n_k old_beta = beta for p in ps: #name stuff to avoid confusion nk = (p[0] if (not n_k_automatic) else n_k_from_rules(T, n_k_rules) ) if fixed_n: n = p[1] else: mutilde = p[1] n = None U = p[2] T = p[3] beta = 1.0/T if nk!=old_nk and (not n_k_automatic): assert False, "changing n_k not implemented" dt.change_ks(IBZ.k_grid(nk)) if beta!=old_beta: assert False, "changing beta not implemented" n_iw = int(((w_cutoff*beta)/math.pi-1.0)/2.0) if n_k_automatic: nk = n_k_from_rules(T, n_k_rules) if nk != old_nk: dt.change_ks(IBZ.k_grid(nk)) dt.change_beta(beta, n_iw) old_beta = beta old_nk = nk nested_scheme.set_nk(nk) #don't forget this part filename = "result" if len(n_ks)>1 and (not n_k_automatic): filename += ".nk%s"%nk if len(ns)>1 and fixed_n: filename += ".n%s"%n if len(mutildes)>1 and not fixed_n: filename += ".mutilde%s"%mutilde if len(Us)>1: filename += ".U%s"%U if len(Ts)>1: filename += ".T%.4f"%T filename += ".h5" dt.archive_name = filename if mpi.is_master_node(): if fixed_n: print "Working: U: %s T %s n: %s n_k: %s n_iw: %s"%(U,n,T,nk,n_iw) else: print "Working: U: %s T %s mutilde: %s n_k: %s n_iw: %s"%(U,mutilde,T,nk,n_iw) if mpi.is_master_node(): print "about to fill dispersion. ph-symmetry: ",ph_symmetry for key in dt.fermionic_struct.keys(): for kxi in range(dt.n_k): for kyi in range(dt.n_k): dt.epsilonk[key][kxi,kyi] = dispersion(dt.ks[kxi], dt.ks[kyi]) if decoupling=='ising': for key in dt.bosonic_struct.keys(): if key=='0': dt.Jq[key][:,:]=decoupling_alpha*U if key=='1': dt.Jq[key][:,:]=(decoupling_alpha-1)*U elif decoupling=='heisenberg': if key=='0': dt.Jq[key][:,:]=(3.0*decoupling_alpha-1.0)*U if key=='1': dt.Jq[key][:,:]=(decoupling_alpha-2.0/3.0)*U else: assert False, "unknown decoupling scheme" prepare_nested_edmft( dt, nested_scheme, solver_class ) solver_class.initialize_solvers( dt, solver_data_package, bosonic_measures=True ) if no_timing: max_times = {} for C in dt.impurity_struct.keys(): max_times[C] = -1 if mpi.is_master_node(): print "no_timing! solvers will run until they perform all the mc steps",max_times if time_rules_automatic and (not no_timing): max_times = {} for C in dt.impurity_struct.keys(): Nc = len(dt.impurity_struct[C]) pref = ((dt.beta/8.0)*U*Nc)**exponent #**1.2 print C print "Nc: ",Nc, print "U: ", U, print "beta: ",dt.beta, print "pref: ",pref max_times[C] = int(overall_prefactor*pref*5*60) if mpi.is_master_node(): print "max times automatic: ",max_times identical_pairs_Sigma = nested_scheme.get_identical_pairs() identical_pairs_G = nested_scheme.get_identical_pairs_for_G() identical_pairs_G_ai = nested_scheme.get_identical_pairs_for_G(across_imps=True) def do_print(*args): for x in args: print x, print "" used_Cs = [] actions =[ generic_action( name = "lattice", main = ( (lambda data: nested_edmft_mains.lattice(data, n=n, ph_symmetry=ph_symmetry, accepted_mu_range=[-2.0,2.0])) if (not no_lattice) else (lambda data: [ data.copy_imp_to_latt(used_Cs[0]), do_print("just copying imp",used_Cs[0],"->latt, no_lattice! Gijw000:",data.Gijw['up'][0,0,0], [ "Wijnu_"+A+ "000:"+str(data.Wijnu['0'][0,0,0]) for A in data.Wijnu.keys()] ) ]) #TODO generalize for any size cluster ), mixers = [], cautionaries = [], allowed_errors = [], printout = lambda data, it: ( [data.dump_general( quantities = ['Gkw','Gijw','Wqnu','Wijnu'], suffix='-current' ), data.dump_scalar(suffix='-current') ] if ((it+1) % print_current==0) else None ) ), generic_action( name = "pre_impurity", main = lambda data: nested_edmft_mains.pre_impurity(data, freeze_Uweiss = freeze_Uweiss, Cs= used_Cs), mixers = [], cautionaries = [], allowed_errors = [], printout = lambda data, it: ( data.dump_general( quantities = ['Gweiss_iw','Uweiss_iw','Uweiss_dyn_iw'], suffix='-current' ) ) ), generic_action( name = "impurity", main = (lambda data: nested_mains.impurity(data, U, symmetrize_quantities = True, alpha=alpha, delta=delta, automatic_alpha_and_delta = automatic_alpha_and_delta, n_cycles=n_cycles, max_times = max_times, solver_data_package = solver_data_package, bosonic_measures=not freeze_Uweiss, Cs= used_Cs )) if (not use_cthyb) else (lambda data: nested_mains.impurity_cthyb(data, U, symmetrize_quantities = True, n_cycles=n_cycles, max_times = max_times, solver_data_package = solver_data_package )), mixers = [], cautionaries = [lambda data,it: local_nan_cautionary(data, data.impurity_struct, Qs = ['Sigma_imp_iw'], raise_exception = True), lambda data,it: ( symmetric_G_and_self_energy_on_impurity(data.G_imp_iw, data.Sigma_imp_iw, data.solvers, identical_pairs_Sigma, identical_pairs_G, across_imps=True, identical_pairs_G_ai=identical_pairs_G_ai ) if it>=10000 else symmetrize_cluster_impurity(data.Sigma_imp_iw, identical_pairs_Sigma) ) ], allowed_errors = [1], printout = lambda data, it: ( [ data.dump_general( quantities = ['Sigma_imp_iw','G_imp_iw'], suffix='-current' ), data.dump_solvers(suffix='-current') ] if ((it+1) % print_current==0) else None) ), generic_action( name = "post_impurity", main = lambda data: nested_edmft_mains.post_impurity(data, identical_pairs = identical_pairs_Sigma, Cs= used_Cs),#, homogeneous_pairs = identical_pairs_G), mixers = [], cautionaries = [], allowed_errors = [], printout = lambda data, it: (data.dump_general( quantities = ['chi_imp_iw','P_imp_iw','W_imp_iw'], suffix='-current' ) if ((it+1) % print_current==0) else None) ), generic_action( name = "selfenergy", main = lambda data: nested_edmft_mains.selfenergy(data), mixers = [], cautionaries = [lambda data,it: nonloc_sign_cautionary(data.Sigmakw['up'], desired_sign = -1, clip_off = False, real_or_imag = 'imag')], allowed_errors = [0], printout = lambda data, it: (data.dump_general( quantities = ['Sigmakw','Sigmaijw','Sigma_loc_iw','Pqnu','Pijnu','P_loc_iw'], suffix='-current' ) if ((it+1) % print_current==0) else None) ) ] monitors = [ monitor( monitored_quantity = lambda: dt.ns['up'], h5key = 'n_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.mus['up'], h5key = 'mu_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.err, h5key = 'err_vs_it', archive_name = dt.archive_name) ] monitors+= [ monitor( monitored_quantity = lambda: dt.Sigma_loc_iw['up'].data[dt.nw/2,0,0].imag, h5key = 'ImSigma_loc_iw0_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.Sigma_loc_iw['up'].data[dt.nw/2,0,0].real, h5key = 'ReSigma_loc_iw0_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.Sigmakw['up'][dt.nw/2, dt.n_k/2, dt.n_k/2].imag, h5key = 'ImSigmakw_pipi_vs_it', archive_name = dt.archive_name), monitor( monitored_quantity = lambda: dt.Sigmakw['up'][dt.nw/2, dt.n_k/2, dt.n_k/2].real, h5key = 'ReSigmakw_pipi_vs_it', archive_name = dt.archive_name)] convergers = [ converger( monitored_quantity = lambda: dt.G_loc_iw, accuracy=accuracy, struct=fermionic_struct, archive_name= dt.archive_name, h5key = 'diffs_G_loc' ), converger( monitored_quantity = lambda: dt.W_loc_iw, accuracy=accuracy, struct=bosonic_struct, archive_name= dt.archive_name, h5key = 'diffs_W_loc' ), converger( monitored_quantity = lambda: dt.P_loc_iw, accuracy=accuracy, struct=bosonic_struct, archive_name= dt.archive_name, h5key = 'diffs_P_loc' ), converger( monitored_quantity = lambda: dt.Sigma_loc_iw, accuracy=accuracy, struct=fermionic_struct, archive_name= dt.archive_name, h5key = 'diffs_Sigma_loc') ] max_dist = 3 for i in range(max_dist+1): for j in range(0,i+1): convergers.append( converger( monitored_quantity = lambda i=i, j=j: dt.Gijw['up'][:,i,j], accuracy=accuracy, func = converger.check_numpy_array, archive_name= dt.archive_name, h5key = 'diffs_G_%s%s'%(i,j) ) ) convergers.append( converger( monitored_quantity = lambda: dt.G_imp_iw, accuracy=accuracy, struct=impurity_struct, archive_name= dt.archive_name, h5key = 'diffs_G_imp' ) ) convergers.append( converger( monitored_quantity = lambda: dt.Gweiss_iw, accuracy=accuracy, struct=impurity_struct, archive_name= dt.archive_name, h5key = 'diffs_Gweiss' ) ) combo_imp_struct = {} for CA,Uw in dt.Uweiss_iw: combo_imp_struct[CA] = impurity_struct[C] convergers.append( converger( monitored_quantity = lambda: dt.Uweiss_iw, accuracy=accuracy, struct=combo_imp_struct, archive_name= dt.archive_name, h5key = 'diffs_Uweiss' ) ) dmft = generic_loop( name = "nested-cluster EDMFT", actions = actions, convergers = convergers, monitors = monitors ) start_from_action_index = 0 if freeze_Uweiss: if mpi.is_master_node(): print "Uweiss frozen! Equivalent to nested DMFT calculation" if (counter==0): #do the initial guess only once! if initial_guess_archive_name!='': if selfenergy_initial: start_from_action_index = 0 if mpi.is_master_node(): print "Taking Sigma from initial guess in:",initial_guess_archive_name, "suffix: ",suffix HDFA = HDFArchive(initial_guess_archive_name,'r') dt.Sigmakw = deepcopy(HDFA['Sigmakw%s'%suffix]) dt.Sigma_imp_iw << HDFA['Sigma_imp_iw%s'%suffix] dt.mus = HDFA['mus%s'%suffix] del HDFA dt.dump_general( quantities = ['Sigmakw','Sigma_imp_iw'], suffix='-initial' ) elif bath_initial: start_from_action_index = 2 if mpi.is_master_node(): print "Taking Gweiss from initial guess in:",initial_guess_archive_name, "suffix: ",suffix HDFA = HDFArchive(initial_guess_archive_name,'r') input_blocks = [C for C,gw in HDFA['Gweiss_iw%s'%suffix]] if set(input_blocks)!=set(impurity_struct.keys()): used_Cs[:]=input_blocks[:] print "WARNING: input block structure does not correspond to the nested scheme block structure. Running only the impurities in the input block set." for C,gw in HDFA['Gweiss_iw%s'%suffix]: dt.Gweiss_iw[C] << gw dt.mus = HDFA['mus%s'%suffix] for C in impurity_struct.keys(): #in any case fill Uweiss for P_imp calculation not to crash for A in bosonic_struct: print "dt.Jq[",A,"][0,0]:",dt.Jq[A][0,0] dt.Uweiss_iw[C+'|'+A] << dt.Jq[A][0,0] dt.Uweiss_dyn_iw[C+'|'+A] << 0.0 del HDFA dt.dump_general( quantities = ['Gweiss_iw','Uweiss_iw','Uweiss_dyn_iw'], suffix='-initial' ) else: if not fixed_n: dt.mus['up'] = mutilde else: dt.mus['up'] = U/2.0 if 'down' in dt.fermionic_struct.keys(): dt.mus['down'] = dt.mus['up'] #this is not necessary at the moment, but may become if Wilson_bath_initial: start_from_action_index = 2 if impurity_struct.keys()!=["1x1"]: assert False, "Wilson initializer inapplicable!" for A in bosonic_struct: print "dt.Jq[",A,"][0,0]:",dt.Jq[A][0,0] dt.Uweiss_iw['1x1|'+A] << dt.Jq[A][0,0] dt.Uweiss_dyn_iw['1x1|'+A] << 0.0 dt.Gweiss_iw['1x1'] << inverse(iOmega_n+U/2.0-Wilson(0.25)) dt.dump_general( quantities = ['Gweiss_iw','Uweiss_iw','Uweiss_dyn_iw'], suffix='-initial' ) else: for C in dt.impurity_struct.keys(): for l in dt.impurity_struct[C]: #just the local components (but on each site!) dt.Sigma_imp_iw[C].data[:,l,l] = U/2.0-int(insulating_initial)*1j/numpy.array(dt.ws) for A in bosonic_struct: CA = C+"|"+A dt.Uweiss_iw[CA] << dt.Jq[A][0,0] dt.Uweiss_dyn_iw[CA] << 0.0 dt.P_imp_iw[CA] << 0.0 for A in bosonic_struct: dt.Pqnu[A][:,:,:] = 0.0 dt.P_loc_iw[A]<< 0.0 dt.Pijnu[A][:,:,:]= 0.0 for key in fermionic_struct.keys(): dt.Sigmakw[key][:,:,:] = U/2.0 numpy.transpose(dt.Sigmakw[key])[:] -= int(insulating_initial)*1j/numpy.array(dt.ws) dt.dump_general( quantities = ['Sigmakw','Sigma_imp_iw'], suffix='-initial' ) #run nested!------------- if mix_GWlatt: actions[0].mixers.extend([ mixer( mixed_quantity = lambda: dt.Gijw, rules=rules, func=mixer.mix_lattice_gf, initialize = True ) ]) actions[0].mixers.extend([ mixer( mixed_quantity = lambda: dt.Wijnu, rules=rules, func=mixer.mix_lattice_gf, initialize = True ) ]) if mix_Uweiss: print "mixing Uweiss, rules:", Uweiss_mix_rules actions[1].mixers.extend([ mixer( mixed_quantity = lambda: dt.Uweiss_iw, rules=Uweiss_mix_rules, func=mixer.mix_block_gf, initialize = True ) ]) actions[1].mixers.extend([ mixer( mixed_quantity = lambda: dt.Uweiss_dyn_iw, rules=Uweiss_mix_rules, func=mixer.mix_block_gf, initialize = True ) ]) dt.dump_parameters() dt.dump_non_interacting() err = dmft.run( dt, max_its=max_its, min_its=min_its, max_it_err_is_allowed = 7, print_final=True, print_current = 1, start_from_action_index = start_from_action_index ) if mpi.is_master_node(): cmd = 'mv %s %s'%(filename, filename.replace("result", "nested_edmft")) print cmd os.system(cmd) if (err==2): print "Cautionary error!!! exiting..." solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package) break if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() counter += 1 if not (solver_data_package is None): solver_data_package['construct|run|exit'] = 2 if MASTER_SLAVE_ARCHITECTURE and (mpi.size>1): solver_data_package = mpi.bcast(solver_data_package) return dt, monitors, convergers
def run(self, data, calculation_name='', total_debug = False, n_loops_max=100, n_loops_min=5, print_local=1, print_impurity_input=1, print_non_local=1, print_three_leg=1, print_impurity_output=1, skip_self_energy_on_first_iteration=False, #1 every iteration, 2 every second, -2 never (except for final) mix_after_selfenergy = False, last_iteration_err_is_allowed = 15 ): for mixer in (self.mixers + self.imp_mixers): mixer.get_initial() for conv in self.convergers: conv.reset() for monitor in self.monitors: monitor.reset() if not (self.cautionary is None): self.cautionary.reset() if mpi.is_master_node(): data.dump_parameters(suffix='') data.dump_non_interacting(suffix='') converged = False failed = False for loop_index in range(n_loops_max): if mpi.is_master_node(): print "---------------------------- loop_index: ",loop_index,"/",n_loops_max,"---------------------------------" times = [] times.append((time(),"selfenergy")) if loop_index!=0 or not skip_self_energy_on_first_iteration: self.selfenergy(data=data) times.append((time(),"mixing 1")) if mix_after_selfenergy: for mixer in self.mixers: mixer.mix(loop_index) times.append((time(),"cautionary")) if not (self.cautionary is None): data.err = self.cautionary.check_and_fix(data) if data.err and (loop_index > last_iteration_err_is_allowed): failed = True times.append((time(),"lattice")) self.lattice(data=data) times.append((time(),"pre_impurity")) self.pre_impurity(data=data) times.append((time(),"dump_impurity_input")) if mpi.is_master_node() and ((loop_index + 1) % print_impurity_input==0): data.dump_impurity_input(suffix='-%s'%loop_index) times.append((time(),"impurity")) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() self.impurity(data=data) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() times.append((time(),"dump_impurity_output and mix impurity")) if mpi.is_master_node(): if (loop_index + 1) % print_local == 0: data.dump_solver(suffix='-%s'%loop_index) for mixer in self.imp_mixers: mixer.mix(loop_index) times.append((time(),"post_impurity")) self.post_impurity(data=data) times.append((time(),"convergers")) c = True for conv in self.convergers: if not conv.check(): c = False converged = c #here we are checking that all have converged, not that at least one has converged times.append((time(),"mixing 2")) if not converged and not mix_after_selfenergy: for mixer in self.mixers: mixer.mix(loop_index) times.append((time(),"monitors")) for monitor in self.monitors: monitor.monitor() times.append((time(),"dumping")) if mpi.is_master_node(): data.dump_errors(suffix='-%s'%loop_index) data.dump_scalar(suffix='-%s'%loop_index) if (loop_index + 1) % print_local == 0: data.dump_local(suffix='-%s'%loop_index) if (loop_index + 1) % print_three_leg == 0: data.dump_three_leg(suffix='-%s'%loop_index) if (loop_index + 1) % print_non_local == 0: data.dump_non_local(suffix='-%s'%loop_index) A = HDFArchive(data.archive_name) A['max_index'] = loop_index del A if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if (mpi.rank==0 or mpi.rank==1) and total_debug: #total debug option archive_name = 'full_data' if calculation_name !='': archive_name += '_%s'%calculation_name archive_name += '.rank%s'%(mpi.rank) print "about to dump all data in ",archive_name data.dump_all(suffix='-%s'%loop_index, archive_name=archive_name) times.append((time(),"")) if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if mpi.is_master_node(): self.print_timings(times) if (converged and loop_index>n_loops_min) or failed: break if not (self.after_it_is_done is None): self.after_it_is_done(data) #notice that if we don't say data=data we can pass a method of data for after_it_is_done, such that here self=data if mpi.is_master_node(): data.dump_all(suffix='-final') if not MASTER_SLAVE_ARCHITECTURE: mpi.barrier() if converged: return 0 else: if failed: return 2 #probably hitting AFM else: return 1 #maximum number of loops reached