16 #include <deal.II/base/function.h> 17 #include <deal.II/base/quadrature.h> 18 #include <deal.II/base/work_stream.h> 19 #include <deal.II/base/geometry_info.h> 20 #include <deal.II/base/quadrature.h> 21 #include <deal.II/dofs/dof_handler.h> 22 #include <deal.II/dofs/dof_accessor.h> 23 #include <deal.II/dofs/dof_tools.h> 24 #include <deal.II/fe/fe.h> 25 #include <deal.II/fe/fe_values.h> 26 #include <deal.II/fe/mapping_q1.h> 27 #include <deal.II/grid/tria_iterator.h> 28 #include <deal.II/hp/fe_values.h> 29 #include <deal.II/hp/mapping_collection.h> 30 #include <deal.II/numerics/matrix_tools.h> 31 #include <deal.II/lac/vector.h> 32 #include <deal.II/lac/block_vector.h> 33 #include <deal.II/lac/full_matrix.h> 34 #include <deal.II/lac/sparse_matrix.h> 35 #include <deal.II/lac/block_sparse_matrix.h> 37 #ifdef DEAL_II_WITH_PETSC 38 # include <deal.II/lac/petsc_parallel_sparse_matrix.h> 39 # include <deal.II/lac/petsc_sparse_matrix.h> 40 # include <deal.II/lac/petsc_parallel_vector.h> 41 # include <deal.II/lac/petsc_vector.h> 42 # include <deal.II/lac/petsc_parallel_block_sparse_matrix.h> 45 #ifdef DEAL_II_WITH_TRILINOS 46 # include <deal.II/lac/trilinos_sparse_matrix.h> 47 # include <deal.II/lac/trilinos_vector.h> 48 # include <deal.II/lac/trilinos_block_sparse_matrix.h> 49 # include <deal.II/lac/trilinos_block_vector.h> 60 DEAL_II_NAMESPACE_OPEN
66 template <
typename Iterator>
67 bool column_less_than(
const typename Iterator::value_type p,
68 const unsigned int column)
70 return (p.column() < column);
75 template <
typename number>
81 const bool eliminate_columns)
84 ExcDimensionMismatch(matrix.
n(), right_hand_side.
size()));
86 ExcDimensionMismatch(matrix.
n(), solution.
size()));
88 ExcDimensionMismatch(matrix.
n(), matrix.
m()));
92 if (boundary_values.size() == 0)
104 number first_nonzero_diagonal_entry = 1;
105 for (
unsigned int i=0; i<n_dofs; ++i)
113 std::map<types::global_dof_index,double>::const_iterator dof = boundary_values.begin(),
114 endd = boundary_values.end();
115 for (; dof != endd; ++dof)
117 Assert (dof->first < n_dofs, ExcInternalError());
125 p = matrix.
begin(dof_number);
126 p != matrix.
end(dof_number); ++p)
127 if (p->column() != dof_number)
146 new_rhs = dof->second * matrix.
diag_element(dof_number);
147 right_hand_side(dof_number) = new_rhs;
151 matrix.
set (dof_number, dof_number,
152 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 q = matrix.
begin(dof_number)+1;
182 q != matrix.
end(dof_number); ++q)
190 const unsigned int column)
210 (p->column() == dof_number),
211 ExcMessage(
"This function is trying to access an element of the " 212 "matrix that doesn't seem to exist. Are you using a " 213 "nonsymmetric sparsity pattern? If so, you are not " 214 "allowed to set the eliminate_column argument of this " 215 "function, see the documentation."));
218 right_hand_side(row) -= p->value() /
219 diagonal_entry * new_rhs;
227 solution(dof_number) = dof->second;
233 template <
typename number>
239 const bool eliminate_columns)
244 ExcDimensionMismatch(matrix.
n(), right_hand_side.
size()));
246 ExcDimensionMismatch(matrix.
n(), solution.
size()));
254 ExcBlocksDontMatch ());
257 ExcBlocksDontMatch ());
261 if (boundary_values.size() == 0)
273 number first_nonzero_diagonal_entry = 0;
274 for (
unsigned int diag_block=0; diag_block<blocks; ++diag_block)
276 for (
unsigned int i=0; i<matrix.
block(diag_block,diag_block).
n(); ++i)
279 first_nonzero_diagonal_entry
286 if (first_nonzero_diagonal_entry != 0)
291 if (first_nonzero_diagonal_entry == 0)
292 first_nonzero_diagonal_entry = 1;
295 std::map<types::global_dof_index,double>::const_iterator dof = boundary_values.begin(),
296 endd = boundary_values.end();
309 for (; dof != endd; ++dof)
311 Assert (dof->first < n_dofs, ExcInternalError());
318 const std::pair<unsigned int,types::global_dof_index>
328 for (
unsigned int block_col=0; block_col<blocks; ++block_col)
330 p = (block_col == block_index.first ?
331 matrix.
block(block_index.first,block_col).
begin(block_index.second) + 1 :
332 matrix.
block(block_index.first,block_col).
begin(block_index.second));
333 p != matrix.
block(block_index.first,block_col).
end(block_index.second);
351 if (matrix.
block(block_index.first, block_index.first)
353 new_rhs = dof->second *
354 matrix.
block(block_index.first, block_index.first)
358 matrix.
block(block_index.first, block_index.first)
360 = first_nonzero_diagonal_entry;
361 new_rhs = dof->second * first_nonzero_diagonal_entry;
363 right_hand_side.
block(block_index.first)(block_index.second)
376 if (eliminate_columns)
381 const number diagonal_entry
382 = matrix.
block(block_index.first,block_index.first)
406 for (
unsigned int block_row=0; block_row<blocks; ++block_row)
411 = sparsity_pattern.
block (block_row, block_index.first);
414 = matrix.
block(block_row, block_index.first);
416 = matrix.
block(block_index.first, block_row);
422 q = (block_index.first == block_row ?
423 transpose_matrix.
begin(block_index.second)+1 :
424 transpose_matrix.
begin(block_index.second));
425 q != transpose_matrix.
end(block_index.second);
437 const unsigned int column)
444 if (this_matrix.
begin(row)->column()
447 p = this_matrix.
begin(row);
450 this_matrix.
end(row),
456 this_matrix.
end(row),
470 Assert ((p->column() == block_index.second) &&
471 (p != this_matrix.
end(row)),
475 right_hand_side.
block(block_row)(row)
477 diagonal_entry * new_rhs;
486 solution.
block(block_index.first)(block_index.second) = dof->second;
497 const std::vector<types::global_dof_index> &local_dof_indices,
500 const bool eliminate_columns)
502 Assert (local_dof_indices.size() == local_matrix.
m(),
503 ExcDimensionMismatch(local_dof_indices.size(),
505 Assert (local_dof_indices.size() == local_matrix.
n(),
506 ExcDimensionMismatch(local_dof_indices.size(),
508 Assert (local_dof_indices.size() == local_rhs.
size(),
509 ExcDimensionMismatch(local_dof_indices.size(),
514 if (boundary_values.size() == 0)
540 double average_diagonal = 0;
541 const unsigned int n_local_dofs = local_dof_indices.size();
542 for (
unsigned int i=0; i<n_local_dofs; ++i)
544 const std::map<types::global_dof_index, double>::const_iterator
545 boundary_value = boundary_values.find (local_dof_indices[i]);
546 if (boundary_value != boundary_values.end())
550 for (
unsigned int j=0; j<n_local_dofs; ++j)
552 local_matrix(i,j) = 0;
559 if (local_matrix(i,i) == 0.)
563 if (average_diagonal == 0.)
565 unsigned int nonzero_diagonals = 0;
566 for (
unsigned int k=0; k<n_local_dofs; ++k)
567 if (local_matrix(k,k) != 0.)
569 average_diagonal += std::fabs(local_matrix(k,k));
572 if (nonzero_diagonals != 0)
573 average_diagonal /= nonzero_diagonals;
575 average_diagonal = 0;
581 if (average_diagonal == 0.)
582 average_diagonal = 1.;
584 local_matrix(i,i) = average_diagonal;
587 local_matrix(i,i) = std::fabs(local_matrix(i,i));
591 local_rhs(i) = local_matrix(i,i) * boundary_value->second;
595 if (eliminate_columns ==
true)
597 for (
unsigned int row=0; row<n_local_dofs; ++row)
600 local_rhs(row) -= local_matrix(row,i) * boundary_value->second;
601 local_matrix(row,i) = 0;
612 #include "matrix_tools.inst" 615 DEAL_II_NAMESPACE_CLOSE
Iterator lower_bound(Iterator first, Iterator last, const T &val)
const_iterator end() const
::ExceptionBase & ExcMessage(std::string arg1)
void set(const size_type i, const size_type j, const number value)
Auxiliary class aiding in the handling of block structures like in BlockVector or FESystem...
const BlockSparsityPattern & get_sparsity_pattern() const
SparsityPatternType & block(const size_type row, const size_type column)
unsigned int n_block_cols() const
unsigned int global_dof_index
number diag_element(const size_type i) const
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
const BlockIndices & get_row_indices() const
const Accessor< number, Constness > & value_type
BlockType & block(const unsigned int row, const unsigned int column)
const_iterator begin() const
unsigned int n_block_rows() 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