16 #include <deal.II/base/function.h> 17 #include <deal.II/base/geometry_info.h> 18 #include <deal.II/base/quadrature.h> 19 #include <deal.II/base/work_stream.h> 21 #include <deal.II/dofs/dof_accessor.h> 22 #include <deal.II/dofs/dof_handler.h> 23 #include <deal.II/dofs/dof_tools.h> 25 #include <deal.II/fe/fe.h> 26 #include <deal.II/fe/fe_values.h> 27 #include <deal.II/fe/mapping_q1.h> 29 #include <deal.II/grid/tria_iterator.h> 31 #include <deal.II/hp/fe_values.h> 32 #include <deal.II/hp/mapping_collection.h> 34 #include <deal.II/lac/block_sparse_matrix.h> 35 #include <deal.II/lac/block_vector.h> 36 #include <deal.II/lac/full_matrix.h> 37 #include <deal.II/lac/sparse_matrix.h> 38 #include <deal.II/lac/vector.h> 40 #include <deal.II/numerics/matrix_tools.h> 42 #ifdef DEAL_II_WITH_PETSC 43 # include <deal.II/lac/petsc_block_sparse_matrix.h> 44 # include <deal.II/lac/petsc_sparse_matrix.h> 45 # include <deal.II/lac/petsc_vector.h> 48 #ifdef DEAL_II_WITH_TRILINOS 49 # include <deal.II/lac/trilinos_block_sparse_matrix.h> 50 # include <deal.II/lac/trilinos_parallel_block_vector.h> 51 # include <deal.II/lac/trilinos_sparse_matrix.h> 52 # include <deal.II/lac/trilinos_vector.h> 60 DEAL_II_NAMESPACE_OPEN
68 template <
typename Iterator>
70 column_less_than(
const typename Iterator::value_type p,
71 const unsigned int column)
73 return (p.column() < column);
79 template <
typename number>
82 const std::map<types::global_dof_index, number> &boundary_values,
86 const bool eliminate_columns)
92 Assert(matrix.n() == matrix.m(),
97 if (boundary_values.size() == 0)
109 number first_nonzero_diagonal_entry = 1;
110 for (
unsigned int i = 0; i < n_dofs; ++i)
111 if (matrix.diag_element(i) != number())
113 first_nonzero_diagonal_entry = matrix.diag_element(i);
118 typename std::map<types::global_dof_index, number>::const_iterator
119 dof = boundary_values.begin(),
120 endd = boundary_values.end();
121 for (; dof != endd; ++dof)
131 matrix.begin(dof_number);
132 p != matrix.end(dof_number);
134 if (p->column() != dof_number)
151 if (matrix.diag_element(dof_number) != number())
153 new_rhs = dof->second * matrix.diag_element(dof_number);
154 right_hand_side(dof_number) = new_rhs;
158 matrix.set(dof_number, dof_number, first_nonzero_diagonal_entry);
159 new_rhs = dof->second * first_nonzero_diagonal_entry;
160 right_hand_side(dof_number) = new_rhs;
171 if (eliminate_columns)
176 const number diagonal_entry = matrix.diag_element(dof_number);
187 matrix.begin(dof_number) + 1;
188 q != matrix.end(dof_number);
198 const unsigned int column) =
216 Assert((p != matrix.end(row)) && (p->column() == dof_number),
218 "This function is trying to access an element of the " 219 "matrix that doesn't seem to exist. Are you using a " 220 "nonsymmetric sparsity pattern? If so, you are not " 221 "allowed to set the eliminate_column argument of this " 222 "function, see the documentation."));
225 right_hand_side(row) -=
226 static_cast<number
>(p->value()) / diagonal_entry * new_rhs;
234 solution(dof_number) = dof->second;
240 template <
typename number>
243 const std::map<types::global_dof_index, number> &boundary_values,
247 const bool eliminate_columns)
249 const unsigned int blocks = matrix.n_block_rows();
256 Assert(matrix.get_sparsity_pattern().get_row_indices() ==
257 matrix.get_sparsity_pattern().get_column_indices(),
259 Assert(matrix.get_sparsity_pattern().get_column_indices() ==
262 Assert(matrix.get_sparsity_pattern().get_row_indices() ==
268 if (boundary_values.size() == 0)
280 number first_nonzero_diagonal_entry = 0;
281 for (
unsigned int diag_block = 0; diag_block < blocks; ++diag_block)
283 for (
unsigned int i = 0; i < matrix.block(diag_block, diag_block).n();
285 if (matrix.block(diag_block, diag_block).diag_element(i) != 0)
287 first_nonzero_diagonal_entry =
288 matrix.block(diag_block, diag_block).diag_element(i);
294 if (first_nonzero_diagonal_entry != 0)
299 if (first_nonzero_diagonal_entry == 0)
300 first_nonzero_diagonal_entry = 1;
303 typename std::map<types::global_dof_index, number>::const_iterator
304 dof = boundary_values.begin(),
305 endd = boundary_values.end();
307 matrix.get_sparsity_pattern();
317 for (; dof != endd; ++dof)
326 const std::pair<unsigned int, types::global_dof_index> block_index =
336 for (
unsigned int block_col = 0; block_col < blocks; ++block_col)
338 (block_col == block_index.first ?
339 matrix.block(block_index.first, block_col)
340 .begin(block_index.second) +
342 matrix.block(block_index.first, block_col)
343 .begin(block_index.second));
344 p != matrix.block(block_index.first, block_col)
345 .end(block_index.second);
363 if (matrix.block(block_index.first, block_index.first)
364 .diag_element(block_index.second) != 0.0)
366 dof->second * matrix.block(block_index.first, block_index.first)
367 .diag_element(block_index.second);
370 matrix.block(block_index.first, block_index.first)
371 .diag_element(block_index.second) = first_nonzero_diagonal_entry;
372 new_rhs = dof->second * first_nonzero_diagonal_entry;
374 right_hand_side.
block(block_index.first)(block_index.second) = new_rhs;
386 if (eliminate_columns)
391 const number diagonal_entry =
392 matrix.block(block_index.first, block_index.first)
393 .diag_element(block_index.second);
416 for (
unsigned int block_row = 0; block_row < blocks; ++block_row)
421 sparsity_pattern.
block(block_row, block_index.first);
424 matrix.block(block_row, block_index.first);
426 matrix.block(block_index.first, block_row);
432 (block_index.first == block_row ?
433 transpose_matrix.
begin(block_index.second) + 1 :
434 transpose_matrix.
begin(block_index.second));
435 q != transpose_matrix.
end(block_index.second);
448 const unsigned int column) =
457 if (this_matrix.
begin(row)->column() ==
459 p = this_matrix.
begin(row);
462 this_matrix.
end(row),
468 this_matrix.
end(row),
482 Assert((p->column() == block_index.second) &&
483 (p != this_matrix.
end(row)),
487 right_hand_side.
block(block_row)(row) -=
488 p->value() / diagonal_entry * new_rhs;
497 solution.
block(block_index.first)(block_index.second) = dof->second;
503 template <
typename number>
506 const std::map<types::global_dof_index, number> &boundary_values,
507 const std::vector<types::global_dof_index> & local_dof_indices,
510 const bool eliminate_columns)
512 Assert(local_dof_indices.size() == local_matrix.
m(),
514 Assert(local_dof_indices.size() == local_matrix.
n(),
516 Assert(local_dof_indices.size() == local_rhs.
size(),
521 if (boundary_values.size() == 0)
547 number average_diagonal = 0;
548 const unsigned int n_local_dofs = local_dof_indices.size();
549 for (
unsigned int i = 0; i < n_local_dofs; ++i)
551 const typename std::map<types::global_dof_index, number>::const_iterator
552 boundary_value = boundary_values.find(local_dof_indices[i]);
553 if (boundary_value != boundary_values.end())
557 for (
unsigned int j = 0; j < n_local_dofs; ++j)
559 local_matrix(i, j) = 0;
566 if (local_matrix(i, i) == 0.)
570 if (average_diagonal == 0.)
572 unsigned int nonzero_diagonals = 0;
573 for (
unsigned int k = 0; k < n_local_dofs; ++k)
574 if (local_matrix(k, k) != 0.)
576 average_diagonal += std::fabs(local_matrix(k, k));
579 if (nonzero_diagonals != 0)
580 average_diagonal /= nonzero_diagonals;
582 average_diagonal = 0;
588 if (average_diagonal == 0.)
589 average_diagonal = 1.;
591 local_matrix(i, i) = average_diagonal;
594 local_matrix(i, i) = std::fabs(local_matrix(i, i));
598 local_rhs(i) = local_matrix(i, i) * boundary_value->second;
602 if (eliminate_columns ==
true)
604 for (
unsigned int row = 0; row < n_local_dofs; ++row)
608 local_matrix(row, i) * boundary_value->second;
609 local_matrix(row, i) = 0;
620 #include "matrix_tools.inst" 623 DEAL_II_NAMESPACE_CLOSE
Iterator lower_bound(Iterator first, Iterator last, const T &val)
const_iterator end() const
SparsityPatternType & block(const size_type row, const size_type column)
static ::ExceptionBase & ExcMessage(std::string arg1)
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotQuadratic()
static ::ExceptionBase & ExcBlocksDontMatch()
unsigned int global_dof_index
const_iterator begin() const
BlockType & block(const unsigned int i)
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
const BlockIndices & get_column_indices() const
const Accessor< number, Constness > & value_type
static ::ExceptionBase & ExcInternalError()