def setUpClass(cls): """ A method that is run before all unit tests in this class. """ cls.maxDiff = None cls.ess_settings = {'gaussian': ['server1'], 'molpro': ['server2', 'server1'], 'qchem': ['server1']} cls.project_directory = os.path.join(arc_path, 'Projects', 'arc_project_for_testing_delete_after_usage3') cls.spc1 = ARCSpecies(label=str('methylamine'), smiles=str('CN')) cls.spc2 = ARCSpecies(label=str('C2H6'), smiles=str('CC')) cls.job1 = Job(project='project_test', ess_settings=cls.ess_settings, species_name='methylamine', xyz='C 0.0 0.0 0.0', job_type='conformer', conformer=0, level_of_theory='b97-d3/6-311+g(d,p)', multiplicity=1, project_directory=cls.project_directory, job_num=101) cls.job2 = Job(project='project_test', ess_settings=cls.ess_settings, species_name='methylamine', xyz='C 0.0 0.0 0.0', job_type='conformer', conformer=1, level_of_theory='b97-d3/6-311+g(d,p)', multiplicity=1, project_directory=cls.project_directory, job_num=102) cls.job3 = Job(project='project_test', ess_settings=cls.ess_settings, species_name='C2H6', xyz='C 0.0 0.0 0.0', job_type='freq', level_of_theory='wb97x-d3/6-311+g(d,p)', multiplicity=1, project_directory=cls.project_directory, software='qchem', job_num=103) cls.rmgdb = rmgdb.make_rmg_database_object() cls.job_types1 = {'conformers': True, 'opt': True, 'fine_grid': False, 'freq': True, 'sp': True, '1d_rotors': False, 'orbitals': False, 'lennard_jones': False, } cls.sched1 = Scheduler(project='project_test', ess_settings=cls.ess_settings, species_list=[cls.spc1, cls.spc2], composite_method='', conformer_level=default_levels_of_theory['conformer'], opt_level=default_levels_of_theory['opt'], freq_level=default_levels_of_theory['freq'], sp_level=default_levels_of_theory['sp'], scan_level=default_levels_of_theory['scan'], ts_guess_level=default_levels_of_theory['ts_guesses'], rmgdatabase=cls.rmgdb, project_directory=cls.project_directory, testing=True, job_types=cls.job_types1, orbitals_level=default_levels_of_theory['orbitals'], adaptive_levels=None)
def test_determine_adaptive_level(self): """Test the determine_adaptive_level() method""" adaptive_levels = {(1, 5): {'optfreq': 'wb97xd/6-311+g(2d,2p)', 'sp': 'ccsd(t)-f12/aug-cc-pvtz-f12'}, (6, 15): {'optfreq': 'b3lyp/cbsb7', 'sp': 'dlpno-ccsd(t)/def2-tzvp/c'}, (16, 30): {'optfreq': 'b3lyp/6-31g(d,p)', 'sp': 'wb97xd/6-311+g(2d,2p)'}, (31, 'inf'): {'optfreq': 'b3lyp/6-31g(d,p)', 'sp': 'b3lyp/6-311+g(d,p)'}} sched2 = Scheduler(project='project_test', ess_settings=self.ess_settings, species_list=[self.spc1, self.spc2], composite_method='', conformer_level=default_levels_of_theory['conformer'], opt_level=default_levels_of_theory['opt'], freq_level=default_levels_of_theory['freq'], sp_level=default_levels_of_theory['sp'], scan_level=default_levels_of_theory['scan'], ts_guess_level=default_levels_of_theory['ts_guesses'], rmgdatabase=self.rmgdb, project_directory=self.project_directory, testing=True, job_types=self.job_types1, orbitals_level=default_levels_of_theory['orbitals'], adaptive_levels=adaptive_levels) level1 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='opt', heavy_atoms=5) level2 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='freq', heavy_atoms=5) level3 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='opt', heavy_atoms=20) level4 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='composite', heavy_atoms=50) level5 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='orbitals', heavy_atoms=5) level6 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='sp', heavy_atoms=7) level7 = sched2.determine_adaptive_level(original_level_of_theory='some_original_level', job_type='sp', heavy_atoms=25) self.assertEqual(level1, 'wb97xd/6-311+g(2d,2p)') self.assertEqual(level2, 'wb97xd/6-311+g(2d,2p)') self.assertEqual(level3, 'b3lyp/6-31g(d,p)') self.assertEqual(level4, 'b3lyp/6-31g(d,p)') self.assertEqual(level5, 'some_original_level') self.assertEqual(level6, 'dlpno-ccsd(t)/def2-tzvp/c') self.assertEqual(level7, 'wb97xd/6-311+g(2d,2p)')
def determine_scaling_factors( levels: List[Union[Level, dict, str]], ess_settings: Optional[dict] = None, init_log: Optional[bool] = True, ) -> list: """ Determine the zero-point energy, harmonic frequencies, and fundamental frequencies scaling factors for a given frequencies level of theory. Args: levels (list): A list of frequencies levels of theory for which scaling factors are determined. Entries are either Level instances, dictionaries, or simple string representations. If a single entry is given, it will be converted to a list. ess_settings (dict, optional): A dictionary of available ESS (keys) and a corresponding server list (values). init_log (bool, optional): Whether to initialize the logger. ``True`` to initialize. Should be ``True`` when called as a standalone, but ``False`` when called within ARC. Returns: list: The determined frequency scaling factors. """ if init_log: initialize_log(log_file='scaling_factor.log', project='Scaling Factors') if not isinstance(levels, (list, tuple)): levels = [levels] levels = [ Level(repr=level) if not isinstance(level, Level) else level for level in levels ] t0 = time.time() logger.info('\n\n\n') logger.info(HEADER) logger.info('\n\nstarting ARC...\n') # only run opt (fine) and freq job_types = initialize_job_types( dict()) # get the defaults, so no job type is missing job_types = {job_type: False for job_type in job_types.keys()} job_types['opt'], job_types['fine'], job_types['freq'] = True, True, True lambda_zpes, zpe_dicts, times = list(), list(), list() for level in levels: t1 = time.time() logger.info( f'\nComputing scaling factors at the {level} level of theory...\n\n' ) renamed_level = rename_level(str(level)) project = 'scaling_' + renamed_level project_directory = os.path.join(arc_path, 'Projects', 'scaling_factors', project) if os.path.isdir(project_directory): shutil.rmtree(project_directory) species_list = get_species_list() if level.method_type == 'composite': freq_level = None composite_method = level job_types['freq'] = False else: freq_level = level composite_method = None ess_settings = check_ess_settings(ess_settings or global_ess_settings) Scheduler(project=project, project_directory=project_directory, species_list=species_list, composite_method=composite_method, opt_level=freq_level, freq_level=freq_level, ess_settings=ess_settings, job_types=job_types, allow_nonisomorphic_2d=True) zpe_dict = dict() for spc in species_list: zpe_dict[spc.label] = parse_zpe( os.path.join(project_directory, 'output', 'Species', spc.label, 'geometry', 'freq.out')) * 1000 # convert to J/mol zpe_dicts.append(zpe_dict) lambda_zpes.append( calculate_truhlar_scaling_factors(zpe_dict=zpe_dict, level=str(level))) times.append(time_lapse(t1)) summarize_results(lambda_zpes=lambda_zpes, levels=[str(level) for level in levels], zpe_dicts=zpe_dicts, times=times, overall_time=time_lapse(t0)) logger.info('\n\n\n') logger.info(HEADER) harmonic_freq_scaling_factors = [ lambda_zpe * 1.014 for lambda_zpe in lambda_zpes ] return harmonic_freq_scaling_factors
def setUpClass(cls): """ A method that is run before all unit tests in this class. """ cls.maxDiff = None cls.ess_settings = { 'gaussian': ['server1'], 'molpro': ['server2', 'server1'], 'qchem': ['server1'] } cls.project_directory = os.path.join( arc_path, 'Projects', 'arc_project_for_testing_delete_after_usage3') cls.spc1 = ARCSpecies(label='methylamine', smiles='CN') cls.spc2 = ARCSpecies(label='C2H6', smiles='CC') xyz1 = """C 1.11424367 -0.01231165 -0.11493630 C -0.07257945 -0.17830906 -0.16010022 O -1.38500471 -0.36381519 -0.20928090 H 2.16904830 0.12689206 -0.07152274 H -1.82570782 0.42754384 -0.56130718""" cls.spc3 = ARCSpecies(label='CtripCO', smiles='C#CO', xyz=xyz1) xyz2 = { 'symbols': ('C', ), 'isotopes': (12, ), 'coords': ((0.0, 0.0, 0.0), ) } cls.job1 = Job(project='project_test', ess_settings=cls.ess_settings, species_name='methylamine', xyz=xyz2, job_type='conformer', conformer=0, level={ 'method': 'b97-d3', 'basis': '6-311+g(d,p)' }, multiplicity=1, project_directory=cls.project_directory, job_num=101) cls.job2 = Job(project='project_test', ess_settings=cls.ess_settings, species_name='methylamine', xyz=xyz2, job_type='conformer', conformer=1, level={ 'method': 'b97-d3', 'basis': '6-311+g(d,p)' }, multiplicity=1, project_directory=cls.project_directory, job_num=102) cls.job3 = Job(project='project_test', ess_settings=cls.ess_settings, species_name='C2H6', xyz=xyz2, job_type='freq', level={ 'method': 'wb97x-d3', 'basis': '6-311+g(d,p)' }, multiplicity=1, project_directory=cls.project_directory, software='qchem', job_num=103) cls.rmg_database = rmgdb.make_rmg_database_object() cls.job_types1 = { 'conformers': True, 'opt': True, 'fine_grid': False, 'freq': True, 'sp': True, 'rotors': False, 'orbitals': False, 'lennard_jones': False, } cls.sched1 = Scheduler( project='project_test', ess_settings=cls.ess_settings, species_list=[cls.spc1, cls.spc2, cls.spc3], composite_method=None, conformer_level=Level(repr=default_levels_of_theory['conformer']), opt_level=Level(repr=default_levels_of_theory['opt']), freq_level=Level(repr=default_levels_of_theory['freq']), sp_level=Level(repr=default_levels_of_theory['sp']), scan_level=Level(repr=default_levels_of_theory['scan']), ts_guess_level=Level(repr=default_levels_of_theory['ts_guesses']), rmg_database=cls.rmg_database, project_directory=cls.project_directory, testing=True, job_types=cls.job_types1, orbitals_level=default_levels_of_theory['orbitals'], adaptive_levels=None, )
def test_determine_adaptive_level(self): """Test the determine_adaptive_level() method""" # adaptive_levels get converted to ``Level`` objects in main, but here we skip main and test Scheduler directly adaptive_levels = { (1, 5): { ('opt', 'freq'): Level(repr='wb97xd/6-311+g(2d,2p)'), ('sp', ): Level(repr='ccsd(t)-f12/aug-cc-pvtz-f12') }, (6, 15): { ('opt', 'freq'): Level(repr='b3lyp/cbsb7'), ('sp', ): Level(repr='dlpno-ccsd(t)/def2-tzvp') }, (16, 30): { ('opt', 'freq'): Level(repr='b3lyp/6-31g(d,p)'), ('sp', ): Level(repr='wb97xd/6-311+g(2d,2p)') }, (31, 'inf'): { ('opt', 'freq'): Level(repr='b3lyp/6-31g(d,p)'), ('sp', ): Level(repr='b3lyp/6-311+g(d,p)') } } sched2 = Scheduler( project='project_test', ess_settings=self.ess_settings, species_list=[self.spc1, self.spc2], composite_method=None, conformer_level=default_levels_of_theory['conformer'], opt_level=default_levels_of_theory['opt'], freq_level=default_levels_of_theory['freq'], sp_level=default_levels_of_theory['sp'], scan_level=default_levels_of_theory['scan'], ts_guess_level=default_levels_of_theory['ts_guesses'], rmg_database=self.rmg_database, project_directory=self.project_directory, testing=True, job_types=self.job_types1, orbitals_level=default_levels_of_theory['orbitals'], adaptive_levels=adaptive_levels) original_level = Level(method='CBS-QB3') level1 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='opt', heavy_atoms=5) level2 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='freq', heavy_atoms=5) level3 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='opt', heavy_atoms=20) level4 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='composite', heavy_atoms=50) level5 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='orbitals', heavy_atoms=5) level6 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='sp', heavy_atoms=7) level7 = sched2.determine_adaptive_level( original_level_of_theory=original_level, job_type='sp', heavy_atoms=25) self.assertEqual(level1.simple(), 'wb97xd/6-311+g(2d,2p)') self.assertEqual(level2.simple(), 'wb97xd/6-311+g(2d,2p)') self.assertEqual(level3.simple(), 'b3lyp/6-31g(d,p)') self.assertEqual(level4.simple(), 'cbs-qb3') self.assertEqual(level5.simple(), 'cbs-qb3') self.assertEqual(level6.simple(), 'dlpno-ccsd(t)/def2-tzvp') self.assertEqual(level7.simple(), 'wb97xd/6-311+g(2d,2p)')
def test_append_conformers(self): """Test that ARC correctly parses its own conformer files""" ess_settings = {'gaussian': 'server1', 'molpro': 'server2', 'qchem': 'server1'} project_directory = os.path.join(arc_path, 'Projects', 'arc_project_for_testing_delete_after_usage4') spc1 = ARCSpecies(label=str('vinoxy'), smiles=str('C=C[O]')) rmgdb = make_rmg_database_object() job_types1 = {'conformers': True, 'opt': True, 'fine_grid': False, 'freq': True, 'sp': True, '1d_rotors': False, 'orbitals': False, 'lennard_jones': False, } sched1 = Scheduler(project='project_test', ess_settings=ess_settings, species_list=[spc1], composite_method='', conformer_level=default_levels_of_theory['conformer'], opt_level=default_levels_of_theory['opt'], freq_level=default_levels_of_theory['freq'], sp_level=default_levels_of_theory['sp'], scan_level=default_levels_of_theory['scan'], ts_guess_level=default_levels_of_theory['ts_guesses'], rmgdatabase=rmgdb, project_directory=project_directory, testing=True, job_types=job_types1, orbitals_level=default_levels_of_theory['orbitals'], adaptive_levels=None) xyzs = ["""O 1.09068700 0.26516800 -0.16706300 C 2.92204100 -1.18335700 -0.38884900 C 2.27655500 -0.00373900 0.08543500 H 2.36544800 -1.88781000 -0.99914600 H 3.96112000 -1.38854500 -0.14958800 H 2.87813500 0.68828400 0.70399400 """, """O 1.19396100 -0.06003700 0.03890100 C 3.18797000 0.77061300 -0.87352700 C 2.43591200 -0.04439300 0.02171600 H 4.27370000 0.76090200 -0.86286100 H 2.66641700 1.41155700 -1.57757300 H 3.00398000 -0.68336800 0.72359800 """, """O 1.35241100 -1.02956000 -0.24056200 C -0.72084300 0.01308200 0.09573000 C 0.69217700 0.01185100 -0.09044300 H -1.25803800 -0.93018100 0.10926800 H -1.26861200 0.94177100 0.22420100 H 1.20290400 0.99303700 -0.09819400 """, """O -1.40102900 -0.98575100 -0.11588500 C 0.72457000 -0.01076700 0.06448800 C -0.69494600 0.03450000 -0.06206300 H 1.22539000 -0.97248000 0.11741200 H 1.31277400 0.90087100 0.10878400 H -1.16675800 1.03362600 -0.11273700 """] energies = [0, 5, 5, 5] # J/mol save_conformers_file(project_directory=project_directory, label='vinoxy', xyzs=xyzs, level_of_theory='level1', multiplicity=2, charge=0) self.assertTrue(os.path.isfile(os.path.join(project_directory, 'output', 'Species', 'vinoxy', 'geometry', 'conformers', 'conformers_before_optimization.txt'))) save_conformers_file(project_directory=project_directory, label='vinoxy', xyzs=xyzs, level_of_theory='level1', multiplicity=2, charge=0, energies=energies) self.assertTrue(os.path.isfile(os.path.join(project_directory, 'output', 'Species', 'vinoxy', 'geometry', 'conformers', 'conformers_after_optimization.txt'))) spc2 = ARCSpecies(label=str('vinoxy'), smiles=str('C=C[O]'), xyz=os.path.join( project_directory, 'output', 'Species', 'vinoxy', 'geometry', 'conformers', 'conformers_before_optimization.txt')) spc3 = ARCSpecies(label=str('vinoxy'), smiles=str('C=C[O]'), xyz=os.path.join( project_directory, 'output', 'Species', 'vinoxy', 'geometry', 'conformers', 'conformers_after_optimization.txt')) self.assertEqual(spc2.conformers[2], xyzs[2]) self.assertEqual(spc3.conformers[2], xyzs[2]) self.assertEqual(spc3.conformer_energies[2], energies[2])
def determine_scaling_factors(levels_of_theory, ess_settings=None, init_log=True): """ Determine the zero-point energy, harmonic frequencies, and fundamental frequencies scaling factors for a given frequencies level of theory. Args: levels_of_theory (list, str): A list of frequencies levels of theory for which scaling factors are determined. A string can also be passed for just one level of theory. ess_settings (dict, optional): A dictionary of available ESS (keys) and a corresponding server list (values). init_log (bool, optional): Whether to initialize the logger. True to initialize. Should be True when called as a stand alone, and False when called within ARC. Returns: str: The modified level of theory """ if init_log: initialize_log(log_file='scaling_factor.log', project='Scaling Factors') if isinstance(levels_of_theory, (str, unicode)): levels_of_theory = [levels_of_theory] if not isinstance(levels_of_theory, list): raise InputError( 'levels_of_theory must be a list (or a string if only one level is desired). Got: {0}' .format(type(levels_of_theory))) t0 = time.time() logger.info('\n\n\n') logger.info(HEADER) logger.info('\n\nstarting ARC...\n') # only run opt (fine) and freq job_types = initialize_job_types( dict()) # get the defaults, so no job type is missing job_types = {job_type: False for job_type in job_types.keys()} job_types['opt'], job_types['fine'], job_types['freq'] = True, True, True lambda_zpes, zpe_dicts, times = list(), list(), list() for level_of_theory in levels_of_theory: t1 = time.time() logger.info( '\nComputing scaling factors at the {0} level of theory...\n\n'. format(level_of_theory)) renamed_level = rename_level(level_of_theory) project = 'scaling_' + renamed_level project_directory = os.path.join(arc_path, 'Projects', 'scaling_factors', project) species_list = get_species_list() if '//' in level_of_theory: raise InputError( 'Level of theory should either be a composite method or in a method/basis-set format. ' 'Got {0}'.format(level_of_theory)) if '/' not in level_of_theory: # assume this is a composite method freq_level = '' composite_method = level_of_theory.lower() job_types['freq'] = False else: freq_level = level_of_theory.lower() composite_method = '' job_types['freq'] = True ess_settings = check_ess_settings(ess_settings or global_ess_settings) Scheduler(project=project, project_directory=project_directory, species_list=species_list, composite_method=composite_method, opt_level=freq_level, freq_level=freq_level, ess_settings=ess_settings, job_types=job_types, allow_nonisomorphic_2d=True) zpe_dict = dict() for spc in species_list: try: zpe = get_zpe( os.path.join(project_directory, 'output', 'Species', spc.label, 'geometry', 'freq.out')) except Exception: zpe = None zpe_dict[spc.label] = zpe zpe_dicts.append(zpe_dict) lambda_zpes.append( calculate_truhlar_scaling_factors(zpe_dict, level_of_theory)) times.append(time_lapse(t1)) summarize_results(lambda_zpes, levels_of_theory, zpe_dicts, times, time_lapse(t0)) logger.info('\n\n\n') logger.info(HEADER) harmonic_freq_scaling_factors = [ lambda_zpe * 1.014 for lambda_zpe in lambda_zpes ] return harmonic_freq_scaling_factors