diff --git a/GridapHybrid.jl/Project.toml b/GridapHybrid.jl/Project.toml deleted file mode 100644 index 81648c0..0000000 --- a/GridapHybrid.jl/Project.toml +++ /dev/null @@ -1 +0,0 @@ -[deps] diff --git a/Manifest.toml b/Manifest.toml index 3dbba5b..e1bd020 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.11.1" +julia_version = "1.11.2" manifest_format = "2.0" project_hash = "fef793fe016e7e018de72e6d17cc203a79f6b51a" diff --git a/src/DistributedHybrid.jl b/src/DistributedHybrid.jl index 1722fce..b433ca7 100644 --- a/src/DistributedHybrid.jl +++ b/src/DistributedHybrid.jl @@ -66,7 +66,6 @@ function Gridap.CellData.change_domain( return Gridap.MultiField.MultiFieldFEBasisComponent(b_data,c_sf,a.fieldid,a.nfields) end - # Cut the data to the local view function Gridap.FESpaces.get_cell_fe_data( fun, f, ttrian::SkeletonView @@ -75,8 +74,6 @@ function Gridap.FESpaces.get_cell_fe_data( return Gridap.Geometry.restrict(data,ttrian.cell_to_parent_cell) end - - # cellwise normal vector for distributed hybrid models function GridapHybrid.get_cell_normal_vector(s::GridapDistributed.DistributedTriangulation) @@ -109,7 +106,7 @@ end function Geometry.best_target( trian1::BodyFittedTriangulation{Dc}, trian2::BodyFittedTriangulation{Dc} - ) where {Dc} +) where {Dc} @check is_change_possible(trian1,trian2) @check is_change_possible(trian2,trian1) D1 = num_cell_dims(trian1) @@ -119,23 +116,21 @@ function Geometry.best_target( best_target(trian1,trian2,glue1,glue2) end - - # Hybrid FE operator for distributed models function HybridAffineFEOperator( weakform::Function, trial::GridapDistributed.DistributedMultiFieldFESpace, test::GridapDistributed.DistributedMultiFieldFESpace, bulk_fields::TB, - skeleton_fields::TS) where {TB <: Vector{<:Integer},TS <: Vector{<:Integer}} - + skeleton_fields::TS +) where {TB <: Vector{<:Integer},TS <: Vector{<:Integer}} # Invoke weak form of the hybridizable system u = get_trial_fe_basis(trial) v = get_fe_basis(test) biform, liform = weakform(u, v) M, L = GridapHybrid._setup_fe_spaces_skeleton_system(trial, test, skeleton_fields) - + # Transform DomainContribution objects of the hybridizable system into a # suitable form for assembling the linear system defined on the skeleton # (i.e., the hybrid system) @@ -146,34 +141,34 @@ function HybridAffineFEOperator( # Add StaticCondensationMap to matvec terms matvec = GridapHybrid._add_static_condensation(matvec, bulk_fields, skeleton_fields) - if (length(skeleton_fields) != 1) - matvec = GridapHybrid._block_skeleton_system_contributions(matvec, L) - end - - uhd = zero(M) - matvec, mat = Gridap.FESpaces._attach_dirichlet(matvec, mat, uhd) - - data = Gridap.FESpaces._collect_cell_matrix_and_vector(M, L, matvec, mat, vec) - return data + if (length(skeleton_fields) != 1) + matvec = GridapHybrid._block_skeleton_system_contributions(matvec, L) + end + + uhd = zero(M) + matvec, mat = Gridap.FESpaces._attach_dirichlet(matvec, mat, uhd) + + data = Gridap.FESpaces._collect_cell_matrix_and_vector(M, L, matvec, mat, vec) + return data end - assem = SparseMatrixAssembler(M, L) - A, b = assemble_matrix_and_vector(assem, data) - - skeleton_op = AffineFEOperator(M, L, A, b) - HybridAffineFEOperator(weakform, trial, test, bulk_fields, skeleton_fields, skeleton_op) + assem = SparseMatrixAssembler(M, L) + A, b = assemble_matrix_and_vector(assem, data) + + skeleton_op = AffineFEOperator(M, L, A, b) + HybridAffineFEOperator(weakform, trial, test, bulk_fields, skeleton_fields, skeleton_op) end # solve function for hybrid distributed models function Gridap.FESpaces.solve!(uh::GridapDistributed.DistributedMultiFieldCellField, solver::LinearFESolver, op::HybridAffineFEOperator, cache) # Solve linear system defined on the skeleton - lh = solve(op.skeleton_op) + lh = solve(op.skeleton_op) # Invoke weak form of the hybridizable system - u = get_trial_fe_basis(op.trial) - v = get_fe_basis(op.test) - biform, liform = op.weakform(u, v) + u = get_trial_fe_basis(op.trial) + v = get_fe_basis(op.test) + biform, liform = op.weakform(u, v) # Transform DomainContribution objects of the hybridizable system into a # suitable form for assembling the linear system defined on the skeleton @@ -186,47 +181,47 @@ function Gridap.FESpaces.solve!(uh::GridapDistributed.DistributedMultiFieldCellF end free_dof_values = GridapHybrid._compute_hybridizable_from_skeleton_free_dof_values( - lh, - op.trial, - op.test, - local_views(Gridap.FESpaces.get_trial(op.skeleton_op)), - matvec, - op.bulk_fields, - op.skeleton_fields) + lh, + op.trial, + op.test, + local_views(Gridap.FESpaces.get_trial(op.skeleton_op)), + matvec, + op.bulk_fields, + op.skeleton_fields + ) - ids = partition(get_free_dof_ids(op.trial)) - xh = FEFunction(op.trial, PVector(free_dof_values,ids)) - cache = nothing - return xh, cache + ids = partition(get_free_dof_ids(op.trial)) + xh = FEFunction(op.trial, PVector(free_dof_values,ids)) + cache = nothing + return xh, cache end function GridapHybrid._compute_hybridizable_from_skeleton_free_dof_values( - skeleton_fe_function::GridapDistributed.DistributedCellField, - trial_hybridizable::GridapDistributed.DistributedMultiFieldFESpace, - test_hybridizable::GridapDistributed.DistributedMultiFieldFESpace, - trial_skeleton, - matvec::AbstractArray{<:DomainContribution}, - bulk_fields::Vector{Int}, - skeleton_fields::Vector{Int}) - + skeleton_fe_function::GridapDistributed.DistributedCellField, + trial_hybridizable::GridapDistributed.DistributedMultiFieldFESpace, + test_hybridizable::GridapDistributed.DistributedMultiFieldFESpace, + trial_skeleton, + matvec::AbstractArray{<:DomainContribution}, + bulk_fields::Vector{Int}, + skeleton_fields::Vector{Int} +) free_dof_values = map(local_views(skeleton_fe_function), local_views(trial_hybridizable), local_views(test_hybridizable), local_views(matvec)) do skeleton_fe_function, trial_hybridizable, test_hybridizable, matvec - - # Convert dof-wise dof values of lh into cell-wise dof values lhₖ Γ = first(keys(matvec.dict)) Gridap.Helpers.@check isa(Γ, GridapHybrid.SkeletonTriangulation) || isa(Γ, GridapHybrid.SkeletonView) lhₖ = get_cell_dof_values(skeleton_fe_function, Γ) - + # Compute cell-wise dof values of bulk fields out of lhₖ t = matvec.dict[Γ] m = BackwardStaticCondensationMap(bulk_fields, skeleton_fields) uhphlhₖ = lazy_map(m, t, lhₖ) - + model = get_background_model(Γ) cell_wise_facets_parent = GridapHybrid._get_cell_wise_facets(model) - cell_wise_facets = Gridap.Geometry.restrict(cell_wise_facets_parent, Γ.cell_to_parent_cell) # + cell_wise_facets = Gridap.Geometry.restrict(cell_wise_facets_parent, Γ.cell_to_parent_cell) cells_around_facets_parent = GridapHybrid._get_cells_around_facets(model) - + facets = unique(vcat(cell_wise_facets...)) + nfields = length(bulk_fields) + length(skeleton_fields) m = Gridap.Fields.BlockMap(nfields, skeleton_fields) L = Gridap.FESpaces.get_fe_space(skeleton_fe_function) @@ -236,23 +231,23 @@ function GridapHybrid._compute_hybridizable_from_skeleton_free_dof_values( cell_wise_facets_parent, lhₖ, get_cell_dof_ids(L))...) - lhₑ = Gridap.Geometry.restrict(lhₑ, collect(1:length(unique(vcat(cell_wise_facets...))))) - + lhₑ = Gridap.Geometry.restrict(lhₑ, 1:length(facets)) + lhₑ_dofs = Gridap.FESpaces.get_cell_dof_ids(trial_hybridizable, get_triangulation(L)) lhₑ_dofs = lazy_map(m, lhₑ_dofs.args[skeleton_fields]...) - lhₑ_dofs = Gridap.Geometry.restrict(lhₑ_dofs,unique(vcat(cell_wise_facets...))) - + lhₑ_dofs = Gridap.Geometry.restrict(lhₑ_dofs, facets) + Ω = trial_hybridizable[first(bulk_fields)] Ω = get_triangulation(Ω) - + m = Gridap.Fields.BlockMap(length(bulk_fields), bulk_fields) uhph_dofs = get_cell_dof_ids(trial_hybridizable, Ω) - + # This last step is needed as get_cell_dof_ids(...) returns as many blocks # as fields in trial, regardless of the FEspaces defined on Ω or not uhph_dofs = lazy_map(m, uhph_dofs.args[bulk_fields]...) uhph_dofs = Gridap.Geometry.restrict(uhph_dofs,Γ.cell_to_parent_cell) - + uhphₖ = lazy_map(RestrictArrayBlockMap(bulk_fields), uhphlhₖ) vecdata = ([lhₑ,uhphₖ], [lhₑ_dofs,uhph_dofs]) @@ -262,29 +257,21 @@ function GridapHybrid._compute_hybridizable_from_skeleton_free_dof_values( end end - # HHO specific functionalities - - function (op::AbstractArray{<:ReconstructionFEOperator})(v::GridapDistributed.DistributedMultiFieldCellField) - image_span = map(local_views(op), local_views(v)) do opi, vi - basis_style = GridapHybrid._get_basis_style(vi) LHSf, RHSf = GridapHybrid._evaluate_forms(opi, vi) cell_dofs = GridapHybrid._compute_cell_dofs(LHSf, RHSf) O = opi.test_space GridapHybrid._generate_image_space_span(opi,O,vi,cell_dofs,basis_style) - end - return image_span |> collect + return image_span end function (op::AbstractArray{<:ProjectionFEOperator})(v::GridapDistributed.DistributedMultiFieldCellField) - image_span = map(local_views(op), local_views(v)) do opi, vi - basis_style = GridapHybrid._get_basis_style(vi) LHSf,RHSf= GridapHybrid._evaluate_forms(opi,vi) cell_dofs= GridapHybrid._compute_cell_dofs(LHSf,RHSf) @@ -293,10 +280,5 @@ function (op::AbstractArray{<:ProjectionFEOperator})(v::GridapDistributed.Distri O = opi.test_space GridapHybrid._generate_image_space_span(opi,O,vi,cell_dofs,basis_style) end - return image_span |> collect + return image_span end - - - - - diff --git a/src/HybridAffineFEOperators.jl b/src/HybridAffineFEOperators.jl index f88596c..e68989d 100644 --- a/src/HybridAffineFEOperators.jl +++ b/src/HybridAffineFEOperators.jl @@ -132,10 +132,11 @@ function _compute_hybridizable_from_skeleton_free_dof_values(skeleton_fe_functio L = Gridap.FESpaces.get_fe_space(skeleton_fe_function) lhₑ = lazy_map(m, convert_cell_wise_dofs_array_to_facet_dofs_array( - cells_around_facets, - cell_wise_facets, - lhₖ, - get_cell_dof_ids(L))...) + cells_around_facets, + cell_wise_facets, + lhₖ, + get_cell_dof_ids(L))... + ) assem = SparseMatrixAssembler(trial_hybridizable, test_hybridizable) lhₑ_dofs = get_cell_dof_ids(trial_hybridizable, get_triangulation(L))