17#ifndef dealii_matrix_free_operators_h
18#define dealii_matrix_free_operators_h
47 template <
typename VectorType>
48 typename std::enable_if<IsBlockVector<VectorType>::value,
52 return vector.n_blocks();
55 template <
typename VectorType>
56 typename std::enable_if<!IsBlockVector<VectorType>::value,
63 template <
typename VectorType>
64 typename std::enable_if<IsBlockVector<VectorType>::value,
65 typename VectorType::BlockType &>::type
66 subblock(VectorType &vector,
unsigned int block_no)
68 return vector.block(block_no);
71 template <
typename VectorType>
72 typename std::enable_if<IsBlockVector<VectorType>::value,
73 const typename VectorType::BlockType &>::type
74 subblock(
const VectorType &vector,
unsigned int block_no)
77 return vector.block(block_no);
80 template <
typename VectorType>
81 typename std::enable_if<!IsBlockVector<VectorType>::value,
88 template <
typename VectorType>
89 typename std::enable_if<!IsBlockVector<VectorType>::value,
90 const VectorType &>::type
91 subblock(
const VectorType &vector,
unsigned int)
96 template <
typename VectorType>
97 typename std::enable_if<IsBlockVector<VectorType>::value,
void>::type
100 vector.collect_sizes();
103 template <
typename VectorType>
104 typename std::enable_if<!IsBlockVector<VectorType>::value,
void>::type
188 typename VectorizedArrayType =
239 const std::vector<unsigned int> &selected_row_blocks =
240 std::vector<unsigned int>(),
241 const std::vector<unsigned int> &selected_column_blocks =
242 std::vector<unsigned int>());
261 const unsigned int level,
262 const std::vector<unsigned int> &selected_row_blocks =
263 std::vector<unsigned int>());
282 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
283 const unsigned int level,
284 const std::vector<unsigned int> & selected_row_blocks =
285 std::vector<unsigned int>());
315 vmult(VectorType &dst,
const VectorType &src)
const;
321 Tvmult(VectorType &dst,
const VectorType &src)
const;
327 vmult_add(VectorType &dst,
const VectorType &src)
const;
340 el(
const unsigned int row,
const unsigned int col)
const;
373 std::shared_ptr<const MatrixFree<dim, value_type, VectorizedArrayType>>
379 const std::shared_ptr<DiagonalMatrix<VectorType>> &
385 const std::shared_ptr<DiagonalMatrix<VectorType>> &
395 const VectorType &src,
424 apply_add(VectorType &dst,
const VectorType &src)
const = 0;
437 std::shared_ptr<const MatrixFree<dim, value_type, VectorizedArrayType>>
473 mutable std::vector<std::vector<std::pair<value_type, value_type>>>
488 const VectorType &src,
500 const bool is_row)
const;
539 template <
typename OperatorType>
573 template <
typename VectorType>
575 vmult(VectorType &dst,
const VectorType &src)
const;
580 template <
typename VectorType>
582 Tvmult(VectorType &dst,
const VectorType &src)
const;
587 template <
typename VectorType>
620 int n_components = 1,
621 typename Number = double,
626 std::is_same<Number, typename VectorizedArrayType::value_type>::value,
627 "Type of Number and of VectorizedArrayType do not match.");
639 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;
705 const VectorizedArrayType *in_array,
706 VectorizedArrayType *out_array)
const;
739 int n_q_points_1d = fe_degree + 1,
740 int n_components = 1,
742 typename VectorizedArrayType =
791 const std::shared_ptr<DiagonalMatrix<VectorType>> &
797 const std::shared_ptr<DiagonalMatrix<VectorType>> &
807 apply_add(VectorType &dst,
const VectorType &src)
const override;
816 const VectorType & src,
817 const std::pair<unsigned int, unsigned int> & cell_range)
const;
846 int n_q_points_1d = fe_degree + 1,
847 int n_components = 1,
849 typename VectorizedArrayType =
947 std::shared_ptr<Table<2, VectorizedArrayType>>
957 apply_add(VectorType &dst,
const VectorType &src)
const override;
966 const VectorType & src,
967 const std::pair<unsigned int, unsigned int> & cell_range)
const;
977 const std::pair<unsigned int, unsigned int> &cell_range)
const;
986 const unsigned int cell)
const;
1002 typename VectorizedArrayType>
1007 VectorizedArrayType>::
1008 CellwiseInverseMassMatrix(
1013 VectorizedArrayType> &fe_eval)
1023 typename VectorizedArrayType>
1029 VectorizedArrayType>::
1030 fill_inverse_JxW_values(
1033 constexpr unsigned int dofs_per_component_on_cell =
1036 inverse_jxw.
size() % dofs_per_component_on_cell == 0,
1038 "Expected diagonal to be a multiple of scalar dof per cells"));
1041 for (
unsigned int q = 0; q < dofs_per_component_on_cell; ++q)
1042 inverse_jxw[q] = 1. / fe_eval.JxW(q);
1044 for (
unsigned int q = dofs_per_component_on_cell; q < inverse_jxw.
size();)
1045 for (
unsigned int i = 0; i < dofs_per_component_on_cell; ++i, ++q)
1046 inverse_jxw[q] = inverse_jxw[i];
1055 typename VectorizedArrayType>
1062 VectorizedArrayType>::apply(
const VectorizedArrayType *in_array,
1063 VectorizedArrayType * out_array)
const
1067 template run<fe_degree>(n_components, fe_eval, in_array, out_array);
1070 n_components, fe_eval, in_array, out_array);
1079 typename VectorizedArrayType>
1085 VectorizedArrayType>::
1087 const unsigned int n_actual_components,
1088 const VectorizedArrayType * in_array,
1089 VectorizedArrayType * out_array)
const
1091 const unsigned int given_degree =
1092 fe_eval.get_shape_info().data[0].fe_degree;
1095 VectorizedArrayType>::
1096 template run<fe_degree>(
1097 n_actual_components,
1098 fe_eval.get_shape_info().data.front().inverse_shape_values_eo,
1099 inverse_coefficients,
1104 n_actual_components,
1106 fe_eval.get_shape_info().data.front().inverse_shape_values_eo,
1107 inverse_coefficients,
1118 typename VectorizedArrayType>
1124 VectorizedArrayType>::
1125 transform_from_q_points_to_basis(
const unsigned int n_actual_components,
1126 const VectorizedArrayType *in_array,
1127 VectorizedArrayType * out_array)
const
1129 const auto n_q_points_1d = fe_eval.get_shape_info().data[0].n_q_points_1d;
1131 if (fe_degree > -1 && (fe_degree + 1 == n_q_points_1d))
1134 VectorizedArrayType>::template run<fe_degree,
1135 fe_degree + 1>(n_actual_components,
1150 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1153 , have_interface_matrices(false)
1158 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1165 for (
const unsigned int selected_row : selected_rows)
1166 total_size += data->get_vector_partitioner(selected_row)->size();
1172 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1179 for (
const unsigned int selected_column : selected_columns)
1180 total_size += data->get_vector_partitioner(selected_column)->size();
1186 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1191 inverse_diagonal_entries.reset();
1196 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1199 const unsigned int col)
const
1203 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1204 inverse_diagonal_entries->m() > 0,
1206 return 1.0 / (*inverse_diagonal_entries)(row, row);
1211 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1214 VectorType &vec)
const
1220 const unsigned int index = selected_rows[i];
1222 .partitioners_are_compatible(
1223 *data->get_dof_info(index).vector_partitioner))
1227 .partitioners_are_globally_compatible(
1228 *data->get_dof_info(index).vector_partitioner),
1236 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1241 const std::vector<unsigned int> &given_row_selection,
1242 const std::vector<unsigned int> &given_column_selection)
1246 selected_rows.clear();
1247 selected_columns.clear();
1248 if (given_row_selection.empty())
1249 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1250 selected_rows.push_back(i);
1253 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1256 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1258 Assert(given_row_selection[j] != given_row_selection[i],
1259 ExcMessage(
"Given row indices must be unique"));
1261 selected_rows.push_back(given_row_selection[i]);
1264 if (given_column_selection.size() == 0)
1265 selected_columns = selected_rows;
1268 for (
unsigned int i = 0; i < given_column_selection.size(); ++i)
1271 for (
unsigned int j = 0; j < given_column_selection.size(); ++j)
1273 Assert(given_column_selection[j] != given_column_selection[i],
1274 ExcMessage(
"Given column indices must be unique"));
1276 selected_columns.push_back(given_column_selection[i]);
1280 edge_constrained_indices.clear();
1281 edge_constrained_indices.resize(selected_rows.size());
1282 edge_constrained_values.clear();
1283 edge_constrained_values.resize(selected_rows.size());
1284 have_interface_matrices =
false;
1289 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1295 const unsigned int level,
1296 const std::vector<unsigned int> &given_row_selection)
1298 std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(
1299 1, mg_constrained_dofs);
1300 initialize(data_, mg_constrained_dofs_vector,
level, given_row_selection);
1305 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1310 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
1311 const unsigned int level,
1312 const std::vector<unsigned int> & given_row_selection)
1317 selected_rows.clear();
1318 selected_columns.clear();
1319 if (given_row_selection.empty())
1320 for (
unsigned int i = 0; i < data_->n_components(); ++i)
1321 selected_rows.push_back(i);
1324 for (
unsigned int i = 0; i < given_row_selection.size(); ++i)
1327 for (
unsigned int j = 0; j < given_row_selection.size(); ++j)
1329 Assert(given_row_selection[j] != given_row_selection[i],
1330 ExcMessage(
"Given row indices must be unique"));
1332 selected_rows.push_back(given_row_selection[i]);
1335 selected_columns = selected_rows;
1338 edge_constrained_indices.clear();
1339 edge_constrained_indices.resize(selected_rows.size());
1340 edge_constrained_values.clear();
1341 edge_constrained_values.resize(selected_rows.size());
1345 for (
unsigned int j = 0; j < selected_rows.size(); ++j)
1347 if (data_->n_cell_batches() > 0)
1353 std::vector<types::global_dof_index> interface_indices;
1354 mg_constrained_dofs[j]
1355 .get_refinement_edge_indices(
level)
1356 .fill_index_vector(interface_indices);
1357 edge_constrained_indices[j].clear();
1358 edge_constrained_indices[j].reserve(interface_indices.size());
1359 edge_constrained_values[j].resize(interface_indices.size());
1361 data->get_dof_handler(selected_rows[j]).locally_owned_mg_dofs(
level);
1362 for (
const auto interface_index : interface_indices)
1363 if (locally_owned.
is_element(interface_index))
1364 edge_constrained_indices[j].push_back(
1366 have_interface_matrices |=
1368 static_cast<unsigned int>(edge_constrained_indices[j].size()),
1369 data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1375 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1378 VectorType &dst)
const
1382 const std::vector<unsigned int> &constrained_dofs =
1383 data->get_constrained_dofs(selected_rows[j]);
1384 for (
const auto constrained_dof : constrained_dofs)
1386 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1388 edge_constrained_indices[j][i]) = 1.;
1394 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1397 const VectorType &src)
const
1402 vmult_add(dst, src);
1407 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1411 const VectorType &src)
const
1413 mult_add(dst, src,
false);
1418 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1422 const VectorType &src)
const
1424 mult_add(dst, src,
true);
1429 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1432 const VectorType &src,
1433 const bool is_row)
const
1439 const unsigned int mf_component =
1440 is_row ? selected_rows[i] : selected_columns[i];
1443 data->get_dof_info(mf_component).vector_partitioner.get())
1450 ->locally_owned_size() ==
1451 data->get_dof_info(mf_component)
1452 .vector_partitioner->locally_owned_size(),
1454 "The vector passed to the vmult() function does not have "
1455 "the correct size for compatibility with MatrixFree."));
1461 this->data->initialize_dof_vector(
1465 .copy_locally_owned_data_from(copy_vec);
1471 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1475 const VectorType &src)
const
1479 adjust_ghost_range_if_necessary(src,
false);
1480 adjust_ghost_range_if_necessary(dst,
true);
1486 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1488 edge_constrained_values[j][i] = std::pair<Number, Number>(
1490 edge_constrained_indices[j][i]),
1492 edge_constrained_indices[j][i]));
1494 .local_element(edge_constrained_indices[j][i]) = 0.;
1501 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1505 const VectorType &src,
1511 preprocess_constraints(dst, src);
1513 Tapply_add(dst, src);
1515 apply_add(dst, src);
1516 postprocess_constraints(dst, src);
1521 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1525 const VectorType &src)
const
1529 const std::vector<unsigned int> &constrained_dofs =
1530 data->get_constrained_dofs(selected_rows[j]);
1531 for (
const auto constrained_dof : constrained_dofs)
1540 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1543 .local_element(edge_constrained_indices[j][i]) =
1544 edge_constrained_values[j][i].first;
1546 edge_constrained_indices[j][i]) =
1547 edge_constrained_values[j][i].second +
1548 edge_constrained_values[j][i].first;
1555 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1559 const VectorType &src)
const
1564 adjust_ghost_range_if_necessary(src,
false);
1565 adjust_ghost_range_if_necessary(dst,
true);
1569 if (!have_interface_matrices)
1575 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1577 edge_constrained_values[j][i] = std::pair<Number, Number>(
1579 edge_constrained_indices[j][i]),
1581 edge_constrained_indices[j][i]));
1583 .local_element(edge_constrained_indices[j][i]) = 0.;
1586 apply_add(dst, src);
1591 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1593 for (; c < edge_constrained_indices[j][i]; ++c)
1599 .local_element(edge_constrained_indices[j][i]) =
1600 edge_constrained_values[j][i].first;
1609 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1613 const VectorType &src)
const
1618 adjust_ghost_range_if_necessary(src,
false);
1619 adjust_ghost_range_if_necessary(dst,
true);
1623 if (!have_interface_matrices)
1626 VectorType src_cpy(src);
1630 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1632 for (; c < edge_constrained_indices[j][i]; ++c)
1640 apply_add(dst, src_cpy);
1643 for (
unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1645 edge_constrained_indices[j][i]) = 0.;
1650 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1654 const VectorType &src)
const
1659 Tvmult_add(dst, src);
1664 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1668 return inverse_diagonal_entries.get() !=
nullptr ?
1669 inverse_diagonal_entries->memory_consumption() :
1675 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1679 VectorizedArrayType>>
1687 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1688 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1692 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1693 inverse_diagonal_entries->m() > 0,
1695 return inverse_diagonal_entries;
1700 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1701 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1704 Assert(diagonal_entries.get() !=
nullptr && diagonal_entries->m() > 0,
1706 return diagonal_entries;
1711 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1715 const VectorType &src)
const
1717 apply_add(dst, src);
1722 template <
int dim,
typename VectorType,
typename VectorizedArrayType>
1726 const VectorType & src,
1730 Assert(inverse_diagonal_entries.get() && inverse_diagonal_entries->m() > 0,
1732 inverse_diagonal_entries->vmult(dst, src);
1740 template <
typename OperatorType>
1743 , mf_base_operator(nullptr)
1748 template <
typename OperatorType>
1752 mf_base_operator =
nullptr;
1757 template <
typename OperatorType>
1761 mf_base_operator = &operator_in;
1766 template <
typename OperatorType>
1767 template <
typename VectorType>
1770 const VectorType &src)
const
1774 std::is_same<typename VectorType::value_type, value_type>::value,
1775 "The vector type must be based on the same value type as this "
1781 mf_base_operator->vmult_interface_down(dst, src);
1786 template <
typename OperatorType>
1787 template <
typename VectorType>
1790 const VectorType &src)
const
1794 std::is_same<typename VectorType::value_type, value_type>::value,
1795 "The vector type must be based on the same value type as this "
1801 mf_base_operator->vmult_interface_up(dst, src);
1806 template <
typename OperatorType>
1807 template <
typename VectorType>
1810 VectorType &vec)
const
1814 mf_base_operator->initialize_dof_vector(vec);
1825 typename VectorType,
1826 typename VectorizedArrayType>
1832 VectorizedArrayType>::MassOperator()
1833 :
Base<dim, VectorType, VectorizedArrayType>()
1842 typename VectorType,
1843 typename VectorizedArrayType>
1850 VectorizedArrayType>::compute_diagonal()
1856 Assert(this->selected_rows == this->selected_columns,
1857 ExcMessage(
"This function is only implemented for square (not "
1858 "rectangular) operators."));
1860 this->inverse_diagonal_entries =
1861 std::make_shared<DiagonalMatrix<VectorType>>();
1862 this->diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
1863 VectorType &inverse_diagonal_vector =
1864 this->inverse_diagonal_entries->get_vector();
1865 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1866 this->initialize_dof_vector(inverse_diagonal_vector);
1867 this->initialize_dof_vector(diagonal_vector);
1871 auto diagonal_evaluation = [](
auto &integrator) {
1873 for (
unsigned int q = 0; q < integrator.n_q_points; ++q)
1874 integrator.submit_value(integrator.get_value(q), q);
1885 VectorizedArrayType> &)>
1886 diagonal_evaluation_f(diagonal_evaluation);
1889 for (
unsigned int block_n = 0; block_n < this->selected_rows.size();
1894 diagonal_evaluation_f,
1895 this->selected_rows[block_n]);
1899 this->set_constrained_entries_to_one(diagonal_vector);
1901 inverse_diagonal_vector = diagonal_vector;
1903 for (
unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size();
1906 Assert(diagonal_vector.local_element(i) > Number(0),
1908 inverse_diagonal_vector.local_element(i) =
1909 1. / inverse_diagonal_vector.local_element(i);
1921 typename VectorType,
1922 typename VectorizedArrayType>
1929 VectorizedArrayType>::compute_lumped_diagonal()
1935 Assert(this->selected_rows == this->selected_columns,
1936 ExcMessage(
"This function is only implemented for square (not "
1937 "rectangular) operators."));
1939 inverse_lumped_diagonal_entries =
1940 std::make_shared<DiagonalMatrix<VectorType>>();
1941 lumped_diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
1942 VectorType &inverse_lumped_diagonal_vector =
1943 inverse_lumped_diagonal_entries->get_vector();
1944 VectorType &lumped_diagonal_vector = lumped_diagonal_entries->get_vector();
1945 this->initialize_dof_vector(inverse_lumped_diagonal_vector);
1946 this->initialize_dof_vector(lumped_diagonal_vector);
1949 inverse_lumped_diagonal_vector = Number(1.);
1950 apply_add(lumped_diagonal_vector, inverse_lumped_diagonal_vector);
1951 this->set_constrained_entries_to_one(lumped_diagonal_vector);
1954 inverse_lumped_diagonal_vector.locally_owned_size();
1959 for (
size_type i = 0; i < locally_owned_size; ++i)
1961 if (lumped_diagonal_vector.local_element(i) == Number(0.))
1962 inverse_lumped_diagonal_vector.local_element(i) = Number(1.);
1964 inverse_lumped_diagonal_vector.local_element(i) =
1965 Number(1.) / lumped_diagonal_vector.local_element(i);
1968 inverse_lumped_diagonal_vector.update_ghost_values();
1969 lumped_diagonal_vector.update_ghost_values();
1978 typename VectorType,
1979 typename VectorizedArrayType>
1980 const std::shared_ptr<DiagonalMatrix<VectorType>> &
1986 VectorizedArrayType>::get_matrix_lumped_diagonal_inverse()
const
1988 Assert(inverse_lumped_diagonal_entries.get() !=
nullptr &&
1989 inverse_lumped_diagonal_entries->m() > 0,
1991 return inverse_lumped_diagonal_entries;
2000 typename VectorType,
2001 typename VectorizedArrayType>
2002 const std::shared_ptr<DiagonalMatrix<VectorType>> &
2008 VectorizedArrayType>::get_matrix_lumped_diagonal()
const
2010 Assert(lumped_diagonal_entries.get() !=
nullptr &&
2011 lumped_diagonal_entries->m() > 0,
2013 return lumped_diagonal_entries;
2022 typename VectorType,
2023 typename VectorizedArrayType>
2030 VectorizedArrayType>::apply_add(VectorType & dst,
2031 const VectorType &src)
const
2043 typename VectorType,
2044 typename VectorizedArrayType>
2051 VectorizedArrayType>::
2056 VectorizedArrayType> & data,
2058 const VectorType & src,
2059 const std::pair<unsigned int, unsigned int> &cell_range)
const
2068 VectorizedArrayType>
2069 phi(data, this->selected_rows[0]);
2070 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2073 phi.read_dof_values(src);
2075 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2076 phi.submit_value(phi.get_value(q), q);
2078 phi.distribute_local_to_global(dst);
2089 typename VectorType,
2090 typename VectorizedArrayType>
2096 VectorizedArrayType>::LaplaceOperator()
2097 :
Base<dim, VectorType, VectorizedArrayType>()
2106 typename VectorType,
2107 typename VectorizedArrayType>
2114 VectorizedArrayType>::clear()
2117 scalar_coefficient.reset();
2126 typename VectorType,
2127 typename VectorizedArrayType>
2134 VectorizedArrayType>::
2138 scalar_coefficient = scalar_coefficient_;
2147 typename VectorType,
2148 typename VectorizedArrayType>
2149 std::shared_ptr<Table<2, VectorizedArrayType>>
2155 VectorizedArrayType>::get_coefficient()
2158 return scalar_coefficient;
2167 typename VectorType,
2168 typename VectorizedArrayType>
2175 VectorizedArrayType>::compute_diagonal()
2182 this->inverse_diagonal_entries =
2183 std::make_shared<DiagonalMatrix<VectorType>>();
2184 this->diagonal_entries = std::make_shared<DiagonalMatrix<VectorType>>();
2185 VectorType &inverse_diagonal_vector =
2186 this->inverse_diagonal_entries->get_vector();
2187 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
2188 this->initialize_dof_vector(inverse_diagonal_vector);
2189 this->initialize_dof_vector(diagonal_vector);
2195 this->set_constrained_entries_to_one(diagonal_vector);
2197 inverse_diagonal_vector = diagonal_vector;
2199 for (
unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size();
2201 if (
std::abs(inverse_diagonal_vector.local_element(i)) >
2202 std::sqrt(std::numeric_limits<Number>::epsilon()))
2203 inverse_diagonal_vector.local_element(i) =
2204 1. / inverse_diagonal_vector.local_element(i);
2206 inverse_diagonal_vector.local_element(i) = 1.;
2217 typename VectorType,
2218 typename VectorizedArrayType>
2225 VectorizedArrayType>::apply_add(VectorType & dst,
2226 const VectorType &src)
const
2232 namespace Implementation
2234 template <
typename VectorizedArrayType>
2238 for (
unsigned int v = 0; v < VectorizedArrayType::size(); ++v)
2252 typename VectorType,
2253 typename VectorizedArrayType>
2255 LaplaceOperator<dim,
2260 VectorizedArrayType>::
2261 do_operation_on_cell(
2268 const unsigned int cell)
const
2271 if (scalar_coefficient.get())
2273 Assert(scalar_coefficient->size(1) == 1 ||
2274 scalar_coefficient->size(1) == phi.n_q_points,
2275 ExcMessage(
"The number of columns in the coefficient table must "
2276 "be either 1 or the number of quadrature points " +
2277 std::to_string(phi.n_q_points) +
2278 ", but the given value was " +
2279 std::to_string(scalar_coefficient->size(1))));
2280 if (scalar_coefficient->size(1) == phi.n_q_points)
2281 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2284 (*scalar_coefficient)(cell, q)),
2285 ExcMessage(
"Coefficient must be non-negative"));
2286 phi.submit_gradient((*scalar_coefficient)(cell, q) *
2287 phi.get_gradient(q),
2293 ExcMessage(
"Coefficient must be non-negative"));
2294 const VectorizedArrayType coefficient =
2295 (*scalar_coefficient)(cell, 0);
2296 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2297 phi.submit_gradient(coefficient * phi.get_gradient(q), q);
2302 for (
unsigned int q = 0; q < phi.n_q_points; ++q)
2304 phi.submit_gradient(phi.get_gradient(q), q);
2316 typename VectorType,
2317 typename VectorizedArrayType>
2324 VectorizedArrayType>::
2329 VectorizedArrayType> & data,
2331 const VectorType & src,
2332 const std::pair<unsigned int, unsigned int> &cell_range)
const
2337 data, this->selected_rows[0]);
2338 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2342 do_operation_on_cell(phi, cell);
2352 typename VectorType,
2353 typename VectorizedArrayType>
2360 VectorizedArrayType>::
2361 local_diagonal_cell(
2365 VectorizedArrayType> &data,
2368 const std::pair<unsigned int, unsigned int> &cell_range)
const
2374 data, this->selected_rows[0]);
2375 for (
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
2384 do_operation_on_cell(phi, cell);
2390 local_diagonal_vector[i];
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0, const std::bitset< VectorizedArrayType::size()> &mask=std::bitset< VectorizedArrayType::size()>().flip()) const
void read_dof_values(const VectorType &src, const unsigned int first_index=0, const std::bitset< VectorizedArrayType::size()> &mask=std::bitset< VectorizedArrayType::size()>().flip())
const Number * begin_dof_values() const
const unsigned int dofs_per_component
void reinit(const unsigned int cell_batch_index)
static constexpr unsigned int static_dofs_per_cell
static constexpr unsigned int n_components
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 do_operation_on_cell(FEEvaluation< dim, fe_degree, n_q_points_1d, n_components, value_type > &phi, const unsigned int cell) 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)
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< IsBlockVector< VectorType >::value, void >::type collect_sizes(VectorType &vector)
std::enable_if< IsBlockVector< VectorType >::value, unsignedint >::type n_blocks(const VectorType &vector)
std::enable_if< IsBlockVector< VectorType >::value, typenameVectorType::BlockType & >::type subblock(VectorType &vector, unsigned int block_no)
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)