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