17 #ifndef dealii_matrix_free_operators_h 18 #define dealii_matrix_free_operators_h 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/vectorization.h> 23 #include <deal.II/base/subscriptor.h> 25 #include <deal.II/lac/diagonal_matrix.h> 26 #include <deal.II/lac/la_parallel_vector.h> 27 #include <deal.II/multigrid/mg_constrained_dofs.h> 28 #include <deal.II/matrix_free/matrix_free.h> 29 #include <deal.II/matrix_free/fe_evaluation.h> 32 DEAL_II_NAMESPACE_OPEN
42 template <
typename VectorType>
43 typename std::enable_if<IsBlockVector<VectorType>::value,
45 n_blocks(
const VectorType &vector)
47 return vector.n_blocks();
50 template <
typename VectorType>
51 typename std::enable_if<!IsBlockVector<VectorType>::value,
53 n_blocks(
const VectorType &)
58 template <
typename VectorType>
59 typename std::enable_if<IsBlockVector<VectorType>::value,
60 typename VectorType::BlockType &>::type
61 subblock(VectorType &vector,
unsigned int block_no)
63 return vector.block(block_no);
66 template <
typename VectorType>
67 typename std::enable_if<IsBlockVector<VectorType>::value,
68 const typename VectorType::BlockType &>::type
69 subblock(
const VectorType &vector,
unsigned int block_no)
72 return vector.block(block_no);
75 template <
typename VectorType>
76 typename std::enable_if<!IsBlockVector<VectorType>::value,
78 subblock(VectorType &vector,
unsigned int)
83 template <
typename VectorType>
84 typename std::enable_if<!IsBlockVector<VectorType>::value,
85 const VectorType &>::type
86 subblock(
const VectorType &vector,
unsigned int)
91 template <
typename VectorType>
92 typename std::enable_if<IsBlockVector<VectorType>::value,
94 collect_sizes(VectorType &vector)
96 vector.collect_sizes();
99 template <
typename VectorType>
100 typename std::enable_if<!IsBlockVector<VectorType>::value,
102 collect_sizes(
const VectorType &)
184 template <
int dim,
typename VectorType = LinearAlgebra::distributed::Vector<
double> >
206 virtual ~Base() =
default;
212 virtual void clear();
231 const std::vector<unsigned int> &selected_row_blocks = std::vector<unsigned int>(),
232 const std::vector<unsigned int> &selected_column_blocks = std::vector<unsigned int>());
249 const unsigned int level,
250 const std::vector<unsigned int> &selected_row_blocks = std::vector<unsigned int>());
268 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
269 const unsigned int level,
270 const std::vector<unsigned int> &selected_row_blocks = std::vector<unsigned int>());
286 const VectorType &src)
const;
292 const VectorType &src)
const;
297 void vmult (VectorType &dst,
298 const VectorType &src)
const;
303 void Tvmult (VectorType &dst,
304 const VectorType &src)
const;
310 const VectorType &src)
const;
316 const VectorType &src)
const;
323 const unsigned int col)
const;
346 std::shared_ptr<const MatrixFree<dim,value_type> >
352 const std::shared_ptr<DiagonalMatrix<VectorType> > &
358 const std::shared_ptr<DiagonalMatrix<VectorType> > &
368 const VectorType &src,
395 const VectorType &src)
const = 0;
403 const VectorType &src)
const;
408 std::shared_ptr<const MatrixFree<dim,value_type> >
data;
444 mutable std::vector<std::vector<std::pair<value_type,value_type> > >
458 const VectorType &src,
469 const bool is_row)
const;
510 template <
typename OperatorType>
537 void initialize (
const OperatorType &operator_in);
542 template <
typename VectorType>
543 void vmult (VectorType &dst,
544 const VectorType &src)
const;
549 template <
typename VectorType>
550 void Tvmult (VectorType &dst,
551 const VectorType &src)
const;
556 template <
typename VectorType>
588 template <
int dim,
int fe_degree,
int n_components = 1,
typename Number =
double>
607 const unsigned int n_actual_components,
641 template <
int dim,
int fe_degree,
int n_q_po
ints_1d = fe_degree+1,
int n_components = 1,
typename VectorType = LinearAlgebra::distributed::Vector<
double> >
672 const VectorType &src)
const;
679 const VectorType &src,
680 const std::pair<unsigned int,unsigned int> &cell_range)
const;
696 template <
int dim,
int fe_degree,
int n_q_po
ints_1d = fe_degree+1,
int n_components = 1,
typename VectorType = LinearAlgebra::distributed::Vector<
double> >
768 virtual void clear();
776 std::shared_ptr< Table<2, VectorizedArray<value_type> > >
get_coefficient();
785 const VectorType &src)
const;
792 const VectorType &src,
793 const std::pair<unsigned int,unsigned int> &cell_range)
const;
800 const unsigned int &,
801 const std::pair<unsigned int,unsigned int> &cell_range)
const;
807 const unsigned int cell)
const;
819 template <
int dim,
int fe_degree,
int n_components,
typename Number>
827 for (
unsigned int i=0, c=0; i<shapes_1d.
m(); ++i)
828 for (
unsigned int j=0; j<shapes_1d.
n(); ++j, ++c)
831 const unsigned int stride = (fe_degree+2)/2;
832 inverse_shape.resize(stride*(fe_degree+1));
833 for (
unsigned int i=0; i<stride; ++i)
834 for (
unsigned int q=0; q<(fe_degree+2)/2; ++q)
836 inverse_shape[i*stride+q] =
837 0.5 * (shapes_1d(i,q) + shapes_1d(i,fe_degree-q));
838 inverse_shape[(fe_degree-i)*stride+q] =
839 0.5 * (shapes_1d(i,q) - shapes_1d(i,fe_degree-q));
841 if (fe_degree % 2 == 0)
842 for (
unsigned int q=0; q<(fe_degree+2)/2; ++q)
843 inverse_shape[fe_degree/2*stride+q] = shapes_1d(fe_degree/2,q);
848 template <
int dim,
int fe_degree,
int n_components,
typename Number>
854 constexpr
unsigned int dofs_per_cell =
Utilities::pow(fe_degree + 1, dim);
855 Assert(inverse_jxw.size() > 0 &&
856 inverse_jxw.size() % dofs_per_cell == 0,
857 ExcMessage(
"Expected diagonal to be a multiple of scalar dof per cells"));
861 const unsigned int previous_size = inverse_jxw.size();
862 inverse_jxw.resize(dofs_per_cell);
863 fe_eval.fill_JxW_values(inverse_jxw);
866 inverse_jxw.resize_fast(previous_size);
867 for (
unsigned int q=0; q<dofs_per_cell; ++q)
868 inverse_jxw[q] = 1./inverse_jxw[q];
870 for (
unsigned int q=dofs_per_cell; q<previous_size; )
871 for (
unsigned int i=0; i<dofs_per_cell; ++i, ++q)
872 inverse_jxw[q] = inverse_jxw[i];
877 template <
int dim,
int fe_degree,
int n_components,
typename Number>
882 const unsigned int n_actual_components,
886 constexpr
unsigned int dofs_per_cell =
Utilities::pow(fe_degree + 1, dim);
887 Assert(inverse_coefficients.size() > 0 &&
888 inverse_coefficients.size() % dofs_per_cell == 0,
889 ExcMessage(
"Expected diagonal to be a multiple of scalar dof per cells"));
890 if (inverse_coefficients.size() != dofs_per_cell)
891 AssertDimension(n_actual_components * dofs_per_cell, inverse_coefficients.size());
897 evaluator(inverse_shape, inverse_shape, inverse_shape);
899 const unsigned int shift_coefficient =
900 inverse_coefficients.size() > dofs_per_cell ? dofs_per_cell : 0;
903 for (
unsigned int d=0; d<n_actual_components; ++d)
909 evaluator.template hessians<0,false,false> (in, temp_data_field);
910 evaluator.template hessians<1,false,false> (temp_data_field, out);
914 evaluator.template hessians<2,false,false> (out, temp_data_field);
915 for (
unsigned int q=0; q<dofs_per_cell; ++q)
916 temp_data_field[q] *= inv_coefficient[q];
917 evaluator.template hessians<2,true,false> (temp_data_field, out);
920 for (
unsigned int q=0; q<dofs_per_cell; ++q)
921 out[q] *= inv_coefficient[q];
923 evaluator.template hessians<1,true,false>(out, temp_data_field);
924 evaluator.template hessians<0,true,false>(temp_data_field, out);
926 inv_coefficient += shift_coefficient;
931 template <
int dim,
typename VectorType>
935 have_interface_matrices(false)
940 template <
int dim,
typename VectorType>
944 Assert(data.get() !=
nullptr,
947 for (
unsigned int i=0; i<selected_rows.size(); ++i)
948 total_size += data->get_vector_partitioner(selected_rows[i])->size();
954 template <
int dim,
typename VectorType>
958 Assert(data.get() !=
nullptr,
961 for (
unsigned int i=0; i<selected_columns.size(); ++i)
962 total_size += data->get_vector_partitioner(selected_columns[i])->size();
968 template <
int dim,
typename VectorType>
973 inverse_diagonal_entries.reset();
978 template <
int dim,
typename VectorType>
981 const unsigned int col)
const 985 Assert (inverse_diagonal_entries.get() !=
nullptr &&
987 return 1.0/(*inverse_diagonal_entries)(row,row);
992 template <
int dim,
typename VectorType>
996 Assert(data.get() !=
nullptr,
999 for (
unsigned int i = 0; i < n_blocks(vec); ++i)
1001 const unsigned int index = selected_rows[i];
1002 if (!subblock(vec,index).partitioners_are_compatible
1003 (*data->get_dof_info(index).vector_partitioner))
1004 data->initialize_dof_vector(subblock(vec,index),index);
1006 Assert(subblock(vec,index).partitioners_are_globally_compatible
1007 (*data->get_dof_info(index).vector_partitioner),
1015 template <
int dim,
typename VectorType>
1019 const std::vector<unsigned int> &given_row_selection,
1020 const std::vector<unsigned int> &given_column_selection)
1024 selected_rows.clear();
1025 selected_columns.clear();
1026 if (given_row_selection.empty())
1027 for (
unsigned int i=0; i<data_->n_components(); ++i)
1028 selected_rows.push_back(i);
1031 for (
unsigned int i=0; i<given_row_selection.size(); ++i)
1034 for (
unsigned int j=0; j<given_row_selection.size(); ++j)
1036 Assert(given_row_selection[j] != given_row_selection[i],
1037 ExcMessage(
"Given row indices must be unique"));
1039 selected_rows.push_back(given_row_selection[i]);
1042 if (given_column_selection.size() == 0)
1043 selected_columns = selected_rows;
1046 for (
unsigned int i=0; i<given_column_selection.size(); ++i)
1049 for (
unsigned int j=0; j<given_column_selection.size(); ++j)
1051 Assert(given_column_selection[j] != given_column_selection[i],
1052 ExcMessage(
"Given column indices must be unique"));
1054 selected_columns.push_back(given_column_selection[i]);
1058 edge_constrained_indices.clear();
1059 edge_constrained_indices.resize(selected_rows.size());
1060 edge_constrained_values.clear();
1061 edge_constrained_values.resize(selected_rows.size());
1062 have_interface_matrices =
false;
1067 template <
int dim,
typename VectorType>
1072 const unsigned int level,
1073 const std::vector<unsigned int> &given_row_selection)
1075 std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(1, mg_constrained_dofs);
1076 initialize(data_, mg_constrained_dofs_vector, level, given_row_selection);
1081 template <
int dim,
typename VectorType>
1085 const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
1086 const unsigned int level,
1087 const std::vector<unsigned int> &given_row_selection)
1092 selected_rows.clear();
1093 selected_columns.clear();
1094 if (given_row_selection.empty())
1095 for (
unsigned int i=0; i<data_->n_components(); ++i)
1096 selected_rows.push_back(i);
1099 for (
unsigned int i=0; i<given_row_selection.size(); ++i)
1102 for (
unsigned int j=0; j<given_row_selection.size(); ++j)
1104 Assert(given_row_selection[j] != given_row_selection[i],
1105 ExcMessage(
"Given row indices must be unique"));
1107 selected_rows.push_back(given_row_selection[i]);
1110 selected_columns = selected_rows;
1113 edge_constrained_indices.clear();
1114 edge_constrained_indices.resize(selected_rows.size());
1115 edge_constrained_values.clear();
1116 edge_constrained_values.resize(selected_rows.size());
1120 for (
unsigned int j = 0; j < selected_rows.size(); ++j)
1122 if (data_->n_macro_cells() > 0)
1125 data_->get_cell_iterator(0,0,j)->level());
1129 std::vector<types::global_dof_index> interface_indices;
1130 mg_constrained_dofs[j].get_refinement_edge_indices(level)
1131 .fill_index_vector(interface_indices);
1132 edge_constrained_indices[j].clear();
1133 edge_constrained_indices[j].reserve(interface_indices.size());
1134 edge_constrained_values[j].resize(interface_indices.size());
1135 const IndexSet &locally_owned = data->get_dof_handler(selected_rows[j]).locally_owned_mg_dofs(level);
1136 for (
unsigned int i=0; i<interface_indices.size(); ++i)
1137 if (locally_owned.
is_element(interface_indices[i]))
1138 edge_constrained_indices[j].push_back
1140 have_interface_matrices |=
1142 data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1148 template <
int dim,
typename VectorType>
1152 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1154 const std::vector<unsigned int> &
1155 constrained_dofs = data->get_constrained_dofs(selected_rows[j]);
1156 for (
unsigned int i=0; i<constrained_dofs.size(); ++i)
1157 subblock(dst,j).local_element(constrained_dofs[i]) = 1.;
1158 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1159 subblock(dst,j).local_element(edge_constrained_indices[j][i]) = 1.;
1165 template <
int dim,
typename VectorType>
1168 const VectorType &src)
const 1172 vmult_add (dst, src);
1177 template <
int dim,
typename VectorType>
1180 const VectorType &src)
const 1182 mult_add (dst, src,
false);
1187 template <
int dim,
typename VectorType>
1190 const VectorType &src)
const 1192 mult_add (dst, src,
true);
1197 template <
int dim,
typename VectorType>
1200 const bool is_row)
const 1203 for (
unsigned int i=0; i<n_blocks(src); ++i)
1205 const unsigned int mf_component = is_row ? selected_rows[i] : selected_columns[i];
1207 if (subblock(src,i).get_partitioner().get() ==
1208 data->get_dof_info(mf_component).vector_partitioner.get())
1213 Assert(subblock(src,i).get_partitioner()->local_size() ==
1214 data->get_dof_info(mf_component).vector_partitioner->local_size(),
1215 ExcMessage(
"The vector passed to the vmult() function does not have " 1216 "the correct size for compatibility with MatrixFree."));
1221 subblock(const_cast<VectorType &>(src),i).
1222 reinit(data->get_dof_info(mf_component).vector_partitioner);
1223 subblock(const_cast<VectorType &>(src),i).copy_locally_owned_data_from(copy_vec);
1229 template <
int dim,
typename VectorType>
1232 const VectorType &src)
const 1235 adjust_ghost_range_if_necessary(src,
false);
1236 adjust_ghost_range_if_necessary(dst,
true);
1240 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1242 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1244 edge_constrained_values[j][i] =
1245 std::pair<Number,Number>
1246 (subblock(src,j).local_element(edge_constrained_indices[j][i]),
1247 subblock(dst,j).local_element(edge_constrained_indices[j][i]));
1248 subblock(const_cast<VectorType &>(src),j).local_element(edge_constrained_indices[j][i]) = 0.;
1255 template <
int dim,
typename VectorType>
1258 const VectorType &src,
1264 preprocess_constraints (dst,src);
1266 Tapply_add(dst,src);
1269 postprocess_constraints(dst,src);
1274 template <
int dim,
typename VectorType>
1277 const VectorType &src)
const 1279 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1281 const std::vector<unsigned int> &
1282 constrained_dofs = data->get_constrained_dofs(selected_rows[j]);
1283 for (
unsigned int i=0; i<constrained_dofs.size(); ++i)
1284 subblock(dst,j).local_element(constrained_dofs[i]) +=
1285 subblock(src,j).local_element(constrained_dofs[i]);
1290 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1292 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1294 subblock(const_cast<VectorType &>(src),j).local_element
1295 (edge_constrained_indices[j][i])
1296 = edge_constrained_values[j][i].first;
1297 subblock(dst,j).local_element(edge_constrained_indices[j][i])
1298 = edge_constrained_values[j][i].second +
1299 edge_constrained_values[j][i].first;
1306 template <
int dim,
typename VectorType>
1310 const VectorType &src)
const 1314 adjust_ghost_range_if_necessary(src,
false);
1315 adjust_ghost_range_if_necessary(dst,
true);
1319 if (!have_interface_matrices)
1324 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1325 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1327 edge_constrained_values[j][i] =
1328 std::pair<Number,Number>
1329 (subblock(src,j).local_element(edge_constrained_indices[j][i]),
1330 subblock(dst,j).local_element(edge_constrained_indices[j][i]));
1331 subblock(const_cast<VectorType &>(src),j)
1332 .local_element(edge_constrained_indices[j][i]) = 0.;
1337 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1340 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1342 for ( ; c<edge_constrained_indices[j][i]; ++c)
1343 subblock(dst,j).local_element(c) = 0.;
1347 subblock(const_cast<VectorType &>(src),j)
1348 .local_element(edge_constrained_indices[j][i])
1349 = edge_constrained_values[j][i].first;
1351 for ( ; c<subblock(dst,j).local_size(); ++c)
1352 subblock(dst,j).local_element(c) = 0.;
1358 template <
int dim,
typename VectorType>
1362 const VectorType &src)
const 1366 adjust_ghost_range_if_necessary(src,
false);
1367 adjust_ghost_range_if_necessary(dst,
true);
1371 if (!have_interface_matrices)
1374 VectorType src_cpy (src);
1375 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1378 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1380 for ( ; c<edge_constrained_indices[j][i]; ++c)
1381 subblock(src_cpy,j).local_element(c) = 0.;
1384 for ( ; c<subblock(src_cpy,j).local_size(); ++c)
1385 subblock(src_cpy,j).local_element(c) = 0.;
1388 apply_add(dst,src_cpy);
1390 for (
unsigned int j=0; j<n_blocks(dst); ++j)
1391 for (
unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1392 subblock(dst,j).local_element(edge_constrained_indices[j][i]) = 0.;
1397 template <
int dim,
typename VectorType>
1400 const VectorType &src)
const 1404 Tvmult_add (dst,src);
1409 template <
int dim,
typename VectorType>
1413 return inverse_diagonal_entries.get() !=
nullptr ?
1414 inverse_diagonal_entries->memory_consumption() :
sizeof(*this);
1419 template <
int dim,
typename VectorType>
1420 std::shared_ptr<const MatrixFree<dim,typename Base<dim,VectorType>::value_type> >
1428 template <
int dim,
typename VectorType>
1429 const std::shared_ptr<DiagonalMatrix<VectorType> > &
1432 Assert(inverse_diagonal_entries.get() !=
nullptr &&
1434 return inverse_diagonal_entries;
1439 template <
int dim,
typename VectorType>
1440 const std::shared_ptr<DiagonalMatrix<VectorType> > &
1443 Assert(diagonal_entries.get() !=
nullptr &&
1445 return diagonal_entries;
1450 template <
int dim,
typename VectorType>
1453 const VectorType &src)
const 1460 template <
int dim,
typename VectorType>
1463 const VectorType &src,
1466 Assert(inverse_diagonal_entries.get() &&
1468 inverse_diagonal_entries->vmult(dst,src);
1476 template <
typename OperatorType>
1480 mf_base_operator(nullptr)
1486 template <
typename OperatorType>
1490 mf_base_operator =
nullptr;
1495 template <
typename OperatorType>
1499 mf_base_operator = &operator_in;
1504 template <
typename OperatorType>
1505 template <
typename VectorType>
1508 const VectorType &src)
const 1510 #ifndef DEAL_II_MSVC 1511 static_assert (std::is_same<typename VectorType::value_type,value_type>::value,
1512 "The vector type must be based on the same value type as this" 1516 Assert(mf_base_operator !=
nullptr,
1519 mf_base_operator->vmult_interface_down(dst, src);
1524 template <
typename OperatorType>
1525 template <
typename VectorType>
1528 const VectorType &src)
const 1530 #ifndef DEAL_II_MSVC 1531 static_assert (std::is_same<typename VectorType::value_type,value_type>::value,
1532 "The vector type must be based on the same value type as this" 1536 Assert(mf_base_operator !=
nullptr,
1539 mf_base_operator->vmult_interface_up(dst, src);
1544 template <
typename OperatorType>
1545 template <
typename VectorType>
1549 Assert(mf_base_operator !=
nullptr,
1552 mf_base_operator->initialize_dof_vector(vec);
1559 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1563 Base<dim, VectorType>()
1568 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1576 this->inverse_diagonal_entries.
1578 this->diagonal_entries.
1580 VectorType &inverse_diagonal_vector = this->inverse_diagonal_entries->get_vector();
1581 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1582 this->initialize_dof_vector(inverse_diagonal_vector);
1583 this->initialize_dof_vector(diagonal_vector);
1584 inverse_diagonal_vector = Number(1.);
1585 apply_add(diagonal_vector, inverse_diagonal_vector);
1587 this->set_constrained_entries_to_one(diagonal_vector);
1588 inverse_diagonal_vector = diagonal_vector;
1590 const unsigned int local_size = inverse_diagonal_vector.local_size();
1591 for (
unsigned int i=0; i<local_size; ++i)
1592 inverse_diagonal_vector.local_element(i)
1593 =1./inverse_diagonal_vector.local_element(i);
1595 inverse_diagonal_vector.update_ghost_values();
1596 diagonal_vector.update_ghost_values();
1601 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1605 const VectorType &src)
const 1613 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1618 const VectorType &src,
1619 const std::pair<unsigned int,unsigned int> &cell_range)
const 1623 for (
unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
1628 for (
unsigned int q=0; q<phi.
n_q_points; ++q)
1638 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1642 Base<dim, VectorType>()
1648 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1654 scalar_coefficient.reset();
1659 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1664 scalar_coefficient = scalar_coefficient_;
1669 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1670 std::shared_ptr< Table<2, VectorizedArray< typename LaplaceOperator<dim, fe_degree, n_q_points_1d, n_components, VectorType>::value_type> > >
1674 Assert (scalar_coefficient.get(),
1676 return scalar_coefficient;
1681 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1689 unsigned int dummy = 0;
1690 this->inverse_diagonal_entries.
1692 this->diagonal_entries.
1694 VectorType &inverse_diagonal_vector = this->inverse_diagonal_entries->get_vector();
1695 VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1696 this->initialize_dof_vector(inverse_diagonal_vector);
1697 this->initialize_dof_vector(diagonal_vector);
1700 this, diagonal_vector, dummy);
1701 this->set_constrained_entries_to_one(diagonal_vector);
1703 inverse_diagonal_vector = diagonal_vector;
1705 for (
unsigned int i=0; i<inverse_diagonal_vector.local_size(); ++i)
1706 if (std::abs(inverse_diagonal_vector.local_element(i)) > std::sqrt(std::numeric_limits<Number>::epsilon()))
1707 inverse_diagonal_vector.local_element(i) = 1./inverse_diagonal_vector.local_element(i);
1709 inverse_diagonal_vector.local_element(i) = 1.;
1711 inverse_diagonal_vector.update_ghost_values();
1712 diagonal_vector.update_ghost_values();
1717 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1721 const VectorType &src)
const 1729 template <
typename Number>
1733 for (
unsigned int v=0; v<VectorizedArray<Number>::n_array_elements; ++v)
1743 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1747 const unsigned int cell)
const 1749 phi.evaluate (
false,
true,
false);
1750 if (scalar_coefficient.get())
1752 for (
unsigned int q=0; q<phi.n_q_points; ++q)
1754 Assert (non_negative((*scalar_coefficient)(cell,q)),
1755 ExcMessage(
"Coefficient must be non-negative"));
1756 phi.submit_gradient ((*scalar_coefficient)(cell,q)*phi.get_gradient(q), q);
1761 for (
unsigned int q=0; q<phi.n_q_points; ++q)
1763 phi.submit_gradient (phi.get_gradient(q), q);
1766 phi.integrate (
false,
true);
1772 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1777 const VectorType &src,
1778 const std::pair<unsigned int,unsigned int> &cell_range)
const 1782 for (
unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
1786 do_operation_on_cell(phi,cell);
1792 template <
int dim,
int fe_degree,
int n_q_po
ints_1d,
int n_components,
typename VectorType>
1797 const unsigned int &,
1798 const std::pair<unsigned int,unsigned int> &cell_range)
const 1802 for (
unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
1811 do_operation_on_cell(phi,cell);
1825 DEAL_II_NAMESPACE_CLOSE
std::shared_ptr< const MatrixFree< dim, value_type > > data
void do_operation_on_cell(FEEvaluation< dim, fe_degree, n_q_points_1d, n_components, value_type > &phi, const unsigned int cell) const
static const unsigned int invalid_unsigned_int
void vmult_interface_down(VectorType &dst, const VectorType &src) const
OperatorType::value_type value_type
std::vector< unsigned int > selected_rows
#define AssertDimension(dim1, dim2)
void set_coefficient(const std::shared_ptr< Table< 2, VectorizedArray< value_type > > > &scalar_coefficient)
void initialize(std::shared_ptr< const MatrixFree< dim, value_type > > data, const std::vector< unsigned int > &selected_row_blocks=std::vector< unsigned int >(), const std::vector< unsigned int > &selected_column_blocks=std::vector< unsigned int >())
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0) const
virtual void apply_add(VectorType &dst, const VectorType &src) const
void local_apply_cell(const MatrixFree< dim, value_type > &data, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
void apply(const AlignedVector< VectorizedArray< Number > > &inverse_coefficient, const unsigned int n_actual_components, const VectorizedArray< Number > *in_array, VectorizedArray< Number > *out_array) const
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal_inverse() const
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
void integrate(const bool integrate_values, const bool integrate_gradients)
void precondition_Jacobi(VectorType &dst, const VectorType &src, const value_type omega) const
static constexpr unsigned int static_dofs_per_cell
#define AssertIndexRange(index, range)
OperatorType::size_type size_type
const FEEvaluationBase< dim, n_components, Number > & fe_eval
void mult_add(VectorType &dst, const VectorType &src, const bool transpose) const
const VectorizedArray< Number > * begin_dof_values() const
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal() const
static ::ExceptionBase & ExcNotInitialized()
void vmult_interface_up(VectorType &dst, const VectorType &src) const
#define AssertThrow(cond, exc)
void set_constrained_entries_to_one(VectorType &dst) const
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
static constexpr unsigned int n_components
AlignedVector< Number > shape_values
const unsigned int dofs_per_component
value_type get_value(const unsigned int q_point) const
void submit_value(const value_type val_in, const unsigned int q_point)
std::shared_ptr< DiagonalMatrix< VectorType > > diagonal_entries
Base< dim, VectorType >::value_type value_type
void initialize_dof_vector(VectorType &vec) const
virtual void compute_diagonal()
std::vector< unsigned int > selected_columns
value_type el(const unsigned int row, const unsigned int col) const
VectorType::value_type value_type
static ::ExceptionBase & ExcMessage(std::string arg1)
const unsigned int n_q_points
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info() const
virtual void Tapply_add(VectorType &dst, const VectorType &src) const
void Tvmult(VectorType &dst, const VectorType &src) const
#define Assert(cond, exc)
void local_diagonal_cell(const MatrixFree< dim, value_type > &data, VectorType &dst, const unsigned int &, const std::pair< unsigned int, unsigned int > &cell_range) const
size_type index_within_set(const size_type global_index) const
virtual void compute_diagonal()=0
VectorType::size_type size_type
std::vector< std::vector< unsigned int > > edge_constrained_indices
AlignedVector< VectorizedArray< Number > > inverse_shape
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
void Tvmult_add(VectorType &dst, const VectorType &src) const
virtual void apply_add(VectorType &dst, const VectorType &src) const
Base< dim, VectorType >::size_type size_type
void vmult(VectorType &dst, const VectorType &src) const
void reinit(const unsigned int cell_batch_index)
virtual void apply_add(VectorType &dst, const VectorType &src) const =0
void vmult(VectorType &dst, const VectorType &src) const
virtual void compute_diagonal()
void preprocess_constraints(VectorType &dst, const VectorType &src) const
CellwiseInverseMassMatrix(const FEEvaluationBase< dim, n_components, Number > &fe_eval)
std::vector< std::vector< std::pair< value_type, value_type > > > edge_constrained_values
void local_apply_cell(const MatrixFree< dim, value_type > &data, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &cell_range) const
std::shared_ptr< const MatrixFree< dim, value_type > > get_matrix_free() const
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > get_coefficient()
virtual std::size_t memory_consumption() const
void fill_inverse_JxW_values(AlignedVector< VectorizedArray< Number > > &inverse_jxw) const
void postprocess_constraints(VectorType &dst, const VectorType &src) const
static ::ExceptionBase & ExcNotImplemented()
Base< dim, VectorType >::value_type value_type
bool is_element(const size_type index) const
void adjust_ghost_range_if_necessary(const VectorType &vec, const bool is_row) const
void vmult_add(VectorType &dst, const VectorType &src) const
void initialize(const OperatorType &operator_in)
SmartPointer< const OperatorType > mf_base_operator
Base< dim, VectorType >::size_type size_type
void Tvmult(VectorType &dst, const VectorType &src) const
std::shared_ptr< DiagonalMatrix< VectorType > > inverse_diagonal_entries
void initialize_dof_vector(VectorType &vec) const
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > scalar_coefficient
T max(const T &t, const MPI_Comm &mpi_communicator)
bool have_interface_matrices
static ::ExceptionBase & ExcInternalError()