@@ -38,16 +38,17 @@ Compute the nonlinear residual for the current solution.
3838function compute_nonlinear_residual! (residual, A, b, sol, unknowns, PD, SC, freedofs)
3939 residual. entries .= b. entries
4040 for j in 1 : length (b), k in 1 : length (b)
41- addblock_matmul! (residual[j], A[j, k], sol[unknowns[k]], factor = - 1 )
41+ addblock_matmul! (residual[j], A[j, k], sol[unknowns[k]], factor = - 1.0 )
4242 end
4343
44- for op in PD. operators
45- residual. entries[fixed_dofs (op)] .= 0
44+ # add Lagrange residuals
45+ for rs in PD. restrictions
46+ mul! (residual. entries, rs. parameters[:matrix ], rs. parameters[:multiplier ], - 1.0 , 1.0 )
4647 end
4748
48- mask_nonrestricted = ones (Bool, length (residual . entries))
49- for rs in PD. restrictions
50- mask_nonrestricted [fixed_dofs (rs )] .= false
49+
50+ for op in PD. operators
51+ residual . entries [fixed_dofs (op )] .= 0
5152 end
5253
5354 for u_off in SC. parameters[:inactive ]
@@ -57,10 +58,22 @@ function compute_nonlinear_residual!(residual, A, b, sol, unknowns, PD, SC, free
5758 end
5859 end
5960
60- nlres = length (freedofs) > 0 ? norm (residual. entries[freedofs]) : norm (residual. entries[mask_nonrestricted])
61+ nlres = length (freedofs) > 0 ? norm (residual. entries[freedofs]) : norm (residual. entries)
62+ restriction_residuals = [norm (rs. parameters[:matrix ]' * sol. entries - rs. parameters[:rhs ]) for rs in PD. restrictions]
6163
62- if SC. parameters[:verbosity ] > 0 && length (residual) > 1
63- @info " sub-residuals = $(norms (residual)) "
64+ if length (PD. restrictions) > 0
65+ nlres = sqrt (nlres^ 2 + norm (restriction_residuals)^ 2 )
66+ end
67+
68+ for rs in PD. restrictions
69+ mul! (residual. entries, rs. parameters[:matrix ], rs. parameters[:multiplier ], 1.0 , 1.0 )
70+ end
71+
72+ if SC. parameters[:verbosity ] > 0
73+ if length (residual) > 1
74+ @info " sub-residuals = $(norms (residual)) "
75+ end
76+ @info " nonlinear residuals of restrictions = $restriction_residuals "
6477 end
6578
6679 return nlres
@@ -244,8 +257,6 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
244257 else
245258 A_unrestricted = A. entries. cscmatrix
246259 end
247- # else
248- # A_unrestricted = A.entries.cscmatrix
249260 end
250261
251262 # we solve for A Δx = r
@@ -267,7 +278,7 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
267278 else
268279 # add possible Lagrange restrictions
269280 restriction_matrices = [length (freedofs) > 0 ? view (restriction_matrix (re), freedofs, :) : restriction_matrix (re) for re in PD. restrictions ]
270- restriction_rhss = [length (freedofs) > 0 ? view (restriction_rhs (re), freedofs) : restriction_rhs (re) for re in PD. restrictions ]
281+ restriction_rhss = deepcopy ( [length (freedofs) > 0 ? view (restriction_rhs (re), freedofs) : restriction_rhs (re) for re in PD. restrictions ])
271282
272283 # block sizes for the block matrix
273284 block_sizes = [length (b_unrestricted), [ length (b) for b in restriction_rhss ]. .. ]
@@ -278,11 +289,6 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
278289
279290 @timeit timer " LM restrictions (nLMs = $nLMs )" begin
280291
281- # # we need to add the (initial) solution to the rhs, since we work with the residual equation
282- for (B, rhs) in zip (restriction_matrices, restriction_rhss)
283- rhs .- = B' sol_freedofs
284- end
285-
286292 Tv = eltype (b_unrestricted)
287293
288294 # # create block matrix
@@ -318,6 +324,9 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
318324 restriction_matrices = [combined_restriction_matrix]
319325 restriction_rhss = [combined_restriction_rhs]
320326
327+ # remove previously defined restrictions (with explicit copy of the rhs; it is otherwise modified later)
328+ PD. restrictions = [CompressedRestriction (combined_restriction_matrix, deepcopy (combined_restriction_rhs))]
329+
321330 # update sizes
322331 block_sizes = [length (b_unrestricted), length (combined_restriction_rhs)]
323332 total_size = sum (block_sizes)
@@ -327,6 +336,11 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
327336 A_block[Block (1 , 1 )] = A_unrestricted
328337 end
329338
339+ # # we need to add the (initial) solution to the rhs, since we work with the residual equation
340+ for (B, rhs) in zip (restriction_matrices, restriction_rhss)
341+ rhs .- = B' sol_freedofs
342+ end
343+
330344 b_block = BlockVector (zeros (Tv, total_size), block_sizes)
331345
332346 b_block[Block (1 )] = b_unrestricted
@@ -406,6 +420,11 @@ function solve_linear_system!(A, b, sol, soltemp, residual, linsolve, unknowns,
406420 block_ends = cumsum (block_sizes)
407421 restriction_residuals = [norm (residual_flat[(block_ends[i] + 1 ): block_ends[i + 1 ]]) for i in 1 : (length (block_sizes) - 1 ) ]
408422 push! (stats[:restriction_residuals ], restriction_residuals)
423+
424+ # store Lagrange multipliers
425+ for (i, rs) in enumerate (PD. restrictions)
426+ rs. parameters[:multiplier ] = linsolve. u[(block_ends[i] + 1 ): block_ends[i + 1 ]]
427+ end
409428 end
410429
411430 linres = norm (residual_flat)
0 commit comments