diff --git a/src/problems.jl b/src/problems.jl index df68a22..28ab40c 100644 --- a/src/problems.jl +++ b/src/problems.jl @@ -8,8 +8,8 @@ abstract MixedProblem <: AbstractProblem """ General linearized problem to solve - (K₁+K₂)Δu + C1*Δλ = f₁+f₂ - C2Δu + D*Δλ = g + (K₁+K₂)Δu + C1'*Δλ = f₁+f₂ + C2Δu + D*Δλ = g """ type Assembly @@ -36,6 +36,7 @@ type Assembly la_prev :: Vector{Float64} # previous solution vector u la_norm_change :: Real # change of norm in la + removed_dofs :: Vector{Int64} # manually remove dofs from assembly end function Assembly() @@ -51,7 +52,8 @@ function Assembly() SparseMatrixCOO(), SparseMatrixCOO(), [], [], Inf, - [], [], Inf) + [], [], Inf, + []) end function empty!(assembly::Assembly) diff --git a/src/solvers.jl b/src/solvers.jl index f69979e..d64bdff 100644 --- a/src/solvers.jl +++ b/src/solvers.jl @@ -136,16 +136,22 @@ function check_for_overconstrained_dofs(solver::Solver) boundary_problems = get_boundary_problems(solver) for problem in boundary_problems new_constraints = Set(problem.assembly.C2.I) + new_constraints = setdiff(new_constraints, problem.assembly.removed_dofs) overconstrained_dofs = intersect(constrained_dofs, new_constraints) if length(overconstrained_dofs) != 0 + warn("problem is overconstrained, finding overconstrained dofs... ") overdetermined = true for dof in overconstrained_dofs for problem_ in boundary_problems new_constraints_ = Set(problem_.assembly.C2.I) + new_constraints_ = setdiff(new_constraints_, problem_.assembly.removed_dofs) if dof in new_constraints_ warn("overconstrained dof $dof defined in problem $(problem_.name)") end end + warn("To solve overconstrained situation, remove dofs from problems so that it exists only in one.") + warn("To do this, use push! to add dofs to remove to problem.assembly.removed_dofs, e.g.") + warn("`push!(bc.assembly.removed_dofs, $dof`)") end end constrained_dofs = union(constrained_dofs, new_constraints) @@ -183,6 +189,11 @@ function get_boundary_assembly(solver::Solver) D_ = sparse(assembly.D, ndofs, ndofs) f_ = sparse(assembly.f, ndofs, 1) g_ = sparse(assembly.g, ndofs, 1) + for dof in assembly.removed_dofs + info("$(problem.name): removing dof $dof from assembly") + C1_[:,dof] = 0.0 + C2_[dof,:] = 0.0 + end already_constrained = get_nonzero_rows(C2) new_constraints = get_nonzero_rows(C2_) diff --git a/test/test_mortar_2d_assembly.jl b/test/test_mortar_2d_assembly.jl index b8f6f3b..e3bc461 100644 --- a/test/test_mortar_2d_assembly.jl +++ b/test/test_mortar_2d_assembly.jl @@ -84,6 +84,9 @@ end bc1 = Problem(Dirichlet, "symmetry dx=0", 2, "displacement") push!(bc1, dx1, dx2) + # remove dof 9 from bc1 to avoid overconstrained problem + push!(bc1.assembly.removed_dofs, 9) + # boundary elements for dirichlet dy=0 dy1 = Element(Seg2, [1, 2]) update!(dy1, "geometry", X)