Skip to content

Commit 3da603e

Browse files
committed
slightly faster and less allocations
1 parent 55434ea commit 3da603e

1 file changed

Lines changed: 55 additions & 51 deletions

File tree

src/helper_functions.jl

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,45 @@ function get_periodic_coupling_info(
158158
end
159159

160160

161+
# compact variant of lazy_interpolate! specialized on ON_FACES interpolations
162+
function interpolate_on_boundaryfaces(
163+
source::FEVector{Tv, TvG, TiG},
164+
give_opposite,
165+
start_cell::Int = 1, # TODO we interpolate on the "b_from" side: a proper start cell should be given
166+
eps = 1.0e-13,
167+
kwargs...,
168+
) where {Tv, TvG, TiG}
169+
170+
# wrap point evaluation into function that is put into normal interpolate!
171+
xgrid = source[1].FES.xgrid
172+
xdim::Int = size(xgrid[Coordinates], 1)
173+
PE = PointEvaluator([(1, Identity)], source)
174+
xref = zeros(TvG, xdim)
175+
x_source = zeros(TvG, xdim)
176+
CF::ExtendableGrids.CellFinder{TvG, TiG} = ExtendableGrids.CellFinder(xgrid)
177+
last_cell = zeros(Int, 1)
178+
last_cell[1] = start_cell
179+
180+
function __setstartcell(new)
181+
return last_cell[1] = Int(new)
182+
end
183+
184+
function __eval_point(result, qpinfo)
185+
give_opposite(x_source, qpinfo.x)
186+
187+
cell = ExtendableGrids.gFindLocal!(xref, CF, x_source; icellstart = last_cell[1], eps)
188+
if cell == 0
189+
@error "boundary coordinate $(qpinfo.x) opposite to $x_source could not be found in the grid"
190+
else
191+
evaluate_bary!(result, PE, xref, cell)
192+
last_cell[1] = cell
193+
end
194+
return nothing
195+
end
196+
197+
return __eval_point, __setstartcell
198+
end
199+
161200
"""
162201
get_periodic_coupling_matrix(
163202
FES::FESpace,
@@ -194,54 +233,18 @@ Note that A is transposed for efficient col-wise storage.
194233
195234
"""
196235
function get_periodic_coupling_matrix(
197-
FES::FESpace,
198-
xgrid::ExtendableGrid,
236+
FES::FESpace{Tv},
237+
xgrid::ExtendableGrid{TvG, TiG},
199238
b_from,
200239
b_to,
201240
give_opposite!::Function;
202241
mask = :auto,
203242
sparsity_tol = 1.0e-12,
204243
heuristic_search = true,
205-
)
244+
) where {Tv, TvG, TiG}
206245

207246
@info "Computing periodic coupling matrix. This may take a while."
208247

209-
# compact variant of lazy_interpolate! specialized on ON_FACES interpolations
210-
function interpolate_on_boundaryfaces(
211-
source,
212-
give_opposite,
213-
Tv = Float64,
214-
start_cell = 1, # TODO we interpolate on the "b_from" side: a proper start cell should be given
215-
eps = 1.0e-13,
216-
kwargs...,
217-
)
218-
219-
# wrap point evaluation into function that is put into normal interpolate!
220-
xgrid = source[1].FES.xgrid
221-
xdim::Int = size(xgrid[Coordinates], 1)
222-
PE = PointEvaluator([(1, Identity)], source)
223-
xref = zeros(Tv, xdim)
224-
x_source = zeros(Tv, xdim)
225-
CF::ExtendableGrids.CellFinder{Tv, Ti} = ExtendableGrids.CellFinder(xgrid)
226-
last_cell = start_cell
227-
228-
function __eval_point(result, qpinfo)
229-
x = qpinfo.x
230-
give_opposite(x_source, x)
231-
232-
cell = ExtendableGrids.gFindLocal!(xref, CF, x_source; icellstart = last_cell, eps)
233-
if cell == 0
234-
@error "boundary coordinate $x opposite to $x_source could not be found in the grid"
235-
else
236-
evaluate_bary!(result, PE, xref, cell)
237-
last_cell = cell
238-
end
239-
return nothing
240-
end
241-
242-
return __eval_point
243-
end
244-
245248
# total number of grid boundary faces
246249
boundary_nodes = xgrid[BFaceNodes]
247250
n_boundary_faces = size(boundary_nodes, 2)
@@ -267,12 +270,9 @@ function get_periodic_coupling_matrix(
267270
# face numbers of the boundary faces
268271
face_numbers_of_bfaces = xgrid[BFaceFaces]
269272

270-
# type of indices
271-
Ti = ExtendableGrids.index_type(xgrid)
272-
273273
# find all faces in b_to
274-
faces_in_b_to = Ti[]
275-
faces_in_b_from = Ti[]
274+
faces_in_b_to = TiG[]
275+
faces_in_b_from = TiG[]
276276
for (i, region) in enumerate(boundary_regions)
277277
if region == b_to
278278
push!(faces_in_b_to, face_numbers_of_bfaces[i])
@@ -309,7 +309,7 @@ function get_periodic_coupling_matrix(
309309
return true
310310
end
311311

312-
dummy = zeros(size(xgrid[Coordinates], 1))
312+
dummy = zeros(TvG, size(xgrid[Coordinates], 1))
313313

314314
# flip a face to the other side using the give_opposite! function
315315
# Warning: this overwrites the face
@@ -322,15 +322,16 @@ function get_periodic_coupling_matrix(
322322
return
323323
end
324324

325-
326-
eval_point = interpolate_on_boundaryfaces(fe_vector, give_opposite!)
325+
eval_point, set_start = interpolate_on_boundaryfaces(fe_vector, give_opposite!)
327326

328327
# precompute approximate search region for each boundary face in b_from
329-
search_areas = Dict{Ti, Vector{Ti}}()
328+
search_areas = Dict{TiG, Vector{TiG}}()
329+
coords = xgrid[Coordinates]
330+
facenodes = xgrid[FaceNodes]
331+
box_from = zeros(TvG, 2)
330332
if heuristic_search
331333
for face_from in faces_in_b_from
332-
# get from_face coords (explicit copy)
333-
coords_from = xgrid[Coordinates][:, xgrid[FaceNodes][:, face_from]]
334+
coords_from = coords[:, facenodes[:, face_from]]
334335

335336
# transfer the coords_from to the other side
336337
transfer_face!(coords_from)
@@ -339,7 +340,7 @@ function get_periodic_coupling_matrix(
339340
@views box_from = extrema(coords_from, dims = (2))[:]
340341

341342
for face_to in faces_in_b_to
342-
@views coords_to = xgrid[Coordinates][:, xgrid[FaceNodes][:, face_to]]
343+
@views coords_to = coords[:, facenodes[:, face_to]]
343344
@views box_to = extrema(coords_to, dims = (2))[:]
344345

345346
if do_boxes_overlap(box_from, box_to)
@@ -359,6 +360,9 @@ function get_periodic_coupling_matrix(
359360
if boundary_regions[i_boundary_face] == b_from
360361

361362
local_dofs = @views dofs_on_boundary[:, i_boundary_face]
363+
if heuristic_search
364+
# set_start(1)
365+
end
362366
for local_dof in local_dofs
363367
# compute number of component
364368
if mask[1 + ((local_dof - 1) ÷ coffset)] == 0.0

0 commit comments

Comments
 (0)