Skip to content

Commit

Permalink
AffineConstraints: Fix usage with get_rhs_data. (#431)
Browse files Browse the repository at this point in the history
This applies affine constraints also in apply_rhs! for solving a system
with multiple right hand sides. Also adds tests, and removes the
workarounds for this bug in computational homogenization example.

Fixes #419.
  • Loading branch information
fredrikekre committed Feb 28, 2022
1 parent f995d04 commit 4e35b2d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
6 changes: 0 additions & 6 deletions docs/src/literate/computational_homogenization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ rhsdata = (
)

apply!(K.dirichlet, ch.dirichlet)
Kp = copy(K.periodic) #hide
apply!(K.periodic, ch.periodic)

# We can now solve the problem(s). Note that we only use `apply_rhs!` in the loops below.
Expand All @@ -388,14 +387,9 @@ for i in 1:size(rhs.dirichlet, 2)
push!(u.dirichlet, u_i) # Save the solution vector
end

rhs_p = copy(rhs.periodic) #hide
for i in 1:size(rhs.periodic, 2)
rhs_i = @view rhs.periodic[:, i] # Extract this RHS
apply_rhs!(rhsdata.periodic, rhs_i, ch.periodic) # Apply BC
rhs_i = @view rhs_p[:, i] #hide
Kpp = copy(Kp) #hide
apply!(Kpp, rhs_i, ch.periodic) #hide
copy!(K.periodic, Kpp) #hide
u_i = cholesky(Symmetric(K.periodic)) \ rhs_i # Solve
apply!(u_i, ch.periodic) # Apply BC on the solution
push!(u.periodic, u_i) # Save the solution vector
Expand Down
24 changes: 17 additions & 7 deletions src/Dofs/ConstraintHandler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,22 +111,31 @@ See also: [`get_rhs_data`](@ref).
"""
function apply_rhs!(data::RHSData, f::AbstractVector, ch::ConstraintHandler, applyzero::Bool=false)
K = data.constrained_columns
@assert length(f) == 0 || length(f) == size(K, 1)
@boundscheck length(f) == 0 || checkbounds(f, ch.prescribed_dofs)

@assert length(f) == size(K, 1)
@boundscheck checkbounds(f, ch.prescribed_dofs)
m = data.m

# TODO: Can the loops be combined or does the order matter?
@inbounds for i in 1:length(ch.inhomogeneities)
d = ch.prescribed_dofs[i]
v = ch.inhomogeneities[i]
if !applyzero && v != 0
for j in nzrange(K, i)
f[K.rowval[j]] -= v * K.nzval[j]
end
end
if length(f) != 0
vz = applyzero ? zero(eltype(f)) : v
f[d] = vz * m
end
@inbounds for ac in ch.acs
global_dof = ac.constrained_dof
for (d, v) in ac.entries
f[d] += f[global_dof] * v
end
f[global_dof] = 0
end
@inbounds for i in 1:length(ch.inhomogeneities)
d = ch.prescribed_dofs[i]
v = ch.inhomogeneities[i]
vz = applyzero ? zero(eltype(f)) : v
f[d] = vz * m
end
end

Expand Down Expand Up @@ -679,6 +688,7 @@ function _condense!(K::SparseMatrixCSC, f::AbstractVector, acs::Vector{AffineCon
for (d,v) in ac.entries
f[d] += f[col] * v
end
@assert ac.constrained_dof == col
f[ac.constrained_dof] = 0.0
end
end
Expand Down
11 changes: 10 additions & 1 deletion test/test_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ end
for cell in CellIterator(dh)
K[celldofs(cell), celldofs(cell)] += 2.0 * [1 -1; -1 1]
end
copies = (K = copy(K), f1 = copy(f), f2 = copy(f))

# Solve by actually condensing the matrix
ff = C' * (f - K * g)
Expand All @@ -162,7 +163,15 @@ end
a = K \ f
apply!(a, ch)

@test a aa
# Solve with extracted RHS data
rhs = get_rhs_data(ch, copies.K)
apply!(copies.K, ch)
apply_rhs!(rhs, copies.f1, ch)
a_rhs1 = apply!(copies.K \ copies.f1, ch)
apply_rhs!(rhs, copies.f2, ch)
a_rhs2 = apply!(copies.K \ copies.f2, ch)

@test a aa a_rhs1 a_rhs2
end

end

0 comments on commit 4e35b2d

Please sign in to comment.