Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set of improvements/fixes in Gridap.Adaptivity module #886

Merged
merged 30 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
faeb23b
Started working on fine-to-coarse dof correspondance
JordiManyer Mar 15, 2023
51f8401
Working concept
JordiManyer Mar 15, 2023
1fafff7
Generalised approach, needs testing for HEX
JordiManyer Mar 19, 2023
c9cff2a
Implemented coarse_nodes_above_fine_nodes, only tested for QUAD
JordiManyer Mar 19, 2023
8bfc6f3
Renamed method to get_face_subface_ldof_to_cell_ldof
JordiManyer Mar 24, 2023
4980531
Added get_d_to_face_to_parent_face for QUAD & TRI
JordiManyer Mar 24, 2023
5fab8ad
Tests for coarse-to-fine relabeling
JordiManyer Mar 26, 2023
8eb11e0
Fixed face labeling for unstructured refined meshes
JordiManyer Mar 26, 2023
0884381
Small bugfix
JordiManyer Mar 26, 2023
3a34204
Added some documentation for the new methods
JordiManyer Mar 26, 2023
2e00274
Added support for HEX
JordiManyer Apr 12, 2023
1e0300b
Merge branch 'master' of github.com:gridap/Gridap.jl into refinement-…
JordiManyer Apr 12, 2023
2fa1cf3
Bugfix: get_face_subface_ldof_to_cell_ldof for HEX faces
JordiManyer Apr 20, 2023
0e9e065
Merge branch 'master' of github.com:gridap/Gridap.jl into refinement-…
amartinhuertas Jul 11, 2023
6f5dc0d
Merge branch 'master' of github.com:gridap/Gridap.jl into refinement-…
amartinhuertas Jul 18, 2023
04b2ac2
Added fix for change_domain when both adapted triangulations are the …
JordiManyer Aug 2, 2023
0049e7b
Added fix to change_domain_n2o for distributed meshes
JordiManyer Aug 2, 2023
6049786
AdaptivityGlue now accepts a Table as n2o_cell_to_child_id
JordiManyer Aug 2, 2023
b698d6b
Added generic version of get_d_to_face_to_parent_face
JordiManyer Aug 3, 2023
162569b
Added generic version of get_d_to_face_to_child_faces
JordiManyer Aug 3, 2023
1066a22
Moved constructors for CartDM out of the struct.
JordiManyer Aug 3, 2023
dfae593
Fix label refining for CartesianDiscreteModels
JordiManyer Aug 3, 2023
bb450f5
Bugfix: Allow domain limits to be floats in CDM refinement routines
JordiManyer Aug 3, 2023
ac6ffc0
Added get_new_cell_refinement_rules for MixedGlue
JordiManyer Aug 3, 2023
b57e715
Added OldToNewFields and change_domain for MixedGlues
JordiManyer Aug 3, 2023
7c0ed0e
Updated NEWS.md
JordiManyer Aug 3, 2023
e76ae7b
Small bugfix
JordiManyer Aug 3, 2023
783010a
Minor change
JordiManyer Aug 3, 2023
c7a5edd
Small bugfix
JordiManyer Aug 3, 2023
39e0175
Small bugfix
JordiManyer Aug 3, 2023
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
14 changes: 14 additions & 0 deletions src/Adaptivity/EdgeBasedRefinement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,20 @@ function _has_interior_point(rr::RefinementRule,::RedRefinement)
return false
end

# [Face dimension][Coarse Face id] -> [Fine faces]
function get_d_to_face_to_child_faces(rr::RefinementRule,::RedRefinement)
p = get_polytope(rr)
if p == QUAD
return [
[Int32[1],Int32[2],Int32[3],Int32[4]], # [Coarse Node] -> [Fine Node]
[Int32[1,5],Int32[8,11],Int32[3,9],Int32[7,12]], # [Coarse Edge] -> [Fine Edge]
[Int32[1,2,3,4]] # [Coarse Cell] -> [Fine Cells]
]
else
@notimplemented
end
end

"""
Edge-based RefinementRule where a new vertex is added to
a single edge of the original Polytope.
Expand Down
86 changes: 86 additions & 0 deletions src/Adaptivity/RefinementRules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,92 @@ function bundle_points_by_subcell(rr::RefinementRule,x::AbstractArray{<:Point})
return Table(data,ptrs)
end


# Faces to child faces, dof maps

# [Face dimension][Coarse Face id] -> [Fine faces]
function get_d_to_face_to_child_faces(rr::RefinementRule)
get_d_to_face_to_child_faces(rr,RefinementRuleType(rr))
end

function get_d_to_face_to_child_faces(::RefinementRule,::RefinementRuleType)
@notimplemented
end

function _get_terms(poly::Polytope,orders)
_nodes, facenodes = ReferenceFEs._compute_nodes(poly,orders)
terms = ReferenceFEs._coords_to_terms(_nodes,orders)
return terms
end

function _get_face_orders(p::Polytope{Dc},D::Int,orders::Tuple) where Dc
@check length(orders) == Dc
@check 1 <= D < Dc
@check is_n_cube(p)

if D == 1 # Edges (2D, 3D)
tangents = get_edge_tangent(p)
face_orders = map(tangents) do t
axis = findfirst(i -> abs(t[i]) > 0.5 ,1:Dc)
return [orders[axis]]
end
elseif D == Dc-1 # Faces (3D)
normals = get_facet_normal(p)
face_orders = map(normals) do n
mask = map(i -> abs(n[i]) < 1.e-3,1:Dc)
return [orders[mask]...]
end
else
@notimplemented
end

return face_orders
end

function coarse_nodes_above_fine_nodes(rr::RefinementRule{ExtrusionPolytope{Dc}},
JordiManyer marked this conversation as resolved.
Show resolved Hide resolved
fine_orders::NTuple{Dc,<:Integer},
D::Int) where Dc
poly = get_polytope(rr)
coarse_orders = 2 .* fine_orders
coarse_reffe = ReferenceFE(poly,lagrangian,Float64,coarse_orders)
coarse_face_polys = CompressedArray(ReferenceFEs._compute_reffaces_and_face_types(poly,Val(D))...)
c_edge_to_coarse_dof = coarse_reffe.face_nodes[get_dimranges(poly)[D+1]]

model = get_ref_grid(rr)
fine_face_grid = Grid(ReferenceFE{D},model)
fine_face_polys = CompressedArray(map(get_polytope,get_reffes(fine_face_grid)),get_cell_type(fine_face_grid))

d_to_face_to_child_faces = get_d_to_face_to_child_faces(rr)
face_to_child_faces = d_to_face_to_child_faces[D+1]

coarse_face_orders = _get_face_orders(poly,D,coarse_orders)
fine_face_orders = _get_face_orders(poly,D,fine_orders)

num_coarse_faces = num_faces(coarse_reffe,D)
coarse_dofs_above_fine_dofs = Vector{Vector{Vector{Int32}}}(undef,num_coarse_faces)
for cF in 1:num_coarse_faces
coarse_face_poly = coarse_face_polys[cF]
coarse_terms = _get_terms(coarse_face_poly,coarse_face_orders[cF])
coarse_dofs = zeros(Int32,Tuple(maximum(coarse_terms)))
coarse_dofs[coarse_terms] .= c_edge_to_coarse_dof[cF]

child_faces = face_to_child_faces[cF]
fine_dofs = Vector{Vector{Int32}}(undef,length(child_faces))
for (i,fF) in enumerate(child_faces)
fine_face_poly = fine_face_polys[fF]
fine_terms = _get_terms(fine_face_poly,fine_face_orders[cF])

local_dof_range = map(o->(i-1)*o+1:i*o+1,fine_face_orders[cF])
local_coarse_dofs = view(coarse_dofs,local_dof_range...)
fine_dofs[i] = map(Reindex(local_coarse_dofs),fine_terms)
end
coarse_dofs_above_fine_dofs[cF] = fine_dofs
end

return coarse_dofs_above_fine_dofs
end


# GenericRefinement Rule

function RefinementRule(reffe::LagrangianRefFE{D},nrefs::Integer;kwargs...) where D
Expand Down
94 changes: 94 additions & 0 deletions test/AdaptivityTests/RefinementRuleBoundaryTests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
module RefinementRuleBoundaryTests

using Test
using Gridap
using Gridap.Helpers
using Gridap.Adaptivity
using Gridap.Geometry
using Gridap.ReferenceFEs
using Gridap.Arrays

function _get_terms(poly::Polytope,orders)
_nodes, facenodes = Gridap.ReferenceFEs._compute_nodes(poly,orders)
terms = Gridap.ReferenceFEs._coords_to_terms(_nodes,orders)
return terms
end

function _get_face_orders(p::Polytope{Dc},D::Int,orders::Tuple) where Dc
@check length(orders) == Dc
@check 1 <= D < Dc
@check is_n_cube(p)

if D == 1 # Edges (2D, 3D)
tangents = get_edge_tangent(p)
face_orders = map(tangents) do t
axis = findfirst(i -> abs(t[i]) > 0.5 ,1:Dc)
return [orders[axis]]
end
elseif D == Dc-1 # Faces (3D)
normals = get_facet_normal(p)
face_orders = map(normals) do n
mask = map(i -> abs(n[i]) < 1.e-3,1:Dc)
return [orders[mask]...]
end
else
@notimplemented
end

return face_orders
end

D = 1
rr = Gridap.Adaptivity.RedRefinementRule(QUAD)
poly = get_polytope(rr)
coarse_orders = (4,4)
coarse_reffe = ReferenceFE(poly,lagrangian,Float64,coarse_orders)
coarse_face_nodes = coarse_reffe.face_nodes
coarse_face_polys = CompressedArray(Gridap.ReferenceFEs._compute_reffaces_and_face_types(poly,Val(D))...)
c_edge_to_coarse_dof = coarse_face_nodes[get_dimranges(poly)[D+1]]

cell_polys = Gridap.Adaptivity.get_cell_polytopes(rr)
fine_orders = coarse_orders .÷ 2
fine_reffe = lazy_map(p->ReferenceFE(p,lagrangian,Float64,fine_orders),cell_polys)

model = Gridap.Adaptivity.get_ref_grid(rr)

fine_topo = get_grid_topology(model)
fine_boundary_faces = findall(get_isboundary_face(fine_topo,D))
fine_face_grid = Grid(ReferenceFE{D},model)
fine_face_polys = CompressedArray(map(get_polytope,get_reffes(fine_face_grid)),get_cell_type(fine_face_grid))
fine_boundary_polys = lazy_map(Reindex(fine_face_polys),fine_boundary_faces)

d_to_face_to_child_faces = Gridap.Adaptivity.get_d_to_face_to_child_faces(rr)
face_to_child_faces = d_to_face_to_child_faces[D+1]

coarse_face_orders = _get_face_orders(poly,D,coarse_orders)
fine_face_orders = _get_face_orders(poly,D,fine_orders)

num_coarse_faces = num_faces(coarse_reffe,D)
coarse_dofs_above_fine_dofs = Vector{Vector{Vector{Int32}}}(undef,num_coarse_faces)
for cF in 1:num_coarse_faces
coarse_face_poly = coarse_face_polys[cF]
coarse_terms = _get_terms(coarse_face_poly,coarse_face_orders[cF])
coarse_dofs = zeros(Int32,Tuple(maximum(coarse_terms)))
coarse_dofs[coarse_terms] .= c_edge_to_coarse_dof[cF]

child_faces = face_to_child_faces[cF]
fine_dofs = Vector{Vector{Int32}}(undef,length(child_faces))
for (i,fF) in enumerate(child_faces)
fine_face_poly = fine_face_polys[fF]
fine_terms = _get_terms(fine_face_poly,fine_face_orders[cF])

local_dof_range = map(o->(i-1)*o+1:i*o+1,fine_face_orders[cF])
local_coarse_dofs = view(coarse_dofs,local_dof_range...)
fine_dofs[i] = map(Reindex(local_coarse_dofs),fine_terms)
end
coarse_dofs_above_fine_dofs[cF] = fine_dofs
end


# Test the final function

res = Adaptivity.coarse_nodes_above_fine_nodes(rr,(2,2),1)

end