Reference documentation for deal.II version 8.5.1
matrix_free.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2017 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_h
18 #define dealii__matrix_free_h
19 
20 #include <deal.II/base/aligned_vector.h>
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/parallel.h>
23 #include <deal.II/base/quadrature.h>
24 #include <deal.II/base/vectorization.h>
25 #include <deal.II/base/thread_local_storage.h>
26 #include <deal.II/base/template_constraints.h>
27 #include <deal.II/fe/fe.h>
28 #include <deal.II/fe/mapping.h>
29 #include <deal.II/fe/mapping_q1.h>
30 #include <deal.II/lac/vector.h>
31 #include <deal.II/lac/la_parallel_vector.h>
32 #include <deal.II/lac/block_vector_base.h>
33 #include <deal.II/lac/constraint_matrix.h>
34 #include <deal.II/dofs/dof_handler.h>
35 #include <deal.II/hp/dof_handler.h>
36 #include <deal.II/hp/q_collection.h>
37 #include <deal.II/matrix_free/helper_functions.h>
38 #include <deal.II/matrix_free/shape_info.h>
39 #include <deal.II/matrix_free/dof_info.h>
40 #include <deal.II/matrix_free/mapping_info.h>
41 
42 #ifdef DEAL_II_WITH_THREADS
43 #include <tbb/task.h>
44 #include <tbb/task_scheduler_init.h>
45 #include <tbb/parallel_for.h>
46 #include <tbb/blocked_range.h>
47 #endif
48 
49 #include <stdlib.h>
50 #include <memory>
51 #include <limits>
52 #include <list>
53 
54 
55 DEAL_II_NAMESPACE_OPEN
56 
57 
58 
108 template <int dim, typename Number=double>
109 class MatrixFree : public Subscriptor
110 {
111 public:
112 
142  {
149  {
167  };
168 
169  // avoid warning about use of deprecated variables
170  DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
171 
176  const unsigned int tasks_block_size = 0,
178  const unsigned int level_mg_handler = numbers::invalid_unsigned_int,
179  const bool store_plain_indices = true,
180  const bool initialize_indices = true,
181  const bool initialize_mapping = true)
182  :
183  mpi_communicator (MPI_COMM_SELF),
191  {};
192 
201  const unsigned int tasks_block_size = 0,
203  const unsigned int level_mg_handler = numbers::invalid_unsigned_int,
204  const bool store_plain_indices = true,
205  const bool initialize_indices = true,
206  const bool initialize_mapping = true)
207  :
216  {} DEAL_II_DEPRECATED
217 
227  MPI_Comm mpi_communicator DEAL_II_DEPRECATED;
228 
258 
268  unsigned int tasks_block_size;
269 
282 
291  unsigned int level_mg_handler;
292 
300 
310 
318  };
319 
320  DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
321 
329  MatrixFree ();
330 
334  MatrixFree (const MatrixFree<dim,Number> &other);
335 
339  ~MatrixFree();
340 
352  template <typename DoFHandlerType, typename QuadratureType>
353  void reinit (const Mapping<dim> &mapping,
354  const DoFHandlerType &dof_handler,
355  const ConstraintMatrix &constraint,
356  const QuadratureType &quad,
357  const AdditionalData additional_data = AdditionalData());
358 
363  template <typename DoFHandlerType, typename QuadratureType>
364  void reinit (const DoFHandlerType &dof_handler,
365  const ConstraintMatrix &constraint,
366  const QuadratureType &quad,
367  const AdditionalData additional_data = AdditionalData());
368 
376  template <typename DoFHandlerType, typename QuadratureType>
377  void reinit (const Mapping<dim> &mapping,
378  const DoFHandlerType &dof_handler,
379  const ConstraintMatrix &constraint,
380  const IndexSet &locally_owned_dofs,
381  const QuadratureType &quad,
382  const AdditionalData additional_data = AdditionalData()) DEAL_II_DEPRECATED;
383 
404  template <typename DoFHandlerType, typename QuadratureType>
405  void reinit (const Mapping<dim> &mapping,
406  const std::vector<const DoFHandlerType *> &dof_handler,
407  const std::vector<const ConstraintMatrix *> &constraint,
408  const std::vector<QuadratureType> &quad,
409  const AdditionalData additional_data = AdditionalData());
410 
415  template <typename DoFHandlerType, typename QuadratureType>
416  void reinit (const std::vector<const DoFHandlerType *> &dof_handler,
417  const std::vector<const ConstraintMatrix *> &constraint,
418  const std::vector<QuadratureType> &quad,
419  const AdditionalData additional_data = AdditionalData());
420 
428  template <typename DoFHandlerType, typename QuadratureType>
429  void reinit (const Mapping<dim> &mapping,
430  const std::vector<const DoFHandlerType *> &dof_handler,
431  const std::vector<const ConstraintMatrix *> &constraint,
432  const std::vector<IndexSet> &locally_owned_set,
433  const std::vector<QuadratureType> &quad,
434  const AdditionalData additional_data = AdditionalData()) DEAL_II_DEPRECATED;
435 
443  template <typename DoFHandlerType, typename QuadratureType>
444  void reinit (const Mapping<dim> &mapping,
445  const std::vector<const DoFHandlerType *> &dof_handler,
446  const std::vector<const ConstraintMatrix *> &constraint,
447  const QuadratureType &quad,
448  const AdditionalData additional_data = AdditionalData());
449 
454  template <typename DoFHandlerType, typename QuadratureType>
455  void reinit (const std::vector<const DoFHandlerType *> &dof_handler,
456  const std::vector<const ConstraintMatrix *> &constraint,
457  const QuadratureType &quad,
458  const AdditionalData additional_data = AdditionalData());
459 
465  void copy_from (const MatrixFree<dim,Number> &matrix_free_base);
466 
471  void clear();
472 
474 
492  template <typename OutVector, typename InVector>
493  void cell_loop (const std_cxx11::function<void (const MatrixFree<dim,Number> &,
494  OutVector &,
495  const InVector &,
496  const std::pair<unsigned int,
497  unsigned int> &)> &cell_operation,
498  OutVector &dst,
499  const InVector &src) const;
500 
510  template <typename CLASS, typename OutVector, typename InVector>
511  void cell_loop (void (CLASS::*function_pointer)(const MatrixFree &,
512  OutVector &,
513  const InVector &,
514  const std::pair<unsigned int,
515  unsigned int> &)const,
516  const CLASS *owning_class,
517  OutVector &dst,
518  const InVector &src) const;
519 
523  template <typename CLASS, typename OutVector, typename InVector>
524  void cell_loop (void (CLASS::*function_pointer)(const MatrixFree &,
525  OutVector &,
526  const InVector &,
527  const std::pair<unsigned int,
528  unsigned int> &),
529  CLASS *owning_class,
530  OutVector &dst,
531  const InVector &src) const;
532 
540  std::pair<unsigned int,unsigned int>
541  create_cell_subrange_hp (const std::pair<unsigned int,unsigned int> &range,
542  const unsigned int fe_degree,
543  const unsigned int vector_component = 0) const;
544 
551  std::pair<unsigned int,unsigned int>
552  create_cell_subrange_hp_by_index (const std::pair<unsigned int,unsigned int> &range,
553  const unsigned int fe_index,
554  const unsigned int vector_component = 0) const;
555 
557 
582  template <typename VectorType>
583  void initialize_dof_vector(VectorType &vec,
584  const unsigned int vector_component=0) const;
585 
606  template <typename Number2>
607  void initialize_dof_vector(LinearAlgebra::distributed::Vector<Number2> &vec,
608  const unsigned int vector_component=0) const;
609 
620  const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &
621  get_vector_partitioner (const unsigned int vector_component=0) const;
622 
626  const IndexSet &
627  get_locally_owned_set (const unsigned int fe_component = 0) const;
628 
632  const IndexSet &
633  get_ghost_set (const unsigned int fe_component = 0) const;
634 
644  const std::vector<unsigned int> &
645  get_constrained_dofs (const unsigned int fe_component = 0) const;
646 
651  void renumber_dofs (std::vector<types::global_dof_index> &renumbering,
652  const unsigned int vector_component = 0);
653 
655 
663  template <int spacedim>
664  static
665  bool is_supported (const FiniteElement<dim, spacedim> &fe);
666 
670  unsigned int n_components () const;
671 
680  unsigned int n_physical_cells () const;
681 
692  unsigned int n_macro_cells () const;
693 
698  const DoFHandler<dim> &
699  get_dof_handler (const unsigned int fe_component = 0) const;
700 
711  typename DoFHandler<dim>::cell_iterator
712  get_cell_iterator (const unsigned int macro_cell_number,
713  const unsigned int vector_number,
714  const unsigned int fe_component = 0) const;
715 
727  typename hp::DoFHandler<dim>::active_cell_iterator
728  get_hp_cell_iterator (const unsigned int macro_cell_number,
729  const unsigned int vector_number,
730  const unsigned int fe_component = 0) const;
731 
743  bool
744  at_irregular_cell (const unsigned int macro_cell_number) const;
745 
754  unsigned int
755  n_components_filled (const unsigned int macro_cell_number) const;
756 
760  unsigned int
761  get_dofs_per_cell (const unsigned int fe_component = 0,
762  const unsigned int hp_active_fe_index = 0) const;
763 
767  unsigned int
768  get_n_q_points (const unsigned int quad_index = 0,
769  const unsigned int hp_active_fe_index = 0) const;
770 
775  unsigned int
776  get_dofs_per_face (const unsigned int fe_component = 0,
777  const unsigned int hp_active_fe_index = 0) const;
778 
783  unsigned int
784  get_n_q_points_face (const unsigned int quad_index = 0,
785  const unsigned int hp_active_fe_index = 0) const;
786 
790  const Quadrature<dim> &
791  get_quadrature (const unsigned int quad_index = 0,
792  const unsigned int hp_active_fe_index = 0) const;
793 
797  const Quadrature<dim-1> &
798  get_face_quadrature (const unsigned int quad_index = 0,
799  const unsigned int hp_active_fe_index = 0) const;
800 
804  bool indices_initialized () const;
805 
811  bool mapping_initialized () const;
812 
817  std::size_t memory_consumption() const;
818 
823  template <typename StreamType>
824  void print_memory_consumption(StreamType &out) const;
825 
830  void print (std::ostream &out) const;
831 
833 
841  const internal::MatrixFreeFunctions::TaskInfo &
842  get_task_info () const;
843 
847  const internal::MatrixFreeFunctions::SizeInfo &
848  get_size_info () const;
849 
850  /*
851  * Return geometry-dependent information on the cells.
852  */
853  const internal::MatrixFreeFunctions::MappingInfo<dim,Number> &
854  get_mapping_info () const;
855 
859  const internal::MatrixFreeFunctions::DoFInfo &
860  get_dof_info (const unsigned int fe_component = 0) const;
861 
865  unsigned int n_constraint_pool_entries() const;
866 
871  const Number *
872  constraint_pool_begin (const unsigned int pool_index) const;
873 
879  const Number *
880  constraint_pool_end (const unsigned int pool_index) const;
881 
885  const internal::MatrixFreeFunctions::ShapeInfo<Number> &
886  get_shape_info (const unsigned int fe_component = 0,
887  const unsigned int quad_index = 0,
888  const unsigned int hp_active_fe_index = 0,
889  const unsigned int hp_active_quad_index = 0) const;
890 
906 
910  void release_scratch_data(const AlignedVector<VectorizedArray<Number> > *memory) const;
911 
913 
914 private:
915 
920  void internal_reinit (const Mapping<dim> &mapping,
921  const std::vector<const DoFHandler<dim> *> &dof_handler,
922  const std::vector<const ConstraintMatrix *> &constraint,
923  const std::vector<IndexSet> &locally_owned_set,
924  const std::vector<hp::QCollection<1> > &quad,
925  const AdditionalData additional_data);
926 
930  void internal_reinit (const Mapping<dim> &mapping,
931  const std::vector<const hp::DoFHandler<dim>*> &dof_handler,
932  const std::vector<const ConstraintMatrix *> &constraint,
933  const std::vector<IndexSet> &locally_owned_set,
934  const std::vector<hp::QCollection<1> > &quad,
935  const AdditionalData additional_data);
936 
943  void
944  initialize_indices (const std::vector<const ConstraintMatrix *> &constraint,
945  const std::vector<IndexSet> &locally_owned_set);
946 
950  void initialize_dof_handlers (const std::vector<const DoFHandler<dim>*> &dof_handlers,
951  const unsigned int level);
952 
956  void initialize_dof_handlers (const std::vector<const hp::DoFHandler<dim>*> &dof_handlers,
957  const unsigned int level);
958 
964  struct DoFHandlers
965  {
966  DoFHandlers ()
967  :
968  active_dof_handler(usual),
969  n_dof_handlers (0),
971  {}
972 
973  std::vector<SmartPointer<const DoFHandler<dim> > > dof_handler;
974  std::vector<SmartPointer<const hp::DoFHandler<dim> > > hp_dof_handler;
976  {
985  } active_dof_handler;
986  unsigned int n_dof_handlers;
987  unsigned int level;
988  };
989 
994 
999  std::vector<internal::MatrixFreeFunctions::DoFInfo> dof_info;
1000 
1007  std::vector<Number> constraint_pool_data;
1008 
1013  std::vector<unsigned int> constraint_pool_row_index;
1014 
1020 
1025 
1032  std::vector<std::pair<unsigned int,unsigned int> > cell_level_index;
1033 
1039 
1044 
1049 
1054 
1063 };
1064 
1065 
1066 
1067 /*----------------------- Inline functions ----------------------------------*/
1068 
1069 #ifndef DOXYGEN
1070 
1071 
1072 template <int dim, typename Number>
1073 template <typename VectorType>
1074 inline
1075 void
1077  const unsigned int comp) const
1078 {
1079  AssertIndexRange (comp, n_components());
1080  vec.reinit(dof_info[comp].vector_partitioner->size());
1081 }
1082 
1083 
1084 
1085 template <int dim, typename Number>
1086 template <typename Number2>
1087 inline
1088 void
1090  const unsigned int comp) const
1091 {
1092  AssertIndexRange (comp, n_components());
1093  vec.reinit(dof_info[comp].vector_partitioner);
1094 }
1095 
1096 
1097 
1098 template <int dim, typename Number>
1099 inline
1100 const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &
1101 MatrixFree<dim,Number>::get_vector_partitioner (const unsigned int comp) const
1102 {
1103  AssertIndexRange (comp, n_components());
1104  return dof_info[comp].vector_partitioner;
1105 }
1106 
1107 
1108 
1109 template <int dim, typename Number>
1110 inline
1111 const std::vector<unsigned int> &
1112 MatrixFree<dim,Number>::get_constrained_dofs (const unsigned int comp) const
1113 {
1114  AssertIndexRange (comp, n_components());
1115  return dof_info[comp].constrained_dofs;
1116 }
1117 
1118 
1119 
1120 template <int dim, typename Number>
1121 inline
1122 unsigned int
1124 {
1125  AssertDimension (dof_handlers.n_dof_handlers, dof_info.size());
1126  return dof_handlers.n_dof_handlers;
1127 }
1128 
1129 
1130 
1131 template <int dim, typename Number>
1132 inline
1135 {
1136  return task_info;
1137 }
1138 
1139 
1140 
1141 template <int dim, typename Number>
1142 inline
1145 {
1146  return size_info;
1147 }
1148 
1149 
1150 
1151 template <int dim, typename Number>
1152 inline
1153 unsigned int
1155 {
1156  return size_info.n_macro_cells;
1157 }
1158 
1159 
1160 
1161 template <int dim, typename Number>
1162 inline
1163 unsigned int
1165 {
1166  return size_info.n_active_cells;
1167 }
1168 
1169 
1170 
1171 template <int dim, typename Number>
1172 inline
1175 {
1176  return mapping_info;
1177 }
1178 
1179 
1180 
1181 template <int dim, typename Number>
1182 inline
1183 const internal::MatrixFreeFunctions::DoFInfo &
1184 MatrixFree<dim,Number>::get_dof_info (unsigned int dof_index) const
1185 {
1186  AssertIndexRange (dof_index, n_components());
1187  return dof_info[dof_index];
1188 }
1189 
1190 
1191 
1192 template <int dim, typename Number>
1193 inline
1194 unsigned int
1196 {
1197  return constraint_pool_row_index.size()-1;
1198 }
1199 
1200 
1201 
1202 template <int dim, typename Number>
1203 inline
1204 const Number *
1205 MatrixFree<dim,Number>::constraint_pool_begin (const unsigned int row) const
1206 {
1207  AssertIndexRange (row, constraint_pool_row_index.size()-1);
1208  return constraint_pool_data.empty() ? 0 :
1209  &constraint_pool_data[0] + constraint_pool_row_index[row];
1210 }
1211 
1212 
1213 
1214 template <int dim, typename Number>
1215 inline
1216 const Number *
1217 MatrixFree<dim,Number>::constraint_pool_end (const unsigned int row) const
1218 {
1219  AssertIndexRange (row, constraint_pool_row_index.size()-1);
1220  return constraint_pool_data.empty() ? 0 :
1221  &constraint_pool_data[0] + constraint_pool_row_index[row+1];
1222 }
1223 
1224 
1225 
1226 template <int dim, typename Number>
1227 inline
1228 std::pair<unsigned int,unsigned int>
1230 (const std::pair<unsigned int,unsigned int> &range,
1231  const unsigned int degree,
1232  const unsigned int vector_component) const
1233 {
1234  AssertIndexRange (vector_component, dof_info.size());
1235  if (dof_info[vector_component].cell_active_fe_index.empty())
1236  {
1237  AssertDimension (dof_info[vector_component].fe_index_conversion.size(),1);
1238  if (dof_info[vector_component].fe_index_conversion[0].first == degree)
1239  return range;
1240  else
1241  return std::pair<unsigned int,unsigned int> (range.second,range.second);
1242  }
1243 
1244  const unsigned int fe_index =
1245  dof_info[vector_component].fe_index_from_degree(degree);
1246  if (fe_index >= dof_info[vector_component].max_fe_index)
1247  return std::pair<unsigned int,unsigned int>(range.second, range.second);
1248  else
1249  return create_cell_subrange_hp_by_index (range, fe_index, vector_component);
1250 }
1251 
1252 
1253 
1254 template <int dim, typename Number>
1255 inline
1256 std::pair<unsigned int,unsigned int>
1258 (const std::pair<unsigned int,unsigned int> &range,
1259  const unsigned int fe_index,
1260  const unsigned int vector_component) const
1261 {
1262  AssertIndexRange (fe_index, dof_info[vector_component].max_fe_index);
1263  const std::vector<unsigned int> &fe_indices =
1264  dof_info[vector_component].cell_active_fe_index;
1265  if (fe_indices.size() == 0)
1266  return range;
1267  else
1268  {
1269  // the range over which we are searching must be ordered, otherwise we
1270  // got a range that spans over too many cells
1271 #ifdef DEBUG
1272  for (unsigned int i=range.first+1; i<range.second; ++i)
1273  Assert (fe_indices[i] >= fe_indices[i-1],
1274  ExcMessage ("Cell range must be over sorted range of fe indices in hp case!"));
1275  AssertIndexRange(range.first,fe_indices.size()+1);
1276  AssertIndexRange(range.second,fe_indices.size()+1);
1277 #endif
1278  std::pair<unsigned int,unsigned int> return_range;
1279  return_range.first =
1280  std::lower_bound(&fe_indices[0] + range.first,
1281  &fe_indices[0] + range.second, fe_index)
1282  -&fe_indices[0] ;
1283  return_range.second =
1284  std::lower_bound(&fe_indices[0] + return_range.first,
1285  &fe_indices[0] + range.second,
1286  fe_index + 1)-&fe_indices[0];
1287  Assert(return_range.first >= range.first &&
1288  return_range.second <= range.second, ExcInternalError());
1289  return return_range;
1290  }
1291 }
1292 
1293 
1294 
1295 template <int dim, typename Number>
1296 inline
1297 void
1298 MatrixFree<dim,Number>::renumber_dofs (std::vector<types::global_dof_index> &renumbering,
1299  const unsigned int vector_component)
1300 {
1301  AssertIndexRange(vector_component, dof_info.size());
1302  dof_info[vector_component].renumber_dofs (renumbering);
1303 }
1304 
1305 
1306 
1307 template <int dim, typename Number>
1308 inline
1309 const DoFHandler<dim> &
1310 MatrixFree<dim,Number>::get_dof_handler (const unsigned int dof_index) const
1311 {
1312  AssertIndexRange (dof_index, n_components());
1313  if (dof_handlers.active_dof_handler == DoFHandlers::usual)
1314  {
1315  AssertDimension (dof_handlers.dof_handler.size(),
1316  dof_handlers.n_dof_handlers);
1317  return *dof_handlers.dof_handler[dof_index];
1318  }
1319  else
1320  {
1321  Assert (false, ExcNotImplemented());
1322  // put pseudo return argument to avoid compiler error, but trigger a
1323  // segfault in case this is only run in optimized mode
1324  return *dof_handlers.dof_handler[numbers::invalid_unsigned_int];
1325  }
1326 }
1327 
1328 
1329 
1330 template <int dim, typename Number>
1331 inline
1333 MatrixFree<dim,Number>::get_cell_iterator(const unsigned int macro_cell_number,
1334  const unsigned int vector_number,
1335  const unsigned int dof_index) const
1336 {
1337  const unsigned int vectorization_length=VectorizedArray<Number>::n_array_elements;
1338 #ifdef DEBUG
1339  AssertIndexRange (dof_index, dof_handlers.n_dof_handlers);
1340  AssertIndexRange (macro_cell_number, size_info.n_macro_cells);
1341  AssertIndexRange (vector_number, vectorization_length);
1342  const unsigned int irreg_filled = dof_info[dof_index].row_starts[macro_cell_number][2];
1343  if (irreg_filled > 0)
1344  AssertIndexRange (vector_number, irreg_filled);
1345 #endif
1346 
1347  const DoFHandler<dim> *dofh = 0;
1348  if (dof_handlers.active_dof_handler == DoFHandlers::usual)
1349  {
1350  AssertDimension (dof_handlers.dof_handler.size(),
1351  dof_handlers.n_dof_handlers);
1352  dofh = dof_handlers.dof_handler[dof_index];
1353  }
1354  else
1355  {
1356  Assert (false, ExcMessage ("Cannot return DoFHandler<dim>::cell_iterator "
1357  "for underlying DoFHandler!"));
1358  }
1359 
1360  std::pair<unsigned int,unsigned int> index =
1361  cell_level_index[macro_cell_number*vectorization_length+vector_number];
1362  return typename DoFHandler<dim>::cell_iterator
1363  (&dofh->get_triangulation(), index.first, index.second, dofh);
1364 }
1365 
1366 
1367 
1368 template <int dim, typename Number>
1369 inline
1371 MatrixFree<dim,Number>::get_hp_cell_iterator(const unsigned int macro_cell_number,
1372  const unsigned int vector_number,
1373  const unsigned int dof_index) const
1374 {
1375  const unsigned int vectorization_length=VectorizedArray<Number>::n_array_elements;
1376 #ifdef DEBUG
1377  AssertIndexRange (dof_index, dof_handlers.n_dof_handlers);
1378  AssertIndexRange (macro_cell_number, size_info.n_macro_cells);
1379  AssertIndexRange (vector_number, vectorization_length);
1380  const unsigned int irreg_filled = dof_info[dof_index].row_starts[macro_cell_number][2];
1381  if (irreg_filled > 0)
1382  AssertIndexRange (vector_number, irreg_filled);
1383 #endif
1384 
1385  Assert (dof_handlers.active_dof_handler == DoFHandlers::hp,
1386  ExcNotImplemented());
1387  const hp::DoFHandler<dim> *dofh = dof_handlers.hp_dof_handler[dof_index];
1388  std::pair<unsigned int,unsigned int> index =
1389  cell_level_index[macro_cell_number*vectorization_length+vector_number];
1390  return typename hp::DoFHandler<dim>::cell_iterator
1391  (&dofh->get_triangulation(), index.first, index.second, dofh);
1392 }
1393 
1394 
1395 
1396 template <int dim, typename Number>
1397 inline
1398 bool
1399 MatrixFree<dim,Number>::at_irregular_cell (const unsigned int macro_cell) const
1400 {
1401  AssertIndexRange (macro_cell, size_info.n_macro_cells);
1402  return dof_info[0].row_starts[macro_cell][2] > 0;
1403 }
1404 
1405 
1406 
1407 template <int dim, typename Number>
1408 inline
1409 unsigned int
1410 MatrixFree<dim,Number>::n_components_filled (const unsigned int macro_cell) const
1411 {
1412  AssertIndexRange (macro_cell, size_info.n_macro_cells);
1413  const unsigned int n_filled = dof_info[0].row_starts[macro_cell][2];
1414  if (n_filled == 0)
1416  else
1417  return n_filled;
1418 }
1419 
1420 
1421 
1422 template <int dim, typename Number>
1423 inline
1424 unsigned int
1425 MatrixFree<dim,Number>::get_dofs_per_cell(const unsigned int dof_index,
1426  const unsigned int active_fe_index) const
1427 {
1428  AssertIndexRange (dof_index, dof_info.size());
1429  return dof_info[dof_index].dofs_per_cell[active_fe_index];
1430 }
1431 
1432 
1433 
1434 template <int dim, typename Number>
1435 inline
1436 unsigned int
1437 MatrixFree<dim,Number>::get_n_q_points(const unsigned int quad_index,
1438  const unsigned int active_fe_index) const
1439 {
1440  AssertIndexRange (quad_index,
1441  mapping_info.mapping_data_gen.size());
1442  return mapping_info.mapping_data_gen[quad_index].n_q_points[active_fe_index];
1443 }
1444 
1445 
1446 
1447 template <int dim, typename Number>
1448 inline
1449 unsigned int
1450 MatrixFree<dim,Number>::get_dofs_per_face(const unsigned int dof_index,
1451  const unsigned int active_fe_index) const
1452 {
1453  AssertIndexRange (dof_index, dof_info.size());
1454  return dof_info[dof_index].dofs_per_face[active_fe_index];
1455 }
1456 
1457 
1458 
1459 template <int dim, typename Number>
1460 inline
1461 unsigned int
1462 MatrixFree<dim,Number>::get_n_q_points_face(const unsigned int quad_index,
1463  const unsigned int active_fe_index) const
1464 {
1465  AssertIndexRange (quad_index,
1466  mapping_info.mapping_data_gen.size());
1467  return mapping_info.mapping_data_gen[quad_index].n_q_points_face[active_fe_index];
1468 }
1469 
1470 
1471 
1472 template <int dim, typename Number>
1473 inline
1474 const IndexSet &
1475 MatrixFree<dim,Number>::get_locally_owned_set(const unsigned int dof_index) const
1476 {
1477  AssertIndexRange (dof_index, dof_info.size());
1478  return dof_info[dof_index].vector_partitioner->locally_owned_range();
1479 }
1480 
1481 
1482 
1483 template <int dim, typename Number>
1484 inline
1485 const IndexSet &
1486 MatrixFree<dim,Number>::get_ghost_set(const unsigned int dof_index) const
1487 {
1488  AssertIndexRange (dof_index, dof_info.size());
1489  return dof_info[dof_index].vector_partitioner->ghost_indices();
1490 }
1491 
1492 
1493 
1494 template <int dim, typename Number>
1495 inline
1497 MatrixFree<dim,Number>::get_shape_info (const unsigned int index_fe,
1498  const unsigned int index_quad,
1499  const unsigned int active_fe_index,
1500  const unsigned int active_quad_index) const
1501 {
1502  AssertIndexRange (index_fe, shape_info.size(0));
1503  AssertIndexRange (index_quad, shape_info.size(1));
1504  AssertIndexRange (active_fe_index, shape_info.size(2));
1505  AssertIndexRange (active_quad_index, shape_info.size(3));
1506  return shape_info(index_fe, index_quad,
1507  active_fe_index, active_quad_index);
1508 }
1509 
1510 
1511 
1512 template <int dim, typename Number>
1513 inline
1514 const Quadrature<dim> &
1515 MatrixFree<dim,Number>::get_quadrature (const unsigned int quad_index,
1516  const unsigned int active_fe_index) const
1517 {
1518  AssertIndexRange (quad_index, mapping_info.mapping_data_gen.size());
1519  return mapping_info.mapping_data_gen[quad_index].
1520  quadrature[active_fe_index];
1521 }
1522 
1523 
1524 
1525 template <int dim, typename Number>
1526 inline
1527 const Quadrature<dim-1> &
1528 MatrixFree<dim,Number>::get_face_quadrature (const unsigned int quad_index,
1529  const unsigned int active_fe_index) const
1530 {
1531  AssertIndexRange (quad_index, mapping_info.mapping_data_gen.size());
1532  return mapping_info.mapping_data_gen[quad_index].
1533  face_quadrature[active_fe_index];
1534 }
1535 
1536 
1537 
1538 template <int dim, typename Number>
1539 inline
1540 bool
1542 {
1543  return indices_are_initialized;
1544 }
1545 
1546 
1547 
1548 template <int dim, typename Number>
1549 inline
1550 bool
1552 {
1553  return mapping_is_initialized;
1554 }
1555 
1556 
1557 
1558 template <int dim,typename Number>
1561 {
1562  typedef std::list<std::pair<bool, AlignedVector<VectorizedArray<Number> > > > list_type;
1563  list_type &data = scratch_pad.get();
1564  for (typename list_type::iterator it=data.begin(); it!=data.end(); ++it)
1565  if (it->first == false)
1566  {
1567  it->first = true;
1568  return &it->second;
1569  }
1570  data.push_front(std::make_pair(true,AlignedVector<VectorizedArray<Number> >()));
1571  return &data.front().second;
1572 }
1573 
1574 
1575 
1576 template <int dim, typename Number>
1577 void
1579 {
1580  typedef std::list<std::pair<bool, AlignedVector<VectorizedArray<Number> > > > list_type;
1581  list_type &data = scratch_pad.get();
1582  for (typename list_type::iterator it=data.begin(); it!=data.end(); ++it)
1583  if (&it->second == scratch)
1584  {
1585  Assert(it->first == true, ExcInternalError());
1586  it->first = false;
1587  return;
1588  }
1589  AssertThrow(false, ExcMessage("Tried to release invalid scratch pad"));
1590 }
1591 
1592 
1593 
1594 // ------------------------------ reinit functions ---------------------------
1595 
1596 namespace internal
1597 {
1598  namespace MatrixFree
1599  {
1600  template <typename DoFHandlerType>
1601  inline
1602  std::vector<IndexSet>
1603  extract_locally_owned_index_sets (const std::vector<const DoFHandlerType *> &dofh,
1604  const unsigned int level)
1605  {
1606  std::vector<IndexSet> locally_owned_set;
1607  locally_owned_set.reserve (dofh.size());
1608  for (unsigned int j=0; j<dofh.size(); j++)
1609  if (level == numbers::invalid_unsigned_int)
1610  locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
1611  else
1612  AssertThrow(false, ExcNotImplemented());
1613  return locally_owned_set;
1614  }
1615 
1616  template <int dim, int spacedim>
1617  inline
1618  std::vector<IndexSet>
1619  extract_locally_owned_index_sets (const std::vector<const ::DoFHandler<dim,spacedim> *> &dofh,
1620  const unsigned int level)
1621  {
1622  std::vector<IndexSet> locally_owned_set;
1623  locally_owned_set.reserve (dofh.size());
1624  for (unsigned int j=0; j<dofh.size(); j++)
1625  if (level == numbers::invalid_unsigned_int)
1626  locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
1627  else
1628  locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(level));
1629  return locally_owned_set;
1630  }
1631  }
1632 }
1633 
1634 
1635 
1636 template <int dim, typename Number>
1637 template <typename DoFHandlerType, typename QuadratureType>
1639 reinit(const DoFHandlerType &dof_handler,
1640  const ConstraintMatrix &constraints_in,
1641  const QuadratureType &quad,
1642  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1643 {
1644  std::vector<const DoFHandlerType *> dof_handlers;
1645  std::vector<const ConstraintMatrix *> constraints;
1646  std::vector<QuadratureType> quads;
1647 
1648  dof_handlers.push_back(&dof_handler);
1649  constraints.push_back (&constraints_in);
1650  quads.push_back (quad);
1651 
1652  std::vector<IndexSet> locally_owned_sets =
1653  internal::MatrixFree::extract_locally_owned_index_sets
1654  (dof_handlers, additional_data.level_mg_handler);
1655 
1656  std::vector<hp::QCollection<1> > quad_hp;
1657  quad_hp.push_back (hp::QCollection<1>(quad));
1658 
1659  internal_reinit(StaticMappingQ1<dim>::mapping, dof_handlers,constraints,
1660  locally_owned_sets, quad_hp, additional_data);
1661 }
1662 
1663 
1664 
1665 template <int dim, typename Number>
1666 template <typename DoFHandlerType, typename QuadratureType>
1668 reinit(const Mapping<dim> &mapping,
1669  const DoFHandlerType &dof_handler,
1670  const ConstraintMatrix &constraints_in,
1671  const QuadratureType &quad,
1672  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1673 {
1674  std::vector<const DoFHandlerType *> dof_handlers;
1675  std::vector<const ConstraintMatrix *> constraints;
1676 
1677  dof_handlers.push_back(&dof_handler);
1678  constraints.push_back (&constraints_in);
1679 
1680  std::vector<IndexSet> locally_owned_sets =
1681  internal::MatrixFree::extract_locally_owned_index_sets
1682  (dof_handlers, additional_data.level_mg_handler);
1683 
1684  std::vector<hp::QCollection<1> > quad_hp;
1685  quad_hp.push_back (hp::QCollection<1>(quad));
1686 
1687  internal_reinit(mapping, dof_handlers,constraints,locally_owned_sets,
1688  quad_hp, additional_data);
1689 }
1690 
1691 
1692 
1693 template <int dim, typename Number>
1694 template <typename DoFHandlerType, typename QuadratureType>
1696 reinit(const std::vector<const DoFHandlerType *> &dof_handler,
1697  const std::vector<const ConstraintMatrix *> &constraint,
1698  const std::vector<QuadratureType> &quad,
1699  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1700 {
1701  std::vector<IndexSet> locally_owned_set =
1702  internal::MatrixFree::extract_locally_owned_index_sets
1703  (dof_handler, additional_data.level_mg_handler);
1704  std::vector<hp::QCollection<1> > quad_hp;
1705  for (unsigned int q=0; q<quad.size(); ++q)
1706  quad_hp.push_back (hp::QCollection<1>(quad[q]));
1707  internal_reinit(StaticMappingQ1<dim>::mapping, dof_handler,constraint,
1708  locally_owned_set, quad_hp, additional_data);
1709 }
1710 
1711 
1712 
1713 template <int dim, typename Number>
1714 template <typename DoFHandlerType, typename QuadratureType>
1716 reinit(const std::vector<const DoFHandlerType *> &dof_handler,
1717  const std::vector<const ConstraintMatrix *> &constraint,
1718  const QuadratureType &quad,
1719  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1720 {
1721  std::vector<IndexSet> locally_owned_set =
1722  internal::MatrixFree::extract_locally_owned_index_sets
1723  (dof_handler, additional_data.level_mg_handler);
1724  std::vector<hp::QCollection<1> > quad_hp;
1725  quad_hp.push_back (hp::QCollection<1>(quad));
1726  internal_reinit(StaticMappingQ1<dim>::mapping, dof_handler,constraint,
1727  locally_owned_set, quad_hp, additional_data);
1728 }
1729 
1730 
1731 
1732 template <int dim, typename Number>
1733 template <typename DoFHandlerType, typename QuadratureType>
1735 reinit(const Mapping<dim> &mapping,
1736  const std::vector<const DoFHandlerType *> &dof_handler,
1737  const std::vector<const ConstraintMatrix *> &constraint,
1738  const QuadratureType &quad,
1739  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1740 {
1741  std::vector<IndexSet> locally_owned_set =
1742  internal::MatrixFree::extract_locally_owned_index_sets
1743  (dof_handler, additional_data.level_mg_handler);
1744  std::vector<hp::QCollection<1> > quad_hp;
1745  quad_hp.push_back (hp::QCollection<1>(quad));
1746  internal_reinit(mapping, dof_handler,constraint,
1747  locally_owned_set, quad_hp, additional_data);
1748 }
1749 
1750 
1751 
1752 template <int dim, typename Number>
1753 template <typename DoFHandlerType, typename QuadratureType>
1755 reinit(const Mapping<dim> &mapping,
1756  const std::vector<const DoFHandlerType *> &dof_handler,
1757  const std::vector<const ConstraintMatrix *> &constraint,
1758  const std::vector<QuadratureType> &quad,
1759  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1760 {
1761  std::vector<IndexSet> locally_owned_set =
1762  internal::MatrixFree::extract_locally_owned_index_sets
1763  (dof_handler, additional_data.level_mg_handler);
1764  std::vector<hp::QCollection<1> > quad_hp;
1765  for (unsigned int q=0; q<quad.size(); ++q)
1766  quad_hp.push_back (hp::QCollection<1>(quad[q]));
1767  internal_reinit(mapping, dof_handler,constraint,locally_owned_set,
1768  quad_hp, additional_data);
1769 }
1770 
1771 
1772 
1773 template <int dim, typename Number>
1774 template <typename DoFHandlerType, typename QuadratureType>
1776 reinit(const Mapping<dim> &mapping,
1777  const std::vector<const DoFHandlerType *> &dof_handler,
1778  const std::vector<const ConstraintMatrix *> &constraint,
1779  const std::vector<IndexSet> &locally_owned_set,
1780  const std::vector<QuadratureType> &quad,
1781  const typename MatrixFree<dim,Number>::AdditionalData additional_data)
1782 {
1783  // find out whether we use a hp Quadrature or a standard quadrature
1784  std::vector<hp::QCollection<1> > quad_hp;
1785  for (unsigned int q=0; q<quad.size(); ++q)
1786  quad_hp.push_back (hp::QCollection<1>(quad[q]));
1787  internal_reinit (mapping,
1788  dof_handler,
1789  constraint, locally_owned_set, quad_hp, additional_data);
1790 }
1791 
1792 
1793 
1794 // ------------------------------ implementation of cell_loop ---------------
1795 
1796 // internal helper functions that define how to call MPI data exchange
1797 // functions: for generic vectors, do nothing at all. For distributed vectors,
1798 // call update_ghost_values_start function and so on. If we have collections
1799 // of vectors, just do the individual functions of the components. In order to
1800 // keep ghost values consistent (whether we are in read or write mode). the whole situation is a bit complicated by the fact
1801 // that we need to treat block vectors differently, which use some additional
1802 // helper functions to select the blocks and template magic.
1803 namespace internal
1804 {
1805  template<typename VectorStruct>
1806  bool update_ghost_values_start_block (const VectorStruct &vec,
1807  const unsigned int channel,
1809  template<typename VectorStruct>
1810  void reset_ghost_values_block (const VectorStruct &vec,
1811  const bool zero_out_ghosts,
1813  template<typename VectorStruct>
1814  void update_ghost_values_finish_block (const VectorStruct &vec,
1816  template<typename VectorStruct>
1817  void compress_start_block (const VectorStruct &vec,
1818  const unsigned int channel,
1820  template<typename VectorStruct>
1821  void compress_finish_block (const VectorStruct &vec,
1823 
1824  template<typename VectorStruct>
1825  bool update_ghost_values_start_block (const VectorStruct &,
1826  const unsigned int,
1828  {
1829  return false;
1830  }
1831  template<typename VectorStruct>
1832  void reset_ghost_values_block (const VectorStruct &,
1833  const bool,
1835  {}
1836  template<typename VectorStruct>
1837  void update_ghost_values_finish_block (const VectorStruct &,
1839  {}
1840  template<typename VectorStruct>
1841  void compress_start_block (const VectorStruct &,
1842  const unsigned int,
1844  {}
1845  template<typename VectorStruct>
1846  void compress_finish_block (const VectorStruct &,
1848  {}
1849 
1850 
1851 
1852  // returns true if the vector was in a state without ghost values before,
1853  // i.e., we need to zero out ghosts in the very end
1854  template<typename VectorStruct>
1855  inline
1856  bool update_ghost_values_start (const VectorStruct &vec,
1857  const unsigned int channel = 0)
1858  {
1859  return
1860  update_ghost_values_start_block(vec, channel,
1862  }
1863 
1864 
1865 
1866  template<typename Number>
1867  inline
1868  bool update_ghost_values_start (const LinearAlgebra::distributed::Vector<Number> &vec,
1869  const unsigned int channel = 0)
1870  {
1871  bool return_value = !vec.has_ghost_elements();
1872  vec.update_ghost_values_start(channel);
1873  return return_value;
1874  }
1875 
1876 
1877 
1878  template <typename VectorStruct>
1879  inline
1880  bool update_ghost_values_start (const std::vector<VectorStruct> &vec)
1881  {
1882  bool return_value = false;
1883  for (unsigned int comp=0; comp<vec.size(); comp++)
1884  return_value = update_ghost_values_start(vec[comp], comp);
1885  return return_value;
1886  }
1887 
1888 
1889 
1890  template <typename VectorStruct>
1891  inline
1892  bool update_ghost_values_start (const std::vector<VectorStruct *> &vec)
1893  {
1894  bool return_value = false;
1895  for (unsigned int comp=0; comp<vec.size(); comp++)
1896  return_value = update_ghost_values_start(*vec[comp], comp);
1897  return return_value;
1898  }
1899 
1900 
1901 
1902  template<typename VectorStruct>
1903  inline
1904  bool update_ghost_values_start_block (const VectorStruct &vec,
1905  const unsigned int channel,
1907  {
1908  bool return_value = false;
1909  for (unsigned int i=0; i<vec.n_blocks(); ++i)
1910  return_value = update_ghost_values_start(vec.block(i), channel+509*i);
1911  return return_value;
1912  }
1913 
1914 
1915 
1916  // if the input vector did not have ghosts imported, clear them here again
1917  // in order to avoid subsequent operations e.g. in linear solvers to work
1918  // with ghosts all the time
1919  template<typename VectorStruct>
1920  inline
1921  void reset_ghost_values (const VectorStruct &vec,
1922  const bool zero_out_ghosts)
1923  {
1924  reset_ghost_values_block(vec, zero_out_ghosts,
1926  }
1927 
1928 
1929 
1930  template<typename Number>
1931  inline
1932  void reset_ghost_values (const LinearAlgebra::distributed::Vector<Number> &vec,
1933  const bool zero_out_ghosts)
1934  {
1935  if (zero_out_ghosts)
1936  const_cast<LinearAlgebra::distributed::Vector<Number>&>(vec).zero_out_ghosts();
1937  }
1938 
1939 
1940 
1941  template <typename VectorStruct>
1942  inline
1943  void reset_ghost_values (const std::vector<VectorStruct> &vec,
1944  const bool zero_out_ghosts)
1945  {
1946  for (unsigned int comp=0; comp<vec.size(); comp++)
1947  reset_ghost_values(vec[comp], zero_out_ghosts);
1948  }
1949 
1950 
1951 
1952  template <typename VectorStruct>
1953  inline
1954  void reset_ghost_values (const std::vector<VectorStruct *> &vec,
1955  const bool zero_out_ghosts)
1956  {
1957  for (unsigned int comp=0; comp<vec.size(); comp++)
1958  reset_ghost_values(*vec[comp], zero_out_ghosts);
1959  }
1960 
1961 
1962 
1963  template<typename VectorStruct>
1964  inline
1965  void reset_ghost_values_block (const VectorStruct &vec,
1966  const bool zero_out_ghosts,
1968  {
1969  for (unsigned int i=0; i<vec.n_blocks(); ++i)
1970  reset_ghost_values(vec.block(i), zero_out_ghosts);
1971  }
1972 
1973 
1974 
1975  template <typename VectorStruct>
1976  inline
1977  void update_ghost_values_finish (const VectorStruct &vec)
1978  {
1979  update_ghost_values_finish_block(vec,
1981  }
1982 
1983 
1984 
1985  template <typename Number>
1986  inline
1987  void update_ghost_values_finish (const LinearAlgebra::distributed::Vector<Number> &vec)
1988  {
1990  }
1991 
1992 
1993 
1994  template <typename VectorStruct>
1995  inline
1996  void update_ghost_values_finish (const std::vector<VectorStruct> &vec)
1997  {
1998  for (unsigned int comp=0; comp<vec.size(); comp++)
1999  update_ghost_values_finish(vec[comp]);
2000  }
2001 
2002 
2003 
2004  template <typename VectorStruct>
2005  inline
2006  void update_ghost_values_finish (const std::vector<VectorStruct *> &vec)
2007  {
2008  for (unsigned int comp=0; comp<vec.size(); comp++)
2009  update_ghost_values_finish(*vec[comp]);
2010  }
2011 
2012 
2013 
2014  template <typename VectorStruct>
2015  inline
2016  void update_ghost_values_finish_block (const VectorStruct &vec,
2018  {
2019  for (unsigned int i=0; i<vec.n_blocks(); ++i)
2020  update_ghost_values_finish(vec.block(i));
2021  }
2022 
2023 
2024 
2025  template <typename VectorStruct>
2026  inline
2027  void compress_start (VectorStruct &vec,
2028  const unsigned int channel = 0)
2029  {
2030  compress_start_block (vec, channel,
2032  }
2033 
2034 
2035 
2036  template <typename Number>
2037  inline
2038  void compress_start (LinearAlgebra::distributed::Vector<Number> &vec,
2039  const unsigned int channel = 0)
2040  {
2041  vec.compress_start(channel);
2042  }
2043 
2044 
2045 
2046  template <typename VectorStruct>
2047  inline
2048  void compress_start (std::vector<VectorStruct> &vec)
2049  {
2050  for (unsigned int comp=0; comp<vec.size(); comp++)
2051  compress_start (vec[comp], comp);
2052  }
2053 
2054 
2055 
2056  template <typename VectorStruct>
2057  inline
2058  void compress_start (std::vector<VectorStruct *> &vec)
2059  {
2060  for (unsigned int comp=0; comp<vec.size(); comp++)
2061  compress_start (*vec[comp], comp);
2062  }
2063 
2064 
2065 
2066  template <typename VectorStruct>
2067  inline
2068  void compress_start_block (VectorStruct &vec,
2069  const unsigned int channel,
2071  {
2072  for (unsigned int i=0; i<vec.n_blocks(); ++i)
2073  compress_start(vec.block(i), channel + 500*i);
2074  }
2075 
2076 
2077 
2078  template <typename VectorStruct>
2079  inline
2080  void compress_finish (VectorStruct &vec)
2081  {
2082  compress_finish_block(vec,
2084  }
2085 
2086 
2087 
2088  template <typename Number>
2089  inline
2090  void compress_finish (LinearAlgebra::distributed::Vector<Number> &vec)
2091  {
2093  }
2094 
2095 
2096 
2097  template <typename VectorStruct>
2098  inline
2099  void compress_finish (std::vector<VectorStruct> &vec)
2100  {
2101  for (unsigned int comp=0; comp<vec.size(); comp++)
2102  compress_finish(vec[comp]);
2103  }
2104 
2105 
2106 
2107  template <typename VectorStruct>
2108  inline
2109  void compress_finish (std::vector<VectorStruct *> &vec)
2110  {
2111  for (unsigned int comp=0; comp<vec.size(); comp++)
2112  compress_finish(*vec[comp]);
2113  }
2114 
2115 
2116 
2117  template <typename VectorStruct>
2118  inline
2119  void compress_finish_block (VectorStruct &vec,
2121  {
2122  for (unsigned int i=0; i<vec.n_blocks(); ++i)
2123  compress_finish(vec.block(i));
2124  }
2125 
2126 
2127 
2128 #ifdef DEAL_II_WITH_THREADS
2129 
2130  // This defines the TBB data structures that are needed to schedule the
2131  // partition-partition variant
2132 
2133  namespace partition
2134  {
2135  template<typename Worker>
2136  class CellWork : public tbb::task
2137  {
2138  public:
2139  CellWork (const Worker &worker_in,
2140  const unsigned int partition_in,
2141  const internal::MatrixFreeFunctions::TaskInfo &task_info_in,
2142  const bool is_blocked_in)
2143  :
2144  dummy (NULL),
2145  worker (worker_in),
2146  partition (partition_in),
2147  task_info (task_info_in),
2148  is_blocked (is_blocked_in)
2149  {};
2150  tbb::task *execute ()
2151  {
2152  std::pair<unsigned int, unsigned int> cell_range
2153  (task_info.partition_color_blocks_data[partition],
2154  task_info.partition_color_blocks_data[partition+1]);
2155  worker(cell_range);
2156  if (is_blocked==true)
2157  dummy->spawn (*dummy);
2158  return NULL;
2159  }
2160 
2161  tbb::empty_task *dummy;
2162 
2163  private:
2164  const Worker &worker;
2165  const unsigned int partition;
2166  const internal::MatrixFreeFunctions::TaskInfo &task_info;
2167  const bool is_blocked;
2168  };
2169 
2170 
2171 
2172  template<typename Worker>
2173  class PartitionWork : public tbb::task
2174  {
2175  public:
2176  PartitionWork (const Worker &function_in,
2177  const unsigned int partition_in,
2178  const internal::MatrixFreeFunctions::TaskInfo &task_info_in,
2179  const bool is_blocked_in = false)
2180  :
2181  dummy (NULL),
2182  function (function_in),
2183  partition (partition_in),
2184  task_info (task_info_in),
2185  is_blocked (is_blocked_in)
2186  {};
2187  tbb::task *execute ()
2188  {
2189  tbb::empty_task *root = new( tbb::task::allocate_root() )
2190  tbb::empty_task;
2191  unsigned int evens = task_info.partition_evens[partition];
2192  unsigned int odds = task_info.partition_odds[partition];
2193  unsigned int n_blocked_workers =
2194  task_info.partition_n_blocked_workers[partition];
2195  unsigned int n_workers = task_info.partition_n_workers[partition];
2196  std::vector<CellWork<Worker>*> worker(n_workers);
2197  std::vector<CellWork<Worker>*> blocked_worker(n_blocked_workers);
2198 
2199  root->set_ref_count(evens+1);
2200  for (unsigned int j=0; j<evens; j++)
2201  {
2202  worker[j] = new(root->allocate_child())
2203  CellWork<Worker>(function, task_info.
2204  partition_color_blocks_row_index[partition]+2*j,
2205  task_info, false);
2206  if (j>0)
2207  {
2208  worker[j]->set_ref_count(2);
2209  blocked_worker[j-1]->dummy = new(worker[j]->allocate_child())
2210  tbb::empty_task;
2211  worker[j-1]->spawn(*blocked_worker[j-1]);
2212  }
2213  else
2214  worker[j]->set_ref_count(1);
2215  if (j<evens-1)
2216  {
2217  blocked_worker[j] = new(worker[j]->allocate_child())
2218  CellWork<Worker>(function, task_info.
2219  partition_color_blocks_row_index
2220  [partition] + 2*j+1, task_info, true);
2221  }
2222  else
2223  {
2224  if (odds==evens)
2225  {
2226  worker[evens] = new(worker[j]->allocate_child())
2227  CellWork<Worker>(function, task_info.
2228  partition_color_blocks_row_index[partition]+2*j+1,
2229  task_info, false);
2230  worker[j]->spawn(*worker[evens]);
2231  }
2232  else
2233  {
2234  tbb::empty_task *child = new(worker[j]->allocate_child())
2235  tbb::empty_task();
2236  worker[j]->spawn(*child);
2237  }
2238  }
2239  }
2240 
2241  root->wait_for_all();
2242  root->destroy(*root);
2243  if (is_blocked==true)
2244  dummy->spawn (*dummy);
2245  return NULL;
2246  }
2247 
2248  tbb::empty_task *dummy;
2249 
2250  private:
2251  const Worker &function;
2252  const unsigned int partition;
2253  const internal::MatrixFreeFunctions::TaskInfo &task_info;
2254  const bool is_blocked;
2255  };
2256 
2257  } // end of namespace partition
2258 
2259 
2260 
2261  namespace color
2262  {
2263  template <typename Worker>
2264  class CellWork
2265  {
2266  public:
2267  CellWork (const Worker &worker_in,
2268  const internal::MatrixFreeFunctions::TaskInfo &task_info_in)
2269  :
2270  worker (worker_in),
2271  task_info (task_info_in)
2272  {};
2273  void operator()(const tbb::blocked_range<unsigned int> &r) const
2274  {
2275  for (unsigned int block=r.begin(); block<r.end(); block++)
2276  {
2277  std::pair<unsigned int,unsigned int> cell_range;
2278  if (task_info.position_short_block<block)
2279  {
2280  cell_range.first = (block-1)*task_info.block_size+
2281  task_info.block_size_last;
2282  cell_range.second = cell_range.first + task_info.block_size;
2283  }
2284  else
2285  {
2286  cell_range.first = block*task_info.block_size;
2287  cell_range.second = cell_range.first +
2288  ((block == task_info.position_short_block)?
2289  (task_info.block_size_last):(task_info.block_size));
2290  }
2291  worker (cell_range);
2292  }
2293  }
2294  private:
2295  const Worker &worker;
2296  const internal::MatrixFreeFunctions::TaskInfo &task_info;
2297  };
2298 
2299 
2300  template<typename Worker>
2301  class PartitionWork : public tbb::task
2302  {
2303  public:
2304  PartitionWork (const Worker &worker_in,
2305  const unsigned int partition_in,
2306  const internal::MatrixFreeFunctions::TaskInfo &task_info_in,
2307  const bool is_blocked_in)
2308  :
2309  dummy (NULL),
2310  worker (worker_in),
2311  partition (partition_in),
2312  task_info (task_info_in),
2313  is_blocked (is_blocked_in)
2314  {};
2315  tbb::task *execute ()
2316  {
2317  unsigned int lower = task_info.partition_color_blocks_data[partition],
2318  upper = task_info.partition_color_blocks_data[partition+1];
2319  parallel_for(tbb::blocked_range<unsigned int>(lower,upper,1),
2320  CellWork<Worker> (worker,task_info));
2321  if (is_blocked==true)
2322  dummy->spawn (*dummy);
2323  return NULL;
2324  }
2325 
2326  tbb::empty_task *dummy;
2327 
2328  private:
2329  const Worker &worker;
2330  const unsigned int partition;
2331  const internal::MatrixFreeFunctions::TaskInfo &task_info;
2332  const bool is_blocked;
2333  };
2334 
2335  } // end of namespace color
2336 
2337 
2338  template<typename VectorStruct>
2339  class MPIComDistribute : public tbb::task
2340  {
2341  public:
2342  MPIComDistribute (const VectorStruct &src_in)
2343  :
2344  src(src_in)
2345  {};
2346 
2347  tbb::task *execute ()
2348  {
2349  internal::update_ghost_values_finish(src);
2350  return 0;
2351  }
2352 
2353  private:
2354  const VectorStruct &src;
2355  };
2356 
2357 
2358 
2359  template<typename VectorStruct>
2360  class MPIComCompress : public tbb::task
2361  {
2362  public:
2363  MPIComCompress (VectorStruct &dst_in)
2364  :
2365  dst(dst_in)
2366  {};
2367 
2368  tbb::task *execute ()
2369  {
2370  internal::compress_start(dst);
2371  return 0;
2372  }
2373 
2374  private:
2375  VectorStruct &dst;
2376  };
2377 
2378 #endif // DEAL_II_WITH_THREADS
2379 
2380 } // end of namespace internal
2381 
2382 
2383 
2384 template <int dim, typename Number>
2385 template <typename OutVector, typename InVector>
2386 inline
2387 void
2389 (const std_cxx11::function<void (const MatrixFree<dim,Number> &,
2390  OutVector &,
2391  const InVector &,
2392  const std::pair<unsigned int,
2393  unsigned int> &)> &cell_operation,
2394  OutVector &dst,
2395  const InVector &src) const
2396 {
2397  // in any case, need to start the ghost import at the beginning
2398  bool ghosts_were_not_set = internal::update_ghost_values_start (src);
2399 
2400 #ifdef DEAL_II_WITH_THREADS
2401 
2402  // Use multithreading if so requested and if there is enough work to do in
2403  // parallel (the code might hang if there are less than two chunks!)
2404  if (task_info.use_multithreading == true && task_info.n_blocks > 3)
2405  {
2406  // to simplify the function calls, bind away all arguments except the
2407  // cell range
2408  typedef
2409  std_cxx11::function<void (const std::pair<unsigned int,unsigned int> &range)>
2410  Worker;
2411 
2412  const Worker func = std_cxx11::bind (std_cxx11::ref(cell_operation),
2413  std_cxx11::cref(*this),
2414  std_cxx11::ref(dst),
2415  std_cxx11::cref(src),
2416  std_cxx11::_1);
2417 
2418  if (task_info.use_partition_partition == true)
2419  {
2420  tbb::empty_task *root = new( tbb::task::allocate_root() )
2421  tbb::empty_task;
2422  unsigned int evens = task_info.evens;
2423  unsigned int odds = task_info.odds;
2424  root->set_ref_count(evens+1);
2425  unsigned int n_blocked_workers = task_info.n_blocked_workers;
2426  unsigned int n_workers = task_info.n_workers;
2427  std::vector<internal::partition::PartitionWork<Worker>*>
2428  worker(n_workers);
2429  std::vector<internal::partition::PartitionWork<Worker>*>
2430  blocked_worker(n_blocked_workers);
2431  internal::MPIComCompress<OutVector> *worker_compr =
2432  new(root->allocate_child())
2433  internal::MPIComCompress<OutVector>(dst);
2434  worker_compr->set_ref_count(1);
2435  for (unsigned int j=0; j<evens; j++)
2436  {
2437  if (j>0)
2438  {
2439  worker[j] = new(root->allocate_child())
2440  internal::partition::PartitionWork<Worker>
2441  (func,2*j,task_info,false);
2442  worker[j]->set_ref_count(2);
2443  blocked_worker[j-1]->dummy = new(worker[j]->allocate_child())
2444  tbb::empty_task;
2445  if (j>1)
2446  worker[j-1]->spawn(*blocked_worker[j-1]);
2447  else
2448  worker_compr->spawn(*blocked_worker[j-1]);
2449  }
2450  else
2451  {
2452  worker[j] = new(worker_compr->allocate_child())
2453  internal::partition::PartitionWork<Worker>
2454  (func,2*j,task_info,false);
2455  worker[j]->set_ref_count(2);
2456  internal::MPIComDistribute<InVector> *worker_dist =
2457  new (worker[j]->allocate_child())
2458  internal::MPIComDistribute<InVector>(src);
2459  worker_dist->spawn(*worker_dist);
2460  }
2461  if (j<evens-1)
2462  {
2463  blocked_worker[j] = new(worker[j]->allocate_child())
2464  internal::partition::PartitionWork<Worker>
2465  (func,2*j+1,task_info,true);
2466  }
2467  else
2468  {
2469  if (odds==evens)
2470  {
2471  worker[evens] = new(worker[j]->allocate_child())
2472  internal::partition::PartitionWork<Worker>
2473  (func,2*j+1,task_info,false);
2474  worker[j]->spawn(*worker[evens]);
2475  }
2476  else
2477  {
2478  tbb::empty_task *child = new(worker[j]->allocate_child())
2479  tbb::empty_task();
2480  worker[j]->spawn(*child);
2481  }
2482  }
2483  }
2484 
2485  root->wait_for_all();
2486  root->destroy(*root);
2487  }
2488  else // end of partition-partition, start of partition-color
2489  {
2490  unsigned int evens = task_info.evens;
2491  unsigned int odds = task_info.odds;
2492 
2493  // check whether there is only one partition. if not, build up the
2494  // tree of partitions
2495  if (odds > 0)
2496  {
2497  tbb::empty_task *root = new( tbb::task::allocate_root() ) tbb::empty_task;
2498  root->set_ref_count(evens+1);
2499  unsigned int n_blocked_workers = odds-(odds+evens+1)%2;
2500  unsigned int n_workers = task_info.partition_color_blocks_data.size()-1-
2501  n_blocked_workers;
2502  std::vector<internal::color::PartitionWork<Worker>*> worker(n_workers);
2503  std::vector<internal::color::PartitionWork<Worker>*> blocked_worker(n_blocked_workers);
2504  unsigned int worker_index = 0, slice_index = 0;
2505  unsigned int spawn_index = 0;
2506  int spawn_index_child = -2;
2507  internal::MPIComCompress<OutVector> *worker_compr = new(root->allocate_child())
2508  internal::MPIComCompress<OutVector>(dst);
2509  worker_compr->set_ref_count(1);
2510  for (unsigned int part=0;
2511  part<task_info.partition_color_blocks_row_index.size()-1; part++)
2512  {
2513  const unsigned int spawn_index_new = worker_index;
2514  if (part == 0)
2515  worker[worker_index] = new(worker_compr->allocate_child())
2516  internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
2517  else
2518  worker[worker_index] = new(root->allocate_child())
2519  internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
2520  slice_index++;
2521  for (; slice_index<task_info.partition_color_blocks_row_index[part+1];
2522  slice_index++)
2523  {
2524  worker[worker_index]->set_ref_count(1);
2525  worker_index++;
2526  worker[worker_index] = new (worker[worker_index-1]->allocate_child())
2527  internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
2528  }
2529  worker[worker_index]->set_ref_count(2);
2530  if (part>0)
2531  {
2532  blocked_worker[(part-1)/2]->dummy =
2533  new (worker[worker_index]->allocate_child()) tbb::empty_task;
2534  worker_index++;
2535  if (spawn_index_child == -1)
2536  worker[spawn_index]->spawn(*blocked_worker[(part-1)/2]);
2537  else
2538  {
2539  Assert(spawn_index_child>=0, ExcInternalError());
2540  worker[spawn_index]->spawn(*worker[spawn_index_child]);
2541  }
2542  spawn_index = spawn_index_new;
2543  }
2544  else
2545  {
2546  internal::MPIComDistribute<InVector> *worker_dist =
2547  new (worker[worker_index]->allocate_child())
2548  internal::MPIComDistribute<InVector>(src);
2549  worker_dist->spawn(*worker_dist);
2550  worker_index++;
2551  }
2552  part += 1;
2553  if (part<task_info.partition_color_blocks_row_index.size()-1)
2554  {
2555  if (part<task_info.partition_color_blocks_row_index.size()-2)
2556  {
2557  blocked_worker[part/2] = new(worker[worker_index-1]->allocate_child())
2558  internal::color::PartitionWork<Worker>(func,slice_index,task_info,true);
2559  slice_index++;
2560  if (slice_index<
2561  task_info.partition_color_blocks_row_index[part+1])
2562  {
2563  blocked_worker[part/2]->set_ref_count(1);
2564  worker[worker_index] = new(blocked_worker[part/2]->allocate_child())
2565  internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
2566  slice_index++;
2567  }
2568  else
2569  {
2570  spawn_index_child = -1;
2571  continue;
2572  }
2573  }
2574  for (; slice_index<task_info.partition_color_blocks_row_index[part+1];
2575  slice_index++)
2576  {
2577  if (slice_index>
2578  task_info.partition_color_blocks_row_index[part])
2579  {
2580  worker[worker_index]->set_ref_count(1);
2581  worker_index++;
2582  }
2583  worker[worker_index] = new (worker[worker_index-1]->allocate_child())
2584  internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
2585  }
2586  spawn_index_child = worker_index;
2587  worker_index++;
2588  }
2589  else
2590  {
2591  tbb::empty_task *final = new (worker[worker_index-1]->allocate_child())
2592  tbb::empty_task;
2593  worker[spawn_index]->spawn(*final);
2594  spawn_index_child = worker_index-1;
2595  }
2596  }
2597  if (evens==odds)
2598  {
2599  Assert(spawn_index_child>=0, ExcInternalError());
2600  worker[spawn_index]->spawn(*worker[spawn_index_child]);
2601  }
2602  root->wait_for_all();
2603  root->destroy(*root);
2604  }
2605  // case when we only have one partition: this is the usual coloring
2606  // scheme, and we just schedule a parallel for loop for each color
2607  else
2608  {
2609  Assert(evens==1,ExcInternalError());
2610  internal::update_ghost_values_finish(src);
2611 
2612  for (unsigned int color=0;
2613  color < task_info.partition_color_blocks_row_index[1];
2614  ++color)
2615  {
2616  unsigned int lower = task_info.partition_color_blocks_data[color],
2617  upper = task_info.partition_color_blocks_data[color+1];
2618  parallel_for(tbb::blocked_range<unsigned int>(lower,upper,1),
2619  internal::color::CellWork<Worker>
2620  (func,task_info));
2621  }
2622 
2623  internal::compress_start(dst);
2624  }
2625  }
2626  }
2627  else
2628 #endif
2629  // serial loop
2630  {
2631  std::pair<unsigned int,unsigned int> cell_range;
2632 
2633  // First operate on cells where no ghost data is needed (inner cells)
2634  {
2635  cell_range.first = 0;
2636  cell_range.second = size_info.boundary_cells_start;
2637  cell_operation (*this, dst, src, cell_range);
2638  }
2639 
2640  // before starting operations on cells that contain ghost nodes (outer
2641  // cells), wait for the MPI commands to finish
2642  internal::update_ghost_values_finish(src);
2643 
2644  // For the outer cells, do the same procedure as for inner cells.
2645  if (size_info.boundary_cells_end > size_info.boundary_cells_start)
2646  {
2647  cell_range.first = size_info.boundary_cells_start;
2648  cell_range.second = size_info.boundary_cells_end;
2649  cell_operation (*this, dst, src, cell_range);
2650  }
2651 
2652  internal::compress_start(dst);
2653 
2654  // Finally operate on cells where no ghost data is needed (inner cells)
2655  if (size_info.n_macro_cells > size_info.boundary_cells_end)
2656  {
2657  cell_range.first = size_info.boundary_cells_end;
2658  cell_range.second = size_info.n_macro_cells;
2659  cell_operation (*this, dst, src, cell_range);
2660  }
2661  }
2662 
2663  // In every case, we need to finish transfers at the very end
2664  internal::compress_finish(dst);
2665  internal::reset_ghost_values(src, ghosts_were_not_set);
2666 }
2667 
2668 
2669 
2670 template <int dim, typename Number>
2671 template <typename CLASS, typename OutVector, typename InVector>
2672 inline
2673 void
2675 (void (CLASS::*function_pointer)(const MatrixFree<dim,Number> &,
2676  OutVector &,
2677  const InVector &,
2678  const std::pair<unsigned int,
2679  unsigned int> &)const,
2680  const CLASS *owning_class,
2681  OutVector &dst,
2682  const InVector &src) const
2683 {
2684  // here, use std_cxx11::bind to hand a function handler with the appropriate
2685  // argument to the other loop function
2686  std_cxx11::function<void (const MatrixFree<dim,Number> &,
2687  OutVector &,
2688  const InVector &,
2689  const std::pair<unsigned int,
2690  unsigned int> &)>
2691  function = std_cxx11::bind<void>(function_pointer,
2692  owning_class,
2693  std_cxx11::_1,
2694  std_cxx11::_2,
2695  std_cxx11::_3,
2696  std_cxx11::_4);
2697  cell_loop (function, dst, src);
2698 }
2699 
2700 
2701 
2702 template <int dim, typename Number>
2703 template <typename CLASS, typename OutVector, typename InVector>
2704 inline
2705 void
2707 (void(CLASS::*function_pointer)(const MatrixFree<dim,Number> &,
2708  OutVector &,
2709  const InVector &,
2710  const std::pair<unsigned int,
2711  unsigned int> &),
2712  CLASS *owning_class,
2713  OutVector &dst,
2714  const InVector &src) const
2715 {
2716  // here, use std_cxx11::bind to hand a function handler with the appropriate
2717  // argument to the other loop function
2718  std_cxx11::function<void (const MatrixFree<dim,Number> &,
2719  OutVector &,
2720  const InVector &,
2721  const std::pair<unsigned int,
2722  unsigned int> &)>
2723  function = std_cxx11::bind<void>(function_pointer,
2724  owning_class,
2725  std_cxx11::_1,
2726  std_cxx11::_2,
2727  std_cxx11::_3,
2728  std_cxx11::_4);
2729  cell_loop (function, dst, src);
2730 }
2731 
2732 
2733 #endif // ifndef DOXYGEN
2734 
2735 
2736 
2737 DEAL_II_NAMESPACE_CLOSE
2738 
2739 #endif
Transformed quadrature weights.
const internal::MatrixFreeFunctions::ShapeInfo< Number > & get_shape_info(const unsigned int fe_component=0, const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0, const unsigned int hp_active_quad_index=0) const
const Quadrature< dim-1 > & get_face_quadrature(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
unsigned int n_physical_cells() const
DoFHandler< dim >::cell_iterator get_cell_iterator(const unsigned int macro_cell_number, const unsigned int vector_number, const unsigned int fe_component=0) const
void reinit(const size_type size, const bool omit_zeroing_entries=false)
internal::MatrixFreeFunctions::TaskInfo task_info
Definition: matrix_free.h:1043
bool indices_are_initialized
Definition: matrix_free.h:1048
static const unsigned int invalid_unsigned_int
Definition: types.h:170
unsigned int get_dofs_per_face(const unsigned int fe_component=0, const unsigned int hp_active_fe_index=0) const
const Number * constraint_pool_begin(const unsigned int pool_index) const
std::vector< unsigned int > constraint_pool_row_index
Definition: matrix_free.h:1013
const DoFHandler< dim > & get_dof_handler(const unsigned int fe_component=0) const
unsigned int get_n_q_points_face(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1146
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int fe_component=0) const
internal::MatrixFreeFunctions::MappingInfo< dim, Number > mapping_info
Definition: matrix_free.h:1019
A class that provides a separate storage location on each thread that accesses the object...
DoFHandlers dof_handlers
Definition: matrix_free.h:993
unsigned int n_components_filled(const unsigned int macro_cell_number) const
unsigned int n_components() const
void initialize_indices(const std::vector< const ConstraintMatrix *> &constraint, const std::vector< IndexSet > &locally_owned_set)
Threads::ThreadLocalStorage< std::list< std::pair< bool, AlignedVector< VectorizedArray< Number > > > > > scratch_pad
Definition: matrix_free.h:1062
std::vector< Number > constraint_pool_data
Definition: matrix_free.h:1007
#define AssertIndexRange(index, range)
Definition: exceptions.h:1170
void reinit(const Mapping< dim > &mapping, const DoFHandlerType &dof_handler, const ConstraintMatrix &constraint, const QuadratureType &quad, const AdditionalData additional_data=AdditionalData())
Table< 4, internal::MatrixFreeFunctions::ShapeInfo< Number > > shape_info
Definition: matrix_free.h:1024
void copy_from(const MatrixFree< dim, Number > &matrix_free_base)
std::vector< std::pair< unsigned int, unsigned int > > cell_level_index
Definition: matrix_free.h:1032
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
const std::vector< unsigned int > & get_constrained_dofs(const unsigned int fe_component=0) const
const IndexSet & get_ghost_set(const unsigned int fe_component=0) const
std::pair< unsigned int, unsigned int > create_cell_subrange_hp(const std::pair< unsigned int, unsigned int > &range, const unsigned int fe_degree, const unsigned int vector_component=0) const
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:163
bool mapping_is_initialized
Definition: matrix_free.h:1053
AlignedVector< VectorizedArray< Number > > * acquire_scratch_data() const
internal::MatrixFreeFunctions::SizeInfo size_info
Definition: matrix_free.h:1038
static ::ExceptionBase & ExcMessage(std::string arg1)
void partition(const SparsityPattern &sparsity_pattern, const unsigned int n_partitions, std::vector< unsigned int > &partition_indices)
void clear()
ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:256
Definition: types.h:30
bool at_irregular_cell(const unsigned int macro_cell_number) const
#define Assert(cond, exc)
Definition: exceptions.h:313
static bool is_supported(const FiniteElement< dim, spacedim > &fe)
UpdateFlags
void print_memory_consumption(StreamType &out) const
unsigned int get_dofs_per_cell(const unsigned int fe_component=0, const unsigned int hp_active_fe_index=0) const
const Number * constraint_pool_end(const unsigned int pool_index) const
unsigned int n_constraint_pool_entries() const
unsigned int n_macro_cells() const
void initialize_dof_handlers(const std::vector< const DoFHandler< dim > *> &dof_handlers, const unsigned int level)
ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:197
void internal_reinit(const Mapping< dim > &mapping, const std::vector< const DoFHandler< dim > *> &dof_handler, const std::vector< const ConstraintMatrix *> &constraint, const std::vector< IndexSet > &locally_owned_set, const std::vector< hp::QCollection< 1 > > &quad, const AdditionalData additional_data)
TasksParallelScheme tasks_parallel_scheme
Definition: matrix_free.h:257
const IndexSet & get_locally_owned_set(const unsigned int fe_component=0) const
bool mapping_initialized() const
std::pair< unsigned int, unsigned int > create_cell_subrange_hp_by_index(const std::pair< unsigned int, unsigned int > &range, const unsigned int fe_index, const unsigned int vector_component=0) const
Definition: hp.h:102
void cell_loop(const std_cxx11::function< void(const MatrixFree< dim, Number > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, OutVector &dst, const InVector &src) const
const internal::MatrixFreeFunctions::SizeInfo & get_size_info() const
void compress_start(const unsigned int communication_channel=0, ::VectorOperation::values operation=VectorOperation::add)
unsigned int tasks_block_size
Definition: matrix_free.h:268
void release_scratch_data(const AlignedVector< VectorizedArray< Number > > *memory) const
Definition: mpi.h:48
const std_cxx11::shared_ptr< const Utilities::MPI::Partitioner > & get_vector_partitioner(const unsigned int vector_component=0) const
void compress_finish(::VectorOperation::values operation)
const Triangulation< dim, spacedim > & get_triangulation() const
AdditionalData(const MPI_Comm mpi_communicator, const TasksParallelScheme tasks_parallel_scheme=partition_partition, const unsigned int tasks_block_size=0, const UpdateFlags mapping_update_flags=update_gradients|update_JxW_values, const unsigned int level_mg_handler=numbers::invalid_unsigned_int, const bool store_plain_indices=true, const bool initialize_indices=true, const bool initialize_mapping=true)
Definition: matrix_free.h:199
unsigned int level_mg_handler
Definition: matrix_free.h:291
hp::DoFHandler< dim >::active_cell_iterator get_hp_cell_iterator(const unsigned int macro_cell_number, const unsigned int vector_number, const unsigned int fe_component=0) const
Shape function gradients.
unsigned int get_n_q_points(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
UpdateFlags mapping_update_flags
Definition: matrix_free.h:281
static ::ExceptionBase & ExcNotImplemented()
std::size_t memory_consumption() const
const Triangulation< dim, spacedim > & get_triangulation() const
void initialize_dof_vector(VectorType &vec, const unsigned int vector_component=0) const
AdditionalData(const TasksParallelScheme tasks_parallel_scheme=partition_partition, const unsigned int tasks_block_size=0, const UpdateFlags mapping_update_flags=update_gradients|update_JxW_values, const unsigned int level_mg_handler=numbers::invalid_unsigned_int, const bool store_plain_indices=true, const bool initialize_indices=true, const bool initialize_mapping=true)
Definition: matrix_free.h:175
Definition: table.h:33
bool indices_initialized() const
const Quadrature< dim > & get_quadrature(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
std::vector< internal::MatrixFreeFunctions::DoFInfo > dof_info
Definition: matrix_free.h:999
void renumber_dofs(std::vector< types::global_dof_index > &renumbering, const unsigned int vector_component=0)
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
static ::ExceptionBase & ExcInternalError()
void print(std::ostream &out) const
void update_ghost_values_start(const unsigned int communication_channel=0) const