@@ -223,7 +223,7 @@ Solves the linear system and updates the solution vector. This includes:
223223"""
224224function solve_linear_system! (A, b, sol, soltemp, residual, linsolve, unknowns, freedofs, damping, PD, SC, stats, is_linear, timer, kwargs... )
225225
226- @timeit timer " Lagrange restrictions " begin
226+ @timeit timer " assembly " begin
227227 # # assemble restrctions
228228 if ! SC. parameters[:initialized ]
229229 for restriction in PD. restrictions
@@ -255,67 +255,64 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
255255 linsolve. b = b_unrestricted
256256 else
257257
258- @timeit timer " LM restrictions" begin
259- # # add possible Lagrange restrictions
260- @timeit timer " prepare" begin
261- restriction_matrices = [length (freedofs) > 0 ? re. parameters[:matrix ][freedofs, :] : re. parameters[:matrix ] for re in PD. restrictions ]
262- restriction_rhs = [length (freedofs) > 0 ? re. parameters[:rhs ][freedofs] : re. parameters[:rhs ] for re in PD. restrictions ]
258+ # add possible Lagrange restrictions
259+ restriction_matrices = [length (freedofs) > 0 ? re. parameters[:matrix ][freedofs, :] : re. parameters[:matrix ] for re in PD. restrictions ]
260+ restriction_rhs = [length (freedofs) > 0 ? re. parameters[:rhs ][freedofs] : re. parameters[:rhs ] for re in PD. restrictions ]
263261
264- # # we need to add the (initial) solution to the rhs, since we work with the residual equation
265- for (B, rhs) in zip (restriction_matrices, restriction_rhs)
266- rhs .+ = B' sol. entries
267- end
268- end
262+ # block sizes for the block matrix
263+ block_sizes = [size (A_unrestricted, 2 ), [ size (B, 2 ) for B in restriction_matrices ]. .. ]
269264
270- @timeit timer " set blocks" begin
271- # block sizes for the block matrix
272- block_sizes = [size (A_unrestricted, 2 ), [ size (B, 2 ) for B in restriction_matrices ]. .. ]
265+ # total number of additional LM dofs
266+ nLMs = @views sum (block_sizes[2 : end ])
273267
274- total_size = sum (block_sizes)
275- Tv = eltype (A_unrestricted)
268+ @timeit timer " LM restrictions (nLMs = $nLMs )" begin
276269
277- # # create block matrix
278- A_block = BlockMatrix (spzeros (Tv, total_size, total_size), block_sizes, block_sizes)
279- A_block[Block (1 , 1 )] = A_unrestricted
270+ # # we need to add the (initial) solution to the rhs, since we work with the residual equation
271+ for (B, rhs) in zip (restriction_matrices, restriction_rhs)
272+ rhs .+ = B' sol. entries
273+ end
280274
281- b_block = BlockVector ( zeros (Tv, total_size), block_sizes)
282- b_block[ Block ( 1 )] = b_unrestricted
275+ total_size = sum ( block_sizes)
276+ Tv = eltype (A_unrestricted)
283277
284- u_unrestricted = linsolve . u
285- u_block = BlockVector ( zeros (Tv, total_size) , block_sizes)
286- u_block [Block (1 )] = u_unrestricted
278+ # # create block matrix
279+ A_block = BlockMatrix ( spzeros (Tv, total_size, total_size), block_sizes , block_sizes)
280+ A_block [Block (1 , 1 )] = A_unrestricted
287281
288- for i in eachindex (PD. restrictions)
289- A_block[Block (1 , i + 1 )] = restriction_matrices[i]
290- A_block[Block (i + 1 , 1 )] = transpose (restriction_matrices[i])
291- b_block[Block (i + 1 )] = restriction_rhs[i]
282+ b_block = BlockVector (zeros (Tv, total_size), block_sizes)
283+ b_block[Block (1 )] = b_unrestricted
292284
293- end
294- end
285+ u_unrestricted = linsolve. u
286+ u_block = BlockVector (zeros (Tv, total_size), block_sizes)
287+ u_block[Block (1 )] = u_unrestricted
288+
289+ for i in eachindex (PD. restrictions)
290+ A_block[Block (1 , i + 1 )] = restriction_matrices[i]
291+ A_block[Block (i + 1 , 1 )] = transpose (restriction_matrices[i])
292+ b_block[Block (i + 1 )] = restriction_rhs[i]
295293
296- @timeit timer " convert " begin
294+ end
297295
298- linsolve. b = Vector (b_block) # convert to dense vector
299- linsolve. u = Vector (u_block) # convert to dense vector
296+ linsolve. b = Vector (b_block) # convert to dense vector
297+ linsolve. u = Vector (u_block) # convert to dense vector
300298
301- # linsolve.A = sparse(A_block) # convert to CSC Matrix is very slow https://github.com/JuliaArrays/BlockArrays.jl/issues/78
302- # do it manually:
303- A_flat = spzeros (size (A_block))
299+ # linsolve.A = sparse(A_block) # convert to CSC Matrix is very slow https://github.com/JuliaArrays/BlockArrays.jl/issues/78
300+ # do it manually:
301+ A_flat = spzeros (size (A_block))
304302
305- lasts_i = [0 , axes (A_block)[1 ]. lasts... ] # add zero
306- lasts_j = [0 , axes (A_block)[2 ]. lasts... ] # add zero
303+ lasts_row = [0 , axes (A_block)[1 ]. lasts... ] # add leading zero
304+ lasts_col = [0 , axes (A_block)[2 ]. lasts... ] # add leading zero
307305
308- (ni, nj ) = size (blocks (A_block))
306+ (n_row, n_col ) = size (blocks (A_block))
309307
310- for i in 1 : ni , j in 1 : nj
311- range_i = (lasts_i [i] + 1 ): lasts_i [i + 1 ]
312- range_j = (lasts_j [j] + 1 ): lasts_j [j + 1 ]
308+ for i in 1 : n_row , j in 1 : n_col
309+ range_row = (lasts_row [i] + 1 ): lasts_row [i + 1 ]
310+ range_col = (lasts_col [j] + 1 ): lasts_col [j + 1 ]
313311
314- # write each block directly in the resulting matrix
315- A_flat[range_i, range_j] = A_block[Block (i, j)]
316- end
317- linsolve. A = A_flat
312+ # write each block directly in the resulting matrix
313+ A_flat[range_row, range_col] = A_block[Block (i, j)]
318314 end
315+ linsolve. A = A_flat
319316 end
320317 end
321318
0 commit comments