Skip to content

Commit adbaf93

Browse files
authored
Test that basis functions are independent (#84)
* add test that the basis functions are linearly independent * adjust parameters for direct serendipity * only run independence test for DirectElements, as Ciarlet elements are guaranteed to be independent
1 parent 00fd908 commit adbaf93

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

symfem/elements/direct_serendipity.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ def __init__(self, reference, order, variant):
2323
# Functions on edges
2424
if order >= 2:
2525
alpha_h = 1
26-
beta_h = 1
26+
beta_h = 2
2727
gamma_h = 1
28-
xi_h = 1
28+
xi_h = 2
2929
eta_h = 1
3030

3131
alpha_v = 1
32-
beta_v = 1
32+
beta_v = 2
3333
gamma_v = 1
34-
xi_v = 1
34+
xi_v = 2
3535
eta_v = 1
3636

3737
lambda_h = alpha_h * (1 - x[1]) + beta_h * x[1] + gamma_h

test/test_elements.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sympy
33
import symfem
44
from symfem import create_element
5-
from symfem.core.finite_element import CiarletElement
5+
from symfem.core.finite_element import CiarletElement, DirectElement
66
from symfem.core.symbolic import subs, x, PiecewiseFunction
77
from symfem.core.vectors import vsub
88
from utils import test_elements, all_symequal
@@ -20,6 +20,67 @@ def test_all_tested():
2020
raise ValueError(f"{e.names[0]} on a {r} is not tested")
2121

2222

23+
@pytest.mark.parametrize(
24+
("cell_type", "element_type", "order", "variant"),
25+
[[reference, element, order, variant]
26+
for reference, i in test_elements.items() for element, j in i.items()
27+
for variant, k in j.items() for order in k])
28+
def test_independence(
29+
elements_to_test, cells_to_test, cell_type, element_type, order, variant,
30+
speed
31+
):
32+
"""Test that DirectElements have independent basis functions."""
33+
if elements_to_test != "ALL" and element_type not in elements_to_test:
34+
pytest.skip()
35+
if cells_to_test != "ALL" and cell_type not in cells_to_test:
36+
pytest.skip()
37+
if speed == "fast":
38+
if order > 2:
39+
pytest.skip()
40+
if order == 2 and cell_type in ["tetrahedron", "hexahedron", "prism", "pyramid"]:
41+
pytest.skip()
42+
43+
space = create_element(cell_type, element_type, order, variant)
44+
45+
# Only run this test for DirectElements
46+
if not isinstance(space, DirectElement):
47+
pytest.skip()
48+
49+
basis = space.get_basis_functions()
50+
all_terms = set()
51+
52+
try:
53+
basis[0].as_coefficients_dict()
54+
scalar = True
55+
except AttributeError:
56+
scalar = False
57+
58+
if scalar:
59+
for f in basis:
60+
for term in f.as_coefficients_dict():
61+
all_terms.add(term)
62+
mat = [[0 for i in all_terms] for j in basis]
63+
for i, t in enumerate(all_terms):
64+
for j, f in enumerate(basis):
65+
fd = f.as_coefficients_dict()
66+
if t in fd:
67+
mat[j][i] = fd[t]
68+
else:
69+
for f in basis:
70+
for fi, fpart in enumerate(f):
71+
for term in fpart.as_coefficients_dict():
72+
all_terms.add((fi, term))
73+
mat = [[0 for i in all_terms] for j in basis]
74+
for i, (fi, t) in enumerate(all_terms):
75+
for j, f in enumerate(basis):
76+
fd = f[fi].as_coefficients_dict()
77+
if t in fd:
78+
mat[j][i] = fd[t]
79+
mat = sympy.Matrix(mat)
80+
81+
assert mat.rank() == mat.rows
82+
83+
2384
@pytest.mark.parametrize(
2485
("cell_type", "element_type", "order", "variant"),
2586
[[reference, element, order, variant]

test/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"matrix discontinuous Lagrange": {"equispaced": range(3), "lobatto": range(3)},
2828
"symmetric matrix discontinuous Lagrange": {
2929
"equispaced": range(3), "lobatto": range(3)},
30-
"bubble": {"equispaced": range(2, 5), "lobatto": range(2, 3)},
30+
"bubble": {"equispaced": range(3, 5), "lobatto": range(3, 3)},
3131
"bubble enriched Lagrange": {"equispaced": range(1, 3), "lobatto": range(1, 3)},
3232
"bubble enriched vector Lagrange":
3333
{"equispaced": range(1, 3), "lobatto": range(1, 3)},
@@ -60,7 +60,7 @@
6060
"vP": {"equispaced": range(3), "lobatto": range(3)},
6161
"matrix discontinuous Lagrange": {"equispaced": range(2), "lobatto": range(3)},
6262
"symmetric matrix discontinuous Lagrange": {"equispaced": range(2), "lobatto": range(3)},
63-
"bubble": {"equispaced": [3], "lobatto": [3]},
63+
"bubble": {"equispaced": [4], "lobatto": [4]},
6464
"CR": {"equispaced": [1]},
6565
"Regge": {None: range(3)},
6666
"Nedelec1": {"equispaced": range(1, 3)},

0 commit comments

Comments
 (0)