@@ -287,9 +287,7 @@ function smoothed_aggregation(;
287287 tentative_prolongator = tentative_prolongator_for_laplace,
288288 repartition_threshold = 2000 ,
289289 )
290- function coarsen (operator)
291- A = matrix (operator)
292- B = nullspace (operator)
290+ function coarsen (A,B)
293291 diagA = dense_diag (A)
294292 node_to_aggregate, aggregates = aggregate (A,diagA;epsilon)
295293 n_nullspace_vecs = length (B)
@@ -299,14 +297,11 @@ function smoothed_aggregation(;
299297 R = transpose (P)
300298 Ac,cache = rap (R,A,P;reuse= true )
301299 Ac,Bc,R,P,cache,repartition_threshold = enhance_coarse_partition (A,Ac,Bc,R,P,cache,repartition_threshold)
302- coarse_operator = attach_nullspace (Ac,Bc)
303- coarse_operator,R,P,cache
300+ Ac,Bc,R,P,cache
304301 end
305- function coarsen! (operator,coarse_operator,R,P,cache)
306- A = matrix (operator)
307- Ac = matrix (coarse_operator)
302+ function coarsen! (A,Ac,R,P,cache)
308303 rap! (Ac,R,A,P,cache)
309- coarse_operator ,R,P,cache
304+ Ac ,R,P,cache
310305 end
311306 (coarsen, coarsen!)
312307end
@@ -341,14 +336,18 @@ function amg(;
341336 fine_params= amg_fine_params (),
342337 coarse_params= amg_coarse_params (),)
343338 amg_params = (;fine_params,coarse_params)
344- setup (x,O,b) = amg_setup (x,O,b,amg_params)
345- setup ! = amg_setup !
339+ setup (x,O,b,options ) = amg_setup (x,O,b, nullspace (options) ,amg_params)
340+ update ! = amg_update !
346341 solve! = amg_solve!
347342 finalize! = amg_finalize!
348- linear_solver (;setup,setup !,solve!,finalize!)
343+ linear_solver (;setup,update !,solve!,finalize!)
349344end
350345
351- function amg_setup (x,operator,b,amg_params)
346+ function amg_setup (x,A,b,:: Nothing ,amg_params)
347+ B = default_nullspace (A)
348+ amg_setup (x,A,b,B,amg_params)
349+ end
350+ function amg_setup (x,A,b,B,amg_params)
352351 fine_params = amg_params. fine_params
353352 coarse_params = amg_params. coarse_params
354353 (;coarse_solver,coarse_size) = coarse_params
@@ -358,11 +357,10 @@ function amg_setup(x,operator,b,amg_params)
358357 return nothing
359358 end
360359 (;pre_smoother,pos_smoother,coarsening,cycle) = fine_level
361- pre_setup = setup (pre_smoother)(x,operator ,b)
362- pos_setup = setup (pos_smoother)(x,operator ,b)
360+ pre_setup = setup (pre_smoother,x,A ,b)
361+ pos_setup = setup (pos_smoother,x,A ,b)
363362 coarsen, _ = coarsening
364- coarse_operator,R,P,coarse_operator_setup = coarsen (operator)
365- Ac = matrix (coarse_operator)
363+ Ac,Bc,R,P,Ac_setup = coarsen (A,B)
366364 nc = size (Ac,1 )
367365 if nc <= coarse_size
368366 done = true
@@ -373,20 +371,21 @@ function amg_setup(x,operator,b,amg_params)
373371 e = similar (x)
374372 ec = similar (e,axes (Ac,2 ))
375373 ec2 = similar (e,axes (P,2 )) # TODO
376- level_setup = (;R,P,r,rc,rc2,e,ec,ec2,operator,coarse_operator, pre_setup,pos_setup,coarse_operator_setup )
374+ level_setup = (;R,P,r,rc,rc2,e,ec,ec2,A,B,Ac,Bc, pre_setup,pos_setup,Ac_setup )
377375 x = ec
378376 b = rc
379- operator = coarse_operator
377+ A = Ac
378+ B = Bc
380379 level_setup
381380 end
382381 n_fine_levels = count (i-> i!= = nothing ,fine_levels)
383382 nlevels = n_fine_levels+ 1
384- coarse_solver_setup = setup (coarse_solver)(x,operator ,b)
383+ coarse_solver_setup = setup (coarse_solver,x,A ,b)
385384 coarse_level = (;coarse_solver_setup)
386385 (;nlevels,fine_levels,coarse_level,amg_params)
387386end
388387
389- function amg_solve! (x,setup,b)
388+ function amg_solve! (x,setup,b,options )
390389 level= 1
391390 amg_cycle! (x,setup,b,level)
392391 x
@@ -395,16 +394,14 @@ end
395394function amg_cycle! (x,setup,b,level)
396395 amg_params = setup. amg_params
397396 if level == setup. nlevels
398- coarse_solver = amg_params. coarse_params. coarse_solver
399397 coarse_solver_setup = setup. coarse_level. coarse_solver_setup
400- return solve! (coarse_solver)( x,coarse_solver_setup,b)
398+ return solve! (x,coarse_solver_setup,b)
401399 end
402400 level_params = amg_params. fine_params[level]
403401 level_setup = setup. fine_levels[level]
404- (;pre_smoother,pos_smoother,cycle) = level_params
405- (;R,P,r,rc,rc2,e,ec,ec2,operator,coarse_operator,pre_setup,pos_setup) = level_setup
406- solve! (pre_smoother)(x,pre_setup,b)
407- A = matrix (operator)
402+ (;cycle) = level_params
403+ (;R,P,r,rc,rc2,e,ec,ec2,A,Ac,pre_setup,pos_setup) = level_setup
404+ solve! (x,pre_setup,b)
408405 mul! (r,A,x)
409406 r .= b .- r
410407 mul! (rc2,R,r)
@@ -414,28 +411,29 @@ function amg_cycle!(x,setup,b,level)
414411 ec2 .= ec
415412 mul! (e,P,ec2)
416413 x .+ = e
417- solve! (pos_smoother)( x,pos_setup,b)
414+ solve! (x,pos_setup,b)
418415 x
419416end
420417
421- function amg_statistics (setup )
418+ function amg_statistics (P :: Preconditioner )
422419 # Taken from: An Introduction to Algebraic Multigrid, R. D. Falgout, April 25, 2006
423420 # Grid complexity is the total number of grid points on all grids divided by the number
424421 # of grid points on the fine grid. Operator complexity is the total number of nonzeroes in the linear operators
425422 # on all grids divided by the number of nonzeroes in the fine grid operator
423+ setup = P. solver_setup
426424 nlevels = setup. nlevels
427425 level_rows = zeros (Int,nlevels)
428426 level_nnz = zeros (Int,nlevels)
429427 for level in 1 : (nlevels- 1 )
430428 level_setup = setup. fine_levels[level]
431- (;operator ,) = level_setup
432- level_rows[level] = size (matrix (operator) ,1 )
433- level_nnz[level] = nnz (matrix (operator) )
429+ (;A ,) = level_setup
430+ level_rows[level] = size (A ,1 )
431+ level_nnz[level] = nnz (A )
434432 end
435433 level_setup = setup. fine_levels[nlevels- 1 ]
436- (;coarse_operator ) = level_setup
437- level_rows[end ] = size (matrix (coarse_operator) ,1 )
438- level_nnz[end ] = nnz (matrix (coarse_operator) )
434+ (;Ac ) = level_setup
435+ level_rows[end ] = size (Ac ,1 )
436+ level_nnz[end ] = nnz (Ac )
439437 nnz_total = sum (level_nnz)
440438 rows_total = sum (level_rows)
441439 level_id = collect (1 : nlevels)
@@ -461,23 +459,22 @@ end
461459 amg_cycle! (args... )
462460end
463461
464- function amg_setup ! (setup,operator )
462+ function amg_update ! (setup,A,options )
465463 amg_params = setup. amg_params
466464 nlevels = setup. nlevels
467465 for level in 1 : (nlevels- 1 )
468466 level_params = amg_params. fine_params[level]
469467 level_setup = setup. fine_levels[level]
470- (;coarsening,pre_smoother,pos_smoother ) = level_params
468+ (;coarsening) = level_params
471469 _, coarsen! = coarsening
472- (;R,P,operator,coarse_operator,coarse_operator_setup ,pre_setup,pos_setup) = level_setup
473- setup! (pre_smoother)( pre_setup,operator )
474- setup! (pos_smoother)( pos_setup,operator )
475- coarsen! (operator,coarse_operator ,R,P,coarse_operator_setup )
476- operator = coarse_operator
470+ (;R,P,A,Ac,Ac_setup ,pre_setup,pos_setup) = level_setup
471+ update! ( pre_setup,A )
472+ update! ( pos_setup,A )
473+ coarsen! (A,Ac ,R,P,Ac_setup )
474+ A = Ac
477475 end
478- coarse_solver = amg_params. coarse_params. coarse_solver
479476 coarse_solver_setup = setup. coarse_level. coarse_solver_setup
480- setup! (coarse_solver)( coarse_solver_setup,operator )
477+ update! ( coarse_solver_setup,A )
481478 setup
482479end
483480
@@ -487,14 +484,12 @@ function amg_finalize!(setup)
487484 for level in 1 : (nlevels- 1 )
488485 level_params = amg_params. fine_params[level]
489486 level_setup = setup. fine_levels[level]
490- (;pre_smoother,pos_smoother) = level_params
491487 (;pre_setup,pos_setup) = level_setup
492- finalize! (pre_smoother)( pre_setup)
493- finalize! (pos_smoother)( pos_setup)
488+ finalize! (pre_setup)
489+ finalize! (pos_setup)
494490 end
495- coarse_solver = amg_params. coarse_params. coarse_solver
496491 coarse_solver_setup = setup. coarse_level. coarse_solver_setup
497- finalize! (coarse_solver)( coarse_solver_setup)
492+ finalize! (coarse_solver_setup)
498493 nothing
499494end
500495
0 commit comments