コード例 #1
0
ファイル: statmechTest.py プロジェクト: saud3001/RMG-Py
 def test_rotor_symmetry_determination(self):
     """
     Test that the correct symmetry number is determined for rotor potential scans.
     """
     path1 = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'NCC_NRotor.out')
     path2 = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'NCC_CRotor.out')
     scan_log1 = QChemLog(path1)
     scan_log2 = QChemLog(path2)
     v_list1, angle = scan_log1.load_scan_energies()
     v_list2, angle = scan_log2.load_scan_energies()
     symmetry1 = determine_rotor_symmetry(energies=v_list1, label='NCC', pivots=[])
     symmetry2 = determine_rotor_symmetry(energies=v_list2, label='NCC', pivots=[])
     self.assertEqual(symmetry1, 1)
     self.assertEqual(symmetry2, 3)
コード例 #2
0
ファイル: common.py プロジェクト: shihchengli/APE
def sampling_along_torsion(symbols,
                           cart_coords,
                           mode,
                           internal_object,
                           conformer,
                           int_freq,
                           rotors_dict,
                           scan_res,
                           path,
                           thresh,
                           ncpus,
                           charge=None,
                           multiplicity=None,
                           rem_variables_dict=None,
                           gen_basis="",
                           is_QM_MM_INTERFACE=None,
                           QM_USER_CONNECT=None,
                           QM_ATOMS=None,
                           force_field_params=None,
                           fixed_molecule_string=None,
                           opt=None,
                           label=None):
    logging.info('Sampling Mode {}'.format(mode))
    XyzDictOfEachMode = {}
    EnergyDictOfEachMode = {}
    ModeDictOfEachMode = {}

    # Extract rotor information
    pivots = rotors_dict[mode]['pivots']
    top = rotors_dict[mode]['top']
    scan = rotors_dict[mode]['scan']

    # Determine sampling step size
    step_size = np.pi / (180 / scan_res)

    # Save information of this mode
    ModeDictOfEachMode['mode'] = 'tors'
    ModeDictOfEachMode['M'] = conformer.get_internal_reduced_moment_of_inertia(
        pivots, top) * constants.Na * 1e23  # in amu*angstrom^2
    ModeDictOfEachMode['K'] = (int_freq *
                               (2 * np.pi * constants.c * 100))**2  # in 1/s^2
    ModeDictOfEachMode['step_size'] = step_size  # in radian

    # Create the unit vector, qk, for displacement along the kth bond torsion
    n_rotors = len(rotors_dict)
    internal = copy.deepcopy(internal_object)
    scan_indices = internal.B_indices[-n_rotors:]
    torsion_ind = len(internal.B_indices) - n_rotors + scan_indices.index(
        [ind - 1 for ind in scan])
    B = internal.B
    nrow = B.shape[0]
    qk = np.zeros(nrow, dtype=int)
    qk[torsion_ind] = 1

    if internal.prim_coords[torsion_ind] > 0:
        qk *= -1

    # Start to sample 1-D PES
    logging.info('direction = 1')
    nsample = int(360 / scan_res) + 1
    initial_geometry = cart_coords.copy()
    cart_coords = initial_geometry.copy()
    fail_in_torsion_sampling = False
    for sample in range(nsample):
        xyz = getXYZ(symbols, cart_coords)
        file_name = 'tors_{}_{}'.format(mode, sample)

        # Calculate electronic energy of each sampling point, and save the result
        if is_QM_MM_INTERFACE:
            e_elec = get_electronic_energy(xyz, path, file_name, ncpus, charge,
                                           multiplicity, rem_variables_dict,
                                           gen_basis, is_QM_MM_INTERFACE,
                                           QM_USER_CONNECT, QM_ATOMS,
                                           force_field_params,
                                           fixed_molecule_string, opt)
        else:
            e_elec = get_electronic_energy(xyz, path, file_name, ncpus, charge,
                                           multiplicity, rem_variables_dict,
                                           gen_basis)
        XyzDictOfEachMode[sample] = xyz

        # Take the electronic energy of stationary point as reference energy, min_elect
        if sample == 0:
            EnergyDictOfEachMode[sample] = 0
            min_elect = e_elec
        else:
            logging.info('ngrid = {}'.format(sample))
            EnergyDictOfEachMode[sample] = e_elec - min_elect

        # Check if this mode is a high-barrier hindered rotation
        if e_elec - min_elect > thresh:
            # Treat this mode as a vibrational normal mode
            fail_in_torsion_sampling = True
            logging.info(
                '\n***********************************************************************'
            )
            logging.info(
                'Since the torsional barrier of mode {} is higher than {} hartree.'
                .format(mode, thresh))
            logging.info(
                'This mode will be treated as vibrational mode later on.')
            logging.info(
                '***********************************************************************\n'
            )
            return {}, {}, {}, min_elect

        # Update cartesian coordinate of each sampling point
        cart_coords += internal.transform_int_step(
            (qk * step_size).reshape(-1, )) * BOHR2ANG

    # Determine the symmetry number of this internal rotation, and save the result
    if fail_in_torsion_sampling is False:
        v_list = [
            i * (constants.E_h * constants.Na)
            for i in EnergyDictOfEachMode.values()
        ]  # in J/mol
        symmetry_number = determine_rotor_symmetry(v_list, label, pivots)
        # symmetry_number = 3
        logging.info('\n')
        ModeDictOfEachMode['symmetry_number'] = symmetry_number

    return XyzDictOfEachMode, EnergyDictOfEachMode, ModeDictOfEachMode, min_elect