예제 #1
0
파일: mess.py 프로젝트: zadorlab/KinBot
    def make_rotors(self, species, norot=None):
        rotors = []
        if self.par['rotor_scan']:
            for i, rot in enumerate(species.dihed):
                if norot is not None:
                    if frequencies.skip_rotor(norot, rot) == 1:
                        continue
                rotorpot, rotortype = self.make_rotorpot(species, i, rot)
                if rotortype == 'hindered':
                    rotors.append(
                        self.hinderedrotortpl.format(
                            group=' '.join([
                                str(pi + 1) for pi in frequencies.partition(
                                    species, rot, species.natom)[0][1:]
                            ]),
                            axis='{} {}'.format(str(rot[1] + 1),
                                                str(rot[2] + 1)),
                            rotorsymm=self.rotorsymm(species, rot),
                            nrotorpot=self.nrotorpot(species, rot),
                            rotorpot=rotorpot))
                elif rotortype == 'free':
                    rotors.append(
                        self.freerotortpl.format(
                            geom=self.make_geom(species),
                            natom=species.natom,
                            group=' '.join([
                                str(pi + 1) for pi in frequencies.partition(
                                    species, rot, species.natom)[0][1:]
                            ]),
                            axis='{} {}'.format(str(rot[1] + 1),
                                                str(rot[2] + 1)),
                        ))

        rotors = '\n'.join(rotors)
        return rotors
예제 #2
0
    def write_well(self, species):
        """
        Create the block for MESS for a well.
        well0: reactant on this PES (zero-energy reference)
        """
        # open the templates
        well_file = pkg_resources.resource_filename('tpl', 'mess_well.tpl')
        with open(well_file) as f:
            tpl = f.read()
        hir_file = pkg_resources.resource_filename('tpl', 'mess_hinderedrotor.tpl')
        with open(hir_file) as f:
            rotor_tpl = f.read()

        rotors = []
        if self.par.par['rotor_scan']:
            for i, rot in enumerate(species.dihed):
                group = ' '.join([str(pi+1) for pi in frequencies.partition(species, rot, species.natom)[0][1:]])
                axis = '{} {}'.format(str(rot[1]+1), str(rot[2]+1))
                rotorsymm = species.sigma_int[rot[1]][rot[2]]
                nrotorpot = species.hir.nrotation // rotorsymm
                ens = species.hir.hir_energies[i]
                rotorpot = [(ei - ens[0])*constants.AUtoKCAL for ei in ens]
                rotorpot = ' '.join(['{:.2f}'.format(ei) for ei in rotorpot[:species.hir.nrotation // rotorsymm]])
                rotors.append(rotor_tpl.format(group=group,
                                               axis=axis,
                                               rotorsymm=rotorsymm,
                                               nrotorpot=nrotorpot,
                                               rotorpot=rotorpot))
        rotors = '\n'.join(rotors)

        freq = ''
        #reduced freqs used for mess input to make more accurate with HIR corrections
        for i, fr in enumerate(species.reduced_freqs):
            if i == 0:
                freq += '{:.4f}'.format(fr)
            elif i > 0 and i % 3 == 0:
                freq += '\n            {:.4f}'.format(fr)
            else:
                freq += '    {:.4f}'.format(fr)

        geom = ''
        for i, at in enumerate(species.atom):
            if i > 0:
                geom += '            '
            x, y, z = species.geom[i]
            geom += '{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z)

        if self.par.par['pes']:
            name = '{name}'
            energy = '{zeroenergy}'
        else:
            name = self.well_names[species.chemid] + ' ! ' + str(species.chemid)
            energy = ((species.energy + species.zpe) - (self.species.energy + self.species.zpe)) * constants.AUtoKCAL


        mess_well = tpl.format(chemid=name,
                               natom=species.natom,
                               geom=geom,
                               symm=float(species.sigma_ext) / float(species.nopt),
                               nfreq=len(species.reduced_freqs),
                               freq=freq,
                               hinderedrotor=rotors,
                               nelec=1,
                               charge=species.charge,
                               mult=species.mult,
                               zeroenergy=energy)

        f = open(str(species.chemid) + '.mess', 'w')
        f.write(mess_well)
        f.close()

        return mess_well
예제 #3
0
    def write_barrier(self, reaction):
        """
        Create the block for a MESS barrier.
        """
        # open the templates
        ts_file = pkg_resources.resource_filename('tpl', 'mess_ts.tpl')
        with open(ts_file) as f:
            tpl = f.read()
        hir_file = pkg_resources.resource_filename('tpl', 'mess_hinderedrotor.tpl')
        with open(hir_file) as f:
            rotor_tpl = f.read()
        tunn_file = pkg_resources.resource_filename('tpl', 'mess_tunneling.tpl')
        with open(tunn_file) as f:
            tun_tpl = f.read()

        rotors = []
        if self.par.par['rotor_scan']:
            for i, rot in enumerate(reaction.ts.dihed):
                group = ' '.join([str(pi+1) for pi in frequencies.partition(reaction.ts, rot, reaction.ts.natom)[0][1:]])
                axis = '{} {}'.format(str(rot[1]+1), str(rot[2]+1))
                rotorsymm = reaction.ts.sigma_int[rot[1]][rot[2]]
                nrotorpot = reaction.ts.hir.nrotation // rotorsymm
                ens = reaction.ts.hir.hir_energies[i]
                rotorpot = [(ei - ens[0])*constants.AUtoKCAL for ei in ens]
                rotorpot = ' '.join(['{:.2f}'.format(ei) for ei in rotorpot[:reaction.ts.hir.nrotation // rotorsymm]])
                rotors.append(rotor_tpl.format(group=group,
                                               axis=axis,
                                               rotorsymm=rotorsymm,
                                               nrotorpot=nrotorpot,
                                               rotorpot=rotorpot))
        rotors = '\n'.join(rotors)

        freq = ''
        #reduced freqs used for better accuracy of mess input files
        for i, fr in enumerate(reaction.ts.reduced_freqs[1:]):
            if i == 0:
                freq += '{:.4f}'.format(fr)
            elif i > 0 and i % 3 == 0:
                freq += '\n            {:.4f}'.format(fr)
            else:
                freq += '    {:.4f}'.format(fr)

        geom = ''
        for i, at in enumerate(reaction.ts.atom):
            if i > 0:
                geom += '            '
            x, y, z = reaction.ts.geom[i]
            geom += '{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z)

        barriers = [
            ((reaction.ts.energy + reaction.ts.zpe) - (self.species.energy + self.species.zpe)) * constants.AUtoKCAL,
            ((reaction.ts.energy + reaction.ts.zpe) - sum([(opt.species.energy + opt.species.zpe) for opt in reaction.prod_opt])) * constants.AUtoKCAL,
        ]
        if any([bi < 0 for bi in barriers]):
            tun = ''
        else:
            tun = tun_tpl.format(cutoff=min(barriers),
                                 imfreq=-reaction.ts.reduced_freqs[0],
                                 welldepth1=barriers[0],
                                 welldepth2=barriers[1])

        if len(reaction.products) == 1:
            prod_name = self.well_names[reaction.products[0].chemid]
        elif len(reaction.products) == 2:
            long_name = '_'.join(sorted([str(pi.chemid) for pi in reaction.products]))
            prod_name = self.bimolec_names[long_name]
        else:
            long_name = '_'.join(sorted([str(pi.chemid) for pi in reaction.products]))
            prod_name = self.termolec_names[long_name]
  
        if self.par.par['pes']:
            name = '{name}'
            chemid_reac = ''
            chemid_prod = ''
            long_rxn_name = ''
            energy = '{zeroenergy}'
        else:
            name = self.ts_names[reaction.instance_name]
            chemid_reac = self.well_names[self.species.chemid]
            chemid_prod = prod_name
            long_rxn_name = reaction.instance_name
            energy = ((reaction.ts.energy + reaction.ts.zpe) - (self.species.energy + self.species.zpe)) * constants.AUtoKCAL

        mess_ts = tpl.format(rxn_name=name,
                             chemid_reac=chemid_reac,
                             chemid_prod=chemid_prod,
                             long_rxn_name=long_rxn_name,
                             natom=reaction.ts.natom,
                             geom=geom,
                             symm=float(reaction.ts.sigma_ext) / float(reaction.ts.nopt),
                             nfreq=len(reaction.ts.reduced_freqs) - 1,
                             freq=freq,
                             hinderedrotor=rotors,
                             tunneling=tun,
                             nelec=1,
                             charge=reaction.ts.charge,
                             mult=reaction.ts.mult,
                             zeroenergy=energy)

        f = open(reaction.instance_name + '.mess', 'w')
        f.write(mess_ts)
        f.close()

        return mess_ts
예제 #4
0
    def write_bimol(self, species_list,  bar):
        """
        Create the block for MESS for a bimolecular product.
        well0: reactant on this PES (zero-energy reference)
        """

        bar=bar #0=barrier, 1=barrierless

        # open the templates
        if bar == 0:
            bimol_file = pkg_resources.resource_filename('tpl', 'mess_bimol.tpl')
        elif bar == 1:
            bimol_file = pkg_resources.resource_filename('tpl', 'mess_barrierless.tpl')
       
        with open(bimol_file) as f:
            tpl = f.read()
        fragment_file = pkg_resources.resource_filename('tpl', 'mess_fragment.tpl')
        with open(fragment_file) as f:
            fragment_tpl = f.read()
        hir_file = pkg_resources.resource_filename('tpl', 'mess_hinderedrotor.tpl')
        with open(hir_file) as f:
            rotor_tpl = f.read()
        atom_file = pkg_resources.resource_filename('tpl', 'mess_atom.tpl')
        with open(atom_file) as f:
            atom_tpl = f.read()

        fragments=''
        for species in species_list:
            if species.natom > 1:
                rotors = []
                if self.par.par['rotor_scan']:
                    for i, rot in enumerate(species.dihed):
                        group = ' '.join([str(pi+1) for pi in frequencies.partition(species, rot, species.natom)[0][1:]])
                        axis = '{} {}'.format(str(rot[1]+1), str(rot[2]+1))
                        rotorsymm = species.sigma_int[rot[1]][rot[2]]
                        nrotorpot = species.hir.nrotation // rotorsymm
                        ens = species.hir.hir_energies[i]
                        rotorpot = [(ei - ens[0])*constants.AUtoKCAL for ei in ens]
                        rotorpot = ' '.join(['{:.2f}'.format(ei) for ei in rotorpot[:species.hir.nrotation // rotorsymm]])
                        rotors.append(rotor_tpl.format(group=group,
                                                       axis=axis,
                                                       rotorsymm=rotorsymm,
                                                       nrotorpot=nrotorpot,
                                                       rotorpot=rotorpot))
                rotors = '\n'.join(rotors)
                freq = ''
                #reduced freqs used always bc HIR creates more accurate mess input
                for i, fr in enumerate(species.reduced_freqs):
                    if i == 0:
                        freq += '{:.4f}'.format(fr)
                    elif i > 0 and i % 3 == 0:
                        freq += '\n            {:.4f}'.format(fr)
                    else:
                        freq += '    {:.4f}'.format(fr)

                geom = ''
                for i, at in enumerate(species.atom):
                    if i > 0:
                        geom += '            '
                    x, y, z = species.geom[i]
                    geom += '{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z)

                energy = ((species.energy + species.zpe) - (self.species.energy + self.species.zpe)) * constants.AUtoKCAL
                if self.par.par['pes']:
                    name = 'fr_name_{}'.format(species.chemid)
                    name = '{' + name + '}'
                else:
                    name = self.fragment_names[species.chemid] + ' ! ' + str(species.chemid)
                fragments += fragment_tpl.format(chemid=name,
                                                 natom=species.natom,
                                                 geom=geom,
                                                 symm=float(species.sigma_ext) / float(species.nopt),
                                                 nfreq=len(species.reduced_freqs),
                                                 freq=freq,
                                                 hinderedrotor=rotors,
                                                 nelec=1,
                                                 charge=species.charge,
                                                 mult=species.mult)
                fragments += '\n'
            else:
                if self.par.par['pes']:
                    name = 'fr_name_{}'.format(species.chemid)
                    name = '{' + name + '}'
                else:
                    name = self.fragment_names[species.chemid] + ' ! ' + str(species.chemid)
                # atom template
                fragments += atom_tpl.format(chemid=name,
                                             element=species.atom[0],
                                             nelec=1,
                                             charge=species.charge,
                                             mult=species.mult)
                fragments += '\n'

        pr_name = '_'.join(sorted([str(species.chemid) for species in species_list]))
        if self.par.par['pes']:
            name = '{name}'
            energy = '{ground_energy}'
        else:
            if bar == 0:
                name = self.bimolec_names[pr_name] + ' ! ' + pr_name
            elif bar == 1:
                name = self.barrierless_names[pr_name]
            energy = (sum([sp.energy for sp in species_list]) + sum([sp.zpe for sp in species_list]) -
                      (self.species.energy + self.species.zpe)) * constants.AUtoKCAL

       
        if bar == 0:
            bimol = tpl.format(chemids=name,
                               fragments=fragments,
                               ground_energy=energy)

        elif bar == 1:
            bimol = tpl.format(barrier='nobar',
                               reactant=name,
                               dummy='',
                               chemids='',
                               fragments=fragments,
                               ground_energy=energy)
        
        f = open(pr_name + '.mess', 'w')
        f.write(bimol)
        f.close()

        return bimol