Skip to content

Commit 6f938d4

Browse files
committed
CrouzeixRaviart: support quad_scheme
1 parent a28c83a commit 6f938d4

File tree

4 files changed

+43
-47
lines changed

4 files changed

+43
-47
lines changed

FIAT/check_format_variant.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def check_format_variant(variant, degree):
3939
extra_degree, = match.groups()
4040
extra_degree = int(extra_degree) if extra_degree is not None else 0
4141
interpolant_degree = degree + extra_degree
42+
if interpolant_degree < degree:
43+
raise ValueError(f"Quadrature degree should be at least {degree}")
4244

4345
if variant not in {"point", "integral"}:
4446
raise ValueError('Choose either variant="point" or variant="integral"'

FIAT/crouzeix_raviart.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111

1212
import numpy
1313
from FIAT import finite_element, polynomial_set, dual_set, functional
14-
from FIAT.check_format_variant import check_format_variant
15-
from FIAT.quadrature_schemes import create_quadrature
14+
from FIAT.check_format_variant import check_format_variant, parse_quadrature_scheme
1615
from FIAT.quadrature import FacetQuadratureRule
1716

1817

1918
class CrouzeixRaviartDualSet(dual_set.DualSet):
2019

21-
def __init__(self, ref_el, degree, variant, interpolant_deg):
20+
def __init__(self, ref_el, degree, variant, interpolant_deg, quad_scheme):
2221
# Get topology dictionary
2322
sd = ref_el.get_spatial_dimension()
2423
top = ref_el.get_topology()
@@ -38,13 +37,14 @@ def __init__(self, ref_el, degree, variant, interpolant_deg):
3837
continue
3938
facet = ref_el.construct_subelement(dim)
4039
if dim == 0:
41-
Q_facet = create_quadrature(facet, degree + interpolant_deg-1)
40+
Q_facet = parse_quadrature_scheme(facet, degree + interpolant_deg-1, quad_scheme)
4241
Phis = numpy.ones((1, len(Q_facet.pts)))
4342
else:
4443
k = degree - 1 if dim == sd-1 else degree - (1+dim)
4544
if k < 0:
4645
continue
47-
Q_facet = create_quadrature(facet, k + interpolant_deg)
46+
Q_facet = parse_quadrature_scheme(facet, k + interpolant_deg, quad_scheme)
47+
4848
poly_set = polynomial_set.ONPolynomialSet(facet, k)
4949
Phis = poly_set.tabulate(Q_facet.get_points())[(0,) * dim]
5050

@@ -80,7 +80,7 @@ class CrouzeixRaviart(finite_element.CiarletElement):
8080
Dual basis: Evaluation at points or integral moments
8181
"""
8282

83-
def __init__(self, ref_el, degree, variant=None):
83+
def __init__(self, ref_el, degree, variant=None, quad_scheme=None):
8484
if degree % 2 != 1:
8585
raise ValueError("Crouzeix-Raviart only defined for odd degree")
8686

@@ -89,5 +89,5 @@ def __init__(self, ref_el, degree, variant=None):
8989
ref_el = splitting(ref_el)
9090

9191
poly_set = polynomial_set.ONPolynomialSet(ref_el, degree)
92-
dual = CrouzeixRaviartDualSet(ref_el, degree, variant, interpolant_deg)
92+
dual = CrouzeixRaviartDualSet(ref_el, degree, variant, interpolant_deg, quad_scheme)
9393
super().__init__(poly_set, dual, degree)

FIAT/hierarchical.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,12 @@ def make_dual_bubbles(ref_el, degree, codim=0, interpolant_deg=None, quad_scheme
2525
if interpolant_deg is None:
2626
interpolant_deg = degree
2727

28-
if interpolant_deg >= degree:
29-
Q = parse_quadrature_scheme(ref_el, degree + interpolant_deg, quad_scheme)
30-
B = make_bubbles(ref_el, degree, codim=codim, scale="orthonormal")
31-
P_at_qpts = B.expansion_set.tabulate(degree, Q.get_points())
32-
M = numpy.dot(numpy.multiply(P_at_qpts, Q.get_weights()), P_at_qpts.T)
33-
phis = numpy.linalg.solve(M, P_at_qpts)
34-
phis = numpy.dot(B.get_coeffs(), phis)
35-
else:
36-
k = max(degree - dim - 1, 0)
37-
Q = parse_quadrature_scheme(ref_el, k + degree, quad_scheme)
38-
P = ONPolynomialSet(ref_el, k, scale="L2 piola")
39-
phis = P.tabulate(Q.get_points())[(0,) * dim]
28+
Q = parse_quadrature_scheme(ref_el, degree + interpolant_deg, quad_scheme)
29+
B = make_bubbles(ref_el, degree, codim=codim, scale="orthonormal")
30+
P_at_qpts = B.expansion_set.tabulate(degree, Q.get_points())
31+
M = numpy.dot(numpy.multiply(P_at_qpts, Q.get_weights()), P_at_qpts.T)
32+
phis = numpy.linalg.solve(M, P_at_qpts)
33+
phis = numpy.dot(B.get_coeffs(), phis)
4034
return Q, phis
4135

4236

finat/fiat_elements.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -296,23 +296,23 @@ def point_evaluation(fiat_element, order, refcoords, entity):
296296

297297

298298
class Regge(FiatElement): # symmetric matrix valued
299-
def __init__(self, cell, degree, variant=None):
300-
super().__init__(FIAT.Regge(cell, degree, variant=variant))
299+
def __init__(self, cell, degree, **kwargs):
300+
super().__init__(FIAT.Regge(cell, degree, **kwargs))
301301

302302

303303
class HellanHerrmannJohnson(FiatElement): # symmetric matrix valued
304-
def __init__(self, cell, degree, variant=None):
305-
super().__init__(FIAT.HellanHerrmannJohnson(cell, degree, variant=variant))
304+
def __init__(self, cell, degree, **kwargs):
305+
super().__init__(FIAT.HellanHerrmannJohnson(cell, degree, **kwargs))
306306

307307

308308
class GopalakrishnanLedererSchoberlFirstKind(FiatElement): # traceless matrix valued
309-
def __init__(self, cell, degree, variant=None):
310-
super().__init__(FIAT.GopalakrishnanLedererSchoberlFirstKind(cell, degree, variant=variant))
309+
def __init__(self, cell, degree, **kwargs):
310+
super().__init__(FIAT.GopalakrishnanLedererSchoberlFirstKind(cell, degree, **kwargs))
311311

312312

313313
class GopalakrishnanLedererSchoberlSecondKind(FiatElement): # traceless matrix valued
314-
def __init__(self, cell, degree, variant=None):
315-
super().__init__(FIAT.GopalakrishnanLedererSchoberlSecondKind(cell, degree, variant=variant))
314+
def __init__(self, cell, degree, **kwargs):
315+
super().__init__(FIAT.GopalakrishnanLedererSchoberlSecondKind(cell, degree, **kwargs))
316316

317317

318318
class ScalarFiatElement(FiatElement):
@@ -328,28 +328,28 @@ def __init__(self, cell, degree):
328328

329329

330330
class Bubble(ScalarFiatElement):
331-
def __init__(self, cell, degree, variant=None):
332-
super().__init__(FIAT.Bubble(cell, degree, variant=variant))
331+
def __init__(self, cell, degree, **kwargs):
332+
super().__init__(FIAT.Bubble(cell, degree, **kwargs))
333333

334334

335335
class FacetBubble(ScalarFiatElement):
336-
def __init__(self, cell, degree, variant=None):
337-
super().__init__(FIAT.FacetBubble(cell, degree, variant=variant))
336+
def __init__(self, cell, degree, **kwargs):
337+
super().__init__(FIAT.FacetBubble(cell, degree, **kwargs))
338338

339339

340340
class CrouzeixRaviart(ScalarFiatElement):
341-
def __init__(self, cell, degree, variant=None):
342-
super().__init__(FIAT.CrouzeixRaviart(cell, degree, variant=variant))
341+
def __init__(self, cell, degree, **kwargs):
342+
super().__init__(FIAT.CrouzeixRaviart(cell, degree, **kwargs))
343343

344344

345345
class Lagrange(ScalarFiatElement):
346-
def __init__(self, cell, degree, variant=None):
347-
super().__init__(FIAT.Lagrange(cell, degree, variant=variant))
346+
def __init__(self, cell, degree, **kwargs):
347+
super().__init__(FIAT.Lagrange(cell, degree, *kwargs))
348348

349349

350350
class DiscontinuousLagrange(ScalarFiatElement):
351-
def __init__(self, cell, degree, variant=None):
352-
super().__init__(FIAT.DiscontinuousLagrange(cell, degree, variant=variant))
351+
def __init__(self, cell, degree, **kwargs):
352+
super().__init__(FIAT.DiscontinuousLagrange(cell, degree, **kwargs))
353353

354354

355355
class Histopolation(ScalarFiatElement):
@@ -377,8 +377,8 @@ def __init__(self, cell, degree):
377377

378378

379379
class HDivTrace(ScalarFiatElement):
380-
def __init__(self, cell, degree, variant=None):
381-
super().__init__(FIAT.HDivTrace(cell, degree, variant=variant))
380+
def __init__(self, cell, degree, **kwargs):
381+
super().__init__(FIAT.HDivTrace(cell, degree, **kwargs))
382382

383383

384384
class VectorFiatElement(FiatElement):
@@ -388,8 +388,8 @@ def value_shape(self):
388388

389389

390390
class RaviartThomas(VectorFiatElement):
391-
def __init__(self, cell, degree, variant=None):
392-
super().__init__(FIAT.RaviartThomas(cell, degree, variant=variant))
391+
def __init__(self, cell, degree, **kwargs):
392+
super().__init__(FIAT.RaviartThomas(cell, degree, **kwargs))
393393

394394

395395
class TrimmedSerendipityFace(VectorFiatElement):
@@ -429,8 +429,8 @@ def entity_permutations(self):
429429

430430

431431
class BrezziDouglasMarini(VectorFiatElement):
432-
def __init__(self, cell, degree, variant=None):
433-
super().__init__(FIAT.BrezziDouglasMarini(cell, degree, variant=variant))
432+
def __init__(self, cell, degree, **kwargs):
433+
super().__init__(FIAT.BrezziDouglasMarini(cell, degree, *kwargs))
434434

435435

436436
class BrezziDouglasMariniCubeEdge(VectorFiatElement):
@@ -457,10 +457,10 @@ def __init__(self, cell, degree):
457457

458458

459459
class Nedelec(VectorFiatElement):
460-
def __init__(self, cell, degree, variant=None):
461-
super().__init__(FIAT.Nedelec(cell, degree, variant=variant))
460+
def __init__(self, cell, degree, **kwargs):
461+
super().__init__(FIAT.Nedelec(cell, degree, **kwargs))
462462

463463

464464
class NedelecSecondKind(VectorFiatElement):
465-
def __init__(self, cell, degree, variant=None):
466-
super().__init__(FIAT.NedelecSecondKind(cell, degree, variant=variant))
465+
def __init__(self, cell, degree, **kwargs):
466+
super().__init__(FIAT.NedelecSecondKind(cell, degree, **kwargs))

0 commit comments

Comments
 (0)