Skip to content

Commit 9bbf922

Browse files
authored
Merge pull request #605 from gridap/compressed_assembly
Compressed assembly
2 parents e41c3a0 + a2657d8 commit 9bbf922

8 files changed

+267
-8
lines changed

src/FESpaces/Assemblers.jl

+8-8
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,9 @@ function collect_cell_matrix(trial::FESpace,test::FESpace,a::DomainContribution)
341341
cell_mat_rc = attach_constraints_rows(test,cell_mat_c,trian)
342342
rows = get_cell_dof_ids(test,trian)
343343
cols = get_cell_dof_ids(trial,trian)
344-
push!(w,cell_mat_rc)
345-
push!(r,rows)
346-
push!(c,cols)
344+
push!(w,compress_contributions(cell_mat_rc,trian))
345+
push!(r,compress_ids(rows,trian))
346+
push!(c,compress_ids(cols,trian))
347347
end
348348
(w,r,c)
349349
end
@@ -356,8 +356,8 @@ function collect_cell_vector(test::FESpace,a::DomainContribution)
356356
@assert ndims(eltype(cell_vec)) == 1
357357
cell_vec_r = attach_constraints_rows(test,cell_vec,trian)
358358
rows = get_cell_dof_ids(test,trian)
359-
push!(w,cell_vec_r)
360-
push!(r,rows)
359+
push!(w,compress_contributions(cell_vec_r,trian))
360+
push!(r,compress_ids(rows,trian))
361361
end
362362
(w,r)
363363
end
@@ -373,9 +373,9 @@ function _collect_cell_matvec(trial::FESpace,test::FESpace,a::DomainContribution
373373
cell_mat_rc = attach_constraints_rows(test,cell_mat_c,trian)
374374
rows = get_cell_dof_ids(test,trian)
375375
cols = get_cell_dof_ids(trial,trian)
376-
push!(w,cell_mat_rc)
377-
push!(r,rows)
378-
push!(c,cols)
376+
push!(w,compress_contributions(cell_mat_rc,trian))
377+
push!(r,compress_ids(rows,trian))
378+
push!(c,compress_ids(cols,trian))
379379
end
380380
(w,r,c)
381381
end

src/Geometry/AppendedTriangulations.jl

+31
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,34 @@ end
9898
#function CellQuadrature(trian::AppendedTriangulation,degree::Integer)
9999
# CellQuadrature(trian,degree,degree)
100100
#end
101+
102+
#function compress_contributions(cell_mat::AppendedArray,trian::AppendedTriangulation)
103+
# if length(cell_mat.a) == num_cells(trian.a) && length(cell_mat.b) == num_cells(trian.b)
104+
# a = compress_contributions(cell_mat.a,trian.a)
105+
# b = compress_contributions(cell_mat.b,trian.b)
106+
# return lazy_append(a,b)
107+
# else
108+
# return cell_mat
109+
# end
110+
#end
111+
#
112+
#function compress_ids(cell_ids::AppendedArray,trian::AppendedTriangulation)
113+
# if length(cell_ids.a) == num_cells(trian.a) && length(cell_ids.b) == num_cells(trian.b)
114+
# a = compress_ids(cell_ids.a,trian.a)
115+
# b = compress_ids(cell_ids.b,trian.b)
116+
# return lazy_append(a,b)
117+
# else
118+
# return cell_ids
119+
# end
120+
#end
121+
122+
function compress_contributions(cell_mat,trian::AppendedTriangulation)
123+
cell_to_bgcell = get_cell_to_bgcell(trian)
124+
ccell_mat = compress_contributions(cell_mat,cell_to_bgcell)
125+
ccell_mat
126+
end
127+
128+
function compress_ids(cell_ids,trian::AppendedTriangulation)
129+
cell_to_bgcell = get_cell_to_bgcell(trian)
130+
compress_ids(cell_ids,cell_to_bgcell)
131+
end

src/Geometry/CompressedCellArrays.jl

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
2+
function compress_ids(cell_to_bgcell::AbstractVector{<:Integer})
3+
nccells = 0
4+
c = -1
5+
for bgcell in cell_to_bgcell
6+
if c != bgcell
7+
nccells += 1
8+
c = bgcell
9+
end
10+
end
11+
ccell_to_first_cell = zeros(Int32,nccells+1)
12+
ccell = 0
13+
c = -1
14+
for (cell,bgcell) in enumerate(cell_to_bgcell)
15+
if c != bgcell
16+
ccell += 1
17+
c = bgcell
18+
ccell_to_first_cell[ccell] = cell
19+
end
20+
end
21+
ccell_to_first_cell[end] = length(cell_to_bgcell)+1
22+
ccell_to_first_cell
23+
end
24+
25+
function compress_ids(cell_ids,cell_to_bgcell::AbstractVector{<:Integer})
26+
ccell_to_first_cell = compress_ids(cell_to_bgcell)
27+
nccells = length(ccell_to_first_cell)-1
28+
ccell_to_cell = view(ccell_to_first_cell,1:nccells)
29+
ccell_ids = view(cell_ids,ccell_to_cell)
30+
ccell_ids
31+
end
32+
33+
function compress_contributions(
34+
cell_to_mat,
35+
cell_to_bgcell::AbstractVector{<:Integer},
36+
ccell_to_first_cell::AbstractVector{<:Integer}=compress_ids(cell_to_bgcell))
37+
38+
nccells = length(ccell_to_first_cell)-1
39+
ccell_to_cell = view(ccell_to_first_cell,1:nccells)
40+
ccell_to_mat = CompressedCellArray(cell_to_mat,ccell_to_first_cell)
41+
ccell_to_mat
42+
end
43+
44+
struct CompressedCellArray{T,A,B} <: AbstractVector{T}
45+
cell_to_array::A
46+
ccell_to_first_cell::B
47+
function CompressedCellArray(cell_to_array::A, ccell_to_first_cell::B) where {A,B}
48+
T = eltype(cell_to_array)
49+
new{T,A,B}(cell_to_array,ccell_to_first_cell)
50+
end
51+
end
52+
53+
Base.size(a::CompressedCellArray) = (length(a.ccell_to_first_cell)-1,)
54+
Base.IndexStyle(::Type{<:CompressedCellArray}) = IndexLinear()
55+
56+
function Base.getindex(a::CompressedCellArray,ccell::Integer)
57+
cell_first = a.ccell_to_first_cell[ccell]
58+
cell_last = a.ccell_to_first_cell[ccell+1]-1
59+
array = a.cell_to_array[cell_first]
60+
cell_range = (cell_first+1):cell_last
61+
_compress!(array,a.cell_to_array,cell_range)
62+
end
63+
64+
@inline function _compress!(array,cell_to_array,cell_range)
65+
r = copy(array)
66+
for cell in cell_range
67+
carray = cell_to_array[cell]
68+
for k in eachindex(r)
69+
r[k] = r[k] + carray[k]
70+
end
71+
end
72+
r
73+
end
74+
75+
@inline function _compress!(matvec::Tuple,cell_to_matvec,cell_range)
76+
mat, vec = matvec
77+
rm = copy(mat)
78+
rv = copy(vec)
79+
for cell in cell_range
80+
cmat, cvec = cell_to_matvec[cell]
81+
for k in eachindex(mat)
82+
rm[k] = rm[k] + cmat[k]
83+
end
84+
for i in eachindex(vec)
85+
rv[i] = rv[i] + cvec[i]
86+
end
87+
end
88+
(rm,rv)
89+
end
90+
91+
function array_cache(a::CompressedCellArray)
92+
array = testitem(a.cell_to_array)
93+
_compress_cache(array,a)
94+
end
95+
96+
function _compress_cache(array,a)
97+
CachedArray(copy(array)), array_cache(a.cell_to_array)
98+
end
99+
100+
function _compress_cache(matvec::Tuple,a)
101+
mat, vec = matvec
102+
cmatvec = (CachedArray(copy(mat)), CachedArray(copy(vec)))
103+
cmatvec, array_cache(a.cell_to_array)
104+
end
105+
106+
function getindex!(cache,a::CompressedCellArray,ccell::Integer)
107+
c, ccache = cache
108+
cell_first = a.ccell_to_first_cell[ccell]
109+
cell_last = a.ccell_to_first_cell[ccell+1]-1
110+
array = getindex!(ccache,a.cell_to_array,cell_first)
111+
cell_range = (cell_first+1):cell_last
112+
_compress!(c,array,ccache,a.cell_to_array,cell_range)
113+
end
114+
115+
@inline function _compress!(c,array,ccache,cell_to_array,cell_range)
116+
setsize!(c,size(array))
117+
r = c.array
118+
copyto!(r,array)
119+
for cell in cell_range
120+
carray = getindex!(ccache,cell_to_array,cell)
121+
for k in eachindex(array)
122+
r[k] = r[k] + carray[k]
123+
end
124+
end
125+
r
126+
end
127+
128+
@inline function _compress!(c,matvec::Tuple,ccache,cell_to_matvec,cell_range)
129+
cm, cv = c
130+
mat, vec = matvec
131+
setsize!(cm,size(mat))
132+
setsize!(cv,size(vec))
133+
rm = cm.array
134+
rv = cv.array
135+
copyto!(rm,mat)
136+
copyto!(rv,vec)
137+
for cell in cell_range
138+
cmat, cvec = getindex!(ccache,cell_to_matvec,cell)
139+
for k in eachindex(mat)
140+
rm[k] = rm[k] + cmat[k]
141+
end
142+
for i in eachindex(vec)
143+
rv[i] = rv[i] + cvec[i]
144+
end
145+
end
146+
(rm, rv)
147+
end

src/Geometry/Geometry.jl

+4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ export is_oriented
9696
export is_regular
9797
export expand_cell_data
9898
export compress_cell_data
99+
export compress_contributions
100+
export compress_ids
99101

100102
export UnstructuredGridTopology
101103

@@ -219,6 +221,8 @@ include("RestrictedDiscreteModels.jl")
219221

220222
include("AppendedTriangulations.jl")
221223

224+
include("CompressedCellArrays.jl")
225+
222226
include("BoundaryDiscreteModel.jl")
223227

224228
end # module

src/Geometry/Triangulations.jl

+8
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,14 @@ function get_cell_node_ids(trian::Triangulation)
326326
@notimplemented
327327
end
328328

329+
function compress_contributions(cell_mat,trian::Triangulation)
330+
cell_mat
331+
end
332+
333+
function compress_ids(cell_ids,trian::Triangulation)
334+
cell_ids
335+
end
336+
329337
function Quadrature(trian::Triangulation,args...;kwargs...)
330338
cell_ctype = get_cell_type(trian)
331339
ctype_polytope = map(get_polytope,get_reffes(trian))

test/FESpacesTests/AppendedTriangulationsTests.jl

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ cellmat = integrate( ∇(dv)⋅∇(du), quad )
6262
@test isa(cellmat.a,Fill)
6363
@test isa(cellmat.b,Fill)
6464

65+
= Measure(Ω,2)
66+
a(u,v) = (u*v)dΩ
67+
A = assemble_matrix(a,V,V)
68+
6569
q1 = Quadrature(tensor_product,1)
6670
q2 = Quadrature(tensor_product,2)
6771
= Measure(Ω,q1,q2)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module CompressedCellArraysTests
2+
3+
using Test
4+
using Gridap.Arrays
5+
using Gridap.Geometry
6+
7+
u(x) = x[1]^2 + x[2]
8+
9+
domain= (0,1,0,1)
10+
cells = (3,3)
11+
model = CartesianDiscreteModel(domain,cells)
12+
13+
Γ = BoundaryTriangulation(model)
14+
15+
cell_mat = [ones(3,3) for cell in 1:num_cells(Γ)]
16+
cell_vec = [ones(3) for cell in 1:num_cells(Γ)]
17+
cell_matvec = pair_arrays(cell_mat,cell_vec)
18+
19+
cell_to_bgcell = get_cell_to_bgcell(Γ)
20+
ccell_to_first_cell = compress_ids(cell_to_bgcell)
21+
@test ccell_to_first_cell == [1, 3, 4, 6, 7, 8, 10, 11, 13]
22+
23+
ccell_to_mat= compress_contributions(cell_mat,cell_to_bgcell,ccell_to_first_cell)
24+
@test length(ccell_to_mat) == 8
25+
@test ccell_to_mat[1] == 2*ones(3,3)
26+
@test ccell_to_mat[1] == 2*ones(3,3)
27+
@test ccell_to_mat[2] == ones(3,3)
28+
@test ccell_to_mat[3] == 2*ones(3,3)
29+
@test ccell_to_mat[3] == 2*ones(3,3)
30+
test_array(ccell_to_mat,collect(ccell_to_mat))
31+
32+
cache = array_cache(ccell_to_mat)
33+
@test getindex!(cache,ccell_to_mat,1) == 2*ones(3,3)
34+
@test getindex!(cache,ccell_to_mat,1) == 2*ones(3,3)
35+
@test getindex!(cache,ccell_to_mat,2) == ones(3,3)
36+
37+
ccell_to_vec = compress_contributions(cell_vec,cell_to_bgcell,ccell_to_first_cell)
38+
@test ccell_to_vec[1] == 2*ones(3)
39+
@test ccell_to_vec[1] == 2*ones(3)
40+
@test ccell_to_vec[2] == ones(3)
41+
@test ccell_to_vec[3] == 2*ones(3)
42+
@test ccell_to_vec[3] == 2*ones(3)
43+
test_array(ccell_to_vec,collect(ccell_to_vec))
44+
45+
cache = array_cache(ccell_to_vec)
46+
@test getindex!(cache,ccell_to_vec,1) == 2*ones(3)
47+
@test getindex!(cache,ccell_to_vec,1) == 2*ones(3)
48+
@test getindex!(cache,ccell_to_vec,2) == ones(3)
49+
50+
ccell_to_matvec = compress_contributions(cell_matvec,cell_to_bgcell,ccell_to_first_cell)
51+
@test ccell_to_matvec[1] == (2*ones(3,3), 2*ones(3))
52+
@test ccell_to_matvec[1] == (2*ones(3,3), 2*ones(3))
53+
@test ccell_to_matvec[2] == (ones(3,3) , ones(3) )
54+
@test ccell_to_matvec[3] == (2*ones(3,3), 2*ones(3))
55+
@test ccell_to_matvec[3] == (2*ones(3,3), 2*ones(3))
56+
test_array(ccell_to_matvec,collect(ccell_to_matvec))
57+
58+
cache = array_cache(ccell_to_matvec)
59+
@test getindex!(cache,ccell_to_matvec,1) == (2*ones(3,3), 2*ones(3))
60+
@test getindex!(cache,ccell_to_matvec,1) == (2*ones(3,3), 2*ones(3))
61+
@test getindex!(cache,ccell_to_matvec,2) == (ones(3,3) , ones(3) )
62+
63+
end # module

test/GeometryTests/runtests.jl

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ using Test
3838

3939
@testset "AppendedTriangulations" begin include("AppendedTriangulationsTests.jl") end
4040

41+
@testset "CompressedCellArrays" begin include("CompressedCellArraysTests.jl") end
42+
4143
@testset "BoundaryDiscreteModels" begin include("BoundaryDiscreteModelsTests.jl") end
4244

4345
#

0 commit comments

Comments
 (0)