File: test_cell.py

package info (click to toggle)
python-ase 3.26.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,484 kB
  • sloc: python: 148,112; xml: 2,728; makefile: 110; javascript: 47
file content (111 lines) | stat: -rw-r--r-- 2,838 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# fmt: off
import numpy as np
import pytest

from ase.cell import Cell

testcellpar = (2, 3, 4, 50, 60, 70)


@pytest.fixture()
def cell():
    return Cell.new(testcellpar)


def test_lengths_angles(cell):
    assert cell.cellpar() == pytest.approx(testcellpar)
    assert cell.lengths() == pytest.approx(testcellpar[:3])
    assert cell.angles() == pytest.approx(testcellpar[3:])


def test_new():
    assert np.array_equal(Cell.new(), np.zeros((3, 3)))
    assert np.array_equal(Cell.new([1, 2, 3]), np.diag([1, 2, 3]))
    assert Cell.new(testcellpar).cellpar() == pytest.approx(testcellpar)
    arr = np.arange(9).reshape(3, 3)
    assert np.array_equal(Cell.new(arr), arr)
    with pytest.raises(ValueError):
        Cell.new([1, 2, 3, 4])


def test_handedness(cell):
    assert cell.handedness == 1
    cell[0] *= -1
    assert cell.handedness == -1
    cell[0] = 0
    assert cell.handedness == 0


@pytest.fixture()
def randcell():
    rng = np.random.RandomState(42)
    return Cell(rng.random((3, 3)))


def test_normal(randcell):
    normals = randcell.normals()

    for i in range(3):
        normal = randcell.normal(i)
        assert normal == pytest.approx(normals[i])

        for j in range(3):
            if i == j:
                ref = np.cross(randcell[j - 2], randcell[j - 1])
                assert normal == pytest.approx(ref)
            else:
                assert abs(randcell[j] @ normal) < 1e-14


def test_area(randcell):
    areas = randcell.areas()
    for i in range(3):
        area = randcell.area(i)
        assert area == pytest.approx(areas[i])
        randcell[i - 2] @ randcell[i - 1]


@pytest.mark.parametrize(
    'zeromask',
    [[], [1], [0, 2], [0, 1, 2]],
    ids=lambda mask: f'dim={3 - len(mask)}'
)
def test_reciprocal_ndim(randcell, zeromask):
    randcell[zeromask] = 0
    ndim = 3 - len(zeromask)
    assert randcell.rank == ndim
    reciprocal = randcell.reciprocal()
    assert reciprocal.rank == ndim

    ref = np.identity(3)
    ref[zeromask] = 0
    assert reciprocal @ randcell.T == pytest.approx(ref)


def test_total_area(randcell):
    lengths = randcell.lengths()
    sin_angles = np.sin(np.radians(randcell.angles()))
    areas = randcell.areas()

    for i in range(3):
        area = lengths[i - 2] * lengths[i - 1] * sin_angles[i]
        assert area == pytest.approx(areas[i])


def test_cell_edit_via_view():
    cell = Cell(np.arange(9).reshape(3, 3))

    # np.reshape() is a no-op so it should not copy by default:
    arr = np.reshape(cell, (3, 3))
    arr[-1] = 42
    assert cell[-1, -1] == 42

    # np.array() should copy, so edit will not be inplace:
    cell1 = np.array(cell)
    cell1[-1, -1] = 64
    assert cell[-1, -1] == 42

    # This should be in-place:
    cell1 = np.array(cell, copy=False)
    cell[-1, -1] = 64
    assert cell[-1, -1] == 64