Skip to content

Commit 7bb88b0

Browse files
chmerdonpjaap
andauthored
restructuring of Interpolators (#30)
* completely replaced old point_evaluation!, point_evaluation_broken! by NodalInterpolator and ensure_moments! by MomentInterpolator and many custom interpolatioon in non-H1 finite elements by a common new FunctionalInterpolator structure; now every finite element interpolation is a composition of these three interpolating structures * better structured interpolation tests --------- Co-authored-by: Patrick Jaap <patrick.jaap@wias-berlin.de>
1 parent 82115f4 commit 7bb88b0

30 files changed

+949
-1011
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# CHANGES
22

3-
## v1.0.0
3+
## v1.1.0 May 15, 2025
4+
- overhaul of interpolators: each finite element
5+
interpolation is composed of the three new
6+
structures NodalInterpolator, MomentInterpolator, FunctionalInterpolator
7+
8+
## v1.0.0 April 7, 2025
49
- doc improvements
510
- several bugfixes regarding finite elements defined on subgrids
611
- integrate now reacts on regions parameter and has proper docstrings

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ExtendableFEMBase"
22
uuid = "12fb9182-3d4c-4424-8fd1-727a0899810c"
3-
authors = ["Christian Merdon <merdon@wias-berlin.de>"]
4-
version = "1.0.0"
3+
authors = ["Christian Merdon <merdon@wias-berlin.de>", "Patrick Jaap <patrick.jaap@wias-berlin.de>"]
4+
version = "1.1.0"
55

66
[deps]
77
DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
@@ -24,7 +24,7 @@ ExtendableFEMBaseUnicodePlotsExt = ["UnicodePlots"]
2424
[compat]
2525
DiffResults = "1"
2626
DocStringExtensions = "0.8,0.9"
27-
ExtendableGrids = "1.9.2"
27+
ExtendableGrids = "1.13.0"
2828
ExtendableSparse = "1.5.1"
2929
ForwardDiff = "0.10.35, 1"
3030
LinearAlgebra = "1.9"

examples/Example281_DiscontinuousPlot.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ function main(; broken = false, nrefs = 3, abs = false, Plotter = nothing)
6161
nodevals4nodes2 = nodevalues(FEFunction[1], Identity; abs = abs, regions = [2], nodes = subnodes2)
6262

6363
## plot
64-
p = GridVisualizer(; Plotter = Plotter, layout = (2, 2), clear = true, resolution = (1000, 500))
65-
gridplot!(p[1,1], xgrid)
66-
scalarplot!(p[1, 2], [subgrid1, subgrid2], xgrid, [view(nodevals4nodes1,:), view(nodevals4nodes2,:)], cellwise = false, levels = 11, title = "u")
64+
if Plotter !== nothing
65+
p = GridVisualizer(; Plotter = Plotter, layout = (2, 2), clear = true, resolution = (1000, 500))
66+
gridplot!(p[1,1], xgrid)
67+
scalarplot!(p[1, 2], [subgrid1, subgrid2], xgrid, [view(nodevals4nodes1,:), view(nodevals4nodes2,:)], cellwise = false, levels = 11, title = "u")
68+
end
6769

6870
return p
6971
end

src/ExtendableFEMBase.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ using ExtendableGrids: ExtendableGrids, AT_NODES, AbstractElementGeometry,
1919
CellFinder, CellGeometries, CellNodes, CellParents,
2020
CellRegions, CellVolumes, Coordinates, Edge1D,
2121
EdgeCells, EdgeGeometries, EdgeNodes, EdgeTangents,
22-
EdgeVolumes, ElementGeometries, ExtendableGrid,
22+
EdgeParents, EdgeVolumes, ElementGeometries, ExtendableGrid,
2323
FaceCells, FaceEdgeSigns, FaceEdges, FaceGeometries,
2424
FaceNodes, FaceNormals, FaceParents, FaceRegions,
2525
FaceVolumes, GridComponentGeometries4AssemblyType,
26+
NodeCells,
2627
GridComponentNodes4AssemblyType,
2728
GridComponentRegions4AssemblyType,
2829
GridComponentUniqueGeometries4AssemblyType,
@@ -107,6 +108,8 @@ export get_polynomialorder, get_ndofs, get_ndofs_all
107108
export get_ncomponents, get_edim
108109
export get_basis, get_coefficients, get_basissubset
109110

111+
export NodalInterpolator
112+
110113
export interpolate! # must be defined separately by each FEdefinition
111114
export nodevalues, continuify
112115
export nodevalues!, nodevalues_subset!

src/fedefs/h1_bubble.jl

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,10 @@ isdefined(FEType::Type{<:H1BUBBLE}, ::Type{<:Tetrahedron3D}) = true
3535

3636
interior_dofs_offset(::Type{ON_CELLS}, ::Type{H1BUBBLE{ncomponents}}, EG::Type{<:AbstractElementGeometry}) where {ncomponents} = 0
3737

38+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}) where {Tv, Ti, FEType <: H1BUBBLE, APT} = MomentInterpolator(FES, ON_CELLS)
39+
3840
function ExtendableGrids.interpolate!(Target::AbstractArray{T, 1}, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}, exact_function!; items = [], kwargs...) where {T, Tv, Ti, FEType <: H1BUBBLE, APT}
39-
xCellVolumes = FE.dofgrid[CellVolumes]
40-
ncells = num_sources(FE.dofgrid[CellNodes])
41-
if items == []
42-
items = 1:ncells
43-
else
44-
items = filter(!iszero, items)
45-
end
46-
ncomponents = get_ncomponents(FEType)
47-
integrals4cell = zeros(T, ncomponents, ncells)
48-
integrate!(integrals4cell, FE.dofgrid, ON_CELLS, exact_function!; items = items, kwargs...)
49-
for cell in items
50-
if cell != 0
51-
for c in 1:ncomponents
52-
Target[(cell - 1) * ncomponents + c] = integrals4cell[c, cell] / xCellVolumes[cell]
53-
end
54-
end
55-
end
56-
return
41+
get_interpolator(FE, ON_CELLS).evaluate!(Target, exact_function!, items, kwargs...)
5742
end
5843

5944
function get_basis(::Type{<:AssemblyType}, ::Type{H1BUBBLE{ncomponents}}, ::Type{<:AbstractElementGeometry1D}) where {ncomponents}

src/fedefs/h1_mini.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ get_ref_cellmoments(::Type{<:H1MINI}, ::Type{<:Quadrilateral2D}) = [1 // 4, 1 //
4242

4343
interior_dofs_offset(::Type{ON_CELLS}, ::Type{H1MINI{ncomponents, edim}}, EG::Type{<:AbstractElementGeometry}) where {ncomponents, edim} = num_nodes(EG)
4444

45+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}) where {Tv, Ti, FEType <: H1MINI, APT} = NodalInterpolator(FES)
46+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}) where {Tv, Ti, FEType <: H1MINI, APT} = MomentInterpolator(FES, ON_CELLS)
47+
4548
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1MINI, APT}
46-
nnodes = size(FE.dofgrid[Coordinates], 2)
47-
ncells = num_sources(FE.dofgrid[CellNodes])
48-
return point_evaluation!(Target, FE, AT_NODES, exact_function!; items = items, component_offset = nnodes + ncells, kwargs...)
49+
return get_interpolator(FE, AT_NODES).evaluate!(Target, exact_function!, items; kwargs...)
4950
end
5051

5152
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_EDGES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1MINI, APT}
@@ -66,7 +67,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
6667
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
6768

6869
# fix cell bubble value by preserving integral mean
69-
return ensure_moments!(Target, FE, ON_CELLS, exact_function!; items = items, kwargs...)
70+
return get_interpolator(FE, ON_CELLS).evaluate!(Target, exact_function!, items; kwargs...)
7071
end
7172

7273
function nodevalues!(Target::AbstractArray{<:Real, 2}, Source::AbstractArray{<:Real, 1}, FE::FESpace{<:H1MINI})

src/fedefs/h1_p1.jl

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,31 +32,32 @@ isdefined(FEType::Type{<:H1P1}, ::Type{<:AbstractElementGeometry1D}) = true
3232
isdefined(FEType::Type{<:H1P1}, ::Type{<:Triangle2D}) = true
3333
isdefined(FEType::Type{<:H1P1}, ::Type{<:Tetrahedron3D}) = true
3434

35-
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
36-
nnodes = size(FE.dofgrid[Coordinates], 2)
37-
return point_evaluation!(Target, FE, AT_NODES, exact_function; items = items, component_offset = nnodes, kwargs...)
35+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}) where {Tv, Ti, FEType <: H1P1, APT} = NodalInterpolator(FES)
36+
37+
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
38+
return get_interpolator(FE, AT_NODES).evaluate!(Target, exact_function!, items; kwargs...)
3839
end
3940

40-
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_EDGES}, exact_function; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
41+
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_EDGES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
4142
# delegate edge nodes to node interpolation
4243
subitems = slice(FE.dofgrid[EdgeNodes], items)
43-
return interpolate!(Target, FE, AT_NODES, exact_function; items = subitems, kwargs...)
44+
return interpolaste!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
4445
end
4546

46-
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_FACES}, exact_function; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
47+
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_FACES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
4748
# delegate face nodes to node interpolation
4849
subitems = slice(FE.dofgrid[FaceNodes], items)
49-
return interpolate!(Target, FE, AT_NODES, exact_function; items = subitems, kwargs...)
50+
return interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
5051
end
5152

52-
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}, exact_function; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
53+
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P1, APT}
5354
return if FE.broken == true
54-
# broken interpolation
55-
point_evaluation_broken!(Target, FE, ON_CELLS, exact_function; items = items, time = time)
55+
# broken nodal interpolation piecewise on cells
56+
interpolate!(Target, FE, AT_NODES, exact_function!; items = items, kwargs...)
5657
else
5758
# delegate cell nodes to node interpolation
5859
subitems = slice(FE.dofgrid[CellNodes], items)
59-
interpolate!(Target, FE, AT_NODES, exact_function; items = subitems, kwargs...)
60+
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
6061
end
6162
end
6263

src/fedefs/h1_p2.jl

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ end
2020
get_ncomponents(FEType::Type{<:H1P2}) = FEType.parameters[1]
2121
get_edim(FEType::Type{<:H1P2}) = FEType.parameters[2]
2222

23-
get_ndofs(::Type{<:AssemblyType}, FEType::Type{<:H1P2}, EG::Type{<:AbstractElementGeometry0D}) = FEType.parameters[1]
24-
get_ndofs(::Union{Type{<:ON_EDGES}, Type{<:ON_BEDGES}}, FEType::Type{<:H1P2}, EG::Type{<:AbstractElementGeometry1D}) = 3 * FEType.parameters[1]
25-
get_ndofs(::Union{Type{<:ON_FACES}, Type{<:ON_BFACES}}, FEType::Type{<:H1P2}, EG::Type{<:Union{AbstractElementGeometry1D, Triangle2D, Tetrahedron3D}}) = Int((FEType.parameters[2]) * (FEType.parameters[2] + 1) / 2 * FEType.parameters[1])
26-
get_ndofs(::Type{<:ON_CELLS}, FEType::Type{<:H1P2}, EG::Type{<:Union{AbstractElementGeometry1D, Triangle2D, Tetrahedron3D}}) = Int((FEType.parameters[2] + 1) * (FEType.parameters[2] + 2) / 2 * FEType.parameters[1])
23+
get_ndofs(::Type{<:AssemblyType}, FEType::Type{H1P2{n, e}}, EG::Type{<:AbstractElementGeometry0D}) where {n, e} = n
24+
get_ndofs(::Type{<:AssemblyType}, FEType::Type{H1P2{n, e}}, EG::Type{<:AbstractElementGeometry1D}) where {n, e} = 3 * n
25+
get_ndofs(::Type{<:AssemblyType}, FEType::Type{H1P2{n, e}}, EG::Type{<:Triangle2D}) where {n, e} = 6 * n
26+
get_ndofs(::Type{<:AssemblyType}, FEType::Type{H1P2{n, e}}, EG::Type{<:Tetrahedron3D}) where {n, e} = 10 * n
2727

2828
get_polynomialorder(::Type{<:H1P2}, ::Type{<:Edge1D}) = 2;
2929
get_polynomialorder(::Type{<:H1P2}, ::Type{<:Triangle2D}) = 2;
@@ -43,18 +43,13 @@ isdefined(FEType::Type{<:H1P2}, ::Type{<:Tetrahedron3D}) = true
4343

4444
interior_dofs_offset(::Type{<:AssemblyType}, ::Type{H1P2{ncomponents, edim}}, ::Type{Edge1D}) where {ncomponents, edim} = 2
4545

46-
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P2, APT}
47-
edim = get_edim(FEType)
48-
nnodes = size(FE.dofgrid[Coordinates], 2)
49-
if edim == 1
50-
nedges = num_sources(FE.dofgrid[CellNodes])
51-
elseif edim == 2
52-
nedges = num_sources(FE.dofgrid[FaceNodes])
53-
elseif edim == 3
54-
nedges = num_sources(FE.dofgrid[EdgeNodes])
55-
end
46+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}) where {Tv, Ti, FEType <: H1P2, APT} = NodalInterpolator(FES)
47+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_FACES}) where {Tv, Ti, FEType <: H1P2, APT} = MomentInterpolator(FES, ON_FACES)
48+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_EDGES}) where {Tv, Ti, FEType <: H1P2, APT} = MomentInterpolator(FES, ON_EDGES)
49+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}) where {Tv, Ti, FEType <: H1P2, APT} = MomentInterpolator(FES, ON_CELLS)
5650

57-
return point_evaluation!(Target, FE, AT_NODES, exact_function!; items = items, component_offset = nnodes + nedges, kwargs...)
51+
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P2, APT}
52+
return get_interpolator(FE, AT_NODES).evaluate!(Target, exact_function!, items; kwargs...)
5853
end
5954

6055
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_EDGES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P2, APT}
@@ -65,7 +60,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
6560
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
6661

6762
# perform edge mean interpolation
68-
ensure_moments!(Target, FE, ON_EDGES, exact_function!; items = items, kwargs...)
63+
get_interpolator(FE, ON_EDGES).evaluate!(Target, exact_function!, items)
6964
end
7065
end
7166

@@ -77,7 +72,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
7772
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
7873

7974
# perform face mean interpolation
80-
ensure_moments!(Target, FE, ON_FACES, exact_function!; items = items, kwargs...)
75+
get_interpolator(FE, ON_FACES).evaluate!(Target, exact_function!, items; kwargs...)
8176
elseif edim == 3
8277
# delegate face edges to edge interpolation
8378
subitems = slice(FE.dofgrid[FaceEdges], items)
@@ -106,7 +101,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
106101
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
107102

108103
# preserve cell integral
109-
ensure_moments!(Target, FE, ON_CELLS, exact_function!; items = items, kwargs...)
104+
get_interpolator(FE, ON_CELLS).evaluate!(Target, exact_function!, items; kwargs...)
110105
end
111106
end
112107

src/fedefs/h1_p2b.jl

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,12 @@ interior_dofs_offset(::Type{<:ON_CELLS}, ::Type{H1P2B{ncomponents, edim}}, ::Typ
3535

3636
get_ref_cellmoments(::Type{<:H1P2B}, ::Type{<:Triangle2D}) = [0 // 1, 0 // 1, 0 // 1, 1 // 3, 1 // 3, 1 // 3, 1 // 1] # integrals of 1D basis functions over reference cell (divided by volume)
3737

38-
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P2B, APT}
39-
edim = get_edim(FEType)
40-
nnodes = size(FE.dofgrid[Coordinates], 2)
41-
offset = nnodes + num_sources(FE.dofgrid[CellNodes])
42-
if edim == 2
43-
offset += num_sources(FE.dofgrid[FaceNodes])
44-
elseif edim == 3
45-
offset += num_sources(FE.dofgrid[EdgeNodes])
46-
end
38+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}) where {Tv, Ti, FEType <: H1P2B, APT} = NodalInterpolator(FES)
39+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_FACES}) where {Tv, Ti, FEType <: H1P2B, APT} = MomentInterpolator(FES, ON_FACES)
40+
init_interpolator!(FES::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_CELLS}) where {Tv, Ti, FEType <: H1P2B, APT} = MomentInterpolator(FES, ON_CELLS)
4741

48-
return point_evaluation!(Target, FE, AT_NODES, exact_function!; items = items, component_offset = offset, kwargs...)
42+
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{AT_NODES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P2B, APT}
43+
return get_interpolator(FE, AT_NODES).evaluate!(Target, exact_function!, items; kwargs...)
4944
end
5045

5146
function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT}, ::Type{ON_EDGES}, exact_function!; items = [], kwargs...) where {Tv, Ti, FEType <: H1P2B, APT}
@@ -56,7 +51,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
5651
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
5752

5853
# perform edge mean interpolation
59-
ensure_moments!(Target, FE, ON_EDGES, exact_function!; items = items, kwargs...)
54+
get_interpolator(FE, ON_EDGES).evaluate!(Target, exact_function!, items)
6055
end
6156
end
6257

@@ -68,7 +63,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
6863
interpolate!(Target, FE, AT_NODES, exact_function!; items = subitems, kwargs...)
6964

7065
# perform face mean interpolation
71-
ensure_moments!(Target, FE, ON_FACES, exact_function!; items = items, kwargs...)
66+
get_interpolator(FE, ON_FACES).evaluate!(Target, exact_function!, items; kwargs...)
7267
elseif edim == 3
7368
# delegate face edges to edge interpolation
7469
subitems = slice(FE.dofgrid[FaceEdges], items)
@@ -100,7 +95,7 @@ function ExtendableGrids.interpolate!(Target, FE::FESpace{Tv, Ti, FEType, APT},
10095
end
10196

10297
# fix cell bubble value by preserving integral mean
103-
return ensure_moments!(Target, FE, ON_CELLS, exact_function!; items = items, kwargs...)
98+
get_interpolator(FE, ON_CELLS).evaluate!(Target, exact_function!, items; kwargs...)
10499
end
105100

106101
function get_basis(AT::Union{Type{<:ON_FACES}, Type{<:ON_BFACES}}, ::Type{H1P2B{ncomponents, edim}}, EG::Type{<:AbstractElementGeometry}) where {ncomponents, edim}

0 commit comments

Comments
 (0)