Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog
## [1.14.1] - 2025-11-14
- fix dangling nodes in full ringsector
- add `isconsistent` checks to CI tests
- somewhat extend `isconsistent` checks

## [1.14.0] - 2025-07-01

- add `trim!`/`trim` function to remove precomputed grid components for lightweight storage
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ExtendableGrids"
uuid = "cfc395e8-590f-11e8-1f13-43a2532b2fa8"
authors = ["Juergen Fuhrmann <[email protected]>", "Christian Merdon <[email protected]>", "Johannes Taraz <[email protected]>", "Patrick Jaap <[email protected]>"]
version = "1.14.0"
version = "1.14.1"

[deps]
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
Expand Down
5 changes: 5 additions & 0 deletions examples/examples1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ end
using Test

function runtests()
@test isconsistent(interval_from_vector())
@test isconsistent(interval_localref())
@test isconsistent(interval_multiregion())
@test isconsistent(interval_subgrid())

@test numbers_match(interval_from_vector(), 21, 20, 2)
@test numbers_match(interval_localref(), 27, 26, 2)
@test numbers_match(interval_multiregion(), 21, 20, 3)
Expand Down
9 changes: 9 additions & 0 deletions examples/examples2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,22 @@ end
# Unit tests
using Test
function runtests()

@test isconsistent(rectangle())
@test isconsistent(rectangle_localref())
@test isconsistent(rectangle_multiregion())
@test isconsistent(rectangle_subgrid())
@test isconsistent(rect2d_bregion_function())

@test numbers_match(rectangle(), 441, 800, 80)
@test numbers_match(rectangle_localref(), 729, 1352, 104)
@test numbers_match(rectangle_multiregion(), 441, 800, 100)
@test numbers_match(rectangle_subgrid(), 360, 600, 120)
@test numbers_match(rect2d_bregion_function(), 79, 112, 44)

g, sg, sf = sorted_subgrid()
@test isconsistent(g)
@test isconsistent(sg)
@test numbers_match(g, 187, 306, 66)
@test numbers_match(sg, 17, 16, 0)
@test issorted(view(sg[Coordinates], 1, :))
Expand Down
4 changes: 4 additions & 0 deletions examples/examples3d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ end
using Test

function runtests()
@test isconsistent(quadrilateral())
@test isconsistent(cross3d())


@test numbers_match(quadrilateral(), 330, 1200, 440)
@test mask_bedges()
@test numbers_match(cross3d(), 189, 480, 344)
Expand Down
14 changes: 14 additions & 0 deletions src/adjacency.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,20 @@ function Base.append!(adj::VariableTargetAdjacency, column)
return push!(adj.colstart, length(adj.colentries) + 1)
end

"""
$(TYPEDSIGNATURES)

Maximum for VariableTargetAdjacency
"""
Base.maximum(adj::VariableTargetAdjacency) = Base.maximum(adj.colentries)

"""
$(TYPEDSIGNATURES)

Minimum for VariableTargetAdjacency
"""
Base.minimum(adj::VariableTargetAdjacency) = Base.minimum(adj.colentries)

"""
$(TYPEDEF)

Expand Down
10 changes: 6 additions & 4 deletions src/commongrids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,12 @@ end


"""
ringsector(rad,ang; eltype=Triangle2D)
ringsector(rad,ang)

Sector of ring or full ring (if `ang[begin]-ang[end]≈2π`)
"""
function ringsector(rad, ang; eltype = Triangle2D)
Tv = Float32
function ringsector(rad, ang)
Tv = promote_type(eltype(rad), eltype(ang))
Ti = Int32

coord = ElasticArray{Tv, 2}(undef, 2, 0)
Expand All @@ -201,7 +201,9 @@ function ringsector(rad, ang; eltype = Triangle2D)
x = cos(ϕ)
y = sin(ϕ)
for irad in 1:nrad
append!(coord, (rad[irad] * x, rad[irad] * y))
if iarc < narc || !fullcircle
append!(coord, (rad[irad] * x, rad[irad] * y))
end
icoord = size(coord, 2)
if irad < nrad
if iarc < narc
Expand Down
24 changes: 24 additions & 0 deletions src/extendablegrid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,30 @@ or, if `warnoly==true`, return false.
"""
function isconsistent(grid; warnonly = false)
consistent = true
nnodes = num_nodes(grid)

if maximum(grid[CellNodes]) != nnodes
@warn "maximum(grid[CellNodes])!=nnodes"
consistent = false
end

if minimum(grid[CellNodes]) != 1
@warn "minimum(grid[CellNodes])!=1"
consistent = false
end

if length(grid[BFaceNodes]) > 0
if maximum(grid[BFaceNodes]) > nnodes
@warn "maximum(grid[BFaceNodes])>nnodes"
consistent = false
end

if minimum(grid[BFaceNodes]) < 1
@warn "minimum(grid[BFaceNodes])<1"
consistent = false
end
end

dnodes = dangling_nodes(grid)
if !isnothing(dnodes)
@warn "Found dangling nodes: $(dnodes)"
Expand Down
17 changes: 17 additions & 0 deletions test/gmsh.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,41 +51,51 @@ end
ExtendableGrids.simplexgrid_to_gmsh(grid1; filename = joinpath(path, "testfile.msh"))

grid2 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "testfile.msh"); Tc = Float32, Ti = Int64)
@test isconsistent(grid2)

@test seemingly_equal(grid2, grid1; sort = true, confidence = :low)
@test seemingly_equal(grid2, grid1; sort = true, confidence = :full)

grid1 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "sto_2d.msh"); Tc = Float64, Ti = Int64)
@test isconsistent(grid1)

ExtendableGrids.simplexgrid_to_gmsh(grid1; filename = joinpath(path, "testfile.msh"))
grid2 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "testfile.msh"); Tc = Float64, Ti = Int64)
@test isconsistent(grid2)

@test seemingly_equal(grid1, grid2; sort = true, confidence = :low)
@test seemingly_equal(grid1, grid2; sort = true, confidence = :full)

grid1 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "sto_3d.msh"); Tc = Float32, Ti = Int64)
@test isconsistent(grid1)

ExtendableGrids.simplexgrid_to_gmsh(grid1; filename = joinpath(path, "testfile.msh"))
grid2 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "testfile.msh"); Tc = Float64, Ti = Int32)
@test isconsistent(grid2)

@test seemingly_equal(grid1, grid2; sort = true, confidence = :low)
@test seemingly_equal(grid1, grid2; sort = true, confidence = :full)

grid1 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "sto_2d.msh"))
@test isconsistent(grid1)

grid2 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "sto_3d.msh"); Tc = Float32, Ti = Int32)
@test isconsistent(grid2)

@test !seemingly_equal(grid1, grid2; sort = true, confidence = :low)
@test !seemingly_equal(grid1, grid2; sort = true, confidence = :full)

grid1 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "testmesh.gmsh"); incomplete = true)
ExtendableGrids.seal!(grid1; encode = false)
@test isconsistent(grid1)

ExtendableGrids.simplexgrid_to_gmsh(grid1; filename = joinpath(path, "completed_testfile.msh"))
grid2 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "completed_testfile.msh"))
@test isconsistent(grid2)

grid3 = ExtendableGrids.simplexgrid_from_gmsh(joinpath(path, "testmesh.gmsh"); incomplete = true)
ExtendableGrids.seal!(grid3; encode = true)
@test isconsistent(grid3)

@test seemingly_equal(grid1, grid2; sort = true, confidence = :low)
@test seemingly_equal(grid1, grid2; sort = true, confidence = :full)
Expand All @@ -98,7 +108,9 @@ end
grid2 = simplexgrid(x, x)
grid3 = simplexgrid(x, x)
ExtendableGrids.seal!(grid2)
@test isconsistent(grid2)
ExtendableGrids.seal!(grid3; encode = false)
@test isconsistent(grid3)

@test seemingly_equal(grid2, grid1; sort = true, confidence = :low)
@test seemingly_equal(grid2, grid1; sort = true, confidence = :full)
Expand All @@ -109,9 +121,11 @@ end
@testset "Read/write mixed gmsh 2d" begin
path = joinpath(pkgdir(ExtendableGrids), "test")
grid1 = ExtendableGrids.mixedgrid_from_gmsh(joinpath(path, "mixedgrid_2d.msh"); Tc = Float64, Ti = Int64)
@test_broken isconsistent(grid1)

ExtendableGrids.mixedgrid_to_gmsh(grid1; filename = joinpath(path, "testfile.msh"))
grid2 = ExtendableGrids.mixedgrid_from_gmsh(joinpath(path, "testfile.msh"); Tc = Float32, Ti = UInt64)
@test_broken isconsistent(grid2)

@test seemingly_equal(grid1, grid2; sort = true, confidence = :low)
@test seemingly_equal(grid1, grid2; sort = true, confidence = :full)
Expand All @@ -121,6 +135,9 @@ end
path = joinpath(pkgdir(ExtendableGrids), "test")
grid = simplexgrid(joinpath(path, "disk1hole.geo"))
@test num_cells(grid) > 0
@test_broken isconsistent(grid)

grid = simplexgrid(joinpath(path, "cube6.geo"))
@test num_cells(grid) > 0
@test isconsistent(grid)
end
3 changes: 3 additions & 0 deletions test/partitioning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Metis


for grid in (grid1, grid2, grid3)
@test isconsistent(grid)
@test num_pcolors(grid) == 1
@test num_partitions(grid) == 1
@test pcolors(grid) == 1:1
Expand All @@ -28,6 +29,7 @@ import Metis

for npart in [10, 15, 20]
grid4 = partition(grid1, PlainMetisPartitioning(npart = npart); nodes = true, keep_nodepermutation = true)
@test isconsistent(grid4)
@test num_pcolors(grid4) > 1
@test num_partitions(grid4) == npart
@test pcolors(grid4) |> length > 0
Expand All @@ -39,6 +41,7 @@ import Metis

for npart in [3, 4, 5, 6]
grid4 = partition(grid1, RecursiveMetisPartitioning(npart = npart); nodes = true, keep_nodepermutation = true)
@test isconsistent(grid4)
@test num_pcolors(grid4) > 1
@test num_partitions(grid4) > npart
@test pcolors(grid4) |> length > 0
Expand Down
14 changes: 13 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ end
end
end

@testset "Common grids" begin
include("test_commongrids.jl")
end

@testset "Base.map" begin
X = 0:0.1:1
fx(x) = x
Expand Down Expand Up @@ -291,11 +295,13 @@ end
sub2 = subgen(; region = 3)

@test numbers_match(subgen(), 756, 3000, 950)
@test isconsistent(subgen())

X = collect(0:0.25:1)
gxy = simplexgrid(X, X)
gxyz = simplexgrid(gxy, X)
g = simplexgrid(X, X, X)
@test isconsistent(gxyz)
@test numbers_match(gxyz, 125, 384, 192)
@test g[Coordinates] ≈ gxyz[Coordinates]
end
Expand All @@ -306,6 +312,7 @@ end
grid = grid_unitsquare(Triangle2D)
grid[CellRegions] = Int32[1, 2, 2, 1]
sgrid = subgrid(grid, [1])
@test isconsistent(sgrid)
@test sgrid[ParentGridRelation] == SubGrid{ON_CELLS}

## check if CellParents are assigned correctly
Expand All @@ -324,9 +331,11 @@ end
@testset "ParentGridRelation-RefinedGrid" begin
## generate a refined
grid = grid_unitsquare(Triangle2D)
@test isconsistent(grid)

## check uniform refinement
rgrid = uniform_refine(grid)
@test isconsistent(rgrid)
@test rgrid[ParentGridRelation] == RefinedGrid

## check if CellParents and BFaceParents are set
Expand All @@ -335,6 +344,7 @@ end

## check barycentric refinement
rgrid = barycentric_refine(grid)
@test isconsistent(rgrid)
@test rgrid[ParentGridRelation] == RefinedGrid

## check if CellParents and BFaceParents are set
Expand Down Expand Up @@ -373,7 +383,9 @@ function tglue(; dim = 2, breg = 0)
g2 = simplexgrid(X2, Y2, Z2)
end

return glue(g1, g2; interface = breg)
grid = glue(g1, g2; interface = breg)
@test isconsistent(grid)
return grid
end

@testset "Glue" begin
Expand Down
26 changes: 26 additions & 0 deletions test/test_commongrids.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@test isconsistent(reference_domain(Edge1D))
@test isconsistent(reference_domain(Triangle2D))
@test isconsistent(reference_domain(Parallelogram2D))
@test isconsistent(reference_domain(Tetrahedron3D))
@test isconsistent(reference_domain(Hexahedron3D))

@test isconsistent(grid_unitcube(Parallelepiped3D))
@test isconsistent(grid_unitcube(Tetrahedron3D))
@test isconsistent(grid_unitsquare(Triangle2D))
@test isconsistent(grid_unitsquare(Parallelogram2D))
@test isconsistent(grid_lshape(Triangle2D))
@test isconsistent(grid_unitsquare_mixedgeometries())

@test isconsistent(
ringsector(
range(0, 1, length = 10),
range(0, π / 2, length = 10)
)
)

@test isconsistent(
ringsector(
range(0, 1, length = 10),
range(0, 2π, length = 10)
)
)
5 changes: 3 additions & 2 deletions test/test_gridstuff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ end
function check_uniform_refinement(xgrid, bary::Bool)
xgrid2 = bary ? barycentric_refine(xgrid) : uniform_refine(xgrid)
minvol = minimum(xgrid2[CellVolumes])
return minvol > 0
return minvol > 0 && isconsistent(xgrid2)
end


Expand Down Expand Up @@ -170,5 +170,6 @@ function run_grid_tests()
@test check_uniform_refinement(reference_domain(Triangle2D), true)
@test check_uniform_refinement(reference_domain(Parallelogram2D), false)
@test check_uniform_refinement(reference_domain(Tetrahedron3D), false)
return @test check_uniform_refinement(reference_domain(Tetrahedron3D), true)
@test check_uniform_refinement(reference_domain(Tetrahedron3D), true)
return nothing
end
4 changes: 4 additions & 0 deletions test/tritet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ end

@testset "Triangulate" begin
@test isa(example_domain_regions(), ExtendableGrid)
@test isconsistent(example_domain_regions())
@test isa(example_domain_holes(), ExtendableGrid)
@test isconsistent(example_domain_holes())
end

function prism(vol = 2)
Expand Down Expand Up @@ -109,5 +111,7 @@ end

@testset "TetGen" begin
@test isa(prism(), ExtendableGrid)
@test isconsistent(prism())
@test isa(material_prism(), ExtendableGrid)
@test isconsistent(material_prism())
end
Loading