64 const std::map<types::global_dof_index, number> &boundary_values,
68 const bool eliminate_columns)
74 Assert(matrix.n() == matrix.m(),
79 if (boundary_values.empty())
91 number first_nonzero_diagonal_entry = 1;
93 if (matrix.diag_element(i) != number())
95 first_nonzero_diagonal_entry = matrix.diag_element(i);
100 typename std::map<types::global_dof_index, number>::const_iterator
101 dof = boundary_values.begin(),
102 endd = boundary_values.end();
103 for (; dof != endd; ++dof)
113 matrix.begin(dof_number);
114 p != matrix.end(dof_number);
116 if (p->column() != dof_number)
133 if (matrix.diag_element(dof_number) != number())
135 new_rhs = dof->second * matrix.diag_element(dof_number);
136 right_hand_side(dof_number) = new_rhs;
140 matrix.set(dof_number, dof_number, first_nonzero_diagonal_entry);
141 new_rhs = dof->second * first_nonzero_diagonal_entry;
142 right_hand_side(dof_number) = new_rhs;
153 if (eliminate_columns)
158 const number diagonal_entry = matrix.diag_element(dof_number);
169 matrix.begin(dof_number) + 1;
170 q != matrix.end(dof_number);
180 [](
const auto &a,
const auto &b) {
181 return a.column() < b;
194 Assert((p != matrix.end(row)) && (p->column() == dof_number),
196 "This function is trying to access an element of the "
197 "matrix that doesn't seem to exist. Are you using a "
198 "nonsymmetric sparsity pattern? If so, you are not "
199 "allowed to set the eliminate_column argument of this "
200 "function, see the documentation."));
203 right_hand_side(row) -=
204 static_cast<number
>(p->value()) / diagonal_entry * new_rhs;
212 solution(dof_number) = dof->second;
221 const std::map<types::global_dof_index, number> &boundary_values,
225 const bool eliminate_columns)
227 const unsigned int blocks = matrix.n_block_rows();
234 Assert(matrix.get_sparsity_pattern().get_row_indices() ==
235 matrix.get_sparsity_pattern().get_column_indices(),
237 Assert(matrix.get_sparsity_pattern().get_column_indices() ==
240 Assert(matrix.get_sparsity_pattern().get_row_indices() ==
246 if (boundary_values.empty())
258 number first_nonzero_diagonal_entry = 0;
259 for (
unsigned int diag_block = 0; diag_block < blocks; ++diag_block)
262 i < matrix.block(diag_block, diag_block).n();
264 if (matrix.block(diag_block, diag_block).diag_element(i) != number{})
266 first_nonzero_diagonal_entry =
267 matrix.block(diag_block, diag_block).diag_element(i);
273 if (first_nonzero_diagonal_entry != number{})
278 if (first_nonzero_diagonal_entry == number{})
279 first_nonzero_diagonal_entry = 1;
282 typename std::map<types::global_dof_index, number>::const_iterator
283 dof = boundary_values.begin(),
284 endd = boundary_values.end();
286 matrix.get_sparsity_pattern();
296 for (; dof != endd; ++dof)
304 const std::pair<unsigned int, types::global_dof_index> block_index =
314 for (
unsigned int block_col = 0; block_col < blocks; ++block_col)
316 (block_col == block_index.first ?
317 matrix.block(block_index.first, block_col)
318 .begin(block_index.second) +
320 matrix.block(block_index.first, block_col)
321 .begin(block_index.second));
322 p != matrix.block(block_index.first, block_col)
323 .end(block_index.second);
341 if (matrix.block(block_index.first, block_index.first)
342 .diag_element(block_index.second) != number{})
344 dof->second * matrix.block(block_index.first, block_index.first)
345 .diag_element(block_index.second);
348 matrix.block(block_index.first, block_index.first)
349 .diag_element(block_index.second) = first_nonzero_diagonal_entry;
350 new_rhs = dof->second * first_nonzero_diagonal_entry;
352 right_hand_side.
block(block_index.first)(block_index.second) = new_rhs;
364 if (eliminate_columns)
369 const number diagonal_entry =
370 matrix.block(block_index.first, block_index.first)
371 .diag_element(block_index.second);
394 for (
unsigned int block_row = 0; block_row < blocks; ++block_row)
399 sparsity_pattern.
block(block_row, block_index.first);
402 matrix.block(block_row, block_index.first);
404 matrix.block(block_index.first, block_row);
410 (block_index.first == block_row ?
411 transpose_matrix.
begin(block_index.second) + 1 :
412 transpose_matrix.
begin(block_index.second));
413 q != transpose_matrix.
end(block_index.second);
429 if (this_matrix.
begin(row)->column() ==
431 p = this_matrix.
begin(row);
434 this_matrix.
end(row),
438 return a.column() < b;
443 this_matrix.
end(row),
447 return a.column() < b;
460 Assert((p->column() == block_index.second) &&
461 (p != this_matrix.
end(row)),
465 right_hand_side.
block(block_row)(row) -=
466 number(p->value()) / diagonal_entry * new_rhs;
475 solution.
block(block_index.first)(block_index.second) = dof->second;
484 const std::map<types::global_dof_index, number> &boundary_values,
485 const std::vector<types::global_dof_index> &local_dof_indices,
488 const bool eliminate_columns)
490 Assert(local_dof_indices.size() == local_matrix.
m(),
492 Assert(local_dof_indices.size() == local_matrix.
n(),
494 Assert(local_dof_indices.size() == local_rhs.
size(),
499 if (boundary_values.empty())
525 number average_diagonal = 0;
526 const unsigned int n_local_dofs = local_dof_indices.size();
527 for (
unsigned int i = 0; i < n_local_dofs; ++i)
529 const typename std::map<types::global_dof_index, number>::const_iterator
530 boundary_value = boundary_values.find(local_dof_indices[i]);
531 if (boundary_value != boundary_values.end())
535 for (
unsigned int j = 0; j < n_local_dofs; ++j)
537 local_matrix(i, j) = 0;
544 if (local_matrix(i, i) == number{})
548 if (average_diagonal == number{})
550 unsigned int nonzero_diagonals = 0;
551 for (
unsigned int k = 0; k < n_local_dofs; ++k)
552 if (local_matrix(k, k) != number{})
554 average_diagonal +=
std::abs(local_matrix(k, k));
557 if (nonzero_diagonals != 0)
558 average_diagonal /= nonzero_diagonals;
560 average_diagonal = 0;
566 if (average_diagonal == number{})
567 average_diagonal = 1.;
569 local_matrix(i, i) = average_diagonal;
572 local_matrix(i, i) =
std::abs(local_matrix(i, i));
576 local_rhs(i) = local_matrix(i, i) * boundary_value->second;
580 if (eliminate_columns ==
true)
582 for (
unsigned int row = 0; row < n_local_dofs; ++row)
586 local_matrix(row, i) * boundary_value->second;
587 local_matrix(row, i) = 0;