1import numpy as np
2import pytest
4from cymsim.mesh import disk_mesh
8def test_disk_mesh_is_a_valid_manifold(h):
9 R = 0.2286
10 m = disk_mesh(R, h)
11 assert (m.area > 0).all()
12 # polygon area approaches pi R^2 from below
13 assert 0.98 * np.pi * R**2 < m.area.sum() <= np.pi * R**2 + 1e-12
14 edges = np.sort(np.concatenate([m.tri[:, [0, 1]], m.tri[:, [1, 2]], m.tri[:, [2, 0]]]), axis=1)
15 _, count = np.unique(edges, axis=0, return_counts=True)
16 assert set(count) == {1, 2} # interior edges shared by two triangles
17 assert (count == 1).sum() == len(m.boundary) # boundary edges = rim nodes
18 assert np.allclose(np.hypot(*m.xy[m.boundary].T), R)
19 # element quality: inradius / circumradius, 1 for equilateral
20 L = m.edge_lengths()
21 a, b, c = L.T
22 s = (a + b + c) / 2
23 q = 8 * (s - a) * (s - b) * (s - c) / (a * b * c)
24 assert q.min() > 0.5
25 assert 0.5 * h < L.mean() < 1.5 * h
28def test_cst_gradient_is_exact_for_linear_fields():
29 m = disk_mesh(0.2, 0.03)
30 f = 2.0 * m.xy[:, 0] - 3.0 * m.xy[:, 1] + 1.0
31 fe = f[m.tri]
32 assert np.allclose((m.Gx * fe).sum(1), 2.0)
33 assert np.allclose((m.Gy * fe).sum(1), -3.0)
36def test_locate_and_interpolate():
37 m = disk_mesh(0.2, 0.03)
38 f = m.xy[:, 0] ** 1 + 0.5 * m.xy[:, 1]
39 nodes, w = m.locate(0.05, -0.07)
40 assert np.isclose(w.sum(), 1.0) and (w >= -1e-9).all()
41 assert np.isclose(m.interpolate(f, 0.05, -0.07), 0.05 - 0.035)
42 with pytest.raises(ValueError):
43 m.locate(0.3, 0.0)