8484
8585Initialize the linear solver for the given system.
8686"""
87- function init_linear_solver! (SC, A, timer, method_linear, precon_linear)
87+ function init_linear_solver! (SC, A, b, timer, method_linear, precon_linear)
8888
8989 # TODO use the timer
9090 time_assembly = 0.0
@@ -98,11 +98,11 @@ function init_linear_solver!(SC, A, timer, method_linear, precon_linear)
9898 stats = @timed begin
9999 abstol = SC. parameters[:abstol ]
100100 reltol = SC. parameters[:reltol ]
101- LP = SC . LP
101+ LP = LinearProblem (A, b)
102102 if precon_linear != = nothing
103- SC. linsolver = init (LP, method_linear; Pl = precon_linear (A. entries . cscmatrix ), abstol = abstol, reltol = reltol)
103+ SC. linsolver = init (LP, method_linear; Pl = precon_linear (A), abstol, reltol)
104104 else
105- SC. linsolver = init (LP, method_linear; abstol = abstol, reltol = reltol)
105+ SC. linsolver = init (LP, method_linear; abstol, reltol)
106106 end
107107 end
108108 time_assembly += stats. time
@@ -242,11 +242,10 @@ Solves the linear system and updates the solution vector. This includes:
242242- Computing the residual
243243- Updating the solution with optional damping
244244"""
245- function solve_linear_system! (A, b, sol, soltemp, residual, linsolve, unknowns, freedofs, damping, PD, SC, stats, is_linear, timer, kwargs... )
245+ function solve_linear_system! (A, b, sol, soltemp, residual, unknowns, freedofs, damping, PD, SC, stats, is_linear, timer, kwargs... )
246246
247247 @timeit timer " linear solver" begin
248248
249-
250249 # does the linsolve object need a (new) matrix?
251250 linsolve_needs_matrix = ! SC. parameters[:constant_matrix ] || ! SC. parameters[:initialized ]
252251
@@ -272,9 +271,9 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
272271
273272 if length (PD. restrictions) == 0
274273 if linsolve_needs_matrix
275- linsolve . A = A_unrestricted
274+ linsolve_A = A_unrestricted
276275 end
277- linsolve . b = b_unrestricted
276+ linsolve_b = b_unrestricted
278277 else
279278 # add possible Lagrange restrictions
280279 restriction_matrices = [length (freedofs) > 0 ? view (restriction_matrix (re), freedofs, :) : restriction_matrix (re) for re in PD. restrictions ]
@@ -342,11 +341,7 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
342341 end
343342
344343 b_block = BlockVector (zeros (Tv, total_size), block_sizes)
345-
346344 b_block[Block (1 )] = b_unrestricted
347- u_unrestricted = @views linsolve. u[1 : block_sizes[1 ]]
348- u_block = BlockVector (zeros (Tv, total_size), block_sizes)
349- u_block[Block (1 )] = u_unrestricted
350345
351346 for i in eachindex (restriction_matrices)
352347 if linsolve_needs_matrix
@@ -358,8 +353,7 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
358353 end
359354
360355 # convert to dense vectors
361- linsolve. b = Vector (b_block)
362- linsolve. u = Vector (u_block)
356+ linsolve_b = Vector (b_block)
363357
364358 if linsolve_needs_matrix
365359
@@ -379,12 +373,20 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
379373 # write each block directly in the resulting matrix
380374 A_flat[range_row, range_col] = A_block[Block (i, j)]
381375 end
382- linsolve . A = A_flat
376+ linsolve_A = A_flat
383377 end
384378 end
385379 end
386380
387- SC. parameters[:initialized ] = true
381+ if ! SC. parameters[:initialized ]
382+ # # init solver if not done before
383+ @timeit timer " linear solver" begin
384+ init_linear_solver! (SC, linsolve_A, linsolve_b, timer, method_linear, precon_linear)
385+ end
386+ SC. parameters[:initialized ] = true
387+ end
388+
389+ linsolve = SC. linsolver
388390
389391 # Solve linear system
390392 push! (stats[:matrix_nnz ], nnz (linsolve. A))
@@ -725,11 +727,6 @@ function CommonSolve.solve(PD::ProblemDescription, FES::Union{<:FESpace, Vector{
725727 @info " .... isposdef = $(isposdef (A. entries. cscmatrix)) "
726728 end
727729
728- # # init solver
729- @timeit timer " linear solver" begin
730- init_linear_solver! (SC, A, timer, method_linear, precon_linear)
731- end
732-
733730 # # compute nonlinear residual
734731 @timeit timer " assembly" @timeit timer " residual vector" begin
735732 nlres = compute_nonlinear_residual! (residual, A, b, sol, unknowns, PD, SC, freedofs)
@@ -744,11 +741,8 @@ function CommonSolve.solve(PD::ProblemDescription, FES::Union{<:FESpace, Vector{
744741 break
745742 end
746743
747- linsolve = SC. linsolver
748-
749-
750744 linres = solve_linear_system! (
751- A, b, sol, soltemp, residual, linsolve, unknowns,
745+ A, b, sol, soltemp, residual, unknowns,
752746 freedofs, damping, PD, SC, stats, is_linear, timer
753747 )
754748
0 commit comments