17#ifndef dealii_matrix_free_operators_h
18#define dealii_matrix_free_operators_h
48 template <
typename VectorType>
49 std::enable_if_t<IsBlockVector<VectorType>::value,
unsigned int>
52 return vector.n_blocks();
55 template <
typename VectorType>
56 std::enable_if_t<!IsBlockVector<VectorType>::value,
unsigned int>
62 template <
typename VectorType>
63 std::enable_if_t<IsBlockVector<VectorType>::value,
64 typename VectorType::BlockType &>
65 subblock(VectorType &vector,
unsigned int block_no)
68 return vector.block(block_no);
71 template <
typename VectorType>
72 std::enable_if_t<IsBlockVector<VectorType>::value,
73 const typename VectorType::BlockType &>
74 subblock(
const VectorType &vector,
unsigned int block_no)
77 return vector.block(block_no);
80 template <
typename VectorType>
81 std::enable_if_t<!IsBlockVector<VectorType>::value, VectorType &>
87 template <
typename VectorType>
88 std::enable_if_t<!IsBlockVector<VectorType>::value,
const VectorType &>
89 subblock(
const VectorType &vector,
unsigned int)
94 template <
typename VectorType>
95 std::enable_if_t<IsBlockVector<VectorType>::value,
void>
98 vector.collect_sizes();
101 template <
typename VectorType>
102 std::enable_if_t<!IsBlockVector<VectorType>::value,
void>
186 typename VectorizedArrayType =
237 const std::vector<unsigned int> &selected_row_blocks =
238 std::vector<unsigned int>(),
239 const std::vector<unsigned int> &selected_column_blocks =
240 std::vector<unsigned int>());
259 const unsigned int level,
260 const std::vector<unsigned int> &selected_row_blocks =
261 std::vector<unsigned int>());
280 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
281 const unsigned int level,
282 const std::vector<unsigned int> & selected_row_blocks =
283 std::vector<unsigned int>());
313 vmult(VectorType &dst,
const VectorType &src)
const;
319 Tvmult(VectorType &dst,
const VectorType &src)
const;
325 vmult_add(VectorType &dst,
const VectorType &src)
const;
338 el(
const unsigned int row,
const unsigned int col)
const;
371 std::shared_ptr<const MatrixFree<dim, value_type, VectorizedArrayType>>
377 const std::shared_ptr<DiagonalMatrix<VectorType>> &
383 const std::shared_ptr<DiagonalMatrix<VectorType>> &
393 const VectorType &src,
422 apply_add(VectorType &dst,
const VectorType &src)
const = 0;
435 std::shared_ptr<const MatrixFree<dim, value_type, VectorizedArrayType>>
471 mutable std::vector<std::vector<std::pair<value_type, value_type>>>
486 const VectorType &src,
498 const bool is_row)
const;
537 template <
typename OperatorType>
571 template <
typename VectorType>
573 vmult(VectorType &dst,
const VectorType &src)
const;
578 template <
typename VectorType>
580 Tvmult(VectorType &dst,
const VectorType &src)
const;
585 template <
typename VectorType>
619 int n_components = 1,
620 typename Number = double,
625 std::is_same<Number, typename VectorizedArrayType::value_type>::value,
626 "Type of Number and of VectorizedArrayType do not match.");
638 VectorizedArrayType> &
fe_eval);
651 const unsigned int n_actual_components,
652 const VectorizedArrayType * in_array,
653 VectorizedArrayType * out_array)
const;
667 apply(
const VectorizedArrayType *in_array,
668 VectorizedArrayType * out_array)
const;
684 & inverse_dyadic_coefficients,
685 const VectorizedArrayType *in_array,
686 VectorizedArrayType * out_array)
const;
723 const VectorizedArrayType *in_array,
724 VectorizedArrayType *out_array)
const;
757 int n_q_points_1d = fe_degree + 1,
758 int n_components = 1,
760 typename VectorizedArrayType =
810 const std::shared_ptr<DiagonalMatrix<VectorType>> &
816 const std::shared_ptr<DiagonalMatrix<VectorType>> &
826 apply_add(VectorType &dst,
const VectorType &src)
const override;
835 const VectorType & src,
836 const std::pair<unsigned int, unsigned int> & cell_range)
const;
865 int n_q_points_1d = fe_degree + 1,
866 int n_components = 1,
868 typename VectorizedArrayType =
966 std::shared_ptr<Table<2, VectorizedArrayType>>
976 apply_add(VectorType &dst,
const VectorType &src)
const override;
985 const VectorType & src,
986 const std::pair<unsigned int, unsigned int> & cell_range)
const;
996 const std::pair<unsigned int, unsigned int> &cell_range)
const;
1001 template <
int n_components_compute>
1006 n_components_compute,
1008 VectorizedArrayType> &phi,
1009 const unsigned int cell)
const;
1025 typename VectorizedArrayType>
1030 VectorizedArrayType>::
1031 CellwiseInverseMassMatrix(
1036 VectorizedArrayType> &fe_eval)
1046 typename VectorizedArrayType>
1052 VectorizedArrayType>::
1053 fill_inverse_JxW_values(
1056 const unsigned int dofs_per_component_on_cell =
1059 Utilities::pow(fe_eval.get_shape_info().data.front().fe_degree + 1,
1063 inverse_jxw.
size() % dofs_per_component_on_cell == 0,
1065 "Expected diagonal to be a multiple of scalar dof per cells"));
1068 for (
unsigned int q = 0; q < dofs_per_component_on_cell; ++q)
1069 inverse_jxw[q] = 1. / fe_eval.JxW(q);
1071 for (
unsigned int q = dofs_per_component_on_cell; q < inverse_jxw.
size();)
1072 for (
unsigned int i = 0; i < dofs_per_component_on_cell; ++i, ++q)
1073 inverse_jxw[q] = inverse_jxw[i];
1082 typename VectorizedArrayType>
1089 VectorizedArrayType>::apply(
const VectorizedArrayType *in_array,
1090 VectorizedArrayType * out_array)
const
1094 template run<fe_degree>(n_components, fe_eval, in_array, out_array);
1097 n_components, fe_eval, in_array, out_array);
1106 typename VectorizedArrayType>
1112 VectorizedArrayType>::
1114 const unsigned int n_actual_components,
1115 const VectorizedArrayType * in_array,
1116 VectorizedArrayType * out_array)
const
1121 VectorizedArrayType>::template run<fe_degree>(n_actual_components,
1124 inverse_coefficients),
1130 n_actual_components,
1142 typename VectorizedArrayType>
1148 VectorizedArrayType>::
1150 & inverse_dyadic_coefficients,
1151 const VectorizedArrayType *in_array,
1152 VectorizedArrayType * out_array)
const
1154 const unsigned int unrolled_size =
1155 inverse_dyadic_coefficients.size() * (n_components * n_components);
1159 VectorizedArrayType>::
1160 template run<fe_degree>(n_components,
1163 &inverse_dyadic_coefficients[0][0][0],
1173 &inverse_dyadic_coefficients[0][0][0], unrolled_size),
1185 typename VectorizedArrayType>
1191 VectorizedArrayType>::
1192 transform_from_q_points_to_basis(
const unsigned int n_actual_components,
1193 const VectorizedArrayType *in_array,
1194 VectorizedArrayType * out_array)
const
1196 const auto n_q_points_1d = fe_eval.get_shape_info().data[0].n_q_points_1d;
1198 if (fe_degree > -1 && (fe_degree + 1 == n_q_points_1d))
1201 VectorizedArrayType>::template run<fe_degree,
1202 fe_degree + 1>(n_actual_components,
1217 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1220 , have_interface_matrices(false)
1225 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1232 for (
const unsigned int selected_row : selected_rows)
1233 total_size += data->get_vector_partitioner(selected_row)->size();
1239 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1246 for (
const unsigned int selected_column : selected_columns)
1247 total_size += data->get_vector_partitioner(selected_column)->size();
1253 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1258 inverse_diagonal_entries.reset();
1263 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1266 const unsigned int col)
const
1270 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1271 inverse_diagonal_entries->m() > 0,
1273 return 1.0 / (*inverse_diagonal_entries)(row, row);
1278 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1281 VectorType &vec)
const
1287 const unsigned int index = selected_rows[i];
1289 .partitioners_are_compatible(
1290 *data->get_dof_info(index).vector_partitioner))
1294 .partitioners_are_globally_compatible(
1295 *data->get_dof_info(index).vector_partitioner),
1303 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1308 const std::vector<unsigned int> &given_row_selection,
1309 const std::vector<unsigned int> &given_column_selection)
1313 selected_rows.clear();
1314 selected_columns.clear();
1315 if (given_row_selection.empty())
1316 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1317 selected_rows.push_back(i);
1320 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1323 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1325 Assert(given_row_selection[j] != given_row_selection[i],
1326 ExcMessage(
"Given row indices must be unique"));
1328 selected_rows.push_back(given_row_selection[i]);
1331 if (given_column_selection.size() == 0)
1332 selected_columns = selected_rows;
1335 for (
unsigned int i = 0; i < given_column_selection.size(); ++i)
1338 for (
unsigned int j = 0; j < given_column_selection.size(); ++j)
1340 Assert(given_column_selection[j] != given_column_selection[i],
1341 ExcMessage(
"Given column indices must be unique"));
1343 selected_columns.push_back(given_column_selection[i]);
1347 edge_constrained_indices.clear();
1348 edge_constrained_indices.resize(selected_rows.size());
1349 edge_constrained_values.clear();
1350 edge_constrained_values.resize(selected_rows.size());
1351 have_interface_matrices =
false;
1356 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1362 const unsigned int level,
1363 const std::vector<unsigned int> &given_row_selection)
1365 std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(
1366 1, mg_constrained_dofs);
1367 initialize(data_, mg_constrained_dofs_vector,
level, given_row_selection);
1372 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1377 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
1378 const unsigned int level,
1379 const std::vector<unsigned int> & given_row_selection)
1384 selected_rows.clear();
1385 selected_columns.clear();
1386 if (given_row_selection.empty())
1387 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1388 selected_rows.push_back(i);
1391 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1394 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1396 Assert(given_row_selection[j] != given_row_selection[i],
1397 ExcMessage(
"Given row indices must be unique"));
1399 selected_rows.push_back(given_row_selection[i]);
1402 selected_columns = selected_rows;
1405 edge_constrained_indices.clear();
1406 edge_constrained_indices.resize(selected_rows.size());
1407 edge_constrained_values.clear();
1408 edge_constrained_values.resize(selected_rows.size());
1412 for (
unsigned int j = 0; j < selected_rows.size(); ++j)
1414 if (data_->n_cell_batches() > 0)
1420 const std::vector<types::global_dof_index> interface_indices =
1421 mg_constrained_dofs[j]
1422 .get_refinement_edge_indices(
level)
1423 .get_index_vector();
1424 edge_constrained_indices[j].clear();
1425 edge_constrained_indices[j].reserve(interface_indices.size());
1426 edge_constrained_values[j].resize(interface_indices.size());
1428 data->get_dof_handler(selected_rows[j]).locally_owned_mg_dofs(
level);
1429 for (
const auto interface_index : interface_indices)
1430 if (locally_owned.
is_element(interface_index))
1431 edge_constrained_indices[j].push_back(
1433 have_interface_matrices |=
1435 static_cast<unsigned int>(edge_constrained_indices[j].size()),
1436 data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1442 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1445 VectorType &dst)
const
1449 const std::vector<unsigned int> &constrained_dofs =
1450 data->get_constrained_dofs(selected_rows[j]);
1451 for (
const auto constrained_dof : constrained_dofs)
1453 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1455 edge_constrained_indices[j][i]) = 1.;
1461 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1464 const VectorType &src)
const
1469 vmult_add(dst, src);
1474 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1478 const VectorType &src)
const
1480 mult_add(dst, src,
false);
1485 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1489 const VectorType &src)
const
1491 mult_add(dst, src,
true);
1496 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1499 const VectorType &src,
1500 const bool is_row)
const
1506 const unsigned int mf_component =
1507 is_row ? selected_rows[i] : selected_columns[i];
1510 data->get_dof_info(mf_component).vector_partitioner.get())
1517 ->locally_owned_size() ==
1518 data->get_dof_info(mf_component)
1519 .vector_partitioner->locally_owned_size(),
1521 "The vector passed to the vmult() function does not have "
1522 "the correct size for compatibility with MatrixFree."));
1528 this->data->initialize_dof_vector(
1532 .copy_locally_owned_data_from(copy_vec);
1538 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1542 const VectorType &src)
const
1546 adjust_ghost_range_if_necessary(src,
false);
1547 adjust_ghost_range_if_necessary(dst,
true);
1553 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1555 edge_constrained_values[j][i] = std::pair<Number, Number>(
1557 edge_constrained_indices[j][i]),
1559 edge_constrained_indices[j][i]));
1561 .local_element(edge_constrained_indices[j][i]) = 0.;
1568 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1572 const VectorType &src,
1578 preprocess_constraints(dst, src);
1580 Tapply_add(dst, src);
1582 apply_add(dst, src);
1583 postprocess_constraints(dst, src);
1588 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1592 const VectorType &src)
const
1596 const std::vector<unsigned int> &constrained_dofs =
1597 data->get_constrained_dofs(selected_rows[j]);
1598 for (
const auto constrained_dof : constrained_dofs)
1607 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1610 .local_element(edge_constrained_indices[j][i]) =
1611 edge_constrained_values[j][i].first;
1613 edge_constrained_indices[j][i]) =
1614 edge_constrained_values[j][i].second +
1615 edge_constrained_values[j][i].first;
1622 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1626 const VectorType &src)
const
1631 adjust_ghost_range_if_necessary(src,
false);
1632 adjust_ghost_range_if_necessary(dst,
true);
1636 if (!have_interface_matrices)
1642 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1644 edge_constrained_values[j][i] = std::pair<Number, Number>(
1646 edge_constrained_indices[j][i]),
1648 edge_constrained_indices[j][i]));
1650 .local_element(edge_constrained_indices[j][i]) = 0.;
1653 apply_add(dst, src);
1658 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1660 for (; c < edge_constrained_indices[j][i]; ++c)
1666 .local_element(edge_constrained_indices[j][i]) =
1667 edge_constrained_values[j][i].first;
1676 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1680 const VectorType &src)
const
1685 adjust_ghost_range_if_necessary(src,
false);
1686 adjust_ghost_range_if_necessary(dst,
true);
1690 if (!have_interface_matrices)
1693 VectorType src_cpy(src);
1697 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1699 for (; c < edge_constrained_indices[j][i]; ++c)
1707 apply_add(dst, src_cpy);
1710 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1712 edge_constrained_indices[j][i]) = 0.;
1717 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1721 const VectorType &src)
const
1726 Tvmult_add(dst, src);
1731 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1735 return inverse_diagonal_entries.get() !=
nullptr ?
1736 inverse_diagonal_entries->memory_consumption() :
1742 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1746 VectorizedArrayType>>
1754 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1755 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1759 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1760 inverse_diagonal_entries->m() > 0,
1762 return inverse_diagonal_entries;
1767 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1768 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1771 Assert(diagonal_entries.get() !=
nullptr && diagonal_entries->m() > 0,
1773 return diagonal_entries;
1778 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1782 const VectorType &src)
const
1784 apply_add(dst, src);
1789 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1793 const VectorType & src,
1797 Assert(inverse_diagonal_entries.get() && inverse_diagonal_entries->m() > 0,
1799 inverse_diagonal_entries->vmult(dst, src);
1807 template <
typename OperatorType>
1810 , mf_base_operator(nullptr)
1815 template <
typename OperatorType>
1819 mf_base_operator =
nullptr;
1824 template <
typename OperatorType>
1828 mf_base_operator = &operator_in;
1833 template <
typename OperatorType>
1834 template <
typename VectorType>
1837 const VectorType &src)
const
1841 std::is_same<typename VectorType::value_type, value_type>::value,
1842 "The vector type must be based on the same value type as this "
1848 mf_base_operator->vmult_interface_down(dst, src);
1853 template <
typename OperatorType>
1854 template <
typename VectorType>
1857 const VectorType &src)
const
1861 std::is_same<typename VectorType::value_type, value_type>::value,
1862 "The vector type must be based on the same value type as this "
1868 mf_base_operator->vmult_interface_up(dst, src);
1873 template <
typename OperatorType>
1874 template <
typename VectorType>
1877 VectorType &vec)
const
1881 mf_base_operator->initialize_dof_vector(vec);
1892 typename VectorType,
1893 typename VectorizedArrayType>
1899 VectorizedArrayType>::MassOperator()
1900 :
Base<dim, VectorType, VectorizedArrayType>()
1905 "This class only supports the non-blocked vector variant of the Base "
1906 "operator because only a single FEEvaluation object is used in the "
1907 "apply function."));
1916 typename VectorType,
1917 typename VectorizedArrayType>
1924 VectorizedArrayType>::compute_diagonal()
1928 Assert(this->selected_rows == this->selected_columns,
1929 ExcMessage(
"This function is only implemented for square (not "
1930 "rectangular) operators."));
1932 this->inverse_diagonal_entries =
1933 std::make_shared<DiagonalMatrix<VectorType>>();
1934 this->diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
1935 VectorType &inverse_diagonal_vector =
1936 this->inverse_diagonal_entries->get_vector();
1937 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1938 this->initialize_dof_vector(inverse_diagonal_vector);
1939 this->initialize_dof_vector(diagonal_vector);
1943 auto diagonal_evaluation = [](
auto &integrator) {
1945 for (
unsigned int q = 0; q < integrator.n_q_points; ++q)
1946 integrator.submit_value(integrator.get_value(q), q);
1957 VectorizedArrayType> &)>
1958 diagonal_evaluation_f(diagonal_evaluation);
1961 for (
unsigned int block_n = 0; block_n < this->selected_rows.size();
1966 diagonal_evaluation_f,
1967 this->selected_rows[block_n]);
1971 this->set_constrained_entries_to_one(diagonal_vector);
1973 inverse_diagonal_vector = diagonal_vector;
1975 for (
unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size();
1982 Assert(diagonal_vector.local_element(i) > Number(0),
1985 inverse_diagonal_vector.local_element(i) =
1986 1. / inverse_diagonal_vector.local_element(i);
1998 typename VectorType,
1999 typename VectorizedArrayType>
2006 VectorizedArrayType>::compute_lumped_diagonal()
2012 Assert(this->selected_rows == this->selected_columns,
2013 ExcMessage(
"This function is only implemented for square (not "
2014 "rectangular) operators."));
2016 inverse_lumped_diagonal_entries =
2017 std::make_shared<DiagonalMatrix<VectorType>>();
2018 lumped_diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
2019 VectorType &inverse_lumped_diagonal_vector =
2020 inverse_lumped_diagonal_entries->get_vector();
2021 VectorType &lumped_diagonal_vector = lumped_diagonal_entries->get_vector();
2022 this->initialize_dof_vector(inverse_lumped_diagonal_vector);
2023 this->initialize_dof_vector(lumped_diagonal_vector);
2026 inverse_lumped_diagonal_vector = Number(1.);
2027 apply_add(lumped_diagonal_vector, inverse_lumped_diagonal_vector);
2028 this->set_constrained_entries_to_one(lumped_diagonal_vector);
2031 inverse_lumped_diagonal_vector.locally_owned_size();
2036 for (
size_type i = 0; i < locally_owned_size; ++i)
2038 if (lumped_diagonal_vector.local_element(i) == Number(0.))
2039 inverse_lumped_diagonal_vector.local_element(i) = Number(1.);
2041 inverse_lumped_diagonal_vector.local_element(i) =
2042 Number(1.) / lumped_diagonal_vector.local_element(i);
2045 inverse_lumped_diagonal_vector.update_ghost_values();
2046 lumped_diagonal_vector.update_ghost_values();
2055 typename VectorType,
2056 typename VectorizedArrayType>
2057 const std::shared_ptr<DiagonalMatrix<VectorType>> &
2063 VectorizedArrayType>::get_matrix_lumped_diagonal_inverse()
const
2065 Assert(inverse_lumped_diagonal_entries.get() !=
nullptr &&
2066 inverse_lumped_diagonal_entries->m() > 0,
2068 return inverse_lumped_diagonal_entries;
2077 typename VectorType,
2078 typename VectorizedArrayType>
2079 const std::shared_ptr<DiagonalMatrix<VectorType>> &
2085 VectorizedArrayType>::get_matrix_lumped_diagonal()
const
2087 Assert(lumped_diagonal_entries.get() !=
nullptr &&
2088 lumped_diagonal_entries->m() > 0,
2090 return lumped_diagonal_entries;
2099 typename VectorType,
2100 typename VectorizedArrayType>
2107 VectorizedArrayType>::apply_add(VectorType & dst,
2108 const VectorType &src)
const
2120 typename VectorType,
2121 typename VectorizedArrayType>
2128 VectorizedArrayType>::
2133 VectorizedArrayType> & data,
2135 const VectorType & src,
2136 const std::pair<unsigned int, unsigned int> &cell_range)
const
2145 VectorizedArrayType>
2146 phi(data, this->selected_rows[0]);
2147 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2150 phi.read_dof_values(src);
2152 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2153 phi.submit_value(phi.get_value(q), q);
2155 phi.distribute_local_to_global(dst);
2166 typename VectorType,
2167 typename VectorizedArrayType>
2173 VectorizedArrayType>::LaplaceOperator()
2174 :
Base<dim, VectorType, VectorizedArrayType>()
2183 typename VectorType,
2184 typename VectorizedArrayType>
2191 VectorizedArrayType>::clear()
2194 scalar_coefficient.reset();
2203 typename VectorType,
2204 typename VectorizedArrayType>
2211 VectorizedArrayType>::
2215 scalar_coefficient = scalar_coefficient_;
2224 typename VectorType,
2225 typename VectorizedArrayType>
2226 std::shared_ptr<Table<2, VectorizedArrayType>>
2232 VectorizedArrayType>::get_coefficient()
2235 return scalar_coefficient;
2244 typename VectorType,
2245 typename VectorizedArrayType>
2252 VectorizedArrayType>::compute_diagonal()
2259 this->inverse_diagonal_entries =
2260 std::make_shared<DiagonalMatrix<VectorType>>();
2261 this->diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
2262 VectorType &inverse_diagonal_vector =
2263 this->inverse_diagonal_entries->get_vector();
2264 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
2265 this->initialize_dof_vector(inverse_diagonal_vector);
2266 this->initialize_dof_vector(diagonal_vector);
2272 this->set_constrained_entries_to_one(diagonal_vector);
2274 inverse_diagonal_vector = diagonal_vector;
2276 for (
unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size();
2278 if (
std::abs(inverse_diagonal_vector.local_element(i)) >
2279 std::sqrt(std::numeric_limits<Number>::epsilon()))
2280 inverse_diagonal_vector.local_element(i) =
2281 1. / inverse_diagonal_vector.local_element(i);
2283 inverse_diagonal_vector.local_element(i) = 1.;
2294 typename VectorType,
2295 typename VectorizedArrayType>
2302 VectorizedArrayType>::apply_add(VectorType & dst,
2303 const VectorType &src)
const
2309 namespace Implementation
2311 template <
typename VectorizedArrayType>
2315 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2329 typename VectorType,
2330 typename VectorizedArrayType>
2331 template <
int n_components_compute>
2333 LaplaceOperator<dim,
2338 VectorizedArrayType>::
2339 do_operation_on_cell(
2344 n_components_compute,
2346 VectorizedArrayType> &phi,
2347 const unsigned int cell)
const
2350 if (scalar_coefficient.get())
2352 Assert(scalar_coefficient->size(1) == 1 ||
2353 scalar_coefficient->size(1) == phi.n_q_points,
2354 ExcMessage(
"The number of columns in the coefficient table must "
2355 "be either 1 or the number of quadrature points " +
2356 std::to_string(phi.n_q_points) +
2357 ", but the given value was " +
2358 std::to_string(scalar_coefficient->size(1))));
2359 if (scalar_coefficient->size(1) == phi.n_q_points)
2360 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2363 (*scalar_coefficient)(cell, q)),
2364 ExcMessage(
"Coefficient must be non-negative"));
2365 phi.submit_gradient((*scalar_coefficient)(cell, q) *
2366 phi.get_gradient(q),
2372 ExcMessage(
"Coefficient must be non-negative"));
2373 const VectorizedArrayType coefficient =
2374 (*scalar_coefficient)(cell, 0);
2375 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2376 phi.submit_gradient(coefficient * phi.get_gradient(q), q);
2381 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2383 phi.submit_gradient(phi.get_gradient(q), q);
2395 typename VectorType,
2396 typename VectorizedArrayType>
2403 VectorizedArrayType>::
2408 VectorizedArrayType> & data,
2410 const VectorType & src,
2411 const std::pair<unsigned int, unsigned int> &cell_range)
const
2420 VectorizedArrayType>
2421 phi(data, this->selected_rows[0]);
2422 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2425 phi.read_dof_values(src);
2426 do_operation_on_cell(phi, cell);
2427 phi.distribute_local_to_global(dst);
2436 typename VectorType,
2437 typename VectorizedArrayType>
2444 VectorizedArrayType>::
2445 local_diagonal_cell(
2449 VectorizedArrayType> &data,
2452 const std::pair<unsigned int, unsigned int> &cell_range)
const
2458 eval(data, this->selected_rows[0]);
2464 VectorizedArrayType>
2465 eval_vector(data, this->selected_rows[0]);
2466 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2469 eval_vector.reinit(cell);
2481 do_operation_on_cell(eval, cell);
2486 for (
unsigned int c = 0; c < n_components; ++c)
2488 .begin_dof_values()[i + c * eval_vector.dofs_per_component] =
2491 eval_vector.distribute_local_to_global(dst);
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, 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
SmartPointer< const OperatorType > mf_base_operator
void vmult(VectorType &dst, const VectorType &src) const
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
#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::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)
static const 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)