def plot_bandstructure(self, filename=None, filepath=None, max_min_e=None, show=False, save=True, show_vbm_cbm=True): if 'bands' in self: from structure import get_kpath if filename == None: filename = 'band_structure.pdf' if filepath == None: filepath = os.path.join(self.abspath, filename) else: filepath = os.path.join(filepath, filename) #end if try: import matplotlib gui_envs = ['GTKAgg', 'TKAgg', 'agg', 'Qt4Agg', 'WXAgg'] for gui in gui_envs: try: matplotlib.use(gui, warn=False, force=True) from matplotlib import pyplot success = True break except: continue #end try #end for from matplotlib.pyplot import figure, plot, xlabel, ylabel, title, show, ylim, legend, xlim, rcParams, rc, savefig, gca, xticks, axvline, scatter params = { 'legend.fontsize': 14, 'figure.facecolor': 'white', 'figure.subplot.hspace': 0., 'axes.labelsize': 16, 'xtick.labelsize': 14, 'ytick.labelsize': 14 } rcParams.update(params) except (ImportError, RuntimeError): success = False if not success: figure, plot, xlabel, ylabel, title, show, ylim, legend, xlim, rcParams, savefig, bar, xticks, subplot, grid, setp, errorbar, loglog, semilogx, semilogy, text = unavailable( 'matplotlib.pyplot', 'figure', 'plot', 'xlabel', 'ylabel', 'title', 'show', 'ylim', 'legend', 'xlim', 'rcParams', 'savefig', 'bar', 'xticks', 'subplot', 'grid', 'setp', 'errorbar', 'loglog', 'semilogx', 'semilogy', 'text') #end if fig = figure() ax = gca() kpath = get_kpath(structure=self.input_structure, check_standard=False) x = kpath['explicit_path_linearcoords'] labels = kpath['explicit_kpoints_labels'] nbands = self.input.system.nbnd for nb in range(nbands): y = [] for bi in self.bands.up: y.append(bi['eigs'][nb]) #end for y = array(y) - self.bands.vbm.energy plot(x, y, 'k') if len(self.bands.down) > 0: y = [] for bi in self.bands.down: y.append(bi['eigs'][nb]) #end for y = array(y) - self.bands.vbm.energy plot(x, y, 'r') #end if #end for for ln, li in enumerate(labels): if li is not '': axvline(x[ln], ymin=-100, ymax=100, linewidth=3, color='k') if li == 'GAMMA': labels[ln] = r'$\Gamma$' elif li is not '': labels[ln] = '${0}$'.format(li) #end if if labels[ln - 1] is not '' and ln > 0: labels[ln] = labels[ln - 1] + '|' + labels[ln] labels[ln - 1] = '' #end if #end if #end for xlim([min(x), max(x)]) if max_min_e is None: ylim(-5, +5) else: ylim(max_min_e[0], max_min_e[1]) #end if ylabel('Energy (eV)') xticks(x, labels) ax.tick_params(axis='x', which='both', length=0) ax.tick_params(axis='x', which='both', pad=10) #end if if show_vbm_cbm: vbm = self.bands.vbm cbm = self.bands.cbm for kn, ki in enumerate(self.bands.up): if (vbm.kpoint_rel == ki['kpoint_rel']).all(): scatter(x[kn], 0, c='green', s=100) #end if if (cbm.kpoint_rel == ki['kpoint_rel']).all(): scatter(x[kn], cbm.energy - vbm.energy, c='r', s=100) #end if #end for #end if if save: savefig(filename, format='pdf', bbox_inches='tight') #end if if show: show()
def post_analyze(self,analyzer): if not self.has_generic_input(): calctypes = self.input.get_output_info('calctypes') opt_run = calctypes!=None and 'opt' in calctypes if opt_run: opt_file = analyzer.results.optimization.optimal_file if opt_file is None: self.failed = True #end if #end if exc_run = 'excitation' in self if exc_run: exc_failure = False edata = self.read_einspline_dat() exc_input = self.excitation exc_spin,exc_type,exc_spins,exc_types,exc1,exc2 = check_excitation_type(exc_input) elns = self.input.get_electron_particle_set() if exc_type==exc_types.band: # Band Index 'tw1 band1 tw2 band2'. Eg., '0 45 3 46' # Check that tw1,band1 is no longer in occupied set tw1,bnd1 = exc2.split()[0:2] tw2,bnd2 = exc2.split()[2:4] if exc1 in ('up','down'): spin_channel = exc1 dsc = edata[spin_channel] for idx,(tw,bnd) in enumerate(zip(dsc.TwistIndex,dsc.BandIndex)): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals if idx<elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the first orbital \'{} {}\' is still occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw1,bnd1) exc_failure = True #end if elif tw == int(tw2) and bnd == int(bnd2): # This orbital should be in the set of occupied orbitals if idx>=elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the second orbital \'{} {}\' is not occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw2,bnd2) exc_failure = True #end if #end if #end for else: self.warn('No check for \'{}\' excitation of type \'{}\' was done. When this path is possible, then a check should be written.'.format(exc_input[0],exc_input[1])) #end if elif exc_type in (exc_types.energy,exc_types.lowest): # Lowest or Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' if exc_type==exc_types.lowest: if exc_spin==exc_spins.down: orb1 = elns.groups.d.size else: orb1 = elns.groups.u.size #end if orb2 = orb1+1 else: orb1 = int(exc_input[1].split()[0][1:]) orb2 = int(exc_input[1].split()[1][1:]) #end if if exc1 in ('up','down'): spin_channel = exc1 nelec = elns.groups[spin_channel[0]].size eigs_spin = edata[spin_channel].Energy # Construct the correct set of occupied orbitals by hand based on # orb1 and orb2 values that were input by the user excited = eigs_spin order = eigs_spin.argsort() ground = excited[order] # einspline orbital ordering for excited state excited = excited[:nelec] # hand-crafted orbital order for excited state # ground can be list or ndarray, but we'll convert it to list # so we can concatenate with list syntax ground = np.asarray(ground).tolist() # After concatenating, convert back to ndarray hc_excited = np.array(ground[:orb1-1]+[ground[orb2-1]]+ground[orb1:nelec]) etol = 1e-6 if np.abs(hc_excited-excited).max() > etol: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the second orbital \'{}\' is not occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],orb1) exc_failure = True #end if elif exc1 in ('singlet','triplet'): wf = self.input.get('wavefunction') occ = wf.determinantset.multideterminant.detlist.csf.occ if occ[int(orb1)-1]!='1': msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, this is inconsistent with the occupations in detlist \'{}\'.\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],occ) exc_failure = True #end if if occ[int(orb2)-1]!='1': msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, this is inconsistent with the occupations in detlist \'{}\'.\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],occ) exc_failure = True #end if #end if else: # The format is: 'gamma vb z cb' if exc1 in ('singlet','triplet'): self.warn('No check for \'{}\' excitation of type \'{}\' was done. When this path is possible, then a check should be written.'.format(exc_input[0],exc_input[1])) else: # assume excitation of form 'gamma vb k cb' or 'gamma vb-1 k cb+1' excitation = exc2.upper().split(' ') k_1, band_1, k_2, band_2 = excitation tilematrix = self.system.structure.tilematrix() wf = self.input.get('wavefunction') if exc_spin==exc_spins.up: sdet = wf.determinantset.get('updet') else: sdet = wf.determinantset.get('downdet') #end if from numpy import linalg,where,isclose vb = int(sdet.size / abs(linalg.det(tilematrix))) -1 # Separate for each spin channel cb = vb+1 # Convert band_1, band_2 to band indexes bands = [band_1, band_2] for bnum, b in enumerate(bands): b = b.lower() if 'cb' in b: if '-' in b: b = b.split('-') bands[bnum] = cb - int(b[1]) elif '+' in b: b = b.split('+') bands[bnum] = cb + int(b[1]) else: bands[bnum] = cb #end if elif 'vb' in b: if '-' in b: b = b.split('-') bands[bnum] = vb - int(b[1]) elif '+' in b: b = b.split('+') bands[bnum] = vb + int(b[1]) else: bands[bnum] = vb #end if else: QmcpackInput.class_error('{0} in excitation has the wrong formatting'.format(b)) #end if #end for band_1, band_2 = bands # Convert k_1 k_2 to wavevector indexes structure = self.system.structure.get_smallest().copy() structure.change_units('A') from structure import get_kpath kpath = get_kpath(structure=structure) kpath_label = array(kpath['explicit_kpoints_labels']) kpath_rel = kpath['explicit_kpoints_rel'] k1_in = k_1 k2_in = k_2 if k_1 in kpath_label and k_2 in kpath_label: k_1 = kpath_rel[where(kpath_label == k_1)][0] k_2 = kpath_rel[where(kpath_label == k_2)][0] kpts = structure.kpoints_unit() found_k1 = False found_k2 = False for knum, k in enumerate(kpts): if isclose(k_1, k).all(): k_1 = knum found_k1 = True #end if if isclose(k_2, k).all(): k_2 = knum found_k2 = True #end if #end for if not found_k1 or not found_k2: QmcpackInput.class_error('Requested special kpoint is not in the tiled cell\nRequested "{}", present={}\nRequested "{}", present={}\nAvailable kpoints: {}'.format(k1_in,found_k1,k2_in,found_k2,sorted(set(kpath_label)))) #end if else: QmcpackInput.class_error('Excitation wavevectors are not found in the kpath\nlabels requested: {} {}\nlabels present: {}'.format(k_1,k_2,sorted(set(kpath_label)))) #end if tw1,bnd1 = (k_1,band_1) tw2,bnd2 = (k_2,band_2) spin_channel = exc1 dsc = edata[spin_channel] for idx,(tw,bnd) in enumerate(zip(dsc.TwistIndex,dsc.BandIndex)): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals if idx<elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the first orbital \'{} {}\' is still occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw1,bnd1) exc_failure = True #end if elif tw == int(tw2) and bnd == int(bnd2): # This orbital should be in the set of occupied orbitals if idx>=elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the second orbital \'{} {}\' is not occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw2,bnd2) exc_failure = True #end if #end if #end for #end if if exc_failure: self.failed = True self.warn(msg) filename = self.identifier+'_errors.txt' open(os.path.join(self.locdir,filename),'w').write(msg)