Пример #1
0
def main():
    try:
        input_file = sys.argv[1]
    except IndexError:
        print('To use KinBot, supply one argument being the input file!')
        sys.exit(-1)

    # print the license message to the console
    print(license_message.message)

    # initialize the parameters for this run
    masterpar = Parameters(input_file)
    par = masterpar.par
    input_file = masterpar.input_file
    # set up the logging environment
    if par['verbose']:
        logging.basicConfig(filename='kinbot.log', level=logging.DEBUG)
    else:
        logging.basicConfig(filename='kinbot.log', level=logging.INFO)

    # write the license message to the log file
    logging.info(license_message.message)
    logging.info('Input parameters')
    for param in par:
        logging.info('{} {}'.format(param, par[param]))
    # time stamp of the KinBot start
    logging.info('Starting KinBot at {}'.format(datetime.datetime.now()))

    # Make the necessary directories
    if not os.path.exists('perm'):
        os.makedirs('perm')
    if not os.path.exists('scratch'):
        os.makedirs('scratch')
    if not os.path.exists(par['single_point_qc']):
        os.mkdir(par['single_point_qc'])
    if par['rotor_scan'] == 1:
        if not os.path.exists('hir'):
            os.mkdir('hir')
        if not os.path.exists('hir_profiles'):
            os.mkdir('hir_profiles')
        if not os.path.exists('perm/hir/'):
            os.makedirs('perm/hir/')
    if par['conformer_search'] == 1:
        if not os.path.exists('conf'):
            os.mkdir('conf')
        if not os.path.exists('perm/conf'):
            os.makedirs('perm/conf')
    if not os.path.exists('me'):
        os.mkdir('me')

    # initialize the reactant
    well0 = StationaryPoint('well0',
                            par['charge'],
                            par['mult'],
                            smiles=par['smiles'],
                            structure=par['structure'])
    well0.short_name = 'w1'
    # write the initial reactant geometry to a file for visualization
    geom_out = open('geometry.xyz', 'w')
    geom_out.write('{}\n\n'.format(well0.natom))
    for i, at in enumerate(well0.atom):
        x, y, z = well0.geom[i]
        geom_out.write('{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z))
    geom_out.write('\n\n')
    geom_out.close()

    # characterize the initial reactant
    well0.characterize(dimer=par['dimer'])
    well0.name = str(well0.chemid)
    start_name = well0.name

    # initialize the qc instance
    qc = QuantumChemistry(par)
    # only run filecopying if PES is turned on
    # if par['pes']:
    # check if this well was calcualted before in another directory
    # this flag indicates that this kinbot run
    # should wait for the information from another
    # kinbot run to become available and copy the necessary information
    #    wait_for_well = 1
    #    while wait_for_well:
    #        wait_for_well = filecopying.copy_from_database_folder(well0.chemid, well0.chemid, qc)
    #        if wait_for_well:
    #            time.sleep(1)

    # start the initial optimization of the reactant
    logging.info('Starting optimization of intial well')
    qc.qc_opt(well0, well0.geom)
    err, well0.geom = qc.get_qc_geom(str(well0.chemid) + '_well',
                                     well0.natom,
                                     wait=1)
    err, well0.freq = qc.get_qc_freq(str(well0.chemid) + '_well',
                                     well0.natom,
                                     wait=1)
    if err < 0:
        logging.error('Error with initial structure optimization.')
        return
    if any(well0.freq[i] <= 0 for i in range(len(well0.freq))):
        logging.error('Found imaginary frequency for initial structure.')
        return

    # characterize again and look for differences
    well0.characterize(dimer=par['dimer'])
    well0.name = str(well0.chemid)
    if well0.name != start_name:
        logging.error(
            'The first well optimized to a structure different from the input.'
        )
        return

    # do an MP2 optimization of the reactant,
    # to compare some scan barrier heigths to
    if par['families'] == ['all'] or \
            'birad_recombination_R' in par['families'] or \
            'r12_cycloaddition' in par['families'] or \
            'r14_birad_scission' in par['families'] or \
            'R_Addition_MultipleBond' in par['families'] or \
            (par['skip_families'] != ['none'] and \
            ('birad_recombination_R' not in par['skip_families'] or \
            'r12_cycloaddition' not in par['skip_families'] or \
            'r14_birad_scission' not in par['skip_families'] or \
            'R_Addition_MultipleBond' not in par['skip_families'])) or \
            par['reaction_search'] == 0:
        logging.info('Starting MP2 optimization of intial well')
        qc.qc_opt(well0, well0.geom, mp2=1)
        err, geom = qc.get_qc_geom(
            str(well0.chemid) + '_well_mp2', well0.natom, 1)

    # comparison for barrierless scan
    if par['barrierless_saddle']:
        logging.info(
            'Optimization of intial well for barrierless at {}/{}'.format(
                par['barrierless_saddle_method'],
                par['barrierless_saddle_basis']))
        qc.qc_opt(well0, well0.geom, bls=1)
        err, geom = qc.get_qc_geom(
            str(well0.chemid) + '_well_bls', well0.natom, 1)

    # characterize again and look for differences
    well0.characterize(dimer=par['dimer'])
    well0.name = str(well0.chemid)

    err, well0.energy = qc.get_qc_energy(str(well0.chemid) + '_well', 1)
    err, well0.zpe = qc.get_qc_zpe(str(well0.chemid) + '_well', 1)

    well_opt = Optimize(well0, par, qc, wait=1)
    well_opt.do_optimization()
    if well_opt.shigh == -999:
        logging.error(
            'Error with high level optimization of initial structure.')
        return

    if par['pes']:
        filecopying.copy_to_database_folder(well0.chemid, well0.chemid, qc)

    if par['reaction_search'] == 1:
        logging.info('Starting reaction searches of intial well')
        rf = ReactionFinder(well0, par, qc)
        rf.find_reactions()
        rg = ReactionGenerator(well0, par, qc, input_file)
        rg.generate()

    if par['homolytic_scissions'] == 1:
        logging.info('Starting the search for homolytic scission products')
        well0.homolytic_scissions = HomolyticScissions(well0, par, qc)
        well0.homolytic_scissions.find_homolytic_scissions()

    if par['me'] > 0:  # it will be 2 for kinbots when the mess file is needed but not run
        mess = MESS(par, well0)
        mess.write_input(qc)

        if par['me'] == 1:
            logging.info('Starting Master Equation calculations')
            if par['me_code'] == 'mess':
                mess.run()

    postprocess.createSummaryFile(well0, qc, par)
    postprocess.createPESViewerInput(well0, qc, par)
    postprocess.creatMLInput(well0, qc, par)

    logging.info('Finished KinBot at {}'.format(datetime.datetime.now()))
    print("Done!")
Пример #2
0
def create_mess_input(par, wells, products, reactions, well_energies,
                      prod_energies, parent):
    """
    When calculating a full pes, the files from the separate wells
    are read and concatenated into one file
    Two things per file need to be updated
    1. the names of all the wells, bimolecular products and ts's
    2. all the zpe corrected energies
    """
    # generate short names for all startionary points
    well_short, pr_short, fr_short, ts_short = create_short_names(
        wells, products, reactions)
    # list of the strings to write to mess input file
    s = []
    # write the header
    s.append(write_header(par, well_short[wells[0]]))

    # write the wells
    s.append('######################')
    s.append('# WELLS')
    s.append('######################')
    for well in wells:
        name = well_short[well] + ' ! ' + well
        energy = well_energies[well]
        with open(parent[well] + '/' + well + '.mess') as f:
            s.append(f.read().format(name=name, zeroenergy=energy))
        s.append('!****************************************')

    # write the products
    s.append('######################')
    s.append('# BIMOLECULAR PRODUCTS')
    s.append('######################')
    for prod in products:
        name = pr_short[prod] + ' ! ' + prod
        energy = prod_energies[prod]
        fr_names = {}
        for fr in prod.split('_'):
            key = 'fr_name_{}'.format(fr)
            value = fr_short[fr] + ' ! ' + fr
            fr_names[key] = value
        with open(parent[prod] + '/' + prod + '.mess') as f:
            s.append(f.read().format(name=name,
                                     ground_energy=energy,
                                     **fr_names))
        s.append('!****************************************')

    # write the barrier
    s.append('######################')
    s.append('# BARRIERS')
    s.append('######################')
    for rxn in reactions:
        name = [ts_short[rxn[1]]]
        name.append(well_short[rxn[0]])
        if len(rxn[2]) == 1:
            name.append(well_short[rxn[2][0]])
        else:
            name.append(pr_short['_'.join(sorted(rxn[2]))])
        name.append('!')
        name.append(rxn[1])
        energy = rxn[3]
        with open(rxn[0] + '/' + rxn[1] + '.mess') as f:
            s.append(f.read().format(name=' '.join(name), zeroenergy=energy))
        s.append('!****************************************')

    # add last end statement
    s.append('!****************************************')
    s.append('End ! end kinetics\n')

    if not os.path.exists('me'):
        os.mkdir('me')

    # write everything to a file
    with open('me/mess.inp', 'w') as f:
        f.write('\n'.join(s))

    dummy = StationaryPoint('dummy',
                            par.par['charge'],
                            par.par['mult'],
                            smiles=par.par['smiles'],
                            structure=par.par['structure'])

    mess = MESS(par, dummy)
    if par.par['me']:
        mess.run()
Пример #3
0
def main():
    try:
        input_file = sys.argv[1]
    except IndexError:
        print('To use KinBot, supply one argument being the input file!')
        sys.exit(-1)

    # print the license message to the console
    print(license_message.message)

    # initialize the parameters for this run
    par = Parameters(input_file)

    # set up the logging environment
    if par.par['verbose']:
        logging.basicConfig(filename='kinbot.log', level=logging.DEBUG)
    else:
        logging.basicConfig(filename='kinbot.log', level=logging.INFO)

    # write the license message to the log file
    logging.info(license_message.message)
    # time stamp of the KinBot start
    logging.info('Starting KinBot at {}'.format(datetime.datetime.now()))

    # Make the necessary directories
    if not os.path.exists('perm'):
        os.makedirs('perm')
    if not os.path.exists('scratch'):
        os.makedirs('scratch')
    if not os.path.exists(par.par['single_point_qc']):
        os.mkdir(par.par['single_point_qc'])
    if par.par['rotor_scan'] == 1:
        if not os.path.exists('hir'):
            os.mkdir('hir')
        if not os.path.exists('hir_profiles'):
            os.mkdir('hir_profiles')
        if not os.path.exists('perm/hir/'):
            os.makedirs('perm/hir/')
    if par.par['conformer_search'] == 1:
        if not os.path.exists('conf'):
            os.mkdir('conf')
        if not os.path.exists('perm/conf'):
            os.makedirs('perm/conf')
    if not os.path.exists('me'):
        os.mkdir('me')


    if par.par['pes'] and par.par['specific_reaction']:
        logging.error('Specific reaction cannot be searched in PES mode.')
        return

    # initialize the reactant
    well0 = StationaryPoint('well0',
                            par.par['charge'],
                            par.par['mult'],
                            smiles=par.par['smiles'],
                            structure=par.par['structure'])
    well0.short_name = 'w1'

    # wrtie the initial reactant geometry to a file for visualization
    geom_out = open('geometry.xyz', 'w')
    geom_out.write('{}\n\n'.format(well0.natom))
    for i, at in enumerate(well0.atom):
        x, y, z = well0.geom[i]
        geom_out.write('{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z))
    geom_out.write('\n\n')
    geom_out.close()

    # characterize the initial reactant
    well0.characterize(par.par['dimer'])
    well0.name = str(well0.chemid)
    start_name = well0.name

    # initialize the qc instance
    qc = QuantumChemistry(par)

    # start the initial optimization of the reactant
    logging.info('Starting optimization of intial well')
    qc.qc_opt(well0, well0.geom)
    err, well0.geom = qc.get_qc_geom(str(well0.chemid) + '_well',
                                     well0.natom, wait=1)
    err, well0.freq = qc.get_qc_freq(str(well0.chemid) + '_well',
                                     well0.natom, wait=1)
    if err < 0:
        logging.error('Error with initial structure optimization.')
        return
    if any(well0.freq[i] <= 0 for i in range(len(well0.freq))):
        logging.error('Found imaginary frequency for initial structure.')
        return

    # characterize again and look for differences
    well0.characterize(par.par['dimer'])
    well0.name = str(well0.chemid)
    if well0.name != start_name:
        logging.error('The first well optimized to a structure different from the input.')
        return

    # do an MP2 optimization of the reactant,
    # to compare Beta scission barrier heigths to
    logging.info('Starting MP2 optimization of intial well')
    qc.qc_opt(well0, well0.geom, mp2=1)
    err, geom = qc.get_qc_geom(str(well0.chemid) + '_well_mp2', well0.natom, 1)

    # characterize again and look for differences
    well0.characterize(par.par['dimer'])
    well0.name = str(well0.chemid)

    # read the energy and the zpe corrected energy
    err, well0.energy = qc.get_qc_energy(str(well0.chemid) + '_well', 1)
    err, well0.zpe = qc.get_qc_zpe(str(well0.chemid) + '_well', 1)

    well_opt = Optimize(well0, par, qc, wait=1)
    well_opt.do_optimization()
    if well_opt.shigh == -999:
        logging.error('Error with high level optimization of initial structure.')
        return

    # do the reaction search using heuristics
    if par.par['reaction_search'] == 1:
        logging.info('Starting reaction searches of intial well')
        rf = ReactionFinder(well0, par, qc)
        rf.find_reactions()
        rg = ReactionGenerator(well0, par, qc)
        rg.generate()
    # do the homolytic scission products search
    if par.par['homolytic_scissions'] == 1:
        logging.info('Starting the search for homolytic scission products')
        well0.homolytic_scissions = HomolyticScissions(well0, par, qc)
        well0.homolytic_scissions.find_homolytic_scissions()
    # initialize the master equation instance
    mess = MESS(par, well0)
    mess.write_input()
    mesmer = MESMER(par, well0)
    mesmer.write_input()
    if par.par['me'] == 1:
        logging.info('Starting Master Equation calculations')
        if par.par['me_code'] == 'mess':
            mess.run()
        elif par.par['me_code'] == 'mesmer':
            mesmer.run()
        else:
            logging.error('Cannot recognize me code {}'.format(par.par['me_code']))

    # postprocess the calculations
    postprocess.createSummaryFile(well0, qc, par)
    postprocess.createPESViewerInput(well0, qc, par)
    postprocess.creatMLInput(well0, qc, par)

    logging.info('Finished KinBot at {}'.format(datetime.datetime.now()))
    print("Done!")
Пример #4
0
def create_mess_input(par, wells, products, reactions,
                      well_energies, prod_energies, parent):
    """
    When calculating a full pes, the files from the separate wells
    are read and concatenated into one file
    Two things per file need to be updated
    1. the names of all the wells, bimolecular products and ts's
    2. all the zpe corrected energies
    """
    # generate short names for all startionary points
    well_short, pr_short, fr_short, ts_short = create_short_names(wells,
                                                                  products,
                                                                  reactions)
    # list of the strings to write to mess input file
    s = []
    # write the header
    s.append(write_header(par, well_short[wells[0]]))

    # write the wells
    s.append('######################')
    s.append('# WELLS')
    s.append('######################')
    for well in wells:
        name = well_short[well] + ' ! ' + well
        energy = well_energies[well]
        with open(parent[well] + '/' + well + '.mess') as f:
            s.append(f.read().format(name=name, zeroenergy=energy))
        s.append('!****************************************')

    # write the products
    s.append('######################')
    s.append('# BIMOLECULAR PRODUCTS')
    s.append('######################')
    for prod in products:
        name = pr_short[prod] + ' ! ' + prod
        energy = prod_energies[prod]
        fr_names = {}
        for fr in prod.split('_'):
            key = 'fr_name_{}'.format(fr)
            value = fr_short[fr] + ' ! ' + fr
            fr_names[key] = value
        with open(parent[prod] + '/' + prod + '.mess') as f:
            s.append(f.read().format(name=name,
                                     ground_energy=energy,
                                     **fr_names))
        s.append('!****************************************')

    # write the barrier
    s.append('######################')
    s.append('# BARRIERS')
    s.append('######################')
    for rxn in reactions:
        name = [ts_short[rxn[1]]]
        name.append(well_short[rxn[0]])
        if len(rxn[2]) == 1:
            name.append(well_short[rxn[2][0]])
        else:
            name.append(pr_short['_'.join(sorted(rxn[2]))])
        name.append('!')
        name.append(rxn[1])
        energy = rxn[3]
        with open(rxn[0] + '/' + rxn[1] + '.mess') as f:
            s.append(f.read().format(name=' '.join(name), zeroenergy=energy))
        s.append('!****************************************')

    # add last end statement
    s.append('!****************************************')
    s.append('End ! end kinetics\n')

    if not os.path.exists('me'):
        os.mkdir('me')

    # write everything to a file
    with open('me/mess.inp', 'w') as f:
        f.write('\n'.join(s))

    dummy = StationaryPoint('dummy',
                            par.par['charge'],
                            par.par['mult'],
                            smiles=par.par['smiles'],
                            structure=par.par['structure'])

    mess = MESS(par, dummy)
    if par.par['me']:
        mess.run()