Skip to content

Commit b530be6

Browse files
authored
Add iso macroelement on an interval (#680)
* Add polyset::type input to all polyset functions, pass standard in everywhere for now * Add polyset_type input to FiniteElement constructor * implement quadrature for macro element on interval * implement macro polyset on an interval * Add test, update demos, clang format * update _basixcpp.pyi * tabulate_polynomial_set * Remove overload of make_quadrature, add python function with optional args instead * default value * flake8 * correct _basixcpp.pyi * rule= * update demos * flake8 * flake8 * Add new element to test_create * update README * dolfinx branch * Add polyset_type input to custom element * flake * _ * implement polyset_type for more elements * update tests * pt -> ptype * update _basixcpp.pyi * update demos * document arg * add "iso" to family strings * _basixcpp.pyi * move basix.quadrature.make_quadrature back to basix.make_quadrature
1 parent 0fc130f commit b530be6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1186
-448
lines changed

.github/workflows/dolfin-tests.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
if: github.event_name != 'workflow_dispatch'
5252
run: |
5353
python3 -m pip install git+https://github.com/FEniCS/ufl.git
54-
python3 -m pip install git+https://github.com/FEniCS/ffcx.git
54+
python3 -m pip install git+https://github.com/FEniCS/ffcx.git@mscroggs/make_quadrature
5555
- name: Install FEniCS Python components
5656
if: github.event_name == 'workflow_dispatch'
5757
run: |
@@ -64,7 +64,7 @@ jobs:
6464
with:
6565
path: ./dolfinx
6666
repository: FEniCS/dolfinx
67-
ref: main
67+
ref: mscroggs/make_quadrature
6868
- name: Get DOLFINx
6969
if: github.event_name == 'workflow_dispatch'
7070
uses: actions/checkout@v3

.github/workflows/ffcx-tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
with:
5555
path: ./ffcx
5656
repository: FEniCS/ffcx
57-
ref: main
57+
ref: mscroggs/make_quadrature
5858
- name: Get FFCx source (specified branch)
5959
if: github.event_name == 'workflow_dispatch'
6060
uses: actions/checkout@v3

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ The following elements are supported on an interval:
7171
- [Bubble](https://defelement.com/elements/bubble.html)
7272
- [Serendipity](https://defelement.com/elements/serendipity.html)
7373
- [Hermite](https://defelement.com/elements/hermite.html)
74-
74+
- [iso](https://defelement.com/elements/p1-iso-p2.html)
7575

7676
### Triangle
7777

cpp/basix/docs.h

+59-39
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Sub-entity of a cell, given by topological dimension and index
5454
)";
5555

5656
const std::string create_lattice__celltype_n_type_exterior = R"(
57-
@brief Create a lattice of points on a reference cell optionally
57+
Create a lattice of points on a reference cell optionally
5858
including the outer surface points.
5959
6060
For a given `celltype`, this creates a set of points on a regular
@@ -80,7 +80,7 @@ type::equispaced when `n < 3`.
8080
)";
8181

8282
const std::string create_lattice__celltype_n_type_exterior_method = R"(
83-
@brief Create a lattice of points on a reference cell optionally
83+
Create a lattice of points on a reference cell optionally
8484
including the outer surface points.
8585
8686
For a given `celltype`, this creates a set of points on a regular
@@ -169,7 +169,7 @@ Get the jacobians of the facets of a reference cell
169169
)";
170170

171171
const std::string FiniteElement__tabulate = R"(
172-
@brief Compute basis values and derivatives at set of points.
172+
Compute basis values and derivatives at set of points.
173173
174174
NOTE: The version of `FiniteElement::tabulate` with the basis data
175175
as an out argument should be preferred for repeated call where
@@ -270,7 +270,7 @@ performance is critical.
270270
)";
271271

272272
const std::string FiniteElement__base_transformations = R"(
273-
@brief Get the base transformations.
273+
Get the base transformations.
274274
275275
The base transformations represent the effect of rotating or reflecting
276276
a subentity of the cell on the numbering and orientation of the DOFs.
@@ -409,6 +409,7 @@ Create a custom finite element
409409
discontinuous: Indicates whether or not this is the discontinuous version of the element
410410
highest_complete_degree: The highest degree n such that a Lagrange (or vector Lagrange) element of degree n is a subspace of this element
411411
highest_degree: The degree of a polynomial in this element's polyset
412+
poly_type: The type of polyset to use for this element
412413
413414
Returns:
414415
A custom finite element
@@ -434,30 +435,30 @@ Create an element using a given Lagrange variant and a given DPC variant
434435
)";
435436

436437
const std::string compute_interpolation_operator = R"(
437-
Computes a matrix that represents the interpolation between two
438-
elements.
438+
Compute a matrix that represents the interpolation between
439+
two elements.
439440
440441
If the two elements have the same value size, this function returns
441442
the interpolation between them.
442443
443-
If element_from has value size 1 and element_to has value size > 1, then
444-
this function returns a matrix to interpolate from a blocked element_from
445-
(ie multiple copies of element_from) into element_to.
444+
If element_from has value size 1 and element_to has value size > 1,
445+
then this function returns a matrix to interpolate from a blocked
446+
element_from (ie multiple copies of element_from) into element_to.
446447
447-
If element_to has value size 1 and element_from has value size > 1, then
448-
this function returns a matrix that interpolates the components of
449-
element_from into copies of element_to.
448+
If element_to has value size 1 and element_from has value size > 1,
449+
then this function returns a matrix that interpolates the components
450+
of element_from into copies of element_to.
450451
451452
NOTE: If the elements have different value sizes and both are
452453
greater than 1, this function throws a runtime error
453454
454-
In order to interpolate functions between finite element spaces on arbitrary
455-
cells, the functions must be pulled back to the reference element (this pull
456-
back includes applying DOF transformations). The matrix that this function
457-
returns can then be applied, then the result pushed forward to the cell. If
458-
element_from and element_to have the same map type, then only the DOF
459-
transformations need to be applied, as the pull back and push forward cancel
460-
each other out.
455+
In order to interpolate functions between finite element spaces on
456+
arbitrary cells, the functions must be pulled back to the reference
457+
element (this pull back includes applying DOF transformations). The
458+
matrix that this function returns can then be applied, then the
459+
result pushed forward to the cell. If element_from and element_to
460+
have the same map type, then only the DOF transformations need to be
461+
applied, as the pull back and push forward cancel each other out.
461462
462463
Args:
463464
element_from: The element to interpolate from
@@ -470,7 +471,7 @@ each other out.
470471
)";
471472

472473
const std::string tabulate_polynomial_set = R"(
473-
@brief Tabulate the orthonormal polynomial basis, and derivatives,
474+
Tabulate the orthonormal polynomial basis, and derivatives,
474475
at points on the reference cell.
475476
476477
All derivatives up to the given order are computed. If derivatives
@@ -486,6 +487,7 @@ there are `(nderiv + 1)(nderiv + 2)(nderiv + 3)/6`. The ordering is
486487
487488
Args:
488489
celltype: Cell type
490+
ptype: The polynomial type
489491
d: Polynomial degree
490492
n: Maximum derivative order. Use n = 0 for the basis only.
491493
x: Points at which to evaluate the basis. The shape is (number of points, geometric dimension).
@@ -512,7 +514,7 @@ there are `(nderiv + 1)(nderiv + 2)(nderiv + 3)/6`. The ordering is
512514
)";
513515

514516
const std::string tabulate_polynomials = R"(
515-
@brief Tabulate a set of polynomials.
517+
Tabulate a set of polynomials.
516518
517519
Args:
518520
polytype: Polynomial type
@@ -526,7 +528,7 @@ const std::string tabulate_polynomials = R"(
526528
)";
527529

528530
const std::string polynomials_dim = R"(
529-
@brief Dimension of a polynomial space.
531+
Dimension of a polynomial space.
530532
531533
Args:
532534
polytype: The polynomial type
@@ -538,24 +540,13 @@ const std::string polynomials_dim = R"(
538540
polynomial degree @p d
539541
)";
540542

541-
const std::string make_quadrature__rule_celltype_m = R"(
543+
const std::string make_quadrature__rule_celltype_polytype_m = R"(
542544
Make a quadrature rule on a reference cell
543545
544546
Args:
545547
rule: Type of quadrature rule (or use quadrature::Default)
546548
celltype: The cell type
547-
m: Maximum degree of polynomial that this quadrature rule will integrate exactly
548-
549-
Returns:
550-
List of points and list of weights. The number of points
551-
arrays has shape (num points, gdim)
552-
)";
553-
554-
const std::string make_quadrature__celltype_m = R"(
555-
Make a default quadrature rule on reference cell
556-
557-
Args:
558-
celltype: The cell type
549+
polytype: The polyset type
559550
m: Maximum degree of polynomial that this quadrature rule will integrate exactly
560551
561552
Returns:
@@ -574,9 +565,9 @@ Compute trivial indexing in a 1D array (for completeness)
574565
)";
575566

576567
const std::string index__p_q = R"(
577-
Compute indexing in a 2D triangular array compressed into a 1D array.
578-
This can be used to find the index of a derivative returned by
579-
`FiniteElement::tabulate`. For instance to find d2N/dx2, use
568+
Compute indexing in a 2D triangular array compressed into a 1D
569+
array. This can be used to find the index of a derivative returned
570+
by `FiniteElement::tabulate`. For instance to find d2N/dx2, use
580571
`FiniteElement::tabulate(2, points)[idx(2, 0)];`
581572
582573
Args:
@@ -588,7 +579,8 @@ This can be used to find the index of a derivative returned by
588579
)";
589580

590581
const std::string index__p_q_r = R"(
591-
Compute indexing in a 3D tetrahedral array compressed into a 1D array
582+
Compute indexing in a 3D tetrahedral array compressed into a 1D
583+
array
592584
593585
Args:
594586
p: Index in x
@@ -610,4 +602,32 @@ Get the intersection of two Sobolev spaces.
610602
Intersection of the spaces
611603
)";
612604

605+
const std::string superset = R"(
606+
Get the polyset types that is a superset of two types on the given
607+
cell
608+
609+
Args:
610+
cell: The cell type
611+
type1: The first polyset type
612+
type2: The second polyset type
613+
614+
Returns::
615+
The superset type
616+
)";
617+
618+
const std::string restriction = R"(
619+
Get the polyset type that represents the restrictions of a type on a
620+
subentity
621+
622+
Args:
623+
ptype: The polyset type
624+
cell: The cell type
625+
restriction_cell: The cell type of the subentity
626+
627+
Returns::
628+
The restricted polyset type
629+
)";
630+
631+
632+
613633
} // namespace basix::docstring

cpp/basix/dof-transformations.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ std::pair<std::vector<T>, std::array<std::size_t, 2>> compute_transformation(
327327

328328
const std::size_t ndofs = imat.extent(0);
329329
const std::size_t npts = pts.extent(0);
330-
const int psize = polyset::dim(cell_type, degree);
330+
const int psize = polyset::dim(cell_type, polyset::type::standard, degree);
331331

332332
std::size_t dofstart = 0;
333333
for (int d = 0; d < tdim; ++d)
@@ -352,7 +352,7 @@ std::pair<std::vector<T>, std::array<std::size_t, 2>> compute_transformation(
352352
}
353353

354354
auto [polyset_vals_b, polyset_shape] = polyset::tabulate(
355-
cell_type, degree, 0,
355+
cell_type, polyset::type::standard, degree, 0,
356356
mdspan_t<const T, 2>(mapped_pts.data(), mapped_pts.extents()));
357357
assert(polyset_shape[0] == 1);
358358
mdspan_t<const T, 2> polyset_vals(polyset_vals_b.data(), polyset_shape[1],

cpp/basix/e-brezzi-douglas-marini.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ FiniteElement<T> element::create_bdm(cell::type celltype, int degree,
4141
= create_lagrange<T>(facettype, degree, lvariant, true);
4242
{
4343
auto [_x, xshape, _M, Mshape] = moments::make_normal_integral_moments<T>(
44-
facet_moment_space, celltype, tdim, degree * 2);
44+
facet_moment_space, celltype, polyset::type::standard, tdim,
45+
degree * 2);
4546
assert(_x.size() == _M.size());
4647
for (std::size_t i = 0; i < _x.size(); ++i)
4748
{
@@ -56,8 +57,8 @@ FiniteElement<T> element::create_bdm(cell::type celltype, int degree,
5657
{
5758
// Interior integral moment
5859
auto [_x, xshape, _M, Mshape] = moments::make_dot_integral_moments<T>(
59-
create_nedelec<T>(celltype, degree - 1, lvariant, true), celltype, tdim,
60-
2 * degree - 1);
60+
create_nedelec<T>(celltype, degree - 1, lvariant, true), celltype,
61+
polyset::type::standard, tdim, 2 * degree - 1);
6162
assert(_x.size() == _M.size());
6263
for (std::size_t i = 0; i < _x.size(); ++i)
6364
{
@@ -90,11 +91,12 @@ FiniteElement<T> element::create_bdm(cell::type celltype, int degree,
9091
}
9192

9293
// The number of order (degree) scalar polynomials
93-
const std::size_t ndofs = tdim * polyset::dim(celltype, degree);
94+
const std::size_t ndofs
95+
= tdim * polyset::dim(celltype, polyset::type::standard, degree);
9496
sobolev::space space
9597
= discontinuous ? sobolev::space::L2 : sobolev::space::HDiv;
9698
return FiniteElement<T>(
97-
family::BDM, celltype, degree, {tdim},
99+
family::BDM, celltype, polyset::type::standard, degree, {tdim},
98100
impl::mdspan_t<T, 2>(math::eye<T>(ndofs).data(), ndofs, ndofs), xview,
99101
Mview, 0, maps::type::contravariantPiola, space, discontinuous, degree,
100102
degree, lvariant, element::dpc_variant::unset);

cpp/basix/e-bubble.cpp

+17-10
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
6767

6868
// Evaluate the expansion polynomials at the quadrature points
6969
const auto [_pts, wts] = quadrature::make_quadrature<T>(
70-
quadrature::type::Default, celltype, 2 * degree);
70+
quadrature::type::Default, celltype, polyset::type::standard, 2 * degree);
7171
impl::mdspan_t<const T, 2> pts(_pts.data(), wts.size(),
7272
_pts.size() / wts.size());
73-
const auto [_phi, shape] = polyset::tabulate(celltype, degree, 0, pts);
73+
const auto [_phi, shape]
74+
= polyset::tabulate(celltype, polyset::type::standard, degree, 0, pts);
7475
impl::mdspan_t<const T, 3> phi(_phi.data(), shape);
7576

7677
// The number of order (degree) polynomials
@@ -103,7 +104,8 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
103104
{
104105
case cell::type::interval:
105106
{
106-
const auto [_phi1, shape] = polyset::tabulate(celltype, degree - 2, 0, pts);
107+
const auto [_phi1, shape] = polyset::tabulate(
108+
celltype, polyset::type::standard, degree - 2, 0, pts);
107109
impl::mdspan_t<const T, 3> p1(_phi1.data(), shape);
108110
phi1 = create_phi1(p1, phi1_buffer);
109111
for (std::size_t i = 0; i < pts.extent(0); ++i)
@@ -115,7 +117,8 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
115117
}
116118
case cell::type::triangle:
117119
{
118-
const auto [_phi1, shape] = polyset::tabulate(celltype, degree - 3, 0, pts);
120+
const auto [_phi1, shape] = polyset::tabulate(
121+
celltype, polyset::type::standard, degree - 3, 0, pts);
119122
impl::mdspan_t<const T, 3> p1(_phi1.data(), shape);
120123
phi1 = create_phi1(p1, phi1_buffer);
121124
for (std::size_t i = 0; i < pts.extent(0); ++i)
@@ -128,7 +131,8 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
128131
}
129132
case cell::type::tetrahedron:
130133
{
131-
const auto [_phi1, shape] = polyset::tabulate(celltype, degree - 4, 0, pts);
134+
const auto [_phi1, shape] = polyset::tabulate(
135+
celltype, polyset::type::standard, degree - 4, 0, pts);
132136
impl::mdspan_t<const T, 3> p1(_phi1.data(), shape);
133137
phi1 = create_phi1(p1, phi1_buffer);
134138
for (std::size_t i = 0; i < pts.extent(0); ++i)
@@ -142,7 +146,8 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
142146
}
143147
case cell::type::quadrilateral:
144148
{
145-
const auto [_phi1, shape] = polyset::tabulate(celltype, degree - 2, 0, pts);
149+
const auto [_phi1, shape] = polyset::tabulate(
150+
celltype, polyset::type::standard, degree - 2, 0, pts);
146151
impl::mdspan_t<const T, 3> p1(_phi1.data(), shape);
147152
phi1 = create_phi1(p1, phi1_buffer);
148153
for (std::size_t i = 0; i < pts.extent(0); ++i)
@@ -155,7 +160,8 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
155160
}
156161
case cell::type::hexahedron:
157162
{
158-
const auto [_phi1, shape] = polyset::tabulate(celltype, degree - 2, 0, pts);
163+
const auto [_phi1, shape] = polyset::tabulate(
164+
celltype, polyset::type::standard, degree - 2, 0, pts);
159165
impl::mdspan_t<const T, 3> p1(_phi1.data(), shape);
160166
phi1 = create_phi1(p1, phi1_buffer);
161167
for (std::size_t i = 0; i < pts.extent(0); ++i)
@@ -185,9 +191,10 @@ FiniteElement<T> basix::element::create_bubble(cell::type celltype, int degree,
185191
sobolev::space space
186192
= discontinuous ? sobolev::space::L2 : sobolev::space::H1;
187193
return FiniteElement<T>(
188-
element::family::bubble, celltype, degree, {}, wview, impl::to_mdspan(x),
189-
impl::to_mdspan(M), 0, maps::type::identity, space, discontinuous, -1,
190-
degree, element::lagrange_variant::unset, element::dpc_variant::unset);
194+
element::family::bubble, celltype, polyset::type::standard, degree, {},
195+
wview, impl::to_mdspan(x), impl::to_mdspan(M), 0, maps::type::identity,
196+
space, discontinuous, -1, degree, element::lagrange_variant::unset,
197+
element::dpc_variant::unset);
191198
}
192199
//-----------------------------------------------------------------------------
193200
template FiniteElement<float> element::create_bubble(cell::type, int, bool);

cpp/basix/e-crouzeix-raviart.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ FiniteElement<T> basix::element::create_cr(cell::type celltype, int degree,
8888
}
8989

9090
return FiniteElement<T>(
91-
element::family::CR, celltype, 1, {},
91+
element::family::CR, celltype, polyset::type::standard, 1, {},
9292
impl::mdspan_t<T, 2>(math::eye<T>(ndofs).data(), ndofs, ndofs), xview,
9393
Mview, 0, maps::type::identity, sobolev::space::L2, discontinuous, degree,
9494
degree, element::lagrange_variant::unset, element::dpc_variant::unset);

0 commit comments

Comments
 (0)