Exemple #1
0
    def test_process_model_chemistry(self):
        """
        Test processing the model chemistry to derive the sp and freq levels
        """
        mc = 'ccsd(t)-f12a/aug-cc-pvtz//b3lyp/6-311++g(3df,3pd)'
        lot = process_model_chemistry(mc)
        self.assertIsInstance(lot, CompositeLevelOfTheory)
        self.assertEqual(lot.energy,
                         LevelOfTheory('ccsd(t)-f12a', 'aug-cc-pvtz'))
        self.assertEqual(lot.freq, LevelOfTheory('b3lyp', '6-311++g(3df,3pd)'))

        mc = 'b3lyp-d3/def2-tzvp'
        lot = process_model_chemistry(mc)
        self.assertIsInstance(lot, LevelOfTheory)
        self.assertEqual(lot, LevelOfTheory('b3lyp-d3', 'def2-tzvp'))

        mc = 'cbs-qb3'
        lot = process_model_chemistry(mc)
        self.assertIsInstance(lot, LevelOfTheory)
        self.assertEqual(lot, LevelOfTheory('cbs-qb3'))

        mc = LevelOfTheory('test')
        lot = process_model_chemistry(mc)
        self.assertIs(mc, lot)

        with self.assertRaises(InputError):
            process_model_chemistry(
                'CCSD(T)-F12a/aug-cc-pVTZ//CCSD(T)-F12a/aug-cc-pVTZ//B3LYP/6-311++G(3df,3pd)'
            )
Exemple #2
0
    def test_attrs(self):
        """
        Test that instance behaves correctly.
        """
        self.assertEqual(FREQ.method, 'wb97xd')
        self.assertEqual(FREQ.basis, 'def2tzvp')
        self.assertEqual(FREQ.software, 'gaussian')
        self.assertTupleEqual(FREQ.args, ('verytight',))
        with self.assertRaises(FrozenInstanceError):
            FREQ.method = ''

        self.assertEqual(repr(FREQ), FREQ_REPR)
        self.assertEqual(repr(ENERGY), ENERGY_REPR)

        with self.assertRaises(ValueError):
            _ = LevelOfTheory(method=FREQ.method)
        lot = LevelOfTheory(method=FREQ.method, software=FREQ.software)
        self.assertIsNone(lot.basis)
        self.assertIsNone(lot.auxiliary_basis)
        self.assertIsNone(lot.cabs)
        self.assertIsNone(lot.software_version)
        self.assertIsNone(lot.solvent)
        self.assertIsNone(lot.solvation_method)
        self.assertIsNone(lot.args)

        self.assertIsInstance(FREQ, LOT)
Exemple #3
0
    def test_to_model_chem(self):
        """
        Test conversion to model chemistry.
        """
        self.assertEqual(FREQ.to_model_chem(), FREQ_MODELCHEM)
        self.assertEqual(ENERGY.to_model_chem(), ENERGY_MODELCHEM)

        lot = LevelOfTheory(method='CBS-QB3', software='g16')
        self.assertEqual(lot.to_model_chem(), 'cbsqb3')
Exemple #4
0
    def test_comparison(self):
        """
        Test comparisons between instances.
        """
        self.assertIsInstance(hash(FREQ), int)
        self.assertNotEqual(FREQ, ENERGY)
        with self.assertRaises(TypeError):
            _ = ENERGY > FREQ

        # Test args in different order
        lot1 = LevelOfTheory('method', args=('arg1', 'arg2'))
        lot2 = LevelOfTheory('method', args=('arg2', 'arg1'))
        self.assertEqual(lot1, lot2)
Exemple #5
0
    def test_level_of_theory_consistency(self):
        """
        Test that ErrorCancelingReaction objects properly check that all species use the same level of theory
        """
        # Take ethane as the target
        ethane = ErrorCancelingSpecies(self.molecule1, (100.0, 'kJ/mol'),
                                       LevelOfTheory('test_A'))
        methyl = ErrorCancelingSpecies(self.molecule2, (20.0, 'kcal/mol'),
                                       LevelOfTheory('test_B'),
                                       (21000.0, 'cal/mol'))

        # This should throw an exception because the model chemistry is different
        with self.assertRaises(ValueError):
            ErrorCancelingReaction(ethane, {methyl: 2})
Exemple #6
0
 def test_molecule_input_in_error_canceling_species(self):
     """
     Test that an exception is raised if an rmgpy Molecule object is not passed to an ErrorCancelingSpecies
     """
     with self.assertRaises(ValueError):
         ErrorCancelingSpecies(self.species, (100.0, 'J/mol'),
                               LevelOfTheory('test'))
Exemple #7
0
 def setUp(cls):
     """Preparation for all unit tests in this class."""
     cls.directory = os.path.join(
         os.path.dirname(os.path.dirname(rmgpy.__file__)), 'examples',
         'arkane')
     cls.level_of_theory = LevelOfTheory("cbs-qb3")
     cls.frequencyScaleFactor = 0.99
     cls.useHinderedRotors = False
     cls.useBondCorrections = True
Exemple #8
0
 def test_list_available_chemistry(self):
     """
     Test that a set of available levels of theory can be return for the reference database
     """
     level_of_theory_list = self.database.list_available_chemistry()
     self.assertIn(
         LevelOfTheory(method='wb97m-v',
                       basis='def2-tzvpd',
                       software='qchem'), level_of_theory_list)
Exemple #9
0
    def test_write_to_database(self):
        """
        Test that results can be written to the database.
        """
        # Check that error is raised when no energies are available
        self.ae.atom_energies = None
        with self.assertRaises(ValueError) as e:
            self.ae.write_to_database('test')
        self.assertIn('No atom energies', str(e.exception))

        # Check that error is raised if energies already exist
        self.ae.atom_energies = {'H': 1.0, 'C': 2.0}
        tmp_datafile_fd, tmp_datafile_path = tempfile.mkstemp(suffix='.py')

        lot = LevelOfTheory(method='wb97m-v',
                            basis='def2-tzvpd',
                            software='Q-Chem')
        with self.assertRaises(ValueError) as e:
            self.ae.write_to_database(lot, alternate_path=tmp_datafile_path)
        self.assertIn('overwrite', str(e.exception))

        # Dynamically set data file as module
        spec = importlib.util.spec_from_file_location(
            os.path.basename(tmp_datafile_path), tmp_datafile_path)
        module = importlib.util.module_from_spec(spec)

        # Check that existing energies can be overwritten
        self.ae.write_to_database(lot,
                                  overwrite=True,
                                  alternate_path=tmp_datafile_path)
        spec.loader.exec_module(module)  # Load data as module
        self.assertEqual(self.ae.atom_energies,
                         module.atom_energies[repr(lot)])

        # Check that new energies can be written
        lot = LevelOfTheory('test')
        self.ae.write_to_database(lot, alternate_path=tmp_datafile_path)
        spec.loader.exec_module(module)  # Reload data module
        self.assertEqual(self.ae.atom_energies,
                         module.atom_energies[repr(lot)])

        os.close(tmp_datafile_fd)
        os.remove(tmp_datafile_path)
Exemple #10
0
 def test_to_arkane(self):
     """Test converting Level to LevelOfTheory"""
     level_1 = Level(repr='wB97xd/def2-tzvp')
     self.assertEqual(
         level_1.to_arkane_level_of_theory(),
         LevelOfTheory(method='wb97xd',
                       basis='def2tzvp',
                       software='gaussian'))
     self.assertEqual(
         level_1.to_arkane_level_of_theory(variant='freq'),
         LevelOfTheory(method='wb97xd',
                       basis='def2tzvp',
                       software='gaussian'))
     level_2 = Level(repr='CBS-QB3')
     self.assertEqual(level_2.to_arkane_level_of_theory(),
                      LevelOfTheory(method='cbs-qb3', software='gaussian'))
     self.assertEqual(level_2.to_arkane_level_of_theory(variant='AEC'),
                      LevelOfTheory(method='cbs-qb3', software='gaussian'))
     self.assertEqual(level_2.to_arkane_level_of_theory(variant='freq'),
                      LevelOfTheory(method='cbs-qb3', software='gaussian'))
     self.assertEqual(level_2.to_arkane_level_of_theory(variant='BAC'),
                      LevelOfTheory(method='cbs-qb3', software='gaussian'))
     self.assertIsNone(
         level_2.to_arkane_level_of_theory(
             variant='BAC', bac_type='m'))  # might change in the future
     level_3 = Level(
         repr={
             'method': 'DLPNO-CCSD(T)',
             'basis': 'def2-TZVp',
             'auxiliary_basis': 'def2-tzvp/c',
             'solvation_method': 'SMD',
             'solvent': 'water',
             'solvation_scheme_level': 'APFD/def2-TZVp'
         })
     self.assertEqual(
         level_3.to_arkane_level_of_theory(),
         LevelOfTheory(method='dlpno-ccsd(t)',
                       basis='def2tzvp',
                       software='orca'))
     self.assertEqual(
         level_3.to_arkane_level_of_theory(comprehensive=True),
         LevelOfTheory(method='dlpnoccsd(t)',
                       basis='def2tzvp',
                       auxiliary_basis='def2tzvp/c',
                       solvent='water',
                       solvation_method='smd',
                       software='orca'))
Exemple #11
0
    def test_create_and_load_yaml(self):
        """
        Test properly loading the ArkaneSpecies object and respective sub-objects
        """
        # Create YAML file by running Arkane
        job_list = self.arkane.load_input_file(self.dump_input_path)
        for job in job_list:
            job.execute(output_directory=self.dump_path)

        # Load in newly created YAML file
        arkane_spc_old = job_list[0].arkane_species
        arkane_spc = ArkaneSpecies.__new__(ArkaneSpecies)
        arkane_spc.load_yaml(
            path=os.path.join(self.dump_path, 'species', arkane_spc_old.label +
                              '.yml'))

        self.assertIsInstance(arkane_spc, ArkaneSpecies)  # checks make_object
        self.assertIsInstance(arkane_spc.molecular_weight, ScalarQuantity)
        self.assertIsInstance(arkane_spc.thermo, NASA)
        self.assertNotEqual(arkane_spc.author, '')
        self.assertEqual(arkane_spc.inchi, 'InChI=1S/C2H6/c1-2/h1-2H3')
        self.assertEqual(arkane_spc.inchi_key, 'OTMSDBZUPAUEDD-UHFFFAOYSA-N')
        self.assertEqual(arkane_spc.smiles, 'CC')
        self.assertTrue('8 H u0 p0 c0 {2,S}' in arkane_spc.adjacency_list)
        self.assertEqual(arkane_spc.label, 'C2H6')
        self.assertEqual(arkane_spc.frequency_scale_factor,
                         0.99 * 1.014)  # checks float conversion
        self.assertFalse(arkane_spc.use_bond_corrections)
        self.assertAlmostEqual(
            arkane_spc.conformer.modes[2].frequencies.value_si[0], 830.38202,
            4)  # HarmonicOsc.
        self.assertIsInstance(arkane_spc.energy_transfer_model,
                              SingleExponentialDown)
        self.assertFalse(arkane_spc.is_ts)
        self.assertEqual(arkane_spc.level_of_theory, LevelOfTheory('cbs-qb3'))
        self.assertIsInstance(arkane_spc.thermo_data, ThermoData)
        self.assertTrue(arkane_spc.use_hindered_rotors)
        self.assertIsInstance(arkane_spc.chemkin_thermo_string, str)
        expected_xyz = """8
C2H6
C       0.00075400    0.00119300    0.00055200
H       0.00074000    0.00117100    1.09413800
H       1.04376600    0.00117100   -0.32820200
H      -0.44760300    0.94289500   -0.32825300
C      -0.76014200   -1.20389600   -0.55748300
H      -0.76012800   -1.20387400   -1.65106900
H      -0.31178500   -2.14559800   -0.22867800
H      -1.80315400   -1.20387400   -0.22872900"""
        self.assertEqual(arkane_spc.xyz, expected_xyz)
Exemple #12
0
    def setUpClass(cls):
        """
        A method called before each unit test in this class.
        """
        # Give all species a low level Hf298 of 100 J/mol--this is not important for this test
        hf = (100.0, 'J/mol')

        lot = LevelOfTheory('test')
        cls.propene = ErrorCancelingSpecies(Molecule(smiles='CC=C'), hf, lot)
        cls.butane = ErrorCancelingSpecies(Molecule(smiles='CCCC'), hf, lot)
        cls.benzene = ErrorCancelingSpecies(Molecule(smiles='c1ccccc1'), hf,
                                            lot)
        cls.caffeine = ErrorCancelingSpecies(
            Molecule(smiles='CN1C=NC2=C1C(=O)N(C(=O)N2C)C'), hf, lot)
        cls.ethyne = ErrorCancelingSpecies(Molecule(smiles='C#C'), hf, lot)
Exemple #13
0
    def test_error_canceling_reactions(self):
        """
        Test that ErrorCancelingReaction object can be created and that hf298 can be calculated for the target
        """
        # Take ethane as the target
        lot = LevelOfTheory('test')
        ethane = ErrorCancelingSpecies(self.molecule1, (100.0, 'kJ/mol'), lot)
        methyl = ErrorCancelingSpecies(self.molecule2, (20.0, 'kcal/mol'), lot,
                                       (21000.0, 'cal/mol'))

        # This reaction is not an isodesmic reaction, but that does not matter for the unit test
        rxn = ErrorCancelingReaction(ethane, {methyl: 2})
        self.assertAlmostEqual(
            rxn.calculate_target_thermo().value_si,
            2 * 21000.0 * 4.184 - (2 * 20.0 * 4184 - 100.0 * 1000))
Exemple #14
0
    def test_error_canceling_species(self):
        """
        Test that ErrorCancelingSpecies can be created properly
        """
        lot = LevelOfTheory('test')
        error_canceling_species = ErrorCancelingSpecies(
            self.molecule1, (123.4, 'kcal/mol'), lot, (100.0, 'kJ/mol'))
        self.assertIsInstance(error_canceling_species, ErrorCancelingSpecies)
        self.assertAlmostEqual(
            error_canceling_species.low_level_hf298.value_si, 123.4 * 4184)

        # For target species the high level data is not given
        target_species = ErrorCancelingSpecies(self.molecule2, (10.1, 'J/mol'),
                                               lot)
        self.assertIs(target_species.high_level_hf298, None)
Exemple #15
0
    def test_specifying_absolute_file_paths(self):
        """Test specifying absolute file paths of statmech files"""
        h2o2_input = """#!/usr/bin/env python
# -*- coding: utf-8 -*-

bonds = {{'H-O': 2, 'O-O': 1}}

externalSymmetry = 2

spinMultiplicity = 1

opticalIsomers = 1

energy = {{'b3lyp/6-311+g(3df,2p)': Log('{energy}')}}

geometry = Log('{freq}')

frequencies = Log('{freq}')

rotors = [HinderedRotor(scanLog=Log('{scan}'), pivots=[1, 2], top=[1, 3], symmetry=1, fit='fourier')]

"""
        abs_arkane_path = os.path.abspath(os.path.dirname(
            __file__))  # this is the absolute path to `.../RMG-Py/arkane`
        energy_path = os.path.join('arkane', 'data', 'H2O2', 'sp_a19032.out')
        freq_path = os.path.join('arkane', 'data', 'H2O2', 'freq_a19031.out')
        scan_path = os.path.join('arkane', 'data', 'H2O2', 'scan_a19034.out')
        h2o2_input = h2o2_input.format(energy=energy_path,
                                       freq=freq_path,
                                       scan=scan_path)
        h2o2_path = os.path.join(abs_arkane_path, 'data', 'H2O2', 'H2O2.py')
        if not os.path.exists(os.path.dirname(h2o2_path)):
            os.makedirs(os.path.dirname(h2o2_path))
        with open(h2o2_path, 'w') as f:
            f.write(h2o2_input)
        h2o2 = Species(label='H2O2', smiles='OO')
        self.assertIsNone(h2o2.conformer)
        statmech_job = StatMechJob(species=h2o2, path=h2o2_path)
        statmech_job.level_of_theory = LevelOfTheory('b3lyp',
                                                     '6-311+g(3df,2p)')
        statmech_job.load(pdep=False, plot=False)
        self.assertAlmostEqual(h2o2.conformer.E0.value_si, -146031.49933673252)
        os.remove(h2o2_path)
Exemple #16
0
    def setUpClass(cls):
        try:
            import pyomo as pyo
        except ImportError:
            pyo = None
        cls.pyo = pyo

        lot = LevelOfTheory('test')
        cls.propene = ErrorCancelingSpecies(Molecule(smiles='CC=C'),
                                            (100, 'kJ/mol'), lot,
                                            (105, 'kJ/mol'))
        cls.propane = ErrorCancelingSpecies(Molecule(smiles='CCC'),
                                            (75, 'kJ/mol'), lot,
                                            (80, 'kJ/mol'))
        cls.butane = ErrorCancelingSpecies(Molecule(smiles='CCCC'),
                                           (150, 'kJ/mol'), lot,
                                           (145, 'kJ/mol'))
        cls.butene = ErrorCancelingSpecies(Molecule(smiles='C=CCC'),
                                           (175, 'kJ/mol'), lot,
                                           (180, 'kJ/mol'))
        cls.pentane = ErrorCancelingSpecies(Molecule(smiles='CCCCC'),
                                            (200, 'kJ/mol'), lot,
                                            (190, 'kJ/mol'))
        cls.pentene = ErrorCancelingSpecies(Molecule(smiles='C=CCCC'),
                                            (225, 'kJ/mol'), lot,
                                            (220, 'kJ/mol'))
        cls.hexane = ErrorCancelingSpecies(Molecule(smiles='CCCCCC'),
                                           (250, 'kJ/mol'), lot,
                                           (260, 'kJ/mol'))
        cls.hexene = ErrorCancelingSpecies(Molecule(smiles='C=CCCCC'),
                                           (275, 'kJ/mol'), lot,
                                           (275, 'kJ/mol'))
        cls.benzene = ErrorCancelingSpecies(Molecule(smiles='c1ccccc1'),
                                            (-50, 'kJ/mol'), lot,
                                            (-80, 'kJ/mol'))
        cls.caffeine = ErrorCancelingSpecies(
            Molecule(smiles='CN1C=NC2=C1C(=O)N(C(=O)N2C)C'), (300, 'kJ/mol'),
            lot)
        cls.ethyne = ErrorCancelingSpecies(Molecule(smiles='C#C'),
                                           (200, 'kJ/mol'), lot)
Exemple #17
0
    def test_extract_level_of_theory(self):
        """
        Test that a given level of theory can be extracted from the reference set database
        """
        # Create a quick example database
        ref_data_1 = ReferenceDataEntry(ThermoData(H298=(100, 'kJ/mol', '+|-', 2)))
        ref_data_2 = ReferenceDataEntry(ThermoData(H298=(25, 'kcal/mol', '+|-', 1)))

        calc_data_1 = CalculatedDataEntry(ThermoData(H298=(110, 'kJ/mol')))
        calc_data_2 = CalculatedDataEntry(ThermoData(H298=(120, 'kJ/mol')))

        ethane = ReferenceSpecies(smiles='CC',
                                  reference_data={'precise': ref_data_1, 'less_precise': ref_data_2},
                                  calculated_data={LevelOfTheory('good_chem'): calc_data_1,
                                                   LevelOfTheory('bad_chem'): calc_data_2},
                                  preferred_reference='less_precise')

        propane = ReferenceSpecies(smiles='CCC',
                                   reference_data={'precise': ref_data_1, 'less_precise': ref_data_2},
                                   calculated_data={LevelOfTheory('good_chem'): calc_data_1,
                                                    LevelOfTheory('bad_chem'): calc_data_2})

        butane = ReferenceSpecies(smiles='CCCC',
                                  reference_data={'precise': ref_data_1, 'less_precise': ref_data_2},
                                  calculated_data={LevelOfTheory('bad_chem'): calc_data_2})

        database = ReferenceDatabase()
        database.reference_sets = {'testing_1': [ethane, butane], 'testing_2': [propane]}

        model_chem_list = database.extract_level_of_theory(LevelOfTheory('good_chem'))
        self.assertEqual(len(model_chem_list), 2)
        self.assertIsInstance(model_chem_list[0], ErrorCancelingSpecies)

        for spcs in model_chem_list:
            smiles = spcs.molecule.to_smiles()
            self.assertNotIn(smiles, ['CCCC'])
            self.assertIn(smiles, ['CC', 'CCC'])

            if smiles == 'CC':  # Test that `less_precise` is the source since it was set manually as preferred
                self.assertAlmostEqual(spcs.high_level_hf298.value_si, 25.0*4184.0)

            if smiles == 'CCC':  # Test that `precise` is the source since it has the lowest uncertainty
                self.assertAlmostEqual(spcs.high_level_hf298.value_si, 100.0*1000.0)
Exemple #18
0
    def setUpClass(cls):
        cls.lot_get = LevelOfTheory(method='CCSD(T)-F12',
                                    basis='cc-pVTZ-F12',
                                    software='Molpro')
        cls.lot_fit = LevelOfTheory(method='wB97M-V',
                                    basis='def2-TZVPD',
                                    software='Q-Chem')
        cls.lot_nonexisting = LevelOfTheory('notamethod')

        cls.bac = BAC(cls.lot_get)

        cls.tmp_melius_params = {
            'atom_corr': {
                'H': 1.0,
                'C': 2.0,
                'N': 3.0,
                'O': 4.0,
                'S': 5.0,
                'F': 6.0,
                'Cl': 7.0,
                'Br': 8.0
            },
            'bond_corr_length': {
                'H': 1.0,
                'C': 2.0,
                'N': 3.0,
                'O': 4.0,
                'S': 5.0,
                'F': 6.0,
                'Cl': 7.0,
                'Br': 8.0
            },
            'bond_corr_neighbor': {
                'H': 1.0,
                'C': 2.0,
                'N': 3.0,
                'O': 4.0,
                'S': 5.0,
                'F': 6.0,
                'Cl': 7.0,
                'Br': 8.0
            },
            'mol_corr': 1.0
        }
        cls.tmp_petersson_params = {
            'C-H': 1.0,
            'C-C': 2.0,
            'C=C': 3.0,
            'C-O': 4.0
        }

        # Set molecule, bonds, nums, and coords for testing Petersson and Melius BACs
        cls.multiplicity = 1
        smi = 'C=C(OSC=S)C#CC1C(=O)N=CNC1SSC(O)C#N'

        mol = Molecule(smiles=smi, multiplicity=cls.multiplicity)
        cls.bonds = Counter(
            f'{b.atom1.element.symbol}{BOND_SYMBOLS[b.order]}{b.atom2.element.symbol}'
            for b in mol.get_all_edges())

        pybel_mol = pybel.readstring('smi', smi)
        pybel_mol.addh()
        pybel_mol.make3D()
        mol_3d = _pybel_to_rmg(pybel_mol)
        cls.nums = [atom.number for atom in mol_3d.atoms]
        cls.coords = np.array([atom.coords for atom in mol_3d.atoms])
    def to_arkane_level_of_theory(
        self,
        variant: Optional[str] = None,
        bac_type: str = 'p',
        comprehensive: bool = False,
        raise_error: bool = False,
        warn: bool = True,
    ) -> Optional[LevelOfTheory]:
        """
        Convert ``Level`` to an Arkane ``LevelOfTheory`` instance.

        Args:
            variant (str, optional): Return a variant of the Arkane ``LevelOfTheory`` that matches an Arkane query.
                                     Allowed values are ``'freq'``, ``'AEC'``, ``'BEC'``. Returns ``None`` if no
                                     functioning variant was found.
            bac_type (str, optional): The BAC type ('p' or 'm') to use when searching for a ``LevelOfTheory`` variant
                                      for BAC.
            comprehensive (bool, optional): Whether to consider all relevant arguments if not looking for a variant.
            raise_error (bool, optional): Whether to raise an error if an AEC variant could not be found.
            warn (bool, optional): Whether to output a warning if an AEC variant could not be found.

        Returns:
            LevelOfTheory: The respective Arkane ``LevelOfTheory`` object
        """
        if variant is None:
            if not comprehensive:
                # only add basis and software if needed
                kwargs = {'method': self.method}
                if self.basis is not None:
                    kwargs['basis'] = self.basis
                kwargs['software'] = self.software
                return LevelOfTheory(**kwargs)
            else:
                # consider all relevant arguments
                kwargs = self.__dict__.copy()
                del kwargs['solvation_scheme_level']
                del kwargs['method_type']
                del kwargs['repr']
                del kwargs['compatible_ess']
                del kwargs['dispersion']
                del kwargs['args']
                if self.args is not None and self.args and all(
                    [val for val in self.args.values()]):
                    # only pass keyword arguments to Arkane (not blocks)
                    if any([key == 'keyword' for key in self.args.keys()]):
                        kwargs['args'] = list()
                        for key1, val1 in self.args.items():
                            if key1 == 'keyword':
                                for val2 in val1.values():
                                    kwargs['args'].append(val2)
                                break
                    else:
                        kwargs['args'] = None
                if self.dispersion is not None:
                    if 'args' not in kwargs:
                        kwargs['args'] = [self.dispersion]
                    else:
                        kwargs['args'].append(self.dispersion)
                if kwargs['method'] is not None:
                    kwargs['method'].replace('f12a',
                                             'f12').replace('f12b', 'f12')
                if kwargs['basis'] is not None:
                    kwargs['basis'].replace('f12a',
                                            'f12').replace('f12b', 'f12')
                return LevelOfTheory(**kwargs)
        else:
            # search for a functioning variant
            if variant not in ['freq', 'AEC', 'BAC']:
                raise ValueError(
                    f'variant must be either "freq", "AEC", or "BAC", got "{variant}".'
                )
            kwargs = {'method': self.method}
            if self.basis is not None:
                kwargs['basis'] = self.basis
            if standardize_name(self.method) in METHODS_THAT_REQUIRE_SOFTWARE:
                # add software if mandatory (otherwise, Arkane won't accept this object initialization)
                kwargs['software'] = self.software
            var_2 = LevelOfTheory(**kwargs)
            kwargs['software'] = self.software  # add or overwrite software
            # start w/ the software argument (var_1) in case there are several entries that only vary by software
            var_1 = LevelOfTheory(**kwargs)

            if variant == 'freq':
                # if not found, the factor is set to exactly 1
                if assign_frequency_scale_factor(level_of_theory=var_1) != 1:
                    return var_1
                if assign_frequency_scale_factor(level_of_theory=var_2) != 1:
                    return var_2
                return None

            if variant == 'AEC':
                try:
                    arkane_data.atom_energies[var_1]
                    return var_1
                except KeyError:
                    try:
                        arkane_data.atom_energies[var_2]
                        return var_2
                    except KeyError:
                        if raise_error:
                            raise ValueError(
                                f'Missing Arkane atom energy corrections for {var_1}\n'
                                f'(If you did not mean to compute thermo, set the compute_thermo '
                                f'argument to False to avoid this error.)')
                        else:
                            if warn:
                                logger.warning(
                                    f'Missing Arkane atom energy corrections for {var_1}.'
                                )
                            return None

            if variant == 'BAC':
                if bac_type not in ['p', 'm']:
                    raise ValueError(
                        f'bac_type must be either "p" or "m", got "{bac_type}".'
                    )
                bac = BAC(level_of_theory=var_1, bac_type=bac_type)
                if bac.bacs is None:
                    bac = BAC(level_of_theory=var_2, bac_type=bac_type)
                    if bac.bacs is None:
                        logger.warning(f'Missing Arkane BAC for {var_2}.')
                        return None
                    else:
                        return var_2
                else:
                    return var_1
Exemple #20
0
###############################################################################

"""
This script contains unit tests for the :mod:`arkane.modelchem` module.
"""

import unittest
from dataclasses import FrozenInstanceError

from arkane.modelchem import (LOT, LevelOfTheory, CompositeLevelOfTheory,
                              model_chem_to_lot, str_to_lot, get_software_id)

# Instances for use in tests
FREQ = LevelOfTheory(
    method='wB97X-D',
    basis='def2-TZVP',
    software='Gaussian 16',
    args='very-tight'
)
ENERGY = LevelOfTheory(
    method='DLPNO-CCSD(T)-F12',
    basis='def2-TZVP',
    software='Orca'
)
COMPOSITE = CompositeLevelOfTheory(
    freq=FREQ,
    energy=ENERGY
)

# Representations corresponding to instances
FREQ_REPR = "LevelOfTheory(method='wb97xd',basis='def2tzvp',software='gaussian',args=('verytight',))"
ENERGY_REPR = "LevelOfTheory(method='dlpnoccsd(t)f12',basis='def2tzvp',software='orca')"
Exemple #21
0
import pybel

from rmgpy.molecule import Molecule as RMGMolecule

import arkane.encorr.data as data
from arkane.encorr.data import (Molecule, Stats, BACDatapoint, DatasetProperty,
                                BACDataset, extract_dataset, geo_to_mol,
                                _pybel_to_rmg)
from arkane.encorr.reference import ReferenceDatabase
from arkane.exceptions import BondAdditivityCorrectionError
from arkane.modelchem import LOT, LevelOfTheory

DATABASE = ReferenceDatabase()
DATABASE.load()
LEVEL_OF_THEORY = LevelOfTheory(method='wb97m-v',
                                basis='def2-tzvpd',
                                software='qchem')


class TestDataLoading(unittest.TestCase):
    """
    A class for testing that the quantum correction data is loaded
    correctly from the RMG database.
    """
    def test_contains_data(self):
        """
        Test that the necessary dictionaries are available.
        """
        self.assertTrue(hasattr(data, 'atom_hf'))
        self.assertTrue(hasattr(data, 'atom_thermal'))
        self.assertTrue(hasattr(data, 'SOC'))