Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/aggregation.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
function smoothed_aggregation(A::TA, _B = nothing,
function smoothed_aggregation(A::TA,
::Type{Val{bs}}=Val{1};
B = nothing,
symmetry = HermitianSymmetry(),
strength = SymmetricStrength(),
aggregate = StandardAggregation(),
Expand All @@ -12,9 +13,8 @@ function smoothed_aggregation(A::TA, _B = nothing,
diagonal_dominance = false,
keep = false,
coarse_solver = Pinv, kwargs...) where {T,V,bs,TA<:SparseMatrixCSC{T,V}}

n = size(A, 1)
B = isnothing(_B) ? ones(T,n) : copy(_B)
B = isnothing(B) ? ones(T,n) : copy(B)
@assert size(A, 1) == size(B, 1)

#=max_levels, max_coarse, strength =
Expand Down
44 changes: 2 additions & 42 deletions src/multilevel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,47 +287,7 @@ end
abstract type AMGAlg end

struct RugeStubenAMG <: AMGAlg end

"""
SmoothedAggregationAMG(B=nothing)

Smoothed Aggregation AMG (Algebraic Multigrid) algorithm configuration.

# Arguments
- `B::Union{AbstractArray, Nothing}`: The **near null space** in SA-AMG represents the low energy that cannot be attenuated by relaxtion, and thus needs to be perserved across the coarse grid.

- `B` can be:
- a `Vector` (e.g., for scalar PDEs),
- a `Matrix` (e.g., for vector PDEs or systems with multiple equations),
- or `nothing`.

# Notes
If `B` is set to `nothing`, it will be internally defaulted to `B = ones(T, n)`, where `T = eltype(A)` and `n = size(A, 1)`.

# Examples

**Poisson equation (scalar PDE):**
```julia
n = size(A, 1)
B = ones(Float64, n)
amg = SmoothedAggregationAMG(B)
```

**Linear elasticity equation in 2d (vector PDE):**
```julia
n = size(A, 1) # Ndof = 2 * number of nodes
B = zeros(Float64, n, 3)
B[1:2:end, :] = [1.0, 0.0, -y]
B[2:2:end, :] = [0.0, 1.0, x]
amg = SmoothedAggregationAMG(B)
```
"""
struct SmoothedAggregationAMG <: AMGAlg
B::Union{<:AbstractArray,Nothing} # `B` can be `Vector`, `Matrix`, or `nothing`
function SmoothedAggregationAMG(B::Union{AbstractArray,Nothing}=nothing)
new(B)
end
end
struct SmoothedAggregationAMG <: AMGAlg end

function solve(A::AbstractMatrix, b::Vector, s::AMGAlg, args...; kwargs...)
solt = init(s, A, b, args...; kwargs...)
Expand All @@ -337,7 +297,7 @@ function init(::RugeStubenAMG, A, b, args...; kwargs...)
AMGSolver(ruge_stuben(A; kwargs...), b)
end
function init(sa::SmoothedAggregationAMG, A, b; kwargs...)
AMGSolver(smoothed_aggregation(A,sa.B; kwargs...), b)
AMGSolver(smoothed_aggregation(A; kwargs...), b)
end
function solve!(solt::AMGSolver, args...; kwargs...)
_solve(solt.ml, solt.b, args...; kwargs...)
Expand Down
3 changes: 1 addition & 2 deletions src/precs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ function SmoothedAggregationPreconBuilder(; blocksize = 1, kwargs...)
end

function (b::SmoothedAggregationPreconBuilder)(A::AbstractSparseMatrixCSC, p)
B = get(b.kwargs, :B, nothing) # extract nns from kwargs, default to `nothing`
return (aspreconditioner(smoothed_aggregation(SparseMatrixCSC(A), B, Val{b.blocksize}; b.kwargs...)),I)
return (aspreconditioner(smoothed_aggregation(SparseMatrixCSC(A), Val{b.blocksize}; b.kwargs...)), I)
end


Expand Down
15 changes: 6 additions & 9 deletions test/nns_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

#2. pass `B` as vector
B = ones(T,n)
x_vec = solve(A, b, SmoothedAggregationAMG(B), maxiter = 1, abstol = 1e-6)
x_vec = solve(A, b, SmoothedAggregationAMG(), maxiter = 1, abstol = 1e-6;B=B)
@test x_vec ≈ x_nothing

#3. pass `B` as matrix
B = ones(T,n,1)
x_mat = solve(A, b, SmoothedAggregationAMG(B), maxiter = 1, abstol = 1e-6)
x_mat = solve(A, b, SmoothedAggregationAMG(), maxiter = 1, abstol = 1e-6;B=B)
@test x_mat ≈ x_nothing
end

Expand Down Expand Up @@ -194,11 +194,8 @@ end
@load "lin_elastic_2d.jld2" A b B
A = SparseMatrixCSC(A.m, A.n, A.colptr, A.rowval, A.nzval)

x_nns, residuals_nns = solve(A, b, SmoothedAggregationAMG(B); log=true, reltol=1e-10)
x_wonns, residuals_wonns = solve(A, b, SmoothedAggregationAMG(); log=true, reltol=1e-10)

ml = smoothed_aggregation(A, B)
@show ml
x_nns, residuals_nns = solve(A, b, SmoothedAggregationAMG(), log=true, reltol=1e-10;B=B)
x_wonns, residuals_wonns = solve(A, b, SmoothedAggregationAMG(), log=true, reltol=1e-10)

println("No NNS: final residual at iteration ", length(residuals_wonns), ": ", residuals_wonns[end])
println("With NNS: final residual at iteration ", length(residuals_nns), ": ", residuals_nns[end])
Expand Down Expand Up @@ -233,8 +230,8 @@ end
@test u[end-1] ≈ (P * L^3) / (3 * E * I) # vertical disp. at the end of the beam


x_nns, residuals_nns = solve(A, b, SmoothedAggregationAMG(B); log=true, reltol=1e-10)
x_wonns, residuals_wonns = solve(A, b, SmoothedAggregationAMG(); log=true, reltol=1e-10)
x_nns, residuals_nns = solve(A, b, SmoothedAggregationAMG(), log=true, reltol=1e-10,B=B)
x_wonns, residuals_wonns = solve(A, b, SmoothedAggregationAMG(), log=true, reltol=1e-10)

println("No NNS: final residual at iteration ", length(residuals_wonns), ": ", residuals_wonns[end])
println("With NNS: final residual at iteration ", length(residuals_nns), ": ", residuals_nns[end])
Expand Down
1 change: 0 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ for sz in [ (10,10), (20,20), (50,50)]
strategy = KrylovJL_CG(precs = RugeStubenPreconBuilder())
@test solve(prob, strategy, atol=1.0e-14) ≈ u0 rtol = 1.0e-8


strategy = KrylovJL_CG(precs = SmoothedAggregationPreconBuilder())
@test solve(prob, strategy, atol=1.0e-14) ≈ u0 rtol = 1.0e-8

Expand Down
Loading