gridap / gridap/Gridap.jl

Bubble elements for a mesh with orphan nodes

Open
#1,195 17 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
879
Forks
119
Avg merge
6d 3h
Merged PRs (30d)
4

Description

Hi all,

I came across this issue with the newly-added bubble elements for a mesh that contains an "orphan" node. I am using Julia 1.12.2 and Gridap 0.19.6. Here is a MWE:

```Julia
using Gridap
using GridapGmsh
using Gmsh

# make simple 2D mesh
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 1)
gmsh.model.add("mesh")
gmsh.model.geo.addPoint(0, 0, 0)
gmsh.model.geo.addPoint(1, 2, 0) # control point
gmsh.model.geo.addPoint(2, 0, 0)
gmsh.model.geo.addBezier([1, 2, 3])
gmsh.model.geo.addLine(3, 1)
gmsh.model.geo.addCurveLoop(1:2, 1)
gmsh.model.geo.addPlaneSurface([1], 1)
gmsh.model.geo.synchronize()
gmsh.model.mesh.generate(2)
# gmsh.option.setNumber("Mesh.SaveWithoutOrphans", 1)
gmsh.write("mesh.msh")
gmsh.finalize()

# load mesh in Gridap
model = GmshDiscreteModel("mesh.msh")

# ✅ define lagrangian element space on mesh
reffe_l = ReferenceFE(lagrangian, Float64, 1)
V = TestFESpace(model, reffe_l)
U = TrialFESpace(V)

# ❌ define bubble element space on mesh
reffe_b = ReferenceFE(bubble, Float64)
R = TestFESpace(model, reffe_b)
B = TrialFESpace(R)
```

The first part makes a simple 2D mesh that contains a Bezier curve. Making this curve creates an "orphan" node that is not actually part of the mesh but is used as a control point. The `lagrangian` elements in Gridap don't seem to mind this node, but when I try to define `bubble` elements, I get the following error:

```Julia
ERROR: LoadError: BoundsError: attempt to access 3-element Vector{Int64} at index [0]
Stacktrace:
[1] throw_boundserror(A::Vector{Int64}, I::Tuple{Int64})
@ Base ./essentials.jl:15
[2] getindex
@ ./essentials.jl:919 [inlined]
[3] getindex
@ ./abstractarray.jl:1345 [inlined]
[4] _generate_face_to_own_dofs_count_d!(face_to_own_dofs_ptrs::Vector{…}, offset::Int64, cell_to_ctype::Vector{…}, dface_to_cell_owner::Gridap.Arrays.LocalItemFromTable{…}, dface_to_ldface::Gridap.Arrays.LocalIndexFromTable{…}, ctype_to_ldface_to_num_own_ldofs::Vector{…})
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/ConformingFESpaces.jl:374
[5] _generate_face_to_own_dofs(n_faces::Int64, cell_to_ctype::Vector{…}, d_to_cell_to_dfaces::Vector{…}, d_to_dface_to_cells::Vector{…}, d_to_offset::Vector{…}, d_to_ctype_to_ldface_to_own_ldofs::Vector{…})
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/ConformingFESpaces.jl:342
[6] compute_conforming_cell_dofs(cell_fe::Gridap.FESpaces.CellFE{…}, cell_conformity::Gridap.FESpaces.CellConformity{…}, grid_topology::Gridap.Geometry.UnstructuredGridTopology{…}, face_labeling::Gridap.Geometry.FaceLabeling, dirichlet_tags::Vector{…}, dirichlet_components::Nothing)
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/ConformingFESpaces.jl:263
[7] _ConformingFESpace(vector_type::Type, model::Gridap.Geometry.UnstructuredDiscreteModel{…}, face_labeling::Gridap.Geometry.FaceLabeling, cell_fe::Gridap.FESpaces.CellFE{…}, dirichlet_tags::Vector{…}, dirichlet_components::Nothing, trian::Gridap.Geometry.BodyFittedTriangulation{…})
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/ConformingFESpaces.jl:175
[8] #FESpace#33
@ ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:23 [inlined]
[9] FESpace
@ ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:8 [inlined]
[10] FESpace(model::Gridap.Geometry.UnstructuredDiscreteModel{…}, cell_reffe::Gridap.Arrays.CompressedArray{…}; conformity::Nothing, trian::Gridap.Geometry.BodyFittedTriangulation{…}, labels::Gridap.Geometry.FaceLabeling, dirichlet_tags::Vector{…}, dirichlet_masks::Nothing, constraint::Nothing, vector_type::Nothing)
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:99
[11] FESpace(model::Gridap.Geometry.UnstructuredDiscreteModel{…}, cell_reffe::Gridap.Arrays.CompressedArray{…})
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:65
[12] #FESpace#35
@ ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:114 [inlined]
[13] FESpace
@ ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:110 [inlined]
[14] #TestFESpace#37
@ ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:126 [inlined]
[15] TestFESpace(::Gridap.Geometry.UnstructuredDiscreteModel{…}, ::Tuple{…})
@ Gridap.FESpaces ~/.julia/packages/Gridap/dk0DA/src/FESpaces/FESpaceFactories.jl:125
...
```

The issue is resolved if the line
```Julia
# gmsh.option.setNumber("Mesh.SaveWithoutOrphans", 1)
```
is uncommented in the MWE. It would be nice if this wasn't necessary, as with the `lagrangian` elements.

Contributor guide

Open the contributing guide

Research direction

Reproduce the MWE with Julia 1.12.2, Gridap 0.19.6, and the generated Gmsh mesh, then inspect Gridap/FESpaces/ConformingFESpaces.jl around _generate_face_to_own_dofs_count_d!. Compare the lagrangian and bubble FESpace paths and verify that bubble elements work with the orphan node without requiring Mesh.SaveWithoutOrphans.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.