|
|
|
@ -524,6 +524,78 @@ function Base.copy!(dst::HYPREVector, src::PVector{HYPRE_Complex}) |
|
|
|
return dst |
|
|
|
return dst |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#################### |
|
|
|
|
|
|
|
## HYPREAssembler ## |
|
|
|
|
|
|
|
#################### |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct HYPREAssembler |
|
|
|
|
|
|
|
A::HYPREMatrix |
|
|
|
|
|
|
|
b::Union{HYPREVector, Nothing} |
|
|
|
|
|
|
|
ncols::Vector{HYPRE_Int} |
|
|
|
|
|
|
|
rows::Vector{HYPRE_BigInt} |
|
|
|
|
|
|
|
cols::Vector{HYPRE_BigInt} |
|
|
|
|
|
|
|
values::Vector{HYPRE_Complex} |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function start_assemble!(A::HYPREMatrix, b::Union{HYPREVector,Nothing}=nothing) |
|
|
|
|
|
|
|
if A.parmatrix != C_NULL |
|
|
|
|
|
|
|
# This matrix have been assembled before, reset to 0 |
|
|
|
|
|
|
|
@check HYPRE_IJMatrixSetConstantValues(A.ijmatrix, 0) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
@check HYPRE_IJMatrixInitialize(A.ijmatrix) |
|
|
|
|
|
|
|
return HYPREAssembler(A, b, HYPRE_Int[], HYPRE_BigInt[], HYPRE_BigInt[], HYPRE_Complex[]) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
function assemble!(A::HYPREAssembler, ij::Vector, a::Matrix, ::Union{Vector,Nothing}=nothing) |
|
|
|
|
|
|
|
nrows, ncols, rows, cols, values = Internals.to_hypre_data(A, a, ij, ij) |
|
|
|
|
|
|
|
@check HYPRE_IJMatrixAddToValues(A.A.ijmatrix, nrows, ncols, rows, cols, values) |
|
|
|
|
|
|
|
return A |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
function assemble!(A::HYPREAssembler, ij::Vector, a::SparseMatrixCSC, ::Union{Vector,Nothing}=nothing) |
|
|
|
|
|
|
|
size(a, 1) == size(a, 2) == length(ij) || error("mismatch in number of rows/cols") |
|
|
|
|
|
|
|
# Reuse single-core functionality and recompute to global rows/cols after |
|
|
|
|
|
|
|
nrows, ncols, rows, cols, values = Internals.to_hypre_data(a, 1, size(a, 1)) |
|
|
|
|
|
|
|
for i in eachindex(rows) |
|
|
|
|
|
|
|
rows[i] = ij[rows[i]] |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
for i in eachindex(cols) |
|
|
|
|
|
|
|
cols[i] = ij[cols[i]] |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
@check HYPRE_IJMatrixAddToValues(A.A.ijmatrix, nrows, ncols, rows, cols, values) |
|
|
|
|
|
|
|
return A |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
function finish_assemble!(A::HYPREAssembler) |
|
|
|
|
|
|
|
Internals.assemble_matrix(A.A) |
|
|
|
|
|
|
|
return nothing |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Internals.to_hypre_data(A::HYPREAssembler, a::Matrix, I::Vector, J::Vector) |
|
|
|
|
|
|
|
size(a, 1) == length(I) || error("mismatching number of rows") |
|
|
|
|
|
|
|
size(a, 2) == length(J) || error("mismatch number of cols") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nrows = HYPRE_Int(length(I)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Resize cache vectors |
|
|
|
|
|
|
|
ncols = resize!(A.ncols, nrows) |
|
|
|
|
|
|
|
rows = resize!(A.rows, length(a)) |
|
|
|
|
|
|
|
cols = resize!(A.cols, length(a)) |
|
|
|
|
|
|
|
values = resize!(A.values, length(a)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Fill vectors |
|
|
|
|
|
|
|
ncols = fill!(ncols, HYPRE_Int(length(J))) |
|
|
|
|
|
|
|
copyto!(rows, I) |
|
|
|
|
|
|
|
idx = 0 |
|
|
|
|
|
|
|
for i in 1:length(I), j in 1:length(J) |
|
|
|
|
|
|
|
idx += 1 |
|
|
|
|
|
|
|
cols[idx] = J[j] |
|
|
|
|
|
|
|
values[idx] = a[i, j] |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
@assert idx == length(a) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nrows, ncols, rows, cols, values |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Solver interface |
|
|
|
# Solver interface |
|
|
|
include("solvers.jl") |
|
|
|
include("solvers.jl") |
|
|
|
include("solver_options.jl") |
|
|
|
include("solver_options.jl") |
|
|
|
|