gridap / gridap/Gridap.jl

Error with quadrilateral mesh generated from Gmsh + Lowest-order Nedelec FEs

Open
#811 10 comments 0 reactions 0 assignees View on GitHub
help wanted new functionality
Dominant language
Julia
Stars
879
Forks
119
Avg merge
6d 3h
Merged PRs (30d)
4

Description

The error is reproduced with MWE below (mesh file attached).

Please see my explanation below on the cause of the problem.

Versions of packages:

* GridapGmsh v0.6.0
* Gridap v0.17.13 `https://github.com/gridap/Gridap.jl#master` (46b538895f4d035374d0e76091b6888870fadac9)

[refined_lshape.zip](https://github.com/gridap/Gridap.jl/files/9100571/refined_lshape.zip)

```julia
using Gridap
using GridapGmsh
mesh_file="refined_lshape.msh"
order = 0
reffe = ReferenceFE(nedelec, Float64, order)
model = GmshDiscreteModel(mesh_file)
writevtk(model,"m")
V0 = FESpace(model, reffe; dirichlet_tags=["dirichlet_surfaces", "dirichlet_points"])
```

And the error is:

```
ERROR: BoundsError: attempt to access 1-element Vector{Vector{Int64}} at index [2]
Stacktrace:
[1] getindex
@ ./array.jl:861 [inlined]
[2] getindex
@ ./abstractarray.jl:1221 [inlined]
[3] getindex!(cache::Gridap.Arrays.CachedVector{Int32, Vector{Int32}}, a::Gridap.FESpaces.CellDofsNonOriented, cell::Int64)
@ Gridap.FESpaces ~/.julia/packages/Gridap/JCqMt/src/FESpaces/ConformingFESpaces.jl:555
[4] _generate_data_and_ptrs_fill_ptrs!(ptrs::Vector{Int32}, vv::Gridap.FESpaces.CellDofsNonOriented)
@ Gridap.Arrays ~/.julia/packages/Gridap/JCqMt/src/Arrays/Tables.jl:151
[5] generate_data_and_ptrs(vv::Gridap.FESpaces.CellDofsNonOriented)
@ Gridap.Arrays ~/.julia/packages/Gridap/JCqMt/src/Arrays/Tables.jl:139
[6] Table
@ ~/.julia/packages/Gridap/JCqMt/src/Arrays/Tables.jl:27 [inlined]
[7] compute_conforming_cell_dofs(cell_fe::Gridap.FESpaces.CellFE{Vector{Int8}}, cell_conformity::Gridap.FESpaces.CellConformity{Vector{Int8}}, grid_topology::Gridap.Geometry.UnstructuredGridTopology{2, 2, Float64, Gridap.Geometry.NonOriented}, face_labeling::Gridap.Geometry.FaceLabeling, dirichlet_tags::Vector{String}, dirichlet_components::Nothing)
@ Gridap.FESpaces ~/.julia/packages/Gridap/JCqMt/src/FESpaces/ConformingFESpaces.jl:269
[8] _ConformingFESpace(vector_type::Type, model::Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, face_labeling::Gridap.Geometry.FaceLabeling, cell_fe::Gridap.FESpaces.CellFE{Vector{Int8}}, dirichlet_tags::Vector{String}, dirichlet_components::Nothing, trian::Gridap.Geometry.BodyFittedTriangulation{2, 2, Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, Gridap.Geometry.UnstructuredGrid{2, 2, Float64, Gridap.Geometry.NonOriented, Nothing}, Gridap.Arrays.IdentityVector{Int64}})
@ Gridap.FESpaces ~/.julia/packages/Gridap/JCqMt/src/FESpaces/ConformingFESpaces.jl:148
[9] FESpace(model::Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, cell_fe::Gridap.FESpaces.CellFE{Vector{Int8}}; trian::Gridap.Geometry.BodyFittedTriangulation{2, 2, Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, Gridap.Geometry.UnstructuredGrid{2, 2, Float64, Gridap.Geometry.NonOriented, Nothing}, Gridap.Arrays.IdentityVector{Int64}}, labels::Gridap.Geometry.FaceLabeling, dirichlet_tags::Vector{String}, dirichlet_masks::Nothing, constraint::Nothing, vector_type::Type)
@ Gridap.FESpaces ~/.julia/packages/Gridap/JCqMt/src/FESpaces/FESpaceFactories.jl:23
[10] FESpace(model::Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, cell_reffe::Gridap.Arrays.CompressedArray{Gridap.ReferenceFEs.GenericRefFE{Nedelec, 2}, 1, Vector{Gridap.ReferenceFEs.GenericRefFE{Nedelec, 2}}, Vector{Int8}}; conformity::Nothing, trian::Gridap.Geometry.BodyFittedTriangulation{2, 2, Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, Gridap.Geometry.UnstructuredGrid{2, 2, Float64, Gridap.Geometry.NonOriented, Nothing}, Gridap.Arrays.IdentityVector{Int64}}, labels::Gridap.Geometry.FaceLabeling, dirichlet_tags::Vector{String}, dirichlet_masks::Nothing, constraint::Nothing, vector_type::Nothing)
@ Gridap.FESpaces ~/.julia/packages/Gridap/JCqMt/src/FESpaces/FESpaceFactories.jl:111
[11] FESpace(model::Gridap.Geometry.UnstructuredDiscreteModel{2, 2, Float64, Gridap.Geometry.NonOriented}, reffe::Tuple{Nedelec, Tuple{DataType, Int64}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}; kwargs::Base.Pairs{Symbol, Vector{String}, Tuple{Symbol}, NamedTuple{(:dirichlet_tags,), Tuple{Vector{String}}}})
@ Gridap.FESpaces ~/.julia/packages/Gridap/JCqMt/src/FESpaces/FESpaceFactories.jl:126
[12] top-level scope
@ ~/git-repos/Gridap.jl/mwe.jl:10
```

# Explanation

As far as I understand GridapGmsh is returning a quadrilateral mesh which is non-oriented

And the current implementation of Nedelec FEs on quadrilaterals does not seem to support non-oriented quadrilateral meshes

Let me explain how I have arrived to that conclusion.

If you execute Table(get_cell_permutations(grid_topology)) with grid_topology being the grid_topology object related to the model

you will get a cell-wise array of arrays, where the array associated to each cell is of size 9 (1..4 vertices, 5..8 edges, 9 cell interior)

the relevant portion of these arrays is the one corresponding to the edges, i.e., positions 5..8 of these arrays

the two possible orientations of an edge within a cell are coded with 1 and 2 resp.

if there is at least one edge for which the orientations of the edge from the perspective of both cells around do not match, i.e., if 1 versus 2 or 2 versus 1, then the mesh is a non-oriented mesh

If you look at the array returned by Table(get_cell_permutations(grid_topology)) you will see 2s and 1s there, so that I guess that the mesh is non-oriented

the indices in the array returned by Table(get_cell_permutations(grid_topology)) are used to indirectly address another array within the CellConformity object, which is called ctype_lface_pindex_pdofs

the third nested index from left to right is the one which is feed from Table(get_cell_permutations(grid_topology))

ctype_lface_pindex_pdofs[ctype][lface][pindex]

the cause of the problem is that the length of ctype_lface_pindex_pdofs[ctype][lface] is 1

so that when we use the 2s in Table(get_cell_permutations(grid_topology)) to feed ctype_lface_pindex_pdofs[ctype][lface][pindex] we get an out-of-bounds error

Contributor guide

Open the contributing guide

Research direction

Reproduce the MWE with GridapGmsh's GmshDiscreteModel and the Nedelec FESpace, then follow the failure through CellDofsNonOriented into ConformingFESpaces.jl. Check the quadrilateral cell permutations and CellConformity indexing; done means the non-oriented quadrilateral mesh no longer raises the reported BoundsError.

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
Quiet
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.