def test_parse_zpe(self):
     """Test the parse_zpe() function for parsing zero point energies"""
     path1 = os.path.join(ARC_PATH, 'arc', 'testing', 'freq', 'C2H6_freq_QChem.out')
     path2 = os.path.join(ARC_PATH, 'arc', 'testing', 'freq', 'CH2O_freq_molpro.out')
     path3 = os.path.join(ARC_PATH, 'arc', 'testing', 'freq', 'NO3_freq_QChem_fails_on_cclib.out')
     path4 = os.path.join(ARC_PATH, 'arc', 'testing', 'composite', 'SO2OO_CBS-QB3.log')
     zpe1, zpe2, zpe3, zpe4 = parser.parse_zpe(path1), parser.parse_zpe(path2), parser.parse_zpe(path3), \
         parser.parse_zpe(path4)
     self.assertAlmostEqual(zpe1, 198.08311200000, 5)
     self.assertAlmostEqual(zpe2, 69.793662734869, 5)
     self.assertAlmostEqual(zpe3, 25.401064000000, 5)
     self.assertAlmostEqual(zpe4, 39.368057626223, 5)
Beispiel #2
0
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