def test__transition_state():
    """ test thermfit.._basis.prepare_refs
    """

    dct1, dct2 = thermfit.prepare_refs(
        SCHEME, SPC_DCT, TS_NAMES,
        repeats=False, parallel=False, zrxn=HABS_ZRXN)

    print(dct1)
    print(dct2)

    dct1, dct2 = thermfit.prepare_refs(
        'cbh0', SPC_DCT, TS_NAMES,
        repeats=False, parallel=False, zrxn=HABS_ZRXN)

    print(dct1)
    print(dct2)

    dct1, dct2 = thermfit.prepare_refs(
        'cbh1', SPC_DCT, TS_NAMES,
        repeats=False, parallel=False, zrxn=HABS_ZRXN)

    print(dct1)
    print(dct2)

    dct1, dct2 = thermfit.prepare_refs(
        'cbh1_0', SPC_DCT, TS_NAMES,
        repeats=False, parallel=False, zrxn=HABS_ZRXN)

    print(dct1)
    print(dct2)
def test__species():
    """ test thermfit.._basis.prepare_refs
    """

    dct1, dct2 = thermfit.prepare_refs(
        SCHEME, SPC_DCT, SPC_NAMES,
        repeats=False, parallel=False, zrxn=None)

    print(dct1)
    print(dct2)
Пример #3
0
def set_reference_ene(rxn_lst,
                      spc_dct,
                      pes_model_dct_i,
                      spc_model_dct_i,
                      run_prefix,
                      save_prefix,
                      ref_idx=0):
    """ Sets the reference species for the PES for which all energies
        are scaled relative to.
    """

    # Set the index for the reference species, right now defualt to 1st spc
    ref_rxn = rxn_lst[ref_idx]

    _, (ref_rgts, _) = ref_rxn

    ioprinter.info_message('Determining the reference energy for PES...',
                           newline=1)
    ioprinter.info_message(
        ' - Reference species assumed to be the',
        ' first set of reactants on PES: {}'.format('+'.join(ref_rgts)))

    # Get the model for the first reference species
    ref_scheme = pes_model_dct_i['therm_fit']['ref_scheme']
    ref_enes = pes_model_dct_i['therm_fit']['ref_enes']

    ref_ene_level = spc_model_dct_i['ene']['lvl1'][0]
    ioprinter.info_message(
        ' - Energy Level for Reference Species: {}'.format(ref_ene_level))

    # Get the elec+zpe energy for the reference species
    ioprinter.info_message('')
    hf0k = 0.0
    for rgt in ref_rgts:

        ioprinter.info_message(' - Calculating energy for {}...'.format(rgt))
        basis_dct, uniref_dct = thermfit.prepare_refs(ref_scheme, spc_dct,
                                                      (rgt, ))
        spc_basis, coeff_basis = basis_dct[rgt]

        # Build filesystem
        ene_spc, ene_basis = thmroutines.basis.basis_energy(
            rgt, spc_basis, uniref_dct, spc_dct, spc_model_dct_i, run_prefix,
            save_prefix)

        # Calcualte the total energy
        hf0k += thermfit.heatform.calc_hform_0k(ene_spc,
                                                ene_basis,
                                                spc_basis,
                                                coeff_basis,
                                                ref_set=ref_enes)

    return hf0k
Пример #4
0
def run(pes_rlst, spc_rlst,
        therm_tsk_lst,
        pes_mod_dct, spc_mod_dct,
        spc_dct,
        run_prefix, save_prefix):
    """ Executes all thermochemistry tasks.

        :param pes_rlst: species from PESs to run
            [(PES formula, PES idx, SUP-PES idx)
            (CHANNEL idx, (REACS, PRODS))
        :type pes_rlst: tuple(dict[str: dict])
        :param spc_rlst: lst of species to run
        :type spc_rlst: tuple(dict[str: dict])
        :param es_tsk_lst: list of the electronic structure tasks
            tuple(tuple(obj, tsk, keyword_dict))
        :type es_tsk_lst: tuple(tuple(str, str, dict))
        :param spc_dct: species information
            dict[spc_name: spc_information]
        :type spc_dct: dict[str:dict]
        :param glob_dct: global information for all species
            dict[spc_name: spc_information]
        :type glob_dct: dict[str: dict]
        :param thy_dct: all of the theory information
            dict[thy name: inf]
        :type thy_dct: dict[str:dict]
        :param run_prefix: root-path to the run-filesystem
        :type run_prefix: str
        :param save_prefix: root-path to the save-filesystem
        :type save_prefix: str
    """

    # Print Header
    ioprinter.info_message('Calculating Thermochem:')
    ioprinter.runlst(('SPC', 0, 0), spc_rlst)

    # ------------------------------------------------ #
    # PREPARE INFORMATION TO PASS TO THERMDRIVER TASKS #
    # ------------------------------------------------ #

    # Build a list of the species to calculate thermochem for loops below
    spc_mods = list(spc_mod_dct.keys())  # hack
    spc_mod_dct_i = spc_mod_dct[spc_mods[0]]
    split_rlst = split_unstable_full(
        pes_rlst, spc_rlst, spc_dct, spc_mod_dct_i, save_prefix)
    spc_queue = parser.rlst.spc_queue(
        tuple(split_rlst.values())[0], 'SPC')

    # Build the paths [(messpf, nasa)], models and levels for each spc
    thm_paths = thermo_paths(spc_dct, spc_queue, spc_mods, run_prefix)

    # ----------------------------------- #
    # RUN THE REQUESTED THERMDRIVER TASKS #
    # ----------------------------------- #

    # Write and Run MESSPF inputs to generate the partition functions
    write_messpf_tsk = parser.run.extract_task('write_mess', therm_tsk_lst)
    if write_messpf_tsk is not None:

        ioprinter.messpf('write_header')

        spc_mods, pes_mod = parser.models.extract_models(write_messpf_tsk)

        for idx, spc_name in enumerate(spc_queue):
            print('write test {}'.format(spc_name))
            for spc_mod in spc_mods:
                messpf_inp_str = thmroutines.qt.make_messpf_str(
                    pes_mod_dct[pes_mod]['therm_temps'],
                    spc_dct, spc_name,
                    pes_mod_dct[pes_mod], spc_mod_dct[spc_mod],
                    run_prefix, save_prefix)
                ioprinter.messpf('input_string')
                ioprinter.info_message(messpf_inp_str)
                autorun.write_input(
                    thm_paths[idx][spc_mod][0], messpf_inp_str,
                    input_name='pf.inp')

    # Run the MESSPF files that have been written
    run_messpf_tsk = parser.run.extract_task('run_mess', therm_tsk_lst)
    if run_messpf_tsk is not None:

        spc_mod, pes_mod = parser.models.extract_models(run_messpf_tsk)
        spc_mods = parser.models.split_model(spc_mod[0])

        ioprinter.messpf('run_header')
        for idx, spc_name in enumerate(spc_queue):

            _spc_mods, coeffs, operators = spc_mods

            # Run MESSPF for all requested models, combine the PFS at the end
            ioprinter.message('Run MESSPF: {}'.format(spc_name), newline=1)
            _pfs = []
            for spc_mod in _spc_mods:
                autorun.run_script(
                   autorun.SCRIPT_DCT['messpf'],
                   thm_paths[idx][spc_mod][0])
                _pfs.append(
                    reader.mess.messpf(thm_paths[idx][spc_mod][0]))
            final_pf = thermfit.pf.combine(_pfs, coeffs, operators)

            # need to clean thm path build
            tdx = len(spc_mods)
            spc_info = sinfo.from_dct(spc_dct[spc_name])
            spc_fml = automol.inchi.formula_string(spc_info[0])
            thm_prefix = [spc_fml, automol.inchi.inchi_key(spc_info[0])]
            thm_paths[idx]['final'] = (
                job_path(run_prefix, 'MESS', 'PF', thm_prefix, locs_idx=tdx),
                job_path(run_prefix, 'THERM', 'NASA', thm_prefix, locs_idx=tdx)
            )
            writer.mess.output(
                fstring(spc_dct[spc_name]['inchi']),
                final_pf, thm_paths[idx]['final'][0],
                filename='pf.dat')

    # Use MESS partition functions to compute thermo quantities
    run_fit_tsk = parser.run.extract_task('run_fits', therm_tsk_lst)
    if run_fit_tsk is not None:

        spc_mods, pes_mod = parser.models.extract_models(run_fit_tsk)
        pes_mod_dct_i = pes_mod_dct[pes_mod]

        ioprinter.nasa('header')
        chn_basis_ene_dct = {}
        for idx, spc_name in enumerate(spc_queue):

            # Take species model and add it to the chn_basis_ene dct
            spc_mod = spc_mods[0]
            spc_mod_dct_i = spc_mod_dct[spc_mod]
            if spc_mod not in chn_basis_ene_dct:
                chn_basis_ene_dct[spc_mod] = {}

            # Get the reference scheme and energies (ref in different place)
            ref_scheme = pes_mod_dct_i['therm_fit']['ref_scheme']
            ref_enes = pes_mod_dct_i['therm_fit']['ref_enes']

            # Determine info about the basis species used in thermochem calcs
            basis_dct, uniref_dct = thermfit.prepare_refs(
                ref_scheme, spc_dct, (spc_name,))

            # Get the basis info for the spc of interest
            spc_basis, coeff_basis = basis_dct[spc_name]

            # Get the energies for the spc and its basis
            ene_basis = []
            energy_missing = False
            for spc_basis_i in spc_basis:
                if spc_basis_i in chn_basis_ene_dct[spc_mod]:
                    ioprinter.message(
                        'Energy already found for basis species: '
                        + spc_basis_i)
                    ene_basis.append(chn_basis_ene_dct[spc_mod][spc_basis_i])
                else:
                    ioprinter.message(
                        'Energy will be determined for basis species: '
                        + spc_basis_i)
                    energy_missing = True
            if not energy_missing:
                pf_filesystems = filesys.models.pf_filesys(
                    spc_dct[spc_name], spc_mod_dct_i,
                    run_prefix, save_prefix, saddle=False)
                ene_spc = ene.read_energy(
                    spc_dct[spc_name], pf_filesystems, spc_mod_dct_i,
                    run_prefix, read_ene=True, read_zpe=True, saddle=False)
            else:
                ene_spc, ene_basis = thmroutines.basis.basis_energy(
                    spc_name, spc_basis, uniref_dct, spc_dct,
                    spc_mod_dct_i,
                    run_prefix, save_prefix)
                for spc_basis_i, ene_basis_i in zip(spc_basis, ene_basis):
                    chn_basis_ene_dct[spc_mod][spc_basis_i] = ene_basis_i

            # Calculate and store the 0 K Enthalpy
            hf0k = thermfit.heatform.calc_hform_0k(
                ene_spc, ene_basis, spc_basis, coeff_basis, ref_set=ref_enes)
            spc_dct[spc_name]['Hfs'] = [hf0k]

        # Write the NASA polynomials in CHEMKIN format
        ckin_nasa_str = ''
        ckin_path = output_path('CKIN')
        for idx, spc_name in enumerate(spc_queue):

            ioprinter.nasa('calculate', spc_name)

            # Write the header describing the models used in thermo calcs
            ckin_nasa_str += writer.ckin.model_header(spc_mods, spc_mod_dct)

            # Build and write the NASA polynomial in CHEMKIN-format string
            # Call dies if you haven't run "write mess" task
            ckin_nasa_str += thmroutines.nasapoly.build_polynomial(
                spc_name, spc_dct,
                thm_paths[idx]['final'][0], thm_paths[idx]['final'][1])
            ckin_nasa_str += '\n\n'
        print('CKIN NASA STR\n')
        print(ckin_nasa_str)

        nasa7_params_all = chemkin_io.parser.thermo.create_spc_nasa7_dct(
            ckin_nasa_str)
        ioprinter.info_message(
            'SPECIES\t\tH(0 K)[kcal/mol]\tH(298 K)[kcal/mol]\t' +
            'S(298 K)[cal/mol K]\n')
        for spc_name in nasa7_params_all:
            nasa7_params = nasa7_params_all[spc_name]
            ht0 = spc_dct[spc_name]['Hfs'][0]
            ht298 = mechanalyzer.calculator.thermo.enthalpy(
                nasa7_params, 298.15)
            st298 = mechanalyzer.calculator.thermo.entropy(
                nasa7_params, 298.15)
            ioprinter.info_message(
                '{}\t{:3.2f}\t{:3.2f}\t{:3.2f}'.format(
                    spc_name, ht0, ht298/1000., st298))

        # Write all of the NASA polynomial strings
        writer.ckin.write_nasa_file(ckin_nasa_str, ckin_path)
Пример #5
0
def enthalpy_calculation(spc_dct,
                         spc_name,
                         ene_chnlvl,
                         chn_basis_ene_dct,
                         pes_mod_dct_i,
                         spc_mod_dct_i,
                         run_prefix,
                         save_prefix,
                         pforktp='ktp',
                         zrxn=None):
    """ Calculate the Enthalpy.
    """

    ref_scheme = pes_mod_dct_i['therm_fit']['ref_scheme']
    ref_enes = pes_mod_dct_i['therm_fit']['ref_enes']

    basis_dct, uniref_dct = thermfit.prepare_refs(ref_scheme,
                                                  spc_dct, (spc_name, ),
                                                  zrxn=zrxn)

    # Get the basis info for the spc of interest
    spc_basis, coeff_basis = basis_dct[spc_name]

    ene_spc = ene_chnlvl
    ene_basis = []

    energy_missing = False
    for spc_basis_i in spc_basis:
        if not isinstance(spc_basis_i, str):
            basreacs, basprods = spc_basis_i
            spc_basis_i = ''.join(basreacs)
            spc_basis_i += ''.join(basprods)
        if spc_basis_i in chn_basis_ene_dct:
            ioprinter.debug_message('Energy already found for basis species: ',
                                    spc_basis_i)
            ene_basis.append(chn_basis_ene_dct[spc_basis_i])
        else:
            ioprinter.debug_message(
                'Energy will be determined for basis species: ', spc_basis_i)
            energy_missing = True

    # Get the energies for the spc and its basis
    if energy_missing:
        _, ene_basis = basis_energy(spc_name,
                                    spc_basis,
                                    uniref_dct,
                                    spc_dct,
                                    spc_mod_dct_i,
                                    run_prefix,
                                    save_prefix,
                                    read_species=False)
        for spc_basis_i, ene_basis_i in zip(spc_basis, ene_basis):
            if not isinstance(spc_basis_i, str):
                basreacs, basprods = spc_basis_i
                spc_basis_i = ''.join(basreacs)
                spc_basis_i += ''.join(basprods)
            chn_basis_ene_dct[spc_basis_i] = ene_basis_i

    # Calculate and store the 0 K Enthalpy
    hf0k = thermfit.heatform.calc_hform_0k(ene_spc,
                                           ene_basis,
                                           spc_basis,
                                           coeff_basis,
                                           ref_set=ref_enes)

    if pforktp == 'ktp':
        if 'basic' in ref_scheme:
            ts_ref_scheme = 'basic'
        else:
            ts_ref_scheme = 'cbh0'
            if '_' in ref_scheme:
                ts_ref_scheme = 'cbh' + ref_scheme.split('_')[1]
        if zrxn is None:
            if ref_scheme != ts_ref_scheme:
                basis_dct_trs, uniref_dct_trs = thermfit.prepare_refs(
                    ts_ref_scheme, spc_dct, (spc_name, ), zrxn=zrxn)
                spc_basis_trs, coeff_basis_trs = basis_dct_trs[spc_name]
                ene_basis_trs = []
                energy_missing = False
                for spc_basis_i in spc_basis_trs:
                    if spc_basis_i in chn_basis_ene_dct:
                        ioprinter.info_message(
                            'Energy already found for basis species: ',
                            spc_basis_i)
                        ene_basis_trs.append(chn_basis_ene_dct[spc_basis_i])
                    else:
                        ioprinter.info_message(
                            'Energy will be determined for basis species: ',
                            spc_basis_i)
                        energy_missing = True
                if energy_missing:
                    _, ene_basis_trs = basis_energy(spc_name, spc_basis_trs,
                                                    uniref_dct_trs, spc_dct,
                                                    spc_mod_dct_i, run_prefix,
                                                    save_prefix)
                    for spc_basis_i, ene_basis_i in zip(
                            spc_basis_trs, ene_basis_trs):
                        chn_basis_ene_dct[spc_basis_i] = ene_basis_i
                ene_spc_trs = ene_chnlvl
                hf0k_trs = thermfit.heatform.calc_hform_0k(ene_spc_trs,
                                                           ene_basis_trs,
                                                           spc_basis_trs,
                                                           coeff_basis_trs,
                                                           ref_set=ref_enes)
            else:
                hf0k_trs = hf0k
        else:
            hf0k_trs = 0.0
    else:
        hf0k_trs = None
    ioprinter.info_message('ABS Energy  (kJ/mol): ', ene_chnlvl)
    ioprinter.info_message('Hf0K Energy (kJ/mol): ', hf0k * phycon.KCAL2KJ)

    return hf0k, hf0k_trs, chn_basis_ene_dct, basis_dct
Пример #6
0
def write_basis_csv(spc_str,
                    outname='species_hof_basis.csv',
                    path='.',
                    parallel=False):
    """ Read the species file in a .csv format and write a new one
        that has hof basis species added to it.
    """

    headers = [
        header for header in read_csv_headers(spc_str) if header != 'name'
    ]
    if 'inchi' not in headers:
        headers.append('inchi')
    headers_noich = [
        header for header in headers if header not in ('inchi', 'inchikey')
    ]
    new_headers = ['inchi', 'inchikey'] + headers_noich
    csv_str = ','.join(['name'] + new_headers) + '\n'
    # Read in the initial CSV information (deal with mult stereo)
    init_dct = csv_dct(spc_str, values=headers, key='name')
    # Build a new dict
    names = list(init_dct.keys())
    spc_queue = []
    for name in names:
        spc_queue.append([name, ''])

    # Find all references
    ref_schemes = ['cbh0', 'cbh1', 'cbh2']
    for ref_scheme in ref_schemes:
        formula_dct = {}
        _, uniref_dct = thermfit.prepare_refs(ref_scheme,
                                              init_dct,
                                              spc_queue,
                                              repeats=True,
                                              parallel=parallel)
        for name in uniref_dct:
            spc_str, formula_dct = _species_row_string(uniref_dct, formula_dct,
                                                       name, new_headers)
            csv_str += ref_scheme + '_' + spc_str
    basis_file = os.path.join(path, outname + '_basis')
    with open(basis_file, 'w') as file_obj:
        file_obj.write(spc_str)

    # Find only the unique references
    new_names = []
    for ref_scheme in ref_schemes:
        _, uniref_dct = thermfit.prepare_refs(ref_scheme,
                                              init_dct,
                                              spc_queue,
                                              repeats=False,
                                              parallel=parallel)
    new_names, init_dct, uniref_dct = _add_unique_references_to_dct(
        new_names, init_dct, uniref_dct, ref_scheme)
    spc_str = ','.join(['name'] + new_headers) + '\n'
    formula_dct = {}
    for name in init_dct:
        if 'cbh' in name:
            namelabel = name.split('_')[0]
            if namelabel not in formula_dct:
                formula_dct[namelabel] = {}
            frmdct = formula_dct[namelabel]
            spc_str += namelabel + '_'
            formula = _get_formula_from_dct(init_dct, name)
            formula, frmdct = _assign_unique_name(frmdct, formula)
            spc_str += formula + ','
        else:
            spc_str += '{},'.format(name)
        for idx, header in enumerate(new_headers):
            val = init_dct[name][header]
            if isinstance(val, str):
                val = "'{}'".format(val)
            spc_str += str(val)
            if idx + 1 < len(new_headers):
                spc_str += ','
        spc_str += '\n'

    # Write the file
    basis_file = os.path.join(path, outname)
    with open(basis_file, 'w') as file_obj:
        file_obj.write(spc_str)