Repository: mscroggs/symfem

Issue:
Bell element is incorrect
see https://github.com/mscroggs/defelement.com/issues/224

Discussion:
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=mscroggs_symfem&pullRequest=229)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=mscroggs_symfem&pullRequest=229)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=mscroggs_symfem&pullRequest=229)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=mscroggs_symfem&pullRequest=229&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=mscroggs_symfem&pullRequest=229&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=mscroggs_symfem&pullRequest=229&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/CHANGELOG_SINCE_LAST_VERSION.md b/CHANGELOG_SINCE_LAST_VERSION.md
index 1ccf031..74e4f28 100644
--- a/CHANGELOG_SINCE_LAST_VERSION.md
+++ b/CHANGELOG_SINCE_LAST_VERSION.md
@@ -4,3 +4,4 @@
 - Added Alfeld-Sorokina element
 - Corrected C1 and higher order C tests
 - Allow element creation on non-default references
+- Corrected Bell element
diff --git a/symfem/elements/bell.py b/symfem/elements/bell.py
index 11c91b9..6c4bba8 100644
--- a/symfem/elements/bell.py
+++ b/symfem/elements/bell.py
@@ -6,13 +6,11 @@ This element's definition is given in https://doi.org/10.1002/nme.1620010108 (Be
 import typing
 
 from ..finite_element import CiarletElement
-from ..functionals import (DerivativePointEvaluation, ListOfFunctionals,
-                           NormalDerivativeIntegralMoment, PointEvaluation)
+from ..functionals import DerivativePointEvaluation, ListOfFunctionals, PointEvaluation
 from ..functions import FunctionInput
-from ..moments import make_integral_moment_dofs
 from ..polynomials import polynomial_set_1d
 from ..references import Reference
-from .lagrange import Lagrange
+from ..symbols import x
 
 
 class Bell(CiarletElement):
@@ -36,14 +34,13 @@ class Bell(CiarletElement):
             dofs.append(DerivativePointEvaluation(reference, v, (2, 0), entity=(0, v_n)))
             dofs.append(DerivativePointEvaluation(reference, v, (1, 1), entity=(0, v_n)))
             dofs.append(DerivativePointEvaluation(reference, v, (0, 2), entity=(0, v_n)))
-        dofs += make_integral_moment_dofs(
-            reference,
-            edges=(NormalDerivativeIntegralMoment, Lagrange, 0, {"variant": variant}),
-        )
         self.variant = variant
 
         poly: typing.List[FunctionInput] = []
-        poly += polynomial_set_1d(reference.tdim, order)
+        poly += polynomial_set_1d(reference.tdim, 4)
+        poly.append(x[0]**5 - x[1]**5)
+        poly.append(x[0]**3*x[1]**2 - x[0]**2*x[1]**3)
+        poly.append(5*x[0]**2*x[1]**3 - x[0]**5)
 
         super().__init__(reference, order, poly, dofs, reference.tdim, 1)
 


Test patch:
diff --git a/test/test_bell.py b/test/test_bell.py
new file mode 100644
index 0000000..ced4516
--- /dev/null
+++ b/test/test_bell.py
@@ -0,0 +1,18 @@
+"""Test Bell elements."""
+
+import symfem
+from symfem.symbols import t, x
+
+
+def test_bell_polyset():
+    b = symfem.create_element("triangle", "Bell", 5)
+    for p in b.get_polynomial_basis():
+        gradp = [p.diff(x[0]), p.diff(x[1])]
+        for en in range(b.reference.sub_entity_count(1)):
+            edge = b.reference.sub_entity(1, en)
+            variables = [o + sum(a[i] * t[0] for a in edge.axes)
+                         for i, o in enumerate(edge.origin)]
+            n = edge.normal()
+            normal_deriv = gradp[0] * n[0] + gradp[1] * n[1]
+            normal_deriv = normal_deriv.subs(x, variables)
+            assert normal_deriv.diff(t[0]).diff(t[0]).diff(t[0]).diff(t[0]) == 0