Esempio n. 1
0
def run():
    log = "logs/05_dmso_hf_orca_freq.out"
    qc = QCData(log, point_group="c1")
    T = 298.15
    thermo = thermochemistry(qc, T)
    print_thermo_results(thermo)

    log = "logs/04_dmso_hf_freq.log"
    qc = QCData(log, point_group="c1")
    T = 298.15
    thermo = thermochemistry(qc, T)
    print_thermo_results(thermo)
Esempio n. 2
0
def run():
    args = parse_args(sys.argv[1:])

    inp_fn = args.inp_fn
    T = args.temp
    pressure = args.pressure
    point_group = args.pg
    scale = args.scale
    vib_kind = args.vibs

    print(f"Using {vib_kind.upper()}-approach for vibrational entropies.")

    qc = QCData(inp_fn, point_group=point_group, scale_factor=scale)
    if args.temps:
        temps = np.linspace(*args.temps)
    else:
        temps = [
            T,
        ]
    thermos = [
        thermochemistry(qc, T, pressure=pressure, kind=vib_kind) for T in temps
    ]

    print_thermos(thermos)
    dump_thermos(inp_fn, thermos)
Esempio n. 3
0
def test_thermoanalysis(this_dir):
    hess_fn = this_dir / "h2o_hessian.h5"
    with h5py.File(hess_fn, "r") as handle:
        masses = handle["masses"][:]
        vibfreqs = handle["vibfreqs"][:]
        coords3d = handle["coords3d"][:]
        energy = handle.attrs["energy"]
        mult = handle.attrs["mult"]

    thermo_dict = {
        "masses": masses,
        "vibfreqs": vibfreqs,
        "coords3d": coords3d,
        "energy": energy,
        "mult": mult,
    }

    from thermoanalysis.QCData import QCData
    from thermoanalysis.thermo import thermochemistry

    qcd = QCData(thermo_dict)
    thermo = thermochemistry(qcd, temperature=298.15)

    assert thermo.M == pytest.approx(18.01528)
    assert thermo.dG == pytest.approx(0.002267160)
Esempio n. 4
0
def calculate_potential(result_1, result_2, T=298.15):
    qcd_1 = redox_result_to_qcdata(result_1)
    qcd_2 = redox_result_to_qcdata(result_2)

    thermo_1 = thermochemistry(qcd_1, temperature=T)
    thermo_2 = thermochemistry(qcd_2, temperature=T)

    DG_solv_neut = result_1.dG_solv
    DG_solv_oxd = result_2.dG_solv
    print(f"ΔG_solv_neut = {DG_solv_neut: >8.6f} E_h")
    print(f"ΔG_solv_oxd  = {DG_solv_oxd: >8.6f} E_h")

    DG_ox_g = thermo_2.G - thermo_1.G
    print(f"ΔG_oxd_gas  = {DG_ox_g: >8.6f} E_h")
    DG_ox_solv = DG_ox_g + DG_solv_oxd - DG_solv_neut
    print(f"ΔG_oxd_solv  = {DG_ox_solv: >8.6f} E_h")

    n = abs(result_1.charge - result_2.charge)
    print(f"Δelectron(s) = {n}")
    # To Joule mol⁻¹
    redox_pot = DG_ox_solv * AU2J * NA / (n * F)
    print(f"E^0/+ = {redox_pot:.2f} V")

    return redox_pot
def test_orca_thermochemistry():
    log = str(THIS_DIR / "logs/05_dmso_hf_orca_freq.out")
    qc = QCData(log, point_group="c1")
    T = 298.15
    thermo = thermochemistry(qc, T, kind="qrrho")

    zpe_ref = 0.08393782
    assert thermo.ZPE == approx(zpe_ref)

    u_trans_ref = 0.00141627
    assert thermo.U_trans == approx(u_trans_ref, rel=1e-5)
    u_rot_ref = 0.00141627
    assert thermo.U_rot == approx(u_rot_ref, rel=1e-5)

    s_el_ref = 0.
    assert thermo.S_el == approx(s_el_ref)
    s_trans_ref = 0.01852169
    assert (thermo.S_trans*T) == approx(s_trans_ref, rel=1e-3)
    s_rot_ref = 0.01092172
    assert (thermo.S_rot*T) == approx(s_rot_ref, rel=1e-1)
    s_vib_ref = 0.00546508
    assert (thermo.S_vib*T) == approx(s_vib_ref, rel=1e-4)
def test_g16_thermochemistry():
    log = str(THIS_DIR / "logs/04_dmso_hf_freq.log")
    qc = QCData(log, point_group="c1")
    T = 298.15
    thermo = thermochemistry(qc, T, kind="rrho")

    zpe_ref = 0.083950
    assert thermo.ZPE == approx(zpe_ref)

    u_trans_ref = 0.889 * KCAL_MOL2AU
    assert thermo.U_trans == approx(u_trans_ref, rel=1e-3)
    u_rot_ref = 0.889 * KCAL_MOL2AU
    assert thermo.U_rot == approx(u_rot_ref, rel=1e-3)
    u_vib_ref = 54.676 * KCAL_MOL2AU
    assert thermo.U_vib == approx(u_vib_ref, rel=1e-1)

    s_el_ref = 0. * CAL_MOL2AU
    assert thermo.S_el == approx(s_el_ref)
    s_trans_ref = 38.978 * CAL_MOL2AU
    assert (thermo.S_trans) == approx(s_trans_ref)
    s_rot_ref = 25.168 * CAL_MOL2AU
    assert (thermo.S_rot) == approx(s_rot_ref, rel=1e-3)
    s_vib_ref = 11.519 * CAL_MOL2AU
    assert (thermo.S_vib) == approx(s_vib_ref, rel=1e-3)
Esempio n. 7
0
def run():
    args = parse_args(sys.argv[1:])

    no_alt = args.no_alt
    show_rxs = not args.norxs
    show_paths = not args.nopaths
    temperature = args.T

    if args.quick:
        show_paths = False
        educts, ts, products = [
            reactants.split(",") for reactants in args.quick.split(";")
        ]
        assert len(ts) == 1
        ed_keys = [f"ed{i}" for i in range(len(educts))]
        prod_keys = [f"prod{i}" for i in range(len(products))]

        inp_dict = {
            "molecules": dict(),
            "program": "orca",
        }

        def add_mols(keys, fns):
            for key, fn in zip(keys, fns):
                inp_dict["molecules"][key] = {
                    "freq": fn,
                }

        add_mols(ed_keys, educts)
        add_mols([
            "ts",
        ], ts)
        add_mols(prod_keys, products)

        # Dummy reaction
        inp_dict["reactions"] = {
            "quick": {
                "educts": ed_keys,
                "ts": "ts",
                "products": prod_keys,
            }
        }
    elif args.yaml:
        with open(args.yaml) as handle:
            inp_dict = yaml.load(handle)
    else:
        print(
            "Specify either a YAML file or use --quick! See also 'plotprofile --help'"
        )
        sys.exit()

    reactions = inp_dict["reactions"]

    if args.interactive:
        rx_keys = list(reactions.keys())
        for i, rx in enumerate(rx_keys):
            print(f"{i:02d}: {rx}")
        ind = int(input("Show reaction: ", ))
        rx_key = rx_keys[ind]
        reaction = reactions[rx_key]
        reactions = {
            rx_key: reaction,
        }
        # Modify molecules so only the ones actually needed are loaded
        rx_molecules = list(
            it.chain(*[to_list(mols) for mols in reaction.values()]))
        inp_dict["molecules"] = {
            key: val
            for key, val in inp_dict["molecules"].items()
            if key in rx_molecules
        }

    molecules = inp_dict["molecules"]
    thermos = load_thermos(molecules, inp_dict["program"])
    mol_energies = load_molecule_energies(thermos, no_alt=no_alt)

    rx_strs = {rx_name: rx_to_string(rx) for rx_name, rx in reactions.items()}

    if args.parsedash:
        freq_logs = {k: v["freq"] for k, v in inp_dict["molecules"].items()}
        qc_datas = {k: QCData(v) for k, v in freq_logs.items()}
        temps = np.arange(298.00, 373.00, 5)
        rows = list()
        for mol_name, temp in it.product(qc_datas, temps):
            qc = qc_datas[mol_name]
            tc = thermochemistry(qc, temp)
            row = [
                mol_name,
            ] + list(tc)
            rows.append(row)
        cols = [
            "name",
        ] + list(tc._fields)
        df = pd.DataFrame(rows, columns=cols)
        df.to_pickle("thermochem_data")
        thermochem_df = pd.read_pickle("thermochem_data")
        df = make_dash_data(inp_dict["reactions"], thermos, thermochem_df)
        df.to_pickle("dash_data")

    print()
    print("Using these G-values:")
    for key, val in mol_energies.items():
        print(key)
        pprint(val._asdict())
    print()

    rx_energies = make_reactions(reactions, mol_energies)

    paths = inp_dict.get("paths", None)
    if paths is None:
        print("Found no defined paths in .yaml file. Using all defined "
              "reactions instead.")
        paths = {"autogenerated": list(reactions.keys())}
    if args.interactive:
        paths = dict()

    print_path_rx_energies(paths, rx_energies, rx_strs, temperature)
    dump_energies(rx_energies)

    mol_labels = {
        # Use molecule key as fallback if no label is defined
        mol: values.get("label", mol)
        for mol, values in molecules.items()
    }
    rx_labels = {}
    rx_titles = {}
    # Create label strings for plotting
    for rx_name in reactions:
        labels = [
            v for k, v in reactions[rx_name].items()
            if k in ("educts", "ts", "products")
        ]

        pretty_labels = list()
        for lbl in labels:
            if isinstance(lbl, str):
                lbl = [
                    lbl,
                ]
            # Replace with pretty labels
            lbl = [mol_labels[mol] for mol in lbl]
            lbl = ",\n".join(lbl)
            pretty_labels.append(lbl)
        rx_labels[rx_name] = pretty_labels

        rx_title = reactions[rx_name].get("label", rx_name)
        rx_titles[rx_name] = rx_title

    # Try to use the 'best' energies for plotting. That is with alternative
    # single point and solvation.
    best_rx_energies = {
        rx_name: rx_energies[rx_name]["G_solv_alt"]
        for rx_name in rx_labels
    }

    if show_rxs:
        plot_reactions(best_rx_energies, rx_labels, rx_titles, temperature)
    else:
        print("Skipped plotting of reactions!")

    if show_paths and not args.interactive and (len(best_rx_energies) > 1):
        plot_paths(best_rx_energies, paths, rx_labels, rx_titles)
    else:
        print("Skipped plotting of reaction paths!")

    path_reactions = set(list(it.chain(*paths.values())))
    all_reactions = set(list(reactions.keys()))
    remainder = all_reactions - path_reactions
    if len(remainder) > 0:
        print()
        print("Warning!".upper())
        print("Not all defined reactions appeared in (defined) paths!")
        for i, rx in enumerate(remainder):
            print(f"\t{i:02d}: {rx}")
        print("Warning!".upper())
        print()

        remainder_path = {
            "remainder": remainder,
        }
        print_path_rx_energies(remainder_path, rx_energies, rx_strs,
                               temperature)

    to_compare = inp_dict.get("compare", dict())
    compare_molecules(to_compare, mol_energies)
    # compare_molecules(to_compare, mol_energies, attr="G_gas_alt")

    # Kinetics
    if "kinetics" in inp_dict:
        kin_dict = inp_dict["kinetics"]
        kin_reactions = kin_dict.get("only", reactions.keys())

        reaction_objs = list()
        for rx_name in kin_reactions:
            reactants = reactions[rx_name]
            educts = reactants["educts"]
            ts = reactants["ts"]
            products = reactants["products"]
            energies = rx_energies[rx_name]
            frx = Reaction(rx_name, educts, ts, products, energies)
            brx = frx.get_back_reaction()
            reaction_objs.extend((frx, brx))
        c0s = kin_dict["c0s"]
        t_span = kin_dict["t_span"]

        mols, res = kinetics(reaction_objs, c0s, t_span=t_span)
        plot_kinetics(mols, res)