76 const std::map<types::global_dof_index, number> &boundary_values,
80 const bool eliminate_columns)
86 Assert(matrix.n() == matrix.m(),
91 if (boundary_values.empty())
103 number first_nonzero_diagonal_entry = 1;
104 for (
unsigned int i = 0; i < n_dofs; ++i)
105 if (matrix.diag_element(i) != number())
107 first_nonzero_diagonal_entry = matrix.diag_element(i);
112 typename std::map<types::global_dof_index, number>::const_iterator
113 dof = boundary_values.begin(),
114 endd = boundary_values.end();
115 for (; dof != endd; ++dof)
125 matrix.begin(dof_number);
126 p != matrix.end(dof_number);
128 if (p->column() != dof_number)
145 if (matrix.diag_element(dof_number) != number())
147 new_rhs = dof->second * matrix.diag_element(dof_number);
148 right_hand_side(dof_number) = new_rhs;
152 matrix.set(dof_number, dof_number, first_nonzero_diagonal_entry);
153 new_rhs = dof->second * first_nonzero_diagonal_entry;
154 right_hand_side(dof_number) = new_rhs;
165 if (eliminate_columns)
170 const number diagonal_entry = matrix.diag_element(dof_number);
181 matrix.begin(dof_number) + 1;
182 q != matrix.end(dof_number);
192 const unsigned int column) =
210 Assert((p != matrix.end(row)) && (p->column() == dof_number),
212 "This function is trying to access an element of the "
213 "matrix that doesn't seem to exist. Are you using a "
214 "nonsymmetric sparsity pattern? If so, you are not "
215 "allowed to set the eliminate_column argument of this "
216 "function, see the documentation."));
219 right_hand_side(row) -=
220 static_cast<number
>(p->value()) / diagonal_entry * new_rhs;
228 solution(dof_number) = dof->second;
237 const std::map<types::global_dof_index, number> &boundary_values,
241 const bool eliminate_columns)
243 const unsigned int blocks = matrix.n_block_rows();
250 Assert(matrix.get_sparsity_pattern().get_row_indices() ==
251 matrix.get_sparsity_pattern().get_column_indices(),
253 Assert(matrix.get_sparsity_pattern().get_column_indices() ==
256 Assert(matrix.get_sparsity_pattern().get_row_indices() ==
262 if (boundary_values.empty())
274 number first_nonzero_diagonal_entry = 0;
275 for (
unsigned int diag_block = 0; diag_block < blocks; ++diag_block)
277 for (
unsigned int i = 0; i < matrix.block(diag_block, diag_block).n();
279 if (matrix.block(diag_block, diag_block).diag_element(i) != number{})
281 first_nonzero_diagonal_entry =
282 matrix.block(diag_block, diag_block).diag_element(i);
288 if (first_nonzero_diagonal_entry != number{})
293 if (first_nonzero_diagonal_entry == number{})
294 first_nonzero_diagonal_entry = 1;
297 typename std::map<types::global_dof_index, number>::const_iterator
298 dof = boundary_values.begin(),
299 endd = boundary_values.end();
301 matrix.get_sparsity_pattern();
311 for (; dof != endd; ++dof)
320 const std::pair<unsigned int, types::global_dof_index> block_index =
330 for (
unsigned int block_col = 0; block_col < blocks; ++block_col)
332 (block_col == block_index.first ?
333 matrix.block(block_index.first, block_col)
334 .begin(block_index.second) +
336 matrix.block(block_index.first, block_col)
337 .begin(block_index.second));
338 p != matrix.block(block_index.first, block_col)
339 .end(block_index.second);
357 if (matrix.block(block_index.first, block_index.first)
358 .diag_element(block_index.second) != number{})
360 dof->second * matrix.block(block_index.first, block_index.first)
361 .diag_element(block_index.second);
364 matrix.block(block_index.first, block_index.first)
365 .diag_element(block_index.second) = first_nonzero_diagonal_entry;
366 new_rhs = dof->second * first_nonzero_diagonal_entry;
368 right_hand_side.
block(block_index.first)(block_index.second) = new_rhs;
380 if (eliminate_columns)
385 const number diagonal_entry =
386 matrix.block(block_index.first, block_index.first)
387 .diag_element(block_index.second);
410 for (
unsigned int block_row = 0; block_row < blocks; ++block_row)
415 sparsity_pattern.
block(block_row, block_index.first);
418 matrix.block(block_row, block_index.first);
420 matrix.block(block_index.first, block_row);
426 (block_index.first == block_row ?
427 transpose_matrix.
begin(block_index.second) + 1 :
428 transpose_matrix.
begin(block_index.second));
429 q != transpose_matrix.
end(block_index.second);
442 const unsigned int column) =
451 if (this_matrix.
begin(row)->column() ==
453 p = this_matrix.
begin(row);
456 this_matrix.
end(row),
462 this_matrix.
end(row),
476 Assert((p->column() == block_index.second) &&
477 (p != this_matrix.
end(row)),
481 right_hand_side.
block(block_row)(row) -=
482 number(p->value()) / diagonal_entry * new_rhs;
491 solution.
block(block_index.first)(block_index.second) = dof->second;
500 const std::map<types::global_dof_index, number> &boundary_values,
501 const std::vector<types::global_dof_index> &local_dof_indices,
504 const bool eliminate_columns)
506 Assert(local_dof_indices.size() == local_matrix.
m(),
508 Assert(local_dof_indices.size() == local_matrix.
n(),
510 Assert(local_dof_indices.size() == local_rhs.
size(),
515 if (boundary_values.empty())
541 number average_diagonal = 0;
542 const unsigned int n_local_dofs = local_dof_indices.size();
543 for (
unsigned int i = 0; i < n_local_dofs; ++i)
545 const typename std::map<types::global_dof_index, number>::const_iterator
546 boundary_value = boundary_values.find(local_dof_indices[i]);
547 if (boundary_value != boundary_values.end())
551 for (
unsigned int j = 0; j < n_local_dofs; ++j)
553 local_matrix(i, j) = 0;
560 if (local_matrix(i, i) == number{})
564 if (average_diagonal == number{})
566 unsigned int nonzero_diagonals = 0;
567 for (
unsigned int k = 0; k < n_local_dofs; ++k)
568 if (local_matrix(k, k) != number{})
570 average_diagonal +=
std::abs(local_matrix(k, k));
573 if (nonzero_diagonals != 0)
574 average_diagonal /= nonzero_diagonals;
576 average_diagonal = 0;
582 if (average_diagonal == number{})
583 average_diagonal = 1.;
585 local_matrix(i, i) = average_diagonal;
588 local_matrix(i, i) =
std::abs(local_matrix(i, i));
592 local_rhs(i) = local_matrix(i, i) * boundary_value->second;
596 if (eliminate_columns ==
true)
598 for (
unsigned int row = 0; row < n_local_dofs; ++row)
602 local_matrix(row, i) * boundary_value->second;
603 local_matrix(row, i) = 0;