17 #ifndef dealii_matrix_free_operators_h 18 #define dealii_matrix_free_operators_h 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/subscriptor.h> 23 #include <deal.II/base/vectorization.h> 25 #include <deal.II/lac/diagonal_matrix.h> 26 #include <deal.II/lac/la_parallel_vector.h> 28 #include <deal.II/matrix_free/fe_evaluation.h> 29 #include <deal.II/matrix_free/matrix_free.h> 31 #include <deal.II/multigrid/mg_constrained_dofs.h> 34 DEAL_II_NAMESPACE_OPEN
44 template <
typename VectorType>
45 typename std::enable_if<IsBlockVector<VectorType>::value,
47 n_blocks(
const VectorType &vector)
49 return vector.n_blocks();
52 template <
typename VectorType>
53 typename std::enable_if<!IsBlockVector<VectorType>::value,
55 n_blocks(
const VectorType &)
60 template <
typename VectorType>
61 typename std::enable_if<IsBlockVector<VectorType>::value,
62 typename VectorType::BlockType &>::type
63 subblock(VectorType &vector,
unsigned int block_no)
65 return vector.block(block_no);
68 template <
typename VectorType>
69 typename std::enable_if<IsBlockVector<VectorType>::value,
70 const typename VectorType::BlockType &>::type
71 subblock(
const VectorType &vector,
unsigned int block_no)
74 return vector.block(block_no);
77 template <
typename VectorType>
78 typename std::enable_if<!IsBlockVector<VectorType>::value,
80 subblock(VectorType &vector,
unsigned int)
85 template <
typename VectorType>
86 typename std::enable_if<!IsBlockVector<VectorType>::value,
87 const VectorType &>::type
88 subblock(
const VectorType &vector,
unsigned int)
93 template <
typename VectorType>
94 typename std::enable_if<IsBlockVector<VectorType>::value,
void>::type
95 collect_sizes(VectorType &vector)
97 vector.collect_sizes();
100 template <
typename VectorType>
101 typename std::enable_if<!IsBlockVector<VectorType>::value,
void>::type
102 collect_sizes(
const VectorType &)
208 virtual ~Base()
override =
default;
235 const std::vector<unsigned int> &selected_row_blocks =
236 std::vector<unsigned int>(),
237 const std::vector<unsigned int> &selected_column_blocks =
238 std::vector<unsigned int>());
256 const unsigned int level,
257 const std::vector<unsigned int> &selected_row_blocks =
258 std::vector<unsigned int>());
276 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
277 const unsigned int level,
278 const std::vector<unsigned int> & selected_row_blocks =
279 std::vector<unsigned int>());
309 vmult(VectorType &dst,
const VectorType &src)
const;
315 Tvmult(VectorType &dst,
const VectorType &src)
const;
321 vmult_add(VectorType &dst,
const VectorType &src)
const;
327 Tvmult_add(VectorType &dst,
const VectorType &src)
const;
334 el(
const unsigned int row,
const unsigned int col)
const;
362 std::shared_ptr<const MatrixFree<dim, value_type>>
368 const std::shared_ptr<DiagonalMatrix<VectorType>> &
374 const std::shared_ptr<DiagonalMatrix<VectorType>> &
385 const VectorType &src,
414 apply_add(VectorType &dst,
const VectorType &src)
const = 0;
422 Tapply_add(VectorType &dst,
const VectorType &src)
const;
427 std::shared_ptr<const MatrixFree<dim, value_type>>
data;
462 mutable std::vector<std::vector<std::pair<value_type, value_type>>>
477 const VectorType &src,
489 const bool is_row)
const;
530 template <
typename OperatorType>
564 template <
typename VectorType>
566 vmult(VectorType &dst,
const VectorType &src)
const;
571 template <
typename VectorType>
573 Tvmult(VectorType &dst,
const VectorType &src)
const;
578 template <
typename VectorType>
613 int n_components = 1,
614 typename Number =
double>
635 const unsigned int n_actual_components,
711 int n_q_points_1d = fe_degree + 1,
712 int n_components = 1,
746 apply_add(VectorType &dst,
const VectorType &src)
const override;
755 const VectorType & src,
756 const std::pair<unsigned int, unsigned int> &cell_range)
const;
775 int n_q_points_1d = fe_degree + 1,
776 int n_components = 1,
864 std::shared_ptr<Table<2, VectorizedArray<value_type>>>
874 apply_add(VectorType &dst,
const VectorType &src)
const;
883 const VectorType & src,
884 const std::pair<unsigned int, unsigned int> &cell_range)
const;
894 const std::pair<unsigned int, unsigned int> &cell_range)
const;
903 const unsigned int cell)
const;
915 template <
int dim,
int fe_degree,
int n_components,
typename Number>
922 for (
unsigned int i = 0, c = 0; i < shapes_1d.
m(); ++i)
923 for (
unsigned int j = 0; j < shapes_1d.
n(); ++j, ++c)
926 const unsigned int stride = (fe_degree + 2) / 2;
928 for (
unsigned int i = 0; i < stride; ++i)
929 for (
unsigned int q = 0; q < (fe_degree + 2) / 2; ++q)
932 0.5 * (shapes_1d(i, q) + shapes_1d(i, fe_degree - q));
934 0.5 * (shapes_1d(i, q) - shapes_1d(i, fe_degree - q));
936 if (fe_degree % 2 == 0)
937 for (
unsigned int q = 0; q < (fe_degree + 2) / 2; ++q)
938 inverse_shape[fe_degree / 2 * stride + q] = shapes_1d(fe_degree / 2, q);
943 template <
int dim,
int fe_degree,
int n_components,
typename Number>
949 constexpr
unsigned int dofs_per_component_on_cell =
951 Assert(inverse_jxw.size() > 0 &&
952 inverse_jxw.size() % dofs_per_component_on_cell == 0,
954 "Expected diagonal to be a multiple of scalar dof per cells"));
958 for (
unsigned int q = 0; q < dofs_per_component_on_cell; ++q)
959 inverse_jxw[q] = 1. / fe_eval.JxW(q);
961 for (
unsigned int q = dofs_per_component_on_cell; q < inverse_jxw.size();)
962 for (
unsigned int i = 0; i < dofs_per_component_on_cell; ++i, ++q)
963 inverse_jxw[q] = inverse_jxw[i];
968 template <
int dim,
int fe_degree,
int n_components,
typename Number>
972 const unsigned int n_actual_components,
976 constexpr
unsigned int dofs_per_component =
978 Assert(inverse_coefficients.size() > 0 &&
979 inverse_coefficients.size() % dofs_per_component == 0,
981 "Expected diagonal to be a multiple of scalar dof per cells"));
982 if (inverse_coefficients.size() != dofs_per_component)
984 inverse_coefficients.size());
993 evaluator(inverse_shape, inverse_shape, inverse_shape);
995 const unsigned int shift_coefficient =
996 inverse_coefficients.size() > dofs_per_component ? dofs_per_component : 0;
998 inverse_coefficients.
data();
1000 for (
unsigned int d = 0; d < n_actual_components; ++d)
1006 evaluator.template hessians<0, false, false>(in, temp_data_field);
1009 evaluator.template hessians<1, false, false>(temp_data_field, out);
1013 evaluator.template hessians<2, false, false>(out,
1015 for (
unsigned int q = 0; q < dofs_per_component; ++q)
1016 temp_data_field[q] *= inv_coefficient[q];
1017 evaluator.template hessians<2, true, false>(temp_data_field,
1021 for (
unsigned int q = 0; q < dofs_per_component; ++q)
1022 out[q] *= inv_coefficient[q];
1024 evaluator.template hessians<1, true, false>(out, temp_data_field);
1028 for (
unsigned int q = 0; q < dofs_per_component; ++q)
1029 temp_data_field[q] *= inv_coefficient[q];
1031 evaluator.template hessians<0, true, false>(temp_data_field, out);
1033 inv_coefficient += shift_coefficient;
1039 template <
int dim,
int fe_degree,
int n_components,
typename Number>
1046 constexpr
unsigned int dofs_per_cell =
Utilities::pow(fe_degree + 1, dim);
1056 for (
unsigned int d = 0; d < n_actual_components; ++d)
1063 evaluator.template hessians<2, true, false>(in, out);
1064 evaluator.template hessians<1, true, false>(out, out);
1065 evaluator.template hessians<0, true, false>(out, out);
1069 evaluator.template hessians<1, true, false>(in, out);
1070 evaluator.template hessians<0, true, false>(out, out);
1073 evaluator.template hessians<0, true, false>(in, out);
1080 template <
int dim,
typename VectorType>
1083 , have_interface_matrices(false)
1088 template <
int dim,
typename VectorType>
1094 for (
unsigned int i = 0; i < selected_rows.size(); ++i)
1095 total_size += data->get_vector_partitioner(selected_rows[i])->size();
1101 template <
int dim,
typename VectorType>
1107 for (
unsigned int i = 0; i < selected_columns.size(); ++i)
1108 total_size += data->get_vector_partitioner(selected_columns[i])->size();
1114 template <
int dim,
typename VectorType>
1119 inverse_diagonal_entries.reset();
1124 template <
int dim,
typename VectorType>
1127 const unsigned int col)
const 1131 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1132 inverse_diagonal_entries->m() > 0,
1134 return 1.0 / (*inverse_diagonal_entries)(row, row);
1139 template <
int dim,
typename VectorType>
1145 for (
unsigned int i = 0; i < BlockHelper::n_blocks(vec); ++i)
1147 const unsigned int index = selected_rows[i];
1148 if (!BlockHelper::subblock(vec, index)
1149 .partitioners_are_compatible(
1150 *data->get_dof_info(index).vector_partitioner))
1151 data->initialize_dof_vector(BlockHelper::subblock(vec, index), index);
1153 Assert(BlockHelper::subblock(vec, index)
1154 .partitioners_are_globally_compatible(
1155 *data->get_dof_info(index).vector_partitioner),
1158 BlockHelper::collect_sizes(vec);
1163 template <
int dim,
typename VectorType>
1168 const std::vector<unsigned int> &given_row_selection,
1169 const std::vector<unsigned int> &given_column_selection)
1173 selected_rows.clear();
1174 selected_columns.clear();
1175 if (given_row_selection.empty())
1176 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1177 selected_rows.push_back(i);
1180 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1183 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1185 Assert(given_row_selection[j] != given_row_selection[i],
1186 ExcMessage(
"Given row indices must be unique"));
1188 selected_rows.push_back(given_row_selection[i]);
1191 if (given_column_selection.size() == 0)
1192 selected_columns = selected_rows;
1195 for (
unsigned int i = 0; i < given_column_selection.size(); ++i)
1198 for (
unsigned int j = 0; j < given_column_selection.size(); ++j)
1200 Assert(given_column_selection[j] != given_column_selection[i],
1201 ExcMessage(
"Given column indices must be unique"));
1203 selected_columns.push_back(given_column_selection[i]);
1207 edge_constrained_indices.clear();
1208 edge_constrained_indices.resize(selected_rows.size());
1209 edge_constrained_values.clear();
1210 edge_constrained_values.resize(selected_rows.size());
1211 have_interface_matrices =
false;
1216 template <
int dim,
typename VectorType>
1222 const unsigned int level,
1223 const std::vector<unsigned int> &given_row_selection)
1225 std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(
1226 1, mg_constrained_dofs);
1227 initialize(data_, mg_constrained_dofs_vector, level, given_row_selection);
1232 template <
int dim,
typename VectorType>
1236 const std::vector<MGConstrainedDoFs> & mg_constrained_dofs,
1237 const unsigned int level,
1238 const std::vector<unsigned int> & given_row_selection)
1243 selected_rows.clear();
1244 selected_columns.clear();
1245 if (given_row_selection.empty())
1246 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1247 selected_rows.push_back(i);
1250 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1253 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1255 Assert(given_row_selection[j] != given_row_selection[i],
1256 ExcMessage(
"Given row indices must be unique"));
1258 selected_rows.push_back(given_row_selection[i]);
1261 selected_columns = selected_rows;
1264 edge_constrained_indices.clear();
1265 edge_constrained_indices.resize(selected_rows.size());
1266 edge_constrained_values.clear();
1267 edge_constrained_values.resize(selected_rows.size());
1271 for (
unsigned int j = 0; j < selected_rows.size(); ++j)
1273 if (data_->n_macro_cells() > 0)
1279 std::vector<types::global_dof_index> interface_indices;
1280 mg_constrained_dofs[j]
1281 .get_refinement_edge_indices(level)
1282 .fill_index_vector(interface_indices);
1283 edge_constrained_indices[j].clear();
1284 edge_constrained_indices[j].reserve(interface_indices.size());
1285 edge_constrained_values[j].resize(interface_indices.size());
1287 data->get_dof_handler(selected_rows[j]).locally_owned_mg_dofs(level);
1288 for (
const auto interface_index : interface_indices)
1289 if (locally_owned.
is_element(interface_index))
1290 edge_constrained_indices[j].push_back(
1292 have_interface_matrices |=
1294 static_cast<unsigned int>(edge_constrained_indices[j].size()),
1295 data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1301 template <
int dim,
typename VectorType>
1305 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1307 const std::vector<unsigned int> &constrained_dofs =
1308 data->get_constrained_dofs(selected_rows[j]);
1309 for (
const auto constrained_dof : constrained_dofs)
1310 BlockHelper::subblock(dst, j).local_element(constrained_dof) = 1.;
1311 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1312 BlockHelper::subblock(dst, j).local_element(
1313 edge_constrained_indices[j][i]) = 1.;
1319 template <
int dim,
typename VectorType>
1325 vmult_add(dst, src);
1330 template <
int dim,
typename VectorType>
1334 mult_add(dst, src,
false);
1339 template <
int dim,
typename VectorType>
1342 const VectorType &src)
const 1344 mult_add(dst, src,
true);
1349 template <
int dim,
typename VectorType>
1352 const VectorType &src,
1353 const bool is_row)
const 1356 for (
unsigned int i = 0; i < BlockHelper::n_blocks(src); ++i)
1358 const unsigned int mf_component =
1359 is_row ? selected_rows[i] : selected_columns[i];
1361 if (BlockHelper::subblock(src, i).get_partitioner().get() ==
1362 data->get_dof_info(mf_component).vector_partitioner.get())
1368 BlockHelper::subblock(src, i).get_partitioner()->local_size() ==
1369 data->get_dof_info(mf_component).vector_partitioner->local_size(),
1370 ExcMessage(
"The vector passed to the vmult() function does not have " 1371 "the correct size for compatibility with MatrixFree."));
1376 BlockHelper::subblock(src, i));
1377 BlockHelper::subblock(const_cast<VectorType &>(src), i)
1378 .reinit(data->get_dof_info(mf_component).vector_partitioner);
1379 BlockHelper::subblock(const_cast<VectorType &>(src), i)
1380 .copy_locally_owned_data_from(copy_vec);
1386 template <
int dim,
typename VectorType>
1389 const VectorType &src)
const 1392 adjust_ghost_range_if_necessary(src,
false);
1393 adjust_ghost_range_if_necessary(dst,
true);
1397 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1399 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1401 edge_constrained_values[j][i] = std::pair<Number, Number>(
1402 BlockHelper::subblock(src, j).local_element(
1403 edge_constrained_indices[j][i]),
1404 BlockHelper::subblock(dst, j).local_element(
1405 edge_constrained_indices[j][i]));
1406 BlockHelper::subblock(const_cast<VectorType &>(src), j)
1407 .local_element(edge_constrained_indices[j][i]) = 0.;
1414 template <
int dim,
typename VectorType>
1417 const VectorType &src,
1421 AssertDimension(BlockHelper::n_blocks(dst), BlockHelper::n_blocks(src));
1423 preprocess_constraints(dst, src);
1425 Tapply_add(dst, src);
1427 apply_add(dst, src);
1428 postprocess_constraints(dst, src);
1433 template <
int dim,
typename VectorType>
1436 const VectorType &src)
const 1438 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1440 const std::vector<unsigned int> &constrained_dofs =
1441 data->get_constrained_dofs(selected_rows[j]);
1442 for (
const auto constrained_dof : constrained_dofs)
1443 BlockHelper::subblock(dst, j).local_element(constrained_dof) +=
1444 BlockHelper::subblock(src, j).local_element(constrained_dof);
1449 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1451 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1453 BlockHelper::subblock(const_cast<VectorType &>(src), j)
1454 .local_element(edge_constrained_indices[j][i]) =
1455 edge_constrained_values[j][i].first;
1456 BlockHelper::subblock(dst, j).local_element(
1457 edge_constrained_indices[j][i]) =
1458 edge_constrained_values[j][i].second +
1459 edge_constrained_values[j][i].first;
1466 template <
int dim,
typename VectorType>
1469 const VectorType &src)
const 1473 adjust_ghost_range_if_necessary(src,
false);
1474 adjust_ghost_range_if_necessary(dst,
true);
1478 if (!have_interface_matrices)
1483 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1484 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1486 edge_constrained_values[j][i] = std::pair<Number, Number>(
1487 BlockHelper::subblock(src, j).local_element(
1488 edge_constrained_indices[j][i]),
1489 BlockHelper::subblock(dst, j).local_element(
1490 edge_constrained_indices[j][i]));
1491 BlockHelper::subblock(const_cast<VectorType &>(src), j)
1492 .local_element(edge_constrained_indices[j][i]) = 0.;
1495 apply_add(dst, src);
1497 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1500 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1502 for (; c < edge_constrained_indices[j][i]; ++c)
1503 BlockHelper::subblock(dst, j).local_element(c) = 0.;
1507 BlockHelper::subblock(const_cast<VectorType &>(src), j)
1508 .local_element(edge_constrained_indices[j][i]) =
1509 edge_constrained_values[j][i].first;
1511 for (; c < BlockHelper::subblock(dst, j).local_size(); ++c)
1512 BlockHelper::subblock(dst, j).local_element(c) = 0.;
1518 template <
int dim,
typename VectorType>
1521 const VectorType &src)
const 1525 adjust_ghost_range_if_necessary(src,
false);
1526 adjust_ghost_range_if_necessary(dst,
true);
1530 if (!have_interface_matrices)
1533 VectorType src_cpy(src);
1534 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1537 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1539 for (; c < edge_constrained_indices[j][i]; ++c)
1540 BlockHelper::subblock(src_cpy, j).local_element(c) = 0.;
1543 for (; c < BlockHelper::subblock(src_cpy, j).local_size(); ++c)
1544 BlockHelper::subblock(src_cpy, j).local_element(c) = 0.;
1547 apply_add(dst, src_cpy);
1549 for (
unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1550 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1551 BlockHelper::subblock(dst, j).local_element(
1552 edge_constrained_indices[j][i]) = 0.;
1557 template <
int dim,
typename VectorType>
1563 Tvmult_add(dst, src);
1568 template <
int dim,
typename VectorType>
1572 return inverse_diagonal_entries.get() !=
nullptr ?
1573 inverse_diagonal_entries->memory_consumption() :
1579 template <
int dim,
typename VectorType>
1589 template <
int dim,
typename VectorType>
1590 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1593 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1594 inverse_diagonal_entries->m() > 0,
1596 return inverse_diagonal_entries;
1601 template <
int dim,
typename VectorType>
1602 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1605 Assert(diagonal_entries.get() !=
nullptr && diagonal_entries->m() > 0,
1607 return diagonal_entries;
1612 template <
int dim,
typename VectorType>
1615 const VectorType &src)
const 1617 apply_add(dst, src);
1622 template <
int dim,
typename VectorType>
1626 const VectorType & src,
1629 Assert(inverse_diagonal_entries.get() && inverse_diagonal_entries->m() > 0,
1631 inverse_diagonal_entries->vmult(dst, src);
1639 template <
typename OperatorType>
1642 , mf_base_operator(nullptr)
1647 template <
typename OperatorType>
1651 mf_base_operator =
nullptr;
1656 template <
typename OperatorType>
1660 mf_base_operator = &operator_in;
1665 template <
typename OperatorType>
1666 template <
typename VectorType>
1669 const VectorType &src)
const 1671 #ifndef DEAL_II_MSVC 1673 std::is_same<typename VectorType::value_type, value_type>::value,
1674 "The vector type must be based on the same value type as this" 1680 mf_base_operator->vmult_interface_down(dst, src);
1685 template <
typename OperatorType>
1686 template <
typename VectorType>
1689 const VectorType &src)
const 1691 #ifndef DEAL_II_MSVC 1693 std::is_same<typename VectorType::value_type, value_type>::value,
1694 "The vector type must be based on the same value type as this" 1700 mf_base_operator->vmult_interface_up(dst, src);
1705 template <
typename OperatorType>
1706 template <
typename VectorType>
1709 VectorType &vec)
const 1713 mf_base_operator->initialize_dof_vector(vec);
1724 typename VectorType>
1727 :
Base<dim, VectorType>()
1736 typename VectorType>
1746 VectorType &inverse_diagonal_vector =
1747 this->inverse_diagonal_entries->get_vector();
1748 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1749 this->initialize_dof_vector(inverse_diagonal_vector);
1750 this->initialize_dof_vector(diagonal_vector);
1751 inverse_diagonal_vector = Number(1.);
1752 apply_add(diagonal_vector, inverse_diagonal_vector);
1754 this->set_constrained_entries_to_one(diagonal_vector);
1755 inverse_diagonal_vector = diagonal_vector;
1757 const unsigned int local_size = inverse_diagonal_vector.local_size();
1758 for (
unsigned int i = 0; i < local_size; ++i)
1759 inverse_diagonal_vector.local_element(i) =
1760 Number(1.) / inverse_diagonal_vector.local_element(i);
1762 inverse_diagonal_vector.update_ghost_values();
1763 diagonal_vector.update_ghost_values();
1772 typename VectorType>
1789 typename VectorType>
1795 const VectorType & src,
1796 const std::pair<unsigned int, unsigned int> &cell_range)
const 1800 data, this->selected_rows[0]);
1801 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
1806 for (
unsigned int q = 0; q < phi.
n_q_points; ++q)
1820 typename VectorType>
1823 :
Base<dim, VectorType>()
1832 typename VectorType>
1838 scalar_coefficient.reset();
1847 typename VectorType>
1851 const std::shared_ptr<
1853 &scalar_coefficient_)
1855 scalar_coefficient = scalar_coefficient_;
1864 typename VectorType>
1871 VectorType>::value_type>>>
1876 return scalar_coefficient;
1885 typename VectorType>
1895 VectorType &inverse_diagonal_vector =
1896 this->inverse_diagonal_entries->get_vector();
1897 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1898 this->initialize_dof_vector(inverse_diagonal_vector);
1899 this->initialize_dof_vector(diagonal_vector);
1905 this->set_constrained_entries_to_one(diagonal_vector);
1907 inverse_diagonal_vector = diagonal_vector;
1909 for (
unsigned int i = 0; i < inverse_diagonal_vector.local_size(); ++i)
1910 if (std::abs(inverse_diagonal_vector.local_element(i)) >
1911 std::sqrt(std::numeric_limits<Number>::epsilon()))
1912 inverse_diagonal_vector.local_element(i) =
1913 1. / inverse_diagonal_vector.local_element(i);
1915 inverse_diagonal_vector.local_element(i) = 1.;
1917 inverse_diagonal_vector.update_ghost_values();
1918 diagonal_vector.update_ghost_values();
1927 typename VectorType>
1938 namespace Implementation
1940 template <
typename Number>
1944 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
1959 typename VectorType>
1968 const unsigned int cell)
const 1970 phi.evaluate(
false,
true,
false);
1971 if (scalar_coefficient.get())
1973 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
1975 Assert(Implementation::non_negative((*scalar_coefficient)(cell, q)),
1976 ExcMessage(
"Coefficient must be non-negative"));
1977 phi.submit_gradient((*scalar_coefficient)(cell, q) *
1978 phi.get_gradient(q),
1984 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
1986 phi.submit_gradient(phi.get_gradient(q), q);
1989 phi.integrate(
false,
true);
1998 typename VectorType>
2004 const VectorType & src,
2005 const std::pair<unsigned int, unsigned int> &cell_range)
const 2009 data, this->selected_rows[0]);
2010 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2014 do_operation_on_cell(phi, cell);
2024 typename VectorType>
2031 const std::pair<unsigned int, unsigned int> &cell_range)
const 2035 data, this->selected_rows[0]);
2036 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2045 do_operation_on_cell(phi, cell);
2051 local_diagonal_vector[i];
2060 DEAL_II_NAMESPACE_CLOSE
typename OperatorType::value_type value_type
void do_operation_on_cell(FEEvaluation< dim, fe_degree, n_q_points_1d, n_components, value_type > &phi, const unsigned int cell) const
static const unsigned int invalid_unsigned_int
void vmult_interface_down(VectorType &dst, const VectorType &src) const
std::vector< unsigned int > selected_rows
#define AssertDimension(dim1, dim2)
virtual void apply_add(VectorType &dst, const VectorType &src) const
void local_apply_cell(const MatrixFree< dim, value_type > &data, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
typename VectorType::size_type size_type
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal_inverse() const
void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
void integrate(const bool integrate_values, const bool integrate_gradients)
typename VectorType::value_type value_type
void precondition_Jacobi(VectorType &dst, const VectorType &src, const value_type omega) const
void fill_inverse_JxW_values(AlignedVector< VectorizedArray< Number >> &inverse_jxw) const
static constexpr unsigned int static_dofs_per_cell
#define AssertIndexRange(index, range)
std::vector< std::vector< std::pair< value_type, value_type > > > edge_constrained_values
void mult_add(VectorType &dst, const VectorType &src, const bool transpose) const
const VectorizedArray< Number > * begin_dof_values() const
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal() const
static ::ExceptionBase & ExcNotInitialized()
void vmult_interface_up(VectorType &dst, const VectorType &src) const
std::shared_ptr< DiagonalMatrix< VectorType > > inverse_diagonal_entries
#define AssertThrow(cond, exc)
void set_constrained_entries_to_one(VectorType &dst) const
std::shared_ptr< DiagonalMatrix< VectorType > > diagonal_entries
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
static constexpr unsigned int n_components
typename OperatorType::size_type size_type
void resize(const size_type size_in)
AlignedVector< Number > shape_values
const unsigned int dofs_per_component
value_type get_value(const unsigned int q_point) const
void submit_value(const value_type val_in, const unsigned int q_point)
const FEEvaluationBase< dim, n_components, Number > & fe_eval
void initialize_dof_vector(VectorType &vec) const
virtual void compute_diagonal()
std::vector< unsigned int > selected_columns
value_type el(const unsigned int row, const unsigned int col) const
static ::ExceptionBase & ExcMessage(std::string arg1)
const unsigned int n_q_points
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info() const
virtual void Tapply_add(VectorType &dst, const VectorType &src) const
void Tvmult(VectorType &dst, const VectorType &src) const
#define Assert(cond, exc)
size_type index_within_set(const size_type global_index) const
void local_diagonal_cell(const MatrixFree< dim, value_type > &data, VectorType &dst, const VectorType &, const std::pair< unsigned int, unsigned int > &cell_range) const
constexpr unsigned int pow(const unsigned int base, const int iexp)
void set_coefficient(const std::shared_ptr< Table< 2, VectorizedArray< value_type >>> &scalar_coefficient)
virtual void compute_diagonal()=0
void apply(const AlignedVector< VectorizedArray< Number >> &inverse_coefficient, const unsigned int n_actual_components, const VectorizedArray< Number > *in_array, VectorizedArray< Number > *out_array) const
std::vector< std::vector< unsigned int > > edge_constrained_indices
AlignedVector< VectorizedArray< Number > > inverse_shape
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
void Tvmult_add(VectorType &dst, const VectorType &src) const
void vmult(VectorType &dst, const VectorType &src) const
void transform_from_q_points_to_basis(const unsigned int n_actual_components, const VectorizedArray< Number > *in_array, VectorizedArray< Number > *out_array) const
void reinit(const unsigned int cell_batch_index)
virtual void apply_add(VectorType &dst, const VectorType &src) const =0
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > scalar_coefficient
void vmult(VectorType &dst, const VectorType &src) const
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0, const std::bitset< VectorizedArray< Number >::n_array_elements > &mask=std::bitset< VectorizedArray< Number >::n_array_elements >().flip()) const
virtual void compute_diagonal() override
virtual ~Base() override=default
void preprocess_constraints(VectorType &dst, const VectorType &src) const
CellwiseInverseMassMatrix(const FEEvaluationBase< dim, n_components, Number > &fe_eval)
void local_apply_cell(const MatrixFree< dim, value_type > &data, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
std::shared_ptr< const MatrixFree< dim, value_type > > get_matrix_free() const
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > get_coefficient()
virtual std::size_t memory_consumption() const
std::shared_ptr< const MatrixFree< dim, value_type > > data
virtual void apply_add(VectorType &dst, const VectorType &src) const override
void postprocess_constraints(VectorType &dst, const VectorType &src) const
static ::ExceptionBase & ExcNotImplemented()
bool is_element(const size_type index) const
void adjust_ghost_range_if_necessary(const VectorType &vec, const bool is_row) const
void vmult_add(VectorType &dst, const VectorType &src) const
void initialize(const OperatorType &operator_in)
SmartPointer< const OperatorType > mf_base_operator
void Tvmult(VectorType &dst, const VectorType &src) const
void initialize_dof_vector(VectorType &vec) const
T max(const T &t, const MPI_Comm &mpi_communicator)
bool have_interface_matrices
void initialize(std::shared_ptr< const MatrixFree< dim, value_type >> data, const std::vector< unsigned int > &selected_row_blocks=std::vector< unsigned int >(), const std::vector< unsigned int > &selected_column_blocks=std::vector< unsigned int >())
static ::ExceptionBase & ExcInternalError()