From 5bb7d4af9fc13766f3deebae48b080daa776e4ba Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:14:20 +1000 Subject: [PATCH 01/74] DistributedDiscreteGeometry implementation --- src/Distributed/Distributed.jl | 3 + .../DistributedDiscreteGeometries.jl | 102 ++++++++++++ src/Distributed/DistributedDiscretizations.jl | 8 +- .../DistributedDiscreteGeometryPoissonTest.jl | 148 ++++++++++++++++++ .../DistributedDiscreteGeometryPoissonTest.jl | 8 + test/DistributedTests/sequential/runtests.jl | 1 + 6 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 src/Distributed/DistributedDiscreteGeometries.jl create mode 100644 test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index aadb4d5b..4fc3e95e 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -43,6 +43,7 @@ import GridapEmbedded.Interfaces: EmbeddedBoundary import GridapEmbedded.Interfaces: compute_bgfacet_to_inoutcut import GridapEmbedded.Interfaces: compute_bgcell_to_inoutcut import GridapEmbedded.CSG: get_geometry +import GridapEmbedded.LevelSetCutters: discretize import Gridap.Geometry: Triangulation import Gridap.Geometry: SkeletonTriangulation import Gridap.Geometry: BoundaryTriangulation @@ -52,6 +53,8 @@ import GridapDistributed: remove_ghost_cells include("DistributedDiscretizations.jl") +include("DistributedDiscreteGeometries.jl") + include("DistributedAgFEM.jl") include("DistributedQuadratures.jl") diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl new file mode 100644 index 00000000..ce3c8be3 --- /dev/null +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -0,0 +1,102 @@ +struct DistributedDiscreteGeometry{A} <: GridapType + geometries::A +end + +local_views(a::DistributedDiscreteGeometry) = a.geometries + +function DistributedDiscreteGeometry(φh::CellField,model::DistributedDiscreteModel) + gids = get_cell_gids(model) + geometries = map(local_views(model),local_views(gids),local_views(φh)) do model,gids,φh + ownmodel = remove_ghost_cells(model,gids) + point_to_coords = collect1d(get_node_coordinates(ownmodel)) + DiscreteGeometry(φh(point_to_coords),point_to_coords) + end + DistributedDiscreteGeometry(geometries) +end + +function get_geometry(a::AbstractArray{<:DiscreteGeometry}) + DistributedDiscreteGeometry(a) +end + +function discretize(a::AnalyticalGeometry,model::DistributedDiscreteModel) + gids = get_cell_gids(model) + geometries = map(local_views(model),local_views(gids)) do model,gids + ownmodel = remove_ghost_cells(model,gids) + point_to_coords = collect1d(get_node_coordinates(ownmodel)) + discretize(a,point_to_coords) + end + DistributedDiscreteGeometry(geometries) +end + +function cut(cutter::Cutter,bgmodel::DistributedDiscreteModel,geom::DistributedDiscreteGeometry) + gids = get_cell_gids(bgmodel) + cuts = map(local_views(bgmodel),local_views(gids),local_views(geom)) do bgmodel,gids,geom + ownmodel = remove_ghost_cells(bgmodel,gids) + cutgeo = cut(cutter,ownmodel,geom) + change_bgmodel(cutgeo,bgmodel,own_to_local(gids)) + end + consistent_bgcell_to_inoutcut!(cuts,gids) + DistributedEmbeddedDiscretization(cuts,bgmodel) +end + +function cut_facets(cutter::Cutter,bgmodel::DistributedDiscreteModel,geom::DistributedDiscreteGeometry) + D = map(num_dims,local_views(bgmodel)) |> PartitionedArrays.getany + cell_gids = get_cell_gids(bgmodel) + facet_gids = get_face_gids(bgmodel,D-1) + cuts = map( + local_views(bgmodel), + local_views(cell_gids), + local_views(facet_gids), + local_views(geom)) do bgmodel,cell_gids,facet_gids,geom + ownmodel = remove_ghost_cells(bgmodel,cell_gids) + facet_to_pfacet = get_face_to_parent_face(ownmodel,D-1) + cutfacets = cut_facets(cutter,ownmodel,geom) + cutfacets = change_bgmodel(cutfacets,bgmodel,facet_to_pfacet) + remove_ghost_subfacets(cutfacets,facet_gids) + end + consistent_bgfacet_to_inoutcut!(cuts,facet_gids) + DistributedEmbeddedDiscretization(cuts,bgmodel) +end + +function distributed_embedded_triangulation( + T, + cutgeo::DistributedEmbeddedDiscretization, + cutinorout, + geom::DistributedDiscreteGeometry) + + trians = map(local_views(cutgeo),local_views(geom)) do lcutgeo,lgeom + T(lcutgeo,cutinorout,lgeom) + end + bgmodel = get_background_model(cutgeo) + DistributedTriangulation(trians,bgmodel) +end + +function distributed_aggregate( + strategy::AggregateCutCellsByThreshold, + cut::DistributedEmbeddedDiscretization, + geo::DistributedDiscreteGeometry, + in_or_out=IN) + + bgmodel = get_background_model(cut) + facet_to_inoutcut = compute_bgfacet_to_inoutcut(bgmodel,geo) + _distributed_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut) +end + +function compute_bgcell_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,geo::DistributedDiscreteGeometry) + map(local_views(cutgeo),local_views(geo)) do cutgeo,geo + compute_bgcell_to_inoutcut(cutgeo,geo) + end +end + +function compute_bgfacet_to_inoutcut( + cutter::Cutter, + bgmodel::DistributedDiscreteModel, + geo::DistributedDiscreteGeometry) + + gids = get_cell_gids(bgmodel) + bgf_to_ioc = map(local_views(bgmodel),local_views(gids),local_views(geo)) do model,gids,geo + ownmodel = remove_ghost_cells(model,gids) + compute_bgfacet_to_inoutcut(cutter,ownmodel,geo) + end + compute_bgfacet_to_inoutcut(bgmodel,bgf_to_ioc) +end \ No newline at end of file diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 850eb181..742a2336 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -16,8 +16,12 @@ local_views(a::DistributedEmbeddedDiscretization) = a.discretizations get_background_model(a::DistributedEmbeddedDiscretization) = a.model function get_geometry(a::DistributedEmbeddedDiscretization) - cut = local_views(a) |> PartitionedArrays.getany - get_geometry(cut) + loc_geometries = map(get_geometry,local_views(a)) + get_geometry(loc_geometries) +end + +function get_geometry(a::AbstractArray{<:CSG.Geometry}) + PartitionedArrays.getany(a) end function cut(bgmodel::DistributedDiscreteModel,args...) diff --git a/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..ffe8f674 --- /dev/null +++ b/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl @@ -0,0 +1,148 @@ +module DistributedDiscreteGeometryPoissonTest + +using Gridap +using GridapEmbedded +using GridapDistributed +using PartitionedArrays +using Test + +using GridapEmbedded.CSG +using GridapEmbedded.LevelSetCutters + +function main(distribute,parts; + threshold=1, + n=8, + cells=(n,n), + geometry=:circle) + + ranks = distribute(LinearIndices((prod(parts),))) + + u(x) = x[1] - x[2] + f(x) = -Δ(u)(x) + ud(x) = u(x) + + geometries = Dict( + :circle => circle_geometry, + :remotes => remotes_geometry, + ) + + bgmodel,_geo = geometries[geometry](ranks,parts,cells) + geo = discretize(_geo,bgmodel) + + D = 2 + cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) + meas = map(first,cell_meas) |> PartitionedArrays.getany + h = meas^(1/D) + + cutgeo = cut(bgmodel,geo) + cutgeo_facets = cut_facets(bgmodel,geo) + + strategy = AggregateCutCellsByThreshold(threshold) + bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) + + Ω_bg = Triangulation(bgmodel) + Ω_act = Triangulation(cutgeo,ACTIVE) + Ω = Triangulation(cutgeo,PHYSICAL) + Γ = EmbeddedBoundary(cutgeo) + + n_Γ = get_normal_vector(Γ) + + order = 1 + degree = 2*order + dΩ = Measure(Ω,degree) + dΓ = Measure(Γ,degree) + + reffe = ReferenceFE(lagrangian,Float64,order) + + Vstd = FESpace(Ω_act,reffe) + + V = AgFEMSpace(bgmodel,Vstd,aggregates) + U = TrialFESpace(V) + + + γd = 10.0 + + a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + + l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + + op = AffineFEOperator(a,l,U,V) + uh = solve(op) + + e = u - uh + + l2(u) = sqrt(sum( ∫( u*u )*dΩ )) + h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + + el2 = l2(e) + eh1 = h1(e) + ul2 = l2(uh) + uh1 = h1(uh) + + # + colors = map(color_aggregates,aggregates,local_views(bgmodel)) + gids = get_cell_gids(bgmodel) + + + global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid + map(i-> i==0 ? 0 : gid[i],agg) + end + own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid + map(Reindex(agg),oid) + end + own_colors = map(colors,own_to_local(gids)) do col,oid + map(Reindex(col),oid) + end + + writevtk(Ω_bg,"trian", + celldata=[ + "aggregate"=>own_aggregates, + "color"=>own_colors, + "gid"=>own_to_global(gids)])#, + # cellfields=["uh"=>uh]) + + writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) + writevtk(Γ,"trian_G") + @test el2/ul2 < 1.e-8 + @test eh1/uh1 < 1.e-7 + +end + +function circle_geometry(ranks,parts,cells) + L = 1 + p0 = Point(0.0,0.0) + pmin = p0-L/2 + pmax = p0+L/2 + R = 0.35 + geo = disk(R,x0=p0) + bgmodel = CartesianDiscreteModel(ranks,parts,pmin,pmax,cells) + bgmodel,geo +end + +function remotes_geometry(ranks,parts,cells) + x0 = Point(0.05,0.05) + d1 = VectorValue(0.9,0.0) + d2 = VectorValue(0.0,0.1) + geo1 = quadrilateral(;x0=x0,d1=d1,d2=d2) + + x0 = Point(0.15,0.1) + d1 = VectorValue(0.25,0.0) + d2 = VectorValue(0.0,0.6) + geo2 = quadrilateral(;x0=x0,d1=d1,d2=d2) + geo = union(geo1,geo2) + + domain = (0, 1, 0, 1) + bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells) + bgmodel,geo +end + +with_debug() do distribute + main(distribute,(2,2)) + main(distribute,(4,1),cells=(12,12),geometry=:remotes) +end + +end # module \ No newline at end of file diff --git a/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..9e29dee1 --- /dev/null +++ b/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl @@ -0,0 +1,8 @@ +module DistributedDiscreteGeometryPoissonTestsSeq +using PartitionedArrays +include("../DistributedDiscreteGeometryPoissonTest.jl") +with_debug() do distribute + PoissonTests.main(distribute,(2,2)) + PoissonTests.main(distribute,(4,1),cells=(12,12),geometry=:remotes) +end +end diff --git a/test/DistributedTests/sequential/runtests.jl b/test/DistributedTests/sequential/runtests.jl index e68831c3..5819b694 100644 --- a/test/DistributedTests/sequential/runtests.jl +++ b/test/DistributedTests/sequential/runtests.jl @@ -3,5 +3,6 @@ module SequentialTests using Test @time @testset "PoissonSeq" begin include("PoissonTests.jl") end +@time @testset "PoissonSeq" begin include("DistributedDiscreteGeometryPoissonTest.jl") end end From 1ac42f2b57551c94c9ae2132fa3a0bccfe07b8e2 Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:24:37 +1000 Subject: [PATCH 02/74] Fix test --- .../sequential/DistributedDiscreteGeometryPoissonTest.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl index 9e29dee1..080d4b9f 100644 --- a/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl +++ b/test/DistributedTests/sequential/DistributedDiscreteGeometryPoissonTest.jl @@ -2,7 +2,7 @@ module DistributedDiscreteGeometryPoissonTestsSeq using PartitionedArrays include("../DistributedDiscreteGeometryPoissonTest.jl") with_debug() do distribute - PoissonTests.main(distribute,(2,2)) - PoissonTests.main(distribute,(4,1),cells=(12,12),geometry=:remotes) + DistributedDiscreteGeometryPoissonTest.main(distribute,(2,2)) + DistributedDiscreteGeometryPoissonTest.main(distribute,(4,1),cells=(12,12),geometry=:remotes) end end From 643efc205a13c8a7a9b6a3e0352d19cb2f6cac3d Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Sat, 8 Jun 2024 10:41:18 +1000 Subject: [PATCH 03/74] Missing MPI test call --- test/DistributedTests/mpi/runtests_body.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/DistributedTests/mpi/runtests_body.jl b/test/DistributedTests/mpi/runtests_body.jl index fe600b7c..7c44d8bc 100644 --- a/test/DistributedTests/mpi/runtests_body.jl +++ b/test/DistributedTests/mpi/runtests_body.jl @@ -6,6 +6,7 @@ using MPI include("../PoissonTests.jl") include("../AggregatesTests.jl") +include("../DistributedDiscreteGeometryPoissonTest.jl") if ! MPI.Initialized() MPI.Init() @@ -21,6 +22,11 @@ function all_tests(distribute,parts) PoissonTests.main(distribute,(prod(parts),1),cells=(12,12),geometry=:remotes) PArrays.toc!(t,"Poisson") + PArrays.tic!(t) + DistributedDiscreteGeometryPoissonTest.main(distribute,parts) + DistributedDiscreteGeometryPoissonTest.main(distribute,(prod(parts),1),cells=(12,12),geometry=:remotes) + PArrays.toc!(t,"DistributedDiscreteGeometryPoisson") + if prod(parts) == 4 DistributedAggregatesTests.main(distribute,parts) end From 2c1d835b91ac94ffe14f4b5cb814800869310c88 Mon Sep 17 00:00:00 2001 From: "Z J Wegert (Workstation)" Date: Mon, 10 Jun 2024 13:21:12 +1000 Subject: [PATCH 04/74] Include name in DistributedDiscreteGeometry --- src/Distributed/DistributedDiscreteGeometries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index ce3c8be3..1f3d32b6 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -4,12 +4,12 @@ end local_views(a::DistributedDiscreteGeometry) = a.geometries -function DistributedDiscreteGeometry(φh::CellField,model::DistributedDiscreteModel) +function DistributedDiscreteGeometry(φh::CellField,model::DistributedDiscreteModel;name::String="") gids = get_cell_gids(model) geometries = map(local_views(model),local_views(gids),local_views(φh)) do model,gids,φh ownmodel = remove_ghost_cells(model,gids) point_to_coords = collect1d(get_node_coordinates(ownmodel)) - DiscreteGeometry(φh(point_to_coords),point_to_coords) + DiscreteGeometry(φh(point_to_coords),point_to_coords;name) end DistributedDiscreteGeometry(geometries) end From 1b5a49014db5568b088a1c0a2a32961c68b27a2a Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:59:43 +1000 Subject: [PATCH 05/74] Added _get_value_at_coords to avoid interpolation --- src/Distributed/Distributed.jl | 2 +- .../DistributedDiscreteGeometries.jl | 49 +++++++++++++++++-- src/LevelSetCutters/DiscreteGeometries.jl | 32 ++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index 4fc3e95e..a08527e7 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -43,7 +43,7 @@ import GridapEmbedded.Interfaces: EmbeddedBoundary import GridapEmbedded.Interfaces: compute_bgfacet_to_inoutcut import GridapEmbedded.Interfaces: compute_bgcell_to_inoutcut import GridapEmbedded.CSG: get_geometry -import GridapEmbedded.LevelSetCutters: discretize +import GridapEmbedded.LevelSetCutters: discretize, DiscreteGeometry import Gridap.Geometry: Triangulation import Gridap.Geometry: SkeletonTriangulation import Gridap.Geometry: BoundaryTriangulation diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 1f3d32b6..616c7120 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -4,12 +4,55 @@ end local_views(a::DistributedDiscreteGeometry) = a.geometries -function DistributedDiscreteGeometry(φh::CellField,model::DistributedDiscreteModel;name::String="") +function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) where {Dc,Dp} + @assert DomainStyle(φh) == ReferenceDomain() gids = get_cell_gids(model) - geometries = map(local_views(model),local_views(gids),local_views(φh)) do model,gids,φh + values = map(local_views(φh),local_views(model),local_views(gids)) do φh, model, gids + # Maps from the no-ghost model to the original model + own_model = remove_ghost_cells(model,gids) + own_to_local_node = Geometry.get_face_to_parent_face(own_model,0) + local_to_own_node = Arrays.find_inverse_index_map(own_to_local_node,num_nodes(model)) + own_to_local_cell = Geometry.get_face_to_parent_face(own_model,Dc) + + # Cell-to-node map for the original model + # topo = get_grid_topology(model) + # c2n_map = get_faces(topo,Dc,0) + c2n_map = collect1d(get_cell_node_ids(model)) + + # Cell-wise node coordinates (in ReferenceDomain coordinates) + cell_reffe = get_cell_reffe(model) + cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) + + φh_data = CellData.get_data(φh) + space = get_fe_space(φh) + T = get_dof_value_type(space) + values = Vector{T}(undef,num_nodes(own_model)) + touched = fill(false,num_nodes(model)) + + cell_node_coords_cache = array_cache(cell_node_coords) + for cell in own_to_local_cell # For each owned cell + field = φh_data[cell] + node_coords = getindex!(cell_node_coords_cache,cell_node_coords,cell) + for (iN,node) in enumerate(c2n_map[cell]) # Go over local nodes + own_node = local_to_own_node[node] + if (own_node != 0) && !touched[node] # Compute value if suitable + values[own_node] = field(node_coords[iN]) + touched[node] = true + end + end + end + return values + end + return values +end + +function DiscreteGeometry(φh::CellField,model::DistributedDiscreteModel;name::String="") + φ_values = _get_values_at_owned_coords(φh,model) + gids = get_cell_gids(model) + geometries = map(local_views(model),local_views(gids),local_views(φ_values)) do model,gids,loc_φ ownmodel = remove_ghost_cells(model,gids) point_to_coords = collect1d(get_node_coordinates(ownmodel)) - DiscreteGeometry(φh(point_to_coords),point_to_coords;name) + DiscreteGeometry(loc_φ,point_to_coords;name) end DistributedDiscreteGeometry(geometries) end diff --git a/src/LevelSetCutters/DiscreteGeometries.jl b/src/LevelSetCutters/DiscreteGeometries.jl index 5289299a..d2e15ffe 100644 --- a/src/LevelSetCutters/DiscreteGeometries.jl +++ b/src/LevelSetCutters/DiscreteGeometries.jl @@ -65,9 +65,41 @@ function _find_unique_leaves(tree) j_to_fun, oid_to_j end +function _get_value_at_coords(φh::CellField,model::DiscreteModel{Dc,Dp}) where {Dc,Dp} + @assert DomainStyle(φh) == ReferenceDomain() + # Cell-to-node map for the original model + c2n_map = collect1d(get_cell_node_ids(model)) + + # Cell-wise node coordinates (in ReferenceDomain coordinates) + cell_reffe = get_cell_reffe(model) + cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) + + # Get cell data + φh_data = CellData.get_data(φh) + space = get_fe_space(φh) + T = get_dof_value_type(space) + values = Vector{T}(undef,num_nodes(model)) + cell_node_coords_cache = array_cache(cell_node_coords) + # Loop over cells + for cell in eachindex(c2n_map) + field = φh_data[cell] + node_coords = getindex!(cell_node_coords_cache,cell_node_coords,cell) + for (iN,node) in enumerate(c2n_map[cell]) + values[node] = field(node_coords[iN]) + end + end +end + function DiscreteGeometry( point_to_value::AbstractVector,point_to_coords::AbstractVector;name::String="") data = (point_to_value,name,nothing) tree = Leaf(data) DiscreteGeometry(tree,point_to_coords) end + +function DiscreteGeometry( + φh::CellField,model::DiscreteModel;name::String="") + point_to_value = _get_value_at_coords(φh,model) + point_to_coords = collect1d(get_node_coordinates(model)) + DiscreteGeometry(point_to_value,point_to_coords;name) +end \ No newline at end of file From e80c763c717ee28cdd8b215c7a0e191da300f1db Mon Sep 17 00:00:00 2001 From: Z J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Wed, 19 Jun 2024 15:12:25 +1000 Subject: [PATCH 06/74] Remove unused test --- .../DistributedDiscreteGeometryPoissonTest.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl index ffe8f674..10a99591 100644 --- a/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl +++ b/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl @@ -140,9 +140,4 @@ function remotes_geometry(ranks,parts,cells) bgmodel,geo end -with_debug() do distribute - main(distribute,(2,2)) - main(distribute,(4,1),cells=(12,12),geometry=:remotes) -end - end # module \ No newline at end of file From 5195d51dcf189b3e401051114cbf80c6c26a93da Mon Sep 17 00:00:00 2001 From: Z J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:50:21 +1000 Subject: [PATCH 07/74] added periodic testing, suggests that weak method is likely required here. --- src/LevelSetCutters/DiscreteGeometries.jl | 3 +- src/LevelSetCutters/LevelSetCutters.jl | 1 + test/AgFEMTests/PeriodicAgFEMSpacesTests.jl | 75 +++++++++ test/AgFEMTests/runtests.jl | 2 + ...cDistributedDiscreteGeometryPoissonTest.jl | 143 ++++++++++++++++++ ...istributedLSDiscreteGeometryPoissonTest.jl | 110 ++++++++++++++ test/DistributedTests/PeriodicPoissonTests.jl | 141 +++++++++++++++++ test/DistributedTests/mpi/runtests_body.jl | 17 +++ ...cDistributedDiscreteGeometryPoissonTest.jl | 8 + ...istributedLSDiscreteGeometryPoissonTest.jl | 7 + .../sequential/PeriodicPoissonTests.jl | 8 + test/DistributedTests/sequential/runtests.jl | 4 +- .../PeriodicDiscreteGeoPoissonAgFEMTests.jl | 76 ++++++++++ .../PeriodicPoissonAgFEMTests.jl | 74 +++++++++ test/GridapEmbeddedTests/runtests.jl | 4 + 15 files changed, 671 insertions(+), 2 deletions(-) create mode 100644 test/AgFEMTests/PeriodicAgFEMSpacesTests.jl create mode 100644 test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/PeriodicPoissonTests.jl create mode 100644 test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/sequential/PeriodicPoissonTests.jl create mode 100644 test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl create mode 100644 test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl diff --git a/src/LevelSetCutters/DiscreteGeometries.jl b/src/LevelSetCutters/DiscreteGeometries.jl index d2e15ffe..3eb9705d 100644 --- a/src/LevelSetCutters/DiscreteGeometries.jl +++ b/src/LevelSetCutters/DiscreteGeometries.jl @@ -76,7 +76,7 @@ function _get_value_at_coords(φh::CellField,model::DiscreteModel{Dc,Dp}) where # Get cell data φh_data = CellData.get_data(φh) - space = get_fe_space(φh) + space = FESpaces.get_fe_space(φh) T = get_dof_value_type(space) values = Vector{T}(undef,num_nodes(model)) cell_node_coords_cache = array_cache(cell_node_coords) @@ -88,6 +88,7 @@ function _get_value_at_coords(φh::CellField,model::DiscreteModel{Dc,Dp}) where values[node] = field(node_coords[iN]) end end + return values end function DiscreteGeometry( diff --git a/src/LevelSetCutters/LevelSetCutters.jl b/src/LevelSetCutters/LevelSetCutters.jl index aa5b1472..75296ea1 100644 --- a/src/LevelSetCutters/LevelSetCutters.jl +++ b/src/LevelSetCutters/LevelSetCutters.jl @@ -28,6 +28,7 @@ using Gridap.Geometry using Gridap.CellData using Gridap.Polynomials using Gridap.Visualization +using Gridap.FESpaces export LevelSetCutter export AnalyticalGeometry diff --git a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl new file mode 100644 index 00000000..cc1845fd --- /dev/null +++ b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl @@ -0,0 +1,75 @@ +module PeriodicAgFEMSpacesTests + +using Test +using Gridap +using GridapEmbedded +using Gridap.Geometry: get_active_model + +const R = 0.5 +geom = disk(R,x0=Point(0.5,0.5)) +n = 21 +partition = (n,n) + +domain = (0,1,0,1) +bgmodel = CartesianDiscreteModel(domain,partition;isperiodic=(true,true)) + +cutdisc = cut(bgmodel,geom) + +strategy = AggregateCutCellsByThreshold(1) +aggregates = aggregate(strategy,cutdisc) + +Ω_bg = Triangulation(bgmodel) +Ω_ac = Triangulation(cutdisc,ACTIVE) +Ω = Triangulation(cutdisc,PHYSICAL) +Ω_in = Triangulation(cutdisc,IN) + +dΩ_bg = Measure(Ω_bg,2) +dΩ = Measure(Ω,2) +dΩ_in = Measure(Ω_in,2) + +model = get_active_model(Ω_ac) +order = 2 + +# In the physical domain +cell_fe = FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order) +Vstd = FESpace(Ω_ac,cell_fe) + +Vagg = AgFEMSpace(Vstd,aggregates) +U = TrialFESpace(Vagg) + +v(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 +vhagg = interpolate(v,Vagg) + +writevtk(Ω_ac,"test",cellfields=["v"=>vhagg]) + +tol = 10e-9 +@test sum( ∫(abs2(v-vhagg))dΩ ) < tol +@test sum( ∫(abs2(v-vhagg))dΩ_in ) < tol + +vh = FEFunction(V,rand(num_free_dofs(V))) +vhagg = interpolate(vh,Vagg) +@test sum( ∫(abs2(vh-vhagg))dΩ_in ) < tol + +# In the reference space + +reffe = ReferenceFE(lagrangian,Float64,order) +V = FESpace(Ω_ac,reffe) +Vagg = AgFEMSpace(V,aggregates) + +v(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 +vhagg = interpolate(v,Vagg) + +tol = 10e-9 +@test sum( ∫(abs2(v-vhagg))dΩ ) < tol +@test sum( ∫(abs2(v-vhagg))dΩ_in ) < tol + +vh = FEFunction(V,rand(num_free_dofs(V))) +vhagg = interpolate(vh,Vagg) +@test sum( ∫(abs2(vh-vhagg))dΩ_in ) < tol + +#cellfields = ["vh"=>vh,"vhagg"=>vhagg,"e"=>vh-vhagg] +#writevtk(Ω_bg,"trian_bg",nsubcells=10,cellfields=cellfields) +#writevtk(Ω_in,"trian_in",nsubcells=10,cellfields=cellfields) +#writevtk(Ω,"trian_phys",cellfields=cellfields) + +end # module diff --git a/test/AgFEMTests/runtests.jl b/test/AgFEMTests/runtests.jl index 9d039176..66d7f07b 100644 --- a/test/AgFEMTests/runtests.jl +++ b/test/AgFEMTests/runtests.jl @@ -6,4 +6,6 @@ using Test @testset "AgFEMSpaces" begin include("AgFEMSpacesTests.jl") end +@testset "PeriodicAgFEMSpaces" begin include("PeriodicAgFEMSpacesTests.jl") end + end # module diff --git a/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..8bd3e679 --- /dev/null +++ b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl @@ -0,0 +1,143 @@ +module PeriodicDistributedDiscreteGeometryPoissonTest + +using Gridap +using GridapEmbedded +using GridapDistributed +using PartitionedArrays +using Test + +using GridapEmbedded.CSG +using GridapEmbedded.LevelSetCutters + +function main(distribute,parts; + threshold=1, + n=8, + cells=(n,n), + geometry=:circle) + + ranks = distribute(LinearIndices((prod(parts),))) + + u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 + f(x) = -Δ(u)(x) + ud(x) = u(x) + + geometries = Dict( + :circle => circle_geometry, + :remotes => remotes_geometry, + ) + + bgmodel,_geo = geometries[geometry](ranks,parts,cells) + geo = discretize(_geo,bgmodel) + + D = 2 + cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) + meas = map(first,cell_meas) |> PartitionedArrays.getany + h = meas^(1/D) + + cutgeo = cut(bgmodel,geo) + cutgeo_facets = cut_facets(bgmodel,geo) + + strategy = AggregateCutCellsByThreshold(threshold) + bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) + + Ω_bg = Triangulation(bgmodel) + Ω_act = Triangulation(cutgeo,ACTIVE) + Ω = Triangulation(cutgeo,PHYSICAL) + Γ = EmbeddedBoundary(cutgeo) + + n_Γ = get_normal_vector(Γ) + + order = 2 + degree = 2*order + dΩ = Measure(Ω,degree) + dΓ = Measure(Γ,degree) + + reffe = ReferenceFE(lagrangian,Float64,order) + + Vstd = FESpace(Ω_act,reffe) + + V = AgFEMSpace(bgmodel,Vstd,aggregates) + U = TrialFESpace(V) + + + γd = 10.0 + + a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + + l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + + op = AffineFEOperator(a,l,U,V) + uh = solve(op) + + e = u - uh + + l2(u) = sqrt(sum( ∫( u*u )*dΩ )) + h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + + el2 = l2(e) + eh1 = h1(e) + ul2 = l2(uh) + uh1 = h1(uh) + + # + colors = map(color_aggregates,aggregates,local_views(bgmodel)) + gids = get_cell_gids(bgmodel) + + + global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid + map(i-> i==0 ? 0 : gid[i],agg) + end + own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid + map(Reindex(agg),oid) + end + own_colors = map(colors,own_to_local(gids)) do col,oid + map(Reindex(col),oid) + end + + writevtk(Ω_bg,"trian", + celldata=[ + "aggregate"=>own_aggregates, + "color"=>own_colors, + "gid"=>own_to_global(gids)])#, + # cellfields=["uh"=>uh]) + + writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) + writevtk(Γ,"trian_G") + @test el2/ul2 < 1.e-8 + @test eh1/uh1 < 1.e-7 + +end + +function circle_geometry(ranks,parts,cells) + L = 1 + p0 = Point(0.5,0.5) + pmin = p0-L/2 + pmax = p0+L/2 + R = 0.55 + geo = disk(R,x0=p0) + bgmodel = CartesianDiscreteModel(ranks,parts,pmin,pmax,cells;isperiodic=(true,true)) + bgmodel,geo +end + +function remotes_geometry(ranks,parts,cells) + x0 = Point(0.0,0.4) + d1 = VectorValue(1.0,0.0) + d2 = VectorValue(0.0,0.2) + geo1 = quadrilateral(;x0=x0,d1=d1,d2=d2) + + x0 = Point(0.4,0.0) + d1 = VectorValue(0.2,0.0) + d2 = VectorValue(0.0,1.0) + geo2 = quadrilateral(;x0=x0,d1=d1,d2=d2) + geo = union(geo1,geo2) + + domain = (0, 1, 0, 1) + bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) + bgmodel,geo +end + +end # module \ No newline at end of file diff --git a/test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..f0b659e0 --- /dev/null +++ b/test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl @@ -0,0 +1,110 @@ +module PeriodicDistributedLSDiscreteGeometryPoissonTest + +using Gridap +using GridapEmbedded +using GridapDistributed +using PartitionedArrays +using Test + +using GridapEmbedded.CSG +using GridapEmbedded.LevelSetCutters + +function main(distribute,parts; + threshold=1, + n=21, + cells=(n,n)) + + order = 2 + ranks = distribute(LinearIndices((prod(parts),))) + domain = (0,1,0,1) + bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) + + u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 + f(x) = -Δ(u)(x) + ud(x) = u(x) + + reffe = ReferenceFE(lagrangian,Float64,order) + Ω_bg = Triangulation(bgmodel) + V_bg = FESpace(Ω_bg,reffe) + φh = interpolate(x->sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.55,V_bg) + geo = DiscreteGeometry(φh,bgmodel) + + D = 2 + cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) + meas = map(first,cell_meas) |> PartitionedArrays.getany + h = meas^(1/D) + + cutgeo = cut(bgmodel,geo) + cutgeo_facets = cut_facets(bgmodel,geo) + + strategy = AggregateCutCellsByThreshold(threshold) + bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) + + Ω_act = Triangulation(cutgeo,ACTIVE) + Ω = Triangulation(cutgeo,PHYSICAL) + Γ = EmbeddedBoundary(cutgeo) + + n_Γ = get_normal_vector(Γ) + + order = 2 + degree = 2*order + dΩ = Measure(Ω,degree) + dΓ = Measure(Γ,degree) + + Vstd = FESpace(Ω_act,reffe) + V = AgFEMSpace(bgmodel,Vstd,aggregates) + U = TrialFESpace(V) + + γd = 10.0 + + a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + + l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + + op = AffineFEOperator(a,l,U,V) + uh = solve(op) + + e = u - uh + + l2(u) = sqrt(sum( ∫( u*u )*dΩ )) + h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + + el2 = l2(e) + eh1 = h1(e) + ul2 = l2(uh) + uh1 = h1(uh) + + # + colors = map(color_aggregates,aggregates,local_views(bgmodel)) + gids = get_cell_gids(bgmodel) + + + global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid + map(i-> i==0 ? 0 : gid[i],agg) + end + own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid + map(Reindex(agg),oid) + end + own_colors = map(colors,own_to_local(gids)) do col,oid + map(Reindex(col),oid) + end + + writevtk(Ω_bg,"trian", + celldata=[ + "aggregate"=>own_aggregates, + "color"=>own_colors, + "gid"=>own_to_global(gids)])#, + # cellfields=["uh"=>uh]) + + writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) + writevtk(Γ,"trian_G") + @test el2/ul2 < 1.e-8 + @test eh1/uh1 < 1.e-7 + +end + +end # module \ No newline at end of file diff --git a/test/DistributedTests/PeriodicPoissonTests.jl b/test/DistributedTests/PeriodicPoissonTests.jl new file mode 100644 index 00000000..130ad414 --- /dev/null +++ b/test/DistributedTests/PeriodicPoissonTests.jl @@ -0,0 +1,141 @@ +module PeriodicPoissonTests + +using Gridap +using GridapEmbedded +using GridapDistributed +using PartitionedArrays +using Test + +using GridapEmbedded.CSG + +function main(distribute,parts; + threshold=1, + n=8, + cells=(n,n), + geometry=:circle) + + ranks = distribute(LinearIndices((prod(parts),))) + + u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 + f(x) = -Δ(u)(x) + ud(x) = u(x) + + geometries = Dict( + :circle => circle_geometry, + :remotes => remotes_geometry, + ) + + bgmodel,geo = geometries[geometry](ranks,parts,cells) + + D = 2 + cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) + meas = map(first,cell_meas) |> PartitionedArrays.getany + h = meas^(1/D) + + cutgeo = cut(bgmodel,geo) + cutgeo_facets = cut_facets(bgmodel,geo) + + strategy = AggregateCutCellsByThreshold(threshold) + bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) + + Ω_bg = Triangulation(bgmodel) + Ω_act = Triangulation(cutgeo,ACTIVE) + Ω = Triangulation(cutgeo,PHYSICAL) + Γ = EmbeddedBoundary(cutgeo) + + n_Γ = get_normal_vector(Γ) + + order = 2 + degree = 2*order + dΩ = Measure(Ω,degree) + dΓ = Measure(Γ,degree) + + reffe = ReferenceFE(lagrangian,Float64,order) + + Vstd = FESpace(Ω_act,reffe) + + V = AgFEMSpace(bgmodel,Vstd,aggregates) + U = TrialFESpace(V) + + + γd = 10.0 + + a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + + l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + + op = AffineFEOperator(a,l,U,V) + uh = solve(op) + + e = u - uh + + l2(u) = sqrt(sum( ∫( u*u )*dΩ )) + h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + + el2 = l2(e) + eh1 = h1(e) + ul2 = l2(uh) + uh1 = h1(uh) + + # + colors = map(color_aggregates,aggregates,local_views(bgmodel)) + gids = get_cell_gids(bgmodel) + + + global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid + map(i-> i==0 ? 0 : gid[i],agg) + end + own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid + map(Reindex(agg),oid) + end + own_colors = map(colors,own_to_local(gids)) do col,oid + map(Reindex(col),oid) + end + + writevtk(Ω_bg,"trian", + celldata=[ + "aggregate"=>own_aggregates, + "color"=>own_colors, + "gid"=>own_to_global(gids)])#, + # cellfields=["uh"=>uh]) + + writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) + writevtk(Γ,"trian_G") + @test el2/ul2 < 1.e-8 + @test eh1/uh1 < 1.e-7 + +end + +function circle_geometry(ranks,parts,cells) + L = 1 + p0 = Point(0.5,0.5) + pmin = p0-L/2 + pmax = p0+L/2 + R = 0.55 + geo = disk(R,x0=p0) + bgmodel = CartesianDiscreteModel(ranks,parts,pmin,pmax,cells;isperiodic=(true,true)) + bgmodel,geo +end + +function remotes_geometry(ranks,parts,cells) + x0 = Point(0.0,0.4) + d1 = VectorValue(1.0,0.0) + d2 = VectorValue(0.0,0.2) + geo1 = quadrilateral(;x0=x0,d1=d1,d2=d2) + + x0 = Point(0.4,0.0) + d1 = VectorValue(0.2,0.0) + d2 = VectorValue(0.0,1.0) + geo2 = quadrilateral(;x0=x0,d1=d1,d2=d2) + geo = union(geo1,geo2) + + domain = (0, 1, 0, 1) + bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) + bgmodel,geo +end + +end # module diff --git a/test/DistributedTests/mpi/runtests_body.jl b/test/DistributedTests/mpi/runtests_body.jl index 7c44d8bc..cdbb6dcb 100644 --- a/test/DistributedTests/mpi/runtests_body.jl +++ b/test/DistributedTests/mpi/runtests_body.jl @@ -7,6 +7,9 @@ using MPI include("../PoissonTests.jl") include("../AggregatesTests.jl") include("../DistributedDiscreteGeometryPoissonTest.jl") +include("../PeriodicPoissonTests.jl") +include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") +include("../PeriodicDistributedLSDiscreteGeometryPoissonTest.jl") if ! MPI.Initialized() MPI.Init() @@ -27,6 +30,20 @@ function all_tests(distribute,parts) DistributedDiscreteGeometryPoissonTest.main(distribute,(prod(parts),1),cells=(12,12),geometry=:remotes) PArrays.toc!(t,"DistributedDiscreteGeometryPoisson") + PArrays.tic!(t) + PeriodicPoissonTests.main(distribute,parts,cells=(21,21)) + PeriodicPoissonTests.main(distribute,(prod(parts),1),cells=(21,21),geometry=:remotes) + PArrays.toc!(t,"PeriodicPoissonTests") + + PArrays.tic!(t) + PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,parts,cells=(21,21)) + PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(prod(parts),1),cells=(21,21),geometry=:remotes) + PArrays.toc!(t,"PeriodicDistributedDiscreteGeometryPoissonTest") + + PArrays.tic!(t) + PeriodicDistributedLSDiscreteGeometryPoissonTest.main(distribute,parts,cells=(21,21)) + PArrays.toc!(t,"PeriodicDistributedLSDiscreteGeometryPoissonTest") + if prod(parts) == 4 DistributedAggregatesTests.main(distribute,parts) end diff --git a/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..87bf08ea --- /dev/null +++ b/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl @@ -0,0 +1,8 @@ +module PeriodicDistributedDiscreteGeometryPoissonTestsSeq +using PartitionedArrays +include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") +with_debug() do distribute + PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(2,2),cells=(21,21)) + PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(4,1),cells=(21,21),geometry=:remotes) +end +end diff --git a/test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..52a24dac --- /dev/null +++ b/test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl @@ -0,0 +1,7 @@ +module PeriodicDistributedLSDiscreteGeometryPoissonTestsSeq +using PartitionedArrays +include("../PeriodicDistributedLSDiscreteGeometryPoissonTest.jl") +with_debug() do distribute + PeriodicDistributedLSDiscreteGeometryPoissonTest.main(distribute,(2,2),cells=(21,21)) +end +end diff --git a/test/DistributedTests/sequential/PeriodicPoissonTests.jl b/test/DistributedTests/sequential/PeriodicPoissonTests.jl new file mode 100644 index 00000000..e0d8ebb0 --- /dev/null +++ b/test/DistributedTests/sequential/PeriodicPoissonTests.jl @@ -0,0 +1,8 @@ +module PeriodicPoissonTestsSeq +using PartitionedArrays +include("../PeriodicPoissonTests.jl") +with_debug() do distribute + PeriodicPoissonTests.main(distribute,(2,2),cells=(21,21)) + PeriodicPoissonTests.main(distribute,(4,1),cells=(21,21),geometry=:remotes) +end +end diff --git a/test/DistributedTests/sequential/runtests.jl b/test/DistributedTests/sequential/runtests.jl index 5819b694..a9ac9931 100644 --- a/test/DistributedTests/sequential/runtests.jl +++ b/test/DistributedTests/sequential/runtests.jl @@ -3,6 +3,8 @@ module SequentialTests using Test @time @testset "PoissonSeq" begin include("PoissonTests.jl") end -@time @testset "PoissonSeq" begin include("DistributedDiscreteGeometryPoissonTest.jl") end +@time @testset "DiscreteGeoPoissonSeq" begin include("DistributedDiscreteGeometryPoissonTest.jl") end +@time @testset "PeriodicPoissonSeq" begin include("PeriodicPoissonTests.jl") end +@time @testset "PeriodicDiscreteGeoPoissonSeq" begin include("PeriodicDistributedDiscreteGeometryPoissonTest.jl") end end diff --git a/test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl b/test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl new file mode 100644 index 00000000..4e791365 --- /dev/null +++ b/test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl @@ -0,0 +1,76 @@ +# module PoissonAgFEMTests + +using Gridap +using GridapEmbedded +using Test + +u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 +f(x) = -Δ(u)(x) +ud(x) = u(x) + +order = 2 +n = 31 +partition = (n,n) +domain = (0,1,0,1) +bgmodel = CartesianDiscreteModel(domain,partition;isperiodic=(true,true)) +dp = 1 +const h = dp/n + +reffe = ReferenceFE(lagrangian,Float64,order) +Ω_bg = Triangulation(bgmodel) +V_bg = FESpace(Ω_bg,reffe) +φh = interpolate(x->sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.55,V_bg) +geo = DiscreteGeometry(φh,bgmodel) +cutgeo = cut(bgmodel,geo) + +strategy = AggregateAllCutCells() +aggregates = aggregate(strategy,cutgeo) + +Ω_bg = Triangulation(bgmodel) +Ω_act = Triangulation(cutgeo,ACTIVE) +Ω = Triangulation(cutgeo,PHYSICAL) +Γ = EmbeddedBoundary(cutgeo) + +n_Γ = get_normal_vector(Γ) + +degree = 2*order +dΩ = Measure(Ω,degree) +dΓ = Measure(Γ,degree) + +model = get_active_model(Ω_act) +Vstd = FESpace(Ω_act,FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order)) + +V = AgFEMSpace(Vstd,aggregates) +U = TrialFESpace(V) + +const γd = 10.0 + +a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + +l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + +op = AffineFEOperator(a,l,U,V) +uh = solve(op) + +e = u - uh + +l2(u) = sqrt(sum( ∫( u*u )*dΩ )) +h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + +el2 = l2(e) +eh1 = h1(e) +ul2 = l2(uh) +uh1 = h1(uh) + +colors = color_aggregates(aggregates,bgmodel) +writevtk(Ω_bg,"trian",celldata=["aggregate"=>aggregates,"color"=>colors],cellfields=["uh"=>uh]) +writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) +writevtk(Γ,"trian_G") +@test el2/ul2 < 1.e-8 +@test eh1/uh1 < 1.e-7 + +# end # module diff --git a/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl b/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl new file mode 100644 index 00000000..c45c38d9 --- /dev/null +++ b/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl @@ -0,0 +1,74 @@ +module PoissonAgFEMTests + +using Gridap +using GridapEmbedded +using Test + +u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 +f(x) = -Δ(u)(x) +ud(x) = u(x) + +const R = 0.55 +geom = disk(R,x0=Point(0.5,0.5)) + +n = 31 +partition = (n,n) +domain = (0,1,0,1) +bgmodel = CartesianDiscreteModel(domain,partition;isperiodic=(true,true)) +dp = 1 +const h = dp/n + +cutgeo = cut(bgmodel,geom) + +strategy = AggregateAllCutCells() +aggregates = aggregate(strategy,cutgeo) + +Ω_bg = Triangulation(bgmodel) +Ω_act = Triangulation(cutgeo,ACTIVE) +Ω = Triangulation(cutgeo,PHYSICAL) +Γ = EmbeddedBoundary(cutgeo) + +n_Γ = get_normal_vector(Γ) + +order = 2 +degree = 2*order +dΩ = Measure(Ω,degree) +dΓ = Measure(Γ,degree) + +model = get_active_model(Ω_act) +Vstd = FESpace(Ω_act,FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order)) + +V = AgFEMSpace(Vstd,aggregates) +U = TrialFESpace(V) + +const γd = 10.0 + +a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + +l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + +op = AffineFEOperator(a,l,U,V) +uh = solve(op) + +e = u - uh + +l2(u) = sqrt(sum( ∫( u*u )*dΩ )) +h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + +el2 = l2(e) +eh1 = h1(e) +ul2 = l2(uh) +uh1 = h1(uh) + +#colors = color_aggregates(aggregates,bgmodel) +#writevtk(Ω_bg,"trian",celldata=["aggregate"=>aggregates,"color"=>colors],cellfields=["uh"=>uh]) +#writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) +#writevtk(Γ,"trian_G") +@test el2/ul2 < 1.e-8 +@test eh1/uh1 < 1.e-7 + +end # module diff --git a/test/GridapEmbeddedTests/runtests.jl b/test/GridapEmbeddedTests/runtests.jl index 1576bc42..a7e3d787 100644 --- a/test/GridapEmbeddedTests/runtests.jl +++ b/test/GridapEmbeddedTests/runtests.jl @@ -6,6 +6,10 @@ using Test @time @testset "PoissonAgFEM" begin include("PoissonAgFEMTests.jl") end +@time @testset "PeriodicPoissonAgFEM" begin include("PeriodicPoissonAgFEMTests.jl") end + +@time @testset "PeriodicDiscreteGeoPoissonAgFEM" begin include("PeriodicDiscreteGeoPoissonAgFEMTests.jl") end + @time @testset "PoissonModalC0AgFEM" begin include("PoissonModalC0AgFEMTests.jl") end @time @testset "BimaterialPoissonCutFEM" begin include("BimaterialPoissonCutFEMTests.jl") end From e0fb29835305190ab4fd49b0b65d25c549eaf3d0 Mon Sep 17 00:00:00 2001 From: Z J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:51:10 +1000 Subject: [PATCH 08/74] add dep --- src/Distributed/Distributed.jl | 1 + src/Distributed/DistributedDiscreteGeometries.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index a08527e7..3c845702 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -10,6 +10,7 @@ using Gridap.CellData using Gridap.Geometry using Gridap.Helpers using Gridap.ReferenceFEs +using Gridap.FESpaces using GridapEmbedded.CSG using GridapEmbedded.LevelSetCutters diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 616c7120..2ea37887 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -24,7 +24,7 @@ function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) φh_data = CellData.get_data(φh) - space = get_fe_space(φh) + space = FESpaces.get_fe_space(φh) T = get_dof_value_type(space) values = Vector{T}(undef,num_nodes(own_model)) touched = fill(false,num_nodes(model)) From 67faf8399d598b91e2bfbfb26d3f8a46c64e52dc Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Wed, 19 Jun 2024 19:21:15 +1000 Subject: [PATCH 09/74] fix test --- test/AgFEMTests/PeriodicAgFEMSpacesTests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl index cc1845fd..ec84d4e1 100644 --- a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl +++ b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl @@ -5,7 +5,7 @@ using Gridap using GridapEmbedded using Gridap.Geometry: get_active_model -const R = 0.5 +const R = 0.55 geom = disk(R,x0=Point(0.5,0.5)) n = 21 partition = (n,n) @@ -46,7 +46,7 @@ tol = 10e-9 @test sum( ∫(abs2(v-vhagg))dΩ ) < tol @test sum( ∫(abs2(v-vhagg))dΩ_in ) < tol -vh = FEFunction(V,rand(num_free_dofs(V))) +vh = FEFunction(Vstd,rand(num_free_dofs(Vstd))) vhagg = interpolate(vh,Vagg) @test sum( ∫(abs2(vh-vhagg))dΩ_in ) < tol From 82d459791f0ac827678af6d185da54dd7cfc476c Mon Sep 17 00:00:00 2001 From: "Z J Wegert (Workstation)" Date: Thu, 20 Jun 2024 10:03:02 +1000 Subject: [PATCH 10/74] Revert changes --- test/AgFEMTests/PeriodicAgFEMSpacesTests.jl | 14 +- ...cDistributedDiscreteGeometryPoissonTest.jl | 143 ------------------ ...istributedLSDiscreteGeometryPoissonTest.jl | 110 -------------- test/DistributedTests/PeriodicPoissonTests.jl | 141 ----------------- test/DistributedTests/mpi/runtests_body.jl | 17 --- ...cDistributedDiscreteGeometryPoissonTest.jl | 8 - ...istributedLSDiscreteGeometryPoissonTest.jl | 7 - .../sequential/PeriodicPoissonTests.jl | 8 - test/DistributedTests/sequential/runtests.jl | 2 - .../PeriodicDiscreteGeoPoissonAgFEMTests.jl | 76 ---------- .../PeriodicPoissonAgFEMTests.jl | 74 --------- 11 files changed, 3 insertions(+), 597 deletions(-) delete mode 100644 test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl delete mode 100644 test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl delete mode 100644 test/DistributedTests/PeriodicPoissonTests.jl delete mode 100644 test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl delete mode 100644 test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl delete mode 100644 test/DistributedTests/sequential/PeriodicPoissonTests.jl delete mode 100644 test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl delete mode 100644 test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl diff --git a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl index ec84d4e1..26b34bae 100644 --- a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl +++ b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl @@ -28,7 +28,7 @@ dΩ = Measure(Ω,2) dΩ_in = Measure(Ω_in,2) model = get_active_model(Ω_ac) -order = 2 +order = 1 # In the physical domain cell_fe = FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order) @@ -42,14 +42,10 @@ vhagg = interpolate(v,Vagg) writevtk(Ω_ac,"test",cellfields=["v"=>vhagg]) -tol = 10e-9 +tol = 10e-7 @test sum( ∫(abs2(v-vhagg))dΩ ) < tol @test sum( ∫(abs2(v-vhagg))dΩ_in ) < tol -vh = FEFunction(Vstd,rand(num_free_dofs(Vstd))) -vhagg = interpolate(vh,Vagg) -@test sum( ∫(abs2(vh-vhagg))dΩ_in ) < tol - # In the reference space reffe = ReferenceFE(lagrangian,Float64,order) @@ -59,14 +55,10 @@ Vagg = AgFEMSpace(V,aggregates) v(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 vhagg = interpolate(v,Vagg) -tol = 10e-9 +tol = 10e-7 @test sum( ∫(abs2(v-vhagg))dΩ ) < tol @test sum( ∫(abs2(v-vhagg))dΩ_in ) < tol -vh = FEFunction(V,rand(num_free_dofs(V))) -vhagg = interpolate(vh,Vagg) -@test sum( ∫(abs2(vh-vhagg))dΩ_in ) < tol - #cellfields = ["vh"=>vh,"vhagg"=>vhagg,"e"=>vh-vhagg] #writevtk(Ω_bg,"trian_bg",nsubcells=10,cellfields=cellfields) #writevtk(Ω_in,"trian_in",nsubcells=10,cellfields=cellfields) diff --git a/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl deleted file mode 100644 index 8bd3e679..00000000 --- a/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl +++ /dev/null @@ -1,143 +0,0 @@ -module PeriodicDistributedDiscreteGeometryPoissonTest - -using Gridap -using GridapEmbedded -using GridapDistributed -using PartitionedArrays -using Test - -using GridapEmbedded.CSG -using GridapEmbedded.LevelSetCutters - -function main(distribute,parts; - threshold=1, - n=8, - cells=(n,n), - geometry=:circle) - - ranks = distribute(LinearIndices((prod(parts),))) - - u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 - f(x) = -Δ(u)(x) - ud(x) = u(x) - - geometries = Dict( - :circle => circle_geometry, - :remotes => remotes_geometry, - ) - - bgmodel,_geo = geometries[geometry](ranks,parts,cells) - geo = discretize(_geo,bgmodel) - - D = 2 - cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) - meas = map(first,cell_meas) |> PartitionedArrays.getany - h = meas^(1/D) - - cutgeo = cut(bgmodel,geo) - cutgeo_facets = cut_facets(bgmodel,geo) - - strategy = AggregateCutCellsByThreshold(threshold) - bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) - - Ω_bg = Triangulation(bgmodel) - Ω_act = Triangulation(cutgeo,ACTIVE) - Ω = Triangulation(cutgeo,PHYSICAL) - Γ = EmbeddedBoundary(cutgeo) - - n_Γ = get_normal_vector(Γ) - - order = 2 - degree = 2*order - dΩ = Measure(Ω,degree) - dΓ = Measure(Γ,degree) - - reffe = ReferenceFE(lagrangian,Float64,order) - - Vstd = FESpace(Ω_act,reffe) - - V = AgFEMSpace(bgmodel,Vstd,aggregates) - U = TrialFESpace(V) - - - γd = 10.0 - - a(u,v) = - ∫( ∇(v)⋅∇(u) ) * dΩ + - ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ - - l(v) = - ∫( v*f ) * dΩ + - ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ - - op = AffineFEOperator(a,l,U,V) - uh = solve(op) - - e = u - uh - - l2(u) = sqrt(sum( ∫( u*u )*dΩ )) - h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) - - el2 = l2(e) - eh1 = h1(e) - ul2 = l2(uh) - uh1 = h1(uh) - - # - colors = map(color_aggregates,aggregates,local_views(bgmodel)) - gids = get_cell_gids(bgmodel) - - - global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid - map(i-> i==0 ? 0 : gid[i],agg) - end - own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid - map(Reindex(agg),oid) - end - own_colors = map(colors,own_to_local(gids)) do col,oid - map(Reindex(col),oid) - end - - writevtk(Ω_bg,"trian", - celldata=[ - "aggregate"=>own_aggregates, - "color"=>own_colors, - "gid"=>own_to_global(gids)])#, - # cellfields=["uh"=>uh]) - - writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) - writevtk(Γ,"trian_G") - @test el2/ul2 < 1.e-8 - @test eh1/uh1 < 1.e-7 - -end - -function circle_geometry(ranks,parts,cells) - L = 1 - p0 = Point(0.5,0.5) - pmin = p0-L/2 - pmax = p0+L/2 - R = 0.55 - geo = disk(R,x0=p0) - bgmodel = CartesianDiscreteModel(ranks,parts,pmin,pmax,cells;isperiodic=(true,true)) - bgmodel,geo -end - -function remotes_geometry(ranks,parts,cells) - x0 = Point(0.0,0.4) - d1 = VectorValue(1.0,0.0) - d2 = VectorValue(0.0,0.2) - geo1 = quadrilateral(;x0=x0,d1=d1,d2=d2) - - x0 = Point(0.4,0.0) - d1 = VectorValue(0.2,0.0) - d2 = VectorValue(0.0,1.0) - geo2 = quadrilateral(;x0=x0,d1=d1,d2=d2) - geo = union(geo1,geo2) - - domain = (0, 1, 0, 1) - bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) - bgmodel,geo -end - -end # module \ No newline at end of file diff --git a/test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl deleted file mode 100644 index f0b659e0..00000000 --- a/test/DistributedTests/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl +++ /dev/null @@ -1,110 +0,0 @@ -module PeriodicDistributedLSDiscreteGeometryPoissonTest - -using Gridap -using GridapEmbedded -using GridapDistributed -using PartitionedArrays -using Test - -using GridapEmbedded.CSG -using GridapEmbedded.LevelSetCutters - -function main(distribute,parts; - threshold=1, - n=21, - cells=(n,n)) - - order = 2 - ranks = distribute(LinearIndices((prod(parts),))) - domain = (0,1,0,1) - bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) - - u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 - f(x) = -Δ(u)(x) - ud(x) = u(x) - - reffe = ReferenceFE(lagrangian,Float64,order) - Ω_bg = Triangulation(bgmodel) - V_bg = FESpace(Ω_bg,reffe) - φh = interpolate(x->sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.55,V_bg) - geo = DiscreteGeometry(φh,bgmodel) - - D = 2 - cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) - meas = map(first,cell_meas) |> PartitionedArrays.getany - h = meas^(1/D) - - cutgeo = cut(bgmodel,geo) - cutgeo_facets = cut_facets(bgmodel,geo) - - strategy = AggregateCutCellsByThreshold(threshold) - bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) - - Ω_act = Triangulation(cutgeo,ACTIVE) - Ω = Triangulation(cutgeo,PHYSICAL) - Γ = EmbeddedBoundary(cutgeo) - - n_Γ = get_normal_vector(Γ) - - order = 2 - degree = 2*order - dΩ = Measure(Ω,degree) - dΓ = Measure(Γ,degree) - - Vstd = FESpace(Ω_act,reffe) - V = AgFEMSpace(bgmodel,Vstd,aggregates) - U = TrialFESpace(V) - - γd = 10.0 - - a(u,v) = - ∫( ∇(v)⋅∇(u) ) * dΩ + - ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ - - l(v) = - ∫( v*f ) * dΩ + - ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ - - op = AffineFEOperator(a,l,U,V) - uh = solve(op) - - e = u - uh - - l2(u) = sqrt(sum( ∫( u*u )*dΩ )) - h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) - - el2 = l2(e) - eh1 = h1(e) - ul2 = l2(uh) - uh1 = h1(uh) - - # - colors = map(color_aggregates,aggregates,local_views(bgmodel)) - gids = get_cell_gids(bgmodel) - - - global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid - map(i-> i==0 ? 0 : gid[i],agg) - end - own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid - map(Reindex(agg),oid) - end - own_colors = map(colors,own_to_local(gids)) do col,oid - map(Reindex(col),oid) - end - - writevtk(Ω_bg,"trian", - celldata=[ - "aggregate"=>own_aggregates, - "color"=>own_colors, - "gid"=>own_to_global(gids)])#, - # cellfields=["uh"=>uh]) - - writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) - writevtk(Γ,"trian_G") - @test el2/ul2 < 1.e-8 - @test eh1/uh1 < 1.e-7 - -end - -end # module \ No newline at end of file diff --git a/test/DistributedTests/PeriodicPoissonTests.jl b/test/DistributedTests/PeriodicPoissonTests.jl deleted file mode 100644 index 130ad414..00000000 --- a/test/DistributedTests/PeriodicPoissonTests.jl +++ /dev/null @@ -1,141 +0,0 @@ -module PeriodicPoissonTests - -using Gridap -using GridapEmbedded -using GridapDistributed -using PartitionedArrays -using Test - -using GridapEmbedded.CSG - -function main(distribute,parts; - threshold=1, - n=8, - cells=(n,n), - geometry=:circle) - - ranks = distribute(LinearIndices((prod(parts),))) - - u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 - f(x) = -Δ(u)(x) - ud(x) = u(x) - - geometries = Dict( - :circle => circle_geometry, - :remotes => remotes_geometry, - ) - - bgmodel,geo = geometries[geometry](ranks,parts,cells) - - D = 2 - cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) - meas = map(first,cell_meas) |> PartitionedArrays.getany - h = meas^(1/D) - - cutgeo = cut(bgmodel,geo) - cutgeo_facets = cut_facets(bgmodel,geo) - - strategy = AggregateCutCellsByThreshold(threshold) - bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) - - Ω_bg = Triangulation(bgmodel) - Ω_act = Triangulation(cutgeo,ACTIVE) - Ω = Triangulation(cutgeo,PHYSICAL) - Γ = EmbeddedBoundary(cutgeo) - - n_Γ = get_normal_vector(Γ) - - order = 2 - degree = 2*order - dΩ = Measure(Ω,degree) - dΓ = Measure(Γ,degree) - - reffe = ReferenceFE(lagrangian,Float64,order) - - Vstd = FESpace(Ω_act,reffe) - - V = AgFEMSpace(bgmodel,Vstd,aggregates) - U = TrialFESpace(V) - - - γd = 10.0 - - a(u,v) = - ∫( ∇(v)⋅∇(u) ) * dΩ + - ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ - - l(v) = - ∫( v*f ) * dΩ + - ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ - - op = AffineFEOperator(a,l,U,V) - uh = solve(op) - - e = u - uh - - l2(u) = sqrt(sum( ∫( u*u )*dΩ )) - h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) - - el2 = l2(e) - eh1 = h1(e) - ul2 = l2(uh) - uh1 = h1(uh) - - # - colors = map(color_aggregates,aggregates,local_views(bgmodel)) - gids = get_cell_gids(bgmodel) - - - global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid - map(i-> i==0 ? 0 : gid[i],agg) - end - own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid - map(Reindex(agg),oid) - end - own_colors = map(colors,own_to_local(gids)) do col,oid - map(Reindex(col),oid) - end - - writevtk(Ω_bg,"trian", - celldata=[ - "aggregate"=>own_aggregates, - "color"=>own_colors, - "gid"=>own_to_global(gids)])#, - # cellfields=["uh"=>uh]) - - writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) - writevtk(Γ,"trian_G") - @test el2/ul2 < 1.e-8 - @test eh1/uh1 < 1.e-7 - -end - -function circle_geometry(ranks,parts,cells) - L = 1 - p0 = Point(0.5,0.5) - pmin = p0-L/2 - pmax = p0+L/2 - R = 0.55 - geo = disk(R,x0=p0) - bgmodel = CartesianDiscreteModel(ranks,parts,pmin,pmax,cells;isperiodic=(true,true)) - bgmodel,geo -end - -function remotes_geometry(ranks,parts,cells) - x0 = Point(0.0,0.4) - d1 = VectorValue(1.0,0.0) - d2 = VectorValue(0.0,0.2) - geo1 = quadrilateral(;x0=x0,d1=d1,d2=d2) - - x0 = Point(0.4,0.0) - d1 = VectorValue(0.2,0.0) - d2 = VectorValue(0.0,1.0) - geo2 = quadrilateral(;x0=x0,d1=d1,d2=d2) - geo = union(geo1,geo2) - - domain = (0, 1, 0, 1) - bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) - bgmodel,geo -end - -end # module diff --git a/test/DistributedTests/mpi/runtests_body.jl b/test/DistributedTests/mpi/runtests_body.jl index cdbb6dcb..7c44d8bc 100644 --- a/test/DistributedTests/mpi/runtests_body.jl +++ b/test/DistributedTests/mpi/runtests_body.jl @@ -7,9 +7,6 @@ using MPI include("../PoissonTests.jl") include("../AggregatesTests.jl") include("../DistributedDiscreteGeometryPoissonTest.jl") -include("../PeriodicPoissonTests.jl") -include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") -include("../PeriodicDistributedLSDiscreteGeometryPoissonTest.jl") if ! MPI.Initialized() MPI.Init() @@ -30,20 +27,6 @@ function all_tests(distribute,parts) DistributedDiscreteGeometryPoissonTest.main(distribute,(prod(parts),1),cells=(12,12),geometry=:remotes) PArrays.toc!(t,"DistributedDiscreteGeometryPoisson") - PArrays.tic!(t) - PeriodicPoissonTests.main(distribute,parts,cells=(21,21)) - PeriodicPoissonTests.main(distribute,(prod(parts),1),cells=(21,21),geometry=:remotes) - PArrays.toc!(t,"PeriodicPoissonTests") - - PArrays.tic!(t) - PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,parts,cells=(21,21)) - PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(prod(parts),1),cells=(21,21),geometry=:remotes) - PArrays.toc!(t,"PeriodicDistributedDiscreteGeometryPoissonTest") - - PArrays.tic!(t) - PeriodicDistributedLSDiscreteGeometryPoissonTest.main(distribute,parts,cells=(21,21)) - PArrays.toc!(t,"PeriodicDistributedLSDiscreteGeometryPoissonTest") - if prod(parts) == 4 DistributedAggregatesTests.main(distribute,parts) end diff --git a/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl deleted file mode 100644 index 87bf08ea..00000000 --- a/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl +++ /dev/null @@ -1,8 +0,0 @@ -module PeriodicDistributedDiscreteGeometryPoissonTestsSeq -using PartitionedArrays -include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") -with_debug() do distribute - PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(2,2),cells=(21,21)) - PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(4,1),cells=(21,21),geometry=:remotes) -end -end diff --git a/test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl deleted file mode 100644 index 52a24dac..00000000 --- a/test/DistributedTests/sequential/PeriodicDistributedLSDiscreteGeometryPoissonTest.jl +++ /dev/null @@ -1,7 +0,0 @@ -module PeriodicDistributedLSDiscreteGeometryPoissonTestsSeq -using PartitionedArrays -include("../PeriodicDistributedLSDiscreteGeometryPoissonTest.jl") -with_debug() do distribute - PeriodicDistributedLSDiscreteGeometryPoissonTest.main(distribute,(2,2),cells=(21,21)) -end -end diff --git a/test/DistributedTests/sequential/PeriodicPoissonTests.jl b/test/DistributedTests/sequential/PeriodicPoissonTests.jl deleted file mode 100644 index e0d8ebb0..00000000 --- a/test/DistributedTests/sequential/PeriodicPoissonTests.jl +++ /dev/null @@ -1,8 +0,0 @@ -module PeriodicPoissonTestsSeq -using PartitionedArrays -include("../PeriodicPoissonTests.jl") -with_debug() do distribute - PeriodicPoissonTests.main(distribute,(2,2),cells=(21,21)) - PeriodicPoissonTests.main(distribute,(4,1),cells=(21,21),geometry=:remotes) -end -end diff --git a/test/DistributedTests/sequential/runtests.jl b/test/DistributedTests/sequential/runtests.jl index a9ac9931..bf7521b2 100644 --- a/test/DistributedTests/sequential/runtests.jl +++ b/test/DistributedTests/sequential/runtests.jl @@ -4,7 +4,5 @@ using Test @time @testset "PoissonSeq" begin include("PoissonTests.jl") end @time @testset "DiscreteGeoPoissonSeq" begin include("DistributedDiscreteGeometryPoissonTest.jl") end -@time @testset "PeriodicPoissonSeq" begin include("PeriodicPoissonTests.jl") end -@time @testset "PeriodicDiscreteGeoPoissonSeq" begin include("PeriodicDistributedDiscreteGeometryPoissonTest.jl") end end diff --git a/test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl b/test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl deleted file mode 100644 index 4e791365..00000000 --- a/test/GridapEmbeddedTests/PeriodicDiscreteGeoPoissonAgFEMTests.jl +++ /dev/null @@ -1,76 +0,0 @@ -# module PoissonAgFEMTests - -using Gridap -using GridapEmbedded -using Test - -u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 -f(x) = -Δ(u)(x) -ud(x) = u(x) - -order = 2 -n = 31 -partition = (n,n) -domain = (0,1,0,1) -bgmodel = CartesianDiscreteModel(domain,partition;isperiodic=(true,true)) -dp = 1 -const h = dp/n - -reffe = ReferenceFE(lagrangian,Float64,order) -Ω_bg = Triangulation(bgmodel) -V_bg = FESpace(Ω_bg,reffe) -φh = interpolate(x->sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.55,V_bg) -geo = DiscreteGeometry(φh,bgmodel) -cutgeo = cut(bgmodel,geo) - -strategy = AggregateAllCutCells() -aggregates = aggregate(strategy,cutgeo) - -Ω_bg = Triangulation(bgmodel) -Ω_act = Triangulation(cutgeo,ACTIVE) -Ω = Triangulation(cutgeo,PHYSICAL) -Γ = EmbeddedBoundary(cutgeo) - -n_Γ = get_normal_vector(Γ) - -degree = 2*order -dΩ = Measure(Ω,degree) -dΓ = Measure(Γ,degree) - -model = get_active_model(Ω_act) -Vstd = FESpace(Ω_act,FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order)) - -V = AgFEMSpace(Vstd,aggregates) -U = TrialFESpace(V) - -const γd = 10.0 - -a(u,v) = - ∫( ∇(v)⋅∇(u) ) * dΩ + - ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ - -l(v) = - ∫( v*f ) * dΩ + - ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ - -op = AffineFEOperator(a,l,U,V) -uh = solve(op) - -e = u - uh - -l2(u) = sqrt(sum( ∫( u*u )*dΩ )) -h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) - -el2 = l2(e) -eh1 = h1(e) -ul2 = l2(uh) -uh1 = h1(uh) - -colors = color_aggregates(aggregates,bgmodel) -writevtk(Ω_bg,"trian",celldata=["aggregate"=>aggregates,"color"=>colors],cellfields=["uh"=>uh]) -writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) -writevtk(Γ,"trian_G") -@test el2/ul2 < 1.e-8 -@test eh1/uh1 < 1.e-7 - -# end # module diff --git a/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl b/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl deleted file mode 100644 index c45c38d9..00000000 --- a/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl +++ /dev/null @@ -1,74 +0,0 @@ -module PoissonAgFEMTests - -using Gridap -using GridapEmbedded -using Test - -u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 -f(x) = -Δ(u)(x) -ud(x) = u(x) - -const R = 0.55 -geom = disk(R,x0=Point(0.5,0.5)) - -n = 31 -partition = (n,n) -domain = (0,1,0,1) -bgmodel = CartesianDiscreteModel(domain,partition;isperiodic=(true,true)) -dp = 1 -const h = dp/n - -cutgeo = cut(bgmodel,geom) - -strategy = AggregateAllCutCells() -aggregates = aggregate(strategy,cutgeo) - -Ω_bg = Triangulation(bgmodel) -Ω_act = Triangulation(cutgeo,ACTIVE) -Ω = Triangulation(cutgeo,PHYSICAL) -Γ = EmbeddedBoundary(cutgeo) - -n_Γ = get_normal_vector(Γ) - -order = 2 -degree = 2*order -dΩ = Measure(Ω,degree) -dΓ = Measure(Γ,degree) - -model = get_active_model(Ω_act) -Vstd = FESpace(Ω_act,FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order)) - -V = AgFEMSpace(Vstd,aggregates) -U = TrialFESpace(V) - -const γd = 10.0 - -a(u,v) = - ∫( ∇(v)⋅∇(u) ) * dΩ + - ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ - -l(v) = - ∫( v*f ) * dΩ + - ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ - -op = AffineFEOperator(a,l,U,V) -uh = solve(op) - -e = u - uh - -l2(u) = sqrt(sum( ∫( u*u )*dΩ )) -h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) - -el2 = l2(e) -eh1 = h1(e) -ul2 = l2(uh) -uh1 = h1(uh) - -#colors = color_aggregates(aggregates,bgmodel) -#writevtk(Ω_bg,"trian",celldata=["aggregate"=>aggregates,"color"=>colors],cellfields=["uh"=>uh]) -#writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) -#writevtk(Γ,"trian_G") -@test el2/ul2 < 1.e-8 -@test eh1/uh1 < 1.e-7 - -end # module From de2d2bbe87ce6399fc5fc306284449bf9a6a6026 Mon Sep 17 00:00:00 2001 From: "Z J Wegert (Workstation)" Date: Thu, 20 Jun 2024 12:03:54 +1000 Subject: [PATCH 11/74] tests passing --- src/Distributed/Distributed.jl | 1 + .../DistributedDiscreteGeometries.jl | 6 +- ...istributedLSDiscreteGeometryPoissonTest.jl | 110 ++++++++++++++++++ test/DistributedTests/mpi/runtests_body.jl | 5 + ...istributedLSDiscreteGeometryPoissonTest.jl | 7 ++ test/DistributedTests/sequential/runtests.jl | 1 + .../DiscreteGeometriesTests.jl | 12 ++ 7 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/sequential/DistributedLSDiscreteGeometryPoissonTest.jl diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index 3c845702..dec113c3 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -26,6 +26,7 @@ using GridapEmbedded.AgFEM: AggregateCutCellsByThreshold using GridapEmbedded.MomentFittedQuadratures: MomentFitted using Gridap.Geometry: AppendedTriangulation using Gridap.Geometry: get_face_to_parent_face +using Gridap.Arrays: find_inverse_index_map using GridapDistributed: DistributedDiscreteModel using GridapDistributed: DistributedTriangulation using GridapDistributed: DistributedFESpace diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 2ea37887..c8a949ee 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -10,9 +10,9 @@ function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) values = map(local_views(φh),local_views(model),local_views(gids)) do φh, model, gids # Maps from the no-ghost model to the original model own_model = remove_ghost_cells(model,gids) - own_to_local_node = Geometry.get_face_to_parent_face(own_model,0) - local_to_own_node = Arrays.find_inverse_index_map(own_to_local_node,num_nodes(model)) - own_to_local_cell = Geometry.get_face_to_parent_face(own_model,Dc) + own_to_local_node = get_face_to_parent_face(own_model,0) + local_to_own_node = find_inverse_index_map(own_to_local_node,num_nodes(model)) + own_to_local_cell = get_face_to_parent_face(own_model,Dc) # Cell-to-node map for the original model # topo = get_grid_topology(model) diff --git a/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..68bbf39f --- /dev/null +++ b/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl @@ -0,0 +1,110 @@ +module DistributedLSDiscreteGeometryPoissonTest + +using Gridap +using GridapEmbedded +using GridapDistributed +using PartitionedArrays +using Test + +using GridapEmbedded.CSG +using GridapEmbedded.LevelSetCutters + +function main(distribute,parts; + threshold=1, + n=21, + cells=(n,n)) + + order = 2 + ranks = distribute(LinearIndices((prod(parts),))) + domain = (0,1,0,1) + bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells) + + u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 + f(x) = -Δ(u)(x) + ud(x) = u(x) + + reffe = ReferenceFE(lagrangian,Float64,order) + Ω_bg = Triangulation(bgmodel) + V_bg = FESpace(Ω_bg,reffe) + φh = interpolate(x->sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.35,V_bg) + geo = DiscreteGeometry(φh,bgmodel) + + D = 2 + cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) + meas = map(first,cell_meas) |> PartitionedArrays.getany + h = meas^(1/D) + + cutgeo = cut(bgmodel,geo) + cutgeo_facets = cut_facets(bgmodel,geo) + + strategy = AggregateCutCellsByThreshold(threshold) + bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) + + Ω_act = Triangulation(cutgeo,ACTIVE) + Ω = Triangulation(cutgeo,PHYSICAL) + Γ = EmbeddedBoundary(cutgeo) + + n_Γ = get_normal_vector(Γ) + + order = 2 + degree = 2*order + dΩ = Measure(Ω,degree) + dΓ = Measure(Γ,degree) + + Vstd = FESpace(Ω_act,reffe) + V = AgFEMSpace(bgmodel,Vstd,aggregates) + U = TrialFESpace(V) + + γd = 10.0 + + a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + + l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + + op = AffineFEOperator(a,l,U,V) + uh = solve(op) + + e = u - uh + + l2(u) = sqrt(sum( ∫( u*u )*dΩ )) + h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + + el2 = l2(e) + eh1 = h1(e) + ul2 = l2(uh) + uh1 = h1(uh) + + # + colors = map(color_aggregates,aggregates,local_views(bgmodel)) + gids = get_cell_gids(bgmodel) + + + global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid + map(i-> i==0 ? 0 : gid[i],agg) + end + own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid + map(Reindex(agg),oid) + end + own_colors = map(colors,own_to_local(gids)) do col,oid + map(Reindex(col),oid) + end + + writevtk(Ω_bg,"trian", + celldata=[ + "aggregate"=>own_aggregates, + "color"=>own_colors, + "gid"=>own_to_global(gids)])#, + # cellfields=["uh"=>uh]) + + writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) + writevtk(Γ,"trian_G") + @test el2/ul2 < 1.e-8 + @test eh1/uh1 < 1.e-7 + +end + +end # module \ No newline at end of file diff --git a/test/DistributedTests/mpi/runtests_body.jl b/test/DistributedTests/mpi/runtests_body.jl index 7c44d8bc..048144f9 100644 --- a/test/DistributedTests/mpi/runtests_body.jl +++ b/test/DistributedTests/mpi/runtests_body.jl @@ -7,6 +7,7 @@ using MPI include("../PoissonTests.jl") include("../AggregatesTests.jl") include("../DistributedDiscreteGeometryPoissonTest.jl") +include("../DistributedLSDiscreteGeometryPoissonTest.jl") if ! MPI.Initialized() MPI.Init() @@ -27,6 +28,10 @@ function all_tests(distribute,parts) DistributedDiscreteGeometryPoissonTest.main(distribute,(prod(parts),1),cells=(12,12),geometry=:remotes) PArrays.toc!(t,"DistributedDiscreteGeometryPoisson") + PArrays.tic!(t) + DistributedLSDiscreteGeometryPoissonTest.main(distribute,parts,cells=(21,21)) + PArrays.toc!(t,"DistributedLSDiscreteGeometryPoissonTest") + if prod(parts) == 4 DistributedAggregatesTests.main(distribute,parts) end diff --git a/test/DistributedTests/sequential/DistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/DistributedLSDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..afdba273 --- /dev/null +++ b/test/DistributedTests/sequential/DistributedLSDiscreteGeometryPoissonTest.jl @@ -0,0 +1,7 @@ +module DistributedLSDiscreteGeometryPoissonTestsSeq +using PartitionedArrays +include("../DistributedLSDiscreteGeometryPoissonTest.jl") +with_debug() do distribute + DistributedLSDiscreteGeometryPoissonTest.main(distribute,(2,2),cells=(21,21)) +end +end diff --git a/test/DistributedTests/sequential/runtests.jl b/test/DistributedTests/sequential/runtests.jl index bf7521b2..0e8f21fe 100644 --- a/test/DistributedTests/sequential/runtests.jl +++ b/test/DistributedTests/sequential/runtests.jl @@ -4,5 +4,6 @@ using Test @time @testset "PoissonSeq" begin include("PoissonTests.jl") end @time @testset "DiscreteGeoPoissonSeq" begin include("DistributedDiscreteGeometryPoissonTest.jl") end +@time @testset "LSDiscreteGeoPoissonSeq" begin include("DistributedLSDiscreteGeometryPoissonTest.jl") end end diff --git a/test/LevelSetCuttersTests/DiscreteGeometriesTests.jl b/test/LevelSetCuttersTests/DiscreteGeometriesTests.jl index 5a7479e3..f246c2e0 100644 --- a/test/LevelSetCuttersTests/DiscreteGeometriesTests.jl +++ b/test/LevelSetCuttersTests/DiscreteGeometriesTests.jl @@ -38,4 +38,16 @@ test_geometry(geo4_y) #print_tree(stdout,get_tree(geo4_x)) #print_tree(stdout,replace_data(d->objectid(first(d)),get_tree(geo4_x))) +#using a cellfield +domain = (0,1,0,1) +n = 10 +bgmodel = CartesianDiscreteModel(domain,(n,n)) + +reffe = ReferenceFE(lagrangian,Float64,1) +Ω_bg = Triangulation(bgmodel) +V_bg = FESpace(Ω_bg,reffe) +φh = interpolate(x->sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.55,V_bg) +geo = DiscreteGeometry(φh,bgmodel) +test_geometry(geo) + end # module From c9da43dedc9981cfdbe5fed169db517f9d8ec37b Mon Sep 17 00:00:00 2001 From: "Z J Wegert (Workstation)" Date: Thu, 20 Jun 2024 14:24:36 +1000 Subject: [PATCH 12/74] Added periodic tests --- ...cDistributedDiscreteGeometryPoissonTest.jl | 193 ++++++++++++++++++ test/DistributedTests/mpi/runtests_body.jl | 7 + ...cDistributedDiscreteGeometryPoissonTest.jl | 8 + test/DistributedTests/sequential/runtests.jl | 3 + .../PeriodicPoissonAgFEMTests.jl | 111 ++++++++++ test/GridapEmbeddedTests/runtests.jl | 2 - 6 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl create mode 100644 test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl create mode 100644 test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl diff --git a/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..26cde8c3 --- /dev/null +++ b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl @@ -0,0 +1,193 @@ +module PeriodicDistributedDiscreteGeometryPoissonTest + +using Gridap +using GridapEmbedded +using GridapDistributed +using PartitionedArrays +using Test + +using GridapDistributed: DistributedDiscreteModel + +using Gridap.Geometry +using Gridap.Geometry: get_vertex_coordinates,get_faces + +using GridapEmbedded.CSG +using GridapEmbedded.LevelSetCutters + +function update_labels!(e::Integer,model::DistributedDiscreteModel,f_Γ::Function,name::String) + mask = mark_nodes(f_Γ,model) + cell_to_entity = map(local_views(model),local_views(mask)) do model,mask + _update_labels_locally!(e,model,mask,name) + end + cell_gids=get_cell_gids(model) + cache=GridapDistributed.fetch_vector_ghost_values_cache(cell_to_entity,partition(cell_gids)) + GridapDistributed.fetch_vector_ghost_values!(cell_to_entity,cache) + nothing +end + +function _update_labels_locally!(e,model::CartesianDiscreteModel{2},mask,name) + topo = get_grid_topology(model) + labels = get_face_labeling(model) + cell_to_entity = labels.d_to_dface_to_entity[end] + entity = maximum(cell_to_entity) + e + # Vertices + vtxs_Γ = findall(mask) + vtx_edge_connectivity = Array(get_faces(topo,0,1)[vtxs_Γ]) + # Edges + edge_entries = [findall(x->any(x .∈ vtx_edge_connectivity[1:end.!=j]), + vtx_edge_connectivity[j]) for j = 1:length(vtx_edge_connectivity)] + edge_Γ = unique(reduce(vcat,getindex.(vtx_edge_connectivity,edge_entries),init=[])) + labels.d_to_dface_to_entity[1][vtxs_Γ] .= entity + labels.d_to_dface_to_entity[2][edge_Γ] .= entity + add_tag!(labels,name,[entity]) + return cell_to_entity +end + +function mark_nodes(f,model::DistributedDiscreteModel) + local_masks = map(local_views(model)) do model + mark_nodes(f,model) + end + gids = get_face_gids(model,0) + mask = PVector(local_masks,partition(gids)) + assemble!(|,mask) |> fetch # Ghosts -> Owned with `or` applied + consistent!(mask) |> fetch # Owned -> Ghost + return mask +end + +function mark_nodes(f,model::DiscreteModel) + topo = get_grid_topology(model) + coords = get_vertex_coordinates(topo) + mask = map(f,coords) + return mask +end + +function main(distribute,parts; + threshold=1, + n=8, + cells=(n,n), + geometry=:circle) + + ranks = distribute(LinearIndices((prod(parts),))) + + u(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 + f(x) = -Δ(u)(x) + ud(x) = u(x) + + geometries = Dict( + :circle => circle_geometry, + :remotes => remotes_geometry, + ) + + bgmodel,_geo = geometries[geometry](ranks,parts,cells) + update_labels!(1,bgmodel,x->iszero(x[1]) || iszero(x[2]),"outer_boundary") + + geo = discretize(_geo,bgmodel) + + D = 2 + cell_meas = map(get_cell_measure∘Triangulation,local_views(bgmodel)) + meas = map(first,cell_meas) |> PartitionedArrays.getany + h = meas^(1/D) + + cutgeo = cut(bgmodel,geo) + cutgeo_facets = cut_facets(bgmodel,geo) + + strategy = AggregateCutCellsByThreshold(threshold) + bgmodel,cutgeo,aggregates = aggregate(strategy,cutgeo) + + Ω_bg = Triangulation(bgmodel) + Ω_act = Triangulation(cutgeo,ACTIVE) + Ω = Triangulation(cutgeo,PHYSICAL) + Γ = EmbeddedBoundary(cutgeo) + + n_Γ = get_normal_vector(Γ) + + order = 2 + degree = 2*order + dΩ = Measure(Ω,degree) + dΓ = Measure(Γ,degree) + + reffe = ReferenceFE(lagrangian,Float64,order) + + Vstd = FESpace(Ω_act,reffe;dirichlet_tags="outer_boundary") + + V = AgFEMSpace(bgmodel,Vstd,aggregates) + U = TrialFESpace(V,ud) + + γd = 10.0 + + a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + + l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + + op = AffineFEOperator(a,l,U,V) + uh = solve(op) + + e = u - uh + + l2(u) = sqrt(sum( ∫( u*u )*dΩ )) + h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + + el2 = l2(e) + eh1 = h1(e) + ul2 = l2(uh) + uh1 = h1(uh) + + # + colors = map(color_aggregates,aggregates,local_views(bgmodel)) + gids = get_cell_gids(bgmodel) + + + global_aggregates = map(aggregates,local_to_global(gids)) do agg,gid + map(i-> i==0 ? 0 : gid[i],agg) + end + own_aggregates = map(global_aggregates,own_to_local(gids)) do agg,oid + map(Reindex(agg),oid) + end + own_colors = map(colors,own_to_local(gids)) do col,oid + map(Reindex(col),oid) + end + + writevtk(Ω_bg,"trian", + celldata=[ + "aggregate"=>own_aggregates, + "color"=>own_colors, + "gid"=>own_to_global(gids)])#, + # cellfields=["uh"=>uh]) + + writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) + writevtk(Γ,"trian_G") + @test el2/ul2 < 1.e-8 + @test eh1/uh1 < 1.e-7 + +end + +function circle_geometry(ranks,parts,cells) + p0 = Point(0.5,0.5) + R = 0.55 + geo = disk(R,x0=p0) + bgmodel = CartesianDiscreteModel(ranks,parts,(0,1,0,1),cells;isperiodic=(true,true)) + bgmodel,geo +end + +function remotes_geometry(ranks,parts,cells) + x0 = Point(0.0,0.4) + d1 = VectorValue(1.0,0.0) + d2 = VectorValue(0.0,0.2) + geo1 = quadrilateral(;x0=x0,d1=d1,d2=d2) + + x0 = Point(0.4,0.0) + d1 = VectorValue(0.2,0.0) + d2 = VectorValue(0.0,1.0) + geo2 = quadrilateral(;x0=x0,d1=d1,d2=d2) + geo = union(geo1,geo2) + + domain = (0, 1, 0, 1) + bgmodel = CartesianDiscreteModel(ranks,parts,domain,cells;isperiodic=(true,true)) + bgmodel,geo +end + +end # module \ No newline at end of file diff --git a/test/DistributedTests/mpi/runtests_body.jl b/test/DistributedTests/mpi/runtests_body.jl index 048144f9..d0510c01 100644 --- a/test/DistributedTests/mpi/runtests_body.jl +++ b/test/DistributedTests/mpi/runtests_body.jl @@ -8,6 +8,7 @@ include("../PoissonTests.jl") include("../AggregatesTests.jl") include("../DistributedDiscreteGeometryPoissonTest.jl") include("../DistributedLSDiscreteGeometryPoissonTest.jl") +include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") if ! MPI.Initialized() MPI.Init() @@ -32,6 +33,12 @@ function all_tests(distribute,parts) DistributedLSDiscreteGeometryPoissonTest.main(distribute,parts,cells=(21,21)) PArrays.toc!(t,"DistributedLSDiscreteGeometryPoissonTest") + ## Disabled due to Issue #87 + # PArrays.tic!(t) + # PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(4,4),cells=(31,31),geometry=:circle) + # PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(4,1),cells=(31,31),geometry=:remotes) + # PArrays.toc!(t,"PeriodicDistributedDiscreteGeometryPoisson") + if prod(parts) == 4 DistributedAggregatesTests.main(distribute,parts) end diff --git a/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl new file mode 100644 index 00000000..7802ba31 --- /dev/null +++ b/test/DistributedTests/sequential/PeriodicDistributedDiscreteGeometryPoissonTest.jl @@ -0,0 +1,8 @@ +module PeriodicDistributedDiscreteGeometryPoissonTest +using PartitionedArrays +include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") +with_debug() do distribute + PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(4,4),cells=(31,31),geometry=:circle) + PeriodicDistributedDiscreteGeometryPoissonTest.main(distribute,(4,1),cells=(31,31),geometry=:remotes) +end +end diff --git a/test/DistributedTests/sequential/runtests.jl b/test/DistributedTests/sequential/runtests.jl index 0e8f21fe..57910a85 100644 --- a/test/DistributedTests/sequential/runtests.jl +++ b/test/DistributedTests/sequential/runtests.jl @@ -6,4 +6,7 @@ using Test @time @testset "DiscreteGeoPoissonSeq" begin include("DistributedDiscreteGeometryPoissonTest.jl") end @time @testset "LSDiscreteGeoPoissonSeq" begin include("DistributedLSDiscreteGeometryPoissonTest.jl") end +## Disabled due to Issue #87 +# @time @testset "PeriodicDiscreteGeoPoissonSeq" begin include("PeriodicDistributedDiscreteGeometryPoissonTest.jl") end + end diff --git a/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl b/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl new file mode 100644 index 00000000..0ce321ef --- /dev/null +++ b/test/GridapEmbeddedTests/PeriodicPoissonAgFEMTests.jl @@ -0,0 +1,111 @@ +module PeriodicPoissonAgFEMTests + +using Gridap +using GridapEmbedded +using Test + +function update_labels!(e::Integer,model::CartesianDiscreteModel,f_Γ::Function,name::String) + mask = mark_nodes(f_Γ,model) + _update_labels_locally!(e,model,mask,name) + nothing +end + +function _update_labels_locally!(e,model::CartesianDiscreteModel{2},mask,name) + topo = Gridap.Geometry.get_grid_topology(model) + labels = Gridap.Geometry.get_face_labeling(model) + cell_to_entity = labels.d_to_dface_to_entity[end] + entity = maximum(cell_to_entity) + e + # Vertices + vtxs_Γ = findall(mask) + vtx_edge_connectivity = Array(Gridap.Geometry.get_faces(topo,0,1)[vtxs_Γ]) + # Edges + edge_entries = [findall(x->any(x .∈ vtx_edge_connectivity[1:end.!=j]), + vtx_edge_connectivity[j]) for j = 1:length(vtx_edge_connectivity)] + edge_Γ = unique(reduce(vcat,getindex.(vtx_edge_connectivity,edge_entries),init=[])) + labels.d_to_dface_to_entity[1][vtxs_Γ] .= entity + labels.d_to_dface_to_entity[2][edge_Γ] .= entity + add_tag!(labels,name,[entity]) + return cell_to_entity +end + +function mark_nodes(f,model::DiscreteModel) + topo = Gridap.Geometry.get_grid_topology(model) + coords = Gridap.Geometry.get_vertex_coordinates(topo) + mask = map(f,coords) + return mask +end + +u(x) = (x[1]-0.5)^2 + 2(x[2]-0.5)^2 +f(x) = -Δ(u)(x) +ud(x) = u(x) + +# R = 0.3 +# geo1 = square(;L=2) +# geo2 = disk(R,x0=Point(0.5,0.5)) + +geom = disk(0.55,x0=Point(0.5,0.5)) +# geom = setdiff(geo1,geo2) + +n = 31 +partition = (n,n) +domain = (0,1,0,1) +bgmodel = CartesianDiscreteModel(domain,partition;isperiodic=(true,true)) +update_labels!(1,bgmodel,x->iszero(x[1]) || iszero(x[2]),"outer_boundary") + +dp = 1 +const h = dp/n + +cutgeo = cut(bgmodel,geom) + +strategy = AggregateAllCutCells() +aggregates = aggregate(strategy,cutgeo) + +Ω_bg = Triangulation(bgmodel) +Ω_act = Triangulation(cutgeo,ACTIVE) +Ω = Triangulation(cutgeo,PHYSICAL) +Γ = EmbeddedBoundary(cutgeo) + +n_Γ = get_normal_vector(Γ) + +order = 2 +degree = 2*order +dΩ = Measure(Ω,degree) +dΓ = Measure(Γ,degree) + +model = get_active_model(Ω_act) +Vstd = FESpace(Ω_act,FiniteElements(PhysicalDomain(),model,lagrangian,Float64,order);dirichlet_tags="outer_boundary") + +V = AgFEMSpace(Vstd,aggregates) +U = TrialFESpace(V,ud) + +const γd = 10.0 + +a(u,v) = + ∫( ∇(v)⋅∇(u) ) * dΩ + + ∫( (γd/h)*v*u - v*(n_Γ⋅∇(u)) - (n_Γ⋅∇(v))*u ) * dΓ + +l(v) = + ∫( v*f ) * dΩ + + ∫( (γd/h)*v*ud - (n_Γ⋅∇(v))*ud ) * dΓ + +op = AffineFEOperator(a,l,U,V) +uh = solve(op) + +e = u - uh + +l2(u) = sqrt(sum( ∫( u*u )*dΩ )) +h1(u) = sqrt(sum( ∫( u*u + ∇(u)⋅∇(u) )*dΩ )) + +el2 = l2(e) +eh1 = h1(e) +ul2 = l2(uh) +uh1 = h1(uh) + +#colors = color_aggregates(aggregates,bgmodel) +#writevtk(Ω_bg,"trian",celldata=["aggregate"=>aggregates,"color"=>colors],cellfields=["uh"=>uh]) +# writevtk(Ω,"trian_O",cellfields=["uh"=>uh,"u"=>u]) +# writevtk(Γ,"trian_G") +@test el2/ul2 < 1.e-8 +@test eh1/uh1 < 1.e-7 + +end # module diff --git a/test/GridapEmbeddedTests/runtests.jl b/test/GridapEmbeddedTests/runtests.jl index a7e3d787..f6d52df3 100644 --- a/test/GridapEmbeddedTests/runtests.jl +++ b/test/GridapEmbeddedTests/runtests.jl @@ -8,8 +8,6 @@ using Test @time @testset "PeriodicPoissonAgFEM" begin include("PeriodicPoissonAgFEMTests.jl") end -@time @testset "PeriodicDiscreteGeoPoissonAgFEM" begin include("PeriodicDiscreteGeoPoissonAgFEMTests.jl") end - @time @testset "PoissonModalC0AgFEM" begin include("PoissonModalC0AgFEMTests.jl") end @time @testset "BimaterialPoissonCutFEM" begin include("BimaterialPoissonCutFEMTests.jl") end From ef1fc9ab14d48328703872901ceb5dc060547de8 Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Fri, 21 Jun 2024 10:51:28 +1000 Subject: [PATCH 13/74] Allow propagation of dual numbers in _get_value_... --- src/Distributed/DistributedDiscreteGeometries.jl | 3 +-- src/LevelSetCutters/DiscreteGeometries.jl | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index c8a949ee..53463289 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -24,8 +24,7 @@ function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) φh_data = CellData.get_data(φh) - space = FESpaces.get_fe_space(φh) - T = get_dof_value_type(space) + T = typeof(first(φh_data)(first(first(cell_node_coords)))) values = Vector{T}(undef,num_nodes(own_model)) touched = fill(false,num_nodes(model)) diff --git a/src/LevelSetCutters/DiscreteGeometries.jl b/src/LevelSetCutters/DiscreteGeometries.jl index 3eb9705d..15824e88 100644 --- a/src/LevelSetCutters/DiscreteGeometries.jl +++ b/src/LevelSetCutters/DiscreteGeometries.jl @@ -76,8 +76,7 @@ function _get_value_at_coords(φh::CellField,model::DiscreteModel{Dc,Dp}) where # Get cell data φh_data = CellData.get_data(φh) - space = FESpaces.get_fe_space(φh) - T = get_dof_value_type(space) + T = typeof(first(φh_data)(first(first(cell_node_coords)))) # Allow propogation of dual numbers values = Vector{T}(undef,num_nodes(model)) cell_node_coords_cache = array_cache(cell_node_coords) # Loop over cells From 0fcedea8b1993caf00f381d9379502e56f4dbf9e Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Fri, 21 Jun 2024 11:44:10 +1000 Subject: [PATCH 14/74] Adjust to use Gridap.Arrays API --- src/Distributed/Distributed.jl | 2 +- src/Distributed/DistributedDiscreteGeometries.jl | 2 +- src/LevelSetCutters/DiscreteGeometries.jl | 2 +- src/LevelSetCutters/LevelSetCutters.jl | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index dec113c3..71d34cdd 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -26,7 +26,7 @@ using GridapEmbedded.AgFEM: AggregateCutCellsByThreshold using GridapEmbedded.MomentFittedQuadratures: MomentFitted using Gridap.Geometry: AppendedTriangulation using Gridap.Geometry: get_face_to_parent_face -using Gridap.Arrays: find_inverse_index_map +using Gridap.Arrays: find_inverse_index_map, testitem, return_type using GridapDistributed: DistributedDiscreteModel using GridapDistributed: DistributedTriangulation using GridapDistributed: DistributedFESpace diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 53463289..935e3b90 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -24,7 +24,7 @@ function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) φh_data = CellData.get_data(φh) - T = typeof(first(φh_data)(first(first(cell_node_coords)))) + T = return_type(testitem(CellData.get_data(φh)),testitem(testitem(cell_node_coords))) values = Vector{T}(undef,num_nodes(own_model)) touched = fill(false,num_nodes(model)) diff --git a/src/LevelSetCutters/DiscreteGeometries.jl b/src/LevelSetCutters/DiscreteGeometries.jl index 15824e88..23d8cbe4 100644 --- a/src/LevelSetCutters/DiscreteGeometries.jl +++ b/src/LevelSetCutters/DiscreteGeometries.jl @@ -76,7 +76,7 @@ function _get_value_at_coords(φh::CellField,model::DiscreteModel{Dc,Dp}) where # Get cell data φh_data = CellData.get_data(φh) - T = typeof(first(φh_data)(first(first(cell_node_coords)))) # Allow propogation of dual numbers + T = return_type(testitem(CellData.get_data(φh)),testitem(testitem(cell_node_coords))) values = Vector{T}(undef,num_nodes(model)) cell_node_coords_cache = array_cache(cell_node_coords) # Loop over cells diff --git a/src/LevelSetCutters/LevelSetCutters.jl b/src/LevelSetCutters/LevelSetCutters.jl index 75296ea1..ac7caf57 100644 --- a/src/LevelSetCutters/LevelSetCutters.jl +++ b/src/LevelSetCutters/LevelSetCutters.jl @@ -22,6 +22,7 @@ using MiniQhull using Gridap.TensorValues using Gridap.ReferenceFEs using Gridap.Arrays +using Gridap.Arrays: testitem, return_type using Gridap.Fields using Gridap.Helpers using Gridap.Geometry From 969d173d426dceaac7c079bc245bddbaa6a83599 Mon Sep 17 00:00:00 2001 From: Eric Neiva Date: Fri, 18 Oct 2024 07:46:32 +0200 Subject: [PATCH 15/74] Bump new Algoim version --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 5ccc3783..2df29281 100644 --- a/Project.toml +++ b/Project.toml @@ -22,9 +22,9 @@ algoimWrapper_jll = "3c43aa7b-5398-51f3-8d75-8f051e6faa4d" [compat] AbstractTrees = "0.3.3, 0.4" -Algoim = "0.2" +Algoim = "0.2.2" Combinatorics = "1" -CxxWrap = "0.14" +CxxWrap = "0.16" FillArrays = "0.10, 0.11, 0.12, 0.13, 1" Gridap = "0.17, 0.18" GridapDistributed = "0.3, 0.4" From d0b2a9341ab95c9a96a24856a6772abc95965904 Mon Sep 17 00:00:00 2001 From: Eric Neiva Date: Fri, 18 Oct 2024 07:48:39 +0200 Subject: [PATCH 16/74] Update NEWS.md --- NEWS.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 53030e64..875cf8d7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,12 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.9.5] - 2024-10-18 ### Added - Adding `compute_redistribute_weights` and `compute_adaptive_flags` functions for load balancing and adaptive mesh refinement, respectively. Since PR [#95](https://github.com/gridap/GridapEmbedded.jl/pull/95). +### Changed + +- Updated to Algoim v0.2.2, which runs on Julia 1.11. Since PR [#96](https://github.com/gridap/GridapEmbedded.jl/pull/96). ## [0.9.4] - 2024-07-09 From 03e11c8ff091210c4f0b672538b42d8c5d40d64c Mon Sep 17 00:00:00 2001 From: Eric Neiva Date: Fri, 18 Oct 2024 07:49:36 +0200 Subject: [PATCH 17/74] New GE 0.9.5 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 2df29281..08903581 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "GridapEmbedded" uuid = "8838a6a3-0006-4405-b874-385995508d5d" authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] -version = "0.9.4" +version = "0.9.5" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From ca1256a2cbebd70d25797b18bd344385c1a8dc0f Mon Sep 17 00:00:00 2001 From: Eric Neiva Date: Fri, 18 Oct 2024 07:51:37 +0200 Subject: [PATCH 18/74] Update NEWS.md [skip ci] --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 875cf8d7..bb65c903 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Updated to Algoim v0.2.2, which runs on Julia 1.11. Since PR [#96](https://github.com/gridap/GridapEmbedded.jl/pull/96). +- Updated to Algoim v0.2.2, which runs on Julia 1.11. Since PR [#97](https://github.com/gridap/GridapEmbedded.jl/pull/97). ## [0.9.4] - 2024-07-09 From 5af2a2b9e7b762576dbb0dca05a64cb2bfcb165d Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 11 Nov 2024 15:32:35 +1100 Subject: [PATCH 19/74] Revised some of the changes --- .../DistributedDiscreteGeometries.jl | 57 +++++++------------ src/Distributed/DistributedDiscretizations.jl | 43 +++++++------- src/LevelSetCutters/DiscreteGeometries.jl | 38 +++---------- 3 files changed, 51 insertions(+), 87 deletions(-) diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 935e3b90..0e1b6021 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -4,41 +4,28 @@ end local_views(a::DistributedDiscreteGeometry) = a.geometries +# TODO: Is this really necessary? function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) where {Dc,Dp} @assert DomainStyle(φh) == ReferenceDomain() gids = get_cell_gids(model) values = map(local_views(φh),local_views(model),local_views(gids)) do φh, model, gids - # Maps from the no-ghost model to the original model own_model = remove_ghost_cells(model,gids) - own_to_local_node = get_face_to_parent_face(own_model,0) - local_to_own_node = find_inverse_index_map(own_to_local_node,num_nodes(model)) - own_to_local_cell = get_face_to_parent_face(own_model,Dc) - - # Cell-to-node map for the original model - # topo = get_grid_topology(model) - # c2n_map = get_faces(topo,Dc,0) - c2n_map = collect1d(get_cell_node_ids(model)) - - # Cell-wise node coordinates (in ReferenceDomain coordinates) - cell_reffe = get_cell_reffe(model) - cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) - - φh_data = CellData.get_data(φh) - T = return_type(testitem(CellData.get_data(φh)),testitem(testitem(cell_node_coords))) + own_cells = get_face_to_parent_face(own_model,Dc) + + trian = get_triangulation(φh) + cell_points = get_cell_points(trian) + cell_ids = get_cell_node_ids(own_model) + cell_values = φh(cell_points) + + T = eltype(testitem(cell_values)) values = Vector{T}(undef,num_nodes(own_model)) - touched = fill(false,num_nodes(model)) - cell_node_coords_cache = array_cache(cell_node_coords) - for cell in own_to_local_cell # For each owned cell - field = φh_data[cell] - node_coords = getindex!(cell_node_coords_cache,cell_node_coords,cell) - for (iN,node) in enumerate(c2n_map[cell]) # Go over local nodes - own_node = local_to_own_node[node] - if (own_node != 0) && !touched[node] # Compute value if suitable - values[own_node] = field(node_coords[iN]) - touched[node] = true - end - end + cell_ids_cache = array_cache(cell_ids) + cell_values_cache = array_cache(cell_values) + for (ocell,cell) in enumerate(own_cells) + ids = getindex!(cell_ids_cache,cell_ids,ocell) + vals = getindex!(cell_values_cache,cell_values,cell) + values[ids] .= vals end return values end @@ -56,7 +43,7 @@ function DiscreteGeometry(φh::CellField,model::DistributedDiscreteModel;name::S DistributedDiscreteGeometry(geometries) end -function get_geometry(a::AbstractArray{<:DiscreteGeometry}) +function distributed_geometry(a::AbstractArray{<:DiscreteGeometry}) DistributedDiscreteGeometry(a) end @@ -104,8 +91,8 @@ function distributed_embedded_triangulation( T, cutgeo::DistributedEmbeddedDiscretization, cutinorout, - geom::DistributedDiscreteGeometry) - + geom::DistributedDiscreteGeometry +) trians = map(local_views(cutgeo),local_views(geom)) do lcutgeo,lgeom T(lcutgeo,cutinorout,lgeom) end @@ -117,8 +104,8 @@ function distributed_aggregate( strategy::AggregateCutCellsByThreshold, cut::DistributedEmbeddedDiscretization, geo::DistributedDiscreteGeometry, - in_or_out=IN) - + in_or_out = IN +) bgmodel = get_background_model(cut) facet_to_inoutcut = compute_bgfacet_to_inoutcut(bgmodel,geo) _distributed_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut) @@ -133,8 +120,8 @@ end function compute_bgfacet_to_inoutcut( cutter::Cutter, bgmodel::DistributedDiscreteModel, - geo::DistributedDiscreteGeometry) - + geo::DistributedDiscreteGeometry +) gids = get_cell_gids(bgmodel) bgf_to_ioc = map(local_views(bgmodel),local_views(gids),local_views(geo)) do model,gids,geo ownmodel = remove_ghost_cells(model,gids) diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 9ae968cf..8bb2d6e4 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -3,11 +3,12 @@ struct DistributedEmbeddedDiscretization{A,B} <: GridapType discretizations::A model::B function DistributedEmbeddedDiscretization( - d::AbstractArray{<:AbstractEmbeddedDiscretization}, - model::DistributedDiscreteModel) - A = typeof(d) + discretizations::AbstractArray{<:AbstractEmbeddedDiscretization}, + model::DistributedDiscreteModel + ) + A = typeof(discretizations) B = typeof(model) - new{A,B}(d,model) + new{A,B}(discretizations,model) end end @@ -16,12 +17,13 @@ local_views(a::DistributedEmbeddedDiscretization) = a.discretizations get_background_model(a::DistributedEmbeddedDiscretization) = a.model function get_geometry(a::DistributedEmbeddedDiscretization) - loc_geometries = map(get_geometry,local_views(a)) - get_geometry(loc_geometries) + geometries = map(get_geometry,local_views(a)) + distributed_geometry(geometries) end -function get_geometry(a::AbstractArray{<:CSG.Geometry}) - PartitionedArrays.getany(a) +# Neeed for dispatching between analytical geometries and distributed geometries +function distributed_geometry(geometries::AbstractArray{<:CSG.Geometry}) + PartitionedArrays.getany(geometries) end function cut(bgmodel::DistributedDiscreteModel,args...) @@ -127,8 +129,8 @@ end function compute_bgfacet_to_inoutcut( cutter::Cutter, bgmodel::DistributedDiscreteModel, - geo) - + geo +) gids = get_cell_gids(bgmodel) bgf_to_ioc = map(local_views(bgmodel),local_views(gids)) do model,gids ownmodel = remove_ghost_cells(model,gids) @@ -243,12 +245,11 @@ function change_bgmodel( DistributedEmbeddedDiscretization(cuts,model) end - function _change_bgmodels( cutgeo::DistributedEmbeddedDiscretization, model::DistributedDiscreteModel, - cell_to_newcell) - + cell_to_newcell +) map(local_views(cutgeo),local_views(model),cell_to_newcell) do c,m,c_to_nc change_bgmodel(c,m,c_to_nc) end @@ -256,8 +257,8 @@ end function _change_bgmodels( cutgeo::DistributedEmbeddedDiscretization, - model::DistributedDiscreteModel) - + model::DistributedDiscreteModel +) map(local_views(cutgeo),local_views(model)) do c,m change_bgmodel(c,m) end @@ -266,8 +267,8 @@ end function change_bgmodel( cut::EmbeddedDiscretization, newmodel::DiscreteModel, - cell_to_newcell=1:num_cells(get_background_model(cut))) - + cell_to_newcell=1:num_cells(get_background_model(cut)) +) ls_to_bgc_to_ioc = map(cut.ls_to_bgcell_to_inoutcut) do bgc_to_ioc new_bgc_to_ioc = Vector{Int8}(undef,num_cells(newmodel)) new_bgc_to_ioc[cell_to_newcell] = bgc_to_ioc @@ -289,10 +290,9 @@ end function change_bgmodel( cut::EmbeddedFacetDiscretization, newmodel::DiscreteModel, - facet_to_newfacet=1:num_facets(get_background_model(cut))) - + facet_to_newfacet=1:num_facets(get_background_model(cut)) +) nfacets = num_facets(newmodel) - ls_to_bgf_to_ioc = map(cut.ls_to_facet_to_inoutcut) do bgf_to_ioc new_bgf_to_ioc = Vector{Int8}(undef,nfacets) new_bgf_to_ioc[facet_to_newfacet] = bgf_to_ioc @@ -305,7 +305,8 @@ function change_bgmodel( subfacets, cut.ls_to_subfacet_to_inout, cut.oid_to_ls, - cut.geo) + cut.geo + ) end function change_bgmodel(cells::SubCellData,cell_to_newcell) diff --git a/src/LevelSetCutters/DiscreteGeometries.jl b/src/LevelSetCutters/DiscreteGeometries.jl index 23d8cbe4..472fa278 100644 --- a/src/LevelSetCutters/DiscreteGeometries.jl +++ b/src/LevelSetCutters/DiscreteGeometries.jl @@ -34,7 +34,6 @@ function discretize(a::AnalyticalGeometry,point_to_coords::AbstractArray{<:Point end function discretize(a::AnalyticalGeometry,point_to_coords::Vector{<:Point}) - tree = get_tree(a) j_to_fun, oid_to_j = _find_unique_leaves(tree) j_to_ls = [ fun.(point_to_coords) for fun in j_to_fun ] @@ -48,13 +47,10 @@ function discretize(a::AnalyticalGeometry,point_to_coords::Vector{<:Point}) end newtree = replace_data(identity,conversion,tree) - DiscreteGeometry(newtree,point_to_coords) - end function _find_unique_leaves(tree) - i_to_fun = map(n->first(n.data),collect(Leaves(tree))) i_to_oid = map(objectid,i_to_fun) j_to_oid = unique(i_to_oid) @@ -65,31 +61,6 @@ function _find_unique_leaves(tree) j_to_fun, oid_to_j end -function _get_value_at_coords(φh::CellField,model::DiscreteModel{Dc,Dp}) where {Dc,Dp} - @assert DomainStyle(φh) == ReferenceDomain() - # Cell-to-node map for the original model - c2n_map = collect1d(get_cell_node_ids(model)) - - # Cell-wise node coordinates (in ReferenceDomain coordinates) - cell_reffe = get_cell_reffe(model) - cell_node_coords = lazy_map(get_node_coordinates,cell_reffe) - - # Get cell data - φh_data = CellData.get_data(φh) - T = return_type(testitem(CellData.get_data(φh)),testitem(testitem(cell_node_coords))) - values = Vector{T}(undef,num_nodes(model)) - cell_node_coords_cache = array_cache(cell_node_coords) - # Loop over cells - for cell in eachindex(c2n_map) - field = φh_data[cell] - node_coords = getindex!(cell_node_coords_cache,cell_node_coords,cell) - for (iN,node) in enumerate(c2n_map[cell]) - values[node] = field(node_coords[iN]) - end - end - return values -end - function DiscreteGeometry( point_to_value::AbstractVector,point_to_coords::AbstractVector;name::String="") data = (point_to_value,name,nothing) @@ -97,9 +68,14 @@ function DiscreteGeometry( DiscreteGeometry(tree,point_to_coords) end +# TODO: This assumes that the level set φh is 1st order, i.e that there is a 1-to-1 correspondence +# between nodes in the mesh and dofs in φh. +# Even if we allowed higher order, the cuts are always linear. Not only it would be a waste +# of time to use higher order, but cuts could actually be wrong. +# This might be developped in the future. function DiscreteGeometry( φh::CellField,model::DiscreteModel;name::String="") - point_to_value = _get_value_at_coords(φh,model) + point_to_value = get_free_dof_values(φh) point_to_coords = collect1d(get_node_coordinates(model)) DiscreteGeometry(point_to_value,point_to_coords;name) -end \ No newline at end of file +end From f04cbcbb90995be46d8b45aa5364917e45bc9e7e Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 11 Nov 2024 15:38:24 +1100 Subject: [PATCH 20/74] Minor --- src/Distributed/DistributedDiscretizations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 8bb2d6e4..e7a8aa1b 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -21,7 +21,7 @@ function get_geometry(a::DistributedEmbeddedDiscretization) distributed_geometry(geometries) end -# Neeed for dispatching between analytical geometries and distributed geometries +# Needed for dispatching between analytical geometries and discrete geometries function distributed_geometry(geometries::AbstractArray{<:CSG.Geometry}) PartitionedArrays.getany(geometries) end From 5d31c824215c0bb3d2ec18d949a665ce956a1be0 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Fuertes Date: Tue, 12 Nov 2024 08:01:39 +1100 Subject: [PATCH 21/74] Update NEWS.md --- NEWS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.md b/NEWS.md index bb65c903..7d7bb3a4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Added support for distributed level-set geometries. Since PR[#99](https://github.com/gridap/GridapEmbedded.jl/pull/99). + ## [0.9.5] - 2024-10-18 ### Added From 3185beb8c5e2af57af4bc9009d9be659fdd455b3 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 14 Nov 2024 14:50:38 +1100 Subject: [PATCH 22/74] Started refactoring the distributed code --- src/Distributed/Distributed.jl | 13 +- .../DistributedDiscreteGeometries.jl | 114 ++---- src/Distributed/DistributedDiscretizations.jl | 375 ++++++------------ src/Interfaces/EmbeddedDiscretizations.jl | 8 +- .../EmbeddedFacetDiscretizations.jl | 2 +- 5 files changed, 156 insertions(+), 356 deletions(-) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index ee2ea62d..e204227b 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -31,14 +31,11 @@ using Gridap.Geometry: get_face_to_parent_face using Gridap.Arrays: find_inverse_index_map, testitem, return_type using Gridap.FESpaces: FESpaceWithLinearConstraints using Gridap.FESpaces: _dof_to_DOF, _DOF_to_dof -using GridapDistributed: DistributedDiscreteModel -using GridapDistributed: DistributedTriangulation -using GridapDistributed: DistributedFESpace -using GridapDistributed: DistributedSingleFieldFESpace -using GridapDistributed: DistributedMeasure -using GridapDistributed: add_ghost_cells -using GridapDistributed: generate_gids -using GridapDistributed: generate_cell_gids + +using GridapDistributed: DistributedDiscreteModel, DistributedTriangulation, DistributedMeasure +using GridapDistributed: DistributedFESpace, DistributedSingleFieldFESpace +using GridapDistributed: NoGhost, WithGhost, filter_cells_when_needed, add_ghost_cells +using GridapDistributed: generate_gids, generate_cell_gids using GridapDistributed: _find_vector_type import GridapEmbedded.AgFEM: aggregate diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 0e1b6021..83f96ad9 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -4,41 +4,9 @@ end local_views(a::DistributedDiscreteGeometry) = a.geometries -# TODO: Is this really necessary? -function _get_values_at_owned_coords(φh,model::DistributedDiscreteModel{Dc,Dp}) where {Dc,Dp} - @assert DomainStyle(φh) == ReferenceDomain() - gids = get_cell_gids(model) - values = map(local_views(φh),local_views(model),local_views(gids)) do φh, model, gids - own_model = remove_ghost_cells(model,gids) - own_cells = get_face_to_parent_face(own_model,Dc) - - trian = get_triangulation(φh) - cell_points = get_cell_points(trian) - cell_ids = get_cell_node_ids(own_model) - cell_values = φh(cell_points) - - T = eltype(testitem(cell_values)) - values = Vector{T}(undef,num_nodes(own_model)) - - cell_ids_cache = array_cache(cell_ids) - cell_values_cache = array_cache(cell_values) - for (ocell,cell) in enumerate(own_cells) - ids = getindex!(cell_ids_cache,cell_ids,ocell) - vals = getindex!(cell_values_cache,cell_values,cell) - values[ids] .= vals - end - return values - end - return values -end - function DiscreteGeometry(φh::CellField,model::DistributedDiscreteModel;name::String="") - φ_values = _get_values_at_owned_coords(φh,model) - gids = get_cell_gids(model) - geometries = map(local_views(model),local_views(gids),local_views(φ_values)) do model,gids,loc_φ - ownmodel = remove_ghost_cells(model,gids) - point_to_coords = collect1d(get_node_coordinates(ownmodel)) - DiscreteGeometry(loc_φ,point_to_coords;name) + geometries = map(local_views(φh),local_views(model)) do φh, model + DiscreteGeometry(φh,model;name) end DistributedDiscreteGeometry(geometries) end @@ -48,56 +16,45 @@ function distributed_geometry(a::AbstractArray{<:DiscreteGeometry}) end function discretize(a::AnalyticalGeometry,model::DistributedDiscreteModel) - gids = get_cell_gids(model) - geometries = map(local_views(model),local_views(gids)) do model,gids - ownmodel = remove_ghost_cells(model,gids) - point_to_coords = collect1d(get_node_coordinates(ownmodel)) - discretize(a,point_to_coords) + geometries = map(local_views(model)) do model + discretize(a,model) end DistributedDiscreteGeometry(geometries) end -function cut(cutter::Cutter,bgmodel::DistributedDiscreteModel,geom::DistributedDiscreteGeometry) +function cut( + cutter::Cutter,bgmodel::DistributedDiscreteModel,geom::DistributedDiscreteGeometry +) gids = get_cell_gids(bgmodel) - cuts = map(local_views(bgmodel),local_views(gids),local_views(geom)) do bgmodel,gids,geom - ownmodel = remove_ghost_cells(bgmodel,gids) - cutgeo = cut(cutter,ownmodel,geom) - change_bgmodel(cutgeo,bgmodel,own_to_local(gids)) + cuts = map(local_views(bgmodel),local_views(geom)) do bgmodel,geom + cut(cutter,bgmodel,geom) end - consistent_bgcell_to_inoutcut!(cuts,gids) + @notimplementedif !isconsistent_bgcell_to_inoutcut(cuts,partition(gids)) DistributedEmbeddedDiscretization(cuts,bgmodel) end -function cut_facets(cutter::Cutter,bgmodel::DistributedDiscreteModel,geom::DistributedDiscreteGeometry) - D = map(num_dims,local_views(bgmodel)) |> PartitionedArrays.getany - cell_gids = get_cell_gids(bgmodel) - facet_gids = get_face_gids(bgmodel,D-1) - cuts = map( - local_views(bgmodel), - local_views(cell_gids), - local_views(facet_gids), - local_views(geom)) do bgmodel,cell_gids,facet_gids,geom - ownmodel = remove_ghost_cells(bgmodel,cell_gids) - facet_to_pfacet = get_face_to_parent_face(ownmodel,D-1) - cutfacets = cut_facets(cutter,ownmodel,geom) - cutfacets = change_bgmodel(cutfacets,bgmodel,facet_to_pfacet) - remove_ghost_subfacets(cutfacets,facet_gids) +function cut_facets( + cutter::Cutter,bgmodel::DistributedDiscreteModel{Dc},geom::DistributedDiscreteGeometry +) where Dc + gids = get_face_gids(bgmodel,Dc-1) + cuts = map(local_views(bgmodel),local_views(geom)) do bgmodel,geom + cut_facets(cutter,bgmodel,geom) end - consistent_bgfacet_to_inoutcut!(cuts,facet_gids) + @notimplementedif !isconsistent_bgcell_to_inoutcut(cuts,partition(gids)) DistributedEmbeddedDiscretization(cuts,bgmodel) end -function distributed_embedded_triangulation( - T, - cutgeo::DistributedEmbeddedDiscretization, - cutinorout, - geom::DistributedDiscreteGeometry -) - trians = map(local_views(cutgeo),local_views(geom)) do lcutgeo,lgeom - T(lcutgeo,cutinorout,lgeom) +for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:EmbeddedBoundary) + @eval begin + function $TT(portion,cutgeo::DistributedEmbeddedDiscretization,cutinorout,geom::DistributedDiscreteGeometry) + model = get_background_model(cutgeo) + gids = get_cell_gids(model) + trians = map(local_views(cutgeo),local_views(geom),partition(gids)) do cutgeo, geom, gids + $TT(portion,gids,cutgeo,cutinorout,geom) + end + DistributedTriangulation(trians,model) + end end - bgmodel = get_background_model(cutgeo) - DistributedTriangulation(trians,bgmodel) end function distributed_aggregate( @@ -111,21 +68,18 @@ function distributed_aggregate( _distributed_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut) end -function compute_bgcell_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,geo::DistributedDiscreteGeometry) - map(local_views(cutgeo),local_views(geo)) do cutgeo,geo +function compute_bgcell_to_inoutcut( + cutgeo::DistributedEmbeddedDiscretization,geo::DistributedDiscreteGeometry +) + map(local_views(cutgeo),local_views(geo)) do cutgeo, geo compute_bgcell_to_inoutcut(cutgeo,geo) end end function compute_bgfacet_to_inoutcut( - cutter::Cutter, - bgmodel::DistributedDiscreteModel, - geo::DistributedDiscreteGeometry + cutter::Cutter, bgmodel::DistributedDiscreteModel, geo::DistributedDiscreteGeometry ) - gids = get_cell_gids(bgmodel) - bgf_to_ioc = map(local_views(bgmodel),local_views(gids),local_views(geo)) do model,gids,geo - ownmodel = remove_ghost_cells(model,gids) - compute_bgfacet_to_inoutcut(cutter,ownmodel,geo) + map(local_views(bgmodel),local_views(geo)) do model, geo + compute_bgfacet_to_inoutcut(cutter,model,geo) end - compute_bgfacet_to_inoutcut(bgmodel,bgf_to_ioc) end \ No newline at end of file diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index e7a8aa1b..3c84be45 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -1,14 +1,14 @@ -struct DistributedEmbeddedDiscretization{A,B} <: GridapType +struct DistributedEmbeddedDiscretization{Dc,Dp,A,B} <: GridapType discretizations::A model::B function DistributedEmbeddedDiscretization( - discretizations::AbstractArray{<:AbstractEmbeddedDiscretization}, + discretizations::AbstractArray{<:AbstractEmbeddedDiscretization{Dc,Dp}}, model::DistributedDiscreteModel - ) + ) where {Dc,Dp} A = typeof(discretizations) B = typeof(model) - new{A,B}(discretizations,model) + new{Dc,Dp,A,B}(discretizations,model) end end @@ -30,14 +30,12 @@ function cut(bgmodel::DistributedDiscreteModel,args...) cut(LevelSetCutter(),bgmodel,args...) end -function cut(cutter::Cutter,bgmodel::DistributedDiscreteModel,args...) - gids = get_cell_gids(bgmodel) - cuts = map(local_views(bgmodel),local_views(gids)) do bgmodel,gids - ownmodel = remove_ghost_cells(bgmodel,gids) - cutgeo = cut(cutter,ownmodel,args...) - change_bgmodel(cutgeo,bgmodel,own_to_local(gids)) +function cut(cutter::Cutter,bgmodel::DistributedDiscreteModel{Dc},args...) where Dc + gids = get_face_gids(bgmodel,Dc) + cuts = map(local_views(bgmodel)) do bgmodel + cut(cutter,bgmodel,args...) end - consistent_bgcell_to_inoutcut!(cuts,gids) + @notimplementedif !isconsistent_bgcell_to_inoutcut(cuts,partition(gids)) DistributedEmbeddedDiscretization(cuts,bgmodel) end @@ -45,124 +43,51 @@ function cut_facets(bgmodel::DistributedDiscreteModel,args...) cut_facets(LevelSetCutter(),bgmodel,args...) end -function cut_facets(cutter::Cutter,bgmodel::DistributedDiscreteModel,args...) - D = map(num_dims,local_views(bgmodel)) |> PartitionedArrays.getany - cell_gids = get_cell_gids(bgmodel) - facet_gids = get_face_gids(bgmodel,D-1) - cuts = map( - local_views(bgmodel), - local_views(cell_gids), - local_views(facet_gids)) do bgmodel,cell_gids,facet_gids - ownmodel = remove_ghost_cells(bgmodel,cell_gids) - facet_to_pfacet = get_face_to_parent_face(ownmodel,D-1) - cutfacets = cut_facets(cutter,ownmodel,args...) - cutfacets = change_bgmodel(cutfacets,bgmodel,facet_to_pfacet) - remove_ghost_subfacets(cutfacets,facet_gids) +function cut_facets(cutter::Cutter,bgmodel::DistributedDiscreteModel{Dc},args...) where Dc + gids = get_face_gids(bgmodel,Dc-1) + cuts = map(local_views(bgmodel)) do bgmodel + cut_facets(cutter,bgmodel,args...) end - consistent_bgfacet_to_inoutcut!(cuts,facet_gids) + @notimplementedif !isconsistent_bgcell_to_inoutcut(cuts,partition(gids)) DistributedEmbeddedDiscretization(cuts,bgmodel) end -function Triangulation( - cutgeo::DistributedEmbeddedDiscretization, - in_or_out::ActiveInOrOut, - args...) - - distributed_embedded_triangulation(Triangulation,cutgeo,in_or_out,args...) -end - -function Triangulation(cutgeo::DistributedEmbeddedDiscretization,args...) - trian = distributed_embedded_triangulation(Triangulation,cutgeo,args...) - remove_ghost_cells(trian) -end - -function EmbeddedBoundary(cutgeo::DistributedEmbeddedDiscretization,args...) - trian = distributed_embedded_triangulation(EmbeddedBoundary,cutgeo,args...) - remove_ghost_cells(trian) -end - -function SkeletonTriangulation(cutgeo::DistributedEmbeddedDiscretization,args...) - trian = distributed_embedded_triangulation(SkeletonTriangulation,cutgeo,args...) - remove_ghost_cells(trian) -end - -function BoundaryTriangulation(cutgeo::DistributedEmbeddedDiscretization,args...) - trian = distributed_embedded_triangulation(BoundaryTriangulation,cutgeo,args...) - remove_ghost_cells(trian) -end - -function distributed_embedded_triangulation( - T, - cutgeo::DistributedEmbeddedDiscretization, - args...) +""" +Note on distributed triangulations: - trians = map(local_views(cutgeo)) do lcutgeo - T(lcutgeo,args...) - end - bgmodel = get_background_model(cutgeo) - DistributedTriangulation(trians,bgmodel) -end +- We allow for more one argument, `portion`, which allows the user to filter +some of the cells/faces. In particular, this is used to remove ghosts from the +local triangulations. +- The default for `portion` is `NoGhost()`, wich filters out all ghost cells, except +when we have the argument `in_or_out`. +""" -function compute_bgfacet_to_inoutcut( - bgmodel::DistributedDiscreteModel, - bgf_to_ioc::AbstractArray{<:AbstractVector}) - - D = num_dims(eltype(local_views(bgmodel))) - gids = get_cell_gids(bgmodel) - bgf_to_ioc = map( - local_views(bgmodel), - local_views(gids), - bgf_to_ioc) do bgmodel,gids,bgf_to_ioc - - ownmodel = remove_ghost_cells(bgmodel,gids) - f_to_pf = Gridap.Geometry.get_face_to_parent_face(ownmodel,D-1) - _bgf_to_ioc = Vector{eltype(bgf_to_ioc)}(undef,num_faces(bgmodel,D-1)) - _bgf_to_ioc[f_to_pf] .= bgf_to_ioc - _bgf_to_ioc - end - facet_gids = get_face_gids(bgmodel,D-1) - pbgf_to_ioc = PVector(bgf_to_ioc,partition(facet_gids)) - consistent!(pbgf_to_ioc) |> wait - local_values(pbgf_to_ioc) -end - -function compute_bgfacet_to_inoutcut( - cutter::Cutter, - bgmodel::DistributedDiscreteModel, - geo +function Triangulation( + cutgeo::DistributedEmbeddedDiscretization,in_or_out::ActiveInOrOut,args... ) - gids = get_cell_gids(bgmodel) - bgf_to_ioc = map(local_views(bgmodel),local_views(gids)) do model,gids - ownmodel = remove_ghost_cells(model,gids) - compute_bgfacet_to_inoutcut(cutter,ownmodel,geo) - end - compute_bgfacet_to_inoutcut(bgmodel,bgf_to_ioc) + Triangulation(WithGhost(),cutgeo,in_or_out,args...) end -function compute_bgfacet_to_inoutcut(bgmodel::DistributedDiscreteModel,args...) - cutter = LevelSetCutter() - compute_bgfacet_to_inoutcut(cutter,bgmodel,args...) -end - -function compute_bgcell_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,args...) - map(local_views(cutgeo)) do cutgeo - compute_bgcell_to_inoutcut(cutgeo,args...) - end -end +for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:EmbeddedBoundary) + @eval begin + function $TT(cutgeo::DistributedEmbeddedDiscretization,args...) + $TT(NoGhost(),cutgeo,args...) + end -function compute_bgfacet_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,args...) - map(local_views(cutgeo)) do cutgeo - compute_bgfacet_to_inoutcut(cutgeo,args...) - end -end + function $TT(portion,cutgeo::DistributedEmbeddedDiscretization,args...) + model = get_background_model(cutgeo) + gids = get_cell_gids(model) + trians = map(local_views(cutgeo),partition(gids)) do cutgeo, gids + $TT(portion,gids,cutgeo,args...) + end + DistributedTriangulation(trians,model) + end -function remove_ghost_cells(trian::DistributedTriangulation) - model = get_background_model(trian) - gids = get_cell_gids(model) - trians = map(local_views(trian),local_views(gids)) do trian,gids - remove_ghost_cells(trian,gids) + function $TT(portion,gids::AbstractLocalIndices,cutgeo::AbstractEmbeddedDiscretization,args...) + trian = $TT(cutgeo,args...) + filter_cells_when_needed(portion,gids,trian) + end end - DistributedTriangulation(trians,model) end function remove_ghost_cells(trian::AppendedTriangulation,gids) @@ -171,180 +96,104 @@ function remove_ghost_cells(trian::AppendedTriangulation,gids) lazy_append(a,b) end -function remove_ghost_cells(trian::SubFacetTriangulation,gids) - model = get_background_model(trian) - D = num_cell_dims(model) - glue = get_glue(trian,Val{D}()) +function remove_ghost_cells(trian::SubFacetTriangulation{Df,Dc},gids) where {Df,Dc} + glue = get_glue(trian,Val{Dc}()) remove_ghost_cells(glue,trian,gids) end -function remove_ghost_cells(model::DiscreteModel,gids::AbstractLocalIndices) - DiscreteModelPortion(model,own_to_local(gids)) -end - -function consistent_bgcell_to_inoutcut!( - cuts::AbstractArray{<:AbstractEmbeddedDiscretization}, - gids::PRange) - - ls_to_bgcell_to_inoutcut = map(get_ls_to_bgcell_to_inoutcut,cuts) - _consistent!(ls_to_bgcell_to_inoutcut,gids) -end - -function get_ls_to_bgcell_to_inoutcut(cut::EmbeddedDiscretization) - cut.ls_to_bgcell_to_inoutcut -end - -function consistent_bgfacet_to_inoutcut!( - cuts::AbstractArray{<:AbstractEmbeddedDiscretization}, - gids::PRange) - - ls_to_bgfacet_to_inoutcut = map(get_ls_to_bgfacet_to_inoutcut,cuts) - _consistent!(ls_to_bgfacet_to_inoutcut,gids) -end - -function get_ls_to_bgfacet_to_inoutcut(cut::EmbeddedFacetDiscretization) - cut.ls_to_facet_to_inoutcut -end - -function _consistent!( - p_to_i_to_a::AbstractArray{<:Vector{<:Vector}}, - prange::PRange) - - n = map(length,p_to_i_to_a) |> PartitionedArrays.getany - for i in 1:n - p_to_a = map(i_to_a->i_to_a[i],p_to_i_to_a) - PVector(p_to_a,partition(prange)) |> consistent! |> wait - map(p_to_a,p_to_i_to_a) do p_to_a,p_to_ia - copyto!(p_to_ia[i],p_to_a) - end +function remove_ghost_subfacets(cut::EmbeddedFacetDiscretization,facet_gids) + bgfacet_mask = map(!iszero,local_to_owner(facet_gids)) + subfacet_mask = map(Reindex(bgfacet_mask),cut.subfacets.cell_to_bgcell) + new_subfacets = findall(subfacet_mask) + subfacets = SubCellData(cut.subfacets,new_subfacets) + ls_to_subfacet_to_inout = map(cut.ls_to_subfacet_to_inout) do sf_to_io + map(Reindex(sf_to_io),new_subfacets) end + EmbeddedFacetDiscretization( + cut.bgmodel, + cut.ls_to_facet_to_inoutcut, + subfacets, + ls_to_subfacet_to_inout, + cut.oid_to_ls, + cut.geo + ) end -function change_bgmodel( - cutgeo::DistributedEmbeddedDiscretization, - model::DistributedDiscreteModel, - args...) - - cuts = _change_bgmodels(cutgeo,model,args...) - gids = get_cell_gids(model) - ls_to_bgcell_to_inoutcut = map(c->c.ls_to_bgcell_to_inoutcut,cuts) - _consistent!(ls_to_bgcell_to_inoutcut,gids) - DistributedEmbeddedDiscretization(cuts,model) -end +# Distributed InOutCut flag methods -function change_bgmodel( - cutgeo::DistributedEmbeddedDiscretization{<:AbstractArray{<:EmbeddedFacetDiscretization}}, - model::DistributedDiscreteModel, - args...) +""" + isconsistent_bgcell_to_inoutcut(cut::DistributedEmbeddedDiscretization) + isconsistent_bgcell_to_inoutcut(cuts::AbstractArray{<:AbstractEmbeddedDiscretization},indices) - D = map(num_dims,local_views(model)) |> PartitionedArrays.getany - cuts = _change_bgmodels(cutgeo,model,args...) - gids = get_face_gids(model,D-1) - ls_to_facet_to_inoutcut = map(c->c.ls_to_facet_to_inoutcut,cuts) - _consistent!(ls_to_facet_to_inoutcut,gids) - DistributedEmbeddedDiscretization(cuts,model) +Returns true if the local `ls_to_bgcell_to_inoutcut` arrays are consistent +accross processors. +""" +function isconsistent_bgcell_to_inoutcut( + cut::DistributedEmbeddedDiscretization{Dc} +) where Dc + model = get_background_model(cut) + gids = get_face_gids(model,Dc) + isconsistent_bgcell_to_inoutcut(local_views(cut),partition(gids)) end -function _change_bgmodels( - cutgeo::DistributedEmbeddedDiscretization, - model::DistributedDiscreteModel, - cell_to_newcell +function isconsistent_bgcell_to_inoutcut( + cuts::AbstractArray{<:AbstractEmbeddedDiscretization},indices::AbstractArray ) - map(local_views(cutgeo),local_views(model),cell_to_newcell) do c,m,c_to_nc - change_bgmodel(c,m,c_to_nc) + get_inoutcut(cut::EmbeddedDiscretization) = Tuple(cut.ls_to_bgcell_to_inoutcut) + get_inoutcut(cut::EmbeddedFacetDiscretization) = Tuple(cut.ls_to_facet_to_inoutcut) + ls_to_bgcell_to_inoutcut = tuple_of_arrays(map(get_inoutcut,cuts)) + return isconsistent_bgcell_to_inoutcut(ls_to_bgcell_to_inoutcut,indices) +end + +function isconsistent_bgcell_to_inoutcut( + ls_to_bgcell_to_inoutcut::NTuple{N,<:AbstractArray{<:Vector}},indices::AbstractArray +) where N + for bgcell_to_inoutcut in ls_to_bgcell_to_inoutcut + if !isconsistent_bgcell_to_inoutcut(bgcell_to_inoutcut,indices) + return false + end end + return true end -function _change_bgmodels( - cutgeo::DistributedEmbeddedDiscretization, - model::DistributedDiscreteModel +function isconsistent_bgcell_to_inoutcut( + bgcell_to_inoutcut::AbstractArray{<:Vector},indices::AbstractArray ) - map(local_views(cutgeo),local_views(model)) do c,m - change_bgmodel(c,m) + # TODO: Some allocations can be avoided by going to the low-level communication API + ref = map(copy,bgcell_to_inoutcut) + wait(consistent!(PVector(ref,indices))) + is_consistent = map(bgcell_to_inoutcut,ref) do bgcell_to_inoutcut,ref + bgcell_to_inoutcut == ref end + return reduce(&,is_consistent,init=true) end -function change_bgmodel( - cut::EmbeddedDiscretization, - newmodel::DiscreteModel, - cell_to_newcell=1:num_cells(get_background_model(cut)) -) - ls_to_bgc_to_ioc = map(cut.ls_to_bgcell_to_inoutcut) do bgc_to_ioc - new_bgc_to_ioc = Vector{Int8}(undef,num_cells(newmodel)) - new_bgc_to_ioc[cell_to_newcell] = bgc_to_ioc - new_bgc_to_ioc - end - subcells = change_bgmodel(cut.subcells,cell_to_newcell) - subfacets = change_bgmodel(cut.subfacets,cell_to_newcell) - EmbeddedDiscretization( - newmodel, - ls_to_bgc_to_ioc, - subcells, - cut.ls_to_subcell_to_inout, - subfacets, - cut.ls_to_subfacet_to_inout, - cut.oid_to_ls, - cut.geo) +# TODO: Should we check for consistency here? +function compute_bgfacet_to_inoutcut(bgmodel::DistributedDiscreteModel,args...) + cutter = LevelSetCutter() + compute_bgfacet_to_inoutcut(cutter,bgmodel,args...) end -function change_bgmodel( - cut::EmbeddedFacetDiscretization, - newmodel::DiscreteModel, - facet_to_newfacet=1:num_facets(get_background_model(cut)) -) - nfacets = num_facets(newmodel) - ls_to_bgf_to_ioc = map(cut.ls_to_facet_to_inoutcut) do bgf_to_ioc - new_bgf_to_ioc = Vector{Int8}(undef,nfacets) - new_bgf_to_ioc[facet_to_newfacet] = bgf_to_ioc - new_bgf_to_ioc +function compute_bgfacet_to_inoutcut(cutter::Cutter,bgmodel::DistributedDiscreteModel,args...) + map(local_views(bgmodel)) do bgmodel + compute_bgfacet_to_inoutcut(cutter,bgmodel,args...) end - subfacets = change_bgmodel(cut.subfacets,facet_to_newfacet) - EmbeddedFacetDiscretization( - newmodel, - ls_to_bgf_to_ioc, - subfacets, - cut.ls_to_subfacet_to_inout, - cut.oid_to_ls, - cut.geo - ) end -function change_bgmodel(cells::SubCellData,cell_to_newcell) - cell_to_bgcell = lazy_map(Reindex(cell_to_newcell),cells.cell_to_bgcell) - SubCellData( - cells.cell_to_points, - collect(Int32,cell_to_bgcell), - cells.point_to_coords, - cells.point_to_rcoords) -end - -function change_bgmodel(facets::SubFacetData,cell_to_newcell) - facet_to_bgcell = lazy_map(Reindex(cell_to_newcell),facets.facet_to_bgcell) - SubFacetData( - facets.facet_to_points, - facets.facet_to_normal, - collect(Int32,facet_to_bgcell), - facets.point_to_coords, - facets.point_to_rcoords) +function compute_bgcell_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,args...) + map(local_views(cutgeo)) do cutgeo + compute_bgcell_to_inoutcut(cutgeo,args...) + end end -function remove_ghost_subfacets(cut::EmbeddedFacetDiscretization,facet_gids) - bgfacet_mask = map(!iszero,local_to_owner(facet_gids)) - subfacet_mask = map(Reindex(bgfacet_mask),cut.subfacets.cell_to_bgcell) - new_subfacets = findall(subfacet_mask) - subfacets = SubCellData(cut.subfacets,new_subfacets) - ls_to_subfacet_to_inout = map(cut.ls_to_subfacet_to_inout) do sf_to_io - map(Reindex(sf_to_io),new_subfacets) +function compute_bgfacet_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,args...) + map(local_views(cutgeo)) do cutgeo + compute_bgfacet_to_inoutcut(cutgeo,args...) end - EmbeddedFacetDiscretization( - cut.bgmodel, - cut.ls_to_facet_to_inoutcut, - subfacets, - ls_to_subfacet_to_inout, - cut.oid_to_ls, - cut.geo) end +# AMR + function compute_redistribute_wights( cut::DistributedEmbeddedDiscretization, args...) diff --git a/src/Interfaces/EmbeddedDiscretizations.jl b/src/Interfaces/EmbeddedDiscretizations.jl index 9dcf6237..61d2e759 100644 --- a/src/Interfaces/EmbeddedDiscretizations.jl +++ b/src/Interfaces/EmbeddedDiscretizations.jl @@ -1,12 +1,12 @@ -abstract type AbstractEmbeddedDiscretization <: GridapType end +abstract type AbstractEmbeddedDiscretization{Dc,Dp} <: GridapType end -struct EmbeddedDiscretization{Dp,T} <: AbstractEmbeddedDiscretization +struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization{Dc,Dc} bgmodel::DiscreteModel ls_to_bgcell_to_inoutcut::Vector{Vector{Int8}} - subcells::SubCellData{Dp,Dp,T} + subcells::SubCellData{Dc,Dc,T} ls_to_subcell_to_inout::Vector{Vector{Int8}} - subfacets::SubFacetData{Dp,T} + subfacets::SubFacetData{Dc,T} ls_to_subfacet_to_inout::Vector{Vector{Int8}} oid_to_ls::Dict{UInt,Int} geo::CSG.Geometry diff --git a/src/Interfaces/EmbeddedFacetDiscretizations.jl b/src/Interfaces/EmbeddedFacetDiscretizations.jl index 4086fb69..b521906c 100644 --- a/src/Interfaces/EmbeddedFacetDiscretizations.jl +++ b/src/Interfaces/EmbeddedFacetDiscretizations.jl @@ -1,5 +1,5 @@ -struct EmbeddedFacetDiscretization{Dc,Dp,T} <: AbstractEmbeddedDiscretization +struct EmbeddedFacetDiscretization{Dc,Dp,T} <: AbstractEmbeddedDiscretization{Dc,Dp} bgmodel::DiscreteModel{Dp,Dp} ls_to_facet_to_inoutcut::Vector{Vector{Int8}} subfacets::SubCellData{Dc,Dp,T} From 1d82808cd65bcff9557a1d3d57ef071db992f3dc Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 14 Nov 2024 15:38:58 +1100 Subject: [PATCH 23/74] Added add_ghost_cells and generate_cell_gids for distributed SubFacetTriangulations --- src/Distributed/Distributed.jl | 2 + .../DistributedDiscreteGeometries.jl | 1 + src/Distributed/DistributedDiscretizations.jl | 17 +++-- .../DistributedSubFacetTriangulations.jl | 63 +++++++++++++++++++ 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 src/Distributed/DistributedSubFacetTriangulations.jl diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index e204227b..6d881bba 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -58,6 +58,8 @@ include("DistributedDiscretizations.jl") include("DistributedDiscreteGeometries.jl") +include("DistributedSubFacetTriangulations.jl") + include("DistributedAgFEM.jl") include("DistributedQuadratures.jl") diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index 83f96ad9..f196c6e9 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -1,3 +1,4 @@ + struct DistributedDiscreteGeometry{A} <: GridapType geometries::A end diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 3c84be45..a35de042 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -52,15 +52,13 @@ function cut_facets(cutter::Cutter,bgmodel::DistributedDiscreteModel{Dc},args... DistributedEmbeddedDiscretization(cuts,bgmodel) end -""" -Note on distributed triangulations: - -- We allow for more one argument, `portion`, which allows the user to filter -some of the cells/faces. In particular, this is used to remove ghosts from the -local triangulations. -- The default for `portion` is `NoGhost()`, wich filters out all ghost cells, except -when we have the argument `in_or_out`. -""" +# Note on distributed triangulations: +# +# - We allow for more one argument, `portion`, which allows the user to filter +# some of the cells/faces. In particular, this is used to remove ghosts from the +# local triangulations. +# - The default for `portion` is `NoGhost()`, wich filters out all ghost cells, except +# when we have the argument `in_or_out`. function Triangulation( cutgeo::DistributedEmbeddedDiscretization,in_or_out::ActiveInOrOut,args... @@ -90,6 +88,7 @@ for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:Embedde end end +# TODO: This should go to GridapDistributed function remove_ghost_cells(trian::AppendedTriangulation,gids) a = remove_ghost_cells(trian.a,gids) b = remove_ghost_cells(trian.b,gids) diff --git a/src/Distributed/DistributedSubFacetTriangulations.jl b/src/Distributed/DistributedSubFacetTriangulations.jl new file mode 100644 index 00000000..d47c3501 --- /dev/null +++ b/src/Distributed/DistributedSubFacetTriangulations.jl @@ -0,0 +1,63 @@ + +const DistributedSubFacetTriangulation{Df,Dc} = DistributedTriangulation{Df,Dc,<:AbstractArray{<:Union{SubFacetTriangulation{Df,Dc},TriangulationView{Df,Dc,<:SubFacetTriangulation{Df,Dc}}}}} + +# Each cut facet belongs to the background cell containing it. So we can generate +# ownership information for the cut facets from the background cell gids. +function GridapDistributed.generate_cell_gids( + trian::DistributedSubFacetTriangulation{Df,Dc}, +) where {Df,Dc} + model = get_background_model(trian) + cgids = get_cell_gids(model) + + n_lfacets = map(num_cells,local_views(trian)) + first_gid = scan(+,n_lfacets,type=:exclusive,init=one(eltype(n_lfacets))) + n_facets = reduce(+,n_lfacets,init=zero(eltype(n_lfacets))) + + fgids = map(local_views(trian),partition(cgids),first_gid,n_lfacets) do trian, cgids, first_gid, n_lfacets + glue = get_glue(trian,Val(Dc)) # Glue from cut facets to background cells + facet_to_bgcell = glue.tface_to_mface + + facet_to_gid = collect(first_gid:(first_gid+n_lfacets-1)) + facet_to_owner = local_to_owner(cgids)[facet_to_bgcell] + LocalIndices(n_facets,part_id(cgids),facet_to_gid,facet_to_owner) + end + return PRange(fgids) +end + +function GridapDistributed.add_ghost_cells( + trian::DistributedSubFacetTriangulation{Df,Dc}, +) where {Df,Dc} + + # In this case, we already have all ghost facets + if eltype(local_views(trian)) <: SubFacetTriangulation + return trian + end + + # First, we create a new Triangulation containing all the cut facets + model = get_background_model(trian) + bgtrians, facet_to_bgfacet = map(local_views(trian)) do trian + @assert isa(trian,TriangulationView) + trian.parent, trian.cell_to_parent_cell + end |> tuple_of_arrays + bgtrian = DistributedTriangulation(bgtrians,model) + fgids = partition(generate_cell_gids(bgtrian)) + + # Exchange info about cut facets + inside_facets = map(fgids,facet_to_bgfacet) do fgids, facet_to_bgfacet + inside_facets = falses(local_length(fgids)) + inside_facets[facet_to_bgfacet] .= true + return inside_facets + end + wait(consistent!(PVector(inside_facets,fgids))) # Exchange information + + # Return ghosted Triangulation + covers_all = reduce(&,map(all,inside_facets),init=true) + if covers_all + ghosted_trian = bgtrian + else + ghosted_trian = DistributedTriangulation( + map(TriangulationView,bgtrians,inside_facets), model + ) + end + return ghosted_trian +end From 946cdc120bf72ce251e1d608cd09abdbcf3a9d66 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 14 Nov 2024 15:45:49 +1100 Subject: [PATCH 24/74] Fixed distributed moment-fitted quads (maybe?) --- src/Distributed/DistributedQuadratures.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Distributed/DistributedQuadratures.jl b/src/Distributed/DistributedQuadratures.jl index 06a40a4c..634b7786 100644 --- a/src/Distributed/DistributedQuadratures.jl +++ b/src/Distributed/DistributedQuadratures.jl @@ -1,18 +1,18 @@ function CellData.Measure( - t::DistributedTriangulation, + trian::DistributedTriangulation, quad::Tuple{MomentFitted,Vararg}; kwargs...) @notimplemented name, _args, _kwargs = quad cut,cutfacets,_args... = _args - t = remove_ghost_cells(t) - measures = map( - local_views(t), - local_views(cut), - local_views(cutfacets)) do trian,cut,cutfacets - quad = name, (cut,cutfacets,_args...), _kwargs - Measure(trian,quad;kwargs...) + + model = get_background_model(trian) + gids = get_cell_gids(model) + trian = remove_ghost_cells(trian,gids) + measures = map(local_views(trian),local_views(cut),local_views(cutfacets)) do trian,cut,cutfacets + quad = name, (cut,cutfacets,_args...), _kwargs + Measure(trian,quad;kwargs...) end DistributedMeasure(measures) end From 7eac5af045a120f5b10a6dde3132b2f00d282d62 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 14 Nov 2024 16:38:16 +1100 Subject: [PATCH 25/74] Fixes --- src/Distributed/DistributedAgFEM.jl | 122 +++++++++++++++--- src/Distributed/DistributedDiscretizations.jl | 12 +- 2 files changed, 107 insertions(+), 27 deletions(-) diff --git a/src/Distributed/DistributedAgFEM.jl b/src/Distributed/DistributedAgFEM.jl index 4501ba76..cdb65ab1 100644 --- a/src/Distributed/DistributedAgFEM.jl +++ b/src/Distributed/DistributedAgFEM.jl @@ -3,8 +3,8 @@ function AgFEMSpace( bgmodel::DistributedDiscreteModel, f::DistributedFESpace, bgcell_to_bgcellin::AbstractArray{<:AbstractVector}, - g::DistributedFESpace=f) - + g::DistributedFESpace=f +) bgmodel_gids = get_cell_gids(bgmodel) spaces = map( local_views(f), @@ -13,9 +13,7 @@ function AgFEMSpace( local_views(bgmodel_gids)) do f,bgcell_to_bgcellin,g,gids AgFEMSpace(f,bgcell_to_bgcellin,g,local_to_global(gids)) end - trians = map(get_triangulation,local_views(f)) - trian = DistributedTriangulation(trians,bgmodel) - trian = add_ghost_cells(trian) + trian = add_ghost_cells(get_triangulation(f)) trian_gids = generate_cell_gids(trian) cell_to_cellin = _active_aggregates(bgcell_to_bgcellin) cell_to_ldofs = cell_ldof_to_mdof(spaces,cell_to_cellin) @@ -26,7 +24,7 @@ function AgFEMSpace( end function aggregate(strategy,cutgeo::DistributedEmbeddedDiscretization,args...) - aggregates,aggregate_owner = distributed_aggregate(strategy,cutgeo,args...) + aggregates, aggregate_owner = distributed_aggregate(strategy,cutgeo,args...) bgmodel = get_background_model(cutgeo) if has_remote_aggregation(bgmodel,aggregates) bgmodel = add_remote_aggregates(bgmodel,aggregates,aggregate_owner) @@ -40,8 +38,8 @@ end function distributed_aggregate( strategy::AggregateCutCellsByThreshold, cut::DistributedEmbeddedDiscretization, - in_or_out=IN) - + in_or_out=IN +) geo = get_geometry(cut) distributed_aggregate(strategy,cut,geo,in_or_out) end @@ -50,14 +48,13 @@ function distributed_aggregate( strategy::AggregateCutCellsByThreshold, cut::DistributedEmbeddedDiscretization, geo::CSG.Geometry, - in_or_out=IN) - + in_or_out=IN +) bgmodel = get_background_model(cut) facet_to_inoutcut = compute_bgfacet_to_inoutcut(bgmodel,geo) _distributed_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut) end - function _distributed_aggregate_by_threshold(threshold,cutgeo,geo,loc,facet_to_inoutcut) @assert loc in (IN,OUT) @@ -82,15 +79,14 @@ function _distributed_aggregate_by_threshold(threshold,cutgeo,geo,loc,facet_to_i _distributed_aggregate_by_threshold_barrier( threshold,cell_to_unit_cut_meas,facet_to_inoutcut,cell_to_inoutcut, - loc,cell_to_coords,cell_to_faces,face_to_cells,gids) + loc,cell_to_coords,cell_to_faces,face_to_cells,gids + ) end - function _distributed_aggregate_by_threshold_barrier( threshold,cell_to_unit_cut_meas,facet_to_inoutcut,cell_to_inoutcut, - loc,cell_to_coords,cell_to_faces,face_to_cells,gids) - - + loc,cell_to_coords,cell_to_faces,face_to_cells,gids +) ocell_to_touched = map(cell_to_unit_cut_meas) do c_to_m map(≥,c_to_m,Fill(threshold,length(c_to_m))) end @@ -111,7 +107,6 @@ function _distributed_aggregate_by_threshold_barrier( end cell_to_neig = map(n->zeros(Int32,n),n_cells) - cell_to_root_part = map(collect,local_to_owner(gids)) c1 = map(array_cache,cell_to_faces) @@ -129,7 +124,8 @@ function _distributed_aggregate_by_threshold_barrier( cell_to_faces, face_to_cells, facet_to_inoutcut, - loc) + loc + ) PVector(cell_to_touched,partition(gids)) |> consistent! |> wait PVector(cell_to_neig,partition(gids)) |> consistent! |> wait @@ -248,8 +244,8 @@ function _find_best_neighbor_from_centroid_distance( cell_to_touched, cell_to_root_centroid, facet_to_inoutcut, - loc) - + loc +) faces = getindex!(c1,cell_to_faces,cell) dmin = Inf T = eltype(eltype(face_to_cells)) @@ -559,6 +555,8 @@ function _local_aggregates(cell_to_gcellin,gcell_to_cell) end end +# change_bgmodel + function change_bgmodel(cell_to_gcellin,gids::PRange) map(change_bgmodel,cell_to_gcellin,local_to_global(gids)) end @@ -571,3 +569,87 @@ function change_bgmodel(cell_to_gcellin,ncell_to_gcell) end ncell_to_gcellin end + +function change_bgmodel( + cutgeo::DistributedEmbeddedDiscretization, + model::DistributedDiscreteModel +) + cuts = map(change_bgmodel,local_views(cutgeo),local_views(model)) + DistributedEmbeddedDiscretization(cuts,model) +end + +function change_bgmodel( + cutgeo::DistributedEmbeddedDiscretization, + model::DistributedDiscreteModel, + cell_to_new_cell +) + cuts = map(change_bgmodel,local_views(cutgeo),local_views(model),cell_to_new_cell) + DistributedEmbeddedDiscretization(cuts,model) +end + +function change_bgmodel( + cut::EmbeddedDiscretization, + newmodel::DiscreteModel, + cell_to_newcell=1:num_cells(get_background_model(cut)) +) + ls_to_bgc_to_ioc = map(cut.ls_to_bgcell_to_inoutcut) do bgc_to_ioc + new_bgc_to_ioc = Vector{Int8}(undef,num_cells(newmodel)) + new_bgc_to_ioc[cell_to_newcell] = bgc_to_ioc + new_bgc_to_ioc + end + subcells = change_bgmodel(cut.subcells,cell_to_newcell) + subfacets = change_bgmodel(cut.subfacets,cell_to_newcell) + EmbeddedDiscretization( + newmodel, + ls_to_bgc_to_ioc, + subcells, + cut.ls_to_subcell_to_inout, + subfacets, + cut.ls_to_subfacet_to_inout, + cut.oid_to_ls, + cut.geo + ) +end + +function change_bgmodel( + cut::EmbeddedFacetDiscretization, + newmodel::DiscreteModel, + facet_to_newfacet=1:num_facets(get_background_model(cut)) +) + nfacets = num_facets(newmodel) + ls_to_bgf_to_ioc = map(cut.ls_to_facet_to_inoutcut) do bgf_to_ioc + new_bgf_to_ioc = Vector{Int8}(undef,nfacets) + new_bgf_to_ioc[facet_to_newfacet] = bgf_to_ioc + new_bgf_to_ioc + end + subfacets = change_bgmodel(cut.subfacets,facet_to_newfacet) + EmbeddedFacetDiscretization( + newmodel, + ls_to_bgf_to_ioc, + subfacets, + cut.ls_to_subfacet_to_inout, + cut.oid_to_ls, + cut.geo + ) +end + +function change_bgmodel(cells::SubCellData,cell_to_newcell) + cell_to_bgcell = lazy_map(Reindex(cell_to_newcell),cells.cell_to_bgcell) + SubCellData( + cells.cell_to_points, + collect(Int32,cell_to_bgcell), + cells.point_to_coords, + cells.point_to_rcoords + ) +end + +function change_bgmodel(facets::SubFacetData,cell_to_newcell) + facet_to_bgcell = lazy_map(Reindex(cell_to_newcell),facets.facet_to_bgcell) + SubFacetData( + facets.facet_to_points, + facets.facet_to_normal, + collect(Int32,facet_to_bgcell), + facets.point_to_coords, + facets.point_to_rcoords + ) +end diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index a35de042..5d6a22ba 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -120,13 +120,11 @@ end # Distributed InOutCut flag methods -""" - isconsistent_bgcell_to_inoutcut(cut::DistributedEmbeddedDiscretization) - isconsistent_bgcell_to_inoutcut(cuts::AbstractArray{<:AbstractEmbeddedDiscretization},indices) - -Returns true if the local `ls_to_bgcell_to_inoutcut` arrays are consistent -accross processors. -""" +# isconsistent_bgcell_to_inoutcut(cut::DistributedEmbeddedDiscretization) +# isconsistent_bgcell_to_inoutcut(cuts::AbstractArray{<:AbstractEmbeddedDiscretization},indices) +# +# Returns true if the local `ls_to_bgcell_to_inoutcut` arrays are consistent +# accross processors. function isconsistent_bgcell_to_inoutcut( cut::DistributedEmbeddedDiscretization{Dc} ) where Dc From af3720f38dbee38a3d20939648f1660dca431d43 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 14 Nov 2024 16:44:42 +1100 Subject: [PATCH 26/74] Minor --- src/Distributed/Distributed.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index 6d881bba..47d92880 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -26,7 +26,7 @@ using GridapEmbedded.Interfaces: AbstractEmbeddedDiscretization using GridapEmbedded.AgFEM: _touch_aggregated_cells! using GridapEmbedded.AgFEM: AggregateCutCellsByThreshold using GridapEmbedded.MomentFittedQuadratures: MomentFitted -using Gridap.Geometry: AppendedTriangulation +using Gridap.Geometry: AppendedTriangulation, TriangulationView using Gridap.Geometry: get_face_to_parent_face using Gridap.Arrays: find_inverse_index_map, testitem, return_type using Gridap.FESpaces: FESpaceWithLinearConstraints From 392b451f8f72d551bd4f665ea40941eacf966f82 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 14 Nov 2024 21:55:26 +1100 Subject: [PATCH 27/74] Updated NEWS --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 7d7bb3a4..325955f8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for distributed level-set geometries. Since PR[#99](https://github.com/gridap/GridapEmbedded.jl/pull/99). +- Refactored the distributed code to allow for ghosted/unghosted geometries and triangulations. Since PR[#100](https://github.com/gridap/GridapEmbedded.jl/pull/100). ## [0.9.5] - 2024-10-18 From 6850b686cc41cf5a018436377fc35efa63e60ed2 Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:19:20 +1000 Subject: [PATCH 28/74] Distributed ghost skeleton --- src/Distributed/Distributed.jl | 1 + .../DistributedDiscreteGeometries.jl | 2 +- src/Distributed/DistributedDiscretizations.jl | 22 +++++++++---------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index 47d92880..b4cf0b8e 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -45,6 +45,7 @@ import GridapEmbedded.Interfaces: cut_facets import GridapEmbedded.Interfaces: EmbeddedBoundary import GridapEmbedded.Interfaces: compute_bgfacet_to_inoutcut import GridapEmbedded.Interfaces: compute_bgcell_to_inoutcut +import GridapEmbedded.Interfaces: GhostSkeleton import GridapEmbedded.CSG: get_geometry import GridapEmbedded.LevelSetCutters: discretize, DiscreteGeometry import Gridap.Geometry: Triangulation diff --git a/src/Distributed/DistributedDiscreteGeometries.jl b/src/Distributed/DistributedDiscreteGeometries.jl index f196c6e9..0f9b55f2 100644 --- a/src/Distributed/DistributedDiscreteGeometries.jl +++ b/src/Distributed/DistributedDiscreteGeometries.jl @@ -45,7 +45,7 @@ function cut_facets( DistributedEmbeddedDiscretization(cuts,bgmodel) end -for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:EmbeddedBoundary) +for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:EmbeddedBoundary,:GhostSkeleton) @eval begin function $TT(portion,cutgeo::DistributedEmbeddedDiscretization,cutinorout,geom::DistributedDiscreteGeometry) model = get_background_model(cutgeo) diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 5d6a22ba..3fdf7e5d 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -52,12 +52,12 @@ function cut_facets(cutter::Cutter,bgmodel::DistributedDiscreteModel{Dc},args... DistributedEmbeddedDiscretization(cuts,bgmodel) end -# Note on distributed triangulations: -# -# - We allow for more one argument, `portion`, which allows the user to filter -# some of the cells/faces. In particular, this is used to remove ghosts from the -# local triangulations. -# - The default for `portion` is `NoGhost()`, wich filters out all ghost cells, except +# Note on distributed triangulations: +# +# - We allow for more one argument, `portion`, which allows the user to filter +# some of the cells/faces. In particular, this is used to remove ghosts from the +# local triangulations. +# - The default for `portion` is `NoGhost()`, wich filters out all ghost cells, except # when we have the argument `in_or_out`. function Triangulation( @@ -66,7 +66,7 @@ function Triangulation( Triangulation(WithGhost(),cutgeo,in_or_out,args...) end -for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:EmbeddedBoundary) +for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:EmbeddedBoundary,:GhostSkeleton) @eval begin function $TT(cutgeo::DistributedEmbeddedDiscretization,args...) $TT(NoGhost(),cutgeo,args...) @@ -122,9 +122,9 @@ end # isconsistent_bgcell_to_inoutcut(cut::DistributedEmbeddedDiscretization) # isconsistent_bgcell_to_inoutcut(cuts::AbstractArray{<:AbstractEmbeddedDiscretization},indices) -# -# Returns true if the local `ls_to_bgcell_to_inoutcut` arrays are consistent -# accross processors. +# +# Returns true if the local `ls_to_bgcell_to_inoutcut` arrays are consistent +# accross processors. function isconsistent_bgcell_to_inoutcut( cut::DistributedEmbeddedDiscretization{Dc} ) where Dc @@ -189,7 +189,7 @@ function compute_bgfacet_to_inoutcut(cutgeo::DistributedEmbeddedDiscretization,a end end -# AMR +# AMR function compute_redistribute_wights( cut::DistributedEmbeddedDiscretization, From a8bb48d051be7f0b49f1e4da09cc6d1b817a3435 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 27 Feb 2025 17:09:49 +1100 Subject: [PATCH 29/74] Minor --- src/Distributed/DistributedDiscretizations.jl | 8 ++++---- src/Interfaces/EmbeddedDiscretizations.jl | 4 ++-- .../EmbeddedFacetDiscretizations.jl | 2 +- src/LevelSetCutters/CutTriangulations.jl | 20 +++++++++---------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 5d6a22ba..0a43c2f6 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -1,14 +1,14 @@ -struct DistributedEmbeddedDiscretization{Dc,Dp,A,B} <: GridapType +struct DistributedEmbeddedDiscretization{A,B} <: GridapType discretizations::A model::B function DistributedEmbeddedDiscretization( - discretizations::AbstractArray{<:AbstractEmbeddedDiscretization{Dc,Dp}}, + discretizations::AbstractArray{<:AbstractEmbeddedDiscretization}, model::DistributedDiscreteModel - ) where {Dc,Dp} + ) A = typeof(discretizations) B = typeof(model) - new{Dc,Dp,A,B}(discretizations,model) + new{A,B}(discretizations,model) end end diff --git a/src/Interfaces/EmbeddedDiscretizations.jl b/src/Interfaces/EmbeddedDiscretizations.jl index 61d2e759..5a6a14b3 100644 --- a/src/Interfaces/EmbeddedDiscretizations.jl +++ b/src/Interfaces/EmbeddedDiscretizations.jl @@ -1,7 +1,7 @@ -abstract type AbstractEmbeddedDiscretization{Dc,Dp} <: GridapType end +abstract type AbstractEmbeddedDiscretization <: GridapType end -struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization{Dc,Dc} +struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization bgmodel::DiscreteModel ls_to_bgcell_to_inoutcut::Vector{Vector{Int8}} subcells::SubCellData{Dc,Dc,T} diff --git a/src/Interfaces/EmbeddedFacetDiscretizations.jl b/src/Interfaces/EmbeddedFacetDiscretizations.jl index b521906c..4086fb69 100644 --- a/src/Interfaces/EmbeddedFacetDiscretizations.jl +++ b/src/Interfaces/EmbeddedFacetDiscretizations.jl @@ -1,5 +1,5 @@ -struct EmbeddedFacetDiscretization{Dc,Dp,T} <: AbstractEmbeddedDiscretization{Dc,Dp} +struct EmbeddedFacetDiscretization{Dc,Dp,T} <: AbstractEmbeddedDiscretization bgmodel::DiscreteModel{Dp,Dp} ls_to_facet_to_inoutcut::Vector{Vector{Int8}} subfacets::SubCellData{Dc,Dp,T} diff --git a/src/LevelSetCutters/CutTriangulations.jl b/src/LevelSetCutters/CutTriangulations.jl index f1bd1f69..17068706 100644 --- a/src/LevelSetCutters/CutTriangulations.jl +++ b/src/LevelSetCutters/CutTriangulations.jl @@ -149,10 +149,14 @@ function cut_sub_triangulation(m::CutTriangulation, mpoint_to_value) end function count_sub_triangulation(m,mpoint_to_value) - n_scells = 0 - n_spoints = 0 mcell_to_mpoints = get_cell_to_points(m) table = get_lookup_table(m) + count_sub_triangulation(table,mcell_to_mpoints,mpoint_to_value) +end + +function count_sub_triangulation(table,mcell_to_mpoints,mpoint_to_value) + n_scells = 0 + n_spoints = 0 for mcell in 1:length(mcell_to_mpoints) case = compute_case(mcell_to_mpoints,mpoint_to_value,mcell) n_scells += length(table.case_to_subcell_to_inout[case]) @@ -444,24 +448,18 @@ end function initial_sub_triangulation(grid::Grid,geom::DiscreteGeometry) ugrid = UnstructuredGrid(grid) - tree = get_tree(geom) - ls_to_point_to_value, oid_to_ls = _find_unique_leaves(tree) + ls_to_point_to_value, oid_to_ls = _find_unique_leaves(get_tree(geom)) out = _initial_sub_triangulation(ugrid,ls_to_point_to_value) out[1], out[2], out[3], oid_to_ls end function _initial_sub_triangulation(grid::UnstructuredGrid,ls_to_point_to_value) - cutgrid, ls_to_cutpoint_to_value, ls_to_bgcell_to_inoutcut = _extract_grid_of_cut_cells(grid,ls_to_point_to_value) - subtrian, ls_to_subpoint_to_value = _simplexify_and_isolate_cells_in_cutgrid(cutgrid,ls_to_cutpoint_to_value) - - subtrian, ls_to_subpoint_to_value, ls_to_bgcell_to_inoutcut + return subtrian, ls_to_subpoint_to_value, ls_to_bgcell_to_inoutcut end function _extract_grid_of_cut_cells(grid,ls_to_point_to_value) - - p = _check_and_get_polytope(grid) table = LookupTable(p) cell_to_points = get_cell_node_ids(grid) @@ -682,4 +680,4 @@ function _ensure_positive_jacobians_facets_work!(tcell_to_tpoints,c1,c2,tjac_q, tcell_to_tpoints.data[p+2] = p1 end end -end \ No newline at end of file +end From c305cfb6099d875cd0d6d4396e56af2a17564437 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Wed, 5 Mar 2025 09:33:21 +1100 Subject: [PATCH 30/74] Update CI actions --- .github/dependabot.yml | 7 ++++++ .github/workflows/ci.yml | 49 +++++++++------------------------------- 2 files changed, 18 insertions(+), 38 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d60f0707 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "monthly" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f316fd1c..441df67b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,21 +14,12 @@ jobs: arch: - x64 steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 @@ -48,21 +39,12 @@ jobs: arch: - x64 steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - run: | julia --color=yes --project=. --check-bounds=yes --depwarn=error -e ' @@ -83,21 +65,12 @@ jobs: arch: - x64 steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - run: | julia --color=yes --project=. --check-bounds=yes --depwarn=error -e ' @@ -109,8 +82,8 @@ jobs: name: Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: '1.8' - run: | From 28d4404efe000407be018af9fbc36ab9b5186620 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Wed, 5 Mar 2025 09:37:52 +1100 Subject: [PATCH 31/74] Update x86 CI actions --- .github/workflows/ci_x86.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci_x86.yml b/.github/workflows/ci_x86.yml index 03ca2ab1..4415f5a5 100644 --- a/.github/workflows/ci_x86.yml +++ b/.github/workflows/ci_x86.yml @@ -20,20 +20,11 @@ jobs: arch: - x86 steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 From 921a96c156ca0cc6338aa366102b00f8e84abe91 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Wed, 5 Mar 2025 14:57:06 +1100 Subject: [PATCH 32/74] Added temp dirs --- .github/workflows/ci.yml | 8 ++++---- test/AgFEMTests/PeriodicAgFEMSpacesTests.jl | 3 ++- test/AlgoimUtilsTests/VisualizationTests.jl | 5 +++-- test/DistributedTests/AggregationTests.jl | 9 ++++----- .../DistributedDiscreteGeometryPoissonTest.jl | 7 ++++--- .../DistributedLSDiscreteGeometryPoissonTest.jl | 7 ++++--- ...eriodicDistributedDiscreteGeometryPoissonTest.jl | 7 ++++--- test/DistributedTests/PoissonTests.jl | 7 ++++--- test/DistributedTests/mpi/runtests.jl | 10 +++++----- test/DistributedTests/testing_remote_no_aggs.jl | 13 +++++++------ .../EmbeddedBimaterialPoissonCutFEMTests.jl | 5 +++-- test/GridapEmbeddedTests/TraceFEMTests.jl | 2 -- 12 files changed, 44 insertions(+), 39 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 441df67b..d116b290 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: version: - - '1.8' + - '1.10' os: - ubuntu-latest arch: @@ -33,7 +33,7 @@ jobs: fail-fast: false matrix: version: - - '1.8' + - '1.10' os: - ubuntu-latest arch: @@ -59,7 +59,7 @@ jobs: fail-fast: false matrix: version: - - '1.8' + - '1.10' os: - ubuntu-latest arch: @@ -85,7 +85,7 @@ jobs: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2 with: - version: '1.8' + version: '1.10' - run: | julia --project=docs -e ' using Pkg diff --git a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl index 26b34bae..9627e598 100644 --- a/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl +++ b/test/AgFEMTests/PeriodicAgFEMSpacesTests.jl @@ -40,7 +40,8 @@ U = TrialFESpace(Vagg) v(x) = (x[1]-0.5)^2 + (x[2]-0.5)^2 vhagg = interpolate(v,Vagg) -writevtk(Ω_ac,"test",cellfields=["v"=>vhagg]) +path = mktempdir() +writevtk(Ω_ac,joinpath(path,"test"),cellfields=["v"=>vhagg]) tol = 10e-7 @test sum( ∫(abs2(v-vhagg))dΩ ) < tol diff --git a/test/AlgoimUtilsTests/VisualizationTests.jl b/test/AlgoimUtilsTests/VisualizationTests.jl index 91181789..d0b52930 100644 --- a/test/AlgoimUtilsTests/VisualizationTests.jl +++ b/test/AlgoimUtilsTests/VisualizationTests.jl @@ -37,7 +37,8 @@ module VisualizationTests vquad = Quadrature(algoim,phi,degree,phase=IN) _,dΩ = TriangulationAndMeasure(Ω,vquad) - writevtk(dΓ,"res_sur",cellfields=["f"=>fₕ],qhulltype=convexhull) - writevtk([dΩ,dΓ],"res_vol",cellfields=["f"=>fₕ]) + path = mktempdir() + writevtk(dΓ,joinpath(path,"res_sur"),cellfields=["f"=>fₕ],qhulltype=convexhull) + writevtk([dΩ,dΓ],joinpath("res_vol"),cellfields=["f"=>fₕ]) end # module \ No newline at end of file diff --git a/test/DistributedTests/AggregationTests.jl b/test/DistributedTests/AggregationTests.jl index 0dff75cf..7175232b 100644 --- a/test/DistributedTests/AggregationTests.jl +++ b/test/DistributedTests/AggregationTests.jl @@ -38,8 +38,6 @@ bgf_to_ioc = compute_bgfacet_to_inoutcut(bgmodel,geo) Ω = Triangulation(cutgeo) -writevtk(Ω,"trian") - strategy = AggregateCutCellsByThreshold(1.0) aggregates,aggregate_owner,aggregate_neig = distributed_aggregate( strategy,cutgeo,geo,IN) @@ -74,9 +72,10 @@ end Ωin = Triangulation(cutgeo,IN) Γ = EmbeddedBoundary(cutgeo) -writevtk(Ωin,"trian_in") -writevtk(Γ,"bnd") -writevtk(Ωbg,"bgtrian",celldata= +path = mktempdir() +writevtk(Ωin,joinpath(path,"trian_in")) +writevtk(Γ,joinpath(path,"bnd")) +writevtk(Ωbg,joinpath(path,"bgtrian"),celldata= ["aggregate"=>oaggregates, "aggregate_owner"=>oaggregate_owner]) diff --git a/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl index 10a99591..9388124d 100644 --- a/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl +++ b/test/DistributedTests/DistributedDiscreteGeometryPoissonTest.jl @@ -98,15 +98,16 @@ function main(distribute,parts; map(Reindex(col),oid) end - writevtk(Ω_bg,"trian", + path = mktempdir() + writevtk(Ω_bg,joinpath(path,"trian"), celldata=[ "aggregate"=>own_aggregates, "color"=>own_colors, "gid"=>own_to_global(gids)])#, # cellfields=["uh"=>uh]) - writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) - writevtk(Γ,"trian_G") + writevtk(Ω,joinpath(path,"trian_O"),cellfields=["uh"=>uh]) + writevtk(Γ,joinpath(path,"trian_G")) @test el2/ul2 < 1.e-8 @test eh1/uh1 < 1.e-7 diff --git a/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl b/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl index 68bbf39f..d27d8f7c 100644 --- a/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl +++ b/test/DistributedTests/DistributedLSDiscreteGeometryPoissonTest.jl @@ -93,15 +93,16 @@ function main(distribute,parts; map(Reindex(col),oid) end - writevtk(Ω_bg,"trian", + path = mktempdir() + writevtk(Ω_bg,joinpath(path,"trian"), celldata=[ "aggregate"=>own_aggregates, "color"=>own_colors, "gid"=>own_to_global(gids)])#, # cellfields=["uh"=>uh]) - writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) - writevtk(Γ,"trian_G") + writevtk(Ω,joinpath(path,"trian_O"),cellfields=["uh"=>uh]) + writevtk(Γ,joinpath(path,"trian_G")) @test el2/ul2 < 1.e-8 @test eh1/uh1 < 1.e-7 diff --git a/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl index 26cde8c3..2c7de035 100644 --- a/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl +++ b/test/DistributedTests/PeriodicDistributedDiscreteGeometryPoissonTest.jl @@ -151,15 +151,16 @@ function main(distribute,parts; map(Reindex(col),oid) end - writevtk(Ω_bg,"trian", + path = mktempdir() + writevtk(Ω_bg,joinpath(path,"trian"), celldata=[ "aggregate"=>own_aggregates, "color"=>own_colors, "gid"=>own_to_global(gids)])#, # cellfields=["uh"=>uh]) - writevtk(Ω,"trian_O",cellfields=["uh"=>uh]) - writevtk(Γ,"trian_G") + writevtk(Ω,joinpath(path,"trian_O"),cellfields=["uh"=>uh]) + writevtk(Γ,joinpath(path,"trian_G")) @test el2/ul2 < 1.e-8 @test eh1/uh1 < 1.e-7 diff --git a/test/DistributedTests/PoissonTests.jl b/test/DistributedTests/PoissonTests.jl index feb6e9b2..d5ece5b9 100644 --- a/test/DistributedTests/PoissonTests.jl +++ b/test/DistributedTests/PoissonTests.jl @@ -96,15 +96,16 @@ function main(distribute,parts; map(Reindex(col),oid) end - writevtk(Ω_bg,"trian", + path = mktempdir() + writevtk(Ω_bg,joinpath(path,"trian"), celldata=[ "aggregate"=>own_aggregates, "color"=>own_colors, "gid"=>own_to_global(gids)])#, # cellfields=["uh"=>uh]) - writevtk(Ω,"trian_O",cellfields=["uh"=>uh,"eh"=>e]) - writevtk(Γ,"trian_G") + writevtk(Ω,joinpath(path,"trian_O"),cellfields=["uh"=>uh,"eh"=>e]) + writevtk(Γ,joinpath(path,"trian_G")) @test el2/ul2 < 1.e-8 @test eh1/uh1 < 1.e-7 diff --git a/test/DistributedTests/mpi/runtests.jl b/test/DistributedTests/mpi/runtests.jl index 4f2c40c9..44a1968b 100644 --- a/test/DistributedTests/mpi/runtests.jl +++ b/test/DistributedTests/mpi/runtests.jl @@ -6,8 +6,8 @@ using MPI #Sysimage sysimage=nothing if length(ARGS)==1 - @assert isfile(ARGS[1]) "$(ARGS[1]) must be a valid Julia sysimage file" - sysimage=ARGS[1] + @assert isfile(ARGS[1]) "$(ARGS[1]) must be a valid Julia sysimage file" + sysimage=ARGS[1] end mpidir = @__DIR__ @@ -17,10 +17,10 @@ repodir = joinpath(testdir,"..","..") function run_driver(procs,file,sysimage) mpiexec() do cmd if sysimage!=nothing - extra_args="-J$(sysimage)" - run(`$cmd -n $procs $(Base.julia_cmd()) $(extra_args) --project=$repodir $(joinpath(mpidir,file))`) + extra_args="-J$(sysimage)" + run(`$cmd -n $procs $(Base.julia_cmd()) $(extra_args) --project=$repodir $(joinpath(mpidir,file))`) else - run(`$cmd -n $procs $(Base.julia_cmd()) --project=$repodir $(joinpath(mpidir,file))`) + run(`$cmd -n $procs $(Base.julia_cmd()) --project=$repodir $(joinpath(mpidir,file))`) end @test true end diff --git a/test/DistributedTests/testing_remote_no_aggs.jl b/test/DistributedTests/testing_remote_no_aggs.jl index 87e5d1aa..0bee27bd 100644 --- a/test/DistributedTests/testing_remote_no_aggs.jl +++ b/test/DistributedTests/testing_remote_no_aggs.jl @@ -133,18 +133,19 @@ uh1 = h1(uh) Γ = EmbeddedBoundary(cutgeo) Ωbg = Triangulation(bgmodel) -writevtk(Ω,"trian"); -writevtk(Γ,"bnd"); -writevtk(Ωbg,"bg_trian"); -writevtk(Ω_act,"act_trian"); +path = mktempdir() +writevtk(Ω,joinpath(path,"trian")); +writevtk(Γ,joinpath(path,"bnd")); +writevtk(Ωbg,joinpath(path,"bg_trian")); +writevtk(Ω_act,joinpath(path,"act_trian")); -writevtk(Ω,"trian", +writevtk(Ω,joinpath(path,"trian"), cellfields=["uh"=>uh,"u"=>u,"e"=>e],); map(local_views(uh),local_views(bgmodel),ranks) do uh,m,p trian = Triangulation(m) - writevtk(trian,"ltrian_$p",cellfields=["uh"=>uh]) + writevtk(trian,joinpath(path,"ltrian_$p"),cellfields=["uh"=>uh]) end end # module diff --git a/test/GridapEmbeddedTests/EmbeddedBimaterialPoissonCutFEMTests.jl b/test/GridapEmbeddedTests/EmbeddedBimaterialPoissonCutFEMTests.jl index 3d3e718d..138857b5 100644 --- a/test/GridapEmbeddedTests/EmbeddedBimaterialPoissonCutFEMTests.jl +++ b/test/GridapEmbeddedTests/EmbeddedBimaterialPoissonCutFEMTests.jl @@ -103,10 +103,11 @@ uh1, uh2 = solve(op) uh = (uh1,uh2) # Postprocess +path = mktempdir() qh1 = α1*∇(uh1) qh2 = α2*∇(uh2) -writevtk(Ω1,"results1",cellfields=["uh"=>uh1,"qh"=>qh1]) -writevtk(Ω2,"results2",cellfields=["uh"=>uh2,"qh"=>qh2]) +writevtk(Ω1,joinpath(path,"results1"),cellfields=["uh"=>uh1,"qh"=>qh1]) +writevtk(Ω2,joinpath(path,"results2"),cellfields=["uh"=>uh2,"qh"=>qh2]) #writevtk(model1,"model1") #writevtk(model2,"model2") diff --git a/test/GridapEmbeddedTests/TraceFEMTests.jl b/test/GridapEmbeddedTests/TraceFEMTests.jl index 7953e8f0..0e46c7d2 100644 --- a/test/GridapEmbeddedTests/TraceFEMTests.jl +++ b/test/GridapEmbeddedTests/TraceFEMTests.jl @@ -26,8 +26,6 @@ cutgeom = cut(bgmodel,geom) Γ = EmbeddedBoundary(cutgeom,geom) Γg = GhostSkeleton(cutgeom,CUT,geom) -writevtk(Γg,"Γg") - order=1 V = TestFESpace(Ωc,ReferenceFE(lagrangian,Float64,order),conformity=:H1) U = TrialFESpace(V) From fd4893e4c11f80a452e270f83068e64e7725a288 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 04:32:19 +0000 Subject: [PATCH 33/74] Bump codecov/codecov-action from 1 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d116b290..c015fee3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v5 with: file: lcov.info drivers: From 7274c837eab42ffbaefb5e67e36d8d0d40881ae9 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Wed, 5 Mar 2025 15:35:53 +1100 Subject: [PATCH 34/74] Swapped LightGraphs for Graphs --- Project.toml | 4 ++-- src/AgFEM/AgFEM.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 08903581..f651a887 100644 --- a/Project.toml +++ b/Project.toml @@ -9,9 +9,9 @@ Algoim = "0eb9048c-21de-4c7a-bfac-056de1940b74" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" CxxWrap = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" +Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" Gridap = "56d4f2e9-7ea1-5844-9cf6-b9c51ca7ce8e" GridapDistributed = "f9701e48-63b3-45aa-9a63-9bc6c271f355" -LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" MiniQhull = "978d7f02-9e05-4691-894f-ae31a51d76ca" @@ -26,9 +26,9 @@ Algoim = "0.2.2" Combinatorics = "1" CxxWrap = "0.16" FillArrays = "0.10, 0.11, 0.12, 0.13, 1" +Graphs = "1.12.0" Gridap = "0.17, 0.18" GridapDistributed = "0.3, 0.4" -LightGraphs = "1.3.3" MPI = "0.20" MiniQhull = "0.1.0, 0.2, 0.3, 0.4" PartitionedArrays = "0.3.4" diff --git a/src/AgFEM/AgFEM.jl b/src/AgFEM/AgFEM.jl index 72fed372..187f1162 100644 --- a/src/AgFEM/AgFEM.jl +++ b/src/AgFEM/AgFEM.jl @@ -1,6 +1,6 @@ module AgFEM -using LightGraphs +using Graphs using LinearAlgebra using Gridap From be5d2f78fbe347c97b74400688105fbcf0514f7f Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 11:53:52 +1000 Subject: [PATCH 35/74] Bump julia version for x86 tests --- .github/workflows/ci_x86.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_x86.yml b/.github/workflows/ci_x86.yml index 4415f5a5..c3b5744c 100644 --- a/.github/workflows/ci_x86.yml +++ b/.github/workflows/ci_x86.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: version: - - '1.8' + - '1.10' os: - ubuntu-latest arch: From ed64edb792e29be8b9a97dab8adc0ce39a68471c Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 12:09:58 +1000 Subject: [PATCH 36/74] Updated NEWS.md --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 325955f8..e01661ba 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for distributed level-set geometries. Since PR[#99](https://github.com/gridap/GridapEmbedded.jl/pull/99). - Refactored the distributed code to allow for ghosted/unghosted geometries and triangulations. Since PR[#100](https://github.com/gridap/GridapEmbedded.jl/pull/100). +### Changed + +- Swapped `LightGraphs.jl` dependency to `Graphs.jl`, due to the former being deprecated. Since PR[#108](https://github.com/gridap/GridapEmbedded.jl/pull/108). + ## [0.9.5] - 2024-10-18 ### Added From 8b239144f52c53ce02a50972cca4681250b562be Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 15:50:21 +1000 Subject: [PATCH 37/74] Added compute_active_model for SubFacetTriangulations --- .../EmbeddedFacetDiscretizations.jl | 14 +++-- src/Interfaces/Interfaces.jl | 3 ++ src/Interfaces/SubFacetTriangulations.jl | 51 ++++++++++++++++--- .../EmbeddedFacetDiscretizationsTests.jl | 30 +++++++---- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/Interfaces/EmbeddedFacetDiscretizations.jl b/src/Interfaces/EmbeddedFacetDiscretizations.jl index 4086fb69..aff4d52a 100644 --- a/src/Interfaces/EmbeddedFacetDiscretizations.jl +++ b/src/Interfaces/EmbeddedFacetDiscretizations.jl @@ -126,10 +126,9 @@ function BoundaryTriangulation( in_or_out::Tuple, geo::CSG.Geometry) - trian1 = BoundaryTriangulation(facets,cut,in_or_out[1],geo) - trian2 = BoundaryTriangulation(facets,cut,in_or_out[2],geo) - num_cells(trian1) == 0 ? trian2 : lazy_append(trian1,trian2) - + a = BoundaryTriangulation(facets,cut,in_or_out[1],geo) + b = BoundaryTriangulation(facets,cut,in_or_out[2],geo) + iszero(num_cells(a)) ? b : lazy_append(a,b) end function BoundaryTriangulation( @@ -139,7 +138,7 @@ function BoundaryTriangulation( geo::CSG.Geometry) bgfacet_to_inoutcut = compute_bgfacet_to_inoutcut(cut,geo) - bgfacet_to_mask = lazy_map( a->a==in_or_out, bgfacet_to_inoutcut) + bgfacet_to_mask = lazy_map(isequal(in_or_out), bgfacet_to_inoutcut) _restrict_boundary_triangulation(cut.bgmodel,facets,bgfacet_to_mask) end @@ -161,7 +160,7 @@ function BoundaryTriangulation( geo::CSG.Geometry) bgfacet_to_inoutcut = compute_bgfacet_to_inoutcut(cut,geo) - bgfacet_to_mask = lazy_map( a->a==CUT, bgfacet_to_inoutcut) + bgfacet_to_mask = lazy_map(isequal(CUT), bgfacet_to_inoutcut) facets = _restrict_boundary_triangulation(cut.bgmodel,_facets,bgfacet_to_mask) facet_to_bgfacet = facets.glue.face_to_bgface @@ -173,7 +172,7 @@ function BoundaryTriangulation( _subfacet_to_facet = lazy_map(Reindex(bgfacet_to_facet),cut.subfacets.cell_to_bgcell) subfacet_to_inout = compute_subfacet_to_inout(cut,geo) - pred(a,b,c) = c != 0 && a==CUT && b==in_or_out.in_or_out + pred(a,b,c) = !iszero(c) && a==CUT && b==in_or_out.in_or_out mask = lazy_map( pred, subfacet_to_inoutcut, subfacet_to_inout, _subfacet_to_facet ) newsubfacets = findall(mask) subfacets = SubCellData(cut.subfacets,newsubfacets) @@ -183,7 +182,6 @@ function BoundaryTriangulation( end function _restrict_boundary_triangulation(model,facets,bgfacet_to_mask) - facet_to_bgfacet = facets.glue.face_to_bgface facet_to_mask = lazy_map(Reindex(bgfacet_to_mask),facet_to_bgfacet) n_bgfacets = length(bgfacet_to_mask) diff --git a/src/Interfaces/Interfaces.jl b/src/Interfaces/Interfaces.jl index 8f351d66..93466bc6 100644 --- a/src/Interfaces/Interfaces.jl +++ b/src/Interfaces/Interfaces.jl @@ -1,5 +1,6 @@ module Interfaces +using Gridap using Gridap.Helpers using Gridap.Arrays using Gridap.Fields @@ -21,12 +22,14 @@ import Gridap.Geometry: get_reffes import Gridap.Geometry: get_cell_type import Gridap.Geometry: get_background_model import Gridap.Geometry: get_active_model +import Gridap.Geometry: compute_active_model import Gridap.Geometry: get_glue import Gridap.Geometry: get_grid import Gridap.Geometry: FaceToFaceGlue import Gridap.Geometry: get_facet_normal import Gridap.Geometry: move_contributions using Gridap.Geometry: GenericTriangulation +using Gridap.Geometry: CompositeTriangulation using GridapEmbedded.CSG diff --git a/src/Interfaces/SubFacetTriangulations.jl b/src/Interfaces/SubFacetTriangulations.jl index 39ae92e2..cad6d6c0 100644 --- a/src/Interfaces/SubFacetTriangulations.jl +++ b/src/Interfaces/SubFacetTriangulations.jl @@ -39,14 +39,6 @@ function get_background_model(a::SubFacetTriangulation) a.bgmodel end -function get_active_model(a::SubFacetTriangulation) - msg = """ - This is not implemented, but also not needed in practice. - Embedded Grids implemented for integration, not interpolation. - """ - @notimplemented msg -end - function get_grid(a::SubFacetTriangulation) a.subgrid end @@ -88,6 +80,49 @@ function move_contributions(scell_to_val::AbstractArray,strian::SubFacetTriangul acell_to_val, Ωa end +# Compute the active model +# To do this, we need to glue together the subfacets, which unfortunately requires comparing +# the point coordinates... +function compute_active_model(trian::SubFacetTriangulation) + subgrid = trian.subgrid + subfacets = trian.subfacets + facet_to_uids, uid_to_point = consistent_facet_to_points( + subfacets.facet_to_points, subfacets.point_to_coords + ) + topo = UnstructuredGridTopology( + subgrid, facet_to_uids, uid_to_point + ) + return UnstructuredDiscreteModel(subgrid,topo,FaceLabeling(topo)) +end + +function consistent_facet_to_points( + facet_to_points::Table, point_to_coords::Vector +) + f(pt::VectorValue) = VectorValue(round.(pt.data;sigdigits=12)) + f(id::Integer) = f(point_to_coords[id]) + + # Create a list of the unique points composing the facets + npts = length(point_to_coords) + nfaces = length(facet_to_points) + touched = zeros(Bool,npts) + for face in 1:nfaces + pts = view(facet_to_points,face) + touched[pts] .= true + end + touched_ids = findall(touched) + unique_ids = unique(f,touched_ids) + + # Create a mapping from the old point ids to the new ones + touched_to_uid = collect(Int32,indexin(f.(touched_ids),f.(unique_ids))) + point_to_uid = extend(touched_to_uid,PosNegPartition(touched_ids,npts)) + + facet_to_uids = Table( + collect(Int32,lazy_map(Reindex(point_to_uid),facet_to_points.data)), + facet_to_points.ptrs + ) + return facet_to_uids, unique_ids +end + # API function UnstructuredGrid(st::SubFacetData{Dp}) where Dp diff --git a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl index 7e6c9416..959f07b5 100644 --- a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl +++ b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl @@ -8,6 +8,9 @@ using Gridap.Geometry using GridapEmbedded.Interfaces using GridapEmbedded.LevelSetCutters +########################################## +# 2D tests + n = 10 partition = (n,n) domain = (0,1,0,1) @@ -37,6 +40,8 @@ u = interpolate(x->x[1]+x[2],V) Γ = lazy_append(Γu,Γf) Λ = SkeletonTriangulation(cutgeo_facets,PHYSICAL) +face_model = get_active_model(Γu) + test_triangulation(Ω) test_triangulation(Γ) test_triangulation(Λ) @@ -69,16 +74,20 @@ celldata_Λ = [ "bgcell_right"=>collect(Int,get_glue(Λ.⁻,Val(D)).tface_to_mface)] cellfields_Λ = ["normal"=> n_Λ.⁺,"jump_v"=>jump(v),"jump_u"=>jump(u)] -d = mktempdir() +d = "./dev"#mktempdir() try - writevtk(Ωbg,joinpath(d,"trian")) - writevtk(Ω,joinpath(d,"trian_O"),celldata=celldata_Ω,cellfields=cellfields_Ω) - writevtk(Γ,joinpath(d,"trian_G"),celldata=celldata_Γ,cellfields=cellfields_Γ) - writevtk(Λ,joinpath(d,"trian_sO"),celldata=celldata_Λ,cellfields=cellfields_Λ) + writevtk(Ωbg,joinpath(d,"trian"),append=false) + writevtk(Ω,joinpath(d,"trian_O"),celldata=celldata_Ω,cellfields=cellfields_Ω,append=false) + writevtk(Γ,joinpath(d,"trian_G"),celldata=celldata_Γ,cellfields=cellfields_Γ,append=false) + writevtk(Λ,joinpath(d,"trian_sO"),celldata=celldata_Λ,cellfields=cellfields_Λ,append=false) + writevtk(Γf,joinpath(d,"trian_Gf"),append=false) finally - rm(d,recursive=true) + #rm(d,recursive=true) end +########################################## +# 3D tests + n = 10 partition = (n,n,n) domain = (0,1,0,1,0,1) @@ -95,11 +104,14 @@ trian_s = SkeletonTriangulation(bgmodel) trian_sΩ = SkeletonTriangulation(trian_s,cutgeo_facets,PHYSICAL_IN,geo) trian_sΩo = SkeletonTriangulation(trian_s,cutgeo_facets,PHYSICAL_OUT,geo) +Γu = EmbeddedBoundary(cutgeo) +face_model = get_active_model(Γu) + d = mktempdir() try -writevtk(trian_s,joinpath(d,"trian_s")) -writevtk(trian_sΩ,joinpath(d,"trian_sO")) -writevtk(trian_sΩo,joinpath(d,"trian_sOo")) + writevtk(trian_s,joinpath(d,"trian_s")) + writevtk(trian_sΩ,joinpath(d,"trian_sO")) + writevtk(trian_sΩo,joinpath(d,"trian_sOo")) finally rm(d,recursive=true) end From 2bf31243e6f41a8ef4d11556fe53a316df537735 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 15:52:27 +1000 Subject: [PATCH 38/74] Fixed remove_ghost_cells for empty parts and AppendedTriangulations --- src/Distributed/DistributedDiscretizations.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index a49fd25c..5d873558 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -92,7 +92,9 @@ end function remove_ghost_cells(trian::AppendedTriangulation,gids) a = remove_ghost_cells(trian.a,gids) b = remove_ghost_cells(trian.b,gids) - lazy_append(a,b) + iszero(num_cells(a)) && return b + iszero(num_cells(b)) && return a + return lazy_append(a,b) end function remove_ghost_cells(trian::SubFacetTriangulation{Df,Dc},gids) where {Df,Dc} From 55715ec3d58d546ba3baebe2105151c682ce5dd5 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 16:45:20 +1000 Subject: [PATCH 39/74] Added CutFaceBoundaryTriangulations --- .../CutFaceBoundaryTriangulations.jl | 455 ++++++++++++++++++ .../EmbeddedFacetDiscretizations.jl | 15 + src/Interfaces/Interfaces.jl | 11 + .../EmbeddedFacetDiscretizationsTests.jl | 2 + 4 files changed, 483 insertions(+) create mode 100644 src/Interfaces/CutFaceBoundaryTriangulations.jl diff --git a/src/Interfaces/CutFaceBoundaryTriangulations.jl b/src/Interfaces/CutFaceBoundaryTriangulations.jl new file mode 100644 index 00000000..d30ada3a --- /dev/null +++ b/src/Interfaces/CutFaceBoundaryTriangulations.jl @@ -0,0 +1,455 @@ + +# Ghost triangulations + +function generate_ghost_trian( + trian::CompositeTriangulation, bgmodel +) + Dc = num_cell_dims(bgmodel) + cell_glue = get_glue(trian,Val(Dc)) + return generate_ghost_trian(trian,bgmodel,cell_glue) +end + +function generate_ghost_trian( + trian::CompositeTriangulation, bgmodel, cell_glue::SkeletonPair{<:FaceToFaceGlue} +) + Dc = num_cell_dims(bgmodel) + topo = get_grid_topology(bgmodel) + face_to_cell = get_faces(topo,Dc-1,Dc) + cell_to_face = get_faces(topo,Dc,Dc-1) + + n_bgfaces = num_faces(bgmodel,Dc-1) + n_faces = num_cells(trian) + ghost_faces = zeros(Int32,n_faces) + p_lcell = ones(Int8,n_bgfaces) + m_lcell = ones(Int8,n_bgfaces) + for (i,(p_cell, m_cell)) in enumerate(zip(cell_glue.plus.tface_to_mface,cell_glue.minus.tface_to_mface)) + inter = intersect(cell_to_face[p_cell],cell_to_face[m_cell]) + @assert length(inter) == 1 + face = first(inter) + ghost_faces[i] = face + + nbors = face_to_cell[ghost_faces[i]] + p_lcell[face] = findfirst(==(p_cell),nbors) + m_lcell[face] = findfirst(==(m_cell),nbors) + end + + plus = BoundaryTriangulation(bgmodel,ghost_faces,p_lcell) + minus = BoundaryTriangulation(bgmodel,ghost_faces,m_lcell) + return SkeletonTriangulation(plus,minus) +end + +function generate_ghost_trian( + trian::CompositeTriangulation, bgmodel, cell_glue::FaceToFaceGlue +) + Dc = num_cell_dims(bgmodel) + topo = get_grid_topology(bgmodel) + face_to_cell = get_faces(topo,Dc-1,Dc) + cell_to_face = get_faces(topo,Dc,Dc-1) + is_boundary(f) = isone(length(view(face_to_cell,f))) + + n_faces = num_cells(trian) + ghost_faces = zeros(Int32,n_faces) + for (i,cell) in enumerate(cell_glue.tface_to_mface) + faces = filter(is_boundary,view(cell_to_face,cell)) + @assert length(faces) == 1 # TODO: This will break if we are in a corner + face = first(faces) + ghost_faces[i] = face + end + + # NOTE: lcell is always 1 for boundary facets + return BoundaryTriangulation(bgmodel,ghost_faces) +end + +""" + get_ghost_mask( + face_trian::SubFacetTriangulation{Df,Dc}, + face_model = get_active_model(face_trian) + ) where {Df,Dc} + +Returns a mask for ghost faces. We define ghost faces as the interfaces between two +different cut facets that are located in different background cells. + +The second condition is important: In 3D, some cuts subcells may not be simplices. +In this case, we simplexify the subcell. This creates extra cut interfaces that are +interior to a background cell. These are not considered ghost faces. + +- In 2D: Dc = 2, Df = 1 -> Ghost faces have dimension 0 (i.e interface points) +- In 3D: Dc = 3, Df = 2 -> Ghost faces have dimension 1 (i.e interface edges) +""" +function get_ghost_mask( + face_trian::SubFacetTriangulation{Df,Dc}, + face_model = get_active_model(face_trian) +) where {Df,Dc} + topo = get_grid_topology(face_model) + face_to_facets = get_faces(topo,Df-1,Df) + + subfacets = face_trian.subfacets + facet_to_bgcell = subfacets.facet_to_bgcell + + n_faces = num_faces(topo,Df-1) + face_is_ghost = zeros(Bool,n_faces) + for face in 1:n_faces + facets = view(face_to_facets,face) + is_boundary = isone(length(facets)) + if !is_boundary + @assert length(facets) == 2 + bgcells = view(facet_to_bgcell,facets) + is_ghost = (bgcells[1] != bgcells[2]) + face_is_ghost[face] = is_ghost + end + end + + return face_is_ghost +end + +""" + struct CutFaceBoundaryTriangulation{Di,Df,Dp} <: Triangulation{Di,Dp} + +Triangulation containing the interfaces between subfacets. We always have dimensions + + - Dc :: Dimension of the background mesh + - Df = Dc-1 :: Dimension of the cut subfacets + - Di = Dc-2 :: Dimension of the subfacet interfaces + +Description of the different components: + +- `face_trian` :: Original SubFacetTriangulation, built on top of the background mesh. +- `face_model` :: Subfacet model. Active model for `face_trian`. +- `face_boundary` :: Triangulation of the interfaces between subfacets. It is glued to the `face_model`. +- `cell_boundary` :: Conceptually the same as `face_boundary`, but it is glued to the + background mesh cells. Created as a CompositeTriangulation between `face_trian` and `face_boundary`. +- `ghost_boundary` :: Triangulation of the background facets that contain each interface. + +The "real" triangulation is `cell_boundary`, but we require the other triangulations to +perform complex changes of domain. Most of the `Triangulation` API is delegated to `cell_boundary`. + +## Constructors + + Boundary(face_trian::SubFacetTriangulation) + Skeleton(face_trian::SubFacetTriangulation) + +""" +struct CutFaceBoundaryTriangulation{Di,Df,Dp} <: Triangulation{Di,Dp} + face_model :: UnstructuredDiscreteModel{Df,Dp} + face_trian :: SubFacetTriangulation{Df,Dp} # Cut Facet -> BG Cell + cell_boundary :: CompositeTriangulation{Di,Dp} # Interface -> BG Cell + face_boundary :: BoundaryTriangulation{Di,Dp} # Interface -> Cut Facet + ghost_boundary :: BoundaryTriangulation{Df,Dp} # Ghost Facet -> BG Cell + interface_sign :: AbstractArray{<:Number} +end + +function BoundaryTriangulation(face_trian::SubFacetTriangulation) + bgmodel = get_background_model(face_trian) + face_model = get_active_model(face_trian) + + face_boundary = BoundaryTriangulation(face_model) + cell_boundary = CompositeTriangulation(face_trian,face_boundary) + ghost_boundary = generate_ghost_trian(cell_boundary,bgmodel) + interface_sign = get_interface_sign(cell_boundary,face_trian,ghost_boundary) + + return CutFaceBoundaryTriangulation( + face_model,face_trian,cell_boundary,face_boundary,ghost_boundary,interface_sign + ) +end + +function get_background_model(t::CutFaceBoundaryTriangulation) + get_background_model(t.cell_boundary) +end + +function get_active_model(t::CutFaceBoundaryTriangulation) + get_active_model(t.cell_boundary) +end + +function get_grid(t::CutFaceBoundaryTriangulation) + get_grid(t.cell_boundary) +end + +# Domain changes + +function get_glue(ttrian::CutFaceBoundaryTriangulation{Di,Df,Dp},::Val{D}) where {D,Di,Df,Dp} + get_glue(ttrian.cell_boundary,Val(D)) +end + +function is_change_possible( + strian::SubFacetTriangulation,ttrian::CutFaceBoundaryTriangulation +) + return strian === ttrian.face_trian +end + +function CellData.change_domain( + a::CellField,ttrian::CutFaceBoundaryTriangulation,tdomain::DomainStyle +) + strian = get_triangulation(a) + if strian === ttrian + # 1) CellField defined on the skeleton + return change_domain(a,DomainStyle(a),tdomain) + end + + if is_change_possible(strian,ttrian.cell_boundary) + # 2) CellField defined on the bgmodel + b = change_domain(a,ttrian.cell_boundary,tdomain) + elseif strian === ttrian.face_trian + # 3) CellField defined on the cut facets + itrian = Triangulation(ttrian.face_model) + _a = CellData.similar_cell_field(a,CellData.get_data(a),itrian,DomainStyle(a)) + b = change_domain(_a,ttrian.face_boundary,tdomain) + else + @notimplemented + end + return CellData.similar_cell_field(b,CellData.get_data(b),ttrian,DomainStyle(b)) +end + +function CellData.change_domain( + f::CellData.OperationCellField,ttrian::CutFaceBoundaryTriangulation,tdomain::DomainStyle +) + args = map(i->change_domain(i,ttrian,tdomain),f.args) + CellData.OperationCellField(f.op,args...) +end + +# Normal vector to the cut facets , n_∂Ω +function get_subfacet_normal_vector(trian::CutFaceBoundaryTriangulation) + n_∂Ω = get_subfacet_facet_normal(trian.cell_boundary,trian.face_trian) + return GenericCellField(n_∂Ω,trian,ReferenceDomain()) +end + +# Normal vector to the ghost facets, n_k +function get_ghost_normal_vector(trian::CutFaceBoundaryTriangulation) + n = get_ghost_facet_normal(trian.cell_boundary,trian.ghost_boundary) + return GenericCellField(n,trian,ReferenceDomain()) +end + +# Orientation of the interface +function get_interface_sign(trian::CutFaceBoundaryTriangulation) + data = lazy_map(constant_field,trian.interface_sign) + return GenericCellField(data,trian,ReferenceDomain()) +end + +# TODO: This is only valid when dealing with linear meshes (where normals are constant over facets). +# If we wanted to use higher-order meshes, we would need to generate the geometric map +# going from the facets to the interfaces. +# However, having a high-order background mesh seems quite silly. +function get_ghost_facet_normal( + itrian::CompositeTriangulation{Di,Dc}, # Interface -> BG Cell + gtrian::BoundaryTriangulation{Df,Dc} # Ghost Facet -> BG Cell +) where {Di,Df,Dc} + n_g = get_facet_normal(gtrian) + n_i = lazy_map(evaluate,n_g,Fill(zero(VectorValue{Df,Float64}),num_cells(itrian))) + return lazy_map(constant_field,n_i) +end + +# This one would be fine for higher-order meshes. +function get_subfacet_facet_normal( + itrian::CompositeTriangulation{Di,Dc}, # Interface -> BG Cell + ftrian::SubFacetTriangulation{Df,Dc}, # Cut Facet -> BG Cell +) where {Di,Df,Dc} + glue = get_glue(itrian.dtrian,Val(Df)) + i_to_f_ids = glue.tface_to_mface + i_to_f_map = glue.tface_to_mface_map + n_f = lazy_map(Reindex(get_facet_normal(ftrian)),i_to_f_ids) + n_i = lazy_map(Broadcasting(∘),n_f,i_to_f_map) + return n_i +end + +# There is still something sweaty about this... +# Why do we apply the sign change but at the same time call `get_edge_tangents` in the +# creation of conormal vectors in 3D? It's like we are cancelling the sign change... +# There is more to think about here. +function get_interface_sign( + itrian::CompositeTriangulation{Di,Dc}, # Interface -> BG Cell + ftrian::SubFacetTriangulation{Df,Dc}, # Cut Facet -> BG Cell + gtrian::BoundaryTriangulation{Df,Dc}, # Ghost Facet -> BG Cell +) where {Di,Df,Dc} + function signdot(a,b) + s = sign(dot(a,b)) + return ifelse(iszero(s),1,s) + end + n_∂Ω = get_subfacet_facet_normal(itrian,ftrian) + n_k = get_ghost_facet_normal(itrian,gtrian) + if Di == 0 + cross2D(n) = VectorValue(-n[2],n[1]) + n_S = lazy_map(Operation(cross2D),n_k) + else + t_S = get_edge_tangents(itrian.dtrian) + n_S = lazy_map(Operation(cross),n_k,t_S) + end + sgn = lazy_map(Operation(signdot),n_∂Ω,n_S) + return collect(lazy_map(evaluate,sgn,Fill(zero(VectorValue{Di,Float64}),num_cells(itrian)))) +end + +function get_edge_tangents(trian::BoundaryTriangulation{1}) + function t(c) + @assert length(c) == 2 + t = c[2] - c[1] + return t/norm(t) + end + return lazy_map(constant_field,lazy_map(t,get_cell_coordinates(trian))) +end + +function get_edge_tangents(trian::CutFaceBoundaryTriangulation{1}) + data = get_edge_tangents(trian.face_boundary) + return GenericCellField(data,trian,ReferenceDomain()) +end + +# Normal vector to the cut interface, n_S +function get_normal_vector(trian::CutFaceBoundaryTriangulation{Di}) where {Di} + n_k = get_ghost_normal_vector(trian) + isign = get_interface_sign(trian) + if Di == 0 # 2D + cross2D(n) = VectorValue(-n[2],n[1]) + n_S = Operation(cross2D)(n_k) # nS = nk x tS and tS = ±e₃ in 2D + elseif Di == 1 # 3D + t_S = get_edge_tangents(trian) + n_S = Operation(cross)(n_k,t_S) # nk = tS x nS -> nS = nk x tS (eq 6.25) + else + @notimplemented + end + return n_S * isign +end + +get_facet_normal(trian::CutFaceBoundaryTriangulation) = get_data(get_normal_vector(trian)) + +# Tangent vector to the cut interface, t_S = n_S x n_k +function get_tangent_vector(trian::CutFaceBoundaryTriangulation{Di}) where {Di} + @notimplementedif Di != 1 + n_S = get_normal_vector(trian) + n_k = get_ghost_normal_vector(trian) + return Operation(cross)(n_S,n_k) +end + +# Conormal vectors, m_k = t_S x n_∂Ω +function get_conormal_vector(trian::CutFaceBoundaryTriangulation{Di}) where {Di} + n_∂Ω = get_subfacet_normal_vector(trian) + isign = get_interface_sign(trian) + if Di == 0 # 2D + cross2D(n) = VectorValue(n[2],-n[1]) + m_k = Operation(cross2D)(n_∂Ω) + elseif Di == 1 # 3D + t_S = get_edge_tangents(trian) + m_k = Operation(cross)(t_S,n_∂Ω) # m_k = t_S x n_∂Ω (eq 6.26) + else + @notimplemented + end + return m_k * isign +end + +# CutFaceSkeletonTriangulation & CutFaceBoundaryTriangulationView +const CutFaceBoundaryTriangulationView{Di,Df,Dp} = TriangulationView{Di,Dp,CutFaceBoundaryTriangulation{Di,Df,Dp}} +const CutFaceSkeletonTriangulation{Di,Df,Dp} = SkeletonTriangulation{Di,Dp,<:Union{ + CutFaceBoundaryTriangulation{Di,Df,Dp}, + CutFaceBoundaryTriangulationView{Di,Df,Dp} + } +} + +function SkeletonTriangulation(face_trian::SubFacetTriangulation) + bgmodel = get_background_model(face_trian) + face_model = get_active_model(face_trian) + + ghost_mask = get_ghost_mask(face_trian,face_model) + face_skeleton = SkeletonTriangulation(face_model,ghost_mask) + cell_skeleton = CompositeTriangulation(face_trian,face_skeleton) + ghost_skeleton = generate_ghost_trian(cell_skeleton,bgmodel) + + ctrian_plus = CompositeTriangulation(face_trian,face_skeleton.plus) + ctrian_minus = CompositeTriangulation(face_trian,face_skeleton.minus) + isign_plus = get_interface_sign(ctrian_plus,face_trian,ghost_skeleton.plus) + isign_minus = get_interface_sign(ctrian_plus,face_trian,ghost_skeleton.minus) + + plus = CutFaceBoundaryTriangulation( + face_model,face_trian,ctrian_plus, + face_skeleton.plus,ghost_skeleton.plus,isign_plus + ) + minus = CutFaceBoundaryTriangulation( + face_model,face_trian,ctrian_minus, + face_skeleton.minus,ghost_skeleton.minus,isign_minus + ) + return SkeletonTriangulation(plus,minus) +end + +for func in (:get_subfacet_normal_vector,:get_ghost_normal_vector,:get_conormal_vector) + @eval begin + function $func(trian::CutFaceSkeletonTriangulation) + plus = GenericCellField(CellData.get_data($func(trian.plus)),trian,ReferenceDomain()) + minus = GenericCellField(CellData.get_data($func(trian.minus)),trian,ReferenceDomain()) + return SkeletonPair(plus,minus) + end + end +end + +for func in (:get_normal_vector,:get_tangent_vector) + @eval begin + function $func(trian::CutFaceSkeletonTriangulation) + return GenericCellField(CellData.get_data($func(trian.plus)),trian,ReferenceDomain()) + end + end +end + +for func in (:get_tangent_vector,:get_subfacet_normal_vector,:get_ghost_normal_vector,:get_conormal_vector) + @eval begin + function $func(trian::CutFaceBoundaryTriangulationView) + data = CellData.get_data($func(trian.parent)) + restricted_data = restrict(data,trian.cell_to_parent_cell) + return GenericCellField(restricted_data,trian,ReferenceDomain()) + end + end +end + +# Distributed +# Until we merge, we need changes in +# - GridapDistributed#master +# - GridapEmbedded#distributed + +# function GridapDistributed.remove_ghost_cells( +# trian::Union{<:CutFaceBoundaryTriangulation,<:CutFaceSkeletonTriangulation},gids +# ) +# model = get_background_model(trian) +# Dm = num_cell_dims(model) +# glue = get_glue(trian,Val(Dm)) +# GridapDistributed.remove_ghost_cells(glue,trian,gids) +# end +# +# for func in (:get_subfacet_normal_vector,:get_ghost_normal_vector,:get_conormal_vector,:get_tangent_vector) +# @eval begin +# function $func(a::DistributedTriangulation) +# fields = map($func,local_views(a)) +# DistributedCellField(fields,a) +# end +# end +# end + +############################################################################################ +# This will go to Gridap + +function Arrays.evaluate!(cache,k::Operation,a::SkeletonPair{<:CellField}) + plus = k(a.plus) + minus = k(a.minus) + SkeletonPair(plus,minus) +end + +function Arrays.evaluate!(cache,k::Operation,a::SkeletonPair{<:CellField},b::SkeletonPair{<:CellField}) + plus = k(a.plus,b.plus) + minus = k(a.minus,b.minus) + SkeletonPair(plus,minus) +end + +import Gridap.TensorValues: inner, outer +import LinearAlgebra: dot +import Base: abs, *, +, -, / + +for op in (:/,) + @eval begin + ($op)(a::CellField,b::SkeletonPair{<:CellField}) = Operation($op)(a,b) + ($op)(a::SkeletonPair{<:CellField},b::CellField) = Operation($op)(a,b) + end +end + +for op in (:outer,:*,:dot,:/) + @eval begin + ($op)(a::SkeletonPair{<:CellField},b::SkeletonPair{<:CellField}) = Operation($op)(a,b) + end +end + +function CellData.change_domain(a::SkeletonPair, ::ReferenceDomain, ::PhysicalDomain) + plus = change_domain(a.plus,ReferenceDomain(),PhysicalDomain()) + minus = change_domain(a.minus,ReferenceDomain(),PhysicalDomain()) + return SkeletonPair(plus,minus) +end diff --git a/src/Interfaces/EmbeddedFacetDiscretizations.jl b/src/Interfaces/EmbeddedFacetDiscretizations.jl index aff4d52a..56ece473 100644 --- a/src/Interfaces/EmbeddedFacetDiscretizations.jl +++ b/src/Interfaces/EmbeddedFacetDiscretizations.jl @@ -223,6 +223,21 @@ function compute_subfacet_to_inout(cut::EmbeddedFacetDiscretization,geo::CSG.Geo compute_inoutcut(newtree) end +""" + struct SubFacetBoundaryTriangulation{Dc,Dp,T} <: Triangulation{Dc,Dp} + +Triangulation of cut facets from the background mesh, i.e each of the facets +in this triangulation is part of a background facet that has been cut by the geometry. + +This differs from the the `SubFacetTriangulation` in that the facets in the `SubFacetTriangulation` +are not cut background facets, but rather subfacets on the interior of a background cell. + +They result from calling `Boundary` or `Skeleton` on an `EmbeddedFacetDiscretization` object, +for instance: + + BoundaryTriangulation(cut::EmbeddedFacetDiscretization,in_or_out,geo;tags=nothing) + +""" struct SubFacetBoundaryTriangulation{Dc,Dp,T} <: Triangulation{Dc,Dp} facets::BoundaryTriangulation{Dc,Dp} subfacets::SubCellData{Dc,Dp,T} diff --git a/src/Interfaces/Interfaces.jl b/src/Interfaces/Interfaces.jl index 93466bc6..c46961dd 100644 --- a/src/Interfaces/Interfaces.jl +++ b/src/Interfaces/Interfaces.jl @@ -1,5 +1,7 @@ module Interfaces +using FillArrays + using Gridap using Gridap.Helpers using Gridap.Arrays @@ -28,8 +30,15 @@ import Gridap.Geometry: get_grid import Gridap.Geometry: FaceToFaceGlue import Gridap.Geometry: get_facet_normal import Gridap.Geometry: move_contributions +import Gridap.Geometry: is_change_possible using Gridap.Geometry: GenericTriangulation using Gridap.Geometry: CompositeTriangulation +using Gridap.Geometry: TriangulationView +using Gridap.Geometry: restrict + +import Gridap.CellData: get_normal_vector +import Gridap.CellData: get_tangent_vector +import Gridap.Geometry: get_facet_normal using GridapEmbedded.CSG @@ -87,6 +96,8 @@ include("EmbeddedDiscretizations.jl") include("EmbeddedFacetDiscretizations.jl") +include("CutFaceBoundaryTriangulations.jl") + include("Cutters.jl") function Simplex(p::Polytope) diff --git a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl index 959f07b5..bb51bcd3 100644 --- a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl +++ b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl @@ -41,6 +41,8 @@ u = interpolate(x->x[1]+x[2],V) Λ = SkeletonTriangulation(cutgeo_facets,PHYSICAL) face_model = get_active_model(Γu) +Σb = BoundaryTriangulation(Γu) +Σi = SkeletonTriangulation(Γu) test_triangulation(Ω) test_triangulation(Γ) From cb903a4410f2ecad7889b23cd22c2c9be186c0cf Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 16:46:29 +1000 Subject: [PATCH 40/74] Minor --- test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl index bb51bcd3..04e7f527 100644 --- a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl +++ b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl @@ -108,6 +108,8 @@ trian_sΩo = SkeletonTriangulation(trian_s,cutgeo_facets,PHYSICAL_OUT,geo) Γu = EmbeddedBoundary(cutgeo) face_model = get_active_model(Γu) +Σb = BoundaryTriangulation(Γu) +Σi = SkeletonTriangulation(Γu) d = mktempdir() try From 02c9f8a98d618e9b70e44e095775430ea9218c5c Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Mon, 14 Apr 2025 16:52:31 +1000 Subject: [PATCH 41/74] Added Differentiable triangulations --- .../DifferentiableTriangulations.jl | 540 ++++++++++++++++++ src/LevelSetCutters/LevelSetCutters.jl | 3 + 2 files changed, 543 insertions(+) create mode 100644 src/LevelSetCutters/DifferentiableTriangulations.jl diff --git a/src/LevelSetCutters/DifferentiableTriangulations.jl b/src/LevelSetCutters/DifferentiableTriangulations.jl new file mode 100644 index 00000000..226e7fa8 --- /dev/null +++ b/src/LevelSetCutters/DifferentiableTriangulations.jl @@ -0,0 +1,540 @@ + + +""" + mutable struct DifferentiableTriangulation{Dc,Dp} <: Triangulation{Dc,Dp} + +A DifferentiableTriangulation is a wrapper around an embedded triangulation +(i.e SubCellTriangulation or SubFacetTriangulation) implementing all the necessary +methods to compute derivatives w.r.t. deformations of the embedded mesh. + +To do so, it propagates dual numbers into the geometric maps mapping cut subcells/subfacets +to the background mesh. + +## Constructor: + + DifferentiableTriangulation(trian::Triangulation,fe_space::FESpace) + +where `trian` must be an embedded triangulation and `fe_space` is the `FESpace` where +the level-set function lives. + +""" +mutable struct DifferentiableTriangulation{Dc,Dp,A,B} <: Triangulation{Dc,Dp} + trian :: A + fe_space :: B + cell_values + caches + function DifferentiableTriangulation( + trian :: Triangulation{Dc,Dp}, + fe_space :: FESpace, + cell_values,caches + ) where {Dc,Dp} + A = typeof(trian) + B = typeof(fe_space) + new{Dc,Dp,A,B}(trian,fe_space,cell_values,caches) + end +end + +# Constructors + +DifferentiableTriangulation(trian::Triangulation,fe_space) = trian + +function DifferentiableTriangulation( + trian::Union{<:SubCellTriangulation,<:SubFacetTriangulation}, + fe_space::FESpace +) + caches = precompute_autodiff_caches(trian) + return DifferentiableTriangulation(trian,fe_space,nothing,caches) +end + +# Update cell values + +(t::DifferentiableTriangulation)(φh) = update_trian!(t,get_fe_space(φh),φh) + +update_trian!(trian::Triangulation,U,φh) = trian + +function update_trian!(trian::DifferentiableTriangulation,space::FESpace,φh) + (trian.fe_space !== space) && return trian + trian.cell_values = extract_dualized_cell_values(trian.trian,φh) + return trian +end + +function update_trian!(trian::DifferentiableTriangulation,::FESpace,::Nothing) + trian.cell_values = nothing + return trian +end + +# Autodiff + +function FESpaces._change_argument( + op,f,trian::DifferentiableTriangulation,uh +) + U = get_fe_space(uh) + function g(cell_u) + cf = CellField(U,cell_u) + update_trian!(trian,U,cf) + cell_grad = f(cf) + update_trian!(trian,U,nothing) # TODO: experimental + get_contribution(cell_grad,trian) + end + g +end + +function FESpaces._compute_cell_ids(uh,ttrian::DifferentiableTriangulation) + FESpaces._compute_cell_ids(uh,ttrian.trian) +end + +function Geometry.get_background_model(t::DifferentiableTriangulation) + get_background_model(t.trian) +end + +function Geometry.get_grid(t::DifferentiableTriangulation) + get_grid(t.trian) +end + +function Geometry.get_cell_reffe(t::DifferentiableTriangulation) + get_cell_reffe(t.trian) +end + +# TODO: Do we ever need to dualize the cell points? +# I think its not necessary, since all the dual numbers are propagated through the cellmaps... +# Also: The current version dualizes only the phys points... +# If we want to indeed dualize this, we should probably also dualize the ref points +# in the case where ttrian.trian is a SubCellTriangulation (but not in the case of a SubFacetTriangulation) +# Anyway, I don't think this matters for now... +function CellData.get_cell_points(ttrian::DifferentiableTriangulation) + pts = get_cell_points(ttrian.trian) + cell_ref_point = pts.cell_ref_point + if isnothing(ttrian.cell_values) || isempty(ttrian.cell_values) + cell_phys_point = pts.cell_phys_point + else + c = ttrian.caches + cell_phys_point = lazy_map( + DualizeCoordsMap(),c.face_to_coords,c.face_to_bgcoords, + ttrian.cell_values,c.face_to_edges,c.face_to_edge_lists + ) + end + return CellPoint(cell_ref_point, cell_phys_point, ttrian, DomainStyle(pts)) +end + +function Geometry.get_cell_map(ttrian::DifferentiableTriangulation) + if isnothing(ttrian.cell_values) || isempty(ttrian.cell_values) + return get_cell_map(ttrian.trian) + end + c = ttrian.caches + cell_values = ttrian.cell_values + cell_to_coords = lazy_map( + DualizeCoordsMap(),c.face_to_coords,c.face_to_bgcoords, + cell_values,c.face_to_edges,c.face_to_edge_lists + ) + cell_reffe = get_cell_reffe(ttrian) + cell_map = compute_cell_maps(cell_to_coords,cell_reffe) + return cell_map +end + +function face_normal(face_coords::Vector{<:Point},orientation::Int8) + n = face_normal(face_coords) + return n*orientation +end +function face_normal(face_coords::Vector{<:Point{2}}) + p1, p2 = face_coords[1:2] + LevelSetCutters._normal_vector(p2-p1) +end +function face_normal(face_coords::Vector{<:Point{3}}) + p1, p2, p3 = face_coords[1:3] + LevelSetCutters._normal_vector(p2-p1,p3-p1) +end + +function Geometry.get_facet_normal( + ttrian::DifferentiableTriangulation{Dc,Dp,<:SubFacetTriangulation} +) where {Dc,Dp} + if isnothing(ttrian.cell_values) || isempty(ttrian.cell_values) + return get_facet_normal(ttrian.trian) + end + c = ttrian.caches + cell_values = ttrian.cell_values + cell_to_coords = lazy_map( + DualizeCoordsMap(),c.face_to_coords,c.face_to_bgcoords, + cell_values,c.face_to_edges,c.face_to_edge_lists + ) + facet_normals = lazy_map(face_normal,cell_to_coords,c.orientations) + return lazy_map(constant_field,facet_normals) +end + +function Geometry.get_glue(ttrian::DifferentiableTriangulation,val::Val{D}) where {D} + glue = get_glue(ttrian.trian,val) + if isnothing(glue) || isnothing(ttrian.cell_values) || isempty(ttrian.cell_values) + return glue + end + + # New reference maps + c = ttrian.caches + cell_values = ttrian.cell_values + cell_to_rcoords = lazy_map( + DualizeCoordsMap(),c.face_to_rcoords,c.face_to_bgrcoords, + cell_values,c.face_to_edges,c.face_to_edge_lists + ) + cell_reffe = get_cell_reffe(ttrian) + ref_cell_map = compute_cell_maps(cell_to_rcoords,cell_reffe) + + return FaceToFaceGlue( + glue.tface_to_mface, + ref_cell_map, + glue.mface_to_tface, + ) +end + +function Geometry.is_change_possible( + strian::A,ttrian::DifferentiableTriangulation{Dc,Dp,A} +) where {Dc,Dp,A <: Union{SubCellTriangulation,SubFacetTriangulation}} + return strian === ttrian.trian +end + +function Geometry.best_target( + strian::A,ttrian::DifferentiableTriangulation{Dc,Dp,A} +) where {Dc,Dp,A <: Union{SubCellTriangulation,SubFacetTriangulation}} + return ttrian +end + +for tdomain in (:ReferenceDomain,:PhysicalDomain) + for sdomain in (:ReferenceDomain,:PhysicalDomain) + @eval begin + function CellData.change_domain( + a::CellField,strian::A,::$sdomain,ttrian::DifferentiableTriangulation{Dc,Dp,A},::$tdomain + ) where {Dc,Dp,A <: Union{SubCellTriangulation,SubFacetTriangulation}} + @assert is_change_possible(strian,ttrian) + b = change_domain(a,$(tdomain)()) + return CellData.similar_cell_field(a,CellData.get_data(b),ttrian,$(tdomain)()) + end + end + end +end + +function FESpaces.get_cell_fe_data(fun,f,ttrian::DifferentiableTriangulation) + FESpaces.get_cell_fe_data(fun,f,ttrian.trian) +end + +function compute_cell_maps(cell_coords,cell_reffes) + cell_shapefuns = lazy_map(get_shapefuns,cell_reffes) + default_cell_map = lazy_map(linear_combination,cell_coords,cell_shapefuns) + default_cell_grad = lazy_map(∇,default_cell_map) + cell_poly = lazy_map(get_polytope,cell_reffes) + cell_q0 = lazy_map(p->zero(first(get_vertex_coordinates(p))),cell_poly) + origins = lazy_map(evaluate,default_cell_map,cell_q0) + gradients = lazy_map(evaluate,default_cell_grad,cell_q0) + cell_map = lazy_map(Gridap.Fields.affine_map,gradients,origins) + return cell_map +end + +# DualizeCoordsMap + +struct DualizeCoordsMap <: Map end + +function Arrays.return_cache( + k::DualizeCoordsMap, + coords::Vector{<:Point{Dp,Tp}}, + bg_coords::Vector{<:Point{Dp,Tp}}, + values::Vector{Tv}, + edges::Vector{Int8}, + edge_list::Vector{Vector{Int8}} +) where {Dp,Tp,Tv} + T = Point{Dp,Tv} + return CachedArray(zeros(T, length(coords))) +end + +function Arrays.evaluate!( + cache, + k::DualizeCoordsMap, + coords::Vector{<:Point{Dp,Tp}}, + bg_coords::Vector{<:Point{Dp,Tp}}, + values::Vector{Tv}, + edges::Vector{Int8}, + edge_list::Vector{Vector{Int8}} +) where {Dp,Tp,Tv} + setsize!(cache,(length(coords),)) + new_coords = cache.array + for (i,e) in enumerate(edges) + if e == -1 + new_coords[i] = coords[i] + else + n1, n2 = edge_list[e] + q1, q2 = bg_coords[n1], bg_coords[n2] + v1, v2 = abs(values[n1]), abs(values[n2]) + λ = v1/(v1+v2) + new_coords[i] = q1 + λ*(q2-q1) + end + end + return new_coords +end + +""" + precompute_cut_edge_ids(rcoords,bg_rcoords,edge_list) + +Given + - `rcoords`: the node ref coordinates of the cut subcell/subfacet, + - `bg_rcoords`: the node ref coordinates of the background cell containing it, + - `edge_list`: the list of nodes defining each edge of the background cell, + +this function returns a vector that for each node of the cut subcell/subfacet contains + - `-1` if the node is also a node of the background cell, + - the id of the edge containing the node otherwise. +""" +function precompute_cut_edge_ids( + rcoords::Vector{<:Point{Dp,Tp}}, + bg_rcoords::Vector{<:Point{Dp,Tp}}, + edge_list::Vector{<:Vector{<:Integer}} +) where {Dp,Tp} + tol = 10*eps(Tp) + edges = Vector{Int8}(undef,length(rcoords)) + for (i,p) in enumerate(rcoords) + if any(q -> norm(q-p) < tol, bg_rcoords) + edges[i] = Int8(-1) + else + e = findfirst(edge -> belongs_to_edge(p,edge,bg_rcoords), edge_list) + edges[i] = Int8(e) + end + end + return edges +end + +function get_edge_list(poly::Polytope) + ltcell_to_lpoints, simplex = simplexify(poly) + simplex_edges = get_faces(simplex,1,0) + ltcell_to_edges = map(pts -> map(e -> pts[e], simplex_edges), ltcell_to_lpoints) + return collect(Vector{Int8},unique(sort,vcat(ltcell_to_edges...))) +end + +function belongs_to_edge( + p::Point{D,T},edge::Vector{<:Integer},bgpts::Vector{Point{D,T}} +) where {D,T} + tol = 10*eps(T) + p1, p2 = bgpts[edge] + return norm(cross(p-p1,p2-p1)) < tol +end + +function precompute_autodiff_caches( + trian::SubCellTriangulation +) + bgmodel = get_background_model(trian) + subcells = trian.subcells + + precompute_autodiff_caches( + bgmodel, + subcells.cell_to_bgcell, + subcells.cell_to_points, + subcells.point_to_rcoords, + subcells.point_to_coords, + ) +end + +function precompute_autodiff_caches( + trian::SubFacetTriangulation +) + bgmodel = get_background_model(trian) + subfacets = trian.subfacets + + caches = precompute_autodiff_caches( + bgmodel, + subfacets.facet_to_bgcell, + subfacets.facet_to_points, + subfacets.point_to_rcoords, + subfacets.point_to_coords, + ) + + # Precompute orientations + orientations = collect(lazy_map(orient,subfacets.facet_to_normal,caches.face_to_coords)) + + cache = (; caches..., orientations) + return cache +end + +orient(n,fcoords) = round(Int8,dot(n,face_normal(fcoords))) +Arrays.return_value(::typeof(orient),n,face_coords) = zero(Int8) + +function precompute_autodiff_caches( + bgmodel, + face_to_bgcell, + face_to_points, + point_to_rcoords, + point_to_coords, +) + bg_ctypes = get_cell_type(bgmodel) + bgcell_to_polys = expand_cell_data(get_polytopes(bgmodel),bg_ctypes) + bgcell_to_coords = get_cell_coordinates(bgmodel) + bgcell_to_rcoords = lazy_map(get_vertex_coordinates,bgcell_to_polys) + + face_to_bgcoords = lazy_map(Reindex(bgcell_to_coords),face_to_bgcell) + face_to_bgrcoords = lazy_map(Reindex(bgcell_to_rcoords),face_to_bgcell) + face_to_rcoords = lazy_map(Broadcasting(Reindex(point_to_rcoords)),face_to_points) + face_to_coords = lazy_map(Broadcasting(Reindex(point_to_coords)),face_to_points) + + bgcell_to_edge_lists = lazy_map(get_edge_list,bgcell_to_polys) + face_to_edge_lists = lazy_map(Reindex(bgcell_to_edge_lists),face_to_bgcell) + face_to_edges = collect(lazy_map(precompute_cut_edge_ids,face_to_rcoords,face_to_bgrcoords,face_to_edge_lists)) + + cache = (; + face_to_rcoords, + face_to_coords, + face_to_bgrcoords, + face_to_bgcoords, + face_to_edges, + face_to_edge_lists + ) + return cache +end + +function extract_dualized_cell_values( + trian::SubCellTriangulation, + φh::CellField, +) + @assert isa(DomainStyle(φh),ReferenceDomain) + bgmodel = get_background_model(trian) + bgcell_to_values = extract_dualized_cell_values(bgmodel,φh) + + subcells = trian.subcells + cell_to_bgcell = subcells.cell_to_bgcell + cell_to_values = lazy_map(Reindex(bgcell_to_values),cell_to_bgcell) + return cell_to_values +end + +function extract_dualized_cell_values( + trian::SubFacetTriangulation, + φh::CellField, +) + @assert isa(DomainStyle(φh),ReferenceDomain) + bgmodel = get_background_model(trian) + bgcell_to_values = extract_dualized_cell_values(bgmodel,φh) + + subfacets = trian.subfacets + facet_to_bgcell = subfacets.facet_to_bgcell + facet_to_values = lazy_map(Reindex(bgcell_to_values),facet_to_bgcell) + return facet_to_values +end + +function extract_dualized_cell_values( + bgmodel::DiscreteModel, + φh::CellField, +) + @assert isa(DomainStyle(φh),ReferenceDomain) + bg_ctypes = get_cell_type(bgmodel) + bgcell_to_polys = expand_cell_data(get_polytopes(bgmodel),bg_ctypes) + bgcell_to_rcoords = lazy_map(get_vertex_coordinates,bgcell_to_polys) + bgcell_to_fields = CellData.get_data(φh) + bgcell_to_values = lazy_map(evaluate,bgcell_to_fields,bgcell_to_rcoords) + return bgcell_to_values +end + +# AppendedTriangulation +# +# When cutting an embedded domain, we will usually end up with an AppendedTriangulation +# containing +# a) a regular triangulation with the IN/OUT cells +# b) a SubCell/SubFacetTriangulation with the CUT cells +# We only need to propagate the dual numbers to the CUT cells, which is what the +# following implementation does: + +const DifferentiableAppendedTriangulation{Dc,Dp,A} = AppendedTriangulation{Dc,Dp,<:DifferentiableTriangulation} + +function DifferentiableTriangulation( + trian::AppendedTriangulation, fe_space::FESpace +) + a = DifferentiableTriangulation(trian.a,fe_space) + b = DifferentiableTriangulation(trian.b,fe_space) + return AppendedTriangulation(a,b) +end + +function update_trian!(trian::DifferentiableAppendedTriangulation,U,φh) + update_trian!(trian.a,U,φh) + update_trian!(trian.b,U,φh) + return trian +end + +function FESpaces._change_argument( + op,f,trian::DifferentiableAppendedTriangulation,uh +) + U = get_fe_space(uh) + function g(cell_u) + cf = CellField(U,cell_u) + update_trian!(trian,U,cf) + cell_grad = f(cf) + update_trian!(trian,U,nothing) + get_contribution(cell_grad,trian) + end + g +end + +# TODO: Move to Gridap +function FESpaces._compute_cell_ids(uh,ttrian::AppendedTriangulation) + ids_a = FESpaces._compute_cell_ids(uh,ttrian.a) + ids_b = FESpaces._compute_cell_ids(uh,ttrian.b) + lazy_append(ids_a,ids_b) +end + +# TriangulationView +# This is mostly used in distributed, where we remove ghost cells by taking a view +# of the local triangulations. + +function DifferentiableTriangulation( + trian :: Geometry.TriangulationView, + fe_space :: FESpace +) + parent = DifferentiableTriangulation(trian.parent,fe_space) + return Geometry.TriangulationView(parent,trian.cell_to_parent_cell) +end + +function update_trian!(trian::Geometry.TriangulationView,U,φh) + update_trian!(trian.parent,U,φh) + return trian +end + +function FESpaces._change_argument( + op,f,trian::Geometry.TriangulationView,uh +) + U = get_fe_space(uh) + function g(cell_u) + cf = CellField(U,cell_u) + update_trian!(trian,U,cf) + cell_grad = f(cf) + update_trian!(trian,U,nothing) + get_contribution(cell_grad,trian) + end + g +end + +#### DistributedTriangulations + +# function DifferentiableTriangulation(trian::DistributedTriangulation,fe_space) +# model = get_background_model(trian) +# trians = map(DifferentiableTriangulation,local_views(trian),local_views(fe_space)) +# return DistributedTriangulation(trians,model) +# end +# +# function FESpaces._change_argument( +# op,f, +# local_trians::AbstractArray{<:Union{<:DifferentiableTriangulation,<:DifferentiableAppendedTriangulation,<:TriangulationView}}, +# uh::GridapDistributed.DistributedADTypes +# ) +# function dist_cf(uh::DistributedCellField,cfs) +# DistributedCellField(cfs,get_triangulation(uh)) +# end +# function dist_cf(uh::DistributedMultiFieldCellField,cfs) +# sf_cfs = map(DistributedCellField, +# [tuple_of_arrays(map(cf -> Tuple(cf.single_fields),cfs))...], +# map(get_triangulation,uh) +# ) +# DistributedMultiFieldCellField(sf_cfs,cfs) +# end +# +# uhs = local_views(uh) +# spaces = map(get_fe_space,uhs) +# function g(cell_u) +# cfs = map(CellField,spaces,cell_u) +# cf = dist_cf(uh,cfs) +# map(update_trian!,local_trians,spaces,local_views(cf)) +# cg = f(cf) +# map(local_trians,spaces) do Ω, V +# update_trian!(Ω,V,nothing) +# end +# map(get_contribution,local_views(cg),local_trians) +# end +# g +# end diff --git a/src/LevelSetCutters/LevelSetCutters.jl b/src/LevelSetCutters/LevelSetCutters.jl index ac7caf57..5b6e0f7c 100644 --- a/src/LevelSetCutters/LevelSetCutters.jl +++ b/src/LevelSetCutters/LevelSetCutters.jl @@ -15,6 +15,7 @@ import GridapEmbedded.Interfaces: compute_bgfacet_to_inoutcut using GridapEmbedded.Interfaces: Simplex using GridapEmbedded.Interfaces: merge_sub_face_data using GridapEmbedded.Interfaces: compute_inoutcut +using GridapEmbedded.Interfaces: SubCellTriangulation, SubFacetTriangulation using LinearAlgebra using MiniQhull @@ -55,6 +56,8 @@ include("LookupTables.jl") include("CutTriangulations.jl") +include("DifferentiableTriangulations.jl") + struct LevelSetCutter <: Cutter end function cut(cutter::LevelSetCutter,background::DiscreteModel,geom) From a2f88679d0291f2f03b1c6838fe91f2b23d2eabb Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 17 Apr 2025 16:20:47 +1000 Subject: [PATCH 42/74] Added Geometrical differentiation tests --- Project.toml | 6 +- .../DifferentiableTriangulations.jl | 2 +- .../GeometricalDifferentiationTests.jl | 513 ++++++++++++++++++ test/LevelSetCuttersTests/runtests.jl | 2 + 4 files changed, 521 insertions(+), 2 deletions(-) create mode 100644 test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl diff --git a/Project.toml b/Project.toml index f651a887..a020b212 100644 --- a/Project.toml +++ b/Project.toml @@ -9,6 +9,7 @@ Algoim = "0eb9048c-21de-4c7a-bfac-056de1940b74" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" CxxWrap = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" Gridap = "56d4f2e9-7ea1-5844-9cf6-b9c51ca7ce8e" GridapDistributed = "f9701e48-63b3-45aa-9a63-9bc6c271f355" @@ -26,6 +27,8 @@ Algoim = "0.2.2" Combinatorics = "1" CxxWrap = "0.16" FillArrays = "0.10, 0.11, 0.12, 0.13, 1" +FiniteDiff = "2.27.0" +ForwardDiff = "0.10.38" Graphs = "1.12.0" Gridap = "0.17, 0.18" GridapDistributed = "0.3, 0.4" @@ -35,7 +38,8 @@ PartitionedArrays = "0.3.4" julia = "1.3" [extras] +FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["Test","FiniteDiff"] diff --git a/src/LevelSetCutters/DifferentiableTriangulations.jl b/src/LevelSetCutters/DifferentiableTriangulations.jl index 226e7fa8..74e39dbe 100644 --- a/src/LevelSetCutters/DifferentiableTriangulations.jl +++ b/src/LevelSetCutters/DifferentiableTriangulations.jl @@ -221,7 +221,7 @@ function compute_cell_maps(cell_coords,cell_reffes) cell_q0 = lazy_map(p->zero(first(get_vertex_coordinates(p))),cell_poly) origins = lazy_map(evaluate,default_cell_map,cell_q0) gradients = lazy_map(evaluate,default_cell_grad,cell_q0) - cell_map = lazy_map(Gridap.Fields.affine_map,gradients,origins) + cell_map = lazy_map(Fields.affine_map,gradients,origins) return cell_map end diff --git a/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl b/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl new file mode 100644 index 00000000..721f4623 --- /dev/null +++ b/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl @@ -0,0 +1,513 @@ +module GeometricalDifferentiationTests +############################################################################################ +# These tests are meant to verify the correctness differentiation of functionals w.r.t the +# level set defining the cut domain. +# They are based on the following work: +# "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation" +# by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis, CMAME (2025) +############################################################################################ +using Test, FiniteDiff + +using Gridap, Gridap.Geometry, Gridap.Adaptivity, Gridap.Arrays +using GridapEmbedded, GridapEmbedded.LevelSetCutters, GridapEmbedded.Interfaces + +using GridapEmbedded.Interfaces: get_conormal_vector +using GridapEmbedded.Interfaces: get_subfacet_normal_vector +using GridapEmbedded.Interfaces: get_ghost_normal_vector + +using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation + + +using Gridap.Fields, Gridap.Polynomials +function Arrays.return_cache( + fg::Fields.FieldGradientArray{1,Polynomials.MonomialBasis{D,V}}, + x::AbstractVector{<:Point}) where {D,V} + xi = testitem(x) + T = gradient_type(V,xi) + Polynomials._return_cache(fg,x,T,Val(false)) +end + +function Arrays.evaluate!( + cache, + fg::Fields.FieldGradientArray{1,Polynomials.MonomialBasis{D,V}}, + x::AbstractVector{<:Point}) where {D,V} + Polynomials._evaluate!(cache,fg,x,Val(false)) +end + +# We general a simplicial model where the simplices are created in a symmetric way using +# varycentric refinement of QUADs and HEXs. +function generate_model(D,n) + domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1) + cell_partition = (D==2) ? (n,n) : (n,n,n) + base_model = UnstructuredDiscreteModel((CartesianDiscreteModel(domain,cell_partition))) + ref_model = refine(base_model, refinement_method = "barycentric") + model = ref_model.model + return model +end + +function level_set(shape::Symbol;N=4) + if shape == :square + x -> max(abs(x[1]-0.5),abs(x[2]-0.5))-0.25 # Square + elseif shape == :corner_2d + x -> ((x[1]-0.5)^N+(x[2]-0.5)^N)^(1/N)-0.25 # Curved corner + elseif shape == :diamond + x -> abs(x[1]-0.5)+abs(x[2]-0.5)-0.25-0/n/10 # Diamond + elseif shape == :circle + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.5223 # Circle + elseif shape == :circle_2 + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.23 # Circle + elseif shape == :square_prism + x -> max(abs(x[1]-0.5),abs(x[2]-0.5),abs(x[3]-0.5))-0.25 # Square prism + elseif shape == :corner_3d + x -> ((x[1]-0.5)^N+(x[2]-0.5)^N+(x[3]-0.5)^N)^(1/N)-0.25 # Curved corner + elseif shape == :diamond_prism + x -> abs(x[1]-0.5)+abs(x[2]-0.5)+abs(x[3]-0.5)-0.25-0/n/10 # Diamond prism + elseif shape == :sphere + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2+(x[3]-0.5)^2)-0.53 # Sphere + elseif shape == :sphere_2 + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2+(x[3]-0.5)^2)-0.23 # Sphere + elseif shape == :regular_2d + x -> cos(2π*x[1])*cos(2π*x[2])-0.11 # "Regular" LSF + elseif shape == :regular_3d + x -> cos(2π*x[1])*cos(2π*x[2])*cos(2π*x[3])-0.11 # "Regular" LSF + else + error("Unknown shape") + end +end + +function main( + model,ls::Function,f::Function; + vtk=false, + name="embedded", + verbose=false, + fdm=false +) + order = 1 + reffe = ReferenceFE(lagrangian,Float64,order) + V_φ = TestFESpace(model,reffe) + + U = TestFESpace(model,reffe) + + φh = interpolate(ls,V_φ) + fh = interpolate(f,V_φ) + uh = interpolate(x->x[1]+x[2],U) + + # Correction if level set is on top of a node + x_φ = get_free_dof_values(φh) + idx = findall(isapprox(0.0;atol=10^-10),x_φ) + !isempty(idx) && @info "Correcting level values!" + x_φ[idx] .+= 100*eps(eltype(x_φ)) + + geo = DiscreteGeometry(φh,model) + cutgeo = cut(model,geo) + + # A.1) Volume integral + + Ω = Triangulation(cutgeo,PHYSICAL_IN) + Ω_AD = DifferentiableTriangulation(Ω,V_φ) + dΩ = Measure(Ω_AD,2*order) + + Γ = EmbeddedBoundary(cutgeo) + n_Γ = get_normal_vector(Γ) + dΓ = Measure(Γ,2*order) + + J_bulk(φ) = ∫(fh)dΩ + dJ_bulk_AD = gradient(J_bulk,φh) + dJ_bulk_AD_vec = assemble_vector(dJ_bulk_AD,V_φ) + + dJ_bulk_exact(q) = ∫(-fh*q/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_exact_vec = assemble_vector(dJ_bulk_exact,V_φ) + + abs_error = norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec,Inf) + + if fdm + function J_fdm_bulk(φ) + φh = FEFunction(V_φ,φ) + cutgeo = cut(model,DiscreteGeometry(φh,model)) + Ω = Triangulation(cutgeo,PHYSICAL_IN) + dΩ = Measure(Ω,2*order) + sum(∫(fh)dΩ) + end + dJ_FD = FiniteDiff.finite_difference_gradient(J_fdm_bulk,get_free_dof_values(φh)) + + abs_error_fdm = norm(dJ_bulk_AD_vec - dJ_FD,Inf) + end + + if verbose + println("A.1) Volume integral:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error) + fdm && println(" - norm(dJ_AD - dJ_FDM,Inf) = ",abs_error_fdm) + end + + @test abs_error < 1e-10 + + # A.1.1) Volume integral with another field + + J_bulk_1(u,φ) = ∫(u+fh)dΩ + dJ_bulk_1_AD = gradient(φ->J_bulk_1(uh,φ),φh) + dJ_bulk_1_AD_vec = assemble_vector(dJ_bulk_1_AD,V_φ) + + dJ_bulk_1_exact(q,u) = ∫(-(u+fh)*q/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_1_exact_vec = assemble_vector(q->dJ_bulk_1_exact(q,uh),V_φ) + @test norm(dJ_bulk_1_AD_vec - dJ_bulk_1_exact_vec) < 1e-10 + + dJ_bulk_1_AD_in_u = gradient(u->J_bulk_1(u,φh),uh) + dJ_bulk_1_AD_in_u_vec = assemble_vector(dJ_bulk_1_AD_in_u,U) + dJ_bulk_1_exact_in_u(q,u) = ∫(q)dΩ + dJ_bulk_1_exact_in_u_vec = assemble_vector(q->dJ_bulk_1_exact_in_u(q,uh),U) + + abs_error = norm(dJ_bulk_1_AD_in_u_vec - dJ_bulk_1_exact_in_u_vec,Inf) + if verbose + println("A.1.1) Volume integral with another field:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error) + end + @test abs_error < 1e-10 + + # A.2) Volume integral + + g(fh) = ∇(fh)⋅∇(fh) + J_bulk2(φ) = ∫(g(fh))dΩ + dJ_bulk_AD2 = gradient(J_bulk2,φh) + dJ_bulk_AD_vec2 = assemble_vector(dJ_bulk_AD2,V_φ) + + dJ_bulk_exact2(q) = ∫(-g(fh)*q/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_exact_vec2 = assemble_vector(dJ_bulk_exact2,V_φ) + + abs_error = norm(dJ_bulk_AD_vec2 - dJ_bulk_exact_vec2,Inf) + + if verbose + println("A.2) Volume integral with grad of fields:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error) + end + + @test abs_error < 1e-10 + + # B.1) Facet integral + + Γ = EmbeddedBoundary(cutgeo) + Γ_AD = DifferentiableTriangulation(Γ,V_φ) + Λ = Skeleton(Γ) + Σ = Boundary(Γ) + + dΓ = Measure(Γ,2*order) + dΛ = Measure(Λ,2*order) + dΣ = Measure(Σ,2*order) + + n_Γ = get_normal_vector(Γ) + + n_S_Λ = get_normal_vector(Λ) + m_k_Λ = get_conormal_vector(Λ) + ∇ˢφ_Λ = Operation(abs)(n_S_Λ ⋅ ∇(φh).plus) + + n_S_Σ = get_normal_vector(Σ) + m_k_Σ = get_conormal_vector(Σ) + ∇ˢφ_Σ = Operation(abs)(n_S_Σ ⋅ ∇(φh)) + + dΓ_AD = Measure(Γ_AD,2*order) + J_int(φ) = ∫(fh)dΓ_AD + dJ_int_AD = gradient(J_int,φh) + dJ_int_AD_vec = assemble_vector(dJ_int_AD,V_φ) + + dJ_int_exact(w) = ∫((-n_Γ⋅∇(fh))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + + ∫(-n_S_Λ ⋅ (jump(fh*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ + + ∫(-n_S_Σ ⋅ (fh*m_k_Σ * w / ∇ˢφ_Σ))dΣ + dJ_int_exact_vec = assemble_vector(dJ_int_exact,V_φ) + + abs_error = norm(dJ_int_AD_vec - dJ_int_exact_vec,Inf) + + if fdm + Ω_data = EmbeddedCollection(model,φh) do cutgeo,_,_ + Γ_AD = DifferentiableTriangulation(EmbeddedBoundary(cutgeo),V_φ) + (;:dΓ_AD => Measure(Γ_AD,2*order)) + end + function J_fdm_surf(φ) + sum(∫(fh)Ω_data.dΓ_AD) + end + dJ_surf_FD = FiniteDiff.finite_difference_gradient(J_fdm_surf,get_free_dof_values(φh)) + + abs_error_fdm = norm(dJ_int_AD_vec - dJ_surf_FD,Inf) + end + + if verbose + println("B.1) Surface integral:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error) + fdm && println(" - norm(dJ_AD - dJ_FDM,Inf) = ",abs_error_fdm) + end + @test abs_error < 1e-10 + + # B.2) Facet integral + g(fh) = ∇(fh)⋅∇(fh) + ∇g(∇∇f,∇f) = ∇∇f⋅∇f + ∇f⋅∇∇f + + J_int2(φ) = ∫(g(fh))dΓ_AD + dJ_int_AD2 = gradient(J_int2,φh) + dJ_int_AD_vec2 = assemble_vector(dJ_int_AD2,V_φ) + + dJ_int_exact2(w) = ∫((-n_Γ⋅ (∇g ∘ (∇∇(fh),∇(fh))))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + + ∫(-n_S_Λ ⋅ (jump(g(fh)*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ + + ∫(-n_S_Σ ⋅ (g(fh)*m_k_Σ * w / ∇ˢφ_Σ))dΣ + dJ_int_exact_vec2 = assemble_vector(dJ_int_exact2,V_φ) + + abs_error = norm(dJ_int_AD_vec2 - dJ_int_exact_vec2,Inf) + if verbose + println("B.2) Surface integral with grad of other fields:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error) + end + @test abs_error < 1e-10 + + if vtk + path = "results/$(name)/" + mkpath(path) + Ω_bg = Triangulation(model) + writevtk( + Ω_bg,"$(path)results", + cellfields = [ + "φh" => φh,"∇φh" => ∇(φh), + "dJ_bulk_AD" => FEFunction(V_φ,dJ_bulk_AD_vec), + "dJ_bulk_exact" => FEFunction(V_φ,dJ_bulk_exact_vec), + "dJ_int_AD" => FEFunction(V_φ,dJ_int_AD_vec), + "dJ_int_exact" => FEFunction(V_φ,dJ_int_exact_vec) + ], + celldata = [ + "inoutcut" => GridapEmbedded.Interfaces.compute_bgcell_to_inoutcut(model,geo) + ]; + append = false + ) + + writevtk( + Ω, "$(path)omega"; append = false + ) + writevtk( + Γ, "$(path)gamma"; append = false + ) + + n_∂Ω_Λ = get_subfacet_normal_vector(Λ) + n_k_Λ = get_ghost_normal_vector(Λ) + writevtk( + Λ, "$(path)_lambda", + cellfields = [ + "n_∂Ω.plus" => n_∂Ω_Λ.plus,"n_∂Ω.minus" => n_∂Ω_Λ.minus, + "n_k.plus" => n_k_Λ.plus,"n_k.minus" => n_k_Λ.minus, + "n_S" => n_S_Λ, + "m_k.plus" => m_k_Λ.plus,"m_k.minus" => m_k_Λ.minus, + "∇ˢφ" => ∇ˢφ_Λ, + "∇φh_Γs_plus" => ∇(φh).plus,"∇φh_Γs_minus" => ∇(φh).minus, + "jump(fh*m_k)" => jump(fh*m_k_Λ) + ]; + append = false + ) + + if num_cells(Σ) > 0 + n_∂Ω_Σ = get_subfacet_normal_vector(Σ) + n_k_Σ = get_ghost_normal_vector(Σ) + writevtk( + Σ, "$(path)_sigma", + cellfields = [ + "n_∂Ω" => n_∂Ω_Σ, "n_k" => n_k_Σ, + "n_S" => n_S_Σ, "m_k" => m_k_Σ, + "∇ˢφ" => ∇ˢφ_Σ, "∇φh_Γs" => ∇(φh), + ]; + append = false + ) + end + end +end + +## Concering integrals of the form `φ->∫(f ⋅ n(φ))dΓ(φ)` +function main_normal( + model,ls::Function,f_vec::Function; + vtk=false, + name="flux integrals", + run_test=true, + verbose=false, + fdm=false +) + order = 1 + reffe = ReferenceFE(lagrangian,Float64,order) + V_φ = TestFESpace(model,reffe) + + φh = interpolate(ls,V_φ) + + # Correction if level set is on top of a node + x_φ = get_free_dof_values(φh) + idx = findall(isapprox(0.0;atol=10^-10),x_φ) + !isempty(idx) && @info "Correcting level values!" + x_φ[idx] .+= 100*eps(eltype(x_φ)) + + geo = DiscreteGeometry(φh,model) + cutgeo = cut(model,geo) + + Γ = EmbeddedBoundary(cutgeo) + n_Γ = get_normal_vector(Γ) + Γ_AD = DifferentiableTriangulation(Γ,V_φ) + dΓ_AD = Measure(Γ_AD,2*order) + dΓ = Measure(Γ,2*order) + + fh_Γ = CellField(f_vec,Γ) + fh_Γ_AD = CellField(f_vec,Γ_AD) + + function J_int(φ) + n = get_normal_vector(Γ_AD) + ∫(fh_Γ_AD⋅n)dΓ_AD + end + dJ_int_AD = gradient(J_int,φh) + dJ_int_AD_vec = assemble_vector(dJ_int_AD,V_φ) + + _n(∇φ) = ∇φ/(10^-20+norm(∇φ)) + dJ_int_phi = ∇(φ->∫(fh_Γ_AD ⋅ (_n ∘ (∇(φ))))dΓ_AD,φh) + dJh_int_phi = assemble_vector(dJ_int_phi,V_φ) + + run_test && @test norm(dJ_int_AD_vec - dJh_int_phi) < 1e-10 + + # Analytic + # Note: currently, the analytic result is only valid on closed domains thanks + # to the divergence theorem. I think it would take significant work to compute + # the analytic derivative generally as we can't rely on divergence theorem to + # rewrite it in a convenient way. As a result, we don't have an analytic result + # for general cases such as ∫( f(n(φ)) )dΓ(φ), nor the case when Γ intersects + # ∂D. Thankfully, we have AD instead ;) + # Note 2: For the case that Γ does intersect the surface, the result is correct + # everywhere except on the intersection. + + fh_Γ = CellField(f_vec,Γ) + fh_Γ_AD = CellField(f_vec,Γ_AD) + + # Note: this comes from rewriting via the divergence theorem: + # ∫(f ⋅ n(φ))dΓ(φ) = ∫(∇⋅f)dΩ(φ) + dJ_int_exact3(w) = ∫(-(∇⋅(fh_Γ))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJh_int_exact3 = assemble_vector(dJ_int_exact3,V_φ) + + # Finite diff + if fdm + function J_fdm_surf(φ) + φh = FEFunction(V_φ,φ) + cutgeo = cut(model,DiscreteGeometry(φh,model)) + Γ = EmbeddedBoundary(cutgeo) + dΓ = Measure(Γ,2*order) + n = get_normal_vector(Γ) + f = CellField(f_vec,Γ) + n = get_normal_vector(Γ) + sum(∫(f⋅n)dΓ) + end + dJ_FD = FiniteDiff.finite_difference_gradient(J_fdm_surf,get_free_dof_values(φh)) + + abs_error_fdm = norm(dJ_int_AD_vec - dJ_FD,Inf) + end + abs_error = norm(dJh_int_exact3 - dJ_int_AD_vec,Inf) + + if verbose + println("C) Flux integral:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error) + fdm && println(" - norm(dJ_AD - dJ_FDM,Inf) = ",abs_error_fdm) + end + + run_test && @test abs_error < 1e-10 + + if vtk + path = "results/$(name)/" + mkpath(path) + Ω_bg = Triangulation(model) + writevtk(Ω_bg,path*"Results",cellfields=[ + "dJ_AD"=>FEFunction(V_φ,dJ_int_AD_vec), + "dJ_AD_with_phi"=>FEFunction(V_φ,dJh_int_phi), + "dJ_exact"=>FEFunction(V_φ,dJh_int_exact3) + ]) + writevtk(Γ,path*"Gamma") + end +end + +# Finite difference verification of gradients of integrals of the form `φ->∫(f(n))dΓ(φ)` and Hessian's. +# Both of these do not currently have rigorous mathematical counterparts so we verify them +# with finite differences. +function main_fdm_only_verif(model,ls::Function; + verbose=false,compute_hess=false,fdm=false +) + order = 1 + reffe = ReferenceFE(lagrangian,Float64,order) + V_φ = TestFESpace(model,reffe) + φh = interpolate(ls,V_φ) + + # Correction if level set is on top of a node + x_φ = get_free_dof_values(φh) + idx = findall(isapprox(0.0;atol=10^-10),x_φ) + !isempty(idx) && @info "Correcting level values!" + x_φ[idx] .+= 100*eps(eltype(x_φ)) + + geo = DiscreteGeometry(φh,model) + cutgeo = cut(model,geo) + + Γ = EmbeddedBoundary(cutgeo) + Γ_AD = DifferentiableTriangulation(Γ,V_φ) + dΓ_AD = Measure(Γ_AD,2*order) + + # Sec 6.2 - 10.1007/s00466-017-1383-6 + g((x,y)) = x - 1/10*sin(2π*y/6) + gh = interpolate(g,V_φ) + _n_g(∇g) = ∇g/(10^-20+norm(∇g)) + n_g = _n_g ∘ ∇(gh) + j(x) = norm(x)^2 + + function J_int(φ) + n = get_normal_vector(Γ_AD) + ∫(j ∘ (n-n_g))dΓ_AD + end + dJ_int_AD = gradient(J_int,φh) + dJ_int_AD_vec = assemble_vector(dJ_int_AD,V_φ) + hess = hessian(J_int,φh) + d²J = assemble_matrix(hess,V_φ,V_φ) + + # Finite diff + if fdm + function J_fdm_surf(φ) + φh = FEFunction(V_φ,φ) + cutgeo = cut(model,DiscreteGeometry(φh,model)) + Γ = EmbeddedBoundary(cutgeo) + dΓ = Measure(Γ,2*order) + n = get_normal_vector(Γ) + sum(∫(j ∘ (n-n_g))dΓ) + end + dJ_FD = FiniteDiff.finite_difference_gradient(J_fdm_surf,get_free_dof_values(φh)) + d²J_FD = compute_hess ? FiniteDiff.finite_difference_hessian(J_fdm_surf,get_free_dof_values(φh)) : nothing + + abs_error_fdm = norm(dJ_int_AD_vec - dJ_FD,Inf) + abs_error_fdm_hess = compute_hess ? norm(d²J - d²J_FD,Inf) : nothing + + if verbose + println("D) g(n) surf integral:") + println(" - norm(dJ_AD - dJ_exact,Inf) = ","N/A") + println(" - norm(dJ_AD - dJ_FDM,Inf) = ",abs_error_fdm) + compute_hess && println(" - norm(d²J_AD - d²J_FDM,Inf) = ",abs_error_fdm_hess) + end + end +end + +####################### + +# FDM is quite expensive, so we only run if required. + +D = 2 +n = 10 +model = generate_model(D,n) +f(x) = x[1]+x[2] +fvec((x,y)) = VectorValue((1-x)^2,(1-y)^2) +main(model,level_set(:circle_2),f;vtk=false,verbose=true,name="2D_circle/")#,fdm=true) +main(model,level_set(:regular_2d),f;vtk=false,verbose=true,name="2D_reg/")#,fdm=true) +main_normal(model,level_set(:circle_2),fvec;vtk=false,verbose=true,name="2D_circle_flux/",run_test=true)#,fdm=true) +main_normal(model,level_set(:regular_2d),fvec;vtk=false,verbose=true,name="2D_reg_flux/",run_test=false)#,fdm=true) # This will fail as expected +main_fdm_only_verif(model,level_set(:circle_2),verbose=true)#,fdm=true) +main_fdm_only_verif(model,level_set(:regular_2d),verbose=true,compute_hess=true)#,fdm=true) + +D = 3 +n = 4 +model = generate_model(D,n) +φ = level_set(:regular_3d) +f(x) = x[1]+x[2] +fvec2((x,y,z)) = VectorValue((1-x)^2,(1-y)^2,0) +main(model,level_set(:sphere_2),f;vtk=false,verbose=true,name="3D_circle/")#,fdm=true) +main(model,level_set(:regular_3d),f;vtk=false,verbose=true,name="3D_reg/")#,fdm=true) +main_normal(model,level_set(:sphere_2),fvec2;vtk=false,verbose=true,name="3D_circle_flux/",run_test=true)#,fdm=true) +main_normal(model,level_set(:regular_3d),fvec2;vtk=false,verbose=true,name="3D_reg_flux/",run_test=false,)#fdm=true) # This will fail as expected +main_fdm_only_verif(model,level_set(:sphere_2),verbose=true)#,fdm=true) +main_fdm_only_verif(model,level_set(:regular_3d),verbose=true)#,fdm=true) + +end \ No newline at end of file diff --git a/test/LevelSetCuttersTests/runtests.jl b/test/LevelSetCuttersTests/runtests.jl index c108a65e..548e1149 100644 --- a/test/LevelSetCuttersTests/runtests.jl +++ b/test/LevelSetCuttersTests/runtests.jl @@ -12,4 +12,6 @@ using Test @testset "LevelSetCutters" begin include("LevelSetCuttersTests.jl") end +@testset "GeometricalDifferentiation" begin include("GeometricalDifferentiationTests.jl") end + end # module From 07aee710a5c009e5a68b4fbaad50a00c0e438c46 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 17 Apr 2025 16:26:58 +1000 Subject: [PATCH 43/74] Minor --- test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl index 04e7f527..aa6bbec0 100644 --- a/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl +++ b/test/InterfacesTests/EmbeddedFacetDiscretizationsTests.jl @@ -76,7 +76,7 @@ celldata_Λ = [ "bgcell_right"=>collect(Int,get_glue(Λ.⁻,Val(D)).tface_to_mface)] cellfields_Λ = ["normal"=> n_Λ.⁺,"jump_v"=>jump(v),"jump_u"=>jump(u)] -d = "./dev"#mktempdir() +d = mktempdir() try writevtk(Ωbg,joinpath(d,"trian"),append=false) writevtk(Ω,joinpath(d,"trian_O"),celldata=celldata_Ω,cellfields=cellfields_Ω,append=false) @@ -84,7 +84,7 @@ try writevtk(Λ,joinpath(d,"trian_sO"),celldata=celldata_Λ,cellfields=cellfields_Λ,append=false) writevtk(Γf,joinpath(d,"trian_Gf"),append=false) finally - #rm(d,recursive=true) + rm(d,recursive=true) end ########################################## From 9c22c37eed9e499f69a6e9ea19a952fb3ae36d22 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Thu, 17 Apr 2025 17:24:52 +1000 Subject: [PATCH 44/74] Started documenting the library --- src/Interfaces/Cutters.jl | 43 ++++++++++++++++++++ src/Interfaces/EmbeddedDiscretizations.jl | 44 ++++++++++++++++++++- src/LevelSetCutters/AnalyticalGeometries.jl | 33 +++++++++++++++- src/LevelSetCutters/DiscreteGeometries.jl | 17 ++++++++ src/LevelSetCutters/LevelSetCutters.jl | 13 ++++++ 5 files changed, 147 insertions(+), 3 deletions(-) diff --git a/src/Interfaces/Cutters.jl b/src/Interfaces/Cutters.jl index 5104430d..2fca363e 100644 --- a/src/Interfaces/Cutters.jl +++ b/src/Interfaces/Cutters.jl @@ -1,17 +1,60 @@ + +""" + abstract type Cutter <: GridapType end + +Abstract type for all mesh cutters. Has to be paired with a [`CSG.Geometry`](@ref) to +cut the background mesh. + +## Methods + +- [`cut(cutter::Cutter,background,geom)`](@ref) +- [`cut_facets(cutter::Cutter,background,geom)`](@ref) +- [`compute_bgcell_to_inoutcut(cutter::Cutter,background,geom)`](@ref) +- [`compute_bgfacet_to_inoutcut(cutter::Cutter,background,geom)`](@ref) + +Generally `cut` and `cut_facets` dispatch based on the geometry provided, so it is +generally more convennient to call the following methods instead: + +- [`cut(background,geom)`](@ref) +- [`cut_facets(background,geom)`](@ref) + +""" abstract type Cutter <: GridapType end +""" + cut(cutter::Cutter,background,geom) + +Cut the background mesh with the provided cutter and geometry, returnning the cut cells. +The cut cells are returned as an [`EmbeddedDiscretization`](@ref) object. +""" function cut(cutter::Cutter,background,geom) @abstractmethod end +""" + compute_bgcell_to_inoutcut(cutter::Cutter,background,geom) + +Returns an array of IN/OUT/CUT states for each cell in the background mesh. +""" function compute_bgcell_to_inoutcut(cutter::Cutter,background,geom) @abstractmethod end +""" + cut_facets(cutter::Cutter,background,geom) + +Cut the background mesh with the provided cutter and geometry, returning the cut facets. +The cut facets are returned as an [`EmbeddedFacetDiscretization`](@ref) object. +""" function cut_facets(cutter::Cutter,background,geom) @abstractmethod end +""" + compute_bgfacet_to_inoutcut(cutter::Cutter,background,geom) + +Returns an array of IN/OUT/CUT states for each facet in the background mesh. +""" function compute_bgfacet_to_inoutcut(cutter::Cutter,background,geom) @abstractmethod end diff --git a/src/Interfaces/EmbeddedDiscretizations.jl b/src/Interfaces/EmbeddedDiscretizations.jl index 5a6a14b3..b8ee0ee0 100644 --- a/src/Interfaces/EmbeddedDiscretizations.jl +++ b/src/Interfaces/EmbeddedDiscretizations.jl @@ -1,6 +1,42 @@ - +""" + abstract type EmbeddedDiscretization <: GridapType end +""" abstract type AbstractEmbeddedDiscretization <: GridapType end +""" + struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization + bgmodel::DiscreteModel + ls_to_bgcell_to_inoutcut::Vector{Vector{Int8}} + subcells::SubCellData{Dc,Dc,T} + ls_to_subcell_to_inout::Vector{Vector{Int8}} + subfacets::SubFacetData{Dc,T} + ls_to_subfacet_to_inout::Vector{Vector{Int8}} + oid_to_ls::Dict{UInt,Int} + geo::CSG.Geometry + end + +This structure contains all the required information to build integration `Triangulation`s +for a cut model. + +## Constructors + + EmbeddedDiscretization(cutter::Cutter,background,geom) + +## Properties + +- `bgmodel::DiscreteModel`: the background mesh +- `geo::CSG.Geometry`: the geometry used to cut the background mesh +- `subcells::SubCellData`: collection of cut subcells, attached to the background mesh +- `subfacets::SubFacetData`: collection of cut facets, attached to the background mesh +- `ls_to_X_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each cell/facet + in the background mesh, for each node in the geometry tree. + +## Methods + +- [`Triangulation(cut::EmbeddedDiscretization,in_or_out)`](@ref) +- [`EmbeddedBoundary(cut::EmbeddedDiscretization)`](@ref) + +""" struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization bgmodel::DiscreteModel ls_to_bgcell_to_inoutcut::Vector{Vector{Int8}} @@ -224,6 +260,9 @@ function Triangulation(cut::EmbeddedDiscretization) Triangulation(cut,PHYSICAL_IN,cut.geo) end +""" + Triangulation(cut::EmbeddedDiscretization[,in_or_out=PHYSICAL_IN]) +""" function Triangulation(cut::EmbeddedDiscretization,in_or_out) Triangulation(cut,in_or_out,cut.geo) end @@ -355,6 +394,9 @@ function _compute_inout_complementary(inout_1) end end +""" + EmbeddedBoundary(cut::EmbeddedDiscretization) +""" function EmbeddedBoundary(cut::EmbeddedDiscretization) EmbeddedBoundary(cut,cut.geo) end diff --git a/src/LevelSetCutters/AnalyticalGeometries.jl b/src/LevelSetCutters/AnalyticalGeometries.jl index 48485ed5..a34103a3 100644 --- a/src/LevelSetCutters/AnalyticalGeometries.jl +++ b/src/LevelSetCutters/AnalyticalGeometries.jl @@ -1,4 +1,33 @@ +""" + struct AnalyticalGeometry <: CSG.Geometry + tree::Node + end + +A structure to represent analytical geometries, used to cut background meshes. + +## Constructor + + AnalyticalGeometry(f::Function;name=string(nameof(f))) + +where `f: Ω -> R ` is a function that, similiarly to a level set function, is negative inside the +geometry and positive outside. + +## Predefined geometries + + doughnut(R,r;x0=zero(Point{3,typeof(R)}),name="doughnut") + popcorn(r0=0.6, σ=0.2, A=2, x0=zero(Point{3,typeof(r0)}), name="popcorn") + sphere(R;x0=zero(Point{3,eltype(R)}),name="sphere") + disk(R;x0=zero(Point{2,eltype(R)}),name="disk") + cylinder(R;x0=zero(Point{3,eltype(R)}),v=VectorValue(1,0,0),name="cylinder") + plane(x0=Point(0,0,0),v=VectorValue(1,0,0),name="plane") + square(L=1,x0=Point(0,0),name="square",edges=["edge_i" for i in 1:4]) + quadrilateral(x0=Point(0,0),d1=VectorValue(1,0),d2=VectorValue(0,1),name="quadrilateral") + cube(L=1,x0=Point(0,0,0),name="cube") + tube(R,L;x0=zero(Point{3,typeof(R)}),v=VectorValue(1,0,0),name="tube") + olympic_rings(R,r,name="olympic_rings") + +""" struct AnalyticalGeometry <: CSG.Geometry tree::Node end @@ -14,8 +43,8 @@ struct BoundingBox{D,T} pmax::Point{D,T} end -function AnalyticalGeometry(f::Function) - tree = Leaf((f,string(nameof(f)),nothing)) +function AnalyticalGeometry(f::Function;name=string(nameof(f))) + tree = Leaf((f,name,nothing)) AnalyticalGeometry(tree) end diff --git a/src/LevelSetCutters/DiscreteGeometries.jl b/src/LevelSetCutters/DiscreteGeometries.jl index 472fa278..8ad1f024 100644 --- a/src/LevelSetCutters/DiscreteGeometries.jl +++ b/src/LevelSetCutters/DiscreteGeometries.jl @@ -1,4 +1,16 @@ +""" + struct DiscreteGeometry{D,T} <: CSG.Geometry + tree::Node + point_to_coords::Vector{Point{D,T}} + end + +## Constructors + + DiscreteGeometry(φh::FEFunction,model::DiscreteModel;name::String="") + DiscreteGeometry(f::Function,model::DiscreteModel;name::String="") + +""" struct DiscreteGeometry{D,T} <: CSG.Geometry tree::Node point_to_coords::Vector{Point{D,T}} @@ -61,6 +73,11 @@ function _find_unique_leaves(tree) j_to_fun, oid_to_j end +function DiscreteGeometry(f::Function,model::DiscreteModel;name::String="") + geo = AnalyticalGeometry(f;name=name) + discretize(geo,model) +end + function DiscreteGeometry( point_to_value::AbstractVector,point_to_coords::AbstractVector;name::String="") data = (point_to_value,name,nothing) diff --git a/src/LevelSetCutters/LevelSetCutters.jl b/src/LevelSetCutters/LevelSetCutters.jl index 5b6e0f7c..30592287 100644 --- a/src/LevelSetCutters/LevelSetCutters.jl +++ b/src/LevelSetCutters/LevelSetCutters.jl @@ -58,6 +58,19 @@ include("CutTriangulations.jl") include("DifferentiableTriangulations.jl") +""" + struct LevelSetCutter <: Cutter end + +Cutter for `DiscreteGeometry` and `AnalyticalGeometry`. + +## Usage + + cut(background::DiscreteModel,geom::AnalyticalGeometry) + cut(background::DiscreteModel,geom::DiscreteGeometry) + cut_facets(background::DiscreteModel,geom::AnalyticalGeometry) + cut_facets(background::DiscreteModel,geom::DiscreteGeometry) + +""" struct LevelSetCutter <: Cutter end function cut(cutter::LevelSetCutter,background::DiscreteModel,geom) From 2977507ef1056dd5954273515b15c7bc255f6cf2 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Fri, 18 Apr 2025 10:55:12 +1000 Subject: [PATCH 45/74] Added documentation skeleton --- docs/Project.toml | 1 + docs/make.jl | 26 +++++++++++----- docs/src/AggregatedFEM.md | 16 ++++++++++ docs/src/CSGCutters.md | 15 +++++++++ docs/src/Distributed.md | 11 +++++++ docs/src/Interfaces.md | 48 +++++++++++++++++++++++++++++ docs/src/LevelSetCutters.md | 16 ++++++++++ docs/src/MomentFittedQuadratures.md | 11 +++++++ docs/src/index.md | 18 ++++++++--- 9 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 docs/src/AggregatedFEM.md create mode 100644 docs/src/CSGCutters.md create mode 100644 docs/src/Distributed.md create mode 100644 docs/src/Interfaces.md create mode 100644 docs/src/LevelSetCutters.md create mode 100644 docs/src/MomentFittedQuadratures.md diff --git a/docs/Project.toml b/docs/Project.toml index dfa65cd1..bb0510fc 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,2 +1,3 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +GridapEmbedded = "8838a6a3-0006-4405-b874-385995508d5d" diff --git a/docs/make.jl b/docs/make.jl index 3bad67a4..d335684c 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,14 +1,24 @@ using Documenter, GridapEmbedded +pages = [ + "Home" => "index.md", + "Interfaces" => "Interfaces.md", + "Constructive Solid Geometry (CSG)" => "CSGCutters.md", + "Level Sets" => "LevelSetCutters.md", + "Aggregated FEM" => "AggregatedFEM.md", + "Moment-Fitted Quadratures" => "MomentFittedQuadratures.md", + "Distributed computing" => "Distributed.md", +], + makedocs(; - modules=[GridapEmbedded], - format=Documenter.HTML(), - pages=[ - "Home" => "index.md", - ], - repo="https://github.com/gridap/GridapEmbedded.jl/blob/{commit}{path}#L{line}", - sitename="GridapEmbedded.jl", - authors="Francesc Verdugo , Eric Neiva and Santiago Badia ", + modules = [GridapEmbedded], + format = Documenter.HTML( + size_threshold=nothing + ), + sitename = "GridapEmbedded.jl", + authors = "Francesc Verdugo , Eric Neiva and Santiago Badia ", + pages = pages, + warnonly = true, ) deploydocs(; diff --git a/docs/src/AggregatedFEM.md b/docs/src/AggregatedFEM.md new file mode 100644 index 00000000..a2d7be88 --- /dev/null +++ b/docs/src/AggregatedFEM.md @@ -0,0 +1,16 @@ + +# Aggregated FEM + +```@meta +CurrentModule = GridapEmbedded.AgFEM +``` + +```@autodocs +Modules = [AgFEM,] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/AgFEM.jl", + "/AgFEMSpaces.jl", + "CellAggregation.jl" +] +``` diff --git a/docs/src/CSGCutters.md b/docs/src/CSGCutters.md new file mode 100644 index 00000000..72dd78dd --- /dev/null +++ b/docs/src/CSGCutters.md @@ -0,0 +1,15 @@ + +# Constructive Solid Geometry (CSG) Cutters + +```@meta +CurrentModule = GridapEmbedded.CSG +``` + +```@autodocs +Modules = [CSG,] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/Nodes.jl", + "/Geometries.jl", +] +``` diff --git a/docs/src/Distributed.md b/docs/src/Distributed.md new file mode 100644 index 00000000..56a17b59 --- /dev/null +++ b/docs/src/Distributed.md @@ -0,0 +1,11 @@ + +# Distributed computing + +```@meta +CurrentModule = GridapEmbedded.Distributed +``` + +```@autodocs +Modules = [Distributed,] +Order = [:type, :constant, :macro, :function] +``` diff --git a/docs/src/Interfaces.md b/docs/src/Interfaces.md new file mode 100644 index 00000000..72d763d2 --- /dev/null +++ b/docs/src/Interfaces.md @@ -0,0 +1,48 @@ + +# Embedded Interfaces + +```@meta +CurrentModule = GridapEmbedded.Interfaces +``` + +## Cutters + +Cutters are used to cut the background mesh according to a provided geometry. + +```@autodocs +Modules = [Interfaces,] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/Cutters.jl", +] +``` + +We provide several types of cutters, including: + +- **CSG Cutters**: Constructive Solid Geometry (CSG) Cutters. See [Constructive Solid Geometry (CSG) Cutters](@ref). +- **Level-Set Cutters**: Level-Set Cutters. See [Level-Set Cutters](@ref). +- **STL Cutters**: Cutters for STL based geometries. Provided by [STLCutters.jl](https://github.com/gridap/STLCutters.jl). + +## Embedded Discretizations + +After cutting the background mesh, you will be returned an `EmbeddedDiscretization` object. These contain all the information you need to generate the integration meshes for embedded methods. + +```@autodocs +Modules = [Interfaces,] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/EmbeddedDiscretizations.jl", + "/EmbeddedFacetDiscretizations.jl", +] +``` + +## Embedded Triangulations + +```@autodocs +Modules = [Interfaces,] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/SubCellTriangulations", + "/SubFacetTriangulations.jl" +] +``` diff --git a/docs/src/LevelSetCutters.md b/docs/src/LevelSetCutters.md new file mode 100644 index 00000000..8980ddc6 --- /dev/null +++ b/docs/src/LevelSetCutters.md @@ -0,0 +1,16 @@ + +# Level-Set Cutters + +```@meta +CurrentModule = GridapEmbedded.LevelSetCutters +``` + +```@autodocs +Modules = [LevelSetCutters,] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/AnalyticalGeometries.jl", + "/DiscreteGeometries.jl", + "LevelSetCutters.jl", +] +``` diff --git a/docs/src/MomentFittedQuadratures.md b/docs/src/MomentFittedQuadratures.md new file mode 100644 index 00000000..5f076ddd --- /dev/null +++ b/docs/src/MomentFittedQuadratures.md @@ -0,0 +1,11 @@ + +# Moment-Fitted Quadratures + +```@meta +CurrentModule = GridapEmbedded.MomentFittedQuadratures +``` + +```@autodocs +Modules = [MomentFittedQuadratures,] +Order = [:type, :constant, :macro, :function] +``` diff --git a/docs/src/index.md b/docs/src/index.md index 84432dfd..21aa5a50 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,8 +1,18 @@ # GridapEmbedded.jl -```@index -``` +## Introduction + +GridapEmbedded.jl is a package for the simulation of PDEs on embedded domains within the Gridap.jl ecosystem. Please refer to the [Gridap.jl documentation](https://gridap.github.io/Gridap.jl/stable/) for information on the core capabilities of the Gridap.jl library. + +## Manual -```@autodocs -Modules = [GridapEmbedded] +```@contents +Pages = [ + "Interfaces.md", + "CSGCutters.md", + "LevelSetCutters.md", + "AggregatedFEM.md", + "MomentFittedQuadratures.md", + "Distributed.md", +] ``` From 3a60103044ec0bc2b3cbb110c1599c396d4cde0d Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Fri, 18 Apr 2025 11:45:31 +1000 Subject: [PATCH 46/74] More docs --- docs/make.jl | 2 +- docs/src/Interfaces.md | 66 +++++++++++++++---- .../CutFaceBoundaryTriangulations.jl | 2 +- src/Interfaces/EmbeddedDiscretizations.jl | 23 ++++--- .../EmbeddedFacetDiscretizations.jl | 38 ++++++++++- 5 files changed, 100 insertions(+), 31 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index d335684c..c5e20ca3 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -8,7 +8,7 @@ pages = [ "Aggregated FEM" => "AggregatedFEM.md", "Moment-Fitted Quadratures" => "MomentFittedQuadratures.md", "Distributed computing" => "Distributed.md", -], +] makedocs(; modules = [GridapEmbedded], diff --git a/docs/src/Interfaces.md b/docs/src/Interfaces.md index 72d763d2..e9927a89 100644 --- a/docs/src/Interfaces.md +++ b/docs/src/Interfaces.md @@ -5,6 +5,45 @@ CurrentModule = GridapEmbedded.Interfaces ``` +## Domain Nomenclature + +Throughout this documentation, many methods accept arguments that select different parts of the cut domain. We split the domain into the following parts: + +The background mesh entities (cells, facets, nodes) are classified as `IN`, `OUT` or `CUT`. The `IN` and `OUT` background cells are uncut, i.e completely inside or outside the geometry, respectively. These states are internally defined as constants: + +```julia + const IN = -1 + const OUT = 1 + const CUT = 0 +``` + +The `CUT` background cells are cut by the embedded boundary, and split into subcells/subfacets. The subcells/subfacets are classified as `IN` or `OUT` depending on whether they are inside or outside the geometry. `CUT-IN` and `CUT-OUT` subentities can be accessed using the `CutInOrOut` objects: + +```julia + struct CutInOrOut + in_or_out::Int + end + const CUT_IN = CutInOrOut(IN) + const CUT_OUT = CutInOrOut(OUT) +``` + +For FEM, we generally want to get sets of uncut and cut cells together, for a given state `IN/OUT`. These are referred as `PHYSICAL` parts of the domain. Moreover, FE spaces are generally defined over the background mesh and need to span both `IN/OUT` and `CUT` background cells. These are referred as `ACTIVE` parts of the domain. You can extract the `PHYSICAL` and `ACTIVE` parts of the domain using the following constants: + +```julia +const PHYSICAL_IN = (CUT_IN,IN) +const PHYSICAL_OUT = (CUT_OUT,OUT) +const PHYSICAL = PHYSICAL_IN +``` + +```julia +struct ActiveInOrOut + in_or_out::Int +end +const ACTIVE_IN = ActiveInOrOut(IN) +const ACTIVE_OUT = ActiveInOrOut(OUT) +const ACTIVE = ACTIVE_IN +``` + ## Cutters Cutters are used to cut the background mesh according to a provided geometry. @@ -27,22 +66,21 @@ We provide several types of cutters, including: After cutting the background mesh, you will be returned an `EmbeddedDiscretization` object. These contain all the information you need to generate the integration meshes for embedded methods. -```@autodocs -Modules = [Interfaces,] -Order = [:type, :constant, :macro, :function] -Pages = [ - "/EmbeddedDiscretizations.jl", - "/EmbeddedFacetDiscretizations.jl", -] +```@docs +AbstractEmbeddedDiscretization +EmbeddedDiscretization +EmbeddedFacetDiscretization ``` ## Embedded Triangulations -```@autodocs -Modules = [Interfaces,] -Order = [:type, :constant, :macro, :function] -Pages = [ - "/SubCellTriangulations", - "/SubFacetTriangulations.jl" -] +From `EmbeddedDiscretization` objects, you can extract all the triangulations you need to perform integration for embedded methods. We currently provide the following methods: + +```@docs +Gridap.Geometry.Triangulation(::EmbeddedDiscretization,::Any) +EmbeddedBoundary(::EmbeddedDiscretization) +GhostSkeleton(::EmbeddedDiscretization) +Gridap.Geometry.BoundaryTriangulation(::EmbeddedFacetDiscretization,::Any) +Gridap.Geometry.SkeletonTriangulation(::EmbeddedFacetDiscretization,::Any) +SubFacetBoundaryTriangulation ``` diff --git a/src/Interfaces/CutFaceBoundaryTriangulations.jl b/src/Interfaces/CutFaceBoundaryTriangulations.jl index d30ada3a..e85e70cc 100644 --- a/src/Interfaces/CutFaceBoundaryTriangulations.jl +++ b/src/Interfaces/CutFaceBoundaryTriangulations.jl @@ -111,7 +111,7 @@ Triangulation containing the interfaces between subfacets. We always have dimens - Df = Dc-1 :: Dimension of the cut subfacets - Di = Dc-2 :: Dimension of the subfacet interfaces -Description of the different components: +# Properties - `face_trian` :: Original SubFacetTriangulation, built on top of the background mesh. - `face_model` :: Subfacet model. Active model for `face_trian`. diff --git a/src/Interfaces/EmbeddedDiscretizations.jl b/src/Interfaces/EmbeddedDiscretizations.jl index b8ee0ee0..95b6ccc2 100644 --- a/src/Interfaces/EmbeddedDiscretizations.jl +++ b/src/Interfaces/EmbeddedDiscretizations.jl @@ -1,26 +1,17 @@ """ - abstract type EmbeddedDiscretization <: GridapType end + abstract type EmbeddedDiscretization <: GridapType """ abstract type AbstractEmbeddedDiscretization <: GridapType end """ struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization - bgmodel::DiscreteModel - ls_to_bgcell_to_inoutcut::Vector{Vector{Int8}} - subcells::SubCellData{Dc,Dc,T} - ls_to_subcell_to_inout::Vector{Vector{Int8}} - subfacets::SubFacetData{Dc,T} - ls_to_subfacet_to_inout::Vector{Vector{Int8}} - oid_to_ls::Dict{UInt,Int} - geo::CSG.Geometry - end This structure contains all the required information to build integration `Triangulation`s for a cut model. ## Constructors - EmbeddedDiscretization(cutter::Cutter,background,geom) + cut(cutter::Cutter,background,geom) ## Properties @@ -28,13 +19,18 @@ for a cut model. - `geo::CSG.Geometry`: the geometry used to cut the background mesh - `subcells::SubCellData`: collection of cut subcells, attached to the background mesh - `subfacets::SubFacetData`: collection of cut facets, attached to the background mesh -- `ls_to_X_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each cell/facet +- `ls_to_bgcell_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each cell in the background mesh, for each node in the geometry tree. +- `ls_to_subcell_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each subcell + in the cut part of the mesh, for each node in the geometry tree. +- `ls_to_subfacet_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each subfacet + in the cut part of the mesh, for each node in the geometry tree. ## Methods - [`Triangulation(cut::EmbeddedDiscretization,in_or_out)`](@ref) - [`EmbeddedBoundary(cut::EmbeddedDiscretization)`](@ref) +- [`GhostSkeleton(cut::EmbeddedDiscretization)`](@ref) """ struct EmbeddedDiscretization{Dc,T} <: AbstractEmbeddedDiscretization @@ -456,6 +452,9 @@ function EmbeddedBoundary(cut::EmbeddedDiscretization,geo1::CSG.Geometry,geo2::C end +""" + GhostSkeleton(cut::EmbeddedDiscretization[,in_or_out=ACTIVE_IN]) +""" function GhostSkeleton(cut::EmbeddedDiscretization) GhostSkeleton(cut,ACTIVE_IN) end diff --git a/src/Interfaces/EmbeddedFacetDiscretizations.jl b/src/Interfaces/EmbeddedFacetDiscretizations.jl index 56ece473..1f5476cc 100644 --- a/src/Interfaces/EmbeddedFacetDiscretizations.jl +++ b/src/Interfaces/EmbeddedFacetDiscretizations.jl @@ -1,4 +1,30 @@ +""" + struct EmbeddedFacetDiscretization{Dc,Dp,T} <: AbstractEmbeddedDiscretization + +This structure contains all the required information to build integration `Triangulations` +for a cut model boundary. + +## Constructors + + cut_facets(cutter::Cutter,background,geom) + +## Properties + +- `bgmodel::DiscreteModel`: the background mesh +- `geo::CSG.Geometry`: the geometry used to cut the background mesh +- `subfacets::SubFacetData`: collection of cut facets, attached to the background mesh +- `ls_to_facet_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each facet + in the background mesh, for each node in the geometry tree. +- `ls_to_subfacet_to_inoutcut::Vector{Vector{Int8}}`: list of IN/OUT/CUT states for each subfacet + in the cut part of the mesh, for each node in the geometry tree. + +## Methods + +- [`BoundaryTriangulation(cut::EmbeddedFacetDiscretization,in_or_out)`](@ref) +- [`SkeletonTriangulation(cut::EmbeddedFacetDiscretization,in_or_out)`](@ref) + +""" struct EmbeddedFacetDiscretization{Dc,Dp,T} <: AbstractEmbeddedDiscretization bgmodel::DiscreteModel{Dp,Dp} ls_to_facet_to_inoutcut::Vector{Vector{Int8}} @@ -20,6 +46,9 @@ function SkeletonTriangulation(cut::EmbeddedFacetDiscretization) SkeletonTriangulation(cut,PHYSICAL_IN) end +""" + SkeletonTriangulation(cut::EmbeddedFacetDiscretization[, in_or_out=PHYSICAL_IN]) +""" function SkeletonTriangulation( cut::EmbeddedFacetDiscretization, in_or_out) @@ -75,6 +104,9 @@ function BoundaryTriangulation( BoundaryTriangulation(cut,PHYSICAL_IN;tags=tags) end +""" + BoundaryTriangulation(cut::EmbeddedFacetDiscretization[, in_or_out=PHYSICAL_IN; tags=nothing]) +""" function BoundaryTriangulation( cut::EmbeddedFacetDiscretization, in_or_out; @@ -232,10 +264,10 @@ in this triangulation is part of a background facet that has been cut by the geo This differs from the the `SubFacetTriangulation` in that the facets in the `SubFacetTriangulation` are not cut background facets, but rather subfacets on the interior of a background cell. -They result from calling `Boundary` or `Skeleton` on an `EmbeddedFacetDiscretization` object, -for instance: +They result from calling `Boundary` or `Skeleton` on an `EmbeddedFacetDiscretization` object. - BoundaryTriangulation(cut::EmbeddedFacetDiscretization,in_or_out,geo;tags=nothing) + BoundaryTriangulation(cut::EmbeddedFacetDiscretization,in_or_out;tags=nothing) + SkeletonTriangulation(cut::EmbeddedFacetDiscretization,in_or_out) """ struct SubFacetBoundaryTriangulation{Dc,Dp,T} <: Triangulation{Dc,Dp} From 56e159fc4b6c33c51ac07c8a460e42c04d9f4c8b Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Fri, 18 Apr 2025 12:07:38 +1000 Subject: [PATCH 47/74] More docs --- docs/make.jl | 6 ++-- docs/src/{CSGCutters.md => CSG.md} | 2 +- docs/src/Interfaces.md | 7 ++--- docs/src/index.md | 2 +- src/CSG/Geometries.jl | 35 +++++++++++++++++++++-- src/Interfaces/EmbeddedDiscretizations.jl | 19 ++++++++++-- src/Interfaces/SubCellTriangulations.jl | 5 ++++ src/Interfaces/SubFacetTriangulations.jl | 5 ++++ 8 files changed, 68 insertions(+), 13 deletions(-) rename docs/src/{CSGCutters.md => CSG.md} (80%) diff --git a/docs/make.jl b/docs/make.jl index c5e20ca3..2c5569a6 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,9 +2,9 @@ using Documenter, GridapEmbedded pages = [ "Home" => "index.md", - "Interfaces" => "Interfaces.md", - "Constructive Solid Geometry (CSG)" => "CSGCutters.md", - "Level Sets" => "LevelSetCutters.md", + "Constructive Solid Geometry (CSG)" => "CSG.md", + "Embedded Interfaces" => "Interfaces.md", + "Level Set Cutters" => "LevelSetCutters.md", "Aggregated FEM" => "AggregatedFEM.md", "Moment-Fitted Quadratures" => "MomentFittedQuadratures.md", "Distributed computing" => "Distributed.md", diff --git a/docs/src/CSGCutters.md b/docs/src/CSG.md similarity index 80% rename from docs/src/CSGCutters.md rename to docs/src/CSG.md index 72dd78dd..d801c34e 100644 --- a/docs/src/CSGCutters.md +++ b/docs/src/CSG.md @@ -1,5 +1,5 @@ -# Constructive Solid Geometry (CSG) Cutters +# Constructive Solid Geometry (CSG) ```@meta CurrentModule = GridapEmbedded.CSG diff --git a/docs/src/Interfaces.md b/docs/src/Interfaces.md index e9927a89..dadc981a 100644 --- a/docs/src/Interfaces.md +++ b/docs/src/Interfaces.md @@ -9,7 +9,7 @@ CurrentModule = GridapEmbedded.Interfaces Throughout this documentation, many methods accept arguments that select different parts of the cut domain. We split the domain into the following parts: -The background mesh entities (cells, facets, nodes) are classified as `IN`, `OUT` or `CUT`. The `IN` and `OUT` background cells are uncut, i.e completely inside or outside the geometry, respectively. These states are internally defined as constants: +**The background mesh entities** (cells, facets, nodes) are classified as `IN`, `OUT` or `CUT`. The `IN` and `OUT` background cells are uncut, i.e completely inside or outside the geometry, respectively. These states are internally defined as constants: ```julia const IN = -1 @@ -17,7 +17,7 @@ The background mesh entities (cells, facets, nodes) are classified as `IN`, `OUT const CUT = 0 ``` -The `CUT` background cells are cut by the embedded boundary, and split into subcells/subfacets. The subcells/subfacets are classified as `IN` or `OUT` depending on whether they are inside or outside the geometry. `CUT-IN` and `CUT-OUT` subentities can be accessed using the `CutInOrOut` objects: +**The `CUT` background cells** are cut by the embedded boundary, and split into subcells/subfacets. The subcells/subfacets are classified as `IN` or `OUT` depending on whether they are inside or outside the geometry. `CUT_IN` and `CUT_OUT` subentities can be accessed using the `CutInOrOut` objects: ```julia struct CutInOrOut @@ -58,8 +58,7 @@ Pages = [ We provide several types of cutters, including: -- **CSG Cutters**: Constructive Solid Geometry (CSG) Cutters. See [Constructive Solid Geometry (CSG) Cutters](@ref). -- **Level-Set Cutters**: Level-Set Cutters. See [Level-Set Cutters](@ref). +- **Level-Set Cutters**: Cutters for Level-Set and function-defined geometries. See [Level-Set Cutters](@ref). - **STL Cutters**: Cutters for STL based geometries. Provided by [STLCutters.jl](https://github.com/gridap/STLCutters.jl). ## Embedded Discretizations diff --git a/docs/src/index.md b/docs/src/index.md index 21aa5a50..4ba7959e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -8,8 +8,8 @@ GridapEmbedded.jl is a package for the simulation of PDEs on embedded domains wi ```@contents Pages = [ + "CSG.md", "Interfaces.md", - "CSGCutters.md", "LevelSetCutters.md", "AggregatedFEM.md", "MomentFittedQuadratures.md", diff --git a/src/CSG/Geometries.jl b/src/CSG/Geometries.jl index 38c39080..f37ee04b 100644 --- a/src/CSG/Geometries.jl +++ b/src/CSG/Geometries.jl @@ -1,14 +1,35 @@ +""" + abstract type Geometry + +Abstract type for the definition of a geometry. + +## Interface + +- `get_tree(geo::Geometry)` +- `similar_geometry(a::Geometry,tree::Node)` +- `compatible_geometries(a::Geometry,b::Geometry)` + +""" abstract type Geometry end +""" + get_tree(geo::Geometry) +""" function get_tree(geo::Geometry) @abstractmethod end +""" + similar_geometry(a::Geometry,tree::Node) +""" function similar_geometry(a::Geometry,tree::Node) @abstractmethod end +""" + compatible_geometries(a::Geometry,b::Geometry) +""" function compatible_geometries(a::Geometry,b::Geometry) @abstractmethod end @@ -51,24 +72,36 @@ function _replace_metadata(tree::Leaf,meta) Leaf(data) end +""" + Base.union(a::Geometry,b::Geometry;name::String="",meta=nothing) +""" function Base.union(a::Geometry,b::Geometry;name::String="",meta=nothing) _a, _b = compatible_geometries(a,b) tree = union(get_tree(_a),get_tree(_b),name,meta) similar_geometry(_a,tree) end +""" + Base.intersect(a::Geometry,b::Geometry;name::String="",meta=nothing) +""" function Base.intersect(a::Geometry,b::Geometry;name::String="",meta=nothing) _a, _b = compatible_geometries(a,b) tree = intersect(get_tree(_a),get_tree(_b),name,meta) similar_geometry(_a,tree) end +""" + Base.setdiff(a::Geometry,b::Geometry;name::String="",meta=nothing) +""" function Base.setdiff(a::Geometry,b::Geometry;name::String="",meta=nothing) _a, _b = compatible_geometries(a,b) tree = setdiff(get_tree(_a),get_tree(_b),name,meta) similar_geometry(_a,tree) end +""" + Base.:!(a::Geometry;name::String="",meta=nothing) +""" function Base.:!(a::Geometry;name::String="",meta=nothing) tree = !(get_tree(a),name,meta) similar_geometry(a,tree) @@ -119,5 +152,3 @@ function get_geometry_node(a::Node,name::String) end @unreachable "There is no entity called $name" end - - diff --git a/src/Interfaces/EmbeddedDiscretizations.jl b/src/Interfaces/EmbeddedDiscretizations.jl index 95b6ccc2..82c9486b 100644 --- a/src/Interfaces/EmbeddedDiscretizations.jl +++ b/src/Interfaces/EmbeddedDiscretizations.jl @@ -258,6 +258,15 @@ end """ Triangulation(cut::EmbeddedDiscretization[,in_or_out=PHYSICAL_IN]) + +Creates a triangulation containing the cell and subcells of the embedded domain selected by +`in_or_out`. + +- If only background cells are selected, the result will be a regular Gridap triangulation. +- If only subcells are selected, the result will be a [`SubCellTriangulation`](@ref). +- If both background cells and subcells are selected, the result will be an `AppendedTriangulation`, + containing a [`SubCellTriangulation`](@ref) and a regular Gridap triangulation. + """ function Triangulation(cut::EmbeddedDiscretization,in_or_out) Triangulation(cut,in_or_out,cut.geo) @@ -392,6 +401,9 @@ end """ EmbeddedBoundary(cut::EmbeddedDiscretization) + +Creates a triangulation containing the cut facets of the embedded domain boundary. +The result is a [`SubFacetTriangulation`](@ref). """ function EmbeddedBoundary(cut::EmbeddedDiscretization) EmbeddedBoundary(cut,cut.geo) @@ -419,7 +431,6 @@ function EmbeddedBoundary(cut::EmbeddedDiscretization,geo::CSG.Geometry) neworientation = orientation[newsubfacets] fst = SubFacetData(cut.subfacets,newsubfacets,neworientation) SubFacetTriangulation(fst,cut.bgmodel) - end function EmbeddedBoundary(cut::EmbeddedDiscretization,name1::String,name2::String) @@ -449,11 +460,15 @@ function EmbeddedBoundary(cut::EmbeddedDiscretization,geo1::CSG.Geometry,geo2::C neworientation = orientation[newsubfacets] fst = SubFacetData(cut.subfacets,newsubfacets,neworientation) SubFacetTriangulation(fst,cut.bgmodel) - end """ GhostSkeleton(cut::EmbeddedDiscretization[,in_or_out=ACTIVE_IN]) + +Creates a triangulation containing the ghost facets. Ghosts facets are defined as the facets +of the **background mesh** that are adjacent to at least one `CUT` background cell. + +Mostly used for CUT-FEM stabilisation. """ function GhostSkeleton(cut::EmbeddedDiscretization) GhostSkeleton(cut,ACTIVE_IN) diff --git a/src/Interfaces/SubCellTriangulations.jl b/src/Interfaces/SubCellTriangulations.jl index aa5139ce..dbcf2404 100644 --- a/src/Interfaces/SubCellTriangulations.jl +++ b/src/Interfaces/SubCellTriangulations.jl @@ -18,6 +18,11 @@ end # Implementation of Triangulation interface +""" + struct SubCellTriangulation{Dc,Dp} <: Triangulation{Dc,Dp} + +A triangulation for subcells. +""" struct SubCellTriangulation{Dc,Dp,T,A} <: Triangulation{Dc,Dp} subcells::SubCellData{Dc,Dp,T} bgmodel::A diff --git a/src/Interfaces/SubFacetTriangulations.jl b/src/Interfaces/SubFacetTriangulations.jl index cad6d6c0..3cc1bbb2 100644 --- a/src/Interfaces/SubFacetTriangulations.jl +++ b/src/Interfaces/SubFacetTriangulations.jl @@ -22,6 +22,11 @@ end # Implementation of the Gridap.Triangulation interface +""" + struct SubFacetTriangulation{Dc,Dp,T,A} <: Triangulation{Dc,Dp} + +A triangulation for subfacets. +""" struct SubFacetTriangulation{Dc,Dp,T,A} <: Triangulation{Dc,Dp} subfacets::SubFacetData{Dp,T} bgmodel::A From 42e77edea4716b88eca6ac89274d701b19fbbe24 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Fri, 18 Apr 2025 13:02:36 +1000 Subject: [PATCH 48/74] Finished documentation --- docs/make.jl | 3 ++- docs/src/Distributed.md | 12 +++++++++++ docs/src/GeometricalDerivatives.md | 33 ++++++++++++++++++++++++++++++ docs/src/Interfaces.md | 2 ++ docs/src/index.md | 1 + 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 docs/src/GeometricalDerivatives.md diff --git a/docs/make.jl b/docs/make.jl index 2c5569a6..fd3e61bc 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -7,6 +7,7 @@ pages = [ "Level Set Cutters" => "LevelSetCutters.md", "Aggregated FEM" => "AggregatedFEM.md", "Moment-Fitted Quadratures" => "MomentFittedQuadratures.md", + "Geometrical Derivatives" => "GeometricalDerivatives.md", "Distributed computing" => "Distributed.md", ] @@ -18,7 +19,7 @@ makedocs(; sitename = "GridapEmbedded.jl", authors = "Francesc Verdugo , Eric Neiva and Santiago Badia ", pages = pages, - warnonly = true, + warnonly = false, ) deploydocs(; diff --git a/docs/src/Distributed.md b/docs/src/Distributed.md index 56a17b59..740e228b 100644 --- a/docs/src/Distributed.md +++ b/docs/src/Distributed.md @@ -5,6 +5,18 @@ CurrentModule = GridapEmbedded.Distributed ``` +We support distributed computing through [GridapDistributed.jl](https://github.com/gridap/GridapDistributed.jl). As per usual, we design our libraries so that the high-level API is unchanged when using distributed computing. This means that for most users, the changes to your driver will be minimal. + +The following features are currently supported: + +- Level-Set Cutters +- STL Cutters + +The folowing features are not yet supported: + +- Aggregated FEM +- Moment-Fitted Quadratures + ```@autodocs Modules = [Distributed,] Order = [:type, :constant, :macro, :function] diff --git a/docs/src/GeometricalDerivatives.md b/docs/src/GeometricalDerivatives.md new file mode 100644 index 00000000..059e80da --- /dev/null +++ b/docs/src/GeometricalDerivatives.md @@ -0,0 +1,33 @@ +# Geometrical Derivatives + +```@meta +CurrentModule = GridapEmbedded +``` + +The geometrical differentiation capabilities are based on the following work: + +!!! note "Reference" + "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation", + by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis, CMAME (2025) + +To see examples of usage, please refer to the tests in `test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl`. + +## Discretize then differentiate + +```@autodocs +Modules = [GridapEmbedded.Interfaces] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/CutFaceBoundaryTriangulations.jl", +] +``` + +## Autodiff + +```@autodocs +Modules = [GridapEmbedded.LevelSetCutters] +Order = [:type, :constant, :macro, :function] +Pages = [ + "/DifferentiableTriangulations.jl", +] +``` diff --git a/docs/src/Interfaces.md b/docs/src/Interfaces.md index dadc981a..a41c22cf 100644 --- a/docs/src/Interfaces.md +++ b/docs/src/Interfaces.md @@ -81,5 +81,7 @@ EmbeddedBoundary(::EmbeddedDiscretization) GhostSkeleton(::EmbeddedDiscretization) Gridap.Geometry.BoundaryTriangulation(::EmbeddedFacetDiscretization,::Any) Gridap.Geometry.SkeletonTriangulation(::EmbeddedFacetDiscretization,::Any) +SubCellTriangulation +SubFacetTriangulation SubFacetBoundaryTriangulation ``` diff --git a/docs/src/index.md b/docs/src/index.md index 4ba7959e..7287c762 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -13,6 +13,7 @@ Pages = [ "LevelSetCutters.md", "AggregatedFEM.md", "MomentFittedQuadratures.md", + "GeometricalDerivatives.md", "Distributed.md", ] ``` From e60324300d8e7932988a40ed3719203eaa1777b2 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Fri, 18 Apr 2025 13:04:22 +1000 Subject: [PATCH 49/74] UPdated NEWS.md --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index e01661ba..5b201d6d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for distributed level-set geometries. Since PR[#99](https://github.com/gridap/GridapEmbedded.jl/pull/99). - Refactored the distributed code to allow for ghosted/unghosted geometries and triangulations. Since PR[#100](https://github.com/gridap/GridapEmbedded.jl/pull/100). +- Implemented geometrical derivatives. Since PR[#109](https://github.com/gridap/GridapEmbedded.jl/pull/109). +- Added a proper documentation. Since PR[#109](https://github.com/gridap/GridapEmbedded.jl/pull/109). ### Changed From 11421bfe99dfa805257b8f0fd6b4f5bd6f1a9971 Mon Sep 17 00:00:00 2001 From: JordiManyer Date: Fri, 18 Apr 2025 13:08:48 +1000 Subject: [PATCH 50/74] Added documentation to the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 77d0b637..d7b3c765 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Embedded finite element methods, level set surface descriptions and constructive solid geometry. +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://gridap.github.io/GridapEmbedded.jl/stable) [![Build Status](https://github.com/gridap/GridapEmbedded.jl/workflows/CI/badge.svg?branch=master)](https://github.com/gridap/GridapEmbedded.jl/actions?query=workflow%3ACI) [![Codecov](https://codecov.io/gh/gridap/GridapEmbedded.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/gridap/GridapEmbedded.jl) @@ -40,4 +41,3 @@ julia> BimaterialLinElastCutFEM.main(n=4,outputfile="results3") ``` - From 0c59722bae54b57c1b04cd52137233a7b260e50f Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 19 Apr 2025 14:03:24 +1000 Subject: [PATCH 51/74] Updated Gridap version --- Project.toml | 4 ++-- docs/src/GeometricalDerivatives.md | 2 +- .../GeometricalDifferentiationTests.jl | 19 +------------------ 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/Project.toml b/Project.toml index a020b212..049bcc05 100644 --- a/Project.toml +++ b/Project.toml @@ -30,7 +30,7 @@ FillArrays = "0.10, 0.11, 0.12, 0.13, 1" FiniteDiff = "2.27.0" ForwardDiff = "0.10.38" Graphs = "1.12.0" -Gridap = "0.17, 0.18" +Gridap = "0.18.12" GridapDistributed = "0.3, 0.4" MPI = "0.20" MiniQhull = "0.1.0, 0.2, 0.3, 0.4" @@ -42,4 +42,4 @@ FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test","FiniteDiff"] +test = ["Test", "FiniteDiff"] diff --git a/docs/src/GeometricalDerivatives.md b/docs/src/GeometricalDerivatives.md index 059e80da..82298b40 100644 --- a/docs/src/GeometricalDerivatives.md +++ b/docs/src/GeometricalDerivatives.md @@ -8,7 +8,7 @@ The geometrical differentiation capabilities are based on the following work: !!! note "Reference" "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation", - by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis, CMAME (2025) + by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis (2025) To see examples of usage, please refer to the tests in `test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl`. diff --git a/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl b/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl index 721f4623..8a90387f 100644 --- a/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl +++ b/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl @@ -4,7 +4,7 @@ module GeometricalDifferentiationTests # level set defining the cut domain. # They are based on the following work: # "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation" -# by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis, CMAME (2025) +# by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis (2025) ############################################################################################ using Test, FiniteDiff @@ -17,23 +17,6 @@ using GridapEmbedded.Interfaces: get_ghost_normal_vector using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation - -using Gridap.Fields, Gridap.Polynomials -function Arrays.return_cache( - fg::Fields.FieldGradientArray{1,Polynomials.MonomialBasis{D,V}}, - x::AbstractVector{<:Point}) where {D,V} - xi = testitem(x) - T = gradient_type(V,xi) - Polynomials._return_cache(fg,x,T,Val(false)) -end - -function Arrays.evaluate!( - cache, - fg::Fields.FieldGradientArray{1,Polynomials.MonomialBasis{D,V}}, - x::AbstractVector{<:Point}) where {D,V} - Polynomials._evaluate!(cache,fg,x,Val(false)) -end - # We general a simplicial model where the simplices are created in a symmetric way using # varycentric refinement of QUADs and HEXs. function generate_model(D,n) From 471264157844765fb78315c258a72596f9d20039 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 19 Apr 2025 14:06:03 +1000 Subject: [PATCH 52/74] Bumped version --- NEWS.md | 2 +- Project.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 5b201d6d..7cfea949 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.9.6] - 2025-04-19 ### Added diff --git a/Project.toml b/Project.toml index 049bcc05..f7dc5034 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "GridapEmbedded" uuid = "8838a6a3-0006-4405-b874-385995508d5d" authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] -version = "0.9.5" +version = "0.9.6" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From 86da7ef5b50915d81fe6c4448959b6a49525fb5c Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 19 Apr 2025 15:01:20 +1000 Subject: [PATCH 53/74] Added distributed implementation and tests --- src/Distributed/Distributed.jl | 10 + src/Distributed/DistributedDiscretizations.jl | 6 + src/Distributed/GeometricalDerivatives.jl | 56 ++++ .../CutFaceBoundaryTriangulations.jl | 23 -- .../DifferentiableTriangulations.jl | 43 +-- .../GeometricalDifferentiationTests.jl | 281 ++++++++++++++++++ test/DistributedTests/mpi/runtests_body.jl | 2 + 7 files changed, 358 insertions(+), 63 deletions(-) create mode 100644 src/Distributed/GeometricalDerivatives.jl create mode 100644 test/DistributedTests/GeometricalDifferentiationTests.jl diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index b4cf0b8e..89816e94 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -23,9 +23,14 @@ using GridapEmbedded.Interfaces: SubFacetTriangulation using GridapEmbedded.Interfaces: SubCellData using GridapEmbedded.Interfaces: SubFacetData using GridapEmbedded.Interfaces: AbstractEmbeddedDiscretization +using GridapEmbedded.Interfaces: CutFaceBoundaryTriangulation +using GridapEmbedded.Interfaces: CutFaceSkeletonTriangulation using GridapEmbedded.AgFEM: _touch_aggregated_cells! using GridapEmbedded.AgFEM: AggregateCutCellsByThreshold using GridapEmbedded.MomentFittedQuadratures: MomentFitted +using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation +using GridapEmbedded.LevelSetCutters: DifferentiableAppendedTriangulation +using GridapEmbedded.LevelSetCutters: DifferentiableTriangulationView using Gridap.Geometry: AppendedTriangulation, TriangulationView using Gridap.Geometry: get_face_to_parent_face using Gridap.Arrays: find_inverse_index_map, testitem, return_type @@ -34,6 +39,7 @@ using Gridap.FESpaces: _dof_to_DOF, _DOF_to_dof using GridapDistributed: DistributedDiscreteModel, DistributedTriangulation, DistributedMeasure using GridapDistributed: DistributedFESpace, DistributedSingleFieldFESpace +using GridapDistributed: DistributedCellField, DistributedMultiFieldCellField using GridapDistributed: NoGhost, WithGhost, filter_cells_when_needed, add_ghost_cells using GridapDistributed: generate_gids, generate_cell_gids using GridapDistributed: _find_vector_type @@ -46,12 +52,14 @@ import GridapEmbedded.Interfaces: EmbeddedBoundary import GridapEmbedded.Interfaces: compute_bgfacet_to_inoutcut import GridapEmbedded.Interfaces: compute_bgcell_to_inoutcut import GridapEmbedded.Interfaces: GhostSkeleton +import GridapEmbedded.Interfaces: get_subfacet_normal_vector, get_ghost_normal_vector, get_conormal_vector import GridapEmbedded.CSG: get_geometry import GridapEmbedded.LevelSetCutters: discretize, DiscreteGeometry import Gridap.Geometry: Triangulation import Gridap.Geometry: SkeletonTriangulation import Gridap.Geometry: BoundaryTriangulation import Gridap.Geometry: get_background_model +import Gridap.CellData: get_tangent_vector import GridapDistributed: local_views import GridapDistributed: remove_ghost_cells @@ -65,4 +73,6 @@ include("DistributedAgFEM.jl") include("DistributedQuadratures.jl") +include("GeometricalDerivatives.jl") + end # module diff --git a/src/Distributed/DistributedDiscretizations.jl b/src/Distributed/DistributedDiscretizations.jl index 5d873558..c8939060 100644 --- a/src/Distributed/DistributedDiscretizations.jl +++ b/src/Distributed/DistributedDiscretizations.jl @@ -88,6 +88,12 @@ for TT in (:Triangulation,:SkeletonTriangulation,:BoundaryTriangulation,:Embedde end end +# TODO: This should go to GridapDistributed +function get_tangent_vector(a::DistributedTriangulation) + fields = map(get_tangent_vector,local_views(a)) + DistributedCellField(fields,a) +end + # TODO: This should go to GridapDistributed function remove_ghost_cells(trian::AppendedTriangulation,gids) a = remove_ghost_cells(trian.a,gids) diff --git a/src/Distributed/GeometricalDerivatives.jl b/src/Distributed/GeometricalDerivatives.jl new file mode 100644 index 00000000..d6450be5 --- /dev/null +++ b/src/Distributed/GeometricalDerivatives.jl @@ -0,0 +1,56 @@ + + +function remove_ghost_cells( + trian::Union{<:CutFaceBoundaryTriangulation,<:CutFaceSkeletonTriangulation},gids +) + model = get_background_model(trian) + Dm = num_cell_dims(model) + glue = get_glue(trian,Val(Dm)) + remove_ghost_cells(glue,trian,gids) +end + +for func in (:get_subfacet_normal_vector,:get_ghost_normal_vector,:get_conormal_vector) + @eval begin + function $func(a::DistributedTriangulation) + fields = map($func,local_views(a)) + DistributedCellField(fields,a) + end + end +end + +function LevelSetCutters.DifferentiableTriangulation(trian::DistributedTriangulation,fe_space) + model = get_background_model(trian) + trians = map(DifferentiableTriangulation,local_views(trian),local_views(fe_space)) + return DistributedTriangulation(trians,model) +end + +function FESpaces._change_argument( + op,f, + local_trians::AbstractArray{<:Union{<:DifferentiableTriangulation,<:DifferentiableAppendedTriangulation,<:DifferentiableTriangulationView}}, + uh::GridapDistributed.DistributedADTypes +) + function dist_cf(uh::DistributedCellField,cfs) + DistributedCellField(cfs,get_triangulation(uh)) + end + function dist_cf(uh::DistributedMultiFieldCellField,cfs) + sf_cfs = map(DistributedCellField, + [tuple_of_arrays(map(cf -> Tuple(cf.single_fields),cfs))...], + map(get_triangulation,uh) + ) + DistributedMultiFieldCellField(sf_cfs,cfs) + end + + uhs = local_views(uh) + spaces = map(get_fe_space,uhs) + function g(cell_u) + cfs = map(CellField,spaces,cell_u) + cf = dist_cf(uh,cfs) + map(update_trian!,local_trians,spaces,local_views(cf)) + cg = f(cf) + map(local_trians,spaces) do Ω, V + update_trian!(Ω,V,nothing) + end + map(get_contribution,local_views(cg),local_trians) + end + g +end diff --git a/src/Interfaces/CutFaceBoundaryTriangulations.jl b/src/Interfaces/CutFaceBoundaryTriangulations.jl index e85e70cc..63f7b2ca 100644 --- a/src/Interfaces/CutFaceBoundaryTriangulations.jl +++ b/src/Interfaces/CutFaceBoundaryTriangulations.jl @@ -393,29 +393,6 @@ for func in (:get_tangent_vector,:get_subfacet_normal_vector,:get_ghost_normal_v end end -# Distributed -# Until we merge, we need changes in -# - GridapDistributed#master -# - GridapEmbedded#distributed - -# function GridapDistributed.remove_ghost_cells( -# trian::Union{<:CutFaceBoundaryTriangulation,<:CutFaceSkeletonTriangulation},gids -# ) -# model = get_background_model(trian) -# Dm = num_cell_dims(model) -# glue = get_glue(trian,Val(Dm)) -# GridapDistributed.remove_ghost_cells(glue,trian,gids) -# end -# -# for func in (:get_subfacet_normal_vector,:get_ghost_normal_vector,:get_conormal_vector,:get_tangent_vector) -# @eval begin -# function $func(a::DistributedTriangulation) -# fields = map($func,local_views(a)) -# DistributedCellField(fields,a) -# end -# end -# end - ############################################################################################ # This will go to Gridap diff --git a/src/LevelSetCutters/DifferentiableTriangulations.jl b/src/LevelSetCutters/DifferentiableTriangulations.jl index 74e39dbe..af6baa97 100644 --- a/src/LevelSetCutters/DifferentiableTriangulations.jl +++ b/src/LevelSetCutters/DifferentiableTriangulations.jl @@ -473,6 +473,8 @@ end # This is mostly used in distributed, where we remove ghost cells by taking a view # of the local triangulations. +const DifferentiableTriangulationView{Dc,Dp} = Geometry.TriangulationView{Dc,Dp,<:Union{<:DifferentiableTriangulation,<:DifferentiableAppendedTriangulation}} + function DifferentiableTriangulation( trian :: Geometry.TriangulationView, fe_space :: FESpace @@ -487,7 +489,7 @@ function update_trian!(trian::Geometry.TriangulationView,U,φh) end function FESpaces._change_argument( - op,f,trian::Geometry.TriangulationView,uh + op,f,trian::DifferentiableTriangulationView,uh ) U = get_fe_space(uh) function g(cell_u) @@ -499,42 +501,3 @@ function FESpaces._change_argument( end g end - -#### DistributedTriangulations - -# function DifferentiableTriangulation(trian::DistributedTriangulation,fe_space) -# model = get_background_model(trian) -# trians = map(DifferentiableTriangulation,local_views(trian),local_views(fe_space)) -# return DistributedTriangulation(trians,model) -# end -# -# function FESpaces._change_argument( -# op,f, -# local_trians::AbstractArray{<:Union{<:DifferentiableTriangulation,<:DifferentiableAppendedTriangulation,<:TriangulationView}}, -# uh::GridapDistributed.DistributedADTypes -# ) -# function dist_cf(uh::DistributedCellField,cfs) -# DistributedCellField(cfs,get_triangulation(uh)) -# end -# function dist_cf(uh::DistributedMultiFieldCellField,cfs) -# sf_cfs = map(DistributedCellField, -# [tuple_of_arrays(map(cf -> Tuple(cf.single_fields),cfs))...], -# map(get_triangulation,uh) -# ) -# DistributedMultiFieldCellField(sf_cfs,cfs) -# end -# -# uhs = local_views(uh) -# spaces = map(get_fe_space,uhs) -# function g(cell_u) -# cfs = map(CellField,spaces,cell_u) -# cf = dist_cf(uh,cfs) -# map(update_trian!,local_trians,spaces,local_views(cf)) -# cg = f(cf) -# map(local_trians,spaces) do Ω, V -# update_trian!(Ω,V,nothing) -# end -# map(get_contribution,local_views(cg),local_trians) -# end -# g -# end diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl new file mode 100644 index 00000000..2eebf1e8 --- /dev/null +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -0,0 +1,281 @@ +module DistributedGeometricalDifferentitationTests +############################################################################################ +# These tests are meant to verify the correctness differentiation of functionals w.r.t the +# level set defining the cut domain. +# They are based on the following work: +# "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation" +# by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis (2025) +############################################################################################ +using Test + +using Gridap, Gridap.Geometry, Gridap.Adaptivity +using GridapEmbedded, GridapEmbedded.Interfaces, GridapEmbedded.LevelSetCutters + +using GridapDistributed, PartitionedArrays + +using Gridap.Arrays: Operation +using GridapTopOpt: get_conormal_vector,get_subfacet_normal_vector,get_ghost_normal_vector + +function generate_model(D,n,ranks,mesh_partition) + domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1) + cell_partition = (D==2) ? (n,n) : (n,n,n) + base_model = UnstructuredDiscreteModel(CartesianDiscreteModel(ranks,mesh_partition,domain,cell_partition)) + ref_model = refine(base_model, refinement_method = "barycentric") + model = Adaptivity.get_model(ref_model) + return model +end + +function level_set(shape::Symbol;N=4) + if shape == :square + x -> max(abs(x[1]-0.5),abs(x[2]-0.5))-0.25 # Square + elseif shape == :corner_2d + x -> ((x[1]-0.5)^N+(x[2]-0.5)^N)^(1/N)-0.25 # Curved corner + elseif shape == :diamond + x -> abs(x[1]-0.5)+abs(x[2]-0.5)-0.25-0/n/10 # Diamond + elseif shape == :circle + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.5223 # Circle + elseif shape == :circle_2 + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.23 # Circle + elseif shape == :square_prism + x -> max(abs(x[1]-0.5),abs(x[2]-0.5),abs(x[3]-0.5))-0.25 # Square prism + elseif shape == :corner_3d + x -> ((x[1]-0.5)^N+(x[2]-0.5)^N+(x[3]-0.5)^N)^(1/N)-0.25 # Curved corner + elseif shape == :diamond_prism + x -> abs(x[1]-0.5)+abs(x[2]-0.5)+abs(x[3]-0.5)-0.25-0/n/10 # Diamond prism + elseif shape == :sphere + x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2+(x[3]-0.5)^2)-0.53 # Sphere + elseif shape == :regular_2d + x -> cos(2π*x[1])*cos(2π*x[2])-0.11 # "Regular" LSF + elseif shape == :regular_3d + x -> cos(2π*x[1])*cos(2π*x[2])*cos(2π*x[3])-0.11 # "Regular" LSF + else + error("Unknown shape") + end +end + +function main_generic( + model,φ::Function,f::Function +) + order = 1 + reffe = ReferenceFE(lagrangian,Float64,order) + V_φ = TestFESpace(model,reffe) + + U = TestFESpace(model,reffe) + + φh = interpolate(φ,V_φ) + fh = interpolate(f,V_φ) + uh = interpolate(x->x[1]+x[2],U) + + geo = DiscreteGeometry(φh,model) + cutgeo = cut(model,geo) + + # A.1) Volume integral + + Ω = Triangulation(cutgeo,PHYSICAL_IN) + Ω_AD = DifferentiableTriangulation(Ω,V_φ) + dΩ = Measure(Ω_AD,2*order) + + Γ = EmbeddedBoundary(cutgeo) + n_Γ = get_normal_vector(Γ) + dΓ = Measure(Γ,2*order) + + J_bulk(φ) = ∫(fh)dΩ + dJ_bulk_AD = gradient(J_bulk,φh) + dJ_bulk_AD_vec = assemble_vector(dJ_bulk_AD,V_φ) + + dJ_bulk_exact(q) = ∫(-fh*q/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_exact_vec = assemble_vector(dJ_bulk_exact,V_φ) + + @test norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec) < 1e-10 + + # A.1.1) Volume integral with another field + + J_bulk_1(u,φ) = ∫(u+fh)dΩ + dJ_bulk_1_AD = gradient(φ->J_bulk_1(uh,φ),φh) + dJ_bulk_1_AD_vec = assemble_vector(dJ_bulk_1_AD,V_φ) + + dJ_bulk_1_exact(q,u) = ∫(-(u+fh)*q/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_1_exact_vec = assemble_vector(q->dJ_bulk_1_exact(q,uh),V_φ) + + @test norm(dJ_bulk_1_AD_vec - dJ_bulk_1_exact_vec) < 1e-10 + + J_bulk_1(u,φ) = ∫(u+fh)dΩ + dJ_bulk_1_AD_in_u = gradient(u->J_bulk_1(u,φh),uh) + dJ_bulk_1_AD_in_u_vec = assemble_vector(dJ_bulk_1_AD_in_u,U) + + dJ_bulk_1_exact_in_u(q,u) = ∫(q)dΩ + dJ_bulk_1_exact_in_u_vec = assemble_vector(q->dJ_bulk_1_exact_in_u(q,uh),U) + + @test norm(dJ_bulk_1_AD_in_u_vec - dJ_bulk_1_exact_in_u_vec) < 1e-10 + + # A.2) Volume integral + + g(fh) = ∇(fh)⋅∇(fh) + J_bulk2(φ) = ∫(g(fh))dΩ + dJ_bulk_AD2 = gradient(J_bulk2,φh) + dJ_bulk_AD_vec2 = assemble_vector(dJ_bulk_AD2,V_φ) + + dJ_bulk_exact2(q) = ∫(-g(fh)*q/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_exact_vec2 = assemble_vector(dJ_bulk_exact2,V_φ) + + @test norm(dJ_bulk_AD_vec2 - dJ_bulk_exact_vec2) < 1e-10 + + # B.1) Facet integral + + Γ = EmbeddedBoundary(cutgeo) + n_Γ = get_normal_vector(Γ) + Γ_AD = DifferentiableTriangulation(Γ,V_φ) + Λ = Skeleton(Γ) + Σ = Boundary(Γ) + + dΓ = Measure(Γ,2*order) + dΛ = Measure(Λ,2*order) + dΣ = Measure(Σ,2*order) + + n_Γ = get_normal_vector(Γ) + + n_S_Λ = get_normal_vector(Λ) + m_k_Λ = get_conormal_vector(Λ) + ∇ˢφ_Λ = Operation(abs)(n_S_Λ ⋅ ∇(φh).plus) + + n_S_Σ = get_normal_vector(Σ) + m_k_Σ = get_conormal_vector(Σ) + ∇ˢφ_Σ = Operation(abs)(n_S_Σ ⋅ ∇(φh)) + + dΓ_AD = Measure(Γ_AD,2*order) + J_int(φ) = ∫(fh)dΓ_AD + dJ_int_AD = gradient(J_int,φh) + dJ_int_AD_vec = assemble_vector(dJ_int_AD,V_φ) + + dJ_int_exact(w) = ∫((-n_Γ⋅∇(fh))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + + ∫(-n_S_Λ ⋅ (jump(fh*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ + + ∫(-n_S_Σ ⋅ (fh*m_k_Σ * w / ∇ˢφ_Σ))dΣ + dJ_int_exact_vec = assemble_vector(dJ_int_exact,V_φ) + + @test norm(dJ_int_AD_vec - dJ_int_exact_vec) < 1e-10 + + # B.2) Facet integral + g(fh) = ∇(fh)⋅∇(fh) + + J_int2(φ) = ∫(g(fh))dΓ_AD + dJ_int_AD2 = gradient(J_int2,φh) + dJ_int_AD_vec2 = assemble_vector(dJ_int_AD2,V_φ) + + ∇g(∇∇f,∇f) = ∇∇f⋅∇f + ∇f⋅∇∇f + dJ_int_exact2(w) = ∫((-n_Γ⋅ (∇g ∘ (∇∇(fh),∇(fh))))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + + ∫(-n_S_Λ ⋅ (jump(g(fh)*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ + + ∫(-n_S_Σ ⋅ (g(fh)*m_k_Σ * w / ∇ˢφ_Σ))dΣ + dJ_int_exact_vec2 = assemble_vector(dJ_int_exact2,V_φ) + + @test norm(dJ_int_AD_vec2 - dJ_int_exact_vec2) < 1e-10 + +end + +## Concering integrals of the form `φ->∫(f ⋅ n(φ))dΓ(φ)` +function main_normal( + model,φ::Function,f::Function; + vtk=false, + name="embedded", + run_test=true +) + order = 1 + reffe = ReferenceFE(lagrangian,Float64,order) + V_φ = TestFESpace(model,reffe) + + φh = interpolate(φ,V_φ) + + geo = DiscreteGeometry(φh,model) + cutgeo = cut(model,geo) + + Γ = EmbeddedBoundary(cutgeo) + n_Γ = get_normal_vector(Γ) + Γ_AD = DifferentiableTriangulation(Γ,V_φ) + dΓ_AD = Measure(Γ_AD,2*order) + dΓ = Measure(Γ,2*order) + + fh_Γ = CellField(f,Γ) + fh_Γ_AD = CellField(f,Γ_AD) + + function J_int(φ) + n = get_normal_vector(Γ_AD) + ∫(fh_Γ_AD⋅n)dΓ_AD + end + dJ_int_AD = gradient(J_int,φh) + dJ_int_AD_vec = assemble_vector(dJ_int_AD,V_φ) + + _n(∇φ) = ∇φ/(10^-20+norm(∇φ)) + dJ_int_phi = ∇(φ->∫(fh_Γ_AD ⋅ (_n ∘ (∇(φ))))dΓ_AD,φh) + dJh_int_phi = assemble_vector(dJ_int_phi,V_φ) + + run_test && @test norm(dJ_int_AD_vec - dJh_int_phi) < 1e-10 + + # Analytic + # Note: currently, the analytic result is only valid on closed domains thanks + # to the divergence theorem. I think it would take significant work to compute + # the analytic derivative generally as we can't rely on divergence theorem to + # rewrite it in a convenient way. As a result, we don't have an analytic result + # for general cases such as ∫( f(n(φ)) )dΓ(φ), nor the case when Γ intersects + # ∂D. Thankfully, we have AD instead ;) + # Note 2: For the case that Γ does intersect the surface, the result is correct + # everywhere except on the intersection. + + fh2(x) = VectorValue((1-x[1])^2,(1-x[2])^2) + fh_Γ = CellField(fh2,Γ) + fh_Γ_AD = CellField(fh2,Γ_AD) + + # Note: this comes from rewriting via the divergence theorem: + # ∫(f ⋅ n(φ))dΓ(φ) = ∫(∇⋅f)dΩ(φ) + dJ_int_exact3(w) = ∫(-(∇⋅(fh_Γ))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJh_int_exact3 = assemble_vector(dJ_int_exact3,V_φ) + + run_test && @test norm(dJh_int_exact3 - dJ_int_AD_vec) < 1e-10 + + if vtk + path = "results/$(name)" + Ω_bg = Triangulation(model) + writevtk(Ω_bg,path,cellfields=[ + "dJ_AD"=>FEFunction(V_φ,dJ_int_AD_vec), + "dJ_AD_with_phi"=>FEFunction(V_φ,dJh_int_phi), + "dJ_exact"=>FEFunction(V_φ,dJh_int_exact3) + ]) + end +end + +####################### + +function main(distribute,np) + @assert np == 4 + + # 2D + mesh_partition = (2,2) + ranks = distribute(LinearIndices((prod(mesh_partition),))) + D = 2 + n = 10 + model = generate_model(D,n,ranks,mesh_partition) + + φ0 = level_set(:circle_2) + f0((x,y)) = VectorValue((1-x)^2,(1-y)^2) + main_normal(model,φ0,f0;vtk=true) + + φ1 = level_set(:circle) + f1 = x -> 1.0 + main_generic(model,φ1,f1) + + model = generate_model(D,n,ranks,mesh_partition) + φ2 = level_set(:circle) + f2 = x -> x[1]+x[2] + main_generic(model,φ2,f2) + + # 3D + mesh_partition = (2,2,1) + ranks = distribute(LinearIndices((prod(mesh_partition),))) + D = 3 + n = 8 + model = generate_model(D,n,ranks,mesh_partition) + + φ3 = level_set(:regular_3d) + f3 = x -> x[1]+x[2] + main_generic(model,φ3,f3) +end + +end \ No newline at end of file diff --git a/test/DistributedTests/mpi/runtests_body.jl b/test/DistributedTests/mpi/runtests_body.jl index d0510c01..ddce7ee4 100644 --- a/test/DistributedTests/mpi/runtests_body.jl +++ b/test/DistributedTests/mpi/runtests_body.jl @@ -9,6 +9,7 @@ include("../AggregatesTests.jl") include("../DistributedDiscreteGeometryPoissonTest.jl") include("../DistributedLSDiscreteGeometryPoissonTest.jl") include("../PeriodicDistributedDiscreteGeometryPoissonTest.jl") +include("../GeometricalDifferentiationTests.jl") if ! MPI.Initialized() MPI.Init() @@ -41,6 +42,7 @@ function all_tests(distribute,parts) if prod(parts) == 4 DistributedAggregatesTests.main(distribute,parts) + DistributedGeometricalDifferentitationTests.main(distribute,4) end PArrays.toc!(t,"Aggregates") From 23bea0d1f0ba51b9135a4dbd3c1019236791a927 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 19 Apr 2025 15:27:28 +1000 Subject: [PATCH 54/74] Minor --- test/DistributedTests/GeometricalDifferentiationTests.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 2eebf1e8..30b6c506 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -14,7 +14,8 @@ using GridapEmbedded, GridapEmbedded.Interfaces, GridapEmbedded.LevelSetCutters using GridapDistributed, PartitionedArrays using Gridap.Arrays: Operation -using GridapTopOpt: get_conormal_vector,get_subfacet_normal_vector,get_ghost_normal_vector +using Gridap.CellData: get_tangent_vector, get_normal_vector +using GridapEmbedded.Interfaces: get_conormal_vector, get_subfacet_normal_vector, get_ghost_normal_vector function generate_model(D,n,ranks,mesh_partition) domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1) From 224d06beeef5b1bb545645a0b0348ed6428d3d57 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 19 Apr 2025 16:10:46 +1000 Subject: [PATCH 55/74] Minor --- test/DistributedTests/GeometricalDifferentiationTests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 30b6c506..4e4dbe91 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -17,6 +17,8 @@ using Gridap.Arrays: Operation using Gridap.CellData: get_tangent_vector, get_normal_vector using GridapEmbedded.Interfaces: get_conormal_vector, get_subfacet_normal_vector, get_ghost_normal_vector +using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation + function generate_model(D,n,ranks,mesh_partition) domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1) cell_partition = (D==2) ? (n,n) : (n,n,n) From f89f6be040c54355c0beffb6754df3c9e03b4558 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 19 Apr 2025 17:37:31 +1000 Subject: [PATCH 56/74] Minor --- src/Distributed/Distributed.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index 89816e94..44ec7802 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -31,6 +31,7 @@ using GridapEmbedded.MomentFittedQuadratures: MomentFitted using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation using GridapEmbedded.LevelSetCutters: DifferentiableAppendedTriangulation using GridapEmbedded.LevelSetCutters: DifferentiableTriangulationView +using GridapEmbedded.LevelSetCutters: update_trian! using Gridap.Geometry: AppendedTriangulation, TriangulationView using Gridap.Geometry: get_face_to_parent_face using Gridap.Arrays: find_inverse_index_map, testitem, return_type From 2e20ac5b166f64ba86e2f2444994d38162a79535 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Fri, 2 May 2025 17:32:58 +1000 Subject: [PATCH 57/74] Bugfixes --- .gitignore | 1 + Project.toml | 35 +++++----- src/Distributed/Distributed.jl | 1 + .../DistributedSubFacetTriangulations.jl | 19 +++++ .../DifferentiableTriangulations.jl | 69 ++++++++++--------- .../GeometricalDifferentiationTests.jl | 26 ++++--- 6 files changed, 89 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index 97dd38a8..1c9b9a66 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,6 @@ /docs/build/ /docs/site/ Manifest.toml +LocalPreferences.toml .vscode/ *.swp diff --git a/Project.toml b/Project.toml index f7dc5034..8bb35cc1 100644 --- a/Project.toml +++ b/Project.toml @@ -1,8 +1,24 @@ +authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] name = "GridapEmbedded" uuid = "8838a6a3-0006-4405-b874-385995508d5d" -authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] version = "0.9.6" +[compat] +AbstractTrees = "0.3.3, 0.4" +Algoim = "0.2.2" +Combinatorics = "1" +CxxWrap = "0.16" +FillArrays = "0.10, 0.11, 0.12, 0.13, 1" +FiniteDiff = "2.27.0" +ForwardDiff = "0.10.38, 1" +Graphs = "1.12.0" +Gridap = "0.18.12" +GridapDistributed = "0.3, 0.4" +MPI = "0.20" +MiniQhull = "0.1.0, 0.2, 0.3, 0.4" +PartitionedArrays = "0.3.4" +julia = "1.3" + [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" Algoim = "0eb9048c-21de-4c7a-bfac-056de1940b74" @@ -21,24 +37,9 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" algoimWrapper_jll = "3c43aa7b-5398-51f3-8d75-8f051e6faa4d" -[compat] -AbstractTrees = "0.3.3, 0.4" -Algoim = "0.2.2" -Combinatorics = "1" -CxxWrap = "0.16" -FillArrays = "0.10, 0.11, 0.12, 0.13, 1" -FiniteDiff = "2.27.0" -ForwardDiff = "0.10.38" -Graphs = "1.12.0" -Gridap = "0.18.12" -GridapDistributed = "0.3, 0.4" -MPI = "0.20" -MiniQhull = "0.1.0, 0.2, 0.3, 0.4" -PartitionedArrays = "0.3.4" -julia = "1.3" - [extras] FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" +MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] diff --git a/src/Distributed/Distributed.jl b/src/Distributed/Distributed.jl index 44ec7802..97d6e7ba 100644 --- a/src/Distributed/Distributed.jl +++ b/src/Distributed/Distributed.jl @@ -60,6 +60,7 @@ import Gridap.Geometry: Triangulation import Gridap.Geometry: SkeletonTriangulation import Gridap.Geometry: BoundaryTriangulation import Gridap.Geometry: get_background_model +import Gridap.Geometry: num_cells import Gridap.CellData: get_tangent_vector import GridapDistributed: local_views import GridapDistributed: remove_ghost_cells diff --git a/src/Distributed/DistributedSubFacetTriangulations.jl b/src/Distributed/DistributedSubFacetTriangulations.jl index d47c3501..b9ffaa46 100644 --- a/src/Distributed/DistributedSubFacetTriangulations.jl +++ b/src/Distributed/DistributedSubFacetTriangulations.jl @@ -61,3 +61,22 @@ function GridapDistributed.add_ghost_cells( end return ghosted_trian end + +function num_cells(trian::DistributedSubFacetTriangulation) + model = get_background_model(trian) + Dc = num_cell_dims(model) + gids = get_face_gids(model,Dc) + n_loc_ocells = map(local_views(trian),partition(gids)) do trian, gids + glue = get_glue(trian,Val(Dc)) + @assert isa(glue,FaceToFaceGlue) + tcell_to_mcell = glue.tface_to_mface + if isa(tcell_to_mcell,IdentityVector) + own_length(gids) + else + mcell_to_owned = local_to_own(gids) + is_owned(mcell) = !iszero(mcell_to_owned[mcell]) + sum(is_owned,tcell_to_mcell;init=0) + end + end + return sum(n_loc_ocells) +end diff --git a/src/LevelSetCutters/DifferentiableTriangulations.jl b/src/LevelSetCutters/DifferentiableTriangulations.jl index af6baa97..19ef9238 100644 --- a/src/LevelSetCutters/DifferentiableTriangulations.jl +++ b/src/LevelSetCutters/DifferentiableTriangulations.jl @@ -423,6 +423,39 @@ function extract_dualized_cell_values( return bgcell_to_values end +# TriangulationView +# This is mostly used in distributed, where we remove ghost cells by taking a view +# of the local triangulations. + +const DifferentiableTriangulationView{Dc,Dp} = Geometry.TriangulationView{Dc,Dp,<:DifferentiableTriangulation} + +function DifferentiableTriangulation( + trian :: Geometry.TriangulationView, + fe_space :: FESpace +) + parent = DifferentiableTriangulation(trian.parent,fe_space) + return Geometry.TriangulationView(parent,trian.cell_to_parent_cell) +end + +function update_trian!(trian::Geometry.TriangulationView,U,φh) + update_trian!(trian.parent,U,φh) + return trian +end + +function FESpaces._change_argument( + op,f,trian::DifferentiableTriangulationView,uh +) + U = get_fe_space(uh) + function g(cell_u) + cf = CellField(U,cell_u) + update_trian!(trian,U,cf) + cell_grad = f(cf) + update_trian!(trian,U,nothing) + get_contribution(cell_grad,trian) + end + g +end + # AppendedTriangulation # # When cutting an embedded domain, we will usually end up with an AppendedTriangulation @@ -432,7 +465,8 @@ end # We only need to propagate the dual numbers to the CUT cells, which is what the # following implementation does: -const DifferentiableAppendedTriangulation{Dc,Dp,A} = AppendedTriangulation{Dc,Dp,<:DifferentiableTriangulation} +const DifferentiableAppendedTriangulation{Dc,Dp,A} = + AppendedTriangulation{Dc,Dp,<:Union{<:DifferentiableTriangulation,<:DifferentiableTriangulationView{Dc,Dp}}} function DifferentiableTriangulation( trian::AppendedTriangulation, fe_space::FESpace @@ -468,36 +502,3 @@ function FESpaces._compute_cell_ids(uh,ttrian::AppendedTriangulation) ids_b = FESpaces._compute_cell_ids(uh,ttrian.b) lazy_append(ids_a,ids_b) end - -# TriangulationView -# This is mostly used in distributed, where we remove ghost cells by taking a view -# of the local triangulations. - -const DifferentiableTriangulationView{Dc,Dp} = Geometry.TriangulationView{Dc,Dp,<:Union{<:DifferentiableTriangulation,<:DifferentiableAppendedTriangulation}} - -function DifferentiableTriangulation( - trian :: Geometry.TriangulationView, - fe_space :: FESpace -) - parent = DifferentiableTriangulation(trian.parent,fe_space) - return Geometry.TriangulationView(parent,trian.cell_to_parent_cell) -end - -function update_trian!(trian::Geometry.TriangulationView,U,φh) - update_trian!(trian.parent,U,φh) - return trian -end - -function FESpaces._change_argument( - op,f,trian::DifferentiableTriangulationView,uh -) - U = get_fe_space(uh) - function g(cell_u) - cf = CellField(U,cell_u) - update_trian!(trian,U,cf) - cell_grad = f(cf) - update_trian!(trian,U,nothing) - get_contribution(cell_grad,trian) - end - g -end diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 4e4dbe91..a1739e72 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -18,6 +18,7 @@ using Gridap.CellData: get_tangent_vector, get_normal_vector using GridapEmbedded.Interfaces: get_conormal_vector, get_subfacet_normal_vector, get_ghost_normal_vector using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation +using GridapDistributed: i_am_main function generate_model(D,n,ranks,mesh_partition) domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1) @@ -69,6 +70,12 @@ function main_generic( fh = interpolate(f,V_φ) uh = interpolate(x->x[1]+x[2],U) + map(partition(get_free_dof_values(φh))) do x_φ + idx = findall(isapprox(0.0;atol=10^-10),x_φ) + !isempty(idx) && @info "Correcting level values!" + x_φ[idx] .+= 100*eps(eltype(x_φ)) + end + geo = DiscreteGeometry(φh,model) cutgeo = cut(model,geo) @@ -102,7 +109,6 @@ function main_generic( @test norm(dJ_bulk_1_AD_vec - dJ_bulk_1_exact_vec) < 1e-10 - J_bulk_1(u,φ) = ∫(u+fh)dΩ dJ_bulk_1_AD_in_u = gradient(u->J_bulk_1(u,φh),uh) dJ_bulk_1_AD_in_u_vec = assemble_vector(dJ_bulk_1_AD_in_u,U) @@ -158,20 +164,19 @@ function main_generic( @test norm(dJ_int_AD_vec - dJ_int_exact_vec) < 1e-10 # B.2) Facet integral - g(fh) = ∇(fh)⋅∇(fh) - J_int2(φ) = ∫(g(fh))dΓ_AD + h(fh) = ∇(fh)⋅∇(fh) + J_int2(φ) = ∫(h(fh))dΓ_AD dJ_int_AD2 = gradient(J_int2,φh) dJ_int_AD_vec2 = assemble_vector(dJ_int_AD2,V_φ) ∇g(∇∇f,∇f) = ∇∇f⋅∇f + ∇f⋅∇∇f dJ_int_exact2(w) = ∫((-n_Γ⋅ (∇g ∘ (∇∇(fh),∇(fh))))*w/(abs(n_Γ ⋅ ∇(φh))))dΓ + - ∫(-n_S_Λ ⋅ (jump(g(fh)*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ + - ∫(-n_S_Σ ⋅ (g(fh)*m_k_Σ * w / ∇ˢφ_Σ))dΣ + ∫(-n_S_Λ ⋅ (jump(h(fh)*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ + + ∫(-n_S_Σ ⋅ (h(fh)*m_k_Σ * w / ∇ˢφ_Σ))dΣ dJ_int_exact_vec2 = assemble_vector(dJ_int_exact2,V_φ) @test norm(dJ_int_AD_vec2 - dJ_int_exact_vec2) < 1e-10 - end ## Concering integrals of the form `φ->∫(f ⋅ n(φ))dΓ(φ)` @@ -258,15 +263,14 @@ function main(distribute,np) φ0 = level_set(:circle_2) f0((x,y)) = VectorValue((1-x)^2,(1-y)^2) - main_normal(model,φ0,f0;vtk=true) + main_normal(model,φ0,f0) φ1 = level_set(:circle) - f1 = x -> 1.0 + f1(x) = 1.0 main_generic(model,φ1,f1) - model = generate_model(D,n,ranks,mesh_partition) φ2 = level_set(:circle) - f2 = x -> x[1]+x[2] + f2(x) = x[1] + x[2] main_generic(model,φ2,f2) # 3D @@ -277,7 +281,7 @@ function main(distribute,np) model = generate_model(D,n,ranks,mesh_partition) φ3 = level_set(:regular_3d) - f3 = x -> x[1]+x[2] + f3(x) = x[1] + x[2] + x[3] main_generic(model,φ3,f3) end From d5ed89efe825026072ec011f3fa10f1e7617e34d Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Sat, 3 May 2025 09:10:15 +1000 Subject: [PATCH 58/74] Minor --- .../DistributedSubFacetTriangulations.jl | 13 +++++++++++++ .../GeometricalDifferentiationTests.jl | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Distributed/DistributedSubFacetTriangulations.jl b/src/Distributed/DistributedSubFacetTriangulations.jl index b9ffaa46..efb3e8b0 100644 --- a/src/Distributed/DistributedSubFacetTriangulations.jl +++ b/src/Distributed/DistributedSubFacetTriangulations.jl @@ -24,6 +24,19 @@ function GridapDistributed.generate_cell_gids( return PRange(fgids) end +# function GridapDistributed.generate_cell_gids( +# trian::DistributedSubFacetTriangulation{Df,Dc}, +# ) where {Df,Dc} +# model = get_background_model(trian) +# ctrians = map(local_views(trian),local_views(model)) do trian, model +# glue = get_glue(trian,Val(Dc)) # Glue from cut facets to background cells +# facet_to_bgcell = glue.tface_to_mface +# Triangulation(model,facet_to_bgcell) +# end +# ctrian = GridapDistributed.DistributedTriangulation(ctrians,model) +# return GridapDistributed.generate_cell_gids(ctrian) +# end + function GridapDistributed.add_ghost_cells( trian::DistributedSubFacetTriangulation{Df,Dc}, ) where {Df,Dc} diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index a1739e72..28a8ebc6 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -258,18 +258,21 @@ function main(distribute,np) mesh_partition = (2,2) ranks = distribute(LinearIndices((prod(mesh_partition),))) D = 2 - n = 10 + n = 12 model = generate_model(D,n,ranks,mesh_partition) + i_am_main(ranks) && println(" >> Case 0") φ0 = level_set(:circle_2) f0((x,y)) = VectorValue((1-x)^2,(1-y)^2) main_normal(model,φ0,f0) - φ1 = level_set(:circle) + i_am_main(ranks) && println(" >> Case 1") + φ1 = level_set(:circle_2) f1(x) = 1.0 main_generic(model,φ1,f1) - φ2 = level_set(:circle) + i_am_main(ranks) && println(" >> Case 2") + φ2 = level_set(:circle_2) f2(x) = x[1] + x[2] main_generic(model,φ2,f2) @@ -280,6 +283,7 @@ function main(distribute,np) n = 8 model = generate_model(D,n,ranks,mesh_partition) + i_am_main(ranks) && println(" >> Case 3") φ3 = level_set(:regular_3d) f3(x) = x[1] + x[2] + x[3] main_generic(model,φ3,f3) From bbd20ef04f1a80feaf70b0ed0c5f2736355d7a4b Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Mon, 5 May 2025 23:09:51 +1000 Subject: [PATCH 59/74] Bugfix --- .../DistributedSubFacetTriangulations.jl | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/Distributed/DistributedSubFacetTriangulations.jl b/src/Distributed/DistributedSubFacetTriangulations.jl index efb3e8b0..51c0099a 100644 --- a/src/Distributed/DistributedSubFacetTriangulations.jl +++ b/src/Distributed/DistributedSubFacetTriangulations.jl @@ -8,34 +8,33 @@ function GridapDistributed.generate_cell_gids( ) where {Df,Dc} model = get_background_model(trian) cgids = get_cell_gids(model) - - n_lfacets = map(num_cells,local_views(trian)) - first_gid = scan(+,n_lfacets,type=:exclusive,init=one(eltype(n_lfacets))) - n_facets = reduce(+,n_lfacets,init=zero(eltype(n_lfacets))) - fgids = map(local_views(trian),partition(cgids),first_gid,n_lfacets) do trian, cgids, first_gid, n_lfacets - glue = get_glue(trian,Val(Dc)) # Glue from cut facets to background cells - facet_to_bgcell = glue.tface_to_mface + n_lfacets, bgcell_to_lfacets = map(local_views(trian)) do trian + model = get_background_model(trian) + lfacet_to_bgcell = get_glue(trian,Val(Dc)).tface_to_mface + n_lfacets = length(lfacet_to_bgcell) - facet_to_gid = collect(first_gid:(first_gid+n_lfacets-1)) - facet_to_owner = local_to_owner(cgids)[facet_to_bgcell] - LocalIndices(n_facets,part_id(cgids),facet_to_gid,facet_to_owner) - end - return PRange(fgids) -end + ptrs = zeros(Int32,num_cells(model)+1) + for bgcell in lfacet_to_bgcell + ptrs[bgcell+1] += 1 + end + Arrays.length_to_ptrs!(ptrs) + @assert ptrs[end] == n_lfacets+1 + + data = zeros(Int32,n_lfacets) + for (lfacet,bgcell) in enumerate(lfacet_to_bgcell) + data[ptrs[bgcell]] = lfacet + ptrs[bgcell] += 1 + end + Arrays.rewind_ptrs!(ptrs) + + return n_lfacets, Table(data,ptrs) + end |> tuple_of_arrays -# function GridapDistributed.generate_cell_gids( -# trian::DistributedSubFacetTriangulation{Df,Dc}, -# ) where {Df,Dc} -# model = get_background_model(trian) -# ctrians = map(local_views(trian),local_views(model)) do trian, model -# glue = get_glue(trian,Val(Dc)) # Glue from cut facets to background cells -# facet_to_bgcell = glue.tface_to_mface -# Triangulation(model,facet_to_bgcell) -# end -# ctrian = GridapDistributed.DistributedTriangulation(ctrians,model) -# return GridapDistributed.generate_cell_gids(ctrian) -# end + return GridapDistributed.generate_gids( + cgids, bgcell_to_lfacets, n_lfacets + ) +end function GridapDistributed.add_ghost_cells( trian::DistributedSubFacetTriangulation{Df,Dc}, From 8ff022a03368496005053479434eea2d439cd73b Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Fri, 9 May 2025 22:33:37 +1000 Subject: [PATCH 60/74] Minor --- test/DistributedTests/GeometricalDifferentiationTests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 28a8ebc6..47fefcc3 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -267,12 +267,12 @@ function main(distribute,np) main_normal(model,φ0,f0) i_am_main(ranks) && println(" >> Case 1") - φ1 = level_set(:circle_2) + φ1 = level_set(:circle) f1(x) = 1.0 main_generic(model,φ1,f1) i_am_main(ranks) && println(" >> Case 2") - φ2 = level_set(:circle_2) + φ2 = level_set(:circle) f2(x) = x[1] + x[2] main_generic(model,φ2,f2) From 7e5162414f397d5d7c6b2cd25ed9b01e0170ef2e Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Fri, 9 May 2025 23:25:19 +1000 Subject: [PATCH 61/74] Minor --- test/DistributedTests/GeometricalDifferentiationTests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 47fefcc3..aad65908 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -284,8 +284,8 @@ function main(distribute,np) model = generate_model(D,n,ranks,mesh_partition) i_am_main(ranks) && println(" >> Case 3") - φ3 = level_set(:regular_3d) - f3(x) = x[1] + x[2] + x[3] + φ3 = level_set(:sphere) + f3(x) = x[1] + x[2] main_generic(model,φ3,f3) end From 5ff3fb01e20128206d9acb1db8fe4578164e9cf1 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Fri, 16 May 2025 23:40:00 +1000 Subject: [PATCH 62/74] Minor --- .../GeometricalDifferentiationTests.jl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index aad65908..855f695f 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -261,17 +261,14 @@ function main(distribute,np) n = 12 model = generate_model(D,n,ranks,mesh_partition) - i_am_main(ranks) && println(" >> Case 0") φ0 = level_set(:circle_2) f0((x,y)) = VectorValue((1-x)^2,(1-y)^2) main_normal(model,φ0,f0) - i_am_main(ranks) && println(" >> Case 1") φ1 = level_set(:circle) f1(x) = 1.0 main_generic(model,φ1,f1) - i_am_main(ranks) && println(" >> Case 2") φ2 = level_set(:circle) f2(x) = x[1] + x[2] main_generic(model,φ2,f2) @@ -283,10 +280,9 @@ function main(distribute,np) n = 8 model = generate_model(D,n,ranks,mesh_partition) - i_am_main(ranks) && println(" >> Case 3") - φ3 = level_set(:sphere) - f3(x) = x[1] + x[2] - main_generic(model,φ3,f3) + # φ3 = level_set(:sphere) + # f3(x) = x[1] + x[2] + # main_generic(model,φ3,f3) end end \ No newline at end of file From 17a63b9fbb8da33728406ed772b618fbbe74331d Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Tue, 3 Jun 2025 22:40:23 +1000 Subject: [PATCH 63/74] Minor --- src/Interfaces/EmbeddedFacetDiscretizations.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Interfaces/EmbeddedFacetDiscretizations.jl b/src/Interfaces/EmbeddedFacetDiscretizations.jl index 1f5476cc..eb71d9df 100644 --- a/src/Interfaces/EmbeddedFacetDiscretizations.jl +++ b/src/Interfaces/EmbeddedFacetDiscretizations.jl @@ -215,12 +215,15 @@ end function _restrict_boundary_triangulation(model,facets,bgfacet_to_mask) facet_to_bgfacet = facets.glue.face_to_bgface - facet_to_mask = lazy_map(Reindex(bgfacet_to_mask),facet_to_bgfacet) + n_bgfacets = length(bgfacet_to_mask) - bgfacet_to_mask2 = fill(false,n_bgfacets) - bgfacet_to_mask2[facet_to_bgfacet] .= facet_to_mask + new_bgfacet_to_mask = fill(false,n_bgfacets) + new_bgfacet_to_mask[facet_to_bgfacet] .= view(bgfacet_to_mask,facet_to_bgfacet) - BoundaryTriangulation(model,bgfacet_to_mask2,facets.glue.bgface_to_lcell) + new_bgfacet_to_lcell = fill(Int8(1),n_bgfacets) + new_bgfacet_to_lcell[facet_to_bgfacet] .= facets.glue.face_to_lcell + + BoundaryTriangulation(model,new_bgfacet_to_mask,new_bgfacet_to_lcell) end function compute_bgfacet_to_inoutcut(cut::EmbeddedFacetDiscretization,geo::CSG.Geometry) From 48b66a0c9b844b718a5208b91c405d219d42e9af Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Wed, 11 Jun 2025 09:19:10 +1000 Subject: [PATCH 64/74] Updated compats --- Project.toml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Project.toml b/Project.toml index 8bb35cc1..a0a0e1a7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,24 +1,8 @@ -authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] name = "GridapEmbedded" uuid = "8838a6a3-0006-4405-b874-385995508d5d" +authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] version = "0.9.6" -[compat] -AbstractTrees = "0.3.3, 0.4" -Algoim = "0.2.2" -Combinatorics = "1" -CxxWrap = "0.16" -FillArrays = "0.10, 0.11, 0.12, 0.13, 1" -FiniteDiff = "2.27.0" -ForwardDiff = "0.10.38, 1" -Graphs = "1.12.0" -Gridap = "0.18.12" -GridapDistributed = "0.3, 0.4" -MPI = "0.20" -MiniQhull = "0.1.0, 0.2, 0.3, 0.4" -PartitionedArrays = "0.3.4" -julia = "1.3" - [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" Algoim = "0eb9048c-21de-4c7a-bfac-056de1940b74" @@ -37,6 +21,22 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" algoimWrapper_jll = "3c43aa7b-5398-51f3-8d75-8f051e6faa4d" +[compat] +AbstractTrees = "0.3.3, 0.4" +Algoim = "0.2.2" +Combinatorics = "1" +CxxWrap = "0.16" +FillArrays = "0.10, 0.11, 0.12, 0.13, 1" +FiniteDiff = "2.27.0" +ForwardDiff = "0.10.38, 1" +Graphs = "1.12.0" +Gridap = "0.18.12, 0.19" +GridapDistributed = "0.3, 0.4" +MPI = "0.20" +MiniQhull = "0.1.0, 0.2, 0.3, 0.4" +PartitionedArrays = "0.3.4" +julia = "1.3" + [extras] FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" From 41839704ef6960610aee6be5f206a79db553a9a7 Mon Sep 17 00:00:00 2001 From: Jordi Manyer Date: Wed, 11 Jun 2025 23:21:48 +1000 Subject: [PATCH 65/74] Bumped version --- NEWS.md | 6 ++++++ Project.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 7cfea949..65146c6d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.9.7] - 2025-6-11 + +### Added + +- Added support for Gridap v0.19. Since PR[#110](https://github.com/gridap/GridapEmbedded.jl/pull/110). + ## [0.9.6] - 2025-04-19 ### Added diff --git a/Project.toml b/Project.toml index a0a0e1a7..4e0cd317 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "GridapEmbedded" uuid = "8838a6a3-0006-4405-b874-385995508d5d" authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] -version = "0.9.6" +version = "0.9.7" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From 747f1023857adc3cdd032e1fa8cd54075af1c6dd Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Wed, 9 Jul 2025 20:01:29 +1000 Subject: [PATCH 66/74] Add missing update_trian! method for multifield --- .../DifferentiableTriangulations.jl | 22 ++++++++++++---- src/LevelSetCutters/LevelSetCutters.jl | 3 +++ .../GeometricalDifferentiationTests.jl | 17 +++++++++++-- .../GeometricalDifferentiationTests.jl | 25 ++++++++++++++++--- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/LevelSetCutters/DifferentiableTriangulations.jl b/src/LevelSetCutters/DifferentiableTriangulations.jl index 19ef9238..3328f493 100644 --- a/src/LevelSetCutters/DifferentiableTriangulations.jl +++ b/src/LevelSetCutters/DifferentiableTriangulations.jl @@ -10,11 +10,11 @@ methods to compute derivatives w.r.t. deformations of the embedded mesh. To do so, it propagates dual numbers into the geometric maps mapping cut subcells/subfacets to the background mesh. -## Constructor: +## Constructor: DifferentiableTriangulation(trian::Triangulation,fe_space::FESpace) -where `trian` must be an embedded triangulation and `fe_space` is the `FESpace` where +where `trian` must be an embedded triangulation and `fe_space` is the `FESpace` where the level-set function lives. """ @@ -63,6 +63,18 @@ function update_trian!(trian::DifferentiableTriangulation,::FESpace,::Nothing) return trian end +const MultiFieldSpaceTypes = Union{<:MultiFieldFESpace,<:DistributedMultiFieldFESpace} + +function update_trian!(trian::DifferentiableTriangulation,space::MultiFieldSpaceTypes,φh) + map((Ui,φi)->update_trian!(trian,Ui,φi),space,φh) + return trian +end + +function update_trian!(trian::DifferentiableTriangulation,::MultiFieldSpaceTypes,::Nothing) + trian.cell_values = nothing + return trian +end + # Autodiff function FESpaces._change_argument( @@ -424,8 +436,8 @@ function extract_dualized_cell_values( end # TriangulationView -# This is mostly used in distributed, where we remove ghost cells by taking a view -# of the local triangulations. +# This is mostly used in distributed, where we remove ghost cells by taking a view +# of the local triangulations. const DifferentiableTriangulationView{Dc,Dp} = Geometry.TriangulationView{Dc,Dp,<:DifferentiableTriangulation} @@ -465,7 +477,7 @@ end # We only need to propagate the dual numbers to the CUT cells, which is what the # following implementation does: -const DifferentiableAppendedTriangulation{Dc,Dp,A} = +const DifferentiableAppendedTriangulation{Dc,Dp,A} = AppendedTriangulation{Dc,Dp,<:Union{<:DifferentiableTriangulation,<:DifferentiableTriangulationView{Dc,Dp}}} function DifferentiableTriangulation( diff --git a/src/LevelSetCutters/LevelSetCutters.jl b/src/LevelSetCutters/LevelSetCutters.jl index 30592287..9c2cda0c 100644 --- a/src/LevelSetCutters/LevelSetCutters.jl +++ b/src/LevelSetCutters/LevelSetCutters.jl @@ -31,6 +31,9 @@ using Gridap.CellData using Gridap.Polynomials using Gridap.Visualization using Gridap.FESpaces +using Gridap.MultiField + +using GridapDistributed: DistributedMultiFieldFESpace export LevelSetCutter export AnalyticalGeometry diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 855f695f..515a66c7 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -1,7 +1,7 @@ module DistributedGeometricalDifferentitationTests ############################################################################################ -# These tests are meant to verify the correctness differentiation of functionals w.r.t the -# level set defining the cut domain. +# These tests are meant to verify the correctness differentiation of functionals w.r.t the +# level set defining the cut domain. # They are based on the following work: # "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation" # by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis (2025) @@ -117,6 +117,19 @@ function main_generic( @test norm(dJ_bulk_1_AD_in_u_vec - dJ_bulk_1_exact_in_u_vec) < 1e-10 + # Multifield case + U = TestFESpace(model,reffe) + V_φu = MultiFieldFESpace([V_φ,U]) + φuh = interpolate([φh,x->x[1]],V_φu) + J_bulk_mult((φ,u)) = ∫(fh)dΩ + dJ_bulk_AD = gradient(J_bulk_mult,φuh) + dJ_bulk_AD_vec = assemble_vector(dJ_bulk_AD,V_φu) + + dJ_bulk_exact_mult((dφ,du)) = ∫(-fh*dφ/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_exact_vec = assemble_vector(dJ_bulk_exact_mult,V_φu) + + @test norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec,Inf) < 1e-10 + # A.2) Volume integral g(fh) = ∇(fh)⋅∇(fh) diff --git a/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl b/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl index 8a90387f..d834b0eb 100644 --- a/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl +++ b/test/LevelSetCuttersTests/GeometricalDifferentiationTests.jl @@ -1,14 +1,14 @@ module GeometricalDifferentiationTests ############################################################################################ -# These tests are meant to verify the correctness differentiation of functionals w.r.t the -# level set defining the cut domain. +# These tests are meant to verify the correctness differentiation of functionals w.r.t the +# level set defining the cut domain. # They are based on the following work: # "Level-set topology optimisation with unfitted finite elements and automatic shape differentiation" # by Z. J. Wegert, J. Manyer, C. Mallon, S. Badia, V. J. Challis (2025) ############################################################################################ using Test, FiniteDiff -using Gridap, Gridap.Geometry, Gridap.Adaptivity, Gridap.Arrays +using Gridap, Gridap.Geometry, Gridap.Adaptivity, Gridap.Arrays, Gridap.MultiField using GridapEmbedded, GridapEmbedded.LevelSetCutters, GridapEmbedded.Interfaces using GridapEmbedded.Interfaces: get_conormal_vector @@ -17,7 +17,7 @@ using GridapEmbedded.Interfaces: get_ghost_normal_vector using GridapEmbedded.LevelSetCutters: DifferentiableTriangulation -# We general a simplicial model where the simplices are created in a symmetric way using +# We general a simplicial model where the simplices are created in a symmetric way using # varycentric refinement of QUADs and HEXs. function generate_model(D,n) domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1) @@ -124,6 +124,23 @@ function main( @test abs_error < 1e-10 + # Multifield case + U = TestFESpace(model,reffe) + V_φu = MultiFieldFESpace([V_φ,U]) + φuh = interpolate([φh,x->x[1]],V_φu) + J_bulk_mult((φ,u)) = ∫(fh)dΩ + dJ_bulk_AD = gradient(J_bulk_mult,φuh) + dJ_bulk_AD_vec = assemble_vector(dJ_bulk_AD,V_φu) + + dJ_bulk_exact_mult((dφ,du)) = ∫(-fh*dφ/(abs(n_Γ ⋅ ∇(φh))))dΓ + dJ_bulk_exact_vec = assemble_vector(dJ_bulk_exact_mult,V_φu) + + abs_error = norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec,Inf) + if verbose + println(" - norm(dJ_AD - dJ_exact,Inf) = ",abs_error," | Multifield test") + end + @test abs_error < 1e-10 + # A.1.1) Volume integral with another field J_bulk_1(u,φ) = ∫(u+fh)dΩ From 3aea54465d1b71cc3828b4dcf6b3a2b695681c5a Mon Sep 17 00:00:00 2001 From: zjwegert <60646897+zjwegert@users.noreply.github.com> Date: Thu, 10 Jul 2025 06:40:35 +1000 Subject: [PATCH 67/74] minor --- test/DistributedTests/GeometricalDifferentiationTests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DistributedTests/GeometricalDifferentiationTests.jl b/test/DistributedTests/GeometricalDifferentiationTests.jl index 515a66c7..147cc6a1 100644 --- a/test/DistributedTests/GeometricalDifferentiationTests.jl +++ b/test/DistributedTests/GeometricalDifferentiationTests.jl @@ -128,7 +128,7 @@ function main_generic( dJ_bulk_exact_mult((dφ,du)) = ∫(-fh*dφ/(abs(n_Γ ⋅ ∇(φh))))dΓ dJ_bulk_exact_vec = assemble_vector(dJ_bulk_exact_mult,V_φu) - @test norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec,Inf) < 1e-10 + @test norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec) < 1e-10 # A.2) Volume integral From 36591829c1cec05908252c392619bd2adc620ed7 Mon Sep 17 00:00:00 2001 From: Zachary J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Thu, 10 Jul 2025 08:46:02 +1000 Subject: [PATCH 68/74] Update NEWS.md --- NEWS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.md b/NEWS.md index 65146c6d..6dff9dcd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.9.8] - 2025-7-10 + +### Added + +- Added missing update_trian! method for MultiField. Since PR[#112](https://github.com/gridap/GridapEmbedded.jl/pull/112). + ## [0.9.7] - 2025-6-11 ### Added From d825d2c33e44bb04de3f2e2c0733f64c624f0b50 Mon Sep 17 00:00:00 2001 From: Zachary J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:08:10 +1000 Subject: [PATCH 69/74] Bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 4e0cd317..b5e91a35 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "GridapEmbedded" uuid = "8838a6a3-0006-4405-b874-385995508d5d" authors = ["Francesc Verdugo ", "Eric Neiva ", "Pere Antoni Martorell ", "Santiago Badia "] -version = "0.9.7" +version = "0.9.8" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From 85136c47b073f996542e94e7fe2db159fc4c2deb Mon Sep 17 00:00:00 2001 From: Zachary J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:16:56 +1000 Subject: [PATCH 70/74] Fix precompilation --- .../CutFaceBoundaryTriangulations.jl | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Interfaces/CutFaceBoundaryTriangulations.jl b/src/Interfaces/CutFaceBoundaryTriangulations.jl index 63f7b2ca..872413a4 100644 --- a/src/Interfaces/CutFaceBoundaryTriangulations.jl +++ b/src/Interfaces/CutFaceBoundaryTriangulations.jl @@ -395,38 +395,38 @@ end ############################################################################################ # This will go to Gridap - -function Arrays.evaluate!(cache,k::Operation,a::SkeletonPair{<:CellField}) - plus = k(a.plus) - minus = k(a.minus) - SkeletonPair(plus,minus) -end - -function Arrays.evaluate!(cache,k::Operation,a::SkeletonPair{<:CellField},b::SkeletonPair{<:CellField}) - plus = k(a.plus,b.plus) - minus = k(a.minus,b.minus) - SkeletonPair(plus,minus) -end - -import Gridap.TensorValues: inner, outer -import LinearAlgebra: dot -import Base: abs, *, +, -, / - -for op in (:/,) - @eval begin - ($op)(a::CellField,b::SkeletonPair{<:CellField}) = Operation($op)(a,b) - ($op)(a::SkeletonPair{<:CellField},b::CellField) = Operation($op)(a,b) - end -end - -for op in (:outer,:*,:dot,:/) - @eval begin - ($op)(a::SkeletonPair{<:CellField},b::SkeletonPair{<:CellField}) = Operation($op)(a,b) - end -end - -function CellData.change_domain(a::SkeletonPair, ::ReferenceDomain, ::PhysicalDomain) - plus = change_domain(a.plus,ReferenceDomain(),PhysicalDomain()) - minus = change_domain(a.minus,ReferenceDomain(),PhysicalDomain()) - return SkeletonPair(plus,minus) -end +# +# function Arrays.evaluate!(cache,k::Operation,a::SkeletonPair{<:CellField}) +# plus = k(a.plus) +# minus = k(a.minus) +# SkeletonPair(plus,minus) +# end + +# function Arrays.evaluate!(cache,k::Operation,a::SkeletonPair{<:CellField},b::SkeletonPair{<:CellField}) +# plus = k(a.plus,b.plus) +# minus = k(a.minus,b.minus) +# SkeletonPair(plus,minus) +# end + +# import Gridap.TensorValues: inner, outer +# import LinearAlgebra: dot +# import Base: abs, *, +, -, / + +# for op in (:/,) +# @eval begin +# ($op)(a::CellField,b::SkeletonPair{<:CellField}) = Operation($op)(a,b) +# ($op)(a::SkeletonPair{<:CellField},b::CellField) = Operation($op)(a,b) +# end +# end + +# for op in (:outer,:*,:dot,:/) +# @eval begin +# ($op)(a::SkeletonPair{<:CellField},b::SkeletonPair{<:CellField}) = Operation($op)(a,b) +# end +# end + +# function CellData.change_domain(a::SkeletonPair, ::ReferenceDomain, ::PhysicalDomain) +# plus = change_domain(a.plus,ReferenceDomain(),PhysicalDomain()) +# minus = change_domain(a.minus,ReferenceDomain(),PhysicalDomain()) +# return SkeletonPair(plus,minus) +# end From c48a4527de1e014d63fe56c1ab2c9287aa5e1430 Mon Sep 17 00:00:00 2001 From: Zachary J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:18:17 +1000 Subject: [PATCH 71/74] Update NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 6dff9dcd..79b8b87d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added missing update_trian! method for MultiField. Since PR[#112](https://github.com/gridap/GridapEmbedded.jl/pull/112). +- Fix failed precompilation due to Gridap v0.19.2. Since PR[#112](https://github.com/gridap/GridapEmbedded.jl/pull/112). ## [0.9.7] - 2025-6-11 From 96f4d979fff378c1bd757c11aff933ba5a717f2f Mon Sep 17 00:00:00 2001 From: Zachary J Wegert <60646897+zjwegert@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:12:20 +1000 Subject: [PATCH 72/74] Update NEWS.md --- NEWS.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 79b8b87d..72fd3937 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added missing update_trian! method for MultiField. Since PR[#112](https://github.com/gridap/GridapEmbedded.jl/pull/112). -- Fix failed precompilation due to Gridap v0.19.2. Since PR[#112](https://github.com/gridap/GridapEmbedded.jl/pull/112). + +### Fixed + +- Fixed failed precompilation due to Gridap v0.19.2. Since PR[#112](https://github.com/gridap/GridapEmbedded.jl/pull/112). ## [0.9.7] - 2025-6-11 From 59911d614ac70d56c4738f83b7770275343cd9ea Mon Sep 17 00:00:00 2001 From: Eric Neiva Date: Mon, 14 Jul 2025 15:09:02 +0200 Subject: [PATCH 73/74] Setup branch to start dev --- Manifest.toml | 989 ++++++++++++++++++++++ test/DistributedTests/AggregationTests.jl | 2 +- 2 files changed, 990 insertions(+), 1 deletion(-) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000..4dc7563e --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,989 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.11.5" +manifest_format = "2.0" +project_hash = "0647d3409ba6f0505a76eb825c3eb703439c42f8" + +[[deps.ADTypes]] +git-tree-sha1 = "be7ae030256b8ef14a441726c4c37766b90b93a3" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "1.15.0" + + [deps.ADTypes.extensions] + ADTypesChainRulesCoreExt = "ChainRulesCore" + ADTypesConstructionBaseExt = "ConstructionBase" + ADTypesEnzymeCoreExt = "EnzymeCore" + + [deps.ADTypes.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + + [deps.AbstractFFTs.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.3.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Algoim]] +deps = ["CxxWrap", "LinearAlgebra", "StaticArrays", "algoimWrapper_jll"] +git-tree-sha1 = "14f3a55809e3e2ef9cd0d5962157f13a418bb00a" +uuid = "0eb9048c-21de-4c7a-bfac-056de1940b74" +version = "0.2.2" + +[[deps.ArgCheck]] +git-tree-sha1 = "f9e9a66c9b7be1ad7372bbd9b062d9230c30c5ce" +uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197" +version = "2.5.0" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.19.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra"] +git-tree-sha1 = "4e25216b8fea1908a0ce0f5d87368587899f75be" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.AutoHashEquals]] +git-tree-sha1 = "4ec6b48702dacc5994a835c1189831755e4e76ef" +uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f" +version = "2.2.0" + +[[deps.BSON]] +git-tree-sha1 = "4c3e506685c527ac6a54ccc0c8c76fd6f91b42fb" +uuid = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0" +version = "0.3.9" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BlockArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] +git-tree-sha1 = "291532989f81db780e435452ccb2a5f902ff665f" +uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +version = "1.7.0" + + [deps.BlockArrays.extensions] + BlockArraysAdaptExt = "Adapt" + BlockArraysBandedMatricesExt = "BandedMatrices" + + [deps.BlockArrays.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + +[[deps.CircularArrays]] +deps = ["OffsetArrays"] +git-tree-sha1 = "e24a6f390e5563583bb4315c73035b5b3f3e7ab4" +uuid = "7a955b69-7140-5f4e-a0ed-f168c5e2e749" +version = "1.4.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.Combinatorics]] +git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.3" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.17.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.CxxWrap]] +deps = ["Libdl", "MacroTools", "libcxxwrap_julia_jll"] +git-tree-sha1 = "3d05a37a8d40524752524da392ec0c2fbee32543" +uuid = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" +version = "0.16.2" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DifferentiationInterface]] +deps = ["ADTypes", "LinearAlgebra"] +git-tree-sha1 = "c092fd1dd0d94e609cd0d29e13897b2825c804bb" +uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" +version = "0.7.2" + + [deps.DifferentiationInterface.extensions] + DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" + DifferentiationInterfaceDiffractorExt = "Diffractor" + DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] + DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" + DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" + DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" + DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] + DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGTPSAExt = "GTPSA" + DifferentiationInterfaceMooncakeExt = "Mooncake" + DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] + DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] + DifferentiationInterfaceSparseArraysExt = "SparseArrays" + DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" + DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" + DifferentiationInterfaceStaticArraysExt = "StaticArrays" + DifferentiationInterfaceSymbolicsExt = "Symbolics" + DifferentiationInterfaceTrackerExt = "Tracker" + DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] + + [deps.DifferentiationInterface.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" + Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" + FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" + SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + + [deps.Distances.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.9.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FastGaussQuadrature]] +deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "fd923962364b645f3719855c88f7074413a6ad92" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "1.0.2" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.0" + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + + [deps.FileIO.weakdeps] + HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.13.0" + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + + [deps.FillArrays.weakdeps] + PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] +git-tree-sha1 = "f089ab1f834470c525562030c8cfde4025d5e915" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.27.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffSparseArraysExt = "SparseArrays" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.0.1" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "c5abfa0ae0aaee162a3fbb053c13ecda39be545b" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.13.0" + +[[deps.Gridap]] +deps = ["AbstractTrees", "BSON", "BlockArrays", "Combinatorics", "DataStructures", "DocStringExtensions", "FastGaussQuadrature", "FileIO", "FillArrays", "ForwardDiff", "JLD2", "JSON", "LineSearches", "LinearAlgebra", "NLsolve", "NearestNeighbors", "PolynomialBases", "Preferences", "QuadGK", "Random", "SparseArrays", "SparseMatricesCSR", "StaticArrays", "Statistics", "Test", "WriteVTK"] +git-tree-sha1 = "956af503f4df1cca06cb018aa8eb68260eb7d6d4" +uuid = "56d4f2e9-7ea1-5844-9cf6-b9c51ca7ce8e" +version = "0.19.2" + +[[deps.GridapDistributed]] +deps = ["BlockArrays", "CircularArrays", "FillArrays", "ForwardDiff", "Gridap", "LinearAlgebra", "MPI", "PartitionedArrays", "SparseArrays", "SparseMatricesCSR", "WriteVTK"] +git-tree-sha1 = "4fa1869debb61b8070446d8f22317571757b0e82" +repo-rev = "expand-ghost" +repo-url = "https://github.com/gridap/GridapDistributed.jl.git" +uuid = "f9701e48-63b3-45aa-9a63-9bc6c271f355" +version = "0.4.8" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.12.1+0" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "0f14a5456bdc6b9731a5682f439a672750a09e48" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.0.4+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.4" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] +git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.5.15" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.6.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.7.2+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "d5d2e3abfb30ea9c2cff81d243e7235b51315ec2" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.2" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.4.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.11.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "5de60bc6cb3899cd318d80d627560fae2e2d99ae" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.0.1+1" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "892676019c58f34e38743bc989b0eca5bce5edc5" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.22" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.3.1+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.5.4+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.6+0" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "bc95bf4149bf535c09602e3acdf950d9b4376227" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+3" + +[[deps.MiniQhull]] +deps = ["QhullMiniWrapper_jll"] +git-tree-sha1 = "9dc837d180ee49eeb7c8b77bb1c860452634b0d1" +uuid = "978d7f02-9e05-4691-894f-ae31a51d76ca" +version = "0.4.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.12.12" + +[[deps.NLSolversBase]] +deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.10.0" + +[[deps.NLsolve]] +deps = ["Distances", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport"] +git-tree-sha1 = "019f12e9a1a7880459d0173c182e6a99365d7ac1" +uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" +version = "4.5.1" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.22" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.OffsetArrays]] +git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.17.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.OpenBLAS32_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ece4587683695fe4c5f20e990da0ed7e83c351e7" +uuid = "656ef2d0-ae68-5445-9ca0-591084a874a2" +version = "0.3.29+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.27+1" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.5+0" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.8+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.PartitionedArrays]] +deps = ["CircularArrays", "Distances", "FillArrays", "IterativeSolvers", "LinearAlgebra", "MPI", "Printf", "Random", "SparseArrays", "SparseMatricesCSR"] +git-tree-sha1 = "149d2287770c6a533507d74beaa73d76c0727922" +uuid = "5a9dfac6-5c52-46f7-8278-5e2210713be9" +version = "0.3.4" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.11.0" + + [deps.Pkg.extensions] + REPLExt = "REPL" + + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PolynomialBases]] +deps = ["ArgCheck", "AutoHashEquals", "FFTW", "FastGaussQuadrature", "LinearAlgebra", "Requires", "SimpleUnPack", "SpecialFunctions"] +git-tree-sha1 = "d04bec789dce5ff61e8f128b6aee0eda09a3855f" +uuid = "c74db56a-226d-5e98-8bb0-a6049094aeea" +version = "0.4.25" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.QhullMiniWrapper_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Qhull_jll"] +git-tree-sha1 = "607cf73c03f8a9f83b36db0b86a3a9c14179621f" +uuid = "460c41e3-6112-5d7f-b78c-b6823adb3f2d" +version = "1.0.0+1" + +[[deps.Qhull_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6f3ac0623e1173c006cc7377798ec3fb33fa504" +uuid = "784f63db-0788-585a-bace-daefebcd302b" +version = "8.0.1004+0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "1147f140b4c8ddab224c94efa9569fc23d63ab44" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.2" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.SimpleUnPack]] +git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" +uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" +version = "1.1.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.11.0" + +[[deps.SparseMatricesCSR]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "cc05d16e340aecfa0e4cf4616194abc894cd0bca" +uuid = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" +version = "0.6.9" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.5.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "0feb6b9031bd5c51f9072393eb5ab3efd31bf9e4" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.13" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.7.0+0" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.VTKBase]] +git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6" +uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534" +version = "1.0.1" + +[[deps.WriteVTK]] +deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] +git-tree-sha1 = "a329e0b6310244173690d6a4dfc6d1141f9b9370" +uuid = "64499a7a-5c06-52f2-abe2-ccb03c286192" +version = "1.21.2" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "9380cd28f093c901600ab70e0201fb18bae226de" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.14.1+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.algoimWrapper_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenBLAS32_jll", "libcxxwrap_julia_jll"] +git-tree-sha1 = "686ddc4227be075cff2ec5df1c15b8edcd32e27d" +uuid = "3c43aa7b-5398-51f3-8d75-8f051e6faa4d" +version = "0.3.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.11.0+0" + +[[deps.libcxxwrap_julia_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "70091a11c756455c15bc6380ea000c16f38f2d3e" +uuid = "3eaa8342-bff7-56a5-9981-c04077f7cee7" +version = "0.13.4+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.59.0+0" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" diff --git a/test/DistributedTests/AggregationTests.jl b/test/DistributedTests/AggregationTests.jl index 7175232b..50a84f2f 100644 --- a/test/DistributedTests/AggregationTests.jl +++ b/test/DistributedTests/AggregationTests.jl @@ -30,7 +30,7 @@ geo = union(geo1,geo2) n = 16 mesh_partition = (n,n) -bgmodel = CartesianDiscreteModel(ranks,np,pmin,pmax,mesh_partition) +bgmodel = CartesianDiscreteModel(ranks,np,pmin,pmax,mesh_partition;ghost=(2,2)) cutgeo = cut(bgmodel,geo) From 3d9a39651b0ab8f55962c791c126e62bacf3a547 Mon Sep 17 00:00:00 2001 From: Eric Neiva Date: Mon, 14 Jul 2025 15:12:42 +0200 Subject: [PATCH 74/74] Revert "Setup branch to start dev" This reverts commit 59911d614ac70d56c4738f83b7770275343cd9ea. --- Manifest.toml | 989 ---------------------- test/DistributedTests/AggregationTests.jl | 2 +- 2 files changed, 1 insertion(+), 990 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 4dc7563e..00000000 --- a/Manifest.toml +++ /dev/null @@ -1,989 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.11.5" -manifest_format = "2.0" -project_hash = "0647d3409ba6f0505a76eb825c3eb703439c42f8" - -[[deps.ADTypes]] -git-tree-sha1 = "be7ae030256b8ef14a441726c4c37766b90b93a3" -uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.15.0" - - [deps.ADTypes.extensions] - ADTypesChainRulesCoreExt = "ChainRulesCore" - ADTypesConstructionBaseExt = "ConstructionBase" - ADTypesEnzymeCoreExt = "EnzymeCore" - - [deps.ADTypes.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - - [deps.AbstractFFTs.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.AbstractTrees]] -git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.5" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.3.0" -weakdeps = ["SparseArrays", "StaticArrays"] - - [deps.Adapt.extensions] - AdaptSparseArraysExt = "SparseArrays" - AdaptStaticArraysExt = "StaticArrays" - -[[deps.Algoim]] -deps = ["CxxWrap", "LinearAlgebra", "StaticArrays", "algoimWrapper_jll"] -git-tree-sha1 = "14f3a55809e3e2ef9cd0d5962157f13a418bb00a" -uuid = "0eb9048c-21de-4c7a-bfac-056de1940b74" -version = "0.2.2" - -[[deps.ArgCheck]] -git-tree-sha1 = "f9e9a66c9b7be1ad7372bbd9b062d9230c30c5ce" -uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197" -version = "2.5.0" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.2" - -[[deps.ArnoldiMethod]] -deps = ["LinearAlgebra", "Random", "StaticArrays"] -git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" -uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.4.0" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.19.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.ArrayLayouts]] -deps = ["FillArrays", "LinearAlgebra"] -git-tree-sha1 = "4e25216b8fea1908a0ce0f5d87368587899f75be" -uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.11.1" -weakdeps = ["SparseArrays"] - - [deps.ArrayLayouts.extensions] - ArrayLayoutsSparseArraysExt = "SparseArrays" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -version = "1.11.0" - -[[deps.AutoHashEquals]] -git-tree-sha1 = "4ec6b48702dacc5994a835c1189831755e4e76ef" -uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f" -version = "2.2.0" - -[[deps.BSON]] -git-tree-sha1 = "4c3e506685c527ac6a54ccc0c8c76fd6f91b42fb" -uuid = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0" -version = "0.3.9" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -version = "1.11.0" - -[[deps.BlockArrays]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] -git-tree-sha1 = "291532989f81db780e435452ccb2a5f902ff665f" -uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" -version = "1.7.0" - - [deps.BlockArrays.extensions] - BlockArraysAdaptExt = "Adapt" - BlockArraysBandedMatricesExt = "BandedMatrices" - - [deps.BlockArrays.weakdeps] - Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - -[[deps.CircularArrays]] -deps = ["OffsetArrays"] -git-tree-sha1 = "e24a6f390e5563583bb4315c73035b5b3f3e7ab4" -uuid = "7a955b69-7140-5f4e-a0ed-f168c5e2e749" -version = "1.4.0" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.8" - -[[deps.Combinatorics]] -git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.3" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools"] -git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.1" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.17.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.ConstructionBase]] -git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.6.0" - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.CxxWrap]] -deps = ["Libdl", "MacroTools", "libcxxwrap_julia_jll"] -git-tree-sha1 = "3d05a37a8d40524752524da392ec0c2fbee32543" -uuid = "1f15a43c-97ca-5a2a-ae31-89f07a497df4" -version = "0.16.2" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" -version = "1.11.0" - -[[deps.DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[deps.DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[deps.DifferentiationInterface]] -deps = ["ADTypes", "LinearAlgebra"] -git-tree-sha1 = "c092fd1dd0d94e609cd0d29e13897b2825c804bb" -uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.7.2" - - [deps.DifferentiationInterface.extensions] - DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" - DifferentiationInterfaceDiffractorExt = "Diffractor" - DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] - DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" - DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" - DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" - DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] - DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" - DifferentiationInterfaceGTPSAExt = "GTPSA" - DifferentiationInterfaceMooncakeExt = "Mooncake" - DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] - DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] - DifferentiationInterfaceSparseArraysExt = "SparseArrays" - DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" - DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" - DifferentiationInterfaceStaticArraysExt = "StaticArrays" - DifferentiationInterfaceSymbolicsExt = "Symbolics" - DifferentiationInterfaceTrackerExt = "Tracker" - DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] - - [deps.DifferentiationInterface.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" - Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" - FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" - FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" - SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - - [deps.Distances.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -version = "1.11.0" - -[[deps.DocStringExtensions]] -git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.5" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.9.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.11+0" - -[[deps.FastGaussQuadrature]] -deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "fd923962364b645f3719855c88f7074413a6ad92" -uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "1.0.2" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.17.0" - - [deps.FileIO.extensions] - HTTPExt = "HTTP" - - [deps.FileIO.weakdeps] - HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -version = "1.11.0" - -[[deps.FillArrays]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.13.0" - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - - [deps.FillArrays.weakdeps] - PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] -git-tree-sha1 = "f089ab1f834470c525562030c8cfde4025d5e915" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.27.0" - - [deps.FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffSparseArraysExt = "SparseArrays" - FiniteDiffStaticArraysExt = "StaticArrays" - - [deps.FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.0.1" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" -version = "1.11.0" - -[[deps.Graphs]] -deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "c5abfa0ae0aaee162a3fbb053c13ecda39be545b" -uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" -version = "1.13.0" - -[[deps.Gridap]] -deps = ["AbstractTrees", "BSON", "BlockArrays", "Combinatorics", "DataStructures", "DocStringExtensions", "FastGaussQuadrature", "FileIO", "FillArrays", "ForwardDiff", "JLD2", "JSON", "LineSearches", "LinearAlgebra", "NLsolve", "NearestNeighbors", "PolynomialBases", "Preferences", "QuadGK", "Random", "SparseArrays", "SparseMatricesCSR", "StaticArrays", "Statistics", "Test", "WriteVTK"] -git-tree-sha1 = "956af503f4df1cca06cb018aa8eb68260eb7d6d4" -uuid = "56d4f2e9-7ea1-5844-9cf6-b9c51ca7ce8e" -version = "0.19.2" - -[[deps.GridapDistributed]] -deps = ["BlockArrays", "CircularArrays", "FillArrays", "ForwardDiff", "Gridap", "LinearAlgebra", "MPI", "PartitionedArrays", "SparseArrays", "SparseMatricesCSR", "WriteVTK"] -git-tree-sha1 = "4fa1869debb61b8070446d8f22317571757b0e82" -repo-rev = "expand-ghost" -repo-url = "https://github.com/gridap/GridapDistributed.jl.git" -uuid = "f9701e48-63b3-45aa-9a63-9bc6c271f355" -version = "0.4.8" - -[[deps.HashArrayMappedTries]] -git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" -uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" -version = "0.2.0" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.1+0" - -[[deps.Inflate]] -git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "0f14a5456bdc6b9731a5682f439a672750a09e48" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2025.0.4+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -version = "1.11.0" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.4" - -[[deps.IterativeSolvers]] -deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" -uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.4" - -[[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] -git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.15" -weakdeps = ["UnPack"] - - [deps.JLD2.extensions] - UnPackExt = "UnPack" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.0" - -[[deps.JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.4" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -version = "1.11.0" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" -version = "1.11.0" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.7.2+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -version = "1.11.0" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.18.0+0" - -[[deps.LightXML]] -deps = ["Libdl", "XML2_jll"] -git-tree-sha1 = "d5d2e3abfb30ea9c2cff81d243e7235b51315ec2" -uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" -version = "0.9.2" - -[[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.4.0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -version = "1.11.0" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.29" - - [deps.LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [deps.LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -version = "1.11.0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "5de60bc6cb3899cd318d80d627560fae2e2d99ae" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2025.0.1+1" - -[[deps.MPI]] -deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] -git-tree-sha1 = "892676019c58f34e38743bc989b0eca5bce5edc5" -uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.22" - - [deps.MPI.extensions] - AMDGPUExt = "AMDGPU" - CUDAExt = "CUDA" - - [deps.MPI.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.3.1+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.5.4+0" - -[[deps.MacroTools]] -git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.16" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -version = "1.11.0" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+0" - -[[deps.MicrosoftMPI_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "bc95bf4149bf535c09602e3acdf950d9b4376227" -uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+3" - -[[deps.MiniQhull]] -deps = ["QhullMiniWrapper_jll"] -git-tree-sha1 = "9dc837d180ee49eeb7c8b77bb1c860452634b0d1" -uuid = "978d7f02-9e05-4691-894f-ae31a51d76ca" -version = "0.4.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" -version = "1.11.0" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.12.12" - -[[deps.NLSolversBase]] -deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.10.0" - -[[deps.NLsolve]] -deps = ["Distances", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport"] -git-tree-sha1 = "019f12e9a1a7880459d0173c182e6a99365d7ac1" -uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" -version = "4.5.1" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" - -[[deps.NearestNeighbors]] -deps = ["Distances", "StaticArrays"] -git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1" -uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" -version = "0.4.22" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.OffsetArrays]] -git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.17.0" -weakdeps = ["Adapt"] - - [deps.OffsetArrays.extensions] - OffsetArraysAdaptExt = "Adapt" - -[[deps.OpenBLAS32_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ece4587683695fe4c5f20e990da0ed7e83c351e7" -uuid = "656ef2d0-ae68-5445-9ca0-591084a874a2" -version = "0.3.29+0" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.27+1" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.5+0" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.8+0" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.6+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.8.1" - -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.3" - -[[deps.PartitionedArrays]] -deps = ["CircularArrays", "Distances", "FillArrays", "IterativeSolvers", "LinearAlgebra", "MPI", "Printf", "Random", "SparseArrays", "SparseMatricesCSR"] -git-tree-sha1 = "149d2287770c6a533507d74beaa73d76c0727922" -uuid = "5a9dfac6-5c52-46f7-8278-5e2210713be9" -version = "0.3.4" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.11.0" - - [deps.Pkg.extensions] - REPLExt = "REPL" - - [deps.Pkg.weakdeps] - REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PolynomialBases]] -deps = ["ArgCheck", "AutoHashEquals", "FFTW", "FastGaussQuadrature", "LinearAlgebra", "Requires", "SimpleUnPack", "SpecialFunctions"] -git-tree-sha1 = "d04bec789dce5ff61e8f128b6aee0eda09a3855f" -uuid = "c74db56a-226d-5e98-8bb0-a6049094aeea" -version = "0.4.25" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.1" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.3" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" -version = "1.11.0" - -[[deps.QhullMiniWrapper_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Qhull_jll"] -git-tree-sha1 = "607cf73c03f8a9f83b36db0b86a3a9c14179621f" -uuid = "460c41e3-6112-5d7f-b78c-b6823adb3f2d" -version = "1.0.0+1" - -[[deps.Qhull_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "b6f3ac0623e1173c006cc7377798ec3fb33fa504" -uuid = "784f63db-0788-585a-bace-daefebcd302b" -version = "8.0.1004+0" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.2" - - [deps.QuadGK.extensions] - QuadGKEnzymeExt = "Enzyme" - - [deps.QuadGK.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -version = "1.11.0" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.1" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.ScopedValues]] -deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "1147f140b4c8ddab224c94efa9569fc23d63ab44" -uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.3.0" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -version = "1.11.0" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.2" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" -version = "1.11.0" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.SimpleUnPack]] -git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" -uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" -version = "1.1.0" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" -version = "1.11.0" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.11.0" - -[[deps.SparseMatricesCSR]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "cc05d16e340aecfa0e4cf4616194abc894cd0bca" -uuid = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" -version = "0.6.9" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.5.1" - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "0feb6b9031bd5c51f9072393eb5ab3efd31bf9e4" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.13" - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - - [deps.StaticArrays.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.Statistics]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.11.1" -weakdeps = ["SparseArrays"] - - [deps.Statistics.extensions] - SparseArraysExt = ["SparseArrays"] - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.7.0+0" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -version = "1.11.0" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.3" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" -version = "1.11.0" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -version = "1.11.0" - -[[deps.VTKBase]] -git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6" -uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534" -version = "1.0.1" - -[[deps.WriteVTK]] -deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] -git-tree-sha1 = "a329e0b6310244173690d6a4dfc6d1141f9b9370" -uuid = "64499a7a-5c06-52f2-abe2-ccb03c286192" -version = "1.21.2" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "9380cd28f093c901600ab70e0201fb18bae226de" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.14.1+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.algoimWrapper_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenBLAS32_jll", "libcxxwrap_julia_jll"] -git-tree-sha1 = "686ddc4227be075cff2ec5df1c15b8edcd32e27d" -uuid = "3c43aa7b-5398-51f3-8d75-8f051e6faa4d" -version = "0.3.1+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.0+0" - -[[deps.libcxxwrap_julia_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "70091a11c756455c15bc6380ea000c16f38f2d3e" -uuid = "3eaa8342-bff7-56a5-9981-c04077f7cee7" -version = "0.13.4+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.59.0+0" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" diff --git a/test/DistributedTests/AggregationTests.jl b/test/DistributedTests/AggregationTests.jl index 50a84f2f..7175232b 100644 --- a/test/DistributedTests/AggregationTests.jl +++ b/test/DistributedTests/AggregationTests.jl @@ -30,7 +30,7 @@ geo = union(geo1,geo2) n = 16 mesh_partition = (n,n) -bgmodel = CartesianDiscreteModel(ranks,np,pmin,pmax,mesh_partition;ghost=(2,2)) +bgmodel = CartesianDiscreteModel(ranks,np,pmin,pmax,mesh_partition) cutgeo = cut(bgmodel,geo)