17 #ifndef dealii__matrix_free_h 18 #define dealii__matrix_free_h 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> 42 #ifdef DEAL_II_WITH_THREADS 44 #include <tbb/task_scheduler_init.h> 45 #include <tbb/parallel_for.h> 46 #include <tbb/blocked_range.h> 55 DEAL_II_NAMESPACE_OPEN
108 template <
int dim,
typename Number=
double>
170 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
216 {} DEAL_II_DEPRECATED
320 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
352 template <
typename DoFHandlerType,
typename QuadratureType>
354 const DoFHandlerType &dof_handler,
356 const QuadratureType &quad,
363 template <
typename DoFHandlerType,
typename QuadratureType>
364 void reinit (
const DoFHandlerType &dof_handler,
366 const QuadratureType &quad,
376 template <
typename DoFHandlerType,
typename QuadratureType>
378 const DoFHandlerType &dof_handler,
381 const QuadratureType &quad,
404 template <typename DoFHandlerType, typename QuadratureType>
406 const
std::vector<const DoFHandlerType *> &dof_handler,
408 const
std::vector<QuadratureType> &quad,
415 template <typename DoFHandlerType, typename QuadratureType>
416 void reinit (const
std::vector<const DoFHandlerType *> &dof_handler,
418 const
std::vector<QuadratureType> &quad,
428 template <typename DoFHandlerType, typename QuadratureType>
430 const
std::vector<const DoFHandlerType *> &dof_handler,
433 const
std::vector<QuadratureType> &quad,
443 template <typename DoFHandlerType, typename QuadratureType>
445 const
std::vector<const DoFHandlerType *> &dof_handler,
447 const QuadratureType &quad,
454 template <typename DoFHandlerType, typename QuadratureType>
455 void reinit (const
std::vector<const DoFHandlerType *> &dof_handler,
457 const QuadratureType &quad,
492 template <typename OutVector, typename InVector>
496 const
std::pair<
unsigned int,
497 unsigned int> &)> &cell_operation,
499 const InVector &src) const;
510 template <typename CLASS, typename OutVector, typename InVector>
514 const
std::pair<
unsigned int,
515 unsigned int> &)const,
516 const CLASS *owning_class,
518 const InVector &src) const;
523 template <typename CLASS, typename OutVector, typename InVector>
527 const
std::pair<
unsigned int,
531 const InVector &src) const;
540 std::pair<
unsigned int,
unsigned int>
542 const
unsigned int fe_degree,
543 const
unsigned int vector_component = 0) const;
551 std::pair<
unsigned int,
unsigned int>
553 const
unsigned int fe_index,
554 const
unsigned int vector_component = 0) const;
582 template <typename VectorType>
584 const
unsigned int vector_component=0) const;
606 template <typename Number2>
608 const
unsigned int vector_component=0) const;
644 const
std::vector<
unsigned int> &
652 const
unsigned int vector_component = 0);
663 template <
int spacedim>
713 const
unsigned int vector_number,
714 const
unsigned int fe_component = 0) const;
729 const
unsigned int vector_number,
730 const
unsigned int fe_component = 0) const;
762 const
unsigned int hp_active_fe_index = 0) const;
769 const
unsigned int hp_active_fe_index = 0) const;
777 const
unsigned int hp_active_fe_index = 0) const;
785 const
unsigned int hp_active_fe_index = 0) const;
792 const
unsigned int hp_active_fe_index = 0) const;
799 const
unsigned int hp_active_fe_index = 0) const;
823 template <typename StreamType>
830 void print (
std::ostream &out) const;
841 const
internal::MatrixFreeFunctions::TaskInfo &
847 const
internal::MatrixFreeFunctions::SizeInfo &
853 const
internal::MatrixFreeFunctions::MappingInfo<dim,Number> &
854 get_mapping_info () const;
859 const
internal::MatrixFreeFunctions::DoFInfo &
860 get_dof_info (const
unsigned int fe_component = 0) const;
885 const
internal::MatrixFreeFunctions::ShapeInfo<Number> &
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;
924 const
std::vector<
hp::QCollection<1> > &quad,
934 const
std::vector<
hp::QCollection<1> > &quad,
951 const
unsigned int level);
957 const
unsigned int level);
968 active_dof_handler(usual),
973 std::vector<SmartPointer<const DoFHandler<dim> > > dof_handler;
974 std::vector<SmartPointer<const hp::DoFHandler<dim> > > hp_dof_handler;
985 } active_dof_handler;
986 unsigned int n_dof_handlers;
999 std::vector<internal::MatrixFreeFunctions::DoFInfo>
dof_info;
1072 template <
int dim,
typename Number>
1073 template <
typename VectorType>
1077 const unsigned int comp)
const 1080 vec.reinit(dof_info[comp].vector_partitioner->size());
1085 template <
int dim,
typename Number>
1086 template <
typename Number2>
1090 const unsigned int comp)
const 1093 vec.
reinit(dof_info[comp].vector_partitioner);
1098 template <
int dim,
typename Number>
1100 const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &
1104 return dof_info[comp].vector_partitioner;
1109 template <
int dim,
typename Number>
1111 const std::vector<unsigned int> &
1115 return dof_info[comp].constrained_dofs;
1120 template <
int dim,
typename Number>
1126 return dof_handlers.n_dof_handlers;
1131 template <
int dim,
typename Number>
1141 template <
int dim,
typename Number>
1151 template <
int dim,
typename Number>
1156 return size_info.n_macro_cells;
1161 template <
int dim,
typename Number>
1166 return size_info.n_active_cells;
1171 template <
int dim,
typename Number>
1176 return mapping_info;
1181 template <
int dim,
typename Number>
1183 const internal::MatrixFreeFunctions::DoFInfo &
1187 return dof_info[dof_index];
1192 template <
int dim,
typename Number>
1197 return constraint_pool_row_index.size()-1;
1202 template <
int dim,
typename Number>
1208 return constraint_pool_data.empty() ? 0 :
1209 &constraint_pool_data[0] + constraint_pool_row_index[row];
1214 template <
int dim,
typename Number>
1220 return constraint_pool_data.empty() ? 0 :
1221 &constraint_pool_data[0] + constraint_pool_row_index[row+1];
1226 template <
int dim,
typename Number>
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 1235 if (dof_info[vector_component].cell_active_fe_index.empty())
1237 AssertDimension (dof_info[vector_component].fe_index_conversion.size(),1);
1238 if (dof_info[vector_component].fe_index_conversion[0].first == degree)
1241 return std::pair<unsigned int,unsigned int> (range.second,range.second);
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);
1249 return create_cell_subrange_hp_by_index (range, fe_index, vector_component);
1254 template <
int dim,
typename Number>
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 1263 const std::vector<unsigned int> &fe_indices =
1264 dof_info[vector_component].cell_active_fe_index;
1265 if (fe_indices.size() == 0)
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!"));
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)
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 &&
1289 return return_range;
1295 template <
int dim,
typename Number>
1299 const unsigned int vector_component)
1302 dof_info[vector_component].renumber_dofs (renumbering);
1307 template <
int dim,
typename Number>
1313 if (dof_handlers.active_dof_handler == DoFHandlers::usual)
1316 dof_handlers.n_dof_handlers);
1317 return *dof_handlers.dof_handler[dof_index];
1330 template <
int dim,
typename Number>
1334 const unsigned int vector_number,
1335 const unsigned int dof_index)
const 1342 const unsigned int irreg_filled = dof_info[dof_index].row_starts[macro_cell_number][2];
1343 if (irreg_filled > 0)
1348 if (dof_handlers.active_dof_handler == DoFHandlers::usual)
1351 dof_handlers.n_dof_handlers);
1352 dofh = dof_handlers.dof_handler[dof_index];
1357 "for underlying DoFHandler!"));
1360 std::pair<unsigned int,unsigned int> index =
1361 cell_level_index[macro_cell_number*vectorization_length+vector_number];
1368 template <
int dim,
typename Number>
1372 const unsigned int vector_number,
1373 const unsigned int dof_index)
const 1380 const unsigned int irreg_filled = dof_info[dof_index].row_starts[macro_cell_number][2];
1381 if (irreg_filled > 0)
1385 Assert (dof_handlers.active_dof_handler == DoFHandlers::hp,
1388 std::pair<unsigned int,unsigned int> index =
1389 cell_level_index[macro_cell_number*vectorization_length+vector_number];
1396 template <
int dim,
typename Number>
1402 return dof_info[0].row_starts[macro_cell][2] > 0;
1407 template <
int dim,
typename Number>
1413 const unsigned int n_filled = dof_info[0].row_starts[macro_cell][2];
1422 template <
int dim,
typename Number>
1426 const unsigned int active_fe_index)
const 1429 return dof_info[dof_index].dofs_per_cell[active_fe_index];
1434 template <
int dim,
typename Number>
1438 const unsigned int active_fe_index)
const 1441 mapping_info.mapping_data_gen.size());
1442 return mapping_info.mapping_data_gen[quad_index].n_q_points[active_fe_index];
1447 template <
int dim,
typename Number>
1451 const unsigned int active_fe_index)
const 1454 return dof_info[dof_index].dofs_per_face[active_fe_index];
1459 template <
int dim,
typename Number>
1463 const unsigned int active_fe_index)
const 1466 mapping_info.mapping_data_gen.size());
1467 return mapping_info.mapping_data_gen[quad_index].n_q_points_face[active_fe_index];
1472 template <
int dim,
typename Number>
1478 return dof_info[dof_index].vector_partitioner->locally_owned_range();
1483 template <
int dim,
typename Number>
1489 return dof_info[dof_index].vector_partitioner->ghost_indices();
1494 template <
int dim,
typename Number>
1498 const unsigned int index_quad,
1499 const unsigned int active_fe_index,
1500 const unsigned int active_quad_index)
const 1506 return shape_info(index_fe, index_quad,
1507 active_fe_index, active_quad_index);
1512 template <
int dim,
typename Number>
1516 const unsigned int active_fe_index)
const 1519 return mapping_info.mapping_data_gen[quad_index].
1520 quadrature[active_fe_index];
1525 template <
int dim,
typename Number>
1529 const unsigned int active_fe_index)
const 1532 return mapping_info.mapping_data_gen[quad_index].
1533 face_quadrature[active_fe_index];
1538 template <
int dim,
typename Number>
1543 return indices_are_initialized;
1548 template <
int dim,
typename Number>
1553 return mapping_is_initialized;
1558 template <
int dim,
typename Number>
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)
1571 return &data.front().second;
1576 template <
int dim,
typename Number>
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)
1600 template <
typename DoFHandlerType>
1602 std::vector<IndexSet>
1603 extract_locally_owned_index_sets (
const std::vector<const DoFHandlerType *> &dofh,
1604 const unsigned int level)
1606 std::vector<IndexSet> locally_owned_set;
1607 locally_owned_set.reserve (dofh.size());
1608 for (
unsigned int j=0; j<dofh.size(); j++)
1610 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
1613 return locally_owned_set;
1616 template <
int dim,
int spacedim>
1618 std::vector<IndexSet>
1619 extract_locally_owned_index_sets (
const std::vector<const ::DoFHandler<dim,spacedim> *> &dofh,
1620 const unsigned int level)
1622 std::vector<IndexSet> locally_owned_set;
1623 locally_owned_set.reserve (dofh.size());
1624 for (
unsigned int j=0; j<dofh.size(); j++)
1626 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
1628 locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(level));
1629 return locally_owned_set;
1636 template <
int dim,
typename Number>
1637 template <
typename DoFHandlerType,
typename QuadratureType>
1639 reinit(
const DoFHandlerType &dof_handler,
1641 const QuadratureType &quad,
1644 std::vector<const DoFHandlerType *> dof_handlers;
1645 std::vector<const ConstraintMatrix *> constraints;
1646 std::vector<QuadratureType> quads;
1648 dof_handlers.push_back(&dof_handler);
1649 constraints.push_back (&constraints_in);
1650 quads.push_back (quad);
1652 std::vector<IndexSet> locally_owned_sets =
1653 internal::MatrixFree::extract_locally_owned_index_sets
1656 std::vector<hp::QCollection<1> > quad_hp;
1660 locally_owned_sets, quad_hp, additional_data);
1665 template <
int dim,
typename Number>
1666 template <
typename DoFHandlerType,
typename QuadratureType>
1669 const DoFHandlerType &dof_handler,
1671 const QuadratureType &quad,
1674 std::vector<const DoFHandlerType *> dof_handlers;
1675 std::vector<const ConstraintMatrix *> constraints;
1677 dof_handlers.push_back(&dof_handler);
1678 constraints.push_back (&constraints_in);
1680 std::vector<IndexSet> locally_owned_sets =
1681 internal::MatrixFree::extract_locally_owned_index_sets
1684 std::vector<hp::QCollection<1> > quad_hp;
1687 internal_reinit(mapping, dof_handlers,constraints,locally_owned_sets,
1688 quad_hp, additional_data);
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,
1701 std::vector<IndexSet> locally_owned_set =
1702 internal::MatrixFree::extract_locally_owned_index_sets
1704 std::vector<hp::QCollection<1> > quad_hp;
1705 for (
unsigned int q=0; q<quad.size(); ++q)
1708 locally_owned_set, quad_hp, additional_data);
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,
1721 std::vector<IndexSet> locally_owned_set =
1722 internal::MatrixFree::extract_locally_owned_index_sets
1724 std::vector<hp::QCollection<1> > quad_hp;
1727 locally_owned_set, quad_hp, additional_data);
1732 template <
int dim,
typename Number>
1733 template <
typename DoFHandlerType,
typename QuadratureType>
1736 const std::vector<const DoFHandlerType *> &dof_handler,
1737 const std::vector<const ConstraintMatrix *> &constraint,
1738 const QuadratureType &quad,
1741 std::vector<IndexSet> locally_owned_set =
1742 internal::MatrixFree::extract_locally_owned_index_sets
1744 std::vector<hp::QCollection<1> > quad_hp;
1746 internal_reinit(mapping, dof_handler,constraint,
1747 locally_owned_set, quad_hp, additional_data);
1752 template <
int dim,
typename Number>
1753 template <
typename DoFHandlerType,
typename QuadratureType>
1756 const std::vector<const DoFHandlerType *> &dof_handler,
1757 const std::vector<const ConstraintMatrix *> &constraint,
1758 const std::vector<QuadratureType> &quad,
1761 std::vector<IndexSet> locally_owned_set =
1762 internal::MatrixFree::extract_locally_owned_index_sets
1764 std::vector<hp::QCollection<1> > quad_hp;
1765 for (
unsigned int q=0; q<quad.size(); ++q)
1767 internal_reinit(mapping, dof_handler,constraint,locally_owned_set,
1768 quad_hp, additional_data);
1773 template <
int dim,
typename Number>
1774 template <
typename DoFHandlerType,
typename QuadratureType>
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,
1784 std::vector<hp::QCollection<1> > quad_hp;
1785 for (
unsigned int q=0; q<quad.size(); ++q)
1787 internal_reinit (mapping,
1789 constraint, locally_owned_set, quad_hp, additional_data);
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,
1824 template<
typename VectorStruct>
1825 bool update_ghost_values_start_block (
const VectorStruct &,
1831 template<
typename VectorStruct>
1832 void reset_ghost_values_block (
const VectorStruct &,
1836 template<
typename VectorStruct>
1837 void update_ghost_values_finish_block (
const VectorStruct &,
1840 template<
typename VectorStruct>
1841 void compress_start_block (
const VectorStruct &,
1845 template<
typename VectorStruct>
1846 void compress_finish_block (
const VectorStruct &,
1854 template<
typename VectorStruct>
1856 bool update_ghost_values_start (
const VectorStruct &vec,
1857 const unsigned int channel = 0)
1860 update_ghost_values_start_block(vec, channel,
1866 template<
typename Number>
1869 const unsigned int channel = 0)
1873 return return_value;
1878 template <
typename VectorStruct>
1880 bool update_ghost_values_start (
const std::vector<VectorStruct> &vec)
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;
1890 template <
typename VectorStruct>
1892 bool update_ghost_values_start (
const std::vector<VectorStruct *> &vec)
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;
1902 template<
typename VectorStruct>
1904 bool update_ghost_values_start_block (
const VectorStruct &vec,
1905 const unsigned int channel,
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;
1919 template<
typename VectorStruct>
1921 void reset_ghost_values (
const VectorStruct &vec,
1922 const bool zero_out_ghosts)
1924 reset_ghost_values_block(vec, zero_out_ghosts,
1930 template<
typename Number>
1933 const bool zero_out_ghosts)
1935 if (zero_out_ghosts)
1941 template <
typename VectorStruct>
1943 void reset_ghost_values (
const std::vector<VectorStruct> &vec,
1944 const bool zero_out_ghosts)
1946 for (
unsigned int comp=0; comp<vec.size(); comp++)
1947 reset_ghost_values(vec[comp], zero_out_ghosts);
1952 template <
typename VectorStruct>
1954 void reset_ghost_values (
const std::vector<VectorStruct *> &vec,
1955 const bool zero_out_ghosts)
1957 for (
unsigned int comp=0; comp<vec.size(); comp++)
1958 reset_ghost_values(*vec[comp], zero_out_ghosts);
1963 template<
typename VectorStruct>
1965 void reset_ghost_values_block (
const VectorStruct &vec,
1966 const bool zero_out_ghosts,
1969 for (
unsigned int i=0; i<vec.n_blocks(); ++i)
1970 reset_ghost_values(vec.block(i), zero_out_ghosts);
1975 template <
typename VectorStruct>
1977 void update_ghost_values_finish (
const VectorStruct &vec)
1979 update_ghost_values_finish_block(vec,
1985 template <
typename Number>
1994 template <
typename VectorStruct>
1996 void update_ghost_values_finish (
const std::vector<VectorStruct> &vec)
1998 for (
unsigned int comp=0; comp<vec.size(); comp++)
1999 update_ghost_values_finish(vec[comp]);
2004 template <
typename VectorStruct>
2006 void update_ghost_values_finish (
const std::vector<VectorStruct *> &vec)
2008 for (
unsigned int comp=0; comp<vec.size(); comp++)
2009 update_ghost_values_finish(*vec[comp]);
2014 template <
typename VectorStruct>
2016 void update_ghost_values_finish_block (
const VectorStruct &vec,
2019 for (
unsigned int i=0; i<vec.n_blocks(); ++i)
2020 update_ghost_values_finish(vec.block(i));
2025 template <
typename VectorStruct>
2027 void compress_start (VectorStruct &vec,
2028 const unsigned int channel = 0)
2030 compress_start_block (vec, channel,
2036 template <
typename Number>
2039 const unsigned int channel = 0)
2046 template <
typename VectorStruct>
2048 void compress_start (std::vector<VectorStruct> &vec)
2050 for (
unsigned int comp=0; comp<vec.size(); comp++)
2051 compress_start (vec[comp], comp);
2056 template <
typename VectorStruct>
2058 void compress_start (std::vector<VectorStruct *> &vec)
2060 for (
unsigned int comp=0; comp<vec.size(); comp++)
2061 compress_start (*vec[comp], comp);
2066 template <
typename VectorStruct>
2068 void compress_start_block (VectorStruct &vec,
2069 const unsigned int channel,
2072 for (
unsigned int i=0; i<vec.n_blocks(); ++i)
2073 compress_start(vec.block(i), channel + 500*i);
2078 template <
typename VectorStruct>
2080 void compress_finish (VectorStruct &vec)
2082 compress_finish_block(vec,
2088 template <
typename Number>
2097 template <
typename VectorStruct>
2099 void compress_finish (std::vector<VectorStruct> &vec)
2101 for (
unsigned int comp=0; comp<vec.size(); comp++)
2102 compress_finish(vec[comp]);
2107 template <
typename VectorStruct>
2109 void compress_finish (std::vector<VectorStruct *> &vec)
2111 for (
unsigned int comp=0; comp<vec.size(); comp++)
2112 compress_finish(*vec[comp]);
2117 template <
typename VectorStruct>
2119 void compress_finish_block (VectorStruct &vec,
2122 for (
unsigned int i=0; i<vec.n_blocks(); ++i)
2123 compress_finish(vec.block(i));
2128 #ifdef DEAL_II_WITH_THREADS 2135 template<
typename Worker>
2136 class CellWork :
public tbb::task
2139 CellWork (
const Worker &worker_in,
2140 const unsigned int partition_in,
2142 const bool is_blocked_in)
2147 task_info (task_info_in),
2148 is_blocked (is_blocked_in)
2150 tbb::task *execute ()
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]);
2156 if (is_blocked==
true)
2157 dummy->spawn (*dummy);
2161 tbb::empty_task *dummy;
2164 const Worker &worker;
2167 const bool is_blocked;
2172 template<
typename Worker>
2173 class PartitionWork :
public tbb::task
2176 PartitionWork (
const Worker &function_in,
2177 const unsigned int partition_in,
2179 const bool is_blocked_in =
false)
2182 function (function_in),
2184 task_info (task_info_in),
2185 is_blocked (is_blocked_in)
2187 tbb::task *execute ()
2189 tbb::empty_task *root =
new( tbb::task::allocate_root() )
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);
2199 root->set_ref_count(evens+1);
2200 for (
unsigned int j=0; j<evens; j++)
2202 worker[j] =
new(root->allocate_child())
2203 CellWork<Worker>(
function, task_info.
2204 partition_color_blocks_row_index[partition]+2*j,
2208 worker[j]->set_ref_count(2);
2209 blocked_worker[j-1]->dummy =
new(worker[j]->allocate_child())
2211 worker[j-1]->spawn(*blocked_worker[j-1]);
2214 worker[j]->set_ref_count(1);
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);
2226 worker[evens] =
new(worker[j]->allocate_child())
2227 CellWork<Worker>(
function, task_info.
2228 partition_color_blocks_row_index[partition]+2*j+1,
2230 worker[j]->spawn(*worker[evens]);
2234 tbb::empty_task *child =
new(worker[j]->allocate_child())
2236 worker[j]->spawn(*child);
2241 root->wait_for_all();
2242 root->destroy(*root);
2243 if (is_blocked==
true)
2244 dummy->spawn (*dummy);
2248 tbb::empty_task *dummy;
2251 const Worker &
function;
2254 const bool is_blocked;
2263 template <
typename Worker>
2267 CellWork (
const Worker &worker_in,
2271 task_info (task_info_in)
2273 void operator()(
const tbb::blocked_range<unsigned int> &r)
const 2275 for (
unsigned int block=r.begin(); block<r.end(); block++)
2277 std::pair<unsigned int,unsigned int> cell_range;
2278 if (task_info.position_short_block<block)
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;
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));
2291 worker (cell_range);
2295 const Worker &worker;
2300 template<
typename Worker>
2301 class PartitionWork :
public tbb::task
2304 PartitionWork (
const Worker &worker_in,
2305 const unsigned int partition_in,
2307 const bool is_blocked_in)
2312 task_info (task_info_in),
2313 is_blocked (is_blocked_in)
2315 tbb::task *execute ()
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);
2326 tbb::empty_task *dummy;
2329 const Worker &worker;
2332 const bool is_blocked;
2338 template<
typename VectorStruct>
2339 class MPIComDistribute :
public tbb::task
2342 MPIComDistribute (
const VectorStruct &src_in)
2347 tbb::task *execute ()
2349 internal::update_ghost_values_finish(src);
2354 const VectorStruct &src;
2359 template<
typename VectorStruct>
2360 class MPIComCompress :
public tbb::task
2363 MPIComCompress (VectorStruct &dst_in)
2368 tbb::task *execute ()
2370 internal::compress_start(dst);
2378 #endif // DEAL_II_WITH_THREADS 2384 template <
int dim,
typename Number>
2385 template <
typename OutVector,
typename InVector>
2392 const std::pair<
unsigned int,
2393 unsigned int> &)> &cell_operation,
2395 const InVector &src)
const 2398 bool ghosts_were_not_set = internal::update_ghost_values_start (src);
2400 #ifdef DEAL_II_WITH_THREADS 2404 if (task_info.use_multithreading ==
true && task_info.n_blocks > 3)
2409 std_cxx11::function<void (const std::pair<unsigned int,unsigned int> &range)>
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),
2418 if (task_info.use_partition_partition ==
true)
2420 tbb::empty_task *root =
new( tbb::task::allocate_root() )
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>*>
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++)
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())
2446 worker[j-1]->spawn(*blocked_worker[j-1]);
2448 worker_compr->spawn(*blocked_worker[j-1]);
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);
2463 blocked_worker[j] =
new(worker[j]->allocate_child())
2464 internal::partition::PartitionWork<Worker>
2465 (func,2*j+1,task_info,
true);
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]);
2478 tbb::empty_task *child =
new(worker[j]->allocate_child())
2480 worker[j]->spawn(*child);
2485 root->wait_for_all();
2486 root->destroy(*root);
2490 unsigned int evens = task_info.evens;
2491 unsigned int odds = task_info.odds;
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-
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++)
2513 const unsigned int spawn_index_new = worker_index;
2515 worker[worker_index] =
new(worker_compr->allocate_child())
2516 internal::color::PartitionWork<Worker>(func,slice_index,task_info,
false);
2518 worker[worker_index] =
new(root->allocate_child())
2519 internal::color::PartitionWork<Worker>(func,slice_index,task_info,
false);
2521 for (; slice_index<task_info.partition_color_blocks_row_index[part+1];
2524 worker[worker_index]->set_ref_count(1);
2526 worker[worker_index] =
new (worker[worker_index-1]->allocate_child())
2527 internal::color::PartitionWork<Worker>(func,slice_index,task_info,
false);
2529 worker[worker_index]->set_ref_count(2);
2532 blocked_worker[(part-1)/2]->dummy =
2533 new (worker[worker_index]->allocate_child()) tbb::empty_task;
2535 if (spawn_index_child == -1)
2536 worker[spawn_index]->spawn(*blocked_worker[(part-1)/2]);
2540 worker[spawn_index]->spawn(*worker[spawn_index_child]);
2542 spawn_index = spawn_index_new;
2546 internal::MPIComDistribute<InVector> *worker_dist =
2547 new (worker[worker_index]->allocate_child())
2548 internal::MPIComDistribute<InVector>(src);
2549 worker_dist->spawn(*worker_dist);
2553 if (part<task_info.partition_color_blocks_row_index.size()-1)
2555 if (part<task_info.partition_color_blocks_row_index.size()-2)
2557 blocked_worker[part/2] =
new(worker[worker_index-1]->allocate_child())
2558 internal::color::PartitionWork<Worker>(func,slice_index,task_info,
true);
2561 task_info.partition_color_blocks_row_index[part+1])
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);
2570 spawn_index_child = -1;
2574 for (; slice_index<task_info.partition_color_blocks_row_index[part+1];
2578 task_info.partition_color_blocks_row_index[part])
2580 worker[worker_index]->set_ref_count(1);
2583 worker[worker_index] =
new (worker[worker_index-1]->allocate_child())
2584 internal::color::PartitionWork<Worker>(func,slice_index,task_info,
false);
2586 spawn_index_child = worker_index;
2591 tbb::empty_task *
final =
new (worker[worker_index-1]->allocate_child())
2593 worker[spawn_index]->spawn(*
final);
2594 spawn_index_child = worker_index-1;
2600 worker[spawn_index]->spawn(*worker[spawn_index_child]);
2602 root->wait_for_all();
2603 root->destroy(*root);
2610 internal::update_ghost_values_finish(src);
2612 for (
unsigned int color=0;
2613 color < task_info.partition_color_blocks_row_index[1];
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>
2623 internal::compress_start(dst);
2631 std::pair<unsigned int,unsigned int> cell_range;
2635 cell_range.first = 0;
2636 cell_range.second = size_info.boundary_cells_start;
2637 cell_operation (*
this, dst, src, cell_range);
2642 internal::update_ghost_values_finish(src);
2645 if (size_info.boundary_cells_end > size_info.boundary_cells_start)
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);
2652 internal::compress_start(dst);
2655 if (size_info.n_macro_cells > size_info.boundary_cells_end)
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);
2664 internal::compress_finish(dst);
2665 internal::reset_ghost_values(src, ghosts_were_not_set);
2670 template <
int dim,
typename Number>
2671 template <
typename CLASS,
typename OutVector,
typename InVector>
2678 const std::pair<
unsigned int,
2679 unsigned int> &)
const,
2680 const CLASS *owning_class,
2682 const InVector &src)
const 2686 std_cxx11::function<void (const MatrixFree<dim,Number> &,
2689 const std::pair<
unsigned int,
2691 function = std_cxx11::bind<void>(function_pointer,
2697 cell_loop (
function, dst, src);
2702 template <
int dim,
typename Number>
2703 template <
typename CLASS,
typename OutVector,
typename InVector>
2710 const std::pair<
unsigned int,
2712 CLASS *owning_class,
2714 const InVector &src)
const 2718 std_cxx11::function<void (const MatrixFree<dim,Number> &,
2721 const std::pair<
unsigned int,
2723 function = std_cxx11::bind<void>(function_pointer,
2729 cell_loop (
function, dst, src);
2733 #endif // ifndef DOXYGEN 2737 DEAL_II_NAMESPACE_CLOSE
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
bool indices_are_initialized
static const unsigned int invalid_unsigned_int
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
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)
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int fe_component=0) const
internal::MatrixFreeFunctions::MappingInfo< dim, Number > mapping_info
A class that provides a separate storage location on each thread that accesses the object...
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
std::vector< Number > constraint_pool_data
#define AssertIndexRange(index, range)
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
void copy_from(const MatrixFree< dim, Number > &matrix_free_base)
std::vector< std::pair< unsigned int, unsigned int > > cell_level_index
#define AssertThrow(cond, exc)
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
bool mapping_is_initialized
AlignedVector< VectorizedArray< Number > > * acquire_scratch_data() const
internal::MatrixFreeFunctions::SizeInfo size_info
static ::ExceptionBase & ExcMessage(std::string arg1)
bool has_ghost_elements() const
ActiveSelector::cell_iterator cell_iterator
bool at_irregular_cell(const unsigned int macro_cell_number) const
#define Assert(cond, exc)
static bool is_supported(const FiniteElement< dim, spacedim > &fe)
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
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
const IndexSet & get_locally_owned_set(const unsigned int fe_component=0) const
bool mapping_initialized() const
MPI_Comm mpi_communicator
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
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
void release_scratch_data(const AlignedVector< VectorizedArray< Number > > *memory) const
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)
unsigned int level_mg_handler
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
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)
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
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
void update_ghost_values_finish() const