Пример #1
0
def test_uniformgrid_from_molecule_o2_uhf():
    with path('chemtools.data', 'o2_uhf.fchk') as fpath:
        mol = Molecule.from_file(str(fpath))

    # create cube file from molecule:
    cube = UniformGrid.from_molecule(mol)

    # test the cube gives the right result:
    origin_result = [-5.0, -5.0, -6.1]
    axes_result = [[0.0, 0.0, 0.2], [0.0, 0.2, 0.0], [0.2, 0.0, 0.0]]
    shape_result = [61, 50, 50]
    weight_result = np.full(cube.npoints, 0.0080)

    np.testing.assert_array_almost_equal(cube.origin, origin_result, decimal=7)
    np.testing.assert_array_almost_equal(cube.axes, axes_result, decimal=7)
    np.testing.assert_array_equal(cube.shape, shape_result)
    np.testing.assert_array_almost_equal(cube.weights(), weight_result, decimal=7)
    np.testing.assert_array_almost_equal(cube.weights(method='R0'), weight_result, decimal=7)
    np.testing.assert_array_almost_equal(cube.weights(method='R'), weight_result, decimal=7)

    # test integration of Fukui functions:

    tool = LocalConceptualDFT.from_file(str(fpath), model='linear', points=cube.points)

    ffm_default = cube.integrate(tool.ff_minus)
    ffm_r = cube.integrate(tool.ff_minus, method='R')
    ffm_r0 = cube.integrate(tool.ff_minus, method='R0')

    np.testing.assert_almost_equal(ffm_default, ffm_r, decimal=7)
    np.testing.assert_almost_equal(ffm_r, ffm_r0, decimal=7)
    np.testing.assert_almost_equal(ffm_default, 1.000, decimal=2)
    np.testing.assert_almost_equal(ffm_default, 1.000, decimal=2)
    np.testing.assert_almost_equal(ffm_default, 1.000, decimal=2)
Пример #2
0
def test_critical_point_h2o():
    # test against multiwfn 3.6 dev src
    with path("chemtools.data",
              "data_multiwfn36_fchk_h2o_q+0_ub3lyp_ccpvtz.npz") as fname:
        data = np.load(str(fname))
    nna, bcp = data["nna_coords"], data["bcp_coords"]
    # find critical points
    with path("chemtools.data", "h2o_q+0_ub3lyp_ccpvtz.fchk") as fpath:
        mol = Molecule.from_file(fpath)
    cub = UniformGrid.from_molecule(mol,
                                    spacing=0.15,
                                    extension=0.1,
                                    rotate=False)
    top = TopologicalTool.from_molecule(mol, points=cub.points)
    # check NA
    assert len(top.nna) == 3
    assert sum([np.allclose(top.nna[0].coordinate, c, rtol=0.0)
                for c in nna]) == 1
    assert sum([np.allclose(top.nna[1].coordinate, c, rtol=0.0)
                for c in nna]) == 1
    assert sum([np.allclose(top.nna[2].coordinate, c, rtol=0.0)
                for c in nna]) == 1
    # check BCP
    assert len(top.bcp) == 2
    assert sum([np.allclose(top.bcp[0].coordinate, c, rtol=0.0)
                for c in bcp]) == 1
    assert sum([np.allclose(top.bcp[1].coordinate, c, rtol=0.0)
                for c in bcp]) == 1
    # check total number of CP
    assert len(top.rcp) == 0
    assert len(top.ccp) == 0
    assert len(top.cps) == 5
    assert top.poincare_hopf_equation
Пример #3
0
    def from_molecule(cls, molecule, spin="ab", index=None, points=None):
        """Initialize class from ``Molecule`` object.

        Parameters
        ----------
        molecule : instance of `Molecule` class.
            Instance of `Molecular` class.
        spin : str, optional
            The type of occupied spin orbitals; options are "a", "b" & "ab".
        index : int or Sequence of int, optional
            Sequence of integers representing the index of spin orbitals.
            If None, all occupied spin orbitals are included.
        points : np.ndarray, optional
            Cartesian coordinates of points used for critical point search.
            If None, cubic grid points with spacing=0.1 & extension=0.1 are used.

        """
        if points is None:
            points = UniformGrid.from_molecule(molecule,
                                               spacing=0.1,
                                               extension=0.1).points
        func_dens = cls._wrapper_compute_density(molecule,
                                                 spin=spin,
                                                 index=index)
        func_grad = cls._wrapper_compute_gradient(molecule,
                                                  spin=spin,
                                                  index=index)
        func_hess = cls._wrapper_compute_hessian(molecule,
                                                 spin=spin,
                                                 index=index)
        return cls(func_dens, func_grad, func_hess, points,
                   molecule.coordinates)
Пример #4
0
    def _check_grid(molecule, grid):
        if grid is None:
            grid = UniformGrid.from_molecule(molecule, spacing=0.1, extension=2.0)
        elif not hasattr(grid, 'points'):
            raise ValueError('Argument grid should have "points" attribute!')

        return grid
Пример #5
0
def load_molecule_and_grid(fname, cube):
    """Return instances of molecule and uniform cubic grid.

    Parameters
    ----------
    fname : str
        Path to wave-function file.
    cube : str
       Uniform cubic grid specifications.

    """
    # load molecule
    mol = Molecule.from_file(fname)

    if cube.endswith(".cube"):
        # load & check cube file
        cube = UniformGrid.from_cube(cube)
        if np.allclose(mol.numbers, cube.numbers):
            raise ValueError(
                "Atomic number in {0} & {1} should be the same!".format(
                    fname, cube))
        if np.allclose(mol.coordinates, cube.coordinates):
            raise ValueError(
                "Atomic coordinates in {0} & {1} should be the same!".format(
                    cube.fname, cube.cube))
    elif len(cube.split(",")) == 2:
        # make a cubic grid
        spacing, extension = [float(item) for item in cube.split(",")]
        cube = UniformGrid.from_molecule(mol,
                                         spacing=spacing,
                                         extension=extension,
                                         rotate=True)

    else:
        raise ValueError("Argument cube={0} is not recognized!".format(cube))

    return mol, cube
Пример #6
0
    def generate_scripts(self, fname, spin='a', index=None, isosurf=0.05, grid=None):
        """Generate VMD script(s) and cube file(s) to visualize MO iso-surface of given orbitals.

        Parameters
        ----------
        fname : str
            A string representing the path to a fname of generated files.
            The VMD script and cube file will be named fname_mo{index}.vmd and
            fname_mo{index}.cube, respectively.
        spin : str, optional
           The type of occupied spin orbitals. Choose either 'a' or 'b'.
        index : int, optional
           Integer representing the index of spin orbital to visualize. Spin orbitals are each
           indexed from 1 to :attr:`nbasis`. If None, files for visualizing all orbitals are
           generated.
        isosurf : float, optional
            Value of MO iso-surface used in VMD script.
        grid : UniformGrid, optional
           Instance of UniformGrid used for computation and generating cube file(s).
           If None, a cubic grid is constructed from molecule with spacing=0.2 & extension=5.0.

        """
        if spin not in ['a', 'b']:
            raise ValueError('Argument spin can only be "a" or "b".')
        if index is not None and not isinstance(index, int):
            raise ValueError('Argument index is either None or an integer for visualization. '
                             'Given index={0}'.format(index))
        if grid is None:
            grid = UniformGrid.from_molecule(self._molecule, spacing=0.2, extension=5.0, rotate=True)
        elif not isinstance(grid, UniformGrid):
            raise ValueError('Argument grid should be a UniformGrid to generate cube files.')

        if index is None:
            spin_index = {'a': 0, 'b': 1}
            index = range(1, self._molecule.mo.homo_index[spin_index[spin]] + 1)
        else:
            index = [index]

        for mo_index in index:
            vmdname = fname + '_mo{0}.vmd'.format(mo_index)
            cubname = fname + '_mo{0}.cube'.format(mo_index)
            mo_value = self.compute_orbital_expression(grid.points, spin=spin, index=mo_index)
            grid.generate_cube(cubname, mo_value)
            print_vmd_script_isosurface(vmdname, cubname, isosurf=isosurf, negative=True,
                                        material='BlownGlass')
Пример #7
0
def test_uniformgrid_o2_raises():
    with path('chemtools.data', 'o2_uhf.fchk') as fpath:
        mol = Molecule.from_file(str(fpath))
        cube = UniformGrid.from_molecule(mol)
        tool = LocalConceptualDFT.from_file(str(fpath), model='linear', points=cube.points)
    o = np.array([-3.0, -3.0, -3.0])
    a = np.array([[2.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 2.0]])
    s = np.array([3, 3, 3])
    # check ValueError
    assert_raises(ValueError, UniformGrid, mol.numbers, mol.pseudo_numbers, mol.coordinates,
                  np.array([0.]), a, s)
    assert_raises(ValueError, UniformGrid, mol.numbers, mol.pseudo_numbers, mol.coordinates,
                  o, np.array([0.]), s)
    assert_raises(ValueError, UniformGrid, mol.numbers, mol.pseudo_numbers, mol.coordinates,
                  o, a, np.array([0.]))
    assert_raises(ValueError, UniformGrid.from_cube, 'test.wrong_end')
    assert_raises(ValueError, cube.generate_cube, 'test.wrong_end', tool.ff_minus)
    assert_raises(ValueError, cube.generate_cube, 'test.cube', np.array([0.]))
    assert_raises(ValueError, cube.weights, method='erroneous')
    assert_raises(ValueError, cube.integrate, np.array([0.]))
Пример #8
0
def test_uniformgrid_points_h2o():
    # replace this test with a better one later
    with path('chemtools.data', 'h2o_dimer_pbe_sto3g.fchk') as fpath:
        cube = UniformGrid.from_file(fpath, spacing=2.0, extension=0.0, rotate=True)
    expected = np.array([[-2.31329824e+00, -2.00000000e+00, 3.82735565e+00],
                         [-2.31329824e+00, -4.99999997e-09, 3.82735565e+00],
                         [-3.19696330e-01, -2.00000000e+00, 3.98720381e+00],
                         [-3.19696330e-01, -4.99999997e-09, 3.98720381e+00],
                         [-2.15345008e+00, -2.00000000e+00, 1.83375375e+00],
                         [-2.15345008e+00, -4.99999997e-09, 1.83375375e+00],
                         [-1.59848169e-01, -2.00000000e+00, 1.99360191e+00],
                         [-1.59848169e-01, -4.99999997e-09, 1.99360191e+00],
                         [-1.99360191e+00, -2.00000000e+00, -1.59848162e-01],
                         [-1.99360191e+00, -4.99999997e-09, -1.59848162e-01],
                         [-6.77400003e-09, -2.00000000e+00, 0.00000000e+00],
                         [-6.77400003e-09, -4.99999997e-09, 0.00000000e+00],
                         [-1.83375375e+00, -2.00000000e+00, -2.15345007e+00],
                         [-1.83375375e+00, -4.99999997e-09, -2.15345007e+00],
                         [ 1.59848155e-01, -2.00000000e+00, -1.99360191e+00],
                         [ 1.59848155e-01, -4.99999997e-09, -1.99360191e+00]])
    assert_allclose(cube.points, expected, rtol=1.e-7, atol=1.e-7)
Пример #9
0
def test_cube_h2o_dimer():
    # test against previous generated .cube files
    with path('chemtools.data', 'h2o_dimer_pbe_sto3g-dens.cube') as file_path:
        cube = UniformGrid.from_cube(file_path)
        mol1 = Molecule.from_file(str(file_path))

    with tmpdir('chemtools.test.test_base.test_cube_h2o_dimer') as dn:
        cube2 = '%s/%s' % (dn, 'h2o_dimer_pbe_sto3g-dens.cube')
        cube.generate_cube(cube2, mol1.cube_data)
        cube2 = '%s/%s' % (dn, 'h2o_dimer_pbe_sto3g-dens.cube')
        mol2 = Molecule.from_file(cube2)
        # Check coordinates
        np.testing.assert_array_almost_equal(mol1.coordinates, mol2.coordinates, decimal=6)
        np.testing.assert_equal(mol1.numbers, mol2.numbers)
        # Check grid data
        ugrid1 = mol1.grid
        ugrid2 = mol2.grid
        np.testing.assert_array_almost_equal(ugrid1.grid_rvecs, ugrid2.grid_rvecs, decimal=6)
        np.testing.assert_equal(ugrid1.shape, ugrid2.shape)
        data1 = mol1.cube_data / mol1.cube_data
        data2 = mol2.cube_data / mol1.cube_data
        np.testing.assert_array_almost_equal(data1, data2, decimal=4)
        np.testing.assert_equal(mol1.pseudo_numbers, mol2.pseudo_numbers)
Пример #10
0
def test_uniformgrid_from_file_o2_uhf():
    with path('chemtools.data', 'o2_uhf.fchk') as fpath:
        mol = Molecule.from_file(str(fpath))

    # create cube file from file:
    cube = UniformGrid.from_file(fpath, spacing=0.5, extension=6.0, rotate=False)

    # test the cube gives the right result:
    origin_result = [-6.0, -6.0, -7.25]
    axes_result = [[0.5, 0.0, 0.0],
                   [0.0, 0.5, 0.0],
                   [0.0, 0.0, 0.5]]
    shape_result = [24, 24, 29]
    weight_result = np.full(cube.npoints, 0.125)

    np.testing.assert_array_almost_equal(cube.origin, origin_result, decimal=7)
    np.testing.assert_array_almost_equal(cube.axes, axes_result, decimal=7)
    np.testing.assert_array_equal(cube.shape, shape_result)
    np.testing.assert_array_equal(cube.numbers, mol.numbers)
    np.testing.assert_array_almost_equal(cube.coordinates, mol.coordinates, decimal=10)
    np.testing.assert_array_almost_equal(cube.pseudo_numbers, mol.pseudo_numbers, decimal=10)
    np.testing.assert_array_almost_equal(cube.weights(), weight_result, decimal=7)
    np.testing.assert_array_almost_equal(cube.weights(method='R0'), weight_result, decimal=7)
    np.testing.assert_array_almost_equal(cube.weights(method='R'), weight_result, decimal=7)
Пример #11
0
def test_critical_point_c4h4():
    # test against multiwfn 3.6 dev src
    with path("chemtools.data",
              "data_multiwfn36_fchk_c4h4_ub3lyp_ccpvdz.npz") as fname:
        data = np.load(str(fname))
        nna, bcp = data["nna_coords"], data["bcp_coords"]
        rcp, ccp = data["rcp_coords"], data["ccp_coords"]
    # find critical points
    with path("chemtools.data", "c4h4_ub3lyp_ccpvdz.fchk") as fpath:
        mol = Molecule.from_file(fpath)
    cub = UniformGrid.from_molecule(mol,
                                    spacing=0.25,
                                    extension=0.1,
                                    rotate=False)
    top = TopologicalTool.from_molecule(mol, points=cub.points)
    # check NA
    assert len(top.nna) == 8
    assert sum([
        np.allclose(top.nna[0].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[1].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[2].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[3].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[4].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[5].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[6].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    assert sum([
        np.allclose(top.nna[7].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in nna
    ]) == 1
    # check BCP
    assert len(top.bcp) == 10
    assert sum([
        np.allclose(top.bcp[0].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[2].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[3].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[4].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[5].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[6].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[7].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[8].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    assert sum([
        np.allclose(top.bcp[9].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in bcp
    ]) == 1
    # check RCP
    assert len(top.rcp) == 4
    assert sum([
        np.allclose(top.rcp[0].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in rcp
    ]) == 1
    assert sum([
        np.allclose(top.rcp[1].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in rcp
    ]) == 1
    assert sum([
        np.allclose(top.rcp[2].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in rcp
    ]) == 1
    assert sum([
        np.allclose(top.rcp[3].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in rcp
    ]) == 1
    # check CCP
    assert len(top.ccp) == 1
    assert sum([
        np.allclose(top.ccp[0].coordinate, c, rtol=0.0, atol=1.0e-5)
        for c in ccp
    ]) == 1
    # check total number of CP
    assert len(top.cps) == 23
    assert top.poincare_hopf_equation