Skip to content

Commit 56ddd10

Browse files
2 parents 4be25ee + ed2c8a8 commit 56ddd10

21 files changed

Lines changed: 580 additions & 257 deletions

.github/workflows/Check.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- uses: julia-actions/setup-julia@v2
2525
with:
2626
version: '1.11'
27-
- uses: julia-actions/cache@v2
27+
- uses: julia-actions/cache@v3
2828
- uses: fredrikekre/runic-action@v1
2929
with:
3030
version: "1.4" # Keep version in sync with .pre-commit-config.yaml
@@ -37,7 +37,7 @@ jobs:
3737
# - uses: julia-actions/setup-julia@v2
3838
# with:
3939
# version: '1'
40-
- uses: julia-actions/cache@v2
40+
- uses: julia-actions/cache@v3
4141
- uses: julia-actions/julia-buildpkg@v1
4242
- name: Install dependencies
4343
shell: julia {0}

.github/workflows/Documentation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
- uses: julia-actions/setup-julia@v2
1515
with:
1616
version: '1.12'
17-
- uses: julia-actions/cache@v2
17+
- uses: julia-actions/cache@v3
1818
- name: Install dependencies
1919
run: julia --project=docs -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'
2020
- name: Build and deploy

.github/workflows/Downstream.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- uses: julia-actions/setup-julia@v2
3434
with:
3535
version: ${{ matrix.julia-version }}
36-
- uses: julia-actions/cache@v2
36+
- uses: julia-actions/cache@v3
3737
# - uses: julia-actions/julia-buildpkg@v1
3838
- name: Clone Downstream
3939
uses: actions/checkout@v6

.github/workflows/SpellCheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ jobs:
1010
- name: Checkout Actions Repository
1111
uses: actions/checkout@v6
1212
- name: Check spelling
13-
uses: crate-ci/typos@v1.44.0
13+
uses: crate-ci/typos@v1.45.0

.github/workflows/Test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- uses: julia-actions/setup-julia@v2
2525
with:
2626
version: ${{ matrix.julia-version }}
27-
- uses: julia-actions/cache@v2
27+
- uses: julia-actions/cache@v3
2828
- uses: julia-actions/julia-buildpkg@v1
2929
- uses: julia-actions/julia-runtest@v1
3030
- name: JET tests
@@ -38,7 +38,7 @@ jobs:
3838
- uses: julia-actions/julia-processcoverage@v1
3939
with:
4040
directories: 'src,ext'
41-
- uses: codecov/codecov-action@v5
41+
- uses: codecov/codecov-action@v6
4242
with:
4343
files: lcov.info
4444
plugins: noop

benchmark/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
[deps]
22
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
3+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
34
Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992"
45
PkgBenchmark = "32113eaa-f34f-5b0d-bd6c-c81e245fc73d"
6+
SparseMatricesCSR = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1"
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using Ferrite
2+
using SparseMatricesCSR: SparseMatrixCSR
3+
using SparseArrays: SparseMatrixCSC
4+
using DataFrames
5+
using Ferrite: FastSparsityPattern
6+
7+
function dh_scalar(grid)
8+
CT = getcelltype(grid)
9+
RS = getrefshape(CT)
10+
return close!(add!(DofHandler(grid), :u, Lagrange{RS, 1}()))
11+
end
12+
13+
function dh_complex(grid::Grid{sdim}) where {sdim}
14+
CT = getcelltype(grid)
15+
RS = getrefshape(CT)
16+
dh = DofHandler(grid)
17+
add!(dh, :u, Lagrange{RS, 2}())
18+
add!(dh, :v, Lagrange{RS, 1}()^sdim)
19+
return close!(dh)
20+
end
21+
22+
create_sp(dh) = add_sparsity_entries!(init_sparsity_pattern(dh), dh)
23+
create_fsp(dh) = FastSparsityPattern(dh)
24+
25+
grid_2d = generate_grid(Triangle, 1000 .* (1, 1))
26+
grid_3d = generate_grid(Hexahedron, 80 .* (1, 1, 1))
27+
28+
dofhandlers = [
29+
"dh_2d_scalar" => dh_scalar(grid_2d),
30+
"dh_3d_scalar" => dh_scalar(grid_3d),
31+
"dh_2d_complex" => dh_complex(grid_2d),
32+
"dh_3d_complex" => dh_complex(grid_3d),
33+
]
34+
35+
function timef(f::F, ::Type{MatrixType}, args...; kwargs...) where {F, MatrixType}
36+
sp0 = f(args...; kwargs...) # Compile
37+
allocate_matrix(MatrixType, sp0) # Compile
38+
GC.gc()
39+
sp_allocs = @allocations (sp_runtime = @elapsed (sp = f(args...; kwargs...)))
40+
m_allocs = @allocations (m_runtime = @elapsed allocate_matrix(MatrixType, sp))
41+
return (; sp_t = sp_runtime, sp_a = sp_allocs, m_t = m_runtime, m_a = m_allocs)
42+
end
43+
44+
function fmt_time(t::Number; digits = 2)
45+
units = ["ns", "μs", "ms", "s", "min", "h"]
46+
values = [1.0e-9, 1.0e-6, 1.0e-3, 1.0, 60.0, 3600]
47+
idx = findfirst(v -> v > t, values)
48+
i = max(idx === nothing ? length(values) : idx - 1, 1)
49+
return string(round(t / values[i]; digits)) * " " * units[i]
50+
end
51+
52+
function fmt_count(n::Integer; digits = 2)
53+
units = ["k", "M", "G"]
54+
values = [1.0e3, 1.0e6, 1.0e9]
55+
n < 1000 && return string(n)
56+
i = findlast(v -> v n, values)
57+
return string(round(n / values[i]; digits)) * units[i]
58+
end
59+
60+
function make_timings(MatrixType)
61+
return map([create_sp, create_fsp]) do f
62+
[key => timef(f, MatrixType, dh) for (key, dh) in dofhandlers]
63+
end
64+
end
65+
66+
function make_df(timings)
67+
_getdata(v, k) = getindex.(last.(v), k)
68+
return DataFrame(
69+
"case" => first.(dofhandlers),
70+
"t (sp) [s]" => fmt_time.(_getdata(timings[1], :sp_t)),
71+
"t (fsp) [s]" => fmt_time.(_getdata(timings[2], :sp_t)),
72+
"allocs (sp)" => fmt_count.(_getdata(timings[1], :sp_a)),
73+
"allocs (fsp)" => fmt_count.(_getdata(timings[2], :sp_a)),
74+
"t (K,sp) [s]" => fmt_time.(_getdata(timings[1], :m_t)),
75+
"t (K,fsp) [s]" => fmt_time.(_getdata(timings[2], :m_t)),
76+
"allocs (K,sp)" => fmt_count.(_getdata(timings[1], :m_a)),
77+
"allocs (K,fsp)" => fmt_count.(_getdata(timings[2], :m_a))
78+
)
79+
end
80+
81+
display(make_df(make_timings(SparseMatrixCSC{Float64, Int})))
82+
# display(make_df(make_timings(SparseMatrixCSR)))

docs/src/devdocs/assembly.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
# [Assembly](@id devdocs-assembly)
22

3-
The assembler handles the insertion of the element matrices and element vectors into the system matrix and right hand side.
3+
An assembler handles the insertion of the element matrices and element vectors into the system matrix and vector.
4+
and should *normally* (the exact interface is yet to be fully established) subtype `AbstractAssembler{T}`. Here `T` is the
5+
`eltype` of the contained system matrix and vector. This allows the user to infer the eltype when preallocating the element
6+
matrix and vector, e.g.
7+
```julia
8+
function doassemble!(assembler::Ferrite.AbstractAssembler{T}, ...) where {T}
9+
Ke = zeros(T, n, n) # n = dofs per cell
10+
fe = zeros(T, n)
11+
for cell in CellIterator(...)
12+
element_routine!(Ke, fe, cell, ...)
13+
assemble!(assembler, celldofs(cell), Ke, fe)
14+
end
15+
end
16+
```
417

518
## Custom matrix formats
619
While the CSC and CSR formats are the most common sparse matrix formats in practice, users might want to have optimized custom matrix formats for their specific use-case. The default assemblers [`Ferrite.CSCAssembler`](@ref) and [`Ferrite.CSRAssembler`](@ref) should be able to handle most cases in practice. To support a custom format users have to dispatch the following functions on their matrix type. There is the public interface

docs/src/devdocs/interpolations.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ order. The [how-to at bottom of this page](@ref devdocs-howto_new-interpolation)
1111
Ferrite.reference_shape_value(::Interpolation, ::Vec, ::Int)
1212
Ferrite.reference_coordinates(::Interpolation)
1313
Ferrite.vertexdof_indices(::Interpolation)
14-
Ferrite.facedof_indices(::Interpolation)
1514
Ferrite.facedof_interior_indices(::Interpolation)
16-
Ferrite.edgedof_indices(::Interpolation)
1715
Ferrite.edgedof_interior_indices(::Interpolation)
1816
Ferrite.volumedof_interior_indices(::Interpolation)
1917
Ferrite.adjust_dofs_during_distribution(::Interpolation)
@@ -41,6 +39,13 @@ Ferrite.mapping_type
4139
Ferrite.get_direction
4240
```
4341

42+
#### Interpolations that cannot be constructed from their type
43+
For interpolations, `ip`, for which `ip == typeof(ip)()` is false (or doesn't work), the following must be implemented manually
44+
```@docs
45+
Ferrite.edgedof_indices(::Interpolation)
46+
Ferrite.facedof_indices(::Interpolation)
47+
```
48+
4449
### The defaults should always work
4550
The following functions are defined such that they should work for
4651
any interpolations that defines the required functions specified above.

docs/src/devdocs/special_datastructures.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ Ferrite.ArrayOfVectorViews
1414
Ferrite.ConstructionBuffer
1515
Ferrite.push_at_index!
1616
```
17+
18+
## `FastSparsityPattern`
19+
```@docs
20+
Ferrite.FastSparsityPattern
21+
```

0 commit comments

Comments
 (0)