Peano
Loading...
Searching...
No Matches
test_sfc.py
Go to the documentation of this file.
1import pytest
2
3from toolbox.loadbalancing.api.strategies.SFC import (
4 Cartesian_to_Peano_2d,
5 Peano_to_Cartesian_2d,
6 Cartesian_to_Peano_3d,
7 Peano_to_Cartesian_3d,
8)
9
10
11# ---------------------------------------------------------------------------
12# 2D: docstring example
13# ---------------------------------------------------------------------------
14
16 """Docstring example: (4, 2) with size=9 must map to 10."""
17 assert Cartesian_to_Peano_2d((4, 2), 9) == 10
18
19
21 """Inverse of docstring example: index 10 with size=9 must map to (4, 2)."""
22 assert Peano_to_Cartesian_2d(10, 9) == (4, 2)
23
24
25# ---------------------------------------------------------------------------
26# 2D: base case (size=1)
27# ---------------------------------------------------------------------------
28
30 assert Cartesian_to_Peano_2d((0, 0), 1) == 0
31
32
34 assert Peano_to_Cartesian_2d(0, 1) == (0, 0)
35
36
37# ---------------------------------------------------------------------------
38# 2D: bijection and round-trip for size=3 and size=9
39# ---------------------------------------------------------------------------
40
41@pytest.mark.parametrize("size", [3, 9])
43 """Every cell maps to a unique index in [0, size²)."""
44 seen = set()
45 for x in range(size):
46 for y in range(size):
47 idx = Cartesian_to_Peano_2d((x, y), size)
48 assert 0 <= idx < size * size, f"Index {idx} out of range for ({x},{y})"
49 assert idx not in seen, f"Duplicate index {idx} for ({x},{y})"
50 seen.add(idx)
51 assert len(seen) == size * size
52
53
54@pytest.mark.parametrize("size", [3, 9])
56 """Forward then inverse returns the original coordinates for all cells."""
57 for x in range(size):
58 for y in range(size):
59 idx = Cartesian_to_Peano_2d((x, y), size)
60 assert Peano_to_Cartesian_2d(idx, size) == (x, y), (
61 f"Round-trip failed for ({x},{y}): got {Peano_to_Cartesian_2d(idx, size)}"
62 )
63
64
65# ---------------------------------------------------------------------------
66# 3D: base case (size=1)
67# ---------------------------------------------------------------------------
68
70 assert Cartesian_to_Peano_3d((0, 0, 0), 1) == 0
71
72
74 assert Peano_to_Cartesian_3d(0, 1) == (0, 0, 0)
75
76
77# ---------------------------------------------------------------------------
78# 3D: bijection and round-trip for size=3 (and size=9 marked slow)
79# ---------------------------------------------------------------------------
80
81@pytest.mark.parametrize("size", [3])
83 """Every 3-D cell maps to a unique index in [0, size³)."""
84 seen = set()
85 for x in range(size):
86 for y in range(size):
87 for z in range(size):
88 idx = Cartesian_to_Peano_3d((x, y, z), size)
89 assert 0 <= idx < size ** 3, f"Index {idx} out of range for ({x},{y},{z})"
90 assert idx not in seen, f"Duplicate index {idx} for ({x},{y},{z})"
91 seen.add(idx)
92 assert len(seen) == size ** 3
93
94
95@pytest.mark.parametrize("size", [3])
97 """Forward then inverse returns the original coordinates for all 3-D cells."""
98 for x in range(size):
99 for y in range(size):
100 for z in range(size):
101 idx = Cartesian_to_Peano_3d((x, y, z), size)
102 assert Peano_to_Cartesian_3d(idx, size) == (x, y, z), (
103 f"Round-trip failed for ({x},{y},{z}): "
104 f"got {Peano_to_Cartesian_3d(idx, size)}"
105 )
106
107
108@pytest.mark.slow
110 """Full bijection check for size=9 (729 cells); marked slow."""
111 size = 9
112 seen = set()
113 for x in range(size):
114 for y in range(size):
115 for z in range(size):
116 idx = Cartesian_to_Peano_3d((x, y, z), size)
117 assert 0 <= idx < size ** 3
118 assert idx not in seen, f"Duplicate index {idx} for ({x},{y},{z})"
119 seen.add(idx)
120 assert len(seen) == size ** 3
121
122
123@pytest.mark.slow
125 """Round-trip check for size=9 (729 cells); marked slow."""
126 size = 9
127 for x in range(size):
128 for y in range(size):
129 for z in range(size):
130 idx = Cartesian_to_Peano_3d((x, y, z), size)
131 assert Peano_to_Cartesian_3d(idx, size) == (x, y, z)
132
133
134# ---------------------------------------------------------------------------
135# The curve has to match Peano's spacetree traversal
136# ---------------------------------------------------------------------------
137
138import os
139import re
140
141from toolbox.loadbalancing.api.strategies.SFC import _children_in_traversal_order
142
143
144def _peano_zfor3_tables(dimensions):
145 """Read the lookup tables of zfor3 from src/peano4/utils/Loop.h"""
146 loop_header = os.path.join(
147 os.path.dirname(__file__), "..", "..", "src", "peano4", "utils", "Loop.h"
148 )
149 with open(loop_header) as header:
150 text = header.read()
151 children = 3**dimensions
152 start = text.index(
153 "static const int lookupzfor3[{}][{}][{}]".format(2**dimensions, children, dimensions)
154 )
155 block = text[start : text.index("};", start)]
156 entries = [
157 tuple(int(value) for value in entry.split(","))
158 for entry in re.findall(r"\{(\d+(?:,\s*\d+)+)\}", block)
159 ]
160 return [entries[i * children : (i + 1) * children] for i in range(2**dimensions)]
161
162
163@pytest.mark.parametrize("dimensions", [2, 3])
165 """The order of the 3^d children replicates peano4::utils::zfor3 for all loop directions."""
166 for direction, table in enumerate(_peano_zfor3_tables(dimensions)):
167 positive = tuple(bool(direction >> axis & 1) for axis in range(dimensions))
168 assert list(_children_in_traversal_order(positive)) == table
169
170
171@pytest.mark.parametrize("size", [3, 9, 27])
173 """Consecutive cells along the curve share a face, i.e. the curve has no jumps."""
174 cells = [Peano_to_Cartesian_2d(i, size) for i in range(size * size)]
175 for a, b in zip(cells, cells[1:]):
176 assert abs(a[0] - b[0]) + abs(a[1] - b[1]) == 1, (a, b)
177
178
179@pytest.mark.parametrize("size", [3, 9])
181 """Consecutive cells along the curve share a face, i.e. the curve has no jumps."""
182 cells = [Peano_to_Cartesian_3d(i, size) for i in range(size**3)]
183 for a, b in zip(cells, cells[1:]):
184 assert sum(abs(x - y) for x, y in zip(a, b)) == 1, (a, b)
test_peano_to_cartesian_2d_size1()
Definition test_sfc.py:33
test_peano_to_cartesian_2d_round_trip(size)
Forward then inverse returns the original coordinates for all cells.
Definition test_sfc.py:55
test_cartesian_to_peano_3d_bijection_size9()
Full bijection check for size=9 (729 cells); marked slow.
Definition test_sfc.py:109
test_peano_to_cartesian_3d_size1()
Definition test_sfc.py:73
test_peano_to_cartesian_3d_round_trip_size9()
Round-trip check for size=9 (729 cells); marked slow.
Definition test_sfc.py:124
test_cartesian_to_peano_2d_bijection(size)
Every cell maps to a unique index in [0, size²).
Definition test_sfc.py:42
test_cartesian_to_peano_3d_size1()
Definition test_sfc.py:69
test_curve_2d_is_continuous(size)
Consecutive cells along the curve share a face, i.e.
Definition test_sfc.py:172
test_cartesian_to_peano_3d_bijection(size)
Every 3-D cell maps to a unique index in [0, size³).
Definition test_sfc.py:82
test_curve_3d_is_continuous(size)
Consecutive cells along the curve share a face, i.e.
Definition test_sfc.py:180
_peano_zfor3_tables(dimensions)
Read the lookup tables of zfor3 from src/peano4/utils/Loop.h.
Definition test_sfc.py:144
test_children_order_matches_peano_zfor3(dimensions)
The order of the 3^d children replicates peano4::utils::zfor3 for all loop directions.
Definition test_sfc.py:164
test_cartesian_to_peano_2d_size1()
Definition test_sfc.py:29
test_peano_to_cartesian_2d_docstring_example()
Inverse of docstring example: index 10 with size=9 must map to (4, 2).
Definition test_sfc.py:20
test_peano_to_cartesian_3d_round_trip(size)
Forward then inverse returns the original coordinates for all 3-D cells.
Definition test_sfc.py:96
test_cartesian_to_peano_2d_docstring_example()
Docstring example: (4, 2) with size=9 must map to 10.
Definition test_sfc.py:15