Skip to content

Commit 59ad089

Browse files
committed
changes suggested by pjaap's review
1 parent 7054d6a commit 59ad089

File tree

3 files changed

+82
-59
lines changed

3 files changed

+82
-59
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

src/interpolators.jl

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function NodalInterpolator(
3232
broken = FES.broken,
3333
component_offset = FES.coffset,
3434
kwargs...) where {T}
35+
3536
FEType = eltype(FES)
3637
ncomponents = get_ncomponents(FEType)
3738
xCoordinates = grid[Coordinates]
@@ -115,7 +116,20 @@ are solved with a mass matrix of interior basis functions (evaluated with operat
115116
basis functions of the moments of type FEType_ref and with moments_operator. In the bestapprox mode
116117
the mass matrix instead is formed from the scalar product of the interior basis functions.
117118
"""
118-
function MomentInterpolator(FE::FESpace{Tv, Ti, FEType, APT}, AT::Type{<:AssemblyType}, xgrid = FE.dofgrid; operator = Identity, FEType_ref = :auto, FEType_moments = :auto, moments_operator = operator, moments_dofs = Int[], bestapprox = false, order = 0, coffset::Int = -1, componentwise = true, kwargs...) where {Tv, Ti, FEType <: AbstractFiniteElement, APT}
119+
function MomentInterpolator(
120+
FE::FESpace{Tv, Ti, FEType, APT},
121+
AT::Type{<:AssemblyType},
122+
xgrid = FE.dofgrid;
123+
operator = Identity,
124+
FEType_ref = :auto,
125+
FEType_moments = :auto,
126+
moments_operator = operator,
127+
moments_dofs = Int[],
128+
bestapprox = false,
129+
order = 0,
130+
coffset::Int = -1,
131+
componentwise = true,
132+
kwargs...) where {Tv, Ti, FEType <: AbstractFiniteElement, APT}
119133

120134
itemvolumes = xgrid[GridComponentVolumes4AssemblyType(AT)]
121135
itemnodes = xgrid[GridComponentNodes4AssemblyType(AT)]
@@ -174,7 +188,10 @@ function MomentInterpolator(FE::FESpace{Tv, Ti, FEType, APT}, AT::Type{<:Assembl
174188
end
175189

176190
## check if mass matrix can be computed once or needs to be recomputed on every mesh
177-
if FEType_ref <: AbstractH1FiniteElement && !(FEType_ref <: AbstractH1FiniteElementWithCoefficients) && FEType_moments <: AbstractH1FiniteElement && moments_operator == Identity
191+
if FEType_ref <: AbstractH1FiniteElement &&
192+
!(FEType_ref <: AbstractH1FiniteElementWithCoefficients) &&
193+
FEType_moments <: AbstractH1FiniteElement &&
194+
moments_operator == Identity
178195
fixed_mass_matrix = true
179196
else
180197
fixed_mass_matrix = false
@@ -444,7 +461,11 @@ function FunctionalInterpolator(
444461
AT::Type{<:AssemblyType} = ON_FACES,
445462
xgrid = FE.dofgrid;
446463
bonus_quadorder = 0,
447-
operator = NormalFlux, nfluxes = 0, dofs = [], mean = false, kwargs...) where {Tv, Ti, FEType <: AbstractFiniteElement, APT}
464+
operator = NormalFlux,
465+
nfluxes = 0,
466+
dofs = [],
467+
mean = false,
468+
kwargs...) where {Tv, Ti, FEType <: AbstractFiniteElement, APT}
448469

449470
itemvolumes = xgrid[GridComponentVolumes4AssemblyType(AT)]
450471
itemnodes = xgrid[GridComponentNodes4AssemblyType(AT)]

test/test_interpolators.jl

Lines changed: 52 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,59 @@ function run_interpolator_tests()
22

33
# list of FETypes that should be tested
44
TestCatalog1D = [
5-
L2P0{1},
6-
H1P1{1},
7-
H1P2{1, 1},
8-
H1P3{1, 1},
9-
H1Pk{1, 1, 3},
10-
H1Pk{1, 1, 4},
11-
H1Pk{1, 1, 5},
5+
L2P0{1} => 0,
6+
H1P1{1} => 1,
7+
H1P2{1, 1} => 2,
8+
H1P3{1, 1} => 3,
9+
H1Pk{1, 1, 3} => 3,
10+
H1Pk{1, 1, 4} => 4,
11+
H1Pk{1, 1, 5} => 5
1212
]
13-
ExpectedOrders1D = [0, 1, 2, 3, 3, 4, 5]
1413

1514
TestCatalog2D = [
16-
HCURLN0{2},
17-
HCURLN1{2},
18-
HDIVRT0{2},
19-
HDIVRTk{2, 0},
20-
HDIVBDM1{2},
21-
HDIVRT1{2},
22-
HDIVRTk{2, 1},
23-
HDIVBDM2{2},
24-
HDIVRTk{2, 2},
25-
HDIVRTk{2, 3},
26-
HDIVRTk{2, 4},
27-
L2P0{2},
28-
L2P1{2},
29-
H1P1{2},
30-
H1Q1{2},
31-
H1CR{2},
32-
H1MINI{2, 2},
33-
H1P1TEB{2},
34-
H1BR{2},
35-
H1P2{2, 2},
36-
H1P2B{2, 2},
37-
H1Q2{2, 2},
38-
H1P3{2, 2},
39-
H1Pk{2, 2, 3},
40-
H1Pk{2, 2, 4},
41-
H1Pk{2, 2, 5},
15+
HCURLN0{2} => 0,
16+
HCURLN1{2} => 1,
17+
HDIVRT0{2} => 0,
18+
HDIVRTk{2, 0} => 0,
19+
HDIVBDM1{2} => 1,
20+
HDIVRT1{2} => 1,
21+
HDIVRTk{2, 1} => 1,
22+
HDIVBDM2{2} => 2,
23+
HDIVRTk{2, 2} => 2,
24+
HDIVRTk{2, 3} => 3,
25+
HDIVRTk{2, 4} => 4,
26+
L2P0{2} => 0,
27+
L2P1{2} => 1,
28+
H1P1{2} => 1,
29+
H1Q1{2} => 1,
30+
H1CR{2} => 1,
31+
H1MINI{2, 2} => 1,
32+
H1P1TEB{2} => 1,
33+
H1BR{2} => 1,
34+
H1P2{2, 2} => 2,
35+
H1P2B{2, 2} => 2,
36+
H1Q2{2, 2} => 2,
37+
H1P3{2, 2} => 3,
38+
H1Pk{2, 2, 3} => 3,
39+
H1Pk{2, 2, 4} => 4,
40+
H1Pk{2, 2, 5} => 5
4241
]
43-
ExpectedOrders2D = [0, 1, 0, 0, 1, 1, 1, 2, 2, 3, 4, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5]
4442

4543
TestCatalog3D = [
46-
HCURLN0{3},
47-
HDIVRT0{3},
48-
HDIVBDM1{3},
49-
HDIVRT1{3},
50-
L2P0{3},
51-
H1P1{3},
52-
H1Q1{3},
53-
H1CR{3},
54-
H1MINI{3, 3},
55-
H1P1TEB{3},
56-
H1BR{3},
57-
H1P2{3, 3},
58-
H1P3{3, 3},
44+
HCURLN0{3} => 0,
45+
HDIVRT0{3} => 0,
46+
HDIVBDM1{3} => 1,
47+
HDIVRT1{3} => 1,
48+
L2P0{3} => 0,
49+
H1P1{3} => 1,
50+
H1Q1{3} => 1,
51+
H1CR{3} => 1,
52+
H1MINI{3, 3} => 1,
53+
H1P1TEB{3} => 1,
54+
H1BR{3} => 1,
55+
H1P2{3, 3} => 2,
56+
H1P3{3, 3} => 3
5957
]
60-
ExpectedOrders3D = [0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 2, 3]
6158

6259
## function that computes errors at enough quadrature points for polynomial of degree order
6360
function compute_error(uh::FEVectorBlock, u::Function, order = get_polynomialorder(get_FEType(uh), uh.FES.xgrid[CellGeometries][1]))
@@ -123,8 +120,8 @@ function run_interpolator_tests()
123120
println("============================")
124121
xgrid = testgrid(Edge1D)
125122
for n in 1:length(TestCatalog1D)
126-
test_interpolation(xgrid, TestCatalog1D[n], ExpectedOrders1D[n])
127-
test_interpolation(xgrid, TestCatalog1D[n], ExpectedOrders1D[n], true)
123+
test_interpolation(xgrid, TestCatalog1D[n].first, TestCatalog1D[n].second)
124+
test_interpolation(xgrid, TestCatalog1D[n].first, TestCatalog1D[n].second, true)
128125
end
129126
println("\n")
130127
println("============================")
@@ -134,8 +131,8 @@ function run_interpolator_tests()
134131
xgrid = uniform_refine(reference_domain(EG), 1)
135132
println("EG = $EG")
136133
for n in 1:length(TestCatalog2D), broken in (false, true)
137-
if ExtendableFEMBase.isdefined(TestCatalog2D[n], EG, broken)
138-
test_interpolation(xgrid, TestCatalog2D[n], ExpectedOrders2D[n], broken)
134+
if ExtendableFEMBase.isdefined(TestCatalog2D[n].first, EG, broken)
135+
test_interpolation(xgrid, TestCatalog2D[n].first, TestCatalog2D[n].second, broken)
139136
else
140137
@warn "$(TestCatalog2D[n]) (broken = $broken) not defined on $EG (skipping test case)"
141138
end
@@ -148,8 +145,8 @@ function run_interpolator_tests()
148145
for EG in [Tetrahedron3D, Parallelepiped3D]
149146
xgrid = uniform_refine(reference_domain(EG), 1)
150147
for n in 1:length(TestCatalog3D), broken in (false, true)
151-
if ExtendableFEMBase.isdefined(TestCatalog3D[n], EG, broken)
152-
test_interpolation(xgrid, TestCatalog3D[n], ExpectedOrders3D[n], broken)
148+
if ExtendableFEMBase.isdefined(TestCatalog3D[n].first, EG, broken)
149+
test_interpolation(xgrid, TestCatalog3D[n].first, TestCatalog3D[n].second, broken)
153150
else
154151
@warn "$(TestCatalog3D[n]) (broken = $broken) not defined on $EG (skipping test case)"
155152
end

0 commit comments

Comments
 (0)