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)
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)
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)
def redox_result_to_qcdata(redox_result): geom = redox_result.geom_gas H = geom.eckart_projection( geom.mass_weigh_hessian(redox_result.hessian_gas)) w, v = np.linalg.eigh(H) nus = eigval_to_wavenumber(w) thermo_dict = { "masses": geom.masses, "vibfreqs": nus, "coords3d": geom.coords3d, "energy": redox_result.energy_gas, "mult": redox_result.mult, } qcd = QCData(thermo_dict) return qcd
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)
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)