Beispiel #1
0
def test_evaluate_basis_spherical():
    """Test gbasis.evals.eval.evaluate_basis_spherical."""
    basis_dict = parse_nwchem(find_datafile("data_sto6g.nwchem"))

    # cartesian and spherical are the same for s orbital
    basis = make_contractions(basis_dict, ["H"], np.array([[0, 0, 0]]))
    evaluate_obj = Eval(basis)
    assert np.allclose(
        evaluate_obj.construct_array_cartesian(points=np.array([[0, 0, 0]])),
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type="spherical"),
    )
    # p orbitals are zero at center
    basis = make_contractions(basis_dict, ["Li"], np.array([[0, 0, 0]]))
    evaluate_obj = Eval(basis)
    assert np.allclose(
        evaluate_obj.construct_array_cartesian(points=np.array([[0, 0, 0]])),
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type="spherical"),
    )

    basis = make_contractions(basis_dict, ["Kr"], np.array([[0, 0, 0]]))
    evaluate_obj = Eval(basis)
    assert np.allclose(
        evaluate_obj.construct_array_spherical(points=np.array([[1, 1, 1]])),
        evaluate_basis(basis, np.array([[1, 1, 1]]), coord_type="spherical"),
    )
Beispiel #2
0
def test_evaluate_basis_mix():
    """Test gbasis.evals.eval.evaluate_basis_mix."""
    basis_dict = parse_nwchem(find_datafile("data_sto6g.nwchem"))

    # cartesian and spherical are the same for s orbital
    basis = make_contractions(basis_dict, ["H"], np.array([[0, 0, 0]]))
    assert np.allclose(
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type="spherical"),
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type=["spherical"]),
    )
    assert np.allclose(
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type="cartesian"),
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type=["cartesian"]),
    )

    basis = make_contractions(basis_dict, ["Kr"], np.array([[0, 0, 0]]))
    assert np.allclose(
        evaluate_basis(basis, np.array([[1, 1, 1]]), coord_type="spherical"),
        evaluate_basis(basis,
                       np.array([[1, 1, 1]]),
                       coord_type=["spherical"] * 8),
    )
    assert np.allclose(
        evaluate_basis(basis, np.array([[1, 1, 1]]), coord_type="cartesian"),
        evaluate_basis(basis,
                       np.array([[1, 1, 1]]),
                       coord_type=["cartesian"] * 8),
    )
Beispiel #3
0
def test_evaluate_basis_cartesian():
    """Test gbasis.evals.eval.evaluate_basis_cartesian."""
    basis_dict = parse_nwchem(find_datafile("data_sto6g.nwchem"))
    basis = make_contractions(basis_dict, ["H"], np.array([[0, 0, 0]]))
    evaluate_obj = Eval(basis)
    assert np.allclose(
        evaluate_obj.construct_array_cartesian(points=np.array([[0, 0, 0]])),
        evaluate_basis(basis, np.array([[0, 0, 0]]), coord_type="cartesian"),
    )
Beispiel #4
0
def test_evaluate_basis_horton():
    """Test gbasis.evals.eval.evaluate_basis against horton results."""
    basis_dict = parse_nwchem(find_datafile("data_anorcc.nwchem"))
    points = np.array([[0, 0, 0], [0.8, 0, 0]])
    basis = make_contractions(basis_dict, ["H", "He"], points)
    basis = [
        HortonContractions(i.angmom, i.coord, i.coeffs, i.exps) for i in basis
    ]

    horton_eval_cart = np.load(find_datafile("data_horton_hhe_cart_eval.npy"))
    horton_eval_sph = np.load(find_datafile("data_horton_hhe_sph_eval.npy"))

    grid_1d = np.linspace(-2, 2, num=5)
    grid_x, grid_y, grid_z = np.meshgrid(grid_1d, grid_1d, grid_1d)
    grid_3d = np.vstack([grid_x.ravel(), grid_y.ravel(), grid_z.ravel()]).T

    assert np.allclose(evaluate_basis(basis, grid_3d, coord_type="cartesian"),
                       horton_eval_cart.T)
    assert np.allclose(evaluate_basis(basis, grid_3d, coord_type="spherical"),
                       horton_eval_sph.T)
Beispiel #5
0
def test_evaluate_density():
    """Test gbasis.evals.density.evaluate_density."""
    basis_dict = parse_nwchem(find_datafile("data_sto6g.nwchem"))
    basis = make_contractions(basis_dict, ["Kr"], np.array([[0, 0, 0]]))
    transform = np.random.rand(14, 18)
    density = np.random.rand(14, 14)
    density += density.T
    points = np.random.rand(10, 3)

    evaluate_orbs = evaluate_basis(basis, points, transform)
    assert np.allclose(
        evaluate_density(density, basis, points, transform),
        np.einsum("ij,ik,jk->k", density, evaluate_orbs, evaluate_orbs),
    )
Beispiel #6
0
def test_evaluate_basis_pyscf_cart_norm():
    """Test gbasis.evals.eval.evaluate_basis against pyscf results.

    These cases fail because pyscf seems to have a different normalization constant for the d and f
    orbitals.

    """
    pytest.importorskip("pyscf")

    from pyscf import gto
    from gbasis.wrappers import from_pyscf

    mol = gto.Mole()
    mol.build(atom="H 0 0 0; He 0.8 0 0", basis="ano-rcc", spin=1)
    basis = from_pyscf(mol)

    grid_1d = np.linspace(-2, 2, num=5)
    grid_x, grid_y, grid_z = np.meshgrid(grid_1d, grid_1d, grid_1d)
    grid_3d = np.vstack([grid_x.ravel(), grid_y.ravel(), grid_z.ravel()]).T

    pyscf_eval_cart = gto.eval_gto(mol, "GTOval_cart", grid_3d)

    # d orbitals are all off by some scalar factor
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[18:36],
        pyscf_eval_cart.T[18:36])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[65:83],
        pyscf_eval_cart.T[65:83])
    # f orbitals are all off by some scalar factor
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[36:46],
        pyscf_eval_cart.T[36:46])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[83:103],
        pyscf_eval_cart.T[83:103])
Beispiel #7
0
def test_evaluate_basis_lincomb():
    """Test gbasis.evals.eval.evaluate_basis_lincomb."""
    basis_dict = parse_nwchem(find_datafile("data_sto6g.nwchem"))
    basis = make_contractions(basis_dict, ["Kr"], np.array([[0, 0, 0]]))
    evaluate_obj = Eval(basis)
    transform = np.random.rand(14, 18)
    assert np.allclose(
        evaluate_obj.construct_array_lincomb(transform,
                                             "spherical",
                                             points=np.array([[1, 1, 1]])),
        evaluate_basis(basis,
                       np.array([[1, 1, 1]]),
                       transform=transform,
                       coord_type="spherical"),
    )
Beispiel #8
0
def test_evaluate_density_gradient():
    """Test gbasis.evals.density.evaluate_density_gradient."""
    basis_dict = parse_nwchem(find_datafile("data_sto6g.nwchem"))
    basis = make_contractions(basis_dict, ["Kr"], np.array([[0, 0, 0]]))
    transform = np.random.rand(14, 18)
    density = np.random.rand(14, 14)
    density += density.T
    points = np.random.rand(10, 3)

    np.allclose(
        evaluate_density_gradient(density, basis, points, transform).T,
        np.array([
            np.einsum(
                "ij,ik,jk->k",
                density,
                evaluate_deriv_basis(basis, points, np.array([1, 0, 0]),
                                     transform),
                evaluate_basis(basis, points, transform),
            ) + np.einsum(
                "ij,ik,jk->k",
                density,
                evaluate_basis(basis, points, transform),
                evaluate_deriv_basis(basis, points, np.array([1, 0, 0]),
                                     transform),
            ),
            np.einsum(
                "ij,ik,jk->k",
                density,
                evaluate_deriv_basis(basis, points, np.array([0, 1, 0]),
                                     transform),
                evaluate_basis(basis, points, transform),
            ) + np.einsum(
                "ij,ik,jk->k",
                density,
                evaluate_basis(basis, points, transform),
                evaluate_deriv_basis(basis, points, np.array([0, 1, 0]),
                                     transform),
            ),
            np.einsum(
                "ij,ik,jk->k",
                density,
                evaluate_deriv_basis(basis, points, np.array([0, 0, 1]),
                                     transform),
                evaluate_basis(basis, points, transform),
            ) + np.einsum(
                "ij,ik,jk->k",
                density,
                evaluate_basis(basis, points, transform),
                evaluate_deriv_basis(basis, points, np.array([0, 0, 1]),
                                     transform),
            ),
        ]),
    )
Beispiel #9
0
def evaluate_density(one_density_matrix,
                     basis,
                     points,
                     transform=None,
                     coord_type="spherical"):
    r"""Return the density of the given basis set at the given points.

    Parameters
    ----------
    one_density_matrix : np.ndarray(K_orbs, K_orbs)
        One-electron density matrix in terms of the given basis set.
        If the basis is transformed using `transform` keyword, then the density matrix is assumed to
        be expressed with respect to the transformed basis set.
    basis : list/tuple of GeneralizedContractionShell
        Shells of generalized contractions.
    points : np.ndarray(N, 3)
        Cartesian coordinates of the points in space (in atomic units) where the basis functions
        are evaluated.
        Rows correspond to the points and columns correspond to the :math:`x, y, \text{and} z`
        components.
    transform : np.ndarray(K_orbs, K_cont)
        Transformation matrix from the basis set in the given coordinate system (e.g. AO) to linear
        combinations of contractions (e.g. MO).
        Transformation is applied to the left, i.e. the sum is over the index 1 of `transform`
        and index 0 of the array for contractions.
        Default is no transformation.
    coord_type : {"cartesian", list/tuple of "cartesian" or "spherical", "spherical"}
        Types of the coordinate system for the contractions.
        If "cartesian", then all of the contractions are treated as Cartesian contractions.
        If "spherical", then all of the contractions are treated as spherical contractions.
        If list/tuple, then each entry must be a "cartesian" or "spherical" to specify the
        coordinate type of each `GeneralizedContractionShell` instance.
        Default value is "spherical".

    Returns
    -------
    density : np.ndarray(N,)
        Density evaluated at `N` grid points.

    """
    orb_eval = evaluate_basis(basis,
                              points,
                              transform=transform,
                              coord_type=coord_type)
    return evaluate_density_using_evaluated_orbs(one_density_matrix, orb_eval)
Beispiel #10
0
b_density_values = evaluate_density(b_dm,
                                    basis,
                                    molgrid.points,
                                    coord_type="cartesian")
inp = {"rho": np.array([a_density_values, b_density_values])}
inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2)
f_xc_values = (xc_function.compute(inp, None, False, False, True,
                                   False))["v2rho2"]
f_xc_values = np.array([
    f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0],
    f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1],
    f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2],
])
del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp)
MO_values = evaluate_basis(basis,
                           molgrid.points,
                           transform=molecule.mo.coeffs.T,
                           coord_type="cartesian")
MO_values_conjugated = np.conjugate(MO_values)
occupied_ind = [[], []]
virtual_ind = [[], []]
for i in range(len(molecule.mo.occsa)):
    if molecule.mo.occsa[i] - 1 == 0:
        occupied_ind[0] = occupied_ind[0] + [i]
    if molecule.mo.occsa[i] == 0:
        virtual_ind[0] = virtual_ind[0] + [i]
for i in range(len(molecule.mo.occsb)):
    if molecule.mo.occsb[i] - 1 == 0:
        occupied_ind[1] = occupied_ind[1] + [i + molecule.mo.nbasis]
    if molecule.mo.occsb[i] == 0:
        virtual_ind[1] = virtual_ind[1] + [i + molecule.mo.nbasis]
indices = (occupied_ind, virtual_ind)
    def evaluate_linear_response(self, r1, r2, spin):
        """Return linear response matrices

        Parameters
        ----------
        spin: tuple of two str,
            elements can only be 'alpha' or 'beta'
        r1: ndarray
            N1 coordinates
        r2: ndarray
            N2 coordiantes

        Return
        ------
        linear_response: np.ndarray of shape [N1, N2]"""
        if not isinstance(spin, tuple):
            raise TypeError(
                """'spin' must be a tuple of two str, being either 'alpha' or 'beta'"""
            )
        if len(spin) != 2:
            raise ValueError(
                """'spin' must be a tuple of two str, being either 'alpha' or 'beta'"""
            )
        if not spin[0] in ["alpha", "beta"]:
            raise ValueError(
                """'spin' must be a tuple of two str, being either 'alpha' or 'beta'"""
            )
        if not spin[1] in ["alpha", "beta"]:
            raise ValueError(
                """'spin' must be a tuple of two str, being either 'alpha' or 'beta'"""
            )
        if not isinstance(r1, np.ndarray):
            raise TypeError("""'r1' must be a np.ndarray""")
        if len(r1.shape) != 2:
            raise ValueError("""'r1' must be a np.ndarray with shape (N, 3)""")
        if r1.shape[1] != 3:
            raise ValueError("""'r1' must be a np.ndarray with shape (N, 3)""")
        if not isinstance(r2, np.ndarray):
            raise TypeError("""'r2' must be a np.ndarray""")
        if len(r2.shape) != 2:
            raise ValueError("""'r2' must be a np.ndarray with shape (N, 3)""")
        if r2.shape[1] != 3:
            raise ValueError("""'r2' must be a np.ndarray with shape (N, 3)""")
        indices = self.K_indices()
        MO_r1 = evaluate_basis(
            self._basis,
            r1,
            transform=self._molecule.mo.coeffs.T,
            coord_type=self._coord_type,
        )
        MO_r2 = evaluate_basis(
            self._basis,
            r2,
            transform=self._molecule.mo.coeffs.T,
            coord_type=self._coord_type,
        )
        a_occ_r1 = MO_r1[indices[0][0]]
        a_occ_r2 = MO_r2[indices[0][0]]
        b_occ_r1 = MO_r1[indices[0][1]]
        b_occ_r2 = MO_r2[indices[0][1]]
        a_virt_r1 = MO_r1[indices[1][0]]
        a_virt_r2 = MO_r2[indices[1][0]]
        b_virt_r1 = MO_r1[indices[1][1]]
        b_virt_r2 = MO_r2[indices[1][1]]
        del (MO_r1, MO_r2)
        phi_a_r1 = a_occ_r1[:, None, :] * a_virt_r1[None, :, :]
        phi_a_r1 = phi_a_r1.reshape(
            phi_a_r1.shape[0] * phi_a_r1.shape[1], phi_a_r1.shape[2]
        )
        phi_a_r2 = a_occ_r2[:, None, :] * a_virt_r2[None, :, :]
        phi_a_r2 = phi_a_r2.reshape(
            phi_a_r2.shape[0] * phi_a_r2.shape[1], phi_a_r2.shape[2]
        )
        del (a_occ_r1, a_occ_r2, a_virt_r1, a_virt_r2)
        phi_b_r1 = b_occ_r1[:, None, :] * b_virt_r1[None, :, :]
        phi_b_r1 = phi_b_r1.reshape(
            phi_b_r1.shape[0] * phi_b_r1.shape[1], phi_b_r1.shape[2]
        )
        phi_b_r2 = b_occ_r2[:, None, :] * b_virt_r2[None, :, :]
        phi_b_r2 = phi_b_r2.reshape(
            phi_b_r2.shape[0] * phi_b_r2.shape[1], phi_b_r2.shape[2]
        )
        del (b_occ_r1, b_occ_r2, b_virt_r1, b_virt_r2)
        M_inv = self.M_inverse
        if self._complex == True:
            if spin[0] == "alpha":
                if spin[1] == "alpha":
                    linear_response = (
                        np.dot(phi_a_r1.conj().T, M_inv[0, 0]).dot(phi_a_r2)
                        + np.dot(phi_a_r1.conj().T, M_inv[0, 1]).dot(phi_a_r2.conj())
                        + np.dot(phi_a_r1.T, M_inv[1, 0]).dot(phi_a_r2)
                        + np.dot(phi_a_r1.T, M_inv[1, 1]).dot(phi_a_r2.conj())
                    )
                else:
                    linear_response = (
                        np.dot(phi_a_r1.conj().T, M_inv[0, 2]).dot(phi_b_r2)
                        + np.dot(phi_a_r1.conj().T, M_inv[0, 3]).dot(phi_b_r2.conj())
                        + np.dot(phi_a_r1.T, M_inv[1, 2]).dot(phi_b_r2)
                        + np.dot(phi_a_r1.T, M_inv[1, 3]).dot(phi_b_r2.conj())
                    )
            else:
                if spin[1] == "alpha":
                    linear_response = (
                        np.dot(phi_b_r1.conj().T, M_inv[2, 0]).dot(phi_a_r2)
                        + np.dot(phi_b_r1.conj().T, M_inv[2, 1]).dot(phi_a_r2.conj())
                        + np.dot(phi_b_r1.T, M_inv[3, 0]).dot(phi_a_r2)
                        + np.dot(phi_b_r1.T, M_inv[3, 1]).dot(phi_a_r2.conj())
                    )
                else:
                    linear_response = (
                        np.dot(phi_b_r1.conj().T, M_inv[2, 2]).dot(phi_b_r2)
                        + np.dot(phi_b_r1.conj().T, M_inv[2, 3]).dot(phi_b_r2.conj())
                        + np.dot(phi_b_r1.T, M_inv[3, 2]).dot(phi_b_r2)
                        + np.dot(phi_b_r1.T, M_inv[3, 3]).dot(phi_b_r2.conj())
                    )
        else:
            if spin[0] == "alpha":
                if spin[1] == "alpha":
                    linear_response = -2 * (
                        np.dot(phi_a_r1.T, M_inv[0, 0]).dot(phi_a_r2)
                    )
                else:
                    linear_response = -2 * (
                        np.dot(phi_a_r1.T, M_inv[0, 1]).dot(phi_b_r2)
                    )
            else:
                if spin[1] == "alpha":
                    linear_response = -2 * (
                        np.dot(phi_b_r1.T, M_inv[1, 0]).dot(phi_a_r2)
                    )
                else:
                    linear_response = -2 * (
                        np.dot(phi_b_r1.T, M_inv[1, 1]).dot(phi_b_r2)
                    )
        return linear_response
Beispiel #12
0
def test_evaluate_basis_pyscf():
    """Test gbasis.evals.eval.evaluate_basis against pyscf results."""
    pytest.importorskip("pyscf")

    from pyscf import gto
    from gbasis.wrappers import from_pyscf

    mol = gto.Mole()
    mol.build(atom="H 0 0 0; He 0.8 0 0", basis="ano-rcc", spin=1)
    basis = from_pyscf(mol)

    grid_1d = np.linspace(-2, 2, num=5)
    grid_x, grid_y, grid_z = np.meshgrid(grid_1d, grid_1d, grid_1d)
    grid_3d = np.vstack([grid_x.ravel(), grid_y.ravel(), grid_z.ravel()]).T

    pyscf_eval_sph = gto.eval_gto(mol, "GTOval_sph", grid_3d)
    pyscf_eval_cart = gto.eval_gto(mol, "GTOval_cart", grid_3d)

    # s orbitals
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[:6],
        pyscf_eval_cart.T[:6])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[46:53],
        pyscf_eval_cart.T[46:53])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[:6],
        pyscf_eval_sph.T[:6])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[40:47],
        pyscf_eval_sph.T[40:47])
    # p orbitals
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[6:18],
        pyscf_eval_cart.T[6:18])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="cartesian")[53:65],
        pyscf_eval_cart.T[53:65])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[6:18],
        pyscf_eval_sph.T[6:18])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[47:59],
        pyscf_eval_sph.T[47:59])
    # d orbitals are off by some constant for the cartesian case
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[18:33],
        pyscf_eval_sph.T[18:33])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[59:74],
        pyscf_eval_sph.T[59:74])
    # f orbitals are off by some constant for the cartesian case
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[33:40],
        pyscf_eval_sph.T[33:40])
    assert np.allclose(
        evaluate_basis(basis, grid_3d, coord_type="spherical")[74:88],
        pyscf_eval_sph.T[74:88])
    def K_fxc_DFT(self,
                  molgrid,
                  Type=1,
                  XC_functional="lda_x",
                  shape="square",
                  index=None):
        """Calculate the exchange-correlation part of the coupling matrix K

        Parameters
        ----------
        molgrid : MolGrid class object (from grid package)  suitable for numerical integration
            of any real space function related to the molecule (such as the density)
        Type : int,
            1 or 2, in cassee of real molecular orbitals, type1 = type2
        XC_functionl : str
            Code name of the exchange correlation functional as given on the
            page: https://tddft.org/programs/libxc/functionals/
        shape: str; 'square', 'rectangle', 'line' or 'point', default is 'square'
            If shape == 'square', generate (K_fxc_DFT)ias,jbt
                Useful to generate the M matrices
            If shape ==  'line' ,
                generate (K_fxc_DFT)ffs,jbt
                Useful to generate the fukui matrices and hardness
            If shape == 'point'
                generate (K_fxc_DFT)ffs,ffs
                Useful to generate the hardness
        index: None or list of two list of int, default is None
            Necessary if shape == 'line' or shape ==  'point'
            If index is a list of two list of integers, it must be like [ l1, l2] with l1 in |[0; molecule.mo.nbasis|[
            and l2 in |[molecule.mo.nbasis, 2 * molecule.mo.nbasis|[, (l1 : alpha indices, l2 : beta indices)
            len(l1) + len(l2) must be equal to 1 if shape is 'line'
            len(l1) + len(l2) must be equal to 2 if shape is 'point'

        Return
        ------
        K_fxc_DFT: ndarray
            [aa_block, ab_block, ba_block, bb_block] if shape ==  'square' or 'line'

        Raises
        ------
        TypeError
            If 'molgrid' is not a 'MolGrid' instance'
            If 'Type' is not an int
            XC_functional is not a str
        ValueError
            If 'Type' is not in [1,2]
            If XC_functional is bot supported by pylibxc (see pylibxc.util.xc_available_functional_names() or https://tddft.org/programs/libxc/functionals/ for the function code spelling)
            IF XC_functional is not a LDA or a GGA"""
        if not isinstance(molgrid, MolGrid):
            raise TypeError("""'molgrid' must be a 'MolGrid' instance""")
        if not isinstance(Type, int):
            raise TypeError("""'Type' must be 1 or 2""")
        if not Type in [1, 2]:
            raise ValueError("""'Type' must be 1 or 2""")
        if not isinstance(XC_functional, str):
            raise TypeError("""'XC_functional' must be a str""")
        if not XC_functional in pylibxc.util.xc_available_functional_names():
            raise ValueError(
                """"Not suported functionnal, see pylibxc.util.xc_available_functional_names() or the webpage: https://tddft.org/programs/libxc/functionals/"""
            )
        xc_function = pylibxc.LibXCFunctional(XC_functional, "polarized")
        if not xc_function.get_family() in [1, 2]:
            raise ValueError(
                """"Not suported functionnal, only the LDA ans GGAs are supported"""
            )

        # Defining the array of values of fxc(r) suitable for the numerical integration
        a_dm = np.dot(
            self._molecule.mo.coeffsa * self._molecule.mo.occsa,
            self._molecule.mo.coeffsa.T.conj(),
        )
        b_dm = np.dot(
            self._molecule.mo.coeffsb * self._molecule.mo.occsb,
            self._molecule.mo.coeffsb.T.conj(),
        )
        a_density_values = evaluate_density(a_dm,
                                            self._basis,
                                            molgrid.points,
                                            coord_type=self._coord_type)
        b_density_values = evaluate_density(b_dm,
                                            self._basis,
                                            molgrid.points,
                                            coord_type=self._coord_type)
        inp = {"rho": np.array([a_density_values, b_density_values])}
        inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2)
        if xc_function.get_family() == 2:
            a_gradient_density = evaluate_density_gradient(
                a_dm, self._basis, molgrid.points, coord_type=self._coord_type)
            b_gradient_density = evaluate_density_gradient(
                b_dm, self._basis, molgrid.points, coord_type=self._coord_type)
            inp["sigma"] = np.array([
                np.sum(a_gradient_density * a_gradient_density, axis=1),
                np.sum(a_gradient_density * b_gradient_density, axis=1),
                np.sum(b_gradient_density * b_gradient_density, axis=1),
            ])
            inp["sigma"] = inp["sigma"].transpose().reshape(
                len(inp["sigma"][0]) * 3)
        f_xc_values = (xc_function.compute(inp, None, False, False, True,
                                           False))["v2rho2"]
        f_xc_values = np.array([
            f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0],
            f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1],
            f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2],
        ])
        if xc_function.get_family() == 2:
            del (a_gradient_density, b_gradient_density)
        del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp)

        MO_basis_func_val = evaluate_basis(
            self._basis,
            molgrid.points,
            transform=self._molecule.mo.coeffs.T,
            coord_type=self._coord_type,
        )
        indices = self.K_indices(shape=shape, index=index)
        # Defining the arrays of values of all the 4 MO products suitable for the numerical integration
        if shape == "square" or shape == "line":
            a_occup_val = MO_basis_func_val[indices[0][0]]
            a_virt_val = MO_basis_func_val[indices[1][0]]
            kl_a = (a_occup_val[:, None].conj() * a_virt_val).reshape([
                a_occup_val.shape[0] * a_virt_val.shape[0], a_virt_val.shape[1]
            ])
            del (a_occup_val, a_virt_val)
            b_occup_val = MO_basis_func_val[indices[0][1]]
            b_virt_val = MO_basis_func_val[indices[1][1]]
            kl_b = (b_occup_val[:, None].conj() * b_virt_val).reshape([
                b_occup_val.shape[0] * b_virt_val.shape[0], b_virt_val.shape[1]
            ])
            del (b_occup_val, b_virt_val)
            klt = np.block([kl_a.T, kl_b.T]).T
            del kl_b
            if shape == "line":
                a_i_values = MO_basis_func_val[indices[2][0]]
                b_j_values = MO_basis_func_val[indices[2][1]]
                ij_a = a_i_values.conj() * a_i_values
                ij_b = b_j_values.conj() * b_j_values
                ijs = np.block([ij_a.T, ij_b.T]).T
                del (a_i_values, b_j_values, ij_b)
            else:
                ijs = klt
                ij_a = kl_a
            del MO_basis_func_val
            if type == 2:
                K_fxc_DFT = ijs[:, None] * klt
            else:
                K_fxc_DFT = ijs[:, None] * klt.conj()
            # generate the alpha-alpha block
            K_fxc_DFT[:ij_a.shape[0], :kl_a.shape[0]] = (
                K_fxc_DFT[:ij_a.shape[0], :kl_a.shape[0]] * f_xc_values[0] *
                molgrid.weights)
            # generate the beta-alpha block
            K_fxc_DFT[ij_a.shape[0]:, :kl_a.shape[0]] = (
                K_fxc_DFT[ij_a.shape[0]:, :kl_a.shape[0]] * f_xc_values[1] *
                molgrid.weights)
            # generate the alpha-beta block
            K_fxc_DFT[:ij_a.shape[0], kl_a.shape[0]:] = (
                K_fxc_DFT[:ij_a.shape[0], kl_a.shape[0]:] * f_xc_values[1] *
                molgrid.weights)
            # generate th beta-beta block
            K_fxc_DFT[ij_a.shape[0]:, kl_a.shape[0]:] = (
                K_fxc_DFT[ij_a.shape[0]:, kl_a.shape[0]:] * f_xc_values[2] *
                molgrid.weights)
            # integrate
            K_fxc_DFT = np.sum(K_fxc_DFT / 3, axis=2)
            K_fxc_DFt = np.array([
                K_fxc_DFT[:ij_a.shape[0], :kl_a.shape[0]],
                K_fxc_DFT[:ij_a.shape[0], kl_a.shape[0]:],
                K_fxc_DFT[ij_a.shape[0]:, :kl_a.shape[0]],
                K_fxc_DFT[ij_a.shape[0]:, kl_a.shape[0]:],
            ])
            return K_fxc_DFt
        else:
            l = indices[2][0] + indices[2][1]
            i_values = MO_basis_func_val[l[0]]
            k_values = MO_basis_func_val[l[1]]
            K_fxc_DFT = i_values * i_values.conj() * k_values * k_values.conj()
            if len(indices[2][0]) == 0:
                return np.sum(K_fxc_DFT * f_xc_values[2] * molgrid.weights / 3)
            if len(indices[2][0]) == 1:
                return np.sum(K_fxc_DFT * f_xc_values[1] * molgrid.weights / 3)
            else:
                return np.sum(K_fxc_DFT * f_xc_values[0] * molgrid.weights / 3)
def test_M_matrix_calculate_M():
    xc_function = pylibxc.LibXCFunctional("lda_x", "polarized")
    a_dm = np.dot(molecule.mo.coeffsa * molecule.mo.occsa,
                  molecule.mo.coeffsa.T.conj())
    b_dm = np.dot(molecule.mo.coeffsb * molecule.mo.occsb,
                  molecule.mo.coeffsb.T.conj())
    a_density_values = evaluate_density(a_dm,
                                        basis,
                                        molgrid.points,
                                        coord_type="cartesian")
    b_density_values = evaluate_density(b_dm,
                                        basis,
                                        molgrid.points,
                                        coord_type="cartesian")
    inp = {"rho": np.array([a_density_values, b_density_values])}
    inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2)
    f_xc_values = (xc_function.compute(inp, None, False, False, True,
                                       False))["v2rho2"]
    f_xc_values = np.array([
        f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0],
        f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1],
        f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2],
    ])
    del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp)
    MO_values = evaluate_basis(basis,
                               molgrid.points,
                               transform=molecule.mo.coeffs.T,
                               coord_type="cartesian")
    MO_values_conjugated = np.conjugate(MO_values)
    occupied_ind = [[], []]
    virtual_ind = [[], []]
    for i in range(len(molecule.mo.occsa)):
        if molecule.mo.occsa[i] - 1 == 0:
            occupied_ind[0] = occupied_ind[0] + [i]
        if molecule.mo.occsa[i] == 0:
            virtual_ind[0] = virtual_ind[0] + [i]
    for i in range(len(molecule.mo.occsb)):
        if molecule.mo.occsb[i] - 1 == 0:
            occupied_ind[1] = occupied_ind[1] + [i + molecule.mo.nbasis]
        if molecule.mo.occsb[i] == 0:
            virtual_ind[1] = virtual_ind[1] + [i + molecule.mo.nbasis]
    indices = (occupied_ind, virtual_ind)
    M_HF = np.zeros([140, 140], float)
    M_LDA = np.zeros([140, 140], float)
    for s in range(2):
        for i_c, i in enumerate(indices[0][s]):
            for a_c, a in enumerate(indices[1][s]):
                ias = (s * len(indices[0][0]) * len(indices[1][0]) +
                       i_c * len(indices[1][s]) + a_c)
                for t in range(2):
                    for j_c, j in enumerate(indices[0][t]):
                        for b_c, b in enumerate(indices[1][t]):
                            jbt = (
                                t * len(indices[0][0]) * len(indices[1][0]) +
                                j_c * len(indices[1][t]) + b_c)
                            M_HF[ias][jbt] = (M_HF[ias][jbt] +
                                              2 * two_electron_int[i, a, j, b])
                            M_LDA[ias][jbt] = (
                                M_LDA[ias][jbt] +
                                2 * two_electron_int[i, a, j, b])
                            values = (f_xc_values[s + t] *
                                      MO_values_conjugated[i] * MO_values[a] *
                                      MO_values_conjugated[j] * MO_values[b])
                            M_LDA[ias][jbt] = M_LDA[ias][
                                jbt] + 2 * molgrid.integrate(values)
                            if s == t:
                                M_HF[ias][jbt] = (
                                    M_HF[ias][jbt] -
                                    2 * two_electron_int[i, a, j, b])
                            if s == t and i == j and a == b:
                                M_HF[ias][jbt] = (M_HF[ias][jbt] +
                                                  molecule.mo.energies[a] -
                                                  molecule.mo.energies[i])
                                M_LDA[ias][jbt] = (M_LDA[ias][jbt] +
                                                   molecule.mo.energies[a] -
                                                   molecule.mo.energies[i])
    assert np.allclose(M_mat.calculate_M(k="HF", complex=False), M_HF)
    assert np.allclose(
        M_mat.calculate_M(k="lda_x", complex=False, molgrid=molgrid), M_LDA)
Beispiel #15
0
def test_K_matrices_K_fxc_DFT():

    xc_function = pylibxc.LibXCFunctional("lda_x", "polarized")
    a_dm = np.dot(molecule.mo.coeffsa * molecule.mo.occsa,
                  molecule.mo.coeffsa.T.conj())
    b_dm = np.dot(molecule.mo.coeffsb * molecule.mo.occsb,
                  molecule.mo.coeffsb.T.conj())
    a_density_values = evaluate_density(a_dm,
                                        basis,
                                        molgrid.points,
                                        coord_type="cartesian")
    b_density_values = evaluate_density(b_dm,
                                        basis,
                                        molgrid.points,
                                        coord_type="cartesian")
    inp = {"rho": np.array([a_density_values, b_density_values])}
    inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2)
    f_xc_values = (xc_function.compute(inp, None, False, False, True,
                                       False))["v2rho2"]
    f_xc_values = np.array([
        f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0],
        f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1],
        f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2],
    ])
    del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp)

    MO_values = evaluate_basis(basis,
                               molgrid.points,
                               transform=molecule.mo.coeffs.T,
                               coord_type="cartesian")
    MO_values_conjugated = np.conjugate(MO_values)

    indices = (occupied_ind, virtual_ind)
    K_size = len(occupied_ind[0]) * len(virtual_ind[0]) + len(
        occupied_ind[1]) * len(virtual_ind[1])
    K_shape = [K_size, K_size]
    K_fxc_DFT = np.zeros(K_shape, float)
    for t in range(2):
        for j_c, j in enumerate(indices[0][t]):
            for b_c, b in enumerate(indices[1][t]):
                jbt = (t * len(indices[0][0]) * len(indices[1][0]) +
                       j_c * len(indices[1][t]) + b_c)
                for s in range(2):
                    for i_c, i in enumerate(indices[0][s]):
                        for a_c, a in enumerate(indices[1][s]):
                            ias = (
                                s * len(indices[0][0]) * len(indices[1][0]) +
                                i_c * len(indices[1][s]) + a_c)
                            values = (f_xc_values[s + t] *
                                      MO_values_conjugated[i] * MO_values[a] *
                                      MO_values_conjugated[j] * MO_values[b])
                            K_fxc_DFT[ias][jbt] = K_fxc_DFT[ias][
                                jbt] + molgrid.integrate(values)
    K_fxc_DFT = np.array([
        K_fxc_DFT[:70, :70],
        K_fxc_DFT[:70, 70:],
        K_fxc_DFT[70:, :70],
        K_fxc_DFT[70:, 70:],
    ])
    assert np.allclose(
        K_mats.K_fxc_DFT(XC_functional="lda_x", molgrid=molgrid), K_fxc_DFT)
    K_shape = [1, K_size]
    K_fxc_DFT = np.zeros(K_shape, float)
    index = [[4], []]
    indices = (occupied_ind, virtual_ind, index)
    for t in range(2):
        for j_c, j in enumerate(indices[0][t]):
            for b_c, b in enumerate(indices[1][t]):
                jbt = (t * len(indices[0][0]) * len(indices[1][0]) +
                       j_c * len(indices[1][t]) + b_c)
                for s in range(2):
                    for f_c, f in enumerate(indices[2][s]):
                        ffs = s * len(indices[2][0]) + f_c
                        values = (f_xc_values[s + t] *
                                  MO_values_conjugated[f] * MO_values[f] *
                                  MO_values_conjugated[j] * MO_values[b])
                        K_fxc_DFT[ffs][jbt] = K_fxc_DFT[ffs][
                            jbt] + molgrid.integrate(values)
    K_fxc_DFT_0 = K_mats.K_fxc_DFT(shape="line",
                                   index=index,
                                   XC_functional="lda_x",
                                   molgrid=molgrid)
    assert np.allclose(K_fxc_DFT_0[0], K_fxc_DFT[0, :70])
    assert np.allclose(K_fxc_DFT_0[1], K_fxc_DFT[0, 70:])
    assert np.allclose(K_fxc_DFT_0[2], np.zeros([0, 70]))
    assert np.allclose(K_fxc_DFT_0[3], np.zeros([0, 70]))
    values = (f_xc_values[0] * MO_values_conjugated[4] * MO_values[4] *
              MO_values_conjugated[4] * MO_values[4])
    K_fxc_DFT = molgrid.integrate(values)
    assert np.allclose(
        K_mats.K_fxc_DFT(shape="point",
                         index=[[4, 4], []],
                         XC_functional="lda_x",
                         molgrid=molgrid),
        K_fxc_DFT,
    )