Exemplo n.º 1
0
def plot_gibbs_vs_pressure(system_dirs):
    return plot_gibbs_vs_pressure_simple(system_dirs)

    all_data = []
    for direc in system_dirs:
        if not os.path.isdir(direc): continue

        # Plot all the sub-directories with relax.out and phonon.dos files
        data = []
        for p_dir in os.listdir(direc):

            p_dir = direc + "/" + p_dir
            relax_file = p_dir + "/relax.out"
            dos_file = p_dir + "/phonon.dos"

            # Read results of geometry optimization (try a few possible locations)
            if not os.path.isfile(relax_file):
                relax_file = p_dir + "/primary_kpts/relax.out"
                if not os.path.isfile(relax_file):
                    relax_file = p_dir + "/aux_kpts/relax.out"
                    if not os.path.isfile(relax_file):
                        print("{0} does not exist, skipping...".format(
                            relax_file))
                        continue

            # Read phonon density of states (try a few possible locations)
            if not os.path.isfile(dos_file):
                dos_file = p_dir + "/primary_kpts/phonon.dos"
                if not os.path.isfile(dos_file):
                    dos_file = p_dir + "/aux_kpts/phonon.dos"
                    if not os.path.isfile(dos_file):
                        print(
                            "{0} does not exist, skipping...".format(dos_file))
                        continue

            # Read in phonon density of states
            omegas, pdos = parse_phonon_dos(dos_file)
            dos = np.sum(pdos, axis=0)

            # Read in thermodynamic quantities
            relax = parse_vc_relax(relax_file)
            nat = len(relax["atoms"])
            pressure = relax["pressure"]
            volume = relax["volume"] / nat
            enthalpy = relax["enthalpy"] / nat
            energy = relax["energy"] / nat

            # Normalize dos to # of phonon states
            dos = 3 * nat * dos / np.trapz(dos, x=omegas)

            # Calculate zero-point energy
            wd = [[w, d] for w, d in zip(omegas, dos) if w > 0]
            zpe = np.trapz([0.5 * w * d
                            for w, d in wd], x=[w for w, d in wd]) / nat

            # Caclulate occupational contribution to
            # phonon free energy at 300 K
            t = 300.0 / RY_TO_K
            occ = t * np.trapz([d * np.log(1 - np.exp(-w / t)) for w, d in wd],
                               x=[w for w, d in wd]) / nat

            stable = True
            for w, d in zip(omegas, dos):
                if w >= -10e-10: continue
                if d <= 10e-10: continue
                stable = False
                break

            # Save data
            data.append([volume, energy, enthalpy, zpe, occ, pressure, stable])

        if len(data) == 0:
            print("No data for " + direc)
            continue

        # Sort data by inverse volume <=> pressure
        data.sort(key=lambda d: 1 / d[0])
        all_data.append([direc, data])

    hrel = None
    erel = None
    pvrel = None

    for direc, data in all_data:

        # Get the data for this system
        vs, es, enthalpy, zpes, occs, dft_ps, ss = np.array(data).T
        pvs = dft_ps * vs * KBAR_AU3_TO_RY

        if hrel is None:
            hrel = CubicSpline(dft_ps, enthalpy)

        plt.subplot(313)
        plt.plot(dft_ps, (enthalpy - hrel(dft_ps)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("Enthalpy (meV/atom)")

        if erel is None:
            erel = CubicSpline(dft_ps, es)

        plt.subplot(312)
        plt.plot(dft_ps, (es - erel(dft_ps)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("E (meV/atom)")

        if pvrel is None:
            pvrel = CubicSpline(dft_ps, pvs)

        plt.subplot(311)
        plt.plot(dft_ps, (pvs - pvrel(dft_ps)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("PV (meV/atom)")

    plt.figure()

    # Get the data at the phonon-corrected pressures
    corrected_data = []
    for direc, data in all_data:

        # Get the data for this system
        vs, es, enthalpy, zpes, occs, dft_ps, ss = np.array(data).T

        # Only fit to the stable points
        include_unstable = False
        vfit = [v for v, s in zip(vs, ss) if s or include_unstable]
        pfit = [p for p, s in zip(dft_ps, ss) if s or include_unstable]
        efit0 = [e for e, s in zip(es + zpes, ss) if s or include_unstable]
        efit300 = [
            e for e, s in zip(es + zpes + occs, ss) if s or include_unstable
        ]

        # Fit the birch murnaghan E.O.S at 0 K
        # and calculate the gibbs as a function of corrected pressure
        e_model, p_model, par, cov = fit_birch_murnaghan(vfit,
                                                         efit0,
                                                         p_guess=pfit)
        ps_corrected_0K = p_model(vs)
        #gibbs_0K        = es + zpes + KBAR_AU3_TO_RY*ps_corrected_0K*vs
        #gibbs_0K_dft    = enthalpy + zpes

        # Fit the birch murnaghan E.O.S at 300 K
        # and calculate the gibbs as a function of corrected pressure
        e_model, p_model, par, cov = fit_birch_murnaghan(vfit,
                                                         efit300,
                                                         p_guess=pfit)
        ps_corrected_300K = p_model(vs)
        #gibbs_300K        = es + zpes + occs + KBAR_AU3_TO_RY*ps_corrected_300K*vs
        #gibbs_300K_dft    = enthalpy + zpes + occs

        # Re-evaluate quantities on the corrected-pressure grid
        es = CubicSpline(dft_ps, es)
        es0 = es(ps_corrected_0K)
        es300 = es(ps_corrected_300K)

        zpes = CubicSpline(dft_ps, zpes)
        zpes0 = zpes(ps_corrected_0K)
        zpes300 = zpes(ps_corrected_300K)

        occs = CubicSpline(dft_ps, occs)
        occs0 = occs(ps_corrected_0K)
        occs300 = occs(ps_corrected_300K)

        # Store the results
        corrected_data.append([
            direc, vs, es0, es300, zpes0, zpes300, occs0, occs300, dft_ps,
            ps_corrected_300K, ps_corrected_0K, ss
        ])

        plot_fitting_info = False
        if plot_fitting_info:

            plt.subplot(221)
            plt.plot(vs, (es + zpes - e_model(vs)) * RY_TO_MEV)
            plt.ylabel("Birch murnaghan fit error (meV)")
            plt.xlabel("Volume/atom")

            plt.subplot(222)
            plt.plot(vs,
                     ps_corrected_0K - dft_ps,
                     label="B-M pressure correction (0K)",
                     linestyle=":")
            plt.plot(vs,
                     ps_corrected_300K - dft_ps,
                     label="B-M pressure correction (300K)")
            plt.ylabel("Pressure (KBar)")
            plt.xlabel("Volume/atom")
            plt.legend()

            plt.subplot(223)
            gp300 = CubicSpline(ps_corrected_300K, gibbs_300K)
            gp0 = CubicSpline(ps_corrected_0K, gibbs_0K)
            plt.plot(dft_ps, (gp300(dft_ps) - gibbs_300K_dft) * RY_TO_MEV,
                     label="300 K")
            plt.plot(dft_ps, (gp0(dft_ps) - gibbs_0K_dft) * RY_TO_MEV,
                     label="0 K")
            plt.xlabel("Pressure (KBar)")
            plt.ylabel("Correction to \n Gibbs free energy/atom (meV)")
            plt.legend()

            plt.figure()

    frel = None
    erel = None
    zrel = None
    orel = None
    pvrel = None

    for direc, vs, es0, es300, zpe0, zpe300, occ0, occ300, dft_ps, p300, p0, ss in corrected_data:

        pvs300 = KBAR_AU3_TO_RY * p300 * vs
        pvs0 = KBAR_AU3_TO_RY * p0 * vs
        g300 = es300 + zpe300 + occ300 + pvs300
        g0 = es0 + zpe0 + pvs0

        label = direc
        if "c2m" in label: label = r"$C_2/m$"
        if "fm3m" in label: label = r"$Fm\bar{3}m$"
        if "r3m" in label: label = "$R3m$"
        if "p63mmc" in label: label = "$P6_3/mmc$"
        if "cmcm" in label: label = "$cmcm$"

        if erel is None: erel = CubicSpline(p300, es300)
        plt.subplot(511)
        plt.plot(p300, (es300 - erel(p300)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("E (meV/atom)")

        if zrel is None: zrel = CubicSpline(p300, zpe300)
        plt.subplot(512)
        plt.plot(p300, (zpe300 - zrel(p300)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("Z.P.E (meV/atom)")

        if orel is None: orel = CubicSpline(p300, occ300)
        plt.subplot(513)
        plt.plot(p300, (occ300 - orel(p300)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("Phonon occupation energy (meV/atom)")

        if pvrel is None: pvrel = CubicSpline(p300, pvs300)
        plt.subplot(514)
        plt.plot(p300, (pvs300 - pvrel(p300)) * RY_TO_MEV)
        plt.xlabel("Pressure (KBar)")
        plt.ylabel("PV(meV/atom)")

        if frel is None:
            # Plot relative to cubic spline fit of first system
            frel = CubicSpline(p300, g300)

        # Plot gibbs free energy at 300K
        plt.subplot(515)
        p = plt.plot(p300 / 10.0, (g300 - frel(p300)) * RY_TO_MEV, label=label)
        col = p[0].get_color()

        # Plot gibbs free energy at 0K
        #plt.plot(p0/10.0, (g0 - frel(p0))*RY_TO_MEV, linestyle=":", color=col)

        # Label stable points
        p300s = np.array([p for p, s in zip(p300, ss) if s])
        g300s = np.array([g for g, s in zip(g300, ss) if s])
        plt.scatter(p300s / 10.0, (g300s - frel(p300s)) * RY_TO_MEV, color=col)

        p300u = np.array([p for p, s in zip(p300, ss) if not s])
        g300u = np.array([g for g, s in zip(g300, ss) if not s])
        plt.scatter(p300u / 10.0, (g300u - frel(p300u)) * RY_TO_MEV,
                    color=col,
                    marker="x")

    plt.xlabel("Pressure (GPa)")
    plt.ylabel("Gibbs free energy\n(meV/atom, relative)")
    plt.legend()
    plt.show()
Exemplo n.º 2
0
def plot_gibbs_vs_pressure_simple(system_dirs):
    plt.rc("text", usetex=True)

    all_data = []
    for direc in system_dirs:
        if not os.path.isdir(direc): continue

        # Plot all the sub-directories with relax.out and phonon.dos files
        data = []
        for p_dir in os.listdir(direc):

            p_dir = direc + "/" + p_dir
            relax_file = p_dir + "/relax.out"
            dos_file = p_dir + "/phonon.dos"

            # Read results of geometry optimization (try a few possible locations)
            if not os.path.isfile(relax_file):
                relax_file = p_dir + "/primary_kpts/relax.out"
                if not os.path.isfile(relax_file):
                    relax_file = p_dir + "/aux_kpts/relax.out"
                    if not os.path.isfile(relax_file):
                        print("{0} does not exist, skipping...".format(
                            relax_file))
                        continue

            # Read phonon density of states (try a few possible locations)
            if not os.path.isfile(dos_file):
                dos_file = p_dir + "/primary_kpts/phonon.dos"
                if not os.path.isfile(dos_file):
                    dos_file = p_dir + "/aux_kpts/phonon.dos"
                    if not os.path.isfile(dos_file):
                        print(
                            "{0} does not exist, skipping...".format(dos_file))
                        continue

            # Read in phonon density of states
            omegas, pdos = parse_phonon_dos(dos_file)
            dos = np.sum(pdos, axis=0)

            # Read in thermodynamic quantities
            relax = parse_vc_relax(relax_file)
            nat = len(relax["atoms"])
            pressure = relax["pressure"]
            volume = relax["volume"] / nat
            enthalpy = relax["enthalpy"] / nat
            energy = relax["energy"] / nat

            # Normalize dos to # of phonon states
            dos = 3 * nat * dos / np.trapz(dos, x=omegas)

            # Calculate zero-point energy
            wd = [[w, d] for w, d in zip(omegas, dos) if w > 0]
            zpe = np.trapz([0.5 * w * d
                            for w, d in wd], x=[w for w, d in wd]) / nat

            # Caclulate occupational contribution to
            # phonon free energy at 300 K
            t = 300.0 / RY_TO_K
            occ = t * np.trapz([d * np.log(1 - np.exp(-w / t)) for w, d in wd],
                               x=[w for w, d in wd]) / nat

            stable = True
            for w, d in zip(omegas, dos):
                if w >= -10e-10: continue
                if d <= 10e-10: continue
                stable = False
                break

            # Calculate Helmholtz free energy
            f0 = energy + zpe
            f300 = energy + zpe + occ

            # Save data
            data.append([volume, f0, f300, pressure, enthalpy, energy, stable])

        if len(data) == 0:
            print("No data for " + direc)
            continue

        # Sort data by inverse volume <=> pressure
        data.sort(key=lambda d: 1 / d[0])
        all_data.append([direc, data])

    grel300 = None
    hrel = None
    greldft = None
    ereldft = None
    fig, axes = plt.subplots(2, 2)

    for direc, data in all_data:
        v, f0, f300, p_dft, h_dft, e_dft, s = np.array(data).T

        if len(h_dft) == 1:
            pv = KBAR_AU3_TO_RY * p_dft[0] * v[0]
            print(direc, f300, f300 + pv, pv)
            continue

        if hrel is None: hrel = CubicSpline(p_dft, h_dft)
        axes[0, 0].plot(p_dft, (h_dft - hrel(p_dft)) * RY_TO_MEV)
        axes[0, 0].set_xlabel(r"$P_{DFT}$ (KBar)")
        axes[0, 0].set_ylabel(r"Enthalpy (meV/atom)")

        use_unstable = True
        v_fit = [i for i, j in zip(v, s) if j or use_unstable]
        f0_fit = [i for i, j in zip(f0, s) if j or use_unstable]
        f300_fit = [i for i, j in zip(f300, s) if j or use_unstable]
        p_dft_fit = [i for i, j in zip(p_dft, s) if j or use_unstable]

        label = direc
        if "fm3m" in label: label = r"$Fm\bar{3}m$"
        elif "c2m" in label: label = r"$C_2/m$"
        elif "p63" in label: label = r"$P6_3/mmc$"
        elif "cmcm" in label: label = r"$Cmcm$"

        e_model, p_model, par, cov = fit_birch_murnaghan(v_fit,
                                                         f300_fit,
                                                         p_guess=p_dft_fit)
        p300 = p_model(v)
        g300 = f300 + p300 * v * KBAR_AU3_TO_RY
        if grel300 is None: grel300 = CubicSpline(p300, g300)
        p = axes[0, 1].plot(p300, (g300 - grel300(p300)) * RY_TO_MEV,
                            label=label)
        plt.legend()
        col = p[0].get_color()

        gs = [i for i, j in zip(g300, s) if j]
        ps = [i for i, j in zip(p300, s) if j]
        axes[0, 1].scatter(ps, (gs - grel300(ps)) * RY_TO_MEV, color=col)

        gu = [i for i, j in zip(g300, s) if not j]
        pu = [i for i, j in zip(p300, s) if not j]
        axes[0, 1].scatter(pu, (gu - grel300(pu)) * RY_TO_MEV,
                           color=col,
                           marker="x")

        e_model, p_model, par, cov = fit_birch_murnaghan(v_fit,
                                                         f0_fit,
                                                         p_guess=p_dft_fit)
        p0 = p_model(v)
        g0 = f0 + p0 * v * KBAR_AU3_TO_RY
        axes[0, 1].plot(p0, (g0 - grel300(p0)) * RY_TO_MEV,
                        linestyle=":",
                        color=col)
        axes[0, 1].set_xlabel(r"$P$ (KBar)")
        axes[0, 1].set_ylabel(r"Gibbs free energy (meV/atom)")
        axes[0, 1].legend()

        g_dft300 = f300 + p_dft * v * KBAR_AU3_TO_RY
        if greldft is None: greldft = CubicSpline(p_dft, g_dft300)
        axes[1, 0].plot(p_dft, (g_dft300 - greldft(p_dft)) * RY_TO_MEV)
        axes[1, 0].set_xlabel(r"$P_{DFT}$ (KBar)")
        axes[1, 0].set_ylabel(r"Gibbs free energy (DFT, meV/atom)")

        if ereldft is None: ereldft = CubicSpline(p_dft, e_dft)
        axes[1, 1].plot(p_dft, (e_dft - ereldft(p_dft)) * RY_TO_MEV)
        axes[1, 1].set_xlabel(r"$P_{DFT}$ (KBar)")
        axes[1, 1].set_ylabel(r"$E_{DFT}$ (meV/atom)")

    plt.show()
Exemplo n.º 3
0
def plot_tc_vs_p(direc,
                 show=True,
                 plot_unstable=False,
                 plot_allen=False,
                 plot_double_delta_info=False):

    # Use LaTeX
    plt.rc("text", usetex=True)

    if not os.path.isdir(direc):
        print("{0} is not a directory, skipping...".format(direc))
        return

    # Check to see if we're using a multi-grid scheme
    for pdir in os.listdir(direc):
        if not os.path.isdir(direc + "/" + pdir): continue
        for subdir in os.listdir(direc + "/" + pdir):
            if "aux_kpts" in subdir or "primary_kpts" in subdir:
                print("Using multi-grid scheme for " + direc)
                return plot_tc_vs_p_aux_primary(
                    direc,
                    show=show,
                    plot_unstable=plot_unstable,
                    plot_allen=plot_allen,
                    plot_double_delta_info=plot_double_delta_info)

    print("Using single-grid scheme for " + direc)

    # Collect data for different pressures in this directory
    data = []
    for pdir in os.listdir(direc):

        # Check this is a directory
        if not os.path.isdir(direc + "/" + pdir):
            continue

        # Get the pressure from the relax.out file
        relax_file = direc + "/" + pdir + "/relax.out"
        if not os.path.isfile(relax_file):
            print(relax_file + " does not exist, skipping...")
            continue

        relax = parse_vc_relax(relax_file)
        pressure = relax["pressure"]

        # Check if the a2F.tc file exists
        a2f_file = direc + "/" + pdir + "/" + get_best_a2f_dos_tc(direc + "/" +
                                                                  pdir)
        if not os.path.isfile(a2f_file):
            print(a2f_file + " does not exist, skipping...")
            continue

        # Read the a2F.tc file
        with open(a2f_file) as f:
            lines = f.read().split("\n")

        # Check if the structure is unstable
        unstable = lines[10].split("#")[0].strip() == "True"
        if unstable and (not plot_unstable):
            print(direc + "/" + pdir, "unstable")
            continue

        # Read in mus and corresponding tcs
        mu1, mu2 = [float(l.split("=")[-1]) for l in [lines[0], lines[5]]]
        tc, tcad, tc2, tcad2 = [
            float(l.split("#")[0])
            for l in [lines[1], lines[2], lines[6], lines[7]]
        ]

        # Record the data
        data.append([pressure, tc, tc2, tcad, tcad2])

    if len(data) == 0:
        print("No data for " + direc + " skipping...")
        return

    # Transppose data into arrays for pressure, tc, tc2 ...
    data.sort()
    data = np.array(data).T
    data[0] /= 10  # Convert pressure from Kbar to GPa

    # Format label as math
    label = convert_common_labels(direc)

    # Plot Eliashberg Tc
    if plot_allen: plt.subplot(211)
    p = plt.plot(data[0], 0.5 * (data[1] + data[2]), linestyle="none")
    color = p[0].get_color()
    plt.fill_between(data[0],
                     data[1],
                     data[2],
                     alpha=0.5,
                     label=label,
                     color=color)
    plt.legend()
    plt.xlabel("Pressure (GPa)")
    plt.ylabel("$T_C$ (K)\nEliashberg, $\mu^* \in [{0},{1}]$".format(mu1, mu2))

    # Plot Allen-Dynes Tc
    if plot_allen:
        plt.subplot(212)
        plt.fill_between(data[0],
                         data[3],
                         data[4],
                         alpha=0.5,
                         label=label,
                         color=color)
        plt.legend()
        plt.xlabel("Pressure (GPa)")
        plt.ylabel("$T_C$ (K)\nAllen-Dynes, $\mu^* \in [{0},{1}]$".format(
            mu1, mu2))

    if show: plt.show()
Exemplo n.º 4
0
def run(parameters, dry=False, aux_kpts=False):

    # Open the output file
    parameters["out_file"] = open("run.out", "w", 1)
    parameters["out_file"].write("Dryrun   : {0}\n".format(dry))
    parameters["out_file"].write("Aux kpts : {0}\n".format(aux_kpts))
    max_l = str(max([len(p) for p in parameters]))
    for p in parameters:
        fs = "{0:" + max_l + "." + max_l + "} : {1}\n"
        parameters["out_file"].write(fs.format(p, parameters[p]))

    # Run with the auxilliary kpt grid
    if aux_kpts:
        parameters["out_file"].write("Running auxillary kpoint grid...\n")
        parameters["kpts_per_qpt"] = parameters["aux_kpts"]

    # Reduce to primitive description
    parameters = reduce_to_primitive(parameters)

    # Caclulate relaxed geometry
    create_relax_in(parameters)
    run_qe("pw.x", "relax", parameters, dry=dry)
    if not dry:
        relax_data = parse_vc_relax("relax.out")
        parameters["lattice"] = relax_data["lattice"]
        parameters["atoms"] = relax_data["atoms"]

    # Stop here if we're just doing relaxations
    if parameters["relax_only"]: return

    # Run SCF with the new geometry
    create_scf_in(parameters)
    run_qe("pw.x", "scf", parameters, dry=dry)

    if parameters["irrep_group_size"] > 0:

        # Run elec-phonon prep calculation
        create_elph_in("elph_prep", parameters, irr_range=[0, 0])
        run_qe("ph.x", "elph_prep", parameters, dry=dry, check_done=False)

        # Count q-points
        qpoint_count = 0
        with open("elph_prep.out") as elph_prep_f:
            for line in elph_prep_f:
                if "q-points):" in line:
                    qpoint_count = int(
                        line.split("q-points")[0].replace("(", ""))
                    break

        parameters["out_file"].write(
            "q-points to calculate: {0}\n".format(qpoint_count))

        # Count irreps
        irrep_counts = {}
        for i in range(1, qpoint_count + 1):
            with open("_ph0/pwscf.phsave/patterns.{0}.xml".format(
                    i)) as pat_file:
                next_line = False
                for l in pat_file:
                    if next_line:
                        irrep_counts[i] = int(l)
                        break
                    if "NUMBER_IRR_REP" in l:
                        next_line = True

        for i in irrep_counts:
            fs = "    irreducible representations for q-point {0}: {1}\n"
            parameters["out_file"].write(fs.format(i, irrep_counts[i]))

        gs = int(parameters["irrep_group_size"])

        # Run elec-phonon calculations for each irrep group
        for q_point in range(1, qpoint_count + 1):
            for irr in range(1, irrep_counts[q_point] + 1, gs):
                name = "elph_{0}_{1}_{2}".format(q_point, irr, irr + gs - 1)
                create_elph_in(
                    name,
                    parameters,
                    irr_range=[irr,
                               min(irr + gs - 1, irrep_counts[q_point])],
                    q_range=[q_point, q_point])
                run_qe("ph.x", name, parameters, dry=dry)

        # Collect phonon results/diagonalise dynamical matrix
        create_elph_in("elph_collect", parameters, force_recover=True)
        run_qe("ph.x", "elph_collect", parameters, dry=dry)

    else:

        # Just calculate all electron-phonon stuff in a single step
        create_elph_in("elph_all", parameters)
        run_qe("ph.x", "elph_all", parameters, dry=dry)

    # Delete phonon files after successful elph run
    if parameters["disk_usage"] == "minimal":
        os.system("rm -r _ph0")

    # Convert dynamcial matricies etc to real space
    create_q2r_in(parameters)
    run_qe("q2r.x", "q2r", parameters, dry=dry)

    # Caclulate the phonon density of states
    create_ph_dos_in(parameters)
    run_qe("matdyn.x", "ph_dos", parameters, dry=dry)

    # Extract the eigenvalues
    create_extract_evals_in(parameters)
    run_qe("bands.x", "extract_evals", parameters, dry=dry)

    # Only do the following if we have a brillouin zone path
    if "bz_path" in parameters:

        # Caclulate the phonon bandstructure
        create_ph_bands_in(parameters)
        run_qe("matdyn.x", "ph_bands", parameters, dry=dry)

        # Caculate the electronic bandstructure
        create_bands_in(parameters)
        run_qe("pw.x", "bands", parameters, dry=dry)

        # Re-order bands and calc band-related things
        create_bands_x_in(parameters)
        run_qe("bands.x", "bands.x", parameters, dry=dry)
Exemplo n.º 5
0
def plot_tc_vs_p_aux_primary(sys_direc,
                             show=True,
                             plot_unstable=False,
                             plot_double_delta_info=False,
                             plot_allen=False):

    # Plot Tc vs pressure for all of the pressure directories in
    # sys_direc, using primary and auxillary k-point grids to
    # estimate the correct double-delta smearing

    if not os.path.isdir(sys_direc):
        print("{0} is not a directory, skipping...".format(sys_direc))
        return

    sys_data = []

    # Loop over pressure directories
    for pdir in os.listdir(sys_direc):
        pdir = sys_direc + "/" + pdir
        if not os.path.isdir(pdir): continue

        grids_data = []
        i_grid_best = 0

        # Look over k-point grid directories
        for grid_dir in os.listdir(pdir):
            grid_dir = pdir + "/" + grid_dir
            if not os.path.isdir(grid_dir): continue

            if "primary" in grid_dir:
                i_grid_best = len(grids_data)

            relax = None
            tc_data = []

            # Loop over files
            for filename in os.listdir(grid_dir):
                filename = grid_dir + "/" + filename

                if filename.endswith(".tc"):

                    # Parse tc information
                    isig = int(filename.split(".dos")[-1].split(".")[0])
                    with open(filename) as f:
                        lines = f.read().split("\n")
                        tc1 = float(lines[1].split("#")[0])
                        tc2 = float(lines[6].split("#")[0])

                    tc_data.append([isig, tc1, tc2])

                elif filename.endswith("relax.out"):

                    # Parse vc-relax output
                    relax = parse_vc_relax(filename)

            if relax is None:
                print("Could not parse relaxation data in " + grid_dir)
                continue

            if len(tc_data) == 0:
                print("No Tc information found in " + grid_dir)
                continue

            tc_data.sort()
            sigma, tc1, tc2 = np.array(tc_data).T

            if plot_double_delta_info:
                label = "Kpoint grid {0}".format(len(grids_data) + 1)

                plt.subplot(221)
                plt.plot(sigma, tc1, label=label)
                plt.xlabel("$\sigma (Ry)$")
                plt.ylabel("$T_C (K)$, Eliashberg\n$\mu^* = 0.1$")

                plt.subplot(222)
                plt.plot(sigma, tc2, label=label)
                plt.xlabel("$\sigma (Ry)$")
                plt.ylabel("$T_C (K)$, Eliashberg\n$\mu^* = 0.15$")

            grids_data.append({
                "relax": relax,
                "sigma": sigma,
                "tc1": tc1,
                "tc2": tc2,
                "pressure": relax["pressure"]
            })

        if len(grids_data) < 2:
            print("Less than 2 k-point grids found in " + pdir +
                  ", skipping...")
            continue

        if len(grids_data[0]["tc1"]) != len(grids_data[1]["tc1"]):
            raise Exception("Mismatched grid sizes in " + pdir)

        # Evaluate the difference in Tc(sigma) between
        # the two grids and use this to work out what the
        # best smearing value is
        sigma = grids_data[0]["sigma"]
        dtc1 = list(abs(grids_data[0]["tc1"] - grids_data[1]["tc1"]))
        dtc2 = list(abs(grids_data[0]["tc2"] - grids_data[1]["tc2"]))
        dtc1 -= dtc1[-1]
        dtc2 -= dtc2[-1]

        delta_t_mu = np.mean(grids_data[0]["tc1"] - grids_data[0]["tc2"])

        # Find the best sigma <=> j by backtracking from
        # the largest smearing until the difference between
        # the two k-point grid reaches 10 K
        keep = lambda dt: dt < 10

        for jbest1 in range(len(dtc1) - 1, -1, -1):
            dt = dtc1[jbest1]
            if not keep(dt):
                jbest1 += 1
                break

        for jbest2 in range(len(dtc2) - 1, -1, -1):
            dt = dtc2[jbest2]
            if not keep(dt):
                jbest2 += 1
                break

        tbest1 = grids_data[i_grid_best]["tc1"][jbest1]
        tbest2 = grids_data[i_grid_best]["tc2"][jbest2]

        tcmax = max(tbest1, tbest2)
        tcmin = min(tbest1, tbest2)
        tcav = 0.5 * (tcmax + tcmin)

        pressure = np.mean([gd["pressure"] for gd in grids_data])
        dpressure = np.std([gd["pressure"] for gd in grids_data])
        sys_data.append([pressure, tcmin, tcmax])

        if plot_double_delta_info:
            plt.suptitle(r"$T_C = {0:8.2f} \pm {1:8.2f}$".format(
                tcav, (tcmax - tcmin) / 2.0))

            plt.subplot(223)
            plt.plot(sigma, dtc1)
            plt.xlabel("$\sigma (Ry)$")
            plt.ylabel("$\Delta T_C (K)$, Eliashberg\n$\mu^* = 0.1$")
            plt.axvline(sigma[jbest1], color="green", label="Best $\sigma$")
            plt.legend()

            plt.subplot(221)
            plt.axvline(sigma[jbest1], color="green", label="Best $\sigma$")
            label = "Best $T_C \in [{0:8.2f}, {1:8.2f}]$"
            label = label.format(tcmin1, tcmax1)
            plt.axhspan(tcmin1, tcmax1, color="green", alpha=0.5, label=label)
            plt.legend()

            plt.subplot(224)
            plt.plot(sigma, dtc2)
            plt.xlabel("$\sigma (Ry)$")
            plt.ylabel("$\Delta T_C (K)$, Eliashberg\n$\mu^* = 0.15$")
            plt.axvline(sigma[jbest2], color="green", label="Best $\sigma$")
            plt.legend()

            plt.subplot(222)
            plt.axvline(sigma[jbest2], color="green", label="Best $\sigma$")
            label = "Best $T_C \in [{0:8.2f}, {1:8.2f}]$"
            label = label.format(tcmin2, tcmax2)
            plt.axhspan(tcmin2, tcmax2, color="green", alpha=0.5, label=label)
            plt.legend()

            plt.tight_layout()
            plt.show()

    if len(sys_data) == 0:
        print("No data found for " + sys_direc)
        return

    sys_data.sort()
    pressure, tmin, tmax = np.array(sys_data).T
    label = convert_common_labels(sys_direc)
    plt.fill_between(pressure / 10.0, tmin, tmax, alpha=0.5, label=label)
    plt.ylabel("$T_C$ (K, Eliashberg)\n" + r"$\mu^* \in [0.1, 0.15]$")
    plt.xlabel("Pressure (GPa)")
    plt.legend()
    if show: plt.show()