From 357e35bf7f77985bc205936cfeca37606a345104 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Thu, 8 Sep 2022 18:57:48 +0200 Subject: [PATCH] Fix face node ordering for Tetrahedron{3} (#475) This commit fixes the ordering for Ferrite.faces(...) s.t. they are counter clockwise from the outside. Also adjust the face order for Lagrange{3,RefCube,2}() to match Lagrange{3,RefCube,1}(). --- src/Grid/grid.jl | 2 +- src/interpolations.jl | 13 ++++++++++--- test/test_interpolations.jl | 24 ++++++++++++++++++++++++ test/test_utils.jl | 2 +- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/Grid/grid.jl b/src/Grid/grid.jl index 536502fccc..f62966e89f 100644 --- a/src/Grid/grid.jl +++ b/src/Grid/grid.jl @@ -727,7 +727,7 @@ faces(c::Union{Quadrilateral,QuadraticQuadrilateral}) = ((c.nodes[1],c.nodes[2]) edges(c::Line3D) = ((c.nodes[1],c.nodes[2]),) vertices(c::Union{Tetrahedron,QuadraticTetrahedron}) = (c.nodes[1], c.nodes[2], c.nodes[3], c.nodes[4]) edges(c::Union{Tetrahedron,QuadraticTetrahedron}) = ((c.nodes[1],c.nodes[2]), (c.nodes[2],c.nodes[3]), (c.nodes[3],c.nodes[1]), (c.nodes[1],c.nodes[4]), (c.nodes[2],c.nodes[4]), (c.nodes[3],c.nodes[4])) -faces(c::Union{Tetrahedron,QuadraticTetrahedron}) = ((c.nodes[1],c.nodes[2],c.nodes[3]), (c.nodes[1],c.nodes[2],c.nodes[4]), (c.nodes[2],c.nodes[3],c.nodes[4]), (c.nodes[1],c.nodes[4],c.nodes[3])) +faces(c::Union{Tetrahedron,QuadraticTetrahedron}) = ((c.nodes[1],c.nodes[3],c.nodes[2]), (c.nodes[1],c.nodes[2],c.nodes[4]), (c.nodes[2],c.nodes[3],c.nodes[4]), (c.nodes[1],c.nodes[4],c.nodes[3])) vertices(c::Union{Hexahedron,Cell{3,20,6}}) = (c.nodes[1], c.nodes[2], c.nodes[3], c.nodes[4], c.nodes[5], c.nodes[6], c.nodes[7], c.nodes[8]) edges(c::Union{Hexahedron,Cell{3,20,6}}) = ((c.nodes[1],c.nodes[2]), (c.nodes[2],c.nodes[3]), (c.nodes[3],c.nodes[4]), (c.nodes[4],c.nodes[1]), (c.nodes[5],c.nodes[6]), (c.nodes[6],c.nodes[7]), (c.nodes[7],c.nodes[8]), (c.nodes[8],c.nodes[5]), (c.nodes[1],c.nodes[5]), (c.nodes[2],c.nodes[6]), (c.nodes[3],c.nodes[7]), (c.nodes[4],c.nodes[8])) faces(c::Union{Hexahedron,Cell{3,20,6}}) = ((c.nodes[1],c.nodes[4],c.nodes[3],c.nodes[2]), (c.nodes[1],c.nodes[2],c.nodes[6],c.nodes[5]), (c.nodes[2],c.nodes[3],c.nodes[7],c.nodes[6]), (c.nodes[3],c.nodes[4],c.nodes[8],c.nodes[7]), (c.nodes[1],c.nodes[5],c.nodes[8],c.nodes[4]), (c.nodes[5],c.nodes[6],c.nodes[7],c.nodes[8])) diff --git a/src/interpolations.jl b/src/interpolations.jl index b4c2f0946a..2cb5ada71d 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -337,7 +337,7 @@ end getnbasefunctions(::Lagrange{3,RefTetrahedron,1}) = 4 nvertexdofs(::Lagrange{3,RefTetrahedron,1}) = 1 -faces(::Lagrange{3,RefTetrahedron,1}) = ((1,2,3), (1,2,4), (2,3,4), (1,4,3)) +faces(::Lagrange{3,RefTetrahedron,1}) = ((1,3,2), (1,2,4), (2,3,4), (1,4,3)) edges(::Lagrange{3,RefTetrahedron,1}) = ((1,2), (2,3), (3,1), (1,4), (2,4), (3,4)) function reference_coordinates(::Lagrange{3,RefTetrahedron,1}) @@ -365,7 +365,7 @@ getnbasefunctions(::Lagrange{3,RefTetrahedron,2}) = 10 nvertexdofs(::Lagrange{3,RefTetrahedron,2}) = 1 nedgedofs(::Lagrange{3,RefTetrahedron,2}) = 1 -faces(::Lagrange{3,RefTetrahedron,2}) = ((1,2,3,5,6,7), (1,2,4,5,9,8), (2,3,4,6,10,9), (1,4,3,8,10,7)) +faces(::Lagrange{3,RefTetrahedron,2}) = ((1,3,2,7,6,5), (1,2,4,5,9,8), (2,3,4,6,10,9), (1,4,3,8,10,7)) edges(::Lagrange{3,RefTetrahedron,2}) = ((1,5,2), (2,6,3), (3,7,1), (1,8,4), (2,9,4), (3,10,4)) function reference_coordinates(::Lagrange{3,RefTetrahedron,2}) @@ -446,7 +446,14 @@ nedgedofs(::Lagrange{3,RefCube,2}) = 1 nfacedofs(::Lagrange{3,RefCube,2}) = 1 ncelldofs(::Lagrange{3,RefCube,2}) = 1 -faces(::Lagrange{3,RefCube,2}) = ((1,2,6,5, 9,18,13,17, 23), (2,3,7,6, 10,19,14,18, 22), (3,4,8,7, 11,20,15,19, 24), (1,5,8,4, 12,17,16,20, 21), (1,4,3,2, 9,10,11,12, 25), (5,6,7,8, 13,14,15,16, 26)) +faces(::Lagrange{3,RefCube,2}) = ( + (1,4,3,2, 9,10,11,12, 25), + (1,2,6,5, 9,18,13,17, 23), + (2,3,7,6, 10,19,14,18, 22), + (3,4,8,7, 11,20,15,19, 24), + (1,5,8,4, 12,17,16,20, 21), + (5,6,7,8, 13,14,15,16, 26), +) edges(::Lagrange{3,RefCube,2}) = ((1,2, 9), (2,3, 10), (3,4, 11), (4,1, 12), (1,5, 16), (2,6, 19), (3,7, 18), (4,8, 19), (5,6, 13), (6,7, 14), (7,8, 15), (8,5, 16)) function reference_coordinates(::Lagrange{3,RefCube,2}) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 5eaac898d4..2e18d9d11c 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -51,6 +51,30 @@ for interpolation in (Lagrange{1, RefCube, 1}(), end end end + + # Test that faces(...) return in counter clockwise order (viewing from the outside) + if interpolation isa Lagrange + function __outward_normal(coords::Vector{<:Vec{1}}, nodes) + n = coords[nodes[1]] + return n / norm(n) + end + function __outward_normal(coords::Vector{<:Vec{2}}, nodes) + p1 = coords[nodes[1]] + p2 = coords[nodes[2]] + n = Vec{2}((p2[2] - p1[2], - p2[1] + p1[1])) + return n / norm(n) + end + function __outward_normal(coords::Vector{<:Vec{3}}, nodes) + p1 = coords[nodes[1]] + p2 = coords[nodes[2]] + p3 = coords[nodes[3]] + n = (p3 - p2) × (p1 - p2) + return n / norm(n) + end + for (facenodes, normal) in zip(Ferrite.faces(interpolation), reference_normals(interpolation)) + @test __outward_normal(coords, facenodes) ≈ normal + end + end end end diff --git a/test/test_utils.jl b/test/test_utils.jl index 716e711d7e..d3c5e251b7 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -44,7 +44,7 @@ function reference_normals(::Lagrange{3, RefTetrahedron}) end # Lagrange{3, Cube} -function reference_normals(::Lagrange{3, RefCube, 1}) +function reference_normals(::Lagrange{3, RefCube}) return [Vec{3, Float64}(( 0.0, 0.0, -1.0)), Vec{3, Float64}(( 0.0, -1.0, 0.0)), Vec{3, Float64}(( 1.0, 0.0, 0.0)),