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/quadrature.h> 23 #include <deal.II/base/template_constraints.h> 24 #include <deal.II/base/thread_local_storage.h> 25 #include <deal.II/base/vectorization.h> 27 #include <deal.II/dofs/dof_handler.h> 29 #include <deal.II/fe/fe.h> 30 #include <deal.II/fe/mapping.h> 31 #include <deal.II/fe/mapping_q1.h> 33 #include <deal.II/grid/grid_tools.h> 35 #include <deal.II/hp/dof_handler.h> 36 #include <deal.II/hp/q_collection.h> 38 #include <deal.II/lac/affine_constraints.h> 39 #include <deal.II/lac/block_vector_base.h> 40 #include <deal.II/lac/la_parallel_vector.h> 41 #include <deal.II/lac/vector_operation.h> 43 #include <deal.II/matrix_free/dof_info.h> 44 #include <deal.II/matrix_free/mapping_info.h> 45 #include <deal.II/matrix_free/shape_info.h> 46 #include <deal.II/matrix_free/task_info.h> 47 #include <deal.II/matrix_free/type_traits.h> 55 DEAL_II_NAMESPACE_OPEN
112 template <
int dim,
typename Number =
double>
185 none = internal::MatrixFreeFunctions::TaskInfo::none,
190 internal::MatrixFreeFunctions::TaskInfo::partition_partition,
195 internal::MatrixFreeFunctions::TaskInfo::partition_color,
200 color = internal::MatrixFreeFunctions::TaskInfo::color
491 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
494 const DoFHandlerType & dof_handler,
496 const QuadratureType & quad,
503 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
505 reinit(
const DoFHandlerType & dof_handler,
507 const QuadratureType & quad,
517 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
518 DEAL_II_DEPRECATED
void 520 const DoFHandlerType & dof_handler,
522 const IndexSet & locally_owned_dofs,
523 const QuadratureType & quad,
547 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
550 const std::vector<const DoFHandlerType *> & dof_handler,
552 const std::vector<QuadratureType> & quad,
559 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
561 reinit(
const std::vector<const DoFHandlerType *> & dof_handler,
563 const std::vector<QuadratureType> & quad,
573 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
574 DEAL_II_DEPRECATED
void 576 const std::vector<const DoFHandlerType *> & dof_handler,
578 const std::vector<IndexSet> & locally_owned_set,
579 const std::vector<QuadratureType> &quad,
589 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
592 const std::vector<const DoFHandlerType *> & dof_handler,
594 const QuadratureType & quad,
601 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
603 reinit(
const std::vector<const DoFHandlerType *> & dof_handler,
605 const QuadratureType & quad,
718 template <
typename OutVector,
typename InVector>
724 const std::pair<unsigned int, unsigned int> &)>
728 const bool zero_dst_vector =
false)
const;
771 template <
typename CLASS,
typename OutVector,
typename InVector>
777 const std::pair<unsigned int, unsigned int> &)
const,
778 const CLASS * owning_class,
781 const bool zero_dst_vector =
false)
const;
786 template <
typename CLASS,
typename OutVector,
typename InVector>
792 const std::pair<unsigned int, unsigned int> &),
793 CLASS * owning_class,
796 const bool zero_dst_vector =
false)
const;
873 template <
typename OutVector,
typename InVector>
878 const std::pair<unsigned int, unsigned int> &)>
883 const std::pair<unsigned int, unsigned int> &)>
888 const std::pair<unsigned int, unsigned int> &)>
889 & boundary_operation,
891 const InVector & src,
892 const bool zero_dst_vector =
false,
982 template <
typename CLASS,
typename OutVector,
typename InVector>
985 void (CLASS::*cell_operation)(
const MatrixFree &,
988 const std::pair<unsigned int, unsigned int> &)
990 void (CLASS::*face_operation)(
const MatrixFree &,
993 const std::pair<unsigned int, unsigned int> &)
995 void (CLASS::*boundary_operation)(
999 const std::pair<unsigned int, unsigned int> &)
const,
1000 const CLASS * owning_class,
1002 const InVector & src,
1003 const bool zero_dst_vector =
false,
1012 template <
typename CLASS,
typename OutVector,
typename InVector>
1014 loop(
void (CLASS::*cell_operation)(
1018 const std::pair<unsigned int, unsigned int> &),
1019 void (CLASS::*face_operation)(
1023 const std::pair<unsigned int, unsigned int> &),
1024 void (CLASS::*boundary_operation)(
1028 const std::pair<unsigned int, unsigned int> &),
1029 CLASS * owning_class,
1031 const InVector & src,
1032 const bool zero_dst_vector =
false,
1045 std::pair<unsigned int, unsigned int>
1047 const unsigned int fe_degree,
1048 const unsigned int dof_handler_index = 0)
const;
1056 std::pair<unsigned int, unsigned int>
1058 const std::pair<unsigned int, unsigned int> &range,
1059 const unsigned int fe_index,
1060 const unsigned int dof_handler_index = 0)
const;
1088 template <
typename VectorType>
1091 const unsigned int dof_handler_index = 0)
const;
1113 template <
typename Number2>
1116 const unsigned int dof_handler_index = 0)
const;
1128 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1141 get_ghost_set(
const unsigned int dof_handler_index = 0)
const;
1152 const std::vector<unsigned int> &
1166 renumber_dofs(std::vector<types::global_dof_index> &renumbering,
1167 const unsigned int dof_handler_index = 0);
1178 template <
int spacedim>
1279 std::array<types::boundary_id, VectorizedArray<Number>::n_array_elements>
1281 const unsigned int face_number)
const;
1302 const unsigned int vector_number,
1303 const unsigned int fe_component = 0)
const;
1318 const unsigned int vector_number,
1319 const unsigned int dof_handler_index = 0)
const;
1374 const unsigned int hp_active_fe_index = 0)
const;
1381 const unsigned int hp_active_fe_index = 0)
const;
1389 const unsigned int hp_active_fe_index = 0)
const;
1397 const unsigned int hp_active_fe_index = 0)
const;
1404 const unsigned int hp_active_fe_index = 0)
const;
1411 const unsigned int hp_active_fe_index = 0)
const;
1426 std::pair<unsigned int, unsigned int>
1453 template <
typename StreamType>
1462 print(std::ostream &out)
const;
1489 get_mapping_info()
const;
1495 get_dof_info(
const unsigned int dof_handler_index_component = 0)
const;
1522 get_shape_info(
const unsigned int dof_handler_index_component = 0,
1523 const unsigned int quad_index = 0,
1524 const unsigned int fe_base_element = 0,
1525 const unsigned int hp_active_fe_index = 0,
1526 const unsigned int hp_active_quad_index = 0)
const;
1584 template <
typename number2>
1590 const std::vector<IndexSet> & locally_owned_set,
1592 const AdditionalData & additional_data);
1597 template <
typename number2>
1603 const std::vector<IndexSet> & locally_owned_set,
1605 const AdditionalData & additional_data);
1613 template <
typename number2>
1617 const std::vector<IndexSet> & locally_owned_set,
1618 const AdditionalData & additional_data);
1626 const AdditionalData & additional_data);
1634 const AdditionalData & additional_data);
1651 : active_dof_handler(
usual)
1656 std::vector<SmartPointer<const DoFHandler<dim>>> dof_handler;
1657 std::vector<SmartPointer<const hp::DoFHandler<dim>>> hp_dof_handler;
1668 } active_dof_handler;
1669 unsigned int n_dof_handlers;
1682 std::vector<internal::MatrixFreeFunctions::DoFInfo>
dof_info;
1760 std::list<std::pair<bool, AlignedVector<VectorizedArray<Number>>>>>
1767 mutable std::list<std::pair<bool, AlignedVector<Number>>>
1779 template <
int dim,
typename Number>
1780 template <
typename VectorType>
1783 const unsigned int comp)
const 1786 vec.reinit(dof_info[comp].vector_partitioner->size());
1791 template <
int dim,
typename Number>
1792 template <
typename Number2>
1796 const unsigned int comp)
const 1799 vec.
reinit(dof_info[comp].vector_partitioner);
1804 template <
int dim,
typename Number>
1805 inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1809 return dof_info[comp].vector_partitioner;
1814 template <
int dim,
typename Number>
1815 inline const std::vector<unsigned int> &
1819 return dof_info[comp].constrained_dofs;
1824 template <
int dim,
typename Number>
1829 return dof_handlers.n_dof_handlers;
1834 template <
int dim,
typename Number>
1840 return dof_handlers.dof_handler[dof_no]->get_fe().n_base_elements();
1845 template <
int dim,
typename Number>
1854 template <
int dim,
typename Number>
1863 template <
int dim,
typename Number>
1867 return *(task_info.cell_partition_data.end() - 2);
1872 template <
int dim,
typename Number>
1876 return task_info.n_active_cells;
1881 template <
int dim,
typename Number>
1885 return *(task_info.cell_partition_data.end() - 2);
1890 template <
int dim,
typename Number>
1894 return *(task_info.cell_partition_data.end() - 1) -
1895 *(task_info.cell_partition_data.end() - 2);
1900 template <
int dim,
typename Number>
1904 if (task_info.face_partition_data.size() == 0)
1906 return task_info.face_partition_data.back();
1911 template <
int dim,
typename Number>
1915 if (task_info.face_partition_data.size() == 0)
1917 return task_info.boundary_partition_data.back() -
1918 task_info.face_partition_data.back();
1923 template <
int dim,
typename Number>
1927 if (task_info.face_partition_data.size() == 0)
1929 return face_info.faces.size() - task_info.boundary_partition_data.back();
1934 template <
int dim,
typename Number>
1938 Assert(macro_face >= task_info.boundary_partition_data[0] &&
1939 macro_face < task_info.boundary_partition_data.back(),
1941 task_info.boundary_partition_data[0],
1942 task_info.boundary_partition_data.back()));
1948 template <
int dim,
typename Number>
1949 inline std::array<types::boundary_id, VectorizedArray<Number>::n_array_elements>
1951 const unsigned int macro_cell,
1952 const unsigned int face_number)
const 1956 Assert(face_info.cell_and_face_boundary_id.size(0) >= n_macro_cells(),
1958 std::array<types::boundary_id, VectorizedArray<Number>::n_array_elements>
1961 for (
unsigned int v = 0; v < n_active_entries_per_cell_batch(macro_cell); ++v)
1962 result[v] = face_info.cell_and_face_boundary_id(macro_cell, face_number, v);
1968 template <
int dim,
typename Number>
1972 return mapping_info;
1977 template <
int dim,
typename Number>
1982 return dof_info[dof_index];
1987 template <
int dim,
typename Number>
1991 return constraint_pool_row_index.size() - 1;
1996 template <
int dim,
typename Number>
1997 inline const Number *
2001 return constraint_pool_data.empty() ?
2003 constraint_pool_data.data() + constraint_pool_row_index[row];
2008 template <
int dim,
typename Number>
2009 inline const Number *
2013 return constraint_pool_data.empty() ?
2015 constraint_pool_data.data() + constraint_pool_row_index[row + 1];
2020 template <
int dim,
typename Number>
2021 inline std::pair<unsigned int, unsigned int>
2023 const std::pair<unsigned int, unsigned int> &range,
2024 const unsigned int degree,
2025 const unsigned int dof_handler_component)
const 2027 if (dof_info[dof_handler_component].cell_active_fe_index.empty())
2030 dof_info[dof_handler_component].fe_index_conversion.size(), 1);
2032 dof_info[dof_handler_component].fe_index_conversion[0].size(), 1);
2033 if (dof_info[dof_handler_component].fe_index_conversion[0][0] == degree)
2036 return {range.second, range.second};
2039 const unsigned int fe_index =
2040 dof_info[dof_handler_component].fe_index_from_degree(0, degree);
2041 if (fe_index >= dof_info[dof_handler_component].max_fe_index)
2042 return {range.second, range.second};
2044 return create_cell_subrange_hp_by_index(range,
2046 dof_handler_component);
2051 template <
int dim,
typename Number>
2057 cell_level_index[(macro_cell + 1) *
2060 cell_level_index[(macro_cell + 1) *
2067 template <
int dim,
typename Number>
2070 const unsigned int cell_batch_number)
const 2072 return n_active_entries_per_cell_batch(cell_batch_number);
2077 template <
int dim,
typename Number>
2080 const unsigned int cell_batch_number)
const 2085 cell_level_index[cell_batch_number *
2088 cell_level_index[cell_batch_number *
2098 template <
int dim,
typename Number>
2101 const unsigned int face_batch_number)
const 2106 face_info.faces[face_batch_number].cells_interior[
n_components - 1] ==
2115 template <
int dim,
typename Number>
2118 const unsigned int dof_handler_index,
2119 const unsigned int active_fe_index)
const 2121 return dof_info[dof_handler_index].dofs_per_cell[active_fe_index];
2126 template <
int dim,
typename Number>
2129 const unsigned int quad_index,
2130 const unsigned int active_fe_index)
const 2133 return mapping_info.cell_data[quad_index]
2134 .descriptor[active_fe_index]
2140 template <
int dim,
typename Number>
2143 const unsigned int dof_handler_index,
2144 const unsigned int active_fe_index)
const 2146 return dof_info[dof_handler_index].dofs_per_face[active_fe_index];
2151 template <
int dim,
typename Number>
2154 const unsigned int quad_index,
2155 const unsigned int active_fe_index)
const 2158 return mapping_info.face_data[quad_index]
2159 .descriptor[active_fe_index]
2165 template <
int dim,
typename Number>
2168 const unsigned int dof_handler_index)
const 2170 return dof_info[dof_handler_index].vector_partitioner->locally_owned_range();
2175 template <
int dim,
typename Number>
2178 const unsigned int dof_handler_index)
const 2180 return dof_info[dof_handler_index].vector_partitioner->ghost_indices();
2185 template <
int dim,
typename Number>
2188 const unsigned int dof_handler_index,
2189 const unsigned int index_quad,
2190 const unsigned int index_fe,
2191 const unsigned int active_fe_index,
2192 const unsigned int active_quad_index)
const 2195 const unsigned int ind =
2196 dof_info[dof_handler_index].global_base_element_offset + index_fe;
2201 return shape_info(ind, index_quad, active_fe_index, active_quad_index);
2206 template <
int dim,
typename Number>
2212 return face_info.faces[macro_face];
2217 template <
int dim,
typename Number>
2220 const unsigned int quad_index,
2221 const unsigned int active_fe_index)
const 2224 return mapping_info.cell_data[quad_index]
2225 .descriptor[active_fe_index]
2231 template <
int dim,
typename Number>
2234 const unsigned int quad_index,
2235 const unsigned int active_fe_index)
const 2238 return mapping_info.face_data[quad_index]
2239 .descriptor[active_fe_index]
2245 template <
int dim,
typename Number>
2251 if (dof_info[0].cell_active_fe_index.empty())
2254 return dof_info[0].cell_active_fe_index[macro_cell];
2259 template <
int dim,
typename Number>
2260 inline std::pair<unsigned int, unsigned int>
2264 if (dof_info[0].cell_active_fe_index.empty())
2265 return std::make_pair(0U, 0U);
2267 std::pair<unsigned int, unsigned int> result;
2268 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements &&
2269 face_info.faces[macro_face].cells_interior[v] !=
2272 result.first = std::max(
2275 .cell_active_fe_index[face_info.faces[macro_face].cells_interior[v]]);
2276 if (face_info.faces[macro_face].cells_exterior[0] !=
2278 for (
unsigned int v = 0; v < VectorizedArray<Number>::n_array_elements &&
2279 face_info.faces[macro_face].cells_exterior[v] !=
2282 result.second = std::max(
2285 .cell_active_fe_index[face_info.faces[macro_face].cells_exterior[v]]);
2293 template <
int dim,
typename Number>
2297 return indices_are_initialized;
2302 template <
int dim,
typename Number>
2306 return mapping_is_initialized;
2311 template <
int dim,
typename Number>
2316 std::list<std::pair<bool, AlignedVector<VectorizedArray<Number>>>>;
2317 list_type &data = scratch_pad.get();
2318 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
2319 if (it->first ==
false)
2326 return &data.front().second;
2331 template <
int dim,
typename Number>
2337 std::list<std::pair<bool, AlignedVector<VectorizedArray<Number>>>>;
2338 list_type &data = scratch_pad.get();
2339 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
2340 if (&it->second == scratch)
2351 template <
int dim,
typename Number>
2356 scratch_pad_non_threadsafe.
begin();
2357 it != scratch_pad_non_threadsafe.end();
2359 if (it->first ==
false)
2364 scratch_pad_non_threadsafe.push_front(
2366 return &scratch_pad_non_threadsafe.front().second;
2371 template <
int dim,
typename Number>
2377 scratch_pad_non_threadsafe.
begin();
2378 it != scratch_pad_non_threadsafe.end();
2380 if (&it->second == scratch)
2395 namespace MatrixFreeImplementation
2397 template <
typename DoFHandlerType>
2398 inline std::vector<IndexSet>
2399 extract_locally_owned_index_sets(
2400 const std::vector<const DoFHandlerType *> &dofh,
2401 const unsigned int level)
2403 std::vector<IndexSet> locally_owned_set;
2404 locally_owned_set.reserve(dofh.size());
2405 for (
unsigned int j = 0; j < dofh.size(); j++)
2407 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
2410 return locally_owned_set;
2413 template <
int dim,
int spacedim>
2414 inline std::vector<IndexSet>
2415 extract_locally_owned_index_sets(
2416 const std::vector<const ::DoFHandler<dim, spacedim> *> &dofh,
2417 const unsigned int level)
2419 std::vector<IndexSet> locally_owned_set;
2420 locally_owned_set.reserve(dofh.size());
2421 for (
unsigned int j = 0; j < dofh.size(); j++)
2423 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
2425 locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(level));
2426 return locally_owned_set;
2433 template <
int dim,
typename Number>
2434 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2437 const DoFHandlerType & dof_handler,
2439 const QuadratureType & quad,
2442 std::vector<const DoFHandlerType *> dof_handlers;
2443 std::vector<const AffineConstraints<number2> *> constraints;
2444 std::vector<QuadratureType> quads;
2446 dof_handlers.push_back(&dof_handler);
2447 constraints.push_back(&constraints_in);
2448 quads.push_back(quad);
2450 std::vector<IndexSet> locally_owned_sets =
2451 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2454 std::vector<hp::QCollection<1>> quad_hp;
2455 quad_hp.emplace_back(quad);
2467 template <
int dim,
typename Number>
2468 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2472 const DoFHandlerType & dof_handler,
2474 const QuadratureType & quad,
2477 std::vector<const DoFHandlerType *> dof_handlers;
2478 std::vector<const AffineConstraints<number2> *> constraints;
2480 dof_handlers.push_back(&dof_handler);
2481 constraints.push_back(&constraints_in);
2483 std::vector<IndexSet> locally_owned_sets =
2484 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2487 std::vector<hp::QCollection<1>> quad_hp;
2488 quad_hp.emplace_back(quad);
2490 internal_reinit(mapping,
2500 template <
int dim,
typename Number>
2501 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2504 const std::vector<const DoFHandlerType *> & dof_handler,
2506 const std::vector<QuadratureType> & quad,
2509 std::vector<IndexSet> locally_owned_set =
2510 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2512 std::vector<hp::QCollection<1>> quad_hp;
2513 for (
unsigned int q = 0; q < quad.size(); ++q)
2514 quad_hp.emplace_back(quad[q]);
2525 template <
int dim,
typename Number>
2526 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2529 const std::vector<const DoFHandlerType *> & dof_handler,
2531 const QuadratureType & quad,
2534 std::vector<IndexSet> locally_owned_set =
2535 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2537 std::vector<hp::QCollection<1>> quad_hp;
2538 quad_hp.emplace_back(quad);
2549 template <
int dim,
typename Number>
2550 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2554 const std::vector<const DoFHandlerType *> & dof_handler,
2556 const QuadratureType & quad,
2559 std::vector<IndexSet> locally_owned_set =
2560 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2562 std::vector<hp::QCollection<1>> quad_hp;
2563 quad_hp.emplace_back(quad);
2564 internal_reinit(mapping,
2574 template <
int dim,
typename Number>
2575 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2579 const std::vector<const DoFHandlerType *> & dof_handler,
2581 const std::vector<QuadratureType> & quad,
2584 std::vector<IndexSet> locally_owned_set =
2585 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2587 std::vector<hp::QCollection<1>> quad_hp;
2588 for (
unsigned int q = 0; q < quad.size(); ++q)
2589 quad_hp.emplace_back(quad[q]);
2590 internal_reinit(mapping,
2600 template <
int dim,
typename Number>
2601 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2605 const std::vector<const DoFHandlerType *> & dof_handler,
2607 const std::vector<IndexSet> & locally_owned_set,
2608 const std::vector<QuadratureType> & quad,
2612 std::vector<hp::QCollection<1>> quad_hp;
2613 for (
unsigned int q = 0; q < quad.size(); ++q)
2614 quad_hp.emplace_back(quad[q]);
2615 internal_reinit(mapping,
2640 template <
int dim,
typename Number>
2641 struct VectorDataExchange
2646 static constexpr
unsigned int channel_shift = 103;
2655 const ::MatrixFree<dim, Number> &matrix_free,
2656 const typename ::MatrixFree<dim, Number>::DataAccessOnFaces
2658 const unsigned int n_components)
2659 : matrix_free(matrix_free)
2660 , vector_face_access(
2661 matrix_free.get_task_info().face_partition_data.empty() ?
2662 ::
MatrixFree<dim, Number>::DataAccessOnFaces::unspecified :
2664 , ghosts_were_set(false)
2665 # ifdef DEAL_II_WITH_MPI
2671 if (this->vector_face_access !=
2673 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
2675 matrix_free.get_dof_info(c).vector_partitioner_face_variants.size(),
2684 ~VectorDataExchange()
2686 # ifdef DEAL_II_WITH_MPI 2687 for (
unsigned int i = 0; i < tmp_data.size(); ++i)
2688 if (tmp_data[i] !=
nullptr)
2689 matrix_free.release_scratch_data_non_threadsafe(tmp_data[i]);
2699 template <
typename VectorType>
2701 find_vector_in_mf(
const VectorType &vec,
2702 const bool check_global_compatibility =
true)
const 2705 (void)check_global_compatibility;
2706 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
2709 check_global_compatibility ?
2710 vec.get_partitioner()->is_globally_compatible(
2711 *matrix_free.get_dof_info(c).vector_partitioner) :
2713 vec.get_partitioner()->is_compatible(
2714 *matrix_free.get_dof_info(c).vector_partitioner))
2719 return mf_component;
2729 get_partitioner(
const unsigned int mf_component)
const 2732 .vector_partitioner_face_variants.size(),
2734 if (vector_face_access ==
2736 return *matrix_free.get_dof_info(mf_component)
2737 .vector_partitioner_face_variants[0];
2738 else if (vector_face_access ==
2740 return *matrix_free.get_dof_info(mf_component)
2741 .vector_partitioner_face_variants[1];
2743 return *matrix_free.get_dof_info(mf_component)
2744 .vector_partitioner_face_variants[2];
2752 template <
typename VectorType,
2753 typename std::enable_if<is_serial_or_dummy<VectorType>::value,
2754 VectorType>::type * =
nullptr>
2756 update_ghost_values_start(
const unsigned int ,
2757 const VectorType & )
2765 template <
typename VectorType,
2766 typename std::enable_if<
2767 !has_update_ghost_values_start<VectorType>::value &&
2768 !is_serial_or_dummy<VectorType>::value,
2769 VectorType>::type * =
nullptr>
2771 update_ghost_values_start(
const unsigned int component_in_block_vector,
2772 const VectorType & vec)
2774 (void)component_in_block_vector;
2775 bool ghosts_set = vec.has_ghost_elements();
2777 ghosts_were_set =
true;
2779 vec.update_ghost_values();
2789 template <
typename VectorType,
2790 typename std::enable_if<
2791 has_update_ghost_values_start<VectorType>::value &&
2792 !has_exchange_on_subset<VectorType>::value,
2793 VectorType>::type * =
nullptr>
2795 update_ghost_values_start(
const unsigned int component_in_block_vector,
2796 const VectorType & vec)
2798 (void)component_in_block_vector;
2799 bool ghosts_set = vec.has_ghost_elements();
2801 ghosts_were_set =
true;
2803 vec.update_ghost_values_start(component_in_block_vector + channel_shift);
2814 template <
typename VectorType,
2815 typename std::enable_if<
2816 has_update_ghost_values_start<VectorType>::value &&
2817 has_exchange_on_subset<VectorType>::value,
2818 VectorType>::type * =
nullptr>
2820 update_ghost_values_start(
const unsigned int component_in_block_vector,
2821 const VectorType & vec)
2824 std::is_same<Number, typename VectorType::value_type>::value,
2825 "Type mismatch between VectorType and VectorDataExchange");
2826 (void)component_in_block_vector;
2827 bool ghosts_set = vec.has_ghost_elements();
2829 ghosts_were_set =
true;
2830 if (vector_face_access ==
2833 vec.update_ghost_values_start(component_in_block_vector +
2837 # ifdef DEAL_II_WITH_MPI 2838 const unsigned int mf_component = find_vector_in_mf(vec);
2839 if (&get_partitioner(mf_component) ==
2840 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
2842 vec.update_ghost_values_start(component_in_block_vector +
2848 get_partitioner(mf_component);
2852 tmp_data[component_in_block_vector] =
2853 matrix_free.acquire_scratch_data_non_threadsafe();
2854 tmp_data[component_in_block_vector]->resize_fast(
2859 component_in_block_vector + channel_shift,
2864 vec.get_partitioner()->local_size(),
2865 vec.get_partitioner()->n_ghost_indices()),
2866 this->requests[component_in_block_vector]);
2878 typename VectorType,
2879 typename std::enable_if<!has_update_ghost_values_start<VectorType>::value,
2880 VectorType>::type * =
nullptr>
2882 update_ghost_values_finish(
const unsigned int ,
2883 const VectorType & )
2893 template <
typename VectorType,
2894 typename std::enable_if<
2895 has_update_ghost_values_start<VectorType>::value &&
2896 !has_exchange_on_subset<VectorType>::value,
2897 VectorType>::type * =
nullptr>
2899 update_ghost_values_finish(
const unsigned int component_in_block_vector,
2900 const VectorType & vec)
2902 (void)component_in_block_vector;
2903 vec.update_ghost_values_finish();
2914 template <
typename VectorType,
2915 typename std::enable_if<
2916 has_update_ghost_values_start<VectorType>::value &&
2917 has_exchange_on_subset<VectorType>::value,
2918 VectorType>::type * =
nullptr>
2920 update_ghost_values_finish(
const unsigned int component_in_block_vector,
2921 const VectorType & vec)
2924 std::is_same<Number, typename VectorType::value_type>::value,
2925 "Type mismatch between VectorType and VectorDataExchange");
2926 (void)component_in_block_vector;
2927 if (vector_face_access ==
2930 vec.update_ghost_values_finish();
2933 # ifdef DEAL_II_WITH_MPI 2938 const unsigned int mf_component = find_vector_in_mf(vec);
2940 get_partitioner(mf_component);
2942 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
2944 vec.update_ghost_values_finish();
2953 vec.get_partitioner()->local_size(),
2954 vec.get_partitioner()->n_ghost_indices()),
2955 this->requests[component_in_block_vector]);
2957 matrix_free.release_scratch_data_non_threadsafe(
2958 tmp_data[component_in_block_vector]);
2959 tmp_data[component_in_block_vector] =
nullptr;
2963 vec.set_ghost_state(
true);
2973 template <
typename VectorType,
2974 typename std::enable_if<is_serial_or_dummy<VectorType>::value,
2975 VectorType>::type * =
nullptr>
2977 compress_start(
const unsigned int ,
2987 template <
typename VectorType,
2988 typename std::enable_if<!has_compress_start<VectorType>::value &&
2989 !is_serial_or_dummy<VectorType>::value,
2990 VectorType>::type * =
nullptr>
2992 compress_start(
const unsigned int component_in_block_vector,
2995 (void)component_in_block_vector;
3008 typename VectorType,
3009 typename std::enable_if<has_compress_start<VectorType>::value &&
3010 !has_exchange_on_subset<VectorType>::value,
3011 VectorType>::type * =
nullptr>
3013 compress_start(
const unsigned int component_in_block_vector,
3016 (void)component_in_block_vector;
3018 vec.compress_start(component_in_block_vector + channel_shift);
3030 typename VectorType,
3031 typename std::enable_if<has_compress_start<VectorType>::value &&
3032 has_exchange_on_subset<VectorType>::value,
3033 VectorType>::type * =
nullptr>
3035 compress_start(
const unsigned int component_in_block_vector,
3039 std::is_same<Number, typename VectorType::value_type>::value,
3040 "Type mismatch between VectorType and VectorDataExchange");
3041 (void)component_in_block_vector;
3043 if (vector_face_access ==
3046 vec.compress_start(component_in_block_vector + channel_shift);
3049 # ifdef DEAL_II_WITH_MPI 3051 const unsigned int mf_component = find_vector_in_mf(vec);
3053 get_partitioner(mf_component);
3055 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3057 vec.compress_start(component_in_block_vector + channel_shift);
3064 tmp_data[component_in_block_vector] =
3065 matrix_free.acquire_scratch_data_non_threadsafe();
3066 tmp_data[component_in_block_vector]->resize_fast(
3072 component_in_block_vector + channel_shift,
3074 vec.get_partitioner()->n_ghost_indices()),
3077 this->requests[component_in_block_vector]);
3088 template <
typename VectorType,
3089 typename std::enable_if<!has_compress_start<VectorType>::value,
3090 VectorType>::type * =
nullptr>
3092 compress_finish(
const unsigned int ,
3104 typename VectorType,
3105 typename std::enable_if<has_compress_start<VectorType>::value &&
3106 !has_exchange_on_subset<VectorType>::value,
3107 VectorType>::type * =
nullptr>
3109 compress_finish(
const unsigned int component_in_block_vector,
3112 (void)component_in_block_vector;
3125 typename VectorType,
3126 typename std::enable_if<has_compress_start<VectorType>::value &&
3127 has_exchange_on_subset<VectorType>::value,
3128 VectorType>::type * =
nullptr>
3130 compress_finish(
const unsigned int component_in_block_vector,
3134 std::is_same<Number, typename VectorType::value_type>::value,
3135 "Type mismatch between VectorType and VectorDataExchange");
3136 (void)component_in_block_vector;
3137 if (vector_face_access ==
3143 # ifdef DEAL_II_WITH_MPI 3147 const unsigned int mf_component = find_vector_in_mf(vec);
3150 get_partitioner(mf_component);
3152 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3164 tmp_data[component_in_block_vector]->begin(),
3168 vec.get_partitioner()->n_ghost_indices()),
3169 this->requests[component_in_block_vector]);
3171 matrix_free.release_scratch_data_non_threadsafe(
3172 tmp_data[component_in_block_vector]);
3173 tmp_data[component_in_block_vector] =
nullptr;
3183 template <
typename VectorType,
3184 typename std::enable_if<is_serial_or_dummy<VectorType>::value,
3185 VectorType>::type * =
nullptr>
3187 reset_ghost_values(
const VectorType & )
const 3197 typename VectorType,
3198 typename std::enable_if<!has_exchange_on_subset<VectorType>::value &&
3199 !is_serial_or_dummy<VectorType>::value,
3200 VectorType>::type * =
nullptr>
3202 reset_ghost_values(
const VectorType &vec)
const 3204 if (ghosts_were_set ==
true)
3207 vec.zero_out_ghosts();
3217 template <
typename VectorType,
3218 typename std::enable_if<has_exchange_on_subset<VectorType>::value,
3219 VectorType>::type * =
nullptr>
3221 reset_ghost_values(
const VectorType &vec)
const 3224 std::is_same<Number, typename VectorType::value_type>::value,
3225 "Type mismatch between VectorType and VectorDataExchange");
3226 if (ghosts_were_set ==
true)
3229 if (vector_face_access ==
3232 vec.zero_out_ghosts();
3235 # ifdef DEAL_II_WITH_MPI 3238 const unsigned int mf_component = find_vector_in_mf(vec);
3240 get_partitioner(mf_component);
3242 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3243 vec.zero_out_ghosts();
3246 for (std::vector<std::pair<unsigned int, unsigned int>>::
3247 const_iterator my_ghosts =
3252 for (
unsigned int j = my_ghosts->first; j < my_ghosts->second;
3274 template <
typename VectorType,
3275 typename std::enable_if<has_exchange_on_subset<VectorType>::value,
3276 VectorType>::type * =
nullptr>
3278 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const 3281 std::is_same<Number, typename VectorType::value_type>::value,
3282 "Type mismatch between VectorType and VectorDataExchange");
3287 const unsigned int mf_component = find_vector_in_mf(vec,
false);
3289 matrix_free.get_dof_info(mf_component);
3297 for (
unsigned int id =
3302 const unsigned int start_pos =
3305 const unsigned int end_pos =
3308 chunk_size_zero_vector,
3311 std::memset(vec.begin() + start_pos,
3313 (end_pos - start_pos) *
sizeof(Number));
3326 typename VectorType,
3327 typename std::enable_if<!has_exchange_on_subset<VectorType>::value,
3328 VectorType>::type * =
nullptr,
3329 typename VectorType::value_type * =
nullptr>
3331 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const 3334 vec =
typename VectorType::value_type();
3348 zero_vector_region(
const unsigned int, ...)
const 3352 "which provide VectorType::value_type"));
3357 const ::MatrixFree<dim, Number> &matrix_free;
3358 const typename ::MatrixFree<dim, Number>::DataAccessOnFaces
3360 bool ghosts_were_set;
3361 # ifdef DEAL_II_WITH_MPI 3362 std::vector<AlignedVector<Number> *> tmp_data;
3363 std::vector<std::vector<MPI_Request>> requests;
3367 template <
typename VectorStruct>
3371 template <
typename VectorStruct>
3373 n_components_block(
const VectorStruct &vec,
3374 std::integral_constant<bool, true>)
3376 unsigned int components = 0;
3377 for (
unsigned int bl = 0; bl < vec.n_blocks(); ++bl)
3382 template <
typename VectorStruct>
3384 n_components_block(
const VectorStruct &, std::integral_constant<bool, false>)
3389 template <
typename VectorStruct>
3393 return n_components_block(
3397 template <
typename VectorStruct>
3401 unsigned int components = 0;
3402 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3403 components += n_components_block(
3409 template <
typename VectorStruct>
3413 unsigned int components = 0;
3414 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3415 components += n_components_block(
3429 typename VectorStruct,
3430 typename std::enable_if<!has_communication_block_size<VectorStruct>::value,
3431 VectorStruct>::type * =
nullptr>
3432 constexpr
unsigned int 3433 get_communication_block_size(
const VectorStruct &)
3441 typename VectorStruct,
3442 typename std::enable_if<has_communication_block_size<VectorStruct>::value,
3443 VectorStruct>::type * =
nullptr>
3444 constexpr
unsigned int 3445 get_communication_block_size(
const VectorStruct &)
3447 return VectorStruct::communication_block_size;
3462 typename VectorStruct,
3464 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3465 VectorStruct>::type * =
nullptr>
3467 update_ghost_values_start(
const VectorStruct & vec,
3468 VectorDataExchange<dim, Number> &exchanger,
3469 const unsigned int channel = 0)
3471 if (get_communication_block_size(vec) < vec.n_blocks())
3475 exchanger.ghosts_were_set = vec.has_ghost_elements();
3476 vec.update_ghost_values();
3480 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3481 update_ghost_values_start(vec.block(i), exchanger, channel + i);
3489 typename VectorStruct,
3491 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
3492 VectorStruct>::type * =
nullptr>
3494 update_ghost_values_start(
const VectorStruct & vec,
3495 VectorDataExchange<dim, Number> &exchanger,
3496 const unsigned int channel = 0)
3498 exchanger.update_ghost_values_start(channel, vec);
3504 template <
int dim,
typename VectorStruct,
typename Number>
3506 update_ghost_values_start(
const std::vector<VectorStruct> &vec,
3507 VectorDataExchange<dim, Number> &exchanger)
3509 unsigned int component_index = 0;
3510 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3512 update_ghost_values_start(vec[comp], exchanger, component_index);
3520 template <
int dim,
typename VectorStruct,
typename Number>
3522 update_ghost_values_start(
const std::vector<VectorStruct *> &vec,
3523 VectorDataExchange<dim, Number> & exchanger)
3525 unsigned int component_index = 0;
3526 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3528 update_ghost_values_start(*vec[comp], exchanger, component_index);
3541 typename VectorStruct,
3543 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3544 VectorStruct>::type * =
nullptr>
3546 update_ghost_values_finish(
const VectorStruct & vec,
3547 VectorDataExchange<dim, Number> &exchanger,
3548 const unsigned int channel = 0)
3550 if (get_communication_block_size(vec) < vec.n_blocks())
3556 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3557 update_ghost_values_finish(vec.block(i), exchanger, channel + i);
3564 typename VectorStruct,
3566 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
3567 VectorStruct>::type * =
nullptr>
3569 update_ghost_values_finish(
const VectorStruct & vec,
3570 VectorDataExchange<dim, Number> &exchanger,
3571 const unsigned int channel = 0)
3573 exchanger.update_ghost_values_finish(channel, vec);
3579 template <
int dim,
typename VectorStruct,
typename Number>
3581 update_ghost_values_finish(
const std::vector<VectorStruct> &vec,
3582 VectorDataExchange<dim, Number> &exchanger)
3584 unsigned int component_index = 0;
3585 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3587 update_ghost_values_finish(vec[comp], exchanger, component_index);
3595 template <
int dim,
typename VectorStruct,
typename Number>
3597 update_ghost_values_finish(
const std::vector<VectorStruct *> &vec,
3598 VectorDataExchange<dim, Number> & exchanger)
3600 unsigned int component_index = 0;
3601 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3603 update_ghost_values_finish(*vec[comp], exchanger, component_index);
3616 typename VectorStruct,
3618 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3619 VectorStruct>::type * =
nullptr>
3621 compress_start(VectorStruct & vec,
3622 VectorDataExchange<dim, Number> &exchanger,
3623 const unsigned int channel = 0)
3625 if (get_communication_block_size(vec) < vec.n_blocks())
3628 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3629 compress_start(vec.block(i), exchanger, channel + i);
3636 typename VectorStruct,
3638 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
3639 VectorStruct>::type * =
nullptr>
3641 compress_start(VectorStruct & vec,
3642 VectorDataExchange<dim, Number> &exchanger,
3643 const unsigned int channel = 0)
3645 exchanger.compress_start(channel, vec);
3651 template <
int dim,
typename VectorStruct,
typename Number>
3653 compress_start(std::vector<VectorStruct> & vec,
3654 VectorDataExchange<dim, Number> &exchanger)
3656 unsigned int component_index = 0;
3657 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3659 compress_start(vec[comp], exchanger, component_index);
3667 template <
int dim,
typename VectorStruct,
typename Number>
3669 compress_start(std::vector<VectorStruct *> & vec,
3670 VectorDataExchange<dim, Number> &exchanger)
3672 unsigned int component_index = 0;
3673 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3675 compress_start(*vec[comp], exchanger, component_index);
3688 typename VectorStruct,
3690 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3691 VectorStruct>::type * =
nullptr>
3693 compress_finish(VectorStruct & vec,
3694 VectorDataExchange<dim, Number> &exchanger,
3695 const unsigned int channel = 0)
3697 if (get_communication_block_size(vec) < vec.n_blocks())
3703 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3704 compress_finish(vec.block(i), exchanger, channel + i);
3711 typename VectorStruct,
3713 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
3714 VectorStruct>::type * =
nullptr>
3716 compress_finish(VectorStruct & vec,
3717 VectorDataExchange<dim, Number> &exchanger,
3718 const unsigned int channel = 0)
3720 exchanger.compress_finish(channel, vec);
3726 template <
int dim,
typename VectorStruct,
typename Number>
3728 compress_finish(std::vector<VectorStruct> & vec,
3729 VectorDataExchange<dim, Number> &exchanger)
3731 unsigned int component_index = 0;
3732 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3734 compress_finish(vec[comp], exchanger, component_index);
3742 template <
int dim,
typename VectorStruct,
typename Number>
3744 compress_finish(std::vector<VectorStruct *> & vec,
3745 VectorDataExchange<dim, Number> &exchanger)
3747 unsigned int component_index = 0;
3748 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3750 compress_finish(*vec[comp], exchanger, component_index);
3767 typename VectorStruct,
3769 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3770 VectorStruct>::type * =
nullptr>
3772 reset_ghost_values(
const VectorStruct & vec,
3773 VectorDataExchange<dim, Number> &exchanger)
3776 if (exchanger.ghosts_were_set ==
true)
3779 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3780 reset_ghost_values(vec.block(i), exchanger);
3787 typename VectorStruct,
3789 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
3790 VectorStruct>::type * =
nullptr>
3792 reset_ghost_values(
const VectorStruct & vec,
3793 VectorDataExchange<dim, Number> &exchanger)
3795 exchanger.reset_ghost_values(vec);
3801 template <
int dim,
typename VectorStruct,
typename Number>
3803 reset_ghost_values(
const std::vector<VectorStruct> &vec,
3804 VectorDataExchange<dim, Number> &exchanger)
3807 if (exchanger.ghosts_were_set ==
true)
3810 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3811 reset_ghost_values(vec[comp], exchanger);
3817 template <
int dim,
typename VectorStruct,
typename Number>
3819 reset_ghost_values(
const std::vector<VectorStruct *> &vec,
3820 VectorDataExchange<dim, Number> & exchanger)
3823 if (exchanger.ghosts_were_set ==
true)
3826 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3827 reset_ghost_values(*vec[comp], exchanger);
3838 typename VectorStruct,
3840 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3841 VectorStruct>::type * =
nullptr>
3843 zero_vector_region(
const unsigned int range_index,
3845 VectorDataExchange<dim, Number> &exchanger)
3847 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3848 exchanger.zero_vector_region(range_index, vec.block(i));
3855 typename VectorStruct,
3857 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
3858 VectorStruct>::type * =
nullptr>
3860 zero_vector_region(
const unsigned int range_index,
3862 VectorDataExchange<dim, Number> &exchanger)
3864 exchanger.zero_vector_region(range_index, vec);
3870 template <
int dim,
typename VectorStruct,
typename Number>
3872 zero_vector_region(
const unsigned int range_index,
3873 std::vector<VectorStruct> & vec,
3874 VectorDataExchange<dim, Number> &exchanger)
3876 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3877 zero_vector_region(range_index, vec[comp], exchanger);
3883 template <
int dim,
typename VectorStruct,
typename Number>
3885 zero_vector_region(
const unsigned int range_index,
3886 std::vector<VectorStruct *> & vec,
3887 VectorDataExchange<dim, Number> &exchanger)
3889 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3890 zero_vector_region(range_index, *vec[comp], exchanger);
3895 namespace MatrixFreeFunctions
3899 template <
typename,
typename,
typename,
typename,
bool>
3900 struct InterfaceSelector
3904 template <
typename MF,
3908 struct InterfaceSelector<MF, InVector, OutVector, Container, true>
3910 using function_type = void (Container::*)(
3914 const std::pair<unsigned int, unsigned int> &)
const;
3918 template <
typename MF,
3922 struct InterfaceSelector<MF, InVector, OutVector, Container, false>
3924 using function_type =
3925 void (Container::*)(
const MF &,
3928 const std::pair<unsigned int, unsigned int> &);
3936 template <
typename MF,
3941 class MFWorker :
public MFWorkerInterface
3945 using function_type =
typename MatrixFreeFunctions::
3946 InterfaceSelector<MF, InVector, OutVector, Container, is_constant>::
3950 MFWorker(
const MF & matrix_free,
3951 const InVector & src,
3953 const bool zero_dst_vector_setting,
3954 const Container & container,
3955 function_type cell_function,
3956 function_type face_function,
3957 function_type boundary_function,
3958 const typename MF::DataAccessOnFaces src_vector_face_access =
3959 MF::DataAccessOnFaces::none,
3960 const typename MF::DataAccessOnFaces dst_vector_face_access =
3961 MF::DataAccessOnFaces::none)
3962 : matrix_free(matrix_free)
3963 , container(const_cast<Container &>(container))
3964 , cell_function(cell_function)
3965 , face_function(face_function)
3966 , boundary_function(boundary_function)
3969 , src_data_exchanger(matrix_free,
3970 src_vector_face_access,
3972 , dst_data_exchanger(matrix_free,
3973 dst_vector_face_access,
3976 , zero_dst_vector_setting(zero_dst_vector_setting &&
3977 !src_and_dst_are_same)
3982 cell(
const std::pair<unsigned int, unsigned int> &cell_range)
override 3984 if (cell_function !=
nullptr && cell_range.second > cell_range.first)
3986 cell_function)(matrix_free, this->dst, this->src, cell_range);
3992 face(
const std::pair<unsigned int, unsigned int> &face_range)
override 3994 if (face_function !=
nullptr && face_range.second > face_range.first)
3996 face_function)(matrix_free, this->dst, this->src, face_range);
4002 boundary(
const std::pair<unsigned int, unsigned int> &face_range)
override 4004 if (boundary_function !=
nullptr && face_range.second > face_range.first)
4006 boundary_function)(matrix_free, this->dst, this->src, face_range);
4016 vector_update_ghosts_start()
override 4018 if (!src_and_dst_are_same)
4019 internal::update_ghost_values_start(src, src_data_exchanger);
4024 vector_update_ghosts_finish()
override 4026 if (!src_and_dst_are_same)
4027 internal::update_ghost_values_finish(src, src_data_exchanger);
4032 vector_compress_start()
override 4034 internal::compress_start(dst, dst_data_exchanger);
4039 vector_compress_finish()
override 4041 internal::compress_finish(dst, dst_data_exchanger);
4042 if (!src_and_dst_are_same)
4043 internal::reset_ghost_values(src, src_data_exchanger);
4048 zero_dst_vector_range(
const unsigned int range_index)
override 4050 if (zero_dst_vector_setting)
4051 internal::zero_vector_region(range_index, dst, dst_data_exchanger);
4055 const MF & matrix_free;
4056 Container & container;
4057 function_type cell_function;
4058 function_type face_function;
4059 function_type boundary_function;
4061 const InVector &src;
4063 VectorDataExchange<MF::dimension, typename MF::value_type>
4065 VectorDataExchange<MF::dimension, typename MF::value_type>
4067 const bool src_and_dst_are_same;
4068 const bool zero_dst_vector_setting;
4077 template <
class MF,
typename InVector,
typename OutVector>
4078 struct MFClassWrapper
4080 using function_type =
4081 std::function<void(
const MF &,
4084 const std::pair<unsigned int, unsigned int> &)>;
4086 MFClassWrapper(
const function_type cell,
4087 const function_type face,
4088 const function_type boundary)
4091 , boundary(boundary)
4095 cell_integrator(
const MF & mf,
4097 const InVector & src,
4098 const std::pair<unsigned int, unsigned int> &range)
const 4101 cell(mf, dst, src, range);
4105 face_integrator(
const MF & mf,
4107 const InVector & src,
4108 const std::pair<unsigned int, unsigned int> &range)
const 4111 face(mf, dst, src, range);
4115 boundary_integrator(
4118 const InVector & src,
4119 const std::pair<unsigned int, unsigned int> &range)
const 4122 boundary(mf, dst, src, range);
4125 const function_type cell;
4126 const function_type face;
4127 const function_type boundary;
4134 template <
int dim,
typename Number>
4135 template <
typename OutVector,
typename InVector>
4141 const std::pair<unsigned int, unsigned int> &)>
4144 const InVector &src,
4145 const bool zero_dst_vector)
const 4148 internal::MFClassWrapper<MatrixFree<dim, Number>, InVector, OutVector>;
4149 Wrapper wrap(cell_operation,
nullptr,
nullptr);
4151 MFWorker<MatrixFree<dim, Number>, InVector, OutVector, Wrapper,
true>
4157 &Wrapper::cell_integrator,
4158 &Wrapper::face_integrator,
4159 &Wrapper::boundary_integrator);
4161 task_info.loop(worker);
4166 template <
int dim,
typename Number>
4167 template <
typename OutVector,
typename InVector>
4173 const std::pair<unsigned int, unsigned int> &)>
4178 const std::pair<unsigned int, unsigned int> &)>
4183 const std::pair<unsigned int, unsigned int> &)>
4184 & boundary_operation,
4186 const InVector & src,
4187 const bool zero_dst_vector,
4188 const DataAccessOnFaces dst_vector_face_access,
4189 const DataAccessOnFaces src_vector_face_access)
const 4192 internal::MFClassWrapper<MatrixFree<dim, Number>, InVector, OutVector>;
4193 Wrapper wrap(cell_operation, face_operation, boundary_operation);
4195 MFWorker<MatrixFree<dim, Number>, InVector, OutVector, Wrapper,
true>
4201 &Wrapper::cell_integrator,
4202 &Wrapper::face_integrator,
4203 &Wrapper::boundary_integrator,
4204 src_vector_face_access,
4205 dst_vector_face_access);
4207 task_info.loop(worker);
4212 template <
int dim,
typename Number>
4213 template <
typename CLASS,
typename OutVector,
typename InVector>
4219 const std::pair<unsigned int, unsigned int> &)
4221 const CLASS * owning_class,
4223 const InVector &src,
4224 const bool zero_dst_vector)
const 4226 internal::MFWorker<MatrixFree<dim, Number>, InVector, OutVector, CLASS,
true>
4235 task_info.loop(worker);
4240 template <
int dim,
typename Number>
4241 template <
typename CLASS,
typename OutVector,
typename InVector>
4247 const std::pair<unsigned int, unsigned int> &)
4252 const std::pair<unsigned int, unsigned int> &)
4254 void (CLASS::*boundary_operation)(
4258 const std::pair<unsigned int, unsigned int> &)
const,
4259 const CLASS * owning_class,
4261 const InVector & src,
4262 const bool zero_dst_vector,
4263 const DataAccessOnFaces dst_vector_face_access,
4264 const DataAccessOnFaces src_vector_face_access)
const 4266 internal::MFWorker<MatrixFree<dim, Number>, InVector, OutVector, CLASS,
true>
4275 src_vector_face_access,
4276 dst_vector_face_access);
4277 task_info.loop(worker);
4282 template <
int dim,
typename Number>
4283 template <
typename CLASS,
typename OutVector,
typename InVector>
4286 void (CLASS::*function_pointer)(
4290 const std::pair<unsigned int, unsigned int> &),
4291 CLASS * owning_class,
4293 const InVector &src,
4294 const bool zero_dst_vector)
const 4296 internal::MFWorker<MatrixFree<dim, Number>, InVector, OutVector, CLASS,
false>
4305 task_info.loop(worker);
4310 template <
int dim,
typename Number>
4311 template <
typename CLASS,
typename OutVector,
typename InVector>
4317 const std::pair<unsigned int, unsigned int> &),
4321 const std::pair<unsigned int, unsigned int> &),
4322 void (CLASS::*boundary_operation)(
4326 const std::pair<unsigned int, unsigned int> &),
4327 CLASS * owning_class,
4329 const InVector & src,
4330 const bool zero_dst_vector,
4331 const DataAccessOnFaces dst_vector_face_access,
4332 const DataAccessOnFaces src_vector_face_access)
const 4334 internal::MFWorker<MatrixFree<dim, Number>, InVector, OutVector, CLASS,
false>
4343 src_vector_face_access,
4344 dst_vector_face_access);
4345 task_info.loop(worker);
4349 #endif // ifndef DOXYGEN 4353 DEAL_II_NAMESPACE_CLOSE
const IndexSet & get_ghost_set(const unsigned int dof_handler_index=0) const
Transformed quadrature weights.
UpdateFlags mapping_update_flags_inner_faces
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 loop(const std::function< void(const MatrixFree< dim, Number > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, const std::function< void(const MatrixFree< dim, Number > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &face_operation, const std::function< void(const MatrixFree< dim, Number > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &boundary_operation, OutVector &dst, const InVector &src, const bool zero_dst_vector=false, const DataAccessOnFaces dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
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
UpdateFlags mapping_update_flags_boundary_faces
const Number * constraint_pool_begin(const unsigned int pool_index) const
std::vector< unsigned int > constraint_pool_row_index
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)
A class that provides a separate storage location on each thread that accesses the object...
unsigned int n_ghost_cell_batches() const
static const unsigned int dimension
std::list< std::pair< bool, AlignedVector< Number > > > scratch_pad_non_threadsafe
unsigned int local_size() const
void initialize_dof_handlers(const std::vector< const DoFHandler< dim > *> &dof_handlers, const AdditionalData &additional_data)
const internal::MatrixFreeFunctions::TaskInfo & get_size_info() const
void import_from_ghosted_array_finish(const VectorOperation::values vector_operation, const ArrayView< const Number, MemorySpaceType > &temporary_storage, const ArrayView< Number, MemorySpaceType > &locally_owned_storage, const ArrayView< Number, MemorySpaceType > &ghost_array, std::vector< MPI_Request > &requests) const
unsigned int n_components() const
void import_from_ghosted_array_start(const VectorOperation::values vector_operation, const unsigned int communication_channel, const ArrayView< Number, MemorySpaceType > &ghost_array, const ArrayView< Number, MemorySpaceType > &temporary_storage, std::vector< MPI_Request > &requests) const
std::vector< std::pair< unsigned int, unsigned int > > cell_level_index
const IndexSet & get_locally_owned_set(const unsigned int dof_handler_index=0) const
unsigned int n_active_entries_per_face_batch(const unsigned int face_batch_number) const
std::vector< Number > constraint_pool_data
#define AssertIndexRange(index, range)
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
std::vector< unsigned int > vector_zero_range_list_index
void copy_from(const MatrixFree< dim, Number > &matrix_free_base)
std::array< types::boundary_id, VectorizedArray< Number >::n_array_elements > get_faces_by_cells_boundary_id(const unsigned int macro_cell, const unsigned int face_number) const
const std::vector< std::pair< unsigned int, unsigned int > > & ghost_indices_within_larger_ghost_set() const
void make_connectivity_graph_faces(DynamicSparsityPattern &connectivity)
void reinit(const size_type size, const bool omit_zeroing_entries=false)
static ::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
void initialize_indices(const std::vector< const AffineConstraints< number2 > *> &constraint, const std::vector< IndexSet > &locally_owned_set, const AdditionalData &additional_data)
hp::DoFHandler< dim >::active_cell_iterator get_hp_cell_iterator(const unsigned int macro_cell_number, const unsigned int vector_number, const unsigned int dof_handler_index=0) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
unsigned int get_dofs_per_cell(const unsigned int dof_handler_index=0, const unsigned int hp_active_fe_index=0) const
unsigned int n_boundary_face_batches() const
unsigned int n_inner_face_batches() const
bool mapping_is_initialized
~MatrixFree() override=default
AlignedVector< VectorizedArray< Number > > * acquire_scratch_data() const
typename ActiveSelector::active_cell_iterator active_cell_iterator
void initialize_dof_vector(VectorType &vec, const unsigned int dof_handler_index=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 dof_handler_index=0) const
unsigned int n_components_filled(const unsigned int cell_batch_number) const
void set_ghost_state(const bool ghosted) const
static ::ExceptionBase & ExcMessage(std::string arg1)
void renumber_dofs(std::vector< types::global_dof_index > &renumbering, const unsigned int dof_handler_index=0)
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_vector_partitioner(const unsigned int dof_handler_index=0) const
unsigned int n_ghost_indices() const
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
const types::boundary_id invalid_boundary_id
bool cell_vectorization_categories_strict
const Number * constraint_pool_end(const unsigned int pool_index) const
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > & get_shape_info(const unsigned int dof_handler_index_component=0, const unsigned int quad_index=0, const unsigned int fe_base_element=0, const unsigned int hp_active_fe_index=0, const unsigned int hp_active_quad_index=0) const
unsigned int n_constraint_pool_entries() 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 UpdateFlags mapping_update_flags_boundary_faces=update_default, const UpdateFlags mapping_update_flags_inner_faces=update_default, const UpdateFlags mapping_update_flags_faces_by_cells=update_default, 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, const bool overlap_communication_computation=true, const bool hold_all_faces_to_owned_cells=false, const bool cell_vectorization_categories_strict=false)
void release_scratch_data_non_threadsafe(const AlignedVector< Number > *memory) const
unsigned int n_macro_cells() const
TasksParallelScheme tasks_parallel_scheme
AlignedVector< Number > * acquire_scratch_data_non_threadsafe() const
types::boundary_id get_boundary_id(const unsigned int macro_face) const
bool hold_all_faces_to_owned_cells
bool mapping_initialized() const
unsigned int n_ghost_inner_face_batches() const
internal::MatrixFreeFunctions::FaceInfo< VectorizedArray< Number >::n_array_elements > face_info
Table< 4, internal::MatrixFreeFunctions::ShapeInfo< VectorizedArray< Number > > > shape_info
void internal_reinit(const Mapping< dim > &mapping, const std::vector< const DoFHandler< dim > *> &dof_handler, const std::vector< const AffineConstraints< number2 > *> &constraint, const std::vector< IndexSet > &locally_owned_set, const std::vector< hp::QCollection< 1 >> &quad, const AdditionalData &additional_data)
void reinit(const Mapping< dim > &mapping, const DoFHandlerType &dof_handler, const AffineConstraints< number2 > &constraint, const QuadratureType &quad, const AdditionalData additional_data=AdditionalData())
unsigned int tasks_block_size
internal::MatrixFreeFunctions::MappingInfo< dim, Number > mapping_info
unsigned int cell_level_index_end_local
unsigned int level_mg_handler
const DoFHandler< dim > & get_dof_handler(const unsigned int dof_handler_index=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
const internal::MatrixFreeFunctions::FaceToCellTopology< VectorizedArray< Number >::n_array_elements > & get_face_info(const unsigned int face_batch_number) const
unsigned int n_active_entries_per_cell_batch(const unsigned int cell_batch_number) 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 dof_handler_index=0) const
void export_to_ghosted_array_start(const unsigned int communication_channel, const ArrayView< const Number, MemorySpaceType > &locally_owned_array, const ArrayView< Number, MemorySpaceType > &temporary_storage, const ArrayView< Number, MemorySpaceType > &ghost_array, std::vector< MPI_Request > &requests) const
unsigned int n_base_elements(const unsigned int dof_handler_index) const
UpdateFlags mapping_update_flags
void export_to_ghosted_array_finish(const ArrayView< Number, MemorySpaceType > &ghost_array, std::vector< MPI_Request > &requests) const
static ::ExceptionBase & ExcNotImplemented()
std::size_t memory_consumption() const
const Quadrature< dim - 1 > & get_face_quadrature(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
Threads::ThreadLocalStorage< std::list< std::pair< bool, AlignedVector< VectorizedArray< Number > > > > > scratch_pad
std::vector< unsigned int > vector_zero_range_list
bool indices_initialized() const
unsigned int get_cell_category(const unsigned int macro_cell) const
std::pair< unsigned int, unsigned int > get_face_category(const unsigned int macro_face) const
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int dof_handler_index_component=0) 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
static const unsigned int chunk_size_zero_vector
unsigned int n_import_indices() const
unsigned int n_cell_batches() const
bool overlap_communication_computation
UpdateFlags mapping_update_flags_faces_by_cells
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
std::vector< unsigned int > cell_vectorization_category
static ::ExceptionBase & ExcInternalError()
void cell_loop(const std::function< void(const MatrixFree< dim, Number > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, OutVector &dst, const InVector &src, const bool zero_dst_vector=false) const
void print(std::ostream &out) const
void release_scratch_data(const AlignedVector< VectorizedArray< Number >> *memory) const
const std::vector< unsigned int > & get_constrained_dofs(const unsigned int dof_handler_index=0) const