@@ -158,6 +158,45 @@ function get_periodic_coupling_info(
158158end
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"""
196235function 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