@@ -223,7 +223,7 @@ Solves the linear system and updates the solution vector. This includes:
223
223
"""
224
224
function solve_linear_system! (A, b, sol, soltemp, residual, linsolve, unknowns, freedofs, damping, PD, SC, stats, is_linear, timer, kwargs... )
225
225
226
- @timeit timer " Lagrange restrictions " begin
226
+ @timeit timer " assembly " begin
227
227
# # assemble restrctions
228
228
if ! SC. parameters[:initialized ]
229
229
for restriction in PD. restrictions
@@ -255,67 +255,64 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
255
255
linsolve. b = b_unrestricted
256
256
else
257
257
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 ]
263
261
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 ]. .. ]
269
264
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 ])
273
267
274
- total_size = sum (block_sizes)
275
- Tv = eltype (A_unrestricted)
268
+ @timeit timer " LM restrictions (nLMs = $nLMs )" begin
276
269
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
280
274
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)
283
277
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
287
281
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
292
284
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]
295
293
296
- @timeit timer " convert " begin
294
+ end
297
295
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
300
298
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))
304
302
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
307
305
308
- (ni, nj ) = size (blocks (A_block))
306
+ (n_row, n_col ) = size (blocks (A_block))
309
307
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 ]
313
311
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)]
318
314
end
315
+ linsolve. A = A_flat
319
316
end
320
317
end
321
318
0 commit comments