예제 #1
0
def assess_pf_convergence(tau_save_fs, ref_ene,
                          temps=(300., 500., 750., 1000., 1500.)):
    """ Determine how much the partition function has converged
    """

    # Calculate sigma values at various temperatures for the PF
    for temp in temps:
        sumq = 0.
        sum2 = 0.
        idx = 0
        ioprinter.debug_message('integral convergence for T = ', temp)
        inf_obj_s = tau_save_fs[0].file.info.read()
        nsamp = inf_obj_s.nsamp
        saved_locs = tau_save_fs[-1].existing()
        ratio = float(nsamp) / len(saved_locs)
        for locs in tau_save_fs[-1].existing():
            idx += 1
            ene = tau_save_fs[-1].file.energy.read(locs)
            ene = (ene - ref_ene) * phycon.EH2KCAL
            tmp = numpy.exp(-ene*349.7/(0.695*temp))
            sumq = sumq + tmp
            sum2 = sum2 + tmp**2
            sigma = numpy.sqrt(
                (abs(sum2/float(idx)-(sumq/float(idx))**2))/float(idx))
            ioprinter.debug_message(
                sumq/float(idx), sigma, 100.*sigma*float(idx)/sumq, idx)
        inf_obj_s = tau_save_fs[0].file.info.read()
        nsamp = inf_obj_s.nsamp
        saved_locs = tau_save_fs[-1].existing()
        ratio = len(saved_locs) / float(nsamp)
        ioprinter.info_message('Ratio of good to sampled geometries: ', ratio)
예제 #2
0
def scale_rotor_pots(rotors, scale_factor=((), None)):
    """ scale the pots
    """

    # Count numbers
    numtors = 0
    for rotor in rotors:
        numtors += len(rotor)

    # Calculate the scaling factors
    scale_indcs, factor = scale_factor
    nscale = numtors - len(scale_indcs)

    if nscale > 0:
        sfactor = factor**(2.0/nscale)
        ioprinter.debug_message(
            'scale_coeff test:', factor, nscale, sfactor)

        # test
        # sfactor = 1
        # test
        for tidx, rotor in enumerate(rotors):
            for torsion in rotor:
                if tidx not in scale_indcs and factor is not None:
                    torsion.pot = automol.pot.scale(torsion.pot, sfactor)
                    # following is being used in a test to see how effective
                    # a scaling of fixed scan torsional pots can be
                    # torsion.pot = automol.pot.relax_scale(torsion.pot)

    return rotors
예제 #3
0
파일: label.py 프로젝트: sjklipp/mechdriver
def make_pes_label_dct(rxn_lst, pes_idx, spc_dct, spc_mod_dct_i):
    """ Builds a dictionary that matches the mechanism name to the labels used
        in the MESS input and output files for the whole PES
    """
    print('spc dct_names', list(spc_dct.keys()))

    pes_label_dct = {}
    for rxn in rxn_lst:
        # Get the wells models
        rwell_mod = spc_mod_dct_i['ts']['rwells']
        pwell_mod = spc_mod_dct_i['ts']['pwells']

        # Get thhe name and class
        chnl_idx, (reacs, prods) = rxn
        tsname = 'ts_{:g}_{:g}'.format(pes_idx+1, chnl_idx+1)
        sub_tsname = '{}_{:g}'.format(tsname, 0)
        rclass = spc_dct[sub_tsname]['zrxn'].class_

        # Build labels
        pes_label_dct.update(
            _make_channel_label_dct(
                tsname, rclass, pes_label_dct, chnl_idx, reacs, prods,
                rwell_mod, pwell_mod))
        ioprinter.debug_message('pes_label dct', pes_label_dct)

    return pes_label_dct
예제 #4
0
def read_energy(spc_dct_i, pf_filesystems,
                spc_model_dct_i, run_prefix,
                read_ene=True, read_zpe=True, conf=None, saddle=False):
    """ Get the energy for a species on a channel
    """

    # Read the electronic energy and ZPVE
    e_elec = None
    if read_ene:
        e_elec = electronic_energy(
            spc_dct_i, pf_filesystems, spc_model_dct_i, conf=conf)
        ioprinter.debug_message('e_elec in models ene ', e_elec)

    e_zpe = None
    if read_zpe:
        e_zpe = zero_point_energy(
            spc_dct_i, pf_filesystems, spc_model_dct_i,
            run_prefix, saddle=saddle)
        ioprinter.debug_message('zpe in models ene ', e_zpe)

    # Return the total energy requested
    ene = None
    if read_ene and read_zpe:
        if e_elec is not None and e_zpe is not None:
            ene = e_elec + e_zpe
    elif read_ene and not read_zpe:
        ene = e_elec
    elif read_ene and not read_zpe:
        ene = e_zpe

    return ene
예제 #5
0
파일: typ.py 프로젝트: Auto-Mech/mechdriver
def scale_1d(spc_mod_dct_i):
    """ determine if we need to scale the potential
    """
    ioprinter.debug_message('tors model in scale set',
                            spc_mod_dct_i['tors']['mod'])
    return (bool(spc_mod_dct_i['tors']['mod'] in ('1dhrfa', '1dhrf', '1dhr'))
            and spc_mod_dct_i['tors']['scale'] == 'on')
예제 #6
0
파일: ene.py 프로젝트: sjklipp/mechdriver
def rpath_ref_idx(ts_dct, scn_vals, coord_name, scn_prefix, ene_info1,
                  ene_info2):
    """ Get the reference energy along a reaction path
    """

    # Set up the filesystem
    zma_fs = autofile.fs.zmatrix(scn_prefix)
    zma_path = zma_fs[-1].path([0])
    scn_fs = autofile.fs.scan(zma_path)

    ene_info1 = ene_info1[1][0][1]
    ene_info2 = ene_info2[0]
    ioprinter.debug_message('mod_eneinf1', ene_info1)
    ioprinter.debug_message('mod_eneinf2', ene_info2)
    mod_ene_info1 = tinfo.modify_orb_label(sinfo.from_dct(ts_dct), ene_info1)
    mod_ene_info2 = tinfo.modify_orb_label(sinfo.from_dct(ts_dct), ene_info2)

    ene1, ene2, ref_val = None, None, None
    for val in reversed(scn_vals):
        locs = [[coord_name], [val]]
        path = scn_fs[-1].path(locs)
        hs_fs = autofile.fs.high_spin(path)
        if hs_fs[-1].file.energy.exists(mod_ene_info1[1:4]):
            ene1 = hs_fs[-1].file.energy.read(mod_ene_info1[1:4])
        if hs_fs[-1].file.energy.exists(mod_ene_info2[1:4]):
            ene2 = hs_fs[-1].file.energy.read(mod_ene_info2[1:4])
        if ene1 is not None and ene2 is not None:
            ref_val = val
            break

    if ref_val is not None:
        scn_idx = scn_vals.index(ref_val)

    return scn_idx, ene1, ene2
예제 #7
0
def saddle_point_checker(imags):
    """ run things for checking Hessian
    """

    big_imag, kick_imag = 0, 0

    ioprinter.checking('the imaginary frequencies of the saddle point...')
    if len(imags) < 1:
        ioprinter.warning_message('No imaginary modes for geometry')
        status = 'fail'
    else:
        if len(imags) > 1:
            ioprinter.warning_message('More than one imaginary mode for geometry')
        for idx, imag in enumerate(imags):
            if imag <= 50.0:
                ioprinter.warning_message('Mode {} {} cm-1 is low,'.format(str(idx+1), imag))
            elif 50.0 < imag <= 200.0:
                lowstr = 'Mode {} {} cm-1 is low,'.format(str(idx+1), imag)
                ioprinter.warning_message(lowstr + 'need a kickoff procedure to remove')
                kick_imag += 1
            else:
                ioprinter.debug_message('Mode {} {} cm-1 likely fine,'.format(str(idx+1), imag))
                big_imag += 1

        if big_imag > 1:
            ioprinter.warning_message('WARNING: More than one imaginary mode for geometry')
            if kick_imag >= 1:
                ioprinter.debug_message('Will kickoff to get saddle point')
                status = 'kickoff'
        elif big_imag == 1:
            status = 'success'

    return status
예제 #8
0
def make_pes_label_dct(rxn_lst, pes_idx, spc_dct, spc_mod_dct_i):
    """  Loop over all of the reaction channels of the PES to build a
         dictionary that systematically maps the mechanism names of all
         species and transition states to formatted labels used to designate
         each as a well, bimol, or barrier component in a MESS input file.
    """

    pes_label_dct = {}
    for rxn in rxn_lst:
        # Get the wells models
        rwell_mod = spc_mod_dct_i['ts']['rwells']
        pwell_mod = spc_mod_dct_i['ts']['pwells']

        # Get thhe name and class
        chnl_idx, (reacs, prods) = rxn
        tsname = 'ts_{:g}_{:g}'.format(pes_idx + 1, chnl_idx + 1)
        sub_tsname = '{}_{:g}'.format(tsname, 0)
        rclass = spc_dct[sub_tsname]['class']

        # Build labels
        pes_label_dct.update(
            _make_channel_label_dct(tsname, rclass, pes_label_dct, chnl_idx,
                                    reacs, prods, rwell_mod, pwell_mod))
        ioprinter.debug_message('pes_label dct', pes_label_dct)

    return pes_label_dct
예제 #9
0
    def _read_basis_energy(ich_name_dct,
                           spc_dct,
                           uni_refs_dct,
                           spc_model_dct_i,
                           run_prefix,
                           save_prefix,
                           ichs,
                           output_queue=None):

        h_basis_dct = {}
        print(f'Process {os.getpid()} reading energy for species: {ichs}')
        for ich in ichs:
            name = ich_name_dct[ich]
            if name in spc_dct:
                spc_dct_i = spc_dct[name]
                prname = name
            elif name in uni_refs_dct:
                spc_dct_i = uni_refs_dct[name]
                prname = name
            if 'ts' in name or 'TS' in name:
                reacs, prods = ich.split('PRODS')
                reacs = reacs.replace('REACS', '')
                reacs = reacs.split('REAC')
                prods = prods.split('PROD')
                reac_lbl = 'r0'
                if len(reacs) > 1:
                    reac_lbl += '+r1'
                prod_lbl = 'p0'
                if len(prods) > 1:
                    prod_lbl += '+p1'
                ioprinter.info_message(
                    f'Basis Reaction: {reac_lbl}={prod_lbl} 1 1 1 ')
                for i, reac in enumerate(reacs):
                    ioprinter.info_message(
                        f'r{i},{reac},{automol.inchi.smiles(reac)},1')
                for i, prod in enumerate(prods):
                    ioprinter.info_message(
                        f'p{i},{prod},{automol.inchi.smiles(prod)},1')
            ioprinter.debug_message('bases energies test:', ich, name)
            pf_filesystems = filesys.models.pf_filesys(
                spc_dct_i,
                spc_model_dct_i,
                run_prefix,
                save_prefix,
                saddle=('ts' in name or 'TS' in name),
                name=name)
            ioprinter.info_message(f'Calculating energy for basis {prname}...',
                                   newline=1)
            h_basis_dct[ich] = read_energy(spc_dct_i,
                                           pf_filesystems,
                                           spc_model_dct_i,
                                           run_prefix,
                                           read_ene=True,
                                           read_zpe=True,
                                           saddle='ts' in name or 'TS' in name)
        output_queue.put((h_basis_dct, ))
예제 #10
0
def run_tsk(tsk, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix,
            save_prefix):
    """ run an electronic structure task
    for generating a list of conformer or tau sampling geometries
    """

    # Print the head of the task
    ioprinter.task_header(tsk, spc_name)
    ioprinter.keyword_list(es_keyword_dct, thy_dct)

    # If species is unstable, set task to 'none'
    ini_method_dct = thy_dct.get(es_keyword_dct['inplvl'])
    ini_thy_info = tinfo.from_dct(ini_method_dct)
    stable = True
    if 'ts' not in spc_name and tsk != 'init_geom':
        zrxn, path = filesys.read.instability_transformation(
            spc_dct, spc_name, ini_thy_info, save_prefix)
        stable = bool(zrxn is None)

    if stable:
        ioprinter.debug_message('- Proceeding with requested task...')

        # Get stuff from task
        job = tsk.split('_', 1)[1]

        # Run the task if an initial geom exists
        if 'init' in tsk and not skip_task(spc_dct, spc_name):
            _ = geom_init(spc_dct, spc_name, thy_dct, es_keyword_dct,
                          run_prefix, save_prefix)
        elif 'conf' in tsk and not skip_task(spc_dct, spc_name):
            conformer_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct,
                          run_prefix, save_prefix)
        elif 'tau' in tsk and not skip_task(spc_dct, spc_name):
            tau_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct,
                    run_prefix, save_prefix)
        elif 'hr' in tsk and not skip_task(spc_dct, spc_name):
            hr_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix,
                   save_prefix)
        elif 'rpath' in tsk and not skip_task(spc_dct, spc_name):
            pass
        elif 'irc' in tsk and not skip_task(spc_dct, spc_name):
            irc_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct,
                    run_prefix, save_prefix)
        elif 'find' in tsk:
            findts(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix,
                   save_prefix)

    else:
        ioprinter.info_message('Skipping task for unstable species...',
                               newline=1)
예제 #11
0
def _kickoff_saddle(geo, norm_coords, size=0.1, backward=False, mode=0):
    """ kickoff from saddle to find connected minima
    """

    # Choose the displacement xyzs and set kickoff direction and size
    kickoff = size if not backward else -1.0*size
    disp_xyzs = norm_coords[mode]
    disp_xyzs = numpy.multiply(disp_xyzs, kickoff)

    disp_geo = automol.geom.translate_along_matrix(geo, disp_xyzs)

    ioprinter.debug_message(
        f'Creating displacement geometry with kickoff size of {kickoff}'
        f'\ninitial geometry:\n{automol.geom.string(geo)}'
        f'\ndisplaced geometry:\n{automol.geom.string(disp_geo)}'
    )

    return disp_geo
예제 #12
0
def _kickoff_saddle(geo, norm_coords, spc_info, mod_thy_info,
                    run_fs, opt_script_str,
                    kickoff_size=0.1, kickoff_backward=False, kickoff_mode=0,
                    opt_cart=True, **kwargs):
    """ kickoff from saddle to find connected minima
    """

    # Choose the displacement xyzs
    disp_xyzs = norm_coords[kickoff_mode]

    # Set the displacement vectors and displace geometry
    disp_len = kickoff_size * phycon.ANG2BOHR
    if kickoff_backward:
        disp_len *= -1
    disp_xyzs = numpy.multiply(disp_xyzs, disp_len)
    ioprinter.debug_message(
        'geo test in kickoff_saddle:',
        automol.geom.string(geo), disp_xyzs)

    geo = automol.geom.displace(geo, disp_xyzs)

    # Optimize displaced geometry
    if opt_cart:
        geom = geo
    else:
        geom = automol.geom.zmatrix(geo)
    success, ret = es_runner.execute_job(
        job=elstruct.Job.OPTIMIZATION,
        script_str=opt_script_str,
        run_fs=run_fs,
        geo=geom,
        spc_info=spc_info,
        thy_info=mod_thy_info,
        overwrite=True,
        **kwargs,
    )

    if success:
        inf_obj, _, out_str = ret
        prog = inf_obj.prog
        geo = elstruct.reader.opt_geometry(prog, out_str)

    return geo, ret
예제 #13
0
def get_matching_tors_locs(spc_model_dct_i,
                           spc_dct_i,
                           harm_filesys,
                           run_prefix,
                           save_prefix,
                           saddle=False,
                           nprocs=1):
    """get a list of locations in at the scan level filesystem
         that match the conformer
       locations at the vib level filesystem
    """
    cnf_save_fs, cnf_path, cnf_locs, _, _ = harm_filesys
    if spc_model_dct_i['tors']['geolvl'] != spc_model_dct_i['vib']['geolvl']:
        tors_run_fs, tors_save_fs, tors_locs_lst = get_all_tors_locs_lst(
            spc_dct_i,
            spc_model_dct_i,
            run_prefix,
            save_prefix,
            saddle,
            nprocs=nprocs)
        match_dct = fs_confs_dict(tors_save_fs, tors_locs_lst, cnf_save_fs,
                                  [cnf_locs])
        if match_dct[tuple(cnf_locs)] is not None:
            match_tors_locs = tuple(match_dct[tuple(cnf_locs)])
            match_path = tors_save_fs[-1].path(match_tors_locs)
            ioprinter.info_message(
                f'Using {cnf_path} as the parent conformer location')
            ioprinter.info_message(f'and {match_path} for torsional profiles')
        else:
            cnf_zma_save_fs = autofile.fs.zmatrix(cnf_path)
            zma = cnf_zma_save_fs[-1].file.zmatrix.read((0, ))
            save_locs = tors_save_fs[-1].existing()
            _, sym_locs_lst = this_conformer_was_run_in_run(zma, tors_run_fs)
            for sym_locs in sym_locs_lst:
                if sym_locs in save_locs:
                    match_tors_locs = sym_locs
                    match_path = tors_save_fs[-1].path(match_tors_locs)
                    ioprinter.debug_message(
                        'this conformer had converged to another conformer at'
                        f'{match_path}')
    else:
        match_tors_locs = cnf_locs
    return match_tors_locs
예제 #14
0
def _obtain_ini_geom(spc_dct_i, ini_cnf_save_fs, mod_ini_thy_info, overwrite):
    """ Obtain an initial geometry to be optimized. Checks a hieratchy
        of places to obtain the initial geom.
            (1) Geom dict which is the input from the user
            (2) Geom from inchi
    """

    geo_init = None
    # Obtain geom from thy fs or remove the conformer filesystem if needed
    if not overwrite:
        ini_min_locs, ini_path = filesys.mincnf.min_energy_conformer_locators(
            ini_cnf_save_fs, mod_ini_thy_info)
        if ini_path:
            geo_init = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs)
            ioprinter.info_message(
                'Getting inital geometry from inplvl at path',
                '{}'.format(ini_cnf_save_fs[-1].path(ini_min_locs)))
    else:
        ioprinter.debug_message(
            'Removing original conformer save data for instability')
        for locs in ini_cnf_save_fs[-1].existing():
            cnf_path = ini_cnf_save_fs[-1].path(locs)
            ioprinter.debug_message('Removing {}'.format(cnf_path))
            shutil.rmtree(cnf_path)

    if geo_init is None:
        if 'geo_inp' in spc_dct_i:
            geo_init = spc_dct_i['geo_inp']
            ioprinter.info_message(
                'Getting initial geometry from geom dictionary')

    if geo_init is None:
        geo_init = automol.inchi.geometry(spc_dct_i['inchi'])
        ioprinter.info_message('Getting initial geometry from inchi')

    # Check if the init geometry is connected
    if geo_init is not None:
        if not automol.geom.connected(geo_init):
            geo_init = None

    return geo_init
예제 #15
0
def make_messrate_str(pes_idx, rxn_lst,
                      pes_model, spc_model,
                      spc_dct, thy_dct,
                      pes_model_dct, spc_model_dct,
                      label_dct,
                      mess_path, run_prefix, save_prefix):
    """ Combine various MESS strings together to combined MESS rates

        spc model could become a list for channel combinations
    """

    pes_model_dct_i = pes_model_dct[pes_model]
    spc_model_dct_i = spc_model_dct[spc_model]

    # Write the strings for the MESS input file
    globkey_str = make_header_str(
        spc_dct,
        temps=pes_model_dct_i['rate_temps'],
        pressures=pes_model_dct_i['pressures'])

    # Write the energy transfer section strings for MESS file
    etransfer = pes_model_dct_i['glob_etransfer']
    energy_trans_str = make_global_etrans_str(
        rxn_lst, spc_dct, etransfer)

    # Write the MESS strings for all the PES channels
    rxn_chan_str, dats, _, _ = make_pes_mess_str(
        spc_dct, rxn_lst, pes_idx,
        run_prefix, save_prefix, label_dct,
        pes_model_dct_i, spc_model_dct_i, spc_model, thy_dct)

    # Combine strings together
    mess_inp_str = mess_io.writer.messrates_inp_str(
        globkey_str, energy_trans_str, rxn_chan_str)

    # Write the MESS file into the filesystem
    ioprinter.obj('line_plus')
    ioprinter.writing('MESS input file', mess_path)
    ioprinter.debug_message(mess_inp_str)

    return mess_inp_str, dats
예제 #16
0
def make_header_str(spc_dct, temps, pressures):
    """ makes the standard header and energy transfer sections for MESS input file
    """

    ioprinter.messpf('global_header')

    keystr1 = (
        'EnergyStepOverTemperature, ExcessEnergyOverTemperature, ' +
        'ModelEnergyLimit'
    )
    keystr2 = (
        'CalculationMethod, WellCutoff, ' +
        'ChemicalEigenvalueMax, ReductionMethod, AtomDistanceMin'
    )
    ioprinter.debug_message('     {}'.format(keystr1))
    ioprinter.debug_message('     {}'.format(keystr2))

    if is_abstraction(spc_dct):
        well_extend = None
    else:
        well_extend = 'auto'
        ioprinter.debug_message('Including WellExtend in MESS input')

    header_str = mess_io.writer.global_rates_input(
        temps, pressures, excess_ene_temp=None, well_extend=well_extend)

    return header_str
예제 #17
0
def _calc_nsamp(tors_names, nsamp_par, zma, zrxn=None):
    """ Determine the number of samples to od
    """

    tors_ranges = tuple((0, 2 * numpy.pi) for tors in tors_names)
    tors_range_dct = dict(zip(tors_names, tors_ranges))
    if zrxn is None:
        gra = automol.zmat.graph(zma)
        ntaudof = len(
            automol.graph.rotational_bond_keys(gra, with_h_rotors=False))
        ioprinter.info_message(
            " - Nonmethyl torsional coordinates {}".format(ntaudof))
    else:
        ntaudof = len(tors_names)
    nsamp = util.nsamp_init(nsamp_par, ntaudof)
    ioprinter.debug_message('tors_names', tors_names)
    ioprinter.debug_message('tors_range_dct', tors_range_dct)
    if not tors_range_dct:
        ioprinter.info_message(
            " - No torsional coordinates. Setting nsamp to 1.")
        nsamp = 1

    return nsamp, tors_range_dct
예제 #18
0
def _this_conformer_is_running(zma, cnf_run_fs):
    """ Check the RUN filesystem for similar geometry
        submissions that are currently running
    """

    running = False
    job = elstruct.Job.OPTIMIZATION
    cnf_run_path = cnf_run_fs[0].path()
    ioprinter.debug_message('cnf path ' + cnf_run_path)
    for locs in cnf_run_fs[-1].existing(ignore_bad_formats=True):
        cnf_run_path = cnf_run_fs[-1].path(locs)
        run_fs = autofile.fs.run(cnf_run_path)
        run_path = run_fs[-1].path([job])
        inf_obj = run_fs[-1].file.info.read([job])
        status = inf_obj.status
        if status == autofile.schema.RunStatus.RUNNING:
            start_time = inf_obj.utc_start_time
            current_time = autofile.schema.utc_time()
            if (current_time - start_time).total_seconds() < 3000000:
                subrun_fs = autofile.fs.subrun(run_path)
                inp_str = subrun_fs[0].file.input.read([0, 0])
                inp_str = inp_str.replace('=', '')
                prog = inf_obj.prog
                inp_zma = elstruct.reader.inp_zmatrix(prog, inp_str)
                if automol.zmat.almost_equal(inp_zma,
                                             zma,
                                             dist_rtol=0.018,
                                             ang_atol=.2):
                    ioprinter.info_message(
                        'This conformer was started in the last ' +
                        '{:3.4f} hours in {}.'.format(
                            (current_time - start_time).total_seconds() /
                            3600., run_path))
                    running = True
                    break
    return running
예제 #19
0
def make_header_str(spc_dct, rxn_lst, pes_idx, pesgrp_num, pes_param_dct,
                    hot_enes_dct, label_dct, temps, pressures, float_type):
    """ Built the head of the MESS input file that contains various global
        keywords used for running rate calculations.

        Function determines certain input parameters for the well-extension
        methodology based on the reaction type stored in spc_dct.

        :param spc_dct:
        :type spc_dct: dict[]
        :param temps: temperatures for the rate calculations (in K)
        :type temps: tuple(float)
        :param pressures: pressures for the rate calculations (in atm)
        :type pressures: tuple(float)
        :rtype: str
    """

    ioprinter.messpf('global_header')

    keystr1 = ('EnergyStepOverTemperature, ExcessEnergyOverTemperature, ' +
               'ModelEnergyLimit')
    keystr2 = ('CalculationMethod, WellCutoff, ' +
               'ChemicalEigenvalueMax, ReductionMethod, AtomDistanceMin')
    ioprinter.debug_message(f'     {keystr1}')
    ioprinter.debug_message(f'     {keystr2}')

    # Set the well extension energy thresh
    if is_abstraction_pes(spc_dct, rxn_lst, pes_idx):
        well_extend = None
    else:
        well_extend = 'auto'
        ioprinter.debug_message('Including WellExtend in MESS input')

    # Set other parameters
    # Need the PES number to pull the correct params out of lists
    ped_spc_lst, hot_enes_dct, micro_out_params = energy_dist_params(
        pesgrp_num, pes_param_dct, hot_enes_dct, label_dct)

    header_str = mess_io.writer.global_rates_input(
        temps,
        pressures,
        calculation_method='direct',
        well_extension=well_extend,
        ped_spc_lst=ped_spc_lst,
        hot_enes_dct=hot_enes_dct,
        excess_ene_temp=None,
        micro_out_params=micro_out_params,
        float_type=float_type)

    return header_str
예제 #20
0
def saddle_point_checker(imags):
    """ run things for checking Hessian
    """

    big_imag, kick_imag = 0, 0

    ioprinter.checking('the imaginary frequencies of the saddle point...')
    if len(imags) < 1:
        ioprinter.warning_message('No imaginary modes for geometry')
        status = 'fail'
    else:
        if len(imags) > 1:
            ioprinter.warning_message(
                'More than one imaginary mode for geometry')
            status = 'fail'
        for idx, imag in enumerate(imags):
            if imag <= 50.0:
                ioprinter.warning_message(
                    f'Mode {str(idx+1)} {imag} cm-1 is low,')
            elif 50.0 < imag <= 200.0:
                lowstr = f'Mode {str(idx+1)} {imag} cm-1 is low,'
                ioprinter.debug_message(
                    lowstr + ' check mode and see if it should be corrected')
                big_imag += 1
                # Adding to the kick counter kills code for good TSs
                # Some addditions of big species have low mode of this
                # ioprinter.warning_message(
                #     lowstr + 'need a kickoff procedure to remove')
                # kick_imag += 1
            else:
                ioprinter.debug_message(
                    f'Mode {str(idx+1)} {imag} cm-1 likely fine')
                big_imag += 1

        if big_imag > 1:
            ioprinter.warning_message(
                'More than one imaginary mode for geometry')
            if kick_imag >= 1:
                ioprinter.debug_message('Will kickoff to get saddle point')
                status = 'kickoff'
            else:
                status = 'failure'
        elif big_imag == 1:
            status = 'success'
        elif big_imag == 0:
            status = 'failure'
            ioprinter.warning_message('Did not find any appropriate modes')

    return status
예제 #21
0
def _check_freqs(imags):
    """ Check the magnitude of the imaginary modes.
    """

    big_imag, kick_imag = 0, 0

    ioprinter.checking('the imaginary frequencies of the saddle point...')
    if len(imags) < 1:
        ioprinter.warning_message('No imaginary modes for geometry')
        status = 'fail'
    else:
        if len(imags) > 1:
            ioprinter.warning_message(
                'More than one imaginary mode for geometry')
            status = 'fail'
        for idx, imag in enumerate(imags):
            if imag <= 50.0:
                ioprinter.warning_message(f'Mode {idx+1} {imag} cm-1 is low,')
            elif 50.0 < imag <= 200.0:
                lowstr = f'Mode {idx+1} {imag} cm-1 is low,'
                ioprinter.debug_message(
                    lowstr + ' check mode and see if it should be corrected')
                big_imag += 1
                # Adding to the kick counter kills code for good TSs
                # Some addditions of big species have low mode of this
                # ioprinter.warning_message(
                #     lowstr + 'need a kickoff procedure to remove')
                # kick_imag += 1
            else:
                ioprinter.debug_message(
                    f'Mode {idx+1} {imag} cm-1 is likely fine,')
                big_imag += 1

        if big_imag > 1:
            ioprinter.warning_message(
                'More than one imaginary mode for geometry')
            if kick_imag >= 1:
                ioprinter.debug_message('Will kickoff to get saddle point')
                status = 'kick'
            else:
                status = False
        elif big_imag == 1:
            status = True
        elif big_imag == 0:
            status = False

    return status
예제 #22
0
def make_header_str(spc_dct, temps, pressures):
    """ Built the head of the MESS input file that contains various global
        keywords used for running rate calculations.

        Function determines certain input parameters for the well-extension
        methodology based on the reaction type stored in spc_dct.

        :param spc_dct:
        :type spc_dct: dict[]
        :param temps: temperatures for the rate calculations (in K)
        :type temps: tuple(float)
        :param pressures: pressures for the rate calculations (in atm)
        :type pressures: tuple(float)
        :rtype: str
    """

    ioprinter.messpf('global_header')

    keystr1 = ('EnergyStepOverTemperature, ExcessEnergyOverTemperature, ' +
               'ModelEnergyLimit')
    keystr2 = ('CalculationMethod, WellCutoff, ' +
               'ChemicalEigenvalueMax, ReductionMethod, AtomDistanceMin')
    ioprinter.debug_message('     {}'.format(keystr1))
    ioprinter.debug_message('     {}'.format(keystr2))

    if is_abstraction_pes(spc_dct):
        well_extend = None
    else:
        well_extend = 'auto'
        ioprinter.debug_message('Including WellExtend in MESS input')

    header_str = mess_io.writer.global_rates_input(temps,
                                                   pressures,
                                                   excess_ene_temp=None,
                                                   well_extend=well_extend)

    return header_str
예제 #23
0
파일: sp.py 프로젝트: Auto-Mech/mechdriver
def run_prop(zma,
             geo,
             spc_info,
             thy_info,
             geo_run_fs,
             geo_save_fs,
             locs,
             run_prefix,
             script_str,
             overwrite,
             zrxn=None,
             retryfail=True,
             method_dct=None,
             ref_val=None,
             **kwargs):
    """ Determine the properties in the given location
    """

    # Set unneeded vals
    _, _, _, _ = zrxn, method_dct, ref_val, run_prefix

    # Set input geom
    geo_run_path = geo_run_fs[-1].path(locs)
    geo_save_path = geo_save_fs[-1].path(locs)
    if geo is not None:
        job_geo = geo
    else:
        job_geo = automol.zmat.geometry(zma)

    if _json_database(geo_save_path):
        dmom_exists = geo_save_fs[-1].json.dipole_moment.exists(locs)
        polar_exists = geo_save_fs[-1].json.polarizability.exists(locs)
    else:
        dmom_exists = geo_save_fs[-1].file.dipole_moment.exists(locs)
        polar_exists = geo_save_fs[-1].file.polarizability.exists(locs)
    if not dmom_exists or not polar_exists:
        ioprinter.info_message(
            'Either no dipole moment or polarizability found in'
            'in save filesys. Running properties...')
        _run = True
    elif overwrite:
        ioprinter.info_message(
            'User specified to overwrite property with new run...')
        _run = True
    else:
        _run = False

    if _run:

        run_fs = autofile.fs.run(geo_run_path)

        success, ret = es_runner.execute_job(
            job=elstruct.Job.MOLPROP,
            script_str=script_str,
            run_fs=run_fs,
            geo=job_geo,
            spc_info=spc_info,
            thy_info=thy_info,
            zrxn=zrxn,
            overwrite=overwrite,
            retryfail=retryfail,
            **kwargs,
        )

        if success:
            inf_obj, _, out_str = ret

            ioprinter.info_message(" - Reading dipole moment from output...")
            dmom = elstruct.reader.dipole_moment(inf_obj.prog, out_str)
            ioprinter.info_message(" - Reading polarizability from output...")
            polar = elstruct.reader.polarizability(inf_obj.prog, out_str)

            ioprinter.debug_message('dip mom', dmom)
            ioprinter.debug_message('polar', polar)
            ioprinter.info_message(
                " - Saving dipole moment and polarizability...")
            if _json_database(geo_save_path):
                # geo_save_fs[-1].json.property_info.write(inf_obj, locs)
                # geo_save_fs[-1].json.property_input.write(
                #     inp_str, locs)
                geo_save_fs[-1].json.dipole_moment.write(dmom, locs)
                geo_save_fs[-1].json.polarizability.write(polar, locs)
            else:
                # geo_save_fs[-1].file.property_info.write(inf_obj, locs)
                # geo_save_fs[-1].file.property_input.write(
                #     inp_str, locs)
                geo_save_fs[-1].file.dipole_moment.write(dmom, locs)
                geo_save_fs[-1].file.polarizability.write(polar, locs)
            ioprinter.save_geo(geo_save_path)

    else:
        ioprinter.existing_path('Dipole moment and polarizability',
                                geo_save_path)
예제 #24
0
파일: ene.py 프로젝트: sjklipp/mechdriver
def sum_channel_enes(channel_infs, ref_ene, ene_lvl='ene_chnlvl'):
    """ sum the energies
    """

    # Initialize sum ene dct
    sum_ene = {}

    # Calculate energies for species
    reac_ene = 0.0
    reac_ref_ene = 0.0
    for rct in channel_infs['reacs']:
        reac_ene += rct[ene_lvl]
        reac_ref_ene += rct['ene_tsref']
        ioprinter.info_message('reac ene', rct[ene_lvl], rct['ene_tsref'])
    sum_ene.update({'reacs': reac_ene})

    prod_ene = 0.0
    prod_ref_ene = 0.0
    for prd in channel_infs['prods']:
        prod_ene += prd[ene_lvl]
        prod_ref_ene += prd['ene_tsref']
        ioprinter.info_message('prod ene', prd[ene_lvl], prd['ene_tsref'])
    sum_ene.update({'prods': prod_ene})

    # Calculate energies for fake entrance- and exit-channel wells
    if 'fake_vdwr' in channel_infs:
        vdwr_ene = reac_ene - (1.0 * phycon.KCAL2EH)
        sum_ene.update({'fake_vdwr': vdwr_ene, 'fake_vdwr_ts': reac_ene})
    if 'fake_vdwp' in channel_infs:
        vdwp_ene = prod_ene - (1.0 * phycon.KCAL2EH)
        sum_ene.update({'fake_vdwp': vdwp_ene, 'fake_vdwp_ts': prod_ene})

    ioprinter.debug_message('REAC HoF (0 K) spc lvl kcal/mol: ',
                            reac_ene * phycon.EH2KCAL)
    ioprinter.debug_message('REAC HoF (0 K) ts lvl kcal/mol: ',
                            reac_ref_ene * phycon.EH2KCAL)
    ioprinter.debug_message('PROD HoF (0 K) spc lvl kcal/mol: ',
                            prod_ene * phycon.EH2KCAL)
    ioprinter.debug_message('PROD HoF (0 K) ts lvl kcal/mol: ',
                            prod_ref_ene * phycon.EH2KCAL)
    # Scale all of the current energies in the dict
    for spc, ene in sum_ene.items():
        sum_ene[spc] = (ene - ref_ene) * phycon.EH2KCAL


# Set the inner TS ene and scale them

    if channel_infs['ts'][0]['writer'] in ('pst_block', 'vrctst_block'):
        if len(channel_infs['reacs']) == 2:
            ts_enes = [sum(inf['ene_chnlvl'] for inf in channel_infs['reacs'])]
        else:
            ts_enes = [sum(inf['ene_chnlvl'] for inf in channel_infs['prods'])]
        channel_infs['ts'][0].update({'ene_chnlvl': ts_enes})
    else:
        if 'rpath' in channel_infs['ts']:
            ts_enes = [dct[ene_lvl] for dct in channel_infs['ts']['rpath']]
        else:
            ts_enes = [dct[ene_lvl] for dct in channel_infs['ts']]
            # ts_enes = [channel_infs['ts'][ene_lvl]]
        ioprinter.debug_message('TS HoF (0 K) ts lvl kcal/mol: ',
                                ts_enes[0] * phycon.EH2KCAL)
        if reac_ref_ene:
            if abs(ts_enes[0] - reac_ref_ene) < abs(ts_enes[0] - prod_ref_ene):
                ts_enes = [ene - reac_ref_ene + reac_ene for ene in ts_enes]
            else:
                ts_enes = [ene - prod_ref_ene + prod_ene for ene in ts_enes]
        ioprinter.debug_message('TS HoF (0 K) approx spc lvl kcal/mol: ',
                                ts_enes[0] * phycon.EH2KCAL)
    ts_enes = [(ene - ref_ene) * phycon.EH2KCAL for ene in ts_enes]

    sum_ene.update({'ts': ts_enes})

    return sum_ene
예제 #25
0
파일: typ.py 프로젝트: Auto-Mech/mechdriver
def squash_tors_pot(spc_mod_dct_i):
    """ determine if we need to scale the potential
    """
    ioprinter.debug_message('tors model in scale set',
                            spc_mod_dct_i['tors']['mod'])
    return bool(spc_mod_dct_i['tors']['mod'] in ('1dhrfa', 'tau-1dhrfa'))
예제 #26
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 = thermfit.prepare_basis(ref_scheme,
                                       spc_dct, (spc_name, ),
                                       zrxn=zrxn)
    uniref_dct = thermfit.unique_basis_species(basis_dct, spc_dct)

    # 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 = thermfit.prepare_basis(ts_ref_scheme,
                                                       spc_dct, (spc_name, ),
                                                       zrxn=zrxn)
                uniref_dct_trs = thermfit.unique_basis_species(
                    basis_dct_trs, spc_dct)

                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,
                                                    read_species=False)
                    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  (hart): ', ene_chnlvl)
    ioprinter.info_message('Hf0K Energy (hart): ', hf0k * phycon.KCAL2KJ)

    return hf0k, hf0k_trs, chn_basis_ene_dct, basis_dct
예제 #27
0
def rpvtst_data(ts_dct,
                reac_dcts,
                spc_mod_dct_i,
                run_prefix,
                save_prefix,
                sadpt=False):
    """ Pull all of the neccessary information from the
        filesystem for a species
    """

    zrxn = ts_dct['zrxn']

    # Set up all the filesystem objects using models and levels
    if sadpt:
        # Set up filesystems and coordinates for saddle point
        # Scan along RxnCoord is under THY/TS/CONFS/cid/Z
        pf_filesystems = filesys.models.pf_filesys(ts_dct, spc_mod_dct_i,
                                                   run_prefix, save_prefix,
                                                   True)
        tspaths = pf_filesystems['harm']
        [_, cnf_save_path, min_locs, _, cnf_run_fs] = tspaths
        ts_run_path = cnf_run_fs[-1].path(min_locs)

        # Set TS reaction coordinate
        frm_name = 'IRC'
        scn_vals = filesys.models.get_rxn_scn_coords(cnf_save_path, frm_name)
        scn_vals.sort()
        scn_ene_info = spc_mod_dct_i['ene'][1][0][1]  # fix to be ene lvl
        scn_prefix = cnf_save_path
    else:
        # Set up filesystems and coordinates for reaction path
        # Scan along RxnCoord is under THY/TS/Z
        tspaths = filesys.models.set_rpath_filesys(ts_dct,
                                                   spc_mod_dct_i['rpath'][1])
        ts_run_path, _, _, thy_save_path = tspaths

        # Set TS reaction coordinate
        scn_vals = filesys.models.get_rxn_scn_coords(thy_save_path, frm_name)
        scn_vals.sort()
        scn_ene_info = spc_mod_dct_i['rpath'][1][0]
        scn_prefix = thy_save_path

    # Modify the scn thy info
    ioprinter.debug_message('scn thy info', scn_ene_info)
    ioprinter.info_message('scn vals', scn_vals)
    mod_scn_ene_info = filesys.inf.modify_orb_restrict(
        filesys.inf.get_spc_info(ts_dct), scn_ene_info)
    # scn thy info [[1.0, ['molpro2015', 'ccsd(t)', 'cc-pvdz', 'RR']]]

    # Need to read the sp vals along the scan. add to read
    ref_ene = 0.0
    enes, geoms, grads, hessians, _, _ = filesys.read.potential(
        [frm_name],
        [scn_vals],
        scn_prefix,
        mod_scn_ene_info,
        ref_ene,
        constraint_dct=None,  # No extra frozen treatments
        read_geom=True,
        read_grad=True,
        read_hess=True)
    script_str = autorun.SCRIPT_DCT['projrot']
    freqs = autorun.projrot.pot_frequencies(script_str, geoms, grads, hessians,
                                            ts_run_path)

    # Get the energies and zpes at R_ref
    if not sadpt:
        _, ene_hs_sr_ref, ene_hs_mr_ref = ene.rpath_ref_idx(
            ts_dct, scn_vals, frm_name, scn_prefix, spc_mod_dct_i['ene'],
            spc_mod_dct_i['rpath'][1])
    fr_idx = len(scn_vals) - 1
    zpe_ref = (sum(freqs[(fr_idx, )]) / 2.0) * phycon.WAVEN2KCAL

    # Get the reactants and infinite seperation energy
    reac_ene = 0.0
    ene_hs_sr_inf = 0.0
    for dct in reac_dcts:
        pf_filesystems = filesys.models.pf_filesys(dct, spc_mod_dct_i,
                                                   run_prefix, save_prefix,
                                                   False)
        new_spc_dct_i = {
            'ene': spc_mod_dct_i['ene'],
            'harm': spc_mod_dct_i['harm'],
            'tors': spc_mod_dct_i['tors']
        }
        reac_ene += ene.read_energy(dct,
                                    pf_filesystems,
                                    new_spc_dct_i,
                                    run_prefix,
                                    read_ene=True,
                                    read_zpe=True,
                                    saddle=sadpt)

        ioprinter.debug_message('rpath', spc_mod_dct_i['rpath'][1])
        new_spc_dct_i = {
            'ene': ['mlvl', [[1.0, spc_mod_dct_i['rpath'][1][2]]]],
            'harm': spc_mod_dct_i['harm'],
            'tors': spc_mod_dct_i['tors']
        }
        ene_hs_sr_inf += ene.read_energy(dct,
                                         pf_filesystems,
                                         new_spc_dct_i,
                                         run_prefix,
                                         read_ene=True,
                                         read_zpe=False)

    # Scale the scn values
    if sadpt:
        scn_vals = [val / 100.0 for val in scn_vals]
    # scn_vals = [val * phycon.BOHR2ANG for val in scn_vals]

    # Grab the values from the read
    inf_dct = {}
    inf_dct['rpath'] = []
    pot_info = zip(scn_vals, enes.values(), geoms.values(), freqs.values())
    for rval, pot, geo, frq in pot_info:

        # Scale the r-values

        # Get the relative energy (edit for radrad scans)
        zpe = (sum(frq) / 2.0) * phycon.WAVEN2KCAL
        if sadpt:
            zero_ene = (pot + zpe) * phycon.KCAL2EH
        else:
            ioprinter.debug_message('enes')
            ioprinter.debug_message('reac ene', reac_ene)
            ioprinter.debug_message('hs sr', ene_hs_sr_ref)
            ioprinter.debug_message('inf', ene_hs_sr_inf)
            ioprinter.debug_message('hs mr', ene_hs_mr_ref)
            ioprinter.debug_message('pot R', pot * phycon.KCAL2EH)
            ioprinter.debug_message('zpe', zpe)
            ioprinter.debug_message('zpe ref', zpe_ref)

            elec_ene = (ene_hs_sr_ref - ene_hs_sr_inf - ene_hs_mr_ref +
                        pot * phycon.KCAL2EH)
            zpe_pt = zpe - zpe_ref
            zero_ene = reac_ene + (elec_ene + zpe_pt * phycon.KCAL2EH)
            ioprinter.info_message('elec ene', elec_ene)
            ioprinter.info_message('zero ene', zero_ene)

        # ENE
        # ene = (reac_ene +
        #        ene_hs_sr(R_ref) - ene_hs_sr(inf) +
        #        ene_ls_mr(R_ref) - ene_hs_mr(R_ref) +
        #        ene_ls_mr(R) - ene_ls_mr(R_ref))
        # ene = (reac_ene +
        #        ene_hs_sr(R_ref) - ene_hs_sr(inf) -
        #        ene_hs_mr(R_ref) + ene_ls_mr(R))
        # inf_sep_ene = reac_ene + hs_sr_ene - hs_mr_ene
        # inf_sep_ene_p = (reac_ene +
        #                  hs_sr_ene(R_ref) - ene_hs_sr(inf) +
        #                  ls_mr_ene(R_ref) - hs_mr_ene(R_ref))
        # ene = inf_sep_ene_p + ene_ls_mr(R) - ene_ls_mr(R_ref)
        # ZPE
        # zpe = zpe(R) - zpe(inf)
        # or
        # zpe = zpe_ls_mr(R) - zpe_ls_mr(R_ref)

        # Set values constant across the scan
        elec_levels = ts_dct['elec_levels']

        # Create info dictionary and append to lst
        keys = ['rval', 'geom', 'freqs', 'elec_levels', 'ene_chnlvl']
        vals = [rval, geo, frq, elec_levels, zero_ene]
        inf_dct['rpath'].append(dict(zip(keys, vals)))

    # Calculate and store the imaginary mode
    if sadpt:
        _, imag, _ = vib.read_harmonic_freqs(pf_filesystems,
                                             run_prefix,
                                             zrxn=zrxn)
        ts_idx = scn_vals.index(0.00)
    else:
        imag = None
        ts_idx = 0
    inf_dct.update({'imag': imag})
    inf_dct.update({'ts_idx': ts_idx})

    return inf_dct
예제 #28
0
def run_tau(zma, spc_info, thy_info, nsamp, tors_range_dct,
            tau_run_fs, tau_save_fs, script_str, overwrite,
            saddle, **kwargs):
    """ run sampling algorithm to find tau dependent geometries
    """
    if not tors_range_dct:
        ioprinter.info_message(
            "No torsional coordinates. Setting nsamp to 1.")
        nsamp = 1

    tau_save_fs[0].create()

    vma = automol.zmat.var_(zma)
    if tau_save_fs[0].file.vmatrix.exists():
        existing_vma = tau_save_fs[0].file.vmatrix.read()
        assert vma == existing_vma
    tau_save_fs[0].file.vmatrix.write(vma)
    idx = 0
    nsamp0 = nsamp
    inf_obj = autofile.schema.info_objects.tau_trunk(0, tors_range_dct)
    while True:
        if tau_save_fs[0].file.info.exists():
            inf_obj_s = tau_save_fs[0].file.info.read()
            nsampd = inf_obj_s.nsamp
        elif tau_run_fs[0].file.info.exists():
            inf_obj_r = tau_run_fs[0].file.info.read()
            nsampd = inf_obj_r.nsamp
        else:
            nsampd = 0

        nsamp = nsamp0 - nsampd
        if nsamp <= 0:
            ioprinter.info_message(
                'Reached requested number of samples. ',
                'Tau sampling complete.')
            break

        ioprinter.info_message("New nsamp is {:d}.".format(nsamp), indent=1)

        samp_zma, = automol.zmat.samples(zma, 1, tors_range_dct)
        tid = autofile.schema.generate_new_tau_id()
        locs = [tid]

        tau_run_fs[-1].create(locs)
        tau_run_prefix = tau_run_fs[-1].path(locs)
        run_fs = autofile.fs.run(tau_run_prefix)

        idx += 1
        ioprinter.info_message("Run {}/{}".format(idx, nsamp0))

        ioprinter.debug_message(
            'Checking if ZMA has high repulsion...', newline=1)
        geo = automol.zmat.geometry(zma)
        samp_geo = automol.zmat.geometry(samp_zma)
        if automol.pot.low_repulsion_struct(geo, samp_geo):
            ioprinter.debug_message('ZMA fine.')
            es_runner.run_job(
                job=elstruct.Job.OPTIMIZATION,
                script_str=script_str,
                run_fs=run_fs,
                geo=samp_zma,
                spc_info=spc_info,
                thy_info=thy_info,
                saddle=saddle,
                overwrite=overwrite,
                frozen_coordinates=tors_range_dct.keys(),
                **kwargs
            )
        else:
            ioprinter.warning_message('repulsive ZMA:')
            inp_str = elstruct.writer.optimization(
                geo=samp_zma,
                charge=spc_info[1],
                mult=spc_info[2],
                method=thy_info[1],
                basis=thy_info[2],
                prog=thy_info[0],
                orb_type=thy_info[3],
                mol_options=['nosym'],
                frozen_coordinates=tors_range_dct.keys(),
            )
            tau_run_fs[-1].file.geometry_input.write(inp_str, locs)
            ioprinter.warning_message(
                'geometry for bad ZMA at', tau_run_fs[-1].path(locs))

        # nsampd += 1
        # inf_obj.nsamp = nsampd
        # tau_save_fs[0].file.info.write(inf_obj)
        # tau_run_fs[0].file.info.write(inf_obj)

        if tau_save_fs[0].file.info.exists():
            inf_obj_s = tau_save_fs[0].file.info.read()
            nsampd = inf_obj_s.nsamp
        elif tau_run_fs[0].file.info.exists():
            inf_obj_r = tau_run_fs[0].file.info.read()
            nsampd = inf_obj_r.nsamp
        nsampd += 1
        inf_obj.nsamp = nsampd
        tau_save_fs[0].file.info.write(inf_obj)
        tau_run_fs[0].file.info.write(inf_obj)
예제 #29
0
def _make_fake_mess_strs(chnl, side, fake_inf_dcts,
                         chnl_enes, label_dct, side_label):
    """ write the MESS strings for the fake wells and TSs
    """

    # Set vars based on the reacs/prods
    reacs, prods = chnl
    if side == 'reacs':
        well_key = 'fake_vdwr'
        ts_key = 'fake_vdwr_ts'
        prepend_key = 'FRB'
        side_idx = 0
    elif side == 'prods':
        well_key = 'fake_vdwp'
        ts_key = 'fake_vdwp_ts'
        side_idx = 1
        if reacs in (prods, prods[::-1]):
            prepend_key = 'FRB'
        else:
            prepend_key = 'FPB'

    # Initialize well and ts strs and data dcts
    fake_dat_dct = {}
    well_str, ts_str = '', ''

    # Build a fake TS dct
    ts_inf_dct = {
        'n_pst': 6.0,
        'cn_pst': 10.0
    }

    # MESS string for the fake reactant side well
    well_dct_key = make_rxn_str(chnl[side_idx], prepend='F')
    well_dct_key_rev = make_rxn_str(chnl[side_idx][::-1], prepend='F')
    if well_dct_key in label_dct:
        fake_well_label = label_dct[well_dct_key]
    elif well_dct_key_rev in label_dct:
        fake_well_label = label_dct[well_dct_key_rev]
    else:
        ioprinter.warning_message(
            'No label {} in label dict'.format(well_dct_key))
    # well_str += mess_io.writer.species_separation_str()
    well_str += '\n! Fake Well for {}\n'.format(
        '+'.join(chnl[side_idx]))
    fake_well, well_dat = blocks.fake_species_block(*fake_inf_dcts)
    well_str += mess_io.writer.well(
        fake_well_label, fake_well, chnl_enes[well_key])

    # MESS PST TS string for fake reactant side well -> reacs
    pst_dct_key = make_rxn_str(chnl[side_idx], prepend=prepend_key)
    pst_dct_key_rev = make_rxn_str(chnl[side_idx][::-1], prepend=prepend_key)
    if pst_dct_key in label_dct:
        pst_label = label_dct[pst_dct_key]
    elif pst_dct_key_rev in label_dct:
        pst_label = label_dct[pst_dct_key_rev]
    else:
        ioprinter.debug_message(
            'No label {} in label dict'.format(pst_dct_key))
    pst_ts_str, pst_ts_dat = blocks.pst_block(ts_inf_dct, *fake_inf_dcts)
    ts_str += '\n' + mess_io.writer.ts_sadpt(
        pst_label, side_label, fake_well_label, pst_ts_str,
        chnl_enes[ts_key], tunnel='')

    # Build the data dct
    if well_dat:
        fake_dat_dct.update(well_dat)
    if pst_ts_dat:
        fake_dat_dct.update(pst_ts_dat)

    return well_str, ts_str, fake_well_label, fake_dat_dct
예제 #30
0
def make_pes_mess_str(spc_dct, rxn_lst, pes_idx,
                      run_prefix, save_prefix, label_dct,
                      pes_model_dct_i, spc_model_dct_i,
                      spc_model, thy_dct):
    """ Write all the MESS input file strings for the reaction channels
    """

    ioprinter.messpf('channel_section')

    # Initialize empty MESS strings
    full_well_str, full_bi_str, full_ts_str = '', '', ''
    full_dat_str_dct = {}
    pes_ene_dct = {}
    conn_lst = tuple()

    # Set the energy and model for the first reference species
    ioprinter.info_message('\nCalculating reference energy for PES')
    ref_ene = set_reference_ene(
        rxn_lst, spc_dct, thy_dct,
        pes_model_dct_i, spc_model_dct_i,
        run_prefix, save_prefix, ref_idx=0)

    # Loop over all the channels and write the MESS strings
    written_labels = []
    basis_energy_dct = {}
    for rxn in rxn_lst:

        chnl_idx, (reacs, prods) = rxn

        ioprinter.obj('vspace')
        ioprinter.reading('PES electrion structure data')
        ioprinter.channel(chnl_idx, reacs, prods)

        # Set the TS name and channel model
        tsname = 'ts_{:g}_{:g}'.format(pes_idx+1, chnl_idx+1)

        # Obtain all of the species data
        if spc_model not in basis_energy_dct:
            basis_energy_dct[spc_model] = {}

        # Pass in full ts class
        chnl_infs, chn_basis_ene_dct = get_channel_data(
            reacs, prods, tsname,
            spc_dct, basis_energy_dct[spc_model],
            pes_model_dct_i, spc_model_dct_i,
            run_prefix, save_prefix)

        basis_energy_dct[spc_model].update(chn_basis_ene_dct)

        # Calculate the relative energies of all spc on the channel
        chnl_enes = sum_channel_enes(chnl_infs, ref_ene)

        # Write the mess strings for all spc on the channel
        mess_strs, dat_str_dct, written_labels = _make_channel_mess_strs(
            tsname, reacs, prods, spc_dct, label_dct, written_labels,
            chnl_infs, chnl_enes, spc_model_dct_i)

        # Append to full MESS strings
        [well_str, bi_str, ts_str] = mess_strs
        full_well_str += well_str
        full_bi_str += bi_str
        full_ts_str += ts_str
        full_dat_str_dct.update(dat_str_dct)

        ioprinter.debug_message('rxn', rxn)
        ioprinter.debug_message('enes', chnl_enes)
        ioprinter.debug_message('label dct', label_dct)
        ioprinter.debug_message('written labels', written_labels)

    # Combine all the reaction channel strings
    rxn_chan_str = '\n'.join([full_well_str, full_bi_str, full_ts_str])

    return rxn_chan_str, full_dat_str_dct, pes_ene_dct, conn_lst