Reference documentation for deal.II version 9.1.0-pre
operators.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #ifndef dealii_matrix_free_operators_h
18 #define dealii_matrix_free_operators_h
19 
20 
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/subscriptor.h>
23 #include <deal.II/base/vectorization.h>
24 
25 #include <deal.II/lac/diagonal_matrix.h>
26 #include <deal.II/lac/la_parallel_vector.h>
27 
28 #include <deal.II/matrix_free/fe_evaluation.h>
29 #include <deal.II/matrix_free/matrix_free.h>
30 
31 #include <deal.II/multigrid/mg_constrained_dofs.h>
32 
33 
34 DEAL_II_NAMESPACE_OPEN
35 
36 
37 namespace MatrixFreeOperators
38 {
39  namespace BlockHelper
40  {
41  // workaroud for unifying non-block vector and block vector implementations
42  // a non-block vector has one block and the only subblock is the vector
43  // itself
44  template <typename VectorType>
45  typename std::enable_if<IsBlockVector<VectorType>::value,
46  unsigned int>::type
47  n_blocks(const VectorType &vector)
48  {
49  return vector.n_blocks();
50  }
51 
52  template <typename VectorType>
53  typename std::enable_if<!IsBlockVector<VectorType>::value,
54  unsigned int>::type
55  n_blocks(const VectorType &)
56  {
57  return 1;
58  }
59 
60  template <typename VectorType>
61  typename std::enable_if<IsBlockVector<VectorType>::value,
62  typename VectorType::BlockType &>::type
63  subblock(VectorType &vector, unsigned int block_no)
64  {
65  return vector.block(block_no);
66  }
67 
68  template <typename VectorType>
69  typename std::enable_if<IsBlockVector<VectorType>::value,
70  const typename VectorType::BlockType &>::type
71  subblock(const VectorType &vector, unsigned int block_no)
72  {
73  AssertIndexRange(block_no, vector.n_blocks());
74  return vector.block(block_no);
75  }
76 
77  template <typename VectorType>
78  typename std::enable_if<!IsBlockVector<VectorType>::value,
79  VectorType &>::type
80  subblock(VectorType &vector, unsigned int)
81  {
82  return vector;
83  }
84 
85  template <typename VectorType>
86  typename std::enable_if<!IsBlockVector<VectorType>::value,
87  const VectorType &>::type
88  subblock(const VectorType &vector, unsigned int)
89  {
90  return vector;
91  }
92 
93  template <typename VectorType>
94  typename std::enable_if<IsBlockVector<VectorType>::value, void>::type
95  collect_sizes(VectorType &vector)
96  {
97  vector.collect_sizes();
98  }
99 
100  template <typename VectorType>
101  typename std::enable_if<!IsBlockVector<VectorType>::value, void>::type
102  collect_sizes(const VectorType &)
103  {}
104  } // namespace BlockHelper
105 
185  template <int dim,
186  typename VectorType = LinearAlgebra::distributed::Vector<double>>
187  class Base : public Subscriptor
188  {
189  public:
193  using value_type = typename VectorType::value_type;
194 
198  using size_type = typename VectorType::size_type;
199 
203  Base();
204 
208  virtual ~Base() override = default;
209 
214  virtual void
215  clear();
216 
233  void
234  initialize(std::shared_ptr<const MatrixFree<dim, value_type>> data,
235  const std::vector<unsigned int> &selected_row_blocks =
236  std::vector<unsigned int>(),
237  const std::vector<unsigned int> &selected_column_blocks =
238  std::vector<unsigned int>());
239 
253  void
254  initialize(std::shared_ptr<const MatrixFree<dim, value_type>> data,
255  const MGConstrainedDoFs & mg_constrained_dofs,
256  const unsigned int level,
257  const std::vector<unsigned int> &selected_row_blocks =
258  std::vector<unsigned int>());
259 
274  void
275  initialize(std::shared_ptr<const MatrixFree<dim, value_type>> data_,
276  const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
277  const unsigned int level,
278  const std::vector<unsigned int> & selected_row_blocks =
279  std::vector<unsigned int>());
280 
284  size_type
285  m() const;
286 
290  size_type
291  n() const;
292 
296  void
297  vmult_interface_down(VectorType &dst, const VectorType &src) const;
298 
302  void
303  vmult_interface_up(VectorType &dst, const VectorType &src) const;
304 
308  void
309  vmult(VectorType &dst, const VectorType &src) const;
310 
314  void
315  Tvmult(VectorType &dst, const VectorType &src) const;
316 
320  void
321  vmult_add(VectorType &dst, const VectorType &src) const;
322 
326  void
327  Tvmult_add(VectorType &dst, const VectorType &src) const;
328 
333  value_type
334  el(const unsigned int row, const unsigned int col) const;
335 
340  virtual std::size_t
341  memory_consumption() const;
342 
346  void
347  initialize_dof_vector(VectorType &vec) const;
348 
356  virtual void
357  compute_diagonal() = 0;
358 
362  std::shared_ptr<const MatrixFree<dim, value_type>>
363  get_matrix_free() const;
364 
368  const std::shared_ptr<DiagonalMatrix<VectorType>> &
369  get_matrix_diagonal_inverse() const;
370 
374  const std::shared_ptr<DiagonalMatrix<VectorType>> &
375  get_matrix_diagonal() const;
376 
377 
383  void
384  precondition_Jacobi(VectorType & dst,
385  const VectorType &src,
386  const value_type omega) const;
387 
388  protected:
393  void
394  preprocess_constraints(VectorType &dst, const VectorType &src) const;
395 
400  void
401  postprocess_constraints(VectorType &dst, const VectorType &src) const;
402 
407  void
408  set_constrained_entries_to_one(VectorType &dst) const;
409 
413  virtual void
414  apply_add(VectorType &dst, const VectorType &src) const = 0;
415 
421  virtual void
422  Tapply_add(VectorType &dst, const VectorType &src) const;
423 
427  std::shared_ptr<const MatrixFree<dim, value_type>> data;
428 
433  std::shared_ptr<DiagonalMatrix<VectorType>> diagonal_entries;
434 
439  std::shared_ptr<DiagonalMatrix<VectorType>> inverse_diagonal_entries;
440 
445  std::vector<unsigned int> selected_rows;
446 
451  std::vector<unsigned int> selected_columns;
452 
453  private:
457  std::vector<std::vector<unsigned int>> edge_constrained_indices;
458 
462  mutable std::vector<std::vector<std::pair<value_type, value_type>>>
464 
470 
475  void
476  mult_add(VectorType & dst,
477  const VectorType &src,
478  const bool transpose) const;
479 
487  void
488  adjust_ghost_range_if_necessary(const VectorType &vec,
489  const bool is_row) const;
490  };
491 
492 
493 
530  template <typename OperatorType>
532  {
533  public:
537  using value_type = typename OperatorType::value_type;
538 
542  using size_type = typename OperatorType::size_type;
543 
548 
552  void
553  clear();
554 
558  void
559  initialize(const OperatorType &operator_in);
560 
564  template <typename VectorType>
565  void
566  vmult(VectorType &dst, const VectorType &src) const;
567 
571  template <typename VectorType>
572  void
573  Tvmult(VectorType &dst, const VectorType &src) const;
574 
578  template <typename VectorType>
579  void
580  initialize_dof_vector(VectorType &vec) const;
581 
582 
583  private:
588  };
589 
590 
591 
611  template <int dim,
612  int fe_degree,
613  int n_components = 1,
614  typename Number = double>
616  {
617  public:
624 
633  void
634  apply(const AlignedVector<VectorizedArray<Number>> &inverse_coefficient,
635  const unsigned int n_actual_components,
636  const VectorizedArray<Number> * in_array,
637  VectorizedArray<Number> * out_array) const;
638 
644  void
645  fill_inverse_JxW_values(
646  AlignedVector<VectorizedArray<Number>> &inverse_jxw) const;
647 
648  private:
653 
658  };
659 
660 
661 
671  template <int dim,
672  int fe_degree,
673  int n_q_points_1d = fe_degree + 1,
674  int n_components = 1,
675  typename VectorType = LinearAlgebra::distributed::Vector<double>>
676  class MassOperator : public Base<dim, VectorType>
677  {
678  public:
683 
688 
692  MassOperator();
693 
698  virtual void
699  compute_diagonal() override;
700 
701  private:
707  virtual void
708  apply_add(VectorType &dst, const VectorType &src) const override;
709 
713  void
714  local_apply_cell(
715  const MatrixFree<dim, value_type> & data,
716  VectorType & dst,
717  const VectorType & src,
718  const std::pair<unsigned int, unsigned int> &cell_range) const;
719  };
720 
721 
722 
735  template <int dim,
736  int fe_degree,
737  int n_q_points_1d = fe_degree + 1,
738  int n_components = 1,
739  typename VectorType = LinearAlgebra::distributed::Vector<double>>
740  class LaplaceOperator : public Base<dim, VectorType>
741  {
742  public:
747 
752 
756  LaplaceOperator();
757 
764  virtual void
765  compute_diagonal();
766 
813  void
814  set_coefficient(const std::shared_ptr<Table<2, VectorizedArray<value_type>>>
815  &scalar_coefficient);
816 
817  virtual void
818  clear();
819 
826  std::shared_ptr<Table<2, VectorizedArray<value_type>>>
827  get_coefficient();
828 
829  private:
835  virtual void
836  apply_add(VectorType &dst, const VectorType &src) const;
837 
841  void
842  local_apply_cell(
843  const MatrixFree<dim, value_type> & data,
844  VectorType & dst,
845  const VectorType & src,
846  const std::pair<unsigned int, unsigned int> &cell_range) const;
847 
851  void
852  local_diagonal_cell(
853  const MatrixFree<dim, value_type> &data,
854  VectorType & dst,
855  const unsigned int &,
856  const std::pair<unsigned int, unsigned int> &cell_range) const;
857 
861  void
862  do_operation_on_cell(
864  & phi,
865  const unsigned int cell) const;
866 
870  std::shared_ptr<Table<2, VectorizedArray<value_type>>> scalar_coefficient;
871  };
872 
873 
874 
875  // ------------------------------------ inline functions ---------------------
876 
877  template <int dim, int fe_degree, int n_components, typename Number>
881  : fe_eval(fe_eval)
882  {
883  FullMatrix<double> shapes_1d(fe_degree + 1, fe_degree + 1);
884  for (unsigned int i = 0, c = 0; i < shapes_1d.m(); ++i)
885  for (unsigned int j = 0; j < shapes_1d.n(); ++j, ++c)
886  shapes_1d(i, j) = fe_eval.get_shape_info().shape_values[c][0];
887  shapes_1d.gauss_jordan();
888  const unsigned int stride = (fe_degree + 2) / 2;
889  inverse_shape.resize(stride * (fe_degree + 1));
890  for (unsigned int i = 0; i < stride; ++i)
891  for (unsigned int q = 0; q < (fe_degree + 2) / 2; ++q)
892  {
893  inverse_shape[i * stride + q] =
894  0.5 * (shapes_1d(i, q) + shapes_1d(i, fe_degree - q));
895  inverse_shape[(fe_degree - i) * stride + q] =
896  0.5 * (shapes_1d(i, q) - shapes_1d(i, fe_degree - q));
897  }
898  if (fe_degree % 2 == 0)
899  for (unsigned int q = 0; q < (fe_degree + 2) / 2; ++q)
900  inverse_shape[fe_degree / 2 * stride + q] = shapes_1d(fe_degree / 2, q);
901  }
902 
903 
904 
905  template <int dim, int fe_degree, int n_components, typename Number>
906  inline void
909  AlignedVector<VectorizedArray<Number>> &inverse_jxw) const
910  {
911  constexpr unsigned int dofs_per_cell = Utilities::pow(fe_degree + 1, dim);
912  Assert(inverse_jxw.size() > 0 && inverse_jxw.size() % dofs_per_cell == 0,
913  ExcMessage(
914  "Expected diagonal to be a multiple of scalar dof per cells"));
915 
916  // temporarily reduce size of inverse_jxw to dofs_per_cell to get JxW values
917  // from fe_eval (will not reallocate any memory)
918  const unsigned int previous_size = inverse_jxw.size();
919  inverse_jxw.resize(dofs_per_cell);
920  fe_eval.fill_JxW_values(inverse_jxw);
921 
922  // invert
923  inverse_jxw.resize_fast(previous_size);
924  for (unsigned int q = 0; q < dofs_per_cell; ++q)
925  inverse_jxw[q] = 1. / inverse_jxw[q];
926  // copy values to rest of vector
927  for (unsigned int q = dofs_per_cell; q < previous_size;)
928  for (unsigned int i = 0; i < dofs_per_cell; ++i, ++q)
929  inverse_jxw[q] = inverse_jxw[i];
930  }
931 
932 
933 
934  template <int dim, int fe_degree, int n_components, typename Number>
935  inline void
937  const AlignedVector<VectorizedArray<Number>> &inverse_coefficients,
938  const unsigned int n_actual_components,
939  const VectorizedArray<Number> * in_array,
940  VectorizedArray<Number> * out_array) const
941  {
942  constexpr unsigned int dofs_per_component =
943  Utilities::pow(fe_degree + 1, dim);
944  Assert(inverse_coefficients.size() > 0 &&
945  inverse_coefficients.size() % dofs_per_component == 0,
946  ExcMessage(
947  "Expected diagonal to be a multiple of scalar dof per cells"));
948  if (inverse_coefficients.size() != dofs_per_component)
949  AssertDimension(n_actual_components * dofs_per_component,
950  inverse_coefficients.size());
951 
952  Assert(dim >= 1 || dim <= 3, ExcNotImplemented());
953 
955  dim,
956  fe_degree + 1,
957  fe_degree + 1,
960 
961  const unsigned int shift_coefficient =
962  inverse_coefficients.size() > dofs_per_component ? dofs_per_component : 0;
963  const VectorizedArray<Number> *inv_coefficient = &inverse_coefficients[0];
964  VectorizedArray<Number> temp_data_field[dofs_per_component];
965  for (unsigned int d = 0; d < n_actual_components; ++d)
966  {
967  const VectorizedArray<Number> *in = in_array + d * dofs_per_component;
968  VectorizedArray<Number> * out = out_array + d * dofs_per_component;
969  // Need to select 'apply' method with hessian slot because values
970  // assume symmetries that do not exist in the inverse shapes
971  evaluator.template hessians<0, false, false>(in, temp_data_field);
972  if (dim > 1)
973  {
974  evaluator.template hessians<1, false, false>(temp_data_field, out);
975 
976  if (dim == 3)
977  {
978  evaluator.template hessians<2, false, false>(out,
979  temp_data_field);
980  for (unsigned int q = 0; q < dofs_per_component; ++q)
981  temp_data_field[q] *= inv_coefficient[q];
982  evaluator.template hessians<2, true, false>(temp_data_field,
983  out);
984  }
985  else if (dim == 2)
986  for (unsigned int q = 0; q < dofs_per_component; ++q)
987  out[q] *= inv_coefficient[q];
988 
989  evaluator.template hessians<1, true, false>(out, temp_data_field);
990  }
991  else
992  {
993  for (unsigned int q = 0; q < dofs_per_component; ++q)
994  temp_data_field[q] *= inv_coefficient[q];
995  }
996  evaluator.template hessians<0, true, false>(temp_data_field, out);
997 
998  inv_coefficient += shift_coefficient;
999  }
1000  }
1001 
1002  //----------------- Base operator -----------------------------
1003  template <int dim, typename VectorType>
1005  : Subscriptor()
1006  , have_interface_matrices(false)
1007  {}
1008 
1009 
1010 
1011  template <int dim, typename VectorType>
1014  {
1015  Assert(data.get() != nullptr, ExcNotInitialized());
1016  typename Base<dim, VectorType>::size_type total_size = 0;
1017  for (unsigned int i = 0; i < selected_rows.size(); ++i)
1018  total_size += data->get_vector_partitioner(selected_rows[i])->size();
1019  return total_size;
1020  }
1021 
1022 
1023 
1024  template <int dim, typename VectorType>
1027  {
1028  Assert(data.get() != nullptr, ExcNotInitialized());
1029  typename Base<dim, VectorType>::size_type total_size = 0;
1030  for (unsigned int i = 0; i < selected_columns.size(); ++i)
1031  total_size += data->get_vector_partitioner(selected_columns[i])->size();
1032  return total_size;
1033  }
1034 
1035 
1036 
1037  template <int dim, typename VectorType>
1038  void
1040  {
1041  data.reset();
1042  inverse_diagonal_entries.reset();
1043  }
1044 
1045 
1046 
1047  template <int dim, typename VectorType>
1049  Base<dim, VectorType>::el(const unsigned int row,
1050  const unsigned int col) const
1051  {
1052  (void)col;
1053  Assert(row == col, ExcNotImplemented());
1054  Assert(inverse_diagonal_entries.get() != nullptr &&
1055  inverse_diagonal_entries->m() > 0,
1056  ExcNotInitialized());
1057  return 1.0 / (*inverse_diagonal_entries)(row, row);
1058  }
1059 
1060 
1061 
1062  template <int dim, typename VectorType>
1063  void
1065  {
1066  Assert(data.get() != nullptr, ExcNotInitialized());
1067  AssertDimension(BlockHelper::n_blocks(vec), selected_rows.size());
1068  for (unsigned int i = 0; i < BlockHelper::n_blocks(vec); ++i)
1069  {
1070  const unsigned int index = selected_rows[i];
1071  if (!BlockHelper::subblock(vec, index)
1072  .partitioners_are_compatible(
1073  *data->get_dof_info(index).vector_partitioner))
1074  data->initialize_dof_vector(BlockHelper::subblock(vec, index), index);
1075 
1076  Assert(BlockHelper::subblock(vec, index)
1077  .partitioners_are_globally_compatible(
1078  *data->get_dof_info(index).vector_partitioner),
1079  ExcInternalError());
1080  }
1081  BlockHelper::collect_sizes(vec);
1082  }
1083 
1084 
1085 
1086  template <int dim, typename VectorType>
1087  void
1089  std::shared_ptr<
1090  const MatrixFree<dim, typename Base<dim, VectorType>::value_type>> data_,
1091  const std::vector<unsigned int> &given_row_selection,
1092  const std::vector<unsigned int> &given_column_selection)
1093  {
1094  data = data_;
1095 
1096  selected_rows.clear();
1097  selected_columns.clear();
1098  if (given_row_selection.empty())
1099  for (unsigned int i = 0; i < data_->n_components(); ++i)
1100  selected_rows.push_back(i);
1101  else
1102  {
1103  for (unsigned int i = 0; i < given_row_selection.size(); ++i)
1104  {
1105  AssertIndexRange(given_row_selection[i], data_->n_components());
1106  for (unsigned int j = 0; j < given_row_selection.size(); ++j)
1107  if (j != i)
1108  Assert(given_row_selection[j] != given_row_selection[i],
1109  ExcMessage("Given row indices must be unique"));
1110 
1111  selected_rows.push_back(given_row_selection[i]);
1112  }
1113  }
1114  if (given_column_selection.size() == 0)
1116  else
1117  {
1118  for (unsigned int i = 0; i < given_column_selection.size(); ++i)
1119  {
1120  AssertIndexRange(given_column_selection[i], data_->n_components());
1121  for (unsigned int j = 0; j < given_column_selection.size(); ++j)
1122  if (j != i)
1123  Assert(given_column_selection[j] != given_column_selection[i],
1124  ExcMessage("Given column indices must be unique"));
1125 
1126  selected_columns.push_back(given_column_selection[i]);
1127  }
1128  }
1129 
1130  edge_constrained_indices.clear();
1131  edge_constrained_indices.resize(selected_rows.size());
1132  edge_constrained_values.clear();
1133  edge_constrained_values.resize(selected_rows.size());
1134  have_interface_matrices = false;
1135  }
1136 
1137 
1138 
1139  template <int dim, typename VectorType>
1140  void
1142  std::shared_ptr<
1143  const MatrixFree<dim, typename Base<dim, VectorType>::value_type>> data_,
1144  const MGConstrainedDoFs & mg_constrained_dofs,
1145  const unsigned int level,
1146  const std::vector<unsigned int> &given_row_selection)
1147  {
1148  std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(
1149  1, mg_constrained_dofs);
1150  initialize(data_, mg_constrained_dofs_vector, level, given_row_selection);
1151  }
1152 
1153 
1154 
1155  template <int dim, typename VectorType>
1156  void
1158  std::shared_ptr<const MatrixFree<dim, value_type>> data_,
1159  const std::vector<MGConstrainedDoFs> & mg_constrained_dofs,
1160  const unsigned int level,
1161  const std::vector<unsigned int> & given_row_selection)
1162  {
1164  ExcMessage("level is not set"));
1165 
1166  selected_rows.clear();
1167  selected_columns.clear();
1168  if (given_row_selection.empty())
1169  for (unsigned int i = 0; i < data_->n_components(); ++i)
1170  selected_rows.push_back(i);
1171  else
1172  {
1173  for (unsigned int i = 0; i < given_row_selection.size(); ++i)
1174  {
1175  AssertIndexRange(given_row_selection[i], data_->n_components());
1176  for (unsigned int j = 0; j < given_row_selection.size(); ++j)
1177  if (j != i)
1178  Assert(given_row_selection[j] != given_row_selection[i],
1179  ExcMessage("Given row indices must be unique"));
1180 
1181  selected_rows.push_back(given_row_selection[i]);
1182  }
1183  }
1185 
1186  AssertDimension(mg_constrained_dofs.size(), selected_rows.size());
1187  edge_constrained_indices.clear();
1188  edge_constrained_indices.resize(selected_rows.size());
1189  edge_constrained_values.clear();
1190  edge_constrained_values.resize(selected_rows.size());
1191 
1192  data = data_;
1193 
1194  for (unsigned int j = 0; j < selected_rows.size(); ++j)
1195  {
1196  if (data_->n_macro_cells() > 0)
1197  {
1198  AssertDimension(static_cast<int>(level),
1199  data_->get_cell_iterator(0, 0, j)->level());
1200  }
1201 
1202  // setup edge_constrained indices
1203  std::vector<types::global_dof_index> interface_indices;
1204  mg_constrained_dofs[j]
1205  .get_refinement_edge_indices(level)
1206  .fill_index_vector(interface_indices);
1207  edge_constrained_indices[j].clear();
1208  edge_constrained_indices[j].reserve(interface_indices.size());
1209  edge_constrained_values[j].resize(interface_indices.size());
1210  const IndexSet &locally_owned =
1211  data->get_dof_handler(selected_rows[j]).locally_owned_mg_dofs(level);
1212  for (unsigned int i = 0; i < interface_indices.size(); ++i)
1213  if (locally_owned.is_element(interface_indices[i]))
1214  edge_constrained_indices[j].push_back(
1215  locally_owned.index_within_set(interface_indices[i]));
1218  static_cast<unsigned int>(edge_constrained_indices[j].size()),
1219  data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1220  }
1221  }
1222 
1223 
1224 
1225  template <int dim, typename VectorType>
1226  void
1228  {
1229  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1230  {
1231  const std::vector<unsigned int> &constrained_dofs =
1232  data->get_constrained_dofs(selected_rows[j]);
1233  for (unsigned int i = 0; i < constrained_dofs.size(); ++i)
1234  BlockHelper::subblock(dst, j).local_element(constrained_dofs[i]) = 1.;
1235  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1236  BlockHelper::subblock(dst, j).local_element(
1237  edge_constrained_indices[j][i]) = 1.;
1238  }
1239  }
1240 
1241 
1242 
1243  template <int dim, typename VectorType>
1244  void
1245  Base<dim, VectorType>::vmult(VectorType &dst, const VectorType &src) const
1246  {
1247  using Number = typename Base<dim, VectorType>::value_type;
1248  dst = Number(0.);
1249  vmult_add(dst, src);
1250  }
1251 
1252 
1253 
1254  template <int dim, typename VectorType>
1255  void
1256  Base<dim, VectorType>::vmult_add(VectorType &dst, const VectorType &src) const
1257  {
1258  mult_add(dst, src, false);
1259  }
1260 
1261 
1262 
1263  template <int dim, typename VectorType>
1264  void
1266  const VectorType &src) const
1267  {
1268  mult_add(dst, src, true);
1269  }
1270 
1271 
1272 
1273  template <int dim, typename VectorType>
1274  void
1276  const VectorType &src,
1277  const bool is_row) const
1278  {
1279  using Number = typename Base<dim, VectorType>::value_type;
1280  for (unsigned int i = 0; i < BlockHelper::n_blocks(src); ++i)
1281  {
1282  const unsigned int mf_component =
1283  is_row ? selected_rows[i] : selected_columns[i];
1284  // If both vectors use the same partitioner -> done
1285  if (BlockHelper::subblock(src, i).get_partitioner().get() ==
1286  data->get_dof_info(mf_component).vector_partitioner.get())
1287  continue;
1288 
1289  // If not, assert that the local ranges are the same and reset to the
1290  // current partitioner
1291  Assert(
1292  BlockHelper::subblock(src, i).get_partitioner()->local_size() ==
1293  data->get_dof_info(mf_component).vector_partitioner->local_size(),
1294  ExcMessage("The vector passed to the vmult() function does not have "
1295  "the correct size for compatibility with MatrixFree."));
1296 
1297  // copy the vector content to a temporary vector so that it does not get
1298  // lost
1300  BlockHelper::subblock(src, i));
1301  BlockHelper::subblock(const_cast<VectorType &>(src), i)
1302  .reinit(data->get_dof_info(mf_component).vector_partitioner);
1303  BlockHelper::subblock(const_cast<VectorType &>(src), i)
1304  .copy_locally_owned_data_from(copy_vec);
1305  }
1306  }
1307 
1308 
1309 
1310  template <int dim, typename VectorType>
1311  void
1313  const VectorType &src) const
1314  {
1315  using Number = typename Base<dim, VectorType>::value_type;
1316  adjust_ghost_range_if_necessary(src, false);
1318 
1319  // set zero Dirichlet values on the input vector (and remember the src and
1320  // dst values because we need to reset them at the end)
1321  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1322  {
1323  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1324  {
1325  edge_constrained_values[j][i] = std::pair<Number, Number>(
1326  BlockHelper::subblock(src, j).local_element(
1327  edge_constrained_indices[j][i]),
1328  BlockHelper::subblock(dst, j).local_element(
1329  edge_constrained_indices[j][i]));
1330  BlockHelper::subblock(const_cast<VectorType &>(src), j)
1331  .local_element(edge_constrained_indices[j][i]) = 0.;
1332  }
1333  }
1334  }
1335 
1336 
1337 
1338  template <int dim, typename VectorType>
1339  void
1341  const VectorType &src,
1342  const bool transpose) const
1343  {
1344  AssertDimension(dst.size(), src.size());
1345  AssertDimension(BlockHelper::n_blocks(dst), BlockHelper::n_blocks(src));
1346  AssertDimension(BlockHelper::n_blocks(dst), selected_rows.size());
1347  preprocess_constraints(dst, src);
1348  if (transpose)
1349  Tapply_add(dst, src);
1350  else
1351  apply_add(dst, src);
1352  postprocess_constraints(dst, src);
1353  }
1354 
1355 
1356 
1357  template <int dim, typename VectorType>
1358  void
1360  const VectorType &src) const
1361  {
1362  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1363  {
1364  const std::vector<unsigned int> &constrained_dofs =
1365  data->get_constrained_dofs(selected_rows[j]);
1366  for (unsigned int i = 0; i < constrained_dofs.size(); ++i)
1367  BlockHelper::subblock(dst, j).local_element(constrained_dofs[i]) +=
1368  BlockHelper::subblock(src, j).local_element(constrained_dofs[i]);
1369  }
1370 
1371  // reset edge constrained values, multiply by unit matrix and add into
1372  // destination
1373  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1374  {
1375  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1376  {
1377  BlockHelper::subblock(const_cast<VectorType &>(src), j)
1378  .local_element(edge_constrained_indices[j][i]) =
1379  edge_constrained_values[j][i].first;
1380  BlockHelper::subblock(dst, j).local_element(
1381  edge_constrained_indices[j][i]) =
1382  edge_constrained_values[j][i].second +
1383  edge_constrained_values[j][i].first;
1384  }
1385  }
1386  }
1387 
1388 
1389 
1390  template <int dim, typename VectorType>
1391  void
1393  const VectorType &src) const
1394  {
1395  using Number = typename Base<dim, VectorType>::value_type;
1396  AssertDimension(dst.size(), src.size());
1397  adjust_ghost_range_if_necessary(src, false);
1399 
1400  dst = Number(0.);
1401 
1403  return;
1404 
1405  // set zero Dirichlet values on the input vector (and remember the src and
1406  // dst values because we need to reset them at the end)
1407  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1408  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1409  {
1410  edge_constrained_values[j][i] = std::pair<Number, Number>(
1411  BlockHelper::subblock(src, j).local_element(
1412  edge_constrained_indices[j][i]),
1413  BlockHelper::subblock(dst, j).local_element(
1414  edge_constrained_indices[j][i]));
1415  BlockHelper::subblock(const_cast<VectorType &>(src), j)
1416  .local_element(edge_constrained_indices[j][i]) = 0.;
1417  }
1418 
1419  apply_add(dst, src);
1420 
1421  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1422  {
1423  unsigned int c = 0;
1424  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1425  {
1426  for (; c < edge_constrained_indices[j][i]; ++c)
1427  BlockHelper::subblock(dst, j).local_element(c) = 0.;
1428  ++c;
1429 
1430  // reset the src values
1431  BlockHelper::subblock(const_cast<VectorType &>(src), j)
1432  .local_element(edge_constrained_indices[j][i]) =
1433  edge_constrained_values[j][i].first;
1434  }
1435  for (; c < BlockHelper::subblock(dst, j).local_size(); ++c)
1436  BlockHelper::subblock(dst, j).local_element(c) = 0.;
1437  }
1438  }
1439 
1440 
1441 
1442  template <int dim, typename VectorType>
1443  void
1445  const VectorType &src) const
1446  {
1447  using Number = typename Base<dim, VectorType>::value_type;
1448  AssertDimension(dst.size(), src.size());
1449  adjust_ghost_range_if_necessary(src, false);
1451 
1452  dst = Number(0.);
1453 
1455  return;
1456 
1457  VectorType src_cpy(src);
1458  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1459  {
1460  unsigned int c = 0;
1461  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1462  {
1463  for (; c < edge_constrained_indices[j][i]; ++c)
1464  BlockHelper::subblock(src_cpy, j).local_element(c) = 0.;
1465  ++c;
1466  }
1467  for (; c < BlockHelper::subblock(src_cpy, j).local_size(); ++c)
1468  BlockHelper::subblock(src_cpy, j).local_element(c) = 0.;
1469  }
1470 
1471  apply_add(dst, src_cpy);
1472 
1473  for (unsigned int j = 0; j < BlockHelper::n_blocks(dst); ++j)
1474  for (unsigned int i = 0; i < edge_constrained_indices[j].size(); ++i)
1475  BlockHelper::subblock(dst, j).local_element(
1476  edge_constrained_indices[j][i]) = 0.;
1477  }
1478 
1479 
1480 
1481  template <int dim, typename VectorType>
1482  void
1483  Base<dim, VectorType>::Tvmult(VectorType &dst, const VectorType &src) const
1484  {
1485  using Number = typename Base<dim, VectorType>::value_type;
1486  dst = Number(0.);
1487  Tvmult_add(dst, src);
1488  }
1489 
1490 
1491 
1492  template <int dim, typename VectorType>
1493  std::size_t
1495  {
1496  return inverse_diagonal_entries.get() != nullptr ?
1497  inverse_diagonal_entries->memory_consumption() :
1498  sizeof(*this);
1499  }
1500 
1501 
1502 
1503  template <int dim, typename VectorType>
1504  std::shared_ptr<
1507  {
1508  return data;
1509  }
1510 
1511 
1512 
1513  template <int dim, typename VectorType>
1514  const std::shared_ptr<DiagonalMatrix<VectorType>> &
1516  {
1517  Assert(inverse_diagonal_entries.get() != nullptr &&
1518  inverse_diagonal_entries->m() > 0,
1519  ExcNotInitialized());
1520  return inverse_diagonal_entries;
1521  }
1522 
1523 
1524 
1525  template <int dim, typename VectorType>
1526  const std::shared_ptr<DiagonalMatrix<VectorType>> &
1528  {
1529  Assert(diagonal_entries.get() != nullptr && diagonal_entries->m() > 0,
1530  ExcNotInitialized());
1531  return diagonal_entries;
1532  }
1533 
1534 
1535 
1536  template <int dim, typename VectorType>
1537  void
1539  const VectorType &src) const
1540  {
1541  apply_add(dst, src);
1542  }
1543 
1544 
1545 
1546  template <int dim, typename VectorType>
1547  void
1549  VectorType & dst,
1550  const VectorType & src,
1551  const typename Base<dim, VectorType>::value_type omega) const
1552  {
1554  ExcNotInitialized());
1555  inverse_diagonal_entries->vmult(dst, src);
1556  dst *= omega;
1557  }
1558 
1559 
1560 
1561  //------------------------- MGInterfaceOperator ------------------------------
1562 
1563  template <typename OperatorType>
1565  : Subscriptor()
1566  , mf_base_operator(nullptr)
1567  {}
1568 
1569 
1570 
1571  template <typename OperatorType>
1572  void
1574  {
1575  mf_base_operator = nullptr;
1576  }
1577 
1578 
1579 
1580  template <typename OperatorType>
1581  void
1582  MGInterfaceOperator<OperatorType>::initialize(const OperatorType &operator_in)
1583  {
1584  mf_base_operator = &operator_in;
1585  }
1586 
1587 
1588 
1589  template <typename OperatorType>
1590  template <typename VectorType>
1591  void
1593  const VectorType &src) const
1594  {
1595 #ifndef DEAL_II_MSVC
1596  static_assert(
1597  std::is_same<typename VectorType::value_type, value_type>::value,
1598  "The vector type must be based on the same value type as this"
1599  "operator");
1600 #endif
1601 
1602  Assert(mf_base_operator != nullptr, ExcNotInitialized());
1603 
1604  mf_base_operator->vmult_interface_down(dst, src);
1605  }
1606 
1607 
1608 
1609  template <typename OperatorType>
1610  template <typename VectorType>
1611  void
1613  const VectorType &src) const
1614  {
1615 #ifndef DEAL_II_MSVC
1616  static_assert(
1617  std::is_same<typename VectorType::value_type, value_type>::value,
1618  "The vector type must be based on the same value type as this"
1619  "operator");
1620 #endif
1621 
1622  Assert(mf_base_operator != nullptr, ExcNotInitialized());
1623 
1624  mf_base_operator->vmult_interface_up(dst, src);
1625  }
1626 
1627 
1628 
1629  template <typename OperatorType>
1630  template <typename VectorType>
1631  void
1633  VectorType &vec) const
1634  {
1635  Assert(mf_base_operator != nullptr, ExcNotInitialized());
1636 
1637  mf_base_operator->initialize_dof_vector(vec);
1638  }
1639 
1640 
1641 
1642  //-----------------------------MassOperator----------------------------------
1643 
1644  template <int dim,
1645  int fe_degree,
1646  int n_q_points_1d,
1647  int n_components,
1648  typename VectorType>
1651  : Base<dim, VectorType>()
1652  {}
1653 
1654 
1655 
1656  template <int dim,
1657  int fe_degree,
1658  int n_q_points_1d,
1659  int n_components,
1660  typename VectorType>
1661  void
1664  {
1665  using Number = typename Base<dim, VectorType>::value_type;
1666  Assert((Base<dim, VectorType>::data.get() != nullptr), ExcNotInitialized());
1667 
1669  this->diagonal_entries.reset(new DiagonalMatrix<VectorType>());
1670  VectorType &inverse_diagonal_vector =
1671  this->inverse_diagonal_entries->get_vector();
1672  VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1673  this->initialize_dof_vector(inverse_diagonal_vector);
1674  this->initialize_dof_vector(diagonal_vector);
1675  inverse_diagonal_vector = Number(1.);
1676  apply_add(diagonal_vector, inverse_diagonal_vector);
1677 
1678  this->set_constrained_entries_to_one(diagonal_vector);
1679  inverse_diagonal_vector = diagonal_vector;
1680 
1681  const unsigned int local_size = inverse_diagonal_vector.local_size();
1682  for (unsigned int i = 0; i < local_size; ++i)
1683  inverse_diagonal_vector.local_element(i) =
1684  Number(1.) / inverse_diagonal_vector.local_element(i);
1685 
1686  inverse_diagonal_vector.update_ghost_values();
1687  diagonal_vector.update_ghost_values();
1688  }
1689 
1690 
1691 
1692  template <int dim,
1693  int fe_degree,
1694  int n_q_points_1d,
1695  int n_components,
1696  typename VectorType>
1697  void
1699  apply_add(VectorType &dst, const VectorType &src) const
1700  {
1702  this,
1703  dst,
1704  src);
1705  }
1706 
1707 
1708 
1709  template <int dim,
1710  int fe_degree,
1711  int n_q_points_1d,
1712  int n_components,
1713  typename VectorType>
1714  void
1717  const MatrixFree<dim, typename Base<dim, VectorType>::value_type> &data,
1718  VectorType & dst,
1719  const VectorType & src,
1720  const std::pair<unsigned int, unsigned int> &cell_range) const
1721  {
1722  using Number = typename Base<dim, VectorType>::value_type;
1724  data, this->selected_rows[0]);
1725  for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
1726  {
1727  phi.reinit(cell);
1728  phi.read_dof_values(src);
1729  phi.evaluate(true, false, false);
1730  for (unsigned int q = 0; q < phi.n_q_points; ++q)
1731  phi.submit_value(phi.get_value(q), q);
1732  phi.integrate(true, false);
1733  phi.distribute_local_to_global(dst);
1734  }
1735  }
1736 
1737 
1738  //-----------------------------LaplaceOperator----------------------------------
1739 
1740  template <int dim,
1741  int fe_degree,
1742  int n_q_points_1d,
1743  int n_components,
1744  typename VectorType>
1747  : Base<dim, VectorType>()
1748  {}
1749 
1750 
1751 
1752  template <int dim,
1753  int fe_degree,
1754  int n_q_points_1d,
1755  int n_components,
1756  typename VectorType>
1757  void
1760  {
1762  scalar_coefficient.reset();
1763  }
1764 
1765 
1766 
1767  template <int dim,
1768  int fe_degree,
1769  int n_q_points_1d,
1770  int n_components,
1771  typename VectorType>
1772  void
1775  const std::shared_ptr<
1777  &scalar_coefficient_)
1778  {
1779  scalar_coefficient = scalar_coefficient_;
1780  }
1781 
1782 
1783 
1784  template <int dim,
1785  int fe_degree,
1786  int n_q_points_1d,
1787  int n_components,
1788  typename VectorType>
1789  std::shared_ptr<
1790  Table<2,
1791  VectorizedArray<typename LaplaceOperator<dim,
1792  fe_degree,
1793  n_q_points_1d,
1794  n_components,
1795  VectorType>::value_type>>>
1798  {
1800  return scalar_coefficient;
1801  }
1802 
1803 
1804 
1805  template <int dim,
1806  int fe_degree,
1807  int n_q_points_1d,
1808  int n_components,
1809  typename VectorType>
1810  void
1813  {
1814  using Number = typename Base<dim, VectorType>::value_type;
1815  Assert((Base<dim, VectorType>::data.get() != nullptr), ExcNotInitialized());
1816 
1817  unsigned int dummy = 0;
1819  this->diagonal_entries.reset(new DiagonalMatrix<VectorType>());
1820  VectorType &inverse_diagonal_vector =
1821  this->inverse_diagonal_entries->get_vector();
1822  VectorType &diagonal_vector = this->diagonal_entries->get_vector();
1823  this->initialize_dof_vector(inverse_diagonal_vector);
1824  this->initialize_dof_vector(diagonal_vector);
1825 
1826  this->data->cell_loop(&LaplaceOperator::local_diagonal_cell,
1827  this,
1828  diagonal_vector,
1829  dummy);
1830  this->set_constrained_entries_to_one(diagonal_vector);
1831 
1832  inverse_diagonal_vector = diagonal_vector;
1833 
1834  for (unsigned int i = 0; i < inverse_diagonal_vector.local_size(); ++i)
1835  if (std::abs(inverse_diagonal_vector.local_element(i)) >
1836  std::sqrt(std::numeric_limits<Number>::epsilon()))
1837  inverse_diagonal_vector.local_element(i) =
1838  1. / inverse_diagonal_vector.local_element(i);
1839  else
1840  inverse_diagonal_vector.local_element(i) = 1.;
1841 
1842  inverse_diagonal_vector.update_ghost_values();
1843  diagonal_vector.update_ghost_values();
1844  }
1845 
1846 
1847 
1848  template <int dim,
1849  int fe_degree,
1850  int n_q_points_1d,
1851  int n_components,
1852  typename VectorType>
1853  void
1855  apply_add(VectorType &dst, const VectorType &src) const
1856  {
1858  this,
1859  dst,
1860  src);
1861  }
1862 
1863  namespace Implementation
1864  {
1865  template <typename Number>
1866  bool
1867  non_negative(const VectorizedArray<Number> &n)
1868  {
1869  for (unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements;
1870  ++v)
1871  if (n[v] < 0.)
1872  return false;
1873 
1874  return true;
1875  }
1876  } // namespace Implementation
1877 
1878 
1879 
1880  template <int dim,
1881  int fe_degree,
1882  int n_q_points_1d,
1883  int n_components,
1884  typename VectorType>
1885  void
1888  FEEvaluation<dim,
1889  fe_degree,
1890  n_q_points_1d,
1891  n_components,
1892  typename Base<dim, VectorType>::value_type> &phi,
1893  const unsigned int cell) const
1894  {
1895  phi.evaluate(false, true, false);
1896  if (scalar_coefficient.get())
1897  {
1898  for (unsigned int q = 0; q < phi.n_q_points; ++q)
1899  {
1900  Assert(Implementation::non_negative((*scalar_coefficient)(cell, q)),
1901  ExcMessage("Coefficient must be non-negative"));
1902  phi.submit_gradient((*scalar_coefficient)(cell, q) *
1903  phi.get_gradient(q),
1904  q);
1905  }
1906  }
1907  else
1908  {
1909  for (unsigned int q = 0; q < phi.n_q_points; ++q)
1910  {
1911  phi.submit_gradient(phi.get_gradient(q), q);
1912  }
1913  }
1914  phi.integrate(false, true);
1915  }
1916 
1917 
1918 
1919  template <int dim,
1920  int fe_degree,
1921  int n_q_points_1d,
1922  int n_components,
1923  typename VectorType>
1924  void
1927  const MatrixFree<dim, typename Base<dim, VectorType>::value_type> &data,
1928  VectorType & dst,
1929  const VectorType & src,
1930  const std::pair<unsigned int, unsigned int> &cell_range) const
1931  {
1932  using Number = typename Base<dim, VectorType>::value_type;
1934  data, this->selected_rows[0]);
1935  for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
1936  {
1937  phi.reinit(cell);
1938  phi.read_dof_values(src);
1939  do_operation_on_cell(phi, cell);
1940  phi.distribute_local_to_global(dst);
1941  }
1942  }
1943 
1944 
1945  template <int dim,
1946  int fe_degree,
1947  int n_q_points_1d,
1948  int n_components,
1949  typename VectorType>
1950  void
1953  const MatrixFree<dim, typename Base<dim, VectorType>::value_type> &data,
1954  VectorType & dst,
1955  const unsigned int &,
1956  const std::pair<unsigned int, unsigned int> &cell_range) const
1957  {
1958  using Number = typename Base<dim, VectorType>::value_type;
1960  data, this->selected_rows[0]);
1961  for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
1962  {
1963  phi.reinit(cell);
1964  VectorizedArray<Number> local_diagonal_vector[phi.static_dofs_per_cell];
1965  for (unsigned int i = 0; i < phi.dofs_per_component; ++i)
1966  {
1967  for (unsigned int j = 0; j < phi.dofs_per_component; ++j)
1969  phi.begin_dof_values()[i] = 1.;
1970  do_operation_on_cell(phi, cell);
1971  local_diagonal_vector[i] = phi.begin_dof_values()[i];
1972  }
1973  for (unsigned int i = 0; i < phi.dofs_per_component; ++i)
1974  for (unsigned int c = 0; c < phi.n_components; ++c)
1975  phi.begin_dof_values()[i + c * phi.dofs_per_component] =
1976  local_diagonal_vector[i];
1977  phi.distribute_local_to_global(dst);
1978  }
1979  }
1980 
1981 
1982 } // end of namespace MatrixFreeOperators
1983 
1984 
1985 DEAL_II_NAMESPACE_CLOSE
1986 
1987 #endif
typename OperatorType::value_type value_type
Definition: operators.h:537
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal() const
Definition: operators.h:1527
void fill_inverse_JxW_values(AlignedVector< VectorizedArray< Number >> &inverse_jxw) const
Definition: operators.h:908
static const unsigned int invalid_unsigned_int
Definition: types.h:173
std::vector< unsigned int > selected_rows
Definition: operators.h:445
void do_operation_on_cell(FEEvaluation< dim, fe_degree, n_q_points_1d, n_components, value_type > &phi, const unsigned int cell) const
Definition: operators.h:1887
void vmult_interface_up(VectorType &dst, const VectorType &src) const
Definition: operators.h:1444
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
void initialize_dof_vector(VectorType &vec) const
Definition: operators.h:1632
void Tvmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1612
typename VectorType::size_type size_type
Definition: operators.h:198
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
Definition: utilities.h:353
void gauss_jordan()
void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians=false)
void integrate(const bool integrate_values, const bool integrate_gradients)
typename VectorType::value_type value_type
Definition: operators.h:193
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info() const
static constexpr unsigned int static_dofs_per_cell
#define AssertIndexRange(index, range)
Definition: exceptions.h:1407
size_type n() const
Definition: operators.h:1026
std::vector< std::vector< std::pair< value_type, value_type > > > edge_constrained_values
Definition: operators.h:463
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
Definition: operators.h:1716
void adjust_ghost_range_if_necessary(const VectorType &vec, const bool is_row) const
Definition: operators.h:1275
static::ExceptionBase & ExcNotInitialized()
std::shared_ptr< DiagonalMatrix< VectorType > > inverse_diagonal_entries
Definition: operators.h:439
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
std::shared_ptr< DiagonalMatrix< VectorType > > diagonal_entries
Definition: operators.h:433
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
static constexpr unsigned int n_components
value_type get_value(const unsigned int q_point) const
void postprocess_constraints(VectorType &dst, const VectorType &src) const
Definition: operators.h:1359
typename OperatorType::size_type size_type
Definition: operators.h:542
void resize(const size_type size_in)
AlignedVector< Number > shape_values
Definition: shape_info.h:139
const unsigned int dofs_per_component
void submit_value(const value_type val_in, const unsigned int q_point)
const FEEvaluationBase< dim, n_components, Number > & fe_eval
Definition: operators.h:652
std::vector< unsigned int > selected_columns
Definition: operators.h:451
void Tvmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1483
static::ExceptionBase & ExcMessage(std::string arg1)
const unsigned int n_q_points
size_type n() const
virtual std::size_t memory_consumption() const
Definition: operators.h:1494
void preprocess_constraints(VectorType &dst, const VectorType &src) const
Definition: operators.h:1312
void apply(const AlignedVector< VectorizedArray< Number >> &inverse_coefficient, const unsigned int n_actual_components, const VectorizedArray< Number > *in_array, VectorizedArray< Number > *out_array) const
Definition: operators.h:936
#define Assert(cond, exc)
Definition: exceptions.h:1227
std::shared_ptr< const MatrixFree< dim, value_type > > get_matrix_free() const
Definition: operators.h:1506
void set_coefficient(const std::shared_ptr< Table< 2, VectorizedArray< value_type >>> &scalar_coefficient)
Definition: operators.h:1774
void fill_JxW_values(AlignedVector< VectorizedArray< Number >> &JxW_values) const
std::vector< std::vector< unsigned int > > edge_constrained_indices
Definition: operators.h:457
size_type m() const
AlignedVector< VectorizedArray< Number > > inverse_shape
Definition: operators.h:657
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
void set_constrained_entries_to_one(VectorType &dst) const
Definition: operators.h:1227
void vmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1245
void reinit(const unsigned int cell_batch_index)
void distribute_local_to_global(VectorType &dst, const unsigned int first_index=0) const
virtual void apply_add(VectorType &dst, const VectorType &src) const =0
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > scalar_coefficient
Definition: operators.h:870
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
Definition: operators.h:1952
void vmult_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1256
virtual void compute_diagonal() override
Definition: operators.h:1663
CellwiseInverseMassMatrix(const FEEvaluationBase< dim, n_components, Number > &fe_eval)
Definition: operators.h:879
const VectorizedArray< Number > * begin_dof_values() const
value_type el(const unsigned int row, const unsigned int col) const
Definition: operators.h:1049
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > get_coefficient()
Definition: operators.h:1797
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
Definition: operators.h:1926
void mult_add(VectorType &dst, const VectorType &src, const bool transpose) const
Definition: operators.h:1340
size_type index_within_set(const size_type global_index) const
Definition: index_set.h:1834
void Tvmult_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1265
std::shared_ptr< const MatrixFree< dim, value_type > > data
Definition: operators.h:427
void precondition_Jacobi(VectorType &dst, const VectorType &src, const value_type omega) const
Definition: operators.h:1548
virtual void apply_add(VectorType &dst, const VectorType &src) const override
Definition: operators.h:1699
bool is_element(const size_type index) const
Definition: index_set.h:1676
static::ExceptionBase & ExcNotImplemented()
void vmult_interface_down(VectorType &dst, const VectorType &src) const
Definition: operators.h:1392
Definition: table.h:37
size_type m() const
Definition: operators.h:1013
void initialize(const OperatorType &operator_in)
Definition: operators.h:1582
virtual void clear()
Definition: operators.h:1039
SmartPointer< const OperatorType > mf_base_operator
Definition: operators.h:587
virtual void Tapply_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1538
void initialize_dof_vector(VectorType &vec) const
Definition: operators.h:1064
void vmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1592
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal_inverse() const
Definition: operators.h:1515
T max(const T &t, const MPI_Comm &mpi_communicator)
void initialize(std::shared_ptr< const MatrixFree< dim, value_type >> data, const std::vector< unsigned int > &selected_row_blocks=std::vector< unsigned int >(), const std::vector< unsigned int > &selected_column_blocks=std::vector< unsigned int >())
static::ExceptionBase & ExcInternalError()
virtual void apply_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1855