Skip to content

Commit dcd406c

Browse files
authored
Fix cellparents interpolation (#54)
* extracted incident cell of items into qpinfo in interpolators for use_cellparents in lazy_interpolate! * correct itemcell fill for various assembly type delegations in interpolations * adjusted itemcells computation for ON_EDGES assembly in MomentInterpolator
1 parent 4197cbd commit dcd406c

File tree

4 files changed

+28
-31
lines changed

4 files changed

+28
-31
lines changed

CHANGELOG.md

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

3-
## v1.5.0 November 03, 2025
3+
## v1.5.0 November 21, 2025
44
- added type parameter to `PointEvaluator` so `lazy_interpolate!` is now accessible for automatic differentiation
55
- added new `compute_lazy_interpolation_jacobian` function for computing Jacobians of interpolations between finite element spaces
66
- added `H1Pk_to_HDIVRT0_interpolator` function for (faster) computation of interpolation matrix from `H1Pk`-conforming spaces into `HDIVRT0`-conforming spaces on the same grid
77
- fixed interpolation of `HCURLN1` finite element
8+
- updated `MomentInterpolator` to deliver incident cells to `QPInfos` to speed up `lazy_interpolate!`
89

910
## v1.4.0 July 17, 2025
1011
- added new weighted reconstruction operator `WeightedReconstruct` (so far only for H1BR{2})

src/interpolators.jl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,29 @@ function MomentInterpolator(
191191
itemregions = xgrid[GridComponentRegions4AssemblyType(AT)]
192192
itemdofs = Dofmap4AssemblyType(FE, AT)
193193
has_normals = true
194+
nitems::Int = num_sources(itemnodes)
194195
if AT <: ON_FACES
195196
itemnormals = xgrid[FaceNormals]
197+
@views itemcells = xgrid[FaceCells][1, :]
196198
elseif AT <: ON_BFACES
197199
itemnormals = xgrid[FaceNormals][:, xgrid[BFaceFaces]]
200+
itemcells = xgrid[BFaceCells]
198201
else
199202
has_normals = false
203+
if AT <: ON_EDGES # e.g. H1P2 delegation for tetrahedron to edges
204+
ec = xgrid[EdgeCells]
205+
# extract first cell to which a given edge belongs for every edge
206+
itemcells = view(ec.colentries, view(ec.colstart, 1:nitems))
207+
else
208+
# leave empty for delegations to cell dofs, fill up with items at call site
209+
itemcells = []
210+
end
200211
end
201212
EGs = xgrid[GridComponentUniqueGeometries4AssemblyType(AT)]
202213

203214
@assert length(EGs) == 1 "MomentInterpolator currently only works with grids with a single element geometry"
204215
EG = EGs[1]
205216

206-
nitems::Int = num_sources(itemnodes)
207217
ncomponents::Int = get_ncomponents(FEType)
208218
edim::Int = dim_element(EG)
209219
order_FE = get_polynomialorder(FEType, EG)
@@ -403,6 +413,8 @@ function MomentInterpolator(
403413
QP.xref = xref[qp]
404414
eval_trafo!(QP.x, L2G, xref[qp])
405415

416+
QP.cell = itemcells[item]
417+
406418
exact_function!(result_f, QP)
407419
if (bestapprox)
408420
for m in 1:nmoments, k in 1:ncomponents
@@ -483,9 +495,8 @@ function MomentInterpolator(
483495
end
484496
QP.params = params === nothing ? [] : params
485497
QP.time = time
486-
if isempty(items)
487-
items = 1:nitems
488-
end
498+
isempty(items) && (items = 1:nitems)
499+
isempty(itemcells) && (itemcells = 1:nitems)
489500
assembly_loop!(target, f_moments, items, exact_function!, QF, L2G, FEB, FEB_moments)
490501
return nothing
491502
end

src/lazy_interpolate.jl

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -87,43 +87,28 @@ function lazy_interpolate!(
8787
same_cells::Bool = xgrid == target.FES.xgrid
8888
CF::CellFinder{Tv, Ti} = CellFinder(xgrid)
8989

90-
if same_cells || use_cellparents == true
91-
if same_cells
92-
xCellParents = 1:num_cells(target.FES.xgrid)
93-
else
94-
xCellParents::Array{Ti, 1} = target.FES.xgrid[CellParents]
95-
end
90+
if same_cells || use_cellparents
91+
xCellParents::Array{Ti, 1} = same_cells ? (1:num_cells(target.FES.xgrid)) : target.FES.xgrid[CellParents]
9692
function point_evaluation_parentgrid!(result, qpinfo)
97-
x = qpinfo.x
98-
cell = xCellParents[qpinfo.cell]
99-
if xtrafo !== nothing
100-
xtrafo(x_source, x)
101-
cell = gFindLocal!(xref, CF, x_source; icellstart = cell, eps = eps, trybrute = !only_localsearch)
102-
else
103-
cell = gFindLocal!(xref, CF, x; icellstart = cell, eps = eps, trybrute = !only_localsearch)
104-
end
105-
evaluate_bary!(result, PE, xref, cell)
106-
return nothing
93+
x = xtrafo !== nothing ? xtrafo(x_source, qpinfo.x) : qpinfo.x
94+
cell = gFindLocal!(xref, CF, x; icellstart = xCellParents[qpinfo.cell], eps = eps, trybrute = !only_localsearch)
95+
return evaluate_bary!(result, PE, xref, cell)
10796
end
10897
fe_function = point_evaluation_parentgrid!
10998
else
11099
function point_evaluation_arbitrarygrids!(result, qpinfo)
111-
x = qpinfo.x
112-
if xtrafo !== nothing
113-
xtrafo(x_source, x)
114-
cell = gFindLocal!(xref, CF, x_source; icellstart = lastnonzerocell, eps = eps, trybrute = !only_localsearch)
115-
else
116-
cell = gFindLocal!(xref, CF, x; icellstart = lastnonzerocell, eps = eps, trybrute = !only_localsearch)
117-
end
100+
x = xtrafo !== nothing ? xtrafo(x_source, qpinfo.x) : qpinfo.x
101+
cell = gFindLocal!(xref, CF, x; icellstart = lastnonzerocell, eps = eps, trybrute = !only_localsearch)
118102
if cell == 0
119-
fill!(result, not_in_domain_value)
103+
return fill!(result, not_in_domain_value)
120104
else
121105
evaluate_bary!(result, PE, xref, cell)
122106
lastnonzerocell = cell
107+
return cell
123108
end
124-
return nothing
125109
end
126110
fe_function = point_evaluation_arbitrarygrids!
127111
end
112+
128113
return interpolate!(target, ON_CELLS, fe_function; resultdim = resultdim, items = items, kwargs...)
129114
end

test/test_interpolation_matrix.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ function run_space_interpolation_matrix_tests()
214214
for EG in [Tetrahedron3D, Parallelepiped3D]
215215
xgrid = uniform_refine(reference_domain(EG), 1)
216216
for ((source_element, target_element), order) in PairTestCatalog3D, broken in (false, true)
217-
@info "Element pair: ($(EG), $(source_element), $(target_element)), order: $(order), broken =$(broken) \n"
217+
@info "Element pair: ($(EG), $(source_element), $(target_element)), order: $(order), broken = $(broken) \n"
218218
if ExtendableFEMBase.isdefined(target_element, EG, broken) && ExtendableFEMBase.isdefined(source_element, EG, broken)
219219
test_space_matrix_computation(xgrid, source_element, target_element, order; broken)
220220
else

0 commit comments

Comments
 (0)