def test_full_relativistic(self): """Parsing the full-relativistic output file produced by ONCVPSPS.""" p = OncvOutputParser(filepath("08_O_r.out")) p.scan(verbose=1) repr(p); str(p) assert p.run_completed assert p.fully_relativistic assert p.calc_type == "fully-relativistic" assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1 # TODO: Wavefunctions # Build the plotter plotter = p.make_plotter() repr(plotter); str(plotter) self._call_plotter_methods(plotter)
def test_full_relativistic(self): """Parsing the full-relativistic output file produced by ONCVPSPS.""" p = OncvOutputParser(filepath("08_O_r.out")) p.scan(verbose=1) repr(p) str(p) assert p.run_completed assert p.fully_relativistic assert p.calc_type == "fully-relativistic" assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1 # TODO: Wavefunctions # Build the plotter plotter = p.make_plotter() repr(plotter) str(plotter) self._call_plotter_methods(plotter)
def test_nonrelativistica(self): """Parsing the non-relativistic output file produced by ONCVPSPS.""" # Non-relativistic results p = OncvOutputParser(filepath("08_O_nr.out")) p.scan(verbose=1) assert p.run_completed print(p) assert p.calc_type == "non-relativistic" assert not p.fully_relativistic assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.lmax == 1 assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1 rhov, rhoc, rhom = p.densities["rhoV"], p.densities["rhoC"], p.densities["rhoM"] assert rhov.rmesh[0] == 0.0100642 assert rhov.rmesh[-1] == 3.9647436 assert rhoc.values[0] == 53.3293576 assert all(rhom.values == 0.0) # Conversion to JSON format. p.to_dict # Build the plotter plotter = p.make_plotter()
def oncv_gnuplot(options): """Plot data with gnuplot.""" out_path = find_oncv_output(options.filename) # Parse output file. onc_parser = OncvOutputParser(out_path) onc_parser.scan() if not onc_parser.run_completed: cprint("oncvpsp output is not complete. Exiting", "red") return 1 onc_parser.gnuplot() return 0
def oncv_json(options): """ Produce a string with the results in a JSON dictionary and exit Requires oncvpsp output file. """ out_path = find_oncv_output(options.filename) onc_parser = OncvOutputParser(out_path) onc_parser.scan() if not onc_parser.run_completed: cprint("oncvpsp output is not complete. Exiting", "red") return 1 # Generate json files with oncvpsp results. print(json.dumps(onc_parser.to_dict, indent=-1)) return 0
def test_full_relativistic(self): """Parsing the full-relativistic output file produced by ONCVPSPS.""" p = OncvOutputParser(filepath("08_O_r.out")) p.scan(verbose=1) assert p.run_completed assert p.fully_relativistic assert p.calc_type == "fully-relativistic" assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1
def oncv_plot(options): """Plot data with matplotlib. Requires oncvpsp output file.""" out_path = find_oncv_output(options.filename) # Parse output file. onc_parser = OncvOutputParser(out_path) onc_parser.scan() if not onc_parser.run_completed: cprint("oncvpsp output is not complete. Exiting", "red") return 1 # Build the plotter plotter = onc_parser.make_plotter() # Plot data plotter.plot_radial_wfs() plotter.plot_atanlogder_econv() plotter.plot_projectors() plotter.plot_potentials() #plotter.plot_der_potentials() #for order in [1,2,3,4]: # plotter.plot_der_densities(order=order) plotter.plot_densities() #plotter.plot_densities(timesr2=True) plotter.plot_den_formfact() return 0 # Table of methods callables = collections.OrderedDict([ ("wp", plotter.plot_waves_and_projs), ("dp", plotter.plot_dens_and_pots), ("lc", plotter.plot_atanlogder_econv), ("df", plotter.plot_den_formfact), ]) # Call function depending on options.plot_mode if options.plot_mode == "slide": for func in callables.values(): func() else: func = callables.get(options.plot_mode, None) if func is not None: func() else: plotter.plot_key(key=options.plot_mode)
def test_nonrelativistica(self): """Parsing the non-relativistic output file produced by ONCVPSPS.""" # Non-relativistic results p = OncvOutputParser(filepath("08_O_nr.out")) repr(p) str(p) p.scan(verbose=1) repr(p) str(p) assert p.run_completed assert p.calc_type == "non-relativistic" assert not p.fully_relativistic assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.lmax == 1 assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1 rhov, rhoc, rhom = p.densities["rhoV"], p.densities[ "rhoC"], p.densities["rhoM"] assert rhov.rmesh[0] == 0.0100642 assert rhov.rmesh[-1] == 3.9647436 assert rhoc.values[0] == 53.3293576 assert all(rhom.values == 0.0) # Conversion to JSON format. p.to_dict # Build the plotter plotter = p.make_plotter() repr(plotter) str(plotter) self._call_plotter_methods(plotter)
#!/usr/bin/env python import sys from pseudo_dojo.ppcodes.oncvpsp import OncvOutputParser path = sys.argv[1] parser = OncvOutputParser(path) parser.scan() print(parser.core) print(parser.valence) print(parser.rc_min) #1s 2s 2p 3s 3p 3d 4s 4p 4d #5s 5p 4f 5d 6s #1.4
def oncv_run(options): """ Run oncvpsp, generate djrepo file, plot results. Requires input file. """ # Select calc_type calc_type = dict(nor="non-relativistic", sr="scalar-relativistic", fr="fully-relativistic")[options.rel] # Build names of psp8 and djson files from input and relativistic mode. in_path = options.filename root, _ = os.path.splitext(in_path) # Enforce convention on output files. if options.rel == "nor": if not root.endswith("_nor"): root += "_nor" elif options.rel == "fr": if not root.endswith("_r"): root += "_r" cprint( "FR calculation with input file without `_r` suffix. Will add `_r` to output files", "yellow") # Build names of output files. psp8_path = root + ".psp8" djrepo_path = root + ".djrepo" out_path = root + ".out" if os.path.exists(psp8_path): cprint( "%s already exists and will be overwritten" % os.path.relpath(psp8_path), "yellow") if os.path.exists(djrepo_path): cprint( "%s already exists and will be overwritten" % os.path.relpath(djrepo_path), "yellow") if os.path.exists(out_path): cprint( "%s already exists and will be overwritten" % os.path.relpath(out_path), "yellow") # Build Generator and start generation. oncv_ppgen = OncvGenerator.from_file(in_path, calc_type, workdir=None) print(oncv_ppgen) print(oncv_ppgen.input_str) oncv_ppgen.start() retcode = oncv_ppgen.wait() if oncv_ppgen.status != oncv_ppgen.S_OK: cprint("oncvpsp returned %s. Exiting" % retcode, "red") return 1 # Tranfer final output file. shutil.copy(oncv_ppgen.stdout_path, out_path) # Parse the output file onc_parser = OncvOutputParser(out_path) onc_parser.scan() if not onc_parser.run_completed: cprint("oncvpsp output is not complete. Exiting", "red") return 1 # Extract psp8 files from the oncvpsp output and write it to file. s = onc_parser.get_psp8_str() with open(psp8_path, "wt") as fh: fh.write(s) # Write upf if available. upf_str = onc_parser.get_upf_str() if upf_str is not None: with open(psp8_path.replace(".psp8", ".upf"), "wt") as fh: fh.write(upf_str) pseudo = Pseudo.from_file(psp8_path) if pseudo is None: cprint("Cannot parse psp8 file: %s" % psp8_path, "red") return 1 # Initialize and write djson file. report = DojoReport.empty_from_pseudo(pseudo, onc_parser.hints, devel=False) report.json_write() return 0
def dojo_figures(options): """ Create figures for a dojo table. currently for all pseudo's in the search space the one with the best df per element is chosen this should probably come from a dojotable eventually """ pseudos = options.pseudos data_dojo, errors = pseudos.get_dojo_dataframe() # add data that is not part of the dojo report data_pseudo = DataFrame(columns=("nv", "valence", "rcmin", "rcmax")) for index, p in data_dojo.iterrows(): out = p.name.replace("psp8", "out") outfile = p.symbol + "/" + out parser = OncvOutputParser(outfile) parser.scan() data_pseudo.loc[index] = [int(parser.nv), parser.valence, parser.rc_min, parser.rc_max] data = concat([data_dojo, data_pseudo], axis=1) """Select entries per element""" grouped = data.groupby("symbol") rows, names = [], [] for name, group in grouped: if False: # options.semicore select = group.sort("nv").iloc[-1] elif False: # options.valence select = group.sort("nv").iloc[0] else: select = group.sort("high_dfact_meV").iloc[0] names.append(name) l = { k: getattr(select, k) for k in ( "name", "Z", "high_b0_GPa", "high_b1", "high_v0", "high_dfact_meV", "high_dfactprime_meV", "high_ecut", "high_gbrv_bcc_a0_rel_err", "high_gbrv_fcc_a0_rel_err", "high_ecut", "low_phonon", "high_phonon", "low_ecut_hint", "normal_ecut_hint", "high_ecut_hint", "nv", "valence", "rcmin", "rcmax", ) } rows.append(l) import matplotlib.pyplot as plt from ptplotter.plotter import ElementDataPlotter import matplotlib.cm as mpl_cm from matplotlib.collections import PatchCollection import numpy as np class ElementDataPlotterRangefixer(ElementDataPlotter): """ modified plotter that alows to set the clim for the plot """ def draw(self, colorbars=True, **kwargs): self.cbars = [] clims = kwargs.get("clims", None) n = len(self.collections) if clims is None: clims = [None] * n elif len(clims) == 1: clims = [clims[0]] * n elif len(clims) == n: pass else: raise RuntimeError("incorrect number of clims provided in draw") for coll, cmap, label, clim in zip(self.collections, self.cmaps, self.cbar_labels, clims): # print(clim) pc = PatchCollection(coll, cmap=cmap) pc.set_clim(vmin=clim[0], vmax=clim[1]) # print(pc.get_clim()) pc.set_array(np.array([p.value for p in coll])) self._ax.add_collection(pc) if colorbars: options = {"orientation": "horizontal", "pad": 0.05, "aspect": 60} options.update(kwargs.get("colorbar-options", {})) cbar = plt.colorbar(pc, **options) cbar.set_label(label) self.cbars.append(cbar) fontdict = kwargs.get("font", {"color": "white"}) for s in self.squares: if not s.label: continue x = s.x + s.dx / 2 y = s.y + s.dy / 2 self._ax.text(x, y, s.label, ha="center", va="center", fontdict=fontdict) qs_labels = [k.split("[")[0] for k in self.labels] if self.guide_square: self.guide_square.set_labels(qs_labels) pc = PatchCollection(self.guide_square.patches, match_original=True) self._ax.add_collection(pc) self._ax.autoscale_view() cmap = mpl_cm.cool color = "black" cmap.set_under("w", 1.0) # functions for plotting def rcmin(elt): """R_c min [Bohr]""" return elt["rcmin"] def rcmax(elt): """R_c max [Bohr]""" return elt["rcmax"] def ar(elt): """Atomic Radius [Bohr]""" return elt["atomic_radii"] * 0.018897161646320722 def df(elt): """Delta Factor [meV / atom]""" try: return elt["high_dfact_meV"] except KeyError: return float("NaN") def dfp(elt): """Delta Factor Prime""" try: return elt["high_dfactprime_meV"] except KeyError: return float("NaN") def bcc(elt): """GBRV BCC [% relative error]""" try: v_bcc = elt["high_gbrv_bcc_a0_rel_err"] if str(elt["high_gbrv_bcc_a0_rel_err"]) != "nan" else -99 # print(v_bcc) return v_bcc except KeyError: print("bcc func fail: ", elt) return -99 # float('NaN') def fcc(elt): """GBRV FCC [% relative error]""" try: v_fcc = elt["high_gbrv_fcc_a0_rel_err"] if str(elt["high_gbrv_fcc_a0_rel_err"]) != "nan" else -99 # print(v_fcc) return v_fcc except KeyError: print("fcc func fail: ", elt) return -99 # float('NaN') def low_phon_with(elt): """Acoustic mode low_cut """ try: return elt["low_phonon"][0] except (KeyError, TypeError): # print('low_phon wiht func fail: ', elt) return float("NaN") def high_phon_with(elt): """AC mode [\mu eV] """ try: return elt["high_phonon"][0] * 1000 except (KeyError, TypeError): # print('high_phon with func fail: ', elt) return float("NaN") def high_ecut(elt): """ecut high [Ha] """ try: return elt["high_ecut_hint"] except (KeyError, TypeError): # print('high_ecut with func fail: ', elt) return float("NaN") def low_ecut(elt): """ecut low [Ha] """ try: return elt["low_ecut_hint"] except (KeyError, TypeError): # print('low_ecut with func fail: ', elt) return float("NaN") def normal_ecut(elt): """ecut normal [Ha] """ try: return elt["normal_ecut_hint"] except (KeyError, TypeError): # print('normal_ecut with func fail: ', elt) return float("NaN") els = [] elsgbrv = [] elsphon = [] rel_ers = [] elements_data = {} for el in rows: symbol = el["name"].split(".")[0].split("-")[0] rel_ers.append(max(abs(el["high_gbrv_bcc_a0_rel_err"]), abs(el["high_gbrv_fcc_a0_rel_err"]))) if el["high_dfact_meV"] > 0: elements_data[symbol] = el els.append(symbol) else: print("failed reading df :", symbol, el["high_dfact_meV"]) if el["high_gbrv_bcc_a0_rel_err"] > -100 and el["high_gbrv_fcc_a0_rel_err"] > -100: elsgbrv.append(symbol) else: print("failed reading gbrv: ", symbol, el["high_gbrv_bcc_a0_rel_err"], el["high_gbrv_fcc_a0_rel_err"]) # print(el) try: if len(el["high_phonon"]) > 2: elsphon.append(symbol) except (KeyError, TypeError): pass max_rel_err = max(rel_ers) # plot the GBRV/DF results periodic table epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) cm1 = mpl_cm.jet cm2 = mpl_cm.cool cm1.set_under("w", 1.0) epd.ptable( functions=[bcc, fcc, df], font={"color": color}, cmaps=[cm1, cm1, cm2], clims=[[-max_rel_err, max_rel_err], [-max_rel_err, max_rel_err], [0, 3]], ) plt.show() # plt.savefig('gbrv.eps', format='eps') # plot the periodic table with df and dfp epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) epd.ptable(functions=[df, dfp], font={"color": color}, cmaps=cmap, clims=[[0, 6]]) plt.show() # plt.savefig('df.eps', format='eps') # plot the GBVR results periodic table epd = ElementDataPlotterRangefixer(elements=elsgbrv, data=elements_data) epd.ptable(functions=[bcc, fcc], font={"color": color}, cmaps=mpl_cm.jet, clims=[[-max_rel_err, max_rel_err]]) plt.show() # plt.savefig('gbrv.eps', format='eps') # plot the hints periodic table epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) cm = mpl_cm.cool cm.set_under("w", 1.0) epd.ptable(functions=[low_ecut, high_ecut, normal_ecut], font={"color": color}, clims=[[6, 80]], cmaps=cmap) plt.show() # plt.savefig('rc.eps', format='eps') # plot the radii periodic table epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) epd.ptable(functions=[rcmin, rcmax, ar], font={"color": color}, clims=[[0, 4]], cmaps=cmap) plt.show() # plt.savefig('rc.eps', format='eps') # plot the accoustic mode periodic table epd = ElementDataPlotterRangefixer(elements=elsphon, data=data) cm = mpl_cm.winter cm.set_under("orange", 1.0) epd.ptable(functions=[high_phon_with], font={"color": color}, cmaps=cm, clims=[[-2, 0]]) plt.show()
def change_icmod3(self, fcfact_list=(3, 4, 5), rcfact_list=(1.3, 1.35, 1.4, 1.45, 1.5, 1.55)): """ Change the value of fcfact and rcfact in the template. Generate the new pseudos and create new directories with the pseudopotentials in the current workding directory. Return: List of `Pseudo` objects Old version with icmod == 1. # icmod fcfact 1 0.085 New version with icmod == 3. # icmod, fcfact (rcfact) 3 5.0 1.3 """ magic = "# icmod fcfact" for i, line in enumerate(self.template_lines): if line.strip() == magic: break else: raise ValueError("Cannot find magic line `%s` in template:\n%s" % (magic, "\n".join(self.template_lines))) # Extract the parameters from the line. pos = i + 1 line = self.template_lines[pos] tokens = line.split() icmod = int(tokens[0]) #if len(tokens) != 3: # raise ValueError("Expecting line with 3 numbers but got:\n%s" % line) #icmod, old_fcfact, old_rcfact = int(tokens[0]), float(tokens[1]), float(tokens[2]) #if icmod != 3: # raise ValueError("Expecting icmod == 3 but got %s" % icmod) base_name = os.path.basename(self.filepath).replace(".in", "") ppgens = [] for fcfact, rcfact in product(fcfact_list, rcfact_list): new_input = self.template_lines[:] new_input[pos] = "%i %s %s\n" % (3, fcfact, rcfact) input_str = "".join(new_input) #print(input_str) ppgen = OncvGenerator(input_str, calc_type=self.calc_type) name = base_name + "_fcfact%3.2f_rcfact%3.2f" % (fcfact, rcfact) ppgen.name = name ppgen.stdin_basename = name + ".in" ppgen.stdout_basename = name + ".out" # Attach fcfact and rcfact to ppgen ppgen.fcfact, ppgen.rcfact = fcfact, rcfact if not ppgen.start() == 1: raise RuntimeError("ppgen.start() failed!") ppgens.append(ppgen) for ppgen in ppgens: retcode = ppgen.wait() ppgen.check_status() # Ignore errored calculations. ok_ppgens = [gen for gen in ppgens if gen.status == gen.S_OK] print("%i/%i generations completed with S_OK" % (len(ok_ppgens), len(ppgens))) ok_pseudos = [] for ppgen in ok_ppgens: # Copy files to dest pseudo = ppgen.pseudo #dest = os.path.basename(self.filepath) + "_fcfact%3.2f_rcfact%3.2f" % (ppgen.fcfact, ppgen.rcfact) dest = os.path.split(self.filepath)[0] shutil.copy(os.path.join(ppgen.workdir, ppgen.stdin_basename), dest) shutil.copy(os.path.join(ppgen.workdir, ppgen.stdout_basename), dest) # Reduce the number of ecuts in the DOJO_REPORT # Re-parse the output and use devel=True to overwrite initial psp8 file psp8_path = os.path.join(dest, ppgen.name + ".psp8") out_path = os.path.join(dest, ppgen.name + ".out") parser = OncvOutputParser(out_path) parser.scan() # Rewrite pseudo file in devel mode. with open(psp8_path, "w") as fh: fh.write(parser.get_pseudo_str(devel=True)) # Build new pseudo. p = Pseudo.from_file(psp8_path) ok_pseudos.append(p) return ok_pseudos
def dojo_figures(options): """ Create figures for a dojo table. Currently for all pseudos in the search space, the one with the best df per element is chosen. This should probably come from a dojotable eventually """ pseudos = options.pseudos if False: """ read the data from a data file instead of psp files """ rows = [] with open('data') as data_file: for line in data_file: line.rstrip('\n') #print(line) data = line.split(',') #print(data) data_dict = {'name': data[0], 'high_dfact_meV': float(data[1]), 'rell_high_dfact_meV': float(data[2]), 'high_dfactprime_meV': float(data[3])} if data[5] != 'nan': data_dict['high_gbrv_bcc_a0_rel_err'] = float(data[5]) data_dict['high_gbrv_fcc_a0_rel_err'] = float(data[7]) rows.append(data_dict) else: # Get data from dojoreport data_dojo, errors = pseudos.get_dojo_dataframe() if errors: cprint("get_dojo_dataframe returned %s errors" % len(errors), "red") if not options.verbose: print("Use --verbose for details.") else: for i, e in enumerate(errors): print("[%s]" % i, e) # add data that is not part of the dojo report data_pseudo = DataFrame(columns=('nv', 'valence', 'rcmin', 'rcmax') ) for index, p in data_dojo.iterrows(): outfile = p.filepath.replace('.psp8', '.out') parser = OncvOutputParser(outfile) parser.scan() if not parser.run_completed: raise RuntimeError("[%s] Corrupted outfile") data_pseudo.loc[index] = [parser.nv, parser.valence, parser.rc_min, parser.rc_max] data = concat([data_dojo, data_pseudo], axis=1) # Select "best" entries per element. rows, names = [], [] sortby, ascending = "high_dfact_meV", True for name, group in data.groupby("symbol"): # Sort group and select best pseudo depending on sortby and ascending. select = group.sort_values(sortby, ascending=ascending).iloc[0] l = {k: getattr(select, k, None) for k in ( 'name', "symbol", 'Z', 'high_b0_GPa', 'high_b1', 'high_v0', 'high_dfact_meV', 'high_dfactprime_meV', 'high_ecut', 'high_gbrv_bcc_a0_rel_err', 'high_gbrv_fcc_a0_rel_err', 'high_ecut', #'low_phonon', 'high_phonon', 'low_ecut_hint', 'normal_ecut_hint', 'high_ecut_hint', 'nv', 'valence', 'rcmin', 'rcmax')} for k, v in l.items(): if v is None: cprint("[%s] Got None for %s" % (name, k), "red") names.append(name) rows.append(l) import matplotlib.pyplot as plt import matplotlib.cm as mpl_cm from pseudo_dojo.util.ptable_plotter import ElementDataPlotterRangefixer cmap = mpl_cm.cool color = 'black' cmap.set_under('w', 1.) # functions for plotting def rcmin(elt): """R_c min [Bohr]""" return elt['rcmin'] def rcmax(elt): """R_c max [Bohr]""" return elt['rcmax'] def ar(elt): """Atomic Radius [Bohr]""" return elt['atomic_radii'] * 0.018897161646320722 def df(elt): """Delta Factor [meV / atom]""" return elt.get('high_dfact_meV', float('NaN')) def dfp(elt): """Delta Factor Prime""" return elt.get('high_dfactprime_meV', float('NaN')) def bcc(elt): """GBRV BCC [% relative error]""" try: return elt['high_gbrv_bcc_a0_rel_err'] if str(elt['high_gbrv_bcc_a0_rel_err']) != 'nan' else -99 except KeyError: #print('bcc func fail: ', elt) return float('NaN') def fcc(elt): """GBRV FCC [% relative error]""" try: return elt['high_gbrv_fcc_a0_rel_err'] if str(elt['high_gbrv_fcc_a0_rel_err']) != 'nan' else -99 except KeyError: #print('fcc func fail: ', elt) return float('NaN') def low_phon_with(elt): """Acoustic mode low_cut""" try: return elt['low_phonon'][0] except (KeyError, TypeError): #print('low_phon wiht func fail: ', elt) return float('NaN') def high_phon_with(elt): """AC mode [\mu eV]""" try: return elt['high_phonon'][0]*1000 except (KeyError, TypeError): #print('high_phon with func fail: ', elt) return float('NaN') def high_ecut(elt): """ecut high [Ha]""" return elt.get('high_ecut_hint', float('NaN')) def low_ecut(elt): """ecut low [Ha]""" return elt.get('low_ecut_hint', float('NaN')) def normal_ecut(elt): """ecut normal [Ha]""" return elt.get('normal_ecut_hint', float('NaN')) els = [] elsgbrv = [] #elsphon = [] rel_ers = [] elements_data = {} for el in rows: symbol = el["symbol"] # Prepare data for deltafactor if el['high_dfact_meV'] is None: cprint('[%s] failed reading high_dfact_meV %s:' % (symbol, el['high_dfact_meV']), "magenta") else: if el['high_dfact_meV'] < 0: cprint('[%s] negative high_dfact_meV %s:' % (symbol, el['high_dfact_meV']), "red") print(symbol, el['high_dfact_meV']) #assert el['high_dfact_meV'] >= 0 elements_data[symbol] = el els.append(symbol) # Prepare data for GBRV try: rel_ers.append(max(abs(el['high_gbrv_bcc_a0_rel_err']), abs(el['high_gbrv_fcc_a0_rel_err']))) except (TypeError, KeyError) as exc: cprint('[%s] failed reading high_gbrv:' % symbol, "magenta") if options.verbose: print(exc) try: if el['high_gbrv_bcc_a0_rel_err'] > -100 and el['high_gbrv_fcc_a0_rel_err'] > -100: elsgbrv.append(symbol) except (KeyError, TypeError) as exc: cprint('[%s] failed reading GBRV data for ' % symbol, "magenta") if options.verbose: print(exc) #try: # if len(el['high_phonon']) > 2: # elsphon.append(symbol) #except (KeyError, TypeError) as exc: # cprint('[%s] failed reading high_phonon' % symbol, "magenta") # if options.verbose: print(exc) #if symbol == "Br": # print (elements_data[symbol]) try: max_rel_err = 0.05 * int((max(rel_ers) / 0.05) + 1) except ValueError: max_rel_err = 0.20 # plot the GBRV/DF results periodic table epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) cm1 = mpl_cm.jet cm2 = mpl_cm.jet cm1.set_under('w', 1.0) epd.ptable(functions=[bcc, fcc, df], font={'color': color}, cmaps=[cm1, cm1, cm2], #clims=[[-max_rel_err, max_rel_err],[-max_rel_err, max_rel_err], [-20,20]]) clims=[[-0.6,0.6],[-0.6, 0.6], [-4,4]]) plt.show() # Test different color maps #for cm2 in [mpl_cm.PiYG_r, mpl_cm.PRGn_r,mpl_cm.RdYlGn_r]: # epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) # epd.ptable(functions=[bcc,fcc,df], font={'color':color}, cmaps=[cm1,cm1,cm2], # clims=[[-max_rel_err,max_rel_err],[-max_rel_err, max_rel_err], [0,3]]) # plt.show() #plt.savefig('gbrv.eps', format='eps') # plot the periodic table with deltafactor and deltafactor prime. epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) epd.ptable(functions=[df, dfp], font={'color': color}, cmaps=cmap, clims=[[0, 6]]) plt.show() #plt.savefig('df.eps', format='eps') # plot the GBVR results periodic table epd = ElementDataPlotterRangefixer(elements=elsgbrv, data=elements_data) epd.ptable(functions=[bcc, fcc], font={'color': color}, cmaps=mpl_cm.jet, clims=[[-max_rel_err, max_rel_err]]) plt.show() #plt.savefig('gbrv.eps', format='eps') # plot the hints periodic table epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) cm = mpl_cm.cool cm.set_under('w', 1.0) epd.ptable(functions=[low_ecut, high_ecut, normal_ecut], font={'color': color}, clims=[[6, 80]], cmaps=cmap) plt.show() #plt.savefig('rc.eps', format='eps') # plot the radii periodic table epd = ElementDataPlotterRangefixer(elements=els, data=elements_data) epd.ptable(functions=[rcmin, rcmax, ar], font={'color': color}, clims=[[0, 4]], cmaps=cmap) plt.show() #plt.savefig('rc.eps', format='eps') # plot the acoustic mode periodic table #epd = ElementDataPlotterRangefixer(elements=elsphon, data=data) #cm = mpl_cm.winter #cm.set_under('orange', 1.0) #epd.ptable(functions=[high_phon_with], font={'color':color}, cmaps=cm, clims=[[-2, 0]]) #plt.show() #plt.savefig('rc.eps', format='eps') return 0
def test_scalar_relativistic(self): """Parsing the scalar-relativistic output file produced by ONCVPSPS.""" # Scalar relativistic output p = OncvOutputParser(filepath("08_O_sr.out")) p.scan(verbose=1) assert p.run_completed assert not p.fully_relativistic assert p.calc_type == "scalar-relativistic" assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1 # Test potentials vloc = p.potentials[-1] pl0 = {0: -7.4449470, 1: -14.6551019, -1: -9.5661177} for l, pot in p.potentials.items(): assert pot.rmesh[0], pot.rmesh[-1] == (0.0099448, 3.9647436) print(l) assert pot.values[0] == pl0[l] assert all(pot.rmesh == vloc.rmesh) # Test wavefunctions ae_wfs, ps_wfs = p.radial_wfs.ae, p.radial_wfs.ps nlk = (1, 0, None) ae10, ps10 = ae_wfs[nlk], ps_wfs[nlk] assert ae10[0] == (0.009945, -0.092997) assert ps10[0] == (0.009945, 0.015273) assert ae10[-1] == (3.964744, 0.037697) assert ps10[-1] == (3.964744, 0.037694) nlk = (2, 1, None) ae21, ps21 = ae_wfs[nlk], ps_wfs[nlk] assert ae21[0] == (0.009945, 0.001463) assert ps21[0] == (0.009945, 0.000396) # Test projectors prjs = p.projectors assert prjs[(1, 0, None)][0] == (0.009945, 0.015274) assert prjs[(2, 0, None)][0] == (0.009945, -0.009284) assert prjs[(1, 0, None)][-1] == (3.964744, 0.037697) assert prjs[(2, 0, None)][-1] == (3.964744, 0.330625) assert prjs[(1, 1, None)][0] == (0.009945, 0.000395) assert prjs[(2, 1, None)][0] == (0.009945, -0.000282) # Test convergence data c = p.ene_vs_ecut assert c[0].energies[0] == 5.019345 assert c[0].values[0] == 0.010000 assert c[0].energies[-1] == 25.317286 assert c[0].values[-1] == 0.000010 assert c[1].energies[0] == 19.469226 assert c[1].values[0] == 0.010000 # Test log derivatives ae0, ps0 = p.atan_logders.ae[0], p.atan_logders.ps[0] assert ae0.energies[0], ae0.values[0] == (2.000000, 0.706765) assert ps0.energies[0], ps0.values[0] == (2.000000, 0.703758) assert ae0.energies[-1], ae0.energies[-1] == (-2.000000, 3.906687) assert ps0.energies[-1], ps0.energies[-1] == (-2.000000, 3.906357) ae1, ps1 = p.atan_logders.ae[1], p.atan_logders.ps[1] assert ae1.energies[0], ae1.values[0] == (2.000000, -2.523018) assert ps1.values[0] == -2.521334
def main(): parser = argparse.ArgumentParser() #formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('filename', default="", help="Path to the output file") parser.add_argument("-p", "--plot-mode", default="slide", help=("Quantity to plot. Possible values: %s" % str(["slide", "wp, dp, lc"] + PseudoGenDataPlotter.all_keys) + "\n" "wp --> wavefunctions and projectors\n" + "dp --> densities and potentials\n" + "lc --> atan(logder) and convergence wrt ecut")) parser.add_argument("-j", "--json", action="store_true", default=False, help="Produce a string with the results in a JSON dictionary and exit") parser.add_argument("-8", "--psp8", action="store_true", default=False, help="produce a .psp8 file with initial dojo report and exit") options = parser.parse_args() onc_parser = OncvOutputParser(options.filename) onc_parser.scan() if options.json: import json print(json.dumps(onc_parser.to_dict, indent=4)) return 0 if options.psp8: print(onc_parser.get_pseudo_str()) return 0 # Build the plotter plotter = onc_parser.make_plotter() # Table of methods callables = collections.OrderedDict([ ("wp", plotter.plot_waves_and_projs), ("dp", plotter.plot_dens_and_pots), ("lc", plotter.plot_atanlogder_econv), ]) #plotter.plot_radial_wfs() #plotter.plot_projectors() #plotter.plot_potentials() #plotter.plot_der_potentials() #plotter.plot_densities() #plotter.plot_der_densities(order=1) #plotter.plot_der_densities(order=2) plotter.plot_der_densities(order=4) return # Call function depending on options.plot_mode if options.plot_mode == "slide": for func in callables.values(): func() else: func = callables.get(options.plot_mode, None) if func is not None: func() else: plotter.plot_key(key=options.plot_mode) return 0
def change_icmod3(self, fcfact_list=(3, 4, 5), rcfact_list=(1.3, 1.35, 1.4, 1.45, 1.5, 1.55)): """ Change the value of fcfact and rcfact in the template. Generate the new pseudos and create new directories with the pseudopotentials in the current workding directory. Return: List of `Pseudo` objects Old version with icmod == 1. # icmod fcfact 1 0.085 New version with icmod == 3. # icmod, fcfact (rcfact) 3 5.0 1.3 """ magic = "# icmod fcfact" for i, line in enumerate(self.template_lines): if line.strip() == magic: break else: raise ValueError("Cannot find magic line `%s` in template:\n%s" % (magic, "\n".join(self.template_lines))) # Extract the parameters from the line. pos = i + 1 line = self.template_lines[pos] tokens = line.split() icmod = int(tokens[0]) #if len(tokens) != 3: # raise ValueError("Expecting line with 3 numbers but got:\n%s" % line) #icmod, old_fcfact, old_rcfact = int(tokens[0]), float(tokens[1]), float(tokens[2]) #if icmod != 3: # raise ValueError("Expecting icmod == 3 but got %s" % icmod) base_name = os.path.basename(self.filepath).replace(".in", "") ppgens = [] for fcfact, rcfact in product(fcfact_list, rcfact_list): new_input = self.template_lines[:] new_input[pos] = "%i %s %s\n" % (3, fcfact, rcfact) input_str = "".join(new_input) #print(input_str) ppgen = OncvGenerator(input_str, calc_type=self.calc_type) name = base_name + "_fcfact%3.2f_rcfact%3.2f" % (fcfact, rcfact) ppgen.name = name ppgen.stdin_basename = name + ".in" ppgen.stdout_basename = name + ".out" # Attach fcfact and rcfact to ppgen ppgen.fcfact, ppgen.rcfact = fcfact, rcfact if not ppgen.start() == 1: raise RuntimeError("ppgen.start() failed!") ppgens.append(ppgen) for ppgen in ppgens: retcode = ppgen.wait() ppgen.check_status() # Ignore errored calculations. ok_ppgens = [gen for gen in ppgens if gen.status == gen.S_OK] print("%i/%i generations completed with S_OK" % (len(ok_ppgens), len(ppgens))) ok_pseudos = [] for ppgen in ok_ppgens: # Copy files to dest pseudo = ppgen.pseudo #dest = os.path.basename(self.filepath) + "_fcfact%3.2f_rcfact%3.2f" % (ppgen.fcfact, ppgen.rcfact) dest = os.path.split(self.filepath)[0] shutil.copy(os.path.join(ppgen.workdir,ppgen.stdin_basename), dest) shutil.copy(os.path.join(ppgen.workdir,ppgen.stdout_basename), dest) # Reduce the number of ecuts in the DOJO_REPORT # Re-parse the output and use devel=True to overwrite initial psp8 file psp8_path = os.path.join(dest, ppgen.name + ".psp8") out_path = os.path.join(dest, ppgen.name + ".out") parser = OncvOutputParser(out_path) parser.scan() # Rewrite pseudo file in devel mode. with open(psp8_path, "w") as fh: fh.write(parser.get_pseudo_str(devel=True)) # Build new pseudo. p = Pseudo.from_file(psp8_path) ok_pseudos.append(p) return ok_pseudos
def test_oncvoutput_parser(): """Test the parsing of the output file produced by ONCVPSPS.""" # TODO: Full-relativistic case not yet supported. with pytest.raises(OncvOutputParser.Error): OncvOutputParser(filepath("08_O_r.out")) # Non-relativistic results p = OncvOutputParser(filepath("08_O_nr.out")) print(p) assert not p.fully_relativistic assert p.calc_type == "non-relativistic" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.lmax == 1 rhov, rhoc, rhom = p.densities["rhoV"], p.densities["rhoC"], p.densities["rhoM"] assert rhov.rmesh[0] == 0.0100642 assert rhov.rmesh[-1] == 3.9647436 assert rhoc.values[0] == 53.3293576 assert all(rhom.values == 0.0) # Conversion to JSON format. p.to_dict # Build the plotter plotter = p.make_plotter() # Scalar relativistic output p = OncvOutputParser(filepath("08_O_sr.out")) assert not p.fully_relativistic assert p.calc_type == "scalar-relativistic" assert p.lmax == 1 # Test potentials vloc = p.potentials[-1] pl0 = {0: -7.4449470, 1: -14.6551019, -1: -9.5661177} for l, pot in p.potentials.items(): assert pot.rmesh[0], pot.rmesh[-1] == (0.0099448, 3.9647436) print(l) assert pot.values[0] == pl0[l] assert all(pot.rmesh == vloc.rmesh) # Test wavefunctions ae_wfs, ps_wfs = p.radial_wfs.ae, p.radial_wfs.ps ae10, ps10 = ae_wfs[(1, 0)], ps_wfs[(1, 0)] assert ae10[0] == (0.009945, -0.092997) assert ps10[0] == (0.009945, 0.015273) assert ae10[-1] == (3.964744, 0.037697) assert ps10[-1] == (3.964744, 0.037694) ae21, ps21 = ae_wfs[(2, 1)], ps_wfs[(2, 1)] assert ae21[0] == (0.009945, 0.001463) assert ps21[0] == (0.009945, 0.000396) # Test projectors prjs = p.projectors assert prjs[(1, 0)][0] == (0.009945, 0.015274) assert prjs[(2, 0)][0] == (0.009945, -0.009284) assert prjs[(1, 0)][-1] == (3.964744, 0.037697) assert prjs[(2, 0)][-1] == (3.964744, 0.330625) assert prjs[(1, 1)][0] == (0.009945, 0.000395) assert prjs[(2, 1)][0] == (0.009945, -0.000282) # Test convergence data c = p.ene_vs_ecut assert c[0].energies[0] == 5.019345 assert c[0].values[0] == 0.010000 assert c[0].energies[-1] == 25.317286 assert c[0].values[-1] == 0.000010 assert c[1].energies[0] == 19.469226 assert c[1].values[0] == 0.010000 # Test log derivatives ae0, ps0 = p.atan_logders.ae[0], p.atan_logders.ps[0] assert ae0.energies[0], ae0.values[0] == (2.000000, 0.706765) assert ps0.energies[0], ps0.values[0] == (2.000000, 0.703758) assert ae0.energies[-1], ae0.energies[-1] == (-2.000000, 3.906687) assert ps0.energies[-1], ps0.energies[-1] == (-2.000000, 3.906357) ae1, ps1 = p.atan_logders.ae[1], p.atan_logders.ps[1] assert ae1.energies[0], ae1.values[0] == (2.000000, -2.523018) assert ps1.values[0] == -2.521334
def oncv_run(options): """ Run oncvpsp, generate djrepo file, plot results. Requires input file. """ # Select calc_type calc_type = dict(nor="non-relativistic", sr="scalar-relativistic", fr="fully-relativistic")[options.rel] # Build names of psp8 and djson files from input and relativistic mode. in_path = options.filename root, _ = os.path.splitext(in_path) # Enforce convention on output files. if options.rel == "nor": if not root.endswith("_nor"): root += "_nor" elif options.rel == "fr": if not root.endswith("_r"): root += "_r" cprint("FR calculation with input file without `_r` suffix. Will add `_r` to output files", "yellow") # Build names of output files. psp8_path = root + ".psp8" djrepo_path = root + ".djrepo" out_path = root + ".out" if os.path.exists(psp8_path): cprint("%s already exists and will be overwritten" % os.path.relpath(psp8_path), "yellow") if os.path.exists(djrepo_path): cprint("%s already exists and will be overwritten" % os.path.relpath(djrepo_path), "yellow") if os.path.exists(out_path): cprint("%s already exists and will be overwritten" % os.path.relpath(out_path), "yellow") # Build Generator and start generation. oncv_ppgen = OncvGenerator.from_file(in_path, calc_type, workdir=None) print(oncv_ppgen) print(oncv_ppgen.input_str) oncv_ppgen.start() retcode = oncv_ppgen.wait() if oncv_ppgen.status != oncv_ppgen.S_OK: cprint("oncvpsp returned %s. Exiting" % retcode, "red") return 1 # Tranfer final output file. shutil.copy(oncv_ppgen.stdout_path, out_path) # Parse the output file onc_parser = OncvOutputParser(out_path) onc_parser.scan() if not onc_parser.run_completed: cprint("oncvpsp output is not complete. Exiting", "red") return 1 # Extract psp8 files from the oncvpsp output and write it to file. s = onc_parser.get_pseudo_str() with open(psp8_path, "wt") as fh: fh.write(s) pseudo = Pseudo.from_file(psp8_path) if pseudo is None: cprint("Cannot parse psp8 file: %s" % psp8_path, "red") return 1 # Initialize and write djson file. report = DojoReport.empty_from_pseudo(pseudo, onc_parser.hints, devel=False) report.json_write() return 0
def test_scalar_relativistic(self): """Parsing the scalar-relativistic output file produced by ONCVPSPS.""" # Scalar relativistic output p = OncvOutputParser(filepath("08_O_sr.out")) p.scan(verbose=1) repr(p) str(p) assert p.run_completed assert not p.fully_relativistic assert p.calc_type == "scalar-relativistic" assert p.version == "2.1.1" assert p.atsym == "O" assert p.z == "8.00" assert p.iexc == "3" assert p.nc == 1 assert p.nv == 2 assert p.lmax == 1 # Test potentials vloc = p.potentials[-1] pl0 = {0: -7.4449470, 1: -14.6551019, -1: -9.5661177} for l, pot in p.potentials.items(): assert pot.rmesh[0], pot.rmesh[-1] == (0.0099448, 3.9647436) str(l) assert pot.values[0] == pl0[l] assert all(pot.rmesh == vloc.rmesh) # Test wavefunctions ae_wfs, ps_wfs = p.radial_wfs.ae, p.radial_wfs.ps nlk = (1, 0, None) ae10, ps10 = ae_wfs[nlk], ps_wfs[nlk] assert ae10[0] == (0.009945, -0.092997) assert ps10[0] == (0.009945, 0.015273) assert ae10[-1] == (3.964744, 0.037697) assert ps10[-1] == (3.964744, 0.037694) nlk = (2, 1, None) ae21, ps21 = ae_wfs[nlk], ps_wfs[nlk] assert ae21[0] == (0.009945, 0.001463) assert ps21[0] == (0.009945, 0.000396) # Test projectors prjs = p.projectors assert prjs[(1, 0, None)][0] == (0.009945, 0.015274) assert prjs[(2, 0, None)][0] == (0.009945, -0.009284) assert prjs[(1, 0, None)][-1] == (3.964744, 0.037697) assert prjs[(2, 0, None)][-1] == (3.964744, 0.330625) assert prjs[(1, 1, None)][0] == (0.009945, 0.000395) assert prjs[(2, 1, None)][0] == (0.009945, -0.000282) # Test convergence data c = p.ene_vs_ecut assert c[0].energies[0] == 5.019345 assert c[0].values[0] == 0.010000 assert c[0].energies[-1] == 25.317286 assert c[0].values[-1] == 0.000010 assert c[1].energies[0] == 19.469226 assert c[1].values[0] == 0.010000 # Test log derivatives ae0, ps0 = p.atan_logders.ae[0], p.atan_logders.ps[0] assert ae0.energies[0], ae0.values[0] == (2.000000, 0.706765) assert ps0.energies[0], ps0.values[0] == (2.000000, 0.703758) assert ae0.energies[-1], ae0.energies[-1] == (-2.000000, 3.906687) assert ps0.energies[-1], ps0.energies[-1] == (-2.000000, 3.906357) ae1, ps1 = p.atan_logders.ae[1], p.atan_logders.ps[1] assert ae1.energies[0], ae1.values[0] == (2.000000, -2.523018) assert ps1.values[0] == -2.521334 # Build the plotter plotter = p.make_plotter() repr(plotter) str(plotter) self._call_plotter_methods(plotter)