Reference documentation for deal.II version 9.0.0
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 at
12 // the top level of the deal.II distribution.
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/vectorization.h>
23 #include <deal.II/base/subscriptor.h>
24 
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>
30 
31 
32 DEAL_II_NAMESPACE_OPEN
33 
34 
35 namespace MatrixFreeOperators
36 {
37 
38  namespace
39  {
40  // workaroud for unifying non-block vector and block vector implementations
41  // a non-block vector has one block and the only subblock is the vector itself
42  template <typename VectorType>
43  typename std::enable_if<IsBlockVector<VectorType>::value,
44  unsigned int>::type
45  n_blocks(const VectorType &vector)
46  {
47  return vector.n_blocks();
48  }
49 
50  template <typename VectorType>
51  typename std::enable_if<!IsBlockVector<VectorType>::value,
52  unsigned int>::type
53  n_blocks(const VectorType &)
54  {
55  return 1;
56  }
57 
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)
62  {
63  return vector.block(block_no);
64  }
65 
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)
70  {
71  AssertIndexRange (block_no, vector.n_blocks());
72  return vector.block(block_no);
73  }
74 
75  template <typename VectorType>
76  typename std::enable_if<!IsBlockVector<VectorType>::value,
77  VectorType &>::type
78  subblock(VectorType &vector, unsigned int)
79  {
80  return vector;
81  }
82 
83  template <typename VectorType>
84  typename std::enable_if<!IsBlockVector<VectorType>::value,
85  const VectorType &>::type
86  subblock(const VectorType &vector, unsigned int)
87  {
88  return vector;
89  }
90 
91  template <typename VectorType>
92  typename std::enable_if<IsBlockVector<VectorType>::value,
93  void>::type
94  collect_sizes(VectorType &vector)
95  {
96  vector.collect_sizes();
97  }
98 
99  template <typename VectorType>
100  typename std::enable_if<!IsBlockVector<VectorType>::value,
101  void>::type
102  collect_sizes(const VectorType &)
103  {}
104  }
105 
184  template <int dim, typename VectorType = LinearAlgebra::distributed::Vector<double> >
185  class Base : public Subscriptor
186  {
187  public:
191  typedef typename VectorType::value_type value_type;
192 
196  typedef typename VectorType::size_type size_type;
197 
201  Base ();
202 
206  virtual ~Base() = default;
207 
212  virtual void clear();
213 
230  void initialize (std::shared_ptr<const MatrixFree<dim,value_type> > data,
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>());
233 
247  void initialize (std::shared_ptr<const MatrixFree<dim,value_type> > data,
248  const MGConstrainedDoFs &mg_constrained_dofs,
249  const unsigned int level,
250  const std::vector<unsigned int> &selected_row_blocks = std::vector<unsigned int>());
251 
266  void
267  initialize(std::shared_ptr<const MatrixFree<dim, value_type> > data_,
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>());
271 
275  size_type m () const;
276 
280  size_type n () const;
281 
285  void vmult_interface_down(VectorType &dst,
286  const VectorType &src) const;
287 
291  void vmult_interface_up(VectorType &dst,
292  const VectorType &src) const;
293 
297  void vmult (VectorType &dst,
298  const VectorType &src) const;
299 
303  void Tvmult (VectorType &dst,
304  const VectorType &src) const;
305 
309  void vmult_add (VectorType &dst,
310  const VectorType &src) const;
311 
315  void Tvmult_add (VectorType &dst,
316  const VectorType &src) const;
317 
322  value_type el (const unsigned int row,
323  const unsigned int col) const;
324 
328  virtual std::size_t memory_consumption () const;
329 
333  void initialize_dof_vector (VectorType &vec) const;
334 
341  virtual void compute_diagonal () = 0;
342 
346  std::shared_ptr<const MatrixFree<dim,value_type> >
347  get_matrix_free () const;
348 
352  const std::shared_ptr<DiagonalMatrix<VectorType> > &
354 
358  const std::shared_ptr<DiagonalMatrix<VectorType> > &
359  get_matrix_diagonal() const;
360 
361 
367  void precondition_Jacobi(VectorType &dst,
368  const VectorType &src,
369  const value_type omega) const;
370 
371  protected:
372 
377  void preprocess_constraints(VectorType &dst, const VectorType &src) const;
378 
383  void postprocess_constraints(VectorType &dst, const VectorType &src) const;
384 
389  void set_constrained_entries_to_one (VectorType &dst) const;
390 
394  virtual void apply_add(VectorType &dst,
395  const VectorType &src) const = 0;
396 
402  virtual void Tapply_add(VectorType &dst,
403  const VectorType &src) const;
404 
408  std::shared_ptr<const MatrixFree<dim,value_type> > data;
409 
414  std::shared_ptr<DiagonalMatrix<VectorType > > diagonal_entries;
415 
420  std::shared_ptr<DiagonalMatrix<VectorType > > inverse_diagonal_entries;
421 
426  std::vector<unsigned int> selected_rows;
427 
432  std::vector<unsigned int> selected_columns;
433 
434  private:
435 
439  std::vector<std::vector<unsigned int> > edge_constrained_indices;
440 
444  mutable std::vector<std::vector<std::pair<value_type,value_type> > >
446 
452 
457  void mult_add (VectorType &dst,
458  const VectorType &src,
459  const bool transpose) const;
460 
468  void adjust_ghost_range_if_necessary(const VectorType &vec,
469  const bool is_row) const;
470  };
471 
472 
473 
510  template <typename OperatorType>
512  {
513  public:
517  typedef typename OperatorType::value_type value_type;
518 
522  typedef typename OperatorType::size_type size_type;
523 
528 
532  void clear();
533 
537  void initialize (const OperatorType &operator_in);
538 
542  template <typename VectorType>
543  void vmult (VectorType &dst,
544  const VectorType &src) const;
545 
549  template <typename VectorType>
550  void Tvmult (VectorType &dst,
551  const VectorType &src) const;
552 
556  template <typename VectorType>
557  void initialize_dof_vector (VectorType &vec) const;
558 
559 
560  private:
565  };
566 
567 
568 
588  template <int dim, int fe_degree, int n_components = 1, typename Number = double>
590  {
591  public:
597 
606  void apply(const AlignedVector<VectorizedArray<Number> > &inverse_coefficient,
607  const unsigned int n_actual_components,
608  const VectorizedArray<Number> *in_array,
609  VectorizedArray<Number> *out_array) const;
610 
617 
618  private:
623 
628  };
629 
630 
631 
641  template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, int n_components = 1, typename VectorType = LinearAlgebra::distributed::Vector<double> >
642  class MassOperator : public Base<dim, VectorType>
643  {
644  public:
649 
654 
658  MassOperator ();
659 
663  virtual void compute_diagonal ();
664 
665  private:
671  virtual void apply_add (VectorType &dst,
672  const VectorType &src) const;
673 
678  VectorType &dst,
679  const VectorType &src,
680  const std::pair<unsigned int,unsigned int> &cell_range) const;
681  };
682 
683 
684 
696  template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, int n_components = 1, typename VectorType = LinearAlgebra::distributed::Vector<double> >
697  class LaplaceOperator : public Base<dim, VectorType>
698  {
699  public:
704 
709 
713  LaplaceOperator ();
714 
721  virtual void compute_diagonal ();
722 
766  void set_coefficient(const std::shared_ptr<Table<2, VectorizedArray<value_type> > > &scalar_coefficient );
767 
768  virtual void clear();
769 
776  std::shared_ptr< Table<2, VectorizedArray<value_type> > > get_coefficient();
777 
778  private:
784  virtual void apply_add (VectorType &dst,
785  const VectorType &src) const;
786 
791  VectorType &dst,
792  const VectorType &src,
793  const std::pair<unsigned int,unsigned int> &cell_range) const;
794 
799  VectorType &dst,
800  const unsigned int &,
801  const std::pair<unsigned int,unsigned int> &cell_range) const;
802 
807  const unsigned int cell) const;
808 
812  std::shared_ptr< Table<2, VectorizedArray<value_type> > > scalar_coefficient;
813  };
814 
815 
816 
817  // ------------------------------------ inline functions ---------------------
818 
819  template <int dim, int fe_degree, int n_components, typename Number>
820  inline
823  :
824  fe_eval (fe_eval)
825  {
826  FullMatrix<double> shapes_1d(fe_degree+1, fe_degree+1);
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)
829  shapes_1d(i,j) = fe_eval.get_shape_info().shape_values[c][0];
830  shapes_1d.gauss_jordan();
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)
835  {
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));
840  }
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);
844  }
845 
846 
847 
848  template <int dim, int fe_degree, int n_components, typename Number>
849  inline
850  void
853  {
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"));
858 
859  // temporarily reduce size of inverse_jxw to dofs_per_cell to get JxW values
860  // from fe_eval (will not reallocate any memory)
861  const unsigned int previous_size = inverse_jxw.size();
862  inverse_jxw.resize(dofs_per_cell);
863  fe_eval.fill_JxW_values(inverse_jxw);
864 
865  // invert
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];
869  // copy values to rest of vector
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];
873  }
874 
875 
876 
877  template <int dim, int fe_degree, int n_components, typename Number>
878  inline
879  void
881  ::apply(const AlignedVector<VectorizedArray<Number> > &inverse_coefficients,
882  const unsigned int n_actual_components,
883  const VectorizedArray<Number> *in_array,
884  VectorizedArray<Number> *out_array) const
885  {
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());
892 
893  Assert(dim == 2 || dim == 3, ExcNotImplemented());
894 
896  fe_degree+1, VectorizedArray<Number> >
897  evaluator(inverse_shape, inverse_shape, inverse_shape);
898 
899  const unsigned int shift_coefficient =
900  inverse_coefficients.size() > dofs_per_cell ? dofs_per_cell : 0;
901  const VectorizedArray<Number> *inv_coefficient = &inverse_coefficients[0];
902  VectorizedArray<Number> temp_data_field[dofs_per_cell];
903  for (unsigned int d=0; d<n_actual_components; ++d)
904  {
905  const VectorizedArray<Number> *in = in_array+d*dofs_per_cell;
906  VectorizedArray<Number> *out = out_array+d*dofs_per_cell;
907  // Need to select 'apply' method with hessian slot because values
908  // assume symmetries that do not exist in the inverse shapes
909  evaluator.template hessians<0,false,false> (in, temp_data_field);
910  evaluator.template hessians<1,false,false> (temp_data_field, out);
911 
912  if (dim == 3)
913  {
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);
918  }
919  else if (dim == 2)
920  for (unsigned int q=0; q<dofs_per_cell; ++q)
921  out[q] *= inv_coefficient[q];
922 
923  evaluator.template hessians<1,true,false>(out, temp_data_field);
924  evaluator.template hessians<0,true,false>(temp_data_field, out);
925 
926  inv_coefficient += shift_coefficient;
927  }
928  }
929 
930  //----------------- Base operator -----------------------------
931  template <int dim, typename VectorType>
933  :
934  Subscriptor(),
935  have_interface_matrices(false)
936  {}
937 
938 
939 
940  template <int dim, typename VectorType>
943  {
944  Assert(data.get() != nullptr,
946  typename Base<dim, VectorType>::size_type total_size = 0;
947  for (unsigned int i=0; i<selected_rows.size(); ++i)
948  total_size += data->get_vector_partitioner(selected_rows[i])->size();
949  return total_size;
950  }
951 
952 
953 
954  template <int dim, typename VectorType>
957  {
958  Assert(data.get() != nullptr,
960  typename Base<dim, VectorType>::size_type total_size = 0;
961  for (unsigned int i=0; i<selected_columns.size(); ++i)
962  total_size += data->get_vector_partitioner(selected_columns[i])->size();
963  return total_size;
964  }
965 
966 
967 
968  template <int dim, typename VectorType>
969  void
971  {
972  data.reset();
973  inverse_diagonal_entries.reset();
974  }
975 
976 
977 
978  template <int dim, typename VectorType>
980  Base<dim,VectorType>::el (const unsigned int row,
981  const unsigned int col) const
982  {
983  (void) col;
984  Assert (row == col, ExcNotImplemented());
985  Assert (inverse_diagonal_entries.get() != nullptr &&
986  inverse_diagonal_entries->m() > 0, ExcNotInitialized());
987  return 1.0/(*inverse_diagonal_entries)(row,row);
988  }
989 
990 
991 
992  template <int dim, typename VectorType>
993  void
995  {
996  Assert(data.get() != nullptr,
998  AssertDimension(n_blocks(vec), selected_rows.size());
999  for (unsigned int i = 0; i < n_blocks(vec); ++i)
1000  {
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);
1005 
1006  Assert(subblock(vec,index).partitioners_are_globally_compatible
1007  (*data->get_dof_info(index).vector_partitioner),
1008  ExcInternalError());
1009  }
1010  collect_sizes(vec);
1011  }
1012 
1013 
1014 
1015  template <int dim, typename VectorType>
1016  void
1018  initialize (std::shared_ptr<const MatrixFree<dim,typename Base<dim,VectorType>::value_type> > data_,
1019  const std::vector<unsigned int> &given_row_selection,
1020  const std::vector<unsigned int> &given_column_selection)
1021  {
1022  data = data_;
1023 
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);
1029  else
1030  {
1031  for (unsigned int i=0; i<given_row_selection.size(); ++i)
1032  {
1033  AssertIndexRange(given_row_selection[i], data_->n_components());
1034  for (unsigned int j=0; j<given_row_selection.size(); ++j)
1035  if (j!=i)
1036  Assert(given_row_selection[j] != given_row_selection[i],
1037  ExcMessage("Given row indices must be unique"));
1038 
1039  selected_rows.push_back(given_row_selection[i]);
1040  }
1041  }
1042  if (given_column_selection.size() == 0)
1043  selected_columns = selected_rows;
1044  else
1045  {
1046  for (unsigned int i=0; i<given_column_selection.size(); ++i)
1047  {
1048  AssertIndexRange(given_column_selection[i], data_->n_components());
1049  for (unsigned int j=0; j<given_column_selection.size(); ++j)
1050  if (j!=i)
1051  Assert(given_column_selection[j] != given_column_selection[i],
1052  ExcMessage("Given column indices must be unique"));
1053 
1054  selected_columns.push_back(given_column_selection[i]);
1055  }
1056  }
1057 
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;
1063  }
1064 
1065 
1066 
1067  template <int dim, typename VectorType>
1068  void
1070  initialize (std::shared_ptr<const MatrixFree<dim,typename Base<dim,VectorType>::value_type> > data_,
1071  const MGConstrainedDoFs &mg_constrained_dofs,
1072  const unsigned int level,
1073  const std::vector<unsigned int> &given_row_selection)
1074  {
1075  std::vector<MGConstrainedDoFs> mg_constrained_dofs_vector(1, mg_constrained_dofs);
1076  initialize(data_, mg_constrained_dofs_vector, level, given_row_selection);
1077  }
1078 
1079 
1080 
1081  template <int dim, typename VectorType>
1082  void
1084  initialize (std::shared_ptr<const MatrixFree<dim, value_type> > data_,
1085  const std::vector<MGConstrainedDoFs> &mg_constrained_dofs,
1086  const unsigned int level,
1087  const std::vector<unsigned int> &given_row_selection)
1088  {
1090  ExcMessage("level is not set"));
1091 
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);
1097  else
1098  {
1099  for (unsigned int i=0; i<given_row_selection.size(); ++i)
1100  {
1101  AssertIndexRange(given_row_selection[i], data_->n_components());
1102  for (unsigned int j=0; j<given_row_selection.size(); ++j)
1103  if (j!=i)
1104  Assert(given_row_selection[j] != given_row_selection[i],
1105  ExcMessage("Given row indices must be unique"));
1106 
1107  selected_rows.push_back(given_row_selection[i]);
1108  }
1109  }
1110  selected_columns = selected_rows;
1111 
1112  AssertDimension(mg_constrained_dofs.size(), selected_rows.size());
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());
1117 
1118  data = data_;
1119 
1120  for (unsigned int j = 0; j < selected_rows.size(); ++j)
1121  {
1122  if (data_->n_macro_cells() > 0)
1123  {
1124  AssertDimension(static_cast<int>(level),
1125  data_->get_cell_iterator(0,0,j)->level());
1126  }
1127 
1128  // setup edge_constrained indices
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
1139  (locally_owned.index_within_set(interface_indices[i]));
1140  have_interface_matrices |=
1141  Utilities::MPI::max(static_cast<unsigned int>(edge_constrained_indices[j].size()),
1142  data->get_vector_partitioner()->get_mpi_communicator()) > 0;
1143  }
1144  }
1145 
1146 
1147 
1148  template <int dim, typename VectorType>
1149  void
1151  {
1152  for (unsigned int j=0; j<n_blocks(dst); ++j)
1153  {
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.;
1160  }
1161  }
1162 
1163 
1164 
1165  template <int dim, typename VectorType>
1166  void
1168  const VectorType &src) const
1169  {
1170  typedef typename Base<dim,VectorType>::value_type Number;
1171  dst = Number(0.);
1172  vmult_add (dst, src);
1173  }
1174 
1175 
1176 
1177  template <int dim, typename VectorType>
1178  void
1180  const VectorType &src) const
1181  {
1182  mult_add (dst, src, false);
1183  }
1184 
1185 
1186 
1187  template <int dim, typename VectorType>
1188  void
1190  const VectorType &src) const
1191  {
1192  mult_add (dst, src, true);
1193  }
1194 
1195 
1196 
1197  template <int dim, typename VectorType>
1198  void
1200  const bool is_row) const
1201  {
1202  typedef typename Base<dim,VectorType>::value_type Number;
1203  for (unsigned int i=0; i<n_blocks(src); ++i)
1204  {
1205  const unsigned int mf_component = is_row ? selected_rows[i] : selected_columns[i];
1206  // If both vectors use the same partitioner -> done
1207  if (subblock(src,i).get_partitioner().get() ==
1208  data->get_dof_info(mf_component).vector_partitioner.get())
1209  continue;
1210 
1211  // If not, assert that the local ranges are the same and reset to the
1212  // current partitioner
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."));
1217 
1218  // copy the vector content to a temporary vector so that it does not get
1219  // lost
1220  LinearAlgebra::distributed::Vector<Number> copy_vec(subblock(src,i));
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);
1224  }
1225  }
1226 
1227 
1228 
1229  template <int dim, typename VectorType>
1230  void
1232  const VectorType &src) const
1233  {
1234  typedef typename Base<dim,VectorType>::value_type Number;
1235  adjust_ghost_range_if_necessary(src, false);
1236  adjust_ghost_range_if_necessary(dst, true);
1237 
1238  // set zero Dirichlet values on the input vector (and remember the src and
1239  // dst values because we need to reset them at the end)
1240  for (unsigned int j=0; j<n_blocks(dst); ++j)
1241  {
1242  for (unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1243  {
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.;
1249  }
1250  }
1251  }
1252 
1253 
1254 
1255  template <int dim, typename VectorType>
1256  void
1258  const VectorType &src,
1259  const bool transpose) const
1260  {
1261  AssertDimension(dst.size(), src.size());
1262  AssertDimension(n_blocks(dst), n_blocks(src));
1263  AssertDimension(n_blocks(dst), selected_rows.size());
1264  preprocess_constraints (dst,src);
1265  if (transpose)
1266  Tapply_add(dst,src);
1267  else
1268  apply_add(dst,src);
1269  postprocess_constraints(dst,src);
1270  }
1271 
1272 
1273 
1274  template <int dim, typename VectorType>
1275  void
1277  const VectorType &src) const
1278  {
1279  for (unsigned int j=0; j<n_blocks(dst); ++j)
1280  {
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]);
1286  }
1287 
1288  // reset edge constrained values, multiply by unit matrix and add into
1289  // destination
1290  for (unsigned int j=0; j<n_blocks(dst); ++j)
1291  {
1292  for (unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1293  {
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;
1300  }
1301  }
1302  }
1303 
1304 
1305 
1306  template <int dim, typename VectorType>
1307  void
1309  vmult_interface_down(VectorType &dst,
1310  const VectorType &src) const
1311  {
1312  typedef typename Base<dim,VectorType>::value_type Number;
1313  AssertDimension(dst.size(), src.size());
1314  adjust_ghost_range_if_necessary(src, false);
1315  adjust_ghost_range_if_necessary(dst, true);
1316 
1317  dst = Number(0.);
1318 
1319  if (!have_interface_matrices)
1320  return;
1321 
1322  // set zero Dirichlet values on the input vector (and remember the src and
1323  // dst values because we need to reset them at the end)
1324  for (unsigned int j=0; j<n_blocks(dst); ++j)
1325  for (unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1326  {
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.;
1333  }
1334 
1335  apply_add(dst,src);
1336 
1337  for (unsigned int j=0; j<n_blocks(dst); ++j)
1338  {
1339  unsigned int c=0;
1340  for (unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1341  {
1342  for ( ; c<edge_constrained_indices[j][i]; ++c)
1343  subblock(dst,j).local_element(c) = 0.;
1344  ++c;
1345 
1346  // reset the src values
1347  subblock(const_cast<VectorType &>(src),j)
1348  .local_element(edge_constrained_indices[j][i])
1349  = edge_constrained_values[j][i].first;
1350  }
1351  for ( ; c<subblock(dst,j).local_size(); ++c)
1352  subblock(dst,j).local_element(c) = 0.;
1353  }
1354  }
1355 
1356 
1357 
1358  template <int dim, typename VectorType>
1359  void
1361  vmult_interface_up(VectorType &dst,
1362  const VectorType &src) const
1363  {
1364  typedef typename Base<dim,VectorType>::value_type Number;
1365  AssertDimension(dst.size(), src.size());
1366  adjust_ghost_range_if_necessary(src, false);
1367  adjust_ghost_range_if_necessary(dst, true);
1368 
1369  dst = Number(0.);
1370 
1371  if (!have_interface_matrices)
1372  return;
1373 
1374  VectorType src_cpy (src);
1375  for (unsigned int j=0; j<n_blocks(dst); ++j)
1376  {
1377  unsigned int c=0;
1378  for (unsigned int i=0; i<edge_constrained_indices[j].size(); ++i)
1379  {
1380  for ( ; c<edge_constrained_indices[j][i]; ++c)
1381  subblock(src_cpy,j).local_element(c) = 0.;
1382  ++c;
1383  }
1384  for ( ; c<subblock(src_cpy,j).local_size(); ++c)
1385  subblock(src_cpy,j).local_element(c) = 0.;
1386  }
1387 
1388  apply_add(dst,src_cpy);
1389 
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.;
1393  }
1394 
1395 
1396 
1397  template <int dim, typename VectorType>
1398  void
1400  const VectorType &src) const
1401  {
1402  typedef typename Base<dim,VectorType>::value_type Number;
1403  dst = Number(0.);
1404  Tvmult_add (dst,src);
1405  }
1406 
1407 
1408 
1409  template <int dim, typename VectorType>
1410  std::size_t
1412  {
1413  return inverse_diagonal_entries.get() != nullptr ?
1414  inverse_diagonal_entries->memory_consumption() : sizeof(*this);
1415  }
1416 
1417 
1418 
1419  template <int dim, typename VectorType>
1420  std::shared_ptr<const MatrixFree<dim,typename Base<dim,VectorType>::value_type> >
1422  {
1423  return data;
1424  }
1425 
1426 
1427 
1428  template <int dim, typename VectorType>
1429  const std::shared_ptr<DiagonalMatrix<VectorType> > &
1431  {
1432  Assert(inverse_diagonal_entries.get() != nullptr &&
1433  inverse_diagonal_entries->m() > 0, ExcNotInitialized());
1434  return inverse_diagonal_entries;
1435  }
1436 
1437 
1438 
1439  template <int dim, typename VectorType>
1440  const std::shared_ptr<DiagonalMatrix<VectorType> > &
1442  {
1443  Assert(diagonal_entries.get() != nullptr &&
1444  diagonal_entries->m() > 0, ExcNotInitialized());
1445  return diagonal_entries;
1446  }
1447 
1448 
1449 
1450  template <int dim, typename VectorType>
1451  void
1453  const VectorType &src) const
1454  {
1455  apply_add(dst,src);
1456  }
1457 
1458 
1459 
1460  template <int dim, typename VectorType>
1461  void
1463  const VectorType &src,
1464  const typename Base<dim,VectorType>::value_type omega) const
1465  {
1466  Assert(inverse_diagonal_entries.get() &&
1467  inverse_diagonal_entries->m() > 0, ExcNotInitialized());
1468  inverse_diagonal_entries->vmult(dst,src);
1469  dst *= omega;
1470  }
1471 
1472 
1473 
1474  //------------------------- MGInterfaceOperator ------------------------------
1475 
1476  template <typename OperatorType>
1478  :
1479  Subscriptor(),
1480  mf_base_operator(nullptr)
1481  {
1482  }
1483 
1484 
1485 
1486  template <typename OperatorType>
1487  void
1489  {
1490  mf_base_operator = nullptr;
1491  }
1492 
1493 
1494 
1495  template <typename OperatorType>
1496  void
1497  MGInterfaceOperator<OperatorType>::initialize (const OperatorType &operator_in)
1498  {
1499  mf_base_operator = &operator_in;
1500  }
1501 
1502 
1503 
1504  template <typename OperatorType>
1505  template <typename VectorType>
1506  void
1508  const VectorType &src) const
1509  {
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"
1513  "operator");
1514 #endif
1515 
1516  Assert(mf_base_operator != nullptr,
1517  ExcNotInitialized());
1518 
1519  mf_base_operator->vmult_interface_down(dst, src);
1520  }
1521 
1522 
1523 
1524  template <typename OperatorType>
1525  template <typename VectorType>
1526  void
1528  const VectorType &src) const
1529  {
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"
1533  "operator");
1534 #endif
1535 
1536  Assert(mf_base_operator != nullptr,
1537  ExcNotInitialized());
1538 
1539  mf_base_operator->vmult_interface_up(dst, src);
1540  }
1541 
1542 
1543 
1544  template <typename OperatorType>
1545  template <typename VectorType>
1546  void
1548  {
1549  Assert(mf_base_operator != nullptr,
1550  ExcNotInitialized());
1551 
1552  mf_base_operator->initialize_dof_vector(vec);
1553  }
1554 
1555 
1556 
1557  //-----------------------------MassOperator----------------------------------
1558 
1559  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1562  :
1563  Base<dim, VectorType>()
1564  {}
1565 
1566 
1567 
1568  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1569  void
1572  {
1573  typedef typename Base<dim,VectorType>::value_type Number;
1574  Assert((Base<dim, VectorType>::data.get() != nullptr), ExcNotInitialized());
1575 
1576  this->inverse_diagonal_entries.
1577  reset(new DiagonalMatrix<VectorType>());
1578  this->diagonal_entries.
1579  reset(new DiagonalMatrix<VectorType>());
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);
1586 
1587  this->set_constrained_entries_to_one(diagonal_vector);
1588  inverse_diagonal_vector = diagonal_vector;
1589 
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);
1594 
1595  inverse_diagonal_vector.update_ghost_values();
1596  diagonal_vector.update_ghost_values();
1597  }
1598 
1599 
1600 
1601  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1602  void
1604  apply_add (VectorType &dst,
1605  const VectorType &src) const
1606  {
1608  this, dst, src);
1609  }
1610 
1611 
1612 
1613  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1614  void
1617  VectorType &dst,
1618  const VectorType &src,
1619  const std::pair<unsigned int,unsigned int> &cell_range) const
1620  {
1621  typedef typename Base<dim,VectorType>::value_type Number;
1623  for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
1624  {
1625  phi.reinit (cell);
1626  phi.read_dof_values(src);
1627  phi.evaluate (true,false,false);
1628  for (unsigned int q=0; q<phi.n_q_points; ++q)
1629  phi.submit_value (phi.get_value(q), q);
1630  phi.integrate (true,false);
1631  phi.distribute_local_to_global (dst);
1632  }
1633  }
1634 
1635 
1636  //-----------------------------LaplaceOperator----------------------------------
1637 
1638  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1641  :
1642  Base<dim, VectorType>()
1643  {
1644  }
1645 
1646 
1647 
1648  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1649  void
1652  {
1654  scalar_coefficient.reset();
1655  }
1656 
1657 
1658 
1659  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1660  void
1662  set_coefficient(const std::shared_ptr<Table<2, VectorizedArray<typename Base<dim,VectorType>::value_type> > > &scalar_coefficient_ )
1663  {
1664  scalar_coefficient = scalar_coefficient_;
1665  }
1666 
1667 
1668 
1669  template <int dim, int fe_degree, int n_q_points_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> > >
1673  {
1674  Assert (scalar_coefficient.get(),
1675  ExcNotInitialized());
1676  return scalar_coefficient;
1677  }
1678 
1679 
1680 
1681  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1682  void
1685  {
1686  typedef typename Base<dim,VectorType>::value_type Number;
1687  Assert((Base<dim, VectorType>::data.get() != nullptr), ExcNotInitialized());
1688 
1689  unsigned int dummy = 0;
1690  this->inverse_diagonal_entries.
1691  reset(new DiagonalMatrix<VectorType>());
1692  this->diagonal_entries.
1693  reset(new DiagonalMatrix<VectorType>());
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);
1698 
1699  this->data->cell_loop (&LaplaceOperator::local_diagonal_cell,
1700  this, diagonal_vector, dummy);
1701  this->set_constrained_entries_to_one(diagonal_vector);
1702 
1703  inverse_diagonal_vector = diagonal_vector;
1704 
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);
1708  else
1709  inverse_diagonal_vector.local_element(i) = 1.;
1710 
1711  inverse_diagonal_vector.update_ghost_values();
1712  diagonal_vector.update_ghost_values();
1713  }
1714 
1715 
1716 
1717  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1718  void
1720  apply_add (VectorType &dst,
1721  const VectorType &src) const
1722  {
1724  this, dst, src);
1725  }
1726 
1727  namespace
1728  {
1729  template <typename Number>
1730  bool
1731  non_negative(const VectorizedArray<Number> &n)
1732  {
1733  for (unsigned int v=0; v<VectorizedArray<Number>::n_array_elements; ++v)
1734  if (n[v] < 0.)
1735  return false;
1736 
1737  return true;
1738  }
1739  }
1740 
1741 
1742 
1743  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1744  void
1746  do_operation_on_cell(FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,typename Base<dim,VectorType>::value_type> &phi,
1747  const unsigned int cell) const
1748  {
1749  phi.evaluate (false,true,false);
1750  if (scalar_coefficient.get())
1751  {
1752  for (unsigned int q=0; q<phi.n_q_points; ++q)
1753  {
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);
1757  }
1758  }
1759  else
1760  {
1761  for (unsigned int q=0; q<phi.n_q_points; ++q)
1762  {
1763  phi.submit_gradient (phi.get_gradient(q), q);
1764  }
1765  }
1766  phi.integrate (false,true);
1767  }
1768 
1769 
1770 
1771 
1772  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1773  void
1776  VectorType &dst,
1777  const VectorType &src,
1778  const std::pair<unsigned int,unsigned int> &cell_range) const
1779  {
1780  typedef typename Base<dim,VectorType>::value_type Number;
1781  FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,Number> phi (data, this->selected_rows[0]);
1782  for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
1783  {
1784  phi.reinit (cell);
1785  phi.read_dof_values(src);
1786  do_operation_on_cell(phi,cell);
1787  phi.distribute_local_to_global (dst);
1788  }
1789  }
1790 
1791 
1792  template <int dim, int fe_degree, int n_q_points_1d, int n_components, typename VectorType>
1793  void
1796  VectorType &dst,
1797  const unsigned int &,
1798  const std::pair<unsigned int,unsigned int> &cell_range) const
1799  {
1800  typedef typename Base<dim,VectorType>::value_type Number;
1801  FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,Number> phi (data, this->selected_rows[0]);
1802  for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
1803  {
1804  phi.reinit (cell);
1805  VectorizedArray<Number> local_diagonal_vector[phi.static_dofs_per_cell];
1806  for (unsigned int i=0; i<phi.dofs_per_component; ++i)
1807  {
1808  for (unsigned int j=0; j<phi.dofs_per_component; ++j)
1810  phi.begin_dof_values()[i] = 1.;
1811  do_operation_on_cell(phi,cell);
1812  local_diagonal_vector[i] = phi.begin_dof_values()[i];
1813  }
1814  for (unsigned int i=0; i<phi.dofs_per_component; ++i)
1815  for (unsigned int c=0; c<phi.n_components; ++c)
1816  phi.begin_dof_values()[i+c*phi.dofs_per_component] = local_diagonal_vector[i];
1817  phi.distribute_local_to_global (dst);
1818  }
1819  }
1820 
1821 
1822 } // end of namespace MatrixFreeOperators
1823 
1824 
1825 DEAL_II_NAMESPACE_CLOSE
1826 
1827 #endif
std::shared_ptr< const MatrixFree< dim, value_type > > data
Definition: operators.h:408
size_type m() const
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:1746
static const unsigned int invalid_unsigned_int
Definition: types.h:173
void vmult_interface_down(VectorType &dst, const VectorType &src) const
Definition: operators.h:1309
OperatorType::value_type value_type
Definition: operators.h:517
std::vector< unsigned int > selected_rows
Definition: operators.h:426
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
void set_coefficient(const std::shared_ptr< Table< 2, VectorizedArray< value_type > > > &scalar_coefficient)
Definition: operators.h:1662
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
Definition: operators.h:1720
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:1775
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:881
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal_inverse() const
Definition: operators.h:1430
constexpr unsigned int pow(const unsigned int base, const unsigned int iexp)
Definition: utilities.h:354
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)
void precondition_Jacobi(VectorType &dst, const VectorType &src, const value_type omega) const
Definition: operators.h:1462
static constexpr unsigned int static_dofs_per_cell
#define AssertIndexRange(index, range)
Definition: exceptions.h:1284
OperatorType::size_type size_type
Definition: operators.h:522
const FEEvaluationBase< dim, n_components, Number > & fe_eval
Definition: operators.h:622
void mult_add(VectorType &dst, const VectorType &src, const bool transpose) const
Definition: operators.h:1257
const VectorizedArray< Number > * begin_dof_values() const
const std::shared_ptr< DiagonalMatrix< VectorType > > & get_matrix_diagonal() const
Definition: operators.h:1441
static ::ExceptionBase & ExcNotInitialized()
void vmult_interface_up(VectorType &dst, const VectorType &src) const
Definition: operators.h:1361
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
void set_constrained_entries_to_one(VectorType &dst) const
Definition: operators.h:1150
void read_dof_values(const VectorType &src, const unsigned int first_index=0)
static constexpr unsigned int n_components
AlignedVector< Number > shape_values
Definition: shape_info.h:136
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
Definition: operators.h:414
Base< dim, VectorType >::value_type value_type
Definition: operators.h:648
void initialize_dof_vector(VectorType &vec) const
Definition: operators.h:1547
std::vector< unsigned int > selected_columns
Definition: operators.h:432
value_type el(const unsigned int row, const unsigned int col) const
Definition: operators.h:980
VectorType::value_type value_type
Definition: operators.h:191
static ::ExceptionBase & ExcMessage(std::string arg1)
const unsigned int n_q_points
size_type n() const
Definition: operators.h:956
size_type n() const
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info() const
virtual void Tapply_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1452
void Tvmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1399
#define Assert(cond, exc)
Definition: exceptions.h:1142
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:1795
size_type index_within_set(const size_type global_index) const
Definition: index_set.h:1811
virtual void compute_diagonal()=0
VectorType::size_type size_type
Definition: operators.h:196
std::vector< std::vector< unsigned int > > edge_constrained_indices
Definition: operators.h:439
AlignedVector< VectorizedArray< Number > > inverse_shape
Definition: operators.h:627
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
void Tvmult_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1189
virtual void apply_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1604
Base< dim, VectorType >::size_type size_type
Definition: operators.h:708
void vmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1167
size_type m() const
Definition: operators.h:942
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
Definition: operators.h:1507
void preprocess_constraints(VectorType &dst, const VectorType &src) const
Definition: operators.h:1231
CellwiseInverseMassMatrix(const FEEvaluationBase< dim, n_components, Number > &fe_eval)
Definition: operators.h:822
std::vector< std::vector< std::pair< value_type, value_type > > > edge_constrained_values
Definition: operators.h:445
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:1616
std::shared_ptr< const MatrixFree< dim, value_type > > get_matrix_free() const
Definition: operators.h:1421
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > get_coefficient()
Definition: operators.h:1672
virtual std::size_t memory_consumption() const
Definition: operators.h:1411
void fill_inverse_JxW_values(AlignedVector< VectorizedArray< Number > > &inverse_jxw) const
Definition: operators.h:852
void postprocess_constraints(VectorType &dst, const VectorType &src) const
Definition: operators.h:1276
static ::ExceptionBase & ExcNotImplemented()
Base< dim, VectorType >::value_type value_type
Definition: operators.h:703
Definition: table.h:34
bool is_element(const size_type index) const
Definition: index_set.h:1645
void adjust_ghost_range_if_necessary(const VectorType &vec, const bool is_row) const
Definition: operators.h:1199
void vmult_add(VectorType &dst, const VectorType &src) const
Definition: operators.h:1179
void initialize(const OperatorType &operator_in)
Definition: operators.h:1497
virtual void clear()
Definition: operators.h:970
SmartPointer< const OperatorType > mf_base_operator
Definition: operators.h:564
Base< dim, VectorType >::size_type size_type
Definition: operators.h:653
void Tvmult(VectorType &dst, const VectorType &src) const
Definition: operators.h:1527
std::shared_ptr< DiagonalMatrix< VectorType > > inverse_diagonal_entries
Definition: operators.h:420
void initialize_dof_vector(VectorType &vec) const
Definition: operators.h:994
std::shared_ptr< Table< 2, VectorizedArray< value_type > > > scalar_coefficient
Definition: operators.h:812
T max(const T &t, const MPI_Comm &mpi_communicator)
static ::ExceptionBase & ExcInternalError()
virtual ~Base()=default