예제 #1
0
def supercell_calc_results(args):

    if args.print:
        print(SupercellCalcResults.load_json(args.json))
        return

    if args.defect_center:
        if len(args.defect_center) != 1 and len(args.defect_center) != 3:
            raise ValueError("Length of the defect center is neither 1 or 3")
        results = SupercellCalcResults.load_json(args.json)
        results.defect_center = args.defect_center
        results.to_json_file(filename=args.json)
        return

    if args.dir_all:
        dirs = glob('*[0-9]/')
        dirs.insert(0, "perfect/")
    else:
        dirs = args.dirs

    for d in dirs:
        if os.path.isdir(d):
            logger.info(f"Parsing data in {d} ...")

            if d in ["perfect", "perfect/"]:
                try:
                    dft_results = SupercellCalcResults.from_vasp_files(
                        directory_path=d,
                        vasprun=args.vasprun,
                        contcar=args.contcar,
                        procar=args.procar,
                        outcar=args.outcar)
                except IOError:
                    raise IOError("Parsing data in perfect failed.")
            else:
                try:
                    de = DefectEntry.load_json(
                        Path(d) / args.defect_entry_name)
                    dft_results = SupercellCalcResults.from_vasp_files(
                        directory_path=d,
                        vasprun=args.vasprun,
                        contcar=args.contcar,
                        outcar=args.outcar,
                        procar=args.procar,
                        cutoff=args.cutoff,
                        defect_entry=de,
                        defect_symprec=args.defect_symprec,
                        angle_tolerance=args.angle_tolerance)
                except IOError as e:
                    logger.warning(f"Parsing data in {d} failed.")
                    logger.warning(e)
                    continue

            dft_results.to_json_file(filename=Path(d) / "dft_results.json")
        else:
            logger.warning(f"{d} does not exist, so nothing is done.")
예제 #2
0
def vertical_transition_input_maker(args):
    if abs(args.additional_charge) != 1:
        raise ValueError(f"{args.additional_charge} is invalid.")

    initial_dirname = Path(args.initial_dir_name)
    de_filename = initial_dirname / "defect_entry.json"
    de = DefectEntry.load_json(de_filename)
    src_filename = initial_dirname / "dft_results.json"
    src = SupercellCalcResults.load_json(src_filename)

    new_charge = de.charge + args.additional_charge
    vis = ViseInputSet.from_prev_calc(initial_dirname,
                                      user_incar_settings={"NSW": 0},
                                      parse_calc_results=False,
                                      contcar_filename=args.contcar,
                                      charge=new_charge)

    de.charge += args.additional_charge
    de.initial_structure = src.final_structure
    de.perturbed_initial_structure = src.final_structure
    de.initial_site_symmetry = src.site_symmetry
    # FIX MAGNETIZATION?
    new_dirname = initial_dirname / f"add_charge_{args.additional_charge}"
    make_dir(str(new_dirname),
             vis,
             force_overwrite=False,
             defect_entry_obj=de,
             add_neighbor=False)
    new_de_filename = new_dirname / "defect_entry.json"
    de.to_json_file(new_de_filename)
예제 #3
0
def vertical_transition_energy(args):

    initial_dir = Path(args.initial_dir)
    initial_calc_results = \
        SupercellCalcResults.load_json(initial_dir / "dft_results.json")
    final_dir = Path(args.dir)
    final_calc_results = \
        SupercellCalcResults.load_json(final_dir / "dft_results.json")
    unitcell = UnitcellCalcResults.load_json(args.unitcell_json)

    if args.print:
        vtec = VerticalTransitionEnergyCorrection.load_json(args.json)
        vtec.plot_potential()
        print(vtec)
        if vtec.additional_charge == 1:
            cbm = unitcell.band_edge[1]
            print(f"CBM position (eV): {cbm}")
            band_edge_related_energy = cbm

        else:
            vbm = unitcell.band_edge[0]
            print(f"VBM position (eV): {vbm}")
            band_edge_related_energy = -vbm

        vte_wo_corr = (final_calc_results.total_energy -
                       initial_calc_results.total_energy +
                       band_edge_related_energy)
        vte = vte_wo_corr + vtec.correction_energy
        print(f"Vertical transition energy w/o correction (eV): {vte_wo_corr}")
        print(f"Vertical transition energy w/  correction (eV): {vte}")
        return

    dielectric_tensor = unitcell.total_dielectric_tensor
    static_dielectric_tensor = unitcell.static_dielectric_tensor

    initial_efnv = \
        ExtendedFnvCorrection.load_json(initial_dir / "correction.json")
    initial_calc_results = \
        SupercellCalcResults.load_json(initial_dir / "dft_results.json")

    final_defect_entry = DefectEntry.load_json(final_dir / "defect_entry.json")

    c = VerticalTransitionEnergyCorrection.from_files(
        dielectric_tensor, static_dielectric_tensor, initial_efnv,
        initial_calc_results, final_defect_entry, final_calc_results)
    c.to_json_file(args.json)
    print(c)
예제 #4
0
def defects(args):

    if args.band_edge:
        if args.band_edge[0] == "up":
            spin = Spin.up
        elif args.band_edge[0] == "down":
            spin = Spin.down
        else:
            raise ValueError(
                "band edge is inadequate (e.g. -be up no_in_gap).")
        state = args.band_edge[1]
        defect = Defect.load_json(args.json)
        defect.set_band_edge_state(spin=spin, state=state)
        defect.to_json_file(args.json)
        return True

    try:
        perfect = SupercellCalcResults.load_json(args.perfect)
    except FileNotFoundError:
        print(f"{args.perfect} not found.")
        raise

    defects_dirs = args.defect_dirs or glob('*[0-9]/')
    for d in defects_dirs:
        filename = os.path.join(d, args.json)
        if args.diagnose:
            print(d.rjust(12), end="  ")
            try:
                print(Defect.load_json(filename).diagnose)
            except FileNotFoundError:
                logger.warning("No supercell results file.")
            except Exception as e:
                logger.warning(f"An error {e} is caught.")
            continue

        logger.info(f"parsing directory {d}...")
        files = [args.defect_entry, args.dft_results, args.correction]
        classes = [DefectEntry, SupercellCalcResults, ExtendedFnvCorrection]
        input_objects = generate_objects_from_json_files(d,
                                                         files,
                                                         classes,
                                                         raise_error=False)
        if input_objects:
            try:
                defect = Defect.from_objects(defect_entry=input_objects[0],
                                             dft_results=input_objects[1],
                                             perfect_dft_results=perfect,
                                             correction=input_objects[2])
                defect.to_json_file(filename)
            except StructureError:
                logger.warning(f"defect.json is not generated in {d}.")

        else:
            logger.warning(f"Generating {filename} failed.")
            continue
    def setUp(self) -> None:
        unitcell = UnitcellCalcResults.load_json(parent / "MgO_unitcell.json")
        dielectric_tensor = unitcell.total_dielectric_tensor
        static_dielectric_tensor = unitcell.static_dielectric_tensor
        initial_efnv_cor = ExtendedFnvCorrection.load_json(
            parent / "MgO_Va_O_1_correction.json")
        initial_calc_results = SupercellCalcResults.load_json(
            parent / "MgO_Va_O_1_dft_results.json")
        final_defect_entry = DefectEntry.load_json(
            parent / "MgO_Va_O_1-added_defect_entry.json")
        final_calc_results = SupercellCalcResults.load_json(
            parent / "MgO_Va_O_1-added_dft_results.json")

        self.vertical_correction = \
            VerticalTransitionEnergyCorrection.from_files(
                dielectric_tensor,
                static_dielectric_tensor,
                initial_efnv_cor,
                initial_calc_results,
                final_defect_entry,
                final_calc_results,
                8)
예제 #6
0
def plot_energy(args):

    if args.reload_defects:
        os.remove(args.energies)

    try:
        defect_energies = DefectEnergies.load_json(args.energies)
    except FileNotFoundError:
        unitcell = UnitcellCalcResults.load_json(args.unitcell)
        perfect = SupercellCalcResults.load_json(args.perfect)

        defects_dirs = args.defect_dirs or glob('*[0-9]/')

        defect_list = []
        for d in defects_dirs:
            filename = Path(d) / 'defect.json'
            logger.info(f"parsing directory {filename}...")
            try:
                defect_list.append(Defect.load_json(filename))
            except FileNotFoundError:
                logger.warning(f"Parsing {filename} failed.")
                continue

        chem_pot = ChemPotDiag.load_json(args.chem_pot_json)

        # First construct DefectEnergies class object.
        defect_energies = \
            DefectEnergies.from_objects(unitcell=unitcell,
                                        perfect=perfect,
                                        defects=defect_list,
                                        chem_pot=chem_pot,
                                        chem_pot_label=args.chem_pot_label,
                                        filtering_words=args.filtering,
                                        system=args.name)

    if args.print:
        print(defect_energies)
        return

    defect_energies.to_json_file(filename=args.energies)

    # if args.concentration:
    #     defect_concentration = \
    #         DefectConcentration.from_defect_energies(
    #             energies=energies,
    #             temperature=args.temperature[0],
    #             unitcell=unitcell,
    #             num_sites_filename=args.num_site_file)

    #  #     if len(args.temperature) == 2:
    #         defect_concentration = \
    #             DefectConcentration.from_defect_energies(
    #                 energies=energies,
    #                 temperature=args.temperature[1],
    #                 unitcell=unitcell,
    #                 num_sites_filename=args.num_site_file,
    #                 previous_concentration=defect_concentration)
    # else:
    #         defect_concentration = None

    # plt = defect_energies.plot_energy(filtering_words=args.filtering,
    #                                   x_range=args.x_range,
    #                                   y_range=args.y_range,
    #                                   show_transition_levels=args.show_tl,
    #                                   show_all_energies=args.show_all)
    plt = defect_energies.plot_energy(
        x_range=args.x_range,
        y_range=args.y_range,
        show_transition_levels=args.show_transition_level,
        show_all_energies=args.show_all)

    if args.save_file:
        plt.savefig(args.save_file, format="pdf", transparent=True)
    else:
        plt.show()
예제 #7
0
def efnv_correction(args):
    if args.print:
        print(ExtendedFnvCorrection.load_json(args.json_file))
        return

    dirs = glob('*[0-9]/') if args.dir_all else args.dirs

    if args.plot_potential:
        for directory in dirs:
            d = Path(directory)
            c = ExtendedFnvCorrection.load_json(d / "correction.json")
            c.plot_potential(d / "potential.pdf", args.y_range)
        return

    if args.nocorr:
        for directory in dirs:
            c = ManualCorrection(manual_correction_energy=args.manual)
            c.to_json_file(Path(directory) / "correction.json")
        return

    try:
        ucr = UnitcellCalcResults.load_json(args.unitcell_json)
        dielectric_tensor = ucr.total_dielectric_tensor
    except IOError:
        raise FileNotFoundError("JSON for the unitcell info is not found.")

    try:
        perfect_dft_data = SupercellCalcResults.load_json(args.perfect_json)
    except IOError:
        raise FileNotFoundError("JSON for the perfect supercell is not found.")

    # Ewald parameter related
    if not Path(args.ewald_json).is_file():
        logger.info("optimizing ewald...")
        ewald = Ewald.from_optimization(
            structure=perfect_dft_data.final_structure,
            dielectric_tensor=dielectric_tensor,
            initial_ewald_param=args.ewald_initial_param,
            convergence=args.ewald_convergence,
            prod_cutoff_fwhm=args.ewald_accuracy)
        ewald.to_json_file(args.ewald_json)

    for directory in dirs:
        d = Path(directory)
        json_to_make = d / "correction.json"

        if json_to_make.exists() and not args.force_overwrite:
            logger.warning(f"{json_to_make} already exists, so nothing done.")
            continue

        logger.info(f"correcting {directory} ...")
        entry = DefectEntry.load_json(d / "defect_entry.json")
        try:
            defect_dft_data = \
                SupercellCalcResults.load_json(d / "dft_results.json")
        except IOError:
            logger.warning(f"dft_results.json in {directory} does not exist.")
            continue

        c = ExtendedFnvCorrection. \
            compute_correction(defect_entry=entry,
                               defect_dft=defect_dft_data,
                               perfect_dft=perfect_dft_data,
                               dielectric_tensor=dielectric_tensor,
                               defect_center=args.defect_center,
                               ewald=args.ewald_json)

        c.plot_potential(d / "potential.pdf", args.y_range)
        c.to_json_file(d / "correction.json")
예제 #8
0
 def test_json(self):
     tmp_file = tempfile.NamedTemporaryFile()
     self.mgo_va_o1_2.to_json_file(tmp_file.name)
     actual = SupercellCalcResults.load_json(tmp_file.name)
     np.testing.assert_equal(actual.eigenvalues[Spin.up],
                             self.mgo_va_o1_2.eigenvalues[Spin.up])