@@ -287,9 +287,7 @@ function smoothed_aggregation(;
287
287
tentative_prolongator = tentative_prolongator_for_laplace,
288
288
repartition_threshold = 2000 ,
289
289
)
290
- function coarsen (operator)
291
- A = matrix (operator)
292
- B = nullspace (operator)
290
+ function coarsen (A,B)
293
291
diagA = dense_diag (A)
294
292
node_to_aggregate, aggregates = aggregate (A,diagA;epsilon)
295
293
n_nullspace_vecs = length (B)
@@ -299,14 +297,11 @@ function smoothed_aggregation(;
299
297
R = transpose (P)
300
298
Ac,cache = rap (R,A,P;reuse= true )
301
299
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
304
301
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)
308
303
rap! (Ac,R,A,P,cache)
309
- coarse_operator ,R,P,cache
304
+ Ac ,R,P,cache
310
305
end
311
306
(coarsen, coarsen!)
312
307
end
@@ -341,14 +336,18 @@ function amg(;
341
336
fine_params= amg_fine_params (),
342
337
coarse_params= amg_coarse_params (),)
343
338
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 !
346
341
solve! = amg_solve!
347
342
finalize! = amg_finalize!
348
- linear_solver (;setup,setup !,solve!,finalize!)
343
+ linear_solver (;setup,update !,solve!,finalize!)
349
344
end
350
345
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)
352
351
fine_params = amg_params. fine_params
353
352
coarse_params = amg_params. coarse_params
354
353
(;coarse_solver,coarse_size) = coarse_params
@@ -358,11 +357,10 @@ function amg_setup(x,operator,b,amg_params)
358
357
return nothing
359
358
end
360
359
(;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)
363
362
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)
366
364
nc = size (Ac,1 )
367
365
if nc <= coarse_size
368
366
done = true
@@ -373,20 +371,21 @@ function amg_setup(x,operator,b,amg_params)
373
371
e = similar (x)
374
372
ec = similar (e,axes (Ac,2 ))
375
373
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 )
377
375
x = ec
378
376
b = rc
379
- operator = coarse_operator
377
+ A = Ac
378
+ B = Bc
380
379
level_setup
381
380
end
382
381
n_fine_levels = count (i-> i!= = nothing ,fine_levels)
383
382
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)
385
384
coarse_level = (;coarse_solver_setup)
386
385
(;nlevels,fine_levels,coarse_level,amg_params)
387
386
end
388
387
389
- function amg_solve! (x,setup,b)
388
+ function amg_solve! (x,setup,b,options )
390
389
level= 1
391
390
amg_cycle! (x,setup,b,level)
392
391
x
@@ -395,16 +394,14 @@ end
395
394
function amg_cycle! (x,setup,b,level)
396
395
amg_params = setup. amg_params
397
396
if level == setup. nlevels
398
- coarse_solver = amg_params. coarse_params. coarse_solver
399
397
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)
401
399
end
402
400
level_params = amg_params. fine_params[level]
403
401
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)
408
405
mul! (r,A,x)
409
406
r .= b .- r
410
407
mul! (rc2,R,r)
@@ -414,28 +411,29 @@ function amg_cycle!(x,setup,b,level)
414
411
ec2 .= ec
415
412
mul! (e,P,ec2)
416
413
x .+ = e
417
- solve! (pos_smoother)( x,pos_setup,b)
414
+ solve! (x,pos_setup,b)
418
415
x
419
416
end
420
417
421
- function amg_statistics (setup )
418
+ function amg_statistics (P :: Preconditioner )
422
419
# Taken from: An Introduction to Algebraic Multigrid, R. D. Falgout, April 25, 2006
423
420
# Grid complexity is the total number of grid points on all grids divided by the number
424
421
# of grid points on the fine grid. Operator complexity is the total number of nonzeroes in the linear operators
425
422
# on all grids divided by the number of nonzeroes in the fine grid operator
423
+ setup = P. solver_setup
426
424
nlevels = setup. nlevels
427
425
level_rows = zeros (Int,nlevels)
428
426
level_nnz = zeros (Int,nlevels)
429
427
for level in 1 : (nlevels- 1 )
430
428
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 )
434
432
end
435
433
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 )
439
437
nnz_total = sum (level_nnz)
440
438
rows_total = sum (level_rows)
441
439
level_id = collect (1 : nlevels)
@@ -461,23 +459,22 @@ end
461
459
amg_cycle! (args... )
462
460
end
463
461
464
- function amg_setup ! (setup,operator )
462
+ function amg_update ! (setup,A,options )
465
463
amg_params = setup. amg_params
466
464
nlevels = setup. nlevels
467
465
for level in 1 : (nlevels- 1 )
468
466
level_params = amg_params. fine_params[level]
469
467
level_setup = setup. fine_levels[level]
470
- (;coarsening,pre_smoother,pos_smoother ) = level_params
468
+ (;coarsening) = level_params
471
469
_, 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
477
475
end
478
- coarse_solver = amg_params. coarse_params. coarse_solver
479
476
coarse_solver_setup = setup. coarse_level. coarse_solver_setup
480
- setup! (coarse_solver)( coarse_solver_setup,operator )
477
+ update! ( coarse_solver_setup,A )
481
478
setup
482
479
end
483
480
@@ -487,14 +484,12 @@ function amg_finalize!(setup)
487
484
for level in 1 : (nlevels- 1 )
488
485
level_params = amg_params. fine_params[level]
489
486
level_setup = setup. fine_levels[level]
490
- (;pre_smoother,pos_smoother) = level_params
491
487
(;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)
494
490
end
495
- coarse_solver = amg_params. coarse_params. coarse_solver
496
491
coarse_solver_setup = setup. coarse_level. coarse_solver_setup
497
- finalize! (coarse_solver)( coarse_solver_setup)
492
+ finalize! (coarse_solver_setup)
498
493
nothing
499
494
end
500
495
0 commit comments