Source code for iodata.test.test_orbitals

# IODATA is an input and output module for quantum chemistry.
# Copyright (C) 2011-2019 The IODATA Development Team
#
# This file is part of IODATA.
#
# IODATA is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# IODATA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>
# --
"""Unit tests for iodata.orbitals."""

import numpy as np
import pytest
from numpy.testing import assert_allclose, assert_equal

from ..orbitals import MolecularOrbitals


[docs] def test_wrong_kind(): with pytest.raises(ValueError): MolecularOrbitals("foo", 5, 5)
[docs] def test_restricted_empty(): with pytest.raises(ValueError): MolecularOrbitals("restricted", 3, None) with pytest.raises(ValueError): MolecularOrbitals("restricted", None, 5) with pytest.raises(ValueError): MolecularOrbitals("restricted", None, None) with pytest.raises(ValueError): MolecularOrbitals("restricted", 5, 3) mo = MolecularOrbitals("restricted", 5, 5) assert mo.norba == 5 assert mo.norbb == 5 assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 5 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None # Test setters for occsa occsa = np.array([1, 1, 0.5, 0.5, 0.0]) mo.occsa = occsa assert_allclose(mo.occsa, occsa) assert_allclose(mo.occsb, 0.0) assert_allclose(mo.occs, occsa) assert_allclose(mo.occs_aminusb, occsa) # Test setters for occsb mo.occs = None mo.occs_aminusb = None occsb = np.array([0.5, 1, 1, 0.5, 0.0]) mo.occsb = occsb assert_allclose(mo.occsa, 0.0) assert_allclose(mo.occsb, occsb) assert_allclose(mo.occs, occsb) assert_allclose(mo.occs_aminusb, -occsb)
[docs] def test_restricted_occs(): occs = [2, 2, 0, 0, 0] with pytest.raises(TypeError): MolecularOrbitals("restricted", 3, 3, occs=occs) mo = MolecularOrbitals("restricted", 5, 5, occs=occs) assert mo.norba == 5 assert mo.norbb == 5 assert mo.nelec == 4 assert mo.nbasis is None assert mo.norb == 5 assert mo.spinpol == 0 # Test heuristics for ROHF or ROKS assert_equal(mo.occsa, [1, 1, 0, 0, 0]) assert_equal(mo.occsb, [1, 1, 0, 0, 0]) assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None # Test setters mo.occsa = [1, 0.3, 0.7, 0, 0] assert_allclose(mo.occsa, [1, 0.3, 0.7, 0, 0]) assert_allclose(mo.occsb, [1, 1, 0, 0, 0]) assert_allclose(mo.occs_aminusb, [0, -0.7, 0.7, 0, 0]) mo.occs_aminusb = None mo.occs = occs assert_equal(mo.occsa, [1, 1, 0, 0, 0]) assert_equal(mo.occsb, [1, 1, 0, 0, 0]) mo.occsb = [0.2, 0.8, 0, 0, 0] assert_allclose(mo.occsa, [1, 1, 0, 0, 0]) assert_allclose(mo.occsb, [0.2, 0.8, 0, 0, 0]) assert_allclose(mo.occs_aminusb, [0.8, 0.2, 0, 0, 0]) # Test heuristics for closed-shell natural orbitals mo.occs = [2, 1.8, 0.2, 0, 0] mo.occs_aminusb = None assert_allclose(mo.occsa, [1, 0.9, 0.1, 0, 0]) assert_allclose(mo.occsb, [1, 0.9, 0.1, 0, 0]) assert_allclose(mo.spinpol, 0.0)
[docs] def test_restricted_occs_aminusb(): occs = [2.0, 1.3, 0.7] occs_aminusb = [0.0, 0.7, 0.1] with pytest.raises(TypeError): MolecularOrbitals("restricted", 2, 2, occs=occs, occs_aminusb=occs_aminusb) mo = MolecularOrbitals("restricted", 3, 3, occs=occs, occs_aminusb=occs_aminusb) assert mo.norba == 3 assert mo.norbb == 3 assert_allclose(mo.nelec, 4.0) assert mo.nbasis is None assert mo.norb == 3 assert_allclose(mo.occsa, [1.0, 1.0, 0.4]) assert_allclose(mo.occsb, [1.0, 0.3, 0.3]) assert_allclose(mo.spinpol, 0.8) assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None # Verify that in-place modification of occsa and occsb does not work. with pytest.raises(ValueError): mo.occsa[1] = 0.5 assert_allclose(mo.occsa, [1.0, 1.0, 0.4]) with pytest.raises(ValueError): mo.occsb[1] = 0.5 assert_allclose(mo.occsb, [1.0, 0.3, 0.3]) # Verify that shooting in one's own foot is still an option. occsa_foo = mo.occsa occsa_foo.flags.writeable = True occsa_foo[1] = 0.5 assert_allclose(mo.occsa, [1.0, 1.0, 0.4]) # Test setters mo.occsa = [1.0, 0.3, 0.7] assert_allclose(mo.occsa, [1.0, 0.3, 0.7]) assert_allclose(mo.occsb, [1.0, 0.3, 0.3]) assert_allclose(mo.occs_aminusb, [0, 0.0, 0.4], atol=1e-10) assert_allclose(mo.spinpol, 0.4) mo.occsb = [0.2, 0.8, 0.0] assert_allclose(mo.occsa, [1.0, 0.3, 0.7]) assert_allclose(mo.occsb, [0.2, 0.8, 0.0]) assert_allclose(mo.occs_aminusb, [0.8, -0.5, 0.7]) assert_allclose(mo.spinpol, 1.0) # Test reverting back to heuristics assert_allclose(mo.occs, [1.2, 1.1, 0.7]) mo.occs_aminusb = None assert_allclose(mo.occsa, [0.6, 0.55, 0.35]) assert_allclose(mo.occsb, [0.6, 0.55, 0.35]) assert_allclose(mo.spinpol, 0.0)
[docs] def test_restricted_coeffs(): rng = np.random.default_rng(1) coeffs = rng.uniform(-1, 1, (7, 5)) with pytest.raises(TypeError): MolecularOrbitals("restricted", 3, 3, coeffs=coeffs) mo = MolecularOrbitals("restricted", 5, 5, coeffs=coeffs) assert mo.norba == 5 assert mo.norbb == 5 assert mo.nelec is None assert mo.nbasis == 7 assert mo.norb == 5 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is coeffs assert mo.coeffsb is coeffs assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None
[docs] def test_restricted_energies(): rng = np.random.default_rng(1) energies = rng.uniform(-1, 1, 5) with pytest.raises(TypeError): MolecularOrbitals("restricted", 3, 3, energies=energies) mo = MolecularOrbitals("restricted", 5, 5, energies=energies) assert mo.norba == 5 assert mo.norbb == 5 assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 5 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is energies assert mo.energiesb is energies assert mo.irrepsa is None assert mo.irrepsb is None
[docs] def test_restricted_irreps(): irreps = ["A", "A", "B", "A", "B"] with pytest.raises(TypeError): MolecularOrbitals("restricted", 3, 3, irreps=irreps) mo = MolecularOrbitals("restricted", 5, 5, irreps=irreps) assert mo.norba == 5 assert mo.norbb == 5 assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 5 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is irreps assert mo.irrepsb is irreps
[docs] def test_unrestricted_empty(): with pytest.raises(ValueError): MolecularOrbitals("unrestricted", 3, None) with pytest.raises(ValueError): MolecularOrbitals("unrestricted", None, 5) with pytest.raises(ValueError): MolecularOrbitals("unrestricted", None, None) mo = MolecularOrbitals("unrestricted", 5, 3) assert mo.norba == 5 assert mo.norbb == 3 assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 8 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None
[docs] def test_unrestricted_occs(): occs = [1, 1, 0, 0, 0, 1, 0, 0] with pytest.raises(TypeError): MolecularOrbitals("unrestricted", 3, 2, occs=occs) mo = MolecularOrbitals("unrestricted", 5, 3, occs=occs) assert mo.norba == 5 assert mo.norbb == 3 assert mo.nelec == 3 assert mo.nbasis is None assert mo.norb == 8 assert mo.spinpol == 1 assert_equal(mo.occsa, [1, 1, 0, 0, 0]) assert_equal(mo.occsb, [1, 0, 0]) assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None # Test setters for occsa and occsb occsa = np.array([1, 1, 0.5, 0.5, 0.0]) mo.occsa = occsa assert_allclose(mo.occsa, occsa) occsb = np.array([1, 0.7, 0.3]) mo.occsb = occsb assert_allclose(mo.occsb, occsb) assert_allclose(mo.occs, np.concatenate([occsa, occsb])) # Test in-place modification of occsa and occsb, which should just work. mo.occs = occs mo.occsa[:] = occsa assert_allclose(mo.occsa, occsa) occsb = np.array([1, 0.7, 0.3]) mo.occsb[:] = occsb assert_allclose(mo.occsb, occsb) assert_allclose(mo.occs, np.concatenate([occsa, occsb]))
[docs] def test_unrestricted_occs_aminusb(): occs = [2, 1, 0] occs_aminusb = [0, 1, 0] with pytest.raises(ValueError): MolecularOrbitals("unrestricted", 2, 1, occs=occs, occs_aminusb=occs_aminusb)
[docs] def test_unrestricted_coeffs(): rng = np.random.default_rng(1) coeffs = rng.uniform(-1, 1, (7, 8)) with pytest.raises(TypeError): MolecularOrbitals("unrestricted", 3, 2, coeffs=coeffs) mo = MolecularOrbitals("unrestricted", 5, 3, coeffs=coeffs) assert mo.norba == 5 assert mo.norbb == 3 assert mo.nelec is None assert mo.nbasis == 7 assert mo.norb == 8 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert_equal(mo.coeffsa, coeffs[:, :5]) assert_equal(mo.coeffsb, coeffs[:, 5:]) assert mo.energiesa is None assert mo.energiesb is None assert mo.irrepsa is None assert mo.irrepsb is None
[docs] def test_unrestricted_energies(): rng = np.random.default_rng(1) energies = rng.uniform(-1, 1, 8) with pytest.raises(TypeError): MolecularOrbitals("unrestricted", 3, 2, energies=energies) mo = MolecularOrbitals("unrestricted", 5, 3, energies=energies) assert mo.norba == 5 assert mo.norbb == 3 assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 8 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is None assert mo.coeffsb is None assert_equal(mo.energiesa, energies[:5]) assert_equal(mo.energiesb, energies[5:]) assert mo.irrepsa is None assert mo.irrepsb is None
[docs] def test_unrestricted_irreps(): irreps = ["A", "A", "B", "A", "B", "B", "B", "A"] with pytest.raises(TypeError): MolecularOrbitals("unrestricted", 3, 2, irreps=irreps) mo = MolecularOrbitals("unrestricted", 5, 3, irreps=irreps) assert mo.norba == 5 assert mo.norbb == 3 assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 8 assert mo.spinpol is None assert mo.occsa is None assert mo.occsb is None assert mo.coeffsa is None assert mo.coeffsb is None assert mo.energiesa is None assert mo.energiesb is None # irreps are lists, not arrays assert mo.irrepsa == irreps[:5] assert mo.irrepsb == irreps[5:]
[docs] def test_generalized_empty(): with pytest.raises(ValueError): mo = MolecularOrbitals("generalized", 5, 3) with pytest.raises(ValueError): mo = MolecularOrbitals("generalized", 5, None) with pytest.raises(ValueError): mo = MolecularOrbitals("generalized", None, 3) mo = MolecularOrbitals("generalized", None, None) assert mo.norba is None assert mo.norbb is None assert mo.nelec is None assert mo.nbasis is None assert mo.norb is None with pytest.raises(NotImplementedError): _ = mo.spinpol with pytest.raises(NotImplementedError): _ = mo.occsa with pytest.raises(NotImplementedError): _ = mo.occsb with pytest.raises(NotImplementedError): _ = mo.coeffsa with pytest.raises(NotImplementedError): _ = mo.coeffsb with pytest.raises(NotImplementedError): _ = mo.energiesa with pytest.raises(NotImplementedError): _ = mo.energiesb with pytest.raises(NotImplementedError): _ = mo.irrepsa with pytest.raises(NotImplementedError): _ = mo.irrepsb
[docs] def test_generalized_occs(): mo = MolecularOrbitals("generalized", None, None, occs=[1, 1, 1, 1, 1, 0, 0]) assert mo.norba is None assert mo.norbb is None assert mo.nelec == 5 assert mo.nbasis is None assert mo.norb == 7 with pytest.raises(NotImplementedError): _ = mo.spinpol with pytest.raises(NotImplementedError): _ = mo.occsa with pytest.raises(NotImplementedError): _ = mo.occsb with pytest.raises(NotImplementedError): _ = mo.coeffsa with pytest.raises(NotImplementedError): _ = mo.coeffsb with pytest.raises(NotImplementedError): _ = mo.energiesa with pytest.raises(NotImplementedError): _ = mo.energiesb with pytest.raises(NotImplementedError): _ = mo.irrepsa with pytest.raises(NotImplementedError): _ = mo.irrepsb
[docs] def test_generalized_occs_aminusb(): occs = [2, 1, 0] occs_aminusb = [0, 1, 0] with pytest.raises(ValueError): MolecularOrbitals("generalized", None, None, occs=occs, occs_aminusb=occs_aminusb)
[docs] def test_generalized_coeffs(): rng = np.random.default_rng(1) coeffs = rng.uniform(-1, 1, (10, 7)) mo = MolecularOrbitals("generalized", None, None, coeffs=coeffs) assert mo.norba is None assert mo.norbb is None assert mo.nelec is None assert mo.nbasis == 5 # 5 *spatial* basis functions! assert mo.norb == 7 with pytest.raises(NotImplementedError): _ = mo.spinpol with pytest.raises(NotImplementedError): _ = mo.occsa with pytest.raises(NotImplementedError): _ = mo.occsb with pytest.raises(NotImplementedError): _ = mo.coeffsa with pytest.raises(NotImplementedError): _ = mo.coeffsb with pytest.raises(NotImplementedError): _ = mo.energiesa with pytest.raises(NotImplementedError): _ = mo.energiesb with pytest.raises(NotImplementedError): _ = mo.irrepsa with pytest.raises(NotImplementedError): _ = mo.irrepsb
[docs] def test_generalized_energies(): rng = np.random.default_rng(1) energies = rng.uniform(-1, 1, 7) mo = MolecularOrbitals("generalized", None, None, energies=energies) assert mo.norba is None assert mo.norbb is None assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 7 with pytest.raises(NotImplementedError): _ = mo.spinpol with pytest.raises(NotImplementedError): _ = mo.occsa with pytest.raises(NotImplementedError): _ = mo.occsb with pytest.raises(NotImplementedError): _ = mo.coeffsa with pytest.raises(NotImplementedError): _ = mo.coeffsb with pytest.raises(NotImplementedError): _ = mo.energiesa with pytest.raises(NotImplementedError): _ = mo.energiesb with pytest.raises(NotImplementedError): _ = mo.irrepsa with pytest.raises(NotImplementedError): _ = mo.irrepsb
[docs] def test_generalized_irreps(): irreps = ["A", "B", "A", "A", "B", "B", "B"] mo = MolecularOrbitals("generalized", None, None, irreps=irreps) assert mo.norba is None assert mo.norbb is None assert mo.nelec is None assert mo.nbasis is None assert mo.norb == 7 with pytest.raises(NotImplementedError): _ = mo.spinpol with pytest.raises(NotImplementedError): _ = mo.occsa with pytest.raises(NotImplementedError): _ = mo.occsb with pytest.raises(NotImplementedError): mo.occsa = [1, 1, 1, 0, 0, 0, 0] with pytest.raises(NotImplementedError): mo.occsb = [1, 1, 1, 0, 0, 0, 0] with pytest.raises(NotImplementedError): _ = mo.coeffsa with pytest.raises(NotImplementedError): _ = mo.coeffsb with pytest.raises(NotImplementedError): _ = mo.energiesa with pytest.raises(NotImplementedError): _ = mo.energiesb with pytest.raises(NotImplementedError): _ = mo.irrepsa with pytest.raises(NotImplementedError): _ = mo.irrepsb