Interpolable for non-conforming (octree) meshes
- Dominant language
- Julia
- Stars
- 879
- Forks
- 119
- Avg merge
- 6d 3h
- Merged PRs (30d)
- 4
Description
Hello @JordiManyer and @amartinhuertas,
For non-conforming meshes, I think we should find a way in the function below to provide a list of `vertex_to_cells` that includes the non-conforming connectivities:
https://github.com/gridap/Gridap.jl/blob/62586b6b285bd1f5a8532f10b4342e18f1861d1c/src/CellData/Interpolation.jl#L99-L118
For `OctreeDistributedDiscreteModel`, one possibility could be to use the `NonConformingGridTopolgy` that I am developing [here](https://github.com/gridap/GridapEmbedded.jl/blob/distributed_aggregate_p4est_meshes/test/dev/NonConformingGridTopologies.jl).
Otherwise, I need to increase the `num_nearest_vertices` to the minimum value that ensures there is always (at least one) conforming node in the list of nearest vertices. This is not ideal.
Here is a [MWE](https://github.com/gridap/GridapEmbedded.jl/blob/distributed_agfem_with_algoim_quads/test/dev/gridap_issue_1266.jl) that illustrates the issue (_running it with 1 proc_).
```julia
using Gridap
using GridapDistributed
using GridapP4est
using PartitionedArrays
using MPI
using GridapEmbedded.AlgoimUtils
if !MPI.Initialized()
MPI.Init()
end
# mpiexec -n 1 julia +1.11 -O1 --project test/dev/gridap_issue_1266.jl
with_mpi() do distribute
# Initial Octree Distributed Discrete Model
ranks = distribute(LinearIndices((MPI.Comm_size(MPI.COMM_WORLD),)))
coarse_model = CartesianDiscreteModel((0,1,0,1),(1,1))
num_levels_initial_refinement = 2
dmodel = OctreeDistributedDiscreteModel(ranks,
coarse_model,
num_levels_initial_refinement)
# Coarsen first four cells
fmodel_refine_coarsen_flags =
map(ranks,partition(get_cell_gids(dmodel.dmodel))) do rank,indices
flags = zeros(Int,length(indices))
flags[1:4] .= coarsen_flag
flags
end
fmodel,_ = Gridap.Adaptivity.adapt(dmodel,fmodel_refine_coarsen_flags);
# writevtk(fmodel,"fmodel")
# Interpolate a fun on a point of the non-conforming grid
Ω = Triangulation(fmodel)
order = 1
reffe_s = ReferenceFE(lagrangian,Float64,order)
Qₕ = TestFESpace(Ω,reffe_s,conformity=:H1)
φ = zero(Qₕ)
sm = Gridap.CellData.KDTreeSearch(num_nearest_vertices=5)
iφ = map(local_views(φ)) do liφ
Gridap.CellData.Interpolable(liφ,searchmethod=sm)
end |> GridapDistributed.DistributedInterpolable
iφ(Point(0.25,0.25)) # OK
φ(Point(0.25,0.25)) # KO
# Using default num_nearest_vertices = 1 fails because the only candidate
# vertex is a hanging node and does not have in its list of cells the coarse cell
# that contains the point. _Detail:_ To be precise, the point that is not found is
# `mean(testitem(get_cell_coordinates(trian)))` of the DistributedInterpolable constructor.
true
end
# MPI.Finalize()
```
I also attach a picture of the mesh in the unit square.
FYI @nannaberre
We can talk about this next time we meet. If you have any questions, lmk. Thanks.
Contributor guide
Research direction
Start with the Interpolation.jl function at lines 99-118 and reproduce the failure using test/dev/gridap_issue_1266.jl with one MPI process. Compare the vertex_to_cells lookup with the NonConformingGridTopologies.jl approach; done means the Interpolable call succeeds on the non-conforming mesh without requiring an increased num_nearest_vertices value.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100