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_block_vector.h> 45 # include <deal.II/lac/petsc_matrix_base.h> 46 # include <deal.II/lac/petsc_vector_base.h> 49 #ifdef DEAL_II_WITH_TRILINOS 50 # include <deal.II/lac/trilinos_block_sparse_matrix.h> 51 # include <deal.II/lac/trilinos_parallel_block_vector.h> 52 # include <deal.II/lac/trilinos_sparse_matrix.h> 53 # include <deal.II/lac/trilinos_vector.h> 60 DEAL_II_NAMESPACE_OPEN
64 #ifdef DEAL_II_WITH_PETSC 67 const std::map<types::global_dof_index, PetscScalar> &boundary_values,
71 const bool eliminate_columns)
73 (void)eliminate_columns;
84 if (boundary_values.size() > 0)
86 const std::pair<types::global_dof_index, types::global_dof_index>
96 PetscScalar average_nonzero_diagonal_entry = 1;
98 i < local_range.second;
102 average_nonzero_diagonal_entry = std::abs(matrix.
diag_element(i));
108 std::vector<types::global_dof_index> constrained_rows;
109 for (std::map<types::global_dof_index, PetscScalar>::const_iterator
110 dof = boundary_values.begin();
111 dof != boundary_values.end();
113 if ((dof->first >= local_range.first) &&
114 (dof->first < local_range.second))
115 constrained_rows.push_back(dof->first);
128 matrix.
clear_rows(constrained_rows, average_nonzero_diagonal_entry);
130 std::vector<types::global_dof_index> indices;
131 std::vector<PetscScalar> solution_values;
132 for (std::map<types::global_dof_index, PetscScalar>::const_iterator
133 dof = boundary_values.begin();
134 dof != boundary_values.end();
136 if ((dof->first >= local_range.first) &&
137 (dof->first < local_range.second))
139 indices.push_back(dof->first);
140 solution_values.push_back(dof->second);
142 solution.
set(indices, solution_values);
146 for (
unsigned int i = 0; i < solution_values.size(); ++i)
147 solution_values[i] *= average_nonzero_diagonal_entry;
149 right_hand_side.
set(indices, solution_values);
155 std::vector<types::global_dof_index> constrained_rows;
167 const std::map<types::global_dof_index, PetscScalar> &boundary_values,
171 const bool eliminate_columns)
185 std::vector<std::map<::types::global_dof_index, PetscScalar>>
186 block_boundary_values(n_blocks);
190 for (std::map<types::global_dof_index, PetscScalar>::const_iterator dof =
191 boundary_values.begin();
192 dof != boundary_values.end();
195 if (dof->first >= matrix.
block(block, 0).
m() + offset)
197 offset += matrix.
block(block, 0).
m();
201 block_boundary_values[block].insert(
202 std::pair<types::global_dof_index, PetscScalar>(index,
210 for (
unsigned int block = 0; block < n_blocks; ++block)
212 matrix.
block(block, block),
213 solution.
block(block),
214 right_hand_side.
block(block),
221 for (
unsigned int block_m = 0; block_m < n_blocks; ++block_m)
223 const std::pair<types::global_dof_index, types::global_dof_index>
224 local_range = matrix.
block(block_m, 0).local_range();
226 std::vector<types::global_dof_index> constrained_rows;
227 for (std::map<types::global_dof_index, PetscScalar>::const_iterator
228 dof = block_boundary_values[block_m].begin();
229 dof != block_boundary_values[block_m].end();
231 if ((dof->first >= local_range.first) &&
232 (dof->first < local_range.second))
233 constrained_rows.push_back(dof->first);
235 for (
unsigned int block_n = 0; block_n < n_blocks; ++block_n)
236 if (block_m != block_n)
237 matrix.
block(block_m, block_n).clear_rows(constrained_rows);
245 #ifdef DEAL_II_WITH_TRILINOS 251 template <
typename TrilinosMatrix,
typename TrilinosVector>
254 TrilinosScalar> &boundary_values,
255 TrilinosMatrix & matrix,
256 TrilinosVector & solution,
257 TrilinosVector & right_hand_side,
258 const bool eliminate_columns)
261 (void)eliminate_columns;
263 Assert(matrix.n() == right_hand_side.size(),
265 Assert(matrix.n() == solution.size(),
271 if (boundary_values.size() > 0)
273 const std::pair<types::global_dof_index, types::global_dof_index>
274 local_range = matrix.local_range();
275 Assert(local_range == right_hand_side.local_range(),
283 TrilinosScalar average_nonzero_diagonal_entry = 1;
285 i < local_range.second;
287 if (matrix.diag_element(i) != 0)
289 average_nonzero_diagonal_entry =
290 std::fabs(matrix.diag_element(i));
296 std::vector<types::global_dof_index> constrained_rows;
298 TrilinosScalar>::const_iterator dof =
299 boundary_values.begin();
300 dof != boundary_values.end();
302 if ((dof->first >= local_range.first) &&
303 (dof->first < local_range.second))
304 constrained_rows.push_back(dof->first);
313 matrix.clear_rows(constrained_rows, average_nonzero_diagonal_entry);
315 std::vector<types::global_dof_index> indices;
316 std::vector<TrilinosScalar> solution_values;
318 TrilinosScalar>::const_iterator dof =
319 boundary_values.begin();
320 dof != boundary_values.end();
322 if ((dof->first >= local_range.first) &&
323 (dof->first < local_range.second))
325 indices.push_back(dof->first);
326 solution_values.push_back(dof->second);
328 solution.set(indices, solution_values);
332 for (
unsigned int i = 0; i < solution_values.size(); ++i)
333 solution_values[i] *= matrix.diag_element(indices[i]);
335 right_hand_side.set(indices, solution_values);
341 std::vector<types::global_dof_index> constrained_rows;
342 matrix.clear_rows(constrained_rows, 1.);
353 template <
typename TrilinosMatrix,
typename TrilinosBlockVector>
355 apply_block_boundary_values(
356 const std::map<types::global_dof_index, TrilinosScalar>
358 TrilinosMatrix & matrix,
359 TrilinosBlockVector &solution,
360 TrilinosBlockVector &right_hand_side,
361 const bool eliminate_columns)
365 Assert(matrix.n() == right_hand_side.size(),
367 Assert(matrix.n() == solution.size(),
369 Assert(matrix.n_block_rows() == matrix.n_block_cols(),
372 const unsigned int n_blocks = matrix.n_block_rows();
378 std::vector<std::map<types::global_dof_index, TrilinosScalar>>
379 block_boundary_values(n_blocks);
383 for (std::map<types::global_dof_index, TrilinosScalar>::const_iterator
384 dof = boundary_values.begin();
385 dof != boundary_values.end();
388 if (dof->first >= matrix.block(block, 0).m() + offset)
390 offset += matrix.block(block, 0).m();
394 block_boundary_values[block].insert(
395 std::pair<types::global_dof_index, TrilinosScalar>(
396 index, dof->second));
403 for (
unsigned int block = 0; block < n_blocks; ++block)
404 TrilinosWrappers::apply_boundary_values(block_boundary_values[block],
405 matrix.block(block, block),
406 solution.block(block),
407 right_hand_side.block(block),
414 for (
unsigned int block_m = 0; block_m < n_blocks; ++block_m)
416 const std::pair<types::global_dof_index, types::global_dof_index>
417 local_range = matrix.block(block_m, 0).local_range();
419 std::vector<types::global_dof_index> constrained_rows;
421 TrilinosScalar>::const_iterator dof =
422 block_boundary_values[block_m].begin();
423 dof != block_boundary_values[block_m].end();
425 if ((dof->first >= local_range.first) &&
426 (dof->first < local_range.second))
427 constrained_rows.push_back(dof->first);
429 for (
unsigned int block_n = 0; block_n < n_blocks; ++block_n)
430 if (block_m != block_n)
431 matrix.block(block_m, block_n).clear_rows(constrained_rows);
441 const std::map<types::global_dof_index, TrilinosScalar> &boundary_values,
445 const bool eliminate_columns)
449 internal::TrilinosWrappers::apply_boundary_values(
450 boundary_values, matrix, solution, right_hand_side, eliminate_columns);
457 const std::map<types::global_dof_index, TrilinosScalar> &boundary_values,
461 const bool eliminate_columns)
463 internal::TrilinosWrappers::apply_block_boundary_values(
464 boundary_values, matrix, solution, right_hand_side, eliminate_columns);
471 DEAL_II_NAMESPACE_CLOSE
unsigned int n_block_cols() const
unsigned long long int global_dof_index
void clear_rows(const std::vector< size_type > &rows, const PetscScalar new_diag_value=0)
void compress(const VectorOperation::values operation)
#define Assert(cond, exc)
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::pair< size_type, size_type > local_range() const
PetscScalar diag_element(const size_type i) const
static::ExceptionBase & ExcNotQuadratic()
BlockType & block(const unsigned int row, const unsigned int column)
static::ExceptionBase & ExcNotImplemented()
BlockType & block(const unsigned int i)
unsigned int n_block_rows() const
static::ExceptionBase & ExcInternalError()
void set(const std::vector< size_type > &indices, const std::vector< PetscScalar > &values)
std::pair< size_type, size_type > local_range() const