14#ifndef dealii_matrix_free_operators_h
15#define dealii_matrix_free_operators_h
45 template <
typename VectorType>
46 std::enable_if_t<IsBlockVector<VectorType>::value,
unsigned int>
49 return vector.n_blocks();
52 template <
typename VectorType>
53 std::enable_if_t<!IsBlockVector<VectorType>::value,
unsigned int>
59 template <
typename VectorType>
60 std::enable_if_t<IsBlockVector<VectorType>::value,
61 typename VectorType::BlockType &>
62 subblock(VectorType &vector,
unsigned int block_no)
65 return vector.block(block_no);
68 template <
typename VectorType>
69 std::enable_if_t<IsBlockVector<VectorType>::value,
70 const typename VectorType::BlockType &>
71 subblock(
const VectorType &vector,
unsigned int block_no)
74 return vector.block(block_no);
77 template <
typename VectorType>
78 std::enable_if_t<!IsBlockVector<VectorType>::value, VectorType &>
84 template <
typename VectorType>
85 std::enable_if_t<!IsBlockVector<VectorType>::value,
const VectorType &>
86 subblock(
const VectorType &vector,
unsigned int)
91 template <
typename VectorType>
92 std::enable_if_t<IsBlockVector<VectorType>::value,
void>
95 vector.collect_sizes();
98 template <
typename VectorType>
99 std::enable_if_t<!IsBlockVector<VectorType>::value,
void>
183 typename VectorizedArrayType =
234 const std::vector<unsigned int> &selected_row_blocks =
235 std::vector<unsigned int>(),
236 const std::vector<unsigned int> &selected_column_blocks =
237 std::vector<unsigned int>());
256 const unsigned int level,
257 const std::vector<unsigned int> &selected_row_blocks =
258 std::vector<unsigned int>());
277 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
278 const unsigned int level,
279 const std::vector<unsigned int> &selected_row_blocks =
280 std::vector<unsigned int>());
310 vmult(VectorType &dst,
const VectorType &src)
const;
316 Tvmult(VectorType &dst,
const VectorType &src)
const;
322 vmult_add(VectorType &dst,
const VectorType &src)
const;
335 el(
const unsigned int row,
const unsigned int col)
const;
368 std::shared_ptr<const MatrixFree<dim, value_type, VectorizedArrayType>>
374 const std::shared_ptr<DiagonalMatrix<VectorType>> &
380 const std::shared_ptr<DiagonalMatrix<VectorType>> &
390 const VectorType &src,
419 apply_add(VectorType &dst,
const VectorType &src)
const = 0;
432 std::shared_ptr<const MatrixFree<dim, value_type, VectorizedArrayType>>
468 mutable std::vector<std::vector<std::pair<value_type, value_type>>>
483 const VectorType &src,
495 const bool is_row)
const;
534 template <
typename OperatorType>
568 template <
typename VectorType>
570 vmult(VectorType &dst,
const VectorType &src)
const;
575 template <
typename VectorType>
577 Tvmult(VectorType &dst,
const VectorType &src)
const;
582 template <
typename VectorType>
616 int n_components = 1,
617 typename Number = double,
622 std::is_same_v<Number, typename VectorizedArrayType::value_type>,
623 "Type of Number and of VectorizedArrayType do not match.");
635 VectorizedArrayType> &
fe_eval);
648 const unsigned int n_actual_components,
649 const VectorizedArrayType *in_array,
650 VectorizedArrayType *out_array)
const;
664 apply(
const VectorizedArrayType *in_array,
665 VectorizedArrayType *out_array)
const;
681 &inverse_dyadic_coefficients,
682 const VectorizedArrayType *in_array,
683 VectorizedArrayType *out_array)
const;
720 const VectorizedArrayType *in_array,
721 VectorizedArrayType *out_array)
const;
754 int n_q_points_1d = fe_degree + 1,
755 int n_components = 1,
757 typename VectorizedArrayType =
807 const std::shared_ptr<DiagonalMatrix<VectorType>> &
813 const std::shared_ptr<DiagonalMatrix<VectorType>> &
823 apply_add(VectorType &dst,
const VectorType &src)
const override;
832 const VectorType &src,
833 const std::pair<unsigned int, unsigned int> &cell_range)
const;
887 int n_q_points_1d = fe_degree + 1,
888 int n_components = 1,
890 typename VectorizedArrayType =
988 std::shared_ptr<Table<2, VectorizedArrayType>>
998 apply_add(VectorType &dst,
const VectorType &src)
const override;
1007 const VectorType &src,
1008 const std::pair<unsigned int, unsigned int> &cell_range)
const;
1018 const std::pair<unsigned int, unsigned int> &cell_range)
const;
1023 template <
int n_components_compute>
1028 n_components_compute,
1030 VectorizedArrayType> &phi,
1031 const unsigned int cell)
const;
1047 typename VectorizedArrayType>
1052 VectorizedArrayType>::
1053 CellwiseInverseMassMatrix(
1058 VectorizedArrayType> &fe_eval)
1062 fe_eval.get_shape_info().n_q_points);
1071 typename VectorizedArrayType>
1077 VectorizedArrayType>::
1078 fill_inverse_JxW_values(
1081 const unsigned int dofs_per_component_on_cell =
1084 Utilities::pow(fe_eval.get_shape_info().data.front().fe_degree + 1,
1088 inverse_jxw.
size() % dofs_per_component_on_cell == 0,
1090 "Expected diagonal to be a multiple of scalar dof per cells"));
1093 for (
unsigned int q = 0; q < dofs_per_component_on_cell; ++q)
1094 inverse_jxw[q] = 1. / fe_eval.JxW(q);
1096 for (
unsigned int q = dofs_per_component_on_cell; q < inverse_jxw.
size();)
1097 for (
unsigned int i = 0; i < dofs_per_component_on_cell; ++i, ++q)
1098 inverse_jxw[q] = inverse_jxw[i];
1107 typename VectorizedArrayType>
1114 VectorizedArrayType>::apply(
const VectorizedArrayType *in_array,
1115 VectorizedArrayType *out_array)
const
1119 template run<fe_degree>(n_components, fe_eval, in_array, out_array);
1122 n_components, fe_eval, in_array, out_array);
1131 typename VectorizedArrayType>
1137 VectorizedArrayType>::
1139 const unsigned int n_actual_components,
1140 const VectorizedArrayType *in_array,
1141 VectorizedArrayType *out_array)
const
1146 VectorizedArrayType>::template run<fe_degree>(n_actual_components,
1149 inverse_coefficients),
1155 n_actual_components,
1167 typename VectorizedArrayType>
1173 VectorizedArrayType>::
1175 &inverse_dyadic_coefficients,
1176 const VectorizedArrayType *in_array,
1177 VectorizedArrayType *out_array)
const
1179 const unsigned int unrolled_size =
1180 inverse_dyadic_coefficients.size() * (n_components * n_components);
1184 VectorizedArrayType>::
1185 template run<fe_degree>(n_components,
1188 &inverse_dyadic_coefficients[0][0][0],
1198 &inverse_dyadic_coefficients[0][0][0], unrolled_size),
1210 typename VectorizedArrayType>
1216 VectorizedArrayType>::
1217 transform_from_q_points_to_basis(
const unsigned int n_actual_components,
1218 const VectorizedArrayType *in_array,
1219 VectorizedArrayType *out_array)
const
1221 const auto n_q_points_1d = fe_eval.get_shape_info().data[0].n_q_points_1d;
1223 if (fe_degree > -1 && (fe_degree + 1 == n_q_points_1d))
1226 VectorizedArrayType>::template run<fe_degree,
1227 fe_degree + 1>(n_actual_components,
1242 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1245 , have_interface_matrices(false)
1250 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1257 for (
const unsigned int selected_row : selected_rows)
1258 total_size +=
data->get_vector_partitioner(selected_row)->size();
1264 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1271 for (
const unsigned int selected_column : selected_columns)
1272 total_size +=
data->get_vector_partitioner(selected_column)->size();
1278 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1283 inverse_diagonal_entries.reset();
1288 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1291 const unsigned int col)
const
1294 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1295 inverse_diagonal_entries->m() > 0,
1297 return 1.0 / (*inverse_diagonal_entries)(row, row);
1302 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1305 VectorType &vec)
const
1311 const unsigned int index = selected_rows[i];
1313 .partitioners_are_compatible(
1314 *
data->get_dof_info(index).vector_partitioner))
1318 .partitioners_are_globally_compatible(
1319 *
data->get_dof_info(index).vector_partitioner),
1327 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1332 const std::vector<unsigned int> &given_row_selection,
1333 const std::vector<unsigned int> &given_column_selection)
1337 selected_rows.clear();
1338 selected_columns.clear();
1339 if (given_row_selection.empty())
1340 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1341 selected_rows.push_back(i);
1344 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1347 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1349 Assert(given_row_selection[j] != given_row_selection[i],
1350 ExcMessage(
"Given row indices must be unique"));
1352 selected_rows.push_back(given_row_selection[i]);
1355 if (given_column_selection.empty())
1356 selected_columns = selected_rows;
1359 for (
unsigned int i = 0; i < given_column_selection.size(); ++i)
1362 for (
unsigned int j = 0; j < given_column_selection.size(); ++j)
1364 Assert(given_column_selection[j] != given_column_selection[i],
1365 ExcMessage(
"Given column indices must be unique"));
1367 selected_columns.push_back(given_column_selection[i]);
1371 edge_constrained_indices.clear();
1372 edge_constrained_indices.resize(selected_rows.size());
1373 edge_constrained_values.clear();
1374 edge_constrained_values.resize(selected_rows.size());
1375 have_interface_matrices =
false;
1380 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1386 const unsigned int level,
1387 const std::vector<unsigned int> &given_row_selection)
1389 std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(
1390 1, mg_constrained_dofs);
1391 initialize(data_, mg_constrained_dofs_vector,
level, given_row_selection);
1396 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1401 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
1402 const unsigned int level,
1403 const std::vector<unsigned int> &given_row_selection)
1408 selected_rows.clear();
1409 selected_columns.clear();
1410 if (given_row_selection.empty())
1411 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1412 selected_rows.push_back(i);
1415 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1418 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1420 Assert(given_row_selection[j] != given_row_selection[i],
1421 ExcMessage(
"Given row indices must be unique"));
1423 selected_rows.push_back(given_row_selection[i]);
1426 selected_columns = selected_rows;
1429 edge_constrained_indices.clear();
1430 edge_constrained_indices.resize(selected_rows.size());
1431 edge_constrained_values.clear();
1432 edge_constrained_values.resize(selected_rows.size());
1436 for (
unsigned int j = 0; j < selected_rows.size(); ++j)
1438 if (data_->n_cell_batches() > 0)
1444 const std::vector<types::global_dof_index> interface_indices =
1445 mg_constrained_dofs[j]
1446 .get_refinement_edge_indices(
level)
1447 .get_index_vector();
1448 edge_constrained_indices[j].clear();
1449 edge_constrained_indices[j].reserve(interface_indices.size());
1450 edge_constrained_values[j].resize(interface_indices.size());
1452 data->get_dof_handler(selected_rows[j]).locally_owned_mg_dofs(
level);
1453 for (
const auto interface_index : interface_indices)
1454 if (locally_owned.
is_element(interface_index))
1457 have_interface_matrices |=
1459 static_cast<unsigned int>(edge_constrained_indices[j].
size()),
1460 data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1466 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1469 VectorType &dst)
const
1473 const std::vector<unsigned int> &constrained_dofs =
1474 data->get_constrained_dofs(selected_rows[j]);
1475 for (
const auto constrained_dof : constrained_dofs)
1477 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1479 edge_constrained_indices[j][i]) = 1.;
1485 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1488 const VectorType &src)
const
1493 vmult_add(dst, src);
1498 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1502 const VectorType &src)
const
1504 mult_add(dst, src,
false);
1509 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1513 const VectorType &src)
const
1515 mult_add(dst, src,
true);
1520 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1523 const VectorType &src,
1524 const bool is_row)
const
1530 const unsigned int mf_component =
1531 is_row ? selected_rows[i] : selected_columns[i];
1534 data->get_dof_info(mf_component).vector_partitioner.get())
1542 data->get_dof_info(mf_component)
1543 .vector_partitioner->locally_owned_size(),
1545 "The vector passed to the vmult() function does not have "
1546 "the correct size for compatibility with MatrixFree."));
1552 this->
data->initialize_dof_vector(
1556 .copy_locally_owned_data_from(copy_vec);
1562 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1566 const VectorType &src)
const
1570 adjust_ghost_range_if_necessary(src,
false);
1571 adjust_ghost_range_if_necessary(dst,
true);
1577 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1579 edge_constrained_values[j][i] = std::pair<Number, Number>(
1581 edge_constrained_indices[j][i]),
1583 edge_constrained_indices[j][i]));
1585 .local_element(edge_constrained_indices[j][i]) = 0.;
1592 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1596 const VectorType &src,
1602 preprocess_constraints(dst, src);
1604 Tapply_add(dst, src);
1606 apply_add(dst, src);
1607 postprocess_constraints(dst, src);
1612 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1616 const VectorType &src)
const
1620 const std::vector<unsigned int> &constrained_dofs =
1621 data->get_constrained_dofs(selected_rows[j]);
1622 for (
const auto constrained_dof : constrained_dofs)
1631 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1634 .local_element(edge_constrained_indices[j][i]) =
1635 edge_constrained_values[j][i].first;
1637 edge_constrained_indices[j][i]) =
1638 edge_constrained_values[j][i].second +
1639 edge_constrained_values[j][i].first;
1646 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1650 const VectorType &src)
const
1655 adjust_ghost_range_if_necessary(src,
false);
1656 adjust_ghost_range_if_necessary(dst,
true);
1660 if (!have_interface_matrices)
1666 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1668 edge_constrained_values[j][i] = std::pair<Number, Number>(
1670 edge_constrained_indices[j][i]),
1672 edge_constrained_indices[j][i]));
1674 .local_element(edge_constrained_indices[j][i]) = 0.;
1677 apply_add(dst, src);
1682 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1684 for (; c < edge_constrained_indices[j][i]; ++c)
1690 .local_element(edge_constrained_indices[j][i]) =
1691 edge_constrained_values[j][i].first;
1700 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1704 const VectorType &src)
const
1709 adjust_ghost_range_if_necessary(src,
false);
1710 adjust_ghost_range_if_necessary(dst,
true);
1714 if (!have_interface_matrices)
1717 VectorType src_cpy(src);
1721 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1723 for (; c < edge_constrained_indices[j][i]; ++c)
1731 apply_add(dst, src_cpy);
1734 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1736 edge_constrained_indices[j][i]) = 0.;
1741 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1745 const VectorType &src)
const
1750 Tvmult_add(dst, src);
1755 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1759 return inverse_diagonal_entries.get() !=
nullptr ?
1760 inverse_diagonal_entries->memory_consumption() :
1766 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1770 VectorizedArrayType>>
1778 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1779 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1783 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1784 inverse_diagonal_entries->m() > 0,
1786 return inverse_diagonal_entries;
1791 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1792 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1795 Assert(diagonal_entries.get() !=
nullptr && diagonal_entries->m() > 0,
1797 return diagonal_entries;
1802 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1806 const VectorType &src)
const
1808 apply_add(dst, src);
1813 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1817 const VectorType &src,
1821 Assert(inverse_diagonal_entries.get() && inverse_diagonal_entries->m() > 0,
1823 inverse_diagonal_entries->vmult(dst, src);
1831 template <
typename OperatorType>
1834 , mf_base_operator(nullptr)
1839 template <
typename OperatorType>
1843 mf_base_operator =
nullptr;
1848 template <
typename OperatorType>
1852 mf_base_operator = &operator_in;
1857 template <
typename OperatorType>
1858 template <
typename VectorType>
1861 const VectorType &src)
const
1865 std::is_same_v<typename VectorType::value_type, value_type>,
1866 "The vector type must be based on the same value type as this "
1872 mf_base_operator->vmult_interface_down(dst, src);
1877 template <
typename OperatorType>
1878 template <
typename VectorType>
1881 const VectorType &src)
const
1885 std::is_same_v<typename VectorType::value_type, value_type>,
1886 "The vector type must be based on the same value type as this "
1892 mf_base_operator->vmult_interface_up(dst, src);
1897 template <
typename OperatorType>
1898 template <
typename VectorType>
1901 VectorType &vec)
const
1905 mf_base_operator->initialize_dof_vector(vec);
1916 typename VectorType,
1917 typename VectorizedArrayType>
1923 VectorizedArrayType>::MassOperator()
1924 :
Base<dim, VectorType, VectorizedArrayType>()
1929 "This class only supports the non-blocked vector variant of the Base "
1930 "operator because only a single FEEvaluation object is used in the "
1931 "apply function."));
1940 typename VectorType,
1941 typename VectorizedArrayType>
1948 VectorizedArrayType>::compute_diagonal()
1952 Assert(this->selected_rows == this->selected_columns,
1953 ExcMessage(
"This function is only implemented for square (not "
1954 "rectangular) operators."));
1956 this->inverse_diagonal_entries =
1957 std::make_shared<DiagonalMatrix<VectorType>>();
1958 this->diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
1959 VectorType &inverse_diagonal_vector =
1960 this->inverse_diagonal_entries->get_vector();
1961 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1962 this->initialize_dof_vector(inverse_diagonal_vector);
1963 this->initialize_dof_vector(diagonal_vector);
1967 auto diagonal_evaluation = [](
auto &integrator) {
1969 for (
unsigned int q = 0; q < integrator.n_q_points; ++q)
1970 integrator.submit_value(integrator.get_value(q), q);
1981 VectorizedArrayType> &)>
1982 diagonal_evaluation_f(diagonal_evaluation);
1985 for (
unsigned int block_n = 0; block_n < this->selected_rows.size();
1990 diagonal_evaluation_f,
1991 this->selected_rows[block_n]);
1995 this->set_constrained_entries_to_one(diagonal_vector);
1997 inverse_diagonal_vector = diagonal_vector;
1999 for (
unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size();
2007 Assert(diagonal_vector.local_element(i) > Number(0),
2010 inverse_diagonal_vector.local_element(i) =
2011 1. / inverse_diagonal_vector.local_element(i);
2023 typename VectorType,
2024 typename VectorizedArrayType>
2031 VectorizedArrayType>::compute_lumped_diagonal()
2037 Assert(this->selected_rows == this->selected_columns,
2038 ExcMessage(
"This function is only implemented for square (not "
2039 "rectangular) operators."));
2041 inverse_lumped_diagonal_entries =
2042 std::make_shared<DiagonalMatrix<VectorType>>();
2043 lumped_diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
2044 VectorType &inverse_lumped_diagonal_vector =
2045 inverse_lumped_diagonal_entries->get_vector();
2046 VectorType &lumped_diagonal_vector = lumped_diagonal_entries->get_vector();
2047 this->initialize_dof_vector(inverse_lumped_diagonal_vector);
2048 this->initialize_dof_vector(lumped_diagonal_vector);
2051 inverse_lumped_diagonal_vector = Number(1.);
2052 apply_add(lumped_diagonal_vector, inverse_lumped_diagonal_vector);
2053 this->set_constrained_entries_to_one(lumped_diagonal_vector);
2056 inverse_lumped_diagonal_vector.locally_owned_size();
2063 if (lumped_diagonal_vector.local_element(i) == Number(0.))
2064 inverse_lumped_diagonal_vector.local_element(i) = Number(1.);
2066 inverse_lumped_diagonal_vector.local_element(i) =
2067 Number(1.) / lumped_diagonal_vector.local_element(i);
2070 inverse_lumped_diagonal_vector.update_ghost_values();
2071 lumped_diagonal_vector.update_ghost_values();
2080 typename VectorType,
2081 typename VectorizedArrayType>
2082 const std::shared_ptr<DiagonalMatrix<VectorType>> &
2088 VectorizedArrayType>::get_matrix_lumped_diagonal_inverse()
const
2090 Assert(inverse_lumped_diagonal_entries.get() !=
nullptr &&
2091 inverse_lumped_diagonal_entries->m() > 0,
2093 return inverse_lumped_diagonal_entries;
2102 typename VectorType,
2103 typename VectorizedArrayType>
2104 const std::shared_ptr<DiagonalMatrix<VectorType>> &
2110 VectorizedArrayType>::get_matrix_lumped_diagonal()
const
2112 Assert(lumped_diagonal_entries.get() !=
nullptr &&
2113 lumped_diagonal_entries->m() > 0,
2115 return lumped_diagonal_entries;
2124 typename VectorType,
2125 typename VectorizedArrayType>
2132 VectorizedArrayType>::apply_add(VectorType &dst,
2133 const VectorType &src)
const
2145 typename VectorType,
2146 typename VectorizedArrayType>
2153 VectorizedArrayType>::
2158 VectorizedArrayType> &
data,
2160 const VectorType &src,
2161 const std::pair<unsigned int, unsigned int> &cell_range)
const
2170 VectorizedArrayType>
2171 phi(
data, this->selected_rows[0]);
2172 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2175 phi.read_dof_values(src);
2177 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2178 phi.submit_value(phi.get_value(q), q);
2180 phi.distribute_local_to_global(dst);
2191 typename VectorType,
2192 typename VectorizedArrayType>
2198 VectorizedArrayType>::LaplaceOperator()
2199 :
Base<dim, VectorType, VectorizedArrayType>()
2208 typename VectorType,
2209 typename VectorizedArrayType>
2216 VectorizedArrayType>::clear()
2219 scalar_coefficient.reset();
2228 typename VectorType,
2229 typename VectorizedArrayType>
2236 VectorizedArrayType>::
2240 scalar_coefficient = scalar_coefficient_;
2249 typename VectorType,
2250 typename VectorizedArrayType>
2251 std::shared_ptr<Table<2, VectorizedArrayType>>
2257 VectorizedArrayType>::get_coefficient()
2260 return scalar_coefficient;
2269 typename VectorType,
2270 typename VectorizedArrayType>
2277 VectorizedArrayType>::compute_diagonal()
2284 this->inverse_diagonal_entries =
2285 std::make_shared<DiagonalMatrix<VectorType>>();
2286 this->diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
2287 VectorType &inverse_diagonal_vector =
2288 this->inverse_diagonal_entries->get_vector();
2289 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
2290 this->initialize_dof_vector(inverse_diagonal_vector);
2291 this->initialize_dof_vector(diagonal_vector);
2297 this->set_constrained_entries_to_one(diagonal_vector);
2299 inverse_diagonal_vector = diagonal_vector;
2301 for (
unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size();
2303 if (
std::abs(inverse_diagonal_vector.local_element(i)) >
2304 std::sqrt(std::numeric_limits<Number>::epsilon()))
2305 inverse_diagonal_vector.local_element(i) =
2306 1. / inverse_diagonal_vector.local_element(i);
2308 inverse_diagonal_vector.local_element(i) = 1.;
2319 typename VectorType,
2320 typename VectorizedArrayType>
2327 VectorizedArrayType>::apply_add(VectorType &dst,
2328 const VectorType &src)
const
2334 namespace Implementation
2336 template <
typename VectorizedArrayType>
2340 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2354 typename VectorType,
2355 typename VectorizedArrayType>
2356 template <
int n_components_compute>
2358 LaplaceOperator<dim,
2363 VectorizedArrayType>::
2364 do_operation_on_cell(
2369 n_components_compute,
2371 VectorizedArrayType> &phi,
2372 const unsigned int cell)
const
2375 if (scalar_coefficient.get())
2377 Assert(scalar_coefficient->size(1) == 1 ||
2378 scalar_coefficient->size(1) == phi.n_q_points,
2379 ExcMessage(
"The number of columns in the coefficient table must "
2380 "be either 1 or the number of quadrature points " +
2381 std::to_string(phi.n_q_points) +
2382 ", but the given value was " +
2383 std::to_string(scalar_coefficient->size(1))));
2384 if (scalar_coefficient->size(1) == phi.n_q_points)
2385 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2388 (*scalar_coefficient)(cell, q)),
2389 ExcMessage(
"Coefficient must be non-negative"));
2390 phi.submit_gradient((*scalar_coefficient)(cell, q) *
2391 phi.get_gradient(q),
2397 ExcMessage(
"Coefficient must be non-negative"));
2398 const VectorizedArrayType coefficient =
2399 (*scalar_coefficient)(cell, 0);
2400 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2401 phi.submit_gradient(coefficient * phi.get_gradient(q), q);
2406 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2408 phi.submit_gradient(phi.get_gradient(q), q);
2420 typename VectorType,
2421 typename VectorizedArrayType>
2428 VectorizedArrayType>::
2433 VectorizedArrayType> &
data,
2435 const VectorType &src,
2436 const std::pair<unsigned int, unsigned int> &cell_range)
const
2445 VectorizedArrayType>
2446 phi(
data, this->selected_rows[0]);
2447 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2450 phi.read_dof_values(src);
2451 do_operation_on_cell(phi, cell);
2452 phi.distribute_local_to_global(dst);
2461 typename VectorType,
2462 typename VectorizedArrayType>
2469 VectorizedArrayType>::
2470 local_diagonal_cell(
2474 VectorizedArrayType> &
data,
2477 const std::pair<unsigned int, unsigned int> &cell_range)
const
2483 eval(
data, this->selected_rows[0]);
2489 VectorizedArrayType>
2490 eval_vector(
data, this->selected_rows[0]);
2491 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2494 eval_vector.reinit(cell);
2506 do_operation_on_cell(eval, cell);
2511 for (
unsigned int c = 0; c < n_components; ++c)
2513 .begin_dof_values()[i + c * eval_vector.dofs_per_component] =
2516 eval_vector.distribute_local_to_global(dst);
***mech_lbc_system increment_interpolation_handlers push_back(scale_z_handler)
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
const Number * begin_dof_values() const
void reinit(const unsigned int cell_batch_index)
const unsigned int dofs_per_cell
size_type index_within_set(const size_type global_index) const
bool is_element(const size_type index) const
virtual ~Base() override=default
std::vector< unsigned int > selected_rows
void Tvmult_add(VectorType &dst, const VectorType &src) const
void set_constrained_entries_to_one(VectorType &dst) const
virtual void compute_diagonal()=0
void vmult_add(VectorType &dst, const VectorType &src) const
void vmult_interface_down(VectorType &dst, const VectorType &src) const
void preprocess_constraints(VectorType &dst, const VectorType &src) const
void mult_add(VectorType &dst, const VectorType &src, const bool transpose) const
std::vector< std::vector< unsigned int > > edge_constrained_indices
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal() const
void Tvmult(VectorType &dst, const VectorType &src) const
std::vector< std::vector< std::pair< value_type, value_type > > > edge_constrained_values
void initialize(std::shared_ptr< const MatrixFree< dim, value_type, VectorizedArrayType > > 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 >())
bool have_interface_matrices
std::vector< unsigned int > selected_columns
std::shared_ptr< const MatrixFree< dim, value_type, VectorizedArrayType > > get_matrix_free() const
void initialize(std::shared_ptr< const MatrixFree< dim, value_type, VectorizedArrayType > > data_, const std::vector< MGConstrainedDoFs > &mg_constrained_dofs, const unsigned int level, const std::vector< unsigned int > &selected_row_blocks=std::vector< unsigned int >())
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal_inverse() const
void initialize(std::shared_ptr< const MatrixFree< dim, value_type, VectorizedArrayType > > data, const MGConstrainedDoFs &mg_constrained_dofs, const unsigned int level, const std::vector< unsigned int > &selected_row_blocks=std::vector< unsigned int >())
void initialize_dof_vector(VectorType &vec) const
std::shared_ptr< DiagonalMatrix< VectorType > > diagonal_entries
virtual void Tapply_add(VectorType &dst, const VectorType &src) const
std::shared_ptr< const MatrixFree< dim, value_type, VectorizedArrayType > > data
void adjust_ghost_range_if_necessary(const VectorType &vec, const bool is_row) const
virtual std::size_t memory_consumption() const
std::shared_ptr< DiagonalMatrix< VectorType > > inverse_diagonal_entries
value_type el(const unsigned int row, const unsigned int col) const
virtual void apply_add(VectorType &dst, const VectorType &src) const =0
typename VectorType::size_type size_type
void precondition_Jacobi(VectorType &dst, const VectorType &src, const value_type omega) const
typename VectorType::value_type value_type
void vmult(VectorType &dst, const VectorType &src) const
void vmult_interface_up(VectorType &dst, const VectorType &src) const
void postprocess_constraints(VectorType &dst, const VectorType &src) const
const FEEvaluationBase< dim, n_components, Number, false, VectorizedArrayType > & fe_eval
void fill_inverse_JxW_values(AlignedVector< VectorizedArrayType > &inverse_jxw) const
void transform_from_q_points_to_basis(const unsigned int n_actual_components, const VectorizedArrayType *in_array, VectorizedArrayType *out_array) const
void apply(const AlignedVector< VectorizedArrayType > &inverse_coefficient, const unsigned int n_actual_components, const VectorizedArrayType *in_array, VectorizedArrayType *out_array) const
std::shared_ptr< Table< 2, VectorizedArrayType > > get_coefficient()
typename Base< dim, VectorType, VectorizedArrayType >::value_type value_type
virtual void compute_diagonal() override
std::shared_ptr< Table< 2, VectorizedArrayType > > scalar_coefficient
void local_diagonal_cell(const MatrixFree< dim, value_type, VectorizedArrayType > &data, VectorType &dst, const VectorType &, const std::pair< unsigned int, unsigned int > &cell_range) const
void local_apply_cell(const MatrixFree< dim, value_type, VectorizedArrayType > &data, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
virtual void apply_add(VectorType &dst, const VectorType &src) const override
typename Base< dim, VectorType, VectorizedArrayType >::size_type size_type
void set_coefficient(const std::shared_ptr< Table< 2, VectorizedArrayType > > &scalar_coefficient)
void do_operation_on_cell(FEEvaluation< dim, fe_degree, n_q_points_1d, n_components_compute, value_type, VectorizedArrayType > &phi, const unsigned int cell) const
virtual void clear() override
typename OperatorType::value_type value_type
void vmult(VectorType &dst, const VectorType &src) const
ObserverPointer< const OperatorType > mf_base_operator
void initialize(const OperatorType &operator_in)
void Tvmult(VectorType &dst, const VectorType &src) const
void initialize_dof_vector(VectorType &vec) const
typename OperatorType::size_type size_type
void compute_lumped_diagonal()
std::shared_ptr< DiagonalMatrix< VectorType > > lumped_diagonal_entries
typename Base< dim, VectorType, VectorizedArrayType >::size_type size_type
virtual void apply_add(VectorType &dst, const VectorType &src) const override
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_lumped_diagonal() const
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_lumped_diagonal_inverse() const
void local_apply_cell(const MatrixFree< dim, value_type, VectorizedArrayType > &data, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
virtual void compute_diagonal() override
typename Base< dim, VectorType, VectorizedArrayType >::value_type value_type
std::shared_ptr< DiagonalMatrix< VectorType > > inverse_lumped_diagonal_entries
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::vector< index_type > data
types::global_dof_index locally_owned_size
std::enable_if_t< IsBlockVector< VectorType >::value, typename VectorType::BlockType & > subblock(VectorType &vector, unsigned int block_no)
std::enable_if_t< IsBlockVector< VectorType >::value, void > collect_sizes(VectorType &vector)
std::enable_if_t< IsBlockVector< VectorType >::value, unsigned int > n_blocks(const VectorType &vector)
bool non_negative(const VectorizedArrayType &n)
T max(const T &t, const MPI_Comm mpi_communicator)
constexpr T pow(const T base, const int iexp)
constexpr unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
static void apply(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, const Number *in_array, Number *out_array)
static void transform_from_q_points_to_basis(const unsigned int n_components, const FEEvaluationData< dim, Number, false > &fe_eval, const Number *in_array, Number *out_array)