Пример #1
0
def test_change_of_basis():
    n = 2
    l = 10
    dim = 2
    new_l = 2 * l - n

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = spas.construct_general_orbital_system()

    C_spas = RandomBasisSet.get_random_elements((spas.l, new_l), np)
    C_gos = RandomBasisSet.get_random_elements((gos.l, new_l), np)

    h_spas = change_basis_h(spas.h.copy(), C_spas)
    u_spas = change_basis_u(spas.u.copy(), C_spas)
    h_gos = change_basis_h(gos.h.copy(), C_gos)
    u_gos = change_basis_u(gos.u.copy(), C_gos)

    spas.change_basis(C_spas)
    gos.change_basis(C_gos)

    assert spas.l == new_l
    assert all([new_l == s for s in spas.h.shape])
    assert all([new_l == s for s in spas.u.shape])
    np.testing.assert_allclose(h_spas, spas.h, atol=1e-12, rtol=1e-12)
    np.testing.assert_allclose(u_spas, spas.u, atol=1e-12, rtol=1e-12)

    assert gos.l == new_l
    assert all([new_l == s for s in gos.h.shape])
    assert all([new_l == s for s in gos.u.shape])
    np.testing.assert_allclose(h_gos, gos.h, atol=1e-12, rtol=1e-12)
    np.testing.assert_allclose(u_gos, gos.u, atol=1e-12, rtol=1e-12)
Пример #2
0
def test_spin_up_down():
    n = 4
    l = 10
    dim = 2

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = spas.construct_general_orbital_system()

    a = gos._basis_set.a
    b = gos._basis_set.b

    sigma_up = 0.5 * (gos._basis_set.sigma_x + 1j * gos._basis_set.sigma_y)
    sigma_down = 0.5 * (gos._basis_set.sigma_x - 1j * gos._basis_set.sigma_y)

    np.testing.assert_allclose(a, sigma_up @ b)
    np.testing.assert_allclose(np.zeros_like(a), sigma_up @ a)
    np.testing.assert_allclose(np.zeros_like(b), sigma_down @ b)
    np.testing.assert_allclose(b, sigma_down @ a)
    np.testing.assert_allclose(a, sigma_up @ sigma_down @ a)
    np.testing.assert_allclose(b, sigma_down @ sigma_up @ b)

    S_up = np.kron(spas.s, sigma_up)
    S_down = np.kron(spas.s, sigma_down)

    np.testing.assert_allclose(S_up, gos.spin_x + 1j * gos.spin_y)
    np.testing.assert_allclose(S_down, gos.spin_x - 1j * gos.spin_y)
Пример #3
0
def test_gos_spin_matrices():
    n = 4
    l = 10
    dim = 2

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = spas.construct_general_orbital_system()

    for spin, sigma in zip(
        [gos.spin_x, gos.spin_y, gos.spin_z],
        [
            gos._basis_set.sigma_x,
            gos._basis_set.sigma_y,
            gos._basis_set.sigma_z,
        ],
    ):
        spin_2 = np.zeros((gos.l, gos.l), dtype=np.complex128)

        for i in range(gos.l):
            a = i % 2
            g = i // 2

            for j in range(gos.l):
                b = j % 2
                d = j // 2

                spin_2[i, j] = 0.5 * spas.s[g, d] * sigma[a, b]

        np.testing.assert_allclose(spin, spin_2)
Пример #4
0
def test_setters():
    n = 2
    l = 10
    dim = 3

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = spas.construct_general_orbital_system()

    assert gos.l == 2 * spas.l
def test_no_operators():
    n = 4
    l = 10
    dim = 3

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = GeneralOrbitalSystem(n, RandomBasisSet(l, dim))

    assert not spas.has_one_body_time_evolution_operator
    assert not gos.has_one_body_time_evolution_operator
    assert not spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    np.testing.assert_allclose(spas.h_t(10), spas.h)
    np.testing.assert_allclose(spas.u_t(10), spas.u)
    np.testing.assert_allclose(gos.h_t(10), gos.h)
    np.testing.assert_allclose(gos.u_t(10), gos.u)

    spas.set_time_evolution_operator(
        [],
        add_h_0=False,
        add_u_0=False,
    )
    gos.set_time_evolution_operator([], add_h_0=False, add_u_0=False)

    assert not spas.has_one_body_time_evolution_operator
    assert not gos.has_one_body_time_evolution_operator
    assert not spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    np.testing.assert_allclose(spas.h_t(0), np.zeros_like(spas.h))
    np.testing.assert_allclose(spas.u_t(0), np.zeros_like(spas.u))
    np.testing.assert_allclose(gos.h_t(0), np.zeros_like(gos.h))
    np.testing.assert_allclose(gos.u_t(0), np.zeros_like(gos.u))
Пример #6
0
def test_spin_squared():
    n = 2
    l = 2
    dim = 2

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    spas = SpatialOrbitalSystem(
        n, ODQD(l, 8, 1001, potential=ODQD.HOPotential(1)))
    gos = spas.construct_general_orbital_system(a=[1, 0], b=[0, 1])

    overlap = spas.s
    overlap_sq = np.einsum("pr, qs -> pqrs", overlap, overlap)

    a = gos._basis_set.a
    b = gos._basis_set.b

    aa = np.kron(a, a)
    ab = np.kron(a, b)
    ba = np.kron(b, a)
    bb = np.kron(b, b)

    triplets = [aa, 1 / np.sqrt(2) * (ab + ba), bb]
    singlet = [1 / np.sqrt(2) * (ab - ba)]

    # S^2 with alpha = [1, 0]^T and beta = [0, 1]^T
    S_sq_spin = np.zeros((4, 4))
    S_sq_spin[0, 0] = 2
    S_sq_spin[3, 3] = 2
    S_sq_spin[1, 1] = 1
    S_sq_spin[2, 2] = 1
    S_sq_spin[1, 2] = 1
    S_sq_spin[2, 1] = 1
    S_sq_spin = S_sq_spin.reshape(2, 2, 2, 2)

    for trip in triplets:
        # Check that the eigenvalue of all triplet states is 2
        np.testing.assert_allclose(trip.T @ S_sq_spin.reshape(4, 4) @ trip, 2)

    # Check that the eigenvalue of the singlet state is 0
    np.testing.assert_allclose(
        singlet[0].T @ S_sq_spin.reshape(4, 4) @ singlet[0], 0)
Пример #7
0
def get_odho_ao():
    n = 2
    l = 20

    grid_length = 5
    num_grid_points = 1001
    omega = 1

    odho = SpatialOrbitalSystem(
        n,
        ODQD(
            l, grid_length, num_grid_points, potential=ODQD.HOPotential(omega)
        ),
    )

    return odho
Пример #8
0
def test_overlap_squared():
    n = 4
    l = 10
    dim = 2

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))

    overlap = spas.s
    overlap_sq = np.einsum("pr, qs -> pqrs", overlap, overlap)

    for p in range(spas.l):
        for q in range(spas.l):
            for r in range(spas.l):
                for s in range(spas.l):
                    np.testing.assert_allclose(overlap_sq[p, q, r, s],
                                               overlap[p, r] * overlap[q, s])
Пример #9
0
def construct_custom_system(
    n,
    l,
    s,
    h,
    u,
    dim=3,
    particle_charge=-1,
    np=None,
    includes_spin=False,
    anti_symmetrized_u=False,
    system_type="general",
    **kwargs,
):

    if np is None:
        import numpy as np

    bs = setup_basis_set(
        n,
        l,
        s,
        h,
        u,
        dim,
        particle_charge,
        np,
        includes_spin,
        anti_symmetrized_u,
        **kwargs,
    )

    if system_type.lower() == "general":
        system = GeneralOrbitalSystem(n, bs)
    elif system_type.lower() == "spatial":
        system = SpatialOrbitalSystem(n, bs)
    else:
        raise NotImplementedError(
            f"System type: {system_type} is not supported!")

    if "C" in kwargs.keys():
        system.change_basis(kwargs["C"])

    return system
def test_single_time_evolution_operator():
    n = 4
    l = 10
    dim = 3

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = GeneralOrbitalSystem(n, RandomBasisSet(l, dim))

    assert not spas.has_one_body_time_evolution_operator
    assert not gos.has_one_body_time_evolution_operator
    assert not spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    np.testing.assert_allclose(spas.h_t(10), spas.h)
    np.testing.assert_allclose(spas.u_t(10), spas.u)
    np.testing.assert_allclose(gos.h_t(10), gos.h)
    np.testing.assert_allclose(gos.u_t(10), gos.u)

    spas.set_time_evolution_operator(CustomOneBodyOperator(2, spas.h),
                                     add_h_0=False)
    gos.set_time_evolution_operator(CustomOneBodyOperator(3, gos.h),
                                    add_u_0=False)

    assert spas.has_one_body_time_evolution_operator
    assert gos.has_one_body_time_evolution_operator
    assert not spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    np.testing.assert_allclose(
        spas.h_t(0),
        spas.h * 2,
    )
    np.testing.assert_allclose(spas.u_t(0), spas.u)

    np.testing.assert_allclose(
        gos.h_t(0),
        gos.h + gos.h * 3,
    )
    np.testing.assert_allclose(gos.u_t(0), np.zeros_like(gos.u))
def test_multiple_time_evolution_operators():
    n = 4
    l = 10
    dim = 3

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = GeneralOrbitalSystem(n, RandomBasisSet(l, dim))

    assert not spas.has_one_body_time_evolution_operator
    assert not gos.has_one_body_time_evolution_operator
    assert not spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    spas.set_time_evolution_operator(
        [
            CustomOneBodyOperator(2, spas.h),
            CustomOneBodyOperator(3, spas.s),
            AdiabaticSwitching(2),
        ],
        add_u_0=False,
    )

    gos.set_time_evolution_operator(
        (
            CustomOneBodyOperator(1, gos.h),
            CustomOneBodyOperator(3, gos.s),
            CustomOneBodyOperator(-2, gos.position[0]),
        ),
        add_h_0=False,
    )

    assert spas.has_one_body_time_evolution_operator
    assert gos.has_one_body_time_evolution_operator
    assert spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    np.testing.assert_allclose(
        spas.h_t(0),
        spas.h + spas.h * 2 + spas.s * 3,
    )
    np.testing.assert_allclose(spas.u_t(0), 2 * spas.u)

    np.testing.assert_allclose(
        gos.h_t(0),
        gos.h + gos.s * 3 - gos.position[0] * 2,
    )
    np.testing.assert_allclose(gos.u_t(0), gos.u)
def test_single_dipole_time_evolution_operator():
    n = 4
    l = 10
    dim = 3

    omega = 0.25

    spas = SpatialOrbitalSystem(n, RandomBasisSet(l, dim))
    gos = GeneralOrbitalSystem(n, RandomBasisSet(l, dim))

    field = lambda t: np.sin(omega * 2)
    polarization = np.zeros(dim)
    polarization[0] = 1

    spas.set_time_evolution_operator(
        DipoleFieldInteraction(
            field,
            polarization,
        ))
    gos.set_time_evolution_operator(
        DipoleFieldInteraction(
            field,
            polarization,
        ))

    assert spas.has_one_body_time_evolution_operator
    assert gos.has_one_body_time_evolution_operator
    assert not spas.has_two_body_time_evolution_operator
    assert not gos.has_two_body_time_evolution_operator

    for t in [0, 0.1, 0.5, 1.3]:
        np.testing.assert_allclose(
            spas.h_t(t),
            spas.h - field(t) * spas.dipole_moment[0],
        )
        np.testing.assert_allclose(
            gos.h_t(t),
            gos.h - field(t) * gos.dipole_moment[0],
        )

        np.testing.assert_allclose(spas.u_t(t), spas.u)
        np.testing.assert_allclose(gos.u_t(t), gos.u)
Пример #13
0
def construct_pyscf_system_rhf(
    molecule,
    basis="cc-pvdz",
    add_spin=True,
    anti_symmetrize=True,
    np=None,
    verbose=False,
    charge=0,
    cart=False,
    dip=None,
    **kwargs,
):
    """Convenience function setting up a closed-shell atom or a molecule from
    PySCF as a ``QuantumSystem`` in RHF-basis using PySCF's RHF-solver.

    Parameters
    ----------
    molecule : str
        String describing the atom or molecule. This gets passed to PySCF which
        means that we support all the same string options as PySCF.
    basis : str
        String describing the basis set. PySCF determines which options are
        available.
    add_spin : bool
        Whether or not to return a ``SpatialOrbitalSystem`` (``False``) or a
        ``GeneralOrbitalSystem`` (``True``). Default is ``True``.
    anti_symmetrize : bool
        Whether or not to anti-symmetrize the two-body elements in a
        ``GeneralOrbitalSystem``. This only applies if ``add_spin = True``.
        Default is ``True``.
    np : module
        Array- and linear algebra module.
    dip : list
        [position, momentum] f.ex. from Dalton
    Returns
    -------
    SpatialOrbitalSystem, GeneralOrbitalSystem
        Depending on the choice of ``add_spin`` we return a
        ``SpatialOrbitalSystem`` (``add_spin = False``), or a
        ``GeneralOrbitalSystem`` (``add_spin = True``).

    See Also
    -------
    PySCF

    Example
    -------
    >>> # Set up the Beryllium atom centered at (0, 0, 0)
    >>> system = construct_pyscf_system_rhf(
    ...     "be 0 0 0", basis="cc-pVDZ", add_spin=False
    ... ) # doctest.ELLIPSIS
    converged SCF energy = -14.5723...
    >>> # Compare the number of occupied basis functions
    >>> system.n == 4 // 2
    True
    >>> gos = system.construct_general_orbital_system()
    >>> gos.n == 4
    True
    >>> system = construct_pyscf_system_rhf(
    ...     "be 0 0 0", basis="cc-pVDZ"
    ... ) # doctest.ELLIPSIS
    converged SCF energy = -14.5723...
    >>> system.n == gos.n
    True
    """

    import pyscf

    if np is None:
        import numpy as np

    # Build molecule in AO-basis
    mol = pyscf.gto.Mole()
    mol.unit = "bohr"
    mol.charge = charge
    mol.cart = cart
    mol.build(atom=molecule, basis=basis, **kwargs)
    nuclear_repulsion_energy = mol.energy_nuc()

    n = mol.nelectron
    assert (
        n %
        2 == 0), "We require closed shell, with an even number of particles"

    l = mol.nao

    hf = pyscf.scf.RHF(mol)
    hf_energy = hf.kernel()

    if not hf.converged:
        warnings.warn("RHF calculation did not converge")

    if verbose:
        print(f"RHF energy: {hf.e_tot}")

    charges = mol.atom_charges()
    coords = mol.atom_coords()
    nuc_charge_center = np.einsum("z,zx->x", charges, coords) / charges.sum()
    mol.set_common_orig_(nuc_charge_center)

    C = np.asarray(hf.mo_coeff)

    h = pyscf.scf.hf.get_hcore(mol)
    s = mol.intor_symmetric("int1e_ovlp")
    u = mol.intor("int2e").reshape(l, l, l, l).transpose(0, 2, 1, 3)
    position = mol.intor("int1e_r").reshape(3, l, l)
    momentum = -1j * mol.intor("int1e_ipovlp").reshape(3, l, l)

    if dip is not None:
        diplen = dip[0]
        arr_eq0 = np.allclose(diplen[0], position[0])
        arr_eq1 = np.allclose(diplen[1], position[1])
        arr_eq2 = np.allclose(diplen[2], position[2])
        if not (arr_eq0 and arr_eq1 and arr_eq2):
            print('WARNING:')
            print('dipole_array_pyscf != dipole_array_dalton')

    bs = BasisSet(l, dim=3, np=np)
    bs.h = h
    bs.s = s
    bs.u = u
    bs.nuclear_repulsion_energy = nuclear_repulsion_energy
    bs.particle_charge = -1
    bs.position = position
    bs.momentum = momentum
    if dip is not None:
        bs.momentum = dip[1]
    bs.change_module(np=np)

    system = SpatialOrbitalSystem(n, bs)
    system.change_basis(C)

    return (system.construct_general_orbital_system(
        anti_symmetrize=anti_symmetrize) if add_spin else system)
Пример #14
0
def construct_pyscf_system_ao(
    molecule,
    basis="cc-pvdz",
    add_spin=True,
    anti_symmetrize=True,
    np=None,
    **kwargs,
):
    """Convenience function setting up an atom or a molecule from PySCF as a
    ``QuantumSystem``.

    Parameters
    ----------
    molecule : str
        String describing the atom or molecule. This gets passed to PySCF which
        means that we support all the same string options as PySCF.
    basis : str
        String describing the basis set. PySCF determines which options are
        available.
    add_spin : bool
        Whether or not to return a ``SpatialOrbitalSystem`` (``False``) or a
        ``GeneralOrbitalSystem`` (``True``). Default is ``True``.
    anti_symmetrize : bool
        Whether or not to anti-symmetrize the two-body elements in a
        ``GeneralOrbitalSystem``. This only applies if ``add_spin = True``.
        Default is ``True``.
    np : module
        Array- and linear algebra module.

    Returns
    -------
    SpatialOrbitalSystem, GeneralOrbitalSystem
        Depending on the choice of ``add_spin`` we return a
        ``SpatialOrbitalSystem`` (``add_spin = False``), or a
        ``GeneralOrbitalSystem`` (``add_spin = True``).

    See Also
    -------
    PySCF

    Example
    -------
    >>> # Set up the Beryllium atom centered at (0, 0, 0)
    >>> system = construct_pyscf_system_ao(
    ...     "be 0 0 0", basis="cc-pVDZ", add_spin=False
    ... )
    >>> # Compare the number of occupied basis functions
    >>> system.n == 4 // 2
    True
    >>> gos = system.construct_general_orbital_system()
    >>> gos.n == 4
    True
    """

    import pyscf

    if np is None:
        import numpy as np

    mol = pyscf.gto.Mole()
    mol.unit = "bohr"
    mol.build(atom=molecule, basis=basis, **kwargs)
    nuclear_repulsion_energy = mol.energy_nuc()

    n = mol.nelectron
    l = mol.nao

    # n_a = (mol.nelectron + mol.spin) // 2
    # n_b = n_a - mol.spin

    # assert n_b == n - n_a

    h = pyscf.scf.hf.get_hcore(mol)
    s = mol.intor_symmetric("int1e_ovlp")
    u = mol.intor("int2e").reshape(l, l, l, l).transpose(0, 2, 1, 3)
    position = mol.intor("int1e_r").reshape(3, l, l)

    bs = BasisSet(l, dim=3, np=np)
    bs.h = h
    bs.s = s
    bs.u = u
    bs.nuclear_repulsion_energy = nuclear_repulsion_energy
    bs.particle_charge = -1
    bs.position = position
    bs.change_module(np=np)

    system = SpatialOrbitalSystem(n, bs)

    return (system.construct_general_orbital_system(
        anti_symmetrize=anti_symmetrize) if add_spin else system)