Example #1
0
 def test_ric_add_ic(self):
     with path("saddle.test.data", "water.xyz") as mol_path:
         mol = Utils.load_file(mol_path)
     ri_mol = Internal(mol.coordinates, mol.numbers, 0, 1)
     ri_mol = ReducedInternal.update_to_reduced_internal(ri_mol)
     ri_mol.add_bond(1, 0)
     ri_mol.add_bond(1, 2)
     ri_mol.add_bond(0, 2)
     ri_mol.vspace
     ri_mol.add_angle(0, 1, 2)
     ri_mol.add_angle(1, 0, 2)
     ri_mol.select_key_ic(0, 2)
     vp_ref = np.array(
         [
             [4.40930006e-01, -7.79280781e-01, 6.12072474e-17],
             [-5.61408260e-01, -6.12047068e-01, -3.33066907e-16],
             [-4.57920570e-01, -3.28254718e-02, -7.16200549e-01],
             [-5.22760813e-01, 4.87258745e-02, 5.58315734e-01],
             [8.62054537e-02, 1.21112047e-01, -4.18736570e-01],
         ]
     )
     for i in range(vp_ref.shape[1]):
         assert np.allclose(ri_mol.vspace[:, i], vp_ref[:, i]) or np.allclose(
             ri_mol.vspace[:, i], -1 * vp_ref[:, i]
         )
     ri_mol.set_key_ic_number(1)
     assert ri_mol._red_space is None
     assert ri_mol._non_red_space is None
Example #2
0
class TestInternal(unittest.TestCase):
    """Test internal coordinates transform."""
    def setUp(self):
        """Setup function."""
        with path("saddle.test.data", "water.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        self.mol = Internal(mol.coordinates, mol.numbers, 0, 1)
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol2 = Utils.load_file(mol_path)
        self.h2o2 = Internal(mol2.coordinates, mol2.numbers, 0, 1)

    def test_ic_weights(self):
        """Test change internal coordinates weights."""
        self.mol.auto_select_ic()
        assert_allclose(self.mol.ic_weights, [1, 1, 1])
        self.mol.set_ic_weights(np.array([0.5, 0.5, 2]))
        assert_allclose(self.mol.ic_weights, [0.5, 0.5, 2])

        self.h2o2.auto_select_ic()
        self.h2o2.set_dihed_weights(0)
        assert self.h2o2.ic[-1].weight == 0

    def test_connectivity(self):
        """Test default connectivity."""
        assert_allclose(self.mol.connectivity, np.eye(3) * -1)

    def test_file_title(self):
        """Test default file title."""
        new_mol = Internal(self.mol.coordinates, self.mol.numbers, 0, 1)
        assert len(new_mol._title) == 15

    def test_add_bond(self):
        """"""
        init_con = np.eye(3) * -1
        assert_allclose(self.mol.connectivity, init_con)
        new_con = init_con.copy()
        # add a bond connection
        self.mol.add_bond(1, 0)
        new_con[0, 1] = 1
        new_con[1, 0] = 1
        # test same connectivity
        assert_allclose(self.mol.connectivity, new_con)
        assert_allclose(self.mol.ic_values, np.array([1.81413724]))
        assert self.mol.ic[0].atoms == (0, 1)
        # add dup bond
        self.mol.add_bond(0, 1)
        ref_hessian = np.array([[
            [
                0.18374187,
                0.25985046,
                0.0,
                -0.18374187,
                -0.25985046,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.25985046,
                0.36748434,
                0.0,
                -0.25985046,
                -0.36748434,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [0.0, 0.0, 0.55122621, 0.0, 0.0, -0.55122621, 0.0, 0.0, 0.0],
            [
                -0.18374187,
                -0.25985046,
                0.0,
                0.18374187,
                0.25985046,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                -0.25985046,
                -0.36748434,
                0.0,
                0.25985046,
                0.36748434,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [0.0, 0.0, -0.55122621, 0.0, 0.0, 0.55122621, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        ]])
        assert_allclose(self.mol._cc_to_ic_hessian, ref_hessian)
        assert len(self.mol.ic) == 1
        # bond_type 1 == covalent bond
        assert_allclose(self.mol.connectivity, new_con)
        self.mol.add_bond(2, 1)
        assert len(self.mol.ic) == 2
        assert self.mol.ic[1].atoms == (1, 2)
        assert_allclose(
            self.mol._cc_to_ic_gradient,
            np.array([
                [
                    0.81649681,
                    -0.57734995,
                    0.0,
                    -0.81649681,
                    0.57734995,
                    0.0,
                    0.0,
                    0.0,
                    0.0,
                ],
                [
                    0.0,
                    0.0,
                    0.0,
                    0.81649681,
                    0.57734995,
                    0.0,
                    -0.81649681,
                    -0.57734995,
                    0.0,
                ],
            ]),
        )

    def test_angle_add(self):
        """Test add angle to internal coordinates."""
        self.mol.add_angle(0, 1, 2)
        assert len(self.mol.ic) == 0
        self.mol.add_bond(0, 1)
        self.mol.add_bond(1, 2)
        connected_index = self.mol.connected_indices(1)
        assert_allclose(connected_index, np.array([0, 2]))
        self.mol.add_angle(0, 1, 2)
        assert len(self.mol.ic) == 3
        assert_allclose(self.mol.ic[2].value, 1.9106340153991836)
        assert_allclose(
            self.mol.b_matrix[2],
            np.array([
                0.31825043,
                0.45007444,
                0.0,
                0.0,
                -0.90014888,
                -0.0,
                -0.31825043,
                0.45007444,
                0.0,
            ]),
        )
        assert_allclose(
            self.mol._cc_to_ic_hessian[2],
            np.array([
                [
                    -2.86472766e-01,
                    -1.01283669e-01,
                    0.00000000e00,
                    2.86472766e-01,
                    1.01283669e-01,
                    0.00000000e00,
                    2.08166817e-17,
                    -6.93889390e-18,
                    0.00000000e00,
                ],
                [
                    -1.01283669e-01,
                    2.86472766e-01,
                    0.00000000e00,
                    1.01283669e-01,
                    -2.86472766e-01,
                    0.00000000e00,
                    6.93889390e-18,
                    4.16333634e-17,
                    0.00000000e00,
                ],
                [
                    0.00000000e00,
                    0.00000000e00,
                    -1.07427583e-01,
                    0.00000000e00,
                    0.00000000e00,
                    4.29709622e-01,
                    0.00000000e00,
                    0.00000000e00,
                    -3.22282039e-01,
                ],
                [
                    2.86472766e-01,
                    1.01283669e-01,
                    0.00000000e00,
                    -5.72945532e-01,
                    0.00000000e00,
                    0.00000000e00,
                    2.86472766e-01,
                    -1.01283669e-01,
                    0.00000000e00,
                ],
                [
                    1.01283669e-01,
                    -2.86472766e-01,
                    0.00000000e00,
                    0.00000000e00,
                    5.72945532e-01,
                    0.00000000e00,
                    -1.01283669e-01,
                    -2.86472766e-01,
                    0.00000000e00,
                ],
                [
                    0.00000000e00,
                    0.00000000e00,
                    4.29709622e-01,
                    0.00000000e00,
                    0.00000000e00,
                    -8.59419245e-01,
                    0.00000000e00,
                    0.00000000e00,
                    4.29709622e-01,
                ],
                [
                    2.08166817e-17,
                    6.93889390e-18,
                    0.00000000e00,
                    2.86472766e-01,
                    -1.01283669e-01,
                    0.00000000e00,
                    -2.86472766e-01,
                    1.01283669e-01,
                    0.00000000e00,
                ],
                [
                    -6.93889390e-18,
                    4.16333634e-17,
                    0.00000000e00,
                    -1.01283669e-01,
                    -2.86472766e-01,
                    0.00000000e00,
                    1.01283669e-01,
                    2.86472766e-01,
                    0.00000000e00,
                ],
                [
                    0.00000000e00,
                    0.00000000e00,
                    -3.22282039e-01,
                    0.00000000e00,
                    0.00000000e00,
                    4.29709622e-01,
                    0.00000000e00,
                    0.00000000e00,
                    -1.07427583e-01,
                ],
            ]),
        )
        self.mol.set_target_ic((1.6, 1.7, -0.5))
        assert_allclose(self.mol.target_ic, np.array([1.6, 1.7, -0.5]))

    def test_dihedral_add(self):
        """Test add normal dihedral."""
        with path("saddle.test.data", "2h-azirine.xyz") as mol_path:
            mol = Utils.load_file(mol_path)  # create a water molecule
        internal = Internal(mol.coordinates, mol.numbers, 0, 1)
        internal.add_bond(0, 1)
        internal.add_bond(1, 2)
        internal.add_bond(1, 3)
        # fake add dihed
        internal.add_dihedral(0, 2, 3, 4)
        assert len(internal.ic) == 3
        internal.add_dihedral(0, 1, 2, 3)
        assert len(internal.ic) == 4
        assert internal.ic_values[3] == dihed_angle(internal.coordinates[:4])

    def test_cost_function(self):
        """"""
        self.mol.add_bond(0, 1)
        self.mol.add_bond(1, 2)
        self.mol.add_angle(0, 1, 2)
        assert_allclose(
            self.mol.ic_values,
            [1.8141372422079882, 1.8141372422079882, 1.9106340153991836],
        )
        self.mol.set_target_ic([1.7, 1.7, 1.5])
        self.mol.swap_internal_coordinates(0, 2)
        assert_allclose(
            self.mol.ic_values,
            [1.9106340153991836, 1.8141372422079882, 1.8141372422079882],
        )
        assert_allclose(self.mol.target_ic, [1.5, 1.7, 1.7])
        self.mol.swap_internal_coordinates(0, 2)
        assert_allclose(
            self.mol.ic_values,
            [1.8141372422079882, 1.8141372422079882, 1.9106340153991836],
        )
        assert_allclose(self.mol.target_ic, [1.7, 1.7, 1.5])
        # test cost function in ic
        v = self.mol.tf_cost
        d = self.mol._cost_q_d
        dd = self.mol._cost_q_dd

        # calculate ref cost value
        ref_cost = (self.mol.ic_values[0] - 1.7)**2 * 2 + (
            np.cos(self.mol.ic_values[-1]) - np.cos(1.5))**2
        assert_allclose(ref_cost, v)
        ref_gradient = np.array(
            [0.22827448441597653, 0.22827448441597653, 0.76192388])
        assert_allclose(d, ref_gradient)
        ref_hessian = np.array([[2.0, 0.0, 0.0], [0.0, 2.0, 0.0],
                                [0.0, 0.0, 1.5083953582]])
        assert_allclose(dd, ref_hessian)
        # assert False
        new_v, xd, xdd = self.mol.cost_value_in_cc
        assert new_v == v
        assert_allclose(xd, np.dot(self.mol._cc_to_ic_gradient.T, d))
        ref_x_hessian = np.dot(np.dot(self.mol._cc_to_ic_gradient.T, dd),
                               self.mol._cc_to_ic_gradient)
        K = np.tensordot(d, self.mol._cc_to_ic_hessian, 1)
        ref_x_hessian += K
        assert_allclose(xdd, ref_x_hessian)
        new_coor = np.array([
            [1.40, -0.93019123, -0.0],
            [-0.0, 0.11720081, -0.0],
            [-1.40, -0.93019123, -0.0],
        ])
        self.mol.set_new_coordinates(new_coor)
        assert_allclose(self.mol.ic_values,
                        [1.7484364736491811, 1.7484364736491811, 1.85697699])
        assert_allclose(
            self.mol._cc_to_ic_gradient[0, :6],
            np.array(
                [0.80071539, -0.59904495, 0.0, -0.80071539, 0.59904495, -0.0]),
        )
        ref_hessian = np.array([
            [0.20524329, 0.27433912, 0.0, -0.20524329, -0.27433912, -0.0],
            [0.27433912, 0.36669628, 0.0, -0.27433912, -0.36669628, -0.0],
            [0.0, 0.0, 0.57193957, -0.0, -0.0, -0.57193957],
            [-0.20524329, -0.27433912, -0.0, 0.20524329, 0.27433912, 0.0],
            [-0.27433912, -0.36669628, -0.0, 0.27433912, 0.36669628, 0.0],
            [-0.0, -0.0, -0.57193957, 0.0, 0.0, 0.57193957],
        ])
        assert_allclose(self.mol._cc_to_ic_hessian[0, :6, :6], ref_hessian)

    def test_transform_function(self):
        self.mol.add_bond(0, 1)
        self.mol.add_bond(1, 2)
        self.mol.add_angle(0, 1, 2)
        self.mol.set_target_ic([1.7, 1.7, -0.4])
        n_p = self.mol.create_geo_point()
        assert isinstance(n_p, Point)
        assert n_p.trust_radius == 1.7320508075688772

        self.mol.converge_to_target_ic(max_iter=100)
        g_array = self.mol.cost_value_in_cc[1]
        assert len(g_array[abs(g_array) > 3e-4]) == 0

    def test_auto_ic_select_water(self):
        self.mol.auto_select_ic()
        assert_allclose(
            self.mol.ic_values,
            [1.8141372422079882, 1.8141372422079882, 1.9106340153991836],
        )

    def test_auto_ic_select_ethane(self):
        with path("saddle.test.data", "ethane.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        ethane = Internal(mol.coordinates, mol.numbers, 0, 1)
        ethane.auto_select_ic()
        assert len(ethane.ic) == 24

    def test_auto_dihed_number_ethane(self):
        with path("saddle.test.data", "ethane.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        mol = Utils.load_file(mol_path)
        ethane = Internal(mol.coordinates, mol.numbers, 0, 1)
        ethane.auto_select_ic()
        counter = 0
        for ic in ethane.ic:
            if isinstance(ic, DihedralAngle):
                counter += 1
        assert counter == 5

    def test_auto_select_improper_ch3_hf(self):
        with path("saddle.test.data", "ch3_hf.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        mol = Internal(mol.coordinates, mol.numbers, 0, 1)
        mol.auto_select_ic()
        ic_ref = np.array([
            2.02762919,
            2.02769736,
            2.02761705,
            1.77505755,
            4.27707385,
            4.87406146,
            2.08356856,
            2.08391343,
            1.64995596,
            2.08364916,
            1.64984524,
            1.64881837,
            1.06512165,
            0.42765264,
            3.14154596,
            2.71390135,
            0.59485389,
            -1.70630517,
            1.7061358,
            -3.14152957,
            2.09455878,
            -2.09427619,
            -2.87079827,
        ])
        assert_allclose(mol.ic_values, ic_ref)

    def test_auto_ic_select_methanol(self):
        with path("saddle.test.data", "methanol.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        methanol = Internal(mol.coordinates, mol.numbers, 0, 1)
        methanol.auto_select_ic()
        assert len(methanol.ic) == 15

    def test_wipe_ic(self):
        self.mol.add_bond(0, 1)
        self.mol.add_bond(1, 2)
        self.mol.add_bond(0, 2)
        assert len(self.mol.ic) == 3
        self.mol.wipe_ic_info(False)
        assert len(self.mol.ic) == 3
        self.mol.wipe_ic_info(True)
        assert len(self.mol.ic) == 0

    def test_set_new_ic(self):
        mol1 = deepcopy(self.mol)
        mol2 = deepcopy(self.mol)
        mol1.add_bond(0, 1)
        mol1.add_bond(0, 2)
        mol1.add_angle(1, 0, 2)
        mol2.set_new_ics(mol1.ic)
        assert_allclose(mol2.ic_values, mol1.ic_values)
        mol2.wipe_ic_info(True)
        mol2.add_bond(2, 0)
        assert len(mol2.ic) == 1
        assert not np.allclose(mol2.connectivity, mol1.connectivity)
        mol2.set_new_ics(mol1.ic)
        assert_allclose(mol1.connectivity, mol2.connectivity)

    def test_get_energy_from_fchk(self):
        with path("saddle.test.data", "water_1.fchk") as fchk_path:
            self.mol.add_bond(0, 1)
            self.mol.add_bond(1, 2)
            self.mol.add_angle(0, 1, 2)
            self.mol.energy_from_fchk(fchk_path)
        ref_g = self.mol.internal_gradient.copy()
        assert_allclose(self.mol.internal_gradient, ref_g)
        ic_ref = deepcopy(self.mol.ic)
        self.mol.add_bond(0, 2)
        assert not np.allclose(self.mol.internal_gradient.shape, ref_g.shape)
        self.mol.set_new_ics(ic_ref)
        assert_allclose(self.mol.internal_gradient, ref_g)
        self.mol.swap_internal_coordinates(0, 2)
        assert_allclose(self.mol.internal_gradient[2], ref_g[0])
        assert_allclose(self.mol.internal_gradient[0], ref_g[2])

    def test_delete_ic(self):
        with path("saddle.test.data", "ethane.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        ethane = Internal(mol.coordinates, mol.numbers, 0, 1)
        ethane.auto_select_ic()
        ethane._delete_ic_index(0)
        assert len(ethane.ic) == 23
        ethane.auto_select_ic(keep_bond=True)
        assert len(ethane.ic) == 12
        # print(ethane.ic)
        ethane.delete_ic(1, 2, 3)
        assert len(ethane.ic) == 9
        # print(ethane.ic)
        # assert False

    def test_fragments_in_mole(self):
        with path("saddle.test.data", "ch3_hf.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        mol = Internal(mol.coordinates, mol.numbers, 0, 1)
        assert len(mol.fragments) == mol.natom
        mol.add_bond(0, 1)
        mol.add_bond(2, 3)
        # print(mol.fragments)
        assert len(mol.fragments) == mol.natom - 2
        mol.add_bond(0, 2)
        assert len(mol.fragments) == mol.natom - 3
        mol.add_bond(0, 3)
        assert len(mol.fragments) == mol.natom - 3
        mol.add_bond(4, 5)
        assert len(mol.fragments) == mol.natom - 4
        mol.add_bond(0, 5, b_type=3)
        assert len(mol.fragments) == 2

    def test_fragments_bond_add(self):
        with path("saddle.test.data", "ch3_hf.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        mol = Internal(mol.coordinates, mol.numbers, 0, 1)
        mol._auto_select_fragment_bond()
        assert len(mol.ic) == 15

        mol.wipe_ic_info(True)
        mol.add_bond(0, 1)
        mol._auto_select_fragment_bond()
        assert len(mol.ic) == 15

        mol.wipe_ic_info(True)
        mol.add_bond(0, 1)
        mol.add_bond(0, 5)
        mol.add_bond(0, 3)
        mol.add_bond(4, 2)
        mol._auto_select_fragment_bond()
        assert len(mol.ic) == 6

        mol.wipe_ic_info(True)
        mol.add_bond(0, 1)
        mol.add_bond(2, 3)
        mol.add_bond(4, 5)
        mol._auto_select_fragment_bond()
        assert len(mol.ic) == 9
        #
        mol.wipe_ic_info(True)
        mol.add_bond(0, 1)
        mol.add_bond(0, 2)
        mol.add_bond(3, 4)
        mol.add_bond(4, 5)
        mol._auto_select_fragment_bond()
        assert_allclose(mol.ic_values[4], 2.02761704779693)
        assert mol.ic[4].atoms == (0, 3)
        assert_allclose(mol.ic_values[5], 3.501060110109399)
        assert mol.ic[5].atoms == (2, 3)
        assert len(mol.ic) == 6

    def test_dihedral_rotation(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        h2o2 = Internal(mol.coordinates, mol.numbers, 0, 1)
        h2o2.auto_select_ic()
        ref_ic = np.array([
            2.47617635, 1.85058569, 1.85070922, 1.81937566, 1.81930967,
            1.43966113
        ])
        assert_allclose(h2o2.ic_values, ref_ic)
        target_ic = [2.4, 1.8, 1.8, 1.6, 1.6, 1.57]
        h2o2.set_target_ic(target_ic)
        h2o2.converge_to_target_ic()
        assert_allclose(h2o2.ic_values, target_ic, atol=1e-3)

        target_ic = [2.4, 1.8, 1.8, 1.6, 1.6, 3.14]
        h2o2.set_target_ic(target_ic)
        h2o2.converge_to_target_ic()
        assert_allclose(h2o2.ic_values, target_ic, atol=1e-4)

        target_ic = [2.4, 1.8, 1.8, 1.6, 1.6, -1.57]
        h2o2.set_target_ic(target_ic)
        h2o2.converge_to_target_ic()
        assert_allclose(h2o2.ic_values, target_ic, atol=1e-3)

    def test_dihedral_repeak(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        h2o2 = Internal(mol.coordinates, mol.numbers, 0, 1)
        h2o2.add_bond(0, 1)
        h2o2.add_bond(1, 2)
        h2o2.add_bond(2, 3)
        h2o2.add_bond(3, 2)
        h2o2.add_bond(0, 2)
        h2o2.add_bond(1, 3)
        assert len(h2o2.ic) == 5
        h2o2.add_dihedral(0, 1, 2, 3)
        assert len(h2o2.ic) == 6
        h2o2.add_dihedral(0, 2, 1, 3)
        assert len(h2o2.ic) == 6

    def test_new_dihed(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        h2o2 = Internal(mol.coordinates, mol.numbers, 0, 1)
        h2o2.add_bond(0, 1)
        h2o2.add_bond(1, 2)
        h2o2.add_bond(2, 3)
        assert len(h2o2.ic) == 3
        h2o2.add_dihedral(0, 1, 2, 3, special=True)
        assert len(h2o2.ic) == 5
        assert h2o2.b_matrix.shape == (5, 12)
        h2o2.add_dihedral(3, 1, 2, 0)
        assert len(h2o2.ic) == 5
        h2o2.add_dihedral(3, 2, 1, 0, special=True)
        assert len(h2o2.ic) == 5
        ref_b = h2o2.b_matrix.copy()
        h2o2._regenerate_ic()
        assert_allclose(h2o2.b_matrix, ref_b)

    def test_new_dihed_converge(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Utils.load_file(mol_path)
        mol = Utils.load_file(mol_path)
        h2o2 = Internal(mol.coordinates, mol.numbers, 0, 1)
        h2o2.auto_select_ic(dihed_special=True)
        assert len(h2o2.ic) == 7
        # print(h2o2.ic_values)
        target_ic = [2.4, 1.8, 1.8, 1.6, 1.6, 0.8, 0.6]
        h2o2.set_target_ic(target_ic)
        h2o2.converge_to_target_ic()
        # print(h2o2.ic_values)
        assert_allclose(h2o2.ic_values, target_ic, atol=1e-2)
        # print(h2o2.ic_values)

    def test_bond_type(self):
        with path("saddle.test.data", "ch3_hf.xyz") as mol_path:
            mol = Internal.from_file(mol_path, charge=0, multi=1)
        mol._auto_select_cov_bond()  # numbers [6 1 1 1 9 1]
        assert np.sum(mol.connectivity[0] == 1) == 3
        assert np.sum(mol.connectivity[4] == 1) == 1
        mol._auto_select_fragment_bond()
        assert np.sum(mol.connectivity[0] == 1) == 3
        assert len(np.unique(mol.fragments)) == 1
        assert np.sum(mol.connectivity[5] == 3) == 2
        mol._regenerate_ic()
        assert np.sum(mol.connectivity[0] == 1) == 3
        assert len(np.unique(mol.fragments)) == 1
        assert np.sum(mol.connectivity[5] == 3) == 2
        mol.wipe_ic_info(True)
        mol.auto_select_ic()
        assert np.sum(mol.connectivity[0] == 1) == 3
        assert len(np.unique(mol.fragments)) == 1
        assert np.sum(mol.connectivity[5] == 3) == 2

    def test_h_bond(self):
        with path("saddle.test.data", "di_water.xyz") as mol_path:
            mol = Internal.from_file(mol_path, charge=0, multi=1)
        mol._auto_select_cov_bond()  # numbers [8 1 1 8 1 1]
        assert np.sum(mol.connectivity[0] == 1) == 2
        assert np.sum(mol.connectivity[3] == 1) == 2
        assert len(mol.fragments) == 2
        # print(mol.connectivity)
        mol._auto_select_h_bond()
        assert mol.connectivity[2][3] == 2
        assert len(mol.fragments) == 2

    def test_mini_dihed(self):
        with path("saddle.test.data", "methanol.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol._auto_select_cov_bond()
        mol._auto_select_h_bond()
        mol._auto_select_fragment_bond()
        mol._auto_select_angle()
        # start real parts
        ref = len(mol.ic)
        mol._auto_select_minimum_dihed_normal()
        assert len(mol.ic) - ref == 1

        with path("saddle.test.data", "ethane.xyz") as mol2_path:
            mol2 = Internal.from_file(mol2_path)
        mol2._auto_select_cov_bond()
        mol2._auto_select_h_bond()
        mol2._auto_select_fragment_bond()
        mol2._auto_select_angle()
        # start real parts
        ref = len(mol2.ic)
        mol2._auto_select_minimum_dihed_normal()
        assert len(mol2.ic) - ref == 1

    def test_b_matrix(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.add_bond(0, 1)
        mol.add_bond(1, 2)
        mol.add_angle(0, 1, 2)
        ref_mol = deepcopy(mol)
        q1 = mol.ic_values[0]
        for i in range(3):
            coor = mol.coordinates.copy()
            coor[0][i] += 1e-4
            ref_mol.set_new_coordinates(coor)
            q2 = ref_mol.ic_values[0]
            fd = (q2 - q1) / 1e-4
            b = mol.b_matrix[0][i]
            assert_allclose(fd, b, atol=1e-4)

        q1 = mol.ic_values[1]
        for i in range(3):
            coor = mol.coordinates.copy()
            coor[1][i] += 1e-4
            ref_mol.set_new_coordinates(coor)
            q2 = ref_mol.ic_values[1]
            fd = (q2 - q1) / 1e-4
            b = mol.b_matrix[1][3 + i]
            assert_allclose(fd, b, atol=1e-4)

        q1 = mol.ic_values[2]
        for i in range(3):
            coor = mol.coordinates.copy()
            coor[2][i] += 1e-4
            ref_mol.set_new_coordinates(coor)
            q2 = ref_mol.ic_values[2]
            fd = (q2 - q1) / 1e-4
            b = mol.b_matrix[2][6 + i]
            assert_allclose(fd, b, atol=1e-4)

    def test_b_matrix_dihed(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        ref_mol = deepcopy(mol)
        for j in range(4):
            q1 = mol.ic_values[j]
            for i in range(3):
                coor = mol.coordinates.copy()
                coor[j][i] += 1e-4
                ref_mol.set_new_coordinates(coor)
                q2 = ref_mol.ic_values[j]
                fd = (q2 - q1) / 1e-4
                b = mol.b_matrix[j][j * 3 + i]
                assert_allclose(fd, b, atol=1e-4)

    def test_tfm_hessian(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.add_bond(0, 1)
        mol.add_bond(1, 2)
        mol.add_angle(0, 1, 2)
        ref_mol = deepcopy(mol)
        qd1 = mol.b_matrix
        for i in range(3):
            coor = mol.coordinates.copy()
            coor[0][i] += 1e-4
            ref_mol.set_new_coordinates(coor)
            qd2 = ref_mol.b_matrix
            fd_b = (qd2 - qd1) / 1e-4
            analytic_b = mol._cc_to_ic_hessian[:, :, i]
            assert_allclose(fd_b, analytic_b, atol=1e-4)

    def test_tfm_hessian_dihed(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        ref_mol = deepcopy(mol)
        qd1 = mol.b_matrix
        for j in range(4):
            for i in range(3):
                coor = mol.coordinates.copy()
                coor[j][i] += 1e-4
                ref_mol.set_new_coordinates(coor)
                qd2 = ref_mol.b_matrix
                fd_b = (qd2 - qd1) / 1e-4
                analytic_b = mol._cc_to_ic_hessian[:, :, 3 * j + i]
                assert_allclose(fd_b, analytic_b, atol=1e-4)

    def test_cost_tfm_bond(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.add_bond(0, 1)
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values
        # print(mol.ic)
        target_ic[0] = 2
        mol.set_target_ic(target_ic)
        # print(mol.ic[0].value - mol.ic[0].target)
        cost_v = mol._compute_tfm_cost()
        cost_g = mol._compute_tfm_gradient()
        diff = 1e-4
        assert_allclose(cost_v, (2 - 2.47617635)**2)
        # finite diff test
        for i in range(4):
            for j in range(3):
                coor = ref_mol.coordinates.copy()
                coor[i][j] += diff
                mol.set_new_coordinates(coor)
                cost_v_2 = mol._compute_tfm_cost()
                fd = (cost_v_2 - cost_v) / 1e-4
                print(fd, cost_g[i * 3 + j], i * 3 + j)
                assert_allclose(fd, cost_g[3 * i + j], atol=2e-4)

        # tests with bond and angle

    def test_cost_tfm_angle(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.add_bond(0, 1)
        mol.add_bond(0, 2)
        mol.add_angle(1, 0, 2)
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values
        # print(mol.ic)
        target_ic[2] = 2
        target_ic[0] = 2
        mol.set_target_ic(target_ic)
        # print(mol.ic[0].value - mol.ic[0].target)
        cost_v = mol._compute_tfm_cost()
        cost_g = mol._compute_tfm_gradient()
        diff = 1e-4
        # assert_allclose(cost_v, (2 - 2.47617635) ** 2)
        # finite diff test
        for i in range(4):
            for j in range(3):
                coor = ref_mol.coordinates.copy()
                coor[i][j] += diff
                mol.set_new_coordinates(coor)
                cost_v_2 = mol._compute_tfm_cost()
                fd = (cost_v_2 - cost_v) / 1e-4
                print(fd, cost_g[i * 3 + j], i * 3 + j)
                assert_allclose(fd, cost_g[3 * i + j], atol=2e-4)

    def test_cost_tfm_dihed(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values
        # print(mol.ic)
        target_ic[0] = 2
        target_ic[3] = 2
        target_ic[5] = 2
        mol.set_target_ic(target_ic)
        # print(mol.ic[0].value - mol.ic[0].target)
        cost_v = mol._compute_tfm_cost()
        cost_g = mol._compute_tfm_gradient()
        diff = 1e-4
        # assert_allclose(cost_v, (2 - 2.47617635) ** 2)
        # finite diff test
        mol.list_ic
        for i in range(4):
            for j in range(3):
                coor = ref_mol.coordinates.copy()
                coor[i][j] += diff
                mol.set_new_coordinates(coor)
                cost_v_2 = mol._compute_tfm_cost()
                fd = (cost_v_2 - cost_v) / 1e-4
                assert_allclose(fd, cost_g[3 * i + j], atol=2e-2)

    def test_cost_tfm_dihed_cmplx(self):
        with path("saddle.test.data", "ethane.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values + 0.5
        # print(mol.ic)
        mol.set_target_ic(target_ic)
        # print(mol.ic[0].value - mol.ic[0].target)
        cost_v = mol._compute_tfm_cost()
        cost_g = mol._compute_tfm_gradient()
        diff = 1e-4
        # assert_allclose(cost_v, (2 - 2.47617635) ** 2)
        # finite diff test
        for i in range(8):
            for j in range(3):
                coor = ref_mol.coordinates.copy()
                coor[i][j] += diff
                mol.set_new_coordinates(coor)
                cost_v_2 = mol._compute_tfm_cost()
                fd = (cost_v_2 - cost_v) / 1e-4
                assert_allclose(fd, cost_g[3 * i + j], atol=4e-2)

    def test_cost_hessian_bond(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.add_bond(0, 1)
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values + 0.5
        # print(mol.ic)
        mol.set_target_ic(target_ic)
        # print(mol.ic[0].value - mol.ic[0].target)
        # cost_v = mol._compute_tfm_cost()
        cost_g = mol._compute_tfm_gradient()
        cost_h = mol._compute_tfm_hessian()
        diff = 1e-4

        for j in range(4):
            for i in range(3):
                coor = ref_mol.coordinates.copy()
                coor[j, i] += diff
                mol.set_new_coordinates(coor)
                cost_g_2 = mol._compute_tfm_gradient()
                fd = (cost_g_2 - cost_g) / 1e-4
                assert_allclose(fd, cost_h[3 * j + i], atol=4e-4)

    def test_cost_hessian_angle(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.add_bond(0, 1)
        mol.add_bond(0, 2)
        mol.add_angle(1, 0, 2)
        # print(mol.b_matrix)
        # print(mol.ic)
        # assert False
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values + 0.5
        # print(mol.ic)
        mol.set_target_ic(target_ic)
        cost_g = mol._compute_tfm_gradient()
        cost_h = mol._compute_tfm_hessian()
        diff = 1e-4

        for j in range(4):
            for i in range(3):
                coor = ref_mol.coordinates.copy()
                coor[j, i] += diff
                mol.set_new_coordinates(coor)
                cost_g_2 = mol._compute_tfm_gradient()
                fd = (cost_g_2 - cost_g) / 1e-4
                assert_allclose(fd, cost_h[j * 3 + i], atol=4e-4)

    def test_cost_hessian_dihed(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values + 0.5
        mol.set_target_ic(target_ic)
        cost_g = mol._compute_tfm_gradient()
        cost_h = mol._compute_tfm_hessian()
        diff = 1e-4

        for j in range(4):
            for i in range(3):
                coor = ref_mol.coordinates.copy()
                coor[j, i] += diff
                mol.set_new_coordinates(coor)
                cost_g_2 = mol._compute_tfm_gradient()
                fd = (cost_g_2 - cost_g) / 1e-4
                assert_allclose(fd, cost_h[j * 3 + i], atol=4e-2)

    def test_cost_hessian_cmpl(self):
        with path("saddle.test.data", "methanol.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        ref_mol = deepcopy(mol)
        coor = mol.coordinates.copy()
        target_ic = mol.ic_values + 0.5
        mol.set_target_ic(target_ic)
        cost_g = mol._compute_tfm_gradient()
        cost_h = mol._compute_tfm_hessian()
        diff = 1e-4

        for j in range(6):
            for i in range(3):
                coor = ref_mol.coordinates.copy()
                coor[j, i] += diff
                mol.set_new_coordinates(coor)
                cost_g_2 = mol._compute_tfm_gradient()
                fd = (cost_g_2 - cost_g) / 1e-4
                assert_allclose(fd, cost_h[j * 3 + i], atol=4e-2)

    def test_scipy_opt_tfm(self):
        with path("saddle.test.data", "h2o2.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        mol.auto_select_ic()
        target_ic = mol.ic_values
        target_ic[0] = 2
        target_ic[3] = 2
        target_ic[5] = 2
        mol.set_target_ic(target_ic)
        mol.converge_to_target_ic()
        np.allclose(mol.ic_values[0], 2, atol=1e-4)
        np.allclose(mol.ic_values[3], 2, atol=1e-4)
        np.allclose(mol.ic_values[5], 2, atol=1e-4)

    def test_scipy_opt_tfm_cmpx(self):
        with path("saddle.test.data", "ethane.xyz") as mol_path:
            mol = Internal.from_file(mol_path)
        # conventional dihedral
        mol.auto_select_ic()
        target_ic = mol.ic_values
        target_ic[-1] = -1
        mol.set_target_ic(target_ic)
        # print(mol.ic_values)
        mol.converge_to_target_ic()
        x_gradient = mol._compute_tfm_gradient()
        assert np.max(np.abs(x_gradient)) < 1e-4
Example #3
0
 def test_ic_ric_transform(self):
     with path("saddle.test.data", "water.xyz") as mol_path:
         mol = Utils.load_file(mol_path)
     ri_mol = Internal(mol.coordinates, mol.numbers, 0, 1)
     ri_mol.add_bond(1, 0)
     ri_mol.add_bond(1, 2)
     ri_mol.add_bond(0, 2)
     ri_mol.add_angle(0, 1, 2)
     ri_mol.add_angle(1, 0, 2)
     vc_ref = np.array([1.81413724, 1.81413724, 2.96247453, 1.91063401, 0.61547931])
     assert np.allclose(ri_mol.ic_values, vc_ref)
     ri_mol = ReducedInternal.update_to_reduced_internal(ri_mol)
     assert isinstance(ri_mol, ReducedInternal)
     ri_mol.set_key_ic_number(2)
     ri_mol.select_key_ic(0, 2)
     print(ri_mol.vspace)
     vp_ref = np.array(
         [
             [4.40930006e-01, -7.79280781e-01, 6.12072474e-17],
             [-5.61408260e-01, -6.12047068e-01, -3.33066907e-16],
             [-4.57920570e-01, -3.28254718e-02, -7.16200549e-01],
             [-5.22760813e-01, 4.87258745e-02, 5.58315734e-01],
             [8.62054537e-02, 1.21112047e-01, -4.18736570e-01],
         ]
     )
     for i in range(vp_ref.shape[1]):
         assert np.allclose(ri_mol.vspace[:, i], vp_ref[:, i]) or np.allclose(
             ri_mol.vspace[:, i], -1 * vp_ref[:, i]
         )
     ri_mol.set_key_ic_number(1)
     assert ri_mol._red_space is None
     assert ri_mol._non_red_space is None
     ri_mol.set_key_ic_number(2)
     for i in range(vp_ref.shape[1]):
         assert np.allclose(ri_mol.vspace[:, i], vp_ref[:, i]) or np.allclose(
             ri_mol.vspace[:, i], -1 * vp_ref[:, i]
         )
     new_coor = np.array(
         [
             [1.40, -0.93019123, -0.0],
             [-0.0, 0.11720081, -0.0],
             [-1.40, -0.93019123, -0.0],
         ]
     )
     ri_mol.set_new_coordinates(new_coor)
     ref_ic = [
         1.7484364736491811,
         2.8,
         1.7484364736491811,
         1.8569769819,
         0.6423078258,
     ]
     assert np.allclose(ri_mol.ic_values, ref_ic)
     ri_mol.vspace
     assert ri_mol._red_space is not None
     assert ri_mol._non_red_space is not None
     print(ri_mol._red_space)
     ri_mol.add_angle(0, 2, 1)
     print(ri_mol._red_space)
     assert ri_mol._red_space is None
     assert ri_mol._non_red_space is None
Example #4
0
class Test_TS_Construct(unittest.TestCase):

    file_list = []

    def setUp(self):
        with path("saddle.test.data", "ch3_hf.xyz") as rct_path:
            self.rct = Utils.load_file(rct_path)
        with path("saddle.test.data", "ch3f_h.xyz") as prd_path:
            self.prd = Utils.load_file(prd_path)

        self.reactant_ic = Internal(self.rct.coordinates, self.rct.numbers, 0,
                                    2)
        self.product_ic = Internal(self.prd.coordinates, self.prd.numbers, 0,
                                   2)

    def test_auto_internal(self):
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        assert isinstance(ts_ins.reactant, Internal)
        assert isinstance(ts_ins.product, Internal)
        ts_ins.auto_select_ic()
        assert len(ts_ins.reactant.ic) == len(ts_ins.product.ic)
        self.reactant_ic.auto_select_ic()
        print(ts_ins.reactant.ic)
        print(self.reactant_ic.ic)
        # self.reactant_ic.add_bond(0, 4)
        # self.reactant_ic.add_angle(1, 0, 4)
        # self.reactant_ic.add_angle(2, 0, 4)
        # assert len(self.reactant_ic.ic) != len(ts_ins.reactant.ic)
        # self.reactant_ic.add_angle(3, 0, 4)
        assert len(ts_ins.reactant.ic_values) - len(
            self.reactant_ic.ic_values) == 11

    def test_auto_ic_create(self):
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        ts_ins.auto_select_ic()
        ref_ic_rct = np.array([
            2.02762919,
            2.02769736,
            2.02761705,
            1.77505755,
            4.27707385,
            4.87406146,
            2.08356856,
            2.08391343,
            1.64995596,
            2.08364916,
            1.64984524,
            1.64881837,
            1.06512165,
            0.427652638,
            3.14154596,
            2.71390135,
            0.594853893,
            -1.70630517,
            1.70613580,
            -3.14152957,
            2.09455878,
            -2.09427619,
            -2.87079827,
            6.05213140,
            1.64996828,
            1.64984426,
            1.64880703,
            1.36936807e-05,
            3.29954545e-05,
            -0.452180460,
            1.64217144,
            -2.54673936,
            2.68941267,
            -1.49942229,
        ])
        ref_ic_prd = np.array([
            2.03992597,
            2.03991419,
            2.03976417,
            5.52444423,
            8.17667938,
            9.06322941,
            1.91251903,
            1.9119936,
            1.92886636,
            1.91202283,
            1.88746552,
            1.91077332,
            1.01701674,
            0.2138026,
            0.01152089,
            0.2133746,
            -1.50710794,
            -2.11774407,
            2.06704189,
            0.05432083,
            2.10752341,
            -2.0822473,
            -2.09807877,
            2.6533652,
            1.90903961,
            1.90907132,
            1.90914538,
            0.02398886,
            3.1060829,
            -2.54607887,
            -0.4513039,
            1.6429288,
            0.60041547,
            2.69383007,
        ])
        print(ts_ins.reactant.ic_values, "r")
        print(ts_ins.product.ic_values, "p")
        assert np.allclose(ts_ins.reactant.ic_values, ref_ic_rct)
        assert np.allclose(ts_ins.product.ic_values, ref_ic_prd)

    def test_ts_construct(self):
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        ts_ins.auto_select_ic()
        ts_ins.create_ts_state(start_with="product", flex_sin=False)
        result = deepcopy(ts_ins.ts)
        ts_ins.create_ts_state(start_with="reactant", flex_sin=False)
        result_2 = deepcopy(ts_ins.ts)
        # print result_2.ic_values
        ref_tar_ic = ts_ins._reactant.ic_values * 0.5 + ts_ins._product.ic_values * 0.5
        assert np.allclose(ref_tar_ic, result.target_ic)
        assert np.allclose(result.target_ic, result_2.target_ic)
        # assert np.allclose(
        #     result.ic_values[:4], result.target_ic[:4], atol=1e-6)
        # TODO: need to check structure
        # assert np.allclose(
        #     result_2.ic_values[:4], result_2.target_ic[:4], atol=1e-6)
        assert_allclose(result.ic_values[:16],
                        result_2.ic_values[:16],
                        atol=1e-3)
        ts_ins.select_key_ic(1)
        assert ts_ins.key_ic_counter == 1
        assert np.allclose(ts_ins.ts.ic_values[:2][::-1],
                           result_2.ic_values[:2])
        assert np.allclose(ts_ins.ts._cc_to_ic_gradient[1],
                           result_2._cc_to_ic_gradient[0])

    def test_ts_union(self):
        self.reactant_ic.add_bond(0, 1)
        self.reactant_ic.add_bond(1, 2)
        self.reactant_ic.add_angle(0, 1, 2)
        self.product_ic.add_bond(1, 0)
        self.product_ic.add_bond(0, 2)
        self.product_ic.add_angle(1, 0, 2)
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        union_ic = ts_ins._get_union_of_ics()
        assert len(union_ic) == 5

    def test_ts_union_reactant(self):
        self.reactant_ic.add_bond(0, 1)
        self.reactant_ic.add_bond(1, 2)
        self.reactant_ic.add_angle(0, 1, 2)
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        union_ic = ts_ins._get_union_of_ics(mode="reactant")
        assert len(union_ic) == 3
        ts_ins.auto_select_ic(auto_select=False, mode="reactant")
        assert len(ts_ins.product.ic) == 3

    def test_ts_union_product(self):
        self.product_ic.add_bond(1, 0)
        self.product_ic.add_bond(0, 2)
        self.product_ic.add_angle(1, 0, 2)
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        union_ic = ts_ins._get_union_of_ics(mode="product")
        assert len(union_ic) == 3
        ts_ins.auto_select_ic(auto_select=False, mode="product")
        assert len(ts_ins.reactant.ic) == 3
        flag = 1
        try:
            ts_ins.auto_select_ic(auto_select=False, mode="wrong")
        except InvalidArgumentError:
            flag = 0
        assert flag == 0

    def test_ts_create(self):
        ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
        ts_ins.auto_select_ic()
        ts_ins.create_ts_state(start_with="reactant")
        ts_ins.select_key_ic(3, 4)
        assert isinstance(ts_ins.ts.ic[0], type(ts_ins.product.ic[3]))
        assert isinstance(ts_ins.product.ic[3], type(ts_ins.ts.ic[0]))
        assert isinstance(ts_ins.ts.ic[1], type(ts_ins.product.ic[4]))
        assert isinstance(ts_ins.product.ic[4], type(ts_ins.ts.ic[1]))
        assert ts_ins.ts.key_ic_number == 2
        new_ins = TSConstruct(self.reactant_ic, self.product_ic)
        assert new_ins is not ts_ins
        new_ins.auto_generate_ts()
        new_ins.select_key_ic(3, 4)
        assert np.allclose(new_ins.ts.ic_values, ts_ins.ts.ic_values)
        assert isinstance(new_ins.ts, ReducedInternal)

    def test_ts_combine(self):  # maybe a problem
        self.reactant_ic.auto_select_ic()
        self.product_ic.auto_select_ic()
        new_ins = TSConstruct(self.reactant_ic, self.product_ic)
        new_ins.auto_generate_ts(start_with="product", reset_ic=False)
        # test gradient
        assert all(np.abs(new_ins.ts._compute_tfm_gradient()) < 3e-4)
        # test hessian eigenvalues
        e_v = np.linalg.eigh(new_ins.ts._compute_tfm_hessian())[0]
        assert all(e_v[np.abs(e_v) > 1e-4] > 0)

    def test_choices_auto_select_ic(self):
        self.reactant_ic.add_bond(2, 4)
        new_ins = TSConstruct(self.reactant_ic, self.product_ic)
        new_ins.auto_generate_ts(auto_select=False)
        print("rct", self.reactant_ic.ic)
        print("prd", self.product_ic.ic)
        ref_ic = (self.reactant_ic.distance(2, 4) +
                  self.product_ic.distance(2, 4)) / 2
        assert np.allclose(new_ins.ts.ic_values, ref_ic)
        new_ins = TSConstruct(self.reactant_ic, self.product_ic)
        print("rct", new_ins.reactant.ic)
        print("prd", new_ins.product.ic)
        new_ins.auto_generate_ts(auto_select=True,
                                 reset_ic=False,
                                 flex_sin=False)
        # print('rct', new_ins.reactant.ic)
        # print('prd', new_ins.product.ic)
        print("ts", new_ins.ts.ic)
        print("target_ic", new_ins.ts.target_ic)
        print("ts g", new_ins.ts._compute_tfm_gradient())
        # print('ts g', new_ins.)
        # with deepcopy 31, no deepcopy 44
        assert len(new_ins.ts.ic) == 31
        # TODO: need to be reviewed
        # print(new_ins.ts.ic)
        print(new_ins.ts.tf_cost)
        assert_allclose(new_ins.ts.ic_values[0],
                        new_ins.ts.target_ic[0],
                        atol=2e-2)
        assert_allclose(new_ins.ts.ic_values[1:4],
                        new_ins.ts.target_ic[1:4],
                        atol=2e-2)
        new_ins = TSConstruct(self.reactant_ic, self.product_ic)
        new_ins.auto_generate_ts(auto_select=True, reset_ic=True)
        assert all(abs(new_ins.ts._compute_tfm_gradient()) < 3e-4)

    # def test_from_file_and_to_file(self):
    #     with path('saddle.test.data', 'ch3_hf.xyz') as rct_p:
    #         with path('saddle.test.data', 'ch3f_h.xyz') as prd_p:
    #             ts = TSConstruct.from_file(rct_p, prd_p)
    #     ts_ins = TSConstruct(self.reactant_ic, self.product_ic)
    #     ts.auto_generate_ts()
    #     ts_ins.auto_generate_ts()
    #     with path('saddle.test.data', 'ts_nose_test_cons.xyz') as filepath:
    #         ts.ts_to_file(filepath)
    #     self.file_list.append(filepath)
    #     mol = Utils.from_file(filepath)
    #     assert np.allclose(mol.coordinates, ts.ts.coordinates)

    def test_from_file_to_path(self):
        with path("saddle.test.data", "rct.xyz") as rct_path:
            with path("saddle.test.data", "prd.xyz") as prd_path:
                ts_mol = TSConstruct.from_file(rct_path, prd_path)
        ts_mol.auto_generate_ts(task="path")
        assert isinstance(ts_mol.ts, PathRI)

    def test_update_rct_prd_structure(self):
        with path("saddle.test.data", "rct.xyz") as rct_path:
            with path("saddle.test.data", "prd.xyz") as prd_path:
                ts_mol = TSConstruct.from_file(rct_path, prd_path)
        ts_mol.auto_generate_ts(task="path")
        assert len(ts_mol.ts.ic) == 9
        ts_mol.ts.auto_select_ic(keep_bond=True)
        assert len(ts_mol.ts.ic) == 12
        ts_mol.update_rct_and_prd_with_ts()
        assert len(ts_mol.rct.ic) == 12
        assert len(ts_mol.prd.ic) == 12
        for i in range(12):
            assert ts_mol.rct.ic[i].atoms == ts_mol.prd.ic[i].atoms

    def test_dihed_special_structure(self):
        with path("saddle.test.data", "rct.xyz") as rct_path:
            with path("saddle.test.data", "prd.xyz") as prd_path:
                ts_mol = TSConstruct.from_file(rct_path, prd_path)
        ts_mol.auto_generate_ts(dihed_special=True)
        assert len(ts_mol.ts.ic) == 11

    @classmethod
    def tearDownClass(cls):
        for i in cls.file_list:
            os.remove(i)